[
  {
    "path": ".editorconfig",
    "content": "[*]\nindent_style = tab\nindent_size = 2\n\n[*.{js,json,ts}]\nindent_style = space\nindent_size = 2\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/new-issue.md",
    "content": "---\nname: New issue\nabout: This is the template for new issues.\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n<!--\nWhen reporting a bug or requesting a feature, please do the following:\n\n* Describe what esbuild is doing incorrectly and what it should be doing instead.\n\n* Provide a way to reproduce the issue. The best way to do this is to demonstrate the issue on the playground (https://esbuild.github.io/try/) and paste the URL here. A link to a minimal code sample with instructions for how to reproduce the issue may also work. Issues without a way to reproduce them may be closed.\n-->\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non:\n  push:\n    branches: ['*']\n  pull_request:\n    branches: ['*']\n  workflow_dispatch:\n\npermissions:\n  contents: read  #  to fetch code (actions/checkout)\n\njobs:\n  esbuild-platforms:\n    # Split this out into its own runner because it's slow\n    name: esbuild CI (All Platforms)\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Read go.version\n        run: |\n          echo \"GO_VERSION=$(cat go.version)\" >> $GITHUB_ENV\n\n      - name: Set up Go 1.x\n        uses: actions/setup-go@v3\n        with:\n          go-version: ${{ env.GO_VERSION }}\n        id: go\n\n      - name: Setup Node.js environment\n        uses: actions/setup-node@v3\n        with:\n          node-version: 18\n\n      - name: Ensure all platforms can be built\n        run: make platform-all\n\n      # Plan 9 is not a supported platform, but someone wanted esbuild to be able to build for it anyway...\n      - name: Ensure esbuild can be built for Plan 9\n        run: |\n          GOOS=plan9 GOARCH=386 go build ./cmd/esbuild\n          GOOS=plan9 GOARCH=amd64 go build ./cmd/esbuild\n          GOOS=plan9 GOARCH=arm go build ./cmd/esbuild\n\n  esbuild-slow:\n    # Split these out into their own runner because they're very slow\n    name: esbuild CI (Slow Tests)\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Read go.version\n        run: |\n          echo \"GO_VERSION=$(cat go.version)\" >> $GITHUB_ENV\n\n      - name: Set up Go 1.x\n        uses: actions/setup-go@v3\n        with:\n          go-version: ${{ env.GO_VERSION }}\n        id: go\n\n      - name: Setup Node.js environment\n        uses: actions/setup-node@v3\n        with:\n          node-version: 16\n\n      # Note: These tests break with node version 18. Something about WebAssembly.\n      - name: Rollup Tests\n        run: make test-rollup\n\n      - name: Uglify Tests\n        run: CI=1 make uglify\n\n      - name: Type check tsc using tsc\n        run: make test-tsc\n\n  esbuild:\n    name: esbuild CI\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        os: [ubuntu-latest, macos-latest, windows-latest]\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Read go.version (non-Windows)\n        if: matrix.os != 'windows-latest'\n        run: |\n          echo \"GO_VERSION=$(cat go.version)\" >> $GITHUB_ENV\n\n      - name: Read go.version (Windows)\n        if: matrix.os == 'windows-latest'\n        run: |\n          echo \"GO_VERSION=$(cat go.version)\" >> $Env:GITHUB_ENV\n\n      - name: Set up Go 1.x\n        uses: actions/setup-go@v3\n        with:\n          go-version: ${{ env.GO_VERSION }}\n        id: go\n\n      - name: Setup Node.js environment\n        uses: actions/setup-node@v3\n        with:\n          node-version: 18\n\n      - name: Setup Deno 1.40.0\n        uses: denoland/setup-deno@main\n        with:\n          deno-version: v1.40.0\n\n      - name: go test\n        run: go test -race ./internal/...\n\n      - name: go vet\n        run: go vet ./cmd/... ./internal/... ./pkg/...\n\n      - name: Deno Tests (non-Windows)\n        if: matrix.os != 'windows-latest'\n        run: make test-deno\n\n      - name: Deno Tests (Windows)\n        if: matrix.os == 'windows-latest'\n        run: make test-deno-windows\n\n      - name: Test for path/filepath\n        if: matrix.os == 'ubuntu-latest'\n        run: make no-filepath\n\n      - name: Make sure \"check-go-version\" works (non-Windows)\n        if: matrix.os != 'windows-latest'\n        run: make check-go-version\n\n      - name: go fmt\n        if: matrix.os == 'macos-latest'\n        run: make fmt-go\n\n      - name: npm ci\n        run: cd scripts && npm ci\n\n      - name: Register Test (ESBUILD_WORKER_THREADS=0, non-Windows)\n        if: matrix.os != 'windows-latest'\n        run: ESBUILD_WORKER_THREADS=0 node scripts/register-test.js\n\n      - name: Register Test\n        run: node scripts/register-test.js\n\n      - name: Verify Source Map\n        run: node scripts/verify-source-map.js\n\n      - name: E2E Tests\n        run: node scripts/end-to-end-tests.js\n\n      - name: JS API Tests (ESBUILD_WORKER_THREADS=0, non-Windows)\n        if: matrix.os != 'windows-latest'\n        run: ESBUILD_WORKER_THREADS=0 node scripts/js-api-tests.js\n\n      - name: JS API Tests\n        run: node scripts/js-api-tests.js\n\n      - name: NodeJS Unref Tests\n        run: node scripts/node-unref-tests.js\n\n      - name: Plugin Tests\n        run: node scripts/plugin-tests.js\n\n      - name: TypeScript Type Definition Tests\n        if: matrix.os == 'ubuntu-latest'\n        run: node scripts/ts-type-tests.js\n\n      - name: JS API Type Check\n        if: matrix.os == 'ubuntu-latest'\n        run: make lib-typecheck\n\n      - name: Decorator Tests\n        if: matrix.os == 'ubuntu-latest'\n        run: make decorator-tests\n\n      - name: WebAssembly API Tests (browser)\n        if: matrix.os == 'ubuntu-latest'\n        run: make test-wasm-browser\n\n      - name: WebAssembly API Tests (node, Linux)\n        if: matrix.os == 'ubuntu-latest'\n        run: make test-wasm-node\n\n      - name: WebAssembly API Tests (node, non-Linux)\n        if: matrix.os != 'ubuntu-latest'\n        run: node scripts/wasm-tests.js\n\n      - name: Sucrase Tests\n        if: matrix.os == 'ubuntu-latest'\n        run: make test-sucrase\n\n      - name: Esprima Tests\n        if: matrix.os == 'ubuntu-latest'\n        run: make test-esprima\n\n      - name: Preact Splitting Tests\n        if: matrix.os == 'ubuntu-latest'\n        run: make test-preact-splitting\n\n      - name: Check the unicode table generator\n        if: matrix.os == 'ubuntu-latest'\n        run: cd scripts && node gen-unicode-table.js\n\n      - name: Yarn PnP tests\n        run: |\n          # Note that Yarn recently deliberately broke \"npm install -g yarn\".\n          # They say you now have to run \"corepack enable\" to fix it. They have\n          # written about this here: https://yarnpkg.com/corepack\n          corepack enable\n\n          make test-yarnpnp\n\n  esbuild-old-go-version:\n    name: esbuild CI (old Go version)\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Set up Go 1.13 (the minimum required Go version for esbuild)\n        uses: actions/setup-go@v3\n        with:\n          go-version: 1.13\n        id: go\n\n      - name: go build\n        run: go build ./cmd/esbuild\n\n      - name: go test\n        run: go test ./internal/...\n\n      - name: make test-old-ts\n        run: make test-old-ts\n\n  esbuild-old-deno-version:\n    name: esbuild CI (old Deno version)\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        # Note: I'm excluding \"macos-latest\" here because GitHub recently\n        # changed their macOS CI VMs from x86_64 to aarch64 (i.e. from Intel\n        # to ARM) and it looks like old Deno versions have WASM bugs on ARM.\n        # Specifically, this test now crashes like this when run on macOS:\n        #\n        #   #\n        #   # Fatal error in , line 0\n        #   # Check failed: RwxMemoryWriteScope::IsAllowed().\n        #   #\n        #   #\n        #   #\n        #   #FailureMessage Object: 0x16f282368\n        #   ==== C stack trace ===============================\n        #\n        #       0   deno                                0x0000000101bb8e78 v8::base::debug::StackTrace::StackTrace() + 24\n        #       1   deno                                0x0000000101bbda84 v8::platform::(anonymous namespace)::PrintStackTrace() + 24\n        #       2   deno                                0x0000000101bb6230 V8_Fatal(char const*, ...) + 268\n        #       3   deno                                0x000000010227e468 v8::internal::wasm::WasmCodeManager::MemoryProtectionKeysEnabled() const + 0\n        #       4   deno                                0x0000000102299994 v8::internal::wasm::WasmEngine::InitializeOncePerProcess() + 44\n        #       5   deno                                0x0000000101e78fd0 v8::internal::V8::Initialize() + 1576\n        #       6   deno                                0x0000000101c3b7d8 v8::V8::Initialize(int) + 32\n        #       7   deno                                0x00000001011833dc _ZN3std4sync4once4Once9call_once28_$u7b$$u7b$closure$u7d$$u7d$17h2bbe74d315ab3e84E + 488\n        #       8   deno                                0x00000001017f8854 std::sync::once::Once::call_inner::h70fbdd48fe002a01 + 724\n        #       9   deno                                0x000000010115ca80 deno_core::runtime::JsRuntime::new::h9c5f1a9c910f1eed + 192\n        #       10  deno                                0x00000001014d3b50 deno_runtime::worker::MainWorker::bootstrap_from_options::h91a0eaac48dfc18e + 4260\n        #       11  deno                                0x0000000100ee692c deno::create_main_worker::h0d1622755821ae7f + 1608\n        #       12  deno                                0x0000000100f6c688 _ZN97_$LT$core..future..from_generator..GenFuture$LT$T$GT$$u20$as$u20$core..future..future..Future$GT$4poll17h87ddfac9566887c8E + 492\n        #       13  deno                                0x0000000100f6ba18 tokio::runtime::task::raw::poll::h7d51f1a7d5a61c15 + 1396\n        #       14  deno                                0x0000000101917b98 std::sys_common::backtrace::__rust_begin_short_backtrace::hd384935dcffe6f2d + 332\n        #       15  deno                                0x0000000101917954 _ZN4core3ops8function6FnOnce40call_once$u7b$$u7b$vtable.shim$u7d$$u7d$17he2755732d5d29cf0E + 124\n        #       16  deno                                0x0000000101829684 std::sys::unix::thread::Thread::new::thread_start::h432bc30153e41f60 + 48\n        #       17  libsystem_pthread.dylib             0x000000018a436f94 _pthread_start + 136\n        #       18  libsystem_pthread.dylib             0x000000018a431d34 thread_start + 8\n        #\n        # Hopefully running this old Deno version on Linux is sufficiently\n        # close to running it on macOS. For reference, I believe this is the\n        # change that GitHub made which broke this test:\n        # https://github.blog/changelog/2023-10-02-github-actions-apple-silicon-m1-macos-runners-are-now-available-in-public-beta/\n        os: [ubuntu-latest, windows-latest]\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Read go.version (non-Windows)\n        if: matrix.os != 'windows-latest'\n        run: |\n          echo \"GO_VERSION=$(cat go.version)\" >> $GITHUB_ENV\n\n      - name: Read go.version (Windows)\n        if: matrix.os == 'windows-latest'\n        run: |\n          echo \"GO_VERSION=$(cat go.version)\" >> $Env:GITHUB_ENV\n\n      - name: Set up Go 1.x\n        uses: actions/setup-go@v3\n        with:\n          go-version: ${{ env.GO_VERSION }}\n        id: go\n\n      # Make sure esbuild works with old versions of Deno. Note: It's important\n      # to test a version before 1.31.0, which introduced the \"Deno.Command\" API.\n      - name: Setup Deno 1.24.0\n        uses: denoland/setup-deno@main\n        with:\n          deno-version: v1.24.0\n\n      - name: Setup Node.js environment\n        uses: actions/setup-node@v3\n        with:\n          node-version: 18\n\n      - name: Deno Tests (non-Windows)\n        if: matrix.os != 'windows-latest'\n        run: make test-deno\n\n      - name: Deno Tests (Windows)\n        if: matrix.os == 'windows-latest'\n        run: make test-deno-windows\n"
  },
  {
    "path": ".github/workflows/e2e.yml",
    "content": "name: End-to-end install tests\n\non:\n  schedule:\n    - cron: '0 */6 * * *'\n  workflow_dispatch:\n\npermissions:\n  contents: read  #  to fetch code (actions/checkout)\n\njobs:\n  validate:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Setup Node.js environment\n        uses: actions/setup-node@v3\n        with:\n          node-version: 18\n\n      # The version of Deno is pinned because version 1.25.1 was causing test\n      # flakes due to random segfaults.\n      - name: Setup Deno 1.24.0\n        uses: denoland/setup-deno@main\n        with:\n          deno-version: v1.24.0\n\n      - name: Test npm\n        run: |\n          npm i -g npm@next-7\n          time make test-e2e-npm\n\n      - name: Test pnpm\n        run: |\n          npm i -g pnpm@next-7\n          time make test-e2e-pnpm\n\n      - name: Test yarn (classic)\n        run: |\n          npm i -g yarn@latest\n          time make test-e2e-yarn\n\n      - name: Test yarn (berry)\n        run: |\n          npm i -g yarn@latest\n          time make test-e2e-yarn-berry\n\n      - name: Test deno\n        run: |\n          time make test-e2e-deno\n"
  },
  {
    "path": ".github/workflows/publish.yml",
    "content": "name: Publish\n\npermissions:\n  id-token: write\n  contents: write\n\non:\n  push:\n    branches:\n      - main\n    paths:\n      - version.txt\n\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Read version info\n        run: |\n          echo \"GO_VERSION=$(cat go.version)\" >> $GITHUB_ENV\n          echo \"ESBUILD_VERSION=$(cat version.txt)\" >> $GITHUB_ENV\n\n      # This is here to fail quickly if the release already exists\n      - name: Try to create the \"v${{ env.ESBUILD_VERSION }}\" tag\n        run: |\n          git fetch --tags\n          git tag \"v$ESBUILD_VERSION\"\n\n      - name: Extract the release notes\n        run: |\n          CHANGELOG=$(awk -v \"ver=$ESBUILD_VERSION\" '/^## / { if (p) { exit }; if ($2 == ver) { p=1; next} } p' CHANGELOG.md)\n          echo \"CHANGELOG<<EOF\" >> $GITHUB_ENV\n          echo \"$CHANGELOG\" >> $GITHUB_ENV\n          echo \"EOF\" >> $GITHUB_ENV\n\n      # Make sure we'll be able to generate release notes later on below\n      - name: Release notes must not be empty\n        run: |\n          test -n \"$CHANGELOG\"\n\n      - name: Set up Go ${{ env.GO_VERSION }}\n        uses: actions/setup-go@v3\n        with:\n          go-version: ${{ env.GO_VERSION }}\n\n      - name: Setup Node.js environment\n        uses: actions/setup-node@v3\n        with:\n          node-version: 24\n\n      # This updates the version in all \"package.json\" files\n      - name: Build for all platforms\n        run: |\n          make platform-all\n\n      # All \"package.json\" files should have been updated already by running \"make platform-all\" and committing the results\n      - name: Reject uncommitted/untracked changes\n        run: |\n          git status --porcelain\n          test -z \"$(git status --porcelain)\"\n\n      # Trusted publishing requires this specific version of npm\n      - name: Install npm\n        run: |\n          npm install -g npm@11.5.1\n\n      - name: Publish packages\n        run: |\n          make publish-all\n\n      - name: Push the tag to GitHub\n        run: |\n          git push origin tag \"v$ESBUILD_VERSION\"\n\n      # Only do this after publishing was successful\n      - name: Create a GitHub Release\n        uses: actions/create-release@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          tag_name: v${{ env.ESBUILD_VERSION }}\n          release_name: v${{ env.ESBUILD_VERSION }}\n          body: ${{ env.CHANGELOG }}\n          draft: false\n          prerelease: false\n"
  },
  {
    "path": ".github/workflows/validate.yml",
    "content": "name: Validate release builds\n\non:\n  push:\n    tags: ['v*']\n  workflow_dispatch:\n\npermissions:\n  contents: read  #  to fetch code (actions/checkout)\n\njobs:\n  release:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Read go.version\n        run: |\n          echo \"GO_VERSION=$(cat go.version)\" >> $GITHUB_ENV\n\n      - name: Set up Go 1.x\n        uses: actions/setup-go@v3\n        with:\n          go-version: ${{ env.GO_VERSION }}\n        id: go\n\n      - name: Validation checks\n        run: |\n          make validate-builds\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\n.idea/\n.vscode/\n/bench/\n/demo/\n/deno/\n/esbuild\n/github/\n/go/\n/lib/deno/lib.deno.d.ts\n/npm/@esbuild/android-arm/esbuild.wasm\n/npm/@esbuild/android-arm/wasm_exec_node.js\n/npm/@esbuild/android-arm/wasm_exec.js\n/npm/@esbuild/android-x64/esbuild.wasm\n/npm/@esbuild/android-x64/wasm_exec_node.js\n/npm/@esbuild/android-x64/wasm_exec.js\n/npm/@esbuild/openharmony-arm64/esbuild.wasm\n/npm/@esbuild/openharmony-arm64/wasm_exec_node.js\n/npm/@esbuild/openharmony-arm64/wasm_exec.js\n/npm/@esbuild/wasi-preview1/esbuild.wasm\n/npm/esbuild-wasm/browser.js\n/npm/esbuild-wasm/esbuild.wasm\n/npm/esbuild-wasm/esm/\n/npm/esbuild-wasm/lib/\n/npm/esbuild-wasm/wasm_exec_node.js\n/npm/esbuild-wasm/wasm_exec.js\n/npm/esbuild/install.js\n/npm/esbuild/lib/\n/require/*/bench/\n/require/*/demo/\n/scripts/.*/\n/validate/\n/www\nbin\nesbuild.exe\nnode_modules/\n"
  },
  {
    "path": "CHANGELOG-2020.md",
    "content": "# Changelog: 2020\n\nThis changelog documents all esbuild versions published in the year 2020 (versions 0.3.0 through 0.8.28).\n\n## 0.8.28\n\n* Add a `--summary` flag that prints helpful information after a build ([#631](https://github.com/evanw/esbuild/issues/631))\n\n    Normally esbuild's CLI doesn't print anything after doing a build if nothing went wrong. This allows esbuild to be used as part of a more complex chain of tools without the output cluttering the terminal. However, sometimes it is nice to have a quick overview in your terminal of what the build just did. You can now add the `--summary` flag when using the CLI and esbuild will print a summary of what the build generated. It looks something like this:\n\n    ```\n    $ ./esbuild --summary --bundle src/Three.js --outfile=build/three.js --sourcemap\n\n      build/three.js      1.0mb ⚠️\n      build/three.js.map  1.8mb\n\n    ⚡ Done in 43ms\n    ```\n\n* Keep unused imports in TypeScript code in one specific case ([#604](https://github.com/evanw/esbuild/issues/604))\n\n    The official TypeScript compiler always removes imported symbols that aren't used as values when converting TypeScript to JavaScript. This is because these symbols could be types and not removing them could result in a run-time module instantiation failure because of missing exports. This even happens when the `tsconfig.json` setting `\"importsNotUsedAsValues\"` is set to `\"preserve\"`. Doing this just keeps the import statement itself but confusingly still removes the imports that aren't used as values.\n\n    Previously esbuild always exactly matched the behavior of the official TypeScript compiler regarding import removal. However, that is problematic when trying to use esbuild to compile a partial module such as when converting TypeScript to JavaScript inside a file written in the [Svelte](https://svelte.dev/) programming language. Here is an example:\n\n    ```html\n    <script lang=\"ts\">\n      import Counter from './Counter.svelte';\n      export let name: string = 'world';\n    </script>\n    <main>\n      <h1>Hello {name}!</h1>\n      <Counter />\n    </main>\n    ```\n\n    The current Svelte compiler plugin for TypeScript only provides esbuild with the contents of the `<script>` tag so to esbuild, the import `Counter` appears to be unused and is removed.\n\n    In this release, esbuild deliberately deviates from the behavior of the official TypeScript compiler if all of these conditions are met:\n\n    * The `\"importsNotUsedAsValues\"` field in `tsconfig.json` must be present and must not be set to `\"remove\"`. This is necessary because this is the only case where esbuild can assume that all imports are values instead of types. Any imports that are types will cause a type error when the code is run through the TypeScript type checker. To import types when the `importsNotUsedAsValues` setting is active, you must use the TypeScript-specific `import type` syntax instead.\n\n    * You must not be using esbuild as a bundler. When bundling, esbuild needs to assume that it's not seeing a partial file because the bundling process requires renaming symbols to avoid cross-file name collisions.\n\n    * You must not have identifier minification enabled. It's useless to preserve unused imports in this case because referencing them by name won't work anyway. And keeping the unused imports would be counter-productive to minification since they would be extra unnecessary data in the output file.\n\n    This should hopefully allow esbuild to be used as a TypeScript-to-JavaScript converter for programming languages such as Svelte, at least in many cases. The build pipeline in esbuild wasn't designed for compiling partial modules and this still won't be a fully robust solution (e.g. some variables may be renamed to avoid name collisions in rare cases). But it's possible that these cases are very unlikely to come up in practice. Basically this change to keep unused imports in this case should be useful at best and harmless at worst.\n\n## 0.8.27\n\n* Mark `import.meta` as supported in node 10.4+ ([#626](https://github.com/evanw/esbuild/issues/626))\n\n    It was previously marked as unsupported due to a typo in esbuild's compatibility table, which meant esbuild generated a shim for `import.meta` even when it's not necessary. It should now be marked as supported in node 10.4 and above so the shim will no longer be included when using a sufficiently new target environment such as `--target=node10.4`.\n\n* Fix for when the working directory ends with `/` ([#627](https://github.com/evanw/esbuild/issues/627))\n\n    If the working directory ended in `/`, the last path component would be incorrectly duplicated. This was the case when running esbuild with Yarn 2 (but not Yarn 1) and is problematic because some externally-facing directories reference the current working directory in plugins and in output files. The problem has now been fixed and the last path component is no longer duplicated in this case. This fix was contributed by [@remorses](https://github.com/remorses).\n\n* Add an option to omit `sourcesContent` from generated source maps ([#624](https://github.com/evanw/esbuild/issues/624))\n\n    You can now pass `--sources-content=false` to omit the `sourcesContent` field from generated source maps. The field embeds the original source code inline in the source map and is the largest part of the source map. This is useful if you don't need the original source code and would like a smaller source map (e.g. you only care about stack traces and don't need the source code for debugging).\n\n* Fix exports from ESM files converted to CJS during code splitting ([#617](https://github.com/evanw/esbuild/issues/617))\n\n    This release fixes an edge case where files in ECMAScript module format that are converted to CommonJS format during bundling can generate exports to non-top-level symbols when code splitting is active. These files must be converted to CommonJS format if they are referenced by a `require()` call. When that happens, the symbols in that file are placed inside the CommonJS wrapper closure and are no longer top-level symbols. This means they should no longer be considered exportable for cross-chunk export generation due to code splitting. The result of this fix is that these cases no longer generate output files with module instantiation errors.\n\n* Allow `--define` with array and object literals ([#581](https://github.com/evanw/esbuild/issues/581))\n\n    The `--define` feature allows you to replace identifiers such as `DEBUG` with literal expressions such as `false`. This is valuable because the substitution can then participate in constant folding and dead code elimination. For example, `if (DEBUG) { ... }` could become `if (false) { ... }` which would then be completely removed in minified builds. However, doing this with compound literal expressions such as array and object literals is an anti-pattern because it could easily result in many copies of the same object in the output file.\n\n    This release adds support for array and object literals with `--define` anyway, but they work differently than other `--define` expressions. In this case a separate virtual file is created and configured to be injected into all files similar to how the `--inject` feature works. This means there is only at most one copy of the value in a given output file. However, these values do not participate in constant folding and dead code elimination, since the object can now potentially be mutated at run-time.\n\n## 0.8.26\n\n* Ensure the current working directory remains unique per `startService()` call\n\n    The change in version 0.8.24 to share service instances caused problems for code that calls `process.chdir()` before calling `startService()` to be able to get a service with a different working directory. With this release, calls to `startService()` no longer share the service instance if the working directory was different at the time of creation.\n\n* Consider import references to be side-effect free ([#613](https://github.com/evanw/esbuild/issues/613))\n\n    This change improves tree shaking for code containing top-level references to imported symbols such as the following code:\n\n    ```js\n    import {Base} from './base'\n    export class Derived extends Base {}\n    ```\n\n    Identifier references are considered side-effect free if they are locally-defined, but esbuild special-cases identifier references to imported symbols in its AST (the identifier `Base` in this example). This meant they did not trigger this check and so were not considered locally-defined and therefore side-effect free. That meant that `Derived` in this example would never be tree-shaken.\n\n    The reason for this is that the side-effect determination is made during parsing and during parsing it's not yet known if `./base` is a CommonJS module or not. If it is, then `Base` would be a dynamic run-time property access on `exports.Base` which could hypothetically be a property with a getter that has side effects. Therefore it could be considered incorrect to remove this code due to tree-shaking because there is technically a side effect.\n\n    However, this is a very unlikely edge case and not tree-shaking this code violates developer expectations. So with this release, esbuild will always consider references to imported symbols as being side-effect free. This also aligns with ECMAScript module semantics because with ECMAScript modules, it's impossible to have a user-defined getter for an imported symbol. This means esbuild will now tree-shake unused code in cases like this.\n\n* Warn about calling an import namespace object\n\n    The following code is an invalid use of an import statement:\n\n    ```js\n    import * as express from \"express\"\n    express()\n    ```\n\n    The `express` symbol here is an import namespace object, not a function, so calling it will fail at run-time. This code should have been written like this instead:\n\n    ```js\n    import express from \"express\"\n    express()\n    ```\n\n    This comes up because for legacy reasons, the TypeScript compiler defaults to a compilation mode where the `import * as` statement is converted to `const express = require(\"express\")` which means you can actually call `express()` successfully. Doing this is incompatible with standard ECMAScript module environments such as the browser, node, and esbuild because an import namespace object is never a function. The TypeScript compiler has a setting to disable this behavior called `esModuleInterop` and they highly recommend applying it both to new and existing projects to avoid these compatibility problems. See [the TypeScript documentation](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#support-for-import-d-from-cjs-from-commonjs-modules-with---esmoduleinterop) for more information.\n\n    With this release, esbuild will now issue a warning when you do this. The warning indicates that your code will crash when run and that your code should be fixed.\n\n## 0.8.25\n\n* Fix a performance regression from version 0.8.4 specific to Yarn 2\n\n    Code using esbuild's `transformSync` function via Yarn 2 experienced a dramatic slowdown in esbuild version 0.8.4 and above. This version added a wrapper script to fix Yarn 2's incompatibility with binary packages. Some code that tries to avoid unnecessarily calling into the wrapper script contained a bug that caused it to fail, which meant that using `transformSync` with Yarn 2 called into the wrapper script unnecessarily. This launched an extra node process every time the esbuild executable was invoked which can be over 6x slower than just invoking the esbuild executable directly. This release should now invoke the esbuild executable directly without going through the wrapper script, which fixes the performance regression.\n\n* Fix a size regression from version 0.7.9 with certain source maps ([#611](https://github.com/evanw/esbuild/issues/611))\n\n    Version 0.7.9 added a new behavior to esbuild where in certain cases a JavaScript file may be split into multiple pieces during bundling. Pieces of the same input file may potentially end up in multiple discontiguous regions in the output file. This was necessary to fix an import ordering bug with CommonJS modules. However, it had the side effect of duplicating that file's information in the resulting source map. This didn't affect source map correctness but it made source maps unnecessarily large. This release corrects the problem by ensuring that a given file's information is only ever represented once in the corresponding source map.\n\n## 0.8.24\n\n* Share reference-counted service instances internally ([#600](https://github.com/evanw/esbuild/issues/600))\n\n    Now calling `startService()` multiple times will share the underlying esbuild child process as long as the lifetimes of the service objects overlap (i.e. the time from `startService()` to `service.stop()`). This is just an internal change; there is no change to the public API. It should result in a faster implementation that uses less memory if your code calls `startService()` multiple times. Previously each call to `startService()` generated a separate esbuild child process.\n\n* Fix re-exports of a side-effect free CommonJS module ([#605](https://github.com/evanw/esbuild/issues/605))\n\n    This release fixes a regression introduced in version 0.8.19 in which an `import` of an `export {...} from` re-export of a CommonJS module does not include the CommonJS module if it has been marked as `\"sideEffects\": false` in its `package.json` file. This was the case with the [Ramda](https://ramdajs.com/) library, and was due to an unhandled case in the linker.\n\n* Optionally take binary executable path from environment variable ([#592](https://github.com/evanw/esbuild/issues/592))\n\n    You can now set the `ESBUILD_BINARY_PATH` environment variable to cause the JavaScript API to use a different binary executable path. This is useful if you want to substitute a modified version of the `esbuild` binary that contains some extra debugging information. This feature was contributed by [@remorses](https://github.com/remorses).\n\n## 0.8.23\n\n* Fix non-string objects being passed to `transformSync` ([#596](https://github.com/evanw/esbuild/issues/596))\n\n    The transform function is only supposed to take a string. The type definitions also specify that the input must be a string. However, it happened to convert non-string inputs to a string and some code relied on that behavior. A change in 0.8.22 broke that behavior for `transformSync` specifically for `Uint8Array` objects, which became an array of numbers instead of a string. This release ensures that the conversion to a string is done up front to avoid something unexpected happening in the implementation. Future releases will likely enforce that the input is a string and throw an error otherwise.\n\n* Revert the speedup to `transformSync` and `buildSync` ([#595](https://github.com/evanw/esbuild/issues/595))\n\n    This speedup relies on the `worker_threads` module in node. However, when esbuild is used via `node -r` as in `node -r esbuild-register file.ts`, the worker thread created by esbuild somehow ends up being completely detached from the main thread. This may be a bug in node itself. Regardless, the approach esbuild was using to improve speed doesn't work in all cases so it has been reverted. It's unclear if it's possible to work around this issue. This approach for improving the speed of synchronous APIs may be a dead end.\n\n## 0.8.22\n\n* Escape fewer characters in virtual module paths ([#588](https://github.com/evanw/esbuild/issues/588))\n\n    If a module's path is not in the `file` namespace (i.e. it was created by a plugin), esbuild doesn't assume it's a file system path. The meaning of these paths is entirely up to the plugin. It could be anything including a HTTP URL, a string of code, or randomly-generated characters.\n\n    Currently esbuild generates a file name for these virtual modules using an internal \"human-friendly identifier\" that can also be used as a valid JavaScript identifier, which is sometimes used to for example derive the name of the default export of a bundled module. But that means virtual module paths which _do_ happen to represent file system paths could cause more characters to be escaped than necessary. For example, esbuild escapes `-` to `_` because `-` is not valid in a JavaScript identifier.\n\n    This release separates the file names derived from virtual module paths from the internal \"human-friendly identifier\" concept. Characters in the virtual module path that are valid in file paths are no longer escaped.\n\n    In the future the output file name of a virtual module will likely be completely customizable with a plugin, so it will be possible to have different behavior for this if desired. But that isn't possible quite yet.\n\n* Speed up the JavaScript `buildSync` and `transformSync` APIs ([#590](https://github.com/evanw/esbuild/issues/590))\n\n    Previously the `buildSync` and `transformSync` API calls created a new child esbuild process on every call because communicating with a long-lived child process is asynchronous in node. However, there's a trick that can work around this limitation: esbuild can communicate with the long-lived child process from a child thread using node's [`worker_threads`](https://nodejs.org/api/worker_threads.html) module and block the main thread using JavaScript's new [Atomics API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/wait). This was a tip from [@cspotcode](https://github.com/cspotcode).\n\n    This approach has now been implemented. A quick benchmark shows that `transformSync` is now **1.5x to 15x faster** than it used to be. The speedup depends on the size of the input (smaller inputs get a bigger speedup). The worker thread and child process should automatically be terminated when there are no more event handlers registered on the main thread, so there is no explicit `stop()` call like there is with a service object.\n\n* Distribute a 32-bit Linux ARM binary executable via npm ([#528](https://github.com/evanw/esbuild/issues/528))\n\n    You should now be able to use npm to install esbuild on a 32-bit Linux ARM device. This lets you run esbuild on a Raspberry Pi. Note that this target isn't officially supported because it's not covered by any automated tests.\n\n## 0.8.21\n\n* On-resolve plugins now apply to entry points ([#546](https://github.com/evanw/esbuild/issues/546))\n\n    Previously entry points were required to already be resolved to valid file system paths. This meant that on-resolve plugins didn't run, which breaks certain workflows. Now entry point paths are resolved using normal import resolution rules.\n\n    To avoid making this a breaking change, there is now special behavior for entry point path resolution. If the entry point path exists relative to the current working directory and the path does not start with `./` or `../`, esbuild will now automatically insert a leading `./` at the start of the path to prevent the path from being interpreted as a `node_modules` package path. This is only done if the file actually exists to avoid introducing `./` for paths with special plugin-specific syntax.\n\n* Enable the build API in the browser ([#527](https://github.com/evanw/esbuild/issues/527))\n\n    Previously you could only use the transform API in the browser, not the build API. You can now use the build API in the browser too. There is currently no in-browser file system so the build API will not do anything by default. Using this API requires you to use plugins to provide your own file system. Instructions for running esbuild in the browser can be found here: https://esbuild.github.io/api/#running-in-the-browser.\n\n* Set the importer to `sourcefile` in on-resolve plugins for stdin\n\n    When the stdin feature is used with on-resolve plugins, the importer for any import paths in stdin is currently always set to `<stdin>`. The `sourcefile` option provides a way to set the file name of stdin but it wasn't carried through to on-resolve plugins due to an oversight. This release changes this behavior so now `sourcefile` is used instead of `<stdin>` if present. In addition, if the stdin resolve directory is also specified the importer will be placed in the `file` namespace similar to a normal file.\n\n## 0.8.20\n\n* Fix an edge case with class body initialization\n\n    When bundling, top-level class statements are rewritten to variable declarations initialized to a class expression. This avoids a severe performance pitfall in Safari when there are a large number of class statements. However, this transformation was done incorrectly if a class contained a static field that references the class name in its own initializer:\n\n    ```js\n    class Foo {\n      static foo = new Foo\n    }\n    ```\n\n    In that specific case, the transformed code could crash when run because the class name is not yet initialized when the static field initializer is run. Only JavaScript code was affected. TypeScript code was not affected. This release fixes this bug.\n\n* Remove more types of statements as dead code ([#580](https://github.com/evanw/esbuild/issues/580))\n\n    This change improves dead-code elimination in the case where unused statements follow an unconditional jump, such as a `return`:\n\n    ```js\n    if (true) return\n    if (something) thisIsDeadCode()\n    ```\n\n    These unused statements are removed in more cases than in the previous release. Some statements may still be kept that contain hoisted symbols (`var` and `function` statements) because they could potentially impact the code before the conditional jump.\n\n## 0.8.19\n\n* Handle non-ambiguous multi-path re-exports ([#568](https://github.com/evanw/esbuild/pull/568))\n\n    Wildcard re-exports using the `export * from 'path'` syntax can potentially result in name collisions that cause an export name to be ambiguous. For example, the following code would result in an ambiguous export if both `a.js` and `b.js` export a symbol with the same name:\n\n    ```js\n    export * from './a.js'\n    export * from './b.js'\n    ```\n\n    Ambiguous exports have two consequences. First, any ambiguous names are silently excluded from the set of exported names. If you use an `import * as` wildcard import, the excluded names will not be present. Second, attempting to explicitly import an ambiguous name using an `import {} from` import clause will result in a module instantiation error.\n\n    This release fixes a bug where esbuild could in certain cases consider a name ambiguous when it actually isn't. Specifically this happens with longer chains of mixed wildcard and named re-exports. Here is one such case:\n\n    ```js\n    // entry.js\n    import {x, y} from './not-ambiguous.js'\n    console.log(x, y)\n    ```\n\n    ```js\n    // /not-ambiguous.js\n    export * from './a.js'\n    export * from './b.js'\n    ```\n\n    ```js\n    // /a.js\n    export * from './c.js'\n    ```\n\n    ```js\n    // /b.js\n    export {x} from './c.js'\n    ```\n\n    ```js\n    // /c.js\n    export let x = 1, y = 2\n    ```\n\n    Previously bundling `entry.js` with esbuild would incorrectly generate an error about an ambiguous `x` export. Now this case builds successfully without an error.\n\n* Omit warnings about non-string paths in `await import()` inside a `try` block ([#574](https://github.com/evanw/esbuild/issues/574))\n\n    Bundling code that uses `require()` or `import()` with a non-string path currently generates a warning, because the target of that import will not be included in the bundle. This is helpful to warn about because other bundlers handle this case differently (e.g. Webpack bundles the entire directory tree and emulates a file system lookup) so existing code may expect the target of the import to be bundled.\n\n    You can avoid the warning with esbuild by surrounding the call to `require()` with a `try` block. The thinking is that if there is a surrounding `try` block, presumably the code is expecting the `require()` call to possibly fail and is prepared to handle the error. However, there is currently no way to avoid the warning for `import()` expressions. This release introduces an analogous behavior for `import()` expressions. You can now avoid the warning with esbuild if you use `await import()` and surround it with a `try` block.\n\n## 0.8.18\n\n* Fix a bug with certain complex optional chains ([#573](https://github.com/evanw/esbuild/issues/573))\n\n    The `?.` optional chaining operator only runs the right side of the operator if the left side is undefined, otherwise it returns undefined. This operator can be applied to both property accesses and function calls, and these can be combined into long chains of operators. These expressions must be transformed to a chain of `?:` operators if the `?.` operator isn't supported in the configured target environment. However, esbuild had a bug where an optional call of an optional property with a further property access afterward didn't preserve the value of `this` for the call. This bug has been fixed.\n\n* Fix a renaming bug with external imports\n\n    There was a possibility of a cross-module name collision while bundling in a certain edge case. Specifically, when multiple files both contained an `import` statement to an external module and then both of those files were imported using `require`. For example:\n\n    ```js\n    // index.js\n    console.log(require('./a.js'), require('./b.js'))\n    ```\n\n    ```js\n    // a.js\n    export {exists} from 'fs'\n    ```\n\n    ```js\n    // b.js\n    export {exists} from 'fs'\n    ```\n\n    In this case the files `a.js` and `b.js` are converted to CommonJS format so they can be imported using `require`:\n\n    ```js\n    // a.js\n    import {exists} from \"fs\";\n    var require_a = __commonJS((exports) => {\n      __export(exports, {\n        exists: () => exists\n      });\n    });\n\n    // b.js\n    import {exists} from \"fs\";\n    var require_b = __commonJS((exports) => {\n      __export(exports, {\n        exists: () => exists\n      });\n    });\n\n    // index.js\n    console.log(require_a(), require_b());\n    ```\n\n    However, the `exists` symbol has been duplicated without being renamed. This is will result in a syntax error at run-time. The reason this happens is that the statements in the files `a.js` and `b.js` are placed in a nested scope because they are inside the CommonJS closure. The `import` statements were extracted outside the closure but the symbols they declared were incorrectly not added to the outer scope. This problem has been fixed, and this edge case should no longer result in name collisions.\n\n## 0.8.17\n\n* Get esbuild working on the Apple M1 chip via Rosetta 2 ([#564](https://github.com/evanw/esbuild/pull/564))\n\n    The Go compiler toolchain does not yet support the new Apple M1 chip. Go version 1.15 is currently in a feature freeze period so support will be added in the next version, Go 1.16, which will be [released in February](https://blog.golang.org/11years#TOC_3.).\n\n    This release changes the install script to install the executable for macOS `x64` on macOS `arm64` too. Doing this should still work because of the executable translation layer built into macOS. This change was contributed by [@sod](https://github.com/sod).\n\n## 0.8.16\n\n* Improve TypeScript type definitions ([#559](https://github.com/evanw/esbuild/issues/559))\n\n    The return value of the `build` API has some optional fields that are undefined unless certain arguments are present. That meant you had to use the `!` null assertion operator to avoid a type error if you have the TypeScript `strictNullChecks` setting enabled in your project. This release adds additional type information so that if the relevant arguments are present, the TypeScript compiler can tell that these optional fields on the return value will never be undefined. This change was contributed by [@lukeed](https://github.com/lukeed).\n\n* Omit a warning about `require.main` when targeting CommonJS ([#560](https://github.com/evanw/esbuild/issues/560))\n\n    A common pattern in code that's intended to be run in node is to check if `require.main === module`. That will be true if the current file is being run from the command line but false if the current file is being run because some other code called `require()` on it. Previously esbuild generated a warning about an unexpected use of `require`. Now this warning is no longer generated for `require.main` when the output format is `cjs`.\n\n* Warn about defining `process.env.NODE_ENV` as an identifier ([#466](https://github.com/evanw/esbuild/issues/466))\n\n    The define feature can be used to replace an expression with either a JSON literal or an identifier. Forgetting to put quotes around a string turns it into an identifier, which is a common mistake. This release introduces a warning when you define `process.env.NODE_ENV` as an identifier instead of a string. It's very common to use define to replace `process.env.NODE_ENV` with either `\"production\"` or `\"development\"` and sometimes people accidentally replace it with `production` or `development` instead. This is worth warning about because otherwise there would be no indication that something is wrong until the code crashes when run.\n\n* Allow starting a local server at a specific host address ([#563](https://github.com/evanw/esbuild/pull/563))\n\n    By default, esbuild's local HTTP server is only available on the internal loopback address. This is deliberate behavior for security reasons, since the local network environment may not be trusted. However, it can be useful to run the server on a different address when developing with esbuild inside of a virtual machine/docker container or to request development assets from a remote testing device on the same network at a different IP address. With this release, you can now optionally specify the host in addition to the port:\n\n    ```\n    esbuild --serve=192.168.0.1:8000\n    ```\n\n    ```js\n    esbuild.serve({\n      host: '192.168.0.1',\n      port: 8000,\n    }, {\n      ...\n    })\n    ```\n\n    ```go\n    server, err := api.Serve(api.ServeOptions{\n      Host: \"192.168.0.1\",\n      Port: 8000,\n    }, api.BuildOptions{\n      ...\n    })\n    ```\n\n    This change was contributed by [@jamalc](https://github.com/jamalc).\n\n## 0.8.15\n\n* Allow `paths` without `baseUrl` in `tsconfig.json`\n\n    This feature was [recently released in TypeScript 4.1](https://devblogs.microsoft.com/typescript/announcing-typescript-4-1/#paths-without-baseurl). The `paths` feature in `tsconfig.json` allows you to do custom import path rewriting. For example, you can map paths matching `@namespace/*` to the path `./namespace/src/*` relative to the `tsconfig.json` file. Previously using the `paths` feature required you to additionally specify `baseUrl` so that the compiler could know which directory the path aliases were supposed to be relative to.\n\n    However, specifying `baseUrl` has the potentially-problematic side effect of causing all import paths to be looked up relative to the `baseUrl` directory, which could potentially cause package paths to accidentally be redirected to non-package files. Specifying `baseUrl` also causes Visual Studio Code's auto-import feature to generate paths relative to the `baseUrl` directory instead of relative to the directory containing the current file. There is more information about the problems this causes here: https://github.com/microsoft/TypeScript/issues/31869.\n\n    With TypeScript 4.1, you can now omit `baseUrl` when using `paths`. When you do this, it as if you had written `\"baseUrl\": \".\"` instead for the purpose of the `paths` feature, but the `baseUrl` value is not actually set and does not affect path resolution. These `tsconfig.json` files are now supported by esbuild.\n\n* Fix evaluation order issue with import cycles and CommonJS-style output formats ([#542](https://github.com/evanw/esbuild/issues/542))\n\n    Previously entry points involved in an import cycle could cause evaluation order issues if the output format was `iife` or `cjs` instead of `esm`. This happened because this edge case was handled by treating the entry point file as a CommonJS file, which extracted the code into a CommonJS wrapper. Here's an example:\n\n    Input files:\n\n    ```js\n    // index.js\n    import { test } from './lib'\n    export function fn() { return 42 }\n    if (test() !== 42) throw 'failure'\n    ```\n\n    ```js\n    // lib.js\n    import { fn } from './index'\n    export let test = fn\n    ```\n\n    Previous output (problematic):\n\n    ```js\n    // index.js\n    var require_esbuild = __commonJS((exports) => {\n      __export(exports, {\n        fn: () => fn2\n      });\n      function fn2() {\n        return 42;\n      }\n      if (test() !== 42)\n        throw \"failure\";\n    });\n\n    // lib.js\n    var index = __toModule(require_esbuild());\n    var test = index.fn;\n    module.exports = require_esbuild();\n    ```\n\n    This approach changed the evaluation order because the CommonJS wrapper conflates both binding and evaluation. Binding and evaluation need to be separated to correctly handle this edge case. This edge case is now handled by inlining what would have been the contents of the CommonJS wrapper into the entry point location itself.\n\n    Current output (fixed):\n\n    ```js\n    // index.js\n    __export(exports, {\n      fn: () => fn\n    });\n\n    // lib.js\n    var test = fn;\n\n    // index.js\n    function fn() {\n      return 42;\n    }\n    if (test() !== 42)\n      throw \"failure\";\n    ```\n\n## 0.8.14\n\n* Fix a concurrency bug caused by an error message change ([#556](https://github.com/evanw/esbuild/issues/556))\n\n    An improvement to the error message for path resolution was introduced in version 0.8.12. It detects when a relative path is being interpreted as a package path because you forgot to start the path with `./`:\n\n    ```\n     > src/posts/index.js: error: Could not resolve \"PostCreate\" (use \"./PostCreate\" to import \"src/posts/PostCreate.js\")\n        2 │ import PostCreate from 'PostCreate';\n          ╵                        ~~~~~~~~~~~~\n    ```\n\n    This is implemented by re-running path resolution for package path resolution failures as a relative path instead. Unfortunately, this second path resolution operation wasn't guarded by a mutex and could result in concurrency bugs. This issue only occurs when path resolution fails. It is fixed in this release.\n\n## 0.8.13\n\n* Assigning to a `const` symbol is now an error when bundling\n\n    This change was made because esbuild may need to change a `const` symbol into a non-constant symbol in certain situations. One situation is when the \"avoid TDZ\" option is enabled. Another situation is some potential upcoming changes to lazily-evaluate certain modules for code splitting purposes. Making this an error gives esbuild the freedom to do these code transformations without potentially causing problems where constants are mutated. This has already been a warning for a while so code that does this should already have been obvious. This warning was made an error in a patch release because the expectation is that no real code relies on this behavior outside of conformance tests.\n\n* Fix for the `--keep-names` option and anonymous lowered classes\n\n    This release fixes an issue where names were not preserved for anonymous classes that contained newer JavaScript syntax when targeting an older version of JavaScript. This was because that causes the class expression to be transformed into a sequence expression, which was then not recognized as a class expression. For example, the class did not have the name `foo` in the code below when the target was set to `es6`:\n\n    ```js\n    let foo = class {\n      #privateMethod() {}\n    }\n    ```\n\n    The `name` property of this class object is now `foo`.\n\n* Fix captured class names when class name is re-assigned\n\n    This fixes a corner case with class lowering to better match the JavaScript specification. In JavaScript, the body of a class statement contains an implicit constant symbol with the same name as the symbol of the class statement itself. Lowering certain class features such as private methods means moving them outside the class body, in which case the contents of the private method are no longer within the scope of the constant symbol. This can lead to a behavior change if the class is later re-assigned:\n\n    ```js\n    class Foo {\n      static test() { return this.#method() }\n      static #method() { return Foo }\n    }\n    let old = Foo\n    Foo = class Bar {}\n    console.log(old.test() === old) // This should be true\n    ```\n\n    Previously this would print `false` when transformed to ES6 by esbuild. This now prints `true`. The current transformed output looks like this:\n\n    ```js\n    var _method, method_fn;\n    const Foo2 = class {\n      static test() {\n        return __privateMethod(this, _method, method_fn).call(this);\n      }\n    };\n    let Foo = Foo2;\n    _method = new WeakSet();\n    method_fn = function() {\n      return Foo2;\n    };\n    _method.add(Foo);\n    let old = Foo;\n    Foo = class Bar {\n    };\n    console.log(old.test() === old);\n    ```\n\n* The `--allow-tdz` option is now always applied during bundling\n\n    This option turns top-level `let`, `const`, and `class` statements into `var` statements to work around some severe performance issues in the JavaScript run-time environment in Safari. Previously you had to explicitly enable this option. Now this behavior will always happen, and there is no way to turn it off. This means the `--allow-tdz` option is now meaningless and no longer does anything. It will be removed in a future release.\n\n* When bundling and minifying, `const` is now converted into `let`\n\n    This was done because it's semantically equivalent but shorter. It's a valid transformation because assignment to a `const` symbol is now a compile-time error when bundling, so changing `const` to `let` should now not affect run-time behavior.\n\n## 0.8.12\n\n* Added an API for incremental builds ([#21](https://github.com/evanw/esbuild/issues/21))\n\n    There is now an API for incremental builds. This is what using the API looks like from JavaScript:\n\n    ```js\n    require('esbuild').build({\n      entryPoints: ['app.js'],\n      bundle: true,\n      outfile: 'out.js',\n      incremental: true,\n    }).then(result => {\n      // The \"rebuild\" method is present if \"incremental\" is true. It returns a\n      // promise that resolves to the same kind of object that \"build\" returns.\n      // You can call \"rebuild\" as many times as you like.\n      result.rebuild().then(result2 => {\n        // Call \"dispose\" when you're done to free up resources.\n        result.rebuild.dispose()\n      })\n    })\n    ```\n\n    Using the API from Go is similar, except there is no need to manually dispose of the rebuild callback:\n\n    ```go\n    result := api.Build(api.BuildOptions{\n      EntryPoints: []string{\"app.js\"},\n      Bundle: true,\n      Outfile: \"out.js\",\n      Incremental: true,\n    })\n    result2 := result.Rebuild()\n    ```\n\n    Incremental builds are more efficient than regular builds because some data is cached and can be reused if the original files haven't changed since the last build. There are currently two forms of caching used by the incremental build API:\n\n    * Files are stored in memory and are not re-read from the file system if the file metadata hasn't changed since the last build. This optimization only applies to file system paths. It does not apply to virtual modules created by plugins.\n\n    * Parsed ASTs are stored in memory and re-parsing the AST is avoided if the file contents haven't changed since the last build. This optimization applies to virtual modules created by plugins in addition to file system modules, as long as the virtual module path remains the same.\n\n    This is just the initial release of the incremental build API. Incremental build times still have room for improvement. Right now esbuild still re-resolves, re-loads, and re-links everything even if none of the input files have changed. Improvements to the incremental build mechanism will be coming in later releases.\n\n* Support for a local file server ([#537](https://github.com/evanw/esbuild/issues/537))\n\n    You can now run esbuild with the `--serve` flag to start a local server that serves the output files over HTTP. This is intended to be used during development. You can point your `<script>` tag to a local server URL and your JavaScript and CSS files will be automatically built by esbuild whenever that URL is accessed. The server defaults to port 8000 but you can customize the port with `--serve=...`.\n\n    There is also an equivalent API for JavaScript:\n\n    ```js\n    require('esbuild').serve({\n      port: 8000,\n    },{\n      entryPoints: ['app.js'],\n      bundle: true,\n      outfile: 'out.js',\n    }).then(server => {\n      // Call \"stop\" on the server when you're done\n      server.stop()\n    })\n    ```\n\n    and for Go:\n\n    ```go\n    server, err := api.Serve(api.ServeOptions{\n      Port: 8000,\n    }, api.BuildOptions{\n      EntryPoints: []string{\"app.js\"},\n      Bundle:      true,\n      Outfile:     \"out.js\",\n    })\n\n    // Call \"stop\" on the server when you're done\n    server.Stop()\n    ```\n\n    This is a similar use case to \"watch mode\" in other tools where something automatically rebuilds your code when a file has changed on disk. The difference is that you don't encounter the problem where you make an edit, switch to your browser, and reload only to load the old files because the rebuild hasn't finished yet. Using a HTTP request instead of a file system access gives the rebuild tool the ability to delay the load until the rebuild operation has finished so your build is always up to date.\n\n* Install to a temporary directory for Windows ([#547](https://github.com/evanw/esbuild/issues/547))\n\n    The install script runs `npm` in a temporary directory to download the correct binary executable for the current architecture. It then removes the temporary directory after the installation. However, removing a directory is sometimes impossible on Windows. To work around this problem, the install script now installs to the system's temporary directory instead of a directory inside the project itself. That way it's not problematic if a directory is left behind by the install script. This change was contributed by [@Djaler](https://github.com/Djaler).\n\n* Fix the public path ending up in the metafile ([#549](https://github.com/evanw/esbuild/issues/549))\n\n    The change in version 0.8.7 to include the public path in import paths of code splitting chunks caused a regression where the public path was also included in the list of chunk imports in the metafile. This was unintentional. Now the public path setting should not affect the metafile contents.\n\n## 0.8.11\n\n* Fix parsing of casts in TypeScript followed by certain tokens\n\n    This aligns esbuild's TypeScript parser with the official TypeScript parser as far as parsing of `as` casts. It's not valid to form an expression after an `as` cast if the next token is a `(`, `[`, `++`, `--`, `?.`, assignment operator, or template literal. Previously esbuild wouldn't generate an error for these expressions. This is normally not a problem because the TypeScript compiler itself would reject the code as invalid. However, if the next token starts on a new line, that new token may be the start of another statement. In that case the code generated by esbuild was different than the code generated by the TypeScript compiler. This difference has been fixed.\n\n* Implement wildcards for external paths ([#406](https://github.com/evanw/esbuild/issues/406))\n\n    You can now use a `*` wildcard character with the `--external` option to mark all files matching a certain pattern as external, which will remove them from the bundle. For example, you can now do `--external:*.png` to remove all `.png` files. When a `*` wildcard character is present in an external path, that pattern will be applied to the original path in the source code instead of to the path after it has been resolved to a real file system path. This lets you match on paths that aren't real file system paths.\n\n* Add a warning about self-assignment\n\n    This release adds a warning for code that assigns an identifier to itself (e.g. `x = x`). This code is likely a mistake since doing this has no effect. This warning is not generated for assignments to global variables, since that can have side effects, and self-assignments with TypeScript casts, since those can be useful for changing the type of a variable in TypeScript. The warning is also not generated for code inside a `node_modules` folder.\n\n## 0.8.10\n\n* Fix parsing of conditional types in TypeScript ([#541](https://github.com/evanw/esbuild/issues/541))\n\n    Conditional types in TypeScript take the form `A extends B ? C : D`. Parsing of conditional types in esbuild was incorrect. The `?` can only follow an `extends` clause but esbuild didn't require the `extends` clause, which potentially led to build failures or miscompilation. The parsing for this syntax has been fixed and should now match the behavior of the TypeScript compiler. This fix was contributed by [@rtsao](https://github.com/rtsao).\n\n* Ignore comments for character frequency analysis ([#543](https://github.com/evanw/esbuild/issues/543))\n\n    Character frequency analysis is used to derive the order of minified names for better gzip compression. The idea is to prefer using the most-used characters in the non-symbol parts of the document (keywords, strings, etc.) over characters that are less-used or absent. This is a very slight win, and is only approximate based on the input text instead of the output text because otherwise it would require minifying twice.\n\n    Right now comments are included in this character frequency histogram. This is not a correctness issue but it does mean that documents with the same code but different comments may be minified to different output files. This release fixes this difference by removing comments from the character frequency histogram.\n\n* Add an option to ignore tree-shaking annotations ([#458](https://github.com/evanw/esbuild/issues/458))\n\n    Tree shaking is the term the JavaScript community uses for dead code elimination, a common compiler optimization that automatically removes unreachable code. Since JavaScript is a dynamic language, identifying unused code is sometimes very difficult for a compiler, so the community has developed certain annotations to help tell compilers what code should be considered unused. Currently there two forms of tree-shaking annotations that esbuild supports: inline `/* @__PURE__ */` comments before function calls and the `sideEffects` field in `package.json`.\n\n    These annotations can be problematic because the compiler depends completely on developers for accuracy and the annotations are occasionally incorrect. The `sideEffects` field is particularly error-prone because by default it causes all files in your package to be considered dead code if no imports are used. If you add a new file containing side effects and forget to update that field, your package will break when people try to bundle it.\n\n    This release adds a new flag `--tree-shaking=ignore-annotations` to allow you to bundle code that contains incorrect tree-shaking annotations with esbuild. An example of such code is [@tensorflow/tfjs](https://github.com/tensorflow/tfjs). Ideally the `--tree-shaking=ignore-annotations` flag is only a temporary workaround. You should report these issues to the maintainer of the package to get them fixed since they will trip up other people too.\n\n* Add support for absolute `baseUrl` paths in `tsconfig.json` files\n\n    Previously esbuild always joined the `baseUrl` path to the end of the current directory path. However, if the `baseUrl` was an absolute path, that would end up including the current directory path twice. This situation could arise internally in certain cases involving multiple `tsconfig.json` files and `extends` fields even if the `tsconfig.json` files themselves didn't have absolute paths. Absolute paths are now not modified and should work correctly.\n\n* Fix crash for modules that do `module.exports = null` ([#532](https://github.com/evanw/esbuild/issues/532))\n\n    The code generated by esbuild would crash at run-time if a module overwrote `module.exports` with null or undefined. This has been fixed and no longer crashes.\n\n## 0.8.9\n\n* Add support for the `mips64le` architecture ([#523](https://github.com/evanw/esbuild/issues/523))\n\n    You should now be able to install esbuild on the `mips64le` architecture. This build target is second-tier as it's not covered by CI, but I tested it in an emulator and it appears to work at the moment.\n\n* Fix for packages with inconsistent side effect markings\n\n    Packages can have multiple entry points in their `package.json` file. Two commonly-used ones are specified using the fields `main` and `module`. Packages can also mark files in the package as not having side effects using the `sideEffects` field. Some packages have one entry point marked as having side effects and the other entry point as not having side effects. This is arguably a problem with the package itself. However, this caused an issue with esbuild's automatic entry point field selection method where it would incorrectly consider both `main` and `module` to not have side effects if one of them was marked as not having side effects. Now `main` and `module` will only be considered to not have side effects if the individual file was marked as not having side effects.\n\n* Warn about `import './file'` when `./file` was marked as having no side effects\n\n    Files in packages containing `\"sideEffects\": false` in the enclosing `package.json` file are intended to be automatically removed from the bundle if they aren't used. However, code containing `import './file'` is likely trying to import that file for a side effect. This is a conflict of intentions so it seems like a good idea to warn about this. It's likely a configuration error by the author of the package. The warning points to the location in `package.json` that caused this situation.\n\n* Add support for glob-style tests in `sideEffects` arrays\n\n    The `sideEffects` field in `package.json` can optionally contain an array of files that are considered to have side effects. Any file not in that list will be removed if the import isn't used. Webpack supports the `*` and `?` wildcard characters in these file strings. With this release, esbuild supports these wildcard characters too.\n\n## 0.8.8\n\n* Add the `--banner` and `--footer` options ([#482](https://github.com/evanw/esbuild/issues/482))\n\n    You can now use the `--banner` and `--footer` options to insert code before and/or after the code that esbuild generates. This is usually used to insert a banner comment at the top of your bundle. However, you can also use this for other purposes such as wrapping your whole bundle in `--banner='try {'` and `--footer='} catch (e) { reportError(e) }'`. Note that since these strings can contain partial JavaScript syntax, esbuild will not do anything to ensure the result is valid JavaScript syntax. This feature was contributed by [@Gelio](https://github.com/Gelio).\n\n* Be more permissive inside TypeScript `declare` contexts\n\n    These cases are now allowed by esbuild:\n\n    * TypeScript supports a special `global { ... }` block inside `declare module`\n    * TypeScript allows arbitrary import and export statements inside `declare module`\n    * The TypeScript-specific `export as namespace name;` syntax is now ignored inside `declare module`.\n    * A trailing comma after a rest argument is disallowed in JavaScript but is allowed in TypeScript if you use `declare function`\n\n* Log output to stderr has been overhauled\n\n    The formatting is now slightly different. Line numbers are now displayed to the left of the source text and source text is now dimmed to make the log messages themselves stand out more. And log messages now support \"notes\" which are additional messages with different attached locations.\n\n    Before:\n\n    ```\n    example.ts:13:6: error: \"test\" has already been declared\n    class test extends BaseTest {\n          ~~~~\n    ```\n\n    After:\n\n    ```\n     > example.ts: error: \"test\" has already been declared\n        13 │ class test extends BaseTest {\n           ╵       ~~~~\n          example.ts: note: \"test\" was originally declared here\n         4 │ function test(name: string, callback: () => void) {\n           ╵          ~~~~\n    ```\n\n## 0.8.7\n\n* `--public-path` now affects code splitting chunk imports ([#524](https://github.com/evanw/esbuild/issues/524))\n\n    The public path setting is a path prefix that bakes in the path where your code is hosted. It can currently be used with the `file` loader to turn the exported URLs into absolute URLs. Previously this path prefix didn't apply to the cross-chunk imports generated by code splitting. This was an oversight. The public path setting now also works for cross-chunk imports in this release.\n\n* Add `exports` for output files in metafile ([#487](https://github.com/evanw/esbuild/issues/487))\n\n    The metafile JSON data now contains a list of export names for all generated output files. This only affects builds that use the `esm` output format. It includes the names of all exports declared using the `export` keyword, including transitive exports that use the `export * from` syntax. If the entry point is in CommonJS format, there will be a single export called `default`.\n\n* Fix values in metafile `inputs` object\n\n    This fixes a regression in the `inputs` object in generated metafile JSON data. Version 0.7.9 introduced the ability for a module to be split into multiple parts to correctly emulate ECMAScript module instantiation order. However, that caused split files to be present in the `inputs` object multiple times, once for each split part. That looked something like this:\n\n    ```json\n    \"outputs\": {\n      \"out/a.js\": {\n        \"imports\": [\n          {\n            \"path\": \"out/chunk.QXHH4FDI.js\"\n          }\n        ],\n        \"inputs\": {\n          \"a.js\": {\n            \"bytesInOutput\": 21\n          },\n          \"a.js\": {\n            \"bytesInOutput\": 0\n          }\n        },\n        \"bytes\": 120\n      }\n    }\n    ```\n\n    This is problematic because duplicate keys are allowed in JSON and overwrite the previous key. The fix in this release is to accumulate the `bytesInOutput` values for all parts of a file and then only write out the accumulated values at the end.\n\n* Avoid arrow functions when `import()` is converted to `require()` for `es5`\n\n    Setting the target to `es5` is supposed to remove arrow functions, since they are only supported in `es6` and above. However, arrow functions would still be generated if an `import()` expression pointed to an external module and the output format was `iife` or `cjs`. Now these arrow functions are replaced by function expressions instead.\n\n* Convert `import()` to `require()` even if the argument isn't a string literal\n\n    The `import()` syntax is supposed to be converted to `require()` if the target is `cjs` instead of `esm`. However, this was previously only done if the argument was a string literal. This is now done for all `import()` expressions regardless of what the argument looks like.\n\n* Transpose `require(a ? 'b' : 'c')` into `a ? require('b') : require('c')`\n\n    The reverse transformation is sometimes done by JavaScript minifiers such as [Terser](https://github.com/terser/terser) even if the original source code used the form `a ? require('b') : require('c')`. This messes up esbuild's import resolution which needs `require()` to take a single string as an argument. The transformation done here is a simple way to make sure esbuild still works on minified code. This transformation is also performed on `import()` and `require.resolve()`.\n\n## 0.8.6\n\n* Changes to TypeScript's `import name =` syntax\n\n    The parsing of TypeScript's `import name =` syntax should now match the official TypeScript parser. Previously esbuild incorrectly allowed any kind of expression after the equals sign. Now you can only use either a sequence of identifiers separated by periods or a call to the `require` function with a string literal.\n\n* Do not report warnings about `require()` inside `try` ([#512](https://github.com/evanw/esbuild/issues/512))\n\n    This release no longer reports warnings about un-bundled calls to `require()` if they are within a `try` block statement. Presumably the try/catch statement is there to handle the potential run-time error from the unbundled `require()` call failing, so the potential failure is expected and not worth warning about.\n\n* Add the `--keep-names` option ([#510](https://github.com/evanw/esbuild/issues/510))\n\n    In JavaScript the `name` property on functions and classes defaults to a nearby identifier in the source code. These syntax forms all set the `name` property of the function to `'fn'`:\n\n    ```js\n    function fn() {}\n    let fn = function() {};\n    obj.fn = function() {};\n    fn = function() {};\n    let [fn = function() {}] = [];\n    let {fn = function() {}} = {};\n    [fn = function() {}] = [];\n    ({fn = function() {}} = {});\n    ```\n\n    However, minification renames symbols to reduce code size. That changes value of the `name` property for many of these cases. This is usually fine because the `name` property is normally only used for debugging. However, some frameworks rely on the `name` property for registration and binding purposes. If this is the case, you can now enable `--keep-names` to preserve the original `name` values even in minified code.\n\n* Omit unused TypeScript import assignment aliases ([#474](https://github.com/evanw/esbuild/issues/474))\n\n    In TypeScript, `import x = y` is an alias statement that works for both values and types and can reach across files. Because esbuild doesn't replicate TypeScript's type system and because esbuild converts each file from TypeScript to JavaScript independently, it's not clear to esbuild if the alias refers to a value and should be kept as JavaScript or if the alias refers to a type and should be removed.\n\n    Previously all import aliases were kept in the generated JavaScript. This could lead to problems if the alias actually referred to a type. Now import aliases are only kept if they are used as values. This way import aliases that are only used as types will be automatically removed. This doesn't exactly match what the TypeScript compiler does in complex scenarios but it should work for many real-world cases.\n\n* Validate that on-resolve plugins return absolute paths in the `file` namespace\n\n    The default path namespace for on-resolve plugins is the `file` namespace. Paths in this namespace are expected to be absolute paths. This is now enforced. If the returned path is not supposed to be a file system path, you should set a namespace other than `file` so esbuild doesn't treat it as a file system path.\n\n* External paths returned by a plugin do not default to the `file` namespace\n\n    The `file` namespace is normally implied if it's not specified. However, that probably does not match the intent of the plugin for paths that have been marked as external. Such paths will now have an empty namespace instead of the namespace `file`. You now have to explicitly specify the `file` namespace in your plugin if you want it for external paths.\n\n## 0.8.5\n\n* Direct `eval()` now causes the module to be considered CommonJS ([#175](https://github.com/evanw/esbuild/pull/175))\n\n    Code containing a direct call to `eval()` can potentially access any name in the current scope or in any parent scope. Therefore all symbols in all of these scopes must not be renamed or minified. This was already the case for all non-top-level symbols, but it accidentally wasn't the case for top-level symbols.\n\n    Preventing top-level symbols from being renamed is problematic because they may be merged in with symbols from other files due to the scope hoisting optimization that applies to files in the ECMAScript module format. That could potentially cause the names to collide and cause a syntax error if they aren't renamed. This problem is now avoided by treating files containing direct `eval()` as CommonJS modules instead, which causes these files to each be wrapped in their own closure with a separate scope.\n\n    Note that this change means that tree shaking is disabled for these files. There is rarely a reason to use direct `eval()` and it is almost always a mistake. You likely want to use a form of indirect eval such as `(0, eval)('code')` instead. That also has the benefit of not disabling symbol minification for that file.\n\n* Add a `text` property to output files in build results ([#496](https://github.com/evanw/esbuild/issues/496))\n\n    If you pass `write: false` to the JavaScript `build` API, the output files that would have been written to the file system are instead returned as an array of objects. Each object has a `Uint8Array` property called `contents` with the bytes of the file. It does not contain a string because the bytes of the file may not be valid UTF-8 (e.g. a PNG image) and it's not safe to decode output files as UTF-8 text in all cases.\n\n    This release adds a convenience property called `text` that lazily evaluates and returns `new TextDecoder().decode(contents)` the first time it's accessed. You should only use this in cases where you are sure the contents of the file are encoded using UTF-8 encoding. Invalid code point sequences will be replaced by the U+FFFD replacement character.\n\n## 0.8.4\n\n* Using `delete` on an import namespace object is now an error\n\n    This release makes the following code forbidden when bundling is active:\n\n    ```js\n    import * as ns from './some-file';\n    delete ns.prop;\n    ```\n\n    Doing this does not delete the property because properties on ECMAScript module objects are not mutable. Assigning to a property of an import namespace object is already an error and not including the `delete` operator as an assignment was an oversight. This release just makes `delete` assignment consistent with other forms of assignment.\n\n* Mark dead code inside branching expressions\n\n    Code inside branching expressions where the branch is statically determined to never be taken is now marked as dead code. Previously this was only the case for statements, not expressions. This change means `false && require('pkg')` will no longer generate an error about `pkg` being missing even if it is indeed missing. This change affects the `||`, `&&`, `??`, and `?:` operators.\n\n* Fix metafile when importing CSS from JS ([#504](https://github.com/evanw/esbuild/pull/504))\n\n    This release fixes a bug where importing a CSS file from JavaScript caused esbuild to generate invalid JSON in the resulting metafile. It was only a problem if you were importing CSS from JS and enabled metafile output. This fix was contributed by [@nitsky](https://github.com/nitsky).\n\n* Fix downloads for Yarn 2 ([#505](https://github.com/evanw/esbuild/pull/505))\n\n    The change related to Yarn 2 in the previous release had a bug that prevented downloads from succeeding when installing esbuild with Yarn 2. This fix was contributed by [@mathieudutour](https://github.com/mathieudutour).\n\n## 0.8.3\n\n* Fix name collision with TypeScript namespaces containing their own name\n\n    This fixes a bug where TypeScript namespaces containing a declaration that re-uses the name of the enclosing namespace incorrectly failed the build with a duplicate declaration error. Here is an example:\n\n    ```ts\n    namespace foo {\n      export let foo\n    }\n    ```\n\n    This happened because esbuild compiles that code into something like this:\n\n    ```ts\n    var foo;\n    (function (foo) {\n      foo.foo = 123;\n      console.log(foo.foo);\n    })(foo || (foo = {}));\n    ```\n\n    The exported name `foo` was colliding with the automatically-declared function argument also named `foo`, which normally must be declared in that scope to shadow the outer namespace variable. This release fixes the problem by not declaring the function argument in the scope if there is already a declaration with that name in that scope.\n\n* Prefer `.css` files for `@import` in CSS\n\n    People sometimes create a `.js`-related file and an adjacent `.css` file with the same name when creating a component (e.g. `button.tsx` and `button.css`). They also sometimes use `@import \"./button\"` in CSS and omit the file extension. Currently esbuild uses a single global order of extensions to try when an extension is omitted. This is configured with `--resolve-extensions` and defaults to `.tsx, .ts, .jsx, .mjs, .cjs, .js, .css, .json`. This means the `.tsx` file will be matched because `.tsx` comes before `.css` in the order.\n\n    This release changes the behavior to use a different order of extensions for `@import` statements in CSS files. The order is the list given by `--resolve-extensions` with all extensions removed that have `.js`-related loaders configured. In this case the filtered list would just be `.css` since all other default resolve extensions have JavaScript loaders, but if you also configure another resolve extension to use the `css` loader that will also qualify for implicit extension support with `@import` statements in CSS.\n\n* Add support for `paths` in `tsconfig.json` for absolute paths\n\n    Previously it wasn't possible to use `paths` in `tsconfig.json` to remap paths starting with `/` on systems that considered that an absolute path (so not Windows). This is because absolute paths are handled before normal path resolution logic. Now this should work correctly.\n\n* Hack around lack of support for binary packages in Yarn 2 ([#467](https://github.com/evanw/esbuild/issues/467))\n\n    The Yarn 2 package manager is deliberately incompatible with binary modules because the Yarn 2 developers don't think they should be used. See [yarnpkg/berry#882](https://github.com/yarnpkg/berry/issues/882) for details. This means running esbuild with Yarn 2 currently doesn't work (Yarn 2 tries to load the esbuild binary as a JavaScript file).\n\n    The suggested workaround from the Yarn 2 team is to replace the binary with a JavaScript file wrapper that invokes the esbuild binary using node's `child_process` module. However, doing that would slow down esbuild for everyone. The `esbuild` command that is exported from the main package is intentionally a native executable instead of a JavaScript wrapper script because starting up a new node process just to invoke a native binary is unnecessary additional overhead.\n\n    The hack added in this release is to detect whether esbuild is being installed with Yarn 2 during the install script and only install a JavaScript file wrapper for Yarn 2 users. Doing this should make it possible to run the esbuild command from Yarn 2 without slowing down esbuild for everyone. This change was contributed by [@rtsao](https://github.com/rtsao).\n\n## 0.8.2\n\n* Fix the omission of `outbase` in the JavaScript API ([#471](https://github.com/evanw/esbuild/pull/471))\n\n    The original PR for the `outbase` setting added it to the CLI and Go APIs but not the JavaScript API. This release adds it to the JavaScript API too.\n\n* Fix the TypeScript type definitions ([#499](https://github.com/evanw/esbuild/pull/499))\n\n    The newly-released `plugins` option in the TypeScript type definitions was incorrectly marked as non-optional. It is now optional. This fix was contributed by [@remorses](https://github.com/remorses).\n\n## 0.8.1\n\n* The initial version of the plugin API ([#111](https://github.com/evanw/esbuild/pull/111))\n\n    The plugin API lets you inject custom code inside esbuild's build process. You can write plugins in either JavaScript or Go. Right now you can add an \"on resolve\" callback to determine where import paths go and an \"on load\" callback to determine what the imported file contains. These two primitives are very powerful, especially in combination with each other.\n\n    Here's a simple example plugin to show off the API in action. Let's say you wanted to enable a workflow where you can import environment variables like this:\n\n    ```js\n    // app.js\n    import { NODE_ENV } from 'env'\n    console.log(`NODE_ENV is ${NODE_ENV}`)\n    ```\n\n    This is how you might do that from JavaScript:\n\n    ```js\n    let envPlugin = {\n      name: 'env-plugin',\n      setup(build) {\n        build.onResolve({ filter: /^env$/ }, args => ({\n          path: args.path,\n          namespace: 'env',\n        }))\n\n        build.onLoad({ filter: /.*/, namespace: 'env' }, () => ({\n          contents: JSON.stringify(process.env),\n          loader: 'json',\n        }))\n      },\n    }\n\n    require('esbuild').build({\n      entryPoints: ['app.js'],\n      bundle: true,\n      outfile: 'out.js',\n      plugins: [envPlugin],\n      logLevel: 'info',\n    }).catch(() => process.exit(1))\n    ```\n\n    This is how you might do that from Go:\n\n    ```go\n    package main\n\n    import (\n      \"encoding/json\"\n      \"os\"\n      \"strings\"\n\n      \"github.com/evanw/esbuild/pkg/api\"\n    )\n\n    var envPlugin = api.Plugin{\n      Name: \"env-plugin\",\n      Setup: func(build api.PluginBuild) {\n        build.OnResolve(api.OnResolveOptions{Filter: `^env$`},\n          func(args api.OnResolveArgs) (api.OnResolveResult, error) {\n            return api.OnResolveResult{\n              Path: args.Path,\n              Namespace: \"env\",\n            }, nil\n          })\n\n        build.OnLoad(api.OnLoadOptions{Filter: `.*`, Namespace: \"env\"},\n          func(args api.OnLoadArgs) (api.OnLoadResult, error) {\n            mappings := make(map[string]string)\n            for _, item := range os.Environ() {\n              if equals := strings.IndexByte(item, '='); equals != -1 {\n                mappings[item[:equals]] = item[equals+1:]\n              }\n            }\n            bytes, _ := json.Marshal(mappings)\n            contents := string(bytes)\n            return api.OnLoadResult{\n              Contents: &contents,\n              Loader: api.LoaderJSON,\n            }, nil\n          })\n      },\n    }\n\n    func main() {\n      result := api.Build(api.BuildOptions{\n        EntryPoints: []string{\"app.js\"},\n        Bundle:      true,\n        Outfile:     \"out.js\",\n        Plugins:     []api.Plugin{envPlugin},\n        Write:       true,\n        LogLevel:    api.LogLevelInfo,\n      })\n\n      if len(result.Errors) > 0 {\n        os.Exit(1)\n      }\n    }\n    ```\n\n    Comprehensive documentation for the plugin API is not yet available but is coming soon.\n\n* Add the `outbase` option ([#471](https://github.com/evanw/esbuild/pull/471))\n\n    Currently, esbuild uses the lowest common ancestor of the entrypoints to determine where to place each entrypoint's output file. This is an excellent default, but is not ideal in some situations. Take for example an app with a folder structure similar to Next.js, with js files at `pages/a/b/c.js` and `pages/a/b/d.js`. These two files correspond to the paths `/a/b/c` and `/a/b/d`. Ideally, esbuild would emit `out/a/b/c.js` and `out/a/b/d.js`. However, esbuild identifies `pages/a/b` as the lowest common ancestor and emits `out/c.js` and `out/d.js`. This release introduces an `--outbase` argument to the cli that allows the user to choose which path to base entrypoint output paths on. With this change, running esbuild with `--outbase=pages` results in the desired behavior. This change was contributed by [@nitsky](https://github.com/nitsky).\n\n## 0.8.0\n\n**This release contains backwards-incompatible changes.** Since esbuild is before version 1.0.0, these changes have been released as a new minor version to reflect this (as [recommended by npm](https://docs.npmjs.com/misc/semver)). You should either be pinning the exact version of `esbuild` in your `package.json` file or be using a version range syntax that only accepts patch upgrades such as `^0.7.0`. See the documentation about [semver](https://docs.npmjs.com/misc/semver) for more information.\n\nThe breaking changes are as follows:\n\n* Changed the transform API result object\n\n    For the transform API, the return values `js` and `jsSourceMap` have been renamed to `code` and `map` respectively. This is because esbuild now supports CSS as a first-class content type, and returning CSS code in a variable called `js` made no sense.\n\n* The class field transform is now more accurate\n\n    Class fields look like this:\n\n    ```js\n    class Foo {\n      foo = 123\n    }\n    ```\n\n    Previously the transform for class fields used a normal assignment for initialization:\n\n    ```js\n    class Foo {\n      constructor() {\n        this.foo = 123;\n      }\n    }\n    ```\n\n    However, this doesn't exactly follow the initialization behavior in the JavaScript specification. For example, it can cause a setter to be called if one exists with that property name, which isn't supposed to happen. A more accurate transform that used `Object.defineProperty()` instead was available under the `--strict:class-fields` option.\n\n    This release removes the `--strict:class-fields` option and makes that the default behavior. There is no longer a way to compile class fields to normal assignments instead, since that doesn't follow JavaScript semantics. Note that for legacy reasons, TypeScript code will still compile class fields to normal assignments unless `useDefineForClassFields` is enabled in `tsconfig.json` just like the official TypeScript compiler.\n\n* When bundling stdin using the API, `resolveDir` is now required to resolve imports\n\n    The `resolveDir` option specifies the directory to resolve relative imports against. Previously it defaulted to the current working directory. Now it no longer does, so you must explicitly specify it if you need it:\n\n    ```js\n    const result = await esbuild.build({\n      stdin: {\n        contents,\n        resolveDir,\n      },\n      bundle: true,\n      outdir,\n    })\n    ```\n\n    This was changed because the original behavior was unintentional, and because being explicit seems better in this case. Note that this only affects the JavaScript and Go APIs. The resolution directory for stdin passed using the command-line API still defaults to the current working directory.\n\n    In addition, it is now possible for esbuild to discover input source maps linked via `//# sourceMappingURL=` comments relative to the `resolveDir` for stdin. This previously only worked for files with a real path on the file system.\n\n* Made names in the Go API consistent\n\n    Previously some of the names in the Go API were unnecessarily different than the corresponding names in the CLI and JavaScript APIs. This made it harder to write documentation and examples for these APIs that work consistently across all three API surfaces. These different names in the Go API have been fixed:\n\n    * `Defines` → `Define`\n    * `Externals` → `External`\n    * `Loaders` → `Loader`\n    * `PureFunctions` → `Pure`\n\n* The global name parameter now takes a JavaScript expression ([#293](https://github.com/evanw/esbuild/issues/293))\n\n    The global name parameter determines the name of the global variable created for exports with the IIFE output format. For example, a global name of `abc` would generate the following IIFE:\n\n    ```js\n    var abc = (() => {\n      ...\n    })();\n    ```\n\n    Previously this name was injected into the source code verbatim without any validation. This meant a global name of `abc.def` would generate this code, which is a syntax error:\n\n    ```js\n    var abc.def = (() => {\n      ...\n    })();\n    ```\n\n    With this release, a global name of `abc.def` will now generate the following code instead:\n\n    ```js\n    var abc = abc || {};\n    abc.def = (() => {\n      ...\n    })();\n    ```\n\n    The full syntax is an identifier followed by one or more property accesses. If you need to include a `.` character in your property name, you can use an index expression instead. For example, the global name `versions['1.0']` will generate the following code:\n\n    ```js\n    var versions = versions || {};\n    versions[\"1.0\"] = (() => {\n      ...\n    })();\n    ```\n\n* Removed the workaround for `document.all` with nullish coalescing and optional chaining\n\n    The `--strict:nullish-coalescing` and `--strict:optional-chaining` options have been removed. They only existed to address a theoretical problem where modern code that uses the new `??` and `?.` operators interacted with the legacy [`document.all` object](https://developer.mozilla.org/en-US/docs/Web/API/Document/all) that has been deprecated for a long time. Realistically this case is extremely unlikely to come up in practice, so these obscure options were removed to simplify the API and reduce code complexity. For what it's worth this behavior also matches [Terser](https://github.com/terser/terser), a commonly-used JavaScript minifier.\n\n## 0.7.22\n\n* Add `tsconfigRaw` to the transform API ([#483](https://github.com/evanw/esbuild/issues/483))\n\n    The `build` API uses access to the file system and doesn't run in the browser, but the `transform` API doesn't access the file system and can run in the browser. Previously you could only use the build API for certain scenarios involving TypeScript code and `tsconfig.json` files, such as configuring the `importsNotUsedAsValues` setting.\n\n    You can now use `tsconfig.json` with the transform API by passing in the raw contents of that file:\n\n    ```js\n    let result = esbuild.transformSync(ts, {\n      loader: 'ts',\n      tsconfigRaw: {\n        compilerOptions: {\n          importsNotUsedAsValues: 'preserve',\n        },\n      },\n    })\n    ```\n\n    Right now four values are supported with the transform API: `jsxFactory`, `jsxFragmentFactory`, `useDefineForClassFields`, and `importsNotUsedAsValues`. The values `extends`, `baseUrl`, and `paths` are not supported because they require access to the file system and the transform API deliberately does not access the file system.\n\n    You can also pass the `tsconfig.json` file as a string instead of a JSON object if you prefer. This can be useful because `tsconfig.json` files actually use a weird pseudo-JSON syntax that allows comments and trailing commas, which means it can't be parsed with `JSON.parse()`.\n\n* Warn about `process.env.NODE_ENV`\n\n    Some popular browser-oriented libraries such as React use `process.env.NODE_ENV` even though this is not an API provided by the browser. While esbuild makes it easy to replace this at compile time using the `--define` feature, you must still do this manually and it's easy to forget. Now esbuild will warn you if you're bundling code containing `process.env.NODE_ENV` for the browser and you haven't configured it to be replaced by something.\n\n* Work around a bug in Safari for the run-time code ([#489](https://github.com/evanw/esbuild/issues/489))\n\n    The `Object.getOwnPropertyDescriptor` function in Safari is broken for numeric properties. It incorrectly returns `undefined`, which crashes the run-time code esbuild uses to bind modules together. This release contains code to avoid a crash in this case.\n\n## 0.7.21\n\n* Use bracketed escape codes for non-BMP characters\n\n    The previous release introduced code that escapes non-ASCII characters using ASCII escape sequences. Since JavaScript uses UCS-2/UTF-16 internally, a non-[BMP](https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane) character such as `𐀀` ended up being encoded using a [surrogate pair](https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates): `\\uD800\\uDC00`. This is fine when the character is contained in a string, but it causes a syntax error when that character is used as an identifier.\n\n    This release fixes this issue by using the newer bracketed escape code instead: `\\u{10000}`. One complication with doing this is that this escape code won't work in older environments without ES6 support. Because of this, using identifiers containing non-BMP characters is now an error if the configured target environment doesn't support bracketed escape codes.\n\n* Escape non-ASCII characters in properties\n\n    The previous release overlooked the need to escape non-ASCII characters in properties in various places in the grammar (e.g. object literals, property accesses, import and export aliases). This resulted in output containing non-ASCII characters even with `--charset=ascii`. These characters should now always be escaped, even in properties.\n\n## 0.7.20\n\n* Default to ASCII-only output ([#70](https://github.com/evanw/esbuild/issues/70), [#485](https://github.com/evanw/esbuild/issues/485))\n\n    While esbuild's output is encoded using UTF-8 encoding, there are many other character encodings in the wild (e.g. [Windows-1250](https://en.wikipedia.org/wiki/Windows-1250)). You can explicitly mark the output files as UTF-8 by adding `<meta charset=\"utf-8\">` to your HTML page or by including `charset=utf-8` in the `Content-Type` header sent by your server. This is probably a good idea regardless of the contents of esbuild's output since information being displayed to users is probably also encoded using UTF-8.\n\n    However, sometimes it's not possible to guarantee that your users will be running your code as UTF-8. For example, you may not control the server response or the contents of the HTML page that loads your script. Also, if your code needs to run in IE, there are [certain cases](https://docs.microsoft.com/en-us/troubleshoot/browsers/wrong-character-set-for-html-page) where IE may ignore the `<meta charset=\"utf-8\">` tag and make up another encoding instead.\n\n    Also content encoded using UTF-8 may be parsed up to 1.7x slower by the browser than ASCII-only content, at least according to this blog post from the V8 team: https://v8.dev/blog/scanner. The official recommendation is to \"avoid non-ASCII identifiers where possible\" to improve parsing performance.\n\n    For these reasons, esbuild's default output has been changed to ASCII-only. All Unicode code points in identifiers and strings that are outside of the printable ASCII range (`\\x20-\\x7E` inclusive) are escaped using backslash escape sequences. If you would like to use raw UTF-8 encoding instead, you can pass the `--charset=utf8` flag to esbuild.\n\n    Further details:\n\n    * This does not yet escape non-ASCII characters embedded in regular expressions. This is because esbuild does not currently parse the contents of regular expressions at all. The flag was added despite this limitation because it's still useful for code that doesn't contain cases like this.\n\n    * This flag does not apply to comments. I believe preserving non-ASCII data in comments should be fine because even if the encoding is wrong, the run time environment should completely ignore the contents of all comments. For example, the [V8 blog post](https://v8.dev/blog/scanner) mentions an optimization that avoids decoding comment contents completely. And all comments other than license-related comments are stripped out by esbuild anyway.\n\n    * This new `--charset` flag simultaneously applies to all output file types (JavaScript, CSS, and JSON). So if you configure your server to send the correct `Content-Type` header and want to use `--charset=utf8`, make sure your server is configured to treat both `.js` and `.css` files as UTF-8.\n\n* Interpret escape sequences in CSS tokens\n\n    Escape sequences in CSS tokens are now interpreted. This was already the case for string and URL tokens before, but this is now the case for all identifier-like tokens as well. For example, `c\\6flor: #\\66 00` is now correctly recognized as `color: #f00`.\n\n* Support `.css` with the `--out-extension` option\n\n    The `--out-extension` option was added so you could generate `.mjs` and `.cjs` files for node like this: `--out-extension:.js=.mjs`. However, now that CSS is a first-class content type in esbuild, this should also be available for `.css` files. I'm not sure why you would want to do this, but you can now do `--out-extension:.css=.something` too.\n\n## 0.7.19\n\n* Add the `--avoid-tdz` option for large bundles in Safari ([#478](https://github.com/evanw/esbuild/issues/478))\n\n    This is a workaround for a performance issue with certain large JavaScript files in Safari.\n\n    First, some background. In JavaScript the `var` statement is \"hoisted\" meaning the variable is declared immediately in the closest surrounding function, module, or global scope. Accessing one of these variables before its declaration has been evaluated results in the value `undefined`. In ES6 the `const`, `let`, and `class` statements introduce what's called a \"temporal dead zone\" or TDZ. This means that, unlike `var` statements, accessing one of these variable before its declaration has been evaluated results in a `ReferenceError` being thrown. It's called a \"temporal dead zone\" because it's a zone of time in which the variable is inaccessible.\n\n    According to [this WebKit bug](https://bugs.webkit.org/show_bug.cgi?id=199866), there's a severe performance issue with the tracking of TDZ checks in JavaScriptCore, the JavaScript JIT compiler used by WebKit. In a large private code base I have access to, the initialization phase of the bundle produced by esbuild runs 10x faster in Safari if top-level `const`, `let`, and `class` are replaced with `var`. It's a difference between a loading time of about 2sec vs. about 200ms. This transformation is not enabled by default because it changes the semantics of the code (it removes the TDZ and `const` assignment checks). However, this change in semantics may be acceptable for you given the performance trade-off. You can enable it with the `--avoid-tdz` flag.\n\n* Warn about assignment to `const` symbols\n\n    Now that some `const` symbols may be converted to `var` due to `--avoid-tdz`, it seems like a good idea to at least warn when an assignment to a `const` symbol is detected during bundling. Otherwise accidental assignments to `const` symbols could go unnoticed if there isn't other tooling in place such as TypeScript or a linter.\n\n## 0.7.18\n\n* Treat paths in CSS without a `./` or `../` prefix as relative ([#469](https://github.com/evanw/esbuild/issues/469))\n\n    JavaScript paths starting with `./` or `../` are considered relative paths, while other JavaScript paths are considered package paths and are looked up in that package's `node_modules` directory. Currently `url()` paths in CSS files use that same logic, so `url(images/image.png)` checks for a file named `image.png` in the `image` package.\n\n    This release changes this behavior. Now `url(images/image.png)` first checks for `./images/image.png`, then checks for a file named `image.png` in the `image` package. This behavior should match the behavior of Webpack's standard `css-loader` package.\n\n* Import non-enumerable properties from CommonJS modules ([#472](https://github.com/evanw/esbuild/issues/472))\n\n    You can now import non-enumerable properties from CommonJS modules using an ES6 `import` statement. Here's an example of a situation where that might matter:\n\n    ```js\n    // example.js\n    module.exports = class {\n      static method() {}\n    }\n    ```\n\n    ```js\n    import { method } from './example.js'\n    method()\n    ```\n\n    Previously that didn't work because the `method` property is non-enumerable. This should now work correctly.\n\n    A minor consequence of this change is that re-exporting from a file using `export * from` will no longer re-export properties inherited from the prototype of the object assigned to `module.exports`. This is because run-time property copying has been changed from a for-in loop to `Object.getOwnPropertyNames`. This change should be inconsequential because as far as I can tell this isn't something any other bundler supports either.\n\n* Remove arrow functions in runtime with `--target=es5`\n\n    The `--target=es5` flag is intended to prevent esbuild from introducing any ES6+ syntax into the generated output file. For example, esbuild usually shortens `{x: x}` into `{x}` since it's shorter, except that requires ES6 support. This release fixes a bug where `=>` arrow expressions in esbuild's runtime of helper functions were not converted to `function` expressions when `--target=es5` was present.\n\n* Merge local variable declarations across files when minifying\n\n    Currently files are minified in parallel and then concatenated together for maximum performance. However, that means certain constructs are not optimally minified if they span multiple files. For example, a bundle containing two files `var a = 1` and `var b = 2` should ideally become `var a=1,b=2;` after minification but it currently becomes `var a=0;var b=2;` instead due to parallelism.\n\n    With this release, esbuild will generate `var a=1,b=2;` in this scenario. This is achieved by splicing the two files together to remove the trailing `;` and the leading `var `, which is more complicated than it sounds when you consider rewriting the source maps.\n\n## 0.7.17\n\n* Add `--public-path=` for the `file` loader ([#459](https://github.com/evanw/esbuild/issues/459))\n\n    The `file` loader causes importing a file to cause that file to be copied into the output directory. The name of the file is exported as the default export:\n\n    ```js\n    // Assume \".png\" is set to the \"file\" loader\n    import name from 'images/image.png'\n\n    // This prints something like \"image.L3XDQOAT.png\"\n    console.log(name)\n    ```\n\n    The new public path setting configures the path prefix. So for example setting it to `https://www.example.com/v1` would change the output text for this example to `https://www.example.com/v1/image.L3XDQOAT.png`.\n\n* Add `--inject:` for polyfills ([#451](https://github.com/evanw/esbuild/issues/451))\n\n    It's now possible to replace global variables with imports from a file with `--inject:file.js`. Note that `file.js` must export symbols using the `export` keyword for this to work. This can be used to polyfill a global variable in code you don't control. For example:\n\n    ```js\n    // process.js\n    export let process = {cwd() {}}\n    ```\n\n    ```js\n    // entry.js\n    console.log(process.cwd())\n    ```\n\n    Building this with `esbuild entry.js --inject:process.js` gives this:\n\n    ```js\n    let process = {cwd() {\n    }};\n    console.log(process.cwd());\n    ```\n\n    You can also combine this with the existing `--define` feature to be more selective about what you import. For example:\n\n    ```js\n    // process.js\n    export function dummy_process_cwd() {}\n    ```\n\n    ```js\n    // entry.js\n    console.log(process.cwd())\n    ```\n\n    Building this with `esbuild entry.js --inject:process.js --define:process.cwd=dummy_process_cwd` gives this:\n\n    ```js\n    function dummy_process_cwd() {\n    }\n    console.log(dummy_process_cwd());\n    ```\n\n    Note that this means you can use `--inject` to provide the implementation for JSX expressions (e.g. auto-import the `react` package):\n\n    ```js\n    // shim.js\n    export * as React from 'react'\n    ```\n\n    ```jsx\n    // entry.jsx\n    console.log(<div/>)\n    ```\n\n    Building this with `esbuild entry.js --inject:shim.js --format=esm` gives this:\n\n    ```js\n    import * as React from \"react\";\n    console.log(/* @__PURE__ */ React.createElement(\"div\", null));\n    ```\n\n    You can also use `--inject:file.js` with files that have no exports. In that case the injected file just comes first before the rest of the output as if every input file contained `import \"./file.js\"`. Because of the way ECMAScript modules work, this injection is still \"hygienic\" in that symbols with the same name in different files are renamed so they don't collide with each other.\n\n    If you want to _conditionally_ import a file only if the export is actually used, you should mark the injected file as not having side effects by putting it in a package and adding `\"sideEffects\": false` in that package's `package.json` file. This setting is a [convention from Webpack](https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free) that esbuild respects for any imported file, not just files used with `--inject`.\n\n* Add an ECMAScript module build for the browser ([#342](https://github.com/evanw/esbuild/pull/342))\n\n    The [current browser API](https://github.com/evanw/esbuild/blob/cfaedaeeb35ae6e8b42921ab98ad98f75375d39f/docs/js-api.md#browser-api) lets you use esbuild in the browser via the `esbuild-wasm` package and a script tag:\n\n    ```html\n    <script src=\"node_modules/esbuild-wasm/lib/browser.js\"></script>\n    <script>\n      esbuild.startService({\n        wasmURL: 'node_modules/esbuild-wasm/esbuild.wasm',\n      }).then(service => {\n        // Use service\n      })\n    </script>\n    ```\n\n    In addition to this approach, you can now also use esbuild in the browser from a module-type script (note the use of `esm/browser.js` instead of `lib/browser.js`):\n\n    ```html\n    <script type=\"module\">\n      import * as esbuild from 'node_modules/esbuild-wasm/esm/browser.js'\n      esbuild.startService({\n        wasmURL: 'node_modules/esbuild-wasm/esbuild.wasm',\n      }).then(service => {\n        // Use service\n      })\n    </script>\n    ```\n\n    Part of this fix was contributed by [@calebeby](https://github.com/calebeby).\n\n## 0.7.16\n\n* Fix backward slashes in source maps on Windows ([#463](https://github.com/evanw/esbuild/issues/463))\n\n    The relative path fix in the previous release caused a regression where paths in source maps contained `\\` instead of `/` on Windows. That is incorrect because source map paths are URLs, not file system paths. This release replaces `\\` with `/` for consistency on Windows.\n\n* `module.require()` is now an alias for `require()` ([#455](https://github.com/evanw/esbuild/issues/455))\n\n    Some packages such as [apollo-server](https://github.com/apollographql/apollo-server) use `module.require()` instead of `require()` with the intent of bypassing the bundler's `require` and calling the underlying function from `node` instead. Unfortunately that doesn't actually work because CommonJS module semantics means `module` is a variable local to that file's CommonJS closure instead of the host's `module` object.\n\n    This wasn't an issue when using `apollo-server` with Webpack because the literal expression `module.require()` is automatically rewritten to `require()` by Webpack: [webpack/webpack#7750](https://github.com/webpack/webpack/pull/7750). To get this package to work, esbuild now matches Webpack's behavior here. Calls to `module.require()` will become external calls to `require()` as long as the required path has been marked as external.\n\n## 0.7.15\n\n* Lower `export * as` syntax for ES2019 and below\n\n    The `export * from 'path'` syntax was added in ES2015 but the `export * as name from 'path'` syntax was added more recently in ES2020. This is a shorthand for an import followed by an export:\n\n    ```js\n    // ES2020\n    export * as name from 'path'\n\n    // ES2019\n    import * as name from 'path'\n    export {name}\n    ```\n\n    With this release, esbuild will now undo this shorthand syntax when using `--target=es2019` or below.\n\n* Better code generation for TypeScript files with type-only exports ([#447](https://github.com/evanw/esbuild/issues/447))\n\n    Previously TypeScript files could have an unnecessary CommonJS wrapper in certain situations. The specific situation is bundling a file that re-exports something from another file without any exports. This happens because esbuild automatically considers a module to be a CommonJS module if there is no ES6 `import`/`export` syntax.\n\n    This behavior is undesirable because the CommonJS wrapper is usually unnecessary. It's especially undesirable for cases where the re-export uses `export * from` because then the re-exporting module is also converted to a CommonJS wrapper (since re-exporting everything from a CommonJS module must be done at run-time). That can also impact the bundle's exports itself if the entry point does this and the format is `esm`.\n\n    It is generally equivalent to avoid the CommonJS wrapper and just rewrite the imports to an `undefined` literal instead:\n\n    ```js\n    import {name} from './empty-file'\n    console.log(name)\n    ```\n\n    This can be rewritten to this instead (with a warning generated about `name` being missing):\n\n    ```js\n    console.log(void 0)\n    ```\n\n    With this release, this is now how cases like these are handled. The only case where this can't be done is when the import uses the `import * as` syntax. In that case a CommonJS wrapper is still necessary because the namespace cannot be rewritten to `undefined`.\n\n* Add support for `importsNotUsedAsValues` in TypeScript ([#448](https://github.com/evanw/esbuild/issues/448))\n\n    The `importsNotUsedAsValues` field in `tsconfig.json` is now respected. Setting it to `\"preserve\"` means esbuild will no longer remove unused imports in TypeScript files. This field was added in TypeScript 3.8.\n\n* Fix relative paths in generated source maps ([#444](https://github.com/evanw/esbuild/issues/444))\n\n    Currently paths in generated source map files don't necessarily correspond to real file system paths. They are really only meant to be human-readable when debugging in the browser.\n\n    However, the Visual Studio Code debugger expects these paths to point back to the original files on the file system. With this release, it should now always be possible to get back to the original source file by joining the directory containing the source map file with the relative path in the source map.\n\n    This fix was contributed by [@yoyo930021](https://github.com/yoyo930021).\n\n## 0.7.14\n\n* Fix a bug with compound import statements ([#446](https://github.com/evanw/esbuild/issues/446))\n\n    Import statements can simultaneously contain both a default import and a namespace import like this:\n\n    ```js\n    import defVal, * as nsVal from 'path'\n    ```\n\n    These statements were previously miscompiled when bundling if the import path was marked as external, or when converting to a specific output format, and the namespace variable itself was used for something other than a property access. The generated code contained a syntax error because it generated a `{...}` import clause containing the default import.\n\n    This particular problem was caused by code that converts namespace imports into import clauses for more efficient bundling. This transformation should not be done if the namespace import cannot be completely removed:\n\n    ```js\n    // Can convert namespace to clause\n    import defVal, * as nsVal from 'path'\n    console.log(defVal, nsVal.prop)\n    ```\n\n    ```js\n    // Cannot convert namespace to clause\n    import defVal, * as nsVal from 'path'\n    console.log(defVal, nsVal)\n    ```\n\n## 0.7.13\n\n* Fix `mainFields` in the JavaScript API ([#440](https://github.com/evanw/esbuild/issues/440) and [#441](https://github.com/evanw/esbuild/pull/441))\n\n    It turns out the JavaScript bindings for the `mainFields` API option didn't work due to a copy/paste error. The fix for this was contributed by [@yoyo930021](https://github.com/yoyo930021).\n\n* The benchmarks have been updated\n\n    The benchmarks now include Parcel 2 and Webpack 5 (in addition to Parcel 1 and Webpack 4, which were already included). It looks like Parcel 2 is slightly faster than Parcel 1 and Webpack 5 is significantly slower than Webpack 4.\n\n## 0.7.12\n\n* Fix another subtle ordering issue with `import` statements\n\n    When importing a file while bundling, the import statement was ordered before the imported code. This could affect import execution order in complex scenarios involving nested hybrid ES6/CommonJS modules. The fix was to move the import statement to after the imported code instead. This issue affected the `@sentry/browser` package.\n\n## 0.7.11\n\n* Fix regression in 0.7.9 when minifying with code splitting ([#437](https://github.com/evanw/esbuild/issues/437))\n\n    In certain specific cases, bundling and minifying with code splitting active can cause a crash. This is a regression that was introduced in version 0.7.9 due to the fix for issue [#421](https://github.com/evanw/esbuild/issues/421). The crash has been fixed and this case now has test coverage.\n\n## 0.7.10\n\n* Recover from bad `main` field in `package.json` ([#423](https://github.com/evanw/esbuild/issues/423))\n\n    Some packages are published with invalid information in the `main` field of `package.json`. In that case, path resolution should fall back to searching for a file named `index.js` before giving up. This matters for the `simple-exiftool` package, for example.\n\n* Ignore TypeScript types on `catch` clause bindings ([435](https://github.com/evanw/esbuild/issues/435))\n\n    This fixes an issue where using a type annotation in a `catch` clause like this was a syntax error:\n\n    ```ts\n    try {\n    } catch (x: unknown) {\n    }\n    ```\n\n## 0.7.9\n\n* Fixed panic when using a `url()` import in CSS with the `--metafile` option\n\n    This release fixes a crash that happens when `metafile` output is enabled and the `url()` syntax is used in a CSS file to import a successfully-resolved file.\n\n* Minify some CSS colors\n\n    The minifier can now reduce the size of some CSS colors. This is the initial work to start CSS minification in general beyond whitespace removal. There is currently support for minifying hex, `rgb()/rgba()`, and `hsl()/hsla()` into hex or shorthand hex. The minification process respects the configured target browser and doesn't use any syntax that wouldn't be supported.\n\n* Lower newer CSS syntax for older browsers\n\n    Newer color syntax such as `rgba(255 0 0 / 50%)` will be converted to older syntax (in this case `rgba(255, 0, 0, 0.5)`) when the target browser doesn't support the newer syntax. For example, this happens when using `--target=chrome60`.\n\n* Fix an ordering issue with `import` statements ([#421](https://github.com/evanw/esbuild/issues/421))\n\n    Previously `import` statements that resolved to a CommonJS module turned into a call to `require()` inline. This was subtly incorrect when combined with tree shaking because it could sometimes cause imported modules to be reordered:\n\n    ```js\n    import {foo} from './cjs-file'\n    import {bar} from './esm-file'\n    console.log(foo, bar)\n    ```\n\n    That code was previously compiled into something like this, which is incorrect because the evaluation of `bar` may depend on side effects from importing `cjs-file.js`:\n\n    ```js\n    // ./cjs-file.js\n    var require_cjs_file = __commonJS(() => {\n      ...\n    })\n\n    // ./esm-file.js\n    let bar = ...;\n\n    // ./example.js\n    const cjs_file = __toModule(require_cjs_file())\n    console.log(cjs_file.foo, bar)\n    ```\n\n    That code is now compiled into something like this:\n\n    ```js\n    // ./cjs-file.js\n    var require_cjs_file = __commonJS(() => {\n      ...\n    })\n\n    // ./example.js\n    const cjs_file = __toModule(require_cjs_file())\n\n    // ./esm-file.js\n    let bar = ...;\n\n    // ./example.js\n    console.log(cjs_file.foo, bar)\n    ```\n\n    This now means that a single input file can end up in multiple discontiguous regions in the output file as is the case with `example.js` here, which wasn't the case before this bug fix.\n\n## 0.7.8\n\n* Move external `@import` rules to the top\n\n    Bundling could cause `@import` rules for paths that have been marked as external to be inserted in the middle of the CSS file. This would cause them to become invalid and be ignored by the browser since all `@import` rules must come first at the top of the file. These `@import` rules are now always moved to the top of the file so they stay valid.\n\n* Better support for `@keyframes` rules\n\n    The parser now directly understands `@keyframes` rules, which means it can now format them more accurately and report more specific syntax errors.\n\n* Minify whitespace around commas in CSS\n\n    Whitespace around commas in CSS will now be pretty-printed when not minifying and removed when minifying. So `a , b` becomes `a, b` when pretty-printed and `a,b` when minified.\n\n* Warn about unknown at-rules in CSS\n\n    Using an `@rule` in a CSS file that isn't known by esbuild now generates a warning and these rules will be passed through unmodified. If they aren't known to esbuild, they are probably part of a CSS preprocessor syntax that should have been compiled away before giving the file to esbuild to parse.\n\n* Recoverable CSS syntax errors are now warnings\n\n    The base CSS syntax can preserve nonsensical rules as long as they contain valid tokens and have matching opening and closing brackets. These rule with incorrect syntax now generate a warning instead of an error and esbuild preserves the syntax in the output file. This makes it possible to use esbuild to process CSS that was generated by another tool that contains bugs.\n\n    For example, the following code is invalid CSS, and was presumably generated by a bug in an automatic prefix generator:\n\n    ```css\n    div {\n      -webkit-undefined;\n      -moz-undefined;\n      -undefined;\n    }\n    ```\n\n    This code will no longer prevent esbuild from processing the CSS file.\n\n* Treat `url(...)` in CSS files as an import ([#415](https://github.com/evanw/esbuild/issues/415))\n\n    When bundling, the `url(...)` syntax in CSS now tries to resolve the URL as a path using the bundler's built in path resolution logic. The following loaders can be used with this syntax: `text`, `base64`, `file`, `dataurl`, and `binary`.\n\n* Automatically treat certain paths as external\n\n    The following path forms are now automatically considered external:\n\n    * `http://example.com/image.png`\n    * `https://example.com/image.png`\n    * `//example.com/image.png`\n    * `data:image/png;base64,iVBORw0KGgo=`\n\n    In addition, paths starting with `#` are considered external in CSS files, which allows the following syntax to continue to work:\n\n    ```css\n    path {\n      /* This can be useful with SVG DOM content */\n      fill: url(#filter);\n    }\n    ```\n\n## 0.7.7\n\n* Fix TypeScript decorators on static members\n\n    This release fixes a bug with the TypeScript transform for the `experimentalDecorators` setting. Previously the target object for all decorators was the class prototype, which was incorrect for static members. Static members now correctly use the class object itself as a target object.\n\n* Experimental support for CSS syntax ([#20](https://github.com/evanw/esbuild/issues/20))\n\n    This release introduces the new `css` loader, enabled by default for `.css` files. It has the following features:\n\n    * You can now use esbuild to process CSS files by passing a CSS file as an entry point. This means CSS is a new first-class file type and you can use it without involving any JavaScript code at all.\n\n    * When bundling is enabled, esbuild will bundle multiple CSS files together if they are referenced using the `@import \"./file.css\";` syntax. CSS files can be excluded from the bundle by marking them as external similar to JavaScript files.\n\n    * There is basic support for pretty-printing CSS, and for whitespace removal when the `--minify` flag is present. There isn't any support for CSS syntax compression yet. Note that pretty-printing and whitespace removal both rely on the CSS syntax being recognized. Currently esbuild only recognizes certain CSS syntax and passes through unrecognized syntax unchanged.\n\n    Some things to keep in mind:\n\n    * CSS support is a significant undertaking and this is the very first release. There are almost certainly going to be issues. This is an experimental release to land the code and get feedback.\n\n    * There is no support for CSS modules yet. Right now all class names are in the global namespace. Importing a CSS file into a JavaScript file will not result in any import names.\n\n    * There is currently no support for code splitting of CSS. I haven't tested multiple entry-point scenarios yet and code splitting will require additional changes to the AST format.\n\n## 0.7.6\n\n* Fix JSON files with multiple entry points ([#413](https://github.com/evanw/esbuild/issues/413))\n\n    This release fixes an issue where a single build operation containing multiple entry points and a shared JSON file which is used by more than one of those entry points can generate incorrect code for the JSON file when code splitting is disabled. The problem was not cloning the AST representing the JSON file before mutating it.\n\n* Silence warnings about `require.resolve()` for external paths ([#410](https://github.com/evanw/esbuild/issues/410))\n\n    Bundling code containing a call to node's [`require.resolve()`](https://nodejs.org/api/modules.html#modules_require_resolve_request_options) function causes a warning because it's an unsupported use of `require` that does not end up being bundled. For example, the following code will likely have unexpected behavior if `foo` ends up being bundled because the `require()` call is evaluated at bundle time but the `require.resolve()` call is evaluated at run time:\n\n    ```js\n    let foo = {\n      path: require.resolve('foo'),\n      module: require('foo'),\n    };\n    ```\n\n    These warnings can already be disabled by surrounding the code with a `try`/`catch` statement. With this release, these warnings can now also be disabled by marking the path as external.\n\n* Ensure external relative paths start with `./` or `../`\n\n    Individual file paths can be marked as external in addition to package paths. In that case, the path to the file is rewritten to be relative to the output directory. However, previously the relative path for files in the output directory itself did not start with `./`, meaning they could potentially be interpreted as a package path instead of a relative path. These paths are now prefixed with `./` to avoid this edge case.\n\n## 0.7.5\n\n* Fix an issue with automatic semicolon insertion after `let` ([#409](https://github.com/evanw/esbuild/issues/409))\n\n    The character sequence `let` can be considered either a keyword or an identifier depending on the context. A fix was previously landed in version 0.6.31 to consider `let` as an identifier in code like this:\n\n    ```js\n    if (0) let\n    x = 0\n    ```\n\n    Handling this edge case is useless but the behavior is required by the specification. However, that fix also unintentionally caused `let` to be considered an identifier in code like this:\n\n    ```js\n    let\n    x = 0\n    ```\n\n    In this case, `let` should be considered a keyword instead. This has been fixed.\n\n* Fix some additional conformance tests\n\n    Some additional syntax edge cases are now forbidden including `let let`, `import {eval} from 'path'`, and `if (1) x: function f() {}`.\n\n## 0.7.4\n\n* Undo an earlier change to try to improve yarn compatibility ([#91](https://github.com/evanw/esbuild/pull/91) and [#407](https://github.com/evanw/esbuild/issues/407))\n\n    The [yarn package manager](https://github.com/yarnpkg/yarn) behaves differently from npm and is not compatible in many ways. While npm is the only officially supported package manager for esbuild, people have contributed fixes for other package managers including yarn. One such fix is PR [#91](https://github.com/evanw/esbuild/pull/91) which makes sure the install script only runs once for a given installation directory.\n\n    I suspect this fix is actually incorrect, and is the cause of issue [#407](https://github.com/evanw/esbuild/issues/407). The problem seems to be that if you change the version of a package using `yarn add esbuild@version`, yarn doesn't clear out the installation directory before reinstalling the package so the package ends up with a mix of files from both package versions. This is not how npm behaves and seems like a pretty severe bug in yarn. I am reverting PR [#91](https://github.com/evanw/esbuild/pull/91) in an attempt to fix this issue.\n\n* Disable some warnings for code inside `node_modules` directories ([#395](https://github.com/evanw/esbuild/issues/395) and [#402](https://github.com/evanw/esbuild/issues/402))\n\n    Using esbuild to build code with certain suspicious-looking syntax may generate a warning. These warnings don't fail the build (the build still succeeds) but they point out code that is very likely to not behave as intended. This has caught real bugs in the past:\n\n    * [rollup/rollup#3729](https://github.com/rollup/rollup/issues/3729): Invalid dead code removal for return statement due to ASI\n    * [aws/aws-sdk-js#3325](https://github.com/aws/aws-sdk-js/issues/3325): Array equality bug in the Node.js XML parser\n    * [olifolkerd/tabulator#2962](https://github.com/olifolkerd/tabulator/issues/2962): Nonsensical comparisons with typeof and \"null\"\n    * [mrdoob/three.js#11183](https://github.com/mrdoob/three.js/pull/11183): Comparison with -0 in Math.js\n    * [mrdoob/three.js#11182](https://github.com/mrdoob/three.js/pull/11182): Operator precedence bug in WWOBJLoader2.js\n\n    However, it's not esbuild's job to find bugs in other libraries, and these warnings are problematic for people using these libraries with esbuild. The only fix is to either disable all esbuild warnings and not get warnings about your own code, or to try to get the warning fixed in the affected library. This is especially annoying if the warning is a false positive as was the case in https://github.com/firebase/firebase-js-sdk/issues/3814. So these warnings are now disabled for code inside `node_modules` directories.\n\n## 0.7.3\n\n* Fix compile error due to missing `unix.SYS_IOCTL` in the latest `golang.org/x/sys` ([#396](https://github.com/evanw/esbuild/pull/396))\n\n    The `unix.SYS_IOCTL` export was apparently removed from `golang.org/x/sys` recently, which affected code in esbuild that gets the width of the terminal. This code now uses another method of getting the terminal width. The fix was contributed by [@akayj](https://github.com/akayj).\n\n* Validate that the versions of the host code and the binary executable match ([#407](https://github.com/evanw/esbuild/issues/407))\n\n    After the install script runs, the version of the downloaded binary should always match the version of the package being installed. I have added some additional checks to verify this in case this invariant is ever broken. Breaking this invariant is very bad because it means the code being run is a mix of code from different package versions.\n\n## 0.7.2\n\n* Transform arrow functions to function expressions with `--target=es5` ([#182](https://github.com/evanw/esbuild/issues/182) and [#297](https://github.com/evanw/esbuild/issues/297))\n\n    Arrow functions are now transformed into function expressions when targeting `es5`. For example, this code:\n\n    ```js\n    function foo() {\n      var x = () => [this, arguments]\n      return x()\n    }\n    ```\n\n    is transformed into this code:\n\n    ```js\n    function foo() {\n      var _this = this, _arguments = arguments;\n      var x = function() {\n        return [_this, _arguments];\n      };\n      return x();\n    }\n    ```\n\n* Parse template literal types from TypeScript 4.1\n\n    TypeScript 4.1 includes a new feature called template literal types. You can read [the announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-1-beta/#template-literal-types) for more details. The following syntax can now be parsed correctly by esbuild:\n\n    ```ts\n    let foo: `${'a' | 'b'}-${'c' | 'd'}` = 'a-c'\n    ```\n\n* Parse key remapping in mapped types from TypeScript 4.1\n\n    TypeScript 4.1 includes a new feature called key remapping in mapped types. You can read [the announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-1-beta/#key-remapping-mapped-types) for more details. The following syntax can now be parsed correctly by esbuild:\n\n    ```ts\n    type RemoveField<T, F> = { [K in keyof T as Exclude<K, F>]: T[K] }\n    ```\n\n* Allow automatic semicolon insertion before the TypeScript `as` operator\n\n    The following code now correctly parses as two separate statements instead of one statement with a newline in the middle:\n\n    ```ts\n    let foo = bar\n    as (null);\n    ```\n\n* Fix a bug where `module` was incorrectly minified for non-JavaScript loaders\n\n    If you pass a non-JavaScript file such as a `.json` file to esbuild, it will by default generate `module.exports = {...}`. However, the `module` variable would incorrectly be minified when `--minify` is present. This issue has been fixed. This bug did not appear if `--format=cjs` was also present, only if no `--format` flag was specified.\n\n* Fix bugs with `async` functions ([#388](https://github.com/evanw/esbuild/issues/388))\n\n    This release contains correctness fixes for `async` arrow functions with regard to the `arguments` variable. This affected `async` arrow functions nested inside `function` expressions or statements. Part of this fix was contributed by [@rtsao](https://github.com/rtsao).\n\n* Fix `export` clause when converting to CommonJS in transform API calls ([#393](https://github.com/evanw/esbuild/issues/393))\n\n    This release fixes some bugs with the recently-released feature in version 0.6.32 where you can specify an output format even when bundling is disabled. This is the case when using the transform API call, for example. Previously esbuild could generate code that crashed at run time while trying to export something incorrectly. This only affected code with top-level `export` statements. This has been fixed and these cases now have test coverage.\n\n## 0.7.1\n\n* Fix bug that forbids `undefined` values in the JavaScript API\n\n    The validation added in the previous release was accidentally overly restrictive and forbids `undefined` values for optional properties. This release allows `undefined` values again (which are simply ignored).\n\n## 0.7.0\n\n* Mark output files with a hashbang as executable ([#364](https://github.com/evanw/esbuild/issues/364))\n\n    Output files that start with a hashbang line such as `#!/usr/bin/env node` will now automatically be marked as executable. This lets you run them directly in a Unix-like shell without using the `node` command.\n\n* Use `\"main\"` for `require()` and `\"module\"` for `import` ([#363](https://github.com/evanw/esbuild/issues/363))\n\n    The [node module resolution algorithm](https://nodejs.org/api/modules.html#modules_all_together) uses the `\"main\"` field in `package.json` to determine which file to load when a package is loaded with `require()`. Independent of node, most bundlers have converged on a convention where the `\"module\"` field takes precedence over the `\"main\"` field when present. Package authors can then use the `\"module\"` field to publish the same code in a different format for bundlers than for node.\n\n    This is commonly used to publish \"dual packages\" that appear to use ECMAScript modules to bundlers but that appear to use CommonJS modules to node. This is useful because ECMAScript modules improve bundler output by taking advantage of \"tree shaking\" (basically dead-code elimination) and because ECMAScript modules cause lots of problems in node (for example, node doesn't support importing ECMAScript modules using `require()`).\n\n    The problem is that if code using `require()` resolves to the `\"module\"` field in esbuild, the resulting value is currently always an object. ECMAScript modules export a namespace containing all exported properties. There is no direct equivalent of `module.exports = value` in CommonJS. The closest is `export default value` but the CommonJS equivalent of that is `exports.default = value`. This is problematic for code containing `module.exports = function() {}` which is a frequently-used CommonJS library pattern. An example of such an issue is Webpack issue [#6584](https://github.com/webpack/webpack/issues/6584).\n\n    An often-proposed way to fix this is to map `require()` to `\"main\"` and map `import` to `\"module\"`. The problem with this is that it means the same package would be loaded into memory more than once if it is loaded both with `require()` and with `import` (perhaps from separate packages). An example of such an issue is GraphQL issue [#1479](https://github.com/graphql/graphql-js/issues/1479#issuecomment-416718578).\n\n    The workaround for these problems in this release is that esbuild will now exclusively use `\"main\"` for a package that is loaded using `require()` at least once. Otherwise, if a package is only loaded using `import`, esbuild will exclusively use the `\"module\"` field. This still takes advantage of tree shaking for ECMAScript modules but gracefully falls back to CommonJS for compatibility.\n\n    Keep in mind that the [`\"browser\"` field](https://github.com/defunctzombie/package-browser-field-spec) still takes precedence over both `\"module\"` and `\"main\"` when building for the browser platform.\n\n* Add the `--main-fields=` flag ([#363](https://github.com/evanw/esbuild/issues/363))\n\n    This adopts a configuration option from Webpack that lets you specify the order of \"main fields\" from `package.json` to use when determining the main module file for a package. Node only uses `main` but bundlers often respect other ones too such as `module` or `browser`. You can read more about this feature in the Webpack documentation [here](https://webpack.js.org/configuration/resolve/#resolvemainfields).\n\n    The default order when targeting the browser is essentially `browser,module,main` with the caveat that `main` may be chosen over `module` for CommonJS compatibility as described above. If choosing `module` over `main` at the expense of CommonJS compatibility is important to you, this behavior can be disabled by explicitly specifying `--main-fields=browser,module,main`.\n\n    The default order when targeting node is `main,module`. Note that this is different than Webpack, which defaults to `module,main`. This is also for compatibility because some packages incorrectly treat `module` as meaning \"code for the browser\" instead of what it actually means, which is \"code for ES6 environments\". Unfortunately this disables most tree shaking that would otherwise be possible because it means CommonJS modules will be chosen over ECMAScript modules. If choosing `module` over `main` is important to you (e.g. to potentially take advantage of improved tree shaking), this behavior can be disabled by explicitly specifying `--main-fields=module,main`.\n\n* Additional validation of arguments to JavaScript API calls ([#381](https://github.com/evanw/esbuild/issues/381))\n\n    JavaScript API calls each take an object with many optional properties as an argument. Previously there was only minimal validation of the contents of that object. If you aren't using TypeScript, this can lead to confusing situations when the data on the object is invalid. Now there is some additional validation done to the shape of the object and the types of the properties.\n\n    It is now an error to pass an object with a property that esbuild won't use. This should help to catch typos. It is also now an error if a property on the object has an unexpected type.\n\n## 0.6.34\n\n* Fix parsing of `type;` statements followed by an identifier in TypeScript ([#377](https://github.com/evanw/esbuild/pull/377))\n\n    The following TypeScript code is now correctly parsed as two separate expression statements instead of one type declaration statement:\n\n    ```ts\n    type\n    Foo = {}\n    ```\n\n    This was contributed by [@rtsao](https://github.com/rtsao).\n\n* Fix `export {Type}` in TypeScript when bundling ([#379](https://github.com/evanw/esbuild/issues/379))\n\n    In TypeScript, `export {Type}` is supposed to be silently removed by the compiler if `Type` does not refer to a value declared locally in the file. Previously this behavior was incompletely implemented. The statement itself was removed but the export record was not, so later stages of the pipeline could sometimes add the export statement back. This release removes the export record as well as the statement so it should stay removed in all cases.\n\n* Forbid exporting non-local symbols in JavaScript\n\n    It is now an error to export an identifier using `export {foo}` if `foo` is not declared locally in the same file. This error matches the error that would happen at run-time if the code were to be evaluated in a JavaScript environment that supports ES6 module syntax. This is only an error in JavaScript. In TypeScript, the missing identifier is silently removed instead since it's assumed to be a type name.\n\n* Handle source maps with out-of-order mappings ([#378](https://github.com/evanw/esbuild/issues/378))\n\n    Almost all tools that generate source maps write out the mappings in increasing order by generated position since the mappings are generated along with the output. However, some tools can apparently generate source maps with out-of-order mappings. It's impossible for generated line numbers to be out of order due to the way the source map format works, but it's possible for generated column numbers to be out of order. This release fixes this issue by sorting the mappings by generated position after parsing if necessary.\n\n## 0.6.33\n\n* Fix precedence of tagged template expressions ([#372](https://github.com/evanw/esbuild/issues/372))\n\n    Previously `` await tag`text` `` and `` new tag`text` `` were incorrectly parsed as `` (await tag)`text` `` and `` (new tag)`text` ``. They are now correctly parsed as `` await (tag`text`) `` and `` new (tag`text`) `` instead.\n\n* Fix invalid syntax when lowering `super` inside `async` to `es2016` or earlier ([#375](https://github.com/evanw/esbuild/issues/375))\n\n    This release fixes a bug where using `super.prop` inside an `async` function with `--target=es2016` or earlier generated code that contained a syntax error. This was because `async` functions are converted to generator functions inside a wrapper function in this case, and `super` is not available inside the wrapper function. The fix is to move the reference to `super` outside of the wrapper function.\n\n* Fix duplicate definition of `module` when targeting CommonJS ([#370](https://github.com/evanw/esbuild/issues/370))\n\n    The bundler didn't properly reserve the identifier `module` when using `--format=cjs`. This meant automatically-generated variables named `module` could potentially not be renamed to avoid collisions with the CommonJS `module` variable. It was possible to get into this situation when importing a module named `module`, such as the [node built-in module by that name](https://nodejs.org/api/module.html). This name is now marked as reserved when bundling to CommonJS, so automatically-generated variables named `module` will now be renamed to `module2` to avoid collisions.\n\n## 0.6.32\n\n* Allow `--format` when bundling is disabled ([#109](https://github.com/evanw/esbuild/issues/109))\n\n    This change means esbuild can be used to convert ES6 import and export syntax to CommonJS syntax. The following code:\n\n    ```js\n    import foo from 'foo'\n    export const bar = foo\n    ```\n\n    will be transformed into the following code with `--format=cjs` (the code for `__export` and `__toModule` was omitted for brevity):\n\n    ```js\n    __export(exports, {\n      bar: () => bar\n    });\n    const foo = __toModule(require(\"foo\"));\n    const bar = foo.default;\n    ```\n\n    This also applies to non-JavaScript loaders too. The following JSON:\n\n    ```json\n    {\"foo\": true, \"bar\": false}\n    ```\n\n    is normally converted to the following code with `--loader=json`:\n\n    ```js\n    module.exports = {foo: true, bar: false};\n    ```\n\n    but will be transformed into the following code instead with `--loader=json --format=esm`:\n\n    ```js\n    var foo = true;\n    var bar = false;\n    var stdin_default = {foo, bar};\n    export {\n      bar,\n      stdin_default as default,\n      foo\n    };\n    ```\n\n    Note that converting CommonJS `require()` calls to ES6 imports is not currently supported. Code containing a reference to `require` in these situations will generate a warning.\n\n* Change the flag for boolean and string minification ([#371](https://github.com/evanw/esbuild/issues/371))\n\n    Previously setting the `--minify-whitespace` flag shortened `true` and `false` to `!0` and `!1` and shortened string literals containing many newlines by writing them as template literals instead. These shortening operations have been changed to the `--minify-syntax` flag instead. There is no change in behavior for the `--minify` flag because that flag already implies both `--minify-whitespace` and `--minify-syntax`.\n\n* Remove trailing `()` from `new` when minifying\n\n    Now `new Foo()` will be printed as `new Foo` when minifying (as long as it's safe to do so), resulting in slightly shorter minified code.\n\n* Forbid `async` functions when the target is `es5`\n\n    Previously using `async` functions did not cause a compile error when targeting `es5` since if they are unavailable, they are rewritten to use generator functions instead. However, generator functions may also be unsupported. It is now an error to use `async` functions if generator functions are unsupported.\n\n* Fix subtle issue with transforming `async` functions when targeting `es2016` or below\n\n    The TypeScript compiler has a bug where, when the language target is set to `ES2016` or earlier, exceptions thrown during argument evaluation are incorrectly thrown immediately instead of later causing the returned promise to be rejected. Since esbuild replicates TypeScript's `async` function transformation pass, esbuild inherited this same bug. The behavior of esbuild has been changed to match the JavaScript specification.\n\n    Here's an example of code that was affected:\n\n    ```js\n    async function test(value = getDefaultValue()) {}\n    let promise = test()\n    ```\n\n    The call to `test()` here should never throw, even if `getDefaultValue()` throws an exception.\n\n## 0.6.31\n\n* Invalid source maps are no longer an error ([#367](https://github.com/evanw/esbuild/issues/367))\n\n    Previously esbuild would fail the build with an error if it encountered a source map that failed validation according to [the specification](https://sourcemaps.info/spec.html). Now invalid source maps will be validated with an error-tolerant validator that will either silently ignore errors or generate a warning, but will never fail the build.\n\n* Fix various edge cases for conformance tests\n\n    * Hoisted function declarations in nested scopes can now shadow symbols in the enclosing scope without a syntax error:\n\n        ```js\n        let foo\n        {\n          function foo() {}\n        }\n        ```\n\n    * If statements directly containing function declarations now introduce a nested scope so this code is no longer a syntax error:\n\n        ```js\n        let foo\n        if (true)\n          function foo() {}\n        ```\n\n    * Keywords can now be used as export aliases with `export * as` statements:\n\n        ```js\n        export * as class from 'path'\n        ```\n\n    * It is now a syntax error to use `break` or `continue` in invalid locations:\n\n        ```js\n        function foo() { break }\n        ```\n\n    * Using `yield` as an identifier outside of a generator function is now allowed:\n\n        ```js\n        var yield = null\n        ```\n\n    * It is now a syntax error to use `yield` or `await` inside a generator or `async` function if it contains an escape sequence:\n\n        ```js\n        async function foo() {\n          return \\u0061wait;\n        }\n        ```\n\n    * It is now a syntax error to use an `import()` expression with the `new` operator without parentheses:\n\n        ```js\n        new import('path')\n        ```\n\n    * Using `let` as an identifier is now allowed:\n\n        ```js\n        let = null\n        ```\n\n    * It is no longer a compile-time error to assign to an import when not bundling:\n\n        ```js\n        import {foo} from 'path'\n        foo = null\n        ```\n\n        Instead the behavior will be left up to the host environment at run-time, which should cause a run-time error. However, this will still be treated as a compile-time error when bundling because the scope-hoisting optimization that happens during bundling means the host may no longer cause run-time errors.\n\n    * You can now declare a variable named `arguments` inside a function without an error:\n\n        ```js\n        function foo() {\n          let arguments = null\n        }\n        ```\n\n    * Comma expressions in the iterable position of for-of loops are now a syntax error:\n\n        ```js\n        for (var a of b, c) {\n        }\n        ```\n\n    * It is now a syntax error to use `||` or `&&` with `??` without parentheses\n\n        ```js\n        a ?? b || c   // Syntax error\n        a ?? (b || c) // Allowed\n        (a ?? b) || c // Allowed\n        ```\n\n    * It is now a syntax error to use `arguments` inside a `class` field initializer\n\n        ```js\n        class Foo {\n          foo = arguments\n        }\n        ```\n\n    * It is now a syntax error to a strict mode reserved word to name a `class`\n\n        ```js\n        class static {}\n        ```\n\n## 0.6.30\n\n* Fix optional call of `super` property ([#362](https://github.com/evanw/esbuild/issues/362))\n\n    This fixes a bug where lowering the code `super.foo?.()` was incorrectly transformed to this:\n\n    ```js\n    var _a, _b;\n    (_b = (_a = super).foo) == null ? void 0 : _b.call(_a);\n    ```\n\n    This is invalid code because a bare `super` keyword is not allowed. Now that code is transformed to this instead:\n\n    ```js\n    var _a;\n    (_a = super.foo) == null ? void 0 : _a.call(this);\n    ```\n\n* Add a `--strict:optional-chaining` option\n\n    This affects the transform for the `?.` optional chaining operator. In loose mode (the default), `a?.b` is transformed to `a == null ? void 0 : a.b`. This works fine in all cases except when `a` is the special object `document.all`. In strict mode, `a?.b` is transformed to `a === null || a === void 0 ? void 0 : a.b` which works correctly with `document.all`. Enable `--strict:optional-chaining` if you need to use `document.all` with the `?.` operator.\n\n## 0.6.29\n\n* Add a warning for comparison with `NaN`\n\n    This warning triggers for code such as `x === NaN`. Code that does this is almost certainly a bug because `NaN === NaN` is false in JavaScript.\n\n* Add a warning for duplicate switch case clauses\n\n    This warning detects situations when multiple `case` clauses in the same `switch` statement match on the same expression. This almost certainly indicates a problem with the code. This warning protects against situations like this:\n\n    ```js\n    switch (typeof x) {\n      case 'object':\n        // ...\n      case 'function':\n        // ...\n      case 'boolean':\n        // ...\n      case 'object':\n        // ...\n    }\n    ```\n\n* Allow getters and setters in ES5 ([#356](https://github.com/evanw/esbuild/issues/356))\n\n    This was an oversight. I incorrectly thought getters and setters were added in ES6, not in ES5. This release allows getter and setter method syntax even when `--target=es5`.\n\n* Fix a Windows-only regression with missing directory errors ([#359](https://github.com/evanw/esbuild/issues/359))\n\n    Various Go file system APIs return `ENOTDIR` for missing file system entries on Windows instead of `ENOENT` like they do on other platforms. This interfered with code added in the previous release that makes unexpected file system errors no longer silent. `ENOTDIR` is usually an unexpected error because it's supposed to happen when the file system entry is present but just unexpectedly a file instead of a directory. This release changes `ENOTDIR` to `ENOENT` in certain cases so that these Windows-only errors are no longer treated as unexpected errors.\n\n* Enforce object accessor argument counts\n\n    According to the JavaScript specification, getter methods must have zero arguments and setter methods must have exactly one argument. This release enforces these rules.\n\n* Validate assignment targets\n\n    Code containing invalid assignments such as `1 = 2` will now be correctly rejected as a syntax error. Previously such code was passed through unmodified and the output file would contain a syntax error (i.e. \"garbage in, garbage out\").\n\n## 0.6.28\n\n* Avoid running out of file handles when ulimit is low ([#348](https://github.com/evanw/esbuild/issues/348))\n\n    When esbuild uses aggressive concurrency, it can sometimes simultaneously use more file handles than allowed by the system. This can be a problem when the limit is low (e.g. using `ulimit -n 32`). In this release, esbuild now limits itself to using a maximum of 32 file operations simultaneously (in practice this may use up to 64 file handles since some file operations need two handles). This limit was chosen to be low enough to not cause issues with normal ulimit values but high enough to not impact benchmark times.\n\n* Unexpected file system errors are no longer silent ([#348](https://github.com/evanw/esbuild/issues/348))\n\n    All file system errors were previously treated the same; any error meant the file or directory was considered to not exist. This was problematic when the process ran out of available file handles because it meant esbuild could ignore files that do actually exist if file handles are exhausted. Then esbuild could potentially generate a different output instead of failing with an error. Now if esbuild gets into this situation, it should report unexpected file system errors and fail to build instead of continuing to build and potentially producing incorrect output.\n\n* Install script tries `npm install` before a direct download ([#347](https://github.com/evanw/esbuild/issues/347))\n\n    The `esbuild` package has a post-install script that downloads the native binary for the current platform over HTTP. Some people have configured their environments such that HTTP requests to npmjs.org will hang, and configured npm to use a proxy for HTTP requests instead. In this case, esbuild's install script will still work as long as `npm install` works because the HTTP request will eventually time out, at which point the install script will run `npm install` as a fallback. The timeout is of course undesirable.\n\n    This release changes the order of attempted download methods in the install script. Now `npm install` is tried first and directly downloading the file over HTTP will be tried as a fallback. This means installations will be slightly slower since npm is slow, but it should avoid the situation where the install script takes a long time because it's waiting for a HTTP timeout. This should still support the scenarios where there is a HTTP proxy configured, where there is a custom registry configured, and where the `npm` command isn't available.\n\n## 0.6.27\n\n* Add parentheses when calling `require()` inside `new` ([#339](https://github.com/evanw/esbuild/issues/339))\n\n    This release fixes an issue where `new (require('path')).ctor()` became `new require_path().ctor()` after bundling, which caused `require_path()` to be invoked as the constructor instead of `ctor()`. With this fix the code `new (require_path()).ctor()` is generated instead, which correctly invokes `ctor()` as the constructor. This was contributed by [@rtsao](https://github.com/rtsao).\n\n## 0.6.26\n\n* Fix syntax error when minifying and bundling CommonJS to ES5 ([#335](https://github.com/evanw/esbuild/issues/335))\n\n    With the flags `--minify --bundle --target=es5`, esbuild had a bug where the arrow function for the closure used to wrap CommonJS modules was not correctly printed as an ES5 function expression, causing a syntax error. This bug has been fixed.\n\n## 0.6.25\n\n* Avoid the `\\v` escape sequence in JSON strings\n\n    Source maps are JSON files, and must obey the [JSON specification](https://www.json.org/). The escape sequence `\\v` (for the ASCII control character 11) is valid in JavaScript but not in JSON. Previously esbuild contained a bug where source maps for files containing this ASCII control character were invalid JSON. This release fixes the bug by printing this character as `\\u000B` instead.\n\n* Speedup for `esbuild-wasm` when using the command line\n\n    The [esbuild-wasm](https://www.npmjs.com/package/esbuild-wasm) package includes a WebAssembly command-line tool called `esbuild` which functions the same as the native command-line tool called `esbuild` in the [esbuild](https://www.npmjs.com/package/esbuild) package. The difference is that the WebAssembly implementation is around an order of magnitude slower than the native version.\n\n    This release changes the API used to instantiate the WebAssembly module from [WebAssembly.instantiate](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate) to [WebAssembly.Module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/Module), which reduces end-to-end build time by around 1 second on my development laptop. The WebAssembly version is still much slower than the native version, but now it's a little faster than before.\n\n* Optimize for the [@material-ui/icons](https://www.npmjs.com/package/@material-ui/icons) package\n\n    This package has a directory containing over 11,000 files. Certain optimizations in esbuild that worked fine for common cases severely impacted performance for this edge case. This release changes some aspects of path resolution caching to fix these problems. Build time for a certain benchmark involving this package improved from 1.01s for the previous release to 0.22s for this release. Other benchmark times appear to be unaffected.\n\n## 0.6.24\n\n* Switch from base64 encoding to base32 encoding for file hashes\n\n    Certain output files contain hashes in their name both to prevent collisions and to improve caching. For example, an SVG file named `example.svg` that is loaded using the `file` loader might be copied to a file named `example.T3K5TRK4.svg` in the build directory. The hashes are based on the file's contents so they only change when the file content itself changes.\n\n    The hashes previously used [base64 encoding](https://en.wikipedia.org/wiki/Base64) but I recently realized that since certain file systems (e.g. Windows) are case-insensitive, this could lead to confusing situations where esbuild could theoretically generate two files with different case-sensitive names but with the same case-insensitive name. Hashes now use [base32 encoding](https://en.wikipedia.org/wiki/Base32) which only includes uppercase letters, not lowercase letters, which should avoid this confusing situation.\n\n* Optimize character frequency for better gzip compression\n\n    The character sequence used to generate minified names is now the characters in the input files sorted descending by frequency. Previously it was just the valid identifier characters in alphabetic order. This means minified names are more likely to contain characters found elsewhere in the output file (e.g. in keywords and strings). This is a pretty small win but it was added because it's a consistent win, it's simple to implement, and it's very fast to compute.\n\n* Minor syntax minification improvements\n\n    This release contains these additional rules for syntax minification:\n\n    * `a ? b : b` is minified to `a, b`\n    * `a ? a : b` is minified to `a || b`\n    * `a ? b : a` is minified to `a && b`\n    * `a == void 0` is minified to `a == null`\n    * `a && (b && c)` is minified to `a && b && c` (same for `||`)\n    * `a ? c : (b, c)` is minified to `(a || b), c`\n    * `a ? (b, c) : c` is minified to `(a && b), c`\n    * `a ? b || c : c` is minified to `(a && b) || c`\n    * `a ? c : b && c` is minified to `(a || b) && c`\n    * `a ? b(c) : b(d)` is minified to `b(a ? c : d)`\n    * `a ? true : false` is minified to `!!a`\n    * `a != null ? a : b` is minified to `a ?? b` if it's supported in the target environment\n    * `a ? (b ? c : d) : d` is minified to `(a && b) ? c : d`\n    * `a ? b : (c ? b : d)` is minified to `(a || c) ? b : d`\n    * `(function foo() {})` is minified to `(function() {})`\n    * `typeof a === \"string\"` is minified to `typeof a == \"string\"`\n    * `if (a) if (b) return c` is minified to `if (a && b) return c`\n    * `while (a) if (!b) break;` is minified to `for (; a && b; ) ;`\n    * `a === null || a === undefined` is minified to `a == null`\n\n    These improvements cause minified code to be slightly smaller.\n\n## 0.6.23\n\n* Add an error message for a missing `--tsconfig` file ([#330](https://github.com/evanw/esbuild/issues/330))\n\n    The `--tsconfig` flag that was added in version 0.6.1 didn't report an error if the provided file doesn't actually exist. This release makes doing this an error that will fail the build.\n\n* Avoid generating the minified label name `if` ([#332](https://github.com/evanw/esbuild/issues/332))\n\n    The recent minification changes in 0.6.20 introduced a regression where input files containing 333 or more label statements resulted in a label being assigned the minified name `if`, which is a JavaScript keyword. This is the first JavaScript keyword in the minified name sequence that esbuild uses for label names: `a b c ... aa ba ca ...`. The regression has been fixed and there is now test coverage for this case.\n\n## 0.6.22\n\n* The bell character is now escaped\n\n    In most terminals, printing the bell character (ASCII code 7) will trigger a sound. The macOS terminal will also flash the screen if sound is muted. This is annoying, and can happen when dumping the output of esbuild to the terminal if the input contains a bell character. Now esbuild will always escape bell characters in the output to avoid this problem.\n\n* CommonJS modules now export properties of prototype ([#326](https://github.com/evanw/esbuild/issues/326))\n\n    This change is for compatibility with Webpack. You can now assign an object with a custom prototype to `module.exports` and esbuild will consider all enumerable properties on the prototype as exports. This behavior is necessary to correctly bundle the [paper.js](https://github.com/paperjs/paper.js) library, for example.\n\n## 0.6.21\n\n* Upgrade from Go 1.14 to Go 1.15\n\n    This change isn't represented by a commit in the repo, but from now on I will be using Go 1.15 to build the distributed binaries instead of Go 1.14. The [release notes for Go 1.15](https://golang.org/doc/go1.15) mention improvements to binary size:\n\n    > Go 1.15 reduces typical binary sizes by around 5% compared to Go 1.14 by eliminating certain types of GC metadata and more aggressively eliminating unused type metadata.\n\n    Initial testing shows that upgrading Go reduces the esbuild binary size on macOS from 7.4mb to 5.3mb, which is a 30% smaller binary! I assume the binary size savings are similar for other platforms. Run-time performance on the esbuild benchmarks seems consistent with previous releases.\n\n* Lower non-tag template literals to ES5 ([#297](https://github.com/evanw/esbuild/issues/297))\n\n    You can now use non-tag template literals such as `` `abc` `` and `` `a${b}c` `` with `--target=es5` and esbuild will convert them to string addition such as `\"abc\"` and `\"a\" + b + \"c\"` instead of reporting an error.\n\n* Newline normalization in template literals\n\n    This fixes a bug with esbuild that caused carriage-return characters to incorrectly end up in multi-line template literals if the source file used Windows-style line endings (i.e. `\\r\\n`). The ES6 language specification says that both carriage-return characters and Windows carriage-return line-feed sequences must be converted to line-feed characters instead. With this change, esbuild's parsing of multi-line template literals should no longer be platform-dependent.\n\n* Fix minification bug with variable hoisting\n\n    Hoisted variables that are declared with `var` in a nested scope but hoisted to the top-level scope were incorrectly minified as a nested scope symbol instead of a top-level symbol, which could potentially cause a name collision. This bug has been fixed.\n\n## 0.6.20\n\n* Symbols are now renamed separately per chunk ([#16](https://github.com/evanw/esbuild/issues/16))\n\n    Previously, bundling with code splitting assigned minified names using a single frequency distribution calculated across all chunks. This meant that typical code changes in one chunk would often cause the contents of all chunks to change, which negated some of the benefits of the browser cache.\n\n    Now symbol renaming (both minified and not minified) is done separately per chunk. It was challenging to implement this without making esbuild a lot slower and causing it to use a lot more memory. Symbol renaming has been mostly rewritten to accomplish this and appears to actually usually use a little less memory and run a bit faster than before, even for code splitting builds that generate a lot of chunks. In addition, minified chunks are now slightly smaller because a given minified name can now be reused by multiple chunks.\n\n## 0.6.19\n\n* Reduce memory usage for large builds by 30-40% ([#304](https://github.com/evanw/esbuild/issues/304))\n\n    This release reduces memory usage. These specific percentages are likely only accurate for builds with a large number of files. Memory is reduced by ~30% for all builds by avoiding unnecessary per-file symbol maps, and is reduced by an additional ~10% for builds with source maps by preallocating some large arrays relating to source map output.\n\n* Replace `.js` and `.jsx` with `.ts` or `.tsx` when resolving ([#118](https://github.com/evanw/esbuild/issues/118))\n\n    This adds an import path resolution behavior that's specific to the TypeScript compiler where you can use an import path that ends in `.js` or `.jsx` when the correct import path actually ends in `.ts` or `.tsx` instead. See the discussion here for more historical context: https://github.com/microsoft/TypeScript/issues/4595.\n\n## 0.6.18\n\n* Install script falls back to `npm install` ([#319](https://github.com/evanw/esbuild/issues/319))\n\n    The `esbuild` package has a post-install script that downloads the esbuild binary. However, this will fail if `registry.npmjs.org` (or the configured custom npm registry) is inaccessible.\n\n    This release adds an additional fallback for when the download fails. It tries to use the `npm install` command to download the esbuild binary instead. This handles situations where users have either configured npm with a proxy or have a custom command in their path called `npm`.\n\n## 0.6.17\n\n* Add a download cache to the install script\n\n    This speeds up repeated esbuild installs for the same version by only downloading the binary from npm the first time and then reusing it for subsequent installs. The binary files are cached in these locations, which are the same locations as the Electron install script:\n\n    * Windows: `%USERPROFILE%\\AppData\\Local\\Cache\\esbuild\\bin`\n    * macOS: `~/Library/Caches/esbuild/bin`\n    * Other: `~/.cache/esbuild/bin`\n\n    The cache holds a maximum of 5 entries and purges least-recently-used entries above that limit.\n\n* Omit `export default` of local type names ([#316](https://github.com/evanw/esbuild/issues/316))\n\n    Normally the `export default` syntax takes a value expression to export. However, TypeScript has a special case for `export default <identifier>` where the identifier is allowed to be a type expression instead of a value expression. In that case, the type expression should not be emitted in the resulting bundle. This release improves support for this case by omitting the export when the identifier matches a local type name.\n\n## 0.6.16\n\n* Colors for Windows console output\n\n    Console output on Windows now uses color instead of being monochrome. This should make log messages easier to read.\n\n* Parenthesize destructuring assignment in arrow function expressions ([#313](https://github.com/evanw/esbuild/issues/313))\n\n    This fixes a bug where `() => ({} = {})` was incorrectly printed as `() => ({}) = {}`, which is a syntax error. This case is now printed correctly.\n\n## 0.6.15\n\n* Support symlinks with absolute paths in `node_modules` ([#310](https://github.com/evanw/esbuild/issues/310))\n\n    Previously esbuild only supported symlinks with relative paths, not absolute paths. Adding support for absolute paths in symlinks fixes issues with esbuild and [pnpm](https://github.com/pnpm/pnpm) on Windows.\n\n* Preserve leading comments inside `import()` expressions ([#309](https://github.com/evanw/esbuild/issues/309))\n\n    This makes it possible to use esbuild as a faster TypeScript-to-JavaScript frontend for Webpack, which has special [magic comments](https://webpack.js.org/api/module-methods/#magic-comments) inside `import()` expressions that affect Webpack's behavior.\n\n* Fix crash for source files beginning with `\\r\\n` when using source maps ([#311](https://github.com/evanw/esbuild/issues/311))\n\n    The source map changes in version 0.6.13 introduced a regression that caused source files beginning with `\\r\\n` to crash esbuild when source map generation was enabled. This was not caught during testing both because not many source files begin with a newline and not many source files have Windows-style line endings in them. This regression has been fixed and Windows-style line endings now have test coverage.\n\n## 0.6.14\n\n* Add support for parsing top-level await ([#253](https://github.com/evanw/esbuild/issues/253))\n\n    It seems appropriate for esbuild to support top-level await syntax now that [node is supporting top-level await syntax by default](https://github.com/nodejs/node/issues/34551) (it's the first widely-used platform to do so). This syntax can now be parsed by esbuild and is always passed through untransformed. It's only allowed when the target is `esnext` because the proposal is still in stage 3. It also cannot be used when bundling. Adding support for top-level await to the bundler is complicated since it causes imports to be asynchronous, which has far-reaching implications. This change is mainly for people using esbuild as a library to transform TypeScript into JavaScript one file at a time.\n\n## 0.6.13\n\n* Exclude non-JavaScript files from source maps ([#304](https://github.com/evanw/esbuild/issues/304))\n\n    Previously all input files were eligible for source map generation, even binary files included using loaders such as `dataurl`. This was not intentional. Doing this doesn't serve a purpose and can massively bloat the resulting source maps. Now all files are excluded except those loaded by the `js`, `jsx`, `ts`, and `tsx` loaders.\n\n* Fix incorrect source maps with code splitting ([#303](https://github.com/evanw/esbuild/issues/303))\n\n    Source maps were completely incorrect when code splitting was enabled for chunk files that imported other chunk files. The source map offsets were not being adjusted past the automatically-generated cross-chunk import statements. This has been fixed.\n\n* Change source map column offsets from bytes to UTF-16 code units\n\n    The [source map specification](https://sourcemaps.info/spec.html) leaves many things unspecified including what column numbers mean. Until now esbuild has been generating byte offsets for column numbers, but Mozilla's popular [source-map](https://github.com/mozilla/source-map) library appears to use UTF-16 code unit counts for column numbers instead. With this release, esbuild now also uses UTF-16 code units for column numbers in source maps. This should help esbuild's compatibility with other tools in the ecosystem.\n\n* Fix a bug with partial source mappings\n\n    The source map specification makes it valid to have mappings that don't actually map to anything. These mappings were never generated by esbuild but they are sometimes present in source maps generated by other tools. There was a bug where the source map line number would be thrown off if one of these mappings was present at the end of a line. This bug has been fixed.\n\n## 0.6.12\n\n* Fix bugs with cross-chunk assignment handling ([#302](https://github.com/evanw/esbuild/issues/302))\n\n    The code splitting process may end up moving the declaration of a file-local variable into a separate chunk from an assignment to that variable. However, it's not possible to assign to a variable in another chunk because assigning to an import is not allowed in ES6. To avoid generating invalid code, esbuild runs an additional pass after code splitting to force all code involved in cross-chunk assignments into the same chunk.\n\n    The logic to do this is quite tricky. For example, moving code between chunks may introduce more cross-chunk assignments that also need to be handled. In this case the bug was caused by not handling complex cases with three or more levels of cross-chunk assignment dependency recursion. These cases now have test coverage and should be handled correctly.\n\n## 0.6.11\n\n* Code splitting chunks now use content hashes ([#16](https://github.com/evanw/esbuild/issues/16))\n\n    Code that is shared between multiple entry points is separated out into \"chunk\" files when code splitting is enabled. These files are named `chunk.HASH.js` where `HASH` is a string of characters derived from a hash (e.g. `chunk.iJkFSV6U.js`).\n\n    Previously the hash was computed from the paths of all entry points which needed that chunk. This was done because it was a simple way to ensure that each chunk was unique, since each chunk represents shared code from a unique set of entry points. But it meant that changing the contents of the chunk did not cause the chunk name to change.\n\n    Now the hash is computed from the contents of the chunk file instead. This better aligns esbuild with the behavior of other bundlers. If changing the contents of the file always causes the name to change, you can serve these files with a very large `max-age` so the browser knows to never re-request them from your server if they are already cached.\n\n    Note that the names of entry points _do not_ currently contain a hash, so this optimization does not apply to entry points. Do not serve entry point files with a very large `max-age` or the browser may not re-request them even when they are updated. Including a hash in the names of entry point files has not been done in this release because that would be a breaking change. This release is an intermediate step to a state where all output file names contain content hashes.\n\n    The reason why this hasn't been done before now is because this change makes chunk generation more complex. Generating the contents of a chunk involves generating import statements for the other chunks which that chunk depends on. However, if chunk names now include a content hash, chunk generation must wait until the dependency chunks have finished. This more complex behavior has now been implemented.\n\n    Care was taken to still parallelize as much as possible despite parts of the code having to block. Each input file in a chunk is still printed to a string fully in parallel. Waiting was only introduced in the chunk assembly stage where input file strings are joined together. In practice, this change doesn't appear to have slowed down esbuild by a noticeable amount.\n\n* Fix an off-by-one error with source map generation ([#289](https://github.com/evanw/esbuild/issues/289))\n\n    The nested source map support added in version 0.6.5 contained a bug. Input files that were included in the bundle but that didn't themselves contain any generated code caused the source index to shift by one, throwing off the source names of all files after it. This could happen with files consisting only of re-export statements (e.g. `export {name} from 'path'`). This bug has been fixed and this specific scenario now has test coverage.\n\n## 0.6.10\n\n* Revert the binary operator chain change\n\n    It turns out this caused some behavior bugs in the generated code.\n\n## 0.6.9\n\n* Performance optimizations for large file transforms\n\n    There are two main JavaScript APIs: `build()` which operates on the file system and `transform()` which operates on in-memory data. Previously transforming large files using the JavaScript `transform()` API could be significantly slower than just writing the in-memory string to the file system, calling `build()`, and reading the result back from the file system. This is based on performance tests done on macOS 10.15.\n\n    Now esbuild will go through the file system when transforming large files (currently >1mb). This approach is only faster for large files, and can be significantly slower for small files, so small files still keep everything in memory.\n\n* Avoid stack overflow for binary operator chains\n\n    Syntax trees with millions of sequential binary operators nested inside each other can cause the parser to stack overflow because it uses a recursive visitor pattern, so each binary operator added an entry to the call stack. Now code like this no longer triggers a stack overflow because the visitor uses the heap instead of the stack in this case. This is unlikely to matter in real-world code but can show up in certain artificial test cases, especially when `--minify-syntax` is enabled.\n\n* Resolve implicitly-named `tsconfig.json` base files ([#279](https://github.com/evanw/esbuild/issues/279))\n\n    The official TypeScript compiler lets you specify a package path as the `extends` property of a `tsconfig.json` file. The base file is then searched for in the relevant `node_modules` directory. Previously the package path had to end with the name of the base file. Now you can additionally omit the name of the base file if the file name is `tsconfig.json`. This more closely matches the behavior of the official TypeScript compiler.\n\n* Support for 32-bit Windows systems ([#285](https://github.com/evanw/esbuild/issues/285))\n\n    You can now install the esbuild npm package on 32-bit Windows systems.\n\n## 0.6.8\n\n* Attempt to support the taobao.org registry ([#291](https://github.com/evanw/esbuild/issues/291))\n\n    This release attempts to add support for the registry at https://registry.npm.taobao.org, which uses a different URL structure than the official npm registry. Also, the install script will now fall back to the official npm registry if installing with the configured custom registry fails.\n\n## 0.6.7\n\n* Custom registry can now have a path ([#286](https://github.com/evanw/esbuild/issues/286))\n\n    This adds support for custom registries hosted at a path other than `/`. Previously the registry had to be hosted at the domain level, like npm itself.\n\n* Nested source maps use relative paths ([#289](https://github.com/evanw/esbuild/issues/289))\n\n    The original paths in nested source maps are now modified to be relative to the directory containing the source map. This means source maps from packages inside `node_modules` will stay inside `node_modules` in browser developer tools instead of appearing at the root of the virtual file system where they might collide with the original paths of files in other packages.\n\n* Support for 32-bit Linux systems ([#285](https://github.com/evanw/esbuild/issues/285))\n\n    You can now install the esbuild npm package on 32-bit Linux systems.\n\n## 0.6.6\n\n* Fix minification bug with `this` values for function calls ([#282](https://github.com/evanw/esbuild/issues/282))\n\n    Previously `(0, this.fn)()` was incorrectly minified to `this.fn()`, which changes the value of `this` used for the function call. Now syntax like this is preserved during minification.\n\n* Install script now respects the npm registry setting ([#286](https://github.com/evanw/esbuild/issues/286))\n\n    If you have configured npm to use a custom registry using `npm config set registry <url>` or by installing esbuild using `npm install --registry=<url> ...`, this custom registry URL should now be respected by the esbuild install script.\n\n    Specifically, the install script now uses the URL from the `npm_config_registry` environment variable if present instead of the default registry URL `https://registry.npmjs.org/`. Note that the URL must have both a protocol and a host name.\n\n* Fixed ordering between `node_modules` and a force-overridden `tsconfig.json` ([#278](https://github.com/evanw/esbuild/issues/278))\n\n    When the `tsconfig.json` settings have been force-overridden using the new `--tsconfig` flag, the path resolution behavior behaved subtly differently than if esbuild naturally discovers the `tsconfig.json` file without the flag. The difference caused package paths present in a `node_modules` directory to incorrectly take precedence over custom path aliases configured in `tsconfig.json`. The ordering has been corrected such that custom path aliases always take place over `node_modules`.\n\n* Add the `--out-extension` flag for custom output extensions ([#281](https://github.com/evanw/esbuild/issues/281))\n\n    Previously esbuild could only output files ending in `.js`. Now you can override this to another extension by passing something like `--out-extension:.js=.mjs`. This allows generating output files with the node-specific `.cjs` and `.mjs` extensions without having to use a separate command to rename them afterwards.\n\n## 0.6.5\n\n* Fix IIFE wrapper for ES5\n\n    The wrapper for immediately-invoked function expressions is hard-coded to an arrow function and was not updated when the ES5 target was added. This meant that bundling ES5 code would generate a bundle what wasn't ES5-compatible. Doing this now uses a function expression instead.\n\n* Add support for nested source maps ([#211](https://github.com/evanw/esbuild/issues/211))\n\n    Source map comments of the form `//# sourceMappingURL=...` inside input files are now respected. This means you can bundle files with source maps and esbuild will generate a source map that maps all the way back to the original files instead of to the intermediate file with the source map.\n\n## 0.6.4\n\n* Allow extending `tsconfig.json` paths inside packages ([#269](https://github.com/evanw/esbuild/issues/269))\n\n    Previously the `extends` field in `tsconfig.json` only worked with relative paths (paths starting with `./` or `../`). Now this field can also take a package path, which will be resolved by looking for the package in the `node_modules` directory.\n\n* Install script now avoids the `npm` command ([#274](https://github.com/evanw/esbuild/issues/274))\n\n    The install script now downloads the binary directly from npmjs.org instead of using the `npm` command to install the package. This should be more compatible with unusual node environments (e.g. having multiple old copies of npm installed).\n\n* Fix a code splitting bug with re-exported symbols ([#273](https://github.com/evanw/esbuild/issues/273))\n\n    Re-exporting a symbol in an entry point didn't correctly track the cross-chunk dependency, which caused the output file to be missing a required import. This bug has been fixed.\n\n* Fix code splitting if a dynamic entry point is doubled as a normal entry point ([#272](https://github.com/evanw/esbuild/issues/272))\n\n    Using a dynamic `import()` expression automatically adds the imported path as an entry point. However, manually adding the imported path to the bundler entry point list resulted in a build failure. This case is now handled.\n\n* Fix dynamic imports from a parent directory ([#264](https://github.com/evanw/esbuild/issues/264))\n\n    The nested output directory feature interacted badly with the code splitting feature when an entry point contained a dynamic `import()` to a file from a directory that was a parent directory to all entry points. This caused esbuild to generate output paths starting with `../` which stepped outside of the output directory.\n\n    The directory structure of the input files is mirrored in the output directory relative to the [lowest common ancestor](https://en.wikipedia.org/wiki/Lowest_common_ancestor) among all entry point paths. However, code splitting introduces a new entry point for each dynamic import. These additional entry points are not in the original entry point list so they were ignored by the lowest common ancestor algorithm. The fix is to make sure all entry points are included, user-specified and dynamic.\n\n## 0.6.3\n\n* Fix `/* @__PURE__ */` IIFEs at start of statement ([#258](https://github.com/evanw/esbuild/issues/258))\n\n    The introduction of support for `/* @__PURE__ */` comments in an earlier release introduced a bug where parentheses were no longer inserted if a statement started with a function expression that was immediately invoked. This bug has been fixed and parentheses are now inserted correctly.\n\n* Add support for `@jsx` and `@jsxFrag` comments ([#138](https://github.com/evanw/esbuild/issues/138))\n\n    You can now override the JSX factory and fragment values on a per-file basis using comments:\n\n    ```jsx\n    // @jsx h\n    // @jsxFrag Fragment\n    import {h, Fragment} from 'preact'\n    console.log(<><a/></>)\n    ```\n\n    This now generates the following code:\n\n    ```js\n    import {h, Fragment} from \"preact\";\n    console.log(h(Fragment, null, h(\"a\", null)));\n    ```\n\n* Add the `Write` option to the Go API\n\n    This brings the Go API to parity with the JavaScript API, and makes certain uses of the `api.Build()` call simpler. You can now specify `Write: true` to have the output files written to the file system during the build instead of having to do that yourself.\n\n## 0.6.2\n\n* Fix code splitting bug with re-export cycles ([#251](https://github.com/evanw/esbuild/issues/251))\n\n    Two files that both re-export each other could cause invalid code to be generated when code splitting is enabled. The specific failure was an export statement without a matching import statement from the shared code chunk. This bug has been fixed.\n\n    Semantically a `export * from 'path'` statement should behave like a `export {name} from 'path'` statement with the export list determined automatically. And likewise `export {name} from 'path'` should behave like `import {name} from 'path'; export {name}`.\n\n    This issue was caused by the re-exported symbols not registering themselves as if they were imported with an import statement. That caused code splitting to fail to generate an import statement when the definition of the symbol ended up in a different chunk than the use of the symbol.\n\n* Fix code splitting bug with missing generated imports\n\n    An ES6 module that doesn't import or export anything but that still uses ES6 module syntax (e.g. `import.meta`) interacted badly with some optimizations and caused invalid code to be generated. This generated an import statement without a matching export statement. The bug has been fixed.\n\n    To improve tree shaking, esbuild automatically converts `import * as ns from 'path'; use(ns.prop)` into `import {prop} from 'path'; use(prop)` at parse time. The parser doesn't yet know anything about `path` because parsing happens in parallel, so this transformation is always performed.\n\n    Later on `path` is determined to be an ES6 module with no exports. This means that there is no symbol to bind `prop` to. Since it was originally a property access on what is now known to be an empty exports object, its value is guaranteed to be undefined. It's no longer a property access so esbuild inlines the undefined value at all uses by replacing `prop` with `void 0`.\n\n    However, code splitting wasn't aware of this and still thought imports needed to be generated for uses of `prop`, even though it doesn't actually exist. That caused invalid and unnecessary import statements to be generated. Now code splitting is aware of this undefined substitution behavior and ignores these symbol uses.\n\n## 0.6.1\n\n* Allow bundling with stdin as input ([#212](https://github.com/evanw/esbuild/issues/212))\n\n    You can now use `--bundle` without providing any input files and the input will come from stdin instead. Use `--sourcefile=...` to set the name of the input file for error messages and source maps. Dependencies of the input file will be resolved relative to the current working directory.\n\n    ```\n    # These two commands are now basically equivalent\n    esbuild --bundle example.js\n    esbuild --bundle < example.js --sourcefile=example.js\n    ```\n\n    This option has also been added to the JavaScript and Go APIs. If needed, you can customize the resolve directory with the `resolveDir` option:\n\n    ```js\n    const {outputFiles: [stdout]} = await build({\n      stdin: {\n        contents: `\n          import {version} from './package.json'\n          console.log(version as string)\n        `,\n        sourcefile: 'example.ts',\n        resolveDir: __dirname,\n        loader: 'ts',\n      },\n      bundle: true,\n      write: false,\n    })\n    console.log(stdout)\n    ```\n\n* Implement `extends` for `tsconfig.json` ([#233](https://github.com/evanw/esbuild/issues/233))\n\n    A `tsconfig.json` file can inherit configurations from another file using the `extends` property. Before this release, esbuild didn't support this property and any inherited settings were missing. Now esbuild should include these inherited settings.\n\n* Allow manually overriding `tsconfig.json` ([#226](https://github.com/evanw/esbuild/issues/226))\n\n    Normally esbuild finds the appropriate `tsconfig.json` file by walking up the directory tree. This release adds the `--tsconfig=...` flag which lets you disable this feature and force esbuild to use the provided configuration file instead. This corresponds to the TypeScript compiler's `--project` flag.\n\n* Remove gaps in source maps within a file ([#249](https://github.com/evanw/esbuild/issues/249))\n\n    The widely-used [source-map](https://github.com/mozilla/source-map) library for parsing source maps [has a bug](https://github.com/mozilla/source-map/issues/261) where it doesn't return mappings from previous lines. This can cause queries within generated code to fail even though there are valid mappings on both sides of the query.\n\n    To work around this issue with the source-map library, esbuild now generates a mapping for every line of code that is generated from an input file. This means that queries with the source-map library should be more robust. For example, you should now be able to query within a multi-line template literal and not have the query fail.\n\n    Note that some lines of code generated during bundling will still not have source mappings. Examples include run-time library code and cross-chunk imports and exports.\n\n## 0.6.0\n\n* Output directory may now contain nested directories ([#224](https://github.com/evanw/esbuild/issues/224))\n\n    Note: This is a breaking change if you use multiple entry points from different directories. Output paths may change with this upgrade.\n\n    Previously esbuild would fail to bundle multiple entry points with the same name because all output files were written to the same directory. This can happen if your entry points are in different nested directories like this:\n\n    ```\n    src/\n     ├─ a/\n     │  └─ page.js\n     └─ b/\n        └─ page.js\n    ```\n\n    With this release, esbuild will now generate nested directories in the output directory that mirror the directory structure of the original entry points. This avoids collisions because the output files will now be in separate directories. The directory structure is mirrored relative to the [lowest common ancestor](https://en.wikipedia.org/wiki/Lowest_common_ancestor) among all entry point paths. This is the same behavior as [Parcel](https://github.com/parcel-bundler/parcel) and the TypeScript compiler.\n\n* Silence errors about missing dependencies inside try/catch blocks ([#247](https://github.com/evanw/esbuild/issues/247))\n\n    This release makes it easier to use esbuild with libraries such as [debug](npmjs.com/package/debug) which contain a use of `require()` inside a `try`/`catch` statement for a module that isn't listed in its dependencies. Normally you need to mark the library as `--external` to silence this error. However, calling `require()` and catching errors is a common pattern for conditionally importing an unknown module, so now esbuild automatically treats the missing module as external in these cases.\n\n* TypeScript type definitions for the browser API\n\n    The node-based JavaScript API already ships with TypeScript type checking for the `esbuild` and `esbuild-wasm` packages. However, up until now the browser-based JavaScript API located in `esbuild-wasm/lib/browser` did not have type definitions. This release adds type definitions so you can now import `esbuild-wasm/lib/browser` in TypeScript and get type checking.\n\n* Add chunk imports to metadata file ([#225](https://github.com/evanw/esbuild/issues/225))\n\n    With code splitting, it's sometimes useful to list out the chunks that will be needed by a given entry point. For example, you may want to use that list to insert one `<link rel=\"modulepreload\">` tag for each chunk in your page header. This information is now present in the JSON metadata file that's generated with the `--metafile` flag. Each object in the `outputs` map now has an `imports` array, and each import has a `path`.\n\n## 0.5.26\n\n* Allow disabling non-existent modules with the `browser` package.json field ([#238](https://github.com/evanw/esbuild/issues/238))\n\n    The [browser field](https://github.com/defunctzombie/package-browser-field-spec) in package.json allows you to disable a module (i.e. force it to become empty) by adding an override that points to `false`. Previously esbuild still required it to have an existing absolute path on the file system so that the disabled module could have a consistent identity. Now this is no longer required, so you can disable modules that don't exist on the file system. For example, you can now use this feature to disable the `fs` module.\n\n* Fix a bug with syntax transformation and `super()` calls ([#242](https://github.com/evanw/esbuild/issues/242))\n\n    In certain situations, esbuild accidentally transformed a class constructor such that a call to `super()` that came first in the original code no longer came first in the generated code. This code generation bug has now been fixed. Calls to `super()` that come first are should now stay that way.\n\n## 0.5.25\n\n* Performance improvment for repeated API calls\n\n    Previously every build or transform API call required parsing a new copy of the [esbuild JavaScript runtime code](internal/runtime/runtime.go). This added a constant overhead for every operation. Now the parsing of the runtime code is cached across API calls. The effect on performance depends on the size of the files you're transforming. Transform API calls appear to be >2x faster for small files, around ~10% faster for normal-sized files, and insignificant for large files.\n\n* Add a binary loader\n\n    You can now assign the `binary` loader to a file extension to load all files of that type into a Uint8Array. The data is encoded as a base64 string and decoded into a Uint8Array at run time. The decoder defaults to a custom platform-independent implementation (faster than `atob`) but it switches to using the `Buffer` API with `--platform=node`.\n\n* Add fine-grained `--target` environments ([#231](https://github.com/evanw/esbuild/issues/231))\n\n    You can now configure individual JavaScript environments as targets. The `--target` flag now takes a comma-separated list of values like this: `--target=chrome58,firefox57,safari11,edge16`. Compatibility data was mainly sourced from [this widely-used compatibility table](https://kangax.github.io/compat-table/es2016plus/).\n\n    There is also now an additional `es5` target. Since no transforms to ES5 are implemented yet, its purpose is mainly to prevent ES6 syntax from accidentally being compiled. This target also prevents esbuild from doing some ES6-specific optimizations that would unintentionally change ES5 code into ES6 code.\n\n## 0.5.24\n\n* Smaller code for loaders that generate expressions\n\n    Loaders that generate expressions (`json`, `text`, `base64`, `file`, and `dataurl`) export them using an assignment to `module.exports`. However, that forces the creation of a CommonJS module which adds unnecessary extra code. Now if the file for that loader is only imported using ES6 import statements instead of `require()`, the expression is exported using an `export default` statement instead. This generates smaller code. The bundler still falls back to the old `module.exports` behavior if the file is imported using `require()` instead of an ES6 import statement.\n\n    Example input file:\n\n    ```js\n    import txt from './example.txt'\n    console.log(txt)\n    ```\n\n    Old bundling behavior:\n\n    ```js\n    // ...code for __commonJS() and __toModule() omitted...\n\n    // example.txt\n    var require_example = __commonJS((exports, module) => {\n      module.exports = \"This is a text file.\";\n    });\n\n    // example.ts\n    const example = __toModule(require_example());\n    console.log(example.default);\n    ```\n\n    New bundling behavior:\n\n    ```js\n    // example.txt\n    var example_default = \"This is a text file.\";\n\n    // example.ts\n    console.log(example_default);\n    ```\n\n    In addition, top-level properties of imported JSON files are now converted into individual ES6 exports for better tree shaking. For example, that means you can now import the `version` property from your `package.json` file and the entire JSON file will be removed from the bundle:\n\n    ```js\n    import {version} from './package.json'\n    console.log(version)\n    ```\n\n    The example above will now generate code that looks like this:\n\n    ```js\n    // package.json\n    var version = \"1.0.0\";\n\n    // example.ts\n    console.log(version);\n    ```\n\n## 0.5.23\n\n* Fix `export declare` inside `namespace` in TypeScript ([#227](https://github.com/evanw/esbuild/issues/227))\n\n    The TypeScript parser assumed that ambient declarations (the `declare` keyword) just declared types and did not affect the output. This was an incorrect assumption for exported declarations of local variables inside namespaces. The assignment to `foo` in the example below must be rewritten to an assignment to `ns.foo`:\n\n    ```ts\n    namespace ns {\n      export declare let foo: number\n      foo = 123\n    }\n    ```\n\n    This should now work correctly.\n\n* Preserve certain statement-level comments ([#221](https://github.com/evanw/esbuild/issues/221))\n\n    Statement-level comments starting with `//!` or `/*!` or containing `@preserve` or `@license` are now preserved in the output. This matches the behavior of other JavaScript tools such as [Terser](https://github.com/terser/terser).\n\n* Higher memory limit for synchronous JavaScript APIs ([#228](https://github.com/evanw/esbuild/issues/228))\n\n    Apparently the synchronous APIs in node's child process module that esbuild relies on will fail with `ENOBUFS` if the output is larger than a certain size. This caused issues with the `write: false` feature from the previous release. The memory limit has been raised to 16mb which should hopefully avoid these crashes. If that limit is still too low, it can be overridden with the `ESBUILD_MAX_BUFFER` environment variable.\n\n## 0.5.22\n\n* JavaScript build API can now avoid writing to the file system ([#139](https://github.com/evanw/esbuild/issues/139) and [#220](https://github.com/evanw/esbuild/issues/220))\n\n    You can now pass `write: false` to the JavaScript build API to avoid writing to the file system. Instead, the returned object will have the `outputFiles` property with an array of output files, each of which has a string `path` property and a Uint8Array `contents` property. This brings the JavaScript API to parity with the Go API, which already had this feature.\n\n* Support `/* @__PURE__ */` annotations for tree shaking\n\n    You can now annotate call expressions and new expressions with a `/* @__PURE__ */` comment, which tells esbuild that the function call is allowed to be removed if the result is not used. This is a convention from other tools (e.g. UglifyJS and Rollup).\n\n    For example, the code below will now be completely removed during bundling if the `fib` variable is never used. The initializer is a function call and esbuild cannot determine that it has no side effects, but the annotation forces esbuild to consider it removable anyway:\n\n    ```js\n    let fib = /* @__PURE__ */ (() => {\n      let cache = {}\n      return function f(n) {\n        return cache[n] || (cache[n] =\n          n <= 2 ? 1 : f(n - 1) + f(n - 2));\n      }\n    })()\n    ```\n\n* Add `--pure:name` to annotate calls to globals ([#28](https://github.com/evanw/esbuild/issues/28))\n\n    This flag makes calls to the named function behave as if that call was prefixed by `/* @__PURE__ */`. For example, `--pure:console.log` means calls to `console.log()` will behave as if they were calls to `/* @__PURE__ */ console.log()` instead. This means when `--minify` is active, the calls will be removed as long as the return value is unused (any function arguments with side effects will be kept, however).\n\n* Add basic tree shaking of JSX elements\n\n    Automatically-generated calls to the JSX factory function (usually `React.createElement`) are now marked as `/* @__PURE__ */`. This means the construction of a JSX element is now not considered to have side effects. For example, the code below will be completely removed during bundling if the `element` variable is never used:\n\n    ```jsx\n    let element = <div>an unused element</div>\n    ```\n\n* Fixed a concurrency issue with the JavaScript API\n\n    Before this release, multiple concurrent JavaScript API calls that used different values for the `define` option could end up using the value from another API call. This bug was due to inverted boolean logic in code that was intended to cache the define map only when there were no user-specified defines. The issue has been fixed.\n\n## 0.5.21\n\n* Binaries for FreeBSD ([#217](https://github.com/evanw/esbuild/pull/217))\n\n    There are now esbuild binaries for FreeBSD, both for AMD64 and ARM64. This was contributed by [@kikuchan](https://github.com/kikuchan).\n\n* Remove nested `node_modules` directory\n\n    The install script for the `esbuild` npm package invokes `npm` recursively to install the binary for the current platform. However, the left over nested `node_modules` directory could potentially cause problems with tools that scan for nested `node_modules` directories. Now the install script no longer leaves a nested `node_modules` directory around after finishing.\n\n## 0.5.20\n\n* Allow multiple `.` characters in loader extensions ([#215](https://github.com/evanw/esbuild/issues/215))\n\n    You are now able to configure two loaders such that one is the suffix of the other. For example, you can now configure both `--loader:.txt=text` and `--loader:.base64.txt=base64`. The loader with the longer matching suffix will be used.\n\n* Add support for scoped external packages ([#214](https://github.com/evanw/esbuild/issues/214))\n\n    You can now mark scoped packages as external. For example, `--external:@babel/core` marks the package `@babel/core` as external. This was contributed by [@floydspace](https://github.com/floydspace).\n\n* Add support for external paths ([#127](https://github.com/evanw/esbuild/issues/127) and [#191](https://github.com/evanw/esbuild/issues/191))\n\n    Previously the `--external:M` flag only worked if `M` was a package name. For example, you can mark the `fs` package as external with `--external:fs`.\n\n    With this release, you can now also mark file paths as external using the same syntax. For example, `--external:./index.js` marks the file `index.js` in the current working directory as external. The path to the external module used in the output file will be relative to the output directory.\n\n## 0.5.19\n\n* Fix bug with TypeScript `typeof` operator ([#213](https://github.com/evanw/esbuild/issues/213))\n\n    The TypeScript parser in esbuild incorrectly treated `readonly` in `typeof readonly` as a type operator instead of an identifier, which meant that it expected a type expression to follow the `readonly` identifier. Type expressions containing `typeof readonly` are now parsed correctly.\n\n## 0.5.18\n\n* Fix bug with code splitting and side effects\n\n    This release fixes a bug with experimental code splitting. Chunks with side effects but without any exports were not imported by the entry points that depended on them, which meant that their side effects accidentally did not occur. The fix ensures that all entry points import all relevant chunks regardless of whether or not the chunks have exports, so their side effects should never be omitted.\n\n## 0.5.17\n\n* Pass through `import.meta` syntax ([#208](https://github.com/evanw/esbuild/issues/208))\n\n    The `import.meta` syntax is a way for code in an ES6 module to access metadata about itself. For example, `import.meta.url` in the browser is the URL of the current module.\n\n    It's a new feature that doesn't work in older browsers, so esbuild converts it to a module-local variable to avoid generating code with a syntax error. However, this is only necessary when targeting older browsers or if the output format doesn't support `import.meta`.\n\n    The `import.meta` syntax is now passed through unmodified when the target is `es2020` or newer and the output format is `esm`. This lets you use features such as `import.meta.url` in those situations.\n\n## 0.5.16\n\n* Experimental code splitting with `--splitting` ([#16](https://github.com/evanw/esbuild/issues/16))\n\n    This release includes experimental support for code splitting. Enable it with the `--splitting` flag. This currently only works with the `esm` output format. Support for the `cjs` and `iife` formats will come later. It's being released early so people can try it out and provide feedback.\n\n    When enabled, code splitting does two things:\n\n    * An asynchronous `import('path')` expression will create another chunk that will only be loaded when that expression is evaluated. This is intended to be used for lazily loading additional code. All additional chunks will be written to the directory configured with `outdir`.\n\n        Note that when code splitting is disabled (i.e. the default behavior), an `import('path')` expression behaves similar to `Promise.resolve(require('path'))` and still bundles the imported file into the entry point bundle. No additional chunks are generated in this case.\n\n    * Multiple entry points will cause additional chunks to be created for code that is shared between entry points. Chunks are generated automatically based on simple principles: code should only ever be in one chunk (i.e. no duplication) and no unnecessary code should be loaded (i.e. chunk boundaries are minimal).\n\n        The way this works is by traversing through the module dependency graph and marking which top-level statements are reachable from which entry points. The set of entry points for a given top-level statement determines which chunk that statement is in.\n\n        This is an advanced form of code splitting where even a single file may end up being split into different chunks. This is not something most other bundlers can do at the moment.\n\n    Note that using code splitting with many entry points may generate many chunks for shared code reachable from different combinations of entry points. This should work fine and should still be efficient with HTTP/2. If you want to only let certain entry points share code, you can run esbuild multiple times for different groups of entry points.\n\n    Please try it out and report any issues on [#16](https://github.com/evanw/esbuild/issues/16).\n\n## 0.5.15\n\n* Remove some unnecessary helper functions ([#206](https://github.com/evanw/esbuild/issues/206))\n\n    Certain unnecessary helper functions were sometimes generated when the output format was `esm`. These helper functions should now only be generated when necessary.\n\n* Optimize CommonJS-to-ES6 module conversion\n\n    CommonJS modules that exported raw strings were unnecessarily slow when imported using an ES6 import statement. This scenario should now be much faster.\n\n    The CommonJS-to-ES6 module conversion in esbuild copies properties off the object one-by-one onto a new object. This is the same approach that the TypeScript compiler uses. However, strings have numeric properties 0 to N-1 where N is the length of the string. Copying all of these numeric properties can take a significantly long time for long strings and is almost certainly unhelpful. Now esbuild's CommonJS-to-ES6 module conversion only copies properties if the export is an object.\n\n* Support JSX fields in `tsconfig.json`\n\n    This release adds support for the `jsxFactory` and `jsxFragmentFactory` fields in `tsconfig.json`. Now you do not have to configure JSX again for esbuild if you have already configured it for TypeScript. The `jsxFragmentFactory` field is a [new feature in the upcoming TypeScript 4.0 release](https://devblogs.microsoft.com/typescript/announcing-typescript-4-0-beta/#custom-jsx-factories).\n\n## 0.5.14\n\n* Prevent assignment to ES6 imports ([#202](https://github.com/evanw/esbuild/issues/202))\n\n    ES6 imports are live bindings to other values, sort of like a getter-only property on an object. An assignment to an import identifier should cause a `TypeError` at run time according to the specification. However, when bundling esbuild performs the \"scope hoisting\" optimization and merges all modules into a single scope. Imports inside the bundle refer to the imported identifiers without any indirection and an assignment will not throw a `TypeError` at run time.\n\n    This release turns assignments to imports into compile-time errors to reject invalid code instead of allowing it to cause this non-conforming behavior. Handling this at compile-time is consistent with other tools such as TypeScript and Rollup.\n\n* Exclude external child paths from the bundle ([#186](https://github.com/evanw/esbuild/pull/186))\n\n    Marking a module as external via `--external:foo` means any imports for the module `foo` will be preserved in the output instead of being traversed by the bundler. This is helpful if the module contains problematic code such as a native node module that can't be bundled.\n\n    However, code often uses child paths to import a file within a module directly such as `import \"foo/bar\"`. These paths accidentally bypassed the external module check. The fix means all paths under an external module are now also considered external. This was contributed by [@floydspace](https://github.com/floydspace).\n\n## 0.5.13\n\n* Add support for TypeScript labelled tuples\n\n    This is a new TypeScript feature to be released in TypeScript 4. Tuple types can now have labels:\n\n    ```ts\n    let foo: [number, number]           // Without labels\n    let bar: [min: number, max: number] // With labels\n    ```\n\n    These labels are ignored by the TypeScript compiler and are only there to improve readability. You can read more here: https://devblogs.microsoft.com/typescript/announcing-typescript-4-0-beta/.\n\n## 0.5.12\n\n* Fix a JSX whitespace bug ([#195](https://github.com/evanw/esbuild/issues/195))\n\n    Whitespace behavior in JSX has unfortunately been [left out of the JSX specification](https://github.com/facebook/jsx/issues/6), so it's up to each implementation to determine how to handle whitespace characters. Most of the JSX parsers in the ecosystem have converged on similar behavior. When they differ, esbuild follows the behavior of the TypeScript JSX parser.\n\n    This release fixes a bug where esbuild's JSX parser behaved differently than TypeScript. Certain whitespace characters between JSX elements were incorrectly removed. For example, the space in `<a><b/> <c/></a>` must be preserved to match the TypeScript JSX parser. These cases now have test coverage.\n\n## 0.5.11\n\n* Fix a JavaScript API crash on node 10.x\n\n    The current LTS version of node is 12.x, but some people are still running 10.x and want to use esbuild. Before this fix, attempting to use the esbuild JavaScript API with node 10.x would crash with `ReferenceError: TextEncoder is not defined`. The JavaScript API has been changed to not require `TextEncoder` and now works fine with node 10.x.\n\n## 0.5.10\n\n* Transform object rest properties\n\n    This release transforms object rest property bindings such as `let {...x} = y` when the language target is set to `--target=es2017` or earlier.\n\n    If you're using Babel to transform your source code to ES6 for older browsers, this probably means esbuild's JavaScript API could now be a suitable replacement for Babel in your case. The only remaining features that esbuild can't yet transform to ES6 are a few very rarely used features that don't matter for the vast majority of real-world code (`for async` loops and `async` generators).\n\n## 0.5.9\n\n* Add the `--strict:nullish-coalescing` option\n\n    This affects the transform for the `??` nullish coalescing operator. In loose mode (the default), `a ?? b` is transformed to `a != null ? a : b`. This works fine in all cases except when `a` is the special object `document.all`. In strict mode, `a ?? b` is transformed to `a !== null && a !== void 0 ? a : b` which works correctly with `document.all`. Enable `--strict:nullish-coalescing` if you need to use `document.all` with the `??` operator.\n\n* Add the `--strict:class-fields` option\n\n    This affects the transform for instance and static class fields. In loose mode (the default), class field initialization is transformed to a normal assignment. This is what the TypeScript compiler does by default. However, it doesn't follow the JavaScript specification exactly (e.g. it may call setter methods). Either enable `--strict:class-fields` or add `useDefineForClassFields` to your `tsconfig.json` file if you need accurate class field initialization.\n\nNote that you can also just use `--strict` to enable strictness for all transforms instead of using `--strict:...` for each transform.\n\n## 0.5.8\n\n* Transform async functions ([#137](https://github.com/evanw/esbuild/issues/137))\n\n    This release transforms async functions into generator functions for older browsers when the language target is set to `--target=es2016` or below. The transform esbuild uses is similar to the one used by the TypeScript compiler.\n\n## 0.5.7\n\n* Transform private fields and private methods ([#47](https://github.com/evanw/esbuild/issues/47))\n\n    Private names are an access control mechanism for classes. They begin with a `#` and are not accessible outside of the class they are declared in. Support for parsing this syntax was added in esbuild version 0.4.9 but the syntax was passed through unmodified, meaning it didn't work in older browsers.\n\n    This release adds support for transforming private fields and private methods for older browsers that don't support this syntax. This transform uses `WeakMap` and `WeakSet` to preserve the privacy properties of this feature, similar to the corresponding transforms in the Babel and TypeScript compilers.\n\n    This code:\n\n    ```js\n    class Counter {\n      #count = 1\n      get value() { return this.#count }\n      increment() { ++this.#count }\n    }\n    ```\n\n    is transformed into this code when using `--target=es2020`:\n\n    ```js\n    var _count;\n    class Counter {\n      constructor() { _count.set(this, 1); }\n      get value() { return __privateGet(this, _count); }\n      increment() { __privateSet(this, _count, +__privateGet(this, _count) + 1); }\n    }\n    _count = new WeakMap();\n    ```\n\n    Note that most modern JavaScript engines (V8, JavaScriptCore, and SpiderMonkey but not ChakraCore) may not have good performance characteristics for large `WeakMap` and `WeakSet` objects. Creating many instances of classes with private fields or private methods with this syntax transform active may cause a lot of overhead for the garbage collector. This is because modern engines (other than ChakraCore) store weak values in an actual map object instead of as hidden properties on the keys themselves, and large map objects can cause performance issues with garbage collection. See [this reference](https://github.com/tc39/ecma262/issues/1657#issuecomment-518916579) for more information.\n\n* Fix re-exports when bundling\n\n    This is similar to the fix for re-exports in version 0.5.6 except that it applies when bundling, instead of just when transforming. It needed to be fixed differently because of how cross-file linking works when bundling.\n\n## 0.5.6\n\n* Fix re-export statements ([#190](https://github.com/evanw/esbuild/issues/190))\n\n    The previous release caused a regression due to some behind-the-scenes work for the upcoming code splitting feature. The re-export alias in statements of the form `export { foo as bar } from 'path'` could sometimes incorrectly be renamed to something else, such as `foo` becoming `foo2`. This release fixes the bug.\n\n## 0.5.5\n\n* Implement logical assignment operator transforms\n\n    There are three new logical assignment operators: `??=`, `&&=`, and `||=`. With this release, you can now use them in older browsers by setting `--target` to a language version other than `esnext`. See [the V8 blog post](https://v8.dev/features/logical-assignment) for more information about how they work.\n\n* Fix re-exports of a CommonJS module in `esm` format\n\n    Previously re-exports of an individual identifier from a CommonJS module generated JavaScript that crashed at run-time when using the `esm` output format. This was because esbuild always tries to generate \"live\" exports for CommonJS modules that always return the current value of the export instead of \"dead\" bindings that only return the initial value of the export. The bug happened because the ES6 module format doesn't have a way to forward a live binding to a CommonJS module as an ES6 export. The fix is to generate \"dead\" exports instead, which is the only available option in this edge case.\n\n    These input files:\n\n    ```js\n    // entry_point.js\n    export {foo} from './cjs-format.js'\n    ```\n\n    ```js\n    // cjs-format.js\n    Object.defineProperty(exports, 'foo', {\n      enumerable: true,\n      get: () => Math.random(),\n    })\n    ```\n\n    Now become this output file:\n\n    ```js\n    // cjs-format.js\n    var require_cjs_format = __commonJS((exports) => {\n      Object.defineProperty(exports, \"foo\", {\n        enumerable: true,\n        get: () => Math.random()\n      });\n    });\n\n    // entry_point.js\n    const cjs_format = __toModule(require_cjs_format());\n    const export_foo = cjs_format.foo; // This is a \"dead\" re-export\n    export {\n      export_foo as foo\n    };\n    ```\n\n## 0.5.4\n\n* Source maps use `/` on Windows ([#188](https://github.com/evanw/esbuild/issues/188))\n\n    Before generated source maps used `\\` on Windows, which meant that tools consuming these source maps (e.g. Chrome) didn't recognize these characters as path separators. Now all platforms consistently use `/` as a path separator.\n\n* Prevent input files from being overwritten\n\n    There are now checks in place to avoid input files being accidentally overwritten. This could easily happen with `--bundle --outdir=.` when bundling JavaScript files since the output file name ends up being the same as the entry point name, and is written to the same directory.\n\n## 0.5.3\n\n* Special-case `require` in browserify bundles ([#80](https://github.com/evanw/esbuild/issues/80) and [#90](https://github.com/evanw/esbuild/issues/90))\n\n    [Browserify](https://browserify.org/) generates code containing the expression `typeof require == \"function\" && require` which then ends up in a lot of npm packages. This expression is problematic because bundling involves statically determining all source files and their dependencies. Using `require` dynamically like this defeats the static analysis. It's also problematic because esbuild replaces `typeof require == \"function\"` with `true` since `require` is a function at compile-time when bundling. Then `true && require` becomes `require` in the generated code, which crashes at run time.\n\n    Previously esbuild would generate an error for these expressions. Now esbuild replaces `typeof require == \"function\" && require` with `false` when targeting the browser and `require` when targeting node. This matches the intent of the browserify prelude snippet and allows esbuild to build libraries containing this code without errors or warnings.\n\n* Allow dynamic dependencies ([#113](https://github.com/evanw/esbuild/issues/113))\n\n    Bundling `require()` or `import()` when the argument isn't a string literal is a dynamic dependency. The dependency path relies on dynamic run-time behavior and cannot be statically determined by esbuild at bundle time.\n\n    Dynamic dependencies used to be an error but are now just a warning. Builds containing them now succeed and the generated code contains the `require()` or `import()` expression. This is useful either when the dynamic dependency is intentional or when you know the dynamic dependency won't ever be triggered. Doing this still generates a warning to alert you that some code was excluded from the bundle and because these expressions may still crash at run time if the imported path isn't valid.\n\n## 0.5.2\n\n* Fix a regression with `--define` and identifiers\n\n    The API refactor introduced a regression where using a `--define` flag to replace something with an identifier followed by another `--define` flag unintentionally caused the first `--define` to use the value from the second `--define` for replacement. This regression was caused by a loop that was added around a Go closure, which caused all closures in that loop to close over the same variable. The bug has been fixed.\n\n* Fix interpretation of legacy `-->` single-line HTML comments\n\n    The `-->` sequence starts a single-line comment similar to `//`. This is legacy behavior from [annex B](https://www.ecma-international.org/ecma-262/6.0/#sec-html-like-comments) under the name `SingleLineHTMLCloseComment`. However, `-->` was incorrectly treated as the start of a comment even when it didn't come at the beginning of the line. Now `-->` only starts a comment if there are no tokens before it on that line.\n\n* Allow shadowing of CommonJS variables ([#165](https://github.com/evanw/esbuild/issues/165))\n\n    It's now no longer an error to re-declare `exports`, `module`, or `require` in a module scope. The re-declared symbol will just silently shadow the CommonJS variable with that name. This allows to use a variable called `exports` in an ES6 module, for example.\n\n## 0.5.1\n\n* Go documentation was moved to godoc ([#177](https://github.com/evanw/esbuild/pull/177))\n\n    The Go documentation is now in the source files itself instead of in an external Markdown file. View it online at https://godoc.org/github.com/evanw/esbuild/pkg/api and https://godoc.org/github.com/evanw/esbuild/pkg/cli.\n\n* The browser API now works in a script tag\n\n    The initial release of the browser API required a bundler to use correctly since it was in CommonJS format. This release adds the ability to use the browser API directly in HTML.\n\n    Here's an example using https://unpkg.com/ for simplicity, although you should consider hosting the files yourself:\n\n    ```html\n    <script src=\"https://unpkg.com/esbuild-wasm@0.5.1/lib/browser.js\"></script>\n    <script>\n      (async () => {\n        const service = await esbuild.startService({\n          wasmURL: 'https://unpkg.com/esbuild-wasm@0.5.1/esbuild.wasm'\n        })\n        try {\n          const ts = 'enum Foo { A, B, C }'\n          const { js } = await service.transform(ts, { loader: 'ts' })\n          console.log(js)\n        } finally {\n          service.stop()\n        }\n      })()\n    </script>\n    ```\n\n## 0.5.0\n\n* Overhaul public-facing API code\n\n    This is a rewrite of all externally facing API code. It fixes some bugs and inconsistencies, adds some new features, and makes it easier to support various use cases going forward.\n\n    At a high-level, esbuild's API supports two separate operations: \"build\" and \"transform\". Building means reading from the file system and writing back to the file system. Transforming takes an input string and generates an output string. You should use the build API if you want to take advantage of esbuild's bundling capability, and you should use the transform API if you want to integrate esbuild as a library inside another tool (e.g. a \"minify\" plugin). This rewrite ensures the APIs for these two operations are exposed consistently for all ways of interacting with esbuild (both through the CLI and as a library).\n\n    Here are some of the highlights:\n\n    * There is now a public Go API ([#152](https://github.com/evanw/esbuild/issues/152))\n\n        The main API can be found in the [`github.com/evanw/esbuild/pkg/api`](pkg/api/api.go) module. It exposes the exact same features as the JavaScript API. This means you can use esbuild as a JavaScript transformation and bundling library from Go code without having to run esbuild as a child process. There is also the [`github.com/evanw/esbuild/pkg/cli`](pkg/cli/cli.go) module which can be used to wrap the esbuild CLI itself.\n\n    * There are now synchronous JavaScript APIs ([#136](https://github.com/evanw/esbuild/issues/136))\n\n        Sometimes JavaScript source transformations must be synchronous. For example, using esbuild's API to shim `require()` for `.ts` files was previously not possible because esbuild only had an asynchronous transform API.\n\n        This release adds the new `transformSync()` and `buildSync()` synchronous functions to mirror the existing `transform()` and `build()` asynchronous functions. Note that these synchronous calls incur the cost of starting up a new child process each time, so you should only use these instead of `startService()` if you have to (or if you don't care about optimal performance).\n\n    * There is now an experimental browser-based API ([#172](https://github.com/evanw/esbuild/issues/172))\n\n        The `esbuild-wasm` package now has a file called `browser.js` that exposes a `startService()` API which is similar to the esbuild API available in node. You can either import the `esbuild-wasm` package using a bundler that respects the `browser` field in `package.json` or import the `esbuild-wasm/lib/browser.js` file directly.\n\n        This is what esbuild's browser API looks like:\n\n        ```ts\n        interface BrowserOptions {\n          wasmURL: string\n          worker?: boolean\n        }\n\n        interface BrowserService {\n          transform(input: string, options: TransformOptions): Promise<TransformResult>\n          stop(): void\n        }\n\n        declare function startService(options: BrowserOptions): Promise<BrowserService>\n        ```\n\n        You must provide the URL to the `esbuild-wasm/esbuild.wasm` file in `wasmURL`. The optional `worker` parameter can be set to `false` to load the WebAssembly module in the same thread instead of creating a worker thread. Using a worker thread is recommended because it means transforming will not block the main thread.\n\n        This API is experimental and may be changed in the future depending on the feedback it gets.\n\n    * Error messages now use `sourcefile` ([#131](https://github.com/evanw/esbuild/issues/131))\n\n        Errors from transform API calls now use `sourcefile` as the original file name if present. Previously the file name in error messages was always `/input.js`.\n\n## 0.4.14\n\n* Do not reorder `\"use strict\"` after support code ([#173](https://github.com/evanw/esbuild/issues/173))\n\n    Even when not in bundling mode, esbuild sometimes adds automatically-generated support code at the start of the output file. For example, using the `**` operator with `--target=es2015` causes `let __pow = Math.pow` to be inserted at the start of the file. This interfered with `\"use strict\"` directives, which must come first. Now `\"use strict\"` directives are written out first before any automatically-generated support code.\n\n* Fix bug with export star pointing to a re-export ([#176](https://github.com/evanw/esbuild/issues/176))\n\n    This fixes a tree shaking bug that involves an `export * from ...` statement pointing to a file with a `export {name} from ...` statement. Now `name` will no longer be incorrectly removed from the bundle.\n\n## 0.4.13\n\n* Fix possible name collision with CommonJS the target ([#174](https://github.com/evanw/esbuild/issues/174))\n\n    A bug meant that the export objects for individual modules with the same filename could in some cases end up reusing the same name in the output file, which then caused a syntax error. This only happened with the `cjs` target. The bug has been fixed.\n\n## 0.4.12\n\n* Support `export * from ...` for CommonJS modules ([#159](https://github.com/evanw/esbuild/issues/159))\n\n    Wildcard re-exports are now supported when the exports come from a CommonJS or external module. Since CommonJS modules are not statically analyzable, this means in these cases the re-exports are evaluated at run time instead of at bundle time. Modules that re-export symbols this way will also be considered CommonJS modules during bundling because their exports are now also not statically analyzable.\n\n* Add 3rd-party library test coverage\n\n    From the esbuild repo, you can now run `make test-extra` to build some 3rd-party libraries (Rollup, Sucrase, and Esprima) with esbuild and run their test suites. This ensures that these libraries will continue to work as esbuild releases new features.\n\n## 0.4.11\n\n* Fix top-level name minification with runtime\n\n    When not bundling, esbuild only minifies top-level names if the file is an ES6 module (as determined by the presence of an ES6 import or export statement). This determination had a bug where a non-module file was considered a module if esbuild automatically generated an import to some internal support code called the \"runtime\". For example, using the `**` operator with `--target=es2015` generates an import for the `__pow` runtime function. Runtime imports are now ignored for module determination, so an automatically-generated runtime import no longer causes top-level names to be minified.\n\n* Fix class name generation for default exports\n\n    Some changes to name generation for TypeScript decorators caused the generated class name for `export default class` statements to sometimes not match the name used for other references to that class in the same file. This bug has been fixed.\n\n## 0.4.10\n\n* Initial implementation of TypeScript decorators ([#104](https://github.com/evanw/esbuild/issues/104))\n\n    This release contains an initial implementation of the non-standard TypeScript-specific decorator syntax. This syntax transformation is enabled by default in esbuild, so no extra configuration is needed. The TypeScript compiler will need `\"experimentalDecorators\": true` configured in `tsconfig.json` for type checking to work with TypeScript decorators.\n\n    Here's an example of a method decorator:\n\n    ```ts\n    function logged(target, key, descriptor) {\n      let method = descriptor.value\n      descriptor.value = function(...args) {\n        let result = method.apply(this, args)\n        let joined = args.map(x => JSON.stringify(x)).join(', ')\n        console.log(`${key}(${joined}) => ${JSON.stringify(result)}`)\n        return result\n      }\n    }\n\n    class Example {\n      @logged\n      method(text: string) {\n        return text + '!'\n      }\n    }\n\n    const x = new Example\n    x.method('text')\n    ```\n\n    There are four kinds of TypeScript decorators: class, method, parameter, and field decorators. See [the TypeScript decorator documentation](https://www.typescriptlang.org/docs/handbook/decorators.html) for more information. Note that esbuild only implements TypeScript's `experimentalDecorators` setting. It does not implement the `emitDecoratorMetadata` setting because that requires type information.\n\n* Fix order of side effects for computed fields\n\n    When transforming computed class fields, esbuild had a bug where the side effects of the field property names were not evaluated in source code order. The order of side effects now matches the order in the source code.\n\n* Fix private fields in TypeScript\n\n    This fixes a bug with private instance fields in TypeScript where the private field declaration was incorrectly removed during the TypeScript class field transform, which inlines the initializers into the constructor. Now the initializers are still moved to the constructor but the private field declaration is preserved without the initializer.\n\n    Note that since static private fields are not currently supported by the official TypeScript compiler, they are also not supported by esbuild in TypeScript files. They are supported by esbuild in JavaScript files, however.\n\n## 0.4.9\n\n* Initial support for private names ([#47](https://github.com/evanw/esbuild/issues/47))\n\n    Private names are an access control mechanism for classes. They begin with a `#` and are not accessible outside of the class they are declared in. The private name syntax can now be parsed, printed, and minified correctly. Transforming this syntax for older browsers is not supported yet. This is what the syntax looks like:\n\n    ```js\n    class Counter {\n      #count = 1\n      get value() { return this.#count }\n      increment() { this.#count++ }\n    }\n    ```\n\n    You can read more about these features here:\n\n    * https://github.com/tc39/proposal-private-methods\n    * https://github.com/tc39/proposal-class-fields\n    * https://github.com/tc39/proposal-static-class-features\n\n* Initial support for logical assignment operators\n\n    This adds support for the three new logical assignment operators `||=`, `&&=`, and `??=`, which can now be parsed and passed through to the output. Transforming this syntax for older browsers is not supported yet. You can read more about these operators here: https://github.com/tc39/proposal-logical-assignment.\n\n* Data loaders now set \"no side effects\"\n\n    Files loaded using the `json`, `text`, `base64`, `dataurl`, and `file` loaders are now removed from the bundle if the files that import them never use the imports. This is the same behavior as the `\"sideEffects\": false` setting in `package.json`.\n\n## 0.4.8\n\n* Add the `--metafile` flag ([#140](https://github.com/evanw/esbuild/issues/140))\n\n    Pass `--metafile=meta.json` to write metadata about the build to the file `meta.json`. This includes information such as which files are in the bundle, what other files a given file depends on, and how much of each file ended up in the bundle. This is similar to the [stats option in Webpack](https://webpack.js.org/api/stats/).\n\n    The format looks like this:\n\n    ```ts\n    interface Metadata {\n      inputs: {\n        [path: string]: {\n          bytes: number\n          imports: {\n            path: string\n          }[]\n        }\n      }\n      outputs: {\n        [path: string]: {\n          bytes: number\n          inputs: {\n            [path: string]: {\n              bytesInOutput: number\n            }\n          }\n        }\n      }\n    }\n    ```\n\n* Shorten numeric literals ([#122](https://github.com/evanw/esbuild/issues/122))\n\n    Certain numeric literals now use shorter representations in the generated JavaScript code. For example, `123400000` is now written out as `1234e5`.\n\n## 0.4.7\n\n* Fixed `sideEffects` and nested directories\n\n    This fixes a bug where `package.json` files with `\"sideEffects\": false` were not respected for files in nested directories. When this bug occurred, bundles could be bigger than necessary. The `sideEffects` hint is now respected if any parent directory contains the hint instead of just the immediate enclosing directory.\n\n* Fixed `sideEffects` and default exports with side effects\n\n    This fixes a bug with default exports with side effects inside a `\"sideEffects\": false` context that were imported and used. These exports were incorrectly discarded instead of being retained, which could cause the resulting bundle to crash.\n\n## 0.4.6\n\n* Respect the `sideEffects` field when tree shaking ([#50](https://github.com/evanw/esbuild/issues/50))\n\n    Tree shaking now respects `\"sideEffects\": false` in `package.json`, which means esbuild now generates smaller bundles with certain libraries such as [lodash-es](https://www.npmjs.com/package/lodash-es). This setting is a [convention from Webpack](https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free). Any files in a package with this setting will not be included in the bundle if they are imported using an ES6 import and then never used.\n\n## 0.4.5\n\n* Fix a crash with more than 8 entry points ([#162](https://github.com/evanw/esbuild/pull/162))\n\n    This bug was due to the wrong index being used for an internal bit set. That caused a crash due to an out-of-bounds array read when esbuild is run with more than 8 entry points. I now have test coverage for large numbers of entry points, so this should not happen again.\n\n* Fix slash characters in file loader ([#164](https://github.com/evanw/esbuild/pull/164))\n\n    This fixes a bug where the base64-encoded hash included in the file name could sometimes contain a `/` character. The fix is to use the base64 character set for URL-encoding, which replaces the `/` character with a `_` character.\n\n## 0.4.4\n\n* Fix optional chaining with TypeScript operators ([#168](https://github.com/evanw/esbuild/issues/168))\n\n    The work on optional chaining in the previous release introduced a regression where the TypeScript infix operators `!` and `<>` incorrectly stopped the propagation of optional chaining. That meant `a?.b!()` and `a?.b<T>()` incorrectly behaved like `(a?.b)()` instead of `a?.b()`. This now has test coverage.\n\n* Add support for the `\"paths\"` field in `tsconfig.json` ([#60](https://github.com/evanw/esbuild/issues/60) and [#144](https://github.com/evanw/esbuild/issues/144))\n\n    This provides a way of remapping module paths to local file paths. It's relatively powerful because it supports wildcard patterns and multiple fallback locations. See [the documentation in the TypeScript handbook](https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping) for more information about how this feature works. This was contributed by [@viankakrisna](https://github.com/viankakrisna).\n\n* Add the `file` loader ([#14](https://github.com/evanw/esbuild/issues/14) and [#135](https://github.com/evanw/esbuild/pull/135))\n\n    The `file` loader copies the input file to the output directory and exports the path of the file as a string to any modules that import the file. For example, `--loader:.png=file` enables this loader for all imported `.png` files. This was contributed by [@viankakrisna](https://github.com/viankakrisna).\n\n* Add the `--resolve-extensions` flag ([#142](https://github.com/evanw/esbuild/pull/142))\n\n    This lets you override the implicit extensions that are tested when importing a file. It must be a comma-separated list of extensions. For example, setting `--resolve-extensions=.jsx,.js` means `import \"./foo\"` will check for `./foo` then `./foo.jsx` then `./foo.js` in that order. The behavior corresponds to [the similarly-named feature in Webpack](https://webpack.js.org/configuration/resolve/#resolveextensions). This was contributed by [@viankakrisna](https://github.com/viankakrisna).\n\n## 0.4.3\n\n* Fix bug with optional chaining parentheses ([#156](https://github.com/evanw/esbuild/issues/156))\n\n    One edge case with JavaScript optional chaining syntax is that parentheses stop the chain. So `a?.b.c` will be `undefined` if `a` is nullish but `(a?.b).c` will crash if `a` is nullish.\n\n    This was handled correctly when lowering is enabled (i.e. when the language target is `es2019` or below) but was not handled correctly when lowering is disabled (i.e. when the language target is `es2020` or above). The output for `(a?.b).c` was incorrectly `a?.b.c` instead of `(a?.b).c`, which would no longer crash if `a` is nullish. The fix is to preserve the parentheses in the output.\n\n* Support for the PowerPC 64-bit Little Endian architecture on Linux ([#146](https://github.com/evanw/esbuild/pull/146))\n\n    This was contributed by [@runlevel5](https://github.com/runlevel5).\n\n## 0.4.2\n\n* Bind imports to re-exports ([#149](https://github.com/evanw/esbuild/issues/149))\n\n    This fixes a bug where imports of re-exported symbols were not correctly merged in some cases. This resulted in the generated code referencing symbols that were not declared, resulting in a crash.\n\n## 0.4.1\n\n* Add a log level setting ([#117](https://github.com/evanw/esbuild/issues/117))\n\n    You can now silence esbuild except for errors with `--log-level=error`, or except for errors and warnings with `--log-level=warning`.\n\n* Now `jsconfig.json` is an alternative to `tsconfig.json` ([#132](https://github.com/evanw/esbuild/pull/132))\n\n    The `\"baseUrl\"` setting in `tsconfig.json`, which lets you avoid `../../` relative import paths, is respected by esbuild. With this change, esbuild will also check for this setting in `jsconfig.json` if no `tsconfig.json` file is found. This is relevant to some projects that use the TypeScript compiler with JavaScript files instead of TypeScript files. You can read more about this feature [here](https://code.visualstudio.com/docs/languages/jsconfig). This was contributed by [@viankakrisna](https://github.com/viankakrisna).\n\n* Chinese translation of documentation ([#129](https://github.com/evanw/esbuild/pull/129))\n\n    Both the readme and the architecture documentation have been translated into Chinese, which is available here: http://docs.breword.com/evanw-esbuild. This was contributed by [@92hackers](https://github.com/92hackers).\n\n* Async generator functions require `--target=es2018`\n\n    This fixes a bug where async generator functions were incorrectly allowed with `--target=es2017`, which is incorrect because the [asynchronous iteration spec](https://github.com/tc39/proposal-async-iteration) is part of ES2018.\n\n## 0.4.0\n\n* Add the `esm` output format ([#48](https://github.com/evanw/esbuild/issues/48))\n\n    It is now possible to generate a bundle in ES6 module format using `--format=esm`. The generated code uses ES6 import and export statements. This is useful for bundling code to be used as a library, for using in a `<script type=\"module>` tag in the browser, or for using with node's `--experimental-modules` flag. Note that CommonJS entry points bundled with this format will become a single default export, which is the same way node works.\n\n* Preliminary tree shaking support ([#50](https://github.com/evanw/esbuild/issues/50))\n\n    Bundling now performs tree shaking, which is also known as dead code elimination. Every top-level statement is considered to be a separate part of the file, and unused parts without any side effects are not included in the bundle. This only really affects code using ES6 modules, so make sure you use ES6 modules to take advantage of tree shaking.\n\n    This is the initial release of tree shaking which lands the fundamental mechanism behind it. This release does not include the [various annotations used by the community](https://webpack.js.org/guides/tree-shaking/) to indicate side-effect free code (e.g. `\"sideEffects\": false` and `/*#__PURE__*/`), so esbuild will likely generate somewhat bigger bundles than other bundlers. Support for these annotations will come in future releases.\n\n* Benchmarks have been re-run\n\n    This updates all of the bundlers used in the benchmark to their latest versions. Due to recent performance work, esbuild is now at least 100x faster than all other bundlers. I have also included a single-threaded version of esbuild for comparison since some people were wondering how much of esbuild's performance was due to multithreading.\n\n* Warnings about future syntax are now errors\n\n    This happens when an input file contains newer JavaScript syntax and `--target` is set to an earlier version of JavaScript than the syntax can be transformed to. These most of transforms will be implemented eventually, but for now some are still unimplemented. This was changed from a warning to an error because ignoring these warnings could result in broken code in older browsers, so these messages are more serious than warnings.\n\n* Using bundle-related flags without `--bundle` is now an error\n\n    This leaves the possibility open of using these flags for non-bundle mode in the future. For example, in the future `--format` may also work when not bundling.\n\n## 0.3.9\n\n* Add the `dataurl` loader ([#107](https://github.com/evanw/esbuild/pull/107))\n\n    This loader turns the file into a base64-encoded data URL. The mime type is automatically derived from the file extension, with the file contents used as a fallback. This was contributed by [@viankakrisna](https://github.com/viankakrisna).\n\n* Fix minification bug with external modules ([#134](https://github.com/evanw/esbuild/issues/134))\n\n    When loading a module marked `--external` with `require()`, the resulting code was sometimes incorrectly minified when bundling. This now has test coverage.\n\n## 0.3.8\n\n* Fix an issue that prevented non-inline source maps with the `build()` API ([#130](https://github.com/evanw/esbuild/issues/130))\n\n    The issue happend when invoking `esbuild.build({ sourcemap: true })` and was a regression due to the addition of inline source map support. This now has test coverage.\n\n## 0.3.7\n\n* Add an unsupported build for ARM64 ([#123](https://github.com/evanw/esbuild/issues/123))\n\n    Now you can `npm install esbuild` on a Linux ARM64 machine and it should work. This lets you run esbuild on a Raspberry Pi. Note that this target isn't officially supported because it's not covered by any automated tests. This was contributed by [@violentmagician](https://github.com/violentmagician).\n\n## 0.3.6\n\n* Fix a bug with JSX element contents that end in a multi-byte unicode character ([#124](https://github.com/evanw/esbuild/issues/124))\n\n    Such characters are now preserved instead of being truncated.\n\n## 0.3.5\n\n* Performance improvements\n\n    The parsing phase was failing to saturate all CPUs in many cases because input files were being read on a single goroutine in a blocking fashion. Each file is now read on its own goroutine and the parsing phase now saturates all CPUs.\n\n    With the performance improvements in this release and the previous release, the time to run the JavaScript benchmark has been reduced from 0.54s to 0.4s, which is approximately a 25% performance improvement.\n\n## 0.3.4\n\n* Performance improvements\n\n    The GC is now disabled when running in build-and-exit mode, which is a noticeable speedup. This release also fixes some accidental O(n^2) behavior in the code that renames variables to avoid collisions in non-minify mode. This didn't affect any of esbuild's benchmarks but it did cause issues on certain other artificial test cases.\n\n## 0.3.3\n\n* Support all unicode whitespace ([#116](https://github.com/evanw/esbuild/issues/116))\n\n    The lexer now accepts all unicode characters in the `WS` category as valid whitespace to match the JavaScript standard.\n\n## 0.3.2\n\n* Add some options related to source maps\n\n    There is now a `sourcefile` option to set the input file path for input files without a path. This happens in two cases: either using the `service.transform()` API or passing an input file using stdin.\n\n    This release also adds the `inline` value for the `sourcemap` option which inlines the source map as a base64-encoded data URL in the output file instead of writing the source map to a separate file.\n\n## 0.3.1\n\n* Remove type-only exports from TypeScript ([#110](https://github.com/evanw/esbuild/issues/110))\n\n    This fixes a bug where type-only exports in TypeScript files could in some cases generate an invalid export statement.\n\n## 0.3.0\n\n* Support for stdin/stdout ([#76](https://github.com/evanw/esbuild/issues/76))\n\n    You can now pass esbuild an input file over stdin instead of using a file path. Use the `--loader=jsx` syntax to set the loader instead of using the `--loader:.js=jsx` syntax.\n\n    Now if there is no output file, esbuild will write the output to stdout. Before this, esbuild would try to infer an output file based on the input file name. This is a breaking change so it was released with a minor version bump.\n"
  },
  {
    "path": "CHANGELOG-2021.md",
    "content": "# Changelog: 2021\n\nThis changelog documents all esbuild versions published in the year 2021 (versions 0.8.29 through 0.14.10).\n\n## 0.14.10\n\n* Enable tree shaking of classes with lowered static fields ([#175](https://github.com/evanw/esbuild/issues/175))\n\n    If the configured target environment doesn't support static class fields, they are converted into a call to esbuild's `__publicField` function instead. However, esbuild's tree-shaking pass treated this call as a side effect, which meant that all classes with static fields were ineligible for tree shaking. This release fixes the problem by explicitly ignoring calls to the `__publicField` function during tree shaking side-effect determination. Tree shaking is now enabled for these classes:\n\n    ```js\n    // Original code\n    class Foo { static foo = 'foo' }\n    class Bar { static bar = 'bar' }\n    new Bar()\n\n    // Old output (with --tree-shaking=true --target=es6)\n    class Foo {\n    }\n    __publicField(Foo, \"foo\", \"foo\");\n    class Bar {\n    }\n    __publicField(Bar, \"bar\", \"bar\");\n    new Bar();\n\n    // New output (with --tree-shaking=true --target=es6)\n    class Bar {\n    }\n    __publicField(Bar, \"bar\", \"bar\");\n    new Bar();\n    ```\n\n* Treat `--define:foo=undefined` as an undefined literal instead of an identifier ([#1407](https://github.com/evanw/esbuild/issues/1407))\n\n    References to the global variable `undefined` are automatically replaced with the literal value for undefined, which appears as `void 0` when printed. This allows for additional optimizations such as collapsing `undefined ?? bar` into just `bar`. However, this substitution was not done for values specified via `--define:`. As a result, esbuild could potentially miss out on certain optimizations in these cases. With this release, it's now possible to use `--define:` to substitute something with an undefined literal:\n\n    ```js\n    // Original code\n    let win = typeof window !== 'undefined' ? window : {}\n\n    // Old output (with --define:window=undefined --minify)\n    let win=typeof undefined!=\"undefined\"?undefined:{};\n\n    // New output (with --define:window=undefined --minify)\n    let win={};\n    ```\n\n* Add the `--drop:debugger` flag ([#1809](https://github.com/evanw/esbuild/issues/1809))\n\n    Passing this flag causes all [`debugger;` statements](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger) to be removed from the output. This is similar to the `drop_debugger: true` flag available in the popular UglifyJS and Terser JavaScript minifiers.\n\n* Add the `--drop:console` flag ([#28](https://github.com/evanw/esbuild/issues/28))\n\n    Passing this flag causes all [`console.xyz()` API calls](https://developer.mozilla.org/en-US/docs/Web/API/console#methods) to be removed from the output. This is similar to the `drop_console: true` flag available in the popular UglifyJS and Terser JavaScript minifiers.\n\n    WARNING: Using this flag can introduce bugs into your code! This flag removes the entire call expression including all call arguments. If any of those arguments had important side effects, using this flag will change the behavior of your code. Be very careful when using this flag. If you want to remove console API calls without removing arguments with side effects (which does not introduce bugs), you should mark the relevant API calls as pure instead like this: `--pure:console.log --minify`.\n\n* Inline calls to certain no-op functions when minifying ([#290](https://github.com/evanw/esbuild/issues/290), [#907](https://github.com/evanw/esbuild/issues/907))\n\n    This release makes esbuild inline two types of no-op functions: empty functions and identity functions. These most commonly arise when most of the function body is eliminated as dead code. In the examples below, this happens because we use `--define:window.DEBUG=false` to cause dead code elimination inside the function body of the resulting `if (false)` statement. This inlining is a small code size and performance win but, more importantly, it allows for people to use these features to add useful abstractions that improve the development experience without needing to worry about the run-time performance impact.\n\n    An identity function is a function that just returns its argument. Here's an example of inlining an identity function:\n\n    ```js\n    // Original code\n    function logCalls(fn) {\n      if (window.DEBUG) return function(...args) {\n        console.log('calling', fn.name, 'with', args)\n        return fn.apply(this, args)\n      }\n      return fn\n    }\n    export const foo = logCalls(function foo() {})\n\n    // Old output (with --minify --define:window.DEBUG=false --tree-shaking=true)\n    function o(n){return n}export const foo=o(function(){});\n\n    // New output (with --minify --define:window.DEBUG=false --tree-shaking=true)\n    export const foo=function(){};\n    ```\n\n    An empty function is a function with an empty body. Here's an example of inlining an empty function:\n\n    ```ts\n    // Original code\n    function assertNotNull(val: Object | null): asserts val is Object {\n      if (window.DEBUG && val === null) throw new Error('null assertion failed');\n    }\n    export const val = getFoo();\n    assertNotNull(val);\n    console.log(val.bar);\n\n    // Old output (with --minify --define:window.DEBUG=false --tree-shaking=true)\n    function l(o){}export const val=getFoo();l(val);console.log(val.bar);\n\n    // New output (with --minify --define:window.DEBUG=false --tree-shaking=true)\n    export const val=getFoo();console.log(val.bar);\n    ```\n\n    To get this behavior you'll need to use the `function` keyword to define your function since that causes the definition to be hoisted, which eliminates concerns around initialization order. These features also work across modules, so functions are still inlined even if the definition of the function is in a separate module from the call to the function. To get cross-module function inlining to work, you'll need to have bundling enabled and use the `import` and `export` keywords to access the function so that esbuild can see which functions are called. And all of this has been added without an observable impact to compile times.\n\n    I previously wasn't able to add this to esbuild easily because of esbuild's low-pass compilation approach. The compiler only does three full passes over the data for speed. The passes are roughly for parsing, binding, and printing. It's only possible to inline something after binding but it needs to be inlined before printing. Also the way module linking was done made it difficult to roll back uses of symbols that were inlined, so the symbol definitions were not tree shaken even when they became unused due to inlining.\n\n    The linking issue was somewhat resolved when I fixed #128 in the previous release. To implement cross-module inlining of TypeScript enums, I came up with a hack to defer certain symbol uses until the linking phase, which happens after binding but before printing. Another hack is that inlining of TypeScript enums is done directly in the printer to avoid needing another pass.\n\n    The possibility of these two hacks has unblocked these simple function inlining use cases that are now handled. This isn't a fully general approach because optimal inlining is recursive. Inlining something may open up further inlining opportunities, which either requires multiple iterations or a worklist algorithm, both of which don't work when doing late-stage inlining in the printer. But the function inlining that esbuild now implements is still useful even though it's one level deep, and so I believe it's still worth adding.\n\n## 0.14.9\n\n* Implement cross-module tree shaking of TypeScript enum values ([#128](https://github.com/evanw/esbuild/issues/128))\n\n    If your bundle uses TypeScript enums across multiple files, esbuild is able to inline the enum values as long as you export and import the enum using the ES module `export` and `import` keywords. However, this previously still left the definition of the enum in the bundle even when it wasn't used anymore. This was because esbuild's tree shaking (i.e. dead code elimination) is based on information recorded during parsing, and at that point we don't know which imported symbols are inlined enum values and which aren't.\n\n    With this release, esbuild will now remove enum definitions that become unused due to cross-module enum value inlining. Property accesses off of imported symbols are now tracked separately during parsing and then resolved during linking once all inlined enum values are known. This behavior change means esbuild's support for cross-module inlining of TypeScript enums is now finally complete. Here's an example:\n\n    ```js\n    // entry.ts\n    import { Foo } from './enum'\n    console.log(Foo.Bar)\n\n    // enum.ts\n    export enum Foo { Bar }\n    ```\n\n    Bundling the example code above now results in the enum definition being completely removed from the bundle:\n\n    ```js\n    // Old output (with --bundle --minify --format=esm)\n    var r=(o=>(o[o.Bar=0]=\"Bar\",o))(r||{});console.log(0);\n\n    // New output (with --bundle --minify --format=esm)\n    console.log(0);\n    ```\n\n* Fix a regression with `export {} from` and CommonJS ([#1890](https://github.com/evanw/esbuild/issues/1890))\n\n    This release fixes a regression that was introduced by the change in 0.14.7 that avoids calling the `__toESM` wrapper for import statements that are converted to `require` calls and that don't use the `default` or `__esModule` export names. The previous change was correct for the `import {} from` syntax but not for the `export {} from` syntax, which meant that in certain cases with re-exported values, the value of the `default` import could be different than expected. This release fixes the regression.\n\n* Warn about using `module` or `exports` in ESM code ([#1887](https://github.com/evanw/esbuild/issues/1887))\n\n    CommonJS export variables cannot be referenced in ESM code. If you do this, they are treated as global variables instead. This release includes a warning for people that try to use both CommonJS and ES module export styles in the same file. Here's an example:\n\n    ```ts\n    export enum Something {\n      a,\n      b,\n    }\n    module.exports = { a: 1, b: 2 }\n    ```\n\n    Running esbuild on that code now generates a warning that looks like this:\n\n    ```\n    ▲ [WARNING] The CommonJS \"module\" variable is treated as a global variable in an ECMAScript module and may not work as expected\n\n        example.ts:5:0:\n          5 │ module.exports = { a: 1, b: 2 }\n            ╵ ~~~~~~\n\n      This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n\n        example.ts:1:0:\n          1 │ export enum Something {\n            ╵ ~~~~~~\n    ```\n\n## 0.14.8\n\n* Add a `resolve` API for plugins ([#641](https://github.com/evanw/esbuild/issues/641), [#1652](https://github.com/evanw/esbuild/issues/1652))\n\n    Plugins now have access to a new API called `resolve` that runs esbuild's path resolution logic and returns the result to the caller. This lets you write plugins that can reuse esbuild's complex built-in path resolution logic to change the inputs and/or adjust the outputs. Here's an example:\n\n    ```js\n    let examplePlugin = {\n      name: 'example',\n      setup(build) {\n        build.onResolve({ filter: /^example$/ }, async () => {\n          const result = await build.resolve('./foo', { resolveDir: '/bar' })\n          if (result.errors.length > 0) return result\n          return { ...result, external: true }\n        })\n      },\n    }\n    ```\n\n    This plugin intercepts imports to the path `example`, tells esbuild to resolve the import `./foo` in the directory `/bar`, and then forces whatever path esbuild returns to be considered external. Here are some additional details:\n\n    * If you don't pass the optional `resolveDir` parameter, esbuild will still run `onResolve` plugin callbacks but will not attempt any path resolution itself. All of esbuild's path resolution logic depends on the `resolveDir` parameter including looking for packages in `node_modules` directories (since it needs to know where those `node_modules` directories might be).\n\n    * If you want to resolve a file name in a specific directory, make sure the input path starts with `./`. Otherwise the input path will be treated as a package path instead of a relative path. This behavior is identical to esbuild's normal path resolution logic.\n\n    * If path resolution fails, the `errors` property on the returned object will be a non-empty array containing the error information. This function does not always throw an error when it fails. You need to check for errors after calling it.\n\n    * The behavior of this function depends on the build configuration. That's why it's a property of the `build` object instead of being a top-level API call. This also means you can't call it until all plugin `setup` functions have finished since these give plugins the opportunity to adjust the build configuration before it's frozen at the start of the build. So the new `resolve` function is going to be most useful inside your `onResolve` and/or `onLoad` callbacks.\n\n    * There is currently no attempt made to detect infinite path resolution loops. Calling `resolve` from within `onResolve` with the same parameters is almost certainly a bad idea.\n\n* Avoid the CJS-to-ESM wrapper in some cases ([#1831](https://github.com/evanw/esbuild/issues/1831))\n\n    Import statements are converted into `require()` calls when the output format is set to CommonJS. To convert from CommonJS semantics to ES module semantics, esbuild wraps the return value in a call to esbuild's `__toESM()` helper function. However, the conversion is only needed if it's possible that the exports named `default` or `__esModule` could be accessed.\n\n    This release avoids calling this helper function in cases where esbuild knows it's impossible for the `default` or `__esModule` exports to be accessed, which results in smaller and faster code. To get this behavior, you have to use the `import {} from` import syntax:\n\n    ```js\n    // Original code\n    import { readFile } from \"fs\";\n    readFile();\n\n    // Old output (with --format=cjs)\n    var __toESM = (module, isNodeMode) => {\n      ...\n    };\n    var import_fs = __toESM(require(\"fs\"));\n    (0, import_fs.readFile)();\n\n    // New output (with --format=cjs)\n    var import_fs = require(\"fs\");\n    (0, import_fs.readFile)();\n    ```\n\n* Strip overwritten function declarations when minifying ([#610](https://github.com/evanw/esbuild/issues/610))\n\n    JavaScript allows functions to be re-declared, with each declaration overwriting the previous declaration. This type of code can sometimes be emitted by automatic code generators. With this release, esbuild now takes this behavior into account when minifying to drop all but the last declaration for a given function:\n\n    ```js\n    // Original code\n    function foo() { console.log(1) }\n    function foo() { console.log(2) }\n\n    // Old output (with --minify)\n    function foo(){console.log(1)}function foo(){console.log(2)}\n\n    // New output (with --minify)\n    function foo(){console.log(2)}\n    ```\n\n* Add support for the Linux IBM Z 64-bit Big Endian platform ([#1864](https://github.com/evanw/esbuild/pull/1864))\n\n    With this release, the esbuild package now includes a Linux binary executable for the IBM System/390 64-bit architecture. This new platform was contributed by [@shahidhs-ibm](https://github.com/shahidhs-ibm).\n\n* Allow whitespace around `:` in JSX elements ([#1877](https://github.com/evanw/esbuild/issues/1877))\n\n    This release allows you to write the JSX `<rdf:Description rdf:ID=\"foo\" />` as `<rdf : Description rdf : ID=\"foo\" />` instead. Doing this is not forbidden by [the JSX specification](https://facebook.github.io/jsx/). While this doesn't work in TypeScript, it does work with other JSX parsers in the ecosystem, so support for this has been added to esbuild.\n\n## 0.14.7\n\n* Cross-module inlining of TypeScript `enum` constants ([#128](https://github.com/evanw/esbuild/issues/128))\n\n    This release adds inlining of TypeScript `enum` constants across separate modules. It activates when bundling is enabled and when the enum is exported via the `export` keyword and imported via the `import` keyword:\n\n    ```ts\n    // foo.ts\n    export enum Foo { Bar }\n\n    // bar.ts\n    import { Foo } from './foo.ts'\n    console.log(Foo.Bar)\n    ```\n\n    The access to `Foo.Bar` will now be compiled into `0 /* Bar */` even though the enum is defined in a separate file. This inlining was added without adding another pass (which would have introduced a speed penalty) by splitting the code for the inlining between the existing parsing and printing passes. Enum inlining is active whether or not you use `enum` or `const enum` because it improves performance.\n\n    To demonstrate the performance improvement, I compared the performance of the TypeScript compiler built by bundling the TypeScript compiler source code with esbuild before and after this change. The speed of the compiler was measured by using it to type check a small TypeScript code base. Here are the results:\n\n    |      | `tsc` | with esbuild 0.14.6 | with esbuild 0.14.7 |\n    |------|-------|---------------------|---------------------|\n    | Time | 2.96s | 3.45s               | 2.95s               |\n\n    As you can see, enum inlining gives around a 15% speedup, which puts the esbuild-bundled version at the same speed as the offical TypeScript compiler build (the `tsc` column)!\n\n    The specifics of the benchmark aren't important here since it's just a demonstration of how enum inlining can affect performance. But if you're wondering, I type checked the [Rollup](https://github.com/rollup/rollup) code base using a work-in-progress branch of the TypeScript compiler that's part of the ongoing effort to convert their use of namespaces into ES modules.\n\n* Mark node built-in modules as having no side effects ([#705](https://github.com/evanw/esbuild/issues/705))\n\n    This release marks node built-in modules such as `fs` as being side-effect free. That means unused imports to these modules are now removed when bundling, which sometimes results in slightly smaller code. For example:\n\n    ```js\n    // Original code\n    import fs from 'fs';\n    import path from 'path';\n    console.log(path.delimiter);\n\n    // Old output (with --bundle --minify --platform=node --format=esm)\n    import\"fs\";import o from\"path\";console.log(o.delimiter);\n\n    // New output (with --bundle --minify --platform=node --format=esm)\n    import o from\"path\";console.log(o.delimiter);\n    ```\n\n    Note that these modules are only automatically considered side-effect when bundling for node, since they are only known to be side-effect free imports in that environment. However, you can customize this behavior with a plugin by returning `external: true` and `sideEffects: false` in an `onResolve` callback for whatever paths you want to be treated this way.\n\n* Recover from a stray top-level `}` in CSS ([#1876](https://github.com/evanw/esbuild/pull/1876))\n\n    This release fixes a bug where a stray `}` at the top-level of a CSS file would incorrectly truncate the remainder of the file in the output (although not without a warning). With this release, the remainder of the file is now still parsed and printed:\n\n    ```css\n    /* Original code */\n    .red {\n      color: red;\n    }\n    }\n    .blue {\n      color: blue;\n    }\n    .green {\n      color: green;\n    }\n\n    /* Old output (with --minify) */\n    .red{color:red}\n\n    /* New output (with --minify) */\n    .red{color:red}} .blue{color:#00f}.green{color:green}\n    ```\n\n    This fix was contributed by [@sbfaulkner](https://github.com/sbfaulkner).\n\n## 0.14.6\n\n* Fix a minifier bug with BigInt literals\n\n    Previously expression simplification optimizations in the minifier incorrectly assumed that numeric operators always return numbers. This used to be true but has no longer been true since the introduction of BigInt literals in ES2020. Now numeric operators can return either a number or a BigInt depending on the arguments. This oversight could potentially have resulted in behavior changes. For example, this code printed `false` before being minified and `true` after being minified because esbuild shortened `===` to `==` under the false assumption that both operands were numbers:\n\n    ```js\n    var x = 0;\n    console.log((x ? 2 : -1n) === -1);\n    ```\n\n    The type checking logic has been rewritten to take into account BigInt literals in this release, so this incorrect simplification is no longer applied.\n\n* Enable removal of certain unused template literals ([#1853](https://github.com/evanw/esbuild/issues/1853))\n\n    This release contains improvements to the minification of unused template literals containing primitive values:\n\n    ```js\n    // Original code\n    `${1}${2}${3}`;\n    `${x ? 1 : 2}${y}`;\n\n    // Old output (with --minify)\n    \"\"+1+2+3,\"\"+(x?1:2)+y;\n\n    // New output (with --minify)\n    x,`${y}`;\n    ```\n\n    This can arise when the template literals are nested inside of another function call that was determined to be unnecessary such as an unused call to a function marked with the `/* @__PURE__ */` pragma.\n\n    This release also fixes a bug with this transformation where minifying the unused expression `` `foo ${bar}` `` into `\"\" + bar` changed the meaning of the expression. Template string interpolation always calls `toString` while string addition may call `valueOf` instead. This unused expression is now minified to `` `${bar}` ``, which is slightly longer but which avoids the behavior change.\n\n* Allow `keyof`/`readonly`/`infer` in TypeScript index signatures ([#1859](https://github.com/evanw/esbuild/pull/1859))\n\n    This release fixes a bug that prevented these keywords from being used as names in index signatures. The following TypeScript code was previously rejected, but is now accepted:\n\n    ```ts\n    interface Foo {\n      [keyof: string]: number\n    }\n    ```\n\n    This fix was contributed by [@magic-akari](https://github.com/magic-akari).\n\n* Avoid warning about `import.meta` if it's replaced ([#1868](https://github.com/evanw/esbuild/issues/1868))\n\n    It's possible to replace the `import.meta` expression using the `--define:` feature. Previously doing that still warned that the `import.meta` syntax was not supported when targeting ES5. With this release, there will no longer be a warning in this case.\n\n## 0.14.5\n\n* Fix an issue with the publishing script\n\n    This release fixes a missing dependency issue in the publishing script where it was previously possible for the published binary executable to have an incorrect version number.\n\n## 0.14.4\n\n* Adjust esbuild's handling of `default` exports and the `__esModule` marker ([#532](https://github.com/evanw/esbuild/issues/532), [#1591](https://github.com/evanw/esbuild/issues/1591), [#1719](https://github.com/evanw/esbuild/issues/1719))\n\n    This change requires some background for context. Here's the history to the best of my understanding:\n\n    When the ECMAScript module `import`/`export` syntax was being developed, the CommonJS module format (used in Node.js) was already widely in use. Because of this the export name called `default` was given special a syntax. Instead of writing `import { default as foo } from 'bar'` you can just write `import foo from 'bar'`. The idea was that when ECMAScript modules (a.k.a. ES modules) were introduced, you could import existing CommonJS modules using the new import syntax for compatibility. Since CommonJS module exports are dynamic while ES module exports are static, it's not generally possible to determine a CommonJS module's export names at module instantiation time since the code hasn't been evaluated yet. So the value of `module.exports` is just exported as the `default` export and the special `default` import syntax gives you easy access to `module.exports` (i.e. `const foo = require('bar')` is the same as `import foo from 'bar'`).\n\n    However, it took a while for ES module syntax to be supported natively by JavaScript runtimes, and people still wanted to start using ES module syntax in the meantime. The [Babel](https://babeljs.io/) JavaScript compiler let you do this. You could transform each ES module file into a CommonJS module file that behaved the same. However, this transformation has a problem: emulating the `import` syntax accurately as described above means that `export default 0` and `import foo from 'bar'` will no longer line up when transformed to CommonJS. The code `export default 0` turns into `module.exports.default = 0` and the code `import foo from 'bar'` turns into `const foo = require('bar')`, meaning `foo` is `0` before the transformation but `foo` is `{ default: 0 }` after the transformation.\n\n    To fix this, Babel sets the property `__esModule` to true as a signal to itself when it converts an ES module to a CommonJS module. Then, when importing a `default` export, it can know to use the value of `module.exports.default` instead of `module.exports` to make sure the behavior of the CommonJS modules correctly matches the behavior of the original ES modules. This fix has been widely adopted across the ecosystem and has made it into other tools such as TypeScript and even esbuild.\n\n    However, when Node.js finally released their ES module implementation, they went with the original implementation where the `default` export is always `module.exports`, which broke compatibility with the existing ecosystem of ES modules that had been cross-compiled into CommonJS modules by Babel. You now have to either add or remove an additional `.default` property depending on whether your code needs to run in a Node environment or in a Babel environment, which created an interoperability headache. In addition, JavaScript tools such as esbuild now need to guess whether you want Node-style or Babel-style `default` imports. There's no way for a tool to know with certainty which one a given file is expecting and if your tool guesses wrong, your code will break.\n\n    This release changes esbuild's heuristics around `default` exports and the `__esModule` marker to attempt to improve compatibility with Webpack and Node, which is what most packages are tuned for. The behavior changes are as follows:\n\n    Old behavior:\n\n    * If an `import` statement is used to load a CommonJS file and a) `module.exports` is an object, b) `module.exports.__esModule` is truthy, and c) the property `default` exists in `module.exports`, then esbuild would set the `default` export to `module.exports.default` (like Babel). Otherwise the `default` export was set to `module.exports` (like Node).\n\n    * If a `require` call is used to load an ES module file, the returned module namespace object had the `__esModule` property set to true. This behaved as if the ES module had been converted to CommonJS via  a Babel-compatible transformation.\n\n    * The `__esModule` marker could inconsistently appear on module namespace objects (i.e. `import * as`) when writing pure ESM code. Specifically, if a module namespace object was materialized then the `__esModule` marker was present, but if it was optimized away then the `__esModule` marker was absent.\n\n    * It was not allowed to create an ES module export named `__esModule`. This avoided generating code that might break due to the inconsistency mentioned above, and also avoided issues with duplicate definitions of `__esModule`.\n\n    New behavior:\n\n    * If an `import` statement is used to load a CommonJS file and a) `module.exports` is an object, b) `module.exports.__esModule` is truthy, and c) the file name does not end in either `.mjs` or `.mts` and the `package.json` file does not contain `\"type\": \"module\"`, then esbuild will set the `default` export to `module.exports.default` (like Babel). Otherwise the `default` export is set to `module.exports` (like Node).\n\n        Note that this means the `default` export may now be undefined in situations where it previously wasn't undefined. This matches Webpack's behavior so it should hopefully be more compatible.\n\n        Also note that this means import behavior now depends on the file extension and on the contents of `package.json`. This also matches Webpack's behavior to hopefully improve compatibility.\n\n    * If a `require` call is used to load an ES module file, the returned module namespace object has the `__esModule` property set to `true`. This behaves as if the ES module had been converted to CommonJS via  a Babel-compatible transformation.\n\n    * If an `import` statement or `import()` expression is used to load an ES module, the `__esModule` marker should now never be present on the module namespace object. This frees up the `__esModule` export name for use with ES modules.\n\n    * It's now allowed to use `__esModule` as a normal export name in an ES module. This property will be accessible to other ES modules but will not be accessible to code that loads the ES module using `require`, where they will observe the property set to `true` instead.\n\n## 0.14.3\n\n* Pass the current esbuild instance to JS plugins ([#1790](https://github.com/evanw/esbuild/issues/1790))\n\n    Previously JS plugins that wanted to run esbuild had to `require('esbuild')` to get the esbuild object. However, that could potentially result in a different version of esbuild. This is also more complicated to do outside of node (such as within a browser). With this release, the current esbuild instance is now passed to JS plugins as the `esbuild` property:\n\n    ```js\n    let examplePlugin = {\n      name: 'example',\n      setup(build) {\n        console.log(build.esbuild.version)\n        console.log(build.esbuild.transformSync('1+2'))\n      },\n    }\n    ```\n\n* Disable `calc()` transform for results with non-finite numbers ([#1839](https://github.com/evanw/esbuild/issues/1839))\n\n    This release disables minification of `calc()` expressions when the result contains `NaN`, `-Infinity`, or `Infinity`. These numbers are valid inside of `calc()` expressions but not outside of them, so the `calc()` expression must be preserved in these cases.\n\n* Move `\"use strict\"` before injected shim imports ([#1837](https://github.com/evanw/esbuild/issues/1837))\n\n    If a CommonJS file contains a `\"use strict\"` directive, it could potentially be unintentionally disabled by esbuild when using the \"inject\" feature when bundling is enabled. This is because the inject feature was inserting a call to the initializer for the injected file before the `\"use strict\"` directive. In JavaScript, directives do not apply if they come after a non-directive statement. This release fixes the problem by moving the `\"use strict\"` directive before the initializer for the injected file so it isn't accidentally disabled.\n\n* Pass the ignored path query/hash suffix to `onLoad` plugins ([#1827](https://github.com/evanw/esbuild/issues/1827))\n\n    The built-in `onResolve` handler that comes with esbuild can strip the query/hash suffix off of a path during path resolution. For example, `url(\"fonts/icons.eot?#iefix\")` can be resolved to the file `fonts/icons.eot`. For context, IE8 has a bug where it considers the font face URL to extend to the last `)` instead of the first `)`. In the example below, IE8 thinks the URL for the font is `Example.eot?#iefix') format('eot'), url('Example.ttf') format('truetype` so by adding `?#iefix`, IE8 thinks the URL has a path of `Example.eot` and a query string of `?#iefix') format('eot...` and can load the font file:\n\n    ```css\n    @font-face {\n      font-family: 'Example';\n      src: url('Example.eot?#iefix') format('eot'), url('Example.ttf') format('truetype');\n    }\n    ```\n\n    However, the suffix is not currently passed to esbuild and plugins may want to use this suffix for something. Previously plugins had to add their own `onResolve` handler if they wanted to use the query suffix. With this release, the suffix can now be returned by plugins from `onResolve` and is now passed to plugins in `onLoad`:\n\n    ```js\n    let examplePlugin = {\n      name: 'example',\n      setup(build) {\n        build.onResolve({ filter: /.*/ }, args => {\n          return { path: args.path, suffix: '?#iefix' }\n        })\n\n        build.onLoad({ filter: /.*/ }, args => {\n          console.log({ path: args.path, suffix: args.suffix })\n        })\n      },\n    }\n    ```\n\n    The suffix is deliberately not included in the path that's provided to plugins because most plugins won't know to handle this strange edge case and would likely break. Keeping the suffix out of the path means that plugins can opt-in to handling this edge case if they want to, and plugins that aren't aware of this edge case will likely still do something reasonable.\n\n## 0.14.2\n\n* Add `[ext]` placeholder for path templates ([#1799](https://github.com/evanw/esbuild/pull/1799))\n\n    This release adds the `[ext]` placeholder to the `--entry-names=`, `--chunk-names=`, and `--asset-names=` configuration options. The `[ext]` placeholder takes the value of the file extension without the leading `.`, and can be used to place output files with different file extensions into different folders. For example, `--asset-names=assets/[ext]/[name]-[hash]` might generate an output path of `assets/png/image-LSAMBFUD.png`.\n\n    This feature was contributed by [@LukeSheard](https://github.com/LukeSheard).\n\n* Disable star-to-clause transform for external imports ([#1801](https://github.com/evanw/esbuild/issues/1801))\n\n    When bundling is enabled, esbuild automatically transforms `import * as x from 'y'; x.z()` into `import {z} as 'y'; z()` to improve tree shaking. This avoids needing to create the import namespace object `x` if it's unnecessary, which can result in the removal of large amounts of unused code. However, this transform shouldn't be done for external imports because that incorrectly changes the semantics of the import. If the export `z` doesn't exist in the previous example, the value `x.z` is a property access that is undefined at run-time, but the value `z` is an import error that will prevent the code from running entirely. This release fixes the problem by avoiding doing this transform for external imports:\n\n    ```js\n    // Original code\n    import * as x from 'y';\n    x.z();\n\n    // Old output (with --bundle --format=esm --external:y)\n    import { z } from \"y\";\n    z();\n\n    // New output (with --bundle --format=esm --external:y)\n    import * as x from \"y\";\n    x.z();\n    ```\n\n* Disable `calc()` transform for numbers with many fractional digits ([#1821](https://github.com/evanw/esbuild/issues/1821))\n\n    Version 0.13.12 introduced simplification of `calc()` expressions in CSS when minifying. For example, `calc(100% / 4)` turns into `25%`. However, this is problematic for numbers with many fractional digits because either the number is printed with reduced precision, which is inaccurate, or the number is printed with full precision, which could be longer than the original expression. For example, turning `calc(100% / 3)` into `33.33333%` is inaccurate and turning it into `33.333333333333336%` likely isn't desired. In this release, minification of `calc()` is now disabled when any number in the result cannot be represented to full precision with at most five fractional digits.\n\n* Fix an edge case with `catch` scope handling ([#1812](https://github.com/evanw/esbuild/issues/1812))\n\n    This release fixes a subtle edge case with `catch` scope and destructuring assignment. Identifiers in computed properties and/or default values inside the destructuring binding pattern should reference the outer scope, not the inner scope. The fix was to split the destructuring pattern into its own scope, separate from the `catch` body. Here's an example of code that was affected by this edge case:\n\n    ```js\n    // Original code\n    let foo = 1\n    try {\n      throw ['a', 'b']\n    } catch ({ [foo]: y }) {\n      let foo = 2\n      assert(y === 'b')\n    }\n\n    // Old output (with --minify)\n    let foo=1;try{throw[\"a\",\"b\"]}catch({[o]:t}){let o=2;assert(t===\"b\")}\n\n    // New output (with --minify)\n    let foo=1;try{throw[\"a\",\"b\"]}catch({[foo]:t}){let o=2;assert(t===\"b\")}\n    ```\n\n* Go 1.17.2 was upgraded to Go 1.17.4\n\n    The previous release was built with Go 1.17.2, but this release is built with Go 1.17.4. This is just a routine upgrade. There are no changes significant to esbuild outside of some security-related fixes to Go's HTTP stack (but you shouldn't be running esbuild's dev server in production anyway).\n\n    One notable change related to this is that esbuild's publishing script now ensures that git's state is free of uncommitted and/or untracked files before building. Previously this wasn't the case because publishing esbuild involved changing the version number, running the publishing script, and committing at the end, which meant that files were uncommitted during the build process. I also typically had some untracked test files in the same directory during publishing (which is harmless).\n\n    This matters because there's an upcoming change in Go 1.18 where the Go compiler will include metadata about whether there are untracked files or not when doing a build: https://github.com/golang/go/issues/37475. Changing esbuild's publishing script should mean that when esbuild upgrades to Go 1.18, esbuild's binary executables will be marked as being built off of a specific commit without any modifications. This is important for reproducibility. Checking out a specific esbuild commit and building it should give a bitwise-identical binary executable to one that I published. But if this metadata indicated that there were untracked files during the published build, then the resulting executable would no longer be bitwise-identical.\n\n## 0.14.1\n\n* Fix `imports` in `package.json` ([#1807](https://github.com/evanw/esbuild/issues/1807))\n\n    This release contains a fix for the rarely-used [`imports` feature in `package.json` files](https://nodejs.org/api/packages.html#subpath-imports) that lets a package specify a custom remapping for import paths inside that package that start with `#`. Support for `imports` was added in version 0.13.9. However, the field was being incorrectly interpreted as relative to the importing file instead of to the `package.json` file, which caused an import failure when the importing file is in a subdirectory instead of being at the top level of the package. Import paths should now be interpreted as relative to the correct directory which should fix these path resolution failures.\n\n* Isolate implicit sibling scope lookup for `enum` and `namespace`\n\n    The previous release implemented sibling namespaces in TypeScript, which introduces a new kind of scope lookup that doesn't exist in JavaScript. Exported members inside an `enum` or `namespace` block can be implicitly referenced in a sibling `enum` or `namespace` block just by using the name without using a property reference. However, this behavior appears to only work for `enum`-to-`enum` and `namespace`-to-`namespace` interactions. Even though sibling enums and namespaces with the same name can be merged together into the same underlying object, this implicit reference behavior doesn't work for `enum`-to-`namespace` interactions and attempting to do this with a `namespace`-to-`enum` interaction [causes the TypeScript compiler itself to crash](https://github.com/microsoft/TypeScript/issues/46891). Here is an example of how the TypeScript compiler behaves in each case:\n\n    ```ts\n    // \"b\" is accessible\n    enum a { b = 1 }\n    enum a { c = b }\n\n    // \"e\" is accessible\n    namespace d { export let e = 1 }\n    namespace d { export let f = e }\n\n    // \"h\" is inaccessible\n    enum g { h = 1 }\n    namespace g { export let i = h }\n\n    // This causes the TypeScript compiler to crash\n    namespace j { export let k = 1 }\n    enum j { l = k }\n    ```\n\n    This release changes the implicit sibling scope lookup behavior to only work for `enum`-to-`enum` and `namespace`-to-`namespace` interactions. These implicit references no longer work with `enum`-to-`namespace` and `namespace`-to-`enum` interactions, which should more accurately match the behavior of the TypeScript compiler.\n\n* Add semicolon insertion before TypeScript-specific definite assignment assertion modifier ([#1810](https://github.com/evanw/esbuild/issues/1810))\n\n    TypeScript lets you add a `!` after a variable declaration to bypass TypeScript's definite assignment analysis:\n\n    ```ts\n    let x!: number[];\n    initialize();\n    x.push(4);\n\n    function initialize() { x = [0, 1, 2, 3]; }\n    ```\n\n    This `!` is called a [definite assignment assertion](https://devblogs.microsoft.com/typescript/announcing-typescript-2-7/#definite-assignment-assertions) and tells TypeScript to assume that the variable has been initialized somehow. However, JavaScript's automatic semicolon insertion rules should be able to insert a semicolon before it:\n\n    ```ts\n    let a\n    !function(){}()\n    ```\n\n    Previously the above code was incorrectly considered a syntax error in TypeScript. With this release, this code is now parsed correctly.\n\n* Log output to stderr has been overhauled\n\n    This release changes the way log messages are formatted to stderr. The changes make the kind of message (e.g. error vs. warning vs. note) more obvious, and they also give more room for paragraph-style notes that can provide more detail about the message. Here's an example:\n\n    Before:\n\n    ```\n     > example.tsx:14:25: warning: Comparison with -0 using the \"===\" operator will also match 0\n        14 │     case 1: return x === -0\n           ╵                          ~~\n     > example.tsx:21:23: error: Could not resolve \"path\" (use \"--platform=node\" when building for node)\n        21 │   const path = require('path')\n           ╵                        ~~~~~~\n    ```\n\n    After:\n\n    ```\n    ▲ [WARNING] Comparison with -0 using the \"===\" operator will also match 0\n\n        example.tsx:14:25:\n          14 │     case 1: return x === -0\n             ╵                          ~~\n\n      Floating-point equality is defined such that 0 and -0 are equal, so \"x === -0\" returns true for\n      both 0 and -0. You need to use \"Object.is(x, -0)\" instead to test for -0.\n\n    ✘ [ERROR] Could not resolve \"path\"\n\n        example.tsx:21:23:\n          21 │   const path = require('path')\n             ╵                        ~~~~~~\n\n      The package \"path\" wasn't found on the file system but is built into node. Are you trying to\n      bundle for node? You can use \"--platform=node\" to do that, which will remove this error.\n    ```\n\n    Note that esbuild's formatted log output is for humans, not for machines. If you need to output a stable machine-readable format, you should be using the API for that. Build and transform results have arrays called `errors` and `warnings` with objects that represent the log messages.\n\n* Show inlined enum value names in comments\n\n    When esbuild inlines an enum, it will now put a comment next to it with the original enum name:\n\n    ```ts\n    // Original code\n    const enum Foo { FOO }\n    console.log(Foo.FOO)\n\n    // Old output\n    console.log(0);\n\n    // New output\n    console.log(0 /* FOO */);\n    ```\n\n    This matches the behavior of the TypeScript compiler, and should help with debugging. These comments are not generated if minification is enabled.\n\n## 0.14.0\n\n**This release contains backwards-incompatible changes.** Since esbuild is before version 1.0.0, these changes have been released as a new minor version to reflect this (as [recommended by npm](https://docs.npmjs.com/cli/v6/using-npm/semver/)). You should either be pinning the exact version of `esbuild` in your `package.json` file or be using a version range syntax that only accepts patch upgrades such as `~0.13.0`. See the documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\n* Add support for TypeScript's `preserveValueImports` setting ([#1525](https://github.com/evanw/esbuild/issues/1525))\n\n    TypeScript 4.5, which was just released, added [a new setting called `preserveValueImports`](https://devblogs.microsoft.com/typescript/announcing-typescript-4-5/#preserve-value-imports). This release of esbuild implements support for this new setting. However, this release also changes esbuild's behavior regarding the `importsNotUsedAsValues` setting, so this release is being considered a breaking change. Now esbuild's behavior should more accurately match the behavior of the TypeScript compiler. This is described in more detail below.\n\n    The difference in behavior is around unused imports. By default, unused import names are considered to be types and are completely removed if they are unused. If all import names are removed for a given import statement, then the whole import statement is removed too. The two `tsconfig.json` settings [`importsNotUsedAsValues`](https://www.typescriptlang.org/tsconfig#importsNotUsedAsValues) and [`preserveValueImports`](https://www.typescriptlang.org/tsconfig#preserveValueImports) let you customize this. Here's what the TypeScript compiler's output looks like with these different settings enabled:\n\n    ```ts\n    // Original code\n    import { unused } from \"foo\";\n\n    // Default output\n    /* (the import is completely removed) */\n\n    // Output with \"importsNotUsedAsValues\": \"preserve\"\n    import \"foo\";\n\n    // Output with \"preserveValueImports\": true\n    import { unused } from \"foo\";\n    ```\n\n    Previously, since the `preserveValueImports` setting didn't exist yet, esbuild had treated the `importsNotUsedAsValues` setting as if it were what is now the `preserveValueImports` setting instead. This was a deliberate deviation from how the TypeScript compiler behaves, but was necessary to allow esbuild to be used as a TypeScript-to-JavaScript compiler inside of certain composite languages such as Svelte and Vue. These languages append additional code after converting the TypeScript to JavaScript so unused imports may actually turn out to be used later on:\n\n    ```svelte\n    <script>\n    import { someFunc } from \"./some-module.js\";\n    </script>\n    <button on:click={someFunc}>Click me!</button>\n    ```\n\n    Previously the implementers of these languages had to use the `importsNotUsedAsValues` setting as a hack for esbuild to preserve the import statements. With this release, esbuild now follows the behavior of the TypeScript compiler so implementers will need to use the new `preserveValueImports` setting to do this instead. This is the breaking change.\n\n* TypeScript code follows JavaScript class field semantics with `--target=esnext` ([#1480](https://github.com/evanw/esbuild/issues/1480))\n\n    TypeScript 4.3 included a subtle breaking change that wasn't mentioned in the [TypeScript 4.3 blog post](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3/): class fields will now be compiled with different semantics if `\"target\": \"ESNext\"` is present in `tsconfig.json`. Specifically in this case `useDefineForClassFields` will default to `true` when not specified instead of `false`. This means class field behavior in TypeScript code will now match JavaScript instead of doing something else:\n\n    ```js\n    class Base {\n      set foo(value) { console.log('set', value) }\n    }\n    class Derived extends Base {\n      foo = 123\n    }\n    new Derived()\n    ```\n\n    In TypeScript 4.2 and below, the TypeScript compiler would generate code that prints `set 123` when `tsconfig.json` contains `\"target\": \"ESNext\"` but in TypeScript 4.3 and above, the TypeScript compiler will now generate code that doesn't print anything. This is the difference between \"assign\" semantics and \"define\" semantics.\n\n    Previously you had to create a `tsconfig.json` file and specify `\"target\": \"ESNext\"` to get this behavior in esbuild. With this release, you can now also just pass `--target=esnext` to esbuild to force-enable this behavior. Note that esbuild doesn't do this by default even though the default value of `--target=` otherwise behaves like `esnext`. Since TypeScript's compiler doesn't do this behavior by default, it seems like a good idea for esbuild to not do this behavior by default either.\n\nIn addition to the breaking changes above, the following changes are also included in this release:\n\n* Allow certain keywords as tuple type labels in TypeScript ([#1797](https://github.com/evanw/esbuild/issues/1797))\n\n    Apparently TypeScript lets you use certain keywords as tuple labels but not others. For example, `type x = [function: number]` is allowed while `type x = [class: number]` isn't. This release replicates this behavior in esbuild's TypeScript parser:\n\n    * Allowed keywords: `false`, `function`, `import`, `new`, `null`, `this`, `true`, `typeof`, `void`\n\n    * Forbidden keywords: `break`, `case`, `catch`, `class`, `const`, `continue`, `debugger`, `default`, `delete`, `do`, `else`, `enum`, `export`, `extends`, `finally`, `for`, `if`, `in`, `instanceof`, `return`, `super`, `switch`, `throw`, `try`, `var`, `while`, `with`\n\n* Support sibling namespaces in TypeScript ([#1410](https://github.com/evanw/esbuild/issues/1410))\n\n    TypeScript has a feature where sibling namespaces with the same name can implicitly reference each other's exports without an explicit property access. This goes against how scope lookup works in JavaScript, so it previously didn't work with esbuild. This release adds support for this feature:\n\n    ```ts\n    // Original TypeScript code\n    namespace x {\n      export let y = 123\n    }\n    namespace x {\n      export let z = y\n    }\n\n    // Old JavaScript output\n    var x;\n    (function(x2) {\n      x2.y = 123;\n    })(x || (x = {}));\n    (function(x2) {\n      x2.z = y;\n    })(x || (x = {}));\n\n    // New JavaScript output\n    var x;\n    (function(x2) {\n      x2.y = 123;\n    })(x || (x = {}));\n    (function(x2) {\n      x2.z = x2.y;\n    })(x || (x = {}));\n    ```\n\n    Notice how the identifier `y` is now compiled to the property access `x2.y` which references the export named `y` on the namespace, instead of being left as the identifier `y` which references the global named `y`. This matches how the TypeScript compiler treats namespace objects. This new behavior also works for enums:\n\n    ```ts\n    // Original TypeScript code\n    enum x {\n      y = 123\n    }\n    enum x {\n      z = y + 1\n    }\n\n    // Old JavaScript output\n    var x;\n    (function(x2) {\n      x2[x2[\"y\"] = 123] = \"y\";\n    })(x || (x = {}));\n    (function(x2) {\n      x2[x2[\"z\"] = y + 1] = \"z\";\n    })(x || (x = {}));\n\n    // New JavaScript output\n    var x;\n    (function(x2) {\n      x2[x2[\"y\"] = 123] = \"y\";\n    })(x || (x = {}));\n    (function(x2) {\n      x2[x2[\"z\"] = 124] = \"z\";\n    })(x || (x = {}));\n    ```\n\n    Note that this behavior does **not** work across files. Each file is still compiled independently so the namespaces in each file are still resolved independently per-file. Implicit namespace cross-references still do not work across files. Getting this to work is counter to esbuild's parallel architecture and does not fit in with esbuild's design. It also doesn't make sense with esbuild's bundling model where input files are either in ESM or CommonJS format and therefore each have their own scope.\n\n* Change output for top-level TypeScript enums\n\n    The output format for top-level TypeScript enums has been changed to reduce code size and improve tree shaking, which means that esbuild's enum output is now somewhat different than TypeScript's enum output. The behavior of both output formats should still be equivalent though. Here's an example that shows the difference:\n\n    ```ts\n    // Original code\n    enum x {\n      y = 1,\n      z = 2\n    }\n\n    // Old output\n    var x;\n    (function(x2) {\n      x2[x2[\"y\"] = 1] = \"y\";\n      x2[x2[\"z\"] = 2] = \"z\";\n    })(x || (x = {}));\n\n    // New output\n    var x = /* @__PURE__ */ ((x2) => {\n      x2[x2[\"y\"] = 1] = \"y\";\n      x2[x2[\"z\"] = 2] = \"z\";\n      return x2;\n    })(x || {});\n    ```\n\n    The function expression has been changed to an arrow expression to reduce code size and the enum initializer has been moved into the variable declaration to make it possible to be marked as `/* @__PURE__ */` to improve tree shaking. The `/* @__PURE__ */` annotation is now automatically added when all of the enum values are side-effect free, which means the entire enum definition can be removed as dead code if it's never referenced. Direct enum value references within the same file that have been inlined do not count as references to the enum definition so this should eliminate enums from the output in many cases:\n\n    ```ts\n    // Original code\n    enum Foo { FOO = 1 }\n    enum Bar { BAR = 2 }\n    console.log(Foo, Bar.BAR)\n\n    // Old output (with --bundle --minify)\n    var n;(function(e){e[e.FOO=1]=\"FOO\"})(n||(n={}));var l;(function(e){e[e.BAR=2]=\"BAR\"})(l||(l={}));console.log(n,2);\n\n    // New output (with --bundle --minify)\n    var n=(e=>(e[e.FOO=1]=\"FOO\",e))(n||{});console.log(n,2);\n    ```\n\n    Notice how the new output is much shorter because the entire definition for `Bar` has been completely removed as dead code by esbuild's tree shaking.\n\n    The output may seem strange since it would be simpler to just have a plain object literal as an initializer. However, TypeScript's enum feature behaves similarly to TypeScript's namespace feature which means enums can merge with existing enums and/or existing namespaces (and in some cases also existing objects) if the existing definition has the same name. This new output format keeps its similarity to the original output format so that it still handles all of the various edge cases that TypeScript's enum feature supports. Initializing the enum using a plain object literal would not merge with existing definitions and would break TypeScript's enum semantics.\n\n* Fix legal comment parsing in CSS ([#1796](https://github.com/evanw/esbuild/issues/1796))\n\n    Legal comments in CSS either start with `/*!` or contain `@preserve` or `@license` and are preserved by esbuild in the generated CSS output. This release fixes a bug where non-top-level legal comments inside a CSS file caused esbuild to skip any following legal comments even if those following comments are top-level:\n\n    ```css\n    /* Original code */\n    .example {\n      --some-var: var(--tw-empty, /*!*/ /*!*/);\n    }\n    /*! Some legal comment */\n    body {\n      background-color: red;\n    }\n\n    /* Old output (with --minify) */\n    .example{--some-var: var(--tw-empty, )}body{background-color:red}\n\n    /* New output (with --minify) */\n    .example{--some-var: var(--tw-empty, )}/*! Some legal comment */body{background-color:red}\n    ```\n\n* Fix panic when printing invalid CSS ([#1803](https://github.com/evanw/esbuild/issues/1803))\n\n    This release fixes a panic caused by a conditional CSS `@import` rule with a URL token. Code like this caused esbuild to enter an unexpected state because the case where tokens in the import condition with associated import records wasn't handled. This case is now handled correctly:\n\n    ```css\n    @import \"example.css\" url(foo);\n    ```\n\n* Mark `Set` and `Map` with array arguments as pure ([#1791](https://github.com/evanw/esbuild/issues/1791))\n\n    This release introduces special behavior for references to the global `Set` and `Map` constructors that marks them as `/* @__PURE__ */` if they are known to not have any side effects. These constructors evaluate the iterator of whatever is passed to them and the iterator could have side effects, so this is only safe if whatever is passed to them is an array, since the array iterator has no side effects.\n\n    Marking a constructor call as `/* @__PURE__ */` means it's safe to remove if the result is unused. This is an existing feature that you can trigger by manually adding a `/* @__PURE__ */` comment before a constructor call. The difference is that this release contains special behavior to automatically mark `Set` and `Map` as pure for you as long as it's safe to do so. As with all constructor calls that are marked `/* @__PURE__ */`, any internal expressions which could cause side effects are still preserved even though the constructor call itself is removed:\n\n    ```js\n    // Original code\n    new Map([\n      ['a', b()],\n      [c(), new Set(['d', e()])],\n    ]);\n\n    // Old output (with --minify)\n    new Map([[\"a\",b()],[c(),new Set([\"d\",e()])]]);\n\n    // New output (with --minify)\n    b(),c(),e();\n    ```\n\n## 0.13.15\n\n* Fix `super` in lowered `async` arrow functions ([#1777](https://github.com/evanw/esbuild/issues/1777))\n\n    This release fixes an edge case that was missed when lowering `async` arrow functions containing `super` property accesses for compile targets that don't support `async` such as with `--target=es6`. The problem was that lowering transforms `async` arrow functions into generator function expressions that are then passed to an esbuild helper function called `__async` that implements the `async` state machine behavior. Since function expressions do not capture `this` and `super` like arrow functions do, this led to a mismatch in behavior which meant that the transform was incorrect. The fix is to introduce a helper function to forward `super` access into the generator function expression body. Here's an example:\n\n    ```js\n    // Original code\n    class Foo extends Bar {\n      foo() { return async () => super.bar() }\n    }\n\n    // Old output (with --target=es6)\n    class Foo extends Bar {\n      foo() {\n        return () => __async(this, null, function* () {\n          return super.bar();\n        });\n      }\n    }\n\n    // New output (with --target=es6)\n    class Foo extends Bar {\n      foo() {\n        return () => {\n          var __superGet = (key) => super[key];\n          return __async(this, null, function* () {\n            return __superGet(\"bar\").call(this);\n          });\n        };\n      }\n    }\n    ```\n\n* Avoid merging certain CSS rules with different units ([#1732](https://github.com/evanw/esbuild/issues/1732))\n\n    This release no longer collapses `border-radius`, `margin`, `padding`, and `inset` rules when they have units with different levels of browser support. Collapsing multiple of these rules into a single rule is not equivalent if the browser supports one unit but not the other unit, since one rule would still have applied before the collapse but no longer applies after the collapse due to the whole rule being ignored. For example, Chrome 10 supports the `rem` unit but not the `vw` unit, so the CSS code below should render with rounded corners in Chrome 10. However, esbuild previously merged everything into a single rule which would cause Chrome 10 to ignore the rule and not round the corners. This issue is now fixed:\n\n    ```css\n    /* Original CSS */\n    div {\n      border-radius: 1rem;\n      border-top-left-radius: 1vw;\n      margin: 0;\n      margin-top: 1Q;\n      left: 10Q;\n      top: 20Q;\n      right: 10Q;\n      bottom: 20Q;\n    }\n\n    /* Old output (with --minify) */\n    div{border-radius:1vw 1rem 1rem;margin:1Q 0 0;inset:20Q 10Q}\n\n    /* New output (with --minify) */\n    div{border-radius:1rem;border-top-left-radius:1vw;margin:0;margin-top:1Q;inset:20Q 10Q}\n    ```\n\n    Notice how esbuild can still collapse rules together when they all share the same unit, even if the unit is one that doesn't have universal browser support such as the unit `Q`. One subtlety is that esbuild now distinguishes between \"safe\" and \"unsafe\" units where safe units are old enough that they are guaranteed to work in any browser a user might reasonably use, such as `px`. Safe units are allowed to be collapsed together even if there are multiple different units while multiple different unsafe units are not allowed to be collapsed together. Another detail is that esbuild no longer minifies zero lengths by removing the unit if the unit is unsafe (e.g. `0rem` into `0`) since that could cause a rendering difference if a previously-ignored rule is now no longer ignored due to the unit change. If you are curious, you can learn more about browser support levels for different CSS units in [Mozilla's documentation about CSS length units](https://developer.mozilla.org/en-US/docs/Web/CSS/length).\n\n* Avoid warning about ignored side-effect free imports for empty files ([#1785](https://github.com/evanw/esbuild/issues/1785))\n\n    When bundling, esbuild warns about bare imports such as `import \"lodash-es\"` when the package has been marked as `\"sideEffects\": false` in its `package.json` file. This is because the only reason to use a bare import is because you are relying on the side effects of the import, but imports for packages marked as side-effect free are supposed to be removed. If the package indicates that it has no side effects, then this bare import is likely a bug.\n\n    However, some people have packages just for TypeScript type definitions. These package can actually have a side effect as they can augment the type of the global object in TypeScript, even if they are marked with `\"sideEffects\": false`. To avoid warning in this case, esbuild will now only issue this warning if the imported file is non-empty. If the file is empty, then it's irrelevant whether you import it or not so any import of that file does not indicate a bug. This fixes this case because `.d.ts` files typically end up being empty after esbuild parses them since they typically only contain type declarations.\n\n* Attempt to fix packages broken due to the `node:` prefix ([#1760](https://github.com/evanw/esbuild/issues/1760))\n\n    Some people have started using the node-specific `node:` path prefix in their packages. This prefix forces the following path to be interpreted as a node built-in module instead of a package on the file system. So `require(\"node:path\")` will always import [node's `path` module](https://nodejs.org/api/path.html) and never import [npm's `path` package](https://www.npmjs.com/package/path).\n\n    Adding the `node:` prefix breaks that code with older node versions that don't understand the `node:` prefix. This is a problem with the package, not with esbuild. The package should be adding a fallback if the `node:` prefix isn't available. However, people still want to be able to use these packages with older node versions even though the code is broken. Now esbuild will automatically strip this prefix if it detects that the code will break in the configured target environment (as specified by `--target=`). Note that this only happens during bundling, since import paths are only examined during bundling.\n\n## 0.13.14\n\n* Fix dynamic `import()` on node 12.20+ ([#1772](https://github.com/evanw/esbuild/issues/1772))\n\n    When you use flags such as `--target=node12.20`, esbuild uses that version number to see what features the target environment supports. This consults an internal table that stores which target environments are supported for each feature. For example, `import(x)` is changed into `Promise.resolve().then(() => require(x))` if dynamic `import` expressions are unsupported.\n\n    Previously esbuild's internal table only stored one version number, since features are rarely ever removed in newer versions of software. Either the target environment is before that version and the feature is unsupported, or the target environment is after that version and the feature is supported. This approach has work for all relevant features in all cases except for one: dynamic `import` support in node. This feature is supported in node 12.20.0 up to but not including node 13.0.0, and then is also supported in node 13.2.0 up. The feature table implementation has been changed to store an array of potentially discontiguous version ranges instead of one version number.\n\n    Up until now, esbuild used 13.2.0 as the lowest supported version number to avoid generating dynamic `import` expressions when targeting node versions that don't support it. But with this release, esbuild will now use the more accurate discontiguous version range in this case. This means dynamic `import` expressions can now be generated when targeting versions of node 12.20.0 up to but not including node 13.0.0.\n\n* Avoid merging certain qualified rules in CSS ([#1776](https://github.com/evanw/esbuild/issues/1776))\n\n    A change was introduced in the previous release to merge adjacent CSS rules that have the same content:\n\n    ```css\n    /* Original code */\n    a { color: red }\n    b { color: red }\n\n    /* Minified output */\n    a,b{color:red}\n    ```\n\n    However, that introduced a regression in cases where the browser considers one selector to be valid and the other selector to be invalid, such as in the following example:\n\n    ```css\n    /* This rule is valid, and is applied */\n    a { color: red }\n\n    /* This rule is invalid, and is ignored */\n    b:-x-invalid { color: red }\n    ```\n\n    Merging these two rules into one causes the browser to consider the entire merged rule to be invalid, which disables both rules. This is a change in behavior from the original code.\n\n    With this release, esbuild will now only merge adjacent duplicate rules together if they are known to work in all browsers (specifically, if they are known to work in IE 7 and up). Adjacent duplicate rules will no longer be merged in all other cases including modern pseudo-class selectors such as `:focus`, HTML5 elements such as `video`, and combinators such as `a + b`.\n\n* Minify syntax in the CSS `font`, `font-family`, and `font-weight` properties ([#1756](https://github.com/evanw/esbuild/pull/1756))\n\n    This release includes size reductions for CSS font syntax when minification is enabled:\n\n    ```css\n    /* Original code */\n    div {\n      font: bold 1rem / 1.2 \"Segoe UI\", sans-serif, \"Segoe UI Emoji\";\n    }\n\n    /* Output with \"--minify\" */\n    div{font:700 1rem/1.2 Segoe UI,sans-serif,\"Segoe UI Emoji\"}\n    ```\n\n    Notice how `bold` has been changed to `700` and the quotes were removed around `\"Segoe UI\"` since it was safe to do so.\n\n    This feature was contributed by [@sapphi-red](https://github.com/sapphi-red).\n\n## 0.13.13\n\n* Add more information about skipping `\"main\"` in `package.json` ([#1754](https://github.com/evanw/esbuild/issues/1754))\n\n    Configuring `mainFields: []` breaks most npm packages since it tells esbuild to ignore the `\"main\"` field in `package.json`, which most npm packages use to specify their entry point. This is not a bug with esbuild because esbuild is just doing what it was told to do. However, people may do this without understanding how npm packages work, and then be confused about why it doesn't work. This release now includes additional information in the error message:\n\n    ```\n     > foo.js:1:27: error: Could not resolve \"events\" (use \"--platform=node\" when building for node)\n         1 │ var EventEmitter = require('events')\n           ╵                            ~~~~~~~~\n       node_modules/events/package.json:20:2: note: The \"main\" field was ignored because the list of main fields to use is currently set to []\n        20 │   \"main\": \"./events.js\",\n           ╵   ~~~~~~\n    ```\n\n* Fix a tree-shaking bug with `var exports` ([#1739](https://github.com/evanw/esbuild/issues/1739))\n\n    This release fixes a bug where a variable named `var exports = {}` was incorrectly removed by tree-shaking (i.e. dead code elimination). The `exports` variable is a special variable in CommonJS modules that is automatically provided by the CommonJS runtime. CommonJS modules are transformed into something like this before being run:\n\n    ```js\n    function(exports, module, require) {\n      var exports = {}\n    }\n    ```\n\n    So using `var exports = {}` should have the same effect as `exports = {}` because the variable `exports` should already be defined. However, esbuild was incorrectly overwriting the definition of the `exports` variable with the one provided by CommonJS. This release merges the definitions together so both are included, which fixes the bug.\n\n* Merge adjacent CSS selector rules with duplicate content ([#1755](https://github.com/evanw/esbuild/issues/1755))\n\n    With this release, esbuild will now merge adjacent selectors when minifying if they have the same content:\n\n    ```css\n    /* Original code */\n    a { color: red }\n    b { color: red }\n\n    /* Old output (with --minify) */\n    a{color:red}b{color:red}\n\n    /* New output (with --minify) */\n    a,b{color:red}\n    ```\n\n* Shorten `top`, `right`, `bottom`, `left` CSS property into `inset` when it is supported ([#1758](https://github.com/evanw/esbuild/pull/1758))\n\n    This release enables collapsing of `inset` related properties:\n\n    ```css\n    /* Original code */\n    div {\n      top: 0;\n      right: 0;\n      bottom: 0;\n      left: 0;\n    }\n\n    /* Output with \"--minify-syntax\" */\n    div {\n      inset: 0;\n    }\n    ```\n\n    This minification rule is only enabled when `inset` property is supported by the target environment. Make sure to set esbuild's `target` setting correctly when minifying if the code will be running in an older environment (e.g. earlier than Chrome 87).\n\n    This feature was contributed by [@sapphi-red](https://github.com/sapphi-red).\n\n## 0.13.12\n\n* Implement initial support for simplifying `calc()` expressions in CSS ([#1607](https://github.com/evanw/esbuild/issues/1607))\n\n    This release includes basic simplification of `calc()` expressions in CSS when minification is enabled. The approach mainly follows the official CSS specification, which means it should behave the way browsers behave: https://www.w3.org/TR/css-values-4/#calc-func. This is a basic implementation so there are probably some `calc()` expressions that can be reduced by other tools but not by esbuild. This release mainly focuses on setting up the parsing infrastructure for `calc()` expressions to make it straightforward to implement additional simplifications in the future. Here's an example of this new functionality:\n\n    ```css\n    /* Input CSS */\n    div {\n      width: calc(60px * 4 - 5px * 2);\n      height: calc(100% / 4);\n    }\n\n    /* Output CSS (with --minify-syntax) */\n    div {\n      width: 230px;\n      height: 25%;\n    }\n    ```\n\n    Expressions that can't be fully simplified will still be partially simplified into a reduced `calc()` expression:\n\n    ```css\n    /* Input CSS */\n    div {\n      width: calc(100% / 5 - 2 * 1em - 2 * 1px);\n    }\n\n    /* Output CSS (with --minify-syntax) */\n    div {\n      width: calc(20% - 2em - 2px);\n    }\n    ```\n\n    Note that this transformation doesn't attempt to modify any expression containing a `var()` CSS variable reference. These variable references can contain any number of tokens so it's not safe to move forward with a simplification assuming that `var()` is a single token. For example, `calc(2px * var(--x) * 3)` is not transformed into `calc(6px * var(--x))` in case `var(--x)` contains something like `4 + 5px` (`calc(2px * 4 + 5px * 3)` evaluates to `23px` while `calc(6px * 4 + 5px)` evaluates to `29px`).\n\n* Fix a crash with a legal comment followed by an import ([#1730](https://github.com/evanw/esbuild/issues/1730))\n\n    Version 0.13.10 introduced parsing for CSS legal comments but caused a regression in the code that checks whether there are any rules that come before `@import`. This is not desired because browsers ignore `@import` rules after other non-`@import` rules, so esbuild warns you when you do this. However, legal comments are modeled as rules in esbuild's internal AST even though they aren't actual CSS rules, and the code that performs this check wasn't updated. This release fixes the crash.\n\n## 0.13.11\n\n* Implement class static blocks ([#1558](https://github.com/evanw/esbuild/issues/1558))\n\n    This release adds support for a new upcoming JavaScript feature called [class static blocks](https://github.com/tc39/proposal-class-static-block) that lets you evaluate code inside of a class body. It looks like this:\n\n    ```js\n    class Foo {\n      static {\n        this.foo = 123\n      }\n    }\n    ```\n\n    This can be useful when you want to use `try`/`catch` or access private `#name` fields during class initialization. Doing that without this feature is quite hacky and basically involves creating temporary static fields containing immediately-invoked functions and then deleting the fields after class initialization. Static blocks are much more ergonomic and avoid performance loss due to `delete` changing the object shape.\n\n    Static blocks are transformed for older browsers by moving the static block outside of the class body and into an immediately invoked arrow function after the class definition:\n\n    ```js\n    // The transformed version of the example code above\n    const _Foo = class {\n    };\n    let Foo = _Foo;\n    (() => {\n      _Foo.foo = 123;\n    })();\n    ```\n\n    In case you're wondering, the additional `let` variable is to guard against the potential reassignment of `Foo` during evaluation such as what happens below. The value of `this` must be bound to the original class, not to the current value of `Foo`:\n\n    ```js\n    let bar\n    class Foo {\n      static {\n        bar = () => this\n      }\n    }\n    Foo = null\n    console.log(bar()) // This should not be \"null\"\n    ```\n\n* Fix issues with `super` property accesses\n\n    Code containing `super` property accesses may need to be transformed even when they are supported. For example, in ES6 `async` methods are unsupported while `super` properties are supported. An `async` method containing `super` property accesses requires those uses of `super` to be transformed (the `async` function is transformed into a nested generator function and the `super` keyword cannot be used inside nested functions).\n\n    Previously esbuild transformed `super` property accesses into a function call that returned the corresponding property. However, this was incorrect for uses of `super` that write to the inherited setter since a function call is not a valid assignment target. This release fixes writing to a `super` property:\n\n    ```js\n    // Original code\n    class Base {\n      set foo(x) { console.log('set foo to', x) }\n    }\n    class Derived extends Base {\n      async bar() { super.foo = 123 }\n    }\n    new Derived().bar()\n\n    // Old output with --target=es6 (contains a syntax error)\n    class Base {\n      set foo(x) {\n        console.log(\"set foo to\", x);\n      }\n    }\n    class Derived extends Base {\n      bar() {\n        var __super = (key) => super[key];\n        return __async(this, null, function* () {\n          __super(\"foo\") = 123;\n        });\n      }\n    }\n    new Derived().bar();\n\n    // New output with --target=es6 (works correctly)\n    class Base {\n      set foo(x) {\n        console.log(\"set foo to\", x);\n      }\n    }\n    class Derived extends Base {\n      bar() {\n        var __superSet = (key, value) => super[key] = value;\n        return __async(this, null, function* () {\n          __superSet(\"foo\", 123);\n        });\n      }\n    }\n    new Derived().bar();\n    ```\n\n    All known edge cases for assignment to a `super` property should now be covered including destructuring assignment and using the unary assignment operators with BigInts.\n\n    In addition, this release also fixes a bug where a `static` class field containing a `super` property access was not transformed when it was moved outside of the class body, which can happen when `static` class fields aren't supported.\n\n    ```js\n    // Original code\n    class Base {\n      static get foo() {\n        return 123\n      }\n    }\n    class Derived extends Base {\n      static bar = super.foo\n    }\n\n    // Old output with --target=es6 (contains a syntax error)\n    class Base {\n      static get foo() {\n        return 123;\n      }\n    }\n    class Derived extends Base {\n    }\n    __publicField(Derived, \"bar\", super.foo);\n\n    // New output with --target=es6 (works correctly)\n    class Base {\n      static get foo() {\n        return 123;\n      }\n    }\n    const _Derived = class extends Base {\n    };\n    let Derived = _Derived;\n    __publicField(Derived, \"bar\", __superStaticGet(_Derived, \"foo\"));\n    ```\n\n    All known edge cases for `super` inside `static` class fields should be handled including accessing `super` after prototype reassignment of the enclosing class object.\n\n## 0.13.10\n\n* Implement legal comment preservation for CSS ([#1539](https://github.com/evanw/esbuild/issues/1539))\n\n    This release adds support for legal comments in CSS the same way they are already supported for JS. A legal comment is one that starts with `/*!` or that contains the text `@license` or `@preserve`. These comments are preserved in output files by esbuild since that follows the intent of the original authors of the code. The specific behavior is controlled via `--legal-comments=` in the CLI and `legalComments` in the JS API, which can be set to any of the following options:\n\n    * `none`: Do not preserve any legal comments\n    * `inline`: Preserve all rule-level legal comments\n    * `eof`: Move all rule-level legal comments to the end of the file\n    * `linked`: Move all rule-level legal comments to a `.LEGAL.txt` file and link to them with a comment\n    * `external`: Move all rule-level legal comments to a `.LEGAL.txt` file but to not link to them\n\n    The default behavior is `eof` when bundling and `inline` otherwise.\n\n* Allow uppercase `es*` targets ([#1717](https://github.com/evanw/esbuild/issues/1717))\n\n    With this release, you can now use target names such as `ESNext` instead of `esnext` as the target name in the CLI and JS API. This is important because people don't want to have to call `.toLowerCase()` on target strings from TypeScript's `tsconfig.json` file before passing it to esbuild (TypeScript uses case-agnostic target names).\n\n    This feature was contributed by [@timse](https://github.com/timse).\n\n* Update to Unicode 14.0.0\n\n    The character tables that determine which characters form valid JavaScript identifiers have been updated from Unicode version 13.0.0 to the newly-released Unicode version 14.0.0. I'm not putting an example in the release notes because all of the new characters will likely just show up as little squares since fonts haven't been updated yet. But you can read https://www.unicode.org/versions/Unicode14.0.0/#Summary for more information about the changes.\n\n## 0.13.9\n\n* Add support for `imports` in `package.json` ([#1691](https://github.com/evanw/esbuild/issues/1691))\n\n    This release adds basic support for the `imports` field in `package.json`. It behaves similarly to the `exports` field but only applies to import paths that start with `#`. The `imports` field provides a way for a package to remap its own internal imports for itself, while the `exports` field provides a way for a package to remap its external exports for other packages. This is useful because the `imports` field respects the currently-configured conditions which means that the import mapping can change at run-time. For example:\n\n    ```\n    $ cat entry.mjs\n    import '#example'\n\n    $ cat package.json\n    {\n      \"imports\": {\n        \"#example\": {\n          \"foo\": \"./example.foo.mjs\",\n          \"default\": \"./example.mjs\"\n        }\n      }\n    }\n\n    $ cat example.foo.mjs\n    console.log('foo is enabled')\n\n    $ cat example.mjs\n    console.log('foo is disabled')\n\n    $ node entry.mjs\n    foo is disabled\n\n    $ node --conditions=foo entry.mjs\n    foo is enabled\n    ```\n\n    Now that esbuild supports this feature too, import paths starting with `#` and any provided conditions will be respected when bundling:\n\n    ```\n    $ esbuild --bundle entry.mjs | node\n    foo is disabled\n\n    $ esbuild --conditions=foo --bundle entry.mjs | node\n    foo is enabled\n    ```\n\n* Fix using `npm rebuild` with the `esbuild` package ([#1703](https://github.com/evanw/esbuild/issues/1703))\n\n    Version 0.13.4 accidentally introduced a regression in the install script where running `npm rebuild` multiple times could fail after the second time. The install script creates a copy of the binary executable using [`link`](https://man7.org/linux/man-pages/man2/link.2.html) followed by [`rename`](https://www.man7.org/linux/man-pages/man2/rename.2.html). Using `link` creates a hard link which saves space on the file system, and `rename` is used for safety since it atomically replaces the destination.\n\n    However, the `rename` syscall has an edge case where it silently fails if the source and destination are both the same link. This meant that the install script would fail after being run twice in a row. With this release, the install script now deletes the source after calling `rename` in case it has silently failed, so this issue should now be fixed. It should now be safe to use `npm rebuild` with the `esbuild` package.\n\n* Fix invalid CSS minification of `border-radius` ([#1702](https://github.com/evanw/esbuild/issues/1702))\n\n    CSS minification does collapsing of `border-radius` related properties. For example:\n\n    ```css\n    /* Original CSS */\n    div {\n      border-radius: 1px;\n      border-top-left-radius: 5px;\n    }\n\n    /* Minified CSS */\n    div{border-radius:5px 1px 1px}\n    ```\n\n    However, this only works for numeric tokens, not identifiers. For example:\n\n    ```css\n    /* Original CSS */\n    div {\n      border-radius: 1px;\n      border-top-left-radius: inherit;\n    }\n\n    /* Minified CSS */\n    div{border-radius:1px;border-top-left-radius:inherit}\n    ```\n\n    Transforming this to `div{border-radius:inherit 1px 1px}`, as was done in previous releases of esbuild, is an invalid transformation and results in incorrect CSS. This release of esbuild fixes this CSS transformation bug.\n\n## 0.13.8\n\n* Fix `super` inside arrow function inside lowered `async` function ([#1425](https://github.com/evanw/esbuild/issues/1425))\n\n    When an `async` function is transformed into a regular function for target environments that don't support `async` such as `--target=es6`, references to `super` inside that function must be transformed too since the `async`-to-regular function transformation moves the function body into a nested function, so the `super` references are no longer syntactically valid. However, this transform didn't handle an edge case and `super` references inside of an arrow function were overlooked. This release fixes this bug:\n\n    ```js\n    // Original code\n    class Foo extends Bar {\n      async foo() {\n        return () => super.foo()\n      }\n    }\n\n    // Old output (with --target=es6)\n    class Foo extends Bar {\n      foo() {\n        return __async(this, null, function* () {\n          return () => super.foo();\n        });\n      }\n    }\n\n    // New output (with --target=es6)\n    class Foo extends Bar {\n      foo() {\n        var __super = (key) => super[key];\n        return __async(this, null, function* () {\n          return () => __super(\"foo\").call(this);\n        });\n      }\n    }\n    ```\n\n* Remove the implicit `/` after `[dir]` in entry names ([#1661](https://github.com/evanw/esbuild/issues/1661))\n\n    The \"entry names\" feature lets you customize the way output file names are generated. The `[dir]` and `[name]` placeholders are filled in with the directory name and file name of the corresponding entry point file, respectively.\n\n    Previously `--entry-names=[dir]/[name]` and `--entry-names=[dir][name]` behaved the same because the value used for `[dir]` always had an implicit trailing slash, since it represents a directory. However, some people want to be able to remove the file name with `--entry-names=[dir]` and the implicit trailing slash gets in the way.\n\n    With this release, you can now use the `[dir]` placeholder without an implicit trailing slash getting in the way. For example, the command `esbuild foo/bar/index.js --outbase=. --outdir=out --entry-names=[dir]` previously generated the file `out/foo/bar/.js` but will now generate the file `out/foo/bar.js`.\n\n## 0.13.7\n\n* Minify CSS alpha values correctly ([#1682](https://github.com/evanw/esbuild/issues/1682))\n\n    When esbuild uses the `rgba()` syntax for a color instead of the 8-character hex code (e.g. when `target` is set to Chrome 61 or earlier), the 0-to-255 integer alpha value must be printed as a floating-point fraction between 0 and 1. The fraction was only printed to three decimal places since that is the minimal number of decimal places required for all 256 different alpha values to be uniquely determined. However, using three decimal places does not necessarily result in the shortest result. For example, `128 / 255` is `0.5019607843137255` which is printed as `\".502\"` using three decimal places, but `\".5\"` is equivalent because `round(0.5 * 255) == 128`, so printing `\".5\"` would be better. With this release, esbuild will always use the minimal numeric representation for the alpha value:\n\n    ```css\n    /* Original code */\n    a { color: #FF800080 }\n\n    /* Old output (with --minify --target=chrome61) */\n    a{color:rgba(255,128,0,.502)}\n\n    /* New output (with --minify --target=chrome61) */\n    a{color:rgba(255,128,0,.5)}\n    ```\n\n* Match node's behavior for core module detection ([#1680](https://github.com/evanw/esbuild/issues/1680))\n\n    Node has a hard-coded list of core modules (e.g. `fs`) that, when required, short-circuit the module resolution algorithm and instead return the corresponding internal core module object. When you pass `--platform=node` to esbuild, esbuild also implements this short-circuiting behavior and doesn't try to bundle these import paths. This was implemented in esbuild using the existing `external` feature (e.g. essentially `--external:fs`). However, there is an edge case where esbuild's `external` feature behaved differently than node.\n\n    Modules specified via esbuild's `external` feature also cause all sub-paths to be excluded as well, so for example `--external:foo` excludes both `foo` and `foo/bar` from the bundle. However, node's core module check is only an exact equality check, so for example `fs` is a core module and bypasses the module resolution algorithm but `fs/foo` is not a core module and causes the module resolution algorithm to search the file system.\n\n    This behavior can be used to load a module on the file system with the same name as one of node's core modules. For example, `require('fs/')` will load the module `fs` from the file system instead of loading node's core `fs` module. With this release, esbuild will now match node's behavior in this edge case. This means the external modules that are automatically added by `--platform=node` now behave subtly differently than `--external:`, which allows code that relies on this behavior to be bundled correctly.\n\n* Fix WebAssembly builds on Go 1.17.2+ ([#1684](https://github.com/evanw/esbuild/pull/1684))\n\n    Go 1.17.2 introduces a change (specifically a [fix for CVE-2021-38297](https://go-review.googlesource.com/c/go/+/354591/)) that causes Go's WebAssembly bootstrap script to throw an error when it's run in situations with many environment variables. One such situation is when the bootstrap script is run inside [GitHub Actions](https://github.com/features/actions). This change was introduced because the bootstrap script writes a copy of the environment variables into WebAssembly memory without any bounds checking, and writing more than 4096 bytes of data ends up writing past the end of the buffer and overwriting who-knows-what. So throwing an error in this situation is an improvement. However, this breaks esbuild which previously (at least seemingly) worked fine.\n\n    With this release, esbuild's WebAssembly bootstrap script that calls out to Go's WebAssembly bootstrap script will now delete all environment variables except for the ones that esbuild checks for, of which there are currently only four: `NO_COLOR`, `NODE_PATH`, `npm_config_user_agent`, and `WT_SESSION`. This should avoid a crash when esbuild is built using Go 1.17.2+ and should reduce the likelihood of memory corruption when esbuild is built using Go 1.17.1 or earlier. This release also updates the Go version that esbuild ships with to version 1.17.2. Note that this problem only affects the `esbuild-wasm` package. The `esbuild` package is not affected.\n\n    See also:\n\n    * https://github.com/golang/go/issues/48797\n    * https://github.com/golang/go/issues/49011\n\n## 0.13.6\n\n* Emit decorators for `declare` class fields ([#1675](https://github.com/evanw/esbuild/issues/1675))\n\n    In version 3.7, TypeScript introduced the `declare` keyword for class fields that avoids generating any code for that field:\n\n    ```ts\n    // TypeScript input\n    class Foo {\n      a: number\n      declare b: number\n    }\n\n    // JavaScript output\n    class Foo {\n      a;\n    }\n    ```\n\n    However, it turns out that TypeScript still emits decorators for these omitted fields. With this release, esbuild will now do this too:\n\n    ```ts\n    // TypeScript input\n    class Foo {\n      @decorator a: number;\n      @decorator declare b: number;\n    }\n\n    // Old JavaScript output\n    class Foo {\n      a;\n    }\n    __decorateClass([\n      decorator\n    ], Foo.prototype, \"a\", 2);\n\n    // New JavaScript output\n    class Foo {\n      a;\n    }\n    __decorateClass([\n      decorator\n    ], Foo.prototype, \"a\", 2);\n    __decorateClass([\n      decorator\n    ], Foo.prototype, \"b\", 2);\n    ```\n\n* Experimental support for esbuild on NetBSD ([#1624](https://github.com/evanw/esbuild/pull/1624))\n\n    With this release, esbuild now has a published binary executable for [NetBSD](https://www.netbsd.org/) in the [`esbuild-netbsd-64`](https://www.npmjs.com/package/esbuild-netbsd-64) npm package, and esbuild's installer has been modified to attempt to use it when on NetBSD. Hopefully this makes installing esbuild via npm work on NetBSD. This change was contributed by [@gdt](https://github.com/gdt).\n\n    ⚠️ Note: NetBSD is not one of [Node's supported platforms](https://nodejs.org/api/process.html#process_process_platform), so installing esbuild may or may not work on NetBSD depending on how Node has been patched. This is not a problem with esbuild. ⚠️\n\n* Disable the \"esbuild was bundled\" warning if `ESBUILD_BINARY_PATH` is provided ([#1678](https://github.com/evanw/esbuild/pull/1678))\n\n    The `ESBUILD_BINARY_PATH` environment variable allows you to substitute an alternate binary executable for esbuild's JavaScript API. This is useful in certain cases such as when debugging esbuild. The JavaScript API has some code that throws an error if it detects that it was bundled before being run, since bundling prevents esbuild from being able to find the path to its binary executable. However, that error is unnecessary if `ESBUILD_BINARY_PATH` is present because an alternate path has been provided. This release disables the warning when `ESBUILD_BINARY_PATH` is present so that esbuild can be used when bundled as long as you also manually specify `ESBUILD_BINARY_PATH`.\n\n    This change was contributed by [@heypiotr](https://github.com/heypiotr).\n\n* Remove unused `catch` bindings when minifying ([#1660](https://github.com/evanw/esbuild/pull/1660))\n\n    With this release, esbuild will now remove unused `catch` bindings when minifying:\n\n    ```js\n    // Original code\n    try {\n      throw 0;\n    } catch (e) {\n    }\n\n    // Old output (with --minify)\n    try{throw 0}catch(t){}\n\n    // New output (with --minify)\n    try{throw 0}catch{}\n    ```\n\n    This takes advantage of the new [optional catch binding](https://github.com/tc39/proposal-optional-catch-binding) syntax feature that was introduced in ES2019. This minification rule is only enabled when optional catch bindings are supported by the target environment. Specifically, it's not enabled when using `--target=es2018` or older. Make sure to set esbuild's `target` setting correctly when minifying if the code will be running in an older JavaScript environment.\n\n    This change was contributed by [@sapphi-red](https://github.com/sapphi-red).\n\n## 0.13.5\n\n* Improve watch mode accuracy ([#1113](https://github.com/evanw/esbuild/issues/1113))\n\n    Watch mode is enabled by `--watch` and causes esbuild to become a long-running process that automatically rebuilds output files when input files are changed. It's implemented by recording all calls to esbuild's internal file system interface and then invalidating the build whenever these calls would return different values. For example, a call to esbuild's internal `ReadFile()` function is considered to be different if either the presence of the file has changed (e.g. the file didn't exist before but now exists) or the presence of the file stayed the same but the content of the file has changed.\n\n    Previously esbuild's watch mode operated at the `ReadFile()` and `ReadDirectory()` level. When esbuild checked whether a directory entry existed or not (e.g. whether a directory contains a `node_modules` subdirectory or a `package.json` file), it called `ReadDirectory()` which then caused the build to depend on that directory's set of entries. This meant the build would be invalidated even if a new unrelated entry was added or removed, since that still changes the set of entries. This is problematic when using esbuild in environments that constantly create and destroy temporary directory entries in your project directory. In that case, esbuild's watch mode would constantly rebuild as the directory was constantly considered to be dirty.\n\n    With this release, watch mode now operates at the `ReadFile()` and `ReadDirectory().Get()` level. So when esbuild checks whether a directory entry exists or not, the build should now only depend on the presence status for that one directory entry. This should avoid unnecessary rebuilds due to unrelated directory entries being added or removed. The log messages generated using `--watch` will now also mention the specific directory entry whose presence status was changed if a build is invalidated for this reason.\n\n    Note that this optimization does not apply to plugins using the `watchDirs` return value because those paths are only specified at the directory level and do not describe individual directory entries. You can use `watchFiles` or `watchDirs` on the individual entries inside the directory to get a similar effect instead.\n\n* Disallow certain uses of `<` in `.mts` and `.cts` files\n\n    The upcoming version 4.5 of TypeScript is introducing the `.mts` and `.cts` extensions that turn into the `.mjs` and `.cjs` extensions when compiled. However, unlike the existing `.ts` and `.tsx` extensions, expressions that start with `<` are disallowed when they would be ambiguous depending on whether they are parsed in `.ts` or `.tsx` mode. The ambiguity is caused by the overlap between the syntax for JSX elements and the old deprecated syntax for type casts:\n\n    | Syntax                        | `.ts`                | `.tsx`           | `.mts`/`.cts`        |\n    |-------------------------------|----------------------|------------------|----------------------|\n    | `<x>y`                        | ✅ Type cast         | 🚫 Syntax error   | 🚫 Syntax error      |\n    | `<T>() => {}`                 | ✅ Arrow function    | 🚫 Syntax error   | 🚫 Syntax error      |\n    | `<x>y</x>`                    | 🚫 Syntax error      | ✅ JSX element    | 🚫 Syntax error      |\n    | `<T>() => {}</T>`             | 🚫 Syntax error      | ✅ JSX element    | 🚫 Syntax error      |\n    | `<T extends>() => {}</T>`     | 🚫 Syntax error      | ✅ JSX element    | 🚫 Syntax error      |\n    | `<T extends={0}>() => {}</T>` | 🚫 Syntax error      | ✅ JSX element    | 🚫 Syntax error      |\n    | `<T,>() => {}`                | ✅ Arrow function    | ✅ Arrow function | ✅ Arrow function    |\n    | `<T extends X>() => {}`       | ✅ Arrow function    | ✅ Arrow function | ✅ Arrow function    |\n\n    This release of esbuild introduces a syntax error for these ambiguous syntax constructs in `.mts` and `.cts` files to match the new behavior of the TypeScript compiler.\n\n* Do not remove empty `@keyframes` rules ([#1665](https://github.com/evanw/esbuild/issues/1665))\n\n    CSS minification in esbuild automatically removes empty CSS rules, since they have no effect. However, empty `@keyframes` rules still trigger JavaScript animation events so it's incorrect to remove them. To demonstrate that empty `@keyframes` rules still have an effect, here is a bug report for Firefox where it was incorrectly not triggering JavaScript animation events for empty `@keyframes` rules: https://bugzilla.mozilla.org/show_bug.cgi?id=1004377.\n\n    With this release, empty `@keyframes` rules are now preserved during minification:\n\n    ```css\n    /* Original CSS */\n    @keyframes foo {\n      from {}\n      to {}\n    }\n\n    /* Old output (with --minify) */\n\n    /* New output (with --minify) */\n    @keyframes foo{}\n    ```\n\n    This fix was contributed by [@eelco](https://github.com/eelco).\n\n* Fix an incorrect duplicate label error ([#1671](https://github.com/evanw/esbuild/pull/1671))\n\n    When labeling a statement in JavaScript, the label must be unique within the enclosing statements since the label determines the jump target of any labeled `break` or `continue` statement:\n\n    ```js\n    // This code is valid\n    x: y: z: break x;\n\n    // This code is invalid\n    x: y: x: break x;\n    ```\n\n    However, an enclosing label with the same name *is* allowed as long as it's located in a different function body. Since `break` and `continue` statements can't jump across function boundaries, the label is not ambiguous. This release fixes a bug where esbuild incorrectly treated this valid code as a syntax error:\n\n    ```js\n    // This code is valid, but was incorrectly considered a syntax error\n    x: (() => {\n      x: break x;\n    })();\n    ```\n\n    This fix was contributed by [@nevkontakte](https://github.com/nevkontakte).\n\n## 0.13.4\n\n* Fix permission issues with the install script ([#1642](https://github.com/evanw/esbuild/issues/1642))\n\n    The `esbuild` package contains a small JavaScript stub file that implements the CLI (command-line interface). Its only purpose is to spawn the binary esbuild executable as a child process and forward the command-line arguments to it.\n\n    The install script contains an optimization that replaces this small JavaScript stub with the actual binary executable at install time to avoid the overhead of unnecessarily creating a new `node` process. This optimization can't be done at package publish time because there is only one `esbuild` package but there are many supported platforms, so the binary executable for the current platform must live outside of the `esbuild` package.\n\n    However, the optimization was implemented with an [unlink](https://www.man7.org/linux/man-pages/man2/unlink.2.html) operation followed by a [link](https://www.man7.org/linux/man-pages/man2/link.2.html) operation. This means that if the first step fails, the package is left in a broken state since the JavaScript stub file is deleted but not yet replaced.\n\n    With this release, the optimization is now implemented with a [link](https://www.man7.org/linux/man-pages/man2/link.2.html) operation followed by a [rename](https://www.man7.org/linux/man-pages/man2/rename.2.html) operation. This should always leave the package in a working state even if either step fails.\n\n* Add a fallback for `npm install esbuild --no-optional` ([#1647](https://github.com/evanw/esbuild/issues/1647))\n\n    The installation method for esbuild's platform-specific binary executable was recently changed in version 0.13.0. Before that version esbuild downloaded it in an install script, and after that version esbuild lets the package manager download it using the `optionalDependencies` feature in `package.json`. This change was made because downloading the binary executable in an install script never really fully worked. The reasons are complex but basically there are a variety of edge cases where people people want to install esbuild in environments that they have customized such that downloading esbuild isn't possible. Using `optionalDependencies` instead lets the package manager deal with it instead, which should work fine in all cases (either that or your package manager has a bug, but that's not esbuild's problem).\n\n    There is one case where this new installation method doesn't work: if you pass the `--no-optional` flag to npm to disable the `optionalDependencies` feature. If you do this, you prevent esbuild from being installed. This is not a problem with esbuild because you are manually enabling a flag to change npm's behavior such that esbuild doesn't install correctly. However, people still want to do this.\n\n    With this release, esbuild will now fall back to the old installation method if the new installation method fails. **THIS MAY NOT WORK.** The new `optionalDependencies` installation method is the only supported way to install esbuild with npm. The old downloading installation method was removed because it doesn't always work. The downloading method is only being provided to try to be helpful but it's not the supported installation method. If you pass `--no-optional` and the download fails due to some environment customization you did, the recommended fix is to just remove the `--no-optional` flag.\n\n* Support the new `.mts` and `.cts` TypeScript file extensions\n\n    The upcoming version 4.5 of TypeScript has two new file extensions: `.mts` and `.cts`. Files with these extensions can be imported using the `.mjs` and `.cjs`, respectively. So the statement `import \"./foo.mjs\"` in TypeScript can actually succeed even if the file `./foo.mjs` doesn't exist on the file system as long as the file `./foo.mts` does exist. The import path with the `.mjs` extension is automatically re-routed to the corresponding file with the `.mts` extension at type-checking time by the TypeScript compiler. See [the TypeScript 4.5 beta announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-5-beta/#new-file-extensions) for details.\n\n    With this release, esbuild will also automatically rewrite `.mjs` to `.mts` and `.cjs` to `.cts` when resolving import paths to files on the file system. This should make it possible to bundle code written in this new style. In addition, the extensions `.mts` and `.cts` are now also considered valid TypeScript file extensions by default along with the `.ts` extension.\n\n* Fix invalid CSS minification of `margin` and `padding` ([#1657](https://github.com/evanw/esbuild/issues/1657))\n\n    CSS minification does collapsing of `margin` and `padding` related properties. For example:\n\n    ```css\n    /* Original CSS */\n    div {\n      margin: auto;\n      margin-top: 5px;\n      margin-left: 5px;\n    }\n\n    /* Minified CSS */\n    div{margin:5px auto auto 5px}\n    ```\n\n    However, while this works for the `auto` keyword, it doesn't work for other keywords. For example:\n\n    ```css\n    /* Original CSS */\n    div {\n      margin: inherit;\n      margin-top: 5px;\n      margin-left: 5px;\n    }\n\n    /* Minified CSS */\n    div{margin:inherit;margin-top:5px;margin-left:5px}\n    ```\n\n    Transforming this to `div{margin:5px inherit inherit 5px}`, as was done in previous releases of esbuild, is an invalid transformation and results in incorrect CSS. This release of esbuild fixes this CSS transformation bug.\n\n## 0.13.3\n\n* Support TypeScript type-only import/export specifiers ([#1637](https://github.com/evanw/esbuild/pull/1637))\n\n    This release adds support for a new TypeScript syntax feature in the upcoming version 4.5 of TypeScript. This feature lets you prefix individual imports and exports with the `type` keyword to indicate that they are types instead of values. This helps tools such as esbuild omit them from your source code, and is necessary because esbuild compiles files one-at-a-time and doesn't know at parse time which imports/exports are types and which are values. The new syntax looks like this:\n\n    ```ts\n    // Input TypeScript code\n    import { type Foo } from 'foo'\n    export { type Bar }\n\n    // Output JavaScript code (requires \"importsNotUsedAsValues\": \"preserve\" in \"tsconfig.json\")\n    import {} from \"foo\";\n    export {};\n    ```\n\n    See [microsoft/TypeScript#45998](https://github.com/microsoft/TypeScript/pull/45998) for full details. From what I understand this is a purely ergonomic improvement since this was already previously possible using a type-only import/export statements like this:\n\n    ```ts\n    // Input TypeScript code\n    import type { Foo } from 'foo'\n    export type { Bar }\n    import 'foo'\n    export {}\n\n    // Output JavaScript code (requires \"importsNotUsedAsValues\": \"preserve\" in \"tsconfig.json\")\n    import \"foo\";\n    export {};\n    ```\n\n    This feature was contributed by [@g-plane](https://github.com/g-plane).\n\n## 0.13.2\n\n* Fix `export {}` statements with `--tree-shaking=true` ([#1628](https://github.com/evanw/esbuild/issues/1628))\n\n    The new `--tree-shaking=true` option allows you to force-enable tree shaking in cases where it wasn't previously possible. One such case is when bundling is disabled and there is no output format configured, in which case esbuild just preserves the format of whatever format the input code is in. Enabling tree shaking in this context caused a bug where `export {}` statements were stripped. This release fixes the bug so `export {}` statements should now be preserved when you pass `--tree-shaking=true`. This bug only affected this new functionality and didn't affect existing scenarios.\n\n## 0.13.1\n\n* Fix the `esbuild` package in yarn 2+\n\n    The [yarn package manager](https://yarnpkg.com/) version 2 and above has a mode called [PnP](https://next.yarnpkg.com/features/pnp/) that installs packages inside zip files instead of using individual files on disk, and then hijacks node's `fs` module to pretend that paths to files inside the zip file are actually individual files on disk so that code that wasn't written specifically for yarn still works. Unfortunately that hijacking is incomplete and it still causes certain things to break such as using these zip file paths to create a JavaScript worker thread or to create a child process.\n\n    This was an issue for the new `optionalDependencies` package installation strategy that was just released in version 0.13.0 since the binary executable is now inside of an installed package instead of being downloaded using an install script. When it's installed with yarn 2+ in PnP mode the binary executable is inside a zip file and can't be run. To work around this, esbuild detects yarn's PnP mode and copies the binary executable to a real file outside of the zip file.\n\n    Unfortunately the code to do this didn't create the parent directory before writing to the file path. That caused esbuild's API to crash when it was run for the first time. This didn't come up during testing because the parent directory already existed when the tests were run. This release changes the location of the binary executable from a shared cache directory to inside the esbuild package itself, which should fix this crash. This problem only affected esbuild's JS API when it was run through yarn 2+ with PnP mode active.\n\n## 0.13.0\n\n**This release contains backwards-incompatible changes.** Since esbuild is before version 1.0.0, these changes have been released as a new minor version to reflect this (as [recommended by npm](https://docs.npmjs.com/cli/v6/using-npm/semver/)). You should either be pinning the exact version of `esbuild` in your `package.json` file or be using a version range syntax that only accepts patch upgrades such as `~0.12.0`. See the documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\n* Allow tree shaking to be force-enabled and force-disabled ([#1518](https://github.com/evanw/esbuild/issues/1518), [#1610](https://github.com/evanw/esbuild/issues/1610), [#1611](https://github.com/evanw/esbuild/issues/1611), [#1617](https://github.com/evanw/esbuild/pull/1617))\n\n    This release introduces a breaking change that gives you more control over when tree shaking happens (\"tree shaking\" here refers to declaration-level dead code removal). Previously esbuild's tree shaking was automatically enabled or disabled for you depending on the situation and there was no manual override to change this. Specifically, tree shaking was only enabled either when bundling was enabled or when the output format was set to `iife` (i.e. wrapped in an immediately-invoked function expression). This was done to avoid issues with people appending code to output files in the `cjs` and `esm` formats and expecting that code to be able to reference code in the output file that isn't otherwise referenced.\n\n    You now have the ability to explicitly force-enable or force-disable tree shaking to bypass this default behavior. This is a breaking change because there is already a setting for tree shaking that does something else, and it has been moved to a separate setting instead. The previous setting allowed you to control whether or not to ignore manual side-effect annotations, which is related to tree shaking since only side-effect free code can be removed as dead code. Specifically you can annotate function calls with `/* @__PURE__ */` to indicate that they can be removed if they are not used, and you can annotate packages with `\"sideEffects\": false` to indicate that imports of that package can be removed if they are not used. Being able to ignore these annotations is necessary because [they are sometimes incorrect](https://github.com/tensorflow/tfjs/issues/4248). This previous setting has been moved to a separate setting because it actually impacts dead-code removal within expressions, which also applies when minifying with tree-shaking disabled.\n\n    ### Old behavior\n\n    * CLI\n        * Ignore side-effect annotations: `--tree-shaking=ignore-annotations`\n    * JS\n        * Ignore side-effect annotations: `treeShaking: 'ignore-annotations'`\n    * Go\n        * Ignore side-effect annotations: `TreeShaking: api.TreeShakingIgnoreAnnotations`\n\n    ### New behavior\n\n    * CLI\n        * Ignore side-effect annotations: `--ignore-annotations`\n        * Force-disable tree shaking: `--tree-shaking=false`\n        * Force-enable tree shaking: `--tree-shaking=true`\n    * JS\n        * Ignore side-effect annotations: `ignoreAnnotations: true`\n        * Force-disable tree shaking: `treeShaking: false`\n        * Force-enable tree shaking: `treeShaking: true`\n    * Go\n        * Ignore side-effect annotations: `IgnoreAnnotations: true`\n        * Force-disable tree shaking: `TreeShaking: api.TreeShakingFalse`\n        * Force-enable tree shaking: `TreeShaking: api.TreeShakingTrue`\n\n* The npm package now uses `optionalDependencies` to install the platform-specific binary executable ([#286](https://github.com/evanw/esbuild/issues/286), [#291](https://github.com/evanw/esbuild/issues/291), [#319](https://github.com/evanw/esbuild/issues/319), [#347](https://github.com/evanw/esbuild/issues/347), [#369](https://github.com/evanw/esbuild/issues/369), [#547](https://github.com/evanw/esbuild/issues/547), [#565](https://github.com/evanw/esbuild/issues/565), [#789](https://github.com/evanw/esbuild/issues/789), [#921](https://github.com/evanw/esbuild/issues/921), [#1193](https://github.com/evanw/esbuild/issues/1193), [#1270](https://github.com/evanw/esbuild/issues/1270), [#1382](https://github.com/evanw/esbuild/issues/1382), [#1422](https://github.com/evanw/esbuild/issues/1422), [#1450](https://github.com/evanw/esbuild/issues/1450), [#1485](https://github.com/evanw/esbuild/issues/1485), [#1546](https://github.com/evanw/esbuild/issues/1546), [#1547](https://github.com/evanw/esbuild/pull/1547), [#1574](https://github.com/evanw/esbuild/issues/1574), [#1609](https://github.com/evanw/esbuild/issues/1609))\n\n    This release changes esbuild's installation strategy in an attempt to improve compatibility with edge cases such as custom registries, custom proxies, offline installations, read-only file systems, or when post-install scripts are disabled. It's being treated as a breaking change out of caution because it's a significant change to how esbuild works with JS package managers, and hasn't been widely tested yet.\n\n    **The old installation strategy** manually downloaded the correct binary executable in a [post-install script](https://docs.npmjs.com/cli/v7/using-npm/scripts). The binary executable is hosted in a separate platform-specific npm package such as [`esbuild-darwin-64`](https://www.npmjs.com/package/esbuild-darwin-64). The install script first attempted to download the package via the `npm` command in case npm had custom network settings configured. If that didn't work, the install script attempted to download the package from https://registry.npmjs.org/ before giving up. This was problematic for many reasons including:\n\n    * Not all of npm's settings can be forwarded due to npm bugs such as https://github.com/npm/cli/issues/2284, and npm has said these bugs will never be fixed.\n    * Some people have configured their network environments such that downloading from https://registry.npmjs.org/ will hang instead of either succeeding or failing.\n    * The installed package was broken if you used `npm --ignore-scripts` because then the post-install script wasn't run. Some people enable this option so that malicious packages must be run first before being able to do malicious stuff.\n\n    **The new installation strategy** automatically downloads the correct binary executable using npm's `optionalDependencies` feature to depend on all esbuild packages for all platforms but only have the one for the current platform be installed. This is a built-in part of the package manager so my assumption is that it should work correctly in all of these edge cases that currently don't work. And if there's an issue with this, then the problem is with the package manager instead of with esbuild so this should hopefully reduce the maintenance burden on esbuild itself. Changing to this installation strategy has these drawbacks:\n\n    * Old versions of certain package managers (specifically npm and yarn) print lots of useless log messages during the installation, at least one for each platform other than the current one. These messages are harmless and can be ignored. However, they are annoying. There is nothing I can do about this. If you have this problem, one solution is to upgrade your package manager to a newer version.\n\n    * Installation will be significantly slower in old versions of npm, old versions of pnpm, and all versions of yarn. These package managers download all packages for all platforms even though they aren't needed and actually cannot be used. This problem has been fixed in npm and pnpm and the problem has been communicated to yarn: https://github.com/yarnpkg/berry/issues/3317. If you have this problem, one solution is to use a newer version of npm or pnpm as your package manager.\n\n    * This installation strategy does not work if you use `npm --no-optional` since then the package with the binary executable is not installed. If you have this problem, the solution is to not pass the `--no-optional` flag when installing packages.\n\n    * There is still a small post-install script but it's now optional in that the `esbuild` package should still function correctly if post-install scripts are disabled (such as with `npm --ignore-scripts`). This post-install script optimizes the installed package by replacing the `esbuild` JavaScript command shim with the actual binary executable at install time. This avoids the overhead of launching another `node` process when using the `esbuild` command. So keep in mind that installing with `--ignore-scripts` will result in a slower `esbuild` command.\n\n    Despite the drawbacks of the new installation strategy, I believe this change is overall a good thing to move forward with. It should fix edge case scenarios where installing esbuild currently doesn't work at all, and this only comes at the expense of the install script working in a less-optimal way (but still working) if you are using an old version of npm. So I'm going to switch installation strategies and see how it goes.\n\n    The platform-specific binary executables are still hosted on npm in the same way, so anyone who wrote code that downloads builds from npm using the instructions here should not have to change their code: https://esbuild.github.io/getting-started/#download-a-build. However, note that these platform-specific packages no longer specify the `bin` field in `package.json` so the `esbuild` command will no longer be automatically put on your path. The `bin` field had to be removed because of a collision with the `bin` field of the `esbuild` package (now that the `esbuild` package depends on all of these platform-specific packages as optional dependencies).\n\nIn addition to the breaking changes above, the following features are also included in this release:\n\n* Treat `x` guarded by `typeof x !== 'undefined'` as side-effect free\n\n    This is a small tree-shaking (i.e. dead code removal) improvement. Global identifier references are considered to potentially have side effects since they will throw a reference error if the global identifier isn't defined, and code with side effects cannot be removed as dead code. However, there's a somewhat-common case where the identifier reference is guarded by a `typeof` check to check that it's defined before accessing it. With this release, code that does this will now be considered to have no side effects which allows it to be tree-shaken:\n\n    ```js\n    // Original code\n    var __foo = typeof foo !== 'undefined' && foo;\n    var __bar = typeof bar !== 'undefined' && bar;\n    console.log(__bar);\n\n    // Old output (with --bundle, which enables tree-shaking)\n    var __foo = typeof foo !== 'undefined' && foo;\n    var __bar = typeof bar !== 'undefined' && bar;\n    console.log(__bar);\n\n    // New output (with --bundle, which enables tree-shaking)\n    var __bar = typeof bar !== 'undefined' && bar;\n    console.log(__bar);\n    ```\n\n## 0.12.29\n\n* Fix compilation of abstract class fields in TypeScript ([#1623](https://github.com/evanw/esbuild/issues/1623))\n\n    This release fixes a bug where esbuild could incorrectly include a TypeScript abstract class field in the compiled JavaScript output. This is incorrect because the official TypeScript compiler never does this. Note that this only happened in scenarios where TypeScript's `useDefineForClassFields` setting was set to `true` (or equivalently where TypeScript's `target` setting was set to `ESNext`). Here is the difference:\n\n    ```js\n    // Original code\n    abstract class Foo {\n      abstract foo: any;\n    }\n\n    // Old output\n    class Foo {\n      foo;\n    }\n\n    // New output\n    class Foo {\n    }\n    ```\n\n* Proxy from the `__require` shim to `require` ([#1614](https://github.com/evanw/esbuild/issues/1614))\n\n    Some background: esbuild's bundler emulates a CommonJS environment. The bundling process replaces the literal syntax `require(<string>)` with the referenced module at compile-time. However, other uses of `require` such as `require(someFunction())` are not bundled since the value of `someFunction()` depends on code evaluation, and esbuild does not evaluate code at compile-time. So it's possible for some references to `require` to remain after bundling.\n\n    This was causing problems for some CommonJS code that was run in the browser and that expected `typeof require === 'function'` to be true (see [#1202](https://github.com/evanw/esbuild/issues/1202)), since the browser does not provide a global called `require`. Thus esbuild introduced a shim `require` function called `__require` (shown below) and replaced all references to `require` in the bundled code with `__require`:\n\n    ```js\n    var __require = x => {\n      if (typeof require !== 'undefined') return require(x);\n      throw new Error('Dynamic require of \"' + x + '\" is not supported');\n    };\n    ```\n\n    However, this broke code that referenced `require.resolve` inside the bundle, which could hypothetically actually work since you could assign your own implementation to `window.require.resolve` (see [#1579](https://github.com/evanw/esbuild/issues/1579)). So the implementation of `__require` was changed to this:\n\n    ```js\n    var __require = typeof require !== 'undefined' ? require : x => {\n      throw new Error('Dynamic require of \"' + x + '\" is not supported');\n    };\n    ```\n\n    However, that broke code that assigned to `window.require` later on after the bundle was loaded ([#1614](https://github.com/evanw/esbuild/issues/1614)). So with this release, the code for `__require` now handles all of these edge cases:\n\n    * `typeof require` is still `function` even if `window.require` is undefined\n    * `window.require` can be assigned to either before or after the bundle is loaded\n    * `require.resolve` and arbitrary other properties can still be accessed\n    * `require` will now forward any number of arguments, not just the first one\n\n    Handling all of these edge cases is only possible with the [Proxy API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy). So the implementation of `__require` now looks like this:\n\n    ```js\n    var __require = (x =>\n      typeof require !== 'undefined' ? require :\n      typeof Proxy !== 'undefined' ? new Proxy(x, {\n        get: (a, b) => (typeof require !== 'undefined' ? require : a)[b]\n      }) : x\n    )(function(x) {\n      if (typeof require !== 'undefined') return require.apply(this, arguments);\n      throw new Error('Dynamic require of \"' + x + '\" is not supported');\n    });\n    ```\n\n* Consider `typeof x` to have no side effects\n\n    The `typeof` operator does not itself trigger any code evaluation so it can safely be removed if evaluating the operand does not cause any side effects. However, there is a special case of the `typeof` operator when the operand is an identifier expression. In that case no reference error is thrown if the referenced symbol does not exist (e.g. `typeof x` does not throw an error if there is no symbol named `x`). With this release, esbuild will now consider `typeof x` to have no side effects even if evaluating `x` would have side effects (i.e. would throw a reference error):\n\n    ```js\n    // Original code\n    var unused = typeof React !== 'undefined';\n\n    // Old output\n    var unused = typeof React !== 'undefined';\n\n    // New output\n    ```\n\n    Note that there is actually an edge case where `typeof x` *can* throw an error: when `x` is being referenced inside of its TDZ, or temporal dead zone (i.e. before it's declared). This applies to `let`, `const`, and `class` symbols. However, esbuild doesn't currently handle TDZ rules so the possibility of errors thrown due to TDZ rules is not currently considered. This typically doesn't matter in real-world code so this hasn't been a priority to fix (and is actually tricky to fix with esbuild's current bundling approach). So esbuild may incorrectly remove a `typeof` expression that actually has side effects. However, esbuild already incorrectly did this in previous releases so its behavior regarding `typeof` and TDZ rules hasn't changed in this release.\n\n## 0.12.28\n\n* Fix U+30FB and U+FF65 in identifier names in ES5 vs. ES6+ ([#1599](https://github.com/evanw/esbuild/issues/1599))\n\n    The ES6 specification caused two code points that were previously valid in identifier names in ES5 to no longer be valid in identifier names in ES6+. The two code points are:\n\n    * `U+30FB` i.e. `KATAKANA MIDDLE DOT` i.e. `・`\n    * `U+FF65` i.e. `HALFWIDTH KATAKANA MIDDLE DOT` i.e. `･`\n\n    This means that using ES6+ parsing rules will fail to parse some valid ES5 code, and generating valid ES5 code may fail to be parsed using ES6+ parsing rules. For example, esbuild would previously fail to parse `x.y･` even though it's valid ES5 code (since it's not valid ES6+ code) and esbuild could generate `{y･:x}` when minifying even though it's not valid ES6+ code (since it's valid ES5 code). This problem is the result of my incorrect assumption that ES6 is a superset of ES5.\n\n    As of this release, esbuild will now parse a superset of ES5 and ES6+ and will now quote identifier names when possible if it's not considered to be a valid identifier name in either ES5 or ES6+. In other words, a union of ES5 and ES6 rules is used for parsing and the intersection of ES5 and ES6 rules is used for printing.\n\n* Fix `++` and `--` on class private fields when used with big integers ([#1600](https://github.com/evanw/esbuild/issues/1600))\n\n    Previously when esbuild lowered class private fields (e.g. `#foo`) to older JavaScript syntax, the transform of the `++` and `--` was not correct if the value is a big integer such as `123n`. The transform in esbuild is similar to Babel's transform which [has the same problem](https://github.com/babel/babel/issues/13756). Specifically, the code was transformed into code that either adds or subtracts the number `1` and `123n + 1` throws an exception in JavaScript. This problem has been fixed so this should now work fine starting with this release.\n\n## 0.12.27\n\n* Update JavaScript syntax feature compatibility tables ([#1594](https://github.com/evanw/esbuild/issues/1594))\n\n    Most JavaScript syntax feature compatibility data is able to be obtained automatically via https://kangax.github.io/compat-table/. However, they are missing data for quite a few new JavaScript features (see ([kangax/compat-table#1034](https://github.com/kangax/compat-table/issues/1034))) so data on these new features has to be added manually. This release manually adds a few new entries:\n\n    * Top-level await\n\n        This feature lets you use `await` at the top level of a module, outside of an `async` function. Doing this holds up the entire module instantiation operation until the awaited expression is resolved or rejected. This release marks this feature as supported in Edge 89, Firefox 89, and Safari 15 (it was already marked as supported in Chrome 89 and Node 14.8). The data source for this is https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await.\n\n    * Arbitrary module namespace identifier names\n\n        This lets you use arbitrary strings as module namespace identifier names as long as they are valid UTF-16 strings. An example is `export { x as \"🍕\" }` which can then be imported as `import { \"🍕\" as y } from \"./example.js\"`. This release marks this feature as supported in Firefox 87 (it was already marked as supported in Chrome 90 and Node 16). The data source for this is https://bugzilla.mozilla.org/show_bug.cgi?id=1670044.\n\n    I would also like to add data for Safari. They have recently added support for arbitrary module namespace identifier names (https://bugs.webkit.org/show_bug.cgi?id=217576) and `export * as` (https://bugs.webkit.org/show_bug.cgi?id=214379). However, I have no idea how to determine which Safari release these bugs correspond to so this compatibility data for Safari has been omitted.\n\n* Avoid unnecessary additional log messages after the server is stopped ([#1589](https://github.com/evanw/esbuild/issues/1589))\n\n    There is a development server built in to esbuild which is accessible via the `serve()` API call. This returns a promise that resolves to an object with a `stop()` method that immediately terminates the development server. Previously calling this could cause esbuild to print stray log messages since `stop()` could cause plugins to be unregistered while a build is still in progress. With this release, calling `stop()` no longer terminates the development server immediately. It now waits for any active builds to finish first so the builds are not interrupted and left in a confusing state.\n\n* Fix an accidental dependency on Go ≥1.17.0 ([#1585](https://github.com/evanw/esbuild/pull/1585))\n\n    The source code of this release no longer uses the `math.MaxInt` constant that was introduced in Go version 1.17.0. This constant was preventing esbuild from being compiled on Go version <1.17.0. This fix was contributed by [@davezuko](https://github.com/davezuko).\n\n## 0.12.26\n\n* Add `--analyze` to print information about the bundle ([#1568](https://github.com/evanw/esbuild/issues/1568))\n\n    The `--metafile=` flag tells esbuild to write information about the bundle into the provided metadata file in JSON format. It contains information about the input files and which other files each one imports, as well as the output files and which input files they include. This information is sufficient to answer many questions such as:\n\n    * Which files are in my bundle?\n    * What's are the biggest files in my bundle?\n    * Why is this file included in my bundle?\n\n    Previously you had to either write your own code to answer these questions, or use another tool such as https://bundle-buddy.com/esbuild to visualize the data. Starting with this release you can now also use `--analyze` to enable esbuild's built-in visualizer. It looks like this:\n\n    ```\n    $ esbuild --bundle example.jsx --outfile=out.js --minify --analyze\n\n      out.js  27.6kb\n\n    ⚡ Done in 6ms\n\n      out.js                                                                    27.6kb  100.0%\n       ├ node_modules/react-dom/cjs/react-dom-server.browser.production.min.js  19.2kb   69.8%\n       ├ node_modules/react/cjs/react.production.min.js                          5.9kb   21.4%\n       ├ node_modules/object-assign/index.js                                     965b     3.4%\n       ├ example.jsx                                                             137b     0.5%\n       ├ node_modules/react-dom/server.browser.js                                 50b     0.2%\n       └ node_modules/react/index.js                                              50b     0.2%\n    ```\n\n    This tells you what input files were bundled into each output file as well as the final minified size contribution of each input file as well as the percentage of the output file it takes up. You can also enable verbose analysis with `--analyze=verbose` to see why each input file was included (i.e. which files imported it from the entry point file):\n\n    ```\n    $ esbuild --bundle example.jsx --outfile=out.js --minify --analyze=verbose\n\n      out.js  27.6kb\n\n    ⚡ Done in 6ms\n\n      out.js ─────────────────────────────────────────────────────────────────── 27.6kb ─ 100.0%\n       ├ node_modules/react-dom/cjs/react-dom-server.browser.production.min.js ─ 19.2kb ── 69.8%\n       │  └ node_modules/react-dom/server.browser.js\n       │     └ example.jsx\n       ├ node_modules/react/cjs/react.production.min.js ───────────────────────── 5.9kb ── 21.4%\n       │  └ node_modules/react/index.js\n       │     └ example.jsx\n       ├ node_modules/object-assign/index.js ──────────────────────────────────── 965b ──── 3.4%\n       │  └ node_modules/react-dom/cjs/react-dom-server.browser.production.min.js\n       │     └ node_modules/react-dom/server.browser.js\n       │        └ example.jsx\n       ├ example.jsx ──────────────────────────────────────────────────────────── 137b ──── 0.5%\n       ├ node_modules/react-dom/server.browser.js ──────────────────────────────── 50b ──── 0.2%\n       │  └ example.jsx\n       └ node_modules/react/index.js ───────────────────────────────────────────── 50b ──── 0.2%\n          └ example.jsx\n    ```\n\n    There is also a JS API for this:\n\n    ```js\n    const result = await esbuild.build({\n      metafile: true,\n      ...\n    })\n    console.log(await esbuild.analyzeMetafile(result.metafile, {\n      verbose: true,\n    }))\n    ```\n\n    and a Go API:\n\n    ```js\n    result := api.Build(api.BuildOptions{\n      Metafile: true,\n      ...\n    })\n    fmt.Println(api.AnalyzeMetafile(result.Metafile, api.AnalyzeMetafileOptions{\n      Verbose: true,\n    }))\n    ```\n\n    Note that this is not the only way to visualize this data. If you want a visualization that's different than the information displayed here, you can easily build it yourself using the information in the metafile that is generated with the `--metafile=` flag.\n\n    Also note that this data is intended for humans, not machines. The specific format of this data may change over time which will likely break any tools that try to parse it. You should not write a tool to parse this data. You should be using the information in the JSON metadata file instead. Everything in this visualization is derived from the JSON metadata so you are not losing out on any information by not using esbuild's output.\n\n* Allow `require.resolve` in non-node builds ([#1579](https://github.com/evanw/esbuild/issues/1579))\n\n    With this release, you can now use `require.resolve` in builds when the target platform is set to `browser` instead of `node` as long as the function `window.require.resolve` exists somehow. This was already possible when the platform is `node` but when the platform is `browser`, esbuild generates a no-op shim `require` function for compatibility reasons (e.g. because some code expects `typeof require` must be `\"function\"` even in the browser). The shim previously had a fallback to `window.require` if it exists, but additional properties of the `require` function such as `require.resolve` were not copied over to the shim. Now the shim function is only used if `window.require` is undefined so additional properties such as `require.resolve` should now work.\n\n    This change was contributed by [@screetBloom](https://github.com/screetBloom).\n\n## 0.12.25\n\n* Fix a TypeScript parsing edge case with the postfix `!` operator ([#1560](https://github.com/evanw/esbuild/issues/1560))\n\n    This release fixes a bug with esbuild's TypeScript parser where the postfix `!` operator incorrectly terminated a member expression after the `new` operator:\n\n    ```js\n    // Original input\n    new Foo!.Bar();\n\n    // Old output\n    new Foo().Bar();\n\n    // New output\n    new Foo.Bar();\n    ```\n\n    The problem was that `!` was considered a postfix operator instead of part of a member expression. It is now considered to be part of a member expression instead, which fixes this edge case.\n\n* Fix a parsing crash with nested private brand checks\n\n    This release fixes a bug in the parser where code of the form `#a in #b in c` caused a crash. This code now causes a syntax error instead. Private identifiers are allowed when followed by `in`, but only if the operator precedence level is such that the `in` operator is allowed. The parser was missing the operator precedence check.\n\n* Publish x86-64 binary executables for illumos ([#1562](https://github.com/evanw/esbuild/pull/1562))\n\n    This release adds support for the [illumos](https://www.illumos.org/) operating system, which is related to Solaris and SunOS. Support for this platform was contributed by [@hadfl](https://github.com/hadfl).\n\n## 0.12.24\n\n* Fix an edge case with direct `eval` and variable renaming\n\n    Use of the direct `eval` construct causes all variable names in the scope containing the direct `eval` and all of its parent scopes to become \"pinned\" and unable to be renamed. This is because the dynamically-evaluated code is allowed to reference any of those variables by name. When this happens esbuild avoids renaming any of these variables, which effectively disables minification for most of the file, and avoids renaming any non-pinned variables to the name of a pinned variable.\n\n    However, there was previously a bug where the pinned variable name avoidance only worked for pinned variables in the top-level scope but not in nested scopes. This could result in a non-pinned variable being incorrectly renamed to the name of a pinned variable in certain cases. For example:\n\n    ```js\n    // Input to esbuild\n    return function($) {\n      function foo(arg) {\n        return arg + $;\n      }\n      // Direct \"eval\" here prevents \"$\" from being renamed\n      // Repeated \"$\" puts \"$\" at the top of the character frequency histogram\n      return eval(foo($$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$))\n    }(2);\n    ```\n\n    When this code is minified with `--minify-identifiers`, the non-pinned variable `arg` is incorrectly transformed into `$` resulting in a name collision with the nested pinned variable `$`:\n\n    ```js\n    // Old output from esbuild (incorrect)\n    return function($) {\n      function foo($) {\n        return $ + $;\n      }\n      return eval(foo($$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$));\n    }(2);\n    ```\n\n    This is because the non-pinned variable `arg` is renamed to the top character in the character frequency histogram `$` (esbuild uses a character frequency histogram for smaller gzipped output sizes) and the pinned variable `$` was incorrectly not present in the list of variable names to avoid. With this release, the output is now correct:\n\n    ```js\n    // New output from esbuild (correct)\n    return function($) {\n      function foo(n) {\n        return n + $;\n      }\n      return eval(foo($$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$));\n    }(2);\n    ```\n\n    Note that even when esbuild handles direct `eval` correctly, using direct `eval` is not recommended because it disables minification for the file and likely won't work correctly in the presence of scope hoisting optimizations. See https://esbuild.github.io/link/direct-eval for more details.\n\n## 0.12.23\n\n* Parsing of rest arguments in certain TypeScript types ([#1553](https://github.com/evanw/esbuild/issues/1553))\n\n    This release implements parsing of rest arguments inside object destructuring inside arrow functions inside TypeScript type declarations. Support for rest arguments in this specific syntax was not previously implemented. The following code was incorrectly considered a syntax error before this release, but is no longer considered a syntax error:\n\n    ```ts\n    type F = ({ ...rest }) => void;\n    ```\n\n* Fix error message for `watch: true` and `buildSync` ([#1552](https://github.com/evanw/esbuild/issues/1552))\n\n    Watch mode currently only works with the `build` API. Previously using watch mode with the `buildSync` API caused a confusing error message. This release explicitly disallows doing this, so the error message is now more clear.\n\n* Fix an minification bug with the `--keep-names` option ([#1552](https://github.com/evanw/esbuild/issues/1552))\n\n    This release fixes a subtle bug that happens with `--keep-names --minify` and nested function declarations in strict mode code. It can be triggered by the following code, which was being compiled incorrectly under those flags:\n\n    ```js\n    export function outer() {\n      {\n        function inner() {\n          return Math.random();\n        }\n        const x = inner();\n        console.log(x);\n      }\n    }\n    outer();\n    ```\n\n    The bug was caused by an unfortunate interaction between a few of esbuild's behaviors:\n\n    1. Function declarations inside of nested scopes behave differently in different situations, so esbuild rewrites this function declaration to a local variable initialized to a function expression instead so that it behaves the same in all situations.\n\n        More specifically, the interpretation of such function declarations depends on whether or not it currently exists in a strict mode context:\n\n        ```\n        > (function(){ { function x(){} } return x })()\n        function x() {}\n\n        > (function(){ 'use strict'; { function x(){} } return x })()\n        ❌ Uncaught ReferenceError: x is not defined\n        ```\n\n        The bundling process sometimes erases strict mode context. For example, different files may have different strict mode status but may be merged into a single file which all shares the same strict mode status. Also, files in ESM format are automatically in strict mode but a bundle output file in IIFE format may not be executed in strict mode. Transforming the nested `function` to a `let` in strict mode and a `var` in non-strict mode means esbuild's output will behave reliably in different environments.\n\n    2. The \"keep names\" feature adds automatic calls to the built-in `__name` helper function to assign the original name to the `.name` property of the minified function object at run-time. That transforms the code into this:\n\n        ```js\n        let inner = function() {\n          return Math.random();\n        };\n        __name(inner, \"inner\");\n        const x = inner();\n        console.log(x);\n        ```\n\n        This injected helper call does not count as a use of the associated function object so that dead-code elimination will still remove the function object as dead code if nothing else uses it. Otherwise dead-code elimination would stop working when the \"keep names\" feature is enabled.\n\n    3. Minification enables an optimization where an initialized variable with a single use immediately following that variable is transformed by inlining the initializer into the use. So for example `var a = 1; return a` is transformed into `return 1`. This code matches this pattern (initialized single-use variable + use immediately following that variable) so the optimization does the inlining, which transforms the code into this:\n\n        ```js\n        __name(function() {\n          return Math.random();\n        }, \"inner\");\n        const x = inner();\n        console.log(x);\n        ```\n\n        The code is now incorrect because `inner` actually has two uses, although only one was actually counted.\n\n    This inlining optimization will now be avoided in this specific case, which fixes the bug without regressing dead-code elimination or initialized variable inlining in any other cases.\n\n## 0.12.22\n\n* Make HTTP range requests more efficient ([#1536](https://github.com/evanw/esbuild/issues/1536))\n\n    The local HTTP server built in to esbuild supports [range requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests), which are necessary for video playback in Safari. This means you can now use `<video>` tags in your HTML pages with esbuild's local HTTP server.\n\n    Previously this was implemented inefficiently for files that aren't part of the build, but that are read from the underlying fallback directory. In that case the entire file was being read even though only part of the file was needed. In this release, only the part of the file that is needed is read so using HTTP range requests with esbuild in this case will now use less memory.\n\n* Fix CSS minification bug with `box-shadow` and `var()` ([#1538](https://github.com/evanw/esbuild/issues/1538))\n\n    The `box-shadow` property can be specified using 2, 3, or 4 numbers. The 3rd and 4th numbers are the blur radius and spread radius, and can be omitted if zero. When minifying, esbuild has an optimization that removes trailing zeros from runs of numbers within the `box-shadow` property. However, that optimization is not correct in the presence of tokens that are neither a number, a color, nor the token `insert`. These edge cases include `var()` or `calc()` tokens. With this release, esbuild will now do stronger validation and will only remove trailing zeros if the contents of the `box-shadow` property matches the underlying CSS grammar exactly.\n\n    ```css\n    /* Original code */\n    button {\n      box-shadow: 0 0 0 var(--spread) red;\n    }\n\n    /* Old minified output */\n    button{box-shadow:0 0 var(--spread) red}\n\n    /* New minified output */\n    button{box-shadow:0 0 0 var(--spread) red}\n    ```\n\n## 0.12.21\n\n* Add support for native esbuild on Windows 64-bit ARM ([#995](https://github.com/evanw/esbuild/issues/995))\n\n    The newly-released Go version 1.17.0 [adds support for Windows 64-bit ARM CPUs](https://golang.org/doc/go1.17#windows), so esbuild can now support these CPUs as well. This release introduces support for `npm install esbuild` on Windows 64-bit ARM.\n\n## 0.12.20\n\n* Avoid the sequence `</style` in CSS output ([#1509](https://github.com/evanw/esbuild/issues/1509))\n\n    The CSS code generator now avoids generating the character sequence `</style` in case you want to embed the CSS output in a `<style>...</style>` tag inside HTML:\n\n    ```css\n    /* Original code */\n    a:after {\n      content: \"</style>\";\n    }\n\n    /* Old output */\n    a:after {\n      content: \"</style>\";\n    }\n\n    /* New output */\n    a:after {\n      content: \"<\\/style>\";\n    }\n    ```\n\n    This mirrors how the JS code generator similarly avoids the character sequence `</script`.\n\n    In addition, the check that escapes `</style` and `</script` is now case-insensitive to match how the browser's HTML parser behaves. So `</STYLE` and `</SCRIPT` are now escaped as well.\n\n* Fix a TypeScript parsing edge case with ASI (Automatic Semicolon Insertion) ([#1512](https://github.com/evanw/esbuild/issues/1512))\n\n    This fixes a parsing bug where TypeScript types consisting of multiple identifiers joined together with a `.` could incorrectly extend onto the next line if the next line started with `<`. This problem was due to ASI; esbuild should be automatically inserting a semicolon at the end of the line:\n\n    ```ts\n    let x: {\n      <A extends B>(): c.d /* A semicolon should be automatically inserted here */\n      <E extends F>(): g.h\n    }\n    ```\n\n    Previously the above code was incorrectly considered a syntax error since esbuild attempted to parse the parameterized type `c.d<E extends F ? ...>`. With this release, this code is now parsed correctly.\n\n## 0.12.19\n\n* Add support for CSS source maps ([#519](https://github.com/evanw/esbuild/issues/519))\n\n    With this release, esbuild will now generate source maps for CSS output files when `--sourcemap` is enabled. This supports all of the same options as JS source maps including `--sourcemap=inline` and `--sourcemap=external`. In addition, CSS input files with embedded `/*# sourceMappingURL=... */` comments will cause the CSS output file source map to map all the way back to the original inputs. CSS source maps are used by the browser's style inspector to link back to the original source code instead of linking to the bundled source code.\n\n* Fix computed class fields in TypeScript edge case ([#1507](https://github.com/evanw/esbuild/issues/1507))\n\n    If TypeScript code contains computed class fields, the target environment supports class fields so syntax lowering is not necessary, and TypeScript's `useDefineForClassFields` setting is set to `true`, then esbuild had a bug where the computed property names were computed after the class definition and were undefined. Note that TypeScript's `useDefineForClassFields` setting defaults to `true` if `tsconfig.json` contains `\"target\": \"ESNext\"`.\n\n    ```ts\n    // Original code\n    class Foo {\n      [foo] = 1;\n      @bar [baz] = 2;\n    }\n\n    // Old output\n    var _a, _b;\n    var Foo = class {\n      [_a] = 1;\n      [_b] = 2;\n    };\n    _a = foo, _b = baz;\n    __decorateClass([\n      bar\n    ], Foo.prototype, _b, 2);\n\n    // New output\n    var _a;\n    var Foo = class {\n      [foo] = 1;\n      [_a = baz] = 2;\n    };\n    __decorateClass([\n      bar\n    ], Foo.prototype, _a, 2);\n    ```\n\n    The problem in this case is that normally TypeScript moves class field initializers into the special `constructor` method (automatically generating one if one doesn't already exist) so the side effects for class field property names must happen after the class body. But if class fields are supported by the target environment then the side effects must happen inline instead.\n\n## 0.12.18\n\n* Allow implicit `./` in CSS `@import` paths ([#1494](https://github.com/evanw/esbuild/pull/1494))\n\n    In the browser, the paths inside CSS `@import` rules are implicitly relative to the path of the current CSS style sheet. Previously esbuild used node's JS path resolution rules in CSS as well, which required a `./` or `../` prefix for a path to be considered a relative path. Paths without that prefix are considered package paths and are searched for inside `node_modules` instead.\n\n    With this release, esbuild will now first try to interpret the path as a relative path and then fall back to interpreting it as a package path if nothing exists at that relative path. This feature was originally added in version 0.7.18 but only worked for CSS `url()` tokens. In this release it now also works for `@import` rules.\n\n    This feature was contributed by [@pd4d10](https://github.com/pd4d10).\n\n* Fix lowering of nullish coalescing assignment edge case ([#1493](https://github.com/evanw/esbuild/issues/1493))\n\n    This release fixes a bug where lowering of the `??=` nullish coalescing assignment operator failed when the target environment supported nullish coalescing and private class fields but not nullish coalescing assignment. An example target environment with this specific feature support matrix combination is node 14.8. This edge case is now lowered correctly:\n\n    ```js\n    // Original code\n    class A {\n      #a;\n      f() {\n        this.#a ??= 1;\n      }\n    }\n\n    // Old output (with --target=node14.8)\n    panic: Unexpected expression of type *js_ast.EPrivateIdentifier\n\n    // New output (with --target=node14.8)\n    class A {\n      #a;\n      f() {\n        this.#a ?? (this.#a = 1);\n      }\n    }\n    ```\n\n* Fix public fields being inserted before `super()` call ([#1497](https://github.com/evanw/esbuild/issues/1497))\n\n    The helper function that esbuild uses to emulate the new public class field syntax can potentially be inserted into the class constructor before the `super()` call. That is problematic because the helper function makes use of `this`, and `this` must only be used after the `super()` call. This release fixes a case where this happens when minification is enabled:\n\n    ```js\n    // Original code\n    class A extends B {\n      x;\n      constructor() {\n        f();\n        super();\n      }\n    }\n\n    // Old output (with --minify-syntax --target=es6)\n    class A extends B {\n      constructor() {\n        __publicField(this, \"x\");\n        f(), super();\n      }\n    }\n\n    // New output (with --minify-syntax --target=es6)\n    class A extends B {\n      constructor() {\n        f();\n        super();\n        __publicField(this, \"x\");\n      }\n    }\n    ```\n\n* Fix lowering of static private methods in class expressions ([#1498](https://github.com/evanw/esbuild/issues/1498))\n\n    Previously static private methods were lowered incorrectly when present in class expressions. The class expression itself was missing in the output due to an oversight (variable shadowing). This issue has been fixed:\n\n    ```js\n    // Original code\n    (class {\n      static #x() {}\n    });\n\n    // Old output (with --target=es6)\n    var _x, _a, x_fn;\n    __privateAdd(_a, _x), _x = new WeakSet(), x_fn = function() {\n    }, __privateAdd(_a, _x), _a;\n\n    // New output (with --target=es6)\n    var _x, _a, x_fn;\n    _a = class {\n    }, _x = new WeakSet(), x_fn = function() {\n    }, __privateAdd(_a, _x), _a;\n    ```\n\n## 0.12.17\n\n* Fix a bug with private fields and logical assignment operators ([#1418](https://github.com/evanw/esbuild/issues/1418))\n\n    This release fixes a bug where code using private fields in combination with [logical assignment operators](https://github.com/tc39/proposal-logical-assignment) was transformed incorrectly if the target environment supported logical assignment operators but not private fields. Since logical assignment operators are assignment operators, the entire operator must be transformed even if the operator is supported. This should now work correctly:\n\n    ```js\n    // Original code\n    class Foo {\n      #x\n      foo() {\n        this.#x &&= 2\n        this.#x ||= 2\n        this.#x ??= 2\n      }\n    }\n\n    // Old output\n    var _x;\n    class Foo {\n      constructor() {\n        __privateAdd(this, _x, void 0);\n      }\n      foo() {\n        this._x &&= 2;\n        this._x ||= 2;\n        this._x ??= 2;\n      }\n    }\n    _x = new WeakMap();\n\n    // New output\n    var _x, _a;\n    class Foo {\n      constructor() {\n        __privateAdd(this, _x, void 0);\n      }\n      foo() {\n        __privateGet(this, _x) && __privateSet(this, _x, 2);\n        __privateGet(this, _x) || __privateSet(this, _x, 2);\n        __privateGet(this, _x) ?? __privateSet(this, _x, 2);\n      }\n    }\n    _x = new WeakMap();\n    ```\n\n* Fix a hoisting bug in the bundler ([#1455](https://github.com/evanw/esbuild/issues/1455))\n\n    This release fixes a bug where variables declared using `var` inside of top-level `for` loop initializers were not hoisted inside lazily-initialized ES modules (such as those that are generated when bundling code that loads an ES module using `require`). This meant that hoisted function declarations incorrectly didn't have access to these loop variables:\n\n    ```js\n    // entry.js\n    console.log(require('./esm-file').test())\n\n    // esm-file.js\n    for (var i = 0; i < 10; i++) ;\n    export function test() { return i }\n    ```\n\n    Old output (incorrect):\n\n    ```js\n    // esm-file.js\n    var esm_file_exports = {};\n    __export(esm_file_exports, {\n      test: () => test\n    });\n    function test() {\n      return i;\n    }\n    var init_esm_file = __esm({\n      \"esm-file.js\"() {\n        for (var i = 0; i < 10; i++)\n          ;\n      }\n    });\n\n    // entry.js\n    console.log((init_esm_file(), esm_file_exports).test());\n    ```\n\n    New output (correct):\n\n    ```js\n    // esm-file.js\n    var esm_file_exports = {};\n    __export(esm_file_exports, {\n      test: () => test\n    });\n    function test() {\n      return i;\n    }\n    var i;\n    var init_esm_file = __esm({\n      \"esm-file.js\"() {\n        for (i = 0; i < 10; i++)\n          ;\n      }\n    });\n\n    // entry.js\n    console.log((init_esm_file(), esm_file_exports).test());\n    ```\n\n* Fix a code generation bug for private methods ([#1424](https://github.com/evanw/esbuild/issues/1424))\n\n    This release fixes a bug where when private methods are transformed and the target environment is one that supports private methods (such as `esnext`), the member function name was uninitialized and took on the zero value by default. This resulted in the member function name becoming `__create` instead of the correct name since that's the name of the symbol at index 0. Now esbuild always generates a private method symbol even when private methods are supported, so this is no longer an issue:\n\n    ```js\n    // Original code\n    class Foo {\n      #a() { return 'a' }\n      #b() { return 'b' }\n      static c\n    }\n\n    // Old output\n    var _a, __create, _b, __create;\n    var Foo = class {\n      constructor() {\n        __privateAdd(this, _a);\n        __privateAdd(this, _b);\n      }\n    };\n    _a = new WeakSet();\n    __create = function() {\n      return \"a\";\n    };\n    _b = new WeakSet();\n    __create = function() {\n      return \"b\";\n    };\n    __publicField(Foo, \"c\");\n\n    // New output\n    var _a, a_fn, _b, b_fn;\n    var Foo = class {\n      constructor() {\n        __privateAdd(this, _a);\n        __privateAdd(this, _b);\n      }\n    };\n    _a = new WeakSet();\n    a_fn = function() {\n      return \"a\";\n    };\n    _b = new WeakSet();\n    b_fn = function() {\n      return \"b\";\n    };\n    __publicField(Foo, \"c\");\n    ```\n\n* The CLI now stops watch and serve mode when stdin is closed ([#1449](https://github.com/evanw/esbuild/pull/1449))\n\n    To facilitate esbuild being called from the Erlang VM, esbuild's command-line interface will now exit when in `--watch` or `--serve` mode if stdin is closed. This change is necessary because the Erlang VM doesn't have an API for terminating a child process, so it instead closes stdin to indicate that the process is no longer needed.\n\n    Note that this only happens when stdin is not a TTY (i.e. only when the CLI is being used non-interactively) to avoid disrupting the use case of manually moving esbuild to a background job using a Unix terminal.\n\n    This change was contributed by [@josevalim](https://github.com/josevalim).\n\n## 0.12.16\n\n* Remove warning about bad CSS `@`-rules ([#1426](https://github.com/evanw/esbuild/issues/1426))\n\n    The CSS bundler built in to esbuild is only designed with real CSS in mind. Running other languages that compile down to CSS through esbuild without compiling them down to CSS first can be a bad idea since esbuild applies browser-style error recovery to invalid syntax and uses browser-style import order that other languages might not be expecting. This is why esbuild previously generated warnings when it encountered unknown CSS `@`-rules.\n\n    However, some people want to run other non-CSS languages through esbuild's CSS bundler anyway. So with this release, esbuild will no longer generate any warnings if you do this. But keep in mind that doing this is still potentially unsafe. Depending on the input language, using esbuild's CSS bundler to bundle non-CSS code can still potentially alter the semantics of your code.\n\n* Allow `ES2021` in `tsconfig.json` ([#1470](https://github.com/evanw/esbuild/issues/1470))\n\n    TypeScript recently [added support for `ES2021`](https://github.com/microsoft/TypeScript/pull/41239) in `tsconfig.json` so esbuild now supports this too. This has the same effect as if you passed `--target=es2021` to esbuild. Keep in mind that the value of `target` in `tsconfig.json` is only respected if you did not pass a `--target=` value to esbuild.\n\n* Avoid using the `worker_threads` optimization in certain old node versions ([#1462](https://github.com/evanw/esbuild/issues/1462))\n\n    The `worker_threads` optimization makes esbuild's synchronous API calls go much faster than they would otherwise. However, it turns out this optimization cannot be used in certain node versions older than `v12.17.0`, where node throws an error when trying to create the worker. This optimization is now disabled in these scenarios.\n\n    Note that these old node versions are [currently in maintenance](https://nodejs.org/en/about/releases/). I recommend upgrading to a modern version of node if run-time performance is important to you.\n\n* Paths starting with `node:` are implicitly external when bundling for node ([#1466](https://github.com/evanw/esbuild/issues/1466))\n\n    This replicates a new node feature where you can [prefix an import path with `node:`](https://nodejs.org/api/esm.html#esm_node_imports) to load a native node module by that name (such as `import fs from \"node:fs/promises\"`). These paths also [have special behavior](https://nodejs.org/api/modules.html#modules_core_modules):\n\n    > Core modules can also be identified using the `node:` prefix, in which case it bypasses the `require` cache. For instance, `require('node:http')` will always return the built in HTTP module, even if there is `require.cache` entry by that name.\n\n    With this release, esbuild's built-in resolver will now automatically consider all import paths starting with `node:` as external. This new behavior is only active when the current platform is set to node such as with `--platform=node`. If you need to customize this behavior, you can write a plugin to intercept these paths and treat them differently.\n\n* Consider `\\` and `/` to be the same in file paths ([#1459](https://github.com/evanw/esbuild/issues/1459))\n\n    On Windows, there are many different file paths that can refer to the same underlying file. Windows uses a case-insensitive file system so for example `foo.js` and `Foo.js` are the same file. When bundling, esbuild needs to treat both of these paths as the same to avoid incorrectly bundling the file twice. This is case is already handled by identifying files by their lower-case file path.\n\n    The case that wasn't being handled is the fact that Windows supports two different path separators, `/` and `\\`, both of which mean the same thing. For example `foo/bar.js` and `foo\\bar.js` are the same file. With this release, this case is also handled by esbuild. Files that are imported in multiple places with inconsistent path separators will now be considered the same file instead of bundling the file multiple times.\n\n## 0.12.15\n\n* Fix a bug with `var()` in CSS color lowering ([#1421](https://github.com/evanw/esbuild/issues/1421))\n\n    This release fixes a bug with esbuild's handling of the `rgb` and `hsl` color functions when they contain `var()`. Each `var()` token sequence can be substituted for any number of tokens including zero or more than one, but previously esbuild's output was only correct if each `var()` inside of `rgb` or `hsl` contained exactly one token. With this release, esbuild will now not attempt to transform newer CSS color syntax to older CSS color syntax if it contains `var()`:\n\n    ```\n    /* Original code */\n    a {\n      color: hsl(var(--hs), var(--l));\n    }\n\n    /* Old output */\n    a {\n      color: hsl(var(--hs), ,, var(--l));\n    }\n\n    /* New output */\n    a {\n      color: hsl(var(--hs), var(--l));\n    }\n    ```\n\n    The bug with the old output above happened because esbuild considered the arguments to `hsl` as matching the pattern `hsl(h s l)` which is the new space-separated form allowed by [CSS Color Module Level 4](https://drafts.csswg.org/css-color/#the-hsl-notation). Then esbuild tried to convert this to the form `hsl(h, s, l)` which is more widely supported by older browsers. But this substitution doesn't work in the presence of `var()`, so it has now been disabled in that case.\n\n## 0.12.14\n\n* Fix the `file` loader with custom namespaces ([#1404](https://github.com/evanw/esbuild/issues/1404))\n\n    This fixes a regression from version 0.12.12 where using a plugin to load an input file with the `file` loader in a custom namespace caused esbuild to write the contents of that input file to the path associated with that namespace instead of to a path inside of the output directory. With this release, the `file` loader should now always copy the file somewhere inside of the output directory.\n\n## 0.12.13\n\n* Fix using JS synchronous API from from non-main threads ([#1406](https://github.com/evanw/esbuild/issues/1406))\n\n    This release fixes an issue with the new implementation of the synchronous JS API calls (`transformSync` and `buildSync`) when they are used from a thread other than the main thread. The problem happened because esbuild's new implementation uses node's `worker_threads` library internally and non-main threads were incorrectly assumed to be esbuild's internal thread instead of potentially another unrelated thread. Now esbuild's synchronous JS APIs should work correctly when called from non-main threads.\n\n## 0.12.12\n\n* Fix `file` loader import paths when subdirectories are present ([#1044](https://github.com/evanw/esbuild/issues/1044))\n\n    Using the `file` loader for a file type causes importing affected files to copy the file into the output directory and to embed the path to the copied file into the code that imported it. However, esbuild previously always embedded the path relative to the output directory itself. This is problematic when the importing code is generated within a subdirectory inside the output directory, since then the relative path is wrong. For example:\n\n    ```\n    $ cat src/example/entry.css\n    div {\n      background: url(../images/image.png);\n    }\n\n    $ esbuild --bundle src/example/entry.css --outdir=out --outbase=src --loader:.png=file\n\n    $ find out -type f\n    out/example/entry.css\n    out/image-55DNWN2R.png\n\n    $ cat out/example/entry.css\n    /* src/example/entry.css */\n    div {\n      background: url(./image-55DNWN2R.png);\n    }\n    ```\n\n    This is output from the previous version of esbuild. The above asset reference in `out/example/entry.css` is wrong. The path should start with `../` because the two files are in different directories.\n\n    With this release, the asset references present in output files will now be the full relative path from the output file to the asset, so imports should now work correctly when the entry point is in a subdirectory within the output directory. This change affects asset reference paths in both CSS and JS output files.\n\n    Note that if you want asset reference paths to be independent of the subdirectory in which they reside, you can use the `--public-path` setting to provide the common path that all asset reference paths should be constructed relative to. Specifically `--public-path=.` should bring back the old problematic behavior in case you need it.\n\n* Add support for `[dir]` in `--asset-names` ([#1196](https://github.com/evanw/esbuild/pull/1196))\n\n    You can now use path templates such as `--asset-names=[dir]/[name]-[hash]` to copy the input directory structure of your asset files (i.e. input files loaded with the `file` loader) to the output directory. Here's an example:\n\n    ```\n    $ cat entry.css\n    header {\n      background: url(images/common/header.png);\n    }\n    main {\n      background: url(images/home/hero.png);\n    }\n\n    $ esbuild --bundle entry.css --outdir=out --asset-names=[dir]/[name]-[hash] --loader:.png=file\n\n    $ find out -type f\n    out/images/home/hero-55DNWN2R.png\n    out/images/common/header-55DNWN2R.png\n    out/entry.css\n\n    $ cat out/entry.css\n    /* entry.css */\n    header {\n      background: url(./images/common/header-55DNWN2R.png);\n    }\n    main {\n      background: url(./images/home/hero-55DNWN2R.png);\n    }\n    ```\n\n## 0.12.11\n\n* Enable faster synchronous transforms with the JS API by default ([#1000](https://github.com/evanw/esbuild/issues/1000))\n\n    Currently the synchronous JavaScript API calls `transformSync` and `buildSync` spawn a new child process on every call. This is due to limitations with node's `child_process` API. Doing this means `transformSync` and `buildSync` are much slower than `transform` and `build`, which share the same child process across calls.\n\n    This release improves the performance of `transformSync` and `buildSync` by up to 20x. It enables a hack where node's `worker_threads` API and atomics are used to block the main thread while asynchronous communication with a single long-lived child process happens in a worker. Previously this was only enabled when the `ESBUILD_WORKER_THREADS` environment variable was set to `1`. But this experiment has been available for a while (since version 0.9.6) without any reported issues. Now this hack will be enabled by default. It can be disabled by setting `ESBUILD_WORKER_THREADS` to `0` before running node.\n\n* Fix nested output directories with WebAssembly on Windows ([#1399](https://github.com/evanw/esbuild/issues/1399))\n\n    Many functions in Go's standard library have a bug where they do not work on Windows when using Go with WebAssembly. This is a long-standing bug and is a fault with the design of the standard library, so it's unlikely to be fixed. Basically Go's standard library is designed to bake \"Windows or not\" decision into the compiled executable, but WebAssembly is platform-independent which makes \"Windows or not\" is a run-time decision instead of a compile-time decision. Oops.\n\n    I have been working around this by trying to avoid using path-related functions in the Go standard library and doing all path manipulation by myself instead. This involved completely replacing Go's `path/filepath` library. However, I missed the `os.MkdirAll` function which is also does path manipulation but is outside of the `path/filepath` package. This meant that nested output directories failed to be created on Windows, which caused a build error. This problem only affected the `esbuild-wasm` package.\n\n    This release manually reimplements nested output directory creation to work around this bug in the Go standard library. So nested output directories should now work on Windows with the `esbuild-wasm` package.\n\n## 0.12.10\n\n* Add a target for ES2021\n\n    It's now possible to use `--target=es2021` to target the newly-released JavaScript version ES2021. The only difference between that and `--target=es2020` is that logical assignment operators such as `a ||= b` are not converted to regular assignment operators such as `a || (a = b)`.\n\n* Minify the syntax `Infinity` to `1 / 0` ([#1385](https://github.com/evanw/esbuild/pull/1385))\n\n    The `--minify-syntax` flag (automatically enabled by `--minify`) will now minify the expression   `Infinity` to `1 / 0`, which uses fewer bytes:\n\n    ```js\n    // Original code\n    const a = Infinity;\n\n    // Output with \"--minify-syntax\"\n    const a = 1 / 0;\n    ```\n\n    This change was contributed by [@Gusted](https://github.com/Gusted).\n\n* Minify syntax in the CSS `transform` property ([#1390](https://github.com/evanw/esbuild/pull/1390))\n\n    This release includes various size reductions for CSS transform matrix syntax when minification is enabled:\n\n    ```css\n    /* Original code */\n    div {\n      transform: translate3d(0, 0, 10px) scale3d(200%, 200%, 1) rotate3d(0, 0, 1, 45deg);\n    }\n\n    /* Output with \"--minify-syntax\" */\n    div {\n      transform: translateZ(10px) scale(2) rotate(45deg);\n    }\n    ```\n\n    The `translate3d` to `translateZ` conversion was contributed by [@steambap](https://github.com/steambap).\n\n* Support for the case-sensitive flag in CSS attribute selectors ([#1397](https://github.com/evanw/esbuild/issues/1397))\n\n    You can now use the case-sensitive CSS attribute selector flag `s` such as in `[type=\"a\" s] { list-style: lower-alpha; }`. Previously doing this caused a warning about unrecognized syntax.\n\n## 0.12.9\n\n* Allow `this` with `--define` ([#1361](https://github.com/evanw/esbuild/issues/1361))\n\n    You can now override the default value of top-level `this` with the `--define` feature. Top-level `this` defaults to being `undefined` in ECMAScript modules and `exports` in CommonJS modules. For example:\n\n    ```js\n    // Original code\n    ((obj) => {\n      ...\n    })(this);\n\n    // Output with \"--define:this=window\"\n    ((obj) => {\n      ...\n    })(window);\n    ```\n\n    Note that overriding what top-level `this` is will likely break code that uses it correctly. So this new feature is only useful in certain cases.\n\n* Fix CSS minification issue with `!important` and duplicate declarations ([#1372](https://github.com/evanw/esbuild/issues/1372))\n\n    Previously CSS with duplicate declarations for the same property where the first one was marked with `!important` was sometimes minified incorrectly. For example:\n\n    ```css\n    .selector {\n      padding: 10px !important;\n      padding: 0;\n    }\n    ```\n\n    This was incorrectly minified as `.selector{padding:0}`. The bug affected three properties: `padding`, `margin`, and `border-radius`. With this release, this code will now be minified as `.selector{padding:10px!important;padding:0}` instead which means there is no longer a difference between minified and non-minified code in this case.\n\n## 0.12.8\n\n* Plugins can now specify `sideEffects: false` ([#1009](https://github.com/evanw/esbuild/issues/1009))\n\n    The default path resolution behavior in esbuild determines if a given file can be considered side-effect free (in the [Webpack-specific sense](https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free)) by reading the contents of the nearest enclosing `package.json` file and looking for `\"sideEffects\": false`. However, up until now this was impossible to achieve in an esbuild plugin because there was no way of returning this metadata back to esbuild.\n\n    With this release, esbuild plugins can now return `sideEffects: false` to mark a file as having no side effects. Here's an example:\n\n    ```js\n    esbuild.build({\n      entryPoints: ['app.js'],\n      bundle: true,\n      plugins: [{\n        name: 'env-plugin',\n        setup(build) {\n          build.onResolve({ filter: /^env$/ }, args => ({\n            path: args.path,\n            namespace: 'some-ns',\n            sideEffects: false,\n          }))\n          build.onLoad({ filter: /.*/, namespace: 'some-ns' }, () => ({\n            contents: `export default self.env || (self.env = getEnv())`,\n          }))\n        },\n      }],\n    })\n    ```\n\n    This plugin creates a virtual module that can be generated by importing the string `env`. However, since the plugin returns `sideEffects: false`, the generated virtual module will not be included in the bundle if all of the imported values from the module `env` end up being unused.\n\n    This feature was contributed by [@chriscasola](https://github.com/chriscasola).\n\n* Remove a warning about unsupported source map comments ([#1358](https://github.com/evanw/esbuild/issues/1358))\n\n    This removes a warning that indicated when a source map comment couldn't be supported. Specifically, this happens when you enable source map generation and esbuild encounters a file with a source map comment pointing to an external file but doesn't have enough information to know where to look for that external file (basically when the source file doesn't have an associated directory to use for path resolution). In this case esbuild can't respect the input source map because it cannot be located. The warning was annoying so it has been removed. Source maps still won't work, however.\n\n## 0.12.7\n\n* Quote object properties that are modern Unicode identifiers ([#1349](https://github.com/evanw/esbuild/issues/1349))\n\n    In ES6 and above, an identifier is a character sequence starting with a character in the `ID_Start` Unicode category and followed by zero or more characters in the `ID_Continue` Unicode category, and these categories must be drawn from Unicode version 5.1 or above.\n\n    But in ES5, an identifier is a character sequence starting with a character in one of the `Lu, Ll, Lt, Lm, Lo, Nl` Unicode categories and followed by zero or more characters in the `Lu, Ll, Lt, Lm, Lo, Nl, Mn, Mc, Nd, Pc` Unicode categories, and these categories must be drawn from Unicode version 3.0 or above.\n\n    Previously esbuild always used the ES6+ identifier validation test when deciding whether to use an identifier or a quoted string to encode an object property but with this release, it will use the ES5 validation test instead:\n\n    ```js\n    // Original code\n    x.ꓷꓶꓲꓵꓭꓢꓱ = { ꓷꓶꓲꓵꓭꓢꓱ: y };\n\n    // Old output\n    x.ꓷꓶꓲꓵꓭꓢꓱ = { ꓷꓶꓲꓵꓭꓢꓱ: y };\n\n    // New output\n    x[\"ꓷꓶꓲꓵꓭꓢꓱ\"] = { \"ꓷꓶꓲꓵꓭꓢꓱ\": y };\n    ```\n\n    This approach should ensure maximum compatibility with all JavaScript environments that support ES5 and above. Note that this means minified files containing Unicode properties may be slightly larger than before.\n\n* Ignore `tsconfig.json` files inside `node_modules` ([#1355](https://github.com/evanw/esbuild/issues/1355))\n\n    Package authors often publish their `tsconfig.json` files to npm because of npm's default-include publishing model and because these authors probably don't know about `.npmignore` files. People trying to use these packages with esbuild have historically complained that esbuild is respecting `tsconfig.json` in these cases. The assumption is that the package author published these files by accident.\n\n    With this release, esbuild will no longer respect `tsconfig.json` files when the source file is inside a `node_modules` folder. Note that `tsconfig.json` files inside `node_modules` are still parsed, and extending `tsconfig.json` files from inside a package is still supported.\n\n* Fix missing `--metafile` when using `--watch` ([#1357](https://github.com/evanw/esbuild/issues/1357))\n\n    Due to an oversight, the `--metafile` setting didn't work when `--watch` was also specified. This only affected the command-line interface. With this release, the `--metafile` setting should now work in this case.\n\n* Add a hidden `__esModule` property to modules in ESM format ([#1338](https://github.com/evanw/esbuild/pull/1338))\n\n    Module namespace objects from ESM files will now have a hidden `__esModule` property. This improves compatibility with code that has been converted from ESM syntax to CommonJS by Babel or TypeScript. For example:\n\n    ```js\n    // Input TypeScript code\n    import x from \"y\"\n    console.log(x)\n\n    // Output JavaScript code from the TypeScript compiler\n    var __importDefault = (this && this.__importDefault) || function (mod) {\n        return (mod && mod.__esModule) ? mod : { \"default\": mod };\n    };\n    Object.defineProperty(exports, \"__esModule\", { value: true });\n    const y_1 = __importDefault(require(\"y\"));\n    console.log(y_1.default);\n    ```\n\n    If the object returned by `require(\"y\")` doesn't have an `__esModule` property, then `y_1` will be the object `{ \"default\": require(\"y\") }`. If the file `\"y\"` is in ESM format and has a default export of, say, the value `null`, that means `y_1` will now be `{ \"default\": { \"default\": null } }` and you will need to use `y_1.default.default` to access the default value. Adding an automatically-generated `__esModule` property when converting files in ESM format to CommonJS is required to make this code work correctly (i.e. for the value to be accessible via just `y_1.default` instead).\n\n    With this release, code in ESM format will now have an automatically-generated `__esModule` property to satisfy this convention. The property is non-enumerable so it shouldn't show up when iterating over the properties of the object. As a result, the export name `__esModule` is now reserved for use with esbuild. It's now an error to create an export with the name `__esModule`.\n\n    This fix was contributed by [@lbwa](https://github.com/lbwa).\n\n## 0.12.6\n\n* Improve template literal lowering transformation conformance ([#1327](https://github.com/evanw/esbuild/issues/1327))\n\n    This release contains the following improvements to template literal lowering for environments that don't support tagged template literals natively (such as `--target=es5`):\n\n    * For tagged template literals, the arrays of strings that are passed to the tag function are now frozen and immutable. They are also now cached so they should now compare identical between multiple template evaluations:\n\n        ```js\n        // Original code\n        console.log(tag`\\u{10000}`)\n\n        // Old output\n        console.log(tag(__template([\"𐀀\"], [\"\\\\u{10000}\"])));\n\n        // New output\n        var _a;\n        console.log(tag(_a || (_a = __template([\"𐀀\"], [\"\\\\u{10000}\"]))));\n        ```\n\n    * For tagged template literals, the generated code size is now smaller in the common case where there are no escape sequences, since in that case there is no distinction between \"raw\" and \"cooked\" values:\n\n        ```js\n        // Original code\n        console.log(tag`some text without escape sequences`)\n\n        // Old output\n        console.log(tag(__template([\"some text without escape sequences\"], [\"some text without escape sequences\"])));\n\n        // New output\n        var _a;\n        console.log(tag(_a || (_a = __template([\"some text without escape sequences\"]))));\n        ```\n\n    * For non-tagged template literals, the generated code now uses chains of `.concat()` calls instead of string addition:\n\n        ```js\n        // Original code\n        console.log(`an ${example} template ${literal}`)\n\n        // Old output\n        console.log(\"an \" + example + \" template \" + literal);\n\n        // New output\n        console.log(\"an \".concat(example, \" template \").concat(literal));\n        ```\n\n        The old output was incorrect for several reasons including that `toString` must be called instead of `valueOf` for objects and that passing a `Symbol` instance should throw instead of converting the symbol to a string. Using `.concat()` instead of string addition fixes both of those correctness issues. And you can't use a single `.concat()` call because side effects must happen inline instead of at the end.\n\n* Only respect `target` in `tsconfig.json` when esbuild's target is not configured ([#1332](https://github.com/evanw/esbuild/issues/1332))\n\n    In version 0.12.4, esbuild began respecting the `target` setting in `tsconfig.json`. However, sometimes `tsconfig.json` contains target values that should not be used. With this release, esbuild will now only use the `target` value in `tsconfig.json` as the language level when esbuild's `target` setting is not configured. If esbuild's `target` setting is configured then the `target` value in `tsconfig.json` is now ignored.\n\n* Fix the order of CSS imported from JS ([#1342](https://github.com/evanw/esbuild/pull/1342))\n\n    Importing CSS from JS when bundling causes esbuild to generate a sibling CSS output file next to the resulting JS output file containing the bundled CSS. The order of the imported CSS files in the output was accidentally the inverse order of the order in which the JS files were evaluated. Instead the order of the imported CSS files should match the order in which the JS files were evaluated. This fix was contributed by [@dmitrage](https://github.com/dmitrage).\n\n* Fix an edge case with transforming `export default class` ([#1346](https://github.com/evanw/esbuild/issues/1346))\n\n    Statements of the form `export default class x {}` were incorrectly transformed to `class x {} var y = x; export {y as default}` instead of `class x {} export {x as default}`. Transforming these statements like this is incorrect in the rare case that the class is later reassigned by name within the same file such as `export default class x {} x = null`. Here the imported value should be `null` but was incorrectly the class object instead. This is unlikely to matter in real-world code but it has still been fixed to improve correctness.\n\n## 0.12.5\n\n* Add support for lowering tagged template literals to ES5 ([#297](https://github.com/evanw/esbuild/issues/297))\n\n    This release adds support for lowering tagged template literals such as `` String.raw`\\unicode` `` to target environments that don't support them such as `--target=es5` (non-tagged template literals were already supported). Each literal turns into a function call to a helper function:\n\n    ```js\n    // Original code\n    console.log(String.raw`\\unicode`)\n\n    // Lowered code\n    console.log(String.raw(__template([void 0], [\"\\\\unicode\"])));\n    ```\n\n* Change class field behavior to match TypeScript 4.3\n\n    TypeScript 4.3 includes a subtle breaking change that wasn't mentioned in the [TypeScript 4.3 blog post](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3/): class fields will now be compiled with different semantics if `\"target\": \"ESNext\"` is present in `tsconfig.json`. Specifically in this case `useDefineForClassFields` will default to `true` when not specified instead of `false`. This means class field behavior in TypeScript code will now match JavaScript instead of doing something else:\n\n    ```js\n    class Base {\n      set foo(value) { console.log('set', value) }\n    }\n    class Derived extends Base {\n      foo = 123\n    }\n    new Derived()\n    ```\n\n    In TypeScript 4.2 and below, the TypeScript compiler would generate code that prints `set 123` when `tsconfig.json` contains `\"target\": \"ESNext\"` but in TypeScript 4.3, the TypeScript compiler will now generate code that doesn't print anything. This is the difference between \"assign\" semantics and \"define\" semantics. With this release, esbuild has been changed to follow the TypeScript 4.3 behavior.\n\n* Avoid generating the character sequence `</script>` ([#1322](https://github.com/evanw/esbuild/issues/1322))\n\n    If the output of esbuild is inlined into a `<script>...</script>` tag inside an HTML file, the character sequence `</script>` inside the JavaScript code will accidentally cause the script tag to be terminated early. There are at least four such cases where this can happen:\n\n    ```js\n    console.log('</script>')\n    console.log(1</script>/.exec(x).length)\n    console.log(String.raw`</script>`)\n    // @license </script>\n    ```\n\n    With this release, esbuild will now handle all of these cases and avoid generating the problematic character sequence:\n\n    ```js\n    console.log('<\\/script>');\n    console.log(1< /script>/.exec(x).length);\n    console.log(String.raw(__template([\"<\\/script>\"], [\"<\\/script>\"])));\n    // @license <\\/script>\n    ```\n\n* Change the triple-slash reference comment for Deno ([#1325](https://github.com/evanw/esbuild/issues/1325))\n\n    The comment in esbuild's JavaScript API implementation for Deno that references the TypeScript type declarations has been changed from `/// <reference path=\"./mod.d.ts\" />` to `/// <reference types=\"./mod.d.ts\" />`. This comment was copied from Deno's documentation but apparently Deno's documentation was incorrect. The comment in esbuild's Deno bundle has been changed to reflect Deno's latest documentation.\n\n## 0.12.4\n\n* Reorder name preservation before TypeScript decorator evaluation ([#1316](https://github.com/evanw/esbuild/issues/1316))\n\n    The `--keep-names` option ensures the `.name` property on functions and classes remains the same after bundling. However, this was being enforced after TypeScript decorator evaluation which meant that the decorator could observe the incorrect name. This has been fixed and now `.name` preservation happens before decorator evaluation instead.\n\n* Potential fix for a determinism issue ([#1304](https://github.com/evanw/esbuild/issues/1304))\n\n    This release contains a potential fix for an unverified issue with non-determinism in esbuild. The regression was apparently introduced in 0.11.13 and may be related to parallelism that was introduced around the point where dynamic `import()` expressions are added to the list of entry points. Hopefully this fix should resolve the regression.\n\n* Respect `target` in `tsconfig.json` ([#277](https://github.com/evanw/esbuild/issues/277))\n\n    Each JavaScript file that esbuild bundles will now be transformed according to the [`target`](https://www.typescriptlang.org/tsconfig#target) language level from the nearest enclosing `tsconfig.json` file. This is in addition to esbuild's own `--target` setting; the two settings are merged by transforming any JavaScript language feature that is unsupported in either esbuild's configured `--target` value or the `target` property in the `tsconfig.json` file.\n\n## 0.12.3\n\n* Ensure JSX element names start with a capital letter ([#1309](https://github.com/evanw/esbuild/issues/1309))\n\n    The JSX specification only describes the syntax and says nothing about how to interpret it. But React (and therefore esbuild) treats JSX tags that start with a lower-case ASCII character as strings instead of identifiers. That way the tag `<i/>` always refers to the italic HTML element `i` and never to a local variable named `i`.\n\n    However, esbuild may rename identifiers for any number of reasons such as when minification is enabled. Previously esbuild could sometimes rename identifiers used as tag names such that they start with a lower-case ASCII character. This is problematic when JSX syntax preservation is enabled since subsequent JSX processing would then turn these identifier references into strings.\n\n    With this release, esbuild will now make sure identifiers used in tag names start with an upper-case ASCII character instead when JSX syntax preservation is enabled. This should avoid problems when using esbuild with JSX transformation tools.\n\n* Fix a single hyphen being treated as a CSS name ([#1310](https://github.com/evanw/esbuild/pull/1310))\n\n    CSS identifiers are allowed to start with a `-` character if (approximately) the following character is a letter, an escape sequence, a non-ASCII character, the character `_`, or another `-` character. This check is used in certain places when printing CSS to determine whether a token is a valid identifier and can be printed as such or whether it's an invalid identifier and needs to be quoted as a string. One such place is in attribute selectors such as `[a*=b]`.\n\n    However, esbuild had a bug where a single `-` character was incorrectly treated as a valid identifier in this case. This is because the end of string became U+FFFD (the Unicode replacement character) which is a non-ASCII character and a valid name-start code point. With this release a single `-` character is no longer treated as a valid identifier. This fix was contributed by [@lbwa](https://github.com/lbwa).\n\n## 0.12.2\n\n* Fix various code generation and minification issues ([#1305](https://github.com/evanw/esbuild/issues/1305))\n\n    This release fixes the following issues, which were all identified by running esbuild against the latest UglifyJS test suite:\n\n    * The `in` operator is now surrounded parentheses inside arrow function expression bodies inside `for` loop initializers:\n\n        ```js\n        // Original code\n        for ((x => y in z); 0; ) ;\n\n        // Old output\n        for ((x) => y in z; 0; ) ;\n\n        // New output\n        for ((x) => (y in z); 0; ) ;\n        ```\n\n        Without this, the `in` operator would cause the for loop to be considered a for-in loop instead.\n\n    * The statement `return undefined;` is no longer minified to `return;` inside async generator functions:\n\n        ```js\n        // Original code\n        return undefined;\n\n        // Old output\n        return;\n\n        // New output\n        return void 0;\n        ```\n\n        Using `return undefined;` inside an async generator function has the same effect as `return await undefined;` which schedules a task in the event loop and runs code in a different order than just `return;`, which doesn't hide an implicit `await` expression.\n\n    * Property access expressions are no longer inlined in template tag position:\n\n        ```js\n        // Original code\n        (null, a.b)``, (null, a[b])``;\n\n        // Old output\n        a.b``, a[b]``;\n\n        // New output\n        (0, a.b)``, (0, a[b])``;\n        ```\n\n        The expression `` a.b`c` `` is different than the expression `` (0, a.b)`c` ``. The first calls the function `a.b` with `a` as the value for `this` but the second calls the function `a.b` with the default value for `this` (the global object in non-strict mode or `undefined` in strict mode).\n\n    * Verbatim `__proto__` properties inside object spread are no longer inlined when minifying:\n\n        ```js\n        // Original code\n        x = { ...{ __proto__: { y: true } } }.y;\n\n        // Old output\n        x = { __proto__: { y: !0 } }.y;\n\n        // New output\n        x = { ...{ __proto__: { y: !0 } } }.y;\n        ```\n\n        A verbatim (i.e. non-computed non-method) property called `__proto__` inside an object literal actually sets the prototype of the surrounding object literal. It does not add an \"own property\" called `__proto__` to that object literal, so inlining it into the parent object literal would be incorrect. The presence of a `__proto__` property now stops esbuild from applying the object spread inlining optimization when minifying.\n\n    * The value of `this` has now been fixed for lowered private class members that are used as template tags:\n\n        ```js\n        // Original code\n        x = (new (class {\n          a = this.#c``;\n          b = 1;\n          #c() { return this }\n        })).a.b;\n\n        // Old output\n        var _c, c_fn, _a;\n        x = new (_a = class {\n          constructor() {\n            __privateAdd(this, _c);\n            __publicField(this, \"a\", __privateMethod(this, _c, c_fn)``);\n            __publicField(this, \"b\", 1);\n          }\n        }, _c = new WeakSet(), c_fn = function() {\n          return this;\n        }, _a)().a.b;\n\n        // New output\n        var _c, c_fn, _a;\n        x = new (_a = class {\n          constructor() {\n            __privateAdd(this, _c);\n            __publicField(this, \"a\", __privateMethod(this, _c, c_fn).bind(this)``);\n            __publicField(this, \"b\", 1);\n          }\n        }, _c = new WeakSet(), c_fn = function() {\n          return this;\n        }, _a)().a.b;\n        ```\n\n        The value of `this` here should be an instance of the class because the template tag is a property access expression. However, it was previously the default value (the global object in non-strict mode or `undefined` in strict mode) instead due to the private member transformation, which is incorrect.\n\n    * Invalid escape sequences are now allowed in tagged template literals\n\n        This implements the template literal revision feature: https://github.com/tc39/proposal-template-literal-revision. It allows you to process tagged template literals using custom semantics that don't follow JavaScript escape sequence rules without causing a syntax error:\n\n        ```js\n        console.log((x => x.raw)`invalid \\unicode escape sequence`)\n        ```\n\n## 0.12.1\n\n* Add the ability to preserve JSX syntax ([#735](https://github.com/evanw/esbuild/issues/735))\n\n    You can now pass `--jsx=preserve` to esbuild to prevent JSX from being transformed into JS. Instead, JSX syntax in all input files is preserved throughout the pipeline and is printed as JSX syntax in the generated output files. Note that this means the output files are no longer valid JavaScript code if you enable this setting. This feature is intended to be used when you want to transform the JSX syntax in esbuild's output files by another tool after bundling, usually one with a different JSX-to-JS transform than the one esbuild implements.\n\n* Update the list of built-in node modules ([#1294](https://github.com/evanw/esbuild/issues/1294))\n\n    The list of built-in modules that come with node was outdated, so it has been updated. It now includes new modules such as `wasi` and `_http_common`. Modules in this list are automatically marked as external when esbuild's platform is configured to `node`.\n\n## 0.12.0\n\n**This release contains backwards-incompatible changes.** Since esbuild is before version 1.0.0, these changes have been released as a new minor version to reflect this (as [recommended by npm](https://docs.npmjs.com/cli/v6/using-npm/semver/)). You should either be pinning the exact version of `esbuild` in your `package.json` file or be using a version range syntax that only accepts patch upgrades such as `~0.11.0`. See the documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\nThe breaking changes in this release relate to CSS import order and also build scenarios where both the `inject` and `define` API options are used (see below for details). These breaking changes are as follows:\n\n* Fix bundled CSS import order ([#465](https://github.com/evanw/esbuild/issues/465))\n\n    JS and CSS use different import ordering algorithms. In JS, importing a file that has already been imported is a no-op but in CSS, importing a file that has already been imported re-imports the file. A simple way to imagine this is to view each `@import` rule in CSS as being replaced by the contents of that file similar to `#include` in C/C++. However, this is incorrect in the case of `@import` cycles because it would cause infinite expansion. A more accurate way to imagine this is that in CSS, a file is evaluated at the *last* `@import` location while in JS, a file is evaluated at the *first* `import` location.\n\n    Previously esbuild followed JS import order rules for CSS but now esbuild will follow CSS import order rules. This is a breaking change because it means your CSS may behave differently when bundled. Note that CSS import order rules are somewhat unintuitive because evaluation order matters. In CSS, using `@import` multiple times can end up unintentionally erasing overriding styles. For example, consider the following files:\n\n    ```css\n    /* entry.css */\n    @import \"./color.css\";\n    @import \"./background.css\";\n    ```\n\n    ```css\n    /* color.css */\n    @import \"./reset.css\";\n    body {\n      color: white;\n    }\n    ```\n\n    ```css\n    /* background.css */\n    @import \"./reset.css\";\n    body {\n      background: black;\n    }\n    ```\n\n    ```css\n    /* reset.css */\n    body {\n      background: white;\n      color: black;\n    }\n    ```\n\n    Because of how CSS import order works, `entry.css` will now be bundled like this:\n\n    ```css\n    /* color.css */\n    body {\n      color: white;\n    }\n\n    /* reset.css */\n    body {\n      background: white;\n      color: black;\n    }\n\n    /* background.css */\n    body {\n      background: black;\n    }\n    ```\n\n    This means the body will unintuitively be all black! The file `reset.css` is evaluated at the location of the *last* `@import` instead of the *first* `@import`. The fix for this case is to remove the nested imports of `reset.css` and to import `reset.css` exactly once at the top of `entry.css`.\n\n    Note that while the evaluation order of external CSS imports is preserved with respect to other external CSS imports, the evaluation order of external CSS imports is *not* preserved with respect to other internal CSS imports. All external CSS imports are \"hoisted\" to the top of the bundle. The alternative would be to generate many smaller chunks which is usually undesirable. So in this case esbuild's CSS bundling behavior will not match the browser.\n\n* Fix bundled CSS when using JS code splitting ([#608](https://github.com/evanw/esbuild/issues/608))\n\n    Previously esbuild generated incorrect CSS output when JS code splitting was enabled and the JS code being bundled imported CSS files. CSS code that was reachable via multiple JS entry points was split off into a shared CSS chunk, but that chunk was not actually imported anywhere so the shared CSS was missing. This happened because both CSS and JS code splitting were experimental features that are still in progress and weren't tested together.\n\n    Now esbuild's CSS output should contain all reachable CSS code when JS code splitting is enabled. Note that this does *not* mean code splitting works for CSS files. Each CSS output file simply contains the transitive set of all CSS reachable from the JS entry point including through dynamic `import()` and `require()` expressions. Specifically, the bundler constructs a virtual CSS file for each JS entry point consisting only of `@import` rules for each CSS file imported into a JS file. These `@import` rules are constructed in JS source order, but then the bundler uses CSS import order from that point forward to bundle this virtual CSS file into the final CSS output file.\n\n    This model makes the most sense when CSS files are imported into JS files via JS `import` statements. Importing CSS via `import()` and `require()` (either directly or transitively through multiple intermediate JS files) should still \"work\" in the sense that all reachable CSS should be included in the output, but in this case esbuild will pick an arbitrary (but consistent) import order. The import order may not match the order that the JS files are evaluated in because JS evaluation order of dynamic imports is only determined at run-time while CSS bundling happens at compile-time.\n\n    It's possible to implement code splitting for CSS such that CSS code used between multiple entry points is shared. However, CSS lacks a mechanism for \"lazily\" importing code (i.e. disconnecting the import location with the evaluation location) so CSS code splitting could potentially need to generate a huge number of very small chunks to preserve import order. It's unclear if this would end up being a net win or not as far as browser download time. So sharing-based code splitting is currently not supported for CSS.\n\n    It's theoretically possible to implement code splitting for CSS such that CSS from a dynamically-imported JS file (e.g. via `import()`) is placed into a separate chunk. However, due to how `@import` order works this would in theory end up re-evaluating all shared dependencies which could overwrite overloaded styles and unintentionally change the way the page is rendered. For example, constructing a single-page app architecture such that each page is JS-driven and can transition to other JS-driven pages via `import()` could end up with pages that look different depending on what order you visit them in. This is clearly undesirable. The simple way to address this is to just not support dynamic-import code splitting for CSS either.\n\n* Change \"define\" to have higher priority than \"inject\" ([#660](https://github.com/evanw/esbuild/issues/660))\n\n    The \"define\" and \"inject\" features are both ways of replacing certain expressions in your source code with other things expressions. Previously esbuild's behavior ran \"inject\" before \"define\", which could lead to some undesirable behavior. For example (from the `react` npm package):\n\n    ```js\n    if (process.env.NODE_ENV === 'production') {\n      module.exports = require('./cjs/react.production.min.js');\n    } else {\n      module.exports = require('./cjs/react.development.js');\n    }\n    ```\n\n    If you use \"define\" to replace `process.env.NODE_ENV` with `\"production\"` and \"inject\" to replace `process` with a shim that emulates node's process API, then `process` was previously replaced first and then `process.env.NODE_ENV` wasn't matched because `process` referred to the injected shim. This wasn't ideal because it means esbuild didn't detect the branch condition as a constant (since it doesn't know how the shim behaves at run-time) and bundled both the development and production versions of the package.\n\n    With this release, esbuild will now run \"define\" before \"inject\". In the above example this means that `process.env.NODE_ENV` will now be replaced with `\"production\"`, the injected shim will not be included, and only the production version of the package will be bundled. This feature was contributed by [@rtsao](https://github.com/rtsao).\n\nIn addition to the breaking changes above, the following features are also included in this release:\n\n* Add support for the `NO_COLOR` environment variable\n\n    The CLI will now omit color if the `NO_COLOR` environment variable is present, which is an existing convention that is followed by some other software. See https://no-color.org/ for more information.\n\n## 0.11.23\n\n* Add a shim function for unbundled uses of `require` ([#1202](https://github.com/evanw/esbuild/issues/1202))\n\n    Modules in CommonJS format automatically get three variables injected into their scope: `module`, `exports`, and `require`. These allow the code to import other modules and to export things from itself. The bundler automatically rewrites uses of `module` and `exports` to refer to the module's exports and certain uses of `require` to a helper function that loads the imported module.\n\n    Not all uses of `require` can be converted though, and un-converted uses of `require` will end up in the output. This is problematic because `require` is only present at run-time if the output is run as a CommonJS module. Otherwise `require` is undefined, which means esbuild's behavior is inconsistent between compile-time and run-time. The `module` and `exports` variables are objects at compile-time and run-time but `require` is a function at compile-time and undefined at run-time. This causes code that checks for `typeof require` to have inconsistent behavior:\n\n    ```js\n    if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') {\n      console.log('CommonJS detected')\n    }\n    ```\n\n    In the above example, ideally `CommonJS detected` would always be printed since the code is being bundled with a CommonJS-aware bundler. To fix this, esbuild will now substitute references to `require` with a stub `__require` function when bundling if the output format is something other than CommonJS. This should ensure that `require` is now consistent between compile-time and run-time. When bundled, code that uses unbundled references to `require` will now look something like this:\n\n    ```js\n    var __require = (x) => {\n      if (typeof require !== \"undefined\")\n        return require(x);\n      throw new Error('Dynamic require of \"' + x + '\" is not supported');\n    };\n\n    var __commonJS = (cb, mod) => () => (mod || cb((mod = {exports: {}}).exports, mod), mod.exports);\n\n    var require_example = __commonJS((exports, module) => {\n      if (typeof __require === \"function\" && typeof exports === \"object\" && typeof module === \"object\") {\n        console.log(\"CommonJS detected\");\n      }\n    });\n\n    require_example();\n    ```\n\n* Fix incorrect caching of internal helper function library ([#1292](https://github.com/evanw/esbuild/issues/1292))\n\n    This release fixes a bug where running esbuild multiple times with different configurations sometimes resulted in code that would crash at run-time. The bug was introduced in version 0.11.19 and happened because esbuild's internal helper function library is parsed once and cached per configuration, but the new profiler name option was accidentally not included in the cache key. This option is now included in the cache key so this bug should now be fixed.\n\n* Minor performance improvements\n\n    This release contains some small performance improvements to offset an earlier minor performance regression due to the addition of certain features such as hashing for entry point files. The benchmark times on the esbuild website should now be accurate again (versions of esbuild after the regression but before this release were slightly slower than the benchmark).\n\n## 0.11.22\n\n* Add support for the \"import assertions\" proposal\n\n    This is new JavaScript syntax that was shipped in Chrome 91. It looks like this:\n\n    ```js\n    import './foo.json' assert { type: 'json' }\n    import('./bar.json', { assert: { type: 'json' } })\n    ```\n\n    On the web, the content type for a given URL is determined by the `Content-Type` HTTP header instead of the file extension. So adding support for importing non-JS content types such as JSON to the web could cause [security issues](https://github.com/WICG/webcomponents/issues/839) since importing JSON from an untrusted source is safe while importing JS from an untrusted source is not.\n\n    Import assertions are a new feature to address this security concern and unblock non-JS content types on the web. They cause the import to fail if the `Content-Type` header doesn't match the expected value. This prevents security issues for data-oriented content types such as JSON since it guarantees that data-oriented content will never accidentally be evaluated as code instead of data. More information about the proposal is available here: https://github.com/tc39/proposal-import-assertions.\n\n    This release includes support for parsing and printing import assertions. They will be printed if the configured target environment supports them (currently only in `esnext` and `chrome91`), otherwise they will be omitted. If they aren't supported in the configured target environment and it's not possible to omit them, which is the case for certain dynamic `import()` expressions, then using them is a syntax error. Import assertions are otherwise unused by the bundler.\n\n* Forbid the token sequence `for ( async of` when not followed by `=>`\n\n    This follows a recently-fixed ambiguity in the JavaScript specification, which you can read about here: https://github.com/tc39/ecma262/pull/2256. Prior to this change in the specification, it was ambiguous whether this token sequence should be parsed as `for ( async of =>` or `for ( async of ;`. V8 and esbuild expected `=>` after `for ( async of` while SpiderMonkey and JavaScriptCore did something else.\n\n    The ambiguity has been removed and the token sequence `for ( async of` is now forbidden by the specification when not followed by `=>`, so esbuild now forbids this as well. Note that the token sequence `for await (async of` is still allowed even when not followed by `=>`. Code such as `for ((async) of []) ;` is still allowed and will now be printed with parentheses to avoid the grammar ambiguity.\n\n* Restrict `super` property access to inside of methods\n\n    You can now only use `super.x` and `super[x]` expressions inside of methods. Previously these expressions were incorrectly allowed everywhere. This means esbuild now follows the JavaScript language specification more closely.\n\n## 0.11.21\n\n* TypeScript `override` for parameter properties ([#1262](https://github.com/evanw/esbuild/pull/1262))\n\n    You can now use the `override` keyword instead of or in addition to the `public`, `private`, `protected`, and `readonly` keywords for declaring a TypeScript parameter property:\n\n    ```ts\n    class Derived extends Base {\n      constructor(override field: any) {\n      }\n    }\n    ```\n\n    This feature was [recently added to the TypeScript compiler](https://github.com/microsoft/TypeScript/pull/43831) and will presumably be in an upcoming version of the TypeScript language. Support for this feature in esbuild was contributed by [@g-plane](https://github.com/g-plane).\n\n* Fix duplicate export errors due to TypeScript import-equals statements ([#1283](https://github.com/evanw/esbuild/issues/1283))\n\n    TypeScript has a special import-equals statement that is not part of JavaScript. It looks like this:\n\n    ```ts\n    import a = foo.a\n    import b = a.b\n    import c = b.c\n\n    import x = foo.x\n    import y = x.y\n    import z = y.z\n\n    export let bar = c\n    ```\n\n    Each import can be a type or a value and type-only imports need to be eliminated when converting this code to JavaScript, since types do not exist at run-time. The TypeScript compiler generates the following JavaScript code for this example:\n\n    ```js\n    var a = foo.a;\n    var b = a.b;\n    var c = b.c;\n    export let bar = c;\n    ```\n\n    The `x`, `y`, and `z` import statements are eliminated in esbuild by iterating over imports and exports multiple times and continuing to remove unused TypeScript import-equals statements until none are left. The first pass removes `z` and marks `y` as unused, the second pass removes `y` and marks `x` as unused, and the third pass removes `x`.\n\n    However, this had the side effect of making esbuild incorrectly think that a single export is exported twice (because it's processed more than once). This release fixes that bug by only iterating multiple times over imports, not exports. There should no longer be duplicate export errors for this case.\n\n* Add support for type-only TypeScript import-equals statements ([#1285](https://github.com/evanw/esbuild/pull/1285))\n\n    This adds support for the following new TypeScript syntax that was added in version 4.2:\n\n    ```ts\n    import type React = require('react')\n    ```\n\n    Unlike `import React = require('react')`, this statement is a type declaration instead of a value declaration and should be omitted from the generated code. See [microsoft/TypeScript#41573](https://github.com/microsoft/TypeScript/pull/41573) for details. This feature was contributed by [@g-plane](https://github.com/g-plane).\n\n## 0.11.20\n\n* Omit warning about duplicate JSON keys from inside `node_modules` ([#1254](https://github.com/evanw/esbuild/issues/1254))\n\n    This release no longer warns about duplicate keys inside `package.json` files inside `node_modules`. There are packages like this that are published to npm, and this warning is unactionable. Now esbuild will only issue this warning outside of `node_modules` directories.\n\n* Add CSS minification for `box-shadow` values\n\n    The CSS `box-shadow` property is now minified when `--mangle-syntax` is enabled. This includes trimming length values and minifying color representations.\n\n* Fix object spread transform for non-spread getters ([#1259](https://github.com/evanw/esbuild/issues/1259))\n\n    When transforming an object literal containing object spread (the `...` syntax), properties inside the spread should be evaluated but properties outside the spread should not be evaluated. Previously esbuild's object spread transform incorrectly evaluated properties in both cases. Consider this example:\n\n    ```js\n    var obj = {\n      ...{ get x() { console.log(1) } },\n      get y() { console.log(3) },\n    }\n    console.log(2)\n    obj.y\n    ```\n\n    This should print out `1 2 3` because the non-spread getter should not be evaluated. Instead, esbuild was incorrectly transforming this into code that printed `1 3 2`. This issue should now be fixed with this release.\n\n* Prevent private class members from being added more than once\n\n    This fixes a corner case with the private class member implementation. Constructors in JavaScript can return an object other than `this`, so private class members can actually be added to objects other than `this`. This can be abused to attach completely private metadata to other objects:\n\n    ```js\n    class Base {\n      constructor(x) {\n        return x\n      }\n    }\n    class Derived extends Base {\n      #y\n      static is(z) {\n        return #y in z\n      }\n    }\n    const foo = {}\n    new Derived(foo)\n    console.log(Derived.is(foo)) // true\n    ```\n\n    This already worked in code transformed by esbuild for older browsers. However, calling `new Derived(foo)` multiple times in the above code was incorrectly allowed. This should not be allowed because it would mean that the private field `#y` would be re-declared. This is no longer allowed starting from this release.\n\n## 0.11.19\n\n* Allow esbuild to be restarted in Deno ([#1238](https://github.com/evanw/esbuild/pull/1238))\n\n    The esbuild API for [Deno](https://deno.land) has an extra function called `stop()` that doesn't exist in esbuild's API for node. This is because Deno doesn't provide a way to stop esbuild automatically, so calling `stop()` is required to allow Deno to exit. However, once stopped the esbuild API could not be restarted.\n\n    With this release, you can now continue to use esbuild after calling `stop()`. This will restart esbuild's API and means that you will need to call `stop()` again for Deno to be able to exit. This feature was contributed by [@lucacasonato](https://github.com/lucacasonato).\n\n* Fix code splitting edge case ([#1252](https://github.com/evanw/esbuild/issues/1252))\n\n    This release fixes an edge case where bundling with code splitting enabled generated incorrect code if multiple ESM entry points re-exported the same re-exported symbol from a CommonJS file. In this case the cross-chunk symbol dependency should be the variable that holds the return value from the `require()` call instead of the original ESM named `import` clause item. When this bug occurred, the generated ESM code contained an export and import for a symbol that didn't exist, which caused a module initialization error. This case should now work correctly.\n\n* Fix code generation with `declare` class fields ([#1242](https://github.com/evanw/esbuild/issues/1242))\n\n    This fixes a bug with TypeScript code that uses `declare` on a class field and your `tsconfig.json` file has `\"useDefineForClassFields\": true`. Fields marked as `declare` should not be defined in the generated code, but they were incorrectly being declared as `undefined`. These fields are now correctly omitted from the generated code.\n\n* Annotate module wrapper functions in debug builds ([#1236](https://github.com/evanw/esbuild/pull/1236))\n\n    Sometimes esbuild needs to wrap certain modules in a function when bundling. This is done both for lazy evaluation and for CommonJS modules that use a top-level `return` statement. Previously these functions were all anonymous, so stack traces for errors thrown during initialization looked like this:\n\n    ```\n    Error: Electron failed to install correctly, please delete node_modules/electron and try installing again\n        at getElectronPath (out.js:16:13)\n        at out.js:19:21\n        at out.js:1:45\n        at out.js:24:3\n        at out.js:1:45\n        at out.js:29:3\n        at out.js:1:45\n        at Object.<anonymous> (out.js:33:1)\n    ```\n\n    This release adds names to these anonymous functions when minification is disabled. The above stack trace now looks like this:\n\n    ```\n    Error: Electron failed to install correctly, please delete node_modules/electron and try installing again\n        at getElectronPath (out.js:19:15)\n        at node_modules/electron/index.js (out.js:22:23)\n        at __require (out.js:2:44)\n        at src/base/window.js (out.js:29:5)\n        at __require (out.js:2:44)\n        at src/base/kiosk.js (out.js:36:5)\n        at __require (out.js:2:44)\n        at Object.<anonymous> (out.js:41:1)\n    ```\n\n    This is similar to Webpack's development-mode behavior:\n\n    ```\n    Error: Electron failed to install correctly, please delete node_modules/electron and try installing again\n        at getElectronPath (out.js:23:11)\n        at Object../node_modules/electron/index.js (out.js:27:18)\n        at __webpack_require__ (out.js:96:41)\n        at Object../src/base/window.js (out.js:49:1)\n        at __webpack_require__ (out.js:96:41)\n        at Object../src/base/kiosk.js (out.js:38:1)\n        at __webpack_require__ (out.js:96:41)\n        at out.js:109:1\n        at out.js:111:3\n        at Object.<anonymous> (out.js:113:12)\n    ```\n\n    These descriptive function names will additionally be available when using a profiler such as the one included in the \"Performance\" tab in Chrome Developer Tools. Previously all functions were named `(anonymous)` which made it difficult to investigate performance issues during bundle initialization.\n\n* Add CSS minification for more cases\n\n    The following CSS minification cases are now supported:\n\n    * The CSS `margin` property family is now minified including combining the `margin-top`, `margin-right`, `margin-bottom`, and `margin-left` properties into a single `margin` property.\n\n    * The CSS `padding` property family is now minified including combining the `padding-top`, `padding-right`, `padding-bottom`, and `padding-left` properties into a single `padding` property.\n\n    * The CSS `border-radius` property family is now minified including combining the `border-top-left-radius`, `border-top-right-radius`, `border-bottom-right-radius`, and `border-bottom-left-radius` properties into a single `border-radius` property.\n\n    * The four special pseudo-elements `::before`, `::after`, `::first-line`, and `::first-letter` are allowed to be parsed with one `:` for legacy reasons, so the `::` is now converted to `:` for these pseudo-elements.\n\n    * Duplicate CSS rules are now deduplicated. Only the last rule is kept, since that's the only one that has any effect. This applies for both top-level rules and nested rules.\n\n* Preserve quotes around properties when minification is disabled ([#1251](https://github.com/evanw/esbuild/issues/1251))\n\n    Previously the parser did not distinguish between unquoted and quoted properties, since there is no semantic difference. However, some tools such as [Google Closure Compiler](https://developers.google.com/closure/compiler) with \"advanced mode\" enabled attach their own semantic meaning to quoted properties, and processing code intended for Google Closure Compiler's advanced mode with esbuild was changing those semantics. The distinction between unquoted and quoted properties is now made in the following cases:\n\n    ```js\n    import * as ns from 'external-pkg'\n    console.log([\n      { x: 1, 'y': 2 },\n      { x() {}, 'y'() {} },\n      class { x = 1; 'y' = 2 },\n      class { x() {}; 'y'() {} },\n      { x: x, 'y': y } = z,\n      [x.x, y['y']],\n      [ns.x, ns['y']],\n    ])\n    ```\n\n    The parser will now preserve the quoted properties in these cases as long as `--minify-syntax` is not enabled. This does not mean that esbuild is officially supporting Google Closure Compiler's advanced mode, just that quoted properties are now preserved when the AST is pretty-printed. Google Closure Compiler's advanced mode accepts a language that shares syntax with JavaScript but that deviates from JavaScript semantics and there could potentially be other situations where preprocessing code intended for Google Closure Compiler's advanced mode with esbuild first causes it to break. If that happens, that is not a bug with esbuild.\n\n## 0.11.18\n\n* Add support for OpenBSD on x86-64 ([#1235](https://github.com/evanw/esbuild/issues/1235))\n\n    Someone has asked for OpenBSD to be supported on x86-64. It should now be supported starting with this release.\n\n* Fix an incorrect warning about top-level `this`\n\n    This was introduced in the previous release, and happens when using a top-level `async` arrow function with a compilation target that doesn't support it. The reason is that doing this generates a shim that preserves the value of `this`. However, this warning message is confusing because there is not necessarily any `this` present in the source code. The warning message has been removed in this case. Now it should only show up if `this` is actually present in the source code.\n\n## 0.11.17\n\n* Fix building with a large `stdin` string with Deno ([#1219](https://github.com/evanw/esbuild/issues/1219))\n\n    When I did the initial port of esbuild's node-based API to Deno, I didn't realize that Deno's `write(bytes)` function doesn't actually write the provided bytes. Instead it may only write some of those bytes and needs to be repeatedly called again until it writes everything. This meant that calling esbuild's Deno-based API could hang if the API request was large enough, which can happen in practice when using the `stdin` string feature. The `write` API is now called in a loop so these hangs in Deno should now be fixed.\n\n* Add a warning about replacing `this` with `undefined` in ESM code ([#1225](https://github.com/evanw/esbuild/issues/1225))\n\n    There is existing JavaScript code that sometimes references top-level `this` as a way to access the global scope. However, top-level `this` is actually specified to be `undefined` inside of ECMAScript module code, which makes referencing top-level `this` inside ESM code useless. This issue can come up when the existing JavaScript code is adapted for ESM by adding `import` and/or `export`. All top-level references to `this` are replaced with `undefined` when bundling to make sure ECMAScript module behavior is emulated correctly regardless of the environment in which the resulting code is run.\n\n    With this release, esbuild will now warn about this when bundling:\n\n    ```\n     > example.mjs:1:61: warning: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\n        1 │ export let Array = (typeof window !== 'undefined' ? window : this).Array\n          ╵                                                              ~~~~\n       example.mjs:1:0: note: This file is considered an ECMAScript module because of the \"export\" keyword here\n        1 │ export let Array = (typeof window !== 'undefined' ? window : this).Array\n          ╵ ~~~~~~\n    ```\n\n    This warning is not unique to esbuild. Rollup also already has a similar warning:\n\n    ```\n    (!) `this` has been rewritten to `undefined`\n    https://rollupjs.org/guide/en/#error-this-is-undefined\n    example.mjs\n    1: export let Array = (typeof window !== 'undefined' ? window : this).Array\n                                                                    ^\n    ```\n\n* Allow a string literal as a JSX fragment ([#1217](https://github.com/evanw/esbuild/issues/1217))\n\n    TypeScript's JSX implementation allows you to configure a custom JSX factory and a custom JSX fragment, but requires that they are both valid JavaScript identifier member expression chains. Since esbuild's JSX implementation is based on TypeScript, esbuild has the same requirement. So `React.createElement` is a valid JSX factory value but `['React', 'createElement']` is not.\n\n    However, the [Mithril](https://mithril.js.org/jsx.html) framework has decided to use `\"[\"` as a JSX fragment, which is not a valid JavaScript identifier member expression chain. This meant that using Mithril with esbuild required a workaround. In this release, esbuild now lets you use a string literal as a custom JSX fragment. It should now be easier to use esbuild's JSX implementation with libraries such as Mithril.\n\n* Fix `metafile` in `onEnd` with `watch` mode enabled ([#1186](https://github.com/evanw/esbuild/issues/1186))\n\n    This release fixes a bug where the `metafile` property was incorrectly undefined inside plugin `onEnd` callbacks if `watch` mode is enabled for all builds after the first build. The `metafile` property was accidentally being set after calling `onEnd` instead of before.\n\n## 0.11.16\n\n* Fix TypeScript `enum` edge case ([#1198](https://github.com/evanw/esbuild/issues/1198))\n\n    In TypeScript, you can reference the inner closure variable in an `enum` within the inner closure by name:\n\n    ```ts\n    enum A { B = A }\n    ```\n\n    The TypeScript compiler generates the following code for this case:\n\n    ```ts\n    var A;\n    (function (A) {\n      A[A[\"B\"] = A] = \"B\";\n    })(A || (A = {}));\n    ```\n\n    However, TypeScript also lets you declare an `enum` value with the same name as the inner closure variable. In that case, the value \"shadows\" the declaration of the inner closure variable:\n\n    ```ts\n    enum A { A = 1, B = A }\n    ```\n\n    The TypeScript compiler generates the following code for this case:\n\n    ```ts\n    var A;\n    (function (A) {\n      A[A[\"A\"] = 1] = \"A\";\n      A[A[\"B\"] = 1] = \"B\";\n    })(A || (A = {}));\n    ```\n\n    Previously esbuild reported a duplicate variable declaration error in the second case due to the collision between the `enum` value and the inner closure variable with the same name. With this release, the shadowing is now handled correctly.\n\n* Parse the `@-moz-document` CSS rule ([#1203](https://github.com/evanw/esbuild/issues/1203))\n\n    This feature has been removed from the web because it's actively harmful, at least according to [this discussion](https://bugzilla.mozilla.org/show_bug.cgi?id=1035091). However, there is one exception where `@-moz-document url-prefix() {` is accepted by Firefox to basically be an \"if Firefox\" conditional rule. Because of this, esbuild now parses the `@-moz-document` CSS rule. This should result in better pretty-printing and minification and no more warning when this rule is used.\n\n* Fix syntax error in TypeScript-specific speculative arrow function parsing ([#1211](https://github.com/evanw/esbuild/issues/1211))\n\n    Because of grammar ambiguities, expressions that start with a parenthesis are parsed using what's called a \"cover grammar\" that is a super-position of both a parenthesized expression and an arrow function parameter list. In JavaScript, the cover grammar is unambiguously an arrow function if and only if the following token is a `=>` token.\n\n    But in TypeScript, the expression is still ambiguously a parenthesized expression or an arrow function if the following token is a `:` since it may be the second half of the `?:` operator or a return type annotation. This requires speculatively attempting to reduce the cover grammar to an arrow function parameter list.\n\n    However, when doing this esbuild eagerly reported an error if a default argument was encountered and the target is `es5` (esbuild doesn't support lowering default arguments to ES5). This is problematic in the following TypeScript code since the parenthesized code turns out to not be an arrow function parameter list:\n\n    ```ts\n    function foo(check, hover) {\n      return check ? (hover = 2, bar) : baz();\n    }\n    ```\n\n    Previously this code incorrectly generated an error since `hover = 2` was incorrectly eagerly validated as a default argument. With this release, the reporting of the default argument error when targeting `es5` is now done lazily and only when it's determined that the parenthesized code should actually be interpreted as an arrow function parameter list.\n\n* Further changes to the behavior of the `browser` field ([#1209](https://github.com/evanw/esbuild/issues/1209))\n\n    This release includes some changes to how the `browser` field in `package.json` is interpreted to better match how Browserify, Webpack, Parcel, and Rollup behave. The interpretation of this map in esbuild is intended to be applied if and only if it's applied by any one of these bundlers. However, there were some cases where esbuild applied the mapping and none of the other bundlers did, which could lead to build failures. These cases have been added to my [growing list of `browser` field test cases](https://github.com/evanw/package-json-browser-tests) and esbuild's behavior should now be consistent with other bundlers again.\n\n* Avoid placing a `super()` call inside a `return` statement ([#1208](https://github.com/evanw/esbuild/issues/1208))\n\n    When minification is enabled, an expression followed by a return statement (e.g. `a(); return b`) is merged into a single statement (e.g. `return a(), b`). This is done because it sometimes results in smaller code. If the return statement is the only statement in a block and the block is in a single-statement context, the block can be removed which saves a few characters.\n\n    Previously esbuild applied this rule to calls to `super()` inside of constructors. Doing that broke esbuild's class lowering transform that tries to insert class field initializers after the `super()` call. This transform isn't robust and only scans the top-level statement list inside the constructor, so inserting the `super()` call inside of the `return` statement means class field initializers were inserted before the `super()` call instead of after. This could lead to run-time crashes due to initialization failure.\n\n    With this release, top-level calls to `super()` will no longer be placed inside `return` statements (in addition to various other kinds of statements such as `throw`, which are now also handled). This should avoid class field initializers being inserted before the `super()` call.\n\n* Fix a bug with `onEnd` and watch mode ([#1186](https://github.com/evanw/esbuild/issues/1186))\n\n    This release fixes a bug where `onEnd` plugin callbacks only worked with watch mode when an `onRebuild` watch mode callback was present. Now `onEnd` callbacks should fire even if there is no `onRebuild` callback.\n\n* Fix an edge case with minified export names and code splitting ([#1201](https://github.com/evanw/esbuild/issues/1201))\n\n    The names of symbols imported from other chunks were previously not considered for renaming during minified name assignment. This could cause a syntax error due to a name collision when two symbols have the same original name. This was just an oversight and has been fixed, so symbols imported from other chunks should now be renamed when minification is enabled.\n\n* Provide a friendly error message when you forget `async` ([#1216](https://github.com/evanw/esbuild/issues/1216))\n\n    If the parser hits a parse error inside a non-asynchronous function or arrow expression and the previous token is `await`, esbuild will now report a friendly error about a missing `async` keyword instead of reporting the parse error. This behavior matches other JavaScript parsers including TypeScript, Babel, and V8.\n\n    The previous error looked like this:\n\n    ```\n     > test.ts:2:8: error: Expected \";\" but found \"f\"\n        2 │   await f();\n          ╵         ^\n    ```\n\n    The error now looks like this:\n\n    ```\n     > example.js:2:2: error: \"await\" can only be used inside an \"async\" function\n        2 │   await f();\n          ╵   ~~~~~\n       example.js:1:0: note: Consider adding the \"async\" keyword here\n        1 │ function f() {\n          │ ^\n          ╵ async\n    ```\n\n## 0.11.15\n\n* Provide options for how to handle legal comments ([#919](https://github.com/evanw/esbuild/issues/919))\n\n    A \"legal comment\" is considered to be any comment that contains `@license` or `@preserve` or that starts with `//!` or `/*!`. These comments are preserved in output files by esbuild since that follows the intent of the original authors of the code.\n\n    However, some people want to remove the automatically-generated license information before they distribute their code. To facilitate this, esbuild now provides several options for how to handle legal comments (via `--legal-comments=` in the CLI and `legalComments` in the JS API):\n\n    * `none`: Do not preserve any legal comments\n    * `inline`: Preserve all statement-level legal comments\n    * `eof`: Move all statement-level legal comments to the end of the file\n    * `linked`: Move all statement-level legal comments to a `.LEGAL.txt` file and link to them with a comment\n    * `external`: Move all statement-level legal comments to a `.LEGAL.txt` file but to not link to them\n\n    The default behavior is `eof` when bundling and `inline` otherwise.\n\n* Add `onStart` and `onEnd` callbacks to the plugin API\n\n    Plugins can now register callbacks to run when a build is started and ended:\n\n    ```js\n    const result = await esbuild.build({\n      ...\n      incremental: true,\n      plugins: [{\n        name: 'example',\n        setup(build) {\n          build.onStart(() => console.log('build started'))\n          build.onEnd(result => console.log('build ended', result))\n        },\n      }],\n    })\n    await result.rebuild()\n    ```\n\n    One benefit of `onStart` and `onEnd` is that they are run for all builds including rebuilds (relevant for incremental mode, watch mode, or serve mode), so they should be a good place to do work related to the build lifecycle.\n\n    More details:\n\n    * `build.onStart()`\n\n        You should not use an `onStart` callback for initialization since it can be run multiple times. If you want to initialize something, just put your plugin initialization code directly inside the `setup` function instead.\n\n        The `onStart` callback can be `async` and can return a promise. However, the build does not wait for the promise to be resolved before starting, so a slow `onStart` callback will not necessarily slow down the build. All `onStart` callbacks are also run concurrently, not consecutively. The returned promise is purely for error reporting, and matters when the `onStart` callback needs to do an asynchronous operation that may fail. If your plugin needs to wait for an asynchronous task in `onStart` to complete before any `onResolve` or `onLoad` callbacks are run, you will need to have your `onResolve` or `onLoad` callbacks block on that task from `onStart`.\n\n        Note that `onStart` callbacks do not have the ability to mutate `build.initialOptions`. The initial options can only be modified within the `setup` function and are consumed once the `setup` function returns. All rebuilds use the same initial options so the initial options are never re-consumed, and modifications to `build.initialOptions` that are done within `onStart` are ignored.\n\n    * `build.onEnd()`\n\n        All `onEnd` callbacks are run in serial and each callback is given access to the final build result. It can modify the build result before returning and can delay the end of the build by returning a promise. If you want to be able to inspect the build graph, you should set `build.initialOptions.metafile = true` and the build graph will be returned as the `metafile` property on the build result object.\n\n## 0.11.14\n\n* Implement arbitrary module namespace identifiers\n\n    This introduces new JavaScript syntax:\n\n    ```js\n    import {'🍕' as food} from 'file'\n    export {food as '🧀'}\n    ```\n\n    [The proposal for this feature](https://github.com/bmeck/proposal-arbitrary-module-namespace-identifiers) appears to not be going through the regular TC39 process. It is being done as a subtle [direct pull request](https://github.com/tc39/ecma262/pull/2154) instead. It seems appropriate for esbuild to support this feature since it has been implemented in V8 and has now shipped in Chrome 90 and node 16.\n\n    According to the proposal, this feature is intended to improve interop with non-JavaScript languages which use exports that aren't valid JavaScript identifiers such as `Foo::~Foo`. In particular, WebAssembly allows any valid UTF-8 string as to be used as an export alias.\n\n    This feature was actually already partially possible in previous versions of JavaScript via the computed property syntax:\n\n    ```js\n    import * as ns from './file.json'\n    console.log(ns['🍕'])\n    ```\n\n    However, doing this is very un-ergonomic and exporting something as an arbitrary name is impossible outside of `export * from`. So this proposal is designed to fully fill out the possibility matrix and make arbitrary alias names a proper first-class feature.\n\n* Implement more accurate `sideEffects` behavior from Webpack ([#1184](https://github.com/evanw/esbuild/issues/1184))\n\n    This release adds support for the implicit `**/` prefix that must be added to paths in the `sideEffects` array in `package.json` if the path does not contain `/`. Another way of saying this is if `package.json` contains a `sideEffects` array with a string that doesn't contain a `/` then it should be treated as a file name instead of a path. Previously esbuild treated all strings in this array as paths, which does not match how Webpack behaves. The result of this meant that esbuild could consider files to have no side effects while Webpack would consider the same files to have side effects. This bug should now be fixed.\n\n## 0.11.13\n\n* Implement ergonomic brand checks for private fields\n\n    This introduces new JavaScript syntax:\n\n    ```js\n    class Foo {\n      #field\n      static isFoo(x) {\n        return #foo in x // This is an \"ergonomic brand check\"\n      }\n    }\n    assert(Foo.isFoo(new Foo))\n    ```\n\n    [The TC39 proposal for this feature](https://github.com/tc39/proposal-private-fields-in-in) is currently at stage 3 but has already been shipped in Chrome 91 and has also landed in Firefox. It seems reasonably inevitable given that it's already shipping and that it's a very simple feature, so it seems appropriate to add this feature to esbuild.\n\n* Add the `--allow-overwrite` flag ([#1152](https://github.com/evanw/esbuild/issues/1152))\n\n    This is a new flag that allows output files to overwrite input files. It's not enabled by default because doing so means overwriting your source code, which can lead to data loss if your code is not checked in. But supporting this makes certain workflows easier by avoiding the need for a temporary directory so doing this is now supported.\n\n* Minify property accesses on object literals ([#1166](https://github.com/evanw/esbuild/issues/1166))\n\n    The code `{a: {b: 1}}.a.b` will now be minified to `1`. This optimization is relatively complex and hard to do safely. Here are some tricky cases that are correctly handled:\n\n    ```js\n    var obj = {a: 1}\n    assert({a: 1, a: 2}.a === 2)\n    assert({a: 1, [String.fromCharCode(97)]: 2}.a === 2)\n    assert({__proto__: obj}.a === 1)\n    assert({__proto__: null}.a === undefined)\n    assert({__proto__: null}.__proto__ === undefined)\n    assert({a: function() { return this.b }, b: 1}.a() === 1)\n    assert(({a: 1}.a = 2) === 2)\n    assert(++{a: 1}.a === 2)\n    assert.throws(() => { new ({ a() {} }.a) })\n    ```\n\n* Improve arrow function parsing edge cases\n\n    There are now more situations where arrow expressions are not allowed. This improves esbuild's alignment with the JavaScript specification. Some examples of cases that were previously allowed but that are now no longer allowed:\n\n    ```js\n    1 + x => {}\n    console.log(x || async y => {})\n    class Foo extends async () => {} {}\n    ```\n\n## 0.11.12\n\n* Fix a bug where `-0` and `0` were collapsed to the same value ([#1159](https://github.com/evanw/esbuild/issues/1159))\n\n    Previously esbuild would collapse `Object.is(x ? 0 : -0, -0)` into `Object.is((x, 0), -0)` during minification, which is incorrect. The IEEE floating-point value `-0` is a different bit pattern than `0` and while they both compare equal, the difference is detectable in a few scenarios such as when using `Object.is()`. The minification transformation now checks for `-0` vs. `0` and no longer has this bug. This fix was contributed by [@rtsao](https://github.com/rtsao).\n\n* Match the TypeScript compiler's output in a strange edge case ([#1158](https://github.com/evanw/esbuild/issues/1158))\n\n    With this release, esbuild's TypeScript-to-JavaScript transform will no longer omit the namespace in this case:\n\n    ```ts\n    namespace Something {\n      export declare function Print(a: string): void\n    }\n    Something.Print = function(a) {}\n    ```\n\n    This was previously omitted because TypeScript omits empty namespaces, and the namespace was considered empty because the `export declare function` statement isn't \"real\":\n\n    ```ts\n    namespace Something {\n      export declare function Print(a: string): void\n      setTimeout(() => Print('test'))\n    }\n    Something.Print = function(a) {}\n    ```\n\n    The TypeScript compiler compiles the above code into the following:\n\n    ```js\n    var Something;\n    (function (Something) {\n      setTimeout(() => Print('test'));\n    })(Something || (Something = {}));\n    Something.Print = function (a) { };\n    ```\n\n    Notice how `Something.Print` is never called, and what appears to be a reference to the `Print` symbol on the namespace `Something` is actually a reference to the global variable `Print`. I can only assume this is a bug in TypeScript, but it's important to replicate this behavior inside esbuild for TypeScript compatibility.\n\n    The TypeScript-to-JavaScript transform in esbuild has been updated to match the TypeScript compiler's output in both of these cases.\n\n* Separate the `debug` log level into `debug` and `verbose`\n\n    You can now use `--log-level=debug` to get some additional information that might indicate some problems with your build, but that has a high-enough false-positive rate that it isn't appropriate for warnings, which are on by default. Enabling the `debug` log level no longer generates a torrent of debug information like it did in the past; that behavior is now reserved for the `verbose` log level instead.\n\n## 0.11.11\n\n* Initial support for Deno ([#936](https://github.com/evanw/esbuild/issues/936))\n\n    You can now use esbuild in the [Deno](https://deno.land/) JavaScript environment via esbuild's official Deno package. Using it looks something like this:\n\n    ```js\n    import * as esbuild from 'https://deno.land/x/esbuild@v0.11.11/mod.js'\n    const ts = 'let hasProcess: boolean = typeof process != \"null\"'\n    const result = await esbuild.transform(ts, { loader: 'ts', logLevel: 'warning' })\n    console.log('result:', result)\n    esbuild.stop()\n    ```\n\n    It has basically the same API as esbuild's npm package with one addition: you need to call `stop()` when you're done because unlike node, Deno doesn't provide the necessary APIs to allow Deno to exit while esbuild's internal child process is still running.\n\n* Remove warnings about non-bundled use of `require` and `import` ([#1153](https://github.com/evanw/esbuild/issues/1153), [#1142](https://github.com/evanw/esbuild/issues/1142), [#1132](https://github.com/evanw/esbuild/issues/1132), [#1045](https://github.com/evanw/esbuild/issues/1045), [#812](https://github.com/evanw/esbuild/issues/812), [#661](https://github.com/evanw/esbuild/issues/661), [#574](https://github.com/evanw/esbuild/issues/574), [#512](https://github.com/evanw/esbuild/issues/512), [#495](https://github.com/evanw/esbuild/issues/495), [#480](https://github.com/evanw/esbuild/issues/480), [#453](https://github.com/evanw/esbuild/issues/453), [#410](https://github.com/evanw/esbuild/issues/410), [#80](https://github.com/evanw/esbuild/issues/80))\n\n    Previously esbuild had warnings when bundling about uses of `require` and `import` that are not of the form `require(<string literal>)` or `import(<string literal>)`. These warnings existed because the bundling process must be able to statically-analyze all dynamic imports to determine which files must be included. Here are some real-world examples of cases that esbuild doesn't statically analyze:\n\n    * From [`mongoose`](https://www.npmjs.com/package/mongoose):\n\n        ```js\n        require('./driver').set(require(global.MONGOOSE_DRIVER_PATH));\n        ```\n\n    * From [`moment`](https://www.npmjs.com/package/moment):\n\n        ```js\n        aliasedRequire = require;\n        aliasedRequire('./locale/' + name);\n        ```\n\n    * From [`logform`](https://www.npmjs.com/package/logform):\n\n        ```js\n        function exposeFormat(name) {\n          Object.defineProperty(format, name, {\n            get() { return require(`./${name}.js`); }\n          });\n        }\n        exposeFormat('align');\n        ```\n\n    All of these dynamic imports will not be bundled (i.e. they will be left as-is) and will crash at run-time if they are evaluated. Some of these crashes are ok since the code paths may have error handling or the code paths may never be used. Other crashes are not ok because the crash will actually be hit.\n\n    The warning from esbuild existed to let you know that esbuild is aware that it's generating a potentially broken bundle. If you discover that your bundle is broken, it's nice to have a warning from esbuild to point out where the problem is. And it was just a warning so the build process still finishes and successfully generates output files. If you didn't want to see the warning, it was easy to turn it off via `--log-level=error`.\n\n    However, there have been quite a few complaints about this warning. Some people seem to not understand the difference between a warning and an error, and think the build has failed even though output files were generated. Other people do not want to see the warning but also do not want to enable `--log-level=error`.\n\n    This release removes this warning for both `require` and `import`. Now when you try to bundle code with esbuild that contains dynamic imports not of the form `require(<string literal>)` or `import(<string literal>)`, esbuild will just silently generate a potentially broken bundle. This may affect people coming from other bundlers that support certain forms of dynamic imports that are not compatible with esbuild such as the [Webpack-specific dynamic `import()` with pattern matching](https://webpack.js.org/api/module-methods/#dynamic-expressions-in-import).\n\n## 0.11.10\n\n* Provide more information about `exports` map import failures if possible ([#1143](https://github.com/evanw/esbuild/issues/1143))\n\n    Node has a new feature where you can [add an `exports` map to your `package.json` file](https://nodejs.org/api/packages.html#packages_package_entry_points) to control how external import paths map to the files in your package. You can change which paths map to which files as well as make it impossible to import certain files (i.e. the files are private).\n\n    If path resolution fails due to an `exports` map and the failure is not related to import conditions, esbuild's current error message for this just says that the import isn't possible:\n\n    ```\n     > example.js:1:15: error: Could not resolve \"vanillajs-datepicker/js/i18n/locales/ca\" (mark it as external to exclude it from the bundle)\n        1 │ import ca from 'vanillajs-datepicker/js/i18n/locales/ca'\n          ╵                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n       node_modules/vanillajs-datepicker/package.json:6:13: note: The path \"./js/i18n/locales/ca\" is not exported by package \"vanillajs-datepicker\"\n        6 │   \"exports\": {\n          ╵              ^\n    ```\n\n    This error message matches the error that node itself throws. However, the message could be improved in the case where someone is trying to import a file using its file system path and that path is actually exported by the package, just under a different export path. This case comes up a lot when using TypeScript because the TypeScript compiler (and therefore the Visual Studio Code IDE) [still doesn't support package `exports`](https://github.com/microsoft/TypeScript/issues/33079).\n\n    With this release, esbuild will now do a reverse lookup of the file system path using the `exports` map to determine what the correct import path should be:\n\n    ```\n     > example.js:1:15: error: Could not resolve \"vanillajs-datepicker/js/i18n/locales/ca\" (mark it as external to exclude it from the bundle)\n         1 │ import ca from 'vanillajs-datepicker/js/i18n/locales/ca'\n           ╵                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n       node_modules/vanillajs-datepicker/package.json:6:13: note: The path \"./js/i18n/locales/ca\" is not exported by package \"vanillajs-datepicker\"\n         6 │   \"exports\": {\n           ╵              ^\n       node_modules/vanillajs-datepicker/package.json:12:19: note: The file \"./js/i18n/locales/ca.js\" is exported at path \"./locales/ca\"\n        12 │     \"./locales/*\": \"./js/i18n/locales/*.js\",\n           ╵                    ~~~~~~~~~~~~~~~~~~~~~~~~\n       example.js:1:15: note: Import from \"vanillajs-datepicker/locales/ca\" to get the file \"node_modules/vanillajs-datepicker/js/i18n/locales/ca.js\"\n         1 │ import ca from 'vanillajs-datepicker/js/i18n/locales/ca'\n           │                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n           ╵                \"vanillajs-datepicker/locales/ca\"\n    ```\n\n    Hopefully this should enable people encountering this issue to fix the problem themselves.\n\n## 0.11.9\n\n* Fix escaping of non-BMP characters in property names ([#977](https://github.com/evanw/esbuild/issues/977))\n\n    Property names in object literals do not have to be quoted if the property is a valid JavaScript identifier. This is defined as starting with a character in the `ID_Start` Unicode category and ending with zero or more characters in the `ID_Continue` Unicode category. However, esbuild had a bug where non-BMP characters (i.e. characters encoded using two UTF-16 code units instead of one) were always checked against `ID_Continue` instead of `ID_Start` because they included a code unit that wasn't at the start. This could result in invalid JavaScript being generated when using `--charset=utf8` because `ID_Continue` is a superset of `ID_Start` and contains some characters that are not valid at the start of an identifier. This bug has been fixed.\n\n* Be maximally liberal in the interpretation of the `browser` field ([#740](https://github.com/evanw/esbuild/issues/740))\n\n    The `browser` field in `package.json` is an informal convention followed by browser-specific bundlers that allows package authors to substitute certain node-specific import paths with alternative browser-specific import paths. It doesn't have a rigorous specification and the [canonical description](https://github.com/defunctzombie/package-browser-field-spec) of the feature doesn't include any tests. As a result, each bundler implements this feature differently. I have tried to create a [survey of how different bundlers interpret the `browser` field](https://github.com/evanw/package-json-browser-tests) and the results are very inconsistent.\n\n    This release attempts to change esbuild to support the union of the behavior of all other bundlers. That way if people have the `browser` field working with some other bundler and they switch to esbuild, the `browser` field shouldn't ever suddenly stop working. This seemed like the most principled approach to take in this situation.\n\n    The drawback of this approach is that it means the `browser` field may start working when switching to esbuild when it was previously not working. This could cause bugs, but I consider this to be a problem with the package (i.e. not using a more well-supported form of the `browser` field), not a problem with esbuild itself.\n\n## 0.11.8\n\n* Fix hash calculation for code splitting and dynamic imports ([#1076](https://github.com/evanw/esbuild/issues/1076))\n\n    The hash included in the file name of each output file is intended to change if and only if anything relevant to the content of that output file changes. It includes:\n\n    * The contents of the file with the paths of other output files omitted\n    * The output path of the file the final hash omitted\n    * Some information about the input files involved in that output file\n    * The contents of the associated source map, if there is one\n    * All of the information above for all transitive dependencies found by following `import` statements\n\n    However, this didn't include dynamic `import()` expressions due to an oversight. With this release, dynamic `import()` expressions are now also counted as transitive dependencies. This fixes an issue where the content of an output file could change without its hash also changing. As a side effect of this change, dynamic imports inside output files of other output files are now listed in the metadata file if the `metafile` setting is enabled.\n\n* Refactor the internal module graph representation\n\n    This release changes a large amount of code relating to esbuild's internal module graph. The changes are mostly organizational and help consolidate most of the logic around maintaining various module graph invariants into a separate file where it's easier to audit. The Go language doesn't have great abstraction capabilities (e.g. no zero-cost iterators) so the enforcement of this new abstraction is unfortunately done by convention instead of by the compiler, and there is currently still some code that bypasses the abstraction. But it's better than it was before.\n\n    Another relevant change was moving a number of special cases that happened during the tree shaking traversal into the graph itself instead. Previously there were quite a few implicit dependency rules that were checked in specific places, which was hard to follow. Encoding these special case constraints into the graph itself makes the problem easier to reason about and should hopefully make the code more regular and robust.\n\n    Finally, this set of changes brings back full support for the `sideEffects` annotation in `package.json`. It was previously disabled when code splitting was active as a temporary measure due to the discovery of some bugs in that scenario. But I believe these bugs have been resolved now that tree shaking and code splitting are done in separate passes (see the previous release for more information).\n\n## 0.11.7\n\n* Fix incorrect chunk reference with code splitting, css, and dynamic imports ([#1125](https://github.com/evanw/esbuild/issues/1125))\n\n    This release fixes a bug where when you use code splitting, CSS imports in JS, and dynamic imports all combined, the dynamic import incorrectly references the sibling CSS chunk for the dynamic import instead of the primary JS chunk. In this scenario the entry point file corresponds to two different output chunks (one for CSS and one for JS) and the wrong chunk was being picked. This bug has been fixed.\n\n* Split apart tree shaking and code splitting ([#1123](https://github.com/evanw/esbuild/issues/1123))\n\n    The original code splitting algorithm allowed for files to be split apart and for different parts of the same file to end up in different chunks based on which entry points needed which parts. This was done at the same time as tree shaking by essentially performing tree shaking multiple times, once per entry point, and tracking which entry points each file part is live in. Each file part that is live in at least one entry point was then assigned to a code splitting chunk with all of the other code that is live in the same set of entry points. This ensures that entry points only import code that they will use (i.e. no code will be downloaded by an entry point that is guaranteed to not be used).\n\n    This file-splitting feature has been removed because it doesn't work well with the recently-added top-level await JavaScript syntax, which has complex evaluation order rules that operate at file boundaries. File parts now have a single boolean flag for whether they are live or not instead of a set of flags that track which entry points that part is reachable from (reachability is still tracked at the file level).\n\n    However, this change appears to have introduced some subtly incorrect behavior with code splitting because there is now an implicit dependency in the import graph between adjacent parts within the same file even if the two parts are unrelated and don't reference each other. This is due to the fact each entry point that references one part pulls in the file (but not the whole file, only the parts that are live in at least one entry point). So liveness must be fully computed first before code splitting is computed.\n\n    This release splits apart tree shaking and code splitting into two separate passes, which fixes certain cases where two generated code splitting chunks ended up each importing symbols from the other and causing a cycle. There should hopefully no longer be cycles in generated code splitting chunks.\n\n* Make `this` work in static class fields in TypeScript files\n\n    Currently `this` is mis-compiled in static fields in TypeScript files if the `useDefineForClassFields` setting in `tsconfig.json` is `false` (the default value):\n\n    ```js\n    class Foo {\n      static foo = 123\n      static bar = this.foo\n    }\n    console.log(Foo.bar)\n    ```\n\n    This is currently compiled into the code below, which is incorrect because it changes the value of `this` (it's supposed to refer to `Foo`):\n\n    ```js\n    class Foo {\n    }\n    Foo.foo = 123;\n    Foo.bar = this.foo;\n    console.log(Foo.bar);\n    ```\n\n    This was an intentionally unhandled case because the TypeScript compiler doesn't handle this either (esbuild's currently incorrect output matches the output from the TypeScript compiler, which is also currently incorrect). However, the TypeScript compiler might fix their output at some point in which case esbuild's behavior would become problematic.\n\n    So this release now generates the correct output:\n\n    ```js\n    const _Foo = class {\n    };\n    let Foo = _Foo;\n    Foo.foo = 123;\n    Foo.bar = _Foo.foo;\n    console.log(Foo.bar);\n    ```\n\n    Presumably the TypeScript compiler will be fixed to also generate something like this in the future. If you're wondering why esbuild generates the extra `_Foo` variable, it's defensive code to handle the possibility of the class being reassigned, since class declarations are not constants:\n\n    ```js\n    class Foo {\n      static foo = 123\n      static bar = () => Foo.foo\n    }\n    let bar = Foo.bar\n    Foo = { foo: 321 }\n    console.log(bar())\n    ```\n\n    We can't just move the initializer containing `Foo.foo` outside of the class body because in JavaScript, the class name is shadowed inside the class body by a special hidden constant that is equal to the class object. Even if the class is reassigned later, references to that shadowing symbol within the class body should still refer to the original class object.\n\n* Various fixes for private class members ([#1131](https://github.com/evanw/esbuild/issues/1131))\n\n    This release fixes multiple issues with esbuild's handling of the `#private` syntax. Previously there could be scenarios where references to `this.#private` could be moved outside of the class body, which would cause them to become invalid (since the `#private` name is only available within the class body). One such case is when TypeScript's `useDefineForClassFields` setting has the value `false` (which is the default value), which causes class field initializers to be replaced with assignment expressions to avoid using \"define\" semantics:\n\n    ```js\n    class Foo {\n      static #foo = 123\n      static bar = Foo.#foo\n    }\n    ```\n\n    Previously this was turned into the following code, which is incorrect because `Foo.#foo` was moved outside of the class body:\n\n    ```js\n    class Foo {\n      static #foo = 123;\n    }\n    Foo.bar = Foo.#foo;\n    ```\n\n    This is now handled by converting the private field syntax into normal JavaScript that emulates it with a `WeakMap` instead.\n\n    This conversion is fairly conservative to make sure certain edge cases are covered, so this release may unfortunately convert more private fields than previous releases, even when the target is `esnext`. It should be possible to improve this transformation in future releases so that this happens less often while still preserving correctness.\n\n## 0.11.6\n\n* Fix an incorrect minification transformation ([#1121](https://github.com/evanw/esbuild/issues/1121))\n\n    This release removes an incorrect substitution rule in esbuild's peephole optimizer, which is run when minification is enabled. The incorrect rule transformed `if(a && falsy)` into `if(a, falsy)` which is equivalent if `falsy` has no side effects (such as the literal `false`). However, the rule didn't check that the expression is side-effect free first which could result in miscompiled code. I have removed the rule instead of modifying it to check for the lack of side effects first because while the code is slightly smaller, it may also be more expensive at run-time which is undesirable. The size savings are also very insignificant.\n\n* Change how `NODE_PATH` works to match node ([#1117](https://github.com/evanw/esbuild/issues/1117))\n\n    Node searches for packages in nearby `node_modules` directories, but it also allows you to inject extra directories to search for packages in using the `NODE_PATH` environment variable. This is supported when using esbuild's CLI as well as via the `nodePaths` option when using esbuild's API.\n\n    Node's module resolution algorithm is well-documented, and esbuild's path resolution is designed to follow it. The full algorithm is here: https://nodejs.org/api/modules.html#modules_all_together. However, it appears that the documented algorithm is incorrect with regard to `NODE_PATH`. The documentation says `NODE_PATH` directories should take precedence over `node_modules` directories, and so that's how esbuild worked. However, in practice node actually does it the other way around.\n\n    Starting with this release, esbuild will now allow `node_modules` directories to take precedence over `NODE_PATH` directories. This is a deviation from the published algorithm.\n\n* Provide a better error message for incorrectly-quoted JSX attributes ([#959](https://github.com/evanw/esbuild/issues/959), [#1115](https://github.com/evanw/esbuild/issues/1115))\n\n    People sometimes try to use the output of `JSON.stringify()` as a JSX attribute when automatically-generating JSX code. Doing so is incorrect because JSX strings work like XML instead of like JS (since JSX is XML-in-JS). Specifically, using a backslash before a quote does not cause it to be escaped:\n\n    ```jsx\n    //     JSX ends the \"content\" attribute here and sets \"content\" to 'some so-called \\\\'\n    //                                            v\n    let button = <Button content=\"some so-called \\\"button text\\\"\" />\n    //                                                        ^\n    //         There is no \"=\" after the JSX attribute \"text\", so we expect a \">\"\n    ```\n\n    It's not just esbuild; Babel and TypeScript also treat this as a syntax error. All of these JSX parsers are just following [the JSX specification](https://facebook.github.io/jsx/). This has come up twice now so it could be worth having a dedicated error message. Previously esbuild had a generic syntax error like this:\n\n    ```\n     > example.jsx:1:58: error: Expected \">\" but found \"\\\\\"\n        1 │ let button = <Button content=\"some so-called \\\"button text\\\"\" />\n          ╵                                                           ^\n    ```\n\n    Now esbuild will provide more information if it detects this case:\n\n    ```\n     > example.jsx:1:58: error: Unexpected backslash in JSX element\n        1 │ let button = <Button content=\"some so-called \\\"button text\\\"\" />\n          ╵                                                           ^\n       example.jsx:1:45: note: Quoted JSX attributes use XML-style escapes instead of JavaScript-style escapes\n        1 │ let button = <Button content=\"some so-called \\\"button text\\\"\" />\n          │                                              ~~\n          ╵                                              &quot;\n       example.jsx:1:29: note: Consider using a JavaScript string inside {...} instead of a quoted JSX attribute\n        1 │ let button = <Button content=\"some so-called \\\"button text\\\"\" />\n          │                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n          ╵                              {\"some so-called \\\"button text\\\"\"}\n    ```\n\n## 0.11.5\n\n* Add support for the `override` keyword in TypeScript 4.3 ([#1105](https://github.com/evanw/esbuild/pull/1105))\n\n    The latest version of TypeScript (now in beta) adds a new keyword called `override` that can be used on class members. You can read more about this feature in [Microsoft's blog post about TypeScript 4.3](https://devblogs.microsoft.com/typescript/announcing-typescript-4-3-beta/#override-and-the-noimplicitoverride-flag). It looks like this:\n\n    ```ts\n    class SpecializedComponent extends SomeComponent {\n      override show() {\n        // ...\n      }\n    }\n    ```\n\n    With this release, esbuild will now ignore the `override` keyword when parsing TypeScript code instead of treating this keyword as a syntax error, which means esbuild can now support TypeScript 4.3 syntax. This change was contributed by [@g-plane](https://github.com/g-plane).\n\n* Allow `async` plugin `setup` functions\n\n    With this release, you can now return a promise from your plugin's `setup` function to delay the start of the build:\n\n    ```js\n    let slowInitPlugin = {\n      name: 'slow-init',\n      async setup(build) {\n        // Delay the start of the build\n        await new Promise(r => setTimeout(r, 1000))\n      },\n    }\n    ```\n\n    This is useful if your plugin needs to do something asynchronous before the build starts. For example, you may need some asynchronous information before modifying the `initialOptions` object, which must be done before the build starts for the modifications to take effect.\n\n* Add some optimizations around hashing\n\n    This release contains two optimizations to the hashes used in output file names:\n\n    1. Hash generation now happens in parallel with other work, and other work only blocks on the hash computation if the hash ends up being needed (which is only if `[hash]` is included in `--entry-names=`, and potentially `--chunk-names=` if it's relevant). This is a performance improvement because `--entry-names=` does not include `[hash]` in the default case, so bundling time no longer always includes hashing time.\n\n    2. The hashing algorithm has been changed from SHA1 to [xxHash](https://github.com/Cyan4973/xxHash) (specifically [this Go implementation](https://github.com/cespare/xxhash)) which means the hashing step is around 6x faster than before. Thanks to [@Jarred-Sumner](https://github.com/Jarred-Sumner) for the suggestion.\n\n* Disable tree shaking annotations when code splitting is active ([#1070](https://github.com/evanw/esbuild/issues/1070), [#1081](https://github.com/evanw/esbuild/issues/1081))\n\n    Support for [Webpack's `\"sideEffects\": false` annotation](https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free) in `package.json` is now disabled when code splitting is enabled and there is more than one entry point. This avoids a bug that could cause generated chunks to reference each other in some cases. Now all chunks generated by code splitting should be acyclic.\n\n## 0.11.4\n\n* Avoid name collisions with TypeScript helper functions ([#1102](https://github.com/evanw/esbuild/issues/1102))\n\n    Helper functions are sometimes used when transforming newer JavaScript syntax for older browsers. For example, `let {x, ...y} = {z}` is transformed into `let _a = {z}, {x} = _a, y = __rest(_a, [\"x\"])` which uses the `__rest` helper function. Many of esbuild's transforms were modeled after the transforms in the TypeScript compiler, so many of the helper functions use the same names as TypeScript's helper functions.\n\n    However, the TypeScript compiler doesn't avoid name collisions with existing identifiers in the transformed code. This means that post-processing esbuild's output with the TypeScript compiler (e.g. for lowering ES6 to ES5) will cause issues since TypeScript will fail to call its own helper functions: [microsoft/TypeScript#43296](https://github.com/microsoft/TypeScript/issues/43296). There is also a problem where TypeScript's `tslib` library overwrites globals with these names, which can overwrite esbuild's helper functions if code bundled with esbuild is run in the global scope.\n\n    To avoid these problems, esbuild will now use different names for its helper functions.\n\n* Fix a chunk hashing issue ([#1099](https://github.com/evanw/esbuild/issues/1099))\n\n    Previously the chunk hashing algorithm skipped hashing entry point chunks when the `--entry-names=` setting doesn't contain `[hash]`, since the hash wasn't used in the file name. However, this is no longer correct with the change in version 0.11.0 that made dynamic entry point chunks use `--chunk-names=` instead of `--entry-names=` since `--chunk-names=` can still contain `[hash]`.\n\n    With this release, chunk contents will now always be hashed regardless of the chunk type. This makes esbuild somewhat slower than before in the common case, but it fixes this correctness issue.\n\n## 0.11.3\n\n* Auto-define `process.env.NODE_ENV` when platform is set to `browser`\n\n    All code in the React world has the requirement that the specific expression `process.env.NODE_ENV` must be replaced with a string at compile-time or your code will immediately crash at run-time. This is a common stumbling point for people when they start using esbuild with React. Previously bundling code with esbuild containing `process.env.NODE_ENV` without defining a string replacement first was a warning that warned you about the lack of a define.\n\n    With this release esbuild will now attempt to define `process.env.NODE_ENV` automatically instead of warning about it. This will be implicitly defined to `\"production\"` if minification is enabled and `\"development\"` otherwise. This automatic behavior only happens when the platform is `browser`, since `process` is not a valid browser API and will never exist in the browser. This is also only done if there are no existing defines for `process`, `process.env`, or `process.env.NODE_ENV` so you can override the automatic value if necessary. If you need to disable this behavior, you can use the `neutral` platform instead of the `browser` platform.\n\n* Retain side-effect free intermediate re-exporting files ([#1088](https://github.com/evanw/esbuild/issues/1088))\n\n    This fixes a subtle bug with esbuild's support for [Webpack's `\"sideEffects\": false` annotation](https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free) in `package.json` when combined with re-export statements. A re-export is when you import something from one file and then export it again. You can re-export something with `export * from` or `export {foo} from` or `import {foo} from` followed by `export {foo}`.\n\n    The bug was that files which only contain re-exports and that are marked as being side-effect free were not being included in the bundle if you import one of the re-exported symbols. This is because esbuild's implementation of re-export linking caused the original importing file to \"short circuit\" the re-export and just import straight from the file containing the final symbol, skipping the file containing the re-export entirely.\n\n    This was normally not observable since the intermediate file consisted entirely of re-exports, which have no side effects. However, a recent change to allow ESM files to be lazily-initialized relies on all intermediate files being included in the bundle to trigger the initialization of the lazy evaluation wrappers. So the behavior of skipping over re-export files is now causing the imported symbols to not be initialized if the re-exported file is marked as lazily-evaluated.\n\n    The fix is to track all re-exports in the import chain from the original file to the file containing the final symbol and then retain all of those statements if the import ends up being used.\n\n* Add a very verbose `debug` log level\n\n    This log level is an experiment. Enabling it logs a lot of information (currently only about path resolution). The idea is that if you are having an obscure issue, the debug log level might contain some useful information. Unlike normal logs which are meant to mainly provide actionable information, these debug logs are intentionally mostly noise and are designed to be searched through instead.\n\n    Here is an example of debug-level log output:\n\n    ```\n     > debug: Resolving import \"react\" in directory \"src\" of type \"import-statement\"\n       note: Read 26 entries for directory \"src\"\n       note: Searching for \"react\" in \"node_modules\" directories starting from \"src\"\n       note: Attempting to load \"src/react\" as a file\n       note: Failed to find file \"src/react\"\n       note: Failed to find file \"src/react.tsx\"\n       note: Failed to find file \"src/react.ts\"\n       note: Failed to find file \"src/react.js\"\n       note: Failed to find file \"src/react.css\"\n       note: Failed to find file \"src/react.svg\"\n       note: Attempting to load \"src/react\" as a directory\n       note: Failed to read directory \"src/react\"\n       note: Parsed package name \"react\" and package subpath \".\"\n       note: Checking for a package in the directory \"node_modules/react\"\n       note: Read 7 entries for directory \"node_modules/react\"\n       note: Read 393 entries for directory \"node_modules\"\n       note: Attempting to load \"node_modules/react\" as a file\n       note: Failed to find file \"node_modules/react\"\n       note: Failed to find file \"node_modules/react.tsx\"\n       note: Failed to find file \"node_modules/react.ts\"\n       note: Failed to find file \"node_modules/react.js\"\n       note: Failed to find file \"node_modules/react.css\"\n       note: Failed to find file \"node_modules/react.svg\"\n       note: Attempting to load \"node_modules/react\" as a directory\n       note: Read 7 entries for directory \"node_modules/react\"\n       note: Resolved to \"node_modules/react/index.js\" using the \"main\" field in \"node_modules/react/package.json\"\n       note: Read 7 entries for directory \"node_modules/react\"\n       note: Read 7 entries for directory \"node_modules/react\"\n       note: Primary path is \"node_modules/react/index.js\" in namespace \"file\"\n    ```\n\n## 0.11.2\n\n* Fix missing symbol dependency for wrapped ESM files ([#1086](https://github.com/evanw/esbuild/issues/1086))\n\n    An internal graph node was missing an edge, which could result in generating code that crashes at run-time when code splitting is enabled. Specifically a part containing an import statement must depend on the imported file's wrapper symbol if the imported file is wrapped, regardless of whether it's a wrapped CommonJS or ESM file. Previously this was only the case for CommonJS files but not for ESM files, which is incorrect. This bug has been fixed.\n\n* Fix an edge case with entry points and top-level await\n\n    If an entry point uses `import()` on itself, it currently has to be wrapped since `import()` expressions call the wrapper for the imported file. This means the another call to the wrapper must be inserted at the bottom of the entry point file to start the lazy evaluation of the entry point code (otherwise nothing will be evaluated, since the entry point is wrapped). However, if this entry point then contains a top-level await that means the wrapper is `async` and must be passed to `await` to catch and forward any exceptions thrown during the evaluation of the entry point code. This `await` was previously missing in this specific case due to a bug, but the `await` should now be added in this release.\n\n## 0.11.1\n\n* Fix a missing space before internal `import()` when minifying ([#1082](https://github.com/evanw/esbuild/issues/1082))\n\n    Internal `import()` of a CommonJS module inside the bundle turns into a call to `Promise.resolve().then(() => require())`. However, a space was not inserted before the `Promise` token when minifying, which could lead to a syntax error. This bug has been fixed.\n\n* Fix code generation for unused imported files without side effects ([#1080](https://github.com/evanw/esbuild/issues/1080))\n\n    When esbuild adds a wrapping closure around a file to turn it from a statically-initialized file to a dynamically-initialized file, it also needs to turn import statements in other files that import the wrapped file into calls to the wrapper so that the wrapped file is initialized in the correct ordering. However, although tree-shaking is disabled for wrapped CommonJS files because CommonJS exports are dynamic, tree-shaking is still enabled for wrapped ESM files because ESM exports are static.\n\n    This caused a bug when files that have been marked with [`\"sideEffects\": false`](https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free) end up being completely unused in the resulting bundle. In that case the file is removed entirely, but esbuild was still turning `import` statements to that file into calls to the ESM wrapper. These wrapper calls should instead be omitted if the file was completely removed from the bundle as dead code. This bug has been fixed.\n\n* Allow top-level await in supported environments\n\n    Top-level await (i.e. using the `await` keyword outside of an `async` function) is not yet part of the JavaScript language standard. The [feature proposal](https://github.com/tc39/proposal-top-level-await) is still at stage 3 and has not yet advanced to stage 4. However, V8 has already implemented it and it has shipped in Chrome 89 and node 14.8. This release allows top-level await to be used when the `--target=` flag is set to those compilation targets.\n\n* Convert `import()` to `require()` if `import()` is not supported ([#1084](https://github.com/evanw/esbuild/issues/1084))\n\n    This release now converts dynamic `import()` expressions into `Promise.resolve().then(() => require())` expressions if the compilation target doesn't support them. This is the case for node before version 13.2, for example.\n\n## 0.11.0\n\n**This release contains backwards-incompatible changes.** Since esbuild is before version 1.0.0, these changes have been released as a new minor version to reflect this (as [recommended by npm](https://docs.npmjs.com/cli/v6/using-npm/semver/)). You should either be pinning the exact version of `esbuild` in your `package.json` file or be using a version range syntax that only accepts patch upgrades such as `~0.10.0`. See the documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\nThe changes in this release mostly relate to how entry points are handled. The way output paths are generated has changed in some cases, so you may need to update how you refer to the output path for a given entry point when you update to this release (see below for details). These breaking changes are as follows:\n\n* Change how `require()` and `import()` of ESM works ([#667](https://github.com/evanw/esbuild/issues/667), [#706](https://github.com/evanw/esbuild/issues/706))\n\n    Previously if you call `require()` on an ESM file, or call `import()` on an ESM file with code splitting disabled, esbuild would convert the ESM file to CommonJS. For example, if you had the following input files:\n\n    ```js\n    // cjs-file.js\n    console.log(require('./esm-file.js').foo)\n\n    // esm-file.js\n    export let foo = bar()\n    ```\n\n    The previous bundling behavior would generate something like this:\n\n    ```js\n    var require_esm_file = __commonJS((exports) => {\n      __markAsModule(exports);\n      __export(exports, {\n        foo: () => foo\n      });\n      var foo = bar();\n    });\n    console.log(require_esm_file().foo);\n    ```\n\n    This behavior has been changed and esbuild now generates something like this instead:\n\n    ```js\n    var esm_file_exports = {};\n    __export(esm_file_exports, {\n      foo: () => foo\n    });\n    var foo;\n    var init_esm_file = __esm(() => {\n      foo = bar();\n    });\n    console.log((init_esm_file(), esm_file_exports).foo);\n    ```\n\n    The variables have been pulled out of the lazily-initialized closure and are accessible to the rest of the module's scope. Some benefits of this approach:\n\n    * If another file does `import {foo} from \"./esm-file.js\"`, it will just reference `foo` directly and will not pay the performance penalty or code size overhead of the dynamic property accesses that come with CommonJS-style exports. So this improves performance and reduces code size in some cases.\n\n    * This fixes a long-standing bug ([#706](https://github.com/evanw/esbuild/issues/706)) where entry point exports could be broken if the entry point is a target of a `require()` call and the output format was ESM. This happened because previously calling `require()` on an entry point converted it to CommonJS, which then meant it only had a single `default` export, and the exported variables were inside the CommonJS closure and inaccessible to an ESM-style `export {}` clause. Now calling `require()` on an entry point only causes it to be lazily-initialized but all exports are still in the module scope and can still be exported using a normal `export {}` clause.\n\n    * Now that this has been changed, `import()` of a module with top-level await ([#253](https://github.com/evanw/esbuild/issues/253)) is now allowed when code splitting is disabled. Previously this didn't work because `import()` with code splitting disabled was implemented by converting the module to CommonJS and using `Promise.resolve().then(() => require())`, but converting a module with top-level await to CommonJS is impossible because the CommonJS call signature must be synchronous. Now that this implemented using lazy initialization instead of CommonJS conversion, the closure wrapping the ESM file can now be `async` and the `import()` expression can be replaced by a call to the lazy initializer.\n\n    * Adding the ability for ESM files to be lazily-initialized is an important step toward additional future code splitting improvements including: manual chunk names ([#207](https://github.com/evanw/esbuild/issues/207)), correct import evaluation order ([#399](https://github.com/evanw/esbuild/issues/399)), and correct top-level await evaluation order ([#253](https://github.com/evanw/esbuild/issues/253)). These features all need to make use of deferred evaluation of ESM code.\n\n    In addition, calling `require()` on an ESM file now recursively wraps all transitive dependencies of that file instead of just wrapping that ESM file itself. This is an increase in the size of the generated code, but it is important for correctness ([#667](https://github.com/evanw/esbuild/issues/667)). Calling `require()` on a module means its evaluation order is determined at run-time, which means the evaluation order of all dependencies must also be determined at run-time. If you don't want the increase in code size, you should use an `import` statement instead of a `require()` call.\n\n* Dynamic imports now use chunk names instead of entry names ([#1056](https://github.com/evanw/esbuild/issues/1056))\n\n    Previously the output paths of dynamic imports (files imported using the `import()` syntax) were determined by the `--entry-names=` setting. However, this can cause problems if you configure the `--entry-names=` setting to omit both `[dir]` and `[hash]` because then two dynamic imports with the same name will cause an output file name collision.\n\n    Now dynamic imports use the `--chunk-names=` setting instead, which is used for automatically-generated chunks. This setting is effectively required to include `[hash]` so dynamic import name collisions should now be avoided.\n\n    In addition, dynamic imports no longer affect the automatically-computed default value of `outbase`. By default `outbase` is computed to be the [lowest common ancestor](https://en.wikipedia.org/wiki/Lowest_common_ancestor) directory of all entry points. Previously dynamic imports were considered entry points in this calculation so adding a dynamic entry point could unexpectedly affect entry point output file paths. This issue has now been fixed.\n\n* Allow custom output paths for individual entry points\n\n    By default, esbuild will automatically generate an output path for each entry point by computing the relative path from the `outbase` directory to the entry point path, and then joining that relative path to the `outdir` directory. The output path can be customized using `outpath`, but that only works for a single file. Sometimes you may need custom output paths while using multiple entry points. You can now do this by passing the entry points as a map instead of an array:\n\n    * CLI\n        ```\n        esbuild out1=in1.js out2=in2.js --outdir=out\n        ```\n\n    * JS\n        ```js\n        esbuild.build({\n          entryPoints: {\n            out1: 'in1.js',\n            out2: 'in2.js',\n          },\n          outdir: 'out',\n        })\n        ```\n\n    * Go\n\n        ```go\n        api.Build(api.BuildOptions{\n          EntryPointsAdvanced: []api.EntryPoint{{\n            OutputPath: \"out1\",\n            InputPath: \"in1.js\",\n          }, {\n            OutputPath: \"out2\",\n            InputPath: \"in2.js\",\n          }},\n          Outdir: \"out\",\n        })\n        ```\n\n    This will cause esbuild to generate the files `out/out1.js` and `out/out2.js` inside the output directory. These custom output paths are used as input for the `--entry-names=` path template setting, so you can use something like `--entry-names=[dir]/[name]-[hash]` to add an automatically-computed hash to each entry point while still using the custom output path.\n\n* Derive entry point output paths from the original input path ([#945](https://github.com/evanw/esbuild/issues/945))\n\n    Previously esbuild would determine the output path for an entry point by looking at the post-resolved path. For example, running `esbuild --bundle react --outdir=out` would generate the output path `out/index.js` because the input path `react` was resolved to `node_modules/react/index.js`. With this release, the output path is now determined by looking at the pre-resolved path. For example, running `esbuild --bundle react --outdir=out` now generates the output path `out/react.js`. If you need to keep using the output path that esbuild previously generated with the old behavior, you can use the custom output path feature (described above).\n\n* Use the `file` namespace for file entry points ([#791](https://github.com/evanw/esbuild/issues/791))\n\n    Plugins that contain an `onResolve` callback with the `file` filter don't apply to entry point paths because it's not clear that entry point paths are files. For example, you could potentially bundle an entry point of `https://www.example.com/file.js` with a HTTP plugin that automatically downloads data from the server at that URL. But this behavior can be unexpected for people writing plugins.\n\n    With this release, esbuild will do a quick check first to see if the entry point path exists on the file system before running plugins. If it exists as a file, the namespace will now be `file` for that entry point path. This only checks the exact entry point name and doesn't attempt to search for the file, so for example it won't handle cases where you pass a package path as an entry point or where you pass an entry point without an extension. Hopefully this should help improve this situation in the common case where the entry point is an exact path.\n\nIn addition to the breaking changes above, the following features are also included in this release:\n\n* Warn about mutation of private methods ([#1067](https://github.com/evanw/esbuild/pull/1067))\n\n    Mutating a private method in JavaScript is not allowed, and will throw at run-time:\n\n    ```js\n    class Foo {\n      #method() {}\n      mutate() {\n        this.#method = () => {}\n      }\n    }\n    ```\n\n    This is the case both when esbuild passes the syntax through untransformed and when esbuild transforms the syntax into the equivalent code that uses a `WeakSet` to emulate private methods in older browsers. However, it's clear from this code that doing this will always throw, so this code is almost surely a mistake. With this release, esbuild will now warn when you do this. This change was contributed by [@jridgewell](https://github.com/jridgewell).\n\n* Fix some obscure TypeScript type parsing edge cases\n\n    In TypeScript, type parameters come after a type and are placed in angle brackets like `Foo<T>`. However, certain built-in types do not accept type parameters including primitive types such as `number`. This means `if (x as number < 1) {}` is not a syntax error while `if (x as Foo < 1) {}` is a syntax error. This release changes TypeScript type parsing to allow type parameters in a more restricted set of situations, which should hopefully better resolve these type parsing ambiguities.\n\n## 0.10.2\n\n* Fix a crash that was introduced in the previous release ([#1064](https://github.com/evanw/esbuild/issues/1064))\n\n    This crash happens when code splitting is active and there is a CSS entry point as well as two or more JavaScript entry points. There is a known issue where CSS bundling does not work when code splitting is active (code splitting is still a work in progress, see [#608](https://github.com/evanw/esbuild/issues/608)) so doing this will likely not work as expected. But esbuild obviously shouldn't crash. This release fixes the crash, although esbuild still does not yet generate the correct CSS output in this case.\n\n* Fix private fields inside destructuring assignment ([#1066](https://github.com/evanw/esbuild/issues/1066))\n\n    Private field syntax (i.e. `this.#field`) is supported for older language targets by converting the code into accesses into a `WeakMap`. However, although regular assignment (i.e. `this.#field = 1`) was handled destructuring assignment (i.e. `[this.#field] = [1]`) was not handled due to an oversight. Support for private fields inside destructuring assignment is now included with this release.\n\n* Fix an issue with direct `eval` and top-level symbols\n\n    It was previously the case that using direct `eval` caused the file containing it to be considered a CommonJS file, even if the file used ESM syntax. This was because the evaluated code could potentially attempt to interact with top-level symbols by name and the CommonJS closure was used to isolate those symbols from other modules so their names could be preserved (otherwise their names may need to be renamed to avoid collisions). However, ESM files are no longer convertable to CommonJS files due to the need to support top-level await.\n\n    This caused a bug where scope hoisting could potentially merge two modules containing direct `eval` and containing the same top-level symbol name into the same scope. These symbols were prevented from being renamed due to the direct `eval`, which caused a syntax error at run-time due to the name collision.\n\n    Because of this, esbuild is dropping the guarantee that using direct `eval` in an ESM file will be able to access top-level symbols. These symbols are now free to be renamed to avoid name collisions, and will now be minified when identifier minification is enabled. This is unlikely to affect real-world code because most real-world uses of direct `eval` only attempt to access local variables, not top-level symbols.\n\n    Using direct `eval` in an ESM file when bundling with esbuild will generate a warning. The warning is not new and is present in previous releases of esbuild as well. The way to avoid the warning is to avoid direct `eval`, since direct `eval` is somewhat of an anti-pattern and there are better alternatives.\n\n## 0.10.1\n\n* Expose `metafile` to `onRebuild` in watch mode ([#1057](https://github.com/evanw/esbuild/issues/1057))\n\n    Previously the build results returned to the watch mode `onRebuild` callback was missing the `metafile` property when the `metafile: true` option was present. This bug has been fixed.\n\n* Add a `formatMessages` API ([#1058](https://github.com/evanw/esbuild/issues/1058))\n\n    This API lets you print log messages to the terminal using the same log format that esbuild itself uses. This can be used to filter esbuild's warnings while still making the output look the same. Here's an example of calling this API:\n\n    ```js\n    import esbuild from 'esbuild'\n\n    const formatted = await esbuild.formatMessages([{\n      text: '\"test\" has already been declared',\n      location: { file: 'file.js', line: 2, column: 4, length: 4, lineText: 'let test = \"second\"' },\n      notes: [{\n        text: '\"test\" was originally declared here',\n        location: { file: 'file.js', line: 1, column: 4, length: 4, lineText: 'let test = \"first\"' },\n      }],\n    }], {\n      kind: 'error',\n      color: true,\n      terminalWidth: 100,\n    })\n\n    process.stdout.write(formatted.join(''))\n    ```\n\n* Remove the file splitting optimization ([#998](https://github.com/evanw/esbuild/issues/998))\n\n    This release removes the \"file splitting optimization\" that has up to this point been a part of esbuild's code splitting algorithm. This optimization allowed code within a single file to end up in separate chunks as long as that code had no side effects. For example, bundling two entry points that both use a disjoint set of code from a shared file consisting only of code without side effects would previously not generate any shared code chunks at all.\n\n    This optimization is being removed because the top-level await feature was added to JavaScript after this optimization was added, and performing this optimization in the presence of top-level await is more difficult than before. The correct evaulation order of a module graph containing top-level await is extremely complicated and is specified at the module boundary. Moving code that is marked as having no side effects across module boundaries under these additional constraints is even more complexity and is getting in the way of implementing top-level await. So the optimization has been removed to unblock work on top-level await, which esbuild must support.\n\n## 0.10.0\n\n**This release contains backwards-incompatible changes.** Since esbuild is before version 1.0.0, these changes have been released as a new minor version to reflect this (as [recommended by npm](https://docs.npmjs.com/cli/v6/using-npm/semver/)). You should either be pinning the exact version of `esbuild` in your `package.json` file or be using a version range syntax that only accepts patch upgrades such as `~0.9.0`. See the documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\nThat said, there are no breaking API changes in this release. The breaking changes are instead about how input files are interpreted and/or how output files are generated in some cases. So upgrading should be relatively straightforward as your API calls should still work the same way, but please make sure to test your code when you upgrade because the output may be different. These breaking changes are as follows:\n\n* No longer support `module` or `exports` in an ESM file ([#769](https://github.com/evanw/esbuild/issues/769))\n\n    This removes support for using CommonJS exports in a file with ESM exports. Previously this worked by converting the ESM file to CommonJS and then mixing the CommonJS and ESM exports into the same `exports` object. But it turns out that supporting this is additional complexity for the bundler, so it has been removed. It's also not something that works in real JavaScript environments since modules will never support both export syntaxes at once.\n\n    Note that this doesn't remove support for using `require` in ESM files. Doing this still works (and can be made to work in a real ESM environment by assigning to `globalThis.require`). This also doesn't remove support for using `import` in CommonJS files. Doing this also still works.\n\n* No longer change `import()` to `require()` ([#1029](https://github.com/evanw/esbuild/issues/1029))\n\n    Previously esbuild's transform for `import()` matched TypeScript's behavior, which is to transform it into `Promise.resolve().then(() => require())` when the current output format is something other than ESM. This was done when an import is external (i.e. not bundled), either due to the expression not being a string or due to the string matching an external import path.\n\n    With this release, esbuild will no longer do this. Now `import()` expressions will be preserved in the output instead. These expressions can be handled in non-ESM code by arranging for the `import` identifier to be a function that imports ESM code. This is how node works, so it will now be possible to use `import()` with node when the output format is something other than ESM.\n\n* Run-time `export * as` statements no longer convert the file to CommonJS\n\n    Certain `export * as` statements require a bundler to evaluate them at run-time instead of at compile-time like the JavaScript specification. This is the case when re-exporting symbols from an external file and a file in CommonJS format.\n\n    Previously esbuild would handle this by converting the module containing the `export * as` statement to CommonJS too, since CommonJS exports are evaluated at run-time while ESM exports are evaluated at bundle-time. However, this is undesirable because tree shaking only works for ESM, not for CommonJS, and the CommonJS wrapper causes additional code bloat. Another upcoming problem is that top-level await cannot work within a CommonJS module because CommonJS `require()` is synchronous.\n\n    With this release, esbuild will now convert modules containing a run-time `export * as` statement to a special ESM-plus-dynamic-fallback mode. In this mode, named exports present at bundle time can still be imported directly by name, but any imports that don't match one of the explicit named imports present at bundle time will be converted to a property access on the fallback object instead of being a bundle error. These property accesses are then resolved at run-time and will be undefined if the export is missing.\n\n* Change whether certain files are interpreted as ESM or CommonJS ([#1043](https://github.com/evanw/esbuild/issues/1043))\n\n    The bundling algorithm currently doesn't contain any logic that requires flagging modules as CommonJS vs. ESM beforehand. Instead it handles a superset and then sort of decides later if the module should be treated as CommonJS vs. ESM based on whether the module uses the `module` or `exports` variables and/or the `exports` keyword.\n\n    With this release, files that follow [node's rules for module types](https://nodejs.org/api/packages.html#packages_type) will be flagged as explicitly ESM. This includes files that end in `.mjs` and files within a package containing `\"type\": \"module\"` in the enclosing `package.json` file. The CommonJS `module` and `exports` features will be unavailable in these files. This matters most for files without any exports, since then it's otherwise ambiguous what the module type is.\n\n    In addition, files without exports should now accurately fall back to being considered CommonJS. They should now generate a `default` export of an empty object when imported using an `import` statement, since that's what happens in node when you import a CommonJS file into an ESM file in node. Previously the default export could be undefined because these export-less files were sort of treated as ESM but with missing import errors turned into warnings instead.\n\n    This is an edge case that rarely comes up in practice, since you usually never import things from a module that has no exports.\n\nIn addition to the breaking changes above, the following features are also included in this release:\n\n* Initial support for bundling with top-level await ([#253](https://github.com/evanw/esbuild/issues/253))\n\n    Top-level await is a feature that lets you use an `await` expression at the top level (outside of an `async` function). Here is an example:\n\n    ```js\n    let promise = fetch('https://www.example.com/data')\n    export let data = await promise.then(x => x.json())\n    ```\n\n    Top-level await only works in ECMAScript modules, and does not work in CommonJS modules. This means that you must use an `import` statement or an `import()` expression to import a module containing top-level await. You cannot use `require()` because it's synchronous while top-level await is asynchronous. There should be a descriptive error message when you try to do this.\n\n    This initial release only has limited support for top-level await. It is only supported with the `esm` output format, but not with the `iife` or `cjs` output formats. In addition, the compilation is not correct in that two modules that both contain top-level await and that are siblings in the import graph will be evaluated in serial instead of in parallel. Full support for top-level await will come in a future release.\n\n* Add the ability to set `sourceRoot` in source maps ([#1028](https://github.com/evanw/esbuild/pull/1028))\n\n    You can now use the `--source-root=` flag to set the `sourceRoot` field in source maps generated by esbuild. When a `sourceRoot` is present in a source map, all source paths are resolved relative to it. This is particularly useful when you are hosting compiled code on a server and you want to point the source files to a GitHub repo, such as [what AMP does](https://cdn.ampproject.org/v0.mjs.map).\n\n    Here is the description of `sourceRoot` from [the source map specification](https://sourcemaps.info/spec.html):\n\n    > An optional source root, useful for relocating source files on a server or removing repeated values in the \"sources\" entry. This value is prepended to the individual entries in the \"source\" field. If the sources are not absolute URLs after prepending of the \"sourceRoot\", the sources are resolved relative to the SourceMap (like resolving script src in a html document).\n\n    This feature was contributed by [@jridgewell](https://github.com/jridgewell).\n\n* Allow plugins to return custom file watcher paths\n\n    Currently esbuild's watch mode automatically watches all file system paths that are handled by esbuild itself, and also automatically watches the paths of files loaded by plugins when the paths are in the `file` namespace. The paths of files that plugins load in namespaces other than the `file` namespace are not automatically watched.\n\n    Also, esbuild never automatically watches any file system paths that are consulted by the plugin during its processing, since esbuild is not aware of those paths. For example, this means that if a plugin calls `require.resolve()`, all of the various \"does this file exist\" checks that it does will not be watched automatically. So if one of those files is created in the future, esbuild's watch mode will not rebuild automatically even though the build is now outdated.\n\n    To fix this problem, this release introduces the `watchFiles` and `watchDirs` properties on plugin return values. Plugins can specify these to add additional custom file system paths to esbuild's internal watch list. Paths in the `watchFiles` array cause esbuild to rebuild if the file contents change, and paths in the `watchDirs` array cause esbuild to rebuild if the set of directory entry names changes for that directory path.\n\n    Note that `watchDirs` does not cause esbuild to rebuild if any of the contents of files inside that directory are changed. It also does not recursively traverse through subdirectories. It only watches the set of directory entry names (i.e. the output of the Unix `ls` command).\n\n## 0.9.7\n\n* Add support for Android on ARM 64-bit ([#803](https://github.com/evanw/esbuild/issues/803))\n\n    This release includes support for Android in the official `esbuild` package. It should now be possible to install and run esbuild on Android devices through npm.\n\n* Fix incorrect MIME types on Windows ([#1030](https://github.com/evanw/esbuild/issues/1030))\n\n    The web server built into esbuild uses the file extension to determine the value of the `Content-Type` header. This was previously done using the `mime.TypeByExtension()` function from Go's standard library. However, this function is apparently broken on Windows because installed programs can change MIME types in the Windows registry: [golang/go#32350](https://github.com/golang/go/issues/32350). This release fixes the problem by using a copy of Go's `mime.TypeByExtension()` function without the part that reads from the Windows registry.\n\n* Using a top-level return inside an ECMAScript module is now forbidden\n\n    The CommonJS module format is implemented as an anonymous function wrapper, so technically you can use a top-level `return` statement and it will actually work. Some packages in the wild use this to exit early from module initialization, so esbuild supports this. However, the ECMAScript module format doesn't allow top-level returns. With this release, esbuild no longer allows top-level returns in ECMAScript modules.\n\n## 0.9.6\n\n* Expose build options to plugins ([#373](https://github.com/evanw/esbuild/issues/373))\n\n    Plugins can now access build options from within the plugin using the `initialOptions` property. For example:\n\n    ```js\n    let nodeEnvPlugin = {\n      name: 'node-env',\n      setup(build) {\n        const options = build.initialOptions\n        options.define = options.define || {}\n        options.define['process.env.NODE_ENV'] =\n          options.minify ? '\"production\"' : '\"development\"'\n      },\n    }\n    ```\n\n* Fix an edge case with the object spread transform ([#1017](https://github.com/evanw/esbuild/issues/1017))\n\n    This release fixes esbuild's object spread transform in cases where property assignment could be different than property definition. For example:\n\n    ```js\n    console.log({\n      get x() {},\n      ...{x: 1},\n    })\n    ```\n\n    This should print `{x: 1}` but transforming this through esbuild with `--target=es6` causes the resulting code to throw an error. The problem is that esbuild currently transforms this code to a call to `Object.assign` and that uses property assignment semantics, which causes the assignment to throw (since you can't assign to a getter-only property).\n\n    With this release, esbuild will now transform this into code that manually loops over the properties and copies them over one-by-one using `Object.defineProperty` instead. This uses property definition semantics which better matches the specification.\n\n* Fix a TypeScript parsing edge case with arrow function return types ([#1016](https://github.com/evanw/esbuild/issues/1016))\n\n    This release fixes the following TypeScript parsing edge case:\n\n    ```ts\n    ():Array<number>=>{return [1]}\n    ```\n\n    This was tripping up esbuild's TypeScript parser because the `>=` token was split into a `>` token and a `=` token because the `>` token is needed to close the type parameter list, but the `=` token was not being combined with the following `>` token to form a `=>` token. This is normally not an issue because there is normally a space in between the `>` and the `=>` tokens here. The issue only happened when the spaces were removed. This bug has been fixed. Now after the `>=` token is split, esbuild will expand the `=` token into the following characters if possible, which can result in a `=>`, `==`, or `===` token.\n\n* Enable faster synchronous transforms under a flag ([#1000](https://github.com/evanw/esbuild/issues/1000))\n\n    Currently the synchronous JavaScript API calls `transformSync` and `buildSync` spawn a new child process on every call. This is due to limitations with node's `child_process` API. Doing this means `transformSync` and `buildSync` are much slower than `transform` and `build`, which share the same child process across calls.\n\n    There was previously a workaround for this limitation that uses node's `worker_threads` API and atomics to block the main thread while asynchronous communication happens in a worker, but that was reverted due to a bug in node's `worker_threads` implementation. Now that this bug has been fixed by node, I am re-enabling this workaround. This should result in `transformSync` and `buildSync` being much faster.\n\n    This approach is experimental and is currently only enabled if the `ESBUILD_WORKER_THREADS` environment variable is present. If this use case matters to you, please try it out and let me know if you find any problems with it.\n\n* Update how optional chains are compiled to match new V8 versions ([#1019](https://github.com/evanw/esbuild/issues/1019))\n\n    An optional chain is an expression that uses the `?.` operator, which roughly avoids evaluation of the right-hand side if the left-hand side is `null` or `undefined`. So `a?.b` is basically equivalent to `a == null ? void 0 : a.b`. When the language target is set to `es2019` or below, esbuild will transform optional chain expressions into equivalent expressions that do not use the `?.` operator.\n\n    This transform is designed to match the behavior of V8 exactly, and is designed to do something similar to the equivalent transform done by the TypeScript compiler. However, V8 has recently changed its behavior in two cases:\n\n    * Forced call of an optional member expression should propagate the object to the method:\n\n        ```js\n        const o = { m() { return this; } };\n        assert((o?.m)() === o);\n        ```\n\n        V8 bug: https://bugs.chromium.org/p/v8/issues/detail?id=10024\n\n    * Optional call of `eval` must be an indirect eval:\n\n        ```js\n        globalThis.a = 'global';\n        var b = (a => eval?.('a'))('local');\n        assert(b === 'global');\n        ```\n\n        V8 bug: https://bugs.chromium.org/p/v8/issues/detail?id=10630\n\n    This release changes esbuild's transform to match V8's new behavior. The transform in the TypeScript compiler is still emulating the old behavior as of version 4.2.3, so these syntax forms should be avoided in TypeScript code for portability.\n\n## 0.9.5\n\n* Fix parsing of the `[dir]` placeholder ([#1013](https://github.com/evanw/esbuild/issues/1013))\n\n    The entry names feature in the previous release accidentally didn't include parsing for the `[dir]` placeholder, so the `[dir]` placeholder was passed through verbatim into the resulting output paths. This release fixes the bug, which means you can now use the `[dir]` placeholder. Sorry about the oversight.\n\n## 0.9.4\n\n* Enable hashes in entry point file paths ([#518](https://github.com/evanw/esbuild/issues/518))\n\n    This release adds the new `--entry-names=` flag. It's similar to the `--chunk-names=` and `--asset-names=` flags except it sets the output paths for entry point files. The pattern defaults to `[dir]/[name]` which should be equivalent to the previous entry point output path behavior, so this should be a backward-compatible change.\n\n    This change has the following consequences:\n\n    * It is now possible for entry point output paths to contain a hash. For example, this now happens if you pass `--entry-names=[dir]/[name]-[hash]`. This means you can now use esbuild to generate output files such that all output paths have a hash in them, which means it should now be possible to serve the output files with an infinite cache lifetime so they are only downloaded once and then cached by the browser forever.\n\n    * It is now possible to prevent the generation of subdirectories inside the output directory. Previously esbuild replicated the directory structure of the input entry points relative to the `outbase` directory (which defaults to the [lowest common ancestor](https://en.wikipedia.org/wiki/Lowest_common_ancestor) directory across all entry points). This value is substituted into the newly-added `[dir]` placeholder. But you can now omit it by omitting that placeholder, like this: `--entry-names=[name]`.\n\n    * Source map names should now be equal to the corresponding output file name plus an additional `.map` extension. Previously the hashes were content hashes, so the source map had a different hash than the corresponding output file because they had different contents. Now they have the same hash so finding the source map should now be easier (just add `.map`).\n\n    * Due to the way the new hashing algorithm works, all chunks can now be generated fully in parallel instead of some chunks having to wait until their dependency chunks have been generated first. The import paths for dependency chunks are now swapped in after chunk generation in a second pass (detailed below). This could theoretically result in a speedup although I haven't done any benchmarks around this.\n\n    Implementing this feature required overhauling how hashes are calculated to prevent the chicken-and-egg hashing problem due to dynamic imports, which can cause cycles in the import graph of the resulting output files when code splitting is enabled. Since generating a hash involved first hashing all of your dependencies, you could end up in a situation where you needed to know the hash to calculate the hash (if a file was a dependency of itself).\n\n    The hashing algorithm now works in three steps (potentially subject to change in the future):\n\n    1. The initial versions of all output files are generated in parallel, with temporary paths used for any imports of other output files. Each temporary path is a randomly-generated string that is unique for each output file. An initial source map is also generated at this step if source maps are enabled.\n\n        The hash for the first step includes: the raw content of the output file excluding the temporary paths, the relative file paths of all input files present in that output file, the relative output path for the resulting output file (with `[hash]` for the hash that hasn't been computed yet), and contents of the initial source map.\n\n    2. After the initial versions of all output files have been generated, calculate the final hash and final output path for each output file. Calculating the final output path involves substituting the final hash for the `[hash]` placeholder in the entry name template.\n\n        The hash for the second step includes: the hash from the first step for this file and all of its transitive dependencies.\n\n    3. After all output files have a final output path, the import paths in each output file for importing other output files are substituted. Source map offsets also have to be adjusted because the final output path is likely a different length than the temporary path used in the first step. This is also done in parallel for each output file.\n\n        This whole algorithm roughly means the hash of a given output file should change if an only if any input file in that output file or any output file it depends on is changed. So the output path and therefore the browser's cache key should not change for a given output file in between builds if none of the relevant input files were changed.\n\n* Fix importing a path containing a `?` character on Windows ([#989](https://github.com/evanw/esbuild/issues/989))\n\n    On Windows, the `?` character is not allowed in path names. This causes esbuild to fail to import paths containing this character. This is usually fine because people don't put `?` in their file names for this reason. However, the import paths for some ancient CSS code contains the `?` character as a hack to work around a bug in Internet Explorer:\n\n    ```css\n    @font-face {\n      src:\n        url(\"./icons.eot?#iefix\") format('embedded-opentype'),\n        url(\"./icons.woff2\") format('woff2'),\n        url(\"./icons.woff\") format('woff'),\n        url(\"./icons.ttf\") format('truetype'),\n        url(\"./icons.svg#icons\") format('svg');\n    }\n    ```\n\n    The intent is for the bundler to ignore the `?#iefix` part. However, there may actually be a file called `icons.eot?#iefix` on the file system so esbuild checks the file system for both `icons.eot?#iefix` and `icons.eot`. This check was triggering this issue. With this release, an invalid path is considered the same as a missing file so bundling code like this should now work on Windows.\n\n* Parse and ignore the deprecated `@-ms-viewport` CSS rule ([#997](https://github.com/evanw/esbuild/issues/997))\n\n    The [`@viewport`](https://www.w3.org/TR/css-device-adapt-1/#atviewport-rule) rule has been deprecated and removed from the web. Modern browsers now completely ignore this rule. However, in theory it sounds like would still work for mobile versions of Internet Explorer, if those still exist. The https://ant.design/ library contains an instance of the `@-ms-viewport` rule and it currently causes a warning with esbuild, so this release adds support for parsing this rule to disable the warning.\n\n* Avoid mutating the binary executable file in place ([#963](https://github.com/evanw/esbuild/issues/963))\n\n    This release changes the install script for the `esbuild` npm package to use the \"rename a temporary file\" approach instead of the \"write the file directly\" approach to replace the `esbuild` command stub file with the real binary executable. This should hopefully work around a problem with the [pnpm](https://pnpm.js.org/) package manager and its use of hard links.\n\n* Avoid warning about potential issues with `sideEffects` in packages ([#999](https://github.com/evanw/esbuild/issues/999))\n\n    Bare imports such as `import \"foo\"` mean the package is only imported for its side effects. Doing this when the package contains `\"sideEffects\": false` in `package.json` causes a warning because it means esbuild will not import the file since it has been marked as having no side effects, even though the import statement clearly expects it to have side effects. This is usually caused by an incorrect `sideEffects` annotation in the package.\n\n    However, this warning is not immediately actionable if the file containing the import statement is itself in a package. So with this release, esbuild will no longer issue this warning if the file containing the import is inside a `node_modules` folder. Note that even though the warning is no longer there, this situation can still result in a broken bundle if the `sideEffects` annotation is incorrect.\n\n## 0.9.3\n\n* Fix path resolution with the `exports` field for scoped packages\n\n    This release fixes a bug where the `exports` field in `package.json` files was not being detected for scoped packages (i.e. packages of the form `@scope/pkg-name` instead of just `pkg-name`). The `exports` field should now be respected for these kinds of packages.\n\n* Improved error message in `exports` failure case\n\n    Node's new [conditional exports feature](https://nodejs.org/docs/latest/api/packages.html#packages_conditional_exports) can be non-intuitive and hard to use. Now that esbuild supports this feature (as of version 0.9.0), you can get into a situation where it's impossible to import a package if the package's `exports` field in its `package.json` file isn't configured correctly.\n\n    Previously the error message for this looked like this:\n\n    ```\n     > entry.js:1:7: error: Could not resolve \"jotai\" (mark it as external to exclude it from the bundle)\n         1 │ import 'jotai'\n           ╵        ~~~~~~~\n       node_modules/jotai/package.json:16:13: note: The path \".\" is not exported by \"jotai\"\n        16 │   \"exports\": {\n           ╵              ^\n    ```\n\n    With this release, the error message will now provide additional information about why the package cannot be imported:\n\n    ```\n     > entry.js:1:7: error: Could not resolve \"jotai\" (mark it as external to exclude it from the bundle)\n         1 │ import 'jotai'\n           ╵        ~~~~~~~\n       node_modules/jotai/package.json:16:13: note: The path \".\" is not currently exported by package \"jotai\"\n        16 │   \"exports\": {\n           ╵              ^\n       node_modules/jotai/package.json:18:9: note: None of the conditions provided (\"module\", \"require\", \"types\") match any of the currently active conditions (\"browser\", \"default\", \"import\")\n        18 │     \".\": {\n           ╵          ^\n       entry.js:1:7: note: Consider using a \"require()\" call to import this package\n         1 │ import 'jotai'\n           ╵        ~~~~~~~\n    ```\n\n    In this case, one solution could be import this module using `require()` since this package provides an export for the `require` condition. Another solution could be to pass `--conditions=module` to esbuild since this package provides an export for the `module` condition (the `types` condition is likely not valid JavaScript code).\n\n    This problem occurs because this package doesn't provide an import path for ESM code using the `import` condition and also doesn't provide a fallback import path using the `default` condition.\n\n* Mention glob syntax in entry point error messages ([#976](https://github.com/evanw/esbuild/issues/976))\n\n    In this release, including a `*` in the entry point path now causes the failure message to tell you that glob syntax must be expanded first before passing the paths to esbuild. People that hit this are usually converting an existing CLI command to a JavaScript API call and don't know that glob expansion is done by their shell instead of by esbuild. An appropriate fix is to use a library such as [`glob`](https://www.npmjs.com/package/glob) to expand the glob pattern first before passing the paths to esbuild.\n\n* Raise certain VM versions in the JavaScript feature compatibility table\n\n    JavaScript VM feature compatibility data is derived from this dataset: https://kangax.github.io/compat-table/. The scripts that process the dataset expand the data to include all VM versions that support a given feature (e.g. `chrome44`, `chrome45`, `chrome46`, ...) so esbuild takes the minimum observed version as the first version for which the feature is supported.\n\n    However, some features can have subtests that each check a different aspect of the feature. In this case the desired version is the minimum version within each individual subtest, but the maximum of those versions across all subtests (since esbuild should only use the feature if it works in all cases). Previously esbuild computed the minimum version across all subtests, but now esbuild computes the maximum version across all subtests. This means esbuild will now lower JavaScript syntax in more cases.\n\n* Mention the configured target environment in error messages ([#975](https://github.com/evanw/esbuild/issues/975))\n\n    Using newer JavaScript syntax with an older target environment (e.g. `chrome10`) can cause a build error if esbuild doesn't support transforming that syntax such that it is compatible with that target environment. Previously the error message was generic but with this release, the target environment is called outp explicitly in the error message. This is helpful if esbuild is being wrapped by some other tool since the other tool can obscure what target environment is actually being passed to esbuild.\n\n* Fix an issue with Unicode and source maps\n\n    This release fixes a bug where non-ASCII content that ended up in an output file but that was not part of an input file could throw off source mappings. An example of this would be passing a string containing non-ASCII characters to the `globalName` setting with the `minify` setting active and the `charset` setting set to `utf8`. The conditions for this bug are fairly specific and unlikely to be hit, so it's unsurprising that this issue hasn't been discovered earlier. It's also unlikely that this issue affected real-world code.\n\n    The underlying cause is that while the meaning of column numbers in source maps is undefined in the specification, in practice most tools treat it as the number of UTF-16 code units from the start of the line. The bug happened because column increments for outside-of-file characters were incorrectly counted using byte offsets instead of UTF-16 code unit counts.\n\n## 0.9.2\n\n* Fix export name annotations in CommonJS output for node ([#960](https://github.com/evanw/esbuild/issues/960))\n\n    The previous release introduced a regression that caused a syntax error when building ESM files that have a default export with `--platform=node`. This is because the generated export contained the `default` keyword like this: `0 && (module.exports = {default});`. This regression has been fixed.\n\n## 0.9.1\n\n* Fix bundling when parent directory is inaccessible ([#938](https://github.com/evanw/esbuild/issues/938))\n\n    Previously bundling with esbuild when a parent directory is inaccessible did not work because esbuild would try to read the directory to search for a `node_modules` folder and would then fail the build when that failed. In practice this caused issues in certain Linux environments where a directory close to the root directory was inaccessible (e.g. on Android). With this release, esbuild will treat inaccessible directories as empty to allow for the `node_modules` search to continue past the inaccessible directory and into its parent directory. This means it should now be possible to bundle with esbuild in these situations.\n\n* Avoid allocations in JavaScript API stdout processing ([#941](https://github.com/evanw/esbuild/pull/941))\n\n    This release improves the efficiency of the JavaScript API. The API runs the binary esbuild executable in a child process and then communicates with it over stdin/stdout. Previously the stdout buffer containing the remaining partial message was copied after each batch of messages due to a bug. This was unintentional and unnecessary, and has been removed. Now this part of the code no longer involves any allocations. This fix was contributed by [@jridgewell](https://github.com/jridgewell).\n\n* Support conditional `@import` syntax when not bundling ([#953](https://github.com/evanw/esbuild/issues/953))\n\n    Previously conditional CSS imports such as `@import \"print.css\" print;` was not supported at all and was considered a syntax error. With this release, it is now supported in all cases except when bundling an internal import. Support for bundling internal CSS imports is planned but will happen in a later release.\n\n* Always lower object spread and rest when targeting V8 ([#951](https://github.com/evanw/esbuild/issues/951))\n\n    This release causes object spread (e.g. `a = {...b}`) and object rest (e.g. `{...a} = b`) to always be lowered to a manual implementation instead of using native syntax when the `--target=` parameter includes a V8-based JavaScript runtime such as `chrome`, `edge`, or `node`. It turns out this feature is implemented inefficiently in V8 and copying properties over to a new object is around a 2x performance improvement. In addition, doing this manually instead of using the native implementation generates a lot less work for the garbage collector. You can see [V8 bug 11536](https://bugs.chromium.org/p/v8/issues/detail?id=11536) for details. If the V8 performance bug is eventually fixed, the translation of this syntax will be disabled again for V8-based targets containing the bug fix.\n\n* Fix object rest return value ([#956](https://github.com/evanw/esbuild/issues/956))\n\n    This release fixes a bug where the value of an object rest assignment was incorrect if the object rest assignment was lowered:\n\n    ```js\n    // This code was affected\n    let x, y\n    console.log({x, ...y} = {x: 1, y: 2})\n    ```\n\n    Previously this code would incorrectly print `{y: 2}` (the value assigned to `y`) when the object rest expression was lowered (i.e. with `--target=es2017` or below). Now this code will correctly print `{x: 1, y: 2}` instead. This bug did not affect code that did not rely on the return value of the assignment expression, such as this code:\n\n    ```js\n    // This code was not affected\n    let x, y\n    ({x, ...y} = {x: 1, y: 2})\n    ```\n\n* Basic support for CSS page margin rules ([#955](https://github.com/evanw/esbuild/issues/955))\n\n    There are 16 different special at-rules that can be nested inside the `@page` rule. They are defined in [this specification](https://www.w3.org/TR/css-page-3/#syntax-page-selector). Previously esbuild treated these as unknown rules, but with this release esbuild will now treat these as known rules. The only real difference in behavior is that esbuild will no longer warn about these rules being unknown.\n\n* Add export name annotations to CommonJS output for node\n\n    When you import a CommonJS file using an ESM `import` statement in node, the `default` import is the value of `module.exports` in the CommonJS file. In addition, node attempts to generate named exports for properties of the `module.exports` object.\n\n    Except that node doesn't actually ever look at the properties of that object to determine the export names. Instead it parses the CommonJS file and scans the AST for certain syntax patterns. A full list of supported patterns can be found in the [documentation for the `cjs-module-lexer` package](https://github.com/guybedford/cjs-module-lexer#grammar). This library doesn't currently support the syntax patterns used by esbuild.\n\n    While esbuild could adapt its syntax to these patterns, the patterns are less compact than the ones used by esbuild and doing this would lead to code bloat. Supporting two separate ways of generating export getters would also complicate esbuild's internal implementation, which is undesirable.\n\n    Another alternative could be to update the implementation of `cjs-module-lexer` to support the specific patterns used by esbuild. This is also undesirable because this pattern detection would break when minification is enabled, this would tightly couple esbuild's output format with node and prevent esbuild from changing it, and it wouldn't work for existing and previous versions of node that still have the old version of this library.\n\n    Instead, esbuild will now add additional code to \"annotate\" ESM files that have been converted to CommonJS when esbuild's platform has been set to `node`. The annotation is dead code but is still detected by the `cjs-module-lexer` library. If the original ESM file has the exports `foo` and `bar`, the additional annotation code will look like this:\n\n    ```js\n    0 && (module.exports = {foo, bar});\n    ```\n\n    This allows you to use named imports with an ESM `import` statement in node (previously you could only use the `default` import):\n\n    ```js\n    import { foo, bar } from './file-built-by-esbuild.cjs'\n    ```\n\n## 0.9.0\n\n**This release contains backwards-incompatible changes.** Since esbuild is before version 1.0.0, these changes have been released as a new minor version to reflect this (as [recommended by npm](https://docs.npmjs.com/cli/v6/using-npm/semver/)). You should either be pinning the exact version of `esbuild` in your `package.json` file or be using a version range syntax that only accepts patch upgrades such as `^0.8.0`. See the documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\n* Add support for node's `exports` field in `package.json` files ([#187](https://github.com/evanw/esbuild/issues/187))\n\n    This feature was recently added to node. It allows you to rewrite what import paths inside your package map to as well as to prevent people from importing certain files in your package. Adding support for this to esbuild is a breaking change (i.e. code that was working fine before can easily stop working) so adding support for it has been delayed until this breaking change release.\n\n    One way to use this feature is to remap import paths for your package. For example, this would remap an import of `your-pkg/esm/lib.js` (the \"public\" import path) to `your-pkg/dist/esm/lib.js` (the \"private\" file system path):\n\n    ```json\n    {\n      \"name\": \"your-pkg\",\n      \"exports\": {\n        \"./esm/*\": \"./dist/esm/*\",\n        \"./cjs/*\": \"./dist/cjs/*\"\n      }\n    }\n    ```\n\n    Another way to use this feature is to have conditional imports where the same import path can mean different things in different situations. For example, this would remap `require('your-pkg')` to `your-pkg/required.cjs` and `import 'your-pkg'` to `your-pkg/imported.mjs`:\n\n    ```json\n    {\n      \"name\": \"your-pkg\",\n      \"exports\": {\n        \"import\": \"./imported.mjs\",\n        \"require\": \"./required.cjs\"\n      }\n    }\n    ```\n\n    There is built-in support for the `import` and `require` conditions depending on the kind of import and the `browser` and `node` conditions depending on the current platform. In addition, the `default` condition always applies regardless of the current configuration settings and can be used as a catch-all fallback condition.\n\n    Note that when you use conditions, _your package may end up in the bundle multiple times!_ This is a subtle issue that can cause bugs due to duplicate copies of your code's state in addition to bloating the resulting bundle. This is commonly known as the [dual package hazard](https://nodejs.org/docs/latest/api/packages.html#packages_dual_package_hazard). The primary way of avoiding this is to put all of your code in the `require` condition and have the `import` condition just be a light wrapper that calls `require` on your package and re-exports the package using ESM syntax.\n\n    There is also support for custom conditions with the `--conditions=` flag. The meaning of these is entirely up to package authors. For example, you could imagine a package that requires you to configure `--conditions=test,en-US`. Node has currently only endorsed the `development` and `production` custom conditions for recommended use.\n\n* Remove the `esbuild.startService()` API\n\n    Due to [#656](https://github.com/evanw/esbuild/issues/656), Calling `service.stop()` no longer does anything, so there is no longer a strong reason for keeping the `esbuild.startService()` API around. The primary thing it currently does is just make the API more complicated and harder to use. You can now just call `esbuild.build()` and `esbuild.transform()` directly instead of calling `esbuild.startService().then(service => service.build())` or `esbuild.startService().then(service => service.transform())`.\n\n    If you are using esbuild in the browser, you now need to call `esbuild.initialize({ wasmURL })` and wait for the returned promise before calling `esbuild.transform()`. It takes the same options that `esbuild.startService()` used to take. Note that the `esbuild.buildSync()` and `esbuild.transformSync()` APIs still exist when using esbuild in node. Nothing has changed about the synchronous esbuild APIs.\n\n* Remove the `metafile` from `outputFiles` ([#633](https://github.com/evanw/esbuild/issues/633))\n\n    Previously using `metafile` with the API is unnecessarily cumbersome because you have to extract the JSON metadata from the output file yourself instead of it just being provided to you as a return value. This is especially a bummer if you are using `write: false` because then you need to use a for loop over the output files and do string comparisons with the file paths to try to find the one corresponding to the `metafile`. Returning the metadata directly is an important UX improvement for the API. It means you can now do this:\n\n    ```js\n    const result = await esbuild.build({\n      entryPoints: ['entry.js'],\n      bundle: true,\n      metafile: true,\n    })\n    console.log(result.metafile.outputs)\n    ```\n\n* The banner and footer options are now language-specific ([#712](https://github.com/evanw/esbuild/issues/712))\n\n    The `--banner=` and `--footer=` options now require you to pass the file type:\n\n    * CLI:\n\n        ```\n        esbuild --banner:js=//banner --footer:js=//footer\n        esbuild --banner:css=/*banner*/ --footer:css=/*footer*/\n        ```\n\n    * JavaScript\n\n        ```js\n        esbuild.build({\n          banner: { js: '//banner', css: '/*banner*/' },\n          footer: { js: '//footer', css: '/*footer*/' },\n        })\n        ```\n\n    * Go\n\n        ```go\n        api.Build(api.BuildOptions{\n          Banner: map[string]string{\"js\": \"//banner\"},\n          Footer: map[string]string{\"js\": \"//footer\"},\n        })\n        api.Build(api.BuildOptions{\n          Banner: map[string]string{\"css\": \"/*banner*/\"},\n          Footer: map[string]string{\"css\": \"/*footer*/\"},\n        })\n        ```\n\n    This was changed because the feature was originally added in a JavaScript-specific manner, which was an oversight. CSS banners and footers must be separate from JavaScript banners and footers to avoid injecting JavaScript syntax into your CSS files.\n\n* The extensions `.mjs` and `.cjs` are no longer implicit\n\n    Previously the \"resolve extensions\" setting included `.mjs` and `.cjs` but this is no longer the case. This wasn't a good default because it doesn't match node's behavior and could break some packages. You now have to either explicitly specify these extensions or configure the \"resolve extensions\" setting yourself.\n\n* Remove the `--summary` flag and instead just always print a summary ([#704](https://github.com/evanw/esbuild/issues/704))\n\n    The summary can be disabled if you don't want it by passing `--log-level=warning` instead. And it can be enabled in the API by setting `logLevel: 'info'`. I'm going to try this because I believe it will improve the UX. People have this problem with esbuild when they first try it where it runs so quickly that they think it must be broken, only to later discover that it actually worked fine. While this is funny, it seems like a good indication that the UX could be improved. So I'm going to try automatically printing a summary to see how that goes. Note that the summary is not printed if incremental builds are active (this includes the watch and serve modes).\n\n* Rename `--error-limit=` to `--log-limit=`\n\n    This parameter has been renamed because it now applies to both warnings and errors, not just to errors. Previously setting the error limit did not apply any limits to the number of warnings printed, which could sometimes result in a deluge of warnings that are problematic for Windows Command Prompt, which is very slow to print to and has very limited scrollback. Now the log limit applies to the total number of log messages including both errors and warnings, so no more than that number of messages will be printed. The log usually prints log messages immediately but it will now intentionally hold back warnings when approaching the limit to make room for possible future errors during a build. So if a build fails you should be guaranteed to see an error message (i.e. warnings can't use up the entire log limit and then prevent errors from being printed).\n\n* Remove the deprecated `--avoid-tdz` option\n\n    This option is now always enabled and cannot be disabled, so it is being removed from the API. The existing API parameter no longer does anything so this removal has no effect the generated output.\n\n* Remove `SpinnerBusy` and `SpinnerIdle` from the Go API\n\n    These options were part of an experiment with the CLI that didn't work out. Watch mode no longer uses a spinner because it turns out people want to be able to interleave esbuild's stderr pipe with other tools and were getting tripped up by the spinner animation. These options no longer do anything and have been removed.\n\n## 0.8.57\n\n* Fix overlapping chunk names when code splitting is active ([#928](https://github.com/evanw/esbuild/issues/928))\n\n    Code splitting chunks use a content hash in their file name. This is good for caching because it means the file name is guaranteed to change if the chunk contents change, and the file name is guaranteed to stay the same if the chunk contents don't change (e.g. someone only modifies a comment). However, using a pure content hash can cause bugs if two separate chunks end up with the same contents.\n\n    A high-level example would be two identical copies of a library being accidentally collapsed into a single copy. While this results in a smaller bundle, this is incorrect because each copy might need to have its own state and so must be represented independently in the bundle.\n\n    This release fixes this issue by mixing additional information into the file name hash, which is no longer a content hash. The information includes the paths of the input files as well as the ranges of code within the file that are included in the chunk. File paths are used because they are a stable file identifier, but the relative path is used with `/` as the path separator to hopefully eliminate cross-platform differences between Unix and Windows.\n\n* Fix `--keep-names` for lowered class fields\n\n    Anonymous function expressions used in class field initializers are automatically assigned a `.name` property in JavaScript:\n\n    ```js\n    class Example {\n      field1 = () => {}\n      static field2 = () => {}\n    }\n    assert(new Example().field1.name === 'field1')\n    assert(Example.field2.name === 'field2')\n    ```\n\n    This usually doesn't need special handling from esbuild's `--keep-names` option because esbuild doesn't modify field names, so the `.name` property will not change. However, esbuild will relocate the field initializer if the configured language target doesn't support class fields (e.g. `--target=es6`). In that case the `.name` property wasn't preserved even when `--keep-names` was specified. This bug has been fixed. Now the `.name` property should be preserved in this case as long as you enable `--keep-names`.\n\n* Enable importing certain data URLs in CSS and JavaScript\n\n    You can now import data URLs of type `text/css` using a CSS `@import` rule and import data URLs of type `text/javascript` and `application/json` using a JavaScript `import` statement. For example, doing this is now possible:\n\n    ```js\n    import 'data:text/javascript,console.log(\"hello!\");';\n    import _ from 'data:application/json,\"world!\"';\n    ```\n\n    This is for compatibility with node which [supports this feature natively](https://nodejs.org/docs/latest/api/esm.html#esm_data_imports). Importing from a data URL is sometimes useful for injecting code to be evaluated before an external import without needing to generate a separate imported file.\n\n## 0.8.56\n\n* Fix a discrepancy with esbuild's `tsconfig.json` implementation ([#913](https://github.com/evanw/esbuild/issues/913))\n\n    If a `tsconfig.json` file contains a `\"baseUrl\"` value and `\"extends\"` another `tsconfig.json` file that contains a `\"paths\"` value, the base URL used for interpreting the paths should be the overridden value. Previously esbuild incorrectly used the inherited value, but with this release esbuild will now use the overridden value instead.\n\n* Work around the Jest testing framework breaking node's `Buffer` API ([#914](https://github.com/evanw/esbuild/issues/914))\n\n    Running esbuild within a Jest test fails because Jest causes `Buffer` instances to not be considered `Uint8Array` instances, which then breaks the code esbuild uses to communicate with its child process. More info is here: https://github.com/facebook/jest/issues/4422. This release contains a workaround that copies each `Buffer` object into a `Uint8Array` object when this invariant is broken. That should prevent esbuild from crashing when it's run from within a Jest test.\n\n* Better handling of implicit `main` fields in `package.json`\n\n    If esbuild's automatic `main` vs. `module` detection is enabled for `package.json` files, esbuild will now use `index.js` as an implicit `main` field if the `main` field is missing but `index.js` is present. This means if a `package.json` file only contains a `module` field but not a `main` field and the package is imported using both an ESM `import` statement and a CommonJS `require` call, the `index.js` file will now be picked instead of the file in the `module` field.\n\n## 0.8.55\n\n* Align more closely with node's `default` import behavior for CommonJS ([#532](https://github.com/evanw/esbuild/issues/532))\n\n    _Note: This could be considered a breaking change or a bug fix depending on your point of view._\n\n    Importing a CommonJS file into an ESM file does not behave the same everywhere. Historically people compiled their ESM code into CommonJS using Babel before ESM was supported natively. More recently, node has made it possible to use ESM syntax natively but to still import CommonJS files into ESM. These behave differently in many ways but one of the most unfortunate differences is how the `default` export is handled.\n\n    When you import a normal CommonJS file, both Babel and node agree that the value of `module.exports` should be stored in the ESM import named `default`. However, if the CommonJS file used to be an ESM file but was compiled into a CommonJS file, Babel will set the ESM import named `default` to the value of the original ESM export named `default` while node will continue to set the ESM import named `default` to the value of `module.exports`. Babel detects if a CommonJS file used to be an ESM file by the presence of the `exports.__esModule = true` marker.\n\n    This is unfortunate because it means there is no general way to make code work with both ecosystems. With Babel the code `import * as someFile from './some-file'` can access the original `default` export with `someFile.default` but with node you need to use `someFile.default.default` instead. Previously esbuild followed Babel's approach but starting with this release, esbuild will now try to use a blend between the Babel and node approaches.\n\n    This is the new behavior: importing a CommonJS file will set the `default` import to `module.exports` in all cases except when `module.exports.__esModule && \"default\" in module.exports`, in which case it will fall through to `module.exports.default`. In other words: in cases where the default import was previously `undefined` for CommonJS files when `exports.__esModule === true`, the default import will now be `module.exports`. This should hopefully keep Babel cross-compiled ESM code mostly working but at the same time now enable some node-oriented code to start working.\n\n    If you are authoring a library using ESM but shipping it as CommonJS, the best way to avoid this mess is to just never use `default` exports in ESM. Only use named exports with names other than `default`.\n\n* Fix bug when ESM file has empty exports and is converted to CommonJS ([#910](https://github.com/evanw/esbuild/issues/910))\n\n    A file containing the contents `export {}` is still considered to be an ESM file even though it has no exports. However, if a file containing this edge case is converted to CommonJS internally during bundling (e.g. when it is the target of `require()`), esbuild failed to mark the `exports` symbol from the CommonJS wrapping closure as used even though it is actually needed. This resulted in an output file that crashed when run. The `exports` symbol is now considered used in this case, so the bug has been fixed.\n\n* Avoid introducing `this` for imported function calls\n\n    It is possible to import a function exported by a CommonJS file into an ESM file like this:\n\n    ```js\n    import {fn} from './cjs-file.js'\n    console.log(fn())\n    ```\n\n    When you do this, esbuild currently transforms your code into something like this:\n\n    ```js\n    var cjs_file = __toModule(require(\"./cjs-file.js\"));\n    console.log(cjs_file.fn());\n    ```\n\n    However, doing that changes the value of `this` observed by the export `fn`. The property access `cjs_file.fn` is in the syntactic \"call target\" position so the value of `this` becomes the value of `cjs_file`. With this release, esbuild will now use a different syntax in this case to avoid passing `cjs_file` as `this`:\n\n    ```js\n    var cjs_file = __toModule(require(\"./cjs-file.js\"));\n    console.log((0, cjs_file.fn)());\n    ```\n\n    This change in esbuild mirrors a similar [recent TypeScript compiler change](https://github.com/microsoft/TypeScript/pull/35877), and also makes esbuild more consistent with Babel which already does this transformation.\n\n## 0.8.54\n\n* Fix ordering issue with private class methods ([#901](https://github.com/evanw/esbuild/issues/901))\n\n    This release fixes an ordering issue with private class fields where private methods were not available inside class field initializers. The issue affected code such as the following when the compilation target was set to `es2020` or lower:\n\n    ```js\n    class A {\n      pub = this.#priv;\n      #priv() {\n        return 'Inside #priv';\n      }\n    }\n    assert(new A().pub() === 'Inside #priv');\n    ```\n\n    With this release, code that does this should now work correctly.\n\n* Fix `--keep-names` for private class members\n\n    Normal class methods and class fields don't need special-casing with esbuild when the `--keep-names` option is enabled because esbuild doesn't rename property names and doesn't transform class syntax in a way that breaks method names, so the names are kept without needing to generate any additional code.\n\n    However, this is not the case for private class methods and private class fields. When esbuild transforms these for `--target=es2020` and earlier, the private class methods and private class field initializers are turned into code that uses a `WeakMap` or a `WeakSet` for access to preserve the privacy semantics. This ends up breaking the `.name` property and previously `--keep-names` didn't handle this edge case.\n\n    With this release, `--keep-names` will also preserve the names of private class methods and private class fields. That means code like this should now work with `--keep-names --target=es2020`:\n\n    ```js\n    class Foo {\n      #foo() {}\n      #bar = () => {}\n      test() {\n        assert(this.#foo.name === '#foo')\n        assert(this.#bar.name === '#bar')\n      }\n    }\n    ```\n\n* Fix cross-chunk import paths ([#899](https://github.com/evanw/esbuild/issues/899))\n\n    This release fixes an issue with the `--chunk-names=` feature where import paths in between two different automatically-generated code splitting chunks were relative to the output directory instead of relative to the importing chunk. This caused an import failure with the imported chunk if the chunk names setting was configured to put the chunks into a subdirectory. This bug has been fixed.\n\n* Remove the guarantee that direct `eval` can access imported symbols\n\n    Using direct `eval` when bundling is not a good idea because esbuild must assume that it can potentially reach anything in any of the containing scopes. Using direct `eval` has the following negative consequences:\n\n    * All names in all containing scopes are frozen and are not renamed during bundling, since the code in the direct `eval` could potentially access them. This prevents code in all scopes containing the call to direct `eval` from being minified or from being removed as dead code.\n\n    * The entire file is converted to CommonJS. This increases code size and decreases performance because exports are now resolved at run-time instead of at compile-time. Normally name collisions with other files are avoided by renaming conflicting symbols, but direct `eval` prevents symbol renaming so name collisions are prevented by wrapping the file in a CommonJS closure instead.\n\n    * Even with all of esbuild's special-casing of direct `eval`, referencing an ESM `import` from direct `eval` still doesn't necessarily work. ESM imports are live bindings to a symbol from another file and are represented by referencing that symbol directly in the flattened bundle. That symbol may use a different name which could break direct `eval`.\n\n    I recently realized that the last consequence of direct `eval` (the problem about not being able to reference `import` symbols) could cause subtle correctness bugs. Specifically esbuild tries to prevent the imported symbol from being renamed, but doing so could cause name collisions that make the resulting bundle crash when it's evaluated. Two files containing direct `eval` that both import the same symbol from a third file but that import it with different aliases create a system of unsatisfiable naming constraints.\n\n    So this release contains these changes to address this:\n\n    1. Direct `eval` is no longer guaranteed to be able to access imported symbols. This means imported symbols may be renamed or removed as dead code even though a call to direct `eval` could theoretically need to access them. If you need this to work, you'll have to store the relevant imports in a variable in a nested scope and move the call to direct `eval` into that nested scope.\n\n    2. Using direct `eval` in a file in ESM format is now a warning. This is because the semantics of direct `eval` are poorly understood (most people don't intend to use direct `eval` at all) and because the negative consequences of bundling code with direct `eval` are usually unexpected and undesired. Of the few valid use cases for direct `eval`, it is usually a good idea to rewrite your code to avoid using direct `eval` in the first place.\n\n        For example, if you write code that looks like this:\n\n        ```js\n        export function runCodeWithFeatureFlags(code) {\n          let featureFlags = {...}\n          eval(code) // \"code\" should be able to access \"featureFlags\"\n        }\n        ```\n\n        you should almost certainly write the code this way instead:\n\n        ```js\n        export function runCodeWithFeatureFlags(code) {\n          let featureFlags = {...}\n          let fn = new Function('featureFlags', code)\n          fn(featureFlags)\n        }\n        ```\n\n        This still gives `code` access to `featureFlags` but avoids all of the negative consequences of bundling code with direct `eval`.\n\n## 0.8.53\n\n* Support chunk and asset file name templates ([#733](https://github.com/evanw/esbuild/issues/733), [#888](https://github.com/evanw/esbuild/issues/888))\n\n    This release introduces the `--chunk-names=` and `--asset-names=` flags. These flags let you customize the output paths for chunks and assets within the output directory. Each output path is a template and currently supports these placeholders:\n\n    * `[name]`: The original name of the file. This will be `chunk` for chunks and will be the original file name (without the extension) for assets.\n    * `[hash]`: The content hash of the file. This is not necessarily stable across different esbuild versions but will be stable within the same esbuild version.\n\n    For example, if you want to move all chunks and assets into separate subdirectories, you could use `--chunk-names=chunks/[name]-[hash]` and `--asset-names=assets/[name]-[hash]`. Note that the path template should not include the file extension since the file extension is always automatically added to the end of the path template.\n\n    Additional name template features are planned in the future including a `[dir]` placeholder for the relative path from the `outbase` directory to the original input directory as well as an `--entry-names=` flag, but these extra features have not been implemented yet.\n\n* Handle `this` in class static field initializers ([#885](https://github.com/evanw/esbuild/issues/885))\n\n    When you use `this` in a static field initializer inside a `class` statement or expression, it references the class object itself:\n\n    ```js\n    class Foo {\n      static Bar = class extends this {\n      }\n    }\n    assert(new Foo.Bar() instanceof Foo)\n    ```\n\n    This case previously wasn't handled because doing this is a compile error in TypeScript code. However, JavaScript does allow this so esbuild needs to be able to handle this. This edge case should now work correctly with this release.\n\n* Do not warn about dynamic imports when `.catch()` is detected ([#893](https://github.com/evanw/esbuild/issues/893))\n\n    Previously esbuild avoids warning about unbundled `import()` expressions when using the `try { await import(_) }` pattern, since presumably the `try` block is there to handle the run-time failure of the `import()` expression failing. This release adds some new patterns that will also suppress the warning: `import(_).catch(_)`, `import(_).then(_).catch(_)`, and `import(_).then(_, _)`.\n\n* CSS namespaces are no longer supported\n\n    [CSS namespaces](https://developer.mozilla.org/en-US/docs/Web/CSS/@namespace) are a weird feature that appears to only really be useful for styling XML. And the world has moved on from XHTML to HTML5 so pretty much no one uses CSS namespaces anymore. They are also complicated to support in a bundler because CSS namespaces are file-scoped, which means:\n\n    * Default namespaces can be different in different files, in which case some default namespaces would have to be converted to prefixed namespaces to avoid collisions.\n\n    * Prefixed namespaces from different files can use the same name, in which case some prefixed namespaces would need to be renamed to avoid collisions.\n\n    Instead of implementing all of that for an extremely obscure feature, CSS namespaces are now just explicitly not supported. The code to handle `@namespace` has been removed from esbuild. This will likely not affect anyone, especially because bundling code using CSS namespaces with esbuild didn't even work correctly in the first place.\n\n## 0.8.52\n\n* Fix a concurrent map write with the `--inject:` feature ([#878](https://github.com/evanw/esbuild/issues/878))\n\n    This release fixes an issue where esbuild could potentially crash sometimes with a concurrent map write when using injected files and entry points that were neither relative nor absolute paths. This was an edge case where esbuild's low-level file subsystem was being used without being behind a mutex lock. This regression was likely introduced in version 0.8.21. The cause of the crash has been fixed.\n\n* Provide `kind` to `onResolve` plugins ([#879](https://github.com/evanw/esbuild/issues/879))\n\n    Plugins that add `onResolve` callbacks now have access to the `kind` parameter which tells you what kind of import is being resolved. It will be one of the following values:\n\n    * `\"entry-point\"` in JS (`api.ResolveEntryPoint` in Go)\n\n        An entry point provided by the user\n\n    * `\"import-statement\"` in JS (`api.ResolveJSImportStatement` in Go)\n\n        A JavaScript `import` or `export` statement\n\n    * `\"require-call\"` in JS (`api.ResolveJSRequireCall` in Go)\n\n        A JavaScript call to `require(...)` with a string argument\n\n    * `\"dynamic-import\"` in JS (`api.ResolveJSDynamicImport` in Go)\n\n        A JavaScript `import(...)` expression with a string argument\n\n    * `\"require-resolve\"` in JS (`api.ResolveJSRequireResolve` in Go)\n\n        A JavaScript call to `require.resolve(...)` with a string argument\n\n    * `\"import-rule\"` in JS (`api.ResolveCSSImportRule` in Go)\n\n        A CSS `@import` rule\n\n    * `\"url-token\"` in JS (`api.ResolveCSSURLToken` in Go)\n\n        A CSS `url(...)` token\n\n    These values are pretty much identical to the `kind` field in the JSON metadata file.\n\n## 0.8.51\n\n* The stderr log format now contains line numbers after file names ([#865](https://github.com/evanw/esbuild/issues/865))\n\n    Error messages in stderr now have a line and column number after the file name.\n\n    Before:\n\n    ```\n     > src/structs/RTree.js: warning: Duplicate key \"compareMinX\" in object literal\n        469 │     compareMinX: function (a, b)\n            ╵     ~~~~~~~~~~~\n       src/structs/RTree.js: note: The original \"compareMinX\" is here\n        206 │     compareMinX: compareNodeMinX,\n            ╵     ~~~~~~~~~~~\n    ```\n\n    After:\n\n    ```\n     > src/structs/RTree.js:469:4: warning: Duplicate key \"compareMinX\" in object literal\n        469 │     compareMinX: function (a, b)\n            ╵     ~~~~~~~~~~~\n       src/structs/RTree.js:206:4: note: The original \"compareMinX\" is here\n        206 │     compareMinX: compareNodeMinX,\n            ╵     ~~~~~~~~~~~\n    ```\n\n    This should make log messages slightly easier to parse if you want to parse stderr instead of using esbuild's API. Previously you needed a multi-line regular expression to get the line number, but now that the line number is duplicated in two places you should only need a single-line regular expression.\n\n    Note that this is still the hacky way to get error information and is potentially unstable, since it will break if the log format changes. Log messages are mainly intended for humans. The straightforward and stable way to do this is still to use esbuild's API, which returns log messages as an array of objects.\n\n* Allow `--define` with `import.meta`\n\n    The `--define` feature lets you replace specific identifiers and member expression chains with compile-time constants. However, it previously didn't work with `import.meta` because this is a special case in the grammar. The `import` keyword is not actually an identifier expression. This distinction isn't helpful though, and it's not unreasonable to want to use the `--define` feature to replace `import.meta` properties too.\n\n    With this release, it's now possible to use e.g. `--define:import.meta.foo=123` to replace specific properties accessed off of the `import.meta` object as well as to use e.g. `--define:import.meta={\\\"foo\\\":123}` to substitute the entire `import.meta` expression with something else.\n\n* Fix a race condition with multiple injected files ([#871](https://github.com/evanw/esbuild/issues/871))\n\n    Using multiple injected files could cause a data race that trips Go's race detector. The data race has been fixed in this release. The fix was contributed by [@Deleplace](https://github.com/Deleplace).\n\n* Change `--serve` behavior to serve on all interfaces ([#866](https://github.com/evanw/esbuild/issues/866))\n\n    The default address for the `--serve` flag has changed from `127.0.0.1` (serve on the loopback interface) to `0.0.0.0` (serve on all interfaces). You can still manually specify either one using `--serve=127.0.0.1:8000` or `--serve=0.0.0.0:8000`. This just changes the default behavior that happens when you pass `--serve` with no host address (or when you just use the `--servedir=` flag without `--serve=`).\n\n    In addition, you can now also specify an IPv6 address. Previously there was a parsing issue that prevented this. For example, you can pass `--serve=[::1]:8000` to serve on the loopback interface and `--serve=[::]:8000` to serve on all interfaces.\n\n* Change the import resolution rules of absolute paths ([#862](https://github.com/evanw/esbuild/issues/862))\n\n    Previously absolute paths were considered to be pre-resolved by the resolver (in contrast to relative and package paths, which need to be converted to an absolute path). This meant that absolute paths which did not actually exist caused a failure in the loader when it tried to load the path instead of in the resolver when it tried to resolve the path.\n\n    With the previous change in version 0.8.47 to support removing URL query and/or hash parameters from the path, path resolution can now be run multiple times. If path resolution fails and the path contains a `?` and/or `#`, path resolution is re-run with the URL query/hash parameters removed. It is problematic to consider absolute paths to be pre-resolved because it means that paths containing query/hash parameters make the loader try to load the wrong path, and do not run the resolver again with the parameter suffix removed.\n\n    In this release, esbuild will now validate absolute paths in the resolver. So invalid paths will now fail in the resolver and retry without the parameter suffix instead of failing in the loader, which correctly handles a parameter suffix on absolute paths. In addition, this release now handles implicit file extensions on absolute paths. This makes esbuild a more accurate copy of [node's module resolution algorithm](https://nodejs.org/api/modules.html#modules_all_together), which does this as well.\n\n* Output files in `metafile` now have `entryPoint` ([#711](https://github.com/evanw/esbuild/issues/711))\n\n    There is now an optional `entryPoint` property on each output file in the JSON metadata file generated with the `--metafile=` flag. It is only present for output files that are the bundled results of entry point files, and contains the path name of the corresponding input entry point file. This property is not present on other kinds of output files (e.g. code splitting chunks). This feature was contributed by [@remorses](https://github.com/remorses).\n\n## 0.8.50\n\n* Using direct `eval` now pulls in `module` and `exports`\n\n    Use of direct `eval` forces the file to become a CommonJS module and disables dead code elimination in the entire file. The CommonJS closure is necessary to avoid name collisions with other modules, since `eval` means symbols in the file can no longer be renamed to avoid collisions.\n\n    However, the CommonJS `module` and `exports` variables that are arguments to the closure previously weren't considered to be used in this scenario, meaning they may be omitted as dead code for size reasons. This could cause code inside `eval` to behave incorrectly. Now use of direct `eval` automatically counts as a use of both `module` and `exports` so these variables should now always be present in this case.\n\n* Always remove all `\"use asm\"` directives ([#856](https://github.com/evanw/esbuild/issues/856))\n\n    The asm.js subset of JavaScript has complicated validation rules that are triggered by this directive. The parser and code generator in esbuild was not designed with asm.js in mind and round-tripping asm.js code through esbuild will very likely cause it to no longer validate as asm.js. When this happens, V8 prints a warning and people don't like seeing the warning. The warning looks like this:\n\n    ```\n    (node:58335) V8: example.js:3 Invalid asm.js: Unexpected token\n    (Use `node --trace-warnings ...` to show where the warning was created)\n    ```\n\n    I am deliberately not attempting to preserve the validity of asm.js code because it's a complicated legacy format and it's obsolete now that WebAssembly exists. By removing all `\"use asm\"` directives, the code will just become normal JavaScript and work fine without generating a warning.\n\n* Fix a variable hoisting edge case ([#857](https://github.com/evanw/esbuild/issues/857))\n\n    It is allowed to use a nested `var` hoisted declaration with the same name as a top-level function declaration. In that case the two symbols should merge and be treated as the same symbol:\n\n    ```js\n    async function x() {}\n    {\n      var x;\n    }\n    ```\n\n    The parser previously allowed this for regular functions but not for async or generator functions. Now with this release, this behavior is also allowed for these special kinds of functions too.\n\n* Remove empty CSS rules when minifying ([#851](https://github.com/evanw/esbuild/pull/851))\n\n    Empty rules with no content such as `div {}` are now removed when CSS is minified. This change was contributed by [@susiwen8](https://github.com/susiwen8).\n\n## 0.8.49\n\n* Work around a problem with `pnpm` and `NODE_PATH` ([#816](https://github.com/evanw/esbuild/issues/816))\n\n    In version 0.8.43, esbuild added support for node's [`NODE_PATH`](https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders) environment variable which contains a list of global folders to use during path resolution. However, this causes a problem when esbuild is installed with [pnpm](https://pnpm.js.org/), an alternative JavaScript package manager. Specifically pnpm adds a bogus path to `NODE_PATH` that doesn't exist but that has a file as a parent directory. Previously this caused esbuild to fail with the error `not a directory`. Now with this release, esbuild will ignore this bogus path instead of giving an error.\n\n* Add more names to the global no-side-effect list ([#842](https://github.com/evanw/esbuild/issues/842))\n\n    This release adds almost all known globals from the browser and node to the list of known globals. Membership in this list means accessing the global is assumed to have no side effects. That means tree shaking is allowed to remove unused references to these globals. For example, since `HTMLElement` is now in the known globals list, the following class will now be removed when unused:\n\n    ```js\n    class MyElement extends HTMLElement {\n    }\n    ```\n\n    In addition, membership in this list relaxes ordering constraints for the purposes of minification. It allows esbuild to reorder references to these globals past other expressions. For example, since `console.log` is now in the known globals list, the following simplification will now be performed during minification:\n\n    ```js\n    // Original\n    export default (a) => {\n      if (a) console.log(b); else console.log(c)\n    }\n\n    // Minified (previous release)\n    export default (a) => {\n      a ? console.log(b) : console.log(c);\n    };\n\n    // Minified (this release)\n    export default (a) => {\n      console.log(a ? b : c);\n    };\n    ```\n\n    This transformation is not generally safe because the `console.log` property access might evaluate code which could potentially change the value of `a`. This is only considered safe in this instance because `console.log` is now in the known globals list.\n\n    Note that membership in this list does not say anything about whether the function has side effects when called. It only says that the identifier has no side effects when referenced. So `console.log()` is still considered to have side effects even though `console.log` is now considered to be free of side effects.\n\n    The following globals are not on the list and are considered to have side effects:\n\n    * `scrollX`\n    * `scrollY`\n    * `innerWidth`\n    * `innerHeight`\n    * `pageXOffset`\n    * `pageYOffset`\n    * `localStorage`\n    * `sessionStorage`\n\n    Accessing layout-related properties can trigger a layout and accessing storage-related properties can throw an exception if certain privacy settings are enabled. Both of these behaviors are considered side effects.\n\n* Fix a TypeScript parser regression ([#846](https://github.com/evanw/esbuild/issues/846))\n\n    Restrictions on array and object destructuring patterns in the previous release introduced a regression where arrays or objects in TypeScript code could fail to parse if they were wrapped in a double layer of parentheses. This was due to the speculative parsing of arrow function arguments. The regression has been fixed.\n\n* Add the Go-specific `cli.ParseServeOptions()` API ([#834](https://github.com/evanw/esbuild/issues/834))\n\n    This API is specifically for people trying to emulate esbuild's CLI in Go. It lets you share esbuild's logic of parsing the `--serve=` and `--servedir=` flags. Use it like this:\n\n    ```go\n    serveOptions, args, err := cli.ParseServeOptions([]string{\n      \"--serve=8000\",\n    })\n    buildOptions, err := cli.ParseBuildOptions(args)\n    result := api.Serve(serveOptions, buildOptions)\n    ```\n\n## 0.8.48\n\n* Fix some parsing edge cases ([#835](https://github.com/evanw/esbuild/issues/835))\n\n    This release fixes the following edge cases:\n\n    * Code using `in` inside a template literal inside a for loop initializer such as ``for (let x = `${a in b ? '0' : '1'}`; false; );`` is now allowed. Previously the `in` operator was incorrectly considered to be part of a for-in loop.\n\n    * In TypeScript, it's not valid to have a newline in between the `async` and the `<` tokens inside the code `async <T>() => {}`. Previously this was incorrectly treated as an asynchronous arrow function expression.\n\n    * Code of the form `new async()` must construct the function called `async`. Previously this was incorrectly treated as `new (async())()` instead due to the speculative parsing of asynchronous arrow functions.\n\n    * Code of the form `new async () => {}` must not be allowed. Previously this was incorrectly allowed since the speculative parsing of asynchronous arrow functions did not check the precedence level.\n\n    * It's not valid to start an initializer expression in a for-of loop with the token `let` such as `for (let.foo of bar) {}`. This is now forbidden. In addition, the code generator now respects this rule so `for ((let.foo) of bar) {}` is now printed as `for ((let).foo of bar) {}`.\n\n    * Array and object binding patterns do not allow a comma after rest elements, so code such as `[...a, b] = [c]` is invalid. This case is correctly handled by esbuild. However, it's possible to have both an array or object binding pattern and an array or object literal on the left-hand side of a destructuring assignment such as `[[...a, b].c] = [d]`. In that case it should be allowed for a comma to come after the spread element in the array or object literal expression. Previously this was incorrectly treated as an error by esbuild.\n\n    * It's technically allowed (although perhaps not ever actually useful) to call `super()` from within a default argument initializer like this:\n\n        ```js\n        class Derived extends Base {\n          constructor(arg = super()) {\n          }\n        }\n        ```\n\n        Previously esbuild did not permit this, which is incorrect. Doing this is now permitted.\n\n    * It is an error to use `arguments` in a class field initializer such as `class { x = arguments[0] }`, but it is not an error to use `arguments` in a computed class property name such as `class { [arguments[0]] = x }` or inside TypeScript decorators such as `class { @decorator(arguments[0]) x() {} }`. Previously all of these cases were an error in esbuild, which is incorrect. Using `arguments` inside computed class property names and TypeScript decorators is now allowed.\n\n    * It is not permitted to use a function declaration inside an if statement such as `if (0) function f() {}` in strict mode. Previously this was allowed, but this is now forbidden.\n\n    * It is not permitted to re-declare a generator and/or asynchronous function declaration inside a block scope:\n\n        ```js\n        // This is allowed\n        function *a() {}\n        function *a() {}\n\n        // This is allowed\n        function f() {\n          function *b() {}\n          function *b() {}\n        }\n\n        // This is not allowed\n        {\n          function *c() {}\n          function *c() {}\n        }\n        ```\n\n        The parser now enforces this rule.\n\n    * Legacy octal escape sequences are octal escape sequences other than `\\0` with a single zero. These are forbidden in untagged template literals and in all strings in strict mode code. Previously esbuild didn't enforce this rule, but it is now enforced.\n\n    * Technically the directive prologue is allowed to contain multiple directives, so strict mode should still be applied even if a `\"use strict\";` directive is preceded by another directive. For example, `\"use \\000\"; \"use strict\";` should be a syntax error because strict mode is active. This technicality has now been implemented.\n\n    * It is supposed to be a syntax error if a use strict directive is inside a function with a non-simple parameter list, such as `(x = 1) => { 'use strict' }`. Previously esbuild allowed this code, but now this code is a syntax error.\n\n    * It is forbidden for a template literal tag to be an optional chain such as `` a?.b`c` ``. This rule is now enforced by esbuild, so code like this is now a syntax error. In addition, the code generator now avoids generating this syntax by wrapping any optional chain template literal tags in parentheses.\n\n    * According to the standard, all code inside a class statement or expression should be in strict mode. Previously esbuild treated code inside a class as the same strict mode status as the surrounding code, but now code in a class is always interpreted as strict mode code.\n\n    * Duplicate bindings in the same parameter list are not allowed if the parameter list isn't simple, such as in the code `function f(a, [a]) {}`, or if the parameter list belongs to an arrow function or a method. This rule is now enforced by esbuild's parser, so doing this is now a syntax error.\n\n    * Array and object destructuring patterns are only valid if they are not surrounded by parentheses. Previously esbuild incorrectly allowed code such as `([]) = []` and `({}) = {}`. This invalid code is now a syntax error.\n\n    * It is now an error to use the shorthand property syntax `({yield})` inside a generator and `({await})` inside an asynchronous function. Previously those cases were incorrectly allowed.\n\n    * A newline in between `async` and a method name is no longer allowed. Instead, this is a syntax error inside an object literal and a class field inside a class body.\n\n* Remove the local web server feature from the WebAssembly package ([#836](https://github.com/evanw/esbuild/issues/836))\n\n    This feature didn't work anyway (maybe sockets don't work with Go's WebAssembly target?) and including it added around 3mb of unnecessary extra code to the WebAssembly module file. Removing this brings the size of the WebAssembly module from around 11mb down to 8.3mb.\n\n## 0.8.47\n\n* Release native binaries for the Apple M1 chip ([#550](https://github.com/evanw/esbuild/issues/550))\n\n    Previously installing esbuild on a M1 actually installed the x86-64 version, which required the Rosetta 2 translator. This was because Go hadn't yet released support for the M1. Now that Go 1.16.0 has been released, esbuild can support the M1 natively. It's supported by esbuild starting with this release. There are reports of the native version being 1.4x faster than the translated version. This change was contributed by [@rtsao](https://github.com/rtsao).\n\n* Omit warning about `require.someProperty` when targeting CommonJS ([#812](https://github.com/evanw/esbuild/issues/812))\n\n    The `require.cache` property allows introspecting the state of the `require` cache, generally without affecting what is imported/bundled.\n\n    Since esbuild's static analyzer only detects direct calls to `require`, it currently warns about uses of `require` in any situation other than a direct call since that means the value is \"escaping\" the analyzer. This is meant to detect and warn about indirect calls such as `['fs', 'path'].map(require)`.\n\n    However, this warning is not relevant when accessing a property off of the `require` object such as `require.cache` because a property access does not result in capturing the value of `require`. Now a warning is no longer generated for `require.someProperty` when the output format is `cjs`. This allows for the use of features such as `require.cache` and `require.extensions`. This fix was contributed by [@huonw](https://github.com/huonw).\n\n* Support ignored URL parameters at the end of import paths ([#826](https://github.com/evanw/esbuild/issues/826))\n\n    If path resolution fails, ebuild will now try again with the URL query and/or fragment removed. This helps handle ancient CSS code like this that contains hacks for Internet Explorer:\n\n    ```css\n    @font-face {\n      src:\n        url(\"./themes/default/assets/fonts/icons.eot?#iefix\") format('embedded-opentype'),\n        url(\"./themes/default/assets/fonts/icons.woff2\") format('woff2'),\n        url(\"./themes/default/assets/fonts/icons.woff\") format('woff'),\n        url(\"./themes/default/assets/fonts/icons.ttf\") format('truetype'),\n        url(\"./themes/default/assets/fonts/icons.svg#icons\") format('svg');\n    }\n    ```\n\n    Previously path resolution would fail because these files do not end with the `.eot?#iefix` or `.svg#icons` extensions. Now path resolution should succeed. The URL query and fragment are not unconditionally stripped because there is apparently [code in the wild that uses `#` as a directory name](https://github.com/medikoo/es5-ext/tree/3ddd2066b19e7c25a782869a304ae35d8188c8f1/string/%23). So esbuild will still try to resolve the full import path first and only try to reinterpret the path as a URL if that fails.\n\n* Prevent paths starting with `/` from being used as relative paths on Windows ([#822](https://github.com/evanw/esbuild/issues/822))\n\n    On Windows, absolute paths start with a drive letter such as `C:\\...` instead of with a slash like `/...`. This means that paths starting with a `/` can actually be used as relative paths. For example, this means an import of `/subfolder/image.png` will match the file at the path `./subfolder/image.png`. This is problematic for Windows users because they may accidentally make use of these paths and then try to run their code on a non-Windows platform only for it to fail to build.\n\n    Now paths starting with a `/` are always treated as an absolute path on all platforms. This means you can no longer import files at a relative path that starts with `/` on Windows. You should be using a `./` prefix instead.\n\n* Warn when importing a path with the wrong case\n\n    Importing a path with the wrong case (e.g. `File.js` instead of `file.js`) will work on Windows and sometimes on macOS because they have case-insensitive file systems, but it will never work on Linux because it has a case-sensitive file system. To help you make your code more portable and to avoid cross-platform build failures, esbuild now issues a warning when you do this.\n\n## 0.8.46\n\n* Fix minification of `.0` in CSS ([#804](https://github.com/evanw/esbuild/issues/804))\n\n    If you write `.0` instead of `0` in CSS and enabled `--minify`, esbuild would previously minify this token incorrectly (the token was deleted). This bug has been fixed and esbuild should now minify this token to `0`.\n\n* Support range requests in local HTTP server\n\n    The local HTTP server built in to esbuild now supports [range requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests), which are necessary for video playback in Safari. This means you can now use `<video>` tags in your HTML pages with esbuild's local HTTP server.\n\n## 0.8.45\n\n* Add the `--servedir=` flag ([#796](https://github.com/evanw/esbuild/issues/796))\n\n    The `--serve` flag starts a local web server and serves the files that would normally be written to the output directory. So for example if you had an entry point called `src/app.ts` and an output directory of `--outdir=www/js`, using esbuild with `--serve` would expose the generated output file via http://localhost:8000/app.js (but not write anything to `www/js`). This can then be used in combination with your normal development server (running concurrently on another port) by adding `<script src=\"http://localhost:8000/app.js\"></script>` in your HTML file. So esbuild with the `--serve` flag is meant to augment your normal development server, not replace it.\n\n    This release introduces a new `--servedir=` flag which gives you the option of replacing your normal development server with esbuild. The directory you pass here will be \"underlayed\" below the output directory. Specifically when an incoming HTTP request comes in esbuild will first check if it matches one of the generated output files and if so, serve the output file directly from memory. Otherwise esbuild will fall back to serving content from the serve directory on the file system. In other words, server's URL structure behaves like a normal file server in a world where esbuild had written the generated output files to the file system (even though the output files actually only exist in memory).\n\n    So for example if you had an entry point called `src/app.ts` and an output directory of `--outdir=www/js`, using esbuild with `--servedir=www` would expose the entire contents of the `www` directory via http://localhost:8000/ except for the http://localhost:8000/js/app.js URL which would contain the compiled contents of `src/app.ts`. This lets you have a `www/index.html` file containing just `<script src=\"/js/app.js\"></script>` and use one web server instead of two.\n\n    The benefit of doing things this way is that you can use the exact same HTML pages in development and production. In development you can run esbuild with `--servedir=` and esbuild will serve the generated output files directly. For production you can omit that flag and esbuild will write the generated files to the file system. In both cases you should be getting the exact same result in the browser with the exact same code in both development and production.\n\n    This will of course not support all workflows, but that's intentional. This is designed to be a quality-of-life improvement for the simple case of building a small static website with some HTML, JavaScript, and CSS. More advanced setups may prefer to avoid the `--servedir=` feature and e.g. configure a NGINX reverse proxy to esbuild's local server to integrate esbuild into a larger existing development setup.\n\n    One unintended consequence of this feature is that esbuild can now be used as a general local HTTP server via `esbuild --servedir=.`. Without any entry points, esbuild won't actually build anything and will just serve files like a normal web server. This isn't the intended use case but it could perhaps be a useful side effect of this feature.\n\n* Remove absolute paths for disabled packages from source maps ([#786](https://github.com/evanw/esbuild/issues/786))\n\n    This change is similar to the one from the previous release for disabled files, but it applies to package paths instead of relative paths. It's relevant when using packages that override dependencies with alternative packages using the `browser` field in their `package.json` file. Using relative paths instead of absolute paths fixes a determinism issue where build output was different on different systems. This fix was contributed by [@eelco](https://github.com/eelco).\n\n* Handle absolute paths in `tsconfig.json` ([#792](https://github.com/evanw/esbuild/issues/792))\n\n    Some automatically-generated `tsconfig.json` paths can have absolute paths in them. This is allowed by the TypeScript compiler (specifically in the `paths` and `extends` fields). With this release, esbuild now supports absolute paths in `paths` and `extends` too.\n\n* Change the watch mode output format ([#793](https://github.com/evanw/esbuild/issues/793))\n\n    Previously esbuild would print a \"...\" animation to the console while watch mode was scanning for changes. The intent of this was to a) not take up too much space in the terminal and b) show that esbuild's watch mode isn't frozen. Since the release I have gotten feedback that this isn't desirable. People want more feedback about what's happening and want to be able to run regexes over the stderr stream instead of using esbuild's actual API.\n\n    This release changes the output format for watch mode. Now esbuild will print `[watch] build started` when watch mode triggers a rebuild and `[watch] build finished` when the rebuild is complete. Any build errors will be printed in between those two log messages.\n\n    Note that this means esbuild's watch mode output is now more verbose, especially when there are frequent file changes. If you want to hide these new messages you can use `--log-level=` with a level other than `info`.\n\n## 0.8.44\n\n* Create a logo for esbuild ([#61](https://github.com/evanw/esbuild/issues/61))\n\n    This release introduces a logo for esbuild:\n\n    <p>\n      &nbsp; &nbsp; &nbsp;\n      <img width=\"100\" height=\"100\" src=\"https://esbuild.github.io/favicon.svg\">\n    </p>\n\n    Inspirations for the logo include:\n\n    * **The fast-forward symbol** because esbuild is extremely fast and because one of esbuild's goals is to accelerate the evolution of the whole web tooling ecosystem.\n\n    * **The right-shift symbol** because esbuild's production optimizations make your code smaller and because esbuild itself contains many low-level optimizations for speed.\n\n    Having a logo for esbuild should make it easier to include esbuild in lists of other tools since the other tools often all have logos.\n\n* Add support for node's `--preserve-symlinks` flag ([#781](https://github.com/evanw/esbuild/issues/781))\n\n    This release adds the `--preserve-symlinks` flag which behaves like [the corresponding flag in node](https://nodejs.org/api/cli.html#cli_preserve_symlinks). Without the flag, esbuild and node will use the real path (after resolving symlinks) as the identity of a file. This means that a given file can only be instantiated once. With the flag, esbuild and node will use the original path (without resolving symlinks) as the identity of a file. This means that a given file can be instantiated multiple times, once for every symlink pointing to it. Each copy will have its own identity so the resulting bundle may contain duplicate files. This option is useful if your code relies on this flag in node (or the [`resolve.symlinks` setting in Webpack](https://webpack.js.org/configuration/resolve/#resolvesymlinks)).\n\n* Ignore a leading byte order mark (BOM) in CSS files ([#776](https://github.com/evanw/esbuild/issues/776))\n\n    Some text editors insert a U+FEFF code point at the start of text files. This is a zero-width non-breaking space character. Using one at the start of a file is a convention which is meant to indicate that the contents of the file are UTF-8 encoded. When this is done, the character is called a [byte order mark](https://en.wikipedia.org/wiki/Byte_order_mark).\n\n    Unlike JavaScript, CSS does not treat U+FEFF as whitespace. It is treated as an identifier instead. This was causing esbuild to misinterpret files starting with a BOM as starting with an extra identifier, which could then cause the initial CSS rule in the file to be parsed incorrectly.\n\n    Now esbuild will skip over a BOM if it's present before beginning to parse CSS. This should prevent issues when working with these files.\n\n* Add message notes to the API\n\n    The internal logging system has the ability to attach additional notes to messages to provide more information. These show up as additional log messages in the terminal when using the command-line interface. Here is an example of a note:\n\n    ```\n     > src/structs/RTree.js: warning: Duplicate key \"compareMinX\" in object literal\n        469 │     compareMinX: function (a, b)\n            ╵     ~~~~~~~~~~~\n       src/structs/RTree.js: note: The original \"compareMinX\" is here\n        206 │     compareMinX: compareNodeMinX,\n            ╵     ~~~~~~~~~~~\n    ```\n\n    With this release, notes are also supported in the JS and Go APIs. This means you can now generate your own notes using plugins as well as inspect the notes generated by esbuild.\n\n* Add origin information to errors from plugins ([#780](https://github.com/evanw/esbuild/issues/780))\n\n    Errors thrown during JavaScript plugin callback evaluation will now be annoated to show where that plugin callback was registered. That looks like this:\n\n    ```\n     > example-plugin.js: error: [example-plugin] foo.bar is not a function\n        15 │         foo.bar();\n           ╵             ^\n        at ./example-plugin.js:15:13\n        at ./node_modules/esbuild/lib/main.js:750:34\n\n       example-plugin.js: note: This error came from the \"onLoad\" callback registered here\n        13 │       build.onLoad({ filter: /.*/ }, args => {\n           ╵             ~~~~~~\n        at setup (./example-plugin.js:13:13)\n        at handlePlugins (./node_modules/esbuild/lib/main.js:668:7)\n    ```\n\n    This should make it easier to debug crashes in plugin code.\n\n* Fix a regression with the synchronous JavaScript API ([#784](https://github.com/evanw/esbuild/issues/784))\n\n    In version 0.8.39, a change was made to avoid dangling esbuild processes when node exits abnormally. The change introduced a periodic ping between the child esbuild process and its host process. If the ping doesn't go through, the child process is able to detect that the host process is no longer there. Then it knows to exit since it's no longer being used.\n\n    This caused a problem with the synchronous JavaScript API calls which run the esbuild child process in a single-response mode. The ping message was interpreted as a second response and tripped up the message protocol. Pings are only useful for the asynchronous API calls. Running the pings during synchronous API calls was unintentional. With this release pings are no longer run for synchronous API calls so this regression should be fixed.\n\n* Remove absolute paths for disabled files from source maps ([#785](https://github.com/evanw/esbuild/issues/785))\n\n    Files can be ignored (i.e. set to empty) using the [`browser` field in `package.json`](https://github.com/defunctzombie/package-browser-field-spec/tree/4f296871cee64e60124841c06c06511885152f19#ignore-a-module). Specifically, you can set the `browser` field to a map where the key is the module name and the value is `false`. This is a convention followed by several bundlers including esbuild.\n\n    Previously ignoring a file caused that file's path to appear as an absolute path in any generated source map. This is problematic because it means different source maps will be generated on different systems, since the absolute path contains system-specific directory information. Now esbuild will treat these paths the same way it treats other paths and will put a relative path in the source map.\n\n## 0.8.43\n\n* Support the `XDG_CACHE_HOME` environment variable ([#757](https://github.com/evanw/esbuild/issues/757))\n\n    On Linux, the install script for esbuild currently caches downloaded binary executables in `~/.cache/esbuild/bin`. This change means esbuild will now try installing to `$XDG_CACHE_HOME/esbuild/bin` instead of the `XDG_CACHE_HOME` environment variable exists. This allows you to customize the cache directory on Linux. The specification that defines `XDG_CACHE_HOME` is [here](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html).\n\n* Further improve constant folding of branches ([#765](https://github.com/evanw/esbuild/issues/765))\n\n    At a high level, this release adds the following substitutions to improve constant folding and dead code elimination:\n\n    * `if (anything && falsyWithSideEffects)` → `if (anything, falsyWithSideEffects)`\n    * `if (anything || truthyWithSideEffects)` → `if (anything, truthyWithSideEffects)`\n    * `if (anything && truthyNoSideEffects)` → `if (anything)`\n    * `if (anything || falsyNoSideEffects)` → `if (anything)`\n    * `if (anything, truthyOrFalsy)` → `anything; if (truthyOrFalsy)`\n\n    And also these substitutions for unused expressions:\n\n    * `primitive == primitive` → `primitive, primitive`\n    * `typeof identifier` → (remove entirely)\n\n    The actual substitutions are more complex since they are more comprehensive but they essentially result in this high-level behavior. Note that these substitutions are only done when minification is enabled.\n\n* Fix an edge case with CSS variable syntax ([#760](https://github.com/evanw/esbuild/issues/760))\n\n    CSS variables are whitespace-sensitive even though other CSS syntax is mostly not whitespace sensitive. It is apparently common for this to cause problems with CSS tooling that pretty-prints and minifies CSS, including esbuild before this release. Some examples of issues with other tools include [postcss/postcss#1404](https://github.com/postcss/postcss/issues/1404) and [tailwindlabs/tailwindcss#2889](https://github.com/tailwindlabs/tailwindcss/issues/2889). The issue affects code like this:\n\n    ```css\n    div {\n      --some-var: ;\n      some-decl: var(--some-var, );\n    }\n    ```\n\n    It would be a change in semantics to minify this code to either `--some-var:;` or `var(--some-var,)` due to the whitespace significance of CSS variables, so such transformations are invalid. With this release, esbuild should now preserve whitespace in these two situations (CSS variable declarations and CSS variable references).\n\n* Add support for recursive symlinks during path resolution ([#766](https://github.com/evanw/esbuild/issues/766))\n\n    Previously recursive symlinks (a symlink that points to another symlink) were an unhandled case in the path resolution algorithm. Now these cases should be supported up to a depth of 256 symlinks. This means esbuild's path resolution should now work with multi-level `yarn link` scenarios.\n\n* Fix subtle circular dependency issue ([#758](https://github.com/evanw/esbuild/issues/758))\n\n    If esbuild is used to transform TypeScript to JavaScript without bundling (i.e. each file is transformed individually), the output format is CommonJS, and the original TypeScript code contains an import cycle where at least one of the links in the cycle is an `export * as` re-export statement, there could be certain situations where evaluating the transformed code results in an import being `undefined`. This is caused by the `__esModule` marker being added after the call to `require()` for the first transformed re-export statement. The fix was to move the marker to before the first call to `require()`. The `__esModule` marker is a convention from Babel that esbuild reuses which marks a module as being originally in the ECMAScript module format instead of the CommonJS module format.\n\n* Add support for the `NODE_PATH` environment variable\n\n    This is a rarely-used feature of Node's module resolution algorithm. From [the documentation](https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders):\n\n    > If the `NODE_PATH` environment variable is set to a colon-delimited list of absolute paths, then Node.js will search those paths for modules if they are not found elsewhere.\n    >\n    > On Windows, `NODE_PATH` is delimited by semicolons (`;`) instead of colons.\n\n    The CLI takes the list of node paths from the value of the `NODE_PATH` environment variable, but the JS and Go APIs take the list as an array of strings instead (called `nodePaths` in JS and `NodePaths` in Go).\n\n## 0.8.42\n\n* Fix crash with block-level function declaration and `--keep-names` ([#755](https://github.com/evanw/esbuild/issues/755))\n\n    This release fixes a crash with block-level function declarations and the `--keep-names` option. The crash affected code that looks like this:\n\n    ```js\n    if (true) function f() {}\n    assert.strictEqual(f.name, 'f')\n    ```\n\n* Disallow additional features in strict mode\n\n    This change improves esbuild's compliance with the JavaScript specification. It is now an error to use legacy octal numeric literals and the identifiers `implements`, `interface`, `let`, `package`, `private`, `protected`, `public`, `static`, and `yield` in strict mode code.\n\n* Basic support for watch mode with plugins ([#752](https://github.com/evanw/esbuild/issues/752))\n\n    With this release, watch mode should now work with simple [on-load plugins](https://esbuild.github.io/plugins/#load-callbacks). Watch mode is implemented by tracking all file system accesses made by esbuild as it does a build. However, this doesn't catch external file system accesses such as those made by plugins. Now if an on-load plugin is used on a path in the `file` namespace, esbuild will also read the file during watch mode so that watch mode is aware of the file system access. Note that there is not yet API support for a plugin to return additional paths for watch mode to monitor.\n\n* Make JavaScript API error format more consistent ([#745](https://github.com/evanw/esbuild/issues/745))\n\n    If a JavaScript error is thrown while validating the build options, the thrown error should now have `errors` and `warnings` properties just like normal build errors. Previously these properties were only present if the build itself failed but not if build options were invalid. This consistency should make it easier to process errors from the build API call.\n\n## 0.8.41\n\n* Fix memory leak with watch mode when using the CLI ([#750](https://github.com/evanw/esbuild/issues/750))\n\n    This release fixes a memory leak when using `--watch` from the CLI (command-line interface). When esbuild was in this state, every incremental build resulted in more memory being consumed. This problem did not affect users of the JS API or Go API, only users of the CLI API.\n\n    The problem was that the GC (garbage collector) was disabled. Oops. This is done by default for speed when you use esbuild via the CLI, which makes sense for most CLI use cases because the process is usually short-lived and doesn't need to waste time cleaning up memory. But it does not make sense for flags that cause esbuild to be a long-running process.\n\n    Previously the only exception to this rule was the `--serve` flag. When I added watch mode, I forgot to enable GC for the `--watch` flag too. With this release, the GC is enabled for both the `--serve` and the `--watch` flags so esbuild should no longer leak memory in watch mode.\n\n* Special-case certain syntax with `--format=esm` ([#749](https://github.com/evanw/esbuild/issues/749))\n\n    You can now no longer use the following syntax features with the `esm` output format:\n\n    * The `with` statement: `with (x) {}`\n    * Delete of a bare identifier: `delete x`\n\n    In addition, the following syntax feature is transformed when using the `esm` output format:\n\n    * For-in variable initializers: `for (var x = y in {}) {}` → `x = y; for (var x in {}) {}`\n\n    The reason is because all JavaScript engines interpret code in the `esm` output format as strict mode and these syntax features are disallowed in strict mode. Note that this new strict mode handling behavior in esbuild is only dependent on the output format. It does not depend on the presence or absence of `\"use strict\"` directives.\n\n* Basic `\"use strict\"` tracking\n\n    The JavaScript parser now tracks `\"use strict\"` directives and propagates strict mode status through the code. In addition, files containing the `import` and/or `export` keywords are also considered to be in strict mode. Strict mode handling is complex and esbuild currently doesn't implement all strict mode checks. But the changes in this release are a starting point. It is now an error to use certain syntax features such as a `with` statement within a strict mode scope.\n\n* Fix a minifier bug with `with` statements\n\n    The minifier removes references to local variables if they are unused. However, that's not correct to do inside a `with` statement scope because what appears to be an identifier may actually be a property access, and property accesses could have arbitrary side effects if they resolve to a getter or setter method. Now all identifier expressions inside `with` statements are preserved when minifying.\n\n* Transform block-level function declarations\n\n    Block-level function declarations are now transformed into equivalent syntax that avoids block-level declarations. Strict mode and non-strict mode have subtly incompatible behavior for how block-level function declarations are interpreted. Doing this transformation prevents problems with code that was originally strict mode that is run as non-strict mode and vice versa.\n\n    Now esbuild uses the presence or absence of a strict mode scope to determine how to interpret the block-level function declaration and then converts it to the equivalent unambiguous syntax such that it works the same regardless of whether or not the current scope is in strict mode:\n\n    ```js\n    // This original code:\n    while (!y) {\n      function y() {}\n    }\n\n    // is transformed into this code in strict mode:\n    while (!y) {\n      let y2 = function() {};\n    }\n\n    // and into this code when not in strict mode:\n    while (!y) {\n      let y2 = function() {};\n      var y = y2;\n    }\n    ```\n\n## 0.8.40\n\n* Fix TypeScript parameter decorators on class constructors ([#734](https://github.com/evanw/esbuild/issues/734))\n\n    This release fixes a TypeScript translation bug where parameter decorators on class constructors were translated incorrectly. Affected code looks like this:\n\n    ```js\n    class Example {\n      constructor(@decorator param: any) {}\n    }\n    ```\n\n    This bug has been fixed. In addition, decorators are no longer allowed on class constructors themselves because they are not allowed in TypeScript.\n\n* Resolve `browser` entries in `package.json` with no file extension ([#740](https://github.com/evanw/esbuild/issues/740))\n\n    This fix changes how esbuild interprets the `browser` field in `package.json`. It will now remap imports without a file extension to `browser` map entries without a file extension, which improves compatibility with Webpack. Specifically, a `package.json` file with `\"browser\": {\"./file\": \"./something.js\"}` will now match an import of `./file`. Previously the `package.json` file had to contain something like `\"browser\": {\"./file.js\": \"./something.js\"}` instead. Note that for compatibility with the rest of the ecosystem, a remapping of `./file` will counter-intuitively _not_ match an import of `./file.js` even though it works fine in the other direction.\n\n* Warning: npm v7 bug may prevent esbuild installation\n\n    This is a warning for people reading these release notes, not a code change. I have discovered a bug in npm v7 where your `package-lock.json` file can become corrupted such that no `postinstall` scripts are run. This bug affects all packages with `postinstall` scripts, not just esbuild, and happens when running npm v7 on a `package-lock.json` file from npm v6 or earlier. It seems like deleting and regenerating your `package-lock.json` file is a valid workaround that should get esbuild working again.\n\n## 0.8.39\n\n* Fix the JavaScript watch mode API exiting early ([#730](https://github.com/evanw/esbuild/issues/730))\n\n    The previous release contained a bug that caused the JavaScript watch mode API to exit early in some cases. This bug should now be fixed. The problem was caused by some code that shouldn't even need to exist now that you are no longer required to call `stop()` on an esbuild service created by `startService()` (it was made optional in version 0.8.32). I took the opportunity to clean up the internals of esbuild's JavaScript API implementation which ended up removing the entire section of code that contained this bug.\n\n* Add an API option for a per-build working directory ([#689](https://github.com/evanw/esbuild/issues/689))\n\n    You can now use the `absWorkingDir` API option to customize the current working directory. It will default to the value of `process.cwd()` at the time of the call to `startService()` when not specified, which matches the existing behavior. The working directory is used for a few different things including resolving relative paths given as API options to absolute paths and pretty-printing absolute paths as relative paths in log messages.\n\n    In addition to being a useful feature, this change also simplifies esbuild's internals. Previously esbuild had to maintain separate child processes if the current working directory was changed in between build API calls. Now esbuild will always reuse the same child process across all build API calls. The `stop()` call on the `startService()` API is also now a no-op (it doesn't do anything anymore) and the `startService()` API may be removed in future releases.\n\n* Fix stray `esbuild` process after `node` exits ([#643](https://github.com/evanw/esbuild/issues/643))\n\n    I discovered that using esbuild's JavaScript incremental build API could result in the child `esbuild` process not exiting when the parent `node` process exits. This was due to a reference counting issue. The bug has been fixed so this shouldn't happen anymore.\n\n## 0.8.38\n\n* Implement a simple cross-platform watch mode ([#21](https://github.com/evanw/esbuild/issues/21))\n\n    With this release, you can use the `--watch` flag to run esbuild in watch mode which watches the file system for changes and does an incremental build when something has changed. The watch mode implementation uses polling instead of OS-specific file system events for portability.\n\n    Note that it is still possible to implement watch mode yourself using esbuild's incremental build API and a file watcher library of your choice if you don't want to use a polling-based approach. Also note that this watch mode feature is about improving developer convenience and does not have any effect on incremental build time (i.e. watch mode is not faster than other forms of incremental builds).\n\n    The new polling system is intended to use relatively little CPU vs. a traditional polling system that scans the whole directory tree at once. The file system is still scanned regularly but each scan only checks a random subset of your files to reduce CPU usage. This means a change to a file will be picked up soon after the change is made but not necessarily instantly. With the current heuristics, large projects should be completely scanned around every 2 seconds so in the worst case it could take up to 2 seconds for a change to be noticed. However, after a change has been noticed the change's path goes on a short list of recently changed paths which are checked on every scan, so further changes to recently changed files should be noticed almost instantly.\n\n* Add `pluginData` to pass data between plugins ([#696](https://github.com/evanw/esbuild/issues/696))\n\n    You can now return additional data from a plugin in the optional `pluginData` field and it will be passed to the next plugin that runs in the plugin chain. So if you return it from an `onLoad` plugin, it will be passed to the `onResolve` plugins for any imports in that file, and if you return it from an `onResolve` plugin, an arbitrary one will be passed to the `onLoad` plugin when it loads the file (it's arbitrary since the relationship is many-to-one). This is useful to pass data between different plugins without them having to coordinate directly.\n\n## 0.8.37\n\n* Improve ambiguous import handling ([#723](https://github.com/evanw/esbuild/issues/723))\n\n    It is an error to try to import a name from a file where there are multiple matching exports due to multiple `export * from` statements from files which export that name. This release contains a few improvements to ambiguous import handling:\n\n    1. This release fixes a bug where named export shadowing didn't work correctly with multiple levels of re-exports. A named export closer in the re-export chain is supposed to hide a named export deeper in the re-export chain without causing an ambiguous import. The bug caused this case to be incorrectly flagged as an error even though it should have been allowed. This case is now allowed without an error.\n\n    2. Previously the error message just said that there was an ambiguous import but didn't have any additional information. With this release, the error message also points out where the two different exports that have collided are in their original source files. Hopefully this should make it quicker to diagnose these types of issues.\n\n    3. Real JavaScript environments only treat ambiguous imports as an error if they are explicitly a named import. Using the `import * as` syntax and then accessing the ambiguous import with a property access results in `undefined` instead of an error. Previously esbuild also treated this case as an error because it automatically rewrites star-import syntax to named-import syntax to improve tree shaking. With this release, this case is now treated as a warning instead of an error and the import will be automatically replaced with an `undefined` literal in the bundled code.\n\n* Reuse automatically-generated temporary `*.node` files ([#719](https://github.com/evanw/esbuild/pull/719))\n\n    The previous change to hide the automatically-generated N-API native node extensions from Yarn 2 writes these `*.node` files to the system's temporary directory. A new one was being created on each run which is wasteful even though they are only a few kilobytes in size. With this release `*.node` files will now be reused if they are already present in the system's temporary directory, so a new one is no longer created on each run. This fix was contributed by [@kzc](https://github.com/kzc).\n\n* Fix the serve API with `outfile` ([#707](https://github.com/evanw/esbuild/issues/707))\n\n    This release fixes a bug where the serve API did not work with the `outfile` setting. Using this setting with the serve API should now work fine.\n\n* Warn about duplicate keys in object literals\n\n    Using a duplicate key in an object literal such as `{x: 1, x: 2}` is now a warning. This is allowed in JavaScript but results in subsequent keys overwriting the previous key. It's usually a copy/paste error and isn't ever useful so it's worth warning about.\n\n* Avoid generating duplicate keys in JSON metadata\n\n    The `output` map that is generated when the `metafile` feature is active could potentially have duplicate keys if the `file` loader is used, there are multiple entry points, and two or more entry points reference the same file. This is harmless because both keys mapped to the same value, but it's confusing and unnecessary. Duplicate keys are no longer present in the output map in this latest release.\n\n* Make the JSON metafile structure match the type definitions ([#726](https://github.com/evanw/esbuild/pull/726))\n\n    Previously `imports` and/or `exports` could be missing from entries in the `output` map in certain cases (specifically for source maps and files loaded with the `file` loader). This was problematic because the TypeScript type definitions for the metafile say that the `imports` and `exports` properties are non-optional. With this release, the `imports` and `exports` properties are now always present so the existing TypeScript type definitions are now accurate.\n\n* Update from Go 1.15.5 to Go 1.15.7\n\n    The version of Go used to build the released binary executables on npm is now Go 1.15.7. This change shouldn't result in any visible changes to esbuild. It was only upgraded because the Go extension for the VSCode IDE now uses the official `gopls` Go language service and this extension wanted the latest version of Go.\n\n## 0.8.36\n\n* Fix an issue with writing large files to stdout using the WebAssembly executable\n\n    The previous release introduced a regression where large output files written to stdout were incorrectly truncated when using the WebAssembly `esbuild` command. This regression was due to a missing callback to the JavaScript `write()` function when called on the stdout stream. The regression has been fixed.\n\n* Hide the N-API native node extensions from Yarn 2\n\n    The previous release introduced some very small (1-2kb) `*.node` native extensions to fix a bug with node failing to exit properly. However, this causes Yarn 2 to unzip the esbuild package, which is undesirable. This release puts these native node extensions inside JavaScript code instead to hide them from Yarn 2. The native extensions are written to a temporary file at run-time if necessary.\n\n## 0.8.35\n\n* Fix a commonly-missed corner case with `await` inside `**`\n\n    I recently discovered an interesting discussion about JavaScript syntax entitled [\"Most implementations seem to have missed that `await x ** 2` is not legal\"](https://github.com/tc39/ecma262/issues/2197). Indeed esbuild has missed this, but this is not surprising because V8 has missed this as well and I usually test esbuild against V8 to test if esbuild is conformant with the JavaScript standard. Regardless, it sounds like the result of the discussion is that the specification should stay the same and implementations should be fixed. This release fixes this bug in esbuild's parser. The syntax `await x ** 2` is no longer allowed and parentheses are now preserved for the syntax `(await x) ** 2`.\n\n* Allow namespaced names in JSX syntax ([#702](https://github.com/evanw/esbuild/issues/702))\n\n    XML-style namespaced names with a `:` in the middle are a part of the [JSX specification](https://facebook.github.io/jsx/) but they are explicitly unimplemented by React and TypeScript so esbuild doesn't currently support them. However, there was a user request to support this feature since it's part of the JSX specification and esbuild's JSX support can be used for non-React purposes. So this release now supports namespaced names in JSX expressions:\n\n    ```jsx\n    let xml =\n      <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n               xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n        <rdf:Description rdf:ID=\"local-record\">\n          <dc:title>Local Record</dc:title>\n        </rdf:Description>\n      </rdf:RDF>\n    ```\n\n    This JSX expression is now transformed by esbuild to the following JavaScript:\n\n    ```js\n    let xml = React.createElement(\"rdf:RDF\", {\n      \"xmlns:rdf\": \"http://www.w3.org/1999/02/22-rdf-syntax-ns#\",\n      \"xmlns:dc\": \"http://purl.org/dc/elements/1.1/\"\n    }, React.createElement(\"rdf:Description\", {\n      \"rdf:ID\": \"local-record\"\n    }, React.createElement(\"dc:title\", null, \"Local Record\")));\n    ```\n\n    Note that if you are trying to namespace your React components, this is _not_ the feature to use. You should be using a `.` instead of a `:` for namespacing your React components since `.` resolves to a JavaScript property access.\n\n* Fix `worker: false` in esbuild's browser-based JavaScript API\n\n    The browser-based JavaScript API creates a web worker by default but this can be disabled by passing `worker: false`. When you do this the WebAssembly code is run in the current thread which will lock up the thread. This is mainly useful if you're calling the JavaScript API from within a web worker and you want to avoid creating another nested web worker.\n\n    This option was unintentionally broken when the internal JavaScript web worker source code was moved from an inline function to a string in version 0.5.20. The regression has been fixed and the `worker: false` scenario now has test coverage.\n\n* Fix absolute paths with the `esbuild-wasm` package on Windows ([#687](https://github.com/evanw/esbuild/issues/687))\n\n    The package `esbuild-wasm` has an `esbuild` command implemented using WebAssembly instead of using native code. It uses node's WebAssembly implementation and calls methods on node's `fs` module to access the file system.\n\n    Go's `path/filepath` module has a bug where Windows paths are interpreted as Unix paths when targeting WebAssembly: [golang/go#43768](https://github.com/golang/go/issues/43768). This causes multiple issues including absolute paths such as `C:\\path\\to\\file.js` being interpreted as relative paths (since they don't start with a `/`) and being joined onto the end of other paths.\n\n    To fix this, esbuild now does all of its own path handling instead of using Go's path handling code. The esbuild code base now contains a forked copy of `path/filepath` that can handle both Windows and Unix paths. The decision about which one to use is made at run-time. When targeting WebAssembly, the presence of the `C:\\` directory is used to determine if Windows-style paths should be used.\n\n    With this release, it should now be possible to use Windows-style paths with esbuild's WebAssembly implementation on Windows.\n\n* Fix using stdin with the `esbuild-wasm` package on Windows ([#687](https://github.com/evanw/esbuild/issues/687))\n\n    Node has an old bug ([nodejs/node#19831](https://github.com/nodejs/node/issues/19831), [nodejs/node#35997](https://github.com/nodejs/node/issues/35997)) where `fs.read` returns an EOF error at the end of stdin on Windows. This causes Go's WebAssembly implementation to panic when esbuild tries to read from stdin.\n\n    The workaround was to manually check for this case and then ignore the error in this specific case. With this release, it should now be possible to pipe something to the `esbuild` command on Windows.\n\n* Fix stdout and stderr not supporting Unicode in the `esbuild-wasm` package on Windows ([#687](https://github.com/evanw/esbuild/issues/687))\n\n    Node's `fs.write` API is broken when writing Unicode to stdout and stderr on Windows, and this will never be fixed: [nodejs/node#24550](https://github.com/nodejs/node/issues/24550). This is problematic for Go's WebAssembly implementation because it uses this API for writing to all file descriptors.\n\n    The workaround is to manually intercept the file descriptors for stdout and stderr and redirect them to `process.stdout` and `process.stderr` respectively. Passing Unicode text to `write()` on these objects instead of on the `fs` API strangely works fine. So with this release, Unicode text should now display correctly when using esbuild's WebAssembly implementation on Windows (or at least, as correctly as the poor Unicode support in Windows Command Prompt allows).\n\n* Add a hack for faster command-line execution for the WebAssembly module in certain cases\n\n    Node has an unfortunate bug where the node process is unnecessarily kept open while a WebAssembly module is being optimized: https://github.com/nodejs/node/issues/36616. This means cases where running `esbuild` should take a few milliseconds can end up taking many seconds instead.\n\n    The workaround is to force node to exit by ending the process early. This is done in one of two ways depending on the exit code. For non-zero exit codes (i.e. when there is a build error), the `esbuild` command now calls `process.kill(process.pid)` to avoid the hang.\n\n    For zero exit codes, the `esbuild` command now loads a N-API native node extension that calls the operating system's `exit(0)` function. This is done without requiring `node-gyp` by precompiling each supported platform and just including all of them in the `esbuild-wasm` package since they are so small. If this hack doesn't work in certain cases, the process should exit anyway just potentially many seconds later. Currently the only supported platforms for this hack are 64-bit macOS, Windows, and Linux.\n\n* Fix non-absolute paths with the `esbuild-wasm` package in the browser ([#693](https://github.com/evanw/esbuild/issues/693))\n\n    When using esbuild in the browser via WebAssembly, it was not possible to specify an non-absolute output path. Normally you can do this and esbuild will just convert it to an absolute path by resolving it as a relative path from the current working directory. However, Go's WebAssembly implementation has no current working directory so the conversion operation to an absolute path failed, causing esbuild's API to fail.\n\n    With this release, esbuild should now behave as if the current working directory is `/` in the browser. For example, this means calling the `build()` API with `outfile: 'file.js'` should now generate an output file called `/file.js` instead of causing an error.\n\n## 0.8.34\n\n* Fix a parser bug about suffix expressions after an arrow function body ([#701](https://github.com/evanw/esbuild/issues/701))\n\n    The JavaScript parser incorrectly handled suffix expressions after a non-expression arrow function body. In practice, this came up when a semicolon was omitted from the end of an expression statement and the following expression could be considered a suffix expression:\n\n    ```js\n    x = () => {}\n    (y)\n    ```\n\n    This was incorrectly parsed as `(x = () => {})(y);` instead of `x = () => {}; y;`. With this release, this edge case should now be parsed correctly.\n\n* Add new `neutral` platform to help text ([#695](https://github.com/evanw/esbuild/pull/695))\n\n    The new `--platform=neutral` API option that was added in the previous release was incorrectly not listed in the CLI help text for the platform feature. This omission has been fixed. The fix was contributed by [@hardfist](https://github.com/hardfist).\n\n## 0.8.33\n\n* Fix esbuild potentially exiting early during incremental rebuilds\n\n    The change in the previous release to make calling `stop()` optional caused a regression for incremental rebuilds where calling `rebuild()` could potentially cause the process to exit early before the incremental rebuild is completed. This is because the implementation of `rebuild()` was missing a reference count to track that the service is now temporarily needed again. This omission was an oversight, and has now been fixed.\n\n* Fix using the new `sourcesContent` option with the transform API ([#682](https://github.com/evanw/esbuild/issues/682))\n\n    Due to an oversight, the `sourcesContent: false` option that was added in version 0.8.27 didn't work with the JavaScript transform API. This was unintentional and has been fixed. This fix was contributed by [@jschaf](https://github.com/jschaf).\n\n* Insert the object spread shim in constructor methods after the `super()` call ([#678](https://github.com/evanw/esbuild/issues/678))\n\n    This fixes an issue with the transform for object spread to older compile targets. Previously the following code would be transformed to code that crashes when run if the compile target is `es2017` or lower:\n\n    ```js\n    class Derived extends Base {\n      prop = null;\n      constructor({ ...args }) {\n        super(args);\n      }\n    }\n    ```\n\n    This code was incorrectly compiled to something like this, which will throw `ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor`:\n\n    ```js\n    class Derived extends Base {\n      constructor(_a) {\n        __publicField(this, \"prop\", null);\n        var args = __rest(_a, []);\n        super(args);\n      }\n    }\n    ```\n\n    With this release, it will now be compiled to something like this instead:\n\n    ```js\n    class Derived extends Base {\n      constructor(_a) {\n        var args = __rest(_a, []);\n        super(args);\n        __publicField(this, \"prop\", null);\n      }\n    }\n    ```\n\n* Add the `--platform=neutral` API option ([#674](https://github.com/evanw/esbuild/issues/674))\n\n    There are currently two platform values: `browser` (the default) and `node`. These settings are a convenient way to configure multiple defaults for other API options for maximum compatibility. However, some users want to configure everything themselves so esbuild does not assume any platform-specific behavior. In this case you can now use `--platform=neutral` to disable platform-specific default values. Note that this means if you want to use npm-style packages you will have to configure a main field yourself with something like `--main-fields=main`.\n\n* Provide minified and non-minified versions of in-browser API library ([#616](https://github.com/evanw/esbuild/issues/616))\n\n    The in-browser JavaScript API libraries for esbuild are in the [esbuild-wasm](https://www.npmjs.com/package/esbuild-wasm) package. There are two: `esbuild-wasm/lib/browser.js` in UMD format and `esbuild-wasm/esm/browser.js` in ESM format. Previously these were minified since they contain a large string of JavaScript that cannot be minified by other tools. Now they are no longer minified, and there are new minified versions available at `esbuild-wasm/lib/browser.min.js` and `esbuild-wasm/esm/browser.min.js`.\n\n## 0.8.32\n\n* Calling `stop()` on the JavaScript API is now optional ([#656](https://github.com/evanw/esbuild/pull/656))\n\n    The JavaScript implementation of esbuild's API now calls `unref()` internally so node will now exit even if the internal long-lived esbuild process is still running. You should no longer need to explicitly call `stop()` on the service returned by `startService()`, which simplifies service lifetime management. This feature was contributed by [@SalvatorePreviti](https://github.com/SalvatorePreviti).\n\n* Fix bug in metafile path generation ([#662](https://github.com/evanw/esbuild/issues/662))\n\n    Certain import path metadata in the JSON file generated by the `--metafile` setting could be incorrect in scenarios with code splitting active and multiple entry points in different subdirectories. The incorrect paths referred to cross-chunk imports of other generated code splitting chunks and were incorrectly relative to the subdirectory inside the output directory instead of relative to the output directory itself. This issue has been fixed.\n\n* Add `kind` to import paths in metafile JSON ([#655](https://github.com/evanw/esbuild/issues/655))\n\n    The `--metafile` flag generates build metadata in JSON format describing the input and output files in the build. Previously import path objects only had a `path` property. With this release, they now also have a `kind` property that describes the way the file was imported. The value is a string that is equal to one of the following values:\n\n    For JavaScript files:\n\n    * `import-statement`\n    * `require-call`\n    * `dynamic-import`\n    * `require-resolve`\n\n    For CSS files:\n\n    * `import-rule`\n    * `url-token`\n\n* Add support for TypeScript 4.2 syntax\n\n    Most of the new features included in the [TypeScript 4.2 beta announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-4-2-beta/) are type system features that don't apply to esbuild. But there's one upcoming feature that adds new syntax: `abstract` construct signatures. They look like this:\n\n    ```ts\n    let Ctor: abstract new () => HasArea = Shape;\n    ```\n\n    This new syntax can now be parsed by esbuild.\n\n* Add `detail` to errors and warnings ([#654](https://github.com/evanw/esbuild/issues/654))\n\n    Errors and warnings returned by the JavaScript and Go APIs now have a `detail` property which contains the original error. This is relevant if a custom JavaScript exception is thrown or a custom Go `error` is returned from inside a plugin callback.\n\n* Disable code warnings inside `node_modules` directories even with plugins ([#666](https://github.com/evanw/esbuild/issues/666))\n\n    Some of the warnings that esbuild generates exist to point out suspicious looking code that is likely a bug. An example is `typeof x == 'null'` since the `typeof` operator never generates the string `null`. Arguably these warnings belong in a linter instead of in esbuild since esbuild is a bundler, but I figured that some warnings about obviously broken code would still be helpful because many people don't run linters. It's part of my quest to improve software quality. And these warnings have caught real bugs in published code so they aren't meaningless. The warning must be considered very unlikely to be a false positive to be included.\n\n    A change was added in version 0.7.4 to exclude files inside `node_modules` directories from these warnings. Even if the warnings flag a real bug, the warning is frustrating as a user because it's mostly non-actionable. The only resolution other than turning off warnings is to file an issue with the package, since code in published packages is immutable.\n\n    However, since then the plugin API has been released and this behavior didn't apply if the import path was resolved by a plugin. It only applied if the import path was resolved by esbuild itself. That problem is fixed in this release. Now these warnings will be omitted from any file with `node_modules` in its path, even if the path originated from a plugin.\n\n* Remove the warning about self-assignment ([#666](https://github.com/evanw/esbuild/issues/666))\n\n    This warning was added in version 0.8.11 and warns about self-assignment such as `x = x`. The rationale is that this is likely a copy/paste error. However, it triggers too often for cross-compiled TypeScript code so the false positive rate is too high. The warning has now been removed.\n\n* Disable constant folding for the `?:` operator when not minifying ([#657](https://github.com/evanw/esbuild/issues/657))\n\n    When minification is not enabled, the `?:` operator will now no longer be simplified if the condition evaluates to `true` or `false`. This could result in slower builds in certain cases because esbuild may now scan more files unnecessarily during bundling. This change was made because of a user request.\n\n## 0.8.31\n\n* Fix minification issue from previous release ([#648](https://github.com/evanw/esbuild/issues/648))\n\n    The minification optimization to omit certain `continue` and `return` statements when it's implied by control flow in version 0.8.29 caused a regression when the branch condition uses a hoisted function:\n\n    ```js\n    if (fn()) return;\n    ...\n    function fn() {}\n    ```\n\n    In that case, transforming the code by inverting the condition and moving the following statements inside the branch is not valid because the function is no longer hoisted to above the branch condition. This release fixes the regression by avoiding this optimization in cases like this.\n\n* Add the option `--sourcemap=both` ([#650](https://github.com/evanw/esbuild/issues/650))\n\n    This new option puts the generated source map both an inline `//# sourceMappingURL=` data URL comment inside the output file and in an external file next to the output file. Using it is also possible with the transform API, which will cause it to return both an inline data URL comment in the `code` value and the source map JSON in the `map` value.\n\n* Tree-shake unused code with `--format=iife` ([#639](https://github.com/evanw/esbuild/issues/639))\n\n    When the output format is IIFE (which wraps the code in an immediately-invoked function expression), esbuild now assumes that it's safe to remove unused code. This is an assumption that esbuild always makes when bundling but that esbuild previously didn't make when not bundling. Now esbuild will remove code even when not bundling as long as the output format is IIFE.\n\n    This is only done for the IIFE output format because people are currently using the other formats to compile \"partial modules\", meaning they expect to be able to append code to esbuild's output and have that appended code be able to reference unused code inside esbuild's output. So it's not safe for esbuild to remove unused code in those cases. The IIFE output format wraps everything in a closure so unused code is not exposed to the module-level scope. Appended code will not be able to access unused code inside the closure so that means it's safe to remove.\n\n## 0.8.30\n\n* Fix `@jsx` and `@jsxFrag` comments without trailing spaces\n\n    The `--jsx-factory` and `--jsx-fragment` settings can be set on a per-file basis using `// @jsx name` or `// @jsxFrag name` comments. Comments of the form `/* @jsx name */` or `/* @jsxFrag name */` will also work. However, there was a bug where comments of the form `/* @jsx name*/` or `/* @jsxFrag name*/` (a multi-line comment without a trailing space at the end) did not work. This bug has been fixed, and you now no longer need a trailing space for multi-line comments.\n\n* Minification improvements\n\n    * The expression before a switch statement is now folded into the value. This means `fn(); switch (x) { ... }` turns into `switch (fn(), x) { ... }`.\n\n    * Uses of `===` and `!==` are converted to `==` or `!=` if the types of both sides can easily be statically determined. This means `(x & 1) === 0` turns into `(x & 1) == 0`.\n\n    * Equality comparisons are removed if both sides are boolean and one side is a constant. This means `!x === true` turns into `!x`.\n\n    * Certain unary and binary operators are now removed if unused. This means `if (a() === b()) {}` turns into `a(), b();`.\n\n    * The comma operator is now extracted from certain expressions. This means `(a, b) + c` turns into `a, b + c`.\n\n    * Minification now takes advantage of the left-associativity of certain operators. This means `a && (b && c)` turns into `a && b && c`.\n\n    * Computed properties that are strings now become no longer computed. This means `{['a']: b}` turns into `{a: b}` and `class { ['a'] = b }` turns into `class { a = b }`.\n\n    * Repeated if-jump statements are now merged. This means `if (a) break; if (b) break;` turns into `if (a || b) break;`.\n\n* Fix issues with nested source maps ([#638](https://github.com/evanw/esbuild/issues/638))\n\n    A nested source map happens when an input file has a valid `//# sourceMappingURL=` comment that points to a valid source map file. In that case, esbuild will read that source map and use it to map back to the original source code from the generated file. This only happens if you enable source map generation in esbuild via `--sourcemap`. This release fixes the following issues:\n\n    * Generated source maps were incorrect when an input file had a nested source map and the input source map had more than one source file. This regression was introduced by an optimization in version 0.8.25 that parallelizes the generation of certain internal source map data structures. The index into the generated `sources` array was incorrectly incremented by 1 for every input file instead of by the number of sources in the input source map. This issue has been fixed and now has test coverage.\n\n    * Generated source maps were incorrect when an input file had a nested source map, the file starts with a local variable, the previous file ends with a local variable of that same type, and the input source map is missing a mapping at the start of the file. An optimization was added in version 0.7.18 that splices together local variable declarations from separate files when they end up adjacent to each other in the generated output file (i.e. `var a=0;var b=2;` becomes `var a=0,b=2;` when `a` and `b` are in separate files). The source map splicing was expecting a mapping at the start of the file and that isn't necessarily the case when using nested source maps. The optimization has been disabled for now to fix source map generation, and this specific case has test coverage.\n\n## 0.8.29\n\n* Allow entry points outside of the `outbase` directory ([#634](https://github.com/evanw/esbuild/issues/634))\n\n    When esbuild generates the output path for a bundled entry point, it computes the relative path from [the `outbase` directory](https://esbuild.github.io/api/#outbase) to the input entry point file and then joins that relative path to the output directory. For example, if there are two entry points `src/pages/home/index.ts` and `src/pages/about/index.ts`, the outbase directory is `src`, and the output directory is `out`, the output directory will contain `out/pages/home/index.js` and `out/pages/about/index.js`.\n\n    However, this means that the `outbase` directory is expected to contain all entry point files (even implicit entry point files from `import()` expressions). If an entry point isn't under the outbase directory then esbuild will to try to write the output file outside of the output directory, since the path of the entry point relative to `outbase` will start with `../` which is then joined to the output directory. This is unintentional. All output files are supposed to be written inside of the output directory.\n\n    This release fixes the problem by creating a directory with the name `_.._` in the output directory for output file paths of entry points that are not inside the `outbase` directory. So if the previous example was bundled with an outbase directory of `temp`, the output directory will contain `out/_.._/pages/home/index.js` and `out/_.._/pages/about/index.js`. Doing this instead of stripping the leading `../` off the relative path is necessary to avoid collisions between different entry points with the same path suffix.\n\n* Minification improvements\n\n    This release contains the following minification improvements:\n\n    * Expressions of the form `!(a == b)` are now converted to `a != b`. This also applies similarly for the other three equality operators.\n\n    * A trailing `continue;` statement inside the body of a loop is now removed.\n\n    * Minification can now omit certain `continue` and `return` statements when it's implied by control flow:\n\n        ```js\n        // Before minification\n        function fn() {\n          if (a) return;\n          while (b) {\n            if (c) continue;\n            d();\n          }\n        }\n        ```\n\n        ```js\n        // After minification\n        function fn() {\n          if (!a)\n            for (; b; )\n              c || d();\n        }\n        ```\n\n    * Certain single-use variables are now inlined if the use directly follows the variable:\n\n        ```js\n        // Before minification\n        let result = fn();\n        let callback = result.callback;\n        return callback.call(this);\n        ```\n\n        ```js\n        // After minification\n        return fn().callback.call(this);\n        ```\n\n        This transformation is only done when it's safe to do so. The safety conditions are complex but at a high level, an expression cannot be reordered past another expression if either of them could possibly have side effects.\n"
  },
  {
    "path": "CHANGELOG-2022.md",
    "content": "# Changelog: 2022\n\nThis changelog documents all esbuild versions published in the year 2022 (versions 0.14.11 through 0.16.12).\n\n## 0.16.12\n\n* Loader defaults to `js` for extensionless files ([#2776](https://github.com/evanw/esbuild/issues/2776))\n\n    Certain packages contain files without an extension. For example, the `yargs` package contains the file `yargs/yargs` which has no extension. Node, Webpack, and Parcel can all understand code that imports `yargs/yargs` because they assume that the file is JavaScript. However, esbuild was previously unable to understand this code because it relies on the file extension to tell it how to interpret the file. With this release, esbuild will now assume files without an extension are JavaScript files. This can be customized by setting the loader for `\"\"` (the empty string, representing files without an extension) to another loader. For example, if you want files without an extension to be treated as CSS instead, you can do that like this:\n\n    * CLI:\n\n        ```\n        esbuild --bundle --loader:=css\n        ```\n\n    * JS:\n\n        ```js\n        esbuild.build({\n          bundle: true,\n          loader: { '': 'css' },\n        })\n        ```\n\n    * Go:\n\n        ```go\n        api.Build(api.BuildOptions{\n          Bundle: true,\n          Loader: map[string]api.Loader{\"\": api.LoaderCSS},\n        })\n        ```\n\n    In addition, the `\"type\"` field in `package.json` files now only applies to files with an explicit `.js`, `.jsx`, `.ts`, or `.tsx` extension. Previously it was incorrectly applied by esbuild to all files that had an extension other than `.mjs`, `.mts`, `.cjs`, or `.cts` including extensionless files. So for example an extensionless file in a `\"type\": \"module\"` package is now treated as CommonJS instead of ESM.\n\n## 0.16.11\n\n* Avoid a syntax error in the presence of direct `eval` ([#2761](https://github.com/evanw/esbuild/issues/2761))\n\n    The behavior of nested `function` declarations in JavaScript depends on whether the code is run in strict mode or not. It would be problematic if esbuild preserved nested `function` declarations in its output because then the behavior would depend on whether the output was run in strict mode or not instead of respecting the strict mode behavior of the original source code. To avoid this, esbuild transforms nested `function` declarations to preserve the intended behavior of the original source code regardless of whether the output is run in strict mode or not:\n\n    ```js\n    // Original code\n    if (true) {\n      function foo() {}\n      console.log(!!foo)\n      foo = null\n      console.log(!!foo)\n    }\n    console.log(!!foo)\n\n    // Transformed code\n    if (true) {\n      let foo2 = function() {\n      };\n      var foo = foo2;\n      console.log(!!foo2);\n      foo2 = null;\n      console.log(!!foo2);\n    }\n    console.log(!!foo);\n    ```\n\n    In the above example, the original code should print `true false true` because it's not run in strict mode (it doesn't contain `\"use strict\"` and is not an ES module). The code that esbuild generates has been transformed such that it prints `true false true` regardless of whether it's run in strict mode or not.\n\n    However, this transformation is impossible if the code contains direct `eval` because direct `eval` \"poisons\" all containing scopes by preventing anything in those scopes from being renamed. That prevents esbuild from splitting up accesses to `foo` into two separate variables with different names. Previously esbuild still did this transformation but with two variables both named `foo`, which is a syntax error. With this release esbuild will now skip doing this transformation when direct `eval` is present to avoid generating code with a syntax error. This means that the generated code may no longer behave as intended since the behavior depends on the run-time strict mode setting instead of the strict mode setting present in the original source code. To fix this problem, you will need to remove the use of direct `eval`.\n\n* Fix a bundling scenario involving multiple symlinks ([#2773](https://github.com/evanw/esbuild/issues/2773), [#2774](https://github.com/evanw/esbuild/issues/2774))\n\n    This release contains a fix for a bundling scenario involving an import path where multiple path segments are symlinks. Previously esbuild was unable to resolve certain import paths in this scenario, but these import paths should now work starting with this release. This fix was contributed by [@onebytegone](https://github.com/onebytegone).\n\n## 0.16.10\n\n* Change the default \"legal comment\" behavior again ([#2745](https://github.com/evanw/esbuild/issues/2745))\n\n    The legal comments feature automatically gathers comments containing `@license` or `@preserve` and puts the comments somewhere (either in the generated code or in a separate file). This behavior used to be on by default but was disabled by default in version 0.16.0 because automatically inserting comments is potentially confusing and misleading. These comments can appear to be assigning the copyright of your code to another entity. And this behavior can be especially problematic if it happens automatically by default since you may not even be aware of it happening. For example, if you bundle the TypeScript compiler the preserving legal comments means your source code would contain this comment, which appears to be assigning the copyright of all of your code to Microsoft:\n\n    ```js\n    /*! *****************************************************************************\n    Copyright (c) Microsoft Corporation. All rights reserved.\n    Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n    this file except in compliance with the License. You may obtain a copy of the\n    License at http://www.apache.org/licenses/LICENSE-2.0\n\n    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\n    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\n    MERCHANTABLITY OR NON-INFRINGEMENT.\n\n    See the Apache Version 2.0 License for specific language governing permissions\n    and limitations under the License.\n    ***************************************************************************** */\n    ```\n\n    However, people have asked for this feature to be re-enabled by default. To resolve the confusion about what these comments are applying to, esbuild's default behavior will now be to attempt to describe which package the comments are coming from. So while this feature has been re-enabled by default, the output will now look something like this instead:\n\n    ```js\n    /*! Bundled license information:\n\n    typescript/lib/typescript.js:\n      (*! *****************************************************************************\n      Copyright (c) Microsoft Corporation. All rights reserved.\n      Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use\n      this file except in compliance with the License. You may obtain a copy of the\n      License at http://www.apache.org/licenses/LICENSE-2.0\n\n      THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n      KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\n      WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\n      MERCHANTABLITY OR NON-INFRINGEMENT.\n\n      See the Apache Version 2.0 License for specific language governing permissions\n      and limitations under the License.\n      ***************************************************************************** *)\n    */\n    ```\n\n    Note that you can still customize this behavior with the `--legal-comments=` flag. For example, you can use `--legal-comments=none` to turn this off, or you can use `--legal-comments=linked` to put these comments in a separate `.LEGAL.txt` file instead.\n\n* Enable `external` legal comments with the transform API ([#2390](https://github.com/evanw/esbuild/issues/2390))\n\n    Previously esbuild's transform API only supported `none`, `inline`, or `eof` legal comments. With this release, `external` legal comments are now also supported with the transform API. This only applies to the JS and Go APIs, not to the CLI, and looks like this:\n\n    * JS:\n\n        ```js\n        const { code, legalComments } = await esbuild.transform(input, {\n          legalComments: 'external',\n        })\n        ```\n\n    * Go:\n\n        ```go\n        result := api.Transform(input, api.TransformOptions{\n          LegalComments: api.LegalCommentsEndOfFile,\n        })\n        code := result.Code\n        legalComments := result.LegalComments\n        ```\n\n* Fix duplicate function declaration edge cases ([#2757](https://github.com/evanw/esbuild/issues/2757))\n\n    The change in the previous release to forbid duplicate function declarations in certain cases accidentally forbid some edge cases that should have been allowed. Specifically duplicate function declarations are forbidden in nested blocks in strict mode and at the top level of modules, but are allowed when they are declared at the top level of function bodies. This release fixes the regression by re-allowing the last case.\n\n* Allow package subpaths with `alias` ([#2715](https://github.com/evanw/esbuild/issues/2715))\n\n    Previously the names passed to the `alias` feature had to be the name of a package (with or without a package scope). With this release, you can now also use the `alias` feature with package subpaths. So for example you can now create an alias that substitutes `@org/pkg/lib` with something else.\n\n## 0.16.9\n\n* Update to Unicode 15.0.0\n\n    The character tables that determine which characters form valid JavaScript identifiers have been updated from Unicode version 14.0.0 to the newly-released Unicode version 15.0.0. I'm not putting an example in the release notes because all of the new characters will likely just show up as little squares since fonts haven't been updated yet. But you can read https://www.unicode.org/versions/Unicode15.0.0/#Summary for more information about the changes.\n\n* Disallow duplicate lexically-declared names in nested blocks and in strict mode\n\n    In strict mode or in a nested block, it's supposed to be a syntax error to declare two symbols with the same name unless all duplicate entries are either `function` declarations or all `var` declarations. However, esbuild was overly permissive and allowed this when duplicate entries were either `function` declarations or `var` declarations (even if they were mixed). This check has now been made more restrictive to match the JavaScript specification:\n\n    ```js\n    // JavaScript allows this\n    var a\n    function a() {}\n    {\n      var b\n      var b\n      function c() {}\n      function c() {}\n    }\n\n    // JavaScript doesn't allow this\n    {\n      var d\n      function d() {}\n    }\n    ```\n\n* Add a type declaration for the new `empty` loader ([#2755](https://github.com/evanw/esbuild/pull/2755))\n\n    I forgot to add this in the previous release. It has now been added.\n\n    This fix was contributed by [@fz6m](https://github.com/fz6m).\n\n* Add support for the `v` flag in regular expression literals\n\n    People are currently working on adding a `v` flag to JavaScript regular expresions. You can read more about this flag here: https://v8.dev/features/regexp-v-flag. This release adds support for parsing this flag, so esbuild will now no longer consider regular expression literals with this flag to be a syntax error. If the target is set to something other than `esnext`, esbuild will transform regular expression literals containing this flag into a `new RegExp()` constructor call so the resulting code doesn't have a syntax error. This enables you to provide a polyfill for `RegExp` that implements the `v` flag to get your code to work at run-time. While esbuild doesn't typically adopt proposals until they're already shipping in a real JavaScript run-time, I'm adding it now because a) esbuild's implementation doesn't need to change as the proposal evolves, b) this isn't really new syntax since regular expression literals already have flags, and c) esbuild's implementation is a trivial pass-through anyway.\n\n* Avoid keeping the name of classes with static `name` properties\n\n    The `--keep-names` property attempts to preserve the original value of the `name` property for functions and classes even when identifiers are renamed by the minifier or to avoid a name collision. This is currently done by generating code to assign a string to the `name` property on the function or class object. However, this should not be done for classes with a static `name` property since in that case the explicitly-defined `name` property overwrites the automatically-generated class name. With this release, esbuild will now no longer attempt to preserve the `name` property for classes with a static `name` property.\n\n## 0.16.8\n\n* Allow plugins to resolve injected files ([#2754](https://github.com/evanw/esbuild/issues/2754))\n\n    Previously paths passed to the `inject` feature were always interpreted as file system paths. This meant that `onResolve` plugins would not be run for them and esbuild's default path resolver would always be used. This meant that the `inject` feature couldn't be used in the browser since the browser doesn't have access to a file system. This release runs paths passed to `inject` through esbuild's full path resolution pipeline so plugins now have a chance to handle them using `onResolve` callbacks. This makes it possible to write a plugin that makes esbuild's `inject` work in the browser.\n\n* Add the `empty` loader ([#1541](https://github.com/evanw/esbuild/issues/1541), [#2753](https://github.com/evanw/esbuild/issues/2753))\n\n    The new `empty` loader tells esbuild to pretend that a file is empty. So for example `--loader:.css=empty` effectively skips all imports of `.css` files in JavaScript so that they aren't included in the bundle, since `import \"./some-empty-file\"` in JavaScript doesn't bundle anything. You can also use the `empty` loader to remove asset references in CSS files. For example `--loader:.png=empty` causes esbuild to replace asset references such as `url(image.png)` with `url()` so that they are no longer included in the resulting style sheet.\n\n* Fix `</script>` and `</style>` escaping for non-default targets ([#2748](https://github.com/evanw/esbuild/issues/2748))\n\n    The change in version 0.16.0 to give control over `</script>` escaping via `--supported:inline-script=false` or `--supported:inline-script=true` accidentally broke automatic escaping of `</script>` when an explicit `target` setting is specified. This release restores the correct automatic escaping of `</script>` (which should not depend on what `target` is set to).\n\n* Enable the `exports` field with `NODE_PATHS` ([#2752](https://github.com/evanw/esbuild/issues/2752))\n\n    Node has a rarely-used feature where you can extend the set of directories that node searches for packages using the `NODE_PATHS` environment variable. While esbuild supports this too, previously it only supported the old `main` field path resolution but did not support the new `exports` field package resolution. This release makes the path resolution rules the same again for both `node_modules` directories and `NODE_PATHS` directories.\n\n## 0.16.7\n\n* Include `file` loader strings in metafile imports ([#2731](https://github.com/evanw/esbuild/issues/2731))\n\n    Bundling a file with the `file` loader copies that file to the output directory and imports a module with the path to the copied file in the `default` export. Previously when bundling with the `file` loader, there was no reference in the metafile from the JavaScript file containing the path string to the copied file. With this release, there will now be a reference in the metafile in the `imports` array with the kind `file-loader`:\n\n    ```diff\n     {\n       ...\n       \"outputs\": {\n         \"out/image-55CCFTCE.svg\": {\n           ...\n         },\n         \"out/entry.js\": {\n           \"imports\": [\n    +        {\n    +          \"path\": \"out/image-55CCFTCE.svg\",\n    +          \"kind\": \"file-loader\"\n    +        }\n           ],\n           ...\n         }\n       }\n     }\n    ```\n\n* Fix byte counts in metafile regarding references to other output files ([#2071](https://github.com/evanw/esbuild/issues/2071))\n\n    Previously files that contained references to other output files had slightly incorrect metadata for the byte counts of input files which contributed to that output file. So for example if `app.js` imports `image.png` using the file loader and esbuild generates `out.js` and `image-LSAMBFUD.png`, the metadata for how many bytes of `out.js` are from `app.js` was slightly off (the metadata for the byte count of `out.js` was still correct). The reason is because esbuild substitutes the final paths for references between output files toward the end of the build to handle cyclic references, and the byte counts needed to be adjusted as well during the path substitution. This release fixes these byte counts (specifically the `bytesInOutput` values).\n\n* The alias feature now strips a trailing slash ([#2730](https://github.com/evanw/esbuild/issues/2730))\n\n    People sometimes add a trailing slash to the name of one of node's built-in modules to force node to import from the file system instead of importing the built-in module. For example, importing `util` imports node's built-in module called `util` but importing `util/` tries to find a package called `util` on the file system. Previously attempting to use esbuild's package alias feature to replace imports to `util` with a specific file would fail because the file path would also gain a trailing slash (e.g. mapping `util` to `./file.js` turned `util/` into `./file.js/`). With this release, esbuild will now omit the path suffix if it's a single trailing slash, which should now allow you to successfully apply aliases to these import paths.\n\n## 0.16.6\n\n* Do not mark subpath imports as external with `--packages=external` ([#2741](https://github.com/evanw/esbuild/issues/2741))\n\n    Node has a feature called [subpath imports](https://nodejs.org/api/packages.html#subpath-imports) where special import paths that start with `#` are resolved using the `imports` field in the `package.json` file of the enclosing package. The intent of the newly-added `--packages=external` setting is to exclude a package's dependencies from the bundle. Since a package's subpath imports are only accessible within that package, it's wrong for them to be affected by `--packages=external`. This release changes esbuild so that `--packages=external` no longer affects subpath imports.\n\n* Forbid invalid numbers in JSON files\n\n    Previously esbuild parsed numbers in JSON files using the same syntax as JavaScript. But starting from this release, esbuild will now parse them with JSON syntax instead. This means the following numbers are no longer allowed by esbuild in JSON files:\n\n    * Legacy octal literals (non-zero integers starting with `0`)\n    * The `0b`, `0o`, and `0x` numeric prefixes\n    * Numbers containing `_` such as `1_000`\n    * Leading and trailing `.` such as `0.` and `.0`\n    * Numbers with a space after the `-` such as `- 1`\n\n* Add external imports to metafile ([#905](https://github.com/evanw/esbuild/issues/905), [#1768](https://github.com/evanw/esbuild/issues/1768), [#1933](https://github.com/evanw/esbuild/issues/1933), [#1939](https://github.com/evanw/esbuild/issues/1939))\n\n    External imports now appear in `imports` arrays in the metafile (which is present when bundling with `metafile: true`) next to normal imports, but additionally have `external: true` to set them apart. This applies both to files in the `inputs` section and the `outputs` section. Here's an example:\n\n    ```diff\n     {\n       \"inputs\": {\n         \"style.css\": {\n           \"bytes\": 83,\n           \"imports\": [\n    +        {\n    +          \"path\": \"https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css\",\n    +          \"kind\": \"import-rule\",\n    +          \"external\": true\n    +        }\n           ]\n         },\n         \"app.js\": {\n           \"bytes\": 100,\n           \"imports\": [\n    +        {\n    +          \"path\": \"https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js\",\n    +          \"kind\": \"import-statement\",\n    +          \"external\": true\n    +        },\n             {\n               \"path\": \"style.css\",\n               \"kind\": \"import-statement\"\n             }\n           ]\n         }\n       },\n       \"outputs\": {\n         \"out/app.js\": {\n           \"imports\": [\n    +        {\n    +          \"path\": \"https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js\",\n    +          \"kind\": \"require-call\",\n    +          \"external\": true\n    +        }\n           ],\n           \"exports\": [],\n           \"entryPoint\": \"app.js\",\n           \"cssBundle\": \"out/app.css\",\n           \"inputs\": {\n             \"app.js\": {\n               \"bytesInOutput\": 113\n             },\n             \"style.css\": {\n               \"bytesInOutput\": 0\n             }\n           },\n           \"bytes\": 528\n         },\n         \"out/app.css\": {\n           \"imports\": [\n    +        {\n    +          \"path\": \"https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css\",\n    +          \"kind\": \"import-rule\",\n    +          \"external\": true\n    +        }\n           ],\n           \"inputs\": {\n             \"style.css\": {\n               \"bytesInOutput\": 0\n             }\n           },\n           \"bytes\": 100\n         }\n       }\n     }\n    ```\n\n    One additional useful consequence of this is that the `imports` array is now populated when bundling is disabled. So you can now use esbuild with bundling disabled to inspect a file's imports.\n\n## 0.16.5\n\n* Make it easy to exclude all packages from a bundle ([#1958](https://github.com/evanw/esbuild/issues/1958), [#1975](https://github.com/evanw/esbuild/issues/1975), [#2164](https://github.com/evanw/esbuild/issues/2164), [#2246](https://github.com/evanw/esbuild/issues/2246), [#2542](https://github.com/evanw/esbuild/issues/2542))\n\n    When bundling for node, it's often necessary to exclude npm packages from the bundle since they weren't designed with esbuild bundling in mind and don't work correctly after being bundled. For example, they may use `__dirname` and run-time file system calls to load files, which doesn't work after bundling with esbuild. Or they may compile a native `.node` extension that has similar expectations about the layout of the file system that are no longer true after bundling (even if the `.node` extension is copied next to the bundle).\n\n    The way to get this to work with esbuild is to use the `--external:` flag. For example, the [`fsevents`](https://www.npmjs.com/package/fsevents) package contains a native `.node` extension and shouldn't be bundled. To bundle code that uses it, you can pass `--external:fsevents` to esbuild to exclude it from your bundle. You will then need to ensure that the `fsevents` package is still present when you run your bundle (e.g. by publishing your bundle to npm as a package with a dependency on `fsevents`).\n\n    It was possible to automatically do this for all of your dependencies, but it was inconvenient. You had to write some code that read your `package.json` file and passed the keys of the `dependencies`, `devDependencies`, `peerDependencies`, and/or `optionalDependencies` maps to esbuild as external packages (either that or write a plugin to mark all package paths as external). Previously esbuild's recommendation for making this easier was to do `--external:./node_modules/*` (added in version 0.14.13). However, this was a bad idea because it caused compatibility problems with many node packages as it caused esbuild to mark the post-resolve path as external instead of the pre-resolve path. Doing that could break packages that are published as both CommonJS and ESM if esbuild's bundler is also used to do a module format conversion.\n\n    With this release, you can now do the following to automatically exclude all packages from your bundle:\n\n    * CLI:\n\n        ```\n        esbuild --bundle --packages=external\n        ```\n\n    * JS:\n\n        ```js\n        esbuild.build({\n          bundle: true,\n          packages: 'external',\n        })\n        ```\n\n    * Go:\n\n        ```go\n        api.Build(api.BuildOptions{\n          Bundle:   true,\n          Packages: api.PackagesExternal,\n        })\n        ```\n\n    Doing `--external:./node_modules/*` is still possible and still has the same behavior, but is no longer recommended. I recommend that you use the new `packages` feature instead.\n\n* Fix some subtle bugs with tagged template literals\n\n    This release fixes a bug where minification could incorrectly change the value of `this` within tagged template literal function calls:\n\n    ```js\n    // Original code\n    function f(x) {\n      let z = y.z\n      return z``\n    }\n\n    // Old output (with --minify)\n    function f(n){return y.z``}\n\n    // New output (with --minify)\n    function f(n){return(0,y.z)``}\n    ```\n\n    This release also fixes a bug where using optional chaining with `--target=es2019` or earlier could incorrectly change the value of `this` within tagged template literal function calls:\n\n    ```js\n    // Original code\n    var obj = {\n      foo: function() {\n        console.log(this === obj);\n      }\n    };\n    (obj?.foo)``;\n\n    // Old output (with --target=es6)\n    var obj = {\n      foo: function() {\n        console.log(this === obj);\n      }\n    };\n    (obj == null ? void 0 : obj.foo)``;\n\n    // New output (with --target=es6)\n    var __freeze = Object.freeze;\n    var __defProp = Object.defineProperty;\n    var __template = (cooked, raw) => __freeze(__defProp(cooked, \"raw\", { value: __freeze(raw || cooked.slice()) }));\n    var _a;\n    var obj = {\n      foo: function() {\n        console.log(this === obj);\n      }\n    };\n    (obj == null ? void 0 : obj.foo).call(obj, _a || (_a = __template([\"\"])));\n    ```\n\n* Some slight minification improvements\n\n    The following minification improvements were implemented:\n\n    * `if (~a !== 0) throw x;` => `if (~a) throw x;`\n    * `if ((a | b) !== 0) throw x;` => `if (a | b) throw x;`\n    * `if ((a & b) !== 0) throw x;` => `if (a & b) throw x;`\n    * `if ((a ^ b) !== 0) throw x;` => `if (a ^ b) throw x;`\n    * `if ((a << b) !== 0) throw x;` => `if (a << b) throw x;`\n    * `if ((a >> b) !== 0) throw x;` => `if (a >> b) throw x;`\n    * `if ((a >>> b) !== 0) throw x;` => `if (a >>> b) throw x;`\n    * `if (!!a || !!b) throw x;` => `if (a || b) throw x;`\n    * `if (!!a && !!b) throw x;` => `if (a && b) throw x;`\n    * `if (a ? !!b : !!c) throw x;` => `if (a ? b : c) throw x;`\n\n## 0.16.4\n\n* Fix binary downloads from the `@esbuild/` scope for Deno ([#2729](https://github.com/evanw/esbuild/issues/2729))\n\n    Version 0.16.0 of esbuild moved esbuild's binary executables into npm packages under the `@esbuild/` scope, which accidentally broke the binary downloader script for Deno. This release fixes this script so it should now be possible to use esbuild version 0.16.4+ with Deno.\n\n## 0.16.3\n\n* Fix a hang with the JS API in certain cases ([#2727](https://github.com/evanw/esbuild/issues/2727))\n\n    A change that was made in version 0.15.13 accidentally introduced a case when using esbuild's JS API could cause the node process to fail to exit. The change broke esbuild's watchdog timer, which detects if the parent process no longer exists and then automatically exits esbuild. This hang happened when you ran node as a child process with the `stderr` stream set to `pipe` instead of `inherit`, in the child process you call esbuild's JS API and pass `incremental: true` but do not call `dispose()` on the returned `rebuild` object, and then call `process.exit()`. In that case the parent node process was still waiting for the esbuild process that was created by the child node process to exit. The change made in version 0.15.13 was trying to avoid using Go's `sync.WaitGroup` API incorrectly because the API is not thread-safe. Instead of doing this, I have now reverted that change and implemented a thread-safe version of the `sync.WaitGroup` API for esbuild to use instead.\n\n## 0.16.2\n\n* Fix `process.env.NODE_ENV` substitution when transforming ([#2718](https://github.com/evanw/esbuild/issues/2718))\n\n    Version 0.16.0 introduced an unintentional regression that caused `process.env.NODE_ENV` to be automatically substituted with either `\"development\"` or `\"production\"` when using esbuild's `transform` API. This substitution is a necessary feature of esbuild's `build` API because the React framework crashes when you bundle it without doing this. But the `transform` API is typically used as part of a larger build pipeline so the benefit of esbuild doing this automatically is not as clear, and esbuild previously didn't do this.\n\n    However, version 0.16.0 switched the default value of the `platform` setting for the `transform` API from `neutral` to `browser`, both to align it with esbuild's documentation (which says `browser` is the default value) and because escaping the `</script>` character sequence is now tied to the `browser` platform (see the release notes for version 0.16.0 for details). That accidentally enabled automatic substitution of `process.env.NODE_ENV` because esbuild always did that for code meant for the browser. To fix this regression, esbuild will now only automatically substitute `process.env.NODE_ENV` when using the `build` API.\n\n* Prevent `define` from substituting constants into assignment position ([#2719](https://github.com/evanw/esbuild/issues/2719))\n\n    The `define` feature lets you replace certain expressions with constants. For example, you could use it to replace references to the global property reference `window.DEBUG` with `false` at compile time, which can then potentially help esbuild remove unused code from your bundle. It's similar to [DefinePlugin](https://webpack.js.org/plugins/define-plugin/) in Webpack.\n\n    However, if you write code such as `window.DEBUG = true` and then defined `window.DEBUG` to `false`, esbuild previously generated the output `false = true` which is a syntax error in JavaScript. This behavior is not typically a problem because it doesn't make sense to substitute `window.DEBUG` with a constant if its value changes at run-time (Webpack's `DefinePlugin` also generates `false = true` in this case). But it can be alarming to have esbuild generate code with a syntax error.\n\n    So with this release, esbuild will no longer substitute `define` constants into assignment position to avoid generating code with a syntax error. Instead esbuild will generate a warning, which currently looks like this:\n\n    ```\n    ▲ [WARNING] Suspicious assignment to defined constant \"window.DEBUG\" [assign-to-define]\n\n        example.js:1:0:\n          1 │ window.DEBUG = true\n            ╵ ~~~~~~~~~~~~\n\n      The expression \"window.DEBUG\" has been configured to be replaced with a constant using the\n      \"define\" feature. If this expression is supposed to be a compile-time constant, then it doesn't\n      make sense to assign to it here. Or if this expression is supposed to change at run-time, this\n      \"define\" substitution should be removed.\n    ```\n\n* Fix a regression with `npm install --no-optional` ([#2720](https://github.com/evanw/esbuild/issues/2720))\n\n    Normally when you install esbuild with `npm install`, npm itself is the tool that downloads the correct binary executable for the current platform. This happens because of how esbuild's primary package uses npm's `optionalDependencies` feature. However, if you deliberately disable this with `npm install --no-optional` then esbuild's install script will attempt to repair the installation by manually downloading and extracting the binary executable from the package that was supposed to be installed.\n\n    The change in version 0.16.0 to move esbuild's nested packages into the `@esbuild/` scope unintentionally broke this logic because of how npm's URL structure is different for scoped packages vs. normal packages. It was actually already broken for a few platforms earlier because esbuild already had packages for some platforms in the `@esbuild/` scope, but I didn't discover this then because esbuild's integration tests aren't run on all platforms. Anyway, this release contains some changes to the install script that should hopefully get this scenario working again.\n\n## 0.16.1\n\nThis is a hotfix for the previous release.\n\n* Re-allow importing JSON with the `copy` loader using an import assertion\n\n    The previous release made it so when `assert { type: 'json' }` is present on an import statement, esbuild validated that the `json` loader was used. This is what an import assertion is supposed to do. However, I forgot about the relatively new `copy` loader, which sort of behaves as if the import path was marked as external (and thus not loaded at all) except that the file is copied to the output directory and the import path is rewritten to point to the copy. In this case whatever JavaScript runtime ends up running the code is the one to evaluate the import assertion. So esbuild should really allow this case as well. With this release, esbuild now allows both the `json` and `copy` loaders when an `assert { type: 'json' }` import assertion is present.\n\n## 0.16.0\n\n**This release deliberately contains backwards-incompatible changes.** To avoid automatically picking up releases like this, you should either be pinning the exact version of `esbuild` in your `package.json` file (recommended) or be using a version range syntax that only accepts patch upgrades such as `^0.15.0` or `~0.15.0`. See npm's documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\n* Move all binary executable packages to the `@esbuild/` scope\n\n    Binary package executables for esbuild are published as individual packages separate from the main `esbuild` package so you only have to download the relevant one for the current platform when you install esbuild. This release moves all of these packages under the `@esbuild/` scope to avoid collisions with 3rd-party packages. It also changes them to a consistent naming scheme that uses the `os` and `cpu` names from node.\n\n    The package name changes are as follows:\n\n    * `@esbuild/linux-loong64` => `@esbuild/linux-loong64` (no change)\n    * `esbuild-android-64` => `@esbuild/android-x64`\n    * `esbuild-android-arm64` => `@esbuild/android-arm64`\n    * `esbuild-darwin-64` => `@esbuild/darwin-x64`\n    * `esbuild-darwin-arm64` => `@esbuild/darwin-arm64`\n    * `esbuild-freebsd-64` => `@esbuild/freebsd-x64`\n    * `esbuild-freebsd-arm64` => `@esbuild/freebsd-arm64`\n    * `esbuild-linux-32` => `@esbuild/linux-ia32`\n    * `esbuild-linux-64` => `@esbuild/linux-x64`\n    * `esbuild-linux-arm` => `@esbuild/linux-arm`\n    * `esbuild-linux-arm64` => `@esbuild/linux-arm64`\n    * `esbuild-linux-mips64le` => `@esbuild/linux-mips64el`\n    * `esbuild-linux-ppc64le` => `@esbuild/linux-ppc64`\n    * `esbuild-linux-riscv64` => `@esbuild/linux-riscv64`\n    * `esbuild-linux-s390x` => `@esbuild/linux-s390x`\n    * `esbuild-netbsd-64` => `@esbuild/netbsd-x64`\n    * `esbuild-openbsd-64` => `@esbuild/openbsd-x64`\n    * `esbuild-sunos-64` => `@esbuild/sunos-x64`\n    * `esbuild-wasm` => `esbuild-wasm` (no change)\n    * `esbuild-windows-32` => `@esbuild/win32-ia32`\n    * `esbuild-windows-64` => `@esbuild/win32-x64`\n    * `esbuild-windows-arm64` => `@esbuild/win32-arm64`\n    * `esbuild` => `esbuild` (no change)\n\n    Normal usage of the `esbuild` and `esbuild-wasm` packages should not be affected. These name changes should only affect tools that hard-coded the individual binary executable package names into custom esbuild downloader scripts.\n\n    This change was not made with performance in mind. But as a bonus, installing esbuild with npm may potentially happen faster now. This is because npm's package installation protocol is inefficient: it always downloads metadata for all past versions of each package even when it only needs metadata about a single version. This makes npm package downloads O(n) in the number of published versions, which penalizes packages like esbuild that are updated regularly. Since most of esbuild's package names have now changed, npm will now need to download much less data when installing esbuild (8.72mb of package manifests before this change → 0.06mb of package manifests after this change). However, this is only a temporary improvement. Installing esbuild will gradually get slower again as further versions of esbuild are published.\n\n* Publish a shell script that downloads esbuild directly\n\n    In addition to all of the existing ways to install esbuild, you can now also download esbuild directly like this:\n\n    ```sh\n    curl -fsSL https://esbuild.github.io/dl/latest | sh\n    ```\n\n    This runs a small shell script that downloads the latest `esbuild` binary executable to the current directory. This can be convenient on systems that don't have `npm` installed or when you just want to get a copy of esbuild quickly without any extra steps. If you want a specific version of esbuild (starting with this version onward), you can provide that version in the URL instead of `latest`:\n\n    ```sh\n    curl -fsSL https://esbuild.github.io/dl/v0.16.0 | sh\n    ```\n\n    Note that the download script needs to be able to access registry.npmjs.org to be able to complete the download. This download script doesn't yet support all of the platforms that esbuild supports because I lack the necessary testing environments. If the download script doesn't work for you because you're on an unsupported platform, please file an issue on the esbuild repo so we can add support for it.\n\n* Fix some parameter names for the Go API\n\n    This release changes some parameter names for the Go API to be consistent with the JavaScript and CLI APIs:\n\n    * `OutExtensions` => `OutExtension`\n    * `JSXMode` => `JSX`\n\n* Add additional validation of API parameters\n\n    The JavaScript API now does some additional validation of API parameters to catch incorrect uses of esbuild's API. The biggest impact of this is likely that esbuild now strictly only accepts strings with the `define` parameter. This would already have been a type error with esbuild's TypeScript type definitions, but it was previously not enforced for people using esbuild's API JavaScript without TypeScript.\n\n    The `define` parameter appears at first glance to take a JSON object if you aren't paying close attention, but this actually isn't true. Values for `define` are instead strings of JavaScript code. This means you have to use `define: { foo: '\"bar\"' }` to replace `foo` with the string `\"bar\"`. Using `define: { foo: 'bar' }` actually replaces `foo` with the identifier `bar`. Previously esbuild allowed you to pass `define: { foo: false }` and `false` was automatically converted into a string, which made it more confusing to understand what `define` actually represents. Starting with this release, passing non-string values such as with `define: { foo: false }` will no longer be allowed. You will now have to write `define: { foo: 'false' }` instead.\n\n* Generate shorter data URLs if possible ([#1843](https://github.com/evanw/esbuild/issues/1843))\n\n    Loading a file with esbuild's `dataurl` loader generates a JavaScript module with a [data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs) for that file in a string as a single default export. Previously the data URLs generated by esbuild all used [base64 encoding](https://en.wikipedia.org/wiki/Base64). However, this is unnecessarily long for most textual data (e.g. SVG images). So with this release, esbuild's `dataurl` loader will now use percent encoding instead of base64 encoding if the result will be shorter. This can result in ~25% smaller data URLs for large SVGs. If you want the old behavior, you can use the `base64` loader instead and then construct the data URL yourself.\n\n* Avoid marking entry points as external ([#2382](https://github.com/evanw/esbuild/issues/2382))\n\n    Previously you couldn't specify `--external:*` to mark all import paths as external because that also ended up making the entry point itself external, which caused the build to fail. With this release, esbuild's `external` API parameter no longer applies to entry points so using `--external:*` is now possible.\n\n    One additional consequence of this change is that the `kind` parameter is now required when calling the `resolve()` function in esbuild's plugin API. Previously the `kind` parameter defaulted to `entry-point`, but that no longer interacts with `external` so it didn't seem wise for this to continue to be the default. You now have to specify `kind` so that the path resolution mode is explicit.\n\n* Disallow non-`default` imports when `assert { type: 'json' }` is present\n\n    There is now standard behavior for importing a JSON file into an ES module using an `import` statement. However, it requires you to place the `assert { type: 'json' }` import assertion after the import path. This import assertion tells the JavaScript runtime to throw an error if the import does not end up resolving to a JSON file. On the web, the type of a file is determined by the `Content-Type` HTTP header instead of by the file extension. The import assertion prevents security problems on the web where a `.json` file may actually resolve to a JavaScript file containing malicious code, which is likely not expected for an import that is supposed to only contain pure side-effect free data.\n\n    By default, esbuild uses the file extension to determine the type of a file, so this import assertion is unnecessary with esbuild. However, esbuild's JSON import feature has a non-standard extension that allows you to import top-level properties of the JSON object as named imports. For example, esbuild lets you do this:\n\n    ```js\n    import { version } from './package.json'\n    ```\n\n    This is useful for tree-shaking when bundling because it means esbuild will only include the the `version` field of `package.json` in your bundle. This is non-standard behavior though and doesn't match the behavior of what happens when you import JSON in a real JavaScript runtime (after adding `assert { type: 'json' }`). In a real JavaScript runtime the only thing you can import is the `default` import. So with this release, esbuild will now prevent you from importing non-`default` import names if `assert { type: 'json' }` is present. This ensures that code containing `assert { type: 'json' }` isn't relying on non-standard behavior that won't work everywhere. So the following code is now an error with esbuild when bundling:\n\n    ```js\n    import { version } from './package.json' assert { type: 'json' }\n    ```\n\n    In addition, adding `assert { type: 'json' }` to an import statement now means esbuild will generate an error if the loader for the file is anything other than `json`, which is required by the import assertion specification.\n\n* Provide a way to disable automatic escaping of `</script>` ([#2649](https://github.com/evanw/esbuild/issues/2649))\n\n    If you inject esbuild's output into a script tag in an HTML file, code containing the literal characters `</script>` will cause the tag to be ended early which will break the code:\n\n    ```html\n    <script>\n      console.log(\"</script>\");\n    </script>\n    ```\n\n    To avoid this, esbuild automatically escapes these strings in generated JavaScript files (e.g. `\"</script>\"` becomes `\"<\\/script>\"` instead). This also applies to `</style>` in generated CSS files. Previously this always happened and there wasn't a way to turn this off.\n\n    With this release, esbuild will now only do this if the `platform` setting is set to `browser` (the default value). Setting `platform` to `node` or `neutral` will disable this behavior. This behavior can also now be disabled with `--supported:inline-script=false` (for JS) and `--supported:inline-style=false` (for CSS).\n\n* Throw an early error if decoded UTF-8 text isn't a `Uint8Array` ([#2532](https://github.com/evanw/esbuild/issues/2532))\n\n    If you run esbuild's JavaScript API in a broken JavaScript environment where `new TextEncoder().encode(\"\") instanceof Uint8Array` is false, then esbuild's API will fail with a confusing serialization error message that makes it seem like esbuild has a bug even though the real problem is that the JavaScript environment itself is broken. This can happen when using the test framework called [Jest](https://jestjs.io/). With this release, esbuild's API will now throw earlier when it detects that the environment is unable to encode UTF-8 text correctly with an error message that makes it more clear that this is not a problem with esbuild.\n\n* Change the default \"legal comment\" behavior\n\n    The legal comments feature automatically gathers comments containing `@license` or `@preserve` and puts the comments somewhere (either in the generated code or in a separate file). People sometimes want this to happen so that the their dependencies' software licenses are retained in the generated output code. By default esbuild puts these comments at the end of the file when bundling. However, people sometimes find this confusing because these comments can be very generic and may not mention which library they come from. So with this release, esbuild will now discard legal comments by default. You now have to opt-in to preserving them if you want this behavior.\n\n* Enable the `module` condition by default ([#2417](https://github.com/evanw/esbuild/issues/2417))\n\n    Package authors want to be able to use the new [`exports`](https://nodejs.org/api/packages.html#conditional-exports) field in `package.json` to provide tree-shakable ESM code for ESM-aware bundlers while simultaneously providing fallback CommonJS code for other cases.\n\n    Node's proposed way to do this involves using the `import` and `require` export conditions so that you get the ESM code if you use an import statement and the CommonJS code if you use a require call. However, this has a major drawback: if some code in the bundle uses an import statement and other code in the bundle uses a require call, then you'll get two copies of the same package in the bundle. This is known as the [dual package hazard](https://nodejs.org/api/packages.html#dual-package-hazard) and can lead to bloated bundles or even worse to subtle logic bugs.\n\n    Webpack supports an alternate solution: an export condition called `module` that takes effect regardless of whether the package was imported using an import statement or a require call. This works because bundlers such as Webpack support importing a ESM using a require call (something node doesn't support). You could already do this with esbuild using `--conditions=module` but you previously had to explicitly enable this. Package authors are concerned that esbuild users won't know to do this and will get suboptimal output with their package, so they have requested for esbuild to do this automatically.\n\n    So with this release, esbuild will now automatically add the `module` condition when there aren't any custom `conditions` already configured. You can disable this with `--conditions=` or `conditions: []` (i.e. explicitly clearing all custom conditions).\n\n* Rename the `master` branch to `main`\n\n    The primary branch for this repository was previously called `master` but is now called `main`. This change mirrors a similar change in many other projects.\n\n* Remove esbuild's `_exit(0)` hack for WebAssembly ([#714](https://github.com/evanw/esbuild/issues/714))\n\n    Node had an unfortunate bug where the node process is unnecessarily kept open while a WebAssembly module is being optimized: https://github.com/nodejs/node/issues/36616. This means cases where running `esbuild` should take a few milliseconds can end up taking many seconds instead.\n\n    The workaround was to force node to exit by ending the process early. This was done by esbuild in one of two ways depending on the exit code. For non-zero exit codes (i.e. when there is a build error), the `esbuild` command could just call `process.kill(process.pid)` to avoid the hang. But for zero exit codes, esbuild had to load a N-API native node extension that calls the operating system's `exit(0)` function.\n\n    However, this problem has essentially been fixed in node starting with version 18.3.0. So I have removed this hack from esbuild. If you are using an earlier version of node with `esbuild-wasm` and you don't want the `esbuild` command to hang for a while when exiting, you can upgrade to node 18.3.0 or higher to remove the hang.\n\n    The fix came from a V8 upgrade: [this commit](https://github.com/v8/v8/commit/bfe12807c14c91714c7db1485e6b265439375e16) enabled [dynamic tiering for WebAssembly](https://v8.dev/blog/wasm-dynamic-tiering) by default for all projects that use V8's WebAssembly implementation. Previously all functions in the WebAssembly module were optimized in a single batch job but with dynamic tiering, V8 now optimizes individual WebAssembly functions as needed. This avoids unnecessary WebAssembly compilation which allows node to exit on time.\n\n## 0.15.18\n\n* Performance improvements for both JS and CSS\n\n    This release brings noticeable performance improvements for JS parsing and for CSS parsing and printing. Here's an example benchmark for using esbuild to pretty-print a single large minified CSS file and JS file:\n\n    | Test case      | Previous release | This release       |\n    |----------------|------------------|--------------------|\n    | 4.8mb CSS file | 19ms             | 11ms (1.7x faster) |\n    | 5.8mb JS file  | 36ms             | 32ms (1.1x faster) |\n\n    The performance improvements were very straightforward:\n\n    * Identifiers were being scanned using a generic character advancement function instead of using custom inline code. Advancing past each character involved UTF-8 decoding as well as updating multiple member variables. This was sped up using loop that skips UTF-8 decoding entirely and that only updates member variables once at the end. This is faster because identifiers are plain ASCII in the vast majority of cases, so Unicode decoding is almost always unnecessary.\n\n    * CSS identifiers and CSS strings were still being printed one character at a time. Apparently I forgot to move this part of esbuild's CSS infrastructure beyond the proof-of-concept stage. These were both very obvious in the profiler, so I think maybe I have just never profiled esbuild's CSS printing before?\n\n    * There was unnecessary work being done that was related to source maps when source map output was disabled. I likely haven't observed this before because esbuild's benchmarks always have source maps enabled. This work is now disabled when it's not going to be used.\n\n    I definitely should have caught these performance issues earlier. Better late than never I suppose.\n\n## 0.15.17\n\n* Search for missing source map code on the file system ([#2711](https://github.com/evanw/esbuild/issues/2711))\n\n    [Source maps](https://sourcemaps.info/spec.html) are JSON files that map from compiled code back to the original code. They provide the original source code using two arrays: `sources` (required) and `sourcesContent` (optional). When bundling is enabled, esbuild is able to bundle code with source maps that was compiled by other tools (e.g. with Webpack) and emit source maps that map all the way back to the original code (e.g. before Webpack compiled it).\n\n    Previously if the input source maps omitted the optional `sourcesContent` array, esbuild would use `null` for the source content in the source map that it generates (since the source content isn't available). However, sometimes the original source code is actually still present on the file system. With this release, esbuild will now try to find the original source code using the path in the `sources` array and will use that instead of `null` if it was found.\n\n* Fix parsing bug with TypeScript `infer` and `extends` ([#2712](https://github.com/evanw/esbuild/issues/2712))\n\n    This release fixes a bug where esbuild incorrectly failed to parse valid TypeScript code that nests `extends` inside `infer` inside `extends`, such as in the example below:\n\n    ```ts\n    type A<T> = {};\n    type B = {} extends infer T extends {} ? A<T> : never;\n    ```\n\n    TypeScript code that does this should now be parsed correctly.\n\n* Use `WebAssembly.instantiateStreaming` if available ([#1036](https://github.com/evanw/esbuild/pull/1036), [#1900](https://github.com/evanw/esbuild/pull/1900))\n\n    Currently the WebAssembly version of esbuild uses `fetch` to download `esbuild.wasm` and then `WebAssembly.instantiate` to compile it. There is a newer API called `WebAssembly.instantiateStreaming` that both downloads and compiles at the same time, which can be a performance improvement if both downloading and compiling are slow. With this release, esbuild now attempts to use `WebAssembly.instantiateStreaming` and falls back to the original approach if that fails.\n\n    The implementation for this builds on a PR by [@lbwa](https://github.com/lbwa).\n\n* Preserve Webpack comments inside constructor calls ([#2439](https://github.com/evanw/esbuild/issues/2439))\n\n    This improves the use of esbuild as a faster TypeScript-to-JavaScript frontend for Webpack, which has special [magic comments](https://webpack.js.org/api/module-methods/#magic-comments) inside `new Worker()` expressions that affect Webpack's behavior.\n\n## 0.15.16\n\n* Add a package alias feature ([#2191](https://github.com/evanw/esbuild/issues/2191))\n\n    With this release, you can now easily substitute one package for another at build time with the new `alias` feature. For example, `--alias:oldpkg=newpkg` replaces all imports of `oldpkg` with `newpkg`. One use case for this is easily replacing a node-only package with a browser-friendly package in 3rd-party code that you don't control. These new substitutions happen first before all of esbuild's existing path resolution logic.\n\n    Note that when an import path is substituted using an alias, the resulting import path is resolved in the working directory instead of in the directory containing the source file with the import path. If needed, the working directory can be set with the `cd` command when using the CLI or with the `absWorkingDir` setting when using the JS or Go APIs.\n\n* Fix crash when pretty-printing minified JSX with object spread of object literal with computed property ([#2697](https://github.com/evanw/esbuild/issues/2697))\n\n    JSX elements are translated to JavaScript function calls and JSX element attributes are translated to properties on a JavaScript object literal. These properties are always either strings (e.g. in `<x y />`, `y` is a string) or an object spread (e.g. in `<x {...y} />`, `y` is an object spread) because JSX doesn't provide syntax for directly passing a computed property as a JSX attribute. However, esbuild's minifier has a rule that tries to inline object spread with an inline object literal in JavaScript. For example, `x = { ...{ y } }` is minified to `x={y}` when minification is enabled. This means that there is a way to generate a non-string non-spread JSX attribute in esbuild's internal representation. One example is with `<x {...{ [y]: z }} />`. When minification is enabled, esbuild's internal representation of this is something like `<x [y]={z} />` due to object spread inlining, which is not valid JSX syntax. If this internal representation is then pretty-printed as JSX using `--minify --jsx=preserve`, esbuild previously crashed when trying to print this invalid syntax. With this release, esbuild will now print `<x {...{[y]:z}}/>` in this scenario instead of crashing.\n\n## 0.15.15\n\n* Remove duplicate CSS rules across files ([#2688](https://github.com/evanw/esbuild/issues/2688))\n\n    When two or more CSS rules are exactly the same (even if they are not adjacent), all but the last one can safely be removed:\n\n    ```css\n    /* Before */\n    a { color: red; }\n    span { font-weight: bold; }\n    a { color: red; }\n\n    /* After */\n    span { font-weight: bold; }\n    a { color: red; }\n    ```\n\n    Previously esbuild only did this transformation within a single source file. But with this release, esbuild will now do this transformation across source files, which may lead to smaller CSS output if the same rules are repeated across multiple CSS source files in the same bundle. This transformation is only enabled when minifying (specifically when syntax minification is enabled).\n\n* Add `deno` as a valid value for `target` ([#2686](https://github.com/evanw/esbuild/issues/2686))\n\n    The `target` setting in esbuild allows you to enable or disable JavaScript syntax features for a given version of a set of target JavaScript VMs. Previously [Deno](https://deno.land/) was not one of the JavaScript VMs that esbuild supported with `target`, but it will now be supported starting from this release. For example, versions of Deno older than v1.2 don't support the new `||=` operator, so adding e.g. `--target=deno1.0` to esbuild now lets you tell esbuild to transpile `||=` to older JavaScript.\n\n* Fix the `esbuild-wasm` package in Node v19 ([#2683](https://github.com/evanw/esbuild/issues/2683))\n\n    A recent change to Node v19 added a non-writable `crypto` property to the global object: https://github.com/nodejs/node/pull/44897. This conflicts with Go's WebAssembly shim code, which overwrites the global `crypto` property. As a result, all Go-based WebAssembly code that uses the built-in shim (including esbuild) is now broken on Node v19. This release of esbuild fixes the issue by reconfiguring the global `crypto` property to be writable before invoking Go's WebAssembly shim code.\n\n* Fix CSS dimension printing exponent confusion edge case ([#2677](https://github.com/evanw/esbuild/issues/2677))\n\n    In CSS, a dimension token has a numeric \"value\" part and an identifier \"unit\" part. For example, the dimension token `32px` has a value of `32` and a unit of `px`. The unit can be any valid CSS identifier. The value can be any number in floating-point format including an optional exponent (e.g. `-3.14e-0` has an exponent of `e-0`). The full details of this syntax are here: https://www.w3.org/TR/css-syntax-3/.\n\n    To maintain the integrity of the dimension token through the printing process, esbuild must handle the edge case where the unit looks like an exponent. One such case is the dimension `1e\\32` which has the value `1` and the unit `e2`. It would be bad if this dimension token was printed such that a CSS parser would parse it as a number token with the value `1e2` instead of a dimension token. The way esbuild currently does this is to escape the leading `e` in the dimension unit, so esbuild would parse `1e\\32` but print `1\\65 2` (both `1e\\32` and `1\\65 2` represent a dimension token with a value of `1` and a unit of `e2`).\n\n    However, there is an even narrower edge case regarding this edge case. If the value part of the dimension token itself has an `e`, then it's not necessary to escape the `e` in the dimension unit because a CSS parser won't confuse the unit with the exponent even though it looks like one (since a number can only have at most one exponent). This came up because the grammar for the CSS `unicode-range` property uses a hack that lets you specify a hexadecimal range without quotes even though CSS has no token for a hexadecimal range. The hack is to allow the hexadecimal range to be parsed as a dimension token and optionally also a number token. Here is the grammar for `unicode-range`:\n\n    ```\n    unicode-range =\n      <urange>#\n\n    <urange> =\n      u '+' <ident-token> '?'*            |\n      u <dimension-token> '?'*            |\n      u <number-token> '?'*               |\n      u <number-token> <dimension-token>  |\n      u <number-token> <number-token>     |\n      u '+' '?'+\n    ```\n\n    and here is an example `unicode-range` declaration that was problematic for esbuild:\n\n    ```css\n    @font-face {\n      unicode-range: U+0e2e-0e2f;\n    }\n    ```\n\n    This is parsed as a dimension with a value of `+0e2` and a unit of `e-0e2f`. This was problematic for esbuild because the unit starts with `e-0` which could be confused with an exponent when appended after a number, so esbuild was escaping the `e` character in the unit. However, this escaping is unnecessary because in this case the dimension value already has an exponent in it. With this release, esbuild will no longer unnecessarily escape the `e` in the dimension unit in these cases, which should fix the printing of `unicode-range` declarations.\n\n    An aside: You may be wondering why esbuild is trying to escape the `e` at all and why it doesn't just pass through the original source code unmodified. The reason why esbuild does this is that, for robustness, esbuild's AST generally tries to omit semantically-unrelated information and esbuild's code printers always try to preserve the semantics of the underlying AST. That way the rest of esbuild's internals can just deal with semantics instead of presentation. They don't have to think about how the AST will be printed when changing the AST. This is the same reason that esbuild's JavaScript AST doesn't have a \"parentheses\" node (e.g. `a * (b + c)` is represented by the AST `multiply(a, add(b, c))` instead of `multiply(a, parentheses(add(b, c)))`). Instead, the printer automatically inserts parentheses as necessary to maintain the semantics of the AST, which means all of the optimizations that run over the AST don't have to worry about keeping the parentheses up to date. Similarly, the CSS AST for the dimension token stores the actual unit and the printer makes sure the unit is properly escaped depending on what value it's placed after. All of the other code operating on CSS ASTs doesn't have to worry about parsing escapes to compare units or about keeping escapes up to date when the AST is modified. Hopefully that makes sense.\n\n* Attempt to avoid creating the `node_modules/.cache` directory for people that use Yarn 2+ in Plug'n'Play mode ([#2685](https://github.com/evanw/esbuild/issues/2685))\n\n    When Yarn's PnP mode is enabled, packages installed by Yarn may or may not be put inside `.zip` files. The specific heuristics for when this happens change over time in between Yarn versions. This is problematic for esbuild because esbuild's JavaScript package needs to execute a binary file inside the package. Yarn makes extensive modifications to Node's file system APIs at run time to pretend that `.zip` files are normal directories and to make it hard to tell whether a file is real or not (since in theory it doesn't matter). But they haven't modified Node's `child_process.execFileSync` API so attempting to execute a file inside a zip file fails. To get around this, esbuild previously used Node's file system APIs to copy the binary executable to another location before invoking `execFileSync`. Under the hood this caused Yarn to extract the file from the zip file into a real file that can then be run.\n\n    However, esbuild copied its executable into `node_modules/.cache/esbuild`. This is the [official recommendation from the Yarn team](https://yarnpkg.com/advanced/rulebook/#packages-should-never-write-inside-their-own-folder-outside-of-postinstall) for where packages are supposed to put these types of files when Yarn PnP is being used. However, users of Yarn PnP with esbuild find this really annoying because they don't like looking at the `node_modules` directory. With this release, esbuild now sets `\"preferUnplugged\": true` in its `package.json` files, which tells newer versions of Yarn to not put esbuild's packages in a zip file. There may exist older versions of Yarn that don't support `preferUnplugged`. In that case esbuild should still copy the executable to a cache directory, so it should still run (hopefully, since I haven't tested this myself). Note that esbuild setting `\"preferUnplugged\": true` may have the side effect of esbuild taking up more space on the file system in the event that multiple platforms are installed simultaneously, or that you're using an older version of Yarn that always installs packages for all platforms. In that case you may want to update to a newer version of Yarn since Yarn has recently changed to only install packages for the current platform.\n\n## 0.15.14\n\n* Fix parsing of TypeScript `infer` inside a conditional `extends` ([#2675](https://github.com/evanw/esbuild/issues/2675))\n\n    Unlike JavaScript, parsing TypeScript sometimes requires backtracking. The `infer A` type operator can take an optional constraint of the form `infer A extends B`. However, this syntax conflicts with the similar conditional type operator `A extends B ? C : D` in cases where the syntax is combined, such as `infer A extends B ? C : D`. This is supposed to be parsed as `(infer A) extends B ? C : D`. Previously esbuild incorrectly parsed this as `(infer A extends B) ? C : D` instead, which is a parse error since the `?:` conditional operator requires the `extends` keyword as part of the conditional type. TypeScript disambiguates by speculatively parsing the `extends` after the `infer`, but backtracking if a `?` token is encountered afterward. With this release, esbuild should now do the same thing, so esbuild should now correctly parse these types. Here's a real-world example of such a type:\n\n    ```ts\n    type Normalized<T> = T extends Array<infer A extends object ? infer A : never>\n      ? Dictionary<Normalized<A>>\n      : {\n          [P in keyof T]: T[P] extends Array<infer A extends object ? infer A : never>\n            ? Dictionary<Normalized<A>>\n            : Normalized<T[P]>\n        }\n    ```\n\n* Avoid unnecessary watch mode rebuilds when debug logging is enabled ([#2661](https://github.com/evanw/esbuild/issues/2661))\n\n    When debug-level logs are enabled (such as with `--log-level=debug`), esbuild's path resolution subsystem generates debug log messages that say something like \"Read 20 entries for directory /home/user\" to help you debug what esbuild's path resolution is doing. This caused esbuild's watch mode subsystem to add a dependency on the full list of entries in that directory since if that changes, the generated log message would also have to be updated. However, meant that on systems where a parent directory undergoes constant directory entry churn, esbuild's watch mode would continue to rebuild if `--log-level=debug` was passed.\n\n    With this release, these debug log messages are now generated by \"peeking\" at the file system state while bypassing esbuild's watch mode dependency tracking. So now watch mode doesn't consider the count of directory entries in these debug log messages to be a part of the build that needs to be kept up to date when the file system state changes.\n\n## 0.15.13\n\n* Add support for the TypeScript 4.9 `satisfies` operator ([#2509](https://github.com/evanw/esbuild/pull/2509))\n\n    TypeScript 4.9 introduces a new operator called `satisfies` that lets you check that a given value satisfies a less specific type without casting it to that less specific type and without generating any additional code at run-time. It looks like this:\n\n    ```ts\n    const value = { foo: 1, bar: false } satisfies Record<string, number | boolean>\n    console.log(value.foo.toFixed(1)) // TypeScript knows that \"foo\" is a number here\n    ```\n\n    Before this existed, you could use a cast with `as` to check that a value satisfies a less specific type, but that removes any additional knowledge that TypeScript has about that specific value:\n\n    ```ts\n    const value = { foo: 1, bar: false } as Record<string, number | boolean>\n    console.log(value.foo.toFixed(1)) // TypeScript no longer knows that \"foo\" is a number\n    ```\n\n    You can read more about this feature in [TypeScript's blog post for 4.9](https://devblogs.microsoft.com/typescript/announcing-typescript-4-9-rc/#the-satisfies-operator) as well as [the associated TypeScript issue for this feature](https://github.com/microsoft/TypeScript/issues/47920).\n\n    This feature was implemented in esbuild by [@magic-akari](https://github.com/magic-akari).\n\n* Fix watch mode constantly rebuilding if the parent directory is inaccessible ([#2640](https://github.com/evanw/esbuild/issues/2640))\n\n    Android is unusual in that it has an inaccessible directory in the path to the root, which esbuild was not originally built to handle. To handle cases like this, the path resolution layer in esbuild has a hack where it treats inaccessible directories as empty. However, esbuild's watch implementation currently triggers a rebuild if a directory previously encountered an error but the directory now exists. The assumption is that the previous error was caused by the directory not existing. Although that's usually the case, it's not the case for this particular parent directory on Android. Instead the error is that the directory previously existed but was inaccessible.\n\n    This discrepancy between esbuild's path resolution layer and its watch mode was causing watch mode to rebuild continuously on Android. With this release, esbuild's watch mode instead checks for an error status change in the `readdir` file system call, so watch mode should no longer rebuild continuously on Android.\n\n* Apply a fix for a rare deadlock with the JavaScript API ([#1842](https://github.com/evanw/esbuild/issues/1842), [#2485](https://github.com/evanw/esbuild/issues/2485))\n\n    There have been reports of esbuild sometimes exiting with an \"all goroutines are asleep\" deadlock message from the Go language runtime. This issue hasn't made much progress until recently, where a possible cause was discovered (thanks to [@jfirebaugh](https://github.com/jfirebaugh) for the investigation). This release contains a possible fix for that possible cause, so this deadlock may have been fixed. The fix cannot be easily verified because the deadlock is non-deterministic and rare. If this was indeed the cause, then this issue only affected the JavaScript API in situations where esbuild was already in the process of exiting.\n\n    In detail: The underlying cause is that Go's [`sync.WaitGroup`](https://pkg.go.dev/sync#WaitGroup) API for waiting for a set of goroutines to finish is not fully thread-safe. Specifically it's not safe to call `Add()` concurrently with `Wait()` when the wait group counter is zero due to a data race. This situation could come up with esbuild's JavaScript API when the host JavaScript process closes the child process's stdin and the child process (with no active tasks) calls `Wait()` to check that there are no active tasks, at the same time as esbuild's watchdog timer calls `Add()` to add an active task (that pings the host to see if it's still there). The fix in this release is to avoid calling `Add()` once we learn that stdin has been closed but before we call `Wait()`.\n\n## 0.15.12\n\n* Fix minifier correctness bug with single-use substitutions ([#2619](https://github.com/evanw/esbuild/issues/2619))\n\n    When minification is enabled, esbuild will attempt to eliminate variables that are only used once in certain cases. For example, esbuild minifies this code:\n\n    ```js\n    function getEmailForUser(name) {\n      let users = db.table('users');\n      let user = users.find({ name });\n      let email = user?.get('email');\n      return email;\n    }\n    ```\n\n    into this code:\n\n    ```js\n    function getEmailForUser(e){return db.table(\"users\").find({name:e})?.get(\"email\")}\n    ```\n\n    However, this transformation had a bug where esbuild did not correctly consider the \"read\" part of binary read-modify-write assignment operators. For example, it's incorrect to minify the following code into `bar += fn()` because the call to `fn()` might modify `bar`:\n\n    ```js\n    const foo = fn();\n    bar += foo;\n    ```\n\n    In addition to fixing this correctness bug, this release also improves esbuild's output in the case where all values being skipped over are primitives:\n\n    ```js\n    function toneMapLuminance(r, g, b) {\n      let hdr = luminance(r, g, b)\n      let decay = 1 / (1 + hdr)\n      return 1 - decay\n    }\n    ```\n\n    Previous releases of esbuild didn't substitute these single-use variables here, but esbuild will now minify this to the following code starting with this release:\n\n    ```js\n    function toneMapLuminance(e,n,a){return 1-1/(1+luminance(e,n,a))}\n    ```\n\n## 0.15.11\n\n* Fix various edge cases regarding template tags and `this` ([#2610](https://github.com/evanw/esbuild/issues/2610))\n\n    This release fixes some bugs where the value of `this` wasn't correctly preserved when evaluating template tags in a few edge cases. These edge cases are listed below:\n\n    ```js\n    async function test() {\n      class Foo { foo() { return this } }\n      class Bar extends Foo {\n        a = async () => super.foo``\n        b = async () => super['foo']``\n        c = async (foo) => super[foo]``\n      }\n      function foo() { return this }\n      const obj = { foo }\n      const bar = new Bar\n      console.log(\n        (await bar.a()) === bar,\n        (await bar.b()) === bar,\n        (await bar.c('foo')) === bar,\n        { foo }.foo``.foo === foo,\n        (true && obj.foo)`` !== obj,\n        (false || obj.foo)`` !== obj,\n        (null ?? obj.foo)`` !== obj,\n      )\n    }\n    test()\n    ```\n\n    Each edge case in the code above previously incorrectly printed `false` when run through esbuild with `--minify --target=es6` but now correctly prints `true`. These edge cases are unlikely to have affected real-world code.\n\n## 0.15.10\n\n* Add support for node's \"pattern trailers\" syntax ([#2569](https://github.com/evanw/esbuild/issues/2569))\n\n    After esbuild implemented node's `exports` feature in `package.json`, node changed the feature to also allow text after `*` wildcards in patterns. Previously the `*` was required to be at the end of the pattern. It lets you do something like this:\n\n    ```json\n    {\n      \"exports\": {\n        \"./features/*\": \"./features/*.js\",\n        \"./features/*.js\": \"./features/*.js\"\n      }\n    }\n    ```\n\n    With this release, esbuild now supports these types of patterns too.\n\n* Fix subpath imports with Yarn PnP ([#2545](https://github.com/evanw/esbuild/issues/2545))\n\n    Node has a little-used feature called [subpath imports](https://nodejs.org/api/packages.html#subpath-imports) which are package-internal imports that start with `#` and that go through the `imports` map in `package.json`. Previously esbuild had a bug that caused esbuild to not handle these correctly in packages installed via Yarn's \"Plug'n'Play\" installation strategy. The problem was that subpath imports were being checked after Yarn PnP instead of before. This release reorders these checks, which should allow subpath imports to work in this case.\n\n* Link from JS to CSS in the metafile ([#1861](https://github.com/evanw/esbuild/issues/1861), [#2565](https://github.com/evanw/esbuild/issues/2565))\n\n    When you import CSS into a bundled JS file, esbuild creates a parallel CSS bundle next to your JS bundle. So if `app.ts` imports some CSS files and you bundle it, esbuild will give you `app.js` and `app.css`. You would then add both `<script src=\"app.js\"></script>` and `<link href=\"app.css\" rel=\"stylesheet\">` to your HTML to include everything in the page. This approach is more efficient than having esbuild insert additional JavaScript into `app.js` that downloads and includes `app.css` because it means the browser can download and parse both the CSS and the JS in parallel (and potentially apply the CSS before the JS has even finished downloading).\n\n    However, sometimes it's difficult to generate the `<link>` tag. One case is when you've added `[hash]` to the [entry names](https://esbuild.github.io/api/#entry-names) setting to include a content hash in the file name. Then the file name will look something like `app-GX7G2SBE.css` and may change across subsequent builds. You can tell esbuild to generate build metadata using the `metafile` API option but the metadata only tells you which generated JS bundle corresponds to a JS entry point (via the `entryPoint` property), not which file corresponds to the associated CSS bundle. Working around this was hacky and involved string manipulation.\n\n    This release adds the `cssBundle` property to the metafile to make this easier. It's present on the metadata for the generated JS bundle and points to the associated CSS bundle. So to generate the HTML tags for a given JS entry point, you first find the output file with the `entryPoint` you are looking for (and put that in a `<script>` tag), then check for the `cssBundle` property to find the associated CSS bundle (and put that in a `<link>` tag).\n\n    One thing to note is that there is deliberately no `jsBundle` property mapping the other way because it's not a 1:1 relationship. Two JS bundles can share the same CSS bundle in the case where the associated CSS bundles have the same name and content. In that case there would be no one value for a hypothetical `jsBundle` property to have.\n\n## 0.15.9\n\n* Fix an obscure npm package installation issue with `--omit=optional` ([#2558](https://github.com/evanw/esbuild/issues/2558))\n\n    The previous release introduced a regression with `npm install esbuild --omit=optional` where the file `node_modules/.bin/esbuild` would no longer be present after installation. That could cause any package scripts which used the `esbuild` command to no longer work. This release fixes the regression so `node_modules/.bin/esbuild` should now be present again after installation. This regression only affected people installing esbuild using `npm` with either the `--omit=optional` or `--no-optional` flag, which is a somewhat unusual situation.\n\n    **More details:**\n\n    The reason for this regression is due to some obscure npm implementation details. Since the Go compiler doesn't support trivial cross-compiling on certain Android platforms, esbuild's installer installs a WebAssembly shim on those platforms instead. In the previous release I attempted to simplify esbuild's WebAssembly shims to depend on the `esbuild-wasm` package instead of including another whole copy of the WebAssembly binary (to make publishing faster and to save on file system space after installation). However, both the `esbuild` package and the `esbuild-wasm` package provide a binary called `esbuild` and it turns out that adding `esbuild-wasm` as a nested dependency of the `esbuild` package (specifically `esbuild` optionally depends on `@esbuild/android-arm` which depends on `esbuild-wasm`) caused npm to be confused about what `node_modules/.bin/esbuild` is supposed to be.\n\n    It's pretty strange and unexpected that disabling the installation of optional dependencies altogether would suddenly cause an optional dependency's dependency to conflict with the top-level package. What happens under the hood is that if `--omit=optional` is present, npm attempts to uninstall the `esbuild-wasm` nested dependency at the end of `npm install` (even though the `esbuild-wasm` package was never installed due to `--omit=optional`). This uninstallation causes `node_modules/.bin/esbuild` to be deleted.\n\n    After doing a full investigation, I discovered that npm's handling of the `.bin` directory is deliberately very brittle. When multiple packages in the dependency tree put something in `.bin` with the same name, the end result is non-deterministic/random. What you get in `.bin` might be from one package, from the other package, or might be missing entirely. The workaround suggested by npm is to just avoid having two packages that put something in `.bin` with the same name. So this was fixed by making the `@esbuild/android-arm` and `esbuild-android-64` packages each include another whole copy of the WebAssembly binary, which works because these packages don't put anything in `.bin`.\n\n## 0.15.8\n\n* Fix JSX name collision edge case ([#2534](https://github.com/evanw/esbuild/issues/2534))\n\n    Code generated by esbuild could have a name collision in the following edge case:\n\n    * The JSX transformation mode is set to `automatic`, which causes `import` statements to be inserted\n    * An element uses a `{...spread}` followed by a `key={...}`, which uses the legacy `createElement` fallback imported from `react`\n    * Another import uses a name that ends with `react` such as `@remix-run/react`\n    * The output format has been set to CommonJS so that `import` statements are converted into require calls\n\n    In this case, esbuild previously generated two variables with the same name `import_react`, like this:\n\n    ```js\n    var import_react = require(\"react\");\n    var import_react2 = require(\"@remix-run/react\");\n    ```\n\n    That bug is fixed in this release. The code generated by esbuild no longer contains a name collision.\n\n* Fall back to WebAssembly on Android ARM ([#1556](https://github.com/evanw/esbuild/issues/1556), [#1578](https://github.com/evanw/esbuild/issues/1578), [#2335](https://github.com/evanw/esbuild/issues/2335), [#2526](https://github.com/evanw/esbuild/issues/2526))\n\n    Go's compiler supports trivial cross-compiling to almost all platforms without installing any additional software other than the Go compiler itself. This has made it very easy for esbuild to publish native binary executables for many platforms. However, it strangely doesn't support cross-compiling to Android ARM without installing the Android build tools.\n\n    So instead of publishing a native esbuild binary executable to npm, this release publishes a WebAssembly fallback build. This is essentially the same as the `esbuild-wasm` package but it's installed automatically when you install the `esbuild` package on Android ARM. So packages that depend on the `esbuild` package should now work on Android ARM. This change has not yet been tested end-to-end because I don't have a 32-bit Android ARM device myself, but in theory it should work.\n\n    This inherits the drawbacks of WebAssembly including significantly slower performance than native as well as potentially also more severe memory usage limitations and lack of certain features (e.g. `--serve`). If you want to use a native binary executable of esbuild on Android ARM, you may be able to build it yourself from source after installing the Android build tools.\n\n* Attempt to better support Yarn's `ignorePatternData` feature ([#2495](https://github.com/evanw/esbuild/issues/2495))\n\n    Part of resolving paths in a project using Yarn's Plug'n'Play feature involves evaluating a regular expression in the `ignorePatternData` property of `.pnp.data.json`. However, it turns out that the particular regular expressions generated by Yarn use some syntax that works with JavaScript regular expressions but that does not work with Go regular expressions.\n\n    In this release, esbuild will now strip some of the the problematic syntax from the regular expression before compiling it, which should hopefully allow it to be compiled by Go's regular expression engine. The specific character sequences that esbuild currently strips are as follows:\n\n    * `(?!\\.)`\n    * `(?!(?:^|\\/)\\.)`\n    * `(?!\\.{1,2}(?:\\/|$))`\n    * `(?!(?:^|\\/)\\.{1,2}(?:\\/|$))`\n\n    These seem to be used by Yarn to avoid the `.` and `..` path segments in the middle of relative paths. The removal of these character sequences seems relatively harmless in this case since esbuild shouldn't ever generate such path segments. This change should add support to esbuild for Yarn's [`pnpIgnorePatterns`](https://yarnpkg.com/configuration/yarnrc/#pnpIgnorePatterns) feature.\n\n* Fix non-determinism issue with legacy block-level function declarations and strict mode ([#2537](https://github.com/evanw/esbuild/issues/2537))\n\n    When function declaration statements are nested inside a block in strict mode, they are supposed to only be available within that block's scope. But in \"sloppy mode\" (which is what non-strict mode is commonly called), they are supposed to be available within the whole function's scope:\n\n    ```js\n    // This returns 1 due to strict mode\n    function test1() {\n      'use strict'\n      function fn() { return 1 }\n      if (true) { function fn() { return 2 } }\n      return fn()\n    }\n\n    // This returns 2 due to sloppy mode\n    function test2() {\n      function fn() { return 1 }\n      if (true) { function fn() { return 2 } }\n      return fn()\n    }\n    ```\n\n    To implement this, esbuild compiles these two functions differently to reflect their different semantics:\n\n    ```js\n    function test1() {\n      \"use strict\";\n      function fn() {\n        return 1;\n      }\n      if (true) {\n        let fn2 = function() {\n          return 2;\n        };\n      }\n      return fn();\n    }\n    function test2() {\n      function fn() {\n        return 1;\n      }\n      if (true) {\n        let fn2 = function() {\n          return 2;\n        };\n        var fn = fn2;\n      }\n      return fn();\n    }\n    ```\n\n    However, the compilation had a subtle bug where the automatically-generated function-level symbols for multible hoisted block-level function declarations in the same block a sloppy-mode context were generated in a random order if the output was in strict mode, which could be the case if TypeScript's `alwaysStrict` setting was set to true. This lead to non-determinism in the output as the minifier would randomly exchange the generated names for these symbols on different runs. This bug has been fixed by sorting the keys of the unordered map before iterating over them.\n\n* Fix parsing of `@keyframes` with string identifiers ([#2555](https://github.com/evanw/esbuild/issues/2555))\n\n    Firefox supports `@keyframes` with string identifier names. Previously this was treated as a syntax error by esbuild as it doesn't work in any other browser. The specification allows for this however, so it's technically not a syntax error (even though it would be unwise to use this feature at the moment). There was also a bug where esbuild would remove the identifier name in this case as the syntax wasn't recognized.\n\n    This release changes esbuild's parsing of `@keyframes` to now consider this case to be an unrecognized CSS rule. That means it will be passed through unmodified (so you can now use esbuild to bundle this Firefox-specific CSS) but the CSS will not be pretty-printed or minified. I don't think it makes sense for esbuild to have special code to handle this Firefox-specific syntax at this time. This decision can be revisited in the future if other browsers add support for this feature.\n\n* Add the `--jsx-side-effects` API option ([#2539](https://github.com/evanw/esbuild/issues/2539), [#2546](https://github.com/evanw/esbuild/pull/2546))\n\n    By default esbuild assumes that JSX expressions are side-effect free, which means they are annoated with `/* @__PURE__ */` comments and are removed during bundling when they are unused. This follows the common use of JSX for virtual DOM and applies to the vast majority of JSX libraries. However, some people have written JSX libraries that don't have this property. JSX expressions can have arbitrary side effects and can't be removed. If you are using such a library, you can now pass `--jsx-side-effects` to tell esbuild that JSX expressions have side effects so it won't remove them when they are unused.\n\n    This feature was contributed by [@rtsao](https://github.com/rtsao).\n\n## 0.15.7\n\n* Add `--watch=forever` to allow esbuild to never terminate ([#1511](https://github.com/evanw/esbuild/issues/1511), [#1885](https://github.com/evanw/esbuild/issues/1885))\n\n    Currently using esbuild's watch mode via `--watch` from the CLI will stop watching if stdin is closed. The rationale is that stdin is automatically closed by the OS when the parent process exits, so stopping watch mode when stdin is closed ensures that esbuild's watch mode doesn't keep running forever after the parent process has been closed. For example, it would be bad if you wrote a shell script that did `esbuild --watch &` to run esbuild's watch mode in the background, and every time you run the script it creates a new `esbuild` process that runs forever.\n\n    However, there are cases when it makes sense for esbuild's watch mode to never exit. One such case is within a short-lived VM where the lifetime of all processes inside the VM is expected to be the lifetime of the VM. Previously you could easily do this by piping the output of a long-lived command into esbuild's stdin such as `sleep 999999999 | esbuild --watch &`. However, this possibility often doesn't occur to people, and it also doesn't work on Windows. People also sometimes attempt to keep esbuild open by piping an infinite stream of data to esbuild such as with `esbuild --watch </dev/zero &` which causes esbuild to spin at 100% CPU. So with this release, esbuild now has a `--watch=forever` flag that will not stop watch mode when stdin is closed.\n\n* Work around `PATH` without `node` in install script ([#2519](https://github.com/evanw/esbuild/issues/2519))\n\n    Some people install esbuild's npm package in an environment without the `node` command in their `PATH`. This fails on Windows because esbuild's install script runs the `esbuild` command before exiting as a sanity check, and on Windows the `esbuild` command has to be a JavaScript file because of some internal details about how npm handles the `bin` folder (specifically the `esbuild` command lacks the `.exe` extension, which is required on Windows). This release attempts to work around this problem by using `process.execPath` instead of `\"node\"` as the command for running node. In theory this means the installer can now still function on Windows if something is wrong with `PATH`.\n\n## 0.15.6\n\n* Lower `for await` loops ([#1930](https://github.com/evanw/esbuild/issues/1930))\n\n    This release lowers `for await` loops to the equivalent `for` loop containing `await` when esbuild is configured such that `for await` loops are unsupported. This transform still requires at least generator functions to be supported since esbuild's lowering of `await` currently relies on generators. This new transformation is mostly modeled after what the TypeScript compiler does. Here's an example:\n\n    ```js\n    async function f() {\n      for await (let x of y)\n        x()\n    }\n    ```\n\n    The code above will now become the following code with `--target=es2017` (omitting the code for the `__forAwait` helper function):\n\n    ```js\n    async function f() {\n      try {\n        for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {\n          let x = temp.value;\n          x();\n        }\n      } catch (temp) {\n        error = [temp];\n      } finally {\n        try {\n          more && (temp = iter.return) && await temp.call(iter);\n        } finally {\n          if (error)\n            throw error[0];\n        }\n      }\n    }\n    ```\n\n* Automatically fix invalid `supported` configurations ([#2497](https://github.com/evanw/esbuild/issues/2497))\n\n    The `--target=` setting lets you tell esbuild to target a specific version of one or more JavaScript runtimes such as `chrome80,node14` and esbuild will restrict its output to only those features supported by all targeted JavaScript runtimes. More recently, esbuild introduced the `--supported:` setting that lets you override which features are supported on a per-feature basis. However, this now lets you configure nonsensical things such as `--supported:async-await=false --supported:async-generator=true`. Previously doing this could result in esbuild building successfully but producing invalid output.\n\n    Starting with this release, esbuild will now attempt to automatically fix nonsensical feature override configurations by introducing more overrides until the configuration makes sense. So now the configuration from previous example will be changed such that `async-await=false` implies `async-generator=false`. The full list of implications that were introduced is below:\n\n    * `async-await=false` implies:\n        * `async-generator=false`\n        * `for-await=false`\n        * `top-level-await=false`\n\n    * `generator=false` implies:\n        * `async-generator=false`\n\n    * `object-accessors=false` implies:\n        * `class-private-accessor=false`\n        * `class-private-static-accessor=false`\n\n    * `class-field=false` implies:\n        * `class-private-field=false`\n\n    * `class-static-field=false` implies:\n        * `class-private-static-field=false`\n\n    * `class=false` implies:\n        * `class-field=false`\n        * `class-private-accessor=false`\n        * `class-private-brand-check=false`\n        * `class-private-field=false`\n        * `class-private-method=false`\n        * `class-private-static-accessor=false`\n        * `class-private-static-field=false`\n        * `class-private-static-method=false`\n        * `class-static-blocks=false`\n        * `class-static-field=false`\n\n* Implement a small minification improvement ([#2496](https://github.com/evanw/esbuild/issues/2496))\n\n    Some people write code that contains a label with an immediate break such as `x: break x`. Previously this code was not removed during minification but it will now be removed during minification starting with this release.\n\n* Fix installing esbuild via Yarn with `enableScripts: false` configured ([#2457](https://github.com/evanw/esbuild/pull/2457))\n\n    If esbuild is installed with Yarn with the `enableScripts: false` setting configured, then Yarn will not \"unplug\" the `esbuild` package (i.e. it will keep the entire package inside a `.zip` file). This messes with esbuild's library code that extracts the platform-specific binary executable because that code copies the binary executable into the esbuild package directory, and Yarn's `.zip` file system shim doesn't let you write to a directory inside of a `.zip` file. This release fixes this problem by writing to the `node_modules/.cache/esbuild` directory instead in this case. So you should now be able to use esbuild with Yarn when `enableScripts: false` is configured.\n\n    This fix was contributed by [@jonaskuske](https://github.com/jonaskuske).\n\n## 0.15.5\n\n* Fix issues with Yarn PnP and Yarn's workspaces feature ([#2476](https://github.com/evanw/esbuild/issues/2476))\n\n    This release makes sure esbuild works with a Yarn feature called [workspaces](https://yarnpkg.com/features/workspaces/). Previously esbuild wasn't tested in this scenario, but this scenario now has test coverage. Getting this to work involved further tweaks to esbuild's custom code for what happens after Yarn PnP's path resolution algorithm runs, which is not currently covered by Yarn's PnP specification. These tweaks also fix `exports` map resolution with Yarn PnP for non-empty subpaths, which wasn't previously working.\n\n## 0.15.4\n\n* Consider TypeScript import assignments to be side-effect free ([#2468](https://github.com/evanw/esbuild/issues/2468))\n\n    TypeScript has a [legacy import syntax](https://www.typescriptlang.org/docs/handbook/namespaces.html#aliases) for working with TypeScript namespaces that looks like this:\n\n    ```ts\n    import { someNamespace } from './some-file'\n    import bar = someNamespace.foo;\n\n    // some-file.ts\n    export namespace someNamespace {\n      export let foo = 123\n    }\n    ```\n\n    Since esbuild converts TypeScript into JavaScript one file at a time, it doesn't know if `bar` is supposed to be a value or a type (or both, which TypeScript actually allows in this case). This is problematic because values are supposed to be kept during the conversion but types are supposed to be removed during the conversion. Currently esbuild keeps `bar` in the output, which is done because `someNamespace.foo` is a property access and property accesses run code that could potentially have a side effect (although there is no side effect in this case).\n\n    With this release, esbuild will now consider `someNamespace.foo` to have no side effects. This means `bar` will now be removed when bundling and when tree shaking is enabled. Note that it will still not be removed when tree shaking is disabled. This is because in this mode, esbuild supports adding additional code to the end of the generated output that's in the same scope as the module. That code could potentially make use of `bar`, so it would be incorrect to remove it. If you want `bar` to be removed, you'll have to enable tree shaking (which tells esbuild that nothing else depends on the unexported top-level symbols in the generated output).\n\n* Change the order of the banner and the `\"use strict\"` directive ([#2467](https://github.com/evanw/esbuild/issues/2467))\n\n    Previously the top of the file contained the following things in order:\n\n    1. The hashbang comment (see below) from the source code, if present\n    2. The `\"use strict\"` directive from the source code, if present\n    3. The content of esbuild's `banner` API option, if specified\n\n    This was problematic for people that used the `banner` API option to insert the hashbang comment instead of using esbuild's hashbang comment preservation feature. So with this release, the order has now been changed to:\n\n    1. The hashbang comment (see below) from the source code, if present\n    2. The content of esbuild's `banner` API option, if specified\n    3. The `\"use strict\"` directive from the source code, if present\n\n    I'm considering this change to be a bug fix instead of a breaking change because esbuild's documentation states that the `banner` API option can be used to \"insert an arbitrary string at the beginning of generated JavaScript files\". While this isn't technically true because esbuild may still insert the original hashbang comment before the banner, it's at least more correct now because the banner will now come before the `\"use strict\"` directive.\n\n    For context: JavaScript files recently allowed using a [hashbang comment](https://github.com/tc39/proposal-hashbang), which starts with `#!` and which must start at the very first character of the file. It allows Unix systems to execute the file directly as a script without needing to prefix it by the `node` command. This comment typically has the value `#!/usr/bin/env node`. Hashbang comments will be a part of ES2023 when it's released next year.\n\n* Fix `exports` maps with Yarn PnP path resolution ([#2473](https://github.com/evanw/esbuild/issues/2473))\n\n    The Yarn PnP specification says that to resolve a package path, you first resolve it to the absolute path of a directory, and then you run node's module resolution algorithm on it. Previously esbuild followed this part of the specification. However, doing this means that `exports` in `package.json` is not respected because node's module resolution algorithm doesn't interpret `exports` for absolute paths. So with this release, esbuild will now use a modified algorithm that deviates from both specifications but that should hopefully behave more similar to what Yarn actually does: node's module resolution algorithm is run with the original import path but starting from the directory returned by Yarn PnP.\n\n## 0.15.3\n\n* Change the Yarn PnP manifest to a singleton ([#2463](https://github.com/evanw/esbuild/issues/2463))\n\n    Previously esbuild searched for the Yarn PnP manifest in the parent directories of each file. But with Yarn's `enableGlobalCache` setting it's possible to configure Yarn PnP's implementation to reach outside of the directory subtree containing the Yarn PnP manifest. This was causing esbuild to fail to bundle projects with the `enableGlobalCache` setting enabled.\n\n    To handle this case, *esbuild will now only search for the Yarn PnP manifest in the current working directory of the esbuild process*. If you're using esbuild's CLI, this means you will now have to `cd` into the appropriate directory first. If you're using esbuild's API, you can override esbuild's value for the current working directory with the `absWorkingDir` API option.\n\n* Fix Yarn PnP resolution failures due to backslashes in paths on Windows ([#2462](https://github.com/evanw/esbuild/issues/2462))\n\n    Previously dependencies of a Yarn PnP virtual dependency failed to resolve on Windows. This was because Windows uses `\\` instead of `/` as a path separator, and the path manipulation algorithms used for Yarn PnP expected `/`. This release converts `\\` into `/` in Windows paths, which fixes this issue.\n\n* Fix `sideEffects` patterns containing slashes on Windows ([#2465](https://github.com/evanw/esbuild/issues/2465))\n\n    The `sideEffects` field in `package.json` lets you specify an array of patterns to mark which files have side effects (which causes all other files to be considered to not have side effects by exclusion). That looks like this:\n\n    ```json\n    \"sideEffects\": [\n      \"**/index.js\",\n      \"**/index.prod.js\"\n    ]\n    ```\n\n    However, the presence of the `/` character in the pattern meant that the pattern failed to match Windows-style paths, which broke `sideEffects` on Windows in this case. This release fixes this problem by adding additional code to handle Windows-style paths.\n\n## 0.15.2\n\n* Fix Yarn PnP issue with packages containing `index.js` ([#2455](https://github.com/evanw/esbuild/issues/2455), [#2461](https://github.com/evanw/esbuild/issues/2461))\n\n    Yarn PnP's tests require the resolved paths to end in `/`. That's not how the rest of esbuild's internals work, however, and doing this messed up esbuild's node module path resolution regarding automatically-detected `index.js` files. Previously packages that relied on implicit `index.js` resolution rules didn't work with esbuild under Yarn PnP. Removing this slash has fixed esbuild's path resolution behavior regarding `index.js`, which should now the same both with and without Yarn PnP.\n\n* Fix Yarn PnP support for `extends` in `tsconfig.json` ([#2456](https://github.com/evanw/esbuild/issues/2456))\n\n    Previously using `extends` in `tsconfig.json` with a path in a Yarn PnP package didn't work. This is because the process of setting up package path resolution rules requires parsing `tsconfig.json` files (due to the `baseUrl` and `paths` features) and resolving `extends` to a package path requires package path resolution rules to already be set up, which is a circular dependency. This cycle is broken by using special rules for `extends` in `tsconfig.json` that bypasses esbuild's normal package path resolution process. This is why using `extends` with a Yarn PnP package didn't automatically work. With this release, these special rules have been modified to check for a Yarn PnP manifest so this case should work now.\n\n* Fix Yarn PnP support in `esbuild-wasm` ([#2458](https://github.com/evanw/esbuild/issues/2458))\n\n    When running esbuild via WebAssembly, Yarn PnP support previously failed because Go's file system internals return `EINVAL` when trying to read a `.zip` file as a directory when run with WebAssembly. This was unexpected because Go's file system internals return `ENOTDIR` for this case on native. This release updates esbuild to treat `EINVAL` like `ENOTDIR` in this case, which fixes using `esbuild-wasm` to bundle a Yarn PnP project.\n\n    Note that to be able to use `esbuild-wasm` for Yarn PnP successfully, you currently have to run it using `node` instead of `yarn node`. This is because the file system shim that Yarn overwrites node's native file system API with currently generates invalid file descriptors with negative values when inside a `.zip` file. This prevents esbuild from working correctly because Go's file system internals don't expect syscalls that succeed without an error to return an invalid file descriptor. Yarn is working on fixing their use of invalid file descriptors.\n\n## 0.15.1\n\n* Update esbuild's Yarn Plug'n'Play implementation to match the latest specification changes ([#2452](https://github.com/evanw/esbuild/issues/2452), [#2453](https://github.com/evanw/esbuild/pull/2453))\n\n    This release updates esbuild's implementation of Yarn Plug'n'Play to match some changes to Yarn's specification that just landed. The changes are as follows:\n\n    * Check for platform-specific absolute paths instead of always for the `/` prefix\n\n        The specification previously said that Yarn Plug'n'Play path resolution rules should not apply for paths that start with `/`. The intent was to avoid accidentally processing absolute paths. However, absolute paths on Windows such as `C:\\project` start with drive letters instead of with `/`. So the specification was changed to instead explicitly avoid processing absolute paths.\n\n    * Make `$$virtual` an alias for `__virtual__`\n\n        Supporting Yarn-style path resolution requires implementing a custom Yarn-specific path traversal scheme where certain path segments are considered no-ops. Specifically any path containing segments of the form `__virtual__/<whatever>/<n>` where `<n>` is an integer must be treated as if they were `n` times the `..` operator instead (the `<whatever>` path segment is ignored). So `/path/to/project/__virtual__/xyz/2/foo.js` maps to the underlying file `/path/to/project/../../foo.js`. This scheme makes it possible for Yarn to get node (and esbuild) to load the same file multiple times (which is sometimes required for correctness) without actually duplicating the file on the file system.\n\n        However, old versions of Yarn used to use `$$virtual` instead of `__virtual__`. This was changed because `$$virtual` was error-prone due to the use of the `$` character, which can cause bugs when it's not correctly escaped within regular expressions. Now that esbuild makes `$$virtual` an alias for `__virtual__`, esbuild should now work with manifests from these old Yarn versions.\n\n    * Ignore PnP manifests in virtual directories\n\n        The specification describes the algorithm for how to find the Plug'n'Play manifest when starting from a certain point in the file system: search through all parent directories in reverse order until the manifest is found. However, this interacts poorly with virtual paths since it can end up finding a virtual copy of the manifest instead of the original. To avoid this, esbuild now ignores manifests in virtual directories so that the search for the manifest will continue and find the original manifest in another parent directory later on.\n\n    These fixes mean that esbuild's implementation of Plug'n'Play now matches Yarn's implementation more closely, and esbuild can now correctly build more projects that use Plug'n'Play.\n\n## 0.15.0\n\n**This release contains backwards-incompatible changes.** Since esbuild is before version 1.0.0, these changes have been released as a new minor version to reflect this (as [recommended by npm](https://docs.npmjs.com/cli/v6/using-npm/semver/)). You should either be pinning the exact version of `esbuild` in your `package.json` file or be using a version range syntax that only accepts patch upgrades such as `~0.14.0`. See the documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\n* Implement the Yarn Plug'n'Play module resolution algorithm ([#154](https://github.com/evanw/esbuild/issues/154), [#237](https://github.com/evanw/esbuild/issues/237), [#1263](https://github.com/evanw/esbuild/issues/1263), [#2451](https://github.com/evanw/esbuild/pull/2451))\n\n    [Node](https://nodejs.org/) comes with a package manager called [npm](https://www.npmjs.com/), which installs packages into a `node_modules` folder. Node and esbuild both come with built-in rules for resolving import paths to packages within `node_modules`, so packages installed via npm work automatically without any configuration. However, many people use an alternative package manager called [Yarn](https://yarnpkg.com/). While Yarn can install packages using `node_modules`, it also offers a different package installation strategy called [Plug'n'Play](https://yarnpkg.com/features/pnp/), which is often shortened to \"PnP\" (not to be confused with [pnpm](https://pnpm.io/), which is an entirely different unrelated package manager).\n\n    Plug'n'Play installs packages as `.zip` files on your file system. The packages are never actually unzipped. Since Node doesn't know anything about Yarn's package installation strategy, this means you can no longer run your code with Node as it won't be able to find your packages. Instead, you need to run your code with Yarn, which applies patches to Node's file system APIs before running your code. These patches attempt to make zip files seem like normal directories. When running under Yarn, using Node's file system API to read `./some.zip/lib/file.js` actually automatically extracts `lib/file.js` from `./some.zip` at run-time as if it was a normal file. Other file system APIs behave similarly. However, these patches don't work with esbuild because esbuild is not written in JavaScript; it's a native binary executable that interacts with the file system directly through the operating system.\n\n    Previously the workaround for using esbuild with Plug'n'Play was to use the [`@yarnpkg/esbuild-plugin-pnp`](https://www.npmjs.com/package/@yarnpkg/esbuild-plugin-pnp) plugin with esbuild's JavaScript API. However, this wasn't great because the plugin needed to potentially intercept every single import path and file load to check whether it was a Plug'n'Play package, which has an unusually high performance cost. It also meant that certain subtleties of path resolution rules within a `.zip` file could differ slightly from the way esbuild normally works since path resolution inside `.zip` files was implemented by Yarn, not by esbuild (which is due to a limitation of esbuild's plugin API).\n\n    With this release, esbuild now contains an independent implementation of Yarn's Plug'n'Play algorithm (which is used when esbuild finds a `.pnp.js`, `.pnp.cjs`, or `.pnp.data.json` file in the directory tree). Creating additional implementations of this algorithm recently became possible because Yarn's package manifest format was recently documented: https://yarnpkg.com/advanced/pnp-spec/. This should mean that you can now use esbuild to bundle Plug'n'Play projects without any additional configuration (so you shouldn't need `@yarnpkg/esbuild-plugin-pnp` anymore). Bundling these projects should now happen much faster as Yarn no longer even needs to be run at all. Bundling the Yarn codebase itself with esbuild before and after this change seems to demonstrate over a 10x speedup (3.4s to 0.24s). And path resolution rules within Yarn packages should now be consistent with how esbuild handles regular Node packages. For example, fields such as `module` and `browser` in `package.json` files within `.zip` files should now be respected.\n\n    Keep in mind that this is brand new code and there may be some initial issues to work through before esbuild's implementation is solid. Yarn's Plug'n'Play specification is also brand new and may need some follow-up edits to guide new implementations to match Yarn's exact behavior. If you try this out, make sure to test it before committing to using it, and let me know if anything isn't working as expected. Should you need to debug esbuild's path resolution, you may find `--log-level=verbose` helpful.\n\n## 0.14.54\n\n* Fix optimizations for calls containing spread arguments ([#2445](https://github.com/evanw/esbuild/issues/2445))\n\n    This release fixes the handling of spread arguments in the optimization of `/* @__PURE__ */` comments, empty functions, and identity functions:\n\n    ```js\n    // Original code\n    function empty() {}\n    function identity(x) { return x }\n    /* @__PURE__ */ a(...x)\n    /* @__PURE__ */ new b(...x)\n    empty(...x)\n    identity(...x)\n\n    // Old output (with --minify --tree-shaking=true)\n    ...x;...x;...x;...x;\n\n    // New output (with --minify --tree-shaking=true)\n    function identity(n){return n}[...x];[...x];[...x];identity(...x);\n    ```\n\n    Previously esbuild assumed arguments with side effects could be directly inlined. This is almost always true except for spread arguments, which are not syntactically valid on their own and which have the side effect of causing iteration, which might have further side effects. Now esbuild will wrap these elements in an unused array so that they are syntactically valid and so that the iteration side effects are preserved.\n\n## 0.14.53\n\nThis release fixes a minor issue with the previous release: I had to rename the package `esbuild-linux-loong64` to `@esbuild/linux-loong64` in the contributed PR because someone registered the package name before I could claim it, and I missed a spot. Hopefully everything is working after this release. I plan to change all platform-specific package names to use the `@esbuild/` scope at some point to avoid this problem in the future.\n\n## 0.14.52\n\n* Allow binary data as input to the JS `transform` and `build` APIs ([#2424](https://github.com/evanw/esbuild/issues/2424))\n\n    Previously esbuild's `transform` and `build` APIs could only take a string. However, some people want to use esbuild to convert binary data to base64 text. This is problematic because JavaScript strings represent UTF-16 text and esbuild internally operates on arrays of bytes, so all strings coming from JavaScript undergo UTF-16 to UTF-8 conversion before use. This meant that using esbuild in this way was doing base64 encoding of the UTF-8 encoding of the text, which was undesired.\n\n    With this release, esbuild now accepts `Uint8Array` in addition to string as an input format for the `transform` and `build` APIs. Now you can use esbuild to convert binary data to base64 text:\n\n    ```js\n    // Original code\n    import esbuild from 'esbuild'\n    console.log([\n      (await esbuild.transform('\\xFF', { loader: 'base64' })).code,\n      (await esbuild.build({ stdin: { contents: '\\xFF', loader: 'base64' }, write: false })).outputFiles[0].text,\n    ])\n    console.log([\n      (await esbuild.transform(new Uint8Array([0xFF]), { loader: 'base64' })).code,\n      (await esbuild.build({ stdin: { contents: new Uint8Array([0xFF]), loader: 'base64' }, write: false })).outputFiles[0].text,\n    ])\n\n    // Old output\n    [ 'module.exports = \"w78=\";\\n', 'module.exports = \"w78=\";\\n' ]\n    /* ERROR: The input to \"transform\" must be a string */\n\n    // New output\n    [ 'module.exports = \"w78=\";\\n', 'module.exports = \"w78=\";\\n' ]\n    [ 'module.exports = \"/w==\";\\n', 'module.exports = \"/w==\";\\n' ]\n    ```\n\n* Update the getter for `text` in build results ([#2423](https://github.com/evanw/esbuild/issues/2423))\n\n    Output files in build results returned from esbuild's JavaScript API have both a `contents` and a `text` property to return the contents of the output file. The `contents` property is a binary UTF-8 Uint8Array and the `text` property is a JavaScript UTF-16 string. The `text` property is a getter that does the UTF-8 to UTF-16 conversion only if it's needed for better performance.\n\n    Previously if you mutate the build results object, you had to overwrite both `contents` and `text` since the value returned from the `text` getter is the original text returned by esbuild. Some people find this confusing so with this release, the getter for `text` has been updated to do the UTF-8 to UTF-16 conversion on the current value of the `contents` property instead of the original value.\n\n* Publish builds for Linux LoongArch 64-bit ([#1804](https://github.com/evanw/esbuild/issues/1804), [#2373](https://github.com/evanw/esbuild/pull/2373))\n\n    This release upgrades to [Go 1.19](https://go.dev/doc/go1.19), which now includes support for LoongArch 64-bit processors. LoongArch 64-bit builds of esbuild will now be published to npm, which means that in theory they can now be installed with `npm install esbuild`. This was contributed by [@beyond-1234](https://github.com/beyond-1234).\n\n## 0.14.51\n\n* Add support for React 17's `automatic` JSX transform ([#334](https://github.com/evanw/esbuild/issues/334), [#718](https://github.com/evanw/esbuild/issues/718), [#1172](https://github.com/evanw/esbuild/issues/1172), [#2318](https://github.com/evanw/esbuild/issues/2318), [#2349](https://github.com/evanw/esbuild/pull/2349))\n\n    This adds support for the [new \"automatic\" JSX runtime from React 17+](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) to esbuild for both the build and transform APIs.\n\n    **New CLI flags and API options:**\n    - `--jsx`, `jsx` &mdash; Set this to `\"automatic\"` to opt in to this new transform\n    - `--jsx-dev`, `jsxDev` &mdash; Toggles development mode for the automatic runtime\n    - `--jsx-import-source`, `jsxImportSource` &mdash; Overrides the root import for runtime functions (default `\"react\"`)\n\n    **New JSX pragma comments:**\n    - `@jsxRuntime` &mdash; Sets the runtime (`automatic` or `classic`)\n    - `@jsxImportSource` &mdash; Sets the import source (only valid with automatic runtime)\n\n    The existing `@jsxFragment` and `@jsxFactory` pragma comments are only valid with \"classic\" runtime.\n\n    **TSConfig resolving:**\n    Along with accepting the new options directly via CLI or API, option inference from `tsconfig.json` compiler options was also implemented:\n\n    - `\"jsx\": \"preserve\"` or `\"jsx\": \"react-native\"` &rarr; Same as `--jsx=preserve` in esbuild\n    - `\"jsx\": \"react\"` &rarr; Same as `--jsx=transform` in esbuild (which is the default behavior)\n    - `\"jsx\": \"react-jsx\"` &rarr; Same as `--jsx=automatic` in esbuild\n    - `\"jsx\": \"react-jsxdev\"` &rarr; Same as `--jsx=automatic --jsx-dev` in esbuild\n\n    It also reads the value of `\"jsxImportSource\"` from `tsconfig.json` if specified.\n\n    For `react-jsx` it's important to note that it doesn't implicitly disable `--jsx-dev`. This is to support the case where a user sets `\"react-jsx\"` in their `tsconfig.json` but then toggles development mode directly in esbuild.\n\n    **esbuild vs Babel vs TS vs...**\n\n    There are a few differences between the various technologies that implement automatic JSX runtimes. The JSX transform in esbuild follows a mix of Babel's and TypeScript's behavior:\n\n    - When an element has `__source` or `__self` props:\n        - Babel: Print an error about a deprecated transform plugin\n        - TypeScript: Allow the props\n        - swc: Hard crash\n        - **esbuild**: Print an error &mdash; Following Babel was chosen for this one because this might help people catch configuration issues where JSX files are being parsed by multiple tools\n\n    - Element has an \"implicit true\" key prop, e.g. `<a key />`:\n        - Babel: Print an error indicating that \"key\" props require an explicit value\n        - TypeScript: Silently omit the \"key\" prop\n        - swc: Hard crash\n        - **esbuild**: Print an error like Babel &mdash; This might help catch legitimate programming mistakes\n\n    - Element has spread children, e.g. `<a>{...children}</a>`\n        - Babel: Print an error stating that React doesn't support spread children\n        - TypeScript: Use static jsx function and pass children as-is, including spread operator\n        - swc: same as Babel\n        - **esbuild**: Same as TypeScript\n\n    Also note that TypeScript has some bugs regarding JSX development mode and the generation of `lineNumber` and `columnNumber` values. Babel's values are accurate though, so esbuild's line and column numbers match Babel. Both numbers are 1-based and columns are counted in terms of UTF-16 code units.\n\n    This feature was contributed by [@jgoz](https://github.com/jgoz).\n\n## 0.14.50\n\n* Emit `names` in source maps ([#1296](https://github.com/evanw/esbuild/issues/1296))\n\n    The [source map specification](https://sourcemaps.info/spec.html) includes an optional `names` field that can associate an identifier with a mapping entry. This can be used to record the original name for an identifier, which is useful if the identifier was renamed to something else in the generated code. When esbuild was originally written, this field wasn't widely used, but now there are some debuggers that make use of it to provide better debugging of minified code. With this release, esbuild now includes a `names` field in the source maps that it generates. To save space, the original name is only recorded when it's different from the final name.\n\n* Update parser for arrow functions with initial default type parameters in `.tsx` files ([#2410](https://github.com/evanw/esbuild/issues/2410))\n\n    TypeScript 4.6 introduced a [change to the parsing of JSX syntax in `.tsx` files](https://github.com/microsoft/TypeScript/issues/47062). Now a `<` token followed by an identifier and then a `=` token is parsed as an arrow function with a default type parameter instead of as a JSX element. This release updates esbuild's parser to match TypeScript's parser.\n\n* Fix an accidental infinite loop with `--define` substitution ([#2407](https://github.com/evanw/esbuild/issues/2407))\n\n    This is a fix for a regression that was introduced in esbuild version 0.14.44 where certain `--define` substitutions could result in esbuild crashing with a stack overflow. The problem was an incorrect fix for #2292. The fix merged the code paths for `--define` and `--jsx-factory` rewriting since the value substitution is now the same for both. However, doing this accidentally made `--define` substitution recursive since the JSX factory needs to be able to match against `--define` substitutions to integrate with the `--inject` feature. The fix is to only do one additional level of matching against define substitutions, and to only do this for JSX factories. Now these cases are able to build successfully without a stack overflow.\n\n* Include the \"public path\" value in hashes ([#2403](https://github.com/evanw/esbuild/issues/2403))\n\n    The `--public-path=` configuration value affects the paths that esbuild uses to reference files from other files and is used in various situations such as cross-chunk imports in JS and references to asset files from CSS files. However, it wasn't included in the hash calculations used for file names due to an oversight. This meant that changing the public path setting incorrectly didn't result in the hashes in file names changing even though the contents of the files changed. This release fixes the issue by including a hash of the public path in all non-asset output files.\n\n* Fix a cross-platform consistency bug ([#2383](https://github.com/evanw/esbuild/issues/2383))\n\n    Previously esbuild would minify `0xFFFF_FFFF_FFFF_FFFF` as `0xffffffffffffffff` (18 bytes) on arm64 chips and as `18446744073709552e3` (19 bytes) on x86_64 chips. The reason was that the number was converted to a 64-bit unsigned integer internally for printing as hexadecimal, the 64-bit floating-point number `0xFFFF_FFFF_FFFF_FFFF` is actually `0x1_0000_0000_0000_0180` (i.e. it's rounded up, not down), and converting `float64` to `uint64` is implementation-dependent in Go when the input is out of bounds. This was fixed by changing the upper limit for which esbuild uses hexadecimal numbers during minification to `0xFFFF_FFFF_FFFF_F800`, which is the next representable 64-bit floating-point number below `0x1_0000_0000_0000_0180`, and which fits in a `uint64`. As a result, esbuild will now consistently never minify `0xFFFF_FFFF_FFFF_FFFF` as `0xffffffffffffffff` anymore, which means the output should now be consistent across platforms.\n\n* Fix a hang with the synchronous API when the package is corrupted ([#2396](https://github.com/evanw/esbuild/issues/2396))\n\n    An error message is already thrown when the esbuild package is corrupted and esbuild can't be run. However, if you are using a synchronous call in the JavaScript API in worker mode, esbuild will use a child worker to initialize esbuild once so that the overhead of initializing esbuild can be amortized across multiple synchronous API calls. However, errors thrown during initialization weren't being propagated correctly which resulted in a hang while the main thread waited forever for the child worker to finish initializing. With this release, initialization errors are now propagated correctly so calling a synchronous API call when the package is corrupted should now result in an error instead of a hang.\n\n* Fix `tsconfig.json` files that collide with directory names ([#2411](https://github.com/evanw/esbuild/issues/2411))\n\n    TypeScript lets you write `tsconfig.json` files with `extends` clauses that refer to another config file using an implicit `.json` file extension. However, if the config file without the `.json` extension existed as a directory name, esbuild and TypeScript had different behavior. TypeScript ignores the directory and continues looking for the config file by adding the `.json` extension while esbuild previously terminated the search and then failed to load the config file (because it's a directory). With this release, esbuild will now ignore exact matches when resolving `extends` fields in `tsconfig.json` files if the exact match results in a directory.\n\n* Add `platform` to the transform API ([#2362](https://github.com/evanw/esbuild/issues/2362))\n\n    The `platform` option is mainly relevant for bundling because it mostly affects path resolution (e.g. activating the `\"browser\"` field in `package.json` files), so it was previously only available for the build API. With this release, it has additionally be made available for the transform API for a single reason: you can now set `--platform=node` when transforming a string so that esbuild will add export annotations for node, which is only relevant when `--format=cjs` is also present.\n\n    This has to do with an implementation detail of node that parses the AST of CommonJS files to discover named exports when importing CommonJS from ESM. However, this new addition to esbuild's API is of questionable usefulness. Node's loader API (the main use case for using esbuild's transform API like this) actually bypasses the content returned from the loader and parses the AST that's present on the file system, so you won't actually be able to use esbuild's API for this. See the linked issue for more information.\n\n## 0.14.49\n\n* Keep inlined constants when direct `eval` is present ([#2361](https://github.com/evanw/esbuild/issues/2361))\n\n    Version 0.14.19 of esbuild added inlining of certain `const` variables during minification, which replaces all references to the variable with the initializer and then removes the variable declaration. However, this could generate incorrect code when direct `eval` is present because the direct `eval` could reference the constant by name. This release fixes the problem by preserving the `const` variable declaration in this case:\n\n    ```js\n    // Original code\n    console.log((() => { const x = 123; return x + eval('x') }))\n\n    // Old output (with --minify)\n    console.log(()=>123+eval(\"x\"));\n\n    // New output (with --minify)\n    console.log(()=>{const x=123;return 123+eval(\"x\")});\n    ```\n\n* Fix an incorrect error in TypeScript when targeting ES5 ([#2375](https://github.com/evanw/esbuild/issues/2375))\n\n    Previously when compiling TypeScript code to ES5, esbuild could incorrectly consider the following syntax forms as a transformation error:\n\n    ```ts\n    0 ? ([]) : 1 ? ({}) : 2;\n    ```\n\n    The error messages looked like this:\n\n    ```\n    ✘ [ERROR] Transforming destructuring to the configured target environment (\"es5\") is not supported yet\n\n        example.ts:1:5:\n          1 │ 0 ? ([]) : 1 ? ({}) : 2;\n            ╵      ^\n\n    ✘ [ERROR] Transforming destructuring to the configured target environment (\"es5\") is not supported yet\n\n        example.ts:1:16:\n          1 │ 0 ? ([]) : 1 ? ({}) : 2;\n            ╵                 ^\n    ```\n\n    These parenthesized literals followed by a colon look like the start of an arrow function expression followed by a TypeScript return type (e.g. `([]) : 1` could be the start of the TypeScript arrow function `([]): 1 => 1`). Unlike in JavaScript, parsing arrow functions in TypeScript requires backtracking. In this case esbuild correctly determined that this expression wasn't an arrow function after all but the check for destructuring was incorrectly not covered under the backtracking process. With this release, the error message is now only reported if the parser successfully parses an arrow function without backtracking.\n\n* Fix generated TypeScript `enum` comments containing `*/` ([#2369](https://github.com/evanw/esbuild/issues/2369), [#2371](https://github.com/evanw/esbuild/pull/2371))\n\n    TypeScript `enum` values that are equal to a number or string literal are inlined (references to the enum are replaced with the literal value) and have a `/* ... */` comment after them with the original enum name to improve readability. However, this comment is omitted if the enum name contains the character sequence `*/` because that would end the comment early and cause a syntax error:\n\n    ```ts\n    // Original TypeScript\n    enum Foo { '/*' = 1, '*/' = 2 }\n    console.log(Foo['/*'], Foo['*/'])\n\n    // Generated JavaScript\n    console.log(1 /* /* */, 2);\n    ```\n\n    This was originally handled correctly when TypeScript `enum` inlining was initially implemented since it was only supported within a single file. However, when esbuild was later extended to support TypeScript `enum` inlining across files, this special case where the enum name contains `*/` was not handled in that new code. Starting with this release, esbuild will now handle enums with names containing `*/` correctly when they are inlined across files:\n\n    ```ts\n    // foo.ts\n    export enum Foo { '/*' = 1, '*/' = 2 }\n\n    // bar.ts\n    import { Foo } from './foo'\n    console.log(Foo['/*'], Foo['*/'])\n\n    // Old output (with --bundle --format=esm)\n    console.log(1 /* /* */, 2 /* */ */);\n\n    // New output (with --bundle --format=esm)\n    console.log(1 /* /* */, 2);\n    ```\n\n    This fix was contributed by [@magic-akari](https://github.com/magic-akari).\n\n* Allow `declare` class fields to be initialized ([#2380](https://github.com/evanw/esbuild/issues/2380))\n\n    This release fixes an oversight in the TypeScript parser that disallowed initializers for `declare` class fields. TypeScript actually allows the following limited initializer expressions for `readonly` fields:\n\n    ```ts\n    declare const enum a { b = 0 }\n\n    class Foo {\n      // These are allowed by TypeScript\n      declare readonly a = 0\n      declare readonly b = -0\n      declare readonly c = 0n\n      declare readonly d = -0n\n      declare readonly e = 'x'\n      declare readonly f = `x`\n      declare readonly g = a.b\n      declare readonly h = a['b']\n\n      // These are not allowed by TypeScript\n      declare readonly x = (0)\n      declare readonly y = null\n      declare readonly z = -a.b\n    }\n    ```\n\n    So with this release, esbuild now allows initializers for `declare` class fields too. To future-proof this in case TypeScript allows more expressions as initializers in the future (such as `null`), esbuild will allow any expression as an initializer and will leave the specifics of TypeScript's special-casing here to the TypeScript type checker.\n\n* Fix a bug in esbuild's feature compatibility table generator ([#2365](https://github.com/evanw/esbuild/issues/2365))\n\n    Passing specific JavaScript engines to esbuild's `--target` flag restricts esbuild to only using JavaScript features that are supported on those engines in the output files that esbuild generates. The data for this feature is automatically derived from this compatibility table with a script: https://kangax.github.io/compat-table/.\n\n    However, the script had a bug that could incorrectly consider a JavaScript syntax feature to be supported in a given engine even when it doesn't actually work in that engine. Specifically this bug happened when a certain aspect of JavaScript syntax has always worked incorrectly in that engine and the bug in that engine has never been fixed. This situation hasn't really come up before because previously esbuild pretty much only targeted JavaScript engines that always fix their bugs, but the two new JavaScript engines that were added in the previous release ([Hermes](https://hermesengine.dev/) and [Rhino](https://github.com/mozilla/rhino)) have many aspects of the JavaScript specification that have never been implemented, and may never be implemented. For example, the `let` and `const` keywords are not implemented correctly in those engines.\n\n    With this release, esbuild's compatibility table generator script has been fixed and as a result, esbuild will now correctly consider a JavaScript syntax feature to be unsupported in a given engine if there is some aspect of that syntax that is broken in all known versions of that engine. This means that the following JavaScript syntax features are no longer considered to be supported by these engines (represented using esbuild's internal names for these syntax features):\n\n    Hermes:\n    - `arrow`\n    - `const-and-let`\n    - `default-argument`\n    - `generator`\n    - `optional-catch-binding`\n    - `optional-chain`\n    - `rest-argument`\n    - `template-literal`\n\n    Rhino:\n    - `arrow`\n    - `const-and-let`\n    - `destructuring`\n    - `for-of`\n    - `generator`\n    - `object-extensions`\n    - `template-literal`\n\n    IE:\n    - `const-and-let`\n\n## 0.14.48\n\n* Enable using esbuild in Deno via WebAssembly ([#2323](https://github.com/evanw/esbuild/issues/2323))\n\n    The native implementation of esbuild is much faster than the WebAssembly version, but some people don't want to give Deno the `--allow-run` permission necessary to run esbuild and are ok waiting longer for their builds to finish when using the WebAssembly backend. With this release, you can now use esbuild via WebAssembly in Deno. To do this you will need to import from `wasm.js` instead of `mod.js`:\n\n    ```js\n    import * as esbuild from 'https://deno.land/x/esbuild@v0.14.48/wasm.js'\n    const ts = 'let test: boolean = true'\n    const result = await esbuild.transform(ts, { loader: 'ts' })\n    console.log('result:', result)\n    ```\n\n    Make sure you run Deno with `--allow-net` so esbuild can download the WebAssembly module. Using esbuild like this starts up a worker thread that runs esbuild in parallel (unless you call `esbuild.initialize({ worker: false })` to tell esbuild to run on the main thread). If you want to, you can call `esbuild.stop()` to terminate the worker if you won't be using esbuild anymore and you want to reclaim the memory.\n\n    Note that Deno appears to have a bug where background WebAssembly optimization can prevent the process from exiting for many seconds. If you are trying to use Deno and WebAssembly to run esbuild quickly, you may need to manually call `Deno.exit(0)` after your code has finished running.\n\n* Add support for font file MIME types ([#2337](https://github.com/evanw/esbuild/issues/2337))\n\n    This release adds support for font file MIME types to esbuild, which means they are now recognized by the built-in local web server and they are now used when a font file is loaded using the `dataurl` loader. The full set of newly-added file extension MIME type mappings is as follows:\n\n    * `.eot` => `application/vnd.ms-fontobject`\n    * `.otf` => `font/otf`\n    * `.sfnt` => `font/sfnt`\n    * `.ttf` => `font/ttf`\n    * `.woff` => `font/woff`\n    * `.woff2` => `font/woff2`\n\n* Remove `\"use strict\";` when targeting ESM ([#2347](https://github.com/evanw/esbuild/issues/2347))\n\n    All ES module code is automatically in strict mode, so a `\"use strict\";` directive is unnecessary. With this release, esbuild will now remove the `\"use strict\";` directive if the output format is ESM. This change makes the generated output file a few bytes smaller:\n\n    ```js\n    // Original code\n    'use strict'\n    export let foo = 123\n\n    // Old output (with --format=esm --minify)\n    \"use strict\";let t=123;export{t as foo};\n\n    // New output (with --format=esm --minify)\n    let t=123;export{t as foo};\n    ```\n\n* Attempt to have esbuild work with Deno on FreeBSD ([#2356](https://github.com/evanw/esbuild/issues/2356))\n\n    Deno doesn't support FreeBSD, but it's possible to build Deno for FreeBSD with some additional patches on top. This release of esbuild changes esbuild's Deno installer to download esbuild's FreeBSD binary in this situation. This configuration is unsupported although in theory everything should work.\n\n* Add some more target JavaScript engines ([#2357](https://github.com/evanw/esbuild/issues/2357))\n\n    This release adds the [Rhino](https://github.com/mozilla/rhino) and [Hermes](https://hermesengine.dev/) JavaScript engines to the set of engine identifiers that can be passed to the `--target` flag. You can use this to restrict esbuild to only using JavaScript features that are supported on those engines in the output files that esbuild generates.\n\n## 0.14.47\n\n* Make global names more compact when `||=` is available ([#2331](https://github.com/evanw/esbuild/issues/2331))\n\n    With this release, the code esbuild generates for the `--global-name=` setting is now slightly shorter when you don't configure esbuild such that the `||=` operator is unsupported (e.g. with `--target=chrome80` or `--supported:logical-assignment=false`):\n\n    ```js\n    // Original code\n    exports.foo = 123\n\n    // Old output (with --format=iife --global-name=foo.bar.baz --minify)\n    var foo=foo||{};foo.bar=foo.bar||{};foo.bar.baz=(()=>{var b=(a,o)=>()=>(o||a((o={exports:{}}).exports,o),o.exports);var c=b(f=>{f.foo=123});return c();})();\n\n    // New output (with --format=iife --global-name=foo.bar.baz --minify)\n    var foo;((foo||={}).bar||={}).baz=(()=>{var b=(a,o)=>()=>(o||a((o={exports:{}}).exports,o),o.exports);var c=b(f=>{f.foo=123});return c();})();\n    ```\n\n* Fix `--mangle-quoted=false` with `--minify-syntax=true`\n\n    If property mangling is active and `--mangle-quoted` is disabled, quoted properties are supposed to be preserved. However, there was a case when this didn't happen if `--minify-syntax` was enabled, since that internally transforms `x['y']` into `x.y` to reduce code size. This issue has been fixed:\n\n    ```js\n    // Original code\n    x.foo = x['bar'] = { foo: y, 'bar': z }\n\n    // Old output (with --mangle-props=. --mangle-quoted=false --minify-syntax=true)\n    x.a = x.b = { a: y, bar: z };\n\n    // New output (with --mangle-props=. --mangle-quoted=false --minify-syntax=true)\n    x.a = x.bar = { a: y, bar: z };\n    ```\n\n    Notice how the property `foo` is always used unquoted but the property `bar` is always used quoted, so `foo` should be consistently mangled while `bar` should be consistently not mangled.\n\n* Fix a minification bug regarding `this` and property initializers\n\n    When minification is enabled, esbuild attempts to inline the initializers of variables that have only been used once into the start of the following expression to reduce code size. However, there was a bug where this transformation could change the value of `this` when the initializer is a property access and the start of the following expression is a call expression. This release fixes the bug:\n\n    ```js\n    // Original code\n    function foo(obj) {\n      let fn = obj.prop;\n      fn();\n    }\n\n    // Old output (with --minify)\n    function foo(f){f.prop()}\n\n    // New output (with --minify)\n    function foo(o){let f=o.prop;f()}\n    ```\n\n## 0.14.46\n\n* Add the ability to override support for individual syntax features ([#2060](https://github.com/evanw/esbuild/issues/2060), [#2290](https://github.com/evanw/esbuild/issues/2290), [#2308](https://github.com/evanw/esbuild/issues/2308))\n\n    The `target` setting already lets you configure esbuild to restrict its output by only making use of syntax features that are known to be supported in the configured target environment. For example, setting `target` to `chrome50` causes esbuild to automatically transform optional chain expressions into the equivalent older JavaScript and prevents you from using BigInts, among many other things. However, sometimes you may want to customize this set of unsupported syntax features at the individual feature level.\n\n    Some examples of why you might want to do this:\n\n    * JavaScript runtimes often do a quick implementation of newer syntax features that is slower than the equivalent older JavaScript, and you can get a speedup by telling esbuild to pretend this syntax feature isn't supported. For example, V8 has a [long-standing performance bug regarding object spread](https://bugs.chromium.org/p/v8/issues/detail?id=11536) that can be avoided by manually copying properties instead of using object spread syntax. Right now esbuild hard-codes this optimization if you set `target` to a V8-based runtime.\n\n    * There are many less-used JavaScript runtimes in addition to the ones present in browsers, and these runtimes sometimes just decide not to implement parts of the specification, which might make sense for runtimes intended for embedded environments. For example, the developers behind Facebook's JavaScript runtime [Hermes](https://hermesengine.dev/) have decided to not implement classes despite it being a major JavaScript feature that was added seven years ago and that is used in virtually every large JavaScript project.\n\n    * You may be processing esbuild's output with another tool, and you may want esbuild to transform certain features and the other tool to transform certain other features. For example, if you are using esbuild to transform files individually to ES5 but you are then feeding the output into Webpack for bundling, you may want to preserve `import()` expressions even though they are a syntax error in ES5.\n\n    With this release, you can now use `--supported:feature=false` to force `feature` to be unsupported. This will cause esbuild to either rewrite code that uses the feature into older code that doesn't use the feature (if esbuild is able to), or to emit a build error (if esbuild is unable to). For example, you can use `--supported:arrow=false` to turn arrow functions into function expressions and `--supported:bigint=false` to make it an error to use a BigInt literal. You can also use `--supported:feature=true` to force it to be supported, which means esbuild will pass it through without transforming it. Keep in mind that this is an advanced feature. For most use cases you will probably want to just use `target` instead of using this.\n\n    The full set of currently-allowed features are as follows:\n\n    **JavaScript:**\n    * `arbitrary-module-namespace-names`\n    * `array-spread`\n    * `arrow`\n    * `async-await`\n    * `async-generator`\n    * `bigint`\n    * `class`\n    * `class-field`\n    * `class-private-accessor`\n    * `class-private-brand-check`\n    * `class-private-field`\n    * `class-private-method`\n    * `class-private-static-accessor`\n    * `class-private-static-field`\n    * `class-private-static-method`\n    * `class-static-blocks`\n    * `class-static-field`\n    * `const-and-let`\n    * `default-argument`\n    * `destructuring`\n    * `dynamic-import`\n    * `exponent-operator`\n    * `export-star-as`\n    * `for-await`\n    * `for-of`\n    * `generator`\n    * `hashbang`\n    * `import-assertions`\n    * `import-meta`\n    * `logical-assignment`\n    * `nested-rest-binding`\n    * `new-target`\n    * `node-colon-prefix-import`\n    * `node-colon-prefix-require`\n    * `nullish-coalescing`\n    * `object-accessors`\n    * `object-extensions`\n    * `object-rest-spread`\n    * `optional-catch-binding`\n    * `optional-chain`\n    * `regexp-dot-all-flag`\n    * `regexp-lookbehind-assertions`\n    * `regexp-match-indices`\n    * `regexp-named-capture-groups`\n    * `regexp-sticky-and-unicode-flags`\n    * `regexp-unicode-property-escapes`\n    * `rest-argument`\n    * `template-literal`\n    * `top-level-await`\n    * `typeof-exotic-object-is-object`\n    * `unicode-escapes`\n\n    **CSS:**\n    * `hex-rgba`\n    * `rebecca-purple`\n    * `modern-rgb-hsl`\n    * `inset-property`\n    * `nesting`\n\n    Since you can now specify `--supported:object-rest-spread=false` yourself to work around the V8 performance issue mentioned above, esbuild will no longer automatically transform all instances of object spread when targeting a V8-based JavaScript runtime going forward.\n\n    _Note that JavaScript feature transformation is very complex and allowing full customization of the set of supported syntax features could cause bugs in esbuild due to new interactions between multiple features that were never possible before. Consider this to be an experimental feature._\n\n* Implement `extends` constraints on `infer` type variables ([#2330](https://github.com/evanw/esbuild/issues/2330))\n\n    TypeScript 4.7 introduced the ability to write an `extends` constraint after an `infer` type variable, which looks like this:\n\n    ```ts\n    type FirstIfString<T> =\n      T extends [infer S extends string, ...unknown[]]\n        ? S\n        : never;\n    ```\n\n    You can read the blog post for more details: https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#extends-constraints-on-infer-type-variables. Previously this was a syntax error in esbuild but with this release, esbuild can now parse this syntax correctly.\n\n* Allow `define` to match optional chain expressions ([#2324](https://github.com/evanw/esbuild/issues/2324))\n\n    Previously esbuild's `define` feature only matched member expressions that did not use optional chaining. With this release, esbuild will now also match those that use optional chaining:\n\n    ```js\n    // Original code\n    console.log(a.b, a?.b)\n\n    // Old output (with --define:a.b=c)\n    console.log(c, a?.b);\n\n    // New output (with --define:a.b=c)\n    console.log(c, c);\n    ```\n\n    This is for compatibility with Webpack's [`DefinePlugin`](https://webpack.js.org/plugins/define-plugin/), which behaves the same way.\n\n## 0.14.45\n\n* Add a log message for ambiguous re-exports ([#2322](https://github.com/evanw/esbuild/issues/2322))\n\n    In JavaScript, you can re-export symbols from another file using `export * from './another-file'`. When you do this from multiple files that export different symbols with the same name, this creates an ambiguous export which is causes that name to not be exported. This is harmless if you don't plan on using the ambiguous export name, so esbuild doesn't have a warning for this. But if you do want a warning for this (or if you want to make it an error), you can now opt-in to seeing this log message with `--log-override:ambiguous-reexport=warning` or `--log-override:ambiguous-reexport=error`. The log message looks like this:\n\n    ```\n    ▲ [WARNING] Re-export of \"common\" in \"example.js\" is ambiguous and has been removed [ambiguous-reexport]\n\n      One definition of \"common\" comes from \"a.js\" here:\n\n        a.js:2:11:\n          2 │ export let common = 2\n            ╵            ~~~~~~\n\n      Another definition of \"common\" comes from \"b.js\" here:\n\n        b.js:3:14:\n          3 │ export { b as common }\n            ╵               ~~~~~~\n    ```\n\n* Optimize the output of the JSON loader ([#2161](https://github.com/evanw/esbuild/issues/2161))\n\n    The `json` loader (which is enabled by default for `.json` files) parses the file as JSON and generates a JavaScript file with the parsed expression as the `default` export. This behavior is standard and works in both node and the browser (well, as long as you use an [import assertion](https://v8.dev/features/import-assertions)). As an extension, esbuild also allows you to import additional top-level properties of the JSON object directly as a named export. This is beneficial for tree shaking. For example:\n\n    ```js\n    import { version } from 'esbuild/package.json'\n    console.log(version)\n    ```\n\n    If you bundle the above code with esbuild, you'll get something like the following:\n\n    ```js\n    // node_modules/esbuild/package.json\n    var version = \"0.14.44\";\n\n    // example.js\n    console.log(version);\n    ```\n\n    Most of the `package.json` file is irrelevant and has been omitted from the output due to tree shaking. The way esbuild implements this is to have the JavaScript file that's generated from the JSON look something like this with a separate exported variable for each property on the top-level object:\n\n    ```js\n    // node_modules/esbuild/package.json\n    export var name = \"esbuild\";\n    export var version = \"0.14.44\";\n    export var repository = \"https://github.com/evanw/esbuild\";\n    export var bin = {\n      esbuild: \"bin/esbuild\"\n    };\n    ...\n    export default {\n      name,\n      version,\n      repository,\n      bin,\n      ...\n    };\n    ```\n\n    However, this means that if you import the `default` export instead of a named export, you will get non-optimal output. The `default` export references all top-level properties, leading to many unnecessary variables in the output. With this release esbuild will now optimize this case to only generate additional variables for top-level object properties that are actually imported:\n\n    ```js\n    // Original code\n    import all, { bar } from 'data:application/json,{\"foo\":[1,2,3],\"bar\":[4,5,6]}'\n    console.log(all, bar)\n\n    // Old output (with --bundle --minify --format=esm)\n    var a=[1,2,3],l=[4,5,6],r={foo:a,bar:l};console.log(r,l);\n\n    // New output (with --bundle --minify --format=esm)\n    var l=[4,5,6],r={foo:[1,2,3],bar:l};console.log(r,l);\n    ```\n\n    Notice how there is no longer an unnecessary generated variable for `foo` since it's never imported. And if you only import the `default` export, esbuild will now reproduce the original JSON object in the output with all top-level properties compactly inline.\n\n* Add `id` to warnings returned from the API\n\n    With this release, warnings returned from esbuild's API now have an `id` property. This identifies which kind of log message it is, which can be used to more easily filter out certain warnings. For example, reassigning a `const` variable will generate a message with an `id` of `\"assign-to-constant\"`. This also gives you the identifier you need to apply a log override for that kind of message: https://esbuild.github.io/api/#log-override.\n\n## 0.14.44\n\n* Add a `copy` loader ([#2255](https://github.com/evanw/esbuild/issues/2255))\n\n    You can configure the \"loader\" for a specific file extension in esbuild, which is a way of telling esbuild how it should treat that file. For example, the `text` loader means the file is imported as a string while the `binary` loader means the file is imported as a `Uint8Array`. If you want the imported file to stay a separate file, the only option was previously the `file` loader (which is intended to be similar to Webpack's [`file-loader`](https://v4.webpack.js.org/loaders/file-loader/) package). This loader copies the file to the output directory and imports the path to that output file as a string. This is useful for a web application because you can refer to resources such as `.png` images by importing them for their URL. However, it's not helpful if you need the imported file to stay a separate file but to still behave the way it normally would when the code is run without bundling.\n\n    With this release, there is now a new loader called `copy` that copies the loaded file to the output directory and then rewrites the path of the import statement or `require()` call to point to the copied file instead of the original file. This will automatically add a content hash to the output name by default (which can be configured with the `--asset-names=` setting). You can use this by specifying `copy` for a specific file extension, such as with `--loader:.png=copy`.\n\n* Fix a regression in arrow function lowering ([#2302](https://github.com/evanw/esbuild/pull/2302))\n\n    This release fixes a regression with lowering arrow functions to function expressions in ES5. This feature was introduced in version 0.7.2 and regressed in version 0.14.30.\n\n    In JavaScript, regular `function` expressions treat `this` as an implicit argument that is determined by how the function is called, but arrow functions treat `this` as a variable that is captured in the closure from the surrounding lexical scope. This is emulated in esbuild by storing the value of `this` in a variable before changing the arrow function into a function expression.\n\n    However, the code that did this didn't treat `this` expressions as a usage of that generated variable. Version 0.14.30 began omitting unused generated variables, which caused the transformation of `this` to break. This regression happened due to missing test coverage. With this release, the problem has been fixed:\n\n    ```js\n    // Original code\n    function foo() {\n      return () => this\n    }\n\n    // Old output (with --target=es5)\n    function foo() {\n      return function() {\n        return _this;\n      };\n    }\n\n    // New output (with --target=es5)\n    function foo() {\n      var _this = this;\n      return function() {\n        return _this;\n      };\n    }\n    ```\n\n    This fix was contributed by [@nkeynes](https://github.com/nkeynes).\n\n* Allow entity names as define values ([#2292](https://github.com/evanw/esbuild/issues/2292))\n\n    The \"define\" feature allows you to replace certain expressions with certain other expressions at compile time. For example, you might want to replace the global identifier `IS_PRODUCTION` with the boolean value `true` when building for production. Previously the only expressions you could substitute in were either identifier expressions or anything that is valid JSON syntax. This limitation exists because supporting more complex expressions is more complex (for example, substituting in a `require()` call could potentially pull in additional files, which would need to be handled). With this release, you can now also now define something as a member expression chain of the form `foo.abc.xyz`.\n\n* Implement package self-references ([#2312](https://github.com/evanw/esbuild/issues/2312))\n\n    This release implements a rarely-used feature in node where a package can import itself by name instead of using relative imports. You can read more about this feature here: https://nodejs.org/api/packages.html#self-referencing-a-package-using-its-name. For example, assuming the `package.json` in a given package looks like this:\n\n    ```json\n    // package.json\n    {\n      \"name\": \"a-package\",\n      \"exports\": {\n        \".\": \"./main.mjs\",\n        \"./foo\": \"./foo.js\"\n      }\n    }\n    ```\n\n    Then any module in that package can reference an export in the package itself:\n\n    ```js\n    // ./a-module.mjs\n    import { something } from 'a-package'; // Imports \"something\" from ./main.mjs.\n    ```\n\n    Self-referencing is also available when using `require`, both in an ES module, and in a CommonJS one. For example, this code will also work:\n\n    ```js\n    // ./a-module.js\n    const { something } = require('a-package/foo'); // Loads from ./foo.js.\n    ```\n\n* Add a warning for assigning to an import ([#2319](https://github.com/evanw/esbuild/issues/2319))\n\n    Import bindings are immutable in JavaScript, and assigning to them will throw an error. So instead of doing this:\n\n    ```js\n    import { foo } from 'foo'\n    foo++\n    ```\n\n    You need to do something like this instead:\n\n    ```js\n    import { foo, setFoo } from 'foo'\n    setFoo(foo + 1)\n    ```\n\n    This is already an error if you try to bundle this code with esbuild. However, this was previously allowed silently when bundling is disabled, which can lead to confusion for people who don't know about this aspect of how JavaScript works. So with this release, there is now a warning when you do this:\n\n    ```\n    ▲ [WARNING] This assignment will throw because \"foo\" is an import [assign-to-import]\n\n        example.js:2:0:\n          2 │ foo++\n            ╵ ~~~\n\n      Imports are immutable in JavaScript. To modify the value of this import, you must export a setter\n      function in the imported file (e.g. \"setFoo\") and then import and call that function here instead.\n    ```\n\n    This new warning can be turned off with `--log-override:assign-to-import=silent` if you don't want to see it.\n\n* Implement `alwaysStrict` in `tsconfig.json` ([#2264](https://github.com/evanw/esbuild/issues/2264))\n\n    This release adds `alwaysStrict` to the set of TypeScript `tsconfig.json` configuration values that esbuild supports. When this is enabled, esbuild will forbid syntax that isn't allowed in strict mode and will automatically insert `\"use strict\";` at the top of generated output files. This matches the behavior of the TypeScript compiler: https://www.typescriptlang.org/tsconfig#alwaysStrict.\n\n## 0.14.43\n\n* Fix TypeScript parse error whe a generic function is the first type argument ([#2306](https://github.com/evanw/esbuild/issues/2306))\n\n    In TypeScript, the `<<` token may need to be split apart into two `<` tokens if it's present in a type argument context. This was already correctly handled for all type expressions and for identifier expressions such as in the following code:\n\n    ```ts\n    // These cases already worked in the previous release\n    let foo: Array<<T>() => T>;\n    bar<<T>() => T>;\n    ```\n\n    However, normal expressions of the following form were previously incorrectly treated as syntax errors:\n\n    ```ts\n    // These cases were broken but have now been fixed\n    foo.bar<<T>() => T>;\n    foo?.<<T>() => T>();\n    ```\n\n    With this release, these cases now parsed correctly.\n\n* Fix minification regression with pure IIFEs ([#2279](https://github.com/evanw/esbuild/issues/2279))\n\n    An Immediately Invoked Function Expression (IIFE) is a function call to an anonymous function, and is a way of introducing a new function-level scope in JavaScript since JavaScript lacks a way to do this otherwise. And a pure function call is a function call with the special `/* @__PURE__ */` comment before it, which tells JavaScript build tools that the function call can be considered to have no side effects (and can be removed if it's unused).\n\n    Version 0.14.9 of esbuild introduced a regression that changed esbuild's behavior when these two features were combined. If the IIFE body contains a single expression, the resulting output still contained that expression instead of being empty. This is a minor regression because you normally wouldn't write code like this, so this shouldn't come up in practice, and it doesn't cause any correctness issues (just larger-than-necessary output). It's unusual that you would tell esbuild \"remove this if the result is unused\" and then not store the result anywhere, since the result is unused by construction. But regardless, the issue has now been fixed.\n\n    For example, the following code is a pure IIFE, which means it should be completely removed when minification is enabled. Previously it was replaced by the contents of the IIFE but it's now completely removed:\n\n    ```js\n    // Original code\n    /* @__PURE__ */ (() => console.log(1))()\n\n    // Old output (with --minify)\n    console.log(1);\n\n    // New output (with --minify)\n    ```\n\n* Add log messages for indirect `require` references ([#2231](https://github.com/evanw/esbuild/issues/2231))\n\n    A long time ago esbuild used to warn about indirect uses of `require` because they break esbuild's ability to analyze the dependencies of the code and cause dependencies to not be bundled, resulting in a potentially broken bundle. However, this warning was removed because many people wanted the warning to be removed. Some packages have code that uses `require` like this but on a code path that isn't used at run-time, so their code still happens to work even though the bundle is incomplete. For example, the following code will _not_ bundle `bindings`:\n\n    ```js\n    // Prevent React Native packager from seeing modules required with this\n    const nodeRequire = require;\n\n    function getRealmConstructor(environment) {\n      switch (environment) {\n        case \"node.js\":\n        case \"electron\":\n          return nodeRequire(\"bindings\")(\"realm.node\").Realm;\n      }\n    }\n    ```\n\n    Version 0.11.11 of esbuild removed this warning, which means people no longer have a way to know at compile time whether their bundle is broken in this way. Now that esbuild has custom log message levels, this warning can be added back in a way that should make both people happy. With this release, there is now a log message for this that defaults to the `debug` log level, which normally isn't visible. You can either do `--log-override:indirect-require=warning` to make this log message a warning (and therefore visible) or use `--log-level=debug` to see this and all other `debug` log messages.\n\n## 0.14.42\n\n* Fix a parser hang on invalid CSS ([#2276](https://github.com/evanw/esbuild/issues/2276))\n\n    Previously invalid CSS with unbalanced parentheses could cause esbuild's CSS parser to hang. An example of such an input is the CSS file `:x(`. This hang has been fixed.\n\n* Add support for custom log message levels\n\n    This release allows you to override the default log level of esbuild's individual log messages. For example, CSS syntax errors are treated as warnings instead of errors by default because CSS grammar allows for rules containing syntax errors to be ignored. However, if you would like for esbuild to consider CSS syntax errors to be build errors, you can now configure that like this:\n\n    * CLI\n\n        ```sh\n        $ esbuild example.css --log-override:css-syntax-error=error\n        ```\n\n    * JS API\n\n        ```js\n        let result = await esbuild.build({\n          entryPoints: ['example.css'],\n          logOverride: {\n            'css-syntax-error': 'error',\n          },\n        })\n        ```\n\n    * Go API\n\n        ```go\n        result := api.Build(api.BuildOptions{\n          EntryPoints: []string{\"example.ts\"},\n          LogOverride: map[string]api.LogLevel{\n            \"css-syntax-error\": api.LogLevelError,\n          },\n        })\n        ```\n\n    You can also now use this feature to silence warnings that you are not interested in. Log messages are referred to by their identifier. Each identifier is stable (i.e. shouldn't change over time) except there is no guarantee that the log message will continue to exist. A given log message may potentially be removed in the future, in which case esbuild will ignore log levels set for that identifier. The current list of supported log level identifiers for use with this feature can be found below:\n\n    **JavaScript:**\n    * `assign-to-constant`\n    * `call-import-namespace`\n    * `commonjs-variable-in-esm`\n    * `delete-super-property`\n    * `direct-eval`\n    * `duplicate-case`\n    * `duplicate-object-key`\n    * `empty-import-meta`\n    * `equals-nan`\n    * `equals-negative-zero`\n    * `equals-new-object`\n    * `html-comment-in-js`\n    * `impossible-typeof`\n    * `private-name-will-throw`\n    * `semicolon-after-return`\n    * `suspicious-boolean-not`\n    * `this-is-undefined-in-esm`\n    * `unsupported-dynamic-import`\n    * `unsupported-jsx-comment`\n    * `unsupported-regexp`\n    * `unsupported-require-call`\n\n    **CSS:**\n    * `css-syntax-error`\n    * `invalid-@charset`\n    * `invalid-@import`\n    * `invalid-@nest`\n    * `invalid-@layer`\n    * `invalid-calc`\n    * `js-comment-in-css`\n    * `unsupported-@charset`\n    * `unsupported-@namespace`\n    * `unsupported-css-property`\n\n    **Bundler:**\n    * `different-path-case`\n    * `ignored-bare-import`\n    * `ignored-dynamic-import`\n    * `import-is-undefined`\n    * `package.json`\n    * `require-resolve-not-external`\n    * `tsconfig.json`\n\n    **Source maps:**\n    * `invalid-source-mappings`\n    * `sections-in-source-map`\n    * `missing-source-map`\n    * `unsupported-source-map-comment`\n\n    Documentation about which identifiers correspond to which log messages will be added in the future, but hasn't been written yet. Note that it's not possible to configure the log level for a build error. This is by design because changing that would cause esbuild to incorrectly proceed in the building process generate invalid build output. You can only configure the log level for non-error log messages (although you can turn non-errors into errors).\n\n## 0.14.41\n\n* Fix a minification regression in 0.14.40 ([#2270](https://github.com/evanw/esbuild/issues/2270), [#2271](https://github.com/evanw/esbuild/issues/2271), [#2273](https://github.com/evanw/esbuild/pull/2273))\n\n    Version 0.14.40 substituted string property keys with numeric property keys if the number has the same string representation as the original string. This was done in three places: computed member expressions, object literal properties, and class fields. However, negative numbers are only valid in computed member expressions while esbuild incorrectly applied this substitution for negative numbers in all places. This release fixes the regression by only doing this substitution for negative numbers in computed member expressions.\n\n    This fix was contributed by [@susiwen8](https://github.com/susiwen8).\n\n## 0.14.40\n\n* Correct esbuild's implementation of `\"preserveValueImports\": true` ([#2268](https://github.com/evanw/esbuild/issues/2268))\n\n    TypeScript's [`preserveValueImports` setting](https://www.typescriptlang.org/tsconfig#preserveValueImports) tells the compiler to preserve unused imports, which can sometimes be necessary because otherwise TypeScript will remove unused imports as it assumes they are type annotations. This setting is useful for programming environments that strip TypeScript types as part of a larger code transformation where additional code is appended later that will then make use of those unused imports, such as with [Svelte](https://svelte.dev/) or [Vue](https://vuejs.org/).\n\n    This release fixes an issue where esbuild's implementation of `preserveValueImports` diverged from the official TypeScript compiler. If the import clause is present but empty of values (even if it contains types), then the import clause should be considered a type-only import clause. This was an oversight, and has now been fixed:\n\n    ```ts\n    // Original code\n    import \"keep\"\n    import { k1 } from \"keep\"\n    import k2, { type t1 } from \"keep\"\n    import {} from \"remove\"\n    import { type t2 } from \"remove\"\n\n    // Old output under \"preserveValueImports\": true\n    import \"keep\";\n    import { k1 } from \"keep\";\n    import k2, {} from \"keep\";\n    import {} from \"remove\";\n    import {} from \"remove\";\n\n    // New output under \"preserveValueImports\": true (matches the TypeScript compiler)\n    import \"keep\";\n    import { k1 } from \"keep\";\n    import k2 from \"keep\";\n    ```\n\n* Avoid regular expression syntax errors in older browsers ([#2215](https://github.com/evanw/esbuild/issues/2215))\n\n    Previously esbuild always passed JavaScript regular expression literals through unmodified from the input to the output. This is undesirable when the regular expression uses newer features that the configured target environment doesn't support. For example, the `d` flag (i.e. the [match indices feature](https://v8.dev/features/regexp-match-indices)) is new in ES2022 and doesn't work in older browsers. If esbuild generated a regular expression literal containing the `d` flag, then older browsers would consider esbuild's output to be a syntax error and none of the code would run.\n\n    With this release, esbuild now detects when an unsupported feature is being used and converts the regular expression literal into a `new RegExp()` constructor instead. One consequence of this is that the syntax error is transformed into a run-time error, which allows the output code to run (and to potentially handle the run-time error). Another consequence of this is that it allows you to include a polyfill that overwrites the `RegExp` constructor in older browsers with one that supports modern features. Note that esbuild does not handle polyfills for you, so you will need to include a `RegExp` polyfill yourself if you want one.\n\n    ```js\n    // Original code\n    console.log(/b/d.exec('abc').indices)\n\n    // New output (with --target=chrome90)\n    console.log(/b/d.exec(\"abc\").indices);\n\n    // New output (with --target=chrome89)\n    console.log(new RegExp(\"b\", \"d\").exec(\"abc\").indices);\n    ```\n\n    This is currently done transparently without a warning. If you would like to debug this transformation to see where in your code esbuild is transforming regular expression literals and why, you can pass `--log-level=debug` to esbuild and review the information present in esbuild's debug logs.\n\n* Add Opera to more internal feature compatibility tables ([#2247](https://github.com/evanw/esbuild/issues/2247), [#2252](https://github.com/evanw/esbuild/pull/2252))\n\n    The internal compatibility tables that esbuild uses to determine which environments support which features are derived from multiple sources. Most of it is automatically derived from [these ECMAScript compatibility tables](https://kangax.github.io/compat-table/), but missing information is manually copied from [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/), GitHub PR comments, and various other websites. Version 0.14.35 of esbuild introduced Opera as a possible target environment which was automatically picked up by the compatibility table script, but the manually-copied information wasn't updated to include Opera. This release fixes this omission so Opera feature compatibility should now be accurate.\n\n    This was contributed by [@lbwa](https://github.com/lbwa).\n\n* Ignore `EPERM` errors on directories ([#2261](https://github.com/evanw/esbuild/issues/2261))\n\n    Previously bundling with esbuild when inside a sandbox environment which does not have permission to access the parent directory did not work because esbuild would try to read the directory to search for a `node_modules` folder and would then fail the build when that failed. In practice this caused issues with running esbuild with `sandbox-exec` on macOS. With this release, esbuild will treat directories with permission failures as empty to allow for the `node_modules` search to continue past the denied directory and into its parent directory. This means it should now be possible to bundle with esbuild in these situations. This fix is similar to the fix in version 0.9.1 but is for `EPERM` while that fix was for `EACCES`.\n\n* Remove an irrelevant extra `\"use strict\"` directive ([#2264](https://github.com/evanw/esbuild/issues/2264))\n\n    The presence of a `\"use strict\"` directive in the output file is controlled by the presence of one in the entry point. However, there was a bug that would include one twice if the output format is ESM. This bug has been fixed.\n\n* Minify strings into integers inside computed properties ([#2214](https://github.com/evanw/esbuild/issues/2214))\n\n    This release now minifies `a[\"0\"]` into `a[0]` when the result is equivalent:\n\n    ```js\n    // Original code\n    console.log(x['0'], { '0': x }, class { '0' = x })\n\n    // Old output (with --minify)\n    console.log(x[\"0\"],{\"0\":x},class{\"0\"=x});\n\n    // New output (with --minify)\n    console.log(x[0],{0:x},class{0=x});\n    ```\n\n    This transformation currently only happens when the numeric property represents an integer within the signed 32-bit integer range.\n\n## 0.14.39\n\n* Fix code generation for `export default` and `/* @__PURE__ */` call ([#2203](https://github.com/evanw/esbuild/issues/2203))\n\n    The `/* @__PURE__ */` comment annotation can be added to function calls to indicate that they are side-effect free. These annotations are passed through into the output by esbuild since many JavaScript tools understand them. However, there was an edge case where printing this comment before a function call caused esbuild to fail to parenthesize a function literal because it thought it was no longer at the start of the expression. This problem has been fixed:\n\n    ```js\n    // Original code\n    export default /* @__PURE__ */ (function() {\n    })()\n\n    // Old output\n    export default /* @__PURE__ */ function() {\n    }();\n\n    // New output\n    export default /* @__PURE__ */ (function() {\n    })();\n    ```\n\n* Preserve `...` before JSX child expressions ([#2245](https://github.com/evanw/esbuild/issues/2245))\n\n    TypeScript 4.5 changed how JSX child expressions that start with `...` are emitted. Previously the `...` was omitted but starting with TypeScript 4.5, the `...` is now preserved instead. This release updates esbuild to match TypeScript's new output in this case:\n\n    ```jsx\n    // Original code\n    console.log(<a>{...b}</a>)\n\n    // Old output\n    console.log(/* @__PURE__ */ React.createElement(\"a\", null, b));\n\n    // New output\n    console.log(/* @__PURE__ */ React.createElement(\"a\", null, ...b));\n    ```\n\n    Note that this behavior is TypeScript-specific. Babel doesn't support the `...` token at all (it gives the error \"Spread children are not supported in React\").\n\n* Slightly adjust esbuild's handling of the `browser` field in `package.json` ([#2239](https://github.com/evanw/esbuild/issues/2239))\n\n    This release changes esbuild's interpretation of `browser` path remapping to fix a regression that was introduced in esbuild version 0.14.21. Browserify has a bug where it incorrectly matches package paths to relative paths in the `browser` field, and esbuild replicates this bug for compatibility with Browserify. I have a set of tests that I use to verify that esbuild's replication of this Browserify is accurate here: https://github.com/evanw/package-json-browser-tests. However, I was missing a test case and esbuild's behavior diverges from Browserify in this case. This release now handles this edge case as well:\n\n    * `entry.js`:\n\n        ```js\n        require('pkg/sub')\n        ```\n\n    * `node_modules/pkg/package.json`:\n\n        ```json\n        {\n          \"browser\": {\n            \"./sub\": \"./sub/foo.js\",\n            \"./sub/sub.js\": \"./sub/foo.js\"\n          }\n        }\n        ```\n\n    * `node_modules/pkg/sub/foo.js`:\n\n        ```js\n        require('sub')\n        ```\n\n    * `node_modules/sub/index.js`:\n\n        ```js\n        console.log('works')\n        ```\n\n    The import path `sub` in `require('sub')` was previously matching the remapping `\"./sub/sub.js\": \"./sub/foo.js\"` but with this release it should now no longer match that remapping. Now `require('sub')` will only match the remapping `\"./sub/sub\": \"./sub/foo.js\"` (without the trailing `.js`). Browserify apparently only matches without the `.js` suffix here.\n\n## 0.14.38\n\n* Further fixes to TypeScript 4.7 instantiation expression parsing ([#2201](https://github.com/evanw/esbuild/issues/2201))\n\n    This release fixes some additional edge cases with parsing instantiation expressions from the upcoming version 4.7 of TypeScript. Previously it was allowed for an instantiation expression to precede a binary operator but with this release, that's no longer allowed. This was sometimes valid in the TypeScript 4.7 beta but is no longer allowed in the latest version of TypeScript 4.7. Fixing this also fixed a regression that was introduced by the previous release of esbuild:\n\n    | Code           | TS 4.6.3     | TS 4.7.0 beta | TS 4.7.0 nightly | esbuild 0.14.36 | esbuild 0.14.37 | esbuild 0.14.38 |\n    |----------------|--------------|---------------|------------------|-----------------|-----------------|-----------------|\n    | `a<b> == c<d>` | Invalid      | `a == c`      | Invalid          | `a == c`        | `a == c`        | Invalid         |\n    | `a<b> in c<d>` | Invalid      | Invalid       | Invalid          | Invalid         | `a in c`        | Invalid         |\n    | `a<b>>=c<d>`   | Invalid      | Invalid       | Invalid          | Invalid         | `a >= c`        | Invalid         |\n    | `a<b>=c<d>`    | Invalid      | `a < b >= c`  | `a = c`          | `a < b >= c`    | `a = c`         | `a = c`         |\n    | `a<b>>c<d>`    | `a < b >> c` | `a < b >> c`  | `a < b >> c`     | `a < b >> c`    | `a > c`         | `a < b >> c`    |\n\n    This table illustrates some of the more significant changes between all of these parsers. The most important part is that esbuild 0.14.38 now matches the behavior of the latest TypeScript compiler for all of these cases.\n\n## 0.14.37\n\n* Add support for TypeScript's `moduleSuffixes` field from TypeScript 4.7\n\n    The upcoming version of TypeScript adds the `moduleSuffixes` field to `tsconfig.json` that introduces more rules to import path resolution. Setting `moduleSuffixes` to `[\".ios\", \".native\", \"\"]` will try to look at the relative files `./foo.ios.ts`, `./foo.native.ts`, and finally `./foo.ts` for an import path of `./foo`. Note that the empty string `\"\"` in `moduleSuffixes` is necessary for TypeScript to also look-up `./foo.ts`. This was announced in the [TypeScript 4.7 beta blog post](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7-beta/#resolution-customization-with-modulesuffixes).\n\n* Match the new ASI behavior from TypeScript nightly builds ([#2188](https://github.com/evanw/esbuild/pull/2188))\n\n    This release updates esbuild to match some very recent behavior changes in the TypeScript parser regarding automatic semicolon insertion. For more information, see TypeScript issues #48711 and #48654 (I'm not linking to them directly to avoid Dependabot linkback spam on these issues due to esbuild's popularity). The result is that the following TypeScript code is now considered valid TypeScript syntax:\n\n    ```ts\n    class A<T> {}\n    new A<number> /* ASI now happens here */\n    if (0) {}\n\n    interface B {\n      (a: number): typeof a /* ASI now happens here */\n      <T>(): void\n    }\n    ```\n\n    This fix was contributed by [@g-plane](https://github.com/g-plane).\n\n## 0.14.36\n\n* Revert path metadata validation for now ([#2177](https://github.com/evanw/esbuild/issues/2177))\n\n    This release reverts the path metadata validation that was introduced in the previous release. This validation has uncovered a potential issue with how esbuild handles `onResolve` callbacks in plugins that will need to be fixed before path metadata validation is re-enabled.\n\n## 0.14.35\n\n* Add support for parsing `typeof` on #private fields from TypeScript 4.7 ([#2174](https://github.com/evanw/esbuild/pull/2174))\n\n    The upcoming version of TypeScript now lets you use `#private` fields in `typeof` type expressions:\n\n    https://devblogs.microsoft.com/typescript/announcing-typescript-4-7-beta/#typeof-on-private-fields\n\n    ```ts\n    class Container {\n      #data = \"hello!\";\n\n      get data(): typeof this.#data {\n        return this.#data;\n      }\n\n      set data(value: typeof this.#data) {\n        this.#data = value;\n      }\n    }\n    ```\n\n    With this release, esbuild can now parse these new type expressions as well. This feature was contributed by [@magic-akari](https://github.com/magic-akari).\n\n* Add Opera and IE to internal CSS feature support matrix ([#2170](https://github.com/evanw/esbuild/pull/2170))\n\n    Version 0.14.18 of esbuild added Opera and IE as available target environments, and added them to the internal JS feature support matrix. CSS feature support was overlooked, however. This release adds knowledge of Opera and IE to esbuild's internal CSS feature support matrix:\n\n    ```css\n    /* Original input */\n    a {\n      color: rgba(0, 0, 0, 0.5);\n    }\n\n    /* Old output (with --target=opera49 --minify) */\n    a{color:rgba(0,0,0,.5)}\n\n    /* New output (with --target=opera49 --minify) */\n    a{color:#00000080}\n    ```\n\n    The fix for this issue was contributed by [@sapphi-red](https://github.com/sapphi-red).\n\n* Change TypeScript class field behavior when targeting ES2022\n\n    TypeScript 4.3 introduced a breaking change where class field behavior changes from assign semantics to define semantics when the `target` setting in `tsconfig.json` is set to `ESNext`. Specifically, the default value for TypeScript's `useDefineForClassFields` setting when unspecified is `true` if and only if `target` is `ESNext`. TypeScript 4.6 introduced another change where this behavior now happens for both `ESNext` and `ES2022`. Presumably this will be the case for `ES2023` and up as well. With this release, esbuild's behavior has also been changed to match. Now configuring esbuild with `--target=es2022` will also cause TypeScript files to use the new class field behavior.\n\n* Validate that path metadata returned by plugins is consistent\n\n    The plugin API assumes that all metadata for the same path returned by a plugin's `onResolve` callback is consistent. Previously this assumption was just assumed without any enforcement. Starting with this release, esbuild will now enforce this by generating a build error if this assumption is violated. The lack of validation has not been an issue (I have never heard of this being a problem), but it still seems like a good idea to enforce it. Here's a simple example of a plugin that generates inconsistent `sideEffects` metadata:\n\n    ```js\n    let buggyPlugin = {\n      name: 'buggy',\n      setup(build) {\n        let count = 0\n        build.onResolve({ filter: /^react$/ }, args => {\n          return {\n            path: require.resolve(args.path),\n            sideEffects: count++ > 0,\n          }\n        })\n      },\n    }\n    ```\n\n    Since esbuild processes everything in parallel, the set of metadata that ends up being used for a given path is essentially random since it's whatever the task scheduler decides to schedule first. Thus if a plugin does not consistently provide the same metadata for a given path, subsequent builds may return different results. This new validation check prevents this problem.\n\n    Here's the new error message that's shown when this happens:\n\n    ```\n    ✘ [ERROR] [plugin buggy] Detected inconsistent metadata for the path \"node_modules/react/index.js\" when it was imported here:\n\n        button.tsx:1:30:\n          1 │ import { createElement } from 'react'\n            ╵                               ~~~~~~~\n\n      The original metadata for that path comes from when it was imported here:\n\n        app.tsx:1:23:\n          1 │ import * as React from 'react'\n            ╵                        ~~~~~~~\n\n      The difference in metadata is displayed below:\n\n       {\n      -  \"sideEffects\": true,\n      +  \"sideEffects\": false,\n       }\n\n      This is a bug in the \"buggy\" plugin. Plugins provide metadata for a given path in an \"onResolve\"\n      callback. All metadata provided for the same path must be consistent to ensure deterministic\n      builds. Due to parallelism, one set of provided metadata will be randomly chosen for a given path,\n      so providing inconsistent metadata for the same path can cause non-determinism.\n    ```\n\n* Suggest enabling a missing condition when `exports` map fails ([#2163](https://github.com/evanw/esbuild/issues/2163))\n\n    This release adds another suggestion to the error message that happens when an `exports` map lookup fails if the failure could potentially be fixed by adding a missing condition. Here's what the new error message looks like (which now suggests `--conditions=module` as a possible workaround):\n\n    ```\n    ✘ [ERROR] Could not resolve \"@sentry/electron/main\"\n\n        index.js:1:24:\n          1 │ import * as Sentry from '@sentry/electron/main'\n            ╵                         ~~~~~~~~~~~~~~~~~~~~~~~\n\n      The path \"./main\" is not currently exported by package \"@sentry/electron\":\n\n        node_modules/@sentry/electron/package.json:8:13:\n          8 │   \"exports\": {\n            ╵              ^\n\n      None of the conditions provided (\"require\", \"module\") match any of the currently active conditions\n      (\"browser\", \"default\", \"import\"):\n\n        node_modules/@sentry/electron/package.json:16:14:\n          16 │     \"./main\": {\n             ╵               ^\n\n      Consider enabling the \"module\" condition if this package expects it to be enabled. You can use\n      \"--conditions=module\" to do that:\n\n        node_modules/@sentry/electron/package.json:18:6:\n          18 │       \"module\": \"./esm/main/index.js\"\n             ╵       ~~~~~~~~\n\n      Consider using a \"require()\" call to import this file, which will work because the \"require\"\n      condition is supported by this package:\n\n        index.js:1:24:\n          1 │ import * as Sentry from '@sentry/electron/main'\n            ╵                         ~~~~~~~~~~~~~~~~~~~~~~~\n\n      You can mark the path \"@sentry/electron/main\" as external to exclude it from the bundle, which\n      will remove this error.\n    ```\n\n    This particular package had an issue where it was using the Webpack-specific `module` condition without providing a `default` condition. It looks like the intent in this case was to use the standard `import` condition instead. This specific change wasn't suggested here because this error message is for package consumers, not package authors.\n\n## 0.14.34\n\nSomething went wrong with the publishing script for the previous release. Publishing again.\n\n## 0.14.33\n\n* Fix a regression regarding `super` ([#2158](https://github.com/evanw/esbuild/issues/2158))\n\n    This fixes a regression from the previous release regarding classes with a super class, a private member, and a static field in the scenario where the static field needs to be lowered but where private members are supported by the configured target environment. In this scenario, esbuild could incorrectly inject the instance field initializers that use `this` into the constructor before the call to `super()`, which is invalid. This problem has now been fixed (notice that `this` is now used after `super()` instead of before):\n\n    ```js\n    // Original code\n    class Foo extends Object {\n      static FOO;\n      constructor() {\n        super();\n      }\n      #foo;\n    }\n\n    // Old output (with --bundle)\n    var _foo;\n    var Foo = class extends Object {\n      constructor() {\n        __privateAdd(this, _foo, void 0);\n        super();\n      }\n    };\n    _foo = new WeakMap();\n    __publicField(Foo, \"FOO\");\n\n    // New output (with --bundle)\n    var _foo;\n    var Foo = class extends Object {\n      constructor() {\n        super();\n        __privateAdd(this, _foo, void 0);\n      }\n    };\n    _foo = new WeakMap();\n    __publicField(Foo, \"FOO\");\n    ```\n\n    During parsing, esbuild scans the class and makes certain decisions about the class such as whether to lower all static fields, whether to lower each private member, or whether calls to `super()` need to be tracked and adjusted. Previously esbuild made two passes through the class members to compute this information. However, with the new `super()` call lowering logic added in the previous release, we now need three passes to capture the whole dependency chain for this case: 1) lowering static fields requires 2) lowering private members which requires 3) adjusting `super()` calls.\n\n    The reason lowering static fields requires lowering private members is because lowering static fields moves their initializers outside of the class body, where they can't access private members anymore. Consider this code:\n\n    ```js\n    class Foo {\n      get #foo() {}\n      static bar = new Foo().#foo\n    }\n    ```\n\n    We can't just lower static fields without also lowering private members, since that causes a syntax error:\n\n    ```js\n    class Foo {\n      get #foo() {}\n    }\n    Foo.bar = new Foo().#foo;\n    ```\n\n    And the reason lowering private members requires adjusting `super()` calls is because the injected private member initializers use `this`, which is only accessible after `super()` calls in the constructor.\n\n* Fix an issue with `--keep-names` not keeping some names ([#2149](https://github.com/evanw/esbuild/issues/2149))\n\n    This release fixes a regression with `--keep-names` from version 0.14.26. PR [#2062](https://github.com/evanw/esbuild/pull/2062) attempted to remove superfluous calls to the `__name` helper function by omitting calls of the form `__name(foo, \"foo\")` where the name of the symbol in the first argument is equal to the string in the second argument. This was assuming that the initializer for the symbol would automatically be assigned the expected `.name` property by the JavaScript VM, which turned out to be an incorrect assumption. To fix the regression, this PR has been reverted.\n\n    The assumption is true in many cases but isn't true when the initializer is moved into another automatically-generated variable, which can sometimes be necessary during the various syntax transformations that esbuild does. For example, consider the following code:\n\n    ```js\n    class Foo {\n      static get #foo() { return Foo.name }\n      static get foo() { return this.#foo }\n    }\n    let Bar = Foo\n    Foo = { name: 'Bar' }\n    console.log(Foo.name, Bar.name)\n    ```\n\n    This code should print `Bar Foo`. With `--keep-names --target=es6` that code is lowered by esbuild into the following code (omitting the helper function definitions for brevity):\n\n    ```js\n    var _foo, foo_get;\n    const _Foo = class {\n      static get foo() {\n        return __privateGet(this, _foo, foo_get);\n      }\n    };\n    let Foo = _Foo;\n    __name(Foo, \"Foo\");\n    _foo = new WeakSet();\n    foo_get = /* @__PURE__ */ __name(function() {\n      return _Foo.name;\n    }, \"#foo\");\n    __privateAdd(Foo, _foo);\n    let Bar = Foo;\n    Foo = { name: \"Bar\" };\n    console.log(Foo.name, Bar.name);\n    ```\n\n    The injection of the automatically-generated `_Foo` variable is necessary to preserve the semantics of the captured `Foo` binding for methods defined within the class body, even when the definition needs to be moved outside of the class body during code transformation. Due to a JavaScript quirk, this binding is immutable and does not change even if `Foo` is later reassigned. The PR that was reverted was incorrectly removing the call to `__name(Foo, \"Foo\")`, which turned out to be necessary after all in this case.\n\n* Print some large integers using hexadecimal when minifying ([#2162](https://github.com/evanw/esbuild/issues/2162))\n\n    When `--minify` is active, esbuild will now use one fewer byte to represent certain large integers:\n\n    ```js\n    // Original code\n    x = 123456787654321;\n\n    // Old output (with --minify)\n    x=123456787654321;\n\n    // New output (with --minify)\n    x=0x704885f926b1;\n    ```\n\n    This works because a hexadecimal representation can be shorter than a decimal representation starting at around 10<sup>12</sup> and above.\n\n    _This optimization made me realize that there's probably an opportunity to optimize printed numbers for smaller gzipped size instead of or in addition to just optimizing for minimal uncompressed byte count. The gzip algorithm does better with repetitive sequences, so for example `0xFFFFFFFF` is probably a better representation than `4294967295` even though the byte counts are the same. As far as I know, no JavaScript minifier does this optimization yet. I don't know enough about how gzip works to know if this is a good idea or what the right metric for this might be._\n\n* Add Linux ARM64 support for Deno ([#2156](https://github.com/evanw/esbuild/issues/2156))\n\n    This release adds Linux ARM64 support to esbuild's [Deno](https://deno.land/) API implementation, which allows esbuild to be used with Deno on a Raspberry Pi.\n\n## 0.14.32\n\n* Fix `super` usage in lowered private methods ([#2039](https://github.com/evanw/esbuild/issues/2039))\n\n    Previously esbuild failed to transform `super` property accesses inside private methods in the case when private methods have to be lowered because the target environment doesn't support them. The generated code still contained the `super` keyword even though the method was moved outside of the class body, which is a syntax error in JavaScript. This release fixes this transformation issue and now produces valid code:\n\n    ```js\n    // Original code\n    class Derived extends Base {\n      #foo() { super.foo() }\n      bar() { this.#foo() }\n    }\n\n    // Old output (with --target=es6)\n    var _foo, foo_fn;\n    class Derived extends Base {\n      constructor() {\n        super(...arguments);\n        __privateAdd(this, _foo);\n      }\n      bar() {\n        __privateMethod(this, _foo, foo_fn).call(this);\n      }\n    }\n    _foo = new WeakSet();\n    foo_fn = function() {\n      super.foo();\n    };\n\n    // New output (with --target=es6)\n    var _foo, foo_fn;\n    const _Derived = class extends Base {\n      constructor() {\n        super(...arguments);\n        __privateAdd(this, _foo);\n      }\n      bar() {\n        __privateMethod(this, _foo, foo_fn).call(this);\n      }\n    };\n    let Derived = _Derived;\n    _foo = new WeakSet();\n    foo_fn = function() {\n      __superGet(_Derived.prototype, this, \"foo\").call(this);\n    };\n    ```\n\n    Because of this change, lowered `super` property accesses on instances were rewritten so that they can exist outside of the class body. This rewrite affects code generation for all `super` property accesses on instances including those inside lowered `async` functions. The new approach is different but should be equivalent to the old approach:\n\n    ```js\n    // Original code\n    class Foo {\n      foo = async () => super.foo()\n    }\n\n    // Old output (with --target=es6)\n    class Foo {\n      constructor() {\n        __publicField(this, \"foo\", () => {\n          var __superGet = (key) => super[key];\n          return __async(this, null, function* () {\n            return __superGet(\"foo\").call(this);\n          });\n        });\n      }\n    }\n\n    // New output (with --target=es6)\n    class Foo {\n      constructor() {\n        __publicField(this, \"foo\", () => __async(this, null, function* () {\n          return __superGet(Foo.prototype, this, \"foo\").call(this);\n        }));\n      }\n    }\n    ```\n\n* Fix some tree-shaking bugs regarding property side effects\n\n    This release fixes some cases where side effects in computed properties were not being handled correctly. Specifically primitives and private names as properties should not be considered to have side effects, and object literals as properties should be considered to have side effects:\n\n    ```js\n    // Original code\n    let shouldRemove = { [1]: 2 }\n    let shouldRemove2 = class { #foo }\n    let shouldKeep = class { [{ toString() { sideEffect() } }] }\n\n    // Old output (with --tree-shaking=true)\n    let shouldRemove = { [1]: 2 };\n    let shouldRemove2 = class {\n      #foo;\n    };\n\n    // New output (with --tree-shaking=true)\n    let shouldKeep = class {\n      [{ toString() {\n        sideEffect();\n      } }];\n    };\n    ```\n\n* Add the `wasmModule` option to the `initialize` JS API ([#1093](https://github.com/evanw/esbuild/issues/1093))\n\n    The `initialize` JS API must be called when using esbuild in the browser to provide the WebAssembly module for esbuild to use. Previously the only way to do that was using the `wasmURL` API option like this:\n\n    ```js\n    await esbuild.initialize({\n      wasmURL: '/node_modules/esbuild-wasm/esbuild.wasm',\n    })\n    console.log(await esbuild.transform('1+2'))\n    ```\n\n    With this release, you can now also initialize esbuild using a `WebAssembly.Module` instance using the `wasmModule` API option instead. The example above is equivalent to the following code:\n\n    ```js\n    await esbuild.initialize({\n      wasmModule: await WebAssembly.compileStreaming(fetch('/node_modules/esbuild-wasm/esbuild.wasm'))\n    })\n    console.log(await esbuild.transform('1+2'))\n    ```\n\n    This could be useful for environments where you want more control over how the WebAssembly download happens or where downloading the WebAssembly module is not possible.\n\n## 0.14.31\n\n* Add support for parsing \"optional variance annotations\" from TypeScript 4.7 ([#2102](https://github.com/evanw/esbuild/pull/2102))\n\n    The upcoming version of TypeScript now lets you specify `in` and/or `out` on certain type parameters (specifically only on a type alias, an interface declaration, or a class declaration). These modifiers control type parameter covariance and contravariance:\n\n    ```ts\n    type Provider<out T> = () => T;\n    type Consumer<in T> = (x: T) => void;\n    type Mapper<in T, out U> = (x: T) => U;\n    type Processor<in out T> = (x: T) => T;\n    ```\n\n    With this release, esbuild can now parse these new type parameter modifiers. This feature was contributed by [@magic-akari](https://github.com/magic-akari).\n\n* Improve support for `super()` constructor calls in nested locations ([#2134](https://github.com/evanw/esbuild/issues/2134))\n\n    In JavaScript, derived classes must call `super()` somewhere in the `constructor` method before being able to access `this`. Class public instance fields, class private instance fields, and TypeScript constructor parameter properties can all potentially cause code which uses `this` to be inserted into the constructor body, which must be inserted after the `super()` call. To make these insertions straightforward to implement, the TypeScript compiler doesn't allow calling `super()` somewhere other than in a root-level statement in the constructor body in these cases.\n\n    Previously esbuild's class transformations only worked correctly when `super()` was called in a root-level statement in the constructor body, just like the TypeScript compiler. But with this release, esbuild should now generate correct code as long as the call to `super()` appears anywhere in the constructor body:\n\n    ```ts\n    // Original code\n    class Foo extends Bar {\n      constructor(public skip = false) {\n        if (skip) {\n          super(null)\n          return\n        }\n        super({ keys: [] })\n      }\n    }\n\n    // Old output (incorrect)\n    class Foo extends Bar {\n      constructor(skip = false) {\n        if (skip) {\n          super(null);\n          return;\n        }\n        super({ keys: [] });\n        this.skip = skip;\n      }\n    }\n\n    // New output (correct)\n    class Foo extends Bar {\n      constructor(skip = false) {\n        var __super = (...args) => {\n          super(...args);\n          this.skip = skip;\n        };\n        if (skip) {\n          __super(null);\n          return;\n        }\n        __super({ keys: [] });\n      }\n    }\n    ```\n\n* Add support for the new `@container` CSS rule ([#2127](https://github.com/evanw/esbuild/pull/2127))\n\n    This release adds support for [`@container`](https://drafts.csswg.org/css-contain-3/#container-rule) in CSS files. This means esbuild will now pretty-print and minify these rules better since it now better understands the internal structure of these rules:\n\n    ```css\n    /* Original code */\n    @container (width <= 150px) {\n      #inner {\n        color: yellow;\n      }\n    }\n\n    /* Old output (with --minify) */\n    @container (width <= 150px){#inner {color: yellow;}}\n\n    /* New output (with --minify) */\n    @container (width <= 150px){#inner{color:#ff0}}\n    ```\n\n    This was contributed by [@yisibl](https://github.com/yisibl).\n\n* Avoid CSS cascade-dependent keywords in the `font-family` property ([#2135](https://github.com/evanw/esbuild/pull/2135))\n\n    In CSS, [`initial`](https://developer.mozilla.org/en-US/docs/Web/CSS/initial), [`inherit`](https://developer.mozilla.org/en-US/docs/Web/CSS/inherit), and [`unset`](https://developer.mozilla.org/en-US/docs/Web/CSS/unset) are [CSS-wide keywords](https://drafts.csswg.org/css-values-4/#css-wide-keywords) which means they have special behavior when they are specified as a property value. For example, while `font-family: 'Arial'` (as a string) and `font-family: Arial` (as an identifier) are the same, `font-family: 'inherit'` (as a string) uses the font family named `inherit` but `font-family: inherit` (as an identifier) inherits the font family from the parent element. This means esbuild must not unquote these CSS-wide keywords (and `default`, which is also reserved) during minification to avoid changing the meaning of the minified CSS.\n\n    The current draft of the new CSS Cascading and Inheritance Level 5 specification adds another concept called [cascade-dependent keywords](https://drafts.csswg.org/css-cascade-5/#defaulting-keywords) of which there are two: [`revert`](https://developer.mozilla.org/en-US/docs/Web/CSS/revert) and [`revert-layer`](https://developer.mozilla.org/en-US/docs/Web/CSS/revert-layer). This release of esbuild guards against unquoting these additional keywords as well to avoid accidentally breaking pages that use a font with the same name:\n\n    ```css\n    /* Original code */\n    a { font-family: 'revert'; }\n    b { font-family: 'revert-layer', 'Segoe UI', serif; }\n\n    /* Old output (with --minify) */\n    a{font-family:revert}b{font-family:revert-layer,Segoe UI,serif}\n\n    /* New output (with --minify) */\n    a{font-family:\"revert\"}b{font-family:\"revert-layer\",Segoe UI,serif}\n    ```\n\n    This fix was contributed by [@yisibl](https://github.com/yisibl).\n\n## 0.14.30\n\n* Change the context of TypeScript parameter decorators ([#2147](https://github.com/evanw/esbuild/issues/2147))\n\n    While TypeScript parameter decorators are expressions, they are not evaluated where they exist in the code. They are moved to after the class declaration and evaluated there instead. Specifically this TypeScript code:\n\n    ```ts\n    class Class {\n      method(@decorator() arg) {}\n    }\n    ```\n\n    becomes this JavaScript code:\n\n    ```js\n    class Class {\n      method(arg) {}\n    }\n    __decorate([\n      __param(0, decorator())\n    ], Class.prototype, \"method\", null);\n    ```\n\n    This has several consequences:\n\n    * Whether `await` is allowed inside a decorator expression or not depends on whether the class declaration itself is in an `async` context or not. With this release, you can now use `await` inside a decorator expression when the class declaration is either inside an `async` function or is at the top-level of an ES module and top-level await is supported. Note that the TypeScript compiler currently has a bug regarding this edge case: https://github.com/microsoft/TypeScript/issues/48509.\n\n        ```ts\n        // Using \"await\" inside a decorator expression is now allowed\n        async function fn(foo: Promise<any>) {\n          class Class {\n            method(@decorator(await foo) arg) {}\n          }\n          return Class\n        }\n        ```\n\n        Also while TypeScript currently allows `await` to be used like this in `async` functions, it doesn't currently allow `yield` to be used like this in generator functions. It's not yet clear whether this behavior with `yield` is a bug or by design, so I haven't made any changes to esbuild's handling of `yield` inside decorator expressions in this release.\n\n    * Since the scope of a decorator expression is the scope enclosing the class declaration, they cannot access private identifiers. Previously this was incorrectly allowed but with this release, esbuild no longer allows this. Note that the TypeScript compiler currently has a bug regarding this edge case: https://github.com/microsoft/TypeScript/issues/48515.\n\n        ```ts\n        // Using private names inside a decorator expression is no longer allowed\n        class Class {\n          static #priv = 123\n          method(@decorator(Class.#priv) arg) {}\n        }\n        ```\n\n    * Since the scope of a decorator expression is the scope enclosing the class declaration, identifiers inside parameter decorator expressions should never be resolved to a parameter of the enclosing method. Previously this could happen, which was a bug with esbuild. This bug no longer happens in this release.\n\n        ```ts\n        // Name collisions now resolve to the outer name instead of the inner name\n        let arg = 1\n        class Class {\n          method(@decorator(arg) arg = 2) {}\n        }\n        ```\n\n        Specifically previous versions of esbuild generated the following incorrect JavaScript (notice the use of `arg2`):\n\n        ```js\n        let arg = 1;\n        class Class {\n          method(arg2 = 2) {\n          }\n        }\n        __decorateClass([\n          __decorateParam(0, decorator(arg2))\n        ], Class.prototype, \"method\", 1);\n        ```\n\n        This release now generates the following correct JavaScript (notice the use of `arg`):\n\n        ```js\n        let arg = 1;\n        class Class {\n          method(arg2 = 2) {\n          }\n        }\n        __decorateClass([\n          __decorateParam(0, decorator(arg))\n        ], Class.prototype, \"method\", 1);\n        ```\n\n* Fix some obscure edge cases with `super` property access\n\n    This release fixes the following obscure problems with `super` when targeting an older JavaScript environment such as `--target=es6`:\n\n    1. The compiler could previously crash when a lowered `async` arrow function contained a class with a field initializer that used a `super` property access:\n\n        ```js\n        let foo = async () => class extends Object {\n          bar = super.toString\n        }\n        ```\n\n    2. The compiler could previously generate incorrect code when a lowered `async` method of a derived class contained a nested class with a computed class member involving a `super` property access on the derived class:\n\n        ```js\n        class Base {\n          foo() { return 'bar' }\n        }\n        class Derived extends Base {\n          async foo() {\n            return new class { [super.foo()] = 'success' }\n          }\n        }\n        new Derived().foo().then(obj => console.log(obj.bar))\n        ```\n\n    3. The compiler could previously generate incorrect code when a default-exported class contained a `super` property access inside a lowered static private class field:\n\n        ```js\n        class Foo {\n          static foo = 123\n        }\n        export default class extends Foo {\n          static #foo = super.foo\n          static bar = this.#foo\n        }\n        ```\n\n## 0.14.29\n\n* Fix a minification bug with a double-nested `if` inside a label followed by `else` ([#2139](https://github.com/evanw/esbuild/issues/2139))\n\n    This fixes a minification bug that affects the edge case where `if` is followed by `else` and the `if` contains a label that contains a nested `if`. Normally esbuild's AST printer automatically wraps the body of a single-statement `if` in braces to avoid the \"dangling else\" `if`/`else` ambiguity common to C-like languages (where the `else` accidentally becomes associated with the inner `if` instead of the outer `if`). However, I was missing automatic wrapping of label statements, which did not have test coverage because they are a rarely-used feature. This release fixes the bug:\n\n    ```js\n    // Original code\n    if (a)\n      b: {\n        if (c) break b\n      }\n    else if (d)\n      e()\n\n    // Old output (with --minify)\n    if(a)e:if(c)break e;else d&&e();\n\n    // New output (with --minify)\n    if(a){e:if(c)break e}else d&&e();\n    ```\n\n* Fix edge case regarding `baseUrl` and `paths` in `tsconfig.json` ([#2119](https://github.com/evanw/esbuild/issues/2119))\n\n    In `tsconfig.json`, TypeScript forbids non-relative values inside `paths` if `baseUrl` is not present, and esbuild does too. However, TypeScript checked this after the entire `tsconfig.json` hierarchy was parsed while esbuild incorrectly checked this immediately when parsing the file containing the `paths` map. This caused incorrect warnings to be generated for `tsconfig.json` files that specify a `baseUrl` value and that inherit a `paths` value from an `extends` clause. Now esbuild will only check for non-relative `paths` values after the entire hierarchy has been parsed to avoid generating incorrect warnings.\n\n* Better handle errors where the esbuild binary executable is corrupted or missing ([#2129](https://github.com/evanw/esbuild/issues/2129))\n\n    If the esbuild binary executable is corrupted or missing, previously there was one situation where esbuild's JavaScript API could hang instead of generating an error. This release changes esbuild's library code to generate an error instead in this case.\n\n## 0.14.28\n\n* Add support for some new CSS rules ([#2115](https://github.com/evanw/esbuild/issues/2115), [#2116](https://github.com/evanw/esbuild/issues/2116), [#2117](https://github.com/evanw/esbuild/issues/2117))\n\n    This release adds support for [`@font-palette-values`](https://drafts.csswg.org/css-fonts-4/#font-palette-values), [`@counter-style`](https://developer.mozilla.org/en-US/docs/Web/CSS/@counter-style), and [`@font-feature-values`](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-feature-values). This means esbuild will now pretty-print and minify these rules better since it now better understands the internal structure of these rules:\n\n    ```css\n    /* Original code */\n    @font-palette-values --Foo { base-palette: 1; }\n    @counter-style bar { symbols: b a r; }\n    @font-feature-values Bop { @styleset { test: 1; } }\n\n    /* Old output (with --minify) */\n    @font-palette-values --Foo{base-palette: 1;}@counter-style bar{symbols: b a r;}@font-feature-values Bop{@styleset {test: 1;}}\n\n    /* New output (with --minify) */\n    @font-palette-values --Foo{base-palette:1}@counter-style bar{symbols:b a r}@font-feature-values Bop{@styleset{test:1}}\n    ```\n\n* Upgrade to Go 1.18.0 ([#2105](https://github.com/evanw/esbuild/issues/2105))\n\n    Binary executables for this version are now published with Go version 1.18.0. The [Go release notes](https://go.dev/doc/go1.18) say that the linker generates smaller binaries and that on 64-bit ARM chips, compiled binaries run around 10% faster. On an M1 MacBook Pro, esbuild's benchmark runs approximately 8% faster than before and the binary executable is approximately 4% smaller than before.\n\n    This also fixes a regression from version 0.14.26 of esbuild where the browser builds of the `esbuild-wasm` package could fail to be bundled due to the use of built-in node libraries. The primary WebAssembly shim for Go 1.18.0 no longer uses built-in node libraries.\n\n## 0.14.27\n\n* Avoid generating an enumerable `default` import for CommonJS files in Babel mode ([#2097](https://github.com/evanw/esbuild/issues/2097))\n\n    Importing a CommonJS module into an ES module can be done in two different ways. In node mode the `default` import is always set to `module.exports`, while in Babel mode the `default` import passes through to `module.exports.default` instead. Node mode is triggered when the importing file ends in `.mjs`, has `type: \"module\"` in its `package.json` file, or the imported module does not have a `__esModule` marker.\n\n    Previously esbuild always created the forwarding `default` import in Babel mode, even if `module.exports` had no property called `default`. This was problematic because the getter named `default` still showed up as a property on the imported namespace object, and could potentially interfere with code that iterated over the properties of the imported namespace object. With this release the getter named `default` will now only be added in Babel mode if the `default` property exists at the time of the import.\n\n* Fix a circular import edge case regarding ESM-to-CommonJS conversion ([#1894](https://github.com/evanw/esbuild/issues/1894), [#2059](https://github.com/evanw/esbuild/pull/2059))\n\n    This fixes a regression that was introduced in version 0.14.5 of esbuild. Ever since that version, esbuild now creates two separate export objects when you convert an ES module file into a CommonJS module: one for ES modules and one for CommonJS modules. The one for CommonJS modules is written to `module.exports` and exported from the file, and the one for ES modules is internal and can be accessed by bundling code that imports the entry point (for example, the entry point might import itself to be able to inspect its own exports).\n\n    The reason for these two separate export objects is that CommonJS modules are supposed to see a special export called `__esModule` which indicates that the module used to be an ES module, while ES modules are not supposed to see any automatically-added export named `__esModule`. This matters for real-world code both because people sometimes iterate over the properties of ES module export namespace objects and because some people write ES module code containing their own exports named `__esModule` that they expect other ES module code to be able to read.\n\n    However, this change to split exports into two separate objects broke ES module re-exports in the edge case where the imported module is involved in an import cycle. This happened because the CommonJS `module.exports` object was no longer mutated as exports were added. Instead it was being initialized at the end of the generated file after the import statements to other modules (which are converted into `require()` calls). This release changes `module.exports` initialization to happen earlier in the file and then double-writes further exports to both the ES module and CommonJS module export objects.\n\n    This fix was contributed by [@indutny](https://github.com/indutny).\n\n## 0.14.26\n\n* Fix a tree shaking regression regarding `var` declarations ([#2080](https://github.com/evanw/esbuild/issues/2080), [#2085](https://github.com/evanw/esbuild/pull/2085), [#2098](https://github.com/evanw/esbuild/issues/2098), [#2099](https://github.com/evanw/esbuild/issues/2099))\n\n    Version 0.14.8 of esbuild enabled removal of duplicate function declarations when minification is enabled (see [#610](https://github.com/evanw/esbuild/issues/610)):\n\n    ```js\n    // Original code\n    function x() { return 1 }\n    console.log(x())\n    function x() { return 2 }\n\n    // Output (with --minify-syntax)\n    console.log(x());\n    function x() {\n      return 2;\n    }\n    ```\n\n    This transformation is safe because function declarations are \"hoisted\" in JavaScript, which means they are all done first before any other code is evaluted. This means the last function declaration will overwrite all previous function declarations with the same name.\n\n    However, this introduced an unintentional regression for `var` declarations in which all but the last declaration was dropped if tree-shaking was enabled. This only happens for top-level `var` declarations that re-declare the same variable multiple times. This regression has now been fixed:\n\n    ```js\n    // Original code\n    var x = 1\n    console.log(x)\n    var x = 2\n\n    // Old output (with --tree-shaking=true)\n    console.log(x);\n    var x = 2;\n\n    // New output (with --tree-shaking=true)\n    var x = 1;\n    console.log(x);\n    var x = 2;\n    ```\n\n    This case now has test coverage.\n\n* Add support for parsing \"instantiation expressions\" from TypeScript 4.7 ([#2038](https://github.com/evanw/esbuild/pull/2038))\n\n    The upcoming version of TypeScript now lets you specify `<...>` type parameters on a JavaScript identifier without using a call expression:\n\n    ```ts\n    const ErrorMap = Map<string, Error>;  // new () => Map<string, Error>\n    const errorMap = new ErrorMap();  // Map<string, Error>\n    ```\n\n    With this release, esbuild can now parse these new type annotations. This feature was contributed by [@g-plane](https://github.com/g-plane).\n\n* Avoid `new Function` in esbuild's library code ([#2081](https://github.com/evanw/esbuild/issues/2081))\n\n    Some JavaScript environments such as Cloudflare Workers or Deno Deploy don't allow `new Function` because they disallow dynamic JavaScript evaluation. Previously esbuild's WebAssembly-based library used this to construct the WebAssembly worker function. With this release, the code is now inlined without using `new Function` so it will be able to run even when this restriction is in place.\n\n* Drop superfluous `__name()` calls ([#2062](https://github.com/evanw/esbuild/pull/2062))\n\n    When the `--keep-names` option is specified, esbuild inserts calls to a `__name` helper function to ensure that the `.name` property on function and class objects remains consistent even if the function or class name is renamed to avoid a name collision or because name minification is enabled. With this release, esbuild will now try to omit these calls to the `__name` helper function when the name of the function or class object was not renamed during the linking process after all:\n\n    ```js\n    // Original code\n    import { foo as foo1 } from 'data:text/javascript,export function foo() { return \"foo1\" }'\n    import { foo as foo2 } from 'data:text/javascript,export function foo() { return \"foo2\" }'\n    console.log(foo1.name, foo2.name)\n\n    // Old output (with --bundle --keep-names)\n    (() => {\n      var __defProp = Object.defineProperty;\n      var __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\n      function foo() {\n        return \"foo1\";\n      }\n      __name(foo, \"foo\");\n      function foo2() {\n        return \"foo2\";\n      }\n      __name(foo2, \"foo\");\n      console.log(foo.name, foo2.name);\n    })();\n\n    // New output (with --bundle --keep-names)\n    (() => {\n      var __defProp = Object.defineProperty;\n      var __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\n      function foo() {\n        return \"foo1\";\n      }\n      function foo2() {\n        return \"foo2\";\n      }\n      __name(foo2, \"foo\");\n      console.log(foo.name, foo2.name);\n    })();\n    ```\n\n    Notice how one of the calls to `__name` is now no longer printed. This change was contributed by [@indutny](https://github.com/indutny).\n\n## 0.14.25\n\n* Reduce minification of CSS transforms to avoid Safari bugs ([#2057](https://github.com/evanw/esbuild/issues/2057))\n\n    In Safari, applying a 3D CSS transform to an element can cause it to render in a different order than applying a 2D CSS transform even if the transformation matrix is identical. I believe this is a bug in Safari because the [CSS `transform` specification](https://drafts.csswg.org/css-transforms-1/#transform-rendering) doesn't seem to distinguish between 2D and 3D transforms as far as rendering order:\n\n    > For elements whose layout is governed by the CSS box model, any value other than `none` for the `transform` property results in the creation of a stacking context.\n\n    This bug means that minifying a 3D transform into a 2D transform must be avoided even though it's a valid transformation because it can cause rendering differences in Safari. Previously esbuild sometimes minified 3D CSS transforms into 2D CSS transforms but with this release, esbuild will no longer do that:\n\n    ```css\n    /* Original code */\n    div { transform: matrix3d(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }\n\n    /* Old output (with --minify) */\n    div{transform:scale(2)}\n\n    /* New output (with --minify) */\n    div{transform:scale3d(2,2,1)}\n    ```\n\n* Minification now takes advantage of the `?.` operator\n\n    This adds new code minification rules that shorten code with the `?.` optional chaining operator when the result is equivalent:\n\n    ```ts\n    // Original code\n    let foo = (x) => {\n      if (x !== null && x !== undefined) x.y()\n      return x === null || x === undefined ? undefined : x.z\n    }\n\n    // Old output (with --minify)\n    let foo=n=>(n!=null&&n.y(),n==null?void 0:n.z);\n\n    // New output (with --minify)\n    let foo=n=>(n?.y(),n?.z);\n    ```\n\n    This only takes effect when minification is enabled and when the configured target environment is known to support the optional chaining operator. As always, make sure to set `--target=` to the appropriate language target if you are running the minified code in an environment that doesn't support the latest JavaScript features.\n\n* Add source mapping information for some non-executable tokens ([#1448](https://github.com/evanw/esbuild/issues/1448))\n\n    Code coverage tools can generate reports that tell you if any code exists that has not been run (or \"covered\") during your tests. You can use this information to add additional tests for code that isn't currently covered.\n\n    Some popular JavaScript code coverage tools have bugs where they incorrectly consider lines without any executable code as uncovered, even though there's no test you could possibly write that would cause those lines to be executed. For example, they apparently complain about the lines that only contain the trailing `}` token of an object literal.\n\n    With this release, esbuild now generates source mappings for some of these trailing non-executable tokens. This may not successfully work around bugs in code coverage tools because there are many non-executable tokens in JavaScript and esbuild doesn't map them all (the drawback of mapping these extra tokens is that esbuild will use more memory, build more slowly, and output a bigger source map). The true solution is to fix the bugs in the code coverage tools in the first place.\n\n* Fall back to WebAssembly on Android x64 ([#2068](https://github.com/evanw/esbuild/issues/2068))\n\n    Go's compiler supports trivial cross-compiling to almost all platforms without installing any additional software other than the Go compiler itself. This has made it very easy for esbuild to publish native binary executables for many platforms. However, it strangely doesn't support cross-compiling to Android x64 without installing the Android build tools. So instead of publishing a native esbuild binary executable to npm, this release publishes a WebAssembly fallback build. This is essentially the same as the `esbuild-wasm` package but it's installed automatically when you install the `esbuild` package on Android x64. So packages that depend on the `esbuild` package should now work on Android x64. If you want to use a native binary executable of esbuild on Android x64, you may be able to build it yourself from source after installing the Android build tools.\n\n* Update to Go 1.17.8\n\n    The version of the Go compiler used to compile esbuild has been upgraded from Go 1.17.7 to Go 1.17.8, which fixes the RISC-V 64-bit build. Compiler optimizations for the RISC-V 64-bit build have now been re-enabled.\n\n## 0.14.24\n\n* Allow `es2022` as a target environment ([#2012](https://github.com/evanw/esbuild/issues/2012))\n\n    TypeScript recently [added support for `es2022`](https://devblogs.microsoft.com/typescript/announcing-typescript-4-6/#target-es2022) as a compilation target so esbuild now supports this too. Support for this is preliminary as there is no published ES2022 specification yet (i.e. https://tc39.es/ecma262/2021/ exists but https://tc39.es/ecma262/2022/ is a 404 error). The meaning of esbuild's `es2022` target may change in the future when the specification is finalized. Right now I have made the `es2022` target enable support for the syntax-related [finished proposals](https://github.com/tc39/proposals/blob/main/finished-proposals.md) that are marked as `2022`:\n\n    * Class fields\n    * Class private members\n    * Class static blocks\n    * Ergonomic class private member checks\n    * Top-level await\n\n    I have also included the \"arbitrary module namespace names\" feature since I'm guessing it will end up in the ES2022 specification (this syntax feature was added to the specification without a proposal). TypeScript has [not added support for this yet](https://github.com/microsoft/TypeScript/issues/40594).\n\n* Match `define` to strings in index expressions ([#2050](https://github.com/evanw/esbuild/issues/2050))\n\n    With this release, configuring `--define:foo.bar=baz` now matches and replaces both `foo.bar` and `foo['bar']` expressions in the original source code. This is necessary for people who have enabled TypeScript's [`noPropertyAccessFromIndexSignature` feature](https://www.typescriptlang.org/tsconfig#noPropertyAccessFromIndexSignature), which prevents you from using normal property access syntax on a type with an index signature such as in the following code:\n\n    ```ts\n    declare let foo: { [key: string]: any }\n    foo.bar // This is a type error if noPropertyAccessFromIndexSignature is enabled\n    foo['bar']\n    ```\n\n    Previously esbuild would generate the following output with `--define:foo.bar=baz`:\n\n    ```js\n    baz;\n    foo[\"bar\"];\n    ```\n\n    Now esbuild will generate the following output instead:\n\n    ```js\n    baz;\n    baz;\n    ```\n\n* Add `--mangle-quoted` to mangle quoted properties ([#218](https://github.com/evanw/esbuild/issues/218))\n\n    The `--mangle-props=` flag tells esbuild to automatically rename all properties matching the provided regular expression to shorter names to save space. Previously esbuild never modified the contents of string literals. In particular, `--mangle-props=_` would mangle `foo._bar` but not `foo['_bar']`. There are some coding patterns where renaming quoted property names is desirable, such as when using TypeScript's [`noPropertyAccessFromIndexSignature` feature](https://www.typescriptlang.org/tsconfig#noPropertyAccessFromIndexSignature) or when using TypeScript's [discriminated union narrowing behavior](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions):\n\n    ```ts\n    interface Foo { _foo: string }\n    interface Bar { _bar: number }\n    declare const value: Foo | Bar\n    console.log('_foo' in value ? value._foo : value._bar)\n    ```\n\n    The `'_foo' in value` check tells TypeScript to narrow the type of `value` to `Foo` in the true branch and to `Bar` in the false branch. Previously esbuild didn't mangle the property name `'_foo'` because it was inside a string literal. With this release, you can now use `--mangle-quoted` to also rename property names inside string literals:\n\n    ```js\n    // Old output (with --mangle-props=_)\n    console.log(\"_foo\" in value ? value.a : value.b);\n\n    // New output (with --mangle-props=_ --mangle-quoted)\n    console.log(\"a\" in value ? value.a : value.b);\n    ```\n\n* Parse and discard TypeScript `export as namespace` statements ([#2070](https://github.com/evanw/esbuild/issues/2070))\n\n    TypeScript `.d.ts` type declaration files can sometimes contain statements of the form `export as namespace foo;`. I believe these serve to declare that the module adds a property of that name to the global object. You aren't supposed to feed `.d.ts` files to esbuild so this normally doesn't matter, but sometimes esbuild can end up having to parse them. One such case is if you import a type-only package who's `main` field in `package.json` is a `.d.ts` file.\n\n    Previously esbuild only allowed `export as namespace` statements inside a `declare` context:\n\n    ```ts\n    declare module Foo {\n      export as namespace foo;\n    }\n    ```\n\n    Now esbuild will also allow these statements outside of a `declare` context:\n\n    ```ts\n    export as namespace foo;\n    ```\n\n    These statements are still just ignored and discarded.\n\n* Strip import assertions from unrecognized `import()` expressions ([#2036](https://github.com/evanw/esbuild/issues/2036))\n\n    The new \"import assertions\" JavaScript language feature adds an optional second argument to dynamic `import()` expressions, which esbuild does support. However, this optional argument must be stripped when targeting older JavaScript environments for which this second argument would be a syntax error. Previously esbuild failed to strip this second argument in cases when the first argument to `import()` wasn't a string literal. This problem is now fixed:\n\n    ```js\n    // Original code\n    console.log(import(foo, { assert: { type: 'json' } }))\n\n    // Old output (with --target=es6)\n    console.log(import(foo, { assert: { type: \"json\" } }));\n\n    // New output (with --target=es6)\n    console.log(import(foo));\n    ```\n\n* Remove simplified statement-level literal expressions ([#2063](https://github.com/evanw/esbuild/issues/2063))\n\n    With this release, esbuild now removes simplified statement-level expressions if the simplified result is a literal expression even when minification is disabled. Previously this was only done when minification is enabled. This change was only made because some people are bothered by seeing top-level literal expressions. This change has no effect on code behavior.\n\n* Ignore `.d.ts` rules in `paths` in `tsconfig.json` files ([#2074](https://github.com/evanw/esbuild/issues/2074), [#2075](https://github.com/evanw/esbuild/pull/2075))\n\n    TypeScript's `tsconfig.json` configuration file has a `paths` field that lets you remap import paths to alternative files on the file system. This field is interpreted by esbuild during bundling so that esbuild's behavior matches that of the TypeScript type checker. However, people sometimes override import paths to JavaScript files to instead point to a `.d.ts` TypeScript type declaration file for that JavaScript file. The intent of this is to just use the remapping for type information and not to actually import the `.d.ts` file during the build.\n\n    With this release, esbuild will now ignore rules in `paths` that result in a `.d.ts` file during path resolution. This means code that does this should now be able to be bundled without modifying its `tsconfig.json` file to remove the `.d.ts` rule. This change was contributed by [@magic-akari](https://github.com/magic-akari).\n\n* Disable Go compiler optimizations for the Linux RISC-V 64bit build ([#2035](https://github.com/evanw/esbuild/pull/2035))\n\n    Go's RISC-V 64bit compiler target has a fatal compiler optimization bug that causes esbuild to crash when it's run: https://github.com/golang/go/issues/51101. As a temporary workaround until a version of the Go compiler with the fix is published, Go compiler optimizations have been disabled for RISC-V. The 7.7mb esbuild binary executable for RISC-V is now 8.7mb instead. This workaround was contributed by [@piggynl](https://github.com/piggynl).\n\n## 0.14.23\n\n* Update feature database to indicate that node 16.14+ supports import assertions ([#2030](https://github.com/evanw/esbuild/issues/2030))\n\n    Node versions 16.14 and above now support import assertions according to [these release notes](https://github.com/nodejs/node/blob/6db686710ee1579452b2908a7a41b91cb729b944/doc/changelogs/CHANGELOG_V16.md#16.14.0). This release updates esbuild's internal feature compatibility database with this information, so esbuild no longer strips import assertions with `--target=node16.14`:\n\n    ```js\n    // Original code\n    import data from './package.json' assert { type: 'json' }\n    console.log(data)\n\n    // Old output (with --target=node16.14)\n    import data from \"./package.json\";\n    console.log(data);\n\n    // New output (with --target=node16.14)\n    import data from \"./package.json\" assert { type: \"json\" };\n    console.log(data);\n    ```\n\n* Basic support for CSS `@layer` rules ([#2027](https://github.com/evanw/esbuild/issues/2027))\n\n    This adds basic parsing support for a new CSS feature called `@layer` that changes how the CSS cascade works. Adding parsing support for this rule to esbuild means esbuild can now minify the contents of `@layer` rules:\n\n    ```css\n    /* Original code */\n    @layer a {\n      @layer b {\n        div {\n          color: yellow;\n          margin: 0.0px;\n        }\n      }\n    }\n\n    /* Old output (with --minify) */\n    @layer a{@layer b {div {color: yellow; margin: 0px;}}}\n\n    /* New output (with --minify) */\n    @layer a.b{div{color:#ff0;margin:0}}\n    ```\n\n    You can read more about `@layer` here:\n\n    * Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/@layer\n    * Motivation: https://developer.chrome.com/blog/cascade-layers/\n\n    Note that the support added in this release is only for parsing and printing `@layer` rules. The bundler does not yet know about these rules and bundling with `@layer` may result in behavior changes since these new rules have unusual ordering constraints that behave differently than all other CSS rules. Specifically the order is derived from the _first_ instance while with every other CSS rule, the order is derived from the _last_ instance.\n\n## 0.14.22\n\n* Preserve whitespace for token lists that look like CSS variable declarations ([#2020](https://github.com/evanw/esbuild/issues/2020))\n\n    Previously esbuild removed the whitespace after the CSS variable declaration in the following CSS:\n\n    ```css\n    /* Original input */\n    @supports (--foo: ){html{background:green}}\n\n    /* Previous output */\n    @supports (--foo:){html{background:green}}\n    ```\n\n    However, that broke rendering in Chrome as it caused Chrome to ignore the entire rule. This did not break rendering in Firefox and Safari, so there's a browser bug either with Chrome or with both Firefox and Safari. In any case, esbuild now preserves whitespace after the CSS variable declaration in this case.\n\n* Ignore legal comments when merging adjacent duplicate CSS rules ([#2016](https://github.com/evanw/esbuild/issues/2016))\n\n    This release now generates more compact minified CSS when there are legal comments in between two adjacent rules with identical content:\n\n    ```css\n    /* Original code */\n    a { color: red }\n    /* @preserve */\n    b { color: red }\n\n    /* Old output (with --minify) */\n    a{color:red}/* @preserve */b{color:red}\n\n    /* New output (with --minify) */\n    a,b{color:red}/* @preserve */\n    ```\n\n* Block `onResolve` and `onLoad` until `onStart` ends ([#1967](https://github.com/evanw/esbuild/issues/1967))\n\n    This release changes the semantics of the `onStart` callback. All `onStart` callbacks from all plugins are run concurrently so that a slow plugin doesn't hold up the entire build. That's still the case. However, previously the only thing waiting for the `onStart` callbacks to finish was the end of the build. This meant that `onResolve` and/or `onLoad` callbacks could sometimes run before `onStart` had finished. This was by design but violated user expectations. With this release, all `onStart` callbacks must finish before any `onResolve` and/or `onLoad` callbacks are run.\n\n* Add a self-referential `default` export to the JS API ([#1897](https://github.com/evanw/esbuild/issues/1897))\n\n    Some people try to use esbuild's API using `import esbuild from 'esbuild'` instead of `import * as esbuild from 'esbuild'` (i.e. using a default import instead of a namespace import). There is no `default` export so that wasn't ever intended to work. But it would work sometimes depending on which tools you used and how they were configured so some people still wrote code this way. This release tries to make that work by adding a self-referential `default` export that is equal to esbuild's module namespace object.\n\n    More detail: The published package for esbuild's JS API is in CommonJS format, although the source code for esbuild's JS API is in ESM format. The original ESM code for esbuild's JS API has no export named `default` so using a default import like this doesn't work with Babel-compatible toolchains (since they respect the semantics of the original ESM code). However, it happens to work with node-compatible toolchains because node's implementation of importing CommonJS from ESM broke compatibility with existing conventions and automatically creates a `default` export which is set to `module.exports`. This is an unfortunate compatibility headache because it means the `default` import only works sometimes. This release tries to fix this by explicitly creating a self-referential `default` export. It now doesn't matter if you do `esbuild.build()`, `esbuild.default.build()`, or `esbuild.default.default.build()` because they should all do the same thing. Hopefully this means people don't have to deal with this problem anymore.\n\n* Handle `write` errors when esbuild's child process is killed ([#2007](https://github.com/evanw/esbuild/issues/2007))\n\n    If you type Ctrl+C in a terminal when a script that uses esbuild's JS library is running, esbuild's child process may be killed before the parent process. In that case calls to the `write()` syscall may fail with an `EPIPE` error. Previously this resulted in an uncaught exception because esbuild didn't handle this case. Starting with this release, esbuild should now catch these errors and redirect them into a general `The service was stopped` error which should be returned from whatever top-level API calls were in progress.\n\n* Better error message when browser WASM bugs are present ([#1863](https://github.com/evanw/esbuild/issues/1863))\n\n    Safari's WebAssembly implementation appears to be broken somehow, at least when running esbuild. Sometimes this manifests as a stack overflow and sometimes as a Go panic. Previously a Go panic resulted in the error message `Can't find variable: fs` but this should now result in the Go panic being printed to the console. Using esbuild's WebAssembly library in Safari is still broken but now there's a more helpful error message.\n\n    More detail: When Go panics, it prints a stack trace to stderr (i.e. file descriptor 2). Go's WebAssembly shim calls out to node's `fs.writeSync()` function to do this, and it converts calls to `fs.writeSync()` into calls to `console.log()` in the browser by providing a shim for `fs`. However, Go's shim code stores the shim on `window.fs` in the browser. This is undesirable because it pollutes the global scope and leads to brittle code that can break if other code also uses `window.fs`. To avoid this, esbuild shadows the global object by wrapping Go's shim. But that broke bare references to `fs` since the shim is no longer stored on `window.fs`. This release now stores the shim in a local variable named `fs` so that bare references to `fs` work correctly.\n\n* Undo incorrect dead-code elimination with destructuring ([#1183](https://github.com/evanw/esbuild/issues/1183))\n\n    Previously esbuild eliminated these statements as dead code if tree-shaking was enabled:\n\n    ```js\n    let [a] = {}\n    let { b } = null\n    ```\n\n    This is incorrect because both of these lines will throw an error when evaluated. With this release, esbuild now preserves these statements even when tree shaking is enabled.\n\n* Update to Go 1.17.7\n\n    The version of the Go compiler used to compile esbuild has been upgraded from Go 1.17.6 to Go 1.17.7, which contains a few [compiler and security bug fixes](https://github.com/golang/go/issues?q=milestone%3AGo1.17.7+label%3ACherryPickApproved).\n\n## 0.14.21\n\n* Handle an additional `browser` map edge case ([#2001](https://github.com/evanw/esbuild/pull/2001), [#2002](https://github.com/evanw/esbuild/issues/2002))\n\n    There is a community convention around the `browser` field in `package.json` that allows remapping import paths within a package when the package is bundled for use within a browser. There isn't a rigorous definition of how it's supposed to work and every bundler implements it differently. The approach esbuild uses is to try to be \"maximally compatible\" in that if at least one bundler exhibits a particular behavior regarding the `browser` map that allows a mapping to work, then esbuild also attempts to make that work.\n\n    I have a collection of test cases for this going here: https://github.com/evanw/package-json-browser-tests. However, I was missing test coverage for the edge case where a package path import in a subdirectory of the package could potentially match a remapping. The \"maximally compatible\" approach means replicating bugs in Browserify's implementation of the feature where package paths are mistaken for relative paths and are still remapped. Here's a specific example of an edge case that's now handled:\n\n    * `entry.js`:\n\n        ```js\n        require('pkg/sub')\n        ```\n\n    * `node_modules/pkg/package.json`:\n\n        ```json\n        {\n          \"browser\": {\n            \"./sub\": \"./sub/foo.js\",\n            \"./sub/sub\": \"./sub/bar.js\"\n          }\n        }\n        ```\n\n    * `node_modules/pkg/sub/foo.js`:\n\n        ```js\n        require('sub')\n        ```\n\n    * `node_modules/pkg/sub/bar.js`:\n\n        ```js\n        console.log('works')\n        ```\n\n    The import path `sub` in `require('sub')` is mistaken for a relative path by Browserify due to a bug in Browserify, so Browserify treats it as if it were `./sub` instead. This is a Browserify-specific behavior and currently doesn't happen in any other bundler (except for esbuild, which attempts to replicate Browserify's bug).\n\n    Previously esbuild was incorrectly resolving `./sub` relative to the top-level package directory instead of to the subdirectory in this case, which meant `./sub` was incorrectly matching `\"./sub\": \"./sub/foo.js\"` instead of `\"./sub/sub\": \"./sub/bar.js\"`. This has been fixed so esbuild can now emulate Browserify's bug correctly in this edge case.\n\n* Support for esbuild with Linux on RISC-V 64bit ([#2000](https://github.com/evanw/esbuild/pull/2000))\n\n    With this release, esbuild now has a published binary executable for the RISC-V 64bit architecture in the [`esbuild-linux-riscv64`](https://www.npmjs.com/package/esbuild-linux-riscv64) npm package. This change was contributed by [@piggynl](https://github.com/piggynl).\n\n## 0.14.20\n\n* Fix property mangling and keyword properties ([#1998](https://github.com/evanw/esbuild/issues/1998))\n\n    Previously enabling property mangling with `--mangle-props=` failed to add a space before property names after a keyword. This bug has been fixed:\n\n    ```js\n    // Original code\n    class Foo {\n      static foo = {\n        get bar() {}\n      }\n    }\n\n    // Old output (with --minify --mangle-props=.)\n    class Foo{statics={gett(){}}}\n\n    // New output (with --minify --mangle-props=.)\n    class Foo{static s={get t(){}}}\n    ```\n\n## 0.14.19\n\n* Special-case `const` inlining at the top of a scope ([#1317](https://github.com/evanw/esbuild/issues/1317), [#1981](https://github.com/evanw/esbuild/issues/1981))\n\n    The minifier now inlines `const` variables (even across modules during bundling) if a certain set of specific requirements are met:\n\n    * All `const` variables to be inlined are at the top of their scope\n    * That scope doesn't contain any `import` or `export` statements with paths\n    * All constants to be inlined are `null`, `undefined`, `true`, `false`, an integer, or a short real number\n    * Any expression outside of a small list of allowed ones stops constant identification\n\n    Practically speaking this basically means that you can trigger this optimization by just putting the constants you want inlined into a separate file (e.g. `constants.js`) and bundling everything together.\n\n    These specific conditions are present to avoid esbuild unintentionally causing any behavior changes by inlining constants when the variable reference could potentially be evaluated before being declared. It's possible to identify more cases where constants can be inlined but doing so may require complex call graph analysis so it has not been implemented. Although these specific heuristics may change over time, this general approach to constant inlining should continue to work going forward.\n\n    Here's an example:\n\n    ```js\n    // Original code\n    const bold = 1 << 0;\n    const italic = 1 << 1;\n    const underline = 1 << 2;\n    const font = bold | italic | underline;\n    console.log(font);\n\n    // Old output (with --minify --bundle)\n    (()=>{var o=1<<0,n=1<<1,c=1<<2,t=o|n|c;console.log(t);})();\n\n    // New output (with --minify --bundle)\n    (()=>{console.log(7);})();\n    ```\n\n## 0.14.18\n\n* Add the `--mangle-cache=` feature ([#1977](https://github.com/evanw/esbuild/issues/1977))\n\n    This release adds a cache API for the newly-released `--mangle-props=` feature. When enabled, all mangled property renamings are recorded in the cache during the initial build. Subsequent builds reuse the renamings stored in the cache and add additional renamings for any newly-added properties. This has a few consequences:\n\n    * You can customize what mangled properties are renamed to by editing the cache before passing it to esbuild (the cache is a map of the original name to the mangled name).\n\n    * The cache serves as a list of all properties that were mangled. You can easily scan it to see if there are any unexpected property renamings.\n\n    * You can disable mangling for individual properties by setting the renamed value to `false` instead of to a string. This is similar to the `--reserve-props=` setting but on a per-property basis.\n\n    * You can ensure consistent renaming between builds (e.g. a main-thread file and a web worker, or a library and a plugin). Without this feature, each build would do an independent renaming operation and the mangled property names likely wouldn't be consistent.\n\n    Here's how to use it:\n\n    * CLI\n\n        ```sh\n        $ esbuild example.ts --mangle-props=_$ --mangle-cache=cache.json\n        ```\n\n    * JS API\n\n        ```js\n        let result = await esbuild.build({\n          entryPoints: ['example.ts'],\n          mangleProps: /_$/,\n          mangleCache: {\n            customRenaming_: '__c',\n            disabledRenaming_: false,\n          },\n        })\n        let updatedMangleCache = result.mangleCache\n        ```\n\n    * Go API\n\n        ```go\n        result := api.Build(api.BuildOptions{\n          EntryPoints: []string{\"example.ts\"},\n          MangleProps: \"_$\",\n          MangleCache: map[string]interface{}{\n            \"customRenaming_\":   \"__c\",\n            \"disabledRenaming_\": false,\n          },\n        })\n        updatedMangleCache := result.MangleCache\n        ```\n\n    The above code would do something like the following:\n\n    ```js\n    // Original code\n    x = {\n      customRenaming_: 1,\n      disabledRenaming_: 2,\n      otherProp_: 3,\n    }\n\n    // Generated code\n    x = {\n      __c: 1,\n      disabledRenaming_: 2,\n      a: 3\n    };\n\n    // Updated mangle cache\n    {\n      \"customRenaming_\": \"__c\",\n      \"disabledRenaming_\": false,\n      \"otherProp_\": \"a\"\n    }\n    ```\n\n* Add `opera` and `ie` as possible target environments\n\n    You can now target [Opera](https://www.opera.com/) and/or [Internet Explorer](https://www.microsoft.com/en-us/download/internet-explorer.aspx) using the `--target=` setting. For example, `--target=opera45,ie9` targets Opera 45 and Internet Explorer 9. This change does not add any additional features to esbuild's code transformation pipeline to transform newer syntax so that it works in Internet Explorer. It just adds information about what features are supported in these browsers to esbuild's internal feature compatibility table.\n\n* Minify `typeof x !== 'undefined'` to `typeof x < 'u'`\n\n    This release introduces a small improvement for code that does a lot of `typeof` checks against `undefined`:\n\n    ```js\n    // Original code\n    y = typeof x !== 'undefined';\n\n    // Old output (with --minify)\n    y=typeof x!=\"undefined\";\n\n    // New output (with --minify)\n    y=typeof x<\"u\";\n    ```\n\n    This transformation is only active when minification is enabled, and is disabled if the language target is set lower than ES2020 or if Internet Explorer is set as a target environment. Before ES2020, implementations were allowed to return non-standard values from the `typeof` operator for a few objects. Internet Explorer took advantage of this to sometimes return the string `'unknown'` instead of `'undefined'`. But this has been removed from the specification and Internet Explorer was the only engine to do this, so this minification is valid for code that does not need to target Internet Explorer.\n\n## 0.14.17\n\n* Attempt to fix an install script issue on Ubuntu Linux ([#1711](https://github.com/evanw/esbuild/issues/1711))\n\n    There have been some reports of esbuild failing to install on Ubuntu Linux for a while now. I haven't been able to reproduce this myself due to lack of reproduction instructions until today, when I learned that the issue only happens when you install node from the [Snap Store](https://snapcraft.io/) instead of downloading the [official version of node](https://nodejs.org/dist/).\n\n    The problem appears to be that when node is installed from the Snap Store, install scripts are run with stderr not being writable? This then appears to cause a problem for esbuild's install script when it uses `execFileSync` to validate that the esbuild binary is working correctly. This throws the error `EACCES: permission denied, write` even though this particular command never writes to stderr.\n\n    Node's documentation says that stderr for `execFileSync` defaults to that of the parent process. Forcing it to `'pipe'` instead appears to fix the issue, although I still don't fully understand what's happening or why. I'm publishing this small change regardless to see if it fixes this install script edge case.\n\n* Avoid a syntax error due to `--mangle-props=.` and `super()` ([#1976](https://github.com/evanw/esbuild/issues/1976))\n\n    This release fixes an issue where passing `--mangle-props=.` (i.e. telling esbuild to mangle every single property) caused a syntax error with code like this:\n\n    ```js\n    class Foo {}\n    class Bar extends Foo {\n      constructor() {\n        super();\n      }\n    }\n    ```\n\n    The problem was that `constructor` was being renamed to another method, which then made it no longer a constructor, which meant that `super()` was now a syntax error. I have added a workaround that avoids renaming any property named `constructor` so that esbuild doesn't generate a syntax error here.\n\n    Despite this fix, I highly recommend not using `--mangle-props=.` because your code will almost certainly be broken. You will have to manually add every single property that you don't want mangled to `--reserve-props=` which is an excessive maintenance burden (e.g. reserve `parse` to use `JSON.parse`). Instead I recommend using a common pattern for all properties you intend to be mangled that is unlikely to appear in the APIs you use such as \"ends in an underscore.\" This is an opt-in approach instead of an opt-out approach. It also makes it obvious when reading the code which properties will be mangled and which ones won't be.\n\n## 0.14.16\n\n* Support property name mangling with some TypeScript syntax features\n\n    The newly-released `--mangle-props=` feature previously only affected JavaScript syntax features. This release adds support for using mangle props with certain TypeScript syntax features:\n\n    * **TypeScript parameter properties**\n\n        Parameter properties are a TypeScript-only shorthand way of initializing a class field directly from the constructor argument list. Previously parameter properties were not treated as properties to be mangled. They should now be handled correctly:\n\n        ```ts\n        // Original code\n        class Foo {\n          constructor(public foo_) {}\n        }\n        new Foo().foo_;\n\n        // Old output (with --minify --mangle-props=_)\n        class Foo{constructor(c){this.foo_=c}}new Foo().o;\n\n        // New output (with --minify --mangle-props=_)\n        class Foo{constructor(o){this.c=o}}new Foo().c;\n        ```\n\n    * **TypeScript namespaces**\n\n        Namespaces are a TypeScript-only way to add properties to an object. Previously exported namespace members were not treated as properties to be mangled. They should now be handled correctly:\n\n        ```ts\n        // Original code\n        namespace ns {\n          export let foo_ = 1;\n          export function bar_(x) {}\n        }\n        ns.bar_(ns.foo_);\n\n        // Old output (with --minify --mangle-props=_)\n        var ns;(e=>{e.foo_=1;function t(a){}e.bar_=t})(ns||={}),ns.e(ns.o);\n\n        // New output (with --minify --mangle-props=_)\n        var ns;(e=>{e.e=1;function o(p){}e.t=o})(ns||={}),ns.t(ns.e);\n        ```\n\n* Fix property name mangling for lowered class fields\n\n    This release fixes a compiler crash with `--mangle-props=` and class fields that need to be transformed to older versions of JavaScript. The problem was that doing this is an unusual case where the mangled property name must be represented as a string instead of as a property name, which previously wasn't implemented. This case should now work correctly:\n\n    ```js\n    // Original code\n    class Foo {\n      static foo_;\n    }\n    Foo.foo_ = 0;\n\n    // New output (with --mangle-props=_ --target=es6)\n    class Foo {\n    }\n    __publicField(Foo, \"a\");\n    Foo.a = 0;\n    ```\n\n## 0.14.15\n\n* Add property name mangling with `--mangle-props=` ([#218](https://github.com/evanw/esbuild/issues/218))\n\n    ⚠️ **Using this feature can break your code in subtle ways.** Do not use this feature unless you know what you are doing, and you know exactly how it will affect both your code and all of your dependencies. ⚠️\n\n    This release introduces property name mangling, which is similar to an existing feature from the popular [UglifyJS](github.com/mishoo/uglifyjs) and [Terser](github.com/terser/terser) JavaScript minifiers. This setting lets you pass a regular expression to esbuild to tell esbuild to automatically rename all properties that match this regular expression. It's useful when you want to minify certain property names in your code either to make the generated code smaller or to somewhat obfuscate your code's intent.\n\n    Here's an example that uses the regular expression `_$` to mangle all properties ending in an underscore, such as `foo_`:\n\n    ```\n    $ echo 'console.log({ foo_: 0 }.foo_)' | esbuild --mangle-props=_$\n    console.log({ a: 0 }.a);\n    ```\n\n    Only mangling properties that end in an underscore is a reasonable heuristic because normal JS code doesn't typically contain identifiers like that. Browser APIs also don't use this naming convention so this also avoids conflicts with browser APIs. If you want to avoid mangling names such as [`__defineGetter__`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/__defineGetter__) you could consider using a more complex regular expression such as `[^_]_$` (i.e. must end in a non-underscore followed by an underscore).\n\n    This is a separate setting instead of being part of the minify setting because it's an unsafe transformation that does not work on arbitrary JavaScript code. It only works if the provided regular expression matches all of the properties that you want mangled and does not match any of the properties that you don't want mangled. It also only works if you do not under any circumstances reference a property name to be mangled as a string. For example, it means you can't use `Object.defineProperty(obj, 'prop', ...)` or `obj['prop']` with a mangled property. Specifically the following syntax constructs are the only ones eligible for property mangling:\n\n    | Syntax                          | Example                 |\n    |---------------------------------|-------------------------|\n    | Dot property access             | `x.foo_`                |\n    | Dot optional chain              | `x?.foo_`               |\n    | Object properties               | `x = { foo_: y }`       |\n    | Object methods                  | `x = { foo_() {} }`     |\n    | Class fields                    | `class x { foo_ = y }`  |\n    | Class methods                   | `class x { foo_() {} }` |\n    | Object destructuring binding    | `let { foo_: x } = y`   |\n    | Object destructuring assignment | `({ foo_: x } = y)`     |\n    | JSX element names               | `<X.foo_></X.foo_>`     |\n    | JSX attribute names             | `<X foo_={y} />`        |\n\n    You can avoid property mangling for an individual property by quoting it as a string. However, you must consistently use quotes or no quotes for a given property everywhere for this to work. For example, `print({ foo_: 0 }.foo_)` will be mangled into `print({ a: 0 }.a)` while `print({ 'foo_': 0 }['foo_'])` will not be mangled.\n\n    When using this feature, keep in mind that property names are only consistently mangled within a single esbuild API call but not across esbuild API calls. Each esbuild API call does an independent property mangling operation so output files generated by two different API calls may mangle the same property to two different names, which could cause the resulting code to behave incorrectly.\n\n    If you would like to exclude certain properties from mangling, you can reserve them with the `--reserve-props=` setting. For example, this uses the regular expression `^__.*__$` to reserve all properties that start and end with two underscores, such as `__foo__`:\n\n    ```\n    $ echo 'console.log({ __foo__: 0 }.__foo__)' | esbuild --mangle-props=_$\n    console.log({ a: 0 }.a);\n\n    $ echo 'console.log({ __foo__: 0 }.__foo__)' | esbuild --mangle-props=_$ \"--reserve-props=^__.*__$\"\n    console.log({ __foo__: 0 }.__foo__);\n    ```\n\n* Mark esbuild as supporting node v12+ ([#1970](https://github.com/evanw/esbuild/issues/1970))\n\n    Someone requested that esbuild populate the `engines.node` field in `package.json`. This release adds the following to each `package.json` file that esbuild publishes:\n\n    ```json\n    \"engines\": {\n      \"node\": \">=12\"\n    },\n    ```\n\n    This was chosen because it's the oldest version of node that's currently still receiving support from the node team, and so is the oldest version of node that esbuild supports: https://nodejs.org/en/about/releases/.\n\n* Remove error recovery for invalid `//` comments in CSS ([#1965](https://github.com/evanw/esbuild/issues/1965))\n\n    Previously esbuild treated `//` as a comment in CSS and generated a warning, even though comments in CSS use `/* ... */` instead. This allowed you to run esbuild on CSS intended for certain CSS preprocessors that support single-line comments.\n\n    However, some people are changing from another build tool to esbuild and have a code base that relies on `//` being preserved even though it's nonsense CSS and causes the entire surrounding rule to be discarded by the browser. Presumably this nonsense CSS ended up there at some point due to an incorrectly-configured build pipeline and the site now relies on that entire rule being discarded. If esbuild interprets `//` as a comment, it could cause the rule to no longer be discarded or even cause something else to happen.\n\n    With this release, esbuild no longer treats `//` as a comment in CSS. It still warns about it but now passes it through unmodified. This means it's no longer possible to run esbuild on CSS code containing single-line comments but it means that esbuild's behavior regarding these nonsensical CSS rules more accurately represents what happens in a browser.\n\n## 0.14.14\n\n* Fix bug with filename hashes and the `file` loader ([#1957](https://github.com/evanw/esbuild/issues/1957))\n\n    This release fixes a bug where if a file name template has the `[hash]` placeholder (either `--entry-names=` or `--chunk-names=`), the hash that esbuild generates didn't include the content of the string generated by the `file` loader. Importing a file with the `file` loader causes the imported file to be copied to the output directory and causes the imported value to be the relative path from the output JS file to that copied file. This bug meant that if the `--asset-names=` setting also contained `[hash]` and the file loaded with the `file` loader was changed, the hash in the copied file name would change but the hash of the JS file would not change, which could potentially result in a stale JS file being loaded. Now the hash of the JS file will be changed too which fixes the reload issue.\n\n* Prefer the `import` condition for entry points ([#1956](https://github.com/evanw/esbuild/issues/1956))\n\n    The `exports` field in `package.json` maps package subpaths to file paths. The mapping can be conditional, which lets it vary in different situations. For example, you can have an `import` condition that applies when the subpath originated from a JS import statement, and a `require` condition that applies when the subpath originated from a JS require call. These are supposed to be mutually exclusive according to the specification: https://nodejs.org/api/packages.html#conditional-exports.\n\n    However, there's a situation with esbuild where it's not immediately obvious which one should be applied: when a package name is specified as an entry point. For example, this can happen if you do `esbuild --bundle some-pkg` on the command line. In this situation `some-pkg` does not originate from either a JS import statement or a JS require call. Previously esbuild just didn't apply the `import` or `require` conditions. But that could result in path resolution failure if the package doesn't provide a back-up `default` condition, as is the case with the `is-plain-object` package.\n\n    Starting with this release, esbuild will now use the `import` condition in this case. This appears to be how Webpack and Rollup handle this situation so this change makes esbuild consistent with other tools in the ecosystem. Parcel (the other major bundler) just doesn't handle this case at all so esbuild's behavior is not at odds with Parcel's behavior here.\n\n* Make parsing of invalid `@keyframes` rules more robust ([#1959](https://github.com/evanw/esbuild/issues/1959))\n\n    This improves esbuild's parsing of certain malformed `@keyframes` rules to avoid them affecting the following rule. This fix only affects invalid CSS files, and does not change any behavior for files containing valid CSS. Here's an example of the fix:\n\n    ```css\n    /* Original code */\n    @keyframes x { . }\n    @keyframes y { 1% { a: b; } }\n\n    /* Old output (with --minify) */\n    @keyframes x{y{1% {a: b;}}}\n\n    /* New output (with --minify) */\n    @keyframes x{.}@keyframes y{1%{a:b}}\n    ```\n\n## 0.14.13\n\n* Be more consistent about external paths ([#619](https://github.com/evanw/esbuild/issues/619))\n\n    The rules for marking paths as external using `--external:` grew over time as more special-cases were added. This release reworks the internal representation to be more straightforward and robust. A side effect is that wildcard patterns can now match post-resolve paths in addition to pre-resolve paths. Specifically you can now do `--external:./node_modules/*` to mark all files in the `./node_modules/` directory as external.\n\n    This is the updated logic:\n\n    * Before path resolution begins, import paths are checked against everything passed via an `--external:` flag. In addition, if something looks like a package path (i.e. doesn't start with `/` or `./` or `../`), import paths are checked to see if they have that package path as a path prefix (so `--external:@foo/bar` matches the import path `@foo/bar/baz`).\n\n    * After path resolution ends, the absolute paths are checked against everything passed via `--external:` that doesn't look like a package path (i.e. that starts with `/` or `./` or `../`). But before checking, the pattern is transformed to be relative to the current working directory.\n\n* Attempt to explain why esbuild can't run ([#1819](https://github.com/evanw/esbuild/issues/1819))\n\n    People sometimes try to install esbuild on one OS and then copy the `node_modules` directory over to another OS without reinstalling. This works with JavaScript code but doesn't work with esbuild because esbuild is a native binary executable. This release attempts to offer a helpful error message when this happens. It looks like this:\n\n    ```\n    $ ./node_modules/.bin/esbuild\n    ./node_modules/esbuild/bin/esbuild:106\n              throw new Error(`\n              ^\n\n    Error:\n    You installed esbuild on another platform than the one you're currently using.\n    This won't work because esbuild is written with native code and needs to\n    install a platform-specific binary executable.\n\n    Specifically the \"esbuild-linux-arm64\" package is present but this platform\n    needs the \"esbuild-darwin-arm64\" package instead. People often get into this\n    situation by installing esbuild on Windows or macOS and copying \"node_modules\"\n    into a Docker image that runs Linux, or by copying \"node_modules\" between\n    Windows and WSL environments.\n\n    If you are installing with npm, you can try not copying the \"node_modules\"\n    directory when you copy the files over, and running \"npm ci\" or \"npm install\"\n    on the destination platform after the copy. Or you could consider using yarn\n    instead which has built-in support for installing a package on multiple\n    platforms simultaneously.\n\n    If you are installing with yarn, you can try listing both this platform and the\n    other platform in your \".yarnrc.yml\" file using the \"supportedArchitectures\"\n    feature: https://yarnpkg.com/configuration/yarnrc/#supportedArchitectures\n    Keep in mind that this means multiple copies of esbuild will be present.\n\n    Another alternative is to use the \"esbuild-wasm\" package instead, which works\n    the same way on all platforms. But it comes with a heavy performance cost and\n    can sometimes be 10x slower than the \"esbuild\" package, so you may also not\n    want to do that.\n\n        at generateBinPath (./node_modules/esbuild/bin/esbuild:106:17)\n        at Object.<anonymous> (./node_modules/esbuild/bin/esbuild:161:39)\n        at Module._compile (node:internal/modules/cjs/loader:1101:14)\n        at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)\n        at Module.load (node:internal/modules/cjs/loader:981:32)\n        at Function.Module._load (node:internal/modules/cjs/loader:822:12)\n        at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)\n        at node:internal/main/run_main_module:17:47\n    ```\n\n## 0.14.12\n\n* Ignore invalid `@import` rules in CSS ([#1946](https://github.com/evanw/esbuild/issues/1946))\n\n    In CSS, `@import` rules must come first before any other kind of rule (except for `@charset` rules). Previously esbuild would warn about incorrectly ordered `@import` rules and then hoist them to the top of the file. This broke people who wrote invalid `@import` rules in the middle of their files and then relied on them being ignored. With this release, esbuild will now ignore invalid `@import` rules and pass them through unmodified. This more accurately follows the CSS specification. Note that this behavior differs from other tools like Parcel, which does hoist CSS `@import` rules.\n\n* Print invalid CSS differently ([#1947](https://github.com/evanw/esbuild/issues/1947))\n\n    This changes how esbuild prints nested `@import` statements that are missing a trailing `;`, which is invalid CSS. The result is still partially invalid CSS, but now printed in a better-looking way:\n\n    ```css\n    /* Original code */\n    .bad { @import url(\"other\") }\n    .red { background: red; }\n\n    /* Old output (with --minify) */\n    .bad{@import url(other) } .red{background: red;}}\n\n    /* New output (with --minify) */\n    .bad{@import url(other);}.red{background:red}\n    ```\n\n* Warn about CSS nesting syntax ([#1945](https://github.com/evanw/esbuild/issues/1945))\n\n    There's a proposed [CSS syntax for nesting rules](https://drafts.csswg.org/css-nesting/) using the `&` selector, but it's not currently implemented in any browser. Previously esbuild silently passed the syntax through untransformed. With this release, esbuild will now warn when you use nesting syntax with a `--target=` setting that includes a browser.\n\n* Warn about `}` and `>` inside JSX elements\n\n    The `}` and `>` characters are invalid inside JSX elements according to [the JSX specification](https://facebook.github.io/jsx/) because they commonly result from typos like these that are hard to catch in code reviews:\n\n    ```jsx\n    function F() {\n      return <div>></div>;\n    }\n    function G() {\n      return <div>{1}}</div>;\n    }\n    ```\n\n    The TypeScript compiler already [treats this as an error](https://github.com/microsoft/TypeScript/issues/36341), so esbuild now treats this as an error in TypeScript files too. That looks like this:\n\n    ```\n    ✘ [ERROR] The character \">\" is not valid inside a JSX element\n\n        example.tsx:2:14:\n          2 │   return <div>></div>;\n            │               ^\n            ╵               {'>'}\n\n      Did you mean to escape it as \"{'>'}\" instead?\n\n    ✘ [ERROR] The character \"}\" is not valid inside a JSX element\n\n        example.tsx:5:17:\n          5 │   return <div>{1}}</div>;\n            │                  ^\n            ╵                  {'}'}\n\n      Did you mean to escape it as \"{'}'}\" instead?\n    ```\n\n    Babel doesn't yet treat this as an error, so esbuild only warns about these characters in JavaScript files for now. Babel 8 [treats this as an error](https://github.com/babel/babel/issues/11042) but Babel 8 [hasn't been released yet](https://github.com/babel/babel/issues/10746). If you see this warning, I recommend fixing the invalid JSX syntax because it will become an error in the future.\n\n* Warn about basic CSS property typos\n\n    This release now generates a warning if you use a CSS property that is one character off from a known CSS property:\n\n    ```\n    ▲ [WARNING] \"marign-left\" is not a known CSS property\n\n        example.css:2:2:\n          2 │   marign-left: 12px;\n            │   ~~~~~~~~~~~\n            ╵   margin-left\n\n      Did you mean \"margin-left\" instead?\n    ```\n\n## 0.14.11\n\n* Fix a bug with enum inlining ([#1903](https://github.com/evanw/esbuild/issues/1903))\n\n    The new TypeScript enum inlining behavior had a bug where it worked correctly if you used `export enum Foo` but not if you used `enum Foo` and then later `export { Foo }`. This release fixes the bug so enum inlining now works correctly in this case.\n\n* Warn about `module.exports.foo = ...` in ESM ([#1907](https://github.com/evanw/esbuild/issues/1907))\n\n    The `module` variable is treated as a global variable reference instead of as a CommonJS module reference in ESM code, which can cause problems for people that try to use both CommonJS and ESM exports in the same file. There has been a warning about this since version 0.14.9. However, the warning only covered cases like `exports.foo = bar` and `module.exports = bar` but not `module.exports.foo = bar`. This last case is now handled;\n\n    ```\n    ▲ [WARNING] The CommonJS \"module\" variable is treated as a global variable in an ECMAScript module and may not work as expected\n\n        example.ts:2:0:\n          2 │ module.exports.b = 1\n            ╵ ~~~~~~\n\n      This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n\n        example.ts:1:0:\n          1 │ export let a = 1\n            ╵ ~~~~~~\n    ```\n\n* Enable esbuild's CLI with Deno ([#1913](https://github.com/evanw/esbuild/issues/1913))\n\n    This release allows you to use Deno as an esbuild installer, without also needing to use esbuild's JavaScript API. You can now use esbuild's CLI with Deno:\n\n    ```\n    deno run --allow-all \"https://deno.land/x/esbuild@v0.14.11/mod.js\" --version\n    ```\n"
  },
  {
    "path": "CHANGELOG-2023.md",
    "content": "# Changelog: 2023\n\nThis changelog documents all esbuild versions published in the year 2023 (versions 0.16.13 through 0.19.11).\n\n## 0.19.11\n\n* Fix TypeScript-specific class transform edge case ([#3559](https://github.com/evanw/esbuild/issues/3559))\n\n    The previous release introduced an optimization that avoided transforming `super()` in the class constructor for TypeScript code compiled with `useDefineForClassFields` set to `false` if all class instance fields have no initializers. The rationale was that in this case, all class instance fields are omitted in the output so no changes to the constructor are needed. However, if all of this is the case _and_ there are `#private` instance fields with initializers, those private instance field initializers were still being moved into the constructor. This was problematic because they were being inserted before the call to `super()` (since `super()` is now no longer transformed in that case). This release introduces an additional optimization that avoids moving the private instance field initializers into the constructor in this edge case, which generates smaller code, matches the TypeScript compiler's output more closely, and avoids this bug:\n\n    ```ts\n    // Original code\n    class Foo extends Bar {\n      #private = 1;\n      public: any;\n      constructor() {\n        super();\n      }\n    }\n\n    // Old output (with esbuild v0.19.9)\n    class Foo extends Bar {\n      constructor() {\n        super();\n        this.#private = 1;\n      }\n      #private;\n    }\n\n    // Old output (with esbuild v0.19.10)\n    class Foo extends Bar {\n      constructor() {\n        this.#private = 1;\n        super();\n      }\n      #private;\n    }\n\n    // New output\n    class Foo extends Bar {\n      #private = 1;\n      constructor() {\n        super();\n      }\n    }\n    ```\n\n* Minifier: allow reording a primitive past a side-effect ([#3568](https://github.com/evanw/esbuild/issues/3568))\n\n    The minifier previously allowed reordering a side-effect past a primitive, but didn't handle the case of reordering a primitive past a side-effect. This additional case is now handled:\n\n    ```js\n    // Original code\n    function f() {\n      let x = false;\n      let y = x;\n      const boolean = y;\n      let frag = $.template(`<p contenteditable=\"${boolean}\">hello world</p>`);\n      return frag;\n    }\n\n    // Old output (with --minify)\n    function f(){const e=!1;return $.template(`<p contenteditable=\"${e}\">hello world</p>`)}\n\n    // New output (with --minify)\n    function f(){return $.template('<p contenteditable=\"false\">hello world</p>')}\n    ```\n\n* Minifier: consider properties named using known `Symbol` instances to be side-effect free ([#3561](https://github.com/evanw/esbuild/issues/3561))\n\n    Many things in JavaScript can have side effects including property accesses and ToString operations, so using a symbol such as `Symbol.iterator` as a computed property name is not obviously side-effect free. This release adds a special case for known `Symbol` instances so that they are considered side-effect free when used as property names. For example, this class declaration will now be considered side-effect free:\n\n    ```js\n    class Foo {\n      *[Symbol.iterator]() {\n      }\n    }\n    ```\n\n* Provide the `stop()` API in node to exit esbuild's child process ([#3558](https://github.com/evanw/esbuild/issues/3558))\n\n    You can now call `stop()` in esbuild's node API to exit esbuild's child process to reclaim the resources used. It only makes sense to do this for a long-lived node process when you know you will no longer be making any more esbuild API calls. It is not necessary to call this to allow node to exit, and it's advantageous to not call this in between calls to esbuild's API as sharing a single long-lived esbuild child process is more efficient than re-creating a new esbuild child process for every API call. This API call used to exist but was removed in [version 0.9.0](https://github.com/evanw/esbuild/releases/v0.9.0). This release adds it back due to a user request.\n\n## 0.19.10\n\n* Fix glob imports in TypeScript files ([#3319](https://github.com/evanw/esbuild/issues/3319))\n\n    This release fixes a problem where bundling a TypeScript file containing a glob import could emit a call to a helper function that doesn't exist. The problem happened because esbuild's TypeScript transformation removes unused imports (which is required for correctness, as they may be type-only imports) and esbuild's glob import transformation wasn't correctly marking the imported helper function as used. This wasn't caught earlier because most of esbuild's glob import tests were written in JavaScript, not in TypeScript.\n\n* Fix `require()` glob imports with bundling disabled ([#3546](https://github.com/evanw/esbuild/issues/3546))\n\n    Previously `require()` calls containing glob imports were incorrectly transformed when bundling was disabled. All glob imports should only be transformed when bundling is enabled. This bug has been fixed.\n\n* Fix a panic when transforming optional chaining with `define` ([#3551](https://github.com/evanw/esbuild/issues/3551), [#3554](https://github.com/evanw/esbuild/pull/3554))\n\n    This release fixes a case where esbuild could crash with a panic, which was triggered by using `define` to replace an expression containing an optional chain. Here is an example:\n\n    ```js\n    // Original code\n    console.log(process?.env.SHELL)\n\n    // Old output (with --define:process.env={})\n    /* panic: Internal error (while parsing \"<stdin>\") */\n\n    // New output (with --define:process.env={})\n    var define_process_env_default = {};\n    console.log(define_process_env_default.SHELL);\n    ```\n\n    This fix was contributed by [@hi-ogawa](https://github.com/hi-ogawa).\n\n* Work around a bug in node's CommonJS export name detector ([#3544](https://github.com/evanw/esbuild/issues/3544))\n\n    The export names of a CommonJS module are dynamically-determined at run time because CommonJS exports are properties on a mutable object. But the export names of an ES module are statically-determined at module instantiation time by using `import` and `export` syntax and cannot be changed at run time.\n\n    When you import a CommonJS module into an ES module in node, node scans over the source code to attempt to detect the set of export names that the CommonJS module will end up using. That statically-determined set of names is used as the set of names that the ES module is allowed to import at module instantiation time. However, this scan appears to have bugs (or at least, can cause false positives) because it doesn't appear to do any scope analysis. Node will incorrectly consider the module to export something even if the assignment is done to a local variable instead of to the module-level `exports` object. For example:\n\n    ```js\n    // confuseNode.js\n    exports.confuseNode = function(exports) {\n      // If this local is called \"exports\", node incorrectly\n      // thinks this file has an export called \"notAnExport\".\n      exports.notAnExport = function() {\n      };\n    };\n    ```\n\n    You can see that node incorrectly thinks the file `confuseNode.js` has an export called `notAnExport` when that file is loaded in an ES module context:\n\n    ```console\n    $ node -e 'import(\"./confuseNode.js\").then(console.log)'\n    [Module: null prototype] {\n      confuseNode: [Function (anonymous)],\n      default: { confuseNode: [Function (anonymous)] },\n      notAnExport: undefined\n    }\n    ```\n\n    To avoid this, esbuild will now rename local variables that use the names `exports` and `module` when generating CommonJS output for the `node` platform.\n\n* Fix the return value of esbuild's `super()` shim ([#3538](https://github.com/evanw/esbuild/issues/3538))\n\n    Some people write `constructor` methods that use the return value of `super()` instead of using `this`. This isn't too common because [TypeScript doesn't let you do that](https://github.com/microsoft/TypeScript/issues/37847) but it can come up when writing JavaScript. Previously esbuild's class lowering transform incorrectly transformed the return value of `super()` into `undefined`. With this release, the return value of `super()` will now be `this` instead:\n\n    ```js\n    // Original code\n    class Foo extends Object {\n      field\n      constructor() {\n        console.log(typeof super())\n      }\n    }\n    new Foo\n\n    // Old output (with --target=es6)\n    class Foo extends Object {\n      constructor() {\n        var __super = (...args) => {\n          super(...args);\n          __publicField(this, \"field\");\n        };\n        console.log(typeof __super());\n      }\n    }\n    new Foo();\n\n    // New output (with --target=es6)\n    class Foo extends Object {\n      constructor() {\n        var __super = (...args) => {\n          super(...args);\n          __publicField(this, \"field\");\n          return this;\n        };\n        console.log(typeof __super());\n      }\n    }\n    new Foo();\n    ```\n\n* Terminate the Go GC when esbuild's `stop()` API is called ([#3552](https://github.com/evanw/esbuild/issues/3552))\n\n    If you use esbuild with WebAssembly and pass the `worker: false` flag to `esbuild.initialize()`, then esbuild will run the WebAssembly module on the main thread. If you do this within a Deno test and that test calls `esbuild.stop()` to clean up esbuild's resources, Deno may complain that a `setTimeout()` call lasted past the end of the test. This happens when the Go is in the middle of a garbage collection pass and has scheduled additional ongoing garbage collection work. Normally calling `esbuild.stop()` will terminate the web worker that the WebAssembly module runs in, which will terminate the Go GC, but that doesn't happen if you disable the web worker with `worker: false`.\n\n    With this release, esbuild will now attempt to terminate the Go GC in this edge case by calling `clearTimeout()` on these pending timeouts.\n\n* Apply `/* @__NO_SIDE_EFFECTS__ */` on tagged template literals ([#3511](https://github.com/evanw/esbuild/issues/3511))\n\n    Tagged template literals that reference functions annotated with a `@__NO_SIDE_EFFECTS__` comment are now able to be removed via tree-shaking if the result is unused. This is a convention from [Rollup](https://github.com/rollup/rollup/pull/5024). Here is an example:\n\n    ```js\n    // Original code\n    const html = /* @__NO_SIDE_EFFECTS__ */ (a, ...b) => ({ a, b })\n    html`<a>remove</a>`\n    x = html`<b>keep</b>`\n\n    // Old output (with --tree-shaking=true)\n    const html = /* @__NO_SIDE_EFFECTS__ */ (a, ...b) => ({ a, b });\n    html`<a>remove</a>`;\n    x = html`<b>keep</b>`;\n\n    // New output (with --tree-shaking=true)\n    const html = /* @__NO_SIDE_EFFECTS__ */ (a, ...b) => ({ a, b });\n    x = html`<b>keep</b>`;\n    ```\n\n    Note that this feature currently only works within a single file, so it's not especially useful. This feature does not yet work across separate files. I still recommend using `@__PURE__` annotations instead of this feature, as they have wider tooling support. The drawback of course is that `@__PURE__` annotations need to be added at each call site, not at the declaration, and for non-call expressions such as template literals you need to wrap the expression in an IIFE (immediately-invoked function expression) to create a call expression to apply the `@__PURE__` annotation to.\n\n* Publish builds for IBM AIX PowerPC 64-bit ([#3549](https://github.com/evanw/esbuild/issues/3549))\n\n    This release publishes a binary executable to npm for IBM AIX PowerPC 64-bit, which means that in theory esbuild can now be installed in that environment with `npm install esbuild`. This hasn't actually been tested yet. If you have access to such a system, it would be helpful to confirm whether or not doing this actually works.\n\n## 0.19.9\n\n* Add support for transforming new CSS gradient syntax for older browsers\n\n    The specification called [CSS Images Module Level 4](https://www.w3.org/TR/css-images-4/) introduces new CSS gradient syntax for customizing how the browser interpolates colors in between color stops. You can now control the color space that the interpolation happens in as well as (for \"polar\" color spaces) control whether hue angle interpolation happens clockwise or counterclockwise. You can read more about this in [Mozilla's blog post about new CSS gradient features](https://developer.mozilla.org/en-US/blog/css-color-module-level-4/).\n\n    With this release, esbuild will now automatically transform this syntax for older browsers in the `target` list. For example, here's a gradient that should appear as a rainbow in a browser that supports this new syntax:\n\n    ```css\n    /* Original code */\n    .rainbow-gradient {\n      width: 100px;\n      height: 100px;\n      background: linear-gradient(in hsl longer hue, #7ff, #77f);\n    }\n\n    /* New output (with --target=chrome99) */\n    .rainbow-gradient {\n      width: 100px;\n      height: 100px;\n      background:\n        linear-gradient(\n          #77ffff,\n          #77ffaa 12.5%,\n          #77ff80 18.75%,\n          #84ff77 21.88%,\n          #99ff77 25%,\n          #eeff77 37.5%,\n          #fffb77 40.62%,\n          #ffe577 43.75%,\n          #ffbb77 50%,\n          #ff9077 56.25%,\n          #ff7b77 59.38%,\n          #ff7788 62.5%,\n          #ff77dd 75%,\n          #ff77f2 78.12%,\n          #f777ff 81.25%,\n          #cc77ff 87.5%,\n          #7777ff);\n    }\n    ```\n\n    You can now use this syntax in your CSS source code and esbuild will automatically convert it to an equivalent gradient for older browsers. In addition, esbuild will now also transform \"double position\" and \"transition hint\" syntax for older browsers as appropriate:\n\n    ```css\n    /* Original code */\n    .stripes {\n      width: 100px;\n      height: 100px;\n      background: linear-gradient(#e65 33%, #ff2 33% 67%, #99e 67%);\n    }\n    .glow {\n      width: 100px;\n      height: 100px;\n      background: radial-gradient(white 10%, 20%, black);\n    }\n\n    /* New output (with --target=chrome33) */\n    .stripes {\n      width: 100px;\n      height: 100px;\n      background:\n        linear-gradient(\n          #e65 33%,\n          #ff2 33%,\n          #ff2 67%,\n          #99e 67%);\n    }\n    .glow {\n      width: 100px;\n      height: 100px;\n      background:\n        radial-gradient(\n          #ffffff 10%,\n          #aaaaaa 12.81%,\n          #959595 15.62%,\n          #7b7b7b 21.25%,\n          #5a5a5a 32.5%,\n          #444444 43.75%,\n          #323232 55%,\n          #161616 77.5%,\n          #000000);\n    }\n    ```\n\n    You can see visual examples of these new syntax features by looking at [esbuild's gradient transformation tests](https://esbuild.github.io/gradient-tests/).\n\n    If necessary, esbuild will construct a new gradient that approximates the original gradient by recursively splitting the interval in between color stops until the approximation error is within a small threshold. That is why the above output CSS contains many more color stops than the input CSS.\n\n    Note that esbuild deliberately _replaces_ the original gradient with the approximation instead of inserting the approximation before the original gradient as a fallback. The latest version of Firefox has multiple gradient rendering bugs (including incorrect interpolation of partially-transparent colors and interpolating non-sRGB colors using the incorrect color space). If esbuild didn't replace the original gradient, then Firefox would use the original gradient instead of the fallback the appearance would be incorrect in Firefox. In other words, the latest version of Firefox supports modern gradient syntax but interprets it incorrectly.\n\n* Add support for `color()`, `lab()`, `lch()`, `oklab()`, `oklch()`, and `hwb()` in CSS\n\n    CSS has recently added lots of new ways of specifying colors. You can read more about this in [Chrome's blog post about CSS color spaces](https://developer.chrome.com/docs/css-ui/high-definition-css-color-guide).\n\n    This release adds support for minifying colors that use the `color()`, `lab()`, `lch()`, `oklab()`, `oklch()`, or `hwb()` syntax and/or transforming these colors for browsers that don't support it yet:\n\n    ```css\n    /* Original code */\n    div {\n      color: hwb(90deg 20% 40%);\n      background: color(display-p3 1 0 0);\n    }\n\n    /* New output (with --target=chrome99) */\n    div {\n      color: #669933;\n      background: #ff0f0e;\n      background: color(display-p3 1 0 0);\n    }\n    ```\n\n    As you can see, colors outside of the sRGB color space such as `color(display-p3 1 0 0)` are mapped back into the sRGB gamut and inserted as a fallback for browsers that don't support the new color syntax.\n\n* Allow empty type parameter lists in certain cases ([#3512](https://github.com/evanw/esbuild/issues/3512))\n\n    TypeScript allows interface declarations and type aliases to have empty type parameter lists. Previously esbuild didn't handle this edge case but with this release, esbuild will now parse this syntax:\n\n    ```ts\n    interface Foo<> {}\n    type Bar<> = {}\n    ```\n\n    This fix was contributed by [@magic-akari](https://github.com/magic-akari).\n\n## 0.19.8\n\n* Add a treemap chart to esbuild's bundle analyzer ([#2848](https://github.com/evanw/esbuild/issues/2848))\n\n    The bundler analyzer on esbuild's website (https://esbuild.github.io/analyze/) now has a treemap chart type in addition to the two existing chart types (sunburst and flame). This should be more familiar for people coming from other similar tools, as well as make better use of large screens.\n\n* Allow decorators after the `export` keyword ([#104](https://github.com/evanw/esbuild/issues/104))\n\n    Previously esbuild's decorator parser followed the original behavior of TypeScript's experimental decorators feature, which only allowed decorators to come before the `export` keyword. However, the upcoming JavaScript decorators feature also allows decorators to come after the `export` keyword. And with TypeScript 5.0, TypeScript now also allows experimental decorators to come after the `export` keyword too. So esbuild now allows this as well:\n\n    ```js\n    // This old syntax has always been permitted:\n    @decorator export class Foo {}\n    @decorator export default class Foo {}\n\n    // This new syntax is now permitted too:\n    export @decorator class Foo {}\n    export default @decorator class Foo {}\n    ```\n\n    In addition, esbuild's decorator parser has been rewritten to fix several subtle and likely unimportant edge cases with esbuild's parsing of exports and decorators in TypeScript (e.g. TypeScript apparently does automatic semicolon insertion after `interface` and `export interface` but not after `export default interface`).\n\n* Pretty-print decorators using the same whitespace as the original\n\n    When printing code containing decorators, esbuild will now try to respect whether the original code contained newlines after the decorator or not. This can make generated code containing many decorators much more compact to read:\n\n    ```js\n    // Original code\n    class Foo {\n      @a @b @c abc\n      @x @y @z xyz\n    }\n\n    // Old output\n    class Foo {\n      @a\n      @b\n      @c\n      abc;\n      @x\n      @y\n      @z\n      xyz;\n    }\n\n    // New output\n    class Foo {\n      @a @b @c abc;\n      @x @y @z xyz;\n    }\n    ```\n\n## 0.19.7\n\n* Add support for bundling code that uses import attributes ([#3384](https://github.com/evanw/esbuild/issues/3384))\n\n    JavaScript is gaining new syntax for associating a map of string key-value pairs with individual ESM imports. The proposal is still a work in progress and is still undergoing significant changes before being finalized. However, the first iteration has already been shipping in Chromium-based browsers for a while, and the second iteration has landed in V8 and is now shipping in node, so it makes sense for esbuild to support it. Here are the two major iterations of this proposal (so far):\n\n    1. Import assertions (deprecated, will not be standardized)\n        * Uses the `assert` keyword\n        * Does _not_ affect module resolution\n        * Causes an error if the assertion fails\n        * Shipping in Chrome 91+ (and in esbuild 0.11.22+)\n\n    2. Import attributes (currently set to become standardized)\n        * Uses the `with` keyword\n        * Affects module resolution\n        * Unknown attributes cause an error\n        * Shipping in node 21+\n\n    You can already use esbuild to bundle code that uses import assertions (the first iteration). However, this feature is mostly useless for bundlers because import assertions are not allowed to affect module resolution. It's basically only useful as an annotation on external imports, which esbuild will then preserve in the output for use in a browser (which would otherwise refuse to load certain imports).\n\n    With this release, esbuild now supports bundling code that uses import attributes (the second iteration). This is much more useful for bundlers because they are allowed to affect module resolution, which means the key-value pairs can be provided to plugins. Here's an example, which uses esbuild's built-in support for the upcoming [JSON module standard](https://github.com/tc39/proposal-json-modules):\n\n    ```js\n    // On static imports\n    import foo from './package.json' with { type: 'json' }\n    console.log(foo)\n\n    // On dynamic imports\n    const bar = await import('./package.json', { with: { type: 'json' } })\n    console.log(bar)\n    ```\n\n    One important consequence of the change in semantics between import assertions and import attributes is that two imports with identical paths but different import attributes are now considered to be different modules. This is because the import attributes are provided to the loader, which might then use those attributes during loading. For example, you could imagine an image loader that produces an image of a different size depending on the import attributes.\n\n    Import attributes are now reported in the [metafile](https://esbuild.github.io/api/#metafile) and are now provided to [on-load plugins](https://esbuild.github.io/plugins/#on-load) as a map in the `with` property. For example, here's an esbuild plugin that turns all imports with a `type` import attribute equal to `'cheese'` into a module that exports the cheese emoji:\n\n    ```js\n    const cheesePlugin = {\n      name: 'cheese',\n      setup(build) {\n        build.onLoad({ filter: /.*/ }, args => {\n          if (args.with.type === 'cheese') return {\n            contents: `export default \"🧀\"`,\n          }\n        })\n      }\n    }\n\n    require('esbuild').build({\n      bundle: true,\n      write: false,\n      stdin: {\n        contents: `\n          import foo from 'data:text/javascript,' with { type: 'cheese' }\n          console.log(foo)\n        `,\n      },\n      plugins: [cheesePlugin],\n    }).then(result => {\n      const code = new Function(result.outputFiles[0].text)\n      code()\n    })\n    ```\n\n    Warning: It's possible that the second iteration of this feature may change significantly again even though it's already shipping in real JavaScript VMs (since it has already happened once before). In that case, esbuild may end up adjusting its implementation to match the eventual standard behavior. So keep in mind that by using this, you are using an unstable upcoming JavaScript feature that may undergo breaking changes in the future.\n\n* Adjust TypeScript experimental decorator behavior ([#3230](https://github.com/evanw/esbuild/issues/3230), [#3326](https://github.com/evanw/esbuild/issues/3326), [#3394](https://github.com/evanw/esbuild/issues/3394))\n\n    With this release, esbuild will now allow TypeScript experimental decorators to access both static class properties and `#private` class names. For example:\n\n    ```js\n    const check =\n      <T,>(a: T, b: T): PropertyDecorator =>\n        () => console.log(a === b)\n\n    async function test() {\n      class Foo {\n        static #foo = 1\n        static bar = 1 + Foo.#foo\n        @check(Foo.#foo, 1) a: any\n        @check(Foo.bar, await Promise.resolve(2)) b: any\n      }\n    }\n\n    test().then(() => console.log('pass'))\n    ```\n\n    This will now print `true true pass` when compiled by esbuild. Previously esbuild evaluated TypeScript decorators outside of the class body, so it didn't allow decorators to access `Foo` or `#foo`. Now esbuild does something different, although it's hard to concisely explain exactly what esbuild is doing now (see the background section below for more information).\n\n    Note that TypeScript's experimental decorator support is currently buggy: TypeScript's compiler passes this test if only the first `@check` is present or if only the second `@check` is present, but TypeScript's compiler fails this test if both checks are present together. I haven't changed esbuild to match TypeScript's behavior exactly here because I'm waiting for TypeScript to fix these bugs instead.\n\n    Some background: TypeScript experimental decorators don't have consistent semantics regarding the context that the decorators are evaluated in. For example, TypeScript will let you use `await` within a decorator, which implies that the decorator runs outside the class body (since `await` isn't supported inside a class body), but TypeScript will also let you use `#private` names, which implies that the decorator runs inside the class body (since `#private` names are only supported inside a class body). The value of `this` in a decorator is also buggy (the run-time value of `this` changes if any decorator in the class uses a `#private` name but the type of `this` doesn't change, leading to the type checker no longer matching reality). These inconsistent semantics make it hard for esbuild to implement this feature as decorator evaluation happens in some superposition of both inside and outside the class body that is particular to the internal implementation details of the TypeScript compiler.\n\n* Forbid `--keep-names` when targeting old browsers ([#3477](https://github.com/evanw/esbuild/issues/3477))\n\n    The `--keep-names` setting needs to be able to assign to the `name` property on functions and classes. However, before ES6 this property was non-configurable, and attempting to assign to it would throw an error. So with this release, esbuild will no longer allow you to enable this setting while also targeting a really old browser.\n\n## 0.19.6\n\n* Fix a constant folding bug with bigint equality\n\n    This release fixes a bug where esbuild incorrectly checked for bigint equality by checking the equality of the bigint literal text. This is correct if the bigint doesn't have a radix because bigint literals without a radix are always in canonical form (since leading zeros are not allowed). However, this is incorrect if the bigint has a radix (e.g. `0x123n`) because the canonical form is not enforced when a radix is present.\n\n    ```js\n    // Original code\n    console.log(!!0n, !!1n, 123n === 123n)\n    console.log(!!0x0n, !!0x1n, 123n === 0x7Bn)\n\n    // Old output\n    console.log(false, true, true);\n    console.log(true, true, false);\n\n    // New output\n    console.log(false, true, true);\n    console.log(!!0x0n, !!0x1n, 123n === 0x7Bn);\n    ```\n\n* Add some improvements to the JavaScript minifier\n\n    This release adds more cases to the JavaScript minifier, including support for inlining `String.fromCharCode` and `String.prototype.charCodeAt` when possible:\n\n    ```js\n    // Original code\n    document.onkeydown = e => e.keyCode === 'A'.charCodeAt(0) && console.log(String.fromCharCode(55358, 56768))\n\n    // Old output (with --minify)\n    document.onkeydown=o=>o.keyCode===\"A\".charCodeAt(0)&&console.log(String.fromCharCode(55358,56768));\n\n    // New output (with --minify)\n    document.onkeydown=o=>o.keyCode===65&&console.log(\"🧀\");\n    ```\n\n    In addition, immediately-invoked function expressions (IIFEs) that return a single expression are now inlined when minifying. This makes it possible to use IIFEs in combination with `@__PURE__` annotations to annotate arbitrary expressions as side-effect free without the IIFE wrapper impacting code size. For example:\n\n    ```js\n    // Original code\n    const sideEffectFreeOffset = /* @__PURE__ */ (() => computeSomething())()\n    use(sideEffectFreeOffset)\n\n    // Old output (with --minify)\n    const e=(()=>computeSomething())();use(e);\n\n    // New output (with --minify)\n    const e=computeSomething();use(e);\n    ```\n\n* Automatically prefix the `mask-composite` CSS property for WebKit ([#3493](https://github.com/evanw/esbuild/issues/3493))\n\n    The `mask-composite` property will now be prefixed as `-webkit-mask-composite` for older WebKit-based browsers. In addition to prefixing the property name, handling older browsers also requires rewriting the values since WebKit uses non-standard names for the mask composite modes:\n\n    ```css\n    /* Original code */\n    div {\n      mask-composite: add, subtract, intersect, exclude;\n    }\n\n    /* New output (with --target=chrome100) */\n    div {\n      -webkit-mask-composite:\n        source-over,\n        source-out,\n        source-in,\n        xor;\n      mask-composite:\n        add,\n        subtract,\n        intersect,\n        exclude;\n    }\n    ```\n\n* Avoid referencing `this` from JSX elements in derived class constructors ([#3454](https://github.com/evanw/esbuild/issues/3454))\n\n    When you enable `--jsx=automatic` and `--jsx-dev`, the JSX transform is supposed to insert `this` as the last argument to the `jsxDEV` function. I'm not sure exactly why this is and I can't find any specification for it, but in any case this causes the generated code to crash when you use a JSX element in a derived class constructor before the call to `super()` as `this` is not allowed to be accessed at that point. For example\n\n    ```js\n    // Original code\n    class ChildComponent extends ParentComponent {\n      constructor() {\n        super(<div />)\n      }\n    }\n\n    // Problematic output (with --loader=jsx --jsx=automatic --jsx-dev)\n    import { jsxDEV } from \"react/jsx-dev-runtime\";\n    class ChildComponent extends ParentComponent {\n      constructor() {\n        super(/* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n          fileName: \"<stdin>\",\n          lineNumber: 3,\n          columnNumber: 15\n        }, this)); // The reference to \"this\" crashes here\n      }\n    }\n    ```\n\n    The TypeScript compiler doesn't handle this at all while the Babel compiler just omits `this` for the entire constructor (even after the call to `super()`). There seems to be no specification so I can't be sure that this change doesn't break anything important. But given that Babel is pretty loose with this and TypeScript doesn't handle this at all, I'm guessing this value isn't too important. React's blog post seems to indicate that this value was intended to be used for a React-specific migration warning at some point, so it could even be that this value is irrelevant now. Anyway the crash in this case should now be fixed.\n\n* Allow package subpath imports to map to node built-ins ([#3485](https://github.com/evanw/esbuild/issues/3485))\n\n    You are now able to use a [subpath import](https://nodejs.org/api/packages.html#subpath-imports) in your package to resolve to a node built-in module. For example, with a `package.json` file like this:\n\n    ```json\n    {\n      \"type\": \"module\",\n      \"imports\": {\n        \"#stream\": {\n          \"node\": \"stream\",\n          \"default\": \"./stub.js\"\n        }\n      }\n    }\n    ```\n\n    You can now import from node's `stream` module like this:\n\n    ```js\n    import * as stream from '#stream';\n    console.log(Object.keys(stream));\n    ```\n\n    This will import from node's `stream` module when the platform is `node` and from `./stub.js` otherwise.\n\n* No longer throw an error when a `Symbol` is missing ([#3453](https://github.com/evanw/esbuild/issues/3453))\n\n    Certain JavaScript syntax features use special properties on the global `Symbol` object. For example, the asynchronous iteration syntax uses `Symbol.asyncIterator`. Previously esbuild's generated code for older browsers required this symbol to be polyfilled. However, starting with this release esbuild will use [`Symbol.for()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for) to construct these symbols if they are missing instead of throwing an error about a missing polyfill. This means your code no longer needs to include a polyfill for missing symbols as long as your code also uses `Symbol.for()` for missing symbols.\n\n* Parse upcoming changes to TypeScript syntax ([#3490](https://github.com/evanw/esbuild/issues/3490), [#3491](https://github.com/evanw/esbuild/pull/3491))\n\n    With this release, you can now use `from` as the name of a default type-only import in TypeScript code, as well as `of` as the name of an `await using` loop iteration variable:\n\n    ```ts\n    import type from from 'from'\n    for (await using of of of) ;\n    ```\n\n    This matches similar changes in the TypeScript compiler ([#56376](https://github.com/microsoft/TypeScript/issues/56376) and [#55555](https://github.com/microsoft/TypeScript/issues/55555)) which will start allowing this syntax in an upcoming version of TypeScript. Please never actually write code like this.\n\n    The type-only import syntax change was contributed by [@magic-akari](https://github.com/magic-akari).\n\n## 0.19.5\n\n* Fix a regression in 0.19.0 regarding `paths` in `tsconfig.json` ([#3354](https://github.com/evanw/esbuild/issues/3354))\n\n    The fix in esbuild version 0.19.0 to process `tsconfig.json` aliases before the `--packages=external` setting unintentionally broke an edge case in esbuild's handling of certain `tsconfig.json` aliases where there are multiple files with the same name in different directories. This release adjusts esbuild's behavior for this edge case so that it passes while still processing aliases before `--packages=external`. Please read the linked issue for more details.\n\n* Fix a CSS `font` property minification bug ([#3452](https://github.com/evanw/esbuild/issues/3452))\n\n    This release fixes a bug where esbuild's CSS minifier didn't insert a space between the font size and the font family in the `font` CSS shorthand property in the edge case where the original source code didn't already have a space and the leading string token was shortened to an identifier:\n\n    ```css\n    /* Original code */\n    .foo { font: 16px\"Menlo\"; }\n\n    /* Old output (with --minify) */\n    .foo{font:16pxMenlo}\n\n    /* New output (with --minify) */\n    .foo{font:16px Menlo}\n    ```\n\n* Fix bundling CSS with asset names containing spaces ([#3410](https://github.com/evanw/esbuild/issues/3410))\n\n    Assets referenced via CSS `url()` tokens may cause esbuild to generate invalid output when bundling if the file name contains spaces (e.g. `url(image 2.png)`). With this release, esbuild will now quote all bundled asset references in `url()` tokens to avoid this problem. This only affects assets loaded using the `file` and `copy` loaders.\n\n* Fix invalid CSS `url()` tokens in `@import` rules ([#3426](https://github.com/evanw/esbuild/issues/3426))\n\n    In the future, CSS `url()` tokens may contain additional stuff after the URL. This is irrelevant today as no CSS specification does this. But esbuild previously had a bug where using these tokens in an `@import` rule resulted in malformed output. This bug has been fixed.\n\n* Fix `browser` + `false` + `type: module` in `package.json` ([#3367](https://github.com/evanw/esbuild/issues/3367))\n\n    The `browser` field in `package.json` allows you to map a file to `false` to have it be treated as an empty file when bundling for the browser. However, if `package.json` contains `\"type\": \"module\"` then all `.js` files will be considered ESM, not CommonJS. Importing a named import from an empty CommonJS file gives you undefined, but importing a named export from an empty ESM file is a build error. This release changes esbuild's interpretation of these files mapped to `false` in this situation from ESM to CommonJS to avoid generating build errors for named imports.\n\n* Fix a bug in top-level await error reporting ([#3400](https://github.com/evanw/esbuild/issues/3400))\n\n    Using `require()` on a file that contains [top-level await](https://v8.dev/features/top-level-await) is not allowed because `require()` must return synchronously and top-level await makes that impossible. You will get a build error if you try to bundle code that does this with esbuild. This release fixes a bug in esbuild's error reporting code for complex cases of this situation involving multiple levels of imports to get to the module containing the top-level await.\n\n* Update to Unicode 15.1.0\n\n    The character tables that determine which characters form valid JavaScript identifiers have been updated from Unicode version 15.0.0 to the newly-released Unicode version 15.1.0. I'm not putting an example in the release notes because all of the new characters will likely just show up as little squares since fonts haven't been updated yet. But you can read https://www.unicode.org/versions/Unicode15.1.0/#Summary for more information about the changes.\n\n    This upgrade was contributed by [@JLHwung](https://github.com/JLHwung).\n\n## 0.19.4\n\n* Fix printing of JavaScript decorators in tricky cases ([#3396](https://github.com/evanw/esbuild/issues/3396))\n\n    This release fixes some bugs where esbuild's pretty-printing of JavaScript decorators could incorrectly produced code with a syntax error. The problem happened because esbuild sometimes substitutes identifiers for other expressions in the pretty-printer itself, but the decision about whether to wrap the expression or not didn't account for this. Here are some examples:\n\n    ```js\n    // Original code\n    import { constant } from './constants.js'\n    import { imported } from 'external'\n    import { undef } from './empty.js'\n    class Foo {\n      @constant()\n      @imported()\n      @undef()\n      foo\n    }\n\n    // Old output (with --bundle --format=cjs --packages=external --minify-syntax)\n    var import_external = require(\"external\");\n    var Foo = class {\n      @123()\n      @(0, import_external.imported)()\n      @(void 0)()\n      foo;\n    };\n\n    // New output (with --bundle --format=cjs --packages=external --minify-syntax)\n    var import_external = require(\"external\");\n    var Foo = class {\n      @(123())\n      @((0, import_external.imported)())\n      @((void 0)())\n      foo;\n    };\n    ```\n\n* Allow pre-release versions to be passed to `target` ([#3388](https://github.com/evanw/esbuild/issues/3388))\n\n    People want to be able to pass version numbers for unreleased versions of node (which have extra stuff after the version numbers) to esbuild's `target` setting and have esbuild do something reasonable with them. These version strings are of course not present in esbuild's internal feature compatibility table because an unreleased version has not been released yet (by definition). With this release, esbuild will now attempt to accept these version strings passed to `target` and do something reasonable with them.\n\n## 0.19.3\n\n* Fix `list-style-type` with the `local-css` loader ([#3325](https://github.com/evanw/esbuild/issues/3325))\n\n    The `local-css` loader incorrectly treated all identifiers provided to `list-style-type` as a custom local identifier. That included identifiers such as `none` which have special meaning in CSS, and which should not be treated as custom local identifiers. This release fixes this bug:\n\n    ```css\n    /* Original code */\n    ul { list-style-type: none }\n\n    /* Old output (with --loader=local-css) */\n    ul {\n      list-style-type: stdin_none;\n    }\n\n    /* New output (with --loader=local-css) */\n    ul {\n      list-style-type: none;\n    }\n    ```\n\n    Note that this bug only affected code using the `local-css` loader. It did not affect code using the `css` loader.\n\n* Avoid inserting temporary variables before `use strict` ([#3322](https://github.com/evanw/esbuild/issues/3322))\n\n    This release fixes a bug where esbuild could incorrectly insert automatically-generated temporary variables before `use strict` directives:\n\n    ```js\n    // Original code\n    function foo() {\n      'use strict'\n      a.b?.c()\n    }\n\n    // Old output (with --target=es6)\n    function foo() {\n      var _a;\n      \"use strict\";\n      (_a = a.b) == null ? void 0 : _a.c();\n    }\n\n    // New output (with --target=es6)\n    function foo() {\n      \"use strict\";\n      var _a;\n      (_a = a.b) == null ? void 0 : _a.c();\n    }\n    ```\n\n* Adjust TypeScript `enum` output to better approximate `tsc` ([#3329](https://github.com/evanw/esbuild/issues/3329))\n\n    TypeScript enum values can be either number literals or string literals. Numbers create a bidirectional mapping between the name and the value but strings only create a unidirectional mapping from the name to the value. When the enum value is neither a number literal nor a string literal, TypeScript and esbuild both default to treating it as a number:\n\n    ```ts\n    // Original TypeScript code\n    declare const foo: any\n    enum Foo {\n      NUMBER = 1,\n      STRING = 'a',\n      OTHER = foo,\n    }\n\n    // Compiled JavaScript code (from \"tsc\")\n    var Foo;\n    (function (Foo) {\n      Foo[Foo[\"NUMBER\"] = 1] = \"NUMBER\";\n      Foo[\"STRING\"] = \"a\";\n      Foo[Foo[\"OTHER\"] = foo] = \"OTHER\";\n    })(Foo || (Foo = {}));\n    ```\n\n    However, TypeScript does constant folding slightly differently than esbuild. For example, it may consider template literals to be string literals in some cases:\n\n    ```ts\n    // Original TypeScript code\n    declare const foo = 'foo'\n    enum Foo {\n      PRESENT = `${foo}`,\n      MISSING = `${bar}`,\n    }\n\n    // Compiled JavaScript code (from \"tsc\")\n    var Foo;\n    (function (Foo) {\n      Foo[\"PRESENT\"] = \"foo\";\n      Foo[Foo[\"MISSING\"] = `${bar}`] = \"MISSING\";\n    })(Foo || (Foo = {}));\n    ```\n\n    The template literal initializer for `PRESENT` is treated as a string while the template literal initializer for `MISSING` is treated as a number. Previously esbuild treated both of these cases as a number but starting with this release, esbuild will now treat both of these cases as a string. This doesn't exactly match the behavior of `tsc` but in the case where the behavior diverges `tsc` reports a compile error, so this seems like acceptible behavior for esbuild. Note that handling these cases completely correctly would require esbuild to parse type declarations (see the `declare` keyword), which esbuild deliberately doesn't do.\n\n* Ignore case in CSS in more places ([#3316](https://github.com/evanw/esbuild/issues/3316))\n\n    This release makes esbuild's CSS support more case-agnostic, which better matches how browsers work. For example:\n\n    ```css\n    /* Original code */\n    @KeyFrames Foo { From { OpaCity: 0 } To { OpaCity: 1 } }\n    body { CoLoR: YeLLoW }\n\n    /* Old output (with --minify) */\n    @KeyFrames Foo{From {OpaCity: 0} To {OpaCity: 1}}body{CoLoR:YeLLoW}\n\n    /* New output (with --minify) */\n    @KeyFrames Foo{0%{OpaCity:0}To{OpaCity:1}}body{CoLoR:#ff0}\n    ```\n\n    Please never actually write code like this.\n\n* Improve the error message for `null` entries in `exports` ([#3377](https://github.com/evanw/esbuild/issues/3377))\n\n    Package authors can disable package export paths with the `exports` map in `package.json`. With this release, esbuild now has a clearer error message that points to the `null` token in `package.json` itself instead of to the surrounding context. Here is an example of the new error message:\n\n    ```\n    ✘ [ERROR] Could not resolve \"msw/browser\"\n\n        lib/msw-config.ts:2:28:\n          2 │ import { setupWorker } from 'msw/browser';\n            ╵                             ~~~~~~~~~~~~~\n\n      The path \"./browser\" cannot be imported from package \"msw\" because it was explicitly disabled by\n      the package author here:\n\n        node_modules/msw/package.json:17:14:\n          17 │       \"node\": null,\n             ╵               ~~~~\n\n      You can mark the path \"msw/browser\" as external to exclude it from the bundle, which will remove\n      this error and leave the unresolved path in the bundle.\n    ```\n\n* Parse and print the `with` keyword in `import` statements\n\n    JavaScript was going to have a feature called \"import assertions\" that adds an `assert` keyword to `import` statements. It looked like this:\n\n    ```js\n    import stuff from './stuff.json' assert { type: 'json' }\n    ```\n\n    The feature provided a way to assert that the imported file is of a certain type (but was not allowed to affect how the import is interpreted, even though that's how everyone expected it to behave). The feature was fully specified and then actually implemented and shipped in Chrome before the people behind the feature realized that they should allow it to affect how the import is interpreted after all. So import assertions are no longer going to be added to the language.\n\n    Instead, the [current proposal](https://github.com/tc39/proposal-import-attributes) is to add a feature called \"import attributes\" instead that adds a `with` keyword to import statements. It looks like this:\n\n    ```js\n    import stuff from './stuff.json' with { type: 'json' }\n    ```\n\n    This feature provides a way to affect how the import is interpreted. With this release, esbuild now has preliminary support for parsing and printing this new `with` keyword. The `with` keyword is not yet interpreted by esbuild, however, so bundling code with it will generate a build error. All this release does is allow you to use esbuild to process code containing it (such as removing types from TypeScript code). Note that this syntax is not yet a part of JavaScript and may be removed or altered in the future if the specification changes (which it already has once, as described above). If that happens, esbuild reserves the right to remove or alter its support for this syntax too.\n\n## 0.19.2\n\n* Update how CSS nesting is parsed again\n\n    CSS nesting syntax has been changed again, and esbuild has been updated to match. Type selectors may now be used with CSS nesting:\n\n    ```css\n    .foo {\n      div {\n        color: red;\n      }\n    }\n    ```\n\n    Previously this was disallowed in the CSS specification because it's ambiguous whether an identifier is a declaration or a nested rule starting with a type selector without requiring unbounded lookahead in the parser. It has now been allowed because the CSS working group has decided that requiring unbounded lookahead is acceptable after all.\n\n    Note that this change means esbuild no longer considers any existing browser to support CSS nesting since none of the existing browsers support this new syntax. CSS nesting will now always be transformed when targeting a browser. This situation will change in the future as browsers add support for this new syntax.\n\n* Fix a scope-related bug with `--drop-labels=` ([#3311](https://github.com/evanw/esbuild/issues/3311))\n\n    The recently-released `--drop-labels=` feature previously had a bug where esbuild's internal scope stack wasn't being restored properly when a statement with a label was dropped. This could manifest as a tree-shaking issue, although it's possible that this could have also been causing other subtle problems too. The bug has been fixed in this release.\n\n* Make renamed CSS names unique across entry points ([#3295](https://github.com/evanw/esbuild/issues/3295))\n\n    Previously esbuild's generated names for local names in CSS were only unique within a given entry point (or across all entry points when code splitting was enabled). That meant that building multiple entry points with esbuild could result in local names being renamed to the same identifier even when those entry points were built simultaneously within a single esbuild API call. This problem was especially likely to happen with minification enabled. With this release, esbuild will now avoid renaming local names from two separate entry points to the same name if those entry points were built with a single esbuild API call, even when code splitting is disabled.\n\n* Fix CSS ordering bug with `@layer` before `@import`\n\n    CSS lets you put `@layer` rules before `@import` rules to define the order of layers in a stylesheet. Previously esbuild's CSS bundler incorrectly ordered these after the imported files because before the introduction of cascade layers to CSS, imported files could be bundled by removing the `@import` rules and then joining files together in the right order. But with `@layer`, CSS files may now need to be split apart into multiple pieces in the bundle. For example:\n\n    ```\n    /* Original code */\n    @layer start;\n    @import \"data:text/css,@layer inner.start;\";\n    @import \"data:text/css,@layer inner.end;\";\n    @layer end;\n\n    /* Old output (with --bundle) */\n    @layer inner.start;\n    @layer inner.end;\n    @layer start;\n    @layer end;\n\n    /* New output (with --bundle) */\n    @layer start;\n    @layer inner.start;\n    @layer inner.end;\n    @layer end;\n    ```\n\n* Unwrap nested duplicate `@media` rules ([#3226](https://github.com/evanw/esbuild/issues/3226))\n\n    With this release, esbuild's CSS minifier will now automatically unwrap duplicate nested `@media` rules:\n\n    ```css\n    /* Original code */\n    @media (min-width: 1024px) {\n      .foo { color: red }\n      @media (min-width: 1024px) {\n        .bar { color: blue }\n      }\n    }\n\n    /* Old output (with --minify) */\n    @media (min-width: 1024px){.foo{color:red}@media (min-width: 1024px){.bar{color:#00f}}}\n\n    /* New output (with --minify) */\n    @media (min-width: 1024px){.foo{color:red}.bar{color:#00f}}\n    ```\n\n    These rules are unlikely to be authored manually but may result from using frameworks such as Tailwind to generate CSS.\n\n## 0.19.1\n\n* Fix a regression with `baseURL` in `tsconfig.json` ([#3307](https://github.com/evanw/esbuild/issues/3307))\n\n    The previous release moved `tsconfig.json` path resolution before `--packages=external` checks to allow the [`paths` field](https://www.typescriptlang.org/tsconfig#paths) in `tsconfig.json` to avoid a package being marked as external. However, that reordering accidentally broke the behavior of the `baseURL` field from `tsconfig.json`. This release moves these path resolution rules around again in an attempt to allow both of these cases to work.\n\n* Parse TypeScript type arguments for JavaScript decorators ([#3308](https://github.com/evanw/esbuild/issues/3308))\n\n    When parsing JavaScript decorators in TypeScript (i.e. with `experimentalDecorators` disabled), esbuild previously didn't parse type arguments. Type arguments will now be parsed starting with this release. For example:\n\n    ```ts\n    @foo<number>\n    @bar<number, string>()\n    class Foo {}\n    ```\n\n* Fix glob patterns matching extra stuff at the end ([#3306](https://github.com/evanw/esbuild/issues/3306))\n\n    Previously glob patterns such as `./*.js` would incorrectly behave like `./*.js*` during path matching (also matching `.js.map` files, for example). This was never intentional behavior, and has now been fixed.\n\n* Change the permissions of esbuild's generated output files ([#3285](https://github.com/evanw/esbuild/issues/3285))\n\n    This release changes the permissions of the output files that esbuild generates to align with the default behavior of node's [`fs.writeFileSync`](https://nodejs.org/api/fs.html#fswritefilesyncfile-data-options) function. Since most tools written in JavaScript use `fs.writeFileSync`, this should make esbuild more consistent with how other JavaScript build tools behave.\n\n    The full Unix-y details: Unix permissions use three-digit octal notation where the three digits mean \"user, group, other\" in that order. Within a digit, 4 means \"read\" and 2 means \"write\" and 1 means \"execute\". So 6 == 4 + 2 == read + write. Previously esbuild uses 0644 permissions (the leading 0 means octal notation) but the permissions for `fs.writeFileSync` defaults to 0666, so esbuild will now use 0666 permissions. This does not necessarily mean that the files esbuild generates will end up having 0666 permissions, however, as there is another Unix feature called \"umask\" where the operating system masks out some of these bits. If your umask is set to 0022 then the generated files will have 0644 permissions, and if your umask is set to 0002 then the generated files will have 0664 permissions.\n\n* Fix a subtle CSS ordering issue with `@import` and `@layer`\n\n    With this release, esbuild may now introduce additional `@layer` rules when bundling CSS to better preserve the layer ordering of the input code. Here's an example of an edge case where this matters:\n\n    ```css\n    /* entry.css */\n    @import \"a.css\";\n    @import \"b.css\";\n    @import \"a.css\";\n    ```\n\n    ```css\n    /* a.css */\n    @layer a {\n      body {\n        background: red;\n      }\n    }\n    ```\n\n    ```css\n    /* b.css */\n    @layer b {\n      body {\n        background: green;\n      }\n    }\n    ```\n\n    This CSS should set the body background to `green`, which is what happens in the browser. Previously esbuild generated the following output which incorrectly sets the body background to `red`:\n\n    ```css\n    /* b.css */\n    @layer b {\n      body {\n        background: green;\n      }\n    }\n\n    /* a.css */\n    @layer a {\n      body {\n        background: red;\n      }\n    }\n    ```\n\n    This difference in behavior is because the browser evaluates `a.css` + `b.css` + `a.css` (in CSS, each `@import` is replaced with a copy of the imported file) while esbuild was only writing out `b.css` + `a.css`. The first copy of `a.css` wasn't being written out by esbuild for two reasons: 1) bundlers care about code size and try to avoid emitting duplicate CSS and 2) when there are multiple copies of a CSS file, normally only the _last_ copy matters since the last declaration with equal specificity wins in CSS.\n\n    However, `@layer` was recently added to CSS and for `@layer` the _first_ copy matters because layers are ordered using their first location in source code order. This introduction of `@layer` means esbuild needs to change its bundling algorithm. An easy solution would be for esbuild to write out `a.css` twice, but that would be inefficient. So what I'm going to try to have esbuild do with this release is to write out an abbreviated form of the first copy of a CSS file that only includes the `@layer` information, and then still only write out the full CSS file once for the last copy. So esbuild's output for this edge case now looks like this:\n\n    ```css\n    /* a.css */\n    @layer a;\n\n    /* b.css */\n    @layer b {\n      body {\n        background: green;\n      }\n    }\n\n    /* a.css */\n    @layer a {\n      body {\n        background: red;\n      }\n    }\n    ```\n\n    The behavior of the bundled CSS now matches the behavior of the unbundled CSS. You may be wondering why esbuild doesn't just write out `a.css` first followed by `b.css`. That would work in this case but it doesn't work in general because for any rules outside of a `@layer` rule, the last copy should still win instead of the first copy.\n\n* Fix a bug with esbuild's TypeScript type definitions ([#3299](https://github.com/evanw/esbuild/pull/3299))\n\n    This release fixes a copy/paste error with the TypeScript type definitions for esbuild's JS API:\n\n    ```diff\n     export interface TsconfigRaw {\n       compilerOptions?: {\n    -    baseUrl?: boolean\n    +    baseUrl?: string\n         ...\n       }\n     }\n    ```\n\n    This fix was contributed by [@privatenumber](https://github.com/privatenumber).\n\n## 0.19.0\n\n**This release deliberately contains backwards-incompatible changes.** To avoid automatically picking up releases like this, you should either be pinning the exact version of `esbuild` in your `package.json` file (recommended) or be using a version range syntax that only accepts patch upgrades such as `^0.18.0` or `~0.18.0`. See npm's documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\n* Handle import paths containing wildcards ([#56](https://github.com/evanw/esbuild/issues/56), [#700](https://github.com/evanw/esbuild/issues/700), [#875](https://github.com/evanw/esbuild/issues/875), [#976](https://github.com/evanw/esbuild/issues/976), [#2221](https://github.com/evanw/esbuild/issues/2221), [#2515](https://github.com/evanw/esbuild/issues/2515))\n\n    This release introduces wildcards in import paths in two places:\n\n    * **Entry points**\n\n        You can now pass a string containing glob-style wildcards such as `./src/*.ts` as an entry point and esbuild will search the file system for files that match the pattern. This can be used to easily pass esbuild all files with a certain extension on the command line in a cross-platform way. Previously you had to rely on the shell to perform glob expansion, but that is obviously shell-dependent and didn't work at all on Windows. Note that to use this feature on the command line you will have to quote the pattern so it's passed verbatim to esbuild without any expansion by the shell. Here's an example:\n\n        ```sh\n        esbuild --minify \"./src/*.ts\" --outdir=out\n        ```\n\n        Specifically the `*` character will match any character except for the `/` character, and the `/**/` character sequence will match a path separator followed by zero or more path elements. Other wildcard operators found in glob patterns such as `?` and `[...]` are not supported.\n\n    * **Run-time import paths**\n\n        Import paths that are evaluated at run-time can now be bundled in certain limited situations. The import path expression must be a form of string concatenation and must start with either `./` or `../`. Each non-string expression in the string concatenation chain becomes a wildcard. The `*` wildcard is chosen unless the previous character is a `/`, in which case the `/**/*` character sequence is used. Some examples:\n\n        ```js\n        // These two forms are equivalent\n        const json1 = await import('./data/' + kind + '.json')\n        const json2 = await import(`./data/${kind}.json`)\n        ```\n\n        This feature works with `require(...)` and `import(...)` because these can all accept run-time expressions. It does not work with `import` and `export` statements because these cannot accept run-time expressions. If you want to prevent esbuild from trying to bundle these imports, you should move the string concatenation expression outside of the `require(...)` or `import(...)`. For example:\n\n        ```js\n        // This will be bundled\n        const json1 = await import('./data/' + kind + '.json')\n\n        // This will not be bundled\n        const path = './data/' + kind + '.json'\n        const json2 = await import(path)\n        ```\n\n        Note that using this feature means esbuild will potentially do a lot of file system I/O to find all possible files that might match the pattern. This is by design, and is not a bug. If this is a concern, I recommend either avoiding the `/**/` pattern (e.g. by not putting a `/` before a wildcard) or using this feature only in directory subtrees which do not have many files that don't match the pattern (e.g. making a subdirectory for your JSON files and explicitly including that subdirectory in the pattern).\n\n* Path aliases in `tsconfig.json` no longer count as packages ([#2792](https://github.com/evanw/esbuild/issues/2792), [#3003](https://github.com/evanw/esbuild/issues/3003), [#3160](https://github.com/evanw/esbuild/issues/3160), [#3238](https://github.com/evanw/esbuild/issues/3238))\n\n    Setting `--packages=external` tells esbuild to make all import paths external when they look like a package path. For example, an import of `./foo/bar` is not a package path and won't be external while an import of `foo/bar` is a package path and will be external. However, the [`paths` field](https://www.typescriptlang.org/tsconfig#paths) in `tsconfig.json` allows you to create import paths that look like package paths but that do not resolve to packages. People do not want these paths to count as package paths. So with this release, the behavior of `--packages=external` has been changed to happen after the `tsconfig.json` path remapping step.\n\n* Use the `local-css` loader for `.module.css` files by default ([#20](https://github.com/evanw/esbuild/issues/20))\n\n    With this release the `css` loader is still used for `.css` files except that `.module.css` files now use the `local-css` loader. This is a common convention in the web development community. If you need `.module.css` files to use the `css` loader instead, then you can override this behavior with `--loader:.module.css=css`.\n\n## 0.18.20\n\n* Support advanced CSS `@import` rules ([#953](https://github.com/evanw/esbuild/issues/953), [#3137](https://github.com/evanw/esbuild/issues/3137))\n\n    CSS `@import` statements have been extended to allow additional trailing tokens after the import path. These tokens sort of make the imported file behave as if it were wrapped in a `@layer`, `@supports`, and/or `@media` rule. Here are some examples:\n\n    ```css\n    @import url(foo.css);\n    @import url(foo.css) layer;\n    @import url(foo.css) layer(bar);\n    @import url(foo.css) layer(bar) supports(display: flex);\n    @import url(foo.css) layer(bar) supports(display: flex) print;\n    @import url(foo.css) layer(bar) print;\n    @import url(foo.css) supports(display: flex);\n    @import url(foo.css) supports(display: flex) print;\n    @import url(foo.css) print;\n    ```\n\n    You can read more about this advanced syntax [here](https://developer.mozilla.org/en-US/docs/Web/CSS/@import). With this release, esbuild will now bundle `@import` rules with these trailing tokens and will wrap the imported files in the corresponding rules. Note that this now means a given imported file can potentially appear in multiple places in the bundle. However, esbuild will still only load it once (e.g. on-load plugins will only run once per file, not once per import).\n\n## 0.18.19\n\n* Implement `composes` from CSS modules ([#20](https://github.com/evanw/esbuild/issues/20))\n\n    This release implements the `composes` annotation from the [CSS modules specification](https://github.com/css-modules/css-modules#composition). It provides a way for class selectors to reference other class selectors (assuming you are using the `local-css` loader). And with the `from` syntax, this can even work with local names across CSS files. For example:\n\n    ```js\n    // app.js\n    import { submit } from './style.css'\n    const div = document.createElement('div')\n    div.className = submit\n    document.body.appendChild(div)\n    ```\n\n    ```css\n    /* style.css */\n    .button {\n      composes: pulse from \"anim.css\";\n      display: inline-block;\n    }\n    .submit {\n      composes: button;\n      font-weight: bold;\n    }\n    ```\n\n    ```css\n    /* anim.css */\n    @keyframes pulse {\n      from, to { opacity: 1 }\n      50% { opacity: 0.5 }\n    }\n    .pulse {\n      animation: 2s ease-in-out infinite pulse;\n    }\n    ```\n\n    Bundling this with esbuild using `--bundle --outdir=dist --loader:.css=local-css` now gives the following:\n\n    ```js\n    (() => {\n      // style.css\n      var submit = \"anim_pulse style_button style_submit\";\n\n      // app.js\n      var div = document.createElement(\"div\");\n      div.className = submit;\n      document.body.appendChild(div);\n    })();\n    ```\n\n    ```css\n    /* anim.css */\n    @keyframes anim_pulse {\n      from, to {\n        opacity: 1;\n      }\n      50% {\n        opacity: 0.5;\n      }\n    }\n    .anim_pulse {\n      animation: 2s ease-in-out infinite anim_pulse;\n    }\n\n    /* style.css */\n    .style_button {\n      display: inline-block;\n    }\n    .style_submit {\n      font-weight: bold;\n    }\n    ```\n\n    Import paths in the `composes: ... from` syntax are resolved using the new `composes-from` import kind, which can be intercepted by plugins during import path resolution when bundling is enabled.\n\n    Note that the order in which composed CSS classes from separate files appear in the bundled output file is deliberately _**undefined**_ by design (see [the specification](https://github.com/css-modules/css-modules#composing-from-other-files) for details). You are not supposed to declare the same CSS property in two separate class selectors and then compose them together. You are only supposed to compose CSS class selectors that declare non-overlapping CSS properties.\n\n    Issue [#20](https://github.com/evanw/esbuild/issues/20) (the issue tracking CSS modules) is esbuild's most-upvoted issue! With this change, I now consider esbuild's implementation of CSS modules to be complete. There are still improvements to make and there may also be bugs with the current implementation, but these can be tracked in separate issues.\n\n* Fix non-determinism with `tsconfig.json` and symlinks ([#3284](https://github.com/evanw/esbuild/issues/3284))\n\n    This release fixes an issue that could cause esbuild to sometimes emit incorrect build output in cases where a file under the effect of `tsconfig.json` is inconsistently referenced through a symlink. It can happen when using `npm link` to create a symlink within `node_modules` to an unpublished package. The build result was non-deterministic because esbuild runs module resolution in parallel and the result of the `tsconfig.json` lookup depended on whether the import through the symlink or not through the symlink was resolved first. This problem was fixed by moving the `realpath` operation before the `tsconfig.json` lookup.\n\n* Add a `hash` property to output files ([#3084](https://github.com/evanw/esbuild/issues/3084), [#3293](https://github.com/evanw/esbuild/issues/3293))\n\n    As a convenience, every output file in esbuild's API now includes a `hash` property that is a hash of the `contents` field. This is the hash that's used internally by esbuild to detect changes between builds for esbuild's live-reload feature. You may also use it to detect changes between your own builds if its properties are sufficient for your use case.\n\n    This feature has been added directly to output file objects since it's just a hash of the `contents` field, so it makes conceptual sense to store it in the same location. Another benefit of putting it there instead of including it as a part of the watch mode API is that it can be used without watch mode enabled. You can use it to compare the output of two independent builds that were done at different times.\n\n    The hash algorithm (currently [XXH64](https://xxhash.com/)) is implementation-dependent and may be changed at any time in between esbuild versions. If you don't like esbuild's choice of hash algorithm then you are welcome to hash the contents yourself instead. As with any hash algorithm, note that while two different hashes mean that the contents are different, two equal hashes do not necessarily mean that the contents are equal. You may still want to compare the contents in addition to the hashes to detect with certainty when output files have been changed.\n\n* Avoid generating duplicate prefixed declarations in CSS ([#3292](https://github.com/evanw/esbuild/issues/3292))\n\n    There was a request for esbuild's CSS prefixer to avoid generating a prefixed declaration if a declaration by that name is already present in the same rule block. So with this release, esbuild will now avoid doing this:\n\n    ```css\n    /* Original code */\n    body {\n      backdrop-filter: blur(30px);\n      -webkit-backdrop-filter: blur(45px);\n    }\n\n    /* Old output (with --target=safari12) */\n    body {\n      -webkit-backdrop-filter: blur(30px);\n      backdrop-filter: blur(30px);\n      -webkit-backdrop-filter: blur(45px);\n    }\n\n    /* New output (with --target=safari12) */\n    body {\n      backdrop-filter: blur(30px);\n      -webkit-backdrop-filter: blur(45px);\n    }\n    ```\n\n    This can result in a visual difference in certain cases (for example if the browser understands `blur(30px)` but not `blur(45px)`, it will be able to fall back to `blur(30px)`). But this change means esbuild now matches the behavior of [Autoprefixer](https://autoprefixer.github.io/) which is probably a good representation of how people expect this feature to work.\n\n## 0.18.18\n\n* Fix asset references with the `--line-limit` flag ([#3286](https://github.com/evanw/esbuild/issues/3286))\n\n    The recently-released `--line-limit` flag tells esbuild to terminate long lines after they pass this length limit. This includes automatically wrapping long strings across multiple lines using escaped newline syntax. However, using this could cause esbuild to generate incorrect code for references from generated output files to assets in the bundle (i.e. files loaded with the `file` or `copy` loaders). This is because esbuild implements asset references internally using find-and-replace with a randomly-generated string, but the find operation fails if the string is split by an escaped newline due to line wrapping. This release fixes the problem by not wrapping these strings. This issue affected asset references in both JS and CSS files.\n\n* Support local names in CSS for `@keyframe`, `@counter-style`, and `@container` ([#20](https://github.com/evanw/esbuild/issues/20))\n\n    This release extends support for local names in CSS files loaded with the `local-css` loader to cover the `@keyframe`, `@counter-style`, and `@container` rules (and also `animation`, `list-style`, and `container` declarations). Here's an example:\n\n    ```css\n    @keyframes pulse {\n      from, to { opacity: 1 }\n      50% { opacity: 0.5 }\n    }\n    @counter-style moon {\n      system: cyclic;\n      symbols: 🌕 🌖 🌗 🌘 🌑 🌒 🌓 🌔;\n    }\n    @container squish {\n      li { float: left }\n    }\n    ul {\n      animation: 2s ease-in-out infinite pulse;\n      list-style: inside moon;\n      container: squish / size;\n    }\n    ```\n\n    With the `local-css` loader enabled, that CSS will be turned into something like this (with the local name mapping exposed to JS):\n\n    ```css\n    @keyframes stdin_pulse {\n      from, to {\n        opacity: 1;\n      }\n      50% {\n        opacity: 0.5;\n      }\n    }\n    @counter-style stdin_moon {\n      system: cyclic;\n      symbols: 🌕 🌖 🌗 🌘 🌑 🌒 🌓 🌔;\n    }\n    @container stdin_squish {\n      li {\n        float: left;\n      }\n    }\n    ul {\n      animation: 2s ease-in-out infinite stdin_pulse;\n      list-style: inside stdin_moon;\n      container: stdin_squish / size;\n    }\n    ```\n\n    If you want to use a global name within a file loaded with the `local-css` loader, you can use a `:global` selector to do that:\n\n    ```css\n    div {\n      /* All symbols are global inside this scope (i.e.\n       * \"pulse\", \"moon\", and \"squish\" are global below) */\n      :global {\n        animation: 2s ease-in-out infinite pulse;\n        list-style: inside moon;\n        container: squish / size;\n      }\n    }\n    ```\n\n    If you want to use `@keyframes`, `@counter-style`, or `@container` with a global name, make sure it's in a file that uses the `css` or `global-css` loader instead of the `local-css` loader. For example, you can configure `--loader:.module.css=local-css` so that the `local-css` loader only applies to `*.module.css` files.\n\n* Support strings as keyframe animation names in CSS ([#2555](https://github.com/evanw/esbuild/issues/2555))\n\n    With this release, esbuild will now parse animation names that are specified as strings and will convert them to identifiers. The CSS specification allows animation names to be specified using either identifiers or strings but Chrome only understands identifiers, so esbuild will now always convert string names to identifier names for Chrome compatibility:\n\n    ```css\n    /* Original code */\n    @keyframes \"hide menu\" {\n      from { opacity: 1 }\n      to { opacity: 0 }\n    }\n    menu.hide {\n      animation: 0.5s ease-in-out \"hide menu\";\n    }\n\n    /* Old output */\n    @keyframes \"hide menu\" { from { opacity: 1 } to { opacity: 0 } }\n    menu.hide {\n      animation: 0.5s ease-in-out \"hide menu\";\n    }\n\n    /* New output */\n    @keyframes hide\\ menu {\n      from {\n        opacity: 1;\n      }\n      to {\n        opacity: 0;\n      }\n    }\n    menu.hide {\n      animation: 0.5s ease-in-out hide\\ menu;\n    }\n    ```\n\n## 0.18.17\n\n* Support `An+B` syntax and `:nth-*()` pseudo-classes in CSS\n\n    This adds support for the `:nth-child()`, `:nth-last-child()`, `:nth-of-type()`, and `:nth-last-of-type()` pseudo-classes to esbuild, which has the following consequences:\n\n    * The [`An+B` syntax](https://drafts.csswg.org/css-syntax-3/#anb-microsyntax) is now parsed, so parse errors are now reported\n    * `An+B` values inside these pseudo-classes are now pretty-printed (e.g. a leading `+` will be stripped because it's not in the AST)\n    * When minification is enabled, `An+B` values are reduced to equivalent but shorter forms (e.g. `2n+0` => `2n`, `2n+1` => `odd`)\n    * Local CSS names in an `of` clause are now detected (e.g. in `:nth-child(2n of :local(.foo))` the name `foo` is now renamed)\n\n    ```css\n    /* Original code */\n    .foo:nth-child(+2n+1 of :local(.bar)) {\n      color: red;\n    }\n\n    /* Old output (with --loader=local-css) */\n    .stdin_foo:nth-child(+2n + 1 of :local(.bar)) {\n      color: red;\n    }\n\n    /* New output (with --loader=local-css) */\n    .stdin_foo:nth-child(2n+1 of .stdin_bar) {\n      color: red;\n    }\n    ```\n\n* Adjust CSS nesting parser for IE7 hacks ([#3272](https://github.com/evanw/esbuild/issues/3272))\n\n    This fixes a regression with esbuild's treatment of IE7 hacks in CSS. CSS nesting allows selectors to be used where declarations are expected. There's an IE7 hack where prefixing a declaration with a `*` causes that declaration to only be applied in IE7 due to a bug in IE7's CSS parser. However, it's valid for nested CSS selectors to start with `*`. So esbuild was incorrectly parsing these declarations and anything following it up until the next `{` as a selector for a nested CSS rule. This release changes esbuild's parser to terminate the parsing of selectors for nested CSS rules when a `;` is encountered to fix this edge case:\n\n    ```css\n    /* Original code */\n    .item {\n      *width: 100%;\n      height: 1px;\n    }\n\n    /* Old output */\n    .item {\n      *width: 100%; height: 1px; {\n      }\n    }\n\n    /* New output */\n    .item {\n      *width: 100%;\n      height: 1px;\n    }\n    ```\n\n    Note that the syntax for CSS nesting is [about to change again](https://github.com/w3c/csswg-drafts/issues/7961), so esbuild's CSS parser may still not be completely accurate with how browsers do and/or will interpret CSS nesting syntax. Expect additional updates to esbuild's CSS parser in the future to deal with upcoming CSS specification changes.\n\n* Adjust esbuild's warning about undefined imports for TypeScript `import` equals declarations ([#3271](https://github.com/evanw/esbuild/issues/3271))\n\n    In JavaScript, accessing a missing property on an import namespace object is supposed to result in a value of `undefined` at run-time instead of an error at compile-time. This is something that esbuild warns you about by default because doing this can indicate a bug with your code. For example:\n\n    ```js\n    // app.js\n    import * as styles from './styles'\n    console.log(styles.buton)\n    ```\n\n    ```js\n    // styles.js\n    export let button = {}\n    ```\n\n    If you bundle `app.js` with esbuild you will get this:\n\n    ```\n    ▲ [WARNING] Import \"buton\" will always be undefined because there is no matching export in \"styles.js\" [import-is-undefined]\n\n        app.js:2:19:\n          2 │ console.log(styles.buton)\n            │                    ~~~~~\n            ╵                    button\n\n      Did you mean to import \"button\" instead?\n\n        styles.js:1:11:\n          1 │ export let button = {}\n            ╵            ~~~~~~\n    ```\n\n    However, there is TypeScript-only syntax for `import` equals declarations that can represent either a type import (which esbuild should ignore) or a value import (which esbuild should respect). Since esbuild doesn't have a type system, it tries to only respect `import` equals declarations that are actually used as values. Previously esbuild always generated this warning for unused imports referenced within `import` equals declarations even when the reference could be a type instead of a value. Starting with this release, esbuild will now only warn in this case if the import is actually used. Here is an example of some code that no longer causes an incorrect warning:\n\n    ```ts\n    // app.ts\n    import * as styles from './styles'\n    import ButtonType = styles.Button\n    ```\n\n    ```ts\n    // styles.ts\n    export interface Button {}\n    ```\n\n## 0.18.16\n\n* Fix a regression with whitespace inside `:is()` ([#3265](https://github.com/evanw/esbuild/issues/3265))\n\n    The change to parse the contents of `:is()` in version 0.18.14 introduced a regression that incorrectly flagged the contents as a syntax error if the contents started with a whitespace token (for example `div:is( .foo ) {}`). This regression has been fixed.\n\n## 0.18.15\n\n* Add the `--serve-fallback=` option ([#2904](https://github.com/evanw/esbuild/issues/2904))\n\n    The web server built into esbuild serves the latest in-memory results of the configured build. If the requested path doesn't match any in-memory build result, esbuild also provides the `--servedir=` option to tell esbuild to serve the requested path from that directory instead. And if the requested path doesn't match either of those things, esbuild will either automatically generate a directory listing (for directories) or return a 404 error.\n\n    Starting with this release, that last step can now be replaced with telling esbuild to serve a specific HTML file using the `--serve-fallback=` option. This can be used to provide a \"not found\" page for missing URLs. It can also be used to implement a [single-page app](https://en.wikipedia.org/wiki/Single-page_application) that mutates the current URL and therefore requires the single app entry point to be served when the page is loaded regardless of whatever the current URL is.\n\n* Use the `tsconfig` field in `package.json` during `extends` resolution ([#3247](https://github.com/evanw/esbuild/issues/3247))\n\n     This release adds a feature from [TypeScript 3.2](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-2.html#tsconfigjson-inheritance-via-nodejs-packages) where if a `tsconfig.json` file specifies a package name in the `extends` field and that package's `package.json` file has a `tsconfig` field, the contents of that field are used in the search for the base `tsconfig.json` file.\n\n* Implement CSS nesting without `:is()` when possible ([#1945](https://github.com/evanw/esbuild/issues/1945))\n\n    Previously esbuild would always produce a warning when transforming nested CSS for a browser that doesn't support the `:is()` pseudo-class. This was because the nesting transform needs to generate an `:is()` in some complex cases which means the transformed CSS would then not work in that browser. However, the CSS nesting transform can often be done without generating an `:is()`. So with this release, esbuild will no longer warn when targeting browsers that don't support `:is()` in the cases where an `:is()` isn't needed to represent the nested CSS.\n\n    In addition, esbuild's nested CSS transform has been updated to avoid generating an `:is()` in cases where an `:is()` is preferable but there's a longer alternative that is also equivalent. This update means esbuild can now generate a combinatorial explosion of CSS for complex CSS nesting syntax when targeting browsers that don't support `:is()`. This combinatorial explosion is necessary to accurately represent the original semantics. For example:\n\n    ```css\n    /* Original code */\n    .first,\n    .second,\n    .third {\n      & > & {\n        color: red;\n      }\n    }\n\n    /* Old output (with --target=chrome80) */\n    :is(.first, .second, .third) > :is(.first, .second, .third) {\n      color: red;\n    }\n\n    /* New output (with --target=chrome80) */\n    .first > .first,\n    .first > .second,\n    .first > .third,\n    .second > .first,\n    .second > .second,\n    .second > .third,\n    .third > .first,\n    .third > .second,\n    .third > .third {\n      color: red;\n    }\n    ```\n\n    This change means you can now use CSS nesting with esbuild when targeting an older browser that doesn't support `:is()`. You'll now only get a warning from esbuild if you use complex CSS nesting syntax that esbuild can't represent in that older browser without using `:is()`. There are two such cases:\n\n    ```css\n    /* Case 1 */\n    a b {\n      .foo & {\n        color: red;\n      }\n    }\n\n    /* Case 2 */\n    a {\n      > b& {\n        color: red;\n      }\n    }\n    ```\n\n    These two cases still need to use `:is()`, both for different reasons, and cannot be used when targeting an older browser that doesn't support `:is()`:\n\n    ```css\n    /* Case 1 */\n    .foo :is(a b) {\n      color: red;\n    }\n\n    /* Case 2 */\n    a > a:is(b) {\n      color: red;\n    }\n    ```\n\n* Automatically lower `inset` in CSS for older browsers\n\n    With this release, esbuild will now automatically expand the `inset` property to the `top`, `right`, `bottom`, and `left` properties when esbuild's `target` is set to a browser that doesn't support `inset`:\n\n    ```css\n    /* Original code */\n    .app {\n      position: absolute;\n      inset: 10px 20px;\n    }\n\n    /* Old output (with --target=chrome80) */\n    .app {\n      position: absolute;\n      inset: 10px 20px;\n    }\n\n    /* New output (with --target=chrome80) */\n    .app {\n      position: absolute;\n      top: 10px;\n      right: 20px;\n      bottom: 10px;\n      left: 20px;\n    }\n    ```\n\n* Add support for the new [`@starting-style`](https://drafts.csswg.org/css-transitions-2/#defining-before-change-style-the-starting-style-rule) CSS rule ([#3249](https://github.com/evanw/esbuild/pull/3249))\n\n    This at rule allow authors to start CSS transitions on first style update. That is, you can now make the transition take effect when the `display` property changes from `none` to `block`.\n\n    ```css\n    /* Original code */\n    @starting-style {\n      h1 {\n        background-color: transparent;\n      }\n    }\n\n    /* Output */\n    @starting-style{h1{background-color:transparent}}\n    ```\n\n    This was contributed by [@yisibl](https://github.com/yisibl).\n\n## 0.18.14\n\n* Implement local CSS names ([#20](https://github.com/evanw/esbuild/issues/20))\n\n    This release introduces two new loaders called `global-css` and `local-css` and two new pseudo-class selectors `:local()` and `:global()`. This is a partial implementation of the popular [CSS modules](https://github.com/css-modules/css-modules) approach for avoiding unintentional name collisions in CSS. I'm not calling this feature \"CSS modules\" because although some people in the community call it that, other people in the community have started using \"CSS modules\" to refer to [something completely different](https://github.com/WICG/webcomponents/blob/60c9f682b63c622bfa0d8222ea6b1f3b659e007c/proposals/css-modules-v1-explainer.md) and now CSS modules is an overloaded term.\n\n    Here's how this new local CSS name feature works with esbuild:\n\n    * Identifiers that look like `.className` and `#idName` are global with the `global-css` loader and local with the `local-css` loader. Global identifiers are the same across all files (the way CSS normally works) but local identifiers are different between different files. If two separate CSS files use the same local identifier `.button`, esbuild will automatically rename one of them so that they don't collide. This is analogous to how esbuild automatically renames JS local variables with the same name in separate JS files to avoid name collisions.\n\n    * It only makes sense to use local CSS names with esbuild when you are also using esbuild's bundler to bundle JS files that import CSS files. When you do that, esbuild will generate one export for each local name in the CSS file. The JS code can import these names and use them when constructing HTML DOM. For example:\n\n        ```js\n        // app.js\n        import { outerShell } from './app.css'\n        const div = document.createElement('div')\n        div.className = outerShell\n        document.body.appendChild(div)\n        ```\n\n        ```css\n        /* app.css */\n        .outerShell {\n          position: absolute;\n          inset: 0;\n        }\n        ```\n\n        When you bundle this with `esbuild app.js --bundle --loader:.css=local-css --outdir=out` you'll now get this (notice how the local CSS name `outerShell` has been renamed):\n\n        ```js\n        // out/app.js\n        (() => {\n          // app.css\n          var outerShell = \"app_outerShell\";\n\n          // app.js\n          var div = document.createElement(\"div\");\n          div.className = outerShell;\n          document.body.appendChild(div);\n        })();\n        ```\n\n        ```css\n        /* out/app.css */\n        .app_outerShell {\n          position: absolute;\n          inset: 0;\n        }\n        ```\n\n        This feature only makes sense to use when bundling is enabled both because your code needs to `import` the renamed local names so that it can use them, and because esbuild needs to be able to process all CSS files containing local names in a single bundling operation so that it can successfully rename conflicting local names to avoid collisions.\n\n    * If you are in a global CSS file (with the `global-css` loader) you can create a local name using `:local()`, and if you are in a local CSS file (with the `local-css` loader) you can create a global name with `:global()`. So the choice of the `global-css` loader vs. the `local-css` loader just sets the default behavior for identifiers, but you can override it on a case-by-case basis as necessary. For example:\n\n        ```css\n        :local(.button) {\n          color: red;\n        }\n        :global(.button) {\n          color: blue;\n        }\n        ```\n\n        Processing this CSS file with esbuild with either the `global-css` or `local-css` loader will result in something like this:\n\n        ```css\n        .stdin_button {\n          color: red;\n        }\n        .button {\n          color: blue;\n        }\n        ```\n\n    * The names that esbuild generates for local CSS names are an implementation detail and are not intended to be hard-coded anywhere. The only way you should be referencing the local CSS names in your JS or HTML is with an `import` statement in JS that is bundled with esbuild, as demonstrated above. For example, when `--minify` is enabled esbuild will use a different name generation algorithm which generates names that are as short as possible (analogous to how esbuild minifies local identifiers in JS).\n\n    * You can easily use both global CSS files and local CSS files simultaneously if you give them different file extensions. For example, you could pass `--loader:.css=global-css` and `--loader:.module.css=local-css` to esbuild so that `.css` files still use global names by default but `.module.css` files use local names by default.\n\n    * Keep in mind that the `css` loader is different than the `global-css` loader. The `:local` and `:global` annotations are not enabled with the `css` loader and will be passed through unchanged. This allows you to have the option of using esbuild to process CSS containing while preserving these annotations. It also means that local CSS names are disabled by default for now (since the `css` loader is currently the default for CSS files). The `:local` and `:global` syntax may be enabled by default in a future release.\n\n    Note that esbuild's implementation does not currently have feature parity with other implementations of modular CSS in similar tools. This is only a preliminary release with a partial implementation that includes some basic behavior to get the process started. Additional behavior may be added in future releases. In particular, this release does not implement:\n\n    * The `composes` pragma\n    * Tree shaking for unused local CSS\n    * Local names for keyframe animations, grid lines, `@container`, `@counter-style`, etc.\n\n    Issue [#20](https://github.com/evanw/esbuild/issues/20) (the issue for this feature) is esbuild's most-upvoted issue! While this release still leaves that issue open, it's an important first step in that direction.\n\n* Parse `:is`, `:has`, `:not`, and `:where` in CSS\n\n    With this release, esbuild will now parse the contents of these pseudo-class selectors as a selector list. This means you will now get syntax warnings within these selectors for invalid selector syntax. It also means that esbuild's CSS nesting transform behaves slightly differently than before because esbuild is now operating on an AST instead of a token stream. For example:\n\n    ```css\n    /* Original code */\n    div {\n      :where(.foo&) {\n        color: red;\n      }\n    }\n\n    /* Old output (with --target=chrome90) */\n    :where(.foo:is(div)) {\n      color: red;\n    }\n\n    /* New output (with --target=chrome90) */\n    :where(div.foo) {\n      color: red;\n    }\n    ```\n\n## 0.18.13\n\n* Add the `--drop-labels=` option ([#2398](https://github.com/evanw/esbuild/issues/2398))\n\n    If you want to conditionally disable some development-only code and have it not be present in the final production bundle, right now the most straightforward way of doing this is to use the `--define:` flag along with a specially-named global variable. For example, consider the following code:\n\n    ```js\n    function main() {\n      DEV && doAnExpensiveCheck()\n    }\n    ```\n\n    You can build this for development and production like this:\n\n    * Development: `esbuild --define:DEV=true`\n    * Production: `esbuild --define:DEV=false`\n\n    One drawback of this approach is that the resulting code crashes if you don't provide a value for `DEV` with `--define:`. In practice this isn't that big of a problem, and there are also various ways to work around this.\n\n    However, another approach that avoids this drawback is to use JavaScript label statements instead. That's what the `--drop-labels=` flag implements. For example, consider the following code:\n\n    ```js\n    function main() {\n      DEV: doAnExpensiveCheck()\n    }\n    ```\n\n    With this release, you can now build this for development and production like this:\n\n    * Development: `esbuild`\n    * Production: `esbuild --drop-labels=DEV`\n\n    This means that code containing optional development-only checks can now be written such that it's safe to run without any additional configuration. The `--drop-labels=` flag takes comma-separated list of multiple label names to drop.\n\n* Avoid causing `unhandledRejection` during shutdown ([#3219](https://github.com/evanw/esbuild/issues/3219))\n\n    All pending esbuild JavaScript API calls are supposed to fail if esbuild's underlying child process is unexpectedly terminated. This can happen if `SIGINT` is sent to the parent `node` process with Ctrl+C, for example. Previously doing this could also cause an unhandled promise rejection when esbuild attempted to communicate this failure to its own child process that no longer exists. This release now swallows this communication failure, which should prevent this internal unhandled promise rejection. This change means that you can now use esbuild's JavaScript API with a custom `SIGINT` handler that extends the lifetime of the `node` process without esbuild's internals causing an early exit due to an unhandled promise rejection.\n\n* Update browser compatibility table scripts\n\n    The scripts that esbuild uses to compile its internal browser compatibility table have been overhauled. Briefly:\n\n    * Converted from JavaScript to TypeScript\n    * Fixed some bugs that resulted in small changes to the table\n    * Added [`caniuse-lite`](https://www.npmjs.com/package/caniuse-lite) and [`@mdn/browser-compat-data`](https://www.npmjs.com/package/@mdn/browser-compat-data) as new data sources (replacing manually-copied information)\n\n    This change means it's now much easier to keep esbuild's internal compatibility tables up to date. You can review the table changes here if you need to debug something about this change:\n\n    * [JS table changes](https://github.com/evanw/esbuild/compare/d259b8fac717ee347c19bd8299f2c26d7c87481a...af1d35c372f78c14f364b63e819fd69548508f55#diff-1649eb68992c79753469f02c097de309adaf7231b45cc816c50bf751af400eb4)\n    * [CSS table changes](https://github.com/evanw/esbuild/commit/95feb2e09877597cb929469ce43811bdf11f50c1#diff-4e1c4f269e02c5ea31cbd5138d66751e32cf0e240524ee8a966ac756f0e3c3cd)\n\n## 0.18.12\n\n* Fix a panic with `const enum` inside parentheses ([#3205](https://github.com/evanw/esbuild/issues/3205))\n\n    This release fixes an edge case where esbuild could potentially panic if a TypeScript `const enum` statement was used inside of a parenthesized expression and was followed by certain other scope-related statements. Here's a minimal example that triggers this edge case:\n\n    ```ts\n    (() => {\n      const enum E { a };\n      () => E.a\n    })\n    ```\n\n* Allow a newline in the middle of TypeScript `export type` statement ([#3225](https://github.com/evanw/esbuild/issues/3225))\n\n    Previously esbuild incorrectly rejected the following valid TypeScript code:\n\n    ```ts\n    export type\n    { T };\n\n    export type\n    * as foo from 'bar';\n    ```\n\n    Code that uses a newline after `export type` is now allowed starting with this release.\n\n* Fix cross-module inlining of string enums ([#3210](https://github.com/evanw/esbuild/issues/3210))\n\n    A refactoring typo in version 0.18.9 accidentally introduced a regression with cross-module inlining of string enums when combined with computed property accesses. This regression has been fixed.\n\n* Rewrite `.js` to `.ts` inside packages with `exports` ([#3201](https://github.com/evanw/esbuild/issues/3201))\n\n    Packages with the `exports` field are supposed to disable node's path resolution behavior that allows you to import a file with a different extension than the one in the source code (for example, importing `foo/bar` to get `foo/bar.js`). And TypeScript has behavior where you can import a non-existent `.js` file and you will get the `.ts` file instead. Previously the presence of the `exports` field caused esbuild to disable all extension manipulation stuff which included both node's implicit file extension searching and TypeScript's file extension swapping. However, TypeScript appears to always apply file extension swapping even in this case. So with this release, esbuild will now rewrite `.js` to `.ts` even inside packages with `exports`.\n\n* Fix a redirect edge case in esbuild's development server ([#3208](https://github.com/evanw/esbuild/issues/3208))\n\n    The development server canonicalizes directory URLs by adding a trailing slash. For example, visiting `/about` redirects to `/about/` if `/about/index.html` would be served. However, if the requested path begins with two slashes, then the redirect incorrectly turned into a protocol-relative URL. For example, visiting `//about` redirected to `//about/` which the browser turns into `http://about/`. This release fixes the bug by canonicalizing the URL path when doing this redirect.\n\n## 0.18.11\n\n* Fix a TypeScript code generation edge case ([#3199](https://github.com/evanw/esbuild/issues/3199))\n\n    This release fixes a regression in version 0.18.4 where using a TypeScript `namespace` that exports a `class` declaration combined with `--keep-names` and a `--target` of `es2021` or earlier could cause esbuild to export the class from the namespace using an incorrect name (notice the assignment to `X2._Y` vs. `X2.Y`):\n\n    ```ts\n    // Original code\n\n    // Old output (with --keep-names --target=es2021)\n    var X;\n    ((X2) => {\n      const _Y = class _Y {\n      };\n      __name(_Y, \"Y\");\n      let Y = _Y;\n      X2._Y = _Y;\n    })(X || (X = {}));\n\n    // New output (with --keep-names --target=es2021)\n    var X;\n    ((X2) => {\n      const _Y = class _Y {\n      };\n      __name(_Y, \"Y\");\n      let Y = _Y;\n      X2.Y = _Y;\n    })(X || (X = {}));\n    ```\n\n## 0.18.10\n\n* Fix a tree-shaking bug that removed side effects ([#3195](https://github.com/evanw/esbuild/issues/3195))\n\n    This fixes a regression in version 0.18.4 where combining `--minify-syntax` with `--keep-names` could cause expressions with side effects after a function declaration to be considered side-effect free for tree shaking purposes. The reason was because `--keep-names` generates an expression statement containing a call to a helper function after the function declaration with a special flag that makes the function call able to be tree shaken, and then `--minify-syntax` could potentially merge that expression statement with following expressions without clearing the flag. This release fixes the bug by clearing the flag when merging expression statements together.\n\n* Fix an incorrect warning about CSS nesting ([#3197](https://github.com/evanw/esbuild/issues/3197))\n\n    A warning is currently generated when transforming nested CSS to a browser that doesn't support `:is()` because transformed nested CSS may need to use that feature to represent nesting. This was previously always triggered when an at-rule was encountered in a declaration context. Typically the only case you would encounter this is when using CSS nesting within a selector rule. However, there is a case where that's not true: when using a margin at-rule such as `@top-left` within `@page`. This release avoids incorrectly generating a warning in this case by checking that the at-rule is within a selector rule before generating a warning.\n\n## 0.18.9\n\n* Fix `await using` declarations inside `async` generator functions\n\n    I forgot about the new `await using` declarations when implementing lowering for `async` generator functions in the previous release. This change fixes the transformation of `await using` declarations when they are inside lowered `async` generator functions:\n\n    ```js\n    // Original code\n    async function* foo() {\n      await using x = await y\n    }\n\n    // Old output (with --supported:async-generator=false)\n    function foo() {\n      return __asyncGenerator(this, null, function* () {\n        await using x = yield new __await(y);\n      });\n    }\n\n    // New output (with --supported:async-generator=false)\n    function foo() {\n      return __asyncGenerator(this, null, function* () {\n        var _stack = [];\n        try {\n          const x = __using(_stack, yield new __await(y), true);\n        } catch (_) {\n          var _error = _, _hasError = true;\n        } finally {\n          var _promise = __callDispose(_stack, _error, _hasError);\n          _promise && (yield new __await(_promise));\n        }\n      });\n    }\n    ```\n\n* Insert some prefixed CSS properties when appropriate ([#3122](https://github.com/evanw/esbuild/issues/3122))\n\n    With this release, esbuild will now insert prefixed CSS properties in certain cases when the `target` setting includes browsers that require a certain prefix. This is currently done for the following properties:\n\n    * `appearance: *;` => `-webkit-appearance: *; -moz-appearance: *;`\n    * `backdrop-filter: *;` => `-webkit-backdrop-filter: *;`\n    * `background-clip: text` => `-webkit-background-clip: text;`\n    * `box-decoration-break: *;` => `-webkit-box-decoration-break: *;`\n    * `clip-path: *;` => `-webkit-clip-path: *;`\n    * `font-kerning: *;` => `-webkit-font-kerning: *;`\n    * `hyphens: *;` => `-webkit-hyphens: *;`\n    * `initial-letter: *;` => `-webkit-initial-letter: *;`\n    * `mask-image: *;` => `-webkit-mask-image: *;`\n    * `mask-origin: *;` => `-webkit-mask-origin: *;`\n    * `mask-position: *;` => `-webkit-mask-position: *;`\n    * `mask-repeat: *;` => `-webkit-mask-repeat: *;`\n    * `mask-size: *;` => `-webkit-mask-size: *;`\n    * `position: sticky;` => `position: -webkit-sticky;`\n    * `print-color-adjust: *;` => `-webkit-print-color-adjust: *;`\n    * `tab-size: *;` => `-moz-tab-size: *; -o-tab-size: *;`\n    * `text-decoration-color: *;` => `-webkit-text-decoration-color: *; -moz-text-decoration-color: *;`\n    * `text-decoration-line: *;` => `-webkit-text-decoration-line: *; -moz-text-decoration-line: *;`\n    * `text-decoration-skip: *;` => `-webkit-text-decoration-skip: *;`\n    * `text-emphasis-color: *;` => `-webkit-text-emphasis-color: *;`\n    * `text-emphasis-position: *;` => `-webkit-text-emphasis-position: *;`\n    * `text-emphasis-style: *;` => `-webkit-text-emphasis-style: *;`\n    * `text-orientation: *;` => `-webkit-text-orientation: *;`\n    * `text-size-adjust: *;` => `-webkit-text-size-adjust: *; -ms-text-size-adjust: *;`\n    * `user-select: *;` => `-webkit-user-select: *; -moz-user-select: *; -ms-user-select: *;`\n\n    Here is an example:\n\n    ```css\n    /* Original code */\n    div {\n      mask-image: url(x.png);\n    }\n\n    /* Old output (with --target=chrome99) */\n    div {\n      mask-image: url(x.png);\n    }\n\n    /* New output (with --target=chrome99) */\n    div {\n      -webkit-mask-image: url(x.png);\n      mask-image: url(x.png);\n    }\n    ```\n\n    Browser compatibility data was sourced from the tables on https://caniuse.com. Support for more CSS properties can be added in the future as appropriate.\n\n* Fix an obscure identifier minification bug ([#2809](https://github.com/evanw/esbuild/issues/2809))\n\n    Function declarations in nested scopes behave differently depending on whether or not `\"use strict\"` is present. To avoid generating code that behaves differently depending on whether strict mode is enabled or not, esbuild transforms nested function declarations into variable declarations. However, there was a bug where the generated variable name was not being recorded as declared internally, which meant that it wasn't being renamed correctly by the minifier and could cause a name collision. This bug has been fixed:\n\n    ```js\n    // Original code\n    const n = ''\n    for (let i of [0,1]) {\n      function f () {}\n    }\n\n    // Old output (with --minify-identifiers --format=esm)\n    const f = \"\";\n    for (let o of [0, 1]) {\n      let n = function() {\n      };\n      var f = n;\n    }\n\n    // New output (with --minify-identifiers --format=esm)\n    const f = \"\";\n    for (let o of [0, 1]) {\n      let n = function() {\n      };\n      var t = n;\n    }\n    ```\n\n* Fix a bug in esbuild's compatibility table script ([#3179](https://github.com/evanw/esbuild/pull/3179))\n\n    Setting esbuild's `target` to a specific JavaScript engine tells esbuild to use the JavaScript syntax feature compatibility data from https://kangax.github.io/compat-table/es6/ for that engine to determine which syntax features to allow. However, esbuild's script that builds this internal compatibility table had a bug that incorrectly ignores tests for engines that still have outstanding implementation bugs which were never fixed. This change fixes this bug with the script.\n\n    The only case where this changed the information in esbuild's internal compatibility table is that the `hermes` target is marked as no longer supporting destructuring. This is because there is a failing destructuring-related test for Hermes on https://kangax.github.io/compat-table/es6/. If you want to use destructuring with Hermes anyway, you can pass `--supported:destructuring=true` to esbuild to override the `hermes` target and force esbuild to accept this syntax.\n\n    This fix was contributed by [@ArrayZoneYour](https://github.com/ArrayZoneYour).\n\n## 0.18.8\n\n* Implement transforming `async` generator functions ([#2780](https://github.com/evanw/esbuild/issues/2780))\n\n    With this release, esbuild will now transform `async` generator functions into normal generator functions when the configured target environment doesn't support them. These functions behave similar to normal generator functions except that they use the `Symbol.asyncIterator` interface instead of the `Symbol.iterator` interface and the iteration methods return promises. Here's an example (helper functions are omitted):\n\n    ```js\n    // Original code\n    async function* foo() {\n      yield Promise.resolve(1)\n      await new Promise(r => setTimeout(r, 100))\n      yield *[Promise.resolve(2)]\n    }\n    async function bar() {\n      for await (const x of foo()) {\n        console.log(x)\n      }\n    }\n    bar()\n\n    // New output (with --target=es6)\n    function foo() {\n      return __asyncGenerator(this, null, function* () {\n        yield Promise.resolve(1);\n        yield new __await(new Promise((r) => setTimeout(r, 100)));\n        yield* __yieldStar([Promise.resolve(2)]);\n      });\n    }\n    function bar() {\n      return __async(this, null, function* () {\n        try {\n          for (var iter = __forAwait(foo()), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {\n            const x = temp.value;\n            console.log(x);\n          }\n        } catch (temp) {\n          error = [temp];\n        } finally {\n          try {\n            more && (temp = iter.return) && (yield temp.call(iter));\n          } finally {\n            if (error)\n              throw error[0];\n          }\n        }\n      });\n    }\n    bar();\n    ```\n\n    This is an older feature that was added to JavaScript in ES2018 but I didn't implement the transformation then because it's a rarely-used feature. Note that esbuild already added support for transforming `for await` loops (the other part of the [asynchronous iteration proposal](https://github.com/tc39/proposal-async-iteration)) a year ago, so support for asynchronous iteration should now be complete.\n\n    I have never used this feature myself and code that uses this feature is hard to come by, so this transformation has not yet been tested on real-world code. If you do write code that uses this feature, please let me know if esbuild's `async` generator transformation doesn't work with your code.\n\n## 0.18.7\n\n* Add support for `using` declarations in TypeScript 5.2+ ([#3191](https://github.com/evanw/esbuild/issues/3191))\n\n    TypeScript 5.2 (due to be released in August of 2023) will introduce `using` declarations, which will allow you to automatically dispose of the declared resources when leaving the current scope. You can read the [TypeScript PR for this feature](https://github.com/microsoft/TypeScript/pull/54505) for more information. This release of esbuild adds support for transforming this syntax to target environments without support for `using` declarations (which is currently all targets other than `esnext`). Here's an example (helper functions are omitted):\n\n    ```js\n    // Original code\n    class Foo {\n      [Symbol.dispose]() {\n        console.log('cleanup')\n      }\n    }\n    using foo = new Foo;\n    foo.bar();\n\n    // New output (with --target=es6)\n    var _stack = [];\n    try {\n      var Foo = class {\n        [Symbol.dispose]() {\n          console.log(\"cleanup\");\n        }\n      };\n      var foo = __using(_stack, new Foo());\n      foo.bar();\n    } catch (_) {\n      var _error = _, _hasError = true;\n    } finally {\n      __callDispose(_stack, _error, _hasError);\n    }\n    ```\n\n    The injected helper functions ensure that the method named `Symbol.dispose` is called on `new Foo` when control exits the scope. Note that as with all new JavaScript APIs, you'll need to polyfill `Symbol.dispose` if it's not present before you use it. This is not something that esbuild does for you because esbuild only handles syntax, not APIs. Polyfilling it can be done with something like this:\n\n    ```js\n    Symbol.dispose ||= Symbol('Symbol.dispose')\n    ```\n\n    This feature also introduces `await using` declarations which are like `using` declarations but they call `await` on the disposal method (not on the initializer). Here's an example (helper functions are omitted):\n\n    ```js\n    // Original code\n    class Foo {\n      async [Symbol.asyncDispose]() {\n        await new Promise(done => {\n          setTimeout(done, 1000)\n        })\n        console.log('cleanup')\n      }\n    }\n    await using foo = new Foo;\n    foo.bar();\n\n    // New output (with --target=es2022)\n    var _stack = [];\n    try {\n      var Foo = class {\n        async [Symbol.asyncDispose]() {\n          await new Promise((done) => {\n            setTimeout(done, 1e3);\n          });\n          console.log(\"cleanup\");\n        }\n      };\n      var foo = __using(_stack, new Foo(), true);\n      foo.bar();\n    } catch (_) {\n      var _error = _, _hasError = true;\n    } finally {\n      var _promise = __callDispose(_stack, _error, _hasError);\n      _promise && await _promise;\n    }\n    ```\n\n    The injected helper functions ensure that the method named `Symbol.asyncDispose` is called on `new Foo` when control exits the scope, and that the returned promise is awaited. Similarly to `Symbol.dispose`, you'll also need to polyfill `Symbol.asyncDispose` before you use it.\n\n* Add a `--line-limit=` flag to limit line length ([#3170](https://github.com/evanw/esbuild/issues/3170))\n\n    Long lines are common in minified code. However, many tools and text editors can't handle long lines. This release introduces the `--line-limit=` flag to tell esbuild to wrap lines longer than the provided number of bytes. For example, `--line-limit=80` tells esbuild to insert a newline soon after a given line reaches 80 bytes in length. This setting applies to both JavaScript and CSS, and works even when minification is disabled. Note that turning this setting on will make your files bigger, as the extra newlines take up additional space in the file (even after gzip compression).\n\n## 0.18.6\n\n* Fix tree-shaking of classes with decorators ([#3164](https://github.com/evanw/esbuild/issues/3164))\n\n    This release fixes a bug where esbuild incorrectly allowed tree-shaking on classes with decorators. Each decorator is a function call, so classes with decorators must never be tree-shaken. This bug was a regression that was unintentionally introduced in version 0.18.2 by the change that enabled tree-shaking of lowered private fields. Previously decorators were always lowered, and esbuild always considered the automatically-generated decorator code to be a side effect. But this is no longer the case now that esbuild analyzes side effects using the AST before lowering takes place. This bug was fixed by considering any decorator a side effect.\n\n* Fix a minification bug involving function expressions ([#3125](https://github.com/evanw/esbuild/issues/3125))\n\n    When minification is enabled, esbuild does limited inlining of `const` symbols at the top of a scope. This release fixes a bug where inlineable symbols were incorrectly removed assuming that they were inlined. They may not be inlined in cases where they were referenced by earlier constants in the body of a function expression. The declarations involved in these edge cases are now kept instead of being removed:\n\n    ```js\n    // Original code\n    {\n      const fn = () => foo\n      const foo = 123\n      console.log(fn)\n    }\n\n    // Old output (with --minify-syntax)\n    console.log((() => foo)());\n\n    // New output (with --minify-syntax)\n    {\n      const fn = () => foo, foo = 123;\n      console.log(fn);\n    }\n    ```\n\n## 0.18.5\n\n* Implement auto accessors ([#3009](https://github.com/evanw/esbuild/issues/3009))\n\n    This release implements the new auto-accessor syntax from the upcoming [JavaScript decorators proposal](https://github.com/tc39/proposal-decorators). The auto-accessor syntax looks like this:\n\n    ```js\n    class Foo {\n      accessor foo;\n      static accessor bar;\n    }\n    new Foo().foo = Foo.bar;\n    ```\n\n    This syntax is not yet a part of JavaScript but it was [added to TypeScript in version 4.9](https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/#auto-accessors-in-classes). More information about this feature can be found in [microsoft/TypeScript#49705](https://github.com/microsoft/TypeScript/pull/49705). Auto-accessors will be transformed if the target is set to something other than `esnext`:\n\n    ```js\n    // Output (with --target=esnext)\n    class Foo {\n      accessor foo;\n      static accessor bar;\n    }\n    new Foo().foo = Foo.bar;\n\n    // Output (with --target=es2022)\n    class Foo {\n      #foo;\n      get foo() {\n        return this.#foo;\n      }\n      set foo(_) {\n        this.#foo = _;\n      }\n      static #bar;\n      static get bar() {\n        return this.#bar;\n      }\n      static set bar(_) {\n        this.#bar = _;\n      }\n    }\n    new Foo().foo = Foo.bar;\n\n    // Output (with --target=es2021)\n    var _foo, _bar;\n    class Foo {\n      constructor() {\n        __privateAdd(this, _foo, void 0);\n      }\n      get foo() {\n        return __privateGet(this, _foo);\n      }\n      set foo(_) {\n        __privateSet(this, _foo, _);\n      }\n      static get bar() {\n        return __privateGet(this, _bar);\n      }\n      static set bar(_) {\n        __privateSet(this, _bar, _);\n      }\n    }\n    _foo = new WeakMap();\n    _bar = new WeakMap();\n    __privateAdd(Foo, _bar, void 0);\n    new Foo().foo = Foo.bar;\n    ```\n\n    You can also now use auto-accessors with esbuild's TypeScript experimental decorator transformation, which should behave the same as decorating the underlying getter/setter pair.\n\n    **Please keep in mind that this syntax is not yet part of JavaScript.** This release enables auto-accessors in `.js` files with the expectation that it will be a part of JavaScript soon. However, esbuild may change or remove this feature in the future if JavaScript ends up changing or removing this feature. Use this feature with caution for now.\n\n* Pass through JavaScript decorators ([#104](https://github.com/evanw/esbuild/issues/104))\n\n    In this release, esbuild now parses decorators from the upcoming [JavaScript decorators proposal](https://github.com/tc39/proposal-decorators) and passes them through to the output unmodified (as long as the language target is set to `esnext`). Transforming JavaScript decorators to environments that don't support them has not been implemented yet. The only decorator transform that esbuild currently implements is still the TypeScript experimental decorator transform, which only works in `.ts` files and which requires `\"experimentalDecorators\": true` in your `tsconfig.json` file.\n\n* Static fields with assign semantics now use static blocks if possible\n\n    Setting `useDefineForClassFields` to false in TypeScript requires rewriting class fields to assignment statements. Previously this was done by removing the field from the class body and adding an assignment statement after the class declaration. However, this also caused any private fields to also be lowered by necessity (in case a field initializer uses a private symbol, either directly or indirectly). This release changes this transform to use an inline static block if it's supported, which avoids needing to lower private fields in this scenario:\n\n    ```js\n    // Original code\n    class Test {\n      static #foo = 123\n      static bar = this.#foo\n    }\n\n    // Old output (with useDefineForClassFields=false)\n    var _foo;\n    const _Test = class _Test {\n    };\n    _foo = new WeakMap();\n    __privateAdd(_Test, _foo, 123);\n    _Test.bar = __privateGet(_Test, _foo);\n    let Test = _Test;\n\n    // New output (with useDefineForClassFields=false)\n    class Test {\n      static #foo = 123;\n      static {\n        this.bar = this.#foo;\n      }\n    }\n    ```\n\n* Fix TypeScript experimental decorators combined with `--mangle-props` ([#3177](https://github.com/evanw/esbuild/issues/3177))\n\n    Previously using TypeScript experimental decorators combined with the `--mangle-props` setting could result in a crash, as the experimental decorator transform was not expecting a mangled property as a class member. This release fixes the crash so you can now combine both of these features together safely.\n\n## 0.18.4\n\n* Bundling no longer unnecessarily transforms class syntax ([#1360](https://github.com/evanw/esbuild/issues/1360), [#1328](https://github.com/evanw/esbuild/issues/1328), [#1524](https://github.com/evanw/esbuild/issues/1524), [#2416](https://github.com/evanw/esbuild/issues/2416))\n\n    When bundling, esbuild automatically converts top-level class statements to class expressions. Previously this conversion had the unfortunate side-effect of also transforming certain other class-related syntax features to avoid correctness issues when the references to the class name within the class body. This conversion has been reworked to avoid doing this:\n\n    ```js\n    // Original code\n    export class Foo {\n      static foo = () => Foo\n    }\n\n    // Old output (with --bundle)\n    var _Foo = class {\n    };\n    var Foo = _Foo;\n    __publicField(Foo, \"foo\", () => _Foo);\n\n    // New output (with --bundle)\n    var Foo = class _Foo {\n      static foo = () => _Foo;\n    };\n    ```\n\n    This conversion process is very complicated and has many edge cases (including interactions with static fields, static blocks, private class properties, and TypeScript experimental decorators). It should already be pretty robust but a change like this may introduce new unintentional behavior. Please report any issues with this upgrade on the esbuild bug tracker.\n\n    You may be wondering why esbuild needs to do this at all. One reason to do this is that esbuild's bundler sometimes needs to lazily-evaluate a module. For example, a module may end up being both the target of a dynamic `import()` call and a static `import` statement. Lazy module evaluation is done by wrapping the top-level module code in a closure. To avoid a performance hit for static `import` statements, esbuild stores top-level exported symbols outside of the closure and references them directly instead of indirectly.\n\n    Another reason to do this is that multiple JavaScript VMs have had and continue to have performance issues with TDZ (i.e. \"temporal dead zone\") checks. These checks validate that a let, or const, or class symbol isn't used before it's initialized. Here are two issues with well-known VMs:\n\n    * V8: https://bugs.chromium.org/p/v8/issues/detail?id=13723 (10% slowdown)\n    * JavaScriptCore: https://bugs.webkit.org/show_bug.cgi?id=199866 (1,000% slowdown!)\n\n    JavaScriptCore had a severe performance issue as their TDZ implementation had time complexity that was quadratic in the number of variables needing TDZ checks in the same scope (with the top-level scope typically being the worst offender). V8 has ongoing issues with TDZ checks being present throughout the code their JIT generates even when they have already been checked earlier in the same function or when the function in question has already been run (so the checks have already happened).\n\n    Due to esbuild's parallel architecture, esbuild both a) needs to convert class statements into class expressions during parsing and b) doesn't yet know whether this module will need to be lazily-evaluated or not in the parser. So esbuild always does this conversion during bundling in case it's needed for correctness (and also to avoid potentially catastrophic performance issues due to bundling creating a large scope with many TDZ variables).\n\n* Enforce TDZ errors in computed class property keys ([#2045](https://github.com/evanw/esbuild/issues/2045))\n\n    JavaScript allows class property keys to be generated at run-time using code, like this:\n\n    ```js\n    class Foo {\n      static foo = 'foo'\n      static [Foo.foo + '2'] = 2\n    }\n    ```\n\n    Previously esbuild treated references to the containing class name within computed property keys as a reference to the partially-initialized class object. That meant code that attempted to reference properties of the class object (such as the code above) would get back `undefined` instead of throwing an error.\n\n    This release rewrites references to the containing class name within computed property keys into code that always throws an error at run-time, which is how this JavaScript code is supposed to work. Code that does this will now also generate a warning. You should never write code like this, but it now should be more obvious when incorrect code like this is written.\n\n* Fix an issue with experimental decorators and static fields ([#2629](https://github.com/evanw/esbuild/issues/2629))\n\n    This release also fixes a bug regarding TypeScript experimental decorators and static class fields which reference the enclosing class name in their initializer. This affected top-level classes when bundling was enabled. Previously code that does this could crash because the class name wasn't initialized yet. This case should now be handled correctly:\n\n    ```ts\n    // Original code\n    class Foo {\n      @someDecorator\n      static foo = 'foo'\n      static bar = Foo.foo.length\n    }\n\n    // Old output\n    const _Foo = class {\n      static foo = \"foo\";\n      static bar = _Foo.foo.length;\n    };\n    let Foo = _Foo;\n    __decorateClass([\n      someDecorator\n    ], Foo, \"foo\", 2);\n\n    // New output\n    const _Foo = class _Foo {\n      static foo = \"foo\";\n      static bar = _Foo.foo.length;\n    };\n    __decorateClass([\n      someDecorator\n    ], _Foo, \"foo\", 2);\n    let Foo = _Foo;\n    ```\n\n* Fix a minification regression with negative numeric properties ([#3169](https://github.com/evanw/esbuild/issues/3169))\n\n    Version 0.18.0 introduced a regression where computed properties with negative numbers were incorrectly shortened into a non-computed property when minification was enabled. This regression has been fixed:\n\n    ```js\n    // Original code\n    x = {\n      [1]: 1,\n      [-1]: -1,\n      [NaN]: NaN,\n      [Infinity]: Infinity,\n      [-Infinity]: -Infinity,\n    }\n\n    // Old output (with --minify)\n    x={1:1,-1:-1,NaN:NaN,1/0:1/0,-1/0:-1/0};\n\n    // New output (with --minify)\n    x={1:1,[-1]:-1,NaN:NaN,[1/0]:1/0,[-1/0]:-1/0};\n    ```\n\n## 0.18.3\n\n* Fix a panic due to empty static class blocks ([#3161](https://github.com/evanw/esbuild/issues/3161))\n\n    This release fixes a bug where an internal invariant that was introduced in the previous release was sometimes violated, which then caused a panic. It happened when bundling code containing an empty static class block with both minification and bundling enabled.\n\n## 0.18.2\n\n* Lower static blocks when static fields are lowered ([#2800](https://github.com/evanw/esbuild/issues/2800), [#2950](https://github.com/evanw/esbuild/issues/2950), [#3025](https://github.com/evanw/esbuild/issues/3025))\n\n    This release fixes a bug where esbuild incorrectly did not lower static class blocks when static class fields needed to be lowered. For example, the following code should print `1 2 3` but previously printed `2 1 3` instead due to this bug:\n\n    ```js\n    // Original code\n    class Foo {\n      static x = console.log(1)\n      static { console.log(2) }\n      static y = console.log(3)\n    }\n\n    // Old output (with --supported:class-static-field=false)\n    class Foo {\n      static {\n        console.log(2);\n      }\n    }\n    __publicField(Foo, \"x\", console.log(1));\n    __publicField(Foo, \"y\", console.log(3));\n\n    // New output (with --supported:class-static-field=false)\n    class Foo {\n    }\n    __publicField(Foo, \"x\", console.log(1));\n    console.log(2);\n    __publicField(Foo, \"y\", console.log(3));\n    ```\n\n* Use static blocks to implement `--keep-names` on classes ([#2389](https://github.com/evanw/esbuild/issues/2389))\n\n    This change fixes a bug where the `name` property could previously be incorrect within a class static context when using `--keep-names`. The problem was that the `name` property was being initialized after static blocks were run instead of before. This has been fixed by moving the `name` property initializer into a static block at the top of the class body:\n\n    ```js\n    // Original code\n    if (typeof Foo === 'undefined') {\n      let Foo = class {\n        static test = this.name\n      }\n      console.log(Foo.test)\n    }\n\n    // Old output (with --keep-names)\n    if (typeof Foo === \"undefined\") {\n      let Foo2 = /* @__PURE__ */ __name(class {\n        static test = this.name;\n      }, \"Foo\");\n      console.log(Foo2.test);\n    }\n\n    // New output (with --keep-names)\n    if (typeof Foo === \"undefined\") {\n      let Foo2 = class {\n        static {\n          __name(this, \"Foo\");\n        }\n        static test = this.name;\n      };\n      console.log(Foo2.test);\n    }\n    ```\n\n    This change was somewhat involved, especially regarding what esbuild considers to be side-effect free. Some unused classes that weren't removed by tree shaking in previous versions of esbuild may now be tree-shaken. One example is classes with static private fields that are transformed by esbuild into code that doesn't use JavaScript's private field syntax. Previously esbuild's tree shaking analysis ran on the class after syntax lowering, but with this release it will run on the class before syntax lowering, meaning it should no longer be confused by class mutations resulting from automatically-generated syntax lowering code.\n\n## 0.18.1\n\n* Fill in `null` entries in input source maps ([#3144](https://github.com/evanw/esbuild/issues/3144))\n\n    If esbuild bundles input files with source maps and those source maps contain a `sourcesContent` array with `null` entries, esbuild previously copied those `null` entries over to the output source map. With this release, esbuild will now attempt to fill in those `null` entries by looking for a file on the file system with the corresponding name from the `sources` array. This matches esbuild's existing behavior that automatically generates the `sourcesContent` array from the file system if the entire `sourcesContent` array is missing.\n\n* Support `/* @__KEY__ */` comments for mangling property names ([#2574](https://github.com/evanw/esbuild/issues/2574))\n\n    Property mangling is an advanced feature that enables esbuild to minify certain property names, even though it's not possible to automatically determine that it's safe to do so. The safe property names are configured via regular expression such as `--mangle-props=_$` (mangle all properties ending in `_`).\n\n    Sometimes it's desirable to also minify strings containing property names, even though it's not possible to automatically determine which strings are property names. This release makes it possible to do this by annotating those strings with `/* @__KEY__ */`. This is a convention that Terser added earlier this year, and which esbuild is now following too: https://github.com/terser/terser/pull/1365. Using it looks like this:\n\n    ```js\n    // Original code\n    console.log(\n      [obj.mangle_, obj.keep],\n      [obj.get('mangle_'), obj.get('keep')],\n      [obj.get(/* @__KEY__ */ 'mangle_'), obj.get(/* @__KEY__ */ 'keep')],\n    )\n\n    // Old output (with --mangle-props=_$)\n    console.log(\n      [obj.a, obj.keep],\n      [obj.get(\"mangle_\"), obj.get(\"keep\")],\n      [obj.get(/* @__KEY__ */ \"mangle_\"), obj.get(/* @__KEY__ */ \"keep\")]\n    );\n\n    // New output (with --mangle-props=_$)\n    console.log(\n      [obj.a, obj.keep],\n      [obj.get(\"mangle_\"), obj.get(\"keep\")],\n      [obj.get(/* @__KEY__ */ \"a\"), obj.get(/* @__KEY__ */ \"keep\")]\n    );\n    ```\n\n* Support `/* @__NO_SIDE_EFFECTS__ */` comments for functions ([#3149](https://github.com/evanw/esbuild/issues/3149))\n\n    Rollup has recently added support for `/* @__NO_SIDE_EFFECTS__ */` annotations before functions to indicate that calls to these functions can be removed if the result is unused (i.e. the calls can be assumed to have no side effects). This release adds basic support for these to esbuild as well, which means esbuild will now parse these comments in input files and preserve them in output files. This should help people that use esbuild in combination with Rollup.\n\n    Note that this doesn't necessarily mean esbuild will treat these calls as having no side effects, as esbuild's parallel architecture currently isn't set up to enable this type of cross-file tree-shaking information (tree-shaking decisions regarding a function call are currently local to the file they appear in). If you want esbuild to consider a function call to have no side effects, make sure you continue to annotate the function call with `/* @__PURE__ */` (which is the previously-established convention for communicating this).\n\n## 0.18.0\n\n**This release deliberately contains backwards-incompatible changes.** To avoid automatically picking up releases like this, you should either be pinning the exact version of `esbuild` in your `package.json` file (recommended) or be using a version range syntax that only accepts patch upgrades such as `^0.17.0` or `~0.17.0`. See npm's documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\nThe breaking changes in this release mainly focus on fixing some long-standing issues with esbuild's handling of `tsconfig.json` files. Here are all the changes in this release, in detail:\n\n* Add a way to try esbuild online ([#797](https://github.com/evanw/esbuild/issues/797))\n\n    There is now a way to try esbuild live on esbuild's website without installing it: https://esbuild.github.io/try/. In addition to being able to more easily evaluate esbuild, this should also make it more efficient to generate esbuild bug reports. For example, you can use it to compare the behavior of different versions of esbuild on the same input. The state of the page is stored in the URL for easy sharing. Many thanks to [@hyrious](https://github.com/hyrious) for creating https://hyrious.me/esbuild-repl/, which was the main inspiration for this addition to esbuild's website.\n\n    Two forms of build options are supported: either CLI-style ([example](https://esbuild.github.io/try/#dAAwLjE3LjE5AC0tbG9hZGVyPXRzeCAtLW1pbmlmeSAtLXNvdXJjZW1hcABsZXQgZWw6IEpTWC5FbGVtZW50ID0gPGRpdiAvPg)) or JS-style ([example](https://esbuild.github.io/try/#dAAwLjE3LjE5AHsKICBsb2FkZXI6ICd0c3gnLAogIG1pbmlmeTogdHJ1ZSwKICBzb3VyY2VtYXA6IHRydWUsCn0AbGV0IGVsOiBKU1guRWxlbWVudCA9IDxkaXYgLz4)). Both are converted into a JS object that's passed to esbuild's WebAssembly API. The CLI-style argument parser is a custom one that simulates shell quoting rules, and the JS-style argument parser is also custom and parses a superset of JSON (basically JSON5 + regular expressions). So argument parsing is an approximate simulation of what happens for real but hopefully it should be close enough.\n\n* Changes to esbuild's `tsconfig.json` support ([#3019](https://github.com/evanw/esbuild/issues/3019)):\n\n    This release makes the following changes to esbuild's `tsconfig.json` support:\n\n    * Using experimental decorators now requires `\"experimentalDecorators\": true` ([#104](https://github.com/evanw/esbuild/issues/104))\n\n        Previously esbuild would always compile decorators in TypeScript code using TypeScript's experimental decorator transform. Now that standard JavaScript decorators are close to being finalized, esbuild will now require you to use `\"experimentalDecorators\": true` to do this. This new requirement makes it possible for esbuild to introduce a transform for standard JavaScript decorators in TypeScript code in the future. Such a transform has not been implemented yet, however.\n\n    * TypeScript's `target` no longer affects esbuild's `target` ([#2628](https://github.com/evanw/esbuild/issues/2628))\n\n        Some people requested that esbuild support TypeScript's `target` setting, so support for it was added (in [version 0.12.4](https://github.com/evanw/esbuild/releases/v0.12.4)). However, esbuild supports reading from multiple `tsconfig.json` files within a single build, which opens up the possibility that different files in the build have different language targets configured. There isn't really any reason to do this and it can lead to unexpected results. So with this release, the `target` setting in `tsconfig.json` will no longer affect esbuild's own `target` setting. You will have to use esbuild's own target setting instead (which is a single, global value).\n\n    * TypeScript's `jsx` setting no longer causes esbuild to preserve JSX syntax ([#2634](https://github.com/evanw/esbuild/issues/2634))\n\n        TypeScript has a setting called [`jsx`](https://www.typescriptlang.org/tsconfig#jsx) that controls how to transform JSX into JS. The tool-agnostic transform is called `react`, and the React-specific transform is called `react-jsx` (or `react-jsxdev`). There is also a setting called `preserve` which indicates JSX should be passed through untransformed. Previously people would run esbuild with `\"jsx\": \"preserve\"` in their `tsconfig.json` files and then be surprised when esbuild preserved their JSX. So with this release, esbuild will now ignore `\"jsx\": \"preserve\"` in `tsconfig.json` files. If you want to preserve JSX syntax with esbuild, you now have to use `--jsx=preserve`.\n\n        Note: Some people have suggested that esbuild's equivalent `jsx` setting override the one in `tsconfig.json`. However, some projects need to legitimately have different files within the same build use different transforms (i.e. `react` vs. `react-jsx`) and having esbuild's global `jsx` setting override `tsconfig.json` would prevent this from working. This release ignores `\"jsx\": \"preserve\"` but still allows other `jsx` values in `tsconfig.json` files to override esbuild's global `jsx` setting to keep the ability for multiple files within the same build to use different transforms.\n\n    * `useDefineForClassFields` behavior has changed ([#2584](https://github.com/evanw/esbuild/issues/2584), [#2993](https://github.com/evanw/esbuild/issues/2993))\n\n        Class fields in TypeScript look like this (`x` is a class field):\n\n        ```js\n        class Foo {\n          x = 123\n        }\n        ```\n\n        TypeScript has legacy behavior that uses assignment semantics instead of define semantics for class fields when [`useDefineForClassFields`](https://www.typescriptlang.org/tsconfig#useDefineForClassFields) is enabled (in which case class fields in TypeScript behave differently than they do in JavaScript, which is arguably \"wrong\").\n\n        This legacy behavior exists because TypeScript added class fields to TypeScript before they were added to JavaScript. The TypeScript team decided to go with assignment semantics and shipped their implementation. Much later on TC39 decided to go with define semantics for class fields in JavaScript instead. This behaves differently if the base class has a setter with the same name:\n\n        ```js\n        class Base {\n          set x(_) {\n            console.log('x:', _)\n          }\n        }\n\n        // useDefineForClassFields: false\n        class AssignSemantics extends Base {\n          constructor() {\n            super()\n            this.x = 123\n          }\n        }\n\n        // useDefineForClassFields: true\n        class DefineSemantics extends Base {\n          constructor() {\n            super()\n            Object.defineProperty(this, 'x', { value: 123 })\n          }\n        }\n\n        console.log(\n          new AssignSemantics().x, // Calls the setter\n          new DefineSemantics().x // Doesn't call the setter\n        )\n        ```\n\n        When you run `tsc`, the value of `useDefineForClassFields` defaults to `false` when it's not specified and the `target` in `tsconfig.json` is present but earlier than `ES2022`. This sort of makes sense because the class field language feature was added in ES2022, so before ES2022 class fields didn't exist (and thus TypeScript's legacy behavior is active). However, TypeScript's `target` setting currently defaults to `ES3` which unfortunately means that the `useDefineForClassFields` setting currently defaults to false (i.e. to \"wrong\"). In other words if you run `tsc` with all default settings, class fields will behave incorrectly.\n\n        Previously esbuild tried to do what `tsc` did. That meant esbuild's version of `useDefineForClassFields` was `false` by default, and was also `false` if esbuild's `--target=` was present but earlier than `es2022`. However, TypeScript's legacy class field behavior is becoming increasingly irrelevant and people who expect class fields in TypeScript to work like they do in JavaScript are confused when they use esbuild with default settings. It's also confusing that the behavior of class fields would change if you changed the language target (even though that's exactly how TypeScript works).\n\n        So with this release, esbuild will now only use the information in `tsconfig.json` to determine whether `useDefineForClassFields` is true or not. Specifically `useDefineForClassFields` will be respected if present, otherwise it will be `false` if `target` is present in `tsconfig.json` and is `ES2021` or earlier, otherwise it will be `true`. Targets passed to esbuild's `--target=` setting will no longer affect `useDefineForClassFields`.\n\n        Note that this means different directories in your build can have different values for this setting since esbuild allows different directories to have different `tsconfig.json` files within the same build. This should let you migrate your code one directory at a time without esbuild's `--target=` setting affecting the semantics of your code.\n\n    * Add support for `verbatimModuleSyntax` from TypeScript 5.0\n\n        TypeScript 5.0 added a new option called [`verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax) that deprecates and replaces two older options, `preserveValueImports` and `importsNotUsedAsValues`. Setting `verbatimModuleSyntax` to true in `tsconfig.json` tells esbuild to not drop unused import statements. Specifically esbuild now treats `\"verbatimModuleSyntax\": true` as if you had specified both `\"preserveValueImports\": true` and `\"importsNotUsedAsValues\": \"preserve\"`.\n\n    * Add multiple inheritance for `tsconfig.json` from TypeScript 5.0\n\n        TypeScript 5.0 now allows [multiple inheritance for `tsconfig.json` files](https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/#supporting-multiple-configuration-files-in-extends). You can now pass an array of filenames via the `extends` parameter and your `tsconfig.json` will start off containing properties from all of those configuration files, in order. This release of esbuild adds support for this new TypeScript feature.\n\n    * Remove support for `moduleSuffixes` ([#2395](https://github.com/evanw/esbuild/issues/2395))\n\n        The community has requested that esbuild remove support for TypeScript's `moduleSuffixes` feature, so it has been removed in this release. Instead you can use esbuild's `--resolve-extensions=` feature to select which module suffix you want to build with.\n\n    * Apply `--tsconfig=` overrides to `stdin` and virtual files ([#385](https://github.com/evanw/esbuild/issues/385), [#2543](https://github.com/evanw/esbuild/issues/2543))\n\n        When you override esbuild's automatic `tsconfig.json` file detection with `--tsconfig=` to pass a specific `tsconfig.json` file, esbuild previously didn't apply these settings to source code passed via the `stdin` API option or to TypeScript files from plugins that weren't in the `file` namespace. This release changes esbuild's behavior so that settings from `tsconfig.json` also apply to these source code files as well.\n\n    * Support `--tsconfig-raw=` in build API calls ([#943](https://github.com/evanw/esbuild/issues/943), [#2440](https://github.com/evanw/esbuild/issues/2440))\n\n        Previously if you wanted to override esbuild's automatic `tsconfig.json` file detection, you had to create a new `tsconfig.json` file and pass the file name to esbuild via the `--tsconfig=` flag. With this release, you can now optionally use `--tsconfig-raw=` instead to pass the contents of `tsconfig.json` to esbuild directly instead of passing the file name. For example, you can now use `--tsconfig-raw={\"compilerOptions\":{\"experimentalDecorators\":true}}` to enable TypeScript experimental decorators directly using a command-line flag (assuming you escape the quotes correctly using your current shell's quoting rules). The `--tsconfig-raw=` flag previously only worked with transform API calls but with this release, it now works with build API calls too.\n\n    * Ignore all `tsconfig.json` files in `node_modules` ([#276](https://github.com/evanw/esbuild/issues/276), [#2386](https://github.com/evanw/esbuild/issues/2386))\n\n        This changes esbuild's behavior that applies `tsconfig.json` to all files in the subtree of the directory containing `tsconfig.json`. In version 0.12.7, esbuild started ignoring `tsconfig.json` files inside `node_modules` folders. The rationale is that people typically do this by mistake and that doing this intentionally is a rare use case that doesn't need to be supported. However, this change only applied to certain syntax-specific settings (e.g. `jsxFactory`) but did not apply to path resolution settings (e.g. `paths`). With this release, esbuild will now ignore all `tsconfig.json` files in `node_modules` instead of only ignoring certain settings.\n\n    * Ignore `tsconfig.json` when resolving paths within `node_modules` ([#2481](https://github.com/evanw/esbuild/issues/2481))\n\n        Previously fields in `tsconfig.json` related to path resolution (e.g. `paths`) were respected for all files in the subtree containing that `tsconfig.json` file, even within a nested `node_modules` subdirectory. This meant that a project's `paths` settings could potentially affect any bundled packages. With this release, esbuild will no longer use `tsconfig.json` settings during path resolution inside nested `node_modules` subdirectories.\n\n    * Prefer `.js` over `.ts` within `node_modules` ([#3019](https://github.com/evanw/esbuild/issues/3019))\n\n        The default list of implicit extensions that esbuild will try appending to import paths contains `.ts` before `.js`. This makes it possible to bundle TypeScript projects that reference other files in the project using extension-less imports (e.g. `./some-file` to load `./some-file.ts` instead of `./some-file.js`). However, this behavior is undesirable within `node_modules` directories. Some package authors publish both their original TypeScript code and their compiled JavaScript code side-by-side. In these cases, esbuild should arguably be using the compiled JavaScript files instead of the original TypeScript files because the TypeScript compilation settings for files within the package should be determined by the package author, not the user of esbuild. So with this release, esbuild will now prefer implicit `.js` extensions over `.ts` when searching for import paths within `node_modules`.\n\n    These changes are intended to improve esbuild's compatibility with `tsc` and reduce the number of unfortunate behaviors regarding `tsconfig.json` and esbuild.\n\n* Add a workaround for bugs in Safari 16.2 and earlier ([#3072](https://github.com/evanw/esbuild/issues/3072))\n\n    Safari's JavaScript parser had a bug (which has now been fixed) where at least something about unary/binary operators nested inside default arguments nested inside either a function or class expression was incorrectly considered a syntax error if that expression was the target of a property assignment. Here are some examples that trigger this Safari bug:\n\n    ```\n    ❱ x(function (y = -1) {}.z = 2)\n    SyntaxError: Left hand side of operator '=' must be a reference.\n\n    ❱ x(class { f(y = -1) {} }.z = 2)\n    SyntaxError: Left hand side of operator '=' must be a reference.\n    ```\n\n    It's not clear what the exact conditions are that trigger this bug. However, a workaround for this bug appears to be to post-process your JavaScript to wrap any in function and class declarations that are the direct target of a property access expression in parentheses. That's the workaround that UglifyJS applies for this issue: [mishoo/UglifyJS#2056](https://github.com/mishoo/UglifyJS/pull/2056). So that's what esbuild now does starting with this release:\n\n    ```js\n    // Original code\n    x(function (y = -1) {}.z = 2, class { f(y = -1) {} }.z = 2)\n\n    // Old output (with --minify --target=safari16.2)\n    x(function(c=-1){}.z=2,class{f(c=-1){}}.z=2);\n\n    // New output (with --minify --target=safari16.2)\n    x((function(c=-1){}).z=2,(class{f(c=-1){}}).z=2);\n    ```\n\n    This fix is not enabled by default. It's only enabled when `--target=` contains Safari 16.2 or earlier, such as with `--target=safari16.2`. You can also explicitly enable or disable this specific transform (called `function-or-class-property-access`) with `--supported:function-or-class-property-access=false`.\n\n* Fix esbuild's TypeScript type declarations to forbid unknown properties ([#3089](https://github.com/evanw/esbuild/issues/3089))\n\n    Version 0.17.0 of esbuild introduced a specific form of function overloads in the TypeScript type definitions for esbuild's API calls that looks like this:\n\n    ```ts\n    interface TransformOptions {\n      legalComments?: 'none' | 'inline' | 'eof' | 'external'\n    }\n\n    interface TransformResult<ProvidedOptions extends TransformOptions = TransformOptions> {\n      legalComments: string | (ProvidedOptions['legalComments'] extends 'external' ? never : undefined)\n    }\n\n    declare function transformSync<ProvidedOptions extends TransformOptions>(input: string, options?: ProvidedOptions): TransformResult<ProvidedOptions>\n    declare function transformSync(input: string, options?: TransformOptions): TransformResult\n    ```\n\n    This more accurately reflects how esbuild's JavaScript API behaves. The result object returned by `transformSync` only has the `legalComments` property if you pass `legalComments: 'external'`:\n\n    ```ts\n    // These have type \"string | undefined\"\n    transformSync('').legalComments\n    transformSync('', { legalComments: 'eof' }).legalComments\n\n    // This has type \"string\"\n    transformSync('', { legalComments: 'external' }).legalComments\n    ```\n\n    However, this form of function overloads unfortunately allows typos (e.g. `egalComments`) to pass the type checker without generating an error as TypeScript allows all objects with unknown properties to extend `TransformOptions`. These typos result in esbuild's API throwing an error at run-time.\n\n    To prevent typos during type checking, esbuild's TypeScript type definitions will now use a different form that looks like this:\n\n    ```ts\n    type SameShape<Out, In extends Out> = In & { [Key in Exclude<keyof In, keyof Out>]: never }\n\n    interface TransformOptions {\n      legalComments?: 'none' | 'inline' | 'eof' | 'external'\n    }\n\n    interface TransformResult<ProvidedOptions extends TransformOptions = TransformOptions> {\n      legalComments: string | (ProvidedOptions['legalComments'] extends 'external' ? never : undefined)\n    }\n\n    declare function transformSync<T extends TransformOptions>(input: string, options?: SameShape<TransformOptions, T>): TransformResult<T>\n    ```\n\n    This change should hopefully not affect correct code. It should hopefully introduce type errors only for incorrect code.\n\n* Fix CSS nesting transform for pseudo-elements ([#3119](https://github.com/evanw/esbuild/issues/3119))\n\n    This release fixes esbuild's CSS nesting transform for pseudo-elements (e.g. `::before` and `::after`). The CSS nesting specification says that [the nesting selector does not work with pseudo-elements](https://www.w3.org/TR/css-nesting-1/#ref-for-matches-pseudo%E2%91%A0). This can be seen in the example below: esbuild does not carry the parent pseudo-element `::before` through the nesting selector `&`. However, that doesn't apply to pseudo-elements that are within the same selector. Previously esbuild had a bug where it considered pseudo-elements in both locations as invalid. This release changes esbuild to only consider those from the parent selector invalid, which should align with the specification:\n\n    ```css\n    /* Original code */\n    a, b::before {\n      &.c, &::after {\n        content: 'd';\n      }\n    }\n\n    /* Old output (with --target=chrome90) */\n    a:is(.c, ::after) {\n      content: \"d\";\n    }\n\n    /* New output (with --target=chrome90) */\n    a.c,\n    a::after {\n      content: \"d\";\n    }\n    ```\n\n* Forbid `&` before a type selector in nested CSS\n\n    The people behind the work-in-progress CSS nesting specification have very recently [decided to forbid nested CSS that looks like `&div`](https://github.com/w3c/csswg-drafts/issues/8662#issuecomment-1514977935). You will have to use either `div&` or `&:is(div)` instead. This release of esbuild has been updated to take this new change into consideration. Doing this now generates a warning. The suggested fix is slightly different depending on where in the overall selector it happened:\n\n    ```\n    ▲ [WARNING] Cannot use type selector \"input\" directly after nesting selector \"&\" [css-syntax-error]\n\n        example.css:2:3:\n          2 │   &input {\n            │    ~~~~~\n            ╵    :is(input)\n\n      CSS nesting syntax does not allow the \"&\" selector to come before a type selector. You can wrap\n      this selector in \":is()\" as a workaround. This restriction exists to avoid problems with SASS\n      nesting, where the same syntax means something very different that has no equivalent in real CSS\n      (appending a suffix to the parent selector).\n\n    ▲ [WARNING] Cannot use type selector \"input\" directly after nesting selector \"&\" [css-syntax-error]\n\n        example.css:6:8:\n          6 │   .form &input {\n            │         ~~~~~~\n            ╵         input&\n\n      CSS nesting syntax does not allow the \"&\" selector to come before a type selector. You can move\n      the \"&\" to the end of this selector as a workaround. This restriction exists to avoid problems\n      with SASS nesting, where the same syntax means something very different that has no equivalent in\n      real CSS (appending a suffix to the parent selector).\n    ```\n\n## 0.17.19\n\n* Fix CSS transform bugs with nested selectors that start with a combinator ([#3096](https://github.com/evanw/esbuild/issues/3096))\n\n    This release fixes several bugs regarding transforming nested CSS into non-nested CSS for older browsers. The bugs were due to lack of test coverage for nested selectors with more than one compound selector where they all start with the same combinator. Here's what some problematic cases look like before and after these fixes:\n\n    ```css\n    /* Original code */\n    .foo {\n      > &a,\n      > &b {\n        color: red;\n      }\n    }\n    .bar {\n      > &a,\n      + &b {\n        color: green;\n      }\n    }\n\n    /* Old output (with --target=chrome90) */\n    .foo :is(> .fooa, > .foob) {\n      color: red;\n    }\n    .bar :is(> .bara, + .barb) {\n      color: green;\n    }\n\n    /* New output (with --target=chrome90) */\n    .foo > :is(a.foo, b.foo) {\n      color: red;\n    }\n    .bar > a.bar,\n    .bar + b.bar {\n      color: green;\n    }\n    ```\n\n* Fix bug with TypeScript parsing of instantiation expressions followed by `=` ([#3111](https://github.com/evanw/esbuild/issues/3111))\n\n    This release fixes esbuild's TypeScript-to-JavaScript conversion code in the case where a potential instantiation expression is followed immediately by a `=` token (such that the trailing `>` becomes a `>=` token). Previously esbuild considered that to still be an instantiation expression, but the official TypeScript compiler considered it to be a `>=` operator instead. This release changes esbuild's interpretation to match TypeScript. This edge case currently [appears to be problematic](https://sucrase.io/#transforms=typescript&compareWithTypeScript=true&code=x%3Cy%3E%3Da%3Cb%3Cc%3E%3E()) for other TypeScript-to-JavaScript converters as well:\n\n    | Original code | TypeScript | esbuild 0.17.18 | esbuild 0.17.19 | Sucrase | Babel |\n    |---|---|---|---|---|---|\n    | `x<y>=a<b<c>>()` | `x<y>=a();` | `x=a();` | `x<y>=a();` | `x=a()` | Invalid left-hand side in assignment expression |\n\n* Avoid removing unrecognized directives from the directive prologue when minifying ([#3115](https://github.com/evanw/esbuild/issues/3115))\n\n    The [directive prologue](https://262.ecma-international.org/6.0/#sec-directive-prologues-and-the-use-strict-directive) in JavaScript is a sequence of top-level string expressions that come before your code. The only directives that JavaScript engines currently recognize are `use strict` and sometimes `use asm`. However, the people behind React have made up their own directive for their own custom dialect of JavaScript. Previously esbuild only preserved the `use strict` directive when minifying, although you could still write React JavaScript with esbuild using something like `--banner:js=\"'your directive here';\"`. With this release, you can now put arbitrary directives in the entry point and esbuild will preserve them in its minified output:\n\n    ```js\n    // Original code\n    'use wtf'; console.log(123)\n\n    // Old output (with --minify)\n    console.log(123);\n\n    // New output (with --minify)\n    \"use wtf\";console.log(123);\n    ```\n\n    Note that this means esbuild will no longer remove certain stray top-level strings when minifying. This behavior is an intentional change because these stray top-level strings are actually part of the directive prologue, and could potentially have semantics assigned to them (as was the case with React).\n\n* Improved minification of binary shift operators\n\n    With this release, esbuild's minifier will now evaluate the `<<` and `>>>` operators if the resulting code would be shorter:\n\n    ```js\n    // Original code\n    console.log(10 << 10, 10 << 20, -123 >>> 5, -123 >>> 10);\n\n    // Old output (with --minify)\n    console.log(10<<10,10<<20,-123>>>5,-123>>>10);\n\n    // New output (with --minify)\n    console.log(10240,10<<20,-123>>>5,4194303);\n    ```\n\n## 0.17.18\n\n* Fix non-default JSON import error with `export {} from` ([#3070](https://github.com/evanw/esbuild/issues/3070))\n\n    This release fixes a bug where esbuild incorrectly identified statements of the form `export { default as x } from \"y\" assert { type: \"json\" }` as a non-default import. The bug did not affect code of the form `import { default as x } from ...` (only code that used the `export` keyword).\n\n* Fix a crash with an invalid subpath import ([#3067](https://github.com/evanw/esbuild/issues/3067))\n\n    Previously esbuild could crash when attempting to generate a friendly error message for an invalid [subpath import](https://nodejs.org/api/packages.html#subpath-imports) (i.e. an import starting with `#`). This happened because esbuild originally only supported the `exports` field and the code for that error message was not updated when esbuild later added support for the `imports` field. This crash has been fixed.\n\n## 0.17.17\n\n* Fix CSS nesting transform for top-level `&` ([#3052](https://github.com/evanw/esbuild/issues/3052))\n\n    Previously esbuild could crash with a stack overflow when lowering CSS nesting rules with a top-level `&`, such as in the code below. This happened because esbuild's CSS nesting transform didn't handle top-level `&`, causing esbuild to inline the top-level selector into itself. This release handles top-level `&` by replacing it with [the `:scope` pseudo-class](https://drafts.csswg.org/selectors-4/#the-scope-pseudo):\n\n    ```css\n    /* Original code */\n    &,\n    a {\n      .b {\n        color: red;\n      }\n    }\n\n    /* New output (with --target=chrome90) */\n    :is(:scope, a) .b {\n      color: red;\n    }\n    ```\n\n* Support `exports` in `package.json` for `extends` in `tsconfig.json` ([#3058](https://github.com/evanw/esbuild/issues/3058))\n\n    TypeScript 5.0 added the ability to use `extends` in `tsconfig.json` to reference a path in a package whose `package.json` file contains an `exports` map that points to the correct location. This doesn't automatically work in esbuild because `tsconfig.json` affects esbuild's path resolution, so esbuild's normal path resolution logic doesn't apply.\n\n    This release adds support for doing this by adding some additional code that attempts to resolve the `extends` path using the `exports` field. The behavior should be similar enough to esbuild's main path resolution logic to work as expected.\n\n    Note that esbuild always treats this `extends` import as a `require()` import since that's what TypeScript appears to do. Specifically the `require` condition will be active and the `import` condition will be inactive.\n\n* Fix watch mode with `NODE_PATH` ([#3062](https://github.com/evanw/esbuild/issues/3062))\n\n    Node has a rarely-used feature where you can extend the set of directories that node searches for packages using the `NODE_PATH` environment variable. While esbuild supports this too, previously a bug prevented esbuild's watch mode from picking up changes to imported files that were contained directly in a `NODE_PATH` directory. You're supposed to use `NODE_PATH` for packages, but some people abuse this feature by putting files in that directory instead (e.g. `node_modules/some-file.js` instead of `node_modules/some-pkg/some-file.js`). The watch mode bug happens when you do this because esbuild first tries to read `some-file.js` as a directory and then as a file. Watch mode was incorrectly waiting for `some-file.js` to become a valid directory. This release fixes this edge case bug by changing watch mode to watch `some-file.js` as a file when this happens.\n\n## 0.17.16\n\n* Fix CSS nesting transform for triple-nested rules that start with a combinator ([#3046](https://github.com/evanw/esbuild/issues/3046))\n\n    This release fixes a bug with esbuild where triple-nested CSS rules that start with a combinator were not transformed correctly for older browsers. Here's an example of such a case before and after this bug fix:\n\n    ```css\n    /* Original input */\n    .a {\n      color: red;\n      > .b {\n        color: green;\n        > .c {\n          color: blue;\n        }\n      }\n    }\n\n    /* Old output (with --target=chrome90) */\n    .a {\n      color: red;\n    }\n    .a > .b {\n      color: green;\n    }\n    .a .b > .c {\n      color: blue;\n    }\n\n    /* New output (with --target=chrome90) */\n    .a {\n      color: red;\n    }\n    .a > .b {\n      color: green;\n    }\n    .a > .b > .c {\n      color: blue;\n    }\n    ```\n\n* Support `--inject` with a file loaded using the `copy` loader ([#3041](https://github.com/evanw/esbuild/issues/3041))\n\n    This release now allows you to use `--inject` with a file that is loaded using the `copy` loader. The `copy` loader copies the imported file to the output directory verbatim and rewrites the path in the `import` statement to point to the copied output file. When used with `--inject`, this means the injected file will be copied to the output directory as-is and a bare `import` statement for that file will be inserted in any non-copy output files that esbuild generates.\n\n    Note that since esbuild doesn't parse the contents of copied files, esbuild will not expose any of the export names as usable imports when you do this (in the way that esbuild's `--inject` feature is typically used). However, any side-effects that the injected file has will still occur.\n\n## 0.17.15\n\n* Allow keywords as type parameter names in mapped types ([#3033](https://github.com/evanw/esbuild/issues/3033))\n\n    TypeScript allows type keywords to be used as parameter names in mapped types. Previously esbuild incorrectly treated this as an error. Code that does this is now supported:\n\n    ```ts\n    type Foo = 'a' | 'b' | 'c'\n    type A = { [keyof in Foo]: number }\n    type B = { [infer in Foo]: number }\n    type C = { [readonly in Foo]: number }\n    ```\n\n* Add annotations for re-exported modules in node ([#2486](https://github.com/evanw/esbuild/issues/2486), [#3029](https://github.com/evanw/esbuild/issues/3029))\n\n    Node lets you import named imports from a CommonJS module using ESM import syntax. However, the allowed names aren't derived from the properties of the CommonJS module. Instead they are derived from an arbitrary syntax-only analysis of the CommonJS module's JavaScript AST.\n\n    To accommodate node doing this, esbuild's ESM-to-CommonJS conversion adds a special non-executable \"annotation\" for node that describes the exports that node should expose in this scenario. It takes the form `0 && (module.exports = { ... })` and comes at the end of the file (`0 && expr` means `expr` is never evaluated).\n\n    Previously esbuild didn't do this for modules re-exported using the `export * from` syntax. Annotations for these re-exports will now be added starting with this release:\n\n    ```js\n    // Original input\n    export { foo } from './foo'\n    export * from './bar'\n\n    // Old output (with --format=cjs --platform=node)\n    ...\n    0 && (module.exports = {\n      foo\n    });\n\n    // New output (with --format=cjs --platform=node)\n    ...\n    0 && (module.exports = {\n      foo,\n      ...require(\"./bar\")\n    });\n    ```\n\n    Note that you need to specify both `--format=cjs` and `--platform=node` to get these node-specific annotations.\n\n* Avoid printing an unnecessary space in between a number and a `.` ([#3026](https://github.com/evanw/esbuild/pull/3026))\n\n    JavaScript typically requires a space in between a number token and a `.` token to avoid the `.` being interpreted as a decimal point instead of a member expression. However, this space is not required if the number token itself contains a decimal point, an exponent, or uses a base other than 10. This release of esbuild now avoids printing the unnecessary space in these cases:\n\n    ```js\n    // Original input\n    foo(1000 .x, 0 .x, 0.1 .x, 0.0001 .x, 0xFFFF_0000_FFFF_0000 .x)\n\n    // Old output (with --minify)\n    foo(1e3 .x,0 .x,.1 .x,1e-4 .x,0xffff0000ffff0000 .x);\n\n    // New output (with --minify)\n    foo(1e3.x,0 .x,.1.x,1e-4.x,0xffff0000ffff0000.x);\n    ```\n\n* Fix server-sent events with live reload when writing to the file system root ([#3027](https://github.com/evanw/esbuild/issues/3027))\n\n    This release fixes a bug where esbuild previously failed to emit server-sent events for live reload when `outdir` was the file system root, such as `/`. This happened because `/` is the only path on Unix that cannot have a trailing slash trimmed from it, which was fixed by improved path handling.\n\n## 0.17.14\n\n* Allow the TypeScript 5.0 `const` modifier in object type declarations ([#3021](https://github.com/evanw/esbuild/issues/3021))\n\n    The new TypeScript 5.0 `const` modifier was added to esbuild in version 0.17.5, and works with classes, functions, and arrow expressions. However, support for it wasn't added to object type declarations (e.g. interfaces) due to an oversight. This release adds support for these cases, so the following TypeScript 5.0 code can now be built with esbuild:\n\n    ```ts\n    interface Foo { <const T>(): T }\n    type Bar = { new <const T>(): T }\n    ```\n\n* Implement preliminary lowering for CSS nesting ([#1945](https://github.com/evanw/esbuild/issues/1945))\n\n    Chrome has [implemented the new CSS nesting specification](https://developer.chrome.com/articles/css-nesting/) in version 112, which is currently in beta but will become stable very soon. So CSS nesting is now a part of the web platform!\n\n    This release of esbuild can now transform nested CSS syntax into non-nested CSS syntax for older browsers. The transformation relies on the `:is()` pseudo-class in many cases, so the transformation is only guaranteed to work when targeting browsers that support `:is()` (e.g. Chrome 88+). You'll need to set esbuild's [`target`](https://esbuild.github.io/api/#target) to the browsers you intend to support to tell esbuild to do this transformation. You will get a warning if you use CSS nesting syntax with a `target` which includes older browsers that don't support `:is()`.\n\n    The lowering transformation looks like this:\n\n    ```css\n    /* Original input */\n    a.btn {\n      color: #333;\n      &:hover { color: #444 }\n      &:active { color: #555 }\n    }\n\n    /* New output (with --target=chrome88) */\n    a.btn {\n      color: #333;\n    }\n    a.btn:hover {\n      color: #444;\n    }\n    a.btn:active {\n      color: #555;\n    }\n    ```\n\n    More complex cases may generate the `:is()` pseudo-class:\n\n    ```css\n    /* Original input */\n    div, p {\n      .warning, .error {\n        padding: 20px;\n      }\n    }\n\n    /* New output (with --target=chrome88) */\n    :is(div, p) :is(.warning, .error) {\n      padding: 20px;\n    }\n    ```\n\n    In addition, esbuild now has a special warning message for nested style rules that start with an identifier. This isn't allowed in CSS because the syntax would be ambiguous with the existing declaration syntax. The new warning message looks like this:\n\n    ```\n    ▲ [WARNING] A nested style rule cannot start with \"p\" because it looks like the start of a declaration [css-syntax-error]\n\n        <stdin>:1:7:\n          1 │ main { p { margin: auto } }\n            │        ^\n            ╵        :is(p)\n\n      To start a nested style rule with an identifier, you need to wrap the identifier in \":is(...)\" to\n      prevent the rule from being parsed as a declaration.\n    ```\n\n    Keep in mind that the transformation in this release is a preliminary implementation. CSS has many features that interact in complex ways, and there may be some edge cases that don't work correctly yet.\n\n* Minification now removes unnecessary `&` CSS nesting selectors\n\n    This release introduces the following CSS minification optimizations:\n\n    ```css\n    /* Original input */\n    a {\n      font-weight: bold;\n      & {\n        color: blue;\n      }\n      & :hover {\n        text-decoration: underline;\n      }\n    }\n\n    /* Old output (with --minify) */\n    a{font-weight:700;&{color:#00f}& :hover{text-decoration:underline}}\n\n    /* New output (with --minify) */\n    a{font-weight:700;:hover{text-decoration:underline}color:#00f}\n    ```\n\n* Minification now removes duplicates from CSS selector lists\n\n    This release introduces the following CSS minification optimization:\n\n    ```css\n    /* Original input */\n    div, div { color: red }\n\n    /* Old output (with --minify) */\n    div,div{color:red}\n\n    /* New output (with --minify) */\n    div{color:red}\n    ```\n\n## 0.17.13\n\n* Work around an issue with `NODE_PATH` and Go's WebAssembly internals ([#3001](https://github.com/evanw/esbuild/issues/3001))\n\n    Go's WebAssembly implementation returns `EINVAL` instead of `ENOTDIR` when using the `readdir` syscall on a file. This messes up esbuild's implementation of node's module resolution algorithm since encountering `ENOTDIR` causes esbuild to continue its search (since it's a normal condition) while other encountering other errors causes esbuild to fail with an I/O error (since it's an unexpected condition). You can encounter this issue in practice if you use node's legacy `NODE_PATH` feature to tell esbuild to resolve node modules in a custom directory that was not installed by npm. This release works around this problem by converting `EINVAL` into `ENOTDIR` for the `readdir` syscall.\n\n* Fix a minification bug with CSS `@layer` rules that have parsing errors ([#3016](https://github.com/evanw/esbuild/issues/3016))\n\n    CSS at-rules [require either a `{}` block or a semicolon at the end](https://www.w3.org/TR/css-syntax-3/#consume-at-rule). Omitting both of these causes esbuild to treat the rule as an unknown at-rule. Previous releases of esbuild had a bug that incorrectly removed unknown at-rules without any children during minification if the at-rule token matched an at-rule that esbuild can handle. Specifically [cssnano](https://cssnano.co/) can generate `@layer` rules with parsing errors, and empty `@layer` rules cannot be removed because they have side effects (`@layer` didn't exist when esbuild's CSS support was added, so esbuild wasn't written to handle this). This release changes esbuild to no longer discard `@layer` rules with parsing errors when minifying (the rule `@layer c` has a parsing error):\n\n    ```css\n    /* Original input */\n    @layer a {\n      @layer b {\n        @layer c\n      }\n    }\n\n    /* Old output (with --minify) */\n    @layer a.b;\n\n    /* New output (with --minify) */\n    @layer a.b.c;\n    ```\n\n* Unterminated strings in CSS are no longer an error\n\n    The CSS specification provides [rules for handling parsing errors](https://www.w3.org/TR/CSS22/syndata.html#parsing-errors). One of those rules is that user agents must close strings upon reaching the end of a line (i.e., before an unescaped line feed, carriage return or form feed character), but then drop the construct (declaration or rule) in which the string was found. For example:\n\n    ```css\n    p {\n      color: green;\n      font-family: 'Courier New Times\n      color: red;\n      color: green;\n    }\n    ```\n\n    ...would be treated the same as:\n\n    ```css\n    p { color: green; color: green; }\n    ```\n\n    ...because the second declaration (from `font-family` to the semicolon after `color: red`) is invalid and is dropped.\n\n    Previously using this CSS with esbuild failed to build due to a syntax error, even though the code can be interpreted by a browser. With this release, the code now produces a warning instead of an error, and esbuild prints the invalid CSS such that it stays invalid in the output:\n\n    ```css\n    /* esbuild's new non-minified output: */\n    p {\n      color: green;\n      font-family: 'Courier New Times\n      color: red;\n      color: green;\n    }\n    ```\n\n    ```css\n    /* esbuild's new minified output: */\n    p{font-family:'Courier New Times\n    color: red;color:green}\n    ```\n\n## 0.17.12\n\n* Fix a crash when parsing inline TypeScript decorators ([#2991](https://github.com/evanw/esbuild/issues/2991))\n\n    Previously esbuild's TypeScript parser crashed when parsing TypeScript decorators if the definition of the decorator was inlined into the decorator itself:\n\n    ```ts\n    @(function sealed(constructor: Function) {\n      Object.seal(constructor);\n      Object.seal(constructor.prototype);\n    })\n    class Foo {}\n    ```\n\n    This crash was not noticed earlier because this edge case did not have test coverage. The crash is fixed in this release.\n\n## 0.17.11\n\n* Fix the `alias` feature to always prefer the longest match ([#2963](https://github.com/evanw/esbuild/issues/2963))\n\n    It's possible to configure conflicting aliases such as `--alias:a=b` and `--alias:a/c=d`, which is ambiguous for the import path `a/c/x` (since it could map to either `b/c/x` or `d/x`). Previously esbuild would pick the first matching `alias`, which would non-deterministically pick between one of the possible matches. This release fixes esbuild to always deterministically pick the longest possible match.\n\n* Minify calls to some global primitive constructors ([#2962](https://github.com/evanw/esbuild/issues/2962))\n\n    With this release, esbuild's minifier now replaces calls to `Boolean`/`Number`/`String`/`BigInt` with equivalent shorter code when relevant:\n\n    ```js\n    // Original code\n    console.log(\n      Boolean(a ? (b | c) !== 0 : (c & d) !== 0),\n      Number(e ? '1' : '2'),\n      String(e ? '1' : '2'),\n      BigInt(e ? 1n : 2n),\n    )\n\n    // Old output (with --minify)\n    console.log(Boolean(a?(b|c)!==0:(c&d)!==0),Number(e?\"1\":\"2\"),String(e?\"1\":\"2\"),BigInt(e?1n:2n));\n\n    // New output (with --minify)\n    console.log(!!(a?b|c:c&d),+(e?\"1\":\"2\"),e?\"1\":\"2\",e?1n:2n);\n    ```\n\n* Adjust some feature compatibility tables for node ([#2940](https://github.com/evanw/esbuild/issues/2940))\n\n    This release makes the following adjustments to esbuild's internal feature compatibility tables for node, which tell esbuild which versions of node are known to support all aspects of that feature:\n\n    * `class-private-brand-checks`: node v16.9+ => node v16.4+ (a decrease)\n    * `hashbang`: node v12.0+ => node v12.5+ (an increase)\n    * `optional-chain`: node v16.9+ => node v16.1+ (a decrease)\n    * `template-literal`: node v4+ => node v10+ (an increase)\n\n    Each of these adjustments was identified by comparing against data from the `node-compat-table` package and was manually verified using old node executables downloaded from https://nodejs.org/download/release/.\n\n## 0.17.10\n\n* Update esbuild's handling of CSS nesting to match the latest specification changes ([#1945](https://github.com/evanw/esbuild/issues/1945))\n\n    The syntax for the upcoming CSS nesting feature has [recently changed](https://webkit.org/blog/13813/try-css-nesting-today-in-safari-technology-preview/). The `@nest` prefix that was previously required in some cases is now gone, and nested rules no longer have to start with `&` (as long as they don't start with an identifier or function token).\n\n    This release updates esbuild's pass-through handling of CSS nesting syntax to match the latest specification changes. So you can now use esbuild to bundle CSS containing nested rules and try them out in a browser that supports CSS nesting (which includes nightly builds of both Chrome and Safari).\n\n    However, I'm not implementing lowering of nested CSS to non-nested CSS for older browsers yet. While the syntax has been decided, the semantics are still in flux. In particular, there is still some debate about changing the fundamental way that CSS nesting works. For example, you might think that the following CSS is equivalent to a `.outer .inner button { ... }` rule:\n\n    ```css\n    .inner button {\n      .outer & {\n        color: red;\n      }\n    }\n    ```\n\n    But instead it's actually equivalent to a `.outer :is(.inner button) { ... }` rule which unintuitively also matches the following DOM structure:\n\n    ```html\n    <div class=\"inner\">\n      <div class=\"outer\">\n        <button></button>\n      </div>\n    </div>\n    ```\n\n    The `:is()` behavior is preferred by browser implementers because it's more memory-efficient, but the straightforward translation into a `.outer .inner button { ... }` rule is preferred by developers used to the existing CSS preprocessing ecosystem (e.g. SASS). It seems premature to commit esbuild to specific semantics for this syntax at this time given the ongoing debate.\n\n* Fix cross-file CSS rule deduplication involving `url()` tokens ([#2936](https://github.com/evanw/esbuild/issues/2936))\n\n    Previously cross-file CSS rule deduplication didn't handle `url()` tokens correctly. These tokens contain references to import paths which may be internal (i.e. in the bundle) or external (i.e. not in the bundle). When comparing two `url()` tokens for equality, the underlying import paths should be compared instead of their references. This release of esbuild fixes `url()` token comparisons. One side effect is that `@font-face` rules should now be deduplicated correctly across files:\n\n    ```css\n    /* Original code */\n    @import \"data:text/css, \\\n      @import 'http://example.com/style.css'; \\\n      @font-face { src: url(http://example.com/font.ttf) }\";\n    @import \"data:text/css, \\\n      @font-face { src: url(http://example.com/font.ttf) }\";\n\n    /* Old output (with --bundle --minify) */\n    @import\"http://example.com/style.css\";@font-face{src:url(http://example.com/font.ttf)}@font-face{src:url(http://example.com/font.ttf)}\n\n    /* New output (with --bundle --minify) */\n    @import\"http://example.com/style.css\";@font-face{src:url(http://example.com/font.ttf)}\n    ```\n\n## 0.17.9\n\n* Parse rest bindings in TypeScript types ([#2937](https://github.com/evanw/esbuild/issues/2937))\n\n    Previously esbuild was unable to parse the following valid TypeScript code:\n\n    ```ts\n    let tuple: (...[e1, e2, ...es]: any) => any\n    ```\n\n    This release includes support for parsing code like this.\n\n* Fix TypeScript code translation for certain computed `declare` class fields ([#2914](https://github.com/evanw/esbuild/issues/2914))\n\n    In TypeScript, the key of a computed `declare` class field should only be preserved if there are no decorators for that field. Previously esbuild always preserved the key, but esbuild will now remove the key to match the output of the TypeScript compiler:\n\n    ```ts\n    // Original code\n    declare function dec(a: any, b: any): any\n    declare const removeMe: unique symbol\n    declare const keepMe: unique symbol\n    class X {\n        declare [removeMe]: any\n        @dec declare [keepMe]: any\n    }\n\n    // Old output\n    var _a;\n    class X {\n    }\n    removeMe, _a = keepMe;\n    __decorateClass([\n      dec\n    ], X.prototype, _a, 2);\n\n    // New output\n    var _a;\n    class X {\n    }\n    _a = keepMe;\n    __decorateClass([\n      dec\n    ], X.prototype, _a, 2);\n    ```\n\n* Fix a crash with path resolution error generation ([#2913](https://github.com/evanw/esbuild/issues/2913))\n\n    In certain situations, a module containing an invalid import path could previously cause esbuild to crash when it attempts to generate a more helpful error message. This crash has been fixed.\n\n## 0.17.8\n\n* Fix a minification bug with non-ASCII identifiers ([#2910](https://github.com/evanw/esbuild/issues/2910))\n\n    This release fixes a bug with esbuild where non-ASCII identifiers followed by a keyword were incorrectly not separated by a space. This bug affected both the `in` and `instanceof` keywords. Here's an example of the fix:\n\n    ```js\n    // Original code\n    π in a\n\n    // Old output (with --minify --charset=utf8)\n    πin a;\n\n    // New output (with --minify --charset=utf8)\n    π in a;\n    ```\n\n* Fix a regression with esbuild's WebAssembly API in version 0.17.6 ([#2911](https://github.com/evanw/esbuild/issues/2911))\n\n    Version 0.17.6 of esbuild updated the Go toolchain to version 1.20.0. This had the unfortunate side effect of increasing the amount of stack space that esbuild uses (presumably due to some changes to Go's WebAssembly implementation) which could cause esbuild's WebAssembly-based API to crash with a stack overflow in cases where it previously didn't crash. One such case is the package `grapheme-splitter` which contains code that looks like this:\n\n    ```js\n    if (\n      (0x0300 <= code && code <= 0x036F) ||\n      (0x0483 <= code && code <= 0x0487) ||\n      (0x0488 <= code && code <= 0x0489) ||\n      (0x0591 <= code && code <= 0x05BD) ||\n      // ... many hundreds of lines later ...\n    ) {\n      return;\n    }\n    ```\n\n    This edge case involves a chain of binary operators that results in an AST over 400 nodes deep. Normally this wouldn't be a problem because Go has growable call stacks, so the call stack would just grow to be as large as needed. However, WebAssembly byte code deliberately doesn't expose the ability to manipulate the stack pointer, so Go's WebAssembly translation is forced to use the fixed-size WebAssembly call stack. So esbuild's WebAssembly implementation is vulnerable to stack overflow in cases like these.\n\n    It's not unreasonable for this to cause a stack overflow, and for esbuild's answer to this problem to be \"don't write code like this.\" That's how many other AST-manipulation tools handle this problem. However, it's possible to implement AST traversal using iteration instead of recursion to work around limited call stack space. This version of esbuild implements this code transformation for esbuild's JavaScript parser and printer, so esbuild's WebAssembly implementation is now able to process the `grapheme-splitter` package (at least when compiled with Go 1.20.0 and run with node's WebAssembly implementation).\n\n## 0.17.7\n\n* Change esbuild's parsing of TypeScript instantiation expressions to match TypeScript 4.8+ ([#2907](https://github.com/evanw/esbuild/issues/2907))\n\n    This release updates esbuild's implementation of instantiation expression erasure to match [microsoft/TypeScript#49353](https://github.com/microsoft/TypeScript/pull/49353). The new rules are as follows (copied from TypeScript's PR description):\n\n    > When a potential type argument list is followed by\n    >\n    > * a line break,\n    > * an `(` token,\n    > * a template literal string, or\n    > * any token except `<` or `>` that isn't the start of an expression,\n    >\n    > we consider that construct to be a type argument list. Otherwise we consider the construct to be a `<` relational expression followed by a `>` relational expression.\n\n* Ignore `sideEffects: false` for imported CSS files ([#1370](https://github.com/evanw/esbuild/issues/1370), [#1458](https://github.com/evanw/esbuild/pull/1458), [#2905](https://github.com/evanw/esbuild/issues/2905))\n\n    This release ignores the `sideEffects` annotation in `package.json` for CSS files that are imported into JS files using esbuild's `css` loader. This means that these CSS files are no longer be tree-shaken.\n\n    Importing CSS into JS causes esbuild to automatically create a CSS entry point next to the JS entry point containing the bundled CSS. Previously packages that specified some form of `\"sideEffects\": false` could potentially cause esbuild to consider one or more of the JS files on the import path to the CSS file to be side-effect free, which would result in esbuild removing that CSS file from the bundle. This was problematic because the removal of that CSS is outwardly observable, since all CSS is global, so it was incorrect for previous versions of esbuild to tree-shake CSS files imported into JS files.\n\n* Add constant folding for certain additional equality cases ([#2394](https://github.com/evanw/esbuild/issues/2394), [#2895](https://github.com/evanw/esbuild/issues/2895))\n\n    This release adds constant folding for expressions similar to the following:\n\n    ```js\n    // Original input\n    console.log(\n      null === 'foo',\n      null === undefined,\n      null == undefined,\n      false === 0,\n      false == 0,\n      1 === true,\n      1 == true,\n    )\n\n    // Old output\n    console.log(\n      null === \"foo\",\n      null === void 0,\n      null == void 0,\n      false === 0,\n      false == 0,\n      1 === true,\n      1 == true\n    );\n\n    // New output\n    console.log(\n      false,\n      false,\n      true,\n      false,\n      true,\n      false,\n      true\n    );\n    ```\n\n## 0.17.6\n\n* Fix a CSS parser crash on invalid CSS ([#2892](https://github.com/evanw/esbuild/issues/2892))\n\n    Previously the following invalid CSS caused esbuild's parser to crash:\n\n    ```css\n    @media screen\n    ```\n\n    The crash was caused by trying to construct a helpful error message assuming that there was an opening `{` token, which is not the case here. This release fixes the crash.\n\n* Inline TypeScript enums that are referenced before their declaration\n\n    Previously esbuild inlined enums within a TypeScript file from top to bottom, which meant that references to TypeScript enum members were only inlined within the same file if they came after the enum declaration. With this release, esbuild will now inline enums even when they are referenced before they are declared:\n\n    ```ts\n    // Original input\n    export const foo = () => Foo.FOO\n    const enum Foo { FOO = 0 }\n\n    // Old output (with --tree-shaking=true)\n    export const foo = () => Foo.FOO;\n    var Foo = /* @__PURE__ */ ((Foo2) => {\n      Foo2[Foo2[\"FOO\"] = 0] = \"FOO\";\n      return Foo2;\n    })(Foo || {});\n\n    // New output (with --tree-shaking=true)\n    export const foo = () => 0 /* FOO */;\n    ```\n\n    This makes esbuild's TypeScript output smaller and faster when processing code that does this. I noticed this issue when I ran the TypeScript compiler's source code through esbuild's bundler. Now that the TypeScript compiler is going to be bundled with esbuild in the upcoming TypeScript 5.0 release, improvements like this will also improve the TypeScript compiler itself!\n\n* Fix esbuild installation on Arch Linux ([#2785](https://github.com/evanw/esbuild/issues/2785), [#2812](https://github.com/evanw/esbuild/issues/2812), [#2865](https://github.com/evanw/esbuild/issues/2865))\n\n    Someone made an unofficial `esbuild` package for Linux that adds the `ESBUILD_BINARY_PATH=/usr/bin/esbuild` environment variable to the user's default environment. This breaks all npm installations of esbuild for users with this unofficial Linux package installed, which has affected many people. Most (all?) people who encounter this problem haven't even installed this unofficial package themselves; instead it was installed for them as a dependency of another Linux package. The problematic change to add the `ESBUILD_BINARY_PATH` environment variable was reverted in the latest version of this unofficial package. However, old versions of this unofficial package are still there and will be around forever. With this release, `ESBUILD_BINARY_PATH` is now ignored by esbuild's install script when it's set to the value `/usr/bin/esbuild`. This should unbreak using npm to install `esbuild` in these problematic Linux environments.\n\n    Note: The `ESBUILD_BINARY_PATH` variable is an undocumented way to override the location of esbuild's binary when esbuild's npm package is installed, which is necessary to substitute your own locally-built esbuild binary when debugging esbuild's npm package. It's only meant for very custom situations and should absolutely not be forced on others by default, especially without their knowledge. I may remove the code in esbuild's installer that reads `ESBUILD_BINARY_PATH` in the future to prevent these kinds of issues. It will unfortunately make debugging esbuild harder. If `ESBUILD_BINARY_PATH` is ever removed, it will be done in a \"breaking change\" release.\n\n## 0.17.5\n\n* Parse `const` type parameters from TypeScript 5.0\n\n    The TypeScript 5.0 beta announcement adds [`const` type parameters](https://devblogs.microsoft.com/typescript/announcing-typescript-5-0-beta/#const-type-parameters) to the language. You can now add the `const` modifier on a type parameter of a function, method, or class like this:\n\n    ```ts\n    type HasNames = { names: readonly string[] };\n    const getNamesExactly = <const T extends HasNames>(arg: T): T[\"names\"] => arg.names;\n    const names = getNamesExactly({ names: [\"Alice\", \"Bob\", \"Eve\"] });\n    ```\n\n    The type of `names` in the above example is `readonly [\"Alice\", \"Bob\", \"Eve\"]`. Marking the type parameter as `const` behaves as if you had written `as const` at every use instead. The above code is equivalent to the following TypeScript, which was the only option before TypeScript 5.0:\n\n    ```ts\n    type HasNames = { names: readonly string[] };\n    const getNamesExactly = <T extends HasNames>(arg: T): T[\"names\"] => arg.names;\n    const names = getNamesExactly({ names: [\"Alice\", \"Bob\", \"Eve\"] } as const);\n    ```\n\n    You can read [the announcement](https://devblogs.microsoft.com/typescript/announcing-typescript-5-0-beta/#const-type-parameters) for more information.\n\n* Make parsing generic `async` arrow functions more strict in `.tsx` files\n\n    Previously esbuild's TypeScript parser incorrectly accepted the following code as valid:\n\n    ```tsx\n    let fn = async <T> () => {};\n    ```\n\n    The official TypeScript parser rejects this code because it thinks it's the identifier `async` followed by a JSX element starting with `<T>`. So with this release, esbuild will now reject this syntax in `.tsx` files too. You'll now have to add a comma after the type parameter to get generic arrow functions like this to parse in `.tsx` files:\n\n    ```tsx\n    let fn = async <T,> () => {};\n    ```\n\n* Allow the `in` and `out` type parameter modifiers on class expressions\n\n    TypeScript 4.7 added the `in` and `out` modifiers on the type parameters of classes, interfaces, and type aliases. However, while TypeScript supported them on both class expressions and class statements, previously esbuild only supported them on class statements due to an oversight. This release now allows these modifiers on class expressions too:\n\n    ```ts\n    declare let Foo: any;\n    Foo = class <in T> { };\n    Foo = class <out T> { };\n    ```\n\n* Update `enum` constant folding for TypeScript 5.0\n\n    TypeScript 5.0 contains an [updated definition of what it considers a constant expression](https://github.com/microsoft/TypeScript/pull/50528):\n\n    > An expression is considered a *constant expression* if it is\n    >\n    > * a number or string literal,\n    > * a unary `+`, `-`, or `~` applied to a numeric constant expression,\n    > * a binary `+`, `-`, `*`, `/`, `%`, `**`, `<<`, `>>`, `>>>`, `|`, `&`, `^` applied to two numeric constant expressions,\n    > * a binary `+` applied to two constant expressions whereof at least one is a string,\n    > * a template expression where each substitution expression is a constant expression,\n    > * a parenthesized constant expression,\n    > * a dotted name (e.g. `x.y.z`) that references a `const` variable with a constant expression initializer and no type annotation,\n    > * a dotted name that references an enum member with an enum literal type, or\n    > * a dotted name indexed by a string literal (e.g. `x.y[\"z\"]`) that references an enum member with an enum literal type.\n\n    This impacts esbuild's implementation of TypeScript's `const enum` feature. With this release, esbuild will now attempt to follow these new rules. For example, you can now initialize an `enum` member with a template literal expression that contains a numeric constant:\n\n    ```ts\n    // Original input\n    const enum Example {\n      COUNT = 100,\n      ERROR = `Expected ${COUNT} items`,\n    }\n    console.log(\n      Example.COUNT,\n      Example.ERROR,\n    )\n\n    // Old output (with --tree-shaking=true)\n    var Example = /* @__PURE__ */ ((Example2) => {\n      Example2[Example2[\"COUNT\"] = 100] = \"COUNT\";\n      Example2[Example2[\"ERROR\"] = `Expected ${100 /* COUNT */} items`] = \"ERROR\";\n      return Example2;\n    })(Example || {});\n    console.log(\n      100 /* COUNT */,\n      Example.ERROR\n    );\n\n    // New output (with --tree-shaking=true)\n    console.log(\n      100 /* COUNT */,\n      \"Expected 100 items\" /* ERROR */\n    );\n    ```\n\n    These rules are not followed exactly due to esbuild's limitations. The rule about dotted references to `const` variables is not followed both because esbuild's enum processing is done in an isolated module setting and because doing so would potentially require esbuild to use a type system, which it doesn't have. For example:\n\n    ```ts\n    // The TypeScript compiler inlines this but esbuild doesn't:\n    declare const x = 'foo'\n    const enum Foo { X = x }\n    console.log(Foo.X)\n    ```\n\n    Also, the rule that requires converting numbers to a string currently only followed for 32-bit signed integers and non-finite numbers. This is done to avoid accidentally introducing a bug if esbuild's number-to-string operation doesn't exactly match the behavior of a real JavaScript VM. Currently esbuild's number-to-string constant folding is conservative for safety.\n\n* Forbid definite assignment assertion operators on class methods\n\n    In TypeScript, class methods can use the `?` optional property operator but not the `!` definite assignment assertion operator (while class fields can use both):\n\n    ```ts\n    class Foo {\n      // These are valid TypeScript\n      a?\n      b!\n      x?() {}\n\n      // This is invalid TypeScript\n      y!() {}\n    }\n    ```\n\n    Previously esbuild incorrectly allowed the definite assignment assertion operator with class methods. This will no longer be allowed starting with this release.\n\n## 0.17.4\n\n* Implement HTTP `HEAD` requests in serve mode ([#2851](https://github.com/evanw/esbuild/issues/2851))\n\n    Previously esbuild's serve mode only responded to HTTP `GET` requests. With this release, esbuild's serve mode will also respond to HTTP `HEAD` requests, which are just like HTTP `GET` requests except that the body of the response is omitted.\n\n* Permit top-level await in dead code branches ([#2853](https://github.com/evanw/esbuild/issues/2853))\n\n    Adding top-level await to a file has a few consequences with esbuild:\n\n    1. It causes esbuild to assume that the input module format is ESM, since top-level await is only syntactically valid in ESM. That prevents you from using `module` and `exports` for exports and also enables strict mode, which disables certain syntax and changes how function hoisting works (among other things).\n    2. This will cause esbuild to fail the build if either top-level await isn't supported by your language target (e.g. it's not supported in ES2021) or if top-level await isn't supported by the chosen output format (e.g. it's not supported with CommonJS).\n    3. Doing this will prevent you from using `require()` on this file or on any file that imports this file (even indirectly), since the `require()` function doesn't return a promise and so can't represent top-level await.\n\n    This release relaxes these rules slightly: rules 2 and 3 will now no longer apply when esbuild has identified the code branch as dead code, such as when it's behind an `if (false)` check. This should make it possible to use esbuild to convert code into different output formats that only uses top-level await conditionally. This release does not relax rule 1. Top-level await will still cause esbuild to unconditionally consider the input module format to be ESM, even when the top-level `await` is in a dead code branch. This is necessary because whether the input format is ESM or not affects the whole file, not just the dead code branch.\n\n* Fix entry points where the entire file name is the extension ([#2861](https://github.com/evanw/esbuild/issues/2861))\n\n    Previously if you passed esbuild an entry point where the file extension is the entire file name, esbuild would use the parent directory name to derive the name of the output file. For example, if you passed esbuild a file `./src/.ts` then the output name would be `src.js`. This bug happened because esbuild first strips the file extension to get `./src/` and then joins the path with the working directory to get the absolute path (e.g. `join(\"/working/dir\", \"./src/\")` gives `/working/dir/src`). However, the join operation also canonicalizes the path which strips the trailing `/`. Later esbuild uses the \"base name\" operation to extract the name of the output file. Since there is no trailing `/`, esbuild returns `\"src\"` as the base name instead of `\"\"`, which causes esbuild to incorrectly include the directory name in the output file name. This release fixes this bug by deferring the stripping of the file extension until after all path manipulations have been completed. So now the file `./src/.ts` will generate an output file named `.js`.\n\n* Support replacing property access expressions with inject\n\n    At a high level, this change means the `inject` feature can now replace all of the same kinds of names as the `define` feature. So `inject` is basically now a more powerful version of `define`, instead of previously only being able to do some of the things that `define` could do.\n\n    Soem background is necessary to understand this change if you aren't already familiar with the `inject` feature. The `inject` feature lets you replace references to global variable with a shim. It works like this:\n\n    1. Put the shim in its own file\n    2. Export the shim as the name of the global variable you intend to replace\n    3. Pass the file to esbuild using the `inject` feature\n\n    For example, if you inject the following file using `--inject:./injected.js`:\n\n    ```js\n    // injected.js\n    let processShim = { cwd: () => '/' }\n    export { processShim as process }\n    ```\n\n    Then esbuild will replace all references to `process` with the `processShim` variable, which will cause `process.cwd()` to return `'/'`. This feature is sort of abusing the ESM export alias syntax to specify the mapping of global variables to shims. But esbuild works this way because using this syntax for that purpose is convenient and terse.\n\n    However, if you wanted to replace a property access expression, the process was more complicated and not as nice. You would have to:\n\n    1. Put the shim in its own file\n    2. Export the shim as some random name\n    3. Pass the file to esbuild using the `inject` feature\n    4. Use esbuild's `define` feature to map the property access expression to the random name you made in step 2\n\n    For example, if you inject the following file using `--inject:./injected2.js --define:process.cwd=someRandomName`:\n\n    ```js\n    // injected2.js\n    let cwdShim = () => '/'\n    export { cwdShim as someRandomName }\n    ```\n\n    Then esbuild will replace all references to `process.cwd` with the `cwdShim` variable, which will also cause `process.cwd()` to return `'/'` (but which this time will not mess with other references to `process`, which might be desirable).\n\n    With this release, using the inject feature to replace a property access expression is now as simple as using it to replace an identifier. You can now use JavaScript's [\"arbitrary module namespace identifier names\"](https://github.com/tc39/ecma262/pull/2154) feature to specify the property access expression directly using a string literal. For example, if you inject the following file using `--inject:./injected3.js`:\n\n    ```js\n    // injected3.js\n    let cwdShim = () => '/'\n    export { cwdShim as 'process.cwd' }\n    ```\n\n    Then esbuild will now replace all references to `process.cwd` with the `cwdShim` variable, which will also cause `process.cwd()` to return `'/'` (but which will also not mess with other references to `process`).\n\n    In addition to inserting a shim for a global variable that doesn't exist, another use case is replacing references to static methods on global objects with cached versions to both minify them better and to make access to them potentially faster. For example:\n\n    ```js\n    // Injected file\n    let cachedMin = Math.min\n    let cachedMax = Math.max\n    export {\n      cachedMin as 'Math.min',\n      cachedMax as 'Math.max',\n    }\n\n    // Original input\n    function clampRGB(r, g, b) {\n      return {\n        r: Math.max(0, Math.min(1, r)),\n        g: Math.max(0, Math.min(1, g)),\n        b: Math.max(0, Math.min(1, b)),\n      }\n    }\n\n    // Old output (with --minify)\n    function clampRGB(a,t,m){return{r:Math.max(0,Math.min(1,a)),g:Math.max(0,Math.min(1,t)),b:Math.max(0,Math.min(1,m))}}\n\n    // New output (with --minify)\n    var a=Math.min,t=Math.max;function clampRGB(h,M,m){return{r:t(0,a(1,h)),g:t(0,a(1,M)),b:t(0,a(1,m))}}\n    ```\n\n## 0.17.3\n\n* Fix incorrect CSS minification for certain rules ([#2838](https://github.com/evanw/esbuild/issues/2838))\n\n    Certain rules such as `@media` could previously be minified incorrectly. Due to a typo in the duplicate rule checker, two known `@`-rules that share the same hash code were incorrectly considered to be equal. This problem was made worse by the rule hashing code considering two unknown declarations (such as CSS variables) to have the same hash code, which also isn't optimal from a performance perspective. Both of these issues have been fixed:\n\n    ```css\n    /* Original input */\n    @media (prefers-color-scheme: dark) { body { --VAR-1: #000; } }\n    @media (prefers-color-scheme: dark) { body { --VAR-2: #000; } }\n\n    /* Old output (with --minify) */\n    @media (prefers-color-scheme: dark){body{--VAR-2: #000}}\n\n    /* New output (with --minify) */\n    @media (prefers-color-scheme: dark){body{--VAR-1: #000}}@media (prefers-color-scheme: dark){body{--VAR-2: #000}}\n    ```\n\n## 0.17.2\n\n* Add `onDispose` to the plugin API ([#2140](https://github.com/evanw/esbuild/issues/2140), [#2205](https://github.com/evanw/esbuild/issues/2205))\n\n    If your plugin wants to perform some cleanup after it's no longer going to be used, you can now use the `onDispose` API to register a callback for cleanup-related tasks. For example, if a plugin starts a long-running child process then it may want to terminate that process when the plugin is discarded. Previously there was no way to do this. Here's an example:\n\n    ```js\n    let examplePlugin = {\n      name: 'example',\n      setup(build) {\n        build.onDispose(() => {\n          console.log('This plugin is no longer used')\n        })\n      },\n    }\n    ```\n\n    These `onDispose` callbacks will be called after every `build()` call regardless of whether the build failed or not as well as after the first `dispose()` call on a given build context.\n\n## 0.17.1\n\n* Make it possible to cancel a build ([#2725](https://github.com/evanw/esbuild/issues/2725))\n\n    The context object introduced in version 0.17.0 has a new `cancel()` method. You can use it to cancel a long-running build so that you can start a new one without needing to wait for the previous one to finish. When this happens, the previous build should always have at least one error and have no output files (i.e. it will be a failed build).\n\n    Using it might look something like this:\n\n    * JS:\n\n        ```js\n        let ctx = await esbuild.context({\n          // ...\n        })\n\n        let rebuildWithTimeLimit = timeLimit => {\n          let timeout = setTimeout(() => ctx.cancel(), timeLimit)\n          return ctx.rebuild().finally(() => clearTimeout(timeout))\n        }\n\n        let build = await rebuildWithTimeLimit(500)\n        ```\n\n    * Go:\n\n        ```go\n        ctx, err := api.Context(api.BuildOptions{\n          // ...\n        })\n        if err != nil {\n          return\n        }\n\n        rebuildWithTimeLimit := func(timeLimit time.Duration) api.BuildResult {\n          t := time.NewTimer(timeLimit)\n          go func() {\n            <-t.C\n            ctx.Cancel()\n          }()\n          result := ctx.Rebuild()\n          t.Stop()\n          return result\n        }\n\n        build := rebuildWithTimeLimit(500 * time.Millisecond)\n        ```\n\n    This API is a quick implementation and isn't maximally efficient, so the build may continue to do some work for a little bit before stopping. For example, I have added stop points between each top-level phase of the bundler and in the main module graph traversal loop, but I haven't added fine-grained stop points within the internals of the linker. How quickly esbuild stops can be improved in future releases. This means you'll want to wait for `cancel()` and/or the previous `rebuild()` to finish (i.e. await the returned promise in JavaScript) before starting a new build, otherwise `rebuild()` will give you the just-canceled build that still hasn't ended yet. Note that `onEnd` callbacks will still be run regardless of whether or not the build was canceled.\n\n* Fix server-sent events without `servedir` ([#2827](https://github.com/evanw/esbuild/issues/2827))\n\n    The server-sent events for live reload were incorrectly using `servedir` to calculate the path to modified output files. This means events couldn't be sent when `servedir` wasn't specified. This release uses the internal output directory (which is always present) instead of `servedir` (which might be omitted), so live reload should now work when `servedir` is not specified.\n\n* Custom entry point output paths now work with the `copy` loader ([#2828](https://github.com/evanw/esbuild/issues/2828))\n\n    Entry points can optionally provide custom output paths to change the path of the generated output file. For example, `esbuild foo=abc.js bar=xyz.js --outdir=out` generates the files `out/foo.js` and `out/bar.js`. However, this previously didn't work when using the `copy` loader due to an oversight. This bug has been fixed. For example, you can now do `esbuild foo=abc.html bar=xyz.html --outdir=out --loader:.html=copy` to generate the files `out/foo.html` and `out/bar.html`.\n\n* The JS API can now take an array of objects ([#2828](https://github.com/evanw/esbuild/issues/2828))\n\n    Previously it was not possible to specify two entry points with the same custom output path using the JS API, although it was possible to do this with the Go API and the CLI. This will not cause a collision if both entry points use different extensions (e.g. if one uses `.js` and the other uses `.css`). You can now pass the JS API an array of objects to work around this API limitation:\n\n    ```js\n    // The previous API didn't let you specify duplicate output paths\n    let result = await esbuild.build({\n      entryPoints: {\n        // This object literal contains a duplicate key, so one is ignored\n        'dist': 'foo.js',\n        'dist': 'bar.css',\n      },\n    })\n\n    // You can now specify duplicate output paths as an array of objects\n    let result = await esbuild.build({\n      entryPoints: [\n        { in: 'foo.js', out: 'dist' },\n        { in: 'bar.css', out: 'dist' },\n      ],\n    })\n    ```\n\n## 0.17.0\n\n**This release deliberately contains backwards-incompatible changes.** To avoid automatically picking up releases like this, you should either be pinning the exact version of `esbuild` in your `package.json` file (recommended) or be using a version range syntax that only accepts patch upgrades such as `^0.16.0` or `~0.16.0`. See npm's documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\nAt a high level, the breaking changes in this release fix some long-standing issues with the design of esbuild's incremental, watch, and serve APIs. This release also introduces some exciting new features such as live reloading. In detail:\n\n* Move everything related to incremental builds to a new `context` API ([#1037](https://github.com/evanw/esbuild/issues/1037), [#1606](https://github.com/evanw/esbuild/issues/1606), [#2280](https://github.com/evanw/esbuild/issues/2280), [#2418](https://github.com/evanw/esbuild/issues/2418))\n\n    This change removes the `incremental` and `watch` options as well as the `serve()` method, and introduces a new `context()` method. The context method takes the same arguments as the `build()` method but only validates its arguments and does not do an initial build. Instead, builds can be triggered using the `rebuild()`, `watch()`, and `serve()` methods on the returned context object. The new context API looks like this:\n\n    ```js\n    // Create a context for incremental builds\n    const context = await esbuild.context({\n      entryPoints: ['app.ts'],\n      bundle: true,\n    })\n\n    // Manually do an incremental build\n    const result = await context.rebuild()\n\n    // Enable watch mode\n    await context.watch()\n\n    // Enable serve mode\n    await context.serve()\n\n    // Dispose of the context\n    context.dispose()\n    ```\n\n    The switch to the context API solves a major issue with the previous API which is that if the initial build fails, a promise is thrown in JavaScript which prevents you from accessing the returned result object. That prevented you from setting up long-running operations such as watch mode when the initial build contained errors. It also makes tearing down incremental builds simpler as there is now a single way to do it instead of three separate ways.\n\n    In addition, this release also makes some subtle changes to how incremental builds work. Previously every call to `rebuild()` started a new build. If you weren't careful, then builds could actually overlap. This doesn't cause any problems with esbuild itself, but could potentially cause problems with plugins (esbuild doesn't even give you a way to identify which overlapping build a given plugin callback is running on). Overlapping builds also arguably aren't useful, or at least aren't useful enough to justify the confusion and complexity that they bring. With this release, there is now only ever a single active build per context. Calling `rebuild()` before the previous rebuild has finished now \"merges\" with the existing rebuild instead of starting a new build.\n\n* Allow using `watch` and `serve` together ([#805](https://github.com/evanw/esbuild/issues/805), [#1650](https://github.com/evanw/esbuild/issues/1650), [#2576](https://github.com/evanw/esbuild/issues/2576))\n\n    Previously it was not possible to use watch mode and serve mode together. The rationale was that watch mode is one way of automatically rebuilding your project and serve mode is another (since serve mode automatically rebuilds on every request). However, people want to combine these two features to make \"live reloading\" where the browser automatically reloads the page when files are changed on the file system.\n\n    This release now allows you to use these two features together. You can only call the `watch()` and `serve()` APIs once each per context, but if you call them together on the same context then esbuild will automatically rebuild both when files on the file system are changed *and* when the server serves a request.\n\n* Support \"live reloading\" through server-sent events ([#802](https://github.com/evanw/esbuild/issues/802))\n\n    [Server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) are a simple way to pass one-directional messages asynchronously from the server to the client. Serve mode now provides a `/esbuild` endpoint with an `change` event that triggers every time esbuild's output changes. So you can now implement simple \"live reloading\" (i.e. reloading the page when a file is edited and saved) like this:\n\n    ```js\n    new EventSource('/esbuild').addEventListener('change', () => location.reload())\n    ```\n\n    The event payload is a JSON object with the following shape:\n\n    ```ts\n    interface ChangeEvent {\n      added: string[]\n      removed: string[]\n      updated: string[]\n    }\n    ```\n\n    This JSON should also enable more complex live reloading scenarios. For example, the following code hot-swaps changed CSS `<link>` tags in place without reloading the page (but still reloads when there are other types of changes):\n\n    ```js\n    new EventSource('/esbuild').addEventListener('change', e => {\n      const { added, removed, updated } = JSON.parse(e.data)\n      if (!added.length && !removed.length && updated.length === 1) {\n        for (const link of document.getElementsByTagName(\"link\")) {\n          const url = new URL(link.href)\n          if (url.host === location.host && url.pathname === updated[0]) {\n            const next = link.cloneNode()\n            next.href = updated[0] + '?' + Math.random().toString(36).slice(2)\n            next.onload = () => link.remove()\n            link.parentNode.insertBefore(next, link.nextSibling)\n            return\n          }\n        }\n      }\n      location.reload()\n    })\n    ```\n\n    Implementing live reloading like this has a few known caveats:\n\n    * These events only trigger when esbuild's output changes. They do not trigger when files unrelated to the build being watched are changed. If your HTML file references other files that esbuild doesn't know about and those files are changed, you can either manually reload the page or you can implement your own live reloading infrastructure instead of using esbuild's built-in behavior.\n\n    * The `EventSource` API is supposed to automatically reconnect for you. However, there's a bug in Firefox that breaks this if the server is ever temporarily unreachable: https://bugzilla.mozilla.org/show_bug.cgi?id=1809332. Workarounds are to use any other browser, to manually reload the page if this happens, or to write more complicated code that manually closes and re-creates the `EventSource` object if there is a connection error. I'm hopeful that this bug will be fixed.\n\n    * Browser vendors have decided to not implement HTTP/2 without TLS. This means that each `/esbuild` event source will take up one of your precious 6 simultaneous per-domain HTTP/1.1 connections. So if you open more than six HTTP tabs that use this live-reloading technique, you will be unable to use live reloading in some of those tabs (and other things will likely also break). The workaround is to enable HTTPS, which is now possible to do in esbuild itself (see below).\n\n* Add built-in support for HTTPS ([#2169](https://github.com/evanw/esbuild/issues/2169))\n\n    You can now tell esbuild's built-in development server to use HTTPS instead of HTTP. This is sometimes necessary because browser vendors have started making modern web features unavailable to HTTP websites. Previously you had to put a proxy in front of esbuild to enable HTTPS since esbuild's development server only supported HTTP. But with this release, you can now enable HTTPS with esbuild without an additional proxy.\n\n    To enable HTTPS with esbuild:\n\n    1. Generate a self-signed certificate. There are many ways to do this. Here's one way, assuming you have `openssl` installed:\n\n        ```\n        openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 9999 -nodes -subj /CN=127.0.0.1\n        ```\n\n    2. Add `--keyfile=key.pem` and `--certfile=cert.pem` to your esbuild development server command\n    3. Click past the scary warning in your browser when you load your page\n\n    If you have more complex needs than this, you can still put a proxy in front of esbuild and use that for HTTPS instead. Note that if you see the message \"Client sent an HTTP request to an HTTPS server\" when you load your page, then you are using the incorrect protocol. Replace `http://` with `https://` in your browser's URL bar.\n\n    Keep in mind that esbuild's HTTPS support has nothing to do with security. The only reason esbuild now supports HTTPS is because browsers have made it impossible to do local development with certain modern web features without jumping through these extra hoops. *Please do not use esbuild's development server for anything that needs to be secure.* It's only intended for local development and no considerations have been made for production environments whatsoever.\n\n* Better support copying `index.html` into the output directory ([#621](https://github.com/evanw/esbuild/issues/621), [#1771](https://github.com/evanw/esbuild/issues/1771))\n\n    Right now esbuild only supports JavaScript and CSS as first-class content types. Previously this meant that if you were building a website with a HTML file, a JavaScript file, and a CSS file, you could use esbuild to build the JavaScript file and the CSS file into the output directory but not to copy the HTML file into the output directory. You needed a separate `cp` command for that.\n\n    Or so I thought. It turns out that the `copy` loader added in version 0.14.44 of esbuild is sufficient to have esbuild copy the HTML file into the output directory as well. You can add something like `index.html --loader:.html=copy` and esbuild will copy `index.html` into the output directory for you. The benefits of this are a) you don't need a separate `cp` command and b) the `index.html` file will automatically be re-copied when esbuild is in watch mode and the contents of `index.html` are edited. This also goes for other non-HTML file types that you might want to copy.\n\n    This pretty much already worked. The one thing that didn't work was that esbuild's built-in development server previously only supported implicitly loading `index.html` (e.g. loading `/about/index.html` when you visit `/about/`) when `index.html` existed on the file system. Previously esbuild didn't support implicitly loading `index.html` if it was a build result. That bug has been fixed with this release so it should now be practical to use the `copy` loader to do this.\n\n* Fix `onEnd` not being called in serve mode ([#1384](https://github.com/evanw/esbuild/issues/1384))\n\n    Previous releases had a bug where plugin `onEnd` callbacks weren't called when using the top-level `serve()` API. This API no longer exists and the internals have been reimplemented such that `onEnd` callbacks should now always be called at the end of every build.\n\n* Incremental builds now write out build results differently ([#2104](https://github.com/evanw/esbuild/issues/2104))\n\n    Previously build results were always written out after every build. However, this could cause the output directory to fill up with files from old builds if code splitting was enabled, since the file names for code splitting chunks contain content hashes and old files were not deleted.\n\n    With this release, incremental builds in esbuild will now delete old output files from previous builds that are no longer relevant. Subsequent incremental builds will also no longer overwrite output files whose contents haven't changed since the previous incremental build.\n\n* The `onRebuild` watch mode callback was removed ([#980](https://github.com/evanw/esbuild/issues/980), [#2499](https://github.com/evanw/esbuild/issues/2499))\n\n    Previously watch mode accepted an `onRebuild` callback which was called whenever watch mode rebuilt something. This was not great in practice because if you are running code after a build, you likely want that code to run after every build, not just after the second and subsequent builds. This release removes option to provide an `onRebuild` callback. You can create a plugin with an `onEnd` callback instead. The `onEnd` plugin API already exists, and is a way to run some code after every build.\n\n* You can now return errors from `onEnd` ([#2625](https://github.com/evanw/esbuild/issues/2625))\n\n    It's now possible to add additional build errors and/or warnings to the current build from within your `onEnd` callback by returning them in an array. This is identical to how the `onStart` callback already works. The evaluation of `onEnd` callbacks have been moved around a bit internally to make this possible.\n\n    Note that the build will only fail (i.e. reject the promise) if the additional errors are returned from `onEnd`. Adding additional errors to the result object that's passed to `onEnd` won't affect esbuild's behavior at all.\n\n* Print URLs and ports from the Go and JS APIs ([#2393](https://github.com/evanw/esbuild/issues/2393))\n\n    Previously esbuild's CLI printed out something like this when serve mode is active:\n\n    ```\n     > Local:   http://127.0.0.1:8000/\n     > Network: http://192.168.0.1:8000/\n    ```\n\n    The CLI still does this, but now the JS and Go serve mode APIs will do this too. This only happens when the log level is set to `verbose`, `debug`, or `info` but not when it's set to `warning`, `error`, or `silent`.\n\n### Upgrade guide for existing code:\n\n* Rebuild (a.k.a. incremental build):\n\n    Before:\n\n    ```js\n    const result = await esbuild.build({ ...buildOptions, incremental: true });\n    builds.push(result);\n    for (let i = 0; i < 4; i++) builds.push(await result.rebuild());\n    await result.rebuild.dispose(); // To free resources\n    ```\n\n    After:\n\n    ```js\n    const ctx = await esbuild.context(buildOptions);\n    for (let i = 0; i < 5; i++) builds.push(await ctx.rebuild());\n    await ctx.dispose(); // To free resources\n    ```\n\n    Previously the first build was done differently than subsequent builds. Now both the first build and subsequent builds are done using the same API.\n\n* Serve:\n\n    Before:\n\n    ```js\n    const serveResult = await esbuild.serve(serveOptions, buildOptions);\n    ...\n    serveResult.stop(); await serveResult.wait; // To free resources\n    ```\n\n    After:\n\n    ```js\n    const ctx = await esbuild.context(buildOptions);\n    const serveResult = await ctx.serve(serveOptions);\n    ...\n    await ctx.dispose(); // To free resources\n    ```\n\n* Watch:\n\n    Before:\n\n    ```js\n    const result = await esbuild.build({ ...buildOptions, watch: true });\n    ...\n    result.stop(); // To free resources\n    ```\n\n    After:\n\n    ```js\n    const ctx = await esbuild.context(buildOptions);\n    await ctx.watch();\n    ...\n    await ctx.dispose(); // To free resources\n    ```\n\n* Watch with `onRebuild`:\n\n    Before:\n\n    ```js\n    const onRebuild = (error, result) => {\n      if (error) console.log('subsequent build:', error);\n      else console.log('subsequent build:', result);\n    };\n    try {\n      const result = await esbuild.build({ ...buildOptions, watch: { onRebuild } });\n      console.log('first build:', result);\n      ...\n      result.stop(); // To free resources\n    } catch (error) {\n      console.log('first build:', error);\n    }\n    ```\n\n    After:\n\n    ```js\n    const plugins = [{\n      name: 'my-plugin',\n      setup(build) {\n        let count = 0;\n        build.onEnd(result => {\n          if (count++ === 0) console.log('first build:', result);\n          else console.log('subsequent build:', result);\n        });\n      },\n    }];\n    const ctx = await esbuild.context({ ...buildOptions, plugins });\n    await ctx.watch();\n    ...\n    await ctx.dispose(); // To free resources\n    ```\n\n    The `onRebuild` function has now been removed. The replacement is to make a plugin with an `onEnd` callback.\n\n    Previously `onRebuild` did not fire for the first build (only for subsequent builds). This was usually problematic, so using `onEnd` instead of `onRebuild` is likely less error-prone. But if you need to emulate the old behavior of `onRebuild` that ignores the first build, then you'll need to manually count and ignore the first build in your plugin (as demonstrated above).\n\nNotice how all of these API calls are now done off the new context object. You should now be able to use all three kinds of incremental builds (`rebuild`, `serve`, and `watch`) together on the same context object. Also notice how calling `dispose` on the context is now the common way to discard the context and free resources in all of these situations.\n\n## 0.16.17\n\n* Fix additional comment-related regressions ([#2814](https://github.com/evanw/esbuild/issues/2814))\n\n    This release fixes more edge cases where the new comment preservation behavior that was added in 0.16.14 could introduce syntax errors. Specifically:\n\n    ```js\n    x = () => (/* comment */ {})\n    for ((/* comment */ let).x of y) ;\n    function *f() { yield (/* comment */class {}) }\n    ```\n\n    These cases caused esbuild to generate code with a syntax error in version 0.16.14 or above. These bugs have now been fixed.\n\n## 0.16.16\n\n* Fix a regression caused by comment preservation ([#2805](https://github.com/evanw/esbuild/issues/2805))\n\n    The new comment preservation behavior that was added in 0.16.14 introduced a regression where comments in certain locations could cause esbuild to omit certain necessary parentheses in the output. The outermost parentheses were incorrectly removed for the following syntax forms, which then introduced syntax errors:\n\n    ```js\n    (/* comment */ { x: 0 }).x;\n    (/* comment */ function () { })();\n    (/* comment */ class { }).prototype;\n    ```\n\n    This regression has been fixed.\n\n## 0.16.15\n\n* Add `format` to input files in the JSON metafile data\n\n    When `--metafile` is enabled, input files may now have an additional `format` field that indicates the export format used by this file. When present, the value will either be `cjs` for CommonJS-style exports or `esm` for ESM-style exports. This can be useful in bundle analysis.\n\n    For example, esbuild's new [Bundle Size Analyzer](https://esbuild.github.io/analyze/) now uses this information to visualize whether ESM or CommonJS was used for each directory and file of source code (click on the CJS/ESM bar at the top).\n\n    This information is helpful when trying to reduce the size of your bundle. Using the ESM variant of a dependency instead of the CommonJS variant always results in a faster and smaller bundle because it omits CommonJS wrappers, and also may result in better tree-shaking as it allows esbuild to perform tree-shaking at the statement level instead of the module level.\n\n* Fix a bundling edge case with dynamic import ([#2793](https://github.com/evanw/esbuild/issues/2793))\n\n    This release fixes a bug where esbuild's bundler could produce incorrect output. The problematic edge case involves the entry point importing itself using a dynamic `import()` expression in an imported file, like this:\n\n    ```js\n    // src/a.js\n    export const A = 42;\n\n    // src/b.js\n    export const B = async () => (await import(\".\")).A\n\n    // src/index.js\n    export * from \"./a\"\n    export * from \"./b\"\n    ```\n\n* Remove new type syntax from type declarations in the `esbuild` package ([#2798](https://github.com/evanw/esbuild/issues/2798))\n\n    Previously you needed to use TypeScript 4.3 or newer when using the `esbuild` package from TypeScript code due to the use of a getter in an interface in `node_modules/esbuild/lib/main.d.ts`. This release removes this newer syntax to allow people with versions of TypeScript as far back as TypeScript 3.5 to use this latest version of the `esbuild` package. Here is change that was made to esbuild's type declarations:\n\n    ```diff\n     export interface OutputFile {\n       /** \"text\" as bytes */\n       contents: Uint8Array;\n       /** \"contents\" as text (changes automatically with \"contents\") */\n    -  get text(): string;\n    +  readonly text: string;\n     }\n    ```\n\n## 0.16.14\n\n* Preserve some comments in expressions ([#2721](https://github.com/evanw/esbuild/issues/2721))\n\n    Various tools give semantic meaning to comments embedded inside of expressions. For example, Webpack and Vite have special \"magic comments\" that can be used to affect code splitting behavior:\n\n    ```js\n    import(/* webpackChunkName: \"foo\" */ '../foo');\n    import(/* @vite-ignore */ dynamicVar);\n    new Worker(/* webpackChunkName: \"bar\" */ new URL(\"../bar.ts\", import.meta.url));\n    new Worker(new URL('./path', import.meta.url), /* @vite-ignore */ dynamicOptions);\n    ```\n\n    Since esbuild can be used as a preprocessor for these tools (e.g. to strip TypeScript types), it can be problematic if esbuild doesn't do additional work to try to retain these comments. Previously esbuild special-cased Webpack comments in these specific locations in the AST. But Vite would now like to use similar comments, and likely other tools as well.\n\n    So with this release, esbuild now will attempt to preserve some comments inside of expressions in more situations than before. This behavior is mainly intended to preserve these special \"magic comments\" that are meant for other tools to consume, although esbuild will no longer only preserve Webpack-specific comments so it should now be tool-agnostic. There is no guarantee that all such comments will be preserved (especially when `--minify-syntax` is enabled). So this change does *not* mean that esbuild is now usable as a code formatter. In particular comment preservation is more likely to happen with leading comments than with trailing comments. You should put comments that you want to be preserved *before* the relevant expression instead of after it. Also note that this change does not retain any more statement-level comments than before (i.e. comments not embedded inside of expressions). Comment preservation is not enabled when `--minify-whitespace` is enabled (which is automatically enabled when you use `--minify`).\n\n## 0.16.13\n\n* Publish a new bundle visualization tool\n\n    While esbuild provides bundle metadata via the `--metafile` flag, previously esbuild left analysis of it completely up to third-party tools (well, outside of the rudimentary `--analyze` flag). However, the esbuild website now has a built-in bundle visualization tool:\n\n    * https://esbuild.github.io/analyze/\n\n    You can pass `--metafile` to esbuild to output bundle metadata, then upload that JSON file to this tool to visualize your bundle. This is helpful for answering questions such as:\n\n    * Which packages are included in my bundle?\n    * How did a specific file get included?\n    * How small did a specific file compress to?\n    * Was a specific file tree-shaken or not?\n\n    I'm publishing this tool because I think esbuild should provide *some* answer to \"how do I visualize my bundle\" without requiring people to reach for third-party tools. At the moment the tool offers two types of visualizations: a radial \"sunburst chart\" and a linear \"flame chart\". They serve slightly different but overlapping use cases (e.g. the sunburst chart is more keyboard-accessible while the flame chart is easier with the mouse). This tool may continue to evolve over time.\n\n* Fix `--metafile` and `--mangle-cache` with `--watch` ([#1357](https://github.com/evanw/esbuild/issues/1357))\n\n    The CLI calls the Go API and then also writes out the metafile and/or mangle cache JSON files if those features are enabled. This extra step is necessary because these files are returned by the Go API as in-memory strings. However, this extra step accidentally didn't happen for all builds after the initial build when watch mode was enabled. This behavior used to work but it was broken in version 0.14.18 by the introduction of the mangle cache feature. This release fixes the combination of these features, so the metafile and mangle cache features should now work with watch mode. This behavior was only broken for the CLI, not for the JS or Go APIs.\n\n* Add an `original` field to the metafile\n\n    The metadata file JSON now has an additional field: each import in an input file now contains the pre-resolved path in the `original` field in addition to the post-resolved path in the `path` field. This means it's now possible to run certain additional analysis over your bundle. For example, you should be able to use this to detect when the same package subpath is represented multiple times in the bundle, either because multiple versions of a package were bundled or because a package is experiencing the [dual-package hazard](https://nodejs.org/api/packages.html#dual-package-hazard).\n"
  },
  {
    "path": "CHANGELOG-2024.md",
    "content": "# Changelog: 2024\n\nThis changelog documents all esbuild versions published in the year 2024 (versions 0.19.12 through 0.24.2).\n\n## 0.24.2\n\n* Fix regression with `--define` and `import.meta` ([#4010](https://github.com/evanw/esbuild/issues/4010), [#4012](https://github.com/evanw/esbuild/issues/4012), [#4013](https://github.com/evanw/esbuild/pull/4013))\n\n    The previous change in version 0.24.1 to use a more expression-like parser for `define` values to allow quoted property names introduced a regression that removed the ability to use `--define:import.meta=...`. Even though `import` is normally a keyword that can't be used as an identifier, ES modules special-case the `import.meta` expression to behave like an identifier anyway. This change fixes the regression.\n\n    This fix was contributed by [@sapphi-red](https://github.com/sapphi-red).\n\n## 0.24.1\n\n* Allow `es2024` as a target in `tsconfig.json` ([#4004](https://github.com/evanw/esbuild/issues/4004))\n\n    TypeScript recently [added `es2024`](https://devblogs.microsoft.com/typescript/announcing-typescript-5-7/#support-for---target-es2024-and---lib-es2024) as a compilation target, so esbuild now supports this in the `target` field of `tsconfig.json` files, such as in the following configuration file:\n\n    ```json\n    {\n      \"compilerOptions\": {\n        \"target\": \"ES2024\"\n      }\n    }\n    ```\n\n    As a reminder, the only thing that esbuild uses this field for is determining whether or not to use legacy TypeScript behavior for class fields. You can read more in [the documentation](https://esbuild.github.io/content-types/#tsconfig-json).\n\n    This fix was contributed by [@billyjanitsch](https://github.com/billyjanitsch).\n\n* Allow automatic semicolon insertion after `get`/`set`\n\n    This change fixes a grammar bug in the parser that incorrectly treated the following code as a syntax error:\n\n    ```ts\n    class Foo {\n      get\n      *x() {}\n      set\n      *y() {}\n    }\n    ```\n\n    The above code will be considered valid starting with this release. This change to esbuild follows a [similar change to TypeScript](https://github.com/microsoft/TypeScript/pull/60225) which will allow this syntax starting with TypeScript 5.7.\n\n* Allow quoted property names in `--define` and `--pure` ([#4008](https://github.com/evanw/esbuild/issues/4008))\n\n    The `define` and `pure` API options now accept identifier expressions containing quoted property names. Previously all identifiers in the identifier expression had to be bare identifiers. This change now makes `--define` and `--pure` consistent with `--global-name`, which already supported quoted property names. For example, the following is now possible:\n\n    ```js\n    // The following code now transforms to \"return true;\\n\"\n    console.log(esbuild.transformSync(\n      `return process.env['SOME-TEST-VAR']`,\n      { define: { 'process.env[\"SOME-TEST-VAR\"]': 'true' } },\n    ))\n    ```\n\n    Note that if you're passing values like this on the command line using esbuild's `--define` flag, then you'll need to know how to escape quote characters for your shell. You may find esbuild's JavaScript API more ergonomic and portable than writing shell code.\n\n* Minify empty `try`/`catch`/`finally` blocks ([#4003](https://github.com/evanw/esbuild/issues/4003))\n\n    With this release, esbuild will now attempt to minify empty `try` blocks:\n\n    ```js\n    // Original code\n    try {} catch { foo() } finally { bar() }\n\n    // Old output (with --minify)\n    try{}catch{foo()}finally{bar()}\n\n    // New output (with --minify)\n    bar();\n    ```\n\n    This can sometimes expose additional minification opportunities.\n\n* Include `entryPoint` metadata for the `copy` loader ([#3985](https://github.com/evanw/esbuild/issues/3985))\n\n    Almost all entry points already include a `entryPoint` field in the `outputs` map in esbuild's build metadata. However, this wasn't the case for the `copy` loader as that loader is a special-case that doesn't behave like other loaders. This release adds the `entryPoint` field in this case.\n\n* Source mappings may now contain `null` entries ([#3310](https://github.com/evanw/esbuild/issues/3310), [#3878](https://github.com/evanw/esbuild/issues/3878))\n\n    With this change, sources that result in an empty source map may now emit a `null` source mapping (i.e. one with a generated position but without a source index or original position). This change improves source map accuracy by fixing a problem where minified code from a source without any source mappings could potentially still be associated with a mapping from another source file earlier in the generated output on the same minified line. It manifests as nonsensical files in source mapped stack traces. Now the `null` mapping \"resets\" the source map so that any lookups into the minified code without any mappings resolves to `null` (which appears as the output file in stack traces) instead of the incorrect source file.\n\n    This change shouldn't affect anything in most situations. I'm only mentioning it in the release notes in case it introduces a bug with source mapping. It's part of a work-in-progress future feature that will let you omit certain unimportant files from the generated source map to reduce source map size.\n\n* Avoid using the parent directory name for determinism ([#3998](https://github.com/evanw/esbuild/issues/3998))\n\n    To make generated code more readable, esbuild includes the name of the source file when generating certain variable names within the file. Specifically bundling a CommonJS file generates a variable to store the lazily-evaluated module initializer. However, if a file is named `index.js` (or with a different extension), esbuild will use the name of the parent directory instead for a better name (since many packages have files all named `index.js` but have unique directory names).\n\n    This is problematic when the bundle entry point is named `index.js` and the parent directory name is non-deterministic (e.g. a temporary directory created by a build script). To avoid non-determinism in esbuild's output, esbuild will now use `index` instead of the parent directory in this case. Specifically this will happen if the parent directory is equal to esbuild's `outbase` API option, which defaults to the [lowest common ancestor](https://en.wikipedia.org/wiki/Lowest_common_ancestor) of all user-specified entry point paths.\n\n* Experimental support for esbuild on NetBSD ([#3974](https://github.com/evanw/esbuild/pull/3974))\n\n    With this release, esbuild now has a published binary executable for [NetBSD](https://www.netbsd.org/) in the [`@esbuild/netbsd-arm64`](https://www.npmjs.com/package/@esbuild/netbsd-arm64) npm package, and esbuild's installer has been modified to attempt to use it when on NetBSD. Hopefully this makes installing esbuild via npm work on NetBSD. This change was contributed by [@bsiegert](https://github.com/bsiegert).\n\n    ⚠️ Note: NetBSD is not one of [Node's supported platforms](https://nodejs.org/api/process.html#process_process_platform), so installing esbuild may or may not work on NetBSD depending on how Node has been patched. This is not a problem with esbuild. ⚠️\n\n## 0.24.0\n\n**_This release deliberately contains backwards-incompatible changes._** To avoid automatically picking up releases like this, you should either be pinning the exact version of `esbuild` in your `package.json` file (recommended) or be using a version range syntax that only accepts patch upgrades such as `^0.23.0` or `~0.23.0`. See npm's documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\n* Drop support for older platforms ([#3902](https://github.com/evanw/esbuild/pull/3902))\n\n    This release drops support for the following operating system:\n\n    * macOS 10.15 Catalina\n\n    This is because the Go programming language dropped support for this operating system version in Go 1.23, and this release updates esbuild from Go 1.22 to Go 1.23. Go 1.23 now requires macOS 11 Big Sur or later.\n\n    Note that this only affects the binary esbuild executables that are published to the esbuild npm package. It's still possible to compile esbuild's source code for these older operating systems. If you need to, you can compile esbuild for yourself using an older version of the Go compiler (before Go version 1.23). That might look something like this:\n\n    ```\n    git clone https://github.com/evanw/esbuild.git\n    cd esbuild\n    go build ./cmd/esbuild\n    ./esbuild --version\n    ```\n\n* Fix class field decorators in TypeScript if `useDefineForClassFields` is `false` ([#3913](https://github.com/evanw/esbuild/issues/3913))\n\n    Setting the `useDefineForClassFields` flag to `false` in `tsconfig.json` means class fields use the legacy TypeScript behavior instead of the standard JavaScript behavior. Specifically they use assign semantics instead of define semantics (e.g. setters are triggered) and fields without an initializer are not initialized at all. However, when this legacy behavior is combined with standard JavaScript decorators, TypeScript switches to always initializing all fields, even those without initializers. Previously esbuild incorrectly continued to omit field initializers for this edge case. These field initializers in this case should now be emitted starting with this release.\n\n* Avoid incorrect cycle warning with `tsconfig.json` multiple inheritance ([#3898](https://github.com/evanw/esbuild/issues/3898))\n\n    TypeScript 5.0 introduced multiple inheritance for `tsconfig.json` files where `extends` can be an array of file paths. Previously esbuild would incorrectly treat files encountered more than once when processing separate subtrees of the multiple inheritance hierarchy as an inheritance cycle. With this release, `tsconfig.json` files containing this edge case should work correctly without generating a warning.\n\n* Handle Yarn Plug'n'Play stack overflow with `tsconfig.json` ([#3915](https://github.com/evanw/esbuild/issues/3915))\n\n    Previously a `tsconfig.json` file that `extends` another file in a package with an `exports` map could cause a stack overflow when Yarn's Plug'n'Play resolution was active. This edge case should work now starting with this release.\n\n* Work around more issues with Deno 1.31+ ([#3917](https://github.com/evanw/esbuild/pull/3917))\n\n    This version of Deno broke the `stdin` and `stdout` properties on command objects for inherited streams, which matters when you run esbuild's Deno module as the entry point (i.e. when `import.meta.main` is `true`). Previously esbuild would crash in Deno 1.31+ if you ran esbuild like that. This should be fixed starting with this release.\n\n    This fix was contributed by [@Joshix-1](https://github.com/Joshix-1).\n\n## 0.23.1\n\n* Allow using the `node:` import prefix with `es*` targets ([#3821](https://github.com/evanw/esbuild/issues/3821))\n\n    The [`node:` prefix on imports](https://nodejs.org/api/esm.html#node-imports) is an alternate way to import built-in node modules. For example, `import fs from \"fs\"` can also be written `import fs from \"node:fs\"`. This only works with certain newer versions of node, so esbuild removes it when you target older versions of node such as with `--target=node14` so that your code still works. With the way esbuild's platform-specific feature compatibility table works, this was added by saying that only newer versions of node support this feature. However, that means that a target such as `--target=node18,es2022` removes the `node:` prefix because none of the `es*` targets are known to support this feature. This release adds the support for the `node:` flag to esbuild's internal compatibility table for `es*` to allow you to use compound targets like this:\n\n    ```js\n    // Original code\n    import fs from 'node:fs'\n    fs.open\n\n    // Old output (with --bundle --format=esm --platform=node --target=node18,es2022)\n    import fs from \"fs\";\n    fs.open;\n\n    // New output (with --bundle --format=esm --platform=node --target=node18,es2022)\n    import fs from \"node:fs\";\n    fs.open;\n    ```\n\n* Fix a panic when using the CLI with invalid build flags if `--analyze` is present ([#3834](https://github.com/evanw/esbuild/issues/3834))\n\n    Previously esbuild's CLI could crash if it was invoked with flags that aren't valid for a \"build\" API call and the `--analyze` flag is present. This was caused by esbuild's internals attempting to add a Go plugin (which is how `--analyze` is implemented) to a null build object. The panic has been fixed in this release.\n\n* Fix incorrect location of certain error messages ([#3845](https://github.com/evanw/esbuild/issues/3845))\n\n    This release fixes a regression that caused certain errors relating to variable declarations to be reported at an incorrect location. The regression was introduced in version 0.18.7 of esbuild.\n\n* Print comments before case clauses in switch statements ([#3838](https://github.com/evanw/esbuild/issues/3838))\n\n    With this release, esbuild will attempt to print comments that come before case clauses in switch statements. This is similar to what esbuild already does for comments inside of certain types of expressions. Note that these types of comments are not printed if minification is enabled (specifically whitespace minification).\n\n* Fix a memory leak with `pluginData` ([#3825](https://github.com/evanw/esbuild/issues/3825))\n\n    With this release, the build context's internal `pluginData` cache will now be cleared when starting a new build. This should fix a leak of memory from plugins that return `pluginData` objects from `onResolve` and/or `onLoad` callbacks.\n\n## 0.23.0\n\n**_This release deliberately contains backwards-incompatible changes._** To avoid automatically picking up releases like this, you should either be pinning the exact version of `esbuild` in your `package.json` file (recommended) or be using a version range syntax that only accepts patch upgrades such as `^0.22.0` or `~0.22.0`. See npm's documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\n* Revert the recent change to avoid bundling dependencies for node ([#3819](https://github.com/evanw/esbuild/issues/3819))\n\n    This release reverts the recent change in version 0.22.0 that made `--packages=external` the default behavior with `--platform=node`.  The default is now back to `--packages=bundle`.\n\n    I've just been made aware that Amazon doesn't pin their dependencies in their \"AWS CDK\" product, which means that whenever esbuild publishes a new release, many people (potentially everyone?) using their SDK around the world instantly starts using it without Amazon checking that it works first. This change in version 0.22.0 happened to break their SDK. I'm amazed that things haven't broken before this point. This revert attempts to avoid these problems for Amazon's customers. Hopefully Amazon will pin their dependencies in the future.\n\n    In addition, this is probably a sign that esbuild is used widely enough that it now needs to switch to a more complicated release model. I may have esbuild use a beta channel model for further development.\n\n* Fix preserving collapsed JSX whitespace ([#3818](https://github.com/evanw/esbuild/issues/3818))\n\n    When transformed, certain whitespace inside JSX elements is ignored completely if it collapses to an empty string. However, the whitespace should only be ignored if the JSX is being transformed, not if it's being preserved. This release fixes a bug where esbuild was previously incorrectly ignoring collapsed whitespace with `--jsx=preserve`. Here is an example:\n\n    ```jsx\n    // Original code\n    <Foo>\n      <Bar />\n    </Foo>\n\n    // Old output (with --jsx=preserve)\n    <Foo><Bar /></Foo>;\n\n    // New output (with --jsx=preserve)\n    <Foo>\n      <Bar />\n    </Foo>;\n    ```\n\n## 0.22.0\n\n**This release deliberately contains backwards-incompatible changes.** To avoid automatically picking up releases like this, you should either be pinning the exact version of `esbuild` in your `package.json` file (recommended) or be using a version range syntax that only accepts patch upgrades such as `^0.21.0` or `~0.21.0`. See npm's documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\n* Omit packages from bundles by default when targeting node ([#1874](https://github.com/evanw/esbuild/issues/1874), [#2830](https://github.com/evanw/esbuild/issues/2830), [#2846](https://github.com/evanw/esbuild/issues/2846), [#2915](https://github.com/evanw/esbuild/issues/2915), [#3145](https://github.com/evanw/esbuild/issues/3145), [#3294](https://github.com/evanw/esbuild/issues/3294), [#3323](https://github.com/evanw/esbuild/issues/3323), [#3582](https://github.com/evanw/esbuild/issues/3582), [#3809](https://github.com/evanw/esbuild/issues/3809), [#3815](https://github.com/evanw/esbuild/issues/3815))\n\n    This breaking change is an experiment. People are commonly confused when using esbuild to bundle code for node (i.e. for `--platform=node`) because some packages may not be intended for bundlers, and may use node-specific features that don't work with a bundler. Even though esbuild's \"getting started\" instructions say to use `--packages=external` to work around this problem, many people don't read the documentation and don't do this, and are then confused when it doesn't work. So arguably this is a bad default behavior for esbuild to have if people keep tripping over this.\n\n    With this release, esbuild will now omit packages from the bundle by default when the platform is `node` (i.e. the previous behavior of `--packages=external` is now the default in this case). _Note that your dependencies must now be present on the file system when your bundle is run._ If you don't want this behavior, you can do `--packages=bundle` to allow packages to be included in the bundle (i.e. the previous default behavior). Note that `--packages=bundle` doesn't mean all packages are bundled, just that packages are allowed to be bundled. You can still exclude individual packages from the bundle using `--external:` even when `--packages=bundle` is present.\n\n    The `--packages=` setting considers all import paths that \"look like\" package imports in the original source code to be package imports. Specifically import paths that don't start with a path segment of `/` or `.` or `..` are considered to be package imports. The only two exceptions to this rule are [subpath imports](https://nodejs.org/api/packages.html#subpath-imports) (which start with a `#` character) and TypeScript path remappings via `paths` and/or `baseUrl` in `tsconfig.json` (which are applied first).\n\n* Drop support for older platforms ([#3802](https://github.com/evanw/esbuild/issues/3802))\n\n    This release drops support for the following operating systems:\n\n    * Windows 7\n    * Windows 8\n    * Windows Server 2008\n    * Windows Server 2012\n\n    This is because the Go programming language dropped support for these operating system versions in [Go 1.21](https://go.dev/doc/go1.21#windows), and this release updates esbuild from Go 1.20 to Go 1.22.\n\n    Note that this only affects the binary esbuild executables that are published to the `esbuild` npm package. It's still possible to compile esbuild's source code for these older operating systems. If you need to, you can compile esbuild for yourself using an older version of the Go compiler (before Go version 1.21). That might look something like this:\n\n    ```\n    git clone https://github.com/evanw/esbuild.git\n    cd esbuild\n    go build ./cmd/esbuild\n    ./esbuild.exe --version\n    ```\n\n    In addition, this release increases the minimum required node version for esbuild's JavaScript API from node 12 to node 18. Node 18 is the oldest version of node that is still being supported (see node's [release schedule](https://nodejs.org/en/about/previous-releases) for more information). This increase is because of an incompatibility between the JavaScript that the Go compiler generates for the `esbuild-wasm` package and versions of node before node 17.4 (specifically the `crypto.getRandomValues` function).\n\n* Update `await using` behavior to match TypeScript\n\n    TypeScript 5.5 subtly changes the way `await using` behaves. This release updates esbuild to match these changes in TypeScript. You can read more about these changes in [microsoft/TypeScript#58624](https://github.com/microsoft/TypeScript/pull/58624).\n\n* Allow `es2024` as a target environment\n\n    The ECMAScript 2024 specification was just approved, so it has been added to esbuild as a possible compilation target. You can read more about the features that it adds here: [https://2ality.com/2024/06/ecmascript-2024.html](https://2ality.com/2024/06/ecmascript-2024.html). The only addition that's relevant for esbuild is the regular expression `/v` flag. With `--target=es2024`, regular expressions that use the `/v` flag will now be passed through untransformed instead of being transformed into a call to `new RegExp`.\n\n* Publish binaries for OpenBSD on 64-bit ARM ([#3665](https://github.com/evanw/esbuild/issues/3665), [#3674](https://github.com/evanw/esbuild/pull/3674))\n\n    With this release, you should now be able to install the `esbuild` npm package in OpenBSD on 64-bit ARM, such as on an Apple device with an M1 chip.\n\n    This was contributed by [@ikmckenz](https://github.com/ikmckenz).\n\n* Publish binaries for WASI (WebAssembly System Interface) preview 1 ([#3300](https://github.com/evanw/esbuild/issues/3300), [#3779](https://github.com/evanw/esbuild/pull/3779))\n\n    The upcoming WASI (WebAssembly System Interface) standard is going to be a way to run WebAssembly outside of a JavaScript host environment. In this scenario you only need a `.wasm` file without any supporting JavaScript code. Instead of JavaScript providing the APIs for the host environment, the WASI standard specifies a \"system interface\" that WebAssembly code can access directly (e.g. for file system access).\n\n    Development versions of the WASI specification are being released using preview numbers. The people behind WASI are currently working on preview 2 but the Go compiler has [released support for preview 1](https://go.dev/blog/wasi), which from what I understand is now considered an unsupported legacy release. However, some people have requested that esbuild publish binary executables that support WASI preview 1 so they can experiment with them.\n\n    This release publishes esbuild precompiled for WASI preview 1 to the `@esbuild/wasi-preview1` package on npm (specifically the file `@esbuild/wasi-preview1/esbuild.wasm`). This binary executable has not been tested and won't be officially supported, as it's for an old preview release of a specification that has since moved in another direction. If it works for you, great! If not, then you'll likely have to wait for the ecosystem to evolve before using esbuild with WASI. For example, it sounds like perhaps WASI preview 1 doesn't include support for opening network sockets so esbuild's local development server is unlikely to work with WASI preview 1.\n\n* Warn about `onResolve` plugins not setting a path ([#3790](https://github.com/evanw/esbuild/issues/3790))\n\n    Plugins that return values from `onResolve` without resolving the path (i.e. without setting either `path` or `external: true`) will now cause a warning. This is because esbuild only uses return values from `onResolve` if it successfully resolves the path, and it's not good for invalid input to be silently ignored.\n\n* Add a new Go API for running the CLI with plugins ([#3539](https://github.com/evanw/esbuild/pull/3539))\n\n    With esbuild's Go API, you can now call `cli.RunWithPlugins(args, plugins)` to pass an array of esbuild plugins to be used during the build process. This allows you to create a CLI that behaves similarly to esbuild's CLI but with additional Go plugins enabled.\n\n    This was contributed by [@edewit](https://github.com/edewit).\n\n## 0.21.5\n\n* Fix `Symbol.metadata` on classes without a class decorator ([#3781](https://github.com/evanw/esbuild/issues/3781))\n\n    This release fixes a bug with esbuild's support for the [decorator metadata proposal](https://github.com/tc39/proposal-decorator-metadata). Previously esbuild only added the `Symbol.metadata` property to decorated classes if there was a decorator on the class element itself. However, the proposal says that the `Symbol.metadata` property should be present on all classes that have any decorators at all, not just those with a decorator on the class element itself.\n\n* Allow unknown import attributes to be used with the `copy` loader ([#3792](https://github.com/evanw/esbuild/issues/3792))\n\n    Import attributes (the `with` keyword on `import` statements) are allowed to alter how that path is loaded. For example, esbuild cannot assume that it knows how to load `./bagel.js` as type `bagel`:\n\n    ```js\n    // This is an error with \"--bundle\" without also using \"--external:./bagel.js\"\n    import tasty from \"./bagel.js\" with { type: \"bagel\" }\n    ```\n\n    Because of that, bundling this code with esbuild is an error unless the file `./bagel.js` is external to the bundle (such as with `--bundle --external:./bagel.js`).\n\n    However, there is an additional case where it's ok for esbuild to allow this: if the file is loaded using the `copy` loader. That's because the `copy` loader behaves similarly to `--external` in that the file is left external to the bundle. The difference is that the `copy` loader copies the file into the output folder and rewrites the import path while `--external` doesn't. That means the following will now work with the `copy` loader (such as with `--bundle --loader:.bagel=copy`):\n\n    ```js\n    // This is no longer an error with \"--bundle\" and \"--loader:.bagel=copy\"\n    import tasty from \"./tasty.bagel\" with { type: \"bagel\" }\n    ```\n\n* Support import attributes with glob-style imports ([#3797](https://github.com/evanw/esbuild/issues/3797))\n\n    This release adds support for import attributes (the `with` option) to glob-style imports (dynamic imports with certain string literal patterns as paths). These imports previously didn't support import attributes due to an oversight. So code like this will now work correctly:\n\n    ```ts\n    async function loadLocale(locale: string): Locale {\n      const data = await import(`./locales/${locale}.data`, { with: { type: 'json' } })\n      return unpackLocale(locale, data)\n    }\n    ```\n\n    Previously this didn't work even though esbuild normally supports forcing the JSON loader using an import attribute. Attempting to do this used to result in the following error:\n\n    ```\n    ✘ [ERROR] No loader is configured for \".data\" files: locales/en-US.data\n\n        example.ts:2:28:\n          2 │   const data = await import(`./locales/${locale}.data`, { with: { type: 'json' } })\n            ╵                             ~~~~~~~~~~~~~~~~~~~~~~~~~~\n    ```\n\n    In addition, this change means plugins can now access the contents of `with` for glob-style imports.\n\n* Support `${configDir}` in `tsconfig.json` files ([#3782](https://github.com/evanw/esbuild/issues/3782))\n\n    This adds support for a new feature from the upcoming TypeScript 5.5 release. The character sequence `${configDir}` is now respected at the start of `baseUrl` and `paths` values, which are used by esbuild during bundling to correctly map import paths to file system paths. This feature lets base `tsconfig.json` files specified via `extends` refer to the directory of the top-level `tsconfig.json` file. Here is an example:\n\n    ```json\n    {\n      \"compilerOptions\": {\n        \"paths\": {\n          \"js/*\": [\"${configDir}/dist/js/*\"]\n        }\n      }\n    }\n    ```\n\n    You can read more in [TypeScript's blog post about their upcoming 5.5 release](https://devblogs.microsoft.com/typescript/announcing-typescript-5-5-rc/#the-configdir-template-variable-for-configuration-files). Note that this feature does not make use of template literals (you need to use `\"${configDir}/dist/js/*\"` not `` `${configDir}/dist/js/*` ``). The syntax for `tsconfig.json` is still just JSON with comments, and JSON syntax does not allow template literals. This feature only recognizes `${configDir}` in strings for certain path-like properties, and only at the beginning of the string.\n\n* Fix internal error with `--supported:object-accessors=false` ([#3794](https://github.com/evanw/esbuild/issues/3794))\n\n    This release fixes a regression in 0.21.0 where some code that was added to esbuild's internal runtime library of helper functions for JavaScript decorators fails to parse when you configure esbuild with `--supported:object-accessors=false`. The reason is that esbuild introduced code that does `{ get [name]() {} }` which uses both the `object-extensions` feature for the `[name]` and the `object-accessors` feature for the `get`, but esbuild was incorrectly only checking for `object-extensions` and not for `object-accessors`. Additional tests have been added to avoid this type of issue in the future. A workaround for this issue in earlier releases is to also add `--supported:object-extensions=false`.\n\n## 0.21.4\n\n* Update support for import assertions and import attributes in node ([#3778](https://github.com/evanw/esbuild/issues/3778))\n\n    Import assertions (the `assert` keyword) have been removed from node starting in v22.0.0. So esbuild will now strip them and generate a warning with `--target=node22` or above:\n\n    ```\n    ▲ [WARNING] The \"assert\" keyword is not supported in the configured target environment (\"node22\") [assert-to-with]\n\n        example.mjs:1:40:\n          1 │ import json from \"esbuild/package.json\" assert { type: \"json\" }\n            │                                         ~~~~~~\n            ╵                                         with\n\n      Did you mean to use \"with\" instead of \"assert\"?\n    ```\n\n    Import attributes (the `with` keyword) have been backported to node 18 starting in v18.20.0. So esbuild will no longer strip them with `--target=node18.N` if `N` is 20 or greater.\n\n* Fix `for await` transform when a label is present\n\n    This release fixes a bug where the `for await` transform, which wraps the loop in a `try` statement, previously failed to also move the loop's label into the `try` statement. This bug only affects code that uses both of these features in combination. Here's an example of some affected code:\n\n    ```js\n    // Original code\n    async function test() {\n      outer: for await (const x of [Promise.resolve([0, 1])]) {\n        for (const y of x) if (y) break outer\n        throw 'fail'\n      }\n    }\n\n    // Old output (with --target=es6)\n    function test() {\n      return __async(this, null, function* () {\n        outer: try {\n          for (var iter = __forAwait([Promise.resolve([0, 1])]), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {\n            const x = temp.value;\n            for (const y of x) if (y) break outer;\n            throw \"fail\";\n          }\n        } catch (temp) {\n          error = [temp];\n        } finally {\n          try {\n            more && (temp = iter.return) && (yield temp.call(iter));\n          } finally {\n            if (error)\n              throw error[0];\n          }\n        }\n      });\n    }\n\n    // New output (with --target=es6)\n    function test() {\n      return __async(this, null, function* () {\n        try {\n          outer: for (var iter = __forAwait([Promise.resolve([0, 1])]), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {\n            const x = temp.value;\n            for (const y of x) if (y) break outer;\n            throw \"fail\";\n          }\n        } catch (temp) {\n          error = [temp];\n        } finally {\n          try {\n            more && (temp = iter.return) && (yield temp.call(iter));\n          } finally {\n            if (error)\n              throw error[0];\n          }\n        }\n      });\n    }\n    ```\n\n* Do additional constant folding after cross-module enum inlining ([#3416](https://github.com/evanw/esbuild/issues/3416), [#3425](https://github.com/evanw/esbuild/issues/3425))\n\n    This release adds a few more cases where esbuild does constant folding after cross-module enum inlining.\n\n    ```ts\n    // Original code: enum.ts\n    export enum Platform {\n      WINDOWS = 'windows',\n      MACOS = 'macos',\n      LINUX = 'linux',\n    }\n\n    // Original code: main.ts\n    import { Platform } from './enum';\n    declare const PLATFORM: string;\n    export function logPlatform() {\n      if (PLATFORM == Platform.WINDOWS) console.log('Windows');\n      else if (PLATFORM == Platform.MACOS) console.log('macOS');\n      else if (PLATFORM == Platform.LINUX) console.log('Linux');\n      else console.log('Other');\n    }\n\n    // Old output (with --bundle '--define:PLATFORM=\"macos\"' --minify --format=esm)\n    function n(){\"windows\"==\"macos\"?console.log(\"Windows\"):\"macos\"==\"macos\"?console.log(\"macOS\"):\"linux\"==\"macos\"?console.log(\"Linux\"):console.log(\"Other\")}export{n as logPlatform};\n\n    // New output (with --bundle '--define:PLATFORM=\"macos\"' --minify --format=esm)\n    function n(){console.log(\"macOS\")}export{n as logPlatform};\n    ```\n\n* Pass import attributes to on-resolve plugins ([#3384](https://github.com/evanw/esbuild/issues/3384), [#3639](https://github.com/evanw/esbuild/issues/3639), [#3646](https://github.com/evanw/esbuild/issues/3646))\n\n    With this release, on-resolve plugins will now have access to the import attributes on the import via the `with` property of the arguments object. This mirrors the `with` property of the arguments object that's already passed to on-load plugins. In addition, you can now pass `with` to the `resolve()` API call which will then forward that value on to all relevant plugins. Here's an example of a plugin that can now be written:\n\n    ```js\n    const examplePlugin = {\n      name: 'Example plugin',\n      setup(build) {\n        build.onResolve({ filter: /.*/ }, args => {\n          if (args.with.type === 'external')\n            return { external: true }\n        })\n      }\n    }\n\n    require('esbuild').build({\n      stdin: {\n        contents: `\n          import foo from \"./foo\" with { type: \"external\" }\n          foo()\n        `,\n      },\n      bundle: true,\n      format: 'esm',\n      write: false,\n      plugins: [examplePlugin],\n    }).then(result => {\n      console.log(result.outputFiles[0].text)\n    })\n    ```\n\n* Formatting support for the `@position-try` rule ([#3773](https://github.com/evanw/esbuild/issues/3773))\n\n    Chrome shipped this new CSS at-rule in version 125 as part of the [CSS anchor positioning API](https://developer.chrome.com/blog/anchor-positioning-api). With this release, esbuild now knows to expect a declaration list inside of the `@position-try` body block and will format it appropriately.\n\n* Always allow internal string import and export aliases ([#3343](https://github.com/evanw/esbuild/issues/3343))\n\n    Import and export names can be string literals in ES2022+. Previously esbuild forbid any usage of these aliases when the target was below ES2022. Starting with this release, esbuild will only forbid such usage when the alias would otherwise end up in output as a string literal. String literal aliases that are only used internally in the bundle and are \"compiled away\" are no longer errors. This makes it possible to use string literal aliases with esbuild's `inject` feature even when the target is earlier than ES2022.\n\n## 0.21.3\n\n* Implement the decorator metadata proposal ([#3760](https://github.com/evanw/esbuild/issues/3760))\n\n    This release implements the [decorator metadata proposal](https://github.com/tc39/proposal-decorator-metadata), which is a sub-proposal of the [decorators proposal](https://github.com/tc39/proposal-decorators). Microsoft shipped the decorators proposal in [TypeScript 5.0](https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/#decorators) and the decorator metadata proposal in [TypeScript 5.2](https://devblogs.microsoft.com/typescript/announcing-typescript-5-2/#decorator-metadata), so it's important that esbuild also supports both of these features. Here's a quick example:\n\n    ```js\n    // Shim the \"Symbol.metadata\" symbol\n    Symbol.metadata ??= Symbol('Symbol.metadata')\n\n    const track = (_, context) => {\n      (context.metadata.names ||= []).push(context.name)\n    }\n\n    class Foo {\n      @track foo = 1\n      @track bar = 2\n    }\n\n    // Prints [\"foo\", \"bar\"]\n    console.log(Foo[Symbol.metadata].names)\n    ```\n\n    **⚠️ WARNING ⚠️**\n\n    This proposal has been marked as \"stage 3\" which means \"recommended for implementation\". However, it's still a work in progress and isn't a part of JavaScript yet, so keep in mind that any code that uses JavaScript decorator metadata may need to be updated as the feature continues to evolve. If/when that happens, I will update esbuild's implementation to match the specification. I will not be supporting old versions of the specification.\n\n* Fix bundled decorators in derived classes ([#3768](https://github.com/evanw/esbuild/issues/3768))\n\n    In certain cases, bundling code that uses decorators in a derived class with a class body that references its own class name could previously generate code that crashes at run-time due to an incorrect variable name. This problem has been fixed. Here is an example of code that was compiled incorrectly before this fix:\n\n    ```js\n    class Foo extends Object {\n      @(x => x) foo() {\n        return Foo\n      }\n    }\n    console.log(new Foo().foo())\n    ```\n\n* Fix `tsconfig.json` files inside symlinked directories ([#3767](https://github.com/evanw/esbuild/issues/3767))\n\n    This release fixes an issue with a scenario involving a `tsconfig.json` file that `extends` another file from within a symlinked directory that uses the `paths` feature. In that case, the implicit `baseURL` value should be based on the real path (i.e. after expanding all symbolic links) instead of the original path. This was already done for other files that esbuild resolves but was not yet done for `tsconfig.json` because it's special-cased (the regular path resolver can't be used because the information inside `tsconfig.json` is involved in path resolution). Note that this fix no longer applies if the `--preserve-symlinks` setting is enabled.\n\n## 0.21.2\n\n* Correct `this` in field and accessor decorators ([#3761](https://github.com/evanw/esbuild/issues/3761))\n\n    This release changes the value of `this` in initializers for class field and accessor decorators from the module-level `this` value to the appropriate `this` value for the decorated element (either the class or the instance). It was previously incorrect due to lack of test coverage. Here's an example of a decorator that doesn't work without this change:\n\n    ```js\n    const dec = () => function() { this.bar = true }\n    class Foo { @dec static foo }\n    console.log(Foo.bar) // Should be \"true\"\n    ```\n\n* Allow `es2023` as a target environment ([#3762](https://github.com/evanw/esbuild/issues/3762))\n\n    TypeScript recently [added `es2023`](https://github.com/microsoft/TypeScript/pull/58140) as a compilation target, so esbuild now supports this too. There is no difference between a target of `es2022` and `es2023` as far as esbuild is concerned since the 2023 edition of JavaScript doesn't introduce any new syntax features.\n\n## 0.21.1\n\n* Fix a regression with `--keep-names` ([#3756](https://github.com/evanw/esbuild/issues/3756))\n\n    The previous release introduced a regression with the `--keep-names` setting and object literals with `get`/`set` accessor methods, in which case the generated code contained syntax errors. This release fixes the regression:\n\n    ```js\n    // Original code\n    x = { get y() {} }\n\n    // Output from version 0.21.0 (with --keep-names)\n    x = { get y: /* @__PURE__ */ __name(function() {\n    }, \"y\") };\n\n    // Output from this version (with --keep-names)\n    x = { get y() {\n    } };\n    ```\n\n## 0.21.0\n\nThis release doesn't contain any deliberately-breaking changes. However, it contains a very complex new feature and while all of esbuild's tests pass, I would not be surprised if an important edge case turns out to be broken. So I'm releasing this as a breaking change release to avoid causing any trouble. As usual, make sure to test your code when you upgrade.\n\n* Implement the JavaScript decorators proposal ([#104](https://github.com/evanw/esbuild/issues/104))\n\n    With this release, esbuild now contains an implementation of the upcoming [JavaScript decorators proposal](https://github.com/tc39/proposal-decorators). This is the same feature that shipped in [TypeScript 5.0](https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/#decorators) and has been highly-requested on esbuild's issue tracker. You can read more about them in that blog post and in this other (now slightly outdated) extensive blog post here: https://2ality.com/2022/10/javascript-decorators.html. Here's a quick example:\n\n    ```js\n    const log = (fn, context) => function() {\n      console.log(`before ${context.name}`)\n      const it = fn.apply(this, arguments)\n      console.log(`after ${context.name}`)\n      return it\n    }\n\n    class Foo {\n      @log static foo() {\n        console.log('in foo')\n      }\n    }\n\n    // Logs \"before foo\", \"in foo\", \"after foo\"\n    Foo.foo()\n    ```\n\n    Note that this feature is different than the existing \"TypeScript experimental decorators\" feature that esbuild already implements. It uses similar syntax but behaves very differently, and the two are not compatible (although it's sometimes possible to write decorators that work with both). TypeScript experimental decorators will still be supported by esbuild going forward as they have been around for a long time, are very widely used, and let you do certain things that are not possible with JavaScript decorators (such as decorating function parameters). By default esbuild will parse and transform JavaScript decorators, but you can tell esbuild to parse and transform TypeScript experimental decorators instead by setting `\"experimentalDecorators\": true` in your `tsconfig.json` file.\n\n    Probably at least half of the work for this feature went into creating a test suite that exercises many of the proposal's edge cases: https://github.com/evanw/decorator-tests. It has given me a reasonable level of confidence that esbuild's initial implementation is acceptable. However, I don't have access to a significant sample of real code that uses JavaScript decorators. If you're currently using JavaScript decorators in a real code base, please try out esbuild's implementation and let me know if anything seems off.\n\n    **⚠️ WARNING ⚠️**\n\n    This proposal has been in the works for a very long time (work began around 10 years ago in 2014) and it is finally getting close to becoming part of the JavaScript language. However, it's still a work in progress and isn't a part of JavaScript yet, so keep in mind that any code that uses JavaScript decorators may need to be updated as the feature continues to evolve. The decorators proposal is pretty close to its final form but it can and likely will undergo some small behavioral adjustments before it ends up becoming a part of the standard. If/when that happens, I will update esbuild's implementation to match the specification. I will not be supporting old versions of the specification.\n\n* Optimize the generated code for private methods\n\n    Previously when lowering private methods for old browsers, esbuild would generate one `WeakSet` for each private method. This mirrors similar logic for generating one `WeakSet` for each private field. Using a separate `WeakMap` for private fields is necessary as their assignment can be observable:\n\n    ```js\n    let it\n    class Bar {\n      constructor() {\n        it = this\n      }\n    }\n    class Foo extends Bar {\n      #x = 1\n      #y = null.foo\n      static check() {\n        console.log(#x in it, #y in it)\n      }\n    }\n    try { new Foo } catch {}\n    Foo.check()\n    ```\n\n    This prints `true false` because this partially-initialized instance has `#x` but not `#y`. In other words, it's not true that all class instances will always have all of their private fields. However, the assignment of private methods to a class instance is not observable. In other words, it's true that all class instances will always have all of their private methods. This means esbuild can lower private methods into code where all methods share a single `WeakSet`, which is smaller, faster, and uses less memory. Other JavaScript processing tools such as the TypeScript compiler already make this optimization. Here's what this change looks like:\n\n    ```js\n    // Original code\n    class Foo {\n      #x() { return this.#x() }\n      #y() { return this.#y() }\n      #z() { return this.#z() }\n    }\n\n    // Old output (--supported:class-private-method=false)\n    var _x, x_fn, _y, y_fn, _z, z_fn;\n    class Foo {\n      constructor() {\n        __privateAdd(this, _x);\n        __privateAdd(this, _y);\n        __privateAdd(this, _z);\n      }\n    }\n    _x = new WeakSet();\n    x_fn = function() {\n      return __privateMethod(this, _x, x_fn).call(this);\n    };\n    _y = new WeakSet();\n    y_fn = function() {\n      return __privateMethod(this, _y, y_fn).call(this);\n    };\n    _z = new WeakSet();\n    z_fn = function() {\n      return __privateMethod(this, _z, z_fn).call(this);\n    };\n\n    // New output (--supported:class-private-method=false)\n    var _Foo_instances, x_fn, y_fn, z_fn;\n    class Foo {\n      constructor() {\n        __privateAdd(this, _Foo_instances);\n      }\n    }\n    _Foo_instances = new WeakSet();\n    x_fn = function() {\n      return __privateMethod(this, _Foo_instances, x_fn).call(this);\n    };\n    y_fn = function() {\n      return __privateMethod(this, _Foo_instances, y_fn).call(this);\n    };\n    z_fn = function() {\n      return __privateMethod(this, _Foo_instances, z_fn).call(this);\n    };\n    ```\n\n* Fix an obscure bug with lowering class members with computed property keys\n\n    When class members that use newer syntax features are transformed for older target environments, they sometimes need to be relocated. However, care must be taken to not reorder any side effects caused by computed property keys. For example, the following code must evaluate `a()` then `b()` then `c()`:\n\n    ```js\n    class Foo {\n      [a()]() {}\n      [b()];\n      static { c() }\n    }\n    ```\n\n    Previously esbuild did this by shifting the computed property key _forward_ to the next spot in the evaluation order. Classes evaluate all computed keys first and then all static class elements, so if the last computed key needs to be shifted, esbuild previously inserted a static block at start of the class body, ensuring it came before all other static class elements:\n\n    ```js\n    var _a;\n    class Foo {\n      constructor() {\n        __publicField(this, _a);\n      }\n      static {\n        _a = b();\n      }\n      [a()]() {\n      }\n      static {\n        c();\n      }\n    }\n    ```\n\n    However, this could cause esbuild to accidentally generate a syntax error if the computed property key contains code that isn't allowed in a static block, such as an `await` expression. With this release, esbuild fixes this problem by shifting the computed property key _backward_ to the previous spot in the evaluation order instead, which may push it into the `extends` clause or even before the class itself:\n\n    ```js\n    // Original code\n    class Foo {\n      [a()]() {}\n      [await b()];\n      static { c() }\n    }\n\n    // Old output (with --supported:class-field=false)\n    var _a;\n    class Foo {\n      constructor() {\n        __publicField(this, _a);\n      }\n      static {\n        _a = await b();\n      }\n      [a()]() {\n      }\n      static {\n        c();\n      }\n    }\n\n    // New output (with --supported:class-field=false)\n    var _a, _b;\n    class Foo {\n      constructor() {\n        __publicField(this, _a);\n      }\n      [(_b = a(), _a = await b(), _b)]() {\n      }\n      static {\n        c();\n      }\n    }\n    ```\n\n* Fix some `--keep-names` edge cases\n\n    The [`NamedEvaluation` syntax-directed operation](https://tc39.es/ecma262/#sec-runtime-semantics-namedevaluation) in the JavaScript specification gives certain anonymous expressions a `name` property depending on where they are in the syntax tree. For example, the following initializers convey a `name` value:\n\n    ```js\n    var foo = function() {}\n    var bar = class {}\n    console.log(foo.name, bar.name)\n    ```\n\n    When you enable esbuild's `--keep-names` setting, esbuild generates additional code to represent this `NamedEvaluation` operation so that the value of the `name` property persists even when the identifiers are renamed (e.g. due to minification).\n\n    However, I recently learned that esbuild's implementation of `NamedEvaluation` is missing a few cases. Specifically esbuild was missing property definitions, class initializers, logical-assignment operators. These cases should now all be handled:\n\n    ```js\n    var obj = { foo: function() {} }\n    class Foo0 { foo = function() {} }\n    class Foo1 { static foo = function() {} }\n    class Foo2 { accessor foo = function() {} }\n    class Foo3 { static accessor foo = function() {} }\n    foo ||= function() {}\n    foo &&= function() {}\n    foo ??= function() {}\n    ```\n\n## 0.20.2\n\n* Support TypeScript experimental decorators on `abstract` class fields ([#3684](https://github.com/evanw/esbuild/issues/3684))\n\n    With this release, you can now use TypeScript experimental decorators on `abstract` class fields. This was silently compiled incorrectly in esbuild 0.19.7 and below, and was an error from esbuild 0.19.8 to esbuild 0.20.1. Code such as the following should now work correctly:\n\n    ```ts\n    // Original code\n    const log = (x: any, y: string) => console.log(y)\n    abstract class Foo { @log abstract foo: string }\n    new class extends Foo { foo = '' }\n\n    // Old output (with --loader=ts --tsconfig-raw={\\\"compilerOptions\\\":{\\\"experimentalDecorators\\\":true}})\n    const log = (x, y) => console.log(y);\n    class Foo {\n    }\n    new class extends Foo {\n      foo = \"\";\n    }();\n\n    // New output (with --loader=ts --tsconfig-raw={\\\"compilerOptions\\\":{\\\"experimentalDecorators\\\":true}})\n    const log = (x, y) => console.log(y);\n    class Foo {\n    }\n    __decorateClass([\n      log\n    ], Foo.prototype, \"foo\", 2);\n    new class extends Foo {\n      foo = \"\";\n    }();\n    ```\n\n* JSON loader now preserves `__proto__` properties ([#3700](https://github.com/evanw/esbuild/issues/3700))\n\n    Copying JSON source code into a JavaScript file will change its meaning if a JSON object contains the `__proto__` key. A literal `__proto__` property in a JavaScript object literal sets the prototype of the object instead of adding a property named `__proto__`, while a literal `__proto__` property in a JSON object literal just adds a property named `__proto__`. With this release, esbuild will now work around this problem by converting JSON to JavaScript with a computed property key in this case:\n\n    ```js\n    // Original code\n    import data from 'data:application/json,{\"__proto__\":{\"fail\":true}}'\n    if (Object.getPrototypeOf(data)?.fail) throw 'fail'\n\n    // Old output (with --bundle)\n    (() => {\n      // <data:application/json,{\"__proto__\":{\"fail\":true}}>\n      var json_proto_fail_true_default = { __proto__: { fail: true } };\n\n      // entry.js\n      if (Object.getPrototypeOf(json_proto_fail_true_default)?.fail)\n        throw \"fail\";\n    })();\n\n    // New output (with --bundle)\n    (() => {\n      // <data:application/json,{\"__proto__\":{\"fail\":true}}>\n      var json_proto_fail_true_default = { [\"__proto__\"]: { fail: true } };\n\n      // example.mjs\n      if (Object.getPrototypeOf(json_proto_fail_true_default)?.fail)\n        throw \"fail\";\n    })();\n    ```\n\n* Improve dead code removal of `switch` statements ([#3659](https://github.com/evanw/esbuild/issues/3659))\n\n    With this release, esbuild will now remove `switch` statements in branches when minifying if they are known to never be evaluated:\n\n    ```js\n    // Original code\n    if (true) foo(); else switch (bar) { case 1: baz(); break }\n\n    // Old output (with --minify)\n    if(1)foo();else switch(bar){case 1:}\n\n    // New output (with --minify)\n    foo();\n    ```\n\n* Empty enums should behave like an object literal ([#3657](https://github.com/evanw/esbuild/issues/3657))\n\n    TypeScript allows you to create an empty enum and add properties to it at run time. While people usually use an empty object literal for this instead of a TypeScript enum, esbuild's enum transform didn't anticipate this use case and generated `undefined` instead of `{}` for an empty enum. With this release, you can now use an empty enum to generate an empty object literal.\n\n    ```ts\n    // Original code\n    enum Foo {}\n\n    // Old output (with --loader=ts)\n    var Foo = /* @__PURE__ */ ((Foo2) => {\n    })(Foo || {});\n\n    // New output (with --loader=ts)\n    var Foo = /* @__PURE__ */ ((Foo2) => {\n      return Foo2;\n    })(Foo || {});\n    ```\n\n* Handle Yarn Plug'n'Play edge case with `tsconfig.json` ([#3698](https://github.com/evanw/esbuild/issues/3698))\n\n    Previously a `tsconfig.json` file that `extends` another file in a package with an `exports` map failed to work when Yarn's Plug'n'Play resolution was active. This edge case should work now starting with this release.\n\n* Work around issues with Deno 1.31+ ([#3682](https://github.com/evanw/esbuild/issues/3682))\n\n    Version 0.20.0 of esbuild changed how the esbuild child process is run in esbuild's API for Deno. Previously it used `Deno.run` but that API is being removed in favor of `Deno.Command`. As part of this change, esbuild is now calling the new `unref` function on esbuild's long-lived child process, which is supposed to allow Deno to exit when your code has finished running even though the child process is still around (previously you had to explicitly call esbuild's `stop()` function to terminate the child process for Deno to be able to exit).\n\n    However, this introduced a problem for Deno's testing API which now fails some tests that use esbuild with `error: Promise resolution is still pending but the event loop has already resolved`. It's unclear to me why this is happening. The call to `unref` was recommended by someone on the Deno core team, and calling Node's equivalent `unref` API has been working fine for esbuild in Node for a long time. It could be that I'm using it incorrectly, or that there's some reference counting and/or garbage collection bug in Deno's internals, or that Deno's `unref` just works differently than Node's `unref`. In any case, it's not good for Deno tests that use esbuild to be failing.\n\n    In this release, I am removing the call to `unref` to fix this issue. This means that you will now have to call esbuild's `stop()` function to allow Deno to exit, just like you did before esbuild version 0.20.0 when this regression was introduced.\n\n    Note: This regression wasn't caught earlier because Deno doesn't seem to fail tests that have outstanding `setTimeout` calls, which esbuild's test harness was using to enforce a maximum test runtime. Adding a `setTimeout` was allowing esbuild's Deno tests to succeed. So this regression doesn't necessarily apply to all people using tests in Deno.\n\n## 0.20.1\n\n* Fix a bug with the CSS nesting transform ([#3648](https://github.com/evanw/esbuild/issues/3648))\n\n    This release fixes a bug with the CSS nesting transform for older browsers where the generated CSS could be incorrect if a selector list contained a pseudo element followed by another selector. The bug was caused by incorrectly mutating the parent rule's selector list when filtering out pseudo elements for the child rules:\n\n    ```css\n    /* Original code */\n    .foo {\n      &:after,\n      & .bar {\n        color: red;\n      }\n    }\n\n    /* Old output (with --supported:nesting=false) */\n    .foo .bar,\n    .foo .bar {\n      color: red;\n    }\n\n    /* New output (with --supported:nesting=false) */\n    .foo:after,\n    .foo .bar {\n      color: red;\n    }\n    ```\n\n* Constant folding for JavaScript inequality operators ([#3645](https://github.com/evanw/esbuild/issues/3645))\n\n    This release introduces constant folding for the `< > <= >=` operators. The minifier will now replace these operators with `true` or `false` when both sides are compile-time numeric or string constants:\n\n    ```js\n    // Original code\n    console.log(1 < 2, '🍕' > '🧀')\n\n    // Old output (with --minify)\n    console.log(1<2,\"🍕\">\"🧀\");\n\n    // New output (with --minify)\n    console.log(!0,!1);\n    ```\n\n* Better handling of `__proto__` edge cases ([#3651](https://github.com/evanw/esbuild/pull/3651))\n\n    JavaScript object literal syntax contains a special case where a non-computed property with a key of `__proto__` sets the prototype of the object. This does not apply to computed properties or to properties that use the shorthand property syntax introduced in ES6. Previously esbuild didn't correctly preserve the \"sets the prototype\" status of properties inside an object literal, meaning a property that sets the prototype could accidentally be transformed into one that doesn't and vice versa. This has now been fixed:\n\n    ```js\n    // Original code\n    function foo(__proto__) {\n      return { __proto__: __proto__ } // Note: sets the prototype\n    }\n    function bar(__proto__, proto) {\n      {\n        let __proto__ = proto\n        return { __proto__ } // Note: doesn't set the prototype\n      }\n    }\n\n    // Old output\n    function foo(__proto__) {\n      return { __proto__ }; // Note: no longer sets the prototype (WRONG)\n    }\n    function bar(__proto__, proto) {\n      {\n        let __proto__2 = proto;\n        return { __proto__: __proto__2 }; // Note: now sets the prototype (WRONG)\n      }\n    }\n\n    // New output\n    function foo(__proto__) {\n      return { __proto__: __proto__ }; // Note: sets the prototype (correct)\n    }\n    function bar(__proto__, proto) {\n      {\n        let __proto__2 = proto;\n        return { [\"__proto__\"]: __proto__2 }; // Note: doesn't set the prototype (correct)\n      }\n    }\n    ```\n\n* Fix cross-platform non-determinism with CSS color space transformations ([#3650](https://github.com/evanw/esbuild/issues/3650))\n\n    The Go compiler takes advantage of \"fused multiply and add\" (FMA) instructions on certain processors which do the operation `x*y + z` without intermediate rounding. This causes esbuild's CSS color space math to differ on different processors (currently `ppc64le` and `s390x`), which breaks esbuild's guarantee of deterministic output. To avoid this, esbuild's color space math now inserts a `float64()` cast around every single math operation. This tells the Go compiler not to use the FMA optimization.\n\n* Fix a crash when resolving a path from a directory that doesn't exist ([#3634](https://github.com/evanw/esbuild/issues/3634))\n\n    This release fixes a regression where esbuild could crash when resolving an absolute path if the source directory for the path resolution operation doesn't exist. While this situation doesn't normally come up, it could come up when running esbuild concurrently with another operation that mutates the file system as esbuild is doing a build (such as using `git` to switch branches). The underlying problem was a regression that was introduced in version 0.18.0.\n\n## 0.20.0\n\n**This release deliberately contains backwards-incompatible changes.** To avoid automatically picking up releases like this, you should either be pinning the exact version of `esbuild` in your `package.json` file (recommended) or be using a version range syntax that only accepts patch upgrades such as `^0.19.0` or `~0.19.0`. See npm's documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\nThis time there is only one breaking change, and it only matters for people using Deno. Deno tests that use esbuild will now fail unless you make the change described below.\n\n* Work around API deprecations in Deno 1.40.x ([#3609](https://github.com/evanw/esbuild/issues/3609), [#3611](https://github.com/evanw/esbuild/pull/3611))\n\n    [Deno 1.40.0](https://deno.com/blog/v1.40) was just released and introduced run-time warnings about certain APIs that esbuild uses. With this release, esbuild will work around these run-time warnings by using newer APIs if they are present and falling back to the original APIs otherwise. This should avoid the warnings without breaking compatibility with older versions of Deno.\n\n    Unfortunately, doing this introduces a breaking change. The newer child process APIs lack a way to synchronously terminate esbuild's child process, so calling `esbuild.stop()` from within a Deno test is no longer sufficient to prevent Deno from failing a test that uses esbuild's API (Deno fails tests that create a child process without killing it before the test ends). To work around this, esbuild's `stop()` function has been changed to return a promise, and you now have to change `esbuild.stop()` to `await esbuild.stop()` in all of your Deno tests.\n\n* Reorder implicit file extensions within `node_modules` ([#3341](https://github.com/evanw/esbuild/issues/3341), [#3608](https://github.com/evanw/esbuild/issues/3608))\n\n    In [version 0.18.0](https://github.com/evanw/esbuild/releases/v0.18.0), esbuild changed the behavior of implicit file extensions within `node_modules` directories (i.e. in published packages) to prefer `.js` over `.ts` even when the `--resolve-extensions=` order prefers `.ts` over `.js` (which it does by default). However, doing that also accidentally made esbuild prefer `.css` over `.ts`, which caused problems for people that published packages containing both TypeScript and CSS in files with the same name.\n\n    With this release, esbuild will reorder TypeScript file extensions immediately after the last JavaScript file extensions in the implicit file extension order instead of putting them at the end of the order. Specifically the default implicit file extension order is `.tsx,.ts,.jsx,.js,.css,.json` which used to become `.jsx,.js,.css,.json,.tsx,.ts` in `node_modules` directories. With this release it will now become `.jsx,.js,.tsx,.ts,.css,.json` instead.\n\n    Why even rewrite the implicit file extension order at all? One reason is because the `.js` file is more likely to behave correctly than the `.ts` file. The behavior of the `.ts` file  may depend on `tsconfig.json` and the `tsconfig.json` file may not even be published, or may use `extends` to refer to a base `tsconfig.json` file that wasn't published. People can get into this situation when they forget to add all `.ts` files to their `.npmignore` file before publishing to npm. Picking `.js` over `.ts` helps make it more likely that resulting bundle will behave correctly.\n\n## 0.19.12\n\n* The \"preserve\" JSX mode now preserves JSX text verbatim ([#3605](https://github.com/evanw/esbuild/issues/3605))\n\n    The [JSX specification](https://facebook.github.io/jsx/) deliberately doesn't specify how JSX text is supposed to be interpreted and there is no canonical way to interpret JSX text. Two most popular interpretations are Babel and TypeScript. Yes [they are different](https://twitter.com/jarredsumner/status/1456118847937781764) (esbuild [deliberately follows TypeScript](https://twitter.com/evanwallace/status/1456122279453208576) by the way).\n\n    Previously esbuild normalized text to the TypeScript interpretation when the \"preserve\" JSX mode is active. However, \"preserve\" should arguably reproduce the original JSX text verbatim so that whatever JSX transform runs after esbuild is free to interpret it however it wants. So with this release, esbuild will now pass JSX text through unmodified:\n\n    ```jsx\n    // Original code\n    let el =\n      <a href={'/'} title='&apos;&quot;'> some text\n        {foo}\n          more text </a>\n\n    // Old output (with --loader=jsx --jsx=preserve)\n    let el = <a href=\"/\" title={`'\"`}>\n      {\" some text\"}\n      {foo}\n      {\"more text \"}\n    </a>;\n\n    // New output (with --loader=jsx --jsx=preserve)\n    let el = <a href={\"/\"} title='&apos;&quot;'> some text\n        {foo}\n          more text </a>;\n    ```\n\n* Allow JSX elements as JSX attribute values\n\n    JSX has an obscure feature where you can use JSX elements in attribute position without surrounding them with `{...}`. It looks like this:\n\n    ```jsx\n    let el = <div data-ab=<><a/><b/></>/>;\n    ```\n\n    I think I originally didn't implement it even though it's part of the [JSX specification](https://facebook.github.io/jsx/) because it previously didn't work in TypeScript (and potentially also in Babel?). However, support for it was [silently added in TypeScript 4.8](https://github.com/microsoft/TypeScript/pull/47994) without me noticing and Babel has also since fixed their [bugs regarding this feature](https://github.com/babel/babel/pull/6006). So I'm adding it to esbuild too now that I know it's widely supported.\n\n    Keep in mind that there is some ongoing discussion about [removing this feature from JSX](https://github.com/facebook/jsx/issues/53). I agree that the syntax seems out of place (it does away with the elegance of \"JSX is basically just XML with `{...}` escapes\" for something arguably harder to read, which doesn't seem like a good trade-off), but it's in the specification and TypeScript and Babel both implement it so I'm going to have esbuild implement it too. However, I reserve the right to remove it from esbuild if it's ever removed from the specification in the future. So use it with caution.\n\n* Fix a bug with TypeScript type parsing ([#3574](https://github.com/evanw/esbuild/issues/3574))\n\n    This release fixes a bug with esbuild's TypeScript parser where a conditional type containing a union type that ends with an infer type that ends with a constraint could fail to parse. This was caused by the \"don't parse a conditional type\" flag not getting passed through the union type parser. Here's an example of valid TypeScript code that previously failed to parse correctly:\n\n    ```ts\n    type InferUnion<T> = T extends { a: infer U extends number } | infer U extends number ? U : never\n    ```\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\n## 0.27.4\n\n* Fix a regression with CSS media queries ([#4395](https://github.com/evanw/esbuild/issues/4395), [#4405](https://github.com/evanw/esbuild/issues/4405), [#4406](https://github.com/evanw/esbuild/issues/4406))\n\n    Version 0.25.11 of esbuild introduced support for parsing media queries. This unintentionally introduced a regression with printing media queries that use the `<media-type> and <media-condition-without-or>` grammar. Specifically, esbuild was failing to wrap an `or` clause with parentheses when inside `<media-condition-without-or>`. This release fixes the regression.\n\n    Here is an example:\n\n    ```css\n    /* Original code */\n    @media only screen and ((min-width: 10px) or (min-height: 10px)) {\n      a { color: red }\n    }\n\n    /* Old output (incorrect) */\n    @media only screen and (min-width: 10px) or (min-height: 10px) {\n      a {\n        color: red;\n      }\n    }\n\n    /* New output (correct) */\n    @media only screen and ((min-width: 10px) or (min-height: 10px)) {\n      a {\n        color: red;\n      }\n    }\n    ```\n\n* Fix an edge case with the `inject` feature ([#4407](https://github.com/evanw/esbuild/issues/4407))\n\n    This release fixes an edge case where esbuild's `inject` feature could not be used with arbitrary module namespace names exported using an `export {} from` statement with bundling disabled and a target environment where arbitrary module namespace names is unsupported.\n\n    With the fix, the following `inject` file:\n\n    ```js\n    import jquery from 'jquery';\n    export { jquery as 'window.jQuery' };\n    ```\n\n    Can now always be rewritten as this without esbuild sometimes incorrectly generating an error:\n\n    ```js\n    export { default as 'window.jQuery' } from 'jquery';\n    ```\n\n* Attempt to improve API handling of huge metafiles ([#4329](https://github.com/evanw/esbuild/issues/4329), [#4415](https://github.com/evanw/esbuild/issues/4415))\n\n    This release contains a few changes that attempt to improve the behavior of esbuild's JavaScript API with huge metafiles (esbuild's name for the build metadata, formatted as a JSON object). The JavaScript API is designed to return the metafile JSON as a JavaScript object in memory, which makes it easy to access from within a JavaScript-based plugin. Multiple people have encountered issues where this API breaks down with a pathologically-large metafile.\n\n    The primary issue is that V8 has an implementation-specific maximum string length, so using the `JSON.parse` API with large enough strings is impossible. This release will now attempt to use a fallback JavaScript-based JSON parser that operates directly on the UTF8-encoded JSON bytes instead of using `JSON.parse` when the JSON metafile is too big to fit in a JavaScript string. The new fallback path has not yet been heavily-tested. The metafile will also now be generated with whitespace removed if the bundle is significantly large, which will reduce the size of the metafile JSON slightly.\n\n    However, hitting this case is potentially a sign that something else is wrong. Ideally you wouldn't be building something so enormous that the build metadata can't even fit inside a JavaScript string. You may want to consider optimizing your project, or breaking up your project into multiple parts that are built independently. Another option could potentially be to use esbuild's command-line API instead of its JavaScript API, which is more efficient (although of course then you can't use JavaScript plugins, so it may not be an option).\n\n## 0.27.3\n\n* Preserve URL fragments in data URLs ([#4370](https://github.com/evanw/esbuild/issues/4370))\n\n    Consider the following HTML, CSS, and SVG:\n\n    * `index.html`:\n\n        ```html\n        <!DOCTYPE html>\n        <html>\n          <head><link rel=\"stylesheet\" href=\"icons.css\"></head>\n          <body><div class=\"triangle\"></div></body>\n        </html>\n        ```\n\n    * `icons.css`:\n\n        ```css\n        .triangle {\n          width: 10px;\n          height: 10px;\n          background: currentColor;\n          clip-path: url(./triangle.svg#x);\n        }\n        ```\n\n    * `triangle.svg`:\n\n        ```xml\n        <svg xmlns=\"http://www.w3.org/2000/svg\">\n          <defs>\n            <clipPath id=\"x\">\n              <path d=\"M0 0H10V10Z\"/>\n            </clipPath>\n          </defs>\n        </svg>\n        ```\n\n    The CSS uses a URL fragment (the `#x`) to reference the `clipPath` element in the SVG file. Previously esbuild's CSS bundler didn't preserve the URL fragment when bundling the SVG using the `dataurl` loader, which broke the bundled CSS. With this release, esbuild will now preserve the URL fragment in the bundled CSS:\n\n    ```css\n    /* icons.css */\n    .triangle {\n      width: 10px;\n      height: 10px;\n      background: currentColor;\n      clip-path: url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\"><defs><clipPath id=\"x\"><path d=\"M0 0H10V10Z\"/></clipPath></defs></svg>#x');\n    }\n    ```\n\n* Parse and print CSS `@scope` rules ([#4322](https://github.com/evanw/esbuild/issues/4322))\n\n    This release includes dedicated support for parsing `@scope` rules in CSS. These rules include optional \"start\" and \"end\" selector lists. One important consequence of this is that the local/global status of names in selector lists is now respected, which improves the correctness of esbuild's support for [CSS modules](https://esbuild.github.io/content-types/#local-css). Minification of selectors inside `@scope` rules has also improved slightly.\n\n    Here's an example:\n\n    ```css\n    /* Original code */\n    @scope (:global(.foo)) to (:local(.bar)) {\n      .bar {\n        color: red;\n      }\n    }\n\n    /* Old output (with --loader=local-css --minify) */\n    @scope (:global(.foo)) to (:local(.bar)){.o{color:red}}\n\n    /* New output (with --loader=local-css --minify) */\n    @scope(.foo)to (.o){.o{color:red}}\n    ```\n\n* Fix a minification bug with lowering of `for await` ([#4378](https://github.com/evanw/esbuild/pull/4378), [#4385](https://github.com/evanw/esbuild/pull/4385))\n\n    This release fixes a bug where the minifier would incorrectly strip the variable in the automatically-generated `catch` clause of lowered `for await` loops. The code that generated the loop previously failed to mark the internal variable references as used.\n\n* Update the Go compiler from v1.25.5 to v1.25.7 ([#4383](https://github.com/evanw/esbuild/issues/4383), [#4388](https://github.com/evanw/esbuild/pull/4388))\n\n    This PR was contributed by [@MikeWillCook](https://github.com/MikeWillCook).\n\n## 0.27.2\n\n* Allow import path specifiers starting with `#/` ([#4361](https://github.com/evanw/esbuild/pull/4361))\n\n    Previously the specification for `package.json` disallowed import path specifiers starting with `#/`, but this restriction [has recently been relaxed](https://github.com/nodejs/node/pull/60864) and support for it is being added across the JavaScript ecosystem. One use case is using it for a wildcard pattern such as mapping `#/*` to `./src/*` (previously you had to use another character such as `#_*` instead, which was more confusing). There is some more context in [nodejs/node#49182](https://github.com/nodejs/node/issues/49182).\n\n    This change was contributed by [@hybrist](https://github.com/hybrist).\n\n* Automatically add the `-webkit-mask` prefix ([#4357](https://github.com/evanw/esbuild/issues/4357), [#4358](https://github.com/evanw/esbuild/issues/4358))\n\n    This release automatically adds the `-webkit-` vendor prefix for the [`mask`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/mask) CSS shorthand property:\n\n    ```css\n    /* Original code */\n    main {\n      mask: url(x.png) center/5rem no-repeat\n    }\n\n    /* Old output (with --target=chrome110) */\n    main {\n      mask: url(x.png) center/5rem no-repeat;\n    }\n\n    /* New output (with --target=chrome110) */\n    main {\n      -webkit-mask: url(x.png) center/5rem no-repeat;\n      mask: url(x.png) center/5rem no-repeat;\n    }\n    ```\n\n    This change was contributed by [@BPJEnnova](https://github.com/BPJEnnova).\n\n* Additional minification of `switch` statements ([#4176](https://github.com/evanw/esbuild/issues/4176), [#4359](https://github.com/evanw/esbuild/issues/4359))\n\n    This release contains additional minification patterns for reducing `switch` statements. Here is an example:\n\n    ```js\n    // Original code\n    switch (x) {\n      case 0:\n        foo()\n        break\n      case 1:\n      default:\n        bar()\n    }\n\n    // Old output (with --minify)\n    switch(x){case 0:foo();break;case 1:default:bar()}\n\n    // New output (with --minify)\n    x===0?foo():bar();\n    ```\n\n* Forbid `using` declarations inside `switch` clauses ([#4323](https://github.com/evanw/esbuild/issues/4323))\n\n    This is a rare change to remove something that was previously possible. The [Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management) proposal introduced `using` declarations. These were previously allowed inside `case` and `default` clauses in `switch` statements. This had well-defined semantics and was already widely implemented (by V8, SpiderMonkey, TypeScript, esbuild, and others). However, it was considered to be too confusing because of how scope works in switch statements, so it has been removed from the specification. This edge case will now be a syntax error. See [tc39/proposal-explicit-resource-management#215](https://github.com/tc39/proposal-explicit-resource-management/issues/215) and [rbuckton/ecma262#14](https://github.com/rbuckton/ecma262/pull/14) for details.\n\n    Here is an example of code that is no longer allowed:\n\n    ```js\n    switch (mode) {\n      case 'read':\n        using readLock = db.read()\n        return readAll(readLock)\n\n      case 'write':\n        using writeLock = db.write()\n        return writeAll(writeLock)\n    }\n    ```\n\n    That code will now have to be modified to look like this instead (note the additional `{` and `}` block statements around each case body):\n\n    ```js\n    switch (mode) {\n      case 'read': {\n        using readLock = db.read()\n        return readAll(readLock)\n      }\n      case 'write': {\n        using writeLock = db.write()\n        return writeAll(writeLock)\n      }\n    }\n    ```\n\n    This is not being released in one of esbuild's breaking change releases since this feature hasn't been finalized yet, and esbuild always tracks the current state of the specification (so esbuild's previous behavior was arguably incorrect).\n\n## 0.27.1\n\n* Fix bundler bug with `var` nested inside `if` ([#4348](https://github.com/evanw/esbuild/issues/4348))\n\n    This release fixes a bug with the bundler that happens when importing an ES module using `require` (which causes it to be wrapped) and there's a top-level `var` inside an `if` statement without being wrapped in a `{ ... }` block (and a few other conditions). The bundling transform needed to hoist these `var` declarations outside of the lazy ES module wrapper for correctness. See the issue for details.\n\n* Fix minifier bug with `for` inside `try` inside label ([#4351](https://github.com/evanw/esbuild/issues/4351))\n\n    This fixes an old regression from [version v0.21.4](https://github.com/evanw/esbuild/releases/v0.21.4). Some code was introduced to move the label inside the `try` statement to address a problem with transforming labeled `for await` loops to avoid the `await` (the transformation involves converting the `for await` loop into a `for` loop and wrapping it in a `try` statement). However, it introduces problems for cross-compiled JVM code that uses all three of these features heavily. This release restricts this transform to only apply to `for` loops that esbuild itself generates internally as part of the `for await` transform. Here is an example of some affected code:\n\n    ```js\n    // Original code\n    d: {\n      e: {\n        try {\n          while (1) { break d }\n        } catch { break e; }\n      }\n    }\n\n    // Old output (with --minify)\n    a:try{e:for(;;)break a}catch{break e}\n\n    // New output (with --minify)\n    a:e:try{for(;;)break a}catch{break e}\n    ```\n\n* Inline IIFEs containing a single expression ([#4354](https://github.com/evanw/esbuild/issues/4354))\n\n    Previously inlining of IIFEs (immediately-invoked function expressions) only worked if the body contained a single `return` statement. Now it should also work if the body contains a single expression statement instead:\n\n    ```js\n    // Original code\n    const foo = () => {\n      const cb = () => {\n        console.log(x())\n      }\n      return cb()\n    }\n\n    // Old output (with --minify)\n    const foo=()=>(()=>{console.log(x())})();\n\n    // New output (with --minify)\n    const foo=()=>{console.log(x())};\n    ```\n\n* The minifier now strips empty `finally` clauses ([#4353](https://github.com/evanw/esbuild/issues/4353))\n\n    This improvement means that `finally` clauses containing dead code can potentially cause the associated `try` statement to be removed from the output entirely in minified builds:\n\n    ```js\n    // Original code\n    function foo(callback) {\n      if (DEBUG) stack.push(callback.name);\n      try {\n        callback();\n      } finally {\n        if (DEBUG) stack.pop();\n      }\n    }\n\n    // Old output (with --minify --define:DEBUG=false)\n    function foo(a){try{a()}finally{}}\n\n    // New output (with --minify --define:DEBUG=false)\n    function foo(a){a()}\n    ```\n\n* Allow tree-shaking of the `Symbol` constructor\n\n    With this release, calling `Symbol` is now considered to be side-effect free when the argument is known to be a primitive value. This means esbuild can now tree-shake module-level symbol variables:\n\n    ```js\n    // Original code\n    const a = Symbol('foo')\n    const b = Symbol(bar)\n\n    // Old output (with --tree-shaking=true)\n    const a = Symbol(\"foo\");\n    const b = Symbol(bar);\n\n    // New output (with --tree-shaking=true)\n    const b = Symbol(bar);\n    ```\n\n## 0.27.0\n\n**This release deliberately contains backwards-incompatible changes.** To avoid automatically picking up releases like this, you should either be pinning the exact version of `esbuild` in your `package.json` file (recommended) or be using a version range syntax that only accepts patch upgrades such as `^0.26.0` or `~0.26.0`. See npm's documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\n* Use `Uint8Array.fromBase64` if available ([#4286](https://github.com/evanw/esbuild/issues/4286))\n\n    With this release, esbuild's `binary` loader will now use the new [`Uint8Array.fromBase64`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/fromBase64) function unless it's unavailable in the configured target environment. If it's unavailable, esbuild's previous code for this will be used as a fallback. Note that this means you may now need to specify `target` when using this feature with Node (for example `--target=node22`) unless you're using Node v25+.\n\n* Update the Go compiler from v1.23.12 to v1.25.4 ([#4208](https://github.com/evanw/esbuild/issues/4208), [#4311](https://github.com/evanw/esbuild/pull/4311))\n\n    This raises the operating system requirements for running esbuild:\n\n    * Linux: now requires a kernel version of 3.2 or later\n    * macOS: now requires macOS 12 (Monterey) or later\n\n## 0.26.0\n\n* Enable trusted publishing ([#4281](https://github.com/evanw/esbuild/issues/4281))\n\n    GitHub and npm are recommending that maintainers for packages such as esbuild switch to [trusted publishing](https://docs.npmjs.com/trusted-publishers). With this release, a VM on GitHub will now build and publish all of esbuild's packages to npm instead of me. In theory.\n\n    Unfortunately there isn't really a way to test that this works other than to do it live. So this release is that live test. Hopefully this release is uneventful and is exactly the same as the previous one (well, except for the green provenance attestation checkmark on npm that happens with trusted publishing).\n\n## 0.25.12\n\n* Fix a minification regression with CSS media queries ([#4315](https://github.com/evanw/esbuild/issues/4315))\n\n    The previous release introduced support for parsing media queries which unintentionally introduced a regression with the removal of duplicate media rules during minification. Specifically the grammar for `@media <media-type> and <media-condition-without-or> { ... }` was missing an equality check for the `<media-condition-without-or>` part, so rules with different suffix clauses in this position would incorrectly compare equal and be deduplicated. This release fixes the regression.\n\n* Update the list of known JavaScript globals ([#4310](https://github.com/evanw/esbuild/issues/4310))\n\n    This release updates esbuild's internal list of known JavaScript globals. These are globals that are known to not have side-effects when the property is accessed. For example, accessing the global `Array` property is considered to be side-effect free but accessing the global `scrollY` property can trigger a layout, which is a side-effect. This is used by esbuild's tree-shaking to safely remove unused code that is known to be side-effect free. This update adds the following global properties:\n\n    From [ES2017](https://tc39.es/ecma262/2017/):\n    - `Atomics`\n    - `SharedArrayBuffer`\n\n    From [ES2020](https://tc39.es/ecma262/2020/):\n    - `BigInt64Array`\n    - `BigUint64Array`\n\n    From [ES2021](https://tc39.es/ecma262/2021/):\n    - `FinalizationRegistry`\n    - `WeakRef`\n\n    From [ES2025](https://tc39.es/ecma262/2025/):\n    - `Float16Array`\n    - `Iterator`\n\n    Note that this does not indicate that constructing any of these objects is side-effect free, just that accessing the identifier is side-effect free. For example, this now allows esbuild to tree-shake classes that extend from `Iterator`:\n\n    ```js\n    // This can now be tree-shaken by esbuild:\n    class ExampleIterator extends Iterator {}\n    ```\n\n* Add support for the new `@view-transition` CSS rule ([#4313](https://github.com/evanw/esbuild/pull/4313))\n\n    With this release, esbuild now has improved support for pretty-printing and minifying the new `@view-transition` rule (which esbuild was previously unaware of):\n\n    ```css\n    /* Original code */\n    @view-transition {\n      navigation: auto;\n      types: check;\n    }\n\n    /* Old output */\n    @view-transition { navigation: auto; types: check; }\n\n    /* New output */\n    @view-transition {\n      navigation: auto;\n      types: check;\n    }\n    ```\n\n    The new view transition feature provides a mechanism for creating animated transitions between documents in a multi-page app. You can read more about view transition rules [here](https://developer.mozilla.org/en-US/docs/Web/CSS/@view-transition).\n\n    This change was contributed by [@yisibl](https://github.com/yisibl).\n\n* Trim CSS rules that will never match\n\n    The CSS minifier will now remove rules whose selectors contain `:is()` and `:where()` as those selectors will never match. These selectors can currently be automatically generated by esbuild when you give esbuild nonsensical input such as the following:\n\n    ```css\n    /* Original code */\n    div:before {\n      color: green;\n      &.foo {\n        color: red;\n      }\n    }\n\n    /* Old output (with --supported:nesting=false --minify) */\n    div:before{color:green}:is().foo{color:red}\n\n    /* New output (with --supported:nesting=false --minify) */\n    div:before{color:green}\n    ```\n\n    This input is nonsensical because CSS nesting is (unfortunately) not supported inside of pseudo-elements such as `:before`. Currently esbuild generates a rule containing `:is()` in this case when you tell esbuild to transform nested CSS into non-nested CSS. I think it's reasonable to do that as it sort of helps explain what's going on (or at least indicates that something is wrong in the output). It shouldn't be present in minified code, however, so this release now strips it out.\n\n## 0.25.11\n\n* Add support for `with { type: 'bytes' }` imports ([#4292](https://github.com/evanw/esbuild/issues/4292))\n\n    The [import bytes](https://github.com/tc39/proposal-import-bytes) proposal has reached stage 2.7 in the TC39 process, which means that although it isn't quite recommended for implementation, it's generally approved and ready for validation. Furthermore it has already been implemented by [Deno](https://docs.deno.com/examples/importing_bytes/) and [Webpack](https://github.com/webpack/webpack/pull/19928). So with this release, esbuild will also add support for this. It behaves exactly the same as esbuild's existing [`binary` loader](https://esbuild.github.io/content-types/#binary). Here's an example:\n\n    ```js\n    import data from './image.png' with { type: 'bytes' }\n    const view = new DataView(data.buffer, 0, 24)\n    const width = view.getInt32(16)\n    const height = view.getInt32(20)\n    console.log('size:', width + '\\xD7' + height)\n    ```\n\n* Lower CSS media query range syntax ([#3748](https://github.com/evanw/esbuild/issues/3748), [#4293](https://github.com/evanw/esbuild/issues/4293))\n\n    With this release, esbuild will now transform CSS media query range syntax into equivalent syntax using `min-`/`max-` prefixes for older browsers. For example, the following CSS:\n\n    ```css\n    @media (640px <= width <= 960px) {\n      main {\n        display: flex;\n      }\n    }\n    ```\n\n    will be transformed like this with a target such as `--target=chrome100` (or more specifically with `--supported:media-range=false` if desired):\n\n    ```css\n    @media (min-width: 640px) and (max-width: 960px) {\n      main {\n        display: flex;\n      }\n    }\n    ```\n\n## 0.25.10\n\n* Fix a panic in a minification edge case ([#4287](https://github.com/evanw/esbuild/issues/4287))\n\n    This release fixes a panic due to a null pointer that could happen when esbuild inlines a doubly-nested identity function and the final result is empty. It was fixed by emitting the value `undefined` in this case, which avoids the panic. This case must be rare since it hasn't come up until now. Here is an example of code that previously triggered the panic (which only happened when minifying):\n\n    ```js\n    function identity(x) { return x }\n    identity({ y: identity(123) })\n    ```\n\n* Fix `@supports` nested inside pseudo-element ([#4265](https://github.com/evanw/esbuild/issues/4265))\n\n    When transforming nested CSS to non-nested CSS, esbuild is supposed to filter out pseudo-elements such as `::placeholder` for correctness. The [CSS nesting specification](https://www.w3.org/TR/css-nesting-1/) says the following:\n\n    > The nesting selector cannot represent pseudo-elements (identical to the behavior of the ':is()' pseudo-class). We’d like to relax this restriction, but need to do so simultaneously for both ':is()' and '&', since they’re intentionally built on the same underlying mechanisms.\n\n    However, it seems like this behavior is different for nested at-rules such as `@supports`, which do work with pseudo-elements. So this release modifies esbuild's behavior to now take that into account:\n\n    ```css\n    /* Original code */\n    ::placeholder {\n      color: red;\n      body & { color: green }\n      @supports (color: blue) { color: blue }\n    }\n\n    /* Old output (with --supported:nesting=false) */\n    ::placeholder {\n      color: red;\n    }\n    body :is() {\n      color: green;\n    }\n    @supports (color: blue) {\n       {\n        color: blue;\n      }\n    }\n\n    /* New output (with --supported:nesting=false) */\n    ::placeholder {\n      color: red;\n    }\n    body :is() {\n      color: green;\n    }\n    @supports (color: blue) {\n      ::placeholder {\n        color: blue;\n      }\n    }\n    ```\n\n## 0.25.9\n\n* Better support building projects that use Yarn on Windows ([#3131](https://github.com/evanw/esbuild/issues/3131), [#3663](https://github.com/evanw/esbuild/issues/3663))\n\n    With this release, you can now use esbuild to bundle projects that use Yarn Plug'n'Play on Windows on drives other than the `C:` drive. The problem was as follows:\n\n    1. Yarn in Plug'n'Play mode on Windows stores its global module cache on the `C:` drive\n    2. Some developers put their projects on the `D:` drive\n    3. Yarn generates relative paths that use `../..` to get from the project directory to the cache directory\n    4. Windows-style paths don't support directory traversal between drives via `..` (so `D:\\..` is just `D:`)\n    5. I didn't have access to a Windows machine for testing this edge case\n\n    Yarn works around this edge case by pretending Windows-style paths beginning with `C:\\` are actually Unix-style paths beginning with `/C:/`, so the `../..` path segments are able to navigate across drives inside Yarn's implementation. This was broken for a long time in esbuild but I finally got access to a Windows machine and was able to debug and fix this edge case. So you should now be able to bundle these projects with esbuild.\n\n* Preserve parentheses around function expressions ([#4252](https://github.com/evanw/esbuild/issues/4252))\n\n    The V8 JavaScript VM uses parentheses around function expressions as an optimization hint to immediately compile the function. Otherwise the function would be lazily-compiled, which has additional overhead if that function is always called immediately as lazy compilation involves parsing the function twice. You can read [V8's blog post about this](https://v8.dev/blog/preparser) for more details.\n\n    Previously esbuild did not represent parentheses around functions in the AST so they were lost during compilation. With this change, esbuild will now preserve parentheses around function expressions when they are present in the original source code. This means these optimization hints will not be lost when bundling with esbuild. In addition, esbuild will now automatically add this optimization hint to immediately-invoked function expressions. Here's an example:\n\n    ```js\n    // Original code\n    const fn0 = () => 0\n    const fn1 = (() => 1)\n    console.log(fn0, function() { return fn1() }())\n\n    // Old output\n    const fn0 = () => 0;\n    const fn1 = () => 1;\n    console.log(fn0, function() {\n      return fn1();\n    }());\n\n    // New output\n    const fn0 = () => 0;\n    const fn1 = (() => 1);\n    console.log(fn0, (function() {\n      return fn1();\n    })());\n    ```\n\n    Note that you do not want to wrap all function expressions in parentheses. This optimization hint should only be used for functions that are called on initial load. Using this hint for functions that are not called on initial load will unnecessarily delay the initial load. Again, see V8's blog post linked above for details.\n\n* Update Go from 1.23.10 to 1.23.12 ([#4257](https://github.com/evanw/esbuild/issues/4257), [#4258](https://github.com/evanw/esbuild/pull/4258))\n\n    This should have no effect on existing code as this version change does not change Go's operating system support. It may remove certain false positive reports (specifically CVE-2025-4674 and CVE-2025-47907) from vulnerability scanners that only detect which version of the Go compiler esbuild uses.\n\n## 0.25.8\n\n* Fix another TypeScript parsing edge case ([#4248](https://github.com/evanw/esbuild/issues/4248))\n\n    This fixes a regression with a change in the previous release that tries to more accurately parse TypeScript arrow functions inside the `?:` operator. The regression specifically involves parsing an arrow function containing a `#private` identifier inside the middle of a `?:` ternary operator inside a class body. This was fixed by propagating private identifier state into the parser clone used to speculatively parse the arrow function body. Here is an example of some affected code:\n\n    ```ts\n    class CachedDict {\n      #has = (a: string) => dict.has(a);\n      has = window\n        ? (word: string): boolean => this.#has(word)\n        : this.#has;\n    }\n    ```\n\n* Fix a regression with the parsing of source phase imports\n\n    The change in the previous release to parse [source phase imports](https://github.com/tc39/proposal-source-phase-imports) failed to properly handle the following cases:\n\n    ```ts\n    import source from 'bar'\n    import source from from 'bar'\n    import source type foo from 'bar'\n    ```\n\n    Parsing for these cases should now be fixed. The first case was incorrectly treated as a syntax error because esbuild was expecting the second case. And the last case was previously allowed but is now forbidden. TypeScript hasn't added this feature yet so it remains to be seen whether the last case will be allowed, but it's safer to disallow it for now. At least Babel doesn't allow the last case when parsing TypeScript, and Babel was involved with the source phase import specification.\n\n## 0.25.7\n\n* Parse and print JavaScript imports with an explicit phase ([#4238](https://github.com/evanw/esbuild/issues/4238))\n\n    This release adds basic syntax support for the `defer` and `source` import phases in JavaScript:\n\n    * `defer`\n\n        This is a [stage 3 proposal](https://github.com/tc39/proposal-defer-import-eval) for an upcoming JavaScript feature that will provide one way to eagerly load but lazily initialize imported modules. The imported module is automatically initialized on first use. Support for this syntax will also be part of the upcoming release of [TypeScript 5.9](https://devblogs.microsoft.com/typescript/announcing-typescript-5-9-beta/#support-for-import-defer). The syntax looks like this:\n\n        ```js\n        import defer * as foo from \"<specifier>\";\n        const bar = await import.defer(\"<specifier>\");\n        ```\n\n        Note that this feature deliberately cannot be used with the syntax `import defer foo from \"<specifier>\"` or `import defer { foo } from \"<specifier>\"`.\n\n    * `source`\n\n        This is a [stage 3 proposal](https://github.com/tc39/proposal-source-phase-imports) for an upcoming JavaScript feature that will provide another way to eagerly load but lazily initialize imported modules. The imported module is returned in an uninitialized state. Support for this syntax may or may not be a part of TypeScript 5.9 (see [this issue](https://github.com/microsoft/TypeScript/issues/61216) for details). The syntax looks like this:\n\n        ```js\n        import source foo from \"<specifier>\";\n        const bar = await import.source(\"<specifier>\");\n        ```\n\n        Note that this feature deliberately cannot be used with the syntax `import defer * as foo from \"<specifier>\"` or `import defer { foo } from \"<specifier>\"`.\n\n    This change only adds support for this syntax. These imports cannot currently be bundled by esbuild. To use these new features with esbuild's bundler, the imported paths must be external to the bundle and the output format must be set to `esm`.\n\n* Support optionally emitting absolute paths instead of relative paths ([#338](https://github.com/evanw/esbuild/issues/338), [#2082](https://github.com/evanw/esbuild/issues/2082), [#3023](https://github.com/evanw/esbuild/issues/3023))\n\n    This release introduces the `--abs-paths=` feature which takes a comma-separated list of situations where esbuild should use absolute paths instead of relative paths. There are currently three supported situations: `code` (comments and string literals), `log` (log message text and location info), and `metafile` (the JSON build metadata).\n\n    Using absolute paths instead of relative paths is not the default behavior because it means that the build results are no longer machine-independent (which means builds are no longer reproducible). Absolute paths can be useful when used with certain terminal emulators that allow you to click on absolute paths in the terminal text and/or when esbuild is being automatically invoked from several different directories within the same script.\n\n* Fix a TypeScript parsing edge case ([#4241](https://github.com/evanw/esbuild/issues/4241))\n\n    This release fixes an edge case with parsing an arrow function in TypeScript with a return type that's in the middle of a `?:` ternary operator. For example:\n\n    ```ts\n    x = a ? (b) : c => d;\n    y = a ? (b) : c => d : e;\n    ```\n\n    The `:` token in the value assigned to `x` pairs with the `?` token, so it's not the start of a return type annotation. However, the first `:` token in the value assigned to `y` is the start of a return type annotation because after parsing the arrow function body, it turns out there's another `:` token that can be used to pair with the `?` token. This case is notable as it's the first TypeScript edge case that esbuild has needed a backtracking parser to parse. It has been addressed by a quick hack (cloning the whole parser) as it's a rare edge case and esbuild doesn't otherwise need a backtracking parser. Hopefully this is sufficient and doesn't cause any issues.\n\n* Inline small constant strings when minifying\n\n    Previously esbuild's minifier didn't inline string constants because strings can be arbitrarily long, and this isn't necessarily a size win if the string is used more than once. Starting with this release, esbuild will now inline string constants when the length of the string is three code units or less. For example:\n\n    ```js\n    // Original code\n    const foo = 'foo'\n    console.log({ [foo]: true })\n\n    // Old output (with --minify --bundle --format=esm)\n    var o=\"foo\";console.log({[o]:!0});\n\n    // New output (with --minify --bundle --format=esm)\n    console.log({foo:!0});\n    ```\n\n    Note that esbuild's constant inlining only happens in very restrictive scenarios to avoid issues with TDZ handling. This change doesn't change when esbuild's constant inlining happens. It only expands the scope of it to include certain string literals in addition to numeric and boolean literals.\n\n## 0.25.6\n\n* Fix a memory leak when `cancel()` is used on a build context ([#4231](https://github.com/evanw/esbuild/issues/4231))\n\n    Calling `rebuild()` followed by `cancel()` in rapid succession could previously leak memory. The bundler uses a producer/consumer model internally, and the resource leak was caused by the consumer being termianted while there were still remaining unreceived results from a producer. To avoid the leak, the consumer now waits for all producers to finish before terminating.\n\n* Support empty `:is()` and `:where()` syntax in CSS ([#4232](https://github.com/evanw/esbuild/issues/4232))\n\n    Previously using these selectors with esbuild would generate a warning. That warning has been removed in this release for these cases.\n\n* Improve tree-shaking of `try` statements in dead code ([#4224](https://github.com/evanw/esbuild/issues/4224))\n\n    With this release, esbuild will now remove certain `try` statements if esbuild considers them to be within dead code (i.e. code that is known to not ever be evaluated). For example:\n\n    ```js\n    // Original code\n    return 'foo'\n    try { return 'bar' } catch {}\n\n    // Old output (with --minify)\n    return\"foo\";try{return\"bar\"}catch{}\n\n    // New output (with --minify)\n    return\"foo\";\n    ```\n\n* Consider negated bigints to have no side effects\n\n    While esbuild currently considers `1`, `-1`, and `1n` to all have no side effects, it didn't previously consider `-1n` to have no side effects. This is because esbuild does constant folding with numbers but not bigints. However, it meant that unused negative bigint constants were not tree-shaken. With this release, esbuild will now consider these expressions to also be side-effect free:\n\n    ```js\n    // Original code\n    let a = 1, b = -1, c = 1n, d = -1n\n\n    // Old output (with --bundle --minify)\n    (()=>{var n=-1n;})();\n\n    // New output (with --bundle --minify)\n    (()=>{})();\n    ```\n\n* Support a configurable delay in watch mode before rebuilding ([#3476](https://github.com/evanw/esbuild/issues/3476), [#4178](https://github.com/evanw/esbuild/issues/4178))\n\n    The `watch()` API now takes a `delay` option that lets you add a delay (in milliseconds) before rebuilding when a change is detected in watch mode. If you use a tool that regenerates multiple source files very slowly, this should make it more likely that esbuild's watch mode won't generate a broken intermediate build before the successful final build. This option is also available via the CLI using the `--watch-delay=` flag.\n\n    This should also help avoid confusion about the `watch()` API's options argument. It was previously empty to allow for future API expansion, which caused some people to think that the documentation was missing. It's no longer empty now that the `watch()` API has an option.\n\n* Allow mixed array for `entryPoints` API option ([#4223](https://github.com/evanw/esbuild/issues/4223))\n\n    The TypeScript type definitions now allow you to pass a mixed array of both string literals and object literals to the `entryPoints` API option, such as `['foo.js', { out: 'lib', in: 'bar.js' }]`. This was always possible to do in JavaScript but the TypeScript type definitions were previously too restrictive.\n\n* Update Go from 1.23.8 to 1.23.10 ([#4204](https://github.com/evanw/esbuild/issues/4204), [#4207](https://github.com/evanw/esbuild/pull/4207))\n\n    This should have no effect on existing code as this version change does not change Go's operating system support. It may remove certain false positive reports (specifically CVE-2025-4673 and CVE-2025-22874) from vulnerability scanners that only detect which version of the Go compiler esbuild uses.\n\n* Experimental support for esbuild on OpenHarmony ([#4212](https://github.com/evanw/esbuild/pull/4212))\n\n    With this release, esbuild now publishes the [`@esbuild/openharmony-arm64`](https://www.npmjs.com/package/@esbuild/openharmony-arm64) npm package for [OpenHarmony](https://en.wikipedia.org/wiki/OpenHarmony). It contains a WebAssembly binary instead of a native binary because Go doesn't currently support OpenHarmony. Node does support it, however, so in theory esbuild should now work on OpenHarmony through WebAssembly.\n\n    This change was contributed by [@hqzing](https://github.com/hqzing).\n\n## 0.25.5\n\n* Fix a regression with `browser` in `package.json` ([#4187](https://github.com/evanw/esbuild/issues/4187))\n\n    The fix to [#4144](https://github.com/evanw/esbuild/issues/4144) in version 0.25.3 introduced a regression that caused `browser` overrides specified in `package.json` to fail to override relative path names that end in a trailing slash. That behavior change affected the `axios@0.30.0` package. This regression has been fixed, and now has test coverage.\n\n* Add support for certain keywords as TypeScript tuple labels ([#4192](https://github.com/evanw/esbuild/issues/4192))\n\n    Previously esbuild could incorrectly fail to parse certain keywords as TypeScript tuple labels that are parsed by the official TypeScript compiler if they were followed by a `?` modifier. These labels included `function`, `import`, `infer`, `new`, `readonly`, and `typeof`. With this release, these keywords will now be parsed correctly. Here's an example of some affected code:\n\n    ```ts\n    type Foo = [\n      value: any,\n      readonly?: boolean, // This is now parsed correctly\n    ]\n    ```\n\n* Add CSS prefixes for the `stretch` sizing value ([#4184](https://github.com/evanw/esbuild/issues/4184))\n\n    This release adds support for prefixing CSS declarations such as `div { width: stretch }`. That CSS is now transformed into this depending on what the `--target=` setting includes:\n\n    ```css\n    div {\n      width: -webkit-fill-available;\n      width: -moz-available;\n      width: stretch;\n    }\n    ```\n\n## 0.25.4\n\n* Add simple support for CORS to esbuild's development server ([#4125](https://github.com/evanw/esbuild/issues/4125))\n\n    Starting with version 0.25.0, esbuild's development server is no longer configured to serve cross-origin requests. This was a deliberate change to prevent any website you visit from accessing your running esbuild development server. However, this change prevented (by design) certain use cases such as \"debugging in production\" by having your production website load code from `localhost` where the esbuild development server is running.\n\n    To enable this use case, esbuild is adding a feature to allow [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) (a.k.a. CORS) for [simple requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS#simple_requests). Specifically, passing your origin to the new `cors` option will now set the `Access-Control-Allow-Origin` response header when the request has a matching `Origin` header. Note that this currently only works for requests that don't send a preflight `OPTIONS` request, as esbuild's development server doesn't currently support `OPTIONS` requests.\n\n    Some examples:\n\n    * **CLI:**\n\n        ```\n        esbuild --servedir=. --cors-origin=https://example.com\n        ```\n\n    * **JS:**\n\n        ```js\n        const ctx = await esbuild.context({})\n        await ctx.serve({\n          servedir: '.',\n          cors: {\n            origin: 'https://example.com',\n          },\n        })\n        ```\n\n    * **Go:**\n\n        ```go\n        ctx, _ := api.Context(api.BuildOptions{})\n        ctx.Serve(api.ServeOptions{\n          Servedir: \".\",\n          CORS: api.CORSOptions{\n            Origin: []string{\"https://example.com\"},\n          },\n        })\n        ```\n\n    The special origin `*` can be used to allow any origin to access esbuild's development server. Note that this means any website you visit will be able to read everything served by esbuild.\n\n* Pass through invalid URLs in source maps unmodified ([#4169](https://github.com/evanw/esbuild/issues/4169))\n\n    This fixes a regression in version 0.25.0 where `sources` in source maps that form invalid URLs were not being passed through to the output. Version 0.25.0 changed the interpretation of `sources` from file paths to URLs, which means that URL parsing can now fail. Previously URLs that couldn't be parsed were replaced with the empty string. With this release, invalid URLs in `sources` should now be passed through unmodified.\n\n* Handle exports named `__proto__` in ES modules ([#4162](https://github.com/evanw/esbuild/issues/4162), [#4163](https://github.com/evanw/esbuild/pull/4163))\n\n    In JavaScript, the special property name `__proto__` sets the prototype when used inside an object literal. Previously esbuild's ESM-to-CommonJS conversion didn't special-case the property name of exports named `__proto__` so the exported getter accidentally became the prototype of the object literal. It's unclear what this affects, if anything, but it's better practice to avoid this by using a computed property name in this case.\n\n    This fix was contributed by [@magic-akari](https://github.com/magic-akari).\n\n## 0.25.3\n\n* Fix lowered `async` arrow functions before `super()` ([#4141](https://github.com/evanw/esbuild/issues/4141), [#4142](https://github.com/evanw/esbuild/pull/4142))\n\n    This change makes it possible to call an `async` arrow function in a constructor before calling `super()` when targeting environments without `async` support, as long as the function body doesn't reference `this`. Here's an example (notice the change from `this` to `null`):\n\n    ```js\n    // Original code\n    class Foo extends Object {\n      constructor() {\n        (async () => await foo())()\n        super()\n      }\n    }\n\n    // Old output (with --target=es2016)\n    class Foo extends Object {\n      constructor() {\n        (() => __async(this, null, function* () {\n          return yield foo();\n        }))();\n        super();\n      }\n    }\n\n    // New output (with --target=es2016)\n    class Foo extends Object {\n      constructor() {\n        (() => __async(null, null, function* () {\n          return yield foo();\n        }))();\n        super();\n      }\n    }\n    ```\n\n    Some background: Arrow functions with the `async` keyword are transformed into generator functions for older language targets such as `--target=es2016`. Since arrow functions capture `this`, the generated code forwards `this` into the body of the generator function. However, JavaScript class syntax forbids using `this` in a constructor before calling `super()`, and this forwarding was problematic since previously happened even when the function body doesn't use `this`. Starting with this release, esbuild will now only forward `this` if it's used within the function body.\n\n    This fix was contributed by [@magic-akari](https://github.com/magic-akari).\n\n* Fix memory leak with `--watch=true` ([#4131](https://github.com/evanw/esbuild/issues/4131), [#4132](https://github.com/evanw/esbuild/pull/4132))\n\n    This release fixes a memory leak with esbuild when `--watch=true` is used instead of `--watch`. Previously using `--watch=true` caused esbuild to continue to use more and more memory for every rebuild, but `--watch=true` should now behave like `--watch` and not leak memory.\n\n    This bug happened because esbuild disables the garbage collector when it's not run as a long-lived process for extra speed, but esbuild's checks for which arguments cause esbuild to be a long-lived process weren't updated for the new `--watch=true` style of boolean command-line flags. This has been an issue since this boolean flag syntax was added in version 0.14.24 in 2022. These checks are unfortunately separate from the regular argument parser because of how esbuild's internals are organized (the command-line interface is exposed as a separate [Go API](https://pkg.go.dev/github.com/evanw/esbuild/pkg/cli) so you can build your own custom esbuild CLI).\n\n    This fix was contributed by [@mxschmitt](https://github.com/mxschmitt).\n\n* More concise output for repeated legal comments ([#4139](https://github.com/evanw/esbuild/issues/4139))\n\n    Some libraries have many files and also use the same legal comment text in all files. Previously esbuild would copy each legal comment to the output file. Starting with this release, legal comments duplicated across separate files will now be grouped in the output file by unique comment content.\n\n* Allow a custom host with the development server ([#4110](https://github.com/evanw/esbuild/issues/4110))\n\n    With this release, you can now use a custom non-IP `host` with esbuild's local development server (either with `--serve=` for the CLI or with the `serve()` call for the API). This was previously possible, but was intentionally broken in [version 0.25.0](https://github.com/evanw/esbuild/releases/v0.25.0) to fix a security issue. This change adds the functionality back except that it's now opt-in and only for a single domain name that you provide.\n\n    For example, if you add a mapping in your `/etc/hosts` file from `local.example.com` to `127.0.0.1` and then use `esbuild --serve=local.example.com:8000`, you will now be able to visit http://local.example.com:8000/ in your browser and successfully connect to esbuild's development server (doing that would previously have been blocked by the browser). This should also work with HTTPS if it's enabled (see esbuild's documentation for how to do that).\n\n* Add a limit to CSS nesting expansion ([#4114](https://github.com/evanw/esbuild/issues/4114))\n\n    With this release, esbuild will now fail with an error if there is too much CSS nesting expansion. This can happen when nested CSS is converted to CSS without nesting for older browsers as expanding CSS nesting is inherently exponential due to the resulting combinatorial explosion. The expansion limit is currently hard-coded and cannot be changed, but is extremely unlikely to trigger for real code. It exists to prevent esbuild from using too much time and/or memory. Here's an example:\n\n    ```css\n    a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{color:red}}}}}}}}}}}}}}}}}}}}\n    ```\n\n    Previously, transforming this file with `--target=safari1` took 5 seconds and generated 40mb of CSS. Trying to do that will now generate the following error instead:\n\n    ```\n    ✘ [ERROR] CSS nesting is causing too much expansion\n\n        example.css:1:60:\n          1 │ a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{color:red}}}}}}}}}}}}}}}}}}}}\n            ╵                                                             ^\n\n      CSS nesting expansion was terminated because a rule was generated with 65536 selectors. This limit\n      exists to prevent esbuild from using too much time and/or memory. Please change your CSS to use\n      fewer levels of nesting.\n    ```\n\n* Fix path resolution edge case ([#4144](https://github.com/evanw/esbuild/issues/4144))\n\n    This fixes an edge case where esbuild's path resolution algorithm could deviate from node's path resolution algorithm. It involves a confusing situation where a directory shares the same file name as a file (but without the file extension). See the linked issue for specific details. This appears to be a case where esbuild is correctly following [node's published resolution algorithm](https://nodejs.org/api/modules.html#all-together) but where node itself is doing something different. Specifically the step `LOAD_AS_FILE` appears to be skipped when the input ends with `..`. This release changes esbuild's behavior for this edge case to match node's behavior.\n\n* Update Go from 1.23.7 to 1.23.8 ([#4133](https://github.com/evanw/esbuild/issues/4133), [#4134](https://github.com/evanw/esbuild/pull/4134))\n\n    This should have no effect on existing code as this version change does not change Go's operating system support. It may remove certain reports from vulnerability scanners that detect which version of the Go compiler esbuild uses, such as for CVE-2025-22871.\n\n    As a reminder, esbuild's development server is intended for development, not for production, so I do not consider most networking-related vulnerabilities in Go to be vulnerabilities in esbuild. Please do not use esbuild's development server in production.\n\n## 0.25.2\n\n* Support flags in regular expressions for the API ([#4121](https://github.com/evanw/esbuild/issues/4121))\n\n    The JavaScript plugin API for esbuild takes JavaScript regular expression objects for the `filter` option. Internally these are translated into Go regular expressions. However, this translation previously ignored the `flags` property of the regular expression. With this release, esbuild will now translate JavaScript regular expression flags into Go regular expression flags. Specifically the JavaScript regular expression `/\\.[jt]sx?$/i` is turned into the Go regular expression `` `(?i)\\.[jt]sx?$` `` internally inside of esbuild's API. This should make it possible to use JavaScript regular expressions with the `i` flag. Note that JavaScript and Go don't support all of the same regular expression features, so this mapping is only approximate.\n\n* Fix node-specific annotations for string literal export names ([#4100](https://github.com/evanw/esbuild/issues/4100))\n\n    When node instantiates a CommonJS module, it scans the AST to look for names to expose via ESM named exports. This is a heuristic that looks for certain patterns such as `exports.NAME = ...` or `module.exports = { ... }`. This behavior is used by esbuild to \"annotate\" CommonJS code that was converted from ESM with the original ESM export names. For example, when converting the file `export let foo, bar` from ESM to CommonJS, esbuild appends this to the end of the file:\n\n    ```js\n    // Annotate the CommonJS export names for ESM import in node:\n    0 && (module.exports = {\n      bar,\n      foo\n    });\n    ```\n\n    However, this feature previously didn't work correctly for export names that are not valid identifiers, which can be constructed using string literal export names. The generated code contained a syntax error. That problem is fixed in this release:\n\n    ```js\n    // Original code\n    let foo\n    export { foo as \"foo!\" }\n\n    // Old output (with --format=cjs --platform=node)\n    ...\n    0 && (module.exports = {\n      \"foo!\"\n    });\n\n    // New output (with --format=cjs --platform=node)\n    ...\n    0 && (module.exports = {\n      \"foo!\": null\n    });\n    ```\n\n* Basic support for index source maps ([#3439](https://github.com/evanw/esbuild/issues/3439), [#4109](https://github.com/evanw/esbuild/pull/4109))\n\n    The source map specification has an optional mode called [index source maps](https://tc39.es/ecma426/#sec-index-source-map) that makes it easier for tools to create an aggregate JavaScript file by concatenating many smaller JavaScript files with source maps, and then generate an aggregate source map by simply providing the original source maps along with some offset information. My understanding is that this is rarely used in practice. I'm only aware of two uses of it in the wild: [ClojureScript](https://clojurescript.org/) and [Turbopack](https://turbo.build/pack/).\n\n    This release provides basic support for indexed source maps. However, the implementation has not been tested on a real app (just on very simple test input). If you are using index source maps in a real app, please try this out and report back if anything isn't working for you.\n\n    Note that this is also not a complete implementation. For example, index source maps technically allows nesting source maps to an arbitrary depth, while esbuild's implementation in this release only supports a single level of nesting. It's unclear whether supporting more than one level of nesting is important or not given the lack of available test cases.\n\n    This feature was contributed by [@clyfish](https://github.com/clyfish).\n\n## 0.25.1\n\n* Fix incorrect paths in inline source maps ([#4070](https://github.com/evanw/esbuild/issues/4070), [#4075](https://github.com/evanw/esbuild/issues/4075), [#4105](https://github.com/evanw/esbuild/issues/4105))\n\n    This fixes a regression from version 0.25.0 where esbuild didn't correctly resolve relative paths contained within source maps in inline `sourceMappingURL` data URLs. The paths were incorrectly being passed through as-is instead of being resolved relative to the source file containing the `sourceMappingURL` comment, which was due to the data URL not being a file URL. This regression has been fixed, and this case now has test coverage.\n\n* Fix invalid generated source maps ([#4080](https://github.com/evanw/esbuild/issues/4080), [#4082](https://github.com/evanw/esbuild/issues/4082), [#4104](https://github.com/evanw/esbuild/issues/4104), [#4107](https://github.com/evanw/esbuild/issues/4107))\n\n    This release fixes a regression from version 0.24.1 that could cause esbuild to generate invalid source maps. Specifically under certain conditions, esbuild could generate a mapping with an out-of-bounds source index. It was introduced by code that attempted to improve esbuild's handling of \"null\" entries in source maps (i.e. mappings with a generated position but no original position). This regression has been fixed.\n\n    This fix was contributed by [@jridgewell](https://github.com/jridgewell).\n\n* Fix a regression with non-file source map paths ([#4078](https://github.com/evanw/esbuild/issues/4078))\n\n    The format of paths in source maps that aren't in the `file` namespace was unintentionally changed in version 0.25.0. Path namespaces is an esbuild-specific concept that is optionally available for plugins to use to distinguish paths from `file` paths and from paths meant for other plugins. Previously the namespace was prepended to the path joined with a `:` character, but version 0.25.0 unintentionally failed to prepend the namespace. The previous behavior has been restored.\n\n* Fix a crash with `switch` optimization ([#4088](https://github.com/evanw/esbuild/issues/4088))\n\n    The new code in the previous release to optimize dead code in switch statements accidentally introduced a crash in the edge case where one or more switch case values include a function expression. This is because esbuild now visits the case values first to determine whether any cases are dead code, and then visits the case bodies once the dead code status is known. That triggered some internal asserts that guard against traversing the AST in an unexpected order. This crash has been fixed by changing esbuild to expect the new traversal ordering. Here's an example of affected code:\n\n    ```js\n    switch (x) {\n      case '':\n        return y.map(z => z.value)\n      case y.map(z => z.key).join(','):\n        return []\n    }\n    ```\n\n* Update Go from 1.23.5 to 1.23.7 ([#4076](https://github.com/evanw/esbuild/issues/4076), [#4077](https://github.com/evanw/esbuild/pull/4077))\n\n    This should have no effect on existing code as this version change does not change Go's operating system support. It may remove certain reports from vulnerability scanners that detect which version of the Go compiler esbuild uses.\n\n    This PR was contributed by [@MikeWillCook](https://github.com/MikeWillCook).\n\n## 0.25.0\n\n**This release deliberately contains backwards-incompatible changes.** To avoid automatically picking up releases like this, you should either be pinning the exact version of `esbuild` in your `package.json` file (recommended) or be using a version range syntax that only accepts patch upgrades such as `^0.24.0` or `~0.24.0`. See npm's documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.\n\n* Restrict access to esbuild's development server ([GHSA-67mh-4wv8-2f99](https://github.com/evanw/esbuild/security/advisories/GHSA-67mh-4wv8-2f99))\n\n    This change addresses esbuild's first security vulnerability report. Previously esbuild set the `Access-Control-Allow-Origin` header to `*` to allow esbuild's development server to be flexible in how it's used for development. However, this allows the websites you visit to make HTTP requests to esbuild's local development server, which gives read-only access to your source code if the website were to fetch your source code's specific URL. You can read more information in [the report](https://github.com/evanw/esbuild/security/advisories/GHSA-67mh-4wv8-2f99).\n\n    Starting with this release, [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) will now be disabled, and requests will now be denied if the host does not match the one provided to `--serve=`. The default host is `0.0.0.0`, which refers to all of the IP addresses that represent the local machine (e.g. both `127.0.0.1` and `192.168.0.1`). If you want to customize anything about esbuild's development server, you can [put a proxy in front of esbuild](https://esbuild.github.io/api/#serve-proxy) and modify the incoming and/or outgoing requests.\n\n    In addition, the `serve()` API call has been changed to return an array of `hosts` instead of a single `host` string. This makes it possible to determine all of the hosts that esbuild's development server will accept.\n\n    Thanks to [@sapphi-red](https://github.com/sapphi-red) for reporting this issue.\n\n* Delete output files when a build fails in watch mode ([#3643](https://github.com/evanw/esbuild/issues/3643))\n\n    It has been requested for esbuild to delete files when a build fails in watch mode. Previously esbuild left the old files in place, which could cause people to not immediately realize that the most recent build failed. With this release, esbuild will now delete all output files if a rebuild fails. Fixing the build error and triggering another rebuild will restore all output files again.\n\n* Fix correctness issues with the CSS nesting transform ([#3620](https://github.com/evanw/esbuild/issues/3620), [#3877](https://github.com/evanw/esbuild/issues/3877), [#3933](https://github.com/evanw/esbuild/issues/3933), [#3997](https://github.com/evanw/esbuild/issues/3997), [#4005](https://github.com/evanw/esbuild/issues/4005), [#4037](https://github.com/evanw/esbuild/pull/4037), [#4038](https://github.com/evanw/esbuild/pull/4038))\n\n    This release fixes the following problems:\n\n    * Naive expansion of CSS nesting can result in an exponential blow-up of generated CSS if each nesting level has multiple selectors. Previously esbuild sometimes collapsed individual nesting levels using `:is()` to limit expansion. However, this collapsing wasn't correct in some cases, so it has been removed to fix correctness issues.\n\n        ```css\n        /* Original code */\n        .parent {\n          > .a,\n          > .b1 > .b2 {\n            color: red;\n          }\n        }\n\n        /* Old output (with --supported:nesting=false) */\n        .parent > :is(.a, .b1 > .b2) {\n          color: red;\n        }\n\n        /* New output (with --supported:nesting=false) */\n        .parent > .a,\n        .parent > .b1 > .b2 {\n          color: red;\n        }\n        ```\n\n        Thanks to [@tim-we](https://github.com/tim-we) for working on a fix.\n\n    * The `&` CSS nesting selector can be repeated multiple times to increase CSS specificity. Previously esbuild ignored this possibility and incorrectly considered `&&` to have the same specificity as `&`. With this release, this should now work correctly:\n\n        ```css\n        /* Original code (color should be red) */\n        div {\n          && { color: red }\n          & { color: blue }\n        }\n\n        /* Old output (with --supported:nesting=false) */\n        div {\n          color: red;\n        }\n        div {\n          color: blue;\n        }\n\n        /* New output (with --supported:nesting=false) */\n        div:is(div) {\n          color: red;\n        }\n        div {\n          color: blue;\n        }\n        ```\n\n        Thanks to [@CPunisher](https://github.com/CPunisher) for working on a fix.\n\n    * Previously transforming nested CSS incorrectly removed leading combinators from within pseudoclass selectors such as `:where()`. This edge case has been fixed and how has test coverage.\n\n        ```css\n        /* Original code */\n        a b:has(> span) {\n          a & {\n            color: green;\n          }\n        }\n\n        /* Old output (with --supported:nesting=false) */\n        a :is(a b:has(span)) {\n          color: green;\n        }\n\n        /* New output (with --supported:nesting=false) */\n        a :is(a b:has(> span)) {\n          color: green;\n        }\n        ```\n\n        This fix was contributed by [@NoremacNergfol](https://github.com/NoremacNergfol).\n\n    * The CSS minifier contains logic to remove the `&` selector when it can be implied, which happens when there is only one and it's the leading token. However, this logic was incorrectly also applied to selector lists inside of pseudo-class selectors such as `:where()`. With this release, the minifier will now avoid applying this logic in this edge case:\n\n        ```css\n        /* Original code */\n        .a {\n          & .b { color: red }\n          :where(& .b) { color: blue }\n        }\n\n        /* Old output (with --minify) */\n        .a{.b{color:red}:where(.b){color:#00f}}\n\n        /* New output (with --minify) */\n        .a{.b{color:red}:where(& .b){color:#00f}}\n        ```\n\n* Fix some correctness issues with source maps ([#1745](https://github.com/evanw/esbuild/issues/1745), [#3183](https://github.com/evanw/esbuild/issues/3183), [#3613](https://github.com/evanw/esbuild/issues/3613), [#3982](https://github.com/evanw/esbuild/issues/3982))\n\n    Previously esbuild incorrectly treated source map path references as file paths instead of as URLs. With this release, esbuild will now treat source map path references as URLs. This fixes the following problems with source maps:\n\n    * File names in `sourceMappingURL` that contained a space previously did not encode the space as `%20`, which resulted in JavaScript tools (including esbuild) failing to read that path back in when consuming the generated output file. This should now be fixed.\n\n    * Absolute URLs in `sourceMappingURL` that use the `file://` scheme previously attempted to read from a folder called `file:`. These URLs should now be recognized and parsed correctly.\n\n    * Entries in the `sources` array in the source map are now treated as URLs instead of file paths. The correct behavior for this is much more clear now that source maps has a [formal specification](https://tc39.es/ecma426/). Many thanks to those who worked on the specification.\n\n* Fix incorrect package for `@esbuild/netbsd-arm64` ([#4018](https://github.com/evanw/esbuild/issues/4018))\n\n    Due to a copy+paste typo, the binary published to `@esbuild/netbsd-arm64` was not actually for `arm64`, and didn't run in that environment. This release should fix running esbuild in that environment (NetBSD on 64-bit ARM). Sorry about the mistake.\n\n* Fix a minification bug with bitwise operators and bigints ([#4065](https://github.com/evanw/esbuild/issues/4065))\n\n    This change removes an incorrect assumption in esbuild that all bitwise operators result in a numeric integer. That assumption was correct up until the introduction of bigints in ES2020, but is no longer correct because almost all bitwise operators now operate on both numbers and bigints. Here's an example of the incorrect minification:\n\n    ```js\n    // Original code\n    if ((a & b) !== 0) found = true\n\n    // Old output (with --minify)\n    a&b&&(found=!0);\n\n    // New output (with --minify)\n    (a&b)!==0&&(found=!0);\n    ```\n\n* Fix esbuild incorrectly rejecting valid TypeScript edge case ([#4027](https://github.com/evanw/esbuild/issues/4027))\n\n    The following TypeScript code is valid:\n\n    ```ts\n    export function open(async?: boolean): void {\n      console.log(async as boolean)\n    }\n    ```\n\n    Before this version, esbuild would fail to parse this with a syntax error as it expected the token sequence `async as ...` to be the start of an async arrow function expression `async as => ...`. This edge case should be parsed correctly by esbuild starting with this release.\n\n* Transform BigInt values into constructor calls when unsupported ([#4049](https://github.com/evanw/esbuild/issues/4049))\n\n    Previously esbuild would refuse to compile the BigInt literals (such as `123n`) if they are unsupported in the configured target environment (such as with `--target=es6`). The rationale was that they cannot be polyfilled effectively because they change the behavior of JavaScript's arithmetic operators and JavaScript doesn't have operator overloading.\n\n    However, this prevents using esbuild with certain libraries that would otherwise work if BigInt literals were ignored, such as with old versions of the [`buffer` library](https://github.com/feross/buffer) before the library fixed support for running in environments without BigInt support. So with this release, esbuild will now turn BigInt literals into BigInt constructor calls (so `123n` becomes `BigInt(123)`) and generate a warning in this case. You can turn off the warning with `--log-override:bigint=silent` or restore the warning to an error with `--log-override:bigint=error` if needed.\n\n* Change how `console` API dropping works ([#4020](https://github.com/evanw/esbuild/issues/4020))\n\n    Previously the `--drop:console` feature replaced all method calls off of the `console` global with `undefined` regardless of how long the property access chain was (so it applied to `console.log()` and `console.log.call(console)` and `console.log.not.a.method()`). However, it was pointed out that this breaks uses of `console.log.bind(console)`. That's also incompatible with Terser's implementation of the feature, which is where this feature originally came from (it does support `bind`). So with this release, using this feature with esbuild will now only replace one level of method call (unless extended by `call` or `apply`) and will replace the method being called with an empty function in complex cases:\n\n    ```js\n    // Original code\n    const x = console.log('x')\n    const y = console.log.call(console, 'y')\n    const z = console.log.bind(console)('z')\n\n    // Old output (with --drop-console)\n    const x = void 0;\n    const y = void 0;\n    const z = (void 0)(\"z\");\n\n    // New output (with --drop-console)\n    const x = void 0;\n    const y = void 0;\n    const z = (() => {\n    }).bind(console)(\"z\");\n    ```\n\n    This should more closely match Terser's existing behavior.\n\n* Allow BigInt literals as `define` values\n\n    With this release, you can now use BigInt literals as define values, such as with `--define:FOO=123n`. Previously trying to do this resulted in a syntax error.\n\n* Fix a bug with resolve extensions in `node_modules` ([#4053](https://github.com/evanw/esbuild/issues/4053))\n\n    The `--resolve-extensions=` option lets you specify the order in which to try resolving implicit file extensions. For complicated reasons, esbuild reorders TypeScript file extensions after JavaScript ones inside of `node_modules` so that JavaScript source code is always preferred to TypeScript source code inside of dependencies. However, this reordering had a bug that could accidentally change the relative order of TypeScript file extensions if one of them was a prefix of the other. That bug has been fixed in this release. You can see the issue for details.\n\n* Better minification of statically-determined `switch` cases ([#4028](https://github.com/evanw/esbuild/issues/4028))\n\n    With this release, esbuild will now try to trim unused code within `switch` statements when the test expression and `case` expressions are primitive literals. This can arise when the test expression is an identifier that is substituted for a primitive literal at compile time. For example:\n\n    ```js\n    // Original code\n    switch (MODE) {\n      case 'dev':\n        installDevToolsConsole()\n        break\n      case 'prod':\n        return\n      default:\n        throw new Error\n    }\n\n    // Old output (with --minify '--define:MODE=\"prod\"')\n    switch(\"prod\"){case\"dev\":installDevToolsConsole();break;case\"prod\":return;default:throw new Error}\n\n    // New output (with --minify '--define:MODE=\"prod\"')\n    return;\n    ```\n\n* Emit `/* @__KEY__ */` for string literals derived from property names ([#4034](https://github.com/evanw/esbuild/issues/4034))\n\n    Property name mangling is an advanced feature that shortens certain property names for better minification (I say \"advanced feature\" because it's very easy to break your code with it). Sometimes you need to store a property name in a string, such as `obj.get('foo')` instead of `obj.foo`. JavaScript minifiers such as esbuild and [Terser](https://terser.org/) have a convention where a `/* @__KEY__ */` comment before the string makes it behave like a property name. So `obj.get(/* @__KEY__ */ 'foo')` allows the contents of the string `'foo'` to be shortened.\n\n    However, esbuild sometimes itself generates string literals containing property names when transforming code, such as when lowering class fields to ES6 or when transforming TypeScript decorators. Previously esbuild didn't generate its own `/* @__KEY__ */` comments in this case, which means that minifying your code by running esbuild again on its own output wouldn't work correctly (this does not affect people that both minify and transform their code in a single step).\n\n    With this release, esbuild will now generate `/* @__KEY__ */` comments for property names in generated string literals. To avoid lots of unnecessary output for people that don't use this advanced feature, the generated comments will only be present when the feature is active. If you want to generate the comments but not actually mangle any property names, you can use a flag that has no effect such as `--reserve-props=.`, which tells esbuild to not mangle any property names (but still activates this feature).\n\n* The `text` loader now strips the UTF-8 BOM if present ([#3935](https://github.com/evanw/esbuild/issues/3935))\n\n    Some software (such as Notepad on Windows) can create text files that start with the three bytes `0xEF 0xBB 0xBF`, which is referred to as the \"byte order mark\". This prefix is intended to be removed before using the text. Previously esbuild's `text` loader included this byte sequence in the string, which turns into a prefix of `\\uFEFF` in a JavaScript string when decoded from UTF-8. With this release, esbuild's `text` loader will now remove these bytes when they occur at the start of the file.\n\n* Omit legal comment output files when empty ([#3670](https://github.com/evanw/esbuild/issues/3670))\n\n    Previously configuring esbuild with `--legal-comment=external` or `--legal-comment=linked` would always generate a `.LEGAL.txt` output file even if it was empty. Starting with this release, esbuild will now only do this if the file will be non-empty. This should result in a more organized output directory in some cases.\n\n* Update Go from 1.23.1 to 1.23.5 ([#4056](https://github.com/evanw/esbuild/issues/4056), [#4057](https://github.com/evanw/esbuild/pull/4057))\n\n    This should have no effect on existing code as this version change does not change Go's operating system support. It may remove certain reports from vulnerability scanners that detect which version of the Go compiler esbuild uses.\n\n    This PR was contributed by [@MikeWillCook](https://github.com/MikeWillCook).\n\n* Allow passing a port of 0 to the development server ([#3692](https://github.com/evanw/esbuild/issues/3692))\n\n    Unix sockets interpret a port of 0 to mean \"pick a random unused port in the [ephemeral port](https://en.wikipedia.org/wiki/Ephemeral_port) range\". However, esbuild's default behavior when the port is not specified is to pick the first unused port starting from 8000 and upward. This is more convenient because port 8000 is typically free, so you can for example restart the development server and reload your app in the browser without needing to change the port in the URL. Since esbuild is written in Go (which does not have optional fields like JavaScript), not specifying the port in Go means it defaults to 0, so previously passing a port of 0 to esbuild caused port 8000 to be picked.\n\n    Starting with this release, passing a port of 0 to esbuild when using the CLI or the JS API will now pass port 0 to the OS, which will pick a random ephemeral port. To make this possible, the `Port` option in the Go API has been changed from `uint16` to `int` (to allow for additional sentinel values) and passing a port of -1 in Go now picks a random port. Both the CLI and JS APIs now remap an explicitly-provided port of 0 into -1 for the internal Go API.\n\n    Another option would have been to change `Port` in Go from `uint16` to `*uint16` (Go's closest equivalent of `number | undefined`). However, that would make the common case of providing an explicit port in Go very awkward as Go doesn't support taking the address of integer constants. This tradeoff isn't worth it as picking a random ephemeral port is a rare use case. So the CLI and JS APIs should now match standard Unix behavior when the port is 0, but you need to use -1 instead with Go API.\n\n* Minification now avoids inlining constants with direct `eval` ([#4055](https://github.com/evanw/esbuild/issues/4055))\n\n    Direct `eval` can be used to introduce a new variable like this:\n\n    ```js\n    const variable = false\n    ;(function () {\n      eval(\"var variable = true\")\n      console.log(variable)\n    })()\n    ```\n\n    Previously esbuild inlined `variable` here (which became `false`), which changed the behavior of the code. This inlining is now avoided, but please keep in mind that direct `eval` breaks many assumptions that JavaScript tools hold about normal code (especially when bundling) and I do not recommend using it. There are usually better alternatives that have a more localized impact on your code. You can read more about this here: https://esbuild.github.io/link/direct-eval/\n\n## 2024\n\nAll esbuild versions published in the year 2024 (versions 0.19.12 through 0.24.2) can be found in [CHANGELOG-2024.md](./CHANGELOG-2024.md).\n\n## 2023\n\nAll esbuild versions published in the year 2023 (versions 0.16.13 through 0.19.11) can be found in [CHANGELOG-2023.md](./CHANGELOG-2023.md).\n\n## 2022\n\nAll esbuild versions published in the year 2022 (versions 0.14.11 through 0.16.12) can be found in [CHANGELOG-2022.md](./CHANGELOG-2022.md).\n\n## 2021\n\nAll esbuild versions published in the year 2021 (versions 0.8.29 through 0.14.10) can be found in [CHANGELOG-2021.md](./CHANGELOG-2021.md).\n\n## 2020\n\nAll esbuild versions published in the year 2020 (versions 0.3.0 through 0.8.28) can be found in [CHANGELOG-2020.md](./CHANGELOG-2020.md).\n"
  },
  {
    "path": "LICENSE.md",
    "content": "MIT License\n\nCopyright (c) 2020 Evan Wallace\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "Makefile",
    "content": "ESBUILD_VERSION = $(shell cat version.txt)\nGO_VERSION = $(shell cat go.version)\n\n# Stash the \"node\" executable because otherwise it breaks on GitHub Actions with Windows when \"PATH\" is changed\nNODE = $(shell which node)\nGO_DIR = $(shell pwd)/go/$(GO_VERSION)/go\nPATH_SEPARATOR = $(shell if uname | grep -qE \"MINGW|WIN32|CYGWIN\"; then echo \";\"; else echo \":\"; fi)\nGO_COMPILER = PATH=\"$(GO_DIR)/bin$(PATH_SEPARATOR)$(PATH)\" GOROOT=\"$(GO_DIR)\" CGO_ENABLED=0\n\n# Strip debug info\nGO_FLAGS += \"-ldflags=-s -w\"\n\n# Avoid embedding the build path in the executable for more reproducible builds\nGO_FLAGS += -trimpath\n\nesbuild: version-go cmd/esbuild/*.go pkg/*/*.go internal/*/*.go go.mod\n\tCGO_ENABLED=0 go build $(GO_FLAGS) ./cmd/esbuild\n\ntest:\n\t@$(MAKE) --no-print-directory -j6 test-common\n\n# These tests are for development\ntest-common: test-go vet-go no-filepath verify-source-map end-to-end-tests js-api-tests plugin-tests register-test node-unref-tests decorator-tests\n\n# These tests are for release (the extra tests are not included in \"test\" because they are pretty slow)\ntest-all:\n\t@$(MAKE) --no-print-directory -j6 test-common test-deno ts-type-tests test-wasm-node test-wasm-browser lib-typecheck test-yarnpnp\n\ncheck-go-version:\n\t@go version | grep -F \" go$(GO_VERSION) \" || (echo 'Please install Go version $(GO_VERSION)' && false)\n\n# Note: Don't add \"-race\" here by default. The Go race detector is currently\n# only supported on the following configurations:\n#\n#   darwin/amd64\n#   darwin/arm64\n#   freebsd/amd64,\n#   linux/amd64\n#   linux/arm64\n#   linux/ppc64le\n#   netbsd/amd64\n#   windows/amd64\n#\n# Also, it isn't necessarily supported on older OS versions even if the OS/CPU\n# combination is supported, such as on macOS 10.9. If you want to test using\n# the race detector, you can manually add it using the ESBUILD_RACE environment\n# variable like this: \"ESBUILD_RACE=-race make test\". Or you can permanently\n# enable it by adding \"export ESBUILD_RACE=-race\" to your shell profile.\ntest-go:\n\tgo test $(ESBUILD_RACE) ./internal/... ./pkg/...\n\nvet-go:\n\tgo vet ./cmd/... ./internal/... ./pkg/...\n\nfmt-go:\n\ttest -z \"$(shell go fmt ./cmd/... ./internal/... ./pkg/... )\"\n\ngo-compiler: go/$(GO_VERSION)\n\n# Build a custom version of the Go compiler that omits buildinfo from the\n# final executable (since there is no command-line option to disable this).\n# This is done in an attempt to avoid poorly-implemented \"security\" tools\n# from breaking esbuild for users solely on the basis of what version of\n# Go esbuild was compiled with.\n#\n# Most (all?) Go-related security tooling effectivelly runs the command\n# \"go version ./esbuild\" and then creates a false-positive report for\n# esbuild for every single CVE in Go's expansive standard library. There is\n# no consideration for whether or not the corresponding API is ever actually\n# used by esbuild. These reports are harmful to users as they prevent users\n# from using esbuild in enterprise environments where these tools are\n# mandatory.\n#\n# These reports are all false-positives because esbuild is not a security\n# boundary. It's just a tool to transform trusted text (your source code)\n# into other text, and a local development server that serves a read-only\n# view of your source code and is not intended for production use.\ngo/$(GO_VERSION):\n\tmkdir -p go/$(GO_VERSION) && cd go/$(GO_VERSION) && curl -LO https://go.dev/dl/go$(GO_VERSION).src.tar.gz && tar xzf go$(GO_VERSION).src.tar.gz\n\tcd go/$(GO_VERSION)/go && grep -qF \"ctxt.buildinfo()\" src/cmd/link/internal/ld/main.go # Make sure this call is still there\n\tcd go/$(GO_VERSION)/go/src/cmd/link/internal/ld && sed \"s/ctxt.buildinfo/\\\\/\\\\/ctxt.buildinfo/\" main.go > temp && mv temp main.go\n\tcd go/$(GO_VERSION)/go/src && if uname | grep -qE \"MINGW|WIN32|CYGWIN\"; then ./make.bat; else ./make.bash; fi\n\nno-filepath:\n\t@! grep --color --include '*.go' -r '\"path/filepath\"' cmd internal pkg || ( \\\n\t\techo 'error: Use of \"path/filepath\" is disallowed. See https://golang.org/issue/43768' && false)\n\n# This uses \"env -i\" to run in a clean environment with no environment\n# variables. It then adds some environment variables back as needed.\n# This is a hack to avoid a problem with the WebAssembly support in Go\n# 1.17.2, which will crash when run in an environment with over 4096\n# bytes of environment variable data such as GitHub Actions.\ntest-wasm-node: esbuild\n\tenv -i $(shell go env) PATH=\"$(shell go env GOROOT)/lib/wasm:$(PATH)\" GOOS=js GOARCH=wasm go test ./internal/...\n\tnode scripts/wasm-tests.js\n\ntest-wasm-browser: platform-wasm | scripts/browser/node_modules\n\tcd scripts/browser && node browser-tests.js\n\ntest-deno: esbuild platform-deno\n\tESBUILD_BINARY_PATH=\"$(shell pwd)/esbuild\" deno test --allow-run --allow-env --allow-net --allow-read --allow-write --no-check scripts/deno-tests.js\n\t@echo '✅ deno tests passed' # I couldn't find a Deno API for telling when tests have failed, so I'm doing this here instead\n\tESBUILD_BINARY_PATH=\"$(shell pwd)/esbuild\" deno eval 'import { transform, stop } from \"file://$(shell pwd)/deno/mod.js\"; console.log((await transform(\"1+2\")).code); stop()' | grep \"1 + 2;\"\n\tESBUILD_BINARY_PATH=\"$(shell pwd)/esbuild\" deno eval 'import { transform, stop } from \"file://$(shell pwd)/deno/wasm.js\"; console.log((await transform(\"1+2\")).code); stop()' | grep \"1 + 2;\"\n\tESBUILD_BINARY_PATH=\"$(shell pwd)/esbuild\" deno run -A './deno/mod.js' # See: https://github.com/evanw/esbuild/pull/3917\n\ntest-deno-windows: esbuild platform-deno\n\tESBUILD_BINARY_PATH=./esbuild.exe deno test --allow-run --allow-env --allow-net --allow-read --allow-write --no-check scripts/deno-tests.js\n\nregister-test: version-go | scripts/node_modules\n\tnode scripts/esbuild.js npm/esbuild/package.json --version\n\tnode scripts/register-test.js\n\nverify-source-map: version-go | scripts/node_modules\n\tnode scripts/esbuild.js npm/esbuild/package.json --version\n\tnode scripts/verify-source-map.js\n\nend-to-end-tests: version-go\n\tnode scripts/esbuild.js npm/esbuild/package.json --version\n\tnode scripts/end-to-end-tests.js\n\n# Note: The TypeScript source code for these tests was copied from the repo\n# https://github.com/evanw/decorator-tests, which is the official location of\n# the source code for these tests. Any changes to these tests should be made\n# there first and then copied here afterward.\ndecorator-tests: esbuild\n\t./esbuild scripts/decorator-tests.ts --target=es2022 --outfile=scripts/decorator-tests.js\n\tnode scripts/decorator-tests.js\n\tnode scripts/decorator-tests.js | grep -q 'All checks passed'\n\tgit diff --exit-code scripts/decorator-tests.js\n\njs-api-tests: version-go\n\tnode scripts/esbuild.js npm/esbuild/package.json --version\n\tnode scripts/js-api-tests.js\n\nplugin-tests: version-go\n\tnode scripts/plugin-tests.js\n\nts-type-tests: | scripts/node_modules\n\tnode scripts/ts-type-tests.js\n\nrequire/old-ts/node_modules:\n\tcd require/old-ts && npm ci\n\ntest-old-ts: platform-neutral | require/old-ts/node_modules\n\trm -fr scripts/.test-old-ts && mkdir scripts/.test-old-ts\n\tcp `find npm/esbuild -name '*.d.ts'` scripts/.test-old-ts\n\tcd scripts/.test-old-ts && ../../require/old-ts/node_modules/.bin/tsc *.d.ts\n\trm -fr scripts/.test-old-ts\n\nnode-unref-tests: | scripts/node_modules\n\tnode scripts/node-unref-tests.js\n\nlib-typecheck: lib-typecheck-node lib-typecheck-node-nolib lib-typecheck-deno\n\nlib-typecheck-node: | lib/node_modules\n\tcd lib && node_modules/.bin/tsc -noEmit -p tsconfig.json\n\nlib-typecheck-node-nolib: | lib/node_modules\n\tcd lib && node_modules/.bin/tsc -noEmit -p tsconfig-nolib.json\n\nlib-typecheck-deno: lib/deno/lib.deno.d.ts | lib/node_modules\n\tcd lib && node_modules/.bin/tsc -noEmit -p tsconfig-deno.json\n\nlib/deno/lib.deno.d.ts:\n\tdeno types > lib/deno/lib.deno.d.ts\n\n# End-to-end tests\ntest-e2e: test-e2e-npm test-e2e-pnpm test-e2e-yarn test-e2e-yarn-berry test-e2e-deno\n\ntest-e2e-npm:\n\t# Test normal install\n\trm -fr e2e-npm && mkdir e2e-npm && cd e2e-npm && echo {} > package.json && npm i esbuild\n\tcd e2e-npm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\t# Test CI reinstall\n\tcd e2e-npm && npm ci\n\tcd e2e-npm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\t# Test rebuild\n\tcd e2e-npm && npm rebuild && npm rebuild\n\tcd e2e-npm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\n\t# Test install without scripts\n\trm -fr e2e-npm && mkdir e2e-npm && cd e2e-npm && echo {} > package.json && npm i --ignore-scripts esbuild\n\tcd e2e-npm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\t# Test CI reinstall\n\tcd e2e-npm && npm ci\n\tcd e2e-npm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\t# Test rebuild\n\tcd e2e-npm && npm rebuild && npm rebuild\n\tcd e2e-npm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\n\t# Test install without optional dependencies\n\trm -fr e2e-npm && mkdir e2e-npm && cd e2e-npm && echo {} > package.json && npm i --no-optional esbuild\n\tcd e2e-npm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\t# Test CI reinstall\n\tcd e2e-npm && npm ci\n\tcd e2e-npm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\t# Test rebuild\n\tcd e2e-npm && npm rebuild && npm rebuild\n\tcd e2e-npm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\n\t# Clean up\n\trm -fr e2e-npm\n\ntest-e2e-pnpm:\n\t# Test normal install\n\trm -fr e2e-pnpm && mkdir e2e-pnpm && cd e2e-pnpm && echo {} > package.json && pnpm i esbuild\n\tcd e2e-pnpm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\t# Test CI reinstall\n\tcd e2e-pnpm && pnpm i --frozen-lockfile\n\tcd e2e-pnpm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\t# Test rebuild\n\tcd e2e-pnpm && pnpm rebuild && pnpm rebuild\n\tcd e2e-pnpm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\n\t# Test install without scripts\n\trm -fr e2e-pnpm && mkdir e2e-pnpm && cd e2e-pnpm && echo {} > package.json && pnpm i --ignore-scripts esbuild\n\tcd e2e-pnpm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\t# Test CI reinstall\n\tcd e2e-pnpm && pnpm i --frozen-lockfile\n\tcd e2e-pnpm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\t# Test rebuild\n\tcd e2e-pnpm && pnpm rebuild && pnpm rebuild\n\tcd e2e-pnpm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\n\t# Test install without optional dependencies\n\trm -fr e2e-pnpm && mkdir e2e-pnpm && cd e2e-pnpm && echo {} > package.json && pnpm i --no-optional esbuild\n\tcd e2e-pnpm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\t# Test CI reinstall\n\tcd e2e-pnpm && pnpm i --frozen-lockfile\n\tcd e2e-pnpm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\t# Test rebuild\n\tcd e2e-pnpm && pnpm rebuild && pnpm rebuild\n\tcd e2e-pnpm && echo \"1+2\" | node_modules/.bin/esbuild | grep \"1 + 2;\" && node -p \"require('esbuild').transformSync('1+2').code\" | grep \"1 + 2;\"\n\n\t# Clean up\n\trm -fr e2e-pnpm\n\ntest-e2e-yarn:\n\t# Test normal install\n\trm -fr e2e-yarn && mkdir e2e-yarn && cd e2e-yarn && echo {} > package.json && touch yarn.lock && yarn set version classic && yarn add esbuild\n\tcd e2e-yarn && echo \"1+2\" | yarn esbuild && yarn node -p \"require('esbuild').transformSync('1+2').code\"\n\t# Test CI reinstall\n\tcd e2e-yarn && rm -fr node_modules && yarn install --immutable\n\tcd e2e-yarn && echo \"1+2\" | yarn esbuild && yarn node -p \"require('esbuild').transformSync('1+2').code\"\n\n\t# Test install without scripts\n\trm -fr e2e-yarn && mkdir e2e-yarn && cd e2e-yarn && echo {} > package.json && touch yarn.lock && echo 'enableScripts: false' > .yarnrc.yml && yarn set version classic && yarn add esbuild\n\tcd e2e-yarn && echo \"1+2\" | yarn esbuild && yarn node -p \"require('esbuild').transformSync('1+2').code\"\n\t# Test CI reinstall\n\tcd e2e-yarn && rm -fr node_modules && yarn install --immutable\n\tcd e2e-yarn && echo \"1+2\" | yarn esbuild && yarn node -p \"require('esbuild').transformSync('1+2').code\"\n\n\t# Test install without optional dependencies\n\trm -fr e2e-yarn && mkdir e2e-yarn && cd e2e-yarn && echo {} > package.json && touch yarn.lock && yarn set version classic && yarn add esbuild\n\tcd e2e-yarn && echo \"1+2\" | yarn esbuild && yarn node -p \"require('esbuild').transformSync('1+2').code\"\n\t# Test CI reinstall\n\tcd e2e-yarn && rm -fr node_modules && yarn install --immutable --ignore-optional\n\tcd e2e-yarn && echo \"1+2\" | yarn esbuild && yarn node -p \"require('esbuild').transformSync('1+2').code\"\n\n\t# Clean up\n\trm -fr e2e-yarn\n\ntest-e2e-yarn-berry:\n\t# Test normal install\n\trm -fr e2e-yb && mkdir e2e-yb && cd e2e-yb && echo {} > package.json && touch yarn.lock && yarn set version berry && yarn add esbuild\n\tcd e2e-yb && echo \"1+2\" | yarn esbuild && yarn node -p \"require('esbuild').transformSync('1+2').code\"\n\t# Test CI reinstall\n\tcd e2e-yb && yarn install --immutable\n\tcd e2e-yb && echo \"1+2\" | yarn esbuild && yarn node -p \"require('esbuild').transformSync('1+2').code\"\n\t# Test rebuild\n\tcd e2e-yb && yarn rebuild && yarn rebuild\n\tcd e2e-yb && echo \"1+2\" | yarn esbuild && yarn node -p \"require('esbuild').transformSync('1+2').code\"\n\n\t# Test install without scripts\n\trm -fr e2e-yb && mkdir e2e-yb && cd e2e-yb && echo {} > package.json && touch yarn.lock && echo 'enableScripts: false' > .yarnrc.yml && yarn set version berry && yarn add esbuild\n\tcd e2e-yb && echo \"1+2\" | yarn esbuild && yarn node -p \"require('esbuild').transformSync('1+2').code\"\n\t# Test CI reinstall\n\tcd e2e-yb && yarn install --immutable\n\tcd e2e-yb && echo \"1+2\" | yarn esbuild && yarn node -p \"require('esbuild').transformSync('1+2').code\"\n\t# Test rebuild\n\tcd e2e-yb && yarn rebuild && yarn rebuild\n\tcd e2e-yb && echo \"1+2\" | yarn esbuild && yarn node -p \"require('esbuild').transformSync('1+2').code\"\n\n\t# Test install without optional dependencies\n\trm -fr e2e-yb && mkdir e2e-yb && cd e2e-yb && echo {} > package.json && touch yarn.lock && yarn set version berry && yarn add --no-optional esbuild\n\tcd e2e-yb && echo \"1+2\" | yarn esbuild && yarn node -p \"require('esbuild').transformSync('1+2').code\"\n\t# Test CI reinstall\n\tcd e2e-yb && yarn install --immutable\n\tcd e2e-yb && echo \"1+2\" | yarn esbuild && yarn node -p \"require('esbuild').transformSync('1+2').code\"\n\t# Test rebuild\n\tcd e2e-yb && yarn rebuild && yarn rebuild\n\tcd e2e-yb && echo \"1+2\" | yarn esbuild && yarn node -p \"require('esbuild').transformSync('1+2').code\"\n\n\t# Clean up\n\trm -fr e2e-yb\n\ntest-e2e-deno:\n\tdeno eval 'import { transform, stop } from \"https://deno.land/x/esbuild@v$(ESBUILD_VERSION)/mod.js\"; console.log((await transform(\"1+2\")).code); stop()' | grep \"1 + 2;\"\n\tdeno eval 'import { transform, stop } from \"https://deno.land/x/esbuild@v$(ESBUILD_VERSION)/wasm.js\"; console.log((await transform(\"1+2\")).code); stop()' | grep \"1 + 2;\"\n\ntest-yarnpnp: platform-wasm\n\tnode scripts/test-yarnpnp.js\n\n# Note: This used to only be rebuilt when \"version.txt\" was newer than\n# \"cmd/esbuild/version.go\", but that caused the publishing script to publish\n# invalid builds in the case when the publishing script failed once, the change\n# to \"cmd/esbuild/version.go\" was reverted, and then the publishing script was\n# run again, since in that case \"cmd/esbuild/version.go\" has a later mtime than\n# \"version.txt\" but is still outdated.\n#\n# To avoid this problem, we now always run this step regardless of mtime status.\n# This step still avoids writing to \"cmd/esbuild/version.go\" if it already has\n# the correct contents, so it won't unnecessarily invalidate anything that uses\n# \"cmd/esbuild/version.go\" as a dependency.\nversion-go:\n\tnode scripts/esbuild.js --update-version-go\n\nplatform-all: go-compiler\n\t@$(MAKE) --no-print-directory -j4 \\\n\t\tplatform-aix-ppc64 \\\n\t\tplatform-android-arm \\\n\t\tplatform-android-arm64 \\\n\t\tplatform-android-x64 \\\n\t\tplatform-darwin-arm64 \\\n\t\tplatform-darwin-x64 \\\n\t\tplatform-deno \\\n\t\tplatform-freebsd-arm64 \\\n\t\tplatform-freebsd-x64 \\\n\t\tplatform-linux-arm \\\n\t\tplatform-linux-arm64 \\\n\t\tplatform-linux-ia32 \\\n\t\tplatform-linux-loong64 \\\n\t\tplatform-linux-mips64el \\\n\t\tplatform-linux-ppc64 \\\n\t\tplatform-linux-riscv64 \\\n\t\tplatform-linux-s390x \\\n\t\tplatform-linux-x64 \\\n\t\tplatform-netbsd-arm64 \\\n\t\tplatform-netbsd-x64 \\\n\t\tplatform-neutral \\\n\t\tplatform-openbsd-arm64 \\\n\t\tplatform-openbsd-x64 \\\n\t\tplatform-openharmony-arm64 \\\n\t\tplatform-sunos-x64 \\\n\t\tplatform-wasi-preview1 \\\n\t\tplatform-wasm \\\n\t\tplatform-win32-arm64 \\\n\t\tplatform-win32-ia32 \\\n\t\tplatform-win32-x64\n\nplatform-win32-x64: version-go go-compiler\n\tnode scripts/esbuild.js npm/@esbuild/win32-x64/package.json --version\n\t$(GO_COMPILER) GOOS=windows GOARCH=amd64 go build $(GO_FLAGS) -o npm/@esbuild/win32-x64/esbuild.exe ./cmd/esbuild\n\nplatform-win32-ia32: version-go go-compiler\n\tnode scripts/esbuild.js npm/@esbuild/win32-ia32/package.json --version\n\t$(GO_COMPILER) GOOS=windows GOARCH=386 go build $(GO_FLAGS) -o npm/@esbuild/win32-ia32/esbuild.exe ./cmd/esbuild\n\nplatform-win32-arm64: version-go go-compiler\n\tnode scripts/esbuild.js npm/@esbuild/win32-arm64/package.json --version\n\t$(GO_COMPILER) GOOS=windows GOARCH=arm64 go build $(GO_FLAGS) -o npm/@esbuild/win32-arm64/esbuild.exe ./cmd/esbuild\n\nplatform-wasi-preview1: version-go go-compiler\n\tnode scripts/esbuild.js npm/@esbuild/wasi-preview1/package.json --version\n\t$(GO_COMPILER) GOOS=wasip1 GOARCH=wasm go build $(GO_FLAGS) -o npm/@esbuild/wasi-preview1/esbuild.wasm ./cmd/esbuild\n\nplatform-unixlike: version-go go-compiler\n\t@test -n \"$(GOOS)\" || (echo \"The environment variable GOOS must be provided\" && false)\n\t@test -n \"$(GOARCH)\" || (echo \"The environment variable GOARCH must be provided\" && false)\n\t@test -n \"$(NPMDIR)\" || (echo \"The environment variable NPMDIR must be provided\" && false)\n\tnode scripts/esbuild.js \"$(NPMDIR)/package.json\" --version\n\t$(GO_COMPILER) GOOS=\"$(GOOS)\" GOARCH=\"$(GOARCH)\" go build $(GO_FLAGS) -o \"$(NPMDIR)/bin/esbuild\" ./cmd/esbuild\n\nplatform-android-x64: platform-wasm\n\tnode scripts/esbuild.js npm/@esbuild/android-x64/package.json --version\n\nplatform-android-arm: platform-wasm\n\tnode scripts/esbuild.js npm/@esbuild/android-arm/package.json --version\n\nplatform-openharmony-arm64: platform-wasm\n\tnode scripts/esbuild.js npm/@esbuild/openharmony-arm64/package.json --version\n\nplatform-aix-ppc64:\n\t@$(MAKE) --no-print-directory GOOS=aix GOARCH=ppc64 NPMDIR=npm/@esbuild/aix-ppc64 platform-unixlike\n\nplatform-android-arm64:\n\t@$(MAKE) --no-print-directory GOOS=android GOARCH=arm64 NPMDIR=npm/@esbuild/android-arm64 platform-unixlike\n\nplatform-darwin-x64:\n\t@$(MAKE) --no-print-directory GOOS=darwin GOARCH=amd64 NPMDIR=npm/@esbuild/darwin-x64 platform-unixlike\n\nplatform-darwin-arm64:\n\t@$(MAKE) --no-print-directory GOOS=darwin GOARCH=arm64 NPMDIR=npm/@esbuild/darwin-arm64 platform-unixlike\n\nplatform-freebsd-x64:\n\t@$(MAKE) --no-print-directory GOOS=freebsd GOARCH=amd64 NPMDIR=npm/@esbuild/freebsd-x64 platform-unixlike\n\nplatform-freebsd-arm64:\n\t@$(MAKE) --no-print-directory GOOS=freebsd GOARCH=arm64 NPMDIR=npm/@esbuild/freebsd-arm64 platform-unixlike\n\nplatform-netbsd-arm64:\n\t@$(MAKE) --no-print-directory GOOS=netbsd GOARCH=arm64 NPMDIR=npm/@esbuild/netbsd-arm64 platform-unixlike\n\nplatform-netbsd-x64:\n\t@$(MAKE) --no-print-directory GOOS=netbsd GOARCH=amd64 NPMDIR=npm/@esbuild/netbsd-x64 platform-unixlike\n\nplatform-openbsd-arm64:\n\t@$(MAKE) --no-print-directory GOOS=openbsd GOARCH=arm64 NPMDIR=npm/@esbuild/openbsd-arm64 platform-unixlike\n\nplatform-openbsd-x64:\n\t@$(MAKE) --no-print-directory GOOS=openbsd GOARCH=amd64 NPMDIR=npm/@esbuild/openbsd-x64 platform-unixlike\n\nplatform-linux-x64:\n\t@$(MAKE) --no-print-directory GOOS=linux GOARCH=amd64 NPMDIR=npm/@esbuild/linux-x64 platform-unixlike\n\nplatform-linux-ia32:\n\t@$(MAKE) --no-print-directory GOOS=linux GOARCH=386 NPMDIR=npm/@esbuild/linux-ia32 platform-unixlike\n\nplatform-linux-arm:\n\t@$(MAKE) --no-print-directory GOOS=linux GOARCH=arm NPMDIR=npm/@esbuild/linux-arm platform-unixlike\n\nplatform-linux-arm64:\n\t@$(MAKE) --no-print-directory GOOS=linux GOARCH=arm64 NPMDIR=npm/@esbuild/linux-arm64 platform-unixlike\n\nplatform-linux-loong64:\n\t@$(MAKE) --no-print-directory GOOS=linux GOARCH=loong64 NPMDIR=npm/@esbuild/linux-loong64 platform-unixlike\n\nplatform-linux-mips64el:\n\t@$(MAKE) --no-print-directory GOOS=linux GOARCH=mips64le NPMDIR=npm/@esbuild/linux-mips64el platform-unixlike\n\nplatform-linux-ppc64:\n\t@$(MAKE) --no-print-directory GOOS=linux GOARCH=ppc64le NPMDIR=npm/@esbuild/linux-ppc64 platform-unixlike\n\nplatform-linux-riscv64:\n\t@$(MAKE) --no-print-directory GOOS=linux GOARCH=riscv64 NPMDIR=npm/@esbuild/linux-riscv64 platform-unixlike\n\nplatform-linux-s390x:\n\t@$(MAKE) --no-print-directory GOOS=linux GOARCH=s390x NPMDIR=npm/@esbuild/linux-s390x platform-unixlike\n\nplatform-sunos-x64:\n\t@$(MAKE) --no-print-directory GOOS=illumos GOARCH=amd64 NPMDIR=npm/@esbuild/sunos-x64 platform-unixlike\n\nplatform-wasm: esbuild go-compiler\n\tnode scripts/esbuild.js npm/esbuild-wasm/package.json --version\n\t$(GO_COMPILER) \"$(NODE)\" scripts/esbuild.js ./esbuild --wasm\n\nplatform-neutral: esbuild\n\tnode scripts/esbuild.js npm/esbuild/package.json --version\n\tnode scripts/esbuild.js ./esbuild --neutral\n\nplatform-deno: platform-wasm go-compiler\n\t$(GO_COMPILER) \"$(NODE)\" scripts/esbuild.js ./esbuild --deno\n\npublish-all: check-go-version\n\t# Make sure the npm directory is pristine (including .gitignored files) since it will be published\n\trm -fr npm && git checkout npm\n\n\t# Publish all platform-dependent packages first\n\t@$(MAKE) --no-print-directory publish-aix-ppc64\n\t@$(MAKE) --no-print-directory publish-android-arm\n\t@$(MAKE) --no-print-directory publish-android-arm64\n\t@$(MAKE) --no-print-directory publish-android-x64\n\t@$(MAKE) --no-print-directory publish-darwin-arm64\n\t@$(MAKE) --no-print-directory publish-darwin-x64\n\t@$(MAKE) --no-print-directory publish-freebsd-arm64\n\t@$(MAKE) --no-print-directory publish-freebsd-x64\n\t@$(MAKE) --no-print-directory publish-linux-arm\n\t@$(MAKE) --no-print-directory publish-linux-arm64\n\t@$(MAKE) --no-print-directory publish-linux-ia32\n\t@$(MAKE) --no-print-directory publish-linux-loong64\n\t@$(MAKE) --no-print-directory publish-linux-mips64el\n\t@$(MAKE) --no-print-directory publish-linux-ppc64\n\t@$(MAKE) --no-print-directory publish-linux-riscv64\n\t@$(MAKE) --no-print-directory publish-linux-s390x\n\t@$(MAKE) --no-print-directory publish-linux-x64\n\t@$(MAKE) --no-print-directory publish-netbsd-arm64\n\t@$(MAKE) --no-print-directory publish-netbsd-x64\n\t@$(MAKE) --no-print-directory publish-openbsd-arm64\n\t@$(MAKE) --no-print-directory publish-openbsd-x64\n\t@$(MAKE) --no-print-directory publish-openharmony-arm64\n\t@$(MAKE) --no-print-directory publish-sunos-x64\n\t@$(MAKE) --no-print-directory publish-wasi-preview1\n\t@$(MAKE) --no-print-directory publish-win32-arm64\n\t@$(MAKE) --no-print-directory publish-win32-ia32\n\t@$(MAKE) --no-print-directory publish-win32-x64\n\n\t# Publish platform-independent packages last to avoid race conditions\n\t@$(MAKE) --no-print-directory publish-neutral\n\t@$(MAKE) --no-print-directory publish-wasm\n\npublish-win32-x64: platform-win32-x64\n\tcd npm/@esbuild/win32-x64 && npm publish\n\npublish-win32-ia32: platform-win32-ia32\n\tcd npm/@esbuild/win32-ia32 && npm publish\n\npublish-win32-arm64: platform-win32-arm64\n\tcd npm/@esbuild/win32-arm64 && npm publish\n\npublish-wasi-preview1: platform-wasi-preview1\n\tcd npm/@esbuild/wasi-preview1 && npm publish\n\npublish-aix-ppc64: platform-aix-ppc64\n\tcd npm/@esbuild/aix-ppc64 && npm publish\n\npublish-android-x64: platform-android-x64\n\tcd npm/@esbuild/android-x64 && npm publish\n\npublish-android-arm: platform-android-arm\n\tcd npm/@esbuild/android-arm && npm publish\n\npublish-android-arm64: platform-android-arm64\n\tcd npm/@esbuild/android-arm64 && npm publish\n\npublish-darwin-x64: platform-darwin-x64\n\tcd npm/@esbuild/darwin-x64 && npm publish\n\npublish-darwin-arm64: platform-darwin-arm64\n\tcd npm/@esbuild/darwin-arm64 && npm publish\n\npublish-freebsd-x64: platform-freebsd-x64\n\tcd npm/@esbuild/freebsd-x64 && npm publish\n\npublish-freebsd-arm64: platform-freebsd-arm64\n\tcd npm/@esbuild/freebsd-arm64 && npm publish\n\npublish-netbsd-arm64: platform-netbsd-arm64\n\tcd npm/@esbuild/netbsd-arm64 && npm publish\n\npublish-netbsd-x64: platform-netbsd-x64\n\tcd npm/@esbuild/netbsd-x64 && npm publish\n\npublish-openbsd-arm64: platform-openbsd-arm64\n\tcd npm/@esbuild/openbsd-arm64 && npm publish\n\npublish-openbsd-x64: platform-openbsd-x64\n\tcd npm/@esbuild/openbsd-x64 && npm publish\n\npublish-openharmony-arm64: platform-openharmony-arm64\n\tcd npm/@esbuild/openharmony-arm64 && npm publish\n\npublish-linux-x64: platform-linux-x64\n\tcd npm/@esbuild/linux-x64 && npm publish\n\npublish-linux-ia32: platform-linux-ia32\n\tcd npm/@esbuild/linux-ia32 && npm publish\n\npublish-linux-arm: platform-linux-arm\n\tcd npm/@esbuild/linux-arm && npm publish\n\npublish-linux-arm64: platform-linux-arm64\n\tcd npm/@esbuild/linux-arm64 && npm publish\n\npublish-linux-loong64: platform-linux-loong64\n\tcd npm/@esbuild/linux-loong64 && npm publish\n\npublish-linux-mips64el: platform-linux-mips64el\n\tcd npm/@esbuild/linux-mips64el && npm publish\n\npublish-linux-ppc64: platform-linux-ppc64\n\tcd npm/@esbuild/linux-ppc64 && npm publish\n\npublish-linux-riscv64: platform-linux-riscv64\n\tcd npm/@esbuild/linux-riscv64 && npm publish\n\npublish-linux-s390x: platform-linux-s390x\n\tcd npm/@esbuild/linux-s390x && npm publish\n\npublish-sunos-x64: platform-sunos-x64\n\tcd npm/@esbuild/sunos-x64 && npm publish\n\npublish-wasm: platform-wasm\n\tcd npm/esbuild-wasm && npm publish\n\npublish-neutral: platform-neutral\n\tcd npm/esbuild && npm publish\n\nvalidate-build:\n\t@test -n \"$(TARGET)\" || (echo \"The environment variable TARGET must be provided\" && false)\n\t@test -n \"$(PACKAGE)\" || (echo \"The environment variable PACKAGE must be provided\" && false)\n\t@test -n \"$(SUBPATH)\" || (echo \"The environment variable SUBPATH must be provided\" && false)\n\t@echo && echo \"🔷 Checking $(SCOPE)$(PACKAGE)\"\n\t@rm -fr validate && mkdir validate\n\t@$(MAKE) --no-print-directory \"$(TARGET)\"\n\t@curl -s \"https://registry.npmjs.org/$(SCOPE)$(PACKAGE)/-/$(PACKAGE)-$(ESBUILD_VERSION).tgz\" > validate/esbuild.tgz\n\t@cd validate && tar xf esbuild.tgz\n\t@ls -l \"npm/$(SCOPE)$(PACKAGE)/$(SUBPATH)\" \"validate/package/$(SUBPATH)\" && \\\n\t\tshasum \"npm/$(SCOPE)$(PACKAGE)/$(SUBPATH)\" \"validate/package/$(SUBPATH)\" && \\\n\t\tcmp \"npm/$(SCOPE)$(PACKAGE)/$(SUBPATH)\" \"validate/package/$(SUBPATH)\"\n\t@rm -fr validate\n\n# This checks that the published binaries are bitwise-identical to the locally-build binaries\nvalidate-builds:\n\tgit fetch --all --tags && git checkout \"v$(ESBUILD_VERSION)\"\n\t@$(MAKE) --no-print-directory TARGET=platform-aix-ppc64         SCOPE=@esbuild/ PACKAGE=aix-ppc64           SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-android-arm       SCOPE=@esbuild/ PACKAGE=android-arm         SUBPATH=esbuild.wasm validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-android-arm64     SCOPE=@esbuild/ PACKAGE=android-arm64       SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-android-x64       SCOPE=@esbuild/ PACKAGE=android-x64         SUBPATH=esbuild.wasm validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-darwin-arm64      SCOPE=@esbuild/ PACKAGE=darwin-arm64        SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-darwin-x64        SCOPE=@esbuild/ PACKAGE=darwin-x64          SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-freebsd-arm64     SCOPE=@esbuild/ PACKAGE=freebsd-arm64       SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-freebsd-x64       SCOPE=@esbuild/ PACKAGE=freebsd-x64         SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-linux-arm         SCOPE=@esbuild/ PACKAGE=linux-arm           SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-linux-arm64       SCOPE=@esbuild/ PACKAGE=linux-arm64         SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-linux-ia32        SCOPE=@esbuild/ PACKAGE=linux-ia32          SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-linux-loong64     SCOPE=@esbuild/ PACKAGE=linux-loong64       SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-linux-mips64el    SCOPE=@esbuild/ PACKAGE=linux-mips64el      SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-linux-ppc64       SCOPE=@esbuild/ PACKAGE=linux-ppc64         SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-linux-riscv64     SCOPE=@esbuild/ PACKAGE=linux-riscv64       SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-linux-s390x       SCOPE=@esbuild/ PACKAGE=linux-s390x         SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-linux-x64         SCOPE=@esbuild/ PACKAGE=linux-x64           SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-netbsd-arm64      SCOPE=@esbuild/ PACKAGE=netbsd-arm64        SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-netbsd-x64        SCOPE=@esbuild/ PACKAGE=netbsd-x64          SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-openbsd-arm64     SCOPE=@esbuild/ PACKAGE=openbsd-arm64       SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-openbsd-x64       SCOPE=@esbuild/ PACKAGE=openbsd-x64         SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-openharmony-arm64 SCOPE=@esbuild/ PACKAGE=openharmony-arm64   SUBPATH=esbuild.wasm validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-sunos-x64         SCOPE=@esbuild/ PACKAGE=sunos-x64           SUBPATH=bin/esbuild  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-wasi-preview1     SCOPE=@esbuild/ PACKAGE=wasi-preview1       SUBPATH=esbuild.wasm validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-wasm                              PACKAGE=esbuild-wasm        SUBPATH=esbuild.wasm validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-win32-arm64       SCOPE=@esbuild/ PACKAGE=win32-arm64         SUBPATH=esbuild.exe  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-win32-ia32        SCOPE=@esbuild/ PACKAGE=win32-ia32          SUBPATH=esbuild.exe  validate-build\n\t@$(MAKE) --no-print-directory TARGET=platform-win32-x64         SCOPE=@esbuild/ PACKAGE=win32-x64           SUBPATH=esbuild.exe  validate-build\n\nclean:\n\tgo clean -cache\n\tgo clean -testcache\n\trm -f esbuild\n\trm -f npm/@esbuild/wasi-preview1/esbuild.wasm\n\trm -f npm/@esbuild/win32-arm64/esbuild.exe\n\trm -f npm/@esbuild/win32-ia32/esbuild.exe\n\trm -f npm/@esbuild/win32-x64/esbuild.exe\n\trm -f npm/esbuild-wasm/esbuild.wasm npm/esbuild-wasm/wasm_exec*.js\n\trm -rf npm/@esbuild/aix-ppc64/bin\n\trm -rf npm/@esbuild/android-arm/bin npm/@esbuild/android-arm/esbuild.wasm npm/@esbuild/android-arm/wasm_exec*.js\n\trm -rf npm/@esbuild/android-arm64/bin\n\trm -rf npm/@esbuild/android-x64/bin npm/@esbuild/android-x64/esbuild.wasm npm/@esbuild/android-x64/wasm_exec*.js\n\trm -rf npm/@esbuild/darwin-arm64/bin\n\trm -rf npm/@esbuild/darwin-x64/bin\n\trm -rf npm/@esbuild/freebsd-arm64/bin\n\trm -rf npm/@esbuild/freebsd-x64/bin\n\trm -rf npm/@esbuild/linux-arm/bin\n\trm -rf npm/@esbuild/linux-arm64/bin\n\trm -rf npm/@esbuild/linux-ia32/bin\n\trm -rf npm/@esbuild/linux-loong64/bin\n\trm -rf npm/@esbuild/linux-mips64el/bin\n\trm -rf npm/@esbuild/linux-ppc64/bin\n\trm -rf npm/@esbuild/linux-riscv64/bin\n\trm -rf npm/@esbuild/linux-s390x/bin\n\trm -rf npm/@esbuild/linux-x64/bin\n\trm -rf npm/@esbuild/netbsd-arm64/bin\n\trm -rf npm/@esbuild/netbsd-x64/bin\n\trm -rf npm/@esbuild/openbsd-arm64/bin\n\trm -rf npm/@esbuild/openbsd-x64/bin\n\trm -rf npm/@esbuild/openharmony-arm64/bin npm/@esbuild/openharmony-arm64/esbuild.wasm npm/@esbuild/openharmony-arm64/wasm_exec*.js\n\trm -rf npm/@esbuild/sunos-x64/bin\n\trm -rf npm/esbuild-wasm/esm\n\trm -rf npm/esbuild-wasm/lib\n\trm -rf npm/esbuild/bin npm/esbuild/lib npm/esbuild/install.js\n\trm -rf require/*/bench/\n\trm -rf require/*/demo/\n\trm -rf require/*/node_modules/\n\trm -rf require/yarnpnp/.pnp* require/yarnpnp/.yarn* require/yarnpnp/out*.js\n\trm -rf validate\n\n# This also cleans directories containing cached code from other projects\nclean-all: clean\n\trm -fr github demo bench\n\n################################################################################\n# These npm packages are used for benchmarks. Install them in subdirectories\n# because we want to install the same package name at multiple versions\n\nrequire/webpack5/node_modules:\n\tcd require/webpack5 && npm ci\n\nrequire/rollup/node_modules:\n\tcd require/rollup && npm ci\n\nrequire/parcel2/node_modules:\n\tcd require/parcel2 && npm ci\n\nlib/node_modules:\n\tcd lib && npm ci\n\nscripts/node_modules:\n\tcd scripts && npm ci\n\nscripts/browser/node_modules:\n\tcd scripts/browser && npm ci\n\n################################################################################\n# This generates browser support mappings\n\ncompat-table: esbuild | compat-table/node_modules\n\t./esbuild compat-table/src/index.ts --bundle --platform=node --external:./compat-table/repos/* --outfile=compat-table/out.js --log-level=warning --sourcemap\n\tnode --enable-source-maps compat-table/out.js\n\nupdate-compat-table: esbuild\n\tcd compat-table && npm i @mdn/browser-compat-data@latest caniuse-lite@latest --silent --save-exact\n\t./esbuild compat-table/src/index.ts --bundle --platform=node --external:./compat-table/repos/* --outfile=compat-table/out.js --log-level=warning --sourcemap\n\tnode --enable-source-maps compat-table/out.js --update\n\ncompat-table/node_modules:\n\tcd compat-table && npm ci\n\n################################################################################\n# This runs the test262 official JavaScript test suite through esbuild\n\ngithub/test262:\n\tmkdir -p github\n\tgit clone --depth 1 https://github.com/tc39/test262.git github/test262\n\ndemo/test262: | github/test262\n\tmkdir -p demo/test262\n\tcp -r github/test262/harness demo/test262/harness\n\tcp -r github/test262/test demo/test262/test\n\ntest262: esbuild | demo/test262\n\tnode --experimental-vm-modules scripts/test262.js\n\ntest262-async: esbuild | demo/test262\n\tnode --experimental-vm-modules scripts/test262-async.js\n\n################################################################################\n# This runs UglifyJS's test suite through esbuild\n\ngithub/uglify:\n\tmkdir -p github/uglify\n\tcd github/uglify && git init && git remote add origin https://github.com/mishoo/uglifyjs.git\n\tcd github/uglify && git fetch --depth 1 origin 860aa9531b2ce660ace8379c335bb092034b6e82 && git checkout FETCH_HEAD\n\ndemo/uglify: | github/uglify\n\tmkdir -p demo\n\tcp -r github/uglify/ demo/uglify\n\tcd demo/uglify && npm i\n\nuglify: esbuild | demo/uglify\n\tnode scripts/uglify-tests.js\n\n################################################################################\n# This builds the TypeScript compiler, then uses it to type check tsc itself\n\ngithub/tsc:\n\tmkdir -p github/tsc\n\tcd github/tsc && git init && git remote add origin https://github.com/Microsoft/TypeScript.git\n\tcd github/tsc && git fetch --depth 1 origin e6ceba084147bd00045c573a1ba9843c0bb5c721 && git checkout FETCH_HEAD\n\ntest-tsc: esbuild | github/tsc\n\trm -fr demo/tsc\n\tmkdir -p demo/tsc/built/local\n\tcp -r github/tsc/src github/tsc/scripts demo/tsc\n\tcp github/tsc/lib/*.d.ts demo/tsc/built/local\n\tcd demo/tsc && node scripts/processDiagnosticMessages.mjs src/compiler/diagnosticMessages.json\n\t./esbuild --bundle demo/tsc/src/tsc/tsc.ts --outfile=demo/tsc/built/local/tsc.js --platform=node --target=es2018 --packages=external\n\techo '{\"dependencies\":{\"@types/node\":\"20.2.5\",\"@types/microsoft__typescript-etw\":\"0.1.1\",\"@types/source-map-support\":\"0.5.6\"}}' > demo/tsc/package.json\n\tcd demo/tsc && npm i --silent && echo 'Type checking tsc using tsc...' && time -p node ./built/local/tsc.js -p src/compiler\n\n################################################################################\n# This builds Rollup using esbuild and then uses it to run Rollup's test suite\n\nTEST_ROLLUP_FIND = \"compilerOptions\": {\n\nTEST_ROLLUP_REPLACE += \"compilerOptions\": {\nTEST_ROLLUP_REPLACE += \"baseUrl\": \".\",\nTEST_ROLLUP_REPLACE += \"paths\": { \"package.json\": [\".\\/package.json\"] },\n\nTEST_ROLLUP_FLAGS += --bundle\nTEST_ROLLUP_FLAGS += --external:fsevents\nTEST_ROLLUP_FLAGS += --outfile=dist/rollup.js\nTEST_ROLLUP_FLAGS += --platform=node\nTEST_ROLLUP_FLAGS += --target=es6\nTEST_ROLLUP_FLAGS += src/node-entry.ts\n\ngithub/rollup:\n\tmkdir -p github\n\tgit clone --depth 1 --branch v2.60.2 https://github.com/rollup/rollup.git github/rollup\n\ndemo/rollup: | github/rollup\n\tmkdir -p demo\n\tcp -RP github/rollup/ demo/rollup\n\tcd demo/rollup && npm ci\n\n\t# Patch over Rollup's custom \"package.json\" alias using \"tsconfig.json\"\n\tcat demo/rollup/tsconfig.json | sed 's/$(TEST_ROLLUP_FIND)/$(TEST_ROLLUP_REPLACE)/' > demo/rollup/tsconfig2.json\n\tmv demo/rollup/tsconfig2.json demo/rollup/tsconfig.json\n\ntest-rollup: esbuild | demo/rollup\n\t# Skip watch tests to avoid flakes\n\tcd demo/rollup && ../../esbuild $(TEST_ROLLUP_FLAGS) && npm run test:only -- --fgrep watch --invert\n\tcd demo/rollup && ../../esbuild $(TEST_ROLLUP_FLAGS) --minify && npm run test:only -- --fgrep watch --invert\n\n################################################################################\n# This builds Preact using esbuild with splitting enabled, which had a bug at one point\n\nPREACT_SPLITTING += import { h } from 'preact';\nPREACT_SPLITTING += import { USE as use } from 'preact/hooks';\nPREACT_SPLITTING += import { renderToString } from 'preact-render-to-string';\nPREACT_SPLITTING += let Component = () => (use(() => {}), h('div'));\nPREACT_SPLITTING += if (renderToString(h(Component)) !== '<div></div>') throw 'fail';\n\nPREACT_HOOKS += useCallback\nPREACT_HOOKS += useContext\nPREACT_HOOKS += useDebugValue\nPREACT_HOOKS += useEffect\nPREACT_HOOKS += useErrorBoundary\nPREACT_HOOKS += useImperativeHandle\nPREACT_HOOKS += useLayoutEffect\nPREACT_HOOKS += useMemo\nPREACT_HOOKS += useReducer\nPREACT_HOOKS += useRef\nPREACT_HOOKS += useState\n\ndemo/preact-splitting:\n\tmkdir -p demo/preact-splitting/src\n\tcd demo/preact-splitting && echo '{}' > package.json && npm i preact@10.4.6 preact-render-to-string@5.1.10\n\tcd demo/preact-splitting && for h in $(PREACT_HOOKS); do echo \"$(PREACT_SPLITTING)\" | sed s/USE/$$h/ > src/$$h.js; done\n\ntest-preact-splitting: esbuild | demo/preact-splitting\n\tcd demo/preact-splitting && rm -fr out && ../../esbuild --bundle --splitting --format=esm src/*.js --outdir=out --out-extension:.js=.mjs\n\tcd demo/preact-splitting && for h in $(PREACT_HOOKS); do set -e && node --experimental-modules out/$$h.mjs; done\n\tcd demo/preact-splitting && rm -fr out && ../../esbuild --bundle --splitting --format=esm src/*.js --outdir=out --out-extension:.js=.mjs --minify --target=node12\n\tcd demo/preact-splitting && for h in $(PREACT_HOOKS); do set -e && node --experimental-modules out/$$h.mjs; done\n\n################################################################################\n# This builds Sucrase using esbuild and then uses it to run Sucrase's test suite\n\ngithub/sucrase:\n\tmkdir -p github/sucrase\n\tcd github/sucrase && git init && git remote add origin https://github.com/alangpierce/sucrase.git\n\tcd github/sucrase && git fetch --depth 1 origin a4a596e5cdd57362f309ae50cc32a235d7817d34 && git checkout FETCH_HEAD\n\ndemo/sucrase: | github/sucrase\n\tmkdir -p demo\n\tcp -r github/sucrase/ demo/sucrase\n\tcd demo/sucrase && npm i\n\tcd demo/sucrase && find test -name '*.ts' | sed 's/\\(.*\\)\\.ts/import \".\\/\\1\"/g' > all-tests.ts\n\techo '{\"compilerOptions\":{\"useDefineForClassFields\":false}}' > demo/sucrase/tsconfig.json # Sucrase tests fail if tsconfig.json is respected due to useDefineForClassFields\n\ntest-sucrase: esbuild | demo/sucrase\n\tcd demo/sucrase && ../../esbuild --bundle all-tests.ts --target=es6 --platform=node > out.js && npx mocha out.js\n\tcd demo/sucrase && ../../esbuild --bundle all-tests.ts --target=es6 --platform=node --minify > out.js && npx mocha out.js\n\n################################################################################\n# This builds Esprima using esbuild and then uses it to run Esprima's test suite\n\ngithub/esprima:\n\tmkdir -p github/esprima\n\tcd github/esprima && git init && git remote add origin https://github.com/jquery/esprima.git\n\tcd github/esprima && git fetch --depth 1 origin fa49b2edc288452eb49441054ce6f7ff4b891eb4 && git checkout FETCH_HEAD\n\ndemo/esprima: | github/esprima\n\tmkdir -p demo\n\tcp -r github/esprima/ demo/esprima\n\tcd demo/esprima && npm ci\n\ntest-esprima: esbuild | demo/esprima\n\tcd demo/esprima && ../../esbuild --bundle src/esprima.ts --outfile=dist/esprima.js --target=es6 --platform=node && npm run all-tests\n\tcd demo/esprima && ../../esbuild --bundle src/esprima.ts --outfile=dist/esprima.js --target=es6 --platform=node --minify && npm run all-tests\n\n################################################################################\n# This runs terser's test suite through esbuild\n\ngithub/terser:\n\tmkdir -p github/terser\n\tcd github/terser && git init && git remote add origin https://github.com/terser/terser.git\n\tcd github/terser && git fetch --depth 1 origin 056623c20dbbc42d2f5a34926c07133981519326 && git checkout FETCH_HEAD\n\ndemo/terser: | github/terser\n\tmkdir -p demo\n\tcp -r github/terser/ demo/terser\n\tcd demo/terser && npm ci && npm run build\n\nterser: esbuild | demo/terser\n\tnode scripts/terser-tests.js\n\n################################################################################\n# three.js demo\n\ngithub/three:\n\tmkdir -p github\n\tgit clone --depth 1 --branch r108 https://github.com/mrdoob/three.js.git github/three\n\ndemo/three: | github/three\n\tmkdir -p demo/three\n\tcp -r github/three/src demo/three/src\n\ndemo-three: demo-three-esbuild demo-three-rollup demo-three-webpack5 demo-three-parcel2\n\ndemo-three-esbuild: esbuild | demo/three\n\trm -fr demo/three/esbuild\n\ttime -p ./esbuild --bundle --global-name=THREE --sourcemap --minify demo/three/src/Three.js --outfile=demo/three/esbuild/Three.esbuild.js\n\tdu -h demo/three/esbuild/Three.esbuild.js*\n\tshasum demo/three/esbuild/Three.esbuild.js*\n\ndemo-three-eswasm: platform-wasm | demo/three\n\trm -fr demo/three/eswasm\n\ttime -p ./npm/esbuild-wasm/bin/esbuild --bundle --global-name=THREE \\\n\t\t--sourcemap --minify demo/three/src/Three.js --outfile=demo/three/eswasm/Three.eswasm.js\n\tdu -h demo/three/eswasm/Three.eswasm.js*\n\tshasum demo/three/eswasm/Three.eswasm.js*\n\nTHREE_ROLLUP_CONFIG += import terser from '@rollup/plugin-terser';\nTHREE_ROLLUP_CONFIG += export default {\nTHREE_ROLLUP_CONFIG +=   output: { format: 'iife', name: 'THREE', sourcemap: true },\nTHREE_ROLLUP_CONFIG +=   plugins: [terser()],\nTHREE_ROLLUP_CONFIG += }\n\ndemo-three-rollup: | require/rollup/node_modules demo/three\n\trm -fr require/rollup/demo/three demo/three/rollup\n\tmkdir -p require/rollup/demo/three demo/three/rollup\n\techo \"$(THREE_ROLLUP_CONFIG)\" > require/rollup/demo/three/config.mjs\n\tln -s ../../../../demo/three/src require/rollup/demo/three/src\n\tln -s ../../../../demo/three/rollup require/rollup/demo/three/out\n\tcd require/rollup/demo/three && time -p ../../node_modules/.bin/rollup src/Three.js -o out/Three.rollup.js -c config.mjs\n\tdu -h demo/three/rollup/Three.rollup.js*\n\nTHREE_WEBPACK5_FLAGS += --devtool=source-map\nTHREE_WEBPACK5_FLAGS += --mode=production\nTHREE_WEBPACK5_FLAGS += --output-library THREE\n\ndemo-three-webpack5: | require/webpack5/node_modules demo/three\n\trm -fr require/webpack5/demo/three demo/three/webpack5\n\tmkdir -p require/webpack5/demo/three demo/three/webpack5\n\tln -s ../../../../demo/three/src require/webpack5/demo/three/src\n\tln -s ../../../../demo/three/webpack5 require/webpack5/demo/three/out\n\tcd require/webpack5/demo/three && time -p ../../node_modules/.bin/webpack --entry ./src/Three.js $(THREE_WEBPACK5_FLAGS) -o out/Three.webpack5.js\n\tdu -h demo/three/webpack5/Three.webpack5.js*\n\ndemo-three-parcel2: | require/parcel2/node_modules demo/three\n\trm -fr require/parcel2/demo/three demo/three/parcel2\n\tmkdir -p require/parcel2/demo/three demo/three/parcel2\n\n\t# Copy the whole source tree since symlinks mess up Parcel's internal package lookup for \"@babel/core\"\n\tcp -r demo/three/src require/parcel2/demo/three/src\n\n\techo 'import * as THREE from \"./src/Three.js\"; window.THREE = THREE' > require/parcel2/demo/three/Three.parcel2.js\n\tcd require/parcel2/demo/three && time -p ../../node_modules/.bin/parcel build \\\n\t\tThree.parcel2.js --dist-dir ../../../../demo/three/parcel2 --cache-dir .cache\n\tdu -h demo/three/parcel2/Three.parcel2.js*\n\n################################################################################\n# three.js benchmark (measures JavaScript performance, same as three.js demo but 10x bigger)\n\nbench/three: | github/three\n\tmkdir -p bench/three/src\n\techo > bench/three/src/entry.js\n\tfor i in 1 2 3 4 5 6 7 8 9 10; do test -d \"bench/three/src/copy$$i\" || cp -r github/three/src \"bench/three/src/copy$$i\"; done\n\tfor i in 1 2 3 4 5 6 7 8 9 10; do echo \"import * as copy$$i from './copy$$i/Three.js'; export {copy$$i}\" >> bench/three/src/entry.js; done\n\techo 'Line count:' && find bench/three/src -name '*.js' | xargs wc -l | tail -n 1\n\nbench-three: bench-three-esbuild bench-three-rollup bench-three-webpack5 bench-three-parcel2\n\nbench-three-esbuild: esbuild | bench/three\n\trm -fr bench/three/esbuild\n\ttime -p ./esbuild --bundle --global-name=THREE --sourcemap --minify bench/three/src/entry.js --outfile=bench/three/esbuild/entry.esbuild.js --timing\n\tdu -h bench/three/esbuild/entry.esbuild.js*\n\tshasum bench/three/esbuild/entry.esbuild.js*\n\nbench-three-eswasm: platform-wasm | bench/three\n\trm -fr bench/three/eswasm\n\ttime -p ./npm/esbuild-wasm/bin/esbuild --bundle --global-name=THREE \\\n\t\t--sourcemap --minify bench/three/src/entry.js --outfile=bench/three/eswasm/entry.eswasm.js\n\tdu -h bench/three/eswasm/entry.eswasm.js*\n\tshasum bench/three/eswasm/entry.eswasm.js*\n\nbench-three-rollup: | require/rollup/node_modules bench/three\n\trm -fr require/rollup/bench/three bench/three/rollup\n\tmkdir -p require/rollup/bench/three bench/three/rollup\n\techo \"$(THREE_ROLLUP_CONFIG)\" > require/rollup/bench/three/config.mjs\n\tln -s ../../../../bench/three/src require/rollup/bench/three/src\n\tln -s ../../../../bench/three/rollup require/rollup/bench/three/out\n\tcd require/rollup/bench/three && time -p ../../node_modules/.bin/rollup src/entry.js -o out/entry.rollup.js -c config.mjs\n\tdu -h bench/three/rollup/entry.rollup.js*\n\nbench-three-webpack5: | require/webpack5/node_modules bench/three\n\trm -fr require/webpack5/bench/three bench/three/webpack5\n\tmkdir -p require/webpack5/bench/three bench/three/webpack5\n\tln -s ../../../../bench/three/src require/webpack5/bench/three/src\n\tln -s ../../../../bench/three/webpack5 require/webpack5/bench/three/out\n\tcd require/webpack5/bench/three && time -p ../../node_modules/.bin/webpack --entry ./src/entry.js $(THREE_WEBPACK5_FLAGS) -o out/entry.webpack5.js\n\tdu -h bench/three/webpack5/entry.webpack5.js*\n\nbench-three-parcel2: | require/parcel2/node_modules bench/three\n\trm -fr require/parcel2/bench/three bench/three/parcel2\n\tmkdir -p require/parcel2/bench/three bench/three/parcel2\n\n\t# Copy the whole source tree since symlinks mess up Parcel's internal package lookup for \"@babel/core\"\n\tcp -r bench/three/src require/parcel2/bench/three/src\n\n\techo 'import * as THREE from \"./src/entry.js\"; window.THREE = THREE' > require/parcel2/bench/three/entry.parcel2.js\n\tcd require/parcel2/bench/three && time -p node ../../node_modules/.bin/parcel build \\\n\t\tentry.parcel2.js --dist-dir ../../../../bench/three/parcel2 --cache-dir .cache\n\tdu -h bench/three/parcel2/entry.parcel2.js*\n\n################################################################################\n# Rome benchmark (measures TypeScript performance)\n\nROME_TSCONFIG += {\nROME_TSCONFIG +=   \\\"compilerOptions\\\": {\nROME_TSCONFIG +=     \\\"sourceMap\\\": true,\nROME_TSCONFIG +=     \\\"esModuleInterop\\\": true,\nROME_TSCONFIG +=     \\\"resolveJsonModule\\\": true,\nROME_TSCONFIG +=     \\\"moduleResolution\\\": \\\"node\\\",\nROME_TSCONFIG +=     \\\"target\\\": \\\"es2019\\\",\nROME_TSCONFIG +=     \\\"module\\\": \\\"commonjs\\\",\nROME_TSCONFIG +=     \\\"baseUrl\\\": \\\".\\\"\nROME_TSCONFIG +=   }\nROME_TSCONFIG += }\n\ngithub/rome:\n\tmkdir -p github/rome\n\tcd github/rome && git init && git remote add origin https://github.com/romejs/rome.git\n\tcd github/rome && git fetch --depth 1 origin d95a3a7aab90773c9b36d9c82a08c8c4c6b68aa5 && git checkout FETCH_HEAD\n\nbench/rome: | github/rome\n\tmkdir -p bench/rome\n\tcp -r github/rome/packages bench/rome/src\n\techo \"$(ROME_TSCONFIG)\" > bench/rome/src/tsconfig.json\n\techo 'import \"rome/bin/rome\"' > bench/rome/src/entry.ts\n\n\t# Patch a cyclic import ordering issue that affects commonjs-style bundlers (webpack and parcel)\n\techo \"export { default as createHook } from './api/createHook';\" > .temp\n\tsed \"/createHook/d\" bench/rome/src/@romejs/js-compiler/index.ts >> .temp\n\tmv .temp bench/rome/src/@romejs/js-compiler/index.ts\n\n\t# Replace \"import fs = require('fs')\" with \"const fs = require('fs')\" because\n\t# the TypeScript compiler strips these statements when targeting \"esnext\",\n\t# which breaks Parcel 2 when scope hoisting is enabled.\n\tfind bench/rome/src -name '*.ts' -type f -print0 | xargs -L1 -0 sed -i '' 's/import \\([A-Za-z0-9_]*\\) =/const \\1 =/g'\n\tfind bench/rome/src -name '*.tsx' -type f -print0 | xargs -L1 -0 sed -i '' 's/import \\([A-Za-z0-9_]*\\) =/const \\1 =/g'\n\n\t# Get an approximate line count\n\trm -r bench/rome/src/@romejs/js-parser/test-fixtures\n\techo 'Line count:' && (find bench/rome/src -name '*.ts' && find bench/rome/src -name '*.js') | xargs wc -l | tail -n 1\n\n# This target provides an easy way to verify that the build is correct. Since\n# Rome is self-hosted, we can just run the bundle to build Rome. This makes sure\n# the bundle doesn't crash when run and is a good test of a non-trivial workload.\nbench/rome-verify: | github/rome\n\tmkdir -p bench/rome-verify\n\tcp -r github/rome/packages bench/rome-verify/packages\n\tcp github/rome/package.json bench/rome-verify/package.json\n\nbench-rome: bench-rome-esbuild bench-rome-webpack5 bench-rome-parcel2\n\nbench-rome-esbuild: esbuild | bench/rome bench/rome-verify\n\trm -fr bench/rome/esbuild\n\ttime -p ./esbuild --bundle --sourcemap --minify bench/rome/src/entry.ts --outfile=bench/rome/esbuild/rome.esbuild.js --platform=node --timing\n\ttime -p ./esbuild --bundle --sourcemap --minify bench/rome/src/entry.ts --outfile=bench/rome/esbuild/rome.esbuild.js --platform=node --timing\n\ttime -p ./esbuild --bundle --sourcemap --minify bench/rome/src/entry.ts --outfile=bench/rome/esbuild/rome.esbuild.js --platform=node --timing\n\tdu -h bench/rome/esbuild/rome.esbuild.js*\n\tshasum bench/rome/esbuild/rome.esbuild.js*\n\tcd bench/rome-verify && rm -fr esbuild && ROME_CACHE=0 node ../rome/esbuild/rome.esbuild.js bundle packages/rome esbuild\n\nROME_WEBPACK5_CONFIG += module.exports = {\nROME_WEBPACK5_CONFIG +=   entry: './src/entry.ts',\nROME_WEBPACK5_CONFIG +=   mode: 'production',\nROME_WEBPACK5_CONFIG +=   target: 'node',\nROME_WEBPACK5_CONFIG +=   devtool: 'source-map',\nROME_WEBPACK5_CONFIG +=   module: { rules: [{ test: /\\.ts$$/, loader: 'ts-loader', options: { transpileOnly: true } }] },\nROME_WEBPACK5_CONFIG +=   resolve: {\nROME_WEBPACK5_CONFIG +=     extensions: ['.ts', '.js'],\nROME_WEBPACK5_CONFIG +=     alias: { rome: __dirname + '/src/rome', '@romejs': __dirname + '/src/@romejs' },\nROME_WEBPACK5_CONFIG +=   },\nROME_WEBPACK5_CONFIG +=   output: { filename: 'rome.webpack.js', path: __dirname + '/out' },\nROME_WEBPACK5_CONFIG += };\n\nbench-rome-webpack5: | require/webpack5/node_modules bench/rome bench/rome-verify\n\trm -fr require/webpack5/bench/rome bench/rome/webpack5\n\tmkdir -p require/webpack5/bench/rome bench/rome/webpack5\n\techo \"$(ROME_WEBPACK5_CONFIG)\" > require/webpack5/bench/rome/webpack.config.js\n\tln -s ../../../../bench/rome/src require/webpack5/bench/rome/src\n\tln -s ../../../../bench/rome/webpack5 require/webpack5/bench/rome/out\n\tcd require/webpack5/bench/rome && time -p ../../node_modules/.bin/webpack\n\tdu -h bench/rome/webpack5/rome.webpack.js*\n\tcd bench/rome-verify && rm -fr webpack5 && ROME_CACHE=0 node ../rome/webpack5/rome.webpack.js bundle packages/rome webpack5\n\nROME_PARCEL_ALIASES += \"alias\": {\nROME_PARCEL_ALIASES +=   $(shell ls bench/rome/src/@romejs | sed 's/.*/\"\\@romejs\\/&\": \".\\/@romejs\\/&\",/g')\nROME_PARCEL_ALIASES +=   \"rome\": \"./rome\"\nROME_PARCEL_ALIASES += }\n\nbench-rome-parcel2: | require/parcel2/node_modules bench/rome bench/rome-verify\n\trm -fr bench/rome/parcel2\n\tcp -r bench/rome/src bench/rome/parcel2\n\trm -fr bench/rome/parcel2/node_modules\n\tcp -RP require/parcel2/node_modules bench/rome/parcel2/node_modules\n\n\t# Inject aliases into \"package.json\" to fix Parcel 2 ignoring \"tsconfig.json\".\n\t# Also inject \"engines\": \"node\" to avoid Parcel 2 mangling node globals.\n\t# Also inject \"includeNodeModules\": true or the aliases will be ignored.\n\tcat require/parcel2/package.json | sed '/^\\}/d' > bench/rome/parcel2/package.json\n\techo ', \"engines\": { \"node\": \"14.0.0\" }' >> bench/rome/parcel2/package.json\n\techo ', \"targets\": { \"main\": { \"includeNodeModules\": true, \"optimize\": true } }' >> bench/rome/parcel2/package.json\n\techo ', $(ROME_PARCEL_ALIASES) }' >> bench/rome/parcel2/package.json\n\n\t# Parcel's minifier preserves all comments in the source code by default.\n\t# Removing comments in the minified output requires a config file.\n\techo '{ \"format\": { \"comments\": false } }' > bench/rome/parcel2/.terserrc\n\n\tcd bench/rome/parcel2 && time -p node_modules/.bin/parcel build entry.ts --dist-dir . --cache-dir .cache\n\tdu -h bench/rome/parcel2/entry.js*\n\tcd bench/rome-verify && rm -fr parcel2 && ROME_CACHE=0 node ../rome/parcel2/entry.js bundle packages/rome parcel2\n\n################################################################################\n# React admin benchmark (measures performance of an application-like setup)\n\nREADMIN_HTML = <meta charset=utf8><div id=root></div><script src=index.js type=module></script>\n\ngithub/react-admin:\n\tmkdir -p github\n\tgit clone --depth 1 --branch v4.6.1 https://github.com/marmelab/react-admin.git github/react-admin\n\nbench/readmin: | github/react-admin\n\tmkdir -p bench/readmin\n\tcp -r github/react-admin bench/readmin/repo\n\tcd bench/readmin/repo && yarn # This takes approximately forever\n\nbench-readmin: bench-readmin-esbuild\n\nREADMIN_ESBUILD_FLAGS += --alias:data-generator-retail=./bench/readmin/repo/examples/data-generator/src\nREADMIN_ESBUILD_FLAGS += --alias:ra-core=./bench/readmin/repo/packages/ra-core/src\nREADMIN_ESBUILD_FLAGS += --alias:ra-data-fakerest=./bench/readmin/repo/packages/ra-data-fakerest/src\nREADMIN_ESBUILD_FLAGS += --alias:ra-data-graphql-simple=./bench/readmin/repo/packages/ra-data-graphql-simple/src\nREADMIN_ESBUILD_FLAGS += --alias:ra-data-graphql=./bench/readmin/repo/packages/ra-data-graphql/src\nREADMIN_ESBUILD_FLAGS += --alias:ra-data-simple-rest=./bench/readmin/repo/packages/ra-data-simple-rest/src\nREADMIN_ESBUILD_FLAGS += --alias:ra-i18n-polyglot=./bench/readmin/repo/packages/ra-i18n-polyglot/src\nREADMIN_ESBUILD_FLAGS += --alias:ra-input-rich-text=./bench/readmin/repo/packages/ra-input-rich-text/src\nREADMIN_ESBUILD_FLAGS += --alias:ra-language-english=./bench/readmin/repo/packages/ra-language-english/src\nREADMIN_ESBUILD_FLAGS += --alias:ra-language-french=./bench/readmin/repo/packages/ra-language-french/src\nREADMIN_ESBUILD_FLAGS += --alias:ra-ui-materialui=./bench/readmin/repo/packages/ra-ui-materialui/src\nREADMIN_ESBUILD_FLAGS += --alias:react-admin=./bench/readmin/repo/packages/react-admin/src\nREADMIN_ESBUILD_FLAGS += --bundle\nREADMIN_ESBUILD_FLAGS += --define:process.env.REACT_APP_DATA_PROVIDER=null\nREADMIN_ESBUILD_FLAGS += --format=esm\nREADMIN_ESBUILD_FLAGS += --loader:.png=file\nREADMIN_ESBUILD_FLAGS += --loader:.svg=file\nREADMIN_ESBUILD_FLAGS += --minify\nREADMIN_ESBUILD_FLAGS += --sourcemap\nREADMIN_ESBUILD_FLAGS += --splitting\nREADMIN_ESBUILD_FLAGS += --target=esnext\nREADMIN_ESBUILD_FLAGS += --timing\nREADMIN_ESBUILD_FLAGS += bench/readmin/repo/examples/demo/src/index.tsx\n\nbench-readmin-esbuild: esbuild | bench/readmin\n\trm -fr bench/readmin/esbuild\n\ttime -p ./esbuild $(READMIN_ESBUILD_FLAGS) --outdir=bench/readmin/esbuild\n\techo \"$(READMIN_HTML)\" > bench/readmin/esbuild/index.html\n\tdu -h bench/readmin/esbuild/index.js*\n\tshasum bench/readmin/esbuild/index.js*\n\nbench-readmin-eswasm: platform-wasm | bench/readmin\n\trm -fr bench/readmin/eswasm\n\ttime -p ./npm/esbuild-wasm/bin/esbuild $(READMIN_ESBUILD_FLAGS) --outdir=bench/readmin/eswasm\n\techo \"$(READMIN_HTML)\" > bench/readmin/eswasm/index.html\n\tdu -h bench/readmin/eswasm/index.js*\n\tshasum bench/readmin/eswasm/index.js*\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"./images/wordmark-dark.svg\">\n    <source media=\"(prefers-color-scheme: light)\" srcset=\"./images/wordmark-light.svg\">\n    <img alt=\"esbuild: An extremely fast JavaScript bundler\" src=\"./images/wordmark-light.svg\">\n  </picture>\n  <br>\n  <a href=\"https://esbuild.github.io/\">Website</a> |\n  <a href=\"https://esbuild.github.io/getting-started/\">Getting started</a> |\n  <a href=\"https://esbuild.github.io/api/\">Documentation</a> |\n  <a href=\"https://esbuild.github.io/plugins/\">Plugins</a> |\n  <a href=\"https://esbuild.github.io/faq/\">FAQ</a>\n</p>\n\n## Why?\n\nOur current build tools for the web are 10-100x slower than they could be:\n\n<p align=\"center\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"./images/benchmark-dark.svg\">\n    <source media=\"(prefers-color-scheme: light)\" srcset=\"./images/benchmark-light.svg\">\n    <img alt=\"Bar chart with benchmark results\" src=\"./images/benchmark-light.svg\">\n  </picture>\n</p>\n\nThe main goal of the esbuild bundler project is to bring about a new era of build tool performance, and create an easy-to-use modern bundler along the way.\n\nMajor features:\n\n- Extreme speed without needing a cache\n- [JavaScript](https://esbuild.github.io/content-types/#javascript), [CSS](https://esbuild.github.io/content-types/#css), [TypeScript](https://esbuild.github.io/content-types/#typescript), and [JSX](https://esbuild.github.io/content-types/#jsx) built-in\n- A straightforward [API](https://esbuild.github.io/api/) for CLI, JS, and Go\n- Bundles ESM and CommonJS modules\n- Bundles CSS including [CSS modules](https://github.com/css-modules/css-modules)\n- Tree shaking, [minification](https://esbuild.github.io/api/#minify), and [source maps](https://esbuild.github.io/api/#sourcemap)\n- [Local server](https://esbuild.github.io/api/#serve), [watch mode](https://esbuild.github.io/api/#watch), and [plugins](https://esbuild.github.io/plugins/)\n\nCheck out the [getting started](https://esbuild.github.io/getting-started/) instructions if you want to give esbuild a try.\n"
  },
  {
    "path": "RUNBOOK.md",
    "content": "# Runbook\n\nThis documents some maintenance tasks for esbuild so I don't forget how they\nwork. There are a lot of moving parts now that esbuild uses trusted publishing.\n\n## Publishing a release\n\nPublishing a release is now done by using GitHub Actions as a\n[trusted publisher](https://docs.npmjs.com/trusted-publishers).\nTo publish a new release:\n\n1. Update the version in [`version.txt`](./version.txt). Only include the number. Do not include a leading `v`.\n2. Copy that version verbatim (without the leading `v`) to a `##` header in [`CHANGELOG.md`](./CHANGELOG.md). This usually replaces the `## Unreleased` header used for unreleased changes.\n3. Run `make platform-all` to update the version number in all `package.json` files. The publishing workflow will fail without this step.\n4. Commit and push using a message such as `publish 0.X.Y to npm`. This should trigger the publishing workflow described below.\n\nPushing a change to [`version.txt`](./version.txt) causes the following:\n\n- The [`publish.yml`](./.github/workflows/publish.yml) workflow in this repo\n  will be triggered, which will:\n\n    1. Build and publish all npm packages to npm using trusted publishing\n    2. Create a tag for the release that looks like `v0.X.Y`\n    3. Publish a [GitHub Release](https://github.com/evanw/esbuild/releases) containing the release notes in [`CHANGELOG.md`](./CHANGELOG.md)\n\n- The [`release.yml`](https://github.com/esbuild/deno-esbuild/blob/main/.github/workflows/release.yml)\n  workflow in the https://github.com/esbuild/deno-esbuild repo runs\n  occasionally. On the next run, it will notice the version change and:\n\n    1. Clone this repo\n    2. Run `make platform-deno`\n    3. Commit and push the new contents of the `deno` folder to the `deno-esbuild` repo\n    4. Create a tag for the release that looks like `v0.X.Y`\n    5. Post an event to the https://api.deno.land/webhook/gh/esbuild webhook\n    6. Deno will then add a new version to https://deno.land/x/esbuild\n\n    You can also manually trigger this workflow if you want it to happen immediately.\n\n- The [`release.yml`](https://github.com/esbuild/esbuild.github.io/blob/main/.github/workflows/release.yml)\n  workflow in the https://github.com/esbuild/esbuild.github.io repo runs\n  occasionally. On the next run, it will notice the version change and:\n\n    1. Create a new `dl/v0.X.Y` script for the new version number\n    2. Update the `dl/latest` script with the new version number\n    3. Commit and push these new scripts to the `gh-pages` branch of the `esbuild.github.io` repo\n    4. GitHub Pages will then deploy these updates to https://esbuild.github.io/\n\n    You can also manually trigger this workflow if you want it to happen immediately.\n\n## Adding a new package\n\nEach platform (operating system + architecture) needs a separate optional npm\npackage due to how esbuild's installer works. New packages should be created\nunder the `@esbuild/` scope so it's obvious that they are official.\n\nCreate a directory for the new package inside the [`npm/@esbuild`](./npm/@esbuild/)\ndirectory. Then modify the rest of the repo to reference the new package. The\nspecifics for what to modify depends on the platform, but a good place to\nstart is to search for the name of a similar existing package and see where\nit's used.\n\nIn addition, you'll need to prepare that package for the next release. To do\nthat:\n\n1. Create an empty package with the expected name and a version of 0.0.1\n2. Publish it with `npm publish --access public` (note that scoped packages are private by default)\n3. Log in to the npm website and go to the package settings\n4. Ensure that the only maintainer is the [esbuild](https://www.npmjs.com/~esbuild) user\n5. Add the GitHub repo as the trusted publisher:\n    - **Organization or user:** `evanw`\n    - **Repository:** `esbuild`\n    - **Workflow filename:** `publish.yml`\n6. Ensure publishing access is set to **Require two-factor authentication and disallow tokens (recommended)**\n"
  },
  {
    "path": "cmd/esbuild/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/evanw/esbuild/internal/api_helpers\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/pkg/cli\"\n)\n\nvar helpText = func(colors logger.Colors) string {\n\t// Read \"NO_COLOR\" from the environment. This is a convention that some\n\t// software follows. See https://no-color.org/ for more information.\n\tif _, ok := os.LookupEnv(\"NO_COLOR\"); ok {\n\t\tcolors = logger.Colors{}\n\t}\n\n\treturn `\n` + colors.Bold + `Usage:` + colors.Reset + `\n  esbuild [options] [entry points]\n\n` + colors.Bold + `Documentation:` + colors.Reset + `\n  ` + colors.Underline + `https://esbuild.github.io/` + colors.Reset + `\n\n` + colors.Bold + `Repository:` + colors.Reset + `\n  ` + colors.Underline + `https://github.com/evanw/esbuild` + colors.Reset + `\n\n` + colors.Bold + `Simple options:` + colors.Reset + `\n  --bundle              Bundle all dependencies into the output files\n  --define:K=V          Substitute K with V while parsing\n  --external:M          Exclude module M from the bundle (can use * wildcards)\n  --format=...          Output format (iife | cjs | esm, no default when not\n                        bundling, otherwise default is iife when platform\n                        is browser and cjs when platform is node)\n  --loader:X=L          Use loader L to load file extension X, where L is\n                        one of: base64 | binary | copy | css | dataurl |\n                        empty | file | global-css | js | json | jsx |\n                        local-css | text | ts | tsx\n  --minify              Minify the output (sets all --minify-* flags)\n  --outdir=...          The output directory (for multiple entry points)\n  --outfile=...         The output file (for one entry point)\n  --packages=...        Set to \"external\" to avoid bundling any package\n  --platform=...        Platform target (browser | node | neutral,\n                        default browser)\n  --serve=...           Start a local HTTP server on this host:port for outputs\n  --sourcemap           Emit a source map\n  --splitting           Enable code splitting (currently only for esm)\n  --target=...          Environment target (e.g. es2017, chrome58, firefox57,\n                        safari11, edge16, node10, ie9, opera45, default esnext)\n  --watch               Watch mode: rebuild on file system changes (stops when\n                        stdin is closed, use \"--watch=forever\" to ignore stdin)\n\n` + colors.Bold + `Advanced options:` + colors.Reset + `\n  --abs-paths=...           Emit absolute instead of relative paths in these\n                            situations (code | log | metafile)\n  --allow-overwrite         Allow output files to overwrite input files\n  --analyze                 Print a report about the contents of the bundle\n                            (use \"--analyze=verbose\" for a detailed report)\n  --asset-names=...         Path template to use for \"file\" loader files\n                            (default \"[name]-[hash]\")\n  --banner:T=...            Text to be prepended to each output file of type T\n                            where T is one of: css | js\n  --certfile=...            Certificate for serving HTTPS (see also \"--keyfile\")\n  --charset=utf8            Do not escape UTF-8 code points\n  --chunk-names=...         Path template to use for code splitting chunks\n                            (default \"[name]-[hash]\")\n  --color=...               Force use of color terminal escapes (true | false)\n  --cors-origin=...         Allow cross-origin requests from this origin\n  --drop:...                Remove certain constructs (console | debugger)\n  --drop-labels=...         Remove labeled statements with these label names\n  --entry-names=...         Path template to use for entry point output paths\n                            (default \"[dir]/[name]\", can also use \"[hash]\")\n  --footer:T=...            Text to be appended to each output file of type T\n                            where T is one of: css | js\n  --global-name=...         The name of the global for the IIFE format\n  --ignore-annotations      Enable this to work with packages that have\n                            incorrect tree-shaking annotations\n  --inject:F                Import the file F into all input files and\n                            automatically replace matching globals with imports\n  --jsx-dev                 Use React's automatic runtime in development mode\n  --jsx-factory=...         What to use for JSX instead of React.createElement\n  --jsx-fragment=...        What to use for JSX instead of React.Fragment\n  --jsx-import-source=...   Override the package name for the automatic runtime\n                            (default \"react\")\n  --jsx-side-effects        Do not remove unused JSX expressions\n  --jsx=...                 Set to \"automatic\" to use React's automatic runtime\n                            or to \"preserve\" to disable transforming JSX to JS\n  --keep-names              Preserve \"name\" on functions and classes\n  --keyfile=...             Key for serving HTTPS (see also \"--certfile\")\n  --legal-comments=...      Where to place legal comments (none | inline |\n                            eof | linked | external, default eof when bundling\n                            and inline otherwise)\n  --line-limit=...          Lines longer than this will be wrap onto a new line\n  --log-level=...           Disable logging (verbose | debug | info | warning |\n                            error | silent, default info)\n  --log-limit=...           Maximum message count or 0 to disable (default 6)\n  --log-override:X=Y        Use log level Y for log messages with identifier X\n  --main-fields=...         Override the main file order in package.json\n                            (default \"browser,module,main\" when platform is\n                            browser and \"main,module\" when platform is node)\n  --mangle-cache=...        Save \"mangle props\" decisions to a JSON file\n  --mangle-props=...        Rename all properties matching a regular expression\n  --mangle-quoted=...       Enable renaming of quoted properties (true | false)\n  --metafile=...            Write metadata about the build to a JSON file\n                            (see also: ` + colors.Underline + `https://esbuild.github.io/analyze/` + colors.Reset + `)\n  --minify-whitespace       Remove whitespace in output files\n  --minify-identifiers      Shorten identifiers in output files\n  --minify-syntax           Use equivalent but shorter syntax in output files\n  --out-extension:.js=.mjs  Use a custom output extension instead of \".js\"\n  --outbase=...             The base path used to determine entry point output\n                            paths (for multiple entry points)\n  --preserve-symlinks       Disable symlink resolution for module lookup\n  --public-path=...         Set the base URL for the \"file\" loader\n  --pure:N                  Mark the name N as a pure function for tree shaking\n  --reserve-props=...       Do not mangle these properties\n  --resolve-extensions=...  A comma-separated list of implicit extensions\n                            (default \".tsx,.ts,.jsx,.js,.css,.json\")\n  --serve-fallback=...      Serve this HTML page when the request doesn't match\n  --servedir=...            What to serve in addition to generated output files\n  --source-root=...         Sets the \"sourceRoot\" field in generated source maps\n  --sourcefile=...          Set the source file for the source map (for stdin)\n  --sourcemap=external      Do not link to the source map with a comment\n  --sourcemap=inline        Emit the source map with an inline data URL\n  --sources-content=false   Omit \"sourcesContent\" in generated source maps\n  --supported:F=...         Consider syntax F to be supported (true | false)\n  --tree-shaking=...        Force tree shaking on or off (false | true)\n  --tsconfig=...            Use this tsconfig.json file instead of other ones\n  --tsconfig-raw=...        Override all tsconfig.json files with this string\n  --version                 Print the current version (` + esbuildVersion + `) and exit\n  --watch-delay=...         Wait before watch mode rebuilds (in milliseconds)\n\n` + colors.Bold + `Examples:` + colors.Reset + `\n  ` + colors.Dim + `# Produces dist/entry_point.js and dist/entry_point.js.map` + colors.Reset + `\n  esbuild --bundle entry_point.js --outdir=dist --minify --sourcemap\n\n  ` + colors.Dim + `# Allow JSX syntax in .js files` + colors.Reset + `\n  esbuild --bundle entry_point.js --outfile=out.js --loader:.js=jsx\n\n  ` + colors.Dim + `# Substitute the identifier RELEASE for the literal true` + colors.Reset + `\n  esbuild example.js --outfile=out.js --define:RELEASE=true\n\n  ` + colors.Dim + `# Provide input via stdin, get output via stdout` + colors.Reset + `\n  esbuild --minify --loader=ts < input.ts > output.js\n\n  ` + colors.Dim + `# Automatically rebuild when input files are changed` + colors.Reset + `\n  esbuild app.ts --bundle --watch\n\n  ` + colors.Dim + `# Start a local HTTP server for everything in \"www\"` + colors.Reset + `\n  esbuild app.ts --bundle --servedir=www --outdir=www/js\n\n`\n}\n\nfunc main() {\n\tlogger.API = logger.CLIAPI\n\n\tosArgs := os.Args[1:]\n\theapFile := \"\"\n\ttraceFile := \"\"\n\tcpuprofileFile := \"\"\n\tisRunningService := false\n\tsendPings := false\n\tisWatch := false\n\tisWatchForever := false\n\tisServe := false\n\n\t// Do an initial scan over the argument list\n\targsEnd := 0\n\tfor _, arg := range osArgs {\n\t\tswitch {\n\t\t// Show help if a common help flag is provided\n\t\tcase arg == \"-h\", arg == \"-help\", arg == \"--help\", arg == \"/?\":\n\t\t\tlogger.PrintText(os.Stdout, logger.LevelSilent, os.Args, helpText)\n\t\t\tos.Exit(0)\n\n\t\t// Special-case the version flag here\n\t\tcase arg == \"--version\":\n\t\t\tfmt.Printf(\"%s\\n\", esbuildVersion)\n\t\t\tos.Exit(0)\n\n\t\tcase strings.HasPrefix(arg, \"--heap=\"):\n\t\t\theapFile = arg[len(\"--heap=\"):]\n\n\t\tcase strings.HasPrefix(arg, \"--trace=\"):\n\t\t\ttraceFile = arg[len(\"--trace=\"):]\n\n\t\tcase strings.HasPrefix(arg, \"--timing\"):\n\t\t\t// This is a hidden flag because it's only intended for debugging esbuild\n\t\t\t// itself. The output is not documented and not stable.\n\t\t\tapi_helpers.UseTimer = true\n\n\t\tcase strings.HasPrefix(arg, \"--cpuprofile=\"):\n\t\t\tcpuprofileFile = arg[len(\"--cpuprofile=\"):]\n\n\t\t// This flag turns the process into a long-running service that uses\n\t\t// message passing with the host process over stdin/stdout\n\t\tcase strings.HasPrefix(arg, \"--service=\"):\n\t\t\thostVersion := arg[len(\"--service=\"):]\n\t\t\tisRunningService = true\n\n\t\t\t// Validate the host's version number to make sure esbuild was installed\n\t\t\t// correctly. This check was added because some people have reported\n\t\t\t// errors that appear to indicate an incorrect installation.\n\t\t\tif hostVersion != esbuildVersion {\n\t\t\t\tlogger.PrintErrorToStderr(osArgs,\n\t\t\t\t\tfmt.Sprintf(\"Cannot start service: Host version %q does not match binary version %q\",\n\t\t\t\t\t\thostVersion, esbuildVersion))\n\t\t\t\tos.Exit(1)\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--ping\"):\n\t\t\tsendPings = true\n\n\t\tdefault:\n\t\t\t// Some people want to be able to run esbuild's watch mode such that it\n\t\t\t// never exits. However, esbuild ends watch mode when stdin is closed\n\t\t\t// because stdin is always closed when the parent process terminates, so\n\t\t\t// ending watch mode when stdin is closed is a good way to avoid\n\t\t\t// accidentally creating esbuild processes that live forever.\n\t\t\t//\n\t\t\t// Explicitly allow processes that live forever with \"--watch=forever\".\n\t\t\t// This may be a reasonable thing to do in a short-lived VM where all\n\t\t\t// processes in the VM are only started once and then the VM is killed\n\t\t\t// when the processes are no longer needed.\n\t\t\tif arg == \"--watch\" || arg == \"--watch=true\" {\n\t\t\t\tisWatch = true\n\t\t\t} else if arg == \"--watch=forever\" {\n\t\t\t\targ = \"--watch\"\n\t\t\t\tisWatch = true\n\t\t\t\tisWatchForever = true\n\t\t\t} else if arg == \"--serve\" ||\n\t\t\t\tstrings.HasPrefix(arg, \"--serve=\") ||\n\t\t\t\tstrings.HasPrefix(arg, \"--servedir=\") ||\n\t\t\t\tstrings.HasPrefix(arg, \"--serve-fallback=\") {\n\t\t\t\tisServe = true\n\t\t\t}\n\n\t\t\t// Strip any arguments that were handled above\n\t\t\tosArgs[argsEnd] = arg\n\t\t\targsEnd++\n\t\t}\n\t}\n\tosArgs = osArgs[:argsEnd]\n\n\t// Run in service mode if requested\n\tif isRunningService {\n\t\trunService(sendPings)\n\t\treturn\n\t}\n\n\t// Print help text when there are no arguments\n\tisStdinTTY := logger.GetTerminalInfo(os.Stdin).IsTTY\n\tif len(osArgs) == 0 && isStdinTTY {\n\t\tlogger.PrintText(os.Stdout, logger.LevelSilent, osArgs, helpText)\n\t\tos.Exit(0)\n\t}\n\n\t// Capture the defer statements below so the \"done\" message comes last\n\texitCode := 1\n\tfunc() {\n\t\t// To view a CPU trace, use \"go tool trace [file]\". Note that the trace\n\t\t// viewer doesn't work under Windows Subsystem for Linux for some reason.\n\t\tif traceFile != \"\" {\n\t\t\tif done := createTraceFile(osArgs, traceFile); done == nil {\n\t\t\t\treturn\n\t\t\t} else {\n\t\t\t\tdefer done()\n\t\t\t}\n\t\t}\n\n\t\t// To view a heap trace, use \"go tool pprof [file]\" and type \"top\". You can\n\t\t// also drop it into https://speedscope.app and use the \"left heavy\" or\n\t\t// \"sandwich\" view modes.\n\t\tif heapFile != \"\" {\n\t\t\tif done := createHeapFile(osArgs, heapFile); done == nil {\n\t\t\t\treturn\n\t\t\t} else {\n\t\t\t\tdefer done()\n\t\t\t}\n\t\t}\n\n\t\t// To view a CPU profile, drop the file into https://speedscope.app.\n\t\t// Note: Running the CPU profiler doesn't work under Windows subsystem for\n\t\t// Linux. The profiler has to be built for native Windows and run using the\n\t\t// command prompt instead.\n\t\tif cpuprofileFile != \"\" {\n\t\t\tif done := createCpuprofileFile(osArgs, cpuprofileFile); done == nil {\n\t\t\t\treturn\n\t\t\t} else {\n\t\t\t\tdefer done()\n\t\t\t}\n\t\t}\n\n\t\tif cpuprofileFile != \"\" {\n\t\t\t// The CPU profiler in Go only runs at 100 Hz, which is far too slow to\n\t\t\t// return useful information for esbuild, since it's so fast. Let's keep\n\t\t\t// running for 30 seconds straight, which should give us 3,000 samples.\n\t\t\tseconds := 30.0\n\t\t\tstart := time.Now()\n\t\t\tfor time.Since(start).Seconds() < seconds {\n\t\t\t\texitCode = cli.Run(osArgs)\n\t\t\t}\n\t\t} else {\n\t\t\tif !isWatch && !isServe {\n\t\t\t\t// If this is not a long-running process and there is at most a single\n\t\t\t\t// entry point, then disable the GC since we're just going to allocate\n\t\t\t\t// a bunch of memory and then exit anyway. This speedup is not\n\t\t\t\t// insignificant. We don't do this when there are multiple entry points\n\t\t\t\t// since otherwise esbuild could unnecessarily use much more memory\n\t\t\t\t// than it might otherwise need to process many entry points.\n\t\t\t\tnonFlagCount := 0\n\t\t\t\tfor _, arg := range osArgs {\n\t\t\t\t\tif !strings.HasPrefix(arg, \"-\") {\n\t\t\t\t\t\tnonFlagCount++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif nonFlagCount <= 1 {\n\t\t\t\t\tdebug.SetGCPercent(-1)\n\t\t\t\t}\n\t\t\t} else if isServe && isServeUnsupported() {\n\t\t\t\t// The development server isn't supported on WebAssembly, so we will\n\t\t\t\t// immediately call \"os.Exit(1)\" below, which will call \"process.exit(1)\"\n\t\t\t\t// in node. However, node has a bug/feature where any pending calls to\n\t\t\t\t// \"fs.read(process.stdin.fd)\" hold up \"process.exit()\" without seemingly\n\t\t\t\t// any way to stop this from happening. So to avoid this bug/feature,\n\t\t\t\t// we explicitly avoid listening to stdin in this case (when we know\n\t\t\t\t// that we are about to exit due to an invalid flag).\n\t\t\t} else if !isStdinTTY && !isWatchForever {\n\t\t\t\t// If stdin isn't a TTY, watch stdin and abort in case it is closed.\n\t\t\t\t// This is necessary when the esbuild binary executable is invoked via\n\t\t\t\t// the Erlang VM, which doesn't provide a way to exit a child process.\n\t\t\t\t// See: https://github.com/brunch/brunch/issues/920.\n\t\t\t\t//\n\t\t\t\t// We don't do this when stdin is a TTY because that interferes with\n\t\t\t\t// the Unix background job system. If we read from stdin then Ctrl+Z\n\t\t\t\t// to move the process to the background will incorrectly cause the\n\t\t\t\t// job to stop. See: https://github.com/brunch/brunch/issues/998.\n\t\t\t\tgo func() {\n\t\t\t\t\t// This just discards information from stdin because we don't use\n\t\t\t\t\t// it and we can avoid unnecessarily allocating space for it\n\t\t\t\t\tbuffer := make([]byte, 512)\n\t\t\t\t\tfor {\n\t\t\t\t\t\t_, err := os.Stdin.Read(buffer)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\tif options := logger.OutputOptionsForArgs(osArgs); options.LogLevel <= logger.LevelInfo {\n\t\t\t\t\t\t\t\tif isWatch {\n\t\t\t\t\t\t\t\t\t// Mention why watch mode was stopped to reduce confusion, and\n\t\t\t\t\t\t\t\t\t// call out \"--watch=forever\" to get the alternative behavior\n\t\t\t\t\t\t\t\t\tlogger.PrintTextWithColor(os.Stderr, options.Color, func(colors logger.Colors) string {\n\t\t\t\t\t\t\t\t\t\treturn fmt.Sprintf(\"%s[watch] stopped automatically because stdin was closed (use \\\"--watch=forever\\\" to keep watching even after stdin is closed)%s\\n\", colors.Dim, colors.Reset)\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t} else if isServe {\n\t\t\t\t\t\t\t\t\tlogger.PrintTextWithColor(os.Stderr, options.Color, func(colors logger.Colors) string {\n\t\t\t\t\t\t\t\t\t\treturn fmt.Sprintf(\"%s[serve] stopped automatically because stdin was closed (keep stdin open to continue serving)%s\\n\", colors.Dim, colors.Reset)\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Only exit cleanly if stdin was closed cleanly\n\t\t\t\t\t\t\tif err == io.EOF {\n\t\t\t\t\t\t\t\tos.Exit(0)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tos.Exit(1)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Some people attempt to keep esbuild's watch mode open by piping\n\t\t\t\t\t\t// an infinite stream of data to stdin such as with \"< /dev/zero\".\n\t\t\t\t\t\t// This will make esbuild spin at 100% CPU. To avoid this, put a\n\t\t\t\t\t\t// small delay after we read some data from stdin.\n\t\t\t\t\t\ttime.Sleep(4 * time.Millisecond)\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\n\t\t\texitCode = cli.Run(osArgs)\n\t\t}\n\t}()\n\n\tos.Exit(exitCode)\n}\n"
  },
  {
    "path": "cmd/esbuild/main_other.go",
    "content": "//go:build !js || !wasm\n// +build !js !wasm\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"runtime/pprof\"\n\t\"runtime/trace\"\n\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\nfunc createTraceFile(osArgs []string, traceFile string) func() {\n\tf, err := os.Create(traceFile)\n\tif err != nil {\n\t\tlogger.PrintErrorToStderr(osArgs, fmt.Sprintf(\n\t\t\t\"Failed to create trace file: %s\", err.Error()))\n\t\treturn nil\n\t}\n\ttrace.Start(f)\n\treturn func() {\n\t\ttrace.Stop()\n\t\tf.Close()\n\t}\n}\n\nfunc createHeapFile(osArgs []string, heapFile string) func() {\n\tf, err := os.Create(heapFile)\n\tif err != nil {\n\t\tlogger.PrintErrorToStderr(osArgs, fmt.Sprintf(\n\t\t\t\"Failed to create heap file: %s\", err.Error()))\n\t\treturn nil\n\t}\n\treturn func() {\n\t\tif err := pprof.WriteHeapProfile(f); err != nil {\n\t\t\tlogger.PrintErrorToStderr(osArgs, fmt.Sprintf(\n\t\t\t\t\"Failed to write heap profile: %s\", err.Error()))\n\t\t}\n\t\tf.Close()\n\t}\n}\n\nfunc createCpuprofileFile(osArgs []string, cpuprofileFile string) func() {\n\tf, err := os.Create(cpuprofileFile)\n\tif err != nil {\n\t\tlogger.PrintErrorToStderr(osArgs, fmt.Sprintf(\n\t\t\t\"Failed to create cpuprofile file: %s\", err.Error()))\n\t\treturn nil\n\t}\n\tpprof.StartCPUProfile(f)\n\treturn func() {\n\t\tpprof.StopCPUProfile()\n\t\tf.Close()\n\t}\n}\n\nfunc isServeUnsupported() bool {\n\treturn false\n}\n"
  },
  {
    "path": "cmd/esbuild/main_wasm.go",
    "content": "//go:build js && wasm\n// +build js,wasm\n\npackage main\n\nimport (\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\n// Remove this code from the WebAssembly binary to reduce size. This only removes 0.4mb of stuff.\n\nfunc createTraceFile(osArgs []string, traceFile string) func() {\n\tlogger.PrintErrorToStderr(osArgs, \"The \\\"--trace\\\" flag is not supported when using WebAssembly\")\n\treturn nil\n}\n\nfunc createHeapFile(osArgs []string, heapFile string) func() {\n\tlogger.PrintErrorToStderr(osArgs, \"The \\\"--heap\\\" flag is not supported when using WebAssembly\")\n\treturn nil\n}\n\nfunc createCpuprofileFile(osArgs []string, cpuprofileFile string) func() {\n\tlogger.PrintErrorToStderr(osArgs, \"The \\\"--cpuprofile\\\" flag is not supported when using WebAssembly\")\n\treturn nil\n}\n\nfunc isServeUnsupported() bool {\n\treturn true\n}\n"
  },
  {
    "path": "cmd/esbuild/service.go",
    "content": "// This implements a simple long-running service over stdin/stdout. Each\n// incoming request is an array of strings, and each outgoing response is a map\n// of strings to byte slices. All values are length-prefixed using 32-bit\n// little endian integers.\n\npackage main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"regexp\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/evanw/esbuild/internal/cli_helpers\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/fs\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/pkg/api\"\n\t\"github.com/evanw/esbuild/pkg/cli\"\n)\n\ntype responseCallback func(interface{})\ntype pluginResolveCallback func(uint32, map[string]interface{}) []byte\n\ntype activeBuild struct {\n\tctx              api.BuildContext\n\tpluginResolve    pluginResolveCallback\n\tmutex            sync.Mutex\n\tdisposeWaitGroup sync.WaitGroup // Allows \"dispose\" to wait for all active tasks\n\n\t// These are guarded by the mutex\n\trebuildWaitGroup   *sync.WaitGroup // Allows \"cancel\" to wait for all active rebuilds (within mutex because \"sync.WaitGroup\" isn't thread-safe)\n\twithinRebuildCount int\n\tdidGetCancel       bool\n}\n\ntype serviceType struct {\n\tcallbacks          map[uint32]responseCallback\n\tactiveBuilds       map[int]*activeBuild\n\toutgoingPackets    chan []byte // Always use \"sendPacket\" instead of sending on this channel\n\tkeepAliveWaitGroup *helpers.ThreadSafeWaitGroup\n\tmutex              sync.Mutex\n\tnextRequestID      uint32\n}\n\nfunc (service *serviceType) getActiveBuild(key int) *activeBuild {\n\tservice.mutex.Lock()\n\tactiveBuild := service.activeBuilds[key]\n\tservice.mutex.Unlock()\n\treturn activeBuild\n}\n\nfunc (service *serviceType) createActiveBuild(key int) *activeBuild {\n\tservice.mutex.Lock()\n\tdefer service.mutex.Unlock()\n\tif service.activeBuilds[key] != nil {\n\t\tpanic(\"Internal error\")\n\t}\n\tactiveBuild := &activeBuild{}\n\tservice.activeBuilds[key] = activeBuild\n\n\t// This pairs with \"Done()\" in \"decRefCount\"\n\tservice.keepAliveWaitGroup.Add(1)\n\treturn activeBuild\n}\n\nfunc (service *serviceType) destroyActiveBuild(key int) {\n\tservice.mutex.Lock()\n\tif service.activeBuilds[key] == nil {\n\t\tpanic(\"Internal error\")\n\t}\n\tdelete(service.activeBuilds, key)\n\tservice.mutex.Unlock()\n\n\t// This pairs with \"Add()\" in \"trackActiveBuild\"\n\tservice.keepAliveWaitGroup.Done()\n}\n\nfunc runService(sendPings bool) {\n\tlogger.API = logger.JSAPI\n\n\tservice := serviceType{\n\t\tcallbacks:          make(map[uint32]responseCallback),\n\t\tactiveBuilds:       make(map[int]*activeBuild),\n\t\toutgoingPackets:    make(chan []byte),\n\t\tkeepAliveWaitGroup: helpers.MakeThreadSafeWaitGroup(),\n\t}\n\tbuffer := make([]byte, 16*1024)\n\tstream := []byte{}\n\n\t// Write packets on a single goroutine so they aren't interleaved\n\tgo func() {\n\t\tfor packet := range service.outgoingPackets {\n\t\t\tif _, err := os.Stdout.Write(packet); err != nil {\n\t\t\t\tos.Exit(1) // I/O error\n\t\t\t}\n\t\t\tservice.keepAliveWaitGroup.Done() // This pairs with the \"Add()\" when putting stuff into \"outgoingPackets\"\n\t\t}\n\t}()\n\n\t// The protocol always starts with the version\n\tos.Stdout.Write(append(writeUint32(nil, uint32(len(esbuildVersion))), esbuildVersion...))\n\n\t// Wait for the last response to be written to stdout before returning from\n\t// the enclosing function, which will return from \"main()\" and exit.\n\tservice.keepAliveWaitGroup.Add(1)\n\tdefer func() {\n\t\tservice.keepAliveWaitGroup.Done()\n\t\tservice.keepAliveWaitGroup.Wait()\n\t}()\n\n\t// Periodically ping the host even when we're idle. This will catch cases\n\t// where the host has disappeared and will never send us anything else but\n\t// we incorrectly think we are still needed. In that case we will now try\n\t// to write to stdout and fail, and then know that we should exit.\n\tif sendPings {\n\t\tgo func() {\n\t\t\tfor {\n\t\t\t\ttime.Sleep(1 * time.Second)\n\t\t\t\tservice.sendRequest(map[string]interface{}{\n\t\t\t\t\t\"command\": \"ping\",\n\t\t\t\t})\n\t\t\t}\n\t\t}()\n\t}\n\n\tfor {\n\t\t// Read more data from stdin\n\t\tn, err := os.Stdin.Read(buffer)\n\t\tif n == 0 || err == io.EOF {\n\t\t\tbreak // End of stdin\n\t\t}\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tstream = append(stream, buffer[:n]...)\n\n\t\t// Process all complete (i.e. not partial) packets\n\t\tbytes := stream\n\t\tfor {\n\t\t\tpacket, afterPacket, ok := readLengthPrefixedSlice(bytes)\n\t\t\tif !ok {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tbytes = afterPacket\n\n\t\t\t// Clone the input since slices into it may be used on another goroutine\n\t\t\tclone := append([]byte{}, packet...)\n\t\t\tservice.handleIncomingPacket(clone)\n\t\t}\n\n\t\t// Move the remaining partial packet to the end to avoid reallocating\n\t\tstream = append(stream[:0], bytes...)\n\t}\n}\n\n// Each packet added to \"outgoingPackets\" must also add to the wait group\nfunc (service *serviceType) sendPacket(packet []byte) {\n\tservice.keepAliveWaitGroup.Add(1) // The writer thread will call \"Done()\"\n\tservice.outgoingPackets <- packet\n}\n\n// This will either block until the request has been sent and a response has\n// been received, or it will return nil to indicate failure to send due to\n// stdin being closed.\nfunc (service *serviceType) sendRequest(request interface{}) interface{} {\n\tresult := make(chan interface{})\n\tvar id uint32\n\tcallback := func(response interface{}) {\n\t\tresult <- response\n\t\tclose(result)\n\t}\n\tid = func() uint32 {\n\t\tservice.mutex.Lock()\n\t\tdefer service.mutex.Unlock()\n\t\tid := service.nextRequestID\n\t\tservice.nextRequestID++\n\t\tservice.callbacks[id] = callback\n\t\treturn id\n\t}()\n\n\tservice.sendPacket(encodePacket(packet{\n\t\tid:        id,\n\t\tisRequest: true,\n\t\tvalue:     request,\n\t}))\n\treturn <-result\n}\n\n// This function deliberately processes incoming packets sequentially on the\n// same goroutine as the caller. We want calling \"dispose\" on a context to take\n// effect immediately and to fail all future calls on that context. We don't\n// want \"dispose\" to accidentally be reordered after any future calls on that\n// context, since those future calls are supposed to fail.\n//\n// If processing a packet could potentially take a while, then the remainder of\n// the work should be run on another goroutine after decoding the command.\nfunc (service *serviceType) handleIncomingPacket(bytes []byte) {\n\tp, ok := decodePacket(bytes)\n\tif !ok {\n\t\treturn\n\t}\n\n\tif !p.isRequest {\n\t\tservice.mutex.Lock()\n\t\tcallback := service.callbacks[p.id]\n\t\tdelete(service.callbacks, p.id)\n\t\tservice.mutex.Unlock()\n\n\t\tif callback == nil {\n\t\t\tpanic(fmt.Sprintf(\"callback nil for id %d, value %v\", p.id, p.value))\n\t\t}\n\n\t\tservice.keepAliveWaitGroup.Add(1)\n\t\tgo func() {\n\t\t\tdefer service.keepAliveWaitGroup.Done()\n\t\t\tcallback(p.value)\n\t\t}()\n\t\treturn\n\t}\n\n\t// Handle the request\n\trequest := p.value.(map[string]interface{})\n\tcommand := request[\"command\"].(string)\n\tswitch command {\n\tcase \"build\":\n\t\tservice.keepAliveWaitGroup.Add(1)\n\t\tgo func() {\n\t\t\tdefer service.keepAliveWaitGroup.Done()\n\t\t\tservice.sendPacket(service.handleBuildRequest(p.id, request))\n\t\t}()\n\n\tcase \"transform\":\n\t\tservice.keepAliveWaitGroup.Add(1)\n\t\tgo func() {\n\t\t\tdefer service.keepAliveWaitGroup.Done()\n\t\t\tservice.sendPacket(service.handleTransformRequest(p.id, request))\n\t\t}()\n\n\tcase \"resolve\":\n\t\tkey := request[\"key\"].(int)\n\t\tif build := service.getActiveBuild(key); build != nil {\n\t\t\tbuild.mutex.Lock()\n\t\t\tctx := build.ctx\n\t\t\tpluginResolve := build.pluginResolve\n\t\t\tif ctx != nil && pluginResolve != nil {\n\t\t\t\tbuild.disposeWaitGroup.Add(1)\n\t\t\t}\n\t\t\tbuild.mutex.Unlock()\n\t\t\tif pluginResolve != nil {\n\t\t\t\tservice.keepAliveWaitGroup.Add(1)\n\t\t\t\tgo func() {\n\t\t\t\t\tdefer service.keepAliveWaitGroup.Done()\n\t\t\t\t\tif ctx != nil {\n\t\t\t\t\t\tdefer build.disposeWaitGroup.Done()\n\t\t\t\t\t}\n\t\t\t\t\tservice.sendPacket(pluginResolve(p.id, request))\n\t\t\t\t}()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tservice.sendPacket(encodePacket(packet{\n\t\t\tid: p.id,\n\t\t\tvalue: map[string]interface{}{\n\t\t\t\t\"error\": \"Cannot call \\\"resolve\\\" on an inactive build\",\n\t\t\t},\n\t\t}))\n\n\tcase \"rebuild\":\n\t\tkey := request[\"key\"].(int)\n\t\tif build := service.getActiveBuild(key); build != nil {\n\t\t\tbuild.mutex.Lock()\n\t\t\tctx := build.ctx\n\t\t\tif ctx != nil {\n\t\t\t\tbuild.withinRebuildCount++\n\t\t\t\tif build.rebuildWaitGroup == nil {\n\t\t\t\t\tbuild.rebuildWaitGroup = &sync.WaitGroup{}\n\t\t\t\t}\n\t\t\t\tbuild.rebuildWaitGroup.Add(1)\n\t\t\t\tbuild.disposeWaitGroup.Add(1)\n\t\t\t}\n\t\t\tbuild.mutex.Unlock()\n\t\t\tif ctx != nil {\n\t\t\t\tservice.keepAliveWaitGroup.Add(1)\n\t\t\t\tgo func() {\n\t\t\t\t\tdefer service.keepAliveWaitGroup.Done()\n\t\t\t\t\tdefer build.disposeWaitGroup.Done()\n\t\t\t\t\tresult := ctx.Rebuild()\n\t\t\t\t\tbuild.mutex.Lock()\n\t\t\t\t\tbuild.withinRebuildCount--\n\t\t\t\t\tbuild.rebuildWaitGroup.Done()\n\t\t\t\t\tif build.withinRebuildCount == 0 {\n\t\t\t\t\t\t// Clear the cancel flag now that the last rebuild has finished\n\t\t\t\t\t\tbuild.didGetCancel = false\n\n\t\t\t\t\t\t// Clear this to avoid confusion with the next group of rebuilds\n\t\t\t\t\t\tbuild.rebuildWaitGroup = nil\n\t\t\t\t\t}\n\t\t\t\t\tbuild.mutex.Unlock()\n\t\t\t\t\tservice.sendPacket(encodePacket(packet{\n\t\t\t\t\t\tid: p.id,\n\t\t\t\t\t\tvalue: map[string]interface{}{\n\t\t\t\t\t\t\t\"errors\":   encodeMessages(result.Errors),\n\t\t\t\t\t\t\t\"warnings\": encodeMessages(result.Warnings),\n\t\t\t\t\t\t},\n\t\t\t\t\t}))\n\t\t\t\t}()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tservice.sendPacket(encodePacket(packet{\n\t\t\tid: p.id,\n\t\t\tvalue: map[string]interface{}{\n\t\t\t\t\"error\": \"Cannot rebuild\",\n\t\t\t},\n\t\t}))\n\n\tcase \"watch\":\n\t\tkey := request[\"key\"].(int)\n\t\tif build := service.getActiveBuild(key); build != nil {\n\t\t\tbuild.mutex.Lock()\n\t\t\tctx := build.ctx\n\t\t\tif ctx != nil {\n\t\t\t\tbuild.disposeWaitGroup.Add(1)\n\t\t\t}\n\t\t\tbuild.mutex.Unlock()\n\t\t\tif ctx != nil {\n\t\t\t\tservice.keepAliveWaitGroup.Add(1)\n\t\t\t\tgo func() {\n\t\t\t\t\tdefer service.keepAliveWaitGroup.Done()\n\t\t\t\t\tdefer build.disposeWaitGroup.Done()\n\t\t\t\t\tvar options api.WatchOptions\n\t\t\t\t\tif value, ok := request[\"delay\"]; ok {\n\t\t\t\t\t\toptions.Delay = value.(int)\n\t\t\t\t\t}\n\t\t\t\t\tif err := ctx.Watch(options); err != nil {\n\t\t\t\t\t\tservice.sendPacket(encodeErrorPacket(p.id, err))\n\t\t\t\t\t} else {\n\t\t\t\t\t\tservice.sendPacket(encodePacket(packet{\n\t\t\t\t\t\t\tid:    p.id,\n\t\t\t\t\t\t\tvalue: make(map[string]interface{}),\n\t\t\t\t\t\t}))\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tservice.sendPacket(encodePacket(packet{\n\t\t\tid: p.id,\n\t\t\tvalue: map[string]interface{}{\n\t\t\t\t\"error\": \"Cannot watch\",\n\t\t\t},\n\t\t}))\n\n\tcase \"serve\":\n\t\tkey := request[\"key\"].(int)\n\t\tif build := service.getActiveBuild(key); build != nil {\n\t\t\tbuild.mutex.Lock()\n\t\t\tctx := build.ctx\n\t\t\tif ctx != nil {\n\t\t\t\tbuild.disposeWaitGroup.Add(1)\n\t\t\t}\n\t\t\tbuild.mutex.Unlock()\n\t\t\tif ctx != nil {\n\t\t\t\tservice.keepAliveWaitGroup.Add(1)\n\t\t\t\tgo func() {\n\t\t\t\t\tdefer service.keepAliveWaitGroup.Done()\n\t\t\t\t\tdefer build.disposeWaitGroup.Done()\n\t\t\t\t\tvar options api.ServeOptions\n\t\t\t\t\tif value, ok := request[\"host\"]; ok {\n\t\t\t\t\t\toptions.Host = value.(string)\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := request[\"port\"]; ok {\n\t\t\t\t\t\tif value == 0 {\n\t\t\t\t\t\t\t// 0 is the default value in Go, which we interpret as \"try to\n\t\t\t\t\t\t\t// pick port 8000\". So Go uses -1 as the sentinel value instead.\n\t\t\t\t\t\t\toptions.Port = -1\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\toptions.Port = value.(int)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := request[\"servedir\"]; ok {\n\t\t\t\t\t\toptions.Servedir = value.(string)\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := request[\"keyfile\"]; ok {\n\t\t\t\t\t\toptions.Keyfile = value.(string)\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := request[\"certfile\"]; ok {\n\t\t\t\t\t\toptions.Certfile = value.(string)\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := request[\"fallback\"]; ok {\n\t\t\t\t\t\toptions.Fallback = value.(string)\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := request[\"corsOrigin\"].([]interface{}); ok {\n\t\t\t\t\t\tfor _, it := range value {\n\t\t\t\t\t\t\toptions.CORS.Origin = append(options.CORS.Origin, it.(string))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif request[\"onRequest\"].(bool) {\n\t\t\t\t\t\toptions.OnRequest = func(args api.ServeOnRequestArgs) {\n\t\t\t\t\t\t\t// This could potentially be called after we return from\n\t\t\t\t\t\t\t// \"Dispose()\". If it does, then make sure we don't call into\n\t\t\t\t\t\t\t// JavaScript because we'll get an error. Also make sure that\n\t\t\t\t\t\t\t// if we do call into JavaScript, we wait to call \"Dispose()\"\n\t\t\t\t\t\t\t// until JavaScript has returned back to us.\n\t\t\t\t\t\t\tbuild.mutex.Lock()\n\t\t\t\t\t\t\tctx := build.ctx\n\t\t\t\t\t\t\tif ctx != nil {\n\t\t\t\t\t\t\t\tbuild.disposeWaitGroup.Add(1)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbuild.mutex.Unlock()\n\t\t\t\t\t\t\tif ctx != nil {\n\t\t\t\t\t\t\t\tservice.sendRequest(map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\"command\": \"serve-request\",\n\t\t\t\t\t\t\t\t\t\"key\":     key,\n\t\t\t\t\t\t\t\t\t\"args\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\t\t\"remoteAddress\": args.RemoteAddress,\n\t\t\t\t\t\t\t\t\t\t\"method\":        args.Method,\n\t\t\t\t\t\t\t\t\t\t\"path\":          args.Path,\n\t\t\t\t\t\t\t\t\t\t\"status\":        args.Status,\n\t\t\t\t\t\t\t\t\t\t\"timeInMS\":      args.TimeInMS,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\tbuild.disposeWaitGroup.Done()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif result, err := ctx.Serve(options); err != nil {\n\t\t\t\t\t\tservice.sendPacket(encodeErrorPacket(p.id, err))\n\t\t\t\t\t} else {\n\t\t\t\t\t\thosts := make([]interface{}, len(result.Hosts))\n\t\t\t\t\t\tfor i, host := range result.Hosts {\n\t\t\t\t\t\t\thosts[i] = host\n\t\t\t\t\t\t}\n\t\t\t\t\t\tservice.sendPacket(encodePacket(packet{\n\t\t\t\t\t\t\tid: p.id,\n\t\t\t\t\t\t\tvalue: map[string]interface{}{\n\t\t\t\t\t\t\t\t\"port\":  int(result.Port),\n\t\t\t\t\t\t\t\t\"hosts\": hosts,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}))\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tservice.sendPacket(encodePacket(packet{\n\t\t\tid: p.id,\n\t\t\tvalue: map[string]interface{}{\n\t\t\t\t\"error\": \"Cannot serve\",\n\t\t\t},\n\t\t}))\n\n\tcase \"cancel\":\n\t\tkey := request[\"key\"].(int)\n\t\tif build := service.getActiveBuild(key); build != nil {\n\t\t\tbuild.mutex.Lock()\n\t\t\tctx := build.ctx\n\t\t\trebuildWaitGroup := build.rebuildWaitGroup\n\t\t\tif build.withinRebuildCount > 0 {\n\t\t\t\t// If Go got a \"rebuild\" message from JS before this, there's a chance\n\t\t\t\t// that Go hasn't run \"ctx.Rebuild()\" by the time our \"ctx.Cancel()\"\n\t\t\t\t// runs below because both of them are on separate goroutines. To\n\t\t\t\t// handle this, we set this flag to tell our \"OnStart\" plugin to cancel\n\t\t\t\t// the build in case things happen in that order.\n\t\t\t\tbuild.didGetCancel = true\n\t\t\t}\n\t\t\tbuild.mutex.Unlock()\n\t\t\tif ctx != nil {\n\t\t\t\tservice.keepAliveWaitGroup.Add(1)\n\t\t\t\tgo func() {\n\t\t\t\t\tdefer service.keepAliveWaitGroup.Done()\n\t\t\t\t\tctx.Cancel()\n\n\t\t\t\t\t// Block until all manual rebuilds that were active at the time the\n\t\t\t\t\t// \"cancel\" packet was originally processed have finished. That way\n\t\t\t\t\t// JS can wait for \"cancel\" to end and be assured that it can call\n\t\t\t\t\t// \"rebuild\" and have it not merge with any other ongoing rebuilds.\n\t\t\t\t\tif rebuildWaitGroup != nil {\n\t\t\t\t\t\trebuildWaitGroup.Wait()\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only return control to JavaScript once the cancel operation has succeeded\n\t\t\t\t\tservice.sendPacket(encodePacket(packet{\n\t\t\t\t\t\tid:    p.id,\n\t\t\t\t\t\tvalue: make(map[string]interface{}),\n\t\t\t\t\t}))\n\t\t\t\t}()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tservice.sendPacket(encodePacket(packet{\n\t\t\tid:    p.id,\n\t\t\tvalue: make(map[string]interface{}),\n\t\t}))\n\n\tcase \"dispose\":\n\t\tkey := request[\"key\"].(int)\n\t\tif build := service.getActiveBuild(key); build != nil {\n\t\t\tbuild.mutex.Lock()\n\t\t\tctx := build.ctx\n\t\t\tbuild.ctx = nil\n\t\t\tbuild.mutex.Unlock()\n\n\t\t\t// Release this ref count if it was held\n\t\t\tif ctx != nil {\n\t\t\t\tservice.keepAliveWaitGroup.Add(1)\n\t\t\t\tgo func() {\n\t\t\t\t\tdefer service.keepAliveWaitGroup.Done()\n\n\t\t\t\t\t// While \"Dispose()\" will wait for any existing operations on the\n\t\t\t\t\t// context to finish, we also don't want to start any new operations.\n\t\t\t\t\t// That can happen because operations (e.g. \"Rebuild()\") are started\n\t\t\t\t\t// from a separate goroutine without locking the build mutex. This\n\t\t\t\t\t// uses a WaitGroup to handle this case. If that happened, then we'll\n\t\t\t\t\t// wait for it here before disposing. Once the wait is over, no more\n\t\t\t\t\t// operations can happen on the context because we have already\n\t\t\t\t\t// zeroed out the shared context pointer above.\n\t\t\t\t\tbuild.disposeWaitGroup.Done()\n\t\t\t\t\tbuild.disposeWaitGroup.Wait()\n\n\t\t\t\t\tctx.Dispose()\n\t\t\t\t\tservice.destroyActiveBuild(key)\n\n\t\t\t\t\t// Only return control to JavaScript once everything relating to this\n\t\t\t\t\t// build has gracefully ended. Otherwise JavaScript will unregister\n\t\t\t\t\t// everything related to this build and any calls an ongoing build\n\t\t\t\t\t// makes into JavaScript will cause errors, which may be observable.\n\t\t\t\t\tservice.sendPacket(encodePacket(packet{\n\t\t\t\t\t\tid:    p.id,\n\t\t\t\t\t\tvalue: make(map[string]interface{}),\n\t\t\t\t\t}))\n\t\t\t\t}()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tservice.sendPacket(encodePacket(packet{\n\t\t\tid:    p.id,\n\t\t\tvalue: make(map[string]interface{}),\n\t\t}))\n\n\tcase \"error\":\n\t\tservice.keepAliveWaitGroup.Add(1)\n\t\tgo func() {\n\t\t\tdefer service.keepAliveWaitGroup.Done()\n\n\t\t\t// This just exists so that errors during JavaScript API setup get printed\n\t\t\t// nicely to the console. This matters if the JavaScript API setup code\n\t\t\t// swallows thrown errors. We still want to be able to see the error.\n\t\t\tflags := decodeStringArray(request[\"flags\"].([]interface{}))\n\t\t\tmsg := decodeMessageToPrivate(request[\"error\"].(map[string]interface{}))\n\t\t\tlogger.PrintMessageToStderr(flags, msg)\n\t\t\tservice.sendPacket(encodePacket(packet{\n\t\t\t\tid:    p.id,\n\t\t\t\tvalue: make(map[string]interface{}),\n\t\t\t}))\n\t\t}()\n\n\tcase \"format-msgs\":\n\t\tservice.keepAliveWaitGroup.Add(1)\n\t\tgo func() {\n\t\t\tdefer service.keepAliveWaitGroup.Done()\n\t\t\tservice.sendPacket(service.handleFormatMessagesRequest(p.id, request))\n\t\t}()\n\n\tcase \"analyze-metafile\":\n\t\tservice.keepAliveWaitGroup.Add(1)\n\t\tgo func() {\n\t\t\tdefer service.keepAliveWaitGroup.Done()\n\t\t\tservice.sendPacket(service.handleAnalyzeMetafileRequest(p.id, request))\n\t\t}()\n\n\tdefault:\n\t\tservice.sendPacket(encodePacket(packet{\n\t\t\tid: p.id,\n\t\t\tvalue: map[string]interface{}{\n\t\t\t\t\"error\": fmt.Sprintf(\"Invalid command: %s\", command),\n\t\t\t},\n\t\t}))\n\t}\n}\n\nfunc encodeErrorPacket(id uint32, err error) []byte {\n\treturn encodePacket(packet{\n\t\tid: id,\n\t\tvalue: map[string]interface{}{\n\t\t\t\"error\": err.Error(),\n\t\t},\n\t})\n}\n\nfunc (service *serviceType) handleBuildRequest(id uint32, request map[string]interface{}) []byte {\n\tisContext := request[\"context\"].(bool)\n\tkey := request[\"key\"].(int)\n\twrite := request[\"write\"].(bool)\n\tentries := request[\"entries\"].([]interface{})\n\tflags := decodeStringArray(request[\"flags\"].([]interface{}))\n\n\toptions, err := cli.ParseBuildOptions(flags)\n\toptions.AbsWorkingDir = request[\"absWorkingDir\"].(string)\n\toptions.NodePaths = decodeStringArray(request[\"nodePaths\"].([]interface{}))\n\toptions.MangleCache, _ = request[\"mangleCache\"].(map[string]interface{})\n\n\tfor _, entry := range entries {\n\t\tentry := entry.([]interface{})\n\t\tkey := entry[0].(string)\n\t\tvalue := entry[1].(string)\n\t\toptions.EntryPointsAdvanced = append(options.EntryPointsAdvanced, api.EntryPoint{\n\t\t\tOutputPath: key,\n\t\t\tInputPath:  value,\n\t\t})\n\t}\n\n\t// Normally when \"write\" is true and there is no output file/directory then\n\t// the output is written to stdout instead. However, we're currently using\n\t// stdout as a communication channel and writing the build output to stdout\n\t// would corrupt our protocol. Special-case this to channel this back to the\n\t// host process and write it to stdout there.\n\twriteToStdout := err == nil && write && options.Outfile == \"\" && options.Outdir == \"\"\n\n\tif err != nil {\n\t\treturn encodeErrorPacket(id, err)\n\t}\n\n\t// Optionally allow input from the stdin channel\n\tif stdin, ok := request[\"stdinContents\"].([]byte); ok {\n\t\tif options.Stdin == nil {\n\t\t\toptions.Stdin = &api.StdinOptions{}\n\t\t}\n\t\toptions.Stdin.Contents = string(stdin)\n\t\tif resolveDir, ok := request[\"stdinResolveDir\"].(string); ok {\n\t\t\toptions.Stdin.ResolveDir = resolveDir\n\t\t}\n\t}\n\n\tactiveBuild := service.createActiveBuild(key)\n\n\thasOnEndCallbacks := false\n\tif plugins, ok := request[\"plugins\"]; ok {\n\t\tif plugins, hasOnEnd, err := service.convertPlugins(key, plugins, activeBuild); err != nil {\n\t\t\treturn encodeErrorPacket(id, err)\n\t\t} else {\n\t\t\toptions.Plugins = plugins\n\t\t\thasOnEndCallbacks = hasOnEnd\n\t\t}\n\t}\n\n\tresultToResponse := func(result api.BuildResult) map[string]interface{} {\n\t\tresponse := map[string]interface{}{\n\t\t\t\"errors\":   encodeMessages(result.Errors),\n\t\t\t\"warnings\": encodeMessages(result.Warnings),\n\t\t}\n\t\tif !write {\n\t\t\t// Pass the output files back to the caller\n\t\t\tresponse[\"outputFiles\"] = encodeOutputFiles(result.OutputFiles)\n\t\t}\n\t\tif options.Metafile {\n\t\t\tresponse[\"metafile\"] = []byte(result.Metafile)\n\t\t}\n\t\tif options.MangleCache != nil {\n\t\t\tresponse[\"mangleCache\"] = result.MangleCache\n\t\t}\n\t\tif writeToStdout && len(result.OutputFiles) == 1 {\n\t\t\tresponse[\"writeToStdout\"] = result.OutputFiles[0].Contents\n\t\t}\n\t\treturn response\n\t}\n\n\tif !writeToStdout {\n\t\toptions.Write = write\n\t}\n\n\tif isContext {\n\t\toptions.Plugins = append(options.Plugins, api.Plugin{\n\t\t\tName: \"onEnd\",\n\t\t\tSetup: func(build api.PluginBuild) {\n\t\t\t\tbuild.OnStart(func() (api.OnStartResult, error) {\n\t\t\t\t\tactiveBuild.mutex.Lock()\n\t\t\t\t\tif currentWaitGroup := activeBuild.rebuildWaitGroup; currentWaitGroup != nil && activeBuild.didGetCancel {\n\t\t\t\t\t\t// Cancel the current build now that the current build is active.\n\t\t\t\t\t\t// This catches the case where JS does \"rebuild()\" then \"cancel()\"\n\t\t\t\t\t\t// but Go's scheduler runs the original \"ctx.Cancel()\" goroutine\n\t\t\t\t\t\t// before it runs the \"ctx.Rebuild()\" goroutine.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// This adds to the rebuild wait group that other cancel operations\n\t\t\t\t\t\t// are waiting on because we also want those other cancel operations\n\t\t\t\t\t\t// to wait on this cancel operation. Go might schedule this new\n\t\t\t\t\t\t// goroutine after all currently-active rebuilds end. We don't want\n\t\t\t\t\t\t// the user's cancel operation to return to the user and for them\n\t\t\t\t\t\t// to start another rebuild before our \"ctx.Cancel\" below runs\n\t\t\t\t\t\t// because our cancel is supposed to cancel the current build, not\n\t\t\t\t\t\t// some independent future build.\n\t\t\t\t\t\tactiveBuild.rebuildWaitGroup.Add(1)\n\t\t\t\t\t\tgo func() {\n\t\t\t\t\t\t\tactiveBuild.ctx.Cancel()\n\n\t\t\t\t\t\t\t// Lock the mutex because \"sync.WaitGroup\" isn't thread-safe.\n\t\t\t\t\t\t\t// But use the wait group that was active at the time the\n\t\t\t\t\t\t\t// \"OnStart\" callback ran instead of the latest one on the\n\t\t\t\t\t\t\t// active build in case this goroutine is delayed.\n\t\t\t\t\t\t\tactiveBuild.mutex.Lock()\n\t\t\t\t\t\t\tcurrentWaitGroup.Done()\n\t\t\t\t\t\t\tactiveBuild.mutex.Unlock()\n\t\t\t\t\t\t}()\n\t\t\t\t\t}\n\t\t\t\t\tactiveBuild.mutex.Unlock()\n\t\t\t\t\treturn api.OnStartResult{}, nil\n\t\t\t\t})\n\n\t\t\t\tbuild.OnEnd(func(result *api.BuildResult) (api.OnEndResult, error) {\n\t\t\t\t\t// For performance, we only send JavaScript an \"onEnd\" message if\n\t\t\t\t\t// it's needed. It's only needed if one of the following is true:\n\t\t\t\t\t//\n\t\t\t\t\t// - There are any \"onEnd\" callbacks registered\n\t\t\t\t\t// - JavaScript has called our \"rebuild()\" function\n\t\t\t\t\t// - We are writing build output to JavaScript's stdout\n\t\t\t\t\t//\n\t\t\t\t\t// This is especially important if \"write\" is false since otherwise\n\t\t\t\t\t// we'd unnecessarily send the entire contents of all output files!\n\t\t\t\t\t//\n\t\t\t\t\t//          \"If a tree falls in a forest and no one is\n\t\t\t\t\t//           around to hear it, does it make a sound?\"\n\t\t\t\t\t//\n\t\t\t\t\tactiveBuild.mutex.Lock()\n\t\t\t\t\tisWithinRebuild := activeBuild.withinRebuildCount > 0\n\t\t\t\t\tactiveBuild.mutex.Unlock()\n\t\t\t\t\tif !hasOnEndCallbacks && !isWithinRebuild && !writeToStdout {\n\t\t\t\t\t\treturn api.OnEndResult{}, nil\n\t\t\t\t\t}\n\t\t\t\t\trequest := resultToResponse(*result)\n\t\t\t\t\trequest[\"command\"] = \"on-end\"\n\t\t\t\t\trequest[\"key\"] = key\n\t\t\t\t\tresponse, ok := service.sendRequest(request).(map[string]interface{})\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\treturn api.OnEndResult{}, errors.New(\"The service was stopped\")\n\t\t\t\t\t}\n\t\t\t\t\tvar errors []api.Message\n\t\t\t\t\tvar warnings []api.Message\n\t\t\t\t\tif value, ok := response[\"errors\"].([]interface{}); ok {\n\t\t\t\t\t\terrors = decodeMessages(value)\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"warnings\"].([]interface{}); ok {\n\t\t\t\t\t\twarnings = decodeMessages(value)\n\t\t\t\t\t}\n\t\t\t\t\treturn api.OnEndResult{\n\t\t\t\t\t\tErrors:   errors,\n\t\t\t\t\t\tWarnings: warnings,\n\t\t\t\t\t}, nil\n\t\t\t\t})\n\t\t\t},\n\t\t})\n\n\t\tctx, err := api.Context(options)\n\t\tif err != nil {\n\t\t\treturn encodePacket(packet{\n\t\t\t\tid: id,\n\t\t\t\tvalue: map[string]interface{}{\n\t\t\t\t\t\"errors\":   encodeMessages(err.Errors),\n\t\t\t\t\t\"warnings\": []interface{}{},\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\n\t\t// Keep the build alive until \"dispose\" has been called\n\t\tactiveBuild.disposeWaitGroup.Add(1)\n\t\tactiveBuild.ctx = ctx\n\n\t\treturn encodePacket(packet{\n\t\t\tid: id,\n\t\t\tvalue: map[string]interface{}{\n\t\t\t\t\"errors\":   []interface{}{},\n\t\t\t\t\"warnings\": []interface{}{},\n\t\t\t},\n\t\t})\n\t}\n\n\tresult := api.Build(options)\n\tresponse := resultToResponse(result)\n\n\tservice.destroyActiveBuild(key)\n\n\treturn encodePacket(packet{\n\t\tid:    id,\n\t\tvalue: response,\n\t})\n}\n\nfunc resolveKindToString(kind api.ResolveKind) string {\n\tswitch kind {\n\tcase api.ResolveEntryPoint:\n\t\treturn \"entry-point\"\n\n\t// JS\n\tcase api.ResolveJSImportStatement:\n\t\treturn \"import-statement\"\n\tcase api.ResolveJSRequireCall:\n\t\treturn \"require-call\"\n\tcase api.ResolveJSDynamicImport:\n\t\treturn \"dynamic-import\"\n\tcase api.ResolveJSRequireResolve:\n\t\treturn \"require-resolve\"\n\n\t// CSS\n\tcase api.ResolveCSSImportRule:\n\t\treturn \"import-rule\"\n\tcase api.ResolveCSSComposesFrom:\n\t\treturn \"composes-from\"\n\tcase api.ResolveCSSURLToken:\n\t\treturn \"url-token\"\n\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\nfunc stringToResolveKind(kind string) (api.ResolveKind, bool) {\n\tswitch kind {\n\tcase \"entry-point\":\n\t\treturn api.ResolveEntryPoint, true\n\n\t// JS\n\tcase \"import-statement\":\n\t\treturn api.ResolveJSImportStatement, true\n\tcase \"require-call\":\n\t\treturn api.ResolveJSRequireCall, true\n\tcase \"dynamic-import\":\n\t\treturn api.ResolveJSDynamicImport, true\n\tcase \"require-resolve\":\n\t\treturn api.ResolveJSRequireResolve, true\n\n\t// CSS\n\tcase \"import-rule\":\n\t\treturn api.ResolveCSSImportRule, true\n\tcase \"composes-from\":\n\t\treturn api.ResolveCSSComposesFrom, true\n\tcase \"url-token\":\n\t\treturn api.ResolveCSSURLToken, true\n\t}\n\n\treturn api.ResolveNone, false\n}\n\nfunc (service *serviceType) convertPlugins(key int, jsPlugins interface{}, activeBuild *activeBuild) ([]api.Plugin, bool, error) {\n\ttype filteredCallback struct {\n\t\tfilter     *regexp.Regexp\n\t\tpluginName string\n\t\tnamespace  string\n\t\tid         int\n\t}\n\n\tvar onResolveCallbacks []filteredCallback\n\tvar onLoadCallbacks []filteredCallback\n\thasOnEnd := false\n\n\tfilteredCallbacks := func(pluginName string, kind string, items []interface{}) (result []filteredCallback, err error) {\n\t\tfor _, item := range items {\n\t\t\titem := item.(map[string]interface{})\n\t\t\tfilter, err := config.CompileFilterForPlugin(pluginName, kind, item[\"filter\"].(string))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tresult = append(result, filteredCallback{\n\t\t\t\tpluginName: pluginName,\n\t\t\t\tid:         item[\"id\"].(int),\n\t\t\t\tfilter:     filter,\n\t\t\t\tnamespace:  item[\"namespace\"].(string),\n\t\t\t})\n\t\t}\n\t\treturn\n\t}\n\n\tfor _, p := range jsPlugins.([]interface{}) {\n\t\tp := p.(map[string]interface{})\n\t\tpluginName := p[\"name\"].(string)\n\n\t\tif p[\"onEnd\"].(bool) {\n\t\t\thasOnEnd = true\n\t\t}\n\n\t\tif callbacks, err := filteredCallbacks(pluginName, \"onResolve\", p[\"onResolve\"].([]interface{})); err != nil {\n\t\t\treturn nil, false, err\n\t\t} else {\n\t\t\tonResolveCallbacks = append(onResolveCallbacks, callbacks...)\n\t\t}\n\n\t\tif callbacks, err := filteredCallbacks(pluginName, \"onLoad\", p[\"onLoad\"].([]interface{})); err != nil {\n\t\t\treturn nil, false, err\n\t\t} else {\n\t\t\tonLoadCallbacks = append(onLoadCallbacks, callbacks...)\n\t\t}\n\t}\n\n\t// We want to minimize the amount of IPC traffic. Instead of adding one Go\n\t// plugin for every JavaScript plugin, we just add a single Go plugin that\n\t// proxies the plugin queries to the list of JavaScript plugins in the host.\n\treturn []api.Plugin{{\n\t\tName: \"JavaScript plugins\",\n\t\tSetup: func(build api.PluginBuild) {\n\t\t\tactiveBuild.mutex.Lock()\n\t\t\tactiveBuild.pluginResolve = func(id uint32, request map[string]interface{}) []byte {\n\t\t\t\tpath := request[\"path\"].(string)\n\t\t\t\tvar options api.ResolveOptions\n\t\t\t\tif value, ok := request[\"pluginName\"]; ok {\n\t\t\t\t\toptions.PluginName = value.(string)\n\t\t\t\t}\n\t\t\t\tif value, ok := request[\"importer\"]; ok {\n\t\t\t\t\toptions.Importer = value.(string)\n\t\t\t\t}\n\t\t\t\tif value, ok := request[\"namespace\"]; ok {\n\t\t\t\t\toptions.Namespace = value.(string)\n\t\t\t\t}\n\t\t\t\tif value, ok := request[\"resolveDir\"]; ok {\n\t\t\t\t\toptions.ResolveDir = value.(string)\n\t\t\t\t}\n\t\t\t\tif value, ok := request[\"kind\"]; ok {\n\t\t\t\t\tstr := value.(string)\n\t\t\t\t\tkind, ok := stringToResolveKind(str)\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\treturn encodePacket(packet{\n\t\t\t\t\t\t\tid: id,\n\t\t\t\t\t\t\tvalue: map[string]interface{}{\n\t\t\t\t\t\t\t\t\"error\": fmt.Sprintf(\"Invalid kind: %q\", str),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\toptions.Kind = kind\n\t\t\t\t}\n\t\t\t\tif value, ok := request[\"pluginData\"]; ok {\n\t\t\t\t\toptions.PluginData = value.(int)\n\t\t\t\t}\n\t\t\t\tif value, ok := request[\"with\"]; ok {\n\t\t\t\t\tvalue := value.(map[string]interface{})\n\t\t\t\t\toptions.With = make(map[string]string, len(value))\n\t\t\t\t\tfor k, v := range value {\n\t\t\t\t\t\toptions.With[k] = v.(string)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tresult := build.Resolve(path, options)\n\t\t\t\treturn encodePacket(packet{\n\t\t\t\t\tid: id,\n\t\t\t\t\tvalue: map[string]interface{}{\n\t\t\t\t\t\t\"errors\":      encodeMessages(result.Errors),\n\t\t\t\t\t\t\"warnings\":    encodeMessages(result.Warnings),\n\t\t\t\t\t\t\"path\":        result.Path,\n\t\t\t\t\t\t\"external\":    result.External,\n\t\t\t\t\t\t\"sideEffects\": result.SideEffects,\n\t\t\t\t\t\t\"namespace\":   result.Namespace,\n\t\t\t\t\t\t\"suffix\":      result.Suffix,\n\t\t\t\t\t\t\"pluginData\":  result.PluginData,\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}\n\t\t\tactiveBuild.mutex.Unlock()\n\n\t\t\t// Always register \"OnStart\" to clear \"pluginData\"\n\t\t\tbuild.OnStart(func() (api.OnStartResult, error) {\n\t\t\t\tresponse, ok := service.sendRequest(map[string]interface{}{\n\t\t\t\t\t\"command\": \"on-start\",\n\t\t\t\t\t\"key\":     key,\n\t\t\t\t}).(map[string]interface{})\n\t\t\t\tif !ok {\n\t\t\t\t\treturn api.OnStartResult{}, errors.New(\"The service was stopped\")\n\t\t\t\t}\n\t\t\t\treturn api.OnStartResult{\n\t\t\t\t\tErrors:   decodeMessages(response[\"errors\"].([]interface{})),\n\t\t\t\t\tWarnings: decodeMessages(response[\"warnings\"].([]interface{})),\n\t\t\t\t}, nil\n\t\t\t})\n\n\t\t\t// Only register \"OnResolve\" if needed\n\t\t\tif len(onResolveCallbacks) > 0 {\n\t\t\t\tbuild.OnResolve(api.OnResolveOptions{Filter: \".*\"}, func(args api.OnResolveArgs) (api.OnResolveResult, error) {\n\t\t\t\t\tvar ids []interface{}\n\t\t\t\t\tapplyPath := logger.Path{Text: args.Path, Namespace: args.Namespace}\n\t\t\t\t\tfor _, item := range onResolveCallbacks {\n\t\t\t\t\t\tif config.PluginAppliesToPath(applyPath, item.filter, item.namespace) {\n\t\t\t\t\t\t\tids = append(ids, item.id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresult := api.OnResolveResult{}\n\t\t\t\t\tif len(ids) == 0 {\n\t\t\t\t\t\treturn result, nil\n\t\t\t\t\t}\n\n\t\t\t\t\twith := make(map[string]interface{}, len(args.With))\n\t\t\t\t\tfor k, v := range args.With {\n\t\t\t\t\t\twith[k] = v\n\t\t\t\t\t}\n\n\t\t\t\t\tresponse, ok := service.sendRequest(map[string]interface{}{\n\t\t\t\t\t\t\"command\":    \"on-resolve\",\n\t\t\t\t\t\t\"key\":        key,\n\t\t\t\t\t\t\"ids\":        ids,\n\t\t\t\t\t\t\"path\":       args.Path,\n\t\t\t\t\t\t\"importer\":   args.Importer,\n\t\t\t\t\t\t\"namespace\":  args.Namespace,\n\t\t\t\t\t\t\"resolveDir\": args.ResolveDir,\n\t\t\t\t\t\t\"kind\":       resolveKindToString(args.Kind),\n\t\t\t\t\t\t\"pluginData\": args.PluginData,\n\t\t\t\t\t\t\"with\":       with,\n\t\t\t\t\t}).(map[string]interface{})\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\treturn result, errors.New(\"The service was stopped\")\n\t\t\t\t\t}\n\n\t\t\t\t\tif value, ok := response[\"id\"]; ok {\n\t\t\t\t\t\tid := value.(int)\n\t\t\t\t\t\tfor _, item := range onResolveCallbacks {\n\t\t\t\t\t\t\tif item.id == id {\n\t\t\t\t\t\t\t\tresult.PluginName = item.pluginName\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"error\"]; ok {\n\t\t\t\t\t\treturn result, errors.New(value.(string))\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"pluginName\"]; ok {\n\t\t\t\t\t\tresult.PluginName = value.(string)\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"path\"]; ok {\n\t\t\t\t\t\tresult.Path = value.(string)\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"namespace\"]; ok {\n\t\t\t\t\t\tresult.Namespace = value.(string)\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"suffix\"]; ok {\n\t\t\t\t\t\tresult.Suffix = value.(string)\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"external\"]; ok {\n\t\t\t\t\t\tresult.External = value.(bool)\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"sideEffects\"]; ok {\n\t\t\t\t\t\tif value.(bool) {\n\t\t\t\t\t\t\tresult.SideEffects = api.SideEffectsTrue\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresult.SideEffects = api.SideEffectsFalse\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"pluginData\"]; ok {\n\t\t\t\t\t\tresult.PluginData = value.(int)\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"errors\"]; ok {\n\t\t\t\t\t\tresult.Errors = decodeMessages(value.([]interface{}))\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"warnings\"]; ok {\n\t\t\t\t\t\tresult.Warnings = decodeMessages(value.([]interface{}))\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"watchFiles\"]; ok {\n\t\t\t\t\t\tresult.WatchFiles = decodeStringArray(value.([]interface{}))\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"watchDirs\"]; ok {\n\t\t\t\t\t\tresult.WatchDirs = decodeStringArray(value.([]interface{}))\n\t\t\t\t\t}\n\n\t\t\t\t\treturn result, nil\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Only register \"OnLoad\" if needed\n\t\t\tif len(onLoadCallbacks) > 0 {\n\t\t\t\tbuild.OnLoad(api.OnLoadOptions{Filter: \".*\"}, func(args api.OnLoadArgs) (api.OnLoadResult, error) {\n\t\t\t\t\tvar ids []interface{}\n\t\t\t\t\tapplyPath := logger.Path{Text: args.Path, Namespace: args.Namespace}\n\t\t\t\t\tfor _, item := range onLoadCallbacks {\n\t\t\t\t\t\tif config.PluginAppliesToPath(applyPath, item.filter, item.namespace) {\n\t\t\t\t\t\t\tids = append(ids, item.id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresult := api.OnLoadResult{}\n\t\t\t\t\tif len(ids) == 0 {\n\t\t\t\t\t\treturn result, nil\n\t\t\t\t\t}\n\n\t\t\t\t\twith := make(map[string]interface{}, len(args.With))\n\t\t\t\t\tfor k, v := range args.With {\n\t\t\t\t\t\twith[k] = v\n\t\t\t\t\t}\n\n\t\t\t\t\tresponse, ok := service.sendRequest(map[string]interface{}{\n\t\t\t\t\t\t\"command\":    \"on-load\",\n\t\t\t\t\t\t\"key\":        key,\n\t\t\t\t\t\t\"ids\":        ids,\n\t\t\t\t\t\t\"path\":       args.Path,\n\t\t\t\t\t\t\"namespace\":  args.Namespace,\n\t\t\t\t\t\t\"suffix\":     args.Suffix,\n\t\t\t\t\t\t\"pluginData\": args.PluginData,\n\t\t\t\t\t\t\"with\":       with,\n\t\t\t\t\t}).(map[string]interface{})\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\treturn result, errors.New(\"The service was stopped\")\n\t\t\t\t\t}\n\n\t\t\t\t\tif value, ok := response[\"id\"]; ok {\n\t\t\t\t\t\tid := value.(int)\n\t\t\t\t\t\tfor _, item := range onLoadCallbacks {\n\t\t\t\t\t\t\tif item.id == id {\n\t\t\t\t\t\t\t\tresult.PluginName = item.pluginName\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"error\"]; ok {\n\t\t\t\t\t\treturn result, errors.New(value.(string))\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"pluginName\"]; ok {\n\t\t\t\t\t\tresult.PluginName = value.(string)\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"loader\"]; ok {\n\t\t\t\t\t\tloader, err := cli_helpers.ParseLoader(value.(string))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn result, errors.New(err.Text)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresult.Loader = loader\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"contents\"]; ok {\n\t\t\t\t\t\tcontents := string(value.([]byte))\n\t\t\t\t\t\tresult.Contents = &contents\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"resolveDir\"]; ok {\n\t\t\t\t\t\tresult.ResolveDir = value.(string)\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"pluginData\"]; ok {\n\t\t\t\t\t\tresult.PluginData = value.(int)\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"errors\"]; ok {\n\t\t\t\t\t\tresult.Errors = decodeMessages(value.([]interface{}))\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"warnings\"]; ok {\n\t\t\t\t\t\tresult.Warnings = decodeMessages(value.([]interface{}))\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"watchFiles\"]; ok {\n\t\t\t\t\t\tresult.WatchFiles = decodeStringArray(value.([]interface{}))\n\t\t\t\t\t}\n\t\t\t\t\tif value, ok := response[\"watchDirs\"]; ok {\n\t\t\t\t\t\tresult.WatchDirs = decodeStringArray(value.([]interface{}))\n\t\t\t\t\t}\n\n\t\t\t\t\treturn result, nil\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\t}}, hasOnEnd, nil\n}\n\nfunc (service *serviceType) handleTransformRequest(id uint32, request map[string]interface{}) []byte {\n\tinputFS := request[\"inputFS\"].(bool)\n\tinput := string(request[\"input\"].([]byte))\n\tflags := decodeStringArray(request[\"flags\"].([]interface{}))\n\n\toptions, err := cli.ParseTransformOptions(flags)\n\tif err != nil {\n\t\treturn encodeErrorPacket(id, err)\n\t}\n\toptions.MangleCache, _ = request[\"mangleCache\"].(map[string]interface{})\n\n\ttransformInput := input\n\tif inputFS {\n\t\tfs.BeforeFileOpen()\n\t\tbytes, err := ioutil.ReadFile(input)\n\t\tfs.AfterFileClose()\n\t\tif err == nil {\n\t\t\terr = os.Remove(input)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn encodeErrorPacket(id, err)\n\t\t}\n\t\ttransformInput = string(bytes)\n\t}\n\n\tresult := api.Transform(transformInput, options)\n\tcodeFS := false\n\tmapFS := false\n\n\tif inputFS && len(result.Code) > 0 {\n\t\tfile := input + \".code\"\n\t\tfs.BeforeFileOpen()\n\t\tif err := ioutil.WriteFile(file, result.Code, 0644); err == nil {\n\t\t\tresult.Code = []byte(file)\n\t\t\tcodeFS = true\n\t\t}\n\t\tfs.AfterFileClose()\n\t}\n\n\tif inputFS && len(result.Map) > 0 {\n\t\tfile := input + \".map\"\n\t\tfs.BeforeFileOpen()\n\t\tif err := ioutil.WriteFile(file, result.Map, 0644); err == nil {\n\t\t\tresult.Map = []byte(file)\n\t\t\tmapFS = true\n\t\t}\n\t\tfs.AfterFileClose()\n\t}\n\n\tresponse := map[string]interface{}{\n\t\t\"errors\":   encodeMessages(result.Errors),\n\t\t\"warnings\": encodeMessages(result.Warnings),\n\n\t\t\"codeFS\": codeFS,\n\t\t\"code\":   string(result.Code),\n\n\t\t\"mapFS\": mapFS,\n\t\t\"map\":   string(result.Map),\n\t}\n\n\tif result.LegalComments != nil {\n\t\tresponse[\"legalComments\"] = string(result.LegalComments)\n\t}\n\n\tif result.MangleCache != nil {\n\t\tresponse[\"mangleCache\"] = result.MangleCache\n\t}\n\n\treturn encodePacket(packet{\n\t\tid:    id,\n\t\tvalue: response,\n\t})\n}\n\nfunc (service *serviceType) handleFormatMessagesRequest(id uint32, request map[string]interface{}) []byte {\n\tmsgs := decodeMessages(request[\"messages\"].([]interface{}))\n\n\toptions := api.FormatMessagesOptions{\n\t\tKind: api.ErrorMessage,\n\t}\n\tif request[\"isWarning\"].(bool) {\n\t\toptions.Kind = api.WarningMessage\n\t}\n\tif value, ok := request[\"color\"].(bool); ok {\n\t\toptions.Color = value\n\t}\n\tif value, ok := request[\"terminalWidth\"].(int); ok {\n\t\toptions.TerminalWidth = value\n\t}\n\n\tresult := api.FormatMessages(msgs, options)\n\n\treturn encodePacket(packet{\n\t\tid: id,\n\t\tvalue: map[string]interface{}{\n\t\t\t\"messages\": encodeStringArray(result),\n\t\t},\n\t})\n}\n\nfunc (service *serviceType) handleAnalyzeMetafileRequest(id uint32, request map[string]interface{}) []byte {\n\tmetafile := request[\"metafile\"].(string)\n\n\toptions := api.AnalyzeMetafileOptions{}\n\tif value, ok := request[\"color\"].(bool); ok {\n\t\toptions.Color = value\n\t}\n\tif value, ok := request[\"verbose\"].(bool); ok {\n\t\toptions.Verbose = value\n\t}\n\n\tresult := api.AnalyzeMetafile(metafile, options)\n\n\treturn encodePacket(packet{\n\t\tid: id,\n\t\tvalue: map[string]interface{}{\n\t\t\t\"result\": result,\n\t\t},\n\t})\n}\n\nfunc encodeStringArray(strings []string) []interface{} {\n\tvalues := make([]interface{}, len(strings))\n\tfor i, value := range strings {\n\t\tvalues[i] = value\n\t}\n\treturn values\n}\n\nfunc decodeStringArray(values []interface{}) []string {\n\tstrings := make([]string, len(values))\n\tfor i, value := range values {\n\t\tstrings[i] = value.(string)\n\t}\n\treturn strings\n}\n\nfunc encodeOutputFiles(outputFiles []api.OutputFile) []interface{} {\n\tvalues := make([]interface{}, len(outputFiles))\n\tfor i, outputFile := range outputFiles {\n\t\tvalues[i] = map[string]interface{}{\n\t\t\t\"path\":     outputFile.Path,\n\t\t\t\"contents\": outputFile.Contents,\n\t\t\t\"hash\":     outputFile.Hash,\n\t\t}\n\t}\n\treturn values\n}\n\nfunc encodeLocation(loc *api.Location) interface{} {\n\tif loc == nil {\n\t\treturn nil\n\t}\n\treturn map[string]interface{}{\n\t\t\"file\":       loc.File,\n\t\t\"namespace\":  loc.Namespace,\n\t\t\"line\":       loc.Line,\n\t\t\"column\":     loc.Column,\n\t\t\"length\":     loc.Length,\n\t\t\"lineText\":   loc.LineText,\n\t\t\"suggestion\": loc.Suggestion,\n\t}\n}\n\nfunc encodeMessages(msgs []api.Message) []interface{} {\n\tvalues := make([]interface{}, len(msgs))\n\tfor i, msg := range msgs {\n\t\tvalue := map[string]interface{}{\n\t\t\t\"id\":         msg.ID,\n\t\t\t\"pluginName\": msg.PluginName,\n\t\t\t\"text\":       msg.Text,\n\t\t\t\"location\":   encodeLocation(msg.Location),\n\t\t}\n\t\tvalues[i] = value\n\n\t\tnotes := make([]interface{}, len(msg.Notes))\n\t\tfor j, note := range msg.Notes {\n\t\t\tnotes[j] = map[string]interface{}{\n\t\t\t\t\"text\":     note.Text,\n\t\t\t\t\"location\": encodeLocation(note.Location),\n\t\t\t}\n\t\t}\n\t\tvalue[\"notes\"] = notes\n\n\t\t// Send \"-1\" to mean \"undefined\"\n\t\tdetail, ok := msg.Detail.(int)\n\t\tif !ok {\n\t\t\tdetail = -1\n\t\t}\n\t\tvalue[\"detail\"] = detail\n\t}\n\treturn values\n}\n\nfunc decodeLocation(value interface{}) *api.Location {\n\tif value == nil {\n\t\treturn nil\n\t}\n\tloc := value.(map[string]interface{})\n\tnamespace := loc[\"namespace\"].(string)\n\tif namespace == \"\" {\n\t\tnamespace = \"file\"\n\t}\n\treturn &api.Location{\n\t\tFile:       loc[\"file\"].(string),\n\t\tNamespace:  namespace,\n\t\tLine:       loc[\"line\"].(int),\n\t\tColumn:     loc[\"column\"].(int),\n\t\tLength:     loc[\"length\"].(int),\n\t\tLineText:   loc[\"lineText\"].(string),\n\t\tSuggestion: loc[\"suggestion\"].(string),\n\t}\n}\n\nfunc decodeMessages(values []interface{}) []api.Message {\n\tmsgs := make([]api.Message, len(values))\n\tfor i, value := range values {\n\t\tobj := value.(map[string]interface{})\n\t\tmsg := api.Message{\n\t\t\tID:         obj[\"id\"].(string),\n\t\t\tPluginName: obj[\"pluginName\"].(string),\n\t\t\tText:       obj[\"text\"].(string),\n\t\t\tLocation:   decodeLocation(obj[\"location\"]),\n\t\t\tDetail:     obj[\"detail\"].(int),\n\t\t}\n\t\tfor _, note := range obj[\"notes\"].([]interface{}) {\n\t\t\tnoteObj := note.(map[string]interface{})\n\t\t\tmsg.Notes = append(msg.Notes, api.Note{\n\t\t\t\tText:     noteObj[\"text\"].(string),\n\t\t\t\tLocation: decodeLocation(noteObj[\"location\"]),\n\t\t\t})\n\t\t}\n\t\tmsgs[i] = msg\n\t}\n\treturn msgs\n}\n\nfunc decodeLocationToPrivate(value interface{}) *logger.MsgLocation {\n\tif value == nil {\n\t\treturn nil\n\t}\n\tloc := value.(map[string]interface{})\n\tnamespace := loc[\"namespace\"].(string)\n\tif namespace == \"\" {\n\t\tnamespace = \"file\"\n\t}\n\tfile := loc[\"file\"].(string)\n\treturn &logger.MsgLocation{\n\t\tFile:       logger.PrettyPaths{Abs: file, Rel: file},\n\t\tNamespace:  namespace,\n\t\tLine:       loc[\"line\"].(int),\n\t\tColumn:     loc[\"column\"].(int),\n\t\tLength:     loc[\"length\"].(int),\n\t\tLineText:   loc[\"lineText\"].(string),\n\t\tSuggestion: loc[\"suggestion\"].(string),\n\t}\n}\n\nfunc decodeMessageToPrivate(obj map[string]interface{}) logger.Msg {\n\tmsg := logger.Msg{\n\t\tID:         logger.StringToMaximumMsgID(obj[\"id\"].(string)),\n\t\tPluginName: obj[\"pluginName\"].(string),\n\t\tData: logger.MsgData{\n\t\t\tText:       obj[\"text\"].(string),\n\t\t\tLocation:   decodeLocationToPrivate(obj[\"location\"]),\n\t\t\tUserDetail: obj[\"detail\"].(int),\n\t\t},\n\t}\n\tfor _, note := range obj[\"notes\"].([]interface{}) {\n\t\tnoteObj := note.(map[string]interface{})\n\t\tmsg.Notes = append(msg.Notes, logger.MsgData{\n\t\t\tText:     noteObj[\"text\"].(string),\n\t\t\tLocation: decodeLocationToPrivate(noteObj[\"location\"]),\n\t\t})\n\t}\n\treturn msg\n}\n"
  },
  {
    "path": "cmd/esbuild/stdio_protocol.go",
    "content": "// The JavaScript API communicates with the Go child process over stdin/stdout\n// using this protocol. It's a very simple binary protocol that uses primitives\n// and nested arrays and maps. It's basically JSON with UTF-8 encoding and an\n// additional byte array primitive. You must send a response after receiving a\n// request because the other end is blocking on the response coming back.\n\npackage main\n\nimport (\n\t\"encoding/binary\"\n\t\"sort\"\n)\n\nfunc readUint32(bytes []byte) (value uint32, leftOver []byte, ok bool) {\n\tif len(bytes) >= 4 {\n\t\treturn binary.LittleEndian.Uint32(bytes), bytes[4:], true\n\t}\n\n\treturn 0, bytes, false\n}\n\nfunc writeUint32(bytes []byte, value uint32) []byte {\n\tbytes = append(bytes, 0, 0, 0, 0)\n\tbinary.LittleEndian.PutUint32(bytes[len(bytes)-4:], value)\n\treturn bytes\n}\n\nfunc readLengthPrefixedSlice(bytes []byte) (slice []byte, leftOver []byte, ok bool) {\n\tif length, afterLength, ok := readUint32(bytes); ok && uint(len(afterLength)) >= uint(length) {\n\t\treturn afterLength[:length], afterLength[length:], true\n\t}\n\n\treturn []byte{}, bytes, false\n}\n\ntype packet struct {\n\tvalue     interface{}\n\tid        uint32\n\tisRequest bool\n}\n\nfunc encodePacket(p packet) []byte {\n\tvar visit func(interface{})\n\tvar bytes []byte\n\n\tvisit = func(value interface{}) {\n\t\tswitch v := value.(type) {\n\t\tcase nil:\n\t\t\tbytes = append(bytes, 0)\n\n\t\tcase bool:\n\t\t\tn := uint8(0)\n\t\t\tif v {\n\t\t\t\tn = 1\n\t\t\t}\n\t\t\tbytes = append(bytes, 1, n)\n\n\t\tcase int:\n\t\t\tbytes = append(bytes, 2)\n\t\t\tbytes = writeUint32(bytes, uint32(v))\n\n\t\tcase string:\n\t\t\tbytes = append(bytes, 3)\n\t\t\tbytes = writeUint32(bytes, uint32(len(v)))\n\t\t\tbytes = append(bytes, v...)\n\n\t\tcase []byte:\n\t\t\tbytes = append(bytes, 4)\n\t\t\tbytes = writeUint32(bytes, uint32(len(v)))\n\t\t\tbytes = append(bytes, v...)\n\n\t\tcase []interface{}:\n\t\t\tbytes = append(bytes, 5)\n\t\t\tbytes = writeUint32(bytes, uint32(len(v)))\n\t\t\tfor _, item := range v {\n\t\t\t\tvisit(item)\n\t\t\t}\n\n\t\tcase map[string]interface{}:\n\t\t\t// Sort keys for determinism\n\t\t\tkeys := make([]string, 0, len(v))\n\t\t\tfor k := range v {\n\t\t\t\tkeys = append(keys, k)\n\t\t\t}\n\t\t\tsort.Strings(keys)\n\t\t\tbytes = append(bytes, 6)\n\t\t\tbytes = writeUint32(bytes, uint32(len(keys)))\n\t\t\tfor _, k := range keys {\n\t\t\t\tbytes = writeUint32(bytes, uint32(len(k)))\n\t\t\t\tbytes = append(bytes, k...)\n\t\t\t\tvisit(v[k])\n\t\t\t}\n\n\t\tdefault:\n\t\t\tpanic(\"Invalid packet\")\n\t\t}\n\t}\n\n\tbytes = writeUint32(bytes, 0) // Reserve space for the length\n\tif p.isRequest {\n\t\tbytes = writeUint32(bytes, p.id<<1)\n\t} else {\n\t\tbytes = writeUint32(bytes, (p.id<<1)|1)\n\t}\n\tvisit(p.value)\n\twriteUint32(bytes[:0], uint32(len(bytes)-4)) // Patch the length in\n\treturn bytes\n}\n\nfunc decodePacket(bytes []byte) (packet, bool) {\n\tvar visit func() (interface{}, bool)\n\n\tvisit = func() (interface{}, bool) {\n\t\tkind := bytes[0]\n\t\tbytes = bytes[1:]\n\t\tswitch kind {\n\t\tcase 0: // nil\n\t\t\treturn nil, true\n\n\t\tcase 1: // bool\n\t\t\tvalue := bytes[0]\n\t\t\tbytes = bytes[1:]\n\t\t\treturn value != 0, true\n\n\t\tcase 2: // int\n\t\t\tvalue, next, ok := readUint32(bytes)\n\t\t\tif !ok {\n\t\t\t\treturn nil, false\n\t\t\t}\n\t\t\tbytes = next\n\t\t\treturn int(value), true\n\n\t\tcase 3: // string\n\t\t\tvalue, next, ok := readLengthPrefixedSlice(bytes)\n\t\t\tif !ok {\n\t\t\t\treturn nil, false\n\t\t\t}\n\t\t\tbytes = next\n\t\t\treturn string(value), true\n\n\t\tcase 4: // []byte\n\t\t\tvalue, next, ok := readLengthPrefixedSlice(bytes)\n\t\t\tif !ok {\n\t\t\t\treturn nil, false\n\t\t\t}\n\t\t\tbytes = next\n\t\t\treturn value, true\n\n\t\tcase 5: // []interface{}\n\t\t\tcount, next, ok := readUint32(bytes)\n\t\t\tif !ok {\n\t\t\t\treturn nil, false\n\t\t\t}\n\t\t\tbytes = next\n\t\t\tvalue := make([]interface{}, count)\n\t\t\tfor i := 0; i < int(count); i++ {\n\t\t\t\titem, ok := visit()\n\t\t\t\tif !ok {\n\t\t\t\t\treturn nil, false\n\t\t\t\t}\n\t\t\t\tvalue[i] = item\n\t\t\t}\n\t\t\treturn value, true\n\n\t\tcase 6: // map[string]interface{}\n\t\t\tcount, next, ok := readUint32(bytes)\n\t\t\tif !ok {\n\t\t\t\treturn nil, false\n\t\t\t}\n\t\t\tbytes = next\n\t\t\tvalue := make(map[string]interface{}, count)\n\t\t\tfor i := 0; i < int(count); i++ {\n\t\t\t\tkey, next, ok := readLengthPrefixedSlice(bytes)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn nil, false\n\t\t\t\t}\n\t\t\t\tbytes = next\n\t\t\t\titem, ok := visit()\n\t\t\t\tif !ok {\n\t\t\t\t\treturn nil, false\n\t\t\t\t}\n\t\t\t\tvalue[string(key)] = item\n\t\t\t}\n\t\t\treturn value, true\n\n\t\tdefault:\n\t\t\tpanic(\"Invalid packet\")\n\t\t}\n\t}\n\n\tid, bytes, ok := readUint32(bytes)\n\tif !ok {\n\t\treturn packet{}, false\n\t}\n\tisRequest := (id & 1) == 0\n\tid >>= 1\n\tvalue, ok := visit()\n\tif !ok {\n\t\treturn packet{}, false\n\t}\n\tif len(bytes) != 0 {\n\t\treturn packet{}, false\n\t}\n\treturn packet{id: id, isRequest: isRequest, value: value}, true\n}\n"
  },
  {
    "path": "cmd/esbuild/version.go",
    "content": "package main\n\nconst esbuildVersion = \"0.27.4\"\n"
  },
  {
    "path": "compat-table/.gitignore",
    "content": "/out.js\n/out.js.map\n/repos/\n"
  },
  {
    "path": "compat-table/README.md",
    "content": "# compat-table\n\nThis code generates esbuild's internal browser compatibility tables from 3rd-party browser compatibility data. Run this code with `make compat-table` in the top-level repository directory. Update the data sources behind these tables using `make update-compat-table`.\n"
  },
  {
    "path": "compat-table/package.json",
    "content": "{\n  \"githubDependencies\": {\n    \"compat-table/compat-table\": \"f12538fe11c48c4fd35d6cdc7789653e10871b90\"\n  },\n  \"dependencies\": {\n    \"@mdn/browser-compat-data\": \"7.3.0\",\n    \"@types/caniuse-lite\": \"1.0.1\",\n    \"@types/node\": \"25.0.2\",\n    \"caniuse-lite\": \"1.0.30001768\"\n  }\n}\n"
  },
  {
    "path": "compat-table/src/caniuse.ts",
    "content": "// This file processes data from https://caniuse.com\n\nimport lite = require('caniuse-lite')\nimport { CSSFeature, CSSPrefixMap, CSSProperty, Engine, JSFeature, PrefixData, Support, SupportMap } from './index'\n\nconst enum StatusCode {\n  Almost = 'a',\n  Disabled = 'd',\n  No = 'n',\n  Polyfill = 'p',\n  Prefix = 'x',\n  Unknown = 'u',\n  Yes = 'y',\n}\n\nconst supportedAgents: Record<string, Engine> = {\n  chrome: 'Chrome',\n  edge: 'Edge',\n  firefox: 'Firefox',\n  ie: 'IE',\n  ios_saf: 'IOS',\n  opera: 'Opera',\n  safari: 'Safari',\n}\n\nconst jsFeatures: Record<string, JSFeature> = {\n  'es6-module-dynamic-import': 'DynamicImport',\n}\n\nconst cssFeatures: Record<string, CSSFeature> = {\n  'css-matches-pseudo': 'IsPseudoClass',\n  'css-media-range-syntax': 'MediaRange',\n}\n\nconst cssPrefixFeatures: Record<string, CSSProperty> = {\n  'css-appearance': 'DAppearance',\n  'css-backdrop-filter': 'DBackdropFilter',\n  'background-clip-text': 'DBackgroundClip',\n  'css-boxdecorationbreak': 'DBoxDecorationBreak',\n  'css-clip-path': 'DClipPath',\n  'font-kerning': 'DFontKerning',\n  'css-hyphens': 'DHyphens',\n  'css-initial-letter': 'DInitialLetter',\n  'css-sticky': 'DPosition',\n  'css-color-adjust': 'DPrintColorAdjust',\n  'css3-tabsize': 'DTabSize',\n  'css-text-orientation': 'DTextOrientation',\n  'text-size-adjust': 'DTextSizeAdjust',\n}\n\nexport const js: SupportMap<JSFeature> = {} as SupportMap<JSFeature>\nexport const css: SupportMap<CSSFeature> = {} as SupportMap<CSSFeature>\nexport const cssPrefix: CSSPrefixMap = {}\n\nconst compareVersions = (aStr: string, bStr: string): number => {\n  const a = aStr.split('.')\n  const b = bStr.split('.')\n  let diff = +a[0] - +b[0]\n  if (diff === 0) {\n    diff = +(a[1] || '0') - +(b[1] || '0')\n    if (diff === 0) {\n      diff = +(a[2] || '0') - +(b[2] || '0')\n    }\n  }\n  return diff\n}\n\nconst addFeatures = <F extends string>(map: SupportMap<F>, features: Record<string, F>): void => {\n  for (const feature in features) {\n    const engines: Partial<Record<Engine, Record<string, Support>>> = {}\n    const entry = lite.feature(lite.features[feature])\n\n    for (const agent in entry.stats) {\n      const engine = supportedAgents[agent]\n      if (!engine) continue\n\n      const versionRanges = entry.stats[agent]\n      const versions: Record<string, Support> = {}\n\n      for (const versionRange in versionRanges) {\n        const statusCodes = versionRanges[versionRange].split(' ')\n        const isSupported = statusCodes.includes(StatusCode.Yes)\n\n        for (const version of versionRange.split('-')) {\n          if (/^\\d+(?:\\.\\d+(?:\\.\\d+)?)?$/.test(version)) {\n            versions[version] = { force: isSupported }\n          }\n        }\n      }\n\n      engines[engine] = versions\n    }\n\n    map[features[feature]] = engines\n  }\n}\n\naddFeatures(js, jsFeatures)\naddFeatures(css, cssFeatures)\n\nfor (const feature in cssPrefixFeatures) {\n  const prefixData: PrefixData[] = []\n  const entry = lite.feature(lite.features[feature])\n\n  for (const agent in entry.stats) {\n    const engine = supportedAgents[agent]\n    if (!engine) continue\n\n    const model = lite.agents[agent]!\n    const versionRanges = entry.stats[agent]\n    const sortedVersions: { version: string, prefix: string | null }[] = []\n    const prefixes = new Set<string>()\n\n    for (const versionRange in versionRanges) {\n      const statusCodes = versionRanges[versionRange].split(' ')\n      const prefix = statusCodes.includes(StatusCode.Prefix)\n        ? (model.prefix_exceptions && model.prefix_exceptions[versionRange]) || model.prefix\n        : null\n      for (const version of versionRange.split('-')) {\n        // Filter out bogus versions such as \"TP\" for Safari\n        if (/^\\d+(\\.\\d+)*$/.test(version)) {\n          sortedVersions.push({ version, prefix })\n        }\n      }\n      if (prefix !== null) {\n        prefixes.add(prefix)\n      }\n    }\n\n    sortedVersions.sort((a, b) => compareVersions(a.version, b.version))\n\n    for (const prefix of prefixes) {\n      // Find the version after the latest version that requires the prefix (if there even is one)\n      let i = sortedVersions.length\n      while (i > 0 && sortedVersions[i - 1].prefix !== prefix) {\n        i--\n      }\n\n      // Add an entry for this prefix combination\n      const result: PrefixData = { engine, prefix }\n      if (i < sortedVersions.length) {\n        result.withoutPrefix = sortedVersions[i].version.split('.').map(x => +x)\n      }\n      prefixData.push(result)\n    }\n  }\n\n  cssPrefix[cssPrefixFeatures[feature]] = prefixData\n}\n"
  },
  {
    "path": "compat-table/src/compat-table.ts",
    "content": "// This file processes the data contained in https://github.com/kangax/compat-table\n\nimport fs = require('fs')\nimport path = require('path')\n\nimport es5 = require('../repos/compat-table/compat-table/data-es5.js')\nimport es6 = require('../repos/compat-table/compat-table/data-es6.js')\nimport stage1to3 = require('../repos/compat-table/compat-table/data-esnext.js')\nimport stage4 = require('../repos/compat-table/compat-table/data-es2016plus.js')\nimport environments = require('../repos/compat-table/compat-table/environments.json')\nimport parseEnvsVersions = require('../repos/compat-table/compat-table/build-utils/parse-envs-versions.js')\nimport interpolateAllResults = require('../repos/compat-table/compat-table/build-utils/interpolate-all-results.js')\nimport { Engine, JSFeature, SupportMap } from './index'\n\ninterpolateAllResults(es5.tests, environments)\ninterpolateAllResults(es6.tests, environments)\ninterpolateAllResults(stage1to3.tests, environments)\ninterpolateAllResults(stage4.tests, environments)\n\nconst features: Record<string, JSFeature> = {\n  // ES5 features\n  'Object/array literal extensions: Getter accessors': 'ObjectAccessors',\n  'Object/array literal extensions: Setter accessors': 'ObjectAccessors',\n\n  // ES6 features\n  'arrow functions': 'Arrow',\n  'class': 'Class',\n  'const': 'ConstAndLet',\n  'default function parameters': 'DefaultArgument',\n  'destructuring, assignment': 'Destructuring',\n  'destructuring, declarations': 'Destructuring',\n  'destructuring, parameters': 'Destructuring',\n  'for..of loops': 'ForOf',\n  'function \"name\" property: isn\\'t writable, is configurable': 'FunctionNameConfigurable',\n  'generators': 'Generator',\n  'let': 'ConstAndLet',\n  'new.target': 'NewTarget',\n  'object literal extensions': 'ObjectExtensions',\n  'RegExp \"y\" and \"u\" flags': 'RegexpStickyAndUnicodeFlags',\n  'rest parameters': 'RestArgument',\n  'spread syntax for iterable objects': 'ArraySpread',\n  'template literals': 'TemplateLiteral',\n  'Unicode code point escapes': 'UnicodeEscapes',\n\n  // >ES6 features\n  'async functions': 'AsyncAwait',\n  'Asynchronous Iterators: async generators': 'AsyncGenerator',\n  'Asynchronous Iterators: for-await-of loops': 'ForAwait',\n  'BigInt: basic functionality': 'Bigint',\n  'exponentiation (**) operator': 'ExponentOperator',\n  'Hashbang Grammar': 'Hashbang',\n  'Logical Assignment': 'LogicalAssignment',\n  'nested rest destructuring, declarations': 'NestedRestBinding',\n  'nested rest destructuring, parameters': 'NestedRestBinding',\n  'nullish coalescing operator (??)': 'NullishCoalescing',\n  'object rest/spread properties': 'ObjectRestSpread',\n  'optional catch binding': 'OptionalCatchBinding',\n  'optional chaining operator (?.)': 'OptionalChain',\n  'RegExp Lookbehind Assertions': 'RegexpLookbehindAssertions',\n  'RegExp named capture groups': 'RegexpNamedCaptureGroups',\n  'RegExp Unicode Property Escapes': 'RegexpUnicodePropertyEscapes',\n  's (dotAll) flag for regular expressions': 'RegexpDotAllFlag',\n  'Explicit Resource Management': 'Using',\n\n  // Public fields\n  'instance class fields: computed instance class fields': 'ClassField',\n  'instance class fields: public instance class fields': 'ClassField',\n  'static class fields: computed static class fields': 'ClassStaticField',\n  'static class fields: public static class fields': 'ClassStaticField',\n\n  // Private fields\n  'instance class fields: optional deep private instance class fields access': 'ClassPrivateField',\n  'instance class fields: optional private instance class fields access': 'ClassPrivateField',\n  'instance class fields: private instance class fields basic support': 'ClassPrivateField',\n  'instance class fields: private instance class fields initializers': 'ClassPrivateField',\n  'static class fields: private static class fields': 'ClassPrivateStaticField',\n\n  // Private methods\n  'private class methods: private accessor properties': 'ClassPrivateAccessor',\n  'private class methods: private instance methods': 'ClassPrivateMethod',\n  'private class methods: private static accessor properties': 'ClassPrivateStaticAccessor',\n  'private class methods: private static methods': 'ClassPrivateStaticMethod',\n\n  // Private \"in\"\n  'Ergonomic brand checks for private fields': 'ClassPrivateBrandCheck',\n}\n\nconst environmentToEngine: Record<string, Engine> = {\n  // The JavaScript standard\n  'es': 'ES',\n\n  // Common JavaScript runtimes\n  'chrome': 'Chrome',\n  'edge': 'Edge',\n  'firefox': 'Firefox',\n  'ie': 'IE',\n  'ios': 'IOS',\n  'node': 'Node',\n  'opera': 'Opera',\n  'safari': 'Safari',\n\n  // Uncommon JavaScript runtimes\n  'deno': 'Deno',\n  'hermes': 'Hermes',\n  'rhino': 'Rhino',\n}\n\nconst subtestsToSkip: Record<string, boolean> = {\n  // Safari supposedly doesn't throw an error for duplicate identifiers in\n  // a function parameter list. The failing test case looks like this:\n  //\n  //   var f = function f([id, id]) { return id }\n  //\n  // However, this code will cause a compile error with esbuild so it's not\n  // possible to encounter this issue when running esbuild-generated code in\n  // Safari. I'm ignoring this test since Safari's destructuring otherwise\n  // works fine so destructuring shouldn't be forbidden when building for\n  // Safari.\n  'destructuring, parameters: duplicate identifier': true,\n}\n\nconst getValueOfTest = (value: boolean | { val: boolean }): boolean => {\n  // Handle values like this:\n  //\n  //   {\n  //     val: true,\n  //     note_id: \"ff-shorthand-methods\",\n  //     ...\n  //   }\n  //\n  if (typeof value === 'object' && value !== null) {\n    return value.val === true\n  }\n\n  // String values such as \"flagged\" are considered to be false\n  return value === true\n}\n\ninterface Test {\n  name: string\n  res: Record<string, boolean | { val: boolean }>\n  subtests?: { name: string, res: Record<string, boolean | { val: boolean }> }[]\n}\n\nconst updateMap = (map: SupportMap<JSFeature>, feature: JSFeature, engine: Engine, version: string, testName: string, passed: boolean): void => {\n  const engines = map[feature] || (map[feature] = {})\n  const versions = engines[engine] || (engines[engine] = {})\n  const support = versions[version] || (versions[version] = {})\n  if (passed) {\n    support.passed = (support.passed || 0) + 1\n  } else {\n    support.failed ||= new Set\n    support.failed.add(testName)\n  }\n}\n\nconst mergeIndividualTestResults = (map: SupportMap<JSFeature>, feature: JSFeature, testName: string, res: Record<string, boolean | { val: boolean }>): void => {\n  const environments = parseEnvsVersions(res)\n  for (const environment in environments) {\n    const engine = environmentToEngine[environment]\n    if (engine) {\n      for (const parsed of environments[environment]) {\n        const version = parsed.version.join('.')\n        if (/^\\d+(?:\\.\\d+(?:\\.\\d+)?)?$/.test(version)) {\n          updateMap(map, feature, engine, version, testName, getValueOfTest(res[parsed.id]))\n        }\n      }\n    }\n  }\n}\n\nconst mergeAllTestResults = (map: SupportMap<JSFeature>, tests: Test[]): void => {\n  for (const test of tests) {\n    const feature = features[test.name]\n    if (feature) {\n      if (test.subtests) {\n        for (const subtest of test.subtests) {\n          const fullName = `${test.name}: ${subtest.name}`\n          if (subtestsToSkip[fullName]) continue\n          mergeIndividualTestResults(map, feature, fullName, subtest.res)\n        }\n      } else {\n        mergeIndividualTestResults(map, feature, test.name, test.res)\n      }\n    } else if (test.subtests) {\n      for (const subtest of test.subtests) {\n        const fullName = `${test.name}: ${subtest.name}`\n        if (subtestsToSkip[fullName]) continue\n        const feature = features[fullName]\n        if (feature) mergeIndividualTestResults(map, feature, fullName, subtest.res)\n      }\n    }\n  }\n}\n\nexport const js: SupportMap<JSFeature> = {} as SupportMap<JSFeature>\nmergeAllTestResults(js, [...es5.tests, ...es6.tests, ...stage4.tests, ...stage1to3.tests])\n"
  },
  {
    "path": "compat-table/src/css_table.ts",
    "content": "// This file generates \"internal/compat/css_table.go\"\n\nimport fs = require('fs')\nimport { Engine, CSSFeature, VersionRange, VersionRangeMap, CSSPrefixMap, PrefixData, CSSProperty } from './index'\n\nconst cssFeatureString = (feature: string): string => {\n  return feature.replace(/([A-Z]+)/g, '-$1').slice(1).toLowerCase().replace(/[-_]+/g, '-')\n}\n\nconst simpleMap = (entries: [string, string][]) => {\n  let maxLength = 0\n  for (const [key] of entries) {\n    maxLength = Math.max(maxLength, key.length + 1)\n  }\n  return entries.map(([key, value]) => `\\t${(key + ':').padEnd(maxLength)} ${value},`).join('\\n')\n}\n\nconst compareEngines = (a: Engine, b: Engine): number => {\n  const lowerA = a.toLowerCase()\n  const lowerB = b.toLowerCase()\n  return lowerA < lowerB ? -1 : lowerA > lowerB ? 1 : 0\n}\n\nconst cssTableMap = (map: Partial<Record<Engine, VersionRange[]>>) => {\n  const engineKeys = (Object.keys(map) as Engine[]).sort(compareEngines)\n  const maxLength = engineKeys.reduce((a, b) => Math.max(a, b.length + 1), 0)\n  if (engineKeys.length === 0) return '{}'\n  return `{\\n${engineKeys.map(engine => {\n    const items = map[engine]!.map(range => {\n      return `{start: v{${range.start.concat(0, 0).slice(0, 3).join(', ')\n        }}${range.end ? `, end: v{${range.end.concat(0, 0).slice(0, 3).join(', ')}}` : ''}}`\n    })\n    return `\\t\\t${(engine + ':').padEnd(maxLength)} {${items.join(', ')}},`\n  }).join('\\n')}\\n\\t}`\n}\n\nconst cssPrefixName = (prefix: string): string => {\n  return prefix[0].toUpperCase() + prefix.slice(1) + 'Prefix'\n}\n\nconst cssPrefixMap = (entries: PrefixData[]) => {\n  if (entries.length === 0) return '{}'\n  entries.sort((a, b) => compareEngines(a.engine, b.engine))\n  return `{\\n${entries.map(({ engine, prefix, withoutPrefix }) => {\n    const version = withoutPrefix && withoutPrefix.concat(0, 0).slice(0, 3).join(', ')\n    return `\\t\\t{engine: ${engine}, prefix: ${cssPrefixName(prefix)}${version ? `, withoutPrefix: v{${version}}` : ''}},`\n  }).join('\\n')}\\n\\t}`\n}\n\nconst generatedByComment = `// This file was automatically generated by \"css_table.ts\"`\n\nexport const generateTableForCSS = (map: VersionRangeMap<CSSFeature>, prefixes: CSSPrefixMap): void => {\n  const prefixNames = new Set<string>()\n  for (const property in prefixes) {\n    for (const { prefix } of prefixes[property as CSSProperty]!) {\n      prefixNames.add(cssPrefixName(prefix))\n    }\n  }\n\n  fs.writeFileSync(__dirname + '/../internal/compat/css_table.go',\n    `${generatedByComment}\n\npackage compat\n\nimport (\n\\t\"github.com/evanw/esbuild/internal/css_ast\"\n)\n\ntype CSSFeature uint16\n\nconst (\n${Object.keys(map).sort().map((feature, i) => `\\t${feature}${i ? '' : ' CSSFeature = 1 << iota'}`).join('\\n')}\n)\n\nvar StringToCSSFeature = map[string]CSSFeature{\n${simpleMap(Object.keys(map).sort().map(feature => [`\"${cssFeatureString(feature)}\"`, feature]))}\n}\n\nfunc (features CSSFeature) Has(feature CSSFeature) bool {\n\\treturn (features & feature) != 0\n}\n\nfunc (features CSSFeature) ApplyOverrides(overrides CSSFeature, mask CSSFeature) CSSFeature {\n\\treturn (features & ^mask) | (overrides & mask)\n}\n\nvar cssTable = map[CSSFeature]map[Engine][]versionRange{\n${Object.keys(map).sort().map(feature => `\\t${feature}: ${cssTableMap(map[feature as CSSFeature]!)},`).join('\\n')}\n}\n\n// Return all features that are not available in at least one environment\nfunc UnsupportedCSSFeatures(constraints map[Engine]Semver) (unsupported CSSFeature) {\n\\tfor feature, engines := range cssTable {\n\\t\\tif feature == InlineStyle {\n\\t\\t\\tcontinue // This is purely user-specified\n\\t\\t}\n\\t\\tfor engine, version := range constraints {\n\\t\\t\\tif !engine.IsBrowser() {\n\\t\\t\\t\\t// Specifying \"--target=es2020\" shouldn't affect CSS\n\\t\\t\\t\\tcontinue\n\\t\\t\\t}\n\\t\\t\\tif versionRanges, ok := engines[engine]; !ok || !isVersionSupported(versionRanges, version) {\n\\t\\t\\t\\tunsupported |= feature\n\\t\\t\\t}\n\\t\\t}\n\\t}\n\\treturn\n}\n\ntype CSSPrefix uint8\n\nconst (\n${[...prefixNames].sort().map((name, i) => `\\t${name}${i ? '' : ' CSSPrefix = 1 << iota'}`).join('\\n')}\n\n\\tNoPrefix CSSPrefix = 0\n)\n\ntype prefixData struct {\n\\t// Note: In some cases, earlier versions did not require a prefix but later\n\\t// ones do. This is the case for Microsoft Edge for example, which switched\n\\t// the underlying browser engine from a custom one to the one from Chrome.\n\\t// However, we assume that users specifying a browser version for CSS mean\n\\t// \"works in this version or newer\", so we still add a prefix when a target\n\\t// is an old Edge version.\n\\tengine        Engine\n\\twithoutPrefix v\n\\tprefix        CSSPrefix\n}\n\nvar cssPrefixTable = map[css_ast.D][]prefixData{\n${Object.keys(prefixes).sort().map(property => `\\tcss_ast.${property}: ${cssPrefixMap(prefixes[property as CSSProperty]!)},`).join('\\n')}\n}\n\nfunc CSSPrefixData(constraints map[Engine]Semver) (entries map[css_ast.D]CSSPrefix) {\n\\tfor property, items := range cssPrefixTable {\n\\t\\tprefixes := NoPrefix\n\\t\\tfor engine, version := range constraints {\n\\t\\t\\tif !engine.IsBrowser() {\n\\t\\t\\t\\t// Specifying \"--target=es2020\" shouldn't affect CSS\n\\t\\t\\t\\tcontinue\n\\t\\t\\t}\n\\t\\t\\tfor _, item := range items {\n\\t\\t\\t\\tif item.engine == engine && (item.withoutPrefix == v{} || compareVersions(item.withoutPrefix, version) > 0) {\n\\t\\t\\t\\t\\tprefixes |= item.prefix\n\\t\\t\\t\\t}\n\\t\\t\\t}\n\\t\\t}\n\\t\\tif prefixes != NoPrefix {\n\\t\\t\\tif entries == nil {\n\\t\\t\\t\\tentries = make(map[css_ast.D]CSSPrefix)\n\\t\\t\\t}\n\\t\\t\\tentries[property] = prefixes\n\\t\\t}\n\\t}\n\\treturn\n}\n`)\n}\n"
  },
  {
    "path": "compat-table/src/index.ts",
    "content": "// Run \"make compat-table\" to run this code\n// Run \"make update-compat-table\" to update the data sources\n\nimport child_process = require('child_process')\nimport fs = require('fs')\nimport path = require('path')\nimport { generateTableForJS } from './js_table'\nimport { generateTableForCSS } from './css_table'\nimport * as caniuse from './caniuse'\nimport * as mdn from './mdn'\n\nexport type Engine = keyof typeof engines\nexport const engines = {\n  Chrome: true,\n  Deno: true,\n  Edge: true,\n  ES: true,\n  Firefox: true,\n  Hermes: true,\n  IE: true,\n  IOS: true,\n  Node: true,\n  Opera: true,\n  Rhino: true,\n  Safari: true,\n}\n\nexport type JSFeature = keyof typeof jsFeatures\nexport const jsFeatures = {\n  ArbitraryModuleNamespaceNames: true,\n  ArraySpread: true,\n  Arrow: true,\n  AsyncAwait: true,\n  AsyncGenerator: true,\n  Bigint: true,\n  Class: true,\n  ClassField: true,\n  ClassPrivateAccessor: true,\n  ClassPrivateBrandCheck: true,\n  ClassPrivateField: true,\n  ClassPrivateMethod: true,\n  ClassPrivateStaticAccessor: true,\n  ClassPrivateStaticField: true,\n  ClassPrivateStaticMethod: true,\n  ClassStaticBlocks: true,\n  ClassStaticField: true,\n  ConstAndLet: true,\n  Decorators: true,\n  DefaultArgument: true,\n  Destructuring: true,\n  DynamicImport: true,\n  ExponentOperator: true,\n  ExportStarAs: true,\n  ForAwait: true,\n  ForOf: true,\n  FromBase64: true,\n  FunctionNameConfigurable: true,\n  FunctionOrClassPropertyAccess: true,\n  Generator: true,\n  Hashbang: true,\n  ImportAssertions: true,\n  ImportAttributes: true,\n  ImportDefer: true,\n  ImportMeta: true,\n  ImportSource: true,\n  InlineScript: true,\n  LogicalAssignment: true,\n  NestedRestBinding: true,\n  NewTarget: true,\n  NodeColonPrefixImport: true,\n  NodeColonPrefixRequire: true,\n  NullishCoalescing: true,\n  ObjectAccessors: true,\n  ObjectExtensions: true,\n  ObjectRestSpread: true,\n  OptionalCatchBinding: true,\n  OptionalChain: true,\n  RegexpDotAllFlag: true,\n  RegexpLookbehindAssertions: true,\n  RegexpMatchIndices: true,\n  RegexpNamedCaptureGroups: true,\n  RegexpSetNotation: true,\n  RegexpStickyAndUnicodeFlags: true,\n  RegexpUnicodePropertyEscapes: true,\n  RestArgument: true,\n  TemplateLiteral: true,\n  TopLevelAwait: true,\n  TypeofExoticObjectIsObject: true,\n  UnicodeEscapes: true,\n  Using: true,\n}\n\nexport type CSSFeature = keyof typeof cssFeatures\nexport const cssFeatures = {\n  ColorFunctions: true,\n  GradientDoublePosition: true,\n  GradientInterpolation: true,\n  GradientMidpoints: true,\n  HexRGBA: true,\n  HWB: true,\n  InlineStyle: true,\n  InsetProperty: true,\n  IsPseudoClass: true,\n  MediaRange: true,\n  Modern_RGB_HSL: true,\n  Nesting: true,\n  RebeccaPurple: true,\n}\n\nexport type CSSProperty = keyof typeof cssProperties\nexport const cssProperties = {\n  DAppearance: true,\n  DBackdropFilter: true,\n  DBackgroundClip: true,\n  DBoxDecorationBreak: true,\n  DClipPath: true,\n  DFontKerning: true,\n  DHeight: true,\n  DHyphens: true,\n  DInitialLetter: true,\n  DMask: true,\n  DMaskComposite: true,\n  DMaskImage: true,\n  DMaskOrigin: true,\n  DMaskPosition: true,\n  DMaskRepeat: true,\n  DMaskSize: true,\n  DMaxHeight: true,\n  DMaxWidth: true,\n  DMinHeight: true,\n  DMinWidth: true,\n  DPosition: true,\n  DPrintColorAdjust: true,\n  DTabSize: true,\n  DTextDecorationColor: true,\n  DTextDecorationLine: true,\n  DTextDecorationSkip: true,\n  DTextEmphasisColor: true,\n  DTextEmphasisPosition: true,\n  DTextEmphasisStyle: true,\n  DTextOrientation: true,\n  DTextSizeAdjust: true,\n  DUserSelect: true,\n  DWidth: true,\n}\n\nexport interface Support {\n  force?: boolean\n  passed?: number\n  failed?: Set<string>\n}\n\nexport interface VersionRange {\n  start: number[]\n  end?: number[]\n}\n\nexport interface PrefixData {\n  engine: Engine\n  prefix: string\n  withoutPrefix?: number[]\n}\n\nexport type SupportMap<F extends string> = Record<F, Partial<Record<Engine, Record<string, Support>>>>\nexport type VersionRangeMap<F extends string> = Partial<Record<F, Partial<Record<Engine, VersionRange[]>>>>\nexport type WhyNotMap<F extends string> = Partial<Record<F, Partial<Record<Engine, string[]>>>>\nexport type CSSPrefixMap = Partial<Record<CSSProperty, PrefixData[]>>\n\nconst compareVersions = (a: number[], b: number[]): number => {\n  let diff = a[0] - b[0]\n  if (!diff) {\n    diff = (a[1] || 0) - (b[1] || 0)\n    if (!diff) {\n      diff = (a[2] || 0) - (b[2] || 0)\n    }\n  }\n  return diff\n}\n\nconst mergeSupportMaps = <F extends string>(to: SupportMap<F>, from: SupportMap<F>): void => {\n  for (const feature in from) {\n    const fromEngines = from[feature as F]\n    const toEngines = to[feature as F] || (to[feature as F] = {})\n\n    for (const engine in fromEngines) {\n      const fromVersions = fromEngines[engine as Engine]\n      const toVersions = toEngines[engine as Engine] || (toEngines[engine as Engine] = {})\n\n      for (const version in fromVersions) {\n        if (version in toVersions) {\n          throw new Error(`Merge conflict with feature=${feature} engine=${engine} version=${version}`)\n        }\n\n        toVersions[version] = fromVersions[version]\n      }\n    }\n  }\n}\n\nconst mergePrefixMaps = (to: CSSPrefixMap, from: CSSPrefixMap): void => {\n  for (const property in from) {\n    if (property in to) {\n      throw new Error(`Merge conflict with property=${property}`)\n    }\n    to[property as CSSProperty] = from[property as CSSProperty]\n  }\n}\n\nconst supportMapToVersionRanges = <F extends string>(supportMap: SupportMap<F>): [VersionRangeMap<F>, WhyNotMap<F>] => {\n  const versionRangeMap: VersionRangeMap<F> = {}\n  const whyNotMap: WhyNotMap<F> = {}\n\n  for (const feature in supportMap) {\n    const engines = supportMap[feature as F]\n    const featureMap: Partial<Record<Engine, VersionRange[]>> = {}\n    const whyNotByEngine: Partial<Record<Engine, string[]>> = {}\n\n    // Compute the maximum number of tests that any one engine has passed\n    let maxPassed = 0\n    for (const engine in engines) {\n      const versions = engines[engine as Engine]\n      for (const version in versions) {\n        const { passed } = versions[version]\n        if (passed && passed > maxPassed) maxPassed = passed\n      }\n    }\n\n    for (const engine in engines) {\n      const versions = engines[engine as Engine]\n      const sortedVersions: { version: number[], supported: boolean, failed?: Set<string> }[] = []\n\n      for (const version in versions) {\n        const { force, passed, failed } = versions[version]\n        const parsed = version.split('.').map(x => +x)\n        sortedVersions.push({\n          version: parsed,\n          supported: force !== void 0 ? force :\n            // If no test failed but less than the maximum number of tests passed,\n            // that means we have partial data (some tests have never been run for\n            // those versions). This happens for really old browser versions that\n            // people can't even run anymore. We conservatively consider this\n            // feature to be unsupported if not all tests were run, since it could\n            // be dangerous to assume otherwise.\n            !failed && passed === maxPassed,\n          failed,\n        })\n      }\n\n      sortedVersions.sort((a, b) => compareVersions(a.version, b.version))\n\n      if (sortedVersions.length) {\n        const last = sortedVersions[sortedVersions.length - 1]\n        if (last.failed) whyNotByEngine[engine as Engine] = [...last.failed].sort()\n      }\n\n      const versionRanges: VersionRange[] = []\n      let i = 0\n\n      while (i < sortedVersions.length) {\n        const { version, supported } = sortedVersions[i++]\n        if (supported) {\n          while (i < sortedVersions.length && sortedVersions[i].supported) {\n            i++\n          }\n          const range: VersionRange = { start: version }\n          if (i < sortedVersions.length) range.end = sortedVersions[i].version\n          versionRanges.push(range)\n        }\n      }\n\n      // The target is typically used to mean \"make sure it works in this\n      // version and later\". So we just take the last version range here.\n      //\n      // However, we make an exception for node since people sometimes use\n      // the target to build for the version of node that they currently\n      // have. Node has a discontiguous version range for the support of\n      // several features that people want to use.\n      if (versionRanges.length && engine as Engine !== 'Node') {\n        if (versionRanges[versionRanges.length - 1].end) {\n          // We say this engine doesn't support this feature at all if\n          // the feature is broken in the latest version of this engine.\n          // This sometimes happens when engines deliberately decide to\n          // not implement a feature of the language (e.g. Hermes).\n          continue\n        }\n\n        // Otherwise, only consider this feature to be supported for the\n        // last version range (i.e. the earliest version for which all\n        // later versions support this feature). Delete all version ranges\n        // before the last version range.\n        versionRanges.splice(0, versionRanges.length - 1)\n      }\n\n      if (versionRanges.length) {\n        featureMap[engine as Engine] = versionRanges\n      }\n    }\n\n    versionRangeMap[feature as F] = featureMap\n    whyNotMap[feature as F] = whyNotByEngine\n  }\n\n  return [versionRangeMap, whyNotMap]\n}\n\nconst installGitHubDependencies = (): void => {\n  const updateCommits = process.argv.includes('--update')\n  const jsonPath = path.join(__dirname, 'package.json')\n  const jsonData = JSON.parse(fs.readFileSync(jsonPath, 'utf8'))\n\n  Object.keys(jsonData.githubDependencies).forEach(repo => {\n    const fullPath = path.join(__dirname, 'repos', repo)\n    if (!fs.existsSync(fullPath)) {\n      fs.mkdirSync(fullPath, { recursive: true })\n      child_process.execFileSync('git', ['clone', '-b', 'gh-pages', `https://github.com/${repo}.git`, fullPath], { cwd: fullPath, stdio: 'inherit' })\n    }\n\n    child_process.execFileSync('git', ['fetch'], { cwd: fullPath, stdio: 'inherit' })\n\n    if (updateCommits) {\n      child_process.execFileSync('git', ['reset', '--hard', '--quiet', 'origin/gh-pages'], { cwd: fullPath, stdio: 'inherit' })\n      const commit = child_process.execFileSync('git', ['rev-parse', 'HEAD'], { cwd: fullPath }).toString().trim()\n      jsonData.githubDependencies[repo] = commit\n    } else {\n      const commit = jsonData.githubDependencies[repo]\n      child_process.execFileSync('git', ['reset', '--hard', '--quiet', commit], { cwd: fullPath, stdio: 'inherit' })\n    }\n  })\n\n  if (updateCommits) {\n    fs.writeFileSync(jsonPath, JSON.stringify(jsonData, null, 2) + '\\n')\n  }\n}\n\n// These dependencies are not published on npm and are instead pulled from GitHub (but pinned to a specific commit)\ninstallGitHubDependencies()\n\nimport('./compat-table').then(compatTable => {\n  const js: SupportMap<JSFeature> = {} as SupportMap<JSFeature>\n  for (const feature in jsFeatures) js[feature as JSFeature] = {}\n\n  mergeSupportMaps(js, compatTable.js)\n  mergeSupportMaps(js, caniuse.js)\n  mergeSupportMaps(js, mdn.js)\n\n  // ES5 features\n  js.ObjectAccessors.ES = { 5: { force: true } }\n  js.ObjectAccessors.Node = { '0.4': { force: true } } // \"node-compat-table\" doesn't appear to cover ES5 features...\n\n  // ES6/ES2015 features\n  js.ArraySpread.ES = { 2015: { force: true } }\n  js.Arrow.ES = { 2015: { force: true } }\n  js.Class.ES = { 2015: { force: true } }\n  js.ConstAndLet.ES = { 2015: { force: true } }\n  js.DefaultArgument.ES = { 2015: { force: true } }\n  js.Destructuring.ES = { 2015: { force: true } }\n  js.DynamicImport.ES = { 2015: { force: true } }\n  js.ForOf.ES = { 2015: { force: true } }\n  js.FunctionNameConfigurable.ES = { 2015: { force: true } }\n  js.Generator.ES = { 2015: { force: true } }\n  js.NewTarget.ES = { 2015: { force: true } }\n  js.ObjectExtensions.ES = { 2015: { force: true } }\n  js.RegexpStickyAndUnicodeFlags.ES = { 2015: { force: true } }\n  js.RestArgument.ES = { 2015: { force: true } }\n  js.TemplateLiteral.ES = { 2015: { force: true } }\n  js.UnicodeEscapes.ES = { 2015: { force: true } }\n\n  // ES2016 features\n  js.ExponentOperator.ES = { 2016: { force: true } }\n  js.NestedRestBinding.ES = { 2016: { force: true } }\n\n  // ES2017 features\n  js.AsyncAwait.ES = { 2017: { force: true } }\n\n  // ES2018 features\n  js.AsyncGenerator.ES = { 2018: { force: true } }\n  js.ForAwait.ES = { 2018: { force: true } }\n  js.ObjectRestSpread.ES = { 2018: { force: true } }\n  js.RegexpDotAllFlag.ES = { 2018: { force: true } }\n  js.RegexpLookbehindAssertions.ES = { 2018: { force: true } }\n  js.RegexpNamedCaptureGroups.ES = { 2018: { force: true } }\n  js.RegexpUnicodePropertyEscapes.ES = { 2018: { force: true } }\n\n  // ES2019 features\n  js.OptionalCatchBinding.ES = { 2019: { force: true } }\n\n  // ES2020 features\n  js.Bigint.ES = { 2020: { force: true } }\n  js.ExportStarAs.ES = { 2020: { force: true } }\n  js.ImportMeta.ES = { 2020: { force: true } }\n  js.NullishCoalescing.ES = { 2020: { force: true } }\n  js.OptionalChain.ES = { 2020: { force: true } }\n  js.TypeofExoticObjectIsObject.ES = { 2020: { force: true } } // https://github.com/tc39/ecma262/pull/1441\n\n  // ES2021 features\n  js.LogicalAssignment.ES = { 2021: { force: true } }\n\n  // ES2022 features\n  js.ClassField.ES = { 2022: { force: true } }\n  js.ClassPrivateAccessor.ES = { 2022: { force: true } }\n  js.ClassPrivateBrandCheck.ES = { 2022: { force: true } }\n  js.ClassPrivateField.ES = { 2022: { force: true } }\n  js.ClassPrivateMethod.ES = { 2022: { force: true } }\n  js.ClassPrivateStaticAccessor.ES = { 2022: { force: true } }\n  js.ClassPrivateStaticField.ES = { 2022: { force: true } }\n  js.ClassPrivateStaticMethod.ES = { 2022: { force: true } }\n  js.ClassStaticBlocks.ES = { 2022: { force: true } }\n  js.ClassStaticField.ES = { 2022: { force: true } }\n  js.TopLevelAwait.ES = { 2022: { force: true } }\n  js.ArbitraryModuleNamespaceNames.ES = { 2022: { force: true } }\n  js.RegexpMatchIndices.ES = { 2022: { force: true } }\n\n  // ES2023 features\n  js.Hashbang.ES = { 2023: { force: true } }\n\n  // ES2024 features\n  js.RegexpSetNotation.ES = { 2024: { force: true } }\n\n  // This is a problem specific to Internet Explorer. See https://github.com/tc39/ecma262/issues/1440\n  for (const engine in engines) {\n    if (engine as Engine !== 'ES' && engine as Engine !== 'IE') {\n      js.TypeofExoticObjectIsObject[engine as Engine] = { 0: { force: true } }\n    }\n  }\n\n  // This is a problem specific to JavaScriptCore. Some examples of when the\n  // problematic case happens (checked in Safari 12.1):\n  //\n  //   ❱ x(function(y=-1){}.z=2)\n  //   SyntaxError: Left hand side of operator '=' must be a reference.\n  //\n  //   ❱ x(class{f(y=-1){}}.z=2)\n  //   SyntaxError: Left hand side of operator '=' must be a reference.\n  //\n  // Some examples of cases that aren't problematic (checked in Safari 12.1):\n  //\n  //   // Adding parentheses makes it ok\n  //   x((function(y=-1){}).z=2)\n  //   x((class{f(y=-1){}}).z=2)\n  //\n  //   // Not using a unary operator in the default argument makes it ok\n  //   x(function(y=1){}.z=2)\n  //   x(class{f(y=1){}}.z=2)\n  //\n  //   // Methods in object literals are not affected\n  //   x({f(y=-1){}}.z=2)\n  //\n  // We don't attempt to reverse-engineer the specific conditions that cause JSC\n  // to exhibit the bug. Instead we just always wrap function and class literals\n  // when they are nested inside of a property access. This workaround is overly\n  // conservative but is the same thing that UglifyJS does to handle this case.\n  //\n  // See https://github.com/mishoo/UglifyJS/pull/2056 and https://github.com/evanw/esbuild/issues/3072\n  for (const engine in engines) {\n    if (engine as Engine !== 'Safari') {\n      js.FunctionOrClassPropertyAccess[engine as Engine] = { 0: { force: true } }\n    } else {\n      // These bugs are known to be fixed in Safari 16.3+\n      js.FunctionOrClassPropertyAccess.Safari = { '16.3': { force: true } }\n    }\n  }\n\n  // This is a special case. Node added support for it to both v12.20+ and v13.2+\n  // so the range is inconveniently discontiguous. Sources:\n  //\n  // - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import\n  // - https://github.com/nodejs/node/pull/35950\n  // - https://github.com/nodejs/node/pull/31974\n  //\n  js.DynamicImport.Node = {\n    '12.20': { force: true },\n    '13': { force: false },\n    '13.2': { force: true },\n  }\n\n  // Manually copied from https://nodejs.org/api/esm.html#node-imports\n  js.NodeColonPrefixImport.Node = {\n    '12.20': { force: true },\n    '13': { force: false },\n    '14.13.1': { force: true },\n  }\n  js.NodeColonPrefixRequire.Node = {\n    '14.18': { force: true },\n    '15': { force: false },\n    '16': { force: true },\n  }\n  js.NodeColonPrefixImport.ES = { 0: { force: true } }\n  js.NodeColonPrefixRequire.ES = { 0: { force: true } }\n\n  // Arbitrary Module Namespace Names\n  {\n    // From https://github.com/tc39/ecma262/pull/2154#issuecomment-825201030\n    js.ArbitraryModuleNamespaceNames.Chrome = { 90: { force: true } }\n    js.ArbitraryModuleNamespaceNames.Node = { 16: { force: true } }\n\n    // From https://bugzilla.mozilla.org/show_bug.cgi?id=1670044\n    js.ArbitraryModuleNamespaceNames.Firefox = { 87: { force: true } }\n\n    // From https://developer.apple.com/documentation/safari-release-notes/safari-14_1-release-notes\n    js.ArbitraryModuleNamespaceNames.Safari = { '14.1': { force: true } }\n    js.ArbitraryModuleNamespaceNames.IOS = { '14.5': { force: true } }\n  }\n\n  // Import assertions (note: these were removed from the JavaScript specification and never standardized)\n  {\n    js.ImportAssertions.Node = {\n      // From https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V16.md#16.14.0\n      '16.14': { force: true },\n\n      // Manually tested using a binary from https://nodejs.org/en/download/prebuilt-binaries\n      '22': { force: false },\n    }\n\n    // MDN data is wrong here: https://bugs.webkit.org/show_bug.cgi?id=251600\n    delete js.ImportAssertions.IOS\n    delete js.ImportAssertions.Safari\n  }\n\n  // Import attributes (the replacement for import assertions)\n  {\n    // Manually tested using binaries from https://nodejs.org/en/download/prebuilt-binaries\n    js.ImportAttributes.Node = {\n      '18.20': { force: true },\n      '19': { force: false },\n      '20.10': { force: true },\n    }\n  }\n\n  // MDN data is wrong here: https://www.chromestatus.com/feature/6482797915013120\n  js.ClassStaticBlocks.Chrome = { 91: { force: true } }\n\n  // WebKit has now been marked as not supporting top-level await because it\n  // turns out they have a pretty severe bug: Importing a module that uses\n  // top-level await twice causes the second import to fail. For more info see:\n  // https://bugs.webkit.org/show_bug.cgi?id=242740\n  //\n  // However, we're going to override this to say it's still supported because:\n  // - It always fails loudly when this happens (the import fails)\n  // - People would otherwise be blocked from using this feature at all in\n  //   WebKit-based browsers\n  // - From what I understand, most use of top-level await is in the entry-point\n  //   module, where this isn't an issue\n  // - When you bundle your code, nested modules become entry points so this\n  //   issue also wouldn't come up\n  // - The top-level await implementation in esbuild isn't even correct for\n  //   nested modules as they become linearized in the bundle (like Rollup, but\n  //   not like Webpack)\n  js.TopLevelAwait.IOS = { 15: { force: true } }\n  js.TopLevelAwait.Safari = { 15: { force: true } }\n\n  // MDN data is incomplete here: https://github.com/mdn/browser-compat-data/issues/28228\n  js.FromBase64.Node = { 25: { force: true } }\n\n  const [jsVersionRanges, jsWhyNot] = supportMapToVersionRanges(js)\n  generateTableForJS(jsVersionRanges, jsWhyNot)\n})\n\nconst css: SupportMap<CSSFeature> = {} as SupportMap<CSSFeature>\nconst cssPrefix: CSSPrefixMap = {}\nfor (const feature in cssFeatures) css[feature as CSSFeature] = {}\n\nmergeSupportMaps(css, caniuse.css)\nmergeSupportMaps(css, mdn.css)\nmergePrefixMaps(cssPrefix, caniuse.cssPrefix)\nmergePrefixMaps(cssPrefix, mdn.cssPrefix)\n\n// MDN data is wrong here, Firefox still had gradient interpolation rendering\n// bugs until version 137: https://bugzilla.mozilla.org/show_bug.cgi?id=1904106\ncss.GradientInterpolation.Firefox = { 137: { force: true } }\n\nconst [cssVersionRanges] = supportMapToVersionRanges(css)\ngenerateTableForCSS(cssVersionRanges, cssPrefix)\n"
  },
  {
    "path": "compat-table/src/js_table.ts",
    "content": "// This file generates \"internal/compat/js_table.go\"\n\nimport fs = require('fs')\nimport { Engine, JSFeature, VersionRange, VersionRangeMap, WhyNotMap, engines } from './index'\n\nconst jsFeatureString = (feature: string): string => {\n  return feature.replace(/([A-Z])/g, '-$1').slice(1).toLowerCase()\n}\n\nconst simpleMap = (entries: [string, string][]) => {\n  let maxLength = 0\n  for (const [key] of entries) {\n    maxLength = Math.max(maxLength, key.length + 1)\n  }\n  return entries.map(([key, value]) => `\\t${(key + ':').padEnd(maxLength)} ${value},`).join('\\n')\n}\n\nconst compareEngines = (a: Engine, b: Engine): number => {\n  const lowerA = a.toLowerCase()\n  const lowerB = b.toLowerCase()\n  return lowerA < lowerB ? -1 : lowerA > lowerB ? 1 : 0\n}\n\nconst jsTableMap = (map: Partial<Record<Engine, VersionRange[]>>, whyNot: Partial<Record<Engine, string[]>>) => {\n  const lines: string[] = []\n  const whyNotKeys = (Object.keys(whyNot) as Engine[]).sort(compareEngines)\n  for (const engine of whyNotKeys) {\n    const failedTests = whyNot[engine]!\n    lines.push(`\\t\\t// Note: The latest version of ${JSON.stringify(engine)} failed ` + (failedTests.length === 1\n      ? `this test: ${failedTests[0]}` : `${failedTests.length} tests including: ${failedTests[0]}`))\n  }\n\n  const engineKeys = (Object.keys(map) as Engine[]).sort(compareEngines)\n  const maxLength = engineKeys.reduce((a, b) => Math.max(a, b.length + 1), 0)\n  for (const engine of engineKeys) {\n    const items = map[engine]!.map(range => {\n      return `{start: v{${range.start.concat(0, 0).slice(0, 3).join(', ')\n        }}${range.end ? `, end: v{${range.end.concat(0, 0).slice(0, 3).join(', ')}}` : ''}}`\n    })\n    lines.push(`\\t\\t${(engine + ':').padEnd(maxLength)} {${items.join(', ')}},`)\n  }\n\n  if (lines.length === 0) return '{}'\n  return `{\\n${lines.join('\\n')}\\n\\t}`\n}\n\nconst jsTableValidEnginesMap = (engines: Engine[]) => {\n  const maxLength = engines.reduce((a, b) => Math.max(a, b.length + 4), 0)\n  if (engines.length === 0) return '{}'\n  return engines.map(engine => {\n    return `\\t${`\"${engine.toLowerCase()}\": `.padEnd(maxLength)}api.Engine${engine},`\n  }).join('\\n')\n}\n\nconst generatedByComment = `// This file was automatically generated by \"js_table.ts\"`\n\nexport const generateTableForJS = (map: VersionRangeMap<JSFeature>, whyNot: WhyNotMap<JSFeature>): void => {\n  const enginesKeys = (Object.keys(engines) as Engine[]).sort(compareEngines)\n\n  fs.writeFileSync(__dirname + '/../internal/compat/js_table.go',\n    `${generatedByComment}\n\npackage compat\n\ntype Engine uint8\n\nconst (\n${enginesKeys.map((engine, i) => `\\t${engine}${i ? '' : ' Engine = iota'}`).join('\\n')}\n)\n\nfunc (e Engine) String() string {\n\\tswitch e {\n${enginesKeys.map(engine => `\\tcase ${engine}:\\n\\t\\treturn \"${engine.toLowerCase()}\"`).join('\\n')}\n\\t}\n\\treturn \"\"\n}\n\nfunc (e Engine) IsBrowser() bool {\n\\tswitch e {\n\\tcase Chrome, Edge, Firefox, IE, IOS, Opera, Safari:\n\\t\\treturn true\n\\t}\n\\treturn false\n}\n\ntype JSFeature uint64\n\nconst (\n${Object.keys(map).sort().map((feature, i) => `\\t${feature}${i ? '' : ' JSFeature = 1 << iota'}`).join('\\n')}\n)\n\nvar StringToJSFeature = map[string]JSFeature{\n${simpleMap(Object.keys(map).sort().map(feature => [`\"${jsFeatureString(feature)}\"`, feature]))}\n}\n\nfunc (features JSFeature) Has(feature JSFeature) bool {\n\\treturn (features & feature) != 0\n}\n\nfunc (features JSFeature) ApplyOverrides(overrides JSFeature, mask JSFeature) JSFeature {\n\\treturn (features & ^mask) | (overrides & mask)\n}\n\nvar jsTable = map[JSFeature]map[Engine][]versionRange{\n${Object.keys(map).sort().map(feature => `\\t${feature}: ${jsTableMap(map[feature as JSFeature]!, whyNot[feature as JSFeature]!)},`).join('\\n')}\n}\n\n// Return all features that are not available in at least one environment\nfunc UnsupportedJSFeatures(constraints map[Engine]Semver) (unsupported JSFeature) {\n\\tfor feature, engines := range jsTable {\n\\t\\tif feature == InlineScript {\n\\t\\t\\tcontinue // This is purely user-specified\n\\t\\t}\n\\t\\tfor engine, version := range constraints {\n\\t\\t\\tif versionRanges, ok := engines[engine]; !ok || !isVersionSupported(versionRanges, version) {\n\\t\\t\\t\\tunsupported |= feature\n\\t\\t\\t}\n\\t\\t}\n\\t}\n\\treturn\n}\n`)\n\n  fs.writeFileSync(__dirname + '/../pkg/api/api_js_table.go',\n    `${generatedByComment}\n\npackage api\n\nimport \"github.com/evanw/esbuild/internal/compat\"\n\ntype EngineName uint8\n\nconst (\n${enginesKeys.filter(engine => engine !== 'ES').map((engine, i) => `\\tEngine${engine}${i ? '' : ' EngineName = iota'}`).join('\\n')}\n)\n\nfunc convertEngineName(engine EngineName) compat.Engine {\n\\tswitch engine {\n${enginesKeys.filter(engine => engine !== 'ES').map(engine => `\\tcase Engine${engine}:\\n\\t\\treturn compat.${engine}`).join('\\n')}\n\\tdefault:\n\\t\\tpanic(\"Invalid engine name\")\n\\t}\n}\n`)\n\n  fs.writeFileSync(__dirname + '/../pkg/cli/cli_js_table.go',\n    `${generatedByComment}\n\npackage cli\n\nimport \"github.com/evanw/esbuild/pkg/api\"\n\nvar validEngines = map[string]api.EngineName{\n${jsTableValidEnginesMap(enginesKeys.filter(engine => engine !== 'ES'))}\n}\n`)\n}\n"
  },
  {
    "path": "compat-table/src/mdn.ts",
    "content": "// This file processes data from https://developer.mozilla.org/en-US/docs/Web\n\nimport bcd, { BrowserName, SimpleSupportStatement, SupportBlock } from '@mdn/browser-compat-data'\nimport { CSSFeature, CSSPrefixMap, CSSProperty, Engine, JSFeature, PrefixData, Support, SupportMap } from './index'\n\nconst supportedEnvironments: Record<string, Engine> = {\n  chrome: 'Chrome',\n  deno: 'Deno',\n  edge: 'Edge',\n  firefox: 'Firefox',\n  ie: 'IE',\n  nodejs: 'Node',\n  opera: 'Opera',\n  safari: 'Safari',\n  safari_ios: 'IOS',\n}\n\nconst jsFeatures: Partial<Record<JSFeature, string>> = {\n  ClassStaticBlocks: 'javascript.classes.static.initialization_blocks',\n  ExportStarAs: 'javascript.statements.export.namespace',\n  FromBase64: 'javascript.builtins.Uint8Array.fromBase64',\n  ImportAssertions: 'javascript.statements.import.import_assertions',\n  ImportAttributes: 'javascript.statements.import.import_attributes',\n  ImportMeta: 'javascript.operators.import_meta',\n  RegexpMatchIndices: 'javascript.builtins.RegExp.hasIndices',\n  TopLevelAwait: 'javascript.operators.await.top_level',\n}\n\nconst cssFeatures: Partial<Record<CSSFeature, string | string[]>> = {\n  ColorFunctions: [\n    'css.types.color.color',\n    'css.types.color.lab',\n    'css.types.color.lch',\n    'css.types.color.oklab',\n    'css.types.color.oklch',\n  ],\n  GradientDoublePosition: [\n    'css.types.gradient.conic-gradient.doubleposition',\n    'css.types.gradient.linear-gradient.doubleposition',\n    'css.types.gradient.radial-gradient.doubleposition',\n    'css.types.gradient.repeating-linear-gradient.doubleposition',\n    'css.types.gradient.repeating-radial-gradient.doubleposition',\n  ],\n  GradientInterpolation: [\n    'css.types.gradient.conic-gradient.hue_interpolation_method',\n    'css.types.gradient.conic-gradient.interpolation_color_space',\n    'css.types.gradient.linear-gradient.hue_interpolation_method',\n    'css.types.gradient.linear-gradient.interpolation_color_space',\n    'css.types.gradient.radial-gradient.hue_interpolation_method',\n    'css.types.gradient.radial-gradient.interpolation_color_space',\n    'css.types.gradient.repeating-conic-gradient.hue_interpolation_method',\n    'css.types.gradient.repeating-conic-gradient.interpolation_color_space',\n    'css.types.gradient.repeating-linear-gradient.hue_interpolation_method',\n    'css.types.gradient.repeating-linear-gradient.interpolation_color_space',\n    'css.types.gradient.repeating-radial-gradient.hue_interpolation_method',\n    'css.types.gradient.repeating-radial-gradient.interpolation_color_space',\n  ],\n  GradientMidpoints: [\n    'css.types.gradient.linear-gradient.interpolation_hints',\n    'css.types.gradient.radial-gradient.interpolation_hints',\n    'css.types.gradient.repeating-linear-gradient.interpolation_hints',\n    'css.types.gradient.repeating-radial-gradient.interpolation_hints',\n  ],\n  HexRGBA: 'css.types.color.rgb_hexadecimal_notation.alpha_hexadecimal_notation',\n  HWB: 'css.types.color.hwb',\n  InsetProperty: 'css.properties.inset',\n  Modern_RGB_HSL: [\n    'css.types.color.hsl.alpha_parameter',\n    'css.types.color.hsl.space_separated_parameters',\n    'css.types.color.rgb.alpha_parameter',\n    'css.types.color.rgb.float_values',\n    'css.types.color.rgb.space_separated_parameters',\n  ],\n  Nesting: 'css.selectors.nesting',\n  RebeccaPurple: 'css.types.color.named-color.rebeccapurple',\n}\n\nconst similarPrefixedProperty: Record<string, { prefix: string, property: string }> = {\n  'css.properties.mask-composite': {\n    prefix: '-webkit-',\n    property: 'css.properties.-webkit-mask-composite',\n  },\n}\n\nconst cssPrefixFeatures: Record<string, CSSProperty> = {\n  'css.properties.height.stretch': 'DHeight',\n  'css.properties.mask': 'DMask',\n  'css.properties.mask-composite': 'DMaskComposite',\n  'css.properties.mask-image': 'DMaskImage',\n  'css.properties.mask-origin': 'DMaskOrigin',\n  'css.properties.mask-position': 'DMaskPosition',\n  'css.properties.mask-repeat': 'DMaskRepeat',\n  'css.properties.mask-size': 'DMaskSize',\n  'css.properties.max-height.stretch': 'DMaxHeight',\n  'css.properties.max-width.stretch': 'DMaxWidth',\n  'css.properties.min-height.stretch': 'DMinHeight',\n  'css.properties.min-width.stretch': 'DMinWidth',\n  'css.properties.text-decoration-color': 'DTextDecorationColor',\n  'css.properties.text-decoration-line': 'DTextDecorationLine',\n  'css.properties.text-decoration-skip': 'DTextDecorationSkip',\n  'css.properties.text-emphasis-color': 'DTextEmphasisColor',\n  'css.properties.text-emphasis-position': 'DTextEmphasisPosition',\n  'css.properties.text-emphasis-style': 'DTextEmphasisStyle',\n  'css.properties.user-select': 'DUserSelect',\n  'css.properties.width.stretch': 'DWidth',\n}\n\nconst alternativeNameToPrefix: Record<string, string> = {\n  '-webkit-fill-available': '-webkit-',\n  '-moz-available': '-moz-',\n}\n\nexport const js: SupportMap<JSFeature> = {} as SupportMap<JSFeature>\nexport const css: SupportMap<CSSFeature> = {} as SupportMap<CSSFeature>\nexport const cssPrefix: CSSPrefixMap = {}\n\nconst isSemver = /^\\d+(?:\\.\\d+(?:\\.\\d+)?)?$/\n\nconst compareVersions = (aStr: string, bStr: string): number => {\n  const a = aStr.split('.')\n  const b = bStr.split('.')\n  let diff = +a[0] - +b[0]\n  if (diff === 0) {\n    diff = +(a[1] || '0') - +(b[1] || '0')\n    if (diff === 0) {\n      diff = +(a[2] || '0') - +(b[2] || '0')\n    }\n  }\n  return diff\n}\n\nconst extractProperty = (object: any, fullKey: string): any => {\n  for (const key of fullKey.split('.')) {\n    object = object[key]\n  }\n  if (!object) throw new Error(`Failed to find \"${fullKey}\"`)\n  return object\n}\n\nconst addFeatures = <F extends string>(map: SupportMap<F>, features: Partial<Record<F, string | string[]>>): void => {\n  for (const feature in features) {\n    const keys = features[feature]\n    const maxVersions: Partial<Record<Engine, { version: string, isSupported: boolean }>> = {}\n\n    for (const fullKey of Array.isArray(keys) ? keys : [keys]) {\n      const support: SupportBlock = extractProperty(bcd, fullKey).__compat.support\n\n      for (const env in support) {\n        const engine = supportedEnvironments[env]\n\n        if (engine) {\n          const entries = support[env as BrowserName]!\n\n          for (const { flags, version_added, version_removed, partial_implementation } of Array.isArray(entries) ? entries : [entries]) {\n            if (typeof version_added === 'string' && isSemver.test(version_added)) {\n              // The feature isn't considered to be supported if it was removed,\n              // if it requires a flag, or if it's only partially-implemented\n              const isSupported = (!version_removed || !flags) && !partial_implementation\n              const maxVersion = maxVersions[engine]\n              if (\n                !maxVersion ||\n                compareVersions(version_added, maxVersion.version) > 0 ||\n                (compareVersions(version_added, maxVersion.version) === 0 && !isSupported)\n              ) {\n                maxVersions[engine] = { version: version_added, isSupported }\n              }\n            }\n          }\n        }\n      }\n    }\n\n    const engines: Partial<Record<Engine, Record<string, Support>>> = {}\n    for (const engine in maxVersions) {\n      const { version, isSupported } = maxVersions[engine as Engine]!\n      engines[engine as Engine] = { [version]: { force: isSupported } }\n    }\n    map[feature] = engines\n  }\n}\n\naddFeatures(js, jsFeatures)\naddFeatures(css, cssFeatures)\n\nfor (const fullKey in cssPrefixFeatures) {\n  const prefixData: PrefixData[] = []\n  const support: SupportBlock = extractProperty(bcd, fullKey).__compat.support\n\n  for (const env in support) {\n    const engine = supportedEnvironments[env]\n\n    if (engine) {\n      const initialEntries = support[env as BrowserName]!\n      let entries: SimpleSupportStatement[] = Array.isArray(initialEntries) ? initialEntries : [initialEntries]\n\n      // Figure out which version this property can be used unprefixed, if any.\n      // This assumes that support for these CSS properties is never removed.\n      // This assumption is wrong (Edge removed many features when it changed\n      // its engine from EdgeHTML to Blink, basically becoming another browser)\n      // but we ignore those cases for now.\n      let version_unprefixed: string | undefined\n      for (const { prefix, flags, version_added, version_removed, alternative_name } of entries) {\n        if (!prefix && !alternative_name && !flags && typeof version_added === 'string' && !version_removed && isSemver.test(version_added)) {\n          version_unprefixed = version_added\n        }\n      }\n\n      type PrefixRange = { prefix: string, start: string, end?: string }\n      const ranges: PrefixRange[] = []\n\n      // The MDN dataset sometimes doesn't list prefixes if the values for the\n      // prefixed property are sufficiently different. In that case, we may need\n      // to search for the prefix information within another property instead.\n      const similar = similarPrefixedProperty[fullKey]\n      if (similar) {\n        const similarSupport: SupportBlock = extractProperty(bcd, similar.property).__compat.support\n        const similarEntries = similarSupport[env as BrowserName]\n        if (!similarEntries) continue\n        entries = Array.isArray(similarEntries) ? similarEntries : [similarEntries]\n      }\n\n      // Find all version ranges where a given prefix is supported\n      for (let i = 0; i < entries.length; i++) {\n        let { prefix, flags, version_added, version_removed, alternative_name } = entries[i]\n\n        if (similar) {\n          if (prefix) throw new Error(`Unexpected prefix \"${prefix}\" for similar property \"${similar.property}\"`)\n          prefix = similar.prefix\n        }\n\n        if ((prefix || alternative_name) && !flags && typeof version_added === 'string' && isSemver.test(version_added)) {\n          const range: PrefixRange = { prefix: prefix || alternativeNameToPrefix[alternative_name!], start: version_added }\n          let withoutPrefix: string | undefined\n\n          // The prefix is no longer needed if support for the feature was removed\n          if (typeof version_removed === 'string' && isSemver.test(version_removed)) {\n            withoutPrefix = version_removed\n          }\n\n          // The prefix is no longer needed if it can be used unprefixed\n          if (version_unprefixed && (!withoutPrefix || compareVersions(version_unprefixed, withoutPrefix) < 0)) {\n            withoutPrefix = version_unprefixed\n          }\n\n          if (withoutPrefix) {\n            if (compareVersions(version_added, withoutPrefix) === 0) {\n              // No prefix is needed if support for the property with and without the prefix was added simultaneously\n              continue\n            }\n            range.end = withoutPrefix\n          }\n\n          ranges.push(range)\n        }\n      }\n\n      // Sort earlier versions first, then sort prefixes for equal versions lexicographically\n      ranges.sort((a, b) => compareVersions(a.start, b.start) || +(a.prefix > b.prefix) - +(a.prefix < b.prefix))\n\n      for (let i = 0; i < ranges.length; i++) {\n        const { prefix, start, end } = ranges[i]\n\n        // Skip this prefix if it's entirely covered by the previous prefix.\n        // Sometimes engines add support for multiple prefixes at a time. For\n        // example, in version 12 Edge added support for both \"-ms-user-select\"\n        // and \"-webkit-user-select\", so we don't need to generate both.\n        if (i > 0) {\n          const prev = ranges[i - 1]\n          if (compareVersions(start, prev.start) >= 0 && (!prev.end || (end && compareVersions(end, prev.end) <= 0))) {\n            continue\n          }\n        }\n\n        const data: PrefixData = { engine, prefix: prefix.replace(/^-|-$/g, '') }\n        if (end) {\n          data.withoutPrefix = end.split('.').map((x: string) => +x)\n        }\n        prefixData.push(data)\n      }\n    }\n  }\n\n  cssPrefix[cssPrefixFeatures[fullKey]] = prefixData\n}\n"
  },
  {
    "path": "compat-table/src/types.d.ts",
    "content": "// Allow TypeScript to import untyped \".js\" files\ndeclare module '*.js' {\n  let any: any\n  export = any\n}\n"
  },
  {
    "path": "compat-table/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"esModuleInterop\": true,\n    \"module\": \"CommonJS\",\n    \"resolveJsonModule\": true,\n    \"strict\": true,\n    \"target\": \"ESNext\",\n  }\n}\n"
  },
  {
    "path": "dl.sh",
    "content": "#!/bin/sh\nset -eu\ndir=$(mktemp -d)\nplatform=$(uname -ms)\ntgz=\"$dir/esbuild-$ESBUILD_VERSION.tgz\"\n\n# Download the binary executable for the current platform\ncase $platform in\n  'Darwin arm64') curl -fo \"$tgz\" \"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-$ESBUILD_VERSION.tgz\";;\n  'Darwin x86_64') curl -fo \"$tgz\" \"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-$ESBUILD_VERSION.tgz\";;\n  'Linux arm64' | 'Linux aarch64') curl -fo \"$tgz\" \"https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-$ESBUILD_VERSION.tgz\";;\n  'Linux x86_64') curl -fo \"$tgz\" \"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-$ESBUILD_VERSION.tgz\";;\n  'NetBSD amd64') curl -fo \"$tgz\" \"https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-$ESBUILD_VERSION.tgz\";;\n  'OpenBSD arm64') curl -fo \"$tgz\" \"https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-$ESBUILD_VERSION.tgz\";;\n  'OpenBSD amd64') curl -fo \"$tgz\" \"https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-$ESBUILD_VERSION.tgz\";;\n  *) echo \"error: Unsupported platform: $platform\"; exit 1\nesac\n\n# Extract the binary executable to the current directory\ntar -xzf \"$tgz\" -C \"$dir\" package/bin/esbuild\nmv \"$dir/package/bin/esbuild\" .\nrm \"$tgz\"\n"
  },
  {
    "path": "docs/architecture.md",
    "content": "* [Architecture](#architecture)\n    * [Design principles](#design-principles)\n* [Overview](#overview)\n    * [Scan phase](#scan-phase)\n    * [Compile phase](#compile-phase)\n* [Notes about parsing](#notes-about-parsing)\n    * [Symbols and scopes](#symbols-and-scopes)\n    * [Constant folding](#constant-folding)\n    * [TypeScript parsing](#typescript-parsing)\n* [Notes about linking](#notes-about-linking)\n    * [CommonJS linking](#commonjs-linking)\n    * [ES6 linking](#es6-linking)\n    * [Hybrid CommonJS and ES6 modules](#hybrid-commonjs-and-es6-modules)\n    * [Scope hoisting](#scope-hoisting)\n    * [Converting ES6 imports to CommonJS imports](#converting-es6-imports-to-commonjs-imports)\n    * [The runtime library](#the-runtime-library)\n    * [Tree shaking](#tree-shaking)\n    * [Code splitting](#code-splitting)\n* [Notes about printing](#notes-about-printing)\n    * [Symbol minification](#symbol-minification)\n\n# Architecture Documentation\n\nThis document covers how esbuild's bundler works. It's intended to aid in understanding the code, in understanding what tricks esbuild uses to improve performance, and hopefully to enable people to modify the code.\n\nNote that there are some design decisions that have been made differently than other bundlers for performance reasons. These decisions may make the code harder to work with. Keep in mind that this project is an experiment in progress, and is not the result of a comprehensive survey of implementation techniques. The way things work now is not necessarily the best way of doing things.\n\n### Design principles\n\n* **Maximize parallelism**\n\n    Most of the time should be spent doing fully parallelizable work. This can be observed by taking a CPU trace using the `--trace=[file]` flag and viewing it using `go tool trace [file]`.\n\n* **Avoid doing unnecessary work**\n\n    For example, many bundlers have intermediate stages where they write out JavaScript code and read it back in using another tool. This work is unnecessary because if the tools used the same data structures, no conversion would be needed.\n\n* **Transparently support both ES6 and CommonJS module syntax**\n\n    The parser in esbuild processes a superset of both ES6 and CommonJS modules. It doesn't distinguish between ES6 modules and other modules so you can use both ES6 and CommonJS syntax in the same file if you'd like.\n\n* **Try to do as few full-AST passes as possible for better cache locality**\n\n    Compilers usually have many more passes because separate passes makes code easier to understand and maintain. There are currently only three full-AST passes in esbuild because individual passes have been merged together as much as possible:\n\n    1. Lexing + parsing + scope setup + symbol declaration\n    2. Symbol binding + constant folding + syntax lowering + syntax mangling\n    3. Printing + source map generation\n\n* **Structure things to permit a \"watch mode\" where compilation can happen incrementally**\n\n    Incremental builds mean only rebuilding changed files to the greatest extent possible. This means not re-running any of the full-AST passes on unchanged files. Data structures that live across builds must be immutable to allow sharing. Unfortunately the Go type system can't enforce this, so care must be taken to uphold this as the code evolves.\n\n## Overview\n\n<p align=\"center\"><img src=\"../images/build-pipeline.png\" alt=\"Diagram of build pipeline\" width=\"752\"></p>\n\nThe build pipeline has two main phases: scan and compile. These both reside in [bundler.go](../internal/bundler/bundler.go).\n\n### Scan phase\n\nThis phase starts with a set of entry points and traverses the dependency graph to find all modules that need to be in the bundle. This is implemented in `bundler.ScanBundle()` as a parallel worklist algorithm. The worklist starts off being the list of entry points. Each file in the list is parsed into an AST on a separate goroutine and may add more files to the worklist if it has any dependencies (either ES6 `import` statements, ES6 `import()` expressions, or CommonJS `require()` expressions). Scanning continues until the worklist is empty.\n\n### Compile phase\n\nThis phase creates a bundle for each entry point, which involves first \"linking\" imports with exports, then converting the parsed ASTs back into JavaScript, then concatenating them together to form the final bundled file. This happens in `(*Bundle).Compile()`.\n\n## Notes about parsing\n\nThe parser is separate from the lexer. The lexer is called on the fly as the file is parsed instead of lexing the entire input ahead of time. This is necessary due to certain syntactical features such as regular expressions vs. the division operator and JSX elements vs. the less-than operator, where which token is parsed depends on the semantic context.\n\nLexer lookahead has been kept to one token in almost all cases with the notable exception of TypeScript, which requires arbitrary lookahead to parse correctly. All such cases are in methods called `trySkipTypeScript*WithBacktracking()` in the parser.\n\nThe parser includes a lot of transformations, all of which have been condensed into just two passes for performance:\n\n1. The first pass does lexing and parsing, sets up the scope tree, and declares all symbols in their respective scopes.\n\n2. The second pass binds all identifiers to their respective symbols using the scope tree, substitutes compile-time definitions for their values, performs constant folding, does lowering of syntax if we're targeting an older version of JavaScript, and performs syntax mangling/compression if we're doing a production build.\n\nNote that, from experience, the overhead of syscalls in import path resolution is appears to be very high. Caching syscall results in the resolver and the file system implementation is a very sizable speedup.\n\n### Symbols and scopes\n\nA symbol is a way to refer to an identifier in a precise way. Symbols are referenced using a 64-bit identifier instead of using the name, which makes them easy to refer to without worrying about scope. For example, the parser can generate new symbols without worrying about name collisions. All identifiers reference a symbol, even \"unbound\" ones that don't have a matching declaration. Symbols have to be declared in a separate pass from the pass that binds identifiers to symbols because JavaScript has \"variable hoisting\" where a child scope can declare a hoisted symbol that can become bound to identifiers in parent and sibling scopes.\n\nSymbols for the whole file are stored in a flat top-level array. That way you can easily traverse over all symbols in the file without traversing the AST. That also lets us easily create a modified AST where the symbols have been changed without affecting the original immutable AST. Because symbols are identified by their index into the top-level symbol array, we can just clone the array to clone the symbols and we don't need to worry about rewiring all of the symbol references.\n\nThe scope tree is not attached to the AST because it's really only needed to pass information from the first pass to the second pass. The scope tree is instead temporarily mapped onto the AST within the parser. This is done by having the first and second passes both call `pushScope*()` and `popScope()` the same number of times in the same order. Specifically the first pass calls `pushScopeForParsePass()` which appends the pushed scope to `scopesInOrder`, and the second pass calls `pushScopeForVisitPass()` which reads off the scope to push from `scopesInOrder`.\n\nThis is mostly pretty straightforward except for a few places where the parser has pushed a scope and is in the middle of parsing a declaration only to discover that it's not a declaration after all. This happens in TypeScript when a function is forward-declared without a body, and in JavaScript when it's ambiguous whether a parenthesized expression is an arrow function or not until we reach the `=>` token afterwards. This would be solved by doing three passes instead of two so we finish parsing before starting to set up scopes and declare symbols, but we're trying to do this in just two passes. So instead we call `popAndDiscardScope()` or `popAndFlattenScope()` instead of `popScope()` to modify the scope tree later if our assumptions turn out to be incorrect.\n\n### Constant folding\n\nThe constant folding and compile-time definition substitution is pretty minimal but is enough to handle libraries such as React which contain code like this:\n\n```js\nif (process.env.NODE_ENV === 'production') {\n  module.exports = require('./cjs/react.production.min.js');\n} else {\n  module.exports = require('./cjs/react.development.js');\n}\n```\n\nUsing `--define:process.env.NODE_ENV=\"production\"` on the command line will cause `process.env.NODE_ENV === 'production'` to become `\"production\" === 'production'` which will then become `true`. The parser then treats the `else` branch as dead code, which means it ignores calls to `require()` and `import()` inside that branch. The `react.development.js` module is never included in the dependency graph.\n\n### TypeScript parsing\n\nTypeScript parsing has been implemented by augmenting the existing JavaScript parser. Most of it just involves skipping over type declarations as if they are whitespace. Enums, namespaces, and TypeScript-only class features such as parameter properties must all be converted to JavaScript syntax, which happens in the second parser pass. I've attempted to match what the TypeScript compiler does as close as is reasonably possible.\n\nOne TypeScript subtlety is that unused imports in TypeScript code must be removed, since they may be type-only imports. And if all imports in an import statement are removed, the whole import statement itself must also be removed. This has semantic consequences because the import may have side effects. However, it's important for correctness because this is how the TypeScript compiler itself works. The imported package itself may not actually even exist on disk since it may only come from a `declare` statement. Tracking used imports is handled by the `tsUseCounts` field in the parser.\n\n## Notes about linking\n\nThe main goal of linking is to merge multiple modules into a single file so that imports from one module can reference exports from another module. This is accomplished in several different ways depending on the import and export features used.\n\nLinking performs an optimization called \"tree shaking\". This is also known as \"dead code elimination\" and removes unreferenced code from the bundle to reduce bundle size. Tree shaking is always active and cannot be disabled.\n\nFinally, linking may also involve dividing the input code among multiple chunks. This is known as \"code splitting\" and both allows lazy loading of code and sharing code between multiple entry points. It's disabled by default in esbuild but can be enabled with the `--splitting` flag.\n\nThis will all be described in more detail below.\n\n### CommonJS linking\n\nIf a module uses any CommonJS features (e.g. references `exports`, references `module`, or uses a top-level `return` statement) then it's considered a CommonJS module. This means it's represented as a separate closure within the bundle. This is similar to how Webpack normally works.\n\nHere's a simplified example to explain what this looks like:\n\n<table>\n<tr><th>foo.js</th><th>bar.js</th><th>bundle.js</th></tr>\n<tr><td>\n\n```js\nexports.fn = () => 123\n```\n\n</td><td>\n\n```js\nconst foo = require('./foo')\nconsole.log(foo.fn())\n```\n\n</td><td>\n\n```js\nlet __commonJS = (callback, module) => () => {\n  if (!module) {\n    module = {exports: {}};\n    callback(module.exports, module);\n  }\n  return module.exports;\n};\n\n// foo.js\nvar require_foo = __commonJS((exports) => {\n  exports.fn = () => 123;\n});\n\n// bar.js\nconst foo = require_foo();\nconsole.log(foo.fn());\n```\n\n</td></tr>\n</table>\n\nThe benefit of bundling modules this way is for compatibility. This emulates exactly [how node itself will run your module](https://nodejs.org/api/modules.html#modules_the_module_wrapper).\n\n### ES6 linking\n\nIf a module doesn't use any CommonJS features, then it's considered an ES6 module. This means it's represented as part of a cross-module scope that may contain many other ES6 modules. This is often known as \"scope hoisting\" and is how Rollup normally works.\n\nHere's a simplified example to explain what this looks like:\n\n<table>\n<tr><th>foo.js</th><th>bar.js</th><th>bundle.js</th></tr>\n<tr><td>\n\n```js\nexport const fn = () => 123\n```\n\n</td><td>\n\n```js\nimport {fn} from './foo'\nconsole.log(fn())\n```\n\n</td><td>\n\n```js\n// foo.js\nconst fn = () => 123;\n\n// bar.js\nconsole.log(fn());\n```\n\n</td></tr>\n</table>\n\nThe benefit of distinguishing between CommonJS and ES6 modules is that bundling ES6 modules is more efficient, both because the generated code is smaller and because symbols are statically bound instead of dynamically bound, which has less overhead at run time.\n\nES6 modules also allow for \"tree shaking\" optimizations which remove unreferenced code from the bundle. For example, if the call to `fn()` is commented out in the above example, the variable `fn` will be omitted from the bundle since it's not used and its definition doesn't have any side effects. This is possible with ES6 modules but not with CommonJS because ES6 imports are bound at compile time while CommonJS imports are bound at run time.\n\n### Hybrid CommonJS and ES6 modules\n\nThese two syntaxes are supported side-by-side as transparently as possible. This means you can use both CommonJS syntax (`exports` and `module` assignments and `require()` calls) and ES6 syntax (`import` and `export` statements and `import()` expressions) in the same module. The ES6 imports will be converted to `require()` calls and the ES6 exports will be converted to getters on that module's `exports` object.\n\n### Scope hoisting\n\nScope hoisting (the merging of all scopes in a module group into a single scope) is implemented using symbol merging. Each imported symbol is merged with the corresponding exported symbol so that they become the same symbol in the output, which means they both get the same name. Symbol merging is possible because each symbol has a `Link` field that, when used, forwards to another symbol. The implementation of `MergeSymbols()` essentially just links one symbol to the other one. Whenever the printer sees a symbol reference it must call `FollowSymbols()` to get to the symbol at the end of the link chain, which represents the final merged symbol. This is similar to the [union-find data structure](https://en.wikipedia.org/wiki/Disjoint-set_data_structure) if you're familiar with it.\n\nDuring bundling, the symbol maps from all files are merged into a single giant symbol map, which allows symbols to be merged across files. The symbol map is represented as an array-of-arrays and a symbol reference is represented as two indices, one for the outer array and one for the inner array. The array-of-arrays representation is convenient because the parser produces a single symbol array for each file. Merging them all into a single map is as simple as making an array of the symbol arrays for each file. Each source file is identified using an incrementing index allocated during the scanning phase, so the index of the outer array is just the index of the source file.\n\n### Converting ES6 imports to CommonJS imports\n\nOne complexity around scope hoisting is that references to ES6 imports may either be a bare identifier (i.e. statically bound) or a property access off of a `require()` call (i.e. dynamically bound) depending on whether the imported module is a CommonJS-style module or not. This information isn't known yet when we're still parsing the file so we are unable to determine whether to create `EIdentifier` or `EDot` AST nodes for these imports.\n\nTo handle this, references to ES6 imports use the special `EImportIdentifier` AST node. Later during linking we can decide if these references to a symbol need to be turned into a property access and, if so, fill in the `NamespaceAlias` field on the symbol. The printer checks that field for `EImportIdentifier` expressions and, if present, prints a property access instead of an identifier. This avoids having to do another full-AST traversal just to replace identifiers with property accesses before printing.\n\n### The runtime library\n\nThis library contains support code that is needed to implement various aspects of JavaScript transformation and bundling. For example, it contains the `__commonJS()` helper function for wrapping CommonJS modules and the `__decorate()` helper function for implementing TypeScript decorators. The code lives in a single string in [runtime.go](../internal/runtime/runtime.go). It's automatically included in every build and esbuild's tree shaking feature automatically strips out unused code. If you need to add a helper function for esbuild to call, it should be added to this library.\n\n### Tree shaking\n\nThe goal of tree shaking is to remove code that will never be used from the final bundle, which reduces download and parse time. Tree shaking treats the input files as a graph. Each node in the graph is a top-level statement, which is called a \"part\" in the code. Tree shaking is a graph traversal that starts from the entry point and marks all traversed parts for inclusion.\n\nEach part may declare symbols, reference symbols, and depend on other files. Parts are also marked as either having side effects or not. For example, the statement `let foo = 123` does not have side effects because, if nothing needs `foo`, the statement can be removed without any observable difference. But the statement `let foo = bar()` does have side effects because even if nothing needs `foo`, the call to `bar()` cannot be removed without changing the meaning of the code.\n\nIf part A references a symbol declared in part B, the graph has an edge from A to B. References can span across files due to ES6 imports and exports. And if part A depends on file C, the graph has an edge from A to every part in C with side effects. A part depends on a file if it contains an ES6 `import` statement, a CommonJS `require()` call, or an ES6 `import()` expression.\n\nTree shaking begins by visiting all parts in the entry point file with side effects, and continues traversing along graph edges until no more new parts are reached. Once the traversal has finished, only parts that were reached during the traversal are included in the bundle. All other parts are excluded.\n\nHere's an example to make this easier to visualize:\n\n<p align=\"center\"><img src=\"../images/tree-shaking.png\" alt=\"Diagram of tree shaking\" width=\"793\"></p>\n\nThere are three input files: `index.js`, `config.js`, and `net.js`. Tree shaking traverses along all graph edges from `index.js` (the entry point). The two types of edges are shown with different arrows. Solid arrows are edges due to parts with side effects. These parts must be included regardless of whether the symbols they declare are used or not. Dashed arrows are edges from symbol references to the parts that declare those symbols. These parts don't have side effects and are only included if symbol they declare is referenced.\n\nThe final bundle only includes the code visited during the tree shaking traversal. That looks like this:\n\n```js\n// net.js\nfunction get(url) {\n  return fetch(url).then((r) => r.text());\n}\n\n// config.js\nlet session = Math.random();\nlet api = \"/api?session=\";\nfunction load() {\n  return get(api + session);\n}\n\n// index.js\nlet el = document.getElementById(\"el\");\nload().then((x) => el.textContent = x);\n```\n\n### Code splitting\n\nCode splitting analyzes bundles with multiple entry points and divides code into chunks such that a) a given piece of code is only ever in one chunk and b) each entry point doesn't download code that it will never use. Note that the target of each dynamic `import()` expression is considered an additional entry point.\n\nSplitting shared code into separate chunks means that downloading the code for two entry points only downloads the shared code once. It also allows code that's only needed for an asynchronous `import()` dependency to be lazily loaded.\n\nCode splitting is implemented as an advanced form of tree shaking. The tree shaking traversal described above is run once for each entry point. Every part (i.e. node in the graph) stores all of the entry points that reached it during the traversal for that entry point. Then the combination of entry points for a given part determines what chunk that part ends up in.\n\nTo continue the tree shaking example above, let's add a second entry point called `settings.js` that uses a different but overlapping set of parts. Tree shaking is run again starting from this new entry point:\n\n<p align=\"center\"><img src=\"../images/code-splitting-1.png\" alt=\"Diagram of code splitting\" width=\"793\"></p>\n\nThese two tree shaking passes result in three chunks: all parts only reachable from `index.js`, all parts only reachable from `settings.js`, and all parts reachable from both `index.js` and `settings.js`. Parts belonging to the three chunks are colored red, blue, and purple in the visualization below:\n\n<p align=\"center\"><img src=\"../images/code-splitting-2.png\" alt=\"Diagram of code splitting\" width=\"793\"></p>\n\nAfter all chunks are identified, the chunks are linked together by automatically generating import and export statements for references to symbols that are declared in another chunk. Import statements must also be inserted for chunks that don't have any exported symbols. This represents shared code with side effects, and code with side effects must be retained.\n\nHere are the final code splitting chunks for this example after linking:\n\n<table>\n<tr><th>Chunk for index.js</th><th>Chunk for settings.js</th><th>Chunk for shared code</th></tr>\n<tr><td>\n\n```js\nimport {\n  api,\n  session\n} from \"./chunk.js\";\n\n// net.js\nfunction get(url) {\n  return fetch(url).then((r) => r.text());\n}\n\n// config.js\nfunction load() {\n  return get(api + session);\n}\n\n// index.js\nlet el = document.getElementById(\"el\");\nload().then((x) => el.textContent = x);\n```\n\n</td><td>\n\n```js\nimport {\n  api,\n  session\n} from \"./chunk.js\";\n\n// net.js\nfunction put(url, body) {\n  fetch(url, {method: \"PUT\", body});\n}\n\n// config.js\nfunction save(value) {\n  return put(api + session, value);\n}\n\n// settings.js\nlet it = document.getElementById(\"it\");\nit.oninput = () => save(it.value);\n```\n\n</td><td>\n\n```js\n// config.js\nlet session = Math.random();\nlet api = \"/api?session=\";\n\nexport {\n  api,\n  session\n};\n```\n\n</td></tr>\n</table>\n\nThere is one additional complexity to code splitting due to how ES6 module boundaries work. Code splitting must not be allowed to move an assignment to a module-local variable into a separate chunk from the declaration of that variable. ES6 imports are read-only and cannot be assigned to, so doing this will cause the assignment to crash at run time.\n\nTo illustrate the problem, consider these three files:\n\n<table>\n<tr><th>entry1.js</th><th>entry2.js</th><th>data.js</th></tr>\n<tr><td>\n\n```js\nimport {data} from './data'\nconsole.log(data)\n```\n\n</td><td>\n\n```js\nimport {setData} from './data'\nsetData(123)\n```\n\n</td><td>\n\n```js\nexport let data\nexport function setData(value) {\n  data = value\n}\n```\n\n</td></tr>\n</table>\n\nIf the two entry points `entry1.js` and `entry2.js` are bundled with the code splitting algorithm described above, the result will be this invalid code:\n\n<table>\n<tr><th>Chunk for entry1.js</th><th>Chunk for entry2.js</th><th>Chunk for shared code</th></tr>\n<tr><td>\n\n```js\nimport {\n  data\n} from \"./chunk.js\";\n\n// entry1.js\nconsole.log(data);\n```\n\n</td><td>\n\n```js\nimport {\n  data\n} from \"./chunk.js\";\n\n// data.js\nfunction setData(value) {\n  data = value;\n}\n\n// entry2.js\nsetData(123);\n```\n\n</td><td>\n\n```js\n// data.js\nlet data;\n\nexport {\n  data\n};\n```\n\n</td></tr>\n</table>\n\nThe assignment `data = value` will crash at run time with `TypeError: Assignment to constant variable`. To fix this, we must make sure that assignment ends up in the same chunk as the declaration `let data`.\n\nThis is done by linking the parts with the assignments and the parts with the symbol declarations together such that their entry point sets are the same. That way all of those parts are marked as reachable from all entry points that can reach any of those parts. Note that linking a group of parts together also involves marking all dependencies of all parts in that group as reachable from those entry points too, including propagathing through any part groups those dependencies are already linked with, recursively.\n\nThe grouping of parts can be non-trivial because there may be many parts involved and many assignments to different variables. Grouping is done by finding connected components on the graph where nodes are parts and edges are cross-part assignments.\n\nWith this algorithm, the function `setData` in our example moves into the chunk of shared code after being bundled with code splitting:\n\n<table>\n<tr><th>Chunk for entry1.js</th><th>Chunk for entry2.js</th><th>Chunk for shared code</th></tr>\n<tr><td>\n\n```js\nimport {\n  data\n} from \"./chunk.js\";\n\n// entry1.js\nconsole.log(data);\n```\n\n</td><td>\n\n```js\nimport {\n  setData\n} from \"./chunk.js\";\n\n// entry2.js\nsetData(123);\n```\n\n</td><td>\n\n```js\n// data.js\nlet data;\nfunction setData(value) {\n  data = value;\n}\n\nexport {\n  data,\n  setData\n};\n```\n\n</td></tr>\n</table>\n\nThis code no longer contains assignments to cross-chunk variables.\n\n## Notes about printing\n\nThe printer converts JavaScript ASTs back into JavaScript source code. This is mainly intended to be consumed by the JavaScript VM for execution, with a secondary goal of being readable enough to debug when minification is disabled. It's not intended to be used as a code formatting tool and does not make complex formatting decisions. It handles the insertion of parentheses to preserve operator precedence as appropriate.\n\nEach file is printed independently from other files, so files can be printed in parallel. This extends to source map generation. As each file is printed, the printer builds up a \"source map chunk\" which is a [VLQ](https://en.wikipedia.org/wiki/Variable-length_quantity)-encoded sequence of source map offsets assuming the output file starts with the AST currently being printed. That source map chunk will later be \"rebased\" to start at the correct offset when all source map chunks are joined together. This is done by rewriting the first item in the sequence, which happens in `AppendSourceMapChunk()`.\n\nThe current AST representation uses a single integer offset per AST node to store the location information. This is the index of the starting byte for that syntax construct in the original source file. Using this representation means that it's not possible to merge ASTs from two separate files and still have source maps work. That's not a problem since AST printing is fully parallelized in esbuild, but is something to keep in mind when modifying the code.\n\n### Symbol minification\n\nAn important part of JavaScript minification is symbol renaming. Internal symbols (i.e. those not externally visible) can be renamed to shorter names without changing the meaning of the code. That looks something like this:\n\n<table>\n<tr><th>Original code</th><th>Code with symbol minification</th></tr>\n<tr><td>\n\n```js\nfunction useReducer(reducer, initialState) {\n  let [state, setState] = useState(initialState);\n  function dispatch(action) {\n    let nextState = reducer(state, action);\n    setState(nextState);\n  }\n  return [state, dispatch];\n}\n```\n\n</td><td>\n\n```js\nfunction useReducer(b, c) {\n  let [a, d] = useState(c);\n  function e(f) {\n    let g = b(a, f);\n    d(g);\n  }\n  return [a, e];\n}\n```\n\n</td></tr>\n</table>\n\nIt may initially seem like we can easily rename all symbols to a single character by assigning a unicode character to each one. There are over 100,000 unicode characters that are valid JavaScript identifiers after all. However, the goal is actually to use as few bytes as possible, and most unicode characters use multiple bytes when encoded as UTF-8.\n\nFor this reason most JavaScript minifiers (including esbuild) restrict generated symbols to ASCII-only. With ASCII, JavaScript has only 54 possible one-character identifiers and 3453 possible two-character identifiers, so we should use the shortest names to rename the most frequently used symbols so that we can save the most bytes.\n\nAnother consideration is that symbols in sibling scopes can share the same name without conflicting due to scoping rules. We can use this to our advantage by deliberately merging unrelated symbols in independent scopes, and then adding the frequency statistics of all of these symbols together before generating the final names.\n\nSomething to keep in mind when renaming symbols is that the resulting JavaScript will likely be compressed before being downloaded, usually with gzip compression. Repeated sequences of characters will compress better than unique sequences of characters. A trick esbuild borrows from [Google Closure Compiler](https://github.com/google/closure-compiler) is to merge the symbols for arguments of sibling functions together:\n\n```js\n// Before renaming\nfunction readFile(path, encoding, callback) { ... }\nfunction writeFile(path, contents, mode, callback) { ... }\n```\n\n```js\n// After renaming\nfunction x(a, b, c) { ... }\nfunction y(a, b, c, d) { ... }\n```\n\nBecause the symbols for the function arguments have been merged together in order, the character sequence `a, b, c` is present in both functions which should help with gzip compression. This is handled in esbuild by assigning each symbol in a nested (i.e. not top-level) scope a \"slot\", which is an incrementing index into an array of frequency counters. The symbols `a`, `b`, `c`, and `d` would be assigned slots `0`, `1`, `2`, and `3` in the example above. This approach is extra helpful for esbuild because slot assignments can be computed in parallel.\n\nThe algorithm:\n\n1. For each input source file (in parallel)\n\n    1. Track information for each top-level statement while parsing\n\n        Each top-level statement tracks the which symbols are used, how many times each symbol is used, which symbols it defines, and which nested scopes that top-level statement contains. Code splitting operates on top-level statement boundaries, so this information will tell us exactly what symbols to include in the frequency analysis after code splitting is complete. This information is collected during parsing.\n\n    2. Assign slots to symbols in nested scopes\n\n        Traverse the scope tree and assign slots to all symbols declared within each scope (skipping top-level scopes). Each scope in the scope tree starts assigning slots immediately after the maximum slot of the parent scope.\n\n2. For each output chunk file (in parallel)\n\n    1. Create an array of frequency counters\n\n        Each counter is indexed by slot and all counts are initially 0. The array length starts off being large enough to handle the maximum slot value of all files included in the chunk.\n\n    2. Assign slots for top-level symbols\n\n        For each top-level statement included in the chunk, iterate over all top-level symbols declared in that statement and assign each symbol to a new slot by appending to the counter array. This slot will not overlap with any slots from nested scopes. The count starts off at 1 to represent the declaration.\n\n    3. Accumulate symbol usage counts into slots\n\n        For each top-level statement included in the chunk, iterate over all symbol use records and increment the counter in that symbol's slot by the stored count from the symbol use record.\n\n    4. Sort slots by decreasing count\n\n        This should tell us which symbol slots should be assigned the shortest names to minimize file size.\n\n    5. Assign names to slots in order\n\n        Names are assigned from a fixed sequence of identifiers that starts off using one-character names, then two-character names, and so on (i.e. `a b c ... aa ba ca ... aaa baa caa ...`). We must be careful to avoid any JavaScript keywords such as `do` and `if` that would cause syntax errors. We must also avoid the names of any \"unbound\" symbols, which are symbols that are used without being declared such as `$` for jQuery.\n\n    6. When printing, use the name in that symbol's slot\n\n        The printer only needs access to the array containing the names (indexed by slot) and a way of mapping a symbol reference to a slot index. This is a compact representation that doesn't need a lot of memory per chunk because the slot array length is O(unique symbol names) instead of O(number of symbols). The mapping of symbols from nested scopes (which is usually the majority of symbols) to their slot index is static and can be shared between all chunks.\n\nIt's worth mentioning that this algorithm must be performed three separate times because there are three separate symbol namespaces in JavaScript that need minification: normal symbols, [label symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label), and [private symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields). The same name in separate namespaces can't conflict with each other, so it's ok to reuse the same name across namespaces.\n"
  },
  {
    "path": "docs/development.md",
    "content": "# Development\n\nHere are some quick notes about how I develop esbuild.\n\n## Primary workflow\n\nMy development workflow revolves around the top-level [`Makefile`](../Makefile), which I use as a script runner.\n\n1. **Build**\n\nAssuming you have [Go](https://go.dev/) installed, you can compile esbuild by running `make` in the top-level directory (or `go build ./cmd/esbuild` if you don't have `make` installed). This creates an executable called `esbuild` (or `esbuild.exe` on Windows).\n\n2. **Test**\n\nYou can run the tests written in Go by running `make test-go` in the top-level directory (or `go test ./internal/... ./pkg/...` if you don't have `make` installed).\n\nIf you want to run more kinds of tests, you can run `make test` instead. This requires installing [node](https://nodejs.org/). And it's possible to run even more tests than that with additional `make` commands (read the [`Makefile`](../Makefile) for details).\n\n3. **Publish**\n\nHere's what I do to publish a new release:\n\n1. Bump the version in [`version.txt`](../version.txt)\n2. Copy that version into [`CHANGELOG.md`](../CHANGELOG.md)\n3. Run `make publish-all` and follow the prompts\n\n## Running in the browser\n\nIf you want to test esbuild in the browser (lets you try out lots of things rapidly), you can:\n\n1. Run `make platform-wasm` to build the WebAssembly version of esbuild\n2. Serve the repo directory over HTTP (such as with `./esbuild --servedir=.`)\n3. Visit [`/scripts/try.html`](../scripts/try.html) in your browser\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/evanw/esbuild\n\n// Support for Go 1.13 is deliberate so people can build esbuild\n// themselves for old OS versions. Please do not change this.\ngo 1.13\n\n// This dependency cannot be upgraded or esbuild would no longer\n// compile with Go 1.13. Please do not change this. For more info,\n// please read this: https://esbuild.github.io/faq/#old-go-version\nrequire golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8\n"
  },
  {
    "path": "go.sum",
    "content": "golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\n"
  },
  {
    "path": "go.version",
    "content": "1.25.7\n"
  },
  {
    "path": "internal/api_helpers/use_timer.go",
    "content": "package api_helpers\n\n// This flag is set by the CLI to activate the timer. It's put here instead of\n// by the timer to discourage code from checking this flag. Only the code that\n// creates the root timer should check this flag. Other code should check that\n// the timer is not null to detect if the timer is being used or not.\nvar UseTimer bool\n"
  },
  {
    "path": "internal/ast/ast.go",
    "content": "package ast\n\n// This file contains data structures that are used with the AST packages for\n// both JavaScript and CSS. This helps the bundler treat both AST formats in\n// a somewhat format-agnostic manner.\n\nimport (\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\ntype ImportKind uint8\n\nconst (\n\t// An entry point provided by the user\n\tImportEntryPoint ImportKind = iota\n\n\t// An ES6 import or re-export statement\n\tImportStmt\n\n\t// A call to \"require()\"\n\tImportRequire\n\n\t// An \"import()\" expression with a string argument\n\tImportDynamic\n\n\t// A call to \"require.resolve()\"\n\tImportRequireResolve\n\n\t// A CSS \"@import\" rule\n\tImportAt\n\n\t// A CSS \"composes\" declaration\n\tImportComposesFrom\n\n\t// A CSS \"url(...)\" token\n\tImportURL\n)\n\nfunc (kind ImportKind) StringForMetafile() string {\n\tswitch kind {\n\tcase ImportStmt:\n\t\treturn \"import-statement\"\n\tcase ImportRequire:\n\t\treturn \"require-call\"\n\tcase ImportDynamic:\n\t\treturn \"dynamic-import\"\n\tcase ImportRequireResolve:\n\t\treturn \"require-resolve\"\n\tcase ImportAt:\n\t\treturn \"import-rule\"\n\tcase ImportComposesFrom:\n\t\treturn \"composes-from\"\n\tcase ImportURL:\n\t\treturn \"url-token\"\n\tcase ImportEntryPoint:\n\t\treturn \"entry-point\"\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\nfunc (kind ImportKind) IsFromCSS() bool {\n\tswitch kind {\n\tcase ImportAt, ImportComposesFrom, ImportURL:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (kind ImportKind) MustResolveToCSS() bool {\n\tswitch kind {\n\tcase ImportAt, ImportComposesFrom:\n\t\treturn true\n\t}\n\treturn false\n}\n\ntype ImportPhase uint8\n\nconst (\n\tEvaluationPhase ImportPhase = iota\n\n\t// See: https://github.com/tc39/proposal-defer-import-eval\n\tDeferPhase\n\n\t// See: https://github.com/tc39/proposal-source-phase-imports\n\tSourcePhase\n)\n\ntype ImportRecordFlags uint16\n\nconst (\n\t// Sometimes the parser creates an import record and decides it isn't needed.\n\t// For example, TypeScript code may have import statements that later turn\n\t// out to be type-only imports after analyzing the whole file.\n\tIsUnused ImportRecordFlags = 1 << iota\n\n\t// If this is true, the import contains syntax like \"* as ns\". This is used\n\t// to determine whether modules that have no exports need to be wrapped in a\n\t// CommonJS wrapper or not.\n\tContainsImportStar\n\n\t// If this is true, the import contains an import for the alias \"default\",\n\t// either via the \"import x from\" or \"import {default as x} from\" syntax.\n\tContainsDefaultAlias\n\n\t// If this is true, the import contains an import for the alias \"__esModule\",\n\t// via the \"import {__esModule} from\" syntax.\n\tContainsESModuleAlias\n\n\t// If true, this \"export * from 'path'\" statement is evaluated at run-time by\n\t// calling the \"__reExport()\" helper function\n\tCallsRunTimeReExportFn\n\n\t// Tell the printer to wrap this call to \"require()\" in \"__toESM(...)\"\n\tWrapWithToESM\n\n\t// Tell the printer to wrap this ESM exports object in \"__toCJS(...)\"\n\tWrapWithToCJS\n\n\t// Tell the printer to use the runtime \"__require()\" instead of \"require()\"\n\tCallRuntimeRequire\n\n\t// True for the following cases:\n\t//\n\t//   try { require('x') } catch { handle }\n\t//   try { await import('x') } catch { handle }\n\t//   try { require.resolve('x') } catch { handle }\n\t//   import('x').catch(handle)\n\t//   import('x').then(_, handle)\n\t//\n\t// In these cases we shouldn't generate an error if the path could not be\n\t// resolved.\n\tHandlesImportErrors\n\n\t// If true, this was originally written as a bare \"import 'file'\" statement\n\tWasOriginallyBareImport\n\n\t// If true, this import can be removed if it's unused\n\tIsExternalWithoutSideEffects\n\n\t// If true, \"assert { type: 'json' }\" was present\n\tAssertTypeJSON\n\n\t// If true, do not generate \"external\": true in the metafile\n\tShouldNotBeExternalInMetafile\n\n\t// CSS \"@import\" of an empty file should be removed\n\tWasLoadedWithEmptyLoader\n\n\t// Unique keys are randomly-generated strings that are used to replace paths\n\t// in the source code after it's printed. These must not ever be split apart.\n\tContainsUniqueKey\n)\n\nfunc (flags ImportRecordFlags) Has(flag ImportRecordFlags) bool {\n\treturn (flags & flag) != 0\n}\n\ntype ImportRecord struct {\n\tAssertOrWith *ImportAssertOrWith\n\tGlobPattern  *GlobPattern\n\tPath         logger.Path\n\tRange        logger.Range\n\n\t// If the \"HandlesImportErrors\" flag is present, then this is the location\n\t// of the error handler. This is used for error reporting.\n\tErrorHandlerLoc logger.Loc\n\n\t// The resolved source index for an internal import (within the bundle) or\n\t// invalid for an external import (not included in the bundle)\n\tSourceIndex Index32\n\n\t// Files imported via the \"copy\" loader use this instead of \"SourceIndex\"\n\t// because they are sort of like external imports, and are not bundled.\n\tCopySourceIndex Index32\n\n\tFlags ImportRecordFlags\n\tPhase ImportPhase\n\tKind  ImportKind\n}\n\ntype AssertOrWithKeyword uint8\n\nconst (\n\tAssertKeyword AssertOrWithKeyword = iota\n\tWithKeyword\n)\n\nfunc (kw AssertOrWithKeyword) String() string {\n\tif kw == AssertKeyword {\n\t\treturn \"assert\"\n\t}\n\treturn \"with\"\n}\n\ntype ImportAssertOrWith struct {\n\tEntries            []AssertOrWithEntry\n\tKeywordLoc         logger.Loc\n\tInnerOpenBraceLoc  logger.Loc\n\tInnerCloseBraceLoc logger.Loc\n\tOuterOpenBraceLoc  logger.Loc\n\tOuterCloseBraceLoc logger.Loc\n\tKeyword            AssertOrWithKeyword\n}\n\ntype AssertOrWithEntry struct {\n\tKey             []uint16 // An identifier or a string\n\tValue           []uint16 // Always a string\n\tKeyLoc          logger.Loc\n\tValueLoc        logger.Loc\n\tPreferQuotedKey bool\n}\n\nfunc FindAssertOrWithEntry(assertions []AssertOrWithEntry, name string) *AssertOrWithEntry {\n\tfor _, assertion := range assertions {\n\t\tif helpers.UTF16EqualsString(assertion.Key, name) {\n\t\t\treturn &assertion\n\t\t}\n\t}\n\treturn nil\n}\n\ntype GlobPattern struct {\n\tParts       []helpers.GlobPart\n\tExportAlias string\n\tKind        ImportKind\n}\n\n// This stores a 32-bit index where the zero value is an invalid index. This is\n// a better alternative to storing the index as a pointer since that has the\n// same properties but takes up more space and costs an extra pointer traversal.\ntype Index32 struct {\n\tflippedBits uint32\n}\n\nfunc MakeIndex32(index uint32) Index32 {\n\treturn Index32{flippedBits: ^index}\n}\n\nfunc (i Index32) IsValid() bool {\n\treturn i.flippedBits != 0\n}\n\nfunc (i Index32) GetIndex() uint32 {\n\treturn ^i.flippedBits\n}\n\ntype SymbolKind uint8\n\nconst (\n\t// An unbound symbol is one that isn't declared in the file it's referenced\n\t// in. For example, using \"window\" without declaring it will be unbound.\n\tSymbolUnbound SymbolKind = iota\n\n\t// This has special merging behavior. You're allowed to re-declare these\n\t// symbols more than once in the same scope. These symbols are also hoisted\n\t// out of the scope they are declared in to the closest containing function\n\t// or module scope. These are the symbols with this kind:\n\t//\n\t// - Function arguments\n\t// - Function statements\n\t// - Variables declared using \"var\"\n\t//\n\tSymbolHoisted\n\tSymbolHoistedFunction\n\n\t// There's a weird special case where catch variables declared using a simple\n\t// identifier (i.e. not a binding pattern) block hoisted variables instead of\n\t// becoming an error:\n\t//\n\t//   var e = 0;\n\t//   try { throw 1 } catch (e) {\n\t//     print(e) // 1\n\t//     var e = 2\n\t//     print(e) // 2\n\t//   }\n\t//   print(e) // 0 (since the hoisting stops at the catch block boundary)\n\t//\n\t// However, other forms are still a syntax error:\n\t//\n\t//   try {} catch (e) { let e }\n\t//   try {} catch ({e}) { var e }\n\t//\n\t// This symbol is for handling this weird special case.\n\tSymbolCatchIdentifier\n\n\t// Generator and async functions are not hoisted, but still have special\n\t// properties such as being able to overwrite previous functions with the\n\t// same name\n\tSymbolGeneratorOrAsyncFunction\n\n\t// This is the special \"arguments\" variable inside functions\n\tSymbolArguments\n\n\t// Classes can merge with TypeScript namespaces.\n\tSymbolClass\n\n\t// Class names are not allowed to be referenced by computed property keys\n\tSymbolClassInComputedPropertyKey\n\n\t// A class-private identifier (i.e. \"#foo\").\n\tSymbolPrivateField\n\tSymbolPrivateMethod\n\tSymbolPrivateGet\n\tSymbolPrivateSet\n\tSymbolPrivateGetSetPair\n\tSymbolPrivateStaticField\n\tSymbolPrivateStaticMethod\n\tSymbolPrivateStaticGet\n\tSymbolPrivateStaticSet\n\tSymbolPrivateStaticGetSetPair\n\n\t// Labels are in their own namespace\n\tSymbolLabel\n\n\t// TypeScript enums can merge with TypeScript namespaces and other TypeScript\n\t// enums.\n\tSymbolTSEnum\n\n\t// TypeScript namespaces can merge with classes, functions, TypeScript enums,\n\t// and other TypeScript namespaces.\n\tSymbolTSNamespace\n\n\t// In TypeScript, imports are allowed to silently collide with symbols within\n\t// the module. Presumably this is because the imports may be type-only.\n\tSymbolImport\n\n\t// Assigning to a \"const\" symbol will throw a TypeError at runtime\n\tSymbolConst\n\n\t// Injected symbols can be overridden by provided defines\n\tSymbolInjected\n\n\t// Properties can optionally be renamed to shorter names\n\tSymbolMangledProp\n\n\t// CSS identifiers that are never renamed\n\tSymbolGlobalCSS\n\n\t// CSS identifiers that are renamed to be unique to the file they are in\n\tSymbolLocalCSS\n\n\t// This annotates all other symbols that don't have special behavior\n\tSymbolOther\n)\n\nfunc (kind SymbolKind) IsPrivate() bool {\n\treturn kind >= SymbolPrivateField && kind <= SymbolPrivateStaticGetSetPair\n}\n\nfunc (kind SymbolKind) IsHoisted() bool {\n\treturn kind == SymbolHoisted || kind == SymbolHoistedFunction\n}\n\nfunc (kind SymbolKind) IsHoistedOrFunction() bool {\n\treturn kind.IsHoisted() || kind == SymbolGeneratorOrAsyncFunction\n}\n\nfunc (kind SymbolKind) IsFunction() bool {\n\treturn kind == SymbolHoistedFunction || kind == SymbolGeneratorOrAsyncFunction\n}\n\nfunc (kind SymbolKind) IsUnboundOrInjected() bool {\n\treturn kind == SymbolUnbound || kind == SymbolInjected\n}\n\nvar InvalidRef Ref = Ref{^uint32(0), ^uint32(0)}\n\n// Files are parsed in parallel for speed. We want to allow each parser to\n// generate symbol IDs that won't conflict with each other. We also want to be\n// able to quickly merge symbol tables from all files into one giant symbol\n// table.\n//\n// We can accomplish both goals by giving each symbol ID two parts: a source\n// index that is unique to the parser goroutine, and an inner index that\n// increments as the parser generates new symbol IDs. Then a symbol map can\n// be an array of arrays indexed first by source index, then by inner index.\n// The maps can be merged quickly by creating a single outer array containing\n// all inner arrays from all parsed files.\ntype Ref struct {\n\tSourceIndex uint32\n\tInnerIndex  uint32\n}\n\ntype LocRef struct {\n\tLoc logger.Loc\n\tRef Ref\n}\n\ntype ImportItemStatus uint8\n\nconst (\n\tImportItemNone ImportItemStatus = iota\n\n\t// The linker doesn't report import/export mismatch errors\n\tImportItemGenerated\n\n\t// The printer will replace this import with \"undefined\"\n\tImportItemMissing\n)\n\ntype SymbolFlags uint16\n\nconst (\n\t// Certain symbols must not be renamed or minified. For example, the\n\t// \"arguments\" variable is declared by the runtime for every function.\n\t// Renaming can also break any identifier used inside a \"with\" statement.\n\tMustNotBeRenamed SymbolFlags = 1 << iota\n\n\t// In React's version of JSX, lower-case names are strings while upper-case\n\t// names are identifiers. If we are preserving JSX syntax (i.e. not\n\t// transforming it), then we need to be careful to name the identifiers\n\t// something with a capital letter so further JSX processing doesn't treat\n\t// them as strings instead.\n\tMustStartWithCapitalLetterForJSX\n\n\t// If true, this symbol is the target of a \"__name\" helper function call.\n\t// This call is special because it deliberately doesn't count as a use\n\t// of the symbol (otherwise keeping names would disable tree shaking)\n\t// so \"UseCountEstimate\" is not incremented. This flag helps us know to\n\t// avoid optimizing this symbol when \"UseCountEstimate\" is 1 in this case.\n\tDidKeepName\n\n\t// Sometimes we lower private symbols even if they are supported. For example,\n\t// consider the following TypeScript code:\n\t//\n\t//   class Foo {\n\t//     #foo = 123\n\t//     bar = this.#foo\n\t//   }\n\t//\n\t// If \"useDefineForClassFields: false\" is set in \"tsconfig.json\", then \"bar\"\n\t// must use assignment semantics instead of define semantics. We can compile\n\t// that to this code:\n\t//\n\t//   class Foo {\n\t//     constructor() {\n\t//       this.#foo = 123;\n\t//       this.bar = this.#foo;\n\t//     }\n\t//     #foo;\n\t//   }\n\t//\n\t// However, we can't do the same for static fields:\n\t//\n\t//   class Foo {\n\t//     static #foo = 123\n\t//     static bar = this.#foo\n\t//   }\n\t//\n\t// Compiling these static fields to something like this would be invalid:\n\t//\n\t//   class Foo {\n\t//     static #foo;\n\t//   }\n\t//   Foo.#foo = 123;\n\t//   Foo.bar = Foo.#foo;\n\t//\n\t// Thus \"#foo\" must be lowered even though it's supported. Another case is\n\t// when we're converting top-level class declarations to class expressions\n\t// to avoid the TDZ and the class shadowing symbol is referenced within the\n\t// class body:\n\t//\n\t//   class Foo {\n\t//     static #foo = Foo\n\t//   }\n\t//\n\t// This cannot be converted into something like this:\n\t//\n\t//   var Foo = class {\n\t//     static #foo;\n\t//   };\n\t//   Foo.#foo = Foo;\n\t//\n\tPrivateSymbolMustBeLowered\n\n\t// This is used to remove the all but the last function re-declaration if a\n\t// function is re-declared multiple times like this:\n\t//\n\t//   function foo() { console.log(1) }\n\t//   function foo() { console.log(2) }\n\t//\n\tRemoveOverwrittenFunctionDeclaration\n\n\t// This flag is to avoid warning about this symbol more than once. It only\n\t// applies to the \"module\" and \"exports\" unbound symbols.\n\tDidWarnAboutCommonJSInESM\n\n\t// If this is present, the symbol could potentially be overwritten. This means\n\t// it's not safe to make assumptions about this symbol from the initializer.\n\tCouldPotentiallyBeMutated\n\n\t// This flags all symbols that were exported from the module using the ES6\n\t// \"export\" keyword, either directly on the declaration or using \"export {}\".\n\tWasExported\n\n\t// This means the symbol is a normal function that has no body statements.\n\tIsEmptyFunction\n\n\t// This means the symbol is a normal function that takes a single argument\n\t// and returns that argument.\n\tIsIdentityFunction\n\n\t// If true, calls to this symbol can be unwrapped (i.e. removed except for\n\t// argument side effects) if the result is unused.\n\tCallCanBeUnwrappedIfUnused\n)\n\nfunc (flags SymbolFlags) Has(flag SymbolFlags) bool {\n\treturn (flags & flag) != 0\n}\n\n// Note: the order of values in this struct matters to reduce struct size.\ntype Symbol struct {\n\t// This is used for symbols that represent items in the import clause of an\n\t// ES6 import statement. These should always be referenced by EImportIdentifier\n\t// instead of an EIdentifier. When this is present, the expression should\n\t// be printed as a property access off the namespace instead of as a bare\n\t// identifier.\n\t//\n\t// For correctness, this must be stored on the symbol instead of indirectly\n\t// associated with the Ref for the symbol somehow. In ES6 \"flat bundling\"\n\t// mode, re-exported symbols are collapsed using MergeSymbols() and renamed\n\t// symbols from other files that end up at this symbol must be able to tell\n\t// if it has a namespace alias.\n\tNamespaceAlias *NamespaceAlias\n\n\t// This is the name that came from the parser. Printed names may be renamed\n\t// during minification or to avoid name collisions. Do not use the original\n\t// name during printing.\n\tOriginalName string\n\n\t// Used by the parser for single pass parsing. Symbols that have been merged\n\t// form a linked-list where the last link is the symbol to use. This link is\n\t// an invalid ref if it's the last link. If this isn't invalid, you need to\n\t// FollowSymbols to get the real one.\n\tLink Ref\n\n\t// An estimate of the number of uses of this symbol. This is used to detect\n\t// whether a symbol is used or not. For example, TypeScript imports that are\n\t// unused must be removed because they are probably type-only imports. This\n\t// is an estimate and may not be completely accurate due to oversights in the\n\t// code. But it should always be non-zero when the symbol is used.\n\tUseCountEstimate uint32\n\n\t// This is for generating cross-chunk imports and exports for code splitting.\n\tChunkIndex Index32\n\n\t// This is used for minification. Symbols that are declared in sibling scopes\n\t// can share a name. A good heuristic (from Google Closure Compiler) is to\n\t// assign names to symbols from sibling scopes in declaration order. That way\n\t// local variable names are reused in each global function like this, which\n\t// improves gzip compression:\n\t//\n\t//   function x(a, b) { ... }\n\t//   function y(a, b, c) { ... }\n\t//\n\t// The parser fills this in for symbols inside nested scopes. There are three\n\t// slot namespaces: regular symbols, label symbols, and private symbols.\n\tNestedScopeSlot Index32\n\n\t// Boolean values should all be flags instead to save space\n\tFlags SymbolFlags\n\n\tKind SymbolKind\n\n\t// We automatically generate import items for property accesses off of\n\t// namespace imports. This lets us remove the expensive namespace imports\n\t// while bundling in many cases, replacing them with a cheap import item\n\t// instead:\n\t//\n\t//   import * as ns from 'path'\n\t//   ns.foo()\n\t//\n\t// That can often be replaced by this, which avoids needing the namespace:\n\t//\n\t//   import {foo} from 'path'\n\t//   foo()\n\t//\n\t// However, if the import is actually missing then we don't want to report a\n\t// compile-time error like we do for real import items. This status lets us\n\t// avoid this. We also need to be able to replace such import items with\n\t// undefined, which this status is also used for.\n\tImportItemStatus ImportItemStatus\n}\n\n// You should call \"MergeSymbols\" instead of calling this directly\nfunc (newSymbol *Symbol) MergeContentsWith(oldSymbol *Symbol) {\n\tnewSymbol.UseCountEstimate += oldSymbol.UseCountEstimate\n\tif oldSymbol.Flags.Has(MustNotBeRenamed) && !newSymbol.Flags.Has(MustNotBeRenamed) {\n\t\tnewSymbol.OriginalName = oldSymbol.OriginalName\n\t\tnewSymbol.Flags |= MustNotBeRenamed\n\t}\n\tif oldSymbol.Flags.Has(MustStartWithCapitalLetterForJSX) {\n\t\tnewSymbol.Flags |= MustStartWithCapitalLetterForJSX\n\t}\n}\n\ntype SlotNamespace uint8\n\nconst (\n\tSlotDefault SlotNamespace = iota\n\tSlotLabel\n\tSlotPrivateName\n\tSlotMangledProp\n\tSlotMustNotBeRenamed\n)\n\nfunc (s *Symbol) SlotNamespace() SlotNamespace {\n\tif s.Kind == SymbolUnbound || s.Flags.Has(MustNotBeRenamed) {\n\t\treturn SlotMustNotBeRenamed\n\t}\n\tif s.Kind.IsPrivate() {\n\t\treturn SlotPrivateName\n\t}\n\tif s.Kind == SymbolLabel {\n\t\treturn SlotLabel\n\t}\n\tif s.Kind == SymbolMangledProp {\n\t\treturn SlotMangledProp\n\t}\n\treturn SlotDefault\n}\n\ntype SlotCounts [4]uint32\n\nfunc (a *SlotCounts) UnionMax(b SlotCounts) {\n\tfor i := range *a {\n\t\tai := &(*a)[i]\n\t\tbi := b[i]\n\t\tif *ai < bi {\n\t\t\t*ai = bi\n\t\t}\n\t}\n}\n\ntype NamespaceAlias struct {\n\tAlias        string\n\tNamespaceRef Ref\n}\n\ntype SymbolMap struct {\n\t// This could be represented as a \"map[Ref]Symbol\" but a two-level array was\n\t// more efficient in profiles. This appears to be because it doesn't involve\n\t// a hash. This representation also makes it trivial to quickly merge symbol\n\t// maps from multiple files together. Each file only generates symbols in a\n\t// single inner array, so you can join the maps together by just make a\n\t// single outer array containing all of the inner arrays. See the comment on\n\t// \"Ref\" for more detail.\n\tSymbolsForSource [][]Symbol\n}\n\nfunc NewSymbolMap(sourceCount int) SymbolMap {\n\treturn SymbolMap{make([][]Symbol, sourceCount)}\n}\n\nfunc (sm SymbolMap) Get(ref Ref) *Symbol {\n\treturn &sm.SymbolsForSource[ref.SourceIndex][ref.InnerIndex]\n}\n\n// Returns the canonical ref that represents the ref for the provided symbol.\n// This may not be the provided ref if the symbol has been merged with another\n// symbol.\nfunc FollowSymbols(symbols SymbolMap, ref Ref) Ref {\n\tsymbol := symbols.Get(ref)\n\tif symbol.Link == InvalidRef {\n\t\treturn ref\n\t}\n\n\tlink := FollowSymbols(symbols, symbol.Link)\n\n\t// Only write if needed to avoid concurrent map update hazards\n\tif symbol.Link != link {\n\t\tsymbol.Link = link\n\t}\n\n\treturn link\n}\n\n// Use this before calling \"FollowSymbols\" from separate threads to avoid\n// concurrent map update hazards. In Go, mutating a map is not threadsafe\n// but reading from a map is. Calling \"FollowAllSymbols\" first ensures that\n// all mutation is done up front.\nfunc FollowAllSymbols(symbols SymbolMap) {\n\tfor sourceIndex, inner := range symbols.SymbolsForSource {\n\t\tfor symbolIndex := range inner {\n\t\t\tFollowSymbols(symbols, Ref{uint32(sourceIndex), uint32(symbolIndex)})\n\t\t}\n\t}\n}\n\n// Makes \"old\" point to \"new\" by joining the linked lists for the two symbols\n// together. That way \"FollowSymbols\" on both \"old\" and \"new\" will result in\n// the same ref.\nfunc MergeSymbols(symbols SymbolMap, old Ref, new Ref) Ref {\n\tif old == new {\n\t\treturn new\n\t}\n\n\toldSymbol := symbols.Get(old)\n\tif oldSymbol.Link != InvalidRef {\n\t\toldSymbol.Link = MergeSymbols(symbols, oldSymbol.Link, new)\n\t\treturn oldSymbol.Link\n\t}\n\n\tnewSymbol := symbols.Get(new)\n\tif newSymbol.Link != InvalidRef {\n\t\tnewSymbol.Link = MergeSymbols(symbols, old, newSymbol.Link)\n\t\treturn newSymbol.Link\n\t}\n\n\toldSymbol.Link = new\n\tnewSymbol.MergeContentsWith(oldSymbol)\n\treturn new\n}\n\n// This is a histogram of character frequencies for minification\ntype CharFreq [64]int32\n\nfunc (freq *CharFreq) Scan(text string, delta int32) {\n\tif delta == 0 {\n\t\treturn\n\t}\n\n\t// This matches the order in \"DefaultNameMinifier\"\n\tfor i, n := 0, len(text); i < n; i++ {\n\t\tc := text[i]\n\t\tswitch {\n\t\tcase c >= 'a' && c <= 'z':\n\t\t\t(*freq)[c-'a'] += delta\n\t\tcase c >= 'A' && c <= 'Z':\n\t\t\t(*freq)[c-('A'-26)] += delta\n\t\tcase c >= '0' && c <= '9':\n\t\t\t(*freq)[c+(52-'0')] += delta\n\t\tcase c == '_':\n\t\t\t(*freq)[62] += delta\n\t\tcase c == '$':\n\t\t\t(*freq)[63] += delta\n\t\t}\n\t}\n}\n\nfunc (freq *CharFreq) Include(other *CharFreq) {\n\tfor i := 0; i < 64; i++ {\n\t\t(*freq)[i] += (*other)[i]\n\t}\n}\n\ntype NameMinifier struct {\n\thead string\n\ttail string\n}\n\nvar DefaultNameMinifierJS = NameMinifier{\n\thead: \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$\",\n\ttail: \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$\",\n}\n\nvar DefaultNameMinifierCSS = NameMinifier{\n\thead: \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_\",\n\ttail: \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_\",\n}\n\ntype charAndCount struct {\n\tchar  string\n\tcount int32\n\tindex byte\n}\n\n// This type is just so we can use Go's native sort function\ntype charAndCountArray []charAndCount\n\nfunc (a charAndCountArray) Len() int          { return len(a) }\nfunc (a charAndCountArray) Swap(i int, j int) { a[i], a[j] = a[j], a[i] }\n\nfunc (a charAndCountArray) Less(i int, j int) bool {\n\tai := a[i]\n\taj := a[j]\n\treturn ai.count > aj.count || (ai.count == aj.count && ai.index < aj.index)\n}\n\nfunc (source NameMinifier) ShuffleByCharFreq(freq CharFreq) NameMinifier {\n\t// Sort the histogram in descending order by count\n\tarray := make(charAndCountArray, 64)\n\tfor i := 0; i < len(source.tail); i++ {\n\t\tarray[i] = charAndCount{\n\t\t\tchar:  source.tail[i : i+1],\n\t\t\tindex: byte(i),\n\t\t\tcount: freq[i],\n\t\t}\n\t}\n\tsort.Sort(array)\n\n\t// Compute the identifier start and identifier continue sequences\n\tminifier := NameMinifier{}\n\tfor _, item := range array {\n\t\tif item.char < \"0\" || item.char > \"9\" {\n\t\t\tminifier.head += item.char\n\t\t}\n\t\tminifier.tail += item.char\n\t}\n\treturn minifier\n}\n\nfunc (minifier NameMinifier) NumberToMinifiedName(i int) string {\n\tn_head := len(minifier.head)\n\tn_tail := len(minifier.tail)\n\n\tj := i % n_head\n\tvar name strings.Builder\n\tname.WriteString(minifier.head[j : j+1])\n\ti = i / n_head\n\n\tfor i > 0 {\n\t\ti--\n\t\tj := i % n_tail\n\t\tname.WriteString(minifier.tail[j : j+1])\n\t\ti = i / n_tail\n\t}\n\n\treturn name.String()\n}\n"
  },
  {
    "path": "internal/bundler/bundler.go",
    "content": "package bundler\n\n// The bundler is the core of the \"build\" and \"transform\" API calls. Each\n// operation has two phases. The first phase scans the module graph, and is\n// represented by the \"ScanBundle\" function. The second phase generates the\n// output files from the module graph, and is implemented by the \"Compile\"\n// function.\n\nimport (\n\t\"bytes\"\n\t\"encoding/base32\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"syscall\"\n\t\"time\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/cache\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/css_parser\"\n\t\"github.com/evanw/esbuild/internal/fs\"\n\t\"github.com/evanw/esbuild/internal/graph\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/js_lexer\"\n\t\"github.com/evanw/esbuild/internal/js_parser\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/resolver\"\n\t\"github.com/evanw/esbuild/internal/runtime\"\n\t\"github.com/evanw/esbuild/internal/sourcemap\"\n\t\"github.com/evanw/esbuild/internal/xxhash\"\n)\n\ntype scannerFile struct {\n\t// If \"AbsMetadataFile\" is present, this will be filled out with information\n\t// about this file in JSON format. This is a partial JSON file that will be\n\t// fully assembled later.\n\tjsonMetadataChunk string\n\n\tpluginData interface{}\n\tinputFile  graph.InputFile\n}\n\n// This is data related to source maps. It's computed in parallel with linking\n// and must be ready by the time printing happens. This is beneficial because\n// it is somewhat expensive to produce.\ntype DataForSourceMap struct {\n\t// This data is for the printer. It maps from byte offsets in the file (which\n\t// are stored at every AST node) to UTF-16 column offsets (required by source\n\t// maps).\n\tLineOffsetTables []sourcemap.LineOffsetTable\n\n\t// This contains the quoted contents of the original source file. It's what\n\t// needs to be embedded in the \"sourcesContent\" array in the final source\n\t// map. Quoting is precomputed because it's somewhat expensive.\n\tQuotedContents [][]byte\n}\n\ntype Bundle struct {\n\t// The unique key prefix is a random string that is unique to every bundling\n\t// operation. It is used as a prefix for the unique keys assigned to every\n\t// chunk during linking. These unique keys are used to identify each chunk\n\t// before the final output paths have been computed.\n\tuniqueKeyPrefix string\n\n\tfs          fs.FS\n\tres         *resolver.Resolver\n\tfiles       []scannerFile\n\tentryPoints []graph.EntryPoint\n\toptions     config.Options\n}\n\ntype parseArgs struct {\n\tfs              fs.FS\n\tlog             logger.Log\n\tres             *resolver.Resolver\n\tcaches          *cache.CacheSet\n\tprettyPaths     logger.PrettyPaths\n\timportSource    *logger.Source\n\timportWith      *ast.ImportAssertOrWith\n\tsideEffects     graph.SideEffects\n\tpluginData      interface{}\n\tresults         chan parseResult\n\tinject          chan config.InjectedFile\n\tuniqueKeyPrefix string\n\tkeyPath         logger.Path\n\toptions         config.Options\n\timportPathRange logger.Range\n\tsourceIndex     uint32\n\tskipResolve     bool\n}\n\ntype parseResult struct {\n\tresolveResults     []*resolver.ResolveResult\n\tglobResolveResults map[uint32]globResolveResult\n\tfile               scannerFile\n\ttlaCheck           tlaCheck\n\tok                 bool\n}\n\ntype globResolveResult struct {\n\tresolveResults map[string]resolver.ResolveResult\n\tabsPath        string\n\tprettyPaths    logger.PrettyPaths\n\texportAlias    string\n}\n\ntype tlaCheck struct {\n\tparent            ast.Index32\n\tdepth             uint32\n\timportRecordIndex uint32\n}\n\nfunc parseFile(args parseArgs) {\n\tpathForIdentifierName := args.keyPath.Text\n\n\t// Identifier name generation may use the name of the parent folder if the\n\t// file name starts with \"index\". However, this is problematic when the\n\t// parent folder includes the parent directory of what the developer\n\t// considers to be the root of the source tree. If that happens, strip the\n\t// parent folder to avoid including it in the generated name.\n\tif relative, ok := args.fs.Rel(args.options.AbsOutputBase, pathForIdentifierName); ok {\n\t\tfor {\n\t\t\tnext := strings.TrimPrefix(strings.TrimPrefix(relative, \"../\"), \"..\\\\\")\n\t\t\tif relative == next {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\trelative = next\n\t\t}\n\t\tpathForIdentifierName = relative\n\t}\n\n\tsource := logger.Source{\n\t\tIndex:          args.sourceIndex,\n\t\tKeyPath:        args.keyPath,\n\t\tPrettyPaths:    args.prettyPaths,\n\t\tIdentifierName: js_ast.GenerateNonUniqueNameFromPath(pathForIdentifierName),\n\t}\n\n\tvar loader config.Loader\n\tvar absResolveDir string\n\tvar pluginName string\n\tvar pluginData interface{}\n\n\tif stdin := args.options.Stdin; stdin != nil {\n\t\t// Special-case stdin\n\t\tsource.Contents = stdin.Contents\n\t\tloader = stdin.Loader\n\t\tif loader == config.LoaderNone {\n\t\t\tloader = config.LoaderJS\n\t\t}\n\t\tabsResolveDir = args.options.Stdin.AbsResolveDir\n\t} else {\n\t\tresult, ok := runOnLoadPlugins(\n\t\t\targs.options.Plugins,\n\t\t\targs.fs,\n\t\t\t&args.caches.FSCache,\n\t\t\targs.log,\n\t\t\t&source,\n\t\t\targs.importSource,\n\t\t\targs.importPathRange,\n\t\t\targs.pluginData,\n\t\t\targs.options.WatchMode,\n\t\t\targs.options.LogPathStyle,\n\t\t)\n\t\tif !ok {\n\t\t\tif args.inject != nil {\n\t\t\t\targs.inject <- config.InjectedFile{\n\t\t\t\t\tSource: source,\n\t\t\t\t}\n\t\t\t}\n\t\t\targs.results <- parseResult{}\n\t\t\treturn\n\t\t}\n\t\tloader = result.loader\n\t\tabsResolveDir = result.absResolveDir\n\t\tpluginName = result.pluginName\n\t\tpluginData = result.pluginData\n\t}\n\n\t_, base, ext := logger.PlatformIndependentPathDirBaseExt(source.KeyPath.Text)\n\n\t// The special \"default\" loader determines the loader from the file path\n\tif loader == config.LoaderDefault {\n\t\tloader = config.LoaderFromFileExtension(args.options.ExtensionToLoader, base+ext)\n\t}\n\n\t// Reject unsupported import attributes when the loader isn't \"copy\" (since\n\t// \"copy\" is kind of like \"external\"). But only do this if this file was not\n\t// loaded by a plugin. Plugins are allowed to assign whatever semantics they\n\t// want to import attributes.\n\tif loader != config.LoaderCopy && pluginName == \"\" {\n\t\tfor _, attr := range source.KeyPath.ImportAttributes.DecodeIntoArray() {\n\t\t\tvar errorText string\n\t\t\tvar errorRange js_lexer.KeyOrValue\n\n\t\t\t// We only currently handle \"type: json\" and \"type: bytes\"\n\t\t\tif attr.Key != \"type\" {\n\t\t\t\terrorText = fmt.Sprintf(\"Importing with the %q attribute is not supported\", attr.Key)\n\t\t\t\terrorRange = js_lexer.KeyRange\n\t\t\t} else if attr.Value == \"json\" {\n\t\t\t\tloader = config.LoaderWithTypeJSON\n\t\t\t\tcontinue\n\t\t\t} else if attr.Value == \"bytes\" {\n\t\t\t\tloader = config.LoaderBinary\n\t\t\t\tcontinue\n\t\t\t} else {\n\t\t\t\terrorText = fmt.Sprintf(\"Importing with a type attribute of %q is not supported\", attr.Value)\n\t\t\t\terrorRange = js_lexer.ValueRange\n\t\t\t}\n\n\t\t\t// Everything else is an error\n\t\t\tr := args.importPathRange\n\t\t\tif args.importWith != nil {\n\t\t\t\tr = js_lexer.RangeOfImportAssertOrWith(*args.importSource, *ast.FindAssertOrWithEntry(args.importWith.Entries, attr.Key), errorRange)\n\t\t\t}\n\t\t\ttracker := logger.MakeLineColumnTracker(args.importSource)\n\t\t\targs.log.AddError(&tracker, r, errorText)\n\t\t\tif args.inject != nil {\n\t\t\t\targs.inject <- config.InjectedFile{\n\t\t\t\t\tSource: source,\n\t\t\t\t}\n\t\t\t}\n\t\t\targs.results <- parseResult{}\n\t\t\treturn\n\t\t}\n\t}\n\n\tif loader == config.LoaderEmpty {\n\t\tsource.Contents = \"\"\n\t}\n\n\tresult := parseResult{\n\t\tfile: scannerFile{\n\t\t\tinputFile: graph.InputFile{\n\t\t\t\tSource:      source,\n\t\t\t\tLoader:      loader,\n\t\t\t\tSideEffects: args.sideEffects,\n\t\t\t},\n\t\t\tpluginData: pluginData,\n\t\t},\n\t}\n\n\tdefer func() {\n\t\tr := recover()\n\t\tif r != nil {\n\t\t\targs.log.AddErrorWithNotes(nil, logger.Range{},\n\t\t\t\tfmt.Sprintf(\"panic: %v (while parsing %q)\", r, source.PrettyPaths.Select(args.options.LogPathStyle)),\n\t\t\t\t[]logger.MsgData{{Text: helpers.PrettyPrintedStack()}})\n\t\t\targs.results <- result\n\t\t}\n\t}()\n\n\tswitch loader {\n\tcase config.LoaderJS, config.LoaderEmpty:\n\t\tast, ok := args.caches.JSCache.Parse(args.log, source, js_parser.OptionsFromConfig(&args.options))\n\t\tif len(ast.Parts) <= 1 { // Ignore the implicitly-generated namespace export part\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_EmptyAST\n\t\t}\n\t\tresult.file.inputFile.Repr = &graph.JSRepr{AST: ast}\n\t\tresult.ok = ok\n\n\tcase config.LoaderJSX:\n\t\targs.options.JSX.Parse = true\n\t\tast, ok := args.caches.JSCache.Parse(args.log, source, js_parser.OptionsFromConfig(&args.options))\n\t\tif len(ast.Parts) <= 1 { // Ignore the implicitly-generated namespace export part\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_EmptyAST\n\t\t}\n\t\tresult.file.inputFile.Repr = &graph.JSRepr{AST: ast}\n\t\tresult.ok = ok\n\n\tcase config.LoaderTS, config.LoaderTSNoAmbiguousLessThan:\n\t\targs.options.TS.Parse = true\n\t\targs.options.TS.NoAmbiguousLessThan = loader == config.LoaderTSNoAmbiguousLessThan\n\t\tast, ok := args.caches.JSCache.Parse(args.log, source, js_parser.OptionsFromConfig(&args.options))\n\t\tif len(ast.Parts) <= 1 { // Ignore the implicitly-generated namespace export part\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_EmptyAST\n\t\t}\n\t\tresult.file.inputFile.Repr = &graph.JSRepr{AST: ast}\n\t\tresult.ok = ok\n\n\tcase config.LoaderTSX:\n\t\targs.options.TS.Parse = true\n\t\targs.options.JSX.Parse = true\n\t\tast, ok := args.caches.JSCache.Parse(args.log, source, js_parser.OptionsFromConfig(&args.options))\n\t\tif len(ast.Parts) <= 1 { // Ignore the implicitly-generated namespace export part\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_EmptyAST\n\t\t}\n\t\tresult.file.inputFile.Repr = &graph.JSRepr{AST: ast}\n\t\tresult.ok = ok\n\n\tcase config.LoaderCSS, config.LoaderGlobalCSS, config.LoaderLocalCSS:\n\t\tast := args.caches.CSSCache.Parse(args.log, source, css_parser.OptionsFromConfig(loader, &args.options))\n\t\tresult.file.inputFile.Repr = &graph.CSSRepr{AST: ast}\n\t\tresult.ok = true\n\n\tcase config.LoaderJSON, config.LoaderWithTypeJSON:\n\t\texpr, ok := args.caches.JSONCache.Parse(args.log, source, js_parser.JSONOptions{\n\t\t\tUnsupportedJSFeatures: args.options.UnsupportedJSFeatures,\n\t\t})\n\t\tast := js_parser.LazyExportAST(args.log, source, js_parser.OptionsFromConfig(&args.options), expr, nil)\n\t\tif loader == config.LoaderWithTypeJSON {\n\t\t\t// The exports kind defaults to \"none\", in which case the linker picks\n\t\t\t// either ESM or CommonJS depending on the situation. Dynamic imports\n\t\t\t// causes the linker to pick CommonJS which uses \"require()\" and then\n\t\t\t// converts the return value to ESM, which adds extra properties that\n\t\t\t// aren't supposed to be there when \"{ with: { type: 'json' } }\" is\n\t\t\t// present. So if there's an import attribute, we force the type to\n\t\t\t// be ESM to avoid this.\n\t\t\tast.ExportsKind = js_ast.ExportsESM\n\t\t}\n\t\tif pluginName != \"\" {\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_PureData_FromPlugin\n\t\t} else {\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_PureData\n\t\t}\n\t\tresult.file.inputFile.Repr = &graph.JSRepr{AST: ast}\n\t\tresult.ok = ok\n\n\tcase config.LoaderText:\n\t\tsource.Contents = strings.TrimPrefix(source.Contents, \"\\xEF\\xBB\\xBF\") // Strip any UTF-8 BOM from the text\n\t\tencoded := base64.StdEncoding.EncodeToString([]byte(source.Contents))\n\t\texpr := js_ast.Expr{Data: &js_ast.EString{Value: helpers.StringToUTF16(source.Contents)}}\n\t\tast := js_parser.LazyExportAST(args.log, source, js_parser.OptionsFromConfig(&args.options), expr, nil)\n\t\tast.URLForCSS = \"data:text/plain;base64,\" + encoded\n\t\tif pluginName != \"\" {\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_PureData_FromPlugin\n\t\t} else {\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_PureData\n\t\t}\n\t\tresult.file.inputFile.Repr = &graph.JSRepr{AST: ast}\n\t\tresult.ok = true\n\n\tcase config.LoaderBase64:\n\t\tmimeType := guessMimeType(ext, source.Contents)\n\t\tencoded := base64.StdEncoding.EncodeToString([]byte(source.Contents))\n\t\texpr := js_ast.Expr{Data: &js_ast.EString{Value: helpers.StringToUTF16(encoded)}}\n\t\tast := js_parser.LazyExportAST(args.log, source, js_parser.OptionsFromConfig(&args.options), expr, nil)\n\t\tast.URLForCSS = \"data:\" + mimeType + \";base64,\" + encoded\n\t\tif pluginName != \"\" {\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_PureData_FromPlugin\n\t\t} else {\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_PureData\n\t\t}\n\t\tresult.file.inputFile.Repr = &graph.JSRepr{AST: ast}\n\t\tresult.ok = true\n\n\tcase config.LoaderBinary:\n\t\tencoded := base64.StdEncoding.EncodeToString([]byte(source.Contents))\n\t\texpr := js_ast.Expr{Data: &js_ast.EString{Value: helpers.StringToUTF16(encoded)}}\n\t\tvar helper *js_parser.HelperCall\n\t\tif args.options.UnsupportedJSFeatures.Has(compat.FromBase64) {\n\t\t\tif args.options.Platform == config.PlatformNode {\n\t\t\t\thelper = &js_parser.HelperCall{Runtime: \"__toBinaryNode\"}\n\t\t\t} else {\n\t\t\t\thelper = &js_parser.HelperCall{Runtime: \"__toBinary\"}\n\t\t\t}\n\t\t} else {\n\t\t\thelper = &js_parser.HelperCall{Global: []string{\"Uint8Array\", \"fromBase64\"}}\n\t\t}\n\t\tast := js_parser.LazyExportAST(args.log, source, js_parser.OptionsFromConfig(&args.options), expr, helper)\n\t\tast.URLForCSS = \"data:application/octet-stream;base64,\" + encoded\n\t\tif pluginName != \"\" {\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_PureData_FromPlugin\n\t\t} else {\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_PureData\n\t\t}\n\t\tresult.file.inputFile.Repr = &graph.JSRepr{AST: ast}\n\t\tresult.ok = true\n\n\tcase config.LoaderDataURL:\n\t\tmimeType := guessMimeType(ext, source.Contents)\n\t\turl := helpers.EncodeStringAsShortestDataURL(mimeType, source.Contents)\n\t\tif strings.HasPrefix(source.KeyPath.IgnoredSuffix, \"#\") {\n\t\t\t// Preserve URL fragments as they are meaningful in CSS\n\t\t\turl += source.KeyPath.IgnoredSuffix\n\t\t}\n\t\texpr := js_ast.Expr{Data: &js_ast.EString{Value: helpers.StringToUTF16(url)}}\n\t\tast := js_parser.LazyExportAST(args.log, source, js_parser.OptionsFromConfig(&args.options), expr, nil)\n\t\tast.URLForCSS = url\n\t\tif pluginName != \"\" {\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_PureData_FromPlugin\n\t\t} else {\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_PureData\n\t\t}\n\t\tresult.file.inputFile.Repr = &graph.JSRepr{AST: ast}\n\t\tresult.ok = true\n\n\tcase config.LoaderFile:\n\t\tuniqueKey := fmt.Sprintf(\"%sA%08d\", args.uniqueKeyPrefix, args.sourceIndex)\n\t\tuniqueKeyPath := uniqueKey + source.KeyPath.IgnoredSuffix\n\t\texpr := js_ast.Expr{Data: &js_ast.EString{\n\t\t\tValue:             helpers.StringToUTF16(uniqueKeyPath),\n\t\t\tContainsUniqueKey: true,\n\t\t}}\n\t\tast := js_parser.LazyExportAST(args.log, source, js_parser.OptionsFromConfig(&args.options), expr, nil)\n\t\tast.URLForCSS = uniqueKeyPath\n\t\tif pluginName != \"\" {\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_PureData_FromPlugin\n\t\t} else {\n\t\t\tresult.file.inputFile.SideEffects.Kind = graph.NoSideEffects_PureData\n\t\t}\n\t\tresult.file.inputFile.Repr = &graph.JSRepr{AST: ast}\n\t\tresult.ok = true\n\n\t\t// Mark that this file is from the \"file\" loader\n\t\tresult.file.inputFile.UniqueKeyForAdditionalFile = uniqueKey\n\n\tcase config.LoaderCopy:\n\t\tuniqueKey := fmt.Sprintf(\"%sA%08d\", args.uniqueKeyPrefix, args.sourceIndex)\n\t\tuniqueKeyPath := uniqueKey + source.KeyPath.IgnoredSuffix\n\t\tresult.file.inputFile.Repr = &graph.CopyRepr{\n\t\t\tURLForCode: uniqueKeyPath,\n\t\t}\n\t\tresult.ok = true\n\n\t\t// Mark that this file is from the \"copy\" loader\n\t\tresult.file.inputFile.UniqueKeyForAdditionalFile = uniqueKey\n\n\tdefault:\n\t\tvar message string\n\t\tif source.KeyPath.Namespace == \"file\" && ext != \"\" {\n\t\t\tmessage = fmt.Sprintf(\"No loader is configured for %q files: %s\", ext, source.PrettyPaths.Select(args.options.LogPathStyle))\n\t\t} else {\n\t\t\tmessage = fmt.Sprintf(\"Do not know how to load path: %s\", source.PrettyPaths.Select(args.options.LogPathStyle))\n\t\t}\n\t\ttracker := logger.MakeLineColumnTracker(args.importSource)\n\t\targs.log.AddError(&tracker, args.importPathRange, message)\n\t}\n\n\t// Only continue now if parsing was successful\n\tif result.ok {\n\t\t// Run the resolver on the parse thread so it's not run on the main thread.\n\t\t// That way the main thread isn't blocked if the resolver takes a while.\n\t\tif recordsPtr := result.file.inputFile.Repr.ImportRecords(); args.options.Mode == config.ModeBundle && !args.skipResolve && recordsPtr != nil {\n\t\t\t// Clone the import records because they will be mutated later\n\t\t\trecords := append([]ast.ImportRecord{}, *recordsPtr...)\n\t\t\t*recordsPtr = records\n\t\t\tresult.resolveResults = make([]*resolver.ResolveResult, len(records))\n\n\t\t\tif len(records) > 0 {\n\t\t\t\ttype cacheEntry struct {\n\t\t\t\t\tresolveResult *resolver.ResolveResult\n\t\t\t\t\tdebug         resolver.DebugMeta\n\t\t\t\t\tdidLogError   bool\n\t\t\t\t}\n\n\t\t\t\ttype cacheKey struct {\n\t\t\t\t\tkind  ast.ImportKind\n\t\t\t\t\tpath  string\n\t\t\t\t\tattrs logger.ImportAttributes\n\t\t\t\t}\n\t\t\t\tresolverCache := make(map[cacheKey]cacheEntry)\n\t\t\t\ttracker := logger.MakeLineColumnTracker(&source)\n\n\t\t\t\tfor importRecordIndex := range records {\n\t\t\t\t\t// Don't try to resolve imports that are already resolved\n\t\t\t\t\trecord := &records[importRecordIndex]\n\t\t\t\t\tif record.SourceIndex.IsValid() {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// Encode the import attributes\n\t\t\t\t\tvar attrs logger.ImportAttributes\n\t\t\t\t\tif record.AssertOrWith != nil && record.AssertOrWith.Keyword == ast.WithKeyword {\n\t\t\t\t\t\tdata := make(map[string]string, len(record.AssertOrWith.Entries))\n\t\t\t\t\t\tfor _, entry := range record.AssertOrWith.Entries {\n\t\t\t\t\t\t\tdata[helpers.UTF16ToString(entry.Key)] = helpers.UTF16ToString(entry.Value)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tattrs = logger.EncodeImportAttributes(data)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Special-case glob pattern imports\n\t\t\t\t\tif record.GlobPattern != nil {\n\t\t\t\t\t\tprettyPath := helpers.GlobPatternToString(record.GlobPattern.Parts)\n\t\t\t\t\t\tphase := \"\"\n\t\t\t\t\t\tswitch record.Phase {\n\t\t\t\t\t\tcase ast.DeferPhase:\n\t\t\t\t\t\t\tphase = \".defer\"\n\t\t\t\t\t\tcase ast.SourcePhase:\n\t\t\t\t\t\t\tphase = \".source\"\n\t\t\t\t\t\t}\n\t\t\t\t\t\tswitch record.GlobPattern.Kind {\n\t\t\t\t\t\tcase ast.ImportRequire:\n\t\t\t\t\t\t\tprettyPath = fmt.Sprintf(\"require%s(%q)\", phase, prettyPath)\n\t\t\t\t\t\tcase ast.ImportDynamic:\n\t\t\t\t\t\t\tprettyPath = fmt.Sprintf(\"import%s(%q)\", phase, prettyPath)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif results, msg := args.res.ResolveGlob(absResolveDir, record.GlobPattern.Parts, record.GlobPattern.Kind, prettyPath); results != nil {\n\t\t\t\t\t\t\tif msg != nil {\n\t\t\t\t\t\t\t\targs.log.AddID(msg.ID, msg.Kind, &tracker, record.Range, msg.Data.Text)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif result.globResolveResults == nil {\n\t\t\t\t\t\t\t\tresult.globResolveResults = make(map[uint32]globResolveResult)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tallAreExternal := true\n\t\t\t\t\t\t\tfor key, result := range results {\n\t\t\t\t\t\t\t\tif !result.PathPair.IsExternal {\n\t\t\t\t\t\t\t\t\tallAreExternal = false\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tresult.PathPair.Primary.ImportAttributes = attrs\n\t\t\t\t\t\t\t\tif result.PathPair.HasSecondary() {\n\t\t\t\t\t\t\t\t\tresult.PathPair.Secondary.ImportAttributes = attrs\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tresults[key] = result\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tresult.globResolveResults[uint32(importRecordIndex)] = globResolveResult{\n\t\t\t\t\t\t\t\tresolveResults: results,\n\t\t\t\t\t\t\t\tabsPath:        args.fs.Join(absResolveDir, \"(glob)\"),\n\t\t\t\t\t\t\t\tprettyPaths: logger.PrettyPaths{\n\t\t\t\t\t\t\t\t\tAbs: fmt.Sprintf(\"%s in %s\", prettyPath, result.file.inputFile.Source.PrettyPaths.Abs),\n\t\t\t\t\t\t\t\t\tRel: fmt.Sprintf(\"%s in %s\", prettyPath, result.file.inputFile.Source.PrettyPaths.Rel),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\texportAlias: record.GlobPattern.ExportAlias,\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Forbid bundling of imports with explicit phases\n\t\t\t\t\t\t\tif record.Phase != ast.EvaluationPhase {\n\t\t\t\t\t\t\t\treportExplicitPhaseImport(args.log, &tracker, record.Range,\n\t\t\t\t\t\t\t\t\trecord.Phase, allAreExternal, args.options.OutputFormat)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\targs.log.AddError(&tracker, record.Range, fmt.Sprintf(\"Could not resolve %s\", prettyPath))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// Ignore records that the parser has discarded. This is used to remove\n\t\t\t\t\t// type-only imports in TypeScript files.\n\t\t\t\t\tif record.Flags.Has(ast.IsUnused) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// Cache the path in case it's imported multiple times in this file\n\t\t\t\t\tcacheKey := cacheKey{\n\t\t\t\t\t\tkind:  record.Kind,\n\t\t\t\t\t\tpath:  record.Path.Text,\n\t\t\t\t\t\tattrs: attrs,\n\t\t\t\t\t}\n\t\t\t\t\tentry, ok := resolverCache[cacheKey]\n\t\t\t\t\tif ok {\n\t\t\t\t\t\tresult.resolveResults[importRecordIndex] = entry.resolveResult\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Run the resolver and log an error if the path couldn't be resolved\n\t\t\t\t\t\tresolveResult, didLogError, debug := RunOnResolvePlugins(\n\t\t\t\t\t\t\targs.options.Plugins,\n\t\t\t\t\t\t\targs.res,\n\t\t\t\t\t\t\targs.log,\n\t\t\t\t\t\t\targs.fs,\n\t\t\t\t\t\t\t&args.caches.FSCache,\n\t\t\t\t\t\t\t&source,\n\t\t\t\t\t\t\trecord.Range,\n\t\t\t\t\t\t\tsource.KeyPath,\n\t\t\t\t\t\t\trecord.Path.Text,\n\t\t\t\t\t\t\tattrs,\n\t\t\t\t\t\t\trecord.Kind,\n\t\t\t\t\t\t\tabsResolveDir,\n\t\t\t\t\t\t\tpluginData,\n\t\t\t\t\t\t\targs.options.LogPathStyle,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tif resolveResult != nil {\n\t\t\t\t\t\t\tresolveResult.PathPair.Primary.ImportAttributes = attrs\n\t\t\t\t\t\t\tif resolveResult.PathPair.HasSecondary() {\n\t\t\t\t\t\t\t\tresolveResult.PathPair.Secondary.ImportAttributes = attrs\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tentry = cacheEntry{\n\t\t\t\t\t\t\tresolveResult: resolveResult,\n\t\t\t\t\t\t\tdebug:         debug,\n\t\t\t\t\t\t\tdidLogError:   didLogError,\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresolverCache[cacheKey] = entry\n\n\t\t\t\t\t\t// All \"require.resolve()\" imports should be external because we don't\n\t\t\t\t\t\t// want to waste effort traversing into them\n\t\t\t\t\t\tif record.Kind == ast.ImportRequireResolve {\n\t\t\t\t\t\t\tif resolveResult != nil && resolveResult.PathPair.IsExternal {\n\t\t\t\t\t\t\t\t// Allow path substitution as long as the result is external\n\t\t\t\t\t\t\t\tresult.resolveResults[importRecordIndex] = resolveResult\n\t\t\t\t\t\t\t} else if !record.Flags.Has(ast.HandlesImportErrors) {\n\t\t\t\t\t\t\t\targs.log.AddID(logger.MsgID_Bundler_RequireResolveNotExternal, logger.Warning, &tracker, record.Range,\n\t\t\t\t\t\t\t\t\tfmt.Sprintf(\"%q should be marked as external for use with \\\"require.resolve\\\"\", record.Path.Text))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check whether we should log an error every time the result is nil,\n\t\t\t\t\t// even if it's from the cache. Do this because the error may not\n\t\t\t\t\t// have been logged for nil entries if the previous instances had\n\t\t\t\t\t// the \"HandlesImportErrors\" flag.\n\t\t\t\t\tif entry.resolveResult == nil {\n\t\t\t\t\t\t// Failed imports inside a try/catch are silently turned into\n\t\t\t\t\t\t// external imports instead of causing errors. This matches a common\n\t\t\t\t\t\t// code pattern for conditionally importing a module with a graceful\n\t\t\t\t\t\t// fallback.\n\t\t\t\t\t\tif !entry.didLogError && !record.Flags.Has(ast.HandlesImportErrors) {\n\t\t\t\t\t\t\t// Report an error\n\t\t\t\t\t\t\ttext, suggestion, notes := ResolveFailureErrorTextSuggestionNotes(\n\t\t\t\t\t\t\t\targs.res, record.Path.Text, record.Kind, pluginName, args.fs, absResolveDir, args.options.Platform,\n\t\t\t\t\t\t\t\tsource.PrettyPaths, entry.debug.ModifiedImportPath, args.options.LogPathStyle)\n\t\t\t\t\t\t\tentry.debug.LogErrorMsg(args.log, &source, record.Range, text, suggestion, notes)\n\n\t\t\t\t\t\t\t// Only report this error once per unique import path in the file\n\t\t\t\t\t\t\tentry.didLogError = true\n\t\t\t\t\t\t\tresolverCache[cacheKey] = entry\n\t\t\t\t\t\t} else if !entry.didLogError && record.Flags.Has(ast.HandlesImportErrors) {\n\t\t\t\t\t\t\t// Report a debug message about why there was no error\n\t\t\t\t\t\t\targs.log.AddIDWithNotes(logger.MsgID_Bundler_IgnoredDynamicImport, logger.Debug, &tracker, record.Range,\n\t\t\t\t\t\t\t\tfmt.Sprintf(\"Importing %q was allowed even though it could not be resolved because dynamic import failures appear to be handled here:\",\n\t\t\t\t\t\t\t\t\trecord.Path.Text), []logger.MsgData{tracker.MsgData(js_lexer.RangeOfIdentifier(source, record.ErrorHandlerLoc),\n\t\t\t\t\t\t\t\t\t\"The handler for dynamic import failures is here:\")})\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// Forbid bundling of imports with explicit phases\n\t\t\t\t\tif record.Phase != ast.EvaluationPhase {\n\t\t\t\t\t\treportExplicitPhaseImport(args.log, &tracker, record.Range,\n\t\t\t\t\t\t\trecord.Phase, entry.resolveResult.PathPair.IsExternal, args.options.OutputFormat)\n\t\t\t\t\t}\n\n\t\t\t\t\tresult.resolveResults[importRecordIndex] = entry.resolveResult\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Attempt to parse the source map if present\n\t\tif loader.CanHaveSourceMap() && args.options.SourceMap != config.SourceMapNone {\n\t\t\tvar sourceMapComment logger.Span\n\t\t\tswitch repr := result.file.inputFile.Repr.(type) {\n\t\t\tcase *graph.JSRepr:\n\t\t\t\tsourceMapComment = repr.AST.SourceMapComment\n\t\t\tcase *graph.CSSRepr:\n\t\t\t\tsourceMapComment = repr.AST.SourceMapComment\n\t\t\t}\n\n\t\t\tif sourceMapComment.Text != \"\" {\n\t\t\t\ttracker := logger.MakeLineColumnTracker(&source)\n\n\t\t\t\tif path, contents := extractSourceMapFromComment(args.log, args.fs, &args.caches.FSCache,\n\t\t\t\t\t&source, &tracker, sourceMapComment, absResolveDir, args.options.LogPathStyle); contents != nil {\n\t\t\t\t\tprettyPaths := resolver.MakePrettyPaths(args.fs, path)\n\t\t\t\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, args.log.Overrides)\n\n\t\t\t\t\tsourceMap := js_parser.ParseSourceMap(log, logger.Source{\n\t\t\t\t\t\tKeyPath:     path,\n\t\t\t\t\t\tPrettyPaths: prettyPaths,\n\t\t\t\t\t\tContents:    *contents,\n\t\t\t\t\t})\n\n\t\t\t\t\tif msgs := log.Done(); len(msgs) > 0 {\n\t\t\t\t\t\tvar text string\n\t\t\t\t\t\tif path.Namespace == \"file\" {\n\t\t\t\t\t\t\ttext = fmt.Sprintf(\"The source map %q was referenced by the file %q here:\",\n\t\t\t\t\t\t\t\tprettyPaths.Select(args.options.LogPathStyle),\n\t\t\t\t\t\t\t\targs.prettyPaths.Select(args.options.LogPathStyle))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttext = fmt.Sprintf(\"This source map came from the file %q here:\",\n\t\t\t\t\t\t\t\targs.prettyPaths.Select(args.options.LogPathStyle))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnote := tracker.MsgData(sourceMapComment.Range, text)\n\t\t\t\t\t\tfor _, msg := range msgs {\n\t\t\t\t\t\t\tmsg.Notes = append(msg.Notes, note)\n\t\t\t\t\t\t\targs.log.AddMsg(msg)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// If \"sourcesContent\" entries aren't present, try filling them in\n\t\t\t\t\t// using the file system. This includes both generating the entire\n\t\t\t\t\t// \"sourcesContent\" array if it's absent as well as filling in\n\t\t\t\t\t// individual null entries in the array if the array is present.\n\t\t\t\t\tif sourceMap != nil && !args.options.ExcludeSourcesContent {\n\t\t\t\t\t\t// Make sure \"sourcesContent\" is big enough\n\t\t\t\t\t\tif len(sourceMap.SourcesContent) < len(sourceMap.Sources) {\n\t\t\t\t\t\t\tslice := make([]sourcemap.SourceContent, len(sourceMap.Sources))\n\t\t\t\t\t\t\tcopy(slice, sourceMap.SourcesContent)\n\t\t\t\t\t\t\tsourceMap.SourcesContent = slice\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor i, source := range sourceMap.Sources {\n\t\t\t\t\t\t\t// Convert absolute paths to \"file://\" URLs, which is especially important\n\t\t\t\t\t\t\t// for Windows where file paths don't look like URLs at all (they use \"\\\"\n\t\t\t\t\t\t\t// as a path separator and start with a \"C:\\\" volume label instead of \"/\").\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// The new source map specification (https://tc39.es/ecma426/) says that\n\t\t\t\t\t\t\t// each source is \"a string that is a (potentially relative) URL\". So we\n\t\t\t\t\t\t\t// should technically not be finding absolute paths here in the first place.\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// However, for a long time source maps was poorly-specified. The old source\n\t\t\t\t\t\t\t// map specification (https://sourcemaps.info/spec.html) only says \"sources\"\n\t\t\t\t\t\t\t// is \"a list of original sources used by the mappings entry\" which could\n\t\t\t\t\t\t\t// be anything, really.\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// So it makes sense that software which predates the formal specification\n\t\t\t\t\t\t\t// of source maps might fill in the sources array with absolute file paths\n\t\t\t\t\t\t\t// instead of URLs. Here are some cases where that happened:\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// - https://github.com/mozilla/source-map/issues/355\n\t\t\t\t\t\t\t// - https://github.com/webpack/webpack/issues/8226\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\tif path.Namespace == \"file\" && args.fs.IsAbs(source) {\n\t\t\t\t\t\t\t\tsource = helpers.FileURLFromFilePath(source).String()\n\t\t\t\t\t\t\t\tsourceMap.Sources[i] = source\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Attempt to fill in null entries using the file system\n\t\t\t\t\t\t\tif sourceMap.SourcesContent[i].Value == nil {\n\t\t\t\t\t\t\t\tif sourceURL, err := url.Parse(source); err == nil && helpers.IsFileURL(sourceURL) {\n\t\t\t\t\t\t\t\t\tif contents, err, _ := args.caches.FSCache.ReadFile(args.fs, helpers.FilePathFromFileURL(args.fs, sourceURL)); err == nil {\n\t\t\t\t\t\t\t\t\t\tsourceMap.SourcesContent[i].Value = helpers.StringToUTF16(contents)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresult.file.inputFile.InputSourceMap = sourceMap\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Note: We must always send on the \"inject\" channel before we send on the\n\t// \"results\" channel to avoid deadlock\n\tif args.inject != nil {\n\t\tvar exports []config.InjectableExport\n\n\t\tif repr, ok := result.file.inputFile.Repr.(*graph.JSRepr); ok {\n\t\t\taliases := make([]string, 0, len(repr.AST.NamedExports))\n\t\t\tfor alias := range repr.AST.NamedExports {\n\t\t\t\taliases = append(aliases, alias)\n\t\t\t}\n\t\t\tsort.Strings(aliases) // Sort for determinism\n\t\t\texports = make([]config.InjectableExport, len(aliases))\n\t\t\tfor i, alias := range aliases {\n\t\t\t\texports[i] = config.InjectableExport{\n\t\t\t\t\tAlias: alias,\n\t\t\t\t\tLoc:   repr.AST.NamedExports[alias].AliasLoc,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Once we send on the \"inject\" channel, the main thread may mutate the\n\t\t// \"options\" object to populate the \"InjectedFiles\" field. So we must\n\t\t// only send on the \"inject\" channel after we're done using the \"options\"\n\t\t// object so we don't introduce a data race.\n\t\tisCopyLoader := loader == config.LoaderCopy\n\t\tif isCopyLoader && args.skipResolve {\n\t\t\t// This is not allowed because the import path would have to be rewritten,\n\t\t\t// but import paths are not rewritten when bundling isn't enabled.\n\t\t\targs.log.AddError(nil, logger.Range{},\n\t\t\t\tfmt.Sprintf(\"Cannot inject %q with the \\\"copy\\\" loader without bundling enabled\",\n\t\t\t\t\tsource.PrettyPaths.Select(args.options.LogPathStyle)))\n\t\t}\n\t\targs.inject <- config.InjectedFile{\n\t\t\tSource:       source,\n\t\t\tExports:      exports,\n\t\t\tIsCopyLoader: isCopyLoader,\n\t\t}\n\t}\n\n\targs.results <- result\n}\n\nfunc reportExplicitPhaseImport(\n\tlog logger.Log,\n\ttracker *logger.LineColumnTracker,\n\tr logger.Range,\n\tphase ast.ImportPhase,\n\tisExternal bool,\n\tformat config.Format,\n) {\n\tvar phaseText string\n\tswitch phase {\n\tcase ast.DeferPhase:\n\t\tphaseText = \"deferred\"\n\tcase ast.SourcePhase:\n\t\tphaseText = \"source phase\"\n\tdefault:\n\t\treturn\n\t}\n\tif format != config.FormatESModule {\n\t\tlog.AddError(tracker, r, fmt.Sprintf(\"Bundling %s imports with the %q output format is not supported\", phaseText, format.String()))\n\t} else if !isExternal {\n\t\tlog.AddError(tracker, r, fmt.Sprintf(\"Bundling with %s imports is not supported unless they are external\", phaseText))\n\t}\n}\n\nfunc ResolveFailureErrorTextSuggestionNotes(\n\tres *resolver.Resolver,\n\tpath string,\n\tkind ast.ImportKind,\n\tpluginName string,\n\tfs fs.FS,\n\tabsResolveDir string,\n\tplatform config.Platform,\n\toriginatingFilePaths logger.PrettyPaths,\n\tmodifiedImportPath string,\n\tlogPathStyle logger.PathStyle,\n) (text string, suggestion string, notes []logger.MsgData) {\n\tif modifiedImportPath != \"\" {\n\t\ttext = fmt.Sprintf(\"Could not resolve %q (originally %q)\", modifiedImportPath, path)\n\t\tnotes = append(notes, logger.MsgData{Text: fmt.Sprintf(\n\t\t\t\"The path %q was remapped to %q using the alias feature, which then couldn't be resolved. \"+\n\t\t\t\t\"Keep in mind that import path aliases are resolved in the current working directory.\",\n\t\t\tpath, modifiedImportPath)})\n\t\tpath = modifiedImportPath\n\t} else {\n\t\ttext = fmt.Sprintf(\"Could not resolve %q\", path)\n\t}\n\thint := \"\"\n\n\tif resolver.IsPackagePath(path) && !fs.IsAbs(path) {\n\t\thint = fmt.Sprintf(\"You can mark the path %q as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\", path)\n\t\tif kind == ast.ImportRequire {\n\t\t\thint += \" You can also surround this \\\"require\\\" call with a try/catch block to handle this failure at run-time instead of bundle-time.\"\n\t\t} else if kind == ast.ImportDynamic {\n\t\t\thint += \" You can also add \\\".catch()\\\" here to handle this failure at run-time instead of bundle-time.\"\n\t\t}\n\t\tif pluginName == \"\" && !fs.IsAbs(path) {\n\t\t\tif query, _ := res.ProbeResolvePackageAsRelative(absResolveDir, path, kind); query != nil {\n\t\t\t\tprettyPaths := resolver.MakePrettyPaths(fs, query.PathPair.Primary)\n\t\t\t\thint = fmt.Sprintf(\"Use the relative path %q to reference the file %q. \"+\n\t\t\t\t\t\"Without the leading \\\"./\\\", the path %q is being interpreted as a package path instead.\",\n\t\t\t\t\t\"./\"+path, prettyPaths.Select(logPathStyle), path)\n\t\t\t\tsuggestion = string(helpers.QuoteForJSON(\"./\"+path, false))\n\t\t\t}\n\t\t}\n\t}\n\n\tif platform != config.PlatformNode {\n\t\tpkg := strings.TrimPrefix(path, \"node:\")\n\t\tif resolver.BuiltInNodeModules[pkg] {\n\t\t\tvar how string\n\t\t\tswitch logger.API {\n\t\t\tcase logger.CLIAPI:\n\t\t\t\thow = \"--platform=node\"\n\t\t\tcase logger.JSAPI:\n\t\t\t\thow = \"platform: 'node'\"\n\t\t\tcase logger.GoAPI:\n\t\t\t\thow = \"Platform: api.PlatformNode\"\n\t\t\t}\n\t\t\thint = fmt.Sprintf(\"The package %q wasn't found on the file system but is built into node. \"+\n\t\t\t\t\"Are you trying to bundle for node? You can use %q to do that, which will remove this error.\", path, how)\n\t\t}\n\t}\n\n\tif absResolveDir == \"\" && pluginName != \"\" {\n\t\twhere := \"\"\n\t\tif originatingFilePaths != (logger.PrettyPaths{}) {\n\t\t\twhere = fmt.Sprintf(\" for the file %q\", originatingFilePaths.Select(logPathStyle))\n\t\t}\n\t\thint = fmt.Sprintf(\"The plugin %q didn't set a resolve directory%s, \"+\n\t\t\t\"so esbuild did not search for %q on the file system.\", pluginName, where, path)\n\t}\n\n\tif hint != \"\" {\n\t\tif modifiedImportPath != \"\" {\n\t\t\t// Add a newline if there's already a paragraph of text\n\t\t\tnotes = append(notes, logger.MsgData{})\n\n\t\t\t// Don't add a suggestion if the path was rewritten using an alias\n\t\t\tsuggestion = \"\"\n\t\t}\n\t\tnotes = append(notes, logger.MsgData{Text: hint})\n\t}\n\treturn\n}\n\nfunc isASCIIOnly(text string) bool {\n\tfor _, c := range text {\n\t\tif c < 0x20 || c > 0x7E {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc guessMimeType(extension string, contents string) string {\n\tmimeType := helpers.MimeTypeByExtension(extension)\n\tif mimeType == \"\" {\n\t\tmimeType = http.DetectContentType([]byte(contents))\n\t}\n\n\t// Turn \"text/plain; charset=utf-8\" into \"text/plain;charset=utf-8\"\n\treturn strings.ReplaceAll(mimeType, \"; \", \";\")\n}\n\nfunc extractSourceMapFromComment(\n\tlog logger.Log,\n\tfs fs.FS,\n\tfsCache *cache.FSCache,\n\tsource *logger.Source,\n\ttracker *logger.LineColumnTracker,\n\tcomment logger.Span,\n\tabsResolveDir string,\n\tlogPathStyle logger.PathStyle,\n) (logger.Path, *string) {\n\t// Support data URLs\n\tif parsed, ok := resolver.ParseDataURL(comment.Text); ok {\n\t\tcontents, err := parsed.DecodeData()\n\t\tif err != nil {\n\t\t\tlog.AddID(logger.MsgID_SourceMap_UnsupportedSourceMapComment, logger.Warning, tracker, comment.Range,\n\t\t\t\tfmt.Sprintf(\"Unsupported source map comment: %s\", err.Error()))\n\t\t\treturn logger.Path{}, nil\n\t\t}\n\t\tpath := source.KeyPath\n\t\tpath.IgnoredSuffix = \"#sourceMappingURL\"\n\t\treturn path, &contents\n\t}\n\n\t// Support file URLs of two forms:\n\t//\n\t//   Relative: \"./foo.js.map\"\n\t//   Absolute: \"file:///Users/User/Desktop/foo.js.map\"\n\t//\n\tvar absPath string\n\tif commentURL, err := url.Parse(comment.Text); err != nil {\n\t\t// Show a warning if the comment can't be parsed as a URL\n\t\tlog.AddID(logger.MsgID_SourceMap_UnsupportedSourceMapComment, logger.Warning, tracker, comment.Range,\n\t\t\tfmt.Sprintf(\"Unsupported source map comment: %s\", err.Error()))\n\t\treturn logger.Path{}, nil\n\t} else if commentURL.Scheme != \"\" && commentURL.Scheme != \"file\" {\n\t\t// URLs with schemes other than \"file\" are unsupported (e.g. \"https\"),\n\t\t// but don't warn the user about this because it's not a bug they can fix\n\t\tlog.AddID(logger.MsgID_SourceMap_UnsupportedSourceMapComment, logger.Debug, tracker, comment.Range,\n\t\t\tfmt.Sprintf(\"Unsupported source map comment: Unsupported URL scheme %q\", commentURL.Scheme))\n\t\treturn logger.Path{}, nil\n\t} else if commentURL.Host != \"\" && commentURL.Host != \"localhost\" {\n\t\t// File URLs with hosts are unsupported (e.g. \"file://foo.js.map\")\n\t\tlog.AddID(logger.MsgID_SourceMap_UnsupportedSourceMapComment, logger.Warning, tracker, comment.Range,\n\t\t\tfmt.Sprintf(\"Unsupported source map comment: Unsupported host %q in file URL\", commentURL.Host))\n\t\treturn logger.Path{}, nil\n\t} else if helpers.IsFileURL(commentURL) {\n\t\t// Handle absolute file URLs\n\t\tabsPath = helpers.FilePathFromFileURL(fs, commentURL)\n\t} else if absResolveDir == \"\" {\n\t\t// Fail if plugins don't set a resolve directory\n\t\tlog.AddID(logger.MsgID_SourceMap_UnsupportedSourceMapComment, logger.Debug, tracker, comment.Range,\n\t\t\t\"Unsupported source map comment: Cannot resolve relative URL without a resolve directory\")\n\t\treturn logger.Path{}, nil\n\t} else {\n\t\t// Join the (potentially relative) URL path from the comment text\n\t\t// to the resolve directory path to form the final absolute path\n\t\tabsResolveURL := helpers.FileURLFromFilePath(absResolveDir)\n\t\tif !strings.HasSuffix(absResolveURL.Path, \"/\") {\n\t\t\tabsResolveURL.Path += \"/\"\n\t\t}\n\t\tabsPath = helpers.FilePathFromFileURL(fs, absResolveURL.ResolveReference(commentURL))\n\t}\n\n\t// Try to read the file contents\n\tpath := logger.Path{Text: absPath, Namespace: \"file\"}\n\tif contents, err, _ := fsCache.ReadFile(fs, absPath); err == syscall.ENOENT {\n\t\tlog.AddID(logger.MsgID_SourceMap_MissingSourceMap, logger.Debug, tracker, comment.Range,\n\t\t\tfmt.Sprintf(\"Cannot read file: %s\", absPath))\n\t\treturn logger.Path{}, nil\n\t} else if err != nil {\n\t\tprettyPaths := resolver.MakePrettyPaths(fs, path)\n\t\tlog.AddID(logger.MsgID_SourceMap_MissingSourceMap, logger.Warning, tracker, comment.Range,\n\t\t\tfmt.Sprintf(\"Cannot read file %q: %s\", prettyPaths.Select(logPathStyle), err.Error()))\n\t\treturn logger.Path{}, nil\n\t} else {\n\t\treturn path, &contents\n\t}\n}\n\nfunc sanitizeLocation(fs fs.FS, loc *logger.MsgLocation) {\n\tif loc != nil {\n\t\tif loc.Namespace == \"\" {\n\t\t\tloc.Namespace = \"file\"\n\t\t}\n\t\tif loc.File != (logger.PrettyPaths{}) {\n\t\t\tloc.File = resolver.MakePrettyPaths(fs, logger.Path{Text: loc.File.Abs, Namespace: loc.Namespace})\n\t\t}\n\t}\n}\n\nfunc logPluginMessages(\n\tfs fs.FS,\n\tlog logger.Log,\n\tname string,\n\tmsgs []logger.Msg,\n\tthrown error,\n\timportSource *logger.Source,\n\timportPathRange logger.Range,\n) bool {\n\tdidLogError := false\n\ttracker := logger.MakeLineColumnTracker(importSource)\n\n\t// Report errors and warnings generated by the plugin\n\tfor _, msg := range msgs {\n\t\tif msg.PluginName == \"\" {\n\t\t\tmsg.PluginName = name\n\t\t}\n\t\tif msg.Kind == logger.Error {\n\t\t\tdidLogError = true\n\t\t}\n\n\t\t// Sanitize the locations\n\t\tfor _, note := range msg.Notes {\n\t\t\tsanitizeLocation(fs, note.Location)\n\t\t}\n\t\tif msg.Data.Location == nil {\n\t\t\tmsg.Data.Location = tracker.MsgLocationOrNil(importPathRange)\n\t\t} else {\n\t\t\tsanitizeLocation(fs, msg.Data.Location)\n\t\t\tif importSource != nil {\n\t\t\t\tif msg.Data.Location.File == (logger.PrettyPaths{}) {\n\t\t\t\t\tmsg.Data.Location.File = importSource.PrettyPaths\n\t\t\t\t}\n\t\t\t\tmsg.Notes = append(msg.Notes, tracker.MsgData(importPathRange,\n\t\t\t\t\tfmt.Sprintf(\"The plugin %q was triggered by this import\", name)))\n\t\t\t}\n\t\t}\n\n\t\tlog.AddMsg(msg)\n\t}\n\n\t// Report errors thrown by the plugin itself\n\tif thrown != nil {\n\t\tdidLogError = true\n\t\ttext := thrown.Error()\n\t\tlog.AddMsg(logger.Msg{\n\t\t\tPluginName: name,\n\t\t\tKind:       logger.Error,\n\t\t\tData: logger.MsgData{\n\t\t\t\tText:       text,\n\t\t\t\tLocation:   tracker.MsgLocationOrNil(importPathRange),\n\t\t\t\tUserDetail: thrown,\n\t\t\t},\n\t\t})\n\t}\n\n\treturn didLogError\n}\n\nfunc RunOnResolvePlugins(\n\tplugins []config.Plugin,\n\tres *resolver.Resolver,\n\tlog logger.Log,\n\tfs fs.FS,\n\tfsCache *cache.FSCache,\n\timportSource *logger.Source,\n\timportPathRange logger.Range,\n\timporter logger.Path,\n\tpath string,\n\timportAttributes logger.ImportAttributes,\n\tkind ast.ImportKind,\n\tabsResolveDir string,\n\tpluginData interface{},\n\tlogPathStyle logger.PathStyle,\n) (*resolver.ResolveResult, bool, resolver.DebugMeta) {\n\tresolverArgs := config.OnResolveArgs{\n\t\tPath:       path,\n\t\tResolveDir: absResolveDir,\n\t\tKind:       kind,\n\t\tPluginData: pluginData,\n\t\tImporter:   importer,\n\t\tWith:       importAttributes,\n\t}\n\tapplyPath := logger.Path{\n\t\tText:      path,\n\t\tNamespace: importer.Namespace,\n\t}\n\ttracker := logger.MakeLineColumnTracker(importSource)\n\n\t// Apply resolver plugins in order until one succeeds\n\tfor _, plugin := range plugins {\n\t\tfor _, onResolve := range plugin.OnResolve {\n\t\t\tif !config.PluginAppliesToPath(applyPath, onResolve.Filter, onResolve.Namespace) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tresult := onResolve.Callback(resolverArgs)\n\t\t\tpluginName := result.PluginName\n\t\t\tif pluginName == \"\" {\n\t\t\t\tpluginName = plugin.Name\n\t\t\t}\n\t\t\tdidLogError := logPluginMessages(fs, log, pluginName, result.Msgs, result.ThrownError, importSource, importPathRange)\n\n\t\t\t// Plugins can also provide additional file system paths to watch\n\t\t\tfor _, file := range result.AbsWatchFiles {\n\t\t\t\tfsCache.ReadFile(fs, file)\n\t\t\t}\n\t\t\tfor _, dir := range result.AbsWatchDirs {\n\t\t\t\tif entries, err, _ := fs.ReadDirectory(dir); err == nil {\n\t\t\t\t\tentries.SortedKeys()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Stop now if there was an error\n\t\t\tif didLogError {\n\t\t\t\treturn nil, true, resolver.DebugMeta{}\n\t\t\t}\n\n\t\t\t// The \"file\" namespace is the default for non-external paths, but not\n\t\t\t// for external paths. External paths must explicitly specify the \"file\"\n\t\t\t// namespace.\n\t\t\tnsFromPlugin := result.Path.Namespace\n\t\t\tif result.Path.Namespace == \"\" && !result.External {\n\t\t\t\tresult.Path.Namespace = \"file\"\n\t\t\t}\n\n\t\t\t// Otherwise, continue on to the next resolver if this loader didn't succeed\n\t\t\tif result.Path.Text == \"\" {\n\t\t\t\tif result.External {\n\t\t\t\t\tresult.Path = logger.Path{Text: path}\n\t\t\t\t} else {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Paths in the file namespace must be absolute paths\n\t\t\tif result.Path.Namespace == \"file\" && !fs.IsAbs(result.Path.Text) {\n\t\t\t\tif nsFromPlugin == \"file\" {\n\t\t\t\t\tlog.AddError(&tracker, importPathRange,\n\t\t\t\t\t\tfmt.Sprintf(\"Plugin %q returned a path in the \\\"file\\\" namespace that is not an absolute path: %s\", pluginName, result.Path.Text))\n\t\t\t\t} else {\n\t\t\t\t\tlog.AddError(&tracker, importPathRange,\n\t\t\t\t\t\tfmt.Sprintf(\"Plugin %q returned a non-absolute path: %s (set a namespace if this is not a file path)\", pluginName, result.Path.Text))\n\t\t\t\t}\n\t\t\t\treturn nil, true, resolver.DebugMeta{}\n\t\t\t}\n\n\t\t\tvar sideEffectsData *resolver.SideEffectsData\n\t\t\tif result.IsSideEffectFree {\n\t\t\t\tsideEffectsData = &resolver.SideEffectsData{\n\t\t\t\t\tPluginName: pluginName,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn &resolver.ResolveResult{\n\t\t\t\tPathPair:               resolver.PathPair{Primary: result.Path, IsExternal: result.External},\n\t\t\t\tPluginData:             result.PluginData,\n\t\t\t\tPrimarySideEffectsData: sideEffectsData,\n\t\t\t}, false, resolver.DebugMeta{}\n\t\t}\n\t}\n\n\t// Resolve relative to the resolve directory by default. All paths in the\n\t// \"file\" namespace automatically have a resolve directory. Loader plugins\n\t// can also configure a custom resolve directory for files in other namespaces.\n\tresult, debug := res.Resolve(absResolveDir, path, kind)\n\n\t// Warn when the case used for importing differs from the actual file name\n\tif result != nil && result.DifferentCase != nil && !helpers.IsInsideNodeModules(absResolveDir) {\n\t\tdiffCase := *result.DifferentCase\n\t\tactualPaths := resolver.MakePrettyPaths(fs, logger.Path{Text: fs.Join(diffCase.Dir, diffCase.Actual), Namespace: \"file\"})\n\t\tqueryPaths := resolver.MakePrettyPaths(fs, logger.Path{Text: fs.Join(diffCase.Dir, diffCase.Query), Namespace: \"file\"})\n\t\tlog.AddID(logger.MsgID_Bundler_DifferentPathCase, logger.Warning, &tracker, importPathRange, fmt.Sprintf(\n\t\t\t\"Use %q instead of %q to avoid issues with case-sensitive file systems\",\n\t\t\tactualPaths.Select(logPathStyle),\n\t\t\tqueryPaths.Select(logPathStyle),\n\t\t))\n\t}\n\n\treturn result, false, debug\n}\n\ntype loaderPluginResult struct {\n\tpluginData    interface{}\n\tabsResolveDir string\n\tpluginName    string\n\tloader        config.Loader\n}\n\nfunc runOnLoadPlugins(\n\tplugins []config.Plugin,\n\tfs fs.FS,\n\tfsCache *cache.FSCache,\n\tlog logger.Log,\n\tsource *logger.Source,\n\timportSource *logger.Source,\n\timportPathRange logger.Range,\n\tpluginData interface{},\n\tisWatchMode bool,\n\tlogPathStyle logger.PathStyle,\n) (loaderPluginResult, bool) {\n\tloaderArgs := config.OnLoadArgs{\n\t\tPath:       source.KeyPath,\n\t\tPluginData: pluginData,\n\t}\n\ttracker := logger.MakeLineColumnTracker(importSource)\n\n\t// Apply loader plugins in order until one succeeds\n\tfor _, plugin := range plugins {\n\t\tfor _, onLoad := range plugin.OnLoad {\n\t\t\tif !config.PluginAppliesToPath(source.KeyPath, onLoad.Filter, onLoad.Namespace) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tresult := onLoad.Callback(loaderArgs)\n\t\t\tpluginName := result.PluginName\n\t\t\tif pluginName == \"\" {\n\t\t\t\tpluginName = plugin.Name\n\t\t\t}\n\t\t\tdidLogError := logPluginMessages(fs, log, pluginName, result.Msgs, result.ThrownError, importSource, importPathRange)\n\n\t\t\t// Plugins can also provide additional file system paths to watch\n\t\t\tfor _, file := range result.AbsWatchFiles {\n\t\t\t\tfsCache.ReadFile(fs, file)\n\t\t\t}\n\t\t\tfor _, dir := range result.AbsWatchDirs {\n\t\t\t\tif entries, err, _ := fs.ReadDirectory(dir); err == nil {\n\t\t\t\t\tentries.SortedKeys()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Stop now if there was an error\n\t\t\tif didLogError {\n\t\t\t\tif isWatchMode && source.KeyPath.Namespace == \"file\" {\n\t\t\t\t\tfsCache.ReadFile(fs, source.KeyPath.Text) // Read the file for watch mode tracking\n\t\t\t\t}\n\t\t\t\treturn loaderPluginResult{}, false\n\t\t\t}\n\n\t\t\t// Otherwise, continue on to the next loader if this loader didn't succeed\n\t\t\tif result.Contents == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tsource.Contents = *result.Contents\n\t\t\tloader := result.Loader\n\t\t\tif loader == config.LoaderNone {\n\t\t\t\tloader = config.LoaderJS\n\t\t\t}\n\t\t\tif result.AbsResolveDir == \"\" && source.KeyPath.Namespace == \"file\" {\n\t\t\t\tresult.AbsResolveDir = fs.Dir(source.KeyPath.Text)\n\t\t\t}\n\t\t\tif isWatchMode && source.KeyPath.Namespace == \"file\" {\n\t\t\t\tfsCache.ReadFile(fs, source.KeyPath.Text) // Read the file for watch mode tracking\n\t\t\t}\n\t\t\treturn loaderPluginResult{\n\t\t\t\tloader:        loader,\n\t\t\t\tabsResolveDir: result.AbsResolveDir,\n\t\t\t\tpluginName:    pluginName,\n\t\t\t\tpluginData:    result.PluginData,\n\t\t\t}, true\n\t\t}\n\t}\n\n\t// Force disabled modules to be empty\n\tif source.KeyPath.IsDisabled() {\n\t\treturn loaderPluginResult{loader: config.LoaderEmpty}, true\n\t}\n\n\t// Read normal modules from disk\n\tif source.KeyPath.Namespace == \"file\" {\n\t\tif contents, err, _ := fsCache.ReadFile(fs, source.KeyPath.Text); err == nil {\n\t\t\tsource.Contents = contents\n\t\t\treturn loaderPluginResult{\n\t\t\t\tloader:        config.LoaderDefault,\n\t\t\t\tabsResolveDir: fs.Dir(source.KeyPath.Text),\n\t\t\t}, true\n\t\t} else {\n\t\t\tif err == syscall.ENOENT {\n\t\t\t\tlog.AddError(&tracker, importPathRange,\n\t\t\t\t\tfmt.Sprintf(\"Cannot read file: %s\", source.KeyPath.Text))\n\t\t\t\treturn loaderPluginResult{}, false\n\t\t\t} else {\n\t\t\t\tprettyPaths := resolver.MakePrettyPaths(fs, source.KeyPath)\n\t\t\t\tlog.AddError(&tracker, importPathRange,\n\t\t\t\t\tfmt.Sprintf(\"Cannot read file %q: %s\", prettyPaths.Select(logPathStyle), err.Error()))\n\t\t\t\treturn loaderPluginResult{}, false\n\t\t\t}\n\t\t}\n\t}\n\n\t// Native support for data URLs. This is supported natively by node:\n\t// https://nodejs.org/docs/latest/api/esm.html#esm_data_imports\n\tif source.KeyPath.Namespace == \"dataurl\" {\n\t\tif parsed, ok := resolver.ParseDataURL(source.KeyPath.Text); ok {\n\t\t\tif contents, err := parsed.DecodeData(); err != nil {\n\t\t\t\tlog.AddError(&tracker, importPathRange,\n\t\t\t\t\tfmt.Sprintf(\"Could not load data URL: %s\", err.Error()))\n\t\t\t\treturn loaderPluginResult{loader: config.LoaderNone}, true\n\t\t\t} else {\n\t\t\t\tsource.Contents = contents\n\t\t\t\tif mimeType := parsed.DecodeMIMEType(); mimeType != resolver.MIMETypeUnsupported {\n\t\t\t\t\tswitch mimeType {\n\t\t\t\t\tcase resolver.MIMETypeTextCSS:\n\t\t\t\t\t\treturn loaderPluginResult{loader: config.LoaderCSS}, true\n\t\t\t\t\tcase resolver.MIMETypeTextJavaScript:\n\t\t\t\t\t\treturn loaderPluginResult{loader: config.LoaderJS}, true\n\t\t\t\t\tcase resolver.MIMETypeApplicationJSON:\n\t\t\t\t\t\treturn loaderPluginResult{loader: config.LoaderJSON}, true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Otherwise, fail to load the path\n\treturn loaderPluginResult{loader: config.LoaderNone}, true\n}\n\n// Identify the path by its lowercase absolute path name with Windows-specific\n// slashes substituted for standard slashes. This should hopefully avoid path\n// issues on Windows where multiple different paths can refer to the same\n// underlying file.\nfunc canonicalFileSystemPathForWindows(absPath string) string {\n\treturn strings.ReplaceAll(strings.ToLower(absPath), \"\\\\\", \"/\")\n}\n\nfunc HashForFileName(hashBytes []byte) string {\n\treturn base32.StdEncoding.EncodeToString(hashBytes)[:8]\n}\n\ntype scanner struct {\n\tlog             logger.Log\n\tfs              fs.FS\n\tres             *resolver.Resolver\n\tcaches          *cache.CacheSet\n\ttimer           *helpers.Timer\n\tuniqueKeyPrefix string\n\n\t// These are not guarded by a mutex because it's only ever modified by a single\n\t// thread. Note that not all results in the \"results\" array are necessarily\n\t// valid. Make sure to check the \"ok\" flag before using them.\n\tresults       []parseResult\n\tvisited       map[logger.Path]visitedFile\n\tresultChannel chan parseResult\n\n\toptions config.Options\n\n\t// Also not guarded by a mutex for the same reason\n\tremaining int\n}\n\ntype visitedFile struct {\n\tsourceIndex uint32\n}\n\ntype EntryPoint struct {\n\tInputPath                string\n\tOutputPath               string\n\tInputPathInFileNamespace bool\n}\n\nfunc generateUniqueKeyPrefix() (string, error) {\n\tvar data [12]byte\n\trand.Seed(time.Now().UnixNano())\n\tif _, err := rand.Read(data[:]); err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// This is 16 bytes and shouldn't generate escape characters when put into strings\n\treturn base64.URLEncoding.EncodeToString(data[:]), nil\n}\n\n// This creates a bundle by scanning over the whole module graph starting from\n// the entry points until all modules are reached. Each module has some number\n// of import paths which are resolved to module identifiers (i.e. \"onResolve\"\n// in the plugin API). Each unique module identifier is loaded once (i.e.\n// \"onLoad\" in the plugin API).\nfunc ScanBundle(\n\tcall config.APICall,\n\tlog logger.Log,\n\tfs fs.FS,\n\tcaches *cache.CacheSet,\n\tentryPoints []EntryPoint,\n\toptions config.Options,\n\ttimer *helpers.Timer,\n) Bundle {\n\ttimer.Begin(\"Scan phase\")\n\tdefer timer.End(\"Scan phase\")\n\n\tapplyOptionDefaults(&options)\n\n\t// Run \"onStart\" plugins in parallel. IMPORTANT: We always need to run all\n\t// \"onStart\" callbacks even when the build is cancelled, because plugins may\n\t// rely on invariants that are started in \"onStart\" and ended in \"onEnd\".\n\t// This works because \"onEnd\" callbacks are always run as well.\n\ttimer.Begin(\"On-start callbacks\")\n\tonStartWaitGroup := sync.WaitGroup{}\n\tfor _, plugin := range options.Plugins {\n\t\tfor _, onStart := range plugin.OnStart {\n\t\t\tonStartWaitGroup.Add(1)\n\t\t\tgo func(plugin config.Plugin, onStart config.OnStart) {\n\t\t\t\tresult := onStart.Callback()\n\t\t\t\tlogPluginMessages(fs, log, plugin.Name, result.Msgs, result.ThrownError, nil, logger.Range{})\n\t\t\t\tonStartWaitGroup.Done()\n\t\t\t}(plugin, onStart)\n\t\t}\n\t}\n\n\t// Each bundling operation gets a separate unique key\n\tuniqueKeyPrefix, err := generateUniqueKeyPrefix()\n\tif err != nil {\n\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\"Failed to read from randomness source: %s\", err.Error()))\n\t}\n\n\t// This may mutate \"options\" by the \"tsconfig.json\" override settings\n\tres := resolver.NewResolver(call, fs, log, caches, &options)\n\n\ts := scanner{\n\t\tlog:             log,\n\t\tfs:              fs,\n\t\tres:             res,\n\t\tcaches:          caches,\n\t\toptions:         options,\n\t\ttimer:           timer,\n\t\tresults:         make([]parseResult, 0, caches.SourceIndexCache.LenHint()),\n\t\tvisited:         make(map[logger.Path]visitedFile),\n\t\tresultChannel:   make(chan parseResult),\n\t\tuniqueKeyPrefix: uniqueKeyPrefix,\n\t}\n\n\t// Always start by parsing the runtime file\n\ts.results = append(s.results, parseResult{})\n\ts.remaining++\n\tgo func() {\n\t\tsource, ast, ok := globalRuntimeCache.parseRuntime(&options)\n\t\ts.resultChannel <- parseResult{\n\t\t\tfile: scannerFile{\n\t\t\t\tinputFile: graph.InputFile{\n\t\t\t\t\tSource: source,\n\t\t\t\t\tRepr: &graph.JSRepr{\n\t\t\t\t\t\tAST: ast,\n\t\t\t\t\t},\n\t\t\t\t\tOmitFromSourceMapsAndMetafile: true,\n\t\t\t\t},\n\t\t\t},\n\t\t\tok: ok,\n\t\t}\n\t}()\n\n\t// Always consume all unused results. Failing to do so could cause a memory\n\t// leak if a build is cancelled. We can't cancel the producers by closing the\n\t// channel because doing so in Go causes a panic (which is arguably a design\n\t// bug with Go).\n\tdefer func() {\n\t\tfor s.remaining > 0 {\n\t\t\t<-s.resultChannel\n\t\t\ts.remaining--\n\t\t}\n\t}()\n\n\t// Wait for all \"onStart\" plugins here before continuing. People sometimes run\n\t// setup code in \"onStart\" that \"onLoad\" expects to be able to use without\n\t// \"onLoad\" needing to block on the completion of their \"onStart\" callback.\n\t//\n\t// We want to enable this:\n\t//\n\t//   let plugin = {\n\t//     name: 'example',\n\t//     setup(build) {\n\t//       let started = false\n\t//       build.onStart(() => started = true)\n\t//       build.onLoad({ filter: /.*/ }, () => {\n\t//         assert(started === true)\n\t//       })\n\t//     },\n\t//   }\n\t//\n\t// without people having to write something like this:\n\t//\n\t//   let plugin = {\n\t//     name: 'example',\n\t//     setup(build) {\n\t//       let started = {}\n\t//       started.promise = new Promise(resolve => {\n\t//         started.resolve = resolve\n\t//       })\n\t//       build.onStart(() => {\n\t//         started.resolve(true)\n\t//       })\n\t//       build.onLoad({ filter: /.*/ }, async () => {\n\t//         assert(await started.promise === true)\n\t//       })\n\t//     },\n\t//   }\n\t//\n\tonStartWaitGroup.Wait()\n\ttimer.End(\"On-start callbacks\")\n\n\t// We can check the cancel flag now that all \"onStart\" callbacks are done\n\tif options.CancelFlag.DidCancel() {\n\t\treturn Bundle{options: options}\n\t}\n\n\ts.preprocessInjectedFiles()\n\n\tif options.CancelFlag.DidCancel() {\n\t\treturn Bundle{options: options}\n\t}\n\n\tentryPointMeta := s.addEntryPoints(entryPoints)\n\n\tif options.CancelFlag.DidCancel() {\n\t\treturn Bundle{options: options}\n\t}\n\n\ts.scanAllDependencies()\n\n\tif options.CancelFlag.DidCancel() {\n\t\treturn Bundle{options: options}\n\t}\n\n\tfiles := s.processScannedFiles(entryPointMeta)\n\n\tif options.CancelFlag.DidCancel() {\n\t\treturn Bundle{options: options}\n\t}\n\n\treturn Bundle{\n\t\tfs:              fs,\n\t\tres:             s.res,\n\t\tfiles:           files,\n\t\tentryPoints:     entryPointMeta,\n\t\tuniqueKeyPrefix: uniqueKeyPrefix,\n\t\toptions:         s.options,\n\t}\n}\n\ntype inputKind uint8\n\nconst (\n\tinputKindNormal inputKind = iota\n\tinputKindEntryPoint\n\tinputKindStdin\n)\n\n// This returns the source index of the resulting file\nfunc (s *scanner) maybeParseFile(\n\tresolveResult resolver.ResolveResult,\n\tprettyPaths logger.PrettyPaths,\n\timportSource *logger.Source,\n\timportPathRange logger.Range,\n\timportWith *ast.ImportAssertOrWith,\n\tkind inputKind,\n\tinject chan config.InjectedFile,\n) uint32 {\n\tpath := resolveResult.PathPair.Primary\n\tvisitedKey := path\n\tif visitedKey.Namespace == \"file\" {\n\t\tvisitedKey.Text = canonicalFileSystemPathForWindows(visitedKey.Text)\n\t}\n\n\t// Only parse a given file path once\n\tvisited, ok := s.visited[visitedKey]\n\tif ok {\n\t\tif inject != nil {\n\t\t\tinject <- config.InjectedFile{}\n\t\t}\n\t\treturn visited.sourceIndex\n\t}\n\n\tvisited = visitedFile{\n\t\tsourceIndex: s.allocateSourceIndex(visitedKey, cache.SourceIndexNormal),\n\t}\n\ts.visited[visitedKey] = visited\n\ts.remaining++\n\toptionsClone := s.options\n\tif kind != inputKindStdin {\n\t\toptionsClone.Stdin = nil\n\t}\n\n\t// Allow certain properties to be overridden by \"tsconfig.json\"\n\tresolveResult.TSConfigJSX.ApplyTo(&optionsClone.JSX)\n\tif resolveResult.TSConfig != nil {\n\t\toptionsClone.TS.Config = *resolveResult.TSConfig\n\t}\n\tif resolveResult.TSAlwaysStrict != nil {\n\t\toptionsClone.TSAlwaysStrict = resolveResult.TSAlwaysStrict\n\t}\n\n\t// Set the module type preference using node's module type rules\n\tif strings.HasSuffix(path.Text, \".mjs\") {\n\t\toptionsClone.ModuleTypeData.Type = js_ast.ModuleESM_MJS\n\t} else if strings.HasSuffix(path.Text, \".mts\") {\n\t\toptionsClone.ModuleTypeData.Type = js_ast.ModuleESM_MTS\n\t} else if strings.HasSuffix(path.Text, \".cjs\") {\n\t\toptionsClone.ModuleTypeData.Type = js_ast.ModuleCommonJS_CJS\n\t} else if strings.HasSuffix(path.Text, \".cts\") {\n\t\toptionsClone.ModuleTypeData.Type = js_ast.ModuleCommonJS_CTS\n\t} else if strings.HasSuffix(path.Text, \".js\") || strings.HasSuffix(path.Text, \".jsx\") ||\n\t\tstrings.HasSuffix(path.Text, \".ts\") || strings.HasSuffix(path.Text, \".tsx\") {\n\t\toptionsClone.ModuleTypeData = resolveResult.ModuleTypeData\n\t} else {\n\t\t// The \"type\" setting in \"package.json\" only applies to \".js\" files\n\t\toptionsClone.ModuleTypeData.Type = js_ast.ModuleUnknown\n\t}\n\n\t// Enable bundling for injected files so we always do tree shaking. We\n\t// never want to include unnecessary code from injected files since they\n\t// are essentially bundled. However, if we do this we should skip the\n\t// resolving step when we're not bundling. It'd be strange to get\n\t// resolution errors when the top-level bundling controls are disabled.\n\tskipResolve := false\n\tif inject != nil && optionsClone.Mode != config.ModeBundle {\n\t\toptionsClone.Mode = config.ModeBundle\n\t\tskipResolve = true\n\t}\n\n\t// Special-case pretty-printed paths for data URLs\n\tif path.Namespace == \"dataurl\" {\n\t\tif _, ok := resolver.ParseDataURL(path.Text); ok {\n\t\t\tprettyPath := path.Text\n\t\t\tif len(prettyPath) > 65 {\n\t\t\t\tprettyPath = prettyPath[:65]\n\t\t\t}\n\t\t\tprettyPath = strings.ReplaceAll(prettyPath, \"\\n\", \"\\\\n\")\n\t\t\tif len(prettyPath) > 64 {\n\t\t\t\tprettyPath = prettyPath[:64] + \"...\"\n\t\t\t}\n\t\t\tprettyPath = fmt.Sprintf(\"<%s>\", prettyPath)\n\t\t\tprettyPaths.Abs = prettyPath\n\t\t\tprettyPaths.Rel = prettyPath\n\t\t}\n\t}\n\n\tvar sideEffects graph.SideEffects\n\tif resolveResult.PrimarySideEffectsData != nil {\n\t\tsideEffects.Kind = graph.NoSideEffects_PackageJSON\n\t\tsideEffects.Data = resolveResult.PrimarySideEffectsData\n\t}\n\n\tgo parseFile(parseArgs{\n\t\tfs:              s.fs,\n\t\tlog:             s.log,\n\t\tres:             s.res,\n\t\tcaches:          s.caches,\n\t\tkeyPath:         path,\n\t\tprettyPaths:     prettyPaths,\n\t\tsourceIndex:     visited.sourceIndex,\n\t\timportSource:    importSource,\n\t\tsideEffects:     sideEffects,\n\t\timportPathRange: importPathRange,\n\t\timportWith:      importWith,\n\t\tpluginData:      resolveResult.PluginData,\n\t\toptions:         optionsClone,\n\t\tresults:         s.resultChannel,\n\t\tinject:          inject,\n\t\tskipResolve:     skipResolve,\n\t\tuniqueKeyPrefix: s.uniqueKeyPrefix,\n\t})\n\n\treturn visited.sourceIndex\n}\n\nfunc (s *scanner) allocateSourceIndex(path logger.Path, kind cache.SourceIndexKind) uint32 {\n\t// Allocate a source index using the shared source index cache so that\n\t// subsequent builds reuse the same source index and therefore use the\n\t// cached parse results for increased speed.\n\tsourceIndex := s.caches.SourceIndexCache.Get(path, kind)\n\n\t// Grow the results array to fit this source index\n\tif newLen := int(sourceIndex) + 1; len(s.results) < newLen {\n\t\t// Reallocate to a bigger array\n\t\tif cap(s.results) < newLen {\n\t\t\ts.results = append(make([]parseResult, 0, 2*newLen), s.results...)\n\t\t}\n\n\t\t// Grow in place\n\t\ts.results = s.results[:newLen]\n\t}\n\n\treturn sourceIndex\n}\n\nfunc (s *scanner) allocateGlobSourceIndex(parentSourceIndex uint32, globIndex uint32) uint32 {\n\t// Allocate a source index using the shared source index cache so that\n\t// subsequent builds reuse the same source index and therefore use the\n\t// cached parse results for increased speed.\n\tsourceIndex := s.caches.SourceIndexCache.GetGlob(parentSourceIndex, globIndex)\n\n\t// Grow the results array to fit this source index\n\tif newLen := int(sourceIndex) + 1; len(s.results) < newLen {\n\t\t// Reallocate to a bigger array\n\t\tif cap(s.results) < newLen {\n\t\t\ts.results = append(make([]parseResult, 0, 2*newLen), s.results...)\n\t\t}\n\n\t\t// Grow in place\n\t\ts.results = s.results[:newLen]\n\t}\n\n\treturn sourceIndex\n}\n\nfunc (s *scanner) preprocessInjectedFiles() {\n\ts.timer.Begin(\"Preprocess injected files\")\n\tdefer s.timer.End(\"Preprocess injected files\")\n\n\tinjectedFiles := make([]config.InjectedFile, 0, len(s.options.InjectedDefines)+len(s.options.InjectPaths))\n\n\t// These are virtual paths that are generated for compound \"--define\" values.\n\t// They are special-cased and are not available for plugins to intercept.\n\tfor _, define := range s.options.InjectedDefines {\n\t\t// These should be unique by construction so no need to check for collisions\n\t\tvisitedKey := logger.Path{Text: fmt.Sprintf(\"<define:%s>\", define.Name)}\n\t\tsourceIndex := s.allocateSourceIndex(visitedKey, cache.SourceIndexNormal)\n\t\ts.visited[visitedKey] = visitedFile{sourceIndex: sourceIndex}\n\t\tsource := logger.Source{\n\t\t\tIndex:          sourceIndex,\n\t\t\tKeyPath:        visitedKey,\n\t\t\tPrettyPaths:    resolver.MakePrettyPaths(s.fs, visitedKey),\n\t\t\tIdentifierName: js_ast.EnsureValidIdentifier(visitedKey.Text),\n\t\t\tContents:       define.Source.Contents,\n\t\t}\n\n\t\t// The first \"len(InjectedDefine)\" injected files intentionally line up\n\t\t// with the injected defines by index. The index will be used to import\n\t\t// references to them in the parser.\n\t\tinjectedFiles = append(injectedFiles, config.InjectedFile{\n\t\t\tSource:     source,\n\t\t\tDefineName: define.Name,\n\t\t})\n\n\t\t// Generate the file inline here since it has already been parsed\n\t\texpr := js_ast.Expr{Data: define.Data}\n\t\tast := js_parser.LazyExportAST(s.log, source, js_parser.OptionsFromConfig(&s.options), expr, nil)\n\t\tresult := parseResult{\n\t\t\tok: true,\n\t\t\tfile: scannerFile{\n\t\t\t\tinputFile: graph.InputFile{\n\t\t\t\t\tSource: source,\n\t\t\t\t\tRepr:   &graph.JSRepr{AST: ast},\n\t\t\t\t\tLoader: config.LoaderJSON,\n\t\t\t\t\tSideEffects: graph.SideEffects{\n\t\t\t\t\t\tKind: graph.NoSideEffects_PureData,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\n\t\t// Append to the channel on a goroutine in case it blocks due to capacity\n\t\ts.remaining++\n\t\tgo func() { s.resultChannel <- result }()\n\t}\n\n\t// Add user-specified injected files. Run resolver plugins on these files\n\t// so plugins can alter where they resolve to. These are run in parallel in\n\t// case any of these plugins block.\n\tinjectResolveResults := make([]*resolver.ResolveResult, len(s.options.InjectPaths))\n\tinjectAbsResolveDir := s.fs.Cwd()\n\tinjectResolveWaitGroup := sync.WaitGroup{}\n\tinjectResolveWaitGroup.Add(len(s.options.InjectPaths))\n\tfor i, importPath := range s.options.InjectPaths {\n\t\tgo func(i int, importPath string) {\n\t\t\tvar importer logger.Path\n\n\t\t\t// Add a leading \"./\" if it's missing, similar to entry points\n\t\t\tabsPath := importPath\n\t\t\tif !s.fs.IsAbs(absPath) {\n\t\t\t\tabsPath = s.fs.Join(injectAbsResolveDir, absPath)\n\t\t\t}\n\t\t\tdir := s.fs.Dir(absPath)\n\t\t\tbase := s.fs.Base(absPath)\n\t\t\tif entries, err, originalError := s.fs.ReadDirectory(dir); err == nil {\n\t\t\t\tif entry, _ := entries.Get(base); entry != nil && entry.Kind(s.fs) == fs.FileEntry {\n\t\t\t\t\timporter.Namespace = \"file\"\n\t\t\t\t\tif !s.fs.IsAbs(importPath) && resolver.IsPackagePath(importPath) {\n\t\t\t\t\t\timportPath = \"./\" + importPath\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if s.log.Level <= logger.LevelDebug && originalError != nil {\n\t\t\t\ts.log.AddID(logger.MsgID_None, logger.Debug, nil, logger.Range{}, fmt.Sprintf(\"Failed to read directory %q: %s\", absPath, originalError.Error()))\n\t\t\t}\n\n\t\t\t// Run the resolver and log an error if the path couldn't be resolved\n\t\t\tresolveResult, didLogError, debug := RunOnResolvePlugins(\n\t\t\t\ts.options.Plugins,\n\t\t\t\ts.res,\n\t\t\t\ts.log,\n\t\t\t\ts.fs,\n\t\t\t\t&s.caches.FSCache,\n\t\t\t\tnil,\n\t\t\t\tlogger.Range{},\n\t\t\t\timporter,\n\t\t\t\timportPath,\n\t\t\t\tlogger.ImportAttributes{},\n\t\t\t\tast.ImportEntryPoint,\n\t\t\t\tinjectAbsResolveDir,\n\t\t\t\tnil,\n\t\t\t\ts.options.LogPathStyle,\n\t\t\t)\n\t\t\tif resolveResult != nil {\n\t\t\t\tif resolveResult.PathPair.IsExternal {\n\t\t\t\t\ts.log.AddError(nil, logger.Range{}, fmt.Sprintf(\"The injected path %q cannot be marked as external\", importPath))\n\t\t\t\t} else {\n\t\t\t\t\tinjectResolveResults[i] = resolveResult\n\t\t\t\t}\n\t\t\t} else if !didLogError {\n\t\t\t\tdebug.LogErrorMsg(s.log, nil, logger.Range{}, fmt.Sprintf(\"Could not resolve %q\", importPath), \"\", nil)\n\t\t\t}\n\t\t\tinjectResolveWaitGroup.Done()\n\t\t}(i, importPath)\n\t}\n\tinjectResolveWaitGroup.Wait()\n\n\tif s.options.CancelFlag.DidCancel() {\n\t\treturn\n\t}\n\n\t// Parse all entry points that were resolved successfully\n\tresults := make([]config.InjectedFile, len(s.options.InjectPaths))\n\tj := 0\n\tvar injectWaitGroup sync.WaitGroup\n\tfor _, resolveResult := range injectResolveResults {\n\t\tif resolveResult != nil {\n\t\t\tchannel := make(chan config.InjectedFile, 1)\n\t\t\ts.maybeParseFile(*resolveResult, resolver.MakePrettyPaths(s.fs, resolveResult.PathPair.Primary), nil, logger.Range{}, nil, inputKindNormal, channel)\n\t\t\tinjectWaitGroup.Add(1)\n\n\t\t\t// Wait for the results in parallel. The results slice is large enough so\n\t\t\t// it is not reallocated during the computations.\n\t\t\tgo func(i int) {\n\t\t\t\tresults[i] = <-channel\n\t\t\t\tinjectWaitGroup.Done()\n\t\t\t}(j)\n\t\t\tj++\n\t\t}\n\t}\n\tinjectWaitGroup.Wait()\n\tinjectedFiles = append(injectedFiles, results[:j]...)\n\n\t// It's safe to mutate the options object to add the injected files here\n\t// because there aren't any concurrent \"parseFile\" goroutines at this point.\n\t// The only ones that were created by this point are the ones we created\n\t// above, and we've already waited for all of them to finish using the\n\t// \"options\" object.\n\ts.options.InjectedFiles = injectedFiles\n}\n\nfunc (s *scanner) addEntryPoints(entryPoints []EntryPoint) []graph.EntryPoint {\n\ts.timer.Begin(\"Add entry points\")\n\tdefer s.timer.End(\"Add entry points\")\n\n\t// Reserve a slot for each entry point\n\tentryMetas := make([]graph.EntryPoint, 0, len(entryPoints)+1)\n\n\t// Treat stdin as an extra entry point\n\tif stdin := s.options.Stdin; stdin != nil {\n\t\tstdinPath := logger.Path{Text: \"<stdin>\"}\n\t\tif stdin.SourceFile != \"\" {\n\t\t\tif stdin.AbsResolveDir == \"\" {\n\t\t\t\tstdinPath = logger.Path{Text: stdin.SourceFile}\n\t\t\t} else if s.fs.IsAbs(stdin.SourceFile) {\n\t\t\t\tstdinPath = logger.Path{Text: stdin.SourceFile, Namespace: \"file\"}\n\t\t\t} else {\n\t\t\t\tstdinPath = logger.Path{Text: s.fs.Join(stdin.AbsResolveDir, stdin.SourceFile), Namespace: \"file\"}\n\t\t\t}\n\t\t}\n\t\tresolveResult := resolver.ResolveResult{PathPair: resolver.PathPair{Primary: stdinPath}}\n\t\tsourceIndex := s.maybeParseFile(resolveResult, resolver.MakePrettyPaths(s.fs, stdinPath), nil, logger.Range{}, nil, inputKindStdin, nil)\n\t\tentryMetas = append(entryMetas, graph.EntryPoint{\n\t\t\tOutputPath:  \"stdin\",\n\t\t\tSourceIndex: sourceIndex,\n\t\t})\n\t}\n\n\tif s.options.CancelFlag.DidCancel() {\n\t\treturn nil\n\t}\n\n\t// Check each entry point ahead of time to see if it's a real file\n\tentryPointAbsResolveDir := s.fs.Cwd()\n\tfor i := range entryPoints {\n\t\tentryPoint := &entryPoints[i]\n\t\tabsPath := entryPoint.InputPath\n\t\tif strings.ContainsRune(absPath, '*') {\n\t\t\tcontinue // Ignore glob patterns\n\t\t}\n\t\tif !s.fs.IsAbs(absPath) {\n\t\t\tabsPath = s.fs.Join(entryPointAbsResolveDir, absPath)\n\t\t}\n\t\tdir := s.fs.Dir(absPath)\n\t\tbase := s.fs.Base(absPath)\n\t\tif entries, err, originalError := s.fs.ReadDirectory(dir); err == nil {\n\t\t\tif entry, _ := entries.Get(base); entry != nil && entry.Kind(s.fs) == fs.FileEntry {\n\t\t\t\tentryPoint.InputPathInFileNamespace = true\n\n\t\t\t\t// Entry point paths without a leading \"./\" are interpreted as package\n\t\t\t\t// paths. This happens because they go through general path resolution\n\t\t\t\t// like all other import paths so that plugins can run on them. Requiring\n\t\t\t\t// a leading \"./\" for a relative path simplifies writing plugins because\n\t\t\t\t// entry points aren't a special case.\n\t\t\t\t//\n\t\t\t\t// However, requiring a leading \"./\" also breaks backward compatibility\n\t\t\t\t// and makes working with the CLI more difficult. So attempt to insert\n\t\t\t\t// \"./\" automatically when needed. We don't want to unconditionally insert\n\t\t\t\t// a leading \"./\" because the path may not be a file system path. For\n\t\t\t\t// example, it may be a URL. So only insert a leading \"./\" when the path\n\t\t\t\t// is an exact match for an existing file.\n\t\t\t\tif !s.fs.IsAbs(entryPoint.InputPath) && resolver.IsPackagePath(entryPoint.InputPath) {\n\t\t\t\t\tentryPoint.InputPath = \"./\" + entryPoint.InputPath\n\t\t\t\t}\n\t\t\t}\n\t\t} else if s.log.Level <= logger.LevelDebug && originalError != nil {\n\t\t\ts.log.AddID(logger.MsgID_None, logger.Debug, nil, logger.Range{}, fmt.Sprintf(\"Failed to read directory %q: %s\", absPath, originalError.Error()))\n\t\t}\n\t}\n\n\tif s.options.CancelFlag.DidCancel() {\n\t\treturn nil\n\t}\n\n\t// Add any remaining entry points. Run resolver plugins on these entry points\n\t// so plugins can alter where they resolve to. These are run in parallel in\n\t// case any of these plugins block.\n\ttype entryPointInfo struct {\n\t\tresults []resolver.ResolveResult\n\t\tisGlob  bool\n\t}\n\tentryPointInfos := make([]entryPointInfo, len(entryPoints))\n\tentryPointWaitGroup := sync.WaitGroup{}\n\tentryPointWaitGroup.Add(len(entryPoints))\n\tfor i, entryPoint := range entryPoints {\n\t\tgo func(i int, entryPoint EntryPoint) {\n\t\t\tvar importer logger.Path\n\t\t\tif entryPoint.InputPathInFileNamespace {\n\t\t\t\timporter.Namespace = \"file\"\n\t\t\t}\n\n\t\t\t// Special-case glob patterns here\n\t\t\tif strings.ContainsRune(entryPoint.InputPath, '*') {\n\t\t\t\tif pattern := helpers.ParseGlobPattern(entryPoint.InputPath); len(pattern) > 1 {\n\t\t\t\t\tprettyPattern := fmt.Sprintf(\"%q\", entryPoint.InputPath)\n\t\t\t\t\tif results, msg := s.res.ResolveGlob(entryPointAbsResolveDir, pattern, ast.ImportEntryPoint, prettyPattern); results != nil {\n\t\t\t\t\t\tkeys := make([]string, 0, len(results))\n\t\t\t\t\t\tfor key := range results {\n\t\t\t\t\t\t\tkeys = append(keys, key)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsort.Strings(keys)\n\t\t\t\t\t\tinfo := entryPointInfo{isGlob: true}\n\t\t\t\t\t\tfor _, key := range keys {\n\t\t\t\t\t\t\tinfo.results = append(info.results, results[key])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tentryPointInfos[i] = info\n\t\t\t\t\t\tif msg != nil {\n\t\t\t\t\t\t\ts.log.AddID(msg.ID, msg.Kind, nil, logger.Range{}, msg.Data.Text)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\ts.log.AddError(nil, logger.Range{}, fmt.Sprintf(\"Could not resolve %q\", entryPoint.InputPath))\n\t\t\t\t\t}\n\t\t\t\t\tentryPointWaitGroup.Done()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Run the resolver and log an error if the path couldn't be resolved\n\t\t\tresolveResult, didLogError, debug := RunOnResolvePlugins(\n\t\t\t\ts.options.Plugins,\n\t\t\t\ts.res,\n\t\t\t\ts.log,\n\t\t\t\ts.fs,\n\t\t\t\t&s.caches.FSCache,\n\t\t\t\tnil,\n\t\t\t\tlogger.Range{},\n\t\t\t\timporter,\n\t\t\t\tentryPoint.InputPath,\n\t\t\t\tlogger.ImportAttributes{},\n\t\t\t\tast.ImportEntryPoint,\n\t\t\t\tentryPointAbsResolveDir,\n\t\t\t\tnil,\n\t\t\t\ts.options.LogPathStyle,\n\t\t\t)\n\t\t\tif resolveResult != nil {\n\t\t\t\tif resolveResult.PathPair.IsExternal {\n\t\t\t\t\ts.log.AddError(nil, logger.Range{}, fmt.Sprintf(\"The entry point %q cannot be marked as external\", entryPoint.InputPath))\n\t\t\t\t} else {\n\t\t\t\t\tentryPointInfos[i] = entryPointInfo{results: []resolver.ResolveResult{*resolveResult}}\n\t\t\t\t}\n\t\t\t} else if !didLogError {\n\t\t\t\tvar notes []logger.MsgData\n\t\t\t\tif !s.fs.IsAbs(entryPoint.InputPath) {\n\t\t\t\t\tif query, _ := s.res.ProbeResolvePackageAsRelative(entryPointAbsResolveDir, entryPoint.InputPath, ast.ImportEntryPoint); query != nil {\n\t\t\t\t\t\tprettyPaths := resolver.MakePrettyPaths(s.fs, query.PathPair.Primary)\n\t\t\t\t\t\tnotes = append(notes, logger.MsgData{\n\t\t\t\t\t\t\tText: fmt.Sprintf(\"Use the relative path %q to reference the file %q. \"+\n\t\t\t\t\t\t\t\t\"Without the leading \\\"./\\\", the path %q is being interpreted as a package path instead.\",\n\t\t\t\t\t\t\t\t\"./\"+entryPoint.InputPath, prettyPaths.Select(s.options.LogPathStyle), entryPoint.InputPath),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdebug.LogErrorMsg(s.log, nil, logger.Range{}, fmt.Sprintf(\"Could not resolve %q\", entryPoint.InputPath), \"\", notes)\n\t\t\t}\n\t\t\tentryPointWaitGroup.Done()\n\t\t}(i, entryPoint)\n\t}\n\tentryPointWaitGroup.Wait()\n\n\tif s.options.CancelFlag.DidCancel() {\n\t\treturn nil\n\t}\n\n\t// Determine output paths for all entry points that were resolved successfully\n\ttype entryPointToParse struct {\n\t\tindex int\n\t\tparse func() uint32\n\t}\n\tvar entryPointsToParse []entryPointToParse\n\tfor i, info := range entryPointInfos {\n\t\tif info.results == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, resolveResult := range info.results {\n\t\t\tresolveResult := resolveResult\n\t\t\tprettyPaths := resolver.MakePrettyPaths(s.fs, resolveResult.PathPair.Primary)\n\t\t\toutputPath := entryPoints[i].OutputPath\n\t\t\toutputPathWasAutoGenerated := false\n\n\t\t\t// If the output path is missing, automatically generate one from the input path\n\t\t\tif outputPath == \"\" {\n\t\t\t\tif info.isGlob {\n\t\t\t\t\toutputPath = prettyPaths.Rel\n\t\t\t\t} else {\n\t\t\t\t\toutputPath = entryPoints[i].InputPath\n\t\t\t\t}\n\t\t\t\twindowsVolumeLabel := \"\"\n\n\t\t\t\t// The \":\" character is invalid in file paths on Windows except when\n\t\t\t\t// it's used as a volume separator. Special-case that here so volume\n\t\t\t\t// labels don't break on Windows.\n\t\t\t\tif s.fs.IsAbs(outputPath) && len(outputPath) >= 3 && outputPath[1] == ':' {\n\t\t\t\t\tif c := outputPath[0]; (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') {\n\t\t\t\t\t\tif c := outputPath[2]; c == '/' || c == '\\\\' {\n\t\t\t\t\t\t\twindowsVolumeLabel = outputPath[:3]\n\t\t\t\t\t\t\toutputPath = outputPath[3:]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// For cross-platform robustness, do not allow characters in the output\n\t\t\t\t// path that are invalid on Windows. This is especially relevant when\n\t\t\t\t// the input path is something other than a file path, such as a URL.\n\t\t\t\toutputPath = sanitizeFilePathForVirtualModulePath(outputPath)\n\t\t\t\tif windowsVolumeLabel != \"\" {\n\t\t\t\t\toutputPath = windowsVolumeLabel + outputPath\n\t\t\t\t}\n\t\t\t\toutputPathWasAutoGenerated = true\n\t\t\t}\n\n\t\t\t// Defer parsing for this entry point until later\n\t\t\tentryPointsToParse = append(entryPointsToParse, entryPointToParse{\n\t\t\t\tindex: len(entryMetas),\n\t\t\t\tparse: func() uint32 {\n\t\t\t\t\treturn s.maybeParseFile(resolveResult, prettyPaths, nil, logger.Range{}, nil, inputKindEntryPoint, nil)\n\t\t\t\t},\n\t\t\t})\n\n\t\t\tentryMetas = append(entryMetas, graph.EntryPoint{\n\t\t\t\tOutputPath:                 outputPath,\n\t\t\t\tSourceIndex:                ast.InvalidRef.SourceIndex,\n\t\t\t\tOutputPathWasAutoGenerated: outputPathWasAutoGenerated,\n\t\t\t})\n\t\t}\n\t}\n\n\t// Turn all automatically-generated output paths into absolute paths\n\tfor i := range entryMetas {\n\t\tentryPoint := &entryMetas[i]\n\t\tif entryPoint.OutputPathWasAutoGenerated && !s.fs.IsAbs(entryPoint.OutputPath) {\n\t\t\tentryPoint.OutputPath = s.fs.Join(entryPointAbsResolveDir, entryPoint.OutputPath)\n\t\t}\n\t}\n\n\t// Automatically compute \"outbase\" if it wasn't provided\n\tif s.options.AbsOutputBase == \"\" {\n\t\ts.options.AbsOutputBase = lowestCommonAncestorDirectory(s.fs, entryMetas)\n\t\tif s.options.AbsOutputBase == \"\" {\n\t\t\ts.options.AbsOutputBase = entryPointAbsResolveDir\n\t\t}\n\t}\n\n\t// Only parse entry points after \"AbsOutputBase\" has been determined\n\tfor _, toParse := range entryPointsToParse {\n\t\tentryMetas[toParse.index].SourceIndex = toParse.parse()\n\t}\n\n\t// Turn all output paths back into relative paths, but this time relative to\n\t// the \"outbase\" value we computed above\n\tfor i := range entryMetas {\n\t\tentryPoint := &entryMetas[i]\n\t\tif s.fs.IsAbs(entryPoint.OutputPath) {\n\t\t\tif !entryPoint.OutputPathWasAutoGenerated {\n\t\t\t\t// If an explicit absolute output path was specified, use the path\n\t\t\t\t// relative to the \"outdir\" directory\n\t\t\t\tif relPath, ok := s.fs.Rel(s.options.AbsOutputDir, entryPoint.OutputPath); ok {\n\t\t\t\t\tentryPoint.OutputPath = relPath\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Otherwise if the absolute output path was derived from the input\n\t\t\t\t// path, use the path relative to the \"outbase\" directory\n\t\t\t\tif relPath, ok := s.fs.Rel(s.options.AbsOutputBase, entryPoint.OutputPath); ok {\n\t\t\t\t\tentryPoint.OutputPath = relPath\n\t\t\t\t}\n\n\t\t\t\t// Strip the file extension from the output path if there is one so the\n\t\t\t\t// \"out extension\" setting is used instead\n\t\t\t\tif last := strings.LastIndexAny(entryPoint.OutputPath, \"/.\\\\\"); last != -1 && entryPoint.OutputPath[last] == '.' {\n\t\t\t\t\tentryPoint.OutputPath = entryPoint.OutputPath[:last]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn entryMetas\n}\n\nfunc lowestCommonAncestorDirectory(fs fs.FS, entryPoints []graph.EntryPoint) string {\n\t// Ignore any explicitly-specified output paths\n\tabsPaths := make([]string, 0, len(entryPoints))\n\tfor _, entryPoint := range entryPoints {\n\t\tif entryPoint.OutputPathWasAutoGenerated {\n\t\t\tabsPaths = append(absPaths, entryPoint.OutputPath)\n\t\t}\n\t}\n\n\tif len(absPaths) == 0 {\n\t\treturn \"\"\n\t}\n\n\tlowestAbsDir := fs.Dir(absPaths[0])\n\n\tfor _, absPath := range absPaths[1:] {\n\t\tabsDir := fs.Dir(absPath)\n\t\tlastSlash := 0\n\t\ta := 0\n\t\tb := 0\n\n\t\tfor {\n\t\t\truneA, widthA := utf8.DecodeRuneInString(absDir[a:])\n\t\t\truneB, widthB := utf8.DecodeRuneInString(lowestAbsDir[b:])\n\t\t\tboundaryA := widthA == 0 || runeA == '/' || runeA == '\\\\'\n\t\t\tboundaryB := widthB == 0 || runeB == '/' || runeB == '\\\\'\n\n\t\t\tif boundaryA && boundaryB {\n\t\t\t\tif widthA == 0 || widthB == 0 {\n\t\t\t\t\t// Truncate to the smaller path if one path is a prefix of the other\n\t\t\t\t\tlowestAbsDir = absDir[:a]\n\t\t\t\t\tbreak\n\t\t\t\t} else {\n\t\t\t\t\t// Track the longest common directory so far\n\t\t\t\t\tlastSlash = a\n\t\t\t\t}\n\t\t\t} else if boundaryA != boundaryB || unicode.ToLower(runeA) != unicode.ToLower(runeB) {\n\t\t\t\t// If we're at the top-level directory, then keep the slash\n\t\t\t\tif lastSlash < len(absDir) && !strings.ContainsAny(absDir[:lastSlash], \"\\\\/\") {\n\t\t\t\t\tlastSlash++\n\t\t\t\t}\n\n\t\t\t\t// If both paths are different at this point, stop and set the lowest so\n\t\t\t\t// far to the common parent directory. Compare using a case-insensitive\n\t\t\t\t// comparison to handle paths on Windows.\n\t\t\t\tlowestAbsDir = absDir[:lastSlash]\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\ta += widthA\n\t\t\tb += widthB\n\t\t}\n\t}\n\n\treturn lowestAbsDir\n}\n\nfunc (s *scanner) scanAllDependencies() {\n\ts.timer.Begin(\"Scan all dependencies\")\n\tdefer s.timer.End(\"Scan all dependencies\")\n\n\t// Continue scanning until all dependencies have been discovered\n\tfor s.remaining > 0 {\n\t\tif s.options.CancelFlag.DidCancel() {\n\t\t\treturn\n\t\t}\n\n\t\tresult := <-s.resultChannel\n\t\ts.remaining--\n\t\tif !result.ok {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Don't try to resolve paths if we're not bundling\n\t\tif recordsPtr := result.file.inputFile.Repr.ImportRecords(); s.options.Mode == config.ModeBundle && recordsPtr != nil {\n\t\t\trecords := *recordsPtr\n\t\t\tfor importRecordIndex := range records {\n\t\t\t\trecord := &records[importRecordIndex]\n\n\t\t\t\t// This is used for error messages\n\t\t\t\tvar with *ast.ImportAssertOrWith\n\t\t\t\tif record.AssertOrWith != nil && record.AssertOrWith.Keyword == ast.WithKeyword {\n\t\t\t\t\twith = record.AssertOrWith\n\t\t\t\t}\n\n\t\t\t\t// Skip this import record if the previous resolver call failed\n\t\t\t\tresolveResult := result.resolveResults[importRecordIndex]\n\t\t\t\tif resolveResult == nil {\n\t\t\t\t\tif globResults := result.globResolveResults[uint32(importRecordIndex)]; globResults.resolveResults != nil {\n\t\t\t\t\t\tsourceIndex := s.allocateGlobSourceIndex(result.file.inputFile.Source.Index, uint32(importRecordIndex))\n\t\t\t\t\t\trecord.SourceIndex = ast.MakeIndex32(sourceIndex)\n\t\t\t\t\t\ts.results[sourceIndex] = s.generateResultForGlobResolve(sourceIndex, globResults.absPath,\n\t\t\t\t\t\t\t&result.file.inputFile.Source, record.Range, with, record.GlobPattern.Kind, record.Phase, globResults, record.AssertOrWith)\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tpath := resolveResult.PathPair.Primary\n\t\t\t\tif !resolveResult.PathPair.IsExternal {\n\t\t\t\t\t// Handle a path within the bundle\n\t\t\t\t\tsourceIndex := s.maybeParseFile(*resolveResult, resolver.MakePrettyPaths(s.fs, path),\n\t\t\t\t\t\t&result.file.inputFile.Source, record.Range, with, inputKindNormal, nil)\n\t\t\t\t\trecord.SourceIndex = ast.MakeIndex32(sourceIndex)\n\t\t\t\t} else {\n\t\t\t\t\t// Allow this import statement to be removed if something marked it as \"sideEffects: false\"\n\t\t\t\t\tif resolveResult.PrimarySideEffectsData != nil {\n\t\t\t\t\t\trecord.Flags |= ast.IsExternalWithoutSideEffects\n\t\t\t\t\t}\n\n\t\t\t\t\t// If the path to the external module is relative to the source\n\t\t\t\t\t// file, rewrite the path to be relative to the working directory\n\t\t\t\t\tif path.Namespace == \"file\" {\n\t\t\t\t\t\tif relPath, ok := s.fs.Rel(s.options.AbsOutputDir, path.Text); ok {\n\t\t\t\t\t\t\t// Prevent issues with path separators being different on Windows\n\t\t\t\t\t\t\trelPath = strings.ReplaceAll(relPath, \"\\\\\", \"/\")\n\t\t\t\t\t\t\tif resolver.IsPackagePath(relPath) {\n\t\t\t\t\t\t\t\trelPath = \"./\" + relPath\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\trecord.Path.Text = relPath\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\trecord.Path = path\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\trecord.Path = path\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ts.results[result.file.inputFile.Source.Index] = result\n\t}\n}\n\nfunc (s *scanner) generateResultForGlobResolve(\n\tsourceIndex uint32,\n\tfakeSourcePath string,\n\timportSource *logger.Source,\n\timportRange logger.Range,\n\timportWith *ast.ImportAssertOrWith,\n\tkind ast.ImportKind,\n\tphase ast.ImportPhase,\n\tresult globResolveResult,\n\tassertions *ast.ImportAssertOrWith,\n) parseResult {\n\tkeys := make([]string, 0, len(result.resolveResults))\n\tfor key := range result.resolveResults {\n\t\tkeys = append(keys, key)\n\t}\n\tsort.Strings(keys)\n\n\tobject := js_ast.EObject{Properties: make([]js_ast.Property, 0, len(result.resolveResults))}\n\timportRecords := make([]ast.ImportRecord, 0, len(result.resolveResults))\n\tresolveResults := make([]*resolver.ResolveResult, 0, len(result.resolveResults))\n\n\tfor _, key := range keys {\n\t\tresolveResult := result.resolveResults[key]\n\t\tvar value js_ast.Expr\n\n\t\timportRecordIndex := uint32(len(importRecords))\n\t\tvar sourceIndex ast.Index32\n\n\t\tif !resolveResult.PathPair.IsExternal {\n\t\t\tsourceIndex = ast.MakeIndex32(s.maybeParseFile(\n\t\t\t\tresolveResult,\n\t\t\t\tresolver.MakePrettyPaths(s.fs, resolveResult.PathPair.Primary),\n\t\t\t\timportSource,\n\t\t\t\timportRange,\n\t\t\t\timportWith,\n\t\t\t\tinputKindNormal,\n\t\t\t\tnil,\n\t\t\t))\n\t\t}\n\n\t\tpath := resolveResult.PathPair.Primary\n\n\t\t// If the path to the external module is relative to the source\n\t\t// file, rewrite the path to be relative to the working directory\n\t\tif path.Namespace == \"file\" {\n\t\t\tif relPath, ok := s.fs.Rel(s.options.AbsOutputDir, path.Text); ok {\n\t\t\t\t// Prevent issues with path separators being different on Windows\n\t\t\t\trelPath = strings.ReplaceAll(relPath, \"\\\\\", \"/\")\n\t\t\t\tif resolver.IsPackagePath(relPath) {\n\t\t\t\t\trelPath = \"./\" + relPath\n\t\t\t\t}\n\t\t\t\tpath.Text = relPath\n\t\t\t}\n\t\t}\n\n\t\tresolveResults = append(resolveResults, &resolveResult)\n\t\timportRecords = append(importRecords, ast.ImportRecord{\n\t\t\tPath:         path,\n\t\t\tSourceIndex:  sourceIndex,\n\t\t\tAssertOrWith: assertions,\n\t\t\tKind:         kind,\n\t\t\tPhase:        phase,\n\t\t})\n\n\t\tswitch kind {\n\t\tcase ast.ImportDynamic:\n\t\t\tvalue.Data = &js_ast.EImportString{ImportRecordIndex: importRecordIndex}\n\t\tcase ast.ImportRequire:\n\t\t\tvalue.Data = &js_ast.ERequireString{ImportRecordIndex: importRecordIndex}\n\t\tdefault:\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\n\t\tobject.Properties = append(object.Properties, js_ast.Property{\n\t\t\tKey: js_ast.Expr{Data: &js_ast.EString{Value: helpers.StringToUTF16(key)}},\n\t\t\tValueOrNil: js_ast.Expr{Data: &js_ast.EArrow{\n\t\t\t\tBody:       js_ast.FnBody{Block: js_ast.SBlock{Stmts: []js_ast.Stmt{{Data: &js_ast.SReturn{ValueOrNil: value}}}}},\n\t\t\t\tPreferExpr: true,\n\t\t\t}},\n\t\t})\n\t}\n\n\tsource := logger.Source{\n\t\tKeyPath:     logger.Path{Text: fakeSourcePath, Namespace: \"file\"},\n\t\tPrettyPaths: result.prettyPaths,\n\t\tIndex:       sourceIndex,\n\t}\n\tast := js_parser.GlobResolveAST(s.log, source, importRecords, &object, result.exportAlias)\n\n\t// Fill out \"nil\" for any additional imports (i.e. from the runtime)\n\tfor len(resolveResults) < len(ast.ImportRecords) {\n\t\tresolveResults = append(resolveResults, nil)\n\t}\n\n\treturn parseResult{\n\t\tresolveResults: resolveResults,\n\t\tfile: scannerFile{\n\t\t\tinputFile: graph.InputFile{\n\t\t\t\tSource: source,\n\t\t\t\tRepr: &graph.JSRepr{\n\t\t\t\t\tAST: ast,\n\t\t\t\t},\n\t\t\t\tOmitFromSourceMapsAndMetafile: true,\n\t\t\t},\n\t\t},\n\t\tok: true,\n\t}\n}\n\nfunc (s *scanner) processScannedFiles(entryPointMeta []graph.EntryPoint) []scannerFile {\n\ts.timer.Begin(\"Process scanned files\")\n\tdefer s.timer.End(\"Process scanned files\")\n\n\t// Build a set of entry point source indices for quick lookup\n\tentryPointSourceIndexToMetaIndex := make(map[uint32]uint32, len(entryPointMeta))\n\tfor i, meta := range entryPointMeta {\n\t\tentryPointSourceIndexToMetaIndex[meta.SourceIndex] = uint32(i)\n\t}\n\n\t// Check for pretty-printed path collisions\n\timportAttributeNameCollisions := make(map[logger.PrettyPaths][]uint32)\n\tfor sourceIndex := range s.results {\n\t\tif result := &s.results[sourceIndex]; result.ok {\n\t\t\tprettyPaths := result.file.inputFile.Source.PrettyPaths\n\t\t\timportAttributeNameCollisions[prettyPaths] = append(importAttributeNameCollisions[prettyPaths], uint32(sourceIndex))\n\t\t}\n\t}\n\n\t// Import attributes can result in the same file being imported multiple\n\t// times in different ways. If that happens, append the import attributes\n\t// to the pretty-printed file names to disambiguate them. This renaming\n\t// must happen before we construct the metafile JSON chunks below.\n\tfor _, sourceIndices := range importAttributeNameCollisions {\n\t\tif len(sourceIndices) == 1 {\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, sourceIndex := range sourceIndices {\n\t\t\tsource := &s.results[sourceIndex].file.inputFile.Source\n\t\t\tattrs := source.KeyPath.ImportAttributes.DecodeIntoArray()\n\t\t\tif len(attrs) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tvar sb strings.Builder\n\t\t\tsb.WriteString(\" with {\")\n\t\t\tfor i, attr := range attrs {\n\t\t\t\tif i > 0 {\n\t\t\t\t\tsb.WriteByte(',')\n\t\t\t\t}\n\t\t\t\tsb.WriteByte(' ')\n\t\t\t\tif js_ast.IsIdentifier(attr.Key) {\n\t\t\t\t\tsb.WriteString(attr.Key)\n\t\t\t\t} else {\n\t\t\t\t\tsb.Write(helpers.QuoteSingle(attr.Key, false))\n\t\t\t\t}\n\t\t\t\tsb.WriteString(\": \")\n\t\t\t\tsb.Write(helpers.QuoteSingle(attr.Value, false))\n\t\t\t}\n\t\t\tsb.WriteString(\" }\")\n\t\t\tsuffix := sb.String()\n\t\t\tsource.PrettyPaths.Abs += suffix\n\t\t\tsource.PrettyPaths.Rel += suffix\n\t\t}\n\t}\n\n\t// Automatically minify the metafile JSON if the bundle is really big\n\tif len(s.results) > 256 {\n\t\ts.options.MetafileFormat = config.MinifiedMetafile\n\t}\n\n\t// Now that all files have been scanned, process the final file import records\n\tfor sourceIndex, result := range s.results {\n\t\tif !result.ok {\n\t\t\tcontinue\n\t\t}\n\n\t\tsb := strings.Builder{}\n\t\tisFirstImport := true\n\n\t\t// Begin the metadata chunk\n\t\tif s.options.NeedsMetafile {\n\t\t\tsb.Write(helpers.QuoteForJSON(result.file.inputFile.Source.PrettyPaths.Select(s.options.MetafilePathStyle), s.options.ASCIIOnly))\n\t\t\tsb.WriteString(fmt.Sprintf(\n\t\t\t\ts.options.MetafileFormat.MaybeRemoveWhitespace(\": {\\n      \\\"bytes\\\": %d,\\n      \\\"imports\\\": [\"),\n\t\t\t\tlen(result.file.inputFile.Source.Contents)))\n\t\t}\n\n\t\t// Don't try to resolve paths if we're not bundling\n\t\tif recordsPtr := result.file.inputFile.Repr.ImportRecords(); s.options.Mode == config.ModeBundle && recordsPtr != nil {\n\t\t\trecords := *recordsPtr\n\t\t\ttracker := logger.MakeLineColumnTracker(&result.file.inputFile.Source)\n\n\t\t\tfor importRecordIndex := range records {\n\t\t\t\trecord := &records[importRecordIndex]\n\n\t\t\t\t// Save the import attributes to the metafile\n\t\t\t\tvar metafileWith string\n\t\t\t\tif s.options.NeedsMetafile {\n\t\t\t\t\tif with := record.AssertOrWith; with != nil && with.Keyword == ast.WithKeyword && len(with.Entries) > 0 {\n\t\t\t\t\t\tdata := strings.Builder{}\n\t\t\t\t\t\tdata.WriteString(s.options.MetafileFormat.MaybeRemoveWhitespace(\",\\n          \\\"with\\\": {\"))\n\t\t\t\t\t\tfor i, entry := range with.Entries {\n\t\t\t\t\t\t\tif i > 0 {\n\t\t\t\t\t\t\t\tdata.WriteByte(',')\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tdata.WriteString(s.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n            \"))\n\t\t\t\t\t\t\tdata.Write(helpers.QuoteForJSON(helpers.UTF16ToString(entry.Key), s.options.ASCIIOnly))\n\t\t\t\t\t\t\tdata.WriteString(s.options.MetafileFormat.MaybeRemoveWhitespace(\": \"))\n\t\t\t\t\t\t\tdata.Write(helpers.QuoteForJSON(helpers.UTF16ToString(entry.Value), s.options.ASCIIOnly))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdata.WriteString(s.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n          }\"))\n\t\t\t\t\t\tmetafileWith = data.String()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Skip this import record if the previous resolver call failed\n\t\t\t\tresolveResult := result.resolveResults[importRecordIndex]\n\t\t\t\tif resolveResult == nil || !record.SourceIndex.IsValid() {\n\t\t\t\t\tif s.options.NeedsMetafile {\n\t\t\t\t\t\tif isFirstImport {\n\t\t\t\t\t\t\tisFirstImport = false\n\t\t\t\t\t\t\tsb.WriteString(s.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n        \"))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsb.WriteString(s.options.MetafileFormat.MaybeRemoveWhitespace(\",\\n        \"))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsb.WriteString(fmt.Sprintf(\n\t\t\t\t\t\t\ts.options.MetafileFormat.MaybeRemoveWhitespace(\"{\\n          \\\"path\\\": %s,\\n          \\\"kind\\\": %s,\\n          \\\"external\\\": true%s\\n        }\"),\n\t\t\t\t\t\t\thelpers.QuoteForJSON(record.Path.Text, s.options.ASCIIOnly),\n\t\t\t\t\t\t\thelpers.QuoteForJSON(record.Kind.StringForMetafile(), s.options.ASCIIOnly),\n\t\t\t\t\t\t\tmetafileWith))\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Now that all files have been scanned, look for packages that are imported\n\t\t\t\t// both with \"import\" and \"require\". Rewrite any imports that reference the\n\t\t\t\t// \"module\" package.json field to the \"main\" package.json field instead.\n\t\t\t\t//\n\t\t\t\t// This attempts to automatically avoid the \"dual package hazard\" where a\n\t\t\t\t// package has both a CommonJS module version and an ECMAScript module\n\t\t\t\t// version and exports a non-object in CommonJS (often a function). If we\n\t\t\t\t// pick the \"module\" field and the package is imported with \"require\" then\n\t\t\t\t// code expecting a function will crash.\n\t\t\t\tif resolveResult.PathPair.HasSecondary() {\n\t\t\t\t\tsecondaryKey := resolveResult.PathPair.Secondary\n\t\t\t\t\tif secondaryKey.Namespace == \"file\" {\n\t\t\t\t\t\tsecondaryKey.Text = canonicalFileSystemPathForWindows(secondaryKey.Text)\n\t\t\t\t\t}\n\t\t\t\t\tif secondaryVisited, ok := s.visited[secondaryKey]; ok {\n\t\t\t\t\t\trecord.SourceIndex = ast.MakeIndex32(secondaryVisited.sourceIndex)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Generate metadata about each import\n\t\t\t\totherResult := &s.results[record.SourceIndex.GetIndex()]\n\t\t\t\totherFile := &otherResult.file\n\t\t\t\tif s.options.NeedsMetafile {\n\t\t\t\t\tif isFirstImport {\n\t\t\t\t\t\tisFirstImport = false\n\t\t\t\t\t\tsb.WriteString(s.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n        \"))\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsb.WriteString(s.options.MetafileFormat.MaybeRemoveWhitespace(\",\\n        \"))\n\t\t\t\t\t}\n\t\t\t\t\tsb.WriteString(fmt.Sprintf(\n\t\t\t\t\t\ts.options.MetafileFormat.MaybeRemoveWhitespace(\"{\\n          \\\"path\\\": %s,\\n          \\\"kind\\\": %s,\\n          \\\"original\\\": %s%s\\n        }\"),\n\t\t\t\t\t\thelpers.QuoteForJSON(otherFile.inputFile.Source.PrettyPaths.Select(s.options.MetafilePathStyle), s.options.ASCIIOnly),\n\t\t\t\t\t\thelpers.QuoteForJSON(record.Kind.StringForMetafile(), s.options.ASCIIOnly),\n\t\t\t\t\t\thelpers.QuoteForJSON(record.Path.Text, s.options.ASCIIOnly),\n\t\t\t\t\t\tmetafileWith))\n\t\t\t\t}\n\n\t\t\t\t// Validate that imports with \"assert { type: 'json' }\" were imported\n\t\t\t\t// with the JSON loader. This is done to match the behavior of these\n\t\t\t\t// import assertions in a real JavaScript runtime. In addition, we also\n\t\t\t\t// allow the copy loader since this is sort of like marking the path\n\t\t\t\t// as external (the import assertions are kept and the real JavaScript\n\t\t\t\t// runtime evaluates them, not us).\n\t\t\t\tif record.Flags.Has(ast.AssertTypeJSON) && otherResult.ok && otherFile.inputFile.Loader != config.LoaderJSON && otherFile.inputFile.Loader != config.LoaderCopy {\n\t\t\t\t\ts.log.AddErrorWithNotes(&tracker, record.Range,\n\t\t\t\t\t\tfmt.Sprintf(\"The file %q was loaded with the %q loader\",\n\t\t\t\t\t\t\totherFile.inputFile.Source.PrettyPaths.Select(s.options.LogPathStyle),\n\t\t\t\t\t\t\tconfig.LoaderToString[otherFile.inputFile.Loader]),\n\t\t\t\t\t\t[]logger.MsgData{\n\t\t\t\t\t\t\ttracker.MsgData(js_lexer.RangeOfImportAssertOrWith(result.file.inputFile.Source,\n\t\t\t\t\t\t\t\t*ast.FindAssertOrWithEntry(record.AssertOrWith.Entries, \"type\"), js_lexer.KeyAndValueRange),\n\t\t\t\t\t\t\t\t\"This import assertion requires the loader to be \\\"json\\\" instead:\"),\n\t\t\t\t\t\t\t{Text: \"You need to either reconfigure esbuild to ensure that the loader for this file is \\\"json\\\" or you need to remove this import assertion.\"}})\n\t\t\t\t}\n\n\t\t\t\tswitch record.Kind {\n\t\t\t\tcase ast.ImportComposesFrom:\n\t\t\t\t\t// Using a JavaScript file with CSS \"composes\" is not allowed\n\t\t\t\t\tif _, ok := otherFile.inputFile.Repr.(*graph.JSRepr); ok && otherFile.inputFile.Loader != config.LoaderEmpty {\n\t\t\t\t\t\ts.log.AddErrorWithNotes(&tracker, record.Range,\n\t\t\t\t\t\t\tfmt.Sprintf(\"Cannot use \\\"composes\\\" with %q\",\n\t\t\t\t\t\t\t\totherFile.inputFile.Source.PrettyPaths.Select(s.options.LogPathStyle)),\n\t\t\t\t\t\t\t[]logger.MsgData{{Text: fmt.Sprintf(\n\t\t\t\t\t\t\t\t\"You can only use \\\"composes\\\" with CSS files and %q is not a CSS file (it was loaded with the %q loader).\",\n\t\t\t\t\t\t\t\totherFile.inputFile.Source.PrettyPaths.Select(s.options.LogPathStyle),\n\t\t\t\t\t\t\t\tconfig.LoaderToString[otherFile.inputFile.Loader])}})\n\t\t\t\t\t}\n\n\t\t\t\tcase ast.ImportAt:\n\t\t\t\t\t// Using a JavaScript file with CSS \"@import\" is not allowed\n\t\t\t\t\tif _, ok := otherFile.inputFile.Repr.(*graph.JSRepr); ok && otherFile.inputFile.Loader != config.LoaderEmpty {\n\t\t\t\t\t\ts.log.AddErrorWithNotes(&tracker, record.Range,\n\t\t\t\t\t\t\tfmt.Sprintf(\"Cannot import %q into a CSS file\",\n\t\t\t\t\t\t\t\totherFile.inputFile.Source.PrettyPaths.Select(s.options.LogPathStyle)),\n\t\t\t\t\t\t\t[]logger.MsgData{{Text: fmt.Sprintf(\n\t\t\t\t\t\t\t\t\"An \\\"@import\\\" rule can only be used to import another CSS file and %q is not a CSS file (it was loaded with the %q loader).\",\n\t\t\t\t\t\t\t\totherFile.inputFile.Source.PrettyPaths.Select(s.options.LogPathStyle),\n\t\t\t\t\t\t\t\tconfig.LoaderToString[otherFile.inputFile.Loader])}})\n\t\t\t\t\t}\n\n\t\t\t\tcase ast.ImportURL:\n\t\t\t\t\t// Using a JavaScript or CSS file with CSS \"url()\" is not allowed\n\t\t\t\t\tswitch otherRepr := otherFile.inputFile.Repr.(type) {\n\t\t\t\t\tcase *graph.CSSRepr:\n\t\t\t\t\t\ts.log.AddErrorWithNotes(&tracker, record.Range,\n\t\t\t\t\t\t\tfmt.Sprintf(\"Cannot use %q as a URL\",\n\t\t\t\t\t\t\t\totherFile.inputFile.Source.PrettyPaths.Select(s.options.LogPathStyle)),\n\t\t\t\t\t\t\t[]logger.MsgData{{Text: fmt.Sprintf(\n\t\t\t\t\t\t\t\t\"You can't use a \\\"url()\\\" token to reference a CSS file, and %q is a CSS file (it was loaded with the %q loader).\",\n\t\t\t\t\t\t\t\totherFile.inputFile.Source.PrettyPaths.Select(s.options.LogPathStyle),\n\t\t\t\t\t\t\t\tconfig.LoaderToString[otherFile.inputFile.Loader])}})\n\n\t\t\t\t\tcase *graph.JSRepr:\n\t\t\t\t\t\tif otherRepr.AST.URLForCSS == \"\" && otherFile.inputFile.Loader != config.LoaderEmpty {\n\t\t\t\t\t\t\ts.log.AddErrorWithNotes(&tracker, record.Range,\n\t\t\t\t\t\t\t\tfmt.Sprintf(\"Cannot use %q as a URL\",\n\t\t\t\t\t\t\t\t\totherFile.inputFile.Source.PrettyPaths.Select(s.options.LogPathStyle)),\n\t\t\t\t\t\t\t\t[]logger.MsgData{{Text: fmt.Sprintf(\n\t\t\t\t\t\t\t\t\t\"You can't use a \\\"url()\\\" token to reference the file %q because it was loaded with the %q loader, which doesn't provide a URL to embed in the resulting CSS.\",\n\t\t\t\t\t\t\t\t\totherFile.inputFile.Source.PrettyPaths.Select(s.options.LogPathStyle),\n\t\t\t\t\t\t\t\t\tconfig.LoaderToString[otherFile.inputFile.Loader])}})\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If the imported file uses the \"copy\" loader, then move it from\n\t\t\t\t// \"SourceIndex\" to \"CopySourceIndex\" so we don't end up bundling it.\n\t\t\t\tif _, ok := otherFile.inputFile.Repr.(*graph.CopyRepr); ok {\n\t\t\t\t\trecord.CopySourceIndex = record.SourceIndex\n\t\t\t\t\trecord.SourceIndex = ast.Index32{}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// If an import from a JavaScript file targets a CSS file, generate a\n\t\t\t\t// JavaScript stub to ensure that JavaScript files only ever import\n\t\t\t\t// other JavaScript files.\n\t\t\t\tif _, ok := result.file.inputFile.Repr.(*graph.JSRepr); ok {\n\t\t\t\t\tif css, ok := otherFile.inputFile.Repr.(*graph.CSSRepr); ok {\n\t\t\t\t\t\tif s.options.WriteToStdout {\n\t\t\t\t\t\t\ts.log.AddError(&tracker, record.Range,\n\t\t\t\t\t\t\t\tfmt.Sprintf(\"Cannot import %q into a JavaScript file without an output path configured\",\n\t\t\t\t\t\t\t\t\totherFile.inputFile.Source.PrettyPaths.Select(s.options.LogPathStyle)))\n\t\t\t\t\t\t} else if !css.JSSourceIndex.IsValid() {\n\t\t\t\t\t\t\tstubKey := otherFile.inputFile.Source.KeyPath\n\t\t\t\t\t\t\tif stubKey.Namespace == \"file\" {\n\t\t\t\t\t\t\t\tstubKey.Text = canonicalFileSystemPathForWindows(stubKey.Text)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsourceIndex := s.allocateSourceIndex(stubKey, cache.SourceIndexJSStubForCSS)\n\t\t\t\t\t\t\tsource := otherFile.inputFile.Source\n\t\t\t\t\t\t\tsource.Index = sourceIndex\n\t\t\t\t\t\t\ts.results[sourceIndex] = parseResult{\n\t\t\t\t\t\t\t\tfile: scannerFile{\n\t\t\t\t\t\t\t\t\tinputFile: graph.InputFile{\n\t\t\t\t\t\t\t\t\t\tSource: source,\n\t\t\t\t\t\t\t\t\t\tLoader: otherFile.inputFile.Loader,\n\t\t\t\t\t\t\t\t\t\tRepr: &graph.JSRepr{\n\t\t\t\t\t\t\t\t\t\t\t// Note: The actual export object will be filled in by the linker\n\t\t\t\t\t\t\t\t\t\t\tAST: js_parser.LazyExportAST(s.log, source,\n\t\t\t\t\t\t\t\t\t\t\t\tjs_parser.OptionsFromConfig(&s.options), js_ast.Expr{Data: js_ast.ENullShared}, nil),\n\t\t\t\t\t\t\t\t\t\t\tCSSSourceIndex: ast.MakeIndex32(record.SourceIndex.GetIndex()),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tok: true,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcss.JSSourceIndex = ast.MakeIndex32(sourceIndex)\n\t\t\t\t\t\t}\n\t\t\t\t\t\trecord.SourceIndex = css.JSSourceIndex\n\t\t\t\t\t\tif !css.JSSourceIndex.IsValid() {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Warn about this import if it's a bare import statement without any\n\t\t\t\t// imported names (i.e. a side-effect-only import) and the module has\n\t\t\t\t// been marked as having no side effects.\n\t\t\t\t//\n\t\t\t\t// Except don't do this if this file is inside \"node_modules\" since\n\t\t\t\t// it's a bug in the package and the user won't be able to do anything\n\t\t\t\t// about it. Note that this can result in esbuild silently generating\n\t\t\t\t// broken code. If this actually happens for people, it's probably worth\n\t\t\t\t// re-enabling the warning about code inside \"node_modules\".\n\t\t\t\tif record.Flags.Has(ast.WasOriginallyBareImport) && !s.options.IgnoreDCEAnnotations &&\n\t\t\t\t\t!helpers.IsInsideNodeModules(result.file.inputFile.Source.KeyPath.Text) {\n\t\t\t\t\tif otherModule := &s.results[record.SourceIndex.GetIndex()].file.inputFile; otherModule.SideEffects.Kind != graph.HasSideEffects &&\n\t\t\t\t\t\t// Do not warn if this is from a plugin, since removing the import\n\t\t\t\t\t\t// would cause the plugin to not run, and running a plugin is a side\n\t\t\t\t\t\t// effect.\n\t\t\t\t\t\totherModule.SideEffects.Kind != graph.NoSideEffects_PureData_FromPlugin &&\n\n\t\t\t\t\t\t// Do not warn if this has no side effects because the parsed AST\n\t\t\t\t\t\t// is empty. This is the case for \".d.ts\" files, for example.\n\t\t\t\t\t\totherModule.SideEffects.Kind != graph.NoSideEffects_EmptyAST {\n\n\t\t\t\t\t\tvar notes []logger.MsgData\n\t\t\t\t\t\tvar by string\n\t\t\t\t\t\tif data := otherModule.SideEffects.Data; data != nil {\n\t\t\t\t\t\t\tif data.PluginName != \"\" {\n\t\t\t\t\t\t\t\tby = fmt.Sprintf(\" by plugin %q\", data.PluginName)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tvar text string\n\t\t\t\t\t\t\t\tif data.IsSideEffectsArrayInJSON {\n\t\t\t\t\t\t\t\t\ttext = \"It was excluded from the \\\"sideEffects\\\" array in the enclosing \\\"package.json\\\" file:\"\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\ttext = \"\\\"sideEffects\\\" is false in the enclosing \\\"package.json\\\" file:\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\ttracker := logger.MakeLineColumnTracker(data.Source)\n\t\t\t\t\t\t\t\tnotes = append(notes, tracker.MsgData(data.Range, text))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\ts.log.AddIDWithNotes(logger.MsgID_Bundler_IgnoredBareImport, logger.Warning, &tracker, record.Range,\n\t\t\t\t\t\t\tfmt.Sprintf(\"Ignoring this import because %q was marked as having no side effects%s\",\n\t\t\t\t\t\t\t\totherModule.Source.PrettyPaths.Select(s.options.LogPathStyle), by), notes)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// End the metadata chunk\n\t\tif s.options.NeedsMetafile {\n\t\t\tif !isFirstImport {\n\t\t\t\tsb.WriteString(s.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n      \"))\n\t\t\t}\n\t\t\tif repr, ok := result.file.inputFile.Repr.(*graph.JSRepr); ok &&\n\t\t\t\t(repr.AST.ExportsKind == js_ast.ExportsCommonJS || repr.AST.ExportsKind == js_ast.ExportsESM) {\n\t\t\t\tformat := \"cjs\"\n\t\t\t\tif repr.AST.ExportsKind == js_ast.ExportsESM {\n\t\t\t\t\tformat = \"esm\"\n\t\t\t\t}\n\t\t\t\tsb.WriteString(fmt.Sprintf(s.options.MetafileFormat.MaybeRemoveWhitespace(\"],\\n      \\\"format\\\": %q\"), format))\n\t\t\t} else {\n\t\t\t\tsb.WriteString(\"]\")\n\t\t\t}\n\t\t\tif attrs := result.file.inputFile.Source.KeyPath.ImportAttributes.DecodeIntoArray(); len(attrs) > 0 {\n\t\t\t\tsb.WriteString(s.options.MetafileFormat.MaybeRemoveWhitespace(\",\\n      \\\"with\\\": {\"))\n\t\t\t\tfor i, attr := range attrs {\n\t\t\t\t\tif i > 0 {\n\t\t\t\t\t\tsb.WriteByte(',')\n\t\t\t\t\t}\n\t\t\t\t\tsb.WriteString(fmt.Sprintf(\n\t\t\t\t\t\ts.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n        %s: %s\"),\n\t\t\t\t\t\thelpers.QuoteForJSON(attr.Key, s.options.ASCIIOnly),\n\t\t\t\t\t\thelpers.QuoteForJSON(attr.Value, s.options.ASCIIOnly),\n\t\t\t\t\t))\n\t\t\t\t}\n\t\t\t\tsb.WriteString(s.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n      }\"))\n\t\t\t}\n\t\t\tsb.WriteString(s.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n    }\"))\n\t\t}\n\n\t\tresult.file.jsonMetadataChunk = sb.String()\n\n\t\t// If this file is from the \"file\" or \"copy\" loaders, generate an additional file\n\t\tif result.file.inputFile.UniqueKeyForAdditionalFile != \"\" {\n\t\t\tbytes := []byte(result.file.inputFile.Source.Contents)\n\t\t\ttemplate := s.options.AssetPathTemplate\n\n\t\t\t// Use the entry path template instead of the asset path template if this\n\t\t\t// file is an entry point and uses the \"copy\" loader. With the \"file\" loader\n\t\t\t// the JS stub is the entry point, but with the \"copy\" loader the file is\n\t\t\t// the entry point itself.\n\t\t\tcustomFilePath := \"\"\n\t\t\tuseOutputFile := false\n\t\t\tisEntryPoint := false\n\t\t\tif result.file.inputFile.Loader == config.LoaderCopy {\n\t\t\t\tif metaIndex, ok := entryPointSourceIndexToMetaIndex[uint32(sourceIndex)]; ok {\n\t\t\t\t\ttemplate = s.options.EntryPathTemplate\n\t\t\t\t\tcustomFilePath = entryPointMeta[metaIndex].OutputPath\n\t\t\t\t\tuseOutputFile = s.options.AbsOutputFile != \"\"\n\t\t\t\t\tisEntryPoint = true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add a hash to the file name to prevent multiple files with the same name\n\t\t\t// but different contents from colliding\n\t\t\tvar hash string\n\t\t\tif config.HasPlaceholder(template, config.HashPlaceholder) {\n\t\t\t\th := xxhash.New()\n\t\t\t\th.Write(bytes)\n\t\t\t\thash = HashForFileName(h.Sum(nil))\n\t\t\t}\n\n\t\t\t// This should use similar logic to how the linker computes output paths\n\t\t\tvar dir, base, ext string\n\t\t\tif useOutputFile {\n\t\t\t\t// If the output path was configured explicitly, use it verbatim\n\t\t\t\tdir = \"/\"\n\t\t\t\tbase = s.fs.Base(s.options.AbsOutputFile)\n\t\t\t\text = s.fs.Ext(base)\n\t\t\t\tbase = base[:len(base)-len(ext)]\n\t\t\t} else {\n\t\t\t\t// Otherwise, derive the output path from the input path\n\t\t\t\t// Generate the input for the template\n\t\t\t\t_, _, originalExt := logger.PlatformIndependentPathDirBaseExt(result.file.inputFile.Source.KeyPath.Text)\n\t\t\t\tdir, base = PathRelativeToOutbase(\n\t\t\t\t\t&result.file.inputFile,\n\t\t\t\t\t&s.options,\n\t\t\t\t\ts.fs,\n\t\t\t\t\t/* avoidIndex */ false,\n\t\t\t\t\tcustomFilePath,\n\t\t\t\t)\n\t\t\t\text = originalExt\n\t\t\t}\n\n\t\t\t// Apply the path template\n\t\t\ttemplateExt := strings.TrimPrefix(ext, \".\")\n\t\t\trelPath := config.TemplateToString(config.SubstituteTemplate(template, config.PathPlaceholders{\n\t\t\t\tDir:  &dir,\n\t\t\t\tName: &base,\n\t\t\t\tHash: &hash,\n\t\t\t\tExt:  &templateExt,\n\t\t\t})) + ext\n\n\t\t\t// Optionally add metadata about the file\n\t\t\tvar jsonMetadataChunk string\n\t\t\tif s.options.NeedsMetafile {\n\t\t\t\tinputs := fmt.Sprintf(\n\t\t\t\t\ts.options.MetafileFormat.MaybeRemoveWhitespace(\"{\\n        %s: {\\n          \\\"bytesInOutput\\\": %d\\n        }\\n      }\"),\n\t\t\t\t\thelpers.QuoteForJSON(result.file.inputFile.Source.PrettyPaths.Select(s.options.MetafilePathStyle), s.options.ASCIIOnly),\n\t\t\t\t\tlen(bytes),\n\t\t\t\t)\n\t\t\t\tentryPointJSON := \"\"\n\t\t\t\tif isEntryPoint {\n\t\t\t\t\tentryPointJSON = fmt.Sprintf(\n\t\t\t\t\t\ts.options.MetafileFormat.MaybeRemoveWhitespace(\"\\\"entryPoint\\\": %s,\\n      \"),\n\t\t\t\t\t\thelpers.QuoteForJSON(result.file.inputFile.Source.PrettyPaths.Select(s.options.MetafilePathStyle), s.options.ASCIIOnly))\n\t\t\t\t}\n\t\t\t\tjsonMetadataChunk = fmt.Sprintf(\n\t\t\t\t\ts.options.MetafileFormat.MaybeRemoveWhitespace(\"{\\n      \\\"imports\\\": [],\\n      \\\"exports\\\": [],\\n      %s\\\"inputs\\\": %s,\\n      \\\"bytes\\\": %d\\n    }\"),\n\t\t\t\t\tentryPointJSON,\n\t\t\t\t\tinputs,\n\t\t\t\t\tlen(bytes),\n\t\t\t\t)\n\t\t\t}\n\n\t\t\t// Generate the additional file to copy into the output directory\n\t\t\tresult.file.inputFile.AdditionalFiles = []graph.OutputFile{{\n\t\t\t\tAbsPath:           s.fs.Join(s.options.AbsOutputDir, relPath),\n\t\t\t\tContents:          bytes,\n\t\t\t\tJSONMetadataChunk: jsonMetadataChunk,\n\t\t\t}}\n\t\t}\n\n\t\ts.results[sourceIndex] = result\n\t}\n\n\t// The linker operates on an array of files, so construct that now. This\n\t// can't be constructed earlier because we generate new parse results for\n\t// JavaScript stub files for CSS imports above.\n\tfiles := make([]scannerFile, len(s.results))\n\tfor sourceIndex := range s.results {\n\t\tif result := &s.results[sourceIndex]; result.ok {\n\t\t\ts.validateTLA(uint32(sourceIndex))\n\t\t\tfiles[sourceIndex] = result.file\n\t\t}\n\t}\n\n\treturn files\n}\n\nfunc (s *scanner) validateTLA(sourceIndex uint32) tlaCheck {\n\tresult := &s.results[sourceIndex]\n\n\tif result.ok && result.tlaCheck.depth == 0 {\n\t\tif repr, ok := result.file.inputFile.Repr.(*graph.JSRepr); ok {\n\t\t\tresult.tlaCheck.depth = 1\n\t\t\tif repr.AST.LiveTopLevelAwaitKeyword.Len > 0 {\n\t\t\t\tresult.tlaCheck.parent = ast.MakeIndex32(sourceIndex)\n\t\t\t}\n\n\t\t\tfor importRecordIndex, record := range repr.AST.ImportRecords {\n\t\t\t\tif record.SourceIndex.IsValid() && (record.Kind == ast.ImportRequire || record.Kind == ast.ImportStmt) {\n\t\t\t\t\tparent := s.validateTLA(record.SourceIndex.GetIndex())\n\t\t\t\t\tif !parent.parent.IsValid() {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// Follow any import chains\n\t\t\t\t\tif record.Kind == ast.ImportStmt && (!result.tlaCheck.parent.IsValid() || parent.depth < result.tlaCheck.depth) {\n\t\t\t\t\t\tresult.tlaCheck.depth = parent.depth + 1\n\t\t\t\t\t\tresult.tlaCheck.parent = record.SourceIndex\n\t\t\t\t\t\tresult.tlaCheck.importRecordIndex = uint32(importRecordIndex)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// Require of a top-level await chain is forbidden\n\t\t\t\t\tif record.Kind == ast.ImportRequire {\n\t\t\t\t\t\tvar notes []logger.MsgData\n\t\t\t\t\t\tvar tlaPrettyPaths logger.PrettyPaths\n\t\t\t\t\t\totherSourceIndex := record.SourceIndex.GetIndex()\n\n\t\t\t\t\t\t// Build up a chain of relevant notes for all of the imports\n\t\t\t\t\t\tfor {\n\t\t\t\t\t\t\tparentResult := &s.results[otherSourceIndex]\n\t\t\t\t\t\t\tparentRepr := parentResult.file.inputFile.Repr.(*graph.JSRepr)\n\n\t\t\t\t\t\t\tif parentRepr.AST.LiveTopLevelAwaitKeyword.Len > 0 {\n\t\t\t\t\t\t\t\ttlaPrettyPaths = parentResult.file.inputFile.Source.PrettyPaths\n\t\t\t\t\t\t\t\ttracker := logger.MakeLineColumnTracker(&parentResult.file.inputFile.Source)\n\t\t\t\t\t\t\t\tnotes = append(notes, tracker.MsgData(parentRepr.AST.LiveTopLevelAwaitKeyword,\n\t\t\t\t\t\t\t\t\tfmt.Sprintf(\"The top-level await in %q is here:\",\n\t\t\t\t\t\t\t\t\t\ttlaPrettyPaths.Select(s.options.LogPathStyle))))\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif !parentResult.tlaCheck.parent.IsValid() {\n\t\t\t\t\t\t\t\tnotes = append(notes, logger.MsgData{Text: \"unexpected invalid index\"})\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\totherSourceIndex = parentResult.tlaCheck.parent.GetIndex()\n\n\t\t\t\t\t\t\ttracker := logger.MakeLineColumnTracker(&parentResult.file.inputFile.Source)\n\t\t\t\t\t\t\tnotes = append(notes, tracker.MsgData(\n\t\t\t\t\t\t\t\tparentRepr.AST.ImportRecords[parentResult.tlaCheck.importRecordIndex].Range,\n\t\t\t\t\t\t\t\tfmt.Sprintf(\"The file %q imports the file %q here:\",\n\t\t\t\t\t\t\t\t\tparentResult.file.inputFile.Source.PrettyPaths.Select(s.options.LogPathStyle),\n\t\t\t\t\t\t\t\t\ts.results[otherSourceIndex].file.inputFile.Source.PrettyPaths.Select(s.options.LogPathStyle))))\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar text string\n\t\t\t\t\t\timportedPrettyPaths := s.results[record.SourceIndex.GetIndex()].file.inputFile.Source.PrettyPaths\n\n\t\t\t\t\t\tif importedPrettyPaths == tlaPrettyPaths {\n\t\t\t\t\t\t\ttext = fmt.Sprintf(\"This require call is not allowed because the imported file %q contains a top-level await\",\n\t\t\t\t\t\t\t\timportedPrettyPaths.Select(s.options.LogPathStyle))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttext = fmt.Sprintf(\"This require call is not allowed because the transitive dependency %q contains a top-level await\",\n\t\t\t\t\t\t\t\ttlaPrettyPaths.Select(s.options.LogPathStyle))\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttracker := logger.MakeLineColumnTracker(&result.file.inputFile.Source)\n\t\t\t\t\t\ts.log.AddErrorWithNotes(&tracker, record.Range, text, notes)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Make sure that if we wrap this module in a closure, the closure is also\n\t\t\t// async. This happens when you call \"import()\" on this module and code\n\t\t\t// splitting is off.\n\t\t\tif result.tlaCheck.parent.IsValid() {\n\t\t\t\trepr.Meta.IsAsyncOrHasAsyncDependency = true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result.tlaCheck\n}\n\nfunc DefaultExtensionToLoaderMap() map[string]config.Loader {\n\treturn map[string]config.Loader{\n\t\t\"\":            config.LoaderJS, // This represents files without an extension\n\t\t\".js\":         config.LoaderJS,\n\t\t\".mjs\":        config.LoaderJS,\n\t\t\".cjs\":        config.LoaderJS,\n\t\t\".jsx\":        config.LoaderJSX,\n\t\t\".ts\":         config.LoaderTS,\n\t\t\".cts\":        config.LoaderTSNoAmbiguousLessThan,\n\t\t\".mts\":        config.LoaderTSNoAmbiguousLessThan,\n\t\t\".tsx\":        config.LoaderTSX,\n\t\t\".css\":        config.LoaderCSS,\n\t\t\".module.css\": config.LoaderLocalCSS,\n\t\t\".json\":       config.LoaderJSON,\n\t\t\".txt\":        config.LoaderText,\n\t}\n}\n\nfunc applyOptionDefaults(options *config.Options) {\n\tif options.ExtensionToLoader == nil {\n\t\toptions.ExtensionToLoader = DefaultExtensionToLoaderMap()\n\t}\n\tif options.OutputExtensionJS == \"\" {\n\t\toptions.OutputExtensionJS = \".js\"\n\t}\n\tif options.OutputExtensionCSS == \"\" {\n\t\toptions.OutputExtensionCSS = \".css\"\n\t}\n\n\t// Configure default path templates\n\tif len(options.EntryPathTemplate) == 0 {\n\t\toptions.EntryPathTemplate = []config.PathTemplate{\n\t\t\t{Data: \"./\", Placeholder: config.DirPlaceholder},\n\t\t\t{Data: \"/\", Placeholder: config.NamePlaceholder},\n\t\t}\n\t}\n\tif len(options.ChunkPathTemplate) == 0 {\n\t\toptions.ChunkPathTemplate = []config.PathTemplate{\n\t\t\t{Data: \"./\", Placeholder: config.NamePlaceholder},\n\t\t\t{Data: \"-\", Placeholder: config.HashPlaceholder},\n\t\t}\n\t}\n\tif len(options.AssetPathTemplate) == 0 {\n\t\toptions.AssetPathTemplate = []config.PathTemplate{\n\t\t\t{Data: \"./\", Placeholder: config.NamePlaceholder},\n\t\t\t{Data: \"-\", Placeholder: config.HashPlaceholder},\n\t\t}\n\t}\n\n\toptions.ProfilerNames = !options.MinifyIdentifiers\n\n\t// Automatically fix invalid configurations of unsupported features\n\tfixInvalidUnsupportedJSFeatureOverrides(options, compat.AsyncAwait, compat.AsyncGenerator|compat.ForAwait|compat.TopLevelAwait)\n\tfixInvalidUnsupportedJSFeatureOverrides(options, compat.Generator, compat.AsyncGenerator)\n\tfixInvalidUnsupportedJSFeatureOverrides(options, compat.ObjectAccessors, compat.ClassPrivateAccessor|compat.ClassPrivateStaticAccessor)\n\tfixInvalidUnsupportedJSFeatureOverrides(options, compat.ClassField, compat.ClassPrivateField)\n\tfixInvalidUnsupportedJSFeatureOverrides(options, compat.ClassStaticField, compat.ClassPrivateStaticField)\n\tfixInvalidUnsupportedJSFeatureOverrides(options, compat.Class,\n\t\tcompat.ClassField|compat.ClassPrivateAccessor|compat.ClassPrivateBrandCheck|compat.ClassPrivateField|\n\t\t\tcompat.ClassPrivateMethod|compat.ClassPrivateStaticAccessor|compat.ClassPrivateStaticField|\n\t\t\tcompat.ClassPrivateStaticMethod|compat.ClassStaticBlocks|compat.ClassStaticField)\n\n\t// If we're not building for the browser, automatically disable support for\n\t// inline </script> and </style> tags if there aren't currently any overrides\n\tif options.Platform != config.PlatformBrowser {\n\t\tif !options.UnsupportedJSFeatureOverridesMask.Has(compat.InlineScript) {\n\t\t\toptions.UnsupportedJSFeatures |= compat.InlineScript\n\t\t}\n\t\tif !options.UnsupportedCSSFeatureOverridesMask.Has(compat.InlineStyle) {\n\t\t\toptions.UnsupportedCSSFeatures |= compat.InlineStyle\n\t\t}\n\t}\n}\n\nfunc fixInvalidUnsupportedJSFeatureOverrides(options *config.Options, implies compat.JSFeature, implied compat.JSFeature) {\n\t// If this feature is unsupported, that implies that the other features must also be unsupported\n\tif options.UnsupportedJSFeatureOverrides.Has(implies) {\n\t\toptions.UnsupportedJSFeatures |= implied\n\t\toptions.UnsupportedJSFeatureOverrides |= implied\n\t\toptions.UnsupportedJSFeatureOverridesMask |= implied\n\t}\n}\n\ntype Linker func(\n\toptions *config.Options,\n\ttimer *helpers.Timer,\n\tlog logger.Log,\n\tfs fs.FS,\n\tres *resolver.Resolver,\n\tinputFiles []graph.InputFile,\n\tentryPoints []graph.EntryPoint,\n\tuniqueKeyPrefix string,\n\treachableFiles []uint32,\n\tdataForSourceMaps func() []DataForSourceMap,\n) []graph.OutputFile\n\nfunc (b *Bundle) Compile(log logger.Log, timer *helpers.Timer, mangleCache map[string]interface{}, link Linker) ([]graph.OutputFile, string) {\n\ttimer.Begin(\"Compile phase\")\n\tdefer timer.End(\"Compile phase\")\n\n\tif b.options.CancelFlag.DidCancel() {\n\t\treturn nil, \"\"\n\t}\n\n\toptions := b.options\n\n\t// In most cases we don't need synchronized access to the mangle cache\n\tcssUsedLocalNames := make(map[string]bool)\n\toptions.ExclusiveMangleCacheUpdate = func(cb func(\n\t\tmangleCache map[string]interface{},\n\t\tcssUsedLocalNames map[string]bool,\n\t)) {\n\t\tcb(mangleCache, cssUsedLocalNames)\n\t}\n\n\tfiles := make([]graph.InputFile, len(b.files))\n\tfor i, file := range b.files {\n\t\tfiles[i] = file.inputFile\n\t}\n\n\t// Get the base path from the options or choose the lowest common ancestor of all entry points\n\tallReachableFiles := findReachableFiles(files, b.entryPoints)\n\n\t// Compute source map data in parallel with linking\n\ttimer.Begin(\"Spawn source map tasks\")\n\tdataForSourceMaps := b.computeDataForSourceMapsInParallel(&options, allReachableFiles)\n\ttimer.End(\"Spawn source map tasks\")\n\n\tvar resultGroups [][]graph.OutputFile\n\tif options.CodeSplitting || len(b.entryPoints) == 1 {\n\t\t// If code splitting is enabled or if there's only one entry point, link all entry points together\n\t\tresultGroups = [][]graph.OutputFile{link(&options, timer, log, b.fs, b.res,\n\t\t\tfiles, b.entryPoints, b.uniqueKeyPrefix, allReachableFiles, dataForSourceMaps)}\n\t} else {\n\t\t// Otherwise, link each entry point with the runtime file separately\n\t\twaitGroup := sync.WaitGroup{}\n\t\tresultGroups = make([][]graph.OutputFile, len(b.entryPoints))\n\t\tserializer := helpers.MakeSerializer(len(b.entryPoints))\n\t\tfor i, entryPoint := range b.entryPoints {\n\t\t\twaitGroup.Add(1)\n\t\t\tgo func(i int, entryPoint graph.EntryPoint) {\n\t\t\t\tentryPoints := []graph.EntryPoint{entryPoint}\n\t\t\t\tforked := timer.Fork()\n\n\t\t\t\t// Each goroutine needs a separate options object\n\t\t\t\toptionsClone := options\n\t\t\t\toptionsClone.ExclusiveMangleCacheUpdate = func(cb func(\n\t\t\t\t\tmangleCache map[string]interface{},\n\t\t\t\t\tcssUsedLocalNames map[string]bool,\n\t\t\t\t)) {\n\t\t\t\t\t// Serialize all accesses to the mangle cache in entry point order for determinism\n\t\t\t\t\tserializer.Enter(i)\n\t\t\t\t\tdefer serializer.Leave(i)\n\t\t\t\t\tcb(mangleCache, cssUsedLocalNames)\n\t\t\t\t}\n\n\t\t\t\tresultGroups[i] = link(&optionsClone, forked, log, b.fs, b.res, files, entryPoints,\n\t\t\t\t\tb.uniqueKeyPrefix, findReachableFiles(files, entryPoints), dataForSourceMaps)\n\t\t\t\ttimer.Join(forked)\n\t\t\t\twaitGroup.Done()\n\t\t\t}(i, entryPoint)\n\t\t}\n\t\twaitGroup.Wait()\n\t}\n\n\t// Join the results in entry point order for determinism\n\tvar outputFiles []graph.OutputFile\n\tfor _, group := range resultGroups {\n\t\toutputFiles = append(outputFiles, group...)\n\t}\n\n\t// Also generate the metadata file if necessary\n\tvar metafileJSON string\n\tif options.NeedsMetafile {\n\t\ttimer.Begin(\"Generate metadata JSON\")\n\t\tmetafileJSON = b.generateMetadataJSON(outputFiles, allReachableFiles, &options)\n\t\ttimer.End(\"Generate metadata JSON\")\n\t}\n\n\tif !options.WriteToStdout {\n\t\t// Make sure an output file never overwrites an input file\n\t\tif !options.AllowOverwrite {\n\t\t\tsourceAbsPaths := make(map[string]uint32)\n\t\t\tfor _, sourceIndex := range allReachableFiles {\n\t\t\t\tkeyPath := b.files[sourceIndex].inputFile.Source.KeyPath\n\t\t\t\tif keyPath.Namespace == \"file\" {\n\t\t\t\t\tabsPathKey := canonicalFileSystemPathForWindows(keyPath.Text)\n\t\t\t\t\tsourceAbsPaths[absPathKey] = sourceIndex\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor _, outputFile := range outputFiles {\n\t\t\t\tabsPathKey := canonicalFileSystemPathForWindows(outputFile.AbsPath)\n\t\t\t\tif sourceIndex, ok := sourceAbsPaths[absPathKey]; ok {\n\t\t\t\t\thint := \"\"\n\t\t\t\t\tswitch logger.API {\n\t\t\t\t\tcase logger.CLIAPI:\n\t\t\t\t\t\thint = \" (use \\\"--allow-overwrite\\\" to allow this)\"\n\t\t\t\t\tcase logger.JSAPI:\n\t\t\t\t\t\thint = \" (use \\\"allowOverwrite: true\\\" to allow this)\"\n\t\t\t\t\tcase logger.GoAPI:\n\t\t\t\t\t\thint = \" (use \\\"AllowOverwrite: true\\\" to allow this)\"\n\t\t\t\t\t}\n\t\t\t\t\tlog.AddError(nil, logger.Range{},\n\t\t\t\t\t\tfmt.Sprintf(\"Refusing to overwrite input file %q%s\",\n\t\t\t\t\t\t\tb.files[sourceIndex].inputFile.Source.PrettyPaths.Select(options.LogPathStyle), hint))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Make sure an output file never overwrites another output file. This\n\t\t// is almost certainly unintentional and would otherwise happen silently.\n\t\t//\n\t\t// Make an exception for files that have identical contents. In that case\n\t\t// the duplicate is just silently filtered out. This can happen with the\n\t\t// \"file\" loader, for example.\n\t\toutputFileMap := make(map[string][]byte)\n\t\tend := 0\n\t\tfor _, outputFile := range outputFiles {\n\t\t\tabsPathKey := canonicalFileSystemPathForWindows(outputFile.AbsPath)\n\t\t\tcontents, ok := outputFileMap[absPathKey]\n\n\t\t\t// If this isn't a duplicate, keep the output file\n\t\t\tif !ok {\n\t\t\t\toutputFileMap[absPathKey] = outputFile.Contents\n\t\t\t\toutputFiles[end] = outputFile\n\t\t\t\tend++\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// If the names and contents are both the same, only keep the first one\n\t\t\tif bytes.Equal(contents, outputFile.Contents) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Otherwise, generate an error\n\t\t\toutputPath := outputFile.AbsPath\n\t\t\tif relPath, ok := b.fs.Rel(b.fs.Cwd(), outputPath); ok {\n\t\t\t\toutputPath = relPath\n\t\t\t}\n\t\t\tlog.AddError(nil, logger.Range{}, \"Two output files share the same path but have different contents: \"+outputPath)\n\t\t}\n\t\toutputFiles = outputFiles[:end]\n\t}\n\n\treturn outputFiles, metafileJSON\n}\n\n// Find all files reachable from all entry points. This order should be\n// deterministic given that the entry point order is deterministic, since the\n// returned order is the postorder of the graph traversal and import record\n// order within a given file is deterministic.\nfunc findReachableFiles(files []graph.InputFile, entryPoints []graph.EntryPoint) []uint32 {\n\tvisited := make(map[uint32]bool)\n\tvar order []uint32\n\tvar visit func(uint32)\n\n\t// Include this file and all files it imports\n\tvisit = func(sourceIndex uint32) {\n\t\tif !visited[sourceIndex] {\n\t\t\tvisited[sourceIndex] = true\n\t\t\tfile := &files[sourceIndex]\n\t\t\tif repr, ok := file.Repr.(*graph.JSRepr); ok && repr.CSSSourceIndex.IsValid() {\n\t\t\t\tvisit(repr.CSSSourceIndex.GetIndex())\n\t\t\t}\n\t\t\tif recordsPtr := file.Repr.ImportRecords(); recordsPtr != nil {\n\t\t\t\tfor _, record := range *recordsPtr {\n\t\t\t\t\tif record.SourceIndex.IsValid() {\n\t\t\t\t\t\tvisit(record.SourceIndex.GetIndex())\n\t\t\t\t\t} else if record.CopySourceIndex.IsValid() {\n\t\t\t\t\t\tvisit(record.CopySourceIndex.GetIndex())\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Each file must come after its dependencies\n\t\t\torder = append(order, sourceIndex)\n\t\t}\n\t}\n\n\t// The runtime is always included in case it's needed\n\tvisit(runtime.SourceIndex)\n\n\t// Include all files reachable from any entry point\n\tfor _, entryPoint := range entryPoints {\n\t\tvisit(entryPoint.SourceIndex)\n\t}\n\n\treturn order\n}\n\n// This is done in parallel with linking because linking is a mostly serial\n// phase and there are extra resources for parallelism. This could also be done\n// during parsing but that would slow down parsing and delay the start of the\n// linking phase, which then delays the whole bundling process.\n//\n// However, doing this during parsing would allow it to be cached along with\n// the parsed ASTs which would then speed up incremental builds. In the future\n// it could be good to optionally have this be computed during the parsing\n// phase when incremental builds are active but otherwise still have it be\n// computed during linking for optimal speed during non-incremental builds.\nfunc (b *Bundle) computeDataForSourceMapsInParallel(options *config.Options, reachableFiles []uint32) func() []DataForSourceMap {\n\tif options.SourceMap == config.SourceMapNone {\n\t\treturn func() []DataForSourceMap {\n\t\t\treturn nil\n\t\t}\n\t}\n\n\tvar waitGroup sync.WaitGroup\n\tresults := make([]DataForSourceMap, len(b.files))\n\n\tfor _, sourceIndex := range reachableFiles {\n\t\tif f := &b.files[sourceIndex]; f.inputFile.Loader.CanHaveSourceMap() {\n\t\t\tvar approximateLineCount int32\n\t\t\tswitch repr := f.inputFile.Repr.(type) {\n\t\t\tcase *graph.JSRepr:\n\t\t\t\tapproximateLineCount = repr.AST.ApproximateLineCount\n\t\t\tcase *graph.CSSRepr:\n\t\t\t\tapproximateLineCount = repr.AST.ApproximateLineCount\n\t\t\t}\n\t\t\twaitGroup.Add(1)\n\t\t\tgo func(sourceIndex uint32, f *scannerFile, approximateLineCount int32) {\n\t\t\t\tresult := &results[sourceIndex]\n\t\t\t\tresult.LineOffsetTables = sourcemap.GenerateLineOffsetTables(f.inputFile.Source.Contents, approximateLineCount)\n\t\t\t\tsm := f.inputFile.InputSourceMap\n\t\t\t\tif !options.ExcludeSourcesContent {\n\t\t\t\t\tif sm == nil {\n\t\t\t\t\t\t// Simple case: no nested source map\n\t\t\t\t\t\tresult.QuotedContents = [][]byte{helpers.QuoteForJSON(f.inputFile.Source.Contents, options.ASCIIOnly)}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Complex case: nested source map\n\t\t\t\t\t\tresult.QuotedContents = make([][]byte, len(sm.Sources))\n\t\t\t\t\t\tnullContents := []byte(\"null\")\n\t\t\t\t\t\tfor i := range sm.Sources {\n\t\t\t\t\t\t\t// Missing contents become a \"null\" literal\n\t\t\t\t\t\t\tquotedContents := nullContents\n\t\t\t\t\t\t\tif i < len(sm.SourcesContent) {\n\t\t\t\t\t\t\t\tif value := sm.SourcesContent[i]; value.Quoted != \"\" && (!options.ASCIIOnly || !isASCIIOnly(value.Quoted)) {\n\t\t\t\t\t\t\t\t\t// Just use the value directly from the input file\n\t\t\t\t\t\t\t\t\tquotedContents = []byte(value.Quoted)\n\t\t\t\t\t\t\t\t} else if value.Value != nil {\n\t\t\t\t\t\t\t\t\t// Re-quote non-ASCII values if output is ASCII-only.\n\t\t\t\t\t\t\t\t\t// Also quote values that haven't been quoted yet\n\t\t\t\t\t\t\t\t\t// (happens when the entire \"sourcesContent\" array is\n\t\t\t\t\t\t\t\t\t// absent and the source has been found on the file\n\t\t\t\t\t\t\t\t\t// system using the \"sources\" array).\n\t\t\t\t\t\t\t\t\tquotedContents = helpers.QuoteForJSON(helpers.UTF16ToString(value.Value), options.ASCIIOnly)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tresult.QuotedContents[i] = quotedContents\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\twaitGroup.Done()\n\t\t\t}(sourceIndex, f, approximateLineCount)\n\t\t}\n\t}\n\n\treturn func() []DataForSourceMap {\n\t\twaitGroup.Wait()\n\t\treturn results\n\t}\n}\n\nfunc (b *Bundle) generateMetadataJSON(results []graph.OutputFile, allReachableFiles []uint32, options *config.Options) string {\n\tsb := strings.Builder{}\n\tsb.WriteString(options.MetafileFormat.MaybeRemoveWhitespace(\"{\\n  \\\"inputs\\\": {\"))\n\n\t// Write inputs\n\tisFirst := true\n\tfor _, sourceIndex := range allReachableFiles {\n\t\tif b.files[sourceIndex].inputFile.OmitFromSourceMapsAndMetafile {\n\t\t\tcontinue\n\t\t}\n\t\tif file := &b.files[sourceIndex]; len(file.jsonMetadataChunk) > 0 {\n\t\t\tif isFirst {\n\t\t\t\tisFirst = false\n\t\t\t\tsb.WriteString(options.MetafileFormat.MaybeRemoveWhitespace(\"\\n    \"))\n\t\t\t} else {\n\t\t\t\tsb.WriteString(options.MetafileFormat.MaybeRemoveWhitespace(\",\\n    \"))\n\t\t\t}\n\t\t\tsb.WriteString(file.jsonMetadataChunk)\n\t\t}\n\t}\n\n\tsb.WriteString(options.MetafileFormat.MaybeRemoveWhitespace(\"\\n  },\\n  \\\"outputs\\\": {\"))\n\n\t// Write outputs\n\tisFirst = true\n\tpathMap := make(map[string]struct{})\n\tfor _, result := range results {\n\t\tif len(result.JSONMetadataChunk) > 0 {\n\t\t\tprettyPaths := resolver.MakePrettyPaths(b.fs, logger.Path{Text: result.AbsPath, Namespace: \"file\"})\n\t\t\tpath := prettyPaths.Select(b.options.MetafilePathStyle)\n\t\t\tif _, ok := pathMap[path]; ok {\n\t\t\t\t// Don't write out the same path twice (can happen with the \"file\" loader)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif isFirst {\n\t\t\t\tisFirst = false\n\t\t\t\tsb.WriteString(options.MetafileFormat.MaybeRemoveWhitespace(\"\\n    \"))\n\t\t\t} else {\n\t\t\t\tsb.WriteString(options.MetafileFormat.MaybeRemoveWhitespace(\",\\n    \"))\n\t\t\t}\n\t\t\tpathMap[path] = struct{}{}\n\t\t\tsb.WriteString(fmt.Sprintf(options.MetafileFormat.MaybeRemoveWhitespace(\"%s: \"), helpers.QuoteForJSON(path, options.ASCIIOnly)))\n\t\t\tsb.WriteString(result.JSONMetadataChunk)\n\t\t}\n\t}\n\n\tsb.WriteString(options.MetafileFormat.MaybeRemoveWhitespace(\"\\n  }\\n}\"))\n\tsb.WriteByte('\\n')\n\treturn sb.String()\n}\n\ntype runtimeCacheKey struct {\n\tunsupportedJSFeatures compat.JSFeature\n\tminifySyntax          bool\n\tminifyIdentifiers     bool\n}\n\ntype runtimeCache struct {\n\tastMap   map[runtimeCacheKey]js_ast.AST\n\tastMutex sync.Mutex\n}\n\nvar globalRuntimeCache runtimeCache\n\nfunc (cache *runtimeCache) parseRuntime(options *config.Options) (source logger.Source, runtimeAST js_ast.AST, ok bool) {\n\tkey := runtimeCacheKey{\n\t\t// All configuration options that the runtime code depends on must go here\n\t\tunsupportedJSFeatures: options.UnsupportedJSFeatures,\n\t\tminifySyntax:          options.MinifySyntax,\n\t\tminifyIdentifiers:     options.MinifyIdentifiers,\n\t}\n\n\t// Determine which source to use\n\tsource = runtime.Source(key.unsupportedJSFeatures)\n\n\t// Cache hit?\n\t(func() {\n\t\tcache.astMutex.Lock()\n\t\tdefer cache.astMutex.Unlock()\n\t\tif cache.astMap != nil {\n\t\t\truntimeAST, ok = cache.astMap[key]\n\t\t}\n\t})()\n\tif ok {\n\t\treturn\n\t}\n\n\t// Cache miss\n\tlog := logger.NewDeferLog(logger.DeferLogAll, nil)\n\truntimeAST, ok = js_parser.Parse(log, source, js_parser.OptionsFromConfig(&config.Options{\n\t\t// These configuration options must only depend on the key\n\t\tUnsupportedJSFeatures: key.unsupportedJSFeatures,\n\t\tMinifySyntax:          key.minifySyntax,\n\t\tMinifyIdentifiers:     key.minifyIdentifiers,\n\n\t\t// Always do tree shaking for the runtime because we never want to\n\t\t// include unnecessary runtime code\n\t\tTreeShaking: true,\n\t}))\n\tif log.HasErrors() {\n\t\tmsgs := \"Internal error: failed to parse runtime:\\n\"\n\t\tfor _, msg := range log.Done() {\n\t\t\tmsgs += msg.String(logger.OutputOptions{IncludeSource: true}, logger.TerminalInfo{})\n\t\t}\n\t\tpanic(msgs[:len(msgs)-1])\n\t}\n\n\t// Cache for next time\n\tif ok {\n\t\tcache.astMutex.Lock()\n\t\tdefer cache.astMutex.Unlock()\n\t\tif cache.astMap == nil {\n\t\t\tcache.astMap = make(map[runtimeCacheKey]js_ast.AST)\n\t\t}\n\t\tcache.astMap[key] = runtimeAST\n\t}\n\treturn\n}\n\n// Returns the path of this file relative to \"outbase\", which is then ready to\n// be joined with the absolute output directory path. The directory and name\n// components are returned separately for convenience.\nfunc PathRelativeToOutbase(\n\tinputFile *graph.InputFile,\n\toptions *config.Options,\n\tfs fs.FS,\n\tavoidIndex bool,\n\tcustomFilePath string,\n) (relDir string, baseName string) {\n\trelDir = \"/\"\n\tabsPath := inputFile.Source.KeyPath.Text\n\n\tif customFilePath != \"\" {\n\t\t// Use the configured output path if present\n\t\tabsPath = customFilePath\n\t\tif !fs.IsAbs(absPath) {\n\t\t\tabsPath = fs.Join(options.AbsOutputBase, absPath)\n\t\t}\n\t} else if inputFile.Source.KeyPath.Namespace != \"file\" {\n\t\t// Come up with a path for virtual paths (i.e. non-file-system paths)\n\t\tdir, base, _ := logger.PlatformIndependentPathDirBaseExt(absPath)\n\t\tif avoidIndex && base == \"index\" {\n\t\t\t_, base, _ = logger.PlatformIndependentPathDirBaseExt(dir)\n\t\t}\n\t\tbaseName = sanitizeFilePathForVirtualModulePath(base)\n\t\treturn\n\t} else {\n\t\t// Heuristic: If the file is named something like \"index.js\", then use\n\t\t// the name of the parent directory instead. This helps avoid the\n\t\t// situation where many chunks are named \"index\" because of people\n\t\t// dynamically-importing npm packages that make use of node's implicit\n\t\t// \"index\" file name feature.\n\t\tif avoidIndex {\n\t\t\tbase := fs.Base(absPath)\n\t\t\tbase = base[:len(base)-len(fs.Ext(base))]\n\t\t\tif base == \"index\" {\n\t\t\t\tabsPath = fs.Dir(absPath)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Try to get a relative path to the base directory\n\trelPath, ok := fs.Rel(options.AbsOutputBase, absPath)\n\tif !ok {\n\t\t// This can fail in some situations such as on different drives on\n\t\t// Windows. In that case we just use the file name.\n\t\tbaseName = fs.Base(absPath)\n\t} else {\n\t\t// Now we finally have a relative path\n\t\trelDir = fs.Dir(relPath) + \"/\"\n\t\tbaseName = fs.Base(relPath)\n\n\t\t// Use platform-independent slashes\n\t\trelDir = strings.ReplaceAll(relDir, \"\\\\\", \"/\")\n\n\t\t// Replace leading \"../\" so we don't try to write outside of the output\n\t\t// directory. This normally can't happen because \"AbsOutputBase\" is\n\t\t// automatically computed to contain all entry point files, but it can\n\t\t// happen if someone sets it manually via the \"outbase\" API option.\n\t\t//\n\t\t// Note that we can't just strip any leading \"../\" because that could\n\t\t// cause two separate entry point paths to collide. For example, there\n\t\t// could be both \"src/index.js\" and \"../src/index.js\" as entry points.\n\t\tdotDotCount := 0\n\t\tfor strings.HasPrefix(relDir[dotDotCount*3:], \"../\") {\n\t\t\tdotDotCount++\n\t\t}\n\t\tif dotDotCount > 0 {\n\t\t\t// The use of \"_.._\" here is somewhat arbitrary but it is unlikely to\n\t\t\t// collide with a folder named by a human and it works on Windows\n\t\t\t// (Windows doesn't like names that end with a \".\"). And not starting\n\t\t\t// with a \".\" means that it will not be hidden on Unix.\n\t\t\trelDir = strings.Repeat(\"_.._/\", dotDotCount) + relDir[dotDotCount*3:]\n\t\t}\n\t\tfor strings.HasSuffix(relDir, \"/\") {\n\t\t\trelDir = relDir[:len(relDir)-1]\n\t\t}\n\t\trelDir = \"/\" + relDir\n\t\tif strings.HasSuffix(relDir, \"/.\") {\n\t\t\trelDir = relDir[:len(relDir)-1]\n\t\t}\n\t}\n\n\t// Strip the file extension if the output path is an input file\n\tif customFilePath == \"\" {\n\t\text := fs.Ext(baseName)\n\t\tbaseName = baseName[:len(baseName)-len(ext)]\n\t}\n\treturn\n}\n\nfunc sanitizeFilePathForVirtualModulePath(path string) string {\n\t// Convert it to a safe file path. See: https://stackoverflow.com/a/31976060\n\tsb := strings.Builder{}\n\tneedsGap := false\n\tfor _, c := range path {\n\t\tswitch c {\n\t\tcase 0:\n\t\t\t// These characters are forbidden on Unix and Windows\n\n\t\tcase '<', '>', ':', '\"', '|', '?', '*':\n\t\t\t// These characters are forbidden on Windows\n\n\t\tdefault:\n\t\t\tif c < 0x20 {\n\t\t\t\t// These characters are forbidden on Windows\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Turn runs of invalid characters into a '_'\n\t\t\tif needsGap {\n\t\t\t\tsb.WriteByte('_')\n\t\t\t\tneedsGap = false\n\t\t\t}\n\n\t\t\tsb.WriteRune(c)\n\t\t\tcontinue\n\t\t}\n\n\t\tif sb.Len() > 0 {\n\t\t\tneedsGap = true\n\t\t}\n\t}\n\n\t// Make sure the name isn't empty\n\tif sb.Len() == 0 {\n\t\treturn \"_\"\n\t}\n\n\t// Note: An extension will be added to this base name, so there is no need to\n\t// avoid forbidden file names such as \"..\" since \".js\" is a valid file name.\n\treturn sb.String()\n}\n"
  },
  {
    "path": "internal/bundler_tests/bundler_css_test.go",
    "content": "package bundler_tests\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n)\n\nvar css_suite = suite{\n\tname: \"css\",\n}\n\nfunc TestCSSEntryPoint(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\tbody {\n\t\t\t\t\tbackground: white;\n\t\t\t\t\tcolor: black }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.css\",\n\t\t},\n\t})\n}\n\nfunc TestCSSAtImportMissing(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"./missing.css\";\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.css\",\n\t\t},\n\t\texpectedScanLog: `entry.css: ERROR: Could not resolve \"./missing.css\"\n`,\n\t})\n}\n\nfunc TestCSSAtImportExternal(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"./internal.css\";\n\t\t\t\t@import \"./external1.css\";\n\t\t\t\t@import \"./external2.css\";\n\t\t\t\t@import \"./charset1.css\";\n\t\t\t\t@import \"./charset2.css\";\n\t\t\t\t@import \"./external5.css\" screen;\n\t\t\t`,\n\t\t\t\"/internal.css\": `\n\t\t\t\t@import \"./external5.css\" print;\n\t\t\t\t.before { color: red }\n\t\t\t`,\n\t\t\t\"/charset1.css\": `\n\t\t\t\t@charset \"UTF-8\";\n\t\t\t\t@import \"./external3.css\";\n\t\t\t\t@import \"./external4.css\";\n\t\t\t\t@import \"./external5.css\";\n\t\t\t\t@import \"https://www.example.com/style1.css\";\n\t\t\t\t@import \"https://www.example.com/style2.css\";\n\t\t\t\t@import \"https://www.example.com/style3.css\" print;\n\t\t\t\t.middle { color: green }\n\t\t\t`,\n\t\t\t\"/charset2.css\": `\n\t\t\t\t@charset \"UTF-8\";\n\t\t\t\t@import \"./external3.css\";\n\t\t\t\t@import \"./external5.css\" screen;\n\t\t\t\t@import \"https://www.example.com/style1.css\";\n\t\t\t\t@import \"https://www.example.com/style3.css\";\n\t\t\t\t.after { color: blue }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPostResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"/external1.css\": true,\n\t\t\t\t\t\"/external2.css\": true,\n\t\t\t\t\t\"/external3.css\": true,\n\t\t\t\t\t\"/external4.css\": true,\n\t\t\t\t\t\"/external5.css\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestCSSAtImport(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"./a.css\";\n\t\t\t\t@import \"./b.css\";\n\t\t\t\t.entry { color: red }\n\t\t\t`,\n\t\t\t\"/a.css\": `\n\t\t\t\t@import \"./shared.css\";\n\t\t\t\t.a { color: green }\n\t\t\t`,\n\t\t\t\"/b.css\": `\n\t\t\t\t@import \"./shared.css\";\n\t\t\t\t.b { color: blue }\n\t\t\t`,\n\t\t\t\"/shared.css\": `\n\t\t\t\t.shared { color: black }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.css\",\n\t\t},\n\t})\n}\n\nfunc TestCSSFromJSMissingImport(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {missing} from \"./a.css\"\n\t\t\t\tconsole.log(missing)\n\t\t\t`,\n\t\t\t\"/a.css\": `\n\t\t\t\t.a { color: red }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedCompileLog: `entry.js: ERROR: No matching export in \"a.css\" for import \"missing\"\n`,\n\t})\n}\n\nfunc TestCSSFromJSMissingStarImport(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from \"./a.css\"\n\t\t\t\tconsole.log(ns.missing)\n\t\t\t`,\n\t\t\t\"/a.css\": `\n\t\t\t\t.a { color: red }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedCompileLog: `entry.js: WARNING: Import \"missing\" will always be undefined because there is no matching export in \"a.css\"\n`,\n\t})\n}\n\nfunc TestImportGlobalCSSFromJS(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"./a.js\"\n\t\t\t\timport \"./b.js\"\n\t\t\t`,\n\t\t\t\"/a.js\": `\n\t\t\t\timport * as stylesA from \"./a.css\"\n\t\t\t\tconsole.log('a', stylesA.a, stylesA.default.a)\n\t\t\t`,\n\t\t\t\"/a.css\": `\n\t\t\t\t.a { color: red }\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport * as stylesB from \"./b.css\"\n\t\t\t\tconsole.log('b', stylesB.b, stylesB.default.b)\n\t\t\t`,\n\t\t\t\"/b.css\": `\n\t\t\t\t.b { color: blue }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedCompileLog: `a.js: WARNING: Import \"a\" will always be undefined because there is no matching export in \"a.css\"\nb.js: WARNING: Import \"b\" will always be undefined because there is no matching export in \"b.css\"\n`,\n\t})\n}\n\nfunc TestImportLocalCSSFromJS(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"./a.js\"\n\t\t\t\timport \"./b.js\"\n\t\t\t`,\n\t\t\t\"/a.js\": `\n\t\t\t\timport * as stylesA from \"./dir1/style.css\"\n\t\t\t\tconsole.log('file 1', stylesA.button, stylesA.default.a)\n\t\t\t`,\n\t\t\t\"/dir1/style.css\": `\n\t\t\t\t.a { color: red }\n\t\t\t\t.button { display: none }\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport * as stylesB from \"./dir2/style.css\"\n\t\t\t\tconsole.log('file 2', stylesB.button, stylesB.default.b)\n\t\t\t`,\n\t\t\t\"/dir2/style.css\": `\n\t\t\t\t.b { color: blue }\n\t\t\t\t.button { display: none }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".css\": config.LoaderLocalCSS,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestImportLocalCSSFromJSMinifyIdentifiers(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"./a.js\"\n\t\t\t\timport \"./b.js\"\n\t\t\t`,\n\t\t\t\"/a.js\": `\n\t\t\t\timport * as stylesA from \"./dir1/style.css\"\n\t\t\t\tconsole.log('file 1', stylesA.button, stylesA.default.a)\n\t\t\t`,\n\t\t\t\"/dir1/style.css\": `\n\t\t\t\t.a { color: red }\n\t\t\t\t.button { display: none }\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport * as stylesB from \"./dir2/style.css\"\n\t\t\t\tconsole.log('file 2', stylesB.button, stylesB.default.b)\n\t\t\t`,\n\t\t\t\"/dir2/style.css\": `\n\t\t\t\t.b { color: blue }\n\t\t\t\t.button { display: none }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".css\": config.LoaderLocalCSS,\n\t\t\t},\n\t\t\tMinifyIdentifiers: true,\n\t\t},\n\t})\n}\n\nfunc TestImportLocalCSSFromJSMinifyIdentifiersAvoidGlobalNames(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"./global.css\"\n\t\t\t\timport \"./local.module.css\"\n\t\t\t`,\n\t\t\t\"/global.css\": `\n\t\t\t\t:is(.a, .b, .c, .d, .e, .f, .g, .h, .i, .j, .k, .l, .m, .n, .o, .p, .q, .r, .s, .t, .u, .v, .w, .x, .y, .z),\n\t\t\t\t:is(.A, .B, .C, .D, .E, .F, .G, .H, .I, .J, .K, .L, .M, .N, .O, .P, .Q, .R, .S, .T, .U, .V, .W, .X, .Y, .Z),\n\t\t\t\t._ { color: red }\n\t\t\t`,\n\t\t\t\"/local.module.css\": `\n\t\t\t\t.rename-this { color: blue }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":         config.LoaderJS,\n\t\t\t\t\".css\":        config.LoaderCSS,\n\t\t\t\t\".module.css\": config.LoaderLocalCSS,\n\t\t\t},\n\t\t\tMinifyIdentifiers: true,\n\t\t},\n\t})\n}\n\n// See: https://github.com/evanw/esbuild/issues/3295\nfunc TestImportLocalCSSFromJSMinifyIdentifiersMultipleEntryPoints(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport { foo, bar } from \"./a.module.css\";\n\t\t\t\tconsole.log(foo, bar);\n\t\t\t`,\n\t\t\t\"/a.module.css\": `\n\t\t\t\t.foo { color: #001; }\n\t\t\t\t.bar { color: #002; }\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport { foo, bar } from \"./b.module.css\";\n\t\t\t\tconsole.log(foo, bar);\n\t\t\t`,\n\t\t\t\"/b.module.css\": `\n\t\t\t\t.foo { color: #003; }\n\t\t\t\t.bar { color: #004; }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tAbsOutputDir:      \"/out\",\n\t\t\tMinifyIdentifiers: true,\n\t\t},\n\t})\n}\n\nfunc TestImportCSSFromJSLocalVsGlobal(t *testing.T) {\n\tcss := `\n\t\t.top_level { color: #000 }\n\n\t\t:global(.GLOBAL) { color: #001 }\n\t\t:local(.local) { color: #002 }\n\n\t\tdiv:global(.GLOBAL) { color: #003 }\n\t\tdiv:local(.local) { color: #004 }\n\n\t\t.top_level:global(div) { color: #005 }\n\t\t.top_level:local(div) { color: #006 }\n\n\t\t:global(div.GLOBAL) { color: #007 }\n\t\t:local(div.local) { color: #008 }\n\n\t\tdiv:global(span.GLOBAL) { color: #009 }\n\t\tdiv:local(span.local) { color: #00A }\n\n\t\tdiv:global(#GLOBAL_A.GLOBAL_B.GLOBAL_C):local(.local_a.local_b#local_c) { color: #00B }\n\t\tdiv:global(#GLOBAL_A .GLOBAL_B .GLOBAL_C):local(.local_a .local_b #local_c) { color: #00C }\n\n\t\t.nested {\n\t\t\t:global(&.GLOBAL) { color: #00D }\n\t\t\t:local(&.local) { color: #00E }\n\n\t\t\t&:global(.GLOBAL) { color: #00F }\n\t\t\t&:local(.local) { color: #010 }\n\t\t}\n\n\t\t:global(.GLOBAL_A .GLOBAL_B) { color: #011 }\n\t\t:local(.local_a .local_b) { color: #012 }\n\n\t\tdiv:global(.GLOBAL_A .GLOBAL_B):hover { color: #013 }\n\t\tdiv:local(.local_a .local_b):hover { color: #014 }\n\n\t\tdiv :global(.GLOBAL_A .GLOBAL_B) span { color: #015 }\n\t\tdiv :local(.local_a .local_b) span { color: #016 }\n\n\t\tdiv > :global(.GLOBAL_A ~ .GLOBAL_B) + span { color: #017 }\n\t\tdiv > :local(.local_a ~ .local_b) + span { color: #018 }\n\n\t\tdiv:global(+ .GLOBAL_A):hover { color: #019 }\n\t\tdiv:local(+ .local_a):hover { color: #01A }\n\n\t\t:global.GLOBAL:local.local { color: #01B }\n\t\t:global .GLOBAL :local .local { color: #01C }\n\n\t\t:global {\n\t\t\t.GLOBAL {\n\t\t\t\tbefore: outer;\n\t\t\t\t:local {\n\t\t\t\t\tbefore: inner;\n\t\t\t\t\t.local {\n\t\t\t\t\t\tcolor: #01D;\n\t\t\t\t\t}\n\t\t\t\t\tafter: inner;\n\t\t\t\t}\n\t\t\t\tafter: outer;\n\t\t\t}\n\t\t}\n\t`\n\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport normalStyles from \"./normal.css\"\n\t\t\t\timport globalStyles from \"./LOCAL.global-css\"\n\t\t\t\timport localStyles from \"./LOCAL.local-css\"\n\n\t\t\t\tconsole.log('should be empty:', normalStyles)\n\t\t\t\tconsole.log('fewer local names:', globalStyles)\n\t\t\t\tconsole.log('more local names:', localStyles)\n\t\t\t`,\n\t\t\t\"/normal.css\":       css,\n\t\t\t\"/LOCAL.global-css\": css,\n\t\t\t\"/LOCAL.local-css\":  css,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":         config.LoaderJS,\n\t\t\t\t\".css\":        config.LoaderCSS,\n\t\t\t\t\".global-css\": config.LoaderGlobalCSS,\n\t\t\t\t\".local-css\":  config.LoaderLocalCSS,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestImportCSSFromJSLowerBareLocalAndGlobal(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport styles from \"./styles.css\"\n\t\t\t\tconsole.log(styles)\n\t\t\t`,\n\t\t\t\"/styles.css\": `\n\t\t\t\t.before { color: #000 }\n\t\t\t\t:local { .button { color: #000 } }\n\t\t\t\t.after { color: #000 }\n\n\t\t\t\t.before { color: #001 }\n\t\t\t\t:global { .button { color: #001 } }\n\t\t\t\t.after { color: #001 }\n\n\t\t\t\tdiv { :local { .button { color: #002 } } }\n\t\t\t\tdiv { :global { .button { color: #003 } } }\n\n\t\t\t\t:local(:global) { color: #004 }\n\t\t\t\t:global(:local) { color: #005 }\n\n\t\t\t\t:local(:global) { .button { color: #006 } }\n\t\t\t\t:global(:local) { .button { color: #007 } }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".css\": config.LoaderLocalCSS,\n\t\t\t},\n\t\t\tUnsupportedCSSFeatures: compat.Nesting,\n\t\t},\n\t})\n}\n\nfunc TestImportCSSFromJSLocalAtKeyframes(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport styles from \"./styles.css\"\n\t\t\t\tconsole.log(styles)\n\t\t\t`,\n\t\t\t\"/styles.css\": `\n\t\t\t\t@keyframes local_name { to { color: red } }\n\n\t\t\t\tdiv :global { animation-name: none }\n\t\t\t\tdiv :local { animation-name: none }\n\n\t\t\t\tdiv :global { animation-name: global_name }\n\t\t\t\tdiv :local { animation-name: local_name }\n\n\t\t\t\tdiv :global { animation-name: global_name1, none, global_name2, Inherit, INITIAL, revert, revert-layer, unset }\n\t\t\t\tdiv :local { animation-name: local_name1, none, local_name2, Inherit, INITIAL, revert, revert-layer, unset }\n\n\t\t\t\tdiv :global { animation: 2s infinite global_name }\n\t\t\t\tdiv :local { animation: 2s infinite local_name }\n\n\t\t\t\t/* Someone wanted to be able to name their animations \"none\" */\n\t\t\t\t@keyframes \"none\" { to { color: red } }\n\t\t\t\tdiv :global { animation-name: \"none\" }\n\t\t\t\tdiv :local { animation-name: \"none\" }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".css\": config.LoaderLocalCSS,\n\t\t\t},\n\t\t\tUnsupportedCSSFeatures: compat.Nesting,\n\t\t},\n\t})\n}\n\nfunc TestImportCSSFromJSLocalAtCounterStyle(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport list_style_type from \"./list_style_type.css\"\n\t\t\t\timport list_style from \"./list_style.css\"\n\t\t\t\tconsole.log(list_style_type, list_style)\n\t\t\t`,\n\t\t\t\"/list_style_type.css\": `\n\t\t\t\t@counter-style local { symbols: A B C }\n\n\t\t\t\tdiv :global { list-style-type: GLOBAL }\n\t\t\t\tdiv :local { list-style-type: local }\n\n\t\t\t\t/* Must not accept invalid type values */\n\t\t\t\tdiv :local { list-style-type: none }\n\t\t\t\tdiv :local { list-style-type: INITIAL }\n\t\t\t\tdiv :local { list-style-type: decimal }\n\t\t\t\tdiv :local { list-style-type: disc }\n\t\t\t\tdiv :local { list-style-type: SQUARE }\n\t\t\t\tdiv :local { list-style-type: circle }\n\t\t\t\tdiv :local { list-style-type: disclosure-OPEN }\n\t\t\t\tdiv :local { list-style-type: DISCLOSURE-closed }\n\t\t\t\tdiv :local { list-style-type: LAO }\n\t\t\t\tdiv :local { list-style-type: \"\\1F44D\" }\n\t\t\t`,\n\n\t\t\t\"/list_style.css\": `\n\t\t\t\t@counter-style local { symbols: A B C }\n\n\t\t\t\tdiv :global { list-style: GLOBAL }\n\t\t\t\tdiv :local { list-style: local }\n\n\t\t\t\t/* The first one is the type */\n\t\t\t\tdiv :local { list-style: local none }\n\t\t\t\tdiv :local { list-style: local url(http://) }\n\t\t\t\tdiv :local { list-style: local linear-gradient(red, green) }\n\t\t\t\tdiv :local { list-style: local inside }\n\t\t\t\tdiv :local { list-style: local outside }\n\n\t\t\t\t/* The second one is the type */\n\t\t\t\tdiv :local { list-style: none local }\n\t\t\t\tdiv :local { list-style: url(http://) local }\n\t\t\t\tdiv :local { list-style: linear-gradient(red, green) local }\n\t\t\t\tdiv :local { list-style: local inside }\n\t\t\t\tdiv :local { list-style: local outside }\n\t\t\t\tdiv :local { list-style: inside inside }\n\t\t\t\tdiv :local { list-style: inside outside }\n\t\t\t\tdiv :local { list-style: outside inside }\n\t\t\t\tdiv :local { list-style: outside outside }\n\n\t\t\t\t/* The type is set to \"none\" here */\n\t\t\t\tdiv :local { list-style: url(http://) none invalid }\n\t\t\t\tdiv :local { list-style: linear-gradient(red, green) none invalid }\n\n\t\t\t\t/* Must not accept invalid type values */\n\t\t\t\tdiv :local { list-style: INITIAL }\n\t\t\t\tdiv :local { list-style: decimal }\n\t\t\t\tdiv :local { list-style: disc }\n\t\t\t\tdiv :local { list-style: SQUARE }\n\t\t\t\tdiv :local { list-style: circle }\n\t\t\t\tdiv :local { list-style: disclosure-OPEN }\n\t\t\t\tdiv :local { list-style: DISCLOSURE-closed }\n\t\t\t\tdiv :local { list-style: LAO }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".css\": config.LoaderLocalCSS,\n\t\t\t},\n\t\t\tUnsupportedCSSFeatures: compat.Nesting,\n\t\t},\n\t})\n}\n\nfunc TestImportCSSFromJSLocalAtContainer(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport styles from \"./styles.css\"\n\t\t\t\tconsole.log(styles)\n\t\t\t`,\n\t\t\t\"/styles.css\": `\n\t\t\t\t@container not (max-width: 100px) { div { color: red } }\n\t\t\t\t@container local (max-width: 100px) { div { color: red } }\n\t\t\t\t@container local not (max-width: 100px) { div { color: red } }\n\t\t\t\t@container local (max-width: 100px) or (min-height: 100px) { div { color: red } }\n\t\t\t\t@container local (max-width: 100px) and (min-height: 100px) { div { color: red } }\n\t\t\t\t@container general_enclosed(max-width: 100px) { div { color: red } }\n\t\t\t\t@container local general_enclosed(max-width: 100px) { div { color: red } }\n\n\t\t\t\tdiv :global { container-name: NONE initial }\n\t\t\t\tdiv :local { container-name: none INITIAL }\n\t\t\t\tdiv :global { container-name: GLOBAL1 GLOBAL2 }\n\t\t\t\tdiv :local { container-name: local1 local2 }\n\n\t\t\t\tdiv :global { container: none }\n\t\t\t\tdiv :local { container: NONE }\n\t\t\t\tdiv :global { container: NONE / size }\n\t\t\t\tdiv :local { container: none / size }\n\n\t\t\t\tdiv :global { container: GLOBAL1 GLOBAL2 }\n\t\t\t\tdiv :local { container: local1 local2 }\n\t\t\t\tdiv :global { container: GLOBAL1 GLOBAL2 / size }\n\t\t\t\tdiv :local { container: local1 local2 / size }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".css\": config.LoaderLocalCSS,\n\t\t\t},\n\t\t\tUnsupportedCSSFeatures: compat.Nesting,\n\t\t},\n\t})\n}\n\nfunc TestImportCSSFromJSNthIndexLocal(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport styles from \"./styles.css\"\n\t\t\t\tconsole.log(styles)\n\t\t\t`,\n\t\t\t\"/styles.css\": `\n\t\t\t\t:nth-child(2n of .local) { color: #000 }\n\t\t\t\t:nth-child(2n of :local(#local), :global(.GLOBAL)) { color: #001 }\n\t\t\t\t:nth-child(2n of .local1 :global .GLOBAL1, .GLOBAL2 :local .local2) { color: #002 }\n\t\t\t\t.local1, :nth-child(2n of :global .GLOBAL), .local2 { color: #003 }\n\n\t\t\t\t:nth-last-child(2n of .local) { color: #000 }\n\t\t\t\t:nth-last-child(2n of :local(#local), :global(.GLOBAL)) { color: #001 }\n\t\t\t\t:nth-last-child(2n of .local1 :global .GLOBAL1, .GLOBAL2 :local .local2) { color: #002 }\n\t\t\t\t.local1, :nth-last-child(2n of :global .GLOBAL), .local2 { color: #003 }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".css\": config.LoaderLocalCSS,\n\t\t\t},\n\t\t\tUnsupportedCSSFeatures: compat.Nesting,\n\t\t},\n\t})\n}\n\nfunc TestImportCSSFromJSComposes(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport styles from \"./styles.module.css\"\n\t\t\t\tconsole.log(styles)\n\t\t\t`,\n\t\t\t\"/global.css\": `\n\t\t\t\t.GLOBAL1 {\n\t\t\t\t\tcolor: black;\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/styles.module.css\": `\n\t\t\t\t@import \"global.css\";\n\t\t\t\t.local0 {\n\t\t\t\t\tcomposes: local1;\n\t\t\t\t\t:global {\n\t\t\t\t\t\tcomposes: GLOBAL1 GLOBAL2;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t.local0 {\n\t\t\t\t\tcomposes: GLOBAL2 GLOBAL3 from global;\n\t\t\t\t\tcomposes: local1 local2;\n\t\t\t\t\tbackground: green;\n\t\t\t\t}\n\t\t\t\t.local0 :global {\n\t\t\t\t\tcomposes: GLOBAL4;\n\t\t\t\t}\n\t\t\t\t.local3 {\n\t\t\t\t\tborder: 1px solid black;\n\t\t\t\t\tcomposes: local4;\n\t\t\t\t}\n\t\t\t\t.local4 {\n\t\t\t\t\topacity: 0.5;\n\t\t\t\t}\n\t\t\t\t.local1 {\n\t\t\t\t\tcolor: red;\n\t\t\t\t\tcomposes: local3;\n\t\t\t\t}\n\t\t\t\t.fromOtherFile {\n\t\t\t\t\tcomposes: local0 from \"other1.module.css\";\n\t\t\t\t\tcomposes: local0 from \"other2.module.css\";\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/other1.module.css\": `\n\t\t\t\t.local0 {\n\t\t\t\t\tcomposes: base1 base2 from \"base.module.css\";\n\t\t\t\t\tcolor: blue;\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/other2.module.css\": `\n\t\t\t\t.local0 {\n\t\t\t\t\tcomposes: base1 base3 from \"base.module.css\";\n\t\t\t\t\tbackground: purple;\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/base.module.css\": `\n\t\t\t\t.base1 {\n\t\t\t\t\tcursor: pointer;\n\t\t\t\t}\n\t\t\t\t.base2 {\n\t\t\t\t\tdisplay: inline;\n\t\t\t\t}\n\t\t\t\t.base3 {\n\t\t\t\t\tfloat: left;\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":         config.LoaderJS,\n\t\t\t\t\".css\":        config.LoaderCSS,\n\t\t\t\t\".module.css\": config.LoaderLocalCSS,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestImportCSSFromJSComposesFromMissingImport(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport styles from \"./styles.module.css\"\n\t\t\t\tconsole.log(styles)\n\t\t\t`,\n\t\t\t\"/styles.module.css\": `\n\t\t\t\t.foo {\n\t\t\t\t\tcomposes: x from \"file.module.css\";\n\t\t\t\t\tcomposes: y from \"file.module.css\";\n\t\t\t\t\tcomposes: z from \"file.module.css\";\n\t\t\t\t\tcomposes: x from \"file.css\";\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/file.module.css\": `\n\t\t\t\t.x {\n\t\t\t\t\tcolor: red;\n\t\t\t\t}\n\t\t\t\t:global(.y) {\n\t\t\t\t\tcolor: blue;\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/file.css\": `\n\t\t\t\t.x {\n\t\t\t\t\tcolor: red;\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":         config.LoaderJS,\n\t\t\t\t\".module.css\": config.LoaderLocalCSS,\n\t\t\t\t\".css\":        config.LoaderCSS,\n\t\t\t},\n\t\t},\n\t\texpectedCompileLog: `styles.module.css: ERROR: Cannot use global name \"y\" with \"composes\"\nfile.module.css: NOTE: The global name \"y\" is defined here:\nNOTE: Use the \":local\" selector to change \"y\" into a local name.\nstyles.module.css: ERROR: The name \"z\" never appears in \"file.module.css\"\nstyles.module.css: ERROR: Cannot use global name \"x\" with \"composes\"\nfile.css: NOTE: The global name \"x\" is defined here:\nNOTE: Use the \"local-css\" loader for \"file.css\" to enable local names.\n`,\n\t})\n}\n\nfunc TestImportCSSFromJSComposesFromNotCSS(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport styles from \"./styles.css\"\n\t\t\t\tconsole.log(styles)\n\t\t\t`,\n\t\t\t\"/styles.css\": `\n\t\t\t\t.foo {\n\t\t\t\t\tcomposes: bar from \"file.txt\";\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/file.txt\": `\n\t\t\t\t.bar {\n\t\t\t\t\tcolor: red;\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".css\": config.LoaderLocalCSS,\n\t\t\t\t\".txt\": config.LoaderText,\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `styles.css: ERROR: Cannot use \"composes\" with \"file.txt\"\nNOTE: You can only use \"composes\" with CSS files and \"file.txt\" is not a CSS file (it was loaded with the \"text\" loader).\n`,\n\t})\n}\n\nfunc TestImportCSSFromJSComposesCircular(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport styles from \"./styles.css\"\n\t\t\t\tconsole.log(styles)\n\t\t\t`,\n\t\t\t\"/styles.css\": `\n\t\t\t\t.foo {\n\t\t\t\t\tcomposes: bar;\n\t\t\t\t}\n\t\t\t\t.bar {\n\t\t\t\t\tcomposes: foo;\n\t\t\t\t}\n\t\t\t\t.baz {\n\t\t\t\t\tcomposes: baz;\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".css\": config.LoaderLocalCSS,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestImportCSSFromJSComposesFromCircular(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport styles from \"./styles.css\"\n\t\t\t\tconsole.log(styles)\n\t\t\t`,\n\t\t\t\"/styles.css\": `\n\t\t\t\t.foo {\n\t\t\t\t\tcomposes: bar from \"other.css\";\n\t\t\t\t}\n\t\t\t\t.bar {\n\t\t\t\t\tcomposes: bar from \"styles.css\";\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/other.css\": `\n\t\t\t\t.bar {\n\t\t\t\t\tcomposes: foo from \"styles.css\";\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".css\": config.LoaderLocalCSS,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestImportCSSFromJSComposesFromUndefined(t *testing.T) {\n\tnote := \"NOTE: The specification of \\\"composes\\\" does not define an order when class declarations from separate files are composed together. \" +\n\t\t\"The value of the \\\"zoom\\\" property for \\\"foo\\\" may change unpredictably as the code is edited. \" +\n\t\t\"Make sure that all definitions of \\\"zoom\\\" for \\\"foo\\\" are in a single file.\"\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport styles from \"./styles.css\"\n\t\t\t\tconsole.log(styles)\n\t\t\t`,\n\t\t\t\"/styles.css\": `\n\t\t\t\t@import \"well-defined.css\";\n\t\t\t\t@import \"undefined/case1.css\";\n\t\t\t\t@import \"undefined/case2.css\";\n\t\t\t\t@import \"undefined/case3.css\";\n\t\t\t\t@import \"undefined/case4.css\";\n\t\t\t\t@import \"undefined/case5.css\";\n\t\t\t`,\n\t\t\t\"/well-defined.css\": `\n\t\t\t\t.z1 { composes: z2; zoom: 1; }\n\t\t\t\t.z2 { zoom: 2; }\n\n\t\t\t\t.z4 { zoom: 4; }\n\t\t\t\t.z3 { composes: z4; zoom: 3; }\n\n\t\t\t\t.z5 { composes: foo bar from \"file-1.css\"; }\n\t\t\t`,\n\t\t\t\"/undefined/case1.css\": `\n\t\t\t\t.foo {\n\t\t\t\t\tcomposes: foo from \"../file-1.css\";\n\t\t\t\t\tzoom: 2;\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/undefined/case2.css\": `\n\t\t\t\t.foo {\n\t\t\t\t\tcomposes: foo from \"../file-1.css\";\n\t\t\t\t\tcomposes: foo from \"../file-2.css\";\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/undefined/case3.css\": `\n\t\t\t\t.foo { composes: nested1 nested2; }\n\t\t\t\t.nested1 { zoom: 3; }\n\t\t\t\t.nested2 { composes: foo from \"../file-2.css\"; }\n\t\t\t`,\n\t\t\t\"/undefined/case4.css\": `\n\t\t\t\t.foo { composes: nested1 nested2; }\n\t\t\t\t.nested1 { composes: foo from \"../file-1.css\"; }\n\t\t\t\t.nested2 { zoom: 3; }\n\t\t\t`,\n\t\t\t\"/undefined/case5.css\": `\n\t\t\t\t.foo { composes: nested1 nested2; }\n\t\t\t\t.nested1 { composes: foo from \"../file-1.css\"; }\n\t\t\t\t.nested2 { composes: foo from \"../file-2.css\"; }\n\t\t\t`,\n\t\t\t\"/file-1.css\": `\n\t\t\t\t.foo { zoom: 1; }\n\t\t\t\t.bar { zoom: 2; }\n\t\t\t`,\n\t\t\t\"/file-2.css\": `\n\t\t\t\t.foo { zoom: 2; }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".css\": config.LoaderLocalCSS,\n\t\t\t},\n\t\t},\n\t\texpectedCompileLog: `undefined/case1.css: WARNING: The value of \"zoom\" in the \"foo\" class is undefined\nfile-1.css: NOTE: The first definition of \"zoom\" is here:\nundefined/case1.css: NOTE: The second definition of \"zoom\" is here:\n` + note + `\nundefined/case2.css: WARNING: The value of \"zoom\" in the \"foo\" class is undefined\nfile-1.css: NOTE: The first definition of \"zoom\" is here:\nfile-2.css: NOTE: The second definition of \"zoom\" is here:\n` + note + `\nundefined/case3.css: WARNING: The value of \"zoom\" in the \"foo\" class is undefined\nundefined/case3.css: NOTE: The first definition of \"zoom\" is here:\nfile-2.css: NOTE: The second definition of \"zoom\" is here:\n` + note + `\nundefined/case4.css: WARNING: The value of \"zoom\" in the \"foo\" class is undefined\nfile-1.css: NOTE: The first definition of \"zoom\" is here:\nundefined/case4.css: NOTE: The second definition of \"zoom\" is here:\n` + note + `\nundefined/case5.css: WARNING: The value of \"zoom\" in the \"foo\" class is undefined\nfile-1.css: NOTE: The first definition of \"zoom\" is here:\nfile-2.css: NOTE: The second definition of \"zoom\" is here:\n` + note + `\n`,\n\t})\n}\n\nfunc TestImportCSSFromJSWriteToStdout(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"./entry.css\"\n\t\t\t`,\n\t\t\t\"/entry.css\": `\n\t\t\t\t.entry { color: red }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tWriteToStdout: true,\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Cannot import \"entry.css\" into a JavaScript file without an output path configured\n`,\n\t})\n}\n\nfunc TestImportJSFromCSS(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport default 123\n\t\t\t`,\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"./entry.js\";\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedScanLog: `entry.css: ERROR: Cannot import \"entry.js\" into a CSS file\nNOTE: An \"@import\" rule can only be used to import another CSS file and \"entry.js\" is not a CSS file (it was loaded with the \"js\" loader).\n`,\n\t})\n}\n\nfunc TestImportJSONFromCSS(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.json\": `\n\t\t\t\t{}\n\t\t\t`,\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"./entry.json\";\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedScanLog: `entry.css: ERROR: Cannot import \"entry.json\" into a CSS file\nNOTE: An \"@import\" rule can only be used to import another CSS file and \"entry.json\" is not a CSS file (it was loaded with the \"json\" loader).\n`,\n\t})\n}\n\nfunc TestMissingImportURLInCSS(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entry.css\": `\n\t\t\t\ta { background: url(./one.png); }\n\t\t\t\tb { background: url(\"./two.png\"); }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/src/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedScanLog: `src/entry.css: ERROR: Could not resolve \"./one.png\"\nsrc/entry.css: ERROR: Could not resolve \"./two.png\"\n`,\n\t})\n}\n\nfunc TestExternalImportURLInCSS(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entry.css\": `\n\t\t\t\tdiv:after {\n\t\t\t\t\tcontent: 'If this is recognized, the path should become \"../src/external.png\"';\n\t\t\t\t\tbackground: url(./external.png);\n\t\t\t\t}\n\n\t\t\t\t/* These URLs should be external automatically */\n\t\t\t\ta { background: url(http://example.com/images/image.png) }\n\t\t\t\tb { background: url(https://example.com/images/image.png) }\n\t\t\t\tc { background: url(//example.com/images/image.png) }\n\t\t\t\td { background: url(data:image/png;base64,iVBORw0KGgo=) }\n\t\t\t\tpath { fill: url(#filter) }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/src/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPostResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"/src/external.png\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestInvalidImportURLInCSS(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\ta {\n\t\t\t\t\tbackground: url(./js.js);\n\t\t\t\t\tbackground: url(\"./jsx.jsx\");\n\t\t\t\t\tbackground: url(./ts.ts);\n\t\t\t\t\tbackground: url('./tsx.tsx');\n\t\t\t\t\tbackground: url(./json.json);\n\t\t\t\t\tbackground: url(./css.css);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/js.js\":     `export default 123`,\n\t\t\t\"/jsx.jsx\":   `export default 123`,\n\t\t\t\"/ts.ts\":     `export default 123`,\n\t\t\t\"/tsx.tsx\":   `export default 123`,\n\t\t\t\"/json.json\": `{ \"test\": true }`,\n\t\t\t\"/css.css\":   `a { color: red }`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedScanLog: `entry.css: ERROR: Cannot use \"js.js\" as a URL\nNOTE: You can't use a \"url()\" token to reference the file \"js.js\" because it was loaded with the \"js\" loader, which doesn't provide a URL to embed in the resulting CSS.\nentry.css: ERROR: Cannot use \"jsx.jsx\" as a URL\nNOTE: You can't use a \"url()\" token to reference the file \"jsx.jsx\" because it was loaded with the \"jsx\" loader, which doesn't provide a URL to embed in the resulting CSS.\nentry.css: ERROR: Cannot use \"ts.ts\" as a URL\nNOTE: You can't use a \"url()\" token to reference the file \"ts.ts\" because it was loaded with the \"ts\" loader, which doesn't provide a URL to embed in the resulting CSS.\nentry.css: ERROR: Cannot use \"tsx.tsx\" as a URL\nNOTE: You can't use a \"url()\" token to reference the file \"tsx.tsx\" because it was loaded with the \"tsx\" loader, which doesn't provide a URL to embed in the resulting CSS.\nentry.css: ERROR: Cannot use \"json.json\" as a URL\nNOTE: You can't use a \"url()\" token to reference the file \"json.json\" because it was loaded with the \"json\" loader, which doesn't provide a URL to embed in the resulting CSS.\nentry.css: ERROR: Cannot use \"css.css\" as a URL\nNOTE: You can't use a \"url()\" token to reference a CSS file, and \"css.css\" is a CSS file (it was loaded with the \"css\" loader).\n`,\n\t})\n}\n\nfunc TestTextImportURLInCSSText(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\ta {\n\t\t\t\t\tbackground: url(./example.txt);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/example.txt\": `This is some text.`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestDataURLImportURLInCSS(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\ta {\n\t\t\t\t\tbackground: url(./example.png);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/example.png\": \"\\x89\\x50\\x4E\\x47\\x0D\\x0A\\x1A\\x0A\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t\t\".png\": config.LoaderDataURL,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestBinaryImportURLInCSS(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\ta {\n\t\t\t\t\tbackground: url(./example.png);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/example.png\": \"\\x89\\x50\\x4E\\x47\\x0D\\x0A\\x1A\\x0A\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t\t\".png\": config.LoaderBinary,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestBase64ImportURLInCSS(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\ta {\n\t\t\t\t\tbackground: url(./example.png);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/example.png\": \"\\x89\\x50\\x4E\\x47\\x0D\\x0A\\x1A\\x0A\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t\t\".png\": config.LoaderBase64,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestFileImportURLInCSS(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"./one.css\";\n\t\t\t\t@import \"./two.css\";\n\t\t\t`,\n\t\t\t\"/one.css\": `\n\t\t\t\ta { background: url(./example.data) }\n\t\t\t`,\n\t\t\t\"/two.css\": `\n\t\t\t\tb { background: url(./example.data) }\n\t\t\t`,\n\t\t\t\"/example.data\": \"This is some data.\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\":  config.LoaderCSS,\n\t\t\t\t\".data\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestIgnoreURLsInAtRulePrelude(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t/* This should not generate a path resolution error */\n\t\t\t\t@supports (background: url(ignored.png)) {\n\t\t\t\t\ta { color: red }\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestPackageURLsInCSS(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t  @import \"test.css\";\n\n\t\t\t\ta { background: url(a/1.png); }\n\t\t\t\tb { background: url(b/2.png); }\n\t\t\t\tc { background: url(c/3.png); }\n\t\t\t`,\n\t\t\t\"/test.css\":             `.css { color: red }`,\n\t\t\t\"/a/1.png\":              `a-1`,\n\t\t\t\"/node_modules/b/2.png\": `b-2-node_modules`,\n\t\t\t\"/c/3.png\":              `c-3`,\n\t\t\t\"/node_modules/c/3.png\": `c-3-node_modules`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t\t\".png\": config.LoaderBase64,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestCSSAtImportExtensionOrderCollision(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t// This should avoid picking \".js\" because it's explicitly configured as non-CSS\n\t\t\t\"/entry.css\": `@import \"./test\";`,\n\t\t\t\"/test.js\":   `console.log('js')`,\n\t\t\t\"/test.css\":  `.css { color: red }`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:           config.ModeBundle,\n\t\t\tAbsOutputFile:  \"/out.css\",\n\t\t\tExtensionOrder: []string{\".js\", \".css\"},\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestCSSAtImportExtensionOrderCollisionUnsupported(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t// This still shouldn't pick \".js\" even though \".sass\" isn't \".css\"\n\t\t\t\"/entry.css\": `@import \"./test\";`,\n\t\t\t\"/test.js\":   `console.log('js')`,\n\t\t\t\"/test.sass\": `// some code`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:           config.ModeBundle,\n\t\t\tAbsOutputFile:  \"/out.css\",\n\t\t\tExtensionOrder: []string{\".js\", \".sass\"},\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `entry.css: ERROR: No loader is configured for \".sass\" files: test.sass\n`,\n\t})\n}\n\nfunc TestCSSAtImportConditionsNoBundle(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `@import \"./print.css\" print;`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.css\",\n\t\t},\n\t})\n}\n\nfunc TestCSSAtImportConditionsBundleExternal(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `@import \"https://example.com/print.css\" print;`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.css\",\n\t\t},\n\t})\n}\n\nfunc TestCSSAtImportConditionsBundleExternalConditionWithURL(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"https://example.com/foo.css\" (foo: url(\"foo.png\")) and (bar: url(\"bar.png\"));\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.css\",\n\t\t},\n\t})\n}\n\nfunc TestCSSAtImportConditionsBundle(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import url(http://example.com/foo.css);\n\t\t\t\t@import url(http://example.com/foo.css) layer;\n\t\t\t\t@import url(http://example.com/foo.css) layer(layer-name);\n\t\t\t\t@import url(http://example.com/foo.css) layer(layer-name) supports(supports-condition);\n\t\t\t\t@import url(http://example.com/foo.css) layer(layer-name) supports(supports-condition) list-of-media-queries;\n\t\t\t\t@import url(http://example.com/foo.css) layer(layer-name) list-of-media-queries;\n\t\t\t\t@import url(http://example.com/foo.css) supports(supports-condition);\n\t\t\t\t@import url(http://example.com/foo.css) supports(supports-condition) list-of-media-queries;\n\t\t\t\t@import url(http://example.com/foo.css) list-of-media-queries;\n\n\t\t\t\t@import url(foo.css);\n\t\t\t\t@import url(foo.css) layer;\n\t\t\t\t@import url(foo.css) layer(layer-name);\n\t\t\t\t@import url(foo.css) layer(layer-name) supports(supports-condition);\n\t\t\t\t@import url(foo.css) layer(layer-name) supports(supports-condition) list-of-media-queries;\n\t\t\t\t@import url(foo.css) layer(layer-name) list-of-media-queries;\n\t\t\t\t@import url(foo.css) supports(supports-condition);\n\t\t\t\t@import url(foo.css) supports(supports-condition) list-of-media-queries;\n\t\t\t\t@import url(foo.css) list-of-media-queries;\n\n\t\t\t\t@import url(empty-1.css) layer(empty-1);\n\t\t\t\t@import url(empty-2.css) supports(empty: 2);\n\t\t\t\t@import url(empty-3.css) (empty: 3);\n\n\t\t\t\t@import \"nested-layer.css\" layer(outer);\n\t\t\t\t@import \"nested-layer.css\" supports(outer: true);\n\t\t\t\t@import \"nested-layer.css\" (outer: true);\n\t\t\t\t@import \"nested-supports.css\" layer(outer);\n\t\t\t\t@import \"nested-supports.css\" supports(outer: true);\n\t\t\t\t@import \"nested-supports.css\" (outer: true);\n\t\t\t\t@import \"nested-media.css\" layer(outer);\n\t\t\t\t@import \"nested-media.css\" supports(outer: true);\n\t\t\t\t@import \"nested-media.css\" (outer: true);\n\t\t\t`,\n\n\t\t\t\"/foo.css\": `body { color: red }`,\n\n\t\t\t\"/empty-1.css\": ``,\n\t\t\t\"/empty-2.css\": ``,\n\t\t\t\"/empty-3.css\": ``,\n\n\t\t\t\"/nested-layer.css\":    `@import \"foo.css\" layer(inner);`,\n\t\t\t\"/nested-supports.css\": `@import \"foo.css\" supports(inner: true);`,\n\t\t\t\"/nested-media.css\":    `@import \"foo.css\" (inner: true);`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.css\",\n\t\t},\n\t})\n}\n\nfunc TestCSSAtImportConditionsWithImportRecordsBundle(t *testing.T) {\n\t// This tests that esbuild correctly clones the import records for all import\n\t// condition tokens. If they aren't cloned correctly, then something will\n\t// likely crash with an out-of-bounds error.\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import url(foo.css) supports(background: url(a.png));\n\t\t\t\t@import url(foo.css) supports(background: url(b.png)) list-of-media-queries;\n\t\t\t\t@import url(foo.css) layer(layer-name) supports(background: url(a.png));\n\t\t\t\t@import url(foo.css) layer(layer-name) supports(background: url(b.png)) list-of-media-queries;\n\t\t\t`,\n\t\t\t\"/foo.css\": `body { color: red }`,\n\t\t\t\"/a.png\":   `A`,\n\t\t\t\"/b.png\":   `B`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.css\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t\t\".png\": config.LoaderBase64,\n\t\t\t},\n\t\t},\n\t})\n}\n\n// From: https://github.com/romainmenke/css-import-tests. These test cases just\n// serve to document any changes in esbuild's behavior. Any changes in behavior\n// should be tested to ensure they don't cause any regressions. The easiest way\n// to test the changes is to bundle https://github.com/evanw/css-import-tests\n// and visually inspect a browser's rendering of the resulting CSS file.\nfunc TestCSSAtImportConditionsFromExternalRepo(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/001/default/a.css\":     `.box { background-color: green; }`,\n\t\t\t\"/001/default/style.css\": `@import url(\"a.css\");`,\n\n\t\t\t\"/001/relative-url/a.css\":     `.box { background-color: green; }`,\n\t\t\t\"/001/relative-url/style.css\": `@import url(\"./a.css\");`,\n\n\t\t\t\"/at-charset/001/a.css\":     `@charset \"utf-8\"; .box { background-color: red; }`,\n\t\t\t\"/at-charset/001/b.css\":     `@charset \"utf-8\"; .box { background-color: green; }`,\n\t\t\t\"/at-charset/001/style.css\": `@charset \"utf-8\"; @import url(\"a.css\"); @import url(\"b.css\");`,\n\n\t\t\t\"/at-keyframes/001/a.css\": `\n\t\t\t\t.box { animation: BOX; animation-duration: 0s; animation-fill-mode: both; }\n\t\t\t\t@keyframes BOX { 0%, 100% { background-color: green; } }\n\t\t\t`,\n\t\t\t\"/at-keyframes/001/b.css\": `\n\t\t\t\t.box { animation: BOX; animation-duration: 0s; animation-fill-mode: both; }\n\t\t\t\t@keyframes BOX { 0%, 100% { background-color: red; } }\n\t\t\t`,\n\t\t\t\"/at-keyframes/001/style.css\": `@import url(\"a.css\") screen; @import url(\"b.css\") print;`,\n\n\t\t\t\"/at-layer/001/a.css\": `.box { background-color: red; }`,\n\t\t\t\"/at-layer/001/b.css\": `.box { background-color: green; }`,\n\t\t\t\"/at-layer/001/style.css\": `\n\t\t\t\t@import url(\"a.css\") layer(a);\n\t\t\t\t@import url(\"b.css\") layer(b);\n\t\t\t\t@import url(\"a.css\") layer(a);\n\t\t\t`,\n\n\t\t\t\"/at-layer/002/a.css\": `.box { background-color: green; }`,\n\t\t\t\"/at-layer/002/b.css\": `.box { background-color: red; }`,\n\t\t\t\"/at-layer/002/style.css\": `\n\t\t\t\t@import url(\"a.css\") layer(a) print;\n\t\t\t\t@import url(\"b.css\") layer(b);\n\t\t\t\t@import url(\"a.css\") layer(a);\n\t\t\t`,\n\n\t\t\t// Note: This case is currently bundled incorrectly. Normal CSS takes\n\t\t\t// effect at the position of the last \"@import\". However, \"@layer\" CSS\n\t\t\t// takes effect at the position of the first \"@import\". This discrepancy\n\t\t\t// in behavior is not currently handled.\n\t\t\t\"/at-layer/003/a.css\":     `@layer a { .box { background-color: red; } }`,\n\t\t\t\"/at-layer/003/b.css\":     `@layer b { .box { background-color: green; } }`,\n\t\t\t\"/at-layer/003/style.css\": `@import url(\"a.css\"); @import url(\"b.css\"); @import url(\"a.css\");`,\n\n\t\t\t\"/at-layer/004/a.css\":     `@layer { .box { background-color: green; } }`,\n\t\t\t\"/at-layer/004/b.css\":     `@layer { .box { background-color: red; } }`,\n\t\t\t\"/at-layer/004/style.css\": `@import url(\"a.css\"); @import url(\"b.css\"); @import url(\"a.css\");`,\n\n\t\t\t\"/at-layer/005/a.css\": `@import url(\"b.css\") layer(b) (width: 1px);`,\n\t\t\t\"/at-layer/005/b.css\": `.box { background-color: red; }`,\n\t\t\t\"/at-layer/005/style.css\": `\n\t\t\t\t@import url(\"a.css\") layer(a) (min-width: 1px);\n\t\t\t\t@layer a.c { .box { background-color: red; } }\n\t\t\t\t@layer a.b { .box { background-color: green; } }\n\t\t\t`,\n\n\t\t\t\"/at-layer/006/a.css\": `@import url(\"b.css\") layer(b) (min-width: 1px);`,\n\t\t\t\"/at-layer/006/b.css\": `.box { background-color: red; }`,\n\t\t\t\"/at-layer/006/style.css\": `\n\t\t\t\t@import url(\"a.css\") layer(a) (min-width: 1px);\n\t\t\t\t@layer a.c { .box { background-color: green; } }\n\t\t\t\t@layer a.b { .box { background-color: red; } }\n\t\t\t`,\n\n\t\t\t\"/at-layer/007/style.css\": `\n\t\t\t\t@layer foo {}\n\t\t\t\t@layer bar {}\n\t\t\t\t@layer bar { .box { background-color: green; } }\n\t\t\t\t@layer foo { .box { background-color: red; } }\n\t\t\t`,\n\n\t\t\t\"/at-layer/008/a.css\":     `@import \"b.css\" layer; .box { background-color: green; }`,\n\t\t\t\"/at-layer/008/b.css\":     `.box { background-color: red; }`,\n\t\t\t\"/at-layer/008/style.css\": `@import url(\"a.css\") layer;`,\n\n\t\t\t\"/at-media/001/default/a.css\":     `.box { background-color: green; }`,\n\t\t\t\"/at-media/001/default/style.css\": `@import url(\"a.css\") screen;`,\n\n\t\t\t\"/at-media/002/a.css\":     `.box { background-color: green; }`,\n\t\t\t\"/at-media/002/b.css\":     `.box { background-color: red; }`,\n\t\t\t\"/at-media/002/style.css\": `@import url(\"a.css\") screen; @import url(\"b.css\") print;`,\n\n\t\t\t\"/at-media/003/a.css\":     `@import url(\"b.css\") (min-width: 1px);`,\n\t\t\t\"/at-media/003/b.css\":     `.box { background-color: green; }`,\n\t\t\t\"/at-media/003/style.css\": `@import url(\"a.css\") screen;`,\n\n\t\t\t\"/at-media/004/a.css\":     `@import url(\"b.css\") print;`,\n\t\t\t\"/at-media/004/b.css\":     `.box { background-color: red; }`,\n\t\t\t\"/at-media/004/c.css\":     `.box { background-color: green; }`,\n\t\t\t\"/at-media/004/style.css\": `@import url(\"c.css\"); @import url(\"a.css\") print;`,\n\n\t\t\t\"/at-media/005/a.css\":     `@import url(\"b.css\") (max-width: 1px);`,\n\t\t\t\"/at-media/005/b.css\":     `.box { background-color: red; }`,\n\t\t\t\"/at-media/005/c.css\":     `.box { background-color: green; }`,\n\t\t\t\"/at-media/005/style.css\": `@import url(\"c.css\"); @import url(\"a.css\") (max-width: 1px);`,\n\n\t\t\t\"/at-media/006/a.css\":     `@import url(\"b.css\") (min-width: 1px);`,\n\t\t\t\"/at-media/006/b.css\":     `.box { background-color: green; }`,\n\t\t\t\"/at-media/006/style.css\": `@import url(\"a.css\") (min-height: 1px);`,\n\n\t\t\t\"/at-media/007/a.css\":     `@import url(\"b.css\") screen;`,\n\t\t\t\"/at-media/007/b.css\":     `.box { background-color: green; }`,\n\t\t\t\"/at-media/007/style.css\": `@import url(\"a.css\") all;`,\n\n\t\t\t\"/at-media/008/a.css\":     `@import url(\"green.css\") layer(alpha) print;`,\n\t\t\t\"/at-media/008/b.css\":     `@import url(\"red.css\") layer(beta) print;`,\n\t\t\t\"/at-media/008/green.css\": `.box { background-color: green; }`,\n\t\t\t\"/at-media/008/red.css\":   `.box { background-color: red; }`,\n\t\t\t\"/at-media/008/style.css\": `\n\t\t\t\t@import url(\"a.css\") layer(alpha) all;\n\t\t\t\t@import url(\"b.css\") layer(beta) all;\n\t\t\t\t@layer beta { .box { background-color: green; } }\n\t\t\t\t@layer alpha { .box { background-color: red; } }\n\t\t\t`,\n\n\t\t\t\"/at-supports/001/a.css\":     `.box { background-color: green; }`,\n\t\t\t\"/at-supports/001/style.css\": `@import url(\"a.css\") supports(display: block);`,\n\n\t\t\t\"/at-supports/002/a.css\":     `@import url(\"b.css\") supports(width: 10px);`,\n\t\t\t\"/at-supports/002/b.css\":     `.box { background-color: green; }`,\n\t\t\t\"/at-supports/002/style.css\": `@import url(\"a.css\") supports(display: block);`,\n\n\t\t\t\"/at-supports/003/a.css\":     `@import url(\"b.css\") supports(width: 10px);`,\n\t\t\t\"/at-supports/003/b.css\":     `.box { background-color: green; }`,\n\t\t\t\"/at-supports/003/style.css\": `@import url(\"a.css\") supports((display: block) or (display: inline));`,\n\n\t\t\t\"/at-supports/004/a.css\":     `@import url(\"b.css\") layer(b) supports(width: 10px);`,\n\t\t\t\"/at-supports/004/b.css\":     `.box { background-color: green; }`,\n\t\t\t\"/at-supports/004/style.css\": `@import url(\"a.css\") layer(a) supports(display: block);`,\n\n\t\t\t\"/at-supports/005/a.css\":     `@import url(\"green.css\") layer(alpha) supports(foo: bar);`,\n\t\t\t\"/at-supports/005/b.css\":     `@import url(\"red.css\") layer(beta) supports(foo: bar);`,\n\t\t\t\"/at-supports/005/green.css\": `.box { background-color: green; }`,\n\t\t\t\"/at-supports/005/red.css\":   `.box { background-color: red; }`,\n\t\t\t\"/at-supports/005/style.css\": `\n\t\t\t\t@import url(\"a.css\") layer(alpha) supports(display: block);\n\t\t\t\t@import url(\"b.css\") layer(beta) supports(display: block);\n\t\t\t\t@layer beta { .box { background-color: green; } }\n\t\t\t\t@layer alpha { .box { background-color: red; } }\n\t\t\t`,\n\n\t\t\t\"/cycles/001/style.css\": `@import url(\"style.css\"); .box { background-color: green; }`,\n\n\t\t\t\"/cycles/002/a.css\":     `@import url(\"red.css\"); @import url(\"b.css\");`,\n\t\t\t\"/cycles/002/b.css\":     `@import url(\"green.css\"); @import url(\"a.css\");`,\n\t\t\t\"/cycles/002/green.css\": `.box { background-color: green; }`,\n\t\t\t\"/cycles/002/red.css\":   `.box { background-color: red; }`,\n\t\t\t\"/cycles/002/style.css\": `@import url(\"a.css\");`,\n\n\t\t\t\"/cycles/003/a.css\":     `@import url(\"b.css\"); .box { background-color: green; }`,\n\t\t\t\"/cycles/003/b.css\":     `@import url(\"a.css\"); .box { background-color: red; }`,\n\t\t\t\"/cycles/003/style.css\": `@import url(\"a.css\");`,\n\n\t\t\t\"/cycles/004/a.css\":     `@import url(\"b.css\"); .box { background-color: red; }`,\n\t\t\t\"/cycles/004/b.css\":     `@import url(\"a.css\"); .box { background-color: green; }`,\n\t\t\t\"/cycles/004/style.css\": `@import url(\"a.css\"); @import url(\"b.css\");`,\n\n\t\t\t\"/cycles/005/a.css\":     `@import url(\"b.css\"); .box { background-color: green; }`,\n\t\t\t\"/cycles/005/b.css\":     `@import url(\"a.css\"); .box { background-color: red; }`,\n\t\t\t\"/cycles/005/style.css\": `@import url(\"a.css\"); @import url(\"b.css\"); @import url(\"a.css\");`,\n\n\t\t\t\"/cycles/006/a.css\":     `@import url(\"red.css\"); @import url(\"b.css\");`,\n\t\t\t\"/cycles/006/b.css\":     `@import url(\"green.css\"); @import url(\"a.css\");`,\n\t\t\t\"/cycles/006/c.css\":     `@import url(\"a.css\");`,\n\t\t\t\"/cycles/006/green.css\": `.box { background-color: green; }`,\n\t\t\t\"/cycles/006/red.css\":   `.box { background-color: red; }`,\n\t\t\t\"/cycles/006/style.css\": `@import url(\"b.css\"); @import url(\"c.css\");`,\n\n\t\t\t\"/cycles/007/a.css\":     `@import url(\"red.css\"); @import url(\"b.css\") screen;`,\n\t\t\t\"/cycles/007/b.css\":     `@import url(\"green.css\"); @import url(\"a.css\") all;`,\n\t\t\t\"/cycles/007/c.css\":     `@import url(\"a.css\") not print;`,\n\t\t\t\"/cycles/007/green.css\": `.box { background-color: green; }`,\n\t\t\t\"/cycles/007/red.css\":   `.box { background-color: red; }`,\n\t\t\t\"/cycles/007/style.css\": `@import url(\"b.css\"); @import url(\"c.css\");`,\n\n\t\t\t\"/cycles/008/a.css\":     `@import url(\"red.css\") layer; @import url(\"b.css\");`,\n\t\t\t\"/cycles/008/b.css\":     `@import url(\"green.css\") layer; @import url(\"a.css\");`,\n\t\t\t\"/cycles/008/c.css\":     `@import url(\"a.css\") layer;`,\n\t\t\t\"/cycles/008/green.css\": `.box { background-color: green; }`,\n\t\t\t\"/cycles/008/red.css\":   `.box { background-color: red; }`,\n\t\t\t\"/cycles/008/style.css\": `@import url(\"b.css\"); @import url(\"c.css\");`,\n\n\t\t\t\"/data-urls/002/style.css\": `@import url('data:text/css;plain,.box%20%7B%0A%09background-color%3A%20green%3B%0A%7D%0A');`,\n\n\t\t\t\"/data-urls/003/style.css\": `@import url('data:text/css,.box%20%7B%0A%09background-color%3A%20green%3B%0A%7D%0A');`,\n\n\t\t\t\"/duplicates/001/a.css\":     `.box { background-color: green; }`,\n\t\t\t\"/duplicates/001/b.css\":     `.box { background-color: red; }`,\n\t\t\t\"/duplicates/001/style.css\": `@import url(\"a.css\"); @import url(\"b.css\"); @import url(\"a.css\");`,\n\n\t\t\t\"/duplicates/002/a.css\":     `.box { background-color: green; }`,\n\t\t\t\"/duplicates/002/b.css\":     `.box { background-color: red; }`,\n\t\t\t\"/duplicates/002/style.css\": `@import url(\"a.css\"); @import url(\"b.css\"); @import url(\"a.css\"); @import url(\"b.css\"); @import url(\"a.css\");`,\n\n\t\t\t\"/empty/001/empty.css\": ``,\n\t\t\t\"/empty/001/style.css\": `@import url(\"./empty.css\"); .box { background-color: green; }`,\n\n\t\t\t\"/relative-paths/001/a/a.css\":   `@import url(\"../b/b.css\")`,\n\t\t\t\"/relative-paths/001/b/b.css\":   `.box { background-color: green; }`,\n\t\t\t\"/relative-paths/001/style.css\": `@import url(\"./a/a.css\");`,\n\n\t\t\t\"/relative-paths/002/a/a.css\":   `@import url(\"./../b/b.css\")`,\n\t\t\t\"/relative-paths/002/b/b.css\":   `.box { background-color: green; }`,\n\t\t\t\"/relative-paths/002/style.css\": `@import url(\"./a/a.css\");`,\n\n\t\t\t\"/subresource/001/something/images/green.png\": `...`,\n\t\t\t\"/subresource/001/something/styles/green.css\": `.box { background-image: url(\"../images/green.png\"); }`,\n\t\t\t\"/subresource/001/style.css\":                  `@import url(\"./something/styles/green.css\");`,\n\n\t\t\t\"/subresource/002/green.png\":        `...`,\n\t\t\t\"/subresource/002/style.css\":        `@import url(\"./styles/green.css\");`,\n\t\t\t\"/subresource/002/styles/green.css\": `.box { background-image: url(\"../green.png\"); }`,\n\n\t\t\t\"/subresource/004/style.css\":        `@import url(\"./styles/green.css\");`,\n\t\t\t\"/subresource/004/styles/green.css\": `.box { background-image: url(\"green.png\"); }`,\n\t\t\t\"/subresource/004/styles/green.png\": `...`,\n\n\t\t\t\"/subresource/005/style.css\":        `@import url(\"./styles/green.css\");`,\n\t\t\t\"/subresource/005/styles/green.css\": `.box { background-image: url(\"./green.png\"); }`,\n\t\t\t\"/subresource/005/styles/green.png\": `...`,\n\n\t\t\t\"/subresource/007/green.png\": `...`,\n\t\t\t\"/subresource/007/style.css\": `.box { background-image: url(\"./green.png\"); }`,\n\n\t\t\t\"/url-format/001/default/a.css\":     `.box { background-color: green; }`,\n\t\t\t\"/url-format/001/default/style.css\": `@import url(a.css);`,\n\n\t\t\t\"/url-format/001/relative-url/a.css\":     `.box { background-color: green; }`,\n\t\t\t\"/url-format/001/relative-url/style.css\": `@import url(./a.css);`,\n\n\t\t\t\"/url-format/002/default/a.css\":     `.box { background-color: green; }`,\n\t\t\t\"/url-format/002/default/style.css\": `@import \"a.css\";`,\n\n\t\t\t\"/url-format/002/relative-url/a.css\":     `.box { background-color: green; }`,\n\t\t\t\"/url-format/002/relative-url/style.css\": `@import \"./a.css\";`,\n\n\t\t\t\"/url-format/003/default/a.css\":     `.box { background-color: green; }`,\n\t\t\t\"/url-format/003/default/style.css\": `@import url(\"a.css\"`,\n\n\t\t\t\"/url-format/003/relative-url/a.css\":     `.box { background-color: green; }`,\n\t\t\t\"/url-format/003/relative-url/style.css\": `@import url(\"./a.css\"`,\n\n\t\t\t\"/url-fragments/001/a.css\":     `.box { background-color: green; }`,\n\t\t\t\"/url-fragments/001/style.css\": `@import url(\"./a.css#foo\");`,\n\n\t\t\t\"/url-fragments/002/a.css\":     `.box { background-color: green; }`,\n\t\t\t\"/url-fragments/002/b.css\":     `.box { background-color: red; }`,\n\t\t\t\"/url-fragments/002/style.css\": `@import url(\"./a.css#1\"); @import url(\"./b.css#2\"); @import url(\"./a.css#3\");`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/001/default/style.css\",\n\t\t\t\"/001/relative-url/style.css\",\n\n\t\t\t\"/at-charset/001/style.css\",\n\n\t\t\t\"/at-keyframes/001/style.css\",\n\n\t\t\t\"/at-layer/001/style.css\",\n\t\t\t\"/at-layer/002/style.css\",\n\t\t\t\"/at-layer/003/style.css\",\n\t\t\t\"/at-layer/004/style.css\",\n\t\t\t\"/at-layer/005/style.css\",\n\t\t\t\"/at-layer/006/style.css\",\n\t\t\t\"/at-layer/007/style.css\",\n\t\t\t\"/at-layer/008/style.css\",\n\n\t\t\t\"/at-media/001/default/style.css\",\n\t\t\t\"/at-media/002/style.css\",\n\t\t\t\"/at-media/003/style.css\",\n\t\t\t\"/at-media/004/style.css\",\n\t\t\t\"/at-media/005/style.css\",\n\t\t\t\"/at-media/006/style.css\",\n\t\t\t\"/at-media/007/style.css\",\n\t\t\t\"/at-media/008/style.css\",\n\n\t\t\t\"/at-supports/001/style.css\",\n\t\t\t\"/at-supports/002/style.css\",\n\t\t\t\"/at-supports/003/style.css\",\n\t\t\t\"/at-supports/004/style.css\",\n\t\t\t\"/at-supports/005/style.css\",\n\n\t\t\t\"/cycles/001/style.css\",\n\t\t\t\"/cycles/002/style.css\",\n\t\t\t\"/cycles/003/style.css\",\n\t\t\t\"/cycles/004/style.css\",\n\t\t\t\"/cycles/005/style.css\",\n\t\t\t\"/cycles/006/style.css\",\n\t\t\t\"/cycles/007/style.css\",\n\t\t\t\"/cycles/008/style.css\",\n\n\t\t\t\"/data-urls/002/style.css\",\n\t\t\t\"/data-urls/003/style.css\",\n\n\t\t\t\"/duplicates/001/style.css\",\n\t\t\t\"/duplicates/002/style.css\",\n\n\t\t\t\"/empty/001/style.css\",\n\n\t\t\t\"/relative-paths/001/style.css\",\n\t\t\t\"/relative-paths/002/style.css\",\n\n\t\t\t\"/subresource/001/style.css\",\n\t\t\t\"/subresource/002/style.css\",\n\t\t\t\"/subresource/004/style.css\",\n\t\t\t\"/subresource/005/style.css\",\n\t\t\t\"/subresource/007/style.css\",\n\n\t\t\t\"/url-format/001/default/style.css\",\n\t\t\t\"/url-format/001/relative-url/style.css\",\n\t\t\t\"/url-format/002/default/style.css\",\n\t\t\t\"/url-format/002/relative-url/style.css\",\n\t\t\t\"/url-format/003/default/style.css\",\n\t\t\t\"/url-format/003/relative-url/style.css\",\n\t\t\t\"/url-fragments/001/style.css\",\n\t\t\t\"/url-fragments/002/style.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t\t\".png\": config.LoaderBase64,\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `relative-paths/001/a/a.css: WARNING: Expected \";\" but found end of file\nrelative-paths/002/a/a.css: WARNING: Expected \";\" but found end of file\nurl-format/003/default/style.css: WARNING: Expected \")\" to go with \"(\"\nurl-format/003/default/style.css: NOTE: The unbalanced \"(\" is here:\nurl-format/003/relative-url/style.css: WARNING: Expected \")\" to go with \"(\"\nurl-format/003/relative-url/style.css: NOTE: The unbalanced \"(\" is here:\n`,\n\t})\n}\n\nfunc TestCSSAtImportConditionsAtLayerBundle(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/case1.css\": `\n\t\t\t\t@import url(case1-foo.css) layer(first.one);\n\t\t\t\t@import url(case1-foo.css) layer(last.one);\n\t\t\t\t@import url(case1-foo.css) layer(first.one);\n\t\t\t`,\n\t\t\t\"/case1-foo.css\": `body { color: red }`,\n\n\t\t\t\"/case2.css\": `\n\t\t\t\t@import url(case2-foo.css);\n\t\t\t\t@import url(case2-bar.css);\n\t\t\t\t@import url(case2-foo.css);\n\t\t\t`,\n\t\t\t\"/case2-foo.css\": `@layer first.one { body { color: red } }`,\n\t\t\t\"/case2-bar.css\": `@layer last.one { body { color: green } }`,\n\n\t\t\t\"/case3.css\": `\n\t\t\t\t@import url(case3-foo.css);\n\t\t\t\t@import url(case3-bar.css);\n\t\t\t\t@import url(case3-foo.css);\n\t\t\t`,\n\t\t\t\"/case3-foo.css\": `@layer { body { color: red } }`,\n\t\t\t\"/case3-bar.css\": `@layer only.one { body { color: green } }`,\n\n\t\t\t\"/case4.css\": `\n\t\t\t\t@import url(case4-foo.css) layer(first);\n\t\t\t\t@import url(case4-foo.css) layer(last);\n\t\t\t\t@import url(case4-foo.css) layer(first);\n\t\t\t`,\n\t\t\t\"/case4-foo.css\": `@layer one { @layer two, three.four; body { color: red } }`,\n\n\t\t\t\"/case5.css\": `\n\t\t\t\t@import url(case5-foo.css) layer;\n\t\t\t\t@import url(case5-foo.css) layer(middle);\n\t\t\t\t@import url(case5-foo.css) layer;\n\t\t\t`,\n\t\t\t\"/case5-foo.css\": `@layer one { @layer two, three.four; body { color: red } }`,\n\n\t\t\t\"/case6.css\": `\n\t\t\t\t@import url(case6-foo.css) layer(first);\n\t\t\t\t@import url(case6-foo.css) layer(last);\n\t\t\t\t@import url(case6-foo.css) layer(first);\n\t\t\t`,\n\t\t\t\"/case6-foo.css\": `@layer { @layer two, three.four; body { color: red } }`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/case1.css\",\n\t\t\t\"/case2.css\",\n\t\t\t\"/case3.css\",\n\t\t\t\"/case4.css\",\n\t\t\t\"/case5.css\",\n\t\t\t\"/case6.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestCSSAtImportConditionsAtLayerBundleAlternatingLayerInFile(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.css\": `@layer first { body { color: red } }`,\n\t\t\t\"/b.css\": `@layer last { body { color: green } }`,\n\n\t\t\t\"/case1.css\": `\n\t\t\t\t@import url(a.css);\n\t\t\t\t@import url(a.css);\n\t\t\t`,\n\n\t\t\t\"/case2.css\": `\n\t\t\t\t@import url(a.css);\n\t\t\t\t@import url(b.css);\n\t\t\t\t@import url(a.css);\n\t\t\t`,\n\n\t\t\t\"/case3.css\": `\n\t\t\t\t@import url(a.css);\n\t\t\t\t@import url(b.css);\n\t\t\t\t@import url(a.css);\n\t\t\t\t@import url(b.css);\n\t\t\t`,\n\n\t\t\t\"/case4.css\": `\n\t\t\t\t@import url(a.css);\n\t\t\t\t@import url(b.css);\n\t\t\t\t@import url(a.css);\n\t\t\t\t@import url(b.css);\n\t\t\t\t@import url(a.css);\n\t\t\t`,\n\n\t\t\t\"/case5.css\": `\n\t\t\t\t@import url(a.css);\n\t\t\t\t@import url(b.css);\n\t\t\t\t@import url(a.css);\n\t\t\t\t@import url(b.css);\n\t\t\t\t@import url(a.css);\n\t\t\t\t@import url(b.css);\n\t\t\t`,\n\n\t\t\t// Note: There was a bug that only showed up in this case. We need at least this many cases.\n\t\t\t\"/case6.css\": `\n\t\t\t\t@import url(a.css);\n\t\t\t\t@import url(b.css);\n\t\t\t\t@import url(a.css);\n\t\t\t\t@import url(b.css);\n\t\t\t\t@import url(a.css);\n\t\t\t\t@import url(b.css);\n\t\t\t\t@import url(a.css);\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/case1.css\",\n\t\t\t\"/case2.css\",\n\t\t\t\"/case3.css\",\n\t\t\t\"/case4.css\",\n\t\t\t\"/case5.css\",\n\t\t\t\"/case6.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestCSSAtImportConditionsAtLayerBundleAlternatingLayerOnImport(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.css\": `body { color: red }`,\n\t\t\t\"/b.css\": `body { color: green }`,\n\n\t\t\t\"/case1.css\": `\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t`,\n\n\t\t\t\"/case2.css\": `\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t\t@import url(b.css) layer(last);\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t`,\n\n\t\t\t\"/case3.css\": `\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t\t@import url(b.css) layer(last);\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t\t@import url(b.css) layer(last);\n\t\t\t`,\n\n\t\t\t\"/case4.css\": `\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t\t@import url(b.css) layer(last);\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t\t@import url(b.css) layer(last);\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t`,\n\n\t\t\t\"/case5.css\": `\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t\t@import url(b.css) layer(last);\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t\t@import url(b.css) layer(last);\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t\t@import url(b.css) layer(last);\n\t\t\t`,\n\n\t\t\t// Note: There was a bug that only showed up in this case. We need at least this many cases.\n\t\t\t\"/case6.css\": `\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t\t@import url(b.css) layer(last);\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t\t@import url(b.css) layer(last);\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t\t@import url(b.css) layer(last);\n\t\t\t\t@import url(a.css) layer(first);\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/case1.css\",\n\t\t\t\"/case2.css\",\n\t\t\t\"/case3.css\",\n\t\t\t\"/case4.css\",\n\t\t\t\"/case5.css\",\n\t\t\t\"/case6.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestCSSAtImportConditionsChainExternal(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"a.css\" layer(a) not print;\n\t\t\t`,\n\t\t\t\"/a.css\": `\n\t\t\t\t@import \"http://example.com/external1.css\";\n\t\t\t\t@import \"b.css\" layer(b) not tv;\n\t\t\t\t@import \"http://example.com/external2.css\" layer(a2);\n\t\t\t`,\n\t\t\t\"/b.css\": `\n\t\t\t\t@import \"http://example.com/external3.css\";\n\t\t\t\t@import \"http://example.com/external4.css\" layer(b2);\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.css\",\n\t\t},\n\t})\n}\n\n// This test mainly just makes sure that this scenario doesn't crash\nfunc TestCSSAndJavaScriptCodeSplittingIssue1064(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport shared from './shared.js'\n\t\t\t\tconsole.log(shared() + 1)\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport shared from './shared.js'\n\t\t\t\tconsole.log(shared() + 2)\n\t\t\t`,\n\t\t\t\"/c.css\": `\n\t\t\t\t@import \"./shared.css\";\n\t\t\t\tbody { color: red }\n\t\t\t`,\n\t\t\t\"/d.css\": `\n\t\t\t\t@import \"./shared.css\";\n\t\t\t\tbody { color: blue }\n\t\t\t`,\n\t\t\t\"/shared.js\": `\n\t\t\t\texport default function() { return 3 }\n\t\t\t`,\n\t\t\t\"/shared.css\": `\n\t\t\t\tbody { background: black }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/a.js\",\n\t\t\t\"/b.js\",\n\t\t\t\"/c.css\",\n\t\t\t\"/d.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tCodeSplitting: true,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestCSSExternalQueryAndHashNoMatchIssue1822(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\ta { background: url(foo/bar.png?baz) }\n\t\t\t\tb { background: url(foo/bar.png#baz) }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.css\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Patterns: []config.WildcardPattern{\n\t\t\t\t\t{Suffix: \".png\"},\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `entry.css: ERROR: Could not resolve \"foo/bar.png?baz\"\nNOTE: You can mark the path \"foo/bar.png?baz\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nentry.css: ERROR: Could not resolve \"foo/bar.png#baz\"\nNOTE: You can mark the path \"foo/bar.png#baz\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestCSSExternalQueryAndHashMatchIssue1822(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\ta { background: url(foo/bar.png?baz) }\n\t\t\t\tb { background: url(foo/bar.png#baz) }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.css\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Patterns: []config.WildcardPattern{\n\t\t\t\t\t{Suffix: \".png?baz\"},\n\t\t\t\t\t{Suffix: \".png#baz\"},\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestCSSNestingOldBrowser(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t// These are now the only two cases that warn about \":is\" not being supported\n\t\t\t\"/two-type-selectors.css\":   `a { .c b& { color: red; } }`,\n\t\t\t\"/two-parent-selectors.css\": `a b { .c & { color: red; } }`,\n\n\t\t\t// Make sure this only generates one warning (even though it generates \":is\" three times)\n\t\t\t\"/only-one-warning.css\": `.a, .b .c, .d { & > & { color: red; } }`,\n\n\t\t\t\"/nested-@layer.css\":          `a { @layer base { color: red; } }`,\n\t\t\t\"/nested-@media.css\":          `a { @media screen { color: red; } }`,\n\t\t\t\"/nested-ampersand-twice.css\": `a { &, & { color: red; } }`,\n\t\t\t\"/nested-ampersand-first.css\": `a { &, b { color: red; } }`,\n\t\t\t\"/nested-attribute.css\":       `a { [href] { color: red; } }`,\n\t\t\t\"/nested-colon.css\":           `a { :hover { color: red; } }`,\n\t\t\t\"/nested-dot.css\":             `a { .cls { color: red; } }`,\n\t\t\t\"/nested-greaterthan.css\":     `a { > b { color: red; } }`,\n\t\t\t\"/nested-hash.css\":            `a { #id { color: red; } }`,\n\t\t\t\"/nested-plus.css\":            `a { + b { color: red; } }`,\n\t\t\t\"/nested-tilde.css\":           `a { ~ b { color: red; } }`,\n\n\t\t\t\"/toplevel-ampersand-twice.css\":  `&, & { color: red; }`,\n\t\t\t\"/toplevel-ampersand-first.css\":  `&, a { color: red; }`,\n\t\t\t\"/toplevel-ampersand-second.css\": `a, & { color: red; }`,\n\t\t\t\"/toplevel-attribute.css\":        `[href] { color: red; }`,\n\t\t\t\"/toplevel-colon.css\":            `:hover { color: red; }`,\n\t\t\t\"/toplevel-dot.css\":              `.cls { color: red; }`,\n\t\t\t\"/toplevel-greaterthan.css\":      `> b { color: red; }`,\n\t\t\t\"/toplevel-hash.css\":             `#id { color: red; }`,\n\t\t\t\"/toplevel-plus.css\":             `+ b { color: red; }`,\n\t\t\t\"/toplevel-tilde.css\":            `~ b { color: red; }`,\n\n\t\t\t\"/media-ampersand-twice.css\":  `@media screen { &, & { color: red; } }`,\n\t\t\t\"/media-ampersand-first.css\":  `@media screen { &, a { color: red; } }`,\n\t\t\t\"/media-ampersand-second.css\": `@media screen { a, & { color: red; } }`,\n\t\t\t\"/media-attribute.css\":        `@media screen { [href] { color: red; } }`,\n\t\t\t\"/media-colon.css\":            `@media screen { :hover { color: red; } }`,\n\t\t\t\"/media-dot.css\":              `@media screen { .cls { color: red; } }`,\n\t\t\t\"/media-greaterthan.css\":      `@media screen { > b { color: red; } }`,\n\t\t\t\"/media-hash.css\":             `@media screen { #id { color: red; } }`,\n\t\t\t\"/media-plus.css\":             `@media screen { + b { color: red; } }`,\n\t\t\t\"/media-tilde.css\":            `@media screen { ~ b { color: red; } }`,\n\n\t\t\t// See: https://github.com/evanw/esbuild/issues/3197\n\t\t\t\"/page-no-warning.css\": `@page { @top-left { background: red } }`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/two-type-selectors.css\",\n\t\t\t\"/two-parent-selectors.css\",\n\n\t\t\t\"/only-one-warning.css\",\n\n\t\t\t\"/nested-@layer.css\",\n\t\t\t\"/nested-@media.css\",\n\t\t\t\"/nested-ampersand-twice.css\",\n\t\t\t\"/nested-ampersand-first.css\",\n\t\t\t\"/nested-attribute.css\",\n\t\t\t\"/nested-colon.css\",\n\t\t\t\"/nested-dot.css\",\n\t\t\t\"/nested-greaterthan.css\",\n\t\t\t\"/nested-hash.css\",\n\t\t\t\"/nested-plus.css\",\n\t\t\t\"/nested-tilde.css\",\n\n\t\t\t\"/toplevel-ampersand-twice.css\",\n\t\t\t\"/toplevel-ampersand-first.css\",\n\t\t\t\"/toplevel-ampersand-second.css\",\n\t\t\t\"/toplevel-attribute.css\",\n\t\t\t\"/toplevel-colon.css\",\n\t\t\t\"/toplevel-dot.css\",\n\t\t\t\"/toplevel-greaterthan.css\",\n\t\t\t\"/toplevel-hash.css\",\n\t\t\t\"/toplevel-plus.css\",\n\t\t\t\"/toplevel-tilde.css\",\n\n\t\t\t\"/media-ampersand-twice.css\",\n\t\t\t\"/media-ampersand-first.css\",\n\t\t\t\"/media-ampersand-second.css\",\n\t\t\t\"/media-attribute.css\",\n\t\t\t\"/media-colon.css\",\n\t\t\t\"/media-dot.css\",\n\t\t\t\"/media-greaterthan.css\",\n\t\t\t\"/media-hash.css\",\n\t\t\t\"/media-plus.css\",\n\t\t\t\"/media-tilde.css\",\n\n\t\t\t\"/page-no-warning.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:                   config.ModeBundle,\n\t\t\tAbsOutputDir:           \"/out\",\n\t\t\tUnsupportedCSSFeatures: compat.Nesting | compat.IsPseudoClass,\n\t\t\tOriginalTargetEnv:      \"chrome10\",\n\t\t},\n\t\texpectedScanLog: `only-one-warning.css: WARNING: Transforming this CSS nesting syntax is not supported in the configured target environment (chrome10)\nNOTE: The nesting transform for this case must generate an \":is(...)\" but the configured target environment does not support the \":is\" pseudo-class.\ntwo-parent-selectors.css: WARNING: Transforming this CSS nesting syntax is not supported in the configured target environment (chrome10)\nNOTE: The nesting transform for this case must generate an \":is(...)\" but the configured target environment does not support the \":is\" pseudo-class.\ntwo-type-selectors.css: WARNING: Transforming this CSS nesting syntax is not supported in the configured target environment (chrome10)\nNOTE: The nesting transform for this case must generate an \":is(...)\" but the configured target environment does not support the \":is\" pseudo-class.\n`,\n\t})\n}\n\n// The mapping of JS entry point to associated CSS bundle isn't necessarily 1:1.\n// Here is a case where it isn't. Two JS entry points share the same associated\n// CSS bundle. This must be reflected in the metafile by only having the JS\n// entry points point to the associated CSS bundle but not the other way around\n// (since there isn't one JS entry point to point to). This test mainly exists\n// to document this edge case.\nfunc TestMetafileCSSBundleTwoToOne(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/foo/entry.js\": `\n\t\t\t\timport '../common.css'\n\t\t\t\tconsole.log('foo')\n\t\t\t`,\n\t\t\t\"/bar/entry.js\": `\n\t\t\t\timport '../common.css'\n\t\t\t\tconsole.log('bar')\n\t\t\t`,\n\t\t\t\"/common.css\": `\n\t\t\t\tbody { color: red }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/foo/entry.js\",\n\t\t\t\"/bar/entry.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tEntryPathTemplate: []config.PathTemplate{\n\t\t\t\t// \"[ext]/[hash]\"\n\t\t\t\t{Data: \"./\", Placeholder: config.ExtPlaceholder},\n\t\t\t\t{Data: \"/\", Placeholder: config.HashPlaceholder},\n\t\t\t},\n\t\t\tNeedsMetafile: true,\n\t\t},\n\t})\n}\n\nfunc TestDeduplicateRules(t *testing.T) {\n\t// These are done as bundler tests instead of parser tests because rule\n\t// deduplication now happens during linking (so that it has effects across files)\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/yes0.css\": \"a { color: red; color: green; color: red }\",\n\t\t\t\"/yes1.css\": \"a { color: red } a { color: green } a { color: red }\",\n\t\t\t\"/yes2.css\": \"@media screen { a { color: red } } @media screen { a { color: red } }\",\n\t\t\t\"/yes3.css\": \"@media screen { a { color: red } } @media screen { & a { color: red } }\",\n\n\t\t\t\"/no0.css\": \"@media screen { a { color: red } } @media screen { b a& { color: red } }\",\n\t\t\t\"/no1.css\": \"@media screen { a { color: red } } @media screen { a[x] { color: red } }\",\n\t\t\t\"/no2.css\": \"@media screen { a { color: red } } @media screen { a.x { color: red } }\",\n\t\t\t\"/no3.css\": \"@media screen { a { color: red } } @media screen { a#x { color: red } }\",\n\t\t\t\"/no4.css\": \"@media screen { a { color: red } } @media screen { a:x { color: red } }\",\n\t\t\t\"/no5.css\": \"@media screen { a:x { color: red } } @media screen { a:x(y) { color: red } }\",\n\t\t\t\"/no6.css\": \"@media screen { a b { color: red } } @media screen { a + b { color: red } }\",\n\n\t\t\t\"/across-files.css\":   \"@import 'across-files-0.css'; @import 'across-files-1.css'; @import 'across-files-2.css';\",\n\t\t\t\"/across-files-0.css\": \"a { color: red; color: red }\",\n\t\t\t\"/across-files-1.css\": \"a { color: green }\",\n\t\t\t\"/across-files-2.css\": \"a { color: red }\",\n\n\t\t\t\"/across-files-url.css\":   \"@import 'across-files-url-0.css'; @import 'across-files-url-1.css'; @import 'across-files-url-2.css';\",\n\t\t\t\"/across-files-url-0.css\": \"@import 'http://example.com/some.css'; @font-face { src: url(http://example.com/some.font); }\",\n\t\t\t\"/across-files-url-1.css\": \"@font-face { src: url(http://example.com/some.other.font); }\",\n\t\t\t\"/across-files-url-2.css\": \"@font-face { src: url(http://example.com/some.font); }\",\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/yes0.css\",\n\t\t\t\"/yes1.css\",\n\t\t\t\"/yes2.css\",\n\t\t\t\"/yes3.css\",\n\n\t\t\t\"/no0.css\",\n\t\t\t\"/no1.css\",\n\t\t\t\"/no2.css\",\n\t\t\t\"/no3.css\",\n\t\t\t\"/no4.css\",\n\t\t\t\"/no5.css\",\n\t\t\t\"/no6.css\",\n\n\t\t\t\"/across-files.css\",\n\t\t\t\"/across-files-url.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestDeduplicateRulesGlobalVsLocalNames(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"a.css\";\n\t\t\t\t@import \"b.css\";\n\t\t\t`,\n\t\t\t\"/a.css\": `\n\t\t\t\ta { color: red } /* SHOULD BE REMOVED */\n\t\t\t\tb { color: green }\n\n\t\t\t\t:global(.foo) { color: red } /* SHOULD BE REMOVED */\n\t\t\t\t:global(.bar) { color: green }\n\n\t\t\t\t:local(.foo) { color: red }\n\t\t\t\t:local(.bar) { color: green }\n\n\t\t\t\tdiv :global { animation-name: anim_global } /* SHOULD BE REMOVED */\n\t\t\t\tdiv :local { animation-name: anim_local }\n\t\t\t`,\n\t\t\t\"/b.css\": `\n\t\t\t\ta { color: red }\n\t\t\t\tb { color: blue }\n\n\t\t\t\t:global(.foo) { color: red }\n\t\t\t\t:global(.bar) { color: blue }\n\n\t\t\t\t:local(.foo) { color: red }\n\t\t\t\t:local(.bar) { color: blue }\n\n\t\t\t\tdiv :global { animation-name: anim_global }\n\t\t\t\tdiv :local { animation-name: anim_local }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\": config.LoaderLocalCSS,\n\t\t\t},\n\t\t},\n\t})\n}\n\n// This test makes sure JS files that import local CSS names using the\n// wrong name (e.g. a typo) get a warning so that the problem is noticed.\nfunc TestUndefinedImportWarningCSS(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as empty_js from './empty.js'\n\t\t\t\timport * as empty_esm_js from './empty.esm.js'\n\t\t\t\timport * as empty_json from './empty.json'\n\t\t\t\timport * as empty_css from './empty.css'\n\t\t\t\timport * as empty_global_css from './empty.global-css'\n\t\t\t\timport * as empty_local_css from './empty.local-css'\n\n\t\t\t\timport * as pkg_empty_js from 'pkg/empty.js'\n\t\t\t\timport * as pkg_empty_esm_js from 'pkg/empty.esm.js'\n\t\t\t\timport * as pkg_empty_json from 'pkg/empty.json'\n\t\t\t\timport * as pkg_empty_css from 'pkg/empty.css'\n\t\t\t\timport * as pkg_empty_global_css from 'pkg/empty.global-css'\n\t\t\t\timport * as pkg_empty_local_css from 'pkg/empty.local-css'\n\n\t\t\t\timport 'pkg'\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tempty_js.foo,\n\t\t\t\t\tempty_esm_js.foo,\n\t\t\t\t\tempty_json.foo,\n\t\t\t\t\tempty_css.foo,\n\t\t\t\t\tempty_global_css.foo,\n\t\t\t\t\tempty_local_css.foo,\n\t\t\t\t)\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tpkg_empty_js.foo,\n\t\t\t\t\tpkg_empty_esm_js.foo,\n\t\t\t\t\tpkg_empty_json.foo,\n\t\t\t\t\tpkg_empty_css.foo,\n\t\t\t\t\tpkg_empty_global_css.foo,\n\t\t\t\t\tpkg_empty_local_css.foo,\n\t\t\t\t)\n\t\t\t`,\n\n\t\t\t\"/empty.js\":         ``,\n\t\t\t\"/empty.esm.js\":     `export {}`,\n\t\t\t\"/empty.json\":       `{}`,\n\t\t\t\"/empty.css\":        ``,\n\t\t\t\"/empty.global-css\": ``,\n\t\t\t\"/empty.local-css\":  ``,\n\n\t\t\t\"/node_modules/pkg/empty.js\":         ``,\n\t\t\t\"/node_modules/pkg/empty.esm.js\":     `export {}`,\n\t\t\t\"/node_modules/pkg/empty.json\":       `{}`,\n\t\t\t\"/node_modules/pkg/empty.css\":        ``,\n\t\t\t\"/node_modules/pkg/empty.global-css\": ``,\n\t\t\t\"/node_modules/pkg/empty.local-css\":  ``,\n\n\t\t\t// Files inside of \"node_modules\" should not generate a warning\n\t\t\t\"/node_modules/pkg/index.js\": `\n\t\t\t\timport * as empty_js from './empty.js'\n\t\t\t\timport * as empty_esm_js from './empty.esm.js'\n\t\t\t\timport * as empty_json from './empty.json'\n\t\t\t\timport * as empty_css from './empty.css'\n\t\t\t\timport * as empty_global_css from './empty.global-css'\n\t\t\t\timport * as empty_local_css from './empty.local-css'\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tempty_js.foo,\n\t\t\t\t\tempty_esm_js.foo,\n\t\t\t\t\tempty_json.foo,\n\t\t\t\t\tempty_css.foo,\n\t\t\t\t\tempty_global_css.foo,\n\t\t\t\t\tempty_local_css.foo,\n\t\t\t\t)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":         config.LoaderJS,\n\t\t\t\t\".json\":       config.LoaderJSON,\n\t\t\t\t\".css\":        config.LoaderCSS,\n\t\t\t\t\".global-css\": config.LoaderGlobalCSS,\n\t\t\t\t\".local-css\":  config.LoaderLocalCSS,\n\t\t\t},\n\t\t},\n\t\texpectedCompileLog: `entry.js: WARNING: Import \"foo\" will always be undefined because the file \"empty.js\" has no exports\nentry.js: WARNING: Import \"foo\" will always be undefined because there is no matching export in \"empty.esm.js\"\nentry.js: WARNING: Import \"foo\" will always be undefined because there is no matching export in \"empty.json\"\nentry.js: WARNING: Import \"foo\" will always be undefined because there is no matching export in \"empty.css\"\nentry.js: WARNING: Import \"foo\" will always be undefined because there is no matching export in \"empty.global-css\"\nentry.js: WARNING: Import \"foo\" will always be undefined because there is no matching export in \"empty.local-css\"\nentry.js: WARNING: Import \"foo\" will always be undefined because the file \"node_modules/pkg/empty.js\" has no exports\nentry.js: WARNING: Import \"foo\" will always be undefined because there is no matching export in \"node_modules/pkg/empty.esm.js\"\nentry.js: WARNING: Import \"foo\" will always be undefined because there is no matching export in \"node_modules/pkg/empty.json\"\nentry.js: WARNING: Import \"foo\" will always be undefined because there is no matching export in \"node_modules/pkg/empty.css\"\nentry.js: WARNING: Import \"foo\" will always be undefined because there is no matching export in \"node_modules/pkg/empty.global-css\"\nentry.js: WARNING: Import \"foo\" will always be undefined because there is no matching export in \"node_modules/pkg/empty.local-css\"\n`,\n\t})\n}\n\nfunc TestCSSMalformedAtImport(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"./url-token-eof.css\";\n\t\t\t\t@import \"./url-token-whitespace-eof.css\";\n\t\t\t\t@import \"./function-token-eof.css\";\n\t\t\t\t@import \"./function-token-whitespace-eof.css\";\n\t\t\t`,\n\t\t\t\"/url-token-eof.css\": `@import url(https://example.com/url-token-eof.css`,\n\t\t\t\"/url-token-whitespace-eof.css\": `\n\t\t\t\t@import url(https://example.com/url-token-whitespace-eof.css\n\t\t\t`,\n\t\t\t\"/function-token-eof.css\": `@import url(\"https://example.com/function-token-eof.css\"`,\n\t\t\t\"/function-token-whitespace-eof.css\": `\n\t\t\t\t@import url(\"https://example.com/function-token-whitespace-eof.css\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedScanLog: `function-token-eof.css: WARNING: Expected \")\" to go with \"(\"\nfunction-token-eof.css: NOTE: The unbalanced \"(\" is here:\nfunction-token-whitespace-eof.css: WARNING: Expected \")\" to go with \"(\"\nfunction-token-whitespace-eof.css: NOTE: The unbalanced \"(\" is here:\nurl-token-eof.css: WARNING: Expected \")\" to end URL token\nurl-token-eof.css: NOTE: The unbalanced \"(\" is here:\nurl-token-eof.css: WARNING: Expected \";\" but found end of file\nurl-token-whitespace-eof.css: WARNING: Expected \")\" to end URL token\nurl-token-whitespace-eof.css: NOTE: The unbalanced \"(\" is here:\nurl-token-whitespace-eof.css: WARNING: Expected \";\" but found end of file\n`,\n\t})\n}\n\nfunc TestCSSAtLayerBeforeImportNoBundle(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@layer layer1, layer2.layer3;\n\t\t\t\t@import \"a.css\";\n\t\t\t\t@import \"b.css\";\n\t\t\t\t@layer layer6.layer7, layer8;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestCSSAtLayerBeforeImportBundle(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@layer layer1, layer2.layer3;\n\t\t\t\t@import \"a.css\";\n\t\t\t\t@import \"b.css\";\n\t\t\t\t@layer layer6.layer7, layer8;\n\t\t\t`,\n\t\t\t\"/a.css\": `\n\t\t\t\t@layer layer4 {\n\t\t\t\t\ta { color: red }\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/b.css\": `\n\t\t\t\t@layer layer5 {\n\t\t\t\t\tb { color: red }\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestCSSAtLayerMergingWithImportConditions(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"a.css\" supports(color: first);\n\n\t\t\t\t@import \"a.css\" supports(color: second);\n\t\t\t\t@import \"b.css\" supports(color: second);\n\n\t\t\t\t@import \"a.css\" supports(color: first);\n\t\t\t\t@import \"b.css\" supports(color: first);\n\n\t\t\t\t@import \"a.css\" supports(color: second);\n\t\t\t\t@import \"b.css\" supports(color: second);\n\n\t\t\t\t@import \"b.css\" supports(color: first);\n\t\t\t`,\n\t\t\t\"/a.css\": `\n\t\t\t\t@layer a;\n\t\t\t\t@import \"http://example.com/a.css\";\n\t\t\t`,\n\t\t\t\"/b.css\": `\n\t\t\t\t@layer b;\n\t\t\t\t@import \"http://example.com/b.css\";\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestCSSCaseInsensitivity(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t/* \"@IMPORT\" should be recognized as an import */\n\t\t\t\t/* \"LAYER(...)\" should wrap with \"@layer\" */\n\t\t\t\t/* \"SUPPORTS(...)\" should wrap with \"@supports\" */\n\t\t\t\t@IMPORT Url(\"nested.css\") LAYER(layer-name) SUPPORTS(supports-condition) list-of-media-queries;\n\t\t\t`,\n\t\t\t\"/nested.css\": `\n\t\t\t\t/* \"from\" should be recognized and optimized to \"0%\" */\n\t\t\t\t@KeyFrames Foo {\n\t\t\t\t\tfroM { OPAcity: 0 }\n\t\t\t\t\ttO { opaCITY: 1 }\n\t\t\t\t}\n\n\t\t\t\tbody {\n\t\t\t\t\t/* \"#FF0000\" should be optimized to \"red\" because \"BACKGROUND-color\" should be recognized */\n\t\t\t\t\tBACKGROUND-color: #FF0000;\n\n\t\t\t\t\t/* This should be optimized to 50px */\n\t\t\t\t\twidth: CaLc(20Px + 30pX);\n\n\t\t\t\t\t/* This URL token should be recognized and bundled */\n\t\t\t\t\tbackground-IMAGE: Url(image.png);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/image.png\": `...`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.css\",\n\t\t\tMinifySyntax:  true,\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t\t\".png\": config.LoaderCopy,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestCSSAssetPathsWithSpacesBundle(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\ta {\n\t\t\t\t\tbackground: url(foo.copy);\n\t\t\t\t\tbackground: url(foo.file);\n\t\t\t\t}\n\n\t\t\t\t/*! The URLs for \"foo 2\" files must have quotes in the final CSS */\n\t\t\t\tb {\n\t\t\t\t\tbackground: url('foo 2.copy');\n\t\t\t\t\tbackground: url('foo 2.file');\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/foo.file\":   `...`,\n\t\t\t\"/foo.copy\":   `...`,\n\t\t\t\"/foo 2.file\": `...`,\n\t\t\t\"/foo 2.copy\": `...`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.css\",\n\t\t\tMinifySyntax:  true,\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\":  config.LoaderCSS,\n\t\t\t\t\".file\": config.LoaderFile,\n\t\t\t\t\".copy\": config.LoaderCopy,\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "internal/bundler_tests/bundler_dce_test.go",
    "content": "package bundler_tests\n\nimport (\n\t\"regexp\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n)\n\nvar dce_suite = suite{\n\tname: \"dce\",\n}\n\nfunc TestPackageJsonSideEffectsFalseKeepNamedImportES6(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": false\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseKeepNamedImportCommonJS(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texports.foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": false\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseKeepStarImportES6(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport * as ns from \"demo-pkg\"\n\t\t\t\tconsole.log(ns)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": false\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseKeepStarImportCommonJS(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport * as ns from \"demo-pkg\"\n\t\t\t\tconsole.log(ns)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texports.foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": false\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsTrueKeepES6(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": true\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsTrueKeepCommonJS(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texports.foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": true\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseKeepBareImportAndRequireES6(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport \"demo-pkg\"\n\t\t\t\trequire('demo-pkg')\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": false\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: WARNING: Ignoring this import because \"Users/user/project/node_modules/demo-pkg/index.js\" was marked as having no side effects\nUsers/user/project/node_modules/demo-pkg/package.json: NOTE: \"sideEffects\" is false in the enclosing \"package.json\" file:\n`,\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseKeepBareImportAndRequireCommonJS(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport \"demo-pkg\"\n\t\t\t\trequire('demo-pkg')\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texports.foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": false\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: WARNING: Ignoring this import because \"Users/user/project/node_modules/demo-pkg/index.js\" was marked as having no side effects\nUsers/user/project/node_modules/demo-pkg/package.json: NOTE: \"sideEffects\" is false in the enclosing \"package.json\" file:\n`,\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseRemoveBareImportES6(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": false\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: WARNING: Ignoring this import because \"Users/user/project/node_modules/demo-pkg/index.js\" was marked as having no side effects\nUsers/user/project/node_modules/demo-pkg/package.json: NOTE: \"sideEffects\" is false in the enclosing \"package.json\" file:\n`,\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseRemoveBareImportCommonJS(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texports.foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": false\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: WARNING: Ignoring this import because \"Users/user/project/node_modules/demo-pkg/index.js\" was marked as having no side effects\nUsers/user/project/node_modules/demo-pkg/package.json: NOTE: \"sideEffects\" is false in the enclosing \"package.json\" file:\n`,\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseRemoveNamedImportES6(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": false\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseRemoveNamedImportCommonJS(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texports.foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": false\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseRemoveStarImportES6(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport * as ns from \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": false\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseRemoveStarImportCommonJS(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport * as ns from \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texports.foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": false\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsArrayRemove(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": []\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsArrayKeep(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": [\"./index.js\"]\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsArrayKeepMainUseModule(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-main.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('TEST FAILED')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-module.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('TEST FAILED')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"index-main.js\",\n\t\t\t\t\t\"module\": \"index-module.js\",\n\t\t\t\t\t\"sideEffects\": [\"./index-main.js\"]\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMainFields:    []string{\"module\"},\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsArrayKeepMainUseMain(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-main.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('this should be kept')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-module.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('TEST FAILED')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"index-main.js\",\n\t\t\t\t\t\"module\": \"index-module.js\",\n\t\t\t\t\t\"sideEffects\": [\"./index-main.js\"]\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMainFields:    []string{\"main\"},\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsArrayKeepMainImplicitModule(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-main.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('TEST FAILED')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-module.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('TEST FAILED')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"index-main.js\",\n\t\t\t\t\t\"module\": \"index-module.js\",\n\t\t\t\t\t\"sideEffects\": [\"./index-main.js\"]\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsArrayKeepMainImplicitMain(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t\timport \"./require-demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/require-demo-pkg.js\": `\n\t\t\t\t// This causes \"index-main.js\" to be selected\n\t\t\t\trequire('demo-pkg')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-main.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('this should be kept')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-module.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('TEST FAILED')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"index-main.js\",\n\t\t\t\t\t\"module\": \"index-module.js\",\n\t\t\t\t\t\"sideEffects\": [\"./index-main.js\"]\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsArrayKeepModuleUseModule(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-main.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('TEST FAILED')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-module.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('this should be kept')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"index-main.js\",\n\t\t\t\t\t\"module\": \"index-module.js\",\n\t\t\t\t\t\"sideEffects\": [\"./index-module.js\"]\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMainFields:    []string{\"module\"},\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsArrayKeepModuleUseMain(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-main.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('TEST FAILED')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-module.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('TEST FAILED')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"index-main.js\",\n\t\t\t\t\t\"module\": \"index-module.js\",\n\t\t\t\t\t\"sideEffects\": [\"./index-module.js\"]\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMainFields:    []string{\"main\"},\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsArrayKeepModuleImplicitModule(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-main.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('TEST FAILED')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-module.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('this should be kept')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"index-main.js\",\n\t\t\t\t\t\"module\": \"index-module.js\",\n\t\t\t\t\t\"sideEffects\": [\"./index-module.js\"]\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsArrayKeepModuleImplicitMain(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t\timport \"./require-demo-pkg\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/require-demo-pkg.js\": `\n\t\t\t\t// This causes \"index-main.js\" to be selected\n\t\t\t\trequire('demo-pkg')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-main.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('this should be kept')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index-module.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('TEST FAILED')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"index-main.js\",\n\t\t\t\t\t\"module\": \"index-module.js\",\n\t\t\t\t\t\"sideEffects\": [\"./index-module.js\"]\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsArrayGlob(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport \"demo-pkg/keep/this/file\"\n\t\t\t\timport \"demo-pkg/remove/this/file\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/keep/this/file.js\": `\n\t\t\t\tconsole.log('this should be kept')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/remove/this/file.js\": `\n\t\t\t\tconsole.log('TEST FAILED')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": [\n\t\t\t\t\t\t\"./ke?p/*/file.js\",\n\t\t\t\t\t\t\"./remove/this/file.j\",\n\t\t\t\t\t\t\"./re?ve/this/file.js\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: WARNING: Ignoring this import because \"Users/user/project/node_modules/demo-pkg/remove/this/file.js\" was marked as having no side effects\nUsers/user/project/node_modules/demo-pkg/package.json: NOTE: It was excluded from the \"sideEffects\" array in the enclosing \"package.json\" file:\n`,\n\t})\n}\n\nfunc TestPackageJsonSideEffectsNestedDirectoryRemove(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg/a/b/c\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": false\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/a/b/c/index.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsKeepExportDefaultExpr(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport foo from \"demo-pkg\"\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texport default exprWithSideEffects()\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": false\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseNoWarningInNodeModulesIssue999(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport \"demo-pkg\"\n\t\t\t\tconsole.log('used import')\n\t\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\timport \"demo-pkg2\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg2/index.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log('hello')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg2/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": false\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseIntermediateFilesUnused(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texport {foo} from \"./foo.js\"\n\t\t\t\tthrow 'REMOVE THIS'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{ \"sideEffects\": false }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseIntermediateFilesUsed(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"demo-pkg\"\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\texport {foo} from \"./foo.js\"\n\t\t\t\tthrow 'keep this'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{ \"sideEffects\": false }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseIntermediateFilesChainAll(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"a\"\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/a/index.js\": `\n\t\t\t\texport {foo} from \"b\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/a/package.json\": `\n\t\t\t\t{ \"sideEffects\": false }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/b/index.js\": `\n\t\t\t\texport {foo} from \"c\"\n\t\t\t\tthrow 'keep this'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/b/package.json\": `\n\t\t\t\t{ \"sideEffects\": false }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/c/index.js\": `\n\t\t\t\texport {foo} from \"d\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/c/package.json\": `\n\t\t\t\t{ \"sideEffects\": false }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/d/index.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/d/package.json\": `\n\t\t\t\t{ \"sideEffects\": false }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseIntermediateFilesChainOne(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"a\"\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/a/index.js\": `\n\t\t\t\texport {foo} from \"b\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/b/index.js\": `\n\t\t\t\texport {foo} from \"c\"\n\t\t\t\tthrow 'keep this'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/b/package.json\": `\n\t\t\t\t{ \"sideEffects\": false }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/c/index.js\": `\n\t\t\t\texport {foo} from \"d\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/d/index.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseIntermediateFilesDiamond(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {foo} from \"a\"\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/a/index.js\": `\n\t\t\t\texport * from \"b1\"\n\t\t\t\texport * from \"b2\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/b1/index.js\": `\n\t\t\t\texport {foo} from \"c\"\n\t\t\t\tthrow 'keep this 1'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/b1/package.json\": `\n\t\t\t\t{ \"sideEffects\": false }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/b2/index.js\": `\n\t\t\t\texport {foo} from \"c\"\n\t\t\t\tthrow 'keep this 2'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/b2/package.json\": `\n\t\t\t\t{ \"sideEffects\": false }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/c/index.js\": `\n\t\t\t\texport {foo} from \"d\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/d/index.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseOneFork(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport(\"a\").then(x => assert(x.foo === \"foo\"))\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/a/index.js\": `\n\t\t\t\texport {foo} from \"b\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/b/index.js\": `\n\t\t\t\texport {foo, bar} from \"c\"\n\t\t\t\texport {baz} from \"d\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/b/package.json\": `\n\t\t\t\t{ \"sideEffects\": false }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/c/index.js\": `\n\t\t\t\texport let foo = \"foo\"\n\t\t\t\texport let bar = \"bar\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/d/index.js\": `\n\t\t\t\texport let baz = \"baz\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseAllFork(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport(\"a\").then(x => assert(x.foo === \"foo\"))\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/a/index.js\": `\n\t\t\t\texport {foo} from \"b\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/b/index.js\": `\n\t\t\t\texport {foo, bar} from \"c\"\n\t\t\t\texport {baz} from \"d\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/b/package.json\": `\n\t\t\t\t{ \"sideEffects\": false }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/c/index.js\": `\n\t\t\t\texport let foo = \"foo\"\n\t\t\t\texport let bar = \"bar\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/c/package.json\": `\n\t\t\t\t{ \"sideEffects\": false }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/d/index.js\": `\n\t\t\t\texport let baz = \"baz\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/d/package.json\": `\n\t\t\t\t{ \"sideEffects\": false }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestJSONLoaderRemoveUnused(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport unused from \"./example.json\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/example.json\": `{\"data\": true}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTextLoaderRemoveUnused(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport unused from \"./example.txt\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/example.txt\": `some data`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestBase64LoaderRemoveUnused(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport unused from \"./example.data\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/example.data\": `some data`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":   config.LoaderJS,\n\t\t\t\t\".data\": config.LoaderBase64,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestDataURLLoaderRemoveUnused(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport unused from \"./example.data\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/example.data\": `some data`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":   config.LoaderJS,\n\t\t\t\t\".data\": config.LoaderDataURL,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestFileLoaderRemoveUnused(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport unused from \"./example.data\"\n\t\t\t\tconsole.log('unused import')\n\t\t\t`,\n\t\t\t\"/example.data\": `some data`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":   config.LoaderJS,\n\t\t\t\t\".data\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestRemoveUnusedImportMeta(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction foo() {\n\t\t\t\t\tconsole.log(import.meta.url, import.meta.path)\n\t\t\t\t}\n\t\t\t\tconsole.log('foo is unused')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRemoveUnusedPureCommentCalls(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction bar() {}\n\t\t\t\tlet bare = foo(bar);\n\n\t\t\t\tlet at_yes = /* @__PURE__ */ foo(bar);\n\t\t\t\tlet at_no = /* @__PURE__ */ foo(bar());\n\t\t\t\tlet new_at_yes = /* @__PURE__ */ new foo(bar);\n\t\t\t\tlet new_at_no = /* @__PURE__ */ new foo(bar());\n\n\t\t\t\tlet nospace_at_yes = /*@__PURE__*/ foo(bar);\n\t\t\t\tlet nospace_at_no = /*@__PURE__*/ foo(bar());\n\t\t\t\tlet nospace_new_at_yes = /*@__PURE__*/ new foo(bar);\n\t\t\t\tlet nospace_new_at_no = /*@__PURE__*/ new foo(bar());\n\n\t\t\t\tlet num_yes = /* #__PURE__ */ foo(bar);\n\t\t\t\tlet num_no = /* #__PURE__ */ foo(bar());\n\t\t\t\tlet new_num_yes = /* #__PURE__ */ new foo(bar);\n\t\t\t\tlet new_num_no = /* #__PURE__ */ new foo(bar());\n\n\t\t\t\tlet nospace_num_yes = /*#__PURE__*/ foo(bar);\n\t\t\t\tlet nospace_num_no = /*#__PURE__*/ foo(bar());\n\t\t\t\tlet nospace_new_num_yes = /*#__PURE__*/ new foo(bar);\n\t\t\t\tlet nospace_new_num_no = /*#__PURE__*/ new foo(bar());\n\n\t\t\t\tlet dot_yes = /* @__PURE__ */ foo(sideEffect()).dot(bar);\n\t\t\t\tlet dot_no = /* @__PURE__ */ foo(sideEffect()).dot(bar());\n\t\t\t\tlet new_dot_yes = /* @__PURE__ */ new foo(sideEffect()).dot(bar);\n\t\t\t\tlet new_dot_no = /* @__PURE__ */ new foo(sideEffect()).dot(bar());\n\n\t\t\t\tlet nested_yes = [1, /* @__PURE__ */ foo(bar), 2];\n\t\t\t\tlet nested_no = [1, /* @__PURE__ */ foo(bar()), 2];\n\t\t\t\tlet new_nested_yes = [1, /* @__PURE__ */ new foo(bar), 2];\n\t\t\t\tlet new_nested_no = [1, /* @__PURE__ */ new foo(bar()), 2];\n\n\t\t\t\tlet single_at_yes = // @__PURE__\n\t\t\t\t\tfoo(bar);\n\t\t\t\tlet single_at_no = // @__PURE__\n\t\t\t\t\tfoo(bar());\n\t\t\t\tlet new_single_at_yes = // @__PURE__\n\t\t\t\t\tnew foo(bar);\n\t\t\t\tlet new_single_at_no = // @__PURE__\n\t\t\t\t\tnew foo(bar());\n\n\t\t\t\tlet single_num_yes = // #__PURE__\n\t\t\t\t\tfoo(bar);\n\t\t\t\tlet single_num_no = // #__PURE__\n\t\t\t\t\tfoo(bar());\n\t\t\t\tlet new_single_num_yes = // #__PURE__\n\t\t\t\t\tnew foo(bar);\n\t\t\t\tlet new_single_num_no = // #__PURE__\n\t\t\t\t\tnew foo(bar());\n\n\t\t\t\tlet bad_no = /* __PURE__ */ foo(bar);\n\t\t\t\tlet new_bad_no = /* __PURE__ */ new foo(bar);\n\n\t\t\t\tlet parens_no = (/* @__PURE__ */ foo)(bar);\n\t\t\t\tlet new_parens_no = new (/* @__PURE__ */ foo)(bar);\n\n\t\t\t\tlet exp_no = /* @__PURE__ */ foo() ** foo();\n\t\t\t\tlet new_exp_no = /* @__PURE__ */ new foo() ** foo();\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRemoveUnusedNoSideEffectsTaggedTemplates(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// @__NO_SIDE_EFFECTS__\n\t\t\t\tfunction foo() {}\n\n\t\t\t\tfoo` + \"`remove`\" + `;\n\t\t\t\tfoo` + \"`remove${null}`\" + `;\n\t\t\t\tfoo` + \"`remove${123}`\" + `;\n\n\t\t\t\tuse(foo` + \"`keep`\" + `);\n\t\t\t\tfoo` + \"`remove this part ${keep} and this ${alsoKeep}`\" + `;\n\t\t\t\t` + \"`remove this part ${keep} and this ${alsoKeep}`\" + `;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMinifySyntax:  true,\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingReactElements(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\tfunction Foo() {}\n\n\t\t\t\tlet a = <div/>\n\t\t\t\tlet b = <Foo>{a}</Foo>\n\t\t\t\tlet c = <>{b}</>\n\n\t\t\t\tlet d = <div/>\n\t\t\t\tlet e = <Foo>{d}</Foo>\n\t\t\t\tlet f = <>{e}</>\n\t\t\t\tconsole.log(f)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestDisableTreeShaking(t *testing.T) {\n\tdefines := config.ProcessDefines([]config.DefineData{\n\t\t{KeyParts: []string{\"pure\"}, Flags: config.CallCanBeUnwrappedIfUnused},\n\t\t{KeyParts: []string{\"some\", \"fn\"}, Flags: config.CallCanBeUnwrappedIfUnused},\n\t})\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\timport './remove-me'\n\t\t\t\tfunction RemoveMe1() {}\n\t\t\t\tlet removeMe2 = 0\n\t\t\t\tclass RemoveMe3 {}\n\n\t\t\t\timport './keep-me'\n\t\t\t\tfunction KeepMe1() {}\n\t\t\t\tlet keepMe2 = <KeepMe1/>\n\t\t\t\tfunction keepMe3() { console.log('side effects') }\n\t\t\t\tlet keepMe4 = /* @__PURE__ */ keepMe3()\n\t\t\t\tlet keepMe5 = pure()\n\t\t\t\tlet keepMe6 = some.fn()\n\t\t\t`,\n\t\t\t\"/remove-me.js\": `\n\t\t\t\texport default 'unused'\n\t\t\t`,\n\t\t\t\"/keep-me/index.js\": `\n\t\t\t\tconsole.log('side effects')\n\t\t\t`,\n\t\t\t\"/keep-me/package.json\": `\n\t\t\t\t{ \"sideEffects\": false }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:                 config.ModeBundle,\n\t\t\tAbsOutputFile:        \"/out.js\",\n\t\t\tIgnoreDCEAnnotations: true,\n\t\t\tDefines:              &defines,\n\t\t},\n\t})\n}\n\nfunc TestDeadCodeFollowingJump(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction testReturn() {\n\t\t\t\t\tif (true) return y + z()\n\t\t\t\t\tif (FAIL) return FAIL\n\t\t\t\t\tif (x) { var y }\n\t\t\t\t\tfunction z() { KEEP_ME() }\n\t\t\t\t\treturn FAIL\n\t\t\t\t}\n\n\t\t\t\tfunction testThrow() {\n\t\t\t\t\tif (true) throw y + z()\n\t\t\t\t\tif (FAIL) return FAIL\n\t\t\t\t\tif (x) { var y }\n\t\t\t\t\tfunction z() { KEEP_ME() }\n\t\t\t\t\treturn FAIL\n\t\t\t\t}\n\n\t\t\t\tfunction testBreak() {\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\tif (true) {\n\t\t\t\t\t\t\ty + z()\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (FAIL) return FAIL\n\t\t\t\t\t\tif (x) { var y }\n\t\t\t\t\t\tfunction z() { KEEP_ME() }\n\t\t\t\t\t\treturn FAIL\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfunction testContinue() {\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\tif (true) {\n\t\t\t\t\t\t\ty + z()\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (FAIL) return FAIL\n\t\t\t\t\t\tif (x) { var y }\n\t\t\t\t\t\tfunction z() { KEEP_ME() }\n\t\t\t\t\t\treturn FAIL\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfunction testStmts() {\n\t\t\t\t\treturn [a, b, c, d, e, f, g, h, i]\n\n\t\t\t\t\twhile (x) { var a }\n\t\t\t\t\twhile (FAIL) { let FAIL }\n\n\t\t\t\t\tdo { var b } while (x)\n\t\t\t\t\tdo { let FAIL } while (FAIL)\n\n\t\t\t\t\tfor (var c; ;) ;\n\t\t\t\t\tfor (let FAIL; ;) ;\n\n\t\t\t\t\tfor (var d in x) ;\n\t\t\t\t\tfor (let FAIL in FAIL) ;\n\n\t\t\t\t\tfor (var e of x) ;\n\t\t\t\t\tfor (let FAIL of FAIL) ;\n\n\t\t\t\t\tif (x) { var f }\n\t\t\t\t\tif (FAIL) { let FAIL }\n\n\t\t\t\t\tif (x) ; else { var g }\n\t\t\t\t\tif (FAIL) ; else { let FAIL }\n\n\t\t\t\t\t{ var h }\n\t\t\t\t\t{ let FAIL }\n\n\t\t\t\t\tx: { var i }\n\t\t\t\t\tx: { let FAIL }\n\t\t\t\t}\n\n\t\t\t\ttestReturn()\n\t\t\t\ttestThrow()\n\t\t\t\ttestBreak()\n\t\t\t\ttestContinue()\n\t\t\t\ttestStmts()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMinifySyntax:  true,\n\t\t},\n\t})\n}\n\nfunc TestDeadCodeInsideEmptyTry(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\ttry { foo() }\n\t\t\t\tcatch { require('./a') }\n\t\t\t\tfinally { require('./b') }\n\n\t\t\t\ttry {}\n\t\t\t\tcatch { require('./c') }\n\t\t\t\tfinally { require('./d') }\n\t\t\t`,\n\t\t\t\"/a.js\": ``,\n\t\t\t\"/b.js\": ``,\n\t\t\t\"/c.js\": `TEST FAILED`, // Dead code paths should not import code\n\t\t\t\"/d.js\": ``,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestDeadCodeInsideUnusedCases(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// Unknown test value\n\t\t\t\tswitch (x) {\n\t\t\t\t\tcase 0: _ = require('./a'); break\n\t\t\t\t\tcase 1: _ = require('./b'); break\n\t\t\t\t}\n\n\t\t\t\t// Known test value\n\t\t\t\tswitch (1) {\n\t\t\t\t\tcase 0: _ = require('./FAIL-known-0'); break\n\t\t\t\t\tcase 1: _ = require('./a'); break\n\t\t\t\t\tcase 1: _ = require('./FAIL-known-1'); break\n\t\t\t\t\tcase 2: _ = require('./FAIL-known-2'); break\n\t\t\t\t}\n\n\t\t\t\t// Check for \"default\"\n\t\t\t\tswitch (0) {\n\t\t\t\t\tcase 1: _ = require('./FAIL-default-1'); break\n\t\t\t\t\tdefault: _ = require('./a'); break\n\t\t\t\t}\n\t\t\t\tswitch (1) {\n\t\t\t\t\tcase 1: _ = require('./a'); break\n\t\t\t\t\tdefault: _ = require('./FAIL-default'); break\n\t\t\t\t}\n\t\t\t\tswitch (0) {\n\t\t\t\t\tcase 1: _ = require('./FAIL-default-1'); break\n\t\t\t\t\tdefault: _ = require('./FAIL-default'); break\n\t\t\t\t\tcase 0: _ = require('./a'); break\n\t\t\t\t}\n\n\t\t\t\t// Check for non-constant cases\n\t\t\t\tswitch (1) {\n\t\t\t\t\tcase x: _ = require('./a'); break\n\t\t\t\t\tcase 1: _ = require('./b'); break\n\t\t\t\t\tcase x: _ = require('./FAIL-x'); break\n\t\t\t\t\tdefault: _ = require('./FAIL-x-default'); break\n\t\t\t\t}\n\n\t\t\t\t// Check for other kinds of jumps\n\t\t\t\tfor (const x of y)\n\t\t\t\t\tswitch (1) {\n\t\t\t\t\t\tcase 0: _ = require('./FAIL-continue-0'); continue\n\t\t\t\t\t\tcase 1: _ = require('./a'); continue\n\t\t\t\t\t\tcase 2: _ = require('./FAIL-continue-2'); continue\n\t\t\t\t\t}\n\t\t\t\tx = () => {\n\t\t\t\t\tswitch (1) {\n\t\t\t\t\t\tcase 0: _ = require('./FAIL-return-0'); return\n\t\t\t\t\t\tcase 1: _ = require('./a'); return\n\t\t\t\t\t\tcase 2: _ = require('./FAIL-return-2'); return\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Check for fall-through\n\t\t\t\tswitch ('b') {\n\t\t\t\t\tcase 'a': _ = require('./FAIL-fallthrough-a')\n\t\t\t\t\tcase 'b': _ = require('./a')\n\t\t\t\t\tcase 'c': _ = require('./b'); break\n\t\t\t\t\tcase 'd': _ = require('./FAIL-fallthrough-d')\n\t\t\t\t}\n\t\t\t\tswitch ('b') {\n\t\t\t\t\tcase 'a': _ = require('./FAIL-fallthrough-a')\n\t\t\t\t\tcase 'b':\n\t\t\t\t\tcase 'c': _ = require('./a')\n\t\t\t\t\tcase 'd': _ = require('./b'); break\n\t\t\t\t\tcase 'e': _ = require('./FAIL-fallthrough-e')\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/a.js\": ``,\n\t\t\t\"/b.js\": ``,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: WARNING: This case clause will never be evaluated because it duplicates an earlier case clause\nentry.js: NOTE: The earlier case clause is here:\nentry.js: WARNING: This case clause will never be evaluated because it duplicates an earlier case clause\nentry.js: NOTE: The earlier case clause is here:\n`,\n\t})\n}\n\nfunc TestRemoveTrailingReturn(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction foo() {\n\t\t\t\t\tif (a) b()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tfunction bar() {\n\t\t\t\t\tif (a) b()\n\t\t\t\t\treturn KEEP_ME\n\t\t\t\t}\n\t\t\t\texport default [\n\t\t\t\t\tfoo,\n\t\t\t\t\tbar,\n\t\t\t\t\tfunction () {\n\t\t\t\t\t\tif (a) b()\n\t\t\t\t\t\treturn\n\t\t\t\t\t},\n\t\t\t\t\tfunction () {\n\t\t\t\t\t\tif (a) b()\n\t\t\t\t\t\treturn KEEP_ME\n\t\t\t\t\t},\n\t\t\t\t\t() => {\n\t\t\t\t\t\tif (a) b()\n\t\t\t\t\t\treturn\n\t\t\t\t\t},\n\t\t\t\t\t() => {\n\t\t\t\t\t\tif (a) b()\n\t\t\t\t\t\treturn KEEP_ME\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMinifySyntax:  true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t},\n\t})\n}\n\nfunc TestImportReExportOfNamespaceImport(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.js\": `\n\t\t\t\timport * as ns from 'pkg'\n\t\t\t\tconsole.log(ns.foo)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/index.js\": `\n\t\t\t\texport { default as foo } from './foo'\n\t\t\t\texport { default as bar } from './bar'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/package.json\": `\n\t\t\t\t{ \"sideEffects\": false }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/foo.js\": `\n\t\t\t\tmodule.exports = 123\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/bar.js\": `\n\t\t\t\tmodule.exports = 'abc'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingImportIdentifier(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as a from './a'\n\t\t\t\tnew a.Keep()\n\t\t\t`,\n\t\t\t\"/a.js\": `\n\t\t\t\timport * as b from './b'\n\t\t\t\texport class Keep extends b.Base {}\n\t\t\t\texport class REMOVE extends b.Base {}\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\texport class Base {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingObjectProperty(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tlet remove1 = { x: 'x' }\n\t\t\t\tlet remove2 = { x() {} }\n\t\t\t\tlet remove3 = { get x() {} }\n\t\t\t\tlet remove4 = { set x(_) {} }\n\t\t\t\tlet remove5 = { async x() {} }\n\t\t\t\tlet remove6 = { ['x']: 'x' }\n\t\t\t\tlet remove7 = { ['x']() {} }\n\t\t\t\tlet remove8 = { get ['x']() {} }\n\t\t\t\tlet remove9 = { set ['x'](_) {} }\n\t\t\t\tlet remove10 = { async ['x']() {} }\n\t\t\t\tlet remove11 = { [0]: 'x' }\n\t\t\t\tlet remove12 = { [null]: 'x' }\n\t\t\t\tlet remove13 = { [undefined]: 'x' }\n\t\t\t\tlet remove14 = { [false]: 'x' }\n\t\t\t\tlet remove15 = { [0n]: 'x' }\n\t\t\t\tlet remove16 = { toString() {} }\n\n\t\t\t\tlet keep1 = { x }\n\t\t\t\tlet keep2 = { x: x }\n\t\t\t\tlet keep3 = { ...x }\n\t\t\t\tlet keep4 = { [x]: 'x' }\n\t\t\t\tlet keep5 = { [x]() {} }\n\t\t\t\tlet keep6 = { get [x]() {} }\n\t\t\t\tlet keep7 = { set [x](_) {} }\n\t\t\t\tlet keep8 = { async [x]() {} }\n\t\t\t\tlet keep9 = { [{ toString() {} }]: 'x' }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tTreeShaking:   true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingClassProperty(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tlet remove1 = class { x }\n\t\t\t\tlet remove2 = class { x = x }\n\t\t\t\tlet remove3 = class { x() {} }\n\t\t\t\tlet remove4 = class { get x() {} }\n\t\t\t\tlet remove5 = class { set x(_) {} }\n\t\t\t\tlet remove6 = class { async x() {} }\n\t\t\t\tlet remove7 = class { ['x'] = x }\n\t\t\t\tlet remove8 = class { ['x']() {} }\n\t\t\t\tlet remove9 = class { get ['x']() {} }\n\t\t\t\tlet remove10 = class { set ['x'](_) {} }\n\t\t\t\tlet remove11 = class { async ['x']() {} }\n\t\t\t\tlet remove12 = class { [0] = 'x' }\n\t\t\t\tlet remove13 = class { [null] = 'x' }\n\t\t\t\tlet remove14 = class { [undefined] = 'x' }\n\t\t\t\tlet remove15 = class { [false] = 'x' }\n\t\t\t\tlet remove16 = class { [0n] = 'x' }\n\t\t\t\tlet remove17 = class { toString() {} }\n\n\t\t\t\tlet keep1 = class { [x] = 'x' }\n\t\t\t\tlet keep2 = class { [x]() {} }\n\t\t\t\tlet keep3 = class { get [x]() {} }\n\t\t\t\tlet keep4 = class { set [x](_) {} }\n\t\t\t\tlet keep5 = class { async [x]() {} }\n\t\t\t\tlet keep6 = class { [{ toString() {} }] = 'x' }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tTreeShaking:   true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingClassStaticProperty(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tlet remove1 = class { static x }\n\t\t\t\tlet remove3 = class { static x() {} }\n\t\t\t\tlet remove4 = class { static get x() {} }\n\t\t\t\tlet remove5 = class { static set x(_) {} }\n\t\t\t\tlet remove6 = class { static async x() {} }\n\t\t\t\tlet remove8 = class { static ['x']() {} }\n\t\t\t\tlet remove9 = class { static get ['x']() {} }\n\t\t\t\tlet remove10 = class { static set ['x'](_) {} }\n\t\t\t\tlet remove11 = class { static async ['x']() {} }\n\t\t\t\tlet remove12 = class { static [0] = 'x' }\n\t\t\t\tlet remove13 = class { static [null] = 'x' }\n\t\t\t\tlet remove14 = class { static [undefined] = 'x' }\n\t\t\t\tlet remove15 = class { static [false] = 'x' }\n\t\t\t\tlet remove16 = class { static [0n] = 'x' }\n\t\t\t\tlet remove17 = class { static toString() {} }\n\n\t\t\t\tlet keep1 = class { static x = x }\n\t\t\t\tlet keep2 = class { static ['x'] = x }\n\t\t\t\tlet keep3 = class { static [x] = 'x' }\n\t\t\t\tlet keep4 = class { static [x]() {} }\n\t\t\t\tlet keep5 = class { static get [x]() {} }\n\t\t\t\tlet keep6 = class { static set [x](_) {} }\n\t\t\t\tlet keep7 = class { static async [x]() {} }\n\t\t\t\tlet keep8 = class { static [{ toString() {} }] = 'x' }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tTreeShaking:   true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingUnaryOperators(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// These operators may have side effects\n\t\t\t\tlet keep;\n\t\t\t\t+keep;\n\t\t\t\t-keep;\n\t\t\t\t~keep;\n\t\t\t\tdelete keep;\n\t\t\t\t++keep;\n\t\t\t\t--keep;\n\t\t\t\tkeep++;\n\t\t\t\tkeep--;\n\n\t\t\t\t// These operators never have side effects\n\t\t\t\tlet REMOVE;\n\t\t\t\t!REMOVE;\n\t\t\t\tvoid REMOVE;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingBinaryOperators(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// These operators may have side effects\n\t\t\t\tlet keep, keep2;\n\t\t\t\tkeep + keep2;\n\t\t\t\tkeep - keep2;\n\t\t\t\tkeep * keep2;\n\t\t\t\tkeep / keep2;\n\t\t\t\tkeep % keep2;\n\t\t\t\tkeep ** keep2;\n\t\t\t\tkeep < keep2;\n\t\t\t\tkeep <= keep2;\n\t\t\t\tkeep > keep2;\n\t\t\t\tkeep >= keep2;\n\t\t\t\tkeep in keep2;\n\t\t\t\tkeep instanceof keep2;\n\t\t\t\tkeep << keep2;\n\t\t\t\tkeep >> keep2;\n\t\t\t\tkeep >>> keep2;\n\t\t\t\tkeep == keep2;\n\t\t\t\tkeep != keep2;\n\t\t\t\tkeep | keep2;\n\t\t\t\tkeep & keep2;\n\t\t\t\tkeep ^ keep2;\n\t\t\t\tkeep = keep2;\n\t\t\t\tkeep += keep2;\n\t\t\t\tkeep -= keep2;\n\t\t\t\tkeep *= keep2;\n\t\t\t\tkeep /= keep2;\n\t\t\t\tkeep %= keep2;\n\t\t\t\tkeep **= keep2;\n\t\t\t\tkeep <<= keep2;\n\t\t\t\tkeep >>= keep2;\n\t\t\t\tkeep >>>= keep2;\n\t\t\t\tkeep |= keep2;\n\t\t\t\tkeep &= keep2;\n\t\t\t\tkeep ^= keep2;\n\t\t\t\tkeep ??= keep2;\n\t\t\t\tkeep ||= keep2;\n\t\t\t\tkeep &&= keep2;\n\n\t\t\t\t// These operators never have side effects\n\t\t\t\tlet REMOVE, REMOVE2;\n\t\t\t\tREMOVE === REMOVE2;\n\t\t\t\tREMOVE !== REMOVE2;\n\t\t\t\tREMOVE, REMOVE2;\n\t\t\t\tREMOVE ?? REMOVE2;\n\t\t\t\tREMOVE || REMOVE2;\n\t\t\t\tREMOVE && REMOVE2;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingNoBundleESM(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction keep() {}\n\t\t\t\tfunction unused() {}\n\t\t\t\tkeep()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingNoBundleCJS(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction keep() {}\n\t\t\t\tfunction unused() {}\n\t\t\t\tkeep()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingNoBundleIIFE(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction keep() {}\n\t\t\t\tfunction REMOVE() {}\n\t\t\t\tkeep()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingInESMWrapper(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {keep1} from './lib'\n\t\t\t\tconsole.log(keep1(), require('./cjs'))\n\t\t\t`,\n\t\t\t\"/cjs.js\": `\n\t\t\t\timport {keep2} from './lib'\n\t\t\t\texport default keep2()\n\t\t\t`,\n\t\t\t\"/lib.js\": `\n\t\t\t\texport let keep1 = () => 'keep1'\n\t\t\t\texport let keep2 = () => 'keep2'\n\t\t\t\texport let REMOVE = () => 'REMOVE'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestDCETypeOf(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// These should be removed because they have no side effects\n\t\t\t\ttypeof x_REMOVE\n\t\t\t\ttypeof v_REMOVE\n\t\t\t\ttypeof f_REMOVE\n\t\t\t\ttypeof g_REMOVE\n\t\t\t\ttypeof a_REMOVE\n\t\t\t\tvar v_REMOVE\n\t\t\t\tfunction f_REMOVE() {}\n\t\t\t\tfunction* g_REMOVE() {}\n\t\t\t\tasync function a_REMOVE() {}\n\n\t\t\t\t// These technically have side effects due to TDZ, but this is not currently handled\n\t\t\t\ttypeof c_remove\n\t\t\t\ttypeof l_remove\n\t\t\t\ttypeof s_remove\n\t\t\t\tconst c_remove = 0\n\t\t\t\tlet l_remove\n\t\t\t\tclass s_remove {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestDCETypeOfEqualsString(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tvar hasBar = typeof bar !== 'undefined'\n\t\t\t\tif (false) console.log(hasBar)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestDCETypeOfEqualsStringMangle(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// Everything here should be removed as dead code due to tree shaking\n\t\t\t\tvar hasBar = typeof bar !== 'undefined'\n\t\t\t\tif (false) console.log(hasBar)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tMinifySyntax:  true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestDCETypeOfEqualsStringGuardCondition(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// Everything here should be removed as dead code due to tree shaking\n\t\t\t\tvar REMOVE_1 = typeof x !== 'undefined' ? x : null\n\t\t\t\tvar REMOVE_1 = typeof x != 'undefined' ? x : null\n\t\t\t\tvar REMOVE_1 = typeof x === 'undefined' ? null : x\n\t\t\t\tvar REMOVE_1 = typeof x == 'undefined' ? null : x\n\t\t\t\tvar REMOVE_1 = typeof x !== 'undefined' && x\n\t\t\t\tvar REMOVE_1 = typeof x != 'undefined' && x\n\t\t\t\tvar REMOVE_1 = typeof x === 'undefined' || x\n\t\t\t\tvar REMOVE_1 = typeof x == 'undefined' || x\n\t\t\t\tvar REMOVE_1 = 'undefined' !== typeof x ? x : null\n\t\t\t\tvar REMOVE_1 = 'undefined' != typeof x ? x : null\n\t\t\t\tvar REMOVE_1 = 'undefined' === typeof x ? null : x\n\t\t\t\tvar REMOVE_1 = 'undefined' == typeof x ? null : x\n\t\t\t\tvar REMOVE_1 = 'undefined' !== typeof x && x\n\t\t\t\tvar REMOVE_1 = 'undefined' != typeof x && x\n\t\t\t\tvar REMOVE_1 = 'undefined' === typeof x || x\n\t\t\t\tvar REMOVE_1 = 'undefined' == typeof x || x\n\n\t\t\t\t// Everything here should be removed as dead code due to tree shaking\n\t\t\t\tvar REMOVE_2 = typeof x === 'object' ? x : null\n\t\t\t\tvar REMOVE_2 = typeof x == 'object' ? x : null\n\t\t\t\tvar REMOVE_2 = typeof x !== 'object' ? null : x\n\t\t\t\tvar REMOVE_2 = typeof x != 'object' ? null : x\n\t\t\t\tvar REMOVE_2 = typeof x === 'object' && x\n\t\t\t\tvar REMOVE_2 = typeof x == 'object' && x\n\t\t\t\tvar REMOVE_2 = typeof x !== 'object' || x\n\t\t\t\tvar REMOVE_2 = typeof x != 'object' || x\n\t\t\t\tvar REMOVE_2 = 'object' === typeof x ? x : null\n\t\t\t\tvar REMOVE_2 = 'object' == typeof x ? x : null\n\t\t\t\tvar REMOVE_2 = 'object' !== typeof x ? null : x\n\t\t\t\tvar REMOVE_2 = 'object' != typeof x ? null : x\n\t\t\t\tvar REMOVE_2 = 'object' === typeof x && x\n\t\t\t\tvar REMOVE_2 = 'object' == typeof x && x\n\t\t\t\tvar REMOVE_2 = 'object' !== typeof x || x\n\t\t\t\tvar REMOVE_2 = 'object' != typeof x || x\n\n\t\t\t\t// Everything here should be kept as live code because it has side effects\n\t\t\t\tvar keep_1 = typeof x !== 'object' ? x : null\n\t\t\t\tvar keep_1 = typeof x != 'object' ? x : null\n\t\t\t\tvar keep_1 = typeof x === 'object' ? null : x\n\t\t\t\tvar keep_1 = typeof x == 'object' ? null : x\n\t\t\t\tvar keep_1 = typeof x !== 'object' && x\n\t\t\t\tvar keep_1 = typeof x != 'object' && x\n\t\t\t\tvar keep_1 = typeof x === 'object' || x\n\t\t\t\tvar keep_1 = typeof x == 'object' || x\n\t\t\t\tvar keep_1 = 'object' !== typeof x ? x : null\n\t\t\t\tvar keep_1 = 'object' != typeof x ? x : null\n\t\t\t\tvar keep_1 = 'object' === typeof x ? null : x\n\t\t\t\tvar keep_1 = 'object' == typeof x ? null : x\n\t\t\t\tvar keep_1 = 'object' !== typeof x && x\n\t\t\t\tvar keep_1 = 'object' != typeof x && x\n\t\t\t\tvar keep_1 = 'object' === typeof x || x\n\t\t\t\tvar keep_1 = 'object' == typeof x || x\n\n\t\t\t\t// Everything here should be kept as live code because it has side effects\n\t\t\t\tvar keep_2 = typeof x !== 'undefined' ? y : null\n\t\t\t\tvar keep_2 = typeof x != 'undefined' ? y : null\n\t\t\t\tvar keep_2 = typeof x === 'undefined' ? null : y\n\t\t\t\tvar keep_2 = typeof x == 'undefined' ? null : y\n\t\t\t\tvar keep_2 = typeof x !== 'undefined' && y\n\t\t\t\tvar keep_2 = typeof x != 'undefined' && y\n\t\t\t\tvar keep_2 = typeof x === 'undefined' || y\n\t\t\t\tvar keep_2 = typeof x == 'undefined' || y\n\t\t\t\tvar keep_2 = 'undefined' !== typeof x ? y : null\n\t\t\t\tvar keep_2 = 'undefined' != typeof x ? y : null\n\t\t\t\tvar keep_2 = 'undefined' === typeof x ? null : y\n\t\t\t\tvar keep_2 = 'undefined' == typeof x ? null : y\n\t\t\t\tvar keep_2 = 'undefined' !== typeof x && y\n\t\t\t\tvar keep_2 = 'undefined' != typeof x && y\n\t\t\t\tvar keep_2 = 'undefined' === typeof x || y\n\t\t\t\tvar keep_2 = 'undefined' == typeof x || y\n\n\t\t\t\t// Everything here should be kept as live code because it has side effects\n\t\t\t\tvar keep_3 = typeof x !== 'undefined' ? null : x\n\t\t\t\tvar keep_3 = typeof x != 'undefined' ? null : x\n\t\t\t\tvar keep_3 = typeof x === 'undefined' ? x : null\n\t\t\t\tvar keep_3 = typeof x == 'undefined' ? x : null\n\t\t\t\tvar keep_3 = typeof x !== 'undefined' || x\n\t\t\t\tvar keep_3 = typeof x != 'undefined' || x\n\t\t\t\tvar keep_3 = typeof x === 'undefined' && x\n\t\t\t\tvar keep_3 = typeof x == 'undefined' && x\n\t\t\t\tvar keep_3 = 'undefined' !== typeof x ? null : x\n\t\t\t\tvar keep_3 = 'undefined' != typeof x ? null : x\n\t\t\t\tvar keep_3 = 'undefined' === typeof x ? x : null\n\t\t\t\tvar keep_3 = 'undefined' == typeof x ? x : null\n\t\t\t\tvar keep_3 = 'undefined' !== typeof x || x\n\t\t\t\tvar keep_3 = 'undefined' != typeof x || x\n\t\t\t\tvar keep_3 = 'undefined' === typeof x && x\n\t\t\t\tvar keep_3 = 'undefined' == typeof x && x\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestDCETypeOfCompareStringGuardCondition(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// Everything here should be removed as dead code due to tree shaking\n\t\t\t\tvar REMOVE_1 = typeof x <= 'u' ? x : null\n\t\t\t\tvar REMOVE_1 = typeof x < 'u' ? x : null\n\t\t\t\tvar REMOVE_1 = typeof x >= 'u' ? null : x\n\t\t\t\tvar REMOVE_1 = typeof x > 'u' ? null : x\n\t\t\t\tvar REMOVE_1 = typeof x <= 'u' && x\n\t\t\t\tvar REMOVE_1 = typeof x < 'u' && x\n\t\t\t\tvar REMOVE_1 = typeof x >= 'u' || x\n\t\t\t\tvar REMOVE_1 = typeof x > 'u' || x\n\t\t\t\tvar REMOVE_1 = 'u' >= typeof x ? x : null\n\t\t\t\tvar REMOVE_1 = 'u' > typeof x ? x : null\n\t\t\t\tvar REMOVE_1 = 'u' <= typeof x ? null : x\n\t\t\t\tvar REMOVE_1 = 'u' < typeof x ? null : x\n\t\t\t\tvar REMOVE_1 = 'u' >= typeof x && x\n\t\t\t\tvar REMOVE_1 = 'u' > typeof x && x\n\t\t\t\tvar REMOVE_1 = 'u' <= typeof x || x\n\t\t\t\tvar REMOVE_1 = 'u' < typeof x || x\n\n\t\t\t\t// Everything here should be kept as live code because it has side effects\n\t\t\t\tvar keep_1 = typeof x <= 'u' ? y : null\n\t\t\t\tvar keep_1 = typeof x < 'u' ? y : null\n\t\t\t\tvar keep_1 = typeof x >= 'u' ? null : y\n\t\t\t\tvar keep_1 = typeof x > 'u' ? null : y\n\t\t\t\tvar keep_1 = typeof x <= 'u' && y\n\t\t\t\tvar keep_1 = typeof x < 'u' && y\n\t\t\t\tvar keep_1 = typeof x >= 'u' || y\n\t\t\t\tvar keep_1 = typeof x > 'u' || y\n\t\t\t\tvar keep_1 = 'u' >= typeof x ? y : null\n\t\t\t\tvar keep_1 = 'u' > typeof x ? y : null\n\t\t\t\tvar keep_1 = 'u' <= typeof x ? null : y\n\t\t\t\tvar keep_1 = 'u' < typeof x ? null : y\n\t\t\t\tvar keep_1 = 'u' >= typeof x && y\n\t\t\t\tvar keep_1 = 'u' > typeof x && y\n\t\t\t\tvar keep_1 = 'u' <= typeof x || y\n\t\t\t\tvar keep_1 = 'u' < typeof x || y\n\n\t\t\t\t// Everything here should be kept as live code because it has side effects\n\t\t\t\tvar keep_2 = typeof x <= 'u' ? null : x\n\t\t\t\tvar keep_2 = typeof x < 'u' ? null : x\n\t\t\t\tvar keep_2 = typeof x >= 'u' ? x : null\n\t\t\t\tvar keep_2 = typeof x > 'u' ? x : null\n\t\t\t\tvar keep_2 = typeof x <= 'u' || x\n\t\t\t\tvar keep_2 = typeof x < 'u' || x\n\t\t\t\tvar keep_2 = typeof x >= 'u' && x\n\t\t\t\tvar keep_2 = typeof x > 'u' && x\n\t\t\t\tvar keep_2 = 'u' >= typeof x ? null : x\n\t\t\t\tvar keep_2 = 'u' > typeof x ? null : x\n\t\t\t\tvar keep_2 = 'u' <= typeof x ? x : null\n\t\t\t\tvar keep_2 = 'u' < typeof x ? x : null\n\t\t\t\tvar keep_2 = 'u' >= typeof x || x\n\t\t\t\tvar keep_2 = 'u' > typeof x || x\n\t\t\t\tvar keep_2 = 'u' <= typeof x && x\n\t\t\t\tvar keep_2 = 'u' < typeof x && x\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// These unused imports should be removed since they aren't used, and removing\n// them makes the code shorter.\nfunc TestRemoveUnusedImports(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport a from 'a'\n\t\t\t\timport * as b from 'b'\n\t\t\t\timport {c} from 'c'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tMinifySyntax:  true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// These unused imports should be kept since the direct eval could potentially\n// reference them, even though they appear to be unused.\nfunc TestRemoveUnusedImportsEval(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport a from 'a'\n\t\t\t\timport * as b from 'b'\n\t\t\t\timport {c} from 'c'\n\t\t\t\teval('foo(a, b, c)')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tMinifySyntax:  true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// These unused imports should be removed even though there is a direct eval\n// because they may be types, not values, so keeping them will likely cause\n// module instantiation failures. It's still true that direct eval could\n// access them of course, but that's very unlikely while module instantiation\n// failure is very likely so we bias towards the likely case here instead.\nfunc TestRemoveUnusedImportsEvalTS(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport a from 'a'\n\t\t\t\timport * as b from 'b'\n\t\t\t\timport {c} from 'c'\n\t\t\t\teval('foo(a, b, c)')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tMinifySyntax:  true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestDCEClassStaticBlocks(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass A_REMOVE {\n\t\t\t\t\tstatic {}\n\t\t\t\t}\n\t\t\t\tclass B_REMOVE {\n\t\t\t\t\tstatic { 123 }\n\t\t\t\t}\n\t\t\t\tclass C_REMOVE {\n\t\t\t\t\tstatic { /* @__PURE__*/ foo() }\n\t\t\t\t}\n\t\t\t\tclass D_REMOVE {\n\t\t\t\t\tstatic { try {} catch {} }\n\t\t\t\t}\n\t\t\t\tclass E_REMOVE {\n\t\t\t\t\tstatic { try { /* @__PURE__*/ foo() } catch {} }\n\t\t\t\t}\n\t\t\t\tclass F_REMOVE {\n\t\t\t\t\tstatic { try { 123 } catch { 123 } finally { 123 } }\n\t\t\t\t}\n\n\t\t\t\tclass A_keep {\n\t\t\t\t\tstatic { foo }\n\t\t\t\t}\n\t\t\t\tclass B_keep {\n\t\t\t\t\tstatic { this.foo }\n\t\t\t\t}\n\t\t\t\tclass C_keep {\n\t\t\t\t\tstatic { try { foo } catch {} }\n\t\t\t\t}\n\t\t\t\tclass D_keep {\n\t\t\t\t\tstatic { try {} finally { foo } }\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestDCEClassStaticBlocksMinifySyntax(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass A_REMOVE {\n\t\t\t\t\tstatic {}\n\t\t\t\t}\n\t\t\t\tclass B_REMOVE {\n\t\t\t\t\tstatic { 123 }\n\t\t\t\t}\n\t\t\t\tclass C_REMOVE {\n\t\t\t\t\tstatic { /* @__PURE__*/ foo() }\n\t\t\t\t}\n\t\t\t\tclass D_REMOVE {\n\t\t\t\t\tstatic { try {} catch {} }\n\t\t\t\t}\n\t\t\t\tclass E_REMOVE {\n\t\t\t\t\tstatic { try { /* @__PURE__*/ foo() } catch {} }\n\t\t\t\t}\n\t\t\t\tclass F_REMOVE {\n\t\t\t\t\tstatic { try { 123 } catch { 123 } finally { 123 } }\n\t\t\t\t}\n\n\t\t\t\tclass A_keep {\n\t\t\t\t\tstatic { foo }\n\t\t\t\t}\n\t\t\t\tclass B_keep {\n\t\t\t\t\tstatic { this.foo }\n\t\t\t\t}\n\t\t\t\tclass C_keep {\n\t\t\t\t\tstatic { try { foo } catch {} }\n\t\t\t\t}\n\t\t\t\tclass D_keep {\n\t\t\t\t\tstatic { try {} finally { foo } }\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMinifySyntax:  true,\n\t\t},\n\t})\n}\n\nfunc TestDCEVarExports(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\tvar foo = { bar: 123 }\n\t\t\t\tmodule.exports = foo\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\tvar exports = { bar: 123 }\n\t\t\t\tmodule.exports = exports\n\t\t\t`,\n\t\t\t\"/c.js\": `\n\t\t\t\tvar module = { bar: 123 }\n\t\t\t\texports.foo = module\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\", \"/c.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestDCETemplateLiteral(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": \"\" +\n\t\t\t\t\"var remove;\\n\" +\n\t\t\t\t\"var alsoKeep;\\n\" +\n\t\t\t\t\"let a = `${keep}`\\n\" +\n\t\t\t\t\"let b = `${123}`\\n\" +\n\t\t\t\t\"let c = `${keep ? 1 : 2n}`\\n\" +\n\t\t\t\t\"let d = `${remove ? 1 : 2n}`\\n\" +\n\t\t\t\t\"let e = `${alsoKeep}`\\n\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\n// Calls to the runtime \"__publicField\" function are not considered side effects\nfunc TestTreeShakingLoweredClassStaticField(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass REMOVE_ME {\n\t\t\t\t\tstatic x = 'x'\n\t\t\t\t\tstatic y = 'y'\n\t\t\t\t\tstatic z = 'z'\n\t\t\t\t}\n\t\t\t\tfunction REMOVE_ME_TOO() {\n\t\t\t\t\tnew REMOVE_ME()\n\t\t\t\t}\n\t\t\t\tclass KeepMe1 {\n\t\t\t\t\tstatic x = 'x'\n\t\t\t\t\tstatic y = sideEffects()\n\t\t\t\t\tstatic z = 'z'\n\t\t\t\t}\n\t\t\t\tclass KeepMe2 {\n\t\t\t\t\tstatic x = 'x'\n\t\t\t\t\tstatic y = 'y'\n\t\t\t\t\tstatic z = 'z'\n\t\t\t\t}\n\t\t\t\tnew KeepMe2()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tUnsupportedJSFeatures: compat.ClassStaticField,\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingLoweredClassStaticFieldMinified(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass REMOVE_ME {\n\t\t\t\t\tstatic x = 'x'\n\t\t\t\t\tstatic y = 'y'\n\t\t\t\t\tstatic z = 'z'\n\t\t\t\t}\n\t\t\t\tfunction REMOVE_ME_TOO() {\n\t\t\t\t\tnew REMOVE_ME()\n\t\t\t\t}\n\t\t\t\tclass KeepMe1 {\n\t\t\t\t\tstatic x = 'x'\n\t\t\t\t\tstatic y = sideEffects()\n\t\t\t\t\tstatic z = 'z'\n\t\t\t\t}\n\t\t\t\tclass KeepMe2 {\n\t\t\t\t\tstatic x = 'x'\n\t\t\t\t\tstatic y = 'y'\n\t\t\t\t\tstatic z = 'z'\n\t\t\t\t}\n\t\t\t\tnew KeepMe2()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tUnsupportedJSFeatures: compat.ClassStaticField,\n\t\t\tMinifySyntax:          true,\n\t\t},\n\t})\n}\n\n// Assignments are considered side effects\nfunc TestTreeShakingLoweredClassStaticFieldAssignment(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass KeepMe1 {\n\t\t\t\t\tstatic x = 'x'\n\t\t\t\t\tstatic y = 'y'\n\t\t\t\t\tstatic z = 'z'\n\t\t\t\t}\n\t\t\t\tclass KeepMe2 {\n\t\t\t\t\tstatic x = 'x'\n\t\t\t\t\tstatic y = sideEffects()\n\t\t\t\t\tstatic z = 'z'\n\t\t\t\t}\n\t\t\t\tclass KeepMe3 {\n\t\t\t\t\tstatic x = 'x'\n\t\t\t\t\tstatic y = 'y'\n\t\t\t\t\tstatic z = 'z'\n\t\t\t\t}\n\t\t\t\tnew KeepMe3()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tUnsupportedJSFeatures: compat.ClassStaticField,\n\t\t\tTS: config.TSOptions{Config: config.TSConfig{\n\t\t\t\tUseDefineForClassFields: config.False,\n\t\t\t}},\n\t\t},\n\t})\n}\n\nfunc TestInlineIdentityFunctionCalls(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/identity.js\": `\n\t\t\t\tfunction DROP(x) { return x }\n\t\t\t\tconsole.log(DROP(1))\n\t\t\t\tDROP(foo())\n\t\t\t\tDROP(1)\n\t\t\t`,\n\n\t\t\t\"/identity-last.js\": `\n\t\t\t\tfunction DROP(x) { return [x] }\n\t\t\t\tfunction DROP(x) { return x }\n\t\t\t\tconsole.log(DROP(1))\n\t\t\t\tDROP(foo())\n\t\t\t\tDROP(1)\n\t\t\t`,\n\n\t\t\t\"/identity-cross-module.js\": `\n\t\t\t\timport { DROP } from './identity-cross-module-def'\n\t\t\t\tconsole.log(DROP(1))\n\t\t\t\tDROP(foo())\n\t\t\t\tDROP(1)\n\t\t\t`,\n\n\t\t\t\"/identity-cross-module-def.js\": `\n\t\t\t\texport function DROP(x) { return x }\n\t\t\t`,\n\n\t\t\t\"/identity-no-args.js\": `\n\t\t\t\tfunction keep(x) { return x }\n\t\t\t\tconsole.log(keep())\n\t\t\t\tkeep()\n\t\t\t`,\n\n\t\t\t\"/identity-two-args.js\": `\n\t\t\t\tfunction keep(x) { return x }\n\t\t\t\tconsole.log(keep(1, 2))\n\t\t\t\tkeep(1, 2)\n\t\t\t`,\n\n\t\t\t\"/identity-first.js\": `\n\t\t\t\tfunction keep(x) { return x }\n\t\t\t\tfunction keep(x) { return [x] }\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/identity-generator.js\": `\n\t\t\t\tfunction* keep(x) { return x }\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/identity-async.js\": `\n\t\t\t\tasync function keep(x) { return x }\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/reassign.js\": `\n\t\t\t\tfunction keep(x) { return x }\n\t\t\t\tkeep = reassigned\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/reassign-inc.js\": `\n\t\t\t\tfunction keep(x) { return x }\n\t\t\t\tkeep++\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/reassign-div.js\": `\n\t\t\t\tfunction keep(x) { return x }\n\t\t\t\tkeep /= reassigned\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/reassign-array.js\": `\n\t\t\t\tfunction keep(x) { return x }\n\t\t\t\t[keep] = reassigned\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/reassign-object.js\": `\n\t\t\t\tfunction keep(x) { return x }\n\t\t\t\t({keep} = reassigned)\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/not-identity-two-args.js\": `\n\t\t\t\tfunction keep(x, y) { return x }\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/not-identity-default.js\": `\n\t\t\t\tfunction keep(x = foo()) { return x }\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/not-identity-array.js\": `\n\t\t\t\tfunction keep([x]) { return x }\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/not-identity-object.js\": `\n\t\t\t\tfunction keep({x}) { return x }\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/not-identity-rest.js\": `\n\t\t\t\tfunction keep(...x) { return x }\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/not-identity-return.js\": `\n\t\t\t\tfunction keep(x) { return [x] }\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/identity-simplify-unused-issue-4287.js\": `\n\t\t\t\tfunction id(x) { return x }\n\t\t\t\tid({ x: id([123, foo()]) })\n\t\t\t\tid({ x: id(123) })\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/identity.js\",\n\t\t\t\"/identity-last.js\",\n\t\t\t\"/identity-first.js\",\n\t\t\t\"/identity-generator.js\",\n\t\t\t\"/identity-async.js\",\n\t\t\t\"/identity-cross-module.js\",\n\t\t\t\"/identity-no-args.js\",\n\t\t\t\"/identity-two-args.js\",\n\t\t\t\"/reassign.js\",\n\t\t\t\"/reassign-inc.js\",\n\t\t\t\"/reassign-div.js\",\n\t\t\t\"/reassign-array.js\",\n\t\t\t\"/reassign-object.js\",\n\t\t\t\"/not-identity-two-args.js\",\n\t\t\t\"/not-identity-default.js\",\n\t\t\t\"/not-identity-array.js\",\n\t\t\t\"/not-identity-object.js\",\n\t\t\t\"/not-identity-rest.js\",\n\t\t\t\"/not-identity-return.js\",\n\t\t\t\"/identity-simplify-unused-issue-4287.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestInlineEmptyFunctionCalls(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/empty.js\": `\n\t\t\t\tfunction DROP() {}\n\t\t\t\tconsole.log(DROP(foo(), bar()))\n\t\t\t\tconsole.log(DROP(foo(), 1))\n\t\t\t\tconsole.log(DROP(1, foo()))\n\t\t\t\tconsole.log(DROP(1))\n\t\t\t\tconsole.log(DROP())\n\t\t\t\tDROP(foo(), bar())\n\t\t\t\tDROP(foo(), 1)\n\t\t\t\tDROP(1, foo())\n\t\t\t\tDROP(1)\n\t\t\t\tDROP()\n\t\t\t`,\n\n\t\t\t\"/empty-comma.js\": `\n\t\t\t\tfunction DROP() {}\n\t\t\t\tconsole.log((DROP(), DROP(), foo()))\n\t\t\t\tconsole.log((DROP(), foo(), DROP()))\n\t\t\t\tconsole.log((foo(), DROP(), DROP()))\n\t\t\t\tfor (DROP(); DROP(); DROP()) DROP();\n\t\t\t\tDROP(), DROP(), foo();\n\t\t\t\tDROP(), foo(), DROP();\n\t\t\t\tfoo(), DROP(), DROP();\n\t\t\t`,\n\n\t\t\t\"/empty-if-else.js\": `\n\t\t\t\tfunction DROP() {}\n\t\t\t\tif (foo) { let bar = baz(); bar(); bar() } else DROP();\n\t\t\t`,\n\n\t\t\t\"/empty-last.js\": `\n\t\t\t\tfunction DROP() { return x }\n\t\t\t\tfunction DROP() { return }\n\t\t\t\tconsole.log(DROP())\n\t\t\t\tDROP()\n\t\t\t`,\n\n\t\t\t\"/empty-cross-module.js\": `\n\t\t\t\timport { DROP } from './empty-cross-module-def'\n\t\t\t\tconsole.log(DROP())\n\t\t\t\tDROP()\n\t\t\t`,\n\n\t\t\t\"/empty-cross-module-def.js\": `\n\t\t\t\texport function DROP() {}\n\t\t\t`,\n\n\t\t\t\"/empty-first.js\": `\n\t\t\t\tfunction keep() { return }\n\t\t\t\tfunction keep() { return x }\n\t\t\t\tconsole.log(keep())\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/empty-generator.js\": `\n\t\t\t\tfunction* keep() {}\n\t\t\t\tconsole.log(keep())\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/empty-async.js\": `\n\t\t\t\tasync function keep() {}\n\t\t\t\tconsole.log(keep())\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/reassign.js\": `\n\t\t\t\tfunction keep() {}\n\t\t\t\tkeep = reassigned\n\t\t\t\tconsole.log(keep())\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/reassign-inc.js\": `\n\t\t\t\tfunction keep() {}\n\t\t\t\tkeep++\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/reassign-div.js\": `\n\t\t\t\tfunction keep() {}\n\t\t\t\tkeep /= reassigned\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/reassign-array.js\": `\n\t\t\t\tfunction keep() {}\n\t\t\t\t[keep] = reassigned\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\n\t\t\t\"/reassign-object.js\": `\n\t\t\t\tfunction keep() {}\n\t\t\t\t({keep} = reassigned)\n\t\t\t\tconsole.log(keep(1))\n\t\t\t\tkeep(foo())\n\t\t\t\tkeep(1)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/empty.js\",\n\t\t\t\"/empty-comma.js\",\n\t\t\t\"/empty-if-else.js\",\n\t\t\t\"/empty-last.js\",\n\t\t\t\"/empty-cross-module.js\",\n\t\t\t\"/empty-first.js\",\n\t\t\t\"/empty-generator.js\",\n\t\t\t\"/empty-async.js\",\n\t\t\t\"/reassign.js\",\n\t\t\t\"/reassign-inc.js\",\n\t\t\t\"/reassign-div.js\",\n\t\t\t\"/reassign-array.js\",\n\t\t\t\"/reassign-object.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestInlineFunctionCallBehaviorChanges(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction empty() {}\n\t\t\t\tfunction id(x) { return x }\n\n\t\t\t\texport let shouldBeWrapped = [\n\t\t\t\t\tid(foo.bar)(),\n\t\t\t\t\tid(foo[bar])(),\n\t\t\t\t\tid(foo?.bar)(),\n\t\t\t\t\tid(foo?.[bar])(),\n\n\t\t\t\t\t(empty(), foo.bar)(),\n\t\t\t\t\t(empty(), foo[bar])(),\n\t\t\t\t\t(empty(), foo?.bar)(),\n\t\t\t\t\t(empty(), foo?.[bar])(),\n\n\t\t\t\t\tid(eval)(),\n\t\t\t\t\tid(eval)?.(),\n\t\t\t\t\t(empty(), eval)(),\n\t\t\t\t\t(empty(), eval)?.(),\n\n\t\t\t\t\tid(foo.bar)` + \"``\" + `,\n\t\t\t\t\tid(foo[bar])` + \"``\" + `,\n\t\t\t\t\tid(foo?.bar)` + \"``\" + `,\n\t\t\t\t\tid(foo?.[bar])` + \"``\" + `,\n\n\t\t\t\t\t(empty(), foo.bar)` + \"``\" + `,\n\t\t\t\t\t(empty(), foo[bar])` + \"``\" + `,\n\t\t\t\t\t(empty(), foo?.bar)` + \"``\" + `,\n\t\t\t\t\t(empty(), foo?.[bar])` + \"``\" + `,\n\n\t\t\t\t\tdelete id(foo),\n\t\t\t\t\tdelete id(foo.bar),\n\t\t\t\t\tdelete id(foo[bar]),\n\t\t\t\t\tdelete id(foo?.bar),\n\t\t\t\t\tdelete id(foo?.[bar]),\n\n\t\t\t\t\tdelete (empty(), foo),\n\t\t\t\t\tdelete (empty(), foo.bar),\n\t\t\t\t\tdelete (empty(), foo[bar]),\n\t\t\t\t\tdelete (empty(), foo?.bar),\n\t\t\t\t\tdelete (empty(), foo?.[bar]),\n\n\t\t\t\t\tdelete empty(),\n\t\t\t\t]\n\n\t\t\t\texport let shouldNotBeWrapped = [\n\t\t\t\t\tid(foo)(),\n\t\t\t\t\t(empty(), foo)(),\n\n\t\t\t\t\tid(foo)` + \"``\" + `,\n\t\t\t\t\t(empty(), foo)` + \"``\" + `,\n\t\t\t\t]\n\n\t\t\t\texport let shouldNotBeDoubleWrapped = [\n\t\t\t\t\tdelete (empty(), foo(), bar()),\n\t\t\t\t\tdelete id((foo(), bar())),\n\t\t\t\t]\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestInlineFunctionCallForInitDecl(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction empty() {}\n\t\t\t\tfunction id(x) { return x }\n\n\t\t\t\tfor (var y = empty(); false; ) ;\n\t\t\t\tfor (var z = id(123); false; ) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestConstValueInliningNoBundle(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/top-level.js\": `\n\t\t\t\t// These should be kept because they are top-level and tree shaking is not enabled\n\t\t\t\tconst n_keep = null\n\t\t\t\tconst u_keep = undefined\n\t\t\t\tconst i_keep = 1234567\n\t\t\t\tconst f_keep = 123.456\n\t\t\t\tconst s_keep = 'abc'\n\n\t\t\t\t// Values should still be inlined\n\t\t\t\tconsole.log(\n\t\t\t\t\t// These are doubled to avoid the \"inline const/let into next statement if used once\" optimization\n\t\t\t\t\tn_keep, n_keep,\n\t\t\t\t\tu_keep, u_keep,\n\t\t\t\t\ti_keep, i_keep,\n\t\t\t\t\tf_keep, f_keep,\n\t\t\t\t\ts_keep, s_keep,\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/nested-block.js\": `\n\t\t\t\t{\n\t\t\t\t\tconst REMOVE_n = null\n\t\t\t\t\tconst REMOVE_u = undefined\n\t\t\t\t\tconst REMOVE_i = 1234567\n\t\t\t\t\tconst REMOVE_f = 123.456\n\t\t\t\t\tconst REMOVE_s = 'abc' // String inlining is intentionally not supported right now\n\t\t\t\t\tconst s_keep = 'Long strings are not inlined as constants'\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t// These are doubled to avoid the \"inline const/let into next statement if used once\" optimization\n\t\t\t\t\t\tREMOVE_n, REMOVE_n,\n\t\t\t\t\t\tREMOVE_u, REMOVE_u,\n\t\t\t\t\t\tREMOVE_i, REMOVE_i,\n\t\t\t\t\t\tREMOVE_f, REMOVE_f,\n\t\t\t\t\t\tREMOVE_s, REMOVE_s,\n\t\t\t\t\t\ts_keep, s_keep,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/nested-function.js\": `\n\t\t\t\tfunction nested() {\n\t\t\t\t\tconst REMOVE_n = null\n\t\t\t\t\tconst REMOVE_u = undefined\n\t\t\t\t\tconst REMOVE_i = 1234567\n\t\t\t\t\tconst REMOVE_f = 123.456\n\t\t\t\t\tconst REMOVE_s = 'abc' // String inlining is intentionally not supported right now\n\t\t\t\t\tconst s_keep = 'Long strings are not inlined as constants'\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t// These are doubled to avoid the \"inline const/let into next statement if used once\" optimization\n\t\t\t\t\t\tREMOVE_n, REMOVE_n,\n\t\t\t\t\t\tREMOVE_u, REMOVE_u,\n\t\t\t\t\t\tREMOVE_i, REMOVE_i,\n\t\t\t\t\t\tREMOVE_f, REMOVE_f,\n\t\t\t\t\t\tREMOVE_s, REMOVE_s,\n\t\t\t\t\t\ts_keep, s_keep,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/namespace-export.ts\": `\n\t\t\t\tnamespace ns {\n\t\t\t\t\tconst x_REMOVE = 1\n\t\t\t\t\texport const y_keep = 2\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\tx_REMOVE, x_REMOVE,\n\t\t\t\t\t\ty_keep, y_keep,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t`,\n\n\t\t\t\"/comment-before.js\": `\n\t\t\t\t{\n\t\t\t\t\t//! comment\n\t\t\t\t\tconst REMOVE = 1\n\t\t\t\t\tx = [REMOVE, REMOVE]\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/directive-before.js\": `\n\t\t\t\tfunction nested() {\n\t\t\t\t\t'directive'\n\t\t\t\t\tconst REMOVE = 1\n\t\t\t\t\tx = [REMOVE, REMOVE]\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/semicolon-before.js\": `\n\t\t\t\t{\n\t\t\t\t\t;\n\t\t\t\t\tconst REMOVE = 1\n\t\t\t\t\tx = [REMOVE, REMOVE]\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/debugger-before.js\": `\n\t\t\t\t{\n\t\t\t\t\tdebugger\n\t\t\t\t\tconst REMOVE = 1\n\t\t\t\t\tx = [REMOVE, REMOVE]\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/type-before.ts\": `\n\t\t\t\t{\n\t\t\t\t\tdeclare let x\n\t\t\t\t\tconst REMOVE = 1\n\t\t\t\t\tx = [REMOVE, REMOVE]\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/exprs-before.js\": `\n\t\t\t\tfunction nested() {\n\t\t\t\t\tconst x = [, '', {}, 0n, /./, function() {}, () => {}]\n\t\t\t\t\tconst y_REMOVE = 1\n\t\t\t\t\tfunction foo() {\n\t\t\t\t\t\treturn y_REMOVE\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\n\t\t\t\"/disabled-tdz.js\": `\n\t\t\t\tfoo()\n\t\t\t\tconst x_keep = 1\n\t\t\t\tfunction foo() {\n\t\t\t\t\treturn x_keep\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/backwards-reference-top-level.js\": `\n\t\t\t\tconst x = y\n\t\t\t\tconst y = 1\n\t\t\t\tconsole.log(\n\t\t\t\t\tx, x,\n\t\t\t\t\ty, y,\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/backwards-reference-nested-function.js\": `\n\t\t\t\tfunction foo() {\n\t\t\t\t\tconst x = y\n\t\t\t\t\tconst y = 1\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\tx, x,\n\t\t\t\t\t\ty, y,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/issue-3125.js\": `\n\t\t\t\tfunction foo() {\n\t\t\t\t\tconst f = () => x\n\t\t\t\t\tconst x = 0\n\t\t\t\t\treturn f()\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/top-level.js\",\n\t\t\t\"/nested-block.js\",\n\t\t\t\"/nested-function.js\",\n\t\t\t\"/namespace-export.ts\",\n\n\t\t\t\"/comment-before.js\",\n\t\t\t\"/directive-before.js\",\n\t\t\t\"/semicolon-before.js\",\n\t\t\t\"/debugger-before.js\",\n\t\t\t\"/type-before.ts\",\n\t\t\t\"/exprs-before.js\",\n\n\t\t\t\"/disabled-tdz.js\",\n\t\t\t\"/backwards-reference-top-level.js\",\n\t\t\t\"/backwards-reference-nested-function.js\",\n\t\t\t\"/issue-3125.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestConstValueInliningBundle(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/exported-entry.js\": `\n\t\t\t\tconst x_REMOVE = 1\n\t\t\t\texport const y_keep = 2\n\t\t\t\tconsole.log(\n\t\t\t\t\tx_REMOVE,\n\t\t\t\t\ty_keep,\n\t\t\t\t)\n\t\t\t`,\n\n\t\t\t\"/re-exported-entry.js\": `\n\t\t\t\timport { x_REMOVE, y_keep } from './re-exported-constants'\n\t\t\t\tconsole.log(x_REMOVE, y_keep)\n\t\t\t\texport { y_keep }\n\t\t\t`,\n\t\t\t\"/re-exported-constants.js\": `\n\t\t\t\texport const x_REMOVE = 1\n\t\t\t\texport const y_keep = 2\n\t\t\t`,\n\n\t\t\t\"/re-exported-2-entry.js\": `\n\t\t\t\texport { y_keep } from './re-exported-2-constants'\n\t\t\t`,\n\t\t\t\"/re-exported-2-constants.js\": `\n\t\t\t\texport const x_REMOVE = 1\n\t\t\t\texport const y_keep = 2\n\t\t\t`,\n\n\t\t\t\"/re-exported-star-entry.js\": `\n\t\t\t\texport * from './re-exported-star-constants'\n\t\t\t`,\n\t\t\t\"/re-exported-star-constants.js\": `\n\t\t\t\texport const x_keep = 1\n\t\t\t\texport const y_keep = 2\n\t\t\t`,\n\n\t\t\t\"/cross-module-entry.js\": `\n\t\t\t\timport { x_REMOVE, y_keep } from './cross-module-constants'\n\t\t\t\tconsole.log(x_REMOVE, y_keep)\n\t\t\t`,\n\t\t\t\"/cross-module-constants.js\": `\n\t\t\t\texport const x_REMOVE = 1\n\t\t\t\tfoo()\n\t\t\t\texport const y_keep = 1\n\t\t\t\texport function foo() {\n\t\t\t\t\treturn [x_REMOVE, y_keep]\n\t\t\t\t}\n\t\t\t`,\n\n\t\t\t\"/print-shorthand-entry.js\": `\n\t\t\t\timport { foo, _bar } from './print-shorthand-constants'\n\t\t\t\t// The inlined constants must still be present in the output! We don't\n\t\t\t\t// want the printer to use the shorthand syntax here to refer to the\n\t\t\t\t// name of the constant itself because the constant declaration is omitted.\n\t\t\t\tconsole.log({ foo, _bar })\n\t\t\t`,\n\t\t\t\"/print-shorthand-constants.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\texport const _bar = -321\n\t\t\t`,\n\n\t\t\t\"/circular-import-entry.js\": `\n\t\t\t\timport './circular-import-constants'\n\t\t\t`,\n\t\t\t\"/circular-import-constants.js\": `\n\t\t\t\texport const foo = 123 // Inlining should be prevented by the cycle\n\t\t\t\texport function bar() {\n\t\t\t\t\treturn foo\n\t\t\t\t}\n\t\t\t\timport './circular-import-cycle'\n\t\t\t`,\n\t\t\t\"/circular-import-cycle.js\": `\n\t\t\t\timport { bar } from './circular-import-constants'\n\t\t\t\tconsole.log(bar()) // This accesses \"foo\" before it's initialized\n\t\t\t`,\n\n\t\t\t\"/circular-re-export-entry.js\": `\n\t\t\t\timport { baz } from './circular-re-export-constants'\n\t\t\t\tconsole.log(baz)\n\t\t\t`,\n\t\t\t\"/circular-re-export-constants.js\": `\n\t\t\t\texport const foo = 123 // Inlining should be prevented by the cycle\n\t\t\t\texport function bar() {\n\t\t\t\t\treturn foo\n\t\t\t\t}\n\t\t\t\texport { baz } from './circular-re-export-cycle'\n\t\t\t`,\n\t\t\t\"/circular-re-export-cycle.js\": `\n\t\t\t\texport const baz = 0\n\t\t\t\timport { bar } from './circular-re-export-constants'\n\t\t\t\tconsole.log(bar()) // This accesses \"foo\" before it's initialized\n\t\t\t`,\n\n\t\t\t\"/circular-re-export-star-entry.js\": `\n\t\t\t\timport './circular-re-export-star-constants'\n\t\t\t`,\n\t\t\t\"/circular-re-export-star-constants.js\": `\n\t\t\t\texport const foo = 123 // Inlining should be prevented by the cycle\n\t\t\t\texport function bar() {\n\t\t\t\t\treturn foo\n\t\t\t\t}\n\t\t\t\texport * from './circular-re-export-star-cycle'\n\t\t\t`,\n\t\t\t\"/circular-re-export-star-cycle.js\": `\n\t\t\t\timport { bar } from './circular-re-export-star-constants'\n\t\t\t\tconsole.log(bar()) // This accesses \"foo\" before it's initialized\n\t\t\t`,\n\n\t\t\t\"/non-circular-export-entry.js\": `\n\t\t\t\timport { foo, bar } from './non-circular-export-constants'\n\t\t\t\tconsole.log(foo, bar())\n\t\t\t`,\n\t\t\t\"/non-circular-export-constants.js\": `\n\t\t\t\tconst foo = 123 // Inlining should be prevented by the cycle\n\t\t\t\tfunction bar() {\n\t\t\t\t\treturn foo\n\t\t\t\t}\n\t\t\t\texport { foo, bar }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/exported-entry.js\",\n\t\t\t\"/re-exported-entry.js\",\n\t\t\t\"/re-exported-2-entry.js\",\n\t\t\t\"/re-exported-star-entry.js\",\n\t\t\t\"/cross-module-entry.js\",\n\t\t\t\"/print-shorthand-entry.js\",\n\t\t\t\"/circular-import-entry.js\",\n\t\t\t\"/circular-re-export-entry.js\",\n\t\t\t\"/circular-re-export-star-entry.js\",\n\t\t\t\"/non-circular-export-entry.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t\tMangleProps:  regexp.MustCompile(\"^_\"),\n\t\t},\n\t})\n}\n\n// Assignment to an inlined constant is not allowed since that would cause a\n// syntax error in the output. We don't just keep the reference there because\n// the declaration may actually have been completely removed already by the\n// time we discover the assignment. I think making these cases an error is\n// fine because it's bad code anyway.\nfunc TestConstValueInliningAssign(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/const-assign.js\": `\n\t\t\t\tconst x = 1\n\t\t\t\tx = 2\n\t\t\t`,\n\t\t\t\"/const-update.js\": `\n\t\t\t\tconst x = 1\n\t\t\t\tx += 2\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/const-assign.js\",\n\t\t\t\"/const-update.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t\texpectedScanLog: `const-assign.js: ERROR: Cannot assign to \"x\" because it is a constant\nconst-assign.js: NOTE: The symbol \"x\" was declared a constant here:\nconst-update.js: ERROR: Cannot assign to \"x\" because it is a constant\nconst-update.js: NOTE: The symbol \"x\" was declared a constant here:\n`,\n\t})\n}\n\nfunc TestConstValueInliningDirectEval(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/top-level-no-eval.js\": `\n\t\t\t\tconst x = 1\n\t\t\t\tconsole.log(x, evil('x'))\n\t\t\t`,\n\t\t\t\"/top-level-eval.js\": `\n\t\t\t\tconst x = 1\n\t\t\t\tconsole.log(x, eval('x'))\n\t\t\t`,\n\t\t\t\"/nested-no-eval.js\": `\n\t\t\t\t(() => {\n\t\t\t\t\tconst x = 1\n\t\t\t\t\tconsole.log(x, evil('x'))\n\t\t\t\t})()\n\t\t\t`,\n\t\t\t\"/nested-eval.js\": `\n\t\t\t\t(() => {\n\t\t\t\t\tconst x = 1\n\t\t\t\t\tconsole.log(x, eval('x'))\n\t\t\t\t})()\n\t\t\t`,\n\t\t\t\"/ts-namespace-no-eval.ts\": `\n\t\t\t\tnamespace y {\n\t\t\t\t\texport const x = 1\n\t\t\t\t\tconsole.log(x, evil('x'))\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/ts-namespace-eval.ts\": `\n\t\t\t\tnamespace z {\n\t\t\t\t\texport const x = 1\n\t\t\t\t\tconsole.log(x, eval('x'))\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/issue-4055.ts\": `\n\t\t\t\tconst variable = false\n\t\t\t\t;(function () {\n\t\t\t\t\teval(\"var variable = true\")\n\t\t\t\t\tconsole.log(variable)\n\t\t\t\t})()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/top-level-no-eval.js\",\n\t\t\t\"/top-level-eval.js\",\n\t\t\t\"/nested-no-eval.js\",\n\t\t\t\"/nested-eval.js\",\n\t\t\t\"/ts-namespace-no-eval.ts\",\n\t\t\t\"/ts-namespace-eval.ts\",\n\t\t\t\"/issue-4055.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestCrossModuleConstantFoldingNumber(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/enum-constants.ts\": `\n\t\t\t\texport enum x {\n\t\t\t\t\ta = 3,\n\t\t\t\t\tb = 6,\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/enum-entry.ts\": `\n\t\t\t\timport { x } from './enum-constants'\n\t\t\t\tconsole.log([\n\t\t\t\t\t+x.b,\n\t\t\t\t\t-x.b,\n\t\t\t\t\t~x.b,\n\t\t\t\t\t!x.b,\n\t\t\t\t\ttypeof x.b,\n\t\t\t\t], [\n\t\t\t\t\tx.a + x.b,\n\t\t\t\t\tx.a - x.b,\n\t\t\t\t\tx.a * x.b,\n\t\t\t\t\tx.a / x.b,\n\t\t\t\t\tx.a % x.b,\n\t\t\t\t\tx.a ** x.b,\n\t\t\t\t], [\n\t\t\t\t\tx.a < x.b,\n\t\t\t\t\tx.a > x.b,\n\t\t\t\t\tx.a <= x.b,\n\t\t\t\t\tx.a >= x.b,\n\t\t\t\t\tx.a == x.b,\n\t\t\t\t\tx.a != x.b,\n\t\t\t\t\tx.a === x.b,\n\t\t\t\t\tx.a !== x.b,\n\t\t\t\t], [\n\t\t\t\t\tx.b << 1,\n\t\t\t\t\tx.b >> 1,\n\t\t\t\t\tx.b >>> 1,\n\t\t\t\t], [\n\t\t\t\t\tx.a & x.b,\n\t\t\t\t\tx.a | x.b,\n\t\t\t\t\tx.a ^ x.b,\n\t\t\t\t], [\n\t\t\t\t\tx.a && x.b,\n\t\t\t\t\tx.a || x.b,\n\t\t\t\t\tx.a ?? x.b,\n\t\t\t\t\tx.a ? 'y' : 'n',\n\t\t\t\t\t!x.b ? 'y' : 'n',\n\t\t\t\t])\n\t\t\t`,\n\n\t\t\t\"/const-constants.js\": `\n\t\t\t\texport const a = 3\n\t\t\t\texport const b = 6\n\t\t\t`,\n\t\t\t\"/const-entry.js\": `\n\t\t\t\timport { a, b } from './const-constants'\n\t\t\t\tconsole.log([\n\t\t\t\t\t+b,\n\t\t\t\t\t-b,\n\t\t\t\t\t~b,\n\t\t\t\t\t!b,\n\t\t\t\t\ttypeof b,\n\t\t\t\t], [\n\t\t\t\t\ta + b,\n\t\t\t\t\ta - b,\n\t\t\t\t\ta * b,\n\t\t\t\t\ta / b,\n\t\t\t\t\ta % b,\n\t\t\t\t\ta ** b,\n\t\t\t\t], [\n\t\t\t\t\ta < b,\n\t\t\t\t\ta > b,\n\t\t\t\t\ta <= b,\n\t\t\t\t\ta >= b,\n\t\t\t\t\ta == b,\n\t\t\t\t\ta != b,\n\t\t\t\t\ta === b,\n\t\t\t\t\ta !== b,\n\t\t\t\t], [\n\t\t\t\t\tb << 1,\n\t\t\t\t\tb >> 1,\n\t\t\t\t\tb >>> 1,\n\t\t\t\t], [\n\t\t\t\t\ta & b,\n\t\t\t\t\ta | b,\n\t\t\t\t\ta ^ b,\n\t\t\t\t], [\n\t\t\t\t\ta && b,\n\t\t\t\t\ta || b,\n\t\t\t\t\ta ?? b,\n\t\t\t\t\ta ? 'y' : 'n',\n\t\t\t\t\t!b ? 'y' : 'n',\n\t\t\t\t])\n\t\t\t`,\n\n\t\t\t\"/nested-constants.ts\": `\n\t\t\t\texport const a = 2\n\t\t\t\texport const b = 4\n\t\t\t\texport const c = 8\n\t\t\t\texport enum x {\n\t\t\t\t\ta = 16,\n\t\t\t\t\tb = 32,\n\t\t\t\t\tc = 64,\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/nested-entry.ts\": `\n\t\t\t\timport { a, b, c, x } from './nested-constants'\n\t\t\t\tconsole.log({\n\t\t\t\t\t'should be 4': ~(~a & ~b) & (b | c),\n\t\t\t\t\t'should be 32': ~(~x.a & ~x.b) & (x.b | x.c),\n\t\t\t\t})\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/enum-entry.ts\",\n\t\t\t\"/const-entry.js\",\n\t\t\t\"/nested-entry.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestCrossModuleConstantFoldingString(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/enum-constants.ts\": `\n\t\t\t\texport enum x {\n\t\t\t\t\ta = 'foo',\n\t\t\t\t\tb = 'bar',\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/enum-entry.ts\": `\n\t\t\t\timport { x } from './enum-constants'\n\t\t\t\tconsole.log([\n\t\t\t\t\ttypeof x.b,\n\t\t\t\t], [\n\t\t\t\t\tx.a + x.b,\n\t\t\t\t], [\n\t\t\t\t\tx.a < x.b,\n\t\t\t\t\tx.a > x.b,\n\t\t\t\t\tx.a <= x.b,\n\t\t\t\t\tx.a >= x.b,\n\t\t\t\t\tx.a == x.b,\n\t\t\t\t\tx.a != x.b,\n\t\t\t\t\tx.a === x.b,\n\t\t\t\t\tx.a !== x.b,\n\t\t\t\t], [\n\t\t\t\t\tx.a && x.b,\n\t\t\t\t\tx.a || x.b,\n\t\t\t\t\tx.a ?? x.b,\n\t\t\t\t\tx.a ? 'y' : 'n',\n\t\t\t\t\t!x.b ? 'y' : 'n',\n\t\t\t\t])\n\t\t\t`,\n\n\t\t\t\"/const-constants.js\": `\n\t\t\t\texport const a = 'foo'\n\t\t\t\texport const b = 'bar'\n\t\t\t`,\n\t\t\t\"/const-entry.js\": `\n\t\t\t\timport { a, b } from './const-constants'\n\t\t\t\tconsole.log([\n\t\t\t\t\ttypeof b,\n\t\t\t\t], [\n\t\t\t\t\ta + b,\n\t\t\t\t], [\n\t\t\t\t\ta < b,\n\t\t\t\t\ta > b,\n\t\t\t\t\ta <= b,\n\t\t\t\t\ta >= b,\n\t\t\t\t\ta == b,\n\t\t\t\t\ta != b,\n\t\t\t\t\ta === b,\n\t\t\t\t\ta !== b,\n\t\t\t\t], [\n\t\t\t\t\ta && b,\n\t\t\t\t\ta || b,\n\t\t\t\t\ta ?? b,\n\t\t\t\t\ta ? 'y' : 'n',\n\t\t\t\t\t!b ? 'y' : 'n',\n\t\t\t\t])\n\t\t\t`,\n\n\t\t\t\"/nested-constants.ts\": `\n\t\t\t\texport const a = 'foo'\n\t\t\t\texport const b = 'bar'\n\t\t\t\texport const c = 'baz'\n\t\t\t\texport enum x {\n\t\t\t\t\ta = 'FOO',\n\t\t\t\t\tb = 'BAR',\n\t\t\t\t\tc = 'BAZ',\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/nested-entry.ts\": `\n\t\t\t\timport { a, b, c, x } from './nested-constants'\n\t\t\t\tconsole.log({\n\t\t\t\t\t'should be foobarbaz': a + b + c,\n\t\t\t\t\t'should be FOOBARBAZ': x.a + x.b + x.c,\n\t\t\t\t})\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/enum-entry.ts\",\n\t\t\t\"/const-entry.js\",\n\t\t\t\"/nested-entry.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestCrossModuleConstantFoldingComputedPropertyName(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/enum-constants.ts\": `\n\t\t\t\texport enum x {\n\t\t\t\t\ta = 123,\n\t\t\t\t\tb = 'abc',\n\t\t\t\t\tproto = '__proto__',\n\t\t\t\t\tptype = 'prototype',\n\t\t\t\t\tctor = 'constructor',\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/enum-entry.ts\": `\n\t\t\t\timport { x } from './enum-constants'\n\t\t\t\tconsole.log({\n\t\t\t\t\t[x.a]: x.a,\n\t\t\t\t\t[x.b]: x.b,\n\t\t\t\t})\n\t\t\t\tclass Foo {\n\t\t\t\t\t[x.proto] = {};\n\t\t\t\t\t[x.ptype] = {};\n\t\t\t\t\t[x.ctor]() {};\n\t\t\t\t}\n\t\t\t`,\n\n\t\t\t\"/const-constants.js\": `\n\t\t\t\texport const a = 456\n\t\t\t\texport const b = 'xyz'\n\t\t\t\texport const proto = '__proto__'\n\t\t\t\texport const ptype = 'prototype'\n\t\t\t\texport const ctor = 'constructor'\n\t\t\t`,\n\t\t\t\"/const-entry.js\": `\n\t\t\t\timport { a, b, proto, ptype, ctor } from './const-constants'\n\t\t\t\tconsole.log({\n\t\t\t\t\t[a]: a,\n\t\t\t\t\t[b]: b,\n\t\t\t\t})\n\t\t\t\tclass Foo {\n\t\t\t\t\t[proto] = {};\n\t\t\t\t\t[ptype] = {};\n\t\t\t\t\t[ctor]() {};\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/enum-entry.ts\",\n\t\t\t\"/const-entry.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestMultipleDeclarationTreeShaking(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/var2.js\": `\n\t\t\t\tvar x = 1\n\t\t\t\tconsole.log(x)\n\t\t\t\tvar x = 2\n\t\t\t`,\n\t\t\t\"/var3.js\": `\n\t\t\t\tvar x = 1\n\t\t\t\tconsole.log(x)\n\t\t\t\tvar x = 2\n\t\t\t\tconsole.log(x)\n\t\t\t\tvar x = 3\n\t\t\t`,\n\t\t\t\"/function2.js\": `\n\t\t\t\tfunction x() { return 1 }\n\t\t\t\tconsole.log(x())\n\t\t\t\tfunction x() { return 2 }\n\t\t\t`,\n\t\t\t\"/function3.js\": `\n\t\t\t\tfunction x() { return 1 }\n\t\t\t\tconsole.log(x())\n\t\t\t\tfunction x() { return 2 }\n\t\t\t\tconsole.log(x())\n\t\t\t\tfunction x() { return 3 }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/var2.js\",\n\t\t\t\"/var3.js\",\n\t\t\t\"/function2.js\",\n\t\t\t\"/function3.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: false,\n\t\t},\n\t})\n}\n\nfunc TestMultipleDeclarationTreeShakingMinifySyntax(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/var2.js\": `\n\t\t\t\tvar x = 1\n\t\t\t\tconsole.log(x)\n\t\t\t\tvar x = 2\n\t\t\t`,\n\t\t\t\"/var3.js\": `\n\t\t\t\tvar x = 1\n\t\t\t\tconsole.log(x)\n\t\t\t\tvar x = 2\n\t\t\t\tconsole.log(x)\n\t\t\t\tvar x = 3\n\t\t\t`,\n\t\t\t\"/function2.js\": `\n\t\t\t\tfunction x() { return 1 }\n\t\t\t\tconsole.log(x())\n\t\t\t\tfunction x() { return 2 }\n\t\t\t`,\n\t\t\t\"/function3.js\": `\n\t\t\t\tfunction x() { return 1 }\n\t\t\t\tconsole.log(x())\n\t\t\t\tfunction x() { return 2 }\n\t\t\t\tconsole.log(x())\n\t\t\t\tfunction x() { return 3 }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/var2.js\",\n\t\t\t\"/var3.js\",\n\t\t\t\"/function2.js\",\n\t\t\t\"/function3.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\n// Pure call removal should still run iterators, which can have side effects\nfunc TestPureCallsWithSpread(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t/* @__PURE__ */ foo(...args);\n\t\t\t\t/* @__PURE__ */ new foo(...args);\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMinifySyntax:  true,\n\t\t},\n\t})\n}\n\nfunc TestTopLevelFunctionInliningWithSpread(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction empty1() {}\n\t\t\t\tfunction empty2() {}\n\t\t\t\tfunction empty3() {}\n\n\t\t\t\tfunction identity1(x) { return x }\n\t\t\t\tfunction identity2(x) { return x }\n\t\t\t\tfunction identity3(x) { return x }\n\n\t\t\t\tempty1()\n\t\t\t\tempty2(args)\n\t\t\t\tempty3(...args)\n\n\t\t\t\tidentity1()\n\t\t\t\tidentity2(args)\n\t\t\t\tidentity3(...args)\n\t\t\t`,\n\n\t\t\t\"/inner.js\": `\n\t\t\t\texport function empty1() {}\n\t\t\t\texport function empty2() {}\n\t\t\t\texport function empty3() {}\n\n\t\t\t\texport function identity1(x) { return x }\n\t\t\t\texport function identity2(x) { return x }\n\t\t\t\texport function identity3(x) { return x }\n\t\t\t`,\n\n\t\t\t\"/entry-outer.js\": `\n\t\t\t\timport {\n\t\t\t\t\tempty1,\n\t\t\t\t\tempty2,\n\t\t\t\t\tempty3,\n\n\t\t\t\t\tidentity1,\n\t\t\t\t\tidentity2,\n\t\t\t\t\tidentity3,\n\t\t\t\t} from './inner.js'\n\n\t\t\t\tempty1()\n\t\t\t\tempty2(args)\n\t\t\t\tempty3(...args)\n\n\t\t\t\tidentity1()\n\t\t\t\tidentity2(args)\n\t\t\t\tidentity3(...args)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\", \"/entry-outer.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestNestedFunctionInliningWithSpread(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction empty1() {}\n\t\t\t\tfunction empty2() {}\n\t\t\t\tfunction empty3() {}\n\n\t\t\t\tfunction identity1(x) { return x }\n\t\t\t\tfunction identity2(x) { return x }\n\t\t\t\tfunction identity3(x) { return x }\n\n\t\t\t\tcheck(\n\t\t\t\t\tempty1(),\n\t\t\t\t\tempty2(args),\n\t\t\t\t\tempty3(...args),\n\n\t\t\t\t\tidentity1(),\n\t\t\t\t\tidentity2(args),\n\t\t\t\t\tidentity3(...args),\n\t\t\t\t)\n\t\t\t`,\n\n\t\t\t\"/inner.js\": `\n\t\t\t\texport function empty1() {}\n\t\t\t\texport function empty2() {}\n\t\t\t\texport function empty3() {}\n\n\t\t\t\texport function identity1(x) { return x }\n\t\t\t\texport function identity2(x) { return x }\n\t\t\t\texport function identity3(x) { return x }\n\t\t\t`,\n\n\t\t\t\"/entry-outer.js\": `\n\t\t\t\timport {\n\t\t\t\t\tempty1,\n\t\t\t\t\tempty2,\n\t\t\t\t\tempty3,\n\n\t\t\t\t\tidentity1,\n\t\t\t\t\tidentity2,\n\t\t\t\t\tidentity3,\n\t\t\t\t} from './inner.js'\n\n\t\t\t\tcheck(\n\t\t\t\t\tempty1(),\n\t\t\t\t\tempty2(args),\n\t\t\t\t\tempty3(...args),\n\n\t\t\t\t\tidentity1(),\n\t\t\t\t\tidentity2(args),\n\t\t\t\t\tidentity3(...args),\n\t\t\t\t)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\", \"/entry-outer.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSideEffectsFalseCrossPlatformSlash(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport \"demo-pkg/foo\"\n\t\t\t\timport \"demo-pkg/bar\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/foo.js\": `\n\t\t\t\tconsole.log('foo')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/bar/index.js\": `\n\t\t\t\tconsole.log('bar')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"sideEffects\": [\n\t\t\t\t\t\t\"**/foo.js\",\n\t\t\t\t\t\t\"bar/index.js\"\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingJSWithAssociatedCSS(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/test.jsx\": `\n\t\t\t\timport { Button } from 'pkg/button'\n\t\t\t\timport { Menu } from 'pkg/menu'\n\t\t\t\trender(<Button/>)\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/button.js\": `\n\t\t\t\timport './button.css'\n\t\t\t\texport let Button\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/button.css\": `\n\t\t\t\tbutton { color: red }\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/menu.js\": `\n\t\t\t\timport './menu.css'\n\t\t\t\texport let Menu\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/menu.css\": `\n\t\t\t\tmenu { color: red }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/project/test.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingJSWithAssociatedCSSReExportSideEffectsFalse(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/test.jsx\": `\n\t\t\t\timport { Button } from 'pkg'\n\t\t\t\trender(<Button/>)\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/entry.js\": `\n\t\t\t\texport { Button } from './components'\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/package.json\": `{\n\t\t\t\t\"main\": \"./entry.js\",\n\t\t\t\t\"sideEffects\": false\n\t\t\t}`,\n\t\t\t\"/project/node_modules/pkg/components.jsx\": `\n\t\t\t\trequire('./button.css')\n\t\t\t\texport const Button = () => <button/>\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/button.css\": `\n\t\t\t\tbutton { color: red }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/project/test.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingJSWithAssociatedCSSReExportSideEffectsFalseOnlyJS(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/test.jsx\": `\n\t\t\t\timport { Button } from 'pkg'\n\t\t\t\trender(<Button/>)\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/entry.js\": `\n\t\t\t\texport { Button } from './components'\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/package.json\": `{\n\t\t\t\t\"main\": \"./entry.js\",\n\t\t\t\t\"sideEffects\": [\"*.css\"]\n\t\t\t}`,\n\t\t\t\"/project/node_modules/pkg/components.jsx\": `\n\t\t\t\trequire('./button.css')\n\t\t\t\texport const Button = () => <button/>\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/button.css\": `\n\t\t\t\tbutton { color: red }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/project/test.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingJSWithAssociatedCSSExportStarSideEffectsFalse(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/test.jsx\": `\n\t\t\t\timport { Button } from 'pkg'\n\t\t\t\trender(<Button/>)\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/entry.js\": `\n\t\t\t\texport * from './components'\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/package.json\": `{\n\t\t\t\t\"main\": \"./entry.js\",\n\t\t\t\t\"sideEffects\": false\n\t\t\t}`,\n\t\t\t\"/project/node_modules/pkg/components.jsx\": `\n\t\t\t\trequire('./button.css')\n\t\t\t\texport const Button = () => <button/>\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/button.css\": `\n\t\t\t\tbutton { color: red }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/project/test.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingJSWithAssociatedCSSExportStarSideEffectsFalseOnlyJS(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/test.jsx\": `\n\t\t\t\timport { Button } from 'pkg'\n\t\t\t\trender(<Button/>)\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/entry.js\": `\n\t\t\t\texport * from './components'\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/package.json\": `{\n\t\t\t\t\"main\": \"./entry.js\",\n\t\t\t\t\"sideEffects\": [\"*.css\"]\n\t\t\t}`,\n\t\t\t\"/project/node_modules/pkg/components.jsx\": `\n\t\t\t\trequire('./button.css')\n\t\t\t\texport const Button = () => <button/>\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/button.css\": `\n\t\t\t\tbutton { color: red }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/project/test.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingJSWithAssociatedCSSUnusedNestedImportSideEffectsFalse(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/test.jsx\": `\n\t\t\t\timport { Button } from 'pkg/button'\n\t\t\t\trender(<Button/>)\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/package.json\": `{\n\t\t\t\t\"sideEffects\": false\n\t\t\t}`,\n\t\t\t\"/project/node_modules/pkg/button.jsx\": `\n\t\t\t\timport styles from './styles'\n\t\t\t\texport const Button = () => <button/>\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/styles.js\": `\n\t\t\t\timport './styles.css'\n\t\t\t\texport default {}\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/styles.css\": `\n\t\t\t\tbutton { color: red }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/project/test.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTreeShakingJSWithAssociatedCSSUnusedNestedImportSideEffectsFalseOnlyJS(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/test.jsx\": `\n\t\t\t\timport { Button } from 'pkg/button'\n\t\t\t\trender(<Button/>)\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/package.json\": `{\n\t\t\t\t\"sideEffects\": [\"*.css\"]\n\t\t\t}`,\n\t\t\t\"/project/node_modules/pkg/button.jsx\": `\n\t\t\t\timport styles from './styles'\n\t\t\t\texport const Button = () => <button/>\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/styles.js\": `\n\t\t\t\timport './styles.css'\n\t\t\t\texport default {}\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/styles.css\": `\n\t\t\t\tbutton { color: red }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/project/test.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestPreserveDirectivesMinifyPassThrough(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t//! 1\n\t\t\t\t'use 1'\n\t\t\t\t//! 2\n\t\t\t\t'use 2'\n\t\t\t\t//! 3\n\t\t\t\t'use 3'\n\t\t\t\tentry()\n\t\t\t\t//! 4\n\t\t\t\t'use 4'\n\t\t\t\t//! 5\n\t\t\t\t'use 5'\n\t\t\t\t//! 6\n\t\t\t\t'use 6'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMinifySyntax:  true,\n\t\t},\n\t})\n}\n\nfunc TestPreserveDirectivesMinifyIIFE(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t//! 1\n\t\t\t\t'use 1'\n\t\t\t\t//! 2\n\t\t\t\t'use 2'\n\t\t\t\t//! 3\n\t\t\t\t'use 3'\n\t\t\t\tentry()\n\t\t\t\t//! 4\n\t\t\t\t'use 4'\n\t\t\t\t//! 5\n\t\t\t\t'use 5'\n\t\t\t\t//! 6\n\t\t\t\t'use 6'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMinifySyntax:  true,\n\t\t},\n\t})\n}\n\nfunc TestPreserveDirectivesMinifyBundle(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t//! 1\n\t\t\t\t'use 1'\n\t\t\t\t//! 2\n\t\t\t\t'use 2'\n\t\t\t\t//! 3\n\t\t\t\t'use 3'\n\t\t\t\tentry()\n\t\t\t\t//! 4\n\t\t\t\t'use 4'\n\t\t\t\t//! 5\n\t\t\t\t'use 5'\n\t\t\t\t//! 6\n\t\t\t\t'use 6'\n\t\t\t\timport \"./nested.js\"\n\t\t\t`,\n\t\t\t\"/nested.js\": `\n\t\t\t\t//! A\n\t\t\t\t'use A'\n\t\t\t\t//! B\n\t\t\t\t'use B'\n\t\t\t\t//! C\n\t\t\t\t'use C'\n\t\t\t\tnested()\n\t\t\t\t//! D\n\t\t\t\t'use D'\n\t\t\t\t//! E\n\t\t\t\t'use E'\n\t\t\t\t//! F\n\t\t\t\t'use F'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMinifySyntax:  true,\n\t\t},\n\t})\n}\n\n// See: https://github.com/rollup/rollup/pull/5024\nfunc TestNoSideEffectsComment(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/expr-fn.js\": `\n\t\t\t\t//! These should all have \"no side effects\"\n\t\t\t\tx([\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ function() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ function y() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ function*() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ function* y() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async function() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async function y() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async function*() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async function* y() {},\n\t\t\t\t])\n\t\t\t`,\n\t\t\t\"/expr-arrow.js\": `\n\t\t\t\t//! These should all have \"no side effects\"\n\t\t\t\tx([\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ y => y,\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ () => {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ (y) => (y),\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async y => y,\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async () => {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async (y) => (y),\n\t\t\t\t])\n\t\t\t`,\n\n\t\t\t\"/stmt-fn.js\": `\n\t\t\t\t//! These should all have \"no side effects\"\n\t\t\t\t// #__NO_SIDE_EFFECTS__\n\t\t\t\tfunction a() {}\n\t\t\t\t// #__NO_SIDE_EFFECTS__\n\t\t\t\tfunction* b() {}\n\t\t\t\t// #__NO_SIDE_EFFECTS__\n\t\t\t\tasync function c() {}\n\t\t\t\t// #__NO_SIDE_EFFECTS__\n\t\t\t\tasync function* d() {}\n\t\t\t`,\n\t\t\t\"/stmt-export-fn.js\": `\n\t\t\t\t//! These should all have \"no side effects\"\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export function a() {}\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export function* b() {}\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export async function c() {}\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export async function* d() {}\n\t\t\t`,\n\t\t\t\"/stmt-local.js\": `\n\t\t\t\t//! Only \"c0\" and \"c2\" should have \"no side effects\" (Rollup only respects \"const\" and only for the first one)\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ var v0 = function() {}, v1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ let l0 = function() {}, l1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ const c0 = function() {}, c1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ var v2 = () => {}, v3 = () => {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ let l2 = () => {}, l3 = () => {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ const c2 = () => {}, c3 = () => {}\n\t\t\t`,\n\t\t\t\"/stmt-export-local.js\": `\n\t\t\t\t//! Only \"c0\" and \"c2\" should have \"no side effects\" (Rollup only respects \"const\" and only for the first one)\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export var v0 = function() {}, v1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export let l0 = function() {}, l1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export const c0 = function() {}, c1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export var v2 = () => {}, v3 = () => {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export let l2 = () => {}, l3 = () => {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export const c2 = () => {}, c3 = () => {}\n\t\t\t`,\n\n\t\t\t\"/ns-export-fn.ts\": `\n\t\t\t\tnamespace ns {\n\t\t\t\t\t//! These should all have \"no side effects\"\n\t\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export function a() {}\n\t\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export function* b() {}\n\t\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export async function c() {}\n\t\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export async function* d() {}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/ns-export-local.ts\": `\n\t\t\t\tnamespace ns {\n\t\t\t\t\t//! Only \"c0\" and \"c2\" should have \"no side effects\" (Rollup only respects \"const\" and only for the first one)\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export var v0 = function() {}, v1 = function() {}\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export let l0 = function() {}, l1 = function() {}\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export const c0 = function() {}, c1 = function() {}\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export var v2 = () => {}, v3 = () => {}\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export let l2 = () => {}, l3 = () => {}\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export const c2 = () => {}, c3 = () => {}\n\t\t\t\t}\n\t\t\t`,\n\n\t\t\t\"/stmt-export-default-before-fn-anon.js\":           `/*! This should have \"no side effects\" */ /* #__NO_SIDE_EFFECTS__ */ export default function() {}`,\n\t\t\t\"/stmt-export-default-before-fn-name.js\":           `/*! This should have \"no side effects\" */ /* #__NO_SIDE_EFFECTS__ */ export default function f() {}`,\n\t\t\t\"/stmt-export-default-before-gen-fn-anon.js\":       `/*! This should have \"no side effects\" */ /* #__NO_SIDE_EFFECTS__ */ export default function*() {}`,\n\t\t\t\"/stmt-export-default-before-gen-fn-name.js\":       `/*! This should have \"no side effects\" */ /* #__NO_SIDE_EFFECTS__ */ export default function* f() {}`,\n\t\t\t\"/stmt-export-default-before-async-fn-anon.js\":     `/*! This should have \"no side effects\" */ /* #__NO_SIDE_EFFECTS__ */ export default async function() {}`,\n\t\t\t\"/stmt-export-default-before-async-fn-name.js\":     `/*! This should have \"no side effects\" */ /* #__NO_SIDE_EFFECTS__ */ export default async function f() {}`,\n\t\t\t\"/stmt-export-default-before-async-gen-fn-anon.js\": `/*! This should have \"no side effects\" */ /* #__NO_SIDE_EFFECTS__ */ export default async function*() {}`,\n\t\t\t\"/stmt-export-default-before-async-gen-fn-name.js\": `/*! This should have \"no side effects\" */ /* #__NO_SIDE_EFFECTS__ */ export default async function* f() {}`,\n\n\t\t\t\"/stmt-export-default-after-fn-anon.js\":           `/*! This should have \"no side effects\" */ export default /* @__NO_SIDE_EFFECTS__ */ function() {}`,\n\t\t\t\"/stmt-export-default-after-fn-name.js\":           `/*! This should have \"no side effects\" */ export default /* @__NO_SIDE_EFFECTS__ */ function f() {}`,\n\t\t\t\"/stmt-export-default-after-gen-fn-anon.js\":       `/*! This should have \"no side effects\" */ export default /* @__NO_SIDE_EFFECTS__ */ function*() {}`,\n\t\t\t\"/stmt-export-default-after-gen-fn-name.js\":       `/*! This should have \"no side effects\" */ export default /* @__NO_SIDE_EFFECTS__ */ function* f() {}`,\n\t\t\t\"/stmt-export-default-after-async-fn-anon.js\":     `/*! This should have \"no side effects\" */ export default /* @__NO_SIDE_EFFECTS__ */ async function() {}`,\n\t\t\t\"/stmt-export-default-after-async-fn-name.js\":     `/*! This should have \"no side effects\" */ export default /* @__NO_SIDE_EFFECTS__ */ async function f() {}`,\n\t\t\t\"/stmt-export-default-after-async-gen-fn-anon.js\": `/*! This should have \"no side effects\" */ export default /* @__NO_SIDE_EFFECTS__ */ async function*() {}`,\n\t\t\t\"/stmt-export-default-after-async-gen-fn-name.js\": `/*! This should have \"no side effects\" */ export default /* @__NO_SIDE_EFFECTS__ */ async function* f() {}`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/expr-fn.js\",\n\t\t\t\"/expr-arrow.js\",\n\n\t\t\t\"/stmt-fn.js\",\n\t\t\t\"/stmt-export-fn.js\",\n\t\t\t\"/stmt-local.js\",\n\t\t\t\"/stmt-export-local.js\",\n\n\t\t\t\"/ns-export-fn.ts\",\n\t\t\t\"/ns-export-local.ts\",\n\n\t\t\t\"/stmt-export-default-before-fn-anon.js\",\n\t\t\t\"/stmt-export-default-before-fn-name.js\",\n\t\t\t\"/stmt-export-default-before-gen-fn-anon.js\",\n\t\t\t\"/stmt-export-default-before-gen-fn-name.js\",\n\t\t\t\"/stmt-export-default-before-async-fn-anon.js\",\n\t\t\t\"/stmt-export-default-before-async-fn-name.js\",\n\t\t\t\"/stmt-export-default-before-async-gen-fn-anon.js\",\n\t\t\t\"/stmt-export-default-before-async-gen-fn-name.js\",\n\n\t\t\t\"/stmt-export-default-after-fn-anon.js\",\n\t\t\t\"/stmt-export-default-after-fn-name.js\",\n\t\t\t\"/stmt-export-default-after-gen-fn-anon.js\",\n\t\t\t\"/stmt-export-default-after-gen-fn-name.js\",\n\t\t\t\"/stmt-export-default-after-async-fn-anon.js\",\n\t\t\t\"/stmt-export-default-after-async-fn-name.js\",\n\t\t\t\"/stmt-export-default-after-async-gen-fn-anon.js\",\n\t\t\t\"/stmt-export-default-after-async-gen-fn-name.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestNoSideEffectsCommentIgnoreAnnotations(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/expr-fn.js\": `\n\t\t\t\tx([\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ function() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ function y() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ function*() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ function* y() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async function() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async function y() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async function*() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async function* y() {},\n\t\t\t\t])\n\t\t\t`,\n\t\t\t\"/expr-arrow.js\": `\n\t\t\t\tx([\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ y => y,\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ () => {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ (y) => (y),\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async y => y,\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async () => {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async (y) => (y),\n\t\t\t\t])\n\t\t\t`,\n\n\t\t\t\"/stmt-fn.js\": `\n\t\t\t\t// #__NO_SIDE_EFFECTS__\n\t\t\t\tfunction a() {}\n\t\t\t\t// #__NO_SIDE_EFFECTS__\n\t\t\t\tfunction* b() {}\n\t\t\t\t// #__NO_SIDE_EFFECTS__\n\t\t\t\tasync function c() {}\n\t\t\t\t// #__NO_SIDE_EFFECTS__\n\t\t\t\tasync function* d() {}\n\t\t\t`,\n\t\t\t\"/stmt-export-fn.js\": `\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export function a() {}\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export function* b() {}\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export async function c() {}\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export async function* d() {}\n\t\t\t`,\n\t\t\t\"/stmt-local.js\": `\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ var v0 = function() {}, v1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ let l0 = function() {}, l1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ const c0 = function() {}, c1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ var v2 = () => {}, v3 = () => {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ let l2 = () => {}, l3 = () => {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ const c2 = () => {}, c3 = () => {}\n\t\t\t`,\n\t\t\t\"/stmt-export-local.js\": `\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export var v0 = function() {}, v1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export let l0 = function() {}, l1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export const c0 = function() {}, c1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export var v2 = () => {}, v3 = () => {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export let l2 = () => {}, l3 = () => {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export const c2 = () => {}, c3 = () => {}\n\t\t\t`,\n\n\t\t\t\"/ns-export-fn.ts\": `\n\t\t\t\tnamespace ns {\n\t\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export function a() {}\n\t\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export function* b() {}\n\t\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export async function c() {}\n\t\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export async function* d() {}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/ns-export-local.ts\": `\n\t\t\t\tnamespace ns {\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export var v0 = function() {}, v1 = function() {}\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export let l0 = function() {}, l1 = function() {}\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export const c0 = function() {}, c1 = function() {}\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export var v2 = () => {}, v3 = () => {}\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export let l2 = () => {}, l3 = () => {}\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export const c2 = () => {}, c3 = () => {}\n\t\t\t\t}\n\t\t\t`,\n\n\t\t\t\"/stmt-export-default-before-fn-anon.js\":           `/* #__NO_SIDE_EFFECTS__ */ export default function() {}`,\n\t\t\t\"/stmt-export-default-before-fn-name.js\":           `/* #__NO_SIDE_EFFECTS__ */ export default function f() {}`,\n\t\t\t\"/stmt-export-default-before-gen-fn-anon.js\":       `/* #__NO_SIDE_EFFECTS__ */ export default function*() {}`,\n\t\t\t\"/stmt-export-default-before-gen-fn-name.js\":       `/* #__NO_SIDE_EFFECTS__ */ export default function* f() {}`,\n\t\t\t\"/stmt-export-default-before-async-fn-anon.js\":     `/* #__NO_SIDE_EFFECTS__ */ export default async function() {}`,\n\t\t\t\"/stmt-export-default-before-async-fn-name.js\":     `/* #__NO_SIDE_EFFECTS__ */ export default async function f() {}`,\n\t\t\t\"/stmt-export-default-before-async-gen-fn-anon.js\": `/* #__NO_SIDE_EFFECTS__ */ export default async function*() {}`,\n\t\t\t\"/stmt-export-default-before-async-gen-fn-name.js\": `/* #__NO_SIDE_EFFECTS__ */ export default async function* f() {}`,\n\n\t\t\t\"/stmt-export-default-after-fn-anon.js\":           `export default /* @__NO_SIDE_EFFECTS__ */ function() {}`,\n\t\t\t\"/stmt-export-default-after-fn-name.js\":           `export default /* @__NO_SIDE_EFFECTS__ */ function f() {}`,\n\t\t\t\"/stmt-export-default-after-gen-fn-anon.js\":       `export default /* @__NO_SIDE_EFFECTS__ */ function*() {}`,\n\t\t\t\"/stmt-export-default-after-gen-fn-name.js\":       `export default /* @__NO_SIDE_EFFECTS__ */ function* f() {}`,\n\t\t\t\"/stmt-export-default-after-async-fn-anon.js\":     `export default /* @__NO_SIDE_EFFECTS__ */ async function() {}`,\n\t\t\t\"/stmt-export-default-after-async-fn-name.js\":     `export default /* @__NO_SIDE_EFFECTS__ */ async function f() {}`,\n\t\t\t\"/stmt-export-default-after-async-gen-fn-anon.js\": `export default /* @__NO_SIDE_EFFECTS__ */ async function*() {}`,\n\t\t\t\"/stmt-export-default-after-async-gen-fn-name.js\": `export default /* @__NO_SIDE_EFFECTS__ */ async function* f() {}`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/expr-fn.js\",\n\t\t\t\"/expr-arrow.js\",\n\n\t\t\t\"/stmt-fn.js\",\n\t\t\t\"/stmt-export-fn.js\",\n\t\t\t\"/stmt-local.js\",\n\t\t\t\"/stmt-export-local.js\",\n\n\t\t\t\"/ns-export-fn.ts\",\n\t\t\t\"/ns-export-local.ts\",\n\n\t\t\t\"/stmt-export-default-before-fn-anon.js\",\n\t\t\t\"/stmt-export-default-before-fn-name.js\",\n\t\t\t\"/stmt-export-default-before-gen-fn-anon.js\",\n\t\t\t\"/stmt-export-default-before-gen-fn-name.js\",\n\t\t\t\"/stmt-export-default-before-async-fn-anon.js\",\n\t\t\t\"/stmt-export-default-before-async-fn-name.js\",\n\t\t\t\"/stmt-export-default-before-async-gen-fn-anon.js\",\n\t\t\t\"/stmt-export-default-before-async-gen-fn-name.js\",\n\n\t\t\t\"/stmt-export-default-after-fn-anon.js\",\n\t\t\t\"/stmt-export-default-after-fn-name.js\",\n\t\t\t\"/stmt-export-default-after-gen-fn-anon.js\",\n\t\t\t\"/stmt-export-default-after-gen-fn-name.js\",\n\t\t\t\"/stmt-export-default-after-async-fn-anon.js\",\n\t\t\t\"/stmt-export-default-after-async-fn-name.js\",\n\t\t\t\"/stmt-export-default-after-async-gen-fn-anon.js\",\n\t\t\t\"/stmt-export-default-after-async-gen-fn-name.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tAbsOutputDir:         \"/out\",\n\t\t\tIgnoreDCEAnnotations: true,\n\t\t},\n\t})\n}\n\nfunc TestNoSideEffectsCommentMinifyWhitespace(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/expr-fn.js\": `\n\t\t\t\tx([\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ function() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ function y() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ function*() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ function* y() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async function() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async function y() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async function*() {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async function* y() {},\n\t\t\t\t])\n\t\t\t`,\n\t\t\t\"/expr-arrow.js\": `\n\t\t\t\tx([\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ y => y,\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ () => {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ (y) => (y),\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async y => y,\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async () => {},\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ async (y) => (y),\n\t\t\t\t])\n\t\t\t`,\n\n\t\t\t\"/stmt-fn.js\": `\n\t\t\t\t// #__NO_SIDE_EFFECTS__\n\t\t\t\tfunction a() {}\n\t\t\t\t// #__NO_SIDE_EFFECTS__\n\t\t\t\tfunction* b() {}\n\t\t\t\t// #__NO_SIDE_EFFECTS__\n\t\t\t\tasync function c() {}\n\t\t\t\t// #__NO_SIDE_EFFECTS__\n\t\t\t\tasync function* d() {}\n\t\t\t`,\n\t\t\t\"/stmt-export-fn.js\": `\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export function a() {}\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export function* b() {}\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export async function c() {}\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export async function* d() {}\n\t\t\t`,\n\t\t\t\"/stmt-local.js\": `\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ var v0 = function() {}, v1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ let l0 = function() {}, l1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ const c0 = function() {}, c1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ var v2 = () => {}, v3 = () => {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ let l2 = () => {}, l3 = () => {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ const c2 = () => {}, c3 = () => {}\n\t\t\t`,\n\t\t\t\"/stmt-export-local.js\": `\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export var v0 = function() {}, v1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export let l0 = function() {}, l1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export const c0 = function() {}, c1 = function() {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export var v2 = () => {}, v3 = () => {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export let l2 = () => {}, l3 = () => {}\n\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export const c2 = () => {}, c3 = () => {}\n\t\t\t`,\n\n\t\t\t\"/ns-export-fn.ts\": `\n\t\t\t\tnamespace ns {\n\t\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export function a() {}\n\t\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export function* b() {}\n\t\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export async function c() {}\n\t\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export async function* d() {}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/ns-export-local.ts\": `\n\t\t\t\tnamespace ns {\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export var v0 = function() {}, v1 = function() {}\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export let l0 = function() {}, l1 = function() {}\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export const c0 = function() {}, c1 = function() {}\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export var v2 = () => {}, v3 = () => {}\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export let l2 = () => {}, l3 = () => {}\n\t\t\t\t\t/* #__NO_SIDE_EFFECTS__ */ export const c2 = () => {}, c3 = () => {}\n\t\t\t\t}\n\t\t\t`,\n\n\t\t\t\"/stmt-export-default-before-fn-anon.js\":           `/* #__NO_SIDE_EFFECTS__ */ export default function() {}`,\n\t\t\t\"/stmt-export-default-before-fn-name.js\":           `/* #__NO_SIDE_EFFECTS__ */ export default function f() {}`,\n\t\t\t\"/stmt-export-default-before-gen-fn-anon.js\":       `/* #__NO_SIDE_EFFECTS__ */ export default function*() {}`,\n\t\t\t\"/stmt-export-default-before-gen-fn-name.js\":       `/* #__NO_SIDE_EFFECTS__ */ export default function* f() {}`,\n\t\t\t\"/stmt-export-default-before-async-fn-anon.js\":     `/* #__NO_SIDE_EFFECTS__ */ export default async function() {}`,\n\t\t\t\"/stmt-export-default-before-async-fn-name.js\":     `/* #__NO_SIDE_EFFECTS__ */ export default async function f() {}`,\n\t\t\t\"/stmt-export-default-before-async-gen-fn-anon.js\": `/* #__NO_SIDE_EFFECTS__ */ export default async function*() {}`,\n\t\t\t\"/stmt-export-default-before-async-gen-fn-name.js\": `/* #__NO_SIDE_EFFECTS__ */ export default async function* f() {}`,\n\n\t\t\t\"/stmt-export-default-after-fn-anon.js\":           `export default /* @__NO_SIDE_EFFECTS__ */ function() {}`,\n\t\t\t\"/stmt-export-default-after-fn-name.js\":           `export default /* @__NO_SIDE_EFFECTS__ */ function f() {}`,\n\t\t\t\"/stmt-export-default-after-gen-fn-anon.js\":       `export default /* @__NO_SIDE_EFFECTS__ */ function*() {}`,\n\t\t\t\"/stmt-export-default-after-gen-fn-name.js\":       `export default /* @__NO_SIDE_EFFECTS__ */ function* f() {}`,\n\t\t\t\"/stmt-export-default-after-async-fn-anon.js\":     `export default /* @__NO_SIDE_EFFECTS__ */ async function() {}`,\n\t\t\t\"/stmt-export-default-after-async-fn-name.js\":     `export default /* @__NO_SIDE_EFFECTS__ */ async function f() {}`,\n\t\t\t\"/stmt-export-default-after-async-gen-fn-anon.js\": `export default /* @__NO_SIDE_EFFECTS__ */ async function*() {}`,\n\t\t\t\"/stmt-export-default-after-async-gen-fn-name.js\": `export default /* @__NO_SIDE_EFFECTS__ */ async function* f() {}`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/expr-fn.js\",\n\t\t\t\"/expr-arrow.js\",\n\n\t\t\t\"/stmt-fn.js\",\n\t\t\t\"/stmt-export-fn.js\",\n\t\t\t\"/stmt-local.js\",\n\t\t\t\"/stmt-export-local.js\",\n\n\t\t\t\"/ns-export-fn.ts\",\n\t\t\t\"/ns-export-local.ts\",\n\n\t\t\t\"/stmt-export-default-before-fn-anon.js\",\n\t\t\t\"/stmt-export-default-before-fn-name.js\",\n\t\t\t\"/stmt-export-default-before-gen-fn-anon.js\",\n\t\t\t\"/stmt-export-default-before-gen-fn-name.js\",\n\t\t\t\"/stmt-export-default-before-async-fn-anon.js\",\n\t\t\t\"/stmt-export-default-before-async-fn-name.js\",\n\t\t\t\"/stmt-export-default-before-async-gen-fn-anon.js\",\n\t\t\t\"/stmt-export-default-before-async-gen-fn-name.js\",\n\n\t\t\t\"/stmt-export-default-after-fn-anon.js\",\n\t\t\t\"/stmt-export-default-after-fn-name.js\",\n\t\t\t\"/stmt-export-default-after-gen-fn-anon.js\",\n\t\t\t\"/stmt-export-default-after-gen-fn-name.js\",\n\t\t\t\"/stmt-export-default-after-async-fn-anon.js\",\n\t\t\t\"/stmt-export-default-after-async-fn-name.js\",\n\t\t\t\"/stmt-export-default-after-async-gen-fn-anon.js\",\n\t\t\t\"/stmt-export-default-after-async-gen-fn-name.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tAbsOutputDir:     \"/out\",\n\t\t\tMinifyWhitespace: true,\n\t\t},\n\t})\n}\n\nfunc TestNoSideEffectsCommentUnusedCalls(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/stmt-fn.js\": `\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ function f(y) { sideEffect(y) }\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ function* g(y) { sideEffect(y) }\n\t\t\t\tf('removeThisCall')\n\t\t\t\tg('removeThisCall')\n\t\t\t\tf(onlyKeepThisIdentifier)\n\t\t\t\tg(onlyKeepThisIdentifier)\n\t\t\t\tx(f('keepThisCall'))\n\t\t\t\tx(g('keepThisCall'))\n\t\t\t`,\n\t\t\t\"/stmt-local.js\": `\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ const f = function (y) { sideEffect(y) }\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ const g = function* (y) { sideEffect(y) }\n\t\t\t\tf('removeThisCall')\n\t\t\t\tg('removeThisCall')\n\t\t\t\tf(onlyKeepThisIdentifier)\n\t\t\t\tg(onlyKeepThisIdentifier)\n\t\t\t\tx(f('keepThisCall'))\n\t\t\t\tx(g('keepThisCall'))\n\t\t\t`,\n\t\t\t\"/expr-fn.js\": `\n\t\t\t\tconst f = /* @__NO_SIDE_EFFECTS__ */ function (y) { sideEffect(y) }\n\t\t\t\tconst g = /* @__NO_SIDE_EFFECTS__ */ function* (y) { sideEffect(y) }\n\t\t\t\tf('removeThisCall')\n\t\t\t\tg('removeThisCall')\n\t\t\t\tf(onlyKeepThisIdentifier)\n\t\t\t\tg(onlyKeepThisIdentifier)\n\t\t\t\tx(f('keepThisCall'))\n\t\t\t\tx(g('keepThisCall'))\n\t\t\t`,\n\t\t\t\"/stmt-export-default-fn.js\": `\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export default function f(y) { sideEffect(y) }\n\t\t\t\tf('removeThisCall')\n\t\t\t\tf(onlyKeepThisIdentifier)\n\t\t\t\tx(f('keepThisCall'))\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/stmt-fn.js\",\n\t\t\t\"/stmt-local.js\",\n\t\t\t\"/expr-fn.js\",\n\t\t\t\"/stmt-export-default-fn.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tTreeShaking:  true,\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestNoSideEffectsCommentTypeScriptDeclare(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\t// These should not cause us to crash\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ declare function f1(y) { sideEffect(y) }\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ declare const f2 = function (y) { sideEffect(y) }\n\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ declare const f3 = (y) => { sideEffect(y) }\n\t\t\t\tdeclare const f4 = /* @__NO_SIDE_EFFECTS__ */ function (y) { sideEffect(y) }\n\t\t\t\tdeclare const f5 = /* @__NO_SIDE_EFFECTS__ */ (y) => { sideEffect(y) }\n\t\t\t\tnamespace ns {\n\t\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export declare function f1(y) { sideEffect(y) }\n\t\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export declare const f2 = function (y) { sideEffect(y) }\n\t\t\t\t\t/* @__NO_SIDE_EFFECTS__ */ export declare const f3 = (y) => { sideEffect(y) }\n\t\t\t\t\texport declare const f4 = /* @__NO_SIDE_EFFECTS__ */ function (y) { sideEffect(y) }\n\t\t\t\t\texport declare const f5 = /* @__NO_SIDE_EFFECTS__ */ (y) => { sideEffect(y) }\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestDCEOfIIFE(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/remove-these.js\": `\n\t\t\t\t(() => {})();\n\t\t\t\t(() => {})(keepThisButRemoveTheIIFE);\n\t\t\t\t(() => { /* @__PURE__ */ removeMe() })();\n\t\t\t\tvar someVar;\n\t\t\t\t(x => {})(someVar);\n\t\t\t\tvar removeThis = /* @__PURE__ */ (() => stuff())();\n\t\t\t\tvar removeThis2 = (() => 123)();\n\t\t\t`,\n\t\t\t\"/keep-these.js\": `\n\t\t\t\tundef = (() => {})();\n\t\t\t\t(() => { keepMe() })();\n\t\t\t\t((x = keepMe()) => {})();\n\t\t\t\tvar someVar;\n\t\t\t\t(([y]) => {})(someVar);\n\t\t\t\t(({z}) => {})(someVar);\n\t\t\t\tvar keepThis = /* @__PURE__ */ (() => stuff())();\n\t\t\t\tkeepThis();\n\t\t\t\t((_ = keepMe()) => {})();\n\t\t\t\tvar isPure = ((x, y) => 123)();\n\t\t\t\tuse(isPure);\n\t\t\t\tvar isNotPure = ((x = foo, y = bar) => 123)();\n\t\t\t\tuse(isNotPure);\n\t\t\t\t(async () => ({ get then() { notPure() } }))();\n\t\t\t\t(async function() { return { get then() { notPure() } }; })();\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/remove-these.js\",\n\t\t\t\"/keep-these.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t\tTreeShaking:  true,\n\t\t},\n\t})\n}\n\nfunc TestDCEOfDestructuring(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// Identifier bindings\n\t\t\t\tvar remove1\n\t\t\t\tvar remove2 = null\n\t\t\t\tvar KEEP1 = x\n\n\t\t\t\t// Array patterns\n\t\t\t\tvar [remove3] = []\n\t\t\t\tvar [remove4, ...remove5] = [...[1, 2], 3]\n\t\t\t\tvar [, , remove6] = [, , 3]\n\t\t\t\tvar [KEEP2] = [x]\n\t\t\t\tvar [KEEP3] = [...{}]\n\n\t\t\t\t// Object patterns (not handled right now)\n\t\t\t\tvar { KEEP4 } = {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestDCEOfDecorators(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/keep-these.js\": `\n\t\t\t\timport { fn } from './decorator'\n\t\t\t\t@fn class Class {}\n\t\t\t\tclass Field { @fn field }\n\t\t\t\tclass Method { @fn method() {} }\n\t\t\t\tclass Accessor { @fn accessor accessor }\n\t\t\t\tclass StaticField { @fn static field }\n\t\t\t\tclass StaticMethod { @fn static method() {} }\n\t\t\t\tclass StaticAccessor { @fn static accessor accessor }\n\t\t\t`,\n\t\t\t\"/decorator.js\": `\n\t\t\t\texport const fn = () => {\n\t\t\t\t\tconsole.log('side effect')\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/keep-these.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestDCEOfExperimentalDecorators(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/keep-these.ts\": `\n\t\t\t\timport { fn } from './decorator'\n\t\t\t\t@fn class Class {}\n\t\t\t\tclass Field { @fn field }\n\t\t\t\tclass Method { @fn method() {} }\n\t\t\t\tclass Accessor { @fn accessor accessor }\n\t\t\t\tclass Parameter { foo(@fn bar) {} }\n\t\t\t\tclass StaticField { @fn static field }\n\t\t\t\tclass StaticMethod { @fn static method() {} }\n\t\t\t\tclass StaticAccessor { @fn static accessor accessor }\n\t\t\t\tclass StaticParameter { static foo(@fn bar) {} }\n\t\t\t`,\n\t\t\t\"/decorator.ts\": `\n\t\t\t\texport const fn = () => {\n\t\t\t\t\tconsole.log('side effect')\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"experimentalDecorators\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/keep-these.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestDCEOfUsingDeclarations(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// Note: Only remove \"using\" if it's null or undefined and not awaited\n\n\t\t\t\tusing null_remove = null\n\t\t\t\tusing null_keep = null\n\t\t\t\tawait using await_null_keep = null\n\n\t\t\t\t// This has a side effect: throwing an error\n\t\t\t\tusing throw_keep = {}\n\n\t\t\t\tusing dispose_keep = { [Symbol.dispose]() { console.log('side effect') } }\n\t\t\t\tawait using await_asyncDispose_keep = { [Symbol.asyncDispose]() { console.log('side effect') } }\n\n\t\t\t\tusing undef_remove = undefined\n\t\t\t\tusing undef_keep = undefined\n\t\t\t\tawait using await_undef_keep = undefined\n\n\t\t\t\t// Assume these have no side effects\n\t\t\t\tconst Symbol_dispose_remove = Symbol.dispose\n\t\t\t\tconst Symbol_asyncDispose_remove = Symbol.asyncDispose\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tnull_keep,\n\t\t\t\t\tundef_keep,\n\t\t\t\t)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tTreeShaking:  true,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestDCEOfExprAfterKeepNamesIssue3195(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t(() => {\n\t\t\t\t\tfunction f() {}\n\t\t\t\t\tfirstImportantSideEffect(f());\n\t\t\t\t})();\n\t\t\t\t(() => {\n\t\t\t\t\tfunction g() {}\n\t\t\t\t\tdebugger;\n\t\t\t\t\tsecondImportantSideEffect(g());\n\t\t\t\t})();\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:  true,\n\t\t\tKeepNames:     true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestDropLabels(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tkeep_1: require('foo1')\n\t\t\t\tDROP_1: require('bar1')\n\t\t\t\texports.bar = function() {\n\t\t\t\t\tif (x) DROP_2: require('foo2')\n\t\t\t\t\tif (y) keep_2: require('bar2')\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t\tDropLabels: []string{\n\t\t\t\t\"DROP_1\",\n\t\t\t\t\"DROP_2\",\n\t\t\t},\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tExact: map[string]bool{\n\t\t\t\t\t\t\"foo1\": true,\n\t\t\t\t\t\t\"bar2\": true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t},\n\t})\n}\n\nfunc TestRemoveCodeAfterLabelWithReturn(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction earlyReturn() {\n\t\t\t\t\t// This comes up when doing conditional compilation with \"DropLabels\"\n\t\t\t\t\tkeep: {\n\t\t\t\t\t\tonlyWithKeep()\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tonlyWithoutKeep()\n\t\t\t\t}\n\t\t\t\tfunction loop() {\n\t\t\t\t\tif (foo()) {\n\t\t\t\t\t\tkeep: {\n\t\t\t\t\t\t\tbar()\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMinifySyntax:  true,\n\t\t},\n\t})\n}\n\nfunc TestDropLabelTreeShakingBugIssue3311(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst myFunc = ()=> {\n\t\t\t\t\tDROP: {console.log(\"drop\")}\n\t\t\t\t\tconsole.log(\"keep\")\n\t\t\t\t}\n\t\t\t\texport default myFunc\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tDropLabels:    []string{\"DROP\"},\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t},\n\t})\n}\n\nfunc TestDCEOfSymbolInstances(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/class.js\": `\n\t\t\t\tclass Remove1 {}\n\t\t\t\tclass Remove2 { *[Symbol.iterator]() {} }\n\t\t\t\tclass Remove3 { *[Symbol['iterator']]() {} }\n\n\t\t\t\tclass Keep1 { *[Symbol.iterator]() {} [keep] }\n\t\t\t\tclass Keep2 { [keep]; *[Symbol.iterator]() {} }\n\t\t\t\tclass Keep3 { *[Symbol.wtf]() {} }\n\t\t\t`,\n\t\t\t\"/object.js\": `\n\t\t\t\tlet remove1 = {}\n\t\t\t\tlet remove2 = { *[Symbol.iterator]() {} }\n\t\t\t\tlet remove3 = { *[Symbol['iterator']]() {} }\n\n\t\t\t\tlet keep1 = { *[Symbol.iterator]() {}, [keep]: null }\n\t\t\t\tlet keep2 = { [keep]: null, *[Symbol.iterator]() {} }\n\t\t\t\tlet keep3 = { *[Symbol.wtf]() {} }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/class.js\",\n\t\t\t\"/object.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestDCEOfNegatedBigints(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tlet a = 1\n\t\t\t\tlet b = -1\n\t\t\t\tlet c = 1n\n\t\t\t\tlet d = -1n\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\n// https://github.com/evanw/esbuild/issues/4310\nfunc TestDCEOfIteratorSuperclassIssue4310(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Keep extends NotIterator {}\n\t\t\t\tclass Remove extends Iterator {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestDCEOfSymbolCtorCall(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst y0 = Symbol()\n\t\t\t\tconst y1 = Symbol(undefined)\n\t\t\t\tconst y2 = Symbol(null)\n\t\t\t\tconst y3 = Symbol(true)\n\t\t\t\tconst y4 = Symbol(123)\n\t\t\t\tconst y5 = Symbol(123n)\n\t\t\t\tconst y6 = Symbol('abc')\n\t\t\t\tconst y7 = Symbol(/* @__PURE__ */ (() => Math.random() < 0.5)() ? 'x' : 'y')\n\n\t\t\t\tconst n0 = Symbol({})\n\t\t\t\tconst n1 = Symbol(/./)\n\t\t\t\tconst n2 = Symbol(() => 0)\n\t\t\t\tconst n3 = Symbol(x)\n\t\t\t\tconst n4 = new Symbol('abc')\n\t\t\t\tconst n5 = Symbol(1, 2, 3)\n\t\t\t\tconst n6 = Symbol((() => Math.random() < 0.5)() ? 'x' : 'y')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestDCEOfSymbolForCall(t *testing.T) {\n\tdce_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst y0 = Symbol.for(undefined)\n\t\t\t\tconst y1 = Symbol.for(null)\n\t\t\t\tconst y2 = Symbol.for(true)\n\t\t\t\tconst y3 = Symbol.for(123)\n\t\t\t\tconst y4 = Symbol.for(123n)\n\t\t\t\tconst y5 = Symbol.for('abc')\n\t\t\t\tconst y6 = Symbol.for(/* @__PURE__ */ (() => Math.random() < 0.5)() ? 'x' : 'y')\n\n\t\t\t\tconst n0 = Symbol.for()\n\t\t\t\tconst n1 = Symbol.for({})\n\t\t\t\tconst n2 = Symbol.for(/./)\n\t\t\t\tconst n3 = Symbol.for(() => 0)\n\t\t\t\tconst n4 = Symbol.for(x)\n\t\t\t\tconst n5 = new Symbol.for('abc')\n\t\t\t\tconst n6 = Symbol.for(1, 2, 3)\n\t\t\t\tconst n7 = Symbol.for((() => Math.random() < 0.5)() ? 'x' : 'y')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "internal/bundler_tests/bundler_default_test.go",
    "content": "package bundler_tests\n\nimport (\n\t\"regexp\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/bundler\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\nvar default_suite = suite{\n\tname: \"default\",\n}\n\nfunc TestSimpleES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {fn} from './foo'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport function fn() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestSimpleCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst fn = require('./foo')\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// This test makes sure that require() calls are still recognized in nested\n// scopes. It guards against bugs where require() calls are only recognized in\n// the top-level module scope.\nfunc TestNestedCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction nestedScope() {\n\t\t\t\t\tconst fn = require('./foo')\n\t\t\t\t\tconsole.log(fn())\n\t\t\t\t}\n\t\t\t\tnestedScope()\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// This test makes sure that NewExpressions containing require() calls aren't\n// broken.\nfunc TestNewExpressionCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tnew (require(\"./foo.js\")).Foo();\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\tclass Foo {}\n\t\t\t\tmodule.exports = {Foo};\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestCommonJSFromES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst {foo} = require('./foo')\n\t\t\t\tconsole.log(foo(), bar())\n\t\t\t\tconst {bar} = require('./bar') // This should not be hoisted\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport function foo() {\n\t\t\t\t\treturn 'foo'\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport function bar() {\n\t\t\t\t\treturn 'bar'\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestES6FromCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {foo} from './foo'\n\t\t\t\tconsole.log(foo(), bar())\n\t\t\t\timport {bar} from './bar' // This should be hoisted\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texports.foo = function() {\n\t\t\t\t\treturn 'foo'\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texports.bar = function() {\n\t\t\t\t\treturn 'bar'\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// This test makes sure that ES6 imports are still recognized in nested\n// scopes. It guards against bugs where require() calls are only recognized in\n// the top-level module scope.\nfunc TestNestedES6FromCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {fn} from './foo'\n\t\t\t\t(() => {\n\t\t\t\t\tconsole.log(fn())\n\t\t\t\t})()\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texports.fn = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportFormsES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport default 123\n\t\t\t\texport var v = 234\n\t\t\t\texport let l = 234\n\t\t\t\texport const c = 234\n\t\t\t\texport {Class as C}\n\t\t\t\texport function Fn() {}\n\t\t\t\texport class Class {}\n\t\t\t\texport * from './a'\n\t\t\t\texport * as b from './b'\n\t\t\t`,\n\t\t\t\"/a.js\": \"export const abc = undefined\",\n\t\t\t\"/b.js\": \"export const xyz = null\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportFormsIIFE(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport default 123\n\t\t\t\texport var v = 234\n\t\t\t\texport let l = 234\n\t\t\t\texport const c = 234\n\t\t\t\texport {Class as C}\n\t\t\t\texport function Fn() {}\n\t\t\t\texport class Class {}\n\t\t\t\texport * from './a'\n\t\t\t\texport * as b from './b'\n\t\t\t`,\n\t\t\t\"/a.js\": \"export const abc = undefined\",\n\t\t\t\"/b.js\": \"export const xyz = null\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tGlobalName:    []string{\"globalName\"},\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportFormsWithMinifyIdentifiersAndNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\texport default 123\n\t\t\t\texport var varName = 234\n\t\t\t\texport let letName = 234\n\t\t\t\texport const constName = 234\n\t\t\t\tfunction Func2() {}\n\t\t\t\tclass Class2 {}\n\t\t\t\texport {Class as Cls, Func2 as Fn2, Class2 as Cls2}\n\t\t\t\texport function Func() {}\n\t\t\t\texport class Class {}\n\t\t\t\texport * from './a'\n\t\t\t\texport * as fromB from './b'\n\t\t\t`,\n\t\t\t\"/b.js\": \"export default function() {}\",\n\t\t\t\"/c.js\": \"export default function foo() {}\",\n\t\t\t\"/d.js\": \"export default class {}\",\n\t\t\t\"/e.js\": \"export default class Foo {}\",\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/a.js\",\n\t\t\t\"/b.js\",\n\t\t\t\"/c.js\",\n\t\t\t\"/d.js\",\n\t\t\t\"/e.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputDir:      \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestImportFormsWithNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport 'foo'\n\t\t\t\timport {} from 'foo'\n\t\t\t\timport * as ns from 'foo'\n\t\t\t\timport {a, b as c} from 'foo'\n\t\t\t\timport def from 'foo'\n\t\t\t\timport def2, * as ns2 from 'foo'\n\t\t\t\timport def3, {a2, b as c3} from 'foo'\n\t\t\t\tconst imp = [\n\t\t\t\t\timport('foo'),\n\t\t\t\t\tfunction nested() { return import('foo') },\n\t\t\t\t]\n\t\t\t\tconsole.log(ns, a, c, def, def2, ns2, def3, a2, c3, imp)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportFormsWithMinifyIdentifiersAndNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport 'foo'\n\t\t\t\timport {} from 'foo'\n\t\t\t\timport * as ns from 'foo'\n\t\t\t\timport {a, b as c} from 'foo'\n\t\t\t\timport def from 'foo'\n\t\t\t\timport def2, * as ns2 from 'foo'\n\t\t\t\timport def3, {a2, b as c3} from 'foo'\n\t\t\t\tconst imp = [\n\t\t\t\t\timport('foo'),\n\t\t\t\t\tfunction() { return import('foo') },\n\t\t\t\t]\n\t\t\t\tconsole.log(ns, a, c, def, def2, ns2, def3, a2, c3, imp)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportFormsCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\trequire('./commonjs')\n\t\t\t\trequire('./c')\n\t\t\t\trequire('./d')\n\t\t\t\trequire('./e')\n\t\t\t\trequire('./f')\n\t\t\t\trequire('./g')\n\t\t\t\trequire('./h')\n\t\t\t`,\n\t\t\t\"/commonjs.js\": `\n\t\t\t\texport default 123\n\t\t\t\texport var v = 234\n\t\t\t\texport let l = 234\n\t\t\t\texport const c = 234\n\t\t\t\texport {Class as C}\n\t\t\t\texport function Fn() {}\n\t\t\t\texport class Class {}\n\t\t\t\texport * from './a'\n\t\t\t\texport * as b from './b'\n\t\t\t`,\n\t\t\t\"/a.js\": \"export const abc = undefined\",\n\t\t\t\"/b.js\": \"export const xyz = null\",\n\t\t\t\"/c.js\": \"export default class {}\",\n\t\t\t\"/d.js\": \"export default class Foo {} Foo.prop = 123\",\n\t\t\t\"/e.js\": \"export default function() {}\",\n\t\t\t\"/f.js\": \"export default function foo() {} foo.prop = 123\",\n\t\t\t\"/g.js\": \"export default async function() {}\",\n\t\t\t\"/h.js\": \"export default async function foo() {} foo.prop = 123\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportChain(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {b as a} from './foo'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport {c as b} from './bar'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport const c = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportInfiniteCycle1(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {a as b} from './entry'\n\t\t\t\texport {b as c} from './entry'\n\t\t\t\texport {c as d} from './entry'\n\t\t\t\texport {d as a} from './entry'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `entry.js: ERROR: Detected cycle while resolving import \"a\"\nentry.js: ERROR: Detected cycle while resolving import \"b\"\nentry.js: ERROR: Detected cycle while resolving import \"c\"\nentry.js: ERROR: Detected cycle while resolving import \"d\"\n`,\n\t})\n}\n\nfunc TestExportInfiniteCycle2(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {a as b} from './foo'\n\t\t\t\texport {c as d} from './foo'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport {b as c} from './entry'\n\t\t\t\texport {d as a} from './entry'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `entry.js: ERROR: Detected cycle while resolving import \"a\"\nentry.js: ERROR: Detected cycle while resolving import \"c\"\nfoo.js: ERROR: Detected cycle while resolving import \"b\"\nfoo.js: ERROR: Detected cycle while resolving import \"d\"\n`,\n\t})\n}\n\nfunc TestJSXImportsCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\timport {elem, frag} from './custom-react'\n\t\t\t\tconsole.log(<div/>, <>fragment</>)\n\t\t\t`,\n\t\t\t\"/custom-react.js\": `\n\t\t\t\tmodule.exports = {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tFactory:  config.DefineExpr{Parts: []string{\"elem\"}},\n\t\t\t\tFragment: config.DefineExpr{Parts: []string{\"frag\"}},\n\t\t\t},\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestJSXImportsES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\timport {elem, frag} from './custom-react'\n\t\t\t\tconsole.log(<div/>, <>fragment</>)\n\t\t\t`,\n\t\t\t\"/custom-react.js\": `\n\t\t\t\texport function elem() {}\n\t\t\t\texport function frag() {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tFactory:  config.DefineExpr{Parts: []string{\"elem\"}},\n\t\t\t\tFragment: config.DefineExpr{Parts: []string{\"frag\"}},\n\t\t\t},\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestJSXSyntaxInJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: The JSX syntax extension is not currently enabled\nNOTE: The esbuild loader for this file is currently set to \"js\" but it must be set to \"jsx\" to be able to parse JSX syntax. ` +\n\t\t\t`You can use 'Loader: map[string]api.Loader{\".js\": api.LoaderJSX}' to do that.\n`,\n\t})\n}\n\nfunc TestJSXConstantFragments(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport './default'\n\t\t\t\timport './null'\n\t\t\t\timport './boolean'\n\t\t\t\timport './number'\n\t\t\t\timport './string-single-empty'\n\t\t\t\timport './string-double-empty'\n\t\t\t\timport './string-single-punctuation'\n\t\t\t\timport './string-double-punctuation'\n\t\t\t\timport './string-template'\n\t\t\t`,\n\t\t\t\"/default.jsx\":                   `console.log(<></>)`,\n\t\t\t\"/null.jsx\":                      `console.log(<></>) // @jsxFrag null`,\n\t\t\t\"/boolean.jsx\":                   `console.log(<></>) // @jsxFrag true`,\n\t\t\t\"/number.jsx\":                    `console.log(<></>) // @jsxFrag 123`,\n\t\t\t\"/string-single-empty.jsx\":       `console.log(<></>) // @jsxFrag ''`,\n\t\t\t\"/string-double-empty.jsx\":       `console.log(<></>) // @jsxFrag \"\"`,\n\t\t\t\"/string-single-punctuation.jsx\": `console.log(<></>) // @jsxFrag '['`,\n\t\t\t\"/string-double-punctuation.jsx\": `console.log(<></>) // @jsxFrag \"[\"`,\n\t\t\t\"/string-template.jsx\":           `console.log(<></>) // @jsxFrag ` + \"``\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tFragment: config.DefineExpr{\n\t\t\t\t\tConstant: &js_ast.EString{Value: helpers.StringToUTF16(\"]\")},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `string-template.jsx: WARNING: Invalid JSX fragment: ` + \"``\" + `\n`,\n\t})\n}\n\nfunc TestJSXAutomaticImportsCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\timport {jsx, Fragment} from './custom-react'\n\t\t\t\tconsole.log(<div jsx={jsx}/>, <><Fragment/></>)\n\t\t\t`,\n\t\t\t\"/custom-react.js\": `\n\t\t\t\tmodule.exports = {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tAutomaticRuntime: true,\n\t\t\t},\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"react/jsx-runtime\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestJSXAutomaticImportsES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\timport {jsx, Fragment} from './custom-react'\n\t\t\t\tconsole.log(<div jsx={jsx}/>, <><Fragment/></>)\n\t\t\t`,\n\t\t\t\"/custom-react.js\": `\n\t\t\t\texport function jsx() {}\n\t\t\t\texport function Fragment() {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tAutomaticRuntime: true,\n\t\t\t},\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"react/jsx-runtime\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestJSXAutomaticSyntaxInJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tAutomaticRuntime: true,\n\t\t\t},\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"react/jsx-runtime\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: The JSX syntax extension is not currently enabled\nNOTE: The esbuild loader for this file is currently set to \"js\" but it must be set to \"jsx\" to be able to parse JSX syntax. ` +\n\t\t\t`You can use 'Loader: map[string]api.Loader{\".js\": api.LoaderJSX}' to do that.\n`,\n\t})\n}\n\nfunc TestNodeModules(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRequireChildDirCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\tconsole.log(require('./dir'))\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/dir/index.js\": `\n\t\t\t\tmodule.exports = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRequireChildDirES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport value from './dir'\n\t\t\t\tconsole.log(value)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/dir/index.js\": `\n\t\t\t\texport default 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRequireParentDirCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/dir/entry.js\": `\n\t\t\t\tconsole.log(require('..'))\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/index.js\": `\n\t\t\t\tmodule.exports = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/dir/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRequireParentDirES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/dir/entry.js\": `\n\t\t\t\timport value from '..'\n\t\t\t\tconsole.log(value)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/index.js\": `\n\t\t\t\texport default 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/dir/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportMissingES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport fn, {x as a, y as b} from './foo'\n\t\t\t\tconsole.log(fn(a, b))\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `entry.js: ERROR: No matching export in \"foo.js\" for import \"default\"\nentry.js: ERROR: No matching export in \"foo.js\" for import \"y\"\n`,\n\t})\n}\n\nfunc TestImportMissingUnusedES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport fn, {x as a, y as b} from './foo'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `entry.js: ERROR: No matching export in \"foo.js\" for import \"default\"\nentry.js: ERROR: No matching export in \"foo.js\" for import \"y\"\n`,\n\t})\n}\n\nfunc TestImportMissingCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport fn, {x as a, y as b} from './foo'\n\t\t\t\tconsole.log(fn(a, b))\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texports.x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportMissingNeitherES6NorCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/named.js\": `\n\t\t\t\timport fn, {x as a, y as b} from './foo'\n\t\t\t\tconsole.log(fn(a, b))\n\t\t\t`,\n\t\t\t\"/star.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tconsole.log(ns.default(ns.x, ns.y))\n\t\t\t`,\n\t\t\t\"/star-capture.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tconsole.log(ns)\n\t\t\t`,\n\t\t\t\"/bare.js\": `\n\t\t\t\timport './foo'\n\t\t\t`,\n\t\t\t\"/require.js\": `\n\t\t\t\tconsole.log(require('./foo'))\n\t\t\t`,\n\t\t\t\"/import.js\": `\n\t\t\t\tconsole.log(import('./foo'))\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\tconsole.log('no exports here')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/named.js\",\n\t\t\t\"/star.js\",\n\t\t\t\"/star-capture.js\",\n\t\t\t\"/bare.js\",\n\t\t\t\"/require.js\",\n\t\t\t\"/import.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedCompileLog: `named.js: WARNING: Import \"x\" will always be undefined because the file \"foo.js\" has no exports\nnamed.js: WARNING: Import \"y\" will always be undefined because the file \"foo.js\" has no exports\nstar.js: WARNING: Import \"x\" will always be undefined because the file \"foo.js\" has no exports\nstar.js: WARNING: Import \"y\" will always be undefined because the file \"foo.js\" has no exports\n`,\n\t})\n}\n\nfunc TestExportMissingES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tconsole.log(ns)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport {buton} from './bar'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport const button = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `foo.js: ERROR: No matching export in \"bar.js\" for import \"buton\"\nbar.js: NOTE: Did you mean to import \"button\" instead?\n`,\n\t})\n}\n\nfunc TestDotImport(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {x} from '.'\n\t\t\t\tconsole.log(x)\n\t\t\t`,\n\t\t\t\"/index.js\": `\n\t\t\t\texports.x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRequireWithTemplate(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\tconsole.log(require('./b'))\n\t\t\t\tconsole.log(require(` + \"`./b`\" + `))\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\texports.x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestDynamicImportWithTemplateIIFE(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport('./b').then(ns => console.log(ns))\n\t\t\t\timport(` + \"`./b`\" + `).then(ns => console.log(ns))\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\texports.x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRequireAndDynamicImportInvalidTemplate(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\trequire(tag` + \"`./b`\" + `)\n\t\t\t\trequire(` + \"`./${b}`\" + `)\n\n\t\t\t\ttry {\n\t\t\t\t\trequire(tag` + \"`./b`\" + `)\n\t\t\t\t\trequire(` + \"`./${b}`\" + `)\n\t\t\t\t} catch {\n\t\t\t\t}\n\n\t\t\t\t(async () => {\n\t\t\t\t\timport(tag` + \"`./b`\" + `)\n\t\t\t\t\timport(` + \"`./${b}`\" + `)\n\t\t\t\t\tawait import(tag` + \"`./b`\" + `)\n\t\t\t\t\tawait import(` + \"`./${b}`\" + `)\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\timport(tag` + \"`./b`\" + `)\n\t\t\t\t\t\timport(` + \"`./${b}`\" + `)\n\t\t\t\t\t\tawait import(tag` + \"`./b`\" + `)\n\t\t\t\t\t\tawait import(` + \"`./${b}`\" + `)\n\t\t\t\t\t} catch {\n\t\t\t\t\t}\n\t\t\t\t})()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestDynamicImportWithExpressionCJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport('foo')\n\t\t\t\timport(foo())\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestMinifiedDynamicImportWithExpressionCJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport('foo')\n\t\t\t\timport(foo())\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:             config.ModeConvertFormat,\n\t\t\tOutputFormat:     config.FormatCommonJS,\n\t\t\tAbsOutputFile:    \"/out.js\",\n\t\t\tMinifyWhitespace: true,\n\t\t},\n\t})\n}\n\nfunc TestConditionalRequireResolve(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\trequire.resolve(x ? 'a' : y ? 'b' : 'c')\n\t\t\t\trequire.resolve(x ? y ? 'a' : 'b' : c)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tPlatform:      config.PlatformNode,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"a\": true,\n\t\t\t\t\t\"b\": true,\n\t\t\t\t\t\"c\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestConditionalRequire(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\trequire(x ? 'a' : y ? './b' : 'c')\n\t\t\t\trequire(x ? y ? 'a' : './b' : c)\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\texports.foo = 213\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"a\": true,\n\t\t\t\t\t\"c\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestConditionalImport(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport(x ? 'a' : y ? './import' : 'c')\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport(x ? y ? 'a' : './import' : c)\n\t\t\t`,\n\t\t\t\"/import.js\": `\n\t\t\t\texports.foo = 213\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"a\": true,\n\t\t\t\t\t\"c\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestRequireBadArgumentCount(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\trequire()\n\t\t\t\trequire(\"a\", \"b\")\n\n\t\t\t\ttry {\n\t\t\t\t\trequire()\n\t\t\t\t\trequire(\"a\", \"b\")\n\t\t\t\t} catch {\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRequireJson(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(require('./test.json'))\n\t\t\t`,\n\t\t\t\"/test.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"a\": true,\n\t\t\t\t\t\"b\": 123,\n\t\t\t\t\t\"c\": [null]\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRequireTxt(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(require('./test.txt'))\n\t\t\t`,\n\t\t\t\"/test.txt\": `This is a test.`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRequireBadExtension(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(require('./test.bad'))\n\t\t\t`,\n\t\t\t\"/test.bad\": `This is a test.`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: No loader is configured for \".bad\" files: test.bad\n`,\n\t})\n}\n\nfunc TestFalseRequire(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t(require => require('/test.txt'))()\n\t\t\t`,\n\t\t\t\"/test.txt\": `This is a test.`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRequireWithoutCall(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst req = require\n\t\t\t\treq('./entry')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestNestedRequireWithoutCall(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t(() => {\n\t\t\t\t\tconst req = require\n\t\t\t\t\treq('./entry')\n\t\t\t\t})()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// Test a workaround for the \"debug\" library\nfunc TestRequireWithCallInsideTry(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\ttry {\n\t\t\t\t\tconst supportsColor = require('supports-color');\n\t\t\t\t\tif (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {\n\t\t\t\t\t\texports.colors = [];\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// Test a workaround for the \"moment\" library\nfunc TestRequireWithoutCallInsideTry(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\ttry {\n\t\t\t\t\toldLocale = globalLocale._abbr;\n\t\t\t\t\tvar aliasedRequire = require;\n\t\t\t\t\taliasedRequire('./locale/' + name);\n\t\t\t\t\tgetSetGlobalLocale(oldLocale);\n\t\t\t\t} catch (e) {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRequirePropertyAccessCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// These shouldn't warn since the format is CommonJS\n\t\t\t\tconsole.log(Object.keys(require.cache))\n\t\t\t\tconsole.log(Object.keys(require.extensions))\n\t\t\t\tdelete require.cache['fs']\n\t\t\t\tdelete require.extensions['.json']\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tPlatform:      config.PlatformNode,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// Test a workaround for code using \"await import()\"\nfunc TestAwaitImportInsideTry(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tasync function main(name) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn await import(name)\n\t\t\t\t\t} catch {\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tmain('fs')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportInsideTry(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tlet x\n\t\t\t\ttry {\n\t\t\t\t\tx = import('nope1')\n\t\t\t\t\tx = await import('nope2')\n\t\t\t\t} catch {\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Could not resolve \"nope1\"\nNOTE: You can mark the path \"nope1\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. You can also add \".catch()\" here to handle this failure at run-time instead of bundle-time.\n`,\n\t})\n}\n\n// Test a workaround for code using \"import().catch()\"\nfunc TestImportThenCatch(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport(name).then(pass, fail)\n\t\t\t\timport(name).then(pass).catch(fail)\n\t\t\t\timport(name).catch(fail)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestSourceMap(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {bar} from './bar'\n\t\t\t\timport data from './data.txt'\n\t\t\t\tfunction foo() { bar() }\n\t\t\t\tfoo()\n\t\t\t\tconsole.log(data)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/bar.js\": `\n\t\t\t\texport function bar() { throw new Error('test') }\n\t\t\t`,\n\t\t\t// Someone wanted data from the text loader to show up in the source map: https://github.com/evanw/esbuild/issues/2041\n\t\t\t\"/Users/user/project/src/data.txt\": `#2041`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tSourceMap:     config.SourceMapLinkedWithComment,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\n// This test covers a bug where a \"var\" in a nested scope did not correctly\n// bind with references to that symbol in sibling scopes. Instead, the\n// references were incorrectly considered to be unbound even though the symbol\n// should be hoisted. This caused the renamer to name them different things to\n// avoid a collision, which changed the meaning of the code.\nfunc TestNestedScopeBug(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t(() => {\n\t\t\t\t\tfunction a() {\n\t\t\t\t\t\tb()\n\t\t\t\t\t}\n\t\t\t\t\t{\n\t\t\t\t\t\tvar b = () => {}\n\t\t\t\t\t}\n\t\t\t\t\ta()\n\t\t\t\t})()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestHashbangBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `#!/usr/bin/env a\n\t\t\t\timport {code} from './code'\n\t\t\t\tprocess.exit(code)\n\t\t\t`,\n\t\t\t\"/code.js\": `#!/usr/bin/env b\n\t\t\t\texport const code = 0\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestHashbangNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `#!/usr/bin/env node\n\t\t\t\tprocess.exit(0);\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestHashbangBannerUseStrictOrder(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `#! in file\n\t\t\t\t'use strict'\n\t\t\t\tfoo()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tJSBanner:      \"#! from banner\",\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t},\n\t})\n}\n\nfunc TestRequireFSBrowser(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(require('fs'))\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformBrowser,\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Could not resolve \"fs\"\nNOTE: The package \"fs\" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use \"Platform: api.PlatformNode\" to do that, which will remove this error.\n`,\n\t})\n}\n\nfunc TestRequireFSNode(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\treturn require('fs')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t},\n\t})\n}\n\nfunc TestRequireFSNodeMinify(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\treturn require('fs')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:             config.ModeBundle,\n\t\t\tMinifyWhitespace: true,\n\t\t\tOutputFormat:     config.FormatCommonJS,\n\t\t\tAbsOutputFile:    \"/out.js\",\n\t\t\tPlatform:         config.PlatformNode,\n\t\t},\n\t})\n}\n\nfunc TestImportFSBrowser(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport 'fs'\n\t\t\t\timport * as fs from 'fs'\n\t\t\t\timport defaultValue from 'fs'\n\t\t\t\timport {readFileSync} from 'fs'\n\t\t\t\tconsole.log(fs, readFileSync, defaultValue)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformBrowser,\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Could not resolve \"fs\"\nNOTE: The package \"fs\" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use \"Platform: api.PlatformNode\" to do that, which will remove this error.\n`,\n\t})\n}\n\nfunc TestImportFSNodeCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport 'fs'\n\t\t\t\timport * as fs from 'fs'\n\t\t\t\timport defaultValue from 'fs'\n\t\t\t\timport {readFileSync} from 'fs'\n\t\t\t\tconsole.log(fs, readFileSync, defaultValue)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t},\n\t})\n}\n\nfunc TestImportFSNodeES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport 'fs'\n\t\t\t\timport * as fs from 'fs'\n\t\t\t\timport defaultValue from 'fs'\n\t\t\t\timport {readFileSync} from 'fs'\n\t\t\t\tconsole.log(fs, readFileSync, defaultValue)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t},\n\t})\n}\n\nfunc TestExportFSBrowser(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * as fs from 'fs'\n\t\t\t\texport {readFileSync} from 'fs'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformBrowser,\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Could not resolve \"fs\"\nNOTE: The package \"fs\" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use \"Platform: api.PlatformNode\" to do that, which will remove this error.\n`,\n\t})\n}\n\nfunc TestExportFSNode(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * as fs from 'fs'\n\t\t\t\texport {readFileSync} from 'fs'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t},\n\t})\n}\n\nfunc TestReExportFSNode(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {fs as f} from './foo'\n\t\t\t\texport {readFileSync as rfs} from './foo'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport * as fs from 'fs'\n\t\t\t\texport {readFileSync} from 'fs'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t},\n\t})\n}\n\nfunc TestExportFSNodeInCommonJSModule(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as fs from 'fs'\n\t\t\t\timport {readFileSync} from 'fs'\n\t\t\t\texports.fs = fs\n\t\t\t\texports.readFileSync = readFileSync\n\t\t\t\texports.foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t},\n\t})\n}\n\nfunc TestExportWildcardFSNodeES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * from 'fs'\n\t\t\t\texport * from './internal'\n\t\t\t\texport * from './external'\n\t\t\t`,\n\t\t\t\"/internal.js\": `\n\t\t\t\texport let foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tExact: map[string]bool{\n\t\t\t\t\t\t\"./external\": true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestExportWildcardFSNodeCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * from 'fs'\n\t\t\t\texport * from './internal'\n\t\t\t\texport * from './external'\n\t\t\t`,\n\t\t\t\"/internal.js\": `\n\t\t\t\texport let foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tExact: map[string]bool{\n\t\t\t\t\t\t\"./external\": true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestExportSpecialName(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.mjs\": `\n\t\t\texport const __proto__ = 123;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.mjs\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t},\n\t})\n}\n\nfunc TestExportSpecialNameBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst lib = require('./lib.mjs');\n\t\t\t\tconsole.log(lib.__proto__);\n\t\t\t`,\n\t\t\t\"/lib.mjs\": `\n\t\t\t\texport const __proto__ = 123;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t},\n\t})\n}\n\n// https://github.com/evanw/esbuild/issues/3544\nfunc TestNodeAnnotationFalsePositiveIssue3544(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.mjs\": `\n\t\t\t\texport function confuseNode(exports) {\n\t\t\t\t\t// If this local is called \"exports\", node incorrectly\n\t\t\t\t\t// thinks this file has an export called \"notAnExport\".\n\t\t\t\t\t// We must make sure that it doesn't have that name\n\t\t\t\t\t// when targeting Node with CommonJS.\n\t\t\t\t\texports.notAnExport = function() {\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.mjs\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t},\n\t})\n}\n\n// https://github.com/evanw/esbuild/issues/4100\nfunc TestNodeAnnotationInvalidIdentifierIssue4100(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.mjs\": `\n\t\t\t\tlet foo, bar, baz\n\t\t\t\texport {\n\t\t\t\t\tfoo, bar as if, baz as \"...\"\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.mjs\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t},\n\t})\n}\n\nfunc TestMinifiedBundleES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {foo} from './a'\n\t\t\t\tconsole.log(foo())\n\t\t\t`,\n\t\t\t\"/a.js\": `\n\t\t\t\texport function foo() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t\tfoo()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tMinifySyntax:      true,\n\t\t\tMinifyWhitespace:  true,\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestMinifiedBundleCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst {foo} = require('./a')\n\t\t\t\tconsole.log(foo(), require('./j.json'))\n\t\t\t`,\n\t\t\t\"/a.js\": `\n\t\t\t\texports.foo = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/j.json\": `\n\t\t\t\t{\"test\": true}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tMinifySyntax:      true,\n\t\t\tMinifyWhitespace:  true,\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestMinifiedBundleEndingWithImportantSemicolon(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\twhile(foo()); // This semicolon must not be stripped\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:             config.ModeBundle,\n\t\t\tMinifyWhitespace: true,\n\t\t\tOutputFormat:     config.FormatIIFE,\n\t\t\tAbsOutputFile:    \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRuntimeNameCollisionNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction __require() { return 123 }\n\t\t\t\tconsole.log(__require())\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTopLevelReturnForbiddenImport(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\treturn\n\t\t\t\timport 'foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Top-level return cannot be used inside an ECMAScript module\nentry.js: NOTE: This file is considered to be an ECMAScript module because of the \"import\" keyword here:\n`,\n\t})\n}\n\nfunc TestTopLevelReturnForbiddenExport(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\treturn\n\t\t\t\texport var foo\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Top-level return cannot be used inside an ECMAScript module\nentry.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n`,\n\t})\n}\n\nfunc TestTopLevelReturnForbiddenTLA(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\treturn await foo\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Top-level return cannot be used inside an ECMAScript module\nentry.js: NOTE: This file is considered to be an ECMAScript module because of the top-level \"await\" keyword here:\n`,\n\t})\n}\n\nfunc TestThisOutsideFunction(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tif (shouldBeExportsNotThis) {\n\t\t\t\t\tconsole.log(this)\n\t\t\t\t\tconsole.log((x = this) => this)\n\t\t\t\t\tconsole.log({x: this})\n\t\t\t\t\tconsole.log(class extends this.foo {})\n\t\t\t\t\tconsole.log(class { [this.foo] })\n\t\t\t\t\tconsole.log(class { [this.foo]() {} })\n\t\t\t\t\tconsole.log(class { static [this.foo] })\n\t\t\t\t\tconsole.log(class { static [this.foo]() {} })\n\t\t\t\t}\n\t\t\t\tif (shouldBeThisNotExports) {\n\t\t\t\t\tconsole.log(class { foo = this })\n\t\t\t\t\tconsole.log(class { foo() { this } })\n\t\t\t\t\tconsole.log(class { static foo = this })\n\t\t\t\t\tconsole.log(class { static foo() { this } })\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestThisInsideFunction(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction foo(x = this) { console.log(this) }\n\t\t\t\tconst objFoo = {\n\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t}\n\t\t\t\tclass Foo {\n\t\t\t\t\tx = this\n\t\t\t\t\tstatic y = this.z\n\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t\tstatic bar(x = this) { console.log(this) }\n\t\t\t\t}\n\t\t\t\tnew Foo(foo(objFoo))\n\t\t\t\tif (nested) {\n\t\t\t\t\tfunction bar(x = this) { console.log(this) }\n\t\t\t\t\tconst objBar = {\n\t\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t\t}\n\t\t\t\t\tclass Bar {\n\t\t\t\t\t\tx = this\n\t\t\t\t\t\tstatic y = this.z\n\t\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t\t\tstatic bar(x = this) { console.log(this) }\n\t\t\t\t\t}\n\t\t\t\t\tnew Bar(bar(objBar))\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// The value of \"this\" is \"exports\" in CommonJS modules and undefined in ES6\n// modules. This is determined by the presence of ES6 import/export syntax.\nfunc TestThisWithES6Syntax(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport './cjs'\n\n\t\t\t\timport './es6-import-stmt'\n\t\t\t\timport './es6-import-assign'\n\t\t\t\timport './es6-import-dynamic'\n\t\t\t\timport './es6-import-meta'\n\t\t\t\timport './es6-expr-import-dynamic'\n\t\t\t\timport './es6-expr-import-meta'\n\n\t\t\t\timport './es6-export-variable'\n\t\t\t\timport './es6-export-function'\n\t\t\t\timport './es6-export-async-function'\n\t\t\t\timport './es6-export-enum'\n\t\t\t\timport './es6-export-const-enum'\n\t\t\t\timport './es6-export-module'\n\t\t\t\timport './es6-export-namespace'\n\t\t\t\timport './es6-export-class'\n\t\t\t\timport './es6-export-abstract-class'\n\t\t\t\timport './es6-export-default'\n\t\t\t\timport './es6-export-clause'\n\t\t\t\timport './es6-export-clause-from'\n\t\t\t\timport './es6-export-star'\n\t\t\t\timport './es6-export-star-as'\n\t\t\t\timport './es6-export-assign'\n\t\t\t\timport './es6-export-import-assign'\n\n\t\t\t\timport './es6-ns-export-variable'\n\t\t\t\timport './es6-ns-export-function'\n\t\t\t\timport './es6-ns-export-async-function'\n\t\t\t\timport './es6-ns-export-enum'\n\t\t\t\timport './es6-ns-export-const-enum'\n\t\t\t\timport './es6-ns-export-module'\n\t\t\t\timport './es6-ns-export-namespace'\n\t\t\t\timport './es6-ns-export-class'\n\t\t\t\timport './es6-ns-export-abstract-class'\n\t\t\t`,\n\t\t\t\"/dummy.js\": `export const dummy = 123`,\n\t\t\t\"/cjs.js\":   `console.log(this)`,\n\n\t\t\t\"/es6-import-stmt.js\":         `import './dummy'; console.log(this)`,\n\t\t\t\"/es6-import-assign.ts\":       `import x = require('./dummy'); console.log(this)`,\n\t\t\t\"/es6-import-dynamic.js\":      `import('./dummy'); console.log(this)`,\n\t\t\t\"/es6-import-meta.js\":         `import.meta; console.log(this)`,\n\t\t\t\"/es6-expr-import-dynamic.js\": `(import('./dummy')); console.log(this)`,\n\t\t\t\"/es6-expr-import-meta.js\":    `(import.meta); console.log(this)`,\n\n\t\t\t\"/es6-export-variable.js\":       `export const foo = 123; console.log(this)`,\n\t\t\t\"/es6-export-function.js\":       `export function foo() {} console.log(this)`,\n\t\t\t\"/es6-export-async-function.js\": `export async function foo() {} console.log(this)`,\n\t\t\t\"/es6-export-enum.ts\":           `export enum Foo {} console.log(this)`,\n\t\t\t\"/es6-export-const-enum.ts\":     `export const enum Foo {} console.log(this)`,\n\t\t\t\"/es6-export-module.ts\":         `export module Foo {} console.log(this)`,\n\t\t\t\"/es6-export-namespace.ts\":      `export namespace Foo {} console.log(this)`,\n\t\t\t\"/es6-export-class.js\":          `export class Foo {} console.log(this)`,\n\t\t\t\"/es6-export-abstract-class.ts\": `export abstract class Foo {} console.log(this)`,\n\t\t\t\"/es6-export-default.js\":        `export default 123; console.log(this)`,\n\t\t\t\"/es6-export-clause.js\":         `export {}; console.log(this)`,\n\t\t\t\"/es6-export-clause-from.js\":    `export {} from './dummy'; console.log(this)`,\n\t\t\t\"/es6-export-star.js\":           `export * from './dummy'; console.log(this)`,\n\t\t\t\"/es6-export-star-as.js\":        `export * as ns from './dummy'; console.log(this)`,\n\t\t\t\"/es6-export-assign.ts\":         `export = 123; console.log(this)`,\n\t\t\t\"/es6-export-import-assign.ts\":  `export import x = require('./dummy'); console.log(this)`,\n\n\t\t\t\"/es6-ns-export-variable.ts\":       `namespace ns { export const foo = 123; } console.log(this)`,\n\t\t\t\"/es6-ns-export-function.ts\":       `namespace ns { export function foo() {} } console.log(this)`,\n\t\t\t\"/es6-ns-export-async-function.ts\": `namespace ns { export async function foo() {} } console.log(this)`,\n\t\t\t\"/es6-ns-export-enum.ts\":           `namespace ns { export enum Foo {} } console.log(this)`,\n\t\t\t\"/es6-ns-export-const-enum.ts\":     `namespace ns { export const enum Foo {} } console.log(this)`,\n\t\t\t\"/es6-ns-export-module.ts\":         `namespace ns { export module Foo {} } console.log(this)`,\n\t\t\t\"/es6-ns-export-namespace.ts\":      `namespace ns { export namespace Foo {} } console.log(this)`,\n\t\t\t\"/es6-ns-export-class.ts\":          `namespace ns { export class Foo {} } console.log(this)`,\n\t\t\t\"/es6-ns-export-abstract-class.ts\": `namespace ns { export abstract class Foo {} } console.log(this)`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\tdebugLogs: true,\n\t\texpectedScanLog: `es6-export-abstract-class.ts: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-export-abstract-class.ts: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nes6-export-async-function.js: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-export-async-function.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nes6-export-class.js: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-export-class.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nes6-export-clause-from.js: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-export-clause-from.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nes6-export-clause.js: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-export-clause.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nes6-export-const-enum.ts: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-export-const-enum.ts: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nes6-export-default.js: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-export-default.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nes6-export-enum.ts: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-export-enum.ts: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nes6-export-function.js: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-export-function.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nes6-export-import-assign.ts: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-export-import-assign.ts: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nes6-export-module.ts: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-export-module.ts: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nes6-export-namespace.ts: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-export-namespace.ts: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nes6-export-star-as.js: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-export-star-as.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nes6-export-star.js: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-export-star.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nes6-export-variable.js: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-export-variable.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nes6-expr-import-meta.js: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-expr-import-meta.js: NOTE: This file is considered to be an ECMAScript module because of the use of \"import.meta\" here:\nes6-import-meta.js: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nes6-import-meta.js: NOTE: This file is considered to be an ECMAScript module because of the use of \"import.meta\" here:\n`,\n\t})\n}\n\nfunc TestArrowFnScope(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\ttests = {\n\t\t\t\t\t0: ((x = y => x + y, y) => x + y),\n\t\t\t\t\t1: ((y, x = y => x + y) => x + y),\n\t\t\t\t\t2: ((x = (y = z => x + y + z, z) => x + y + z, y, z) => x + y + z),\n\t\t\t\t\t3: ((y, z, x = (z, y = z => x + y + z) => x + y + z) => x + y + z),\n\t\t\t\t\t4: ((x = y => x + y, y), x + y),\n\t\t\t\t\t5: ((y, x = y => x + y), x + y),\n\t\t\t\t\t6: ((x = (y = z => x + y + z, z) => x + y + z, y, z), x + y + z),\n\t\t\t\t\t7: ((y, z, x = (z, y = z => x + y + z) => x + y + z), x + y + z),\n\t\t\t\t};\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestSwitchScopeNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tswitch (foo) { default: var foo }\n\t\t\t\tswitch (bar) { default: let bar }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestArgumentDefaultValueScopeNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport function a(x = foo) { var foo; return x }\n\t\t\t\texport class b { fn(x = foo) { var foo; return x } }\n\t\t\t\texport let c = [\n\t\t\t\t\tfunction(x = foo) { var foo; return x },\n\t\t\t\t\t(x = foo) => { var foo; return x },\n\t\t\t\t\t{ fn(x = foo) { var foo; return x }},\n\t\t\t\t\tclass { fn(x = foo) { var foo; return x }},\n\t\t\t\t]\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestArgumentsSpecialCaseNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t(() => {\n\t\t\t\t\tvar arguments;\n\n\t\t\t\t\tfunction foo(x = arguments) { return arguments }\n\t\t\t\t\t(function(x = arguments) { return arguments });\n\t\t\t\t\t({foo(x = arguments) { return arguments }});\n\t\t\t\t\tclass Foo { foo(x = arguments) { return arguments } }\n\t\t\t\t\t(class { foo(x = arguments) { return arguments } });\n\n\t\t\t\t\tfunction foo(x = arguments) { var arguments; return arguments }\n\t\t\t\t\t(function(x = arguments) { var arguments; return arguments });\n\t\t\t\t\t({foo(x = arguments) { var arguments; return arguments }});\n\n\t\t\t\t\t(x => arguments);\n\t\t\t\t\t(() => arguments);\n\t\t\t\t\t(async () => arguments);\n\t\t\t\t\t((x = arguments) => arguments);\n\t\t\t\t\t(async (x = arguments) => arguments);\n\n\t\t\t\t\tx => arguments;\n\t\t\t\t\t() => arguments;\n\t\t\t\t\tasync () => arguments;\n\t\t\t\t\t(x = arguments) => arguments;\n\t\t\t\t\tasync (x = arguments) => arguments;\n\n\t\t\t\t\t(x => { return arguments });\n\t\t\t\t\t(() => { return arguments });\n\t\t\t\t\t(async () => { return arguments });\n\t\t\t\t\t((x = arguments) => { return arguments });\n\t\t\t\t\t(async (x = arguments) => { return arguments });\n\n\t\t\t\t\tx => { return arguments };\n\t\t\t\t\t() => { return arguments };\n\t\t\t\t\tasync () => { return arguments };\n\t\t\t\t\t(x = arguments) => { return arguments };\n\t\t\t\t\tasync (x = arguments) => { return arguments };\n\t\t\t\t})()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestWithStatementTaintingNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t(() => {\n\t\t\t\t\tlet local = 1\n\t\t\t\t\tlet outer = 2\n\t\t\t\t\tlet outerDead = 3\n\t\t\t\t\twith ({}) {\n\t\t\t\t\t\tvar hoisted = 4\n\t\t\t\t\t\tlet local = 5\n\t\t\t\t\t\thoisted++\n\t\t\t\t\t\tlocal++\n\t\t\t\t\t\tif (1) outer++\n\t\t\t\t\t\tif (0) outerDead++\n\t\t\t\t\t}\n\t\t\t\t\tif (1) {\n\t\t\t\t\t\thoisted++\n\t\t\t\t\t\tlocal++\n\t\t\t\t\t\touter++\n\t\t\t\t\t\touterDead++\n\t\t\t\t\t}\n\t\t\t\t})()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestDirectEvalTaintingNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction test1() {\n\t\t\t\t\tfunction add(first, second) {\n\t\t\t\t\t\treturn first + second\n\t\t\t\t\t}\n\t\t\t\t\teval('add(1, 2)')\n\t\t\t\t}\n\n\t\t\t\tfunction test2() {\n\t\t\t\t\tfunction add(first, second) {\n\t\t\t\t\t\treturn first + second\n\t\t\t\t\t}\n\t\t\t\t\t(0, eval)('add(1, 2)')\n\t\t\t\t}\n\n\t\t\t\tfunction test3() {\n\t\t\t\t\tfunction add(first, second) {\n\t\t\t\t\t\treturn first + second\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfunction test4(eval) {\n\t\t\t\t\tfunction add(first, second) {\n\t\t\t\t\t\treturn first + second\n\t\t\t\t\t}\n\t\t\t\t\teval('add(1, 2)')\n\t\t\t\t}\n\n\t\t\t\tfunction test5() {\n\t\t\t\t\tfunction containsDirectEval() { eval() }\n\t\t\t\t\tif (true) { var shouldNotBeRenamed }\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportReExportES6Issue149(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/app.jsx\": `\n\t\t\t\timport { p as Part, h, render } from './import';\n\t\t\t\timport { Internal } from './in2';\n\t\t\t\tconst App = () => <Part> <Internal /> T </Part>;\n\t\t\t\trender(<App />, document.getElementById('app'));\n\t\t\t`,\n\t\t\t\"/in2.jsx\": `\n\t\t\t\timport { p as Part, h } from './import';\n\t\t\t\texport const Internal = () => <Part> Test 2 </Part>;\n\t\t\t`,\n\t\t\t\"/import.js\": `\n\t\t\t\timport { h, render } from 'preact';\n\t\t\t\texport const p = \"p\";\n\t\t\t\texport { h, render }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/app.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tFactory: config.DefineExpr{Parts: []string{\"h\"}},\n\t\t\t},\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"preact\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestExternalModuleExclusionPackage(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/index.js\": `\n\t\t\t\timport { S3 } from 'aws-sdk';\n\t\t\t\timport { DocumentClient } from 'aws-sdk/clients/dynamodb';\n\t\t\t\texport const s3 = new S3();\n\t\t\t\texport const dynamodb = new DocumentClient();\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/index.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"aws-sdk\": true,\n\t\t\t\t}, Patterns: []config.WildcardPattern{\n\t\t\t\t\t{Prefix: \"aws-sdk/\"},\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestExternalModuleExclusionScopedPackage(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/index.js\": `\n\t\t\t\timport '@a1'\n\t\t\t\timport '@a1/a2'\n\t\t\t\timport '@a1-a2'\n\n\t\t\t\timport '@b1'\n\t\t\t\timport '@b1/b2'\n\t\t\t\timport '@b1/b2/b3'\n\t\t\t\timport '@b1/b2-b3'\n\n\t\t\t\timport '@c1'\n\t\t\t\timport '@c1/c2'\n\t\t\t\timport '@c1/c2/c3'\n\t\t\t\timport '@c1/c2/c3/c4'\n\t\t\t\timport '@c1/c2/c3-c4'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/index.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"@a1\":       true,\n\t\t\t\t\t\"@b1/b2\":    true,\n\t\t\t\t\t\"@c1/c2/c3\": true,\n\t\t\t\t}, Patterns: []config.WildcardPattern{\n\t\t\t\t\t{Prefix: \"@a1/\"},\n\t\t\t\t\t{Prefix: \"@b1/b2/\"},\n\t\t\t\t\t{Prefix: \"@c1/c2/c3/\"},\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `index.js: ERROR: Could not resolve \"@a1-a2\"\nNOTE: You can mark the path \"@a1-a2\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nindex.js: ERROR: Could not resolve \"@b1\"\nNOTE: You can mark the path \"@b1\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nindex.js: ERROR: Could not resolve \"@b1/b2-b3\"\nNOTE: You can mark the path \"@b1/b2-b3\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nindex.js: ERROR: Could not resolve \"@c1\"\nNOTE: You can mark the path \"@c1\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nindex.js: ERROR: Could not resolve \"@c1/c2\"\nNOTE: You can mark the path \"@c1/c2\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nindex.js: ERROR: Could not resolve \"@c1/c2/c3-c4\"\nNOTE: You can mark the path \"@c1/c2/c3-c4\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestScopedExternalModuleExclusion(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/index.js\": `\n\t\t\t\timport { Foo } from '@scope/foo';\n\t\t\t\timport { Bar } from '@scope/foo/bar';\n\t\t\t\texport const foo = new Foo();\n\t\t\t\texport const bar = new Bar();\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/index.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"@scope/foo\": true,\n\t\t\t\t}, Patterns: []config.WildcardPattern{\n\t\t\t\t\t{Prefix: \"@scope/foo/\"},\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestExternalModuleExclusionRelativePath(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/index.js\": `\n\t\t\t\timport './nested/folder/test'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/nested/folder/test.js\": `\n\t\t\t\timport foo from './foo.js'\n\t\t\t\timport out from '../../../out/in-out-dir.js'\n\t\t\t\timport sha256 from '../../sha256.min.js'\n\t\t\t\timport config from '/api/config?a=1&b=2'\n\t\t\t\tconsole.log(foo, out, sha256, config)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/index.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPostResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"/Users/user/project/out/in-out-dir.js\":        true,\n\t\t\t\t\t\"/Users/user/project/src/nested/folder/foo.js\": true,\n\t\t\t\t\t\"/Users/user/project/src/sha256.min.js\":        true,\n\t\t\t\t}},\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"/api/config?a=1&b=2\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\n// Webpack supports this case, so we do too. Some libraries apparently have\n// these paths: https://github.com/webpack/enhanced-resolve/issues/247\nfunc TestImportWithHashInPath(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport foo from './file#foo.txt'\n\t\t\t\timport bar from './file#bar.txt'\n\t\t\t\tconsole.log(foo, bar)\n\t\t\t`,\n\t\t\t\"/file#foo.txt\": `foo`,\n\t\t\t\"/file#bar.txt\": `bar`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestImportWithHashParameter(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// Each of these should have a separate identity (i.e. end up in the output file twice)\n\t\t\t\timport foo from './file.txt#foo'\n\t\t\t\timport bar from './file.txt#bar'\n\t\t\t\tconsole.log(foo, bar)\n\t\t\t`,\n\t\t\t\"/file.txt\": `This is some text`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestImportWithQueryParameter(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// Each of these should have a separate identity (i.e. end up in the output file twice)\n\t\t\t\timport foo from './file.txt?foo'\n\t\t\t\timport bar from './file.txt?bar'\n\t\t\t\tconsole.log(foo, bar)\n\t\t\t`,\n\t\t\t\"/file.txt\": `This is some text`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestImportAbsPathWithQueryParameter(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.js\": `\n\t\t\t\t// Each of these should have a separate identity (i.e. end up in the output file twice)\n\t\t\t\timport foo from '/Users/user/project/file.txt?foo'\n\t\t\t\timport bar from '/Users/user/project/file.txt#bar'\n\t\t\t\tconsole.log(foo, bar)\n\t\t\t`,\n\t\t\t\"/Users/user/project/file.txt\": `This is some text`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestImportAbsPathAsFile(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.js\": `\n\t\t\t\timport pkg from '/Users/user/project/node_modules/pkg/index'\n\t\t\t\tconsole.log(pkg)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/index.js\": `\n\t\t\t\texport default 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestImportAbsPathAsDir(t *testing.T) {\n\tdefault_suite.expectBundledUnix(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.js\": `\n\t\t\t\timport pkg from '/Users/user/project/node_modules/pkg'\n\t\t\t\tconsole.log(pkg)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/index.js\": `\n\t\t\t\texport default 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n\n\tdefault_suite.expectBundledWindows(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"C:\\\\Users\\\\user\\\\project\\\\entry.js\": `\n\t\t\t\timport pkg from 'C:\\\\Users\\\\user\\\\project\\\\node_modules\\\\pkg'\n\t\t\t\tconsole.log(pkg)\n\t\t\t`,\n\t\t\t\"C:\\\\Users\\\\user\\\\project\\\\node_modules\\\\pkg\\\\index.js\": `\n\t\t\t\texport default 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"C:\\\\Users\\\\user\\\\project\\\\entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"C:\\\\out\",\n\t\t},\n\t})\n}\n\nfunc TestAutoExternal(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// These URLs should be external automatically\n\t\t\t\timport \"http://example.com/code.js\";\n\t\t\t\timport \"https://example.com/code.js\";\n\t\t\t\timport \"//example.com/code.js\";\n\t\t\t\timport \"data:application/javascript;base64,ZXhwb3J0IGRlZmF1bHQgMTIz\";\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestAutoExternalNode(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// These URLs should be external automatically\n\t\t\t\timport fs from \"node:fs/promises\";\n\t\t\t\tfs.readFile();\n\n\t\t\t\t// This should be external and should be tree-shaken because it's side-effect free\n\t\t\t\timport \"node:path\";\n\n\t\t\t\t// This should be external too, but shouldn't be tree-shaken because it could be a run-time error\n\t\t\t\timport \"node:what-is-this\";\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tPlatform:     config.PlatformNode,\n\t\t},\n\t})\n}\n\nfunc TestExternalWithWildcard(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// Should match\n\t\t\t\timport \"/assets/images/test.jpg\";\n\t\t\t\timport \"/dir/x/file.gif\";\n\t\t\t\timport \"/dir//file.gif\";\n\t\t\t\timport \"./file.png\";\n\n\t\t\t\t// Should not match\n\t\t\t\timport \"/sassets/images/test.jpg\";\n\t\t\t\timport \"/dir/file.gif\";\n\t\t\t\timport \"./file.ping\";\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Patterns: []config.WildcardPattern{\n\t\t\t\t\t{Prefix: \"/assets/\"},\n\t\t\t\t\t{Suffix: \".png\"},\n\t\t\t\t\t{Prefix: \"/dir/\", Suffix: \"/file.gif\"},\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Could not resolve \"/sassets/images/test.jpg\"\nentry.js: ERROR: Could not resolve \"/dir/file.gif\"\nentry.js: ERROR: Could not resolve \"./file.ping\"\n`,\n\t})\n}\n\nfunc TestExternalWildcardDoesNotMatchEntryPoint(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t// The \"*\" pattern should not apply to this entry point\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Patterns: []config.WildcardPattern{\n\t\t\t\t\t{},\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\n// This test case makes sure many entry points don't cause a crash\nfunc TestManyEntryPoints(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/shared.js\": `export default 123`,\n\n\t\t\t\"/e00.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e01.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e02.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e03.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e04.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e05.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e06.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e07.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e08.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e09.js\": `import x from './shared'; console.log(x)`,\n\n\t\t\t\"/e10.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e11.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e12.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e13.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e14.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e15.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e16.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e17.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e18.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e19.js\": `import x from './shared'; console.log(x)`,\n\n\t\t\t\"/e20.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e21.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e22.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e23.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e24.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e25.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e26.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e27.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e28.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e29.js\": `import x from './shared'; console.log(x)`,\n\n\t\t\t\"/e30.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e31.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e32.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e33.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e34.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e35.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e36.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e37.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e38.js\": `import x from './shared'; console.log(x)`,\n\t\t\t\"/e39.js\": `import x from './shared'; console.log(x)`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/e00.js\", \"/e01.js\", \"/e02.js\", \"/e03.js\", \"/e04.js\", \"/e05.js\", \"/e06.js\", \"/e07.js\", \"/e08.js\", \"/e09.js\",\n\t\t\t\"/e10.js\", \"/e11.js\", \"/e12.js\", \"/e13.js\", \"/e14.js\", \"/e15.js\", \"/e16.js\", \"/e17.js\", \"/e18.js\", \"/e19.js\",\n\t\t\t\"/e20.js\", \"/e21.js\", \"/e22.js\", \"/e23.js\", \"/e24.js\", \"/e25.js\", \"/e26.js\", \"/e27.js\", \"/e28.js\", \"/e29.js\",\n\t\t\t\"/e30.js\", \"/e31.js\", \"/e32.js\", \"/e33.js\", \"/e34.js\", \"/e35.js\", \"/e36.js\", \"/e37.js\", \"/e38.js\", \"/e39.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestRenamePrivateIdentifiersNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#foo\n\t\t\t\t\tfoo = class {\n\t\t\t\t\t\t#foo\n\t\t\t\t\t\t#foo2\n\t\t\t\t\t\t#bar\n\t\t\t\t\t}\n\t\t\t\t\tget #bar() {}\n\t\t\t\t\tset #bar(x) {}\n\t\t\t\t}\n\t\t\t\tclass Bar {\n\t\t\t\t\t#foo\n\t\t\t\t\tfoo = class {\n\t\t\t\t\t\t#foo2\n\t\t\t\t\t\t#foo\n\t\t\t\t\t\t#bar\n\t\t\t\t\t}\n\t\t\t\t\tget #bar() {}\n\t\t\t\t\tset #bar(x) {}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestMinifyPrivateIdentifiersNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#foo\n\t\t\t\t\tfoo = class {\n\t\t\t\t\t\t#foo\n\t\t\t\t\t\t#foo2\n\t\t\t\t\t\t#bar\n\t\t\t\t\t}\n\t\t\t\t\tget #bar() {}\n\t\t\t\t\tset #bar(x) {}\n\t\t\t\t}\n\t\t\t\tclass Bar {\n\t\t\t\t\t#foo\n\t\t\t\t\tfoo = class {\n\t\t\t\t\t\t#foo2\n\t\t\t\t\t\t#foo\n\t\t\t\t\t\t#bar\n\t\t\t\t\t}\n\t\t\t\t\tget #bar() {}\n\t\t\t\t\tset #bar(x) {}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRenameLabelsNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfoo: {\n\t\t\t\t\tbar: {\n\t\t\t\t\t\tif (x) break bar\n\t\t\t\t\t\tbreak foo\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfoo2: {\n\t\t\t\t\tbar2: {\n\t\t\t\t\t\tif (x) break bar2\n\t\t\t\t\t\tbreak foo2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfoo: {\n\t\t\t\t\tbar: {\n\t\t\t\t\t\tif (x) break bar\n\t\t\t\t\t\tbreak foo\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// These labels should all share the same minified names\nfunc TestMinifySiblingLabelsNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfoo: {\n\t\t\t\t\tbar: {\n\t\t\t\t\t\tif (x) break bar\n\t\t\t\t\t\tbreak foo\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfoo2: {\n\t\t\t\t\tbar2: {\n\t\t\t\t\t\tif (x) break bar2\n\t\t\t\t\t\tbreak foo2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfoo: {\n\t\t\t\t\tbar: {\n\t\t\t\t\t\tif (x) break bar\n\t\t\t\t\t\tbreak foo\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\n// We shouldn't ever generate a label with the name \"if\"\nfunc TestMinifyNestedLabelsNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tL001:L002:L003:L004:L005:L006:L007:L008:L009:L010:L011:L012:L013:L014:L015:L016:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL017:L018:L019:L020:L021:L022:L023:L024:L025:L026:L027:L028:L029:L030:L031:L032:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL033:L034:L035:L036:L037:L038:L039:L040:L041:L042:L043:L044:L045:L046:L047:L048:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL049:L050:L051:L052:L053:L054:L055:L056:L057:L058:L059:L060:L061:L062:L063:L064:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL065:L066:L067:L068:L069:L070:L071:L072:L073:L074:L075:L076:L077:L078:L079:L080:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL081:L082:L083:L084:L085:L086:L087:L088:L089:L090:L091:L092:L093:L094:L095:L096:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL097:L098:L099:L100:L101:L102:L103:L104:L105:L106:L107:L108:L109:L110:L111:L112:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL113:L114:L115:L116:L117:L118:L119:L120:L121:L122:L123:L124:L125:L126:L127:L128:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL129:L130:L131:L132:L133:L134:L135:L136:L137:L138:L139:L140:L141:L142:L143:L144:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL145:L146:L147:L148:L149:L150:L151:L152:L153:L154:L155:L156:L157:L158:L159:L160:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL161:L162:L163:L164:L165:L166:L167:L168:L169:L170:L171:L172:L173:L174:L175:L176:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL177:L178:L179:L180:L181:L182:L183:L184:L185:L186:L187:L188:L189:L190:L191:L192:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL193:L194:L195:L196:L197:L198:L199:L200:L201:L202:L203:L204:L205:L206:L207:L208:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL209:L210:L211:L212:L213:L214:L215:L216:L217:L218:L219:L220:L221:L222:L223:L224:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL225:L226:L227:L228:L229:L230:L231:L232:L233:L234:L235:L236:L237:L238:L239:L240:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL241:L242:L243:L244:L245:L246:L247:L248:L249:L250:L251:L252:L253:L254:L255:L256:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL257:L258:L259:L260:L261:L262:L263:L264:L265:L266:L267:L268:L269:L270:L271:L272:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL273:L274:L275:L276:L277:L278:L279:L280:L281:L282:L283:L284:L285:L286:L287:L288:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL289:L290:L291:L292:L293:L294:L295:L296:L297:L298:L299:L300:L301:L302:L303:L304:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL305:L306:L307:L308:L309:L310:L311:L312:L313:L314:L315:L316:L317:L318:L319:L320:{nl(` + \"`\\n`\" + `)\n\t\t\t\tL321:L322:L323:L324:L325:L326:L327:L328:L329:L330:L331:L332:L333:{}}}}}}}}}}}}}}}}}}nl(` + \"`\\n`\" + `)\n\t\t\t\t}}}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMinifyWhitespace:  true,\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportsAndModuleFormatCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as foo from './foo/test'\n\t\t\t\timport * as bar from './bar/test'\n\t\t\t\tconsole.log(exports, module.exports, foo, bar)\n\t\t\t`,\n\t\t\t\"/foo/test.js\": `\n\t\t\t\texport let foo = 123\n\t\t\t`,\n\t\t\t\"/bar/test.js\": `\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t},\n\n\t\t// The \"test_exports\" names must be different\n\t})\n}\n\nfunc TestMinifiedExportsAndModuleFormatCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as foo from './foo/test'\n\t\t\t\timport * as bar from './bar/test'\n\t\t\t\tconsole.log(exports, module.exports, foo, bar)\n\t\t\t`,\n\t\t\t\"/foo/test.js\": `\n\t\t\t\texport let foo = 123\n\t\t\t`,\n\t\t\t\"/bar/test.js\": `\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tMinifyIdentifiers: true,\n\t\t\tOutputFormat:      config.FormatCommonJS,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t\tPlatform:          config.PlatformNode,\n\t\t},\n\n\t\t// The \"test_exports\" names must be minified, and the \"exports\" and\n\t\t// \"module\" names must not be minified\n\t})\n}\n\nfunc TestEmptyExportClauseBundleAsCommonJSIssue910(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(require('./types.mjs'))\n\t\t\t`,\n\t\t\t\"/types.mjs\": `\n\t\t\t\texport {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t},\n\t})\n}\n\n// The minifier should not remove \"use strict\" or join it with other expressions\nfunc TestUseStrictDirectiveMinifyNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t'use strict'\n\t\t\t\t'use loose'\n\t\t\t\ta\n\t\t\t\tb\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:     true,\n\t\t\tMinifyWhitespace: true,\n\t\t\tAbsOutputFile:    \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestUseStrictDirectiveBundleIssue1837(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(require('./cjs'))\n\t\t\t`,\n\t\t\t\"/cjs.js\": `\n\t\t\t\t'use strict'\n\t\t\t\texports.foo = process\n\t\t\t`,\n\t\t\t\"/shims.js\": `\n\t\t\t\timport process from 'process'\n\t\t\t\texport { process }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tInjectPaths:   []string{\"/shims.js\"},\n\t\t\tPlatform:      config.PlatformNode,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t},\n\t})\n}\n\nfunc TestUseStrictDirectiveBundleIIFEIssue2264(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t'use strict'\n\t\t\t\texport let a = 1\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t},\n\t})\n}\n\nfunc TestUseStrictDirectiveBundleCJSIssue2264(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t'use strict'\n\t\t\t\texport let a = 1\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t},\n\t})\n}\n\nfunc TestUseStrictDirectiveBundleESMIssue2264(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t'use strict'\n\t\t\t\texport let a = 1\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t},\n\t})\n}\n\nfunc TestNoOverwriteInputFileError(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(123)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/\",\n\t\t},\n\t\texpectedCompileLog: `ERROR: Refusing to overwrite input file \"entry.js\" (use \"AllowOverwrite: true\" to allow this)\n`,\n\t})\n}\n\nfunc TestDuplicateEntryPoint(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(123)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\", \"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRelativeEntryPointError(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(123)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"entry\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `ERROR: Could not resolve \"entry\"\nNOTE: Use the relative path \"./entry\" to reference the file \"entry.js\". Without the leading \"./\", the path \"entry\" is being interpreted as a package path instead.\n`,\n\t})\n}\n\nfunc TestMultipleEntryPointsSameNameCollision(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a/entry.js\": `import {foo} from '../common.js'; console.log(foo)`,\n\t\t\t\"/b/entry.js\": `import {foo} from '../common.js'; console.log(foo)`,\n\t\t\t\"/common.js\":  `export let foo = 123`,\n\t\t},\n\t\tentryPaths: []string{\"/a/entry.js\", \"/b/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out/\",\n\t\t},\n\t})\n}\n\nfunc TestReExportCommonJSAsES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {bar} from './foo'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texports.bar = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestReExportDefaultInternal(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {default as foo} from './foo'\n\t\t\t\texport {default as bar} from './bar'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport default 'foo'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport default 'bar'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestReExportDefaultExternalES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {default as foo} from 'foo'\n\t\t\t\texport {bar} from './bar'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport {default as bar} from 'bar'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"foo\": true,\n\t\t\t\t\t\"bar\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestReExportDefaultExternalCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {default as foo} from 'foo'\n\t\t\t\texport {bar} from './bar'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport {default as bar} from 'bar'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"foo\": true,\n\t\t\t\t\t\"bar\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestReExportDefaultNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {default as foo} from './foo'\n\t\t\t\texport {default as bar} from './bar'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestReExportDefaultNoBundleES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {default as foo} from './foo'\n\t\t\t\texport {default as bar} from './bar'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestReExportDefaultNoBundleCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {default as foo} from './foo'\n\t\t\t\texport {default as bar} from './bar'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportMetaCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(import.meta.url, import.meta.path)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: WARNING: \"import.meta\" is not available with the \"cjs\" output format and will be empty\nNOTE: You need to set the output format to \"esm\" for \"import.meta\" to work correctly.\nentry.js: WARNING: \"import.meta\" is not available with the \"cjs\" output format and will be empty\nNOTE: You need to set the output format to \"esm\" for \"import.meta\" to work correctly.\n`,\n\t})\n}\n\nfunc TestImportMetaES6(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(import.meta.url, import.meta.path)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportMetaNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(import.meta.url, import.meta.path)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLegalCommentsNone(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/empty.js\": ``,\n\t\t\t\"/entry.js\": `\n\t\t\t\timport './a'\n\t\t\t\timport './b'\n\t\t\t\timport './c'\n\t\t\t`,\n\t\t\t\"/a.js\": `console.log('in a') //! Copyright notice 1`,\n\t\t\t\"/b.js\": `console.log('in b') //! Copyright notice 1`,\n\t\t\t\"/c.js\": `console.log('in c') //! Copyright notice 2`,\n\n\t\t\t\"/empty.css\": ``,\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"./a.css\";\n\t\t\t\t@import \"./b.css\";\n\t\t\t\t@import \"./c.css\";\n\t\t\t`,\n\t\t\t\"/a.css\": `a { zoom: 2 } /*! Copyright notice 1 */`,\n\t\t\t\"/b.css\": `b { zoom: 2 } /*! Copyright notice 1 */`,\n\t\t\t\"/c.css\": `c { zoom: 2 } /*! Copyright notice 2 */`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry.js\",\n\t\t\t\"/entry.css\",\n\t\t\t\"/empty.js\",\n\t\t\t\"/empty.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tLegalComments: config.LegalCommentsNone,\n\t\t},\n\t})\n}\n\nfunc TestLegalCommentsInline(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/empty.js\": ``,\n\t\t\t\"/entry.js\": `\n\t\t\t\timport './a'\n\t\t\t\timport './b'\n\t\t\t\timport './c'\n\t\t\t`,\n\t\t\t\"/a.js\": `console.log('in a') //! Copyright notice 1`,\n\t\t\t\"/b.js\": `console.log('in b') //! Copyright notice 1`,\n\t\t\t\"/c.js\": `console.log('in c') //! Copyright notice 2`,\n\n\t\t\t\"/empty.css\": ``,\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"./a.css\";\n\t\t\t\t@import \"./b.css\";\n\t\t\t\t@import \"./c.css\";\n\t\t\t`,\n\t\t\t\"/a.css\": `a { zoom: 2 } /*! Copyright notice 1 */`,\n\t\t\t\"/b.css\": `b { zoom: 2 } /*! Copyright notice 1 */`,\n\t\t\t\"/c.css\": `c { zoom: 2 } /*! Copyright notice 2 */`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry.js\",\n\t\t\t\"/entry.css\",\n\t\t\t\"/empty.js\",\n\t\t\t\"/empty.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tLegalComments: config.LegalCommentsInline,\n\t\t},\n\t})\n}\n\nfunc TestLegalCommentsEndOfFile(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/empty.js\": ``,\n\t\t\t\"/entry.js\": `\n\t\t\t\timport './a'\n\t\t\t\timport './b'\n\t\t\t\timport './c'\n\t\t\t`,\n\t\t\t\"/a.js\": `console.log('in a') //! Copyright notice 1`,\n\t\t\t\"/b.js\": `console.log('in b') //! Copyright notice 1`,\n\t\t\t\"/c.js\": `console.log('in c') //! Copyright notice 2`,\n\n\t\t\t\"/empty.css\": ``,\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"./a.css\";\n\t\t\t\t@import \"./b.css\";\n\t\t\t\t@import \"./c.css\";\n\t\t\t`,\n\t\t\t\"/a.css\": `a { zoom: 2 } /*! Copyright notice 1 */`,\n\t\t\t\"/b.css\": `b { zoom: 2 } /*! Copyright notice 1 */`,\n\t\t\t\"/c.css\": `c { zoom: 2 } /*! Copyright notice 2 */`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry.js\",\n\t\t\t\"/entry.css\",\n\t\t\t\"/empty.js\",\n\t\t\t\"/empty.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tLegalComments: config.LegalCommentsEndOfFile,\n\t\t},\n\t})\n}\n\nfunc TestLegalCommentsLinked(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/empty.js\": ``,\n\t\t\t\"/entry.js\": `\n\t\t\t\timport './a'\n\t\t\t\timport './b'\n\t\t\t\timport './c'\n\t\t\t`,\n\t\t\t\"/a.js\": `console.log('in a') //! Copyright notice 1`,\n\t\t\t\"/b.js\": `console.log('in b') //! Copyright notice 1`,\n\t\t\t\"/c.js\": `console.log('in c') //! Copyright notice 2`,\n\n\t\t\t\"/empty.css\": ``,\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"./a.css\";\n\t\t\t\t@import \"./b.css\";\n\t\t\t\t@import \"./c.css\";\n\t\t\t`,\n\t\t\t\"/a.css\": `a { zoom: 2 } /*! Copyright notice 1 */`,\n\t\t\t\"/b.css\": `b { zoom: 2 } /*! Copyright notice 1 */`,\n\t\t\t\"/c.css\": `c { zoom: 2 } /*! Copyright notice 2 */`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry.js\",\n\t\t\t\"/entry.css\",\n\t\t\t\"/empty.js\",\n\t\t\t\"/empty.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tLegalComments: config.LegalCommentsLinkedWithComment,\n\t\t},\n\t})\n}\n\nfunc TestLegalCommentsExternal(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/empty.js\": ``,\n\t\t\t\"/entry.js\": `\n\t\t\t\timport './a'\n\t\t\t\timport './b'\n\t\t\t\timport './c'\n\t\t\t`,\n\t\t\t\"/a.js\": `console.log('in a') //! Copyright notice 1`,\n\t\t\t\"/b.js\": `console.log('in b') //! Copyright notice 1`,\n\t\t\t\"/c.js\": `console.log('in c') //! Copyright notice 2`,\n\n\t\t\t\"/empty.css\": ``,\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"./a.css\";\n\t\t\t\t@import \"./b.css\";\n\t\t\t\t@import \"./c.css\";\n\t\t\t`,\n\t\t\t\"/a.css\": `a { zoom: 2 } /*! Copyright notice 1 */`,\n\t\t\t\"/b.css\": `b { zoom: 2 } /*! Copyright notice 1 */`,\n\t\t\t\"/c.css\": `c { zoom: 2 } /*! Copyright notice 2 */`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry.js\",\n\t\t\t\"/entry.css\",\n\t\t\t\"/empty.js\",\n\t\t\t\"/empty.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tLegalComments: config.LegalCommentsExternalWithoutComment,\n\t\t},\n\t})\n}\n\nfunc TestLegalCommentsModifyIndent(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport default () => {\n\t\t\t\t\t/**\n\t\t\t\t\t * @preserve\n\t\t\t\t\t */\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/entry.css\": `\n\t\t\t\t@media (x: y) {\n\t\t\t\t\t/**\n\t\t\t\t\t * @preserve\n\t\t\t\t\t */\n\t\t\t\t\tz { zoom: 2 }\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\", \"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tLegalComments: config.LegalCommentsInline,\n\t\t},\n\t})\n}\n\nfunc TestLegalCommentsAvoidSlashTagInline(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t//! <script>foo</script>\n\t\t\t\texport let x\n\t\t\t`,\n\t\t\t\"/entry.css\": `\n\t\t\t\t/*! <style>foo</style> */\n\t\t\t\tx { y: z }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\", \"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tLegalComments: config.LegalCommentsInline,\n\t\t},\n\t})\n}\n\nfunc TestLegalCommentsAvoidSlashTagEndOfFile(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t//! <script>foo</script>\n\t\t\t\texport let x\n\t\t\t`,\n\t\t\t\"/entry.css\": `\n\t\t\t\t/*! <style>foo</style> */\n\t\t\t\tx { y: z }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\", \"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tLegalComments: config.LegalCommentsEndOfFile,\n\t\t},\n\t})\n}\n\nfunc TestLegalCommentsAvoidSlashTagExternal(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t//! <script>foo</script>\n\t\t\t\texport let x\n\t\t\t`,\n\t\t\t\"/entry.css\": `\n\t\t\t\t/*! <style>foo</style> */\n\t\t\t\tx { y: z }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\", \"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tLegalComments: config.LegalCommentsExternalWithoutComment,\n\t\t},\n\t})\n}\n\nfunc TestLegalCommentsManyEndOfFile(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/entry.js\": `\n\t\t\t\timport './a'\n\t\t\t\timport './b'\n\t\t\t\timport './c'\n\t\t\t\timport 'some-pkg/js'\n\t\t\t`,\n\t\t\t\"/project/a.js\": `\n\t\t\t\tconsole.log('in a') //! Copyright notice 1\n\t\t\t\t//! Duplicate comment\n\t\t\t\t//! Duplicate comment\n\t\t\t`,\n\t\t\t\"/project/b.js\": `\n\t\t\t\tconsole.log('in b') //! Copyright notice 1\n\t\t\t\t//! Duplicate comment\n\t\t\t\t//! Duplicate comment\n\t\t\t`,\n\t\t\t\"/project/c.js\": `\n\t\t\t\tfunction foo() {\n\t\t\t\t\t/*\n\t\t\t\t\t * @license\n\t\t\t\t\t * Copyright notice 2\n\t\t\t\t\t */\n\t\t\t\t\tconsole.log('in c')\n\t\t\t\t\t// @preserve This is another comment\n\t\t\t\t}\n\t\t\t\tfoo()\n\t\t\t`,\n\t\t\t\"/project/node_modules/some-pkg/js/index.js\": `\n\t\t\t\timport \"some-other-pkg/js\" //! (c) Good Software Corp\n\t\t\t\t//! Duplicate third-party comment\n\t\t\t\t//! Duplicate third-party comment\n\t\t\t`,\n\t\t\t\"/project/node_modules/some-other-pkg/js/index.js\": `\n\t\t\t\tfunction bar() {\n\t\t\t\t\t/*\n\t\t\t\t\t * @preserve\n\t\t\t\t\t * (c) Evil Software Corp\n\t\t\t\t\t */\n\t\t\t\t\tconsole.log('some-other-pkg')\n\t\t\t\t}\n\t\t\t\t//! Duplicate third-party comment\n\t\t\t\t//! Duplicate third-party comment\n\t\t\t\tbar()\n\t\t\t`,\n\n\t\t\t\"/project/entry.css\": `\n\t\t\t\t@import \"./a.css\";\n\t\t\t\t@import \"./b.css\";\n\t\t\t\t@import \"./c.css\";\n\t\t\t\t@import 'some-pkg/css';\n\t\t\t`,\n\t\t\t\"/project/a.css\": `\n\t\t\t\ta { zoom: 2 } /*! Copyright notice 1 */\n\t\t\t\t/*! Duplicate comment */\n\t\t\t\t/*! Duplicate comment */\n\t\t\t`,\n\t\t\t\"/project/b.css\": `\n\t\t\t\tb { zoom: 2 } /*! Copyright notice 1 */\n\t\t\t\t/*! Duplicate comment */\n\t\t\t\t/*! Duplicate comment */\n\t\t\t`,\n\t\t\t\"/project/c.css\": `\n\t\t\t\t/*\n\t\t\t\t * @license\n\t\t\t\t * Copyright notice 2\n\t\t\t\t */\n\t\t\t\tc {\n\t\t\t\t\tzoom: 2\n\t\t\t\t}\n\t\t\t\t/* @preserve This is another comment */\n\t\t\t`,\n\t\t\t\"/project/node_modules/some-pkg/css/index.css\": `\n\t\t\t\t@import \"some-other-pkg/css\"; /*! (c) Good Software Corp */\n\t\t\t\t/*! Duplicate third-party comment */\n\t\t\t\t/*! Duplicate third-party comment */\n\t\t\t`,\n\t\t\t\"/project/node_modules/some-other-pkg/css/index.css\": `\n\t\t\t\t/*! Duplicate third-party comment */\n\t\t\t\t/*! Duplicate third-party comment */\n\t\t\t\t.some-other-pkg {\n\t\t\t\t\tzoom: 2\n\t\t\t\t}\n\t\t\t\t/** @preserve\n\t\t\t\t * (c) Evil Software Corp\n\t\t\t\t */\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/project/entry.js\", \"/project/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:             config.ModeBundle,\n\t\t\tAbsOutputDir:     \"/out\",\n\t\t\tMinifyWhitespace: true,\n\t\t\tLegalComments:    config.LegalCommentsEndOfFile,\n\t\t},\n\t})\n}\n\nfunc TestLegalCommentsEscapeSlashScriptAndStyleEndOfFile(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/entry.js\":                     `import \"js-pkg\"; a /*! </script> */`,\n\t\t\t\"/project/node_modules/js-pkg/index.js\": `x /*! </script> */`,\n\n\t\t\t\"/project/entry.css\":                      `@import \"css-pkg\"; a { b: c } /*! </style> */`,\n\t\t\t\"/project/node_modules/css-pkg/index.css\": `x { y: z } /*! </style> */`,\n\t\t},\n\t\tentryPaths: []string{\"/project/entry.js\", \"/project/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:             config.ModeBundle,\n\t\t\tAbsOutputDir:     \"/out\",\n\t\t\tMinifyWhitespace: true,\n\t\t\tLegalComments:    config.LegalCommentsEndOfFile,\n\t\t},\n\t})\n}\n\nfunc TestLegalCommentsEscapeSlashScriptAndStyleExternal(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/entry.js\":                     `import \"js-pkg\"; a /*! </script> */`,\n\t\t\t\"/project/node_modules/js-pkg/index.js\": `x /*! </script> */`,\n\n\t\t\t\"/project/entry.css\":                      `@import \"css-pkg\"; a { b: c } /*! </style> */`,\n\t\t\t\"/project/node_modules/css-pkg/index.css\": `x { y: z } /*! </style> */`,\n\t\t},\n\t\tentryPaths: []string{\"/project/entry.js\", \"/project/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:             config.ModeBundle,\n\t\t\tAbsOutputDir:     \"/out\",\n\t\t\tMinifyWhitespace: true,\n\t\t\tLegalComments:    config.LegalCommentsExternalWithoutComment,\n\t\t},\n\t})\n}\n\nfunc TestLegalCommentsNoEscapeSlashScriptEndOfFile(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/entry.js\":                     `import \"js-pkg\"; a /*! </script> */`,\n\t\t\t\"/project/node_modules/js-pkg/index.js\": `x /*! </script> */`,\n\n\t\t\t\"/project/entry.css\":                      `@import \"css-pkg\"; a { b: c } /*! </style> */`,\n\t\t\t\"/project/node_modules/css-pkg/index.css\": `x { y: z } /*! </style> */`,\n\t\t},\n\t\tentryPaths: []string{\"/project/entry.js\", \"/project/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tMinifyWhitespace:      true,\n\t\t\tLegalComments:         config.LegalCommentsEndOfFile,\n\t\t\tUnsupportedJSFeatures: compat.InlineScript,\n\t\t},\n\t})\n}\n\nfunc TestLegalCommentsNoEscapeSlashStyleEndOfFile(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/entry.js\":                     `import \"js-pkg\"; a /*! </script> */`,\n\t\t\t\"/project/node_modules/js-pkg/index.js\": `x /*! </script> */`,\n\n\t\t\t\"/project/entry.css\":                      `@import \"css-pkg\"; a { b: c } /*! </style> */`,\n\t\t\t\"/project/node_modules/css-pkg/index.css\": `x { y: z } /*! </style> */`,\n\t\t},\n\t\tentryPaths: []string{\"/project/entry.js\", \"/project/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:                   config.ModeBundle,\n\t\t\tAbsOutputDir:           \"/out\",\n\t\t\tMinifyWhitespace:       true,\n\t\t\tLegalComments:          config.LegalCommentsEndOfFile,\n\t\t\tUnsupportedCSSFeatures: compat.InlineStyle,\n\t\t},\n\t})\n}\n\nfunc TestLegalCommentsManyLinked(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/entry.js\": `\n\t\t\t\timport './a'\n\t\t\t\timport './b'\n\t\t\t\timport './c'\n\t\t\t\timport 'some-pkg/js'\n\t\t\t`,\n\t\t\t\"/project/a.js\": `console.log('in a') //! Copyright notice 1`,\n\t\t\t\"/project/b.js\": `console.log('in b') //! Copyright notice 1`,\n\t\t\t\"/project/c.js\": `\n\t\t\t\tfunction foo() {\n\t\t\t\t\t/*\n\t\t\t\t\t * @license\n\t\t\t\t\t * Copyright notice 2\n\t\t\t\t\t */\n\t\t\t\t\tconsole.log('in c')\n\t\t\t\t\t// @preserve This is another comment\n\t\t\t\t}\n\t\t\t\tfoo()\n\t\t\t`,\n\t\t\t\"/project/node_modules/some-pkg/js/index.js\": `import \"some-other-pkg/js\" //! (c) Good Software Corp`,\n\t\t\t\"/project/node_modules/some-other-pkg/js/index.js\": `\n\t\t\t\tfunction bar() {\n\t\t\t\t\t/*\n\t\t\t\t\t * @preserve\n\t\t\t\t\t * (c) Evil Software Corp\n\t\t\t\t\t */\n\t\t\t\t\tconsole.log('some-other-pkg')\n\t\t\t\t}\n\t\t\t\tbar()\n\t\t\t`,\n\n\t\t\t\"/project/entry.css\": `\n\t\t\t\t@import \"./a.css\";\n\t\t\t\t@import \"./b.css\";\n\t\t\t\t@import \"./c.css\";\n\t\t\t\t@import 'some-pkg/css';\n\t\t\t`,\n\t\t\t\"/project/a.css\": `a { zoom: 2 } /*! Copyright notice 1 */`,\n\t\t\t\"/project/b.css\": `b { zoom: 2 } /*! Copyright notice 1 */`,\n\t\t\t\"/project/c.css\": `\n\t\t\t\t/*\n\t\t\t\t * @license\n\t\t\t\t * Copyright notice 2\n\t\t\t\t */\n\t\t\t\tc {\n\t\t\t\t\tzoom: 2\n\t\t\t\t}\n\t\t\t\t/* @preserve This is another comment */\n\t\t\t`,\n\t\t\t\"/project/node_modules/some-pkg/css/index.css\": `@import \"some-other-pkg/css\"; /*! (c) Good Software Corp */`,\n\t\t\t\"/project/node_modules/some-other-pkg/css/index.css\": `\n\t\t\t\t.some-other-pkg {\n\t\t\t\t\tzoom: 2\n\t\t\t\t}\n\t\t\t\t/** @preserve\n\t\t\t\t * (c) Evil Software Corp\n\t\t\t\t */\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/project/entry.js\", \"/project/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:             config.ModeBundle,\n\t\t\tAbsOutputDir:     \"/out\",\n\t\t\tMinifyWhitespace: true,\n\t\t\tLegalComments:    config.LegalCommentsLinkedWithComment,\n\t\t},\n\t})\n}\n\n// https://github.com/evanw/esbuild/issues/4139\nfunc TestLegalCommentsMergeDuplicatesIssue4139(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/entry.js\": `\n\t\t\t\timport 'pkg/a'\n\t\t\t\timport 'pkg/b'\n\t\t\t\timport 'pkg/c'\n\t\t\t\timport 'pkg/d'\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/a.js\": `\n/*!-----------------------------------------------------------------------------\n * Copyright (c) Example Corporation. All rights reserved.\n * Version: 1.2.3\n * Released under the MIT license\n * https://example.com/LICENSE.txt\n *-----------------------------------------------------------------------------*/\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/b.js\": `\n/*!-----------------------------------------------------------------------------\n * Copyright (c) Example Corporation. All rights reserved.\n * Version: 1.2.3\n * Released under the MIT license\n * https://example.com/LICENSE.txt\n *-----------------------------------------------------------------------------*/\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/c.js\": `\n//! some other comment\n/*!-----------------------------------------------------------------------------\n * Copyright (c) Example Corporation. All rights reserved.\n * Version: 1.2.3\n * Released under the MIT license\n * https://example.com/LICENSE.txt\n *-----------------------------------------------------------------------------*/\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg/d.js\": `\n/*!-----------------------------------------------------------------------------\n * Copyright (c) Example Corporation. All rights reserved.\n * Version: 1.2.3\n * Released under the MIT license\n * https://example.com/LICENSE.txt\n *-----------------------------------------------------------------------------*/\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/project/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tLegalComments: config.LegalCommentsEndOfFile,\n\t\t},\n\t})\n}\n\n// The IIFE should not be an arrow function when targeting ES5\nfunc TestIIFE_ES5(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log('test');\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(5),\n\t\t\tOutputFormat:          config.FormatIIFE,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestOutputExtensionRemappingFile(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log('test');\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tOutputExtensionJS: \".notjs\",\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestOutputExtensionRemappingDir(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log('test');\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tOutputExtensionJS: \".notjs\",\n\t\t\tAbsOutputDir:      \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTopLevelAwaitIIFE(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tawait foo;\n\t\t\t\tfor await (foo of bar) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Top-level await is currently not supported with the \"iife\" output format\nentry.js: ERROR: Top-level await is currently not supported with the \"iife\" output format\n`,\n\t})\n}\n\nfunc TestTopLevelAwaitIIFEDeadBranch(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tif (false) await foo;\n\t\t\t\tif (false) for await (foo of bar) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTopLevelAwaitCJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tawait foo;\n\t\t\t\tfor await (foo of bar) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Top-level await is currently not supported with the \"cjs\" output format\nentry.js: ERROR: Top-level await is currently not supported with the \"cjs\" output format\n`,\n\t})\n}\n\nfunc TestTopLevelAwaitCJSDeadBranch(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tif (false) await foo;\n\t\t\t\tif (false) for await (foo of bar) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTopLevelAwaitESM(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tawait foo;\n\t\t\t\tfor await (foo of bar) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTopLevelAwaitESMDeadBranch(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tif (false) await foo;\n\t\t\t\tif (false) for await (foo of bar) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTopLevelAwaitNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tawait foo;\n\t\t\t\tfor await (foo of bar) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTopLevelAwaitNoBundleDeadBranch(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tif (false) await foo;\n\t\t\t\tif (false) for await (foo of bar) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTopLevelAwaitNoBundleESM(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tawait foo;\n\t\t\t\tfor await (foo of bar) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTopLevelAwaitNoBundleESMDeadBranch(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tif (false) await foo;\n\t\t\t\tif (false) for await (foo of bar) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTopLevelAwaitNoBundleCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tawait foo;\n\t\t\t\tfor await (foo of bar) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Top-level await is currently not supported with the \"cjs\" output format\nentry.js: ERROR: Top-level await is currently not supported with the \"cjs\" output format\n`,\n\t})\n}\n\nfunc TestTopLevelAwaitNoBundleCommonJSDeadBranch(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tif (false) await foo;\n\t\t\t\tif (false) for await (foo of bar) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTopLevelAwaitNoBundleIIFE(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tawait foo;\n\t\t\t\tfor await (foo of bar) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Top-level await is currently not supported with the \"iife\" output format\nentry.js: ERROR: Top-level await is currently not supported with the \"iife\" output format\n`,\n\t})\n}\n\nfunc TestTopLevelAwaitNoBundleIIFEDeadBranch(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tif (false) await foo;\n\t\t\t\tif (false) for await (foo of bar) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTopLevelAwaitForbiddenRequire(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\trequire('./a')\n\t\t\t\trequire('./b')\n\t\t\t\trequire('./c')\n\t\t\t\trequire('./entry')\n\t\t\t\tawait 0\n\t\t\t`,\n\t\t\t\"/a.js\": `\n\t\t\t\timport './something' // Deliberately offset the import record index\n\t\t\t\timport './b'\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport './c'\n\t\t\t`,\n\t\t\t\"/c.js\": `\n\t\t\t\tawait 0\n\t\t\t`,\n\t\t\t\"/something.js\": ``,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: This require call is not allowed because the transitive dependency \"c.js\" contains a top-level await\na.js: NOTE: The file \"a.js\" imports the file \"b.js\" here:\nb.js: NOTE: The file \"b.js\" imports the file \"c.js\" here:\nc.js: NOTE: The top-level await in \"c.js\" is here:\nentry.js: ERROR: This require call is not allowed because the transitive dependency \"c.js\" contains a top-level await\nb.js: NOTE: The file \"b.js\" imports the file \"c.js\" here:\nc.js: NOTE: The top-level await in \"c.js\" is here:\nentry.js: ERROR: This require call is not allowed because the imported file \"c.js\" contains a top-level await\nc.js: NOTE: The top-level await in \"c.js\" is here:\nentry.js: ERROR: This require call is not allowed because the imported file \"entry.js\" contains a top-level await\nentry.js: NOTE: The top-level await in \"entry.js\" is here:\n`,\n\t})\n}\n\nfunc TestTopLevelAwaitForbiddenRequireDeadBranch(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\trequire('./a')\n\t\t\t\trequire('./b')\n\t\t\t\trequire('./c')\n\t\t\t\trequire('./entry')\n\t\t\t\tif (false) for await (let x of y) await 0\n\t\t\t`,\n\t\t\t\"/a.js\": `\n\t\t\t\timport './b'\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport './c'\n\t\t\t`,\n\t\t\t\"/c.js\": `\n\t\t\t\tif (false) for await (let x of y) await 0\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTopLevelAwaitAllowedImportWithoutSplitting(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport('./a')\n\t\t\t\timport('./b')\n\t\t\t\timport('./c')\n\t\t\t\timport('./entry')\n\t\t\t\tawait 0\n\t\t\t`,\n\t\t\t\"/a.js\": `\n\t\t\t\timport './b'\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport './c'\n\t\t\t`,\n\t\t\t\"/c.js\": `\n\t\t\t\tawait 0\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTopLevelAwaitAllowedImportWithSplitting(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport('./a')\n\t\t\t\timport('./b')\n\t\t\t\timport('./c')\n\t\t\t\timport('./entry')\n\t\t\t\tawait 0\n\t\t\t`,\n\t\t\t\"/a.js\": `\n\t\t\t\timport './b'\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport './c'\n\t\t\t`,\n\t\t\t\"/c.js\": `\n\t\t\t\tawait 0\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tCodeSplitting: true,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestAssignToImport(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"./bad0.js\"\n\t\t\t\timport \"./bad1.js\"\n\t\t\t\timport \"./bad2.js\"\n\t\t\t\timport \"./bad3.js\"\n\t\t\t\timport \"./bad4.js\"\n\t\t\t\timport \"./bad5.js\"\n\t\t\t\timport \"./bad6.js\"\n\t\t\t\timport \"./bad7.js\"\n\t\t\t\timport \"./bad8.js\"\n\t\t\t\timport \"./bad9.js\"\n\t\t\t\timport \"./bad10.js\"\n\t\t\t\timport \"./bad11.js\"\n\t\t\t\timport \"./bad12.js\"\n\t\t\t\timport \"./bad13.js\"\n\t\t\t\timport \"./bad14.js\"\n\t\t\t\timport \"./bad15.js\"\n\n\t\t\t\timport \"./good0.js\"\n\t\t\t\timport \"./good1.js\"\n\t\t\t\timport \"./good2.js\"\n\t\t\t\timport \"./good3.js\"\n\t\t\t\timport \"./good4.js\"\n\t\t\t`,\n\t\t\t\"/node_modules/foo/index.js\": ``,\n\n\t\t\t\"/bad0.js\":  `import x from \"foo\"; x = 1`,\n\t\t\t\"/bad1.js\":  `import x from \"foo\"; x++`,\n\t\t\t\"/bad2.js\":  `import x from \"foo\"; ([x] = 1)`,\n\t\t\t\"/bad3.js\":  `import x from \"foo\"; ({x} = 1)`,\n\t\t\t\"/bad4.js\":  `import x from \"foo\"; ({y: x} = 1)`,\n\t\t\t\"/bad5.js\":  `import {x} from \"foo\"; x++`,\n\t\t\t\"/bad6.js\":  `import * as x from \"foo\"; x++`,\n\t\t\t\"/bad7.js\":  `import * as x from \"foo\"; x.y = 1`,\n\t\t\t\"/bad8.js\":  `import * as x from \"foo\"; x[y] = 1`,\n\t\t\t\"/bad9.js\":  `import * as x from \"foo\"; x['y'] = 1`,\n\t\t\t\"/bad10.js\": `import * as x from \"foo\"; x['y z'] = 1`,\n\t\t\t\"/bad11.js\": `import x from \"foo\"; delete x`,\n\t\t\t\"/bad12.js\": `import {x} from \"foo\"; delete x`,\n\t\t\t\"/bad13.js\": `import * as x from \"foo\"; delete x.y`,\n\t\t\t\"/bad14.js\": `import * as x from \"foo\"; delete x['y']`,\n\t\t\t\"/bad15.js\": `import * as x from \"foo\"; delete x[y]`,\n\n\t\t\t\"/good0.js\": `import x from \"foo\"; ({y = x} = 1)`,\n\t\t\t\"/good1.js\": `import x from \"foo\"; ({[x]: y} = 1)`,\n\t\t\t\"/good2.js\": `import x from \"foo\"; x.y = 1`,\n\t\t\t\"/good3.js\": `import x from \"foo\"; x[y] = 1`,\n\t\t\t\"/good4.js\": `import x from \"foo\"; x['y'] = 1`,\n\t\t\t\"/good5.js\": `import x from \"foo\"; x['y z'] = 1`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `bad0.js: ERROR: Cannot assign to import \"x\"\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setX\") and then import and call that function here instead.\nbad1.js: ERROR: Cannot assign to import \"x\"\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setX\") and then import and call that function here instead.\nbad10.js: ERROR: Cannot assign to import \"y z\"\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file and then import and call that function here instead.\nbad11.js: ERROR: Delete of a bare identifier cannot be used in an ECMAScript module\nbad11.js: NOTE: This file is considered to be an ECMAScript module because of the \"import\" keyword here:\nbad12.js: ERROR: Delete of a bare identifier cannot be used in an ECMAScript module\nbad12.js: NOTE: This file is considered to be an ECMAScript module because of the \"import\" keyword here:\nbad13.js: ERROR: Cannot assign to import \"y\"\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setY\") and then import and call that function here instead.\nbad14.js: ERROR: Cannot assign to import \"y\"\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setY\") and then import and call that function here instead.\nbad15.js: ERROR: Cannot assign to property on import \"x\"\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file and then import and call that function here instead.\nbad2.js: ERROR: Cannot assign to import \"x\"\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setX\") and then import and call that function here instead.\nbad3.js: ERROR: Cannot assign to import \"x\"\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setX\") and then import and call that function here instead.\nbad4.js: ERROR: Cannot assign to import \"x\"\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setX\") and then import and call that function here instead.\nbad5.js: ERROR: Cannot assign to import \"x\"\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setX\") and then import and call that function here instead.\nbad6.js: ERROR: Cannot assign to import \"x\"\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setX\") and then import and call that function here instead.\nbad7.js: ERROR: Cannot assign to import \"y\"\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setY\") and then import and call that function here instead.\nbad8.js: ERROR: Cannot assign to property on import \"x\"\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file and then import and call that function here instead.\nbad9.js: ERROR: Cannot assign to import \"y\"\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setY\") and then import and call that function here instead.\n`,\n\t})\n}\n\nfunc TestAssignToImportNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t// The cases labeled \"uncaught\" below are not caught when bundling is\n\t\t\t// disabled. This is because bundling enables extra transforms and\n\t\t\t// analysis that isn't done otherwise that then allows these cases\n\t\t\t// to be caught. Despite these gaps, we still enable the warning\n\t\t\t// because it's still useful for the cases it does catch.\n\n\t\t\t\"/bad0.js\":       `import x from \"foo\"; x = 1`,\n\t\t\t\"/bad1.js\":       `import x from \"foo\"; x++`,\n\t\t\t\"/bad2.js\":       `import x from \"foo\"; ([x] = 1)`,\n\t\t\t\"/bad3.js\":       `import x from \"foo\"; ({x} = 1)`,\n\t\t\t\"/bad4.js\":       `import x from \"foo\"; ({y: x} = 1)`,\n\t\t\t\"/bad5.js\":       `import {x} from \"foo\"; x++`,\n\t\t\t\"/bad6.js\":       `import * as x from \"foo\"; x++`,\n\t\t\t\"/uncaught7.js\":  `import * as x from \"foo\"; x.y = 1`,\n\t\t\t\"/uncaught8.js\":  `import * as x from \"foo\"; x[y] = 1`,\n\t\t\t\"/uncaught9.js\":  `import * as x from \"foo\"; x['y'] = 1`,\n\t\t\t\"/uncaught10.js\": `import * as x from \"foo\"; x['y z'] = 1`,\n\t\t\t\"/bad11.js\":      `import x from \"foo\"; delete x`,\n\t\t\t\"/bad12.js\":      `import {x} from \"foo\"; delete x`,\n\t\t\t\"/uncaught13.js\": `import * as x from \"foo\"; delete x.y`,\n\t\t\t\"/uncaught14.js\": `import * as x from \"foo\"; delete x['y']`,\n\t\t\t\"/uncaught15.js\": `import * as x from \"foo\"; delete x[y]`,\n\n\t\t\t\"/good0.js\": `import x from \"foo\"; ({y = x} = 1)`,\n\t\t\t\"/good1.js\": `import x from \"foo\"; ({[x]: y} = 1)`,\n\t\t\t\"/good2.js\": `import x from \"foo\"; x.y = 1`,\n\t\t\t\"/good3.js\": `import x from \"foo\"; x[y] = 1`,\n\t\t\t\"/good4.js\": `import x from \"foo\"; x['y'] = 1`,\n\t\t\t\"/good5.js\": `import x from \"foo\"; x['y z'] = 1`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/bad0.js\",\n\t\t\t\"/bad1.js\",\n\t\t\t\"/bad2.js\",\n\t\t\t\"/bad3.js\",\n\t\t\t\"/bad4.js\",\n\t\t\t\"/bad5.js\",\n\t\t\t\"/bad6.js\",\n\t\t\t\"/uncaught7.js\",\n\t\t\t\"/uncaught8.js\",\n\t\t\t\"/uncaught9.js\",\n\t\t\t\"/uncaught10.js\",\n\t\t\t\"/bad11.js\",\n\t\t\t\"/bad12.js\",\n\t\t\t\"/uncaught13.js\",\n\t\t\t\"/uncaught14.js\",\n\t\t\t\"/uncaught15.js\",\n\t\t\t\"/good0.js\",\n\t\t\t\"/good1.js\",\n\t\t\t\"/good2.js\",\n\t\t\t\"/good3.js\",\n\t\t\t\"/good4.js\",\n\t\t\t\"/good5.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `bad0.js: WARNING: This assignment will throw because \"x\" is an import\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setX\") and then import and call that function here instead.\nbad1.js: WARNING: This assignment will throw because \"x\" is an import\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setX\") and then import and call that function here instead.\nbad11.js: ERROR: Delete of a bare identifier cannot be used in an ECMAScript module\nbad11.js: NOTE: This file is considered to be an ECMAScript module because of the \"import\" keyword here:\nbad12.js: ERROR: Delete of a bare identifier cannot be used in an ECMAScript module\nbad12.js: NOTE: This file is considered to be an ECMAScript module because of the \"import\" keyword here:\nbad2.js: WARNING: This assignment will throw because \"x\" is an import\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setX\") and then import and call that function here instead.\nbad3.js: WARNING: This assignment will throw because \"x\" is an import\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setX\") and then import and call that function here instead.\nbad4.js: WARNING: This assignment will throw because \"x\" is an import\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setX\") and then import and call that function here instead.\nbad5.js: WARNING: This assignment will throw because \"x\" is an import\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setX\") and then import and call that function here instead.\nbad6.js: WARNING: This assignment will throw because \"x\" is an import\nNOTE: Imports are immutable in JavaScript. To modify the value of this import, you must export a setter function in the imported file (e.g. \"setX\") and then import and call that function here instead.\n`,\n\t})\n}\n\nfunc TestMinifyArguments(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction a(x = arguments) {\n\t\t\t\t\tlet arguments\n\t\t\t\t}\n\t\t\t\tfunction b(x = arguments) {\n\t\t\t\t\tlet arguments\n\t\t\t\t}\n\t\t\t\tfunction c(x = arguments) {\n\t\t\t\t\tlet arguments\n\t\t\t\t}\n\t\t\t\ta()\n\t\t\t\tb()\n\t\t\t\tc()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t\tOutputFormat:      config.FormatIIFE,\n\t\t},\n\t})\n}\n\nfunc TestWarningsInsideNodeModules(t *testing.T) {\n\tdefault_suite.expectBundledUnix(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"./dup-case.js\";        import \"./node_modules/dup-case.js\";        import \"@plugin/dup-case.js\"\n\t\t\t\timport \"./not-in.js\";          import \"./node_modules/not-in.js\";          import \"@plugin/not-in.js\"\n\t\t\t\timport \"./not-instanceof.js\";  import \"./node_modules/not-instanceof.js\";  import \"@plugin/not-instanceof.js\"\n\t\t\t\timport \"./return-asi.js\";      import \"./node_modules/return-asi.js\";      import \"@plugin/return-asi.js\"\n\t\t\t\timport \"./bad-typeof.js\";      import \"./node_modules/bad-typeof.js\";      import \"@plugin/bad-typeof.js\"\n\t\t\t\timport \"./equals-neg-zero.js\"; import \"./node_modules/equals-neg-zero.js\"; import \"@plugin/equals-neg-zero.js\"\n\t\t\t\timport \"./equals-nan.js\";      import \"./node_modules/equals-nan.js\";      import \"@plugin/equals-nan.js\"\n\t\t\t\timport \"./equals-object.js\";   import \"./node_modules/equals-object.js\";   import \"@plugin/equals-object.js\"\n\t\t\t\timport \"./write-getter.js\";    import \"./node_modules/write-getter.js\";    import \"@plugin/write-getter.js\"\n\t\t\t\timport \"./read-setter.js\";     import \"./node_modules/read-setter.js\";     import \"@plugin/read-setter.js\"\n\t\t\t\timport \"./delete-super.js\";    import \"./node_modules/delete-super.js\";    import \"@plugin/delete-super.js\"\n\t\t\t`,\n\n\t\t\t\"/dup-case.js\":                         \"switch (x) { case 0: case 0: }\",\n\t\t\t\"/node_modules/dup-case.js\":            \"switch (x) { case 0: case 0: }\",\n\t\t\t\"/plugin-dir/node_modules/dup-case.js\": \"switch (x) { case 0: case 0: }\",\n\n\t\t\t\"/not-in.js\":                         \"!a in b\",\n\t\t\t\"/node_modules/not-in.js\":            \"!a in b\",\n\t\t\t\"/plugin-dir/node_modules/not-in.js\": \"!a in b\",\n\n\t\t\t\"/not-instanceof.js\":                         \"!a instanceof b\",\n\t\t\t\"/node_modules/not-instanceof.js\":            \"!a instanceof b\",\n\t\t\t\"/plugin-dir/node_modules/not-instanceof.js\": \"!a instanceof b\",\n\n\t\t\t\"/return-asi.js\":                         \"return\\n123\",\n\t\t\t\"/node_modules/return-asi.js\":            \"return\\n123\",\n\t\t\t\"/plugin-dir/node_modules/return-asi.js\": \"return\\n123\",\n\n\t\t\t\"/bad-typeof.js\":                         \"typeof x == 'null'\",\n\t\t\t\"/node_modules/bad-typeof.js\":            \"typeof x == 'null'\",\n\t\t\t\"/plugin-dir/node_modules/bad-typeof.js\": \"typeof x == 'null'\",\n\n\t\t\t\"/equals-neg-zero.js\":                         \"x === -0\",\n\t\t\t\"/node_modules/equals-neg-zero.js\":            \"x === -0\",\n\t\t\t\"/plugin-dir/node_modules/equals-neg-zero.js\": \"x === -0\",\n\n\t\t\t\"/equals-nan.js\":                         \"x === NaN\",\n\t\t\t\"/node_modules/equals-nan.js\":            \"x === NaN\",\n\t\t\t\"/plugin-dir/node_modules/equals-nan.js\": \"x === NaN\",\n\n\t\t\t\"/equals-object.js\":                         \"x === []\",\n\t\t\t\"/node_modules/equals-object.js\":            \"x === []\",\n\t\t\t\"/plugin-dir/node_modules/equals-object.js\": \"x === []\",\n\n\t\t\t\"/write-getter.js\":                         \"class Foo { get #foo() {} foo() { this.#foo = 123 } }\",\n\t\t\t\"/node_modules/write-getter.js\":            \"class Foo { get #foo() {} foo() { this.#foo = 123 } }\",\n\t\t\t\"/plugin-dir/node_modules/write-getter.js\": \"class Foo { get #foo() {} foo() { this.#foo = 123 } }\",\n\n\t\t\t\"/read-setter.js\":                         \"class Foo { set #foo(x) {} foo() { return this.#foo } }\",\n\t\t\t\"/node_modules/read-setter.js\":            \"class Foo { set #foo(x) {} foo() { return this.#foo } }\",\n\t\t\t\"/plugin-dir/node_modules/read-setter.js\": \"class Foo { set #foo(x) {} foo() { return this.#foo } }\",\n\n\t\t\t\"/delete-super.js\":                         \"class Foo extends Bar { foo() { delete super.foo } }\",\n\t\t\t\"/node_modules/delete-super.js\":            \"class Foo extends Bar { foo() { delete super.foo } }\",\n\t\t\t\"/plugin-dir/node_modules/delete-super.js\": \"class Foo extends Bar { foo() { delete super.foo } }\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlugins: []config.Plugin{{\n\t\t\t\tOnResolve: []config.OnResolve{\n\t\t\t\t\t{\n\t\t\t\t\t\tFilter: regexp.MustCompile(\"^@plugin/\"),\n\t\t\t\t\t\tCallback: func(args config.OnResolveArgs) config.OnResolveResult {\n\t\t\t\t\t\t\treturn config.OnResolveResult{\n\t\t\t\t\t\t\t\tPath: logger.Path{\n\t\t\t\t\t\t\t\t\tText:      strings.Replace(args.Path, \"@plugin/\", \"/plugin-dir/node_modules/\", 1),\n\t\t\t\t\t\t\t\t\tNamespace: \"file\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}},\n\t\t},\n\t\texpectedScanLog: `bad-typeof.js: WARNING: The \"typeof\" operator will never evaluate to \"null\"\nNOTE: The expression \"typeof x\" actually evaluates to \"object\" in JavaScript, not \"null\". You need to use \"x === null\" to test for null.\ndelete-super.js: WARNING: Attempting to delete a property of \"super\" will throw a ReferenceError\ndup-case.js: WARNING: This case clause will never be evaluated because it duplicates an earlier case clause\ndup-case.js: NOTE: The earlier case clause is here:\nequals-nan.js: WARNING: Comparison with NaN using the \"===\" operator here is always false\nNOTE: Floating-point equality is defined such that NaN is never equal to anything, so \"x === NaN\" always returns false. You need to use \"Number.isNaN(x)\" instead to test for NaN.\nequals-neg-zero.js: WARNING: Comparison with -0 using the \"===\" operator will also match 0\nNOTE: Floating-point equality is defined such that 0 and -0 are equal, so \"x === -0\" returns true for both 0 and -0. You need to use \"Object.is(x, -0)\" instead to test for -0.\nequals-object.js: WARNING: Comparison using the \"===\" operator here is always false\nNOTE: Equality with a new object is always false in JavaScript because the equality operator tests object identity. You need to write code to compare the contents of the object instead. For example, use \"Array.isArray(x) && x.length === 0\" instead of \"x === []\" to test for an empty array.\nnot-in.js: WARNING: Suspicious use of the \"!\" operator inside the \"in\" operator\nNOTE: The code \"!x in y\" is parsed as \"(!x) in y\". You need to insert parentheses to get \"!(x in y)\" instead.\nnot-instanceof.js: WARNING: Suspicious use of the \"!\" operator inside the \"instanceof\" operator\nNOTE: The code \"!x instanceof y\" is parsed as \"(!x) instanceof y\". You need to insert parentheses to get \"!(x instanceof y)\" instead.\nread-setter.js: WARNING: Reading from setter-only property \"#foo\" will throw\nreturn-asi.js: WARNING: The following expression is not returned because of an automatically-inserted semicolon\nwrite-getter.js: WARNING: Writing to getter-only property \"#foo\" will throw\n`,\n\t})\n}\n\nfunc TestRequireResolve(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(require.resolve)\n\t\t\t\tconsole.log(require.resolve())\n\t\t\t\tconsole.log(require.resolve(foo))\n\t\t\t\tconsole.log(require.resolve('a', 'b'))\n\t\t\t\tconsole.log(require.resolve('./present-file'))\n\t\t\t\tconsole.log(require.resolve('./missing-file'))\n\t\t\t\tconsole.log(require.resolve('./external-file'))\n\t\t\t\tconsole.log(require.resolve('missing-pkg'))\n\t\t\t\tconsole.log(require.resolve('external-pkg'))\n\t\t\t\tconsole.log(require.resolve('@scope/missing-pkg'))\n\t\t\t\tconsole.log(require.resolve('@scope/external-pkg'))\n\t\t\t\ttry {\n\t\t\t\t\tconsole.log(require.resolve('inside-try'))\n\t\t\t\t} catch (e) {\n\t\t\t\t}\n\t\t\t\tif (false) {\n\t\t\t\t\tconsole.log(require.resolve('dead-code'))\n\t\t\t\t}\n\t\t\t\tconsole.log(false ? require.resolve('dead-if') : 0)\n\t\t\t\tconsole.log(true ? 0 : require.resolve('dead-if'))\n\t\t\t\tconsole.log(false && require.resolve('dead-and'))\n\t\t\t\tconsole.log(true || require.resolve('dead-or'))\n\t\t\t\tconsole.log(true ?? require.resolve('dead-nullish'))\n\t\t\t`,\n\t\t\t\"/present-file.js\": ``,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tPlatform:      config.PlatformNode,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPostResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"/external-file\": true,\n\t\t\t\t}},\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"external-pkg\":        true,\n\t\t\t\t\t\"@scope/external-pkg\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `entry.js: WARNING: \"./present-file\" should be marked as external for use with \"require.resolve\"\nentry.js: WARNING: \"./missing-file\" should be marked as external for use with \"require.resolve\"\nentry.js: WARNING: \"missing-pkg\" should be marked as external for use with \"require.resolve\"\nentry.js: WARNING: \"@scope/missing-pkg\" should be marked as external for use with \"require.resolve\"\n`,\n\t})\n}\n\nfunc TestInjectMissing(t *testing.T) {\n\tdefault_suite.expectBundledUnix(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": ``,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tInjectPaths: []string{\n\t\t\t\t\"/inject.js\",\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: \"ERROR: Could not resolve \\\"/inject.js\\\"\\n\",\n\t})\n\n\tdefault_suite.expectBundledWindows(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"C:\\\\entry.js\": ``,\n\t\t},\n\t\tentryPaths: []string{\"C:\\\\entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"C:\\\\out.js\",\n\t\t\tInjectPaths: []string{\n\t\t\t\t\"C:\\\\inject.js\",\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: \"ERROR: Could not resolve \\\"C:\\\\\\\\inject.js\\\"\\n\",\n\t})\n}\n\n// Duplicates are allowed, and should only be injected once\nfunc TestInjectDuplicate(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\":  ``,\n\t\t\t\"/inject.js\": `console.log('injected')`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tInjectPaths: []string{\n\t\t\t\t\"/inject.js\",\n\t\t\t\t\"/inject.js\",\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestInject(t *testing.T) {\n\tdefines := config.ProcessDefines([]config.DefineData{\n\t\t{\n\t\t\tKeyParts: []string{\"chain\", \"prop\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tParts: []string{\"replace\"},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"obj\", \"defined\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: &js_ast.EString{Value: helpers.StringToUTF16(\"defined\")},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"injectedAndDefined\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: &js_ast.EString{Value: helpers.StringToUTF16(\"should be used\")},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"injected\", \"and\", \"defined\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: &js_ast.EString{Value: helpers.StringToUTF16(\"should be used\")},\n\t\t\t},\n\t\t},\n\t})\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tlet sideEffects = console.log('this should be renamed')\n\t\t\t\tlet collide = 123\n\t\t\t\tconsole.log(obj.prop)\n\t\t\t\tconsole.log(obj.defined)\n\t\t\t\tconsole.log(injectedAndDefined)\n\t\t\t\tconsole.log(injected.and.defined)\n\t\t\t\tconsole.log(chain.prop.test)\n\t\t\t\tconsole.log(chain2.prop2.test)\n\t\t\t\tconsole.log(collide)\n\t\t\t\tconsole.log(re_export)\n\t\t\t\tconsole.log(re.export)\n\t\t\t`,\n\t\t\t\"/inject.js\": `\n\t\t\t\texport let obj = {}\n\t\t\t\texport let sideEffects = console.log('side effects')\n\t\t\t\texport let noSideEffects = /* @__PURE__ */ console.log('side effects')\n\t\t\t\texport let injectedAndDefined = 'should not be used'\n\t\t\t\tlet injected_and_defined = 'should not be used'\n\t\t\t\texport { injected_and_defined as 'injected.and.defined' }\n\t\t\t`,\n\t\t\t\"/node_modules/unused/index.js\": `\n\t\t\t\tconsole.log('This is unused but still has side effects')\n\t\t\t`,\n\t\t\t\"/node_modules/sideEffects-false/index.js\": `\n\t\t\t\tconsole.log('This is unused and has no side effects')\n\t\t\t`,\n\t\t\t\"/node_modules/sideEffects-false/package.json\": `{\n\t\t\t\t\"sideEffects\": false\n\t\t\t}`,\n\t\t\t\"/replacement.js\": `\n\t\t\t\texport let replace = {\n\t\t\t\t\ttest() {}\n\t\t\t\t}\n\t\t\t\tlet replace2 = {\n\t\t\t\t\ttest() {}\n\t\t\t\t}\n\t\t\t\texport { replace2 as 'chain2.prop2' }\n\t\t\t`,\n\t\t\t\"/collision.js\": `\n\t\t\t\texport let collide = 123\n\t\t\t`,\n\t\t\t\"/re-export.js\": `\n\t\t\t\texport {re_export} from 'external-pkg'\n\t\t\t\texport {'re.export'} from 'external-pkg2'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tDefines:       &defines,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tInjectPaths: []string{\n\t\t\t\t\"/inject.js\",\n\t\t\t\t\"/node_modules/unused/index.js\",\n\t\t\t\t\"/node_modules/sideEffects-false/index.js\",\n\t\t\t\t\"/replacement.js\",\n\t\t\t\t\"/collision.js\",\n\t\t\t\t\"/re-export.js\",\n\t\t\t},\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"external-pkg\":  true,\n\t\t\t\t\t\"external-pkg2\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestInjectNoBundle(t *testing.T) {\n\tdefines := config.ProcessDefines([]config.DefineData{\n\t\t{\n\t\t\tKeyParts: []string{\"chain\", \"prop\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tParts: []string{\"replace\"},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"obj\", \"defined\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: &js_ast.EString{Value: helpers.StringToUTF16(\"defined\")},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"injectedAndDefined\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: &js_ast.EString{Value: helpers.StringToUTF16(\"should be used\")},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"injected\", \"and\", \"defined\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: &js_ast.EString{Value: helpers.StringToUTF16(\"should be used\")},\n\t\t\t},\n\t\t},\n\t})\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tlet sideEffects = console.log('side effects')\n\t\t\t\tlet collide = 123\n\t\t\t\tconsole.log(obj.prop)\n\t\t\t\tconsole.log(obj.defined)\n\t\t\t\tconsole.log(injectedAndDefined)\n\t\t\t\tconsole.log(injected.and.defined)\n\t\t\t\tconsole.log(chain.prop.test)\n\t\t\t\tconsole.log(chain2.prop2.test)\n\t\t\t\tconsole.log(collide)\n\t\t\t\tconsole.log(re_export)\n\t\t\t\tconsole.log(reexpo.rt)\n\t\t\t`,\n\t\t\t\"/inject.js\": `\n\t\t\t\texport let obj = {}\n\t\t\t\texport let sideEffects = console.log('this should be renamed')\n\t\t\t\texport let noSideEffects = /* @__PURE__ */ console.log('side effects')\n\t\t\t\texport let injectedAndDefined = 'should not be used'\n\t\t\t\tlet injected_and_defined = 'should not be used'\n\t\t\t\texport { injected_and_defined as 'injected.and.defined' }\n\t\t\t`,\n\t\t\t\"/node_modules/unused/index.js\": `\n\t\t\t\tconsole.log('This is unused but still has side effects')\n\t\t\t`,\n\t\t\t\"/node_modules/sideEffects-false/index.js\": `\n\t\t\t\tconsole.log('This is unused and has no side effects')\n\t\t\t`,\n\t\t\t\"/node_modules/sideEffects-false/package.json\": `{\n\t\t\t\t\"sideEffects\": false\n\t\t\t}`,\n\t\t\t\"/replacement.js\": `\n\t\t\t\texport let replace = {\n\t\t\t\t\ttest() {}\n\t\t\t\t}\n\t\t\t\tlet replaceDot = {\n\t\t\t\t\ttest() {}\n\t\t\t\t}\n\t\t\t\texport { replaceDot as 'chain2.prop2' }\n\t\t\t`,\n\t\t\t\"/collision.js\": `\n\t\t\t\texport let collide = 123\n\t\t\t`,\n\t\t\t\"/re-export.js\": `\n\t\t\t\texport {re_export} from 'external-pkg'\n\t\t\t\texport {'reexpo.rt'} from 'external-pkg2'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tTreeShaking:   true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tDefines:       &defines,\n\t\t\tInjectPaths: []string{\n\t\t\t\t\"/inject.js\",\n\t\t\t\t\"/node_modules/unused/index.js\",\n\t\t\t\t\"/node_modules/sideEffects-false/index.js\",\n\t\t\t\t\"/replacement.js\",\n\t\t\t\t\"/collision.js\",\n\t\t\t\t\"/re-export.js\",\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestInjectJSX(t *testing.T) {\n\tdefines := config.ProcessDefines([]config.DefineData{\n\t\t{\n\t\t\tKeyParts: []string{\"React\", \"createElement\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tParts: []string{\"el\"},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"React\", \"Fragment\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tParts: []string{\"frag\"},\n\t\t\t},\n\t\t},\n\t})\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\tconsole.log(<><div/></>)\n\t\t\t`,\n\t\t\t\"/inject.js\": `\n\t\t\t\texport function el() {}\n\t\t\t\texport function frag() {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tDefines:       &defines,\n\t\t\tInjectPaths: []string{\n\t\t\t\t\"/inject.js\",\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestInjectJSXDotNames(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\tconsole.log(<><div/></>)\n\t\t\t`,\n\t\t\t\"/inject.js\": `\n\t\t\t\tfunction el() {}\n\t\t\t\tfunction frag() {}\n\t\t\t\texport {\n\t\t\t\t\tel as 'React.createElement',\n\t\t\t\t\tfrag as 'React.Fragment',\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tInjectPaths: []string{\n\t\t\t\t\"/inject.js\",\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestInjectImportTS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tconsole.log('here')\n\t\t\t`,\n\t\t\t\"/inject.js\": `\n\t\t\t\t// Unused imports are automatically removed in TypeScript files (this\n\t\t\t\t// is a mis-feature of the TypeScript language). However, injected\n\t\t\t\t// imports are an esbuild feature so we get to decide what the\n\t\t\t\t// semantics are. We do not want injected imports to disappear unless\n\t\t\t\t// they have been explicitly marked as having no side effects.\n\t\t\t\tconsole.log('must be present')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tInjectPaths: []string{\n\t\t\t\t\"/inject.js\",\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestInjectImportOrder(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport 'third'\n\t\t\t\tconsole.log('third')\n\t\t\t`,\n\t\t\t\"/inject-1.js\": `\n\t\t\t\timport 'first'\n\t\t\t\tconsole.log('first')\n\t\t\t`,\n\t\t\t\"/inject-2.js\": `\n\t\t\t\timport 'second'\n\t\t\t\tconsole.log('second')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tInjectPaths: []string{\n\t\t\t\t\"/inject-1.js\",\n\t\t\t\t\"/inject-2.js\",\n\t\t\t},\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"first\":  true,\n\t\t\t\t\t\"second\": true,\n\t\t\t\t\t\"third\":  true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestInjectAssign(t *testing.T) {\n\tdefines := config.ProcessDefines([]config.DefineData{{\n\t\tKeyParts:   []string{\"defined\"},\n\t\tDefineExpr: &config.DefineExpr{Parts: []string{\"some\", \"define\"}},\n\t}})\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\ttest = true\n\t\t\t\tfoo.bar = true\n\t\t\t\tdefined = true\n\t\t\t`,\n\t\t\t\"/inject.js\": `\n\t\t\t\texport let test = 0\n\t\t\t\tlet fooBar = 1\n\t\t\t\tlet someDefine = 2\n\t\t\t\texport { fooBar as 'foo.bar' }\n\t\t\t\texport { someDefine as 'some.define' }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tInjectPaths: []string{\n\t\t\t\t\"/inject.js\",\n\t\t\t},\n\t\t\tDefines: &defines,\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Cannot assign to \"test\" because it's an import from an injected file\ninject.js: NOTE: The symbol \"test\" was exported from \"inject.js\" here:\nentry.js: ERROR: Cannot assign to \"foo.bar\" because it's an import from an injected file\ninject.js: NOTE: The symbol \"foo.bar\" was exported from \"inject.js\" here:\nentry.js: ERROR: Cannot assign to \"some.define\" because it's an import from an injected file\ninject.js: NOTE: The symbol \"some.define\" was exported from \"inject.js\" here:\n`,\n\t})\n}\n\nfunc TestInjectWithDefine(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(\n\t\t\t\t\t// define wins over inject\n\t\t\t\t\tboth === 'define',\n\t\t\t\t\tbo.th === 'defi.ne',\n\t\t\t\t\t// define forwards to inject\n\t\t\t\t\tfirst === 'success (identifier)',\n\t\t\t\t\tfir.st === 'success (dot name)',\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/inject.js\": `\n\t\t\t\texport let both = 'inject'\n\t\t\t\texport let first = 'TEST FAILED!'\n\t\t\t\texport let second = 'success (identifier)'\n\n\t\t\t\tlet both2 = 'inject'\n\t\t\t\tlet first2 = 'TEST FAILED!'\n\t\t\t\tlet second2 = 'success (dot name)'\n\t\t\t\texport {\n\t\t\t\t\tboth2 as 'bo.th',\n\t\t\t\t\tfirst2 as 'fir.st',\n\t\t\t\t\tsecond2 as 'seco.nd',\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tInjectPaths: []string{\n\t\t\t\t\"/inject.js\",\n\t\t\t},\n\t\t\tDefines: &config.ProcessedDefines{\n\t\t\t\tIdentifierDefines: map[string]config.DefineData{\n\t\t\t\t\t\"both\":  {DefineExpr: &config.DefineExpr{Constant: &js_ast.EString{Value: helpers.StringToUTF16(\"define\")}}},\n\t\t\t\t\t\"first\": {DefineExpr: &config.DefineExpr{Parts: []string{\"second\"}}},\n\t\t\t\t},\n\t\t\t\tDotDefines: map[string][]config.DefineData{\n\t\t\t\t\t\"th\": {{KeyParts: []string{\"bo\", \"th\"}, DefineExpr: &config.DefineExpr{Constant: &js_ast.EString{Value: helpers.StringToUTF16(\"defi.ne\")}}}},\n\t\t\t\t\t\"st\": {{KeyParts: []string{\"fir\", \"st\"}, DefineExpr: &config.DefineExpr{Parts: []string{\"seco\", \"nd\"}}}},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestOutbase(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a/b/c.js\": `\n\t\t\t\tconsole.log('c')\n\t\t\t`,\n\t\t\t\"/a/b/d.js\": `\n\t\t\t\tconsole.log('d')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a/b/c.js\", \"/a/b/d.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tAbsOutputBase: \"/\",\n\t\t},\n\t})\n}\n\nfunc TestAvoidTDZ(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\tstatic foo = new Foo\n\t\t\t\t}\n\t\t\t\tlet foo = Foo.foo\n\t\t\t\tconsole.log(foo)\n\t\t\t\texport class Bar {}\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestAvoidTDZNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\tstatic foo = new Foo\n\t\t\t\t}\n\t\t\t\tlet foo = Foo.foo\n\t\t\t\tconsole.log(foo)\n\t\t\t\texport class Bar {}\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestDefineImportMeta(t *testing.T) {\n\tdefines := config.ProcessDefines([]config.DefineData{\n\t\t{\n\t\t\tKeyParts: []string{\"import\", \"meta\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: &js_ast.ENumber{Value: 1},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"import\", \"meta\", \"foo\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: &js_ast.ENumber{Value: 2},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"import\", \"meta\", \"foo\", \"bar\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: &js_ast.ENumber{Value: 3},\n\t\t\t},\n\t\t},\n\t})\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(\n\t\t\t\t\t// These should be fully substituted\n\t\t\t\t\timport.meta,\n\t\t\t\t\timport.meta.foo,\n\t\t\t\t\timport.meta.foo.bar,\n\n\t\t\t\t\t// Should just substitute \"import.meta.foo\"\n\t\t\t\t\timport.meta.foo.baz,\n\n\t\t\t\t\t// This should not be substituted\n\t\t\t\t\timport.meta.bar,\n\t\t\t\t)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tDefines:       &defines,\n\t\t},\n\t})\n}\n\nfunc TestDefineImportMetaES5(t *testing.T) {\n\tdefines := config.ProcessDefines([]config.DefineData{\n\t\t{\n\t\t\tKeyParts: []string{\"import\", \"meta\", \"x\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: &js_ast.ENumber{Value: 1},\n\t\t\t},\n\t\t},\n\t})\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/replaced.js\": `\n\t\t\t\tconsole.log(import.meta.x)\n\t\t\t`,\n\t\t\t\"/kept.js\": `\n\t\t\t\tconsole.log(import.meta.y)\n\t\t\t`,\n\t\t\t\"/dead-code.js\": `\n\t\t\t\tvar x = () => console.log(import.meta.z)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/replaced.js\",\n\t\t\t\"/kept.js\",\n\t\t\t\"/dead-code.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tDefines:               &defines,\n\t\t\tUnsupportedJSFeatures: compat.ImportMeta,\n\t\t},\n\t\texpectedScanLog: `dead-code.js: WARNING: \"import.meta\" is not available in the configured target environment and will be empty\nkept.js: WARNING: \"import.meta\" is not available in the configured target environment and will be empty\n`,\n\t})\n}\n\nfunc TestInjectImportMeta(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(\n\t\t\t\t\t// These should be fully substituted\n\t\t\t\t\timport.meta,\n\t\t\t\t\timport.meta.foo,\n\t\t\t\t\timport.meta.foo.bar,\n\n\t\t\t\t\t// Should just substitute \"import.meta.foo\"\n\t\t\t\t\timport.meta.foo.baz,\n\n\t\t\t\t\t// This should not be substituted\n\t\t\t\t\timport.meta.bar,\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/inject.js\": `\n\t\t\t\tlet foo = 1\n\t\t\t\tlet bar = 2\n\t\t\t\tlet baz = 3\n\t\t\t\texport {\n\t\t\t\t\tfoo as 'import.meta',\n\t\t\t\t\tbar as 'import.meta.foo',\n\t\t\t\t\tbaz as 'import.meta.foo.bar',\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tInjectPaths:   []string{\"/inject.js\"},\n\t\t},\n\t})\n}\n\nfunc TestDefineThis(t *testing.T) {\n\tdefines := config.ProcessDefines([]config.DefineData{\n\t\t{\n\t\t\tKeyParts: []string{\"this\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: &js_ast.ENumber{Value: 1},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"this\", \"foo\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: &js_ast.ENumber{Value: 2},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"this\", \"foo\", \"bar\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: &js_ast.ENumber{Value: 3},\n\t\t\t},\n\t\t},\n\t})\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tok(\n\t\t\t\t\t// These should be fully substituted\n\t\t\t\t\tthis,\n\t\t\t\t\tthis.foo,\n\t\t\t\t\tthis.foo.bar,\n\n\t\t\t\t\t// Should just substitute \"this.foo\"\n\t\t\t\t\tthis.foo.baz,\n\n\t\t\t\t\t// This should not be substituted\n\t\t\t\t\tthis.bar,\n\t\t\t\t);\n\n\t\t\t\t// This code should be the same as above\n\t\t\t\t(() => {\n\t\t\t\t\tok(\n\t\t\t\t\t\tthis,\n\t\t\t\t\t\tthis.foo,\n\t\t\t\t\t\tthis.foo.bar,\n\t\t\t\t\t\tthis.foo.baz,\n\t\t\t\t\t\tthis.bar,\n\t\t\t\t\t);\n\t\t\t\t})();\n\n\t\t\t\t// Nothing should be substituted in this code\n\t\t\t\t(function() {\n\t\t\t\t\tdoNotSubstitute(\n\t\t\t\t\t\tthis,\n\t\t\t\t\t\tthis.foo,\n\t\t\t\t\t\tthis.foo.bar,\n\t\t\t\t\t\tthis.foo.baz,\n\t\t\t\t\t\tthis.bar,\n\t\t\t\t\t);\n\t\t\t\t})();\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tDefines:       &defines,\n\t\t},\n\t})\n}\n\nfunc TestDefineOptionalChain(t *testing.T) {\n\tdefines := config.ProcessDefines([]config.DefineData{{\n\t\tKeyParts: []string{\"a\", \"b\", \"c\"},\n\t\tDefineExpr: &config.DefineExpr{\n\t\t\tConstant: &js_ast.ENumber{Value: 1},\n\t\t},\n\t}})\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\ta.b.c,\n\t\t\t\t\ta?.b.c,\n\t\t\t\t\ta.b?.c,\n\t\t\t\t], [\n\t\t\t\t\ta['b']['c'],\n\t\t\t\t\ta?.['b']['c'],\n\t\t\t\t\ta['b']?.['c'],\n\t\t\t\t], [\n\t\t\t\t\ta[b][c],\n\t\t\t\t\ta?.[b][c],\n\t\t\t\t\ta[b]?.[c],\n\t\t\t\t])\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tDefines:       &defines,\n\t\t},\n\t})\n}\n\nfunc TestDefineOptionalChainLowered(t *testing.T) {\n\tdefines := config.ProcessDefines([]config.DefineData{{\n\t\tKeyParts: []string{\"a\", \"b\", \"c\"},\n\t\tDefineExpr: &config.DefineExpr{\n\t\t\tConstant: &js_ast.ENumber{Value: 1},\n\t\t},\n\t}})\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\ta.b.c,\n\t\t\t\t\ta?.b.c,\n\t\t\t\t\ta.b?.c,\n\t\t\t\t], [\n\t\t\t\t\ta['b']['c'],\n\t\t\t\t\ta?.['b']['c'],\n\t\t\t\t\ta['b']?.['c'],\n\t\t\t\t], [\n\t\t\t\t\ta[b][c],\n\t\t\t\t\ta?.[b][c],\n\t\t\t\t\ta[b]?.[c],\n\t\t\t\t])\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tDefines:               &defines,\n\t\t\tUnsupportedJSFeatures: compat.OptionalChain,\n\t\t},\n\t})\n}\n\n// See: https://github.com/evanw/esbuild/issues/3551\nfunc TestDefineOptionalChainPanicIssue3551(t *testing.T) {\n\tdefines := config.ProcessDefines([]config.DefineData{\n\t\t{\n\t\t\tKeyParts: []string{\"x\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: &js_ast.ENumber{Value: 1},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"a\", \"b\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: &js_ast.ENumber{Value: 1},\n\t\t\t},\n\t\t},\n\t})\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/id-define.js\": `\n\t\t\t\tx?.y.z;\n\t\t\t\t(x?.y).z;\n\t\t\t\tx?.y[\"z\"];\n\t\t\t\t(x?.y)[\"z\"];\n\t\t\t\tx?.y();\n\t\t\t\t(x?.y)();\n\t\t\t\tx?.y.z();\n\t\t\t\t(x?.y).z();\n\t\t\t\tx?.y[\"z\"]();\n\t\t\t\t(x?.y)[\"z\"]();\n\t\t\t\tdelete x?.y.z;\n\t\t\t\tdelete (x?.y).z;\n\t\t\t\tdelete x?.y[\"z\"];\n\t\t\t\tdelete (x?.y)[\"z\"];\n\t\t\t`,\n\t\t\t\"/dot-define.js\": `\n\t\t\t\ta?.b.c;\n\t\t\t\t(a?.b).c;\n\t\t\t\ta?.b[\"c\"];\n\t\t\t\t(a?.b)[\"c\"];\n\t\t\t\ta?.b();\n\t\t\t\t(a?.b)();\n\t\t\t\ta?.b.c();\n\t\t\t\t(a?.b).c();\n\t\t\t\ta?.b[\"c\"]();\n\t\t\t\t(a?.b)[\"c\"]();\n\t\t\t\tdelete a?.b.c;\n\t\t\t\tdelete (a?.b).c;\n\t\t\t\tdelete a?.b[\"c\"];\n\t\t\t\tdelete (a?.b)[\"c\"];\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/id-define.js\", \"/dot-define.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tDefines:      &defines,\n\t\t},\n\t})\n}\n\n// See: https://github.com/evanw/esbuild/issues/2407\nfunc TestDefineInfiniteLoopIssue2407(t *testing.T) {\n\tdefines := config.ProcessDefines([]config.DefineData{\n\t\t{\n\t\t\tKeyParts: []string{\"a\", \"b\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tParts: []string{\"b\", \"c\"},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"b\", \"c\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tParts: []string{\"c\", \"a\"},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"c\", \"a\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tParts: []string{\"a\", \"b\"},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"x\", \"y\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tParts: []string{\"y\"},\n\t\t\t},\n\t\t},\n\t})\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\ta.b()\n\t\t\t\tx.y()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tDefines:       &defines,\n\t\t},\n\t})\n}\n\nfunc TestDefineAssignWarning(t *testing.T) {\n\tdefines := config.ProcessDefines([]config.DefineData{\n\t\t{\n\t\t\tKeyParts: []string{\"a\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: js_ast.ENullShared,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"b\", \"c\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tConstant: js_ast.ENullShared,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"d\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tParts: []string{\"ident\"},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"e\", \"f\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tParts: []string{\"ident\"},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"g\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tParts: []string{\"dot\", \"chain\"},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKeyParts: []string{\"h\", \"i\"},\n\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\tParts: []string{\"dot\", \"chain\"},\n\t\t\t},\n\t\t},\n\t})\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/read.js\": `\n\t\t\t\tconsole.log(\n\t\t\t\t\t[a, b.c, b['c']],\n\t\t\t\t\t[d, e.f, e['f']],\n\t\t\t\t\t[g, h.i, h['i']],\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/write.js\": `\n\t\t\t\tconsole.log(\n\t\t\t\t\t[a = 0, b.c = 0, b['c'] = 0],\n\t\t\t\t\t[d = 0, e.f = 0, e['f'] = 0],\n\t\t\t\t\t[g = 0, h.i = 0, h['i'] = 0],\n\t\t\t\t)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/read.js\",\n\t\t\t\"/write.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tDefines:      &defines,\n\t\t},\n\t\texpectedScanLog: `write.js: WARNING: Suspicious assignment to defined constant \"a\"\nNOTE: The expression \"a\" has been configured to be replaced with a constant using the \"define\" feature. If this expression is supposed to be a compile-time constant, then it doesn't make sense to assign to it here. Or if this expression is supposed to change at run-time, this \"define\" substitution should be removed.\nwrite.js: WARNING: Suspicious assignment to defined constant \"b.c\"\nNOTE: The expression \"b.c\" has been configured to be replaced with a constant using the \"define\" feature. If this expression is supposed to be a compile-time constant, then it doesn't make sense to assign to it here. Or if this expression is supposed to change at run-time, this \"define\" substitution should be removed.\nwrite.js: WARNING: Suspicious assignment to defined constant \"b['c']\"\nNOTE: The expression \"b['c']\" has been configured to be replaced with a constant using the \"define\" feature. If this expression is supposed to be a compile-time constant, then it doesn't make sense to assign to it here. Or if this expression is supposed to change at run-time, this \"define\" substitution should be removed.\n`,\n\t})\n}\n\nfunc TestKeepNamesAllForms(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/keep.js\": `\n\t\t\t\t// Initializers\n\t\t\t\tfunction fn() {}\n\t\t\t\tfunction foo(fn = function() {}) {}\n\t\t\t\tvar fn = function() {};\n\t\t\t\tvar obj = { \"f n\": function() {} };\n\t\t\t\tclass Foo0 { \"f n\" = function() {} }\n\t\t\t\tclass Foo1 { static \"f n\" = function() {} }\n\t\t\t\tclass Foo2 { accessor \"f n\" = function() {} }\n\t\t\t\tclass Foo3 { static accessor \"f n\" = function() {} }\n\t\t\t\tclass Foo4 { #fn = function() {} }\n\t\t\t\tclass Foo5 { static #fn = function() {} }\n\t\t\t\tclass Foo6 { accessor #fn = function() {} }\n\t\t\t\tclass Foo7 { static accessor #fn = function() {} }\n\n\t\t\t\t// Assignments\n\t\t\t\tfn = function() {};\n\t\t\t\tfn ||= function() {};\n\t\t\t\tfn &&= function() {};\n\t\t\t\tfn ??= function() {};\n\n\t\t\t\t// Destructuring\n\t\t\t\tvar [fn = function() {}] = [];\n\t\t\t\tvar { fn = function() {} } = {};\n\t\t\t\tfor (var [fn = function() {}] = []; ; ) ;\n\t\t\t\tfor (var { fn = function() {} } = {}; ; ) ;\n\t\t\t\tfor (var [fn = function() {}] in obj) ;\n\t\t\t\tfor (var { fn = function() {} } in obj) ;\n\t\t\t\tfor (var [fn = function() {}] of obj) ;\n\t\t\t\tfor (var { fn = function() {} } of obj) ;\n\t\t\t\tfunction foo([fn = function() {}]) {}\n\t\t\t\tfunction foo({ fn = function() {} }) {}\n\t\t\t\t[fn = function() {}] = [];\n\t\t\t\t({ fn = function() {} } = {});\n\t\t\t`,\n\t\t\t\"/do-not-keep.js\": `\n\t\t\t\t// Class methods\n\t\t\t\tclass Foo0 { fn() {} }\n\t\t\t\tclass Foo1 { *fn() {} }\n\t\t\t\tclass Foo2 { get fn() {} }\n\t\t\t\tclass Foo3 { set fn(_) {} }\n\t\t\t\tclass Foo4 { async fn() {} }\n\t\t\t\tclass Foo5 { static fn() {} }\n\t\t\t\tclass Foo6 { static *fn() {} }\n\t\t\t\tclass Foo7 { static get fn() {} }\n\t\t\t\tclass Foo8 { static set fn(_) {} }\n\t\t\t\tclass Foo9 { static async fn() {} }\n\n\t\t\t\t// Class private methods\n\t\t\t\tclass Bar0 { #fn() {} }\n\t\t\t\tclass Bar1 { *#fn() {} }\n\t\t\t\tclass Bar2 { get #fn() {} }\n\t\t\t\tclass Bar3 { set #fn(_) {} }\n\t\t\t\tclass Bar4 { async #fn() {} }\n\t\t\t\tclass Bar5 { static #fn() {} }\n\t\t\t\tclass Bar6 { static *#fn() {} }\n\t\t\t\tclass Bar7 { static get #fn() {} }\n\t\t\t\tclass Bar8 { static set #fn(_) {} }\n\t\t\t\tclass Bar9 { static async #fn(_) {} }\n\n\t\t\t\t// Object methods\n\t\t\t\tconst Baz0 = { fn() {} }\n\t\t\t\tconst Baz1 = { *fn() {} }\n\t\t\t\tconst Baz2 = { get fn() {} }\n\t\t\t\tconst Baz3 = { set fn(_) {} }\n\t\t\t\tconst Baz4 = { async fn() {} }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/keep.js\",\n\t\t\t\"/do-not-keep.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tKeepNames:    true,\n\t\t},\n\t})\n}\n\nfunc TestKeepNamesTreeShaking(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction fnStmtRemove() {}\n\t\t\t\tfunction fnStmtKeep() {}\n\t\t\t\tx = fnStmtKeep\n\n\t\t\t\tlet fnExprRemove = function remove() {}\n\t\t\t\tlet fnExprKeep = function keep() {}\n\t\t\t\tx = fnExprKeep\n\n\t\t\t\tclass clsStmtRemove {}\n\t\t\t\tclass clsStmtKeep {}\n\t\t\t\tnew clsStmtKeep()\n\n\t\t\t\tlet clsExprRemove = class remove {}\n\t\t\t\tlet clsExprKeep = class keep {}\n\t\t\t\tnew clsExprKeep()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tKeepNames:     true,\n\t\t\tMinifySyntax:  true,\n\t\t},\n\t})\n}\n\nfunc TestKeepNamesClassStaticName(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass A { static foo }\n\t\t\t\tclass B { static name }\n\t\t\t\tclass C { static name() {} }\n\t\t\t\tclass D { static get name() {} }\n\t\t\t\tclass E { static set name(x) {} }\n\t\t\t\tclass F { static ['name'] = 0 }\n\n\t\t\t\tlet a = class a { static foo }\n\t\t\t\tlet b = class b { static name }\n\t\t\t\tlet c = class c { static name() {} }\n\t\t\t\tlet d = class d { static get name() {} }\n\t\t\t\tlet e = class e { static set name(x) {} }\n\t\t\t\tlet f = class f { static ['name'] = 0 }\n\n\t\t\t\tlet a2 = class { static foo }\n\t\t\t\tlet b2 = class { static name }\n\t\t\t\tlet c2 = class { static name() {} }\n\t\t\t\tlet d2 = class { static get name() {} }\n\t\t\t\tlet e2 = class { static set name(x) {} }\n\t\t\t\tlet f2 = class { static ['name'] = 0 }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tKeepNames:     true,\n\t\t},\n\t})\n}\n\nfunc TestCharFreqIgnoreComments(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\texport default function(one, two, three, four) {\n\t\t\t\t\treturn 'the argument names must be the same'\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\texport default function(one, two, three, four) {\n\t\t\t\t\treturn 'the argument names must be the same'\n\t\t\t\t}\n\n\t\t\t\t// Some comment text to change the character frequency histogram:\n\t\t\t\t// ________________________________________________________________________________\n\t\t\t\t// FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n\t\t\t\t// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n\t\t\t\t// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII\n\t\t\t\t// LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tAbsOutputDir:      \"/out\",\n\t\t\tMinifyIdentifiers: true,\n\t\t},\n\t})\n}\n\nfunc TestImportRelativeAsPackage(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'some/other/file'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/some/other/file.js\": `\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"some/other/file\"\nNOTE: Use the relative path \"./some/other/file\" to reference the file \"Users/user/project/src/some/other/file.js\". Without the leading \"./\", the path \"some/other/file\" is being interpreted as a package path instead.\n`,\n\t})\n}\n\n// Assigning to a top-level \"const\" that will be transformed into a \"var\" must\n// be an error at compile-time because it won't be an error at run-time. Note\n// that the minifier is allowed to transform nested \"const\" into \"let\" (to\n// reduce code size further) when bundling is active, so nested \"const\" also\n// needs to be an error in this case.\nfunc TestForbidConstAssignWhenBundling(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst x = 1\n\t\t\t\tx = 2\n\t\t\t\tfunction foo() {\n\t\t\t\t\tconst y = 1\n\t\t\t\t\ty = 2\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Cannot assign to \"x\" because it is a constant\nentry.js: NOTE: The symbol \"x\" was declared a constant here:\nentry.js: ERROR: Cannot assign to \"y\" because it is a constant\nentry.js: NOTE: The symbol \"y\" was declared a constant here:\n`,\n\t})\n}\n\n// Assigning to a top-level \"const\" that will be transformed into a \"var\" must\n// be an error at compile-time because it won't be an error at run-time\nfunc TestForbidConstAssignWhenLoweringUsing(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst x = 1\n\t\t\t\tusing x2 = 2\n\t\t\t\tx = 3\n\t\t\t\tfunction foo() {\n\t\t\t\t\tconst y = 1\n\t\t\t\t\tusing y2 = 2\n\t\t\t\t\ty = 3\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.Using,\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Cannot assign to \"x\" because it is a constant\nentry.js: NOTE: The symbol \"x\" was declared a constant here:\nentry.js: WARNING: This assignment will throw because \"y\" is a constant\nentry.js: NOTE: The symbol \"y\" was declared a constant here:\n`,\n\t})\n}\n\nfunc TestConstWithLet(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst a = 1; console.log(a)\n\t\t\t\tif (true) { const b = 2; console.log(b) }\n\t\t\t\tif (true) { const b = 3; unknownFn(b) }\n\t\t\t\tfor (const c = x;;) console.log(c)\n\t\t\t\tfor (const d in x) console.log(d)\n\t\t\t\tfor (const e of x) console.log(e)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMinifySyntax:  true,\n\t\t},\n\t})\n}\n\nfunc TestConstWithLetNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst a = 1; console.log(a)\n\t\t\t\tif (true) { const b = 2; console.log(b) }\n\t\t\t\tif (true) { const b = 3; unknownFn(b) }\n\t\t\t\tfor (const c = x;;) console.log(c)\n\t\t\t\tfor (const d in x) console.log(d)\n\t\t\t\tfor (const e of x) console.log(e)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMinifySyntax:  true,\n\t\t},\n\t})\n}\n\nfunc TestConstWithLetNoMangle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst a = 1; console.log(a)\n\t\t\t\tif (true) { const b = 2; console.log(b) }\n\t\t\t\tfor (const c = x;;) console.log(c)\n\t\t\t\tfor (const d in x) console.log(d)\n\t\t\t\tfor (const e of x) console.log(e)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestRequireMainCacheCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log('is main:', require.main === module)\n\t\t\t\tconsole.log(require('./is-main'))\n\t\t\t\tconsole.log('cache:', require.cache);\n\t\t\t`,\n\t\t\t\"/is-main.js\": `\n\t\t\t\tmodule.exports = require.main === module\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tPlatform:      config.PlatformNode,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t},\n\t})\n}\n\nfunc TestExternalES6ConvertedToCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\trequire('./a')\n\t\t\t\trequire('./b')\n\t\t\t\trequire('./c')\n\t\t\t\trequire('./d')\n\t\t\t\trequire('./e')\n\t\t\t`,\n\t\t\t\"/a.js\": `\n\t\t\t\timport * as ns from 'x'\n\t\t\t\texport {ns}\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport * as ns from 'x' // \"ns\" must be renamed to avoid collisions with \"a.js\"\n\t\t\t\texport {ns}\n\t\t\t`,\n\t\t\t\"/c.js\": `\n\t\t\t\texport * as ns from 'x'\n\t\t\t`,\n\t\t\t\"/d.js\": `\n\t\t\t\texport {ns} from 'x'\n\t\t\t`,\n\t\t\t\"/e.js\": `\n\t\t\t\texport * from 'x'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"x\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestCallImportNamespaceWarning(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/js.js\": `\n\t\t\t\timport * as a from \"a\"\n\t\t\t\timport {b} from \"b\"\n\t\t\t\timport c from \"c\"\n\t\t\t\ta()\n\t\t\t\tb()\n\t\t\t\tc()\n\t\t\t\tnew a()\n\t\t\t\tnew b()\n\t\t\t\tnew c()\n\t\t\t`,\n\t\t\t\"/ts.ts\": `\n\t\t\t\timport * as a from \"a\"\n\t\t\t\timport {b} from \"b\"\n\t\t\t\timport c from \"c\"\n\t\t\t\ta()\n\t\t\t\tb()\n\t\t\t\tc()\n\t\t\t\tnew a()\n\t\t\t\tnew b()\n\t\t\t\tnew c()\n\t\t\t`,\n\t\t\t\"/jsx-components.jsx\": `\n\t\t\t\timport * as A from \"a\"\n\t\t\t\timport {B} from \"b\"\n\t\t\t\timport C from \"c\"\n\t\t\t\t<A/>;\n\t\t\t\t<B/>;\n\t\t\t\t<C/>;\n\t\t\t`,\n\t\t\t\"/jsx-a.jsx\": `\n\t\t\t\t// @jsx a\n\t\t\t\timport * as a from \"a\"\n\t\t\t\t<div/>\n\t\t\t`,\n\t\t\t\"/jsx-b.jsx\": `\n\t\t\t\t// @jsx b\n\t\t\t\timport {b} from \"b\"\n\t\t\t\t<div/>\n\t\t\t`,\n\t\t\t\"/jsx-c.jsx\": `\n\t\t\t\t// @jsx c\n\t\t\t\timport c from \"c\"\n\t\t\t\t<div/>\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/js.js\",\n\t\t\t\"/ts.ts\",\n\t\t\t\"/jsx-components.jsx\",\n\t\t\t\"/jsx-a.jsx\",\n\t\t\t\"/jsx-b.jsx\",\n\t\t\t\"/jsx-c.jsx\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeConvertFormat,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t},\n\t\texpectedScanLog: `js.js: WARNING: Calling \"a\" will crash at run-time because it's an import namespace object, not a function\njs.js: NOTE: Consider changing \"a\" to a default import instead:\njs.js: WARNING: Constructing \"a\" will crash at run-time because it's an import namespace object, not a constructor\njs.js: NOTE: Consider changing \"a\" to a default import instead:\njsx-a.jsx: WARNING: Calling \"a\" will crash at run-time because it's an import namespace object, not a function\njsx-a.jsx: NOTE: Consider changing \"a\" to a default import instead:\njsx-components.jsx: WARNING: Using \"A\" in a JSX expression will crash at run-time because it's an import namespace object, not a component\njsx-components.jsx: NOTE: Consider changing \"A\" to a default import instead:\nts.ts: WARNING: Calling \"a\" will crash at run-time because it's an import namespace object, not a function\nts.ts: NOTE: Consider changing \"a\" to a default import instead:\nNOTE: Make sure to enable TypeScript's \"esModuleInterop\" setting so that TypeScript's type checker generates an error when you try to do this. You can read more about this setting here: https://www.typescriptlang.org/tsconfig#esModuleInterop\nts.ts: WARNING: Constructing \"a\" will crash at run-time because it's an import namespace object, not a constructor\nts.ts: NOTE: Consider changing \"a\" to a default import instead:\nNOTE: Make sure to enable TypeScript's \"esModuleInterop\" setting so that TypeScript's type checker generates an error when you try to do this. You can read more about this setting here: https://www.typescriptlang.org/tsconfig#esModuleInterop\n`,\n\t})\n}\n\nfunc TestJSXThisValueCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/factory.jsx\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\t<x />,\n\t\t\t\t\t/* @__PURE__ */ this('x', null),\n\t\t\t\t])\n\t\t\t\tf = function() {\n\t\t\t\t\tconsole.log([\n\t\t\t\t\t\t<y />,\n\t\t\t\t\t\t/* @__PURE__ */ this('y', null),\n\t\t\t\t\t])\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/fragment.jsx\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\t<>x</>,\n\t\t\t\t\t/* @__PURE__ */ this(this, null, 'x'),\n\t\t\t\t]),\n\t\t\t\tf = function() {\n\t\t\t\t\tconsole.log([\n\t\t\t\t\t\t<>y</>,\n\t\t\t\t\t\t/* @__PURE__ */ this(this, null, 'y'),\n\t\t\t\t\t])\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/factory.jsx\", \"/fragment.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tFactory:  config.DefineExpr{Parts: []string{\"this\"}},\n\t\t\t\tFragment: config.DefineExpr{Parts: []string{\"this\"}},\n\t\t\t},\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestJSXThisValueESM(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/factory.jsx\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\t<x />,\n\t\t\t\t\t/* @__PURE__ */ this('x', null),\n\t\t\t\t])\n\t\t\t\tf = function() {\n\t\t\t\t\tconsole.log([\n\t\t\t\t\t\t<y />,\n\t\t\t\t\t\t/* @__PURE__ */ this('y', null),\n\t\t\t\t\t])\n\t\t\t\t}\n\t\t\t\texport {}\n\t\t\t`,\n\t\t\t\"/fragment.jsx\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\t<>x</>,\n\t\t\t\t\t/* @__PURE__ */ this(this, null, 'x'),\n\t\t\t\t]),\n\t\t\t\tf = function() {\n\t\t\t\t\tconsole.log([\n\t\t\t\t\t\t<>y</>,\n\t\t\t\t\t\t/* @__PURE__ */ this(this, null, 'y'),\n\t\t\t\t\t])\n\t\t\t\t}\n\t\t\t\texport {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/factory.jsx\", \"/fragment.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tFactory:  config.DefineExpr{Parts: []string{\"this\"}},\n\t\t\t\tFragment: config.DefineExpr{Parts: []string{\"this\"}},\n\t\t\t},\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\tdebugLogs: true,\n\t\texpectedScanLog: `factory.jsx: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nfactory.jsx: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nfragment.jsx: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nfragment.jsx: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n`,\n\t})\n}\n\nfunc TestJSXThisPropertyCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/factory.jsx\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\t<x />,\n\t\t\t\t\t/* @__PURE__ */ this.factory('x', null),\n\t\t\t\t])\n\t\t\t\tf = function() {\n\t\t\t\t\tconsole.log([\n\t\t\t\t\t\t<y />,\n\t\t\t\t\t\t/* @__PURE__ */ this.factory('y', null),\n\t\t\t\t\t])\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/fragment.jsx\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\t<>x</>,\n\t\t\t\t\t/* @__PURE__ */ this.factory(this.fragment, null, 'x'),\n\t\t\t\t]),\n\t\t\t\tf = function() {\n\t\t\t\t\tconsole.log([\n\t\t\t\t\t\t<>y</>,\n\t\t\t\t\t\t/* @__PURE__ */ this.factory(this.fragment, null, 'y'),\n\t\t\t\t\t])\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/factory.jsx\", \"/fragment.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tFactory:  config.DefineExpr{Parts: []string{\"this\", \"factory\"}},\n\t\t\t\tFragment: config.DefineExpr{Parts: []string{\"this\", \"fragment\"}},\n\t\t\t},\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestJSXThisPropertyESM(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/factory.jsx\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\t<x />,\n\t\t\t\t\t/* @__PURE__ */ this.factory('x', null),\n\t\t\t\t])\n\t\t\t\tf = function() {\n\t\t\t\t\tconsole.log([\n\t\t\t\t\t\t<y />,\n\t\t\t\t\t\t/* @__PURE__ */ this.factory('y', null),\n\t\t\t\t\t])\n\t\t\t\t}\n\t\t\t\texport {}\n\t\t\t`,\n\t\t\t\"/fragment.jsx\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\t<>x</>,\n\t\t\t\t\t/* @__PURE__ */ this.factory(this.fragment, null, 'x'),\n\t\t\t\t]),\n\t\t\t\tf = function() {\n\t\t\t\t\tconsole.log([\n\t\t\t\t\t\t<>y</>,\n\t\t\t\t\t\t/* @__PURE__ */ this.factory(this.fragment, null, 'y'),\n\t\t\t\t\t])\n\t\t\t\t}\n\t\t\t\texport {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/factory.jsx\", \"/fragment.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tFactory:  config.DefineExpr{Parts: []string{\"this\", \"factory\"}},\n\t\t\t\tFragment: config.DefineExpr{Parts: []string{\"this\", \"fragment\"}},\n\t\t\t},\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\tdebugLogs: true,\n\t\texpectedScanLog: `factory.jsx: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nfactory.jsx: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nfragment.jsx: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nfragment.jsx: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n`,\n\t})\n}\n\nfunc TestJSXImportMetaValue(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/factory.jsx\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\t<x />,\n\t\t\t\t\t/* @__PURE__ */ import.meta('x', null),\n\t\t\t\t])\n\t\t\t\tf = function() {\n\t\t\t\t\tconsole.log([\n\t\t\t\t\t\t<y />,\n\t\t\t\t\t\t/* @__PURE__ */ import.meta('y', null),\n\t\t\t\t\t])\n\t\t\t\t}\n\t\t\t\texport {}\n\t\t\t`,\n\t\t\t\"/fragment.jsx\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\t<>x</>,\n\t\t\t\t\t/* @__PURE__ */ import.meta(import.meta, null, 'x'),\n\t\t\t\t]),\n\t\t\t\tf = function() {\n\t\t\t\t\tconsole.log([\n\t\t\t\t\t\t<>y</>,\n\t\t\t\t\t\t/* @__PURE__ */ import.meta(import.meta, null, 'y'),\n\t\t\t\t\t])\n\t\t\t\t}\n\t\t\t\texport {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/factory.jsx\", \"/fragment.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: compat.ImportMeta,\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tFactory:  config.DefineExpr{Parts: []string{\"import\", \"meta\"}},\n\t\t\t\tFragment: config.DefineExpr{Parts: []string{\"import\", \"meta\"}},\n\t\t\t},\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedScanLog: `factory.jsx: WARNING: \"import.meta\" is not available in the configured target environment and will be empty\nfactory.jsx: WARNING: \"import.meta\" is not available in the configured target environment and will be empty\nfragment.jsx: WARNING: \"import.meta\" is not available in the configured target environment and will be empty\nfragment.jsx: WARNING: \"import.meta\" is not available in the configured target environment and will be empty\nfragment.jsx: WARNING: \"import.meta\" is not available in the configured target environment and will be empty\nfragment.jsx: WARNING: \"import.meta\" is not available in the configured target environment and will be empty\n`,\n\t})\n}\n\nfunc TestJSXImportMetaProperty(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/factory.jsx\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\t<x />,\n\t\t\t\t\t/* @__PURE__ */ import.meta.factory('x', null),\n\t\t\t\t])\n\t\t\t\tf = function() {\n\t\t\t\t\tconsole.log([\n\t\t\t\t\t\t<y />,\n\t\t\t\t\t\t/* @__PURE__ */ import.meta.factory('y', null),\n\t\t\t\t\t])\n\t\t\t\t}\n\t\t\t\texport {}\n\t\t\t`,\n\t\t\t\"/fragment.jsx\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\t<>x</>,\n\t\t\t\t\t/* @__PURE__ */ import.meta.factory(import.meta.fragment, null, 'x'),\n\t\t\t\t]),\n\t\t\t\tf = function() {\n\t\t\t\t\tconsole.log([\n\t\t\t\t\t\t<>y</>,\n\t\t\t\t\t\t/* @__PURE__ */ import.meta.factory(import.meta.fragment, null, 'y'),\n\t\t\t\t\t])\n\t\t\t\t}\n\t\t\t\texport {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/factory.jsx\", \"/fragment.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: compat.ImportMeta,\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tFactory:  config.DefineExpr{Parts: []string{\"import\", \"meta\", \"factory\"}},\n\t\t\t\tFragment: config.DefineExpr{Parts: []string{\"import\", \"meta\", \"fragment\"}},\n\t\t\t},\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedScanLog: `factory.jsx: WARNING: \"import.meta\" is not available in the configured target environment and will be empty\nfactory.jsx: WARNING: \"import.meta\" is not available in the configured target environment and will be empty\nfragment.jsx: WARNING: \"import.meta\" is not available in the configured target environment and will be empty\nfragment.jsx: WARNING: \"import.meta\" is not available in the configured target environment and will be empty\nfragment.jsx: WARNING: \"import.meta\" is not available in the configured target environment and will be empty\nfragment.jsx: WARNING: \"import.meta\" is not available in the configured target environment and will be empty\n`,\n\t})\n}\n\nfunc TestBundlingFilesOutsideOfOutbase(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entry.js\": `\n\t\t\t\tconsole.log('test')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputBase: \"/some/nested/directory\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nvar relocateFiles = map[string]string{\n\t\"/top-level.js\": `\n\t\tvar a;\n\t\tfor (var b; 0;);\n\t\tfor (var { c, x: [d] } = {}; 0;);\n\t\tfor (var e of []);\n\t\tfor (var { f, x: [g] } of []);\n\t\tfor (var h in {});\n\t\tfor (var i = 1 in {});\n\t\tfor (var { j, x: [k] } in {});\n\t\tfunction l() {}\n\t`,\n\t\"/nested.js\": `\n\t\tif (true) {\n\t\t\tvar a;\n\t\t\tfor (var b; 0;);\n\t\t\tfor (var { c, x: [d] } = {}; 0;);\n\t\t\tfor (var e of []);\n\t\t\tfor (var { f, x: [g] } of []);\n\t\t\tfor (var h in {});\n\t\t\tfor (var i = 1 in {});\n\t\t\tfor (var { j, x: [k] } in {});\n\t\t\tfunction l() {}\n\t\t}\n\t`,\n\t\"/let.js\": `\n\t\tif (true) {\n\t\t\tlet a;\n\t\t\tfor (let b; 0;);\n\t\t\tfor (let { c, x: [d] } = {}; 0;);\n\t\t\tfor (let e of []);\n\t\t\tfor (let { f, x: [g] } of []);\n\t\t\tfor (let h in {});\n\t\t\t// for (let i = 1 in {});\n\t\t\tfor (let { j, x: [k] } in {});\n\t\t}\n\t`,\n\t\"/function.js\": `\n\t\tfunction x() {\n\t\t\tvar a;\n\t\t\tfor (var b; 0;);\n\t\t\tfor (var { c, x: [d] } = {}; 0;);\n\t\t\tfor (var e of []);\n\t\t\tfor (var { f, x: [g] } of []);\n\t\t\tfor (var h in {});\n\t\t\tfor (var i = 1 in {});\n\t\t\tfor (var { j, x: [k] } in {});\n\t\t\tfunction l() {}\n\t\t}\n\t\tx()\n\t`,\n\t\"/function-nested.js\": `\n\t\tfunction x() {\n\t\t\tif (true) {\n\t\t\t\tvar a;\n\t\t\t\tfor (var b; 0;);\n\t\t\t\tfor (var { c, x: [d] } = {}; 0;);\n\t\t\t\tfor (var e of []);\n\t\t\t\tfor (var { f, x: [g] } of []);\n\t\t\t\tfor (var h in {});\n\t\t\t\tfor (var i = 1 in {});\n\t\t\t\tfor (var { j, x: [k] } in {});\n\t\t\t\tfunction l() {}\n\t\t\t}\n\t\t}\n\t\tx()\n\t`,\n}\n\nvar relocateEntries = []string{\n\t\"/top-level.js\",\n\t\"/nested.js\",\n\t\"/let.js\",\n\t\"/function.js\",\n\t\"/function-nested.js\",\n}\n\nfunc TestVarRelocatingBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles:      relocateFiles,\n\t\tentryPaths: relocateEntries,\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestVarRelocatingNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles:      relocateFiles,\n\t\tentryPaths: relocateEntries,\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeConvertFormat,\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestImportNamespaceThisValue(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport def, * as ns from 'external'\n\t\t\t\tconsole.log(ns[foo](), new ns[foo]())\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport def, * as ns from 'external'\n\t\t\t\tconsole.log(ns.foo(), new ns.foo())\n\t\t\t`,\n\t\t\t\"/c.js\": `\n\t\t\t\timport def, {foo} from 'external'\n\t\t\t\tconsole.log(def(), foo())\n\t\t\t\tconsole.log(new def(), new foo())\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\", \"/c.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tOutputFormat: config.FormatCommonJS,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"external\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestThisUndefinedWarningESM(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport x from './file1.js'\n\t\t\t\timport y from 'pkg/file2.js'\n\t\t\t\tconsole.log(x, y)\n\t\t\t`,\n\t\t\t\"/file1.js\": `\n\t\t\t\texport default [this, this]\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/file2.js\": `\n\t\t\t\texport default [this, this]\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\tdebugLogs: true,\n\t\texpectedScanLog: `file1.js: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nfile1.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nnode_modules/pkg/file2.js: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nnode_modules/pkg/file2.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n`,\n\t})\n}\n\nfunc TestQuotedProperty(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from 'ext'\n\t\t\t\tconsole.log(ns.mustBeUnquoted, ns['mustBeQuoted'])\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tOutputFormat: config.FormatCommonJS,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"ext\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestQuotedPropertyMangle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from 'ext'\n\t\t\t\tconsole.log(ns.mustBeUnquoted, ns['mustBeUnquoted2'])\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tOutputFormat: config.FormatCommonJS,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"ext\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestDuplicatePropertyWarning(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport './outside-node-modules'\n\t\t\t\timport 'inside-node-modules'\n\t\t\t`,\n\t\t\t\"/outside-node-modules/index.jsx\": `\n\t\t\t\tconsole.log({ a: 1, a: 2 }, <div a2 a2={3}/>)\n\t\t\t`,\n\t\t\t\"/outside-node-modules/package.json\": `\n\t\t\t\t{ \"b\": 1, \"b\": 2 }\n\t\t\t`,\n\t\t\t\"/node_modules/inside-node-modules/index.jsx\": `\n\t\t\t\tconsole.log({ c: 1, c: 2 }, <div c2 c2={3}/>)\n\t\t\t`,\n\t\t\t\"/node_modules/inside-node-modules/package.json\": `\n\t\t\t\t{ \"d\": 1, \"d\": 2 }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedScanLog: `outside-node-modules/index.jsx: WARNING: Duplicate key \"a\" in object literal\noutside-node-modules/index.jsx: NOTE: The original key \"a\" is here:\noutside-node-modules/index.jsx: WARNING: Duplicate \"a2\" attribute in JSX element\noutside-node-modules/index.jsx: NOTE: The original \"a2\" attribute is here:\noutside-node-modules/package.json: WARNING: Duplicate key \"b\" in object literal\noutside-node-modules/package.json: NOTE: The original key \"b\" is here:\n`,\n\t})\n}\n\nfunc TestRequireShimSubstitution(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\trequire,\n\t\t\t\t\ttypeof require,\n\t\t\t\t\trequire('./example.json'),\n\t\t\t\t\trequire('./example.json', { type: 'json' }),\n\t\t\t\t\trequire(window.SOME_PATH),\n\t\t\t\t\tmodule.require('./example.json'),\n\t\t\t\t\tmodule.require('./example.json', { type: 'json' }),\n\t\t\t\t\tmodule.require(window.SOME_PATH),\n\t\t\t\t\trequire.resolve('some-path'),\n\t\t\t\t\trequire.resolve(window.SOME_PATH),\n\t\t\t\t\timport('some-path'),\n\t\t\t\t\timport(window.SOME_PATH),\n\t\t\t\t])\n\t\t\t`,\n\t\t\t\"/example.json\": `{ \"works\": true }`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"some-path\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t\tUnsupportedJSFeatures: compat.DynamicImport,\n\t\t},\n\t})\n}\n\n// This guards against a bad interaction between the strict mode nested function\n// declarations, name keeping, and initialized variable inlining. See this issue\n// for full context: https://github.com/evanw/esbuild/issues/1552.\nfunc TestStrictModeNestedFnDeclKeepNamesVariableInliningIssue1552(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport function outer() {\n\t\t\t\t\t{\n\t\t\t\t\t\tfunction inner() {\n\t\t\t\t\t\t\treturn Math.random();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst x = inner();\n\t\t\t\t\t\tconsole.log(x);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\touter();\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tKeepNames:    true,\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestBuiltInNodeModulePrecedence(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log([\n\t\t\t\t\t// These are node core modules\n\t\t\t\t\trequire('fs'),\n\t\t\t\t\trequire('fs/promises'),\n\t\t\t\t\trequire('node:foo'),\n\n\t\t\t\t\t// These are not node core modules\n\t\t\t\t\trequire('fs/abc'),\n\t\t\t\t\trequire('fs/'),\n\t\t\t\t])\n\t\t\t`,\n\t\t\t\"/node_modules/fs/abc.js\": `\n\t\t\t\tconsole.log('include this')\n\t\t\t`,\n\t\t\t\"/node_modules/fs/index.js\": `\n\t\t\t\tconsole.log('include this too')\n\t\t\t`,\n\t\t\t\"/node_modules/fs/promises.js\": `\n\t\t\t\tthrow 'DO NOT INCLUDE THIS'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tPlatform:     config.PlatformNode,\n\t\t\tOutputFormat: config.FormatCommonJS,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestEntryNamesNoSlashAfterDir(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/app1/main.ts\": `console.log(1)`,\n\t\t\t\"/src/app2/main.ts\": `console.log(2)`,\n\t\t\t\"/src/app3/main.ts\": `console.log(3)`,\n\t\t},\n\t\tentryPathsAdvanced: []bundler.EntryPoint{\n\t\t\t{InputPath: \"/src/app1/main.ts\"},\n\t\t\t{InputPath: \"/src/app2/main.ts\"},\n\t\t\t{InputPath: \"/src/app3/main.ts\", OutputPath: \"customPath\"},\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModePassThrough,\n\t\t\tEntryPathTemplate: []config.PathTemplate{\n\t\t\t\t// \"[dir]-[name]\"\n\t\t\t\t{Data: \"./\", Placeholder: config.DirPlaceholder},\n\t\t\t\t{Data: \"-\", Placeholder: config.NamePlaceholder},\n\t\t\t},\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestEntryNamesNonPortableCharacter(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry1-:.ts\": `console.log(1)`,\n\t\t\t\"/entry2-:.ts\": `console.log(2)`,\n\t\t},\n\t\tentryPathsAdvanced: []bundler.EntryPoint{\n\t\t\t// The \":\" should turn into \"_\" for cross-platform Windows portability\n\t\t\t{InputPath: \"/entry1-:.ts\"},\n\n\t\t\t// The \":\" should be preserved since the user _really_ wants it\n\t\t\t{InputPath: \"/entry2-:.ts\", OutputPath: \"entry2-*\"},\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestEntryNamesChunkNamesExtPlaceholder(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entries/entry1.js\":  `import \"../lib/shared.js\"; import \"./entry1.css\"; console.log('entry1')`,\n\t\t\t\"/src/entries/entry2.js\":  `import \"../lib/shared.js\"; import \"./entry2.css\"; console.log('entry2')`,\n\t\t\t\"/src/entries/entry1.css\": `a:after { content: \"entry1\" }`,\n\t\t\t\"/src/entries/entry2.css\": `a:after { content: \"entry2\" }`,\n\t\t\t\"/src/lib/shared.js\":      `console.log('shared')`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/src/entries/entry1.js\",\n\t\t\t\"/src/entries/entry2.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputBase: \"/src\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tCodeSplitting: true,\n\t\t\tEntryPathTemplate: []config.PathTemplate{\n\t\t\t\t{Data: \"main/\", Placeholder: config.ExtPlaceholder},\n\t\t\t\t{Data: \"/\", Placeholder: config.NamePlaceholder},\n\t\t\t\t{Data: \"-\", Placeholder: config.HashPlaceholder},\n\t\t\t},\n\t\t\tChunkPathTemplate: []config.PathTemplate{\n\t\t\t\t{Data: \"common/\", Placeholder: config.ExtPlaceholder},\n\t\t\t\t{Data: \"/\", Placeholder: config.NamePlaceholder},\n\t\t\t\t{Data: \"-\", Placeholder: config.HashPlaceholder},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestMinifyIdentifiersImportPathFrequencyAnalysis(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/import.js\": `\n\t\t\t\timport foo from \"./WWWWWWWWWWXXXXXXXXXXYYYYYYYYYYZZZZZZZZZZ\"\n\t\t\t\tconsole.log(foo, 'no identifier in this file should be named W, X, Y, or Z')\n\t\t\t`,\n\t\t\t\"/WWWWWWWWWWXXXXXXXXXXYYYYYYYYYYZZZZZZZZZZ.js\": `export default 123`,\n\n\t\t\t\"/require.js\": `\n\t\t\t\tconst foo = require(\"./AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDD\")\n\t\t\t\tconsole.log(foo, 'no identifier in this file should be named A, B, C, or D')\n\t\t\t`,\n\t\t\t\"/AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDD.js\": `module.exports = 123`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/import.js\",\n\t\t\t\"/require.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tAbsOutputDir:      \"/out\",\n\t\t\tMinifyWhitespace:  true,\n\t\t\tMinifyIdentifiers: true,\n\t\t},\n\t})\n}\n\nfunc TestToESMWrapperOmission(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport 'a_nowrap'\n\n\t\t\t\timport { b } from 'b_nowrap'\n\t\t\t\tb()\n\n\t\t\t\texport * from 'c_nowrap'\n\n\t\t\t\timport * as d from 'd_WRAP'\n\t\t\t\tx = d.x\n\n\t\t\t\timport e from 'e_WRAP'\n\t\t\t\te()\n\n\t\t\t\timport { default as f } from 'f_WRAP'\n\t\t\t\tf()\n\n\t\t\t\timport { __esModule as g } from 'g_WRAP'\n\t\t\t\tg()\n\n\t\t\t\timport * as h from 'h_WRAP'\n\t\t\t\tx = h\n\n\t\t\t\timport * as i from 'i_WRAP'\n\t\t\t\ti.x()\n\n\t\t\t\timport * as j from 'j_WRAP'\n\t\t\t\tj.x` + \"``\" + `\n\n\t\t\t\tx = import(\"k_WRAP\")\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeConvertFormat,\n\t\t\tOutputFormat:          config.FormatCommonJS,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tUnsupportedJSFeatures: compat.DynamicImport,\n\t\t},\n\t})\n}\n\n// This is coverage for a past bug in esbuild. We used to generate this, which is wrong:\n//\n//\tlet x = function(foo) {\n//\t  var foo2;\n//\t  return foo2;\n//\t};\nfunc TestNamedFunctionExpressionArgumentCollision(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tlet x = function foo(foo) {\n\t\t\t\t\tvar foo;\n\t\t\t\t\treturn foo;\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestNoWarnCommonJSExportsInESMPassThrough(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/cjs-in-esm.js\": `\n\t\t\t\texport let foo = 1\n\t\t\t\texports.foo = 2\n\t\t\t\tmodule.exports = 3\n\t\t\t`,\n\t\t\t\"/import-in-cjs.js\": `\n\t\t\t\timport { foo } from 'bar'\n\t\t\t\texports.foo = foo\n\t\t\t\tmodule.exports = foo\n\t\t\t`,\n\t\t\t\"/no-warnings-here.js\": `\n\t\t\t\tconsole.log(module, exports)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/cjs-in-esm.js\",\n\t\t\t\"/import-in-cjs.js\",\n\t\t\t\"/no-warnings-here.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestWarnCommonJSExportsInESMConvert(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/cjs-in-esm.js\": `\n\t\t\t\texport let foo = 1\n\t\t\t\texports.foo = 2\n\t\t\t\tmodule.exports = 3\n\t\t\t`,\n\t\t\t\"/cjs-in-esm2.js\": `\n\t\t\t\texport let foo = 1\n\t\t\t\tmodule.exports.bar = 3\n\t\t\t`,\n\t\t\t\"/import-in-cjs.js\": `\n\t\t\t\timport { foo } from 'bar'\n\t\t\t\texports.foo = foo\n\t\t\t\tmodule.exports = foo\n\t\t\t\tmodule.exports.bar = foo\n\t\t\t`,\n\t\t\t\"/no-warnings-here.js\": `\n\t\t\t\tconsole.log(module, exports)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/cjs-in-esm.js\",\n\t\t\t\"/cjs-in-esm2.js\",\n\t\t\t\"/import-in-cjs.js\",\n\t\t\t\"/no-warnings-here.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeConvertFormat,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tOutputFormat: config.FormatCommonJS,\n\t\t},\n\t\texpectedScanLog: `cjs-in-esm.js: WARNING: The CommonJS \"exports\" variable is treated as a global variable in an ECMAScript module and may not work as expected\ncjs-in-esm.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\ncjs-in-esm.js: WARNING: The CommonJS \"module\" variable is treated as a global variable in an ECMAScript module and may not work as expected\ncjs-in-esm.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\ncjs-in-esm2.js: WARNING: The CommonJS \"module\" variable is treated as a global variable in an ECMAScript module and may not work as expected\ncjs-in-esm2.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n`,\n\t})\n}\n\nfunc TestWarnCommonJSExportsInESMBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/cjs-in-esm.js\": `\n\t\t\t\texport let foo = 1\n\t\t\t\texports.foo = 2\n\t\t\t\tmodule.exports = 3\n\t\t\t`,\n\t\t\t\"/import-in-cjs.js\": `\n\t\t\t\timport { foo } from 'bar'\n\t\t\t\texports.foo = foo\n\t\t\t\tmodule.exports = foo\n\t\t\t`,\n\t\t\t\"/no-warnings-here.js\": `\n\t\t\t\tconsole.log(module, exports)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/cjs-in-esm.js\",\n\t\t\t\"/import-in-cjs.js\",\n\t\t\t\"/no-warnings-here.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tOutputFormat: config.FormatCommonJS,\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"bar\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `cjs-in-esm.js: WARNING: The CommonJS \"exports\" variable is treated as a global variable in an ECMAScript module and may not work as expected\ncjs-in-esm.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\ncjs-in-esm.js: WARNING: The CommonJS \"module\" variable is treated as a global variable in an ECMAScript module and may not work as expected\ncjs-in-esm.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n`,\n\t})\n}\n\nfunc TestMangleProps(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry1.js\": `\n\t\t\t\texport function shouldMangle() {\n\t\t\t\t\tlet foo = {\n\t\t\t\t\t\tbar_: 0,\n\t\t\t\t\t\tbaz_() {},\n\t\t\t\t\t};\n\t\t\t\t\tlet { bar_ } = foo;\n\t\t\t\t\t({ bar_ } = foo);\n\t\t\t\t\tclass foo_ {\n\t\t\t\t\t\tbar_ = 0\n\t\t\t\t\t\tbaz_() {}\n\t\t\t\t\t\tstatic bar_ = 0\n\t\t\t\t\t\tstatic baz_() {}\n\t\t\t\t\t}\n\t\t\t\t\treturn { bar_, foo_ }\n\t\t\t\t}\n\n\t\t\t\texport function shouldNotMangle() {\n\t\t\t\t\tlet foo = {\n\t\t\t\t\t\t'bar_': 0,\n\t\t\t\t\t\t'baz_'() {},\n\t\t\t\t\t};\n\t\t\t\t\tlet { 'bar_': bar_ } = foo;\n\t\t\t\t\t({ 'bar_': bar_ } = foo);\n\t\t\t\t\tclass foo_ {\n\t\t\t\t\t\t'bar_' = 0\n\t\t\t\t\t\t'baz_'() {}\n\t\t\t\t\t\tstatic 'bar_' = 0\n\t\t\t\t\t\tstatic 'baz_'() {}\n\t\t\t\t\t}\n\t\t\t\t\treturn { 'bar_': bar_, 'foo_': foo_ }\n\t\t\t\t}\n\t\t\t`,\n\n\t\t\t\"/entry2.js\": `\n\t\t\t\texport default {\n\t\t\t\t\tbar_: 0,\n\t\t\t\t\t'baz_': 1,\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry1.js\",\n\t\t\t\"/entry2.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMangleProps:  regexp.MustCompile(\"_$\"),\n\t\t},\n\t})\n}\n\nfunc TestManglePropsMinify(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t// These repeating characters test for frequency analysis\n\n\t\t\t\"/entry1.js\": `\n\t\t\t\texport function shouldMangle_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX() {\n\t\t\t\t\tlet foo = {\n\t\t\t\t\t\tbar_: 0,\n\t\t\t\t\t\tbaz_() {},\n\t\t\t\t\t};\n\t\t\t\t\tlet { bar_ } = foo;\n\t\t\t\t\t({ bar_ } = foo);\n\t\t\t\t\tclass foo_ {\n\t\t\t\t\t\tbar_ = 0\n\t\t\t\t\t\tbaz_() {}\n\t\t\t\t\t\tstatic bar_ = 0\n\t\t\t\t\t\tstatic baz_() {}\n\t\t\t\t\t}\n\t\t\t\t\treturn { bar_, foo_ }\n\t\t\t\t}\n\n\t\t\t\texport function shouldNotMangle_YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY() {\n\t\t\t\t\tlet foo = {\n\t\t\t\t\t\t'bar_': 0,\n\t\t\t\t\t\t'baz_'() {},\n\t\t\t\t\t};\n\t\t\t\t\tlet { 'bar_': bar_ } = foo;\n\t\t\t\t\t({ 'bar_': bar_ } = foo);\n\t\t\t\t\tclass foo_ {\n\t\t\t\t\t\t'bar_' = 0\n\t\t\t\t\t\t'baz_'() {}\n\t\t\t\t\t\tstatic 'bar_' = 0\n\t\t\t\t\t\tstatic 'baz_'() {}\n\t\t\t\t\t}\n\t\t\t\t\treturn { 'bar_': bar_, 'foo_': foo_ }\n\t\t\t\t}\n\t\t\t`,\n\n\t\t\t\"/entry2.js\": `\n\t\t\t\texport default {\n\t\t\t\t\tbar_: 0,\n\t\t\t\t\t'baz_': 1,\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry1.js\",\n\t\t\t\"/entry2.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModePassThrough,\n\t\t\tAbsOutputDir:      \"/out\",\n\t\t\tMangleProps:       regexp.MustCompile(\"_$\"),\n\t\t\tMinifyIdentifiers: true,\n\t\t\tMinifySyntax:      true,\n\t\t},\n\t})\n}\n\nfunc TestManglePropsKeywordPropertyMinify(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\tstatic bar = { get baz() { return 123 } }\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModePassThrough,\n\t\t\tAbsOutputDir:      \"/out\",\n\t\t\tMangleProps:       regexp.MustCompile(\".\"),\n\t\t\tMinifyIdentifiers: true,\n\t\t\tMinifySyntax:      true,\n\t\t\tMinifyWhitespace:  true,\n\t\t},\n\t})\n}\n\nfunc TestManglePropsOptionalChain(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport default function(x) {\n\t\t\t\t\tx.foo_;\n\t\t\t\t\tx.foo_?.();\n\t\t\t\t\tx?.foo_;\n\t\t\t\t\tx?.foo_();\n\t\t\t\t\tx?.foo_.bar_;\n\t\t\t\t\tx?.foo_.bar_();\n\t\t\t\t\tx?.['foo_'].bar_;\n\t\t\t\t\tx?.foo_['bar_'];\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMangleProps:   regexp.MustCompile(\"_$\"),\n\t\t},\n\t})\n}\n\nfunc TestManglePropsLoweredOptionalChain(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport default function(x) {\n\t\t\t\t\tx.foo_;\n\t\t\t\t\tx.foo_?.();\n\t\t\t\t\tx?.foo_;\n\t\t\t\t\tx?.foo_();\n\t\t\t\t\tx?.foo_.bar_;\n\t\t\t\t\tx?.foo_.bar_();\n\t\t\t\t\tx?.['foo_'].bar_;\n\t\t\t\t\tx?.foo_['bar_'];\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tMangleProps:           regexp.MustCompile(\"_$\"),\n\t\t\tUnsupportedJSFeatures: compat.OptionalChain,\n\t\t},\n\t})\n}\n\nfunc TestReserveProps(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport default {\n\t\t\t\t\tfoo_: 0,\n\t\t\t\t\t_bar_: 1,\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMangleProps:   regexp.MustCompile(\"_$\"),\n\t\t\tReserveProps:  regexp.MustCompile(\"^_.*_$\"),\n\t\t},\n\t})\n}\n\nfunc TestManglePropsImportExport(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t// These don't count as property names, and aren't mangled\n\t\t\t\"/esm.js\": `\n\t\t\t\texport let foo_ = 123\n\t\t\t\timport { bar_ } from 'xyz'\n\t\t\t`,\n\n\t\t\t// These do count as property names, and are mangled\n\t\t\t\"/cjs.js\": `\n\t\t\t\texports.foo_ = 123\n\t\t\t\tlet bar_ = require('xyz').bar_\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/esm.js\",\n\t\t\t\"/cjs.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMangleProps:  regexp.MustCompile(\"_$\"),\n\t\t},\n\t})\n}\n\nfunc TestManglePropsImportExportBundled(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t// Note: import and export syntax does not count as a property name. That\n\t\t\t// means the following code is broken. This test just serves to document\n\t\t\t// this behavior and to detect if something about this behavior changes.\n\t\t\t\"/entry-esm.js\": `\n\t\t\t\timport { esm_foo_ } from './esm'\n\t\t\t\timport { cjs_foo_ } from './cjs'\n\t\t\t\timport * as esm from './esm'\n\t\t\t\timport * as cjs from './cjs'\n\t\t\t\texport let bar_ = [\n\t\t\t\t\tesm_foo_,\n\t\t\t\t\tcjs_foo_,\n\t\t\t\t\tesm.esm_foo_,\n\t\t\t\t\tcjs.cjs_foo_,\n\t\t\t\t]\n\t\t\t`,\n\t\t\t\"/entry-cjs.js\": `\n\t\t\t\tlet { esm_foo_ } = require('./esm')\n\t\t\t\tlet { cjs_foo_ } = require('./cjs')\n\t\t\t\texports.bar_ = [\n\t\t\t\t\tesm_foo_,\n\t\t\t\t\tcjs_foo_,\n\t\t\t\t]\n\t\t\t`,\n\t\t\t\"/esm.js\": `\n\t\t\t\texport let esm_foo_ = 'foo'\n\t\t\t`,\n\t\t\t\"/cjs.js\": `\n\t\t\t\texports.cjs_foo_ = 'foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry-esm.js\",\n\t\t\t\"/entry-cjs.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMangleProps:  regexp.MustCompile(\"_$\"),\n\t\t},\n\t})\n}\n\nfunc TestManglePropsJSXTransform(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\tlet Foo = {\n\t\t\t\t\tBar_(props) {\n\t\t\t\t\t\treturn <>{props.text_}</>\n\t\t\t\t\t},\n\t\t\t\t\thello_: 'hello, world',\n\t\t\t\t\tcreateElement_(...args) {\n\t\t\t\t\t\tconsole.log('createElement', ...args)\n\t\t\t\t\t},\n\t\t\t\t\tFragment_(...args) {\n\t\t\t\t\t\tconsole.log('Fragment', ...args)\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\texport default <Foo.Bar_ text_={Foo.hello_}></Foo.Bar_>\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMangleProps:   regexp.MustCompile(\"_$\"),\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tFactory:  config.DefineExpr{Parts: []string{\"Foo\", \"createElement_\"}},\n\t\t\t\tFragment: config.DefineExpr{Parts: []string{\"Foo\", \"Fragment_\"}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestManglePropsJSXPreserve(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\tlet Foo = {\n\t\t\t\t\tBar_(props) {\n\t\t\t\t\t\treturn <>{props.text_}</>\n\t\t\t\t\t},\n\t\t\t\t\thello_: 'hello, world',\n\t\t\t\t}\n\t\t\t\texport default <Foo.Bar_ text_={Foo.hello_}></Foo.Bar_>\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.jsx\",\n\t\t\tMangleProps:   regexp.MustCompile(\"_$\"),\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tPreserve: true,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestManglePropsJSXTransformNamespace(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\texport default [\n\t\t\t\t\t<KEEP_THIS_ />,\n\t\t\t\t\t<KEEP:THIS_ />,\n\t\t\t\t\t<foo KEEP:THIS_ />,\n\t\t\t\t]\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMangleProps:   regexp.MustCompile(\"_$\"),\n\t\t},\n\t})\n}\n\nfunc TestManglePropsAvoidCollisions(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport default {\n\t\t\t\t\tfoo_: 0, // Must not be named \"a\"\n\t\t\t\t\tbar_: 1, // Must not be named \"b\"\n\t\t\t\t\ta: 2,\n\t\t\t\t\tb: 3,\n\t\t\t\t\t__proto__: {}, // Always avoid mangling this\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMangleProps:   regexp.MustCompile(\"_$\"),\n\t\t},\n\t})\n}\n\nfunc TestManglePropsTypeScriptFeatures(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/parameter-properties.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\tconstructor(\n\t\t\t\t\t\tpublic KEEP_FIELD: number,\n\t\t\t\t\t\tpublic MANGLE_FIELD_: number,\n\t\t\t\t\t) {\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlet foo = new Foo\n\t\t\t\tconsole.log(foo.KEEP_FIELD, foo.MANGLE_FIELD_)\n\t\t\t`,\n\n\t\t\t\"/namespace-exports.ts\": `\n\t\t\t\tnamespace ns {\n\t\t\t\t\texport var MANGLE_VAR_ = 1\n\t\t\t\t\texport let MANGLE_LET_ = 2\n\t\t\t\t\texport const MANGLE_CONST_ = 3\n\t\t\t\t\texport let { NESTED_: { DESTRUCTURING_ } } = 4\n\t\t\t\t\texport function MANGLE_FUNCTION_() {}\n\t\t\t\t\texport class MANGLE_CLASS_ {}\n\t\t\t\t\texport namespace MANGLE_NAMESPACE_ { ; }\n\t\t\t\t\texport enum MANGLE_ENUM_ {}\n\n\t\t\t\t\tconsole.log({\n\t\t\t\t\t\tVAR: MANGLE_VAR_,\n\t\t\t\t\t\tLET: MANGLE_LET_,\n\t\t\t\t\t\tCONST: MANGLE_CONST_,\n\t\t\t\t\t\tDESTRUCTURING: DESTRUCTURING_,\n\t\t\t\t\t\tFUNCTION: MANGLE_FUNCTION_,\n\t\t\t\t\t\tCLASS: MANGLE_CLASS_,\n\t\t\t\t\t\tNAMESPACE: MANGLE_NAMESPACE_,\n\t\t\t\t\t\tENUM: MANGLE_ENUM_,\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tconsole.log({\n\t\t\t\t\tVAR: ns.MANGLE_VAR_,\n\t\t\t\t\tLET: ns.MANGLE_LET_,\n\t\t\t\t\tCONST: ns.MANGLE_CONST_,\n\t\t\t\t\tDESTRUCTURING: ns.DESTRUCTURING_,\n\t\t\t\t\tFUNCTION: ns.MANGLE_FUNCTION_,\n\t\t\t\t\tCLASS: ns.MANGLE_CLASS_,\n\t\t\t\t\tNAMESPACE: ns.MANGLE_NAMESPACE_,\n\t\t\t\t\tENUM: ns.MANGLE_ENUM_,\n\t\t\t\t})\n\n\t\t\t\tnamespace ns {\n\t\t\t\t\tconsole.log({\n\t\t\t\t\t\tVAR: MANGLE_VAR_,\n\t\t\t\t\t\tLET: MANGLE_LET_,\n\t\t\t\t\t\tCONST: MANGLE_CONST_,\n\t\t\t\t\t\tDESTRUCTURING: DESTRUCTURING_,\n\t\t\t\t\t\tFUNCTION: MANGLE_FUNCTION_,\n\t\t\t\t\t\tCLASS: MANGLE_CLASS_,\n\t\t\t\t\t\tNAMESPACE: MANGLE_NAMESPACE_,\n\t\t\t\t\t\tENUM: MANGLE_ENUM_,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t`,\n\n\t\t\t// Mangle props deliberately doesn't work with TypeScript enums. The\n\t\t\t// rationale is that the TypeScript compiler outputs quoted strings\n\t\t\t// for enum values, so our JavaScript implementation of mangle props\n\t\t\t// wouldn't pick them up. Therefore for consistency our TypeScript\n\t\t\t// implementation of mangle props shouldn't either.\n\t\t\t//\n\t\t\t// This should be ok because esbuild supports inlining of enums instead,\n\t\t\t// which is superior to using mangle props with enums because it results\n\t\t\t// in even smaller and faster code. So people should just use enum inlining\n\t\t\t// instead of mangle props with TypeScript enums.\n\t\t\t//\n\t\t\t// This test just serves to document that this behavior deliberately\n\t\t\t// doesn't work.\n\t\t\t\"/enum-values.ts\": `\n\t\t\t\tenum TopLevelNumber { foo_ = 0 }\n\t\t\t\tenum TopLevelString { bar_ = '' }\n\t\t\t\tconsole.log({\n\t\t\t\t\tfoo: TopLevelNumber.foo_,\n\t\t\t\t\tbar: TopLevelString.bar_,\n\t\t\t\t})\n\n\t\t\t\tfunction fn() {\n\t\t\t\t\tenum NestedNumber { foo_ = 0 }\n\t\t\t\t\tenum NestedString { bar_ = '' }\n\t\t\t\t\tconsole.log({\n\t\t\t\t\t\tfoo: TopLevelNumber.foo_,\n\t\t\t\t\t\tbar: TopLevelString.bar_,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/parameter-properties.ts\",\n\t\t\t\"/namespace-exports.ts\",\n\t\t\t\"/enum-values.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMangleProps:  regexp.MustCompile(\"_$\"),\n\t\t},\n\t})\n}\n\nfunc TestManglePropsShorthand(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// This should print as \"({ y }) => ({ y })\" not \"({ y: y }) => ({ y: y })\"\n\t\t\t\texport let yyyyy = ({ xxxxx }) => ({ xxxxx })\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModePassThrough,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t\tMangleProps:       regexp.MustCompile(\"x\"),\n\t\t\tMinifyIdentifiers: true,\n\t\t},\n\t})\n}\n\nfunc TestManglePropsNoShorthand(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// This should print as \"({ y }) => ({ y: y })\" not \"({ y: y }) => ({ y: y })\"\n\t\t\t\texport let yyyyy = ({ xxxxx }) => ({ xxxxx })\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tMangleProps:           regexp.MustCompile(\"x\"),\n\t\t\tMinifyIdentifiers:     true,\n\t\t\tUnsupportedJSFeatures: compat.ObjectExtensions,\n\t\t},\n\t})\n}\n\nfunc TestManglePropsLoweredClassFields(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\tfoo_ = 123\n\t\t\t\t\tstatic bar_ = 234\n\t\t\t\t}\n\t\t\t\tFoo.bar_ = new Foo().foo_\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tMangleProps:           regexp.MustCompile(\"_$\"),\n\t\t\tUnsupportedJSFeatures: compat.ClassField | compat.ClassStaticField,\n\t\t},\n\t})\n}\n\n// This tests for a case where \"constructor\" was being mangled, which made the\n// method become a non-constructor, and then \"super()\" caused a parse error.\n// The fix was to prevent the property \"constructor\" from being mangled.\n// See: https://github.com/evanw/esbuild/issues/1976\nfunc TestManglePropsSuperCall(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {}\n\t\t\t\tclass Bar extends Foo {\n\t\t\t\t\tconstructor() {\n\t\t\t\t\t\tsuper();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMangleProps:   regexp.MustCompile(\".\"),\n\t\t},\n\t})\n}\n\nfunc TestMangleNoQuotedProps(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tx['_doNotMangleThis'];\n\t\t\t\tx?.['_doNotMangleThis'];\n\t\t\t\tx[y ? '_doNotMangleThis' : z];\n\t\t\t\tx?.[y ? '_doNotMangleThis' : z];\n\t\t\t\tx[y ? z : '_doNotMangleThis'];\n\t\t\t\tx?.[y ? z : '_doNotMangleThis'];\n\t\t\t\t({ '_doNotMangleThis': x });\n\t\t\t\t(class { '_doNotMangleThis' = x });\n\t\t\t\tvar { '_doNotMangleThis': x } = y;\n\t\t\t\t'_doNotMangleThis' in x;\n\t\t\t\t(y ? '_doNotMangleThis' : z) in x;\n\t\t\t\t(y ? z : '_doNotMangleThis') in x;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMangleProps:  regexp.MustCompile(\"_\"),\n\t\t\tMangleQuoted: false,\n\t\t},\n\t})\n}\n\nfunc TestMangleNoQuotedPropsMinifySyntax(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tx['_doNotMangleThis'];\n\t\t\t\tx?.['_doNotMangleThis'];\n\t\t\t\tx[y ? '_doNotMangleThis' : z];\n\t\t\t\tx?.[y ? '_doNotMangleThis' : z];\n\t\t\t\tx[y ? z : '_doNotMangleThis'];\n\t\t\t\tx?.[y ? z : '_doNotMangleThis'];\n\t\t\t\t({ '_doNotMangleThis': x });\n\t\t\t\t(class { '_doNotMangleThis' = x });\n\t\t\t\tvar { '_doNotMangleThis': x } = y;\n\t\t\t\t'_doNotMangleThis' in x;\n\t\t\t\t(y ? '_doNotMangleThis' : z) in x;\n\t\t\t\t(y ? z : '_doNotMangleThis') in x;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMangleProps:  regexp.MustCompile(\"_\"),\n\t\t\tMangleQuoted: false,\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestMangleQuotedProps(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/keep.js\": `\n\t\t\t\tfoo(\"_keepThisProperty\");\n\t\t\t\tfoo((x, \"_keepThisProperty\"));\n\t\t\t\tfoo(x ? \"_keepThisProperty\" : \"_keepThisPropertyToo\");\n\t\t\t\tx[foo(\"_keepThisProperty\")];\n\t\t\t\tx?.[foo(\"_keepThisProperty\")];\n\t\t\t\t({ [foo(\"_keepThisProperty\")]: x });\n\t\t\t\t(class { [foo(\"_keepThisProperty\")] = x });\n\t\t\t\tvar { [foo(\"_keepThisProperty\")]: x } = y;\n\t\t\t\tfoo(\"_keepThisProperty\") in x;\n\t\t\t`,\n\t\t\t\"/mangle.js\": `\n\t\t\t\tx['_mangleThis'];\n\t\t\t\tx?.['_mangleThis'];\n\t\t\t\tx[y ? '_mangleThis' : z];\n\t\t\t\tx?.[y ? '_mangleThis' : z];\n\t\t\t\tx[y ? z : '_mangleThis'];\n\t\t\t\tx?.[y ? z : '_mangleThis'];\n\t\t\t\tx[y, '_mangleThis'];\n\t\t\t\tx?.[y, '_mangleThis'];\n\t\t\t\t({ '_mangleThis': x });\n\t\t\t\t({ ['_mangleThis']: x });\n\t\t\t\t({ [(y, '_mangleThis')]: x });\n\t\t\t\t(class { '_mangleThis' = x });\n\t\t\t\t(class { ['_mangleThis'] = x });\n\t\t\t\t(class { [(y, '_mangleThis')] = x });\n\t\t\t\tvar { '_mangleThis': x } = y;\n\t\t\t\tvar { ['_mangleThis']: x } = y;\n\t\t\t\tvar { [(z, '_mangleThis')]: x } = y;\n\t\t\t\t'_mangleThis' in x;\n\t\t\t\t(y ? '_mangleThis' : z) in x;\n\t\t\t\t(y ? z : '_mangleThis') in x;\n\t\t\t\t(y, '_mangleThis') in x;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/keep.js\", \"/mangle.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMangleProps:  regexp.MustCompile(\"_\"),\n\t\t\tMangleQuoted: true,\n\t\t},\n\t})\n}\n\nfunc TestMangleQuotedPropsMinifySyntax(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/keep.js\": `\n\t\t\t\tfoo(\"_keepThisProperty\");\n\t\t\t\tfoo((x, \"_keepThisProperty\"));\n\t\t\t\tfoo(x ? \"_keepThisProperty\" : \"_keepThisPropertyToo\");\n\t\t\t\tx[foo(\"_keepThisProperty\")];\n\t\t\t\tx?.[foo(\"_keepThisProperty\")];\n\t\t\t\t({ [foo(\"_keepThisProperty\")]: x });\n\t\t\t\t(class { [foo(\"_keepThisProperty\")] = x });\n\t\t\t\tvar { [foo(\"_keepThisProperty\")]: x } = y;\n\t\t\t\tfoo(\"_keepThisProperty\") in x;\n\t\t\t`,\n\t\t\t\"/mangle.js\": `\n\t\t\t\tx['_mangleThis'];\n\t\t\t\tx?.['_mangleThis'];\n\t\t\t\tx[y ? '_mangleThis' : z];\n\t\t\t\tx?.[y ? '_mangleThis' : z];\n\t\t\t\tx[y ? z : '_mangleThis'];\n\t\t\t\tx?.[y ? z : '_mangleThis'];\n\t\t\t\tx[y, '_mangleThis'];\n\t\t\t\tx?.[y, '_mangleThis'];\n\t\t\t\t({ '_mangleThis': x });\n\t\t\t\t({ ['_mangleThis']: x });\n\t\t\t\t({ [(y, '_mangleThis')]: x });\n\t\t\t\t(class { '_mangleThis' = x });\n\t\t\t\t(class { ['_mangleThis'] = x });\n\t\t\t\t(class { [(y, '_mangleThis')] = x });\n\t\t\t\tvar { '_mangleThis': x } = y;\n\t\t\t\tvar { ['_mangleThis']: x } = y;\n\t\t\t\tvar { [(z, '_mangleThis')]: x } = y;\n\t\t\t\t'_mangleThis' in x;\n\t\t\t\t(y ? '_mangleThis' : z) in x;\n\t\t\t\t(y ? z : '_mangleThis') in x;\n\t\t\t\t(y, '_mangleThis') in x;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/keep.js\", \"/mangle.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMangleProps:  regexp.MustCompile(\"_\"),\n\t\t\tMangleQuoted: true,\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestPreserveKeyComment(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tx(/* __KEY__ */ 'notKey', /* __KEY__ */ ` + \"`\" + `notKey` + \"`\" + `)\n\t\t\t\tx(/* @__KEY__ */ 'key', /* @__KEY__ */ ` + \"`\" + `key` + \"`\" + `)\n\t\t\t\tx(/* #__KEY__ */ 'alsoKey', /* #__KEY__ */ ` + \"`\" + `alsoKey` + \"`\" + `)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestManglePropsKeyComment(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tx(/* __KEY__ */ '_doNotMangleThis', /* __KEY__ */ ` + \"`\" + `_doNotMangleThis` + \"`\" + `)\n\t\t\t\tx._mangleThis(/* @__KEY__ */ '_mangleThis', /* @__KEY__ */ ` + \"`\" + `_mangleThis` + \"`\" + `)\n\t\t\t\tx._mangleThisToo(/* #__KEY__ */ '_mangleThisToo', /* #__KEY__ */ ` + \"`\" + `_mangleThisToo` + \"`\" + `)\n\t\t\t\tx._someKey = /* #__KEY__ */ '_someKey' in y\n\t\t\t\tx([\n\t\t\t\t\t` + \"`\" + `foo.${/* @__KEY__ */ '_mangleThis'} = bar.${/* @__KEY__ */ '_mangleThisToo'}` + \"`\" + `,\n\t\t\t\t\t` + \"`\" + `foo.${/* @__KEY__ */ 'notMangled'} = bar.${/* @__KEY__ */ 'notMangledEither'}` + \"`\" + `,\n\t\t\t\t])\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMangleProps:  regexp.MustCompile(\"_\"),\n\t\t},\n\t})\n}\n\nfunc TestManglePropsKeyCommentMinify(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tx = class {\n\t\t\t\t\t_mangleThis = 1;\n\t\t\t\t\t[/* @__KEY__ */ '_mangleThisToo'] = 2;\n\t\t\t\t\t'_doNotMangleThis' = 3;\n\t\t\t\t}\n\t\t\t\tx = {\n\t\t\t\t\t_mangleThis: 1,\n\t\t\t\t\t[/* @__KEY__ */ '_mangleThisToo']: 2,\n\t\t\t\t\t'_doNotMangleThis': 3,\n\t\t\t\t}\n\t\t\t\tx._mangleThis = 1\n\t\t\t\tx[/* @__KEY__ */ '_mangleThisToo'] = 2\n\t\t\t\tx['_doNotMangleThis'] = 3\n\t\t\t\tx([\n\t\t\t\t\t` + \"`\" + `${foo}.${/* @__KEY__ */ '_mangleThis'} = bar.${/* @__KEY__ */ '_mangleThisToo'}` + \"`\" + `,\n\t\t\t\t\t` + \"`\" + `${foo}.${/* @__KEY__ */ 'notMangled'} = bar.${/* @__KEY__ */ 'notMangledEither'}` + \"`\" + `,\n\t\t\t\t])\n\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMangleProps:  regexp.MustCompile(\"_\"),\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestIndirectRequireMessage(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/array.js\":  `let x = [require]`,\n\t\t\t\"/assign.js\": `require = x`,\n\t\t\t\"/ident.js\":  `let x = require`,\n\n\t\t\t// These shouldn't log anything: https://github.com/evanw/esbuild/issues/812\n\t\t\t\"/dot.js\":   `let x = require.cache`,\n\t\t\t\"/index.js\": `let x = require[cache]`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/array.js\",\n\t\t\t\"/assign.js\",\n\t\t\t\"/dot.js\",\n\t\t\t\"/ident.js\",\n\t\t\t\"/index.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\tdebugLogs: true,\n\t\texpectedScanLog: `array.js: DEBUG: Indirect calls to \"require\" will not be bundled\nassign.js: DEBUG: Indirect calls to \"require\" will not be bundled\nident.js: DEBUG: Indirect calls to \"require\" will not be bundled\n`,\n\t})\n}\n\nfunc TestAmbiguousReexportMsg(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * from './a'\n\t\t\t\texport * from './b'\n\t\t\t\texport * from './c'\n\t\t\t`,\n\t\t\t\"/a.js\": `export let a = 1, x = 2`,\n\t\t\t\"/b.js\": `export let b = 3; export { b as x }`,\n\t\t\t\"/c.js\": `export let c = 4, x = 5`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\tdebugLogs: true,\n\t\texpectedCompileLog: `DEBUG: Re-export of \"x\" in \"entry.js\" is ambiguous and has been removed\na.js: NOTE: One definition of \"x\" comes from \"a.js\" here:\nb.js: NOTE: Another definition of \"x\" comes from \"b.js\" here:\n`,\n\t})\n}\n\n// See: https://github.com/evanw/esbuild/issues/2537\nfunc TestNonDeterminismIssue2537(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\texport function aap(noot: boolean, wim: number) {\n\t\t\t\t\tlet mies = \"teun\"\n\t\t\t\t\tif (noot) {\n\t\t\t\t\t\tfunction vuur(v: number) {\n\t\t\t\t\t\t\treturn v * 2\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfunction schaap(s: number) {\n\t\t\t\t\t\t\treturn s / 2\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmies = vuur(wim) + schaap(wim)\n\t\t\t\t\t}\n\t\t\t\t\treturn mies\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"alwaysStrict\": true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t\tMinifyIdentifiers: true,\n\t\t},\n\t})\n}\n\n// See: https://github.com/evanw/esbuild/issues/2697\nfunc TestMinifiedJSXPreserveWithObjectSpread(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\tconst obj = {\n\t\t\t\t\tbefore,\n\t\t\t\t\t...{ [key]: value },\n\t\t\t\t\t...{ key: value },\n\t\t\t\t\tafter,\n\t\t\t\t};\n\t\t\t\t<Foo\n\t\t\t\t\tbefore\n\t\t\t\t\t{...{ [key]: value }}\n\t\t\t\t\t{...{ key: value }}\n\t\t\t\t\tafter\n\t\t\t\t/>;\n\t\t\t\t<Bar\n\t\t\t\t\t{...{\n\t\t\t\t\t\ta,\n\t\t\t\t\t\t[b]: c,\n\t\t\t\t\t\t...d,\n\t\t\t\t\t\te,\n\t\t\t\t\t}}\n\t\t\t\t/>;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMinifySyntax:  true,\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tPreserve: true,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestPackageAlias(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"pkg1\"\n\t\t\t\timport \"pkg2/foo\"\n\t\t\t\timport \"./nested3\"\n\t\t\t\timport \"@scope/pkg4\"\n\t\t\t\timport \"@scope/pkg5/foo\"\n\t\t\t\timport \"@abs-path/pkg6\"\n\t\t\t\timport \"@abs-path/pkg7/foo\"\n\t\t\t\timport \"@scope-only/pkg8\"\n\t\t\t\timport \"slash/\"\n\t\t\t\timport \"prefix-foo\"\n\t\t\t\timport \"@scope/prefix-foo\"\n\t\t\t`,\n\t\t\t\"/nested3/index.js\":                        `import \"pkg3\"`,\n\t\t\t\"/nested3/node_modules/alias3/index.js\":    `test failure`,\n\t\t\t\"/node_modules/alias1/index.js\":            `console.log(1)`,\n\t\t\t\"/node_modules/alias2/foo.js\":              `console.log(2)`,\n\t\t\t\"/node_modules/alias3/index.js\":            `console.log(3)`,\n\t\t\t\"/node_modules/alias4/index.js\":            `console.log(4)`,\n\t\t\t\"/node_modules/alias5/foo.js\":              `console.log(5)`,\n\t\t\t\"/alias6/dir/index.js\":                     `console.log(6)`,\n\t\t\t\"/alias7/dir/foo/index.js\":                 `console.log(7)`,\n\t\t\t\"/alias8/dir/pkg8/index.js\":                `console.log(8)`,\n\t\t\t\"/alias9/some/file.js\":                     `console.log(9)`,\n\t\t\t\"/node_modules/prefix-foo/index.js\":        `console.log(10)`,\n\t\t\t\"/node_modules/@scope/prefix-foo/index.js\": `console.log(11)`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPackageAliases: map[string]string{\n\t\t\t\t\"pkg1\":           \"alias1\",\n\t\t\t\t\"pkg2\":           \"alias2\",\n\t\t\t\t\"pkg3\":           \"alias3\",\n\t\t\t\t\"@scope/pkg4\":    \"alias4\",\n\t\t\t\t\"@scope/pkg5\":    \"alias5\",\n\t\t\t\t\"@abs-path/pkg6\": `/alias6/dir`,\n\t\t\t\t\"@abs-path/pkg7\": `/alias7/dir`,\n\t\t\t\t\"@scope-only\":    \"/alias8/dir\",\n\t\t\t\t\"slash\":          \"/alias9/some/file.js\",\n\t\t\t\t\"prefix\":         \"alias10\",\n\t\t\t\t\"@scope/prefix\":  \"alias11\",\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestPackageAliasMatchLongest(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"pkg\"\n\t\t\t\timport \"pkg/foo\"\n\t\t\t\timport \"pkg/foo/bar\"\n\t\t\t\timport \"pkg/foo/bar/baz\"\n\t\t\t\timport \"pkg/bar/baz\"\n\t\t\t\timport \"pkg/baz\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPackageAliases: map[string]string{\n\t\t\t\t\"pkg\":         \"alias/pkg\",\n\t\t\t\t\"pkg/foo\":     \"alias/pkg_foo\",\n\t\t\t\t\"pkg/foo/bar\": \"alias/pkg_foo_bar\",\n\t\t\t},\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tPatterns: []config.WildcardPattern{{Prefix: \"alias/\"}},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestErrorsForAssertTypeJSON(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/js-entry.js\": `\n\t\t\t\timport all from './foo.json' assert { type: 'json' }\n\t\t\t\timport { default as def } from './foo.json' assert { type: 'json' }\n\t\t\t\timport { unused } from './foo.json' assert { type: 'json' }\n\t\t\t\timport { used } from './foo.json' assert { type: 'json' }\n\t\t\t\timport * as ns from './foo.json' assert { type: 'json' }\n\t\t\t\tuse(used, ns.prop)\n\t\t\t\texport { exported } from './foo.json' assert { type: 'json' }\n\t\t\t\texport { default as def2 } from './foo.json' assert { type: 'json' }\n\t\t\t\texport { def3 as default } from './foo.json' assert { type: 'json' }\n\t\t\t\timport text from './foo.text' assert { type: 'json' }\n\t\t\t\timport file from './foo.file' assert { type: 'json' }\n\t\t\t\timport copy from './foo.copy' assert { type: 'json' }\n\t\t\t`,\n\t\t\t\"/ts-entry.ts\": `\n\t\t\t\timport all from './foo.json' assert { type: 'json' }\n\t\t\t\timport { default as def } from './foo.json' assert { type: 'json' }\n\t\t\t\timport { unused } from './foo.json' assert { type: 'json' }\n\t\t\t\timport { used } from './foo.json' assert { type: 'json' }\n\t\t\t\timport * as ns from './foo.json' assert { type: 'json' }\n\t\t\t\tuse(used, ns.prop)\n\t\t\t\texport { exported } from './foo.json' assert { type: 'json' }\n\t\t\t\texport { default as def2 } from './foo.json' assert { type: 'json' }\n\t\t\t\texport { def3 as default } from './foo.json' assert { type: 'json' }\n\t\t\t\timport text from './foo.text' assert { type: 'json' }\n\t\t\t\timport file from './foo.file' assert { type: 'json' }\n\t\t\t\timport copy from './foo.copy' assert { type: 'json' }\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t\t\"/foo.text\": `{}`,\n\t\t\t\"/foo.file\": `{}`,\n\t\t\t\"/foo.copy\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/js-entry.js\",\n\t\t\t\"/ts-entry.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":   config.LoaderJS,\n\t\t\t\t\".ts\":   config.LoaderTS,\n\t\t\t\t\".json\": config.LoaderJSON,\n\t\t\t\t\".text\": config.LoaderText,\n\t\t\t\t\".file\": config.LoaderFile,\n\t\t\t\t\".copy\": config.LoaderCopy,\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `js-entry.js: ERROR: Cannot use non-default import \"unused\" with a JSON import assertion\njs-entry.js: NOTE: The JSON import assertion is here:\nNOTE: You can either keep the import assertion and only use the \"default\" import, or you can remove the import assertion and use the \"unused\" import.\njs-entry.js: ERROR: Cannot use non-default import \"used\" with a JSON import assertion\njs-entry.js: NOTE: The JSON import assertion is here:\nNOTE: You can either keep the import assertion and only use the \"default\" import, or you can remove the import assertion and use the \"used\" import.\njs-entry.js: WARNING: Non-default import \"prop\" is undefined with a JSON import assertion\njs-entry.js: NOTE: The JSON import assertion is here:\nNOTE: You can either keep the import assertion and only use the \"default\" import, or you can remove the import assertion and use the \"prop\" import.\njs-entry.js: ERROR: Cannot use non-default import \"exported\" with a JSON import assertion\njs-entry.js: NOTE: The JSON import assertion is here:\nNOTE: You can either keep the import assertion and only use the \"default\" import, or you can remove the import assertion and use the \"exported\" import.\njs-entry.js: ERROR: Cannot use non-default import \"def3\" with a JSON import assertion\njs-entry.js: NOTE: The JSON import assertion is here:\nNOTE: You can either keep the import assertion and only use the \"default\" import, or you can remove the import assertion and use the \"def3\" import.\njs-entry.js: ERROR: The file \"foo.text\" was loaded with the \"text\" loader\njs-entry.js: NOTE: This import assertion requires the loader to be \"json\" instead:\nNOTE: You need to either reconfigure esbuild to ensure that the loader for this file is \"json\" or you need to remove this import assertion.\njs-entry.js: ERROR: The file \"foo.file\" was loaded with the \"file\" loader\njs-entry.js: NOTE: This import assertion requires the loader to be \"json\" instead:\nNOTE: You need to either reconfigure esbuild to ensure that the loader for this file is \"json\" or you need to remove this import assertion.\nts-entry.ts: ERROR: Cannot use non-default import \"used\" with a JSON import assertion\nts-entry.ts: NOTE: The JSON import assertion is here:\nNOTE: You can either keep the import assertion and only use the \"default\" import, or you can remove the import assertion and use the \"used\" import.\nts-entry.ts: WARNING: Non-default import \"prop\" is undefined with a JSON import assertion\nts-entry.ts: NOTE: The JSON import assertion is here:\nNOTE: You can either keep the import assertion and only use the \"default\" import, or you can remove the import assertion and use the \"prop\" import.\nts-entry.ts: ERROR: Cannot use non-default import \"exported\" with a JSON import assertion\nts-entry.ts: NOTE: The JSON import assertion is here:\nNOTE: You can either keep the import assertion and only use the \"default\" import, or you can remove the import assertion and use the \"exported\" import.\nts-entry.ts: ERROR: Cannot use non-default import \"def3\" with a JSON import assertion\nts-entry.ts: NOTE: The JSON import assertion is here:\nNOTE: You can either keep the import assertion and only use the \"default\" import, or you can remove the import assertion and use the \"def3\" import.\n`,\n\t})\n}\n\nfunc TestOutputForAssertTypeJSON(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/js-entry.js\": `\n\t\t\t\timport all from './foo.json' assert { type: 'json' }\n\t\t\t\timport copy from './foo.copy' assert { type: 'json' }\n\t\t\t\timport { default as def } from './foo.json' assert { type: 'json' }\n\t\t\t\timport * as ns from './foo.json' assert { type: 'json' }\n\t\t\t\tuse(all, copy, def, ns.prop)\n\t\t\t\texport { default } from './foo.json' assert { type: 'json' }\n\t\t\t`,\n\t\t\t\"/ts-entry.ts\": `\n\t\t\t\timport all from './foo.json' assert { type: 'json' }\n\t\t\t\timport copy from './foo.copy' assert { type: 'json' }\n\t\t\t\timport { default as def } from './foo.json' assert { type: 'json' }\n\t\t\t\timport { unused } from './foo.json' assert { type: 'json' }\n\t\t\t\timport * as ns from './foo.json' assert { type: 'json' }\n\t\t\t\tuse(all, copy, def, ns.prop)\n\t\t\t\texport { default } from './foo.json' assert { type: 'json' }\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t\t\"/foo.copy\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/js-entry.js\",\n\t\t\t\"/ts-entry.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":   config.LoaderJS,\n\t\t\t\t\".ts\":   config.LoaderTS,\n\t\t\t\t\".json\": config.LoaderJSON,\n\t\t\t\t\".copy\": config.LoaderCopy,\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `js-entry.js: WARNING: Non-default import \"prop\" is undefined with a JSON import assertion\njs-entry.js: NOTE: The JSON import assertion is here:\nNOTE: You can either keep the import assertion and only use the \"default\" import, or you can remove the import assertion and use the \"prop\" import.\nts-entry.ts: WARNING: Non-default import \"prop\" is undefined with a JSON import assertion\nts-entry.ts: NOTE: The JSON import assertion is here:\nNOTE: You can either keep the import assertion and only use the \"default\" import, or you can remove the import assertion and use the \"prop\" import.\n`,\n\t})\n}\n\nfunc TestExternalPackages(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/entry.js\": `\n\t\t\t\timport 'pkg1'\n\t\t\t\timport './file'\n\t\t\t\timport './node_modules/pkg2/index.js'\n\t\t\t\timport '#pkg3'\n\t\t\t`,\n\t\t\t\"/project/package.json\": `{\n\t\t\t\t\"imports\": {\n\t\t\t\t\t\"#pkg3\": \"./libs/pkg3.js\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/project/file.js\": `\n\t\t\t\tconsole.log('file')\n\t\t\t`,\n\t\t\t\"/project/node_modules/pkg2/index.js\": `\n\t\t\t\tconsole.log('pkg2')\n\t\t\t`,\n\t\t\t\"/project/libs/pkg3.js\": `\n\t\t\t\tconsole.log('pkg3')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/project/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:             config.ModeBundle,\n\t\t\tAbsOutputFile:    \"/out.js\",\n\t\t\tExternalPackages: true,\n\t\t},\n\t})\n}\n\nfunc TestMetafileVariousCases(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/entry.js\": `\n\t\t\t\timport a from 'extern-esm'\n\t\t\t\timport b from './esm'\n\t\t\t\timport c from 'data:application/json,2'\n\t\t\t\timport d from './file.file'\n\t\t\t\timport e from './copy.copy'\n\t\t\t\tconsole.log(\n\t\t\t\t\ta,\n\t\t\t\t\tb,\n\t\t\t\t\tc,\n\t\t\t\t\td,\n\t\t\t\t\te,\n\t\t\t\t\trequire('extern-cjs'),\n\t\t\t\t\trequire('./cjs'),\n\t\t\t\t\timport('./dynamic'),\n\t\t\t\t)\n\t\t\t\texport let exported\n\t\t\t`,\n\t\t\t\"/project/entry.css\": `\n\t\t\t\t@import \"extern.css\";\n\t\t\t\ta { background: url(inline.svg) }\n\t\t\t\tb { background: url(file.file) }\n\t\t\t\tc { background: url(copy.copy) }\n\t\t\t\td { background: url(extern.png) }\n\t\t\t`,\n\t\t\t\"/project/esm.js\":     `export default 1`,\n\t\t\t\"/project/cjs.js\":     `module.exports = 4`,\n\t\t\t\"/project/dynamic.js\": `export default 5`,\n\t\t\t\"/project/file.file\":  `file`,\n\t\t\t\"/project/copy.copy\":  `copy`,\n\t\t\t\"/project/inline.svg\": `<svg/>`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/project/entry.js\",\n\t\t\t\"/project/entry.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":   config.LoaderJS,\n\t\t\t\t\".css\":  config.LoaderCSS,\n\t\t\t\t\".file\": config.LoaderFile,\n\t\t\t\t\".copy\": config.LoaderCopy,\n\t\t\t\t\".svg\":  config.LoaderDataURL,\n\t\t\t},\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tExact: map[string]bool{\n\t\t\t\t\t\t\"extern-esm\": true,\n\t\t\t\t\t\t\"extern-cjs\": true,\n\t\t\t\t\t\t\"extern.css\": true,\n\t\t\t\t\t\t\"extern.png\": true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tNeedsMetafile: true,\n\t\t\tCodeSplitting: true,\n\t\t},\n\t})\n}\n\nfunc TestMetafileNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/entry.js\": `\n\t\t\t\timport a from 'pkg'\n\t\t\t\timport b from './file'\n\t\t\t\tconsole.log(\n\t\t\t\t\ta,\n\t\t\t\t\tb,\n\t\t\t\t\trequire('pkg2'),\n\t\t\t\t\trequire('./file2'),\n\t\t\t\t\timport('./dynamic'),\n\t\t\t\t)\n\t\t\t\texport let exported\n\t\t\t`,\n\t\t\t\"/project/entry.css\": `\n\t\t\t\t@import \"pkg\";\n\t\t\t\t@import \"./file\";\n\t\t\t\ta { background: url(pkg2) }\n\t\t\t\ta { background: url(./file2) }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/project/entry.js\",\n\t\t\t\"/project/entry.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tNeedsMetafile: true,\n\t\t},\n\t})\n}\n\nfunc TestMetafileVeryLongExternalPaths(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/bytesInOutput should be at least 99 (1).js\": `\n\t\t\t\timport a from './` + strings.Repeat(\"1\", 99) + `.file'\n\t\t\t\tconsole.log(a)\n\t\t\t`,\n\t\t\t\"/project/bytesInOutput should be at least 99 (2).js\": `\n\t\t\t\timport a from './` + strings.Repeat(\"2\", 99) + `.copy'\n\t\t\t\tconsole.log(a)\n\t\t\t`,\n\t\t\t\"/project/bytesInOutput should be at least 99 (3).js\": `\n\t\t\t\timport('./` + strings.Repeat(\"3\", 99) + `.js').then(console.log)\n\t\t\t`,\n\t\t\t\"/project/bytesInOutput should be at least 99.css\": `\n\t\t\t\ta { background: url(` + strings.Repeat(\"4\", 99) + `.file) }\n\t\t\t`,\n\t\t\t\"/project/\" + strings.Repeat(\"1\", 99) + \".file\": ``,\n\t\t\t\"/project/\" + strings.Repeat(\"2\", 99) + \".copy\": ``,\n\t\t\t\"/project/\" + strings.Repeat(\"3\", 99) + \".js\":   ``,\n\t\t\t\"/project/\" + strings.Repeat(\"4\", 99) + \".file\": ``,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/project/bytesInOutput should be at least 99 (1).js\",\n\t\t\t\"/project/bytesInOutput should be at least 99 (2).js\",\n\t\t\t\"/project/bytesInOutput should be at least 99 (3).js\",\n\t\t\t\"/project/bytesInOutput should be at least 99.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tNeedsMetafile: true,\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":   config.LoaderJS,\n\t\t\t\t\".css\":  config.LoaderCSS,\n\t\t\t\t\".file\": config.LoaderFile,\n\t\t\t\t\".copy\": config.LoaderCopy,\n\t\t\t},\n\t\t\tCodeSplitting: true,\n\t\t},\n\t})\n}\n\nfunc TestMetafileImportWithTypeJSON(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/entry.js\": `\n\t\t\t\timport a from './data.json'\n\t\t\t\timport b from './data.json' assert { type: 'json' }\n\t\t\t\timport c from './data.json' with { type: 'json' }\n\t\t\t\tx = [a, b, c]\n\t\t\t`,\n\t\t\t\"/project/data.json\": `{\"some\": \"data\"}`,\n\t\t},\n\t\tentryPaths: []string{\"/project/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tNeedsMetafile: true,\n\t\t},\n\t})\n}\n\nfunc TestCommentPreservation(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(\n\t\t\t\t\timport(/* before */ foo),\n\t\t\t\t\timport(/* before */ 'foo'),\n\t\t\t\t\timport(foo /* after */),\n\t\t\t\t\timport('foo' /* after */),\n\t\t\t\t)\n\n\t\t\t\tconsole.log(\n\t\t\t\t\timport('foo', /* before */ { assert: { type: 'json' } }),\n\t\t\t\t\timport('foo', { /* before */ assert: { type: 'json' } }),\n\t\t\t\t\timport('foo', { assert: /* before */ { type: 'json' } }),\n\t\t\t\t\timport('foo', { assert: { /* before */ type: 'json' } }),\n\t\t\t\t\timport('foo', { assert: { type: /* before */ 'json' } }),\n\t\t\t\t\timport('foo', { assert: { type: 'json' /* before */ } }),\n\t\t\t\t\timport('foo', { assert: { type: 'json' } /* before */ }),\n\t\t\t\t\timport('foo', { assert: { type: 'json' } } /* before */),\n\t\t\t\t)\n\n\t\t\t\tconsole.log(\n\t\t\t\t\trequire(/* before */ foo),\n\t\t\t\t\trequire(/* before */ 'foo'),\n\t\t\t\t\trequire(foo /* after */),\n\t\t\t\t\trequire('foo' /* after */),\n\t\t\t\t)\n\n\t\t\t\tconsole.log(\n\t\t\t\t\trequire.resolve(/* before */ foo),\n\t\t\t\t\trequire.resolve(/* before */ 'foo'),\n\t\t\t\t\trequire.resolve(foo /* after */),\n\t\t\t\t\trequire.resolve('foo' /* after */),\n\t\t\t\t)\n\n\t\t\t\tlet [/* foo */] = [/* bar */];\n\t\t\t\tlet [\n\t\t\t\t\t// foo\n\t\t\t\t] = [\n\t\t\t\t\t// bar\n\t\t\t\t];\n\t\t\t\tlet [/*before*/ ...s] = [/*before*/ ...s]\n\t\t\t\tlet [... /*before*/ s2] = [... /*before*/ s2]\n\n\t\t\t\tlet { /* foo */ } = { /* bar */ };\n\t\t\t\tlet {\n\t\t\t\t\t// foo\n\t\t\t\t} = {\n\t\t\t\t\t// bar\n\t\t\t\t};\n\t\t\t\tlet { /*before*/ ...s3 } = { /*before*/ ...s3 }\n\t\t\t\tlet { ... /*before*/ s4 } = { ... /*before*/ s4 }\n\n\t\t\t\tlet [/* before */ x] = [/* before */ x];\n\t\t\t\tlet [/* before */ x2 /* after */] = [/* before */ x2 /* after */];\n\t\t\t\tlet [\n\t\t\t\t\t// before\n\t\t\t\t\tx3\n\t\t\t\t\t// after\n\t\t\t\t] = [\n\t\t\t\t\t// before\n\t\t\t\t\tx3\n\t\t\t\t\t// after\n\t\t\t\t];\n\n\t\t\t\tlet { /* before */ y } = { /* before */ y };\n\t\t\t\tlet { /* before */ y2 /* after */ } = { /* before */ y2 /* after */ };\n\t\t\t\tlet {\n\t\t\t\t\t// before\n\t\t\t\t\ty3\n\t\t\t\t\t// after\n\t\t\t\t} = {\n\t\t\t\t\t// before\n\t\t\t\t\ty3\n\t\t\t\t\t// after\n\t\t\t\t};\n\t\t\t\tlet { /* before */ [y4]: y4 } = { /* before */ [y4]: y4 };\n\t\t\t\tlet { [/* before */ y5]: y5 } = { [/* before */ y5]: y5 };\n\t\t\t\tlet { [y6 /* after */]: y6 } = { [y6 /* after */]: y6 };\n\n\t\t\t\tfoo[/* before */ x] = foo[/* before */ x]\n\t\t\t\tfoo[x /* after */] = foo[x /* after */]\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t// before\n\t\t\t\t\tfoo,\n\t\t\t\t\t/* comment before */\n\t\t\t\t\tbar,\n\t\t\t\t\t// comment after\n\t\t\t\t)\n\n\t\t\t\tconsole.log([\n\t\t\t\t\t// before\n\t\t\t\t\tfoo,\n\t\t\t\t\t/* comment before */\n\t\t\t\t\tbar,\n\t\t\t\t\t// comment after\n\t\t\t\t])\n\n\t\t\t\tconsole.log({\n\t\t\t\t\t// before\n\t\t\t\t\tfoo,\n\t\t\t\t\t/* comment before */\n\t\t\t\t\tbar,\n\t\t\t\t\t// comment after\n\t\t\t\t})\n\n\t\t\t\tconsole.log(class {\n\t\t\t\t\t// before\n\t\t\t\t\tfoo\n\t\t\t\t\t/* comment before */\n\t\t\t\t\tbar\n\t\t\t\t\t// comment after\n\t\t\t\t})\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t() => { return /* foo */ null },\n\t\t\t\t\t() => { throw /* foo */ null },\n\t\t\t\t\t() => { return (/* foo */ null) + 1 },\n\t\t\t\t\t() => { throw (/* foo */ null) + 1 },\n\t\t\t\t\t() => {\n\t\t\t\t\t\treturn (// foo\n\t\t\t\t\t\t\tnull) + 1\n\t\t\t\t\t},\n\t\t\t\t\t() => {\n\t\t\t\t\t\tthrow (// foo\n\t\t\t\t\t\t\tnull) + 1\n\t\t\t\t\t},\n\t\t\t\t)\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t/*a*/ a ? /*b*/ b : /*c*/ c,\n\t\t\t\t\ta /*a*/ ? b /*b*/ : c /*c*/,\n\t\t\t\t)\n\n\t\t\t\tfor (/*foo*/a;;);\n\t\t\t\tfor (;/*foo*/a;);\n\t\t\t\tfor (;;/*foo*/a);\n\n\t\t\t\tfor (/*foo*/a in b);\n\t\t\t\tfor (a in /*foo*/b);\n\n\t\t\t\tfor (/*foo*/a of b);\n\t\t\t\tfor (a of /*foo*/b);\n\n\t\t\t\tif (/*foo*/a);\n\t\t\t\twith (/*foo*/a);\n\t\t\t\twhile (/*foo*/a);\n\t\t\t\tdo {} while (/*foo*/a);\n\t\t\t\tswitch (/*foo*/a) {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tExact: map[string]bool{\"foo\": true},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestCommentPreservationImportAssertions(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\timport 'foo' /* before */ assert { type: 'json' }\n\t\t\t\timport 'foo' assert /* before */ { type: 'json' }\n\t\t\t\timport 'foo' assert { /* before */ type: 'json' }\n\t\t\t\timport 'foo' assert { type: /* before */ 'json' }\n\t\t\t\timport 'foo' assert { type: 'json' /* before */ }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tExact: map[string]bool{\"foo\": true},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestCommentPreservationTransformJSX(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\tconsole.log(\n\t\t\t\t\t<div x={/*before*/x} />,\n\t\t\t\t\t<div x={/*before*/'y'} />,\n\t\t\t\t\t<div x={/*before*/true} />,\n\t\t\t\t\t<div {/*before*/...x} />,\n\t\t\t\t\t<div>{/*before*/x}</div>,\n\t\t\t\t\t<>{/*before*/x}</>,\n\n\t\t\t\t\t// Comments on absent AST nodes\n\t\t\t\t\t<div>before{}after</div>,\n\t\t\t\t\t<div>before{/* comment 1 *//* comment 2 */}after</div>,\n\t\t\t\t\t<div>before{\n\t\t\t\t\t\t// comment 1\n\t\t\t\t\t\t// comment 2\n\t\t\t\t\t}after</div>,\n\t\t\t\t\t<>before{}after</>,\n\t\t\t\t\t<>before{/* comment 1 *//* comment 2 */}after</>,\n\t\t\t\t\t<>before{\n\t\t\t\t\t\t// comment 1\n\t\t\t\t\t\t// comment 2\n\t\t\t\t\t}after</>,\n\t\t\t\t)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestCommentPreservationPreserveJSX(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\tconsole.log(\n\t\t\t\t\t<div x={/*before*/x} />,\n\t\t\t\t\t<div x={/*before*/'y'} />,\n\t\t\t\t\t<div x={/*before*/true} />,\n\t\t\t\t\t<div {/*before*/...x} />,\n\t\t\t\t\t<div>{/*before*/x}</div>,\n\t\t\t\t\t<>{/*before*/x}</>,\n\n\t\t\t\t\t// Comments on absent AST nodes\n\t\t\t\t\t<div>before{}after</div>,\n\t\t\t\t\t<div>before{/* comment 1 *//* comment 2 */}after</div>,\n\t\t\t\t\t<div>before{\n\t\t\t\t\t\t// comment 1\n\t\t\t\t\t\t// comment 2\n\t\t\t\t\t}after</div>,\n\t\t\t\t\t<>before{}after</>,\n\t\t\t\t\t<>before{/* comment 1 *//* comment 2 */}after</>,\n\t\t\t\t\t<>before{\n\t\t\t\t\t\t// comment 1\n\t\t\t\t\t\t// comment 2\n\t\t\t\t\t}after</>,\n\t\t\t\t)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tPreserve: true,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestErrorMessageCrashStdinIssue2913(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/node_modules/fflate/package.json\": `{ \"main\": \"main.js\" }`,\n\t\t\t\"/project/node_modules/fflate/main.js\":      ``,\n\t\t},\n\t\toptions: config.Options{\n\t\t\tStdin: &config.StdinInfo{\n\t\t\t\tContents:      `import \"node_modules/fflate\"`,\n\t\t\t\tAbsResolveDir: \"/project\",\n\t\t\t},\n\t\t\tMode:         config.ModeBundle,\n\t\t\tPlatform:     config.PlatformNeutral,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedScanLog: `<stdin>: ERROR: Could not resolve \"node_modules/fflate\"\nNOTE: You can mark the path \"node_modules/fflate\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestLineLimitNotMinified(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/script.jsx\": `\n\t\t\t\timport fileURL from './x.file'\n\t\t\t\timport copyURL from './x.copy'\n\t\t\t\timport dataURL from './x.data'\n\t\t\t\texport const SignUpForm = (props) => {\n\t\t\t\t\treturn <p class=\"signup\">\n\t\t\t\t\t\t<label>Username: <input class=\"username\" type=\"text\"/></label>\n\t\t\t\t\t\t<label>Password: <input class=\"password\" type=\"password\"/></label>\n\t\t\t\t\t\t<div class=\"primary disabled\">\n\t\t\t\t\t\t\t{props.buttonText}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<small>By signing up, you are agreeing to our <a href=\"/tos/\">terms of service</a>.</small>\n\t\t\t\t\t\t<img src={fileURL} />\n\t\t\t\t\t\t<img src={copyURL} />\n\t\t\t\t\t\t<img src={dataURL} />\n\t\t\t\t\t</p>\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/style.css\": `\n\t\t\t\tbody.light-mode.new-user-segment:not(.logged-in) .signup,\n\t\t\t\tbody.light-mode.new-user-segment:not(.logged-in) .login {\n\t\t\t\t\tfont: 10px/12px 'Font 1', 'Font 2', 'Font 3', 'Font 4', sans-serif;\n\t\t\t\t\tuser-select: none;\n\t\t\t\t\tcolor: var(--fg, rgba(11, 22, 33, 0.5));\n\t\t\t\t\tbackground: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgeG1sb` +\n\t\t\t\t`nM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8Y2lyY2xlIGN4PSIxMDAiIGN5PSIxMDAiIHI9IjEwM` +\n\t\t\t\t`CIgZmlsbD0iI0ZGQ0YwMCIvPgogIDxwYXRoIGQ9Ik00Ny41IDUyLjVMOTUgMTAwbC00Ny41IDQ3LjVtNjAtOTVMM` +\n\t\t\t\t`TU1IDEwMGwtNDcuNSA0Ny41IiBmaWxsPSJub25lIiBzdHJva2U9IiMxOTE5MTkiIHN0cm9rZS13aWR0aD0iMjQiL` +\n\t\t\t\t`z4KPC9zdmc+Cg==);\n\t\t\t\t\tcursor: url(x.file);\n\t\t\t\t\tcursor: url(x.copy);\n\t\t\t\t\tcursor: url(x.data);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/x.file\": `...file...`,\n\t\t\t\"/x.copy\": `...copy...`,\n\t\t\t\"/x.data\": `...lots of long data...lots of long data...`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/script.jsx\",\n\t\t\t\"/style.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tLineLimit:    32,\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".jsx\":  config.LoaderJSX,\n\t\t\t\t\".css\":  config.LoaderCSS,\n\t\t\t\t\".file\": config.LoaderFile,\n\t\t\t\t\".copy\": config.LoaderCopy,\n\t\t\t\t\".data\": config.LoaderDataURL,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLineLimitMinified(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/script.jsx\": `\n\t\t\t\texport const SignUpForm = (props) => {\n\t\t\t\t\treturn <p class=\"signup\">\n\t\t\t\t\t\t<label>Username: <input class=\"username\" type=\"text\"/></label>\n\t\t\t\t\t\t<label>Password: <input class=\"password\" type=\"password\"/></label>\n\t\t\t\t\t\t<div class=\"primary disabled\">\n\t\t\t\t\t\t\t{props.buttonText}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<small>By signing up, you are agreeing to our <a href=\"/tos/\">terms of service</a>.</small>\n\t\t\t\t\t</p>\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/style.css\": `\n\t\t\t\tbody.light-mode.new-user-segment:not(.logged-in) .signup,\n\t\t\t\tbody.light-mode.new-user-segment:not(.logged-in) .login {\n\t\t\t\t\tfont: 10px/12px 'Font 1', 'Font 2', 'Font 3', 'Font 4', sans-serif;\n\t\t\t\t\tuser-select: none;\n\t\t\t\t\tcolor: var(--fg, rgba(11, 22, 33, 0.5));\n\t\t\t\t\tbackground: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgeG1sb` +\n\t\t\t\t`nM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8Y2lyY2xlIGN4PSIxMDAiIGN5PSIxMDAiIHI9IjEwM` +\n\t\t\t\t`CIgZmlsbD0iI0ZGQ0YwMCIvPgogIDxwYXRoIGQ9Ik00Ny41IDUyLjVMOTUgMTAwbC00Ny41IDQ3LjVtNjAtOTVMM` +\n\t\t\t\t`TU1IDEwMGwtNDcuNSA0Ny41IiBmaWxsPSJub25lIiBzdHJva2U9IiMxOTE5MTkiIHN0cm9rZS13aWR0aD0iMjQiL` +\n\t\t\t\t`z4KPC9zdmc+Cg==);\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/script.jsx\",\n\t\t\t\"/style.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tAbsOutputDir:     \"/out\",\n\t\t\tLineLimit:        32,\n\t\t\tMinifyWhitespace: true,\n\t\t},\n\t})\n}\n\nfunc TestBadImportErrorMessageWithHandlesImportErrorsFlag(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport('foo')\n\t\t\t\timport('foo')\n\t\t\t\timport('foo').catch()\n\t\t\t\timport('foo').catch()\n\n\t\t\t\timport('bar').catch()\n\t\t\t\timport('bar').catch()\n\t\t\t\timport('bar') // We should get an error report here even though the earlier imports have the \"HandlesImportErrors\" flag\n\t\t\t\timport('bar')\n\n\t\t\t\timport('baz').catch()\n\t\t\t\timport('baz').catch()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Could not resolve \"foo\"\nNOTE: You can mark the path \"foo\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. You can also add \".catch()\" here to handle this failure at run-time instead of bundle-time.\nentry.js: ERROR: Could not resolve \"bar\"\nNOTE: You can mark the path \"bar\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. You can also add \".catch()\" here to handle this failure at run-time instead of bundle-time.\n`,\n\t})\n}\n\nfunc TestDecoratorPrintingESM(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport { constant } from './constants'\n\t\t\t\timport { imported } from 'somewhere'\n\t\t\t\timport { undef } from './empty'\n\n\t\t\t\t_ = class Outer {\n\t\t\t\t\t#bar;\n\n\t\t\t\t\tclasses = [\n\t\t\t\t\t\tclass { @imported @imported() imported },\n\t\t\t\t\t\tclass { @unbound @unbound() unbound },\n\t\t\t\t\t\tclass { @constant @constant() constant },\n\t\t\t\t\t\tclass { @undef @undef() undef },\n\n\t\t\t\t\t\tclass { @(element[access]) indexed },\n\t\t\t\t\t\tclass { @foo.#bar private },\n\t\t\t\t\t\tclass { @foo.\\u30FF unicode },\n\t\t\t\t\t\tclass { @(() => {}) arrow },\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/constants.js\": `\n\t\t\t\texport const constant = 123\n\t\t\t`,\n\t\t\t\"/empty.js\": ``,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:             config.ModeBundle,\n\t\t\tOutputFormat:     config.FormatESModule,\n\t\t\tAbsOutputFile:    \"/out.js\",\n\t\t\tExternalPackages: true,\n\t\t\tMinifySyntax:     true,\n\t\t},\n\t\texpectedCompileLog: `entry.js: WARNING: Import \"undef\" will always be undefined because the file \"empty.js\" has no exports\n`,\n\t})\n}\n\nfunc TestDecoratorPrintingCJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport { constant } from './constants'\n\t\t\t\timport { imported } from 'somewhere'\n\t\t\t\timport { undef } from './empty'\n\n\t\t\t\t_ = class Outer {\n\t\t\t\t\t#bar;\n\n\t\t\t\t\tclasses = [\n\t\t\t\t\t\tclass { @imported @imported() imported },\n\t\t\t\t\t\tclass { @unbound @unbound() unbound },\n\t\t\t\t\t\tclass { @constant @constant() constant },\n\t\t\t\t\t\tclass { @undef @undef() undef },\n\n\t\t\t\t\t\tclass { @(element[access]) indexed },\n\t\t\t\t\t\tclass { @foo.#bar private },\n\t\t\t\t\t\tclass { @foo.\\u30FF unicode },\n\t\t\t\t\t\tclass { @(() => {}) arrow },\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/constants.js\": `\n\t\t\t\texport const constant = 123\n\t\t\t`,\n\t\t\t\"/empty.js\": ``,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:             config.ModeBundle,\n\t\t\tOutputFormat:     config.FormatCommonJS,\n\t\t\tAbsOutputFile:    \"/out.js\",\n\t\t\tExternalPackages: true,\n\t\t\tMinifySyntax:     true,\n\t\t},\n\t\texpectedCompileLog: `entry.js: WARNING: Import \"undef\" will always be undefined because the file \"empty.js\" has no exports\n`,\n\t})\n}\n\n// React's development-mode transform has a special \"__self\" value that's sort\n// of supposed to be set to \"this\". Except there's no specification for it\n// AFAIK and the value of \"this\" isn't always allowed to be accessed. For\n// example, accessing it before \"super()\" in a constructor call will crash.\n//\n// From what I understand the React team wanted to have it in case they need it\n// for some run-time warnings, but having it be accurate in all cases doesn't\n// really matter. For example, I'm not sure if it needs to even be any value in\n// particular for top-level JSX elements (top-level \"this\" can technically be\n// the module's exports object, which could materialize a lot of code to\n// generate one when bundling, so Facebook probably doesn't want that to\n// happen?).\n//\n// Anyway, this test case documents what esbuild does in case a specification\n// is produced in the future and it turns out esbuild should be doing something\n// else.\nfunc TestJSXDevSelfEdgeCases(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/function-this.jsx\":             `export function Foo() { return <div/> }`,\n\t\t\t\"/class-this.jsx\":                `export class Foo { foo() { return <div/> } }`,\n\t\t\t\"/normal-constructor.jsx\":        `export class Foo { constructor() { this.foo = <div/> } }`,\n\t\t\t\"/derived-constructor.jsx\":       `export class Foo extends Object { constructor() { super(<div/>); this.foo = <div/> } }`,\n\t\t\t\"/normal-constructor-arg.jsx\":    `export class Foo { constructor(foo = <div/>) {} }`,\n\t\t\t\"/derived-constructor-arg.jsx\":   `export class Foo extends Object { constructor(foo = <div/>) { super() } }`,\n\t\t\t\"/normal-constructor-field.tsx\":  `export class Foo { foo = <div/> }`,\n\t\t\t\"/derived-constructor-field.tsx\": `export class Foo extends Object { foo = <div/> }`,\n\t\t\t\"/static-field.jsx\":              `export class Foo { static foo = <div/> }`,\n\t\t\t\"/top-level-this-esm.jsx\":        `export let foo = <div/>; if (Foo) { foo = <Foo>nested top-level this</Foo> }`,\n\t\t\t\"/top-level-this-cjs.jsx\":        `exports.foo = <div/>`,\n\t\t\t\"/typescript-namespace.tsx\":      `export namespace Foo { export let foo = <div/> }`,\n\t\t\t\"/typescript-enum.tsx\":           `export enum Foo { foo = <div/> }`,\n\t\t\t\"/tsconfig.json\":                 `{ \"compilerOptions\": { \"useDefineForClassFields\": false } }`,\n\t\t},\n\t\tentryPaths: []string{\"*\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tAutomaticRuntime: true,\n\t\t\t\tDevelopment:      true,\n\t\t\t},\n\t\t\tUnsupportedJSFeatures: compat.ClassStaticField,\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tExact: map[string]bool{\n\t\t\t\t\t\t\"react/jsx-dev-runtime\": true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestObjectLiteralProtoSetterEdgeCases(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/local-shorthand.js\": `\n\t\t\t\tfunction foo(__proto__, bar) {\n\t\t\t\t\t{\n\t\t\t\t\t\tlet __proto__, bar // These locals will be renamed\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t'this must not become \"{ __proto__: ... }\":',\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t__proto__,\n\t\t\t\t\t\t\t\tbar,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/local-normal.js\": `\n\t\t\t\tfunction foo(__proto__, bar) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t'this must not become \"{ __proto__ }\":',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t__proto__: __proto__,\n\t\t\t\t\t\t\tbar: bar,\n\t\t\t\t\t\t},\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/import-shorthand.js\": `\n\t\t\t\timport { __proto__, bar } from 'foo'\n\t\t\t\tfunction foo() {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t'this must not become \"{ __proto__: ... }\":',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t__proto__,\n\t\t\t\t\t\t\tbar,\n\t\t\t\t\t\t},\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/import-normal.js\": `\n\t\t\t\timport { __proto__, bar } from 'foo'\n\t\t\t\tfunction foo() {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t'this must not become \"{ __proto__ }\":',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t__proto__: __proto__,\n\t\t\t\t\t\t\tbar: bar,\n\t\t\t\t\t\t},\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"*\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestObjectLiteralProtoSetterEdgeCasesMinifySyntax(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/local-computed.js\": `\n\t\t\t\tfunction foo(__proto__, bar) {\n\t\t\t\t\t{\n\t\t\t\t\t\tlet __proto__, bar // These locals will be renamed\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t'this must not become \"{ __proto__: ... }\":',\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t['__proto__']: __proto__,\n\t\t\t\t\t\t\t\t['bar']: bar,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/local-normal.js\": `\n\t\t\t\tfunction foo(__proto__, bar) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t'this must not become \"{ __proto__ }\":',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t__proto__: __proto__,\n\t\t\t\t\t\t\tbar: bar,\n\t\t\t\t\t\t},\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/import-computed.js\": `\n\t\t\t\timport { __proto__, bar } from 'foo'\n\t\t\t\tfunction foo() {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t'this must not become \"{ __proto__: ... }\":',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t['__proto__']: __proto__,\n\t\t\t\t\t\t\t['bar']: bar,\n\t\t\t\t\t\t},\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/import-normal.js\": `\n\t\t\t\timport { __proto__, bar } from 'foo'\n\t\t\t\tfunction foo() {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t'this must not become \"{ __proto__ }\":',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t__proto__: __proto__,\n\t\t\t\t\t\t\tbar: bar,\n\t\t\t\t\t\t},\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"*\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tMinifySyntax: true,\n\t\t},\n\t})\n}\n\nfunc TestForbidStringImportNamesNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport { \"an import\" as anImport } from \"./foo\"\n\t\t\t\texport { \"another import\" as \"an export\" } from \"./foo\"\n\t\t\t\tanImport()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.ArbitraryModuleNamespaceNames,\n\t\t},\n\t\texpectedCompileLog: `entry.js: ERROR: Using the string \"an import\" as an import name is not supported in the configured target environment\nentry.js: ERROR: Using the string \"another import\" as an import name is not supported in the configured target environment\nentry.js: ERROR: Using the string \"an export\" as an export name is not supported in the configured target environment\n`,\n\t})\n}\n\nfunc TestForbidStringExportNamesNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tlet ok = true\n\t\t\t\texport { ok as \"ok\", ok as \"not ok\" }\n\t\t\t\texport { \"same name\" } from \"./foo\"\n\t\t\t\texport { \"name 1\" as \"name 2\" } from \"./foo\"\n\t\t\t\texport * as \"name space\" from \"./foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.ArbitraryModuleNamespaceNames,\n\t\t},\n\t\texpectedCompileLog: `entry.js: ERROR: Using the string \"not ok\" as an export name is not supported in the configured target environment\nentry.js: ERROR: Using the string \"same name\" as an import name is not supported in the configured target environment\nentry.js: ERROR: Using the string \"name 1\" as an import name is not supported in the configured target environment\nentry.js: ERROR: Using the string \"name 2\" as an export name is not supported in the configured target environment\nentry.js: ERROR: Using the string \"name space\" as an export name is not supported in the configured target environment\n`,\n\t})\n}\n\nfunc TestForbidStringImportNamesBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport { \"nest ed\" as nested } from \"./nested.js\"\n\t\t\t\texport { nested }\n\t\t\t`,\n\t\t\t\"/nested.js\": `\n\t\t\t\timport { \"some import\" as nested } from \"external\"\n\t\t\t\texport { nested as \"nest ed\" }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.ArbitraryModuleNamespaceNames,\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"external\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t\texpectedCompileLog: `nested.js: ERROR: Using the string \"some import\" as an import name is not supported in the configured target environment\n`,\n\t})\n}\n\nfunc TestForbidStringExportNamesBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport { \"o.k.\" as ok } from \"./internal.js\"\n\t\t\t\texport { ok as \"ok\", ok as \"not ok\" }\n\t\t\t\texport * from \"./nested.js\"\n\t\t\t\texport * as \"name space\" from \"./nested.js\"\n\t\t\t`,\n\t\t\t\"/internal.js\": `\n\t\t\t\tlet ok = true\n\t\t\t\texport { ok as \"o.k.\" }\n\t\t\t`,\n\t\t\t\"/nested.js\": `\n\t\t\t\texport * from \"./very-nested.js\"\n\t\t\t\tlet nested = 1\n\t\t\t\texport { nested as \"nested name\" }\n\t\t\t`,\n\t\t\t\"/very-nested.js\": `\n\t\t\t\tlet nested = 2\n\t\t\t\texport { nested as \"very nested name\" }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.ArbitraryModuleNamespaceNames,\n\t\t},\n\t\texpectedCompileLog: `entry.js: ERROR: Using the string \"not ok\" as an export name is not supported in the configured target environment\nentry.js: ERROR: Using the string \"name space\" as an export name is not supported in the configured target environment\nnested.js: ERROR: Using the string \"nested name\" as an export name is not supported in the configured target environment\nvery-nested.js: ERROR: Using the string \"very nested name\" as an export name is not supported in the configured target environment\n`,\n\t})\n}\n\nfunc TestInjectWithStringExportNameNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(test)\n\t\t\t`,\n\t\t\t\"/inject.js\": `\n\t\t\t\tconst old = console.log\n\t\t\t\tconst fn = (...args) => old.apply(console, ['log:'].concat(args))\n\t\t\t\texport { fn as \"console.log\" }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tInjectPaths:           []string{\"/inject.js\"},\n\t\t\tUnsupportedJSFeatures: compat.ArbitraryModuleNamespaceNames,\n\t\t},\n\t})\n}\n\nfunc TestInjectWithStringExportNameBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(test)\n\t\t\t\tconsole.info(test)\n\t\t\t\tconsole.warn(test)\n\t\t\t`,\n\t\t\t\"/inject.js\": `\n\t\t\t\tconst old = console.log\n\t\t\t\tconst fn = (...args) => old.apply(console, ['log:'].concat(args))\n\t\t\t\texport { fn as \"console.log\" }\n\t\t\t\texport { \"console.log\" as \"console.info\" } from \"./inject.js\"\n\t\t\t\timport { \"console.info\" as info } from \"./inject.js\"\n\t\t\t\texport { info as \"console.warn\" }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tInjectPaths:           []string{\"/inject.js\"},\n\t\t\tUnsupportedJSFeatures: compat.ArbitraryModuleNamespaceNames,\n\t\t},\n\t})\n}\n\nfunc TestInjectWithStringReExportNameNoBundle(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(test)\n\t\t\t`,\n\t\t\t\"/inject.js\": `\n\t\t\t\texport { fn as \"console.log\" } from 'pkg'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tInjectPaths:           []string{\"/inject.js\"},\n\t\t\tUnsupportedJSFeatures: compat.ArbitraryModuleNamespaceNames,\n\t\t},\n\t})\n}\n\nfunc TestStringExportNamesCommonJS(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport { \"some import\" as someImport } from \"./foo\"\n\t\t\t\texport { someImport as \"some export\" }\n\t\t\t\texport * as \"all the stuff\" from \"./foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeConvertFormat,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tOutputFormat:          config.FormatCommonJS,\n\t\t\tUnsupportedJSFeatures: compat.ArbitraryModuleNamespaceNames,\n\t\t},\n\t})\n}\n\nfunc TestStringExportNamesIIFE(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport { \"some import\" as someImport } from \"./foo\"\n\t\t\t\texport { someImport as \"some export\" }\n\t\t\t\texport * as \"all the stuff\" from \"./foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeConvertFormat,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tOutputFormat:          config.FormatIIFE,\n\t\t\tUnsupportedJSFeatures: compat.ArbitraryModuleNamespaceNames,\n\t\t\tGlobalName:            []string{\"global\", \"name\"},\n\t\t},\n\t})\n}\n\nfunc TestSourceIdentifierNameIndexSingleEntry(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t// Generate identifier names for top-level and nested files\n\t\t\t\"/Users/user/project/index.js\": `\n\t\t\t\trequire('.')\n\t\t\t\trequire('pkg')\n\t\t\t\trequire('./nested')\n\t\t\t`,\n\t\t\t\"/Users/user/project/nested/index.js\":           `exports.nested = true`,\n\t\t\t\"/Users/user/project/node_modules/pkg/index.js\": `exports.pkg = true`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/index.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t},\n\t})\n}\n\nfunc TestSourceIdentifierNameIndexMultipleEntry(t *testing.T) {\n\tdefault_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t// Generate identifier names for top-level and nested files\n\t\t\t\"/Users/user/project/home/index.js\": `\n\t\t\t\trequire('.')\n\t\t\t\trequire('pkg')\n\t\t\t\trequire('../common')\n\t\t\t`,\n\t\t\t\"/Users/user/project/about/index.js\": `\n\t\t\t\trequire('.')\n\t\t\t\trequire('pkg')\n\t\t\t\trequire('../common')\n\t\t\t`,\n\t\t\t\"/Users/user/project/common/index.js\":           `exports.common = true`,\n\t\t\t\"/Users/user/project/node_modules/pkg/index.js\": `exports.pkg = true`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/Users/user/project/home/index.js\",\n\t\t\t\"/Users/user/project/about/index.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t},\n\t})\n}\n\nfunc TestResolveExtensionsOrderIssue4053(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport test from \"./Test\"\n\t\t\t\timport image from \"expo-image\"\n\t\t\t\tconsole.log(test === 'Test.web.tsx')\n\t\t\t\tconsole.log(image === 'Image.web.tsx')\n\t\t\t`,\n\t\t\t\"/Test.web.tsx\": `export default 'Test.web.tsx'`,\n\t\t\t\"/Test.tsx\":     `export default 'Test.tsx'`,\n\t\t\t\"/node_modules/expo-image/index.js\": `\n\t\t\t\texport { default } from \"./Image\"\n\t\t\t`,\n\t\t\t\"/node_modules/expo-image/Image.web.tsx\": `export default 'Image.web.tsx'`,\n\t\t\t\"/node_modules/expo-image/Image.tsx\":     `export default 'Image.tsx'`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionOrder: []string{\n\t\t\t\t\".web.mjs\",\n\t\t\t\t\".mjs\",\n\t\t\t\t\".web.js\",\n\t\t\t\t\".js\",\n\t\t\t\t\".web.mts\",\n\t\t\t\t\".mts\",\n\t\t\t\t\".web.ts\",\n\t\t\t\t\".ts\",\n\t\t\t\t\".web.jsx\",\n\t\t\t\t\".jsx\",\n\t\t\t\t\".web.tsx\",\n\t\t\t\t\".tsx\",\n\t\t\t\t\".json\",\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestBundleESMWithNestedVarIssue4348(t *testing.T) {\n\tcss_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\trequire('./foo')\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\tvar a = 'a'\n\t\t\t\tfor (var b = 'b'; 0; ) ;\n\t\t\t\tif (true) { var c = 'c' }\n\t\t\t\tif (true) var d = 'd'\n\t\t\t\tif (false) {} else var e = 'e'\n\t\t\t\tvar x = 1\n\t\t\t\twhile (x--) var f = 'f'\n\t\t\t\tdo var g = 'g'; while (0);\n\t\t\t\tfor (; x++; ) var h = 'h'\n\t\t\t\tfor (var y in 'y') var i = 'i'\n\t\t\t\tfor (var y of 'y') var j = 'j'\n\t\t\t\texport { a, b, c, d, e, f, g, h, i, j }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "internal/bundler_tests/bundler_glob_test.go",
    "content": "package bundler_tests\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/config\"\n)\n\nvar glob_suite = suite{\n\tname: \"glob\",\n}\n\nfunc TestGlobBasicNoBundle(t *testing.T) {\n\tglob_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst ab = Math.random() < 0.5 ? 'a.js' : 'b.js'\n\t\t\t\tconsole.log({\n\t\t\t\t\tconcat: {\n\t\t\t\t\t\trequire: require('./src/' + ab),\n\t\t\t\t\t\timport: import('./src/' + ab),\n\t\t\t\t\t},\n\t\t\t\t\ttemplate: {\n\t\t\t\t\t\trequire: require(` + \"`./src/${ab}`\" + `),\n\t\t\t\t\t\timport: import(` + \"`./src/${ab}`\" + `),\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestGlobBasicNoSplitting(t *testing.T) {\n\tglob_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst ab = Math.random() < 0.5 ? 'a.js' : 'b.js'\n\t\t\t\tconsole.log({\n\t\t\t\t\tconcat: {\n\t\t\t\t\t\trequire: require('./src/' + ab),\n\t\t\t\t\t\timport: import('./src/' + ab),\n\t\t\t\t\t},\n\t\t\t\t\ttemplate: {\n\t\t\t\t\t\trequire: require(` + \"`./src/${ab}`\" + `),\n\t\t\t\t\t\timport: import(` + \"`./src/${ab}`\" + `),\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t`,\n\t\t\t\"/src/a.js\": `module.exports = 'a'`,\n\t\t\t\"/src/b.js\": `module.exports = 'b'`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSGlobBasicNoSplitting(t *testing.T) {\n\tglob_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tconst ab = Math.random() < 0.5 ? 'a.ts' : 'b.ts'\n\t\t\t\tconsole.log({\n\t\t\t\t\tconcat: {\n\t\t\t\t\t\trequire: require('./src/' + ab),\n\t\t\t\t\t\timport: import('./src/' + ab),\n\t\t\t\t\t},\n\t\t\t\t\ttemplate: {\n\t\t\t\t\t\trequire: require(` + \"`./src/${ab}`\" + `),\n\t\t\t\t\t\timport: import(` + \"`./src/${ab}`\" + `),\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t`,\n\t\t\t\"/src/a.ts\": `module.exports = 'a'`,\n\t\t\t\"/src/b.ts\": `module.exports = 'b'`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestGlobBasicSplitting(t *testing.T) {\n\tglob_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst ab = Math.random() < 0.5 ? 'a.js' : 'b.js'\n\t\t\t\tconsole.log({\n\t\t\t\t\tconcat: {\n\t\t\t\t\t\trequire: require('./src/' + ab),\n\t\t\t\t\t\timport: import('./src/' + ab),\n\t\t\t\t\t},\n\t\t\t\t\ttemplate: {\n\t\t\t\t\t\trequire: require(` + \"`./src/${ab}`\" + `),\n\t\t\t\t\t\timport: import(` + \"`./src/${ab}`\" + `),\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t`,\n\t\t\t\"/src/a.js\": `module.exports = 'a'`,\n\t\t\t\"/src/b.js\": `module.exports = 'b'`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tCodeSplitting: true,\n\t\t},\n\t})\n}\n\nfunc TestTSGlobBasicSplitting(t *testing.T) {\n\tglob_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tconst ab = Math.random() < 0.5 ? 'a.ts' : 'b.ts'\n\t\t\t\tconsole.log({\n\t\t\t\t\tconcat: {\n\t\t\t\t\t\trequire: require('./src/' + ab),\n\t\t\t\t\t\timport: import('./src/' + ab),\n\t\t\t\t\t},\n\t\t\t\t\ttemplate: {\n\t\t\t\t\t\trequire: require(` + \"`./src/${ab}`\" + `),\n\t\t\t\t\t\timport: import(` + \"`./src/${ab}`\" + `),\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t`,\n\t\t\t\"/src/a.ts\": `module.exports = 'a'`,\n\t\t\t\"/src/b.ts\": `module.exports = 'b'`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tCodeSplitting: true,\n\t\t},\n\t})\n}\n\nfunc TestGlobDirDoesNotExist(t *testing.T) {\n\tglob_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst ab = Math.random() < 0.5 ? 'a.js' : 'b.js'\n\t\t\t\tconsole.log({\n\t\t\t\t\tconcat: {\n\t\t\t\t\t\trequire: require('./src/' + ab),\n\t\t\t\t\t\timport: import('./src/' + ab),\n\t\t\t\t\t},\n\t\t\t\t\ttemplate: {\n\t\t\t\t\t\trequire: require(` + \"`./src/${ab}`\" + `),\n\t\t\t\t\t\timport: import(` + \"`./src/${ab}`\" + `),\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tCodeSplitting: true,\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Could not resolve require(\"./src/**/*\")\nentry.js: ERROR: Could not resolve import(\"./src/**/*\")\n`,\n\t})\n}\n\nfunc TestGlobNoMatches(t *testing.T) {\n\tglob_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst ab = Math.random() < 0.5 ? 'a.js' : 'b.js'\n\t\t\t\tconsole.log({\n\t\t\t\t\tconcat: {\n\t\t\t\t\t\trequire: require('./src/' + ab + '.json'),\n\t\t\t\t\t\timport: import('./src/' + ab + '.json'),\n\t\t\t\t\t},\n\t\t\t\t\ttemplate: {\n\t\t\t\t\t\trequire: require(` + \"`./src/${ab}.json`\" + `),\n\t\t\t\t\t\timport: import(` + \"`./src/${ab}.json`\" + `),\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t`,\n\t\t\t\"/src/dummy.js\": ``,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tCodeSplitting: true,\n\t\t},\n\t\texpectedScanLog: `entry.js: WARNING: The glob pattern require(\"./src/**/*.json\") did not match any files\nentry.js: WARNING: The glob pattern import(\"./src/**/*.json\") did not match any files\n`,\n\t})\n}\n\nfunc TestGlobEntryPointAbsPath(t *testing.T) {\n\tglob_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\tworks = true\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/**/*.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestGlobWildcardSlash(t *testing.T) {\n\tglob_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst ab = Math.random() < 0.5 ? 'a.js' : 'b.js'\n\t\t\t\tconsole.log({\n\t\t\t\t\tconcat: {\n\t\t\t\t\t\trequire: require('./src/' + ab + '.js'),\n\t\t\t\t\t\timport: import('./src/' + ab + '.js'),\n\t\t\t\t\t},\n\t\t\t\t\ttemplate: {\n\t\t\t\t\t\trequire: require(` + \"`./src/${ab}.js`\" + `),\n\t\t\t\t\t\timport: import(` + \"`./src/${ab}.js`\" + `),\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t`,\n\n\t\t\t\"/src/file-a.js\":     `module.exports = 'a'`,\n\t\t\t\"/src/file-b.js\":     `module.exports = 'b'`,\n\t\t\t\"/src/file-a.js.map\": `DO NOT BUNDLE`,\n\t\t\t\"/src/file-b.js.map\": `DO NOT BUNDLE`,\n\n\t\t\t\"/src/nested/dir/file-a.js\":     `module.exports = 'a'`,\n\t\t\t\"/src/nested/dir/file-b.js\":     `module.exports = 'b'`,\n\t\t\t\"/src/nested/dir/file-a.js.map\": `DO NOT BUNDLE`,\n\t\t\t\"/src/nested/dir/file-b.js.map\": `DO NOT BUNDLE`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestGlobWildcardNoSlash(t *testing.T) {\n\tglob_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst ab = Math.random() < 0.5 ? 'a.js' : 'b.js'\n\t\t\t\tconsole.log({\n\t\t\t\t\tconcat: {\n\t\t\t\t\t\trequire: require('./src/file-' + ab + '.js'),\n\t\t\t\t\t\timport: import('./src/file-' + ab + '.js'),\n\t\t\t\t\t},\n\t\t\t\t\ttemplate: {\n\t\t\t\t\t\trequire: require(` + \"`./src/file-${ab}.js`\" + `),\n\t\t\t\t\t\timport: import(` + \"`./src/file-${ab}.js`\" + `),\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t`,\n\n\t\t\t\"/src/file-a.js\":     `module.exports = 'a'`,\n\t\t\t\"/src/file-b.js\":     `module.exports = 'b'`,\n\t\t\t\"/src/file-a.js.map\": `DO NOT BUNDLE`,\n\t\t\t\"/src/file-b.js.map\": `DO NOT BUNDLE`,\n\n\t\t\t\"/src/nested/dir/file-a.js\":     `DO NOT BUNDLE`,\n\t\t\t\"/src/nested/dir/file-b.js\":     `DO NOT BUNDLE`,\n\t\t\t\"/src/nested/dir/file-a.js.map\": `DO NOT BUNDLE`,\n\t\t\t\"/src/nested/dir/file-b.js.map\": `DO NOT BUNDLE`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "internal/bundler_tests/bundler_importphase_test.go",
    "content": "package bundler_tests\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/config\"\n)\n\nvar importphase_suite = suite{\n\tname: \"importphase\",\n}\n\nfunc TestImportDeferExternalESM(t *testing.T) {\n\timportphase_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport defer * as foo0 from './foo.json'\n\t\t\t\timport defer * as foo1 from './foo.json' with { type: 'json' }\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tfoo0,\n\t\t\t\t\tfoo1,\n\t\t\t\t\timport.defer('./foo.json'),\n\t\t\t\t\timport.defer('./foo.json', { with: { type: 'json' } }),\n\t\t\t\t\timport.defer(` + \"`./${foo}.json`\" + `),\n\t\t\t\t\timport.defer(` + \"`./${foo}.json`\" + `, { with: { type: 'json' } }),\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tPatterns: []config.WildcardPattern{{Suffix: \".json\"}},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestImportDeferExternalCommonJS(t *testing.T) {\n\timportphase_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport defer * as foo0 from './foo.json'\n\t\t\t\timport defer * as foo1 from './foo.json' with { type: 'json' }\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tfoo0,\n\t\t\t\t\tfoo1,\n\t\t\t\t\timport.defer('./foo.json'),\n\t\t\t\t\timport.defer('./foo.json', { with: { type: 'json' } }),\n\t\t\t\t\timport.defer(` + \"`./${foo}.json`\" + `),\n\t\t\t\t\timport.defer(` + \"`./${foo}.json`\" + `, { with: { type: 'json' } }),\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tPatterns: []config.WildcardPattern{{Suffix: \".json\"}},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Bundling deferred imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"cjs\" output format is not supported\n`,\n\t})\n}\n\nfunc TestImportDeferExternalIIFE(t *testing.T) {\n\timportphase_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport defer * as foo0 from './foo.json'\n\t\t\t\timport defer * as foo1 from './foo.json' with { type: 'json' }\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tfoo0,\n\t\t\t\t\tfoo1,\n\t\t\t\t\timport.defer('./foo.json'),\n\t\t\t\t\timport.defer('./foo.json', { with: { type: 'json' } }),\n\t\t\t\t\timport.defer(` + \"`./${foo}.json`\" + `),\n\t\t\t\t\timport.defer(` + \"`./${foo}.json`\" + `, { with: { type: 'json' } }),\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tPatterns: []config.WildcardPattern{{Suffix: \".json\"}},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Bundling deferred imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"iife\" output format is not supported\n`,\n\t})\n}\n\nfunc TestImportDeferInternalESM(t *testing.T) {\n\timportphase_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport defer * as foo0 from './foo.json'\n\t\t\t\timport defer * as foo1 from './foo.json' with { type: 'json' }\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tfoo0,\n\t\t\t\t\tfoo1,\n\t\t\t\t\timport.defer('./foo.json'),\n\t\t\t\t\timport.defer('./foo.json', { with: { type: 'json' } }),\n\t\t\t\t\timport.defer(` + \"`./${foo}.json`\" + `),\n\t\t\t\t\timport.defer(` + \"`./${foo}.json`\" + `, { with: { type: 'json' } }),\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Bundling with deferred imports is not supported unless they are external\nentry.js: ERROR: Bundling with deferred imports is not supported unless they are external\nentry.js: ERROR: Bundling with deferred imports is not supported unless they are external\nentry.js: ERROR: Bundling with deferred imports is not supported unless they are external\nentry.js: ERROR: Bundling with deferred imports is not supported unless they are external\nentry.js: ERROR: Bundling with deferred imports is not supported unless they are external\n`,\n\t})\n}\n\nfunc TestImportDeferInternalCommonJS(t *testing.T) {\n\timportphase_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport defer * as foo0 from './foo.json'\n\t\t\t\timport defer * as foo1 from './foo.json' with { type: 'json' }\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tfoo0,\n\t\t\t\t\tfoo1,\n\t\t\t\t\timport.defer('./foo.json'),\n\t\t\t\t\timport.defer('./foo.json', { with: { type: 'json' } }),\n\t\t\t\t\timport.defer(` + \"`./${foo}.json`\" + `),\n\t\t\t\t\timport.defer(` + \"`./${foo}.json`\" + `, { with: { type: 'json' } }),\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Bundling deferred imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"cjs\" output format is not supported\n`,\n\t})\n}\n\nfunc TestImportDeferInternalIIFE(t *testing.T) {\n\timportphase_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport defer * as foo0 from './foo.json'\n\t\t\t\timport defer * as foo1 from './foo.json' with { type: 'json' }\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tfoo0,\n\t\t\t\t\tfoo1,\n\t\t\t\t\timport.defer('./foo.json'),\n\t\t\t\t\timport.defer('./foo.json', { with: { type: 'json' } }),\n\t\t\t\t\timport.defer(` + \"`./${foo}.json`\" + `),\n\t\t\t\t\timport.defer(` + \"`./${foo}.json`\" + `, { with: { type: 'json' } }),\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Bundling deferred imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling deferred imports with the \"iife\" output format is not supported\n`,\n\t})\n}\n\nfunc TestImportSourceExternalESM(t *testing.T) {\n\timportphase_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport source foo0 from './foo.json'\n\t\t\t\timport source foo1 from './foo.json' with { type: 'json' }\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tfoo0,\n\t\t\t\t\tfoo1,\n\t\t\t\t\timport.source('./foo.json'),\n\t\t\t\t\timport.source('./foo.json', { with: { type: 'json' } }),\n\t\t\t\t\timport.source(` + \"`./${foo}.json`\" + `),\n\t\t\t\t\timport.source(` + \"`./${foo}.json`\" + `, { with: { type: 'json' } }),\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tPatterns: []config.WildcardPattern{{Suffix: \".json\"}},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestImportSourceExternalCommonJS(t *testing.T) {\n\timportphase_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport source foo0 from './foo.json'\n\t\t\t\timport source foo1 from './foo.json' with { type: 'json' }\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tfoo0,\n\t\t\t\t\tfoo1,\n\t\t\t\t\timport.source('./foo.json'),\n\t\t\t\t\timport.source('./foo.json', { with: { type: 'json' } }),\n\t\t\t\t\timport.source(` + \"`./${foo}.json`\" + `),\n\t\t\t\t\timport.source(` + \"`./${foo}.json`\" + `, { with: { type: 'json' } }),\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tPatterns: []config.WildcardPattern{{Suffix: \".json\"}},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Bundling source phase imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"cjs\" output format is not supported\n`,\n\t})\n}\n\nfunc TestImportSourceExternalIIFE(t *testing.T) {\n\timportphase_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport source foo0 from './foo.json'\n\t\t\t\timport source foo1 from './foo.json' with { type: 'json' }\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tfoo0,\n\t\t\t\t\tfoo1,\n\t\t\t\t\timport.source('./foo.json'),\n\t\t\t\t\timport.source('./foo.json', { with: { type: 'json' } }),\n\t\t\t\t\timport.source(` + \"`./${foo}.json`\" + `),\n\t\t\t\t\timport.source(` + \"`./${foo}.json`\" + `, { with: { type: 'json' } }),\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tPatterns: []config.WildcardPattern{{Suffix: \".json\"}},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Bundling source phase imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"iife\" output format is not supported\n`,\n\t})\n}\n\nfunc TestImportSourceInternalESM(t *testing.T) {\n\timportphase_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport source foo0 from './foo.json'\n\t\t\t\timport source foo1 from './foo.json' with { type: 'json' }\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tfoo0,\n\t\t\t\t\tfoo1,\n\t\t\t\t\timport.source('./foo.json'),\n\t\t\t\t\timport.source('./foo.json', { with: { type: 'json' } }),\n\t\t\t\t\timport.source(` + \"`./${foo}.json`\" + `),\n\t\t\t\t\timport.source(` + \"`./${foo}.json`\" + `, { with: { type: 'json' } }),\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Bundling with source phase imports is not supported unless they are external\nentry.js: ERROR: Bundling with source phase imports is not supported unless they are external\nentry.js: ERROR: Bundling with source phase imports is not supported unless they are external\nentry.js: ERROR: Bundling with source phase imports is not supported unless they are external\nentry.js: ERROR: Bundling with source phase imports is not supported unless they are external\nentry.js: ERROR: Bundling with source phase imports is not supported unless they are external\n`,\n\t})\n}\n\nfunc TestImportSourceInternalCommonJS(t *testing.T) {\n\timportphase_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport source foo0 from './foo.json'\n\t\t\t\timport source foo1 from './foo.json' with { type: 'json' }\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tfoo0,\n\t\t\t\t\tfoo1,\n\t\t\t\t\timport.source('./foo.json'),\n\t\t\t\t\timport.source('./foo.json', { with: { type: 'json' } }),\n\t\t\t\t\timport.source(` + \"`./${foo}.json`\" + `),\n\t\t\t\t\timport.source(` + \"`./${foo}.json`\" + `, { with: { type: 'json' } }),\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Bundling source phase imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"cjs\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"cjs\" output format is not supported\n`,\n\t})\n}\n\nfunc TestImportSourceInternalIIFE(t *testing.T) {\n\timportphase_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport source foo0 from './foo.json'\n\t\t\t\timport source foo1 from './foo.json' with { type: 'json' }\n\n\t\t\t\tconsole.log(\n\t\t\t\t\tfoo0,\n\t\t\t\t\tfoo1,\n\t\t\t\t\timport.source('./foo.json'),\n\t\t\t\t\timport.source('./foo.json', { with: { type: 'json' } }),\n\t\t\t\t\timport.source(` + \"`./${foo}.json`\" + `),\n\t\t\t\t\timport.source(` + \"`./${foo}.json`\" + `, { with: { type: 'json' } }),\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Bundling source phase imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"iife\" output format is not supported\nentry.js: ERROR: Bundling source phase imports with the \"iife\" output format is not supported\n`,\n\t})\n}\n"
  },
  {
    "path": "internal/bundler_tests/bundler_importstar_test.go",
    "content": "package bundler_tests\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/config\"\n)\n\nvar importstar_suite = suite{\n\tname: \"importstar\",\n}\n\nfunc TestImportStarUnused(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarCapture(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarNoCapture(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns.foo, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarExportImportStarUnused(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {ns} from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\texport {ns}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarExportImportStarNoCapture(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {ns} from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns.foo, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\texport {ns}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarExportImportStarCapture(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {ns} from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\texport {ns}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarExportStarAsUnused(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {ns} from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport * as ns from './foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarExportStarAsNoCapture(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {ns} from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns.foo, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport * as ns from './foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarExportStarAsCapture(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {ns} from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport * as ns from './foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarExportStarUnused(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport * from './foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarExportStarNoCapture(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns.foo, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport * from './foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarExportStarCapture(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport * from './foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarCommonJSUnused(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texports.foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarCommonJSCapture(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texports.foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarCommonJSNoCapture(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns.foo, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texports.foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarAndCommonJS(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tconst ns2 = require('./foo')\n\t\t\t\tconsole.log(ns.foo, ns2.foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarNoBundleUnused(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarNoBundleCapture(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns, ns.foo, foo)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarNoBundleNoCapture(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns.foo, ns.foo, foo)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarMangleNoBundleUnused(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:  true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarMangleNoBundleCapture(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns, ns.foo, foo)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:  true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarMangleNoBundleNoCapture(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns.foo, ns.foo, foo)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:  true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarExportStarOmitAmbiguous(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './common'\n\t\t\t\tconsole.log(ns)\n\t\t\t`,\n\t\t\t\"/common.js\": `\n\t\t\t\texport * from './foo'\n\t\t\t\texport * from './bar'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const x = 1\n\t\t\t\texport const y = 2\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport const y = 3\n\t\t\t\texport const z = 4\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportExportStarAmbiguousError(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {x, y, z} from './common'\n\t\t\t\tconsole.log(x, y, z)\n\t\t\t`,\n\t\t\t\"/common.js\": `\n\t\t\t\texport * from './foo'\n\t\t\t\texport * from './bar'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const x = 1\n\t\t\t\texport const y = 2\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport const y = 3\n\t\t\t\texport const z = 4\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `entry.js: ERROR: Ambiguous import \"y\" has multiple matching exports\nfoo.js: NOTE: One matching export is here:\nbar.js: NOTE: Another matching export is here:\n`,\n\t})\n}\n\nfunc TestImportExportStarAmbiguousWarning(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './common'\n\t\t\t\tconsole.log(ns.x, ns.y, ns.z)\n\t\t\t`,\n\t\t\t\"/common.js\": `\n\t\t\t\texport * from './foo'\n\t\t\t\texport * from './bar'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const x = 1\n\t\t\t\texport const y = 2\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport const y = 3\n\t\t\t\texport const z = 4\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `entry.js: WARNING: Import \"y\" will always be undefined because there are multiple matching exports\nfoo.js: NOTE: One matching export is here:\nbar.js: NOTE: Another matching export is here:\n`,\n\t})\n}\n\nfunc TestReExportStarNameCollisionNotAmbiguousImport(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {x, y} from './common'\n\t\t\t\tconsole.log(x, y)\n\t\t\t`,\n\t\t\t\"/common.js\": `\n\t\t\t\texport * from './a'\n\t\t\t\texport * from './b'\n\t\t\t`,\n\t\t\t\"/a.js\": `\n\t\t\t\texport * from './c'\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\texport {x} from './c'\n\t\t\t`,\n\t\t\t\"/c.js\": `\n\t\t\t\texport let x = 1, y = 2\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestReExportStarNameCollisionNotAmbiguousExport(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * from './a'\n\t\t\t\texport * from './b'\n\t\t\t`,\n\t\t\t\"/a.js\": `\n\t\t\t\texport * from './c'\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\texport {x} from './c'\n\t\t\t`,\n\t\t\t\"/c.js\": `\n\t\t\t\texport let x = 1, y = 2\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestReExportStarNameShadowingNotAmbiguous(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {x} from './a'\n\t\t\t\tconsole.log(x)\n\t\t\t`,\n\t\t\t\"/a.js\": `\n\t\t\t\texport * from './b'\n\t\t\t\texport let x = 1\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\texport let x = 2\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestReExportStarNameShadowingNotAmbiguousReExport(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {x} from './a'\n\t\t\t\tconsole.log(x)\n\t\t\t`,\n\t\t\t\"/a.js\": `\n\t\t\t\texport * from './b'\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\texport * from './c'\n\t\t\t\texport let x = 1\n\t\t\t`,\n\t\t\t\"/c.js\": `\n\t\t\t\texport let x = 2\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportStarOfExportStarAs(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as foo_ns from './foo'\n\t\t\t\tconsole.log(foo_ns)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport * as bar_ns from './bar'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport const bar = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportOfExportStar(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {bar} from './foo'\n\t\t\t\tconsole.log(bar)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport * from './bar'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\t// Add some statements to increase the part index (this reproduced a crash)\n\t\t\t\tstatement()\n\t\t\t\tstatement()\n\t\t\t\tstatement()\n\t\t\t\tstatement()\n\t\t\t\texport const bar = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportOfExportStarOfImport(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {bar} from './foo'\n\t\t\t\tconsole.log(bar)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\t// Add some statements to increase the part index (this reproduced a crash)\n\t\t\t\tstatement()\n\t\t\t\tstatement()\n\t\t\t\tstatement()\n\t\t\t\tstatement()\n\t\t\t\texport * from './bar'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport {value as bar} from './baz'\n\t\t\t`,\n\t\t\t\"/baz.js\": `\n\t\t\t\texport const value = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportSelfIIFE(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\texport * from './entry'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportSelfIIFEWithName(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\texport * from './entry'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tGlobalName:    []string{\"someName\"},\n\t\t},\n\t})\n}\n\nfunc TestExportSelfES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\texport * from './entry'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportSelfCommonJS(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\texport * from './entry'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportSelfCommonJSMinified(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tmodule.exports = {foo: 123}\n\t\t\t\tconsole.log(require('./entry'))\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tMinifyIdentifiers: true,\n\t\t\tOutputFormat:      config.FormatCommonJS,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportSelfCommonJS(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texports.foo = 123\n\t\t\t\timport {foo} from './entry'\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportSelfAsNamespaceES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\texport * as ns from './entry'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportExportSelfAsNamespaceES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\timport * as ns from './entry'\n\t\t\t\texport {ns}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestReExportOtherFileExportSelfAsNamespaceES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * from './foo'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\texport * as ns from './foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestReExportOtherFileImportExportSelfAsNamespaceES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * from './foo'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\timport * as ns from './foo'\n\t\t\t\texport {ns}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestOtherFileExportSelfAsNamespaceUnusedES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {foo} from './foo'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\texport * as ns from './foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestOtherFileImportExportSelfAsNamespaceUnusedES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {foo} from './foo'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\timport * as ns from './foo'\n\t\t\t\texport {ns}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportSelfAsNamespaceCommonJS(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\texport * as ns from './entry'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportSelfAndRequireSelfCommonJS(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log(require('./entry'))\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportSelfAndImportSelfCommonJS(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as x from './entry'\n\t\t\t\texport const foo = 123\n\t\t\t\tconsole.log(x)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportOtherAsNamespaceCommonJS(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * as ns from './foo'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texports.foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportExportOtherAsNamespaceCommonJS(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\texport {ns}\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texports.foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestNamespaceImportMissingES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tconsole.log(ns, ns.foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `entry.js: WARNING: Import \"foo\" will always be undefined because there is no matching export in \"foo.js\"\n`,\n\t})\n}\n\nfunc TestExportOtherCommonJS(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {bar} from './foo'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texports.foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExportOtherNestedCommonJS(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {y} from './bar'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport {x as y} from './foo'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texports.foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestNamespaceImportUnusedMissingES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tconsole.log(ns.foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `entry.js: WARNING: Import \"foo\" will always be undefined because there is no matching export in \"foo.js\"\n`,\n\t})\n}\n\nfunc TestNamespaceImportMissingCommonJS(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tconsole.log(ns, ns.foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texports.x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestNamespaceImportUnusedMissingCommonJS(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tconsole.log(ns.foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texports.x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestReExportNamespaceImportMissingES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {ns} from './foo'\n\t\t\t\tconsole.log(ns, ns.foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport * as ns from './bar'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport const x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestReExportNamespaceImportUnusedMissingES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {ns} from './foo'\n\t\t\t\tconsole.log(ns.foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport * as ns from './bar'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport const x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestNamespaceImportReExportMissingES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tconsole.log(ns, ns.foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport {foo} from './bar'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport const x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `foo.js: ERROR: No matching export in \"bar.js\" for import \"foo\"\nfoo.js: ERROR: No matching export in \"bar.js\" for import \"foo\"\n`,\n\t})\n}\n\nfunc TestNamespaceImportReExportUnusedMissingES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tconsole.log(ns.foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport {foo} from './bar'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport const x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `foo.js: ERROR: No matching export in \"bar.js\" for import \"foo\"\nfoo.js: ERROR: No matching export in \"bar.js\" for import \"foo\"\n`,\n\t})\n}\n\nfunc TestNamespaceImportReExportStarMissingES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tconsole.log(ns, ns.foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport * from './bar'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport const x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `entry.js: WARNING: Import \"foo\" will always be undefined because there is no matching export in \"foo.js\"\n`,\n\t})\n}\n\nfunc TestNamespaceImportReExportStarUnusedMissingES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tconsole.log(ns.foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport * from './bar'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport const x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `entry.js: WARNING: Import \"foo\" will always be undefined because there is no matching export in \"foo.js\"\n`,\n\t})\n}\n\nfunc TestExportStarDefaultExportCommonJS(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * from './foo'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport default 'default' // This should not be picked up\n\t\t\t\texport let foo = 'foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestIssue176(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as things from './folders'\n\t\t\t\tconsole.log(JSON.stringify(things))\n\t\t\t`,\n\t\t\t\"/folders/index.js\": `\n\t\t\t\texport * from \"./child\"\n\t\t\t`,\n\t\t\t\"/folders/child/index.js\": `\n\t\t\t\texport { foo } from './foo'\n\t\t\t`,\n\t\t\t\"/folders/child/foo.js\": `\n\t\t\t\texport const foo = () => 'hi there'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestReExportStarExternalIIFE(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * from \"foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tGlobalName:    []string{\"mod\"},\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"foo\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestReExportStarExternalES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * from \"foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"foo\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestReExportStarExternalCommonJS(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * from \"foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"foo\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestReExportStarIIFENoBundle(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * from \"foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tGlobalName:    []string{\"mod\"},\n\t\t},\n\t})\n}\n\nfunc TestReExportStarES6NoBundle(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * from \"foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestReExportStarCommonJSNoBundle(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * from \"foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestReExportStarAsExternalIIFE(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * as out from \"foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tGlobalName:    []string{\"mod\"},\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"foo\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestReExportStarAsExternalES6(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * as out from \"foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"foo\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestReExportStarAsExternalCommonJS(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * as out from \"foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"foo\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestReExportStarAsIIFENoBundle(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * as out from \"foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tGlobalName:    []string{\"mod\"},\n\t\t},\n\t})\n}\n\nfunc TestReExportStarAsES6NoBundle(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * as out from \"foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestReExportStarAsCommonJSNoBundle(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * as out from \"foo\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestImportDefaultNamespaceComboIssue446(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/external-default2.js\": `\n\t\t\t\timport def, {default as default2} from 'external'\n\t\t\t\tconsole.log(def, default2)\n\t\t\t`,\n\t\t\t\"/external-ns.js\": `\n\t\t\t\timport def, * as ns from 'external'\n\t\t\t\tconsole.log(def, ns)\n\t\t\t`,\n\t\t\t\"/external-ns-default.js\": `\n\t\t\t\timport def, * as ns from 'external'\n\t\t\t\tconsole.log(def, ns, ns.default)\n\t\t\t`,\n\t\t\t\"/external-ns-def.js\": `\n\t\t\t\timport def, * as ns from 'external'\n\t\t\t\tconsole.log(def, ns, ns.def)\n\t\t\t`,\n\t\t\t\"/external-default.js\": `\n\t\t\t\timport def, * as ns from 'external'\n\t\t\t\tconsole.log(def, ns.default)\n\t\t\t`,\n\t\t\t\"/external-def.js\": `\n\t\t\t\timport def, * as ns from 'external'\n\t\t\t\tconsole.log(def, ns.def)\n\t\t\t`,\n\t\t\t\"/internal-default2.js\": `\n\t\t\t\timport def, {default as default2} from './internal'\n\t\t\t\tconsole.log(def, default2)\n\t\t\t`,\n\t\t\t\"/internal-ns.js\": `\n\t\t\t\timport def, * as ns from './internal'\n\t\t\t\tconsole.log(def, ns)\n\t\t\t`,\n\t\t\t\"/internal-ns-default.js\": `\n\t\t\t\timport def, * as ns from './internal'\n\t\t\t\tconsole.log(def, ns, ns.default)\n\t\t\t`,\n\t\t\t\"/internal-ns-def.js\": `\n\t\t\t\timport def, * as ns from './internal'\n\t\t\t\tconsole.log(def, ns, ns.def)\n\t\t\t`,\n\t\t\t\"/internal-default.js\": `\n\t\t\t\timport def, * as ns from './internal'\n\t\t\t\tconsole.log(def, ns.default)\n\t\t\t`,\n\t\t\t\"/internal-def.js\": `\n\t\t\t\timport def, * as ns from './internal'\n\t\t\t\tconsole.log(def, ns.def)\n\t\t\t`,\n\t\t\t\"/internal.js\": `\n\t\t\t\texport default 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/external-default2.js\",\n\t\t\t\"/external-ns.js\",\n\t\t\t\"/external-ns-default.js\",\n\t\t\t\"/external-ns-def.js\",\n\t\t\t\"/external-default.js\",\n\t\t\t\"/external-def.js\",\n\t\t\t\"/internal-default2.js\",\n\t\t\t\"/internal-ns.js\",\n\t\t\t\"/internal-ns-default.js\",\n\t\t\t\"/internal-ns-def.js\",\n\t\t\t\"/internal-default.js\",\n\t\t\t\"/internal-def.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"external\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t\texpectedCompileLog: `internal-def.js: WARNING: Import \"def\" will always be undefined because there is no matching export in \"internal.js\"\ninternal-ns-def.js: WARNING: Import \"def\" will always be undefined because there is no matching export in \"internal.js\"\n`,\n\t})\n}\n\nfunc TestImportDefaultNamespaceComboNoDefault(t *testing.T) {\n\t// Note: \"entry-dead.js\" checks that this warning doesn't happen for dead code\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry-default-ns-prop.js\": `import def, * as ns from './foo'; console.log(def, ns, ns.default)`,\n\t\t\t\"/entry-default-ns.js\":      `import def, * as ns from './foo'; console.log(def, ns)`,\n\t\t\t\"/entry-default-prop.js\":    `import def, * as ns from './foo'; console.log(def, ns.default)`,\n\t\t\t\"/entry-default.js\":         `import def from './foo'; console.log(def)`,\n\t\t\t\"/entry-prop.js\":            `import * as ns from './foo'; console.log(ns.default)`,\n\t\t\t\"/entry-dead.js\":            `import * as ns from './foo'; 0 && console.log(ns.default)`,\n\t\t\t\"/entry-typo.js\":            `import * as ns from './foo'; console.log(ns.buton)`,\n\t\t\t\"/entry-typo-indirect.js\":   `import * as ns from './indirect'; console.log(ns.buton)`,\n\t\t\t\"/foo.js\":                   `export let button = {}`,\n\t\t\t\"/indirect.js\":              `export * from './foo'`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry-default-ns-prop.js\",\n\t\t\t\"/entry-default-ns.js\",\n\t\t\t\"/entry-default-prop.js\",\n\t\t\t\"/entry-default.js\",\n\t\t\t\"/entry-prop.js\",\n\t\t\t\"/entry-dead.js\",\n\t\t\t\"/entry-typo.js\",\n\t\t\t\"/entry-typo-indirect.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedCompileLog: `entry-default-ns-prop.js: ERROR: No matching export in \"foo.js\" for import \"default\"\nentry-default-ns-prop.js: WARNING: Import \"default\" will always be undefined because there is no matching export in \"foo.js\"\nentry-default-ns.js: ERROR: No matching export in \"foo.js\" for import \"default\"\nentry-default-prop.js: ERROR: No matching export in \"foo.js\" for import \"default\"\nentry-default-prop.js: WARNING: Import \"default\" will always be undefined because there is no matching export in \"foo.js\"\nentry-default.js: ERROR: No matching export in \"foo.js\" for import \"default\"\nentry-prop.js: WARNING: Import \"default\" will always be undefined because there is no matching export in \"foo.js\"\nentry-typo-indirect.js: WARNING: Import \"buton\" will always be undefined because there is no matching export in \"indirect.js\"\nfoo.js: NOTE: Did you mean to import \"button\" instead?\nentry-typo.js: WARNING: Import \"buton\" will always be undefined because there is no matching export in \"foo.js\"\nfoo.js: NOTE: Did you mean to import \"button\" instead?\n`,\n\t})\n}\n\nfunc TestImportNamespaceUndefinedPropertyEmptyFile(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry-nope.js\": `\n\t\t\t\timport * as js from './empty.js'\n\t\t\t\timport * as mjs from './empty.mjs'\n\t\t\t\timport * as cjs from './empty.cjs'\n\t\t\t\tconsole.log(\n\t\t\t\t\tjs.nope,\n\t\t\t\t\tmjs.nope,\n\t\t\t\t\tcjs.nope,\n\t\t\t\t)\n\t\t\t`,\n\n\t\t\t// Note: For CommonJS-style modules, we automatically assign the exports\n\t\t\t// object to the \"default\" property if there is no property named \"default\".\n\t\t\t// This is for compatibility with node. So this test intentionally behaves\n\t\t\t// differently from the test above.\n\t\t\t\"/entry-default.js\": `\n\t\t\t\timport * as js from './empty.js'\n\t\t\t\timport * as mjs from './empty.mjs'\n\t\t\t\timport * as cjs from './empty.cjs'\n\t\t\t\tconsole.log(\n\t\t\t\t\tjs.default,\n\t\t\t\t\tmjs.default,\n\t\t\t\t\tcjs.default,\n\t\t\t\t)\n\t\t\t`,\n\n\t\t\t\"/empty.js\":  ``,\n\t\t\t\"/empty.mjs\": ``,\n\t\t\t\"/empty.cjs\": ``,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry-nope.js\",\n\t\t\t\"/entry-default.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedCompileLog: `entry-default.js: WARNING: Import \"default\" will always be undefined because there is no matching export in \"empty.mjs\"\nentry-nope.js: WARNING: Import \"nope\" will always be undefined because the file \"empty.js\" has no exports\nentry-nope.js: WARNING: Import \"nope\" will always be undefined because the file \"empty.mjs\" has no exports\nentry-nope.js: WARNING: Import \"nope\" will always be undefined because the file \"empty.cjs\" has no exports\n`,\n\t})\n}\n\nfunc TestImportNamespaceUndefinedPropertySideEffectFreeFile(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry-nope.js\": `\n\t\t\t\timport * as js from './foo/no-side-effects.js'\n\t\t\t\timport * as mjs from './foo/no-side-effects.mjs'\n\t\t\t\timport * as cjs from './foo/no-side-effects.cjs'\n\t\t\t\tconsole.log(\n\t\t\t\t\tjs.nope,\n\t\t\t\t\tmjs.nope,\n\t\t\t\t\tcjs.nope,\n\t\t\t\t)\n\t\t\t`,\n\n\t\t\t// Note: For CommonJS-style modules, we automatically assign the exports\n\t\t\t// object to the \"default\" property if there is no property named \"default\".\n\t\t\t// This is for compatibility with node. So this test intentionally behaves\n\t\t\t// differently from the test above.\n\t\t\t\"/entry-default.js\": `\n\t\t\t\timport * as js from './foo/no-side-effects.js'\n\t\t\t\timport * as mjs from './foo/no-side-effects.mjs'\n\t\t\t\timport * as cjs from './foo/no-side-effects.cjs'\n\t\t\t\tconsole.log(\n\t\t\t\t\tjs.default,\n\t\t\t\t\tmjs.default,\n\t\t\t\t\tcjs.default,\n\t\t\t\t)\n\t\t\t`,\n\n\t\t\t\"/foo/package.json\":        `{ \"sideEffects\": false }`,\n\t\t\t\"/foo/no-side-effects.js\":  `console.log('js')`,\n\t\t\t\"/foo/no-side-effects.mjs\": `console.log('mjs')`,\n\t\t\t\"/foo/no-side-effects.cjs\": `console.log('cjs')`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry-nope.js\",\n\t\t\t\"/entry-default.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedCompileLog: `entry-default.js: WARNING: Import \"default\" will always be undefined because there is no matching export in \"foo/no-side-effects.mjs\"\nentry-nope.js: WARNING: Import \"nope\" will always be undefined because the file \"foo/no-side-effects.js\" has no exports\nentry-nope.js: WARNING: Import \"nope\" will always be undefined because the file \"foo/no-side-effects.mjs\" has no exports\nentry-nope.js: WARNING: Import \"nope\" will always be undefined because the file \"foo/no-side-effects.cjs\" has no exports\n`,\n\t})\n}\n\n// Failure case due to a bug in https://github.com/evanw/esbuild/pull/2059\nfunc TestReExportStarEntryPointAndInnerFile(t *testing.T) {\n\timportstar_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * from 'a'\n\t\t\t\timport * as inner from './inner.js'\n\t\t\t\texport { inner }\n\t\t\t`,\n\t\t\t\"/inner.js\": `\n\t\t\t\texport * from 'b'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tOutputFormat: config.FormatCommonJS,\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tExact: map[string]bool{\n\t\t\t\t\t\t\"a\": true,\n\t\t\t\t\t\t\"b\": true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "internal/bundler_tests/bundler_importstar_ts_test.go",
    "content": "package bundler_tests\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/config\"\n)\n\nvar importstar_ts_suite = suite{\n\tname: \"importstar_ts\",\n}\n\nfunc TestTSImportStarUnused(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarCapture(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarNoCapture(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns.foo, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarExportImportStarUnused(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport {ns} from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.ts\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\texport {ns}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarExportImportStarNoCapture(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport {ns} from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns.foo, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.ts\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\texport {ns}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarExportImportStarCapture(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport {ns} from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.ts\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\texport {ns}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarExportStarAsUnused(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport {ns} from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.ts\": `\n\t\t\t\texport * as ns from './foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarExportStarAsNoCapture(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport {ns} from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns.foo, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.ts\": `\n\t\t\t\texport * as ns from './foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarExportStarAsCapture(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport {ns} from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.ts\": `\n\t\t\t\texport * as ns from './foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarExportStarUnused(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.ts\": `\n\t\t\t\texport * from './foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarExportStarNoCapture(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns.foo, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.ts\": `\n\t\t\t\texport * from './foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarExportStarCapture(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './bar'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t\t\"/bar.ts\": `\n\t\t\t\texport * from './foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarCommonJSUnused(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texports.foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarCommonJSCapture(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texports.foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarCommonJSNoCapture(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns.foo, ns.foo, foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texports.foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarAndCommonJS(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tconst ns2 = require('./foo')\n\t\t\t\tconsole.log(ns.foo, ns2.foo)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texport const foo = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarNoBundleUnused(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarNoBundleCapture(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns, ns.foo, foo)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarNoBundleNoCapture(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns.foo, ns.foo, foo)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarMangleNoBundleUnused(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:  true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarMangleNoBundleCapture(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns, ns.foo, foo)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:  true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportStarMangleNoBundleNoCapture(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tlet foo = 234\n\t\t\t\tconsole.log(ns.foo, ns.foo, foo)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:  true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSReExportTypeOnlyFileES6(t *testing.T) {\n\timportstar_ts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './re-export'\n\t\t\t\tconsole.log(ns.foo)\n\t\t\t`,\n\t\t\t\"/re-export.ts\": `\n\t\t\t\texport * from './types1'\n\t\t\t\texport * from './types2'\n\t\t\t\texport * from './types3'\n\t\t\t\texport * from './values'\n\t\t\t`,\n\t\t\t\"/types1.ts\": `\n\t\t\t\texport interface Foo {}\n\t\t\t\texport type Bar = number\n\t\t\t\tconsole.log('some code')\n\t\t\t`,\n\t\t\t\"/types2.ts\": `\n\t\t\t\timport {Foo} from \"./type\"\n\t\t\t\texport {Foo}\n\t\t\t\tconsole.log('some code')\n\t\t\t`,\n\t\t\t\"/types3.ts\": `\n\t\t\t\texport {Foo} from \"./type\"\n\t\t\t\tconsole.log('some code')\n\t\t\t`,\n\t\t\t\"/values.ts\": `\n\t\t\t\texport let foo = 123\n\t\t\t`,\n\t\t\t\"/type.ts\": `\n\t\t\t\texport type Foo = number\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "internal/bundler_tests/bundler_loader_test.go",
    "content": "package bundler_tests\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/bundler\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n)\n\nvar loader_suite = suite{\n\tname: \"loader\",\n}\n\nfunc TestLoaderFile(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(require('./test.svg'))\n\t\t\t`,\n\t\t\t\"/test.svg\": \"<svg></svg>\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out/\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".svg\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderFileMultipleNoCollision(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(\n\t\t\t\t\trequire('./a/test.txt'),\n\t\t\t\t\trequire('./b/test.txt'),\n\t\t\t\t)\n\t\t\t`,\n\n\t\t\t// Two files with the same contents but different paths\n\t\t\t\"/a/test.txt\": \"test\",\n\t\t\t\"/b/test.txt\": \"test\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/dist/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".txt\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestJSXSyntaxInJSWithJSXLoader(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\": config.LoaderJSX,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestJSXPreserveCapitalLetter(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\timport { mustStartWithUpperCaseLetter as Test } from './foo'\n\t\t\t\tconsole.log(<Test/>)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport class mustStartWithUpperCaseLetter {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tParse:    true,\n\t\t\t\tPreserve: true,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestJSXPreserveCapitalLetterMinify(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\timport { mustStartWithUpperCaseLetter as XYYYY } from './foo'\n\t\t\t\tconsole.log(<XYYYY tag-must-start-with-capital-letter />)\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport class mustStartWithUpperCaseLetter {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t\tMinifyIdentifiers: true,\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tParse:    true,\n\t\t\t\tPreserve: true,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestJSXPreserveCapitalLetterMinifyNested(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\tx = () => {\n\t\t\t\t\tclass XYYYYY {} // This should be named \"Y\" due to frequency analysis\n\t\t\t\t\treturn <XYYYYY tag-must-start-with-capital-letter />\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t\tMinifyIdentifiers: true,\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tParse:    true,\n\t\t\t\tPreserve: true,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestRequireCustomExtensionString(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(require('./test.custom'))\n\t\t\t`,\n\t\t\t\"/test.custom\": `#include <stdio.h>`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":     config.LoaderJS,\n\t\t\t\t\".custom\": config.LoaderText,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestRequireCustomExtensionBase64(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(require('./test.custom'))\n\t\t\t`,\n\t\t\t\"/test.custom\": \"a\\x00b\\x80c\\xFFd\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":     config.LoaderJS,\n\t\t\t\t\".custom\": config.LoaderBase64,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestRequireCustomExtensionDataURL(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(require('./test.custom'))\n\t\t\t`,\n\t\t\t\"/test.custom\": \"a\\x00b\\x80c\\xFFd\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":     config.LoaderJS,\n\t\t\t\t\".custom\": config.LoaderDataURL,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestRequireCustomExtensionPreferLongest(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(require('./test.txt'), require('./test.base64.txt'))\n\t\t\t`,\n\t\t\t\"/test.txt\":        `test.txt`,\n\t\t\t\"/test.base64.txt\": `test.base64.txt`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":         config.LoaderJS,\n\t\t\t\t\".txt\":        config.LoaderText,\n\t\t\t\t\".base64.txt\": config.LoaderBase64,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestAutoDetectMimeTypeFromExtension(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(require('./test.svg'))\n\t\t\t`,\n\t\t\t\"/test.svg\": \"a\\x00b\\x80c\\xFFd\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".svg\": config.LoaderDataURL,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderJSONCommonJSAndES6(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst x_json = require('./x.json')\n\t\t\t\timport y_json from './y.json'\n\t\t\t\timport {small, if as fi} from './z.json'\n\t\t\t\tconsole.log(x_json, y_json, small, fi)\n\t\t\t`,\n\t\t\t\"/x.json\": `{\"x\": true}`,\n\t\t\t\"/y.json\": `{\"y1\": true, \"y2\": false}`,\n\t\t\t\"/z.json\": `{\n\t\t\t\t\"big\": \"this is a big long line of text that should be discarded\",\n\t\t\t\t\"small\": \"some small text\",\n\t\t\t\t\"if\": \"test keyword imports\"\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderJSONInvalidIdentifierES6(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './test.json'\n\t\t\t\timport * as ns2 from './test2.json'\n\t\t\t\tconsole.log(ns['invalid-identifier'], ns2)\n\t\t\t`,\n\t\t\t\"/test.json\":  `{\"invalid-identifier\": true}`,\n\t\t\t\"/test2.json\": `{\"invalid-identifier\": true}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderJSONMissingES6(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {missing} from './test.json'\n\t\t\t`,\n\t\t\t\"/test.json\": `{\"present\": true}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `entry.js: ERROR: No matching export in \"test.json\" for import \"missing\"\n`,\n\t})\n}\n\nfunc TestLoaderTextCommonJSAndES6(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst x_txt = require('./x.txt')\n\t\t\t\timport y_txt from './y.txt'\n\t\t\t\tconsole.log(x_txt, y_txt)\n\t\t\t`,\n\t\t\t\"/x.txt\": \"x\",\n\t\t\t\"/y.txt\": \"y\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderBase64CommonJSAndES6(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst x_b64 = require('./x.b64')\n\t\t\t\timport y_b64 from './y.b64'\n\t\t\t\tconsole.log(x_b64, y_b64)\n\t\t\t`,\n\t\t\t\"/x.b64\": \"x\",\n\t\t\t\"/y.b64\": \"y\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".b64\": config.LoaderBase64,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderDataURLCommonJSAndES6(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst x_url = require('./x.txt')\n\t\t\t\timport y_url from './y.txt'\n\t\t\t\tconsole.log(x_url, y_url)\n\t\t\t`,\n\t\t\t\"/x.txt\": \"x\",\n\t\t\t\"/y.txt\": \"y\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".txt\": config.LoaderDataURL,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderFileCommonJSAndES6(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconst x_url = require('./x.txt')\n\t\t\t\timport y_url from './y.txt'\n\t\t\t\tconsole.log(x_url, y_url)\n\t\t\t`,\n\t\t\t\"/x.txt\": \"x\",\n\t\t\t\"/y.txt\": \"y\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".txt\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderFileRelativePathJS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entries/entry.js\": `\n\t\t\t\timport x from '../images/image.png'\n\t\t\t\tconsole.log(x)\n\t\t\t`,\n\t\t\t\"/src/images/image.png\": \"x\",\n\t\t},\n\t\tentryPaths: []string{\"/src/entries/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputBase: \"/src\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".png\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderFileRelativePathCSS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entries/entry.css\": `\n\t\t\t\tdiv {\n\t\t\t\t\tbackground: url(../images/image.png);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/src/images/image.png\": \"x\",\n\t\t},\n\t\tentryPaths: []string{\"/src/entries/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputBase: \"/src\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t\t\".png\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderFileRelativePathAssetNamesJS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entries/entry.js\": `\n\t\t\t\timport x from '../images/image.png'\n\t\t\t\tconsole.log(x)\n\t\t\t`,\n\t\t\t\"/src/images/image.png\": \"x\",\n\t\t},\n\t\tentryPaths: []string{\"/src/entries/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputBase: \"/src\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tAssetPathTemplate: []config.PathTemplate{\n\t\t\t\t{Data: \"\", Placeholder: config.DirPlaceholder},\n\t\t\t\t{Data: \"/\", Placeholder: config.NamePlaceholder},\n\t\t\t\t{Data: \"-\", Placeholder: config.HashPlaceholder},\n\t\t\t},\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".png\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderFileExtPathAssetNamesJS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entries/entry.js\": `\n\t\t\t\timport x from '../images/image.png'\n\t\t\t\timport y from '../uploads/file.txt'\n\t\t\t\tconsole.log(x, y)\n\t\t\t`,\n\t\t\t\"/src/images/image.png\": \"x\",\n\t\t\t\"/src/uploads/file.txt\": \"y\",\n\t\t},\n\t\tentryPaths: []string{\"/src/entries/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputBase: \"/src\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tAssetPathTemplate: []config.PathTemplate{\n\t\t\t\t{Data: \"\", Placeholder: config.ExtPlaceholder},\n\t\t\t\t{Data: \"/\", Placeholder: config.NamePlaceholder},\n\t\t\t\t{Data: \"-\", Placeholder: config.HashPlaceholder},\n\t\t\t},\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".png\": config.LoaderFile,\n\t\t\t\t\".txt\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderFileRelativePathAssetNamesCSS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entries/entry.css\": `\n\t\t\t\tdiv {\n\t\t\t\t\tbackground: url(../images/image.png);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/src/images/image.png\": \"x\",\n\t\t},\n\t\tentryPaths: []string{\"/src/entries/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputBase: \"/src\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tAssetPathTemplate: []config.PathTemplate{\n\t\t\t\t{Data: \"\", Placeholder: config.DirPlaceholder},\n\t\t\t\t{Data: \"/\", Placeholder: config.NamePlaceholder},\n\t\t\t\t{Data: \"-\", Placeholder: config.HashPlaceholder},\n\t\t\t},\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t\t\".png\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderFilePublicPathJS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entries/entry.js\": `\n\t\t\t\timport x from '../images/image.png'\n\t\t\t\tconsole.log(x)\n\t\t\t`,\n\t\t\t\"/src/images/image.png\": \"x\",\n\t\t},\n\t\tentryPaths: []string{\"/src/entries/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputBase: \"/src\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tPublicPath:    \"https://example.com\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".png\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderFilePublicPathCSS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entries/entry.css\": `\n\t\t\t\tdiv {\n\t\t\t\t\tbackground: url(../images/image.png);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/src/images/image.png\": \"x\",\n\t\t},\n\t\tentryPaths: []string{\"/src/entries/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputBase: \"/src\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tPublicPath:    \"https://example.com\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t\t\".png\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderFilePublicPathAssetNamesJS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entries/entry.js\": `\n\t\t\t\timport x from '../images/image.png'\n\t\t\t\tconsole.log(x)\n\t\t\t`,\n\t\t\t\"/src/images/image.png\": \"x\",\n\t\t},\n\t\tentryPaths: []string{\"/src/entries/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputBase: \"/src\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tPublicPath:    \"https://example.com\",\n\t\t\tAssetPathTemplate: []config.PathTemplate{\n\t\t\t\t{Data: \"\", Placeholder: config.DirPlaceholder},\n\t\t\t\t{Data: \"/\", Placeholder: config.NamePlaceholder},\n\t\t\t\t{Data: \"-\", Placeholder: config.HashPlaceholder},\n\t\t\t},\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".png\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderFilePublicPathAssetNamesCSS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entries/entry.css\": `\n\t\t\t\tdiv {\n\t\t\t\t\tbackground: url(../images/image.png);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/src/images/image.png\": \"x\",\n\t\t},\n\t\tentryPaths: []string{\"/src/entries/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputBase: \"/src\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tPublicPath:    \"https://example.com\",\n\t\t\tAssetPathTemplate: []config.PathTemplate{\n\t\t\t\t{Data: \"\", Placeholder: config.DirPlaceholder},\n\t\t\t\t{Data: \"/\", Placeholder: config.NamePlaceholder},\n\t\t\t\t{Data: \"-\", Placeholder: config.HashPlaceholder},\n\t\t\t},\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t\t\".png\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderFileOneSourceTwoDifferentOutputPathsJS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entries/entry.js\": `\n\t\t\t\timport '../shared/common.js'\n\t\t\t`,\n\t\t\t\"/src/entries/other/entry.js\": `\n\t\t\t\timport '../../shared/common.js'\n\t\t\t`,\n\t\t\t\"/src/shared/common.js\": `\n\t\t\t\timport x from './common.png'\n\t\t\t\tconsole.log(x)\n\t\t\t`,\n\t\t\t\"/src/shared/common.png\": \"x\",\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/src/entries/entry.js\",\n\t\t\t\"/src/entries/other/entry.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputBase: \"/src\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".png\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderFileOneSourceTwoDifferentOutputPathsCSS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entries/entry.css\": `\n\t\t\t\t@import \"../shared/common.css\";\n\t\t\t`,\n\t\t\t\"/src/entries/other/entry.css\": `\n\t\t\t\t@import \"../../shared/common.css\";\n\t\t\t`,\n\t\t\t\"/src/shared/common.css\": `\n\t\t\t\tdiv {\n\t\t\t\t\tbackground: url(common.png);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/src/shared/common.png\": \"x\",\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/src/entries/entry.css\",\n\t\t\t\"/src/entries/other/entry.css\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputBase: \"/src\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t\t\".png\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderJSONNoBundle(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/test.json\": `{\"test\": 123, \"invalid-identifier\": true}`,\n\t\t},\n\t\tentryPaths: []string{\"/test.json\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderJSONNoBundleES6(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/test.json\": `{\"test\": 123, \"invalid-identifier\": true}`,\n\t\t},\n\t\tentryPaths: []string{\"/test.json\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeConvertFormat,\n\t\t\tOutputFormat:          config.FormatESModule,\n\t\t\tUnsupportedJSFeatures: compat.ArbitraryModuleNamespaceNames,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderJSONNoBundleES6ArbitraryModuleNamespaceNames(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/test.json\": `{\"test\": 123, \"invalid-identifier\": true}`,\n\t\t},\n\t\tentryPaths: []string{\"/test.json\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderJSONNoBundleCommonJS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/test.json\": `{\"test\": 123, \"invalid-identifier\": true}`,\n\t\t},\n\t\tentryPaths: []string{\"/test.json\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderJSONNoBundleIIFE(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/test.json\": `{\"test\": 123, \"invalid-identifier\": true}`,\n\t\t},\n\t\tentryPaths: []string{\"/test.json\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderJSONSharedWithMultipleEntriesIssue413(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport data from './data.json'\n\t\t\t\tconsole.log('a:', data)\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport data from './data.json'\n\t\t\t\tconsole.log('b:', data)\n\t\t\t`,\n\t\t\t\"/data.json\": `{\"test\": 123}`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderFileWithQueryParameter(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t// Each of these should have a separate identity (i.e. end up in the output file twice)\n\t\t\t\timport foo from './file.txt?foo'\n\t\t\t\timport bar from './file.txt?bar'\n\t\t\t\tconsole.log(foo, bar)\n\t\t\t`,\n\t\t\t\"/file.txt\": `This is some text`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".txt\": config.LoaderFile,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderFromExtensionWithQueryParameter(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport foo from './file.abc?query.xyz'\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/file.abc\": `This should not be base64 encoded`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".abc\": config.LoaderText,\n\t\t\t\t\".xyz\": config.LoaderBase64,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderDataURLTextCSS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"data:text/css,body{color:%72%65%64}\";\n\t\t\t\t@import \"data:text/css;base64,Ym9keXtiYWNrZ3JvdW5kOmJsdWV9\";\n\t\t\t\t@import \"data:text/css;charset=UTF-8,body{color:%72%65%64}\";\n\t\t\t\t@import \"data:text/css;charset=UTF-8;base64,Ym9keXtiYWNrZ3JvdW5kOmJsdWV9\";\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderDataURLTextCSSCannotImport(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import \"data:text/css,@import './other.css';\";\n\t\t\t`,\n\t\t\t\"/other.css\": `\n\t\t\t\tdiv { should-not-be-imported: true }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedScanLog: `<data:text/css,@import './other.css';>: ERROR: Could not resolve \"./other.css\"\n`,\n\t})\n}\n\nfunc TestLoaderDataURLTextJavaScript(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"data:text/javascript,console.log('%31%32%33')\";\n\t\t\t\timport \"data:text/javascript;base64,Y29uc29sZS5sb2coMjM0KQ==\";\n\t\t\t\timport \"data:text/javascript;charset=UTF-8,console.log(%31%32%33)\";\n\t\t\t\timport \"data:text/javascript;charset=UTF-8;base64,Y29uc29sZS5sb2coMjM0KQ==\";\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderDataURLTextJavaScriptCannotImport(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"data:text/javascript,import './other.js'\"\n\t\t\t`,\n\t\t\t\"/other.js\": `\n\t\t\t\tshouldNotBeImported = true\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\texpectedScanLog: `<data:text/javascript,import './other.js'>: ERROR: Could not resolve \"./other.js\"\n`,\n\t})\n}\n\n// The \"+\" character must not be interpreted as a \" \" character\nfunc TestLoaderDataURLTextJavaScriptPlusCharacter(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"data:text/javascript,console.log(1+2)\";\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderDataURLApplicationJSON(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport a from 'data:application/json,\"%31%32%33\"';\n\t\t\t\timport b from 'data:application/json;base64,eyJ3b3JrcyI6dHJ1ZX0=';\n\t\t\t\timport c from 'data:application/json;charset=UTF-8,%31%32%33';\n\t\t\t\timport d from 'data:application/json;charset=UTF-8;base64,eyJ3b3JrcyI6dHJ1ZX0=';\n\t\t\t\tconsole.log([\n\t\t\t\t\ta, b, c, d,\n\t\t\t\t])\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderDataURLUnknownMIME(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport a from 'data:some/thing;what,someData%31%32%33';\n\t\t\t\timport b from 'data:other/thing;stuff;base64,c29tZURhdGEyMzQ=';\n\t\t\t\tconsole.log(a, b)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderDataURLExtensionBasedMIME(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.foo\": `\n\t\t\t\texport { default as css }   from \"./example.css\"\n\t\t\t\texport { default as eot }   from \"./example.eot\"\n\t\t\t\texport { default as gif }   from \"./example.gif\"\n\t\t\t\texport { default as htm }   from \"./example.htm\"\n\t\t\t\texport { default as html }  from \"./example.html\"\n\t\t\t\texport { default as jpeg }  from \"./example.jpeg\"\n\t\t\t\texport { default as jpg }   from \"./example.jpg\"\n\t\t\t\texport { default as js }    from \"./example.js\"\n\t\t\t\texport { default as json }  from \"./example.json\"\n\t\t\t\texport { default as mjs }   from \"./example.mjs\"\n\t\t\t\texport { default as otf }   from \"./example.otf\"\n\t\t\t\texport { default as pdf }   from \"./example.pdf\"\n\t\t\t\texport { default as png }   from \"./example.png\"\n\t\t\t\texport { default as sfnt }  from \"./example.sfnt\"\n\t\t\t\texport { default as svg }   from \"./example.svg\"\n\t\t\t\texport { default as ttf }   from \"./example.ttf\"\n\t\t\t\texport { default as wasm }  from \"./example.wasm\"\n\t\t\t\texport { default as webp }  from \"./example.webp\"\n\t\t\t\texport { default as woff }  from \"./example.woff\"\n\t\t\t\texport { default as woff2 } from \"./example.woff2\"\n\t\t\t\texport { default as xml }   from \"./example.xml\"\n\t\t\t`,\n\t\t\t\"/example.css\":   `css`,\n\t\t\t\"/example.eot\":   `eot`,\n\t\t\t\"/example.gif\":   `gif`,\n\t\t\t\"/example.htm\":   `htm`,\n\t\t\t\"/example.html\":  `html`,\n\t\t\t\"/example.jpeg\":  `jpeg`,\n\t\t\t\"/example.jpg\":   `jpg`,\n\t\t\t\"/example.js\":    `js`,\n\t\t\t\"/example.json\":  `json`,\n\t\t\t\"/example.mjs\":   `mjs`,\n\t\t\t\"/example.otf\":   `otf`,\n\t\t\t\"/example.pdf\":   `pdf`,\n\t\t\t\"/example.png\":   `png`,\n\t\t\t\"/example.sfnt\":  `sfnt`,\n\t\t\t\"/example.svg\":   `svg`,\n\t\t\t\"/example.ttf\":   `ttf`,\n\t\t\t\"/example.wasm\":  `wasm`,\n\t\t\t\"/example.webp\":  `webp`,\n\t\t\t\"/example.woff\":  `woff`,\n\t\t\t\"/example.woff2\": `woff2`,\n\t\t\t\"/example.xml\":   `xml`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.foo\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".foo\":   config.LoaderJS,\n\t\t\t\t\".css\":   config.LoaderDataURL,\n\t\t\t\t\".eot\":   config.LoaderDataURL,\n\t\t\t\t\".gif\":   config.LoaderDataURL,\n\t\t\t\t\".htm\":   config.LoaderDataURL,\n\t\t\t\t\".html\":  config.LoaderDataURL,\n\t\t\t\t\".jpeg\":  config.LoaderDataURL,\n\t\t\t\t\".jpg\":   config.LoaderDataURL,\n\t\t\t\t\".js\":    config.LoaderDataURL,\n\t\t\t\t\".json\":  config.LoaderDataURL,\n\t\t\t\t\".mjs\":   config.LoaderDataURL,\n\t\t\t\t\".otf\":   config.LoaderDataURL,\n\t\t\t\t\".pdf\":   config.LoaderDataURL,\n\t\t\t\t\".png\":   config.LoaderDataURL,\n\t\t\t\t\".sfnt\":  config.LoaderDataURL,\n\t\t\t\t\".svg\":   config.LoaderDataURL,\n\t\t\t\t\".ttf\":   config.LoaderDataURL,\n\t\t\t\t\".wasm\":  config.LoaderDataURL,\n\t\t\t\t\".webp\":  config.LoaderDataURL,\n\t\t\t\t\".woff\":  config.LoaderDataURL,\n\t\t\t\t\".woff2\": config.LoaderDataURL,\n\t\t\t\t\".xml\":   config.LoaderDataURL,\n\t\t\t},\n\t\t},\n\t})\n}\n\n// Percent-encoded data URLs should switch over to base64\n// data URLs if it would result in a smaller size\nfunc TestLoaderDataURLBase64VsPercentEncoding(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport a from './shouldUsePercent_1.txt'\n\t\t\t\timport b from './shouldUsePercent_2.txt'\n\t\t\t\timport c from './shouldUseBase64_1.txt'\n\t\t\t\timport d from './shouldUseBase64_2.txt'\n\t\t\t\tconsole.log(\n\t\t\t\t\ta,\n\t\t\t\t\tb,\n\t\t\t\t\tc,\n\t\t\t\t\td,\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/shouldUsePercent_1.txt\": \"\\n\\n\\n\",\n\t\t\t\"/shouldUsePercent_2.txt\": \"\\n\\n\\n\\n\",\n\t\t\t\"/shouldUseBase64_1.txt\":  \"\\n\\n\\n\\n\\n\",\n\t\t\t\"/shouldUseBase64_2.txt\":  \"\\n\\n\\n\\n\\n\\n\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".txt\": config.LoaderDataURL,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderDataURLBase64InvalidUTF8(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport a from './binary.txt'\n\t\t\t\tconsole.log(a)\n\t\t\t`,\n\t\t\t\"/binary.txt\": \"\\xFF\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".txt\": config.LoaderDataURL,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderDataURLEscapePercents(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport a from './percents.txt'\n\t\t\t\tconsole.log(a)\n\t\t\t`,\n\t\t\t\"/percents.txt\": `\n%, %3, %33, %333\n%, %e, %ee, %eee\n%, %E, %EE, %EEE\n`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":  config.LoaderJS,\n\t\t\t\t\".txt\": config.LoaderDataURL,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderCopyWithBundleFromJS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport x from \"../assets/some.file\"\n\t\t\t\tconsole.log(x)\n\t\t\t`,\n\t\t\t\"/Users/user/project/assets/some.file\": `stuff`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputBase: \"/Users/user/project\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":   config.LoaderJS,\n\t\t\t\t\".file\": config.LoaderCopy,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderCopyWithBundleFromCSS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.css\": `\n\t\t\t\tbody {\n\t\t\t\t\tbackground: url(../assets/some.file);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/assets/some.file\": `stuff`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputBase: \"/Users/user/project\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\":  config.LoaderCSS,\n\t\t\t\t\".file\": config.LoaderCopy,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderCopyWithBundleEntryPoint(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport x from \"../assets/some.file\"\n\t\t\t\tconsole.log(x)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/entry.css\": `\n\t\t\t\tbody {\n\t\t\t\t\tbackground: url(../assets/some.file);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/assets/some.file\": `stuff`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/Users/user/project/src/entry.js\",\n\t\t\t\"/Users/user/project/src/entry.css\",\n\t\t\t\"/Users/user/project/assets/some.file\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputBase: \"/Users/user/project\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":   config.LoaderJS,\n\t\t\t\t\".css\":  config.LoaderCSS,\n\t\t\t\t\".file\": config.LoaderCopy,\n\t\t\t},\n\t\t\tNeedsMetafile: true,\n\t\t},\n\t})\n}\n\nfunc TestLoaderCopyWithTransform(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\":     `console.log('entry')`,\n\t\t\t\"/Users/user/project/assets/some.file\": `stuff`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/Users/user/project/src/entry.js\",\n\t\t\t\"/Users/user/project/assets/some.file\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputBase: \"/Users/user/project\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":   config.LoaderJS,\n\t\t\t\t\".file\": config.LoaderCopy,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderCopyWithFormat(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\":     `console.log('entry')`,\n\t\t\t\"/Users/user/project/assets/some.file\": `stuff`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/Users/user/project/src/entry.js\",\n\t\t\t\"/Users/user/project/assets/some.file\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t\tAbsOutputBase: \"/Users/user/project\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":   config.LoaderJS,\n\t\t\t\t\".file\": config.LoaderCopy,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestJSXAutomaticNoNameCollision(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\timport { Link } from \"@remix-run/react\"\n\t\t\t\tconst x = <Link {...y} key={z} />\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tAutomaticRuntime: true,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestAssertTypeJSONWrongLoader(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport foo from './foo.json' assert { type: 'json' }\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":   config.LoaderJS,\n\t\t\t\t\".json\": config.LoaderJS,\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: The file \"foo.json\" was loaded with the \"js\" loader\nentry.js: NOTE: This import assertion requires the loader to be \"json\" instead:\nNOTE: You need to either reconfigure esbuild to ensure that the loader for this file is \"json\" or you need to remove this import assertion.\n`,\n\t})\n}\n\nfunc TestWithTypeJSONOverrideLoader(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport foo from './foo.js' with { type: 'json' }\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `{ \"this is json not js\": true }`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestWithTypeJSONOverrideLoaderGlob(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport(\"./foo\" + bar, { with: { type: 'json' } }).then(console.log)\n\t\t\t`,\n\t\t\t\"/foo.js\": `{ \"this is json not js\": true }`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestWithTypeBytesOverrideLoader(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport foo from './foo.js' with { type: 'bytes' }\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/foo.js\": `export default 'js'`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestWithTypeBytesOverrideLoaderGlob(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport(\"./foo\" + bar, { with: { type: 'bytes' } }).then(console.log)\n\t\t\t`,\n\t\t\t\"/foo.js\": `export default 'js'`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestWithBadType(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport foo from './foo.json' with { type: '' }\n\t\t\t\timport bar from './foo.json' with { type: 'garbage' }\n\t\t\t\tconsole.log(bar)\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Importing with a type attribute of \"\" is not supported\nentry.js: ERROR: Importing with a type attribute of \"garbage\" is not supported\n`,\n\t})\n}\n\nfunc TestWithBadAttribute(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport foo from './foo.json' with { '': 'json' }\n\t\t\t\timport bar from './foo.json' with { garbage: 'json' }\n\t\t\t\tconsole.log(bar)\n\t\t\t`,\n\t\t\t\"/foo.json\": `{}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Importing with the \"\" attribute is not supported\nentry.js: ERROR: Importing with the \"garbage\" attribute is not supported\n`,\n\t})\n}\n\nfunc TestEmptyLoaderJS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport './a.empty'\n\t\t\t\timport * as ns from './b.empty'\n\t\t\t\timport def from './c.empty'\n\t\t\t\timport { named } from './d.empty'\n\t\t\t\tconsole.log(ns, def, named)\n\t\t\t`,\n\t\t\t\"/a.empty\": `throw 'FAIL'`,\n\t\t\t\"/b.empty\": `throw 'FAIL'`,\n\t\t\t\"/c.empty\": `throw 'FAIL'`,\n\t\t\t\"/d.empty\": `throw 'FAIL'`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tSourceMap:     config.SourceMapExternalWithoutComment,\n\t\t\tNeedsMetafile: true,\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":    config.LoaderJS,\n\t\t\t\t\".empty\": config.LoaderEmpty,\n\t\t\t},\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `entry.js: WARNING: Import \"named\" will always be undefined because the file \"d.empty\" has no exports\n`,\n\t})\n}\n\nfunc TestEmptyLoaderCSS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import 'a.empty';\n\t\t\t\ta { background: url(b.empty) }\n\t\t\t`,\n\t\t\t\"/a.empty\": `body { color: fail }`,\n\t\t\t\"/b.empty\": `fail`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tSourceMap:     config.SourceMapExternalWithoutComment,\n\t\t\tNeedsMetafile: true,\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\":   config.LoaderCSS,\n\t\t\t\t\".empty\": config.LoaderEmpty,\n\t\t\t},\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExtensionlessLoaderJS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport './what'\n\t\t\t`,\n\t\t\t\"/what\": `foo()`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\": config.LoaderJS,\n\t\t\t\t\"\":    config.LoaderJS,\n\t\t\t},\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestExtensionlessLoaderCSS(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.css\": `\n\t\t\t\t@import './what';\n\t\t\t`,\n\t\t\t\"/what\": `.foo { color: red }`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t\t\"\":     config.LoaderCSS,\n\t\t\t},\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// Make sure custom entry point output names are respected for the copy loader\nfunc TestLoaderCopyEntryPointAdvanced(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/entry.js\": `\n\t\t\t\timport xyz from './xyz.copy'\n\t\t\t\tconsole.log(xyz)\n\t\t\t`,\n\t\t\t\"/project/TEST FAILED.copy\": `some stuff`,\n\t\t\t\"/project/xyz.copy\":         `more stuff`,\n\t\t},\n\t\tentryPathsAdvanced: []bundler.EntryPoint{\n\t\t\t{\n\t\t\t\tInputPath:                \"/project/entry.js\",\n\t\t\t\tOutputPath:               \"js/input/path\",\n\t\t\t\tInputPathInFileNamespace: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tInputPath:                \"/project/TEST FAILED.copy\",\n\t\t\t\tOutputPath:               \"copy/input/path\",\n\t\t\t\tInputPathInFileNamespace: true,\n\t\t\t},\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":   config.LoaderJS,\n\t\t\t\t\".copy\": config.LoaderCopy,\n\t\t\t},\n\t\t},\n\t})\n}\n\n// Make sure we don't turn \"src/index.copy\" into \"src.copy\" for files copied\n// via the file loader. This is sometimes done for JS files to try to generate\n// more useful names because lots of developers name their code \"index.js\" due\n// to node's implicit \"index.js\" path resolution logic.\nfunc TestLoaderCopyUseIndex(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/index.copy\": `some stuff`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/index.copy\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".copy\": config.LoaderCopy,\n\t\t\t},\n\t\t},\n\t})\n}\n\n// Make sure that if \"outfile\" is used, a file copied with the copy loader is\n// written out to that path. We don't want the file name to come from the\n// original source name instead of the \"outfile\" name, for example.\nfunc TestLoaderCopyExplicitOutputFile(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/TEST FAILED.copy\": `some stuff`,\n\t\t},\n\t\tentryPaths: []string{\"/project/TEST FAILED.copy\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out/this.worked\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".copy\": config.LoaderCopy,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderCopyStartsWithDotAbsPath(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/src/.htaccess\": `some stuff`,\n\t\t\t\"/project/src/entry.js\":  `some.stuff()`,\n\t\t\t\"/project/src/.ts\":       `foo as number`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/project/src/.htaccess\",\n\t\t\t\"/project/src/entry.js\",\n\t\t\t\"/project/src/.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":       config.LoaderJS,\n\t\t\t\t\".ts\":       config.LoaderTS,\n\t\t\t\t\".htaccess\": config.LoaderCopy,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderCopyStartsWithDotRelPath(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/src/.htaccess\": `some stuff`,\n\t\t\t\"/project/src/entry.js\":  `some.stuff()`,\n\t\t\t\"/project/src/.ts\":       `foo as number`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"./.htaccess\",\n\t\t\t\"./entry.js\",\n\t\t\t\"./.ts\",\n\t\t},\n\t\tabsWorkingDir: \"/project/src\",\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":       config.LoaderJS,\n\t\t\t\t\".ts\":       config.LoaderTS,\n\t\t\t\t\".htaccess\": config.LoaderCopy,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderCopyWithInjectedFileNoBundle(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entry.ts\":  `console.log('in entry.ts')`,\n\t\t\t\"/src/inject.js\": `console.log('in inject.js')`,\n\t\t},\n\t\tentryPaths: []string{\"/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tInjectPaths:  []string{\"/src/inject.js\"},\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".ts\": config.LoaderTS,\n\t\t\t\t\".js\": config.LoaderCopy,\n\t\t\t},\n\t\t},\n\t\texpectedScanLog: `ERROR: Cannot inject \"src/inject.js\" with the \"copy\" loader without bundling enabled\n`,\n\t})\n}\n\nfunc TestLoaderCopyWithInjectedFileBundle(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entry.ts\":  `console.log('in entry.ts')`,\n\t\t\t\"/src/inject.js\": `console.log('in inject.js')`,\n\t\t},\n\t\tentryPaths: []string{\"/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tInjectPaths:  []string{\"/src/inject.js\"},\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".ts\": config.LoaderTS,\n\t\t\t\t\".js\": config.LoaderCopy,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLoaderBundleWithImportAttributes(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport x from \"./data.json\"\n\t\t\t\timport y from \"./data.json\" assert { type: 'json' }\n\t\t\t\timport z from \"./data.json\" with { type: 'json' }\n\t\t\t\tconsole.log(x === y, x !== z)\n\t\t\t`,\n\t\t\t\"/data.json\": `{ \"works\": true }`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderBundleWithUnknownImportAttributesAndJSLoader(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport foo from \"./foo.js\" with { type: 'js' }\n\t\t\t\timport bar from \"./bar.js\" with { js: 'true' }\n\t\t\t\timport foo2 from \"data:text/javascript,foo\" with { type: 'js' }\n\t\t\t\timport bar2 from \"data:text/javascript,bar\" with { js: 'true' }\n\t\t\t\tconsole.log(foo, bar, foo2, bar2)\n\t\t\t`,\n\t\t\t\"/foo.js\": `...`,\n\t\t\t\"/bar.js\": `,,,`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: ERROR: Importing with a type attribute of \"js\" is not supported\nentry.js: ERROR: Importing with the \"js\" attribute is not supported\nentry.js: ERROR: Importing with a type attribute of \"js\" is not supported\nentry.js: ERROR: Importing with the \"js\" attribute is not supported\n`,\n\t})\n}\n\nfunc TestLoaderBundleWithUnknownImportAttributesAndCopyLoader(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport foo from \"./foo.thing\" with { type: 'whatever' }\n\t\t\t\timport bar from \"./bar.thing\" with { whatever: 'true' }\n\t\t\t\tconsole.log(foo, bar)\n\t\t\t`,\n\t\t\t\"/foo.thing\": `...`,\n\t\t\t\"/bar.thing\": `,,,`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode: config.ModeBundle,\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".js\":    config.LoaderJS,\n\t\t\t\t\".thing\": config.LoaderCopy,\n\t\t\t},\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLoaderBundleWithTypeJSONOnlyDefaultExport(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport x, {foo as x2} from \"./data.json\"\n\t\t\t\timport y, {foo as y2} from \"./data.json\" with { type: 'json' }\n\t\t\t`,\n\t\t\t\"/data.json\": `{ \"foo\": 123 }`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `entry.js: ERROR: No matching export in \"data.json with { type: 'json' }\" for import \"foo\"\n`,\n\t})\n}\n\nfunc TestLoaderJSONPrototype(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport data from \"./data.json\"\n\t\t\t\tconsole.log(data)\n\t\t\t`,\n\t\t\t\"/data.json\": `{\n\t\t\t\t\"\": \"The property below should be converted to a computed property:\",\n\t\t\t\t\"__proto__\": { \"foo\": \"bar\" }\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMinifySyntax:  true,\n\t\t},\n\t})\n}\n\nfunc TestLoaderJSONPrototypeES5(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport data from \"./data.json\"\n\t\t\t\tconsole.log(data)\n\t\t\t`,\n\t\t\t\"/data.json\": `{\n\t\t\t\t\"\": \"The property below should NOT be converted to a computed property for ES5:\",\n\t\t\t\t\"__proto__\": { \"foo\": \"bar\" }\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tMinifySyntax:          true,\n\t\t\tUnsupportedJSFeatures: es(5),\n\t\t},\n\t})\n}\n\nfunc TestLoaderJSONWithBigInt(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport data from \"./data.json\"\n\t\t\t\tconsole.log(data)\n\t\t\t`,\n\t\t\t\"/data.json\": `{\n\t\t\t\t\"invalid\": [123n]\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `data.json: ERROR: Unexpected \"123n\" in JSON\n`,\n\t})\n}\n\nfunc TestLoaderTextUTF8BOM(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport data1 from \"./data1.txt\"\n\t\t\t\timport data2 from \"./data2.txt\"\n\t\t\t\tconsole.log(data1, data2)\n\t\t\t`,\n\t\t\t\"/data1.txt\": \"\\xEF\\xBB\\xBFtext\",\n\t\t\t\"/data2.txt\": \"text\\xEF\\xBB\\xBF\",\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// See: https://github.com/evanw/esbuild/issues/4075\nfunc TestLoaderInlineSourceMapAbsolutePathIssue4075Unix(t *testing.T) {\n\turlEncodedUnix := \"%22file%3A%2F%2F%2Fout%2Fsrc%2Fstyles1.scss%22\" // file:///out/src/styles1.scss\n\tpathEncodedUnix := \"%22%2Fout%2Fsrc%2Fstyles2.scss%22\"             // /out/src/styles2.scss\n\n\tloader_suite.expectBundledUnix(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/home/user/project/src/entry.css\": `\n\t\t\t\t@import \"./styles1.css\";\n\t\t\t\t@import \"./styles2.css\";\n\t\t\t`,\n\t\t\t\"/home/user/project/src/styles1.css\": `/* You can add global styles to this file, and also import other style files */\n\t\t\t* {\n\t\t\t\tcontent: \"foo\";\n\t\t\t}\n\n\t\t\t/*# sourceMappingURL=data:application/json;charset=utf-8,%7B%22version%22:3,` +\n\t\t\t\t`%22sourceRoot%22:%22%22,%22sources%22:%5B` + urlEncodedUnix + `%5D,%22n` +\n\t\t\t\t`ames%22:%5B%5D,%22mappings%22:%22AAAA;AACA;EACE,SAAS%22,%22file%22:%22o` +\n\t\t\t\t`ut%22,%22sourcesContent%22:%5B%22/*%20You%20can%20add%20global%20styles` +\n\t\t\t\t`%20to%20this%20file,%20and%20also%20import%20other%20style%20files%20%2` +\n\t\t\t\t`A/%5Cn*%20%7B%5Cn%20%20content:%20%5C%22foo%5C%22%5Cn%7D%5Cn%22%5D%7D */`,\n\t\t\t\"/home/user/project/src/styles2.css\": `/* You can add global styles to this file, and also import other style files */\n\t\t\t* {\n\t\t\t\tcontent: \"bar\";\n\t\t\t}\n\n\t\t\t/*# sourceMappingURL=data:application/json;charset=utf-8,%7B%22version%22:3,` +\n\t\t\t\t`%22sourceRoot%22:%22%22,%22sources%22:%5B` + pathEncodedUnix + `%5D,%22` +\n\t\t\t\t`names%22:%5B%5D,%22mappings%22:%22AAAA;AACA;EACE,SAAS%22,%22file%22:%22` +\n\t\t\t\t`out%22,%22sourcesContent%22:%5B%22/*%20You%20can%20add%20global%20style` +\n\t\t\t\t`s%20to%20this%20file,%20and%20also%20import%20other%20style%20files%20%` +\n\t\t\t\t`2A/%5Cn*%20%7B%5Cn%20%20content:%20%5C%22bar%5C%22%5Cn%7D%5Cn%22%5D%7D */`,\n\t\t},\n\t\tentryPaths: []string{\"/home/user/project/src/entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tSourceMap:    config.SourceMapLinkedWithComment,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\n// See: https://github.com/evanw/esbuild/issues/4075\nfunc TestLoaderInlineSourceMapAbsolutePathIssue4075Windows(t *testing.T) {\n\turlEncodedWin := \"%22file%3A%2F%2F%2FC%3A%2Fout%2Fsrc%2Fstyles1.scss%22\" // file:///C:/out/src/styles1.scss\n\tpathEncodedWin := \"%22C%3A%5C%5Cout%5C%5Csrc%5C%5Cstyles2.scss%22\"       // C:\\out\\src\\styles2.scss\n\n\tloader_suite.expectBundledWindows(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"C:\\\\home\\\\user\\\\project\\\\src\\\\entry.css\": `\n\t\t\t\t@import \"./styles1.css\";\n\t\t\t\t@import \"./styles2.css\";\n\t\t\t`,\n\t\t\t\"C:\\\\home\\\\user\\\\project\\\\src\\\\styles1.css\": `/* You can add global styles to this file, and also import other style files */\n\t\t\t* {\n\t\t\t\tcontent: \"foo\";\n\t\t\t}\n\n\t\t\t/*# sourceMappingURL=data:application/json;charset=utf-8,%7B%22version%22:3,` +\n\t\t\t\t`%22sourceRoot%22:%22%22,%22sources%22:%5B` + urlEncodedWin + `%5D,%22n` +\n\t\t\t\t`ames%22:%5B%5D,%22mappings%22:%22AAAA;AACA;EACE,SAAS%22,%22file%22:%22o` +\n\t\t\t\t`ut%22,%22sourcesContent%22:%5B%22/*%20You%20can%20add%20global%20styles` +\n\t\t\t\t`%20to%20this%20file,%20and%20also%20import%20other%20style%20files%20%2` +\n\t\t\t\t`A/%5Cn*%20%7B%5Cn%20%20content:%20%5C%22foo%5C%22%5Cn%7D%5Cn%22%5D%7D */`,\n\t\t\t\"C:\\\\home\\\\user\\\\project\\\\src\\\\styles2.css\": `/* You can add global styles to this file, and also import other style files */\n\t\t\t* {\n\t\t\t\tcontent: \"bar\";\n\t\t\t}\n\n\t\t\t/*# sourceMappingURL=data:application/json;charset=utf-8,%7B%22version%22:3,` +\n\t\t\t\t`%22sourceRoot%22:%22%22,%22sources%22:%5B` + pathEncodedWin + `%5D,%22` +\n\t\t\t\t`names%22:%5B%5D,%22mappings%22:%22AAAA;AACA;EACE,SAAS%22,%22file%22:%22` +\n\t\t\t\t`out%22,%22sourcesContent%22:%5B%22/*%20You%20can%20add%20global%20style` +\n\t\t\t\t`s%20to%20this%20file,%20and%20also%20import%20other%20style%20files%20%` +\n\t\t\t\t`2A/%5Cn*%20%7B%5Cn%20%20content:%20%5C%22bar%5C%22%5Cn%7D%5Cn%22%5D%7D */`,\n\t\t},\n\t\tentryPaths: []string{\"C:\\\\home\\\\user\\\\project\\\\src\\\\entry.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tSourceMap:    config.SourceMapLinkedWithComment,\n\t\t\tAbsOutputDir: \"C:\\\\out\",\n\t\t},\n\t})\n}\n\n// See: https://github.com/evanw/esbuild/issues/4370\nfunc TestLoaderDataURLHashSuffixIssue4370(t *testing.T) {\n\tloader_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/icons.css\": `\n\t\t\t\t.triangle {\n\t\t\t\t\twidth: 10px;\n\t\t\t\t\theight: 10px;\n\t\t\t\t\tbackground: currentColor;\n\t\t\t\t\tclip-path: url(./triangle.svg#x);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/triangle.svg\": `<svg xmlns=\"http://www.w3.org/2000/svg\"><defs><clipPath id=\"x\"><path d=\"M0 0H10V10Z\"/></clipPath></defs></svg>`,\n\t\t},\n\t\tentryPaths: []string{\"/icons.css\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out/\",\n\t\t\tExtensionToLoader: map[string]config.Loader{\n\t\t\t\t\".css\": config.LoaderCSS,\n\t\t\t\t\".svg\": config.LoaderDataURL,\n\t\t\t},\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "internal/bundler_tests/bundler_lower_test.go",
    "content": "package bundler_tests\n\n// This file contains tests for \"lowering\" syntax, which means converting it to\n// older JavaScript. For example, \"a ** b\" becomes a call to \"Math.pow(a, b)\"\n// when lowered. Which syntax is lowered is determined by the language target.\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n)\n\nvar lower_suite = suite{\n\tname: \"lower\",\n}\n\nfunc TestLowerOptionalCatchNameCollisionNoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\ttry {}\n\t\t\t\tcatch { var e, e2 }\n\t\t\t\tvar e3\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2018),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerObjectSpreadNoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\tlet tests = [\n\t\t\t\t\t{...a, ...b},\n\t\t\t\t\t{a, b, ...c},\n\t\t\t\t\t{...a, b, c},\n\t\t\t\t\t{a, ...b, c},\n\t\t\t\t\t{a, b, ...c, ...d, e, f, ...g, ...h, i, j},\n\t\t\t\t]\n\t\t\t\tlet jsx = [\n\t\t\t\t\t<div {...a} {...b}/>,\n\t\t\t\t\t<div a b {...c}/>,\n\t\t\t\t\t<div {...a} b c/>,\n\t\t\t\t\t<div a {...b} c/>,\n\t\t\t\t\t<div a b {...c} {...d} e f {...g} {...h} i j/>,\n\t\t\t\t]\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2017),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerExponentiationOperatorNoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tlet tests = {\n\t\t\t\t\t// Exponentiation operator\n\t\t\t\t\t0: a ** b ** c,\n\t\t\t\t\t1: (a ** b) ** c,\n\n\t\t\t\t\t// Exponentiation assignment operator\n\t\t\t\t\t2: a **= b,\n\t\t\t\t\t3: a.b **= c,\n\t\t\t\t\t4: a[b] **= c,\n\t\t\t\t\t5: a().b **= c,\n\t\t\t\t\t6: a()[b] **= c,\n\t\t\t\t\t7: a[b()] **= c,\n\t\t\t\t\t8: a()[b()] **= c,\n\n\t\t\t\t\t// These all should not need capturing (no object identity)\n\t\t\t\t\t9: a[0] **= b,\n\t\t\t\t\t10: a[false] **= b,\n\t\t\t\t\t11: a[null] **= b,\n\t\t\t\t\t12: a[void 0] **= b,\n\t\t\t\t\t13: a[123n] **= b,\n\t\t\t\t\t14: a[this] **= b,\n\n\t\t\t\t\t// These should need capturing (have object identitiy)\n\t\t\t\t\t15: a[/x/] **= b,\n\t\t\t\t\t16: a[{}] **= b,\n\t\t\t\t\t17: a[[]] **= b,\n\t\t\t\t\t18: a[() => {}] **= b,\n\t\t\t\t\t19: a[function() {}] **= b,\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2015),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: WARNING: Big integer literals are not available in the configured target environment and may crash at run-time\n`,\n\t})\n}\n\nfunc TestLowerPrivateFieldAssignments2015NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#x\n\t\t\t\t\tunary() {\n\t\t\t\t\t\tthis.#x++\n\t\t\t\t\t\tthis.#x--\n\t\t\t\t\t\t++this.#x\n\t\t\t\t\t\t--this.#x\n\t\t\t\t\t}\n\t\t\t\t\tbinary() {\n\t\t\t\t\t\tthis.#x = 1\n\t\t\t\t\t\tthis.#x += 1\n\t\t\t\t\t\tthis.#x -= 1\n\t\t\t\t\t\tthis.#x *= 1\n\t\t\t\t\t\tthis.#x /= 1\n\t\t\t\t\t\tthis.#x %= 1\n\t\t\t\t\t\tthis.#x **= 1\n\t\t\t\t\t\tthis.#x <<= 1\n\t\t\t\t\t\tthis.#x >>= 1\n\t\t\t\t\t\tthis.#x >>>= 1\n\t\t\t\t\t\tthis.#x &= 1\n\t\t\t\t\t\tthis.#x |= 1\n\t\t\t\t\t\tthis.#x ^= 1\n\t\t\t\t\t\tthis.#x &&= 1\n\t\t\t\t\t\tthis.#x ||= 1\n\t\t\t\t\t\tthis.#x ??= 1\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2015),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateFieldAssignments2019NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#x\n\t\t\t\t\tunary() {\n\t\t\t\t\t\tthis.#x++\n\t\t\t\t\t\tthis.#x--\n\t\t\t\t\t\t++this.#x\n\t\t\t\t\t\t--this.#x\n\t\t\t\t\t}\n\t\t\t\t\tbinary() {\n\t\t\t\t\t\tthis.#x = 1\n\t\t\t\t\t\tthis.#x += 1\n\t\t\t\t\t\tthis.#x -= 1\n\t\t\t\t\t\tthis.#x *= 1\n\t\t\t\t\t\tthis.#x /= 1\n\t\t\t\t\t\tthis.#x %= 1\n\t\t\t\t\t\tthis.#x **= 1\n\t\t\t\t\t\tthis.#x <<= 1\n\t\t\t\t\t\tthis.#x >>= 1\n\t\t\t\t\t\tthis.#x >>>= 1\n\t\t\t\t\t\tthis.#x &= 1\n\t\t\t\t\t\tthis.#x |= 1\n\t\t\t\t\t\tthis.#x ^= 1\n\t\t\t\t\t\tthis.#x &&= 1\n\t\t\t\t\t\tthis.#x ||= 1\n\t\t\t\t\t\tthis.#x ??= 1\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2019),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateFieldAssignments2020NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#x\n\t\t\t\t\tunary() {\n\t\t\t\t\t\tthis.#x++\n\t\t\t\t\t\tthis.#x--\n\t\t\t\t\t\t++this.#x\n\t\t\t\t\t\t--this.#x\n\t\t\t\t\t}\n\t\t\t\t\tbinary() {\n\t\t\t\t\t\tthis.#x = 1\n\t\t\t\t\t\tthis.#x += 1\n\t\t\t\t\t\tthis.#x -= 1\n\t\t\t\t\t\tthis.#x *= 1\n\t\t\t\t\t\tthis.#x /= 1\n\t\t\t\t\t\tthis.#x %= 1\n\t\t\t\t\t\tthis.#x **= 1\n\t\t\t\t\t\tthis.#x <<= 1\n\t\t\t\t\t\tthis.#x >>= 1\n\t\t\t\t\t\tthis.#x >>>= 1\n\t\t\t\t\t\tthis.#x &= 1\n\t\t\t\t\t\tthis.#x |= 1\n\t\t\t\t\t\tthis.#x ^= 1\n\t\t\t\t\t\tthis.#x &&= 1\n\t\t\t\t\t\tthis.#x ||= 1\n\t\t\t\t\t\tthis.#x ??= 1\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2020),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateFieldAssignmentsNextNoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#x\n\t\t\t\t\tunary() {\n\t\t\t\t\t\tthis.#x++\n\t\t\t\t\t\tthis.#x--\n\t\t\t\t\t\t++this.#x\n\t\t\t\t\t\t--this.#x\n\t\t\t\t\t}\n\t\t\t\t\tbinary() {\n\t\t\t\t\t\tthis.#x = 1\n\t\t\t\t\t\tthis.#x += 1\n\t\t\t\t\t\tthis.#x -= 1\n\t\t\t\t\t\tthis.#x *= 1\n\t\t\t\t\t\tthis.#x /= 1\n\t\t\t\t\t\tthis.#x %= 1\n\t\t\t\t\t\tthis.#x **= 1\n\t\t\t\t\t\tthis.#x <<= 1\n\t\t\t\t\t\tthis.#x >>= 1\n\t\t\t\t\t\tthis.#x >>>= 1\n\t\t\t\t\t\tthis.#x &= 1\n\t\t\t\t\t\tthis.#x |= 1\n\t\t\t\t\t\tthis.#x ^= 1\n\t\t\t\t\t\tthis.#x &&= 1\n\t\t\t\t\t\tthis.#x ||= 1\n\t\t\t\t\t\tthis.#x ??= 1\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateFieldOptionalChain2019NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#x\n\t\t\t\t\tfoo() {\n\t\t\t\t\t\tthis?.#x.y\n\t\t\t\t\t\tthis?.y.#x\n\t\t\t\t\t\tthis.#x?.y\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2019),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateFieldOptionalChain2020NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#x\n\t\t\t\t\tfoo() {\n\t\t\t\t\t\tthis?.#x.y\n\t\t\t\t\t\tthis?.y.#x\n\t\t\t\t\t\tthis.#x?.y\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2020),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateFieldOptionalChainNextNoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#x\n\t\t\t\t\tfoo() {\n\t\t\t\t\t\tthis?.#x.y\n\t\t\t\t\t\tthis?.y.#x\n\t\t\t\t\t\tthis.#x?.y\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSLowerPrivateFieldOptionalChain2015NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#x\n\t\t\t\t\tfoo() {\n\t\t\t\t\t\tthis?.#x.y\n\t\t\t\t\t\tthis?.y.#x\n\t\t\t\t\t\tthis.#x?.y\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2015),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSLowerPrivateStaticMembers2015NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\tstatic #x\n\t\t\t\t\tstatic get #y() {}\n\t\t\t\t\tstatic set #y(x) {}\n\t\t\t\t\tstatic #z() {}\n\t\t\t\t\tfoo() {\n\t\t\t\t\t\tFoo.#x += 1\n\t\t\t\t\t\tFoo.#y += 1\n\t\t\t\t\t\tFoo.#z()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2015),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSLowerPrivateFieldAndMethodAvoidNameCollision2015(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\texport class WeakMap {\n\t\t\t\t\t#x\n\t\t\t\t}\n\t\t\t\texport class WeakSet {\n\t\t\t\t\t#y() {}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2015),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateGetterSetter2015(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport class Foo {\n\t\t\t\t\tget #foo() { return this.foo }\n\t\t\t\t\tset #bar(val) { this.bar = val }\n\t\t\t\t\tget #prop() { return this.prop }\n\t\t\t\t\tset #prop(val) { this.prop = val }\n\t\t\t\t\tfoo(fn) {\n\t\t\t\t\t\tfn().#foo\n\t\t\t\t\t\tfn().#bar = 1\n\t\t\t\t\t\tfn().#prop\n\t\t\t\t\t\tfn().#prop = 2\n\t\t\t\t\t}\n\t\t\t\t\tunary(fn) {\n\t\t\t\t\t\tfn().#prop++;\n\t\t\t\t\t\tfn().#prop--;\n\t\t\t\t\t\t++fn().#prop;\n\t\t\t\t\t\t--fn().#prop;\n\t\t\t\t\t}\n\t\t\t\t\tbinary(fn) {\n\t\t\t\t\t\tfn().#prop = 1;\n\t\t\t\t\t\tfn().#prop += 1;\n\t\t\t\t\t\tfn().#prop -= 1;\n\t\t\t\t\t\tfn().#prop *= 1;\n\t\t\t\t\t\tfn().#prop /= 1;\n\t\t\t\t\t\tfn().#prop %= 1;\n\t\t\t\t\t\tfn().#prop **= 1;\n\t\t\t\t\t\tfn().#prop <<= 1;\n\t\t\t\t\t\tfn().#prop >>= 1;\n\t\t\t\t\t\tfn().#prop >>>= 1;\n\t\t\t\t\t\tfn().#prop &= 1;\n\t\t\t\t\t\tfn().#prop |= 1;\n\t\t\t\t\t\tfn().#prop ^= 1;\n\t\t\t\t\t\tfn().#prop &&= 1;\n\t\t\t\t\t\tfn().#prop ||= 1;\n\t\t\t\t\t\tfn().#prop ??= 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2015),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateGetterSetter2019(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport class Foo {\n\t\t\t\t\tget #foo() { return this.foo }\n\t\t\t\t\tset #bar(val) { this.bar = val }\n\t\t\t\t\tget #prop() { return this.prop }\n\t\t\t\t\tset #prop(val) { this.prop = val }\n\t\t\t\t\tfoo(fn) {\n\t\t\t\t\t\tfn().#foo\n\t\t\t\t\t\tfn().#bar = 1\n\t\t\t\t\t\tfn().#prop\n\t\t\t\t\t\tfn().#prop = 2\n\t\t\t\t\t}\n\t\t\t\t\tunary(fn) {\n\t\t\t\t\t\tfn().#prop++;\n\t\t\t\t\t\tfn().#prop--;\n\t\t\t\t\t\t++fn().#prop;\n\t\t\t\t\t\t--fn().#prop;\n\t\t\t\t\t}\n\t\t\t\t\tbinary(fn) {\n\t\t\t\t\t\tfn().#prop = 1;\n\t\t\t\t\t\tfn().#prop += 1;\n\t\t\t\t\t\tfn().#prop -= 1;\n\t\t\t\t\t\tfn().#prop *= 1;\n\t\t\t\t\t\tfn().#prop /= 1;\n\t\t\t\t\t\tfn().#prop %= 1;\n\t\t\t\t\t\tfn().#prop **= 1;\n\t\t\t\t\t\tfn().#prop <<= 1;\n\t\t\t\t\t\tfn().#prop >>= 1;\n\t\t\t\t\t\tfn().#prop >>>= 1;\n\t\t\t\t\t\tfn().#prop &= 1;\n\t\t\t\t\t\tfn().#prop |= 1;\n\t\t\t\t\t\tfn().#prop ^= 1;\n\t\t\t\t\t\tfn().#prop &&= 1;\n\t\t\t\t\t\tfn().#prop ||= 1;\n\t\t\t\t\t\tfn().#prop ??= 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2019),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateGetterSetter2020(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport class Foo {\n\t\t\t\t\tget #foo() { return this.foo }\n\t\t\t\t\tset #bar(val) { this.bar = val }\n\t\t\t\t\tget #prop() { return this.prop }\n\t\t\t\t\tset #prop(val) { this.prop = val }\n\t\t\t\t\tfoo(fn) {\n\t\t\t\t\t\tfn().#foo\n\t\t\t\t\t\tfn().#bar = 1\n\t\t\t\t\t\tfn().#prop\n\t\t\t\t\t\tfn().#prop = 2\n\t\t\t\t\t}\n\t\t\t\t\tunary(fn) {\n\t\t\t\t\t\tfn().#prop++;\n\t\t\t\t\t\tfn().#prop--;\n\t\t\t\t\t\t++fn().#prop;\n\t\t\t\t\t\t--fn().#prop;\n\t\t\t\t\t}\n\t\t\t\t\tbinary(fn) {\n\t\t\t\t\t\tfn().#prop = 1;\n\t\t\t\t\t\tfn().#prop += 1;\n\t\t\t\t\t\tfn().#prop -= 1;\n\t\t\t\t\t\tfn().#prop *= 1;\n\t\t\t\t\t\tfn().#prop /= 1;\n\t\t\t\t\t\tfn().#prop %= 1;\n\t\t\t\t\t\tfn().#prop **= 1;\n\t\t\t\t\t\tfn().#prop <<= 1;\n\t\t\t\t\t\tfn().#prop >>= 1;\n\t\t\t\t\t\tfn().#prop >>>= 1;\n\t\t\t\t\t\tfn().#prop &= 1;\n\t\t\t\t\t\tfn().#prop |= 1;\n\t\t\t\t\t\tfn().#prop ^= 1;\n\t\t\t\t\t\tfn().#prop &&= 1;\n\t\t\t\t\t\tfn().#prop ||= 1;\n\t\t\t\t\t\tfn().#prop ??= 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2020),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateGetterSetterNext(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport class Foo {\n\t\t\t\t\tget #foo() { return this.foo }\n\t\t\t\t\tset #bar(val) { this.bar = val }\n\t\t\t\t\tget #prop() { return this.prop }\n\t\t\t\t\tset #prop(val) { this.prop = val }\n\t\t\t\t\tfoo(fn) {\n\t\t\t\t\t\tfn().#foo\n\t\t\t\t\t\tfn().#bar = 1\n\t\t\t\t\t\tfn().#prop\n\t\t\t\t\t\tfn().#prop = 2\n\t\t\t\t\t}\n\t\t\t\t\tunary(fn) {\n\t\t\t\t\t\tfn().#prop++;\n\t\t\t\t\t\tfn().#prop--;\n\t\t\t\t\t\t++fn().#prop;\n\t\t\t\t\t\t--fn().#prop;\n\t\t\t\t\t}\n\t\t\t\t\tbinary(fn) {\n\t\t\t\t\t\tfn().#prop = 1;\n\t\t\t\t\t\tfn().#prop += 1;\n\t\t\t\t\t\tfn().#prop -= 1;\n\t\t\t\t\t\tfn().#prop *= 1;\n\t\t\t\t\t\tfn().#prop /= 1;\n\t\t\t\t\t\tfn().#prop %= 1;\n\t\t\t\t\t\tfn().#prop **= 1;\n\t\t\t\t\t\tfn().#prop <<= 1;\n\t\t\t\t\t\tfn().#prop >>= 1;\n\t\t\t\t\t\tfn().#prop >>>= 1;\n\t\t\t\t\t\tfn().#prop &= 1;\n\t\t\t\t\t\tfn().#prop |= 1;\n\t\t\t\t\t\tfn().#prop ^= 1;\n\t\t\t\t\t\tfn().#prop &&= 1;\n\t\t\t\t\t\tfn().#prop ||= 1;\n\t\t\t\t\t\tfn().#prop ??= 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateMethod2019(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport class Foo {\n\t\t\t\t\t#field\n\t\t\t\t\t#method() {}\n\t\t\t\t\tbaseline() {\n\t\t\t\t\t\ta().foo\n\t\t\t\t\t\tb().foo(x)\n\t\t\t\t\t\tc()?.foo(x)\n\t\t\t\t\t\td().foo?.(x)\n\t\t\t\t\t\te()?.foo?.(x)\n\t\t\t\t\t}\n\t\t\t\t\tprivateField() {\n\t\t\t\t\t\ta().#field\n\t\t\t\t\t\tb().#field(x)\n\t\t\t\t\t\tc()?.#field(x)\n\t\t\t\t\t\td().#field?.(x)\n\t\t\t\t\t\te()?.#field?.(x)\n\t\t\t\t\t\tf()?.foo.#field(x).bar()\n\t\t\t\t\t}\n\t\t\t\t\tprivateMethod() {\n\t\t\t\t\t\ta().#method\n\t\t\t\t\t\tb().#method(x)\n\t\t\t\t\t\tc()?.#method(x)\n\t\t\t\t\t\td().#method?.(x)\n\t\t\t\t\t\te()?.#method?.(x)\n\t\t\t\t\t\tf()?.foo.#method(x).bar()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2019),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateMethod2020(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport class Foo {\n\t\t\t\t\t#field\n\t\t\t\t\t#method() {}\n\t\t\t\t\tbaseline() {\n\t\t\t\t\t\ta().foo\n\t\t\t\t\t\tb().foo(x)\n\t\t\t\t\t\tc()?.foo(x)\n\t\t\t\t\t\td().foo?.(x)\n\t\t\t\t\t\te()?.foo?.(x)\n\t\t\t\t\t}\n\t\t\t\t\tprivateField() {\n\t\t\t\t\t\ta().#field\n\t\t\t\t\t\tb().#field(x)\n\t\t\t\t\t\tc()?.#field(x)\n\t\t\t\t\t\td().#field?.(x)\n\t\t\t\t\t\te()?.#field?.(x)\n\t\t\t\t\t\tf()?.foo.#field(x).bar()\n\t\t\t\t\t}\n\t\t\t\t\tprivateMethod() {\n\t\t\t\t\t\ta().#method\n\t\t\t\t\t\tb().#method(x)\n\t\t\t\t\t\tc()?.#method(x)\n\t\t\t\t\t\td().#method?.(x)\n\t\t\t\t\t\te()?.#method?.(x)\n\t\t\t\t\t\tf()?.foo.#method(x).bar()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2020),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateMethodNext(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport class Foo {\n\t\t\t\t\t#field\n\t\t\t\t\t#method() {}\n\t\t\t\t\tbaseline() {\n\t\t\t\t\t\ta().foo\n\t\t\t\t\t\tb().foo(x)\n\t\t\t\t\t\tc()?.foo(x)\n\t\t\t\t\t\td().foo?.(x)\n\t\t\t\t\t\te()?.foo?.(x)\n\t\t\t\t\t}\n\t\t\t\t\tprivateField() {\n\t\t\t\t\t\ta().#field\n\t\t\t\t\t\tb().#field(x)\n\t\t\t\t\t\tc()?.#field(x)\n\t\t\t\t\t\td().#field?.(x)\n\t\t\t\t\t\te()?.#field?.(x)\n\t\t\t\t\t\tf()?.foo.#field(x).bar()\n\t\t\t\t\t}\n\t\t\t\t\tprivateMethod() {\n\t\t\t\t\t\ta().#method\n\t\t\t\t\t\tb().#method(x)\n\t\t\t\t\t\tc()?.#method(x)\n\t\t\t\t\t\td().#method?.(x)\n\t\t\t\t\t\te()?.#method?.(x)\n\t\t\t\t\t\tf()?.foo.#method(x).bar()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateClassExpr2020NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport let Foo = class {\n\t\t\t\t\t#field\n\t\t\t\t\t#method() {}\n\t\t\t\t\tstatic #staticField\n\t\t\t\t\tstatic #staticMethod() {}\n\t\t\t\t\tfoo() {\n\t\t\t\t\t\tthis.#field = this.#method()\n\t\t\t\t\t\tFoo.#staticField = Foo.#staticMethod()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2020),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateMethodWithModifiers2020(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport class Foo {\n\t\t\t\t\t*#g() {}\n\t\t\t\t\tasync #a() {}\n\t\t\t\t\tasync *#ag() {}\n\n\t\t\t\t\tstatic *#sg() {}\n\t\t\t\t\tstatic async #sa() {}\n\t\t\t\t\tstatic async *#sag() {}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2020),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerAsync2016NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tasync function foo(bar) {\n\t\t\t\t\tawait bar\n\t\t\t\t\treturn [this, arguments]\n\t\t\t\t}\n\t\t\t\tclass Foo {async foo() {}}\n\t\t\t\tnew (class Bar extends class { } {\n\t\t\t\t\tconstructor() {\n\t\t\t\t\t\tlet x = 1;\n\t\t\t\t\t\t(async () => {\n\t\t\t\t\t\t\tconsole.log(\"before super\", x);  // (1) Sync phase\n\t\t\t\t\t\t\tawait 1;\n\t\t\t\t\t\t\tconsole.log(\"after super\", x);   // (2) Async phase\n\t\t\t\t\t\t})();\n\t\t\t\t\t\tsuper();\n\t\t\t\t\t\tx = 2;\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t\texport default [\n\t\t\t\t\tfoo,\n\t\t\t\t\tFoo,\n\t\t\t\t\tasync function() {},\n\t\t\t\t\tasync () => {},\n\t\t\t\t\t{async foo() {}},\n\t\t\t\t\tclass {async foo() {}},\n\t\t\t\t\tfunction() {\n\t\t\t\t\t\treturn async (bar) => {\n\t\t\t\t\t\t\tawait bar\n\t\t\t\t\t\t\treturn [this, arguments]\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2016),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerAsync2017NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tasync function foo(bar) {\n\t\t\t\t\tawait bar\n\t\t\t\t\treturn arguments\n\t\t\t\t}\n\t\t\t\tclass Foo {async foo() {}}\n\t\t\t\texport default [\n\t\t\t\t\tfoo,\n\t\t\t\t\tFoo,\n\t\t\t\t\tasync function() {},\n\t\t\t\t\tasync () => {},\n\t\t\t\t\t{async foo() {}},\n\t\t\t\t\tclass {async foo() {}},\n\t\t\t\t\tfunction() {\n\t\t\t\t\t\treturn async (bar) => {\n\t\t\t\t\t\t\tawait bar\n\t\t\t\t\t\t\treturn [this, arguments]\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2017),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerAsyncThis2016CommonJS(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texports.foo = async () => this\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2016),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerAsyncThis2016ES6(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport {bar} from \"./other\"\n\t\t\t\texport let foo = async () => this\n\t\t\t`,\n\t\t\t\"/other.js\": `\n\t\t\t\texport let bar = async () => {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2016),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t\tdebugLogs: true,\n\t\texpectedScanLog: `entry.js: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nentry.js: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n`,\n\t})\n}\n\nfunc TestLowerAsyncES5(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport './fn-stmt'\n\t\t\t\timport './fn-expr'\n\t\t\t\timport './arrow-1'\n\t\t\t\timport './arrow-2'\n\t\t\t\timport './export-def-1'\n\t\t\t\timport './export-def-2'\n\t\t\t\timport './obj-method'\n\t\t\t`,\n\t\t\t\"/fn-stmt.js\":      `async function foo() {}`,\n\t\t\t\"/fn-expr.js\":      `(async function() {})`,\n\t\t\t\"/arrow-1.js\":      `(async () => {})`,\n\t\t\t\"/arrow-2.js\":      `(async x => {})`,\n\t\t\t\"/export-def-1.js\": `export default async function foo() {}`,\n\t\t\t\"/export-def-2.js\": `export default async function() {}`,\n\t\t\t\"/obj-method.js\":   `({async foo() {}})`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(5),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `arrow-1.js: ERROR: Transforming async functions to the configured target environment is not supported yet\narrow-2.js: ERROR: Transforming async functions to the configured target environment is not supported yet\nexport-def-1.js: ERROR: Transforming async functions to the configured target environment is not supported yet\nexport-def-2.js: ERROR: Transforming async functions to the configured target environment is not supported yet\nfn-expr.js: ERROR: Transforming async functions to the configured target environment is not supported yet\nfn-stmt.js: ERROR: Transforming async functions to the configured target environment is not supported yet\nobj-method.js: ERROR: Transforming async functions to the configured target environment is not supported yet\n`,\n\t})\n}\n\nfunc TestLowerAsyncSuperES2017NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Derived extends Base {\n\t\t\t\t\tasync test(key) {\n\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\tawait super.foo,\n\t\t\t\t\t\t\tawait super[key],\n\t\t\t\t\t\t\tawait ([super.foo] = [0]),\n\t\t\t\t\t\t\tawait ([super[key]] = [0]),\n\n\t\t\t\t\t\t\tawait (super.foo = 1),\n\t\t\t\t\t\t\tawait (super[key] = 1),\n\t\t\t\t\t\t\tawait (super.foo += 2),\n\t\t\t\t\t\t\tawait (super[key] += 2),\n\n\t\t\t\t\t\t\tawait ++super.foo,\n\t\t\t\t\t\t\tawait ++super[key],\n\t\t\t\t\t\t\tawait super.foo++,\n\t\t\t\t\t\t\tawait super[key]++,\n\n\t\t\t\t\t\t\tawait super.foo.name,\n\t\t\t\t\t\t\tawait super[key].name,\n\t\t\t\t\t\t\tawait super.foo?.name,\n\t\t\t\t\t\t\tawait super[key]?.name,\n\n\t\t\t\t\t\t\tawait super.foo(1, 2),\n\t\t\t\t\t\t\tawait super[key](1, 2),\n\t\t\t\t\t\t\tawait super.foo?.(1, 2),\n\t\t\t\t\t\t\tawait super[key]?.(1, 2),\n\n\t\t\t\t\t\t\tawait (() => super.foo)(),\n\t\t\t\t\t\t\tawait (() => super[key])(),\n\t\t\t\t\t\t\tawait (() => super.foo())(),\n\t\t\t\t\t\t\tawait (() => super[key]())(),\n\n\t\t\t\t\t\t\tawait super.foo` + \"``\" + `,\n\t\t\t\t\t\t\tawait super[key]` + \"``\" + `,\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// This covers a bug that caused a compiler crash\n\t\t\t\tlet fn = async () => class extends Base {\n\t\t\t\t\ta = super.a\n\t\t\t\t\tb = () => super.b\n\t\t\t\t\tc() { return super.c }\n\t\t\t\t\td() { return () => super.d }\n\t\t\t\t}\n\n\t\t\t\t// This covers a bug that generated bad code\n\t\t\t\tclass Derived2 extends Base {\n\t\t\t\t\tasync a() { return class { [super.foo] = 123 } }\n\t\t\t\t\tb = async () => class { [super.foo] = 123 }\n\t\t\t\t}\n\n\t\t\t\t// This covers putting the generated temporary variable inside the loop\n\t\t\t\tfor (let i = 0; i < 3; i++) {\n\t\t\t\t\tobjs.push({\n\t\t\t\t\t\t__proto__: {\n\t\t\t\t\t\t\tfoo() { return i },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tasync bar() { return super.foo() },\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2017),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerAsyncSuperES2016NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Derived extends Base {\n\t\t\t\t\tasync test(key) {\n\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\tawait super.foo,\n\t\t\t\t\t\t\tawait super[key],\n\t\t\t\t\t\t\tawait ([super.foo] = [0]),\n\t\t\t\t\t\t\tawait ([super[key]] = [0]),\n\n\t\t\t\t\t\t\tawait (super.foo = 1),\n\t\t\t\t\t\t\tawait (super[key] = 1),\n\t\t\t\t\t\t\tawait (super.foo += 2),\n\t\t\t\t\t\t\tawait (super[key] += 2),\n\n\t\t\t\t\t\t\tawait ++super.foo,\n\t\t\t\t\t\t\tawait ++super[key],\n\t\t\t\t\t\t\tawait super.foo++,\n\t\t\t\t\t\t\tawait super[key]++,\n\n\t\t\t\t\t\t\tawait super.foo.name,\n\t\t\t\t\t\t\tawait super[key].name,\n\t\t\t\t\t\t\tawait super.foo?.name,\n\t\t\t\t\t\t\tawait super[key]?.name,\n\n\t\t\t\t\t\t\tawait super.foo(1, 2),\n\t\t\t\t\t\t\tawait super[key](1, 2),\n\t\t\t\t\t\t\tawait super.foo?.(1, 2),\n\t\t\t\t\t\t\tawait super[key]?.(1, 2),\n\n\t\t\t\t\t\t\tawait (() => super.foo)(),\n\t\t\t\t\t\t\tawait (() => super[key])(),\n\t\t\t\t\t\t\tawait (() => super.foo())(),\n\t\t\t\t\t\t\tawait (() => super[key]())(),\n\n\t\t\t\t\t\t\tawait super.foo` + \"``\" + `,\n\t\t\t\t\t\t\tawait super[key]` + \"``\" + `,\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// This covers a bug that caused a compiler crash\n\t\t\t\tlet fn = async () => class extends Base {\n\t\t\t\t\ta = super.a\n\t\t\t\t\tb = () => super.b\n\t\t\t\t\tc() { return super.c }\n\t\t\t\t\td() { return () => super.d }\n\t\t\t\t}\n\n\t\t\t\t// This covers a bug that generated bad code\n\t\t\t\tclass Derived2 extends Base {\n\t\t\t\t\tasync a() { return class { [super.foo] = 123 } }\n\t\t\t\t\tb = async () => class { [super.foo] = 123 }\n\t\t\t\t}\n\n\t\t\t\t// This covers putting the generated temporary variable inside the loop\n\t\t\t\tfor (let i = 0; i < 3; i++) {\n\t\t\t\t\tobjs.push({\n\t\t\t\t\t\t__proto__: {\n\t\t\t\t\t\t\tfoo() { return i },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tasync bar() { return super.foo() },\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2016),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerStaticAsyncSuperES2021NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Derived extends Base {\n\t\t\t\t\tstatic test = async (key) => {\n\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\tawait super.foo,\n\t\t\t\t\t\t\tawait super[key],\n\t\t\t\t\t\t\tawait ([super.foo] = [0]),\n\t\t\t\t\t\t\tawait ([super[key]] = [0]),\n\n\t\t\t\t\t\t\tawait (super.foo = 1),\n\t\t\t\t\t\t\tawait (super[key] = 1),\n\t\t\t\t\t\t\tawait (super.foo += 2),\n\t\t\t\t\t\t\tawait (super[key] += 2),\n\n\t\t\t\t\t\t\tawait ++super.foo,\n\t\t\t\t\t\t\tawait ++super[key],\n\t\t\t\t\t\t\tawait super.foo++,\n\t\t\t\t\t\t\tawait super[key]++,\n\n\t\t\t\t\t\t\tawait super.foo.name,\n\t\t\t\t\t\t\tawait super[key].name,\n\t\t\t\t\t\t\tawait super.foo?.name,\n\t\t\t\t\t\t\tawait super[key]?.name,\n\n\t\t\t\t\t\t\tawait super.foo(1, 2),\n\t\t\t\t\t\t\tawait super[key](1, 2),\n\t\t\t\t\t\t\tawait super.foo?.(1, 2),\n\t\t\t\t\t\t\tawait super[key]?.(1, 2),\n\n\t\t\t\t\t\t\tawait (() => super.foo)(),\n\t\t\t\t\t\t\tawait (() => super[key])(),\n\t\t\t\t\t\t\tawait (() => super.foo())(),\n\t\t\t\t\t\t\tawait (() => super[key]())(),\n\n\t\t\t\t\t\t\tawait super.foo` + \"``\" + `,\n\t\t\t\t\t\t\tawait super[key]` + \"``\" + `,\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// This covers a bug that caused a compiler crash\n\t\t\t\tlet fn = async () => class extends Base {\n\t\t\t\t\tstatic a = super.a\n\t\t\t\t\tstatic b = () => super.b\n\t\t\t\t\tstatic c() { return super.c }\n\t\t\t\t\tstatic d() { return () => super.d }\n\t\t\t\t}\n\n\t\t\t\t// This covers a bug that generated bad code\n\t\t\t\tclass Derived2 extends Base {\n\t\t\t\t\tstatic async a() { return class { [super.foo] = 123 } }\n\t\t\t\t\tstatic b = async () => class { [super.foo] = 123 }\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2021),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerStaticAsyncSuperES2016NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Derived extends Base {\n\t\t\t\t\tstatic test = async (key) => {\n\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\tawait super.foo,\n\t\t\t\t\t\t\tawait super[key],\n\t\t\t\t\t\t\tawait ([super.foo] = [0]),\n\t\t\t\t\t\t\tawait ([super[key]] = [0]),\n\n\t\t\t\t\t\t\tawait (super.foo = 1),\n\t\t\t\t\t\t\tawait (super[key] = 1),\n\t\t\t\t\t\t\tawait (super.foo += 2),\n\t\t\t\t\t\t\tawait (super[key] += 2),\n\n\t\t\t\t\t\t\tawait ++super.foo,\n\t\t\t\t\t\t\tawait ++super[key],\n\t\t\t\t\t\t\tawait super.foo++,\n\t\t\t\t\t\t\tawait super[key]++,\n\n\t\t\t\t\t\t\tawait super.foo.name,\n\t\t\t\t\t\t\tawait super[key].name,\n\t\t\t\t\t\t\tawait super.foo?.name,\n\t\t\t\t\t\t\tawait super[key]?.name,\n\n\t\t\t\t\t\t\tawait super.foo(1, 2),\n\t\t\t\t\t\t\tawait super[key](1, 2),\n\t\t\t\t\t\t\tawait super.foo?.(1, 2),\n\t\t\t\t\t\t\tawait super[key]?.(1, 2),\n\n\t\t\t\t\t\t\tawait (() => super.foo)(),\n\t\t\t\t\t\t\tawait (() => super[key])(),\n\t\t\t\t\t\t\tawait (() => super.foo())(),\n\t\t\t\t\t\t\tawait (() => super[key]())(),\n\n\t\t\t\t\t\t\tawait super.foo` + \"``\" + `,\n\t\t\t\t\t\t\tawait super[key]` + \"``\" + `,\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// This covers a bug that caused a compiler crash\n\t\t\t\tlet fn = async () => class extends Base {\n\t\t\t\t\tstatic a = super.a\n\t\t\t\t\tstatic b = () => super.b\n\t\t\t\t\tstatic c() { return super.c }\n\t\t\t\t\tstatic d() { return () => super.d }\n\t\t\t\t}\n\n\t\t\t\t// This covers a bug that generated bad code\n\t\t\t\tclass Derived2 extends Base {\n\t\t\t\t\tstatic async a() { return class { [super.foo] = 123 } }\n\t\t\t\t\tstatic b = async () => class { [super.foo] = 123 }\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2016),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerStaticSuperES2021NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Derived extends Base {\n\t\t\t\t\tstatic test = key => {\n\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\tsuper.foo,\n\t\t\t\t\t\t\tsuper[key],\n\t\t\t\t\t\t\t([super.foo] = [0]),\n\t\t\t\t\t\t\t([super[key]] = [0]),\n\n\t\t\t\t\t\t\t(super.foo = 1),\n\t\t\t\t\t\t\t(super[key] = 1),\n\t\t\t\t\t\t\t(super.foo += 2),\n\t\t\t\t\t\t\t(super[key] += 2),\n\n\t\t\t\t\t\t\t++super.foo,\n\t\t\t\t\t\t\t++super[key],\n\t\t\t\t\t\t\tsuper.foo++,\n\t\t\t\t\t\t\tsuper[key]++,\n\n\t\t\t\t\t\t\tsuper.foo.name,\n\t\t\t\t\t\t\tsuper[key].name,\n\t\t\t\t\t\t\tsuper.foo?.name,\n\t\t\t\t\t\t\tsuper[key]?.name,\n\n\t\t\t\t\t\t\tsuper.foo(1, 2),\n\t\t\t\t\t\t\tsuper[key](1, 2),\n\t\t\t\t\t\t\tsuper.foo?.(1, 2),\n\t\t\t\t\t\t\tsuper[key]?.(1, 2),\n\n\t\t\t\t\t\t\t(() => super.foo)(),\n\t\t\t\t\t\t\t(() => super[key])(),\n\t\t\t\t\t\t\t(() => super.foo())(),\n\t\t\t\t\t\t\t(() => super[key]())(),\n\n\t\t\t\t\t\t\tsuper.foo` + \"``\" + `,\n\t\t\t\t\t\t\tsuper[key]` + \"``\" + `,\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2021),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerStaticSuperES2016NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Derived extends Base {\n\t\t\t\t\tstatic test = key => {\n\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\tsuper.foo,\n\t\t\t\t\t\t\tsuper[key],\n\t\t\t\t\t\t\t([super.foo] = [0]),\n\t\t\t\t\t\t\t([super[key]] = [0]),\n\n\t\t\t\t\t\t\t(super.foo = 1),\n\t\t\t\t\t\t\t(super[key] = 1),\n\t\t\t\t\t\t\t(super.foo += 2),\n\t\t\t\t\t\t\t(super[key] += 2),\n\n\t\t\t\t\t\t\t++super.foo,\n\t\t\t\t\t\t\t++super[key],\n\t\t\t\t\t\t\tsuper.foo++,\n\t\t\t\t\t\t\tsuper[key]++,\n\n\t\t\t\t\t\t\tsuper.foo.name,\n\t\t\t\t\t\t\tsuper[key].name,\n\t\t\t\t\t\t\tsuper.foo?.name,\n\t\t\t\t\t\t\tsuper[key]?.name,\n\n\t\t\t\t\t\t\tsuper.foo(1, 2),\n\t\t\t\t\t\t\tsuper[key](1, 2),\n\t\t\t\t\t\t\tsuper.foo?.(1, 2),\n\t\t\t\t\t\t\tsuper[key]?.(1, 2),\n\n\t\t\t\t\t\t\t(() => super.foo)(),\n\t\t\t\t\t\t\t(() => super[key])(),\n\t\t\t\t\t\t\t(() => super.foo())(),\n\t\t\t\t\t\t\t(() => super[key]())(),\n\n\t\t\t\t\t\t\tsuper.foo` + \"``\" + `,\n\t\t\t\t\t\t\tsuper[key]` + \"``\" + `,\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2016),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerAsyncArrowSuperES2016(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport { default as foo1 } from \"./foo1\"\n\t\t\t\texport { default as foo2 } from \"./foo2\"\n\t\t\t\texport { default as foo3 } from \"./foo3\"\n\t\t\t\texport { default as foo4 } from \"./foo4\"\n\t\t\t\texport { default as bar1 } from \"./bar1\"\n\t\t\t\texport { default as bar2 } from \"./bar2\"\n\t\t\t\texport { default as bar3 } from \"./bar3\"\n\t\t\t\texport { default as bar4 } from \"./bar4\"\n\t\t\t\texport { default as baz1 } from \"./baz1\"\n\t\t\t\texport { default as baz2 } from \"./baz2\"\n\t\t\t\timport \"./outer\"\n\t\t\t`,\n\t\t\t\"/foo1.js\": `export default class extends x { foo1() { return async () => super.foo('foo1') } }`,\n\t\t\t\"/foo2.js\": `export default class extends x { foo2() { return async () => () => super.foo('foo2') } }`,\n\t\t\t\"/foo3.js\": `export default class extends x { foo3() { return () => async () => super.foo('foo3') } }`,\n\t\t\t\"/foo4.js\": `export default class extends x { foo4() { return async () => async () => super.foo('foo4') } }`,\n\t\t\t\"/bar1.js\": `export default class extends x { bar1 = async () => super.foo('bar1') }`,\n\t\t\t\"/bar2.js\": `export default class extends x { bar2 = async () => () => super.foo('bar2') }`,\n\t\t\t\"/bar3.js\": `export default class extends x { bar3 = () => async () => super.foo('bar3') }`,\n\t\t\t\"/bar4.js\": `export default class extends x { bar4 = async () => async () => super.foo('bar4') }`,\n\t\t\t\"/baz1.js\": `export default class extends x { async baz1() { return () => super.foo('baz1') } }`,\n\t\t\t\"/baz2.js\": `export default class extends x { async baz2() { return () => () => super.foo('baz2') } }`,\n\t\t\t\"/outer.js\": `\n\t\t\t\t// Helper functions for \"super\" shouldn't be inserted into this outer function\n\t\t\t\texport default (async function () {\n\t\t\t\t\tclass y extends z {\n\t\t\t\t\t\tfoo = async () => super.foo()\n\t\t\t\t\t}\n\t\t\t\t\tawait new y().foo()()\n\t\t\t\t})()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2016),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerAsyncArrowSuperSetterES2016(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport { default as foo1 } from \"./foo1\"\n\t\t\t\texport { default as foo2 } from \"./foo2\"\n\t\t\t\texport { default as foo3 } from \"./foo3\"\n\t\t\t\texport { default as foo4 } from \"./foo4\"\n\t\t\t\texport { default as bar1 } from \"./bar1\"\n\t\t\t\texport { default as bar2 } from \"./bar2\"\n\t\t\t\texport { default as bar3 } from \"./bar3\"\n\t\t\t\texport { default as bar4 } from \"./bar4\"\n\t\t\t\texport { default as baz1 } from \"./baz1\"\n\t\t\t\texport { default as baz2 } from \"./baz2\"\n\t\t\t\timport \"./outer\"\n\t\t\t`,\n\t\t\t\"/foo1.js\": `export default class extends x { foo1() { return async () => super.foo = 'foo1' } }`,\n\t\t\t\"/foo2.js\": `export default class extends x { foo2() { return async () => () => super.foo = 'foo2' } }`,\n\t\t\t\"/foo3.js\": `export default class extends x { foo3() { return () => async () => super.foo = 'foo3' } }`,\n\t\t\t\"/foo4.js\": `export default class extends x { foo4() { return async () => async () => super.foo = 'foo4' } }`,\n\t\t\t\"/bar1.js\": `export default class extends x { bar1 = async () => super.foo = 'bar1' }`,\n\t\t\t\"/bar2.js\": `export default class extends x { bar2 = async () => () => super.foo = 'bar2' }`,\n\t\t\t\"/bar3.js\": `export default class extends x { bar3 = () => async () => super.foo = 'bar3' }`,\n\t\t\t\"/bar4.js\": `export default class extends x { bar4 = async () => async () => super.foo = 'bar4' }`,\n\t\t\t\"/baz1.js\": `export default class extends x { async baz1() { return () => super.foo = 'baz1' } }`,\n\t\t\t\"/baz2.js\": `export default class extends x { async baz2() { return () => () => super.foo = 'baz2' } }`,\n\t\t\t\"/outer.js\": `\n\t\t\t\t// Helper functions for \"super\" shouldn't be inserted into this outer function\n\t\t\t\texport default (async function () {\n\t\t\t\t\tclass y extends z {\n\t\t\t\t\t\tfoo = async () => super.foo = 'foo'\n\t\t\t\t\t}\n\t\t\t\t\tawait new y().foo()()\n\t\t\t\t})()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2016),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerStaticAsyncArrowSuperES2016(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport { default as foo1 } from \"./foo1\"\n\t\t\t\texport { default as foo2 } from \"./foo2\"\n\t\t\t\texport { default as foo3 } from \"./foo3\"\n\t\t\t\texport { default as foo4 } from \"./foo4\"\n\t\t\t\texport { default as bar1 } from \"./bar1\"\n\t\t\t\texport { default as bar2 } from \"./bar2\"\n\t\t\t\texport { default as bar3 } from \"./bar3\"\n\t\t\t\texport { default as bar4 } from \"./bar4\"\n\t\t\t\texport { default as baz1 } from \"./baz1\"\n\t\t\t\texport { default as baz2 } from \"./baz2\"\n\t\t\t\timport \"./outer\"\n\t\t\t`,\n\t\t\t\"/foo1.js\": `export default class extends x { static foo1() { return async () => super.foo('foo1') } }`,\n\t\t\t\"/foo2.js\": `export default class extends x { static foo2() { return async () => () => super.foo('foo2') } }`,\n\t\t\t\"/foo3.js\": `export default class extends x { static foo3() { return () => async () => super.foo('foo3') } }`,\n\t\t\t\"/foo4.js\": `export default class extends x { static foo4() { return async () => async () => super.foo('foo4') } }`,\n\t\t\t\"/bar1.js\": `export default class extends x { static bar1 = async () => super.foo('bar1') }`,\n\t\t\t\"/bar2.js\": `export default class extends x { static bar2 = async () => () => super.foo('bar2') }`,\n\t\t\t\"/bar3.js\": `export default class extends x { static bar3 = () => async () => super.foo('bar3') }`,\n\t\t\t\"/bar4.js\": `export default class extends x { static bar4 = async () => async () => super.foo('bar4') }`,\n\t\t\t\"/baz1.js\": `export default class extends x { static async baz1() { return () => super.foo('baz1') } }`,\n\t\t\t\"/baz2.js\": `export default class extends x { static async baz2() { return () => () => super.foo('baz2') } }`,\n\t\t\t\"/outer.js\": `\n\t\t\t\t// Helper functions for \"super\" shouldn't be inserted into this outer function\n\t\t\t\texport default (async function () {\n\t\t\t\t\tclass y extends z {\n\t\t\t\t\t\tstatic foo = async () => super.foo()\n\t\t\t\t\t}\n\t\t\t\t\tawait y.foo()()\n\t\t\t\t})()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2016),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerStaticAsyncArrowSuperSetterES2016(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport { default as foo1 } from \"./foo1\"\n\t\t\t\texport { default as foo2 } from \"./foo2\"\n\t\t\t\texport { default as foo3 } from \"./foo3\"\n\t\t\t\texport { default as foo4 } from \"./foo4\"\n\t\t\t\texport { default as bar1 } from \"./bar1\"\n\t\t\t\texport { default as bar2 } from \"./bar2\"\n\t\t\t\texport { default as bar3 } from \"./bar3\"\n\t\t\t\texport { default as bar4 } from \"./bar4\"\n\t\t\t\texport { default as baz1 } from \"./baz1\"\n\t\t\t\texport { default as baz2 } from \"./baz2\"\n\t\t\t\timport \"./outer\"\n\t\t\t`,\n\t\t\t\"/foo1.js\": `export default class extends x { static foo1() { return async () => super.foo = 'foo1' } }`,\n\t\t\t\"/foo2.js\": `export default class extends x { static foo2() { return async () => () => super.foo = 'foo2' } }`,\n\t\t\t\"/foo3.js\": `export default class extends x { static foo3() { return () => async () => super.foo = 'foo3' } }`,\n\t\t\t\"/foo4.js\": `export default class extends x { static foo4() { return async () => async () => super.foo = 'foo4' } }`,\n\t\t\t\"/bar1.js\": `export default class extends x { static bar1 = async () => super.foo = 'bar1' }`,\n\t\t\t\"/bar2.js\": `export default class extends x { static bar2 = async () => () => super.foo = 'bar2' }`,\n\t\t\t\"/bar3.js\": `export default class extends x { static bar3 = () => async () => super.foo = 'bar3' }`,\n\t\t\t\"/bar4.js\": `export default class extends x { static bar4 = async () => async () => super.foo = 'bar4' }`,\n\t\t\t\"/baz1.js\": `export default class extends x { static async baz1() { return () => super.foo = 'baz1' } }`,\n\t\t\t\"/baz2.js\": `export default class extends x { static async baz2() { return () => () => super.foo = 'baz2' } }`,\n\t\t\t\"/outer.js\": `\n\t\t\t\t// Helper functions for \"super\" shouldn't be inserted into this outer function\n\t\t\t\texport default (async function () {\n\t\t\t\t\tclass y extends z {\n\t\t\t\t\t\tstatic foo = async () => super.foo = 'foo'\n\t\t\t\t\t}\n\t\t\t\t\tawait y.foo()()\n\t\t\t\t})()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2016),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateSuperES2022(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport { default as foo1 } from \"./foo1\"\n\t\t\t\texport { default as foo2 } from \"./foo2\"\n\t\t\t\texport { default as foo3 } from \"./foo3\"\n\t\t\t\texport { default as foo4 } from \"./foo4\"\n\t\t\t\texport { default as foo5 } from \"./foo5\"\n\t\t\t\texport { default as foo6 } from \"./foo6\"\n\t\t\t\texport { default as foo7 } from \"./foo7\"\n\t\t\t\texport { default as foo8 } from \"./foo8\"\n\t\t\t`,\n\t\t\t\"/foo1.js\": `export default class extends x { #foo() { super.foo() } }`,\n\t\t\t\"/foo2.js\": `export default class extends x { #foo() { super.foo++ } }`,\n\t\t\t\"/foo3.js\": `export default class extends x { static #foo() { super.foo() } }`,\n\t\t\t\"/foo4.js\": `export default class extends x { static #foo() { super.foo++ } }`,\n\t\t\t\"/foo5.js\": `export default class extends x { #foo = () => { super.foo() } }`,\n\t\t\t\"/foo6.js\": `export default class extends x { #foo = () => { super.foo++ } }`,\n\t\t\t\"/foo7.js\": `export default class extends x { static #foo = () => { super.foo() } }`,\n\t\t\t\"/foo8.js\": `export default class extends x { static #foo = () => { super.foo++ } }`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2022),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateSuperES2021(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport { default as foo1 } from \"./foo1\"\n\t\t\t\texport { default as foo2 } from \"./foo2\"\n\t\t\t\texport { default as foo3 } from \"./foo3\"\n\t\t\t\texport { default as foo4 } from \"./foo4\"\n\t\t\t\texport { default as foo5 } from \"./foo5\"\n\t\t\t\texport { default as foo6 } from \"./foo6\"\n\t\t\t\texport { default as foo7 } from \"./foo7\"\n\t\t\t\texport { default as foo8 } from \"./foo8\"\n\t\t\t`,\n\t\t\t\"/foo1.js\": `export default class extends x { #foo() { super.foo() } }`,\n\t\t\t\"/foo2.js\": `export default class extends x { #foo() { super.foo++ } }`,\n\t\t\t\"/foo3.js\": `export default class extends x { static #foo() { super.foo() } }`,\n\t\t\t\"/foo4.js\": `export default class extends x { static #foo() { super.foo++ } }`,\n\t\t\t\"/foo5.js\": `export default class extends x { #foo = () => { super.foo() } }`,\n\t\t\t\"/foo6.js\": `export default class extends x { #foo = () => { super.foo++ } }`,\n\t\t\t\"/foo7.js\": `export default class extends x { static #foo = () => { super.foo() } }`,\n\t\t\t\"/foo8.js\": `export default class extends x { static #foo = () => { super.foo++ } }`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2021),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\n// https://github.com/evanw/esbuild/issues/2158\nfunc TestLowerPrivateSuperStaticBundleIssue2158(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport class Foo extends Object {\n\t\t\t\t\tstatic FOO;\n\t\t\t\t\tconstructor() {\n\t\t\t\t\t\tsuper();\n\t\t\t\t\t}\n\t\t\t\t\t#foo;\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerClassField2020NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#foo = 123\n\t\t\t\t\t#bar\n\t\t\t\t\tfoo = 123\n\t\t\t\t\tbar\n\t\t\t\t\tstatic #s_foo = 123\n\t\t\t\t\tstatic #s_bar\n\t\t\t\t\tstatic s_foo = 123\n\t\t\t\t\tstatic s_bar\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2020),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerClassFieldNextNoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#foo = 123\n\t\t\t\t\t#bar\n\t\t\t\t\tfoo = 123\n\t\t\t\t\tbar\n\t\t\t\t\tstatic #s_foo = 123\n\t\t\t\t\tstatic #s_bar\n\t\t\t\t\tstatic s_foo = 123\n\t\t\t\t\tstatic s_bar\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSLowerClassField2020NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#foo = 123\n\t\t\t\t\t#bar\n\t\t\t\t\tfoo = 123\n\t\t\t\t\tbar\n\t\t\t\t\tstatic #s_foo = 123\n\t\t\t\t\tstatic #s_bar\n\t\t\t\t\tstatic s_foo = 123\n\t\t\t\t\tstatic s_bar\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": false\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2020),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSLowerClassPrivateFieldNextNoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#foo = 123\n\t\t\t\t\t#bar\n\t\t\t\t\tfoo = 123\n\t\t\t\t\tbar\n\t\t\t\t\tstatic #s_foo = 123\n\t\t\t\t\tstatic #s_bar\n\t\t\t\t\tstatic s_foo = 123\n\t\t\t\t\tstatic s_bar\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": false\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerClassFieldStrictTsconfigJson2020(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport loose from './loose'\n\t\t\t\timport strict from './strict'\n\t\t\t\tconsole.log(loose, strict)\n\t\t\t`,\n\t\t\t\"/loose/index.js\": `\n\t\t\t\texport default class {\n\t\t\t\t\tfoo\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/loose/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"useDefineForClassFields\": false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/strict/index.js\": `\n\t\t\t\texport default class {\n\t\t\t\t\tfoo\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/strict/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"useDefineForClassFields\": true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2020),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSLowerClassFieldStrictTsconfigJson2020(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport loose from './loose'\n\t\t\t\timport strict from './strict'\n\t\t\t\tconsole.log(loose, strict)\n\t\t\t`,\n\t\t\t\"/loose/index.ts\": `\n\t\t\t\texport default class {\n\t\t\t\t\tfoo\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/loose/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"useDefineForClassFields\": false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/strict/index.ts\": `\n\t\t\t\texport default class {\n\t\t\t\t\tfoo\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/strict/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"useDefineForClassFields\": true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2020),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSLowerObjectRest2017NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tconst { ...local_const } = {};\n\t\t\t\tlet { ...local_let } = {};\n\t\t\t\tvar { ...local_var } = {};\n\t\t\t\tlet arrow_fn = ({ ...x }) => { };\n\t\t\t\tlet fn_expr = function ({ ...x } = default_value) {};\n\t\t\t\tlet class_expr = class { method(x, ...[y, { ...z }]) {} };\n\n\t\t\t\tfunction fn_stmt({ a = b(), ...x }, { c = d(), ...y }) {}\n\t\t\t\tclass class_stmt { method({ ...x }) {} }\n\t\t\t\tnamespace ns { export let { ...x } = {} }\n\t\t\t\ttry { } catch ({ ...catch_clause }) {}\n\n\t\t\t\tfor (const { ...for_in_const } in { abc }) {}\n\t\t\t\tfor (let { ...for_in_let } in { abc }) {}\n\t\t\t\tfor (var { ...for_in_var } in { abc }) ;\n\t\t\t\tfor (const { ...for_of_const } of [{}]) ;\n\t\t\t\tfor (let { ...for_of_let } of [{}]) x()\n\t\t\t\tfor (var { ...for_of_var } of [{}]) x()\n\t\t\t\tfor (const { ...for_const } = {}; x; x = null) {}\n\t\t\t\tfor (let { ...for_let } = {}; x; x = null) {}\n\t\t\t\tfor (var { ...for_var } = {}; x; x = null) {}\n\t\t\t\tfor ({ ...x } in { abc }) {}\n\t\t\t\tfor ({ ...x } of [{}]) {}\n\t\t\t\tfor ({ ...x } = {}; x; x = null) {}\n\n\t\t\t\t({ ...assign } = {});\n\t\t\t\t({ obj_method({ ...x }) {} });\n\n\t\t\t\t// Check for used return values\n\t\t\t\t({ ...x } = x);\n\t\t\t\tfor ({ ...x } = x; 0; ) ;\n\t\t\t\tconsole.log({ ...x } = x);\n\t\t\t\tconsole.log({ x, ...xx } = { x });\n\t\t\t\tconsole.log({ x: { ...xx } } = { x });\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2017),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSLowerObjectRest2018NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tconst { ...local_const } = {};\n\t\t\t\tlet { ...local_let } = {};\n\t\t\t\tvar { ...local_var } = {};\n\t\t\t\tlet arrow_fn = ({ ...x }) => { };\n\t\t\t\tlet fn_expr = function ({ ...x } = default_value) {};\n\t\t\t\tlet class_expr = class { method(x, ...[y, { ...z }]) {} };\n\n\t\t\t\tfunction fn_stmt({ a = b(), ...x }, { c = d(), ...y }) {}\n\t\t\t\tclass class_stmt { method({ ...x }) {} }\n\t\t\t\tnamespace ns { export let { ...x } = {} }\n\t\t\t\ttry { } catch ({ ...catch_clause }) {}\n\n\t\t\t\tfor (const { ...for_in_const } in { abc }) {}\n\t\t\t\tfor (let { ...for_in_let } in { abc }) {}\n\t\t\t\tfor (var { ...for_in_var } in { abc }) ;\n\t\t\t\tfor (const { ...for_of_const } of [{}]) ;\n\t\t\t\tfor (let { ...for_of_let } of [{}]) x()\n\t\t\t\tfor (var { ...for_of_var } of [{}]) x()\n\t\t\t\tfor (const { ...for_const } = {}; x; x = null) {}\n\t\t\t\tfor (let { ...for_let } = {}; x; x = null) {}\n\t\t\t\tfor (var { ...for_var } = {}; x; x = null) {}\n\t\t\t\tfor ({ ...x } in { abc }) {}\n\t\t\t\tfor ({ ...x } of [{}]) {}\n\t\t\t\tfor ({ ...x } = {}; x; x = null) {}\n\n\t\t\t\t({ ...assign } = {});\n\t\t\t\t({ obj_method({ ...x }) {} });\n\n\t\t\t\t// Check for used return values\n\t\t\t\t({ ...x } = x);\n\t\t\t\tfor ({ ...x } = x; 0; ) ;\n\t\t\t\tconsole.log({ ...x } = x);\n\t\t\t\tconsole.log({ x, ...xx } = { x });\n\t\t\t\tconsole.log({ x: { ...xx } } = { x });\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2018),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestClassSuperThisIssue242NoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\texport class A {}\n\n\t\t\t\texport class B extends A {\n\t\t\t\t\t#e: string\n\t\t\t\t\tconstructor(c: { d: any }) {\n\t\t\t\t\t\tsuper()\n\t\t\t\t\t\tthis.#e = c.d ?? 'test'\n\t\t\t\t\t}\n\t\t\t\t\tf() {\n\t\t\t\t\t\treturn this.#e\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2019),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerExportStarAsNameCollisionNoBundle(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport * as ns from 'path'\n\t\t\t\tlet ns = 123\n\t\t\t\texport {ns as sn}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tUnsupportedJSFeatures: es(2019),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerExportStarAsNameCollision(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as test from './nested'\n\t\t\t\tconsole.log(test.foo, test.oof)\n\t\t\t\texport * as ns from 'path1'\n\t\t\t\tlet ns = 123\n\t\t\t\texport {ns as sn}\n\t\t\t`,\n\t\t\t\"/nested.js\": `\n\t\t\t\texport * as foo from 'path2'\n\t\t\t\tlet foo = 123\n\t\t\t\texport {foo as oof}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tUnsupportedJSFeatures: es(2019),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"path1\": true,\n\t\t\t\t\t\"path2\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestLowerStrictModeSyntax(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport './for-in'\n\t\t\t`,\n\t\t\t\"/for-in.js\": `\n\t\t\t\tif (test)\n\t\t\t\t\tfor (var a = b in {}) ;\n\t\t\t\tfor (var x = y in {}) ;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerForbidStrictModeSyntax(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport './with'\n\t\t\t\timport './delete-1'\n\t\t\t\timport './delete-2'\n\t\t\t\timport './delete-3'\n\t\t\t`,\n\t\t\t\"/with.js\": `\n\t\t\t\twith (x) y\n\t\t\t`,\n\t\t\t\"/delete-1.js\": `\n\t\t\t\tdelete x\n\t\t\t`,\n\t\t\t\"/delete-2.js\": `\n\t\t\t\tdelete (y)\n\t\t\t`,\n\t\t\t\"/delete-3.js\": `\n\t\t\t\tdelete (1 ? z : z)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `delete-1.js: ERROR: Delete of a bare identifier cannot be used with the \"esm\" output format due to strict mode\ndelete-2.js: ERROR: Delete of a bare identifier cannot be used with the \"esm\" output format due to strict mode\nwith.js: ERROR: With statements cannot be used with the \"esm\" output format due to strict mode\n`,\n\t})\n}\n\nfunc TestLowerPrivateClassFieldOrder(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#foo = 123 // This must be set before \"bar\" is initialized\n\t\t\t\t\tbar = this.#foo\n\t\t\t\t}\n\t\t\t\tconsole.log(new Foo().bar === 123)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.ClassPrivateField,\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateClassMethodOrder(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\tbar = this.#foo()\n\t\t\t\t\t#foo() { return 123 } // This must be set before \"bar\" is initialized\n\t\t\t\t}\n\t\t\t\tconsole.log(new Foo().bar === 123)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.ClassPrivateMethod,\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateClassAccessorOrder(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\tbar = this.#foo\n\t\t\t\t\tget #foo() { return 123 } // This must be set before \"bar\" is initialized\n\t\t\t\t}\n\t\t\t\tconsole.log(new Foo().bar === 123)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.ClassPrivateAccessor,\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateClassStaticFieldOrder(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\tstatic #foo = 123 // This must be set before \"bar\" is initialized\n\t\t\t\t\tstatic bar = Foo.#foo\n\t\t\t\t}\n\t\t\t\tconsole.log(Foo.bar === 123)\n\n\t\t\t\tclass FooThis {\n\t\t\t\t\tstatic #foo = 123 // This must be set before \"bar\" is initialized\n\t\t\t\t\tstatic bar = this.#foo\n\t\t\t\t}\n\t\t\t\tconsole.log(FooThis.bar === 123)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.ClassPrivateStaticField,\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateClassStaticMethodOrder(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\tstatic bar = Foo.#foo()\n\t\t\t\t\tstatic #foo() { return 123 } // This must be set before \"bar\" is initialized\n\t\t\t\t}\n\t\t\t\tconsole.log(Foo.bar === 123)\n\n\t\t\t\tclass FooThis {\n\t\t\t\t\tstatic bar = this.#foo()\n\t\t\t\t\tstatic #foo() { return 123 } // This must be set before \"bar\" is initialized\n\t\t\t\t}\n\t\t\t\tconsole.log(FooThis.bar === 123)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.ClassPrivateStaticMethod,\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateClassStaticAccessorOrder(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\tstatic bar = Foo.#foo\n\t\t\t\t\tstatic get #foo() { return 123 } // This must be set before \"bar\" is initialized\n\t\t\t\t}\n\t\t\t\tconsole.log(Foo.bar === 123)\n\n\t\t\t\tclass FooThis {\n\t\t\t\t\tstatic bar = this.#foo\n\t\t\t\t\tstatic get #foo() { return 123 } // This must be set before \"bar\" is initialized\n\t\t\t\t}\n\t\t\t\tconsole.log(FooThis.bar === 123)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.ClassPrivateStaticAccessor,\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateClassBrandCheckUnsupported(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#foo\n\t\t\t\t\t#bar\n\t\t\t\t\tbaz() {\n\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\tthis.#foo,\n\t\t\t\t\t\t\tthis.#bar,\n\t\t\t\t\t\t\t#foo in this,\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.ClassPrivateBrandCheck,\n\t\t},\n\t})\n}\n\nfunc TestLowerPrivateClassBrandCheckSupported(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t#foo\n\t\t\t\t\t#bar\n\t\t\t\t\tbaz() {\n\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\tthis.#foo,\n\t\t\t\t\t\t\tthis.#bar,\n\t\t\t\t\t\t\t#foo in this,\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestLowerTemplateObject(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tx = () => [\n\t\t\t\t\ttag` + \"`x`\" + `,\n\t\t\t\t\ttag` + \"`\\\\xFF`\" + `,\n\t\t\t\t\ttag` + \"`\\\\x`\" + `,\n\t\t\t\t\ttag` + \"`\\\\u`\" + `,\n\t\t\t\t]\n\t\t\t\ty = () => [\n\t\t\t\t\ttag` + \"`x${y}z`\" + `,\n\t\t\t\t\ttag` + \"`\\\\xFF${y}z`\" + `,\n\t\t\t\t\ttag` + \"`x${y}\\\\z`\" + `,\n\t\t\t\t\ttag` + \"`x${y}\\\\u`\" + `,\n\t\t\t\t]\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.TemplateLiteral,\n\t\t},\n\t})\n}\n\n// See https://github.com/evanw/esbuild/issues/1424 for more information\nfunc TestLowerPrivateClassFieldStaticIssue1424(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass T {\n\t\t\t\t\t#a() { return 'a'; }\n\t\t\t\t\t#b() { return 'b'; }\n\t\t\t\t\tstatic c;\n\t\t\t\t\td() { console.log(this.#a()); }\n\t\t\t\t}\n\t\t\t\tnew T().d();\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.ClassPrivateMethod,\n\t\t},\n\t})\n}\n\n// See https://github.com/evanw/esbuild/issues/1493 for more information\nfunc TestLowerNullishCoalescingAssignmentIssue1493(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport class A {\n\t\t\t\t\t#a;\n\t\t\t\t\tf() {\n\t\t\t\t\t\tthis.#a ??= 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.LogicalAssignment,\n\t\t},\n\t})\n}\n\nfunc TestStaticClassBlockESNext(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass A {\n\t\t\t\t\tstatic {}\n\t\t\t\t\tstatic {\n\t\t\t\t\t\tthis.thisField++\n\t\t\t\t\t\tA.classField++\n\t\t\t\t\t\tsuper.superField = super.superField + 1\n\t\t\t\t\t\tsuper.superField++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlet B = class {\n\t\t\t\t\tstatic {}\n\t\t\t\t\tstatic {\n\t\t\t\t\t\tthis.thisField++\n\t\t\t\t\t\tsuper.superField = super.superField + 1\n\t\t\t\t\t\tsuper.superField++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestStaticClassBlockES2021(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tclass A {\n\t\t\t\t\tstatic {}\n\t\t\t\t\tstatic {\n\t\t\t\t\t\tthis.thisField++\n\t\t\t\t\t\tA.classField++\n\t\t\t\t\t\tsuper.superField = super.superField + 1\n\t\t\t\t\t\tsuper.superField++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlet B = class {\n\t\t\t\t\tstatic {}\n\t\t\t\t\tstatic {\n\t\t\t\t\t\tthis.thisField++\n\t\t\t\t\t\tsuper.superField = super.superField + 1\n\t\t\t\t\t\tsuper.superField++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: es(2021),\n\t\t},\n\t})\n}\n\nfunc TestLowerRegExpNameCollision(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport function foo(RegExp) {\n\t\t\t\t\treturn new RegExp(/./d, 'd')\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: es(2021),\n\t\t},\n\t})\n}\n\nfunc TestLowerForAwait2017(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport default [\n\t\t\t\t\tasync () => { for await (x of y) z(x) },\n\t\t\t\t\tasync () => { for await (x.y of y) z(x) },\n\t\t\t\t\tasync () => { for await (let x of y) z(x) },\n\t\t\t\t\tasync () => { for await (const x of y) z(x) },\n\t\t\t\t\tasync () => { label: for await (const x of y) break label },\n\t\t\t\t\tasync () => { label: for await (const x of y) continue label },\n\t\t\t\t]\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: es(2017),\n\t\t},\n\t})\n}\n\nfunc TestLowerForAwait2015(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\texport default [\n\t\t\t\t\tasync () => { for await (x of y) z(x) },\n\t\t\t\t\tasync () => { for await (x.y of y) z(x) },\n\t\t\t\t\tasync () => { for await (let x of y) z(x) },\n\t\t\t\t\tasync () => { for await (const x of y) z(x) },\n\t\t\t\t\tasync () => { label: for await (const x of y) break label },\n\t\t\t\t\tasync () => { label: for await (const x of y) continue label },\n\t\t\t\t]\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: es(2015),\n\t\t},\n\t})\n}\n\nfunc TestLowerNestedFunctionDirectEval(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/1.js\": \"if (foo) { function x() {} }\",\n\t\t\t\"/2.js\": \"if (foo) { function x() {} eval('') }\",\n\t\t\t\"/3.js\": \"if (foo) { function x() {} if (bar) { eval('') } }\",\n\t\t\t\"/4.js\": \"if (foo) { eval(''); function x() {} }\",\n\t\t\t\"/5.js\": \"'use strict'; if (foo) { function x() {} }\",\n\t\t\t\"/6.js\": \"'use strict'; if (foo) { function x() {} eval('') }\",\n\t\t\t\"/7.js\": \"'use strict'; if (foo) { function x() {} if (bar) { eval('') } }\",\n\t\t\t\"/8.js\": \"'use strict'; if (foo) { eval(''); function x() {} }\",\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/1.js\",\n\t\t\t\"/2.js\",\n\t\t\t\"/3.js\",\n\t\t\t\"/4.js\",\n\t\t\t\"/5.js\",\n\t\t\t\"/6.js\",\n\t\t\t\"/7.js\",\n\t\t\t\"/8.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestJavaScriptDecoratorsESNext(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\t@x.y()\n\t\t\t\t@(new y.x)\n\t\t\t\texport default class Foo {\n\t\t\t\t\t@x @y mUndef\n\t\t\t\t\t@x @y mDef = 1\n\t\t\t\t\t@x @y method() { return new Foo }\n\t\t\t\t\t@x @y static sUndef\n\t\t\t\t\t@x @y static sDef = new Foo\n\t\t\t\t\t@x @y static sMethod() { return new Foo }\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestJavaScriptAutoAccessorESNext(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/js-define.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\taccessor one = 1\n\t\t\t\t\taccessor #two = 2\n\t\t\t\t\taccessor [three()] = 3\n\n\t\t\t\t\tstatic accessor four = 4\n\t\t\t\t\tstatic accessor #five = 5\n\t\t\t\t\tstatic accessor [six()] = 6\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/ts-define/ts-define.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\taccessor one = 1\n\t\t\t\t\taccessor #two = 2\n\t\t\t\t\taccessor [three()] = 3\n\n\t\t\t\t\tstatic accessor four = 4\n\t\t\t\t\tstatic accessor #five = 5\n\t\t\t\t\tstatic accessor [six()] = 6\n\t\t\t\t}\n\t\t\t\tclass Normal { accessor a = b; c = d }\n\t\t\t\tclass Private { accessor #a = b; c = d }\n\t\t\t\tclass StaticNormal { static accessor a = b; static c = d }\n\t\t\t\tclass StaticPrivate { static accessor #a = b; static c = d }\n\t\t\t`,\n\t\t\t\"/ts-define/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": true,\n\t\t\t\t},\n\t\t\t}`,\n\t\t\t\"/ts-assign/ts-assign.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\taccessor one = 1\n\t\t\t\t\taccessor #two = 2\n\t\t\t\t\taccessor [three()] = 3\n\n\t\t\t\t\tstatic accessor four = 4\n\t\t\t\t\tstatic accessor #five = 5\n\t\t\t\t\tstatic accessor [six()] = 6\n\t\t\t\t}\n\t\t\t\tclass Normal { accessor a = b; c = d }\n\t\t\t\tclass Private { accessor #a = b; c = d }\n\t\t\t\tclass StaticNormal { static accessor a = b; static c = d }\n\t\t\t\tclass StaticPrivate { static accessor #a = b; static c = d }\n\t\t\t`,\n\t\t\t\"/ts-assign/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": false,\n\t\t\t\t},\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/js-define.js\",\n\t\t\t\"/ts-define/ts-define.ts\",\n\t\t\t\"/ts-assign/ts-assign.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestJavaScriptAutoAccessorES2022(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/js-define.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\taccessor one = 1\n\t\t\t\t\taccessor #two = 2\n\t\t\t\t\taccessor [three()] = 3\n\n\t\t\t\t\tstatic accessor four = 4\n\t\t\t\t\tstatic accessor #five = 5\n\t\t\t\t\tstatic accessor [six()] = 6\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/ts-define/ts-define.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\taccessor one = 1\n\t\t\t\t\taccessor #two = 2\n\t\t\t\t\taccessor [three()] = 3\n\n\t\t\t\t\tstatic accessor four = 4\n\t\t\t\t\tstatic accessor #five = 5\n\t\t\t\t\tstatic accessor [six()] = 6\n\t\t\t\t}\n\t\t\t\tclass Normal { accessor a = b; c = d }\n\t\t\t\tclass Private { accessor #a = b; c = d }\n\t\t\t\tclass StaticNormal { static accessor a = b; static c = d }\n\t\t\t\tclass StaticPrivate { static accessor #a = b; static c = d }\n\t\t\t`,\n\t\t\t\"/ts-define/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": true,\n\t\t\t\t},\n\t\t\t}`,\n\t\t\t\"/ts-assign/ts-assign.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\taccessor one = 1\n\t\t\t\t\taccessor #two = 2\n\t\t\t\t\taccessor [three()] = 3\n\n\t\t\t\t\tstatic accessor four = 4\n\t\t\t\t\tstatic accessor #five = 5\n\t\t\t\t\tstatic accessor [six()] = 6\n\t\t\t\t}\n\t\t\t\tclass Normal { accessor a = b; c = d }\n\t\t\t\tclass Private { accessor #a = b; c = d }\n\t\t\t\tclass StaticNormal { static accessor a = b; static c = d }\n\t\t\t\tclass StaticPrivate { static accessor #a = b; static c = d }\n\t\t\t`,\n\t\t\t\"/ts-assign/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": false,\n\t\t\t\t},\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/js-define.js\",\n\t\t\t\"/ts-define/ts-define.ts\",\n\t\t\t\"/ts-assign/ts-assign.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tUnsupportedJSFeatures: es(2022),\n\t\t},\n\t})\n}\n\nfunc TestJavaScriptAutoAccessorES2021(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/js-define.js\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\taccessor one = 1\n\t\t\t\t\taccessor #two = 2\n\t\t\t\t\taccessor [three()] = 3\n\n\t\t\t\t\tstatic accessor four = 4\n\t\t\t\t\tstatic accessor #five = 5\n\t\t\t\t\tstatic accessor [six()] = 6\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/ts-define/ts-define.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\taccessor one = 1\n\t\t\t\t\taccessor #two = 2\n\t\t\t\t\taccessor [three()] = 3\n\n\t\t\t\t\tstatic accessor four = 4\n\t\t\t\t\tstatic accessor #five = 5\n\t\t\t\t\tstatic accessor [six()] = 6\n\t\t\t\t}\n\t\t\t\tclass Normal { accessor a = b; c = d }\n\t\t\t\tclass Private { accessor #a = b; c = d }\n\t\t\t\tclass StaticNormal { static accessor a = b; static c = d }\n\t\t\t\tclass StaticPrivate { static accessor #a = b; static c = d }\n\t\t\t`,\n\t\t\t\"/ts-define/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": true,\n\t\t\t\t},\n\t\t\t}`,\n\t\t\t\"/ts-assign/ts-assign.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\taccessor one = 1\n\t\t\t\t\taccessor #two = 2\n\t\t\t\t\taccessor [three()] = 3\n\n\t\t\t\t\tstatic accessor four = 4\n\t\t\t\t\tstatic accessor #five = 5\n\t\t\t\t\tstatic accessor [six()] = 6\n\t\t\t\t}\n\t\t\t\tclass Normal { accessor a = b; c = d }\n\t\t\t\tclass Private { accessor #a = b; c = d }\n\t\t\t\tclass StaticNormal { static accessor a = b; static c = d }\n\t\t\t\tclass StaticPrivate { static accessor #a = b; static c = d }\n\t\t\t`,\n\t\t\t\"/ts-assign/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": false,\n\t\t\t\t},\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/js-define.js\",\n\t\t\t\"/ts-define/ts-define.ts\",\n\t\t\t\"/ts-assign/ts-assign.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tUnsupportedJSFeatures: es(2021),\n\t\t},\n\t})\n}\n\nfunc TestLowerUsing(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tusing a = b\n\t\t\t\tawait using c = d\n\t\t\t\tif (nested) {\n\t\t\t\t\tusing x = 1\n\t\t\t\t\tawait using y = 2\n\t\t\t\t}\n\n\t\t\t\tfunction foo() {\n\t\t\t\t\tusing a = b\n\t\t\t\t\tif (nested) {\n\t\t\t\t\t\tusing x = 1\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tasync function bar() {\n\t\t\t\t\tusing a = b\n\t\t\t\t\tawait using c = d\n\t\t\t\t\tif (nested) {\n\t\t\t\t\t\tusing x = 1\n\t\t\t\t\t\tawait using y = 2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/loops.js\": `\n\t\t\t\tfor (using a of b) c(() => a)\n\t\t\t\tfor (await using d of e) f(() => d)\n\t\t\t\tfor await (using g of h) i(() => g)\n\t\t\t\tfor await (await using j of k) l(() => j)\n\n\t\t\t\tif (nested) {\n\t\t\t\t\tfor (using a of b) c(() => a)\n\t\t\t\t\tfor (await using d of e) f(() => d)\n\t\t\t\t\tfor await (using g of h) i(() => g)\n\t\t\t\t\tfor await (await using j of k) l(() => j)\n\t\t\t\t}\n\n\t\t\t\tfunction foo() {\n\t\t\t\t\tfor (using a of b) c(() => a)\n\t\t\t\t}\n\n\t\t\t\tasync function bar() {\n\t\t\t\t\tfor (using a of b) c(() => a)\n\t\t\t\t\tfor (await using d of e) f(() => d)\n\t\t\t\t\tfor await (using g of h) i(() => g)\n\t\t\t\t\tfor await (await using j of k) l(() => j)\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry.js\",\n\t\t\t\"/loops.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tUnsupportedJSFeatures: compat.Using,\n\t\t},\n\t})\n}\n\nfunc TestLowerUsingUnsupportedAsync(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction foo() {\n\t\t\t\t\tusing a = b\n\t\t\t\t\tif (nested) {\n\t\t\t\t\t\tusing x = 1\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tasync function bar() {\n\t\t\t\t\tusing a = b\n\t\t\t\t\tawait using c = d\n\t\t\t\t\tif (nested) {\n\t\t\t\t\t\tusing x = 1\n\t\t\t\t\t\tawait using y = 2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/loops.js\": `\n\t\t\t\tfor (using a of b) c(() => a)\n\n\t\t\t\tif (nested) {\n\t\t\t\t\tfor (using a of b) c(() => a)\n\t\t\t\t}\n\n\t\t\t\tfunction foo() {\n\t\t\t\t\tfor (using a of b) c(() => a)\n\t\t\t\t}\n\n\t\t\t\tasync function bar() {\n\t\t\t\t\tfor (using a of b) c(() => a)\n\t\t\t\t\tfor (await using d of e) f(() => d)\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry.js\",\n\t\t\t\"/loops.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tUnsupportedJSFeatures: compat.AsyncAwait | compat.TopLevelAwait,\n\t\t},\n\t})\n}\n\nfunc TestLowerUsingUnsupportedUsingAndAsync(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tfunction foo() {\n\t\t\t\t\tusing a = b\n\t\t\t\t\tif (nested) {\n\t\t\t\t\t\tusing x = 1\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tasync function bar() {\n\t\t\t\t\tusing a = b\n\t\t\t\t\tawait using c = d\n\t\t\t\t\tif (nested) {\n\t\t\t\t\t\tusing x = 1\n\t\t\t\t\t\tawait using y = 2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/loops.js\": `\n\t\t\t\tfor (using a of b) c(() => a)\n\n\t\t\t\tif (nested) {\n\t\t\t\t\tfor (using a of b) c(() => a)\n\t\t\t\t}\n\n\t\t\t\tfunction foo() {\n\t\t\t\t\tfor (using a of b) c(() => a)\n\t\t\t\t}\n\n\t\t\t\tasync function bar() {\n\t\t\t\t\tfor (using a of b) c(() => a)\n\t\t\t\t\tfor (await using d of e) f(() => d)\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/entry.js\",\n\t\t\t\"/loops.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tUnsupportedJSFeatures: compat.Using | compat.AsyncAwait | compat.TopLevelAwait,\n\t\t},\n\t})\n}\n\nfunc TestLowerUsingHoisting(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/hoist-use-strict.js\": `\n\t\t\t\t\"use strict\"\n\t\t\t\tusing a = b\n\t\t\t\tfunction foo() {\n\t\t\t\t\t\"use strict\"\n\t\t\t\t\tusing a = b\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/hoist-directive.js\": `\n\t\t\t\t\"use wtf\"\n\t\t\t\tusing a = b\n\t\t\t\tfunction foo() {\n\t\t\t\t\t\"use wtf\"\n\t\t\t\t\tusing a = b\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/hoist-import.js\": `\n\t\t\t\tusing a = b\n\t\t\t\timport \"./foo\"\n\t\t\t\tusing c = d\n\t\t\t`,\n\t\t\t\"/hoist-export-star.js\": `\n\t\t\t\tusing a = b\n\t\t\t\texport * from './foo'\n\t\t\t\tusing c = d\n\t\t\t`,\n\t\t\t\"/hoist-export-from.js\": `\n\t\t\t\tusing a = b\n\t\t\t\texport {x, y} from './foo'\n\t\t\t\tusing c = d\n\t\t\t`,\n\t\t\t\"/hoist-export-clause.js\": `\n\t\t\t\tusing a = b\n\t\t\t\texport {a, c as 'c!'}\n\t\t\t\tusing c = d\n\t\t\t`,\n\t\t\t\"/hoist-export-local-direct.js\": `\n\t\t\t\tusing a = b\n\t\t\t\texport var ac1 = [a, c], { x: [x1] } = foo\n\t\t\t\texport let a1 = a, { y: [y1] } = foo\n\t\t\t\texport const c1 = c, { z: [z1] } = foo\n\t\t\t\tvar ac2 = [a, c], { x: [x2] } = foo\n\t\t\t\tlet a2 = a, { y: [y2] } = foo\n\t\t\t\tconst c2 = c, { z: [z2] } = foo\n\t\t\t\tusing c = d\n\t\t\t`,\n\t\t\t\"/hoist-export-local-indirect.js\": `\n\t\t\t\tusing a = b\n\t\t\t\tvar ac1 = [a, c], { x: [x1] } = foo\n\t\t\t\tlet a1 = a, { y: [y1] } = foo\n\t\t\t\tconst c1 = c, { z: [z1] } = foo\n\t\t\t\tvar ac2 = [a, c], { x: [x2] } = foo\n\t\t\t\tlet a2 = a, { y: [y2] } = foo\n\t\t\t\tconst c2 = c, { z: [z2] } = foo\n\t\t\t\tusing c = d\n\t\t\t\texport {x1, y1, z1}\n\t\t\t`,\n\t\t\t\"/hoist-export-class-direct.js\": `\n\t\t\t\tusing a = b\n\t\t\t\texport class Foo1 { ac = [a, c] }\n\t\t\t\texport class Bar1 { ac = [a, c, Bar1] }\n\t\t\t\tclass Foo2 { ac = [a, c] }\n\t\t\t\tclass Bar2 { ac = [a, c, Bar2] }\n\t\t\t\tusing c = d\n\t\t\t`,\n\t\t\t\"/hoist-export-class-indirect.js\": `\n\t\t\t\tusing a = b\n\t\t\t\tclass Foo1 { ac = [a, c] }\n\t\t\t\tclass Bar1 { ac = [a, c, Bar1] }\n\t\t\t\tclass Foo2 { ac = [a, c] }\n\t\t\t\tclass Bar2 { ac = [a, c, Bar2] }\n\t\t\t\tusing c = d\n\t\t\t\texport {Foo1, Bar1}\n\t\t\t`,\n\t\t\t\"/hoist-export-function-direct.js\": `\n\t\t\t\tusing a = b\n\t\t\t\texport function foo1() { return [a, c] }\n\t\t\t\texport function bar1() { return [a, c, bar1] }\n\t\t\t\tfunction foo2() { return [a, c] }\n\t\t\t\tfunction bar2() { return [a, c, bar2] }\n\t\t\t\tusing c = d\n\t\t\t`,\n\t\t\t\"/hoist-export-function-indirect.js\": `\n\t\t\t\tusing a = b\n\t\t\t\tfunction foo1() { return [a, c] }\n\t\t\t\tfunction bar1() { return [a, c, bar1] }\n\t\t\t\tfunction foo2() { return [a, c] }\n\t\t\t\tfunction bar2() { return [a, c, bar2] }\n\t\t\t\tusing c = d\n\t\t\t\texport {foo1, bar1}\n\t\t\t`,\n\t\t\t\"/hoist-export-default-class-name-unused.js\": `\n\t\t\t\tusing a = b\n\t\t\t\texport default class Foo {\n\t\t\t\t\tac = [a, c]\n\t\t\t\t}\n\t\t\t\tusing c = d\n\t\t\t`,\n\t\t\t\"/hoist-export-default-class-name-used.js\": `\n\t\t\t\tusing a = b\n\t\t\t\texport default class Foo {\n\t\t\t\t\tac = [a, c, Foo]\n\t\t\t\t}\n\t\t\t\tusing c = d\n\t\t\t`,\n\t\t\t\"/hoist-export-default-class-anonymous.js\": `\n\t\t\t\tusing a = b\n\t\t\t\texport default class {\n\t\t\t\t\tac = [a, c]\n\t\t\t\t}\n\t\t\t\tusing c = d\n\t\t\t`,\n\t\t\t\"/hoist-export-default-function-name-unused.js\": `\n\t\t\t\tusing a = b\n\t\t\t\texport default function foo() {\n\t\t\t\t\treturn [a, c]\n\t\t\t\t}\n\t\t\t\tusing c = d\n\t\t\t`,\n\t\t\t\"/hoist-export-default-function-name-used.js\": `\n\t\t\t\tusing a = b\n\t\t\t\texport default function foo() {\n\t\t\t\t\treturn [a, c, foo]\n\t\t\t\t}\n\t\t\t\tusing c = d\n\t\t\t`,\n\t\t\t\"/hoist-export-default-function-anonymous.js\": `\n\t\t\t\tusing a = b\n\t\t\t\texport default function() {\n\t\t\t\t\treturn [a, c]\n\t\t\t\t}\n\t\t\t\tusing c = d\n\t\t\t`,\n\t\t\t\"/hoist-export-default-expr.js\": `\n\t\t\t\tusing a = b\n\t\t\t\texport default [a, c]\n\t\t\t\tusing c = d\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/hoist-use-strict.js\",\n\t\t\t\"/hoist-directive.js\",\n\t\t\t\"/hoist-import.js\",\n\t\t\t\"/hoist-export-star.js\",\n\t\t\t\"/hoist-export-from.js\",\n\t\t\t\"/hoist-export-clause.js\",\n\t\t\t\"/hoist-export-local-direct.js\",\n\t\t\t\"/hoist-export-local-indirect.js\",\n\t\t\t\"/hoist-export-class-direct.js\",\n\t\t\t\"/hoist-export-class-indirect.js\",\n\t\t\t\"/hoist-export-function-direct.js\",\n\t\t\t\"/hoist-export-function-indirect.js\",\n\t\t\t\"/hoist-export-default-class-name-unused.js\",\n\t\t\t\"/hoist-export-default-class-name-used.js\",\n\t\t\t\"/hoist-export-default-class-anonymous.js\",\n\t\t\t\"/hoist-export-default-function-name-unused.js\",\n\t\t\t\"/hoist-export-default-function-name-used.js\",\n\t\t\t\"/hoist-export-default-function-anonymous.js\",\n\t\t\t\"/hoist-export-default-expr.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tUnsupportedJSFeatures: compat.Using,\n\t\t},\n\t})\n}\n\nfunc TestLowerUsingInsideTSNamespace(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tnamespace ns {\n\t\t\t\t\texport let a = b\n\t\t\t\t\tusing c = d\n\t\t\t\t\texport let e = f\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tUnsupportedJSFeatures: compat.Using,\n\t\t},\n\t})\n}\n\nfunc TestLowerAsyncGenerator(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tasync function* foo() {\n\t\t\t\t\tyield\n\t\t\t\t\tyield x\n\t\t\t\t\tyield *x\n\t\t\t\t\tawait using x = await y\n\t\t\t\t\tfor await (let x of y) {}\n\t\t\t\t\tfor await (await using x of y) {}\n\t\t\t\t}\n\t\t\t\tfoo = async function* () {\n\t\t\t\t\tyield\n\t\t\t\t\tyield x\n\t\t\t\t\tyield *x\n\t\t\t\t\tawait using x = await y\n\t\t\t\t\tfor await (let x of y) {}\n\t\t\t\t\tfor await (await using x of y) {}\n\t\t\t\t}\n\t\t\t\tfoo = { async *bar () {\n\t\t\t\t\tyield\n\t\t\t\t\tyield x\n\t\t\t\t\tyield *x\n\t\t\t\t\tawait using x = await y\n\t\t\t\t\tfor await (let x of y) {}\n\t\t\t\t\tfor await (await using x of y) {}\n\t\t\t\t} }\n\t\t\t\tclass Foo { async *bar () {\n\t\t\t\t\tyield\n\t\t\t\t\tyield x\n\t\t\t\t\tyield *x\n\t\t\t\t\tawait using x = await y\n\t\t\t\t\tfor await (let x of y) {}\n\t\t\t\t\tfor await (await using x of y) {}\n\t\t\t\t} }\n\t\t\t\tFoo = class { async *bar () {\n\t\t\t\t\tyield\n\t\t\t\t\tyield x\n\t\t\t\t\tyield *x\n\t\t\t\t\tawait using x = await y\n\t\t\t\t\tfor await (let x of y) {}\n\t\t\t\t\tfor await (await using x of y) {}\n\t\t\t\t} }\n\t\t\t\tasync function bar() {\n\t\t\t\t\tawait using x = await y\n\t\t\t\t\tfor await (let x of y) {}\n\t\t\t\t\tfor await (await using x of y) {}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tUnsupportedJSFeatures: compat.AsyncGenerator,\n\t\t},\n\t})\n}\n\nfunc TestLowerAsyncGeneratorNoAwait(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tasync function* foo() {\n\t\t\t\t\tyield\n\t\t\t\t\tyield x\n\t\t\t\t\tyield *x\n\t\t\t\t\tawait using x = await y\n\t\t\t\t\tfor await (let x of y) {}\n\t\t\t\t\tfor await (await using x of y) {}\n\t\t\t\t}\n\t\t\t\tfoo = async function* () {\n\t\t\t\t\tyield\n\t\t\t\t\tyield x\n\t\t\t\t\tyield *x\n\t\t\t\t\tawait using x = await y\n\t\t\t\t\tfor await (let x of y) {}\n\t\t\t\t\tfor await (await using x of y) {}\n\t\t\t\t}\n\t\t\t\tfoo = { async *bar () {\n\t\t\t\t\tyield\n\t\t\t\t\tyield x\n\t\t\t\t\tyield *x\n\t\t\t\t\tawait using x = await y\n\t\t\t\t\tfor await (let x of y) {}\n\t\t\t\t\tfor await (await using x of y) {}\n\t\t\t\t} }\n\t\t\t\tclass Foo { async *bar () {\n\t\t\t\t\tyield\n\t\t\t\t\tyield x\n\t\t\t\t\tyield *x\n\t\t\t\t\tawait using x = await y\n\t\t\t\t\tfor await (let x of y) {}\n\t\t\t\t\tfor await (await using x of y) {}\n\t\t\t\t} }\n\t\t\t\tFoo = class { async *bar () {\n\t\t\t\t\tyield\n\t\t\t\t\tyield x\n\t\t\t\t\tyield *x\n\t\t\t\t\tawait using x = await y\n\t\t\t\t\tfor await (let x of y) {}\n\t\t\t\t\tfor await (await using x of y) {}\n\t\t\t\t} }\n\t\t\t\tasync function bar() {\n\t\t\t\t\tawait using x = await y\n\t\t\t\t\tfor await (let x of y) {}\n\t\t\t\t\tfor await (await using x of y) {}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tUnsupportedJSFeatures: compat.AsyncGenerator | compat.AsyncAwait,\n\t\t},\n\t})\n}\n\n// https://github.com/evanw/esbuild/issues/3768\nfunc TestJavaScriptDecoratorsBundleIssue3768(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/base-instance-method.js\":   `class Foo { @dec foo() { return Foo } }`,\n\t\t\t\"/base-instance-field.js\":    `class Foo { @dec foo = Foo }`,\n\t\t\t\"/base-instance-accessor.js\": `class Foo { @dec accessor foo = Foo }`,\n\n\t\t\t\"/base-static-method.js\":   `class Foo { @dec static foo() { return Foo } }`,\n\t\t\t\"/base-static-field.js\":    `class Foo { @dec static foo = Foo }`,\n\t\t\t\"/base-static-accessor.js\": `class Foo { @dec static accessor foo = Foo }`,\n\n\t\t\t\"/derived-instance-method.js\":   `class Foo extends Bar { @dec foo() { return Foo } }`,\n\t\t\t\"/derived-instance-field.js\":    `class Foo extends Bar { @dec foo = Foo }`,\n\t\t\t\"/derived-instance-accessor.js\": `class Foo extends Bar { @dec accessor foo = Foo }`,\n\n\t\t\t\"/derived-static-method.js\":   `class Foo extends Bar { @dec static foo() { return Foo } }`,\n\t\t\t\"/derived-static-field.js\":    `class Foo extends Bar { @dec static foo = Foo }`,\n\t\t\t\"/derived-static-accessor.js\": `class Foo extends Bar { @dec static accessor foo = Foo }`,\n\t\t},\n\t\tentryPaths: []string{\"/*\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputDir:          \"/out\",\n\t\t\tUnsupportedJSFeatures: compat.Decorators,\n\t\t},\n\t})\n}\n\n// https://github.com/evanw/esbuild/issues/4378\nfunc TestForAwaitWithOptionalCatchIssue4378(t *testing.T) {\n\tlower_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tasync function test(b) {\n\t\t\t\t\tfor await (const a of b) a()\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.ForAwait,\n\t\t\tMinifySyntax:          true,\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "internal/bundler_tests/bundler_packagejson_test.go",
    "content": "package bundler_tests\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/config\"\n)\n\nvar packagejson_suite = suite{\n\tname: \"packagejson\",\n}\n\nfunc TestPackageJsonMain(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./custom-main.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/custom-main.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBadMain(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./does-not-exist.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonSyntaxErrorComment(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t// Single-line comment\n\t\t\t\t\t\"a\": 1\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/node_modules/demo-pkg/package.json: ERROR: JSON does not support comments\n`,\n\t})\n}\n\nfunc TestPackageJsonSyntaxErrorTrailingComma(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"a\": 1,\n\t\t\t\t\t\"b\": 2,\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/node_modules/demo-pkg/package.json: ERROR: JSON does not support trailing commas\n`,\n\t})\n}\n\nfunc TestPackageJsonModule(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main.js\",\n\t\t\t\t\t\"module\": \"./main.esm.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.esm.js\": `\n\t\t\t\texport default function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserString(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"browser\": \"./browser\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/browser.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserMapRelativeToRelative(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main\",\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"./main.js\": \"./main-browser\",\n\t\t\t\t\t\t\"./lib/util.js\": \"./lib/util-browser\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tconst util = require('./lib/util')\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn ['main', util]\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main-browser.js\": `\n\t\t\t\tconst util = require('./lib/util')\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn ['main-browser', util]\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/lib/util.js\": `\n\t\t\t\tmodule.exports = 'util'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/lib/util-browser.js\": `\n\t\t\t\tmodule.exports = 'util-browser'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserMapRelativeToModule(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main\",\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"./util.js\": \"util-browser\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tconst util = require('./util')\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn ['main', util]\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/util.js\": `\n\t\t\t\tmodule.exports = 'util'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/util-browser/index.js\": `\n\t\t\t\tmodule.exports = 'util-browser'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserMapRelativeDisabled(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main\",\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"./util-node.js\": false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tconst util = require('./util-node')\n\t\t\t\tmodule.exports = function(obj) {\n\t\t\t\t\treturn util.inspect(obj)\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/util-node.js\": `\n\t\t\t\tmodule.exports = require('util')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserMapModuleToRelative(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"node-pkg\": \"./node-pkg-browser\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/node-pkg-browser.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\tconst fn = require('node-pkg')\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn fn()\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/node-pkg/index.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 234\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserMapModuleToModule(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"node-pkg\": \"node-pkg-browser\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/node-pkg-browser/index.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\tconst fn = require('node-pkg')\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn fn()\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/node-pkg/index.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 234\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserMapModuleDisabled(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"node-pkg\": false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\tconst fn = require('node-pkg')\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn fn()\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/node-pkg/index.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 234\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserMapNativeModuleDisabled(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"fs\": false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\tconst fs = require('fs')\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn fs.readFile()\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserMapAvoidMissing(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'component-classes'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/component-classes/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"indexof\": \"component-indexof\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/component-classes/index.js\": `\n\t\t\t\ttry {\n\t\t\t\t\tvar index = require('indexof');\n\t\t\t\t} catch (err) {\n\t\t\t\t\tvar index = require('component-indexof');\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/component-indexof/index.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 234\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserOverModuleBrowser(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main.js\",\n\t\t\t\t\t\"module\": \"./main.esm.js\",\n\t\t\t\t\t\"browser\": \"./main.browser.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.esm.js\": `\n\t\t\t\texport default function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.browser.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tPlatform:      config.PlatformBrowser,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserOverMainNode(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main.js\",\n\t\t\t\t\t\"module\": \"./main.esm.js\",\n\t\t\t\t\t\"browser\": \"./main.browser.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.esm.js\": `\n\t\t\t\texport default function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.browser.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tPlatform:      config.PlatformNode,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserWithModuleBrowser(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main.js\",\n\t\t\t\t\t\"module\": \"./main.esm.js\",\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"./main.js\": \"./main.browser.js\",\n\t\t\t\t\t\t\"./main.esm.js\": \"./main.browser.esm.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.esm.js\": `\n\t\t\t\texport default function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.browser.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.browser.esm.js\": `\n\t\t\t\texport default function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tPlatform:      config.PlatformBrowser,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserWithMainNode(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main.js\",\n\t\t\t\t\t\"module\": \"./main.esm.js\",\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"./main.js\": \"./main.browser.js\",\n\t\t\t\t\t\t\"./main.esm.js\": \"./main.browser.esm.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.esm.js\": `\n\t\t\t\texport default function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.browser.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.browser.esm.js\": `\n\t\t\t\texport default function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tPlatform:      config.PlatformNode,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserNodeModulesNoExt(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {browser as a} from 'demo-pkg/no-ext'\n\t\t\t\timport {node as b} from 'demo-pkg/no-ext.js'\n\t\t\t\timport {browser as c} from 'demo-pkg/ext'\n\t\t\t\timport {browser as d} from 'demo-pkg/ext.js'\n\t\t\t\tconsole.log(a)\n\t\t\t\tconsole.log(b)\n\t\t\t\tconsole.log(c)\n\t\t\t\tconsole.log(d)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"./no-ext\": \"./no-ext-browser.js\",\n\t\t\t\t\t\t\"./ext.js\": \"./ext-browser.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/no-ext.js\": `\n\t\t\t\texport let node = 'node'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/no-ext-browser.js\": `\n\t\t\t\texport let browser = 'browser'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/ext.js\": `\n\t\t\t\texport let node = 'node'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/ext-browser.js\": `\n\t\t\t\texport let browser = 'browser'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserNodeModulesIndexNoExt(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {browser as a} from 'demo-pkg/no-ext'\n\t\t\t\timport {node as b} from 'demo-pkg/no-ext/index.js'\n\t\t\t\timport {browser as c} from 'demo-pkg/ext'\n\t\t\t\timport {browser as d} from 'demo-pkg/ext/index.js'\n\t\t\t\tconsole.log(a)\n\t\t\t\tconsole.log(b)\n\t\t\t\tconsole.log(c)\n\t\t\t\tconsole.log(d)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"./no-ext\": \"./no-ext-browser/index.js\",\n\t\t\t\t\t\t\"./ext/index.js\": \"./ext-browser/index.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/no-ext/index.js\": `\n\t\t\t\texport let node = 'node'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/no-ext-browser/index.js\": `\n\t\t\t\texport let browser = 'browser'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/ext/index.js\": `\n\t\t\t\texport let node = 'node'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/ext-browser/index.js\": `\n\t\t\t\texport let browser = 'browser'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserNoExt(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {browser as a} from './demo-pkg/no-ext'\n\t\t\t\timport {node as b} from './demo-pkg/no-ext.js'\n\t\t\t\timport {browser as c} from './demo-pkg/ext'\n\t\t\t\timport {browser as d} from './demo-pkg/ext.js'\n\t\t\t\tconsole.log(a)\n\t\t\t\tconsole.log(b)\n\t\t\t\tconsole.log(c)\n\t\t\t\tconsole.log(d)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"./no-ext\": \"./no-ext-browser.js\",\n\t\t\t\t\t\t\"./ext.js\": \"./ext-browser.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/demo-pkg/no-ext.js\": `\n\t\t\t\texport let node = 'node'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/demo-pkg/no-ext-browser.js\": `\n\t\t\t\texport let browser = 'browser'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/demo-pkg/ext.js\": `\n\t\t\t\texport let node = 'node'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/demo-pkg/ext-browser.js\": `\n\t\t\t\texport let browser = 'browser'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserIndexNoExt(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport {browser as a} from './demo-pkg/no-ext'\n\t\t\t\timport {node as b} from './demo-pkg/no-ext/index.js'\n\t\t\t\timport {browser as c} from './demo-pkg/ext'\n\t\t\t\timport {browser as d} from './demo-pkg/ext/index.js'\n\t\t\t\tconsole.log(a)\n\t\t\t\tconsole.log(b)\n\t\t\t\tconsole.log(c)\n\t\t\t\tconsole.log(d)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"./no-ext\": \"./no-ext-browser/index.js\",\n\t\t\t\t\t\t\"./ext/index.js\": \"./ext-browser/index.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/demo-pkg/no-ext/index.js\": `\n\t\t\t\texport let node = 'node'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/demo-pkg/no-ext-browser/index.js\": `\n\t\t\t\texport let browser = 'browser'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/demo-pkg/ext/index.js\": `\n\t\t\t\texport let node = 'node'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/demo-pkg/ext-browser/index.js\": `\n\t\t\t\texport let browser = 'browser'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\n// See https://github.com/evanw/esbuild/issues/2002\nfunc TestPackageJsonBrowserIssue2002A(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `require('pkg/sub')`,\n\t\t\t\"/Users/user/project/src/node_modules/pkg/package.json\": `{\n\t\t\t\t\"browser\": {\n\t\t\t\t\t\"./sub\": \"./sub/foo.js\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/Users/user/project/src/node_modules/pkg/sub/foo.js\":   `require('sub')`,\n\t\t\t\"/Users/user/project/src/node_modules/sub/package.json\": `{ \"main\": \"./bar\" }`,\n\t\t\t\"/Users/user/project/src/node_modules/sub/bar.js\":       `works()`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonBrowserIssue2002B(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `require('pkg/sub')`,\n\t\t\t\"/Users/user/project/src/node_modules/pkg/package.json\": `{\n\t\t\t\t\"browser\": {\n\t\t\t\t\t\"./sub\": \"./sub/foo.js\",\n\t\t\t\t\t\"./sub/sub\": \"./sub/bar.js\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/Users/user/project/src/node_modules/pkg/sub/foo.js\": `require('sub')`,\n\t\t\t\"/Users/user/project/src/node_modules/pkg/sub/bar.js\": `works()`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\n// See https://github.com/evanw/esbuild/issues/2239\nfunc TestPackageJsonBrowserIssue2002C(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `require('pkg/sub')`,\n\t\t\t\"/Users/user/project/src/node_modules/pkg/package.json\": `{\n\t\t\t\t\"browser\": {\n\t\t\t\t\t\"./sub\": \"./sub/foo.js\",\n\t\t\t\t\t\"./sub/sub.js\": \"./sub/bar.js\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/Users/user/project/src/node_modules/pkg/sub/foo.js\": `require('sub')`,\n\t\t\t\"/Users/user/project/src/node_modules/sub/index.js\":   `works()`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonDualPackageHazardImportOnly(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport value from 'demo-pkg'\n\t\t\t\tconsole.log(value)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main.js\",\n\t\t\t\t\t\"module\": \"./module.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tmodule.exports = 'main'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/module.js\": `\n\t\t\t\texport default 'module'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonDualPackageHazardRequireOnly(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\tconsole.log(require('demo-pkg'))\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main.js\",\n\t\t\t\t\t\"module\": \"./module.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tmodule.exports = 'main'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/module.js\": `\n\t\t\t\texport default 'module'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonDualPackageHazardImportAndRequireSameFile(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport value from 'demo-pkg'\n\t\t\t\tconsole.log(value, require('demo-pkg'))\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main.js\",\n\t\t\t\t\t\"module\": \"./module.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tmodule.exports = 'main'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/module.js\": `\n\t\t\t\texport default 'module'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonDualPackageHazardImportAndRequireSeparateFiles(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport './test-main'\n\t\t\t\timport './test-module'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/test-main.js\": `\n\t\t\t\tconsole.log(require('demo-pkg'))\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/test-module.js\": `\n\t\t\t\timport value from 'demo-pkg'\n\t\t\t\tconsole.log(value)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main.js\",\n\t\t\t\t\t\"module\": \"./module.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tmodule.exports = 'main'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/module.js\": `\n\t\t\t\texport default 'module'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonDualPackageHazardImportAndRequireForceModuleBeforeMain(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport './test-main'\n\t\t\t\timport './test-module'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/test-main.js\": `\n\t\t\t\tconsole.log(require('demo-pkg'))\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/test-module.js\": `\n\t\t\t\timport value from 'demo-pkg'\n\t\t\t\tconsole.log(value)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main.js\",\n\t\t\t\t\t\"module\": \"./module.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tmodule.exports = 'main'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/module.js\": `\n\t\t\t\texport default 'module'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tMainFields:    []string{\"module\", \"main\"},\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonDualPackageHazardImportAndRequireImplicitMain(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport './test-index'\n\t\t\t\timport './test-module'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/test-index.js\": `\n\t\t\t\tconsole.log(require('demo-pkg'))\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/test-module.js\": `\n\t\t\t\timport value from 'demo-pkg'\n\t\t\t\tconsole.log(value)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"module\": \"./module.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\tmodule.exports = 'index'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/module.js\": `\n\t\t\t\texport default 'module'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonDualPackageHazardImportAndRequireImplicitMainForceModuleBeforeMain(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport './test-index'\n\t\t\t\timport './test-module'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/test-index.js\": `\n\t\t\t\tconsole.log(require('demo-pkg'))\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/test-module.js\": `\n\t\t\t\timport value from 'demo-pkg'\n\t\t\t\tconsole.log(value)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"module\": \"./module.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/index.js\": `\n\t\t\t\tmodule.exports = 'index'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/module.js\": `\n\t\t\t\texport default 'module'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tMainFields:    []string{\"module\", \"main\"},\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonDualPackageHazardImportAndRequireBrowser(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport './test-main'\n\t\t\t\timport './test-module'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/test-main.js\": `\n\t\t\t\tconsole.log(require('demo-pkg'))\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/test-module.js\": `\n\t\t\t\timport value from 'demo-pkg'\n\t\t\t\tconsole.log(value)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main.js\",\n\t\t\t\t\t\"module\": \"./module.js\",\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"./main.js\": \"./main.browser.js\",\n\t\t\t\t\t\t\"./module.js\": \"./module.browser.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tmodule.exports = 'main'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/module.js\": `\n\t\t\t\texport default 'module'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.browser.js\": `\n\t\t\t\tmodule.exports = 'browser main'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/module.browser.js\": `\n\t\t\t\texport default 'browser module'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonMainFieldsA(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport value from 'demo-pkg'\n\t\t\t\tconsole.log(value)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"a\": \"./a.js\",\n\t\t\t\t\t\"b\": \"./b.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/a.js\": `\n\t\t\t\tmodule.exports = 'a'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/b.js\": `\n\t\t\t\texport default 'b'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tMainFields:    []string{\"a\", \"b\"},\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonMainFieldsB(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport value from 'demo-pkg'\n\t\t\t\tconsole.log(value)\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"a\": \"./a.js\",\n\t\t\t\t\t\"b\": \"./b.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/a.js\": `\n\t\t\t\tmodule.exports = 'a'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/b.js\": `\n\t\t\t\texport default 'b'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tMainFields:    []string{\"b\", \"a\"},\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonNeutralNoDefaultMainFields(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main.js\",\n\t\t\t\t\t\"module\": \"./main.esm.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.esm.js\": `\n\t\t\t\texport default function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tPlatform:      config.PlatformNeutral,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"demo-pkg\"\nUsers/user/project/node_modules/demo-pkg/package.json: NOTE: The \"main\" field here was ignored. Main fields must be configured explicitly when using the \"neutral\" platform.\nNOTE: You can mark the path \"demo-pkg\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonNeutralExplicitMainFields(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport fn from 'demo-pkg'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"hello\": \"./main.js\",\n\t\t\t\t\t\"module\": \"./main.esm.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/demo-pkg/main.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tPlatform:      config.PlatformNeutral,\n\t\t\tMainFields:    []string{\"hello\"},\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonExportsErrorInvalidModuleSpecifier(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg1'\n\t\t\t\timport 'pkg2'\n\t\t\t\timport 'pkg3'\n\t\t\t\timport 'pkg4'\n\t\t\t\timport 'pkg5'\n\t\t\t\timport 'pkg6'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{ \"exports\": { \".\": \"./%%\" } }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg2/package.json\": `\n\t\t\t\t{ \"exports\": { \".\": \"./%2f\" } }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg3/package.json\": `\n\t\t\t\t{ \"exports\": { \".\": \"./%2F\" } }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg4/package.json\": `\n\t\t\t\t{ \"exports\": { \".\": \"./%5c\" } }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg5/package.json\": `\n\t\t\t\t{ \"exports\": { \".\": \"./%5C\" } }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg6/package.json\": `\n\t\t\t\t{ \"exports\": { \".\": \"./%31.js\" } }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg6/1.js\": `\n\t\t\t\tconsole.log(1)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"pkg1\"\nUsers/user/project/node_modules/pkg1/package.json: NOTE: The module specifier \"./%%\" is invalid:\nNOTE: You can mark the path \"pkg1\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nUsers/user/project/src/entry.js: ERROR: Could not resolve \"pkg2\"\nUsers/user/project/node_modules/pkg2/package.json: NOTE: The module specifier \"./%2f\" is invalid:\nNOTE: You can mark the path \"pkg2\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nUsers/user/project/src/entry.js: ERROR: Could not resolve \"pkg3\"\nUsers/user/project/node_modules/pkg3/package.json: NOTE: The module specifier \"./%2F\" is invalid:\nNOTE: You can mark the path \"pkg3\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nUsers/user/project/src/entry.js: ERROR: Could not resolve \"pkg4\"\nUsers/user/project/node_modules/pkg4/package.json: NOTE: The module specifier \"./%5c\" is invalid:\nNOTE: You can mark the path \"pkg4\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nUsers/user/project/src/entry.js: ERROR: Could not resolve \"pkg5\"\nUsers/user/project/node_modules/pkg5/package.json: NOTE: The module specifier \"./%5C\" is invalid:\nNOTE: You can mark the path \"pkg5\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonExportsErrorInvalidPackageConfiguration(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg1'\n\t\t\t\timport 'pkg2/foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{ \"exports\": { \".\": false } }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg2/package.json\": `\n\t\t\t\t{ \"exports\": { \"./foo\": false } }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/node_modules/pkg1/package.json: WARNING: This value must be a string, an object, an array, or null\nUsers/user/project/node_modules/pkg2/package.json: WARNING: This value must be a string, an object, an array, or null\nUsers/user/project/src/entry.js: ERROR: Could not resolve \"pkg1\"\nUsers/user/project/node_modules/pkg1/package.json: NOTE: The package configuration has an invalid value here:\nNOTE: You can mark the path \"pkg1\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nUsers/user/project/src/entry.js: ERROR: Could not resolve \"pkg2/foo\"\nUsers/user/project/node_modules/pkg2/package.json: NOTE: The package configuration has an invalid value here:\nNOTE: You can mark the path \"pkg2/foo\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonExportsErrorInvalidPackageTarget(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg1'\n\t\t\t\timport 'pkg2'\n\t\t\t\timport 'pkg3'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{ \"exports\": { \".\": \"invalid\" } }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg2/package.json\": `\n\t\t\t\t{ \"exports\": { \".\": \"./../pkg3\" } }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg3/package.json\": `\n\t\t\t\t{ \"exports\": { \".\": \"./node_modules/pkg\" } }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"pkg1\"\nUsers/user/project/node_modules/pkg1/package.json: NOTE: The package target \"invalid\" is invalid because it doesn't start with \"./\":\nNOTE: You can mark the path \"pkg1\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nUsers/user/project/src/entry.js: ERROR: Could not resolve \"pkg2\"\nUsers/user/project/node_modules/pkg2/package.json: NOTE: The package target \"./../pkg3\" is invalid because it contains invalid segment \"..\":\nNOTE: You can mark the path \"pkg2\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nUsers/user/project/src/entry.js: ERROR: Could not resolve \"pkg3\"\nUsers/user/project/node_modules/pkg3/package.json: NOTE: The package target \"./node_modules/pkg\" is invalid because it contains invalid segment \"node_modules\":\nNOTE: You can mark the path \"pkg3\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonExportsErrorPackagePathNotExported(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg1/foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{ \"exports\": { \".\": {} } }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"pkg1/foo\"\nUsers/user/project/node_modules/pkg1/package.json: NOTE: The path \"./foo\" is not exported by package \"pkg1\":\nNOTE: You can mark the path \"pkg1/foo\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonExportsErrorModuleNotFound(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg1'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{ \"exports\": { \".\": \"./foo.js\" } }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"pkg1\"\nUsers/user/project/node_modules/pkg1/package.json: NOTE: The module \"./foo.js\" was not found on the file system:\nNOTE: You can mark the path \"pkg1\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonExportsErrorUnsupportedDirectoryImport(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg1'\n\t\t\t\timport 'pkg2'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{ \"exports\": { \".\": \"./foo/\" } }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg2/package.json\": `\n\t\t\t\t{ \"exports\": { \".\": \"./foo\" } }\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg2/foo/bar.js\": `\n\t\t\t\tconsole.log(bar)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"pkg1\"\nUsers/user/project/node_modules/pkg1/package.json: NOTE: The module \"./foo\" was not found on the file system:\nNOTE: You can mark the path \"pkg1\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nUsers/user/project/src/entry.js: ERROR: Could not resolve \"pkg2\"\nUsers/user/project/node_modules/pkg2/package.json: NOTE: Importing the directory \"./foo\" is forbidden by this package:\nUsers/user/project/node_modules/pkg2/package.json: NOTE: The presence of \"exports\" here makes importing a directory forbidden:\nNOTE: You can mark the path \"pkg2\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonImportsErrorUnsupportedDirectoryImport(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport '#foo1/bar'\n\t\t\t\timport '#foo2/bar'\n\t\t\t`,\n\t\t\t\"/Users/user/project/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"imports\": {\n\t\t\t\t\t\t\"#foo1/*\": \"./foo1/*\",\n\t\t\t\t\t\t\"#foo2/bar\": \"./foo2/bar\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/foo1/bar/index.js\": `\n\t\t\t\tconsole.log(bar)\n\t\t\t`,\n\t\t\t\"/Users/user/project/foo2/bar/index.js\": `\n\t\t\t\tconsole.log(bar)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"#foo1/bar\"\nUsers/user/project/package.json: NOTE: Importing the directory \"./foo1/bar\" is forbidden by this package:\nUsers/user/project/package.json: NOTE: The presence of \"imports\" here makes importing a directory forbidden:\nUsers/user/project/src/entry.js: NOTE: Import from \"/index.js\" to get the file \"Users/user/project/foo1/bar/index.js\":\nNOTE: You can mark the path \"#foo1/bar\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nUsers/user/project/src/entry.js: ERROR: Could not resolve \"#foo2/bar\"\nUsers/user/project/package.json: NOTE: Importing the directory \"./foo2/bar\" is forbidden by this package:\nUsers/user/project/package.json: NOTE: The presence of \"imports\" here makes importing a directory forbidden:\nNOTE: You can mark the path \"#foo2/bar\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonExportsRequireOverImport(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\trequire('pkg')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"import\": \"./import.js\",\n\t\t\t\t\t\t\"require\": \"./require.js\",\n\t\t\t\t\t\t\"default\": \"./default.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/import.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/require.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonExportsImportOverRequire(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"require\": \"./require.js\",\n\t\t\t\t\t\t\"import\": \"./import.js\",\n\t\t\t\t\t\t\"default\": \"./default.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/require.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/import.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonExportsDefaultOverImportAndRequire(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"default\": \"./default.js\",\n\t\t\t\t\t\t\"import\": \"./import.js\",\n\t\t\t\t\t\t\"require\": \"./require.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/require.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/import.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/default.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonExportsEntryPointImportOverRequire(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/node_modules/pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"import\": \"./import.js\",\n\t\t\t\t\t\t\"require\": \"./require.js\"\n\t\t\t\t\t},\n\t\t\t\t\t\"module\": \"./module.js\",\n\t\t\t\t\t\"main\": \"./main.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/import.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/require.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/module.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/main.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"pkg\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonExportsEntryPointRequireOnly(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/node_modules/pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"require\": \"./require.js\"\n\t\t\t\t\t},\n\t\t\t\t\t\"module\": \"./module.js\",\n\t\t\t\t\t\"main\": \"./main.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/require.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/module.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/main.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"pkg\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `ERROR: Could not resolve \"pkg\"\nnode_modules/pkg/package.json: NOTE: The path \".\" is not currently exported by package \"pkg\":\nnode_modules/pkg/package.json: NOTE: None of the conditions in the package definition (\"require\") match any of the currently active conditions (\"browser\", \"default\", \"import\"):\n`,\n\t})\n}\n\nfunc TestPackageJsonExportsEntryPointModuleOverMain(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/node_modules/pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"module\": \"./module.js\",\n\t\t\t\t\t\"main\": \"./main.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/module.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/main.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"pkg\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonExportsEntryPointMainOnly(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/node_modules/pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./main.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/main.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"pkg\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonExportsBrowser(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"node\": \"./node.js\",\n\t\t\t\t\t\t\"browser\": \"./browser.js\",\n\t\t\t\t\t\t\"default\": \"./default.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/node.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/browser.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tPlatform:      config.PlatformBrowser,\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonExportsNode(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"browser\": \"./browser.js\",\n\t\t\t\t\t\t\"node\": \"./node.js\",\n\t\t\t\t\t\t\"default\": \"./default.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/browser.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/node.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonExportsNeutral(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"node\": \"./node.js\",\n\t\t\t\t\t\t\"browser\": \"./browser.js\",\n\t\t\t\t\t\t\"default\": \"./default.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/node.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/browser.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/default.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tPlatform:      config.PlatformNeutral,\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonExportsOrderIndependent(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg1/foo/bar.js'\n\t\t\t\timport 'pkg2/foo/bar.js'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"./\": \"./1/\",\n\t\t\t\t\t\t\"./foo/\": \"./2/\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/1/foo/bar.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/2/bar.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg2/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"./foo/\": \"./1/\",\n\t\t\t\t\t\t\"./\": \"./2/\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg2/1/bar.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg2/2/foo/bar.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonExportsWildcard(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg1/foo'\n\t\t\t\timport 'pkg1/foo2'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"./foo*\": \"./file*.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/file.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/file2.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonExportsErrorMissingTrailingSlash(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg1/foo/bar'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{ \"exports\": { \"./foo/\": \"./test\" } }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"pkg1/foo/bar\"\nUsers/user/project/node_modules/pkg1/package.json: NOTE: The module specifier \"./test\" is invalid because it doesn't end in \"/\":\nNOTE: You can mark the path \"pkg1/foo/bar\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonExportsCustomConditions(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg1'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"custom1\": \"./custom1.js\",\n\t\t\t\t\t\t\"custom2\": \"./custom2.js\",\n\t\t\t\t\t\t\"default\": \"./default.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/custom2.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tConditions:    []string{\"custom2\"},\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonExportsNotExactMissingExtension(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg1/foo/bar'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"./foo/\": \"./dir/\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/dir/bar.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonExportsNotExactMissingExtensionPattern(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg1/foo/bar'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"./foo/*\": \"./dir/*\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/dir/bar.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"pkg1/foo/bar\"\nUsers/user/project/node_modules/pkg1/package.json: NOTE: The module \"./dir/bar\" was not found on the file system:\nUsers/user/project/src/entry.js: NOTE: Import from \"pkg1/foo/bar.js\" to get the file \"Users/user/project/node_modules/pkg1/dir/bar.js\":\nNOTE: You can mark the path \"pkg1/foo/bar\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonExportsExactMissingExtension(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg1/foo/bar'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"./foo/bar\": \"./dir/bar\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/dir/bar.js\": `\n\t\t\t\tconsole.log('SUCCESS')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"pkg1/foo/bar\"\nUsers/user/project/node_modules/pkg1/package.json: NOTE: The module \"./dir/bar\" was not found on the file system:\nNOTE: You can mark the path \"pkg1/foo/bar\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonExportsNoConditionsMatch(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg1'\n\t\t\t\timport 'pkg1/foo.js'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\".\": {\n\t\t\t\t\t\t\t\"what\": \"./foo.js\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"./foo.js\": {\n\t\t\t\t\t\t\t\"what\": \"./foo.js\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/foo.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"pkg1\"\nUsers/user/project/node_modules/pkg1/package.json: NOTE: The path \".\" is not currently exported by package \"pkg1\":\nUsers/user/project/node_modules/pkg1/package.json: NOTE: None of the conditions in the package definition (\"what\") match any of the currently active conditions (\"browser\", \"default\", \"import\"):\nUsers/user/project/node_modules/pkg1/package.json: NOTE: Consider enabling the \"what\" condition if this package expects it to be enabled. You can use 'Conditions: []string{\"what\"}' to do that:\nNOTE: You can mark the path \"pkg1\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nUsers/user/project/src/entry.js: ERROR: Could not resolve \"pkg1/foo.js\"\nUsers/user/project/node_modules/pkg1/package.json: NOTE: The path \"./foo.js\" is not currently exported by package \"pkg1\":\nUsers/user/project/node_modules/pkg1/package.json: NOTE: None of the conditions in the package definition (\"what\") match any of the currently active conditions (\"browser\", \"default\", \"import\"):\nUsers/user/project/node_modules/pkg1/package.json: NOTE: Consider enabling the \"what\" condition if this package expects it to be enabled. You can use 'Conditions: []string{\"what\"}' to do that:\nNOTE: You can mark the path \"pkg1/foo.js\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonExportsMustUseRequire(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg1'\n\t\t\t\timport 'pkg1/foo.js'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\".\": {\n\t\t\t\t\t\t\t\"require\": \"./foo.js\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"./foo.js\": {\n\t\t\t\t\t\t\t\"require\": \"./foo.js\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/foo.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"pkg1\"\nUsers/user/project/node_modules/pkg1/package.json: NOTE: The path \".\" is not currently exported by package \"pkg1\":\nUsers/user/project/node_modules/pkg1/package.json: NOTE: None of the conditions in the package definition (\"require\") match any of the currently active conditions (\"browser\", \"default\", \"import\"):\nUsers/user/project/src/entry.js: NOTE: Consider using a \"require()\" call to import this file, which will work because the \"require\" condition is supported by this package:\nNOTE: You can mark the path \"pkg1\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nUsers/user/project/src/entry.js: ERROR: Could not resolve \"pkg1/foo.js\"\nUsers/user/project/node_modules/pkg1/package.json: NOTE: The path \"./foo.js\" is not currently exported by package \"pkg1\":\nUsers/user/project/node_modules/pkg1/package.json: NOTE: None of the conditions in the package definition (\"require\") match any of the currently active conditions (\"browser\", \"default\", \"import\"):\nUsers/user/project/src/entry.js: NOTE: Consider using a \"require()\" call to import this file, which will work because the \"require\" condition is supported by this package:\nNOTE: You can mark the path \"pkg1/foo.js\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonExportsMustUseImport(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\trequire('pkg1')\n\t\t\t\trequire('pkg1/foo.js')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\".\": {\n\t\t\t\t\t\t\t\"import\": \"./foo.js\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"./foo.js\": {\n\t\t\t\t\t\t\t\"import\": \"./foo.js\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg1/foo.js\": `\n\t\t\t\tconsole.log('FAILURE')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"pkg1\"\nUsers/user/project/node_modules/pkg1/package.json: NOTE: The path \".\" is not currently exported by package \"pkg1\":\nUsers/user/project/node_modules/pkg1/package.json: NOTE: None of the conditions in the package definition (\"import\") match any of the currently active conditions (\"browser\", \"default\", \"require\"):\nUsers/user/project/src/entry.js: NOTE: Consider using an \"import\" statement to import this file, which will work because the \"import\" condition is supported by this package:\nNOTE: You can mark the path \"pkg1\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. You can also surround this \"require\" call with a try/catch block to handle this failure at run-time instead of bundle-time.\nUsers/user/project/src/entry.js: ERROR: Could not resolve \"pkg1/foo.js\"\nUsers/user/project/node_modules/pkg1/package.json: NOTE: The path \"./foo.js\" is not currently exported by package \"pkg1\":\nUsers/user/project/node_modules/pkg1/package.json: NOTE: None of the conditions in the package definition (\"import\") match any of the currently active conditions (\"browser\", \"default\", \"require\"):\nUsers/user/project/src/entry.js: NOTE: Consider using an \"import\" statement to import this file, which will work because the \"import\" condition is supported by this package:\nNOTE: You can mark the path \"pkg1/foo.js\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. You can also surround this \"require\" call with a try/catch block to handle this failure at run-time instead of bundle-time.\n`,\n\t})\n}\n\nfunc TestPackageJsonExportsReverseLookup(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\trequire('pkg/path/to/real/file')\n\t\t\t\trequire('pkg/path/to/other/file')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"./lib/te*\": {\n\t\t\t\t\t\t\t\"default\": \"./path/to/re*.js\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"./extra/\": {\n\t\t\t\t\t\t\t\"default\": \"./path/to/\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/path/to/real/file.js\":  ``,\n\t\t\t\"/Users/user/project/node_modules/pkg/path/to/other/file.js\": ``,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"pkg/path/to/real/file\"\nUsers/user/project/node_modules/pkg/package.json: NOTE: The path \"./path/to/real/file\" is not exported by package \"pkg\":\nUsers/user/project/node_modules/pkg/package.json: NOTE: The file \"./path/to/real/file.js\" is exported at path \"./lib/teal/file\":\nUsers/user/project/src/entry.js: NOTE: Import from \"pkg/lib/teal/file\" to get the file \"Users/user/project/node_modules/pkg/path/to/real/file.js\":\nNOTE: You can mark the path \"pkg/path/to/real/file\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. You can also surround this \"require\" call with a try/catch block to handle this failure at run-time instead of bundle-time.\nUsers/user/project/src/entry.js: ERROR: Could not resolve \"pkg/path/to/other/file\"\nUsers/user/project/node_modules/pkg/package.json: NOTE: The path \"./path/to/other/file\" is not exported by package \"pkg\":\nUsers/user/project/node_modules/pkg/package.json: NOTE: The file \"./path/to/other/file.js\" is exported at path \"./extra/other/file.js\":\nUsers/user/project/src/entry.js: NOTE: Import from \"pkg/extra/other/file.js\" to get the file \"Users/user/project/node_modules/pkg/path/to/other/file.js\":\nNOTE: You can mark the path \"pkg/path/to/other/file\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. You can also surround this \"require\" call with a try/catch block to handle this failure at run-time instead of bundle-time.\n`,\n\t})\n}\n\nfunc TestPackageJsonExportsPatternTrailers(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'pkg/path/foo.js/bar.js'\n\t\t\t\timport 'pkg2/features/abc'\n\t\t\t\timport 'pkg2/features/xyz.js'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"./path/*/bar.js\": \"./dir/baz-*\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/dir/baz-foo.js\": `\n\t\t\t\tconsole.log('works')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg2/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"./features/*\": \"./public/*.js\",\n\t\t\t\t\t\t\"./features/*.js\": \"./public/*.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg2/public/abc.js\": `\n\t\t\t\tconsole.log('abc')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg2/public/xyz.js\": `\n\t\t\t\tconsole.log('xyz')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\n// Node's package.json format for \"exports\" allows for arrays to be used as map\n// values, like in the example below. Webpack's implementation interprets this\n// as a way to specify several alternative directories to search for packages.\n// See: https://webpack.js.org/guides/package-exports/#alternatives. However,\n// this doesn't follow Node's specification for how \"exports\" should work:\n// https://nodejs.org/api/esm.html#resolver-algorithm. Also no one else\n// implements it this way (e.g. both Node and Rollup don't do this).\n//\n// This test case can only be built by Webpack. Implementations that follow the\n// specification (including esbuild) will fail to build this test case. This\n// test case only exists to document that esbuild doesn't follow Webpack's\n// behavior here.\nfunc TestPackageJsonExportsAlternatives(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport redApple from 'pkg/apples/red.js'\n\t\t\t\timport greenApple from 'pkg/apples/green.js'\n\t\t\t\timport redBook from 'pkg/books/red'\n\t\t\t\timport greenBook from 'pkg/books/green'\n\t\t\t\tconsole.log({redApple, greenApple, redBook, greenBook})\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"./apples/\": [\"./good-apples/\", \"./bad-apples/\"],\n\t\t\t\t\t\t\"./books/*\": [\"./good-books/*-book.js\", \"./bad-books/*-book.js\"]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/good-apples/green.js\": `\n\t\t\t\texport default '🍏'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/bad-apples/red.js\": `\n\t\t\t\texport default '🍎'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/good-books/green-book.js\": `\n\t\t\t\texport default '📗'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/bad-books/red-book.js\": `\n\t\t\t\texport default '📕'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"pkg/apples/red.js\"\nUsers/user/project/node_modules/pkg/package.json: NOTE: The module \"./good-apples/red.js\" was not found on the file system:\nNOTE: You can mark the path \"pkg/apples/red.js\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nUsers/user/project/src/entry.js: ERROR: Could not resolve \"pkg/books/red\"\nUsers/user/project/node_modules/pkg/package.json: NOTE: The module \"./good-books/red-book.js\" was not found on the file system:\nNOTE: You can mark the path \"pkg/books/red\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonImports(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/foo/entry.js\": `\n\t\t\t\timport '#top-level'\n\t\t\t\timport '#nested/path.js'\n\t\t\t\timport '#star/c.js'\n\t\t\t\timport '#slash/d.js'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"imports\": {\n\t\t\t\t\t\t\"#top-level\": \"./a.js\",\n\t\t\t\t\t\t\"#nested/path.js\": \"./b.js\",\n\t\t\t\t\t\t\"#star/*\": \"./some-star/*\",\n\t\t\t\t\t\t\"#slash/\": \"./some-slash/\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/a.js\":            `console.log('a.js')`,\n\t\t\t\"/Users/user/project/src/b.js\":            `console.log('b.js')`,\n\t\t\t\"/Users/user/project/src/some-star/c.js\":  `console.log('c.js')`,\n\t\t\t\"/Users/user/project/src/some-slash/d.js\": `console.log('d.js')`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/foo/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonImportsRemapToOtherPackage(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport '#top-level'\n\t\t\t\timport '#nested/path.js'\n\t\t\t\timport '#star/c.js'\n\t\t\t\timport '#slash/d.js'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"imports\": {\n\t\t\t\t\t\t\"#top-level\": \"pkg/a.js\",\n\t\t\t\t\t\t\"#nested/path.js\": \"pkg/b.js\",\n\t\t\t\t\t\t\"#star/*\": \"pkg/some-star/*\",\n\t\t\t\t\t\t\"#slash/\": \"pkg/some-slash/\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/node_modules/pkg/a.js\":            `console.log('a.js')`,\n\t\t\t\"/Users/user/project/src/node_modules/pkg/b.js\":            `console.log('b.js')`,\n\t\t\t\"/Users/user/project/src/node_modules/pkg/some-star/c.js\":  `console.log('c.js')`,\n\t\t\t\"/Users/user/project/src/node_modules/pkg/some-slash/d.js\": `console.log('d.js')`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonImportsErrorMissingRemappedPackage(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport '#foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"imports\": {\n\t\t\t\t\t\t\"#foo\": \"bar\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"#foo\"\nUsers/user/project/src/package.json: NOTE: The remapped path \"bar\" could not be resolved:\nNOTE: You can mark the path \"#foo\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonImportsInvalidPackageConfiguration(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport '#foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"imports\": \"#foo\"\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"#foo\"\nUsers/user/project/src/package.json: NOTE: The package configuration has an invalid value here:\nNOTE: You can mark the path \"#foo\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\nUsers/user/project/src/package.json: WARNING: The value for \"imports\" must be an object\n`,\n\t})\n}\n\nfunc TestPackageJsonImportsErrorEqualsHash(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport '#'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"imports\": {}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"#\"\nUsers/user/project/src/package.json: NOTE: This \"imports\" map was ignored because the module specifier \"#\" is invalid:\nNOTE: You can mark the path \"#\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\n// Tests for new Node.js behavior: https://github.com/nodejs/node/pull/60864\n// The #/ prefix is now allowed in subpath imports when there's a matching pattern\n\nfunc TestPackageJsonImportsHashSlashWithWildcard(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport '#/foo.js'\n\t\t\t\timport '#/bar/baz.js'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"imports\": {\n\t\t\t\t\t\t\"#/*\": \"./src/*\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/src/foo.js\":     `console.log('foo.js')`,\n\t\t\t\"/Users/user/project/src/src/bar/baz.js\": `console.log('bar/baz.js')`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonImportsHashSlashExactMatch(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport '#/'\n\t\t\t\timport '#/utils'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"imports\": {\n\t\t\t\t\t\t\"#/\": \"./index.js\",\n\t\t\t\t\t\t\"#/utils\": \"./utils.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/index.js\": `console.log('index.js')`,\n\t\t\t\"/Users/user/project/src/utils.js\": `console.log('utils.js')`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonImportsHashSlashWithConditions(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport '#/lib'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"imports\": {\n\t\t\t\t\t\t\"#/*\": {\n\t\t\t\t\t\t\t\"import\": \"./esm/*.js\",\n\t\t\t\t\t\t\t\"require\": \"./cjs/*.js\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/esm/lib.js\": `console.log('esm/lib.js')`,\n\t\t\t\"/Users/user/project/src/cjs/lib.js\": `console.log('cjs/lib.js')`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonImportsHashSlashSymmetricWithExports(t *testing.T) {\n\t// Common pattern: symmetric imports/exports for root-relative imports\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport '#/components/button.js'\n\t\t\t\timport '#/utils/format.js'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": { \"./*\": \"./src/*\" },\n\t\t\t\t\t\"imports\": { \"#/*\": \"./src/*\" }\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/src/components/button.js\": `console.log('button.js')`,\n\t\t\t\"/Users/user/project/src/src/utils/format.js\":      `console.log('format.js')`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonMainFieldsErrorMessageDefault(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/foo/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./foo\"\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"foo\"\nNOTE: You can mark the path \"foo\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonMainFieldsErrorMessageNotIncluded(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/foo/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./foo\"\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tMainFields:    []string{\"some\", \"fields\"},\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"foo\"\nUsers/user/project/node_modules/foo/package.json: NOTE: The \"main\" field here was ignored because the list of main fields to use is currently set to [\"some\", \"fields\"].\nNOTE: You can mark the path \"foo\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonMainFieldsErrorMessageEmpty(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/foo/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./foo\"\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tMainFields:    []string{},\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.js: ERROR: Could not resolve \"foo\"\nUsers/user/project/node_modules/foo/package.json: NOTE: The \"main\" field here was ignored because the list of main fields to use is currently set to [].\nNOTE: You can mark the path \"foo\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestPackageJsonTypeShouldBeTypes(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/index.js\": ``,\n\t\t\t\"/Users/user/project/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./src/index.js\",\n\t\t\t\t\t\"type\": \"./src/index.d.ts\"\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/index.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tMainFields:    []string{},\n\t\t},\n\t\texpectedScanLog: `Users/user/project/package.json: WARNING: \"./src/index.d.ts\" is not a valid value for the \"type\" field\nUsers/user/project/package.json: NOTE: TypeScript type declarations use the \"types\" field, not the \"type\" field:\n`,\n\t})\n}\n\nfunc TestPackageJsonImportSelfUsingRequire(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/index.js\": `\n\t\t\t\tmodule.exports = 'index'\n\t\t\t\tconsole.log(\n\t\t\t\t\trequire(\"xyz\"),\n\t\t\t\t\trequire(\"xyz/bar\"),\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/foo-import.js\": `\n\t\t\t\texport default 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/foo-require.js\": `\n\t\t\t\tmodule.exports = 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"xyz\",\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\".\": \"./src/index.js\",\n\t\t\t\t\t\t\"./bar\": {\n\t\t\t\t\t\t\t\"import\": \"./src/foo-import.js\",\n\t\t\t\t\t\t\t\"require\": \"./src/foo-require.js\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/index.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tMainFields:    []string{},\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonImportSelfUsingImport(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/index.js\": `\n\t\t\t\timport xyz from \"xyz\"\n\t\t\t\timport foo from \"xyz/bar\"\n\t\t\t\texport default 'index'\n\t\t\t\tconsole.log(xyz, foo)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/foo-import.js\": `\n\t\t\t\texport default 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/foo-require.js\": `\n\t\t\t\tmodule.exports = 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"xyz\",\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\".\": \"./src/index.js\",\n\t\t\t\t\t\t\"./bar\": {\n\t\t\t\t\t\t\t\"import\": \"./src/foo-import.js\",\n\t\t\t\t\t\t\t\"require\": \"./src/foo-require.js\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/index.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tMainFields:    []string{},\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonImportSelfUsingRequireScoped(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/index.js\": `\n\t\t\t\tmodule.exports = 'index'\n\t\t\t\tconsole.log(\n\t\t\t\t\trequire(\"@some-scope/xyz\"),\n\t\t\t\t\trequire(\"@some-scope/xyz/bar\"),\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/foo-import.js\": `\n\t\t\t\texport default 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/foo-require.js\": `\n\t\t\t\tmodule.exports = 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"@some-scope/xyz\",\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\".\": \"./src/index.js\",\n\t\t\t\t\t\t\"./bar\": {\n\t\t\t\t\t\t\t\"import\": \"./src/foo-import.js\",\n\t\t\t\t\t\t\t\"require\": \"./src/foo-require.js\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/index.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tMainFields:    []string{},\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonImportSelfUsingImportScoped(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/index.js\": `\n\t\t\t\timport xyz from \"@some-scope/xyz\"\n\t\t\t\timport foo from \"@some-scope/xyz/bar\"\n\t\t\t\texport default 'index'\n\t\t\t\tconsole.log(xyz, foo)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/foo-import.js\": `\n\t\t\t\texport default 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/foo-require.js\": `\n\t\t\t\tmodule.exports = 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"@some-scope/xyz\",\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\".\": \"./src/index.js\",\n\t\t\t\t\t\t\"./bar\": {\n\t\t\t\t\t\t\t\"import\": \"./src/foo-import.js\",\n\t\t\t\t\t\t\t\"require\": \"./src/foo-require.js\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/index.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tMainFields:    []string{},\n\t\t},\n\t})\n}\n\nfunc TestPackageJsonImportSelfUsingRequireFailure(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/index.js\": `\n\t\t\t\trequire(\"xyz/src/foo.js\")\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/foo.js\": `\n\t\t\t\tmodule.exports = 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"xyz\",\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\".\": \"./src/index.js\",\n\t\t\t\t\t\t\"./bar\": \"./src/foo.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/index.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tMainFields:    []string{},\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/index.js: ERROR: Could not resolve \"xyz/src/foo.js\"\nUsers/user/project/package.json: NOTE: The path \"./src/foo.js\" is not exported by package \"xyz\":\nUsers/user/project/package.json: NOTE: The file \"./src/foo.js\" is exported at path \"./bar\":\nUsers/user/project/src/index.js: NOTE: Import from \"xyz/bar\" to get the file \"Users/user/project/src/foo.js\":\nNOTE: You can mark the path \"xyz/src/foo.js\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle. You can also surround this \"require\" call with a try/catch block to handle this failure at run-time instead of bundle-time.\n`,\n\t})\n}\n\nfunc TestPackageJsonImportSelfUsingImportFailure(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/index.js\": `\n\t\t\t\timport \"xyz/src/foo.js\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/foo.js\": `\n\t\t\t\texport default 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"name\": \"xyz\",\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\".\": \"./src/index.js\",\n\t\t\t\t\t\t\"./bar\": \"./src/foo.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/index.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tMainFields:    []string{},\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/index.js: ERROR: Could not resolve \"xyz/src/foo.js\"\nUsers/user/project/package.json: NOTE: The path \"./src/foo.js\" is not exported by package \"xyz\":\nUsers/user/project/package.json: NOTE: The file \"./src/foo.js\" is exported at path \"./bar\":\nUsers/user/project/src/index.js: NOTE: Import from \"xyz/bar\" to get the file \"Users/user/project/src/foo.js\":\nNOTE: You can mark the path \"xyz/src/foo.js\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestCommonJSVariableInESMTypeModule(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\":     `module.exports = null`,\n\t\t\t\"/package.json\": `{ \"type\": \"module\" }`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.js: WARNING: The CommonJS \"module\" variable is treated as a global variable in an ECMAScript module and may not work as expected\npackage.json: NOTE: This file is considered to be an ECMAScript module because the enclosing \"package.json\" file sets the type of this file to \"module\":\nNOTE: Node's package format requires that CommonJS files in a \"type\": \"module\" package use the \".cjs\" file extension.\n`,\n\t})\n}\n\nfunc TestPackageJsonNodePathsIssue2752(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/entry.js\": `\n\t\t\t\timport \"pkg1\"\n\t\t\t\timport \"pkg2\"\n\t\t\t\timport \"@scope/pkg3/baz\"\n\t\t\t\timport \"@scope/pkg4\"\n\t\t\t`,\n\t\t\t\"/usr/lib/pkg/pkg1/package.json\":          `{ \"main\": \"./foo.js\" }`,\n\t\t\t\"/usr/lib/pkg/pkg1/foo.js\":                `console.log('pkg1')`,\n\t\t\t\"/lib/pkg/pkg2/package.json\":              `{ \"exports\": { \".\": \"./bar.js\" } }`,\n\t\t\t\"/lib/pkg/pkg2/bar.js\":                    `console.log('pkg2')`,\n\t\t\t\"/var/lib/pkg/@scope/pkg3/package.json\":   `{ \"browser\": { \"./baz.js\": \"./baz-browser.js\" } }`,\n\t\t\t\"/var/lib/pkg/@scope/pkg3/baz-browser.js\": `console.log('pkg3')`,\n\t\t\t\"/tmp/pkg/@scope/pkg4/package.json\":       `{ \"exports\": { \".\": { \"import\": \"./bat.js\" } } }`,\n\t\t\t\"/tmp/pkg/@scope/pkg4/bat.js\":             `console.log('pkg4')`,\n\t\t},\n\t\tentryPaths: []string{\"/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tAbsNodePaths: []string{\n\t\t\t\t\"/usr/lib/pkg\",\n\t\t\t\t\"/lib/pkg\",\n\t\t\t\t\"/var/lib/pkg\",\n\t\t\t\t\"/tmp/pkg\",\n\t\t\t},\n\t\t},\n\t})\n}\n\n// See: https://github.com/evanw/esbuild/issues/3377\nfunc TestPackageJsonReversePackageExportsIssue3377(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/lib/msw-config.ts\": `\n\t\t\t\timport { setupWorker, type SetupWorker } from 'msw/browser'\n\t\t\t\tsetupWorker();\n\t\t\t`,\n\t\t\t\"/node_modules/msw/package.json\": `{\n\t\t\t\t\"exports\": {\n\t\t\t\t\t\"./browser\": {\n\t\t\t\t\t\t\"node\": null,\n\t\t\t\t\t\t\"require\": \"./lib/browser/index.js\",\n\t\t\t\t\t\t\"import\": \"./lib/browser/index.mjs\",\n\t\t\t\t\t\t\"default\": \"./lib/browser/index.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/node_modules/msw/browser/package.json\": `{\n\t\t\t\t\"main\": \"../lib/browser/index.js\",\n\t\t\t\t\"module\": \"../lib/browser/index.mjs\"\n\t\t\t}`,\n\t\t\t\"/node_modules/msw/lib/browser/index.js\":  `TEST FAILURE`,\n\t\t\t\"/node_modules/msw/lib/browser/index.mjs\": `TEST FAILURE`,\n\t\t},\n\t\tentryPaths: []string{\"/lib/msw-config.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tPlatform:      config.PlatformNode,\n\t\t},\n\t\texpectedScanLog: `lib/msw-config.ts: ERROR: Could not resolve \"msw/browser\"\nnode_modules/msw/package.json: NOTE: The path \"./browser\" cannot be imported from package \"msw\" because it was explicitly disabled by the package author here:\nNOTE: You can mark the path \"msw/browser\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\n// See: https://github.com/evanw/esbuild/issues/3367\nfunc TestPackageJsonDisabledTypeModuleIssue3367(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport foo from 'foo'\n\t\t\t\tfoo()\n\t\t\t`,\n\t\t\t\"/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"foo\": false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/node_modules/foo/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"type\": \"module\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/node_modules/foo/index.js\": `\n\t\t\t\texport default function() {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// See: https://github.com/evanw/esbuild/issues/3485\nfunc TestPackageJsonSubpathImportNodeBuiltinIssue3485(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport fs from '#fs'\n\t\t\t\timport http from '#http'\n\t\t\t\tfs.readFileSync()\n\t\t\t\thttp.createServer()\n\t\t\t`,\n\t\t\t\"/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"imports\": {\n\t\t\t\t\t\t\"#fs\": {\n\t\t\t\t\t\t\t\"node\": \"fs\",\n\t\t\t\t\t\t\t\"default\": \"./empty.js\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"#http\": {\n\t\t\t\t\t\t\t\"node\": \"node:http\",\n\t\t\t\t\t\t\t\"default\": \"./empty.js\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/empty.js\": ``,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tPlatform:      config.PlatformNode,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// See: https://github.com/evanw/esbuild/issues/3867\nfunc TestPackageJsonBadExportsImportAndRequireWarningIssue3867(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"foo\"\n\t\t\t`,\n\t\t\t\"/node_modules/foo/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\".\": {\n\t\t\t\t\t\t\t\"import\": \"./dist/node/index.js\",\n\t\t\t\t\t\t\t\"require\": \"./dist/node/index.cjs\",\n\t\t\t\t\t\t\t\"node\": {\n\t\t\t\t\t\t\t\t\"import\": \"./dist/node/index.js\",\n\t\t\t\t\t\t\t\t\"require\": \"./dist/node/index.cjs\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\t\t\"import\": \"./dist/browser/index.js\",\n\t\t\t\t\t\t\t\t\"require\": \"./dist/browser/index.cjs\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"worker\": {\n\t\t\t\t\t\t\t\t\"import\": \"./dist/browser/index.js\",\n\t\t\t\t\t\t\t\t\"require\": \"./dist/browser/index.cjs\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/node_modules/foo/dist/node/index.js\":     ``,\n\t\t\t\"/node_modules/foo/dist/node/index.cjs\":    ``,\n\t\t\t\"/node_modules/foo/dist/browser/index.js\":  ``,\n\t\t\t\"/node_modules/foo/dist/browser/index.cjs\": ``,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tPlatform:      config.PlatformNode,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\tdebugLogs: true,\n\t\texpectedScanLog: `node_modules/foo/package.json: DEBUG: The conditions \"node\" and \"browser\" and \"worker\" here will never be used as they come after both \"import\" and \"require\"\nnode_modules/foo/package.json: NOTE: The \"import\" condition comes earlier and will be used for all \"import\" statements:\nnode_modules/foo/package.json: NOTE: The \"require\" condition comes earlier and will be used for all \"require\" calls:\n`,\n\t})\n}\n\n// See: https://github.com/evanw/esbuild/issues/3867\nfunc TestPackageJsonBadExportsDefaultWarningIssue3867(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"foo\"\n\t\t\t`,\n\t\t\t\"/node_modules/foo/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\".\": {\n\t\t\t\t\t\t\t\"default\": \"./dist/node/index.js\",\n\t\t\t\t\t\t\t\"node\": {\n\t\t\t\t\t\t\t\t\"import\": \"./dist/node/index.js\",\n\t\t\t\t\t\t\t\t\"require\": \"./dist/node/index.cjs\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\t\t\"import\": \"./dist/browser/index.js\",\n\t\t\t\t\t\t\t\t\"require\": \"./dist/browser/index.cjs\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\"worker\": {\n\t\t\t\t\t\t\t\t\"import\": \"./dist/browser/index.js\",\n\t\t\t\t\t\t\t\t\"require\": \"./dist/browser/index.cjs\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/node_modules/foo/dist/node/index.js\":     ``,\n\t\t\t\"/node_modules/foo/dist/node/index.cjs\":    ``,\n\t\t\t\"/node_modules/foo/dist/browser/index.js\":  ``,\n\t\t\t\"/node_modules/foo/dist/browser/index.cjs\": ``,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tPlatform:      config.PlatformNode,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\tdebugLogs: true,\n\t\texpectedScanLog: `node_modules/foo/package.json: DEBUG: The conditions \"node\" and \"browser\" and \"worker\" here will never be used as they come after \"default\"\nnode_modules/foo/package.json: NOTE: The \"default\" condition comes earlier and will always be chosen:\n`,\n\t})\n}\n\n// See: https://github.com/evanw/esbuild/issues/3887\nfunc TestPackageJsonExportsDefaultWarningIssue3887(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport \"foo\"\n\t\t\t`,\n\t\t\t\"/node_modules/foo/dist/index.js\": `\n\t\t\t\tsuccess()\n\t\t\t`,\n\t\t\t\"/node_modules/foo/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\".\": {\n\t\t\t\t\t\t\t\"node\": \"./dist/index.js\",\n\t\t\t\t\t\t\t\"require\": \"./dist/index.js\",\n\t\t\t\t\t\t\t\"import\": \"./dist/index.esm.js\",\n\t\t\t\t\t\t\t\"default\": \"./dist/index.esm.js\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tPlatform:      config.PlatformNode,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\tdebugLogs: true,\n\t})\n}\n\n// https://github.com/evanw/esbuild/issues/4144\nfunc TestConfusingNameCollisionsIssue4144(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport { it } from 'mydependency'\n\t\t\t\tconsole.log(it())\n\t\t\t`,\n\t\t\t\"/node_modules/mydependency/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"main\": \"./package/index.js\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/node_modules/mydependency/package/index.js\": `\n\t\t\t\texport { it } from './utils'\n\t\t\t\texport let works = true\n\t\t\t`,\n\t\t\t\"/node_modules/mydependency/package/utils/index.js\": `\n\t\t\t\texport { it } from './utils'\n\t\t\t`,\n\t\t\t\"/node_modules/mydependency/package/utils/utils.js\": `\n\t\t\t\t// This should resolve to \"../index.js\" not \"../../package.json\"\n\t\t\t\timport { works } from '..'\n\t\t\t\texport function it() { return works }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// https://github.com/evanw/esbuild/issues/4187\nfunc TestPackageJsonBrowserMatchingTrailingSlashIssue4187(t *testing.T) {\n\tpackagejson_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport axios from \"axios\"\n\t\t\t`,\n\t\t\t\"/node_modules/axios/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"browser\": {\n\t\t\t\t\t\t\"./node/index.js\": \"./browser/index.js\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/node_modules/axios/index.js\": `\n\t\t\t\tmodule.exports = require('./node/');\n\t\t\t`,\n\t\t\t\"/node_modules/axios/node/index.js\": `\n\t\t\t\tmodule.exports = { get: () => new Promise('Node') }\n\t\t\t`,\n\t\t\t\"/node_modules/axios/browser/index.js\": `\n\t\t\t\tmodule.exports = { get: () => new Promise('Browser') }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "internal/bundler_tests/bundler_splitting_test.go",
    "content": "package bundler_tests\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/config\"\n)\n\nvar splitting_suite = suite{\n\tname: \"splitting\",\n}\n\nfunc TestSplittingSharedES6IntoES6(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport {foo} from \"./shared.js\"\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport {foo} from \"./shared.js\"\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/shared.js\": `export let foo = 123`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingSharedCommonJSIntoES6(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\tconst {foo} = require(\"./shared.js\")\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\tconst {foo} = require(\"./shared.js\")\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/shared.js\": `exports.foo = 123`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingDynamicES6IntoES6(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport(\"./foo.js\").then(({bar}) => console.log(bar))\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingDynamicCommonJSIntoES6(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport(\"./foo.js\").then(({default: {bar}}) => console.log(bar))\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texports.bar = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingDynamicAndNotDynamicES6IntoES6(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {bar as a} from \"./foo.js\"\n\t\t\t\timport(\"./foo.js\").then(({bar: b}) => console.log(a, b))\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingDynamicAndNotDynamicCommonJSIntoES6(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport {bar as a} from \"./foo.js\"\n\t\t\t\timport(\"./foo.js\").then(({default: {bar: b}}) => console.log(a, b))\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texports.bar = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingAssignToLocal(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport {foo, setFoo} from \"./shared.js\"\n\t\t\t\tsetFoo(123)\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport {foo} from \"./shared.js\"\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/shared.js\": `\n\t\t\t\texport let foo\n\t\t\t\texport function setFoo(value) {\n\t\t\t\t\tfoo = value\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingSideEffectsWithoutDependencies(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport {a} from \"./shared.js\"\n\t\t\t\tconsole.log(a)\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport {b} from \"./shared.js\"\n\t\t\t\tconsole.log(b)\n\t\t\t`,\n\t\t\t\"/shared.js\": `\n\t\t\t\texport let a = 1\n\t\t\t\texport let b = 2\n\t\t\t\tconsole.log('side effect')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingNestedDirectories(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/pages/pageA/page.js\": `\n\t\t\t\timport x from \"../shared.js\"\n\t\t\t\tconsole.log(x)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/pages/pageB/page.js\": `\n\t\t\t\timport x from \"../shared.js\"\n\t\t\t\tconsole.log(-x)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/pages/shared.js\": `\n\t\t\t\texport default 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/Users/user/project/src/pages/pageA/page.js\",\n\t\t\t\"/Users/user/project/src/pages/pageB/page.js\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/Users/user/project/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingCircularReferenceIssue251(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\texport * from './b.js';\n\t\t\t\texport var p = 5;\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\texport * from './a.js';\n\t\t\t\texport var q = 6;\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingMissingLazyExport(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport {foo} from './common.js'\n\t\t\t\tconsole.log(foo())\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport {bar} from './common.js'\n\t\t\t\tconsole.log(bar())\n\t\t\t`,\n\t\t\t\"/common.js\": `\n\t\t\t\timport * as ns from './empty.js'\n\t\t\t\texport function foo() { return [ns, ns.missing] }\n\t\t\t\texport function bar() { return [ns.missing] }\n\t\t\t`,\n\t\t\t\"/empty.js\": `\n\t\t\t\t// This forces the module into ES6 mode without importing or exporting anything\n\t\t\t\timport.meta\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t\texpectedCompileLog: `common.js: WARNING: Import \"missing\" will always be undefined because the file \"empty.js\" has no exports\n`,\n\t})\n}\n\nfunc TestSplittingReExportIssue273(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\texport const a = 1\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\texport { a } from './a'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingDynamicImportIssue272(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport('./b')\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\texport default 1\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingDynamicImportOutsideSourceTreeIssue264(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry1.js\": `\n\t\t\t\timport('package')\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/entry2.js\": `\n\t\t\t\timport('package')\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/package/index.js\": `\n\t\t\t\tconsole.log('imported')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry1.js\", \"/Users/user/project/src/entry2.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingCrossChunkAssignmentDependencies(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport {setValue} from './shared'\n\t\t\t\tsetValue(123)\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport './shared'\n\t\t\t`,\n\t\t\t\"/shared.js\": `\n\t\t\t\tvar observer;\n\t\t\t\tvar value;\n\t\t\t\texport function setObserver(cb) {\n\t\t\t\t\tobserver = cb;\n\t\t\t\t}\n\t\t\t\texport function getValue() {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t\texport function setValue(next) {\n\t\t\t\t\tvalue = next;\n\t\t\t\t\tif (observer) observer();\n\t\t\t\t}\n\t\t\t\tsideEffects(getValue);\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingCrossChunkAssignmentDependenciesRecursive(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport { setX } from './x'\n\t\t\t\tsetX()\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport { setZ } from './z'\n\t\t\t\tsetZ()\n\t\t\t`,\n\t\t\t\"/c.js\": `\n\t\t\t\timport { setX2 } from './x'\n\t\t\t\timport { setY2 } from './y'\n\t\t\t\timport { setZ2 } from './z'\n\t\t\t\tsetX2();\n\t\t\t\tsetY2();\n\t\t\t\tsetZ2();\n\t\t\t`,\n\t\t\t\"/x.js\": `\n\t\t\t\tlet _x\n\t\t\t\texport function setX(v) { _x = v }\n\t\t\t\texport function setX2(v) { _x = v }\n\t\t\t`,\n\t\t\t\"/y.js\": `\n\t\t\t\timport { setX } from './x'\n\t\t\t\tlet _y\n\t\t\t\texport function setY(v) { _y = v }\n\t\t\t\texport function setY2(v) { setX(v); _y = v }\n\t\t\t`,\n\t\t\t\"/z.js\": `\n\t\t\t\timport { setY } from './y'\n\t\t\t\tlet _z\n\t\t\t\texport function setZ(v) { _z = v }\n\t\t\t\texport function setZ2(v) { setY(v); _z = v }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\", \"/c.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingDuplicateChunkCollision(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport \"./ab\"\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport \"./ab\"\n\t\t\t`,\n\t\t\t\"/c.js\": `\n\t\t\t\timport \"./cd\"\n\t\t\t`,\n\t\t\t\"/d.js\": `\n\t\t\t\timport \"./cd\"\n\t\t\t`,\n\t\t\t\"/ab.js\": `\n\t\t\t\tconsole.log(123)\n\t\t\t`,\n\t\t\t\"/cd.js\": `\n\t\t\t\tconsole.log(123)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\", \"/c.js\", \"/d.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:             config.ModeBundle,\n\t\t\tCodeSplitting:    true,\n\t\t\tMinifyWhitespace: true,\n\t\t\tOutputFormat:     config.FormatESModule,\n\t\t\tAbsOutputDir:     \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingMinifyIdentifiersCrashIssue437(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport {foo} from \"./shared\"\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\timport {foo} from \"./shared\"\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/c.js\": `\n\t\t\t\timport \"./shared\"\n\t\t\t`,\n\t\t\t\"/shared.js\": `\n\t\t\t\texport function foo(bar) {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\", \"/c.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tCodeSplitting:     true,\n\t\t\tMinifyIdentifiers: true,\n\t\t\tOutputFormat:      config.FormatESModule,\n\t\t\tAbsOutputDir:      \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingHybridESMAndCJSIssue617(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\texport let foo\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\texport let bar = require('./a')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\", \"/b.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingPublicPathEntryName(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.js\": `\n\t\t\t\timport(\"./b\")\n\t\t\t`,\n\t\t\t\"/b.js\": `\n\t\t\t\tconsole.log('b')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tCodeSplitting: true,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tPublicPath:    \"/www/\",\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestSplittingChunkPathDirPlaceholderImplicitOutbase(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/project/entry.js\": `\n\t\t\t\tconsole.log(import('./output-path/should-contain/this-text/file'))\n\t\t\t`,\n\t\t\t\"/project/output-path/should-contain/this-text/file.js\": `\n\t\t\t\tconsole.log('file.js')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/project/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tCodeSplitting: true,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t\tChunkPathTemplate: []config.PathTemplate{\n\t\t\t\t{Data: \"./\", Placeholder: config.DirPlaceholder},\n\t\t\t\t{Data: \"/\", Placeholder: config.NamePlaceholder},\n\t\t\t\t{Data: \"-\", Placeholder: config.HashPlaceholder},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestEdgeCaseIssue2793WithSplitting(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/a.js\": `\n\t\t\t\texport const A = 42;\n\t\t\t`,\n\t\t\t\"/src/b.js\": `\n\t\t\t\texport const B = async () => (await import(\".\")).A\n\t\t\t`,\n\t\t\t\"/src/index.js\": `\n\t\t\t\texport * from \"./a\"\n\t\t\t\texport * from \"./b\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/src/index.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tCodeSplitting: true,\n\t\t\tAbsOutputDir:  \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestEdgeCaseIssue2793WithoutSplitting(t *testing.T) {\n\tsplitting_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/src/a.js\": `\n\t\t\t\texport const A = 42;\n\t\t\t`,\n\t\t\t\"/src/b.js\": `\n\t\t\t\texport const B = async () => (await import(\".\")).A\n\t\t\t`,\n\t\t\t\"/src/index.js\": `\n\t\t\t\texport * from \"./a\"\n\t\t\t\texport * from \"./b\"\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/src/index.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "internal/bundler_tests/bundler_test.go",
    "content": "package bundler_tests\n\n// Bundling test results are stored in snapshot files, located in the\n// \"snapshots\" directory. This allows test results to be updated easily without\n// manually rewriting all of the expected values. To update the tests run\n// \"UPDATE_SNAPSHOTS=1 make test\" and commit the updated values. Make sure to\n// inspect the diff to ensure the expected values are valid.\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/bundler\"\n\t\"github.com/evanw/esbuild/internal/cache\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/fs\"\n\t\"github.com/evanw/esbuild/internal/linker\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/test\"\n)\n\nfunc es(version int) compat.JSFeature {\n\treturn compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{\n\t\tcompat.ES: {Parts: []int{version}},\n\t})\n}\n\nfunc assertLog(t *testing.T, msgs []logger.Msg, expected string) {\n\tt.Helper()\n\tvar text strings.Builder\n\tfor _, msg := range msgs {\n\t\ttext.WriteString(msg.String(logger.OutputOptions{}, logger.TerminalInfo{}))\n\t}\n\ttest.AssertEqualWithDiff(t, text.String(), expected)\n}\n\nfunc hasErrors(msgs []logger.Msg) bool {\n\tfor _, msg := range msgs {\n\t\tif msg.Kind == logger.Error {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\ntype bundled struct {\n\tfiles              map[string]string\n\tentryPaths         []string\n\tentryPathsAdvanced []bundler.EntryPoint\n\texpectedScanLog    string\n\texpectedCompileLog string\n\toptions            config.Options\n\tdebugLogs          bool\n\tabsWorkingDir      string\n}\n\ntype suite struct {\n\texpectedSnapshots  map[string]string\n\tgeneratedSnapshots map[string]string\n\tname               string\n\tpath               string\n\tmutex              sync.Mutex\n}\n\nfunc (s *suite) expectBundled(t *testing.T, args bundled) {\n\tt.Helper()\n\ts.__expectBundledImpl(t, args, fs.MockUnix)\n\n\t// Handle conversion to Windows-style paths\n\t{\n\t\tfiles := make(map[string]string)\n\t\tfor k, v := range args.files {\n\t\t\tfiles[unix2win(k)] = v\n\t\t}\n\t\targs.files = files\n\n\t\targs.entryPaths = append([]string{}, args.entryPaths...)\n\t\tfor i, entry := range args.entryPaths {\n\t\t\targs.entryPaths[i] = unix2win(entry)\n\t\t}\n\t\targs.absWorkingDir = unix2win(args.absWorkingDir)\n\n\t\targs.options.InjectPaths = append([]string{}, args.options.InjectPaths...)\n\t\tfor i, absPath := range args.options.InjectPaths {\n\t\t\targs.options.InjectPaths[i] = unix2win(absPath)\n\t\t}\n\n\t\taliases := make(map[string]string)\n\t\tfor k, v := range args.options.PackageAliases {\n\t\t\tif strings.HasPrefix(v, \"/\") {\n\t\t\t\tv = unix2win(v)\n\t\t\t}\n\t\t\taliases[k] = v\n\t\t}\n\t\targs.options.PackageAliases = aliases\n\n\t\treplace := make(map[string]bool)\n\t\tfor k, v := range args.options.ExternalSettings.PostResolve.Exact {\n\t\t\treplace[unix2win(k)] = v\n\t\t}\n\t\targs.options.ExternalSettings.PostResolve.Exact = replace\n\n\t\targs.options.AbsOutputFile = unix2win(args.options.AbsOutputFile)\n\t\targs.options.AbsOutputBase = unix2win(args.options.AbsOutputBase)\n\t\targs.options.AbsOutputDir = unix2win(args.options.AbsOutputDir)\n\t\targs.options.TSConfigPath = unix2win(args.options.TSConfigPath)\n\t}\n\n\ts.__expectBundledImpl(t, args, fs.MockWindows)\n}\n\nfunc (s *suite) expectBundledUnix(t *testing.T, args bundled) {\n\tt.Helper()\n\ts.__expectBundledImpl(t, args, fs.MockUnix)\n}\n\nfunc (s *suite) expectBundledWindows(t *testing.T, args bundled) {\n\tt.Helper()\n\ts.__expectBundledImpl(t, args, fs.MockWindows)\n}\n\n// Don't call this directly. Call the helpers above instead.\nfunc (s *suite) __expectBundledImpl(t *testing.T, args bundled, fsKind fs.MockKind) {\n\tt.Helper()\n\n\ttestName := t.Name()\n\tsubName := \"Unix\"\n\tif fsKind == fs.MockWindows {\n\t\tsubName = \"Windows\"\n\t}\n\n\tt.Run(subName, func(t *testing.T) {\n\t\tt.Helper()\n\n\t\t// Prepare the options\n\t\tif args.options.ExtensionOrder == nil {\n\t\t\targs.options.ExtensionOrder = []string{\".tsx\", \".ts\", \".jsx\", \".js\", \".css\", \".json\"}\n\t\t}\n\t\tif args.options.AbsOutputFile != \"\" {\n\t\t\tif fsKind == fs.MockWindows {\n\t\t\t\targs.options.AbsOutputDir = unix2win(path.Dir(win2unix(args.options.AbsOutputFile)))\n\t\t\t} else {\n\t\t\t\targs.options.AbsOutputDir = path.Dir(args.options.AbsOutputFile)\n\t\t\t}\n\t\t}\n\t\tif args.options.Mode == config.ModeBundle || (args.options.Mode == config.ModeConvertFormat && args.options.OutputFormat == config.FormatIIFE) {\n\t\t\t// Apply this default to all tests since it was not configurable when the tests were written\n\t\t\targs.options.TreeShaking = true\n\t\t}\n\t\tif args.options.Mode == config.ModeBundle && args.options.OutputFormat == config.FormatPreserve {\n\t\t\t// The format can't be \"preserve\" while bundling\n\t\t\targs.options.OutputFormat = config.FormatESModule\n\t\t}\n\t\tlogKind := logger.DeferLogNoVerboseOrDebug\n\t\tif args.debugLogs {\n\t\t\tlogKind = logger.DeferLogAll\n\t\t}\n\t\tentryPoints := make([]bundler.EntryPoint, 0, len(args.entryPaths)+len(args.entryPathsAdvanced))\n\t\tfor _, path := range args.entryPaths {\n\t\t\tentryPoints = append(entryPoints, bundler.EntryPoint{InputPath: path})\n\t\t}\n\t\tentryPoints = append(entryPoints, args.entryPathsAdvanced...)\n\t\tif args.absWorkingDir == \"\" {\n\t\t\tif fsKind == fs.MockWindows {\n\t\t\t\targs.absWorkingDir = \"C:\\\\\"\n\t\t\t} else {\n\t\t\t\targs.absWorkingDir = \"/\"\n\t\t\t}\n\t\t}\n\t\tif args.options.AbsOutputDir == \"\" {\n\t\t\targs.options.AbsOutputDir = args.absWorkingDir // Match the behavior of the API in this case\n\t\t}\n\n\t\t// Run the bundler\n\t\tlog := logger.NewDeferLog(logKind, nil)\n\t\tcaches := cache.MakeCacheSet()\n\t\tmockFS := fs.MockFS(args.files, fsKind, args.absWorkingDir)\n\t\targs.options.OmitRuntimeForTests = true\n\t\tbundle := bundler.ScanBundle(config.BuildCall, log, mockFS, caches, entryPoints, args.options, nil)\n\t\tmsgs := log.Done()\n\t\tassertLog(t, msgs, args.expectedScanLog)\n\n\t\t// Stop now if there were any errors during the scan\n\t\tif hasErrors(msgs) {\n\t\t\treturn\n\t\t}\n\n\t\tlog = logger.NewDeferLog(logKind, nil)\n\t\tresults, metafileJSON := bundle.Compile(log, nil, nil, linker.Link)\n\t\tmsgs = log.Done()\n\t\tassertLog(t, msgs, args.expectedCompileLog)\n\n\t\t// Stop now if there were any errors during the compile\n\t\tif hasErrors(msgs) {\n\t\t\treturn\n\t\t}\n\n\t\t// Don't include source maps in results since they are just noise. Source\n\t\t// map validity is tested separately in a test that uses Mozilla's source\n\t\t// map parsing library.\n\t\tgenerated := \"\"\n\t\tfor _, result := range results {\n\t\t\tif generated != \"\" {\n\t\t\t\tgenerated += \"\\n\"\n\t\t\t}\n\t\t\tif fsKind == fs.MockWindows {\n\t\t\t\tresult.AbsPath = win2unix(result.AbsPath)\n\t\t\t}\n\t\t\tgenerated += fmt.Sprintf(\"---------- %s ----------\\n%s\", result.AbsPath, string(result.Contents))\n\t\t}\n\t\tif metafileJSON != \"\" {\n\t\t\tgenerated += fmt.Sprintf(\"---------- metafile.json ----------\\n%s\", metafileJSON)\n\t\t}\n\t\ts.compareSnapshot(t, testName, generated)\n\t})\n}\n\nconst snapshotsDir = \"snapshots\"\nconst snapshotSplitter = \"\\n================================================================================\\n\"\n\nvar globalTestMutex sync.Mutex\nvar globalSuites map[*suite]bool\nvar globalUpdateSnapshots bool\n\nfunc (s *suite) compareSnapshot(t *testing.T, testName string, generated string) {\n\tt.Helper()\n\t// Initialize the test suite during the first test\n\ts.mutex.Lock()\n\tdefer s.mutex.Unlock()\n\tif s.path == \"\" {\n\t\ts.path = snapshotsDir + \"/snapshots_\" + s.name + \".txt\"\n\t\ts.generatedSnapshots = make(map[string]string)\n\t\ts.expectedSnapshots = make(map[string]string)\n\t\tif contents, err := ioutil.ReadFile(s.path); err == nil {\n\t\t\t// Replacing CRLF with LF is necessary to fix tests in GitHub actions,\n\t\t\t// which for some reason check out the source code in CLRF mode\n\t\t\tfor _, part := range strings.Split(strings.ReplaceAll(string(contents), \"\\r\\n\", \"\\n\"), snapshotSplitter) {\n\t\t\t\tif newline := strings.IndexByte(part, '\\n'); newline != -1 {\n\t\t\t\t\tkey := part[:newline]\n\t\t\t\t\tvalue := part[newline+1:]\n\t\t\t\t\ts.expectedSnapshots[key] = value\n\t\t\t\t} else {\n\t\t\t\t\ts.expectedSnapshots[part] = \"\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tglobalTestMutex.Lock()\n\t\tdefer globalTestMutex.Unlock()\n\t\tif globalSuites == nil {\n\t\t\tglobalSuites = make(map[*suite]bool)\n\t\t}\n\t\tglobalSuites[s] = true\n\t\t_, globalUpdateSnapshots = os.LookupEnv(\"UPDATE_SNAPSHOTS\")\n\t}\n\n\t// Check against the stored snapshot if present\n\ts.generatedSnapshots[testName] = generated\n\tif !globalUpdateSnapshots {\n\t\tif expected, ok := s.expectedSnapshots[testName]; ok {\n\t\t\ttest.AssertEqualWithDiff(t, generated, expected)\n\t\t} else {\n\t\t\tt.Fatalf(\"No snapshot saved for %s\\n%s%s%s\",\n\t\t\t\ttestName,\n\t\t\t\tlogger.TerminalColors.Green,\n\t\t\t\tgenerated,\n\t\t\t\tlogger.TerminalColors.Reset,\n\t\t\t)\n\t\t}\n\t}\n}\n\nfunc (s *suite) updateSnapshots() {\n\tos.Mkdir(snapshotsDir, 0755)\n\tkeys := make([]string, 0, len(s.generatedSnapshots))\n\tfor key := range s.generatedSnapshots {\n\t\tkeys = append(keys, key)\n\t}\n\tsort.Strings(keys)\n\tvar contents strings.Builder\n\tfor i, key := range keys {\n\t\tif i > 0 {\n\t\t\tcontents.WriteString(snapshotSplitter)\n\t\t}\n\t\tcontents.WriteString(fmt.Sprintf(\"%s\\n%s\", key, s.generatedSnapshots[key]))\n\t}\n\tif err := ioutil.WriteFile(s.path, []byte(contents.String()), 0644); err != nil {\n\t\tpanic(err)\n\t}\n}\n\nfunc (s *suite) validateSnapshots() bool {\n\tisValid := true\n\tfor key := range s.expectedSnapshots {\n\t\tif _, ok := s.generatedSnapshots[key]; !ok {\n\t\t\tif isValid {\n\t\t\t\tfmt.Printf(\"%s\\n\", s.path)\n\t\t\t}\n\t\t\tfmt.Printf(\"    No test found for snapshot %s\\n\", key)\n\t\t\tisValid = false\n\t\t}\n\t}\n\treturn isValid\n}\n\nfunc TestMain(m *testing.M) {\n\tcode := m.Run()\n\tif globalSuites != nil {\n\t\tif globalUpdateSnapshots {\n\t\t\tfor s := range globalSuites {\n\t\t\t\ts.updateSnapshots()\n\t\t\t}\n\t\t} else {\n\t\t\tfor s := range globalSuites {\n\t\t\t\tif !s.validateSnapshots() {\n\t\t\t\t\tcode = 1\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tos.Exit(code)\n}\n\nfunc win2unix(p string) string {\n\tif strings.HasPrefix(p, \"C:\\\\\") {\n\t\tp = p[2:]\n\t}\n\tp = strings.ReplaceAll(p, \"\\\\\", \"/\")\n\treturn p\n}\n\nfunc unix2win(p string) string {\n\tp = strings.ReplaceAll(p, \"/\", \"\\\\\")\n\tif strings.HasPrefix(p, \"\\\\\") {\n\t\tp = \"C:\" + p\n\t}\n\treturn p\n}\n"
  },
  {
    "path": "internal/bundler_tests/bundler_ts_test.go",
    "content": "package bundler_tests\n\nimport (\n\t\"regexp\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n)\n\nvar ts_suite = suite{\n\tname: \"ts\",\n}\n\nfunc TestTSDeclareConst(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tdeclare const require: any\n\t\t\t\tdeclare const exports: any;\n\t\t\t\tdeclare const module: any\n\n\t\t\t\tdeclare const foo: any\n\t\t\t\tlet foo = bar()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSDeclareLet(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tdeclare let require: any\n\t\t\t\tdeclare let exports: any;\n\t\t\t\tdeclare let module: any\n\n\t\t\t\tdeclare let foo: any\n\t\t\t\tlet foo = bar()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSDeclareVar(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tdeclare var require: any\n\t\t\t\tdeclare var exports: any;\n\t\t\t\tdeclare var module: any\n\n\t\t\t\tdeclare var foo: any\n\t\t\t\tlet foo = bar()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSDeclareClass(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tdeclare class require {}\n\t\t\t\tdeclare class exports {};\n\t\t\t\tdeclare class module {}\n\n\t\t\t\tdeclare class foo {}\n\t\t\t\tlet foo = bar()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSDeclareClassFields(t *testing.T) {\n\t// Note: this test uses arrow functions to validate that\n\t// scopes inside \"declare\" fields are correctly discarded\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport './define-false'\n\t\t\t\timport './define-true'\n\t\t\t`,\n\t\t\t\"/define-false/index.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\ta\n\t\t\t\t\tdeclare b\n\t\t\t\t\t[(() => null, c)]\n\t\t\t\t\tdeclare [(() => null, d)]\n\n\t\t\t\t\tstatic A\n\t\t\t\t\tstatic declare B\n\t\t\t\t\tstatic [(() => null, C)]\n\t\t\t\t\tstatic declare [(() => null, D)]\n\t\t\t\t}\n\t\t\t\t(() => new Foo())()\n\t\t\t`,\n\t\t\t\"/define-true/index.ts\": `\n\t\t\t\tclass Bar {\n\t\t\t\t\ta\n\t\t\t\t\tdeclare b\n\t\t\t\t\t[(() => null, c)]\n\t\t\t\t\tdeclare [(() => null, d)]\n\n\t\t\t\t\tstatic A\n\t\t\t\t\tstatic declare B\n\t\t\t\t\tstatic [(() => null, C)]\n\t\t\t\t\tstatic declare [(() => null, D)]\n\t\t\t\t}\n\t\t\t\t(() => new Bar())()\n\t\t\t`,\n\t\t\t\"/define-false/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": false\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.ClassField,\n\t\t},\n\t})\n}\n\nfunc TestTSDeclareFunction(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tdeclare function require(): void\n\t\t\t\tdeclare function exports(): void;\n\t\t\t\tdeclare function module(): void\n\n\t\t\t\tdeclare function foo() {}\n\t\t\t\tlet foo = bar()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSDeclareNamespace(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tdeclare namespace require {}\n\t\t\t\tdeclare namespace exports {};\n\t\t\t\tdeclare namespace module {}\n\n\t\t\t\tdeclare namespace foo {}\n\t\t\t\tlet foo = bar()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSDeclareEnum(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tdeclare enum require {}\n\t\t\t\tdeclare enum exports {};\n\t\t\t\tdeclare enum module {}\n\n\t\t\t\tdeclare enum foo {}\n\t\t\t\tlet foo = bar()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSDeclareConstEnum(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tdeclare const enum require {}\n\t\t\t\tdeclare const enum exports {};\n\t\t\t\tdeclare const enum module {}\n\n\t\t\t\tdeclare const enum foo {}\n\t\t\t\tlet foo = bar()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSConstEnumComments(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/bar.ts\": `\n\t\t\t\texport const enum Foo {\n\t\t\t\t\t\"%/*\" = 1,\n\t\t\t\t\t\"*/%\" = 2,\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\timport { Foo } from \"./bar\";\n\t\t\t\tconst enum Bar {\n\t\t\t\t\t\"%/*\" = 1,\n\t\t\t\t\t\"*/%\" = 2,\n\t\t\t\t}\n\t\t\t\tconsole.log({\n\t\t\t\t\t'should have comments': [\n\t\t\t\t\t\tFoo[\"%/*\"],\n\t\t\t\t\t\tBar[\"%/*\"],\n\t\t\t\t\t],\n\t\t\t\t\t'should not have comments': [\n\t\t\t\t\t\tFoo[\"*/%\"],\n\t\t\t\t\t\tBar[\"*/%\"],\n\t\t\t\t\t],\n\t\t\t\t});\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/foo.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportEmptyNamespace(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport {ns} from './ns.ts'\n\t\t\t\tfunction foo(): ns.type {}\n\t\t\t\tfoo();\n\t\t\t`,\n\t\t\t\"/ns.ts\": `\n\t\t\t\texport namespace ns {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportMissingES6(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport fn, {x as a, y as b} from './foo'\n\t\t\t\tconsole.log(fn(a, b))\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedCompileLog: `entry.ts: ERROR: No matching export in \"foo.js\" for import \"default\"\nentry.ts: ERROR: No matching export in \"foo.js\" for import \"y\"\n`,\n\t})\n}\n\nfunc TestTSImportMissingUnusedES6(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport fn, {x as a, y as b} from './foo'\n\t\t\t`,\n\t\t\t\"/foo.js\": `\n\t\t\t\texport const x = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSExportMissingES6(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport * as ns from './foo'\n\t\t\t\tconsole.log(ns)\n\t\t\t`,\n\t\t\t\"/foo.ts\": `\n\t\t\t\texport {nope} from './bar'\n\t\t\t`,\n\t\t\t\"/bar.js\": `\n\t\t\t\texport const yep = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\n// It's an error to import from a file that does not exist\nfunc TestTSImportMissingFile(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport {Something} from './doesNotExist.ts'\n\t\t\t\tlet foo = new Something\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.ts: ERROR: Could not resolve \"./doesNotExist.ts\"\n`,\n\t})\n}\n\n// It's not an error to import a type from a file that does not exist\nfunc TestTSImportTypeOnlyFile(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport {SomeType1} from './doesNotExist1.ts'\n\t\t\t\timport {SomeType2} from './doesNotExist2.ts'\n\t\t\t\tlet foo: SomeType1 = bar()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSExportEquals(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.ts\": `\n\t\t\t\timport b from './b.ts'\n\t\t\t\tconsole.log(b)\n\t\t\t`,\n\t\t\t\"/b.ts\": `\n\t\t\t\texport = [123, foo]\n\t\t\t\tfunction foo() {}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSExportNamespace(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.ts\": `\n\t\t\t\timport {Foo} from './b.ts'\n\t\t\t\tconsole.log(new Foo)\n\t\t\t`,\n\t\t\t\"/b.ts\": `\n\t\t\t\texport class Foo {}\n\t\t\t\texport namespace Foo {\n\t\t\t\t\texport let foo = 1\n\t\t\t\t}\n\t\t\t\texport namespace Foo {\n\t\t\t\t\texport let bar = 2\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSNamespaceKeepNames(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tnamespace ns {\n\t\t\t\t\texport let foo = () => {}\n\t\t\t\t\texport function bar() {}\n\t\t\t\t\texport class Baz {}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tKeepNames:     true,\n\t\t},\n\t})\n}\n\nfunc TestTSNamespaceKeepNamesTargetES2015(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tnamespace ns {\n\t\t\t\t\texport let foo = () => {}\n\t\t\t\t\texport function bar() {}\n\t\t\t\t\texport class Baz {}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tKeepNames:             true,\n\t\t\tUnsupportedJSFeatures: es(2015),\n\t\t},\n\t})\n}\n\nfunc TestTSMinifyEnum(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.ts\": `\n\t\t\t\tenum Foo { A, B, C = Foo }\n\t\t\t`,\n\t\t\t\"/b.ts\": `\n\t\t\t\texport enum Foo { X, Y, Z = Foo }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.ts\", \"/b.ts\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:      true,\n\t\t\tMinifyWhitespace:  true,\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputDir:      \"/\",\n\t\t},\n\t})\n}\n\nfunc TestTSMinifyNestedEnum(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.ts\": `\n\t\t\t\tfunction foo() { enum Foo { A, B, C = Foo } return Foo }\n\t\t\t`,\n\t\t\t\"/b.ts\": `\n\t\t\t\texport function foo() { enum Foo { X, Y, Z = Foo } return Foo }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.ts\", \"/b.ts\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:      true,\n\t\t\tMinifyWhitespace:  true,\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputDir:      \"/\",\n\t\t},\n\t})\n}\n\nfunc TestTSMinifyNestedEnumNoLogicalAssignment(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.ts\": `\n\t\t\t\tfunction foo() { enum Foo { A, B, C = Foo } return Foo }\n\t\t\t`,\n\t\t\t\"/b.ts\": `\n\t\t\t\texport function foo() { enum Foo { X, Y, Z = Foo } return Foo }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.ts\", \"/b.ts\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:          true,\n\t\t\tMinifyWhitespace:      true,\n\t\t\tMinifyIdentifiers:     true,\n\t\t\tAbsOutputDir:          \"/\",\n\t\t\tUnsupportedJSFeatures: compat.LogicalAssignment,\n\t\t},\n\t})\n}\n\nfunc TestTSMinifyNestedEnumNoArrow(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.ts\": `\n\t\t\t\tfunction foo() { enum Foo { A, B, C = Foo } return Foo }\n\t\t\t`,\n\t\t\t\"/b.ts\": `\n\t\t\t\texport function foo() { enum Foo { X, Y, Z = Foo } return Foo }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.ts\", \"/b.ts\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:          true,\n\t\t\tMinifyWhitespace:      true,\n\t\t\tMinifyIdentifiers:     true,\n\t\t\tAbsOutputDir:          \"/\",\n\t\t\tUnsupportedJSFeatures: compat.Arrow,\n\t\t},\n\t})\n}\n\nfunc TestTSMinifyNamespace(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.ts\": `\n\t\t\t\tnamespace Foo {\n\t\t\t\t\texport namespace Bar {\n\t\t\t\t\t\tfoo(Foo, Bar)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/b.ts\": `\n\t\t\t\texport namespace Foo {\n\t\t\t\t\texport namespace Bar {\n\t\t\t\t\t\tfoo(Foo, Bar)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.ts\", \"/b.ts\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:      true,\n\t\t\tMinifyWhitespace:  true,\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputDir:      \"/\",\n\t\t},\n\t})\n}\n\nfunc TestTSMinifyNamespaceNoLogicalAssignment(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.ts\": `\n\t\t\t\tnamespace Foo {\n\t\t\t\t\texport namespace Bar {\n\t\t\t\t\t\tfoo(Foo, Bar)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/b.ts\": `\n\t\t\t\texport namespace Foo {\n\t\t\t\t\texport namespace Bar {\n\t\t\t\t\t\tfoo(Foo, Bar)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.ts\", \"/b.ts\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:          true,\n\t\t\tMinifyWhitespace:      true,\n\t\t\tMinifyIdentifiers:     true,\n\t\t\tAbsOutputDir:          \"/\",\n\t\t\tUnsupportedJSFeatures: compat.LogicalAssignment,\n\t\t},\n\t})\n}\n\nfunc TestTSMinifyNamespaceNoArrow(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/a.ts\": `\n\t\t\t\tnamespace Foo {\n\t\t\t\t\texport namespace Bar {\n\t\t\t\t\t\tfoo(Foo, Bar)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/b.ts\": `\n\t\t\t\texport namespace Foo {\n\t\t\t\t\texport namespace Bar {\n\t\t\t\t\t\tfoo(Foo, Bar)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/a.ts\", \"/b.ts\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:          true,\n\t\t\tMinifyWhitespace:      true,\n\t\t\tMinifyIdentifiers:     true,\n\t\t\tAbsOutputDir:          \"/\",\n\t\t\tUnsupportedJSFeatures: compat.Arrow,\n\t\t},\n\t})\n}\n\nfunc TestTSMinifyDerivedClass(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass Foo extends Bar {\n\t\t\t\t\tfoo = 1;\n\t\t\t\t\tbar = 2;\n\t\t\t\t\tconstructor() {\n\t\t\t\t\t\tsuper();\n\t\t\t\t\t\tfoo();\n\t\t\t\t\t\tbar();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": false\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMinifySyntax:          true,\n\t\t\tUnsupportedJSFeatures: es(2015),\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSMinifyEnumPropertyNames(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport { CrossFileGood, CrossFileBad } from './cross-file'\n\t\t\t\tconst enum SameFileGood {\n\t\t\t\t\tSTR = 'str 1',\n\t\t\t\t\tNUM = 123,\n\t\t\t\t}\n\t\t\t\tconst enum SameFileBad {\n\t\t\t\t\tPROTO = '__proto__',\n\t\t\t\t\tCONSTRUCTOR = 'constructor',\n\t\t\t\t\tPROTOTYPE = 'prototype',\n\t\t\t\t}\n\t\t\t\tclass Foo {\n\t\t\t\t\t[100] = 100;\n\t\t\t\t\t'200' = 200;\n\t\t\t\t\t['300'] = 300;\n\t\t\t\t\t[SameFileGood.STR] = SameFileGood.STR;\n\t\t\t\t\t[SameFileGood.NUM] = SameFileGood.NUM;\n\t\t\t\t\t[CrossFileGood.STR] = CrossFileGood.STR;\n\t\t\t\t\t[CrossFileGood.NUM] = CrossFileGood.NUM;\n\t\t\t\t}\n\t\t\t\tshouldNotBeComputed(\n\t\t\t\t\tclass {\n\t\t\t\t\t\t[100] = 100;\n\t\t\t\t\t\t'200' = 200;\n\t\t\t\t\t\t['300'] = 300;\n\t\t\t\t\t\t[SameFileGood.STR] = SameFileGood.STR;\n\t\t\t\t\t\t[SameFileGood.NUM] = SameFileGood.NUM;\n\t\t\t\t\t\t[CrossFileGood.STR] = CrossFileGood.STR;\n\t\t\t\t\t\t[CrossFileGood.NUM] = CrossFileGood.NUM;\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t[100]: 100,\n\t\t\t\t\t\t'200': 200,\n\t\t\t\t\t\t['300']: 300,\n\t\t\t\t\t\t[SameFileGood.STR]: SameFileGood.STR,\n\t\t\t\t\t\t[SameFileGood.NUM]: SameFileGood.NUM,\n\t\t\t\t\t\t[CrossFileGood.STR]: CrossFileGood.STR,\n\t\t\t\t\t\t[CrossFileGood.NUM]: CrossFileGood.NUM,\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t\tmustBeComputed(\n\t\t\t\t\t{ [SameFileBad.PROTO]: null },\n\t\t\t\t\t{ [CrossFileBad.PROTO]: null },\n\t\t\t\t\tclass { [SameFileBad.CONSTRUCTOR]() {} },\n\t\t\t\t\tclass { [CrossFileBad.CONSTRUCTOR]() {} },\n\t\t\t\t\tclass { static [SameFileBad.PROTOTYPE]() {} },\n\t\t\t\t\tclass { static [CrossFileBad.PROTOTYPE]() {} },\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/cross-file.ts\": `\n\t\t\t\texport const enum CrossFileGood {\n\t\t\t\t\tSTR = 'str 2',\n\t\t\t\t\tNUM = 321,\n\t\t\t\t}\n\t\t\t\texport const enum CrossFileBad {\n\t\t\t\t\tPROTO = '__proto__',\n\t\t\t\t\tCONSTRUCTOR = 'constructor',\n\t\t\t\t\tPROTOTYPE = 'prototype',\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tMinifySyntax:  true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\nfunc TestTSMinifyEnumCrossFileInlineStringsIntoTemplates(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport { CrossFile } from './cross-file'\n\t\t\t\tenum SameFile {\n\t\t\t\t\tSTR = 'str 1',\n\t\t\t\t\tNUM = 123,\n\t\t\t\t}\n\t\t\t\tconsole.log(` + \"`\" + `\n\t\t\t\t\tSameFile.STR = ${SameFile.STR}\n\t\t\t\t\tSameFile.NUM = ${SameFile.NUM}\n\t\t\t\t\tCrossFile.STR = ${CrossFile.STR}\n\t\t\t\t\tCrossFile.NUM = ${CrossFile.NUM}\n\t\t\t\t` + \"`\" + `)\n\t\t\t`,\n\t\t\t\"/cross-file.ts\": `\n\t\t\t\texport enum CrossFile {\n\t\t\t\t\tSTR = 'str 2',\n\t\t\t\t\tNUM = 321,\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tMinifySyntax:  true,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportVsLocalCollisionAllTypes(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport {a, b, c, d, e} from './other.ts'\n\t\t\t\tlet a\n\t\t\t\tconst b = 0\n\t\t\t\tvar c\n\t\t\t\tfunction d() {}\n\t\t\t\tclass e {}\n\t\t\t\tconsole.log(a, b, c, d, e)\n\t\t\t`,\n\t\t\t\"/other.ts\": `\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportVsLocalCollisionMixed(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport {a, b, c, d, e, real} from './other.ts'\n\t\t\t\tlet a\n\t\t\t\tconst b = 0\n\t\t\t\tvar c\n\t\t\t\tfunction d() {}\n\t\t\t\tclass e {}\n\t\t\t\tconsole.log(a, b, c, d, e, real)\n\t\t\t`,\n\t\t\t\"/other.ts\": `\n\t\t\t\texport let real = 123\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportEqualsEliminationTest(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport a = foo.a\n\t\t\t\timport b = a.b\n\t\t\t\timport c = b.c\n\n\t\t\t\timport x = foo.x\n\t\t\t\timport y = x.y\n\t\t\t\timport z = y.z\n\n\t\t\t\texport let bar = c\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportEqualsTreeShakingFalse(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport { foo } from 'pkg'\n\t\t\t\timport used = foo.used\n\t\t\t\timport unused = foo.unused\n\t\t\t\texport { used }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tTreeShaking:   false,\n\t\t},\n\t})\n}\n\nfunc TestTSImportEqualsTreeShakingTrue(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport { foo } from 'pkg'\n\t\t\t\timport used = foo.used\n\t\t\t\timport unused = foo.unused\n\t\t\t\texport { used }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tTreeShaking:   true,\n\t\t},\n\t})\n}\n\nfunc TestTSImportEqualsBundle(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport { foo } from 'pkg'\n\t\t\t\timport used = foo.used\n\t\t\t\timport unused = foo.unused\n\t\t\t\texport { used }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tExact: map[string]bool{\n\t\t\t\t\t\t\"pkg\": true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestTSImportEqualsUndefinedImport(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as ns from './import.ts'\n\t\t\t\timport value_copy = ns.value\n\t\t\t\timport Type_copy = ns.Type\n\t\t\t\tlet foo: Type_copy = value_copy\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/import.ts\": `\n\t\t\t\texport let value = 123\n\t\t\t\texport type Type = number\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{\n\t\t\t\t\tExact: map[string]bool{\n\t\t\t\t\t\t\"pkg\": true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestTSMinifiedBundleES6(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport {foo} from './a'\n\t\t\t\tconsole.log(foo())\n\t\t\t`,\n\t\t\t\"/a.ts\": `\n\t\t\t\texport function foo() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tMinifySyntax:      true,\n\t\t\tMinifyWhitespace:  true,\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSMinifiedBundleCommonJS(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tconst {foo} = require('./a')\n\t\t\t\tconsole.log(foo(), require('./j.json'))\n\t\t\t`,\n\t\t\t\"/a.ts\": `\n\t\t\t\texports.foo = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/j.json\": `\n\t\t\t\t{\"test\": true}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tMinifySyntax:      true,\n\t\t\tMinifyWhitespace:  true,\n\t\t\tMinifyIdentifiers: true,\n\t\t\tAbsOutputFile:     \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSExperimentalDecoratorsNoConfig(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tdeclare let x: any, y: any\n\t\t\t\t@x.y()\n\t\t\t\t@(new y.x)\n\t\t\t\texport default class Foo {\n\t\t\t\t\t@x @y mUndef: any\n\t\t\t\t\t@x @y mDef = 1\n\t\t\t\t\t@x @y method() { return new Foo }\n\t\t\t\t\t@x @y accessor aUndef: any\n\t\t\t\t\t@x @y accessor aDef = 1\n\n\t\t\t\t\t@x @y static sUndef: any\n\t\t\t\t\t@x @y static sDef = new Foo\n\t\t\t\t\t@x @y static sMethod() { return new Foo }\n\t\t\t\t\t@x @y static accessor asUndef: any\n\t\t\t\t\t@x @y static accessor asDef = 1\n\n\t\t\t\t\t@x @y #mUndef: any\n\t\t\t\t\t@x @y #mDef = 1\n\t\t\t\t\t@x @y #method() { return new Foo }\n\t\t\t\t\t@x @y accessor #aUndef: any\n\t\t\t\t\t@x @y accessor #aDef = 1\n\n\t\t\t\t\t@x @y static #sUndef: any\n\t\t\t\t\t@x @y static #sDef = 1\n\t\t\t\t\t@x @y static #sMethod() { return new Foo }\n\t\t\t\t\t@x @y static accessor #asUndef: any\n\t\t\t\t\t@x @y static accessor #asDef = 1\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"experimentalDecorators\": false\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSExperimentalDecorators(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport all from './all'\n\t\t\t\timport all_computed from './all_computed'\n\t\t\t\timport {a} from './a'\n\t\t\t\timport {b} from './b'\n\t\t\t\timport {c} from './c'\n\t\t\t\timport {d} from './d'\n\t\t\t\timport e from './e'\n\t\t\t\timport f from './f'\n\t\t\t\timport g from './g'\n\t\t\t\timport h from './h'\n\t\t\t\timport {i} from './i'\n\t\t\t\timport {j} from './j'\n\t\t\t\timport k from './k'\n\t\t\t\timport {fn} from './arguments'\n\t\t\t\tconsole.log(all, all_computed, a, b, c, d, e, f, g, h, i, j, k, fn)\n\t\t\t`,\n\t\t\t\"/all.ts\": `\n\t\t\t\t@x.y()\n\t\t\t\t@new y.x()\n\t\t\t\texport default class Foo {\n\t\t\t\t\t@x @y mUndef\n\t\t\t\t\t@x @y mDef = 1\n\t\t\t\t\t@x @y method(@x0 @y0 arg0, @x1 @y1 arg1) { return new Foo }\n\t\t\t\t\t@x @y declare mDecl\n\t\t\t\t\t@x @y abstract mAbst\n\t\t\t\t\tconstructor(@x0 @y0 arg0, @x1 @y1 arg1) {}\n\n\t\t\t\t\t@x @y static sUndef\n\t\t\t\t\t@x @y static sDef = new Foo\n\t\t\t\t\t@x @y static sMethod(@x0 @y0 arg0, @x1 @y1 arg1) { return new Foo }\n\t\t\t\t\t@x @y static declare mDecl\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/all_computed.ts\": `\n\t\t\t\t@x?.[_ + 'y']()\n\t\t\t\t@new y?.[_ + 'x']()\n\t\t\t\texport default class Foo {\n\t\t\t\t\t@x @y [mUndef()]\n\t\t\t\t\t@x @y [mDef()] = 1\n\t\t\t\t\t@x @y [method()](@x0 @y0 arg0, @x1 @y1 arg1) { return new Foo }\n\t\t\t\t\t@x @y declare [mDecl()]\n\t\t\t\t\t@x @y abstract [mAbst()]\n\n\t\t\t\t\t// Side effect order must be preserved even for fields without decorators\n\t\t\t\t\t[xUndef()]\n\t\t\t\t\t[xDef()] = 2\n\t\t\t\t\tstatic [yUndef()]\n\t\t\t\t\tstatic [yDef()] = 3\n\n\t\t\t\t\t@x @y static [sUndef()]\n\t\t\t\t\t@x @y static [sDef()] = new Foo\n\t\t\t\t\t@x @y static [sMethod()](@x0 @y0 arg0, @x1 @y1 arg1) { return new Foo }\n\t\t\t\t\t@x @y static declare [mDecl()]\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/a.ts\": `\n\t\t\t\t@x(() => 0) @y(() => 1)\n\t\t\t\tclass a_class {\n\t\t\t\t\tfn() { return new a_class }\n\t\t\t\t\tstatic z = new a_class\n\t\t\t\t}\n\t\t\t\texport let a = a_class\n\t\t\t`,\n\t\t\t\"/b.ts\": `\n\t\t\t\t@x(() => 0) @y(() => 1)\n\t\t\t\tabstract class b_class {\n\t\t\t\t\tfn() { return new b_class }\n\t\t\t\t\tstatic z = new b_class\n\t\t\t\t}\n\t\t\t\texport let b = b_class\n\t\t\t`,\n\t\t\t\"/c.ts\": `\n\t\t\t\t@x(() => 0) @y(() => 1)\n\t\t\t\texport class c {\n\t\t\t\t\tfn() { return new c }\n\t\t\t\t\tstatic z = new c\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/d.ts\": `\n\t\t\t\t@x(() => 0) @y(() => 1)\n\t\t\t\texport abstract class d {\n\t\t\t\t\tfn() { return new d }\n\t\t\t\t\tstatic z = new d\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/e.ts\": `\n\t\t\t\t@x(() => 0) @y(() => 1)\n\t\t\t\texport default class {}\n\t\t\t`,\n\t\t\t\"/f.ts\": `\n\t\t\t\t@x(() => 0) @y(() => 1)\n\t\t\t\texport default class f {\n\t\t\t\t\tfn() { return new f }\n\t\t\t\t\tstatic z = new f\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/g.ts\": `\n\t\t\t\t@x(() => 0) @y(() => 1)\n\t\t\t\texport default abstract class {}\n\t\t\t`,\n\t\t\t\"/h.ts\": `\n\t\t\t\t@x(() => 0) @y(() => 1)\n\t\t\t\texport default abstract class h {\n\t\t\t\t\tfn() { return new h }\n\t\t\t\t\tstatic z = new h\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/i.ts\": `\n\t\t\t\tclass i_class {\n\t\t\t\t\t@x(() => 0) @y(() => 1)\n\t\t\t\t\tfoo\n\t\t\t\t}\n\t\t\t\texport let i = i_class\n\t\t\t`,\n\t\t\t\"/j.ts\": `\n\t\t\t\texport class j {\n\t\t\t\t\t@x(() => 0) @y(() => 1)\n\t\t\t\t\tfoo() {}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/k.ts\": `\n\t\t\t\texport default class {\n\t\t\t\t\tfoo(@x(() => 0) @y(() => 1) x) {}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/arguments.ts\": `\n\t\t\t\tfunction dec(x: any): any {}\n\t\t\t\texport function fn(x: string): any {\n\t\t\t\t\tclass Foo {\n\t\t\t\t\t\t@dec(arguments[0])\n\t\t\t\t\t\t[arguments[0]]() {}\n\t\t\t\t\t}\n\t\t\t\t\treturn Foo;\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": false,\n\t\t\t\t\t\"experimentalDecorators\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSExperimentalDecoratorsKeepNames(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\t@decoratorMustComeAfterName\n\t\t\t\texport class Foo {}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"experimentalDecorators\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tKeepNames:     true,\n\t\t},\n\t})\n}\n\n// See: https://github.com/evanw/esbuild/issues/2147\nfunc TestTSExperimentalDecoratorScopeIssue2147(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tlet foo = 1\n\t\t\t\tclass Foo {\n\t\t\t\t\tmethod1(@dec(foo) foo = 2) {}\n\t\t\t\t\tmethod2(@dec(() => foo) foo = 3) {}\n\t\t\t\t}\n\n\t\t\t\tclass Bar {\n\t\t\t\t\tstatic x = class {\n\t\t\t\t\t\tstatic y = () => {\n\t\t\t\t\t\t\tlet bar = 1\n\t\t\t\t\t\t\t@dec(bar)\n\t\t\t\t\t\t\t@dec(() => bar)\n\t\t\t\t\t\t\tclass Baz {\n\t\t\t\t\t\t\t\t@dec(bar) method1() {}\n\t\t\t\t\t\t\t\t@dec(() => bar) method2() {}\n\t\t\t\t\t\t\t\tmethod3(@dec(() => bar) bar) {}\n\t\t\t\t\t\t\t\tmethod4(@dec(() => bar) bar) {}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn Baz\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": false,\n\t\t\t\t\t\"experimentalDecorators\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSExportDefaultTypeIssue316(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport dc_def, { bar as dc } from './keep/declare-class'\n\t\t\t\timport dl_def, { bar as dl } from './keep/declare-let'\n\t\t\t\timport im_def, { bar as im } from './keep/interface-merged'\n\t\t\t\timport in_def, { bar as _in } from './keep/interface-nested'\n\t\t\t\timport tn_def, { bar as tn } from './keep/type-nested'\n\t\t\t\timport vn_def, { bar as vn } from './keep/value-namespace'\n\t\t\t\timport vnm_def, { bar as vnm } from './keep/value-namespace-merged'\n\n\t\t\t\timport i_def, { bar as i } from './remove/interface'\n\t\t\t\timport ie_def, { bar as ie } from './remove/interface-exported'\n\t\t\t\timport t_def, { bar as t } from './remove/type'\n\t\t\t\timport te_def, { bar as te } from './remove/type-exported'\n\t\t\t\timport ton_def, { bar as ton } from './remove/type-only-namespace'\n\t\t\t\timport tone_def, { bar as tone } from './remove/type-only-namespace-exported'\n\n\t\t\t\texport default [\n\t\t\t\t\tdc_def, dc,\n\t\t\t\t\tdl_def, dl,\n\t\t\t\t\tim_def, im,\n\t\t\t\t\tin_def, _in,\n\t\t\t\t\ttn_def, tn,\n\t\t\t\t\tvn_def, vn,\n\t\t\t\t\tvnm_def, vnm,\n\n\t\t\t\t\ti,\n\t\t\t\t\tie,\n\t\t\t\t\tt,\n\t\t\t\t\tte,\n\t\t\t\t\tton,\n\t\t\t\t\ttone,\n\t\t\t\t]\n\t\t\t`,\n\t\t\t\"/keep/declare-class.ts\": `\n\t\t\t\tdeclare class foo {}\n\t\t\t\texport default foo\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t\t\"/keep/declare-let.ts\": `\n\t\t\t\tdeclare let foo: number\n\t\t\t\texport default foo\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t\t\"/keep/interface-merged.ts\": `\n\t\t\t\tclass foo {\n\t\t\t\t\tstatic x = new foo\n\t\t\t\t}\n\t\t\t\tinterface foo {}\n\t\t\t\texport default foo\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t\t\"/keep/interface-nested.ts\": `\n\t\t\t\tif (true) {\n\t\t\t\t\tinterface foo {}\n\t\t\t\t}\n\t\t\t\texport default foo\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t\t\"/keep/type-nested.ts\": `\n\t\t\t\tif (true) {\n\t\t\t\t\ttype foo = number\n\t\t\t\t}\n\t\t\t\texport default foo\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t\t\"/keep/value-namespace.ts\": `\n\t\t\t\tnamespace foo {\n\t\t\t\t\texport let num = 0\n\t\t\t\t}\n\t\t\t\texport default foo\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t\t\"/keep/value-namespace-merged.ts\": `\n\t\t\t\tnamespace foo {\n\t\t\t\t\texport type num = number\n\t\t\t\t}\n\t\t\t\tnamespace foo {\n\t\t\t\t\texport let num = 0\n\t\t\t\t}\n\t\t\t\texport default foo\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t\t\"/remove/interface.ts\": `\n\t\t\t\tinterface foo { }\n\t\t\t\texport default foo\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t\t\"/remove/interface-exported.ts\": `\n\t\t\t\texport interface foo { }\n\t\t\t\texport default foo\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t\t\"/remove/type.ts\": `\n\t\t\t\ttype foo = number\n\t\t\t\texport default foo\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t\t\"/remove/type-exported.ts\": `\n\t\t\t\texport type foo = number\n\t\t\t\texport default foo\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t\t\"/remove/type-only-namespace.ts\": `\n\t\t\t\tnamespace foo {\n\t\t\t\t\texport type num = number\n\t\t\t\t}\n\t\t\t\texport default foo\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t\t\"/remove/type-only-namespace-exported.ts\": `\n\t\t\t\texport namespace foo {\n\t\t\t\t\texport type num = number\n\t\t\t\t}\n\t\t\t\texport default foo\n\t\t\t\texport let bar = 123\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": false\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImplicitExtensions(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport './pick-js.js'\n\t\t\t\timport './pick-ts.js'\n\t\t\t\timport './pick-jsx.jsx'\n\t\t\t\timport './pick-tsx.jsx'\n\t\t\t\timport './order-js.js'\n\t\t\t\timport './order-jsx.jsx'\n\n\t\t\t\timport 'pkg/foo-js.js'\n\t\t\t\timport 'pkg/foo-jsx.jsx'\n\t\t\t\timport 'pkg-exports/xyz-js'\n\t\t\t\timport 'pkg-exports/xyz-jsx'\n\t\t\t\timport 'pkg-exports/foo-js.js'\n\t\t\t\timport 'pkg-exports/foo-jsx.jsx'\n\t\t\t\timport 'pkg-imports'\n\t\t\t`,\n\n\t\t\t\"/pick-js.js\": `console.log(\"correct\")`,\n\t\t\t\"/pick-js.ts\": `console.log(\"wrong\")`,\n\n\t\t\t\"/pick-ts.jsx\": `console.log(\"wrong\")`,\n\t\t\t\"/pick-ts.ts\":  `console.log(\"correct\")`,\n\n\t\t\t\"/pick-jsx.jsx\": `console.log(\"correct\")`,\n\t\t\t\"/pick-jsx.tsx\": `console.log(\"wrong\")`,\n\n\t\t\t\"/pick-tsx.js\":  `console.log(\"wrong\")`,\n\t\t\t\"/pick-tsx.tsx\": `console.log(\"correct\")`,\n\n\t\t\t\"/order-js.ts\":  `console.log(\"correct\")`,\n\t\t\t\"/order-js.tsx\": `console.log(\"wrong\")`,\n\n\t\t\t\"/order-jsx.ts\":  `console.log(\"correct\")`,\n\t\t\t\"/order-jsx.tsx\": `console.log(\"wrong\")`,\n\n\t\t\t\"/node_modules/pkg/foo-js.ts\":   `console.log(\"correct\")`,\n\t\t\t\"/node_modules/pkg/foo-jsx.tsx\": `console.log(\"correct\")`,\n\n\t\t\t\"/node_modules/pkg-exports/package.json\": `{\n\t\t\t\t\"exports\": {\n\t\t\t\t\t\"./xyz-js\": \"./abc-js.js\",\n\t\t\t\t\t\"./xyz-jsx\": \"./abc-jsx.jsx\",\n\t\t\t\t\t\"./*\": \"./lib/*\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/node_modules/pkg-exports/abc-js.ts\":       `console.log(\"correct\")`,\n\t\t\t\"/node_modules/pkg-exports/abc-jsx.tsx\":     `console.log(\"correct\")`,\n\t\t\t\"/node_modules/pkg-exports/lib/foo-js.ts\":   `console.log(\"correct\")`,\n\t\t\t\"/node_modules/pkg-exports/lib/foo-jsx.tsx\": `console.log(\"correct\")`,\n\n\t\t\t\"/node_modules/pkg-imports/package.json\": `{\n\t\t\t\t\"imports\": {\n\t\t\t\t\t\"#xyz-js\": \"./abc-js.js\",\n\t\t\t\t\t\"#xyz-jsx\": \"./abc-jsx.jsx\",\n\t\t\t\t\t\"#bar/*\": \"./lib/*\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/node_modules/pkg-imports/index.js\": `\n\t\t\t\timport \"#xyz-js\"\n\t\t\t\timport \"#xyz-jsx\"\n\t\t\t\timport \"#bar/foo-js.js\"\n\t\t\t\timport \"#bar/foo-jsx.jsx\"\n\t\t\t`,\n\t\t\t\"/node_modules/pkg-imports/abc-js.ts\":       `console.log(\"correct\")`,\n\t\t\t\"/node_modules/pkg-imports/abc-jsx.tsx\":     `console.log(\"correct\")`,\n\t\t\t\"/node_modules/pkg-imports/lib/foo-js.ts\":   `console.log(\"correct\")`,\n\t\t\t\"/node_modules/pkg-imports/lib/foo-jsx.tsx\": `console.log(\"correct\")`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImplicitExtensionsMissing(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport './mjs.mjs'\n\t\t\t\timport './cjs.cjs'\n\t\t\t\timport './js.js'\n\t\t\t\timport './jsx.jsx'\n\t\t\t`,\n\t\t\t\"/mjs.ts\":      ``,\n\t\t\t\"/mjs.tsx\":     ``,\n\t\t\t\"/cjs.ts\":      ``,\n\t\t\t\"/cjs.tsx\":     ``,\n\t\t\t\"/js.ts.js\":    ``,\n\t\t\t\"/jsx.tsx.jsx\": ``,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.ts: ERROR: Could not resolve \"./mjs.mjs\"\nentry.ts: ERROR: Could not resolve \"./cjs.cjs\"\nentry.ts: ERROR: Could not resolve \"./js.js\"\nentry.ts: ERROR: Could not resolve \"./jsx.jsx\"\n`,\n\t})\n}\n\nfunc TestExportTypeIssue379(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport * as A from './a'\n\t\t\t\timport * as B from './b'\n\t\t\t\timport * as C from './c'\n\t\t\t\timport * as D from './d'\n\t\t\t\tconsole.log(A, B, C, D)\n\t\t\t`,\n\t\t\t\"/a.ts\": `\n\t\t\t\ttype Test = Element\n\t\t\t\tlet foo = 123\n\t\t\t\texport { Test, foo }\n\t\t\t`,\n\t\t\t\"/b.ts\": `\n\t\t\t\texport type Test = Element\n\t\t\t\texport let foo = 123\n\t\t\t`,\n\t\t\t\"/c.ts\": `\n\t\t\t\timport { Test } from './test'\n\t\t\t\tlet foo = 123\n\t\t\t\texport { Test }\n\t\t\t\texport { foo }\n\t\t\t`,\n\t\t\t\"/d.ts\": `\n\t\t\t\texport { Test }\n\t\t\t\texport { foo }\n\t\t\t\timport { Test } from './test'\n\t\t\t\tlet foo = 123\n\t\t\t`,\n\t\t\t\"/test.ts\": `\n\t\t\t\texport type Test = Element\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tTS: config.TSOptions{Config: config.TSConfig{\n\t\t\t\tUseDefineForClassFields: config.False,\n\t\t\t}},\n\t\t},\n\t})\n}\n\nfunc TestThisInsideFunctionTS(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tfunction foo(x = this) { console.log(this) }\n\t\t\t\tconst objFoo = {\n\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t}\n\t\t\t\tclass Foo {\n\t\t\t\t\tx = this\n\t\t\t\t\tstatic y = this.z\n\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t\tstatic bar(x = this) { console.log(this) }\n\t\t\t\t}\n\t\t\t\tnew Foo(foo(objFoo))\n\t\t\t\tif (nested) {\n\t\t\t\t\tfunction bar(x = this) { console.log(this) }\n\t\t\t\t\tconst objBar = {\n\t\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t\t}\n\t\t\t\t\tclass Bar {\n\t\t\t\t\t\tx = this\n\t\t\t\t\t\tstatic y = this.z\n\t\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t\t\tstatic bar(x = this) { console.log(this) }\n\t\t\t\t\t}\n\t\t\t\t\tnew Bar(bar(objBar))\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tTS: config.TSOptions{Config: config.TSConfig{\n\t\t\t\tUseDefineForClassFields: config.False,\n\t\t\t}},\n\t\t},\n\t})\n}\n\nfunc TestThisInsideFunctionTSUseDefineForClassFields(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tfunction foo(x = this) { console.log(this) }\n\t\t\t\tconst objFoo = {\n\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t}\n\t\t\t\tclass Foo {\n\t\t\t\t\tx = this\n\t\t\t\t\tstatic y = this.z\n\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t\tstatic bar(x = this) { console.log(this) }\n\t\t\t\t}\n\t\t\t\tnew Foo(foo(objFoo))\n\t\t\t\tif (nested) {\n\t\t\t\t\tfunction bar(x = this) { console.log(this) }\n\t\t\t\t\tconst objBar = {\n\t\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t\t}\n\t\t\t\t\tclass Bar {\n\t\t\t\t\t\tx = this\n\t\t\t\t\t\tstatic y = this.z\n\t\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t\t\tstatic bar(x = this) { console.log(this) }\n\t\t\t\t\t}\n\t\t\t\t\tnew Bar(bar(objBar))\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tTS: config.TSOptions{Config: config.TSConfig{\n\t\t\t\tUseDefineForClassFields: config.True,\n\t\t\t}},\n\t\t},\n\t})\n}\n\nfunc TestThisInsideFunctionTSNoBundle(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tfunction foo(x = this) { console.log(this) }\n\t\t\t\tconst objFoo = {\n\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t}\n\t\t\t\tclass Foo {\n\t\t\t\t\tx = this\n\t\t\t\t\tstatic y = this.z\n\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t\tstatic bar(x = this) { console.log(this) }\n\t\t\t\t}\n\t\t\t\tnew Foo(foo(objFoo))\n\t\t\t\tif (nested) {\n\t\t\t\t\tfunction bar(x = this) { console.log(this) }\n\t\t\t\t\tconst objBar = {\n\t\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t\t}\n\t\t\t\t\tclass Bar {\n\t\t\t\t\t\tx = this\n\t\t\t\t\t\tstatic y = this.z\n\t\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t\t\tstatic bar(x = this) { console.log(this) }\n\t\t\t\t\t}\n\t\t\t\t\tnew Bar(bar(objBar))\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": false\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestThisInsideFunctionTSNoBundleUseDefineForClassFields(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tfunction foo(x = this) { console.log(this) }\n\t\t\t\tconst objFoo = {\n\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t}\n\t\t\t\tclass Foo {\n\t\t\t\t\tx = this\n\t\t\t\t\tstatic y = this.z\n\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t\tstatic bar(x = this) { console.log(this) }\n\t\t\t\t}\n\t\t\t\tnew Foo(foo(objFoo))\n\t\t\t\tif (nested) {\n\t\t\t\t\tfunction bar(x = this) { console.log(this) }\n\t\t\t\t\tconst objBar = {\n\t\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t\t}\n\t\t\t\t\tclass Bar {\n\t\t\t\t\t\tx = this\n\t\t\t\t\t\tstatic y = this.z\n\t\t\t\t\t\tfoo(x = this) { console.log(this) }\n\t\t\t\t\t\tstatic bar(x = this) { console.log(this) }\n\t\t\t\t\t}\n\t\t\t\t\tnew Bar(bar(objBar))\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tTS: config.TSOptions{Config: config.TSConfig{\n\t\t\t\tUseDefineForClassFields: config.True,\n\t\t\t}},\n\t\t},\n\t})\n}\n\nfunc TestTSComputedClassFieldUseDefineFalse(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t[q];\n\t\t\t\t\t[r] = s;\n\t\t\t\t\t@dec\n\t\t\t\t\t[x];\n\t\t\t\t\t@dec\n\t\t\t\t\t[y] = z;\n\t\t\t\t}\n\t\t\t\tnew Foo()\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": false,\n\t\t\t\t\t\"experimentalDecorators\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSComputedClassFieldUseDefineTrue(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t[q];\n\t\t\t\t\t[r] = s;\n\t\t\t\t\t@dec\n\t\t\t\t\t[x];\n\t\t\t\t\t@dec\n\t\t\t\t\t[y] = z;\n\t\t\t\t}\n\t\t\t\tnew Foo()\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": true,\n\t\t\t\t\t\"experimentalDecorators\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSComputedClassFieldUseDefineTrueLower(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t[q];\n\t\t\t\t\t[r] = s;\n\t\t\t\t\t@dec\n\t\t\t\t\t[x];\n\t\t\t\t\t@dec\n\t\t\t\t\t[y] = z;\n\t\t\t\t}\n\t\t\t\tnew Foo()\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": true,\n\t\t\t\t\t\"experimentalDecorators\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModePassThrough,\n\t\t\tAbsOutputFile:         \"/out.js\",\n\t\t\tUnsupportedJSFeatures: compat.ClassField,\n\t\t},\n\t})\n}\n\nfunc TestTSAbstractClassFieldUseAssign(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tconst keepThis = Symbol('keepThis')\n\t\t\t\tdeclare const AND_REMOVE_THIS: unique symbol\n\t\t\t\tabstract class Foo {\n\t\t\t\t\tREMOVE_THIS: any\n\t\t\t\t\t[keepThis]: any\n\t\t\t\t\tabstract REMOVE_THIS_TOO: any\n\t\t\t\t\tabstract [AND_REMOVE_THIS]: any\n\t\t\t\t\tabstract [(x => y => x + y)('nested')('scopes')]: any\n\t\t\t\t}\n\t\t\t\t(() => new Foo())()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tTS: config.TSOptions{Config: config.TSConfig{\n\t\t\t\tUseDefineForClassFields: config.False,\n\t\t\t}},\n\t\t},\n\t})\n}\n\nfunc TestTSAbstractClassFieldUseDefine(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tconst keepThisToo = Symbol('keepThisToo')\n\t\t\t\tdeclare const REMOVE_THIS_TOO: unique symbol\n\t\t\t\tabstract class Foo {\n\t\t\t\t\tkeepThis: any\n\t\t\t\t\t[keepThisToo]: any\n\t\t\t\t\tabstract REMOVE_THIS: any\n\t\t\t\t\tabstract [REMOVE_THIS_TOO]: any\n\t\t\t\t\tabstract [(x => y => x + y)('nested')('scopes')]: any\n\t\t\t\t}\n\t\t\t\t(() => new Foo())()\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tTS: config.TSOptions{Config: config.TSConfig{\n\t\t\t\tUseDefineForClassFields: config.True,\n\t\t\t}},\n\t\t},\n\t})\n}\n\nfunc TestTSImportMTS(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport './imported.mjs'\n\t\t\t`,\n\t\t\t\"/imported.mts\": `\n\t\t\t\tconsole.log('works')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t},\n\t})\n}\n\nfunc TestTSImportCTS(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\trequire('./required.cjs')\n\t\t\t`,\n\t\t\t\"/required.cjs\": `\n\t\t\t\tconsole.log('works')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tOutputFormat:  config.FormatCommonJS,\n\t\t},\n\t})\n}\n\nfunc TestTSSideEffectsFalseWarningTypeDeclarations(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport \"some-js\"\n\t\t\t\timport \"some-ts\"\n\t\t\t\timport \"empty-js\"\n\t\t\t\timport \"empty-ts\"\n\t\t\t\timport \"empty-dts\"\n\t\t\t`,\n\n\t\t\t\"/node_modules/some-js/package.json\": `{ \"main\": \"./foo.js\", \"sideEffects\": false }`,\n\t\t\t\"/node_modules/some-js/foo.js\":       `console.log('foo')`,\n\n\t\t\t\"/node_modules/some-ts/package.json\": `{ \"main\": \"./foo.ts\", \"sideEffects\": false }`,\n\t\t\t\"/node_modules/some-ts/foo.ts\":       `console.log('foo' as string)`,\n\n\t\t\t\"/node_modules/empty-js/package.json\": `{ \"main\": \"./foo.js\", \"sideEffects\": false }`,\n\t\t\t\"/node_modules/empty-js/foo.js\":       ``,\n\n\t\t\t\"/node_modules/empty-ts/package.json\": `{ \"main\": \"./foo.ts\", \"sideEffects\": false }`,\n\t\t\t\"/node_modules/empty-ts/foo.ts\":       `export type Foo = number`,\n\n\t\t\t\"/node_modules/empty-dts/package.json\": `{ \"main\": \"./foo.d.ts\", \"sideEffects\": false }`,\n\t\t\t\"/node_modules/empty-dts/foo.d.ts\":     `export type Foo = number`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.ts: WARNING: Ignoring this import because \"node_modules/some-js/foo.js\" was marked as having no side effects\nnode_modules/some-js/package.json: NOTE: \"sideEffects\" is false in the enclosing \"package.json\" file:\nentry.ts: WARNING: Ignoring this import because \"node_modules/some-ts/foo.ts\" was marked as having no side effects\nnode_modules/some-ts/package.json: NOTE: \"sideEffects\" is false in the enclosing \"package.json\" file:\n`,\n\t})\n}\n\nfunc TestTSSiblingNamespace(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/let.ts\": `\n\t\t\t\texport namespace x { export let y = 123 }\n\t\t\t\texport namespace x { export let z = y }\n\t\t\t`,\n\t\t\t\"/function.ts\": `\n\t\t\t\texport namespace x { export function y() {} }\n\t\t\t\texport namespace x { export let z = y }\n\t\t\t`,\n\t\t\t\"/class.ts\": `\n\t\t\t\texport namespace x { export class y {} }\n\t\t\t\texport namespace x { export let z = y }\n\t\t\t`,\n\t\t\t\"/namespace.ts\": `\n\t\t\t\texport namespace x { export namespace y { 0 } }\n\t\t\t\texport namespace x { export let z = y }\n\t\t\t`,\n\t\t\t\"/enum.ts\": `\n\t\t\t\texport namespace x { export enum y {} }\n\t\t\t\texport namespace x { export let z = y }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/let.ts\",\n\t\t\t\"/function.ts\",\n\t\t\t\"/class.ts\",\n\t\t\t\"/namespace.ts\",\n\t\t\t\"/enum.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTSSiblingEnum(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/number.ts\": `\n\t\t\t\texport enum x { y, yy = y }\n\t\t\t\texport enum x { z = y + 1 }\n\n\t\t\t\tdeclare let y: any, z: any\n\t\t\t\texport namespace x { console.log(y, z) }\n\t\t\t\tconsole.log(x.y, x.z)\n\t\t\t`,\n\t\t\t\"/string.ts\": `\n\t\t\t\texport enum x { y = 'a', yy = y }\n\t\t\t\texport enum x { z = y }\n\n\t\t\t\tdeclare let y: any, z: any\n\t\t\t\texport namespace x { console.log(y, z) }\n\t\t\t\tconsole.log(x.y, x.z)\n\t\t\t`,\n\t\t\t\"/propagation.ts\": `\n\t\t\t\texport enum a { b = 100 }\n\t\t\t\texport enum x {\n\t\t\t\t\tc = a.b,\n\t\t\t\t\td = c * 2,\n\t\t\t\t\te = x.d ** 2,\n\t\t\t\t\tf = x['e'] / 4,\n\t\t\t\t}\n\t\t\t\texport enum x { g = f >> 4 }\n\t\t\t\tconsole.log(a.b, a['b'], x.g, x['g'])\n\t\t\t`,\n\t\t\t\"/nested-number.ts\": `\n\t\t\t\texport namespace foo { export enum x { y, yy = y } }\n\t\t\t\texport namespace foo { export enum x { z = y + 1 } }\n\n\t\t\t\tdeclare let y: any, z: any\n\t\t\t\texport namespace foo.x {\n\t\t\t\t\tconsole.log(y, z)\n\t\t\t\t\tconsole.log(x.y, x.z)\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/nested-string.ts\": `\n\t\t\t\texport namespace foo { export enum x { y = 'a', yy = y } }\n\t\t\t\texport namespace foo { export enum x { z = y } }\n\n\t\t\t\tdeclare let y: any, z: any\n\t\t\t\texport namespace foo.x {\n\t\t\t\t\tconsole.log(y, z)\n\t\t\t\t\tconsole.log(x.y, x.z)\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/nested-propagation.ts\": `\n\t\t\t\texport namespace n { export enum a { b = 100 } }\n\t\t\t\texport namespace n {\n\t\t\t\t\texport enum x {\n\t\t\t\t\t\tc = n.a.b,\n\t\t\t\t\t\td = c * 2,\n\t\t\t\t\t\te = x.d ** 2,\n\t\t\t\t\t\tf = x['e'] / 4,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\texport namespace n {\n\t\t\t\t\texport enum x { g = f >> 4 }\n\t\t\t\t\tconsole.log(a.b, n.a.b, n['a']['b'], x.g, n.x.g, n['x']['g'])\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/number.ts\",\n\t\t\t\"/string.ts\",\n\t\t\t\"/propagation.ts\",\n\t\t\t\"/nested-number.ts\",\n\t\t\t\"/nested-string.ts\",\n\t\t\t\"/nested-propagation.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTSEnumTreeShaking(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/simple-member.ts\": `\n\t\t\t\tenum x { y = 123 }\n\t\t\t\tconsole.log(x.y)\n\t\t\t`,\n\t\t\t\"/simple-enum.ts\": `\n\t\t\t\tenum x { y = 123 }\n\t\t\t\tconsole.log(x)\n\t\t\t`,\n\t\t\t\"/sibling-member.ts\": `\n\t\t\t\tenum x { y = 123 }\n\t\t\t\tenum x { z = y * 2 }\n\t\t\t\tconsole.log(x.y, x.z)\n\t\t\t`,\n\t\t\t\"/sibling-enum-before.ts\": `\n\t\t\t\tconsole.log(x)\n\t\t\t\tenum x { y = 123 }\n\t\t\t\tenum x { z = y * 2 }\n\t\t\t`,\n\t\t\t\"/sibling-enum-middle.ts\": `\n\t\t\t\tenum x { y = 123 }\n\t\t\t\tconsole.log(x)\n\t\t\t\tenum x { z = y * 2 }\n\t\t\t`,\n\t\t\t\"/sibling-enum-after.ts\": `\n\t\t\t\tenum x { y = 123 }\n\t\t\t\tenum x { z = y * 2 }\n\t\t\t\tconsole.log(x)\n\t\t\t`,\n\t\t\t\"/namespace-before.ts\": `\n\t\t\t\tnamespace x { console.log(x, y) }\n\t\t\t\tenum x { y = 123 }\n\t\t\t`,\n\t\t\t\"/namespace-after.ts\": `\n\t\t\t\tenum x { y = 123 }\n\t\t\t\tnamespace x { console.log(x, y) }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/simple-member.ts\",\n\t\t\t\"/simple-enum.ts\",\n\t\t\t\"/sibling-member.ts\",\n\t\t\t\"/sibling-enum-before.ts\",\n\t\t\t\"/sibling-enum-middle.ts\",\n\t\t\t\"/sibling-enum-after.ts\",\n\t\t\t\"/namespace-before.ts\",\n\t\t\t\"/namespace-after.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t},\n\t})\n}\n\nfunc TestTSEnumJSX(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/element.tsx\": `\n\t\t\t\texport enum Foo { Div = 'div' }\n\t\t\t\tconsole.log(<Foo.Div />)\n\t\t\t`,\n\t\t\t\"/fragment.tsx\": `\n\t\t\t\texport enum React { Fragment = 'div' }\n\t\t\t\tconsole.log(<>test</>)\n\t\t\t`,\n\t\t\t\"/nested-element.tsx\": `\n\t\t\t\tnamespace x.y { export enum Foo { Div = 'div' } }\n\t\t\t\tnamespace x.y { console.log(<x.y.Foo.Div />) }\n\t\t\t`,\n\t\t\t\"/nested-fragment.tsx\": `\n\t\t\t\tnamespace x.y { export enum React { Fragment = 'div' } }\n\t\t\t\tnamespace x.y { console.log(<>test</>) }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/element.tsx\",\n\t\t\t\"/fragment.tsx\",\n\t\t\t\"/nested-element.tsx\",\n\t\t\t\"/nested-fragment.tsx\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTSEnumDefine(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tenum a { b = 123, c = d }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t\tDefines: &config.ProcessedDefines{\n\t\t\t\tIdentifierDefines: map[string]config.DefineData{\n\t\t\t\t\t\"d\": {\n\t\t\t\t\t\tDefineExpr: &config.DefineExpr{\n\t\t\t\t\t\t\tParts: []string{\"b\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestTSEnumSameModuleInliningAccess(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tenum a_num { x = 123 }\n\t\t\t\tenum b_num { x = 123 }\n\t\t\t\tenum c_num { x = 123 }\n\t\t\t\tenum d_num { x = 123 }\n\t\t\t\tenum e_num { x = 123 }\n\n\t\t\t\tenum a_str { x = 'abc' }\n\t\t\t\tenum b_str { x = 'abc' }\n\t\t\t\tenum c_str { x = 'abc' }\n\t\t\t\tenum d_str { x = 'abc' }\n\t\t\t\tenum e_str { x = 'abc' }\n\n\t\t\t\tinlined = [\n\t\t\t\t\ta_num.x,\n\t\t\t\t\tb_num['x'],\n\n\t\t\t\t\ta_str.x,\n\t\t\t\t\tb_str['x'],\n\t\t\t\t]\n\n\t\t\t\tnot_inlined = [\n\t\t\t\t\tc_num?.x,\n\t\t\t\t\td_num?.['x'],\n\t\t\t\t\te_num,\n\n\t\t\t\t\tc_str?.x,\n\t\t\t\t\td_str?.['x'],\n\t\t\t\t\te_str,\n\t\t\t\t]\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTSEnumCrossModuleInliningAccess(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport {\n\t\t\t\t\ta_num, b_num, c_num, d_num, e_num,\n\t\t\t\t\ta_str, b_str, c_str, d_str, e_str,\n\t\t\t\t} from './enums'\n\n\t\t\t\tinlined = [\n\t\t\t\t\ta_num.x,\n\t\t\t\t\tb_num['x'],\n\n\t\t\t\t\ta_str.x,\n\t\t\t\t\tb_str['x'],\n\t\t\t\t]\n\n\t\t\t\tnot_inlined = [\n\t\t\t\t\tc_num?.x,\n\t\t\t\t\td_num?.['x'],\n\t\t\t\t\te_num,\n\n\t\t\t\t\tc_str?.x,\n\t\t\t\t\td_str?.['x'],\n\t\t\t\t\te_str,\n\t\t\t\t]\n\t\t\t`,\n\t\t\t\"/enums.ts\": `\n\t\t\t\texport enum a_num { x = 123 }\n\t\t\t\texport enum b_num { x = 123 }\n\t\t\t\texport enum c_num { x = 123 }\n\t\t\t\texport enum d_num { x = 123 }\n\t\t\t\texport enum e_num { x = 123 }\n\n\t\t\t\texport enum a_str { x = 'abc' }\n\t\t\t\texport enum b_str { x = 'abc' }\n\t\t\t\texport enum c_str { x = 'abc' }\n\t\t\t\texport enum d_str { x = 'abc' }\n\t\t\t\texport enum e_str { x = 'abc' }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTSEnumCrossModuleInliningDefinitions(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport { a } from './enums'\n\t\t\t\tconsole.log([\n\t\t\t\t\ta.implicit_number,\n\t\t\t\t\ta.explicit_number,\n\t\t\t\t\ta.explicit_string,\n\t\t\t\t\ta.non_constant,\n\t\t\t\t])\n\t\t\t`,\n\t\t\t\"/enums.ts\": `\n\t\t\t\texport enum a {\n\t\t\t\t\timplicit_number,\n\t\t\t\t\texplicit_number = 123,\n\t\t\t\t\texplicit_string = 'xyz',\n\t\t\t\t\tnon_constant = foo,\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTSEnumCrossModuleInliningReExport(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\timport { a } from './re-export'\n\t\t\t\timport { b } from './re-export-star'\n\t\t\t\timport * as ns from './enums'\n\t\t\t\tconsole.log([\n\t\t\t\t\ta.x,\n\t\t\t\t\tb.x,\n\t\t\t\t\tns.c.x,\n\t\t\t\t])\n\t\t\t`,\n\t\t\t\"/re-export.js\": `\n\t\t\t\texport { a } from './enums'\n\t\t\t`,\n\t\t\t\"/re-export-star.js\": `\n\t\t\t\texport * from './enums'\n\t\t\t`,\n\t\t\t\"/enums.ts\": `\n\t\t\t\texport enum a { x = 'a' }\n\t\t\t\texport enum b { x = 'b' }\n\t\t\t\texport enum c { x = 'c' }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTSEnumCrossModuleInliningMinifyIndexIntoDot(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tconst enum Foo {\n\t\t\t\t\tfoo1 = 'abc',\n\t\t\t\t\tfoo2 = 'a b c',\n\t\t\t\t}\n\t\t\t\timport { Bar } from './lib'\n\t\t\t\tinlined = [\n\t\t\t\t\tobj[Foo.foo1],\n\t\t\t\t\tobj[Bar.bar1],\n\t\t\t\t\tobj?.[Foo.foo1],\n\t\t\t\t\tobj?.[Bar.bar1],\n\t\t\t\t\tobj?.prop[Foo.foo1],\n\t\t\t\t\tobj?.prop[Bar.bar1],\n\t\t\t\t]\n\t\t\t\tnotInlined = [\n\t\t\t\t\tobj[Foo.foo2],\n\t\t\t\t\tobj[Bar.bar2],\n\t\t\t\t\tobj?.[Foo.foo2],\n\t\t\t\t\tobj?.[Bar.bar2],\n\t\t\t\t\tobj?.prop[Foo.foo2],\n\t\t\t\t\tobj?.prop[Bar.bar2],\n\t\t\t\t]\n\t\t\t`,\n\t\t\t\"/lib.ts\": `\n\t\t\t\texport const enum Bar {\n\t\t\t\t\tbar1 = 'xyz',\n\t\t\t\t\tbar2 = 'x y z',\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMinifySyntax:  true,\n\t\t},\n\t})\n}\n\nfunc TestTSEnumCrossModuleTreeShaking(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport {\n\t\t\t\t\ta_DROP,\n\t\t\t\t\tb_DROP,\n\t\t\t\t\tc_DROP,\n\t\t\t\t} from './enums'\n\n\t\t\t\tconsole.log([\n\t\t\t\t\ta_DROP.x,\n\t\t\t\t\tb_DROP['x'],\n\t\t\t\t\tc_DROP.x,\n\t\t\t\t])\n\n\t\t\t\timport {\n\t\t\t\t\ta_keep,\n\t\t\t\t\tb_keep,\n\t\t\t\t\tc_keep,\n\t\t\t\t\td_keep,\n\t\t\t\t\te_keep,\n\t\t\t\t} from './enums'\n\n\t\t\t\tconsole.log([\n\t\t\t\t\ta_keep.x,\n\t\t\t\t\tb_keep.x,\n\t\t\t\t\tc_keep,\n\t\t\t\t\td_keep.y,\n\t\t\t\t\te_keep.x,\n\t\t\t\t])\n\t\t\t`,\n\t\t\t\"/enums.ts\": `\n\t\t\t\texport enum a_DROP { x = 1 }  // test a dot access\n\t\t\t\texport enum b_DROP { x = 2 }  // test an index access\n\t\t\t\texport enum c_DROP { x = '' } // test a string enum\n\n\t\t\t\texport enum a_keep { x = false } // false is not inlinable\n\t\t\t\texport enum b_keep { x = foo }   // foo has side effects\n\t\t\t\texport enum c_keep { x = 3 }     // this enum object is captured\n\t\t\t\texport enum d_keep { x = 4 }     // we access \"y\" on this object\n\t\t\t\texport let e_keep = {}           // non-enum properties should be kept\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTSEnumExportClause(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport {\n\t\t\t\t\tA,\n\t\t\t\t\tB,\n\t\t\t\t\tC as c,\n\t\t\t\t\td as dd,\n\t\t\t\t} from './enums'\n\n\t\t\t\tconsole.log([\n\t\t\t\t\tA.A,\n\t\t\t\t\tB.B,\n\t\t\t\t\tc.C,\n\t\t\t\t\tdd.D,\n\t\t\t\t])\n\t\t\t`,\n\t\t\t\"/enums.ts\": `\n\t\t\t\t\texport enum A { A = 1 }\n\t\t\t\t\tenum B { B = 2 }\n\t\t\t\t\texport enum C { C = 3 }\n\t\t\t\t\tenum D { D = 4 }\n\t\t\t\t\texport { B, D as d }\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\n// This checks that we don't generate a warning for code that the TypeScript\n// compiler generates that looks like this:\n//\n//\tvar __rest = (this && this.__rest) || function (s, e) {\n//\t  ...\n//\t};\nfunc TestTSThisIsUndefinedWarning(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/warning1.ts\": `export var foo = this`,\n\t\t\t\"/warning2.ts\": `export var foo = this || this.foo`,\n\t\t\t\"/warning3.ts\": `export var foo = this ? this.foo : null`,\n\n\t\t\t\"/silent1.ts\": `export var foo = this && this.foo`,\n\t\t\t\"/silent2.ts\": `export var foo = this && (() => this.foo)`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/warning1.ts\",\n\t\t\t\"/warning2.ts\",\n\t\t\t\"/warning3.ts\",\n\n\t\t\t\"/silent1.ts\",\n\t\t\t\"/silent2.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t\tdebugLogs: true,\n\t\texpectedScanLog: `warning1.ts: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nwarning1.ts: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nwarning2.ts: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nwarning2.ts: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\nwarning3.ts: DEBUG: Top-level \"this\" will be replaced with undefined since this file is an ECMAScript module\nwarning3.ts: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n`,\n\t})\n}\n\nfunc TestTSCommonJSVariableInESMTypeModule(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\":     `module.exports = null`,\n\t\t\t\"/package.json\": `{ \"type\": \"module\" }`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `entry.ts: WARNING: The CommonJS \"module\" variable is treated as a global variable in an ECMAScript module and may not work as expected\npackage.json: NOTE: This file is considered to be an ECMAScript module because the enclosing \"package.json\" file sets the type of this file to \"module\":\nNOTE: Node's package format requires that CommonJS files in a \"type\": \"module\" package use the \".cjs\" file extension. If you are using TypeScript, you can use the \".cts\" file extension with esbuild instead.\n`,\n\t})\n}\n\nfunc TestEnumRulesFrom_TypeScript_5_0(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/supported.ts\": `\n\t\t\t\t// From https://github.com/microsoft/TypeScript/pull/50528:\n\t\t\t\t// \"An expression is considered a constant expression if it is\n\t\t\t\tconst enum Foo {\n\t\t\t\t\t// a number or string literal,\n\t\t\t\t\tX0 = 123,\n\t\t\t\t\tX1 = 'x',\n\n\t\t\t\t\t// a unary +, -, or ~ applied to a numeric constant expression,\n\t\t\t\t\tX2 = +1,\n\t\t\t\t\tX3 = -2,\n\t\t\t\t\tX4 = ~3,\n\n\t\t\t\t\t// a binary +, -, *, /, %, **, <<, >>, >>>, |, &, ^ applied to two numeric constant expressions,\n\t\t\t\t\tX5 = 1 + 2,\n\t\t\t\t\tX6 = 1 - 2,\n\t\t\t\t\tX7 = 2 * 3,\n\t\t\t\t\tX8 = 1 / 2,\n\t\t\t\t\tX9 = 3 % 2,\n\t\t\t\t\tX10 = 2 ** 3,\n\t\t\t\t\tX11 = 1 << 2,\n\t\t\t\t\tX12 = -9 >> 1,\n\t\t\t\t\tX13 = -9 >>> 1,\n\t\t\t\t\tX14 = 5 | 12,\n\t\t\t\t\tX15 = 5 & 12,\n\t\t\t\t\tX16 = 5 ^ 12,\n\n\t\t\t\t\t// a binary + applied to two constant expressions whereof at least one is a string,\n\t\t\t\t\tX17 = 'x' + 0,\n\t\t\t\t\tX18 = 0 + 'x',\n\t\t\t\t\tX19 = 'x' + 'y',\n\t\t\t\t\tX20 = '' + NaN,\n\t\t\t\t\tX21 = '' + Infinity,\n\t\t\t\t\tX22 = '' + -Infinity,\n\t\t\t\t\tX23 = '' + -0,\n\n\t\t\t\t\t// a template expression where each substitution expression is a constant expression,\n\t\t\t\t\tX24 = ` + \"`A${0}B${'x'}C${1 + 3 - 4 / 2 * 5 ** 6}D`\" + `,\n\n\t\t\t\t\t// a parenthesized constant expression,\n\t\t\t\t\tX25 = (321),\n\n\t\t\t\t\t// a dotted name (e.g. x.y.z) that references a const variable with a constant expression initializer and no type annotation,\n\t\t\t\t\t/* (we don't implement this one) */\n\n\t\t\t\t\t// a dotted name that references an enum member with an enum literal type, or\n\t\t\t\t\tX26 = X0,\n\t\t\t\t\tX27 = X0 + 'x',\n\t\t\t\t\tX28 = 'x' + X0,\n\t\t\t\t\tX29 = ` + \"`a${X0}b`\" + `,\n\t\t\t\t\tX30 = Foo.X0,\n\t\t\t\t\tX31 = Foo.X0 + 'x',\n\t\t\t\t\tX32 = 'x' + Foo.X0,\n\t\t\t\t\tX33 = ` + \"`a${Foo.X0}b`\" + `,\n\n\t\t\t\t\t// a dotted name indexed by a string literal (e.g. x.y[\"z\"]) that references an enum member with an enum literal type.\"\n\t\t\t\t\tX34 = X1,\n\t\t\t\t\tX35 = X1 + 'y',\n\t\t\t\t\tX36 = 'y' + X1,\n\t\t\t\t\tX37 = ` + \"`a${X1}b`\" + `,\n\t\t\t\t\tX38 = Foo['X1'],\n\t\t\t\t\tX39 = Foo['X1'] + 'y',\n\t\t\t\t\tX40 = 'y' + Foo['X1'],\n\t\t\t\t\tX41 = ` + \"`a${Foo['X1']}b`\" + `,\n\t\t\t\t}\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t// a number or string literal,\n\t\t\t\t\tFoo.X0,\n\t\t\t\t\tFoo.X1,\n\n\t\t\t\t\t// a unary +, -, or ~ applied to a numeric constant expression,\n\t\t\t\t\tFoo.X2,\n\t\t\t\t\tFoo.X3,\n\t\t\t\t\tFoo.X4,\n\n\t\t\t\t\t// a binary +, -, *, /, %, **, <<, >>, >>>, |, &, ^ applied to two numeric constant expressions,\n\t\t\t\t\tFoo.X5,\n\t\t\t\t\tFoo.X6,\n\t\t\t\t\tFoo.X7,\n\t\t\t\t\tFoo.X8,\n\t\t\t\t\tFoo.X9,\n\t\t\t\t\tFoo.X10,\n\t\t\t\t\tFoo.X11,\n\t\t\t\t\tFoo.X12,\n\t\t\t\t\tFoo.X13,\n\t\t\t\t\tFoo.X14,\n\t\t\t\t\tFoo.X15,\n\t\t\t\t\tFoo.X16,\n\n\t\t\t\t\t// a template expression where each substitution expression is a constant expression,\n\t\t\t\t\tFoo.X17,\n\t\t\t\t\tFoo.X18,\n\t\t\t\t\tFoo.X19,\n\t\t\t\t\tFoo.X20,\n\t\t\t\t\tFoo.X21,\n\t\t\t\t\tFoo.X22,\n\t\t\t\t\tFoo.X23,\n\n\t\t\t\t\t// a template expression where each substitution expression is a constant expression,\n\t\t\t\t\tFoo.X24,\n\n\t\t\t\t\t// a parenthesized constant expression,\n\t\t\t\t\tFoo.X25,\n\n\t\t\t\t\t// a dotted name that references an enum member with an enum literal type, or\n\t\t\t\t\tFoo.X26,\n\t\t\t\t\tFoo.X27,\n\t\t\t\t\tFoo.X28,\n\t\t\t\t\tFoo.X29,\n\t\t\t\t\tFoo.X30,\n\t\t\t\t\tFoo.X31,\n\t\t\t\t\tFoo.X32,\n\t\t\t\t\tFoo.X33,\n\n\t\t\t\t\t// a dotted name indexed by a string literal (e.g. x.y[\"z\"]) that references an enum member with an enum literal type.\"\n\t\t\t\t\tFoo.X34,\n\t\t\t\t\tFoo.X35,\n\t\t\t\t\tFoo.X36,\n\t\t\t\t\tFoo.X37,\n\t\t\t\t\tFoo.X38,\n\t\t\t\t\tFoo.X39,\n\t\t\t\t\tFoo.X40,\n\t\t\t\t\tFoo.X41,\n\t\t\t\t)\n\t\t\t`,\n\t\t\t\"/not-supported.ts\": `\n\t\t\t\tconst enum NonIntegerNumberToString {\n\t\t\t\t\tSUPPORTED = '' + 1,\n\t\t\t\t\tUNSUPPORTED = '' + 1.5,\n\t\t\t\t}\n\t\t\t\tconsole.log(\n\t\t\t\t\tNonIntegerNumberToString.SUPPORTED,\n\t\t\t\t\tNonIntegerNumberToString.UNSUPPORTED,\n\t\t\t\t)\n\n\t\t\t\tconst enum OutOfBoundsNumberToString {\n\t\t\t\t\tSUPPORTED = '' + 1_000_000_000,\n\t\t\t\t\tUNSUPPORTED = '' + 1_000_000_000_000,\n\t\t\t\t}\n\t\t\t\tconsole.log(\n\t\t\t\t\tOutOfBoundsNumberToString.SUPPORTED,\n\t\t\t\t\tOutOfBoundsNumberToString.UNSUPPORTED,\n\t\t\t\t)\n\n\t\t\t\tconst enum TemplateExpressions {\n\t\t\t\t\t// TypeScript enums don't handle any of these\n\t\t\t\t\tNULL = '' + null,\n\t\t\t\t\tTRUE = '' + true,\n\t\t\t\t\tFALSE = '' + false,\n\t\t\t\t\tBIGINT = '' + 123n,\n\t\t\t\t}\n\t\t\t\tconsole.log(\n\t\t\t\t\tTemplateExpressions.NULL,\n\t\t\t\t\tTemplateExpressions.TRUE,\n\t\t\t\t\tTemplateExpressions.FALSE,\n\t\t\t\t\tTemplateExpressions.BIGINT,\n\t\t\t\t)\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/supported.ts\",\n\t\t\t\"/not-supported.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTSEnumUseBeforeDeclare(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\texport function before() {\n\t\t\t\t\tconsole.log(Foo.FOO)\n\t\t\t\t}\n\t\t\t\tenum Foo { FOO }\n\t\t\t\texport function after() {\n\t\t\t\t\tconsole.log(Foo.FOO)\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTSPreferJSOverTSInsideNodeModules(t *testing.T) {\n\t// We now prefer \".js\" over \".ts\" inside \"node_modules\"\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/main.ts\": `\n\t\t\t\t// Implicit extensions\n\t\t\t\timport './relative/path'\n\t\t\t\timport 'package/path'\n\n\t\t\t\t// Explicit extensions\n\t\t\t\timport './relative2/path.js'\n\t\t\t\timport 'package2/path.js'\n\t\t\t`,\n\n\t\t\t\"/Users/user/project/src/relative/path.ts\": `console.log('success')`,\n\t\t\t\"/Users/user/project/src/relative/path.js\": `console.log('FAILURE')`,\n\n\t\t\t\"/Users/user/project/src/relative2/path.ts\": `console.log('FAILURE')`,\n\t\t\t\"/Users/user/project/src/relative2/path.js\": `console.log('success')`,\n\n\t\t\t\"/Users/user/project/node_modules/package/path.ts\": `console.log('FAILURE')`,\n\t\t\t\"/Users/user/project/node_modules/package/path.js\": `console.log('success')`,\n\n\t\t\t\"/Users/user/project/node_modules/package2/path.ts\": `console.log('FAILURE')`,\n\t\t\t\"/Users/user/project/node_modules/package2/path.js\": `console.log('success')`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/main.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/out\",\n\t\t},\n\t})\n}\n\nfunc TestTSExperimentalDecoratorsManglePropsDefineSemantics(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t@dec(1) prop1 = null\n\t\t\t\t\t@dec(2) prop2_ = null\n\t\t\t\t\t@dec(3) ['prop3'] = null\n\t\t\t\t\t@dec(4) ['prop4_'] = null\n\t\t\t\t\t@dec(5) [/* @__KEY__ */ 'prop5'] = null\n\t\t\t\t\t@dec(6) [/* @__KEY__ */ 'prop6_'] = null\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true,\n          \"useDefineForClassFields\": true,\n        },\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMangleProps:   regexp.MustCompile(\"_$\"),\n\t\t},\n\t})\n}\n\nfunc TestTSExperimentalDecoratorsManglePropsAssignSemantics(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t@dec(1) prop1 = null\n\t\t\t\t\t@dec(2) prop2_ = null\n\t\t\t\t\t@dec(3) ['prop3'] = null\n\t\t\t\t\t@dec(4) ['prop4_'] = null\n\t\t\t\t\t@dec(5) [/* @__KEY__ */ 'prop5'] = null\n\t\t\t\t\t@dec(6) [/* @__KEY__ */ 'prop6_'] = null\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true,\n          \"useDefineForClassFields\": false,\n        },\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMangleProps:   regexp.MustCompile(\"_$\"),\n\t\t},\n\t})\n}\n\nfunc TestTSExperimentalDecoratorsManglePropsMethods(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t@dec(1) prop1() {}\n\t\t\t\t\t@dec(2) prop2_() {}\n\t\t\t\t\t@dec(3) ['prop3']() {}\n\t\t\t\t\t@dec(4) ['prop4_']() {}\n\t\t\t\t\t@dec(5) [/* @__KEY__ */ 'prop5']() {}\n\t\t\t\t\t@dec(6) [/* @__KEY__ */ 'prop6_']() {}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true,\n        },\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMangleProps:   regexp.MustCompile(\"_$\"),\n\t\t},\n\t})\n}\n\nfunc TestTSExperimentalDecoratorsManglePropsStaticDefineSemantics(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t@dec(1) static prop1 = null\n\t\t\t\t\t@dec(2) static prop2_ = null\n\t\t\t\t\t@dec(3) static ['prop3'] = null\n\t\t\t\t\t@dec(4) static ['prop4_'] = null\n\t\t\t\t\t@dec(5) static [/* @__KEY__ */ 'prop5'] = null\n\t\t\t\t\t@dec(6) static [/* @__KEY__ */ 'prop6_'] = null\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true,\n          \"useDefineForClassFields\": true,\n        },\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMangleProps:   regexp.MustCompile(\"_$\"),\n\t\t},\n\t})\n}\n\nfunc TestTSExperimentalDecoratorsManglePropsStaticAssignSemantics(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t@dec(1) static prop1 = null\n\t\t\t\t\t@dec(2) static prop2_ = null\n\t\t\t\t\t@dec(3) static ['prop3'] = null\n\t\t\t\t\t@dec(4) static ['prop4_'] = null\n\t\t\t\t\t@dec(5) static [/* @__KEY__ */ 'prop5'] = null\n\t\t\t\t\t@dec(6) static [/* @__KEY__ */ 'prop6_'] = null\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true,\n          \"useDefineForClassFields\": false,\n        },\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMangleProps:   regexp.MustCompile(\"_$\"),\n\t\t},\n\t})\n}\n\nfunc TestTSExperimentalDecoratorsManglePropsStaticMethods(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\tclass Foo {\n\t\t\t\t\t@dec(1) static prop1() {}\n\t\t\t\t\t@dec(2) static prop2_() {}\n\t\t\t\t\t@dec(3) static ['prop3']() {}\n\t\t\t\t\t@dec(4) static ['prop4_']() {}\n\t\t\t\t\t@dec(5) static [/* @__KEY__ */ 'prop5']() {}\n\t\t\t\t\t@dec(6) static [/* @__KEY__ */ 'prop6_']() {}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true,\n        },\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tMangleProps:   regexp.MustCompile(\"_$\"),\n\t\t},\n\t})\n}\n\nfunc TestTSPrintNonFiniteNumberInsideWith(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\t// Use const enums to force inline values\n\t\t\t\tconst enum Foo {\n\t\t\t\t\tNAN = 0 / 0,\n\t\t\t\t\tPOS_INF = 1 / 0,\n\t\t\t\t\tNEG_INF = -1 / 0,\n\t\t\t\t}\n\n\t\t\t\t//! It's ok to use \"NaN\" and \"Infinity\" here\n\t\t\t\tconsole.log(\n\t\t\t\t\tFoo.NAN,\n\t\t\t\t\tFoo.POS_INF,\n\t\t\t\t\tFoo.NEG_INF,\n\t\t\t\t)\n\t\t\t\tcheckPrecedence(\n\t\t\t\t\t1 / Foo.NAN,\n\t\t\t\t\t1 / Foo.POS_INF,\n\t\t\t\t\t1 / Foo.NEG_INF,\n\t\t\t\t)\n\n\t\t\t\t//! We must not use \"NaN\" or \"Infinity\" inside \"with\"\n\t\t\t\twith (x) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\tFoo.NAN,\n\t\t\t\t\t\tFoo.POS_INF,\n\t\t\t\t\t\tFoo.NEG_INF,\n\t\t\t\t\t)\n\t\t\t\t\tcheckPrecedence(\n\t\t\t\t\t\t1 / Foo.NAN,\n\t\t\t\t\t\t1 / Foo.POS_INF,\n\t\t\t\t\t\t1 / Foo.NEG_INF,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTSImportInNodeModulesNameCollisionWithCSS(t *testing.T) {\n\tts_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": `\n\t\t\t\timport \"pkg\"\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/index.ts\": `\n\t\t\t\timport js_ts_css from \"./js_ts_css\"\n\t\t\t\timport ts_css from \"./ts_css\"\n\t\t\t\timport js_ts from \"./js_ts\"\n\t\t\t\tjs_ts_css()\n\t\t\t\tts_css()\n\t\t\t\tjs_ts()\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/js_ts_css.js\": `\n\t\t\t\timport './js_ts_css.css'\n\t\t\t\texport default function() {}\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/js_ts_css.ts\": `\n\t\t\t\tTEST FAILED\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/js_ts_css.css\": `\n\t\t\t\t.js_ts_css {}\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/ts_css.ts\": `\n\t\t\t\timport './ts_css.css'\n\t\t\t\texport default function() {}\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/ts_css.css\": `\n\t\t\t\t.ts_css {}\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/js_ts.js\": `\n\t\t\t\texport default function() {}\n\t\t\t`,\n\t\t\t\"/node_modules/pkg/js_ts.ts\": `\n\t\t\t\tTEST FAILED\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "internal/bundler_tests/bundler_tsconfig_test.go",
    "content": "package bundler_tests\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/config\"\n)\n\nvar tsconfig_suite = suite{\n\tname: \"tsconfig\",\n}\n\nfunc TestTsconfigPaths(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.ts\": `\n\t\t\t\timport baseurl_dot from './baseurl_dot'\n\t\t\t\timport baseurl_nested from './baseurl_nested'\n\t\t\t\tconsole.log(baseurl_dot, baseurl_nested)\n\t\t\t`,\n\n\t\t\t// Tests with \"baseUrl\": \".\"\n\t\t\t\"/Users/user/project/baseurl_dot/index.ts\": `\n\t\t\t\timport test0 from 'test0'\n\t\t\t\timport test1 from 'test1/foo'\n\t\t\t\timport test2 from 'test2/foo'\n\t\t\t\timport test3 from 'test3/foo'\n\t\t\t\timport test4 from 'test4/foo'\n\t\t\t\timport test5 from 'test5/foo'\n\t\t\t\timport absoluteIn from './absolute-in'\n\t\t\t\timport absoluteInStar from './absolute-in-star'\n\t\t\t\timport absoluteOut from './absolute-out'\n\t\t\t\timport absoluteOutStar from './absolute-out-star'\n\t\t\t\texport default {\n\t\t\t\t\ttest0,\n\t\t\t\t\ttest1,\n\t\t\t\t\ttest2,\n\t\t\t\t\ttest3,\n\t\t\t\t\ttest4,\n\t\t\t\t\ttest5,\n\t\t\t\t\tabsoluteIn,\n\t\t\t\t\tabsoluteInStar,\n\t\t\t\t\tabsoluteOut,\n\t\t\t\t\tabsoluteOutStar,\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_dot/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \".\",\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"test0\": [\"./test0-success.ts\"],\n\t\t\t\t\t\t\t\"test1/*\": [\"./test1-success.ts\"],\n\t\t\t\t\t\t\t\"test2/*\": [\"./test2-success/*\"],\n\t\t\t\t\t\t\t\"t*t3/foo\": [\"./test3-succ*s.ts\"],\n\t\t\t\t\t\t\t\"test4/*\": [\"./test4-first/*\", \"./test4-second/*\"],\n\t\t\t\t\t\t\t\"test5/*\": [\"./test5-first/*\", \"./test5-second/*\"],\n\t\t\t\t\t\t\t\"/virtual-in/test\": [\"./actual/test\"],\n\t\t\t\t\t\t\t\"/virtual-in-star/*\": [\"./actual/*\"],\n\t\t\t\t\t\t\t\"/virtual-out/test\": [\"/Users/user/project/baseurl_dot/actual/test\"],\n\t\t\t\t\t\t\t\"/virtual-out-star/*\": [\"/Users/user/project/baseurl_dot/actual/*\"],\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_dot/test0-success.ts\": `\n\t\t\t\texport default 'test0-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_dot/test1-success.ts\": `\n\t\t\t\texport default 'test1-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_dot/test2-success/foo.ts\": `\n\t\t\t\texport default 'test2-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_dot/test3-success.ts\": `\n\t\t\t\texport default 'test3-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_dot/test4-first/foo.ts\": `\n\t\t\t\texport default 'test4-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_dot/test5-second/foo.ts\": `\n\t\t\t\texport default 'test5-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_dot/absolute-in.ts\": `\n\t\t\t\texport {default} from '/virtual-in/test'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_dot/absolute-in-star.ts\": `\n\t\t\t\texport {default} from '/virtual-in-star/test'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_dot/absolute-out.ts\": `\n\t\t\t\texport {default} from '/virtual-out/test'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_dot/absolute-out-star.ts\": `\n\t\t\t\texport {default} from '/virtual-out-star/test'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_dot/actual/test.ts\": `\n\t\t\t\texport default 'absolute-success'\n\t\t\t`,\n\n\t\t\t// Tests with \"baseUrl\": \"nested\"\n\t\t\t\"/Users/user/project/baseurl_nested/index.ts\": `\n\t\t\t\timport test0 from 'test0'\n\t\t\t\timport test1 from 'test1/foo'\n\t\t\t\timport test2 from 'test2/foo'\n\t\t\t\timport test3 from 'test3/foo'\n\t\t\t\timport test4 from 'test4/foo'\n\t\t\t\timport test5 from 'test5/foo'\n\t\t\t\timport absoluteIn from './absolute-in'\n\t\t\t\timport absoluteInStar from './absolute-in-star'\n\t\t\t\timport absoluteOut from './absolute-out'\n\t\t\t\timport absoluteOutStar from './absolute-out-star'\n\t\t\t\texport default {\n\t\t\t\t\ttest0,\n\t\t\t\t\ttest1,\n\t\t\t\t\ttest2,\n\t\t\t\t\ttest3,\n\t\t\t\t\ttest4,\n\t\t\t\t\ttest5,\n\t\t\t\t\tabsoluteIn,\n\t\t\t\t\tabsoluteInStar,\n\t\t\t\t\tabsoluteOut,\n\t\t\t\t\tabsoluteOutStar,\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_nested/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \"nested\",\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"test0\": [\"./test0-success.ts\"],\n\t\t\t\t\t\t\t\"test1/*\": [\"./test1-success.ts\"],\n\t\t\t\t\t\t\t\"test2/*\": [\"./test2-success/*\"],\n\t\t\t\t\t\t\t\"t*t3/foo\": [\"./test3-succ*s.ts\"],\n\t\t\t\t\t\t\t\"test4/*\": [\"./test4-first/*\", \"./test4-second/*\"],\n\t\t\t\t\t\t\t\"test5/*\": [\"./test5-first/*\", \"./test5-second/*\"],\n\t\t\t\t\t\t\t\"/virtual-in/test\": [\"./actual/test\"],\n\t\t\t\t\t\t\t\"/virtual-in-star/*\": [\"./actual/*\"],\n\t\t\t\t\t\t\t\"/virtual-out/test\": [\"/Users/user/project/baseurl_nested/nested/actual/test\"],\n\t\t\t\t\t\t\t\"/virtual-out-star/*\": [\"/Users/user/project/baseurl_nested/nested/actual/*\"],\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_nested/nested/test0-success.ts\": `\n\t\t\t\texport default 'test0-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_nested/nested/test1-success.ts\": `\n\t\t\t\texport default 'test1-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_nested/nested/test2-success/foo.ts\": `\n\t\t\t\texport default 'test2-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_nested/nested/test3-success.ts\": `\n\t\t\t\texport default 'test3-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_nested/nested/test4-first/foo.ts\": `\n\t\t\t\texport default 'test4-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_nested/nested/test5-second/foo.ts\": `\n\t\t\t\texport default 'test5-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_nested/absolute-in.ts\": `\n\t\t\t\texport {default} from '/virtual-in/test'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_nested/absolute-in-star.ts\": `\n\t\t\t\texport {default} from '/virtual-in/test'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_nested/absolute-out.ts\": `\n\t\t\t\texport {default} from '/virtual-out/test'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_nested/absolute-out-star.ts\": `\n\t\t\t\texport {default} from '/virtual-out-star/test'\n\t\t\t`,\n\t\t\t\"/Users/user/project/baseurl_nested/nested/actual/test.ts\": `\n\t\t\t\texport default 'absolute-success'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigPathsNoBaseURL(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.ts\": `\n\t\t\t\timport simple from './simple'\n\t\t\t\timport extended from './extended'\n\t\t\t\tconsole.log(simple, extended)\n\t\t\t`,\n\n\t\t\t// Tests with \"baseUrl\": \".\"\n\t\t\t\"/Users/user/project/simple/index.ts\": `\n\t\t\t\timport test0 from 'test0'\n\t\t\t\timport test1 from 'test1/foo'\n\t\t\t\timport test2 from 'test2/foo'\n\t\t\t\timport test3 from 'test3/foo'\n\t\t\t\timport test4 from 'test4/foo'\n\t\t\t\timport test5 from 'test5/foo'\n\t\t\t\timport absolute from './absolute'\n\t\t\t\texport default {\n\t\t\t\t\ttest0,\n\t\t\t\t\ttest1,\n\t\t\t\t\ttest2,\n\t\t\t\t\ttest3,\n\t\t\t\t\ttest4,\n\t\t\t\t\ttest5,\n\t\t\t\t\tabsolute,\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/simple/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"test0\": [\"./test0-success.ts\"],\n\t\t\t\t\t\t\t\"test1/*\": [\"./test1-success.ts\"],\n\t\t\t\t\t\t\t\"test2/*\": [\"./test2-success/*\"],\n\t\t\t\t\t\t\t\"t*t3/foo\": [\"./test3-succ*s.ts\"],\n\t\t\t\t\t\t\t\"test4/*\": [\"./test4-first/*\", \"./test4-second/*\"],\n\t\t\t\t\t\t\t\"test5/*\": [\"./test5-first/*\", \"./test5-second/*\"],\n\t\t\t\t\t\t\t\"/virtual/*\": [\"./actual/*\"],\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/simple/test0-success.ts\": `\n\t\t\t\texport default 'test0-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/simple/test1-success.ts\": `\n\t\t\t\texport default 'test1-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/simple/test2-success/foo.ts\": `\n\t\t\t\texport default 'test2-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/simple/test3-success.ts\": `\n\t\t\t\texport default 'test3-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/simple/test4-first/foo.ts\": `\n\t\t\t\texport default 'test4-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/simple/test5-second/foo.ts\": `\n\t\t\t\texport default 'test5-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/simple/absolute.ts\": `\n\t\t\t\texport {default} from '/virtual/test'\n\t\t\t`,\n\t\t\t\"/Users/user/project/simple/actual/test.ts\": `\n\t\t\t\texport default 'absolute-success'\n\t\t\t`,\n\n\t\t\t// Tests with \"baseUrl\": \"nested\"\n\t\t\t\"/Users/user/project/extended/index.ts\": `\n\t\t\t\timport test0 from 'test0'\n\t\t\t\timport test1 from 'test1/foo'\n\t\t\t\timport test2 from 'test2/foo'\n\t\t\t\timport test3 from 'test3/foo'\n\t\t\t\timport test4 from 'test4/foo'\n\t\t\t\timport test5 from 'test5/foo'\n\t\t\t\timport absolute from './absolute'\n\t\t\t\texport default {\n\t\t\t\t\ttest0,\n\t\t\t\t\ttest1,\n\t\t\t\t\ttest2,\n\t\t\t\t\ttest3,\n\t\t\t\t\ttest4,\n\t\t\t\t\ttest5,\n\t\t\t\t\tabsolute,\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/extended/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"./nested/tsconfig.json\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/extended/nested/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"test0\": [\"./test0-success.ts\"],\n\t\t\t\t\t\t\t\"test1/*\": [\"./test1-success.ts\"],\n\t\t\t\t\t\t\t\"test2/*\": [\"./test2-success/*\"],\n\t\t\t\t\t\t\t\"t*t3/foo\": [\"./test3-succ*s.ts\"],\n\t\t\t\t\t\t\t\"test4/*\": [\"./test4-first/*\", \"./test4-second/*\"],\n\t\t\t\t\t\t\t\"test5/*\": [\"./test5-first/*\", \"./test5-second/*\"],\n\t\t\t\t\t\t\t\"/virtual/*\": [\"./actual/*\"],\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/extended/nested/test0-success.ts\": `\n\t\t\t\texport default 'test0-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/extended/nested/test1-success.ts\": `\n\t\t\t\texport default 'test1-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/extended/nested/test2-success/foo.ts\": `\n\t\t\t\texport default 'test2-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/extended/nested/test3-success.ts\": `\n\t\t\t\texport default 'test3-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/extended/nested/test4-first/foo.ts\": `\n\t\t\t\texport default 'test4-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/extended/nested/test5-second/foo.ts\": `\n\t\t\t\texport default 'test5-success'\n\t\t\t`,\n\t\t\t\"/Users/user/project/extended/absolute.ts\": `\n\t\t\t\texport {default} from '/virtual/test'\n\t\t\t`,\n\t\t\t\"/Users/user/project/extended/nested/actual/test.ts\": `\n\t\t\t\texport default 'absolute-success'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigBadPathsNoBaseURL(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.ts\": `\n\t\t\t\timport \"should-not-be-imported\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/should-not-be-imported.ts\": `\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"test\": [\n\t\t\t\t\t\t\t\t\".\",\n\t\t\t\t\t\t\t\t\"..\",\n\t\t\t\t\t\t\t\t\"./good\",\n\t\t\t\t\t\t\t\t\".\\\\good\",\n\t\t\t\t\t\t\t\t\"../good\",\n\t\t\t\t\t\t\t\t\"..\\\\good\",\n\t\t\t\t\t\t\t\t\"/good\",\n\t\t\t\t\t\t\t\t\"\\\\good\",\n\t\t\t\t\t\t\t\t\"c:/good\",\n\t\t\t\t\t\t\t\t\"c:\\\\good\",\n\t\t\t\t\t\t\t\t\"C:/good\",\n\t\t\t\t\t\t\t\t\"C:\\\\good\",\n\n\t\t\t\t\t\t\t\t\"bad\",\n\t\t\t\t\t\t\t\t\"@bad/core\",\n\t\t\t\t\t\t\t\t\".*/bad\",\n\t\t\t\t\t\t\t\t\"..*/bad\",\n\t\t\t\t\t\t\t\t\"c*:\\\\bad\",\n\t\t\t\t\t\t\t\t\"c:*\\\\bad\",\n\t\t\t\t\t\t\t\t\"http://bad\"\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/entry.ts: ERROR: Could not resolve \"should-not-be-imported\"\nNOTE: Use the relative path \"./should-not-be-imported\" to reference the file \"Users/user/project/should-not-be-imported.ts\". Without the leading \"./\", the path \"should-not-be-imported\" is being interpreted as a package path instead.\nUsers/user/project/tsconfig.json: WARNING: Non-relative path \"bad\" is not allowed when \"baseUrl\" is not set (did you forget a leading \"./\"?)\nUsers/user/project/tsconfig.json: WARNING: Non-relative path \"@bad/core\" is not allowed when \"baseUrl\" is not set (did you forget a leading \"./\"?)\nUsers/user/project/tsconfig.json: WARNING: Non-relative path \".*/bad\" is not allowed when \"baseUrl\" is not set (did you forget a leading \"./\"?)\nUsers/user/project/tsconfig.json: WARNING: Non-relative path \"..*/bad\" is not allowed when \"baseUrl\" is not set (did you forget a leading \"./\"?)\nUsers/user/project/tsconfig.json: WARNING: Non-relative path \"c*:\\\\bad\" is not allowed when \"baseUrl\" is not set (did you forget a leading \"./\"?)\nUsers/user/project/tsconfig.json: WARNING: Non-relative path \"c:*\\\\bad\" is not allowed when \"baseUrl\" is not set (did you forget a leading \"./\"?)\nUsers/user/project/tsconfig.json: WARNING: Non-relative path \"http://bad\" is not allowed when \"baseUrl\" is not set (did you forget a leading \"./\"?)\n`,\n\t})\n}\n\n// https://github.com/evanw/esbuild/issues/913\nfunc TestTsconfigPathsOverriddenBaseURL(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\timport test from '#/test'\n\t\t\t\tconsole.log(test)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/test.ts\": `\n\t\t\t\texport default 123\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"./tsconfig.paths.json\",\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \"./src\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.paths.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"#/*\": [\"./*\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigPathsOverriddenBaseURLDifferentDir(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\timport test from '#/test'\n\t\t\t\tconsole.log(test)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/test.ts\": `\n\t\t\t\texport default 123\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"../tsconfig.paths.json\",\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \"./\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.paths.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"#/*\": [\"./*\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigPathsMissingBaseURL(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\timport test from '#/test'\n\t\t\t\tconsole.log(test)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/test.ts\": `\n\t\t\t\texport default 123\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"../tsconfig.paths.json\",\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.paths.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"#/*\": [\"./*\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.ts: ERROR: Could not resolve \"#/test\"\nNOTE: You can mark the path \"#/test\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestTsconfigPathsTypeOnly(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.ts\": `\n\t\t\t\timport { fib } from \"fib\";\n\n\t\t\t\tconsole.log(fib(10));\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/fib/index.js\": `\n\t\t\t\texport function fib(input) {\n\t\t\t\t\tif (input < 2) {\n\t\t\t\t\t\treturn input;\n\t\t\t\t\t}\n\t\t\t\t\treturn fib(input - 1) + fib(input - 2);\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/fib-local.d.ts\": `\n\t\t\t\texport function fib(input: number): number;\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \".\",\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"fib\": [\"fib-local.d.ts\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJSX(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.tsx\": `\n\t\t\t\tconsole.log(<><div/><div/></>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFactory\": \"R.c\",\n\t\t\t\t\t\t\"jsxFragmentFactory\": \"R.F\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigNestedJSX(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.ts\": `\n\t\t\t\timport factory from './factory'\n\t\t\t\timport fragment from './fragment'\n\t\t\t\timport both from './both'\n\t\t\t\tconsole.log(factory, fragment, both)\n\t\t\t`,\n\t\t\t\"/Users/user/project/factory/index.tsx\": `\n\t\t\t\texport default <><div/><div/></>\n\t\t\t`,\n\t\t\t\"/Users/user/project/factory/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFactory\": \"h\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/fragment/index.tsx\": `\n\t\t\t\texport default <><div/><div/></>\n\t\t\t`,\n\t\t\t\"/Users/user/project/fragment/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFragmentFactory\": \"a.b\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/both/index.tsx\": `\n\t\t\t\texport default <><div/><div/></>\n\t\t\t`,\n\t\t\t\"/Users/user/project/both/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFactory\": \"R.c\",\n\t\t\t\t\t\t\"jsxFragmentFactory\": \"R.F\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigPreserveJSX(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.tsx\": `\n\t\t\t\tconsole.log(<><div/><div/></>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsx\": \"preserve\" // This should be ignored\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigPreserveJSXAutomatic(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.tsx\": `\n\t\t\t\tconsole.log(<><div/><div/></>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsx\": \"preserve\" // This should be ignored\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tAutomaticRuntime: true,\n\t\t\t},\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"react/jsx-runtime\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestTsconfigReactJSX(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.tsx\": `\n\t\t\t\tconsole.log(<><div/><div/></>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsx\": \"react-jsx\",\n\t\t\t\t\t\t\"jsxImportSource\": \"notreact\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"notreact/jsx-runtime\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestTsconfigReactJSXDev(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.tsx\": `\n\t\t\t\tconsole.log(<><div/><div/></>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsx\": \"react-jsxdev\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"react/jsx-dev-runtime\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestTsconfigReactJSXWithDevInMainConfig(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.tsx\": `\n\t\t\t\tconsole.log(<><div/><div/></>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsx\": \"react-jsx\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tDevelopment: true,\n\t\t\t},\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPreResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"react/jsx-dev-runtime\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonBaseUrl(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/app/entry.js\": `\n\t\t\t\timport fn from 'lib/util'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \".\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/lib/util.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/app/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestJsconfigJsonBaseUrl(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/app/entry.js\": `\n\t\t\t\timport fn from 'lib/util'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/jsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \".\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/lib/util.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/app/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonAbsoluteBaseUrl(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/app/entry.js\": `\n\t\t\t\timport fn from 'lib/util'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \"/Users/user/project/src\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/lib/util.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/app/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonCommentAllowed(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/app/entry.js\": `\n\t\t\t\timport fn from 'lib/util'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t// Single-line comment\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \".\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/lib/util.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/app/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonTrailingCommaAllowed(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/app/entry.js\": `\n\t\t\t\timport fn from 'lib/util'\n\t\t\t\tconsole.log(fn())\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \".\",\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/lib/util.js\": `\n\t\t\t\tmodule.exports = function() {\n\t\t\t\t\treturn 123\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/app/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonExtends(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.jsx\": `\n\t\t\t\tconsole.log(<div/>, <></>)\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"./base\",\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFragmentFactory\": \"derivedFragment\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/base.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFactory\": \"baseFactory\",\n\t\t\t\t\t\t\"jsxFragmentFactory\": \"baseFragment\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonExtendsAbsolute(t *testing.T) {\n\ttsconfig_suite.expectBundledUnix(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.jsx\": `\n\t\t\t\tconsole.log(<div/>, <></>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"/Users/user/project/base.json\",\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFragmentFactory\": \"derivedFragment\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/base.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFactory\": \"baseFactory\",\n\t\t\t\t\t\t\"jsxFragmentFactory\": \"baseFragment\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n\n\ttsconfig_suite.expectBundledWindows(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"C:\\\\Users\\\\user\\\\project\\\\entry.jsx\": `\n\t\t\t\tconsole.log(<div/>, <></>)\n\t\t\t`,\n\t\t\t\"C:\\\\Users\\\\user\\\\project\\\\tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"C:\\\\Users\\\\user\\\\project\\\\base.json\",\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFragmentFactory\": \"derivedFragment\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"C:\\\\Users\\\\user\\\\project\\\\base.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFactory\": \"baseFactory\",\n\t\t\t\t\t\t\"jsxFragmentFactory\": \"baseFragment\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"C:\\\\Users\\\\user\\\\project\\\\entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"C:\\\\out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonExtendsThreeLevels(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.jsx\": `\n\t\t\t\timport \"test/import.js\"\n\t\t\t\tconsole.log(<div/>, <></>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"./path1/base\",\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFragmentFactory\": \"derivedFragment\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/path1/base.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"../path2/base2\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/path2/base2.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \".\",\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"test/*\": [\"./works/*\"]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"jsxFactory\": \"baseFactory\",\n\t\t\t\t\t\t\"jsxFragmentFactory\": \"baseFragment\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/path2/works/import.js\": `\n\t\t\t\tconsole.log('works')\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonExtendsLoop(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.js\": `\n\t\t\t\tconsole.log(123)\n\t\t\t`,\n\t\t\t\"/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"./base.json\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/base.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"./tsconfig\"\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t},\n\t\texpectedScanLog: `base.json: WARNING: Base config file \"./tsconfig\" forms cycle\n`,\n\t})\n}\n\nfunc TestTsconfigJsonExtendsPackage(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/app/entry.jsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"@package/foo/tsconfig.json\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/@package/foo/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFactory\": \"worked\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/app/entry.jsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonOverrideMissing(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/app/entry.ts\": `\n\t\t\t\timport 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/foo-bad.ts\": `\n\t\t\t\tconsole.log('bad')\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \".\",\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"foo\": [\"./foo-bad.ts\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/other/foo-good.ts\": `\n\t\t\t\tconsole.log('good')\n\t\t\t`,\n\t\t\t\"/Users/user/project/other/config-for-ts.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \".\",\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"foo\": [\"./foo-good.ts\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/app/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tTSConfigPath:  \"/Users/user/project/other/config-for-ts.json\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonOverrideNodeModules(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/app/entry.ts\": `\n\t\t\t\timport 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/node_modules/foo/index.js\": `\n\t\t\t\tconsole.log('default')\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/foo-bad.ts\": `\n\t\t\t\tconsole.log('bad')\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \".\",\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"foo\": [\"./foo-bad.ts\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/other/foo-good.ts\": `\n\t\t\t\tconsole.log('good')\n\t\t\t`,\n\t\t\t\"/Users/user/project/other/config-for-ts.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \".\",\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"foo\": [\"./foo-good.ts\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/app/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tTSConfigPath:  \"/Users/user/project/other/config-for-ts.json\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonOverrideInvalid(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/entry.ts\": ``,\n\t\t},\n\t\tentryPaths: []string{\"/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/out.js\",\n\t\t\tTSConfigPath:  \"/this/file/doesn't/exist/tsconfig.json\",\n\t\t},\n\t\texpectedScanLog: `ERROR: Cannot find tsconfig file \"this/file/doesn't/exist/tsconfig.json\"\n`,\n\t})\n}\n\nfunc TestTsconfigJsonNodeModulesImplicitFile(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/app/entry.tsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"foo\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/node_modules/foo/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsx\": \"react\",\n\t\t\t\t\t\t\"jsxFactory\": \"worked\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/app/entry.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonNodeModulesTsconfigPathExact(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/app/entry.tsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"foo\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/node_modules/foo/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"tsconfig\": \"over/here.json\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/node_modules/foo/over/here.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsx\": \"react\",\n\t\t\t\t\t\t\"jsxFactory\": \"worked\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/app/entry.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonNodeModulesTsconfigPathImplicitJson(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/app/entry.tsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"foo\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/node_modules/foo/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"tsconfig\": \"over/here\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/node_modules/foo/over/here.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsx\": \"react\",\n\t\t\t\t\t\t\"jsxFactory\": \"worked\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/app/entry.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonNodeModulesTsconfigPathDirectory(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/app/entry.tsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"foo\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/node_modules/foo/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"tsconfig\": \"over/here\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/node_modules/foo/over/here/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsx\": \"react\",\n\t\t\t\t\t\t\"jsxFactory\": \"worked\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/app/entry.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonNodeModulesTsconfigPathBad(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/app/entry.tsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"foo\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/node_modules/foo/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"tsconfig\": \"over/here.json\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/node_modules/foo/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsx\": \"react\",\n\t\t\t\t\t\t\"jsxFactory\": \"THIS SHOULD NOT BE LOADED\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/app/entry.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/tsconfig.json: WARNING: Cannot find base config file \"foo\"\n`,\n\t})\n}\n\nfunc TestTsconfigJsonInsideNodeModules(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/app/entry.tsx\": `\n\t\t\t\timport 'foo'\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/node_modules/foo/index.tsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/node_modules/foo/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFactory\": \"TEST_FAILED\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/app/entry.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigWarningsInsideNodeModules(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.tsx\": `\n\t\t\t\timport \"./foo\"\n\t\t\t\timport \"bar\"\n\t\t\t`,\n\n\t\t\t\"/Users/user/project/src/foo/tsconfig.json\": `{ \"extends\": \"extends for foo\" }`,\n\t\t\t\"/Users/user/project/src/foo/index.js\":      ``,\n\n\t\t\t\"/Users/user/project/src/node_modules/bar/tsconfig.json\": `{ \"extends\": \"extends for bar\" }`,\n\t\t\t\"/Users/user/project/src/node_modules/bar/index.js\":      ``,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/foo/tsconfig.json: WARNING: Cannot find base config file \"extends for foo\"\n`,\n\t})\n}\n\nfunc TestTsconfigRemoveUnusedImports(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\timport {x, y} from \"./foo\"\n\t\t\t\tconsole.log(1 as x)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"importsNotUsedAsValues\": \"remove\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigPreserveUnusedImports(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\timport {x, y} from \"./foo\"\n\t\t\t\tconsole.log(1 as x)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"importsNotUsedAsValues\": \"preserve\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPostResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"/Users/user/project/src/foo\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestTsconfigImportsNotUsedAsValuesPreserve(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\timport {x, y} from \"./foo\"\n\t\t\t\timport z from \"./foo\"\n\t\t\t\timport * as ns from \"./foo\"\n\t\t\t\tconsole.log(1 as x, 2 as z, 3 as ns.y)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"importsNotUsedAsValues\": \"preserve\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPostResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"/Users/user/project/src/foo\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestTsconfigPreserveValueImports(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\timport {} from \"a\"\n\t\t\t\timport {b1} from \"b\"\n\t\t\t\timport {c1, type c2} from \"c\"\n\t\t\t\timport {d1, d2, type d3} from \"d\"\n\t\t\t\timport {type e1, type e2} from \"e\"\n\t\t\t\timport f1, {} from \"f\"\n\t\t\t\timport g1, {g2} from \"g\"\n\t\t\t\timport h1, {type h2} from \"h\"\n\t\t\t\timport * as i1 from \"i\"\n\t\t\t\timport \"j\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"preserveValueImports\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPostResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"/Users/user/project/src/foo\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestTsconfigPreserveValueImportsAndImportsNotUsedAsValuesPreserve(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\timport {} from \"a\"\n\t\t\t\timport {b1} from \"b\"\n\t\t\t\timport {c1, type c2} from \"c\"\n\t\t\t\timport {d1, d2, type d3} from \"d\"\n\t\t\t\timport {type e1, type e2} from \"e\"\n\t\t\t\timport f1, {} from \"f\"\n\t\t\t\timport g1, {g2} from \"g\"\n\t\t\t\timport h1, {type h2} from \"h\"\n\t\t\t\timport * as i1 from \"i\"\n\t\t\t\timport \"j\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"importsNotUsedAsValues\": \"preserve\",\n\t\t\t\t\t\"preserveValueImports\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeConvertFormat,\n\t\t\tOutputFormat:  config.FormatESModule,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tExternalSettings: config.ExternalSettings{\n\t\t\t\tPostResolve: config.ExternalMatchers{Exact: map[string]bool{\n\t\t\t\t\t\"/Users/user/project/src/foo\": true,\n\t\t\t\t}},\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestTsconfigUseDefineForClassFieldsES2020(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\tFoo = class {\n\t\t\t\t\tuseDefine = false\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"target\": \"ES2020\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tAbsOutputFile:     \"/Users/user/project/out.js\",\n\t\t\tOriginalTargetEnv: \"esnext\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigUseDefineForClassFieldsESNext(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\tFoo = class {\n\t\t\t\t\tuseDefine = true\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"target\": \"ESNext\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModeBundle,\n\t\t\tAbsOutputFile:     \"/Users/user/project/out.js\",\n\t\t\tOriginalTargetEnv: \"esnext\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigUnrecognizedTargetWarning(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\timport \"./a\"\n\t\t\t\timport \"b\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/a/index.ts\": ``,\n\t\t\t\"/Users/user/project/src/a/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"target\": \"es4\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/Users/user/project/src/node_modules/b/index.ts\": ``,\n\t\t\t\"/Users/user/project/src/node_modules/b/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"target\": \"es4\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/a/tsconfig.json: WARNING: Unrecognized target environment \"es4\"\n`,\n\t})\n}\n\nfunc TestTsconfigIgnoredTargetSilent(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\timport \"./a\"\n\t\t\t\timport \"b\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/a/index.ts\": ``,\n\t\t\t\"/Users/user/project/src/a/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"target\": \"es5\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/Users/user/project/src/node_modules/b/index.ts\": ``,\n\t\t\t\"/Users/user/project/src/node_modules/b/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"target\": \"es5\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:                  config.ModeBundle,\n\t\t\tAbsOutputFile:         \"/Users/user/project/out.js\",\n\t\t\tUnsupportedJSFeatures: es(5),\n\t\t\tOriginalTargetEnv:     \"ES5\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigNoBaseURLExtendsPaths(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\timport { foo } from \"foo\"\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/Users/user/project/lib/foo.ts\": `\n\t\t\t\texport let foo = 123\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"extends\": \"./base/defaults\"\n\t\t\t}`,\n\t\t\t\"/Users/user/project/base/defaults.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\"*\": [\"lib/*\"]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/base/defaults.json: WARNING: Non-relative path \"lib/*\" is not allowed when \"baseUrl\" is not set (did you forget a leading \"./\"?)\nUsers/user/project/src/entry.ts: ERROR: Could not resolve \"foo\"\nNOTE: You can mark the path \"foo\" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.\n`,\n\t})\n}\n\nfunc TestTsconfigBaseURLExtendsPaths(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\timport { foo } from \"foo\"\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/Users/user/project/lib/foo.ts\": `\n\t\t\t\texport let foo = 123\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"extends\": \"./base/defaults\",\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"baseUrl\": \".\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/Users/user/project/base/defaults.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\"*\": [\"lib/*\"]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigPathsExtendsBaseURL(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\timport { foo } from \"foo\"\n\t\t\t\tconsole.log(foo)\n\t\t\t`,\n\t\t\t\"/Users/user/project/base/test/lib/foo.ts\": `\n\t\t\t\texport let foo = 123\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"extends\": \"./base/defaults\",\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\"*\": [\"lib/*\"]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/Users/user/project/base/defaults.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"baseUrl\": \"test\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigPathsInNodeModulesIssue2386(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/main.js\": `\n\t\t\t\timport first from \"wow/first\";\n\t\t\t\timport next from \"wow/next\";\n\t\t\t\tconsole.log(first, next);\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/wow/package.json\": `{\n\t\t\t\t\"name\": \"wow\",\n\t\t\t\t\"type\": \"module\",\n\t\t\t\t\"private\": true,\n\t\t\t\t\"exports\": {\n\t\t\t\t\t\"./*\": \"./dist/*.js\"\n\t\t\t\t},\n\t\t\t\t\"typesVersions\": {\n\t\t\t\t\t\"*\": {\n\t\t\t\t\t\t\"*\": [\n\t\t\t\t\t\t\t\"dist/*\"\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/Users/user/project/node_modules/wow/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"paths\": { \"wow/*\": [ \"./*\" ] }\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/Users/user/project/node_modules/wow/dist/first.js\": `\n\t\t\t\texport default \"dist\";\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/wow/dist/next.js\": `\n\t\t\t\timport next from \"wow/first\";\n\t\t\t\texport default next;\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/wow/first.ts\": `\n\t\t\t\texport default \"source\";\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/main.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigWithStatementAlwaysStrictFalse(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\twith (x) y\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"alwaysStrict\": false\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t},\n\t})\n}\n\nfunc TestTsconfigWithStatementAlwaysStrictTrue(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\twith (x) y\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"alwaysStrict\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.ts: ERROR: With statements cannot be used in strict mode\nUsers/user/project/tsconfig.json: NOTE: TypeScript's \"alwaysStrict\" setting was enabled here:\n`,\n\t})\n}\n\nfunc TestTsconfigWithStatementStrictFalse(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\twith (x) y\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"strict\": false\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t},\n\t})\n}\n\nfunc TestTsconfigWithStatementStrictTrue(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\twith (x) y\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"strict\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.ts: ERROR: With statements cannot be used in strict mode\nUsers/user/project/tsconfig.json: NOTE: TypeScript's \"strict\" setting was enabled here:\n`,\n\t})\n}\n\nfunc TestTsconfigWithStatementStrictFalseAlwaysStrictTrue(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\twith (x) y\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"strict\": false,\n\t\t\t\t\t\"alwaysStrict\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/entry.ts: ERROR: With statements cannot be used in strict mode\nUsers/user/project/tsconfig.json: NOTE: TypeScript's \"alwaysStrict\" setting was enabled here:\n`,\n\t})\n}\n\nfunc TestTsconfigWithStatementStrictTrueAlwaysStrictFalse(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\twith (x) y\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"strict\": true,\n\t\t\t\t\t\"alwaysStrict\": false\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tOutputFormat:  config.FormatIIFE,\n\t\t},\n\t})\n}\n\nfunc TestTsconfigAlwaysStrictTrueEmitDirectivePassThrough(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/implicit.ts\": `\n\t\t\t\tconsole.log('this file should start with \"use strict\"')\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/explicit.ts\": `\n\t\t\t\t'use strict'\n\t\t\t\tconsole.log('this file should start with \"use strict\"')\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"alwaysStrict\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/Users/user/project/src/implicit.ts\",\n\t\t\t\"/Users/user/project/src/explicit.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigAlwaysStrictTrueEmitDirectiveFormat(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/implicit.ts\": `\n\t\t\t\tconsole.log('this file should start with \"use strict\"')\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/explicit.ts\": `\n\t\t\t\t'use strict'\n\t\t\t\tconsole.log('this file should start with \"use strict\"')\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"alwaysStrict\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/Users/user/project/src/implicit.ts\",\n\t\t\t\"/Users/user/project/src/explicit.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeConvertFormat,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigAlwaysStrictTrueEmitDirectiveBundleIIFE(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/implicit.ts\": `\n\t\t\t\tconsole.log('this file should start with \"use strict\"')\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/explicit.ts\": `\n\t\t\t\t'use strict'\n\t\t\t\tconsole.log('this file should start with \"use strict\"')\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"alwaysStrict\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/Users/user/project/src/implicit.ts\",\n\t\t\t\"/Users/user/project/src/explicit.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t\tOutputFormat: config.FormatIIFE,\n\t\t},\n\t})\n}\n\nfunc TestTsconfigAlwaysStrictTrueEmitDirectiveBundleCJS(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/implicit.ts\": `\n\t\t\t\tconsole.log('this file should start with \"use strict\"')\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/explicit.ts\": `\n\t\t\t\t'use strict'\n\t\t\t\tconsole.log('this file should start with \"use strict\"')\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"alwaysStrict\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/Users/user/project/src/implicit.ts\",\n\t\t\t\"/Users/user/project/src/explicit.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t\tOutputFormat: config.FormatCommonJS,\n\t\t},\n\t})\n}\n\nfunc TestTsconfigAlwaysStrictTrueEmitDirectiveBundleESM(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/implicit.ts\": `\n\t\t\t\tconsole.log('this file should not start with \"use strict\"')\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/explicit.ts\": `\n\t\t\t\t'use strict'\n\t\t\t\tconsole.log('this file should not start with \"use strict\"')\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"alwaysStrict\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/Users/user/project/src/implicit.ts\",\n\t\t\t\"/Users/user/project/src/explicit.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t},\n\t})\n}\n\nfunc TestTsconfigExtendsDotWithoutSlash(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/main.tsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/foo.json\": `{\n\t\t\t\t\"extends\": \".\"\n\t\t\t}`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"jsxFactory\": \"success\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/main.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t\tTSConfigPath: \"/Users/user/project/src/foo.json\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigExtendsDotDotWithoutSlash(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/main.tsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `{\n\t\t\t\t\"extends\": \"..\"\n\t\t\t}`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"jsxFactory\": \"success\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/main.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t},\n\t})\n}\n\nfunc TestTsconfigExtendsDotWithSlash(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/main.tsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/foo.json\": `{\n\t\t\t\t\"extends\": \"./\"\n\t\t\t}`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"jsxFactory\": \"FAILURE\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/main.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t\tTSConfigPath: \"/Users/user/project/src/foo.json\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/foo.json: WARNING: Cannot find base config file \"./\"\n`,\n\t})\n}\n\nfunc TestTsconfigExtendsDotDotWithSlash(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/main.tsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `{\n\t\t\t\t\"extends\": \"../\"\n\t\t\t}`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"jsxFactory\": \"FAILURE\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/main.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/tsconfig.json: WARNING: Cannot find base config file \"../\"\n`,\n\t})\n}\n\nfunc TestTsconfigExtendsWithExports(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/main.tsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"extends\": \"@whatever/tsconfig/a/b/c\"\n\t\t\t}`,\n\t\t\t\"/Users/user/project/node_modules/@whatever/tsconfig/package.json\": `{\n\t\t\t\t\"exports\": {\n\t\t\t\t\t\"./a/b/c\": \"./foo.json\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/Users/user/project/node_modules/@whatever/tsconfig/foo.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"jsxFactory\": \"success\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/main.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t},\n\t})\n}\n\nfunc TestTsconfigExtendsWithExportsStar(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/main.tsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"extends\": \"@whatever/tsconfig/a/b/c\"\n\t\t\t}`,\n\t\t\t\"/Users/user/project/node_modules/@whatever/tsconfig/package.json\": `{\n\t\t\t\t\"exports\": {\n\t\t\t\t\t\"./*\": \"./tsconfig.*.json\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/Users/user/project/node_modules/@whatever/tsconfig/tsconfig.a/b/c.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"jsxFactory\": \"success\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/main.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t},\n\t})\n}\n\nfunc TestTsconfigExtendsWithExportsStarTrailing(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/main.tsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"extends\": \"@whatever/tsconfig/a/b/c.json\"\n\t\t\t}`,\n\t\t\t\"/Users/user/project/node_modules/@whatever/tsconfig/package.json\": `{\n\t\t\t\t\"exports\": {\n\t\t\t\t\t\"./*\": \"./tsconfig.*\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/Users/user/project/node_modules/@whatever/tsconfig/tsconfig.a/b/c.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"jsxFactory\": \"success\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/main.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t},\n\t})\n}\n\nfunc TestTsconfigExtendsWithExportsRequire(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/main.tsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"extends\": \"@whatever/tsconfig/a/b/c.json\"\n\t\t\t}`,\n\t\t\t\"/Users/user/project/node_modules/@whatever/tsconfig/package.json\": `{\n\t\t\t\t\"exports\": {\n\t\t\t\t\t\"./*\": {\n\t\t\t\t\t\t\"import\": \"./import.json\",\n\t\t\t\t\t\t\"require\": \"./require.json\",\n\t\t\t\t\t\t\"default\": \"./default.json\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}`,\n\t\t\t\"/Users/user/project/node_modules/@whatever/tsconfig/import.json\":  `FAILURE`,\n\t\t\t\"/Users/user/project/node_modules/@whatever/tsconfig/default.json\": `FAILURE`,\n\t\t\t\"/Users/user/project/node_modules/@whatever/tsconfig/require.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"jsxFactory\": \"success\"\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/main.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t\tOutputFormat: config.FormatESModule,\n\t\t},\n\t})\n}\n\nfunc TestTsconfigVerbatimModuleSyntaxTrue(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/main.ts\": `\n\t\t\t\texport { Car } from \"./car\";\n\t\t\t\timport type * as car from \"./car\";\n\t\t\t\timport { type Car } from \"./car\";\n\t\t\t\texport { type Car } from \"./car\";\n\t\t\t\timport type { A } from \"a\";\n\t\t\t\timport { b, type c, type d } from \"bcd\";\n\t\t\t\timport { type xyz } from \"xyz\";\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"verbatimModuleSyntax\": true\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/main.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigVerbatimModuleSyntaxFalse(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/main.ts\": `\n\t\t\t\texport { Car } from \"./car\";\n\t\t\t\timport type * as car from \"./car\";\n\t\t\t\timport { type Car } from \"./car\";\n\t\t\t\texport { type Car } from \"./car\";\n\t\t\t\timport type { A } from \"a\";\n\t\t\t\timport { b, type c, type d } from \"bcd\";\n\t\t\t\timport { type xyz } from \"xyz\";\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"verbatimModuleSyntax\": false\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/main.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigExtendsArray(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/main.tsx\": `\n\t\t\t\tdeclare let h: any, frag: any\n\t\t\t\tconsole.log(<><div /></>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"extends\": [\n\t\t\t\t\t\"./a.json\",\n\t\t\t\t\t\"./b.json\",\n\t\t\t\t],\n\t\t\t}`,\n\t\t\t\"/Users/user/project/a.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"jsxFactory\": \"h\",\n\t\t\t\t\t\"jsxFragmentFactory\": \"FAILURE\",\n\t\t\t\t},\n\t\t\t}`,\n\t\t\t\"/Users/user/project/b.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"jsxFragmentFactory\": \"frag\",\n\t\t\t\t},\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/main.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModePassThrough,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigExtendsArrayNested(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/main.tsx\": `\n\t\t\t\timport { foo } from 'foo'\n\t\t\t\tdeclare let b: any, bBase: any\n\t\t\t\texport class Foo {\n\t\t\t\t\trender = () => <><div /></>\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"extends\": [\n\t\t\t\t\t\"./a.json\",\n\t\t\t\t\t\"./b.json\",\n\t\t\t\t],\n\t\t\t}`,\n\t\t\t\"/Users/user/project/a.json\": `{\n\t\t\t\t\"extends\": \"./a-base.json\",\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"jsxFactory\": \"a\",\n\t\t\t\t\t\"jsxFragmentFactory\": \"a\",\n\t\t\t\t\t\"target\": \"ES2015\",\n\t\t\t\t},\n\t\t\t}`,\n\t\t\t\"/Users/user/project/a-base.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"jsxFactory\": \"aBase\",\n\t\t\t\t\t\"jsxFragmentFactory\": \"aBase\",\n\t\t\t\t\t\"target\": \"ES2022\",\n\t\t\t\t\t\"verbatimModuleSyntax\": true,\n\t\t\t\t},\n\t\t\t}`,\n\t\t\t\"/Users/user/project/b.json\": `{\n\t\t\t\t\"extends\": \"./b-base.json\",\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"jsxFactory\": \"b\",\n\t\t\t\t},\n\t\t\t}`,\n\t\t\t\"/Users/user/project/b-base.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"jsxFactory\": \"bBase\",\n\t\t\t\t\t\"jsxFragmentFactory\": \"bBase\",\n\t\t\t\t},\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/main.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:              config.ModePassThrough,\n\t\t\tAbsOutputDir:      \"/Users/user/project/out\",\n\t\t\tOriginalTargetEnv: \"esnext\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigIgnoreInsideNodeModules(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/main.ts\": `\n\t\t\t\timport { foo } from 'js-pkg'\n\t\t\t\timport { bar } from 'ts-pkg'\n\t\t\t\timport { foo as shimFoo, bar as shimBar } from 'pkg'\n\t\t\t\tif (foo !== 'foo') throw 'fail: foo'\n\t\t\t\tif (bar !== 'bar') throw 'fail: bar'\n\t\t\t\tif (shimFoo !== 'shimFoo') throw 'fail: shimFoo'\n\t\t\t\tif (shimBar !== 'shimBar') throw 'fail: shimBar'\n\t\t\t`,\n\t\t\t\"/Users/user/project/shim.ts\": `\n\t\t\t\texport let foo = 'shimFoo'\n\t\t\t\texport let bar = 'shimBar'\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\"pkg\": [\"./shim\"],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}`,\n\t\t\t\"/Users/user/project/node_modules/js-pkg/index.js\": `\n\t\t\t\timport { foo as pkgFoo } from 'pkg'\n\t\t\t\texport let foo = pkgFoo\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/ts-pkg/index.ts\": `\n\t\t\t\timport { bar as pkgBar } from 'pkg'\n\t\t\t\texport let bar = pkgBar\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/pkg/index.js\": `\n\t\t\t\texport let foo = 'foo'\n\t\t\t\texport let bar = 'bar'\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/main.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonPackagesExternal(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport truePkg from 'pkg1'\n\t\t\t\timport falsePkg from 'internal/pkg2'\n\t\t\t\ttruePkg()\n\t\t\t\tfalsePkg()\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"internal/*\": [\"./stuff/*\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/stuff/pkg2.js\": `\n\t\t\t\texport default success\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:             config.ModeBundle,\n\t\t\tAbsOutputFile:    \"/Users/user/project/out.js\",\n\t\t\tExternalPackages: true,\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonTopLevelMistakeWarning(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\t@foo\n\t\t\t\tclass Foo {}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"experimentalDecorators\": true\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.ts\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t\texpectedScanLog: `Users/user/project/src/tsconfig.json: WARNING: Expected the \"experimentalDecorators\" option to be nested inside a \"compilerOptions\" object\n`,\n\t})\n}\n\n// https://github.com/evanw/esbuild/issues/3307\nfunc TestTsconfigJsonBaseUrlIssue3307(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \"./subdir\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/test.ts\": `\n\t\t\t\texport const foo = \"well, this is correct...\";\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/subdir/test.ts\": `\n\t\t\t\texport const foo = \"WRONG\";\n\t\t\t`,\n\t\t},\n\t\tentryPaths:    []string{\"test.ts\"},\n\t\tabsWorkingDir: \"/Users/user/project/src\",\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\n// https://github.com/evanw/esbuild/issues/3354\nfunc TestTsconfigJsonAsteriskNameCollisionIssue3354(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\timport {foo} from \"foo\";\n\t\t\t\tfoo();\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \".\",\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"*\": [\"web/*\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/web/foo.ts\": `\n\t\t\t\timport {foo as barFoo} from 'bar/foo';\n\t\t\t\texport function foo() {\n\t\t\t\t\tconsole.log('web/foo');\n\t\t\t\t\tbarFoo();\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/web/bar/foo/foo.ts\": `\n\t\t\t\texport function foo() {\n\t\t\t\t\tconsole.log('bar/foo');\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/web/bar/foo/index.ts\": `\n\t\t\t\texport {foo} from './foo'\n\t\t\t`,\n\t\t},\n\t\tentryPaths:    []string{\"entry.ts\"},\n\t\tabsWorkingDir: \"/Users/user/project/src\",\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonConfigDirBaseURL(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport \"foo/bar\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/lib/foo/bar\": `\n\t\t\t\tconsole.log('works')\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"@scope/configs/tsconfig\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/@scope/configs/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \"${configDir}../lib\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonConfigDirPaths(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport \"library/foo/bar\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/lib/foo/bar\": `\n\t\t\t\tconsole.log('works')\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"@scope/configs/tsconfig\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/@scope/configs/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"library/*\": [\"${configDir}../lib/*\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonConfigDirBaseURLInheritedPaths(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.js\": `\n\t\t\t\timport \"library/foo/bar\"\n\t\t\t`,\n\t\t\t\"/Users/user/project/lib/foo/bar\": `\n\t\t\t\tconsole.log('works')\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"@scope/configs/tsconfig\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/node_modules/@scope/configs/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"baseUrl\": \"${configDir}..\",\n\t\t\t\t\t\t\"paths\": {\n\t\t\t\t\t\t\t\"library/*\": [\"./lib/*\"]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/src/entry.js\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\nfunc TestTsconfigJsonExtendsArrayIssue3898(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/index.tsx\": `\n\t\t\t\timport { type SomeType } from 'MUST_KEEP'\n\t\t\t\tconsole.log(<>\n\t\t\t\t\t<div/>\n\t\t\t\t</>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": [\n\t\t\t\t\t\t\"./tsconfigs/a.json\",\n\t\t\t\t\t\t\"./tsconfigs/b.json\",\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfigs/base.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"verbatimModuleSyntax\": true,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfigs/a.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"./base.json\",\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFactory\": \"SUCCESS\",\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfigs/b.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"./base.json\",\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFragmentFactory\": \"WORKS\",\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths: []string{\"/Users/user/project/index.tsx\"},\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModePassThrough,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t\tJSX: config.JSXOptions{\n\t\t\t\tSideEffects: true,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc TestTsconfigDecoratorsUseDefineForClassFieldsFalse(t *testing.T) {\n\ttsconfig_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/src/entry.ts\": `\n\t\t\t\tclass Class {\n\t\t\t\t}\n\t\t\t\tclass ClassMethod {\n\t\t\t\t\tfoo() {}\n\t\t\t\t}\n\t\t\t\tclass ClassField {\n\t\t\t\t\tfoo = 123\n\t\t\t\t\tbar\n\t\t\t\t}\n\t\t\t\tclass ClassAccessor {\n\t\t\t\t\taccessor foo = 123\n\t\t\t\t\taccessor bar\n\t\t\t\t}\n\t\t\t\tnew Class\n\t\t\t\tnew ClassMethod\n\t\t\t\tnew ClassField\n\t\t\t\tnew ClassAccessor\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/entrywithdec.ts\": `\n\t\t\t\t@dec class Class {\n\t\t\t\t}\n\t\t\t\tclass ClassMethod {\n\t\t\t\t\t@dec foo() {}\n\t\t\t\t}\n\t\t\t\tclass ClassField {\n\t\t\t\t\t@dec foo = 123\n\t\t\t\t\t@dec bar\n\t\t\t\t}\n\t\t\t\tclass ClassAccessor {\n\t\t\t\t\t@dec accessor foo = 123\n\t\t\t\t\t@dec accessor bar\n\t\t\t\t}\n\t\t\t\tnew Class\n\t\t\t\tnew ClassMethod\n\t\t\t\tnew ClassField\n\t\t\t\tnew ClassAccessor\n\t\t\t`,\n\t\t\t\"/Users/user/project/src/tsconfig.json\": `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": false\n\t\t\t\t}\n\t\t\t}`,\n\t\t},\n\t\tentryPaths: []string{\n\t\t\t\"/Users/user/project/src/entry.ts\",\n\t\t\t\"/Users/user/project/src/entrywithdec.ts\",\n\t\t},\n\t\toptions: config.Options{\n\t\t\tMode:         config.ModeBundle,\n\t\t\tAbsOutputDir: \"/Users/user/project/out\",\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "internal/bundler_tests/bundler_yarnpnp_test.go",
    "content": "package bundler_tests\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/config\"\n)\n\nvar yarnpnp_suite = suite{\n\tname: \"yarnpnp\",\n}\n\n// https://github.com/evanw/esbuild/issues/3698\nfunc TestTsconfigPackageJsonExportsYarnPnP(t *testing.T) {\n\tyarnpnp_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/packages/app/index.tsx\": `\n\t\t\t\tconsole.log(<div/>)\n\t\t\t`,\n\t\t\t\"/Users/user/project/packages/app/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"tsconfigs/config\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/packages/tsconfigs/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"./config\": \"./configs/tsconfig.json\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/packages/tsconfigs/configs/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFactory\": \"success\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/.pnp.data.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"packageRegistryData\": [\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"app\",\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\"workspace:packages/app\",\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"packageLocation\": \"./packages/app/\",\n\t\t\t\t\t\t\t\t\t\t\"packageDependencies\": [\n\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\"tsconfigs\",\n\t\t\t\t\t\t\t\t\t\t\t\t\"workspace:packages/tsconfigs\"\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\"linkType\": \"SOFT\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t],\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\"tsconfigs\",\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\"workspace:packages/tsconfigs\",\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\"packageLocation\": \"./packages/tsconfigs/\",\n\t\t\t\t\t\t\t\t\t\t\"packageDependencies\": [],\n\t\t\t\t\t\t\t\t\t\t\"linkType\": \"SOFT\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t]\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths:    []string{\"/Users/user/project/packages/app/index.tsx\"},\n\t\tabsWorkingDir: \"/Users/user/project\",\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\n\n// https://github.com/evanw/esbuild/issues/3915\nfunc TestTsconfigStackOverflowYarnPnP(t *testing.T) {\n\tyarnpnp_suite.expectBundled(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"/Users/user/project/entry.jsx\": `\n\t\t\t\tconsole.log(<div />)\n\t\t\t`,\n\t\t\t\"/Users/user/project/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"extends\": \"tsconfigs/config\"\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/packages/tsconfigs/package.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"exports\": {\n\t\t\t\t\t\t\"./config\": \"./configs/tsconfig.json\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/packages/tsconfigs/configs/tsconfig.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\t\"jsxFactory\": \"success\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t`,\n\t\t\t\"/Users/user/project/.pnp.data.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"packageRegistryData\": [\n\t\t\t\t\t\t[null, [\n\t\t\t\t\t\t\t[null, {\n\t\t\t\t\t\t\t\t\"packageLocation\": \"./\",\n\t\t\t\t\t\t\t\t\"packageDependencies\": [\n\t\t\t\t\t\t\t\t\t[\"tsconfigs\", \"virtual:some-path\"]\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"linkType\": \"SOFT\"\n\t\t\t\t\t\t\t}]\n\t\t\t\t\t\t]],\n\t\t\t\t\t\t[\"tsconfigs\", [\n\t\t\t\t\t\t\t[\"virtual:some-path\", {\n\t\t\t\t\t\t\t\t\"packageLocation\": \"./packages/tsconfigs/\",\n\t\t\t\t\t\t\t\t\"packageDependencies\": [\n\t\t\t\t\t\t\t\t\t[\"tsconfigs\", \"virtual:some-path\"]\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"packagePeers\": [],\n\t\t\t\t\t\t\t\t\"linkType\": \"SOFT\"\n\t\t\t\t\t\t\t}],\n\t\t\t\t\t\t\t[\"workspace:packages/tsconfigs\", {\n\t\t\t\t\t\t\t\t\"packageLocation\": \"./packages/tsconfigs/\",\n\t\t\t\t\t\t\t\t\"packageDependencies\": [\n\t\t\t\t\t\t\t\t\t[\"tsconfigs\", \"workspace:packages/tsconfigs\"]\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"linkType\": \"SOFT\"\n\t\t\t\t\t\t\t}]\n\t\t\t\t\t\t]]\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths:    []string{\"/Users/user/project/entry.jsx\"},\n\t\tabsWorkingDir: \"/Users/user/project\",\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"/Users/user/project/out.js\",\n\t\t},\n\t})\n}\nfunc TestWindowsCrossVolumeReferenceYarnPnP(t *testing.T) {\n\tyarnpnp_suite.expectBundledWindows(t, bundled{\n\t\tfiles: map[string]string{\n\t\t\t\"D:\\\\project\\\\entry.jsx\": `\n\t\t\t\timport * as React from 'react'\n\t\t\t\tconsole.log(<div />)\n\t\t\t`,\n\t\t\t\"C:\\\\Users\\\\user\\\\AppData\\\\Local\\\\Yarn\\\\Berry\\\\cache\\\\react.zip\\\\node_modules\\\\react\\\\index.js\": `\n\t\t\t\texport function createElement() {}\n\t\t\t`,\n\t\t\t\"D:\\\\project\\\\.pnp.data.json\": `\n\t\t\t\t{\n\t\t\t\t\t\"packageRegistryData\": [\n\t\t\t\t\t\t[null, [\n\t\t\t\t\t\t\t[null, {\n\t\t\t\t\t\t\t\t\"packageLocation\": \"./\",\n\t\t\t\t\t\t\t\t\"packageDependencies\": [\n\t\t\t\t\t\t\t\t\t[\"react\", \"npm:19.1.1\"],\n\t\t\t\t\t\t\t\t\t[\"project\", \"workspace:.\"]\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"linkType\": \"SOFT\"\n\t\t\t\t\t\t\t}]\n\t\t\t\t\t\t]],\n\t\t\t\t\t\t[\"react\", [\n\t\t\t\t\t\t\t[\"npm:19.1.1\", {\n\t\t\t\t\t\t\t\t\"packageLocation\": \"../../C:/Users/user/AppData/Local/Yarn/Berry/cache/react.zip/node_modules/react/\",\n\t\t\t\t\t\t\t\t\"packageDependencies\": [\n\t\t\t\t\t\t\t\t\t[\"react\", \"npm:19.1.1\"]\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"linkType\": \"HARD\"\n\t\t\t\t\t\t\t}]\n\t\t\t\t\t\t]],\n\t\t\t\t\t\t[\"project\", [\n\t\t\t\t\t\t\t[\"workspace:.\", {\n\t\t\t\t\t\t\t\t\"packageLocation\": \"./\",\n\t\t\t\t\t\t\t\t\"packageDependencies\": [\n\t\t\t\t\t\t\t\t\t[\"react\", \"npm:19.1.1\"],\n\t\t\t\t\t\t\t\t\t[\"project\", \"workspace:.\"]\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\"linkType\": \"SOFT\"\n\t\t\t\t\t\t\t}]\n\t\t\t\t\t\t]]\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t`,\n\t\t},\n\t\tentryPaths:    []string{\"D:\\\\project\\\\entry.jsx\"},\n\t\tabsWorkingDir: \"D:\\\\project\",\n\t\toptions: config.Options{\n\t\t\tMode:          config.ModeBundle,\n\t\t\tAbsOutputFile: \"D:\\\\project\\\\out.js\",\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "internal/bundler_tests/snapshots/snapshots_css.txt",
    "content": "TestBase64ImportURLInCSS\n---------- /out/entry.css ----------\n/* entry.css */\na {\n  background: url(data:image/png;base64,iVBORw0KGgo=);\n}\n\n================================================================================\nTestBinaryImportURLInCSS\n---------- /out/entry.css ----------\n/* entry.css */\na {\n  background: url(data:application/octet-stream;base64,iVBORw0KGgo=);\n}\n\n================================================================================\nTestBundleESMWithNestedVarIssue4348\n---------- /out.js ----------\n// foo.js\nvar foo_exports = {};\n__export(foo_exports, {\n  a: () => a,\n  b: () => b,\n  c: () => c,\n  d: () => d,\n  e: () => e,\n  f: () => f,\n  g: () => g,\n  h: () => h,\n  i: () => i,\n  j: () => j\n});\nvar a, b, c, d, e, x, f, g, h, i, y, j, y;\nvar init_foo = __esm({\n  \"foo.js\"() {\n    a = \"a\";\n    for (b = \"b\"; 0; ) ;\n    if (true) {\n      c = \"c\";\n    }\n    if (true) d = \"d\";\n    if (false) {\n    } else e = \"e\";\n    x = 1;\n    while (x--) f = \"f\";\n    do\n      g = \"g\";\n    while (0);\n    for (; x++; ) h = \"h\";\n    for (y in \"y\") i = \"i\";\n    for (y of \"y\") j = \"j\";\n  }\n});\n\n// entry.js\ninit_foo();\n\n================================================================================\nTestCSSAndJavaScriptCodeSplittingIssue1064\n---------- /out/a.js ----------\nimport {\n  shared_default\n} from \"./chunk-XTGNVFM6.js\";\n\n// a.js\nconsole.log(shared_default() + 1);\n\n---------- /out/b.js ----------\nimport {\n  shared_default\n} from \"./chunk-XTGNVFM6.js\";\n\n// b.js\nconsole.log(shared_default() + 2);\n\n---------- /out/chunk-XTGNVFM6.js ----------\n// shared.js\nfunction shared_default() {\n  return 3;\n}\n\nexport {\n  shared_default\n};\n\n---------- /out/c.css ----------\n/* shared.css */\nbody {\n  background: black;\n}\n\n/* c.css */\nbody {\n  color: red;\n}\n\n---------- /out/d.css ----------\n/* shared.css */\nbody {\n  background: black;\n}\n\n/* d.css */\nbody {\n  color: blue;\n}\n\n================================================================================\nTestCSSAssetPathsWithSpacesBundle\n---------- /foo-AKINYSFH.copy ----------\n...\n---------- /foo-AKINYSFH.file ----------\n...\n---------- /foo 2-AKINYSFH.copy ----------\n...\n---------- /foo 2-AKINYSFH.file ----------\n...\n---------- /out.css ----------\n/* entry.css */\na {\n  background: url(\"./foo-AKINYSFH.copy\");\n  background: url(\"./foo-AKINYSFH.file\");\n}\n/*! The URLs for \"foo 2\" files must have quotes in the final CSS */\nb {\n  background: url(\"./foo 2-AKINYSFH.copy\");\n  background: url(\"./foo 2-AKINYSFH.file\");\n}\n\n================================================================================\nTestCSSAtImport\n---------- /out.css ----------\n/* a.css */\n.a {\n  color: green;\n}\n\n/* shared.css */\n.shared {\n  color: black;\n}\n\n/* b.css */\n.b {\n  color: blue;\n}\n\n/* entry.css */\n.entry {\n  color: red;\n}\n\n================================================================================\nTestCSSAtImportConditionsAtLayerBundle\n---------- /out/case1.css ----------\n@layer first.one;\n\n/* case1-foo.css */\n@layer last.one {\n  body {\n    color: red;\n  }\n}\n\n/* case1-foo.css */\n@layer first.one {\n  body {\n    color: red;\n  }\n}\n\n/* case1.css */\n\n---------- /out/case2.css ----------\n@layer first.one;\n\n/* case2-bar.css */\n@layer last.one {\n  body {\n    color: green;\n  }\n}\n\n/* case2-foo.css */\n@layer first.one {\n  body {\n    color: red;\n  }\n}\n\n/* case2.css */\n\n---------- /out/case3.css ----------\n/* case3-bar.css */\n@layer only.one {\n  body {\n    color: green;\n  }\n}\n\n/* case3-foo.css */\n@layer {\n  body {\n    color: red;\n  }\n}\n\n/* case3.css */\n\n---------- /out/case4.css ----------\n@layer first {\n  @layer one, one.two, one.three.four;\n}\n\n/* case4-foo.css */\n@layer last {\n  @layer one {\n    @layer two, three.four;\n    body {\n      color: red;\n    }\n  }\n}\n\n/* case4-foo.css */\n@layer first {\n  @layer one {\n    @layer two, three.four;\n    body {\n      color: red;\n    }\n  }\n}\n\n/* case4.css */\n\n---------- /out/case5.css ----------\n/* case5-foo.css */\n@layer middle {\n  @layer one {\n    @layer two, three.four;\n    body {\n      color: red;\n    }\n  }\n}\n\n/* case5-foo.css */\n@layer {\n  @layer one {\n    @layer two, three.four;\n    body {\n      color: red;\n    }\n  }\n}\n\n/* case5.css */\n\n---------- /out/case6.css ----------\n@layer first;\n\n/* case6-foo.css */\n@layer last {\n  @layer {\n    @layer two, three.four;\n    body {\n      color: red;\n    }\n  }\n}\n\n/* case6-foo.css */\n@layer first {\n  @layer {\n    @layer two, three.four;\n    body {\n      color: red;\n    }\n  }\n}\n\n/* case6.css */\n\n================================================================================\nTestCSSAtImportConditionsAtLayerBundleAlternatingLayerInFile\n---------- /out/case1.css ----------\n/* a.css */\n@layer first {\n  body {\n    color: red;\n  }\n}\n\n/* case1.css */\n\n---------- /out/case2.css ----------\n@layer first;\n\n/* b.css */\n@layer last {\n  body {\n    color: green;\n  }\n}\n\n/* a.css */\n@layer first {\n  body {\n    color: red;\n  }\n}\n\n/* case2.css */\n\n---------- /out/case3.css ----------\n@layer first, last;\n\n/* a.css */\n@layer first {\n  body {\n    color: red;\n  }\n}\n\n/* b.css */\n@layer last {\n  body {\n    color: green;\n  }\n}\n\n/* case3.css */\n\n---------- /out/case4.css ----------\n@layer first;\n\n/* b.css */\n@layer last {\n  body {\n    color: green;\n  }\n}\n\n/* a.css */\n@layer first {\n  body {\n    color: red;\n  }\n}\n\n/* case4.css */\n\n---------- /out/case5.css ----------\n@layer first, last;\n\n/* a.css */\n@layer first {\n  body {\n    color: red;\n  }\n}\n\n/* b.css */\n@layer last {\n  body {\n    color: green;\n  }\n}\n\n/* case5.css */\n\n---------- /out/case6.css ----------\n@layer first;\n\n/* b.css */\n@layer last {\n  body {\n    color: green;\n  }\n}\n\n/* a.css */\n@layer first {\n  body {\n    color: red;\n  }\n}\n\n/* case6.css */\n\n================================================================================\nTestCSSAtImportConditionsAtLayerBundleAlternatingLayerOnImport\n---------- /out/case1.css ----------\n/* a.css */\n@layer first {\n  body {\n    color: red;\n  }\n}\n\n/* case1.css */\n\n---------- /out/case2.css ----------\n@layer first;\n\n/* b.css */\n@layer last {\n  body {\n    color: green;\n  }\n}\n\n/* a.css */\n@layer first {\n  body {\n    color: red;\n  }\n}\n\n/* case2.css */\n\n---------- /out/case3.css ----------\n@layer first;\n@layer last;\n\n/* a.css */\n@layer first {\n  body {\n    color: red;\n  }\n}\n\n/* b.css */\n@layer last {\n  body {\n    color: green;\n  }\n}\n\n/* case3.css */\n\n---------- /out/case4.css ----------\n@layer first;\n\n/* b.css */\n@layer last {\n  body {\n    color: green;\n  }\n}\n\n/* a.css */\n@layer first {\n  body {\n    color: red;\n  }\n}\n\n/* case4.css */\n\n---------- /out/case5.css ----------\n@layer first;\n@layer last;\n\n/* a.css */\n@layer first {\n  body {\n    color: red;\n  }\n}\n\n/* b.css */\n@layer last {\n  body {\n    color: green;\n  }\n}\n\n/* case5.css */\n\n---------- /out/case6.css ----------\n@layer first;\n\n/* b.css */\n@layer last {\n  body {\n    color: green;\n  }\n}\n\n/* a.css */\n@layer first {\n  body {\n    color: red;\n  }\n}\n\n/* case6.css */\n\n================================================================================\nTestCSSAtImportConditionsBundle\n---------- /out.css ----------\n@import \"http://example.com/foo.css\";\n@import \"http://example.com/foo.css\" layer;\n@import \"http://example.com/foo.css\" layer(layer-name);\n@import \"http://example.com/foo.css\" layer(layer-name) supports(supports-condition);\n@import \"http://example.com/foo.css\" layer(layer-name) list-of-media-queries;\n@import \"http://example.com/foo.css\" supports(supports-condition);\n@import \"http://example.com/foo.css\" list-of-media-queries;\n\n/* foo.css */\nbody {\n  color: red;\n}\n\n/* foo.css */\n@layer {\n  body {\n    color: red;\n  }\n}\n\n/* foo.css */\n@layer layer-name {\n  body {\n    color: red;\n  }\n}\n\n/* foo.css */\n@supports (supports-condition) {\n  @layer layer-name {\n    body {\n      color: red;\n    }\n  }\n}\n\n/* foo.css */\n@media list-of-media-queries {\n  @layer layer-name {\n    body {\n      color: red;\n    }\n  }\n}\n\n/* foo.css */\n@supports (supports-condition) {\n  body {\n    color: red;\n  }\n}\n\n/* foo.css */\n@media list-of-media-queries {\n  body {\n    color: red;\n  }\n}\n\n/* empty-1.css */\n@layer empty-1;\n\n/* empty-2.css */\n\n/* empty-3.css */\n\n/* foo.css */\n@layer outer {\n  @layer inner {\n    body {\n      color: red;\n    }\n  }\n}\n\n/* nested-layer.css */\n@layer outer;\n\n/* foo.css */\n@supports (outer: true) {\n  @layer inner {\n    body {\n      color: red;\n    }\n  }\n}\n\n/* nested-layer.css */\n\n/* foo.css */\n@media (outer: true) {\n  @layer inner {\n    body {\n      color: red;\n    }\n  }\n}\n\n/* nested-layer.css */\n\n/* foo.css */\n@layer outer {\n  @supports (inner: true) {\n    body {\n      color: red;\n    }\n  }\n}\n\n/* nested-supports.css */\n@layer outer;\n\n/* foo.css */\n@supports (outer: true) {\n  @supports (inner: true) {\n    body {\n      color: red;\n    }\n  }\n}\n\n/* nested-supports.css */\n\n/* foo.css */\n@media (outer: true) {\n  @supports (inner: true) {\n    body {\n      color: red;\n    }\n  }\n}\n\n/* nested-supports.css */\n\n/* foo.css */\n@layer outer {\n  @media (inner: true) {\n    body {\n      color: red;\n    }\n  }\n}\n\n/* nested-media.css */\n@layer outer;\n\n/* foo.css */\n@supports (outer: true) {\n  @media (inner: true) {\n    body {\n      color: red;\n    }\n  }\n}\n\n/* nested-media.css */\n\n/* foo.css */\n@media (outer: true) {\n  @media (inner: true) {\n    body {\n      color: red;\n    }\n  }\n}\n\n/* nested-media.css */\n\n/* entry.css */\n\n================================================================================\nTestCSSAtImportConditionsBundleExternal\n---------- /out.css ----------\n@import \"https://example.com/print.css\" print;\n\n/* entry.css */\n\n================================================================================\nTestCSSAtImportConditionsBundleExternalConditionWithURL\n---------- /out.css ----------\n@import \"https://example.com/foo.css\" (foo: url(foo.png)) and (bar: url(bar.png));\n\n/* entry.css */\n\n================================================================================\nTestCSSAtImportConditionsChainExternal\n---------- /out.css ----------\n@import \"http://example.com/external1.css\" layer(a) not print;\n@import 'data:text/css,@import \"http://example.com/external3.css\" layer(b) not tv;' layer(a) not print;\n@import \"data:text/css,@import 'data:text/css,@import \\\"http://example.com/external4.css\\\" layer(b2);' layer(b) not tv;\" layer(a) not print;\n@import 'data:text/css,@import \"http://example.com/external2.css\" layer(a2);' layer(a) not print;\n\n/* b.css */\n@media not print {\n  @layer a {\n    @media not tv {\n      @layer b;\n    }\n  }\n}\n\n/* a.css */\n@media not print {\n  @layer a;\n}\n\n/* entry.css */\n\n================================================================================\nTestCSSAtImportConditionsFromExternalRepo\n---------- /out/001/default/style.css ----------\n/* 001/default/a.css */\n.box {\n  background-color: green;\n}\n\n/* 001/default/style.css */\n\n---------- /out/001/relative-url/style.css ----------\n/* 001/relative-url/a.css */\n.box {\n  background-color: green;\n}\n\n/* 001/relative-url/style.css */\n\n---------- /out/at-charset/001/style.css ----------\n@charset \"UTF-8\";\n\n/* at-charset/001/a.css */\n.box {\n  background-color: red;\n}\n\n/* at-charset/001/b.css */\n.box {\n  background-color: green;\n}\n\n/* at-charset/001/style.css */\n\n---------- /out/at-keyframes/001/style.css ----------\n/* at-keyframes/001/a.css */\n@media screen {\n  .box {\n    animation: BOX;\n    animation-duration: 0s;\n    animation-fill-mode: both;\n  }\n  @keyframes BOX {\n    0%, 100% {\n      background-color: green;\n    }\n  }\n}\n\n/* at-keyframes/001/b.css */\n@media print {\n  .box {\n    animation: BOX;\n    animation-duration: 0s;\n    animation-fill-mode: both;\n  }\n  @keyframes BOX {\n    0%, 100% {\n      background-color: red;\n    }\n  }\n}\n\n/* at-keyframes/001/style.css */\n\n---------- /out/at-layer/001/style.css ----------\n@layer a;\n\n/* at-layer/001/b.css */\n@layer b {\n  .box {\n    background-color: green;\n  }\n}\n\n/* at-layer/001/a.css */\n@layer a {\n  .box {\n    background-color: red;\n  }\n}\n\n/* at-layer/001/style.css */\n\n---------- /out/at-layer/002/style.css ----------\n@media print {\n  @layer a;\n}\n\n/* at-layer/002/b.css */\n@layer b {\n  .box {\n    background-color: red;\n  }\n}\n\n/* at-layer/002/a.css */\n@layer a {\n  .box {\n    background-color: green;\n  }\n}\n\n/* at-layer/002/style.css */\n\n---------- /out/at-layer/003/style.css ----------\n@layer a;\n\n/* at-layer/003/b.css */\n@layer b {\n  .box {\n    background-color: green;\n  }\n}\n\n/* at-layer/003/a.css */\n@layer a {\n  .box {\n    background-color: red;\n  }\n}\n\n/* at-layer/003/style.css */\n\n---------- /out/at-layer/004/style.css ----------\n/* at-layer/004/b.css */\n@layer {\n  .box {\n    background-color: red;\n  }\n}\n\n/* at-layer/004/a.css */\n@layer {\n  .box {\n    background-color: green;\n  }\n}\n\n/* at-layer/004/style.css */\n\n---------- /out/at-layer/005/style.css ----------\n/* at-layer/005/b.css */\n@media (min-width: 1px) {\n  @layer a {\n    @media (width: 1px) {\n      @layer b {\n        .box {\n          background-color: red;\n        }\n      }\n    }\n  }\n}\n\n/* at-layer/005/a.css */\n@media (min-width: 1px) {\n  @layer a;\n}\n\n/* at-layer/005/style.css */\n@layer a.c {\n  .box {\n    background-color: red;\n  }\n}\n@layer a.b {\n  .box {\n    background-color: green;\n  }\n}\n\n---------- /out/at-layer/006/style.css ----------\n/* at-layer/006/b.css */\n@media (min-width: 1px) {\n  @layer a {\n    @media (min-width: 1px) {\n      @layer b {\n        .box {\n          background-color: red;\n        }\n      }\n    }\n  }\n}\n\n/* at-layer/006/a.css */\n@media (min-width: 1px) {\n  @layer a;\n}\n\n/* at-layer/006/style.css */\n@layer a.c {\n  .box {\n    background-color: green;\n  }\n}\n@layer a.b {\n  .box {\n    background-color: red;\n  }\n}\n\n---------- /out/at-layer/007/style.css ----------\n/* at-layer/007/style.css */\n@layer foo {\n}\n@layer bar {\n}\n@layer bar {\n  .box {\n    background-color: green;\n  }\n}\n@layer foo {\n  .box {\n    background-color: red;\n  }\n}\n\n---------- /out/at-layer/008/style.css ----------\n/* at-layer/008/b.css */\n@layer {\n  @layer {\n    .box {\n      background-color: red;\n    }\n  }\n}\n\n/* at-layer/008/a.css */\n@layer {\n  .box {\n    background-color: green;\n  }\n}\n\n/* at-layer/008/style.css */\n\n---------- /out/at-media/001/default/style.css ----------\n/* at-media/001/default/a.css */\n@media screen {\n  .box {\n    background-color: green;\n  }\n}\n\n/* at-media/001/default/style.css */\n\n---------- /out/at-media/002/style.css ----------\n/* at-media/002/a.css */\n@media screen {\n  .box {\n    background-color: green;\n  }\n}\n\n/* at-media/002/b.css */\n@media print {\n  .box {\n    background-color: red;\n  }\n}\n\n/* at-media/002/style.css */\n\n---------- /out/at-media/003/style.css ----------\n/* at-media/003/b.css */\n@media screen {\n  @media (min-width: 1px) {\n    .box {\n      background-color: green;\n    }\n  }\n}\n\n/* at-media/003/a.css */\n\n/* at-media/003/style.css */\n\n---------- /out/at-media/004/style.css ----------\n/* at-media/004/c.css */\n.box {\n  background-color: green;\n}\n\n/* at-media/004/b.css */\n@media print {\n  @media print {\n    .box {\n      background-color: red;\n    }\n  }\n}\n\n/* at-media/004/a.css */\n\n/* at-media/004/style.css */\n\n---------- /out/at-media/005/style.css ----------\n/* at-media/005/c.css */\n.box {\n  background-color: green;\n}\n\n/* at-media/005/b.css */\n@media (max-width: 1px) {\n  @media (max-width: 1px) {\n    .box {\n      background-color: red;\n    }\n  }\n}\n\n/* at-media/005/a.css */\n\n/* at-media/005/style.css */\n\n---------- /out/at-media/006/style.css ----------\n/* at-media/006/b.css */\n@media (min-height: 1px) {\n  @media (min-width: 1px) {\n    .box {\n      background-color: green;\n    }\n  }\n}\n\n/* at-media/006/a.css */\n\n/* at-media/006/style.css */\n\n---------- /out/at-media/007/style.css ----------\n/* at-media/007/b.css */\n@media all {\n  @media screen {\n    .box {\n      background-color: green;\n    }\n  }\n}\n\n/* at-media/007/a.css */\n\n/* at-media/007/style.css */\n\n---------- /out/at-media/008/style.css ----------\n/* at-media/008/green.css */\n@media all {\n  @layer alpha {\n    @media print {\n      @layer alpha {\n        .box {\n          background-color: green;\n        }\n      }\n    }\n  }\n}\n\n/* at-media/008/a.css */\n@media all {\n  @layer alpha;\n}\n\n/* at-media/008/red.css */\n@media all {\n  @layer beta {\n    @media print {\n      @layer beta {\n        .box {\n          background-color: red;\n        }\n      }\n    }\n  }\n}\n\n/* at-media/008/b.css */\n@media all {\n  @layer beta;\n}\n\n/* at-media/008/style.css */\n@layer beta {\n  .box {\n    background-color: green;\n  }\n}\n@layer alpha {\n  .box {\n    background-color: red;\n  }\n}\n\n---------- /out/at-supports/001/style.css ----------\n/* at-supports/001/a.css */\n@supports (display: block) {\n  .box {\n    background-color: green;\n  }\n}\n\n/* at-supports/001/style.css */\n\n---------- /out/at-supports/002/style.css ----------\n/* at-supports/002/b.css */\n@supports (display: block) {\n  @supports (width: 10px) {\n    .box {\n      background-color: green;\n    }\n  }\n}\n\n/* at-supports/002/a.css */\n\n/* at-supports/002/style.css */\n\n---------- /out/at-supports/003/style.css ----------\n/* at-supports/003/b.css */\n@supports ((display: block) or (display: inline)) {\n  @supports (width: 10px) {\n    .box {\n      background-color: green;\n    }\n  }\n}\n\n/* at-supports/003/a.css */\n\n/* at-supports/003/style.css */\n\n---------- /out/at-supports/004/style.css ----------\n/* at-supports/004/b.css */\n@supports (display: block) {\n  @layer a {\n    @supports (width: 10px) {\n      @layer b {\n        .box {\n          background-color: green;\n        }\n      }\n    }\n  }\n}\n\n/* at-supports/004/a.css */\n@supports (display: block) {\n  @layer a;\n}\n\n/* at-supports/004/style.css */\n\n---------- /out/at-supports/005/style.css ----------\n/* at-supports/005/green.css */\n@supports (display: block) {\n  @layer alpha {\n    @supports (foo: bar) {\n      @layer alpha {\n        .box {\n          background-color: green;\n        }\n      }\n    }\n  }\n}\n\n/* at-supports/005/a.css */\n@supports (display: block) {\n  @layer alpha;\n}\n\n/* at-supports/005/red.css */\n@supports (display: block) {\n  @layer beta {\n    @supports (foo: bar) {\n      @layer beta {\n        .box {\n          background-color: red;\n        }\n      }\n    }\n  }\n}\n\n/* at-supports/005/b.css */\n@supports (display: block) {\n  @layer beta;\n}\n\n/* at-supports/005/style.css */\n@layer beta {\n  .box {\n    background-color: green;\n  }\n}\n@layer alpha {\n  .box {\n    background-color: red;\n  }\n}\n\n---------- /out/cycles/001/style.css ----------\n/* cycles/001/style.css */\n.box {\n  background-color: green;\n}\n\n---------- /out/cycles/002/style.css ----------\n/* cycles/002/red.css */\n.box {\n  background-color: red;\n}\n\n/* cycles/002/green.css */\n.box {\n  background-color: green;\n}\n\n/* cycles/002/b.css */\n\n/* cycles/002/a.css */\n\n/* cycles/002/style.css */\n\n---------- /out/cycles/003/style.css ----------\n/* cycles/003/b.css */\n.box {\n  background-color: red;\n}\n\n/* cycles/003/a.css */\n.box {\n  background-color: green;\n}\n\n/* cycles/003/style.css */\n\n---------- /out/cycles/004/style.css ----------\n/* cycles/004/a.css */\n.box {\n  background-color: red;\n}\n\n/* cycles/004/b.css */\n.box {\n  background-color: green;\n}\n\n/* cycles/004/style.css */\n\n---------- /out/cycles/005/style.css ----------\n/* cycles/005/b.css */\n.box {\n  background-color: red;\n}\n\n/* cycles/005/a.css */\n.box {\n  background-color: green;\n}\n\n/* cycles/005/style.css */\n\n---------- /out/cycles/006/style.css ----------\n/* cycles/006/red.css */\n.box {\n  background-color: red;\n}\n\n/* cycles/006/green.css */\n.box {\n  background-color: green;\n}\n\n/* cycles/006/b.css */\n\n/* cycles/006/a.css */\n\n/* cycles/006/c.css */\n\n/* cycles/006/style.css */\n\n---------- /out/cycles/007/style.css ----------\n/* cycles/007/green.css */\n.box {\n  background-color: green;\n}\n\n/* cycles/007/red.css */\n@media all {\n  .box {\n    background-color: red;\n  }\n}\n\n/* cycles/007/a.css */\n\n/* cycles/007/b.css */\n\n/* cycles/007/red.css */\n@media not print {\n  .box {\n    background-color: red;\n  }\n}\n\n/* cycles/007/green.css */\n@media not print {\n  @media screen {\n    .box {\n      background-color: green;\n    }\n  }\n}\n\n/* cycles/007/b.css */\n\n/* cycles/007/a.css */\n\n/* cycles/007/c.css */\n\n/* cycles/007/style.css */\n\n---------- /out/cycles/008/style.css ----------\n/* cycles/008/green.css */\n@layer {\n  .box {\n    background-color: green;\n  }\n}\n\n/* cycles/008/red.css */\n@layer {\n  .box {\n    background-color: red;\n  }\n}\n\n/* cycles/008/a.css */\n\n/* cycles/008/b.css */\n\n/* cycles/008/red.css */\n@layer {\n  @layer {\n    .box {\n      background-color: red;\n    }\n  }\n}\n\n/* cycles/008/green.css */\n@layer {\n  @layer {\n    .box {\n      background-color: green;\n    }\n  }\n}\n\n/* cycles/008/b.css */\n\n/* cycles/008/a.css */\n\n/* cycles/008/c.css */\n\n/* cycles/008/style.css */\n\n---------- /out/data-urls/002/style.css ----------\n/* <data:text/css;plain,.box%20%7B%0A%09background-color%3A%20green%...> */\n.box {\n  background-color: green;\n}\n\n/* data-urls/002/style.css */\n\n---------- /out/data-urls/003/style.css ----------\n/* <data:text/css,.box%20%7B%0A%09background-color%3A%20green%3B%0A%...> */\n.box {\n  background-color: green;\n}\n\n/* data-urls/003/style.css */\n\n---------- /out/duplicates/001/style.css ----------\n/* duplicates/001/b.css */\n.box {\n  background-color: red;\n}\n\n/* duplicates/001/a.css */\n.box {\n  background-color: green;\n}\n\n/* duplicates/001/style.css */\n\n---------- /out/duplicates/002/style.css ----------\n/* duplicates/002/b.css */\n.box {\n  background-color: red;\n}\n\n/* duplicates/002/a.css */\n.box {\n  background-color: green;\n}\n\n/* duplicates/002/style.css */\n\n---------- /out/empty/001/style.css ----------\n/* empty/001/empty.css */\n/* empty/001/style.css */\n.box {\n  background-color: green;\n}\n\n---------- /out/relative-paths/001/style.css ----------\n/* relative-paths/001/b/b.css */\n.box {\n  background-color: green;\n}\n\n/* relative-paths/001/a/a.css */\n\n/* relative-paths/001/style.css */\n\n---------- /out/relative-paths/002/style.css ----------\n/* relative-paths/002/b/b.css */\n.box {\n  background-color: green;\n}\n\n/* relative-paths/002/a/a.css */\n\n/* relative-paths/002/style.css */\n\n---------- /out/subresource/001/style.css ----------\n/* subresource/001/something/styles/green.css */\n.box {\n  background-image: url(data:image/png;base64,Li4u);\n}\n\n/* subresource/001/style.css */\n\n---------- /out/subresource/002/style.css ----------\n/* subresource/002/styles/green.css */\n.box {\n  background-image: url(data:image/png;base64,Li4u);\n}\n\n/* subresource/002/style.css */\n\n---------- /out/subresource/004/style.css ----------\n/* subresource/004/styles/green.css */\n.box {\n  background-image: url(data:image/png;base64,Li4u);\n}\n\n/* subresource/004/style.css */\n\n---------- /out/subresource/005/style.css ----------\n/* subresource/005/styles/green.css */\n.box {\n  background-image: url(data:image/png;base64,Li4u);\n}\n\n/* subresource/005/style.css */\n\n---------- /out/subresource/007/style.css ----------\n/* subresource/007/style.css */\n.box {\n  background-image: url(data:image/png;base64,Li4u);\n}\n\n---------- /out/url-format/001/default/style.css ----------\n/* url-format/001/default/a.css */\n.box {\n  background-color: green;\n}\n\n/* url-format/001/default/style.css */\n\n---------- /out/url-format/001/relative-url/style.css ----------\n/* url-format/001/relative-url/a.css */\n.box {\n  background-color: green;\n}\n\n/* url-format/001/relative-url/style.css */\n\n---------- /out/url-format/002/default/style.css ----------\n/* url-format/002/default/a.css */\n.box {\n  background-color: green;\n}\n\n/* url-format/002/default/style.css */\n\n---------- /out/url-format/002/relative-url/style.css ----------\n/* url-format/002/relative-url/a.css */\n.box {\n  background-color: green;\n}\n\n/* url-format/002/relative-url/style.css */\n\n---------- /out/url-format/003/default/style.css ----------\n/* url-format/003/default/a.css */\n.box {\n  background-color: green;\n}\n\n/* url-format/003/default/style.css */\n\n---------- /out/url-format/003/relative-url/style.css ----------\n/* url-format/003/relative-url/a.css */\n.box {\n  background-color: green;\n}\n\n/* url-format/003/relative-url/style.css */\n\n---------- /out/url-fragments/001/style.css ----------\n/* url-fragments/001/a.css#foo */\n.box {\n  background-color: green;\n}\n\n/* url-fragments/001/style.css */\n\n---------- /out/url-fragments/002/style.css ----------\n/* url-fragments/002/a.css#1 */\n.box {\n  background-color: green;\n}\n\n/* url-fragments/002/b.css#2 */\n.box {\n  background-color: red;\n}\n\n/* url-fragments/002/a.css#3 */\n.box {\n  background-color: green;\n}\n\n/* url-fragments/002/style.css */\n\n================================================================================\nTestCSSAtImportConditionsNoBundle\n---------- /out.css ----------\n@import \"./print.css\" print;\n\n================================================================================\nTestCSSAtImportConditionsWithImportRecordsBundle\n---------- /out.css ----------\n/* foo.css */\n@supports (background: url(a.png)) {\n  body {\n    color: red;\n  }\n}\n\n/* foo.css */\n@media list-of-media-queries {\n  @supports (background: url(b.png)) {\n    body {\n      color: red;\n    }\n  }\n}\n\n/* foo.css */\n@supports (background: url(a.png)) {\n  @layer layer-name {\n    body {\n      color: red;\n    }\n  }\n}\n\n/* foo.css */\n@media list-of-media-queries {\n  @supports (background: url(b.png)) {\n    @layer layer-name {\n      body {\n        color: red;\n      }\n    }\n  }\n}\n\n/* entry.css */\n\n================================================================================\nTestCSSAtImportExtensionOrderCollision\n---------- /out.css ----------\n/* test.css */\n.css {\n  color: red;\n}\n\n/* entry.css */\n\n================================================================================\nTestCSSAtImportExternal\n---------- /out/entry.css ----------\n@charset \"UTF-8\";\n@import \"../external1.css\";\n@import \"../external2.css\";\n@import \"../external4.css\";\n@import \"../external5.css\";\n@import \"https://www.example.com/style2.css\";\n@import \"../external3.css\";\n@import \"https://www.example.com/style1.css\";\n@import \"https://www.example.com/style3.css\";\n@import \"../external5.css\" screen;\n\n/* internal.css */\n.before {\n  color: red;\n}\n\n/* charset1.css */\n.middle {\n  color: green;\n}\n\n/* charset2.css */\n.after {\n  color: blue;\n}\n\n/* entry.css */\n\n================================================================================\nTestCSSAtLayerBeforeImportBundle\n---------- /out/entry.css ----------\n@layer layer1, layer2.layer3;\n\n/* a.css */\n@layer layer4 {\n  a {\n    color: red;\n  }\n}\n\n/* b.css */\n@layer layer5 {\n  b {\n    color: red;\n  }\n}\n\n/* entry.css */\n@layer layer6.layer7, layer8;\n\n================================================================================\nTestCSSAtLayerBeforeImportNoBundle\n---------- /out/entry.css ----------\n@layer layer1, layer2.layer3;\n@import \"a.css\";\n@import \"b.css\";\n@layer layer6.layer7, layer8;\n\n================================================================================\nTestCSSAtLayerMergingWithImportConditions\n---------- /out/entry.css ----------\n@supports (color: first) {\n  @layer a;\n}\n@import \"http://example.com/a.css\" supports(color: first);\n@import \"http://example.com/a.css\" supports(color: second);\n@import \"http://example.com/b.css\" supports(color: second);\n@import \"http://example.com/b.css\" supports(color: first);\n@supports (color: second) {\n  @layer a, b;\n}\n\n/* a.css */\n@supports (color: first) {\n  @layer b;\n}\n\n/* a.css */\n\n/* b.css */\n\n/* b.css */\n\n/* entry.css */\n\n================================================================================\nTestCSSCaseInsensitivity\n---------- /image-AKINYSFH.png ----------\n...\n---------- /out.css ----------\n/* nested.css */\n@media list-of-media-queries {\n  @supports (supports-condition) {\n    @layer layer-name {\n      @KeyFrames Foo {\n        0% {\n          OPAcity: 0;\n        }\n        tO {\n          opaCITY: 1;\n        }\n      }\n      body {\n        BACKGROUND-color: red;\n        width: 50Px;\n        background-IMAGE: url(\"./image-AKINYSFH.png\");\n      }\n    }\n  }\n}\n\n/* entry.css */\n\n================================================================================\nTestCSSEntryPoint\n---------- /out.css ----------\n/* entry.css */\nbody {\n  background: white;\n  color: black;\n}\n\n================================================================================\nTestCSSExternalQueryAndHashMatchIssue1822\n---------- /out.css ----------\n/* entry.css */\na {\n  background: url(foo/bar.png?baz);\n}\nb {\n  background: url(foo/bar.png#baz);\n}\n\n================================================================================\nTestCSSFromJSMissingStarImport\n---------- /out/entry.js ----------\n// entry.js\nconsole.log(void 0);\n\n---------- /out/entry.css ----------\n/* a.css */\n.a {\n  color: red;\n}\n\n================================================================================\nTestCSSMalformedAtImport\n---------- /out/entry.css ----------\n@import \"https://example.com/url-token-eof.css\";\n@import \"https://example.com/url-token-whitespace-eof.css\";\n@import \"https://example.com/function-token-eof.css\";\n@import \"https://example.com/function-token-whitespace-eof.css\";\n\n/* url-token-eof.css */\n\n/* url-token-whitespace-eof.css */\n\n/* function-token-eof.css */\n\n/* function-token-whitespace-eof.css */\n\n/* entry.css */\n\n================================================================================\nTestCSSNestingOldBrowser\n---------- /out/two-type-selectors.css ----------\n/* two-type-selectors.css */\n.c a:is(b) {\n  color: red;\n}\n\n---------- /out/two-parent-selectors.css ----------\n/* two-parent-selectors.css */\n.c :is(a b) {\n  color: red;\n}\n\n---------- /out/only-one-warning.css ----------\n/* only-one-warning.css */\n.a > .a,\n.a > :is(.b .c),\n.a > .d,\n.b .c > .a,\n.b .c > :is(.b .c),\n.b .c > .d,\n.d > .a,\n.d > :is(.b .c),\n.d > .d {\n  color: red;\n}\n\n---------- /out/nested-@layer.css ----------\n/* nested-@layer.css */\n@layer base {\n  a {\n    color: red;\n  }\n}\n\n---------- /out/nested-@media.css ----------\n/* nested-@media.css */\n@media screen {\n  a {\n    color: red;\n  }\n}\n\n---------- /out/nested-ampersand-twice.css ----------\n/* nested-ampersand-twice.css */\na,\na {\n  color: red;\n}\n\n---------- /out/nested-ampersand-first.css ----------\n/* nested-ampersand-first.css */\na,\na b {\n  color: red;\n}\n\n---------- /out/nested-attribute.css ----------\n/* nested-attribute.css */\na [href] {\n  color: red;\n}\n\n---------- /out/nested-colon.css ----------\n/* nested-colon.css */\na :hover {\n  color: red;\n}\n\n---------- /out/nested-dot.css ----------\n/* nested-dot.css */\na .cls {\n  color: red;\n}\n\n---------- /out/nested-greaterthan.css ----------\n/* nested-greaterthan.css */\na > b {\n  color: red;\n}\n\n---------- /out/nested-hash.css ----------\n/* nested-hash.css */\na #id {\n  color: red;\n}\n\n---------- /out/nested-plus.css ----------\n/* nested-plus.css */\na + b {\n  color: red;\n}\n\n---------- /out/nested-tilde.css ----------\n/* nested-tilde.css */\na ~ b {\n  color: red;\n}\n\n---------- /out/toplevel-ampersand-twice.css ----------\n/* toplevel-ampersand-twice.css */\n:scope,\n:scope {\n  color: red;\n}\n\n---------- /out/toplevel-ampersand-first.css ----------\n/* toplevel-ampersand-first.css */\n:scope,\na {\n  color: red;\n}\n\n---------- /out/toplevel-ampersand-second.css ----------\n/* toplevel-ampersand-second.css */\na,\n:scope {\n  color: red;\n}\n\n---------- /out/toplevel-attribute.css ----------\n/* toplevel-attribute.css */\n[href] {\n  color: red;\n}\n\n---------- /out/toplevel-colon.css ----------\n/* toplevel-colon.css */\n:hover {\n  color: red;\n}\n\n---------- /out/toplevel-dot.css ----------\n/* toplevel-dot.css */\n.cls {\n  color: red;\n}\n\n---------- /out/toplevel-greaterthan.css ----------\n/* toplevel-greaterthan.css */\n> b {\n  color: red;\n}\n\n---------- /out/toplevel-hash.css ----------\n/* toplevel-hash.css */\n#id {\n  color: red;\n}\n\n---------- /out/toplevel-plus.css ----------\n/* toplevel-plus.css */\n+ b {\n  color: red;\n}\n\n---------- /out/toplevel-tilde.css ----------\n/* toplevel-tilde.css */\n~ b {\n  color: red;\n}\n\n---------- /out/media-ampersand-twice.css ----------\n/* media-ampersand-twice.css */\n@media screen {\n  :scope,\n  :scope {\n    color: red;\n  }\n}\n\n---------- /out/media-ampersand-first.css ----------\n/* media-ampersand-first.css */\n@media screen {\n  :scope,\n  a {\n    color: red;\n  }\n}\n\n---------- /out/media-ampersand-second.css ----------\n/* media-ampersand-second.css */\n@media screen {\n  a,\n  :scope {\n    color: red;\n  }\n}\n\n---------- /out/media-attribute.css ----------\n/* media-attribute.css */\n@media screen {\n  [href] {\n    color: red;\n  }\n}\n\n---------- /out/media-colon.css ----------\n/* media-colon.css */\n@media screen {\n  :hover {\n    color: red;\n  }\n}\n\n---------- /out/media-dot.css ----------\n/* media-dot.css */\n@media screen {\n  .cls {\n    color: red;\n  }\n}\n\n---------- /out/media-greaterthan.css ----------\n/* media-greaterthan.css */\n@media screen {\n  > b {\n    color: red;\n  }\n}\n\n---------- /out/media-hash.css ----------\n/* media-hash.css */\n@media screen {\n  #id {\n    color: red;\n  }\n}\n\n---------- /out/media-plus.css ----------\n/* media-plus.css */\n@media screen {\n  + b {\n    color: red;\n  }\n}\n\n---------- /out/media-tilde.css ----------\n/* media-tilde.css */\n@media screen {\n  ~ b {\n    color: red;\n  }\n}\n\n---------- /out/page-no-warning.css ----------\n/* page-no-warning.css */\n@page {\n  @top-left {\n    background: red;\n  }\n}\n\n================================================================================\nTestDataURLImportURLInCSS\n---------- /out/entry.css ----------\n/* entry.css */\na {\n  background: url(data:image/png;base64,iVBORw0KGgo=);\n}\n\n================================================================================\nTestDeduplicateRules\n---------- /out/yes0.css ----------\n/* yes0.css */\na {\n  color: green;\n  color: red;\n}\n\n---------- /out/yes1.css ----------\n/* yes1.css */\na {\n  color: green;\n}\na {\n  color: red;\n}\n\n---------- /out/yes2.css ----------\n/* yes2.css */\n@media screen {\n  a {\n    color: red;\n  }\n}\n\n---------- /out/yes3.css ----------\n/* yes3.css */\n@media screen {\n  a {\n    color: red;\n  }\n}\n\n---------- /out/no0.css ----------\n/* no0.css */\n@media screen {\n  a {\n    color: red;\n  }\n}\n@media screen {\n  b a& {\n    color: red;\n  }\n}\n\n---------- /out/no1.css ----------\n/* no1.css */\n@media screen {\n  a {\n    color: red;\n  }\n}\n@media screen {\n  a[x] {\n    color: red;\n  }\n}\n\n---------- /out/no2.css ----------\n/* no2.css */\n@media screen {\n  a {\n    color: red;\n  }\n}\n@media screen {\n  a.x {\n    color: red;\n  }\n}\n\n---------- /out/no3.css ----------\n/* no3.css */\n@media screen {\n  a {\n    color: red;\n  }\n}\n@media screen {\n  a#x {\n    color: red;\n  }\n}\n\n---------- /out/no4.css ----------\n/* no4.css */\n@media screen {\n  a {\n    color: red;\n  }\n}\n@media screen {\n  a:x {\n    color: red;\n  }\n}\n\n---------- /out/no5.css ----------\n/* no5.css */\n@media screen {\n  a:x {\n    color: red;\n  }\n}\n@media screen {\n  a:x(y) {\n    color: red;\n  }\n}\n\n---------- /out/no6.css ----------\n/* no6.css */\n@media screen {\n  a b {\n    color: red;\n  }\n}\n@media screen {\n  a + b {\n    color: red;\n  }\n}\n\n---------- /out/across-files.css ----------\n/* across-files-0.css */\n/* across-files-1.css */\na {\n  color: green;\n}\n\n/* across-files-2.css */\na {\n  color: red;\n}\n\n/* across-files.css */\n\n---------- /out/across-files-url.css ----------\n@import \"http://example.com/some.css\";\n\n/* across-files-url-0.css */\n\n/* across-files-url-1.css */\n@font-face {\n  src: url(http://example.com/some.other.font);\n}\n\n/* across-files-url-2.css */\n@font-face {\n  src: url(http://example.com/some.font);\n}\n\n/* across-files-url.css */\n\n================================================================================\nTestDeduplicateRulesGlobalVsLocalNames\n---------- /out/entry.css ----------\n/* a.css */\nb {\n  color: green;\n}\n.bar {\n  color: green;\n}\n.a_foo {\n  color: red;\n}\n.a_bar {\n  color: green;\n}\ndiv {\n  animation-name: a_anim_local;\n}\n\n/* b.css */\na {\n  color: red;\n}\nb {\n  color: #00f;\n}\n.foo {\n  color: red;\n}\n.bar {\n  color: #00f;\n}\n.b_foo {\n  color: red;\n}\n.b_bar {\n  color: #00f;\n}\ndiv {\n  animation-name: anim_global;\n}\ndiv {\n  animation-name: b_anim_local;\n}\n\n/* entry.css */\n\n================================================================================\nTestExternalImportURLInCSS\n---------- /out/entry.css ----------\n/* src/entry.css */\ndiv:after {\n  content: 'If this is recognized, the path should become \"../src/external.png\"';\n  background: url(../src/external.png);\n}\na {\n  background: url(http://example.com/images/image.png);\n}\nb {\n  background: url(https://example.com/images/image.png);\n}\nc {\n  background: url(//example.com/images/image.png);\n}\nd {\n  background: url(data:image/png;base64,iVBORw0KGgo=);\n}\npath {\n  fill: url(#filter);\n}\n\n================================================================================\nTestFileImportURLInCSS\n---------- /out/example-GDKWWYFY.data ----------\nThis is some data.\n---------- /out/entry.css ----------\n/* one.css */\na {\n  background: url(\"./example-GDKWWYFY.data\");\n}\n\n/* two.css */\nb {\n  background: url(\"./example-GDKWWYFY.data\");\n}\n\n/* entry.css */\n\n================================================================================\nTestIgnoreURLsInAtRulePrelude\n---------- /out/entry.css ----------\n/* entry.css */\n@supports (background: url(ignored.png)) {\n  a {\n    color: red;\n  }\n}\n\n================================================================================\nTestImportCSSFromJSComposes\n---------- /out/entry.js ----------\n// styles.module.css\nvar styles_default = {\n  local0: \"GLOBAL1 GLOBAL2 styles_local4 styles_local3 styles_local1 GLOBAL3 styles_local2 GLOBAL4 styles_local0\",\n  local1: \"styles_local4 styles_local3 styles_local1\",\n  local2: \"styles_local2\",\n  local3: \"styles_local4 styles_local3\",\n  local4: \"styles_local4\",\n  fromOtherFile: \"base_base1 base_base2 other1_local0 base_base3 other2_local0 styles_fromOtherFile\"\n};\n\n// entry.js\nconsole.log(styles_default);\n\n---------- /out/entry.css ----------\n/* global.css */\n.GLOBAL1 {\n  color: black;\n}\n\n/* other1.module.css */\n.other1_local0 {\n  color: blue;\n}\n\n/* base.module.css */\n.base_base1 {\n  cursor: pointer;\n}\n.base_base2 {\n  display: inline;\n}\n.base_base3 {\n  float: left;\n}\n\n/* other2.module.css */\n.other2_local0 {\n  background: purple;\n}\n\n/* styles.module.css */\n.styles_local0 {\n}\n.styles_local0 {\n  background: green;\n}\n.styles_local0 {\n}\n.styles_local3 {\n  border: 1px solid black;\n}\n.styles_local4 {\n  opacity: 0.5;\n}\n.styles_local1 {\n  color: red;\n}\n.styles_fromOtherFile {\n}\n\n================================================================================\nTestImportCSSFromJSComposesCircular\n---------- /out/entry.js ----------\n// styles.css\nvar styles_default = {\n  foo: \"styles_bar styles_foo\",\n  bar: \"styles_foo styles_bar\",\n  baz: \"styles_baz\"\n};\n\n// entry.js\nconsole.log(styles_default);\n\n---------- /out/entry.css ----------\n/* styles.css */\n.styles_foo {\n}\n.styles_bar {\n}\n.styles_baz {\n}\n\n================================================================================\nTestImportCSSFromJSComposesFromCircular\n---------- /out/entry.js ----------\n// styles.css\nvar styles_default = {\n  foo: \"other_bar styles_foo\",\n  bar: \"styles_bar\"\n};\n\n// entry.js\nconsole.log(styles_default);\n\n---------- /out/entry.css ----------\n/* other.css */\n.other_bar {\n}\n\n/* styles.css */\n.styles_foo {\n}\n.styles_bar {\n}\n\n================================================================================\nTestImportCSSFromJSComposesFromUndefined\n---------- /out/entry.js ----------\n// styles.css\nvar styles_default = {};\n\n// entry.js\nconsole.log(styles_default);\n\n---------- /out/entry.css ----------\n/* well-defined.css */\n.well_defined_z1 {\n  zoom: 1;\n}\n.well_defined_z2 {\n  zoom: 2;\n}\n.well_defined_z4 {\n  zoom: 4;\n}\n.well_defined_z3 {\n  zoom: 3;\n}\n.well_defined_z5 {\n}\n\n/* undefined/case1.css */\n.case1_foo {\n  zoom: 2;\n}\n\n/* undefined/case2.css */\n.case2_foo {\n}\n\n/* undefined/case3.css */\n.case3_foo {\n}\n.case3_nested1 {\n  zoom: 3;\n}\n.case3_nested2 {\n}\n\n/* undefined/case4.css */\n.case4_foo {\n}\n.case4_nested1 {\n}\n.case4_nested2 {\n  zoom: 3;\n}\n\n/* file-1.css */\n.file_1_foo {\n  zoom: 1;\n}\n.file_1_bar {\n  zoom: 2;\n}\n\n/* file-2.css */\n.file_2_foo {\n  zoom: 2;\n}\n\n/* undefined/case5.css */\n.case5_foo {\n}\n.case5_nested1 {\n}\n.case5_nested2 {\n}\n\n/* styles.css */\n\n================================================================================\nTestImportCSSFromJSLocalAtContainer\n---------- /out/entry.js ----------\n// styles.css\nvar styles_default = {\n  local: \"styles_local\",\n  local1: \"styles_local1\",\n  local2: \"styles_local2\"\n};\n\n// entry.js\nconsole.log(styles_default);\n\n---------- /out/entry.css ----------\n/* styles.css */\n@container not (max-width: 100px) {\n  div {\n    color: red;\n  }\n}\n@container styles_local (max-width: 100px) {\n  div {\n    color: red;\n  }\n}\n@container styles_local not (max-width: 100px) {\n  div {\n    color: red;\n  }\n}\n@container styles_local (max-width: 100px) or (min-height: 100px) {\n  div {\n    color: red;\n  }\n}\n@container styles_local (max-width: 100px) and (min-height: 100px) {\n  div {\n    color: red;\n  }\n}\n@container general_enclosed(max-width: 100px) {\n  div {\n    color: red;\n  }\n}\n@container styles_local general_enclosed(max-width: 100px) {\n  div {\n    color: red;\n  }\n}\ndiv {\n  container-name: NONE initial;\n}\ndiv {\n  container-name: none INITIAL;\n}\ndiv {\n  container-name: GLOBAL1 GLOBAL2;\n}\ndiv {\n  container-name: styles_local1 styles_local2;\n}\ndiv {\n  container: none;\n}\ndiv {\n  container: NONE;\n}\ndiv {\n  container: NONE / size;\n}\ndiv {\n  container: none / size;\n}\ndiv {\n  container: GLOBAL1 GLOBAL2;\n}\ndiv {\n  container: styles_local1 styles_local2;\n}\ndiv {\n  container: GLOBAL1 GLOBAL2 / size;\n}\ndiv {\n  container: styles_local1 styles_local2 / size;\n}\n\n================================================================================\nTestImportCSSFromJSLocalAtCounterStyle\n---------- /out/entry.js ----------\n// list_style_type.css\nvar list_style_type_default = {\n  local: \"list_style_type_local\"\n};\n\n// list_style.css\nvar list_style_default = {\n  local: \"list_style_local\",\n  inside: \"list_style_inside\",\n  outside: \"list_style_outside\"\n};\n\n// entry.js\nconsole.log(list_style_type_default, list_style_default);\n\n---------- /out/entry.css ----------\n/* list_style_type.css */\n@counter-style list_style_type_local {\n  symbols: A B C;\n}\ndiv {\n  list-style-type: GLOBAL;\n}\ndiv {\n  list-style-type: list_style_type_local;\n}\ndiv {\n  list-style-type: none;\n}\ndiv {\n  list-style-type: INITIAL;\n}\ndiv {\n  list-style-type: decimal;\n}\ndiv {\n  list-style-type: disc;\n}\ndiv {\n  list-style-type: SQUARE;\n}\ndiv {\n  list-style-type: circle;\n}\ndiv {\n  list-style-type: disclosure-OPEN;\n}\ndiv {\n  list-style-type: DISCLOSURE-closed;\n}\ndiv {\n  list-style-type: LAO;\n}\ndiv {\n  list-style-type: \"👍\";\n}\n\n/* list_style.css */\n@counter-style list_style_local {\n  symbols: A B C;\n}\ndiv {\n  list-style: GLOBAL;\n}\ndiv {\n  list-style: list_style_local;\n}\ndiv {\n  list-style: list_style_local none;\n}\ndiv {\n  list-style: list_style_local url(http://);\n}\ndiv {\n  list-style: list_style_local linear-gradient(red, green);\n}\ndiv {\n  list-style: list_style_local inside;\n}\ndiv {\n  list-style: list_style_local outside;\n}\ndiv {\n  list-style: none list_style_local;\n}\ndiv {\n  list-style: url(http://) list_style_local;\n}\ndiv {\n  list-style: linear-gradient(red, green) list_style_local;\n}\ndiv {\n  list-style: list_style_local inside;\n}\ndiv {\n  list-style: list_style_local outside;\n}\ndiv {\n  list-style: inside list_style_inside;\n}\ndiv {\n  list-style: inside list_style_outside;\n}\ndiv {\n  list-style: outside list_style_inside;\n}\ndiv {\n  list-style: outside list_style_outside;\n}\ndiv {\n  list-style: url(http://) none invalid;\n}\ndiv {\n  list-style: linear-gradient(red, green) none invalid;\n}\ndiv {\n  list-style: INITIAL;\n}\ndiv {\n  list-style: decimal;\n}\ndiv {\n  list-style: disc;\n}\ndiv {\n  list-style: SQUARE;\n}\ndiv {\n  list-style: circle;\n}\ndiv {\n  list-style: disclosure-OPEN;\n}\ndiv {\n  list-style: DISCLOSURE-closed;\n}\ndiv {\n  list-style: LAO;\n}\n\n================================================================================\nTestImportCSSFromJSLocalAtKeyframes\n---------- /out/entry.js ----------\n// styles.css\nvar styles_default = {\n  local_name: \"styles_local_name\",\n  local_name1: \"styles_local_name1\",\n  local_name2: \"styles_local_name2\",\n  none: \"styles_none\"\n};\n\n// entry.js\nconsole.log(styles_default);\n\n---------- /out/entry.css ----------\n/* styles.css */\n@keyframes styles_local_name {\n  to {\n    color: red;\n  }\n}\ndiv {\n  animation-name: none;\n}\ndiv {\n  animation-name: none;\n}\ndiv {\n  animation-name: global_name;\n}\ndiv {\n  animation-name: styles_local_name;\n}\ndiv {\n  animation-name:\n    global_name1,\n    none,\n    global_name2,\n    Inherit,\n    INITIAL,\n    revert,\n    revert-layer,\n    unset;\n}\ndiv {\n  animation-name:\n    styles_local_name1,\n    none,\n    styles_local_name2,\n    Inherit,\n    INITIAL,\n    revert,\n    revert-layer,\n    unset;\n}\ndiv {\n  animation: 2s infinite global_name;\n}\ndiv {\n  animation: 2s infinite styles_local_name;\n}\n@keyframes styles_none {\n  to {\n    color: red;\n  }\n}\ndiv {\n  animation-name: \"none\";\n}\ndiv {\n  animation-name: styles_none;\n}\n\n================================================================================\nTestImportCSSFromJSLocalVsGlobal\n---------- /out/entry.js ----------\n// normal.css\nvar normal_default = {};\n\n// LOCAL.global-css\nvar LOCAL_default = {\n  local: \"LOCAL_local\",\n  local_a: \"LOCAL_local_a\",\n  local_b: \"LOCAL_local_b\",\n  local_c: \"LOCAL_local_c\"\n};\n\n// LOCAL.local-css\nvar LOCAL_default2 = {\n  top_level: \"LOCAL_top_level\",\n  local: \"LOCAL_local2\",\n  local_a: \"LOCAL_local_a2\",\n  local_b: \"LOCAL_local_b2\",\n  local_c: \"LOCAL_local_c2\",\n  nested: \"LOCAL_nested\"\n};\n\n// entry.js\nconsole.log(\"should be empty:\", normal_default);\nconsole.log(\"fewer local names:\", LOCAL_default);\nconsole.log(\"more local names:\", LOCAL_default2);\n\n---------- /out/entry.css ----------\n/* normal.css */\n.top_level {\n  color: #000;\n}\n:global(.GLOBAL) {\n  color: #001;\n}\n:local(.local) {\n  color: #002;\n}\ndiv:global(.GLOBAL) {\n  color: #003;\n}\ndiv:local(.local) {\n  color: #004;\n}\n.top_level:global(div) {\n  color: #005;\n}\n.top_level:local(div) {\n  color: #006;\n}\n:global(div.GLOBAL) {\n  color: #007;\n}\n:local(div.local) {\n  color: #008;\n}\ndiv:global(span.GLOBAL) {\n  color: #009;\n}\ndiv:local(span.local) {\n  color: #00A;\n}\ndiv:global(#GLOBAL_A.GLOBAL_B.GLOBAL_C):local(.local_a.local_b#local_c) {\n  color: #00B;\n}\ndiv:global(#GLOBAL_A .GLOBAL_B .GLOBAL_C):local(.local_a .local_b #local_c) {\n  color: #00C;\n}\n.nested {\n  :global(&.GLOBAL) {\n    color: #00D;\n  }\n  :local(&.local) {\n    color: #00E;\n  }\n  &:global(.GLOBAL) {\n    color: #00F;\n  }\n  &:local(.local) {\n    color: #010;\n  }\n}\n:global(.GLOBAL_A .GLOBAL_B) {\n  color: #011;\n}\n:local(.local_a .local_b) {\n  color: #012;\n}\ndiv:global(.GLOBAL_A .GLOBAL_B):hover {\n  color: #013;\n}\ndiv:local(.local_a .local_b):hover {\n  color: #014;\n}\ndiv :global(.GLOBAL_A .GLOBAL_B) span {\n  color: #015;\n}\ndiv :local(.local_a .local_b) span {\n  color: #016;\n}\ndiv > :global(.GLOBAL_A ~ .GLOBAL_B) + span {\n  color: #017;\n}\ndiv > :local(.local_a ~ .local_b) + span {\n  color: #018;\n}\ndiv:global(+ .GLOBAL_A):hover {\n  color: #019;\n}\ndiv:local(+ .local_a):hover {\n  color: #01A;\n}\n:global.GLOBAL:local.local {\n  color: #01B;\n}\n:global .GLOBAL :local .local {\n  color: #01C;\n}\n:global {\n  .GLOBAL {\n    before: outer;\n    :local {\n      before: inner;\n      .local {\n        color: #01D;\n      }\n      after: inner;\n    }\n    after: outer;\n  }\n}\n\n/* LOCAL.global-css */\n.top_level {\n  color: #000;\n}\n.GLOBAL {\n  color: #001;\n}\n.LOCAL_local {\n  color: #002;\n}\ndiv.GLOBAL {\n  color: #003;\n}\ndiv.LOCAL_local {\n  color: #004;\n}\ndiv.top_level {\n  color: #005;\n}\ndiv.top_level {\n  color: #006;\n}\ndiv.GLOBAL {\n  color: #007;\n}\ndiv.LOCAL_local {\n  color: #008;\n}\ndiv:is(span).GLOBAL {\n  color: #009;\n}\ndiv:is(span).LOCAL_local {\n  color: #00A;\n}\ndiv#GLOBAL_A.GLOBAL_B.GLOBAL_C.LOCAL_local_a.LOCAL_local_b#LOCAL_local_c {\n  color: #00B;\n}\ndiv#GLOBAL_A .GLOBAL_B .GLOBAL_C.LOCAL_local_a .LOCAL_local_b #LOCAL_local_c {\n  color: #00C;\n}\n.nested {\n  &.GLOBAL {\n    color: #00D;\n  }\n  &.LOCAL_local {\n    color: #00E;\n  }\n  &.GLOBAL {\n    color: #00F;\n  }\n  &.LOCAL_local {\n    color: #010;\n  }\n}\n.GLOBAL_A .GLOBAL_B {\n  color: #011;\n}\n.LOCAL_local_a .LOCAL_local_b {\n  color: #012;\n}\ndiv.GLOBAL_A .GLOBAL_B:hover {\n  color: #013;\n}\ndiv.LOCAL_local_a .LOCAL_local_b:hover {\n  color: #014;\n}\ndiv .GLOBAL_A .GLOBAL_B span {\n  color: #015;\n}\ndiv .LOCAL_local_a .LOCAL_local_b span {\n  color: #016;\n}\ndiv > .GLOBAL_A ~ .GLOBAL_B + span {\n  color: #017;\n}\ndiv > .LOCAL_local_a ~ .LOCAL_local_b + span {\n  color: #018;\n}\ndiv + .GLOBAL_A:hover {\n  color: #019;\n}\ndiv + .LOCAL_local_a:hover {\n  color: #01A;\n}\n.GLOBAL.LOCAL_local {\n  color: #01B;\n}\n.GLOBAL .LOCAL_local {\n  color: #01C;\n}\n& {\n  .GLOBAL {\n    before: outer;\n    before: inner;\n    .LOCAL_local {\n      color: #01D;\n    }\n    after: inner;\n    after: outer;\n  }\n}\n\n/* LOCAL.local-css */\n.LOCAL_top_level {\n  color: #000;\n}\n.GLOBAL {\n  color: #001;\n}\n.LOCAL_local2 {\n  color: #002;\n}\ndiv.GLOBAL {\n  color: #003;\n}\ndiv.LOCAL_local2 {\n  color: #004;\n}\ndiv.LOCAL_top_level {\n  color: #005;\n}\ndiv.LOCAL_top_level {\n  color: #006;\n}\ndiv.GLOBAL {\n  color: #007;\n}\ndiv.LOCAL_local2 {\n  color: #008;\n}\ndiv:is(span).GLOBAL {\n  color: #009;\n}\ndiv:is(span).LOCAL_local2 {\n  color: #00A;\n}\ndiv#GLOBAL_A.GLOBAL_B.GLOBAL_C.LOCAL_local_a2.LOCAL_local_b2#LOCAL_local_c2 {\n  color: #00B;\n}\ndiv#GLOBAL_A .GLOBAL_B .GLOBAL_C.LOCAL_local_a2 .LOCAL_local_b2 #LOCAL_local_c2 {\n  color: #00C;\n}\n.LOCAL_nested {\n  &.GLOBAL {\n    color: #00D;\n  }\n  &.LOCAL_local2 {\n    color: #00E;\n  }\n  &.GLOBAL {\n    color: #00F;\n  }\n  &.LOCAL_local2 {\n    color: #010;\n  }\n}\n.GLOBAL_A .GLOBAL_B {\n  color: #011;\n}\n.LOCAL_local_a2 .LOCAL_local_b2 {\n  color: #012;\n}\ndiv.GLOBAL_A .GLOBAL_B:hover {\n  color: #013;\n}\ndiv.LOCAL_local_a2 .LOCAL_local_b2:hover {\n  color: #014;\n}\ndiv .GLOBAL_A .GLOBAL_B span {\n  color: #015;\n}\ndiv .LOCAL_local_a2 .LOCAL_local_b2 span {\n  color: #016;\n}\ndiv > .GLOBAL_A ~ .GLOBAL_B + span {\n  color: #017;\n}\ndiv > .LOCAL_local_a2 ~ .LOCAL_local_b2 + span {\n  color: #018;\n}\ndiv + .GLOBAL_A:hover {\n  color: #019;\n}\ndiv + .LOCAL_local_a2:hover {\n  color: #01A;\n}\n.GLOBAL.LOCAL_local2 {\n  color: #01B;\n}\n.GLOBAL .LOCAL_local2 {\n  color: #01C;\n}\n& {\n  .GLOBAL {\n    before: outer;\n    before: inner;\n    .LOCAL_local2 {\n      color: #01D;\n    }\n    after: inner;\n    after: outer;\n  }\n}\n\n================================================================================\nTestImportCSSFromJSLowerBareLocalAndGlobal\n---------- /out/entry.js ----------\n// styles.css\nvar styles_default = {\n  before: \"styles_before\",\n  button: \"styles_button\",\n  after: \"styles_after\"\n};\n\n// entry.js\nconsole.log(styles_default);\n\n---------- /out/entry.css ----------\n/* styles.css */\n.styles_before {\n  color: #000;\n}\n:scope .styles_button {\n  color: #000;\n}\n.styles_after {\n  color: #000;\n}\n.styles_before {\n  color: #001;\n}\n:scope .button {\n  color: #001;\n}\n.styles_after {\n  color: #001;\n}\ndiv .styles_button {\n  color: #002;\n}\ndiv .button {\n  color: #003;\n}\n:scope {\n  color: #004;\n}\n:scope {\n  color: #005;\n}\n:scope .styles_button {\n  color: #006;\n}\n:scope .styles_button {\n  color: #007;\n}\n\n================================================================================\nTestImportCSSFromJSNthIndexLocal\n---------- /out/entry.js ----------\n// styles.css\nvar styles_default = {\n  local: \"styles_local\",\n  local1: \"styles_local1\",\n  local2: \"styles_local2\"\n};\n\n// entry.js\nconsole.log(styles_default);\n\n---------- /out/entry.css ----------\n/* styles.css */\n:nth-child(2n of .styles_local) {\n  color: #000;\n}\n:nth-child(2n of #styles_local, .GLOBAL) {\n  color: #001;\n}\n:nth-child(2n of .styles_local1 .GLOBAL1, .GLOBAL2 .styles_local2) {\n  color: #002;\n}\n.styles_local1,\n:nth-child(2n of .GLOBAL),\n.styles_local2 {\n  color: #003;\n}\n:nth-last-child(2n of .styles_local) {\n  color: #000;\n}\n:nth-last-child(2n of #styles_local, .GLOBAL) {\n  color: #001;\n}\n:nth-last-child(2n of .styles_local1 .GLOBAL1, .GLOBAL2 .styles_local2) {\n  color: #002;\n}\n.styles_local1,\n:nth-last-child(2n of .GLOBAL),\n.styles_local2 {\n  color: #003;\n}\n\n================================================================================\nTestImportGlobalCSSFromJS\n---------- /out/entry.js ----------\n// a.css\nvar a_default = {};\n\n// a.js\nconsole.log(\"a\", void 0, a_default.a);\n\n// b.css\nvar b_default = {};\n\n// b.js\nconsole.log(\"b\", void 0, b_default.b);\n\n---------- /out/entry.css ----------\n/* a.css */\n.a {\n  color: red;\n}\n\n/* b.css */\n.b {\n  color: blue;\n}\n\n================================================================================\nTestImportLocalCSSFromJS\n---------- /out/entry.js ----------\n// dir1/style.css\nvar button = \"style_button\";\nvar style_default = {\n  a: \"style_a\",\n  button\n};\n\n// a.js\nconsole.log(\"file 1\", button, style_default.a);\n\n// dir2/style.css\nvar button2 = \"style_button2\";\nvar style_default2 = {\n  b: \"style_b\",\n  button: button2\n};\n\n// b.js\nconsole.log(\"file 2\", button2, style_default2.b);\n\n---------- /out/entry.css ----------\n/* dir1/style.css */\n.style_a {\n  color: red;\n}\n.style_button {\n  display: none;\n}\n\n/* dir2/style.css */\n.style_b {\n  color: blue;\n}\n.style_button2 {\n  display: none;\n}\n\n================================================================================\nTestImportLocalCSSFromJSMinifyIdentifiers\n---------- /out/entry.js ----------\n// dir1/style.css\nvar t = \"l\";\nvar l = {\n  a: \"o\",\n  button: t\n};\n\n// a.js\nconsole.log(\"file 1\", t, l.a);\n\n// dir2/style.css\nvar e = \"n\";\nvar n = {\n  b: \"e\",\n  button: e\n};\n\n// b.js\nconsole.log(\"file 2\", e, n.b);\n\n---------- /out/entry.css ----------\n/* dir1/style.css */\n.o {\n  color: red;\n}\n.l {\n  display: none;\n}\n\n/* dir2/style.css */\n.e {\n  color: blue;\n}\n.n {\n  display: none;\n}\n\n================================================================================\nTestImportLocalCSSFromJSMinifyIdentifiersAvoidGlobalNames\n---------- /out/entry.js ----------\n\n---------- /out/entry.css ----------\n/* global.css */\n:is(.a, .b, .c, .d, .e, .f, .g, .h, .i, .j, .k, .l, .m, .n, .o, .p, .q, .r, .s, .t, .u, .v, .w, .x, .y, .z),\n:is(.A, .B, .C, .D, .E, .F, .G, .H, .I, .J, .K, .L, .M, .N, .O, .P, .Q, .R, .S, .T, .U, .V, .W, .X, .Y, .Z),\n._ {\n  color: red;\n}\n\n/* local.module.css */\n.oo {\n  color: blue;\n}\n\n================================================================================\nTestImportLocalCSSFromJSMinifyIdentifiersMultipleEntryPoints\n---------- /out/a.js ----------\n// a.module.css\nvar r = \"o\";\nvar l = \"c\";\n\n// a.js\nconsole.log(r, l);\n\n---------- /out/a.css ----------\n/* a.module.css */\n.o {\n  color: #001;\n}\n.c {\n  color: #002;\n}\n\n---------- /out/b.js ----------\n// b.module.css\nvar r = \"l\";\nvar l = \"r\";\n\n// b.js\nconsole.log(r, l);\n\n---------- /out/b.css ----------\n/* b.module.css */\n.l {\n  color: #003;\n}\n.r {\n  color: #004;\n}\n\n================================================================================\nTestMetafileCSSBundleTwoToOne\n---------- /out/js/2PSDKYWE.js ----------\n// foo/entry.js\nconsole.log(\"foo\");\n\n---------- /out/css/DIO3TRUB.css ----------\n/* common.css */\nbody {\n  color: red;\n}\n\n---------- /out/js/MA6C7ZBK.js ----------\n// bar/entry.js\nconsole.log(\"bar\");\n---------- metafile.json ----------\n{\n  \"inputs\": {\n    \"common.css\": {\n      \"bytes\": 28,\n      \"imports\": []\n    },\n    \"foo/entry.js\": {\n      \"bytes\": 54,\n      \"imports\": [\n        {\n          \"path\": \"common.css\",\n          \"kind\": \"import-statement\",\n          \"original\": \"../common.css\"\n        }\n      ],\n      \"format\": \"esm\"\n    },\n    \"bar/entry.js\": {\n      \"bytes\": 54,\n      \"imports\": [\n        {\n          \"path\": \"common.css\",\n          \"kind\": \"import-statement\",\n          \"original\": \"../common.css\"\n        }\n      ],\n      \"format\": \"esm\"\n    }\n  },\n  \"outputs\": {\n    \"out/js/2PSDKYWE.js\": {\n      \"imports\": [],\n      \"exports\": [],\n      \"entryPoint\": \"foo/entry.js\",\n      \"cssBundle\": \"out/css/DIO3TRUB.css\",\n      \"inputs\": {\n        \"common.css\": {\n          \"bytesInOutput\": 0\n        },\n        \"foo/entry.js\": {\n          \"bytesInOutput\": 20\n        }\n      },\n      \"bytes\": 36\n    },\n    \"out/css/DIO3TRUB.css\": {\n      \"imports\": [],\n      \"inputs\": {\n        \"common.css\": {\n          \"bytesInOutput\": 23\n        }\n      },\n      \"bytes\": 40\n    },\n    \"out/js/MA6C7ZBK.js\": {\n      \"imports\": [],\n      \"exports\": [],\n      \"entryPoint\": \"bar/entry.js\",\n      \"cssBundle\": \"out/css/DIO3TRUB.css\",\n      \"inputs\": {\n        \"common.css\": {\n          \"bytesInOutput\": 0\n        },\n        \"bar/entry.js\": {\n          \"bytesInOutput\": 20\n        }\n      },\n      \"bytes\": 36\n    }\n  }\n}\n\n================================================================================\nTestPackageURLsInCSS\n---------- /out/entry.css ----------\n/* test.css */\n.css {\n  color: red;\n}\n\n/* entry.css */\na {\n  background: url(data:image/png;base64,YS0x);\n}\nb {\n  background: url(data:image/png;base64,Yi0yLW5vZGVfbW9kdWxlcw==);\n}\nc {\n  background: url(data:image/png;base64,Yy0z);\n}\n\n================================================================================\nTestResolveExtensionsOrderIssue4053\n---------- /out.js ----------\n// Test.web.tsx\nvar Test_web_default = \"Test.web.tsx\";\n\n// node_modules/expo-image/Image.web.tsx\nvar Image_web_default = \"Image.web.tsx\";\n\n// entry.js\nconsole.log(Test_web_default === \"Test.web.tsx\");\nconsole.log(Image_web_default === \"Image.web.tsx\");\n\n================================================================================\nTestTextImportURLInCSSText\n---------- /out/entry.css ----------\n/* entry.css */\na {\n  background: url(data:text/plain;base64,VGhpcyBpcyBzb21lIHRleHQu);\n}\n\n================================================================================\nTestUndefinedImportWarningCSS\n---------- /out/entry.js ----------\n// empty.js\nvar require_empty = __commonJS({\n  \"empty.js\"() {\n  }\n});\n\n// node_modules/pkg/empty.js\nvar require_empty2 = __commonJS({\n  \"node_modules/pkg/empty.js\"() {\n  }\n});\n\n// entry.js\nvar empty_js2 = __toESM(require_empty());\nvar pkg_empty_js = __toESM(require_empty2());\n\n// node_modules/pkg/index.js\nvar empty_js = __toESM(require_empty2());\nconsole.log(\n  void 0,\n  void 0,\n  void 0,\n  void 0,\n  void 0,\n  void 0\n);\n\n// entry.js\nconsole.log(\n  void 0,\n  void 0,\n  void 0,\n  void 0,\n  void 0,\n  void 0\n);\nconsole.log(\n  void 0,\n  void 0,\n  void 0,\n  void 0,\n  void 0,\n  void 0\n);\n\n---------- /out/entry.css ----------\n/* empty.css */\n/* empty.global-css */\n/* empty.local-css */\n/* node_modules/pkg/empty.css */\n/* node_modules/pkg/empty.global-css */\n/* node_modules/pkg/empty.local-css */\n"
  },
  {
    "path": "internal/bundler_tests/snapshots/snapshots_dce.txt",
    "content": "TestBase64LoaderRemoveUnused\n---------- /out.js ----------\n// entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestConstValueInliningBundle\n---------- /out/exported-entry.js ----------\n// exported-entry.js\nvar y_keep = 2;\nconsole.log(\n  1,\n  2\n);\nexport {\n  y_keep\n};\n\n---------- /out/re-exported-entry.js ----------\n// re-exported-constants.js\nvar y_keep = 2;\n\n// re-exported-entry.js\nconsole.log(1, 2);\nexport {\n  y_keep\n};\n\n---------- /out/re-exported-2-entry.js ----------\n// re-exported-2-constants.js\nvar y_keep = 2;\nexport {\n  y_keep\n};\n\n---------- /out/re-exported-star-entry.js ----------\n// re-exported-star-constants.js\nvar x_keep = 1, y_keep = 2;\nexport {\n  x_keep,\n  y_keep\n};\n\n---------- /out/cross-module-entry.js ----------\n// cross-module-constants.js\nfoo();\nvar y_keep = 1;\nfunction foo() {\n  return [1, y_keep];\n}\n\n// cross-module-entry.js\nconsole.log(1, y_keep);\n\n---------- /out/print-shorthand-entry.js ----------\n// print-shorthand-entry.js\nconsole.log({ foo: 123, a: -321 });\n\n---------- /out/circular-import-entry.js ----------\n// circular-import-cycle.js\nconsole.log(bar());\n\n// circular-import-constants.js\nvar foo = 123;\nfunction bar() {\n  return foo;\n}\n\n---------- /out/circular-re-export-entry.js ----------\n// circular-re-export-cycle.js\nvar baz = 0;\nconsole.log(bar());\n\n// circular-re-export-constants.js\nvar foo = 123;\nfunction bar() {\n  return foo;\n}\n\n// circular-re-export-entry.js\nconsole.log(baz);\n\n---------- /out/circular-re-export-star-entry.js ----------\n// circular-re-export-star-cycle.js\nconsole.log(bar());\n\n// circular-re-export-star-constants.js\nvar foo = 123;\nfunction bar() {\n  return foo;\n}\n\n---------- /out/non-circular-export-entry.js ----------\n// non-circular-export-constants.js\nfunction bar() {\n  return 123;\n}\n\n// non-circular-export-entry.js\nconsole.log(123, bar());\n\n================================================================================\nTestConstValueInliningDirectEval\n---------- /out/top-level-no-eval.js ----------\nconst x = 1;\nconsole.log(1, evil(\"x\"));\n\n---------- /out/top-level-eval.js ----------\nconst x = 1;\nconsole.log(1, eval(\"x\"));\n\n---------- /out/nested-no-eval.js ----------\nconsole.log(1, evil(\"x\"));\n\n---------- /out/nested-eval.js ----------\n(() => {\n  const x = 1;\n  console.log(1, eval(\"x\"));\n})();\n\n---------- /out/ts-namespace-no-eval.js ----------\nvar y;\n((y2) => (y2.x = 1, console.log(1, evil(\"x\"))))(y ||= {});\n\n---------- /out/ts-namespace-eval.js ----------\nvar z;\n((z) => (z.x = 1, console.log(1, eval(\"x\"))))(z ||= {});\n\n---------- /out/issue-4055.js ----------\nconst variable = !1;\n(function() {\n  eval(\"var variable = true\"), console.log(variable);\n})();\n\n================================================================================\nTestConstValueInliningNoBundle\n---------- /out/top-level.js ----------\nconst n_keep = null, u_keep = void 0, i_keep = 1234567, f_keep = 123.456, s_keep = \"abc\";\nconsole.log(\n  // These are doubled to avoid the \"inline const/let into next statement if used once\" optimization\n  null,\n  null,\n  void 0,\n  void 0,\n  1234567,\n  1234567,\n  123.456,\n  123.456,\n  \"abc\",\n  \"abc\"\n);\n\n---------- /out/nested-block.js ----------\n{\n  const s_keep = \"Long strings are not inlined as constants\";\n  console.log(\n    // These are doubled to avoid the \"inline const/let into next statement if used once\" optimization\n    null,\n    null,\n    void 0,\n    void 0,\n    1234567,\n    1234567,\n    123.456,\n    123.456,\n    \"abc\",\n    \"abc\",\n    s_keep,\n    s_keep\n  );\n}\n\n---------- /out/nested-function.js ----------\nfunction nested() {\n  const s_keep = \"Long strings are not inlined as constants\";\n  console.log(\n    // These are doubled to avoid the \"inline const/let into next statement if used once\" optimization\n    null,\n    null,\n    void 0,\n    void 0,\n    1234567,\n    1234567,\n    123.456,\n    123.456,\n    \"abc\",\n    \"abc\",\n    s_keep,\n    s_keep\n  );\n}\n\n---------- /out/namespace-export.js ----------\nvar ns;\n((ns2) => (ns2.y_keep = 2, console.log(\n  1,\n  1,\n  2,\n  2\n)))(ns ||= {});\n\n---------- /out/comment-before.js ----------\n{\n  //! comment\n  x = [1, 1];\n}\n\n---------- /out/directive-before.js ----------\nfunction nested() {\n  \"directive\";\n  x = [1, 1];\n}\n\n---------- /out/semicolon-before.js ----------\nx = [1, 1];\n\n---------- /out/debugger-before.js ----------\n{\n  debugger;\n  x = [1, 1];\n}\n\n---------- /out/type-before.js ----------\nx = [1, 1];\n\n---------- /out/exprs-before.js ----------\nfunction nested() {\n  const x = [, \"\", {}, 0n, /./, function() {\n  }, () => {\n  }];\n  function foo() {\n    return 1;\n  }\n}\n\n---------- /out/disabled-tdz.js ----------\nfoo();\nconst x_keep = 1;\nfunction foo() {\n  return x_keep;\n}\n\n---------- /out/backwards-reference-top-level.js ----------\nconst x = y, y = 1;\nconsole.log(\n  x,\n  x,\n  y,\n  y\n);\n\n---------- /out/backwards-reference-nested-function.js ----------\nfunction foo() {\n  const x = y, y = 1;\n  console.log(\n    x,\n    x,\n    y,\n    y\n  );\n}\n\n---------- /out/issue-3125.js ----------\nfunction foo() {\n  const f = () => x, x = 0;\n  return f();\n}\n\n================================================================================\nTestCrossModuleConstantFoldingComputedPropertyName\n---------- /out/enum-entry.js ----------\n// enum-entry.ts\nconsole.log({\n  123: 123 /* a */,\n  abc: \"abc\" /* b */\n});\nvar Foo = class {\n  [\"__proto__\"] = {};\n  [\"prototype\"] = {};\n  [\"constructor\"]() {\n  }\n};\n\n---------- /out/const-entry.js ----------\n// const-constants.js\nvar proto = \"__proto__\", ptype = \"prototype\", ctor = \"constructor\";\n\n// const-entry.js\nconsole.log({\n  456: 456,\n  xyz: \"xyz\"\n});\nvar Foo = class {\n  [proto] = {};\n  [ptype] = {};\n  [ctor]() {\n  }\n};\n\n================================================================================\nTestCrossModuleConstantFoldingNumber\n---------- /out/enum-entry.js ----------\n// enum-entry.ts\nconsole.log([\n  6,\n  -6,\n  -7,\n  !6 /* b */,\n  typeof 6 /* b */\n], [\n  9,\n  -3,\n  18,\n  3 /* a */ / 6 /* b */,\n  3 /* a */ % 6 /* b */,\n  3 /* a */ ** 6 /* b */\n], [\n  !0,\n  !1,\n  !0,\n  !1,\n  !1,\n  !0,\n  !1,\n  !0\n], [\n  12,\n  3,\n  3\n], [\n  2,\n  7,\n  5\n], [\n  6 /* b */,\n  3 /* a */,\n  3 /* a */,\n  \"y\",\n  \"n\"\n]);\n\n---------- /out/const-entry.js ----------\n// const-entry.js\nconsole.log([\n  6,\n  -6,\n  -7,\n  !6,\n  typeof 6\n], [\n  9,\n  -3,\n  18,\n  3 / 6,\n  3 % 6,\n  3 ** 6\n], [\n  !0,\n  !1,\n  !0,\n  !1,\n  !1,\n  !0,\n  !1,\n  !0\n], [\n  12,\n  3,\n  3\n], [\n  2,\n  7,\n  5\n], [\n  6,\n  3,\n  3,\n  \"y\",\n  \"n\"\n]);\n\n---------- /out/nested-entry.js ----------\n// nested-entry.ts\nconsole.log({\n  \"should be 4\": 4,\n  \"should be 32\": 32\n});\n\n================================================================================\nTestCrossModuleConstantFoldingString\n---------- /out/enum-entry.js ----------\n// enum-entry.ts\nconsole.log([\n  typeof \"bar\" /* b */\n], [\n  \"foobar\"\n], [\n  !1,\n  !0,\n  !1,\n  !0,\n  !1,\n  !0,\n  !1,\n  !0\n], [\n  \"bar\" /* b */,\n  \"foo\" /* a */,\n  \"foo\" /* a */,\n  \"y\",\n  \"n\"\n]);\n\n---------- /out/const-entry.js ----------\n// const-entry.js\nconsole.log([\n  typeof \"bar\"\n], [\n  \"foobar\"\n], [\n  !1,\n  !0,\n  !1,\n  !0,\n  !1,\n  !0,\n  !1,\n  !0\n], [\n  \"bar\",\n  \"foo\",\n  \"foo\",\n  \"y\",\n  \"n\"\n]);\n\n---------- /out/nested-entry.js ----------\n// nested-entry.ts\nconsole.log({\n  \"should be foobarbaz\": \"foobarbaz\",\n  \"should be FOOBARBAZ\": \"FOOBARBAZ\"\n});\n\n================================================================================\nTestDCEClassStaticBlocks\n---------- /out.js ----------\n// entry.ts\nvar A_keep = class {\n  static {\n    foo;\n  }\n};\nvar B_keep = class {\n  static {\n    this.foo;\n  }\n};\nvar C_keep = class {\n  static {\n    try {\n      foo;\n    } catch {\n    }\n  }\n};\nvar D_keep = class {\n  static {\n    try {\n    } finally {\n      foo;\n    }\n  }\n};\n\n================================================================================\nTestDCEClassStaticBlocksMinifySyntax\n---------- /out.js ----------\n// entry.ts\nvar A_keep = class {\n  static {\n    foo;\n  }\n}, B_keep = class {\n  static {\n    this.foo;\n  }\n}, C_keep = class {\n  static {\n    try {\n      foo;\n    } catch {\n    }\n  }\n}, D_keep = class {\n  static {\n    foo;\n  }\n};\n\n================================================================================\nTestDCEOfDecorators\n---------- /out/keep-these.js ----------\n// decorator.js\nvar fn = () => {\n  console.log(\"side effect\");\n};\n\n// keep-these.js\nvar Class = @fn class {\n};\nvar Field = class {\n  @fn field;\n};\nvar Method = class {\n  @fn method() {\n  }\n};\nvar Accessor = class {\n  @fn accessor accessor;\n};\nvar StaticField = class {\n  @fn static field;\n};\nvar StaticMethod = class {\n  @fn static method() {\n  }\n};\nvar StaticAccessor = class {\n  @fn static accessor accessor;\n};\n\n================================================================================\nTestDCEOfDestructuring\n---------- /out/entry.js ----------\n// entry.js\nvar KEEP1 = x;\nvar [KEEP2] = [x];\nvar [KEEP3] = [...{}];\nvar { KEEP4 } = {};\n\n================================================================================\nTestDCEOfExperimentalDecorators\n---------- /out/keep-these.js ----------\n// decorator.ts\nvar fn = () => {\n  console.log(\"side effect\");\n};\n\n// keep-these.ts\nvar Class = class {\n};\nClass = __decorateClass([\n  fn\n], Class);\nvar Field = class {\n  field;\n};\n__decorateClass([\n  fn\n], Field.prototype, \"field\", 2);\nvar Method = class {\n  method() {\n  }\n};\n__decorateClass([\n  fn\n], Method.prototype, \"method\", 1);\nvar Accessor = class {\n  accessor accessor;\n};\n__decorateClass([\n  fn\n], Accessor.prototype, \"accessor\", 1);\nvar Parameter = class {\n  foo(bar) {\n  }\n};\n__decorateClass([\n  __decorateParam(0, fn)\n], Parameter.prototype, \"foo\", 1);\nvar StaticField = class {\n  static field;\n};\n__decorateClass([\n  fn\n], StaticField, \"field\", 2);\nvar StaticMethod = class {\n  static method() {\n  }\n};\n__decorateClass([\n  fn\n], StaticMethod, \"method\", 1);\nvar StaticAccessor = class {\n  static accessor accessor;\n};\n__decorateClass([\n  fn\n], StaticAccessor, \"accessor\", 1);\nvar StaticParameter = class {\n  static foo(bar) {\n  }\n};\n__decorateClass([\n  __decorateParam(0, fn)\n], StaticParameter, \"foo\", 1);\n\n================================================================================\nTestDCEOfExprAfterKeepNamesIssue3195\n---------- /out.js ----------\n(() => {\n  function f() {\n  }\n  __name(f, \"f\"), firstImportantSideEffect(void 0);\n})(), (() => {\n  function g() {\n  }\n  __name(g, \"g\");\n  debugger;\n  secondImportantSideEffect(void 0);\n})();\n\n================================================================================\nTestDCEOfIIFE\n---------- /out/remove-these.js ----------\nkeepThisButRemoveTheIIFE;\n\n---------- /out/keep-these.js ----------\nundef = void 0;\nkeepMe();\n((x = keepMe()) => {\n})();\nvar someVar;\n(([y]) => {\n})(someVar);\n(({ z }) => {\n})(someVar);\nvar keepThis = stuff();\nkeepThis();\n((_ = keepMe()) => {\n})();\nvar isPure = /* @__PURE__ */ ((x, y) => 123)();\nuse(isPure);\nvar isNotPure = ((x = foo, y = bar) => 123)();\nuse(isNotPure);\n(async () => ({ get then() {\n  notPure();\n} }))();\n(async function() {\n  return { get then() {\n    notPure();\n  } };\n})();\n\n================================================================================\nTestDCEOfIteratorSuperclassIssue4310\n---------- /out/entry.js ----------\n// entry.js\nvar Keep = class extends NotIterator {\n};\n\n================================================================================\nTestDCEOfNegatedBigints\n---------- /out/entry.js ----------\n\n================================================================================\nTestDCEOfSymbolCtorCall\n---------- /out.js ----------\n// entry.js\nvar n0 = Symbol({});\nvar n1 = Symbol(/./);\nvar n2 = Symbol(() => 0);\nvar n3 = Symbol(x);\nvar n4 = new Symbol(\"abc\");\nvar n5 = Symbol(1, 2, 3);\nvar n6 = /* @__PURE__ */ Symbol((() => Math.random() < 0.5)() ? \"x\" : \"y\");\n\n================================================================================\nTestDCEOfSymbolForCall\n---------- /out.js ----------\n// entry.js\nvar n0 = Symbol.for();\nvar n1 = Symbol.for({});\nvar n2 = Symbol.for(/./);\nvar n3 = Symbol.for(() => 0);\nvar n4 = Symbol.for(x);\nvar n5 = new Symbol.for(\"abc\");\nvar n6 = Symbol.for(1, 2, 3);\nvar n7 = /* @__PURE__ */ Symbol.for((() => Math.random() < 0.5)() ? \"x\" : \"y\");\n\n================================================================================\nTestDCEOfSymbolInstances\n---------- /out/class.js ----------\n// class.js\nvar Keep1 = class {\n  *[Symbol.iterator]() {\n  }\n  [keep];\n};\nvar Keep2 = class {\n  [keep];\n  *[Symbol.iterator]() {\n  }\n};\nvar Keep3 = class {\n  *[Symbol.wtf]() {\n  }\n};\n\n---------- /out/object.js ----------\n// object.js\nvar keep1 = { *[Symbol.iterator]() {\n}, [keep]: null };\nvar keep2 = { [keep]: null, *[Symbol.iterator]() {\n} };\nvar keep3 = { *[Symbol.wtf]() {\n} };\n\n================================================================================\nTestDCEOfUsingDeclarations\n---------- /out/entry.js ----------\n// entry.js\nusing null_keep = null;\nawait using await_null_keep = null;\nusing throw_keep = {};\nusing dispose_keep = { [Symbol.dispose]() {\n  console.log(\"side effect\");\n} };\nawait using await_asyncDispose_keep = { [Symbol.asyncDispose]() {\n  console.log(\"side effect\");\n} };\nusing undef_keep = void 0;\nawait using await_undef_keep = void 0;\nconsole.log(\n  null_keep,\n  undef_keep\n);\n\n================================================================================\nTestDCETemplateLiteral\n---------- /out/entry.js ----------\n// entry.js\nvar alsoKeep;\nvar a = `${keep}`;\nvar c = `${keep ? 1 : 2n}`;\nvar e = `${alsoKeep}`;\n\n================================================================================\nTestDCETypeOf\n---------- /out.js ----------\n\n================================================================================\nTestDCETypeOfCompareStringGuardCondition\n---------- /out.js ----------\n(() => {\n  // entry.js\n  var keep_1 = typeof x <= \"u\" ? y : null;\n  var keep_1 = typeof x < \"u\" ? y : null;\n  var keep_1 = typeof x >= \"u\" ? null : y;\n  var keep_1 = typeof x > \"u\" ? null : y;\n  var keep_1 = typeof x <= \"u\" && y;\n  var keep_1 = typeof x < \"u\" && y;\n  var keep_1 = typeof x >= \"u\" || y;\n  var keep_1 = typeof x > \"u\" || y;\n  var keep_1 = \"u\" >= typeof x ? y : null;\n  var keep_1 = \"u\" > typeof x ? y : null;\n  var keep_1 = \"u\" <= typeof x ? null : y;\n  var keep_1 = \"u\" < typeof x ? null : y;\n  var keep_1 = \"u\" >= typeof x && y;\n  var keep_1 = \"u\" > typeof x && y;\n  var keep_1 = \"u\" <= typeof x || y;\n  var keep_1 = \"u\" < typeof x || y;\n  var keep_2 = typeof x <= \"u\" ? null : x;\n  var keep_2 = typeof x < \"u\" ? null : x;\n  var keep_2 = typeof x >= \"u\" ? x : null;\n  var keep_2 = typeof x > \"u\" ? x : null;\n  var keep_2 = typeof x <= \"u\" || x;\n  var keep_2 = typeof x < \"u\" || x;\n  var keep_2 = typeof x >= \"u\" && x;\n  var keep_2 = typeof x > \"u\" && x;\n  var keep_2 = \"u\" >= typeof x ? null : x;\n  var keep_2 = \"u\" > typeof x ? null : x;\n  var keep_2 = \"u\" <= typeof x ? x : null;\n  var keep_2 = \"u\" < typeof x ? x : null;\n  var keep_2 = \"u\" >= typeof x || x;\n  var keep_2 = \"u\" > typeof x || x;\n  var keep_2 = \"u\" <= typeof x && x;\n  var keep_2 = \"u\" < typeof x && x;\n})();\n\n================================================================================\nTestDCETypeOfEqualsString\n---------- /out.js ----------\n(() => {\n  // entry.js\n  if (false) console.log(hasBar);\n})();\n\n================================================================================\nTestDCETypeOfEqualsStringGuardCondition\n---------- /out.js ----------\n(() => {\n  // entry.js\n  var keep_1 = typeof x !== \"object\" ? x : null;\n  var keep_1 = typeof x != \"object\" ? x : null;\n  var keep_1 = typeof x === \"object\" ? null : x;\n  var keep_1 = typeof x == \"object\" ? null : x;\n  var keep_1 = typeof x !== \"object\" && x;\n  var keep_1 = typeof x != \"object\" && x;\n  var keep_1 = typeof x === \"object\" || x;\n  var keep_1 = typeof x == \"object\" || x;\n  var keep_1 = \"object\" !== typeof x ? x : null;\n  var keep_1 = \"object\" != typeof x ? x : null;\n  var keep_1 = \"object\" === typeof x ? null : x;\n  var keep_1 = \"object\" == typeof x ? null : x;\n  var keep_1 = \"object\" !== typeof x && x;\n  var keep_1 = \"object\" != typeof x && x;\n  var keep_1 = \"object\" === typeof x || x;\n  var keep_1 = \"object\" == typeof x || x;\n  var keep_2 = typeof x !== \"undefined\" ? y : null;\n  var keep_2 = typeof x != \"undefined\" ? y : null;\n  var keep_2 = typeof x === \"undefined\" ? null : y;\n  var keep_2 = typeof x == \"undefined\" ? null : y;\n  var keep_2 = typeof x !== \"undefined\" && y;\n  var keep_2 = typeof x != \"undefined\" && y;\n  var keep_2 = typeof x === \"undefined\" || y;\n  var keep_2 = typeof x == \"undefined\" || y;\n  var keep_2 = \"undefined\" !== typeof x ? y : null;\n  var keep_2 = \"undefined\" != typeof x ? y : null;\n  var keep_2 = \"undefined\" === typeof x ? null : y;\n  var keep_2 = \"undefined\" == typeof x ? null : y;\n  var keep_2 = \"undefined\" !== typeof x && y;\n  var keep_2 = \"undefined\" != typeof x && y;\n  var keep_2 = \"undefined\" === typeof x || y;\n  var keep_2 = \"undefined\" == typeof x || y;\n  var keep_3 = typeof x !== \"undefined\" ? null : x;\n  var keep_3 = typeof x != \"undefined\" ? null : x;\n  var keep_3 = typeof x === \"undefined\" ? x : null;\n  var keep_3 = typeof x == \"undefined\" ? x : null;\n  var keep_3 = typeof x !== \"undefined\" || x;\n  var keep_3 = typeof x != \"undefined\" || x;\n  var keep_3 = typeof x === \"undefined\" && x;\n  var keep_3 = typeof x == \"undefined\" && x;\n  var keep_3 = \"undefined\" !== typeof x ? null : x;\n  var keep_3 = \"undefined\" != typeof x ? null : x;\n  var keep_3 = \"undefined\" === typeof x ? x : null;\n  var keep_3 = \"undefined\" == typeof x ? x : null;\n  var keep_3 = \"undefined\" !== typeof x || x;\n  var keep_3 = \"undefined\" != typeof x || x;\n  var keep_3 = \"undefined\" === typeof x && x;\n  var keep_3 = \"undefined\" == typeof x && x;\n})();\n\n================================================================================\nTestDCETypeOfEqualsStringMangle\n---------- /out.js ----------\n(() => {\n})();\n\n================================================================================\nTestDCEVarExports\n---------- /out/a.js ----------\n// a.js\nvar require_a = __commonJS({\n  \"a.js\"(exports, module) {\n    var foo = { bar: 123 };\n    module.exports = foo;\n  }\n});\nexport default require_a();\n\n---------- /out/b.js ----------\n// b.js\nvar require_b = __commonJS({\n  \"b.js\"(exports, module) {\n    var exports = { bar: 123 };\n    module.exports = exports;\n  }\n});\nexport default require_b();\n\n---------- /out/c.js ----------\n// c.js\nvar require_c = __commonJS({\n  \"c.js\"(exports, module) {\n    var module = { bar: 123 };\n    exports.foo = module;\n  }\n});\nexport default require_c();\n\n================================================================================\nTestDataURLLoaderRemoveUnused\n---------- /out.js ----------\n// entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestDeadCodeFollowingJump\n---------- /out.js ----------\n// entry.js\nfunction testReturn() {\n  return y + z();\n  if (x)\n    var y;\n  function z() {\n    KEEP_ME();\n  }\n}\nfunction testThrow() {\n  throw y + z();\n  if (x)\n    var y;\n  function z() {\n    KEEP_ME();\n  }\n}\nfunction testBreak() {\n  for (; ; ) {\n    let z2 = function() {\n      KEEP_ME();\n    };\n    var z = z2;\n    y + z2();\n    break;\n    if (x)\n      var y;\n  }\n}\nfunction testContinue() {\n  for (; ; ) {\n    let z2 = function() {\n      KEEP_ME();\n    };\n    var z = z2;\n    y + z2();\n    continue;\n    if (x)\n      var y;\n  }\n}\nfunction testStmts() {\n  return [a, b, c, d, e, f, g, h, i];\n  for (; x; )\n    var a;\n  do\n    var b;\n  while (x);\n  for (var c; ; ) ;\n  for (var d in x) ;\n  for (var e of x) ;\n  if (x)\n    var f;\n  if (!x) var g;\n  var h, i;\n}\ntestReturn();\ntestThrow();\ntestBreak();\ntestContinue();\ntestStmts();\n\n================================================================================\nTestDeadCodeInsideEmptyTry\n---------- /out.js ----------\n// a.js\nvar require_a = __commonJS({\n  \"a.js\"() {\n  }\n});\n\n// b.js\nvar require_b = __commonJS({\n  \"b.js\"() {\n  }\n});\n\n// d.js\nvar require_d = __commonJS({\n  \"d.js\"() {\n  }\n});\n\n// entry.js\ntry {\n  foo();\n} catch {\n  require_a();\n} finally {\n  require_b();\n}\ntry {\n} catch {\n} finally {\n  require_d();\n}\n\n================================================================================\nTestDeadCodeInsideUnusedCases\n---------- /out.js ----------\n// a.js\nvar require_a = __commonJS({\n  \"a.js\"() {\n  }\n});\n\n// b.js\nvar require_b = __commonJS({\n  \"b.js\"() {\n  }\n});\n\n// entry.js\nswitch (x) {\n  case 0:\n    _ = require_a();\n    break;\n  case 1:\n    _ = require_b();\n    break;\n}\nswitch (1) {\n  case 0:\n    _ = null;\n    break;\n  case 1:\n    _ = require_a();\n    break;\n  case 1:\n    _ = null;\n    break;\n  case 2:\n    _ = null;\n    break;\n}\nswitch (0) {\n  case 1:\n    _ = null;\n    break;\n  default:\n    _ = require_a();\n    break;\n}\nswitch (1) {\n  case 1:\n    _ = require_a();\n    break;\n  default:\n    _ = null;\n    break;\n}\nswitch (0) {\n  case 1:\n    _ = null;\n    break;\n  default:\n    _ = null;\n    break;\n  case 0:\n    _ = require_a();\n    break;\n}\nswitch (1) {\n  case x:\n    _ = require_a();\n    break;\n  case 1:\n    _ = require_b();\n    break;\n  case x:\n    _ = null;\n    break;\n  default:\n    _ = null;\n    break;\n}\nfor (const x2 of y)\n  switch (1) {\n    case 0:\n      _ = null;\n      continue;\n    case 1:\n      _ = require_a();\n      continue;\n    case 2:\n      _ = null;\n      continue;\n  }\nx = () => {\n  switch (1) {\n    case 0:\n      _ = null;\n      return;\n    case 1:\n      _ = require_a();\n      return;\n    case 2:\n      _ = null;\n      return;\n  }\n};\nswitch (\"b\") {\n  case \"a\":\n    _ = null;\n  case \"b\":\n    _ = require_a();\n  case \"c\":\n    _ = require_b();\n    break;\n  case \"d\":\n    _ = null;\n}\nswitch (\"b\") {\n  case \"a\":\n    _ = null;\n  case \"b\":\n  case \"c\":\n    _ = require_a();\n  case \"d\":\n    _ = require_b();\n    break;\n  case \"e\":\n    _ = null;\n}\n\n================================================================================\nTestDisableTreeShaking\n---------- /out.js ----------\n// keep-me/index.js\nconsole.log(\"side effects\");\n\n// entry.jsx\nfunction KeepMe1() {\n}\nvar keepMe2 = React.createElement(KeepMe1, null);\nfunction keepMe3() {\n  console.log(\"side effects\");\n}\nvar keepMe4 = keepMe3();\nvar keepMe5 = pure();\nvar keepMe6 = some.fn();\n\n================================================================================\nTestDropLabelTreeShakingBugIssue3311\n---------- /out.js ----------\n// entry.js\nvar myFunc = () => {\n  console.log(\"keep\");\n};\nvar entry_default = myFunc;\nexport {\n  entry_default as default\n};\n\n================================================================================\nTestDropLabels\n---------- /out.js ----------\n// entry.js\nkeep_1: require(\"foo1\");\nexports.bar = function() {\n  if (x) ;\n  if (y) keep_2: require(\"bar2\");\n};\n\n================================================================================\nTestFileLoaderRemoveUnused\n---------- /out.js ----------\n// entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestImportReExportOfNamespaceImport\n---------- /out.js ----------\n// Users/user/project/node_modules/pkg/foo.js\nvar require_foo = __commonJS({\n  \"Users/user/project/node_modules/pkg/foo.js\"(exports, module) {\n    module.exports = 123;\n  }\n});\n\n// Users/user/project/node_modules/pkg/index.js\nvar import_foo = __toESM(require_foo());\n\n// Users/user/project/entry.js\nconsole.log(import_foo.default);\n\n================================================================================\nTestInlineEmptyFunctionCalls\n---------- /out/empty.js ----------\n// empty.js\nconsole.log((foo(), bar(), void 0));\nconsole.log((foo(), void 0));\nconsole.log((foo(), void 0));\nconsole.log(void 0);\nconsole.log(void 0);\nfoo(), bar();\nfoo();\nfoo();\n\n---------- /out/empty-comma.js ----------\n// empty-comma.js\nconsole.log(foo());\nconsole.log((foo(), void 0));\nconsole.log((foo(), void 0));\nfor (; void 0; ) ;\nfoo();\nfoo();\nfoo();\n\n---------- /out/empty-if-else.js ----------\n// empty-if-else.js\nif (foo) {\n  let bar = baz();\n  bar(), bar();\n}\n\n---------- /out/empty-last.js ----------\n// empty-last.js\nconsole.log(void 0);\n\n---------- /out/empty-cross-module.js ----------\n// empty-cross-module.js\nconsole.log(void 0);\n\n---------- /out/empty-first.js ----------\n// empty-first.js\nfunction keep() {\n  return x;\n}\nconsole.log(keep());\nkeep(foo());\nkeep(1);\n\n---------- /out/empty-generator.js ----------\n// empty-generator.js\nfunction* keep() {\n}\nconsole.log(keep());\nkeep(foo());\nkeep(1);\n\n---------- /out/empty-async.js ----------\n// empty-async.js\nasync function keep() {\n}\nconsole.log(keep());\nkeep(foo());\nkeep(1);\n\n---------- /out/reassign.js ----------\n// reassign.js\nfunction keep() {\n}\nkeep = reassigned;\nconsole.log(keep());\nkeep(foo());\nkeep(1);\n\n---------- /out/reassign-inc.js ----------\n// reassign-inc.js\nfunction keep() {\n}\nkeep++;\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/reassign-div.js ----------\n// reassign-div.js\nfunction keep() {\n}\nkeep /= reassigned;\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/reassign-array.js ----------\n// reassign-array.js\nfunction keep() {\n}\n[keep] = reassigned;\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/reassign-object.js ----------\n// reassign-object.js\nfunction keep() {\n}\n({ keep } = reassigned);\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n================================================================================\nTestInlineFunctionCallBehaviorChanges\n---------- /out/entry.js ----------\nfunction empty() {\n}\nfunction id(x) {\n  return x;\n}\nexport let shouldBeWrapped = [\n  (0, foo.bar)(),\n  (0, foo[bar])(),\n  (0, foo?.bar)(),\n  (0, foo?.[bar])(),\n  (0, foo.bar)(),\n  (0, foo[bar])(),\n  (0, foo?.bar)(),\n  (0, foo?.[bar])(),\n  (0, eval)(),\n  (0, eval)?.(),\n  (0, eval)(),\n  (0, eval)?.(),\n  (0, foo.bar)``,\n  (0, foo[bar])``,\n  (0, foo?.bar)``,\n  (0, foo?.[bar])``,\n  (0, foo.bar)``,\n  (0, foo[bar])``,\n  (0, foo?.bar)``,\n  (0, foo?.[bar])``,\n  delete (0, foo),\n  delete (0, foo.bar),\n  delete (0, foo[bar]),\n  delete (0, foo?.bar),\n  delete (0, foo?.[bar]),\n  delete (0, foo),\n  delete (0, foo.bar),\n  delete (0, foo[bar]),\n  delete (0, foo?.bar),\n  delete (0, foo?.[bar]),\n  delete (0, void 0)\n], shouldNotBeWrapped = [\n  foo(),\n  foo(),\n  foo``,\n  foo``\n], shouldNotBeDoubleWrapped = [\n  delete (foo(), bar()),\n  delete (foo(), bar())\n];\n\n================================================================================\nTestInlineFunctionCallForInitDecl\n---------- /out/entry.js ----------\n// entry.js\nfor (y = void 0; !1; ) ;\nvar y;\nfor (z = 123; !1; ) ;\nvar z;\n\n================================================================================\nTestInlineIdentityFunctionCalls\n---------- /out/identity.js ----------\n// identity.js\nconsole.log(1);\nfoo();\n\n---------- /out/identity-last.js ----------\n// identity-last.js\nconsole.log(1);\nfoo();\n\n---------- /out/identity-first.js ----------\n// identity-first.js\nfunction keep(x) {\n  return [x];\n}\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/identity-generator.js ----------\n// identity-generator.js\nfunction* keep(x) {\n  return x;\n}\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/identity-async.js ----------\n// identity-async.js\nasync function keep(x) {\n  return x;\n}\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/identity-cross-module.js ----------\n// identity-cross-module.js\nconsole.log(1);\nfoo();\n\n---------- /out/identity-no-args.js ----------\n// identity-no-args.js\nfunction keep(x) {\n  return x;\n}\nconsole.log(keep());\nkeep();\n\n---------- /out/identity-two-args.js ----------\n// identity-two-args.js\nfunction keep(x) {\n  return x;\n}\nconsole.log(keep(1, 2));\nkeep(1, 2);\n\n---------- /out/reassign.js ----------\n// reassign.js\nfunction keep(x) {\n  return x;\n}\nkeep = reassigned;\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/reassign-inc.js ----------\n// reassign-inc.js\nfunction keep(x) {\n  return x;\n}\nkeep++;\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/reassign-div.js ----------\n// reassign-div.js\nfunction keep(x) {\n  return x;\n}\nkeep /= reassigned;\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/reassign-array.js ----------\n// reassign-array.js\nfunction keep(x) {\n  return x;\n}\n[keep] = reassigned;\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/reassign-object.js ----------\n// reassign-object.js\nfunction keep(x) {\n  return x;\n}\n({ keep } = reassigned);\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/not-identity-two-args.js ----------\n// not-identity-two-args.js\nfunction keep(x, y) {\n  return x;\n}\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/not-identity-default.js ----------\n// not-identity-default.js\nfunction keep(x = foo()) {\n  return x;\n}\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/not-identity-array.js ----------\n// not-identity-array.js\nfunction keep([x]) {\n  return x;\n}\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/not-identity-object.js ----------\n// not-identity-object.js\nfunction keep({ x }) {\n  return x;\n}\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/not-identity-rest.js ----------\n// not-identity-rest.js\nfunction keep(...x) {\n  return x;\n}\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/not-identity-return.js ----------\n// not-identity-return.js\nfunction keep(x) {\n  return [x];\n}\nconsole.log(keep(1));\nkeep(foo());\nkeep(1);\n\n---------- /out/identity-simplify-unused-issue-4287.js ----------\n// identity-simplify-unused-issue-4287.js\nfoo();\nvoid 0;\n\n================================================================================\nTestJSONLoaderRemoveUnused\n---------- /out.js ----------\n// entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestMultipleDeclarationTreeShaking\n---------- /out/var2.js ----------\n// var2.js\nvar x = 1;\nconsole.log(x);\nvar x = 2;\n\n---------- /out/var3.js ----------\n// var3.js\nvar x = 1;\nconsole.log(x);\nvar x = 2;\nconsole.log(x);\nvar x = 3;\n\n---------- /out/function2.js ----------\n// function2.js\nfunction x() {\n  return 1;\n}\nconsole.log(x());\nfunction x() {\n  return 2;\n}\n\n---------- /out/function3.js ----------\n// function3.js\nfunction x() {\n  return 1;\n}\nconsole.log(x());\nfunction x() {\n  return 2;\n}\nconsole.log(x());\nfunction x() {\n  return 3;\n}\n\n================================================================================\nTestMultipleDeclarationTreeShakingMinifySyntax\n---------- /out/var2.js ----------\n// var2.js\nvar x = 1;\nconsole.log(x);\nvar x = 2;\n\n---------- /out/var3.js ----------\n// var3.js\nvar x = 1;\nconsole.log(x);\nvar x = 2;\nconsole.log(x);\nvar x = 3;\n\n---------- /out/function2.js ----------\n// function2.js\nconsole.log(x());\nfunction x() {\n  return 2;\n}\n\n---------- /out/function3.js ----------\n// function3.js\nconsole.log(x());\nconsole.log(x());\nfunction x() {\n  return 3;\n}\n\n================================================================================\nTestNestedFunctionInliningWithSpread\n---------- /out/entry.js ----------\n// entry.js\nfunction identity1(x) {\n  return x;\n}\nfunction identity3(x) {\n  return x;\n}\ncheck(\n  void 0,\n  (args, void 0),\n  ([...args], void 0),\n  identity1(),\n  args,\n  identity3(...args)\n);\n\n---------- /out/entry-outer.js ----------\n// inner.js\nfunction identity1(x) {\n  return x;\n}\nfunction identity3(x) {\n  return x;\n}\n\n// entry-outer.js\ncheck(\n  void 0,\n  (args, void 0),\n  ([...args], void 0),\n  identity1(),\n  args,\n  identity3(...args)\n);\n\n================================================================================\nTestNoSideEffectsComment\n---------- /out/expr-fn.js ----------\n//! These should all have \"no side effects\"\nx([\n  /* @__NO_SIDE_EFFECTS__ */ function() {\n  },\n  /* @__NO_SIDE_EFFECTS__ */ function y() {\n  },\n  /* @__NO_SIDE_EFFECTS__ */ function* () {\n  },\n  /* @__NO_SIDE_EFFECTS__ */ function* y2() {\n  },\n  /* @__NO_SIDE_EFFECTS__ */ async function() {\n  },\n  /* @__NO_SIDE_EFFECTS__ */ async function y3() {\n  },\n  /* @__NO_SIDE_EFFECTS__ */ async function* () {\n  },\n  /* @__NO_SIDE_EFFECTS__ */ async function* y4() {\n  }\n]);\n\n---------- /out/expr-arrow.js ----------\n//! These should all have \"no side effects\"\nx([\n  /* @__NO_SIDE_EFFECTS__ */ (y) => y,\n  /* @__NO_SIDE_EFFECTS__ */ () => {\n  },\n  /* @__NO_SIDE_EFFECTS__ */ (y) => y,\n  /* @__NO_SIDE_EFFECTS__ */ async (y) => y,\n  /* @__NO_SIDE_EFFECTS__ */ async () => {\n  },\n  /* @__NO_SIDE_EFFECTS__ */ async (y) => y\n]);\n\n---------- /out/stmt-fn.js ----------\n//! These should all have \"no side effects\"\n// @__NO_SIDE_EFFECTS__\nfunction a() {\n}\n// @__NO_SIDE_EFFECTS__\nfunction* b() {\n}\n// @__NO_SIDE_EFFECTS__\nasync function c() {\n}\n// @__NO_SIDE_EFFECTS__\nasync function* d() {\n}\n\n---------- /out/stmt-export-fn.js ----------\n//! These should all have \"no side effects\"\n// @__NO_SIDE_EFFECTS__\nexport function a() {\n}\n// @__NO_SIDE_EFFECTS__\nexport function* b() {\n}\n// @__NO_SIDE_EFFECTS__\nexport async function c() {\n}\n// @__NO_SIDE_EFFECTS__\nexport async function* d() {\n}\n\n---------- /out/stmt-local.js ----------\n//! Only \"c0\" and \"c2\" should have \"no side effects\" (Rollup only respects \"const\" and only for the first one)\nvar v0 = function() {\n}, v1 = function() {\n};\nlet l0 = function() {\n}, l1 = function() {\n};\nconst c0 = /* @__NO_SIDE_EFFECTS__ */ function() {\n}, c1 = function() {\n};\nvar v2 = () => {\n}, v3 = () => {\n};\nlet l2 = () => {\n}, l3 = () => {\n};\nconst c2 = /* @__NO_SIDE_EFFECTS__ */ () => {\n}, c3 = () => {\n};\n\n---------- /out/stmt-export-local.js ----------\n//! Only \"c0\" and \"c2\" should have \"no side effects\" (Rollup only respects \"const\" and only for the first one)\nexport var v0 = function() {\n}, v1 = function() {\n};\nexport let l0 = function() {\n}, l1 = function() {\n};\nexport const c0 = /* @__NO_SIDE_EFFECTS__ */ function() {\n}, c1 = function() {\n};\nexport var v2 = () => {\n}, v3 = () => {\n};\nexport let l2 = () => {\n}, l3 = () => {\n};\nexport const c2 = /* @__NO_SIDE_EFFECTS__ */ () => {\n}, c3 = () => {\n};\n\n---------- /out/ns-export-fn.js ----------\nvar ns;\n((ns2) => {\n  //! These should all have \"no side effects\"\n  // @__NO_SIDE_EFFECTS__\n  function a() {\n  }\n  ns2.a = a;\n  // @__NO_SIDE_EFFECTS__\n  function* b() {\n  }\n  ns2.b = b;\n  // @__NO_SIDE_EFFECTS__\n  async function c() {\n  }\n  ns2.c = c;\n  // @__NO_SIDE_EFFECTS__\n  async function* d() {\n  }\n  ns2.d = d;\n})(ns || (ns = {}));\n\n---------- /out/ns-export-local.js ----------\nvar ns;\n((ns2) => {\n  //! Only \"c0\" and \"c2\" should have \"no side effects\" (Rollup only respects \"const\" and only for the first one)\n  ns2.v0 = function() {\n  };\n  ns2.v1 = function() {\n  };\n  ns2.l0 = function() {\n  };\n  ns2.l1 = function() {\n  };\n  ns2.c0 = /* @__NO_SIDE_EFFECTS__ */ function() {\n  };\n  ns2.c1 = function() {\n  };\n  ns2.v2 = () => {\n  };\n  ns2.v3 = () => {\n  };\n  ns2.l2 = () => {\n  };\n  ns2.l3 = () => {\n  };\n  ns2.c2 = /* @__NO_SIDE_EFFECTS__ */ () => {\n  };\n  ns2.c3 = () => {\n  };\n})(ns || (ns = {}));\n\n---------- /out/stmt-export-default-before-fn-anon.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default function() {\n}\n\n---------- /out/stmt-export-default-before-fn-name.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default function f() {\n}\n\n---------- /out/stmt-export-default-before-gen-fn-anon.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default function* () {\n}\n\n---------- /out/stmt-export-default-before-gen-fn-name.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default function* f() {\n}\n\n---------- /out/stmt-export-default-before-async-fn-anon.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default async function() {\n}\n\n---------- /out/stmt-export-default-before-async-fn-name.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default async function f() {\n}\n\n---------- /out/stmt-export-default-before-async-gen-fn-anon.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default async function* () {\n}\n\n---------- /out/stmt-export-default-before-async-gen-fn-name.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default async function* f() {\n}\n\n---------- /out/stmt-export-default-after-fn-anon.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default function() {\n}\n\n---------- /out/stmt-export-default-after-fn-name.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default function f() {\n}\n\n---------- /out/stmt-export-default-after-gen-fn-anon.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default function* () {\n}\n\n---------- /out/stmt-export-default-after-gen-fn-name.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default function* f() {\n}\n\n---------- /out/stmt-export-default-after-async-fn-anon.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default async function() {\n}\n\n---------- /out/stmt-export-default-after-async-fn-name.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default async function f() {\n}\n\n---------- /out/stmt-export-default-after-async-gen-fn-anon.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default async function* () {\n}\n\n---------- /out/stmt-export-default-after-async-gen-fn-name.js ----------\n/*! This should have \"no side effects\" */\n// @__NO_SIDE_EFFECTS__\nexport default async function* f() {\n}\n\n================================================================================\nTestNoSideEffectsCommentIgnoreAnnotations\n---------- /out/expr-fn.js ----------\nx([\n  function() {\n  },\n  function y() {\n  },\n  function* () {\n  },\n  function* y2() {\n  },\n  async function() {\n  },\n  async function y3() {\n  },\n  async function* () {\n  },\n  async function* y4() {\n  }\n]);\n\n---------- /out/expr-arrow.js ----------\nx([\n  (y) => y,\n  () => {\n  },\n  (y) => y,\n  async (y) => y,\n  async () => {\n  },\n  async (y) => y\n]);\n\n---------- /out/stmt-fn.js ----------\nfunction a() {\n}\nfunction* b() {\n}\nasync function c() {\n}\nasync function* d() {\n}\n\n---------- /out/stmt-export-fn.js ----------\nexport function a() {\n}\nexport function* b() {\n}\nexport async function c() {\n}\nexport async function* d() {\n}\n\n---------- /out/stmt-local.js ----------\nvar v0 = function() {\n}, v1 = function() {\n};\nlet l0 = function() {\n}, l1 = function() {\n};\nconst c0 = function() {\n}, c1 = function() {\n};\nvar v2 = () => {\n}, v3 = () => {\n};\nlet l2 = () => {\n}, l3 = () => {\n};\nconst c2 = () => {\n}, c3 = () => {\n};\n\n---------- /out/stmt-export-local.js ----------\nexport var v0 = function() {\n}, v1 = function() {\n};\nexport let l0 = function() {\n}, l1 = function() {\n};\nexport const c0 = function() {\n}, c1 = function() {\n};\nexport var v2 = () => {\n}, v3 = () => {\n};\nexport let l2 = () => {\n}, l3 = () => {\n};\nexport const c2 = () => {\n}, c3 = () => {\n};\n\n---------- /out/ns-export-fn.js ----------\nvar ns;\n((ns2) => {\n  function a() {\n  }\n  ns2.a = a;\n  function* b() {\n  }\n  ns2.b = b;\n  async function c() {\n  }\n  ns2.c = c;\n  async function* d() {\n  }\n  ns2.d = d;\n})(ns || (ns = {}));\n\n---------- /out/ns-export-local.js ----------\nvar ns;\n((ns2) => {\n  ns2.v0 = function() {\n  };\n  ns2.v1 = function() {\n  };\n  ns2.l0 = function() {\n  };\n  ns2.l1 = function() {\n  };\n  ns2.c0 = function() {\n  };\n  ns2.c1 = function() {\n  };\n  ns2.v2 = () => {\n  };\n  ns2.v3 = () => {\n  };\n  ns2.l2 = () => {\n  };\n  ns2.l3 = () => {\n  };\n  ns2.c2 = () => {\n  };\n  ns2.c3 = () => {\n  };\n})(ns || (ns = {}));\n\n---------- /out/stmt-export-default-before-fn-anon.js ----------\nexport default function() {\n}\n\n---------- /out/stmt-export-default-before-fn-name.js ----------\nexport default function f() {\n}\n\n---------- /out/stmt-export-default-before-gen-fn-anon.js ----------\nexport default function* () {\n}\n\n---------- /out/stmt-export-default-before-gen-fn-name.js ----------\nexport default function* f() {\n}\n\n---------- /out/stmt-export-default-before-async-fn-anon.js ----------\nexport default async function() {\n}\n\n---------- /out/stmt-export-default-before-async-fn-name.js ----------\nexport default async function f() {\n}\n\n---------- /out/stmt-export-default-before-async-gen-fn-anon.js ----------\nexport default async function* () {\n}\n\n---------- /out/stmt-export-default-before-async-gen-fn-name.js ----------\nexport default async function* f() {\n}\n\n---------- /out/stmt-export-default-after-fn-anon.js ----------\nexport default function() {\n}\n\n---------- /out/stmt-export-default-after-fn-name.js ----------\nexport default function f() {\n}\n\n---------- /out/stmt-export-default-after-gen-fn-anon.js ----------\nexport default function* () {\n}\n\n---------- /out/stmt-export-default-after-gen-fn-name.js ----------\nexport default function* f() {\n}\n\n---------- /out/stmt-export-default-after-async-fn-anon.js ----------\nexport default async function() {\n}\n\n---------- /out/stmt-export-default-after-async-fn-name.js ----------\nexport default async function f() {\n}\n\n---------- /out/stmt-export-default-after-async-gen-fn-anon.js ----------\nexport default async function* () {\n}\n\n---------- /out/stmt-export-default-after-async-gen-fn-name.js ----------\nexport default async function* f() {\n}\n\n================================================================================\nTestNoSideEffectsCommentMinifyWhitespace\n---------- /out/expr-fn.js ----------\nx([function(){},function y(){},function*(){},function*y2(){},async function(){},async function y3(){},async function*(){},async function*y4(){}]);\n\n---------- /out/expr-arrow.js ----------\nx([y=>y,()=>{},y=>y,async y=>y,async()=>{},async y=>y]);\n\n---------- /out/stmt-fn.js ----------\nfunction a(){}function*b(){}async function c(){}async function*d(){}\n\n---------- /out/stmt-export-fn.js ----------\nexport function a(){}export function*b(){}export async function c(){}export async function*d(){}\n\n---------- /out/stmt-local.js ----------\nvar v0=function(){},v1=function(){};let l0=function(){},l1=function(){};const c0=function(){},c1=function(){};var v2=()=>{},v3=()=>{};let l2=()=>{},l3=()=>{};const c2=()=>{},c3=()=>{};\n\n---------- /out/stmt-export-local.js ----------\nexport var v0=function(){},v1=function(){};export let l0=function(){},l1=function(){};export const c0=function(){},c1=function(){};export var v2=()=>{},v3=()=>{};export let l2=()=>{},l3=()=>{};export const c2=()=>{},c3=()=>{};\n\n---------- /out/ns-export-fn.js ----------\nvar ns;(ns2=>{function a(){}ns2.a=a;function*b(){}ns2.b=b;async function c(){}ns2.c=c;async function*d(){}ns2.d=d})(ns||(ns={}));\n\n---------- /out/ns-export-local.js ----------\nvar ns;(ns2=>{ns2.v0=function(){};ns2.v1=function(){};ns2.l0=function(){};ns2.l1=function(){};ns2.c0=function(){};ns2.c1=function(){};ns2.v2=()=>{};ns2.v3=()=>{};ns2.l2=()=>{};ns2.l3=()=>{};ns2.c2=()=>{};ns2.c3=()=>{}})(ns||(ns={}));\n\n---------- /out/stmt-export-default-before-fn-anon.js ----------\nexport default function(){}\n\n---------- /out/stmt-export-default-before-fn-name.js ----------\nexport default function f(){}\n\n---------- /out/stmt-export-default-before-gen-fn-anon.js ----------\nexport default function*(){}\n\n---------- /out/stmt-export-default-before-gen-fn-name.js ----------\nexport default function*f(){}\n\n---------- /out/stmt-export-default-before-async-fn-anon.js ----------\nexport default async function(){}\n\n---------- /out/stmt-export-default-before-async-fn-name.js ----------\nexport default async function f(){}\n\n---------- /out/stmt-export-default-before-async-gen-fn-anon.js ----------\nexport default async function*(){}\n\n---------- /out/stmt-export-default-before-async-gen-fn-name.js ----------\nexport default async function*f(){}\n\n---------- /out/stmt-export-default-after-fn-anon.js ----------\nexport default function(){}\n\n---------- /out/stmt-export-default-after-fn-name.js ----------\nexport default function f(){}\n\n---------- /out/stmt-export-default-after-gen-fn-anon.js ----------\nexport default function*(){}\n\n---------- /out/stmt-export-default-after-gen-fn-name.js ----------\nexport default function*f(){}\n\n---------- /out/stmt-export-default-after-async-fn-anon.js ----------\nexport default async function(){}\n\n---------- /out/stmt-export-default-after-async-fn-name.js ----------\nexport default async function f(){}\n\n---------- /out/stmt-export-default-after-async-gen-fn-anon.js ----------\nexport default async function*(){}\n\n---------- /out/stmt-export-default-after-async-gen-fn-name.js ----------\nexport default async function*f(){}\n\n================================================================================\nTestNoSideEffectsCommentTypeScriptDeclare\n---------- /out/entry.js ----------\nvar ns;\n((ns2) => {\n})(ns || (ns = {}));\n\n================================================================================\nTestNoSideEffectsCommentUnusedCalls\n---------- /out/stmt-fn.js ----------\n// @__NO_SIDE_EFFECTS__\nfunction f(y) {\n  sideEffect(y);\n}\n// @__NO_SIDE_EFFECTS__\nfunction* g(y) {\n  sideEffect(y);\n}\nonlyKeepThisIdentifier;\nonlyKeepThisIdentifier;\nx(/* @__PURE__ */ f(\"keepThisCall\"));\nx(/* @__PURE__ */ g(\"keepThisCall\"));\n\n---------- /out/stmt-local.js ----------\nconst f = /* @__NO_SIDE_EFFECTS__ */ function(y) {\n  sideEffect(y);\n}, g = /* @__NO_SIDE_EFFECTS__ */ function* (y) {\n  sideEffect(y);\n};\nonlyKeepThisIdentifier;\nonlyKeepThisIdentifier;\nx(/* @__PURE__ */ f(\"keepThisCall\"));\nx(/* @__PURE__ */ g(\"keepThisCall\"));\n\n---------- /out/expr-fn.js ----------\nconst f = /* @__NO_SIDE_EFFECTS__ */ function(y) {\n  sideEffect(y);\n}, g = /* @__NO_SIDE_EFFECTS__ */ function* (y) {\n  sideEffect(y);\n};\nonlyKeepThisIdentifier;\nonlyKeepThisIdentifier;\nx(/* @__PURE__ */ f(\"keepThisCall\"));\nx(/* @__PURE__ */ g(\"keepThisCall\"));\n\n---------- /out/stmt-export-default-fn.js ----------\n// @__NO_SIDE_EFFECTS__\nexport default function f(y) {\n  sideEffect(y);\n}\nonlyKeepThisIdentifier;\nx(/* @__PURE__ */ f(\"keepThisCall\"));\n\n================================================================================\nTestPackageJsonSideEffectsArrayGlob\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/keep/this/file.js\nconsole.log(\"this should be kept\");\n\n================================================================================\nTestPackageJsonSideEffectsArrayKeep\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index.js\nconsole.log(\"hello\");\n\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsArrayKeepMainImplicitMain\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index-main.js\nvar index_main_exports = {};\n__export(index_main_exports, {\n  foo: () => foo\n});\nvar foo;\nvar init_index_main = __esm({\n  \"Users/user/project/node_modules/demo-pkg/index-main.js\"() {\n    foo = 123;\n    console.log(\"this should be kept\");\n  }\n});\n\n// Users/user/project/src/entry.js\ninit_index_main();\n\n// Users/user/project/src/require-demo-pkg.js\ninit_index_main();\n\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsArrayKeepMainImplicitModule\n---------- /out.js ----------\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsArrayKeepMainUseMain\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index-main.js\nconsole.log(\"this should be kept\");\n\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsArrayKeepMainUseModule\n---------- /out.js ----------\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsArrayKeepModuleImplicitMain\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index-main.js\nvar index_main_exports = {};\n__export(index_main_exports, {\n  foo: () => foo\n});\nvar foo;\nvar init_index_main = __esm({\n  \"Users/user/project/node_modules/demo-pkg/index-main.js\"() {\n    foo = 123;\n    console.log(\"this should be kept\");\n  }\n});\n\n// Users/user/project/src/require-demo-pkg.js\ninit_index_main();\n\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsArrayKeepModuleImplicitModule\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index-module.js\nconsole.log(\"this should be kept\");\n\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsArrayKeepModuleUseMain\n---------- /out.js ----------\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsArrayKeepModuleUseModule\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index-module.js\nconsole.log(\"this should be kept\");\n\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsArrayRemove\n---------- /out.js ----------\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsFalseAllFork\n---------- /out.js ----------\n// Users/user/project/node_modules/c/index.js\nvar foo;\nvar init_c = __esm({\n  \"Users/user/project/node_modules/c/index.js\"() {\n    foo = \"foo\";\n  }\n});\n\n// Users/user/project/node_modules/b/index.js\nvar init_b = __esm({\n  \"Users/user/project/node_modules/b/index.js\"() {\n    init_c();\n  }\n});\n\n// Users/user/project/node_modules/a/index.js\nvar a_exports = {};\n__export(a_exports, {\n  foo: () => foo\n});\nvar init_a = __esm({\n  \"Users/user/project/node_modules/a/index.js\"() {\n    init_b();\n  }\n});\n\n// Users/user/project/src/entry.js\nPromise.resolve().then(() => (init_a(), a_exports)).then((x) => assert(x.foo === \"foo\"));\n\n================================================================================\nTestPackageJsonSideEffectsFalseCrossPlatformSlash\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/foo.js\nconsole.log(\"foo\");\n\n// Users/user/project/node_modules/demo-pkg/bar/index.js\nconsole.log(\"bar\");\n\n================================================================================\nTestPackageJsonSideEffectsFalseIntermediateFilesChainAll\n---------- /out.js ----------\n// Users/user/project/node_modules/d/index.js\nvar foo = 123;\n\n// Users/user/project/node_modules/b/index.js\nthrow \"keep this\";\n\n// Users/user/project/src/entry.js\nconsole.log(foo);\n\n================================================================================\nTestPackageJsonSideEffectsFalseIntermediateFilesChainOne\n---------- /out.js ----------\n// Users/user/project/node_modules/d/index.js\nvar foo = 123;\n\n// Users/user/project/node_modules/b/index.js\nthrow \"keep this\";\n\n// Users/user/project/src/entry.js\nconsole.log(foo);\n\n================================================================================\nTestPackageJsonSideEffectsFalseIntermediateFilesDiamond\n---------- /out.js ----------\n// Users/user/project/node_modules/d/index.js\nvar foo = 123;\n\n// Users/user/project/node_modules/b1/index.js\nthrow \"keep this 1\";\n\n// Users/user/project/node_modules/b2/index.js\nthrow \"keep this 2\";\n\n// Users/user/project/src/entry.js\nconsole.log(foo);\n\n================================================================================\nTestPackageJsonSideEffectsFalseIntermediateFilesUnused\n---------- /out.js ----------\n\n================================================================================\nTestPackageJsonSideEffectsFalseIntermediateFilesUsed\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/foo.js\nvar foo = 123;\n\n// Users/user/project/node_modules/demo-pkg/index.js\nthrow \"keep this\";\n\n// Users/user/project/src/entry.js\nconsole.log(foo);\n\n================================================================================\nTestPackageJsonSideEffectsFalseKeepBareImportAndRequireCommonJS\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index.js\nvar require_demo_pkg = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/index.js\"(exports) {\n    exports.foo = 123;\n    console.log(\"hello\");\n  }\n});\n\n// Users/user/project/src/entry.js\nrequire_demo_pkg();\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsFalseKeepBareImportAndRequireES6\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index.js\nvar demo_pkg_exports = {};\n__export(demo_pkg_exports, {\n  foo: () => foo\n});\nvar foo;\nvar init_demo_pkg = __esm({\n  \"Users/user/project/node_modules/demo-pkg/index.js\"() {\n    foo = 123;\n    console.log(\"hello\");\n  }\n});\n\n// Users/user/project/src/entry.js\ninit_demo_pkg();\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsFalseKeepNamedImportCommonJS\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index.js\nvar require_demo_pkg = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/index.js\"(exports) {\n    exports.foo = 123;\n    console.log(\"hello\");\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_demo_pkg());\nconsole.log(import_demo_pkg.foo);\n\n================================================================================\nTestPackageJsonSideEffectsFalseKeepNamedImportES6\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index.js\nvar foo = 123;\nconsole.log(\"hello\");\n\n// Users/user/project/src/entry.js\nconsole.log(foo);\n\n================================================================================\nTestPackageJsonSideEffectsFalseKeepStarImportCommonJS\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index.js\nvar require_demo_pkg = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/index.js\"(exports) {\n    exports.foo = 123;\n    console.log(\"hello\");\n  }\n});\n\n// Users/user/project/src/entry.js\nvar ns = __toESM(require_demo_pkg());\nconsole.log(ns);\n\n================================================================================\nTestPackageJsonSideEffectsFalseKeepStarImportES6\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index.js\nvar demo_pkg_exports = {};\n__export(demo_pkg_exports, {\n  foo: () => foo\n});\nvar foo = 123;\nconsole.log(\"hello\");\n\n// Users/user/project/src/entry.js\nconsole.log(demo_pkg_exports);\n\n================================================================================\nTestPackageJsonSideEffectsFalseNoWarningInNodeModulesIssue999\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index.js\nconsole.log(\"unused import\");\n\n// Users/user/project/src/entry.js\nconsole.log(\"used import\");\n\n================================================================================\nTestPackageJsonSideEffectsFalseOneFork\n---------- /out.js ----------\n// Users/user/project/node_modules/c/index.js\nvar foo;\nvar init_c = __esm({\n  \"Users/user/project/node_modules/c/index.js\"() {\n    foo = \"foo\";\n  }\n});\n\n// Users/user/project/node_modules/d/index.js\nvar init_d = __esm({\n  \"Users/user/project/node_modules/d/index.js\"() {\n  }\n});\n\n// Users/user/project/node_modules/b/index.js\nvar init_b = __esm({\n  \"Users/user/project/node_modules/b/index.js\"() {\n    init_c();\n    init_d();\n  }\n});\n\n// Users/user/project/node_modules/a/index.js\nvar a_exports = {};\n__export(a_exports, {\n  foo: () => foo\n});\nvar init_a = __esm({\n  \"Users/user/project/node_modules/a/index.js\"() {\n    init_b();\n  }\n});\n\n// Users/user/project/src/entry.js\nPromise.resolve().then(() => (init_a(), a_exports)).then((x) => assert(x.foo === \"foo\"));\n\n================================================================================\nTestPackageJsonSideEffectsFalseRemoveBareImportCommonJS\n---------- /out.js ----------\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsFalseRemoveBareImportES6\n---------- /out.js ----------\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsFalseRemoveNamedImportCommonJS\n---------- /out.js ----------\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsFalseRemoveNamedImportES6\n---------- /out.js ----------\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsFalseRemoveStarImportCommonJS\n---------- /out.js ----------\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsFalseRemoveStarImportES6\n---------- /out.js ----------\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsKeepExportDefaultExpr\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index.js\nvar demo_pkg_default = exprWithSideEffects();\n\n// Users/user/project/src/entry.js\nconsole.log(demo_pkg_default);\n\n================================================================================\nTestPackageJsonSideEffectsNestedDirectoryRemove\n---------- /out.js ----------\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsTrueKeepCommonJS\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index.js\nvar require_demo_pkg = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/index.js\"(exports) {\n    exports.foo = 123;\n    console.log(\"hello\");\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_demo_pkg());\nconsole.log(\"unused import\");\n\n================================================================================\nTestPackageJsonSideEffectsTrueKeepES6\n---------- /out.js ----------\n// Users/user/project/node_modules/demo-pkg/index.js\nconsole.log(\"hello\");\n\n// Users/user/project/src/entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestPreserveDirectivesMinifyBundle\n---------- /out.js ----------\n\"use 1\";\n\"use 2\";\n\"use 3\";\n(() => {\n  // nested.js\n  //! A\n  //! B\n  //! C\n  nested();\n  //! D\n  //! E\n  //! F\n\n  // entry.js\n  //! 1\n  //! 2\n  //! 3\n  entry();\n  //! 4\n  //! 5\n  //! 6\n})();\n\n================================================================================\nTestPreserveDirectivesMinifyIIFE\n---------- /out.js ----------\n\"use 1\";\n\"use 2\";\n\"use 3\";\n(() => {\n  //! 1\n  //! 2\n  //! 3\n  entry();\n  //! 4\n  //! 5\n  //! 6\n})();\n\n================================================================================\nTestPreserveDirectivesMinifyPassThrough\n---------- /out.js ----------\n\"use 1\";\n\"use 2\";\n\"use 3\";\n//! 1\n//! 2\n//! 3\nentry();\n//! 4\n//! 5\n//! 6\n\n================================================================================\nTestPureCallsWithSpread\n---------- /out.js ----------\n// entry.js\n[...args];\n[...args];\n\n================================================================================\nTestRemoveCodeAfterLabelWithReturn\n---------- /out.js ----------\nfunction earlyReturn() {\n  onlyWithKeep();\n}\nfunction loop() {\n  if (foo()) {\n    bar();\n    return;\n  }\n}\n\n================================================================================\nTestRemoveTrailingReturn\n---------- /out.js ----------\n// entry.js\nfunction foo() {\n  a && b();\n}\nfunction bar() {\n  return a && b(), KEEP_ME;\n}\nvar entry_default = [\n  foo,\n  bar,\n  function() {\n    a && b();\n  },\n  function() {\n    return a && b(), KEEP_ME;\n  },\n  () => {\n    a && b();\n  },\n  () => (a && b(), KEEP_ME)\n];\nexport {\n  entry_default as default\n};\n\n================================================================================\nTestRemoveUnusedImportMeta\n---------- /out.js ----------\n// entry.js\nconsole.log(\"foo is unused\");\n\n================================================================================\nTestRemoveUnusedImports\n---------- /out.js ----------\nimport \"a\";\nimport \"b\";\nimport \"c\";\n\n================================================================================\nTestRemoveUnusedImportsEval\n---------- /out.js ----------\nimport a from \"a\";\nimport * as b from \"b\";\nimport { c } from \"c\";\neval(\"foo(a, b, c)\");\n\n================================================================================\nTestRemoveUnusedImportsEvalTS\n---------- /out.js ----------\neval(\"foo(a, b, c)\");\n\n================================================================================\nTestRemoveUnusedNoSideEffectsTaggedTemplates\n---------- /out.js ----------\n// entry.js\n// @__NO_SIDE_EFFECTS__\nfunction foo() {\n}\nuse(foo`keep`);\nkeep, alsoKeep;\n`${keep}${alsoKeep}`;\n\n================================================================================\nTestRemoveUnusedPureCommentCalls\n---------- /out.js ----------\n// entry.js\nfunction bar() {\n}\nvar bare = foo(bar);\nvar at_no = /* @__PURE__ */ foo(bar());\nvar new_at_no = /* @__PURE__ */ new foo(bar());\nvar nospace_at_no = /* @__PURE__ */ foo(bar());\nvar nospace_new_at_no = /* @__PURE__ */ new foo(bar());\nvar num_no = /* @__PURE__ */ foo(bar());\nvar new_num_no = /* @__PURE__ */ new foo(bar());\nvar nospace_num_no = /* @__PURE__ */ foo(bar());\nvar nospace_new_num_no = /* @__PURE__ */ new foo(bar());\nvar dot_no = /* @__PURE__ */ foo(sideEffect()).dot(bar());\nvar new_dot_no = /* @__PURE__ */ new foo(sideEffect()).dot(bar());\nvar nested_no = [1, /* @__PURE__ */ foo(bar()), 2];\nvar new_nested_no = [1, /* @__PURE__ */ new foo(bar()), 2];\nvar single_at_no = /* @__PURE__ */ foo(bar());\nvar new_single_at_no = /* @__PURE__ */ new foo(bar());\nvar single_num_no = /* @__PURE__ */ foo(bar());\nvar new_single_num_no = /* @__PURE__ */ new foo(bar());\nvar bad_no = (\n  /* __PURE__ */\n  foo(bar)\n);\nvar new_bad_no = (\n  /* __PURE__ */\n  new foo(bar)\n);\nvar parens_no = foo(bar);\nvar new_parens_no = new foo(bar);\nvar exp_no = /* @__PURE__ */ foo() ** foo();\nvar new_exp_no = /* @__PURE__ */ new foo() ** foo();\n\n================================================================================\nTestTextLoaderRemoveUnused\n---------- /out.js ----------\n// entry.js\nconsole.log(\"unused import\");\n\n================================================================================\nTestTopLevelFunctionInliningWithSpread\n---------- /out/entry.js ----------\n// entry.js\nfunction identity1(x) {\n  return x;\n}\nfunction identity3(x) {\n  return x;\n}\nargs;\n[...args];\nidentity1();\nargs;\nidentity3(...args);\n\n---------- /out/entry-outer.js ----------\n// inner.js\nfunction identity1(x) {\n  return x;\n}\nfunction identity3(x) {\n  return x;\n}\n\n// entry-outer.js\nargs;\n[...args];\nidentity1();\nargs;\nidentity3(...args);\n\n================================================================================\nTestTreeShakingBinaryOperators\n---------- /out.js ----------\n// entry.js\nvar keep;\nvar keep2;\nkeep + keep2;\nkeep - keep2;\nkeep * keep2;\nkeep / keep2;\nkeep % keep2;\nkeep ** keep2;\nkeep < keep2;\nkeep <= keep2;\nkeep > keep2;\nkeep >= keep2;\nkeep in keep2;\nkeep instanceof keep2;\nkeep << keep2;\nkeep >> keep2;\nkeep >>> keep2;\nkeep == keep2;\nkeep != keep2;\nkeep | keep2;\nkeep & keep2;\nkeep ^ keep2;\nkeep = keep2;\nkeep += keep2;\nkeep -= keep2;\nkeep *= keep2;\nkeep /= keep2;\nkeep %= keep2;\nkeep **= keep2;\nkeep <<= keep2;\nkeep >>= keep2;\nkeep >>>= keep2;\nkeep |= keep2;\nkeep &= keep2;\nkeep ^= keep2;\nkeep ??= keep2;\nkeep ||= keep2;\nkeep &&= keep2;\n\n================================================================================\nTestTreeShakingClassProperty\n---------- /out.js ----------\nlet keep1 = class {\n  [x] = \"x\";\n};\nlet keep2 = class {\n  [x]() {\n  }\n};\nlet keep3 = class {\n  get [x]() {\n  }\n};\nlet keep4 = class {\n  set [x](_) {\n  }\n};\nlet keep5 = class {\n  async [x]() {\n  }\n};\nlet keep6 = class {\n  [{ toString() {\n  } }] = \"x\";\n};\n\n================================================================================\nTestTreeShakingClassStaticProperty\n---------- /out.js ----------\nlet keep1 = class {\n  static x = x;\n};\nlet keep2 = class {\n  static [\"x\"] = x;\n};\nlet keep3 = class {\n  static [x] = \"x\";\n};\nlet keep4 = class {\n  static [x]() {\n  }\n};\nlet keep5 = class {\n  static get [x]() {\n  }\n};\nlet keep6 = class {\n  static set [x](_) {\n  }\n};\nlet keep7 = class {\n  static async [x]() {\n  }\n};\nlet keep8 = class {\n  static [{ toString() {\n  } }] = \"x\";\n};\n\n================================================================================\nTestTreeShakingImportIdentifier\n---------- /out.js ----------\n// b.js\nvar Base = class {\n};\n\n// a.js\nvar Keep = class extends Base {\n};\n\n// entry.js\nnew Keep();\n\n================================================================================\nTestTreeShakingInESMWrapper\n---------- /out.js ----------\n// lib.js\nvar keep1, keep2;\nvar init_lib = __esm({\n  \"lib.js\"() {\n    keep1 = () => \"keep1\";\n    keep2 = () => \"keep2\";\n  }\n});\n\n// cjs.js\nvar cjs_exports = {};\n__export(cjs_exports, {\n  default: () => cjs_default\n});\nvar cjs_default;\nvar init_cjs = __esm({\n  \"cjs.js\"() {\n    init_lib();\n    cjs_default = keep2();\n  }\n});\n\n// entry.js\ninit_lib();\nconsole.log(keep1(), (init_cjs(), __toCommonJS(cjs_exports)));\n\n================================================================================\nTestTreeShakingJSWithAssociatedCSS\n---------- /out/test.js ----------\n// project/node_modules/pkg/button.js\nvar Button;\n\n// project/test.jsx\nrender(/* @__PURE__ */ React.createElement(Button, null));\n\n---------- /out/test.css ----------\n/* project/node_modules/pkg/button.css */\nbutton {\n  color: red;\n}\n\n/* project/node_modules/pkg/menu.css */\nmenu {\n  color: red;\n}\n\n================================================================================\nTestTreeShakingJSWithAssociatedCSSExportStarSideEffectsFalse\n---------- /out/test.js ----------\n// project/node_modules/pkg/button.css\nvar require_button = __commonJS({\n  \"project/node_modules/pkg/button.css\"(exports, module) {\n    module.exports = {};\n  }\n});\n\n// project/node_modules/pkg/components.jsx\nrequire_button();\nvar Button = () => /* @__PURE__ */ React.createElement(\"button\", null);\n\n// project/test.jsx\nrender(/* @__PURE__ */ React.createElement(Button, null));\n\n---------- /out/test.css ----------\n/* project/node_modules/pkg/button.css */\nbutton {\n  color: red;\n}\n\n================================================================================\nTestTreeShakingJSWithAssociatedCSSExportStarSideEffectsFalseOnlyJS\n---------- /out/test.js ----------\n// project/node_modules/pkg/button.css\nvar require_button = __commonJS({\n  \"project/node_modules/pkg/button.css\"(exports, module) {\n    module.exports = {};\n  }\n});\n\n// project/node_modules/pkg/components.jsx\nrequire_button();\nvar Button = () => /* @__PURE__ */ React.createElement(\"button\", null);\n\n// project/test.jsx\nrender(/* @__PURE__ */ React.createElement(Button, null));\n\n---------- /out/test.css ----------\n/* project/node_modules/pkg/button.css */\nbutton {\n  color: red;\n}\n\n================================================================================\nTestTreeShakingJSWithAssociatedCSSReExportSideEffectsFalse\n---------- /out/test.js ----------\n// project/node_modules/pkg/button.css\nvar require_button = __commonJS({\n  \"project/node_modules/pkg/button.css\"(exports, module) {\n    module.exports = {};\n  }\n});\n\n// project/node_modules/pkg/components.jsx\nrequire_button();\nvar Button = () => /* @__PURE__ */ React.createElement(\"button\", null);\n\n// project/test.jsx\nrender(/* @__PURE__ */ React.createElement(Button, null));\n\n---------- /out/test.css ----------\n/* project/node_modules/pkg/button.css */\nbutton {\n  color: red;\n}\n\n================================================================================\nTestTreeShakingJSWithAssociatedCSSReExportSideEffectsFalseOnlyJS\n---------- /out/test.js ----------\n// project/node_modules/pkg/button.css\nvar require_button = __commonJS({\n  \"project/node_modules/pkg/button.css\"(exports, module) {\n    module.exports = {};\n  }\n});\n\n// project/node_modules/pkg/components.jsx\nrequire_button();\nvar Button = () => /* @__PURE__ */ React.createElement(\"button\", null);\n\n// project/test.jsx\nrender(/* @__PURE__ */ React.createElement(Button, null));\n\n---------- /out/test.css ----------\n/* project/node_modules/pkg/button.css */\nbutton {\n  color: red;\n}\n\n================================================================================\nTestTreeShakingJSWithAssociatedCSSUnusedNestedImportSideEffectsFalse\n---------- /out/test.js ----------\n// project/node_modules/pkg/button.jsx\nvar Button = () => /* @__PURE__ */ React.createElement(\"button\", null);\n\n// project/test.jsx\nrender(/* @__PURE__ */ React.createElement(Button, null));\n\n---------- /out/test.css ----------\n/* project/node_modules/pkg/styles.css */\nbutton {\n  color: red;\n}\n\n================================================================================\nTestTreeShakingJSWithAssociatedCSSUnusedNestedImportSideEffectsFalseOnlyJS\n---------- /out/test.js ----------\n// project/node_modules/pkg/button.jsx\nvar Button = () => /* @__PURE__ */ React.createElement(\"button\", null);\n\n// project/test.jsx\nrender(/* @__PURE__ */ React.createElement(Button, null));\n\n---------- /out/test.css ----------\n/* project/node_modules/pkg/styles.css */\nbutton {\n  color: red;\n}\n\n================================================================================\nTestTreeShakingLoweredClassStaticField\n---------- /out/entry.js ----------\n// entry.js\nvar KeepMe1 = class {\n};\n__publicField(KeepMe1, \"x\", \"x\");\n__publicField(KeepMe1, \"y\", sideEffects());\n__publicField(KeepMe1, \"z\", \"z\");\nvar KeepMe2 = class {\n};\n__publicField(KeepMe2, \"x\", \"x\");\n__publicField(KeepMe2, \"y\", \"y\");\n__publicField(KeepMe2, \"z\", \"z\");\nnew KeepMe2();\n\n================================================================================\nTestTreeShakingLoweredClassStaticFieldAssignment\n---------- /out/entry.js ----------\n// entry.ts\nvar KeepMe1 = class {\n};\nKeepMe1.x = \"x\";\nKeepMe1.y = \"y\";\nKeepMe1.z = \"z\";\nvar KeepMe2 = class {\n};\nKeepMe2.x = \"x\";\nKeepMe2.y = sideEffects();\nKeepMe2.z = \"z\";\nvar KeepMe3 = class {\n};\nKeepMe3.x = \"x\";\nKeepMe3.y = \"y\";\nKeepMe3.z = \"z\";\nnew KeepMe3();\n\n================================================================================\nTestTreeShakingLoweredClassStaticFieldMinified\n---------- /out/entry.js ----------\n// entry.js\nvar KeepMe1 = class {\n};\n__publicField(KeepMe1, \"x\", \"x\"), __publicField(KeepMe1, \"y\", sideEffects()), __publicField(KeepMe1, \"z\", \"z\");\nvar KeepMe2 = class {\n};\n__publicField(KeepMe2, \"x\", \"x\"), __publicField(KeepMe2, \"y\", \"y\"), __publicField(KeepMe2, \"z\", \"z\");\nnew KeepMe2();\n\n================================================================================\nTestTreeShakingNoBundleCJS\n---------- /out.js ----------\nfunction keep() {\n}\nfunction unused() {\n}\nkeep();\n\n================================================================================\nTestTreeShakingNoBundleESM\n---------- /out.js ----------\nfunction keep() {\n}\nfunction unused() {\n}\nkeep();\n\n================================================================================\nTestTreeShakingNoBundleIIFE\n---------- /out.js ----------\n(() => {\n  function keep() {\n  }\n  keep();\n})();\n\n================================================================================\nTestTreeShakingObjectProperty\n---------- /out.js ----------\nlet keep1 = { x };\nlet keep2 = { x };\nlet keep3 = { ...x };\nlet keep4 = { [x]: \"x\" };\nlet keep5 = { [x]() {\n} };\nlet keep6 = { get [x]() {\n} };\nlet keep7 = { set [x](_) {\n} };\nlet keep8 = { async [x]() {\n} };\nlet keep9 = { [{ toString() {\n} }]: \"x\" };\n\n================================================================================\nTestTreeShakingReactElements\n---------- /out.js ----------\n// entry.jsx\nfunction Foo() {\n}\nvar d = /* @__PURE__ */ React.createElement(\"div\", null);\nvar e = /* @__PURE__ */ React.createElement(Foo, null, d);\nvar f = /* @__PURE__ */ React.createElement(React.Fragment, null, e);\nconsole.log(f);\n\n================================================================================\nTestTreeShakingUnaryOperators\n---------- /out.js ----------\n(() => {\n  // entry.js\n  var keep;\n  +keep;\n  -keep;\n  ~keep;\n  delete keep;\n  ++keep;\n  --keep;\n  keep++;\n  keep--;\n})();\n"
  },
  {
    "path": "internal/bundler_tests/snapshots/snapshots_default.txt",
    "content": "TestAmbiguousReexportMsg\n---------- /out/entry.js ----------\n// a.js\nvar a = 1;\n\n// b.js\nvar b = 3;\n\n// c.js\nvar c = 4;\nexport {\n  a,\n  b,\n  c\n};\n\n================================================================================\nTestArgumentDefaultValueScopeNoBundle\n---------- /out.js ----------\nexport function a(o = foo) {\n  var r;\n  return o;\n}\nexport class b {\n  fn(r = foo) {\n    var f;\n    return r;\n  }\n}\nexport let c = [\n  function(o = foo) {\n    var r;\n    return o;\n  },\n  (o = foo) => {\n    var r;\n    return o;\n  },\n  { fn(o = foo) {\n    var r;\n    return o;\n  } },\n  class {\n    fn(o = foo) {\n      var r;\n      return o;\n    }\n  }\n];\n\n================================================================================\nTestArgumentsSpecialCaseNoBundle\n---------- /out.js ----------\n/* @__PURE__ */ (() => {\n  var r;\n  function t(n = arguments) {\n    return arguments;\n  }\n  (function(n = arguments) {\n    return arguments;\n  });\n  ({ foo(n = arguments) {\n    return arguments;\n  } });\n  class u {\n    foo(e = arguments) {\n      return arguments;\n    }\n  }\n  (class {\n    foo(n = arguments) {\n      return arguments;\n    }\n  });\n  function t(n = arguments) {\n    var arguments;\n    return arguments;\n  }\n  (function(n = arguments) {\n    var arguments;\n    return arguments;\n  });\n  ({ foo(n = arguments) {\n    var arguments;\n    return arguments;\n  } });\n  ((n) => r);\n  (() => r);\n  (async () => r);\n  ((n = r) => r);\n  (async (n = r) => r);\n  (n) => r;\n  () => r;\n  async () => r;\n  (n = r) => r;\n  async (n = r) => r;\n  ((n) => {\n    return r;\n  });\n  (() => {\n    return r;\n  });\n  (async () => {\n    return r;\n  });\n  ((n = r) => {\n    return r;\n  });\n  (async (n = r) => {\n    return r;\n  });\n  (n) => {\n    return r;\n  };\n  () => {\n    return r;\n  };\n  async () => {\n    return r;\n  };\n  (n = r) => {\n    return r;\n  };\n  async (n = r) => {\n    return r;\n  };\n})();\n\n================================================================================\nTestArrowFnScope\n---------- /out.js ----------\n// entry.js\ntests = {\n  0: ((s = (e) => s + e, t) => s + t),\n  1: ((s, t = (e) => t + e) => t + s),\n  2: ((s = (a = (c) => s + a + c, b) => s + a + b, t, e) => s + t + e),\n  3: ((s, t, e = (a, b = (c) => e + b + c) => e + b + a) => e + s + t),\n  4: (x = (s) => x + s, y, x + y),\n  5: (y, x = (s) => x + s, x + y),\n  6: (x = (s = (e) => x + s + e, t) => x + s + t, y, z, x + y + z),\n  7: (y, z, x = (s, t = (e) => x + t + e) => x + t + s, x + y + z)\n};\n\n================================================================================\nTestAutoExternal\n---------- /out/entry.js ----------\n// entry.js\nimport \"http://example.com/code.js\";\nimport \"https://example.com/code.js\";\nimport \"//example.com/code.js\";\nimport \"data:application/javascript;base64,ZXhwb3J0IGRlZmF1bHQgMTIz\";\n\n================================================================================\nTestAutoExternalNode\n---------- /out/entry.js ----------\n// entry.js\nimport fs from \"node:fs/promises\";\nimport \"node:what-is-this\";\nfs.readFile();\n\n================================================================================\nTestAvoidTDZ\n---------- /out.js ----------\n// entry.js\nvar Foo = class _Foo {\n  static foo = new _Foo();\n};\nvar foo = Foo.foo;\nconsole.log(foo);\nvar Bar = class {\n};\nvar bar = 123;\nexport {\n  Bar,\n  bar\n};\n\n================================================================================\nTestAvoidTDZNoBundle\n---------- /out.js ----------\nclass Foo {\n  static foo = new Foo();\n}\nlet foo = Foo.foo;\nconsole.log(foo);\nexport class Bar {\n}\nexport let bar = 123;\n\n================================================================================\nTestAwaitImportInsideTry\n---------- /out.js ----------\n// entry.js\nasync function main(name) {\n  try {\n    return await import(name);\n  } catch {\n  }\n}\nmain(\"fs\");\n\n================================================================================\nTestBuiltInNodeModulePrecedence\n---------- /out/entry.js ----------\n// node_modules/fs/abc.js\nvar require_abc = __commonJS({\n  \"node_modules/fs/abc.js\"() {\n    console.log(\"include this\");\n  }\n});\n\n// node_modules/fs/index.js\nvar require_fs = __commonJS({\n  \"node_modules/fs/index.js\"() {\n    console.log(\"include this too\");\n  }\n});\n\n// entry.js\nconsole.log([\n  // These are node core modules\n  require(\"fs\"),\n  require(\"fs/promises\"),\n  require(\"node:foo\"),\n  // These are not node core modules\n  require_abc(),\n  require_fs()\n]);\n\n================================================================================\nTestBundlingFilesOutsideOfOutbase\n---------- /out/_.._/_.._/_.._/src/entry.js ----------\n// src/entry.js\nconsole.log(\"test\");\n\n================================================================================\nTestCallImportNamespaceWarning\n---------- /out/js.js ----------\nimport * as a from \"a\";\nimport { b } from \"b\";\nimport c from \"c\";\na();\nb();\nc();\nnew a();\nnew b();\nnew c();\n\n---------- /out/ts.js ----------\nimport * as a from \"a\";\nimport { b } from \"b\";\nimport c from \"c\";\na();\nb();\nc();\nnew a();\nnew b();\nnew c();\n\n---------- /out/jsx-components.js ----------\nimport * as A from \"a\";\nimport { B } from \"b\";\nimport C from \"c\";\n/* @__PURE__ */ React.createElement(A, null);\n/* @__PURE__ */ React.createElement(B, null);\n/* @__PURE__ */ React.createElement(C, null);\n\n---------- /out/jsx-a.js ----------\nimport * as a from \"a\";\n/* @__PURE__ */ a(\"div\", null);\n\n---------- /out/jsx-b.js ----------\nimport { b } from \"b\";\n/* @__PURE__ */ b(\"div\", null);\n\n---------- /out/jsx-c.js ----------\nimport c from \"c\";\n/* @__PURE__ */ c(\"div\", null);\n\n================================================================================\nTestCharFreqIgnoreComments\n---------- /out/a.js ----------\n// a.js\nfunction u(e, t, n, r) {\n  return \"the argument names must be the same\";\n}\nexport {\n  u as default\n};\n\n---------- /out/b.js ----------\n// b.js\nfunction u(e, t, n, r) {\n  return \"the argument names must be the same\";\n}\nexport {\n  u as default\n};\n\n================================================================================\nTestCommentPreservation\n---------- /out/entry.js ----------\nconsole.log(\n  import(\n    /* before */\n    foo\n  ),\n  import(\n    /* before */\n    \"foo\"\n  ),\n  import(\n    foo\n    /* after */\n  ),\n  import(\n    \"foo\"\n    /* after */\n  )\n);\nconsole.log(\n  import(\n    \"foo\",\n    /* before */\n    { assert: { type: \"json\" } }\n  ),\n  import(\"foo\", {\n    /* before */\n    assert: { type: \"json\" }\n  }),\n  import(\"foo\", {\n    assert:\n      /* before */\n      { type: \"json\" }\n  }),\n  import(\"foo\", { assert: {\n    /* before */\n    type: \"json\"\n  } }),\n  import(\"foo\", { assert: {\n    type:\n      /* before */\n      \"json\"\n  } }),\n  import(\"foo\", { assert: {\n    type: \"json\"\n    /* before */\n  } }),\n  import(\"foo\", {\n    assert: { type: \"json\" }\n    /* before */\n  }),\n  import(\n    \"foo\",\n    { assert: { type: \"json\" } }\n    /* before */\n  )\n);\nconsole.log(\n  require(\n    /* before */\n    foo\n  ),\n  require(\n    /* before */\n    \"foo\"\n  ),\n  require(\n    foo\n    /* after */\n  ),\n  require(\n    \"foo\"\n    /* after */\n  )\n);\nconsole.log(\n  require.resolve(\n    /* before */\n    foo\n  ),\n  require.resolve(\n    /* before */\n    \"foo\"\n  ),\n  require.resolve(\n    foo\n    /* after */\n  ),\n  require.resolve(\n    \"foo\"\n    /* after */\n  )\n);\nlet [\n  /* foo */\n] = [\n  /* bar */\n];\nlet [\n  // foo\n] = [\n  // bar\n];\nlet [\n  /*before*/\n  ...s\n] = [\n  /*before*/\n  ...s\n];\nlet [.../*before*/\ns2] = [.../*before*/\ns2];\nlet {\n  /* foo */\n} = {\n  /* bar */\n};\nlet {\n  // foo\n} = {\n  // bar\n};\nlet {\n  /*before*/\n  ...s3\n} = {\n  /*before*/\n  ...s3\n};\nlet { .../*before*/\ns4 } = { .../*before*/\ns4 };\nlet [\n  /* before */\n  x\n] = [\n  /* before */\n  x\n];\nlet [\n  /* before */\n  x2\n  /* after */\n] = [\n  /* before */\n  x2\n  /* after */\n];\nlet [\n  // before\n  x3\n  // after\n] = [\n  // before\n  x3\n  // after\n];\nlet {\n  /* before */\n  y\n} = {\n  /* before */\n  y\n};\nlet {\n  /* before */\n  y2\n  /* after */\n} = {\n  /* before */\n  y2\n  /* after */\n};\nlet {\n  // before\n  y3\n  // after\n} = {\n  // before\n  y3\n  // after\n};\nlet {\n  /* before */\n  [y4]: y4\n} = {\n  /* before */\n  [y4]: y4\n};\nlet { [\n  /* before */\n  y5\n]: y5 } = { [\n  /* before */\n  y5\n]: y5 };\nlet { [\n  y6\n  /* after */\n]: y6 } = { [\n  y6\n  /* after */\n]: y6 };\nfoo[\n  /* before */\n  x\n] = foo[\n  /* before */\n  x\n];\nfoo[\n  x\n  /* after */\n] = foo[\n  x\n  /* after */\n];\nconsole.log(\n  // before\n  foo,\n  /* comment before */\n  bar\n  // comment after\n);\nconsole.log([\n  // before\n  foo,\n  /* comment before */\n  bar\n  // comment after\n]);\nconsole.log({\n  // before\n  foo,\n  /* comment before */\n  bar\n  // comment after\n});\nconsole.log(class {\n  // before\n  foo;\n  /* comment before */\n  bar;\n  // comment after\n});\nconsole.log(\n  () => {\n    return (\n      /* foo */\n      null\n    );\n  },\n  () => {\n    throw (\n      /* foo */\n      null\n    );\n  },\n  () => {\n    return (\n      /* foo */\n      null + 1\n    );\n  },\n  () => {\n    throw (\n      /* foo */\n      null + 1\n    );\n  },\n  () => {\n    return (\n      // foo\n      null + 1\n    );\n  },\n  () => {\n    throw (\n      // foo\n      null + 1\n    );\n  }\n);\nconsole.log(\n  /*a*/\n  a ? (\n    /*b*/\n    b\n  ) : (\n    /*c*/\n    c\n  ),\n  a ? b : c\n);\nfor (\n  /*foo*/\n  a;\n  ;\n) ;\nfor (\n  ;\n  /*foo*/\n  a;\n) ;\nfor (\n  ;\n  ;\n  /*foo*/\n  a\n) ;\nfor (\n  /*foo*/\n  a in b\n) ;\nfor (\n  a in\n  /*foo*/\n  b\n) ;\nfor (\n  /*foo*/\n  a of b\n) ;\nfor (\n  a of\n  /*foo*/\n  b\n) ;\nif (\n  /*foo*/\n  a\n) ;\nwith (\n  /*foo*/\n  a\n) ;\nwhile (\n  /*foo*/\n  a\n) ;\ndo {\n} while (\n  /*foo*/\n  a\n);\nswitch (\n  /*foo*/\n  a\n) {\n}\n\n================================================================================\nTestCommentPreservationImportAssertions\n---------- /out/entry.js ----------\n// entry.jsx\nimport \"foo\" assert { type: \"json\" };\nimport \"foo\" assert { type: \"json\" };\nimport \"foo\" assert {\n  /* before */\n  type: \"json\"\n};\nimport \"foo\" assert {\n  type:\n    /* before */\n    \"json\"\n};\nimport \"foo\" assert {\n  type: \"json\"\n  /* before */\n};\n\n================================================================================\nTestCommentPreservationPreserveJSX\n---------- /out/entry.js ----------\n// entry.jsx\nconsole.log(\n  <div x={\n    /*before*/\n    x\n  } />,\n  <div x={\n    /*before*/\n    \"y\"\n  } />,\n  <div x={\n    /*before*/\n    true\n  } />,\n  <div {\n    /*before*/\n    ...x\n  } />,\n  <div>{\n    /*before*/\n    x\n  }</div>,\n  <>{\n    /*before*/\n    x\n  }</>,\n  // Comments on absent AST nodes\n  <div>before{}after</div>,\n  <div>before{\n    /* comment 1 */\n    /* comment 2 */\n  }after</div>,\n  <div>before{\n    // comment 1\n    // comment 2\n  }after</div>,\n  <>before{}after</>,\n  <>before{\n    /* comment 1 */\n    /* comment 2 */\n  }after</>,\n  <>before{\n    // comment 1\n    // comment 2\n  }after</>\n);\n\n================================================================================\nTestCommentPreservationTransformJSX\n---------- /out/entry.js ----------\n// entry.jsx\nconsole.log(\n  /* @__PURE__ */ React.createElement(\"div\", { x: (\n    /*before*/\n    x\n  ) }),\n  /* @__PURE__ */ React.createElement(\"div\", { x: (\n    /*before*/\n    \"y\"\n  ) }),\n  /* @__PURE__ */ React.createElement(\"div\", { x: (\n    /*before*/\n    true\n  ) }),\n  /* @__PURE__ */ React.createElement(\"div\", {\n    /*before*/\n    ...x\n  }),\n  /* @__PURE__ */ React.createElement(\n    \"div\",\n    null,\n    /*before*/\n    x\n  ),\n  /* @__PURE__ */ React.createElement(\n    React.Fragment,\n    null,\n    /*before*/\n    x\n  ),\n  // Comments on absent AST nodes\n  /* @__PURE__ */ React.createElement(\"div\", null, \"before\", \"after\"),\n  /* @__PURE__ */ React.createElement(\"div\", null, \"before\", \"after\"),\n  /* @__PURE__ */ React.createElement(\"div\", null, \"before\", \"after\"),\n  /* @__PURE__ */ React.createElement(React.Fragment, null, \"before\", \"after\"),\n  /* @__PURE__ */ React.createElement(React.Fragment, null, \"before\", \"after\"),\n  /* @__PURE__ */ React.createElement(React.Fragment, null, \"before\", \"after\")\n);\n\n================================================================================\nTestCommonJSFromES6\n---------- /out.js ----------\n// foo.js\nvar foo_exports = {};\n__export(foo_exports, {\n  foo: () => foo\n});\nfunction foo() {\n  return \"foo\";\n}\nvar init_foo = __esm({\n  \"foo.js\"() {\n  }\n});\n\n// bar.js\nvar bar_exports = {};\n__export(bar_exports, {\n  bar: () => bar\n});\nfunction bar() {\n  return \"bar\";\n}\nvar init_bar = __esm({\n  \"bar.js\"() {\n  }\n});\n\n// entry.js\nvar { foo: foo2 } = (init_foo(), __toCommonJS(foo_exports));\nconsole.log(foo2(), bar2());\nvar { bar: bar2 } = (init_bar(), __toCommonJS(bar_exports));\n\n================================================================================\nTestConditionalImport\n---------- /out/a.js ----------\n// import.js\nvar require_import = __commonJS({\n  \"import.js\"(exports) {\n    exports.foo = 213;\n  }\n});\n\n// a.js\nx ? import(\"a\") : y ? Promise.resolve().then(() => __toESM(require_import())) : import(\"c\");\n\n---------- /out/b.js ----------\n// import.js\nvar require_import = __commonJS({\n  \"import.js\"(exports) {\n    exports.foo = 213;\n  }\n});\n\n// b.js\nx ? y ? import(\"a\") : Promise.resolve().then(() => __toESM(require_import())) : import(c);\n\n================================================================================\nTestConditionalRequire\n---------- /out.js ----------\n// b.js\nvar require_b = __commonJS({\n  \"b.js\"(exports) {\n    exports.foo = 213;\n  }\n});\n\n// a.js\nx ? __require(\"a\") : y ? require_b() : __require(\"c\");\nx ? y ? __require(\"a\") : require_b() : __require(c);\n\n================================================================================\nTestConditionalRequireResolve\n---------- /out.js ----------\n// a.js\nx ? require.resolve(\"a\") : y ? require.resolve(\"b\") : require.resolve(\"c\");\nx ? y ? require.resolve(\"a\") : require.resolve(\"b\") : require.resolve(c);\n\n================================================================================\nTestConstWithLet\n---------- /out.js ----------\n// entry.js\nconsole.log(1);\nconsole.log(2);\nunknownFn(3);\nfor (let c = x; ; ) console.log(c);\nfor (let d in x) console.log(d);\nfor (let e of x) console.log(e);\n\n================================================================================\nTestConstWithLetNoBundle\n---------- /out.js ----------\nconst a = 1;\nconsole.log(1), console.log(2), unknownFn(3);\nfor (const c = x; ; ) console.log(c);\nfor (const d in x) console.log(d);\nfor (const e of x) console.log(e);\n\n================================================================================\nTestConstWithLetNoMangle\n---------- /out.js ----------\n// entry.js\nvar a = 1;\nconsole.log(a);\nif (true) {\n  const b = 2;\n  console.log(b);\n}\nfor (const c = x; ; ) console.log(c);\nfor (const d in x) console.log(d);\nfor (const e of x) console.log(e);\n\n================================================================================\nTestDecoratorPrintingCJS\n---------- /out.js ----------\n// entry.js\nvar import_somewhere = require(\"somewhere\");\n_ = class {\n  #bar;\n  classes = [\n    class {\n      @import_somewhere.imported @((0, import_somewhere.imported)()) imported;\n    },\n    class {\n      @unbound @unbound() unbound;\n    },\n    class {\n      @(123) @(123()) constant;\n    },\n    class {\n      @(void 0) @((void 0)()) undef;\n    },\n    class {\n      @(element[access]) indexed;\n    },\n    class {\n      @foo.#bar private;\n    },\n    class {\n      @(foo[\"ヿ\"]) unicode;\n    },\n    class {\n      @(() => {\n      }) arrow;\n    }\n  ];\n};\n\n================================================================================\nTestDecoratorPrintingESM\n---------- /out.js ----------\n// entry.js\nimport { imported } from \"somewhere\";\n_ = class {\n  #bar;\n  classes = [\n    class {\n      @imported @imported() imported;\n    },\n    class {\n      @unbound @unbound() unbound;\n    },\n    class {\n      @(123) @(123()) constant;\n    },\n    class {\n      @(void 0) @((void 0)()) undef;\n    },\n    class {\n      @(element[access]) indexed;\n    },\n    class {\n      @foo.#bar private;\n    },\n    class {\n      @(foo[\"ヿ\"]) unicode;\n    },\n    class {\n      @(() => {\n      }) arrow;\n    }\n  ];\n};\n\n================================================================================\nTestDefineAssignWarning\n---------- /out/read.js ----------\n// read.js\nconsole.log(\n  [null, null, null],\n  [ident, ident, ident],\n  [dot.chain, dot.chain, dot.chain]\n);\n\n---------- /out/write.js ----------\n// write.js\nconsole.log(\n  [a = 0, b.c = 0, b[\"c\"] = 0],\n  [ident = 0, ident = 0, ident = 0],\n  [dot.chain = 0, dot.chain = 0, dot.chain = 0]\n);\n\n================================================================================\nTestDefineImportMeta\n---------- /out.js ----------\n// entry.js\nconsole.log(\n  // These should be fully substituted\n  1,\n  2,\n  3,\n  // Should just substitute \"import.meta.foo\"\n  2 .baz,\n  // This should not be substituted\n  1 .bar\n);\n\n================================================================================\nTestDefineImportMetaES5\n---------- /out/replaced.js ----------\n// replaced.js\nconsole.log(1);\n\n---------- /out/kept.js ----------\n// kept.js\nvar import_meta = {};\nconsole.log(import_meta.y);\n\n---------- /out/dead-code.js ----------\n\n================================================================================\nTestDefineInfiniteLoopIssue2407\n---------- /out.js ----------\n// entry.js\nb.c();\ny();\n\n================================================================================\nTestDefineOptionalChain\n---------- /out.js ----------\n// entry.js\nconsole.log([\n  1,\n  1,\n  1\n], [\n  1,\n  1,\n  1\n], [\n  a[b][c],\n  a?.[b][c],\n  a[b]?.[c]\n]);\n\n================================================================================\nTestDefineOptionalChainLowered\n---------- /out.js ----------\n// entry.js\nvar _a;\nconsole.log([\n  1,\n  1,\n  1\n], [\n  1,\n  1,\n  1\n], [\n  a[b][c],\n  a == null ? void 0 : a[b][c],\n  (_a = a[b]) == null ? void 0 : _a[c]\n]);\n\n================================================================================\nTestDefineOptionalChainPanicIssue3551\n---------- /out/id-define.js ----------\n// id-define.js\n1?.y.z;\n(1?.y).z;\n1?.y[\"z\"];\n(1?.y)[\"z\"];\n1?.y();\n(1?.y)();\n1?.y.z();\n(1?.y).z();\n1?.y[\"z\"]();\n(1?.y)[\"z\"]();\ndelete 1?.y.z;\ndelete (1?.y).z;\ndelete 1?.y[\"z\"];\ndelete (1?.y)[\"z\"];\n\n---------- /out/dot-define.js ----------\n// dot-define.js\n1 .c;\n1 .c;\n1[\"c\"];\n1[\"c\"];\n1();\n1();\n1 .c();\n1 .c();\n1[\"c\"]();\n1[\"c\"]();\ndelete 1 .c;\ndelete 1 .c;\ndelete 1[\"c\"];\ndelete 1[\"c\"];\n\n================================================================================\nTestDefineThis\n---------- /out.js ----------\n// entry.js\nok(\n  // These should be fully substituted\n  1,\n  2,\n  3,\n  // Should just substitute \"this.foo\"\n  2 .baz,\n  // This should not be substituted\n  1 .bar\n);\n(() => {\n  ok(\n    1,\n    2,\n    3,\n    2 .baz,\n    1 .bar\n  );\n})();\n(function() {\n  doNotSubstitute(\n    this,\n    this.foo,\n    this.foo.bar,\n    this.foo.baz,\n    this.bar\n  );\n})();\n\n================================================================================\nTestDirectEvalTaintingNoBundle\n---------- /out.js ----------\nfunction test1() {\n  function add(n, t) {\n    return n + t;\n  }\n  eval(\"add(1, 2)\");\n}\nfunction test2() {\n  function n(t, e) {\n    return t + e;\n  }\n  (0, eval)(\"add(1, 2)\");\n}\nfunction test3() {\n  function n(t, e) {\n    return t + e;\n  }\n}\nfunction test4(eval) {\n  function add(n, t) {\n    return n + t;\n  }\n  eval(\"add(1, 2)\");\n}\nfunction test5() {\n  function containsDirectEval() {\n    eval();\n  }\n  if (true) {\n    var shouldNotBeRenamed;\n  }\n}\n\n================================================================================\nTestDotImport\n---------- /out.js ----------\n// index.js\nvar require_index = __commonJS({\n  \"index.js\"(exports) {\n    exports.x = 123;\n  }\n});\n\n// entry.js\nvar import__ = __toESM(require_index());\nconsole.log(import__.x);\n\n================================================================================\nTestDuplicateEntryPoint\n---------- /out.js/entry.js ----------\n// entry.js\nconsole.log(123);\n\n================================================================================\nTestDuplicatePropertyWarning\n---------- /out/entry.js ----------\n// outside-node-modules/index.jsx\nconsole.log({ a: 1, a: 2 }, /* @__PURE__ */ React.createElement(\"div\", { a2: true, a2: 3 }));\n\n// node_modules/inside-node-modules/index.jsx\nconsole.log({ c: 1, c: 2 }, /* @__PURE__ */ React.createElement(\"div\", { c2: true, c2: 3 }));\n\n================================================================================\nTestDynamicImportWithExpressionCJS\n---------- /out.js ----------\nimport(\"foo\");\nimport(foo());\n\n================================================================================\nTestDynamicImportWithTemplateIIFE\n---------- /out.js ----------\n(() => {\n  // b.js\n  var require_b = __commonJS({\n    \"b.js\"(exports) {\n      exports.x = 123;\n    }\n  });\n\n  // a.js\n  Promise.resolve().then(() => __toESM(require_b())).then((ns) => console.log(ns));\n  Promise.resolve().then(() => __toESM(require_b())).then((ns) => console.log(ns));\n})();\n\n================================================================================\nTestES6FromCommonJS\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports) {\n    exports.foo = function() {\n      return \"foo\";\n    };\n  }\n});\n\n// bar.js\nvar require_bar = __commonJS({\n  \"bar.js\"(exports) {\n    exports.bar = function() {\n      return \"bar\";\n    };\n  }\n});\n\n// entry.js\nvar import_foo = __toESM(require_foo());\nvar import_bar = __toESM(require_bar());\nconsole.log((0, import_foo.foo)(), (0, import_bar.bar)());\n\n================================================================================\nTestEmptyExportClauseBundleAsCommonJSIssue910\n---------- /out.js ----------\n// types.mjs\nvar types_exports = {};\nvar init_types = __esm({\n  \"types.mjs\"() {\n  }\n});\n\n// entry.js\nconsole.log((init_types(), __toCommonJS(types_exports)));\n\n================================================================================\nTestEntryNamesChunkNamesExtPlaceholder\n---------- /out/main/js/entry1-4X3SO762.js ----------\nimport \"../../common/js/chunk-XHGYOYUR.js\";\n\n// src/entries/entry1.js\nconsole.log(\"entry1\");\n\n---------- /out/main/js/entry2-URQRHZS5.js ----------\nimport \"../../common/js/chunk-XHGYOYUR.js\";\n\n// src/entries/entry2.js\nconsole.log(\"entry2\");\n\n---------- /out/common/js/chunk-XHGYOYUR.js ----------\n// src/lib/shared.js\nconsole.log(\"shared\");\n\n---------- /out/main/css/entry1-3JZGIUSL.css ----------\n/* src/entries/entry1.css */\na:after {\n  content: \"entry1\";\n}\n\n---------- /out/main/css/entry2-NXZBPPIA.css ----------\n/* src/entries/entry2.css */\na:after {\n  content: \"entry2\";\n}\n\n================================================================================\nTestEntryNamesNoSlashAfterDir\n---------- /out/app1-main.js ----------\nconsole.log(1);\n\n---------- /out/app2-main.js ----------\nconsole.log(2);\n\n---------- /out/-customPath.js ----------\nconsole.log(3);\n\n================================================================================\nTestEntryNamesNonPortableCharacter\n---------- /out/entry1-_.js ----------\nconsole.log(1);\n\n---------- /out/entry2-*.js ----------\nconsole.log(2);\n\n================================================================================\nTestExportChain\n---------- /out.js ----------\n// bar.js\nvar c = 123;\nexport {\n  c as a\n};\n\n================================================================================\nTestExportFSNode\n---------- /out.js ----------\n// entry.js\nimport * as fs from \"fs\";\nimport { readFileSync } from \"fs\";\nexport {\n  fs,\n  readFileSync\n};\n\n================================================================================\nTestExportFSNodeInCommonJSModule\n---------- /out.js ----------\n// entry.js\nimport * as fs from \"fs\";\nimport { readFileSync } from \"fs\";\nvar require_entry = __commonJS({\n  \"entry.js\"(exports) {\n    exports.fs = fs;\n    exports.readFileSync = readFileSync;\n    exports.foo = 123;\n  }\n});\nexport default require_entry();\n\n================================================================================\nTestExportFormsCommonJS\n---------- /out.js ----------\n// a.js\nvar abc;\nvar init_a = __esm({\n  \"a.js\"() {\n    abc = void 0;\n  }\n});\n\n// b.js\nvar b_exports = {};\n__export(b_exports, {\n  xyz: () => xyz\n});\nvar xyz;\nvar init_b = __esm({\n  \"b.js\"() {\n    xyz = null;\n  }\n});\n\n// commonjs.js\nvar commonjs_exports = {};\n__export(commonjs_exports, {\n  C: () => Class,\n  Class: () => Class,\n  Fn: () => Fn,\n  abc: () => abc,\n  b: () => b_exports,\n  c: () => c,\n  default: () => commonjs_default,\n  l: () => l,\n  v: () => v\n});\nfunction Fn() {\n}\nvar commonjs_default, v, l, c, Class;\nvar init_commonjs = __esm({\n  \"commonjs.js\"() {\n    init_a();\n    init_b();\n    commonjs_default = 123;\n    v = 234;\n    l = 234;\n    c = 234;\n    Class = class {\n    };\n  }\n});\n\n// c.js\nvar c_exports = {};\n__export(c_exports, {\n  default: () => c_default\n});\nvar c_default;\nvar init_c = __esm({\n  \"c.js\"() {\n    c_default = class {\n    };\n  }\n});\n\n// d.js\nvar d_exports = {};\n__export(d_exports, {\n  default: () => Foo\n});\nvar Foo;\nvar init_d = __esm({\n  \"d.js\"() {\n    Foo = class {\n    };\n    Foo.prop = 123;\n  }\n});\n\n// e.js\nvar e_exports = {};\n__export(e_exports, {\n  default: () => e_default\n});\nfunction e_default() {\n}\nvar init_e = __esm({\n  \"e.js\"() {\n  }\n});\n\n// f.js\nvar f_exports = {};\n__export(f_exports, {\n  default: () => foo\n});\nfunction foo() {\n}\nvar init_f = __esm({\n  \"f.js\"() {\n    foo.prop = 123;\n  }\n});\n\n// g.js\nvar g_exports = {};\n__export(g_exports, {\n  default: () => g_default\n});\nasync function g_default() {\n}\nvar init_g = __esm({\n  \"g.js\"() {\n  }\n});\n\n// h.js\nvar h_exports = {};\n__export(h_exports, {\n  default: () => foo2\n});\nasync function foo2() {\n}\nvar init_h = __esm({\n  \"h.js\"() {\n    foo2.prop = 123;\n  }\n});\n\n// entry.js\ninit_commonjs();\ninit_c();\ninit_d();\ninit_e();\ninit_f();\ninit_g();\ninit_h();\n\n================================================================================\nTestExportFormsES6\n---------- /out.js ----------\n// a.js\nvar abc = void 0;\n\n// b.js\nvar b_exports = {};\n__export(b_exports, {\n  xyz: () => xyz\n});\nvar xyz = null;\n\n// entry.js\nvar entry_default = 123;\nvar v = 234;\nvar l = 234;\nvar c = 234;\nfunction Fn() {\n}\nvar Class = class {\n};\nexport {\n  Class as C,\n  Class,\n  Fn,\n  abc,\n  b_exports as b,\n  c,\n  entry_default as default,\n  l,\n  v\n};\n\n================================================================================\nTestExportFormsIIFE\n---------- /out.js ----------\nvar globalName = (() => {\n  // entry.js\n  var entry_exports = {};\n  __export(entry_exports, {\n    C: () => Class,\n    Class: () => Class,\n    Fn: () => Fn,\n    abc: () => abc,\n    b: () => b_exports,\n    c: () => c,\n    default: () => entry_default,\n    l: () => l,\n    v: () => v\n  });\n\n  // a.js\n  var abc = void 0;\n\n  // b.js\n  var b_exports = {};\n  __export(b_exports, {\n    xyz: () => xyz\n  });\n  var xyz = null;\n\n  // entry.js\n  var entry_default = 123;\n  var v = 234;\n  var l = 234;\n  var c = 234;\n  function Fn() {\n  }\n  var Class = class {\n  };\n  return __toCommonJS(entry_exports);\n})();\n\n================================================================================\nTestExportFormsWithMinifyIdentifiersAndNoBundle\n---------- /out/a.js ----------\nexport default 123;\nexport var varName = 234;\nexport let letName = 234;\nexport const constName = 234;\nfunction s() {\n}\nclass t {\n}\nexport { Class as Cls, s as Fn2, t as Cls2 };\nexport function Func() {\n}\nexport class Class {\n}\nexport * from \"./a\";\nexport * as fromB from \"./b\";\n\n---------- /out/b.js ----------\nexport default function() {\n}\n\n---------- /out/c.js ----------\nexport default function o() {\n}\n\n---------- /out/d.js ----------\nexport default class {\n}\n\n---------- /out/e.js ----------\nexport default class o {\n}\n\n================================================================================\nTestExportSpecialName\n---------- /out.js ----------\nvar entry_exports = {};\n__export(entry_exports, {\n  [\"__proto__\"]: () => __proto__\n});\nmodule.exports = __toCommonJS(entry_exports);\nconst __proto__ = 123;\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n  __proto__\n});\n\n================================================================================\nTestExportSpecialNameBundle\n---------- /out.js ----------\n// lib.mjs\nvar lib_exports = {};\n__export(lib_exports, {\n  [\"__proto__\"]: () => __proto__\n});\nvar __proto__;\nvar init_lib = __esm({\n  \"lib.mjs\"() {\n    __proto__ = 123;\n  }\n});\n\n// entry.js\nvar lib = (init_lib(), __toCommonJS(lib_exports));\nconsole.log(lib.__proto__);\n\n================================================================================\nTestExportWildcardFSNodeCommonJS\n---------- /out.js ----------\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  foo: () => foo\n});\nmodule.exports = __toCommonJS(entry_exports);\n__reExport(entry_exports, require(\"fs\"), module.exports);\n\n// internal.js\nvar foo = 123;\n\n// entry.js\n__reExport(entry_exports, require(\"./external\"), module.exports);\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n  foo,\n  ...require(\"fs\"),\n  ...require(\"./external\")\n});\n\n================================================================================\nTestExportWildcardFSNodeES6\n---------- /out.js ----------\n// entry.js\nexport * from \"fs\";\n\n// internal.js\nvar foo = 123;\n\n// entry.js\nexport * from \"./external\";\nexport {\n  foo\n};\n\n================================================================================\nTestExportsAndModuleFormatCommonJS\n---------- /out.js ----------\n// foo/test.js\nvar test_exports = {};\n__export(test_exports, {\n  foo: () => foo\n});\nvar foo = 123;\n\n// bar/test.js\nvar test_exports2 = {};\n__export(test_exports2, {\n  bar: () => bar\n});\nvar bar = 123;\n\n// entry.js\nconsole.log(exports, module.exports, test_exports, test_exports2);\n\n================================================================================\nTestExternalES6ConvertedToCommonJS\n---------- /out.js ----------\n// a.js\nvar a_exports = {};\n__export(a_exports, {\n  ns: () => ns\n});\nimport * as ns from \"x\";\nvar init_a = __esm({\n  \"a.js\"() {\n  }\n});\n\n// b.js\nvar b_exports = {};\n__export(b_exports, {\n  ns: () => ns2\n});\nimport * as ns2 from \"x\";\nvar init_b = __esm({\n  \"b.js\"() {\n  }\n});\n\n// c.js\nvar c_exports = {};\n__export(c_exports, {\n  ns: () => ns3\n});\nimport * as ns3 from \"x\";\nvar init_c = __esm({\n  \"c.js\"() {\n  }\n});\n\n// d.js\nvar d_exports = {};\n__export(d_exports, {\n  ns: () => ns4\n});\nimport { ns as ns4 } from \"x\";\nvar init_d = __esm({\n  \"d.js\"() {\n  }\n});\n\n// e.js\nvar e_exports = {};\nimport * as x_star from \"x\";\nvar init_e = __esm({\n  \"e.js\"() {\n    __reExport(e_exports, x_star);\n  }\n});\n\n// entry.js\ninit_a();\ninit_b();\ninit_c();\ninit_d();\ninit_e();\n\n================================================================================\nTestExternalModuleExclusionPackage\n---------- /out.js ----------\n// index.js\nimport { S3 } from \"aws-sdk\";\nimport { DocumentClient } from \"aws-sdk/clients/dynamodb\";\nvar s3 = new S3();\nvar dynamodb = new DocumentClient();\nexport {\n  dynamodb,\n  s3\n};\n\n================================================================================\nTestExternalModuleExclusionRelativePath\n---------- /Users/user/project/out/index.js ----------\n// Users/user/project/src/nested/folder/test.js\nimport foo from \"../src/nested/folder/foo.js\";\nimport out from \"./in-out-dir.js\";\nimport sha256 from \"../src/sha256.min.js\";\nimport config from \"/api/config?a=1&b=2\";\nconsole.log(foo, out, sha256, config);\n\n================================================================================\nTestExternalPackages\n---------- /out.js ----------\n// project/entry.js\nimport \"pkg1\";\n\n// project/file.js\nconsole.log(\"file\");\n\n// project/node_modules/pkg2/index.js\nconsole.log(\"pkg2\");\n\n// project/libs/pkg3.js\nconsole.log(\"pkg3\");\n\n================================================================================\nTestExternalWildcardDoesNotMatchEntryPoint\n---------- /out.js ----------\n// entry.js\nimport \"foo\";\n\n================================================================================\nTestFalseRequire\n---------- /out.js ----------\n// entry.js\n((require2) => require2(\"/test.txt\"))();\n\n================================================================================\nTestHashbangBannerUseStrictOrder\n---------- /out.js ----------\n#! in file\n#! from banner\n\"use strict\";\n(() => {\n  // entry.js\n  foo();\n})();\n\n================================================================================\nTestHashbangBundle\n---------- /out.js ----------\n#!/usr/bin/env a\n\n// code.js\nvar code = 0;\n\n// entry.js\nprocess.exit(code);\n\n================================================================================\nTestHashbangNoBundle\n---------- /out.js ----------\n#!/usr/bin/env node\nprocess.exit(0);\n\n================================================================================\nTestIIFE_ES5\n---------- /out.js ----------\n(function() {\n  // entry.js\n  console.log(\"test\");\n})();\n\n================================================================================\nTestImportAbsPathAsDir\n---------- /out/entry.js ----------\n// Users/user/project/node_modules/pkg/index.js\nvar pkg_default = 123;\n\n// Users/user/project/entry.js\nconsole.log(pkg_default);\n\n================================================================================\nTestImportAbsPathAsFile\n---------- /out/entry.js ----------\n// Users/user/project/node_modules/pkg/index.js\nvar pkg_default = 123;\n\n// Users/user/project/entry.js\nconsole.log(pkg_default);\n\n================================================================================\nTestImportAbsPathWithQueryParameter\n---------- /out/entry.js ----------\n// Users/user/project/file.txt?foo\nvar file_default = \"This is some text\";\n\n// Users/user/project/file.txt#bar\nvar file_default2 = \"This is some text\";\n\n// Users/user/project/entry.js\nconsole.log(file_default, file_default2);\n\n================================================================================\nTestImportFSNodeCommonJS\n---------- /out.js ----------\n// entry.js\nvar fs = __toESM(require(\"fs\"));\nvar import_fs = __toESM(require(\"fs\"));\nvar import_fs2 = require(\"fs\");\nconsole.log(fs, import_fs2.readFileSync, import_fs.default);\n\n================================================================================\nTestImportFSNodeES6\n---------- /out.js ----------\n// entry.js\nimport * as fs from \"fs\";\nimport defaultValue from \"fs\";\nimport { readFileSync } from \"fs\";\nconsole.log(fs, readFileSync, defaultValue);\n\n================================================================================\nTestImportFormsWithMinifyIdentifiersAndNoBundle\n---------- /out.js ----------\nimport \"foo\";\nimport {} from \"foo\";\nimport * as o from \"foo\";\nimport { a as r, b as m } from \"foo\";\nimport t from \"foo\";\nimport f, * as i from \"foo\";\nimport p, { a2 as s, b as n } from \"foo\";\nconst a = [\n  import(\"foo\"),\n  function() {\n    return import(\"foo\");\n  }\n];\nconsole.log(o, r, m, t, f, i, p, s, n, a);\n\n================================================================================\nTestImportFormsWithNoBundle\n---------- /out.js ----------\nimport \"foo\";\nimport {} from \"foo\";\nimport * as ns from \"foo\";\nimport { a, b as c } from \"foo\";\nimport def from \"foo\";\nimport def2, * as ns2 from \"foo\";\nimport def3, { a2, b as c3 } from \"foo\";\nconst imp = [\n  import(\"foo\"),\n  function nested() {\n    return import(\"foo\");\n  }\n];\nconsole.log(ns, a, c, def, def2, ns2, def3, a2, c3, imp);\n\n================================================================================\nTestImportMetaCommonJS\n---------- /out.js ----------\n// entry.js\nvar import_meta = {};\nconsole.log(import_meta.url, import_meta.path);\n\n================================================================================\nTestImportMetaES6\n---------- /out.js ----------\n// entry.js\nconsole.log(import.meta.url, import.meta.path);\n\n================================================================================\nTestImportMetaNoBundle\n---------- /out.js ----------\nconsole.log(import.meta.url, import.meta.path);\n\n================================================================================\nTestImportMissingCommonJS\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports) {\n    exports.x = 123;\n  }\n});\n\n// entry.js\nvar import_foo = __toESM(require_foo());\nconsole.log((0, import_foo.default)(import_foo.x, import_foo.y));\n\n================================================================================\nTestImportMissingNeitherES6NorCommonJS\n---------- /out/named.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"() {\n    console.log(\"no exports here\");\n  }\n});\n\n// named.js\nvar import_foo = __toESM(require_foo());\nconsole.log((0, import_foo.default)(void 0, void 0));\n\n---------- /out/star.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"() {\n    console.log(\"no exports here\");\n  }\n});\n\n// star.js\nvar ns = __toESM(require_foo());\nconsole.log(ns.default(void 0, void 0));\n\n---------- /out/star-capture.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"() {\n    console.log(\"no exports here\");\n  }\n});\n\n// star-capture.js\nvar ns = __toESM(require_foo());\nconsole.log(ns);\n\n---------- /out/bare.js ----------\n// foo.js\nconsole.log(\"no exports here\");\n\n---------- /out/require.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"() {\n    console.log(\"no exports here\");\n  }\n});\n\n// require.js\nconsole.log(require_foo());\n\n---------- /out/import.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"() {\n    console.log(\"no exports here\");\n  }\n});\n\n// import.js\nconsole.log(Promise.resolve().then(() => __toESM(require_foo())));\n\n================================================================================\nTestImportNamespaceThisValue\n---------- /out/a.js ----------\n// a.js\nvar ns = __toESM(require(\"external\"));\nconsole.log(ns[foo](), new ns[foo]());\n\n---------- /out/b.js ----------\n// b.js\nvar ns = __toESM(require(\"external\"));\nconsole.log(ns.foo(), new ns.foo());\n\n---------- /out/c.js ----------\n// c.js\nvar import_external = __toESM(require(\"external\"));\nconsole.log((0, import_external.default)(), (0, import_external.foo)());\nconsole.log(new import_external.default(), new import_external.foo());\n\n================================================================================\nTestImportReExportES6Issue149\n---------- /out.js ----------\n// import.js\nimport { h, render } from \"preact\";\nvar p = \"p\";\n\n// in2.jsx\nvar Internal = () => /* @__PURE__ */ h(p, null, \" Test 2 \");\n\n// app.jsx\nvar App = () => /* @__PURE__ */ h(p, null, \" \", /* @__PURE__ */ h(Internal, null), \" T \");\nrender(/* @__PURE__ */ h(App, null), document.getElementById(\"app\"));\n\n================================================================================\nTestImportThenCatch\n---------- /out.js ----------\n// entry.js\nimport(name).then(pass, fail);\nimport(name).then(pass).catch(fail);\nimport(name).catch(fail);\n\n================================================================================\nTestImportWithHashInPath\n---------- /out/entry.js ----------\n// file#foo.txt\nvar file_foo_default = \"foo\";\n\n// file#bar.txt\nvar file_bar_default = \"bar\";\n\n// entry.js\nconsole.log(file_foo_default, file_bar_default);\n\n================================================================================\nTestImportWithHashParameter\n---------- /out/entry.js ----------\n// file.txt#foo\nvar file_default = \"This is some text\";\n\n// file.txt#bar\nvar file_default2 = \"This is some text\";\n\n// entry.js\nconsole.log(file_default, file_default2);\n\n================================================================================\nTestImportWithQueryParameter\n---------- /out/entry.js ----------\n// file.txt?foo\nvar file_default = \"This is some text\";\n\n// file.txt?bar\nvar file_default2 = \"This is some text\";\n\n// entry.js\nconsole.log(file_default, file_default2);\n\n================================================================================\nTestIndirectRequireMessage\n---------- /out/array.js ----------\n\n---------- /out/assign.js ----------\n// assign.js\n__require = x;\n\n---------- /out/dot.js ----------\n// dot.js\nvar x = __require.cache;\n\n---------- /out/ident.js ----------\n\n---------- /out/index.js ----------\n// index.js\nvar x = __require[cache];\n\n================================================================================\nTestInject\n---------- /out.js ----------\n// inject.js\nvar obj = {};\nvar sideEffects = console.log(\"side effects\");\n\n// node_modules/unused/index.js\nconsole.log(\"This is unused but still has side effects\");\n\n// replacement.js\nvar replace = {\n  test() {\n  }\n};\nvar replace2 = {\n  test() {\n  }\n};\n\n// re-export.js\nvar import_external_pkg = require(\"external-pkg\");\nvar import_external_pkg2 = require(\"external-pkg2\");\n\n// entry.js\nvar sideEffects2 = console.log(\"this should be renamed\");\nvar collide = 123;\nconsole.log(obj.prop);\nconsole.log(\"defined\");\nconsole.log(\"should be used\");\nconsole.log(\"should be used\");\nconsole.log(replace.test);\nconsole.log(replace2.test);\nconsole.log(collide);\nconsole.log(import_external_pkg.re_export);\nconsole.log(re_export2);\n\n================================================================================\nTestInjectDuplicate\n---------- /out.js ----------\n// inject.js\nconsole.log(\"injected\");\n\n================================================================================\nTestInjectImportMeta\n---------- /out.js ----------\n// inject.js\nvar foo = 1;\nvar bar = 2;\nvar baz = 3;\n\n// entry.js\nconsole.log(\n  // These should be fully substituted\n  foo,\n  bar,\n  baz,\n  // Should just substitute \"import.meta.foo\"\n  bar.baz,\n  // This should not be substituted\n  foo.bar\n);\n\n================================================================================\nTestInjectImportOrder\n---------- /out.js ----------\n// inject-1.js\nimport \"first\";\nconsole.log(\"first\");\n\n// inject-2.js\nimport \"second\";\nconsole.log(\"second\");\n\n// entry.ts\nimport \"third\";\nconsole.log(\"third\");\n\n================================================================================\nTestInjectImportTS\n---------- /out.js ----------\nconsole.log(\"must be present\");\nconsole.log(\"here\");\n\n================================================================================\nTestInjectJSX\n---------- /out.js ----------\n// inject.js\nfunction el() {\n}\nfunction frag() {\n}\n\n// entry.jsx\nconsole.log(/* @__PURE__ */ el(frag, null, /* @__PURE__ */ el(\"div\", null)));\n\n================================================================================\nTestInjectJSXDotNames\n---------- /out.js ----------\n// inject.js\nfunction el() {\n}\nfunction frag() {\n}\n\n// entry.jsx\nconsole.log(/* @__PURE__ */ el(frag, null, /* @__PURE__ */ el(\"div\", null)));\n\n================================================================================\nTestInjectNoBundle\n---------- /out.js ----------\nvar obj2 = {};\nvar sideEffects2 = console.log(\"this should be renamed\");\nconsole.log(\"This is unused but still has side effects\");\nvar replace2 = {\n  test() {\n  }\n};\nvar replaceDot = {\n  test() {\n  }\n};\nimport { re_export as re_export2 } from \"external-pkg\";\nimport { \"reexpo.rt\" as reexpo_rt } from \"external-pkg2\";\nlet sideEffects = console.log(\"side effects\");\nlet collide = 123;\nconsole.log(obj2.prop);\nconsole.log(\"defined\");\nconsole.log(\"should be used\");\nconsole.log(\"should be used\");\nconsole.log(replace2.test);\nconsole.log(replaceDot.test);\nconsole.log(collide);\nconsole.log(re_export2);\nconsole.log(reexpo_rt);\n\n================================================================================\nTestInjectWithDefine\n---------- /out.js ----------\n// inject.js\nvar second = \"success (identifier)\";\nvar second2 = \"success (dot name)\";\n\n// entry.js\nconsole.log(\n  // define wins over inject\n  true,\n  true,\n  // define forwards to inject\n  second === \"success (identifier)\",\n  second2 === \"success (dot name)\"\n);\n\n================================================================================\nTestInjectWithStringExportNameBundle\n---------- /out.js ----------\n// inject.js\nvar old = console.log;\nvar fn = (...args) => old.apply(console, [\"log:\"].concat(args));\n\n// entry.js\nfn(test);\nfn(test);\nfn(test);\n\n================================================================================\nTestInjectWithStringExportNameNoBundle\n---------- /out.js ----------\nvar old = console.log;\nvar fn = (...args) => old.apply(console, [\"log:\"].concat(args));\nfn(test);\n\n================================================================================\nTestInjectWithStringReExportNameNoBundle\n---------- /out.js ----------\nimport { fn } from \"pkg\";\nfn(test);\n\n================================================================================\nTestJSXAutomaticImportsCommonJS\n---------- /out.js ----------\n// custom-react.js\nvar require_custom_react = __commonJS({\n  \"custom-react.js\"(exports, module) {\n    module.exports = {};\n  }\n});\n\n// entry.jsx\nvar import_custom_react = __toESM(require_custom_react());\nimport { Fragment as Fragment2, jsx as jsx2 } from \"react/jsx-runtime\";\nconsole.log(/* @__PURE__ */ jsx2(\"div\", { jsx: import_custom_react.jsx }), /* @__PURE__ */ jsx2(Fragment2, { children: /* @__PURE__ */ jsx2(import_custom_react.Fragment, {}) }));\n\n================================================================================\nTestJSXAutomaticImportsES6\n---------- /out.js ----------\n// custom-react.js\nfunction jsx() {\n}\nfunction Fragment() {\n}\n\n// entry.jsx\nimport { Fragment as Fragment2, jsx as jsx2 } from \"react/jsx-runtime\";\nconsole.log(/* @__PURE__ */ jsx2(\"div\", { jsx }), /* @__PURE__ */ jsx2(Fragment2, { children: /* @__PURE__ */ jsx2(Fragment, {}) }));\n\n================================================================================\nTestJSXConstantFragments\n---------- /out.js ----------\n// default.jsx\nconsole.log(/* @__PURE__ */ React.createElement(\"]\", null));\n\n// null.jsx\nconsole.log(/* @__PURE__ */ React.createElement(null, null));\n\n// boolean.jsx\nconsole.log(/* @__PURE__ */ React.createElement(true, null));\n\n// number.jsx\nconsole.log(/* @__PURE__ */ React.createElement(123, null));\n\n// string-single-empty.jsx\nconsole.log(/* @__PURE__ */ React.createElement(\"\", null));\n\n// string-double-empty.jsx\nconsole.log(/* @__PURE__ */ React.createElement(\"\", null));\n\n// string-single-punctuation.jsx\nconsole.log(/* @__PURE__ */ React.createElement(\"[\", null));\n\n// string-double-punctuation.jsx\nconsole.log(/* @__PURE__ */ React.createElement(\"[\", null));\n\n// string-template.jsx\nconsole.log(/* @__PURE__ */ React.createElement(\"]\", null));\n\n================================================================================\nTestJSXDevSelfEdgeCases\n---------- /out/class-this.js ----------\n// class-this.jsx\nimport { jsxDEV } from \"react/jsx-dev-runtime\";\nvar Foo = class {\n  foo() {\n    return /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n      fileName: \"class-this.jsx\",\n      lineNumber: 1,\n      columnNumber: 35\n    }, this);\n  }\n};\nexport {\n  Foo\n};\n\n---------- /out/derived-constructor-arg.js ----------\n// derived-constructor-arg.jsx\nimport { jsxDEV } from \"react/jsx-dev-runtime\";\nvar Foo = class extends Object {\n  constructor(foo = /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n    fileName: \"derived-constructor-arg.jsx\",\n    lineNumber: 1,\n    columnNumber: 53\n  })) {\n    super();\n  }\n};\nexport {\n  Foo\n};\n\n---------- /out/derived-constructor-field.js ----------\n// derived-constructor-field.tsx\nimport { jsxDEV } from \"react/jsx-dev-runtime\";\nvar Foo = class extends Object {\n  constructor() {\n    super(...arguments);\n    this.foo = /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n      fileName: \"derived-constructor-field.tsx\",\n      lineNumber: 1,\n      columnNumber: 41\n    }, this);\n  }\n};\nexport {\n  Foo\n};\n\n---------- /out/derived-constructor.js ----------\n// derived-constructor.jsx\nimport { jsxDEV } from \"react/jsx-dev-runtime\";\nvar Foo = class extends Object {\n  constructor() {\n    super(/* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n      fileName: \"derived-constructor.jsx\",\n      lineNumber: 1,\n      columnNumber: 57\n    }));\n    this.foo = /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n      fileName: \"derived-constructor.jsx\",\n      lineNumber: 1,\n      columnNumber: 77\n    });\n  }\n};\nexport {\n  Foo\n};\n\n---------- /out/function-this.js ----------\n// function-this.jsx\nimport { jsxDEV } from \"react/jsx-dev-runtime\";\nfunction Foo() {\n  return /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n    fileName: \"function-this.jsx\",\n    lineNumber: 1,\n    columnNumber: 32\n  }, this);\n}\nexport {\n  Foo\n};\n\n---------- /out/normal-constructor-arg.js ----------\n// normal-constructor-arg.jsx\nimport { jsxDEV } from \"react/jsx-dev-runtime\";\nvar Foo = class {\n  constructor(foo = /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n    fileName: \"normal-constructor-arg.jsx\",\n    lineNumber: 1,\n    columnNumber: 38\n  }, this)) {\n  }\n};\nexport {\n  Foo\n};\n\n---------- /out/normal-constructor-field.js ----------\n// normal-constructor-field.tsx\nimport { jsxDEV } from \"react/jsx-dev-runtime\";\nvar Foo = class {\n  constructor() {\n    this.foo = /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n      fileName: \"normal-constructor-field.tsx\",\n      lineNumber: 1,\n      columnNumber: 26\n    }, this);\n  }\n};\nexport {\n  Foo\n};\n\n---------- /out/normal-constructor.js ----------\n// normal-constructor.jsx\nimport { jsxDEV } from \"react/jsx-dev-runtime\";\nvar Foo = class {\n  constructor() {\n    this.foo = /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n      fileName: \"normal-constructor.jsx\",\n      lineNumber: 1,\n      columnNumber: 47\n    }, this);\n  }\n};\nexport {\n  Foo\n};\n\n---------- /out/static-field.js ----------\n// static-field.jsx\nimport { jsxDEV } from \"react/jsx-dev-runtime\";\nvar _Foo = class _Foo {\n};\n__publicField(_Foo, \"foo\", /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n  fileName: \"static-field.jsx\",\n  lineNumber: 1,\n  columnNumber: 33\n}, _Foo));\nvar Foo = _Foo;\nexport {\n  Foo\n};\n\n---------- /out/top-level-this-cjs.js ----------\n// top-level-this-cjs.jsx\nimport { jsxDEV } from \"react/jsx-dev-runtime\";\nvar require_top_level_this_cjs = __commonJS({\n  \"top-level-this-cjs.jsx\"(exports) {\n    exports.foo = /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n      fileName: \"top-level-this-cjs.jsx\",\n      lineNumber: 1,\n      columnNumber: 15\n    });\n  }\n});\nexport default require_top_level_this_cjs();\n\n---------- /out/top-level-this-esm.js ----------\n// top-level-this-esm.jsx\nimport { jsxDEV } from \"react/jsx-dev-runtime\";\nvar foo = /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n  fileName: \"top-level-this-esm.jsx\",\n  lineNumber: 1,\n  columnNumber: 18\n});\nif (Foo) {\n  foo = /* @__PURE__ */ jsxDEV(Foo, { children: \"nested top-level this\" }, void 0, false, {\n    fileName: \"top-level-this-esm.jsx\",\n    lineNumber: 1,\n    columnNumber: 43\n  });\n}\nexport {\n  foo\n};\n\n---------- /out/tsconfig.js ----------\n// tsconfig.json\nvar compilerOptions = { useDefineForClassFields: false };\nvar tsconfig_default = { compilerOptions };\nexport {\n  compilerOptions,\n  tsconfig_default as default\n};\n\n---------- /out/typescript-enum.js ----------\n// typescript-enum.tsx\nimport { jsxDEV } from \"react/jsx-dev-runtime\";\nvar Foo = /* @__PURE__ */ ((Foo2) => {\n  Foo2[Foo2[\"foo\"] = /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n    fileName: \"typescript-enum.tsx\",\n    lineNumber: 1,\n    columnNumber: 25\n  })] = \"foo\";\n  return Foo2;\n})(Foo || {});\nexport {\n  Foo\n};\n\n---------- /out/typescript-namespace.js ----------\n// typescript-namespace.tsx\nimport { jsxDEV } from \"react/jsx-dev-runtime\";\nvar Foo;\n((Foo2) => {\n  Foo2.foo = /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n    fileName: \"typescript-namespace.tsx\",\n    lineNumber: 1,\n    columnNumber: 41\n  });\n})(Foo || (Foo = {}));\nexport {\n  Foo\n};\n\n================================================================================\nTestJSXImportMetaProperty\n---------- /out/factory.js ----------\n// factory.jsx\nvar import_meta = {};\nconsole.log([\n  /* @__PURE__ */ import_meta.factory(\"x\", null),\n  /* @__PURE__ */ import_meta.factory(\"x\", null)\n]);\nf = function() {\n  console.log([\n    /* @__PURE__ */ import_meta.factory(\"y\", null),\n    /* @__PURE__ */ import_meta.factory(\"y\", null)\n  ]);\n};\n\n---------- /out/fragment.js ----------\n// fragment.jsx\nvar import_meta = {};\nconsole.log([\n  /* @__PURE__ */ import_meta.factory(import_meta.fragment, null, \"x\"),\n  /* @__PURE__ */ import_meta.factory(import_meta.fragment, null, \"x\")\n]), f = function() {\n  console.log([\n    /* @__PURE__ */ import_meta.factory(import_meta.fragment, null, \"y\"),\n    /* @__PURE__ */ import_meta.factory(import_meta.fragment, null, \"y\")\n  ]);\n};\n\n================================================================================\nTestJSXImportMetaValue\n---------- /out/factory.js ----------\n// factory.jsx\nvar import_meta = {};\nconsole.log([\n  /* @__PURE__ */ import_meta(\"x\", null),\n  /* @__PURE__ */ import_meta(\"x\", null)\n]);\nf = function() {\n  console.log([\n    /* @__PURE__ */ import_meta(\"y\", null),\n    /* @__PURE__ */ import_meta(\"y\", null)\n  ]);\n};\n\n---------- /out/fragment.js ----------\n// fragment.jsx\nvar import_meta = {};\nconsole.log([\n  /* @__PURE__ */ import_meta(import_meta, null, \"x\"),\n  /* @__PURE__ */ import_meta(import_meta, null, \"x\")\n]), f = function() {\n  console.log([\n    /* @__PURE__ */ import_meta(import_meta, null, \"y\"),\n    /* @__PURE__ */ import_meta(import_meta, null, \"y\")\n  ]);\n};\n\n================================================================================\nTestJSXImportsCommonJS\n---------- /out.js ----------\n// custom-react.js\nvar require_custom_react = __commonJS({\n  \"custom-react.js\"(exports, module) {\n    module.exports = {};\n  }\n});\n\n// entry.jsx\nvar import_custom_react = __toESM(require_custom_react());\nconsole.log(/* @__PURE__ */ (0, import_custom_react.elem)(\"div\", null), /* @__PURE__ */ (0, import_custom_react.elem)(import_custom_react.frag, null, \"fragment\"));\n\n================================================================================\nTestJSXImportsES6\n---------- /out.js ----------\n// custom-react.js\nfunction elem() {\n}\nfunction frag() {\n}\n\n// entry.jsx\nconsole.log(/* @__PURE__ */ elem(\"div\", null), /* @__PURE__ */ elem(frag, null, \"fragment\"));\n\n================================================================================\nTestJSXThisPropertyCommonJS\n---------- /out/factory.js ----------\n// factory.jsx\nvar require_factory = __commonJS({\n  \"factory.jsx\"(exports) {\n    console.log([\n      /* @__PURE__ */ exports.factory(\"x\", null),\n      /* @__PURE__ */ exports.factory(\"x\", null)\n    ]);\n    f = function() {\n      console.log([\n        /* @__PURE__ */ this.factory(\"y\", null),\n        /* @__PURE__ */ this.factory(\"y\", null)\n      ]);\n    };\n  }\n});\nexport default require_factory();\n\n---------- /out/fragment.js ----------\n// fragment.jsx\nvar require_fragment = __commonJS({\n  \"fragment.jsx\"(exports) {\n    console.log([\n      /* @__PURE__ */ exports.factory(exports.fragment, null, \"x\"),\n      /* @__PURE__ */ exports.factory(exports.fragment, null, \"x\")\n    ]), f = function() {\n      console.log([\n        /* @__PURE__ */ this.factory(this.fragment, null, \"y\"),\n        /* @__PURE__ */ this.factory(this.fragment, null, \"y\")\n      ]);\n    };\n  }\n});\nexport default require_fragment();\n\n================================================================================\nTestJSXThisPropertyESM\n---------- /out/factory.js ----------\n// factory.jsx\nconsole.log([\n  /* @__PURE__ */ (void 0).factory(\"x\", null),\n  /* @__PURE__ */ (void 0).factory(\"x\", null)\n]);\nf = function() {\n  console.log([\n    /* @__PURE__ */ this.factory(\"y\", null),\n    /* @__PURE__ */ this.factory(\"y\", null)\n  ]);\n};\n\n---------- /out/fragment.js ----------\n// fragment.jsx\nconsole.log([\n  /* @__PURE__ */ (void 0).factory((void 0).fragment, null, \"x\"),\n  /* @__PURE__ */ (void 0).factory((void 0).fragment, null, \"x\")\n]), f = function() {\n  console.log([\n    /* @__PURE__ */ this.factory(this.fragment, null, \"y\"),\n    /* @__PURE__ */ this.factory(this.fragment, null, \"y\")\n  ]);\n};\n\n================================================================================\nTestJSXThisValueCommonJS\n---------- /out/factory.js ----------\n// factory.jsx\nvar require_factory = __commonJS({\n  \"factory.jsx\"(exports) {\n    console.log([\n      /* @__PURE__ */ exports(\"x\", null),\n      /* @__PURE__ */ exports(\"x\", null)\n    ]);\n    f = function() {\n      console.log([\n        /* @__PURE__ */ this(\"y\", null),\n        /* @__PURE__ */ this(\"y\", null)\n      ]);\n    };\n  }\n});\nexport default require_factory();\n\n---------- /out/fragment.js ----------\n// fragment.jsx\nvar require_fragment = __commonJS({\n  \"fragment.jsx\"(exports) {\n    console.log([\n      /* @__PURE__ */ exports(exports, null, \"x\"),\n      /* @__PURE__ */ exports(exports, null, \"x\")\n    ]), f = function() {\n      console.log([\n        /* @__PURE__ */ this(this, null, \"y\"),\n        /* @__PURE__ */ this(this, null, \"y\")\n      ]);\n    };\n  }\n});\nexport default require_fragment();\n\n================================================================================\nTestJSXThisValueESM\n---------- /out/factory.js ----------\n// factory.jsx\nconsole.log([\n  /* @__PURE__ */ (void 0)(\"x\", null),\n  /* @__PURE__ */ (void 0)(\"x\", null)\n]);\nf = function() {\n  console.log([\n    /* @__PURE__ */ this(\"y\", null),\n    /* @__PURE__ */ this(\"y\", null)\n  ]);\n};\n\n---------- /out/fragment.js ----------\n// fragment.jsx\nconsole.log([\n  /* @__PURE__ */ (void 0)(void 0, null, \"x\"),\n  /* @__PURE__ */ (void 0)(void 0, null, \"x\")\n]), f = function() {\n  console.log([\n    /* @__PURE__ */ this(this, null, \"y\"),\n    /* @__PURE__ */ this(this, null, \"y\")\n  ]);\n};\n\n================================================================================\nTestKeepNamesAllForms\n---------- /out/keep.js ----------\nfunction fn() {\n}\n__name(fn, \"fn\");\nfunction foo(fn2 = function() {\n}) {\n}\n__name(foo, \"foo\");\nvar fn = /* @__PURE__ */ __name(function() {\n}, \"fn\");\nvar obj = { \"f n\": /* @__PURE__ */ __name(function() {\n}, \"f n\") };\nclass Foo0 {\n  static {\n    __name(this, \"Foo0\");\n  }\n  \"f n\" = /* @__PURE__ */ __name(function() {\n  }, \"f n\");\n}\nclass Foo1 {\n  static {\n    __name(this, \"Foo1\");\n  }\n  static \"f n\" = /* @__PURE__ */ __name(function() {\n  }, \"f n\");\n}\nclass Foo2 {\n  static {\n    __name(this, \"Foo2\");\n  }\n  accessor \"f n\" = /* @__PURE__ */ __name(function() {\n  }, \"f n\");\n}\nclass Foo3 {\n  static {\n    __name(this, \"Foo3\");\n  }\n  static accessor \"f n\" = /* @__PURE__ */ __name(function() {\n  }, \"f n\");\n}\nclass Foo4 {\n  static {\n    __name(this, \"Foo4\");\n  }\n  #fn = /* @__PURE__ */ __name(function() {\n  }, \"#fn\");\n}\nclass Foo5 {\n  static {\n    __name(this, \"Foo5\");\n  }\n  static #fn = /* @__PURE__ */ __name(function() {\n  }, \"#fn\");\n}\nclass Foo6 {\n  static {\n    __name(this, \"Foo6\");\n  }\n  accessor #fn = /* @__PURE__ */ __name(function() {\n  }, \"#fn\");\n}\nclass Foo7 {\n  static {\n    __name(this, \"Foo7\");\n  }\n  static accessor #fn = /* @__PURE__ */ __name(function() {\n  }, \"#fn\");\n}\nfn = /* @__PURE__ */ __name(function() {\n}, \"fn\");\nfn ||= /* @__PURE__ */ __name(function() {\n}, \"fn\");\nfn &&= /* @__PURE__ */ __name(function() {\n}, \"fn\");\nfn ??= /* @__PURE__ */ __name(function() {\n}, \"fn\");\nvar [fn = /* @__PURE__ */ __name(function() {\n}, \"fn\")] = [];\nvar { fn = /* @__PURE__ */ __name(function() {\n}, \"fn\") } = {};\nfor (var [fn = /* @__PURE__ */ __name(function() {\n}, \"fn\")] = []; ; ) ;\nfor (var { fn = /* @__PURE__ */ __name(function() {\n}, \"fn\") } = {}; ; ) ;\nfor (var [fn = /* @__PURE__ */ __name(function() {\n}, \"fn\")] in obj) ;\nfor (var { fn = /* @__PURE__ */ __name(function() {\n}, \"fn\") } in obj) ;\nfor (var [fn = /* @__PURE__ */ __name(function() {\n}, \"fn\")] of obj) ;\nfor (var { fn = /* @__PURE__ */ __name(function() {\n}, \"fn\") } of obj) ;\nfunction foo([fn2 = /* @__PURE__ */ __name(function() {\n}, \"fn\")]) {\n}\n__name(foo, \"foo\");\nfunction foo({ fn: fn2 = /* @__PURE__ */ __name(function() {\n}, \"fn\") }) {\n}\n__name(foo, \"foo\");\n[fn = /* @__PURE__ */ __name(function() {\n}, \"fn\")] = [];\n({ fn = /* @__PURE__ */ __name(function() {\n}, \"fn\") } = {});\n\n---------- /out/do-not-keep.js ----------\nclass Foo0 {\n  static {\n    __name(this, \"Foo0\");\n  }\n  fn() {\n  }\n}\nclass Foo1 {\n  static {\n    __name(this, \"Foo1\");\n  }\n  *fn() {\n  }\n}\nclass Foo2 {\n  static {\n    __name(this, \"Foo2\");\n  }\n  get fn() {\n  }\n}\nclass Foo3 {\n  static {\n    __name(this, \"Foo3\");\n  }\n  set fn(_) {\n  }\n}\nclass Foo4 {\n  static {\n    __name(this, \"Foo4\");\n  }\n  async fn() {\n  }\n}\nclass Foo5 {\n  static {\n    __name(this, \"Foo5\");\n  }\n  static fn() {\n  }\n}\nclass Foo6 {\n  static {\n    __name(this, \"Foo6\");\n  }\n  static *fn() {\n  }\n}\nclass Foo7 {\n  static {\n    __name(this, \"Foo7\");\n  }\n  static get fn() {\n  }\n}\nclass Foo8 {\n  static {\n    __name(this, \"Foo8\");\n  }\n  static set fn(_) {\n  }\n}\nclass Foo9 {\n  static {\n    __name(this, \"Foo9\");\n  }\n  static async fn() {\n  }\n}\nclass Bar0 {\n  static {\n    __name(this, \"Bar0\");\n  }\n  #fn() {\n  }\n}\nclass Bar1 {\n  static {\n    __name(this, \"Bar1\");\n  }\n  *#fn() {\n  }\n}\nclass Bar2 {\n  static {\n    __name(this, \"Bar2\");\n  }\n  get #fn() {\n  }\n}\nclass Bar3 {\n  static {\n    __name(this, \"Bar3\");\n  }\n  set #fn(_) {\n  }\n}\nclass Bar4 {\n  static {\n    __name(this, \"Bar4\");\n  }\n  async #fn() {\n  }\n}\nclass Bar5 {\n  static {\n    __name(this, \"Bar5\");\n  }\n  static #fn() {\n  }\n}\nclass Bar6 {\n  static {\n    __name(this, \"Bar6\");\n  }\n  static *#fn() {\n  }\n}\nclass Bar7 {\n  static {\n    __name(this, \"Bar7\");\n  }\n  static get #fn() {\n  }\n}\nclass Bar8 {\n  static {\n    __name(this, \"Bar8\");\n  }\n  static set #fn(_) {\n  }\n}\nclass Bar9 {\n  static {\n    __name(this, \"Bar9\");\n  }\n  static async #fn(_) {\n  }\n}\nconst Baz0 = { fn() {\n} };\nconst Baz1 = { *fn() {\n} };\nconst Baz2 = { get fn() {\n} };\nconst Baz3 = { set fn(_) {\n} };\nconst Baz4 = { async fn() {\n} };\n\n================================================================================\nTestKeepNamesClassStaticName\n---------- /out.js ----------\nclass A {\n  static {\n    __name(this, \"A\");\n  }\n  static foo;\n}\nclass B {\n  static name;\n}\nclass C {\n  static name() {\n  }\n}\nclass D {\n  static get name() {\n  }\n}\nclass E {\n  static set name(x) {\n  }\n}\nclass F {\n  static [\"name\"] = 0;\n}\nlet a = class a3 {\n  static {\n    __name(this, \"a\");\n  }\n  static foo;\n};\nlet b = class b3 {\n  static name;\n};\nlet c = class c3 {\n  static name() {\n  }\n};\nlet d = class d3 {\n  static get name() {\n  }\n};\nlet e = class e3 {\n  static set name(x) {\n  }\n};\nlet f = class f3 {\n  static [\"name\"] = 0;\n};\nlet a2 = class {\n  static {\n    __name(this, \"a2\");\n  }\n  static foo;\n};\nlet b2 = class {\n  static name;\n};\nlet c2 = class {\n  static name() {\n  }\n};\nlet d2 = class {\n  static get name() {\n  }\n};\nlet e2 = class {\n  static set name(x) {\n  }\n};\nlet f2 = class {\n  static [\"name\"] = 0;\n};\n\n================================================================================\nTestKeepNamesTreeShaking\n---------- /out.js ----------\n// entry.js\nfunction fnStmtKeep() {\n}\n__name(fnStmtKeep, \"fnStmtKeep\");\nx = fnStmtKeep;\nvar fnExprKeep = /* @__PURE__ */ __name(function() {\n}, \"keep\");\nx = fnExprKeep;\nvar clsStmtKeep = class {\n  static {\n    __name(this, \"clsStmtKeep\");\n  }\n};\nnew clsStmtKeep();\nvar clsExprKeep = class {\n  static {\n    __name(this, \"keep\");\n  }\n};\nnew clsExprKeep();\n\n================================================================================\nTestLegalCommentsAvoidSlashTagEndOfFile\n---------- /out/entry.js ----------\n// entry.js\nvar x;\nexport {\n  x\n};\n//! <script>foo<\\/script>\n\n---------- /out/entry.css ----------\n/* entry.css */\nx {\n  y: z;\n}\n/*! <style>foo<\\/style> */\n\n================================================================================\nTestLegalCommentsAvoidSlashTagExternal\n---------- /out/entry.js.LEGAL.txt ----------\n//! <script>foo</script>\n\n---------- /out/entry.js ----------\n// entry.js\nvar x;\nexport {\n  x\n};\n\n---------- /out/entry.css.LEGAL.txt ----------\n/*! <style>foo</style> */\n\n---------- /out/entry.css ----------\n/* entry.css */\nx {\n  y: z;\n}\n\n================================================================================\nTestLegalCommentsAvoidSlashTagInline\n---------- /out/entry.js ----------\n// entry.js\n//! <script>foo<\\/script>\nvar x;\nexport {\n  x\n};\n\n---------- /out/entry.css ----------\n/* entry.css */\n/*! <style>foo<\\/style> */\nx {\n  y: z;\n}\n\n================================================================================\nTestLegalCommentsEndOfFile\n---------- /out/entry.js ----------\n// a.js\nconsole.log(\"in a\");\n\n// b.js\nconsole.log(\"in b\");\n\n// c.js\nconsole.log(\"in c\");\n//! Copyright notice 1\n//! Copyright notice 2\n\n---------- /out/entry.css ----------\n/* a.css */\na {\n  zoom: 2;\n}\n\n/* b.css */\nb {\n  zoom: 2;\n}\n\n/* c.css */\nc {\n  zoom: 2;\n}\n\n/* entry.css */\n/*! Copyright notice 1 */\n/*! Copyright notice 2 */\n\n---------- /out/empty.js ----------\n\n---------- /out/empty.css ----------\n/* empty.css */\n\n================================================================================\nTestLegalCommentsEscapeSlashScriptAndStyleEndOfFile\n---------- /out/entry.js ----------\nx;a;\n/*! <\\/script> */\n/*! Bundled license information:\n\njs-pkg/index.js:\n  (*! <\\/script> *)\n*/\n\n---------- /out/entry.css ----------\nx{y:z}a{b:c}\n/*! <\\/style> */\n/*! Bundled license information:\n\ncss-pkg/index.css:\n  (*! <\\/style> *)\n*/\n\n================================================================================\nTestLegalCommentsEscapeSlashScriptAndStyleExternal\n---------- /out/entry.js.LEGAL.txt ----------\n/*! </script> */\n\nBundled license information:\n\njs-pkg/index.js:\n  /*! </script> */\n\n---------- /out/entry.js ----------\nx;a;\n\n---------- /out/entry.css.LEGAL.txt ----------\n/*! </style> */\n\nBundled license information:\n\ncss-pkg/index.css:\n  /*! </style> */\n\n---------- /out/entry.css ----------\nx{y:z}a{b:c}\n\n================================================================================\nTestLegalCommentsExternal\n---------- /out/entry.js.LEGAL.txt ----------\n//! Copyright notice 1\n//! Copyright notice 2\n\n---------- /out/entry.js ----------\n// a.js\nconsole.log(\"in a\");\n\n// b.js\nconsole.log(\"in b\");\n\n// c.js\nconsole.log(\"in c\");\n\n---------- /out/entry.css.LEGAL.txt ----------\n/*! Copyright notice 1 */\n/*! Copyright notice 2 */\n\n---------- /out/entry.css ----------\n/* a.css */\na {\n  zoom: 2;\n}\n\n/* b.css */\nb {\n  zoom: 2;\n}\n\n/* c.css */\nc {\n  zoom: 2;\n}\n\n/* entry.css */\n\n---------- /out/empty.js ----------\n\n---------- /out/empty.css ----------\n/* empty.css */\n\n================================================================================\nTestLegalCommentsInline\n---------- /out/entry.js ----------\n// a.js\nconsole.log(\"in a\");\n//! Copyright notice 1\n\n// b.js\nconsole.log(\"in b\");\n//! Copyright notice 1\n\n// c.js\nconsole.log(\"in c\");\n//! Copyright notice 2\n\n---------- /out/entry.css ----------\n/* a.css */\na {\n  zoom: 2;\n}\n/*! Copyright notice 1 */\n\n/* b.css */\nb {\n  zoom: 2;\n}\n/*! Copyright notice 1 */\n\n/* c.css */\nc {\n  zoom: 2;\n}\n/*! Copyright notice 2 */\n\n/* entry.css */\n\n---------- /out/empty.js ----------\n\n---------- /out/empty.css ----------\n/* empty.css */\n\n================================================================================\nTestLegalCommentsLinked\n---------- /out/entry.js.LEGAL.txt ----------\n//! Copyright notice 1\n//! Copyright notice 2\n\n---------- /out/entry.js ----------\n// a.js\nconsole.log(\"in a\");\n\n// b.js\nconsole.log(\"in b\");\n\n// c.js\nconsole.log(\"in c\");\n/*! For license information please see entry.js.LEGAL.txt */\n\n---------- /out/entry.css.LEGAL.txt ----------\n/*! Copyright notice 1 */\n/*! Copyright notice 2 */\n\n---------- /out/entry.css ----------\n/* a.css */\na {\n  zoom: 2;\n}\n\n/* b.css */\nb {\n  zoom: 2;\n}\n\n/* c.css */\nc {\n  zoom: 2;\n}\n\n/* entry.css */\n/*! For license information please see entry.css.LEGAL.txt */\n\n---------- /out/empty.js ----------\n\n---------- /out/empty.css ----------\n/* empty.css */\n\n================================================================================\nTestLegalCommentsManyEndOfFile\n---------- /out/entry.js ----------\nconsole.log(\"in a\");console.log(\"in b\");function foo(){console.log(\"in c\");}foo();function bar(){console.log(\"some-other-pkg\")}bar();\n//! Copyright notice 1\n//! Duplicate comment\n/*\n * @license\n * Copyright notice 2\n */\n// @preserve This is another comment\n/*! Bundled license information:\n\nsome-other-pkg/js/index.js:\n  (*\n   * @preserve\n   * (c) Evil Software Corp\n   *)\n  (*! Duplicate third-party comment *)\n\nsome-pkg/js/index.js:\n  (*! (c) Good Software Corp *)\n  (*! Duplicate third-party comment *)\n*/\n\n---------- /out/entry.css ----------\na{zoom:2}b{zoom:2}c{zoom:2}.some-other-pkg{zoom:2}\n/*! Copyright notice 1 */\n/*! Duplicate comment */\n/*\n * @license\n * Copyright notice 2\n */\n/* @preserve This is another comment */\n/*! Bundled license information:\n\nsome-other-pkg/css/index.css:\n  (*! Duplicate third-party comment *)\n  (** @preserve\n   * (c) Evil Software Corp\n   *)\n\nsome-pkg/css/index.css:\n  (*! (c) Good Software Corp *)\n  (*! Duplicate third-party comment *)\n*/\n\n================================================================================\nTestLegalCommentsManyLinked\n---------- /out/entry.js.LEGAL.txt ----------\n//! Copyright notice 1\n/*\n * @license\n * Copyright notice 2\n */\n// @preserve This is another comment\n\nBundled license information:\n\nsome-other-pkg/js/index.js:\n  /*\n   * @preserve\n   * (c) Evil Software Corp\n   */\n\nsome-pkg/js/index.js:\n  //! (c) Good Software Corp\n\n---------- /out/entry.js ----------\nconsole.log(\"in a\");console.log(\"in b\");function foo(){console.log(\"in c\");}foo();function bar(){console.log(\"some-other-pkg\")}bar();\n/*! For license information please see entry.js.LEGAL.txt */\n\n---------- /out/entry.css.LEGAL.txt ----------\n/*! Copyright notice 1 */\n/*\n * @license\n * Copyright notice 2\n */\n/* @preserve This is another comment */\n\nBundled license information:\n\nsome-other-pkg/css/index.css:\n  /** @preserve\n   * (c) Evil Software Corp\n   */\n\nsome-pkg/css/index.css:\n  /*! (c) Good Software Corp */\n\n---------- /out/entry.css ----------\na{zoom:2}b{zoom:2}c{zoom:2}.some-other-pkg{zoom:2}\n/*! For license information please see entry.css.LEGAL.txt */\n\n================================================================================\nTestLegalCommentsMergeDuplicatesIssue4139\n---------- /out.js ----------\n/*! Bundled license information:\n\npkg/a.js:\npkg/b.js:\npkg/d.js:\n  (*!-----------------------------------------------------------------------------\n   * Copyright (c) Example Corporation. All rights reserved.\n   * Version: 1.2.3\n   * Released under the MIT license\n   * https://example.com/LICENSE.txt\n   *-----------------------------------------------------------------------------*)\n\npkg/c.js:\n  (*! some other comment *)\n  (*!-----------------------------------------------------------------------------\n   * Copyright (c) Example Corporation. All rights reserved.\n   * Version: 1.2.3\n   * Released under the MIT license\n   * https://example.com/LICENSE.txt\n   *-----------------------------------------------------------------------------*)\n*/\n\n================================================================================\nTestLegalCommentsModifyIndent\n---------- /out/entry.js ----------\n// entry.js\nvar entry_default = () => {\n  /**\n   * @preserve\n   */\n};\nexport {\n  entry_default as default\n};\n\n---------- /out/entry.css ----------\n/* entry.css */\n@media (x: y) {\n  /**\n   * @preserve\n   */\n  z {\n    zoom: 2;\n  }\n}\n\n================================================================================\nTestLegalCommentsNoEscapeSlashScriptEndOfFile\n---------- /out/entry.js ----------\nx;a;\n/*! </script> */\n/*! Bundled license information:\n\njs-pkg/index.js:\n  (*! </script> *)\n*/\n\n---------- /out/entry.css ----------\nx{y:z}a{b:c}\n/*! <\\/style> */\n/*! Bundled license information:\n\ncss-pkg/index.css:\n  (*! <\\/style> *)\n*/\n\n================================================================================\nTestLegalCommentsNoEscapeSlashStyleEndOfFile\n---------- /out/entry.js ----------\nx;a;\n/*! <\\/script> */\n/*! Bundled license information:\n\njs-pkg/index.js:\n  (*! <\\/script> *)\n*/\n\n---------- /out/entry.css ----------\nx{y:z}a{b:c}\n/*! </style> */\n/*! Bundled license information:\n\ncss-pkg/index.css:\n  (*! </style> *)\n*/\n\n================================================================================\nTestLegalCommentsNone\n---------- /out/entry.js ----------\n// a.js\nconsole.log(\"in a\");\n\n// b.js\nconsole.log(\"in b\");\n\n// c.js\nconsole.log(\"in c\");\n\n---------- /out/entry.css ----------\n/* a.css */\na {\n  zoom: 2;\n}\n\n/* b.css */\nb {\n  zoom: 2;\n}\n\n/* c.css */\nc {\n  zoom: 2;\n}\n\n/* entry.css */\n\n---------- /out/empty.js ----------\n\n---------- /out/empty.css ----------\n/* empty.css */\n\n================================================================================\nTestLineLimitMinified\n---------- /out/script.js ----------\nexport const SignUpForm=props=>{\nreturn React.createElement(\"p\",{\nclass:\"signup\"},React.createElement(\n\"label\",null,\"Username: \",React.\ncreateElement(\"input\",{class:\"us\\\nername\",type:\"text\"})),React.createElement(\n\"label\",null,\"Password: \",React.\ncreateElement(\"input\",{class:\"pa\\\nssword\",type:\"password\"})),React.\ncreateElement(\"div\",{class:\"prim\\\nary disabled\"},props.buttonText),\nReact.createElement(\"small\",null,\n\"By signing up, you are agreeing\\\n to our \",React.createElement(\"a\",\n{href:\"/tos/\"},\"terms of service\"),\n\".\"))};\n\n---------- /out/style.css ----------\nbody.light-mode.new-user-segment:not(.logged-in)\n.signup,body.light-mode.new-user-segment:not(.logged-in)\n.login{font:10px/12px \"Font 1\",\"\\\nFont 2\",\"Font 3\",\"Font 4\",sans-serif;\nuser-select:none;color:var(--fg,\nrgba(11, 22, 33, 0.5));background:url(\"\\\ndata:image/svg+xml;base64,PHN2Zy\\\nB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMC\\\nIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3\\\nJnLzIwMDAvc3ZnIj4KICA8Y2lyY2xlIG\\\nN4PSIxMDAiIGN5PSIxMDAiIHI9IjEwMC\\\nIgZmlsbD0iI0ZGQ0YwMCIvPgogIDxwYX\\\nRoIGQ9Ik00Ny41IDUyLjVMOTUgMTAwbC\\\n00Ny41IDQ3LjVtNjAtOTVMMTU1IDEwMG\\\nwtNDcuNSA0Ny41IiBmaWxsPSJub25lIi\\\nBzdHJva2U9IiMxOTE5MTkiIHN0cm9rZS\\\n13aWR0aD0iMjQiLz4KPC9zdmc+Cg==\")}\n\n================================================================================\nTestLineLimitNotMinified\n---------- /out/x-TZ25B4WH.file ----------\n...file...\n---------- /out/x-UF3O47Y3.copy ----------\n...copy...\n---------- /out/script.js ----------\n// x.file\nvar x_default = \"./x-TZ25B4WH.file\";\n\n// script.jsx\nimport copyURL from \"./x-UF3O47Y3.copy\";\n\n// x.data\nvar x_default2 = \"data:text/plai\\\nn;charset=utf-8,...lots of long \\\ndata...lots of long data...\";\n\n// script.jsx\nvar SignUpForm = (props) => {\n  return /* @__PURE__ */ React.createElement(\n  \"p\", { class: \"signup\" }, /* @__PURE__ */ React.\n  createElement(\"label\", null, \"\\\nUsername: \", /* @__PURE__ */ React.\n  createElement(\"input\", { class: \"\\\nusername\", type: \"text\" })), /* @__PURE__ */ React.\n  createElement(\"label\", null, \"\\\nPassword: \", /* @__PURE__ */ React.\n  createElement(\"input\", { class: \"\\\npassword\", type: \"password\" })),\n  /* @__PURE__ */ React.createElement(\n  \"div\", { class: \"primary disab\\\nled\" }, props.buttonText), /* @__PURE__ */ React.\n  createElement(\"small\", null, \"\\\nBy signing up, you are agreeing \\\nto our \", /* @__PURE__ */ React.\n  createElement(\"a\", { href: \"/t\\\nos/\" }, \"terms of service\"), \".\"),\n  /* @__PURE__ */ React.createElement(\n  \"img\", { src: x_default }), /* @__PURE__ */ React.\n  createElement(\"img\", { src: copyURL }),\n  /* @__PURE__ */ React.createElement(\n  \"img\", { src: x_default2 }));\n};\nexport {\n  SignUpForm\n};\n\n---------- /out/style.css ----------\n/* style.css */\nbody.light-mode.new-user-segment:not(.logged-in)\n.signup,\nbody.light-mode.new-user-segment:not(.logged-in)\n.login {\n  font:\n    10px/12px \"Font 1\",\n    \"Font 2\",\n    \"Font 3\",\n    \"Font 4\",\n    sans-serif;\n  user-select: none;\n  color: var(--fg, rgba(11, 22, 33,\n    0.5));\n  background: url(\"data:image/sv\\\ng+xml;base64,PHN2ZyB3aWR0aD0iMjA\\\nwIiBoZWlnaHQ9IjIwMCIgeG1sbnM9Imh\\\n0dHA6Ly93d3cudzMub3JnLzIwMDAvc3Z\\\nnIj4KICA8Y2lyY2xlIGN4PSIxMDAiIGN\\\n5PSIxMDAiIHI9IjEwMCIgZmlsbD0iI0Z\\\nGQ0YwMCIvPgogIDxwYXRoIGQ9Ik00Ny4\\\n1IDUyLjVMOTUgMTAwbC00Ny41IDQ3LjV\\\ntNjAtOTVMMTU1IDEwMGwtNDcuNSA0Ny4\\\n1IiBmaWxsPSJub25lIiBzdHJva2U9IiM\\\nxOTE5MTkiIHN0cm9rZS13aWR0aD0iMjQ\\\niLz4KPC9zdmc+Cg==\");\n  cursor: url(\"./x-TZ25B4WH.file\");\n  cursor: url(\"./x-UF3O47Y3.copy\");\n  cursor: url(\"data:text/plain;c\\\nharset=utf-8,...lots of long dat\\\na...lots of long data...\");\n}\n\n================================================================================\nTestMangleNoQuotedProps\n---------- /out/entry.js ----------\nx[\"_doNotMangleThis\"];\nx?.[\"_doNotMangleThis\"];\nx[y ? \"_doNotMangleThis\" : z];\nx?.[y ? \"_doNotMangleThis\" : z];\nx[y ? z : \"_doNotMangleThis\"];\nx?.[y ? z : \"_doNotMangleThis\"];\n({ \"_doNotMangleThis\": x });\n(class {\n  \"_doNotMangleThis\" = x;\n});\nvar { \"_doNotMangleThis\": x } = y;\n\"_doNotMangleThis\" in x;\n(y ? \"_doNotMangleThis\" : z) in x;\n(y ? z : \"_doNotMangleThis\") in x;\n\n================================================================================\nTestMangleNoQuotedPropsMinifySyntax\n---------- /out/entry.js ----------\nx._doNotMangleThis, x?._doNotMangleThis, x[y ? \"_doNotMangleThis\" : z], x?.[y ? \"_doNotMangleThis\" : z], x[y ? z : \"_doNotMangleThis\"], x?.[y ? z : \"_doNotMangleThis\"];\nvar { _doNotMangleThis: x } = y;\n\"_doNotMangleThis\" in x, (y ? \"_doNotMangleThis\" : z) in x, (y ? z : \"_doNotMangleThis\") in x;\n\n================================================================================\nTestMangleProps\n---------- /out/entry1.js ----------\nexport function shouldMangle() {\n  let foo = {\n    a: 0,\n    b() {\n    }\n  };\n  let { a: bar_ } = foo;\n  ({ a: bar_ } = foo);\n  class foo_ {\n    a = 0;\n    b() {\n    }\n    static a = 0;\n    static b() {\n    }\n  }\n  return { a: bar_, c: foo_ };\n}\nexport function shouldNotMangle() {\n  let foo = {\n    \"bar_\": 0,\n    \"baz_\"() {\n    }\n  };\n  let { \"bar_\": bar_ } = foo;\n  ({ \"bar_\": bar_ } = foo);\n  class foo_ {\n    \"bar_\" = 0;\n    \"baz_\"() {\n    }\n    static \"bar_\" = 0;\n    static \"baz_\"() {\n    }\n  }\n  return { \"bar_\": bar_, \"foo_\": foo_ };\n}\n\n---------- /out/entry2.js ----------\nexport default {\n  a: 0,\n  \"baz_\": 1\n};\n\n================================================================================\nTestManglePropsAvoidCollisions\n---------- /out.js ----------\nexport default {\n  c: 0,\n  // Must not be named \"a\"\n  d: 1,\n  // Must not be named \"b\"\n  a: 2,\n  b: 3,\n  __proto__: {}\n  // Always avoid mangling this\n};\n\n================================================================================\nTestManglePropsImportExport\n---------- /out/esm.js ----------\nexport let foo_ = 123;\nimport { bar_ } from \"xyz\";\n\n---------- /out/cjs.js ----------\nexports.a = 123;\nlet bar_ = require(\"xyz\").b;\n\n================================================================================\nTestManglePropsImportExportBundled\n---------- /out/entry-esm.js ----------\n// cjs.js\nvar require_cjs = __commonJS({\n  \"cjs.js\"(exports) {\n    exports.a = \"foo\";\n  }\n});\n\n// esm.js\nvar esm_exports = {};\n__export(esm_exports, {\n  esm_foo_: () => esm_foo_\n});\nvar esm_foo_ = \"foo\";\n\n// entry-esm.js\nvar import_cjs = __toESM(require_cjs());\nvar cjs = __toESM(require_cjs());\nvar bar_ = [\n  esm_foo_,\n  import_cjs.cjs_foo_,\n  esm_exports.b,\n  cjs.a\n];\nexport {\n  bar_\n};\n\n---------- /out/entry-cjs.js ----------\n// esm.js\nvar esm_exports = {};\n__export(esm_exports, {\n  esm_foo_: () => esm_foo_\n});\nvar esm_foo_;\nvar init_esm = __esm({\n  \"esm.js\"() {\n    esm_foo_ = \"foo\";\n  }\n});\n\n// cjs.js\nvar require_cjs = __commonJS({\n  \"cjs.js\"(exports) {\n    exports.a = \"foo\";\n  }\n});\n\n// entry-cjs.js\nvar require_entry_cjs = __commonJS({\n  \"entry-cjs.js\"(exports) {\n    var { b: esm_foo_2 } = (init_esm(), __toCommonJS(esm_exports));\n    var { a: cjs_foo_ } = require_cjs();\n    exports.c = [\n      esm_foo_2,\n      cjs_foo_\n    ];\n  }\n});\nexport default require_entry_cjs();\n\n================================================================================\nTestManglePropsJSXPreserve\n---------- /out.jsx ----------\nlet Foo = {\n  a(props) {\n    return <>{props.b}</>;\n  },\n  c: \"hello, world\"\n};\nexport default <Foo.a b={Foo.c} />;\n\n================================================================================\nTestManglePropsJSXTransform\n---------- /out.js ----------\nlet Foo = {\n  b(props) {\n    return /* @__PURE__ */ Foo.a(Foo.d, null, props.c);\n  },\n  e: \"hello, world\",\n  a(...args) {\n    console.log(\"createElement\", ...args);\n  },\n  d(...args) {\n    console.log(\"Fragment\", ...args);\n  }\n};\nexport default /* @__PURE__ */ Foo.a(Foo.b, { c: Foo.e });\n\n================================================================================\nTestManglePropsJSXTransformNamespace\n---------- /out.js ----------\nexport default [\n  /* @__PURE__ */ React.createElement(KEEP_THIS_, null),\n  /* @__PURE__ */ React.createElement(\"KEEP:THIS_\", null),\n  /* @__PURE__ */ React.createElement(\"foo\", { \"KEEP:THIS_\": true })\n];\n\n================================================================================\nTestManglePropsKeyComment\n---------- /out/entry.js ----------\nx(\n  /* __KEY__ */\n  \"_doNotMangleThis\",\n  /* __KEY__ */\n  `_doNotMangleThis`\n);\nx.a(/* @__KEY__ */ \"a\", /* @__KEY__ */ \"a\");\nx.b(/* @__KEY__ */ \"b\", /* @__KEY__ */ \"b\");\nx.c = /* @__KEY__ */ \"c\" in y;\nx([\n  `foo.${/* @__KEY__ */ \"a\"} = bar.${/* @__KEY__ */ \"b\"}`,\n  `foo.${/* @__KEY__ */ \"notMangled\"} = bar.${/* @__KEY__ */ \"notMangledEither\"}`\n]);\n\n================================================================================\nTestManglePropsKeyCommentMinify\n---------- /out/entry.js ----------\nx = class {\n  a = 1;\n  b = 2;\n  _doNotMangleThis = 3;\n}, x = {\n  a: 1,\n  b: 2,\n  _doNotMangleThis: 3\n}, x.a = 1, x.b = 2, x._doNotMangleThis = 3, x([\n  `${foo}.a = bar.b`,\n  `${foo}.notMangled = bar.notMangledEither`\n]);\n\n================================================================================\nTestManglePropsKeywordPropertyMinify\n---------- /out/entry.js ----------\nclass Foo{static t={get s(){return 123}}}\n\n================================================================================\nTestManglePropsLoweredClassFields\n---------- /out.js ----------\nclass Foo {\n  constructor() {\n    __publicField(this, /* @__KEY__ */ \"a\", 123);\n  }\n}\n__publicField(Foo, /* @__KEY__ */ \"b\", 234);\nFoo.b = new Foo().a;\n\n================================================================================\nTestManglePropsLoweredOptionalChain\n---------- /out.js ----------\nexport default function(x) {\n  var _a;\n  x.a;\n  (_a = x.a) == null ? void 0 : _a.call(x);\n  x == null ? void 0 : x.a;\n  x == null ? void 0 : x.a();\n  x == null ? void 0 : x.a.b;\n  x == null ? void 0 : x.a.b();\n  x == null ? void 0 : x[\"foo_\"].b;\n  x == null ? void 0 : x.a[\"bar_\"];\n}\n\n================================================================================\nTestManglePropsMinify\n---------- /out/entry1.js ----------\nexport function shouldMangle_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX() {\n  let X = {\n    X: 0,\n    Y() {\n    }\n  }, { X: Y } = X;\n  ({ X: Y } = X);\n  class t {\n    X = 0;\n    Y() {\n    }\n    static X = 0;\n    static Y() {\n    }\n  }\n  return { X: Y, t };\n}\nexport function shouldNotMangle_YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY() {\n  let X = {\n    bar_: 0,\n    baz_() {\n    }\n  }, { bar_: Y } = X;\n  ({ bar_: Y } = X);\n  class t {\n    bar_ = 0;\n    baz_() {\n    }\n    static bar_ = 0;\n    static baz_() {\n    }\n  }\n  return { bar_: Y, foo_: t };\n}\n\n---------- /out/entry2.js ----------\nexport default {\n  a: 0,\n  baz_: 1\n};\n\n================================================================================\nTestManglePropsNoShorthand\n---------- /out.js ----------\nexport let yyyyy = ({ y }) => ({ y: y });\n\n================================================================================\nTestManglePropsOptionalChain\n---------- /out.js ----------\nexport default function(x) {\n  x.a;\n  x.a?.();\n  x?.a;\n  x?.a();\n  x?.a.b;\n  x?.a.b();\n  x?.[\"foo_\"].b;\n  x?.a[\"bar_\"];\n}\n\n================================================================================\nTestManglePropsShorthand\n---------- /out.js ----------\nexport let yyyyy = ({ y }) => ({ y });\n\n================================================================================\nTestManglePropsSuperCall\n---------- /out.js ----------\nclass Foo {\n}\nclass Bar extends Foo {\n  constructor() {\n    super();\n  }\n}\n\n================================================================================\nTestManglePropsTypeScriptFeatures\n---------- /out/parameter-properties.js ----------\nclass Foo {\n  constructor(KEEP_FIELD, MANGLE_FIELD_) {\n    this.KEEP_FIELD = KEEP_FIELD;\n    this.a = MANGLE_FIELD_;\n  }\n}\nlet foo = new Foo();\nconsole.log(foo.KEEP_FIELD, foo.a);\n\n---------- /out/namespace-exports.js ----------\nvar ns;\n((ns2) => {\n  ns2.c = 1;\n  ns2.d = 2;\n  ns2.e = 3;\n  ({ i: { a: ns2.a } } = 4);\n  function MANGLE_FUNCTION_() {\n  }\n  ns2.g = MANGLE_FUNCTION_;\n  class MANGLE_CLASS_ {\n  }\n  ns2.h = MANGLE_CLASS_;\n  let MANGLE_NAMESPACE_;\n  ((MANGLE_NAMESPACE_2) => {\n    ;\n  })(MANGLE_NAMESPACE_ = ns2.f || (ns2.f = {}));\n  let MANGLE_ENUM_;\n  ((MANGLE_ENUM_2) => {\n  })(MANGLE_ENUM_ = ns2.b || (ns2.b = {}));\n  console.log({\n    VAR: ns2.c,\n    LET: ns2.d,\n    CONST: ns2.e,\n    DESTRUCTURING: ns2.a,\n    FUNCTION: MANGLE_FUNCTION_,\n    CLASS: MANGLE_CLASS_,\n    NAMESPACE: MANGLE_NAMESPACE_,\n    ENUM: MANGLE_ENUM_\n  });\n})(ns || (ns = {}));\nconsole.log({\n  VAR: ns.c,\n  LET: ns.d,\n  CONST: ns.e,\n  DESTRUCTURING: ns.a,\n  FUNCTION: ns.g,\n  CLASS: ns.h,\n  NAMESPACE: ns.f,\n  ENUM: ns.b\n});\n((ns2) => {\n  console.log({\n    VAR: ns2.c,\n    LET: ns2.d,\n    CONST: ns2.e,\n    DESTRUCTURING: ns2.a,\n    FUNCTION: ns2.g,\n    CLASS: ns2.h,\n    NAMESPACE: ns2.f,\n    ENUM: ns2.b\n  });\n})(ns || (ns = {}));\n\n---------- /out/enum-values.js ----------\nvar TopLevelNumber = /* @__PURE__ */ ((TopLevelNumber2) => {\n  TopLevelNumber2[TopLevelNumber2[\"foo_\"] = 0] = \"foo_\";\n  return TopLevelNumber2;\n})(TopLevelNumber || {});\nvar TopLevelString = /* @__PURE__ */ ((TopLevelString2) => {\n  TopLevelString2[\"bar_\"] = \"\";\n  return TopLevelString2;\n})(TopLevelString || {});\nconsole.log({\n  foo: TopLevelNumber.a,\n  bar: TopLevelString.b\n});\nfunction fn() {\n  let NestedNumber;\n  ((NestedNumber2) => {\n    NestedNumber2[NestedNumber2[\"foo_\"] = 0] = \"foo_\";\n  })(NestedNumber || (NestedNumber = {}));\n  let NestedString;\n  ((NestedString2) => {\n    NestedString2[\"bar_\"] = \"\";\n  })(NestedString || (NestedString = {}));\n  console.log({\n    foo: TopLevelNumber.a,\n    bar: TopLevelString.b\n  });\n}\n\n================================================================================\nTestMangleQuotedProps\n---------- /out/keep.js ----------\nfoo(\"_keepThisProperty\");\nfoo((x, \"_keepThisProperty\"));\nfoo(x ? \"_keepThisProperty\" : \"_keepThisPropertyToo\");\nx[foo(\"_keepThisProperty\")];\nx?.[foo(\"_keepThisProperty\")];\n({ [foo(\"_keepThisProperty\")]: x });\n(class {\n  [foo(\"_keepThisProperty\")] = x;\n});\nvar { [foo(\"_keepThisProperty\")]: x } = y;\nfoo(\"_keepThisProperty\") in x;\n\n---------- /out/mangle.js ----------\nx.a;\nx?.a;\nx[y ? \"a\" : z];\nx?.[y ? \"a\" : z];\nx[y ? z : \"a\"];\nx?.[y ? z : \"a\"];\nx[y, \"a\"];\nx?.[y, \"a\"];\n({ a: x });\n({ [\"a\"]: x });\n({ [(y, \"a\")]: x });\n(class {\n  a = x;\n});\n(class {\n  [\"a\"] = x;\n});\n(class {\n  [(y, \"a\")] = x;\n});\nvar { a: x } = y;\nvar { [\"a\"]: x } = y;\nvar { [(z, \"a\")]: x } = y;\n\"a\" in x;\n(y ? \"a\" : z) in x;\n(y ? z : \"a\") in x;\n(y, \"a\") in x;\n\n================================================================================\nTestMangleQuotedPropsMinifySyntax\n---------- /out/keep.js ----------\nfoo(\"_keepThisProperty\"), foo(\"_keepThisProperty\"), foo(x ? \"_keepThisProperty\" : \"_keepThisPropertyToo\"), x[foo(\"_keepThisProperty\")], x?.[foo(\"_keepThisProperty\")], foo(\"_keepThisProperty\") + \"\", class {\n  [foo(\"_keepThisProperty\")] = x;\n};\nvar { [foo(\"_keepThisProperty\")]: x } = y;\nfoo(\"_keepThisProperty\") in x;\n\n---------- /out/mangle.js ----------\nx.a, x?.a, x[y ? \"a\" : z], x?.[y ? \"a\" : z], x[y ? z : \"a\"], x?.[y ? z : \"a\"], x[y, \"a\"], x?.[y, \"a\"], (y, \"a\") + \"\", class {\n  [(y, \"a\")] = x;\n};\nvar { a: x } = y, { [\"a\"]: x } = y, { [(z, \"a\")]: x } = y;\n\"a\" in x, (y ? \"a\" : z) in x, (y ? z : \"a\") in x, y, \"a\" in x;\n\n================================================================================\nTestManyEntryPoints\n---------- /out/e00.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e00.js\nconsole.log(shared_default);\n\n---------- /out/e01.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e01.js\nconsole.log(shared_default);\n\n---------- /out/e02.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e02.js\nconsole.log(shared_default);\n\n---------- /out/e03.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e03.js\nconsole.log(shared_default);\n\n---------- /out/e04.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e04.js\nconsole.log(shared_default);\n\n---------- /out/e05.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e05.js\nconsole.log(shared_default);\n\n---------- /out/e06.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e06.js\nconsole.log(shared_default);\n\n---------- /out/e07.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e07.js\nconsole.log(shared_default);\n\n---------- /out/e08.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e08.js\nconsole.log(shared_default);\n\n---------- /out/e09.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e09.js\nconsole.log(shared_default);\n\n---------- /out/e10.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e10.js\nconsole.log(shared_default);\n\n---------- /out/e11.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e11.js\nconsole.log(shared_default);\n\n---------- /out/e12.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e12.js\nconsole.log(shared_default);\n\n---------- /out/e13.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e13.js\nconsole.log(shared_default);\n\n---------- /out/e14.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e14.js\nconsole.log(shared_default);\n\n---------- /out/e15.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e15.js\nconsole.log(shared_default);\n\n---------- /out/e16.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e16.js\nconsole.log(shared_default);\n\n---------- /out/e17.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e17.js\nconsole.log(shared_default);\n\n---------- /out/e18.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e18.js\nconsole.log(shared_default);\n\n---------- /out/e19.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e19.js\nconsole.log(shared_default);\n\n---------- /out/e20.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e20.js\nconsole.log(shared_default);\n\n---------- /out/e21.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e21.js\nconsole.log(shared_default);\n\n---------- /out/e22.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e22.js\nconsole.log(shared_default);\n\n---------- /out/e23.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e23.js\nconsole.log(shared_default);\n\n---------- /out/e24.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e24.js\nconsole.log(shared_default);\n\n---------- /out/e25.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e25.js\nconsole.log(shared_default);\n\n---------- /out/e26.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e26.js\nconsole.log(shared_default);\n\n---------- /out/e27.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e27.js\nconsole.log(shared_default);\n\n---------- /out/e28.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e28.js\nconsole.log(shared_default);\n\n---------- /out/e29.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e29.js\nconsole.log(shared_default);\n\n---------- /out/e30.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e30.js\nconsole.log(shared_default);\n\n---------- /out/e31.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e31.js\nconsole.log(shared_default);\n\n---------- /out/e32.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e32.js\nconsole.log(shared_default);\n\n---------- /out/e33.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e33.js\nconsole.log(shared_default);\n\n---------- /out/e34.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e34.js\nconsole.log(shared_default);\n\n---------- /out/e35.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e35.js\nconsole.log(shared_default);\n\n---------- /out/e36.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e36.js\nconsole.log(shared_default);\n\n---------- /out/e37.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e37.js\nconsole.log(shared_default);\n\n---------- /out/e38.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e38.js\nconsole.log(shared_default);\n\n---------- /out/e39.js ----------\n// shared.js\nvar shared_default = 123;\n\n// e39.js\nconsole.log(shared_default);\n\n================================================================================\nTestMetafileImportWithTypeJSON\n---------- /out/entry.js ----------\n// project/data.json\nvar data_default = { some: \"data\" };\n\n// project/data.json with { type: 'json' }\nvar data_default2 = { some: \"data\" };\n\n// project/entry.js\nx = [data_default, data_default, data_default2];\n---------- metafile.json ----------\n{\n  \"inputs\": {\n    \"project/data.json\": {\n      \"bytes\": 16,\n      \"imports\": []\n    },\n    \"project/data.json with { type: 'json' }\": {\n      \"bytes\": 16,\n      \"imports\": [],\n      \"format\": \"esm\",\n      \"with\": {\n        \"type\": \"json\"\n      }\n    },\n    \"project/entry.js\": {\n      \"bytes\": 164,\n      \"imports\": [\n        {\n          \"path\": \"project/data.json\",\n          \"kind\": \"import-statement\",\n          \"original\": \"./data.json\"\n        },\n        {\n          \"path\": \"project/data.json\",\n          \"kind\": \"import-statement\",\n          \"original\": \"./data.json\"\n        },\n        {\n          \"path\": \"project/data.json with { type: 'json' }\",\n          \"kind\": \"import-statement\",\n          \"original\": \"./data.json\",\n          \"with\": {\n            \"type\": \"json\"\n          }\n        }\n      ],\n      \"format\": \"esm\"\n    }\n  },\n  \"outputs\": {\n    \"out/entry.js\": {\n      \"imports\": [],\n      \"exports\": [],\n      \"entryPoint\": \"project/entry.js\",\n      \"inputs\": {\n        \"project/data.json\": {\n          \"bytesInOutput\": 37\n        },\n        \"project/data.json with { type: 'json' }\": {\n          \"bytesInOutput\": 38\n        },\n        \"project/entry.js\": {\n          \"bytesInOutput\": 49\n        }\n      },\n      \"bytes\": 210\n    }\n  }\n}\n\n================================================================================\nTestMetafileNoBundle\n---------- /out/entry.js ----------\nimport a from \"pkg\";\nimport b from \"./file\";\nconsole.log(\n  a,\n  b,\n  require(\"pkg2\"),\n  require(\"./file2\"),\n  import(\"./dynamic\")\n);\nlet exported;\n\n---------- /out/entry.css ----------\n@import \"pkg\";\n@import \"./file\";\na {\n  background: url(pkg2);\n}\na {\n  background: url(./file2);\n}\n---------- metafile.json ----------\n{\n  \"inputs\": {\n    \"project/entry.js\": {\n      \"bytes\": 191,\n      \"imports\": [],\n      \"format\": \"esm\"\n    },\n    \"project/entry.css\": {\n      \"bytes\": 112,\n      \"imports\": []\n    }\n  },\n  \"outputs\": {\n    \"out/entry.js\": {\n      \"imports\": [\n        {\n          \"path\": \"pkg\",\n          \"kind\": \"import-statement\",\n          \"external\": true\n        },\n        {\n          \"path\": \"./file\",\n          \"kind\": \"import-statement\",\n          \"external\": true\n        },\n        {\n          \"path\": \"pkg2\",\n          \"kind\": \"require-call\",\n          \"external\": true\n        },\n        {\n          \"path\": \"./file2\",\n          \"kind\": \"require-call\",\n          \"external\": true\n        },\n        {\n          \"path\": \"./dynamic\",\n          \"kind\": \"dynamic-import\",\n          \"external\": true\n        }\n      ],\n      \"exports\": [\n        \"exported\"\n      ],\n      \"entryPoint\": \"project/entry.js\",\n      \"inputs\": {\n        \"project/entry.js\": {\n          \"bytesInOutput\": 148\n        }\n      },\n      \"bytes\": 148\n    },\n    \"out/entry.css\": {\n      \"imports\": [\n        {\n          \"path\": \"pkg\",\n          \"kind\": \"import-rule\",\n          \"external\": true\n        },\n        {\n          \"path\": \"./file\",\n          \"kind\": \"import-rule\",\n          \"external\": true\n        },\n        {\n          \"path\": \"pkg2\",\n          \"kind\": \"url-token\",\n          \"external\": true\n        },\n        {\n          \"path\": \"./file2\",\n          \"kind\": \"url-token\",\n          \"external\": true\n        }\n      ],\n      \"entryPoint\": \"project/entry.css\",\n      \"inputs\": {\n        \"project/entry.css\": {\n          \"bytesInOutput\": 65\n        }\n      },\n      \"bytes\": 98\n    }\n  }\n}\n\n================================================================================\nTestMetafileVariousCases\n---------- /out/file-NVISQQTV.file ----------\nfile\n---------- /out/copy-O3Y5SCJE.copy ----------\ncopy\n---------- /out/entry.js ----------\nimport {\n  __commonJS,\n  __require\n} from \"./chunk-MQN2VSL5.js\";\n\n// project/cjs.js\nvar require_cjs = __commonJS({\n  \"project/cjs.js\"(exports, module) {\n    module.exports = 4;\n  }\n});\n\n// project/entry.js\nimport a from \"extern-esm\";\n\n// project/esm.js\nvar esm_default = 1;\n\n// <data:application/json,2>\nvar json_2_default = 2;\n\n// project/file.file\nvar file_default = \"./file-NVISQQTV.file\";\n\n// project/entry.js\nimport e from \"./copy-O3Y5SCJE.copy\";\nconsole.log(\n  a,\n  esm_default,\n  json_2_default,\n  file_default,\n  e,\n  __require(\"extern-cjs\"),\n  require_cjs(),\n  import(\"./dynamic-Q2DWDUFV.js\")\n);\nvar exported;\nexport {\n  exported\n};\n\n---------- /out/dynamic-Q2DWDUFV.js ----------\nimport \"./chunk-MQN2VSL5.js\";\n\n// project/dynamic.js\nvar dynamic_default = 5;\nexport {\n  dynamic_default as default\n};\n\n---------- /out/chunk-MQN2VSL5.js ----------\nexport {\n  __require,\n  __commonJS\n};\n\n---------- /out/entry.css ----------\n@import \"extern.css\";\n\n/* project/entry.css */\na {\n  background: url(data:image/svg+xml,<svg/>);\n}\nb {\n  background: url(\"./file-NVISQQTV.file\");\n}\nc {\n  background: url(\"./copy-O3Y5SCJE.copy\");\n}\nd {\n  background: url(extern.png);\n}\n---------- metafile.json ----------\n{\n  \"inputs\": {\n    \"project/esm.js\": {\n      \"bytes\": 16,\n      \"imports\": [],\n      \"format\": \"esm\"\n    },\n    \"<data:application/json,2>\": {\n      \"bytes\": 1,\n      \"imports\": []\n    },\n    \"project/file.file\": {\n      \"bytes\": 4,\n      \"imports\": []\n    },\n    \"project/copy.copy\": {\n      \"bytes\": 4,\n      \"imports\": []\n    },\n    \"project/cjs.js\": {\n      \"bytes\": 18,\n      \"imports\": [],\n      \"format\": \"cjs\"\n    },\n    \"project/dynamic.js\": {\n      \"bytes\": 16,\n      \"imports\": [],\n      \"format\": \"esm\"\n    },\n    \"project/entry.js\": {\n      \"bytes\": 333,\n      \"imports\": [\n        {\n          \"path\": \"extern-esm\",\n          \"kind\": \"import-statement\",\n          \"external\": true\n        },\n        {\n          \"path\": \"project/esm.js\",\n          \"kind\": \"import-statement\",\n          \"original\": \"./esm\"\n        },\n        {\n          \"path\": \"<data:application/json,2>\",\n          \"kind\": \"import-statement\",\n          \"original\": \"data:application/json,2\"\n        },\n        {\n          \"path\": \"project/file.file\",\n          \"kind\": \"import-statement\",\n          \"original\": \"./file.file\"\n        },\n        {\n          \"path\": \"project/copy.copy\",\n          \"kind\": \"import-statement\",\n          \"original\": \"./copy.copy\"\n        },\n        {\n          \"path\": \"extern-cjs\",\n          \"kind\": \"require-call\",\n          \"external\": true\n        },\n        {\n          \"path\": \"project/cjs.js\",\n          \"kind\": \"require-call\",\n          \"original\": \"./cjs\"\n        },\n        {\n          \"path\": \"project/dynamic.js\",\n          \"kind\": \"dynamic-import\",\n          \"original\": \"./dynamic\"\n        }\n      ],\n      \"format\": \"esm\"\n    },\n    \"project/inline.svg\": {\n      \"bytes\": 6,\n      \"imports\": []\n    },\n    \"project/entry.css\": {\n      \"bytes\": 180,\n      \"imports\": [\n        {\n          \"path\": \"extern.css\",\n          \"kind\": \"import-rule\",\n          \"external\": true\n        },\n        {\n          \"path\": \"project/inline.svg\",\n          \"kind\": \"url-token\",\n          \"original\": \"inline.svg\"\n        },\n        {\n          \"path\": \"project/file.file\",\n          \"kind\": \"url-token\",\n          \"original\": \"file.file\"\n        },\n        {\n          \"path\": \"project/copy.copy\",\n          \"kind\": \"url-token\",\n          \"original\": \"copy.copy\"\n        },\n        {\n          \"path\": \"extern.png\",\n          \"kind\": \"url-token\",\n          \"external\": true\n        }\n      ]\n    }\n  },\n  \"outputs\": {\n    \"out/file-NVISQQTV.file\": {\n      \"imports\": [],\n      \"exports\": [],\n      \"inputs\": {\n        \"project/file.file\": {\n          \"bytesInOutput\": 4\n        }\n      },\n      \"bytes\": 4\n    },\n    \"out/copy-O3Y5SCJE.copy\": {\n      \"imports\": [],\n      \"exports\": [],\n      \"inputs\": {\n        \"project/copy.copy\": {\n          \"bytesInOutput\": 4\n        }\n      },\n      \"bytes\": 4\n    },\n    \"out/entry.js\": {\n      \"imports\": [\n        {\n          \"path\": \"out/chunk-MQN2VSL5.js\",\n          \"kind\": \"import-statement\"\n        },\n        {\n          \"path\": \"extern-esm\",\n          \"kind\": \"import-statement\",\n          \"external\": true\n        },\n        {\n          \"path\": \"out/file-NVISQQTV.file\",\n          \"kind\": \"file-loader\"\n        },\n        {\n          \"path\": \"out/copy-O3Y5SCJE.copy\",\n          \"kind\": \"import-statement\"\n        },\n        {\n          \"path\": \"extern-cjs\",\n          \"kind\": \"require-call\",\n          \"external\": true\n        },\n        {\n          \"path\": \"out/dynamic-Q2DWDUFV.js\",\n          \"kind\": \"dynamic-import\"\n        }\n      ],\n      \"exports\": [\n        \"exported\"\n      ],\n      \"entryPoint\": \"project/entry.js\",\n      \"inputs\": {\n        \"project/cjs.js\": {\n          \"bytesInOutput\": 101\n        },\n        \"project/entry.js\": {\n          \"bytesInOutput\": 233\n        },\n        \"project/esm.js\": {\n          \"bytesInOutput\": 21\n        },\n        \"<data:application/json,2>\": {\n          \"bytesInOutput\": 24\n        },\n        \"project/file.file\": {\n          \"bytesInOutput\": 43\n        }\n      },\n      \"bytes\": 642\n    },\n    \"out/dynamic-Q2DWDUFV.js\": {\n      \"imports\": [\n        {\n          \"path\": \"out/chunk-MQN2VSL5.js\",\n          \"kind\": \"import-statement\"\n        }\n      ],\n      \"exports\": [\n        \"default\"\n      ],\n      \"entryPoint\": \"project/dynamic.js\",\n      \"inputs\": {\n        \"project/dynamic.js\": {\n          \"bytesInOutput\": 25\n        }\n      },\n      \"bytes\": 119\n    },\n    \"out/chunk-MQN2VSL5.js\": {\n      \"imports\": [],\n      \"exports\": [\n        \"__commonJS\",\n        \"__require\"\n      ],\n      \"inputs\": {},\n      \"bytes\": 38\n    },\n    \"out/entry.css\": {\n      \"imports\": [\n        {\n          \"path\": \"extern.css\",\n          \"kind\": \"import-rule\",\n          \"external\": true\n        },\n        {\n          \"path\": \"data:image/svg+xml,<svg/>\",\n          \"kind\": \"url-token\"\n        },\n        {\n          \"path\": \"out/file-NVISQQTV.file\",\n          \"kind\": \"url-token\"\n        },\n        {\n          \"path\": \"out/copy-O3Y5SCJE.copy\",\n          \"kind\": \"url-token\"\n        },\n        {\n          \"path\": \"extern.png\",\n          \"kind\": \"url-token\",\n          \"external\": true\n        }\n      ],\n      \"entryPoint\": \"project/entry.css\",\n      \"inputs\": {\n        \"project/entry.css\": {\n          \"bytesInOutput\": 187\n        }\n      },\n      \"bytes\": 234\n    }\n  }\n}\n\n================================================================================\nTestMetafileVeryLongExternalPaths\n---------- /out/111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111-55DNWN2R.file ----------\n\n---------- /out/bytesInOutput should be at least 99 (1).js ----------\n// project/111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.file\nvar __default = \"./111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111-55DNWN2R.file\";\n\n// project/bytesInOutput should be at least 99 (1).js\nconsole.log(__default);\n\n---------- /out/222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222-55DNWN2R.copy ----------\n\n---------- /out/bytesInOutput should be at least 99 (2).js ----------\n// project/bytesInOutput should be at least 99 (2).js\nimport a from \"./222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222-55DNWN2R.copy\";\nconsole.log(a);\n\n---------- /out/bytesInOutput should be at least 99 (3).js ----------\n// project/bytesInOutput should be at least 99 (3).js\nimport(\"./333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333-DH3FVEAA.js\").then(console.log);\n\n---------- /out/333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333-DH3FVEAA.js ----------\n\n---------- /out/444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444-55DNWN2R.file ----------\n\n---------- /out/bytesInOutput should be at least 99.css ----------\n/* project/bytesInOutput should be at least 99.css */\na {\n  background: url(\"./444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444-55DNWN2R.file\");\n}\n---------- metafile.json ----------\n{\n  \"inputs\": {\n    \"project/111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.file\": {\n      \"bytes\": 0,\n      \"imports\": []\n    },\n    \"project/bytesInOutput should be at least 99 (1).js\": {\n      \"bytes\": 150,\n      \"imports\": [\n        {\n          \"path\": \"project/111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.file\",\n          \"kind\": \"import-statement\",\n          \"original\": \"./111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.file\"\n        }\n      ],\n      \"format\": \"esm\"\n    },\n    \"project/222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222.copy\": {\n      \"bytes\": 0,\n      \"imports\": []\n    },\n    \"project/bytesInOutput should be at least 99 (2).js\": {\n      \"bytes\": 150,\n      \"imports\": [\n        {\n          \"path\": \"project/222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222.copy\",\n          \"kind\": \"import-statement\",\n          \"original\": \"./222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222.copy\"\n        }\n      ],\n      \"format\": \"esm\"\n    },\n    \"project/333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333.js\": {\n      \"bytes\": 0,\n      \"imports\": []\n    },\n    \"project/bytesInOutput should be at least 99 (3).js\": {\n      \"bytes\": 141,\n      \"imports\": [\n        {\n          \"path\": \"project/333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333.js\",\n          \"kind\": \"dynamic-import\",\n          \"original\": \"./333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333.js\"\n        }\n      ]\n    },\n    \"project/444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444.file\": {\n      \"bytes\": 0,\n      \"imports\": []\n    },\n    \"project/bytesInOutput should be at least 99.css\": {\n      \"bytes\": 136,\n      \"imports\": [\n        {\n          \"path\": \"project/444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444.file\",\n          \"kind\": \"url-token\",\n          \"original\": \"444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444.file\"\n        }\n      ]\n    }\n  },\n  \"outputs\": {\n    \"out/111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111-55DNWN2R.file\": {\n      \"imports\": [],\n      \"exports\": [],\n      \"inputs\": {\n        \"project/111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.file\": {\n          \"bytesInOutput\": 0\n        }\n      },\n      \"bytes\": 0\n    },\n    \"out/bytesInOutput should be at least 99 (1).js\": {\n      \"imports\": [\n        {\n          \"path\": \"out/111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111-55DNWN2R.file\",\n          \"kind\": \"file-loader\"\n        }\n      ],\n      \"exports\": [],\n      \"entryPoint\": \"project/bytesInOutput should be at least 99 (1).js\",\n      \"inputs\": {\n        \"project/111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111.file\": {\n          \"bytesInOutput\": 135\n        },\n        \"project/bytesInOutput should be at least 99 (1).js\": {\n          \"bytesInOutput\": 24\n        }\n      },\n      \"bytes\": 330\n    },\n    \"out/222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222-55DNWN2R.copy\": {\n      \"imports\": [],\n      \"exports\": [],\n      \"inputs\": {\n        \"project/222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222.copy\": {\n          \"bytesInOutput\": 0\n        }\n      },\n      \"bytes\": 0\n    },\n    \"out/bytesInOutput should be at least 99 (2).js\": {\n      \"imports\": [\n        {\n          \"path\": \"out/222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222-55DNWN2R.copy\",\n          \"kind\": \"import-statement\"\n        }\n      ],\n      \"exports\": [],\n      \"entryPoint\": \"project/bytesInOutput should be at least 99 (2).js\",\n      \"inputs\": {\n        \"project/bytesInOutput should be at least 99 (2).js\": {\n          \"bytesInOutput\": 149\n        }\n      },\n      \"bytes\": 203\n    },\n    \"out/bytesInOutput should be at least 99 (3).js\": {\n      \"imports\": [\n        {\n          \"path\": \"out/333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333-DH3FVEAA.js\",\n          \"kind\": \"dynamic-import\"\n        }\n      ],\n      \"exports\": [],\n      \"entryPoint\": \"project/bytesInOutput should be at least 99 (3).js\",\n      \"inputs\": {\n        \"project/bytesInOutput should be at least 99 (3).js\": {\n          \"bytesInOutput\": 143\n        }\n      },\n      \"bytes\": 197\n    },\n    \"out/333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333-DH3FVEAA.js\": {\n      \"imports\": [],\n      \"exports\": [],\n      \"entryPoint\": \"project/333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333.js\",\n      \"inputs\": {\n        \"project/333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333.js\": {\n          \"bytesInOutput\": 0\n        }\n      },\n      \"bytes\": 0\n    },\n    \"out/444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444-55DNWN2R.file\": {\n      \"imports\": [],\n      \"exports\": [],\n      \"inputs\": {\n        \"project/444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444.file\": {\n          \"bytesInOutput\": 0\n        }\n      },\n      \"bytes\": 0\n    },\n    \"out/bytesInOutput should be at least 99.css\": {\n      \"imports\": [\n        {\n          \"path\": \"out/444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444-55DNWN2R.file\",\n          \"kind\": \"url-token\"\n        }\n      ],\n      \"entryPoint\": \"project/bytesInOutput should be at least 99.css\",\n      \"inputs\": {\n        \"project/bytesInOutput should be at least 99.css\": {\n          \"bytesInOutput\": 144\n        }\n      },\n      \"bytes\": 198\n    }\n  }\n}\n\n================================================================================\nTestMinifiedBundleCommonJS\n---------- /out.js ----------\nvar t=e(r=>{r.foo=function(){return 123}});var n=e((l,c)=>{c.exports={test:!0}});var{foo:f}=t();console.log(f(),n());\n\n================================================================================\nTestMinifiedBundleES6\n---------- /out.js ----------\nfunction o(){return 123}o();console.log(o());\n\n================================================================================\nTestMinifiedBundleEndingWithImportantSemicolon\n---------- /out.js ----------\n(()=>{while(foo());})();\n\n================================================================================\nTestMinifiedDynamicImportWithExpressionCJS\n---------- /out.js ----------\nimport(\"foo\");import(foo());\n\n================================================================================\nTestMinifiedExportsAndModuleFormatCommonJS\n---------- /out.js ----------\n// foo/test.js\nvar o = {};\np(o, {\n  foo: () => l\n});\nvar l = 123;\n\n// bar/test.js\nvar r = {};\np(r, {\n  bar: () => m\n});\nvar m = 123;\n\n// entry.js\nconsole.log(exports, module.exports, o, r);\n\n================================================================================\nTestMinifiedJSXPreserveWithObjectSpread\n---------- /out.js ----------\n// entry.jsx\nvar obj = {\n  before,\n  [key]: value,\n  key: value,\n  after\n};\n<Foo\n  before\n  {...{ [key]: value }}\n  key={value}\n  after\n/>;\n<Bar\n  a={a}\n  {...{ [b]: c }}\n  {...d}\n  e={e}\n/>;\n\n================================================================================\nTestMinifyArguments\n---------- /out.js ----------\n(() => {\n  // entry.js\n  function e(n = arguments) {\n    let t;\n  }\n  function u(n = arguments) {\n    let t;\n  }\n  function a(n = arguments) {\n    let t;\n  }\n  e();\n  u();\n  a();\n})();\n\n================================================================================\nTestMinifyIdentifiersImportPathFrequencyAnalysis\n---------- /out/import.js ----------\nvar o=123;console.log(o,\"no identifier in this file should be named W, X, Y, or Z\");\n\n---------- /out/require.js ----------\nvar i=r((t,e)=>{e.exports=123});var s=i();console.log(s,\"no identifier in this file should be named A, B, C, or D\");\n\n================================================================================\nTestMinifyNestedLabelsNoBundle\n---------- /out.js ----------\nl:n:a:b:c:d:e:f:g:h:i:j:k:m:o:p:{nl(`\n`);q:r:s:t:u:v:w:x:y:z:A:B:C:D:E:F:{nl(`\n`);G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:{nl(`\n`);W:X:Y:Z:_:$:ll:nl:al:bl:cl:dl:el:fl:gl:hl:{nl(`\n`);il:jl:kl:ml:ol:pl:ql:rl:sl:tl:ul:vl:wl:xl:yl:zl:{nl(`\n`);Al:Bl:Cl:Dl:El:Fl:Gl:Hl:Il:Jl:Kl:Ll:Ml:Nl:Ol:Pl:{nl(`\n`);Ql:Rl:Sl:Tl:Ul:Vl:Wl:Xl:Yl:Zl:_l:$l:ln:nn:an:bn:{nl(`\n`);cn:dn:en:fn:gn:hn:jn:kn:mn:on:pn:qn:rn:sn:tn:un:{nl(`\n`);vn:wn:xn:yn:zn:An:Bn:Cn:Dn:En:Fn:Gn:Hn:In:Jn:Kn:{nl(`\n`);Ln:Mn:Nn:On:Pn:Qn:Rn:Sn:Tn:Un:Vn:Wn:Xn:Yn:Zn:_n:{nl(`\n`);$n:la:na:aa:ba:ca:da:ea:fa:ga:ha:ia:ja:ka:ma:oa:{nl(`\n`);pa:qa:ra:sa:ta:ua:va:wa:xa:ya:za:Aa:Ba:Ca:Da:Ea:{nl(`\n`);Fa:Ga:Ha:Ia:Ja:Ka:La:Ma:Na:Oa:Pa:Qa:Ra:Sa:Ta:Ua:{nl(`\n`);Va:Wa:Xa:Ya:Za:_a:$a:lb:nb:ab:bb:cb:db:eb:fb:gb:{nl(`\n`);hb:ib:jb:kb:mb:ob:pb:qb:rb:sb:tb:ub:vb:wb:xb:yb:{nl(`\n`);zb:Ab:Bb:Cb:Db:Eb:Fb:Gb:Hb:Ib:Jb:Kb:Lb:Mb:Nb:Ob:{nl(`\n`);Pb:Qb:Rb:Sb:Tb:Ub:Vb:Wb:Xb:Yb:Zb:_b:$b:lc:nc:ac:{nl(`\n`);bc:cc:dc:ec:fc:gc:hc:ic:jc:kc:mc:oc:pc:qc:rc:sc:{nl(`\n`);tc:uc:vc:wc:xc:yc:zc:Ac:Bc:Cc:Dc:Ec:Fc:Gc:Hc:Ic:{nl(`\n`);Jc:Kc:Lc:Mc:Nc:Oc:Pc:Qc:Rc:Sc:Tc:Uc:Vc:Wc:Xc:Yc:{nl(`\n`);Zc:_c:$c:ld:nd:ad:bd:cd:dd:ed:fd:gd:hd:{}}}}}}}}}}}}}}}}}}nl(`\n`)}}}\n\n================================================================================\nTestMinifyPrivateIdentifiersNoBundle\n---------- /out.js ----------\nclass Foo {\n  #a;\n  foo = class {\n    #s;\n    #f;\n    #r;\n  };\n  get #o() {\n  }\n  set #o(a) {\n  }\n}\nclass Bar {\n  #a;\n  foo = class {\n    #s;\n    #f;\n    #r;\n  };\n  get #o() {\n  }\n  set #o(a) {\n  }\n}\n\n================================================================================\nTestMinifySiblingLabelsNoBundle\n---------- /out.js ----------\na: {\n  b: {\n    if (x) break b;\n    break a;\n  }\n}\na: {\n  b: {\n    if (x) break b;\n    break a;\n  }\n}\na: {\n  b: {\n    if (x) break b;\n    break a;\n  }\n}\n\n================================================================================\nTestMultipleEntryPointsSameNameCollision\n---------- /out/a/entry.js ----------\n// common.js\nvar foo = 123;\n\n// a/entry.js\nconsole.log(foo);\n\n---------- /out/b/entry.js ----------\n// common.js\nvar foo = 123;\n\n// b/entry.js\nconsole.log(foo);\n\n================================================================================\nTestNamedFunctionExpressionArgumentCollision\n---------- /out/entry.js ----------\nlet x = function(foo) {\n  var foo;\n  return foo;\n};\n\n================================================================================\nTestNestedCommonJS\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// entry.js\nfunction nestedScope() {\n  const fn = require_foo();\n  console.log(fn());\n}\nnestedScope();\n\n================================================================================\nTestNestedES6FromCommonJS\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports) {\n    exports.fn = function() {\n      return 123;\n    };\n  }\n});\n\n// entry.js\nvar import_foo = __toESM(require_foo());\n(() => {\n  console.log((0, import_foo.fn)());\n})();\n\n================================================================================\nTestNestedRequireWithoutCall\n---------- /out.js ----------\n// entry.js\n(() => {\n  const req = __require;\n  req(\"./entry\");\n})();\n\n================================================================================\nTestNestedScopeBug\n---------- /out.js ----------\n// entry.js\n(() => {\n  function a() {\n    b();\n  }\n  {\n    var b = () => {\n    };\n  }\n  a();\n})();\n\n================================================================================\nTestNewExpressionCommonJS\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports, module) {\n    var Foo = class {\n    };\n    module.exports = { Foo };\n  }\n});\n\n// entry.js\nnew (require_foo()).Foo();\n\n================================================================================\nTestNoWarnCommonJSExportsInESMPassThrough\n---------- /out/cjs-in-esm.js ----------\nexport let foo = 1;\nexports.foo = 2;\nmodule.exports = 3;\n\n---------- /out/import-in-cjs.js ----------\nimport { foo } from \"bar\";\nexports.foo = foo;\nmodule.exports = foo;\n\n---------- /out/no-warnings-here.js ----------\nconsole.log(module, exports);\n\n================================================================================\nTestNodeAnnotationFalsePositiveIssue3544\n---------- /out.js ----------\n// entry.mjs\nvar entry_exports = {};\n__export(entry_exports, {\n  confuseNode: () => confuseNode\n});\nmodule.exports = __toCommonJS(entry_exports);\nfunction confuseNode(exports2) {\n  exports2.notAnExport = function() {\n  };\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n  confuseNode\n});\n\n================================================================================\nTestNodeAnnotationInvalidIdentifierIssue4100\n---------- /out.js ----------\n// entry.mjs\nvar entry_exports = {};\n__export(entry_exports, {\n  \"...\": () => baz,\n  foo: () => foo,\n  if: () => bar\n});\nmodule.exports = __toCommonJS(entry_exports);\nvar foo;\nvar bar;\nvar baz;\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n  \"...\": null,\n  foo,\n  if: null\n});\n\n================================================================================\nTestNodeModules\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/index.js\nvar require_demo_pkg = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/index.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_demo_pkg());\nconsole.log((0, import_demo_pkg.default)());\n\n================================================================================\nTestNonDeterminismIssue2537\n---------- /out.js ----------\n// entry.ts\nfunction i(o, e) {\n  let r = \"teun\";\n  if (o) {\n    let u = function(n) {\n      return n * 2;\n    }, t = function(n) {\n      return n / 2;\n    };\n    var b = u, f = t;\n    r = u(e) + t(e);\n  }\n  return r;\n}\nexport {\n  i as aap\n};\n\n================================================================================\nTestObjectLiteralProtoSetterEdgeCases\n---------- /out/import-normal.js ----------\nimport { __proto__, bar } from \"foo\";\nfunction foo() {\n  console.log(\n    'this must not become \"{ __proto__ }\":',\n    {\n      __proto__: __proto__,\n      bar\n    }\n  );\n}\n\n---------- /out/import-shorthand.js ----------\nimport { __proto__, bar } from \"foo\";\nfunction foo() {\n  console.log(\n    'this must not become \"{ __proto__: ... }\":',\n    {\n      __proto__,\n      bar\n    }\n  );\n}\n\n---------- /out/local-normal.js ----------\nfunction foo(__proto__, bar) {\n  console.log(\n    'this must not become \"{ __proto__ }\":',\n    {\n      __proto__: __proto__,\n      bar\n    }\n  );\n}\n\n---------- /out/local-shorthand.js ----------\nfunction foo(__proto__, bar) {\n  {\n    let __proto__2, bar2;\n    console.log(\n      'this must not become \"{ __proto__: ... }\":',\n      {\n        [\"__proto__\"]: __proto__2,\n        bar: bar2\n      }\n    );\n  }\n}\n\n================================================================================\nTestObjectLiteralProtoSetterEdgeCasesMinifySyntax\n---------- /out/import-computed.js ----------\nimport { __proto__, bar } from \"foo\";\nfunction foo() {\n  console.log(\n    'this must not become \"{ __proto__: ... }\":',\n    {\n      [\"__proto__\"]: __proto__,\n      bar\n    }\n  );\n}\n\n---------- /out/import-normal.js ----------\nimport { __proto__, bar } from \"foo\";\nfunction foo() {\n  console.log(\n    'this must not become \"{ __proto__ }\":',\n    {\n      __proto__: __proto__,\n      bar\n    }\n  );\n}\n\n---------- /out/local-computed.js ----------\nfunction foo(__proto__, bar) {\n  {\n    let __proto__2, bar2;\n    console.log(\n      'this must not become \"{ __proto__: ... }\":',\n      {\n        [\"__proto__\"]: __proto__2,\n        bar: bar2\n      }\n    );\n  }\n}\n\n---------- /out/local-normal.js ----------\nfunction foo(__proto__, bar) {\n  console.log(\n    'this must not become \"{ __proto__ }\":',\n    {\n      __proto__: __proto__,\n      bar\n    }\n  );\n}\n\n================================================================================\nTestOutbase\n---------- /out/a/b/c.js ----------\n// a/b/c.js\nconsole.log(\"c\");\n\n---------- /out/a/b/d.js ----------\n// a/b/d.js\nconsole.log(\"d\");\n\n================================================================================\nTestOutputExtensionRemappingDir\n---------- /out/entry.notjs ----------\n// entry.js\nconsole.log(\"test\");\n\n================================================================================\nTestOutputExtensionRemappingFile\n---------- /out.js ----------\n// entry.js\nconsole.log(\"test\");\n\n================================================================================\nTestOutputForAssertTypeJSON\n---------- /out/foo-FYKHFNL2.copy ----------\n{}\n---------- /out/js-entry.js ----------\n// foo.json\nvar foo_default = {};\n\n// js-entry.js\nimport copy from \"./foo-FYKHFNL2.copy\" assert { type: \"json\" };\nuse(foo_default, copy, foo_default, void 0);\nexport {\n  foo_default as default\n};\n\n---------- /out/ts-entry.js ----------\n// foo.json\nvar foo_default = {};\n\n// ts-entry.ts\nimport copy from \"./foo-FYKHFNL2.copy\" assert { type: \"json\" };\nuse(foo_default, copy, foo_default, void 0);\nexport {\n  foo_default as default\n};\n\n================================================================================\nTestPackageAlias\n---------- /out.js ----------\n// node_modules/alias1/index.js\nconsole.log(1);\n\n// node_modules/alias2/foo.js\nconsole.log(2);\n\n// node_modules/alias3/index.js\nconsole.log(3);\n\n// node_modules/alias4/index.js\nconsole.log(4);\n\n// node_modules/alias5/foo.js\nconsole.log(5);\n\n// alias6/dir/index.js\nconsole.log(6);\n\n// alias7/dir/foo/index.js\nconsole.log(7);\n\n// alias8/dir/pkg8/index.js\nconsole.log(8);\n\n// alias9/some/file.js\nconsole.log(9);\n\n// node_modules/prefix-foo/index.js\nconsole.log(10);\n\n// node_modules/@scope/prefix-foo/index.js\nconsole.log(11);\n\n================================================================================\nTestPackageAliasMatchLongest\n---------- /out.js ----------\n// entry.js\nimport \"alias/pkg\";\nimport \"alias/pkg_foo\";\nimport \"alias/pkg_foo_bar\";\nimport \"alias/pkg_foo_bar/baz\";\nimport \"alias/pkg/bar/baz\";\nimport \"alias/pkg/baz\";\n\n================================================================================\nTestPreserveKeyComment\n---------- /out/entry.js ----------\nx(\n  /* __KEY__ */\n  \"notKey\",\n  /* __KEY__ */\n  `notKey`\n);\nx(/* @__KEY__ */ \"key\", /* @__KEY__ */ `key`);\nx(/* @__KEY__ */ \"alsoKey\", /* @__KEY__ */ `alsoKey`);\n\n================================================================================\nTestQuotedProperty\n---------- /out/entry.js ----------\n// entry.js\nvar ns = __toESM(require(\"ext\"));\nconsole.log(ns.mustBeUnquoted, ns[\"mustBeQuoted\"]);\n\n================================================================================\nTestQuotedPropertyMangle\n---------- /out/entry.js ----------\n// entry.js\nvar ns = __toESM(require(\"ext\"));\nconsole.log(ns.mustBeUnquoted, ns.mustBeUnquoted2);\n\n================================================================================\nTestReExportCommonJSAsES6\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports) {\n    exports.bar = 123;\n  }\n});\n\n// entry.js\nvar import_foo = __toESM(require_foo());\nvar export_bar = import_foo.bar;\nexport {\n  export_bar as bar\n};\n\n================================================================================\nTestReExportDefaultExternalCommonJS\n---------- /out.js ----------\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  bar: () => import_bar.default,\n  foo: () => import_foo.default\n});\nmodule.exports = __toCommonJS(entry_exports);\nvar import_foo = __toESM(require(\"foo\"));\n\n// bar.js\nvar import_bar = __toESM(require(\"bar\"));\n\n================================================================================\nTestReExportDefaultExternalES6\n---------- /out.js ----------\n// entry.js\nimport { default as default3 } from \"foo\";\n\n// bar.js\nimport { default as default2 } from \"bar\";\nexport {\n  default2 as bar,\n  default3 as foo\n};\n\n================================================================================\nTestReExportDefaultInternal\n---------- /out.js ----------\n// foo.js\nvar foo_default = \"foo\";\n\n// bar.js\nvar bar_default = \"bar\";\nexport {\n  bar_default as bar,\n  foo_default as foo\n};\n\n================================================================================\nTestReExportDefaultNoBundle\n---------- /out.js ----------\nexport { default as foo } from \"./foo\";\nexport { default as bar } from \"./bar\";\n\n================================================================================\nTestReExportDefaultNoBundleCommonJS\n---------- /out.js ----------\nvar entry_exports = {};\n__export(entry_exports, {\n  bar: () => import_bar.default,\n  foo: () => import_foo.default\n});\nmodule.exports = __toCommonJS(entry_exports);\nvar import_foo = __toESM(require(\"./foo\"));\nvar import_bar = __toESM(require(\"./bar\"));\n\n================================================================================\nTestReExportDefaultNoBundleES6\n---------- /out.js ----------\nimport { default as default2 } from \"./foo\";\nimport { default as default3 } from \"./bar\";\nexport {\n  default3 as bar,\n  default2 as foo\n};\n\n================================================================================\nTestReExportFSNode\n---------- /out.js ----------\n// foo.js\nimport * as fs from \"fs\";\nimport { readFileSync } from \"fs\";\nexport {\n  fs as f,\n  readFileSync as rfs\n};\n\n================================================================================\nTestRenameLabelsNoBundle\n---------- /out.js ----------\nfoo: {\n  bar: {\n    if (x) break bar;\n    break foo;\n  }\n}\nfoo2: {\n  bar2: {\n    if (x) break bar2;\n    break foo2;\n  }\n}\nfoo: {\n  bar: {\n    if (x) break bar;\n    break foo;\n  }\n}\n\n================================================================================\nTestRenamePrivateIdentifiersNoBundle\n---------- /out.js ----------\nclass Foo {\n  #foo;\n  foo = class {\n    #foo2;\n    #foo22;\n    #bar2;\n  };\n  get #bar() {\n  }\n  set #bar(x) {\n  }\n}\nclass Bar {\n  #foo;\n  foo = class {\n    #foo2;\n    #foo3;\n    #bar2;\n  };\n  get #bar() {\n  }\n  set #bar(x) {\n  }\n}\n\n================================================================================\nTestRequireAndDynamicImportInvalidTemplate\n---------- /out.js ----------\n// require(\"./**/*\") in entry.js\nvar globRequire;\nvar init_ = __esm({\n  'require(\"./**/*\") in entry.js'() {\n    globRequire = __glob({\n      \"./entry.js\": () => require_entry()\n    });\n  }\n});\n\n// import(\"./**/*\") in entry.js\nvar globImport;\nvar init_2 = __esm({\n  'import(\"./**/*\") in entry.js'() {\n    globImport = __glob({\n      \"./entry.js\": () => Promise.resolve().then(() => __toESM(require_entry()))\n    });\n  }\n});\n\n// entry.js\nvar require_entry = __commonJS({\n  \"entry.js\"() {\n    init_();\n    init_2();\n    __require(tag`./b`);\n    globRequire(`./${b}`);\n    try {\n      __require(tag`./b`);\n      globRequire(`./${b}`);\n    } catch {\n    }\n    (async () => {\n      import(tag`./b`);\n      globImport(`./${b}`);\n      await import(tag`./b`);\n      await globImport(`./${b}`);\n      try {\n        import(tag`./b`);\n        globImport(`./${b}`);\n        await import(tag`./b`);\n        await globImport(`./${b}`);\n      } catch {\n      }\n    })();\n  }\n});\nexport default require_entry();\n\n================================================================================\nTestRequireBadArgumentCount\n---------- /out.js ----------\n// entry.js\n__require();\n__require(\"a\", \"b\");\ntry {\n  __require();\n  __require(\"a\", \"b\");\n} catch {\n}\n\n================================================================================\nTestRequireChildDirCommonJS\n---------- /out.js ----------\n// Users/user/project/src/dir/index.js\nvar require_dir = __commonJS({\n  \"Users/user/project/src/dir/index.js\"(exports, module) {\n    module.exports = 123;\n  }\n});\n\n// Users/user/project/src/entry.js\nconsole.log(require_dir());\n\n================================================================================\nTestRequireChildDirES6\n---------- /out.js ----------\n// Users/user/project/src/dir/index.js\nvar dir_default = 123;\n\n// Users/user/project/src/entry.js\nconsole.log(dir_default);\n\n================================================================================\nTestRequireFSNode\n---------- /out.js ----------\n// entry.js\nreturn require(\"fs\");\n\n================================================================================\nTestRequireFSNodeMinify\n---------- /out.js ----------\nreturn require(\"fs\");\n\n================================================================================\nTestRequireJson\n---------- /out.js ----------\n// test.json\nvar require_test = __commonJS({\n  \"test.json\"(exports, module) {\n    module.exports = {\n      a: true,\n      b: 123,\n      c: [null]\n    };\n  }\n});\n\n// entry.js\nconsole.log(require_test());\n\n================================================================================\nTestRequireMainCacheCommonJS\n---------- /out.js ----------\n// is-main.js\nvar require_is_main = __commonJS({\n  \"is-main.js\"(exports2, module2) {\n    module2.exports = require.main === module2;\n  }\n});\n\n// entry.js\nconsole.log(\"is main:\", require.main === module);\nconsole.log(require_is_main());\nconsole.log(\"cache:\", require.cache);\n\n================================================================================\nTestRequireParentDirCommonJS\n---------- /out.js ----------\n// Users/user/project/src/index.js\nvar require_index = __commonJS({\n  \"Users/user/project/src/index.js\"(exports, module) {\n    module.exports = 123;\n  }\n});\n\n// Users/user/project/src/dir/entry.js\nconsole.log(require_index());\n\n================================================================================\nTestRequireParentDirES6\n---------- /out.js ----------\n// Users/user/project/src/index.js\nvar index_default = 123;\n\n// Users/user/project/src/dir/entry.js\nconsole.log(index_default);\n\n================================================================================\nTestRequirePropertyAccessCommonJS\n---------- /out.js ----------\n// entry.js\nconsole.log(Object.keys(require.cache));\nconsole.log(Object.keys(require.extensions));\ndelete require.cache[\"fs\"];\ndelete require.extensions[\".json\"];\n\n================================================================================\nTestRequireResolve\n---------- /out.js ----------\n// entry.js\nconsole.log(require.resolve);\nconsole.log(require.resolve());\nconsole.log(require.resolve(foo));\nconsole.log(require.resolve(\"a\", \"b\"));\nconsole.log(require.resolve(\"./present-file\"));\nconsole.log(require.resolve(\"./missing-file\"));\nconsole.log(require.resolve(\"./external-file\"));\nconsole.log(require.resolve(\"missing-pkg\"));\nconsole.log(require.resolve(\"external-pkg\"));\nconsole.log(require.resolve(\"@scope/missing-pkg\"));\nconsole.log(require.resolve(\"@scope/external-pkg\"));\ntry {\n  console.log(require.resolve(\"inside-try\"));\n} catch (e) {\n}\nif (false) {\n  console.log(null);\n}\nconsole.log(false ? null : 0);\nconsole.log(true ? 0 : null);\nconsole.log(false);\nconsole.log(true);\nconsole.log(true);\n\n================================================================================\nTestRequireShimSubstitution\n---------- /out/entry.js ----------\n// example.json\nvar require_example = __commonJS({\n  \"example.json\"(exports, module) {\n    module.exports = { works: true };\n  }\n});\n\n// entry.js\nconsole.log([\n  __require,\n  typeof __require,\n  require_example(),\n  __require(\"./example.json\", { type: \"json\" }),\n  __require(window.SOME_PATH),\n  require_example(),\n  __require(\"./example.json\", { type: \"json\" }),\n  __require(window.SOME_PATH),\n  __require.resolve(\"some-path\"),\n  __require.resolve(window.SOME_PATH),\n  Promise.resolve().then(() => __toESM(__require(\"some-path\"))),\n  Promise.resolve().then(() => __toESM(__require(window.SOME_PATH)))\n]);\n\n================================================================================\nTestRequireTxt\n---------- /out.js ----------\n// test.txt\nvar require_test = __commonJS({\n  \"test.txt\"(exports, module) {\n    module.exports = \"This is a test.\";\n  }\n});\n\n// entry.js\nconsole.log(require_test());\n\n================================================================================\nTestRequireWithCallInsideTry\n---------- /out.js ----------\n// entry.js\nvar require_entry = __commonJS({\n  \"entry.js\"(exports) {\n    try {\n      const supportsColor = __require(\"supports-color\");\n      if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {\n        exports.colors = [];\n      }\n    } catch (error) {\n    }\n  }\n});\nexport default require_entry();\n\n================================================================================\nTestRequireWithTemplate\n---------- /out.js ----------\n// b.js\nvar require_b = __commonJS({\n  \"b.js\"(exports) {\n    exports.x = 123;\n  }\n});\n\n// a.js\nconsole.log(require_b());\nconsole.log(require_b());\n\n================================================================================\nTestRequireWithoutCall\n---------- /out.js ----------\n// entry.js\nvar req = __require;\nreq(\"./entry\");\n\n================================================================================\nTestRequireWithoutCallInsideTry\n---------- /out.js ----------\n// entry.js\ntry {\n  oldLocale = globalLocale._abbr;\n  aliasedRequire = __require;\n  aliasedRequire(\"./locale/\" + name);\n  getSetGlobalLocale(oldLocale);\n} catch (e) {\n}\nvar aliasedRequire;\n\n================================================================================\nTestReserveProps\n---------- /out.js ----------\nexport default {\n  a: 0,\n  _bar_: 1\n};\n\n================================================================================\nTestRuntimeNameCollisionNoBundle\n---------- /out.js ----------\nfunction __require() {\n  return 123;\n}\nconsole.log(__require());\n\n================================================================================\nTestScopedExternalModuleExclusion\n---------- /out.js ----------\n// index.js\nimport { Foo } from \"@scope/foo\";\nimport { Bar } from \"@scope/foo/bar\";\nvar foo = new Foo();\nvar bar = new Bar();\nexport {\n  bar,\n  foo\n};\n\n================================================================================\nTestSimpleCommonJS\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// entry.js\nvar fn = require_foo();\nconsole.log(fn());\n\n================================================================================\nTestSimpleES6\n---------- /out.js ----------\n// foo.js\nfunction fn() {\n  return 123;\n}\n\n// entry.js\nconsole.log(fn());\n\n================================================================================\nTestSourceIdentifierNameIndexMultipleEntry\n---------- /Users/user/project/out/home/index.js ----------\n// Users/user/project/node_modules/pkg/index.js\nvar require_pkg = __commonJS({\n  \"Users/user/project/node_modules/pkg/index.js\"(exports) {\n    exports.pkg = true;\n  }\n});\n\n// Users/user/project/common/index.js\nvar require_common = __commonJS({\n  \"Users/user/project/common/index.js\"(exports) {\n    exports.common = true;\n  }\n});\n\n// Users/user/project/home/index.js\nvar require_home = __commonJS({\n  \"Users/user/project/home/index.js\"() {\n    require_home();\n    require_pkg();\n    require_common();\n  }\n});\nexport default require_home();\n\n---------- /Users/user/project/out/about/index.js ----------\n// Users/user/project/node_modules/pkg/index.js\nvar require_pkg = __commonJS({\n  \"Users/user/project/node_modules/pkg/index.js\"(exports) {\n    exports.pkg = true;\n  }\n});\n\n// Users/user/project/common/index.js\nvar require_common = __commonJS({\n  \"Users/user/project/common/index.js\"(exports) {\n    exports.common = true;\n  }\n});\n\n// Users/user/project/about/index.js\nvar require_about = __commonJS({\n  \"Users/user/project/about/index.js\"() {\n    require_about();\n    require_pkg();\n    require_common();\n  }\n});\nexport default require_about();\n\n================================================================================\nTestSourceIdentifierNameIndexSingleEntry\n---------- /Users/user/project/out/index.js ----------\n// Users/user/project/node_modules/pkg/index.js\nvar require_pkg = __commonJS({\n  \"Users/user/project/node_modules/pkg/index.js\"(exports) {\n    exports.pkg = true;\n  }\n});\n\n// Users/user/project/nested/index.js\nvar require_nested = __commonJS({\n  \"Users/user/project/nested/index.js\"(exports) {\n    exports.nested = true;\n  }\n});\n\n// Users/user/project/index.js\nvar require_index = __commonJS({\n  \"Users/user/project/index.js\"() {\n    require_index();\n    require_pkg();\n    require_nested();\n  }\n});\nexport default require_index();\n\n================================================================================\nTestSourceMap\n---------- /Users/user/project/out.js.map ----------\n{\n  \"version\": 3,\n  \"sources\": [\"src/bar.js\", \"src/data.txt\", \"src/entry.js\"],\n  \"sourcesContent\": [\"\\n\\t\\t\\t\\texport function bar() { throw new Error('test') }\\n\\t\\t\\t\", \"#2041\", \"\\n\\t\\t\\t\\timport {bar} from './bar'\\n\\t\\t\\t\\timport data from './data.txt'\\n\\t\\t\\t\\tfunction foo() { bar() }\\n\\t\\t\\t\\tfoo()\\n\\t\\t\\t\\tconsole.log(data)\\n\\t\\t\\t\"],\n  \"mappings\": \";AACW,SAAS,MAAM;AAAE,QAAM,IAAI,MAAM,MAAM;AAAE;;;ACDpD;;;ACGI,SAAS,MAAM;AAAE,MAAI;AAAE;AACvB,IAAI;AACJ,QAAQ,IAAI,YAAI;\",\n  \"names\": []\n}\n\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/bar.js\nfunction bar() {\n  throw new Error(\"test\");\n}\n\n// Users/user/project/src/data.txt\nvar data_default = \"#2041\";\n\n// Users/user/project/src/entry.js\nfunction foo() {\n  bar();\n}\nfoo();\nconsole.log(data_default);\n//# sourceMappingURL=out.js.map\n\n================================================================================\nTestStrictModeNestedFnDeclKeepNamesVariableInliningIssue1552\n---------- /out/entry.js ----------\nexport function outer() {\n  {\n    let inner = function() {\n      return Math.random();\n    };\n    __name(inner, \"inner\");\n    const x = inner();\n    console.log(x);\n  }\n}\n__name(outer, \"outer\"), outer();\n\n================================================================================\nTestStringExportNamesCommonJS\n---------- /out.js ----------\nvar entry_exports = {};\n__export(entry_exports, {\n  \"all the stuff\": () => all_the_stuff,\n  \"some export\": () => import_foo[\"some import\"]\n});\nmodule.exports = __toCommonJS(entry_exports);\nvar import_foo = require(\"./foo\");\nvar all_the_stuff = __toESM(require(\"./foo\"));\n\n================================================================================\nTestStringExportNamesIIFE\n---------- /out.js ----------\nvar global;\n(global ||= {}).name = (() => {\n  var entry_exports = {};\n  __export(entry_exports, {\n    \"all the stuff\": () => all_the_stuff,\n    \"some export\": () => import_foo[\"some import\"]\n  });\n  var import_foo = require(\"./foo\");\n  var all_the_stuff = __toESM(require(\"./foo\"));\n  return __toCommonJS(entry_exports);\n})();\n\n================================================================================\nTestSwitchScopeNoBundle\n---------- /out.js ----------\nswitch (foo) {\n  default:\n    var foo;\n}\nswitch (bar) {\n  default:\n    let a;\n}\n\n================================================================================\nTestThisInsideFunction\n---------- /out.js ----------\n// entry.js\nfunction foo(x = this) {\n  console.log(this);\n}\nvar objFoo = {\n  foo(x = this) {\n    console.log(this);\n  }\n};\nvar Foo = class {\n  x = this;\n  static y = this.z;\n  foo(x = this) {\n    console.log(this);\n  }\n  static bar(x = this) {\n    console.log(this);\n  }\n};\nnew Foo(foo(objFoo));\nif (nested) {\n  let bar = function(x = this) {\n    console.log(this);\n  };\n  bar2 = bar;\n  const objBar = {\n    foo(x = this) {\n      console.log(this);\n    }\n  };\n  class Bar {\n    x = this;\n    static y = this.z;\n    foo(x = this) {\n      console.log(this);\n    }\n    static bar(x = this) {\n      console.log(this);\n    }\n  }\n  new Bar(bar(objBar));\n}\nvar bar2;\n\n================================================================================\nTestThisOutsideFunction\n---------- /out.js ----------\n// entry.js\nvar require_entry = __commonJS({\n  \"entry.js\"(exports) {\n    if (shouldBeExportsNotThis) {\n      console.log(exports);\n      console.log((x = exports) => exports);\n      console.log({ x: exports });\n      console.log(class extends exports.foo {\n      });\n      console.log(class {\n        [exports.foo];\n      });\n      console.log(class {\n        [exports.foo]() {\n        }\n      });\n      console.log(class {\n        static [exports.foo];\n      });\n      console.log(class {\n        static [exports.foo]() {\n        }\n      });\n    }\n    if (shouldBeThisNotExports) {\n      console.log(class {\n        foo = this;\n      });\n      console.log(class {\n        foo() {\n          this;\n        }\n      });\n      console.log(class {\n        static foo = this;\n      });\n      console.log(class {\n        static foo() {\n          this;\n        }\n      });\n    }\n  }\n});\nexport default require_entry();\n\n================================================================================\nTestThisUndefinedWarningESM\n---------- /out/entry.js ----------\n// file1.js\nvar file1_default = [void 0, void 0];\n\n// node_modules/pkg/file2.js\nvar file2_default = [void 0, void 0];\n\n// entry.js\nconsole.log(file1_default, file2_default);\n\n================================================================================\nTestThisWithES6Syntax\n---------- /out.js ----------\n// cjs.js\nvar require_cjs = __commonJS({\n  \"cjs.js\"(exports) {\n    console.log(exports);\n  }\n});\n\n// dummy.js\nvar dummy_exports = {};\n__export(dummy_exports, {\n  dummy: () => dummy\n});\nvar dummy;\nvar init_dummy = __esm({\n  \"dummy.js\"() {\n    dummy = 123;\n  }\n});\n\n// es6-import-stmt.js\nvar require_es6_import_stmt = __commonJS({\n  \"es6-import-stmt.js\"(exports) {\n    init_dummy();\n    console.log(exports);\n  }\n});\n\n// es6-import-assign.ts\nvar require_es6_import_assign = __commonJS({\n  \"es6-import-assign.ts\"(exports) {\n    var x2 = (init_dummy(), __toCommonJS(dummy_exports));\n    console.log(exports);\n  }\n});\n\n// es6-import-dynamic.js\nvar require_es6_import_dynamic = __commonJS({\n  \"es6-import-dynamic.js\"(exports) {\n    Promise.resolve().then(() => init_dummy());\n    console.log(exports);\n  }\n});\n\n// es6-expr-import-dynamic.js\nvar require_es6_expr_import_dynamic = __commonJS({\n  \"es6-expr-import-dynamic.js\"(exports) {\n    Promise.resolve().then(() => init_dummy());\n    console.log(exports);\n  }\n});\n\n// es6-export-assign.ts\nvar require_es6_export_assign = __commonJS({\n  \"es6-export-assign.ts\"(exports, module) {\n    console.log(exports);\n    module.exports = 123;\n  }\n});\n\n// es6-ns-export-variable.ts\nvar require_es6_ns_export_variable = __commonJS({\n  \"es6-ns-export-variable.ts\"(exports) {\n    var ns;\n    ((ns2) => {\n      ns2.foo = 123;\n    })(ns || (ns = {}));\n    console.log(exports);\n  }\n});\n\n// es6-ns-export-function.ts\nvar require_es6_ns_export_function = __commonJS({\n  \"es6-ns-export-function.ts\"(exports) {\n    var ns;\n    ((ns2) => {\n      function foo() {\n      }\n      ns2.foo = foo;\n    })(ns || (ns = {}));\n    console.log(exports);\n  }\n});\n\n// es6-ns-export-async-function.ts\nvar require_es6_ns_export_async_function = __commonJS({\n  \"es6-ns-export-async-function.ts\"(exports) {\n    var ns;\n    ((ns2) => {\n      async function foo() {\n      }\n      ns2.foo = foo;\n    })(ns || (ns = {}));\n    console.log(exports);\n  }\n});\n\n// es6-ns-export-enum.ts\nvar require_es6_ns_export_enum = __commonJS({\n  \"es6-ns-export-enum.ts\"(exports) {\n    var ns;\n    ((ns2) => {\n      let Foo;\n      ((Foo2) => {\n      })(Foo = ns2.Foo || (ns2.Foo = {}));\n    })(ns || (ns = {}));\n    console.log(exports);\n  }\n});\n\n// es6-ns-export-const-enum.ts\nvar require_es6_ns_export_const_enum = __commonJS({\n  \"es6-ns-export-const-enum.ts\"(exports) {\n    var ns;\n    ((ns2) => {\n      let Foo;\n      ((Foo2) => {\n      })(Foo = ns2.Foo || (ns2.Foo = {}));\n    })(ns || (ns = {}));\n    console.log(exports);\n  }\n});\n\n// es6-ns-export-module.ts\nvar require_es6_ns_export_module = __commonJS({\n  \"es6-ns-export-module.ts\"(exports) {\n    console.log(exports);\n  }\n});\n\n// es6-ns-export-namespace.ts\nvar require_es6_ns_export_namespace = __commonJS({\n  \"es6-ns-export-namespace.ts\"(exports) {\n    console.log(exports);\n  }\n});\n\n// es6-ns-export-class.ts\nvar require_es6_ns_export_class = __commonJS({\n  \"es6-ns-export-class.ts\"(exports) {\n    var ns;\n    ((ns2) => {\n      class Foo {\n      }\n      ns2.Foo = Foo;\n    })(ns || (ns = {}));\n    console.log(exports);\n  }\n});\n\n// es6-ns-export-abstract-class.ts\nvar require_es6_ns_export_abstract_class = __commonJS({\n  \"es6-ns-export-abstract-class.ts\"(exports) {\n    var ns;\n    ((ns2) => {\n      class Foo {\n      }\n      ns2.Foo = Foo;\n    })(ns || (ns = {}));\n    console.log(exports);\n  }\n});\n\n// entry.js\nvar import_cjs = __toESM(require_cjs());\nvar import_es6_import_stmt = __toESM(require_es6_import_stmt());\nvar import_es6_import_assign = __toESM(require_es6_import_assign());\nvar import_es6_import_dynamic = __toESM(require_es6_import_dynamic());\n\n// es6-import-meta.js\nconsole.log(void 0);\n\n// entry.js\nvar import_es6_expr_import_dynamic = __toESM(require_es6_expr_import_dynamic());\n\n// es6-expr-import-meta.js\nconsole.log(void 0);\n\n// es6-export-variable.js\nconsole.log(void 0);\n\n// es6-export-function.js\nconsole.log(void 0);\n\n// es6-export-async-function.js\nconsole.log(void 0);\n\n// es6-export-enum.ts\nconsole.log(void 0);\n\n// es6-export-const-enum.ts\nconsole.log(void 0);\n\n// es6-export-module.ts\nconsole.log(void 0);\n\n// es6-export-namespace.ts\nconsole.log(void 0);\n\n// es6-export-class.js\nconsole.log(void 0);\n\n// es6-export-abstract-class.ts\nconsole.log(void 0);\n\n// es6-export-default.js\nconsole.log(void 0);\n\n// es6-export-clause.js\nconsole.log(void 0);\n\n// es6-export-clause-from.js\ninit_dummy();\nconsole.log(void 0);\n\n// es6-export-star.js\ninit_dummy();\nconsole.log(void 0);\n\n// es6-export-star-as.js\ninit_dummy();\nconsole.log(void 0);\n\n// entry.js\nvar import_es6_export_assign = __toESM(require_es6_export_assign());\n\n// es6-export-import-assign.ts\nvar x = (init_dummy(), __toCommonJS(dummy_exports));\nconsole.log(void 0);\n\n// entry.js\nvar import_es6_ns_export_variable = __toESM(require_es6_ns_export_variable());\nvar import_es6_ns_export_function = __toESM(require_es6_ns_export_function());\nvar import_es6_ns_export_async_function = __toESM(require_es6_ns_export_async_function());\nvar import_es6_ns_export_enum = __toESM(require_es6_ns_export_enum());\nvar import_es6_ns_export_const_enum = __toESM(require_es6_ns_export_const_enum());\nvar import_es6_ns_export_module = __toESM(require_es6_ns_export_module());\nvar import_es6_ns_export_namespace = __toESM(require_es6_ns_export_namespace());\nvar import_es6_ns_export_class = __toESM(require_es6_ns_export_class());\nvar import_es6_ns_export_abstract_class = __toESM(require_es6_ns_export_abstract_class());\n\n================================================================================\nTestToESMWrapperOmission\n---------- /out/entry.js ----------\nvar entry_exports = {};\nmodule.exports = __toCommonJS(entry_exports);\nvar import_a_nowrap = require(\"a_nowrap\");\nvar import_b_nowrap = require(\"b_nowrap\");\n__reExport(entry_exports, require(\"c_nowrap\"), module.exports);\nvar d = __toESM(require(\"d_WRAP\"));\nvar import_e_WRAP = __toESM(require(\"e_WRAP\"));\nvar import_f_WRAP = __toESM(require(\"f_WRAP\"));\nvar import_g_WRAP = __toESM(require(\"g_WRAP\"));\nvar h = __toESM(require(\"h_WRAP\"));\nvar i = __toESM(require(\"i_WRAP\"));\nvar j = __toESM(require(\"j_WRAP\"));\n(0, import_b_nowrap.b)();\nx = d.x;\n(0, import_e_WRAP.default)();\n(0, import_f_WRAP.default)();\n(0, import_g_WRAP.__esModule)();\nx = h;\ni.x();\nj.x``;\nx = Promise.resolve().then(() => __toESM(require(\"k_WRAP\")));\n\n================================================================================\nTestTopLevelAwaitAllowedImportWithSplitting\n---------- /out/entry.js ----------\n// entry.js\nimport(\"./a-3BAWOBN3.js\");\nimport(\"./b-2IGVSUS7.js\");\nimport(\"./c-DMBKURS2.js\");\nrequire_entry();\nawait 0;\n\n---------- /out/c-DMBKURS2.js ----------\nimport \"./chunk-GETF6B5C.js\";\n\n---------- /out/b-2IGVSUS7.js ----------\nimport \"./chunk-QJYGFXJG.js\";\nimport \"./chunk-GETF6B5C.js\";\n\n---------- /out/a-3BAWOBN3.js ----------\nimport \"./chunk-QJYGFXJG.js\";\nimport \"./chunk-GETF6B5C.js\";\n\n---------- /out/chunk-QJYGFXJG.js ----------\n\n---------- /out/chunk-GETF6B5C.js ----------\n// c.js\nawait 0;\n\n================================================================================\nTestTopLevelAwaitAllowedImportWithoutSplitting\n---------- /out.js ----------\n// c.js\nvar c_exports = {};\nvar init_c = __esm({\n  async \"c.js\"() {\n    await 0;\n  }\n});\n\n// b.js\nvar b_exports = {};\nvar init_b = __esm({\n  async \"b.js\"() {\n    await init_c();\n  }\n});\n\n// a.js\nvar a_exports = {};\nvar init_a = __esm({\n  async \"a.js\"() {\n    await init_b();\n  }\n});\n\n// entry.js\nvar entry_exports = {};\nvar init_entry = __esm({\n  async \"entry.js\"() {\n    init_a();\n    init_b();\n    init_c();\n    init_entry();\n    await 0;\n  }\n});\nawait init_entry();\n\n================================================================================\nTestTopLevelAwaitCJSDeadBranch\n---------- /out.js ----------\n// entry.js\nif (false) foo;\nif (false) for (foo of bar) ;\n\n================================================================================\nTestTopLevelAwaitESM\n---------- /out.js ----------\n// entry.js\nawait foo;\nfor await (foo of bar) ;\n\n================================================================================\nTestTopLevelAwaitESMDeadBranch\n---------- /out.js ----------\n// entry.js\nif (false) await foo;\nif (false) for await (foo of bar) ;\n\n================================================================================\nTestTopLevelAwaitForbiddenRequireDeadBranch\n---------- /out.js ----------\n(() => {\n  // c.js\n  var c_exports = {};\n  var init_c = __esm({\n    \"c.js\"() {\n      if (false) for (let x of y) ;\n    }\n  });\n\n  // b.js\n  var b_exports = {};\n  var init_b = __esm({\n    \"b.js\"() {\n      init_c();\n    }\n  });\n\n  // a.js\n  var a_exports = {};\n  var init_a = __esm({\n    \"a.js\"() {\n      init_b();\n    }\n  });\n\n  // entry.js\n  var entry_exports = {};\n  var init_entry = __esm({\n    \"entry.js\"() {\n      init_a();\n      init_b();\n      init_c();\n      init_entry();\n      if (false) for (let x of y) ;\n    }\n  });\n  init_entry();\n})();\n\n================================================================================\nTestTopLevelAwaitIIFEDeadBranch\n---------- /out.js ----------\n(() => {\n  // entry.js\n  if (false) foo;\n  if (false) for (foo of bar) ;\n})();\n\n================================================================================\nTestTopLevelAwaitNoBundle\n---------- /out.js ----------\nawait foo;\nfor await (foo of bar) ;\n\n================================================================================\nTestTopLevelAwaitNoBundleCommonJSDeadBranch\n---------- /out.js ----------\nif (false) foo;\nif (false) for (foo of bar) ;\n\n================================================================================\nTestTopLevelAwaitNoBundleDeadBranch\n---------- /out.js ----------\nif (false) await foo;\nif (false) for await (foo of bar) ;\n\n================================================================================\nTestTopLevelAwaitNoBundleESM\n---------- /out.js ----------\nawait foo;\nfor await (foo of bar) ;\n\n================================================================================\nTestTopLevelAwaitNoBundleESMDeadBranch\n---------- /out.js ----------\nif (false) await foo;\nif (false) for await (foo of bar) ;\n\n================================================================================\nTestTopLevelAwaitNoBundleIIFEDeadBranch\n---------- /out.js ----------\n(() => {\n  if (false) foo;\n  if (false) for (foo of bar) ;\n})();\n\n================================================================================\nTestUseStrictDirectiveBundleCJSIssue2264\n---------- /out.js ----------\n\"use strict\";\n\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  a: () => a\n});\nmodule.exports = __toCommonJS(entry_exports);\nvar a = 1;\n\n================================================================================\nTestUseStrictDirectiveBundleESMIssue2264\n---------- /out.js ----------\n// entry.js\nvar a = 1;\nexport {\n  a\n};\n\n================================================================================\nTestUseStrictDirectiveBundleIIFEIssue2264\n---------- /out.js ----------\n\"use strict\";\n(() => {\n  // entry.js\n  var a = 1;\n})();\n\n================================================================================\nTestUseStrictDirectiveBundleIssue1837\n---------- /out.js ----------\n(() => {\n  // shims.js\n  var import_process;\n  var init_shims = __esm({\n    \"shims.js\"() {\n      import_process = __toESM(__require(\"process\"));\n    }\n  });\n\n  // cjs.js\n  var require_cjs = __commonJS({\n    \"cjs.js\"(exports) {\n      \"use strict\";\n      init_shims();\n      exports.foo = import_process.default;\n    }\n  });\n\n  // entry.js\n  init_shims();\n  console.log(require_cjs());\n})();\n\n================================================================================\nTestUseStrictDirectiveMinifyNoBundle\n---------- /out.js ----------\n\"use strict\";\"use loose\";a,b;\n\n================================================================================\nTestVarRelocatingBundle\n---------- /out/top-level.js ----------\n// top-level.js\nfor (; 0; ) ;\nvar b;\nfor ({ c, x: [d] } = {}; 0; ) ;\nvar c;\nvar d;\nfor (e of []) ;\nvar e;\nfor ({ f, x: [g] } of []) ;\nvar f;\nvar g;\nfor (h in {}) ;\nvar h;\ni = 1;\nfor (i in {}) ;\nvar i;\nfor ({ j, x: [k] } in {}) ;\nvar j;\nvar k;\n\n---------- /out/nested.js ----------\n// nested.js\nif (true) {\n  let l = function() {\n  };\n  l2 = l;\n  for (; 0; ) ;\n  for ({ c, x: [d] } = {}; 0; ) ;\n  for (e of []) ;\n  for ({ f, x: [g] } of []) ;\n  for (h in {}) ;\n  i = 1;\n  for (i in {}) ;\n  for ({ j, x: [k] } in {}) ;\n}\nvar a;\nvar b;\nvar c;\nvar d;\nvar e;\nvar f;\nvar g;\nvar h;\nvar i;\nvar j;\nvar k;\nvar l2;\n\n---------- /out/let.js ----------\n// let.js\nif (true) {\n  let a;\n  for (let b; 0; ) ;\n  for (let { c, x: [d] } = {}; 0; ) ;\n  for (let e of []) ;\n  for (let { f, x: [g] } of []) ;\n  for (let h in {}) ;\n  for (let { j, x: [k] } in {}) ;\n}\n\n---------- /out/function.js ----------\n// function.js\nfunction x() {\n  var a;\n  for (var b; 0; ) ;\n  for (var { c, x: [d] } = {}; 0; ) ;\n  for (var e of []) ;\n  for (var { f, x: [g] } of []) ;\n  for (var h in {}) ;\n  i = 1;\n  for (var i in {}) ;\n  for (var { j, x: [k] } in {}) ;\n  function l() {\n  }\n}\nx();\n\n---------- /out/function-nested.js ----------\n// function-nested.js\nfunction x() {\n  if (true) {\n    let l2 = function() {\n    };\n    var l = l2;\n    var a;\n    for (var b; 0; ) ;\n    for (var { c, x: [d] } = {}; 0; ) ;\n    for (var e of []) ;\n    for (var { f, x: [g] } of []) ;\n    for (var h in {}) ;\n    i = 1;\n    for (var i in {}) ;\n    for (var { j, x: [k] } in {}) ;\n  }\n}\nx();\n\n================================================================================\nTestVarRelocatingNoBundle\n---------- /out/top-level.js ----------\nvar a;\nfor (var b; 0; ) ;\nfor (var { c, x: [d] } = {}; 0; ) ;\nfor (var e of []) ;\nfor (var { f, x: [g] } of []) ;\nfor (var h in {}) ;\ni = 1;\nfor (var i in {}) ;\nfor (var { j, x: [k] } in {}) ;\nfunction l() {\n}\n\n---------- /out/nested.js ----------\nif (true) {\n  let l = function() {\n  };\n  var l2 = l;\n  var a;\n  for (var b; 0; ) ;\n  for (var { c, x: [d] } = {}; 0; ) ;\n  for (var e of []) ;\n  for (var { f, x: [g] } of []) ;\n  for (var h in {}) ;\n  i = 1;\n  for (var i in {}) ;\n  for (var { j, x: [k] } in {}) ;\n}\n\n---------- /out/let.js ----------\nif (true) {\n  let a;\n  for (let b; 0; ) ;\n  for (let { c, x: [d] } = {}; 0; ) ;\n  for (let e of []) ;\n  for (let { f, x: [g] } of []) ;\n  for (let h in {}) ;\n  for (let { j, x: [k] } in {}) ;\n}\n\n---------- /out/function.js ----------\nfunction x() {\n  var a;\n  for (var b; 0; ) ;\n  for (var { c, x: [d] } = {}; 0; ) ;\n  for (var e of []) ;\n  for (var { f, x: [g] } of []) ;\n  for (var h in {}) ;\n  i = 1;\n  for (var i in {}) ;\n  for (var { j, x: [k] } in {}) ;\n  function l() {\n  }\n}\nx();\n\n---------- /out/function-nested.js ----------\nfunction x() {\n  if (true) {\n    let l2 = function() {\n    };\n    var l = l2;\n    var a;\n    for (var b; 0; ) ;\n    for (var { c, x: [d] } = {}; 0; ) ;\n    for (var e of []) ;\n    for (var { f, x: [g] } of []) ;\n    for (var h in {}) ;\n    i = 1;\n    for (var i in {}) ;\n    for (var { j, x: [k] } in {}) ;\n  }\n}\nx();\n\n================================================================================\nTestWarnCommonJSExportsInESMBundle\n---------- /out/cjs-in-esm.js ----------\n// cjs-in-esm.js\nvar cjs_in_esm_exports = {};\n__export(cjs_in_esm_exports, {\n  foo: () => foo\n});\nmodule.exports = __toCommonJS(cjs_in_esm_exports);\nvar foo = 1;\nexports.foo = 2;\nmodule.exports = 3;\n\n---------- /out/import-in-cjs.js ----------\n// import-in-cjs.js\nvar import_bar = require(\"bar\");\nexports.foo = import_bar.foo;\nmodule.exports = import_bar.foo;\n\n---------- /out/no-warnings-here.js ----------\n// no-warnings-here.js\nconsole.log(module, exports);\n\n================================================================================\nTestWarnCommonJSExportsInESMConvert\n---------- /out/cjs-in-esm.js ----------\nvar cjs_in_esm_exports = {};\n__export(cjs_in_esm_exports, {\n  foo: () => foo\n});\nmodule.exports = __toCommonJS(cjs_in_esm_exports);\nlet foo = 1;\nexports.foo = 2;\nmodule.exports = 3;\n\n---------- /out/cjs-in-esm2.js ----------\nvar cjs_in_esm2_exports = {};\n__export(cjs_in_esm2_exports, {\n  foo: () => foo\n});\nmodule.exports = __toCommonJS(cjs_in_esm2_exports);\nlet foo = 1;\nmodule.exports.bar = 3;\n\n---------- /out/import-in-cjs.js ----------\nvar import_bar = require(\"bar\");\nexports.foo = import_bar.foo;\nmodule.exports = import_bar.foo;\nmodule.exports.bar = import_bar.foo;\n\n---------- /out/no-warnings-here.js ----------\nconsole.log(module, exports);\n\n================================================================================\nTestWarningsInsideNodeModules\n---------- /out.js ----------\n// return-asi.js\nvar require_return_asi = __commonJS({\n  \"return-asi.js\"() {\n    return;\n  }\n});\n\n// node_modules/return-asi.js\nvar require_return_asi2 = __commonJS({\n  \"node_modules/return-asi.js\"() {\n    return;\n  }\n});\n\n// plugin-dir/node_modules/return-asi.js\nvar require_return_asi3 = __commonJS({\n  \"plugin-dir/node_modules/return-asi.js\"() {\n    return;\n  }\n});\n\n// dup-case.js\nswitch (x) {\n  case 0:\n  case 0:\n}\n\n// node_modules/dup-case.js\nswitch (x) {\n  case 0:\n  case 0:\n}\n\n// plugin-dir/node_modules/dup-case.js\nswitch (x) {\n  case 0:\n  case 0:\n}\n\n// not-in.js\n!a in b;\n\n// node_modules/not-in.js\n!a in b;\n\n// plugin-dir/node_modules/not-in.js\n!a in b;\n\n// not-instanceof.js\n!a instanceof b;\n\n// node_modules/not-instanceof.js\n!a instanceof b;\n\n// plugin-dir/node_modules/not-instanceof.js\n!a instanceof b;\n\n// entry.js\nvar import_return_asi = __toESM(require_return_asi());\nvar import_return_asi2 = __toESM(require_return_asi2());\nvar import_return_asi3 = __toESM(require_return_asi3());\n\n// equals-neg-zero.js\nx === -0;\n\n// node_modules/equals-neg-zero.js\nx === -0;\n\n// plugin-dir/node_modules/equals-neg-zero.js\nx === -0;\n\n// equals-nan.js\nx === NaN;\n\n// node_modules/equals-nan.js\nx === NaN;\n\n// plugin-dir/node_modules/equals-nan.js\nx === NaN;\n\n// equals-object.js\nx === [];\n\n// node_modules/equals-object.js\nx === [];\n\n// plugin-dir/node_modules/equals-object.js\nx === [];\n\n// delete-super.js\nvar Foo = class extends Bar {\n  foo() {\n    delete super.foo;\n  }\n};\n\n// node_modules/delete-super.js\nvar Foo2 = class extends Bar {\n  foo() {\n    delete super.foo;\n  }\n};\n\n// plugin-dir/node_modules/delete-super.js\nvar Foo3 = class extends Bar {\n  foo() {\n    delete super.foo;\n  }\n};\n\n================================================================================\nTestWithStatementTaintingNoBundle\n---------- /out.js ----------\n(() => {\n  let e = 1;\n  let outer = 2;\n  let outerDead = 3;\n  with ({}) {\n    var hoisted = 4;\n    let t = 5;\n    hoisted++;\n    t++;\n    if (1) outer++;\n    if (0) outerDead++;\n  }\n  if (1) {\n    hoisted++;\n    e++;\n    outer++;\n    outerDead++;\n  }\n})();\n"
  },
  {
    "path": "internal/bundler_tests/snapshots/snapshots_glob.txt",
    "content": "TestGlobBasicNoBundle\n---------- /out.js ----------\nconst ab = Math.random() < 0.5 ? \"a.js\" : \"b.js\";\nconsole.log({\n  concat: {\n    require: require(\"./src/\" + ab),\n    import: import(\"./src/\" + ab)\n  },\n  template: {\n    require: require(`./src/${ab}`),\n    import: import(`./src/${ab}`)\n  }\n});\n\n================================================================================\nTestGlobBasicNoSplitting\n---------- /out.js ----------\n// src/a.js\nvar require_a = __commonJS({\n  \"src/a.js\"(exports, module) {\n    module.exports = \"a\";\n  }\n});\n\n// src/b.js\nvar require_b = __commonJS({\n  \"src/b.js\"(exports, module) {\n    module.exports = \"b\";\n  }\n});\n\n// require(\"./src/**/*\") in entry.js\nvar globRequire_src = __glob({\n  \"./src/a.js\": () => require_a(),\n  \"./src/b.js\": () => require_b()\n});\n\n// import(\"./src/**/*\") in entry.js\nvar globImport_src = __glob({\n  \"./src/a.js\": () => Promise.resolve().then(() => __toESM(require_a())),\n  \"./src/b.js\": () => Promise.resolve().then(() => __toESM(require_b()))\n});\n\n// entry.js\nvar ab = Math.random() < 0.5 ? \"a.js\" : \"b.js\";\nconsole.log({\n  concat: {\n    require: globRequire_src(\"./src/\" + ab),\n    import: globImport_src(\"./src/\" + ab)\n  },\n  template: {\n    require: globRequire_src(`./src/${ab}`),\n    import: globImport_src(`./src/${ab}`)\n  }\n});\n\n================================================================================\nTestGlobBasicSplitting\n---------- /out/entry.js ----------\nimport {\n  require_a\n} from \"./chunk-KO426RN2.js\";\nimport {\n  require_b\n} from \"./chunk-SGVK3D4Q.js\";\nimport {\n  __glob\n} from \"./chunk-WCFE7E2E.js\";\n\n// require(\"./src/**/*\") in entry.js\nvar globRequire_src = __glob({\n  \"./src/a.js\": () => require_a(),\n  \"./src/b.js\": () => require_b()\n});\n\n// import(\"./src/**/*\") in entry.js\nvar globImport_src = __glob({\n  \"./src/a.js\": () => import(\"./a-7QA47R6Z.js\"),\n  \"./src/b.js\": () => import(\"./b-KY4MVCQS.js\")\n});\n\n// entry.js\nvar ab = Math.random() < 0.5 ? \"a.js\" : \"b.js\";\nconsole.log({\n  concat: {\n    require: globRequire_src(\"./src/\" + ab),\n    import: globImport_src(\"./src/\" + ab)\n  },\n  template: {\n    require: globRequire_src(`./src/${ab}`),\n    import: globImport_src(`./src/${ab}`)\n  }\n});\n\n---------- /out/a-7QA47R6Z.js ----------\nimport {\n  require_a\n} from \"./chunk-KO426RN2.js\";\nimport \"./chunk-WCFE7E2E.js\";\nexport default require_a();\n\n---------- /out/chunk-KO426RN2.js ----------\nimport {\n  __commonJS\n} from \"./chunk-WCFE7E2E.js\";\n\n// src/a.js\nvar require_a = __commonJS({\n  \"src/a.js\"(exports, module) {\n    module.exports = \"a\";\n  }\n});\n\nexport {\n  require_a\n};\n\n---------- /out/b-KY4MVCQS.js ----------\nimport {\n  require_b\n} from \"./chunk-SGVK3D4Q.js\";\nimport \"./chunk-WCFE7E2E.js\";\nexport default require_b();\n\n---------- /out/chunk-SGVK3D4Q.js ----------\nimport {\n  __commonJS\n} from \"./chunk-WCFE7E2E.js\";\n\n// src/b.js\nvar require_b = __commonJS({\n  \"src/b.js\"(exports, module) {\n    module.exports = \"b\";\n  }\n});\n\nexport {\n  require_b\n};\n\n---------- /out/chunk-WCFE7E2E.js ----------\nexport {\n  __glob,\n  __commonJS\n};\n\n================================================================================\nTestGlobEntryPointAbsPath\n---------- /out/entry.js ----------\n// Users/user/project/src/entry.js\nworks = true;\n\n================================================================================\nTestGlobNoMatches\n---------- /out/entry.js ----------\n// require(\"./src/**/*.json\") in entry.js\nvar globRequire_src_json = __glob({});\n\n// import(\"./src/**/*.json\") in entry.js\nvar globImport_src_json = __glob({});\n\n// entry.js\nvar ab = Math.random() < 0.5 ? \"a.js\" : \"b.js\";\nconsole.log({\n  concat: {\n    require: globRequire_src_json(\"./src/\" + ab + \".json\"),\n    import: globImport_src_json(\"./src/\" + ab + \".json\")\n  },\n  template: {\n    require: globRequire_src_json(`./src/${ab}.json`),\n    import: globImport_src_json(`./src/${ab}.json`)\n  }\n});\n\n================================================================================\nTestGlobWildcardNoSlash\n---------- /out.js ----------\n// src/file-a.js\nvar require_file_a = __commonJS({\n  \"src/file-a.js\"(exports, module) {\n    module.exports = \"a\";\n  }\n});\n\n// src/file-b.js\nvar require_file_b = __commonJS({\n  \"src/file-b.js\"(exports, module) {\n    module.exports = \"b\";\n  }\n});\n\n// require(\"./src/file-*.js\") in entry.js\nvar globRequire_src_file_js = __glob({\n  \"./src/file-a.js\": () => require_file_a(),\n  \"./src/file-b.js\": () => require_file_b()\n});\n\n// import(\"./src/file-*.js\") in entry.js\nvar globImport_src_file_js = __glob({\n  \"./src/file-a.js\": () => Promise.resolve().then(() => __toESM(require_file_a())),\n  \"./src/file-b.js\": () => Promise.resolve().then(() => __toESM(require_file_b()))\n});\n\n// entry.js\nvar ab = Math.random() < 0.5 ? \"a.js\" : \"b.js\";\nconsole.log({\n  concat: {\n    require: globRequire_src_file_js(\"./src/file-\" + ab + \".js\"),\n    import: globImport_src_file_js(\"./src/file-\" + ab + \".js\")\n  },\n  template: {\n    require: globRequire_src_file_js(`./src/file-${ab}.js`),\n    import: globImport_src_file_js(`./src/file-${ab}.js`)\n  }\n});\n\n================================================================================\nTestGlobWildcardSlash\n---------- /out.js ----------\n// src/file-a.js\nvar require_file_a = __commonJS({\n  \"src/file-a.js\"(exports, module) {\n    module.exports = \"a\";\n  }\n});\n\n// src/file-b.js\nvar require_file_b = __commonJS({\n  \"src/file-b.js\"(exports, module) {\n    module.exports = \"b\";\n  }\n});\n\n// src/nested/dir/file-a.js\nvar require_file_a2 = __commonJS({\n  \"src/nested/dir/file-a.js\"(exports, module) {\n    module.exports = \"a\";\n  }\n});\n\n// src/nested/dir/file-b.js\nvar require_file_b2 = __commonJS({\n  \"src/nested/dir/file-b.js\"(exports, module) {\n    module.exports = \"b\";\n  }\n});\n\n// require(\"./src/**/*.js\") in entry.js\nvar globRequire_src_js = __glob({\n  \"./src/file-a.js\": () => require_file_a(),\n  \"./src/file-b.js\": () => require_file_b(),\n  \"./src/nested/dir/file-a.js\": () => require_file_a2(),\n  \"./src/nested/dir/file-b.js\": () => require_file_b2()\n});\n\n// import(\"./src/**/*.js\") in entry.js\nvar globImport_src_js = __glob({\n  \"./src/file-a.js\": () => Promise.resolve().then(() => __toESM(require_file_a())),\n  \"./src/file-b.js\": () => Promise.resolve().then(() => __toESM(require_file_b())),\n  \"./src/nested/dir/file-a.js\": () => Promise.resolve().then(() => __toESM(require_file_a2())),\n  \"./src/nested/dir/file-b.js\": () => Promise.resolve().then(() => __toESM(require_file_b2()))\n});\n\n// entry.js\nvar ab = Math.random() < 0.5 ? \"a.js\" : \"b.js\";\nconsole.log({\n  concat: {\n    require: globRequire_src_js(\"./src/\" + ab + \".js\"),\n    import: globImport_src_js(\"./src/\" + ab + \".js\")\n  },\n  template: {\n    require: globRequire_src_js(`./src/${ab}.js`),\n    import: globImport_src_js(`./src/${ab}.js`)\n  }\n});\n\n================================================================================\nTestTSGlobBasicNoSplitting\n---------- /out.js ----------\n// src/a.ts\nvar require_a = __commonJS({\n  \"src/a.ts\"(exports, module) {\n    module.exports = \"a\";\n  }\n});\n\n// src/b.ts\nvar require_b = __commonJS({\n  \"src/b.ts\"(exports, module) {\n    module.exports = \"b\";\n  }\n});\n\n// require(\"./src/**/*\") in entry.ts\nvar globRequire_src = __glob({\n  \"./src/a.ts\": () => require_a(),\n  \"./src/b.ts\": () => require_b()\n});\n\n// import(\"./src/**/*\") in entry.ts\nvar globImport_src = __glob({\n  \"./src/a.ts\": () => Promise.resolve().then(() => __toESM(require_a())),\n  \"./src/b.ts\": () => Promise.resolve().then(() => __toESM(require_b()))\n});\n\n// entry.ts\nvar ab = Math.random() < 0.5 ? \"a.ts\" : \"b.ts\";\nconsole.log({\n  concat: {\n    require: globRequire_src(\"./src/\" + ab),\n    import: globImport_src(\"./src/\" + ab)\n  },\n  template: {\n    require: globRequire_src(`./src/${ab}`),\n    import: globImport_src(`./src/${ab}`)\n  }\n});\n\n================================================================================\nTestTSGlobBasicSplitting\n---------- /out/entry.js ----------\nimport {\n  require_a\n} from \"./chunk-YMCIDKCT.js\";\nimport {\n  require_b\n} from \"./chunk-2BST4PYI.js\";\nimport {\n  __glob\n} from \"./chunk-WCFE7E2E.js\";\n\n// require(\"./src/**/*\") in entry.ts\nvar globRequire_src = __glob({\n  \"./src/a.ts\": () => require_a(),\n  \"./src/b.ts\": () => require_b()\n});\n\n// import(\"./src/**/*\") in entry.ts\nvar globImport_src = __glob({\n  \"./src/a.ts\": () => import(\"./a-YXM4MR7E.js\"),\n  \"./src/b.ts\": () => import(\"./b-IPMBSSGN.js\")\n});\n\n// entry.ts\nvar ab = Math.random() < 0.5 ? \"a.ts\" : \"b.ts\";\nconsole.log({\n  concat: {\n    require: globRequire_src(\"./src/\" + ab),\n    import: globImport_src(\"./src/\" + ab)\n  },\n  template: {\n    require: globRequire_src(`./src/${ab}`),\n    import: globImport_src(`./src/${ab}`)\n  }\n});\n\n---------- /out/a-YXM4MR7E.js ----------\nimport {\n  require_a\n} from \"./chunk-YMCIDKCT.js\";\nimport \"./chunk-WCFE7E2E.js\";\nexport default require_a();\n\n---------- /out/chunk-YMCIDKCT.js ----------\nimport {\n  __commonJS\n} from \"./chunk-WCFE7E2E.js\";\n\n// src/a.ts\nvar require_a = __commonJS({\n  \"src/a.ts\"(exports, module) {\n    module.exports = \"a\";\n  }\n});\n\nexport {\n  require_a\n};\n\n---------- /out/b-IPMBSSGN.js ----------\nimport {\n  require_b\n} from \"./chunk-2BST4PYI.js\";\nimport \"./chunk-WCFE7E2E.js\";\nexport default require_b();\n\n---------- /out/chunk-2BST4PYI.js ----------\nimport {\n  __commonJS\n} from \"./chunk-WCFE7E2E.js\";\n\n// src/b.ts\nvar require_b = __commonJS({\n  \"src/b.ts\"(exports, module) {\n    module.exports = \"b\";\n  }\n});\n\nexport {\n  require_b\n};\n\n---------- /out/chunk-WCFE7E2E.js ----------\nexport {\n  __glob,\n  __commonJS\n};\n"
  },
  {
    "path": "internal/bundler_tests/snapshots/snapshots_importphase.txt",
    "content": "TestImportDeferExternalESM\n---------- /out.js ----------\n// entry.js\nimport defer * as foo0 from \"./foo.json\";\nimport defer * as foo1 from \"./foo.json\" with { type: \"json\" };\n\n// import.defer(\"./**/*.json\") in entry.js\nvar globImport_json = __glob({\n  \"./foo.json\": () => import.defer(\"./foo.json\")\n});\n\n// import.defer(\"./**/*.json\") in entry.js\nvar globImport_json2 = __glob({\n  \"./foo.json\": () => import.defer(\"./foo.json\", { with: { type: \"json\" } })\n});\n\n// entry.js\nconsole.log(\n  foo0,\n  foo1,\n  import.defer(\"./foo.json\"),\n  import.defer(\"./foo.json\", { with: { type: \"json\" } }),\n  globImport_json(`./${foo}.json`),\n  globImport_json2(`./${foo}.json`)\n);\n\n================================================================================\nTestImportSourceExternalESM\n---------- /out.js ----------\n// entry.js\nimport source foo0 from \"./foo.json\";\nimport source foo1 from \"./foo.json\" with { type: \"json\" };\n\n// import.source(\"./**/*.json\") in entry.js\nvar globImport_json = __glob({\n  \"./foo.json\": () => import.source(\"./foo.json\")\n});\n\n// import.source(\"./**/*.json\") in entry.js\nvar globImport_json2 = __glob({\n  \"./foo.json\": () => import.source(\"./foo.json\", { with: { type: \"json\" } })\n});\n\n// entry.js\nconsole.log(\n  foo0,\n  foo1,\n  import.source(\"./foo.json\"),\n  import.source(\"./foo.json\", { with: { type: \"json\" } }),\n  globImport_json(`./${foo}.json`),\n  globImport_json2(`./${foo}.json`)\n);\n"
  },
  {
    "path": "internal/bundler_tests/snapshots/snapshots_importstar.txt",
    "content": "TestExportOtherAsNamespaceCommonJS\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports) {\n    exports.foo = 123;\n  }\n});\n\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  ns: () => ns\n});\nmodule.exports = __toCommonJS(entry_exports);\nvar ns = __toESM(require_foo());\n\n================================================================================\nTestExportOtherCommonJS\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports) {\n    exports.foo = 123;\n  }\n});\n\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  bar: () => import_foo.bar\n});\nmodule.exports = __toCommonJS(entry_exports);\nvar import_foo = __toESM(require_foo());\n\n================================================================================\nTestExportOtherNestedCommonJS\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports) {\n    exports.foo = 123;\n  }\n});\n\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  y: () => import_foo.x\n});\nmodule.exports = __toCommonJS(entry_exports);\n\n// bar.js\nvar import_foo = __toESM(require_foo());\n\n================================================================================\nTestExportSelfAndImportSelfCommonJS\n---------- /out.js ----------\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  foo: () => foo\n});\nmodule.exports = __toCommonJS(entry_exports);\nvar foo = 123;\nconsole.log(entry_exports);\n\n================================================================================\nTestExportSelfAndRequireSelfCommonJS\n---------- /out.js ----------\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  foo: () => foo\n});\nmodule.exports = __toCommonJS(entry_exports);\nvar foo;\nvar init_entry = __esm({\n  \"entry.js\"() {\n    foo = 123;\n    console.log((init_entry(), __toCommonJS(entry_exports)));\n  }\n});\ninit_entry();\n\n================================================================================\nTestExportSelfAsNamespaceCommonJS\n---------- /out.js ----------\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  foo: () => foo,\n  ns: () => entry_exports\n});\nmodule.exports = __toCommonJS(entry_exports);\nvar foo = 123;\n\n================================================================================\nTestExportSelfAsNamespaceES6\n---------- /out.js ----------\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  foo: () => foo,\n  ns: () => entry_exports\n});\nvar foo = 123;\nexport {\n  foo,\n  entry_exports as ns\n};\n\n================================================================================\nTestExportSelfCommonJS\n---------- /out.js ----------\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  foo: () => foo\n});\nmodule.exports = __toCommonJS(entry_exports);\nvar foo = 123;\n\n================================================================================\nTestExportSelfCommonJSMinified\n---------- /out.js ----------\n// entry.js\nvar r = s((f, e) => {\n  e.exports = { foo: 123 };\n  console.log(r());\n});\nmodule.exports = r();\n\n================================================================================\nTestExportSelfES6\n---------- /out.js ----------\n// entry.js\nvar foo = 123;\nexport {\n  foo\n};\n\n================================================================================\nTestExportSelfIIFE\n---------- /out.js ----------\n(() => {\n  // entry.js\n  var foo = 123;\n})();\n\n================================================================================\nTestExportSelfIIFEWithName\n---------- /out.js ----------\nvar someName = (() => {\n  // entry.js\n  var entry_exports = {};\n  __export(entry_exports, {\n    foo: () => foo\n  });\n  var foo = 123;\n  return __toCommonJS(entry_exports);\n})();\n\n================================================================================\nTestExportStarDefaultExportCommonJS\n---------- /out.js ----------\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  foo: () => foo\n});\nmodule.exports = __toCommonJS(entry_exports);\n\n// foo.js\nvar foo = \"foo\";\n\n================================================================================\nTestImportDefaultNamespaceComboIssue446\n---------- /out/external-default2.js ----------\n// external-default2.js\nimport def, { default as default2 } from \"external\";\nconsole.log(def, default2);\n\n---------- /out/external-ns.js ----------\n// external-ns.js\nimport def, * as ns from \"external\";\nconsole.log(def, ns);\n\n---------- /out/external-ns-default.js ----------\n// external-ns-default.js\nimport def, * as ns from \"external\";\nconsole.log(def, ns, ns.default);\n\n---------- /out/external-ns-def.js ----------\n// external-ns-def.js\nimport def, * as ns from \"external\";\nconsole.log(def, ns, ns.def);\n\n---------- /out/external-default.js ----------\n// external-default.js\nimport def, * as ns from \"external\";\nconsole.log(def, ns.default);\n\n---------- /out/external-def.js ----------\n// external-def.js\nimport def, * as ns from \"external\";\nconsole.log(def, ns.def);\n\n---------- /out/internal-default2.js ----------\n// internal.js\nvar internal_default = 123;\n\n// internal-default2.js\nconsole.log(internal_default, internal_default);\n\n---------- /out/internal-ns.js ----------\n// internal.js\nvar internal_exports = {};\n__export(internal_exports, {\n  default: () => internal_default\n});\nvar internal_default = 123;\n\n// internal-ns.js\nconsole.log(internal_default, internal_exports);\n\n---------- /out/internal-ns-default.js ----------\n// internal.js\nvar internal_exports = {};\n__export(internal_exports, {\n  default: () => internal_default\n});\nvar internal_default = 123;\n\n// internal-ns-default.js\nconsole.log(internal_default, internal_exports, internal_default);\n\n---------- /out/internal-ns-def.js ----------\n// internal.js\nvar internal_exports = {};\n__export(internal_exports, {\n  default: () => internal_default\n});\nvar internal_default = 123;\n\n// internal-ns-def.js\nconsole.log(internal_default, internal_exports, void 0);\n\n---------- /out/internal-default.js ----------\n// internal.js\nvar internal_default = 123;\n\n// internal-default.js\nconsole.log(internal_default, internal_default);\n\n---------- /out/internal-def.js ----------\n// internal.js\nvar internal_default = 123;\n\n// internal-def.js\nconsole.log(internal_default, void 0);\n\n================================================================================\nTestImportExportOtherAsNamespaceCommonJS\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports) {\n    exports.foo = 123;\n  }\n});\n\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  ns: () => ns\n});\nmodule.exports = __toCommonJS(entry_exports);\nvar ns = __toESM(require_foo());\n\n================================================================================\nTestImportExportSelfAsNamespaceES6\n---------- /out.js ----------\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  foo: () => foo,\n  ns: () => entry_exports\n});\nvar foo = 123;\nexport {\n  foo,\n  entry_exports as ns\n};\n\n================================================================================\nTestImportExportStarAmbiguousWarning\n---------- /out.js ----------\n// foo.js\nvar x = 1;\n\n// bar.js\nvar z = 4;\n\n// entry.js\nconsole.log(x, void 0, z);\n\n================================================================================\nTestImportNamespaceUndefinedPropertyEmptyFile\n---------- /out/entry-nope.js ----------\n// empty.js\nvar require_empty = __commonJS({\n  \"empty.js\"() {\n  }\n});\n\n// empty.cjs\nvar require_empty2 = __commonJS({\n  \"empty.cjs\"() {\n  }\n});\n\n// entry-nope.js\nvar js = __toESM(require_empty());\nvar cjs = __toESM(require_empty2());\nconsole.log(\n  void 0,\n  void 0,\n  void 0\n);\n\n---------- /out/entry-default.js ----------\n// empty.js\nvar require_empty = __commonJS({\n  \"empty.js\"() {\n  }\n});\n\n// empty.cjs\nvar require_empty2 = __commonJS({\n  \"empty.cjs\"() {\n  }\n});\n\n// entry-default.js\nvar js = __toESM(require_empty());\nvar cjs = __toESM(require_empty2());\nconsole.log(\n  js.default,\n  void 0,\n  cjs.default\n);\n\n================================================================================\nTestImportNamespaceUndefinedPropertySideEffectFreeFile\n---------- /out/entry-nope.js ----------\n// foo/no-side-effects.js\nvar require_no_side_effects = __commonJS({\n  \"foo/no-side-effects.js\"() {\n    console.log(\"js\");\n  }\n});\n\n// foo/no-side-effects.cjs\nvar require_no_side_effects2 = __commonJS({\n  \"foo/no-side-effects.cjs\"() {\n    console.log(\"cjs\");\n  }\n});\n\n// entry-nope.js\nvar js = __toESM(require_no_side_effects());\nvar cjs = __toESM(require_no_side_effects2());\nconsole.log(\n  void 0,\n  void 0,\n  void 0\n);\n\n---------- /out/entry-default.js ----------\n// foo/no-side-effects.js\nvar require_no_side_effects = __commonJS({\n  \"foo/no-side-effects.js\"() {\n    console.log(\"js\");\n  }\n});\n\n// foo/no-side-effects.cjs\nvar require_no_side_effects2 = __commonJS({\n  \"foo/no-side-effects.cjs\"() {\n    console.log(\"cjs\");\n  }\n});\n\n// entry-default.js\nvar js = __toESM(require_no_side_effects());\nvar cjs = __toESM(require_no_side_effects2());\nconsole.log(\n  js.default,\n  void 0,\n  cjs.default\n);\n\n================================================================================\nTestImportOfExportStar\n---------- /out.js ----------\n// bar.js\nstatement();\nstatement();\nstatement();\nstatement();\nvar bar = 123;\n\n// entry.js\nconsole.log(bar);\n\n================================================================================\nTestImportOfExportStarOfImport\n---------- /out.js ----------\n// baz.js\nvar value = 123;\n\n// foo.js\nstatement();\nstatement();\nstatement();\nstatement();\n\n// entry.js\nconsole.log(value);\n\n================================================================================\nTestImportSelfCommonJS\n---------- /out.js ----------\n// entry.js\nvar require_entry = __commonJS({\n  \"entry.js\"(exports) {\n    var import_entry = __toESM(require_entry());\n    exports.foo = 123;\n    console.log(import_entry.foo);\n  }\n});\nmodule.exports = require_entry();\n\n================================================================================\nTestImportStarAndCommonJS\n---------- /out.js ----------\n// foo.js\nvar foo_exports = {};\n__export(foo_exports, {\n  foo: () => foo\n});\nvar foo;\nvar init_foo = __esm({\n  \"foo.js\"() {\n    foo = 123;\n  }\n});\n\n// entry.js\ninit_foo();\nvar ns2 = (init_foo(), __toCommonJS(foo_exports));\nconsole.log(foo, ns2.foo);\n\n================================================================================\nTestImportStarCapture\n---------- /out.js ----------\n// foo.js\nvar foo_exports = {};\n__export(foo_exports, {\n  foo: () => foo\n});\nvar foo = 123;\n\n// entry.js\nvar foo2 = 234;\nconsole.log(foo_exports, foo, foo2);\n\n================================================================================\nTestImportStarCommonJSCapture\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports) {\n    exports.foo = 123;\n  }\n});\n\n// entry.js\nvar ns = __toESM(require_foo());\nvar foo2 = 234;\nconsole.log(ns, ns.foo, foo2);\n\n================================================================================\nTestImportStarCommonJSNoCapture\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports) {\n    exports.foo = 123;\n  }\n});\n\n// entry.js\nvar ns = __toESM(require_foo());\nvar foo2 = 234;\nconsole.log(ns.foo, ns.foo, foo2);\n\n================================================================================\nTestImportStarCommonJSUnused\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports) {\n    exports.foo = 123;\n  }\n});\n\n// entry.js\nvar ns = __toESM(require_foo());\nvar foo = 234;\nconsole.log(foo);\n\n================================================================================\nTestImportStarExportImportStarCapture\n---------- /out.js ----------\n// foo.js\nvar foo_exports = {};\n__export(foo_exports, {\n  foo: () => foo\n});\nvar foo = 123;\n\n// entry.js\nvar foo2 = 234;\nconsole.log(foo_exports, foo_exports.foo, foo2);\n\n================================================================================\nTestImportStarExportImportStarNoCapture\n---------- /out.js ----------\n// foo.js\nvar foo_exports = {};\n__export(foo_exports, {\n  foo: () => foo\n});\nvar foo = 123;\n\n// entry.js\nvar foo2 = 234;\nconsole.log(foo_exports.foo, foo_exports.foo, foo2);\n\n================================================================================\nTestImportStarExportImportStarUnused\n---------- /out.js ----------\n// entry.js\nvar foo = 234;\nconsole.log(foo);\n\n================================================================================\nTestImportStarExportStarAsCapture\n---------- /out.js ----------\n// foo.js\nvar foo_exports = {};\n__export(foo_exports, {\n  foo: () => foo\n});\nvar foo = 123;\n\n// entry.js\nvar foo2 = 234;\nconsole.log(foo_exports, foo_exports.foo, foo2);\n\n================================================================================\nTestImportStarExportStarAsNoCapture\n---------- /out.js ----------\n// foo.js\nvar foo_exports = {};\n__export(foo_exports, {\n  foo: () => foo\n});\nvar foo = 123;\n\n// entry.js\nvar foo2 = 234;\nconsole.log(foo_exports.foo, foo_exports.foo, foo2);\n\n================================================================================\nTestImportStarExportStarAsUnused\n---------- /out.js ----------\n// entry.js\nvar foo = 234;\nconsole.log(foo);\n\n================================================================================\nTestImportStarExportStarCapture\n---------- /out.js ----------\n// bar.js\nvar bar_exports = {};\n__export(bar_exports, {\n  foo: () => foo\n});\n\n// foo.js\nvar foo = 123;\n\n// entry.js\nvar foo2 = 234;\nconsole.log(bar_exports, foo, foo2);\n\n================================================================================\nTestImportStarExportStarNoCapture\n---------- /out.js ----------\n// foo.js\nvar foo = 123;\n\n// entry.js\nvar foo2 = 234;\nconsole.log(foo, foo, foo2);\n\n================================================================================\nTestImportStarExportStarOmitAmbiguous\n---------- /out.js ----------\n// common.js\nvar common_exports = {};\n__export(common_exports, {\n  x: () => x,\n  z: () => z\n});\n\n// foo.js\nvar x = 1;\n\n// bar.js\nvar z = 4;\n\n// entry.js\nconsole.log(common_exports);\n\n================================================================================\nTestImportStarExportStarUnused\n---------- /out.js ----------\n// entry.js\nvar foo = 234;\nconsole.log(foo);\n\n================================================================================\nTestImportStarMangleNoBundleCapture\n---------- /out.js ----------\nimport * as ns from \"./foo\";\nlet foo = 234;\nconsole.log(ns, ns.foo, foo);\n\n================================================================================\nTestImportStarMangleNoBundleNoCapture\n---------- /out.js ----------\nimport * as ns from \"./foo\";\nlet foo = 234;\nconsole.log(ns.foo, ns.foo, foo);\n\n================================================================================\nTestImportStarMangleNoBundleUnused\n---------- /out.js ----------\nimport \"./foo\";\nlet foo = 234;\nconsole.log(foo);\n\n================================================================================\nTestImportStarNoBundleCapture\n---------- /out.js ----------\nimport * as ns from \"./foo\";\nlet foo = 234;\nconsole.log(ns, ns.foo, foo);\n\n================================================================================\nTestImportStarNoBundleNoCapture\n---------- /out.js ----------\nimport * as ns from \"./foo\";\nlet foo = 234;\nconsole.log(ns.foo, ns.foo, foo);\n\n================================================================================\nTestImportStarNoBundleUnused\n---------- /out.js ----------\nimport * as ns from \"./foo\";\nlet foo = 234;\nconsole.log(foo);\n\n================================================================================\nTestImportStarNoCapture\n---------- /out.js ----------\n// foo.js\nvar foo = 123;\n\n// entry.js\nvar foo2 = 234;\nconsole.log(foo, foo, foo2);\n\n================================================================================\nTestImportStarOfExportStarAs\n---------- /out.js ----------\n// foo.js\nvar foo_exports = {};\n__export(foo_exports, {\n  bar_ns: () => bar_exports\n});\n\n// bar.js\nvar bar_exports = {};\n__export(bar_exports, {\n  bar: () => bar\n});\nvar bar = 123;\n\n// entry.js\nconsole.log(foo_exports);\n\n================================================================================\nTestImportStarUnused\n---------- /out.js ----------\n// entry.js\nvar foo = 234;\nconsole.log(foo);\n\n================================================================================\nTestIssue176\n---------- /out.js ----------\n// folders/index.js\nvar folders_exports = {};\n__export(folders_exports, {\n  foo: () => foo\n});\n\n// folders/child/foo.js\nvar foo = () => \"hi there\";\n\n// entry.js\nconsole.log(JSON.stringify(folders_exports));\n\n================================================================================\nTestNamespaceImportMissingCommonJS\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports) {\n    exports.x = 123;\n  }\n});\n\n// entry.js\nvar ns = __toESM(require_foo());\nconsole.log(ns, ns.foo);\n\n================================================================================\nTestNamespaceImportMissingES6\n---------- /out.js ----------\n// foo.js\nvar foo_exports = {};\n__export(foo_exports, {\n  x: () => x\n});\nvar x = 123;\n\n// entry.js\nconsole.log(foo_exports, void 0);\n\n================================================================================\nTestNamespaceImportReExportStarMissingES6\n---------- /out.js ----------\n// foo.js\nvar foo_exports = {};\n__export(foo_exports, {\n  x: () => x\n});\n\n// bar.js\nvar x = 123;\n\n// entry.js\nconsole.log(foo_exports, void 0);\n\n================================================================================\nTestNamespaceImportReExportStarUnusedMissingES6\n---------- /out.js ----------\n// entry.js\nconsole.log(void 0);\n\n================================================================================\nTestNamespaceImportUnusedMissingCommonJS\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports) {\n    exports.x = 123;\n  }\n});\n\n// entry.js\nvar ns = __toESM(require_foo());\nconsole.log(ns.foo);\n\n================================================================================\nTestNamespaceImportUnusedMissingES6\n---------- /out.js ----------\n// entry.js\nconsole.log(void 0);\n\n================================================================================\nTestOtherFileExportSelfAsNamespaceUnusedES6\n---------- /out.js ----------\n// foo.js\nvar foo = 123;\nexport {\n  foo\n};\n\n================================================================================\nTestOtherFileImportExportSelfAsNamespaceUnusedES6\n---------- /out.js ----------\n// foo.js\nvar foo = 123;\nexport {\n  foo\n};\n\n================================================================================\nTestReExportNamespaceImportMissingES6\n---------- /out.js ----------\n// bar.js\nvar bar_exports = {};\n__export(bar_exports, {\n  x: () => x\n});\nvar x = 123;\n\n// entry.js\nconsole.log(bar_exports, bar_exports.foo);\n\n================================================================================\nTestReExportNamespaceImportUnusedMissingES6\n---------- /out.js ----------\n// bar.js\nvar bar_exports = {};\n__export(bar_exports, {\n  x: () => x\n});\nvar x = 123;\n\n// entry.js\nconsole.log(bar_exports.foo);\n\n================================================================================\nTestReExportOtherFileExportSelfAsNamespaceES6\n---------- /out.js ----------\n// foo.js\nvar foo_exports = {};\n__export(foo_exports, {\n  foo: () => foo,\n  ns: () => foo_exports\n});\nvar foo = 123;\nexport {\n  foo,\n  foo_exports as ns\n};\n\n================================================================================\nTestReExportOtherFileImportExportSelfAsNamespaceES6\n---------- /out.js ----------\n// foo.js\nvar foo_exports = {};\n__export(foo_exports, {\n  foo: () => foo,\n  ns: () => foo_exports\n});\nvar foo = 123;\nexport {\n  foo,\n  foo_exports as ns\n};\n\n================================================================================\nTestReExportStarAsCommonJSNoBundle\n---------- /out.js ----------\nvar entry_exports = {};\n__export(entry_exports, {\n  out: () => out\n});\nmodule.exports = __toCommonJS(entry_exports);\nvar out = __toESM(require(\"foo\"));\n\n================================================================================\nTestReExportStarAsES6NoBundle\n---------- /out.js ----------\nimport * as out from \"foo\";\nexport {\n  out\n};\n\n================================================================================\nTestReExportStarAsExternalCommonJS\n---------- /out.js ----------\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  out: () => out\n});\nmodule.exports = __toCommonJS(entry_exports);\nvar out = __toESM(require(\"foo\"));\n\n================================================================================\nTestReExportStarAsExternalES6\n---------- /out.js ----------\n// entry.js\nimport * as out from \"foo\";\nexport {\n  out\n};\n\n================================================================================\nTestReExportStarAsExternalIIFE\n---------- /out.js ----------\nvar mod = (() => {\n  // entry.js\n  var entry_exports = {};\n  __export(entry_exports, {\n    out: () => out\n  });\n  var out = __toESM(__require(\"foo\"));\n  return __toCommonJS(entry_exports);\n})();\n\n================================================================================\nTestReExportStarAsIIFENoBundle\n---------- /out.js ----------\nvar mod = (() => {\n  var entry_exports = {};\n  __export(entry_exports, {\n    out: () => out\n  });\n  var out = __toESM(require(\"foo\"));\n  return __toCommonJS(entry_exports);\n})();\n\n================================================================================\nTestReExportStarCommonJSNoBundle\n---------- /out.js ----------\nvar entry_exports = {};\nmodule.exports = __toCommonJS(entry_exports);\n__reExport(entry_exports, require(\"foo\"), module.exports);\n\n================================================================================\nTestReExportStarES6NoBundle\n---------- /out.js ----------\nexport * from \"foo\";\n\n================================================================================\nTestReExportStarEntryPointAndInnerFile\n---------- /out/entry.js ----------\n// entry.js\nvar entry_exports = {};\n__export(entry_exports, {\n  inner: () => inner_exports\n});\nmodule.exports = __toCommonJS(entry_exports);\n__reExport(entry_exports, require(\"a\"), module.exports);\n\n// inner.js\nvar inner_exports = {};\n__reExport(inner_exports, require(\"b\"));\n\n================================================================================\nTestReExportStarExternalCommonJS\n---------- /out.js ----------\n// entry.js\nvar entry_exports = {};\nmodule.exports = __toCommonJS(entry_exports);\n__reExport(entry_exports, require(\"foo\"), module.exports);\n\n================================================================================\nTestReExportStarExternalES6\n---------- /out.js ----------\n// entry.js\nexport * from \"foo\";\n\n================================================================================\nTestReExportStarExternalIIFE\n---------- /out.js ----------\nvar mod = (() => {\n  // entry.js\n  var entry_exports = {};\n  __reExport(entry_exports, __require(\"foo\"));\n  return __toCommonJS(entry_exports);\n})();\n\n================================================================================\nTestReExportStarIIFENoBundle\n---------- /out.js ----------\nvar mod = (() => {\n  var entry_exports = {};\n  __reExport(entry_exports, require(\"foo\"));\n  return __toCommonJS(entry_exports);\n})();\n\n================================================================================\nTestReExportStarNameCollisionNotAmbiguousExport\n---------- /out.js ----------\n// c.js\nvar x = 1;\nvar y = 2;\nexport {\n  x,\n  y\n};\n\n================================================================================\nTestReExportStarNameCollisionNotAmbiguousImport\n---------- /out.js ----------\n// c.js\nvar x = 1;\nvar y = 2;\n\n// entry.js\nconsole.log(x, y);\n\n================================================================================\nTestReExportStarNameShadowingNotAmbiguous\n---------- /out.js ----------\n// a.js\nvar x = 1;\n\n// entry.js\nconsole.log(x);\n\n================================================================================\nTestReExportStarNameShadowingNotAmbiguousReExport\n---------- /out.js ----------\n// b.js\nvar x = 1;\n\n// entry.js\nconsole.log(x);\n"
  },
  {
    "path": "internal/bundler_tests/snapshots/snapshots_importstar_ts.txt",
    "content": "TestTSImportStarAndCommonJS\n---------- /out.js ----------\n// foo.ts\nvar foo_exports = {};\n__export(foo_exports, {\n  foo: () => foo\n});\nvar foo;\nvar init_foo = __esm({\n  \"foo.ts\"() {\n    foo = 123;\n  }\n});\n\n// entry.js\ninit_foo();\nvar ns2 = (init_foo(), __toCommonJS(foo_exports));\nconsole.log(foo, ns2.foo);\n\n================================================================================\nTestTSImportStarCapture\n---------- /out.js ----------\n// foo.ts\nvar foo_exports = {};\n__export(foo_exports, {\n  foo: () => foo\n});\nvar foo = 123;\n\n// entry.ts\nvar foo2 = 234;\nconsole.log(foo_exports, foo, foo2);\n\n================================================================================\nTestTSImportStarCommonJSCapture\n---------- /out.js ----------\n// foo.ts\nvar require_foo = __commonJS({\n  \"foo.ts\"(exports) {\n    exports.foo = 123;\n  }\n});\n\n// entry.ts\nvar ns = __toESM(require_foo());\nvar foo2 = 234;\nconsole.log(ns, ns.foo, foo2);\n\n================================================================================\nTestTSImportStarCommonJSNoCapture\n---------- /out.js ----------\n// foo.ts\nvar require_foo = __commonJS({\n  \"foo.ts\"(exports) {\n    exports.foo = 123;\n  }\n});\n\n// entry.ts\nvar ns = __toESM(require_foo());\nvar foo2 = 234;\nconsole.log(ns.foo, ns.foo, foo2);\n\n================================================================================\nTestTSImportStarCommonJSUnused\n---------- /out.js ----------\n// entry.ts\nvar foo = 234;\nconsole.log(foo);\n\n================================================================================\nTestTSImportStarExportImportStarCapture\n---------- /out.js ----------\n// foo.ts\nvar foo_exports = {};\n__export(foo_exports, {\n  foo: () => foo\n});\nvar foo = 123;\n\n// entry.ts\nvar foo2 = 234;\nconsole.log(foo_exports, foo_exports.foo, foo2);\n\n================================================================================\nTestTSImportStarExportImportStarNoCapture\n---------- /out.js ----------\n// foo.ts\nvar foo_exports = {};\n__export(foo_exports, {\n  foo: () => foo\n});\nvar foo = 123;\n\n// entry.ts\nvar foo2 = 234;\nconsole.log(foo_exports.foo, foo_exports.foo, foo2);\n\n================================================================================\nTestTSImportStarExportImportStarUnused\n---------- /out.js ----------\n// entry.ts\nvar foo = 234;\nconsole.log(foo);\n\n================================================================================\nTestTSImportStarExportStarAsCapture\n---------- /out.js ----------\n// foo.ts\nvar foo_exports = {};\n__export(foo_exports, {\n  foo: () => foo\n});\nvar foo = 123;\n\n// entry.ts\nvar foo2 = 234;\nconsole.log(foo_exports, foo_exports.foo, foo2);\n\n================================================================================\nTestTSImportStarExportStarAsNoCapture\n---------- /out.js ----------\n// foo.ts\nvar foo_exports = {};\n__export(foo_exports, {\n  foo: () => foo\n});\nvar foo = 123;\n\n// entry.ts\nvar foo2 = 234;\nconsole.log(foo_exports.foo, foo_exports.foo, foo2);\n\n================================================================================\nTestTSImportStarExportStarAsUnused\n---------- /out.js ----------\n// entry.ts\nvar foo = 234;\nconsole.log(foo);\n\n================================================================================\nTestTSImportStarExportStarCapture\n---------- /out.js ----------\n// bar.ts\nvar bar_exports = {};\n__export(bar_exports, {\n  foo: () => foo\n});\n\n// foo.ts\nvar foo = 123;\n\n// entry.ts\nvar foo2 = 234;\nconsole.log(bar_exports, foo, foo2);\n\n================================================================================\nTestTSImportStarExportStarNoCapture\n---------- /out.js ----------\n// foo.ts\nvar foo = 123;\n\n// entry.ts\nvar foo2 = 234;\nconsole.log(foo, foo, foo2);\n\n================================================================================\nTestTSImportStarExportStarUnused\n---------- /out.js ----------\n// entry.ts\nvar foo = 234;\nconsole.log(foo);\n\n================================================================================\nTestTSImportStarMangleNoBundleCapture\n---------- /out.js ----------\nimport * as ns from \"./foo\";\nlet foo = 234;\nconsole.log(ns, ns.foo, foo);\n\n================================================================================\nTestTSImportStarMangleNoBundleNoCapture\n---------- /out.js ----------\nimport * as ns from \"./foo\";\nlet foo = 234;\nconsole.log(ns.foo, ns.foo, foo);\n\n================================================================================\nTestTSImportStarMangleNoBundleUnused\n---------- /out.js ----------\nlet foo = 234;\nconsole.log(foo);\n\n================================================================================\nTestTSImportStarNoBundleCapture\n---------- /out.js ----------\nimport * as ns from \"./foo\";\nlet foo = 234;\nconsole.log(ns, ns.foo, foo);\n\n================================================================================\nTestTSImportStarNoBundleNoCapture\n---------- /out.js ----------\nimport * as ns from \"./foo\";\nlet foo = 234;\nconsole.log(ns.foo, ns.foo, foo);\n\n================================================================================\nTestTSImportStarNoBundleUnused\n---------- /out.js ----------\nlet foo = 234;\nconsole.log(foo);\n\n================================================================================\nTestTSImportStarNoCapture\n---------- /out.js ----------\n// foo.ts\nvar foo = 123;\n\n// entry.ts\nvar foo2 = 234;\nconsole.log(foo, foo, foo2);\n\n================================================================================\nTestTSImportStarUnused\n---------- /out.js ----------\n// entry.ts\nvar foo = 234;\nconsole.log(foo);\n\n================================================================================\nTestTSReExportTypeOnlyFileES6\n---------- /out.js ----------\n// types1.ts\nconsole.log(\"some code\");\n\n// types2.ts\nconsole.log(\"some code\");\n\n// types3.ts\nconsole.log(\"some code\");\n\n// values.ts\nvar foo = 123;\n\n// entry.ts\nconsole.log(foo);\n"
  },
  {
    "path": "internal/bundler_tests/snapshots/snapshots_loader.txt",
    "content": "TestAutoDetectMimeTypeFromExtension\n---------- /out.js ----------\n// test.svg\nvar require_test = __commonJS({\n  \"test.svg\"(exports, module) {\n    module.exports = \"data:image/svg+xml;base64,YQBigGP/ZA==\";\n  }\n});\n\n// entry.js\nconsole.log(require_test());\n\n================================================================================\nTestEmptyLoaderCSS\n---------- /out.js.map ----------\n{\n  \"version\": 3,\n  \"sources\": [\"entry.css\"],\n  \"sourcesContent\": [\"\\n\\t\\t\\t\\t@import 'a.empty';\\n\\t\\t\\t\\ta { background: url(b.empty) }\\n\\t\\t\\t\"],\n  \"mappings\": \";AAEI;AAAI,cAAY;AAAa;\",\n  \"names\": []\n}\n\n---------- /out.js ----------\n/* entry.css */\na {\n  background: url();\n}\n---------- metafile.json ----------\n{\n  \"inputs\": {\n    \"a.empty\": {\n      \"bytes\": 0,\n      \"imports\": []\n    },\n    \"b.empty\": {\n      \"bytes\": 0,\n      \"imports\": []\n    },\n    \"entry.css\": {\n      \"bytes\": 62,\n      \"imports\": [\n        {\n          \"path\": \"a.empty\",\n          \"kind\": \"import-rule\",\n          \"original\": \"a.empty\"\n        },\n        {\n          \"path\": \"b.empty\",\n          \"kind\": \"url-token\",\n          \"original\": \"b.empty\"\n        }\n      ]\n    }\n  },\n  \"outputs\": {\n    \"out.js.map\": {\n      \"imports\": [],\n      \"exports\": [],\n      \"inputs\": {},\n      \"bytes\": 203\n    },\n    \"out.js\": {\n      \"imports\": [\n        {\n          \"path\": \"\",\n          \"kind\": \"url-token\",\n          \"external\": true\n        }\n      ],\n      \"entryPoint\": \"entry.css\",\n      \"inputs\": {\n        \"entry.css\": {\n          \"bytesInOutput\": 27\n        }\n      },\n      \"bytes\": 43\n    }\n  }\n}\n\n================================================================================\nTestEmptyLoaderJS\n---------- /out.js.map ----------\n{\n  \"version\": 3,\n  \"sources\": [\"entry.js\"],\n  \"sourcesContent\": [\"\\n\\t\\t\\t\\timport './a.empty'\\n\\t\\t\\t\\timport * as ns from './b.empty'\\n\\t\\t\\t\\timport def from './c.empty'\\n\\t\\t\\t\\timport { named } from './d.empty'\\n\\t\\t\\t\\tconsole.log(ns, def, named)\\n\\t\\t\\t\"],\n  \"mappings\": \";;;;;;;;;;;;;AAEI,SAAoB;AACpB,eAAgB;AAEhB,QAAQ,IAAI,IAAI,SAAAA,SAAK,MAAK;\",\n  \"names\": [\"def\"]\n}\n\n---------- /out.js ----------\n// b.empty\nvar require_b = __commonJS({\n  \"b.empty\"() {\n  }\n});\n\n// c.empty\nvar require_c = __commonJS({\n  \"c.empty\"() {\n  }\n});\n\n// entry.js\nvar ns = __toESM(require_b());\nvar import_c = __toESM(require_c());\nconsole.log(ns, import_c.default, void 0);\n---------- metafile.json ----------\n{\n  \"inputs\": {\n    \"a.empty\": {\n      \"bytes\": 0,\n      \"imports\": []\n    },\n    \"b.empty\": {\n      \"bytes\": 0,\n      \"imports\": []\n    },\n    \"c.empty\": {\n      \"bytes\": 0,\n      \"imports\": []\n    },\n    \"d.empty\": {\n      \"bytes\": 0,\n      \"imports\": []\n    },\n    \"entry.js\": {\n      \"bytes\": 165,\n      \"imports\": [\n        {\n          \"path\": \"a.empty\",\n          \"kind\": \"import-statement\",\n          \"original\": \"./a.empty\"\n        },\n        {\n          \"path\": \"b.empty\",\n          \"kind\": \"import-statement\",\n          \"original\": \"./b.empty\"\n        },\n        {\n          \"path\": \"c.empty\",\n          \"kind\": \"import-statement\",\n          \"original\": \"./c.empty\"\n        },\n        {\n          \"path\": \"d.empty\",\n          \"kind\": \"import-statement\",\n          \"original\": \"./d.empty\"\n        }\n      ],\n      \"format\": \"esm\"\n    }\n  },\n  \"outputs\": {\n    \"out.js.map\": {\n      \"imports\": [],\n      \"exports\": [],\n      \"inputs\": {},\n      \"bytes\": 377\n    },\n    \"out.js\": {\n      \"imports\": [],\n      \"exports\": [],\n      \"entryPoint\": \"entry.js\",\n      \"inputs\": {\n        \"b.empty\": {\n          \"bytesInOutput\": 53\n        },\n        \"c.empty\": {\n          \"bytesInOutput\": 53\n        },\n        \"entry.js\": {\n          \"bytesInOutput\": 111\n        }\n      },\n      \"bytes\": 253\n    }\n  }\n}\n\n================================================================================\nTestExtensionlessLoaderCSS\n---------- /out.js ----------\n/* what */\n.foo {\n  color: red;\n}\n\n/* entry.css */\n\n================================================================================\nTestExtensionlessLoaderJS\n---------- /out.js ----------\n// what\nfoo();\n\n================================================================================\nTestJSXAutomaticNoNameCollision\n---------- /out.js ----------\nvar import_react = require(\"react\");\nvar import_react2 = require(\"@remix-run/react\");\nconst x = /* @__PURE__ */ (0, import_react.createElement)(import_react2.Link, { ...y, key: z });\n\n================================================================================\nTestJSXPreserveCapitalLetter\n---------- /out.js ----------\n// foo.js\nvar MustStartWithUpperCaseLetter = class {\n};\n\n// entry.jsx\nconsole.log(<MustStartWithUpperCaseLetter />);\n\n================================================================================\nTestJSXPreserveCapitalLetterMinify\n---------- /out.js ----------\n// foo.js\nvar Y = class {\n};\n\n// entry.jsx\nconsole.log(<Y tag-must-start-with-capital-letter />);\n\n================================================================================\nTestJSXPreserveCapitalLetterMinifyNested\n---------- /out.js ----------\n// entry.jsx\nx = () => {\n  class Y {\n  }\n  return <Y tag-must-start-with-capital-letter />;\n};\n\n================================================================================\nTestJSXSyntaxInJSWithJSXLoader\n---------- /out.js ----------\n// entry.js\nconsole.log(/* @__PURE__ */ React.createElement(\"div\", null));\n\n================================================================================\nTestLoaderBase64CommonJSAndES6\n---------- /out.js ----------\n// x.b64\nvar require_x = __commonJS({\n  \"x.b64\"(exports, module) {\n    module.exports = \"eA==\";\n  }\n});\n\n// y.b64\nvar y_default = \"eQ==\";\n\n// entry.js\nvar x_b64 = require_x();\nconsole.log(x_b64, y_default);\n\n================================================================================\nTestLoaderBundleWithImportAttributes\n---------- /out.js ----------\n// data.json\nvar data_default = { works: true };\n\n// data.json with { type: 'json' }\nvar data_default2 = { works: true };\n\n// entry.js\nconsole.log(data_default === data_default, data_default !== data_default2);\n\n================================================================================\nTestLoaderBundleWithUnknownImportAttributesAndCopyLoader\n---------- /foo-AKINYSFH.thing ----------\n...\n---------- /bar-AXZXSLHF.thing ----------\n,,,\n---------- /out.js ----------\n// entry.js\nimport foo from \"./foo-AKINYSFH.thing\" with { type: \"whatever\" };\nimport bar from \"./bar-AXZXSLHF.thing\" with { whatever: \"true\" };\nconsole.log(foo, bar);\n\n================================================================================\nTestLoaderCopyEntryPointAdvanced\n---------- /out/xyz-DYPYXS7B.copy ----------\nmore stuff\n---------- /out/js/input/path.js ----------\n// project/entry.js\nimport xyz from \"../../xyz-DYPYXS7B.copy\";\nconsole.log(xyz);\n\n---------- /out/copy/input/path.copy ----------\nsome stuff\n================================================================================\nTestLoaderCopyExplicitOutputFile\n---------- /out/this.worked ----------\nsome stuff\n================================================================================\nTestLoaderCopyStartsWithDotAbsPath\n---------- /out/.htaccess ----------\nsome stuff\n---------- /out/entry.js ----------\n// project/src/entry.js\nsome.stuff();\n\n---------- /out/.js ----------\n// project/src/.ts\nfoo;\n\n================================================================================\nTestLoaderCopyStartsWithDotRelPath\n---------- /out/.htaccess ----------\nsome stuff\n---------- /out/entry.js ----------\n// entry.js\nsome.stuff();\n\n---------- /out/.js ----------\n// .ts\nfoo;\n\n================================================================================\nTestLoaderCopyUseIndex\n---------- /out/index.copy ----------\nsome stuff\n================================================================================\nTestLoaderCopyWithBundleEntryPoint\n---------- /out/assets/some.file ----------\nstuff\n---------- /out/src/entry.js ----------\n// Users/user/project/src/entry.js\nimport x from \"../assets/some.file\";\nconsole.log(x);\n\n---------- /out/src/entry.css ----------\n/* Users/user/project/src/entry.css */\nbody {\n  background: url(\"../assets/some.file\");\n}\n---------- metafile.json ----------\n{\n  \"inputs\": {\n    \"Users/user/project/assets/some.file\": {\n      \"bytes\": 5,\n      \"imports\": []\n    },\n    \"Users/user/project/src/entry.js\": {\n      \"bytes\": 63,\n      \"imports\": [\n        {\n          \"path\": \"Users/user/project/assets/some.file\",\n          \"kind\": \"import-statement\",\n          \"original\": \"../assets/some.file\"\n        }\n      ],\n      \"format\": \"esm\"\n    },\n    \"Users/user/project/src/entry.css\": {\n      \"bytes\": 64,\n      \"imports\": [\n        {\n          \"path\": \"Users/user/project/assets/some.file\",\n          \"kind\": \"url-token\",\n          \"original\": \"../assets/some.file\"\n        }\n      ]\n    }\n  },\n  \"outputs\": {\n    \"out/assets/some.file\": {\n      \"imports\": [],\n      \"exports\": [],\n      \"entryPoint\": \"Users/user/project/assets/some.file\",\n      \"inputs\": {\n        \"Users/user/project/assets/some.file\": {\n          \"bytesInOutput\": 5\n        }\n      },\n      \"bytes\": 5\n    },\n    \"out/src/entry.js\": {\n      \"imports\": [\n        {\n          \"path\": \"out/assets/some.file\",\n          \"kind\": \"import-statement\"\n        }\n      ],\n      \"exports\": [],\n      \"entryPoint\": \"Users/user/project/src/entry.js\",\n      \"inputs\": {\n        \"Users/user/project/src/entry.js\": {\n          \"bytesInOutput\": 53\n        }\n      },\n      \"bytes\": 88\n    },\n    \"out/src/entry.css\": {\n      \"imports\": [\n        {\n          \"path\": \"out/assets/some.file\",\n          \"kind\": \"url-token\"\n        }\n      ],\n      \"entryPoint\": \"Users/user/project/src/entry.css\",\n      \"inputs\": {\n        \"Users/user/project/src/entry.css\": {\n          \"bytesInOutput\": 51\n        }\n      },\n      \"bytes\": 90\n    }\n  }\n}\n\n================================================================================\nTestLoaderCopyWithBundleFromCSS\n---------- /out/some-BYATPJRB.file ----------\nstuff\n---------- /out/src/entry.css ----------\n/* Users/user/project/src/entry.css */\nbody {\n  background: url(\"../some-BYATPJRB.file\");\n}\n\n================================================================================\nTestLoaderCopyWithBundleFromJS\n---------- /out/some-BYATPJRB.file ----------\nstuff\n---------- /out/src/entry.js ----------\n// Users/user/project/src/entry.js\nimport x from \"../some-BYATPJRB.file\";\nconsole.log(x);\n\n================================================================================\nTestLoaderCopyWithFormat\n---------- /out/src/entry.js ----------\n(() => {\n  console.log(\"entry\");\n})();\n\n---------- /out/assets/some.file ----------\nstuff\n================================================================================\nTestLoaderCopyWithInjectedFileBundle\n---------- /out/inject-IFR6YGWW.js ----------\nconsole.log('in inject.js')\n---------- /out/entry.js ----------\n// src/entry.ts\nimport \"./inject-IFR6YGWW.js\";\nconsole.log(\"in entry.ts\");\n\n================================================================================\nTestLoaderCopyWithTransform\n---------- /out/src/entry.js ----------\nconsole.log(\"entry\");\n\n---------- /out/assets/some.file ----------\nstuff\n================================================================================\nTestLoaderDataURLApplicationJSON\n---------- /out/entry.js ----------\n// <data:application/json,\"%31%32%33\">\nvar json_31_32_33_default = \"123\";\n\n// <data:application/json;base64,eyJ3b3JrcyI6dHJ1ZX0=>\nvar json_base64_eyJ3b3JrcyI6dHJ1ZX0_default = { works: true };\n\n// <data:application/json;charset=UTF-8,%31%32%33>\nvar json_charset_UTF_8_31_32_33_default = 123;\n\n// <data:application/json;charset=UTF-8;base64,eyJ3b3JrcyI6dHJ1ZX0=>\nvar json_charset_UTF_8_base64_eyJ3b3JrcyI6dHJ1ZX0_default = { works: true };\n\n// entry.js\nconsole.log([\n  json_31_32_33_default,\n  json_base64_eyJ3b3JrcyI6dHJ1ZX0_default,\n  json_charset_UTF_8_31_32_33_default,\n  json_charset_UTF_8_base64_eyJ3b3JrcyI6dHJ1ZX0_default\n]);\n\n================================================================================\nTestLoaderDataURLBase64InvalidUTF8\n---------- /out.js ----------\n// binary.txt\nvar binary_default = \"data:text/plain;charset=utf-8;base64,/w==\";\n\n// entry.js\nconsole.log(binary_default);\n\n================================================================================\nTestLoaderDataURLBase64VsPercentEncoding\n---------- /out.js ----------\n// shouldUsePercent_1.txt\nvar shouldUsePercent_1_default = \"data:text/plain;charset=utf-8,%0A%0A%0A\";\n\n// shouldUsePercent_2.txt\nvar shouldUsePercent_2_default = \"data:text/plain;charset=utf-8,%0A%0A%0A%0A\";\n\n// shouldUseBase64_1.txt\nvar shouldUseBase64_1_default = \"data:text/plain;charset=utf-8;base64,CgoKCgo=\";\n\n// shouldUseBase64_2.txt\nvar shouldUseBase64_2_default = \"data:text/plain;charset=utf-8;base64,CgoKCgoK\";\n\n// entry.js\nconsole.log(\n  shouldUsePercent_1_default,\n  shouldUsePercent_2_default,\n  shouldUseBase64_1_default,\n  shouldUseBase64_2_default\n);\n\n================================================================================\nTestLoaderDataURLCommonJSAndES6\n---------- /out.js ----------\n// x.txt\nvar require_x = __commonJS({\n  \"x.txt\"(exports, module) {\n    module.exports = \"data:text/plain;charset=utf-8,x\";\n  }\n});\n\n// y.txt\nvar y_default = \"data:text/plain;charset=utf-8,y\";\n\n// entry.js\nvar x_url = require_x();\nconsole.log(x_url, y_default);\n\n================================================================================\nTestLoaderDataURLEscapePercents\n---------- /out.js ----------\n// percents.txt\nvar percents_default = \"data:text/plain;charset=utf-8,%0A%, %3, %2533, %25333%0A%, %e, %25ee, %25eee%0A%, %E, %25EE, %25EEE%0A\";\n\n// entry.js\nconsole.log(percents_default);\n\n================================================================================\nTestLoaderDataURLExtensionBasedMIME\n---------- /out/entry.js ----------\n// example.css\nvar example_default = \"data:text/css;charset=utf-8,css\";\n\n// example.eot\nvar example_default2 = \"data:application/vnd.ms-fontobject,eot\";\n\n// example.gif\nvar example_default3 = \"data:image/gif,gif\";\n\n// example.htm\nvar example_default4 = \"data:text/html;charset=utf-8,htm\";\n\n// example.html\nvar example_default5 = \"data:text/html;charset=utf-8,html\";\n\n// example.jpeg\nvar example_default6 = \"data:image/jpeg,jpeg\";\n\n// example.jpg\nvar example_default7 = \"data:image/jpeg,jpg\";\n\n// example.js\nvar example_default8 = \"data:text/javascript;charset=utf-8,js\";\n\n// example.json\nvar example_default9 = \"data:application/json;charset=utf-8,json\";\n\n// example.mjs\nvar example_default10 = \"data:text/javascript;charset=utf-8,mjs\";\n\n// example.otf\nvar example_default11 = \"data:font/otf,otf\";\n\n// example.pdf\nvar example_default12 = \"data:application/pdf,pdf\";\n\n// example.png\nvar example_default13 = \"data:image/png,png\";\n\n// example.sfnt\nvar example_default14 = \"data:font/sfnt,sfnt\";\n\n// example.svg\nvar example_default15 = \"data:image/svg+xml,svg\";\n\n// example.ttf\nvar example_default16 = \"data:font/ttf,ttf\";\n\n// example.wasm\nvar example_default17 = \"data:application/wasm,wasm\";\n\n// example.webp\nvar example_default18 = \"data:image/webp,webp\";\n\n// example.woff\nvar example_default19 = \"data:font/woff,woff\";\n\n// example.woff2\nvar example_default20 = \"data:font/woff2,woff2\";\n\n// example.xml\nvar example_default21 = \"data:text/xml;charset=utf-8,xml\";\nexport {\n  example_default as css,\n  example_default2 as eot,\n  example_default3 as gif,\n  example_default4 as htm,\n  example_default5 as html,\n  example_default6 as jpeg,\n  example_default7 as jpg,\n  example_default8 as js,\n  example_default9 as json,\n  example_default10 as mjs,\n  example_default11 as otf,\n  example_default12 as pdf,\n  example_default13 as png,\n  example_default14 as sfnt,\n  example_default15 as svg,\n  example_default16 as ttf,\n  example_default17 as wasm,\n  example_default18 as webp,\n  example_default19 as woff,\n  example_default20 as woff2,\n  example_default21 as xml\n};\n\n================================================================================\nTestLoaderDataURLHashSuffixIssue4370\n---------- /out/icons.css ----------\n/* icons.css */\n.triangle {\n  width: 10px;\n  height: 10px;\n  background: currentColor;\n  clip-path: url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\"><defs><clipPath id=\"x\"><path d=\"M0 0H10V10Z\"/></clipPath></defs></svg>#x');\n}\n\n================================================================================\nTestLoaderDataURLTextCSS\n---------- /out/entry.css ----------\n/* <data:text/css,body{color:%72%65%64}> */\nbody {\n  color: red;\n}\n\n/* <data:text/css;base64,Ym9keXtiYWNrZ3JvdW5kOmJsdWV9> */\nbody {\n  background: blue;\n}\n\n/* <data:text/css;charset=UTF-8,body{color:%72%65%64}> */\nbody {\n  color: red;\n}\n\n/* <data:text/css;charset=UTF-8;base64,Ym9keXtiYWNrZ3JvdW5kOmJsdWV9> */\nbody {\n  background: blue;\n}\n\n/* entry.css */\n\n================================================================================\nTestLoaderDataURLTextJavaScript\n---------- /out/entry.js ----------\n// <data:text/javascript,console.log('%31%32%33')>\nconsole.log(\"123\");\n\n// <data:text/javascript;base64,Y29uc29sZS5sb2coMjM0KQ==>\nconsole.log(234);\n\n// <data:text/javascript;charset=UTF-8,console.log(%31%32%33)>\nconsole.log(123);\n\n// <data:text/javascript;charset=UTF-8;base64,Y29uc29sZS5sb2coMjM0KQ...>\nconsole.log(234);\n\n================================================================================\nTestLoaderDataURLTextJavaScriptPlusCharacter\n---------- /out/entry.js ----------\n// <data:text/javascript,console.log(1+2)>\nconsole.log(1 + 2);\n\n================================================================================\nTestLoaderDataURLUnknownMIME\n---------- /out/entry.js ----------\n// entry.js\nimport a from \"data:some/thing;what,someData%31%32%33\";\nimport b from \"data:other/thing;stuff;base64,c29tZURhdGEyMzQ=\";\nconsole.log(a, b);\n\n================================================================================\nTestLoaderFile\n---------- /out/test-IPILGNO5.svg ----------\n<svg></svg>\n---------- /out/entry.js ----------\n// test.svg\nvar require_test = __commonJS({\n  \"test.svg\"(exports, module) {\n    module.exports = \"./test-IPILGNO5.svg\";\n  }\n});\n\n// entry.js\nconsole.log(require_test());\n\n================================================================================\nTestLoaderFileCommonJSAndES6\n---------- /y-YE5AYNFB.txt ----------\ny\n---------- /x-LSAMBFUD.txt ----------\nx\n---------- /out.js ----------\n// x.txt\nvar require_x = __commonJS({\n  \"x.txt\"(exports, module) {\n    module.exports = \"./x-LSAMBFUD.txt\";\n  }\n});\n\n// y.txt\nvar y_default = \"./y-YE5AYNFB.txt\";\n\n// entry.js\nvar x_url = require_x();\nconsole.log(x_url, y_default);\n\n================================================================================\nTestLoaderFileExtPathAssetNamesJS\n---------- /out/png/image-LSAMBFUD.png ----------\nx\n---------- /out/txt/file-YE5AYNFB.txt ----------\ny\n---------- /out/entries/entry.js ----------\n// src/images/image.png\nvar image_default = \"../png/image-LSAMBFUD.png\";\n\n// src/uploads/file.txt\nvar file_default = \"../txt/file-YE5AYNFB.txt\";\n\n// src/entries/entry.js\nconsole.log(image_default, file_default);\n\n================================================================================\nTestLoaderFileMultipleNoCollision\n---------- /dist/test-J7OMUXO3.txt ----------\ntest\n---------- /dist/out.js ----------\n// a/test.txt\nvar require_test = __commonJS({\n  \"a/test.txt\"(exports, module) {\n    module.exports = \"./test-J7OMUXO3.txt\";\n  }\n});\n\n// b/test.txt\nvar require_test2 = __commonJS({\n  \"b/test.txt\"(exports, module) {\n    module.exports = \"./test-J7OMUXO3.txt\";\n  }\n});\n\n// entry.js\nconsole.log(\n  require_test(),\n  require_test2()\n);\n\n================================================================================\nTestLoaderFileOneSourceTwoDifferentOutputPathsCSS\n---------- /out/common-LSAMBFUD.png ----------\nx\n---------- /out/entries/entry.css ----------\n/* src/shared/common.css */\ndiv {\n  background: url(\"../common-LSAMBFUD.png\");\n}\n\n/* src/entries/entry.css */\n\n---------- /out/entries/other/entry.css ----------\n/* src/shared/common.css */\ndiv {\n  background: url(\"../../common-LSAMBFUD.png\");\n}\n\n/* src/entries/other/entry.css */\n\n================================================================================\nTestLoaderFileOneSourceTwoDifferentOutputPathsJS\n---------- /out/common-LSAMBFUD.png ----------\nx\n---------- /out/entries/entry.js ----------\n// src/shared/common.png\nvar common_default = \"../common-LSAMBFUD.png\";\n\n// src/shared/common.js\nconsole.log(common_default);\n\n---------- /out/entries/other/entry.js ----------\n// src/shared/common.png\nvar common_default = \"../../common-LSAMBFUD.png\";\n\n// src/shared/common.js\nconsole.log(common_default);\n\n================================================================================\nTestLoaderFilePublicPathAssetNamesCSS\n---------- /out/images/image-LSAMBFUD.png ----------\nx\n---------- /out/entries/entry.css ----------\n/* src/entries/entry.css */\ndiv {\n  background: url(\"https://example.com/images/image-LSAMBFUD.png\");\n}\n\n================================================================================\nTestLoaderFilePublicPathAssetNamesJS\n---------- /out/images/image-LSAMBFUD.png ----------\nx\n---------- /out/entries/entry.js ----------\n// src/images/image.png\nvar image_default = \"https://example.com/images/image-LSAMBFUD.png\";\n\n// src/entries/entry.js\nconsole.log(image_default);\n\n================================================================================\nTestLoaderFilePublicPathCSS\n---------- /out/image-LSAMBFUD.png ----------\nx\n---------- /out/entries/entry.css ----------\n/* src/entries/entry.css */\ndiv {\n  background: url(\"https://example.com/image-LSAMBFUD.png\");\n}\n\n================================================================================\nTestLoaderFilePublicPathJS\n---------- /out/image-LSAMBFUD.png ----------\nx\n---------- /out/entries/entry.js ----------\n// src/images/image.png\nvar image_default = \"https://example.com/image-LSAMBFUD.png\";\n\n// src/entries/entry.js\nconsole.log(image_default);\n\n================================================================================\nTestLoaderFileRelativePathAssetNamesCSS\n---------- /out/images/image-LSAMBFUD.png ----------\nx\n---------- /out/entries/entry.css ----------\n/* src/entries/entry.css */\ndiv {\n  background: url(\"../images/image-LSAMBFUD.png\");\n}\n\n================================================================================\nTestLoaderFileRelativePathAssetNamesJS\n---------- /out/images/image-LSAMBFUD.png ----------\nx\n---------- /out/entries/entry.js ----------\n// src/images/image.png\nvar image_default = \"../images/image-LSAMBFUD.png\";\n\n// src/entries/entry.js\nconsole.log(image_default);\n\n================================================================================\nTestLoaderFileRelativePathCSS\n---------- /out/image-LSAMBFUD.png ----------\nx\n---------- /out/entries/entry.css ----------\n/* src/entries/entry.css */\ndiv {\n  background: url(\"../image-LSAMBFUD.png\");\n}\n\n================================================================================\nTestLoaderFileRelativePathJS\n---------- /out/image-LSAMBFUD.png ----------\nx\n---------- /out/entries/entry.js ----------\n// src/images/image.png\nvar image_default = \"../image-LSAMBFUD.png\";\n\n// src/entries/entry.js\nconsole.log(image_default);\n\n================================================================================\nTestLoaderFileWithQueryParameter\n---------- /out/file-UEHVHXRQ.txt ----------\nThis is some text\n---------- /out/entry.js ----------\n// file.txt?foo\nvar file_default = \"./file-UEHVHXRQ.txt?foo\";\n\n// file.txt?bar\nvar file_default2 = \"./file-UEHVHXRQ.txt?bar\";\n\n// entry.js\nconsole.log(file_default, file_default2);\n\n================================================================================\nTestLoaderFromExtensionWithQueryParameter\n---------- /out/entry.js ----------\n// file.abc?query.xyz\nvar file_default = \"This should not be base64 encoded\";\n\n// entry.js\nconsole.log(file_default);\n\n================================================================================\nTestLoaderInlineSourceMapAbsolutePathIssue4075Unix\n---------- /out/entry.css.map ----------\n{\n  \"version\": 3,\n  \"sources\": [\"src/styles1.scss\", \"src/styles2.scss\"],\n  \"sourcesContent\": [\"/* You can add global styles to this file, and also import other style files */\\n* {\\n  content: \\\"foo\\\"\\n}\\n\", \"/* You can add global styles to this file, and also import other style files */\\n* {\\n  content: \\\"bar\\\"\\n}\\n\"],\n  \"mappings\": \";AACA;AACE,WAAS;;;;ACDX;AACE,WAAS;;\",\n  \"names\": []\n}\n\n---------- /out/entry.css ----------\n/* home/user/project/src/styles1.css */\n* {\n  content: \"foo\";\n}\n\n/* home/user/project/src/styles2.css */\n* {\n  content: \"bar\";\n}\n\n/* home/user/project/src/entry.css */\n/*# sourceMappingURL=entry.css.map */\n\n================================================================================\nTestLoaderInlineSourceMapAbsolutePathIssue4075Windows\n---------- /out/entry.css.map ----------\n{\n  \"version\": 3,\n  \"sources\": [\"src/styles1.scss\", \"src/styles2.scss\"],\n  \"sourcesContent\": [\"/* You can add global styles to this file, and also import other style files */\\n* {\\n  content: \\\"foo\\\"\\n}\\n\", \"/* You can add global styles to this file, and also import other style files */\\n* {\\n  content: \\\"bar\\\"\\n}\\n\"],\n  \"mappings\": \";AACA;AACE,WAAS;;;;ACDX;AACE,WAAS;;\",\n  \"names\": []\n}\n\n---------- /out/entry.css ----------\n/* home/user/project/src/styles1.css */\n* {\n  content: \"foo\";\n}\n\n/* home/user/project/src/styles2.css */\n* {\n  content: \"bar\";\n}\n\n/* home/user/project/src/entry.css */\n/*# sourceMappingURL=entry.css.map */\n\n================================================================================\nTestLoaderJSONCommonJSAndES6\n---------- /out.js ----------\n// x.json\nvar require_x = __commonJS({\n  \"x.json\"(exports, module) {\n    module.exports = { x: true };\n  }\n});\n\n// y.json\nvar y_default = { y1: true, y2: false };\n\n// z.json\nvar small = \"some small text\";\nvar if2 = \"test keyword imports\";\n\n// entry.js\nvar x_json = require_x();\nconsole.log(x_json, y_default, small, if2);\n\n================================================================================\nTestLoaderJSONInvalidIdentifierES6\n---------- /out.js ----------\n// test.json\nvar invalid_identifier = true;\n\n// test2.json\nvar test2_exports = {};\n__export(test2_exports, {\n  default: () => test2_default,\n  \"invalid-identifier\": () => invalid_identifier2\n});\nvar invalid_identifier2 = true;\nvar test2_default = { \"invalid-identifier\": invalid_identifier2 };\n\n// entry.js\nconsole.log(invalid_identifier, test2_exports);\n\n================================================================================\nTestLoaderJSONNoBundle\n---------- /out.js ----------\nmodule.exports = { test: 123, \"invalid-identifier\": true };\n\n================================================================================\nTestLoaderJSONNoBundleCommonJS\n---------- /out.js ----------\nmodule.exports = { test: 123, \"invalid-identifier\": true };\n\n================================================================================\nTestLoaderJSONNoBundleES6\n---------- /out.js ----------\nvar test = 123;\nvar test_default = { test, \"invalid-identifier\": true };\nexport {\n  test_default as default,\n  test\n};\n\n================================================================================\nTestLoaderJSONNoBundleES6ArbitraryModuleNamespaceNames\n---------- /out.js ----------\nvar test = 123;\nvar invalid_identifier = true;\nvar test_default = { test, \"invalid-identifier\": invalid_identifier };\nexport {\n  test_default as default,\n  invalid_identifier as \"invalid-identifier\",\n  test\n};\n\n================================================================================\nTestLoaderJSONNoBundleIIFE\n---------- /out.js ----------\n(() => {\n  var require_test = __commonJS({\n    \"test.json\"(exports, module) {\n      module.exports = { test: 123, \"invalid-identifier\": true };\n    }\n  });\n  require_test();\n})();\n\n================================================================================\nTestLoaderJSONPrototype\n---------- /out.js ----------\n// data.json\nvar data_default = {\n  \"\": \"The property below should be converted to a computed property:\",\n  [\"__proto__\"]: { foo: \"bar\" }\n};\n\n// entry.js\nconsole.log(data_default);\n\n================================================================================\nTestLoaderJSONPrototypeES5\n---------- /out.js ----------\n// data.json\nvar data_default = {\n  \"\": \"The property below should NOT be converted to a computed property for ES5:\",\n  __proto__: { foo: \"bar\" }\n};\n\n// entry.js\nconsole.log(data_default);\n\n================================================================================\nTestLoaderJSONSharedWithMultipleEntriesIssue413\n---------- /out/a.js ----------\n// data.json\nvar data_default = { test: 123 };\n\n// a.js\nconsole.log(\"a:\", data_default);\n\n---------- /out/b.js ----------\n// data.json\nvar data_default = { test: 123 };\n\n// b.js\nconsole.log(\"b:\", data_default);\n\n================================================================================\nTestLoaderTextCommonJSAndES6\n---------- /out.js ----------\n// x.txt\nvar require_x = __commonJS({\n  \"x.txt\"(exports, module) {\n    module.exports = \"x\";\n  }\n});\n\n// y.txt\nvar y_default = \"y\";\n\n// entry.js\nvar x_txt = require_x();\nconsole.log(x_txt, y_default);\n\n================================================================================\nTestLoaderTextUTF8BOM\n---------- /out.js ----------\n// data1.txt\nvar data1_default = \"text\";\n\n// data2.txt\nvar data2_default = \"text\\uFEFF\";\n\n// entry.js\nconsole.log(data1_default, data2_default);\n\n================================================================================\nTestRequireCustomExtensionBase64\n---------- /out.js ----------\n// test.custom\nvar require_test = __commonJS({\n  \"test.custom\"(exports, module) {\n    module.exports = \"YQBigGP/ZA==\";\n  }\n});\n\n// entry.js\nconsole.log(require_test());\n\n================================================================================\nTestRequireCustomExtensionDataURL\n---------- /out.js ----------\n// test.custom\nvar require_test = __commonJS({\n  \"test.custom\"(exports, module) {\n    module.exports = \"data:application/octet-stream;base64,YQBigGP/ZA==\";\n  }\n});\n\n// entry.js\nconsole.log(require_test());\n\n================================================================================\nTestRequireCustomExtensionPreferLongest\n---------- /out.js ----------\n// test.txt\nvar require_test = __commonJS({\n  \"test.txt\"(exports, module) {\n    module.exports = \"test.txt\";\n  }\n});\n\n// test.base64.txt\nvar require_test_base64 = __commonJS({\n  \"test.base64.txt\"(exports, module) {\n    module.exports = \"dGVzdC5iYXNlNjQudHh0\";\n  }\n});\n\n// entry.js\nconsole.log(require_test(), require_test_base64());\n\n================================================================================\nTestRequireCustomExtensionString\n---------- /out.js ----------\n// test.custom\nvar require_test = __commonJS({\n  \"test.custom\"(exports, module) {\n    module.exports = \"#include <stdio.h>\";\n  }\n});\n\n// entry.js\nconsole.log(require_test());\n\n================================================================================\nTestWithTypeBytesOverrideLoader\n---------- /out.js ----------\n// foo.js\nvar foo_default = Uint8Array.fromBase64(\"ZXhwb3J0IGRlZmF1bHQgJ2pzJw==\");\n\n// entry.js\nconsole.log(foo_default);\n\n================================================================================\nTestWithTypeBytesOverrideLoaderGlob\n---------- /out.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports, module) {\n    module.exports = Uint8Array.fromBase64(\"ZXhwb3J0IGRlZmF1bHQgJ2pzJw==\");\n  }\n});\n\n// import(\"./foo*\") in entry.js\nvar globImport_foo = __glob({\n  \"./foo.js\": () => Promise.resolve().then(() => __toESM(require_foo()))\n});\n\n// entry.js\nglobImport_foo(\"./foo\" + bar).then(console.log);\n\n================================================================================\nTestWithTypeJSONOverrideLoader\n---------- /out.js ----------\n// foo.js\nvar foo_default = { \"this is json not js\": true };\n\n// entry.js\nconsole.log(foo_default);\n\n================================================================================\nTestWithTypeJSONOverrideLoaderGlob\n---------- /out.js ----------\n// foo.js\nvar foo_exports = {};\n__export(foo_exports, {\n  default: () => foo_default\n});\nvar foo_default;\nvar init_foo = __esm({\n  \"foo.js\"() {\n    foo_default = { \"this is json not js\": true };\n  }\n});\n\n// import(\"./foo*\") in entry.js\nvar globImport_foo = __glob({\n  \"./foo.js\": () => Promise.resolve().then(() => (init_foo(), foo_exports))\n});\n\n// entry.js\nglobImport_foo(\"./foo\" + bar).then(console.log);\n"
  },
  {
    "path": "internal/bundler_tests/snapshots/snapshots_lower.txt",
    "content": "TestClassSuperThisIssue242NoBundle\n---------- /out.js ----------\nvar _e;\nexport class A {\n}\nexport class B extends A {\n  constructor(c) {\n    var _a;\n    super();\n    __privateAdd(this, _e);\n    __privateSet(this, _e, (_a = c.d) != null ? _a : \"test\");\n  }\n  f() {\n    return __privateGet(this, _e);\n  }\n}\n_e = new WeakMap();\n\n================================================================================\nTestForAwaitWithOptionalCatchIssue4378\n---------- /out.js ----------\nasync function test(b) {\n  try {\n    for (var iter = __forAwait(b), more, temp, error; more = !(temp = await iter.next()).done; more = !1) {\n      const a = temp.value;\n      a();\n    }\n  } catch (temp) {\n    error = [temp];\n  } finally {\n    try {\n      more && (temp = iter.return) && await temp.call(iter);\n    } finally {\n      if (error)\n        throw error[0];\n    }\n  }\n}\n\n================================================================================\nTestJavaScriptAutoAccessorES2021\n---------- /out/js-define.js ----------\nvar _a, _b, _one, __two, _Foo_instances, two_get, two_set, _a2, _four, __five, _Foo_static, five_get, five_set, _b2;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _Foo_instances);\n    __privateAdd(this, _one, 1);\n    __privateAdd(this, __two, 2);\n    __privateAdd(this, _a2, 3);\n  }\n  get one() {\n    return __privateGet(this, _one);\n  }\n  set one(_) {\n    __privateSet(this, _one, _);\n  }\n  get [_b = three()]() {\n    return __privateGet(this, _a2);\n  }\n  set [_b](_) {\n    __privateSet(this, _a2, _);\n  }\n  static get four() {\n    return __privateGet(this, _four);\n  }\n  static set four(_) {\n    __privateSet(this, _four, _);\n  }\n  static get [_a = six()]() {\n    return __privateGet(this, _b2);\n  }\n  static set [_a](_) {\n    __privateSet(this, _b2, _);\n  }\n}\n_one = new WeakMap();\n__two = new WeakMap();\n_Foo_instances = new WeakSet();\ntwo_get = function() {\n  return __privateGet(this, __two);\n};\ntwo_set = function(_) {\n  __privateSet(this, __two, _);\n};\n_a2 = new WeakMap();\n_four = new WeakMap();\n__five = new WeakMap();\n_Foo_static = new WeakSet();\nfive_get = function() {\n  return __privateGet(this, __five);\n};\nfive_set = function(_) {\n  __privateSet(this, __five, _);\n};\n_b2 = new WeakMap();\n__privateAdd(Foo, _Foo_static);\n__privateAdd(Foo, _four, 4);\n__privateAdd(Foo, __five, 5);\n__privateAdd(Foo, _b2, 6);\n\n---------- /out/ts-define/ts-define.js ----------\nvar _a, _b, _one, __two, _Foo_instances, two_get, two_set, _a2, _four, __five, _Foo_static, five_get, five_set, _b2, _a3, __a, _Private_instances, a_get, a_set, _a4, __a2, _StaticPrivate_static, a_get2, a_set2;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _Foo_instances);\n    __privateAdd(this, _one, 1);\n    __privateAdd(this, __two, 2);\n    __privateAdd(this, _a2, 3);\n  }\n  get one() {\n    return __privateGet(this, _one);\n  }\n  set one(_) {\n    __privateSet(this, _one, _);\n  }\n  get [_b = three()]() {\n    return __privateGet(this, _a2);\n  }\n  set [_b](_) {\n    __privateSet(this, _a2, _);\n  }\n  static get four() {\n    return __privateGet(this, _four);\n  }\n  static set four(_) {\n    __privateSet(this, _four, _);\n  }\n  static get [_a = six()]() {\n    return __privateGet(this, _b2);\n  }\n  static set [_a](_) {\n    __privateSet(this, _b2, _);\n  }\n}\n_one = new WeakMap();\n__two = new WeakMap();\n_Foo_instances = new WeakSet();\ntwo_get = function() {\n  return __privateGet(this, __two);\n};\ntwo_set = function(_) {\n  __privateSet(this, __two, _);\n};\n_a2 = new WeakMap();\n_four = new WeakMap();\n__five = new WeakMap();\n_Foo_static = new WeakSet();\nfive_get = function() {\n  return __privateGet(this, __five);\n};\nfive_set = function(_) {\n  __privateSet(this, __five, _);\n};\n_b2 = new WeakMap();\n__privateAdd(Foo, _Foo_static);\n__privateAdd(Foo, _four, 4);\n__privateAdd(Foo, __five, 5);\n__privateAdd(Foo, _b2, 6);\nclass Normal {\n  constructor() {\n    __privateAdd(this, _a3, b);\n    __publicField(this, \"c\", d);\n  }\n  get a() {\n    return __privateGet(this, _a3);\n  }\n  set a(_) {\n    __privateSet(this, _a3, _);\n  }\n}\n_a3 = new WeakMap();\nclass Private {\n  constructor() {\n    __privateAdd(this, _Private_instances);\n    __privateAdd(this, __a, b);\n    __publicField(this, \"c\", d);\n  }\n}\n__a = new WeakMap();\n_Private_instances = new WeakSet();\na_get = function() {\n  return __privateGet(this, __a);\n};\na_set = function(_) {\n  __privateSet(this, __a, _);\n};\nclass StaticNormal {\n  static get a() {\n    return __privateGet(this, _a4);\n  }\n  static set a(_) {\n    __privateSet(this, _a4, _);\n  }\n}\n_a4 = new WeakMap();\n__privateAdd(StaticNormal, _a4, b);\n__publicField(StaticNormal, \"c\", d);\nclass StaticPrivate {\n}\n__a2 = new WeakMap();\n_StaticPrivate_static = new WeakSet();\na_get2 = function() {\n  return __privateGet(this, __a2);\n};\na_set2 = function(_) {\n  __privateSet(this, __a2, _);\n};\n__privateAdd(StaticPrivate, _StaticPrivate_static);\n__privateAdd(StaticPrivate, __a2, b);\n__publicField(StaticPrivate, \"c\", d);\n\n---------- /out/ts-assign/ts-assign.js ----------\nvar _a, _b, _one, __two, _Foo_instances, two_get, two_set, _a2, _four, __five, _Foo_static, five_get, five_set, _b2, _a3, __a, _Private_instances, a_get, a_set, _a4, __a2, _StaticPrivate_static, a_get2, a_set2;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _Foo_instances);\n    __privateAdd(this, _one, 1);\n    __privateAdd(this, __two, 2);\n    __privateAdd(this, _a2, 3);\n  }\n  get one() {\n    return __privateGet(this, _one);\n  }\n  set one(_) {\n    __privateSet(this, _one, _);\n  }\n  get [_b = three()]() {\n    return __privateGet(this, _a2);\n  }\n  set [_b](_) {\n    __privateSet(this, _a2, _);\n  }\n  static get four() {\n    return __privateGet(this, _four);\n  }\n  static set four(_) {\n    __privateSet(this, _four, _);\n  }\n  static get [_a = six()]() {\n    return __privateGet(this, _b2);\n  }\n  static set [_a](_) {\n    __privateSet(this, _b2, _);\n  }\n}\n_one = new WeakMap();\n__two = new WeakMap();\n_Foo_instances = new WeakSet();\ntwo_get = function() {\n  return __privateGet(this, __two);\n};\ntwo_set = function(_) {\n  __privateSet(this, __two, _);\n};\n_a2 = new WeakMap();\n_four = new WeakMap();\n__five = new WeakMap();\n_Foo_static = new WeakSet();\nfive_get = function() {\n  return __privateGet(this, __five);\n};\nfive_set = function(_) {\n  __privateSet(this, __five, _);\n};\n_b2 = new WeakMap();\n__privateAdd(Foo, _Foo_static);\n__privateAdd(Foo, _four, 4);\n__privateAdd(Foo, __five, 5);\n__privateAdd(Foo, _b2, 6);\nclass Normal {\n  constructor() {\n    __privateAdd(this, _a3, b);\n    this.c = d;\n  }\n  get a() {\n    return __privateGet(this, _a3);\n  }\n  set a(_) {\n    __privateSet(this, _a3, _);\n  }\n}\n_a3 = new WeakMap();\nclass Private {\n  constructor() {\n    __privateAdd(this, _Private_instances);\n    __privateAdd(this, __a, b);\n    this.c = d;\n  }\n}\n__a = new WeakMap();\n_Private_instances = new WeakSet();\na_get = function() {\n  return __privateGet(this, __a);\n};\na_set = function(_) {\n  __privateSet(this, __a, _);\n};\nclass StaticNormal {\n  static get a() {\n    return __privateGet(this, _a4);\n  }\n  static set a(_) {\n    __privateSet(this, _a4, _);\n  }\n}\n_a4 = new WeakMap();\n__privateAdd(StaticNormal, _a4, b);\nStaticNormal.c = d;\nclass StaticPrivate {\n}\n__a2 = new WeakMap();\n_StaticPrivate_static = new WeakSet();\na_get2 = function() {\n  return __privateGet(this, __a2);\n};\na_set2 = function(_) {\n  __privateSet(this, __a2, _);\n};\n__privateAdd(StaticPrivate, _StaticPrivate_static);\n__privateAdd(StaticPrivate, __a2, b);\nStaticPrivate.c = d;\n\n================================================================================\nTestJavaScriptAutoAccessorES2022\n---------- /out/js-define.js ----------\nvar _a, _b;\nclass Foo {\n  #one = 1;\n  get one() {\n    return this.#one;\n  }\n  set one(_) {\n    this.#one = _;\n  }\n  #_two = 2;\n  get #two() {\n    return this.#_two;\n  }\n  set #two(_) {\n    this.#_two = _;\n  }\n  #a = 3;\n  get [_b = three()]() {\n    return this.#a;\n  }\n  set [_b](_) {\n    this.#a = _;\n  }\n  static #four = 4;\n  static get four() {\n    return this.#four;\n  }\n  static set four(_) {\n    this.#four = _;\n  }\n  static #_five = 5;\n  static get #five() {\n    return this.#_five;\n  }\n  static set #five(_) {\n    this.#_five = _;\n  }\n  static #b = 6;\n  static get [_a = six()]() {\n    return this.#b;\n  }\n  static set [_a](_) {\n    this.#b = _;\n  }\n}\n\n---------- /out/ts-define/ts-define.js ----------\nvar _a, _b;\nclass Foo {\n  #one = 1;\n  get one() {\n    return this.#one;\n  }\n  set one(_) {\n    this.#one = _;\n  }\n  #_two = 2;\n  get #two() {\n    return this.#_two;\n  }\n  set #two(_) {\n    this.#_two = _;\n  }\n  #a = 3;\n  get [_b = three()]() {\n    return this.#a;\n  }\n  set [_b](_) {\n    this.#a = _;\n  }\n  static #four = 4;\n  static get four() {\n    return this.#four;\n  }\n  static set four(_) {\n    this.#four = _;\n  }\n  static #_five = 5;\n  static get #five() {\n    return this.#_five;\n  }\n  static set #five(_) {\n    this.#_five = _;\n  }\n  static #b = 6;\n  static get [_a = six()]() {\n    return this.#b;\n  }\n  static set [_a](_) {\n    this.#b = _;\n  }\n}\nclass Normal {\n  #a = b;\n  get a() {\n    return this.#a;\n  }\n  set a(_) {\n    this.#a = _;\n  }\n  c = d;\n}\nclass Private {\n  #_a = b;\n  get #a() {\n    return this.#_a;\n  }\n  set #a(_) {\n    this.#_a = _;\n  }\n  c = d;\n}\nclass StaticNormal {\n  static #a = b;\n  static get a() {\n    return this.#a;\n  }\n  static set a(_) {\n    this.#a = _;\n  }\n  static c = d;\n}\nclass StaticPrivate {\n  static #_a = b;\n  static get #a() {\n    return this.#_a;\n  }\n  static set #a(_) {\n    this.#_a = _;\n  }\n  static c = d;\n}\n\n---------- /out/ts-assign/ts-assign.js ----------\nvar _a, _b, _a2, __a;\nclass Foo {\n  #one = 1;\n  get one() {\n    return this.#one;\n  }\n  set one(_) {\n    this.#one = _;\n  }\n  #_two = 2;\n  get #two() {\n    return this.#_two;\n  }\n  set #two(_) {\n    this.#_two = _;\n  }\n  #a = 3;\n  get [_b = three()]() {\n    return this.#a;\n  }\n  set [_b](_) {\n    this.#a = _;\n  }\n  static #four = 4;\n  static get four() {\n    return this.#four;\n  }\n  static set four(_) {\n    this.#four = _;\n  }\n  static #_five = 5;\n  static get #five() {\n    return this.#_five;\n  }\n  static set #five(_) {\n    this.#_five = _;\n  }\n  static #b = 6;\n  static get [_a = six()]() {\n    return this.#b;\n  }\n  static set [_a](_) {\n    this.#b = _;\n  }\n}\nclass Normal {\n  constructor() {\n    __privateAdd(this, _a2, b);\n    this.c = d;\n  }\n  get a() {\n    return __privateGet(this, _a2);\n  }\n  set a(_) {\n    __privateSet(this, _a2, _);\n  }\n}\n_a2 = new WeakMap();\nclass Private {\n  constructor() {\n    __privateAdd(this, __a, b);\n    this.c = d;\n  }\n  get #a() {\n    return __privateGet(this, __a);\n  }\n  set #a(_) {\n    __privateSet(this, __a, _);\n  }\n}\n__a = new WeakMap();\nclass StaticNormal {\n  static #a = b;\n  static get a() {\n    return this.#a;\n  }\n  static set a(_) {\n    this.#a = _;\n  }\n  static {\n    this.c = d;\n  }\n}\nclass StaticPrivate {\n  static #_a = b;\n  static get #a() {\n    return this.#_a;\n  }\n  static set #a(_) {\n    this.#_a = _;\n  }\n  static {\n    this.c = d;\n  }\n}\n\n================================================================================\nTestJavaScriptAutoAccessorESNext\n---------- /out/js-define.js ----------\nclass Foo {\n  accessor one = 1;\n  accessor #two = 2;\n  accessor [three()] = 3;\n  static accessor four = 4;\n  static accessor #five = 5;\n  static accessor [six()] = 6;\n}\n\n---------- /out/ts-define/ts-define.js ----------\nclass Foo {\n  accessor one = 1;\n  accessor #two = 2;\n  accessor [three()] = 3;\n  static accessor four = 4;\n  static accessor #five = 5;\n  static accessor [six()] = 6;\n}\nclass Normal {\n  accessor a = b;\n  c = d;\n}\nclass Private {\n  accessor #a = b;\n  c = d;\n}\nclass StaticNormal {\n  static accessor a = b;\n  static c = d;\n}\nclass StaticPrivate {\n  static accessor #a = b;\n  static c = d;\n}\n\n---------- /out/ts-assign/ts-assign.js ----------\nvar _a, __a;\nclass Foo {\n  accessor one = 1;\n  accessor #two = 2;\n  accessor [three()] = 3;\n  static accessor four = 4;\n  static accessor #five = 5;\n  static accessor [six()] = 6;\n}\nclass Normal {\n  constructor() {\n    __privateAdd(this, _a, b);\n    this.c = d;\n  }\n  get a() {\n    return __privateGet(this, _a);\n  }\n  set a(_) {\n    __privateSet(this, _a, _);\n  }\n}\n_a = new WeakMap();\nclass Private {\n  constructor() {\n    __privateAdd(this, __a, b);\n    this.c = d;\n  }\n  get #a() {\n    return __privateGet(this, __a);\n  }\n  set #a(_) {\n    __privateSet(this, __a, _);\n  }\n}\n__a = new WeakMap();\nclass StaticNormal {\n  static accessor a = b;\n  static {\n    this.c = d;\n  }\n}\nclass StaticPrivate {\n  static accessor #a = b;\n  static {\n    this.c = d;\n  }\n}\n\n================================================================================\nTestJavaScriptDecoratorsBundleIssue3768\n---------- /out/base-instance-accessor.js ----------\n// base-instance-accessor.js\nvar _foo_dec, _init, _foo;\n_foo_dec = [dec];\nvar _Foo = class _Foo {\n  constructor() {\n    __privateAdd(this, _foo, __runInitializers(_init, 8, this, _Foo)), __runInitializers(_init, 11, this);\n  }\n};\n_init = __decoratorStart(null);\n_foo = new WeakMap();\n__decorateElement(_init, 4, \"foo\", _foo_dec, _Foo, _foo);\n__decoratorMetadata(_init, _Foo);\nvar Foo = _Foo;\n\n---------- /out/base-instance-field.js ----------\n// base-instance-field.js\nvar _foo_dec, _init;\n_foo_dec = [dec];\nvar _Foo = class _Foo {\n  constructor() {\n    __publicField(this, \"foo\", __runInitializers(_init, 8, this, _Foo)), __runInitializers(_init, 11, this);\n  }\n};\n_init = __decoratorStart(null);\n__decorateElement(_init, 5, \"foo\", _foo_dec, _Foo);\n__decoratorMetadata(_init, _Foo);\nvar Foo = _Foo;\n\n---------- /out/base-instance-method.js ----------\n// base-instance-method.js\nvar _foo_dec, _init;\n_foo_dec = [dec];\nvar _Foo = class _Foo {\n  constructor() {\n    __runInitializers(_init, 5, this);\n  }\n  foo() {\n    return _Foo;\n  }\n};\n_init = __decoratorStart(null);\n__decorateElement(_init, 1, \"foo\", _foo_dec, _Foo);\n__decoratorMetadata(_init, _Foo);\nvar Foo = _Foo;\n\n---------- /out/base-static-accessor.js ----------\n// base-static-accessor.js\nvar _foo_dec, _init, _foo;\n_foo_dec = [dec];\nvar _Foo = class _Foo {\n};\n_init = __decoratorStart(null);\n_foo = new WeakMap();\n__decorateElement(_init, 12, \"foo\", _foo_dec, _Foo, _foo);\n__decoratorMetadata(_init, _Foo);\n__privateAdd(_Foo, _foo, __runInitializers(_init, 8, _Foo, _Foo)), __runInitializers(_init, 11, _Foo);\nvar Foo = _Foo;\n\n---------- /out/base-static-field.js ----------\n// base-static-field.js\nvar _foo_dec, _init;\n_foo_dec = [dec];\nvar _Foo = class _Foo {\n};\n_init = __decoratorStart(null);\n__decorateElement(_init, 13, \"foo\", _foo_dec, _Foo);\n__decoratorMetadata(_init, _Foo);\n__publicField(_Foo, \"foo\", __runInitializers(_init, 8, _Foo, _Foo)), __runInitializers(_init, 11, _Foo);\nvar Foo = _Foo;\n\n---------- /out/base-static-method.js ----------\n// base-static-method.js\nvar _foo_dec, _init;\n_foo_dec = [dec];\nvar _Foo = class _Foo {\n  static foo() {\n    return _Foo;\n  }\n};\n_init = __decoratorStart(null);\n__decorateElement(_init, 9, \"foo\", _foo_dec, _Foo);\n__decoratorMetadata(_init, _Foo);\n__runInitializers(_init, 3, _Foo);\nvar Foo = _Foo;\n\n---------- /out/derived-instance-accessor.js ----------\n// derived-instance-accessor.js\nvar _foo_dec, _a, _init, _foo;\nvar _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) {\n  constructor() {\n    super(...arguments);\n    __privateAdd(this, _foo, __runInitializers(_init, 8, this, _Foo)), __runInitializers(_init, 11, this);\n  }\n};\n_init = __decoratorStart(_a);\n_foo = new WeakMap();\n__decorateElement(_init, 4, \"foo\", _foo_dec, _Foo, _foo);\n__decoratorMetadata(_init, _Foo);\nvar Foo = _Foo;\n\n---------- /out/derived-instance-field.js ----------\n// derived-instance-field.js\nvar _foo_dec, _a, _init;\nvar _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"foo\", __runInitializers(_init, 8, this, _Foo)), __runInitializers(_init, 11, this);\n  }\n};\n_init = __decoratorStart(_a);\n__decorateElement(_init, 5, \"foo\", _foo_dec, _Foo);\n__decoratorMetadata(_init, _Foo);\nvar Foo = _Foo;\n\n---------- /out/derived-instance-method.js ----------\n// derived-instance-method.js\nvar _foo_dec, _a, _init;\nvar _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) {\n  constructor() {\n    super(...arguments);\n    __runInitializers(_init, 5, this);\n  }\n  foo() {\n    return _Foo;\n  }\n};\n_init = __decoratorStart(_a);\n__decorateElement(_init, 1, \"foo\", _foo_dec, _Foo);\n__decoratorMetadata(_init, _Foo);\nvar Foo = _Foo;\n\n---------- /out/derived-static-accessor.js ----------\n// derived-static-accessor.js\nvar _foo_dec, _a, _init, _foo;\nvar _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) {\n};\n_init = __decoratorStart(_a);\n_foo = new WeakMap();\n__decorateElement(_init, 12, \"foo\", _foo_dec, _Foo, _foo);\n__decoratorMetadata(_init, _Foo);\n__privateAdd(_Foo, _foo, __runInitializers(_init, 8, _Foo, _Foo)), __runInitializers(_init, 11, _Foo);\nvar Foo = _Foo;\n\n---------- /out/derived-static-field.js ----------\n// derived-static-field.js\nvar _foo_dec, _a, _init;\nvar _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) {\n};\n_init = __decoratorStart(_a);\n__decorateElement(_init, 13, \"foo\", _foo_dec, _Foo);\n__decoratorMetadata(_init, _Foo);\n__publicField(_Foo, \"foo\", __runInitializers(_init, 8, _Foo, _Foo)), __runInitializers(_init, 11, _Foo);\nvar Foo = _Foo;\n\n---------- /out/derived-static-method.js ----------\n// derived-static-method.js\nvar _foo_dec, _a, _init;\nvar _Foo = class _Foo extends (_a = Bar, _foo_dec = [dec], _a) {\n  static foo() {\n    return _Foo;\n  }\n};\n_init = __decoratorStart(_a);\n__decorateElement(_init, 9, \"foo\", _foo_dec, _Foo);\n__decoratorMetadata(_init, _Foo);\n__runInitializers(_init, 3, _Foo);\nvar Foo = _Foo;\n\n================================================================================\nTestJavaScriptDecoratorsESNext\n---------- /out.js ----------\n@x.y()\n@(new y.x())\nexport default class Foo {\n  @x @y mUndef;\n  @x @y mDef = 1;\n  @x @y method() {\n    return new Foo();\n  }\n  @x @y static sUndef;\n  @x @y static sDef = new Foo();\n  @x @y static sMethod() {\n    return new Foo();\n  }\n}\n\n================================================================================\nTestLowerAsync2016NoBundle\n---------- /out.js ----------\nfunction foo(_0) {\n  return __async(this, arguments, function* (bar) {\n    yield bar;\n    return [this, arguments];\n  });\n}\nclass Foo {\n  foo() {\n    return __async(this, null, function* () {\n    });\n  }\n}\nnew class Bar extends class {\n} {\n  constructor() {\n    let x = 1;\n    (() => __async(null, null, function* () {\n      console.log(\"before super\", x);\n      yield 1;\n      console.log(\"after super\", x);\n    }))();\n    super();\n    x = 2;\n  }\n}();\nexport default [\n  foo,\n  Foo,\n  function() {\n    return __async(this, null, function* () {\n    });\n  },\n  () => __async(null, null, function* () {\n  }),\n  { foo() {\n    return __async(this, null, function* () {\n    });\n  } },\n  class {\n    foo() {\n      return __async(this, null, function* () {\n      });\n    }\n  },\n  function() {\n    var _arguments = arguments;\n    return (bar) => __async(this, null, function* () {\n      yield bar;\n      return [this, _arguments];\n    });\n  }\n];\n\n================================================================================\nTestLowerAsync2017NoBundle\n---------- /out.js ----------\nasync function foo(bar) {\n  await bar;\n  return arguments;\n}\nclass Foo {\n  async foo() {\n  }\n}\nexport default [\n  foo,\n  Foo,\n  async function() {\n  },\n  async () => {\n  },\n  { async foo() {\n  } },\n  class {\n    async foo() {\n    }\n  },\n  function() {\n    return async (bar) => {\n      await bar;\n      return [this, arguments];\n    };\n  }\n];\n\n================================================================================\nTestLowerAsyncArrowSuperES2016\n---------- /out.js ----------\n// foo1.js\nvar foo1_default = class _foo1_default extends x {\n  foo1() {\n    return () => __async(null, null, function* () {\n      return __superGet(_foo1_default.prototype, this, \"foo\").call(this, \"foo1\");\n    });\n  }\n};\n\n// foo2.js\nvar foo2_default = class _foo2_default extends x {\n  foo2() {\n    return () => __async(null, null, function* () {\n      return () => __superGet(_foo2_default.prototype, this, \"foo\").call(this, \"foo2\");\n    });\n  }\n};\n\n// foo3.js\nvar foo3_default = class _foo3_default extends x {\n  foo3() {\n    return () => () => __async(null, null, function* () {\n      return __superGet(_foo3_default.prototype, this, \"foo\").call(this, \"foo3\");\n    });\n  }\n};\n\n// foo4.js\nvar foo4_default = class _foo4_default extends x {\n  foo4() {\n    return () => __async(null, null, function* () {\n      return () => __async(null, null, function* () {\n        return __superGet(_foo4_default.prototype, this, \"foo\").call(this, \"foo4\");\n      });\n    });\n  }\n};\n\n// bar1.js\nvar bar1_default = class _bar1_default extends x {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"bar1\", () => __async(null, null, function* () {\n      return __superGet(_bar1_default.prototype, this, \"foo\").call(this, \"bar1\");\n    }));\n  }\n};\n\n// bar2.js\nvar bar2_default = class _bar2_default extends x {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"bar2\", () => __async(null, null, function* () {\n      return () => __superGet(_bar2_default.prototype, this, \"foo\").call(this, \"bar2\");\n    }));\n  }\n};\n\n// bar3.js\nvar bar3_default = class _bar3_default extends x {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"bar3\", () => () => __async(null, null, function* () {\n      return __superGet(_bar3_default.prototype, this, \"foo\").call(this, \"bar3\");\n    }));\n  }\n};\n\n// bar4.js\nvar bar4_default = class _bar4_default extends x {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"bar4\", () => __async(null, null, function* () {\n      return () => __async(null, null, function* () {\n        return __superGet(_bar4_default.prototype, this, \"foo\").call(this, \"bar4\");\n      });\n    }));\n  }\n};\n\n// baz1.js\nvar baz1_default = class _baz1_default extends x {\n  baz1() {\n    return __async(this, null, function* () {\n      return () => __superGet(_baz1_default.prototype, this, \"foo\").call(this, \"baz1\");\n    });\n  }\n};\n\n// baz2.js\nvar baz2_default = class _baz2_default extends x {\n  baz2() {\n    return __async(this, null, function* () {\n      return () => () => __superGet(_baz2_default.prototype, this, \"foo\").call(this, \"baz2\");\n    });\n  }\n};\n\n// outer.js\nvar outer_default = (function() {\n  return __async(this, null, function* () {\n    class y extends z {\n      constructor() {\n        super(...arguments);\n        __publicField(this, \"foo\", () => __async(null, null, function* () {\n          return __superGet(y.prototype, this, \"foo\").call(this);\n        }));\n      }\n    }\n    yield new y().foo()();\n  });\n})();\nexport {\n  bar1_default as bar1,\n  bar2_default as bar2,\n  bar3_default as bar3,\n  bar4_default as bar4,\n  baz1_default as baz1,\n  baz2_default as baz2,\n  foo1_default as foo1,\n  foo2_default as foo2,\n  foo3_default as foo3,\n  foo4_default as foo4\n};\n\n================================================================================\nTestLowerAsyncArrowSuperSetterES2016\n---------- /out.js ----------\n// foo1.js\nvar foo1_default = class _foo1_default extends x {\n  foo1() {\n    return () => __async(null, null, function* () {\n      return __superSet(_foo1_default.prototype, this, \"foo\", \"foo1\");\n    });\n  }\n};\n\n// foo2.js\nvar foo2_default = class _foo2_default extends x {\n  foo2() {\n    return () => __async(null, null, function* () {\n      return () => __superSet(_foo2_default.prototype, this, \"foo\", \"foo2\");\n    });\n  }\n};\n\n// foo3.js\nvar foo3_default = class _foo3_default extends x {\n  foo3() {\n    return () => () => __async(null, null, function* () {\n      return __superSet(_foo3_default.prototype, this, \"foo\", \"foo3\");\n    });\n  }\n};\n\n// foo4.js\nvar foo4_default = class _foo4_default extends x {\n  foo4() {\n    return () => __async(null, null, function* () {\n      return () => __async(null, null, function* () {\n        return __superSet(_foo4_default.prototype, this, \"foo\", \"foo4\");\n      });\n    });\n  }\n};\n\n// bar1.js\nvar bar1_default = class _bar1_default extends x {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"bar1\", () => __async(null, null, function* () {\n      return __superSet(_bar1_default.prototype, this, \"foo\", \"bar1\");\n    }));\n  }\n};\n\n// bar2.js\nvar bar2_default = class _bar2_default extends x {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"bar2\", () => __async(null, null, function* () {\n      return () => __superSet(_bar2_default.prototype, this, \"foo\", \"bar2\");\n    }));\n  }\n};\n\n// bar3.js\nvar bar3_default = class _bar3_default extends x {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"bar3\", () => () => __async(null, null, function* () {\n      return __superSet(_bar3_default.prototype, this, \"foo\", \"bar3\");\n    }));\n  }\n};\n\n// bar4.js\nvar bar4_default = class _bar4_default extends x {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"bar4\", () => __async(null, null, function* () {\n      return () => __async(null, null, function* () {\n        return __superSet(_bar4_default.prototype, this, \"foo\", \"bar4\");\n      });\n    }));\n  }\n};\n\n// baz1.js\nvar baz1_default = class _baz1_default extends x {\n  baz1() {\n    return __async(this, null, function* () {\n      return () => __superSet(_baz1_default.prototype, this, \"foo\", \"baz1\");\n    });\n  }\n};\n\n// baz2.js\nvar baz2_default = class _baz2_default extends x {\n  baz2() {\n    return __async(this, null, function* () {\n      return () => () => __superSet(_baz2_default.prototype, this, \"foo\", \"baz2\");\n    });\n  }\n};\n\n// outer.js\nvar outer_default = (function() {\n  return __async(this, null, function* () {\n    class y extends z {\n      constructor() {\n        super(...arguments);\n        __publicField(this, \"foo\", () => __async(null, null, function* () {\n          return __superSet(y.prototype, this, \"foo\", \"foo\");\n        }));\n      }\n    }\n    yield new y().foo()();\n  });\n})();\nexport {\n  bar1_default as bar1,\n  bar2_default as bar2,\n  bar3_default as bar3,\n  bar4_default as bar4,\n  baz1_default as baz1,\n  baz2_default as baz2,\n  foo1_default as foo1,\n  foo2_default as foo2,\n  foo3_default as foo3,\n  foo4_default as foo4\n};\n\n================================================================================\nTestLowerAsyncGenerator\n---------- /out/entry.js ----------\nfunction foo() {\n  return __asyncGenerator(this, null, function* () {\n    var _stack2 = [];\n    try {\n      yield;\n      yield x;\n      yield* __yieldStar(x);\n      const x = __using(_stack2, yield new __await(y), true);\n      try {\n        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {\n          let x2 = temp.value;\n        }\n      } catch (temp) {\n        error = [temp];\n      } finally {\n        try {\n          more && (temp = iter.return) && (yield new __await(temp.call(iter)));\n        } finally {\n          if (error)\n            throw error[0];\n        }\n      }\n      try {\n        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {\n          var _x = temp2.value;\n          var _stack = [];\n          try {\n            const x2 = __using(_stack, _x, true);\n          } catch (_) {\n            var _error = _, _hasError = true;\n          } finally {\n            var _promise = __callDispose(_stack, _error, _hasError);\n            _promise && (yield new __await(_promise));\n          }\n        }\n      } catch (temp2) {\n        error2 = [temp2];\n      } finally {\n        try {\n          more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));\n        } finally {\n          if (error2)\n            throw error2[0];\n        }\n      }\n    } catch (_2) {\n      var _error2 = _2, _hasError2 = true;\n    } finally {\n      var _promise2 = __callDispose(_stack2, _error2, _hasError2);\n      _promise2 && (yield new __await(_promise2));\n    }\n  });\n}\nfoo = function() {\n  return __asyncGenerator(this, null, function* () {\n    var _stack2 = [];\n    try {\n      yield;\n      yield x;\n      yield* __yieldStar(x);\n      const x = __using(_stack2, yield new __await(y), true);\n      try {\n        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {\n          let x2 = temp.value;\n        }\n      } catch (temp) {\n        error = [temp];\n      } finally {\n        try {\n          more && (temp = iter.return) && (yield new __await(temp.call(iter)));\n        } finally {\n          if (error)\n            throw error[0];\n        }\n      }\n      try {\n        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {\n          var _x = temp2.value;\n          var _stack = [];\n          try {\n            const x2 = __using(_stack, _x, true);\n          } catch (_) {\n            var _error = _, _hasError = true;\n          } finally {\n            var _promise = __callDispose(_stack, _error, _hasError);\n            _promise && (yield new __await(_promise));\n          }\n        }\n      } catch (temp2) {\n        error2 = [temp2];\n      } finally {\n        try {\n          more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));\n        } finally {\n          if (error2)\n            throw error2[0];\n        }\n      }\n    } catch (_2) {\n      var _error2 = _2, _hasError2 = true;\n    } finally {\n      var _promise2 = __callDispose(_stack2, _error2, _hasError2);\n      _promise2 && (yield new __await(_promise2));\n    }\n  });\n};\nfoo = { bar() {\n  return __asyncGenerator(this, null, function* () {\n    var _stack2 = [];\n    try {\n      yield;\n      yield x;\n      yield* __yieldStar(x);\n      const x = __using(_stack2, yield new __await(y), true);\n      try {\n        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {\n          let x2 = temp.value;\n        }\n      } catch (temp) {\n        error = [temp];\n      } finally {\n        try {\n          more && (temp = iter.return) && (yield new __await(temp.call(iter)));\n        } finally {\n          if (error)\n            throw error[0];\n        }\n      }\n      try {\n        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {\n          var _x = temp2.value;\n          var _stack = [];\n          try {\n            const x2 = __using(_stack, _x, true);\n          } catch (_) {\n            var _error = _, _hasError = true;\n          } finally {\n            var _promise = __callDispose(_stack, _error, _hasError);\n            _promise && (yield new __await(_promise));\n          }\n        }\n      } catch (temp2) {\n        error2 = [temp2];\n      } finally {\n        try {\n          more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));\n        } finally {\n          if (error2)\n            throw error2[0];\n        }\n      }\n    } catch (_2) {\n      var _error2 = _2, _hasError2 = true;\n    } finally {\n      var _promise2 = __callDispose(_stack2, _error2, _hasError2);\n      _promise2 && (yield new __await(_promise2));\n    }\n  });\n} };\nclass Foo {\n  bar() {\n    return __asyncGenerator(this, null, function* () {\n      var _stack2 = [];\n      try {\n        yield;\n        yield x;\n        yield* __yieldStar(x);\n        const x = __using(_stack2, yield new __await(y), true);\n        try {\n          for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {\n            let x2 = temp.value;\n          }\n        } catch (temp) {\n          error = [temp];\n        } finally {\n          try {\n            more && (temp = iter.return) && (yield new __await(temp.call(iter)));\n          } finally {\n            if (error)\n              throw error[0];\n          }\n        }\n        try {\n          for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {\n            var _x = temp2.value;\n            var _stack = [];\n            try {\n              const x2 = __using(_stack, _x, true);\n            } catch (_) {\n              var _error = _, _hasError = true;\n            } finally {\n              var _promise = __callDispose(_stack, _error, _hasError);\n              _promise && (yield new __await(_promise));\n            }\n          }\n        } catch (temp2) {\n          error2 = [temp2];\n        } finally {\n          try {\n            more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));\n          } finally {\n            if (error2)\n              throw error2[0];\n          }\n        }\n      } catch (_2) {\n        var _error2 = _2, _hasError2 = true;\n      } finally {\n        var _promise2 = __callDispose(_stack2, _error2, _hasError2);\n        _promise2 && (yield new __await(_promise2));\n      }\n    });\n  }\n}\nFoo = class {\n  bar() {\n    return __asyncGenerator(this, null, function* () {\n      var _stack2 = [];\n      try {\n        yield;\n        yield x;\n        yield* __yieldStar(x);\n        const x = __using(_stack2, yield new __await(y), true);\n        try {\n          for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {\n            let x2 = temp.value;\n          }\n        } catch (temp) {\n          error = [temp];\n        } finally {\n          try {\n            more && (temp = iter.return) && (yield new __await(temp.call(iter)));\n          } finally {\n            if (error)\n              throw error[0];\n          }\n        }\n        try {\n          for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {\n            var _x = temp2.value;\n            var _stack = [];\n            try {\n              const x2 = __using(_stack, _x, true);\n            } catch (_) {\n              var _error = _, _hasError = true;\n            } finally {\n              var _promise = __callDispose(_stack, _error, _hasError);\n              _promise && (yield new __await(_promise));\n            }\n          }\n        } catch (temp2) {\n          error2 = [temp2];\n        } finally {\n          try {\n            more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));\n          } finally {\n            if (error2)\n              throw error2[0];\n          }\n        }\n      } catch (_2) {\n        var _error2 = _2, _hasError2 = true;\n      } finally {\n        var _promise2 = __callDispose(_stack2, _error2, _hasError2);\n        _promise2 && (yield new __await(_promise2));\n      }\n    });\n  }\n};\nasync function bar() {\n  await using x = await y;\n  for await (let x2 of y) {\n  }\n  for await (await using x2 of y) {\n  }\n}\n\n================================================================================\nTestLowerAsyncGeneratorNoAwait\n---------- /out/entry.js ----------\nfunction foo() {\n  return __asyncGenerator(this, null, function* () {\n    var _stack2 = [];\n    try {\n      yield;\n      yield x;\n      yield* __yieldStar(x);\n      const x = __using(_stack2, yield new __await(y), true);\n      try {\n        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {\n          let x2 = temp.value;\n        }\n      } catch (temp) {\n        error = [temp];\n      } finally {\n        try {\n          more && (temp = iter.return) && (yield new __await(temp.call(iter)));\n        } finally {\n          if (error)\n            throw error[0];\n        }\n      }\n      try {\n        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {\n          var _x = temp2.value;\n          var _stack = [];\n          try {\n            const x2 = __using(_stack, _x, true);\n          } catch (_) {\n            var _error = _, _hasError = true;\n          } finally {\n            var _promise = __callDispose(_stack, _error, _hasError);\n            _promise && (yield new __await(_promise));\n          }\n        }\n      } catch (temp2) {\n        error2 = [temp2];\n      } finally {\n        try {\n          more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));\n        } finally {\n          if (error2)\n            throw error2[0];\n        }\n      }\n    } catch (_2) {\n      var _error2 = _2, _hasError2 = true;\n    } finally {\n      var _promise2 = __callDispose(_stack2, _error2, _hasError2);\n      _promise2 && (yield new __await(_promise2));\n    }\n  });\n}\nfoo = function() {\n  return __asyncGenerator(this, null, function* () {\n    var _stack2 = [];\n    try {\n      yield;\n      yield x;\n      yield* __yieldStar(x);\n      const x = __using(_stack2, yield new __await(y), true);\n      try {\n        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {\n          let x2 = temp.value;\n        }\n      } catch (temp) {\n        error = [temp];\n      } finally {\n        try {\n          more && (temp = iter.return) && (yield new __await(temp.call(iter)));\n        } finally {\n          if (error)\n            throw error[0];\n        }\n      }\n      try {\n        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {\n          var _x = temp2.value;\n          var _stack = [];\n          try {\n            const x2 = __using(_stack, _x, true);\n          } catch (_) {\n            var _error = _, _hasError = true;\n          } finally {\n            var _promise = __callDispose(_stack, _error, _hasError);\n            _promise && (yield new __await(_promise));\n          }\n        }\n      } catch (temp2) {\n        error2 = [temp2];\n      } finally {\n        try {\n          more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));\n        } finally {\n          if (error2)\n            throw error2[0];\n        }\n      }\n    } catch (_2) {\n      var _error2 = _2, _hasError2 = true;\n    } finally {\n      var _promise2 = __callDispose(_stack2, _error2, _hasError2);\n      _promise2 && (yield new __await(_promise2));\n    }\n  });\n};\nfoo = { bar() {\n  return __asyncGenerator(this, null, function* () {\n    var _stack2 = [];\n    try {\n      yield;\n      yield x;\n      yield* __yieldStar(x);\n      const x = __using(_stack2, yield new __await(y), true);\n      try {\n        for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {\n          let x2 = temp.value;\n        }\n      } catch (temp) {\n        error = [temp];\n      } finally {\n        try {\n          more && (temp = iter.return) && (yield new __await(temp.call(iter)));\n        } finally {\n          if (error)\n            throw error[0];\n        }\n      }\n      try {\n        for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {\n          var _x = temp2.value;\n          var _stack = [];\n          try {\n            const x2 = __using(_stack, _x, true);\n          } catch (_) {\n            var _error = _, _hasError = true;\n          } finally {\n            var _promise = __callDispose(_stack, _error, _hasError);\n            _promise && (yield new __await(_promise));\n          }\n        }\n      } catch (temp2) {\n        error2 = [temp2];\n      } finally {\n        try {\n          more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));\n        } finally {\n          if (error2)\n            throw error2[0];\n        }\n      }\n    } catch (_2) {\n      var _error2 = _2, _hasError2 = true;\n    } finally {\n      var _promise2 = __callDispose(_stack2, _error2, _hasError2);\n      _promise2 && (yield new __await(_promise2));\n    }\n  });\n} };\nclass Foo {\n  bar() {\n    return __asyncGenerator(this, null, function* () {\n      var _stack2 = [];\n      try {\n        yield;\n        yield x;\n        yield* __yieldStar(x);\n        const x = __using(_stack2, yield new __await(y), true);\n        try {\n          for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {\n            let x2 = temp.value;\n          }\n        } catch (temp) {\n          error = [temp];\n        } finally {\n          try {\n            more && (temp = iter.return) && (yield new __await(temp.call(iter)));\n          } finally {\n            if (error)\n              throw error[0];\n          }\n        }\n        try {\n          for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {\n            var _x = temp2.value;\n            var _stack = [];\n            try {\n              const x2 = __using(_stack, _x, true);\n            } catch (_) {\n              var _error = _, _hasError = true;\n            } finally {\n              var _promise = __callDispose(_stack, _error, _hasError);\n              _promise && (yield new __await(_promise));\n            }\n          }\n        } catch (temp2) {\n          error2 = [temp2];\n        } finally {\n          try {\n            more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));\n          } finally {\n            if (error2)\n              throw error2[0];\n          }\n        }\n      } catch (_2) {\n        var _error2 = _2, _hasError2 = true;\n      } finally {\n        var _promise2 = __callDispose(_stack2, _error2, _hasError2);\n        _promise2 && (yield new __await(_promise2));\n      }\n    });\n  }\n}\nFoo = class {\n  bar() {\n    return __asyncGenerator(this, null, function* () {\n      var _stack2 = [];\n      try {\n        yield;\n        yield x;\n        yield* __yieldStar(x);\n        const x = __using(_stack2, yield new __await(y), true);\n        try {\n          for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield new __await(iter.next())).done; more = false) {\n            let x2 = temp.value;\n          }\n        } catch (temp) {\n          error = [temp];\n        } finally {\n          try {\n            more && (temp = iter.return) && (yield new __await(temp.call(iter)));\n          } finally {\n            if (error)\n              throw error[0];\n          }\n        }\n        try {\n          for (var iter2 = __forAwait(y), more2, temp2, error2; more2 = !(temp2 = yield new __await(iter2.next())).done; more2 = false) {\n            var _x = temp2.value;\n            var _stack = [];\n            try {\n              const x2 = __using(_stack, _x, true);\n            } catch (_) {\n              var _error = _, _hasError = true;\n            } finally {\n              var _promise = __callDispose(_stack, _error, _hasError);\n              _promise && (yield new __await(_promise));\n            }\n          }\n        } catch (temp2) {\n          error2 = [temp2];\n        } finally {\n          try {\n            more2 && (temp2 = iter2.return) && (yield new __await(temp2.call(iter2)));\n          } finally {\n            if (error2)\n              throw error2[0];\n          }\n        }\n      } catch (_2) {\n        var _error2 = _2, _hasError2 = true;\n      } finally {\n        var _promise2 = __callDispose(_stack2, _error2, _hasError2);\n        _promise2 && (yield new __await(_promise2));\n      }\n    });\n  }\n};\nfunction bar() {\n  return __async(this, null, function* () {\n    var _stack2 = [];\n    try {\n      const x = __using(_stack2, yield y, true);\n      for await (let x2 of y) {\n      }\n      for await (var _x of y) {\n        var _stack = [];\n        try {\n          const x2 = __using(_stack, _x, true);\n        } catch (_) {\n          var _error = _, _hasError = true;\n        } finally {\n          var _promise = __callDispose(_stack, _error, _hasError);\n          _promise && (yield _promise);\n        }\n      }\n    } catch (_2) {\n      var _error2 = _2, _hasError2 = true;\n    } finally {\n      var _promise2 = __callDispose(_stack2, _error2, _hasError2);\n      _promise2 && (yield _promise2);\n    }\n  });\n}\n\n================================================================================\nTestLowerAsyncSuperES2016NoBundle\n---------- /out.js ----------\nclass Derived extends Base {\n  test(key) {\n    return __async(this, null, function* () {\n      var _a, _b, _c, _d;\n      return [\n        yield __superGet(Derived.prototype, this, \"foo\"),\n        yield __superGet(Derived.prototype, this, key),\n        yield [__superWrapper(Derived.prototype, this, \"foo\")._] = [0],\n        yield [__superWrapper(Derived.prototype, this, key)._] = [0],\n        yield __superSet(Derived.prototype, this, \"foo\", 1),\n        yield __superSet(Derived.prototype, this, key, 1),\n        yield __superSet(Derived.prototype, this, \"foo\", __superGet(Derived.prototype, this, \"foo\") + 2),\n        yield __superSet(Derived.prototype, this, key, __superGet(Derived.prototype, this, key) + 2),\n        yield ++__superWrapper(Derived.prototype, this, \"foo\")._,\n        yield ++__superWrapper(Derived.prototype, this, key)._,\n        yield __superWrapper(Derived.prototype, this, \"foo\")._++,\n        yield __superWrapper(Derived.prototype, this, key)._++,\n        yield __superGet(Derived.prototype, this, \"foo\").name,\n        yield __superGet(Derived.prototype, this, key).name,\n        yield (_a = __superGet(Derived.prototype, this, \"foo\")) == null ? void 0 : _a.name,\n        yield (_b = __superGet(Derived.prototype, this, key)) == null ? void 0 : _b.name,\n        yield __superGet(Derived.prototype, this, \"foo\").call(this, 1, 2),\n        yield __superGet(Derived.prototype, this, key).call(this, 1, 2),\n        yield (_c = __superGet(Derived.prototype, this, \"foo\")) == null ? void 0 : _c.call(this, 1, 2),\n        yield (_d = __superGet(Derived.prototype, this, key)) == null ? void 0 : _d.call(this, 1, 2),\n        yield (() => __superGet(Derived.prototype, this, \"foo\"))(),\n        yield (() => __superGet(Derived.prototype, this, key))(),\n        yield (() => __superGet(Derived.prototype, this, \"foo\").call(this))(),\n        yield (() => __superGet(Derived.prototype, this, key).call(this))(),\n        yield __superGet(Derived.prototype, this, \"foo\").bind(this)``,\n        yield __superGet(Derived.prototype, this, key).bind(this)``\n      ];\n    });\n  }\n}\nlet fn = () => __async(null, null, function* () {\n  return class extends Base {\n    constructor() {\n      super(...arguments);\n      __publicField(this, \"a\", super.a);\n      __publicField(this, \"b\", () => super.b);\n    }\n    c() {\n      return super.c;\n    }\n    d() {\n      return () => super.d;\n    }\n  };\n});\nclass Derived2 extends Base {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"b\", () => __async(null, null, function* () {\n      var _a;\n      return _a = __superGet(Derived2.prototype, this, \"foo\"), class {\n        constructor() {\n          __publicField(this, _a, 123);\n        }\n      };\n    }));\n  }\n  a() {\n    return __async(this, null, function* () {\n      var _a;\n      return _a = __superGet(Derived2.prototype, this, \"foo\"), class {\n        constructor() {\n          __publicField(this, _a, 123);\n        }\n      };\n    });\n  }\n}\nfor (let i = 0; i < 3; i++) {\n  let _a;\n  objs.push(_a = {\n    __proto__: {\n      foo() {\n        return i;\n      }\n    },\n    bar() {\n      return __async(this, null, function* () {\n        return __superGet(_a, this, \"foo\").call(this);\n      });\n    }\n  });\n}\n\n================================================================================\nTestLowerAsyncSuperES2017NoBundle\n---------- /out.js ----------\nclass Derived extends Base {\n  async test(key) {\n    var _a, _b, _c, _d;\n    return [\n      await super.foo,\n      await super[key],\n      await ([super.foo] = [0]),\n      await ([super[key]] = [0]),\n      await (super.foo = 1),\n      await (super[key] = 1),\n      await (super.foo += 2),\n      await (super[key] += 2),\n      await ++super.foo,\n      await ++super[key],\n      await super.foo++,\n      await super[key]++,\n      await super.foo.name,\n      await super[key].name,\n      await ((_a = super.foo) == null ? void 0 : _a.name),\n      await ((_b = super[key]) == null ? void 0 : _b.name),\n      await super.foo(1, 2),\n      await super[key](1, 2),\n      await ((_c = super.foo) == null ? void 0 : _c.call(this, 1, 2)),\n      await ((_d = super[key]) == null ? void 0 : _d.call(this, 1, 2)),\n      await (() => super.foo)(),\n      await (() => super[key])(),\n      await (() => super.foo())(),\n      await (() => super[key]())(),\n      await super.foo``,\n      await super[key]``\n    ];\n  }\n}\nlet fn = async () => class extends Base {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"a\", super.a);\n    __publicField(this, \"b\", () => super.b);\n  }\n  c() {\n    return super.c;\n  }\n  d() {\n    return () => super.d;\n  }\n};\nclass Derived2 extends Base {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"b\", async () => {\n      var _a;\n      return _a = super.foo, class {\n        constructor() {\n          __publicField(this, _a, 123);\n        }\n      };\n    });\n  }\n  async a() {\n    var _a;\n    return _a = super.foo, class {\n      constructor() {\n        __publicField(this, _a, 123);\n      }\n    };\n  }\n}\nfor (let i = 0; i < 3; i++) {\n  objs.push({\n    __proto__: {\n      foo() {\n        return i;\n      }\n    },\n    async bar() {\n      return super.foo();\n    }\n  });\n}\n\n================================================================================\nTestLowerAsyncThis2016CommonJS\n---------- /out.js ----------\n// entry.js\nvar require_entry = __commonJS({\n  \"entry.js\"(exports) {\n    exports.foo = () => __async(exports, null, function* () {\n      return exports;\n    });\n  }\n});\nexport default require_entry();\n\n================================================================================\nTestLowerAsyncThis2016ES6\n---------- /out.js ----------\n// other.js\nvar bar = () => __async(null, null, function* () {\n});\n\n// entry.js\nvar foo = () => __async(void 0, null, function* () {\n  return void 0;\n});\nexport {\n  bar,\n  foo\n};\n\n================================================================================\nTestLowerClassField2020NoBundle\n---------- /out.js ----------\nvar _foo, _bar, _s_foo, _s_bar;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _foo, 123);\n    __privateAdd(this, _bar);\n    __publicField(this, \"foo\", 123);\n    __publicField(this, \"bar\");\n  }\n}\n_foo = new WeakMap();\n_bar = new WeakMap();\n_s_foo = new WeakMap();\n_s_bar = new WeakMap();\n__privateAdd(Foo, _s_foo, 123);\n__privateAdd(Foo, _s_bar);\n__publicField(Foo, \"s_foo\", 123);\n__publicField(Foo, \"s_bar\");\n\n================================================================================\nTestLowerClassFieldNextNoBundle\n---------- /out.js ----------\nclass Foo {\n  #foo = 123;\n  #bar;\n  foo = 123;\n  bar;\n  static #s_foo = 123;\n  static #s_bar;\n  static s_foo = 123;\n  static s_bar;\n}\n\n================================================================================\nTestLowerClassFieldStrictTsconfigJson2020\n---------- /out.js ----------\n// loose/index.js\nvar loose_default = class {\n  constructor() {\n    __publicField(this, \"foo\");\n  }\n};\n\n// strict/index.js\nvar strict_default = class {\n  constructor() {\n    __publicField(this, \"foo\");\n  }\n};\n\n// entry.js\nconsole.log(loose_default, strict_default);\n\n================================================================================\nTestLowerExponentiationOperatorNoBundle\n---------- /out.js ----------\nvar _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;\nlet tests = {\n  // Exponentiation operator\n  0: __pow(a, __pow(b, c)),\n  1: __pow(__pow(a, b), c),\n  // Exponentiation assignment operator\n  2: a = __pow(a, b),\n  3: a.b = __pow(a.b, c),\n  4: a[b] = __pow(a[b], c),\n  5: (_a = a()).b = __pow(_a.b, c),\n  6: (_b = a())[b] = __pow(_b[b], c),\n  7: a[_c = b()] = __pow(a[_c], c),\n  8: (_d = a())[_e = b()] = __pow(_d[_e], c),\n  // These all should not need capturing (no object identity)\n  9: a[0] = __pow(a[0], b),\n  10: a[false] = __pow(a[false], b),\n  11: a[null] = __pow(a[null], b),\n  12: a[void 0] = __pow(a[void 0], b),\n  13: a[/* @__PURE__ */ BigInt(\"123\")] = __pow(a[/* @__PURE__ */ BigInt(\"123\")], b),\n  14: a[this] = __pow(a[this], b),\n  // These should need capturing (have object identitiy)\n  15: a[_f = /x/] = __pow(a[_f], b),\n  16: a[_g = {}] = __pow(a[_g], b),\n  17: a[_h = []] = __pow(a[_h], b),\n  18: a[_i = () => {\n  }] = __pow(a[_i], b),\n  19: a[_j = function() {\n  }] = __pow(a[_j], b)\n};\n\n================================================================================\nTestLowerExportStarAsNameCollision\n---------- /out.js ----------\n// nested.js\nimport * as foo from \"path2\";\nvar foo2 = 123;\n\n// entry.js\nimport * as ns from \"path1\";\nconsole.log(foo, foo2);\nvar ns2 = 123;\nexport {\n  ns,\n  ns2 as sn\n};\n\n================================================================================\nTestLowerExportStarAsNameCollisionNoBundle\n---------- /out.js ----------\nimport * as ns from \"path\";\nexport { ns };\nlet ns2 = 123;\nexport { ns2 as sn };\n\n================================================================================\nTestLowerForAwait2015\n---------- /out.js ----------\nexport default [\n  () => __async(null, null, function* () {\n    try {\n      for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {\n        x = temp.value;\n        z(x);\n      }\n    } catch (temp) {\n      error = [temp];\n    } finally {\n      try {\n        more && (temp = iter.return) && (yield temp.call(iter));\n      } finally {\n        if (error)\n          throw error[0];\n      }\n    }\n  }),\n  () => __async(null, null, function* () {\n    try {\n      for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {\n        x.y = temp.value;\n        z(x);\n      }\n    } catch (temp) {\n      error = [temp];\n    } finally {\n      try {\n        more && (temp = iter.return) && (yield temp.call(iter));\n      } finally {\n        if (error)\n          throw error[0];\n      }\n    }\n  }),\n  () => __async(null, null, function* () {\n    try {\n      for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {\n        let x2 = temp.value;\n        z(x2);\n      }\n    } catch (temp) {\n      error = [temp];\n    } finally {\n      try {\n        more && (temp = iter.return) && (yield temp.call(iter));\n      } finally {\n        if (error)\n          throw error[0];\n      }\n    }\n  }),\n  () => __async(null, null, function* () {\n    try {\n      for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {\n        const x2 = temp.value;\n        z(x2);\n      }\n    } catch (temp) {\n      error = [temp];\n    } finally {\n      try {\n        more && (temp = iter.return) && (yield temp.call(iter));\n      } finally {\n        if (error)\n          throw error[0];\n      }\n    }\n  }),\n  () => __async(null, null, function* () {\n    try {\n      label: for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {\n        const x2 = temp.value;\n        break label;\n      }\n    } catch (temp) {\n      error = [temp];\n    } finally {\n      try {\n        more && (temp = iter.return) && (yield temp.call(iter));\n      } finally {\n        if (error)\n          throw error[0];\n      }\n    }\n  }),\n  () => __async(null, null, function* () {\n    try {\n      label: for (var iter = __forAwait(y), more, temp, error; more = !(temp = yield iter.next()).done; more = false) {\n        const x2 = temp.value;\n        continue label;\n      }\n    } catch (temp) {\n      error = [temp];\n    } finally {\n      try {\n        more && (temp = iter.return) && (yield temp.call(iter));\n      } finally {\n        if (error)\n          throw error[0];\n      }\n    }\n  })\n];\n\n================================================================================\nTestLowerForAwait2017\n---------- /out.js ----------\nexport default [\n  async () => {\n    try {\n      for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {\n        x = temp.value;\n        z(x);\n      }\n    } catch (temp) {\n      error = [temp];\n    } finally {\n      try {\n        more && (temp = iter.return) && await temp.call(iter);\n      } finally {\n        if (error)\n          throw error[0];\n      }\n    }\n  },\n  async () => {\n    try {\n      for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {\n        x.y = temp.value;\n        z(x);\n      }\n    } catch (temp) {\n      error = [temp];\n    } finally {\n      try {\n        more && (temp = iter.return) && await temp.call(iter);\n      } finally {\n        if (error)\n          throw error[0];\n      }\n    }\n  },\n  async () => {\n    try {\n      for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {\n        let x2 = temp.value;\n        z(x2);\n      }\n    } catch (temp) {\n      error = [temp];\n    } finally {\n      try {\n        more && (temp = iter.return) && await temp.call(iter);\n      } finally {\n        if (error)\n          throw error[0];\n      }\n    }\n  },\n  async () => {\n    try {\n      for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {\n        const x2 = temp.value;\n        z(x2);\n      }\n    } catch (temp) {\n      error = [temp];\n    } finally {\n      try {\n        more && (temp = iter.return) && await temp.call(iter);\n      } finally {\n        if (error)\n          throw error[0];\n      }\n    }\n  },\n  async () => {\n    try {\n      label: for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {\n        const x2 = temp.value;\n        break label;\n      }\n    } catch (temp) {\n      error = [temp];\n    } finally {\n      try {\n        more && (temp = iter.return) && await temp.call(iter);\n      } finally {\n        if (error)\n          throw error[0];\n      }\n    }\n  },\n  async () => {\n    try {\n      label: for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {\n        const x2 = temp.value;\n        continue label;\n      }\n    } catch (temp) {\n      error = [temp];\n    } finally {\n      try {\n        more && (temp = iter.return) && await temp.call(iter);\n      } finally {\n        if (error)\n          throw error[0];\n      }\n    }\n  }\n];\n\n================================================================================\nTestLowerNestedFunctionDirectEval\n---------- /out/1.js ----------\nif (foo) {\n  let x2 = function() {\n  };\n  var x = x2;\n}\n\n---------- /out/2.js ----------\nif (foo) {\n  function x() {\n  }\n  eval(\"\");\n}\n\n---------- /out/3.js ----------\nif (foo) {\n  function x() {\n  }\n  if (bar) {\n    eval(\"\");\n  }\n}\n\n---------- /out/4.js ----------\nif (foo) {\n  function x() {\n  }\n  eval(\"\");\n}\n\n---------- /out/5.js ----------\n\"use strict\";\nif (foo) {\n  let x = function() {\n  };\n}\n\n---------- /out/6.js ----------\n\"use strict\";\nif (foo) {\n  function x() {\n  }\n  eval(\"\");\n}\n\n---------- /out/7.js ----------\n\"use strict\";\nif (foo) {\n  function x() {\n  }\n  if (bar) {\n    eval(\"\");\n  }\n}\n\n---------- /out/8.js ----------\n\"use strict\";\nif (foo) {\n  function x() {\n  }\n  eval(\"\");\n}\n\n================================================================================\nTestLowerNullishCoalescingAssignmentIssue1493\n---------- /out.js ----------\n// entry.js\nvar A = class {\n  #a;\n  f() {\n    this.#a ?? (this.#a = 1);\n  }\n};\nexport {\n  A\n};\n\n================================================================================\nTestLowerObjectSpreadNoBundle\n---------- /out.js ----------\nlet tests = [\n  __spreadValues(__spreadValues({}, a), b),\n  __spreadValues({ a, b }, c),\n  __spreadProps(__spreadValues({}, a), { b, c }),\n  __spreadProps(__spreadValues({ a }, b), { c }),\n  __spreadProps(__spreadValues(__spreadValues(__spreadProps(__spreadValues(__spreadValues({ a, b }, c), d), { e, f }), g), h), { i, j })\n];\nlet jsx = [\n  /* @__PURE__ */ React.createElement(\"div\", __spreadValues(__spreadValues({}, a), b)),\n  /* @__PURE__ */ React.createElement(\"div\", __spreadValues({ a: true, b: true }, c)),\n  /* @__PURE__ */ React.createElement(\"div\", __spreadProps(__spreadValues({}, a), { b: true, c: true })),\n  /* @__PURE__ */ React.createElement(\"div\", __spreadProps(__spreadValues({ a: true }, b), { c: true })),\n  /* @__PURE__ */ React.createElement(\"div\", __spreadProps(__spreadValues(__spreadValues(__spreadProps(__spreadValues(__spreadValues({ a: true, b: true }, c), d), { e: true, f: true }), g), h), { i: true, j: true }))\n];\n\n================================================================================\nTestLowerOptionalCatchNameCollisionNoBundle\n---------- /out.js ----------\ntry {\n} catch (e4) {\n  var e, e2;\n}\nvar e3;\n\n================================================================================\nTestLowerPrivateClassAccessorOrder\n---------- /out.js ----------\nvar _Foo_instances, foo_get;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _Foo_instances);\n    __publicField(this, \"bar\", __privateGet(this, _Foo_instances, foo_get));\n  }\n  // This must be set before \"bar\" is initialized\n}\n_Foo_instances = new WeakSet();\nfoo_get = function() {\n  return 123;\n};\nconsole.log(new Foo().bar === 123);\n\n================================================================================\nTestLowerPrivateClassBrandCheckSupported\n---------- /out.js ----------\nclass Foo {\n  #foo;\n  #bar;\n  baz() {\n    return [\n      this.#foo,\n      this.#bar,\n      #foo in this\n    ];\n  }\n}\n\n================================================================================\nTestLowerPrivateClassBrandCheckUnsupported\n---------- /out.js ----------\nvar _foo;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _foo);\n    this.#bar = void 0;\n  }\n  #bar;\n  baz() {\n    return [\n      __privateGet(this, _foo),\n      this.#bar,\n      __privateIn(_foo, this)\n    ];\n  }\n}\n_foo = new WeakMap();\n\n================================================================================\nTestLowerPrivateClassExpr2020NoBundle\n---------- /out.js ----------\nvar _field, _Foo_instances, method_fn, _a, _staticField, _Foo_static, staticMethod_fn;\nexport let Foo = (_a = class {\n  constructor() {\n    __privateAdd(this, _Foo_instances);\n    __privateAdd(this, _field);\n  }\n  foo() {\n    var _a2;\n    __privateSet(this, _field, __privateMethod(this, _Foo_instances, method_fn).call(this));\n    __privateSet(Foo, _staticField, __privateMethod(_a2 = Foo, _Foo_static, staticMethod_fn).call(_a2));\n  }\n}, _field = new WeakMap(), _Foo_instances = new WeakSet(), method_fn = function() {\n}, _staticField = new WeakMap(), _Foo_static = new WeakSet(), staticMethod_fn = function() {\n}, __privateAdd(_a, _Foo_static), __privateAdd(_a, _staticField), _a);\n\n================================================================================\nTestLowerPrivateClassFieldOrder\n---------- /out.js ----------\nvar _foo;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _foo, 123);\n    // This must be set before \"bar\" is initialized\n    __publicField(this, \"bar\", __privateGet(this, _foo));\n  }\n}\n_foo = new WeakMap();\nconsole.log(new Foo().bar === 123);\n\n================================================================================\nTestLowerPrivateClassFieldStaticIssue1424\n---------- /out.js ----------\n// entry.js\nvar _T_instances, a_fn, b_fn;\nvar T = class {\n  constructor() {\n    __privateAdd(this, _T_instances);\n  }\n  d() {\n    console.log(__privateMethod(this, _T_instances, a_fn).call(this));\n  }\n};\n_T_instances = new WeakSet();\na_fn = function() {\n  return \"a\";\n};\nb_fn = function() {\n  return \"b\";\n};\n__publicField(T, \"c\");\nnew T().d();\n\n================================================================================\nTestLowerPrivateClassMethodOrder\n---------- /out.js ----------\nvar _Foo_instances, foo_fn;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _Foo_instances);\n    __publicField(this, \"bar\", __privateMethod(this, _Foo_instances, foo_fn).call(this));\n  }\n  // This must be set before \"bar\" is initialized\n}\n_Foo_instances = new WeakSet();\nfoo_fn = function() {\n  return 123;\n};\nconsole.log(new Foo().bar === 123);\n\n================================================================================\nTestLowerPrivateClassStaticAccessorOrder\n---------- /out.js ----------\nvar _Foo_static, foo_get, _FooThis_static, foo_get2;\nconst _Foo = class _Foo {\n  // This must be set before \"bar\" is initialized\n};\n_Foo_static = new WeakSet();\nfoo_get = function() {\n  return 123;\n};\n__privateAdd(_Foo, _Foo_static);\n__publicField(_Foo, \"bar\", __privateGet(_Foo, _Foo_static, foo_get));\nlet Foo = _Foo;\nconsole.log(Foo.bar === 123);\nconst _FooThis = class _FooThis {\n  // This must be set before \"bar\" is initialized\n};\n_FooThis_static = new WeakSet();\nfoo_get2 = function() {\n  return 123;\n};\n__privateAdd(_FooThis, _FooThis_static);\n__publicField(_FooThis, \"bar\", __privateGet(_FooThis, _FooThis_static, foo_get2));\nlet FooThis = _FooThis;\nconsole.log(FooThis.bar === 123);\n\n================================================================================\nTestLowerPrivateClassStaticFieldOrder\n---------- /out.js ----------\nvar _foo, _foo2;\nconst _Foo = class _Foo {\n};\n_foo = new WeakMap();\n__privateAdd(_Foo, _foo, 123);\n// This must be set before \"bar\" is initialized\n__publicField(_Foo, \"bar\", __privateGet(_Foo, _foo));\nlet Foo = _Foo;\nconsole.log(Foo.bar === 123);\nconst _FooThis = class _FooThis {\n};\n_foo2 = new WeakMap();\n__privateAdd(_FooThis, _foo2, 123);\n// This must be set before \"bar\" is initialized\n__publicField(_FooThis, \"bar\", __privateGet(_FooThis, _foo2));\nlet FooThis = _FooThis;\nconsole.log(FooThis.bar === 123);\n\n================================================================================\nTestLowerPrivateClassStaticMethodOrder\n---------- /out.js ----------\nvar _a, _Foo_static, foo_fn, _b, _FooThis_static, foo_fn2;\nconst _Foo = class _Foo {\n  // This must be set before \"bar\" is initialized\n};\n_Foo_static = new WeakSet();\nfoo_fn = function() {\n  return 123;\n};\n__privateAdd(_Foo, _Foo_static);\n__publicField(_Foo, \"bar\", __privateMethod(_a = _Foo, _Foo_static, foo_fn).call(_a));\nlet Foo = _Foo;\nconsole.log(Foo.bar === 123);\nconst _FooThis = class _FooThis {\n  // This must be set before \"bar\" is initialized\n};\n_FooThis_static = new WeakSet();\nfoo_fn2 = function() {\n  return 123;\n};\n__privateAdd(_FooThis, _FooThis_static);\n__publicField(_FooThis, \"bar\", __privateMethod(_b = _FooThis, _FooThis_static, foo_fn2).call(_b));\nlet FooThis = _FooThis;\nconsole.log(FooThis.bar === 123);\n\n================================================================================\nTestLowerPrivateFieldAssignments2015NoBundle\n---------- /out.js ----------\nvar _x;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x);\n  }\n  unary() {\n    __privateWrapper(this, _x)._++;\n    __privateWrapper(this, _x)._--;\n    ++__privateWrapper(this, _x)._;\n    --__privateWrapper(this, _x)._;\n  }\n  binary() {\n    var _a;\n    __privateSet(this, _x, 1);\n    __privateSet(this, _x, __privateGet(this, _x) + 1);\n    __privateSet(this, _x, __privateGet(this, _x) - 1);\n    __privateSet(this, _x, __privateGet(this, _x) * 1);\n    __privateSet(this, _x, __privateGet(this, _x) / 1);\n    __privateSet(this, _x, __privateGet(this, _x) % 1);\n    __privateSet(this, _x, __pow(__privateGet(this, _x), 1));\n    __privateSet(this, _x, __privateGet(this, _x) << 1);\n    __privateSet(this, _x, __privateGet(this, _x) >> 1);\n    __privateSet(this, _x, __privateGet(this, _x) >>> 1);\n    __privateSet(this, _x, __privateGet(this, _x) & 1);\n    __privateSet(this, _x, __privateGet(this, _x) | 1);\n    __privateSet(this, _x, __privateGet(this, _x) ^ 1);\n    __privateGet(this, _x) && __privateSet(this, _x, 1);\n    __privateGet(this, _x) || __privateSet(this, _x, 1);\n    (_a = __privateGet(this, _x)) != null ? _a : __privateSet(this, _x, 1);\n  }\n}\n_x = new WeakMap();\n\n================================================================================\nTestLowerPrivateFieldAssignments2019NoBundle\n---------- /out.js ----------\nvar _x;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x);\n  }\n  unary() {\n    __privateWrapper(this, _x)._++;\n    __privateWrapper(this, _x)._--;\n    ++__privateWrapper(this, _x)._;\n    --__privateWrapper(this, _x)._;\n  }\n  binary() {\n    var _a;\n    __privateSet(this, _x, 1);\n    __privateSet(this, _x, __privateGet(this, _x) + 1);\n    __privateSet(this, _x, __privateGet(this, _x) - 1);\n    __privateSet(this, _x, __privateGet(this, _x) * 1);\n    __privateSet(this, _x, __privateGet(this, _x) / 1);\n    __privateSet(this, _x, __privateGet(this, _x) % 1);\n    __privateSet(this, _x, __privateGet(this, _x) ** 1);\n    __privateSet(this, _x, __privateGet(this, _x) << 1);\n    __privateSet(this, _x, __privateGet(this, _x) >> 1);\n    __privateSet(this, _x, __privateGet(this, _x) >>> 1);\n    __privateSet(this, _x, __privateGet(this, _x) & 1);\n    __privateSet(this, _x, __privateGet(this, _x) | 1);\n    __privateSet(this, _x, __privateGet(this, _x) ^ 1);\n    __privateGet(this, _x) && __privateSet(this, _x, 1);\n    __privateGet(this, _x) || __privateSet(this, _x, 1);\n    (_a = __privateGet(this, _x)) != null ? _a : __privateSet(this, _x, 1);\n  }\n}\n_x = new WeakMap();\n\n================================================================================\nTestLowerPrivateFieldAssignments2020NoBundle\n---------- /out.js ----------\nvar _x;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x);\n  }\n  unary() {\n    __privateWrapper(this, _x)._++;\n    __privateWrapper(this, _x)._--;\n    ++__privateWrapper(this, _x)._;\n    --__privateWrapper(this, _x)._;\n  }\n  binary() {\n    __privateSet(this, _x, 1);\n    __privateSet(this, _x, __privateGet(this, _x) + 1);\n    __privateSet(this, _x, __privateGet(this, _x) - 1);\n    __privateSet(this, _x, __privateGet(this, _x) * 1);\n    __privateSet(this, _x, __privateGet(this, _x) / 1);\n    __privateSet(this, _x, __privateGet(this, _x) % 1);\n    __privateSet(this, _x, __privateGet(this, _x) ** 1);\n    __privateSet(this, _x, __privateGet(this, _x) << 1);\n    __privateSet(this, _x, __privateGet(this, _x) >> 1);\n    __privateSet(this, _x, __privateGet(this, _x) >>> 1);\n    __privateSet(this, _x, __privateGet(this, _x) & 1);\n    __privateSet(this, _x, __privateGet(this, _x) | 1);\n    __privateSet(this, _x, __privateGet(this, _x) ^ 1);\n    __privateGet(this, _x) && __privateSet(this, _x, 1);\n    __privateGet(this, _x) || __privateSet(this, _x, 1);\n    __privateGet(this, _x) ?? __privateSet(this, _x, 1);\n  }\n}\n_x = new WeakMap();\n\n================================================================================\nTestLowerPrivateFieldAssignmentsNextNoBundle\n---------- /out.js ----------\nclass Foo {\n  #x;\n  unary() {\n    this.#x++;\n    this.#x--;\n    ++this.#x;\n    --this.#x;\n  }\n  binary() {\n    this.#x = 1;\n    this.#x += 1;\n    this.#x -= 1;\n    this.#x *= 1;\n    this.#x /= 1;\n    this.#x %= 1;\n    this.#x **= 1;\n    this.#x <<= 1;\n    this.#x >>= 1;\n    this.#x >>>= 1;\n    this.#x &= 1;\n    this.#x |= 1;\n    this.#x ^= 1;\n    this.#x &&= 1;\n    this.#x ||= 1;\n    this.#x ??= 1;\n  }\n}\n\n================================================================================\nTestLowerPrivateFieldOptionalChain2019NoBundle\n---------- /out.js ----------\nvar _x;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x);\n  }\n  foo() {\n    var _a;\n    this == null ? void 0 : __privateGet(this, _x).y;\n    this == null ? void 0 : __privateGet(this.y, _x);\n    (_a = __privateGet(this, _x)) == null ? void 0 : _a.y;\n  }\n}\n_x = new WeakMap();\n\n================================================================================\nTestLowerPrivateFieldOptionalChain2020NoBundle\n---------- /out.js ----------\nvar _x;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x);\n  }\n  foo() {\n    this == null ? void 0 : __privateGet(this, _x).y;\n    this == null ? void 0 : __privateGet(this.y, _x);\n    __privateGet(this, _x)?.y;\n  }\n}\n_x = new WeakMap();\n\n================================================================================\nTestLowerPrivateFieldOptionalChainNextNoBundle\n---------- /out.js ----------\nclass Foo {\n  #x;\n  foo() {\n    this?.#x.y;\n    this?.y.#x;\n    this.#x?.y;\n  }\n}\n\n================================================================================\nTestLowerPrivateGetterSetter2015\n---------- /out.js ----------\n// entry.js\nvar _Foo_instances, foo_get, bar_set, prop_get, prop_set;\nvar Foo = class {\n  constructor() {\n    __privateAdd(this, _Foo_instances);\n  }\n  foo(fn) {\n    __privateGet(fn(), _Foo_instances, foo_get);\n    __privateSet(fn(), _Foo_instances, 1, bar_set);\n    __privateGet(fn(), _Foo_instances, prop_get);\n    __privateSet(fn(), _Foo_instances, 2, prop_set);\n  }\n  unary(fn) {\n    __privateWrapper(fn(), _Foo_instances, prop_set, prop_get)._++;\n    __privateWrapper(fn(), _Foo_instances, prop_set, prop_get)._--;\n    ++__privateWrapper(fn(), _Foo_instances, prop_set, prop_get)._;\n    --__privateWrapper(fn(), _Foo_instances, prop_set, prop_get)._;\n  }\n  binary(fn) {\n    var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;\n    __privateSet(fn(), _Foo_instances, 1, prop_set);\n    __privateSet(_a = fn(), _Foo_instances, __privateGet(_a, _Foo_instances, prop_get) + 1, prop_set);\n    __privateSet(_b = fn(), _Foo_instances, __privateGet(_b, _Foo_instances, prop_get) - 1, prop_set);\n    __privateSet(_c = fn(), _Foo_instances, __privateGet(_c, _Foo_instances, prop_get) * 1, prop_set);\n    __privateSet(_d = fn(), _Foo_instances, __privateGet(_d, _Foo_instances, prop_get) / 1, prop_set);\n    __privateSet(_e = fn(), _Foo_instances, __privateGet(_e, _Foo_instances, prop_get) % 1, prop_set);\n    __privateSet(_f = fn(), _Foo_instances, __pow(__privateGet(_f, _Foo_instances, prop_get), 1), prop_set);\n    __privateSet(_g = fn(), _Foo_instances, __privateGet(_g, _Foo_instances, prop_get) << 1, prop_set);\n    __privateSet(_h = fn(), _Foo_instances, __privateGet(_h, _Foo_instances, prop_get) >> 1, prop_set);\n    __privateSet(_i = fn(), _Foo_instances, __privateGet(_i, _Foo_instances, prop_get) >>> 1, prop_set);\n    __privateSet(_j = fn(), _Foo_instances, __privateGet(_j, _Foo_instances, prop_get) & 1, prop_set);\n    __privateSet(_k = fn(), _Foo_instances, __privateGet(_k, _Foo_instances, prop_get) | 1, prop_set);\n    __privateSet(_l = fn(), _Foo_instances, __privateGet(_l, _Foo_instances, prop_get) ^ 1, prop_set);\n    __privateGet(_m = fn(), _Foo_instances, prop_get) && __privateSet(_m, _Foo_instances, 1, prop_set);\n    __privateGet(_n = fn(), _Foo_instances, prop_get) || __privateSet(_n, _Foo_instances, 1, prop_set);\n    (_p = __privateGet(_o = fn(), _Foo_instances, prop_get)) != null ? _p : __privateSet(_o, _Foo_instances, 1, prop_set);\n  }\n};\n_Foo_instances = new WeakSet();\nfoo_get = function() {\n  return this.foo;\n};\nbar_set = function(val) {\n  this.bar = val;\n};\nprop_get = function() {\n  return this.prop;\n};\nprop_set = function(val) {\n  this.prop = val;\n};\nexport {\n  Foo\n};\n\n================================================================================\nTestLowerPrivateGetterSetter2019\n---------- /out.js ----------\n// entry.js\nvar _Foo_instances, foo_get, bar_set, prop_get, prop_set;\nvar Foo = class {\n  constructor() {\n    __privateAdd(this, _Foo_instances);\n  }\n  foo(fn) {\n    __privateGet(fn(), _Foo_instances, foo_get);\n    __privateSet(fn(), _Foo_instances, 1, bar_set);\n    __privateGet(fn(), _Foo_instances, prop_get);\n    __privateSet(fn(), _Foo_instances, 2, prop_set);\n  }\n  unary(fn) {\n    __privateWrapper(fn(), _Foo_instances, prop_set, prop_get)._++;\n    __privateWrapper(fn(), _Foo_instances, prop_set, prop_get)._--;\n    ++__privateWrapper(fn(), _Foo_instances, prop_set, prop_get)._;\n    --__privateWrapper(fn(), _Foo_instances, prop_set, prop_get)._;\n  }\n  binary(fn) {\n    var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;\n    __privateSet(fn(), _Foo_instances, 1, prop_set);\n    __privateSet(_a = fn(), _Foo_instances, __privateGet(_a, _Foo_instances, prop_get) + 1, prop_set);\n    __privateSet(_b = fn(), _Foo_instances, __privateGet(_b, _Foo_instances, prop_get) - 1, prop_set);\n    __privateSet(_c = fn(), _Foo_instances, __privateGet(_c, _Foo_instances, prop_get) * 1, prop_set);\n    __privateSet(_d = fn(), _Foo_instances, __privateGet(_d, _Foo_instances, prop_get) / 1, prop_set);\n    __privateSet(_e = fn(), _Foo_instances, __privateGet(_e, _Foo_instances, prop_get) % 1, prop_set);\n    __privateSet(_f = fn(), _Foo_instances, __privateGet(_f, _Foo_instances, prop_get) ** 1, prop_set);\n    __privateSet(_g = fn(), _Foo_instances, __privateGet(_g, _Foo_instances, prop_get) << 1, prop_set);\n    __privateSet(_h = fn(), _Foo_instances, __privateGet(_h, _Foo_instances, prop_get) >> 1, prop_set);\n    __privateSet(_i = fn(), _Foo_instances, __privateGet(_i, _Foo_instances, prop_get) >>> 1, prop_set);\n    __privateSet(_j = fn(), _Foo_instances, __privateGet(_j, _Foo_instances, prop_get) & 1, prop_set);\n    __privateSet(_k = fn(), _Foo_instances, __privateGet(_k, _Foo_instances, prop_get) | 1, prop_set);\n    __privateSet(_l = fn(), _Foo_instances, __privateGet(_l, _Foo_instances, prop_get) ^ 1, prop_set);\n    __privateGet(_m = fn(), _Foo_instances, prop_get) && __privateSet(_m, _Foo_instances, 1, prop_set);\n    __privateGet(_n = fn(), _Foo_instances, prop_get) || __privateSet(_n, _Foo_instances, 1, prop_set);\n    (_p = __privateGet(_o = fn(), _Foo_instances, prop_get)) != null ? _p : __privateSet(_o, _Foo_instances, 1, prop_set);\n  }\n};\n_Foo_instances = new WeakSet();\nfoo_get = function() {\n  return this.foo;\n};\nbar_set = function(val) {\n  this.bar = val;\n};\nprop_get = function() {\n  return this.prop;\n};\nprop_set = function(val) {\n  this.prop = val;\n};\nexport {\n  Foo\n};\n\n================================================================================\nTestLowerPrivateGetterSetter2020\n---------- /out.js ----------\n// entry.js\nvar _Foo_instances, foo_get, bar_set, prop_get, prop_set;\nvar Foo = class {\n  constructor() {\n    __privateAdd(this, _Foo_instances);\n  }\n  foo(fn) {\n    __privateGet(fn(), _Foo_instances, foo_get);\n    __privateSet(fn(), _Foo_instances, 1, bar_set);\n    __privateGet(fn(), _Foo_instances, prop_get);\n    __privateSet(fn(), _Foo_instances, 2, prop_set);\n  }\n  unary(fn) {\n    __privateWrapper(fn(), _Foo_instances, prop_set, prop_get)._++;\n    __privateWrapper(fn(), _Foo_instances, prop_set, prop_get)._--;\n    ++__privateWrapper(fn(), _Foo_instances, prop_set, prop_get)._;\n    --__privateWrapper(fn(), _Foo_instances, prop_set, prop_get)._;\n  }\n  binary(fn) {\n    var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;\n    __privateSet(fn(), _Foo_instances, 1, prop_set);\n    __privateSet(_a = fn(), _Foo_instances, __privateGet(_a, _Foo_instances, prop_get) + 1, prop_set);\n    __privateSet(_b = fn(), _Foo_instances, __privateGet(_b, _Foo_instances, prop_get) - 1, prop_set);\n    __privateSet(_c = fn(), _Foo_instances, __privateGet(_c, _Foo_instances, prop_get) * 1, prop_set);\n    __privateSet(_d = fn(), _Foo_instances, __privateGet(_d, _Foo_instances, prop_get) / 1, prop_set);\n    __privateSet(_e = fn(), _Foo_instances, __privateGet(_e, _Foo_instances, prop_get) % 1, prop_set);\n    __privateSet(_f = fn(), _Foo_instances, __privateGet(_f, _Foo_instances, prop_get) ** 1, prop_set);\n    __privateSet(_g = fn(), _Foo_instances, __privateGet(_g, _Foo_instances, prop_get) << 1, prop_set);\n    __privateSet(_h = fn(), _Foo_instances, __privateGet(_h, _Foo_instances, prop_get) >> 1, prop_set);\n    __privateSet(_i = fn(), _Foo_instances, __privateGet(_i, _Foo_instances, prop_get) >>> 1, prop_set);\n    __privateSet(_j = fn(), _Foo_instances, __privateGet(_j, _Foo_instances, prop_get) & 1, prop_set);\n    __privateSet(_k = fn(), _Foo_instances, __privateGet(_k, _Foo_instances, prop_get) | 1, prop_set);\n    __privateSet(_l = fn(), _Foo_instances, __privateGet(_l, _Foo_instances, prop_get) ^ 1, prop_set);\n    __privateGet(_m = fn(), _Foo_instances, prop_get) && __privateSet(_m, _Foo_instances, 1, prop_set);\n    __privateGet(_n = fn(), _Foo_instances, prop_get) || __privateSet(_n, _Foo_instances, 1, prop_set);\n    __privateGet(_o = fn(), _Foo_instances, prop_get) ?? __privateSet(_o, _Foo_instances, 1, prop_set);\n  }\n};\n_Foo_instances = new WeakSet();\nfoo_get = function() {\n  return this.foo;\n};\nbar_set = function(val) {\n  this.bar = val;\n};\nprop_get = function() {\n  return this.prop;\n};\nprop_set = function(val) {\n  this.prop = val;\n};\nexport {\n  Foo\n};\n\n================================================================================\nTestLowerPrivateGetterSetterNext\n---------- /out.js ----------\n// entry.js\nvar Foo = class {\n  get #foo() {\n    return this.foo;\n  }\n  set #bar(val) {\n    this.bar = val;\n  }\n  get #prop() {\n    return this.prop;\n  }\n  set #prop(val) {\n    this.prop = val;\n  }\n  foo(fn) {\n    fn().#foo;\n    fn().#bar = 1;\n    fn().#prop;\n    fn().#prop = 2;\n  }\n  unary(fn) {\n    fn().#prop++;\n    fn().#prop--;\n    ++fn().#prop;\n    --fn().#prop;\n  }\n  binary(fn) {\n    fn().#prop = 1;\n    fn().#prop += 1;\n    fn().#prop -= 1;\n    fn().#prop *= 1;\n    fn().#prop /= 1;\n    fn().#prop %= 1;\n    fn().#prop **= 1;\n    fn().#prop <<= 1;\n    fn().#prop >>= 1;\n    fn().#prop >>>= 1;\n    fn().#prop &= 1;\n    fn().#prop |= 1;\n    fn().#prop ^= 1;\n    fn().#prop &&= 1;\n    fn().#prop ||= 1;\n    fn().#prop ??= 1;\n  }\n};\nexport {\n  Foo\n};\n\n================================================================================\nTestLowerPrivateMethod2019\n---------- /out.js ----------\n// entry.js\nvar _field, _Foo_instances, method_fn;\nvar Foo = class {\n  constructor() {\n    __privateAdd(this, _Foo_instances);\n    __privateAdd(this, _field);\n  }\n  baseline() {\n    var _a, _b, _c, _d, _e;\n    a().foo;\n    b().foo(x);\n    (_a = c()) == null ? void 0 : _a.foo(x);\n    (_c = (_b = d()).foo) == null ? void 0 : _c.call(_b, x);\n    (_e = (_d = e()) == null ? void 0 : _d.foo) == null ? void 0 : _e.call(_d, x);\n  }\n  privateField() {\n    var _a, _b, _c, _d, _e, _f, _g, _h;\n    __privateGet(a(), _field);\n    __privateGet(_a = b(), _field).call(_a, x);\n    (_b = c()) == null ? void 0 : __privateGet(_b, _field).call(_b, x);\n    (_d = __privateGet(_c = d(), _field)) == null ? void 0 : _d.call(_c, x);\n    (_f = (_e = e()) == null ? void 0 : __privateGet(_e, _field)) == null ? void 0 : _f.call(_e, x);\n    (_g = f()) == null ? void 0 : __privateGet(_h = _g.foo, _field).call(_h, x).bar();\n  }\n  privateMethod() {\n    var _a, _b, _c, _d, _e, _f, _g, _h;\n    __privateMethod(a(), _Foo_instances, method_fn);\n    __privateMethod(_a = b(), _Foo_instances, method_fn).call(_a, x);\n    (_b = c()) == null ? void 0 : __privateMethod(_b, _Foo_instances, method_fn).call(_b, x);\n    (_d = __privateMethod(_c = d(), _Foo_instances, method_fn)) == null ? void 0 : _d.call(_c, x);\n    (_f = (_e = e()) == null ? void 0 : __privateMethod(_e, _Foo_instances, method_fn)) == null ? void 0 : _f.call(_e, x);\n    (_g = f()) == null ? void 0 : __privateMethod(_h = _g.foo, _Foo_instances, method_fn).call(_h, x).bar();\n  }\n};\n_field = new WeakMap();\n_Foo_instances = new WeakSet();\nmethod_fn = function() {\n};\nexport {\n  Foo\n};\n\n================================================================================\nTestLowerPrivateMethod2020\n---------- /out.js ----------\n// entry.js\nvar _field, _Foo_instances, method_fn;\nvar Foo = class {\n  constructor() {\n    __privateAdd(this, _Foo_instances);\n    __privateAdd(this, _field);\n  }\n  baseline() {\n    a().foo;\n    b().foo(x);\n    c()?.foo(x);\n    d().foo?.(x);\n    e()?.foo?.(x);\n  }\n  privateField() {\n    var _a, _b, _c, _d, _e, _f, _g;\n    __privateGet(a(), _field);\n    __privateGet(_a = b(), _field).call(_a, x);\n    (_b = c()) == null ? void 0 : __privateGet(_b, _field).call(_b, x);\n    (_d = __privateGet(_c = d(), _field)) == null ? void 0 : _d.call(_c, x);\n    ((_e = e()) == null ? void 0 : __privateGet(_e, _field))?.(x);\n    (_f = f()) == null ? void 0 : __privateGet(_g = _f.foo, _field).call(_g, x).bar();\n  }\n  privateMethod() {\n    var _a, _b, _c, _d, _e, _f, _g;\n    __privateMethod(a(), _Foo_instances, method_fn);\n    __privateMethod(_a = b(), _Foo_instances, method_fn).call(_a, x);\n    (_b = c()) == null ? void 0 : __privateMethod(_b, _Foo_instances, method_fn).call(_b, x);\n    (_d = __privateMethod(_c = d(), _Foo_instances, method_fn)) == null ? void 0 : _d.call(_c, x);\n    ((_e = e()) == null ? void 0 : __privateMethod(_e, _Foo_instances, method_fn))?.(x);\n    (_f = f()) == null ? void 0 : __privateMethod(_g = _f.foo, _Foo_instances, method_fn).call(_g, x).bar();\n  }\n};\n_field = new WeakMap();\n_Foo_instances = new WeakSet();\nmethod_fn = function() {\n};\nexport {\n  Foo\n};\n\n================================================================================\nTestLowerPrivateMethodNext\n---------- /out.js ----------\n// entry.js\nvar Foo = class {\n  #field;\n  #method() {\n  }\n  baseline() {\n    a().foo;\n    b().foo(x);\n    c()?.foo(x);\n    d().foo?.(x);\n    e()?.foo?.(x);\n  }\n  privateField() {\n    a().#field;\n    b().#field(x);\n    c()?.#field(x);\n    d().#field?.(x);\n    e()?.#field?.(x);\n    f()?.foo.#field(x).bar();\n  }\n  privateMethod() {\n    a().#method;\n    b().#method(x);\n    c()?.#method(x);\n    d().#method?.(x);\n    e()?.#method?.(x);\n    f()?.foo.#method(x).bar();\n  }\n};\nexport {\n  Foo\n};\n\n================================================================================\nTestLowerPrivateMethodWithModifiers2020\n---------- /out.js ----------\n// entry.js\nvar _Foo_instances, g_fn, a_fn, ag_fn, _Foo_static, sg_fn, sa_fn, sag_fn;\nvar Foo = class {\n  constructor() {\n    __privateAdd(this, _Foo_instances);\n  }\n};\n_Foo_instances = new WeakSet();\ng_fn = function* () {\n};\na_fn = async function() {\n};\nag_fn = async function* () {\n};\n_Foo_static = new WeakSet();\nsg_fn = function* () {\n};\nsa_fn = async function() {\n};\nsag_fn = async function* () {\n};\n__privateAdd(Foo, _Foo_static);\nexport {\n  Foo\n};\n\n================================================================================\nTestLowerPrivateSuperES2021\n---------- /out.js ----------\n// foo1.js\nvar _default_instances, foo_fn;\nvar _foo1_default = class _foo1_default extends x {\n  constructor() {\n    super(...arguments);\n    __privateAdd(this, _default_instances);\n  }\n};\n_default_instances = new WeakSet();\nfoo_fn = function() {\n  __superGet(_foo1_default.prototype, this, \"foo\").call(this);\n};\nvar foo1_default = _foo1_default;\n\n// foo2.js\nvar _default_instances2, foo_fn2;\nvar _foo2_default = class _foo2_default extends x {\n  constructor() {\n    super(...arguments);\n    __privateAdd(this, _default_instances2);\n  }\n};\n_default_instances2 = new WeakSet();\nfoo_fn2 = function() {\n  __superWrapper(_foo2_default.prototype, this, \"foo\")._++;\n};\nvar foo2_default = _foo2_default;\n\n// foo3.js\nvar _default_static, foo_fn3;\nvar _foo3_default = class _foo3_default extends x {\n};\n_default_static = new WeakSet();\nfoo_fn3 = function() {\n  __superGet(_foo3_default, this, \"foo\").call(this);\n};\n__privateAdd(_foo3_default, _default_static);\nvar foo3_default = _foo3_default;\n\n// foo4.js\nvar _default_static2, foo_fn4;\nvar _foo4_default = class _foo4_default extends x {\n};\n_default_static2 = new WeakSet();\nfoo_fn4 = function() {\n  __superWrapper(_foo4_default, this, \"foo\")._++;\n};\n__privateAdd(_foo4_default, _default_static2);\nvar foo4_default = _foo4_default;\n\n// foo5.js\nvar _foo;\nvar foo5_default = class extends x {\n  constructor() {\n    super(...arguments);\n    __privateAdd(this, _foo, () => {\n      super.foo();\n    });\n  }\n};\n_foo = new WeakMap();\n\n// foo6.js\nvar _foo2;\nvar foo6_default = class extends x {\n  constructor() {\n    super(...arguments);\n    __privateAdd(this, _foo2, () => {\n      super.foo++;\n    });\n  }\n};\n_foo2 = new WeakMap();\n\n// foo7.js\nvar _foo3;\nvar _foo7_default = class _foo7_default extends x {\n};\n_foo3 = new WeakMap();\n__privateAdd(_foo7_default, _foo3, () => {\n  __superGet(_foo7_default, _foo7_default, \"foo\").call(this);\n});\nvar foo7_default = _foo7_default;\n\n// foo8.js\nvar _foo4;\nvar _foo8_default = class _foo8_default extends x {\n};\n_foo4 = new WeakMap();\n__privateAdd(_foo8_default, _foo4, () => {\n  __superWrapper(_foo8_default, _foo8_default, \"foo\")._++;\n});\nvar foo8_default = _foo8_default;\nexport {\n  foo1_default as foo1,\n  foo2_default as foo2,\n  foo3_default as foo3,\n  foo4_default as foo4,\n  foo5_default as foo5,\n  foo6_default as foo6,\n  foo7_default as foo7,\n  foo8_default as foo8\n};\n\n================================================================================\nTestLowerPrivateSuperES2022\n---------- /out.js ----------\n// foo1.js\nvar foo1_default = class extends x {\n  #foo() {\n    super.foo();\n  }\n};\n\n// foo2.js\nvar foo2_default = class extends x {\n  #foo() {\n    super.foo++;\n  }\n};\n\n// foo3.js\nvar foo3_default = class extends x {\n  static #foo() {\n    super.foo();\n  }\n};\n\n// foo4.js\nvar foo4_default = class extends x {\n  static #foo() {\n    super.foo++;\n  }\n};\n\n// foo5.js\nvar foo5_default = class extends x {\n  #foo = () => {\n    super.foo();\n  };\n};\n\n// foo6.js\nvar foo6_default = class extends x {\n  #foo = () => {\n    super.foo++;\n  };\n};\n\n// foo7.js\nvar foo7_default = class extends x {\n  static #foo = () => {\n    super.foo();\n  };\n};\n\n// foo8.js\nvar foo8_default = class extends x {\n  static #foo = () => {\n    super.foo++;\n  };\n};\nexport {\n  foo1_default as foo1,\n  foo2_default as foo2,\n  foo3_default as foo3,\n  foo4_default as foo4,\n  foo5_default as foo5,\n  foo6_default as foo6,\n  foo7_default as foo7,\n  foo8_default as foo8\n};\n\n================================================================================\nTestLowerPrivateSuperStaticBundleIssue2158\n---------- /out.js ----------\n// entry.js\nvar Foo = class extends Object {\n  static FOO;\n  constructor() {\n    super();\n  }\n  #foo;\n};\nexport {\n  Foo\n};\n\n================================================================================\nTestLowerRegExpNameCollision\n---------- /out.js ----------\n// entry.js\nfunction foo(RegExp2) {\n  return new RegExp2(new RegExp(\".\", \"d\"), \"d\");\n}\nexport {\n  foo\n};\n\n================================================================================\nTestLowerStaticAsyncArrowSuperES2016\n---------- /out.js ----------\n// foo1.js\nvar foo1_default = class _foo1_default extends x {\n  static foo1() {\n    return () => __async(null, null, function* () {\n      return __superGet(_foo1_default, this, \"foo\").call(this, \"foo1\");\n    });\n  }\n};\n\n// foo2.js\nvar foo2_default = class _foo2_default extends x {\n  static foo2() {\n    return () => __async(null, null, function* () {\n      return () => __superGet(_foo2_default, this, \"foo\").call(this, \"foo2\");\n    });\n  }\n};\n\n// foo3.js\nvar foo3_default = class _foo3_default extends x {\n  static foo3() {\n    return () => () => __async(null, null, function* () {\n      return __superGet(_foo3_default, this, \"foo\").call(this, \"foo3\");\n    });\n  }\n};\n\n// foo4.js\nvar foo4_default = class _foo4_default extends x {\n  static foo4() {\n    return () => __async(null, null, function* () {\n      return () => __async(null, null, function* () {\n        return __superGet(_foo4_default, this, \"foo\").call(this, \"foo4\");\n      });\n    });\n  }\n};\n\n// bar1.js\nvar _bar1_default = class _bar1_default extends x {\n};\n__publicField(_bar1_default, \"bar1\", () => __async(null, null, function* () {\n  return __superGet(_bar1_default, _bar1_default, \"foo\").call(this, \"bar1\");\n}));\nvar bar1_default = _bar1_default;\n\n// bar2.js\nvar _bar2_default = class _bar2_default extends x {\n};\n__publicField(_bar2_default, \"bar2\", () => __async(null, null, function* () {\n  return () => __superGet(_bar2_default, _bar2_default, \"foo\").call(this, \"bar2\");\n}));\nvar bar2_default = _bar2_default;\n\n// bar3.js\nvar _bar3_default = class _bar3_default extends x {\n};\n__publicField(_bar3_default, \"bar3\", () => () => __async(null, null, function* () {\n  return __superGet(_bar3_default, _bar3_default, \"foo\").call(this, \"bar3\");\n}));\nvar bar3_default = _bar3_default;\n\n// bar4.js\nvar _bar4_default = class _bar4_default extends x {\n};\n__publicField(_bar4_default, \"bar4\", () => __async(null, null, function* () {\n  return () => __async(null, null, function* () {\n    return __superGet(_bar4_default, _bar4_default, \"foo\").call(this, \"bar4\");\n  });\n}));\nvar bar4_default = _bar4_default;\n\n// baz1.js\nvar baz1_default = class _baz1_default extends x {\n  static baz1() {\n    return __async(this, null, function* () {\n      return () => __superGet(_baz1_default, this, \"foo\").call(this, \"baz1\");\n    });\n  }\n};\n\n// baz2.js\nvar baz2_default = class _baz2_default extends x {\n  static baz2() {\n    return __async(this, null, function* () {\n      return () => () => __superGet(_baz2_default, this, \"foo\").call(this, \"baz2\");\n    });\n  }\n};\n\n// outer.js\nvar outer_default = (function() {\n  return __async(this, null, function* () {\n    const _y = class _y extends z {\n    };\n    __publicField(_y, \"foo\", () => __async(null, null, function* () {\n      return __superGet(_y, _y, \"foo\").call(this);\n    }));\n    let y = _y;\n    yield y.foo()();\n  });\n})();\nexport {\n  bar1_default as bar1,\n  bar2_default as bar2,\n  bar3_default as bar3,\n  bar4_default as bar4,\n  baz1_default as baz1,\n  baz2_default as baz2,\n  foo1_default as foo1,\n  foo2_default as foo2,\n  foo3_default as foo3,\n  foo4_default as foo4\n};\n\n================================================================================\nTestLowerStaticAsyncArrowSuperSetterES2016\n---------- /out.js ----------\n// foo1.js\nvar foo1_default = class _foo1_default extends x {\n  static foo1() {\n    return () => __async(null, null, function* () {\n      return __superSet(_foo1_default, this, \"foo\", \"foo1\");\n    });\n  }\n};\n\n// foo2.js\nvar foo2_default = class _foo2_default extends x {\n  static foo2() {\n    return () => __async(null, null, function* () {\n      return () => __superSet(_foo2_default, this, \"foo\", \"foo2\");\n    });\n  }\n};\n\n// foo3.js\nvar foo3_default = class _foo3_default extends x {\n  static foo3() {\n    return () => () => __async(null, null, function* () {\n      return __superSet(_foo3_default, this, \"foo\", \"foo3\");\n    });\n  }\n};\n\n// foo4.js\nvar foo4_default = class _foo4_default extends x {\n  static foo4() {\n    return () => __async(null, null, function* () {\n      return () => __async(null, null, function* () {\n        return __superSet(_foo4_default, this, \"foo\", \"foo4\");\n      });\n    });\n  }\n};\n\n// bar1.js\nvar _bar1_default = class _bar1_default extends x {\n};\n__publicField(_bar1_default, \"bar1\", () => __async(null, null, function* () {\n  return __superSet(_bar1_default, _bar1_default, \"foo\", \"bar1\");\n}));\nvar bar1_default = _bar1_default;\n\n// bar2.js\nvar _bar2_default = class _bar2_default extends x {\n};\n__publicField(_bar2_default, \"bar2\", () => __async(null, null, function* () {\n  return () => __superSet(_bar2_default, _bar2_default, \"foo\", \"bar2\");\n}));\nvar bar2_default = _bar2_default;\n\n// bar3.js\nvar _bar3_default = class _bar3_default extends x {\n};\n__publicField(_bar3_default, \"bar3\", () => () => __async(null, null, function* () {\n  return __superSet(_bar3_default, _bar3_default, \"foo\", \"bar3\");\n}));\nvar bar3_default = _bar3_default;\n\n// bar4.js\nvar _bar4_default = class _bar4_default extends x {\n};\n__publicField(_bar4_default, \"bar4\", () => __async(null, null, function* () {\n  return () => __async(null, null, function* () {\n    return __superSet(_bar4_default, _bar4_default, \"foo\", \"bar4\");\n  });\n}));\nvar bar4_default = _bar4_default;\n\n// baz1.js\nvar baz1_default = class _baz1_default extends x {\n  static baz1() {\n    return __async(this, null, function* () {\n      return () => __superSet(_baz1_default, this, \"foo\", \"baz1\");\n    });\n  }\n};\n\n// baz2.js\nvar baz2_default = class _baz2_default extends x {\n  static baz2() {\n    return __async(this, null, function* () {\n      return () => () => __superSet(_baz2_default, this, \"foo\", \"baz2\");\n    });\n  }\n};\n\n// outer.js\nvar outer_default = (function() {\n  return __async(this, null, function* () {\n    const _y = class _y extends z {\n    };\n    __publicField(_y, \"foo\", () => __async(null, null, function* () {\n      return __superSet(_y, _y, \"foo\", \"foo\");\n    }));\n    let y = _y;\n    yield y.foo()();\n  });\n})();\nexport {\n  bar1_default as bar1,\n  bar2_default as bar2,\n  bar3_default as bar3,\n  bar4_default as bar4,\n  baz1_default as baz1,\n  baz2_default as baz2,\n  foo1_default as foo1,\n  foo2_default as foo2,\n  foo3_default as foo3,\n  foo4_default as foo4\n};\n\n================================================================================\nTestLowerStaticAsyncSuperES2016NoBundle\n---------- /out.js ----------\nconst _Derived = class _Derived extends Base {\n};\n__publicField(_Derived, \"test\", (key) => __async(null, null, function* () {\n  var _a, _b, _c, _d;\n  return [\n    yield __superGet(_Derived, _Derived, \"foo\"),\n    yield __superGet(_Derived, _Derived, key),\n    yield [__superWrapper(_Derived, _Derived, \"foo\")._] = [0],\n    yield [__superWrapper(_Derived, _Derived, key)._] = [0],\n    yield __superSet(_Derived, _Derived, \"foo\", 1),\n    yield __superSet(_Derived, _Derived, key, 1),\n    yield __superSet(_Derived, _Derived, \"foo\", __superGet(_Derived, _Derived, \"foo\") + 2),\n    yield __superSet(_Derived, _Derived, key, __superGet(_Derived, _Derived, key) + 2),\n    yield ++__superWrapper(_Derived, _Derived, \"foo\")._,\n    yield ++__superWrapper(_Derived, _Derived, key)._,\n    yield __superWrapper(_Derived, _Derived, \"foo\")._++,\n    yield __superWrapper(_Derived, _Derived, key)._++,\n    yield __superGet(_Derived, _Derived, \"foo\").name,\n    yield __superGet(_Derived, _Derived, key).name,\n    yield (_a = __superGet(_Derived, _Derived, \"foo\")) == null ? void 0 : _a.name,\n    yield (_b = __superGet(_Derived, _Derived, key)) == null ? void 0 : _b.name,\n    yield __superGet(_Derived, _Derived, \"foo\").call(this, 1, 2),\n    yield __superGet(_Derived, _Derived, key).call(this, 1, 2),\n    yield (_c = __superGet(_Derived, _Derived, \"foo\")) == null ? void 0 : _c.call(this, 1, 2),\n    yield (_d = __superGet(_Derived, _Derived, key)) == null ? void 0 : _d.call(this, 1, 2),\n    yield (() => __superGet(_Derived, _Derived, \"foo\"))(),\n    yield (() => __superGet(_Derived, _Derived, key))(),\n    yield (() => __superGet(_Derived, _Derived, \"foo\").call(this))(),\n    yield (() => __superGet(_Derived, _Derived, key).call(this))(),\n    yield __superGet(_Derived, _Derived, \"foo\").bind(this)``,\n    yield __superGet(_Derived, _Derived, key).bind(this)``\n  ];\n}));\nlet Derived = _Derived;\nlet fn = () => __async(null, null, function* () {\n  var _a;\n  return _a = class extends Base {\n    static c() {\n      return super.c;\n    }\n    static d() {\n      return () => super.d;\n    }\n  }, __publicField(_a, \"a\", __superGet(_a, _a, \"a\")), __publicField(_a, \"b\", () => __superGet(_a, _a, \"b\")), _a;\n});\nconst _Derived2 = class _Derived2 extends Base {\n  static a() {\n    return __async(this, null, function* () {\n      var _a;\n      return _a = __superGet(_Derived2, this, \"foo\"), class {\n        constructor() {\n          __publicField(this, _a, 123);\n        }\n      };\n    });\n  }\n};\n__publicField(_Derived2, \"b\", () => __async(null, null, function* () {\n  var _a;\n  return _a = __superGet(_Derived2, _Derived2, \"foo\"), class {\n    constructor() {\n      __publicField(this, _a, 123);\n    }\n  };\n}));\nlet Derived2 = _Derived2;\n\n================================================================================\nTestLowerStaticAsyncSuperES2021NoBundle\n---------- /out.js ----------\nconst _Derived = class _Derived extends Base {\n};\n__publicField(_Derived, \"test\", async (key) => {\n  return [\n    await __superGet(_Derived, _Derived, \"foo\"),\n    await __superGet(_Derived, _Derived, key),\n    await ([__superWrapper(_Derived, _Derived, \"foo\")._] = [0]),\n    await ([__superWrapper(_Derived, _Derived, key)._] = [0]),\n    await __superSet(_Derived, _Derived, \"foo\", 1),\n    await __superSet(_Derived, _Derived, key, 1),\n    await __superSet(_Derived, _Derived, \"foo\", __superGet(_Derived, _Derived, \"foo\") + 2),\n    await __superSet(_Derived, _Derived, key, __superGet(_Derived, _Derived, key) + 2),\n    await ++__superWrapper(_Derived, _Derived, \"foo\")._,\n    await ++__superWrapper(_Derived, _Derived, key)._,\n    await __superWrapper(_Derived, _Derived, \"foo\")._++,\n    await __superWrapper(_Derived, _Derived, key)._++,\n    await __superGet(_Derived, _Derived, \"foo\").name,\n    await __superGet(_Derived, _Derived, key).name,\n    await __superGet(_Derived, _Derived, \"foo\")?.name,\n    await __superGet(_Derived, _Derived, key)?.name,\n    await __superGet(_Derived, _Derived, \"foo\").call(this, 1, 2),\n    await __superGet(_Derived, _Derived, key).call(this, 1, 2),\n    await super.foo?.(1, 2),\n    await super[key]?.(1, 2),\n    await (() => __superGet(_Derived, _Derived, \"foo\"))(),\n    await (() => __superGet(_Derived, _Derived, key))(),\n    await (() => __superGet(_Derived, _Derived, \"foo\").call(this))(),\n    await (() => __superGet(_Derived, _Derived, key).call(this))(),\n    await __superGet(_Derived, _Derived, \"foo\").bind(this)``,\n    await __superGet(_Derived, _Derived, key).bind(this)``\n  ];\n});\nlet Derived = _Derived;\nlet fn = async () => {\n  var _a;\n  return _a = class extends Base {\n    static c() {\n      return super.c;\n    }\n    static d() {\n      return () => super.d;\n    }\n  }, __publicField(_a, \"a\", __superGet(_a, _a, \"a\")), __publicField(_a, \"b\", () => __superGet(_a, _a, \"b\")), _a;\n};\nconst _Derived2 = class _Derived2 extends Base {\n  static async a() {\n    var _a;\n    return _a = super.foo, class {\n      constructor() {\n        __publicField(this, _a, 123);\n      }\n    };\n  }\n};\n__publicField(_Derived2, \"b\", async () => {\n  var _a;\n  return _a = __superGet(_Derived2, _Derived2, \"foo\"), class {\n    constructor() {\n      __publicField(this, _a, 123);\n    }\n  };\n});\nlet Derived2 = _Derived2;\n\n================================================================================\nTestLowerStaticSuperES2016NoBundle\n---------- /out.js ----------\nconst _Derived = class _Derived extends Base {\n};\n__publicField(_Derived, \"test\", (key) => {\n  var _a, _b, _c, _d;\n  return [\n    __superGet(_Derived, _Derived, \"foo\"),\n    __superGet(_Derived, _Derived, key),\n    [__superWrapper(_Derived, _Derived, \"foo\")._] = [0],\n    [__superWrapper(_Derived, _Derived, key)._] = [0],\n    __superSet(_Derived, _Derived, \"foo\", 1),\n    __superSet(_Derived, _Derived, key, 1),\n    __superSet(_Derived, _Derived, \"foo\", __superGet(_Derived, _Derived, \"foo\") + 2),\n    __superSet(_Derived, _Derived, key, __superGet(_Derived, _Derived, key) + 2),\n    ++__superWrapper(_Derived, _Derived, \"foo\")._,\n    ++__superWrapper(_Derived, _Derived, key)._,\n    __superWrapper(_Derived, _Derived, \"foo\")._++,\n    __superWrapper(_Derived, _Derived, key)._++,\n    __superGet(_Derived, _Derived, \"foo\").name,\n    __superGet(_Derived, _Derived, key).name,\n    (_a = __superGet(_Derived, _Derived, \"foo\")) == null ? void 0 : _a.name,\n    (_b = __superGet(_Derived, _Derived, key)) == null ? void 0 : _b.name,\n    __superGet(_Derived, _Derived, \"foo\").call(this, 1, 2),\n    __superGet(_Derived, _Derived, key).call(this, 1, 2),\n    (_c = __superGet(_Derived, _Derived, \"foo\")) == null ? void 0 : _c.call(this, 1, 2),\n    (_d = __superGet(_Derived, _Derived, key)) == null ? void 0 : _d.call(this, 1, 2),\n    (() => __superGet(_Derived, _Derived, \"foo\"))(),\n    (() => __superGet(_Derived, _Derived, key))(),\n    (() => __superGet(_Derived, _Derived, \"foo\").call(this))(),\n    (() => __superGet(_Derived, _Derived, key).call(this))(),\n    __superGet(_Derived, _Derived, \"foo\").bind(this)``,\n    __superGet(_Derived, _Derived, key).bind(this)``\n  ];\n});\nlet Derived = _Derived;\n\n================================================================================\nTestLowerStaticSuperES2021NoBundle\n---------- /out.js ----------\nconst _Derived = class _Derived extends Base {\n};\n__publicField(_Derived, \"test\", (key) => {\n  return [\n    __superGet(_Derived, _Derived, \"foo\"),\n    __superGet(_Derived, _Derived, key),\n    [__superWrapper(_Derived, _Derived, \"foo\")._] = [0],\n    [__superWrapper(_Derived, _Derived, key)._] = [0],\n    __superSet(_Derived, _Derived, \"foo\", 1),\n    __superSet(_Derived, _Derived, key, 1),\n    __superSet(_Derived, _Derived, \"foo\", __superGet(_Derived, _Derived, \"foo\") + 2),\n    __superSet(_Derived, _Derived, key, __superGet(_Derived, _Derived, key) + 2),\n    ++__superWrapper(_Derived, _Derived, \"foo\")._,\n    ++__superWrapper(_Derived, _Derived, key)._,\n    __superWrapper(_Derived, _Derived, \"foo\")._++,\n    __superWrapper(_Derived, _Derived, key)._++,\n    __superGet(_Derived, _Derived, \"foo\").name,\n    __superGet(_Derived, _Derived, key).name,\n    __superGet(_Derived, _Derived, \"foo\")?.name,\n    __superGet(_Derived, _Derived, key)?.name,\n    __superGet(_Derived, _Derived, \"foo\").call(this, 1, 2),\n    __superGet(_Derived, _Derived, key).call(this, 1, 2),\n    super.foo?.(1, 2),\n    super[key]?.(1, 2),\n    (() => __superGet(_Derived, _Derived, \"foo\"))(),\n    (() => __superGet(_Derived, _Derived, key))(),\n    (() => __superGet(_Derived, _Derived, \"foo\").call(this))(),\n    (() => __superGet(_Derived, _Derived, key).call(this))(),\n    __superGet(_Derived, _Derived, \"foo\").bind(this)``,\n    __superGet(_Derived, _Derived, key).bind(this)``\n  ];\n});\nlet Derived = _Derived;\n\n================================================================================\nTestLowerStrictModeSyntax\n---------- /out.js ----------\n// for-in.js\nif (test) {\n  a = b;\n  for (a in {}) ;\n}\nvar a;\nx = y;\nfor (x in {}) ;\nvar x;\n\n================================================================================\nTestLowerTemplateObject\n---------- /out.js ----------\nvar _a, _b, _c, _d, _e, _f, _g, _h;\nx = () => [\n  tag(_a || (_a = __template([\"x\"]))),\n  tag(_b || (_b = __template([\"ÿ\"], [\"\\\\xFF\"]))),\n  tag(_c || (_c = __template([void 0], [\"\\\\x\"]))),\n  tag(_d || (_d = __template([void 0], [\"\\\\u\"])))\n];\ny = () => [\n  tag(_e || (_e = __template([\"x\", \"z\"])), y),\n  tag(_f || (_f = __template([\"ÿ\", \"z\"], [\"\\\\xFF\", \"z\"])), y),\n  tag(_g || (_g = __template([\"x\", \"z\"], [\"x\", \"\\\\z\"])), y),\n  tag(_h || (_h = __template([\"x\", void 0], [\"x\", \"\\\\u\"])), y)\n];\n\n================================================================================\nTestLowerUsing\n---------- /out/entry.js ----------\nfunction foo() {\n  var _stack4 = [];\n  try {\n    const a2 = __using(_stack4, b);\n    if (nested) {\n      var _stack3 = [];\n      try {\n        const x = __using(_stack3, 1);\n      } catch (_3) {\n        var _error3 = _3, _hasError3 = true;\n      } finally {\n        __callDispose(_stack3, _error3, _hasError3);\n      }\n    }\n  } catch (_4) {\n    var _error4 = _4, _hasError4 = true;\n  } finally {\n    __callDispose(_stack4, _error4, _hasError4);\n  }\n}\nasync function bar() {\n  var _stack4 = [];\n  try {\n    const a2 = __using(_stack4, b);\n    const c2 = __using(_stack4, d, true);\n    if (nested) {\n      var _stack3 = [];\n      try {\n        const x = __using(_stack3, 1);\n        const y = __using(_stack3, 2, true);\n      } catch (_3) {\n        var _error3 = _3, _hasError3 = true;\n      } finally {\n        var _promise3 = __callDispose(_stack3, _error3, _hasError3);\n        _promise3 && await _promise3;\n      }\n    }\n  } catch (_4) {\n    var _error4 = _4, _hasError4 = true;\n  } finally {\n    var _promise4 = __callDispose(_stack4, _error4, _hasError4);\n    _promise4 && await _promise4;\n  }\n}\nvar _stack2 = [];\ntry {\n  var a = __using(_stack2, b);\n  var c = __using(_stack2, d, true);\n  if (nested) {\n    var _stack = [];\n    try {\n      const x = __using(_stack, 1);\n      const y = __using(_stack, 2, true);\n    } catch (_) {\n      var _error = _, _hasError = true;\n    } finally {\n      var _promise = __callDispose(_stack, _error, _hasError);\n      _promise && await _promise;\n    }\n  }\n} catch (_2) {\n  var _error2 = _2, _hasError2 = true;\n} finally {\n  var _promise2 = __callDispose(_stack2, _error2, _hasError2);\n  _promise2 && await _promise2;\n}\n\n---------- /out/loops.js ----------\nfor (var _a of b) {\n  var _stack = [];\n  try {\n    const a = __using(_stack, _a);\n    c(() => a);\n  } catch (_) {\n    var _error = _, _hasError = true;\n  } finally {\n    __callDispose(_stack, _error, _hasError);\n  }\n}\nfor (var _d of e) {\n  var _stack2 = [];\n  try {\n    const d = __using(_stack2, _d, true);\n    f(() => d);\n  } catch (_2) {\n    var _error2 = _2, _hasError2 = true;\n  } finally {\n    var _promise = __callDispose(_stack2, _error2, _hasError2);\n    _promise && await _promise;\n  }\n}\nfor await (var _g of h) {\n  var _stack3 = [];\n  try {\n    const g = __using(_stack3, _g);\n    i(() => g);\n  } catch (_3) {\n    var _error3 = _3, _hasError3 = true;\n  } finally {\n    __callDispose(_stack3, _error3, _hasError3);\n  }\n}\nfor await (var _j of k) {\n  var _stack4 = [];\n  try {\n    const j = __using(_stack4, _j, true);\n    l(() => j);\n  } catch (_4) {\n    var _error4 = _4, _hasError4 = true;\n  } finally {\n    var _promise2 = __callDispose(_stack4, _error4, _hasError4);\n    _promise2 && await _promise2;\n  }\n}\nif (nested) {\n  for (var _a of b) {\n    var _stack5 = [];\n    try {\n      const a = __using(_stack5, _a);\n      c(() => a);\n    } catch (_5) {\n      var _error5 = _5, _hasError5 = true;\n    } finally {\n      __callDispose(_stack5, _error5, _hasError5);\n    }\n  }\n  for (var _d of e) {\n    var _stack6 = [];\n    try {\n      const d = __using(_stack6, _d, true);\n      f(() => d);\n    } catch (_6) {\n      var _error6 = _6, _hasError6 = true;\n    } finally {\n      var _promise3 = __callDispose(_stack6, _error6, _hasError6);\n      _promise3 && await _promise3;\n    }\n  }\n  for await (var _g of h) {\n    var _stack7 = [];\n    try {\n      const g = __using(_stack7, _g);\n      i(() => g);\n    } catch (_7) {\n      var _error7 = _7, _hasError7 = true;\n    } finally {\n      __callDispose(_stack7, _error7, _hasError7);\n    }\n  }\n  for await (var _j of k) {\n    var _stack8 = [];\n    try {\n      const j = __using(_stack8, _j, true);\n      l(() => j);\n    } catch (_8) {\n      var _error8 = _8, _hasError8 = true;\n    } finally {\n      var _promise4 = __callDispose(_stack8, _error8, _hasError8);\n      _promise4 && await _promise4;\n    }\n  }\n}\nfunction foo() {\n  for (var _a of b) {\n    var _stack9 = [];\n    try {\n      const a = __using(_stack9, _a);\n      c(() => a);\n    } catch (_9) {\n      var _error9 = _9, _hasError9 = true;\n    } finally {\n      __callDispose(_stack9, _error9, _hasError9);\n    }\n  }\n}\nasync function bar() {\n  for (var _a of b) {\n    var _stack9 = [];\n    try {\n      const a = __using(_stack9, _a);\n      c(() => a);\n    } catch (_9) {\n      var _error9 = _9, _hasError9 = true;\n    } finally {\n      __callDispose(_stack9, _error9, _hasError9);\n    }\n  }\n  for (var _d of e) {\n    var _stack10 = [];\n    try {\n      const d = __using(_stack10, _d, true);\n      f(() => d);\n    } catch (_10) {\n      var _error10 = _10, _hasError10 = true;\n    } finally {\n      var _promise5 = __callDispose(_stack10, _error10, _hasError10);\n      _promise5 && await _promise5;\n    }\n  }\n  for await (var _g of h) {\n    var _stack11 = [];\n    try {\n      const g = __using(_stack11, _g);\n      i(() => g);\n    } catch (_11) {\n      var _error11 = _11, _hasError11 = true;\n    } finally {\n      __callDispose(_stack11, _error11, _hasError11);\n    }\n  }\n  for await (var _j of k) {\n    var _stack12 = [];\n    try {\n      const j = __using(_stack12, _j, true);\n      l(() => j);\n    } catch (_12) {\n      var _error12 = _12, _hasError12 = true;\n    } finally {\n      var _promise6 = __callDispose(_stack12, _error12, _hasError12);\n      _promise6 && await _promise6;\n    }\n  }\n}\n\n================================================================================\nTestLowerUsingHoisting\n---------- /out/hoist-use-strict.js ----------\n\"use strict\";\nfunction foo() {\n  \"use strict\";\n  var _stack2 = [];\n  try {\n    const a2 = __using(_stack2, b);\n  } catch (_2) {\n    var _error2 = _2, _hasError2 = true;\n  } finally {\n    __callDispose(_stack2, _error2, _hasError2);\n  }\n}\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\n\n---------- /out/hoist-directive.js ----------\n\"use wtf\";\nfunction foo() {\n  \"use wtf\";\n  var _stack2 = [];\n  try {\n    const a2 = __using(_stack2, b);\n  } catch (_2) {\n    var _error2 = _2, _hasError2 = true;\n  } finally {\n    __callDispose(_stack2, _error2, _hasError2);\n  }\n}\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\n\n---------- /out/hoist-import.js ----------\nimport \"./foo\";\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\n\n---------- /out/hoist-export-star.js ----------\nexport * from \"./foo\";\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\n\n---------- /out/hoist-export-from.js ----------\nexport { x, y } from \"./foo\";\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\n\n---------- /out/hoist-export-clause.js ----------\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\nexport {\n  a,\n  c as \"c!\"\n};\n\n---------- /out/hoist-export-local-direct.js ----------\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var ac1 = [a, c], { x: [x1] } = foo;\n  var a1 = a, { y: [y1] } = foo;\n  var c1 = c, { z: [z1] } = foo;\n  var ac2 = [a, c], { x: [x2] } = foo;\n  var a2 = a, { y: [y2] } = foo;\n  var c2 = c, { z: [z2] } = foo;\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\nexport {\n  ac1,\n  x1,\n  a1,\n  y1,\n  c1,\n  z1\n};\n\n---------- /out/hoist-export-local-indirect.js ----------\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var ac1 = [a, c], { x: [x1] } = foo;\n  var a1 = a, { y: [y1] } = foo;\n  var c1 = c, { z: [z1] } = foo;\n  var ac2 = [a, c], { x: [x2] } = foo;\n  var a2 = a, { y: [y2] } = foo;\n  var c2 = c, { z: [z2] } = foo;\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\nexport {\n  x1,\n  y1,\n  z1\n};\n\n---------- /out/hoist-export-class-direct.js ----------\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var Foo1 = class {\n    ac = [a, c];\n  };\n  var Bar1 = class _Bar1 {\n    ac = [a, c, _Bar1];\n  };\n  var Foo2 = class {\n    ac = [a, c];\n  };\n  var Bar2 = class _Bar2 {\n    ac = [a, c, _Bar2];\n  };\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\nexport {\n  Foo1,\n  Bar1\n};\n\n---------- /out/hoist-export-class-indirect.js ----------\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var Foo1 = class {\n    ac = [a, c];\n  };\n  var Bar1 = class _Bar1 {\n    ac = [a, c, _Bar1];\n  };\n  var Foo2 = class {\n    ac = [a, c];\n  };\n  var Bar2 = class _Bar2 {\n    ac = [a, c, _Bar2];\n  };\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\nexport {\n  Foo1,\n  Bar1\n};\n\n---------- /out/hoist-export-function-direct.js ----------\nexport function foo1() {\n  return [a, c];\n}\nexport function bar1() {\n  return [a, c, bar1];\n}\nfunction foo2() {\n  return [a, c];\n}\nfunction bar2() {\n  return [a, c, bar2];\n}\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\n\n---------- /out/hoist-export-function-indirect.js ----------\nfunction foo1() {\n  return [a, c];\n}\nfunction bar1() {\n  return [a, c, bar1];\n}\nfunction foo2() {\n  return [a, c];\n}\nfunction bar2() {\n  return [a, c, bar2];\n}\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\nexport {\n  foo1,\n  bar1\n};\n\n---------- /out/hoist-export-default-class-name-unused.js ----------\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var Foo = class {\n    ac = [a, c];\n  };\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\nexport {\n  Foo as default\n};\n\n---------- /out/hoist-export-default-class-name-used.js ----------\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var Foo = class _Foo {\n    ac = [a, c, _Foo];\n  };\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\nexport {\n  Foo as default\n};\n\n---------- /out/hoist-export-default-class-anonymous.js ----------\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var hoist_export_default_class_anonymous_default = class {\n    ac = [a, c];\n  };\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\nexport {\n  hoist_export_default_class_anonymous_default as default\n};\n\n---------- /out/hoist-export-default-function-name-unused.js ----------\nexport default function foo() {\n  return [a, c];\n}\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\n\n---------- /out/hoist-export-default-function-name-used.js ----------\nexport default function foo() {\n  return [a, c, foo];\n}\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\n\n---------- /out/hoist-export-default-function-anonymous.js ----------\nexport default function() {\n  return [a, c];\n}\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\n\n---------- /out/hoist-export-default-expr.js ----------\nvar _stack = [];\ntry {\n  var a = __using(_stack, b);\n  var hoist_export_default_expr_default = [a, c];\n  var c = __using(_stack, d);\n} catch (_) {\n  var _error = _, _hasError = true;\n} finally {\n  __callDispose(_stack, _error, _hasError);\n}\nexport {\n  hoist_export_default_expr_default as default\n};\n\n================================================================================\nTestLowerUsingInsideTSNamespace\n---------- /out/entry.js ----------\nvar ns;\n((ns2) => {\n  var _stack = [];\n  try {\n    ns2.a = b;\n    const c = __using(_stack, d);\n    ns2.e = f;\n  } catch (_) {\n    var _error = _, _hasError = true;\n  } finally {\n    __callDispose(_stack, _error, _hasError);\n  }\n})(ns || (ns = {}));\n\n================================================================================\nTestLowerUsingUnsupportedAsync\n---------- /out/entry.js ----------\nfunction foo() {\n  using a = b;\n  if (nested) {\n    using x = 1;\n  }\n}\nfunction bar() {\n  return __async(this, null, function* () {\n    var _stack2 = [];\n    try {\n      const a = __using(_stack2, b);\n      const c = __using(_stack2, d, true);\n      if (nested) {\n        var _stack = [];\n        try {\n          const x = __using(_stack, 1);\n          const y = __using(_stack, 2, true);\n        } catch (_) {\n          var _error = _, _hasError = true;\n        } finally {\n          var _promise = __callDispose(_stack, _error, _hasError);\n          _promise && (yield _promise);\n        }\n      }\n    } catch (_2) {\n      var _error2 = _2, _hasError2 = true;\n    } finally {\n      var _promise2 = __callDispose(_stack2, _error2, _hasError2);\n      _promise2 && (yield _promise2);\n    }\n  });\n}\n\n---------- /out/loops.js ----------\nfor (using a of b) c(() => a);\nif (nested) {\n  for (using a of b) c(() => a);\n}\nfunction foo() {\n  for (using a of b) c(() => a);\n}\nfunction bar() {\n  return __async(this, null, function* () {\n    for (using a of b) c(() => a);\n    for (var _d of e) {\n      var _stack = [];\n      try {\n        const d = __using(_stack, _d, true);\n        f(() => d);\n      } catch (_) {\n        var _error = _, _hasError = true;\n      } finally {\n        var _promise = __callDispose(_stack, _error, _hasError);\n        _promise && (yield _promise);\n      }\n    }\n  });\n}\n\n================================================================================\nTestLowerUsingUnsupportedUsingAndAsync\n---------- /out/entry.js ----------\nfunction foo() {\n  var _stack2 = [];\n  try {\n    const a = __using(_stack2, b);\n    if (nested) {\n      var _stack = [];\n      try {\n        const x = __using(_stack, 1);\n      } catch (_) {\n        var _error = _, _hasError = true;\n      } finally {\n        __callDispose(_stack, _error, _hasError);\n      }\n    }\n  } catch (_2) {\n    var _error2 = _2, _hasError2 = true;\n  } finally {\n    __callDispose(_stack2, _error2, _hasError2);\n  }\n}\nfunction bar() {\n  return __async(this, null, function* () {\n    var _stack2 = [];\n    try {\n      const a = __using(_stack2, b);\n      const c = __using(_stack2, d, true);\n      if (nested) {\n        var _stack = [];\n        try {\n          const x = __using(_stack, 1);\n          const y = __using(_stack, 2, true);\n        } catch (_) {\n          var _error = _, _hasError = true;\n        } finally {\n          var _promise = __callDispose(_stack, _error, _hasError);\n          _promise && (yield _promise);\n        }\n      }\n    } catch (_2) {\n      var _error2 = _2, _hasError2 = true;\n    } finally {\n      var _promise2 = __callDispose(_stack2, _error2, _hasError2);\n      _promise2 && (yield _promise2);\n    }\n  });\n}\n\n---------- /out/loops.js ----------\nfor (var _a of b) {\n  var _stack = [];\n  try {\n    const a = __using(_stack, _a);\n    c(() => a);\n  } catch (_) {\n    var _error = _, _hasError = true;\n  } finally {\n    __callDispose(_stack, _error, _hasError);\n  }\n}\nif (nested) {\n  for (var _a of b) {\n    var _stack2 = [];\n    try {\n      const a = __using(_stack2, _a);\n      c(() => a);\n    } catch (_2) {\n      var _error2 = _2, _hasError2 = true;\n    } finally {\n      __callDispose(_stack2, _error2, _hasError2);\n    }\n  }\n}\nfunction foo() {\n  for (var _a of b) {\n    var _stack3 = [];\n    try {\n      const a = __using(_stack3, _a);\n      c(() => a);\n    } catch (_3) {\n      var _error3 = _3, _hasError3 = true;\n    } finally {\n      __callDispose(_stack3, _error3, _hasError3);\n    }\n  }\n}\nfunction bar() {\n  return __async(this, null, function* () {\n    for (var _a of b) {\n      var _stack3 = [];\n      try {\n        const a = __using(_stack3, _a);\n        c(() => a);\n      } catch (_3) {\n        var _error3 = _3, _hasError3 = true;\n      } finally {\n        __callDispose(_stack3, _error3, _hasError3);\n      }\n    }\n    for (var _d of e) {\n      var _stack4 = [];\n      try {\n        const d = __using(_stack4, _d, true);\n        f(() => d);\n      } catch (_4) {\n        var _error4 = _4, _hasError4 = true;\n      } finally {\n        var _promise = __callDispose(_stack4, _error4, _hasError4);\n        _promise && (yield _promise);\n      }\n    }\n  });\n}\n\n================================================================================\nTestStaticClassBlockES2021\n---------- /out.js ----------\n// entry.js\nvar _A = class _A {\n};\n_A.thisField++;\n_A.classField++;\n__superSet(_A, _A, \"superField\", __superGet(_A, _A, \"superField\") + 1);\n__superWrapper(_A, _A, \"superField\")._++;\nvar A = _A;\nvar _a;\nvar B = (_a = class {\n}, _a.thisField++, __superSet(_a, _a, \"superField\", __superGet(_a, _a, \"superField\") + 1), __superWrapper(_a, _a, \"superField\")._++, _a);\n\n================================================================================\nTestStaticClassBlockESNext\n---------- /out.js ----------\n// entry.js\nvar A = class _A {\n  static {\n  }\n  static {\n    this.thisField++;\n    _A.classField++;\n    super.superField = super.superField + 1;\n    super.superField++;\n  }\n};\nvar B = class {\n  static {\n  }\n  static {\n    this.thisField++;\n    super.superField = super.superField + 1;\n    super.superField++;\n  }\n};\n\n================================================================================\nTestTSLowerClassField2020NoBundle\n---------- /out.js ----------\nvar _foo, _bar, _s_foo, _s_bar;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _foo, 123);\n    __privateAdd(this, _bar);\n    this.foo = 123;\n  }\n}\n_foo = new WeakMap();\n_bar = new WeakMap();\n_s_foo = new WeakMap();\n_s_bar = new WeakMap();\n__privateAdd(Foo, _s_foo, 123);\n__privateAdd(Foo, _s_bar);\nFoo.s_foo = 123;\n\n================================================================================\nTestTSLowerClassFieldStrictTsconfigJson2020\n---------- /out.js ----------\n// loose/index.ts\nvar loose_default = class {\n};\n\n// strict/index.ts\nvar strict_default = class {\n  constructor() {\n    __publicField(this, \"foo\");\n  }\n};\n\n// entry.js\nconsole.log(loose_default, strict_default);\n\n================================================================================\nTestTSLowerClassPrivateFieldNextNoBundle\n---------- /out.js ----------\nclass Foo {\n  constructor() {\n    this.#foo = 123;\n    this.foo = 123;\n  }\n  #foo;\n  #bar;\n  static #s_foo = 123;\n  static #s_bar;\n  static {\n    this.s_foo = 123;\n  }\n}\n\n================================================================================\nTestTSLowerObjectRest2017NoBundle\n---------- /out.js ----------\nvar _q, _r, _t, _u, _v, _w, _x;\nconst local_const = __objRest({}, []);\nlet local_let = __objRest({}, []);\nvar local_var = __objRest({}, []);\nlet arrow_fn = (_a) => {\n  var x2 = __objRest(_a, []);\n};\nlet fn_expr = function(_b = default_value) {\n  var x2 = __objRest(_b, []);\n};\nlet class_expr = class {\n  method(x2, ..._c) {\n    var [y, _d] = _c, z = __objRest(_d, []);\n  }\n};\nfunction fn_stmt(_e, _g) {\n  var _f = _e, { a = b() } = _f, x2 = __objRest(_f, [\"a\"]);\n  var _h = _g, { c = d() } = _h, y = __objRest(_h, [\"c\"]);\n}\nclass class_stmt {\n  method(_i) {\n    var x2 = __objRest(_i, []);\n  }\n}\nvar ns;\n((ns2) => {\n  ns2.x = __objRest({}, []);\n})(ns || (ns = {}));\ntry {\n} catch (_j) {\n  let catch_clause = __objRest(_j, []);\n}\nfor (const _k in { abc }) {\n  const for_in_const = __objRest(_k, []);\n}\nfor (let _l in { abc }) {\n  let for_in_let = __objRest(_l, []);\n}\nfor (var _m in { abc }) {\n  var for_in_var = __objRest(_m, []);\n  ;\n}\nfor (const _n of [{}]) {\n  const for_of_const = __objRest(_n, []);\n  ;\n}\nfor (let _o of [{}]) {\n  let for_of_let = __objRest(_o, []);\n  x();\n}\nfor (var _p of [{}]) {\n  var for_of_var = __objRest(_p, []);\n  x();\n}\nfor (const for_const = __objRest({}, []); x; x = null) {\n}\nfor (let for_let = __objRest({}, []); x; x = null) {\n}\nfor (var for_var = __objRest({}, []); x; x = null) {\n}\nfor (_q in { abc }) {\n  x = __objRest(_q, []);\n}\nfor (_r of [{}]) {\n  x = __objRest(_r, []);\n}\nfor (x = __objRest({}, []); x; x = null) {\n}\nassign = __objRest({}, []);\n({ obj_method(_s) {\n  var x2 = __objRest(_s, []);\n} });\nx = __objRest(x, []);\nfor (x = __objRest(x, []); 0; ) ;\nconsole.log((x = __objRest(_t = x, []), _t));\nconsole.log((_v = _u = { x }, { x } = _v, xx = __objRest(_v, [\"x\"]), _u));\nconsole.log(({ x: _x } = _w = { x }, xx = __objRest(_x, []), _w));\n\n================================================================================\nTestTSLowerObjectRest2018NoBundle\n---------- /out.js ----------\nconst { ...local_const } = {};\nlet { ...local_let } = {};\nvar { ...local_var } = {};\nlet arrow_fn = ({ ...x2 }) => {\n};\nlet fn_expr = function({ ...x2 } = default_value) {\n};\nlet class_expr = class {\n  method(x2, ...[y, { ...z }]) {\n  }\n};\nfunction fn_stmt({ a = b(), ...x2 }, { c = d(), ...y }) {\n}\nclass class_stmt {\n  method({ ...x2 }) {\n  }\n}\nvar ns;\n((ns2) => {\n  ({ ...ns2.x } = {});\n})(ns || (ns = {}));\ntry {\n} catch ({ ...catch_clause }) {\n}\nfor (const { ...for_in_const } in { abc }) {\n}\nfor (let { ...for_in_let } in { abc }) {\n}\nfor (var { ...for_in_var } in { abc }) ;\nfor (const { ...for_of_const } of [{}]) ;\nfor (let { ...for_of_let } of [{}]) x();\nfor (var { ...for_of_var } of [{}]) x();\nfor (const { ...for_const } = {}; x; x = null) {\n}\nfor (let { ...for_let } = {}; x; x = null) {\n}\nfor (var { ...for_var } = {}; x; x = null) {\n}\nfor ({ ...x } in { abc }) {\n}\nfor ({ ...x } of [{}]) {\n}\nfor ({ ...x } = {}; x; x = null) {\n}\n({ ...assign } = {});\n({ obj_method({ ...x2 }) {\n} });\n({ ...x } = x);\nfor ({ ...x } = x; 0; ) ;\nconsole.log({ ...x } = x);\nconsole.log({ x, ...xx } = { x });\nconsole.log({ x: { ...xx } } = { x });\n\n================================================================================\nTestTSLowerPrivateFieldAndMethodAvoidNameCollision2015\n---------- /out.js ----------\n// entry.ts\nvar _x;\nvar WeakMap2 = class {\n  constructor() {\n    __privateAdd(this, _x);\n  }\n};\n_x = new WeakMap();\nvar _WeakSet_instances, y_fn;\nvar WeakSet2 = class {\n  constructor() {\n    __privateAdd(this, _WeakSet_instances);\n  }\n};\n_WeakSet_instances = new WeakSet();\ny_fn = function() {\n};\nexport {\n  WeakMap2 as WeakMap,\n  WeakSet2 as WeakSet\n};\n\n================================================================================\nTestTSLowerPrivateFieldOptionalChain2015NoBundle\n---------- /out.js ----------\nvar _x;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x);\n  }\n  foo() {\n    var _a;\n    this == null ? void 0 : __privateGet(this, _x).y;\n    this == null ? void 0 : __privateGet(this.y, _x);\n    (_a = __privateGet(this, _x)) == null ? void 0 : _a.y;\n  }\n}\n_x = new WeakMap();\n\n================================================================================\nTestTSLowerPrivateStaticMembers2015NoBundle\n---------- /out.js ----------\nvar _x, _Foo_static, y_get, y_set, z_fn;\nconst _Foo = class _Foo {\n  foo() {\n    var _a;\n    __privateSet(_Foo, _x, __privateGet(_Foo, _x) + 1);\n    __privateSet(_Foo, _Foo_static, __privateGet(_Foo, _Foo_static, y_get) + 1, y_set);\n    __privateMethod(_a = _Foo, _Foo_static, z_fn).call(_a);\n  }\n};\n_x = new WeakMap();\n_Foo_static = new WeakSet();\ny_get = function() {\n};\ny_set = function(x) {\n};\nz_fn = function() {\n};\n__privateAdd(_Foo, _Foo_static);\n__privateAdd(_Foo, _x);\nlet Foo = _Foo;\n"
  },
  {
    "path": "internal/bundler_tests/snapshots/snapshots_packagejson.txt",
    "content": "TestCommonJSVariableInESMTypeModule\n---------- /out.js ----------\n// entry.js\nmodule.exports = null;\n\n================================================================================\nTestConfusingNameCollisionsIssue4144\n---------- /out.js ----------\n// node_modules/mydependency/package/utils/utils.js\nfunction it() {\n  return works;\n}\n\n// node_modules/mydependency/package/index.js\nvar works = true;\n\n// entry.js\nconsole.log(it());\n\n================================================================================\nTestPackageJsonBadExportsDefaultWarningIssue3867\n---------- /out.js ----------\n\n================================================================================\nTestPackageJsonBadExportsImportAndRequireWarningIssue3867\n---------- /out.js ----------\n\n================================================================================\nTestPackageJsonBadMain\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/index.js\nvar require_demo_pkg = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/index.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_demo_pkg());\nconsole.log((0, import_demo_pkg.default)());\n\n================================================================================\nTestPackageJsonBrowserIndexNoExt\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/demo-pkg/no-ext-browser/index.js\nvar browser = \"browser\";\n\n// Users/user/project/src/demo-pkg/no-ext/index.js\nvar node = \"node\";\n\n// Users/user/project/src/demo-pkg/ext-browser/index.js\nvar browser2 = \"browser\";\n\n// Users/user/project/src/entry.js\nconsole.log(browser);\nconsole.log(node);\nconsole.log(browser2);\nconsole.log(browser2);\n\n================================================================================\nTestPackageJsonBrowserIssue2002A\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/node_modules/sub/bar.js\nvar require_bar = __commonJS({\n  \"Users/user/project/src/node_modules/sub/bar.js\"() {\n    works();\n  }\n});\n\n// Users/user/project/src/node_modules/pkg/sub/foo.js\nvar require_foo = __commonJS({\n  \"Users/user/project/src/node_modules/pkg/sub/foo.js\"() {\n    require_bar();\n  }\n});\n\n// Users/user/project/src/entry.js\nrequire_foo();\n\n================================================================================\nTestPackageJsonBrowserIssue2002B\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/node_modules/pkg/sub/bar.js\nvar require_bar = __commonJS({\n  \"Users/user/project/src/node_modules/pkg/sub/bar.js\"() {\n    works();\n  }\n});\n\n// Users/user/project/src/node_modules/pkg/sub/foo.js\nvar require_foo = __commonJS({\n  \"Users/user/project/src/node_modules/pkg/sub/foo.js\"() {\n    require_bar();\n  }\n});\n\n// Users/user/project/src/entry.js\nrequire_foo();\n\n================================================================================\nTestPackageJsonBrowserIssue2002C\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/node_modules/sub/index.js\nvar require_sub = __commonJS({\n  \"Users/user/project/src/node_modules/sub/index.js\"() {\n    works();\n  }\n});\n\n// Users/user/project/src/node_modules/pkg/sub/foo.js\nvar require_foo = __commonJS({\n  \"Users/user/project/src/node_modules/pkg/sub/foo.js\"() {\n    require_sub();\n  }\n});\n\n// Users/user/project/src/entry.js\nrequire_foo();\n\n================================================================================\nTestPackageJsonBrowserMapAvoidMissing\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/component-indexof/index.js\nvar require_component_indexof = __commonJS({\n  \"Users/user/project/node_modules/component-indexof/index.js\"(exports, module) {\n    module.exports = function() {\n      return 234;\n    };\n  }\n});\n\n// Users/user/project/node_modules/component-classes/index.js\ntry {\n  index = require_component_indexof();\n} catch (err) {\n  index = require_component_indexof();\n}\nvar index;\n\n================================================================================\nTestPackageJsonBrowserMapModuleDisabled\n---------- /Users/user/project/out.js ----------\n// (disabled):Users/user/project/node_modules/node-pkg/index.js\nvar require_node_pkg = __commonJS({\n  \"(disabled):Users/user/project/node_modules/node-pkg/index.js\"() {\n  }\n});\n\n// Users/user/project/node_modules/demo-pkg/index.js\nvar require_demo_pkg = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/index.js\"(exports, module) {\n    var fn2 = require_node_pkg();\n    module.exports = function() {\n      return fn2();\n    };\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_demo_pkg());\nconsole.log((0, import_demo_pkg.default)());\n\n================================================================================\nTestPackageJsonBrowserMapModuleToModule\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/node-pkg-browser/index.js\nvar require_node_pkg_browser = __commonJS({\n  \"Users/user/project/node_modules/node-pkg-browser/index.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// Users/user/project/node_modules/demo-pkg/index.js\nvar require_demo_pkg = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/index.js\"(exports, module) {\n    var fn2 = require_node_pkg_browser();\n    module.exports = function() {\n      return fn2();\n    };\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_demo_pkg());\nconsole.log((0, import_demo_pkg.default)());\n\n================================================================================\nTestPackageJsonBrowserMapModuleToRelative\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/node-pkg-browser.js\nvar require_node_pkg_browser = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/node-pkg-browser.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// Users/user/project/node_modules/demo-pkg/index.js\nvar require_demo_pkg = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/index.js\"(exports, module) {\n    var fn2 = require_node_pkg_browser();\n    module.exports = function() {\n      return fn2();\n    };\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_demo_pkg());\nconsole.log((0, import_demo_pkg.default)());\n\n================================================================================\nTestPackageJsonBrowserMapNativeModuleDisabled\n---------- /Users/user/project/out.js ----------\n// (disabled):fs\nvar require_fs = __commonJS({\n  \"(disabled):fs\"() {\n  }\n});\n\n// Users/user/project/node_modules/demo-pkg/index.js\nvar require_demo_pkg = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/index.js\"(exports, module) {\n    var fs = require_fs();\n    module.exports = function() {\n      return fs.readFile();\n    };\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_demo_pkg());\nconsole.log((0, import_demo_pkg.default)());\n\n================================================================================\nTestPackageJsonBrowserMapRelativeDisabled\n---------- /Users/user/project/out.js ----------\n// (disabled):Users/user/project/node_modules/demo-pkg/util-node\nvar require_util_node = __commonJS({\n  \"(disabled):Users/user/project/node_modules/demo-pkg/util-node\"() {\n  }\n});\n\n// Users/user/project/node_modules/demo-pkg/main.js\nvar require_main = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/main.js\"(exports, module) {\n    var util = require_util_node();\n    module.exports = function(obj) {\n      return util.inspect(obj);\n    };\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_main());\nconsole.log((0, import_demo_pkg.default)());\n\n================================================================================\nTestPackageJsonBrowserMapRelativeToModule\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/util-browser/index.js\nvar require_util_browser = __commonJS({\n  \"Users/user/project/node_modules/util-browser/index.js\"(exports, module) {\n    module.exports = \"util-browser\";\n  }\n});\n\n// Users/user/project/node_modules/demo-pkg/main.js\nvar require_main = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/main.js\"(exports, module) {\n    var util = require_util_browser();\n    module.exports = function() {\n      return [\"main\", util];\n    };\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_main());\nconsole.log((0, import_demo_pkg.default)());\n\n================================================================================\nTestPackageJsonBrowserMapRelativeToRelative\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/lib/util-browser.js\nvar require_util_browser = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/lib/util-browser.js\"(exports, module) {\n    module.exports = \"util-browser\";\n  }\n});\n\n// Users/user/project/node_modules/demo-pkg/main-browser.js\nvar require_main_browser = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/main-browser.js\"(exports, module) {\n    var util = require_util_browser();\n    module.exports = function() {\n      return [\"main-browser\", util];\n    };\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_main_browser());\nconsole.log((0, import_demo_pkg.default)());\n\n================================================================================\nTestPackageJsonBrowserMatchingTrailingSlashIssue4187\n---------- /out.js ----------\n// node_modules/axios/browser/index.js\nvar require_browser = __commonJS({\n  \"node_modules/axios/browser/index.js\"(exports, module) {\n    module.exports = { get: () => new Promise(\"Browser\") };\n  }\n});\n\n// node_modules/axios/index.js\nvar require_axios = __commonJS({\n  \"node_modules/axios/index.js\"(exports, module) {\n    module.exports = require_browser();\n  }\n});\n\n// entry.js\nvar import_axios = __toESM(require_axios());\n\n================================================================================\nTestPackageJsonBrowserNoExt\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/demo-pkg/no-ext-browser.js\nvar browser = \"browser\";\n\n// Users/user/project/src/demo-pkg/no-ext.js\nvar node = \"node\";\n\n// Users/user/project/src/demo-pkg/ext-browser.js\nvar browser2 = \"browser\";\n\n// Users/user/project/src/entry.js\nconsole.log(browser);\nconsole.log(node);\nconsole.log(browser2);\nconsole.log(browser2);\n\n================================================================================\nTestPackageJsonBrowserNodeModulesIndexNoExt\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/no-ext-browser/index.js\nvar browser = \"browser\";\n\n// Users/user/project/node_modules/demo-pkg/no-ext/index.js\nvar node = \"node\";\n\n// Users/user/project/node_modules/demo-pkg/ext-browser/index.js\nvar browser2 = \"browser\";\n\n// Users/user/project/src/entry.js\nconsole.log(browser);\nconsole.log(node);\nconsole.log(browser2);\nconsole.log(browser2);\n\n================================================================================\nTestPackageJsonBrowserNodeModulesNoExt\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/no-ext-browser.js\nvar browser = \"browser\";\n\n// Users/user/project/node_modules/demo-pkg/no-ext.js\nvar node = \"node\";\n\n// Users/user/project/node_modules/demo-pkg/ext-browser.js\nvar browser2 = \"browser\";\n\n// Users/user/project/src/entry.js\nconsole.log(browser);\nconsole.log(node);\nconsole.log(browser2);\nconsole.log(browser2);\n\n================================================================================\nTestPackageJsonBrowserOverMainNode\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/main.js\nvar require_main = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/main.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_main());\nconsole.log((0, import_demo_pkg.default)());\n\n================================================================================\nTestPackageJsonBrowserOverModuleBrowser\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/main.browser.js\nvar require_main_browser = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/main.browser.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_main_browser());\nconsole.log((0, import_demo_pkg.default)());\n\n================================================================================\nTestPackageJsonBrowserString\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/browser.js\nvar require_browser = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/browser.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_browser());\nconsole.log((0, import_demo_pkg.default)());\n\n================================================================================\nTestPackageJsonBrowserWithMainNode\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/main.js\nvar require_main = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/main.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_main());\nconsole.log((0, import_demo_pkg.default)());\n\n================================================================================\nTestPackageJsonBrowserWithModuleBrowser\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/main.browser.esm.js\nfunction main_browser_esm_default() {\n  return 123;\n}\n\n// Users/user/project/src/entry.js\nconsole.log(main_browser_esm_default());\n\n================================================================================\nTestPackageJsonDisabledTypeModuleIssue3367\n---------- /out.js ----------\n// (disabled):node_modules/foo/index.js\nvar require_foo = __commonJS({\n  \"(disabled):node_modules/foo/index.js\"() {\n  }\n});\n\n// entry.js\nvar import_foo = __toESM(require_foo());\n(0, import_foo.default)();\n\n================================================================================\nTestPackageJsonDualPackageHazardImportAndRequireBrowser\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/main.browser.js\nvar require_main_browser = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/main.browser.js\"(exports, module) {\n    module.exports = \"browser main\";\n  }\n});\n\n// Users/user/project/src/test-main.js\nconsole.log(require_main_browser());\n\n// Users/user/project/src/test-module.js\nvar import_demo_pkg = __toESM(require_main_browser());\nconsole.log(import_demo_pkg.default);\n\n================================================================================\nTestPackageJsonDualPackageHazardImportAndRequireForceModuleBeforeMain\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/module.js\nvar module_exports = {};\n__export(module_exports, {\n  default: () => module_default\n});\nvar module_default;\nvar init_module = __esm({\n  \"Users/user/project/node_modules/demo-pkg/module.js\"() {\n    module_default = \"module\";\n  }\n});\n\n// Users/user/project/src/test-main.js\nconsole.log((init_module(), __toCommonJS(module_exports)));\n\n// Users/user/project/src/test-module.js\ninit_module();\nconsole.log(module_default);\n\n================================================================================\nTestPackageJsonDualPackageHazardImportAndRequireImplicitMain\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/index.js\nvar require_demo_pkg = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/index.js\"(exports, module) {\n    module.exports = \"index\";\n  }\n});\n\n// Users/user/project/src/test-index.js\nconsole.log(require_demo_pkg());\n\n// Users/user/project/src/test-module.js\nvar import_demo_pkg = __toESM(require_demo_pkg());\nconsole.log(import_demo_pkg.default);\n\n================================================================================\nTestPackageJsonDualPackageHazardImportAndRequireImplicitMainForceModuleBeforeMain\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/module.js\nvar module_exports = {};\n__export(module_exports, {\n  default: () => module_default\n});\nvar module_default;\nvar init_module = __esm({\n  \"Users/user/project/node_modules/demo-pkg/module.js\"() {\n    module_default = \"module\";\n  }\n});\n\n// Users/user/project/src/test-index.js\nconsole.log((init_module(), __toCommonJS(module_exports)));\n\n// Users/user/project/src/test-module.js\ninit_module();\nconsole.log(module_default);\n\n================================================================================\nTestPackageJsonDualPackageHazardImportAndRequireSameFile\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/main.js\nvar require_main = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/main.js\"(exports, module) {\n    module.exports = \"main\";\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_main());\nconsole.log(import_demo_pkg.default, require_main());\n\n================================================================================\nTestPackageJsonDualPackageHazardImportAndRequireSeparateFiles\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/main.js\nvar require_main = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/main.js\"(exports, module) {\n    module.exports = \"main\";\n  }\n});\n\n// Users/user/project/src/test-main.js\nconsole.log(require_main());\n\n// Users/user/project/src/test-module.js\nvar import_demo_pkg = __toESM(require_main());\nconsole.log(import_demo_pkg.default);\n\n================================================================================\nTestPackageJsonDualPackageHazardImportOnly\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/module.js\nvar module_default = \"module\";\n\n// Users/user/project/src/entry.js\nconsole.log(module_default);\n\n================================================================================\nTestPackageJsonDualPackageHazardRequireOnly\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/main.js\nvar require_main = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/main.js\"(exports, module) {\n    module.exports = \"main\";\n  }\n});\n\n// Users/user/project/src/entry.js\nconsole.log(require_main());\n\n================================================================================\nTestPackageJsonExportsBrowser\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/pkg/browser.js\nconsole.log(\"SUCCESS\");\n\n================================================================================\nTestPackageJsonExportsCustomConditions\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/pkg1/custom2.js\nconsole.log(\"SUCCESS\");\n\n================================================================================\nTestPackageJsonExportsDefaultOverImportAndRequire\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/pkg/default.js\nconsole.log(\"SUCCESS\");\n\n================================================================================\nTestPackageJsonExportsDefaultWarningIssue3887\n---------- /out.js ----------\n// node_modules/foo/dist/index.js\nsuccess();\n\n================================================================================\nTestPackageJsonExportsEntryPointImportOverRequire\n---------- /out.js ----------\n// node_modules/pkg/import.js\nconsole.log(\"SUCCESS\");\n\n================================================================================\nTestPackageJsonExportsEntryPointMainOnly\n---------- /out.js ----------\n// node_modules/pkg/main.js\nconsole.log(\"SUCCESS\");\n\n================================================================================\nTestPackageJsonExportsEntryPointModuleOverMain\n---------- /out.js ----------\n// node_modules/pkg/module.js\nconsole.log(\"SUCCESS\");\n\n================================================================================\nTestPackageJsonExportsImportOverRequire\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/pkg/import.js\nconsole.log(\"SUCCESS\");\n\n================================================================================\nTestPackageJsonExportsNeutral\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/pkg/default.js\nconsole.log(\"SUCCESS\");\n\n================================================================================\nTestPackageJsonExportsNode\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/pkg/node.js\nconsole.log(\"SUCCESS\");\n\n================================================================================\nTestPackageJsonExportsNotExactMissingExtension\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/pkg1/dir/bar.js\nconsole.log(\"SUCCESS\");\n\n================================================================================\nTestPackageJsonExportsOrderIndependent\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/pkg1/2/bar.js\nconsole.log(\"SUCCESS\");\n\n// Users/user/project/node_modules/pkg2/1/bar.js\nconsole.log(\"SUCCESS\");\n\n================================================================================\nTestPackageJsonExportsPatternTrailers\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/pkg/dir/baz-foo.js\nconsole.log(\"works\");\n\n// Users/user/project/node_modules/pkg2/public/abc.js\nconsole.log(\"abc\");\n\n// Users/user/project/node_modules/pkg2/public/xyz.js\nconsole.log(\"xyz\");\n\n================================================================================\nTestPackageJsonExportsRequireOverImport\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/pkg/require.js\nvar require_require = __commonJS({\n  \"Users/user/project/node_modules/pkg/require.js\"() {\n    console.log(\"SUCCESS\");\n  }\n});\n\n// Users/user/project/src/entry.js\nrequire_require();\n\n================================================================================\nTestPackageJsonExportsWildcard\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/pkg1/file.js\nconsole.log(\"SUCCESS\");\n\n// Users/user/project/node_modules/pkg1/file2.js\nconsole.log(\"SUCCESS\");\n\n================================================================================\nTestPackageJsonImportSelfUsingImport\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/foo-import.js\nvar foo_import_default = \"foo\";\n\n// Users/user/project/src/index.js\nvar index_default = \"index\";\nconsole.log(index_default, foo_import_default);\nexport {\n  index_default as default\n};\n\n================================================================================\nTestPackageJsonImportSelfUsingImportScoped\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/foo-import.js\nvar foo_import_default = \"foo\";\n\n// Users/user/project/src/index.js\nvar index_default = \"index\";\nconsole.log(index_default, foo_import_default);\nexport {\n  index_default as default\n};\n\n================================================================================\nTestPackageJsonImportSelfUsingRequire\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/foo-require.js\nvar require_foo_require = __commonJS({\n  \"Users/user/project/src/foo-require.js\"(exports, module) {\n    module.exports = \"foo\";\n  }\n});\n\n// Users/user/project/src/index.js\nvar require_index = __commonJS({\n  \"Users/user/project/src/index.js\"(exports, module) {\n    module.exports = \"index\";\n    console.log(\n      require_index(),\n      require_foo_require()\n    );\n  }\n});\nexport default require_index();\n\n================================================================================\nTestPackageJsonImportSelfUsingRequireScoped\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/foo-require.js\nvar require_foo_require = __commonJS({\n  \"Users/user/project/src/foo-require.js\"(exports, module) {\n    module.exports = \"foo\";\n  }\n});\n\n// Users/user/project/src/index.js\nvar require_index = __commonJS({\n  \"Users/user/project/src/index.js\"(exports, module) {\n    module.exports = \"index\";\n    console.log(\n      require_index(),\n      require_foo_require()\n    );\n  }\n});\nexport default require_index();\n\n================================================================================\nTestPackageJsonImports\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/a.js\nconsole.log(\"a.js\");\n\n// Users/user/project/src/b.js\nconsole.log(\"b.js\");\n\n// Users/user/project/src/some-star/c.js\nconsole.log(\"c.js\");\n\n// Users/user/project/src/some-slash/d.js\nconsole.log(\"d.js\");\n\n================================================================================\nTestPackageJsonImportsRemapToOtherPackage\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/node_modules/pkg/a.js\nconsole.log(\"a.js\");\n\n// Users/user/project/src/node_modules/pkg/b.js\nconsole.log(\"b.js\");\n\n// Users/user/project/src/node_modules/pkg/some-star/c.js\nconsole.log(\"c.js\");\n\n// Users/user/project/src/node_modules/pkg/some-slash/d.js\nconsole.log(\"d.js\");\n\n================================================================================\nTestPackageJsonImportsHashSlashExactMatch\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/index.js\nconsole.log(\"index.js\");\n\n// Users/user/project/src/utils.js\nconsole.log(\"utils.js\");\n\n================================================================================\nTestPackageJsonImportsHashSlashSymmetricWithExports\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/src/components/button.js\nconsole.log(\"button.js\");\n\n// Users/user/project/src/src/utils/format.js\nconsole.log(\"format.js\");\n\n================================================================================\nTestPackageJsonImportsHashSlashWithConditions\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/esm/lib.js\nconsole.log(\"esm/lib.js\");\n\n================================================================================\nTestPackageJsonImportsHashSlashWithWildcard\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/src/foo.js\nconsole.log(\"foo.js\");\n\n// Users/user/project/src/src/bar/baz.js\nconsole.log(\"bar/baz.js\");\n\n================================================================================\nTestPackageJsonMain\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/custom-main.js\nvar require_custom_main = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/custom-main.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_custom_main());\nconsole.log((0, import_demo_pkg.default)());\n\n================================================================================\nTestPackageJsonMainFieldsA\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/a.js\nvar require_a = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/a.js\"(exports, module) {\n    module.exports = \"a\";\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_a());\nconsole.log(import_demo_pkg.default);\n\n================================================================================\nTestPackageJsonMainFieldsB\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/b.js\nvar b_default = \"b\";\n\n// Users/user/project/src/entry.js\nconsole.log(b_default);\n\n================================================================================\nTestPackageJsonModule\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/main.esm.js\nfunction main_esm_default() {\n  return 123;\n}\n\n// Users/user/project/src/entry.js\nconsole.log(main_esm_default());\n\n================================================================================\nTestPackageJsonNeutralExplicitMainFields\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/demo-pkg/main.js\nvar require_main = __commonJS({\n  \"Users/user/project/node_modules/demo-pkg/main.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// Users/user/project/src/entry.js\nvar import_demo_pkg = __toESM(require_main());\nconsole.log((0, import_demo_pkg.default)());\n\n================================================================================\nTestPackageJsonNodePathsIssue2752\n---------- /out.js ----------\n// usr/lib/pkg/pkg1/foo.js\nconsole.log(\"pkg1\");\n\n// lib/pkg/pkg2/bar.js\nconsole.log(\"pkg2\");\n\n// var/lib/pkg/@scope/pkg3/baz-browser.js\nconsole.log(\"pkg3\");\n\n// tmp/pkg/@scope/pkg4/bat.js\nconsole.log(\"pkg4\");\n\n================================================================================\nTestPackageJsonSubpathImportNodeBuiltinIssue3485\n---------- /out.js ----------\n// entry.js\nimport fs from \"fs\";\nimport http from \"node:http\";\nfs.readFileSync();\nhttp.createServer();\n\n================================================================================\nTestPackageJsonTypeShouldBeTypes\n---------- /Users/user/project/out.js ----------\n"
  },
  {
    "path": "internal/bundler_tests/snapshots/snapshots_splitting.txt",
    "content": "TestEdgeCaseIssue2793WithSplitting\n---------- /out/index.js ----------\n// src/a.js\nvar A = 42;\n\n// src/b.js\nvar B = async () => (await import(\"./index.js\")).A;\nexport {\n  A,\n  B\n};\n\n================================================================================\nTestEdgeCaseIssue2793WithoutSplitting\n---------- /out/index.js ----------\n// src/a.js\nvar A;\nvar init_a = __esm({\n  \"src/a.js\"() {\n    A = 42;\n  }\n});\n\n// src/b.js\nvar B;\nvar init_b = __esm({\n  \"src/b.js\"() {\n    B = async () => (await Promise.resolve().then(() => (init_index(), index_exports))).A;\n  }\n});\n\n// src/index.js\nvar index_exports = {};\n__export(index_exports, {\n  A: () => A,\n  B: () => B\n});\nvar init_index = __esm({\n  \"src/index.js\"() {\n    init_a();\n    init_b();\n  }\n});\ninit_index();\nexport {\n  A,\n  B\n};\n\n================================================================================\nTestSplittingAssignToLocal\n---------- /out/a.js ----------\nimport {\n  foo,\n  setFoo\n} from \"./chunk-GX7G2SBE.js\";\n\n// a.js\nsetFoo(123);\nconsole.log(foo);\n\n---------- /out/b.js ----------\nimport {\n  foo\n} from \"./chunk-GX7G2SBE.js\";\n\n// b.js\nconsole.log(foo);\n\n---------- /out/chunk-GX7G2SBE.js ----------\n// shared.js\nvar foo;\nfunction setFoo(value) {\n  foo = value;\n}\n\nexport {\n  foo,\n  setFoo\n};\n\n================================================================================\nTestSplittingChunkPathDirPlaceholderImplicitOutbase\n---------- /out/entry.js ----------\n// project/entry.js\nconsole.log(import(\"./output-path/should-contain/this-text/file-G2XPANW2.js\"));\n\n---------- /out/output-path/should-contain/this-text/file-G2XPANW2.js ----------\n// project/output-path/should-contain/this-text/file.js\nconsole.log(\"file.js\");\n\n================================================================================\nTestSplittingCircularReferenceIssue251\n---------- /out/a.js ----------\nimport {\n  p,\n  q\n} from \"./chunk-HK23737J.js\";\nexport {\n  p,\n  q\n};\n\n---------- /out/b.js ----------\nimport {\n  p,\n  q\n} from \"./chunk-HK23737J.js\";\nexport {\n  p,\n  q\n};\n\n---------- /out/chunk-HK23737J.js ----------\n// a.js\nvar p = 5;\n\n// b.js\nvar q = 6;\n\nexport {\n  q,\n  p\n};\n\n================================================================================\nTestSplittingCrossChunkAssignmentDependencies\n---------- /out/a.js ----------\nimport {\n  setValue\n} from \"./chunk-3GNPIT25.js\";\n\n// a.js\nsetValue(123);\n\n---------- /out/b.js ----------\nimport \"./chunk-3GNPIT25.js\";\n\n---------- /out/chunk-3GNPIT25.js ----------\n// shared.js\nvar observer;\nvar value;\nfunction getValue() {\n  return value;\n}\nfunction setValue(next) {\n  value = next;\n  if (observer) observer();\n}\nsideEffects(getValue);\n\nexport {\n  setValue\n};\n\n================================================================================\nTestSplittingCrossChunkAssignmentDependenciesRecursive\n---------- /out/a.js ----------\nimport {\n  setX\n} from \"./chunk-NAKBUG5G.js\";\n\n// a.js\nsetX();\n\n---------- /out/b.js ----------\nimport {\n  setZ\n} from \"./chunk-BSMDVSN6.js\";\nimport \"./chunk-NAKBUG5G.js\";\n\n// b.js\nsetZ();\n\n---------- /out/c.js ----------\nimport {\n  setY2,\n  setZ2\n} from \"./chunk-BSMDVSN6.js\";\nimport {\n  setX2\n} from \"./chunk-NAKBUG5G.js\";\n\n// c.js\nsetX2();\nsetY2();\nsetZ2();\n\n---------- /out/chunk-BSMDVSN6.js ----------\nimport {\n  setX\n} from \"./chunk-NAKBUG5G.js\";\n\n// y.js\nvar _y;\nfunction setY(v) {\n  _y = v;\n}\nfunction setY2(v) {\n  setX(v);\n  _y = v;\n}\n\n// z.js\nvar _z;\nfunction setZ(v) {\n  _z = v;\n}\nfunction setZ2(v) {\n  setY(v);\n  _z = v;\n}\n\nexport {\n  setY2,\n  setZ,\n  setZ2\n};\n\n---------- /out/chunk-NAKBUG5G.js ----------\n// x.js\nvar _x;\nfunction setX(v) {\n  _x = v;\n}\nfunction setX2(v) {\n  _x = v;\n}\n\nexport {\n  setX,\n  setX2\n};\n\n================================================================================\nTestSplittingDuplicateChunkCollision\n---------- /out/a.js ----------\nimport\"./chunk-QPOQRTMB.js\";\n\n---------- /out/b.js ----------\nimport\"./chunk-QPOQRTMB.js\";\n\n---------- /out/chunk-QPOQRTMB.js ----------\nconsole.log(123);\n\n---------- /out/c.js ----------\nimport\"./chunk-TOGNOMR3.js\";\n\n---------- /out/d.js ----------\nimport\"./chunk-TOGNOMR3.js\";\n\n---------- /out/chunk-TOGNOMR3.js ----------\nconsole.log(123);\n\n================================================================================\nTestSplittingDynamicAndNotDynamicCommonJSIntoES6\n---------- /out/entry.js ----------\nimport {\n  __toESM,\n  require_foo\n} from \"./chunk-X3UWZZCR.js\";\n\n// entry.js\nvar import_foo = __toESM(require_foo());\nimport(\"./foo-BJYZ44Z3.js\").then(({ default: { bar: b } }) => console.log(import_foo.bar, b));\n\n---------- /out/foo-BJYZ44Z3.js ----------\nimport {\n  require_foo\n} from \"./chunk-X3UWZZCR.js\";\nexport default require_foo();\n\n---------- /out/chunk-X3UWZZCR.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports) {\n    exports.bar = 123;\n  }\n});\n\nexport {\n  __toESM,\n  require_foo\n};\n\n================================================================================\nTestSplittingDynamicAndNotDynamicES6IntoES6\n---------- /out/entry.js ----------\nimport {\n  bar\n} from \"./chunk-UDDKLWVZ.js\";\n\n// entry.js\nimport(\"./foo-BNHN4WV6.js\").then(({ bar: b }) => console.log(bar, b));\n\n---------- /out/foo-BNHN4WV6.js ----------\nimport {\n  bar\n} from \"./chunk-UDDKLWVZ.js\";\nexport {\n  bar\n};\n\n---------- /out/chunk-UDDKLWVZ.js ----------\n// foo.js\nvar bar = 123;\n\nexport {\n  bar\n};\n\n================================================================================\nTestSplittingDynamicCommonJSIntoES6\n---------- /out/entry.js ----------\n// entry.js\nimport(\"./foo-X6C7FV5C.js\").then(({ default: { bar } }) => console.log(bar));\n\n---------- /out/foo-X6C7FV5C.js ----------\n// foo.js\nvar require_foo = __commonJS({\n  \"foo.js\"(exports) {\n    exports.bar = 123;\n  }\n});\nexport default require_foo();\n\n================================================================================\nTestSplittingDynamicES6IntoES6\n---------- /out/entry.js ----------\n// entry.js\nimport(\"./foo-R2VCCZUR.js\").then(({ bar }) => console.log(bar));\n\n---------- /out/foo-R2VCCZUR.js ----------\n// foo.js\nvar bar = 123;\nexport {\n  bar\n};\n\n================================================================================\nTestSplittingDynamicImportIssue272\n---------- /out/a.js ----------\n// a.js\nimport(\"./b.js\");\n\n---------- /out/b.js ----------\n// b.js\nvar b_default = 1;\nexport {\n  b_default as default\n};\n\n================================================================================\nTestSplittingDynamicImportOutsideSourceTreeIssue264\n---------- /out/entry1.js ----------\n// Users/user/project/src/entry1.js\nimport(\"./package-ZBNDRRRB.js\");\n\n---------- /out/entry2.js ----------\n// Users/user/project/src/entry2.js\nimport(\"./package-ZBNDRRRB.js\");\n\n---------- /out/package-ZBNDRRRB.js ----------\n// Users/user/project/node_modules/package/index.js\nconsole.log(\"imported\");\n\n================================================================================\nTestSplittingHybridESMAndCJSIssue617\n---------- /out/a.js ----------\nimport {\n  foo,\n  init_a\n} from \"./chunk-PDZFCFBH.js\";\ninit_a();\nexport {\n  foo\n};\n\n---------- /out/b.js ----------\nimport {\n  __toCommonJS,\n  a_exports,\n  init_a\n} from \"./chunk-PDZFCFBH.js\";\n\n// b.js\nvar bar = (init_a(), __toCommonJS(a_exports));\nexport {\n  bar\n};\n\n---------- /out/chunk-PDZFCFBH.js ----------\n// a.js\nvar a_exports = {};\n__export(a_exports, {\n  foo: () => foo\n});\nvar foo;\nvar init_a = __esm({\n  \"a.js\"() {\n  }\n});\n\nexport {\n  __toCommonJS,\n  foo,\n  a_exports,\n  init_a\n};\n\n================================================================================\nTestSplittingMinifyIdentifiersCrashIssue437\n---------- /out/a.js ----------\nimport {\n  a as o\n} from \"./chunk-7N7J6VKT.js\";\n\n// a.js\nconsole.log(o);\n\n---------- /out/b.js ----------\nimport {\n  a as o\n} from \"./chunk-7N7J6VKT.js\";\n\n// b.js\nconsole.log(o);\n\n---------- /out/c.js ----------\nimport \"./chunk-7N7J6VKT.js\";\n\n---------- /out/chunk-7N7J6VKT.js ----------\n// shared.js\nfunction f(o) {\n}\n\nexport {\n  f as a\n};\n\n================================================================================\nTestSplittingMissingLazyExport\n---------- /out/a.js ----------\nimport {\n  foo\n} from \"./chunk-QVTGQSXT.js\";\n\n// a.js\nconsole.log(foo());\n\n---------- /out/b.js ----------\nimport {\n  bar\n} from \"./chunk-QVTGQSXT.js\";\n\n// b.js\nconsole.log(bar());\n\n---------- /out/chunk-QVTGQSXT.js ----------\n// empty.js\nvar empty_exports = {};\n\n// common.js\nfunction foo() {\n  return [empty_exports, void 0];\n}\nfunction bar() {\n  return [void 0];\n}\n\nexport {\n  foo,\n  bar\n};\n\n================================================================================\nTestSplittingNestedDirectories\n---------- /Users/user/project/out/pageA/page.js ----------\nimport {\n  shared_default\n} from \"../chunk-GWC2ABNX.js\";\n\n// Users/user/project/src/pages/pageA/page.js\nconsole.log(shared_default);\n\n---------- /Users/user/project/out/pageB/page.js ----------\nimport {\n  shared_default\n} from \"../chunk-GWC2ABNX.js\";\n\n// Users/user/project/src/pages/pageB/page.js\nconsole.log(-shared_default);\n\n---------- /Users/user/project/out/chunk-GWC2ABNX.js ----------\n// Users/user/project/src/pages/shared.js\nvar shared_default = 123;\n\nexport {\n  shared_default\n};\n\n================================================================================\nTestSplittingPublicPathEntryName\n---------- /out/a.js ----------\n// a.js\nimport(\"/www/b-AQIID5BE.js\");\n\n---------- /out/b-AQIID5BE.js ----------\n// b.js\nconsole.log(\"b\");\n\n================================================================================\nTestSplittingReExportIssue273\n---------- /out/a.js ----------\nimport {\n  a\n} from \"./chunk-RLFZNZQZ.js\";\nexport {\n  a\n};\n\n---------- /out/b.js ----------\nimport {\n  a\n} from \"./chunk-RLFZNZQZ.js\";\nexport {\n  a\n};\n\n---------- /out/chunk-RLFZNZQZ.js ----------\n// a.js\nvar a = 1;\n\nexport {\n  a\n};\n\n================================================================================\nTestSplittingSharedCommonJSIntoES6\n---------- /out/a.js ----------\nimport {\n  require_shared\n} from \"./chunk-JQJBVS2P.js\";\n\n// a.js\nvar { foo } = require_shared();\nconsole.log(foo);\n\n---------- /out/b.js ----------\nimport {\n  require_shared\n} from \"./chunk-JQJBVS2P.js\";\n\n// b.js\nvar { foo } = require_shared();\nconsole.log(foo);\n\n---------- /out/chunk-JQJBVS2P.js ----------\n// shared.js\nvar require_shared = __commonJS({\n  \"shared.js\"(exports) {\n    exports.foo = 123;\n  }\n});\n\nexport {\n  require_shared\n};\n\n================================================================================\nTestSplittingSharedES6IntoES6\n---------- /out/a.js ----------\nimport {\n  foo\n} from \"./chunk-25TWIR6T.js\";\n\n// a.js\nconsole.log(foo);\n\n---------- /out/b.js ----------\nimport {\n  foo\n} from \"./chunk-25TWIR6T.js\";\n\n// b.js\nconsole.log(foo);\n\n---------- /out/chunk-25TWIR6T.js ----------\n// shared.js\nvar foo = 123;\n\nexport {\n  foo\n};\n\n================================================================================\nTestSplittingSideEffectsWithoutDependencies\n---------- /out/a.js ----------\nimport {\n  a\n} from \"./chunk-Y3CWGI3W.js\";\n\n// a.js\nconsole.log(a);\n\n---------- /out/b.js ----------\nimport {\n  b\n} from \"./chunk-Y3CWGI3W.js\";\n\n// b.js\nconsole.log(b);\n\n---------- /out/chunk-Y3CWGI3W.js ----------\n// shared.js\nvar a = 1;\nvar b = 2;\nconsole.log(\"side effect\");\n\nexport {\n  a,\n  b\n};\n"
  },
  {
    "path": "internal/bundler_tests/snapshots/snapshots_ts.txt",
    "content": "TestEnumRulesFrom_TypeScript_5_0\n---------- /out/supported.js ----------\n// supported.ts\nconsole.log(\n  // a number or string literal,\n  123 /* X0 */,\n  \"x\" /* X1 */,\n  // a unary +, -, or ~ applied to a numeric constant expression,\n  1 /* X2 */,\n  -2 /* X3 */,\n  -4 /* X4 */,\n  // a binary +, -, *, /, %, **, <<, >>, >>>, |, &, ^ applied to two numeric constant expressions,\n  3 /* X5 */,\n  -1 /* X6 */,\n  6 /* X7 */,\n  0.5 /* X8 */,\n  1 /* X9 */,\n  8 /* X10 */,\n  4 /* X11 */,\n  -5 /* X12 */,\n  2147483643 /* X13 */,\n  13 /* X14 */,\n  4 /* X15 */,\n  9 /* X16 */,\n  // a template expression where each substitution expression is a constant expression,\n  \"x0\" /* X17 */,\n  \"0x\" /* X18 */,\n  \"xy\" /* X19 */,\n  \"NaN\" /* X20 */,\n  \"Infinity\" /* X21 */,\n  \"-Infinity\" /* X22 */,\n  \"0\" /* X23 */,\n  // a template expression where each substitution expression is a constant expression,\n  \"A0BxC-31246D\" /* X24 */,\n  // a parenthesized constant expression,\n  321 /* X25 */,\n  // a dotted name that references an enum member with an enum literal type, or\n  123 /* X26 */,\n  \"123x\" /* X27 */,\n  \"x123\" /* X28 */,\n  \"a123b\" /* X29 */,\n  123 /* X30 */,\n  \"123x\" /* X31 */,\n  \"x123\" /* X32 */,\n  \"a123b\" /* X33 */,\n  // a dotted name indexed by a string literal (e.g. x.y[\"z\"]) that references an enum member with an enum literal type.\"\n  \"x\" /* X34 */,\n  \"xy\" /* X35 */,\n  \"yx\" /* X36 */,\n  \"axb\" /* X37 */,\n  \"x\" /* X38 */,\n  \"xy\" /* X39 */,\n  \"yx\" /* X40 */,\n  \"axb\" /* X41 */\n);\n\n---------- /out/not-supported.js ----------\n// not-supported.ts\nvar NonIntegerNumberToString = ((NonIntegerNumberToString2) => {\n  NonIntegerNumberToString2[\"SUPPORTED\"] = \"1\";\n  NonIntegerNumberToString2[\"UNSUPPORTED\"] = \"\" + 1.5;\n  return NonIntegerNumberToString2;\n})(NonIntegerNumberToString || {});\nconsole.log(\n  \"1\" /* SUPPORTED */,\n  NonIntegerNumberToString.UNSUPPORTED\n);\nvar OutOfBoundsNumberToString = ((OutOfBoundsNumberToString2) => {\n  OutOfBoundsNumberToString2[\"SUPPORTED\"] = \"1000000000\";\n  OutOfBoundsNumberToString2[\"UNSUPPORTED\"] = \"\" + 1e12;\n  return OutOfBoundsNumberToString2;\n})(OutOfBoundsNumberToString || {});\nconsole.log(\n  \"1000000000\" /* SUPPORTED */,\n  OutOfBoundsNumberToString.UNSUPPORTED\n);\nconsole.log(\n  \"null\" /* NULL */,\n  \"true\" /* TRUE */,\n  \"false\" /* FALSE */,\n  \"123\" /* BIGINT */\n);\n\n================================================================================\nTestExportTypeIssue379\n---------- /out.js ----------\n// a.ts\nvar a_exports = {};\n__export(a_exports, {\n  foo: () => foo\n});\nvar foo = 123;\n\n// b.ts\nvar b_exports = {};\n__export(b_exports, {\n  foo: () => foo2\n});\nvar foo2 = 123;\n\n// c.ts\nvar c_exports = {};\n__export(c_exports, {\n  foo: () => foo3\n});\nvar foo3 = 123;\n\n// d.ts\nvar d_exports = {};\n__export(d_exports, {\n  foo: () => foo4\n});\nvar foo4 = 123;\n\n// entry.ts\nconsole.log(a_exports, b_exports, c_exports, d_exports);\n\n================================================================================\nTestTSAbstractClassFieldUseAssign\n---------- /out.js ----------\nconst keepThis = /* @__PURE__ */ Symbol(\"keepThis\");\nkeepThis;\nclass Foo {\n}\n(() => new Foo())();\n\n================================================================================\nTestTSAbstractClassFieldUseDefine\n---------- /out.js ----------\nconst keepThisToo = /* @__PURE__ */ Symbol(\"keepThisToo\");\nclass Foo {\n  keepThis;\n  [keepThisToo];\n}\n(() => new Foo())();\n\n================================================================================\nTestTSCommonJSVariableInESMTypeModule\n---------- /out.js ----------\n// entry.ts\nmodule.exports = null;\n\n================================================================================\nTestTSComputedClassFieldUseDefineFalse\n---------- /out.js ----------\nvar _a, _b, _c;\nq, _c = r, _b = x, _a = y;\nclass Foo {\n  constructor() {\n    this[_c] = s;\n    this[_a] = z;\n  }\n}\n__decorateClass([\n  dec\n], Foo.prototype, _b, 2);\n__decorateClass([\n  dec\n], Foo.prototype, _a, 2);\nnew Foo();\n\n================================================================================\nTestTSComputedClassFieldUseDefineTrue\n---------- /out.js ----------\nvar _a, _b;\nclass Foo {\n  [q];\n  [r] = s;\n  [_b = x];\n  [_a = y] = z;\n}\n__decorateClass([\n  dec\n], Foo.prototype, _b, 2);\n__decorateClass([\n  dec\n], Foo.prototype, _a, 2);\nnew Foo();\n\n================================================================================\nTestTSComputedClassFieldUseDefineTrueLower\n---------- /out.js ----------\nvar _a, _b, _c, _d;\n_d = q, _c = r, _b = x, _a = y;\nclass Foo {\n  constructor() {\n    __publicField(this, _d);\n    __publicField(this, _c, s);\n    __publicField(this, _b);\n    __publicField(this, _a, z);\n  }\n}\n__decorateClass([\n  dec\n], Foo.prototype, _b, 2);\n__decorateClass([\n  dec\n], Foo.prototype, _a, 2);\nnew Foo();\n\n================================================================================\nTestTSConstEnumComments\n---------- /out.js ----------\n// foo.ts\nconsole.log({\n  \"should have comments\": [\n    1 /* %/* */,\n    1 /* %/* */\n  ],\n  \"should not have comments\": [\n    2,\n    2\n  ]\n});\n\n================================================================================\nTestTSDeclareClass\n---------- /out.js ----------\n// entry.ts\nvar foo = bar();\n\n================================================================================\nTestTSDeclareClassFields\n---------- /out.js ----------\n// define-false/index.ts\n() => null, c, () => null, C;\nvar Foo = class {\n};\n(() => new Foo())();\n\n// define-true/index.ts\nvar _a;\nvar Bar = class {\n  constructor() {\n    __publicField(this, \"a\");\n    __publicField(this, _a);\n  }\n  static A;\n  static [(_a = (() => null, c), () => null, C)];\n};\n(() => new Bar())();\n\n================================================================================\nTestTSDeclareConst\n---------- /out.js ----------\n// entry.ts\nvar foo = bar();\n\n================================================================================\nTestTSDeclareConstEnum\n---------- /out.js ----------\n// entry.ts\nvar foo = bar();\n\n================================================================================\nTestTSDeclareEnum\n---------- /out.js ----------\n// entry.ts\nvar foo = bar();\n\n================================================================================\nTestTSDeclareFunction\n---------- /out.js ----------\n// entry.ts\nvar foo = bar();\n\n================================================================================\nTestTSDeclareLet\n---------- /out.js ----------\n// entry.ts\nvar foo = bar();\n\n================================================================================\nTestTSDeclareNamespace\n---------- /out.js ----------\n// entry.ts\nvar foo = bar();\n\n================================================================================\nTestTSDeclareVar\n---------- /out.js ----------\n// entry.ts\nvar foo = bar();\n\n================================================================================\nTestTSEnumCrossModuleInliningAccess\n---------- /out/entry.js ----------\n// enums.ts\nvar c_num = /* @__PURE__ */ ((c_num2) => {\n  c_num2[c_num2[\"x\"] = 123] = \"x\";\n  return c_num2;\n})(c_num || {});\nvar d_num = /* @__PURE__ */ ((d_num2) => {\n  d_num2[d_num2[\"x\"] = 123] = \"x\";\n  return d_num2;\n})(d_num || {});\nvar e_num = /* @__PURE__ */ ((e_num2) => {\n  e_num2[e_num2[\"x\"] = 123] = \"x\";\n  return e_num2;\n})(e_num || {});\nvar c_str = /* @__PURE__ */ ((c_str2) => {\n  c_str2[\"x\"] = \"abc\";\n  return c_str2;\n})(c_str || {});\nvar d_str = /* @__PURE__ */ ((d_str2) => {\n  d_str2[\"x\"] = \"abc\";\n  return d_str2;\n})(d_str || {});\nvar e_str = /* @__PURE__ */ ((e_str2) => {\n  e_str2[\"x\"] = \"abc\";\n  return e_str2;\n})(e_str || {});\n\n// entry.ts\ninlined = [\n  123 /* x */,\n  123 /* x */,\n  \"abc\" /* x */,\n  \"abc\" /* x */\n];\nnot_inlined = [\n  c_num?.x,\n  d_num?.[\"x\"],\n  e_num,\n  c_str?.x,\n  d_str?.[\"x\"],\n  e_str\n];\n\n================================================================================\nTestTSEnumCrossModuleInliningDefinitions\n---------- /out/entry.js ----------\n// enums.ts\nvar a = ((a2) => {\n  a2[a2[\"implicit_number\"] = 0] = \"implicit_number\";\n  a2[a2[\"explicit_number\"] = 123] = \"explicit_number\";\n  a2[\"explicit_string\"] = \"xyz\";\n  a2[a2[\"non_constant\"] = foo] = \"non_constant\";\n  return a2;\n})(a || {});\n\n// entry.ts\nconsole.log([\n  0 /* implicit_number */,\n  123 /* explicit_number */,\n  \"xyz\" /* explicit_string */,\n  a.non_constant\n]);\n\n================================================================================\nTestTSEnumCrossModuleInliningMinifyIndexIntoDot\n---------- /out.js ----------\n// entry.ts\ninlined = [\n  obj.abc,\n  obj.xyz,\n  obj?.abc,\n  obj?.xyz,\n  obj?.prop.abc,\n  obj?.prop.xyz\n];\nnotInlined = [\n  obj[\"a b c\" /* foo2 */],\n  obj[\"x y z\" /* bar2 */],\n  obj?.[\"a b c\" /* foo2 */],\n  obj?.[\"x y z\" /* bar2 */],\n  obj?.prop[\"a b c\" /* foo2 */],\n  obj?.prop[\"x y z\" /* bar2 */]\n];\n\n================================================================================\nTestTSEnumCrossModuleInliningReExport\n---------- /out/entry.js ----------\n// entry.js\nconsole.log([\n  \"a\" /* x */,\n  \"b\" /* x */,\n  \"c\" /* x */\n]);\n\n================================================================================\nTestTSEnumCrossModuleTreeShaking\n---------- /out/entry.js ----------\n// enums.ts\nvar a_keep = /* @__PURE__ */ ((a_keep2) => {\n  a_keep2[a_keep2[\"x\"] = false] = \"x\";\n  return a_keep2;\n})(a_keep || {});\nvar b_keep = ((b_keep2) => {\n  b_keep2[b_keep2[\"x\"] = foo] = \"x\";\n  return b_keep2;\n})(b_keep || {});\nvar c_keep = /* @__PURE__ */ ((c_keep2) => {\n  c_keep2[c_keep2[\"x\"] = 3] = \"x\";\n  return c_keep2;\n})(c_keep || {});\nvar d_keep = /* @__PURE__ */ ((d_keep2) => {\n  d_keep2[d_keep2[\"x\"] = 4] = \"x\";\n  return d_keep2;\n})(d_keep || {});\nvar e_keep = {};\n\n// entry.ts\nconsole.log([\n  1 /* x */,\n  2 /* x */,\n  \"\" /* x */\n]);\nconsole.log([\n  a_keep.x,\n  b_keep.x,\n  c_keep,\n  d_keep.y,\n  e_keep.x\n]);\n\n================================================================================\nTestTSEnumDefine\n---------- /out/entry.js ----------\nvar a = /* @__PURE__ */ ((a2) => {\n  a2[a2[\"b\"] = 123] = \"b\";\n  a2[a2[\"c\"] = 123 /* b */] = \"c\";\n  return a2;\n})(a || {});\n\n================================================================================\nTestTSEnumExportClause\n---------- /out/entry.js ----------\n// entry.ts\nconsole.log([\n  1 /* A */,\n  2 /* B */,\n  3 /* C */,\n  4 /* D */\n]);\n\n================================================================================\nTestTSEnumJSX\n---------- /out/element.js ----------\nexport var Foo = /* @__PURE__ */ ((Foo2) => {\n  Foo2[\"Div\"] = \"div\";\n  return Foo2;\n})(Foo || {});\nconsole.log(/* @__PURE__ */ React.createElement(\"div\" /* Div */, null));\n\n---------- /out/fragment.js ----------\nexport var React = /* @__PURE__ */ ((React2) => {\n  React2[\"Fragment\"] = \"div\";\n  return React2;\n})(React || {});\nconsole.log(/* @__PURE__ */ React.createElement(\"div\" /* Fragment */, null, \"test\"));\n\n---------- /out/nested-element.js ----------\nvar x;\n((x2) => {\n  let y;\n  ((y2) => {\n    let Foo;\n    ((Foo2) => {\n      Foo2[\"Div\"] = \"div\";\n    })(Foo = y2.Foo || (y2.Foo = {}));\n  })(y = x2.y || (x2.y = {}));\n})(x || (x = {}));\n((x2) => {\n  let y;\n  ((y2) => {\n    console.log(/* @__PURE__ */ React.createElement(\"div\" /* Div */, null));\n  })(y = x2.y || (x2.y = {}));\n})(x || (x = {}));\n\n---------- /out/nested-fragment.js ----------\nvar x;\n((x2) => {\n  let y;\n  ((y2) => {\n    let React;\n    ((React2) => {\n      React2[\"Fragment\"] = \"div\";\n    })(React = y2.React || (y2.React = {}));\n  })(y = x2.y || (x2.y = {}));\n})(x || (x = {}));\n((x2) => {\n  let y;\n  ((y2) => {\n    console.log(/* @__PURE__ */ y2.React.createElement(\"div\" /* Fragment */, null, \"test\"));\n  })(y = x2.y || (x2.y = {}));\n})(x || (x = {}));\n\n================================================================================\nTestTSEnumSameModuleInliningAccess\n---------- /out/entry.js ----------\n// entry.ts\nvar c_num = /* @__PURE__ */ ((c_num2) => {\n  c_num2[c_num2[\"x\"] = 123] = \"x\";\n  return c_num2;\n})(c_num || {});\nvar d_num = /* @__PURE__ */ ((d_num2) => {\n  d_num2[d_num2[\"x\"] = 123] = \"x\";\n  return d_num2;\n})(d_num || {});\nvar e_num = /* @__PURE__ */ ((e_num2) => {\n  e_num2[e_num2[\"x\"] = 123] = \"x\";\n  return e_num2;\n})(e_num || {});\nvar c_str = /* @__PURE__ */ ((c_str2) => {\n  c_str2[\"x\"] = \"abc\";\n  return c_str2;\n})(c_str || {});\nvar d_str = /* @__PURE__ */ ((d_str2) => {\n  d_str2[\"x\"] = \"abc\";\n  return d_str2;\n})(d_str || {});\nvar e_str = /* @__PURE__ */ ((e_str2) => {\n  e_str2[\"x\"] = \"abc\";\n  return e_str2;\n})(e_str || {});\ninlined = [\n  123 /* x */,\n  123 /* x */,\n  \"abc\" /* x */,\n  \"abc\" /* x */\n];\nnot_inlined = [\n  c_num?.x,\n  d_num?.[\"x\"],\n  e_num,\n  c_str?.x,\n  d_str?.[\"x\"],\n  e_str\n];\n\n================================================================================\nTestTSEnumTreeShaking\n---------- /out/simple-member.js ----------\n// simple-member.ts\nconsole.log(123 /* y */);\n\n---------- /out/simple-enum.js ----------\n// simple-enum.ts\nvar x = /* @__PURE__ */ ((x2) => {\n  x2[x2[\"y\"] = 123] = \"y\";\n  return x2;\n})(x || {});\nconsole.log(x);\n\n---------- /out/sibling-member.js ----------\n// sibling-member.ts\nconsole.log(123 /* y */, 246 /* z */);\n\n---------- /out/sibling-enum-before.js ----------\n// sibling-enum-before.ts\nconsole.log(x);\nvar x = /* @__PURE__ */ ((x2) => {\n  x2[x2[\"y\"] = 123] = \"y\";\n  return x2;\n})(x || {});\nvar x = /* @__PURE__ */ ((x2) => {\n  x2[x2[\"z\"] = 246] = \"z\";\n  return x2;\n})(x || {});\n\n---------- /out/sibling-enum-middle.js ----------\n// sibling-enum-middle.ts\nvar x = /* @__PURE__ */ ((x2) => {\n  x2[x2[\"y\"] = 123] = \"y\";\n  return x2;\n})(x || {});\nconsole.log(x);\nvar x = /* @__PURE__ */ ((x2) => {\n  x2[x2[\"z\"] = 246] = \"z\";\n  return x2;\n})(x || {});\n\n---------- /out/sibling-enum-after.js ----------\n// sibling-enum-after.ts\nvar x = /* @__PURE__ */ ((x2) => {\n  x2[x2[\"y\"] = 123] = \"y\";\n  return x2;\n})(x || {});\nvar x = /* @__PURE__ */ ((x2) => {\n  x2[x2[\"z\"] = 246] = \"z\";\n  return x2;\n})(x || {});\nconsole.log(x);\n\n---------- /out/namespace-before.js ----------\n// namespace-before.ts\n((x2) => {\n  console.log(x2, y);\n})(x || (x = {}));\nvar x = /* @__PURE__ */ ((x2) => {\n  x2[x2[\"y\"] = 123] = \"y\";\n  return x2;\n})(x || {});\n\n---------- /out/namespace-after.js ----------\n// namespace-after.ts\nvar x = /* @__PURE__ */ ((x2) => {\n  x2[x2[\"y\"] = 123] = \"y\";\n  return x2;\n})(x || {});\n((x2) => {\n  console.log(x2, y);\n})(x || (x = {}));\n\n================================================================================\nTestTSEnumUseBeforeDeclare\n---------- /out/entry.js ----------\n// entry.ts\nfunction before() {\n  console.log(0 /* FOO */);\n}\nfunction after() {\n  console.log(0 /* FOO */);\n}\nexport {\n  after,\n  before\n};\n\n================================================================================\nTestTSExperimentalDecoratorScopeIssue2147\n---------- /out.js ----------\nlet foo = 1;\nclass Foo {\n  method1(foo2 = 2) {\n  }\n  method2(foo2 = 3) {\n  }\n}\n__decorateClass([\n  __decorateParam(0, dec(foo))\n], Foo.prototype, \"method1\", 1);\n__decorateClass([\n  __decorateParam(0, dec(() => foo))\n], Foo.prototype, \"method2\", 1);\nclass Bar {\n  static {\n    this.x = class {\n      static {\n        this.y = () => {\n          let bar = 1;\n          let Baz = class {\n            method1() {\n            }\n            method2() {\n            }\n            method3(bar2) {\n            }\n            method4(bar2) {\n            }\n          };\n          __decorateClass([\n            dec(bar)\n          ], Baz.prototype, \"method1\", 1);\n          __decorateClass([\n            dec(() => bar)\n          ], Baz.prototype, \"method2\", 1);\n          __decorateClass([\n            __decorateParam(0, dec(() => bar))\n          ], Baz.prototype, \"method3\", 1);\n          __decorateClass([\n            __decorateParam(0, dec(() => bar))\n          ], Baz.prototype, \"method4\", 1);\n          Baz = __decorateClass([\n            dec(bar),\n            dec(() => bar)\n          ], Baz);\n          return Baz;\n        };\n      }\n    };\n  }\n}\n\n================================================================================\nTestTSExperimentalDecorators\n---------- /out.js ----------\n// all.ts\nvar Foo = class {\n  constructor(arg0, arg1) {\n    this.mDef = 1;\n  }\n  method(arg0, arg1) {\n    return new Foo();\n  }\n  static sMethod(arg0, arg1) {\n    return new Foo();\n  }\n};\nFoo.sDef = new Foo();\n__decorateClass([\n  x,\n  y\n], Foo.prototype, \"mUndef\", 2);\n__decorateClass([\n  x,\n  y\n], Foo.prototype, \"mDef\", 2);\n__decorateClass([\n  x,\n  y,\n  __decorateParam(0, x0),\n  __decorateParam(0, y0),\n  __decorateParam(1, x1),\n  __decorateParam(1, y1)\n], Foo.prototype, \"method\", 1);\n__decorateClass([\n  x,\n  y\n], Foo.prototype, \"mDecl\", 2);\n__decorateClass([\n  x,\n  y\n], Foo.prototype, \"mAbst\", 2);\n__decorateClass([\n  x,\n  y\n], Foo, \"sUndef\", 2);\n__decorateClass([\n  x,\n  y\n], Foo, \"sDef\", 2);\n__decorateClass([\n  x,\n  y,\n  __decorateParam(0, x0),\n  __decorateParam(0, y0),\n  __decorateParam(1, x1),\n  __decorateParam(1, y1)\n], Foo, \"sMethod\", 1);\n__decorateClass([\n  x,\n  y\n], Foo, \"mDecl\", 2);\nFoo = __decorateClass([\n  x.y(),\n  new y.x(),\n  __decorateParam(0, x0),\n  __decorateParam(0, y0),\n  __decorateParam(1, x1),\n  __decorateParam(1, y1)\n], Foo);\n\n// all_computed.ts\nvar _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;\nvar Foo2 = class {\n  constructor() {\n    this[_j] = 1;\n    this[_f] = 2;\n  }\n  [(_k = mUndef(), _j = mDef(), _i = method())](arg0, arg1) {\n    return new Foo2();\n  }\n  static [(_h = mDecl(), _g = mAbst(), xUndef(), _f = xDef(), yUndef(), _e = yDef(), _d = sUndef(), _c = sDef(), _b = sMethod(), _a = mDecl(), _b)](arg0, arg1) {\n    return new Foo2();\n  }\n};\nFoo2[_e] = 3;\nFoo2[_c] = new Foo2();\n__decorateClass([\n  x,\n  y\n], Foo2.prototype, _k, 2);\n__decorateClass([\n  x,\n  y\n], Foo2.prototype, _j, 2);\n__decorateClass([\n  x,\n  y,\n  __decorateParam(0, x0),\n  __decorateParam(0, y0),\n  __decorateParam(1, x1),\n  __decorateParam(1, y1)\n], Foo2.prototype, _i, 1);\n__decorateClass([\n  x,\n  y\n], Foo2.prototype, _h, 2);\n__decorateClass([\n  x,\n  y\n], Foo2.prototype, _g, 2);\n__decorateClass([\n  x,\n  y\n], Foo2, _d, 2);\n__decorateClass([\n  x,\n  y\n], Foo2, _c, 2);\n__decorateClass([\n  x,\n  y,\n  __decorateParam(0, x0),\n  __decorateParam(0, y0),\n  __decorateParam(1, x1),\n  __decorateParam(1, y1)\n], Foo2, _b, 1);\n__decorateClass([\n  x,\n  y\n], Foo2, _a, 2);\nFoo2 = __decorateClass([\n  x?.[_ + \"y\"](),\n  new y?.[_ + \"x\"]()\n], Foo2);\n\n// a.ts\nvar a_class = class {\n  fn() {\n    return new a_class();\n  }\n};\na_class.z = new a_class();\na_class = __decorateClass([\n  x(() => 0),\n  y(() => 1)\n], a_class);\nvar a = a_class;\n\n// b.ts\nvar b_class = class {\n  fn() {\n    return new b_class();\n  }\n};\nb_class.z = new b_class();\nb_class = __decorateClass([\n  x(() => 0),\n  y(() => 1)\n], b_class);\nvar b = b_class;\n\n// c.ts\nvar c = class {\n  fn() {\n    return new c();\n  }\n};\nc.z = new c();\nc = __decorateClass([\n  x(() => 0),\n  y(() => 1)\n], c);\n\n// d.ts\nvar d = class {\n  fn() {\n    return new d();\n  }\n};\nd.z = new d();\nd = __decorateClass([\n  x(() => 0),\n  y(() => 1)\n], d);\n\n// e.ts\nvar e_default = class {\n};\ne_default = __decorateClass([\n  x(() => 0),\n  y(() => 1)\n], e_default);\n\n// f.ts\nvar f = class {\n  fn() {\n    return new f();\n  }\n};\nf.z = new f();\nf = __decorateClass([\n  x(() => 0),\n  y(() => 1)\n], f);\n\n// g.ts\nvar g_default = class {\n};\ng_default = __decorateClass([\n  x(() => 0),\n  y(() => 1)\n], g_default);\n\n// h.ts\nvar h = class {\n  fn() {\n    return new h();\n  }\n};\nh.z = new h();\nh = __decorateClass([\n  x(() => 0),\n  y(() => 1)\n], h);\n\n// i.ts\nvar i_class = class {\n};\n__decorateClass([\n  x(() => 0),\n  y(() => 1)\n], i_class.prototype, \"foo\", 2);\nvar i = i_class;\n\n// j.ts\nvar j = class {\n  foo() {\n  }\n};\n__decorateClass([\n  x(() => 0),\n  y(() => 1)\n], j.prototype, \"foo\", 1);\n\n// k.ts\nvar k_default = class {\n  foo(x2) {\n  }\n};\n__decorateClass([\n  __decorateParam(0, x(() => 0)),\n  __decorateParam(0, y(() => 1))\n], k_default.prototype, \"foo\", 1);\n\n// arguments.ts\nfunction dec(x2) {\n}\nfunction fn(x2) {\n  var _a2;\n  class Foo3 {\n    [_a2 = arguments[0]]() {\n    }\n  }\n  __decorateClass([\n    dec(arguments[0])\n  ], Foo3.prototype, _a2, 1);\n  return Foo3;\n}\n\n// entry.js\nconsole.log(Foo, Foo2, a, b, c, d, e_default, f, g_default, h, i, j, k_default, fn);\n\n================================================================================\nTestTSExperimentalDecoratorsKeepNames\n---------- /out.js ----------\n// entry.ts\nvar Foo = class {\n};\n__name(Foo, \"Foo\");\nFoo = __decorateClass([\n  decoratorMustComeAfterName\n], Foo);\nexport {\n  Foo\n};\n\n================================================================================\nTestTSExperimentalDecoratorsManglePropsAssignSemantics\n---------- /out.js ----------\n// entry.ts\nvar Foo = class {\n  constructor() {\n    this.prop1 = null;\n    this.a = null;\n    this[\"prop3\"] = null;\n    this[\"prop4_\"] = null;\n    this[/* @__KEY__ */ \"prop5\"] = null;\n    this.b = null;\n  }\n};\n__decorateClass([\n  dec(1)\n], Foo.prototype, \"prop1\", 2);\n__decorateClass([\n  dec(2)\n], Foo.prototype, /* @__KEY__ */ \"a\", 2);\n__decorateClass([\n  dec(3)\n], Foo.prototype, \"prop3\", 2);\n__decorateClass([\n  dec(4)\n], Foo.prototype, \"prop4_\", 2);\n__decorateClass([\n  dec(5)\n], Foo.prototype, /* @__KEY__ */ \"prop5\", 2);\n__decorateClass([\n  dec(6)\n], Foo.prototype, /* @__KEY__ */ \"b\", 2);\n\n================================================================================\nTestTSExperimentalDecoratorsManglePropsDefineSemantics\n---------- /out.js ----------\n// entry.ts\nvar Foo = class {\n  prop1 = null;\n  a = null;\n  [\"prop3\"] = null;\n  [\"prop4_\"] = null;\n  [/* @__KEY__ */ \"prop5\"] = null;\n  [/* @__KEY__ */ \"b\"] = null;\n};\n__decorateClass([\n  dec(1)\n], Foo.prototype, \"prop1\", 2);\n__decorateClass([\n  dec(2)\n], Foo.prototype, /* @__KEY__ */ \"a\", 2);\n__decorateClass([\n  dec(3)\n], Foo.prototype, \"prop3\", 2);\n__decorateClass([\n  dec(4)\n], Foo.prototype, \"prop4_\", 2);\n__decorateClass([\n  dec(5)\n], Foo.prototype, /* @__KEY__ */ \"prop5\", 2);\n__decorateClass([\n  dec(6)\n], Foo.prototype, /* @__KEY__ */ \"b\", 2);\n\n================================================================================\nTestTSExperimentalDecoratorsManglePropsMethods\n---------- /out.js ----------\n// entry.ts\nvar Foo = class {\n  prop1() {\n  }\n  a() {\n  }\n  [\"prop3\"]() {\n  }\n  [\"prop4_\"]() {\n  }\n  [/* @__KEY__ */ \"prop5\"]() {\n  }\n  [/* @__KEY__ */ \"b\"]() {\n  }\n};\n__decorateClass([\n  dec(1)\n], Foo.prototype, \"prop1\", 1);\n__decorateClass([\n  dec(2)\n], Foo.prototype, /* @__KEY__ */ \"a\", 1);\n__decorateClass([\n  dec(3)\n], Foo.prototype, \"prop3\", 1);\n__decorateClass([\n  dec(4)\n], Foo.prototype, \"prop4_\", 1);\n__decorateClass([\n  dec(5)\n], Foo.prototype, /* @__KEY__ */ \"prop5\", 1);\n__decorateClass([\n  dec(6)\n], Foo.prototype, /* @__KEY__ */ \"b\", 1);\n\n================================================================================\nTestTSExperimentalDecoratorsManglePropsStaticAssignSemantics\n---------- /out.js ----------\n// entry.ts\nvar Foo = class {\n  static {\n    this.prop1 = null;\n  }\n  static {\n    this.a = null;\n  }\n  static {\n    this[\"prop3\"] = null;\n  }\n  static {\n    this[\"prop4_\"] = null;\n  }\n  static {\n    this[/* @__KEY__ */ \"prop5\"] = null;\n  }\n  static {\n    this.b = null;\n  }\n};\n__decorateClass([\n  dec(1)\n], Foo, \"prop1\", 2);\n__decorateClass([\n  dec(2)\n], Foo, /* @__KEY__ */ \"a\", 2);\n__decorateClass([\n  dec(3)\n], Foo, \"prop3\", 2);\n__decorateClass([\n  dec(4)\n], Foo, \"prop4_\", 2);\n__decorateClass([\n  dec(5)\n], Foo, /* @__KEY__ */ \"prop5\", 2);\n__decorateClass([\n  dec(6)\n], Foo, /* @__KEY__ */ \"b\", 2);\n\n================================================================================\nTestTSExperimentalDecoratorsManglePropsStaticDefineSemantics\n---------- /out.js ----------\n// entry.ts\nvar Foo = class {\n  static prop1 = null;\n  static a = null;\n  static [\"prop3\"] = null;\n  static [\"prop4_\"] = null;\n  static [/* @__KEY__ */ \"prop5\"] = null;\n  static [/* @__KEY__ */ \"b\"] = null;\n};\n__decorateClass([\n  dec(1)\n], Foo, \"prop1\", 2);\n__decorateClass([\n  dec(2)\n], Foo, /* @__KEY__ */ \"a\", 2);\n__decorateClass([\n  dec(3)\n], Foo, \"prop3\", 2);\n__decorateClass([\n  dec(4)\n], Foo, \"prop4_\", 2);\n__decorateClass([\n  dec(5)\n], Foo, /* @__KEY__ */ \"prop5\", 2);\n__decorateClass([\n  dec(6)\n], Foo, /* @__KEY__ */ \"b\", 2);\n\n================================================================================\nTestTSExperimentalDecoratorsManglePropsStaticMethods\n---------- /out.js ----------\n// entry.ts\nvar Foo = class {\n  static prop1() {\n  }\n  static a() {\n  }\n  static [\"prop3\"]() {\n  }\n  static [\"prop4_\"]() {\n  }\n  static [/* @__KEY__ */ \"prop5\"]() {\n  }\n  static [/* @__KEY__ */ \"b\"]() {\n  }\n};\n__decorateClass([\n  dec(1)\n], Foo, \"prop1\", 1);\n__decorateClass([\n  dec(2)\n], Foo, /* @__KEY__ */ \"a\", 1);\n__decorateClass([\n  dec(3)\n], Foo, \"prop3\", 1);\n__decorateClass([\n  dec(4)\n], Foo, \"prop4_\", 1);\n__decorateClass([\n  dec(5)\n], Foo, /* @__KEY__ */ \"prop5\", 1);\n__decorateClass([\n  dec(6)\n], Foo, /* @__KEY__ */ \"b\", 1);\n\n================================================================================\nTestTSExperimentalDecoratorsNoConfig\n---------- /out.js ----------\n// entry.ts\nvar Foo = @x.y() @(new y.x()) class _Foo {\n  @x @y mUndef;\n  @x @y mDef = 1;\n  @x @y method() {\n    return new _Foo();\n  }\n  @x @y accessor aUndef;\n  @x @y accessor aDef = 1;\n  @x @y static sUndef;\n  @x @y static sDef = new _Foo();\n  @x @y static sMethod() {\n    return new _Foo();\n  }\n  @x @y static accessor asUndef;\n  @x @y static accessor asDef = 1;\n  @x @y #mUndef;\n  @x @y #mDef = 1;\n  @x @y #method() {\n    return new _Foo();\n  }\n  @x @y accessor #aUndef;\n  @x @y accessor #aDef = 1;\n  @x @y static #sUndef;\n  @x @y static #sDef = 1;\n  @x @y static #sMethod() {\n    return new _Foo();\n  }\n  @x @y static accessor #asUndef;\n  @x @y static accessor #asDef = 1;\n};\nexport {\n  Foo as default\n};\n\n================================================================================\nTestTSExportDefaultTypeIssue316\n---------- /out.js ----------\n// keep/declare-class.ts\nvar declare_class_default = foo;\nvar bar = 123;\n\n// keep/declare-let.ts\nvar declare_let_default = foo;\nvar bar2 = 123;\n\n// keep/interface-merged.ts\nvar foo2 = class _foo {\n  static {\n    this.x = new _foo();\n  }\n};\nvar interface_merged_default = foo2;\nvar bar3 = 123;\n\n// keep/interface-nested.ts\nif (true) {\n}\nvar interface_nested_default = foo;\nvar bar4 = 123;\n\n// keep/type-nested.ts\nif (true) {\n}\nvar type_nested_default = foo;\nvar bar5 = 123;\n\n// keep/value-namespace.ts\nvar foo3;\n((foo5) => {\n  foo5.num = 0;\n})(foo3 || (foo3 = {}));\nvar value_namespace_default = foo3;\nvar bar6 = 123;\n\n// keep/value-namespace-merged.ts\nvar foo4;\n((foo5) => {\n  foo5.num = 0;\n})(foo4 || (foo4 = {}));\nvar value_namespace_merged_default = foo4;\nvar bar7 = 123;\n\n// remove/interface.ts\nvar bar8 = 123;\n\n// remove/interface-exported.ts\nvar bar9 = 123;\n\n// remove/type.ts\nvar bar10 = 123;\n\n// remove/type-exported.ts\nvar bar11 = 123;\n\n// remove/type-only-namespace.ts\nvar bar12 = 123;\n\n// remove/type-only-namespace-exported.ts\nvar bar13 = 123;\n\n// entry.ts\nvar entry_default = [\n  declare_class_default,\n  bar,\n  declare_let_default,\n  bar2,\n  interface_merged_default,\n  bar3,\n  interface_nested_default,\n  bar4,\n  type_nested_default,\n  bar5,\n  value_namespace_default,\n  bar6,\n  value_namespace_merged_default,\n  bar7,\n  bar8,\n  bar9,\n  bar10,\n  bar11,\n  bar12,\n  bar13\n];\nexport {\n  entry_default as default\n};\n\n================================================================================\nTestTSExportEquals\n---------- /out.js ----------\n// b.ts\nvar require_b = __commonJS({\n  \"b.ts\"(exports, module) {\n    function foo() {\n    }\n    module.exports = [123, foo];\n  }\n});\n\n// a.ts\nvar import_b = __toESM(require_b());\nconsole.log(import_b.default);\n\n================================================================================\nTestTSExportMissingES6\n---------- /out.js ----------\n// foo.ts\nvar foo_exports = {};\n\n// entry.js\nconsole.log(foo_exports);\n\n================================================================================\nTestTSExportNamespace\n---------- /out.js ----------\n// b.ts\nvar Foo = class {\n};\n((Foo2) => {\n  Foo2.foo = 1;\n})(Foo || (Foo = {}));\n((Foo2) => {\n  Foo2.bar = 2;\n})(Foo || (Foo = {}));\n\n// a.ts\nconsole.log(new Foo());\n\n================================================================================\nTestTSImplicitExtensions\n---------- /out.js ----------\n// pick-js.js\nconsole.log(\"correct\");\n\n// pick-ts.ts\nconsole.log(\"correct\");\n\n// pick-jsx.jsx\nconsole.log(\"correct\");\n\n// pick-tsx.tsx\nconsole.log(\"correct\");\n\n// order-js.ts\nconsole.log(\"correct\");\n\n// order-jsx.ts\nconsole.log(\"correct\");\n\n// node_modules/pkg/foo-js.ts\nconsole.log(\"correct\");\n\n// node_modules/pkg/foo-jsx.tsx\nconsole.log(\"correct\");\n\n// node_modules/pkg-exports/abc-js.ts\nconsole.log(\"correct\");\n\n// node_modules/pkg-exports/abc-jsx.tsx\nconsole.log(\"correct\");\n\n// node_modules/pkg-exports/lib/foo-js.ts\nconsole.log(\"correct\");\n\n// node_modules/pkg-exports/lib/foo-jsx.tsx\nconsole.log(\"correct\");\n\n// node_modules/pkg-imports/abc-js.ts\nconsole.log(\"correct\");\n\n// node_modules/pkg-imports/abc-jsx.tsx\nconsole.log(\"correct\");\n\n// node_modules/pkg-imports/lib/foo-js.ts\nconsole.log(\"correct\");\n\n// node_modules/pkg-imports/lib/foo-jsx.tsx\nconsole.log(\"correct\");\n\n================================================================================\nTestTSImportCTS\n---------- /out.js ----------\n// required.cjs\nvar require_required = __commonJS({\n  \"required.cjs\"() {\n    console.log(\"works\");\n  }\n});\n\n// entry.ts\nrequire_required();\n\n================================================================================\nTestTSImportEmptyNamespace\n---------- /out.js ----------\n// entry.ts\nfunction foo() {\n}\nfoo();\n\n================================================================================\nTestTSImportEqualsBundle\n---------- /out.js ----------\n// entry.ts\nimport { foo } from \"pkg\";\nvar used = foo.used;\nexport {\n  used\n};\n\n================================================================================\nTestTSImportEqualsEliminationTest\n---------- /out.js ----------\n// entry.ts\nvar a = foo.a;\nvar b = a.b;\nvar c = b.c;\nvar bar = c;\nexport {\n  bar\n};\n\n================================================================================\nTestTSImportEqualsTreeShakingFalse\n---------- /out.js ----------\nimport { foo } from \"pkg\";\nconst used = foo.used;\nexport { used };\n\n================================================================================\nTestTSImportEqualsTreeShakingTrue\n---------- /out.js ----------\nimport { foo } from \"pkg\";\nconst used = foo.used;\nexport { used };\n\n================================================================================\nTestTSImportEqualsUndefinedImport\n---------- /out.js ----------\n// import.ts\nvar value = 123;\n\n// entry.ts\nvar value_copy = value;\nvar foo = value_copy;\nconsole.log(foo);\n\n================================================================================\nTestTSImportInNodeModulesNameCollisionWithCSS\n---------- /out.js ----------\n// node_modules/pkg/js_ts_css.js\nfunction js_ts_css_default() {\n}\n\n// node_modules/pkg/ts_css.ts\nfunction ts_css_default() {\n}\n\n// node_modules/pkg/js_ts.js\nfunction js_ts_default() {\n}\n\n// node_modules/pkg/index.ts\njs_ts_css_default();\nts_css_default();\njs_ts_default();\n\n---------- /out.css ----------\n/* node_modules/pkg/js_ts_css.css */\n.js_ts_css {\n}\n\n/* node_modules/pkg/ts_css.css */\n.ts_css {\n}\n\n================================================================================\nTestTSImportMTS\n---------- /out.js ----------\n// imported.mts\nconsole.log(\"works\");\n\n================================================================================\nTestTSImportMissingUnusedES6\n---------- /out.js ----------\n\n================================================================================\nTestTSImportTypeOnlyFile\n---------- /out.js ----------\n// entry.ts\nvar foo = bar();\n\n================================================================================\nTestTSImportVsLocalCollisionAllTypes\n---------- /out.js ----------\n// entry.ts\nvar a;\nvar b = 0;\nvar c;\nfunction d() {\n}\nvar e = class {\n};\nconsole.log(a, b, c, d, e);\n\n================================================================================\nTestTSImportVsLocalCollisionMixed\n---------- /out.js ----------\n// other.ts\nvar real = 123;\n\n// entry.ts\nvar a;\nvar b = 0;\nvar c;\nfunction d() {\n}\nvar e = class {\n};\nconsole.log(a, b, c, d, e, real);\n\n================================================================================\nTestTSMinifiedBundleCommonJS\n---------- /out.js ----------\nvar t=e(r=>{r.foo=function(){return 123}});var n=e((l,c)=>{c.exports={test:!0}});var{foo:f}=t();console.log(f(),n());\n\n================================================================================\nTestTSMinifiedBundleES6\n---------- /out.js ----------\nfunction o(){return 123}console.log(o());\n\n================================================================================\nTestTSMinifyDerivedClass\n---------- /out.js ----------\nclass Foo extends Bar {\n  constructor() {\n    super();\n    this.foo = 1;\n    this.bar = 2;\n    foo(), bar();\n  }\n}\n\n================================================================================\nTestTSMinifyEnum\n---------- /a.js ----------\nvar Foo=(e=>(e[e.A=0]=\"A\",e[e.B=1]=\"B\",e[e.C=e]=\"C\",e))(Foo||{});\n\n---------- /b.js ----------\nexport var Foo=(e=>(e[e.X=0]=\"X\",e[e.Y=1]=\"Y\",e[e.Z=e]=\"Z\",e))(Foo||{});\n\n================================================================================\nTestTSMinifyEnumCrossFileInlineStringsIntoTemplates\n---------- /out.js ----------\n// entry.ts\nconsole.log(`\n\t\t\t\t\tSameFile.STR = str 1\n\t\t\t\t\tSameFile.NUM = 123\n\t\t\t\t\tCrossFile.STR = str 2\n\t\t\t\t\tCrossFile.NUM = 321\n\t\t\t\t`);\n\n================================================================================\nTestTSMinifyEnumPropertyNames\n---------- /out.js ----------\n// entry.ts\nvar Foo = class {\n  100 = 100;\n  200 = 200;\n  300 = 300;\n  \"str 1\" = \"str 1\" /* STR */;\n  123 = 123 /* NUM */;\n  \"str 2\" = \"str 2\" /* STR */;\n  321 = 321 /* NUM */;\n};\nshouldNotBeComputed(\n  class {\n    100 = 100;\n    200 = 200;\n    300 = 300;\n    \"str 1\" = \"str 1\" /* STR */;\n    123 = 123 /* NUM */;\n    \"str 2\" = \"str 2\" /* STR */;\n    321 = 321 /* NUM */;\n  },\n  {\n    100: 100,\n    200: 200,\n    300: 300,\n    \"str 1\": \"str 1\" /* STR */,\n    123: 123 /* NUM */,\n    \"str 2\": \"str 2\" /* STR */,\n    321: 321 /* NUM */\n  }\n);\nmustBeComputed(\n  { [\"__proto__\"]: null },\n  { [\"__proto__\"]: null },\n  class {\n    [\"constructor\"]() {\n    }\n  },\n  class {\n    [\"constructor\"]() {\n    }\n  },\n  class {\n    static [\"prototype\"]() {\n    }\n  },\n  class {\n    static [\"prototype\"]() {\n    }\n  }\n);\n\n================================================================================\nTestTSMinifyNamespace\n---------- /a.js ----------\nvar Foo;(e=>{let a;(p=>foo(e,p))(a=e.Bar||={})})(Foo||={});\n\n---------- /b.js ----------\nexport var Foo;(e=>{let a;(p=>foo(e,p))(a=e.Bar||={})})(Foo||={});\n\n================================================================================\nTestTSMinifyNamespaceNoArrow\n---------- /a.js ----------\nvar Foo;(function(e){let a;(function(p){foo(e,p)})(a=e.Bar||={})})(Foo||={});\n\n---------- /b.js ----------\nexport var Foo;(function(e){let a;(function(p){foo(e,p)})(a=e.Bar||={})})(Foo||={});\n\n================================================================================\nTestTSMinifyNamespaceNoLogicalAssignment\n---------- /a.js ----------\nvar Foo;(e=>{let a;(p=>foo(e,p))(a=e.Bar||(e.Bar={}))})(Foo||(Foo={}));\n\n---------- /b.js ----------\nexport var Foo;(e=>{let a;(p=>foo(e,p))(a=e.Bar||(e.Bar={}))})(Foo||(Foo={}));\n\n================================================================================\nTestTSMinifyNestedEnum\n---------- /a.js ----------\nfunction foo(){let u;return(n=>(n[n.A=0]=\"A\",n[n.B=1]=\"B\",n[n.C=n]=\"C\"))(u||={}),u}\n\n---------- /b.js ----------\nexport function foo(){let e;return(n=>(n[n.X=0]=\"X\",n[n.Y=1]=\"Y\",n[n.Z=n]=\"Z\"))(e||={}),e}\n\n================================================================================\nTestTSMinifyNestedEnumNoArrow\n---------- /a.js ----------\nfunction foo(){let u;return function(n){n[n.A=0]=\"A\",n[n.B=1]=\"B\",n[n.C=n]=\"C\"}(u||={}),u}\n\n---------- /b.js ----------\nexport function foo(){let e;return function(n){n[n.X=0]=\"X\",n[n.Y=1]=\"Y\",n[n.Z=n]=\"Z\"}(e||={}),e}\n\n================================================================================\nTestTSMinifyNestedEnumNoLogicalAssignment\n---------- /a.js ----------\nfunction foo(){let u;return(n=>(n[n.A=0]=\"A\",n[n.B=1]=\"B\",n[n.C=n]=\"C\"))(u||(u={})),u}\n\n---------- /b.js ----------\nexport function foo(){let e;return(n=>(n[n.X=0]=\"X\",n[n.Y=1]=\"Y\",n[n.Z=n]=\"Z\"))(e||(e={})),e}\n\n================================================================================\nTestTSNamespaceKeepNames\n---------- /out.js ----------\n// entry.ts\nvar ns;\n((ns2) => {\n  ns2.foo = /* @__PURE__ */ __name(() => {\n  }, \"foo\");\n  function bar() {\n  }\n  ns2.bar = bar;\n  __name(bar, \"bar\");\n  class Baz {\n    static {\n      __name(this, \"Baz\");\n    }\n  }\n  ns2.Baz = Baz;\n})(ns || (ns = {}));\n\n================================================================================\nTestTSNamespaceKeepNamesTargetES2015\n---------- /out.js ----------\n// entry.ts\nvar ns;\n((ns2) => {\n  ns2.foo = /* @__PURE__ */ __name(() => {\n  }, \"foo\");\n  function bar() {\n  }\n  ns2.bar = bar;\n  __name(bar, \"bar\");\n  const _Baz = class _Baz {\n  };\n  __name(_Baz, \"Baz\");\n  let Baz = _Baz;\n  ns2.Baz = _Baz;\n})(ns || (ns = {}));\n\n================================================================================\nTestTSPreferJSOverTSInsideNodeModules\n---------- /out/main.js ----------\n// Users/user/project/src/relative/path.ts\nconsole.log(\"success\");\n\n// Users/user/project/node_modules/package/path.js\nconsole.log(\"success\");\n\n// Users/user/project/src/relative2/path.js\nconsole.log(\"success\");\n\n// Users/user/project/node_modules/package2/path.js\nconsole.log(\"success\");\n\n================================================================================\nTestTSPrintNonFiniteNumberInsideWith\n---------- /out.js ----------\nvar Foo = /* @__PURE__ */ ((Foo2) => {\n  Foo2[Foo2[\"NAN\"] = NaN] = \"NAN\";\n  Foo2[Foo2[\"POS_INF\"] = Infinity] = \"POS_INF\";\n  Foo2[Foo2[\"NEG_INF\"] = -Infinity] = \"NEG_INF\";\n  return Foo2;\n})(Foo || {});\n//! It's ok to use \"NaN\" and \"Infinity\" here\nconsole.log(\n  NaN /* NAN */,\n  Infinity /* POS_INF */,\n  -Infinity /* NEG_INF */\n);\ncheckPrecedence(\n  1 / NaN /* NAN */,\n  1 / Infinity /* POS_INF */,\n  1 / -Infinity /* NEG_INF */\n);\n//! We must not use \"NaN\" or \"Infinity\" inside \"with\"\nwith (x) {\n  console.log(\n    0 / 0 /* NAN */,\n    1 / 0 /* POS_INF */,\n    -1 / 0 /* NEG_INF */\n  );\n  checkPrecedence(\n    1 / (0 / 0) /* NAN */,\n    1 / (1 / 0) /* POS_INF */,\n    1 / (-1 / 0) /* NEG_INF */\n  );\n}\n\n================================================================================\nTestTSSiblingEnum\n---------- /out/number.js ----------\nexport var x = /* @__PURE__ */ ((x2) => {\n  x2[x2[\"y\"] = 0] = \"y\";\n  x2[x2[\"yy\"] = 0 /* y */] = \"yy\";\n  return x2;\n})(x || {});\nvar x = /* @__PURE__ */ ((x2) => {\n  x2[x2[\"z\"] = 1] = \"z\";\n  return x2;\n})(x || {});\n((x2) => {\n  console.log(y, z);\n})(x || (x = {}));\nconsole.log(0 /* y */, 1 /* z */);\n\n---------- /out/string.js ----------\nexport var x = /* @__PURE__ */ ((x2) => {\n  x2[\"y\"] = \"a\";\n  x2[\"yy\"] = \"a\" /* y */;\n  return x2;\n})(x || {});\nvar x = /* @__PURE__ */ ((x2) => {\n  x2[\"z\"] = \"a\" /* y */;\n  return x2;\n})(x || {});\n((x2) => {\n  console.log(y, z);\n})(x || (x = {}));\nconsole.log(\"a\" /* y */, \"a\" /* z */);\n\n---------- /out/propagation.js ----------\nexport var a = /* @__PURE__ */ ((a2) => {\n  a2[a2[\"b\"] = 100] = \"b\";\n  return a2;\n})(a || {});\nexport var x = /* @__PURE__ */ ((x2) => {\n  x2[x2[\"c\"] = 100 /* b */] = \"c\";\n  x2[x2[\"d\"] = 200] = \"d\";\n  x2[x2[\"e\"] = 4e4] = \"e\";\n  x2[x2[\"f\"] = 1e4] = \"f\";\n  return x2;\n})(x || {});\nvar x = /* @__PURE__ */ ((x2) => {\n  x2[x2[\"g\"] = 625] = \"g\";\n  return x2;\n})(x || {});\nconsole.log(100 /* b */, 100 /* b */, 625 /* g */, 625 /* g */);\n\n---------- /out/nested-number.js ----------\nexport var foo;\n((foo2) => {\n  let x;\n  ((x2) => {\n    x2[x2[\"y\"] = 0] = \"y\";\n    x2[x2[\"yy\"] = 0 /* y */] = \"yy\";\n  })(x = foo2.x || (foo2.x = {}));\n})(foo || (foo = {}));\n((foo2) => {\n  let x;\n  ((x2) => {\n    x2[x2[\"z\"] = 1] = \"z\";\n  })(x = foo2.x || (foo2.x = {}));\n})(foo || (foo = {}));\n((foo2) => {\n  let x;\n  ((x2) => {\n    console.log(y, z);\n    console.log(0 /* y */, 1 /* z */);\n  })(x = foo2.x || (foo2.x = {}));\n})(foo || (foo = {}));\n\n---------- /out/nested-string.js ----------\nexport var foo;\n((foo2) => {\n  let x;\n  ((x2) => {\n    x2[\"y\"] = \"a\";\n    x2[\"yy\"] = \"a\" /* y */;\n  })(x = foo2.x || (foo2.x = {}));\n})(foo || (foo = {}));\n((foo2) => {\n  let x;\n  ((x2) => {\n    x2[\"z\"] = \"a\" /* y */;\n  })(x = foo2.x || (foo2.x = {}));\n})(foo || (foo = {}));\n((foo2) => {\n  let x;\n  ((x2) => {\n    console.log(y, z);\n    console.log(\"a\" /* y */, \"a\" /* z */);\n  })(x = foo2.x || (foo2.x = {}));\n})(foo || (foo = {}));\n\n---------- /out/nested-propagation.js ----------\nexport var n;\n((n2) => {\n  let a;\n  ((a2) => {\n    a2[a2[\"b\"] = 100] = \"b\";\n  })(a = n2.a || (n2.a = {}));\n})(n || (n = {}));\n((n2) => {\n  let x;\n  ((x2) => {\n    x2[x2[\"c\"] = 100 /* b */] = \"c\";\n    x2[x2[\"d\"] = 200] = \"d\";\n    x2[x2[\"e\"] = 4e4] = \"e\";\n    x2[x2[\"f\"] = 1e4] = \"f\";\n  })(x = n2.x || (n2.x = {}));\n})(n || (n = {}));\n((n2) => {\n  let x;\n  ((x2) => {\n    x2[x2[\"g\"] = 625] = \"g\";\n  })(x = n2.x || (n2.x = {}));\n  console.log(100 /* b */, 100 /* b */, 100 /* b */, 625 /* g */, 625 /* g */, 625 /* g */);\n})(n || (n = {}));\n\n================================================================================\nTestTSSiblingNamespace\n---------- /out/let.js ----------\nexport var x;\n((x2) => {\n  x2.y = 123;\n})(x || (x = {}));\n((x2) => {\n  x2.z = x2.y;\n})(x || (x = {}));\n\n---------- /out/function.js ----------\nexport var x;\n((x2) => {\n  function y() {\n  }\n  x2.y = y;\n})(x || (x = {}));\n((x2) => {\n  x2.z = x2.y;\n})(x || (x = {}));\n\n---------- /out/class.js ----------\nexport var x;\n((x2) => {\n  class y {\n  }\n  x2.y = y;\n})(x || (x = {}));\n((x2) => {\n  x2.z = x2.y;\n})(x || (x = {}));\n\n---------- /out/namespace.js ----------\nexport var x;\n((x2) => {\n  let y;\n  ((y2) => {\n    0;\n  })(y = x2.y || (x2.y = {}));\n})(x || (x = {}));\n((x2) => {\n  x2.z = x2.y;\n})(x || (x = {}));\n\n---------- /out/enum.js ----------\nexport var x;\n((x2) => {\n  let y;\n  ((y2) => {\n  })(y = x2.y || (x2.y = {}));\n})(x || (x = {}));\n((x2) => {\n  x2.z = x2.y;\n})(x || (x = {}));\n\n================================================================================\nTestTSSideEffectsFalseWarningTypeDeclarations\n---------- /out.js ----------\n\n================================================================================\nTestTSThisIsUndefinedWarning\n---------- /out/warning1.js ----------\n// warning1.ts\nvar foo = void 0;\nexport {\n  foo\n};\n\n---------- /out/warning2.js ----------\n// warning2.ts\nvar foo = (void 0).foo;\nexport {\n  foo\n};\n\n---------- /out/warning3.js ----------\n// warning3.ts\nvar foo = void 0 ? (void 0).foo : null;\nexport {\n  foo\n};\n\n---------- /out/silent1.js ----------\n// silent1.ts\nvar foo = void 0;\nexport {\n  foo\n};\n\n---------- /out/silent2.js ----------\n// silent2.ts\nvar foo = void 0;\nexport {\n  foo\n};\n\n================================================================================\nTestThisInsideFunctionTS\n---------- /out.js ----------\n// entry.ts\nfunction foo(x = this) {\n  console.log(this);\n}\nvar objFoo = {\n  foo(x = this) {\n    console.log(this);\n  }\n};\nvar Foo = class {\n  constructor() {\n    this.x = this;\n  }\n  static {\n    this.y = this.z;\n  }\n  foo(x = this) {\n    console.log(this);\n  }\n  static bar(x = this) {\n    console.log(this);\n  }\n};\nnew Foo(foo(objFoo));\nif (nested) {\n  let bar = function(x = this) {\n    console.log(this);\n  };\n  bar2 = bar;\n  const objBar = {\n    foo(x = this) {\n      console.log(this);\n    }\n  };\n  class Bar {\n    constructor() {\n      this.x = this;\n    }\n    static {\n      this.y = this.z;\n    }\n    foo(x = this) {\n      console.log(this);\n    }\n    static bar(x = this) {\n      console.log(this);\n    }\n  }\n  new Bar(bar(objBar));\n}\nvar bar2;\n\n================================================================================\nTestThisInsideFunctionTSNoBundle\n---------- /out.js ----------\nfunction foo(x = this) {\n  console.log(this);\n}\nconst objFoo = {\n  foo(x = this) {\n    console.log(this);\n  }\n};\nclass Foo {\n  constructor() {\n    this.x = this;\n  }\n  static {\n    this.y = this.z;\n  }\n  foo(x = this) {\n    console.log(this);\n  }\n  static bar(x = this) {\n    console.log(this);\n  }\n}\nnew Foo(foo(objFoo));\nif (nested) {\n  let bar2 = function(x = this) {\n    console.log(this);\n  };\n  var bar = bar2;\n  const objBar = {\n    foo(x = this) {\n      console.log(this);\n    }\n  };\n  class Bar {\n    constructor() {\n      this.x = this;\n    }\n    static {\n      this.y = this.z;\n    }\n    foo(x = this) {\n      console.log(this);\n    }\n    static bar(x = this) {\n      console.log(this);\n    }\n  }\n  new Bar(bar2(objBar));\n}\n\n================================================================================\nTestThisInsideFunctionTSNoBundleUseDefineForClassFields\n---------- /out.js ----------\nfunction foo(x = this) {\n  console.log(this);\n}\nconst objFoo = {\n  foo(x = this) {\n    console.log(this);\n  }\n};\nclass Foo {\n  x = this;\n  static y = this.z;\n  foo(x = this) {\n    console.log(this);\n  }\n  static bar(x = this) {\n    console.log(this);\n  }\n}\nnew Foo(foo(objFoo));\nif (nested) {\n  let bar2 = function(x = this) {\n    console.log(this);\n  };\n  var bar = bar2;\n  const objBar = {\n    foo(x = this) {\n      console.log(this);\n    }\n  };\n  class Bar {\n    x = this;\n    static y = this.z;\n    foo(x = this) {\n      console.log(this);\n    }\n    static bar(x = this) {\n      console.log(this);\n    }\n  }\n  new Bar(bar2(objBar));\n}\n\n================================================================================\nTestThisInsideFunctionTSUseDefineForClassFields\n---------- /out.js ----------\n// entry.ts\nfunction foo(x = this) {\n  console.log(this);\n}\nvar objFoo = {\n  foo(x = this) {\n    console.log(this);\n  }\n};\nvar Foo = class {\n  x = this;\n  static y = this.z;\n  foo(x = this) {\n    console.log(this);\n  }\n  static bar(x = this) {\n    console.log(this);\n  }\n};\nnew Foo(foo(objFoo));\nif (nested) {\n  let bar = function(x = this) {\n    console.log(this);\n  };\n  bar2 = bar;\n  const objBar = {\n    foo(x = this) {\n      console.log(this);\n    }\n  };\n  class Bar {\n    x = this;\n    static y = this.z;\n    foo(x = this) {\n      console.log(this);\n    }\n    static bar(x = this) {\n      console.log(this);\n    }\n  }\n  new Bar(bar(objBar));\n}\nvar bar2;\n"
  },
  {
    "path": "internal/bundler_tests/snapshots/snapshots_tsconfig.txt",
    "content": "TestJsconfigJsonBaseUrl\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/lib/util.js\nvar require_util = __commonJS({\n  \"Users/user/project/src/lib/util.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// Users/user/project/src/app/entry.js\nvar import_util = __toESM(require_util());\nconsole.log((0, import_util.default)());\n\n================================================================================\nTestTsconfigAlwaysStrictTrueEmitDirectiveBundleCJS\n---------- /Users/user/project/out/implicit.js ----------\n\"use strict\";\n\n// Users/user/project/src/implicit.ts\nconsole.log('this file should start with \"use strict\"');\n\n---------- /Users/user/project/out/explicit.js ----------\n\"use strict\";\n\n// Users/user/project/src/explicit.ts\nconsole.log('this file should start with \"use strict\"');\n\n================================================================================\nTestTsconfigAlwaysStrictTrueEmitDirectiveBundleESM\n---------- /Users/user/project/out/implicit.js ----------\n// Users/user/project/src/implicit.ts\nconsole.log('this file should not start with \"use strict\"');\n\n---------- /Users/user/project/out/explicit.js ----------\n// Users/user/project/src/explicit.ts\nconsole.log('this file should not start with \"use strict\"');\n\n================================================================================\nTestTsconfigAlwaysStrictTrueEmitDirectiveBundleIIFE\n---------- /Users/user/project/out/implicit.js ----------\n\"use strict\";\n(() => {\n  // Users/user/project/src/implicit.ts\n  console.log('this file should start with \"use strict\"');\n})();\n\n---------- /Users/user/project/out/explicit.js ----------\n\"use strict\";\n(() => {\n  // Users/user/project/src/explicit.ts\n  console.log('this file should start with \"use strict\"');\n})();\n\n================================================================================\nTestTsconfigAlwaysStrictTrueEmitDirectiveFormat\n---------- /Users/user/project/out/implicit.js ----------\n\"use strict\";\nconsole.log('this file should start with \"use strict\"');\n\n---------- /Users/user/project/out/explicit.js ----------\n\"use strict\";\nconsole.log('this file should start with \"use strict\"');\n\n================================================================================\nTestTsconfigAlwaysStrictTrueEmitDirectivePassThrough\n---------- /Users/user/project/out/implicit.js ----------\n\"use strict\";\nconsole.log('this file should start with \"use strict\"');\n\n---------- /Users/user/project/out/explicit.js ----------\n\"use strict\";\nconsole.log('this file should start with \"use strict\"');\n\n================================================================================\nTestTsconfigBaseURLExtendsPaths\n---------- /Users/user/project/out.js ----------\n// Users/user/project/lib/foo.ts\nvar foo = 123;\n\n// Users/user/project/src/entry.ts\nconsole.log(foo);\n\n================================================================================\nTestTsconfigDecoratorsUseDefineForClassFieldsFalse\n---------- /Users/user/project/out/entry.js ----------\n// Users/user/project/src/entry.ts\nvar Class = class {\n};\nvar ClassMethod = class {\n  foo() {\n  }\n};\nvar ClassField = class {\n  constructor() {\n    this.foo = 123;\n  }\n};\nvar ClassAccessor = class {\n  accessor foo = 123;\n  accessor bar;\n};\nnew Class();\nnew ClassMethod();\nnew ClassField();\nnew ClassAccessor();\n\n---------- /Users/user/project/out/entrywithdec.js ----------\n// Users/user/project/src/entrywithdec.ts\nvar _Class_decorators, _init;\n_Class_decorators = [dec];\nvar Class = class {\n};\n_init = __decoratorStart(null);\nClass = __decorateElement(_init, 0, \"Class\", _Class_decorators, Class);\n__runInitializers(_init, 1, Class);\nvar _foo_dec, _init2;\n_foo_dec = [dec];\nvar ClassMethod = class {\n  constructor() {\n    __runInitializers(_init2, 5, this);\n  }\n  foo() {\n  }\n};\n_init2 = __decoratorStart(null);\n__decorateElement(_init2, 1, \"foo\", _foo_dec, ClassMethod);\n__decoratorMetadata(_init2, ClassMethod);\nvar _bar_dec, _foo_dec2, _init3;\n_foo_dec2 = [dec], _bar_dec = [dec];\nvar ClassField = class {\n  constructor() {\n    this.foo = __runInitializers(_init3, 8, this, 123), __runInitializers(_init3, 11, this);\n    this.bar = __runInitializers(_init3, 12, this), __runInitializers(_init3, 15, this);\n  }\n};\n_init3 = __decoratorStart(null);\n__decorateElement(_init3, 5, \"foo\", _foo_dec2, ClassField);\n__decorateElement(_init3, 5, \"bar\", _bar_dec, ClassField);\n__decoratorMetadata(_init3, ClassField);\nvar _bar_dec2, _foo_dec3, _init4, _foo, _bar;\n_foo_dec3 = [dec], _bar_dec2 = [dec];\nvar ClassAccessor = class {\n  constructor() {\n    __privateAdd(this, _foo, __runInitializers(_init4, 8, this, 123)), __runInitializers(_init4, 11, this);\n    __privateAdd(this, _bar, __runInitializers(_init4, 12, this)), __runInitializers(_init4, 15, this);\n  }\n};\n_init4 = __decoratorStart(null);\n_foo = new WeakMap();\n_bar = new WeakMap();\n__decorateElement(_init4, 4, \"foo\", _foo_dec3, ClassAccessor, _foo);\n__decorateElement(_init4, 4, \"bar\", _bar_dec2, ClassAccessor, _bar);\n__decoratorMetadata(_init4, ClassAccessor);\nnew Class();\nnew ClassMethod();\nnew ClassField();\nnew ClassAccessor();\n\n================================================================================\nTestTsconfigExtendsArray\n---------- /Users/user/project/out/main.js ----------\nconsole.log(/* @__PURE__ */ h(frag, null, /* @__PURE__ */ h(\"div\", null)));\n\n================================================================================\nTestTsconfigExtendsArrayNested\n---------- /Users/user/project/out/main.js ----------\nimport { foo } from \"foo\";\nexport class Foo {\n  constructor() {\n    this.render = () => /* @__PURE__ */ b(bBase, null, /* @__PURE__ */ b(\"div\", null));\n  }\n}\n\n================================================================================\nTestTsconfigExtendsDotDotWithSlash\n---------- /Users/user/project/out/main.js ----------\n// Users/user/project/src/main.tsx\nconsole.log(/* @__PURE__ */ React.createElement(\"div\", null));\n\n================================================================================\nTestTsconfigExtendsDotDotWithoutSlash\n---------- /Users/user/project/out/main.js ----------\n// Users/user/project/src/main.tsx\nconsole.log(/* @__PURE__ */ success(\"div\", null));\n\n================================================================================\nTestTsconfigExtendsDotWithSlash\n---------- /Users/user/project/out/main.js ----------\n// Users/user/project/src/main.tsx\nconsole.log(/* @__PURE__ */ React.createElement(\"div\", null));\n\n================================================================================\nTestTsconfigExtendsDotWithoutSlash\n---------- /Users/user/project/out/main.js ----------\n// Users/user/project/src/main.tsx\nconsole.log(/* @__PURE__ */ success(\"div\", null));\n\n================================================================================\nTestTsconfigExtendsWithExports\n---------- /Users/user/project/out/main.js ----------\n// Users/user/project/src/main.tsx\nconsole.log(/* @__PURE__ */ success(\"div\", null));\n\n================================================================================\nTestTsconfigExtendsWithExportsRequire\n---------- /Users/user/project/out/main.js ----------\n// Users/user/project/src/main.tsx\nconsole.log(/* @__PURE__ */ success(\"div\", null));\n\n================================================================================\nTestTsconfigExtendsWithExportsStar\n---------- /Users/user/project/out/main.js ----------\n// Users/user/project/src/main.tsx\nconsole.log(/* @__PURE__ */ success(\"div\", null));\n\n================================================================================\nTestTsconfigExtendsWithExportsStarTrailing\n---------- /Users/user/project/out/main.js ----------\n// Users/user/project/src/main.tsx\nconsole.log(/* @__PURE__ */ success(\"div\", null));\n\n================================================================================\nTestTsconfigIgnoreInsideNodeModules\n---------- /Users/user/project/out/main.js ----------\n// Users/user/project/node_modules/pkg/index.js\nvar foo = \"foo\";\nvar bar = \"bar\";\n\n// Users/user/project/node_modules/js-pkg/index.js\nvar foo2 = foo;\n\n// Users/user/project/node_modules/ts-pkg/index.ts\nvar bar2 = bar;\n\n// Users/user/project/shim.ts\nvar foo3 = \"shimFoo\";\nvar bar3 = \"shimBar\";\n\n// Users/user/project/src/main.ts\nif (foo2 !== \"foo\") throw \"fail: foo\";\nif (bar2 !== \"bar\") throw \"fail: bar\";\nif (foo3 !== \"shimFoo\") throw \"fail: shimFoo\";\nif (bar3 !== \"shimBar\") throw \"fail: shimBar\";\n\n================================================================================\nTestTsconfigIgnoredTargetSilent\n---------- /Users/user/project/out.js ----------\n\n================================================================================\nTestTsconfigImportsNotUsedAsValuesPreserve\n---------- /Users/user/project/out.js ----------\nimport \"./foo\";\nimport \"./foo\";\nimport \"./foo\";\nconsole.log(1, 2, 3);\n\n================================================================================\nTestTsconfigJSX\n---------- /Users/user/project/out.js ----------\n// Users/user/project/entry.tsx\nconsole.log(/* @__PURE__ */ R.c(R.F, null, /* @__PURE__ */ R.c(\"div\", null), /* @__PURE__ */ R.c(\"div\", null)));\n\n================================================================================\nTestTsconfigJsonAbsoluteBaseUrl\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/lib/util.js\nvar require_util = __commonJS({\n  \"Users/user/project/src/lib/util.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// Users/user/project/src/app/entry.js\nvar import_util = __toESM(require_util());\nconsole.log((0, import_util.default)());\n\n================================================================================\nTestTsconfigJsonAsteriskNameCollisionIssue3354\n---------- /Users/user/project/out.js ----------\n// web/bar/foo/foo.ts\nfunction foo() {\n  console.log(\"bar/foo\");\n}\n\n// web/foo.ts\nfunction foo2() {\n  console.log(\"web/foo\");\n  foo();\n}\n\n// entry.ts\nfoo2();\n\n================================================================================\nTestTsconfigJsonBaseUrl\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/lib/util.js\nvar require_util = __commonJS({\n  \"Users/user/project/src/lib/util.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// Users/user/project/src/app/entry.js\nvar import_util = __toESM(require_util());\nconsole.log((0, import_util.default)());\n\n================================================================================\nTestTsconfigJsonBaseUrlIssue3307\n---------- /Users/user/project/out.js ----------\n// test.ts\nvar foo = \"well, this is correct...\";\nexport {\n  foo\n};\n\n================================================================================\nTestTsconfigJsonCommentAllowed\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/lib/util.js\nvar require_util = __commonJS({\n  \"Users/user/project/src/lib/util.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// Users/user/project/src/app/entry.js\nvar import_util = __toESM(require_util());\nconsole.log((0, import_util.default)());\n\n================================================================================\nTestTsconfigJsonConfigDirBaseURL\n---------- /Users/user/project/out.js ----------\n// Users/user/project/lib/foo/bar\nconsole.log(\"works\");\n\n================================================================================\nTestTsconfigJsonConfigDirBaseURLInheritedPaths\n---------- /Users/user/project/out.js ----------\n// Users/user/project/lib/foo/bar\nconsole.log(\"works\");\n\n================================================================================\nTestTsconfigJsonConfigDirPaths\n---------- /Users/user/project/out.js ----------\n// Users/user/project/lib/foo/bar\nconsole.log(\"works\");\n\n================================================================================\nTestTsconfigJsonExtends\n---------- /out.js ----------\n// entry.jsx\nconsole.log(/* @__PURE__ */ baseFactory(\"div\", null), /* @__PURE__ */ baseFactory(derivedFragment, null));\n\n================================================================================\nTestTsconfigJsonExtendsAbsolute\n---------- /out.js ----------\n// Users/user/project/entry.jsx\nconsole.log(/* @__PURE__ */ baseFactory(\"div\", null), /* @__PURE__ */ baseFactory(derivedFragment, null));\n\n================================================================================\nTestTsconfigJsonExtendsArrayIssue3898\n---------- /Users/user/project/out.js ----------\nimport {} from \"MUST_KEEP\";\nconsole.log(SUCCESS(WORKS, null, SUCCESS(\"div\", null)));\n\n================================================================================\nTestTsconfigJsonExtendsLoop\n---------- /out.js ----------\n// entry.js\nconsole.log(123);\n\n================================================================================\nTestTsconfigJsonExtendsPackage\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/app/entry.jsx\nconsole.log(/* @__PURE__ */ worked(\"div\", null));\n\n================================================================================\nTestTsconfigJsonExtendsThreeLevels\n---------- /out.js ----------\n// Users/user/project/src/path2/works/import.js\nconsole.log(\"works\");\n\n// Users/user/project/src/entry.jsx\nconsole.log(/* @__PURE__ */ baseFactory(\"div\", null), /* @__PURE__ */ baseFactory(derivedFragment, null));\n\n================================================================================\nTestTsconfigJsonInsideNodeModules\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/node_modules/foo/index.tsx\nconsole.log(/* @__PURE__ */ React.createElement(\"div\", null));\n\n================================================================================\nTestTsconfigJsonNodeModulesImplicitFile\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/app/entry.tsx\nconsole.log(/* @__PURE__ */ worked(\"div\", null));\n\n================================================================================\nTestTsconfigJsonNodeModulesTsconfigPathBad\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/app/entry.tsx\nconsole.log(/* @__PURE__ */ React.createElement(\"div\", null));\n\n================================================================================\nTestTsconfigJsonNodeModulesTsconfigPathDirectory\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/app/entry.tsx\nconsole.log(/* @__PURE__ */ worked(\"div\", null));\n\n================================================================================\nTestTsconfigJsonNodeModulesTsconfigPathExact\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/app/entry.tsx\nconsole.log(/* @__PURE__ */ worked(\"div\", null));\n\n================================================================================\nTestTsconfigJsonNodeModulesTsconfigPathImplicitJson\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/app/entry.tsx\nconsole.log(/* @__PURE__ */ worked(\"div\", null));\n\n================================================================================\nTestTsconfigJsonOverrideMissing\n---------- /Users/user/project/out.js ----------\n// Users/user/project/other/foo-good.ts\nconsole.log(\"good\");\n\n================================================================================\nTestTsconfigJsonOverrideNodeModules\n---------- /Users/user/project/out.js ----------\n// Users/user/project/other/foo-good.ts\nconsole.log(\"good\");\n\n================================================================================\nTestTsconfigJsonPackagesExternal\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/entry.js\nimport truePkg from \"pkg1\";\n\n// Users/user/project/src/stuff/pkg2.js\nvar pkg2_default = success;\n\n// Users/user/project/src/entry.js\ntruePkg();\npkg2_default();\n\n================================================================================\nTestTsconfigJsonTopLevelMistakeWarning\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/entry.ts\nvar Foo = @foo class {\n};\n\n================================================================================\nTestTsconfigJsonTrailingCommaAllowed\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/lib/util.js\nvar require_util = __commonJS({\n  \"Users/user/project/src/lib/util.js\"(exports, module) {\n    module.exports = function() {\n      return 123;\n    };\n  }\n});\n\n// Users/user/project/src/app/entry.js\nvar import_util = __toESM(require_util());\nconsole.log((0, import_util.default)());\n\n================================================================================\nTestTsconfigNestedJSX\n---------- /Users/user/project/out.js ----------\n// Users/user/project/factory/index.tsx\nvar factory_default = /* @__PURE__ */ h(React.Fragment, null, /* @__PURE__ */ h(\"div\", null), /* @__PURE__ */ h(\"div\", null));\n\n// Users/user/project/fragment/index.tsx\nvar fragment_default = /* @__PURE__ */ React.createElement(a.b, null, /* @__PURE__ */ React.createElement(\"div\", null), /* @__PURE__ */ React.createElement(\"div\", null));\n\n// Users/user/project/both/index.tsx\nvar both_default = /* @__PURE__ */ R.c(R.F, null, /* @__PURE__ */ R.c(\"div\", null), /* @__PURE__ */ R.c(\"div\", null));\n\n// Users/user/project/entry.ts\nconsole.log(factory_default, fragment_default, both_default);\n\n================================================================================\nTestTsconfigPaths\n---------- /Users/user/project/out.js ----------\n// Users/user/project/baseurl_dot/test0-success.ts\nvar test0_success_default = \"test0-success\";\n\n// Users/user/project/baseurl_dot/test1-success.ts\nvar test1_success_default = \"test1-success\";\n\n// Users/user/project/baseurl_dot/test2-success/foo.ts\nvar foo_default = \"test2-success\";\n\n// Users/user/project/baseurl_dot/test3-success.ts\nvar test3_success_default = \"test3-success\";\n\n// Users/user/project/baseurl_dot/test4-first/foo.ts\nvar foo_default2 = \"test4-success\";\n\n// Users/user/project/baseurl_dot/test5-second/foo.ts\nvar foo_default3 = \"test5-success\";\n\n// Users/user/project/baseurl_dot/actual/test.ts\nvar test_default = \"absolute-success\";\n\n// Users/user/project/baseurl_dot/index.ts\nvar baseurl_dot_default = {\n  test0: test0_success_default,\n  test1: test1_success_default,\n  test2: foo_default,\n  test3: test3_success_default,\n  test4: foo_default2,\n  test5: foo_default3,\n  absoluteIn: test_default,\n  absoluteInStar: test_default,\n  absoluteOut: test_default,\n  absoluteOutStar: test_default\n};\n\n// Users/user/project/baseurl_nested/nested/test0-success.ts\nvar test0_success_default2 = \"test0-success\";\n\n// Users/user/project/baseurl_nested/nested/test1-success.ts\nvar test1_success_default2 = \"test1-success\";\n\n// Users/user/project/baseurl_nested/nested/test2-success/foo.ts\nvar foo_default4 = \"test2-success\";\n\n// Users/user/project/baseurl_nested/nested/test3-success.ts\nvar test3_success_default2 = \"test3-success\";\n\n// Users/user/project/baseurl_nested/nested/test4-first/foo.ts\nvar foo_default5 = \"test4-success\";\n\n// Users/user/project/baseurl_nested/nested/test5-second/foo.ts\nvar foo_default6 = \"test5-success\";\n\n// Users/user/project/baseurl_nested/nested/actual/test.ts\nvar test_default2 = \"absolute-success\";\n\n// Users/user/project/baseurl_nested/index.ts\nvar baseurl_nested_default = {\n  test0: test0_success_default2,\n  test1: test1_success_default2,\n  test2: foo_default4,\n  test3: test3_success_default2,\n  test4: foo_default5,\n  test5: foo_default6,\n  absoluteIn: test_default2,\n  absoluteInStar: test_default2,\n  absoluteOut: test_default2,\n  absoluteOutStar: test_default2\n};\n\n// Users/user/project/entry.ts\nconsole.log(baseurl_dot_default, baseurl_nested_default);\n\n================================================================================\nTestTsconfigPathsExtendsBaseURL\n---------- /Users/user/project/out.js ----------\n// Users/user/project/base/test/lib/foo.ts\nvar foo = 123;\n\n// Users/user/project/src/entry.ts\nconsole.log(foo);\n\n================================================================================\nTestTsconfigPathsInNodeModulesIssue2386\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/wow/dist/first.js\nvar first_default = \"dist\";\n\n// Users/user/project/node_modules/wow/dist/next.js\nvar next_default = first_default;\n\n// Users/user/project/main.js\nconsole.log(first_default, next_default);\n\n================================================================================\nTestTsconfigPathsNoBaseURL\n---------- /Users/user/project/out.js ----------\n// Users/user/project/simple/test0-success.ts\nvar test0_success_default = \"test0-success\";\n\n// Users/user/project/simple/test1-success.ts\nvar test1_success_default = \"test1-success\";\n\n// Users/user/project/simple/test2-success/foo.ts\nvar foo_default = \"test2-success\";\n\n// Users/user/project/simple/test3-success.ts\nvar test3_success_default = \"test3-success\";\n\n// Users/user/project/simple/test4-first/foo.ts\nvar foo_default2 = \"test4-success\";\n\n// Users/user/project/simple/test5-second/foo.ts\nvar foo_default3 = \"test5-success\";\n\n// Users/user/project/simple/actual/test.ts\nvar test_default = \"absolute-success\";\n\n// Users/user/project/simple/index.ts\nvar simple_default = {\n  test0: test0_success_default,\n  test1: test1_success_default,\n  test2: foo_default,\n  test3: test3_success_default,\n  test4: foo_default2,\n  test5: foo_default3,\n  absolute: test_default\n};\n\n// Users/user/project/extended/nested/test0-success.ts\nvar test0_success_default2 = \"test0-success\";\n\n// Users/user/project/extended/nested/test1-success.ts\nvar test1_success_default2 = \"test1-success\";\n\n// Users/user/project/extended/nested/test2-success/foo.ts\nvar foo_default4 = \"test2-success\";\n\n// Users/user/project/extended/nested/test3-success.ts\nvar test3_success_default2 = \"test3-success\";\n\n// Users/user/project/extended/nested/test4-first/foo.ts\nvar foo_default5 = \"test4-success\";\n\n// Users/user/project/extended/nested/test5-second/foo.ts\nvar foo_default6 = \"test5-success\";\n\n// Users/user/project/extended/nested/actual/test.ts\nvar test_default2 = \"absolute-success\";\n\n// Users/user/project/extended/index.ts\nvar extended_default = {\n  test0: test0_success_default2,\n  test1: test1_success_default2,\n  test2: foo_default4,\n  test3: test3_success_default2,\n  test4: foo_default5,\n  test5: foo_default6,\n  absolute: test_default2\n};\n\n// Users/user/project/entry.ts\nconsole.log(simple_default, extended_default);\n\n================================================================================\nTestTsconfigPathsOverriddenBaseURL\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/test.ts\nvar test_default = 123;\n\n// Users/user/project/src/entry.ts\nconsole.log(test_default);\n\n================================================================================\nTestTsconfigPathsOverriddenBaseURLDifferentDir\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/test.ts\nvar test_default = 123;\n\n// Users/user/project/src/entry.ts\nconsole.log(test_default);\n\n================================================================================\nTestTsconfigPathsTypeOnly\n---------- /Users/user/project/out.js ----------\n// Users/user/project/node_modules/fib/index.js\nfunction fib(input) {\n  if (input < 2) {\n    return input;\n  }\n  return fib(input - 1) + fib(input - 2);\n}\n\n// Users/user/project/entry.ts\nconsole.log(fib(10));\n\n================================================================================\nTestTsconfigPreserveJSX\n---------- /Users/user/project/out.js ----------\n// Users/user/project/entry.tsx\nconsole.log(/* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(\"div\", null), /* @__PURE__ */ React.createElement(\"div\", null)));\n\n================================================================================\nTestTsconfigPreserveJSXAutomatic\n---------- /Users/user/project/out.js ----------\n// Users/user/project/entry.tsx\nimport { Fragment, jsx, jsxs } from \"react/jsx-runtime\";\nconsole.log(/* @__PURE__ */ jsxs(Fragment, { children: [\n  /* @__PURE__ */ jsx(\"div\", {}),\n  /* @__PURE__ */ jsx(\"div\", {})\n] }));\n\n================================================================================\nTestTsconfigPreserveUnusedImports\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/entry.ts\nimport \"./src/foo\";\nconsole.log(1);\n\n================================================================================\nTestTsconfigPreserveValueImports\n---------- /Users/user/project/out.js ----------\nimport { b1 } from \"b\";\nimport { c1 } from \"c\";\nimport { d1, d2 } from \"d\";\nimport f1 from \"f\";\nimport g1, { g2 } from \"g\";\nimport h1 from \"h\";\nimport * as i1 from \"i\";\nimport \"j\";\n\n================================================================================\nTestTsconfigPreserveValueImportsAndImportsNotUsedAsValuesPreserve\n---------- /Users/user/project/out.js ----------\nimport {} from \"a\";\nimport { b1 } from \"b\";\nimport { c1 } from \"c\";\nimport { d1, d2 } from \"d\";\nimport {} from \"e\";\nimport f1, {} from \"f\";\nimport g1, { g2 } from \"g\";\nimport h1, {} from \"h\";\nimport * as i1 from \"i\";\nimport \"j\";\n\n================================================================================\nTestTsconfigReactJSX\n---------- /Users/user/project/out.js ----------\n// Users/user/project/entry.tsx\nimport { Fragment, jsx, jsxs } from \"notreact/jsx-runtime\";\nconsole.log(/* @__PURE__ */ jsxs(Fragment, { children: [\n  /* @__PURE__ */ jsx(\"div\", {}),\n  /* @__PURE__ */ jsx(\"div\", {})\n] }));\n\n================================================================================\nTestTsconfigReactJSXDev\n---------- /Users/user/project/out.js ----------\n// Users/user/project/entry.tsx\nimport { Fragment, jsxDEV } from \"react/jsx-dev-runtime\";\nconsole.log(/* @__PURE__ */ jsxDEV(Fragment, { children: [\n  /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n    fileName: \"Users/user/project/entry.tsx\",\n    lineNumber: 2,\n    columnNumber: 19\n  }),\n  /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n    fileName: \"Users/user/project/entry.tsx\",\n    lineNumber: 2,\n    columnNumber: 25\n  })\n] }, void 0, true, {\n  fileName: \"Users/user/project/entry.tsx\",\n  lineNumber: 2,\n  columnNumber: 17\n}));\n\n================================================================================\nTestTsconfigReactJSXWithDevInMainConfig\n---------- /Users/user/project/out.js ----------\n// Users/user/project/entry.tsx\nimport { Fragment, jsxDEV } from \"react/jsx-dev-runtime\";\nconsole.log(/* @__PURE__ */ jsxDEV(Fragment, { children: [\n  /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n    fileName: \"Users/user/project/entry.tsx\",\n    lineNumber: 2,\n    columnNumber: 19\n  }),\n  /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\n    fileName: \"Users/user/project/entry.tsx\",\n    lineNumber: 2,\n    columnNumber: 25\n  })\n] }, void 0, true, {\n  fileName: \"Users/user/project/entry.tsx\",\n  lineNumber: 2,\n  columnNumber: 17\n}));\n\n================================================================================\nTestTsconfigRemoveUnusedImports\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/entry.ts\nconsole.log(1);\n\n================================================================================\nTestTsconfigUnrecognizedTargetWarning\n---------- /Users/user/project/out.js ----------\n\n================================================================================\nTestTsconfigUseDefineForClassFieldsES2020\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/entry.ts\nFoo = class {\n  constructor() {\n    this.useDefine = false;\n  }\n};\n\n================================================================================\nTestTsconfigUseDefineForClassFieldsESNext\n---------- /Users/user/project/out.js ----------\n// Users/user/project/src/entry.ts\nFoo = class {\n  useDefine = true;\n};\n\n================================================================================\nTestTsconfigVerbatimModuleSyntaxFalse\n---------- /Users/user/project/out/main.js ----------\nexport { Car } from \"./car\";\n\n================================================================================\nTestTsconfigVerbatimModuleSyntaxTrue\n---------- /Users/user/project/out/main.js ----------\nexport { Car } from \"./car\";\nimport {} from \"./car\";\nexport {} from \"./car\";\nimport { b } from \"bcd\";\nimport {} from \"xyz\";\n\n================================================================================\nTestTsconfigWarningsInsideNodeModules\n---------- /Users/user/project/out.js ----------\n\n================================================================================\nTestTsconfigWithStatementAlwaysStrictFalse\n---------- /Users/user/project/out.js ----------\n(() => {\n  // Users/user/project/src/entry.ts\n  with (x) y;\n})();\n\n================================================================================\nTestTsconfigWithStatementStrictFalse\n---------- /Users/user/project/out.js ----------\n(() => {\n  // Users/user/project/src/entry.ts\n  with (x) y;\n})();\n\n================================================================================\nTestTsconfigWithStatementStrictTrueAlwaysStrictFalse\n---------- /Users/user/project/out.js ----------\n(() => {\n  // Users/user/project/src/entry.ts\n  with (x) y;\n})();\n"
  },
  {
    "path": "internal/bundler_tests/snapshots/snapshots_yarnpnp.txt",
    "content": "TestTsconfigPackageJsonExportsYarnPnP\n---------- /Users/user/project/out.js ----------\n// packages/app/index.tsx\nconsole.log(/* @__PURE__ */ success(\"div\", null));\n\n================================================================================\nTestTsconfigStackOverflowYarnPnP\n---------- /Users/user/project/out.js ----------\n// entry.jsx\nconsole.log(/* @__PURE__ */ success(\"div\", null));\n\n================================================================================\nTestWindowsCrossVolumeReferenceYarnPnP\n---------- D:/project/out.js ----------\n// C:/Users/user/AppData/Local/Yarn/Berry/cache/react.zip/node_modules/react/index.js\nfunction createElement() {\n}\n\n// entry.jsx\nconsole.log(/* @__PURE__ */ createElement(\"div\", null));\n"
  },
  {
    "path": "internal/cache/cache.go",
    "content": "package cache\n\nimport (\n\t\"sync\"\n\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/runtime\"\n)\n\n// This is a cache of the parsed contents of a set of files. The idea is to be\n// able to reuse the results of parsing between builds and make subsequent\n// builds faster by avoiding redundant parsing work. This only works if:\n//\n//   - The AST information in the cache must be considered immutable. There is\n//     no way to enforce this in Go, but please be disciplined about this. The\n//     ASTs are shared in between builds. Any information that must be mutated\n//     in the AST during a build must be done on a shallow clone of the data if\n//     the mutation happens after parsing (i.e. a clone that clones everything\n//     that will be mutated and shares only the parts that won't be mutated).\n//\n//   - The information in the cache must not depend at all on the contents of\n//     any file other than the file being cached. Invalidating an entry in the\n//     cache does not also invalidate any entries that depend on that file, so\n//     caching information that depends on other files can result in incorrect\n//     results due to reusing stale data. For example, do not \"bake in\" some\n//     value imported from another file.\n//\n//   - Cached ASTs must only be reused if the parsing options are identical\n//     between builds. For example, it would be bad if the AST parser depended\n//     on options inherited from a nearby \"package.json\" file but those options\n//     were not part of the cache key. Then the cached AST could incorrectly be\n//     reused even if the contents of that \"package.json\" file have changed.\ntype CacheSet struct {\n\tFSCache          FSCache\n\tCSSCache         CSSCache\n\tJSONCache        JSONCache\n\tJSCache          JSCache\n\tSourceIndexCache SourceIndexCache\n}\n\nfunc MakeCacheSet() *CacheSet {\n\treturn &CacheSet{\n\t\tSourceIndexCache: SourceIndexCache{\n\t\t\tglobEntries:     make(map[uint64]uint32),\n\t\t\tentries:         make(map[sourceIndexKey]uint32),\n\t\t\tnextSourceIndex: runtime.SourceIndex + 1,\n\t\t},\n\t\tFSCache: FSCache{\n\t\t\tentries: make(map[string]*fsEntry),\n\t\t},\n\t\tCSSCache: CSSCache{\n\t\t\tentries: make(map[logger.Path]*cssCacheEntry),\n\t\t},\n\t\tJSONCache: JSONCache{\n\t\t\tentries: make(map[logger.Path]*jsonCacheEntry),\n\t\t},\n\t\tJSCache: JSCache{\n\t\t\tentries: make(map[logger.Path]*jsCacheEntry),\n\t\t},\n\t}\n}\n\ntype SourceIndexCache struct {\n\tglobEntries     map[uint64]uint32\n\tentries         map[sourceIndexKey]uint32\n\tmutex           sync.Mutex\n\tnextSourceIndex uint32\n}\n\ntype SourceIndexKind uint8\n\nconst (\n\tSourceIndexNormal SourceIndexKind = iota\n\tSourceIndexJSStubForCSS\n)\n\ntype sourceIndexKey struct {\n\tpath logger.Path\n\tkind SourceIndexKind\n}\n\nfunc (c *SourceIndexCache) LenHint() uint32 {\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\n\t// Add some extra room at the end for a new file or two without reallocating\n\tconst someExtraRoom = 16\n\treturn c.nextSourceIndex + someExtraRoom\n}\n\nfunc (c *SourceIndexCache) Get(path logger.Path, kind SourceIndexKind) uint32 {\n\tkey := sourceIndexKey{path: path, kind: kind}\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\tif sourceIndex, ok := c.entries[key]; ok {\n\t\treturn sourceIndex\n\t}\n\tsourceIndex := c.nextSourceIndex\n\tc.nextSourceIndex++\n\tc.entries[key] = sourceIndex\n\treturn sourceIndex\n}\n\nfunc (c *SourceIndexCache) GetGlob(parentSourceIndex uint32, globIndex uint32) uint32 {\n\tkey := (uint64(parentSourceIndex) << 32) | uint64(globIndex)\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\tif sourceIndex, ok := c.globEntries[key]; ok {\n\t\treturn sourceIndex\n\t}\n\tsourceIndex := c.nextSourceIndex\n\tc.nextSourceIndex++\n\tc.globEntries[key] = sourceIndex\n\treturn sourceIndex\n}\n"
  },
  {
    "path": "internal/cache/cache_ast.go",
    "content": "package cache\n\nimport (\n\t\"sync\"\n\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_parser\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/js_parser\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\n// This cache intends to avoid unnecessarily re-parsing files in subsequent\n// builds. For a given path, parsing can be avoided if the contents of the file\n// and the options for the parser are the same as last time. Even if the\n// contents of the file are the same, the options for the parser may have\n// changed if they depend on some other file (\"package.json\" for example).\n//\n// This cache checks if the file contents have changed even though we have\n// the ability to detect if a file has changed on the file system by reading\n// its metadata. First of all, if the file contents are cached then they should\n// be the same pointer, which makes the comparison trivial. Also we want to\n// cache the AST for plugins in the common case that the plugin output stays\n// the same.\n\n////////////////////////////////////////////////////////////////////////////////\n// CSS\n\ntype CSSCache struct {\n\tentries map[logger.Path]*cssCacheEntry\n\tmutex   sync.Mutex\n}\n\ntype cssCacheEntry struct {\n\tsource  logger.Source\n\tmsgs    []logger.Msg\n\tast     css_ast.AST\n\toptions css_parser.Options\n}\n\nfunc (c *CSSCache) Parse(log logger.Log, source logger.Source, options css_parser.Options) css_ast.AST {\n\t// Check the cache\n\tentry := func() *cssCacheEntry {\n\t\tc.mutex.Lock()\n\t\tdefer c.mutex.Unlock()\n\t\treturn c.entries[source.KeyPath]\n\t}()\n\n\t// Cache hit\n\tif entry != nil && entry.source == source && entry.options.Equal(&options) {\n\t\tfor _, msg := range entry.msgs {\n\t\t\tlog.AddMsg(msg)\n\t\t}\n\t\treturn entry.ast\n\t}\n\n\t// Cache miss\n\ttempLog := logger.NewDeferLog(logger.DeferLogAll, log.Overrides)\n\tast := css_parser.Parse(tempLog, source, options)\n\tmsgs := tempLog.Done()\n\tfor _, msg := range msgs {\n\t\tlog.AddMsg(msg)\n\t}\n\n\t// Create the cache entry\n\tentry = &cssCacheEntry{\n\t\tsource:  source,\n\t\toptions: options,\n\t\tast:     ast,\n\t\tmsgs:    msgs,\n\t}\n\n\t// Save for next time\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\tc.entries[source.KeyPath] = entry\n\treturn ast\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// JSON\n\ntype JSONCache struct {\n\tentries map[logger.Path]*jsonCacheEntry\n\tmutex   sync.Mutex\n}\n\ntype jsonCacheEntry struct {\n\texpr    js_ast.Expr\n\tmsgs    []logger.Msg\n\tsource  logger.Source\n\toptions js_parser.JSONOptions\n\tok      bool\n}\n\nfunc (c *JSONCache) Parse(log logger.Log, source logger.Source, options js_parser.JSONOptions) (js_ast.Expr, bool) {\n\t// Check the cache\n\tentry := func() *jsonCacheEntry {\n\t\tc.mutex.Lock()\n\t\tdefer c.mutex.Unlock()\n\t\treturn c.entries[source.KeyPath]\n\t}()\n\n\t// Cache hit\n\tif entry != nil && entry.source == source && entry.options == options {\n\t\tfor _, msg := range entry.msgs {\n\t\t\tlog.AddMsg(msg)\n\t\t}\n\t\treturn entry.expr, entry.ok\n\t}\n\n\t// Cache miss\n\ttempLog := logger.NewDeferLog(logger.DeferLogAll, log.Overrides)\n\texpr, ok := js_parser.ParseJSON(tempLog, source, options)\n\tmsgs := tempLog.Done()\n\tfor _, msg := range msgs {\n\t\tlog.AddMsg(msg)\n\t}\n\n\t// Create the cache entry\n\tentry = &jsonCacheEntry{\n\t\tsource:  source,\n\t\toptions: options,\n\t\texpr:    expr,\n\t\tok:      ok,\n\t\tmsgs:    msgs,\n\t}\n\n\t// Save for next time\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\tc.entries[source.KeyPath] = entry\n\treturn expr, ok\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// JS\n\ntype JSCache struct {\n\tentries map[logger.Path]*jsCacheEntry\n\tmutex   sync.Mutex\n}\n\ntype jsCacheEntry struct {\n\tsource  logger.Source\n\tmsgs    []logger.Msg\n\toptions js_parser.Options\n\tast     js_ast.AST\n\tok      bool\n}\n\nfunc (c *JSCache) Parse(log logger.Log, source logger.Source, options js_parser.Options) (js_ast.AST, bool) {\n\t// Check the cache\n\tentry := func() *jsCacheEntry {\n\t\tc.mutex.Lock()\n\t\tdefer c.mutex.Unlock()\n\t\treturn c.entries[source.KeyPath]\n\t}()\n\n\t// Cache hit\n\tif entry != nil && entry.source == source && entry.options.Equal(&options) {\n\t\tfor _, msg := range entry.msgs {\n\t\t\tlog.AddMsg(msg)\n\t\t}\n\t\treturn entry.ast, entry.ok\n\t}\n\n\t// Cache miss\n\ttempLog := logger.NewDeferLog(logger.DeferLogAll, log.Overrides)\n\tast, ok := js_parser.Parse(tempLog, source, options)\n\tmsgs := tempLog.Done()\n\tfor _, msg := range msgs {\n\t\tlog.AddMsg(msg)\n\t}\n\n\t// Create the cache entry\n\tentry = &jsCacheEntry{\n\t\tsource:  source,\n\t\toptions: options,\n\t\tast:     ast,\n\t\tok:      ok,\n\t\tmsgs:    msgs,\n\t}\n\n\t// Save for next time\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\tc.entries[source.KeyPath] = entry\n\treturn ast, ok\n}\n"
  },
  {
    "path": "internal/cache/cache_fs.go",
    "content": "package cache\n\nimport (\n\t\"sync\"\n\n\t\"github.com/evanw/esbuild/internal/fs\"\n)\n\n// This cache uses information from the \"stat\" syscall to try to avoid re-\n// reading files from the file system during subsequent builds if the file\n// hasn't changed. The assumption is reading the file metadata is faster than\n// reading the file contents.\n\ntype FSCache struct {\n\tentries map[string]*fsEntry\n\tmutex   sync.Mutex\n}\n\ntype fsEntry struct {\n\tcontents       string\n\tmodKey         fs.ModKey\n\tisModKeyUsable bool\n}\n\nfunc (c *FSCache) ReadFile(fs fs.FS, path string) (contents string, canonicalError error, originalError error) {\n\tentry := func() *fsEntry {\n\t\tc.mutex.Lock()\n\t\tdefer c.mutex.Unlock()\n\t\treturn c.entries[path]\n\t}()\n\n\t// If the file's modification key hasn't changed since it was cached, assume\n\t// the contents of the file are also the same and skip reading the file.\n\tmodKey, modKeyErr := fs.ModKey(path)\n\tif entry != nil && entry.isModKeyUsable && modKeyErr == nil && entry.modKey == modKey {\n\t\treturn entry.contents, nil, nil\n\t}\n\n\tcontents, err, originalError := fs.ReadFile(path)\n\tif err != nil {\n\t\treturn \"\", err, originalError\n\t}\n\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\tc.entries[path] = &fsEntry{\n\t\tcontents:       contents,\n\t\tmodKey:         modKey,\n\t\tisModKeyUsable: modKeyErr == nil,\n\t}\n\treturn contents, nil, nil\n}\n"
  },
  {
    "path": "internal/cli_helpers/cli_helpers.go",
    "content": "// This package contains internal CLI-related code that must be shared with\n// other internal code outside of the CLI package.\n\npackage cli_helpers\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/evanw/esbuild/pkg/api\"\n)\n\ntype ErrorWithNote struct {\n\tText string\n\tNote string\n}\n\nfunc MakeErrorWithNote(text string, note string) *ErrorWithNote {\n\treturn &ErrorWithNote{\n\t\tText: text,\n\t\tNote: note,\n\t}\n}\n\nfunc ParseLoader(text string) (api.Loader, *ErrorWithNote) {\n\tswitch text {\n\tcase \"base64\":\n\t\treturn api.LoaderBase64, nil\n\tcase \"binary\":\n\t\treturn api.LoaderBinary, nil\n\tcase \"copy\":\n\t\treturn api.LoaderCopy, nil\n\tcase \"css\":\n\t\treturn api.LoaderCSS, nil\n\tcase \"dataurl\":\n\t\treturn api.LoaderDataURL, nil\n\tcase \"default\":\n\t\treturn api.LoaderDefault, nil\n\tcase \"empty\":\n\t\treturn api.LoaderEmpty, nil\n\tcase \"file\":\n\t\treturn api.LoaderFile, nil\n\tcase \"global-css\":\n\t\treturn api.LoaderGlobalCSS, nil\n\tcase \"js\":\n\t\treturn api.LoaderJS, nil\n\tcase \"json\":\n\t\treturn api.LoaderJSON, nil\n\tcase \"jsx\":\n\t\treturn api.LoaderJSX, nil\n\tcase \"local-css\":\n\t\treturn api.LoaderLocalCSS, nil\n\tcase \"text\":\n\t\treturn api.LoaderText, nil\n\tcase \"ts\":\n\t\treturn api.LoaderTS, nil\n\tcase \"tsx\":\n\t\treturn api.LoaderTSX, nil\n\tdefault:\n\t\treturn api.LoaderNone, MakeErrorWithNote(\n\t\t\tfmt.Sprintf(\"Invalid loader value: %q\", text),\n\t\t\t\"Valid values are \\\"base64\\\", \\\"binary\\\", \\\"copy\\\", \\\"css\\\", \\\"dataurl\\\", \\\"empty\\\", \\\"file\\\", \\\"global-css\\\", \\\"js\\\", \\\"json\\\", \\\"jsx\\\", \\\"local-css\\\", \\\"text\\\", \\\"ts\\\", or \\\"tsx\\\".\",\n\t\t)\n\t}\n}\n"
  },
  {
    "path": "internal/compat/compat.go",
    "content": "package compat\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n)\n\ntype v struct {\n\tmajor uint16\n\tminor uint8\n\tpatch uint8\n}\n\ntype Semver struct {\n\t// \"1.2.3-alpha\" => { Parts: {1, 2, 3}, PreRelease: \"-alpha\" }\n\tParts      []int\n\tPreRelease string\n}\n\nfunc (v Semver) String() string {\n\tb := strings.Builder{}\n\tfor _, part := range v.Parts {\n\t\tif b.Len() > 0 {\n\t\t\tb.WriteRune('.')\n\t\t}\n\t\tb.WriteString(strconv.Itoa(part))\n\t}\n\tb.WriteString(v.PreRelease)\n\treturn b.String()\n}\n\n// Returns <0 if \"a < b\"\n// Returns 0 if \"a == b\"\n// Returns >0 if \"a > b\"\nfunc compareVersions(a v, b Semver) int {\n\tdiff := int(a.major)\n\tif len(b.Parts) > 0 {\n\t\tdiff -= b.Parts[0]\n\t}\n\tif diff == 0 {\n\t\tdiff = int(a.minor)\n\t\tif len(b.Parts) > 1 {\n\t\t\tdiff -= b.Parts[1]\n\t\t}\n\t}\n\tif diff == 0 {\n\t\tdiff = int(a.patch)\n\t\tif len(b.Parts) > 2 {\n\t\t\tdiff -= b.Parts[2]\n\t\t}\n\t}\n\tif diff == 0 && len(b.PreRelease) != 0 {\n\t\treturn 1 // \"1.0.0\" > \"1.0.0-alpha\"\n\t}\n\treturn diff\n}\n\n// The start is inclusive and the end is exclusive\ntype versionRange struct {\n\tstart v\n\tend   v // Use 0.0.0 for \"no end\"\n}\n\nfunc isVersionSupported(ranges []versionRange, version Semver) bool {\n\tfor _, r := range ranges {\n\t\tif compareVersions(r.start, version) <= 0 && (r.end == (v{}) || compareVersions(r.end, version) > 0) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc SymbolFeature(kind ast.SymbolKind) JSFeature {\n\tswitch kind {\n\tcase ast.SymbolPrivateField:\n\t\treturn ClassPrivateField\n\tcase ast.SymbolPrivateMethod:\n\t\treturn ClassPrivateMethod\n\tcase ast.SymbolPrivateGet, ast.SymbolPrivateSet, ast.SymbolPrivateGetSetPair:\n\t\treturn ClassPrivateAccessor\n\tcase ast.SymbolPrivateStaticField:\n\t\treturn ClassPrivateStaticField\n\tcase ast.SymbolPrivateStaticMethod:\n\t\treturn ClassPrivateStaticMethod\n\tcase ast.SymbolPrivateStaticGet, ast.SymbolPrivateStaticSet, ast.SymbolPrivateStaticGetSetPair:\n\t\treturn ClassPrivateStaticAccessor\n\tdefault:\n\t\treturn 0\n\t}\n}\n"
  },
  {
    "path": "internal/compat/compat_test.go",
    "content": "package compat\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/test\"\n)\n\nfunc TestCompareVersions(t *testing.T) {\n\tt.Helper()\n\n\tcheck := func(a v, b Semver, expected rune) {\n\t\tt.Helper()\n\n\t\tat := fmt.Sprintf(\"%d.%d.%d\", a.major, a.minor, a.patch)\n\t\tbt := b.String()\n\n\t\tt.Run(fmt.Sprintf(\"%q ? %q\", at, bt), func(t *testing.T) {\n\t\t\tobserved := '='\n\t\t\tif result := compareVersions(a, b); result < 0 {\n\t\t\t\tobserved = '<'\n\t\t\t} else if result > 0 {\n\t\t\t\tobserved = '>'\n\t\t\t}\n\t\t\tif observed != expected {\n\t\t\t\ttest.AssertEqual(t, fmt.Sprintf(\"%c\", observed), fmt.Sprintf(\"%c\", expected))\n\t\t\t}\n\t\t})\n\t}\n\n\tcheck(v{0, 0, 0}, Semver{}, '=')\n\n\tcheck(v{1, 0, 0}, Semver{}, '>')\n\tcheck(v{0, 1, 0}, Semver{}, '>')\n\tcheck(v{0, 0, 1}, Semver{}, '>')\n\n\tcheck(v{0, 0, 0}, Semver{Parts: []int{1}}, '<')\n\tcheck(v{0, 0, 0}, Semver{Parts: []int{0, 1}}, '<')\n\tcheck(v{0, 0, 0}, Semver{Parts: []int{0, 0, 1}}, '<')\n\n\tcheck(v{0, 4, 0}, Semver{Parts: []int{0, 5, 0}}, '<')\n\tcheck(v{0, 5, 0}, Semver{Parts: []int{0, 5, 0}}, '=')\n\tcheck(v{0, 6, 0}, Semver{Parts: []int{0, 5, 0}}, '>')\n\n\tcheck(v{0, 5, 0}, Semver{Parts: []int{0, 5, 1}}, '<')\n\tcheck(v{0, 5, 0}, Semver{Parts: []int{0, 5, 0}}, '=')\n\tcheck(v{0, 5, 1}, Semver{Parts: []int{0, 5, 0}}, '>')\n\n\tcheck(v{0, 5, 0}, Semver{Parts: []int{0, 5}}, '=')\n\tcheck(v{0, 5, 1}, Semver{Parts: []int{0, 5}}, '>')\n\n\tcheck(v{1, 0, 0}, Semver{Parts: []int{1}}, '=')\n\tcheck(v{1, 1, 0}, Semver{Parts: []int{1}}, '>')\n\tcheck(v{1, 0, 1}, Semver{Parts: []int{1}}, '>')\n\n\tcheck(v{1, 2, 0}, Semver{Parts: []int{1, 2}, PreRelease: \"-pre\"}, '>')\n\tcheck(v{1, 2, 1}, Semver{Parts: []int{1, 2}, PreRelease: \"-pre\"}, '>')\n\tcheck(v{1, 1, 0}, Semver{Parts: []int{1, 2}, PreRelease: \"-pre\"}, '<')\n\n\tcheck(v{1, 2, 3}, Semver{Parts: []int{1, 2, 3}, PreRelease: \"-pre\"}, '>')\n\tcheck(v{1, 2, 2}, Semver{Parts: []int{1, 2, 3}, PreRelease: \"-pre\"}, '<')\n}\n"
  },
  {
    "path": "internal/compat/css_table.go",
    "content": "// This file was automatically generated by \"css_table.ts\"\n\npackage compat\n\nimport (\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n)\n\ntype CSSFeature uint16\n\nconst (\n\tColorFunctions CSSFeature = 1 << iota\n\tGradientDoublePosition\n\tGradientInterpolation\n\tGradientMidpoints\n\tHWB\n\tHexRGBA\n\tInlineStyle\n\tInsetProperty\n\tIsPseudoClass\n\tMediaRange\n\tModern_RGB_HSL\n\tNesting\n\tRebeccaPurple\n)\n\nvar StringToCSSFeature = map[string]CSSFeature{\n\t\"color-functions\":          ColorFunctions,\n\t\"gradient-double-position\": GradientDoublePosition,\n\t\"gradient-interpolation\":   GradientInterpolation,\n\t\"gradient-midpoints\":       GradientMidpoints,\n\t\"hwb\":                      HWB,\n\t\"hex-rgba\":                 HexRGBA,\n\t\"inline-style\":             InlineStyle,\n\t\"inset-property\":           InsetProperty,\n\t\"is-pseudo-class\":          IsPseudoClass,\n\t\"media-range\":              MediaRange,\n\t\"modern-rgb-hsl\":           Modern_RGB_HSL,\n\t\"nesting\":                  Nesting,\n\t\"rebecca-purple\":           RebeccaPurple,\n}\n\nfunc (features CSSFeature) Has(feature CSSFeature) bool {\n\treturn (features & feature) != 0\n}\n\nfunc (features CSSFeature) ApplyOverrides(overrides CSSFeature, mask CSSFeature) CSSFeature {\n\treturn (features & ^mask) | (overrides & mask)\n}\n\nvar cssTable = map[CSSFeature]map[Engine][]versionRange{\n\tColorFunctions: {\n\t\tChrome:  {{start: v{111, 0, 0}}},\n\t\tEdge:    {{start: v{111, 0, 0}}},\n\t\tFirefox: {{start: v{113, 0, 0}}},\n\t\tIOS:     {{start: v{15, 4, 0}}},\n\t\tOpera:   {{start: v{97, 0, 0}}},\n\t\tSafari:  {{start: v{15, 4, 0}}},\n\t},\n\tGradientDoublePosition: {\n\t\tChrome:  {{start: v{72, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tFirefox: {{start: v{83, 0, 0}}},\n\t\tIOS:     {{start: v{12, 2, 0}}},\n\t\tOpera:   {{start: v{60, 0, 0}}},\n\t\tSafari:  {{start: v{12, 1, 0}}},\n\t},\n\tGradientInterpolation: {\n\t\tChrome:  {{start: v{111, 0, 0}}},\n\t\tEdge:    {{start: v{111, 0, 0}}},\n\t\tFirefox: {{start: v{137, 0, 0}}},\n\t\tIOS:     {{start: v{16, 2, 0}}},\n\t\tOpera:   {{start: v{97, 0, 0}}},\n\t\tSafari:  {{start: v{16, 2, 0}}},\n\t},\n\tGradientMidpoints: {\n\t\tChrome:  {{start: v{40, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tFirefox: {{start: v{36, 0, 0}}},\n\t\tIOS:     {{start: v{7, 0, 0}}},\n\t\tOpera:   {{start: v{27, 0, 0}}},\n\t\tSafari:  {{start: v{7, 0, 0}}},\n\t},\n\tHWB: {\n\t\tChrome:  {{start: v{101, 0, 0}}},\n\t\tEdge:    {{start: v{101, 0, 0}}},\n\t\tFirefox: {{start: v{96, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tOpera:   {{start: v{87, 0, 0}}},\n\t\tSafari:  {{start: v{15, 0, 0}}},\n\t},\n\tHexRGBA: {\n\t\tChrome:  {{start: v{62, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tFirefox: {{start: v{49, 0, 0}}},\n\t\tIOS:     {{start: v{9, 3, 0}}},\n\t\tOpera:   {{start: v{49, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tInlineStyle: {},\n\tInsetProperty: {\n\t\tChrome:  {{start: v{87, 0, 0}}},\n\t\tEdge:    {{start: v{87, 0, 0}}},\n\t\tFirefox: {{start: v{66, 0, 0}}},\n\t\tIOS:     {{start: v{14, 5, 0}}},\n\t\tOpera:   {{start: v{73, 0, 0}}},\n\t\tSafari:  {{start: v{14, 1, 0}}},\n\t},\n\tIsPseudoClass: {\n\t\tChrome:  {{start: v{88, 0, 0}}},\n\t\tEdge:    {{start: v{88, 0, 0}}},\n\t\tFirefox: {{start: v{78, 0, 0}}},\n\t\tIOS:     {{start: v{14, 0, 0}}},\n\t\tOpera:   {{start: v{75, 0, 0}}},\n\t\tSafari:  {{start: v{14, 0, 0}}},\n\t},\n\tMediaRange: {\n\t\tChrome:  {{start: v{104, 0, 0}}},\n\t\tEdge:    {{start: v{104, 0, 0}}},\n\t\tFirefox: {{start: v{63, 0, 0}}},\n\t\tIOS:     {{start: v{16, 4, 0}}},\n\t\tOpera:   {{start: v{91, 0, 0}}},\n\t\tSafari:  {{start: v{16, 4, 0}}},\n\t},\n\tModern_RGB_HSL: {\n\t\tChrome:  {{start: v{66, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tFirefox: {{start: v{52, 0, 0}}},\n\t\tIOS:     {{start: v{12, 2, 0}}},\n\t\tOpera:   {{start: v{53, 0, 0}}},\n\t\tSafari:  {{start: v{12, 1, 0}}},\n\t},\n\tNesting: {\n\t\tChrome:  {{start: v{120, 0, 0}}},\n\t\tEdge:    {{start: v{120, 0, 0}}},\n\t\tFirefox: {{start: v{117, 0, 0}}},\n\t\tIOS:     {{start: v{17, 2, 0}}},\n\t\tOpera:   {{start: v{106, 0, 0}}},\n\t\tSafari:  {{start: v{17, 2, 0}}},\n\t},\n\tRebeccaPurple: {\n\t\tChrome:  {{start: v{38, 0, 0}}},\n\t\tEdge:    {{start: v{12, 0, 0}}},\n\t\tFirefox: {{start: v{33, 0, 0}}},\n\t\tIE:      {{start: v{11, 0, 0}}},\n\t\tIOS:     {{start: v{8, 0, 0}}},\n\t\tOpera:   {{start: v{25, 0, 0}}},\n\t\tSafari:  {{start: v{9, 0, 0}}},\n\t},\n}\n\n// Return all features that are not available in at least one environment\nfunc UnsupportedCSSFeatures(constraints map[Engine]Semver) (unsupported CSSFeature) {\n\tfor feature, engines := range cssTable {\n\t\tif feature == InlineStyle {\n\t\t\tcontinue // This is purely user-specified\n\t\t}\n\t\tfor engine, version := range constraints {\n\t\t\tif !engine.IsBrowser() {\n\t\t\t\t// Specifying \"--target=es2020\" shouldn't affect CSS\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif versionRanges, ok := engines[engine]; !ok || !isVersionSupported(versionRanges, version) {\n\t\t\t\tunsupported |= feature\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\ntype CSSPrefix uint8\n\nconst (\n\tKhtmlPrefix CSSPrefix = 1 << iota\n\tMozPrefix\n\tMsPrefix\n\tOPrefix\n\tWebkitPrefix\n\n\tNoPrefix CSSPrefix = 0\n)\n\ntype prefixData struct {\n\t// Note: In some cases, earlier versions did not require a prefix but later\n\t// ones do. This is the case for Microsoft Edge for example, which switched\n\t// the underlying browser engine from a custom one to the one from Chrome.\n\t// However, we assume that users specifying a browser version for CSS mean\n\t// \"works in this version or newer\", so we still add a prefix when a target\n\t// is an old Edge version.\n\tengine        Engine\n\twithoutPrefix v\n\tprefix        CSSPrefix\n}\n\nvar cssPrefixTable = map[css_ast.D][]prefixData{\n\tcss_ast.DAppearance: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{84, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{84, 0, 0}},\n\t\t{engine: Firefox, prefix: MozPrefix, withoutPrefix: v{80, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{73, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t},\n\tcss_ast.DBackdropFilter: {\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{18, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{18, 0, 0}},\n\t},\n\tcss_ast.DBackgroundClip: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: Edge, prefix: MsPrefix, withoutPrefix: v{15, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{106, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{5, 0, 0}},\n\t},\n\tcss_ast.DBoxDecorationBreak: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{130, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{130, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{116, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix},\n\t},\n\tcss_ast.DClipPath: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{55, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{13, 0, 0}},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{42, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{13, 1, 0}},\n\t},\n\tcss_ast.DFontKerning: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{33, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{12, 0, 0}},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{20, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{9, 1, 0}},\n\t},\n\tcss_ast.DHeight: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{138, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{138, 0, 0}},\n\t\t{engine: Firefox, prefix: WebkitPrefix},\n\t\t{engine: IOS, prefix: WebkitPrefix},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{122, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix},\n\t},\n\tcss_ast.DHyphens: {\n\t\t{engine: Edge, prefix: MsPrefix, withoutPrefix: v{79, 0, 0}},\n\t\t{engine: Firefox, prefix: MozPrefix, withoutPrefix: v{43, 0, 0}},\n\t\t{engine: IE, prefix: MsPrefix},\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{17, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{17, 0, 0}},\n\t},\n\tcss_ast.DInitialLetter: {\n\t\t{engine: IOS, prefix: WebkitPrefix},\n\t\t{engine: Safari, prefix: WebkitPrefix},\n\t},\n\tcss_ast.DMask: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{106, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t},\n\tcss_ast.DMaskComposite: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{106, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t},\n\tcss_ast.DMaskImage: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t\t{engine: Opera, prefix: WebkitPrefix},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t},\n\tcss_ast.DMaskOrigin: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{106, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t},\n\tcss_ast.DMaskPosition: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{106, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t},\n\tcss_ast.DMaskRepeat: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{106, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t},\n\tcss_ast.DMaskSize: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{120, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{106, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t},\n\tcss_ast.DMaxHeight: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{138, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{138, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{122, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix},\n\t},\n\tcss_ast.DMaxWidth: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{138, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{138, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{122, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix},\n\t},\n\tcss_ast.DMinHeight: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{138, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{138, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{122, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix},\n\t},\n\tcss_ast.DMinWidth: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{138, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{138, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{122, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix},\n\t},\n\tcss_ast.DPosition: {\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{13, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{13, 0, 0}},\n\t},\n\tcss_ast.DPrintColorAdjust: {\n\t\t{engine: Chrome, prefix: WebkitPrefix},\n\t\t{engine: Edge, prefix: WebkitPrefix},\n\t\t{engine: Opera, prefix: WebkitPrefix},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},\n\t},\n\tcss_ast.DTabSize: {\n\t\t{engine: Firefox, prefix: MozPrefix, withoutPrefix: v{91, 0, 0}},\n\t\t{engine: Opera, prefix: OPrefix, withoutPrefix: v{15, 0, 0}},\n\t},\n\tcss_ast.DTextDecorationColor: {\n\t\t{engine: Firefox, prefix: MozPrefix, withoutPrefix: v{36, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{12, 2, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{12, 1, 0}},\n\t},\n\tcss_ast.DTextDecorationLine: {\n\t\t{engine: Firefox, prefix: MozPrefix, withoutPrefix: v{36, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{12, 2, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{12, 1, 0}},\n\t},\n\tcss_ast.DTextDecorationSkip: {\n\t\t{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{12, 2, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{12, 1, 0}},\n\t},\n\tcss_ast.DTextEmphasisColor: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{99, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{99, 0, 0}},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{85, 0, 0}},\n\t},\n\tcss_ast.DTextEmphasisPosition: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{99, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{99, 0, 0}},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{85, 0, 0}},\n\t},\n\tcss_ast.DTextEmphasisStyle: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{99, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{99, 0, 0}},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{85, 0, 0}},\n\t},\n\tcss_ast.DTextOrientation: {\n\t\t{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{14, 0, 0}},\n\t},\n\tcss_ast.DTextSizeAdjust: {\n\t\t{engine: Edge, prefix: MsPrefix, withoutPrefix: v{79, 0, 0}},\n\t\t{engine: IOS, prefix: WebkitPrefix},\n\t},\n\tcss_ast.DUserSelect: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{54, 0, 0}},\n\t\t{engine: Edge, prefix: MsPrefix, withoutPrefix: v{79, 0, 0}},\n\t\t{engine: Firefox, prefix: MozPrefix, withoutPrefix: v{69, 0, 0}},\n\t\t{engine: IE, prefix: MsPrefix},\n\t\t{engine: IOS, prefix: WebkitPrefix},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{41, 0, 0}},\n\t\t{engine: Safari, prefix: KhtmlPrefix, withoutPrefix: v{3, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix},\n\t},\n\tcss_ast.DWidth: {\n\t\t{engine: Chrome, prefix: WebkitPrefix, withoutPrefix: v{138, 0, 0}},\n\t\t{engine: Edge, prefix: WebkitPrefix, withoutPrefix: v{138, 0, 0}},\n\t\t{engine: Firefox, prefix: WebkitPrefix},\n\t\t{engine: IOS, prefix: WebkitPrefix},\n\t\t{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{122, 0, 0}},\n\t\t{engine: Safari, prefix: WebkitPrefix},\n\t},\n}\n\nfunc CSSPrefixData(constraints map[Engine]Semver) (entries map[css_ast.D]CSSPrefix) {\n\tfor property, items := range cssPrefixTable {\n\t\tprefixes := NoPrefix\n\t\tfor engine, version := range constraints {\n\t\t\tif !engine.IsBrowser() {\n\t\t\t\t// Specifying \"--target=es2020\" shouldn't affect CSS\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfor _, item := range items {\n\t\t\t\tif item.engine == engine && (item.withoutPrefix == v{} || compareVersions(item.withoutPrefix, version) > 0) {\n\t\t\t\t\tprefixes |= item.prefix\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif prefixes != NoPrefix {\n\t\t\tif entries == nil {\n\t\t\t\tentries = make(map[css_ast.D]CSSPrefix)\n\t\t\t}\n\t\t\tentries[property] = prefixes\n\t\t}\n\t}\n\treturn\n}\n"
  },
  {
    "path": "internal/compat/js_table.go",
    "content": "// This file was automatically generated by \"js_table.ts\"\n\npackage compat\n\ntype Engine uint8\n\nconst (\n\tChrome Engine = iota\n\tDeno\n\tEdge\n\tES\n\tFirefox\n\tHermes\n\tIE\n\tIOS\n\tNode\n\tOpera\n\tRhino\n\tSafari\n)\n\nfunc (e Engine) String() string {\n\tswitch e {\n\tcase Chrome:\n\t\treturn \"chrome\"\n\tcase Deno:\n\t\treturn \"deno\"\n\tcase Edge:\n\t\treturn \"edge\"\n\tcase ES:\n\t\treturn \"es\"\n\tcase Firefox:\n\t\treturn \"firefox\"\n\tcase Hermes:\n\t\treturn \"hermes\"\n\tcase IE:\n\t\treturn \"ie\"\n\tcase IOS:\n\t\treturn \"ios\"\n\tcase Node:\n\t\treturn \"node\"\n\tcase Opera:\n\t\treturn \"opera\"\n\tcase Rhino:\n\t\treturn \"rhino\"\n\tcase Safari:\n\t\treturn \"safari\"\n\t}\n\treturn \"\"\n}\n\nfunc (e Engine) IsBrowser() bool {\n\tswitch e {\n\tcase Chrome, Edge, Firefox, IE, IOS, Opera, Safari:\n\t\treturn true\n\t}\n\treturn false\n}\n\ntype JSFeature uint64\n\nconst (\n\tArbitraryModuleNamespaceNames JSFeature = 1 << iota\n\tArraySpread\n\tArrow\n\tAsyncAwait\n\tAsyncGenerator\n\tBigint\n\tClass\n\tClassField\n\tClassPrivateAccessor\n\tClassPrivateBrandCheck\n\tClassPrivateField\n\tClassPrivateMethod\n\tClassPrivateStaticAccessor\n\tClassPrivateStaticField\n\tClassPrivateStaticMethod\n\tClassStaticBlocks\n\tClassStaticField\n\tConstAndLet\n\tDecorators\n\tDefaultArgument\n\tDestructuring\n\tDynamicImport\n\tExponentOperator\n\tExportStarAs\n\tForAwait\n\tForOf\n\tFromBase64\n\tFunctionNameConfigurable\n\tFunctionOrClassPropertyAccess\n\tGenerator\n\tHashbang\n\tImportAssertions\n\tImportAttributes\n\tImportDefer\n\tImportMeta\n\tImportSource\n\tInlineScript\n\tLogicalAssignment\n\tNestedRestBinding\n\tNewTarget\n\tNodeColonPrefixImport\n\tNodeColonPrefixRequire\n\tNullishCoalescing\n\tObjectAccessors\n\tObjectExtensions\n\tObjectRestSpread\n\tOptionalCatchBinding\n\tOptionalChain\n\tRegexpDotAllFlag\n\tRegexpLookbehindAssertions\n\tRegexpMatchIndices\n\tRegexpNamedCaptureGroups\n\tRegexpSetNotation\n\tRegexpStickyAndUnicodeFlags\n\tRegexpUnicodePropertyEscapes\n\tRestArgument\n\tTemplateLiteral\n\tTopLevelAwait\n\tTypeofExoticObjectIsObject\n\tUnicodeEscapes\n\tUsing\n)\n\nvar StringToJSFeature = map[string]JSFeature{\n\t\"arbitrary-module-namespace-names\":  ArbitraryModuleNamespaceNames,\n\t\"array-spread\":                      ArraySpread,\n\t\"arrow\":                             Arrow,\n\t\"async-await\":                       AsyncAwait,\n\t\"async-generator\":                   AsyncGenerator,\n\t\"bigint\":                            Bigint,\n\t\"class\":                             Class,\n\t\"class-field\":                       ClassField,\n\t\"class-private-accessor\":            ClassPrivateAccessor,\n\t\"class-private-brand-check\":         ClassPrivateBrandCheck,\n\t\"class-private-field\":               ClassPrivateField,\n\t\"class-private-method\":              ClassPrivateMethod,\n\t\"class-private-static-accessor\":     ClassPrivateStaticAccessor,\n\t\"class-private-static-field\":        ClassPrivateStaticField,\n\t\"class-private-static-method\":       ClassPrivateStaticMethod,\n\t\"class-static-blocks\":               ClassStaticBlocks,\n\t\"class-static-field\":                ClassStaticField,\n\t\"const-and-let\":                     ConstAndLet,\n\t\"decorators\":                        Decorators,\n\t\"default-argument\":                  DefaultArgument,\n\t\"destructuring\":                     Destructuring,\n\t\"dynamic-import\":                    DynamicImport,\n\t\"exponent-operator\":                 ExponentOperator,\n\t\"export-star-as\":                    ExportStarAs,\n\t\"for-await\":                         ForAwait,\n\t\"for-of\":                            ForOf,\n\t\"from-base64\":                       FromBase64,\n\t\"function-name-configurable\":        FunctionNameConfigurable,\n\t\"function-or-class-property-access\": FunctionOrClassPropertyAccess,\n\t\"generator\":                         Generator,\n\t\"hashbang\":                          Hashbang,\n\t\"import-assertions\":                 ImportAssertions,\n\t\"import-attributes\":                 ImportAttributes,\n\t\"import-defer\":                      ImportDefer,\n\t\"import-meta\":                       ImportMeta,\n\t\"import-source\":                     ImportSource,\n\t\"inline-script\":                     InlineScript,\n\t\"logical-assignment\":                LogicalAssignment,\n\t\"nested-rest-binding\":               NestedRestBinding,\n\t\"new-target\":                        NewTarget,\n\t\"node-colon-prefix-import\":          NodeColonPrefixImport,\n\t\"node-colon-prefix-require\":         NodeColonPrefixRequire,\n\t\"nullish-coalescing\":                NullishCoalescing,\n\t\"object-accessors\":                  ObjectAccessors,\n\t\"object-extensions\":                 ObjectExtensions,\n\t\"object-rest-spread\":                ObjectRestSpread,\n\t\"optional-catch-binding\":            OptionalCatchBinding,\n\t\"optional-chain\":                    OptionalChain,\n\t\"regexp-dot-all-flag\":               RegexpDotAllFlag,\n\t\"regexp-lookbehind-assertions\":      RegexpLookbehindAssertions,\n\t\"regexp-match-indices\":              RegexpMatchIndices,\n\t\"regexp-named-capture-groups\":       RegexpNamedCaptureGroups,\n\t\"regexp-set-notation\":               RegexpSetNotation,\n\t\"regexp-sticky-and-unicode-flags\":   RegexpStickyAndUnicodeFlags,\n\t\"regexp-unicode-property-escapes\":   RegexpUnicodePropertyEscapes,\n\t\"rest-argument\":                     RestArgument,\n\t\"template-literal\":                  TemplateLiteral,\n\t\"top-level-await\":                   TopLevelAwait,\n\t\"typeof-exotic-object-is-object\":    TypeofExoticObjectIsObject,\n\t\"unicode-escapes\":                   UnicodeEscapes,\n\t\"using\":                             Using,\n}\n\nfunc (features JSFeature) Has(feature JSFeature) bool {\n\treturn (features & feature) != 0\n}\n\nfunc (features JSFeature) ApplyOverrides(overrides JSFeature, mask JSFeature) JSFeature {\n\treturn (features & ^mask) | (overrides & mask)\n}\n\nvar jsTable = map[JSFeature]map[Engine][]versionRange{\n\tArbitraryModuleNamespaceNames: {\n\t\tChrome:  {{start: v{90, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{87, 0, 0}}},\n\t\tIOS:     {{start: v{14, 5, 0}}},\n\t\tNode:    {{start: v{16, 0, 0}}},\n\t\tSafari:  {{start: v{14, 1, 0}}},\n\t},\n\tArraySpread: {\n\t\t// Note: The latest version of \"IE\" failed 15 tests including: spread syntax for iterable objects: spreading non-iterables is a runtime error\n\t\t// Note: The latest version of \"Rhino\" failed 15 tests including: spread syntax for iterable objects: spreading non-iterables is a runtime error\n\t\tChrome:  {{start: v{46, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{13, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{36, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{5, 0, 0}}},\n\t\tOpera:   {{start: v{33, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tArrow: {\n\t\t// Note: The latest version of \"Hermes\" failed 3 tests including: arrow functions: lexical \"super\" binding in constructors\n\t\t// Note: The latest version of \"IE\" failed 13 tests including: arrow functions: \"this\" unchanged by call or apply\n\t\t// Note: The latest version of \"Rhino\" failed 3 tests including: arrow functions: lexical \"new.target\" binding\n\t\tChrome:  {{start: v{49, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{13, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{45, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{36, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tAsyncAwait: {\n\t\t// Note: The latest version of \"Hermes\" failed 4 tests including: async functions: async arrow functions\n\t\t// Note: The latest version of \"IE\" failed 16 tests including: async functions: async arrow functions\n\t\t// Note: The latest version of \"Rhino\" failed 16 tests including: async functions: async arrow functions\n\t\tChrome:  {{start: v{55, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{15, 0, 0}}},\n\t\tES:      {{start: v{2017, 0, 0}}},\n\t\tFirefox: {{start: v{52, 0, 0}}},\n\t\tIOS:     {{start: v{11, 0, 0}}},\n\t\tNode:    {{start: v{7, 6, 0}}},\n\t\tOpera:   {{start: v{42, 0, 0}}},\n\t\tSafari:  {{start: v{11, 0, 0}}},\n\t},\n\tAsyncGenerator: {\n\t\t// Note: The latest version of \"Hermes\" failed this test: Asynchronous Iterators: async generators\n\t\t// Note: The latest version of \"IE\" failed this test: Asynchronous Iterators: async generators\n\t\t// Note: The latest version of \"Rhino\" failed this test: Asynchronous Iterators: async generators\n\t\tChrome:  {{start: v{63, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2018, 0, 0}}},\n\t\tFirefox: {{start: v{57, 0, 0}}},\n\t\tIOS:     {{start: v{12, 0, 0}}},\n\t\tNode:    {{start: v{10, 0, 0}}},\n\t\tOpera:   {{start: v{50, 0, 0}}},\n\t\tSafari:  {{start: v{12, 0, 0}}},\n\t},\n\tBigint: {\n\t\t// Note: The latest version of \"IE\" failed this test: BigInt: basic functionality\n\t\tChrome:  {{start: v{67, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2020, 0, 0}}},\n\t\tFirefox: {{start: v{68, 0, 0}}},\n\t\tHermes:  {{start: v{0, 12, 0}}},\n\t\tIOS:     {{start: v{14, 0, 0}}},\n\t\tNode:    {{start: v{10, 4, 0}}},\n\t\tOpera:   {{start: v{54, 0, 0}}},\n\t\tRhino:   {{start: v{1, 7, 14}}},\n\t\tSafari:  {{start: v{14, 0, 0}}},\n\t},\n\tClass: {\n\t\t// Note: The latest version of \"Hermes\" failed 24 tests including: class: accessor properties\n\t\t// Note: The latest version of \"IE\" failed 24 tests including: class: accessor properties\n\t\t// Note: The latest version of \"Rhino\" failed 24 tests including: class: accessor properties\n\t\tChrome:  {{start: v{49, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{13, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{45, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{36, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tClassField: {\n\t\t// Note: The latest version of \"Hermes\" failed 2 tests including: instance class fields: computed instance class fields\n\t\t// Note: The latest version of \"IE\" failed 2 tests including: instance class fields: computed instance class fields\n\t\t// Note: The latest version of \"Rhino\" failed 2 tests including: instance class fields: computed instance class fields\n\t\tChrome:  {{start: v{73, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{69, 0, 0}}},\n\t\tIOS:     {{start: v{14, 0, 0}}},\n\t\tNode:    {{start: v{12, 0, 0}}},\n\t\tOpera:   {{start: v{60, 0, 0}}},\n\t\tSafari:  {{start: v{14, 0, 0}}},\n\t},\n\tClassPrivateAccessor: {\n\t\t// Note: The latest version of \"Hermes\" failed this test: private class methods: private accessor properties\n\t\t// Note: The latest version of \"IE\" failed this test: private class methods: private accessor properties\n\t\t// Note: The latest version of \"Rhino\" failed this test: private class methods: private accessor properties\n\t\tChrome:  {{start: v{84, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{84, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{90, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tNode:    {{start: v{14, 6, 0}}},\n\t\tOpera:   {{start: v{70, 0, 0}}},\n\t\tSafari:  {{start: v{15, 0, 0}}},\n\t},\n\tClassPrivateBrandCheck: {\n\t\t// Note: The latest version of \"Hermes\" failed this test: Ergonomic brand checks for private fields\n\t\t// Note: The latest version of \"IE\" failed this test: Ergonomic brand checks for private fields\n\t\t// Note: The latest version of \"Rhino\" failed this test: Ergonomic brand checks for private fields\n\t\tChrome:  {{start: v{91, 0, 0}}},\n\t\tDeno:    {{start: v{1, 9, 0}}},\n\t\tEdge:    {{start: v{91, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{90, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tNode:    {{start: v{16, 9, 0}}},\n\t\tOpera:   {{start: v{77, 0, 0}}},\n\t\tSafari:  {{start: v{15, 0, 0}}},\n\t},\n\tClassPrivateField: {\n\t\t// Note: The latest version of \"Hermes\" failed 4 tests including: instance class fields: optional deep private instance class fields access\n\t\t// Note: The latest version of \"IE\" failed 4 tests including: instance class fields: optional deep private instance class fields access\n\t\t// Note: The latest version of \"Rhino\" failed 4 tests including: instance class fields: optional deep private instance class fields access\n\t\tChrome:  {{start: v{84, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{84, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{90, 0, 0}}},\n\t\tIOS:     {{start: v{14, 5, 0}}},\n\t\tNode:    {{start: v{14, 6, 0}}},\n\t\tOpera:   {{start: v{70, 0, 0}}},\n\t\tSafari:  {{start: v{14, 1, 0}}},\n\t},\n\tClassPrivateMethod: {\n\t\t// Note: The latest version of \"Hermes\" failed this test: private class methods: private instance methods\n\t\t// Note: The latest version of \"IE\" failed this test: private class methods: private instance methods\n\t\t// Note: The latest version of \"Rhino\" failed this test: private class methods: private instance methods\n\t\tChrome:  {{start: v{84, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{84, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{90, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tNode:    {{start: v{14, 6, 0}}},\n\t\tOpera:   {{start: v{70, 0, 0}}},\n\t\tSafari:  {{start: v{15, 0, 0}}},\n\t},\n\tClassPrivateStaticAccessor: {\n\t\t// Note: The latest version of \"Hermes\" failed this test: private class methods: private static accessor properties\n\t\t// Note: The latest version of \"IE\" failed this test: private class methods: private static accessor properties\n\t\t// Note: The latest version of \"Rhino\" failed this test: private class methods: private static accessor properties\n\t\tChrome:  {{start: v{84, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{84, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{90, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tNode:    {{start: v{14, 6, 0}}},\n\t\tOpera:   {{start: v{70, 0, 0}}},\n\t\tSafari:  {{start: v{15, 0, 0}}},\n\t},\n\tClassPrivateStaticField: {\n\t\t// Note: The latest version of \"Hermes\" failed this test: static class fields: private static class fields\n\t\t// Note: The latest version of \"IE\" failed this test: static class fields: private static class fields\n\t\t// Note: The latest version of \"Rhino\" failed this test: static class fields: private static class fields\n\t\tChrome:  {{start: v{74, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{90, 0, 0}}},\n\t\tIOS:     {{start: v{14, 5, 0}}},\n\t\tNode:    {{start: v{12, 0, 0}}},\n\t\tOpera:   {{start: v{62, 0, 0}}},\n\t\tSafari:  {{start: v{14, 1, 0}}},\n\t},\n\tClassPrivateStaticMethod: {\n\t\t// Note: The latest version of \"Hermes\" failed this test: private class methods: private static methods\n\t\t// Note: The latest version of \"IE\" failed this test: private class methods: private static methods\n\t\t// Note: The latest version of \"Rhino\" failed this test: private class methods: private static methods\n\t\tChrome:  {{start: v{84, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{84, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{90, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tNode:    {{start: v{14, 6, 0}}},\n\t\tOpera:   {{start: v{70, 0, 0}}},\n\t\tSafari:  {{start: v{15, 0, 0}}},\n\t},\n\tClassStaticBlocks: {\n\t\tChrome:  {{start: v{91, 0, 0}}},\n\t\tDeno:    {{start: v{1, 14, 0}}},\n\t\tEdge:    {{start: v{94, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{93, 0, 0}}},\n\t\tIOS:     {{start: v{16, 4, 0}}},\n\t\tNode:    {{start: v{16, 11, 0}}},\n\t\tOpera:   {{start: v{80, 0, 0}}},\n\t\tSafari:  {{start: v{16, 4, 0}}},\n\t},\n\tClassStaticField: {\n\t\t// Note: The latest version of \"Hermes\" failed 2 tests including: static class fields: computed static class fields\n\t\t// Note: The latest version of \"IE\" failed 2 tests including: static class fields: computed static class fields\n\t\t// Note: The latest version of \"Rhino\" failed 2 tests including: static class fields: computed static class fields\n\t\tChrome:  {{start: v{73, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{75, 0, 0}}},\n\t\tIOS:     {{start: v{14, 5, 0}}},\n\t\tNode:    {{start: v{12, 0, 0}}},\n\t\tOpera:   {{start: v{60, 0, 0}}},\n\t\tSafari:  {{start: v{14, 1, 0}}},\n\t},\n\tConstAndLet: {\n\t\t// Note: The latest version of \"Hermes\" failed 20 tests including: const: for loop statement scope\n\t\t// Note: The latest version of \"IE\" failed 6 tests including: const: for-in loop iteration scope\n\t\t// Note: The latest version of \"Rhino\" failed 22 tests including: const: cannot be in statements\n\t\tChrome:  {{start: v{49, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{14, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{51, 0, 0}}},\n\t\tIOS:     {{start: v{11, 0, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{36, 0, 0}}},\n\t\tSafari:  {{start: v{11, 0, 0}}},\n\t},\n\tDecorators: {},\n\tDefaultArgument: {\n\t\t// Note: The latest version of \"Hermes\" failed 2 tests including: default function parameters: separate scope\n\t\t// Note: The latest version of \"IE\" failed 7 tests including: default function parameters: arguments object interaction\n\t\t// Note: The latest version of \"Rhino\" failed 2 tests including: default function parameters: separate scope\n\t\tChrome:  {{start: v{49, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{14, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{53, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{36, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tDestructuring: {\n\t\t// Note: The latest version of \"Hermes\" failed 3 tests including: destructuring, declarations: defaults, let temporal dead zone\n\t\t// Note: The latest version of \"IE\" failed 71 tests including: destructuring, assignment: chained iterable destructuring\n\t\t// Note: The latest version of \"Rhino\" failed 28 tests including: destructuring, assignment: computed properties\n\t\tChrome:  {{start: v{51, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{18, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{53, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{6, 5, 0}}},\n\t\tOpera:   {{start: v{38, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tDynamicImport: {\n\t\tChrome:  {{start: v{63, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{67, 0, 0}}},\n\t\tIOS:     {{start: v{11, 0, 0}}},\n\t\tNode:    {{start: v{12, 20, 0}, end: v{13, 0, 0}}, {start: v{13, 2, 0}}},\n\t\tOpera:   {{start: v{50, 0, 0}}},\n\t\tSafari:  {{start: v{11, 1, 0}}},\n\t},\n\tExponentOperator: {\n\t\t// Note: The latest version of \"IE\" failed 3 tests including: exponentiation (**) operator: assignment\n\t\tChrome:  {{start: v{52, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{14, 0, 0}}},\n\t\tES:      {{start: v{2016, 0, 0}}},\n\t\tFirefox: {{start: v{52, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIOS:     {{start: v{10, 3, 0}}},\n\t\tNode:    {{start: v{7, 0, 0}}},\n\t\tOpera:   {{start: v{39, 0, 0}}},\n\t\tRhino:   {{start: v{1, 7, 14}}},\n\t\tSafari:  {{start: v{10, 1, 0}}},\n\t},\n\tExportStarAs: {\n\t\tChrome:  {{start: v{72, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2020, 0, 0}}},\n\t\tFirefox: {{start: v{80, 0, 0}}},\n\t\tIOS:     {{start: v{14, 5, 0}}},\n\t\tNode:    {{start: v{13, 2, 0}}},\n\t\tOpera:   {{start: v{60, 0, 0}}},\n\t\tSafari:  {{start: v{14, 1, 0}}},\n\t},\n\tForAwait: {\n\t\t// Note: The latest version of \"Hermes\" failed this test: Asynchronous Iterators: for-await-of loops\n\t\t// Note: The latest version of \"IE\" failed this test: Asynchronous Iterators: for-await-of loops\n\t\t// Note: The latest version of \"Rhino\" failed this test: Asynchronous Iterators: for-await-of loops\n\t\tChrome:  {{start: v{63, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2018, 0, 0}}},\n\t\tFirefox: {{start: v{57, 0, 0}}},\n\t\tIOS:     {{start: v{12, 0, 0}}},\n\t\tNode:    {{start: v{10, 0, 0}}},\n\t\tOpera:   {{start: v{50, 0, 0}}},\n\t\tSafari:  {{start: v{12, 0, 0}}},\n\t},\n\tForOf: {\n\t\t// Note: The latest version of \"IE\" failed 9 tests including: for..of loops: iterator closing, break\n\t\t// Note: The latest version of \"Rhino\" failed 2 tests including: for..of loops: iterator closing, break\n\t\tChrome:  {{start: v{51, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{15, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{53, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{6, 5, 0}}},\n\t\tOpera:   {{start: v{38, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tFromBase64: {\n\t\tChrome:  {{start: v{140, 0, 0}}},\n\t\tDeno:    {{start: v{2, 5, 0}}},\n\t\tEdge:    {{start: v{140, 0, 0}}},\n\t\tFirefox: {{start: v{133, 0, 0}}},\n\t\tIOS:     {{start: v{18, 2, 0}}},\n\t\tNode:    {{start: v{25, 0, 0}}},\n\t\tOpera:   {{start: v{124, 0, 0}}},\n\t\tSafari:  {{start: v{18, 2, 0}}},\n\t},\n\tFunctionNameConfigurable: {\n\t\t// Note: The latest version of \"IE\" failed this test: function \"name\" property: isn't writable, is configurable\n\t\tChrome:  {{start: v{43, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{12, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{38, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{4, 0, 0}}},\n\t\tOpera:   {{start: v{30, 0, 0}}},\n\t\tRhino:   {{start: v{1, 7, 15}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tFunctionOrClassPropertyAccess: {\n\t\tChrome:  {{start: v{0, 0, 0}}},\n\t\tDeno:    {{start: v{0, 0, 0}}},\n\t\tEdge:    {{start: v{0, 0, 0}}},\n\t\tES:      {{start: v{0, 0, 0}}},\n\t\tFirefox: {{start: v{0, 0, 0}}},\n\t\tHermes:  {{start: v{0, 0, 0}}},\n\t\tIE:      {{start: v{0, 0, 0}}},\n\t\tIOS:     {{start: v{0, 0, 0}}},\n\t\tNode:    {{start: v{0, 0, 0}}},\n\t\tOpera:   {{start: v{0, 0, 0}}},\n\t\tRhino:   {{start: v{0, 0, 0}}},\n\t\tSafari:  {{start: v{16, 3, 0}}},\n\t},\n\tGenerator: {\n\t\t// Note: The latest version of \"Hermes\" failed 3 tests including: generators: computed shorthand generators, classes\n\t\t// Note: The latest version of \"IE\" failed 27 tests including: generators: %GeneratorPrototype%\n\t\t// Note: The latest version of \"Rhino\" failed 8 tests including: generators: %GeneratorPrototype%\n\t\tChrome:  {{start: v{50, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{13, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{53, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{37, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tHashbang: {\n\t\t// Note: The latest version of \"IE\" failed this test: Hashbang Grammar\n\t\tChrome:  {{start: v{74, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2023, 0, 0}}},\n\t\tFirefox: {{start: v{67, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIOS:     {{start: v{13, 4, 0}}},\n\t\tNode:    {{start: v{12, 0, 0}}},\n\t\tOpera:   {{start: v{62, 0, 0}}},\n\t\tRhino:   {{start: v{1, 7, 15}}},\n\t\tSafari:  {{start: v{13, 1, 0}}},\n\t},\n\tImportAssertions: {\n\t\tChrome: {{start: v{91, 0, 0}}},\n\t\tDeno:   {{start: v{1, 17, 0}}},\n\t\tEdge:   {{start: v{91, 0, 0}}},\n\t\tNode:   {{start: v{16, 14, 0}, end: v{22, 0, 0}}},\n\t},\n\tImportAttributes: {\n\t\tChrome:  {{start: v{123, 0, 0}}},\n\t\tDeno:    {{start: v{1, 37, 0}}},\n\t\tEdge:    {{start: v{123, 0, 0}}},\n\t\tFirefox: {{start: v{138, 0, 0}}},\n\t\tIOS:     {{start: v{17, 2, 0}}},\n\t\tNode:    {{start: v{18, 20, 0}, end: v{19, 0, 0}}, {start: v{20, 10, 0}}},\n\t\tOpera:   {{start: v{109, 0, 0}}},\n\t\tSafari:  {{start: v{17, 2, 0}}},\n\t},\n\tImportDefer: {},\n\tImportMeta: {\n\t\tChrome:  {{start: v{64, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2020, 0, 0}}},\n\t\tFirefox: {{start: v{62, 0, 0}}},\n\t\tIOS:     {{start: v{12, 0, 0}}},\n\t\tNode:    {{start: v{10, 4, 0}}},\n\t\tOpera:   {{start: v{51, 0, 0}}},\n\t\tSafari:  {{start: v{11, 1, 0}}},\n\t},\n\tImportSource: {},\n\tInlineScript: {},\n\tLogicalAssignment: {\n\t\t// Note: The latest version of \"IE\" failed 9 tests including: Logical Assignment: &&= basic support\n\t\t// Note: The latest version of \"Rhino\" failed 3 tests including: Logical Assignment: &&= setter not unecessarily invoked\n\t\tChrome:  {{start: v{85, 0, 0}}},\n\t\tDeno:    {{start: v{1, 2, 0}}},\n\t\tEdge:    {{start: v{85, 0, 0}}},\n\t\tES:      {{start: v{2021, 0, 0}}},\n\t\tFirefox: {{start: v{79, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIOS:     {{start: v{14, 0, 0}}},\n\t\tNode:    {{start: v{15, 0, 0}}},\n\t\tOpera:   {{start: v{71, 0, 0}}},\n\t\tSafari:  {{start: v{14, 0, 0}}},\n\t},\n\tNestedRestBinding: {\n\t\t// Note: The latest version of \"IE\" failed 2 tests including: nested rest destructuring, declarations\n\t\t// Note: The latest version of \"Rhino\" failed 2 tests including: nested rest destructuring, declarations\n\t\tChrome:  {{start: v{49, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{14, 0, 0}}},\n\t\tES:      {{start: v{2016, 0, 0}}},\n\t\tFirefox: {{start: v{47, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIOS:     {{start: v{10, 3, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{36, 0, 0}}},\n\t\tSafari:  {{start: v{10, 1, 0}}},\n\t},\n\tNewTarget: {\n\t\t// Note: The latest version of \"IE\" failed 2 tests including: new.target: assignment is an early error\n\t\t// Note: The latest version of \"Rhino\" failed 2 tests including: new.target: assignment is an early error\n\t\tChrome:  {{start: v{46, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{14, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{41, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{5, 0, 0}}},\n\t\tOpera:   {{start: v{33, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tNodeColonPrefixImport: {\n\t\tES:   {{start: v{0, 0, 0}}},\n\t\tNode: {{start: v{12, 20, 0}, end: v{13, 0, 0}}, {start: v{14, 13, 1}}},\n\t},\n\tNodeColonPrefixRequire: {\n\t\tES:   {{start: v{0, 0, 0}}},\n\t\tNode: {{start: v{14, 18, 0}, end: v{15, 0, 0}}, {start: v{16, 0, 0}}},\n\t},\n\tNullishCoalescing: {\n\t\t// Note: The latest version of \"IE\" failed this test: nullish coalescing operator (??)\n\t\tChrome:  {{start: v{80, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{80, 0, 0}}},\n\t\tES:      {{start: v{2020, 0, 0}}},\n\t\tFirefox: {{start: v{72, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIOS:     {{start: v{13, 4, 0}}},\n\t\tNode:    {{start: v{14, 0, 0}}},\n\t\tOpera:   {{start: v{67, 0, 0}}},\n\t\tRhino:   {{start: v{1, 8, 0}}},\n\t\tSafari:  {{start: v{13, 1, 0}}},\n\t},\n\tObjectAccessors: {\n\t\tChrome:  {{start: v{5, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{12, 0, 0}}},\n\t\tES:      {{start: v{5, 0, 0}}},\n\t\tFirefox: {{start: v{2, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIE:      {{start: v{9, 0, 0}}},\n\t\tIOS:     {{start: v{6, 0, 0}}},\n\t\tNode:    {{start: v{0, 4, 0}}},\n\t\tOpera:   {{start: v{10, 10, 0}}},\n\t\tRhino:   {{start: v{1, 7, 13}}},\n\t\tSafari:  {{start: v{3, 1, 0}}},\n\t},\n\tObjectExtensions: {\n\t\t// Note: The latest version of \"IE\" failed 6 tests including: object literal extensions: computed accessors\n\t\tChrome:  {{start: v{44, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{12, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{34, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{4, 0, 0}}},\n\t\tOpera:   {{start: v{31, 0, 0}}},\n\t\tRhino:   {{start: v{1, 8, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tObjectRestSpread: {\n\t\t// Note: The latest version of \"IE\" failed 2 tests including: object rest/spread properties: object rest properties\n\t\t// Note: The latest version of \"Rhino\" failed 2 tests including: object rest/spread properties: object rest properties\n\t\tChrome:  {{start: v{60, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2018, 0, 0}}},\n\t\tFirefox: {{start: v{55, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIOS:     {{start: v{11, 3, 0}}},\n\t\tNode:    {{start: v{8, 3, 0}}},\n\t\tOpera:   {{start: v{47, 0, 0}}},\n\t\tSafari:  {{start: v{11, 1, 0}}},\n\t},\n\tOptionalCatchBinding: {\n\t\t// Note: The latest version of \"IE\" failed 3 tests including: optional catch binding: await\n\t\t// Note: The latest version of \"Rhino\" failed this test: optional catch binding: await\n\t\tChrome:  {{start: v{66, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2019, 0, 0}}},\n\t\tFirefox: {{start: v{58, 0, 0}}},\n\t\tHermes:  {{start: v{0, 12, 0}}},\n\t\tIOS:     {{start: v{11, 3, 0}}},\n\t\tNode:    {{start: v{10, 0, 0}}},\n\t\tOpera:   {{start: v{53, 0, 0}}},\n\t\tSafari:  {{start: v{11, 1, 0}}},\n\t},\n\tOptionalChain: {\n\t\t// Note: The latest version of \"IE\" failed 5 tests including: optional chaining operator (?.): optional bracket access\n\t\t// Note: The latest version of \"Rhino\" failed this test: optional chaining operator (?.): spread parameters after optional chaining\n\t\tChrome:  {{start: v{91, 0, 0}}},\n\t\tDeno:    {{start: v{1, 9, 0}}},\n\t\tEdge:    {{start: v{91, 0, 0}}},\n\t\tES:      {{start: v{2020, 0, 0}}},\n\t\tFirefox: {{start: v{74, 0, 0}}},\n\t\tHermes:  {{start: v{0, 12, 0}}},\n\t\tIOS:     {{start: v{13, 4, 0}}},\n\t\tNode:    {{start: v{16, 9, 0}}},\n\t\tOpera:   {{start: v{77, 0, 0}}},\n\t\tSafari:  {{start: v{13, 1, 0}}},\n\t},\n\tRegexpDotAllFlag: {\n\t\t// Note: The latest version of \"IE\" failed this test: s (dotAll) flag for regular expressions\n\t\tChrome:  {{start: v{62, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2018, 0, 0}}},\n\t\tFirefox: {{start: v{78, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIOS:     {{start: v{11, 3, 0}}},\n\t\tNode:    {{start: v{8, 10, 0}}},\n\t\tOpera:   {{start: v{49, 0, 0}}},\n\t\tRhino:   {{start: v{1, 7, 15}}},\n\t\tSafari:  {{start: v{11, 1, 0}}},\n\t},\n\tRegexpLookbehindAssertions: {\n\t\t// Note: The latest version of \"IE\" failed this test: RegExp Lookbehind Assertions\n\t\t// Note: The latest version of \"Rhino\" failed this test: RegExp Lookbehind Assertions\n\t\tChrome:  {{start: v{62, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2018, 0, 0}}},\n\t\tFirefox: {{start: v{78, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIOS:     {{start: v{16, 4, 0}}},\n\t\tNode:    {{start: v{8, 10, 0}}},\n\t\tOpera:   {{start: v{49, 0, 0}}},\n\t\tSafari:  {{start: v{16, 4, 0}}},\n\t},\n\tRegexpMatchIndices: {\n\t\tChrome:  {{start: v{90, 0, 0}}},\n\t\tDeno:    {{start: v{1, 8, 0}}},\n\t\tEdge:    {{start: v{90, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{88, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tNode:    {{start: v{16, 0, 0}}},\n\t\tOpera:   {{start: v{76, 0, 0}}},\n\t\tSafari:  {{start: v{15, 0, 0}}},\n\t},\n\tRegexpNamedCaptureGroups: {\n\t\t// Note: The latest version of \"Hermes\" failed this test: RegExp named capture groups\n\t\t// Note: The latest version of \"IE\" failed this test: RegExp named capture groups\n\t\t// Note: The latest version of \"Rhino\" failed this test: RegExp named capture groups\n\t\tChrome:  {{start: v{64, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2018, 0, 0}}},\n\t\tFirefox: {{start: v{78, 0, 0}}},\n\t\tIOS:     {{start: v{11, 3, 0}}},\n\t\tNode:    {{start: v{10, 0, 0}}},\n\t\tOpera:   {{start: v{51, 0, 0}}},\n\t\tSafari:  {{start: v{11, 1, 0}}},\n\t},\n\tRegexpSetNotation: {\n\t\tES: {{start: v{2024, 0, 0}}},\n\t},\n\tRegexpStickyAndUnicodeFlags: {\n\t\t// Note: The latest version of \"IE\" failed 6 tests including: RegExp \"y\" and \"u\" flags: \"u\" flag\n\t\t// Note: The latest version of \"Rhino\" failed 4 tests including: RegExp \"y\" and \"u\" flags: \"u\" flag\n\t\tChrome:  {{start: v{50, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{13, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{46, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIOS:     {{start: v{12, 0, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{37, 0, 0}}},\n\t\tSafari:  {{start: v{12, 0, 0}}},\n\t},\n\tRegexpUnicodePropertyEscapes: {\n\t\t// Note: The latest version of \"Chrome\" failed 2 tests including: RegExp Unicode Property Escapes: Unicode 16.0\n\t\t// Note: The latest version of \"Edge\" failed 2 tests including: RegExp Unicode Property Escapes: Unicode 16.0\n\t\t// Note: The latest version of \"Firefox\" failed this test: RegExp Unicode Property Escapes: Unicode 17.0\n\t\t// Note: The latest version of \"Hermes\" failed 8 tests including: RegExp Unicode Property Escapes: Unicode 11\n\t\t// Note: The latest version of \"IE\" failed 8 tests including: RegExp Unicode Property Escapes: Unicode 11\n\t\t// Note: The latest version of \"IOS\" failed this test: RegExp Unicode Property Escapes: Unicode 17.0\n\t\t// Note: The latest version of \"Node\" failed 2 tests including: RegExp Unicode Property Escapes: Unicode 16.0\n\t\t// Note: The latest version of \"Rhino\" failed 9 tests including: RegExp Unicode Property Escapes: Unicode 11\n\t\t// Note: The latest version of \"Safari\" failed this test: RegExp Unicode Property Escapes: Unicode 17.0\n\t\tES: {{start: v{2018, 0, 0}}},\n\t},\n\tRestArgument: {\n\t\t// Note: The latest version of \"Hermes\" failed this test: rest parameters: function 'length' property\n\t\t// Note: The latest version of \"IE\" failed 5 tests including: rest parameters: arguments object interaction\n\t\t// Note: The latest version of \"Rhino\" failed 2 tests including: rest parameters: arguments object interaction\n\t\tChrome:  {{start: v{47, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{12, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{43, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{34, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tTemplateLiteral: {\n\t\t// Note: The latest version of \"Hermes\" failed this test: template literals: TemplateStrings call site caching\n\t\t// Note: The latest version of \"IE\" failed 7 tests including: template literals: TemplateStrings call site caching\n\t\t// Note: The latest version of \"Rhino\" failed this test: template literals: toString conversion\n\t\tChrome:  {{start: v{62, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{53, 0, 0}}},\n\t\tIOS:     {{start: v{13, 0, 0}}},\n\t\tNode:    {{start: v{8, 10, 0}}},\n\t\tOpera:   {{start: v{49, 0, 0}}},\n\t\tSafari:  {{start: v{13, 0, 0}}},\n\t},\n\tTopLevelAwait: {\n\t\tChrome:  {{start: v{89, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{89, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{89, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tNode:    {{start: v{14, 8, 0}}},\n\t\tOpera:   {{start: v{75, 0, 0}}},\n\t\tSafari:  {{start: v{15, 0, 0}}},\n\t},\n\tTypeofExoticObjectIsObject: {\n\t\tChrome:  {{start: v{0, 0, 0}}},\n\t\tDeno:    {{start: v{0, 0, 0}}},\n\t\tEdge:    {{start: v{0, 0, 0}}},\n\t\tES:      {{start: v{2020, 0, 0}}},\n\t\tFirefox: {{start: v{0, 0, 0}}},\n\t\tHermes:  {{start: v{0, 0, 0}}},\n\t\tIOS:     {{start: v{0, 0, 0}}},\n\t\tNode:    {{start: v{0, 0, 0}}},\n\t\tOpera:   {{start: v{0, 0, 0}}},\n\t\tRhino:   {{start: v{0, 0, 0}}},\n\t\tSafari:  {{start: v{0, 0, 0}}},\n\t},\n\tUnicodeEscapes: {\n\t\t// Note: The latest version of \"IE\" failed 2 tests including: Unicode code point escapes: in identifiers\n\t\tChrome:  {{start: v{44, 0, 0}}},\n\t\tDeno:    {{start: v{1, 0, 0}}},\n\t\tEdge:    {{start: v{12, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{53, 0, 0}}},\n\t\tHermes:  {{start: v{0, 7, 0}}},\n\t\tIOS:     {{start: v{9, 0, 0}}},\n\t\tNode:    {{start: v{4, 0, 0}}},\n\t\tOpera:   {{start: v{31, 0, 0}}},\n\t\tRhino:   {{start: v{1, 7, 15}}},\n\t\tSafari:  {{start: v{9, 0, 0}}},\n\t},\n\tUsing: {\n\t\t// Note: The latest version of \"IE\" failed 7 tests including: Explicit Resource Management: AsyncDisposableStack\n\t\t// Note: The latest version of \"IOS\" failed 7 tests including: Explicit Resource Management: AsyncDisposableStack\n\t\t// Note: The latest version of \"Safari\" failed 7 tests including: Explicit Resource Management: AsyncDisposableStack\n\t\tChrome:  {{start: v{143, 0, 0}}},\n\t\tEdge:    {{start: v{143, 0, 0}}},\n\t\tFirefox: {{start: v{147, 0, 0}}},\n\t\tNode:    {{start: v{25, 0, 0}}},\n\t},\n}\n\n// Return all features that are not available in at least one environment\nfunc UnsupportedJSFeatures(constraints map[Engine]Semver) (unsupported JSFeature) {\n\tfor feature, engines := range jsTable {\n\t\tif feature == InlineScript {\n\t\t\tcontinue // This is purely user-specified\n\t\t}\n\t\tfor engine, version := range constraints {\n\t\t\tif versionRanges, ok := engines[engine]; !ok || !isVersionSupported(versionRanges, version) {\n\t\t\t\tunsupported |= feature\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n"
  },
  {
    "path": "internal/config/config.go",
    "content": "package config\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\ntype JSXOptions struct {\n\tFactory          DefineExpr\n\tFragment         DefineExpr\n\tParse            bool\n\tPreserve         bool\n\tAutomaticRuntime bool\n\tImportSource     string\n\tDevelopment      bool\n\tSideEffects      bool\n}\n\ntype TSJSX uint8\n\nconst (\n\tTSJSXNone TSJSX = iota\n\tTSJSXPreserve\n\tTSJSXReactNative\n\tTSJSXReact\n\tTSJSXReactJSX\n\tTSJSXReactJSXDev\n)\n\ntype TSOptions struct {\n\tConfig              TSConfig\n\tParse               bool\n\tNoAmbiguousLessThan bool\n}\n\ntype TSConfigJSX struct {\n\t// If not empty, these should override the default values\n\tJSXFactory         []string // Default if empty: \"React.createElement\"\n\tJSXFragmentFactory []string // Default if empty: \"React.Fragment\"\n\tJSXImportSource    *string  // Default if empty: \"react\"\n\tJSX                TSJSX\n}\n\n// This is used for \"extends\" in \"tsconfig.json\"\nfunc (derived *TSConfigJSX) ApplyExtendedConfig(base TSConfigJSX) {\n\tif base.JSXFactory != nil {\n\t\tderived.JSXFactory = base.JSXFactory\n\t}\n\tif base.JSXFragmentFactory != nil {\n\t\tderived.JSXFragmentFactory = base.JSXFragmentFactory\n\t}\n\tif base.JSXImportSource != nil {\n\t\tderived.JSXImportSource = base.JSXImportSource\n\t}\n\tif base.JSX != TSJSXNone {\n\t\tderived.JSX = base.JSX\n\t}\n}\n\nfunc (tsConfig *TSConfigJSX) ApplyTo(jsxOptions *JSXOptions) {\n\tswitch tsConfig.JSX {\n\tcase TSJSXPreserve, TSJSXReactNative:\n\t\t// Deliberately don't set \"Preserve = true\" here. Some tools from Vercel\n\t\t// apparently automatically set \"jsx\": \"preserve\" in \"tsconfig.json\" and\n\t\t// people are then confused when esbuild preserves their JSX. Ignoring this\n\t\t// value means you now have to explicitly pass \"--jsx=preserve\" to esbuild\n\t\t// to get this behavior.\n\n\tcase TSJSXReact:\n\t\tjsxOptions.AutomaticRuntime = false\n\t\tjsxOptions.Development = false\n\n\tcase TSJSXReactJSX:\n\t\tjsxOptions.AutomaticRuntime = true\n\t\t// Deliberately don't set \"Development = false\" here. People want to be\n\t\t// able to have \"react-jsx\" in their \"tsconfig.json\" file and then swap\n\t\t// that to \"react-jsxdev\" by passing \"--jsx-dev\" to esbuild.\n\n\tcase TSJSXReactJSXDev:\n\t\tjsxOptions.AutomaticRuntime = true\n\t\tjsxOptions.Development = true\n\t}\n\n\tif len(tsConfig.JSXFactory) > 0 {\n\t\tjsxOptions.Factory = DefineExpr{Parts: tsConfig.JSXFactory}\n\t}\n\n\tif len(tsConfig.JSXFragmentFactory) > 0 {\n\t\tjsxOptions.Fragment = DefineExpr{Parts: tsConfig.JSXFragmentFactory}\n\t}\n\n\tif tsConfig.JSXImportSource != nil {\n\t\tjsxOptions.ImportSource = *tsConfig.JSXImportSource\n\t}\n}\n\n// Note: This can currently only contain primitive values. It's compared\n// for equality using a structural equality comparison by the JS parser.\ntype TSConfig struct {\n\tExperimentalDecorators  MaybeBool\n\tImportsNotUsedAsValues  TSImportsNotUsedAsValues\n\tPreserveValueImports    MaybeBool\n\tTarget                  TSTarget\n\tUseDefineForClassFields MaybeBool\n\tVerbatimModuleSyntax    MaybeBool\n}\n\n// This is used for \"extends\" in \"tsconfig.json\"\nfunc (derived *TSConfig) ApplyExtendedConfig(base TSConfig) {\n\tif base.ExperimentalDecorators != Unspecified {\n\t\tderived.ExperimentalDecorators = base.ExperimentalDecorators\n\t}\n\tif base.ImportsNotUsedAsValues != TSImportsNotUsedAsValues_None {\n\t\tderived.ImportsNotUsedAsValues = base.ImportsNotUsedAsValues\n\t}\n\tif base.PreserveValueImports != Unspecified {\n\t\tderived.PreserveValueImports = base.PreserveValueImports\n\t}\n\tif base.Target != TSTargetUnspecified {\n\t\tderived.Target = base.Target\n\t}\n\tif base.UseDefineForClassFields != Unspecified {\n\t\tderived.UseDefineForClassFields = base.UseDefineForClassFields\n\t}\n\tif base.VerbatimModuleSyntax != Unspecified {\n\t\tderived.VerbatimModuleSyntax = base.VerbatimModuleSyntax\n\t}\n}\n\nfunc (cfg *TSConfig) UnusedImportFlags() (flags TSUnusedImportFlags) {\n\tif cfg.VerbatimModuleSyntax == True {\n\t\treturn TSUnusedImport_KeepStmt | TSUnusedImport_KeepValues\n\t}\n\tif cfg.PreserveValueImports == True {\n\t\tflags |= TSUnusedImport_KeepValues\n\t}\n\tif cfg.ImportsNotUsedAsValues == TSImportsNotUsedAsValues_Preserve || cfg.ImportsNotUsedAsValues == TSImportsNotUsedAsValues_Error {\n\t\tflags |= TSUnusedImport_KeepStmt\n\t}\n\treturn\n}\n\ntype Platform uint8\n\nconst (\n\tPlatformBrowser Platform = iota\n\tPlatformNode\n\tPlatformNeutral\n)\n\ntype SourceMap uint8\n\nconst (\n\tSourceMapNone SourceMap = iota\n\tSourceMapInline\n\tSourceMapLinkedWithComment\n\tSourceMapExternalWithoutComment\n\tSourceMapInlineAndExternal\n)\n\ntype LegalComments uint8\n\nconst (\n\tLegalCommentsInline LegalComments = iota\n\tLegalCommentsNone\n\tLegalCommentsEndOfFile\n\tLegalCommentsLinkedWithComment\n\tLegalCommentsExternalWithoutComment\n)\n\nfunc (lc LegalComments) HasExternalFile() bool {\n\treturn lc == LegalCommentsLinkedWithComment || lc == LegalCommentsExternalWithoutComment\n}\n\ntype Loader uint8\n\nconst (\n\tLoaderNone Loader = iota\n\tLoaderBase64\n\tLoaderBinary\n\tLoaderCopy\n\tLoaderCSS\n\tLoaderDataURL\n\tLoaderDefault\n\tLoaderEmpty\n\tLoaderFile\n\tLoaderGlobalCSS\n\tLoaderJS\n\tLoaderJSON\n\tLoaderWithTypeJSON // Has a \"with { type: 'json' }\" attribute\n\tLoaderJSX\n\tLoaderLocalCSS\n\tLoaderText\n\tLoaderTS\n\tLoaderTSNoAmbiguousLessThan // Used with \".mts\" and \".cts\"\n\tLoaderTSX\n)\n\nvar LoaderToString = []string{\n\t\"none\",\n\t\"base64\",\n\t\"binary\",\n\t\"copy\",\n\t\"css\",\n\t\"dataurl\",\n\t\"default\",\n\t\"empty\",\n\t\"file\",\n\t\"global-css\",\n\t\"js\",\n\t\"json\",\n\t\"json\",\n\t\"jsx\",\n\t\"local-css\",\n\t\"text\",\n\t\"ts\",\n\t\"ts\",\n\t\"tsx\",\n}\n\nfunc (loader Loader) IsTypeScript() bool {\n\tswitch loader {\n\tcase LoaderTS, LoaderTSNoAmbiguousLessThan, LoaderTSX:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (loader Loader) IsCSS() bool {\n\tswitch loader {\n\tcase\n\t\tLoaderCSS, LoaderGlobalCSS, LoaderLocalCSS:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (loader Loader) CanHaveSourceMap() bool {\n\tswitch loader {\n\tcase\n\t\tLoaderJS, LoaderJSX,\n\t\tLoaderTS, LoaderTSNoAmbiguousLessThan, LoaderTSX,\n\t\tLoaderCSS, LoaderGlobalCSS, LoaderLocalCSS,\n\t\tLoaderJSON, LoaderWithTypeJSON, LoaderText:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc LoaderFromFileExtension(extensionToLoader map[string]Loader, base string) Loader {\n\t// Pick the loader with the longest matching extension. So if there's an\n\t// extension for \".css\" and for \".module.css\", we want to match the one for\n\t// \".module.css\" before the one for \".css\".\n\tif i := strings.IndexByte(base, '.'); i != -1 {\n\t\tfor {\n\t\t\tif loader, ok := extensionToLoader[base[i:]]; ok {\n\t\t\t\treturn loader\n\t\t\t}\n\t\t\tbase = base[i+1:]\n\t\t\ti = strings.IndexByte(base, '.')\n\t\t\tif i == -1 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// If there's no extension, explicitly check for an extensionless loader\n\t\tif loader, ok := extensionToLoader[\"\"]; ok {\n\t\t\treturn loader\n\t\t}\n\t}\n\treturn LoaderNone\n}\n\ntype Format uint8\n\nconst (\n\t// This is used when not bundling. It means to preserve whatever form the\n\t// import or export was originally in. ES6 syntax stays ES6 syntax and\n\t// CommonJS syntax stays CommonJS syntax.\n\tFormatPreserve Format = iota\n\n\t// IIFE stands for immediately-invoked function expression. That looks like\n\t// this:\n\t//\n\t//   (() => {\n\t//     ... bundled code ...\n\t//   })();\n\t//\n\t// If the optional GlobalName is configured, then we'll write out this:\n\t//\n\t//   let globalName = (() => {\n\t//     ... bundled code ...\n\t//     return exports;\n\t//   })();\n\t//\n\tFormatIIFE\n\n\t// The CommonJS format looks like this:\n\t//\n\t//   ... bundled code ...\n\t//   module.exports = exports;\n\t//\n\tFormatCommonJS\n\n\t// The ES module format looks like this:\n\t//\n\t//   ... bundled code ...\n\t//   export {...};\n\t//\n\tFormatESModule\n)\n\nfunc (f Format) KeepESMImportExportSyntax() bool {\n\treturn f == FormatPreserve || f == FormatESModule\n}\n\nfunc (f Format) String() string {\n\tswitch f {\n\tcase FormatIIFE:\n\t\treturn \"iife\"\n\tcase FormatCommonJS:\n\t\treturn \"cjs\"\n\tcase FormatESModule:\n\t\treturn \"esm\"\n\t}\n\treturn \"\"\n}\n\ntype StdinInfo struct {\n\tContents      string\n\tSourceFile    string\n\tAbsResolveDir string\n\tLoader        Loader\n}\n\ntype WildcardPattern struct {\n\tPrefix string\n\tSuffix string\n}\n\ntype ExternalMatchers struct {\n\tExact    map[string]bool\n\tPatterns []WildcardPattern\n}\n\nfunc (matchers ExternalMatchers) HasMatchers() bool {\n\treturn len(matchers.Exact) > 0 || len(matchers.Patterns) > 0\n}\n\ntype ExternalSettings struct {\n\tPreResolve  ExternalMatchers\n\tPostResolve ExternalMatchers\n}\n\ntype APICall uint8\n\nconst (\n\tBuildCall APICall = iota\n\tTransformCall\n)\n\ntype Mode uint8\n\nconst (\n\tModePassThrough Mode = iota\n\tModeConvertFormat\n\tModeBundle\n)\n\ntype MaybeBool uint8\n\nconst (\n\tUnspecified MaybeBool = iota\n\tTrue\n\tFalse\n)\n\ntype CancelFlag struct {\n\tuint32\n}\n\nfunc (flag *CancelFlag) Cancel() {\n\tatomic.StoreUint32(&flag.uint32, 1)\n}\n\n// This checks for nil in one place so we don't have to do that everywhere\nfunc (flag *CancelFlag) DidCancel() bool {\n\treturn flag != nil && atomic.LoadUint32(&flag.uint32) != 0\n}\n\ntype Options struct {\n\tModuleTypeData js_ast.ModuleTypeData\n\tDefines        *ProcessedDefines\n\tTSAlwaysStrict *TSAlwaysStrict\n\tMangleProps    *regexp.Regexp\n\tReserveProps   *regexp.Regexp\n\tCancelFlag     *CancelFlag\n\n\t// When mangling property names, call this function with a callback and do\n\t// the property name mangling inside the callback. The callback takes an\n\t// argument which is the mangle cache map to mutate. These callbacks are\n\t// serialized so mutating the map does not require extra synchronization.\n\t//\n\t// This is a callback for determinism reasons. We may be building multiple\n\t// entry points in parallel that are supposed to share a single cache. We\n\t// don't want the order that each entry point mangles properties in to cause\n\t// the output to change, so we serialize the property mangling over all entry\n\t// points in entry point order. However, we still want to link everything in\n\t// parallel so only property mangling is serialized, which is implemented by\n\t// this function blocking until the previous entry point's property mangling\n\t// has finished.\n\tExclusiveMangleCacheUpdate func(cb func(\n\t\tmangleCache map[string]interface{},\n\t\tcssUsedLocalNames map[string]bool,\n\t))\n\n\t// This is the original information that was used to generate the\n\t// unsupported feature sets above. It's used for error messages.\n\tOriginalTargetEnv string\n\n\tDropLabels       []string\n\tExtensionOrder   []string\n\tMainFields       []string\n\tConditions       []string\n\tAbsNodePaths     []string // The \"NODE_PATH\" variable from Node.js\n\tExternalSettings ExternalSettings\n\tExternalPackages bool\n\tPackageAliases   map[string]string\n\n\tAbsOutputFile      string\n\tAbsOutputDir       string\n\tAbsOutputBase      string\n\tOutputExtensionJS  string\n\tOutputExtensionCSS string\n\tGlobalName         []string\n\tTSConfigPath       string\n\tTSConfigRaw        string\n\tExtensionToLoader  map[string]Loader\n\n\tPublicPath      string\n\tInjectPaths     []string\n\tInjectedDefines []InjectedDefine\n\tInjectedFiles   []InjectedFile\n\n\tJSBanner  string\n\tJSFooter  string\n\tCSSBanner string\n\tCSSFooter string\n\n\tEntryPathTemplate []PathTemplate\n\tChunkPathTemplate []PathTemplate\n\tAssetPathTemplate []PathTemplate\n\n\tPlugins    []Plugin\n\tSourceRoot string\n\tStdin      *StdinInfo\n\tJSX        JSXOptions\n\tLineLimit  int\n\n\tCSSPrefixData          map[css_ast.D]compat.CSSPrefix\n\tUnsupportedJSFeatures  compat.JSFeature\n\tUnsupportedCSSFeatures compat.CSSFeature\n\n\tUnsupportedJSFeatureOverrides      compat.JSFeature\n\tUnsupportedJSFeatureOverridesMask  compat.JSFeature\n\tUnsupportedCSSFeatureOverrides     compat.CSSFeature\n\tUnsupportedCSSFeatureOverridesMask compat.CSSFeature\n\n\tTS                TSOptions\n\tMode              Mode\n\tPreserveSymlinks  bool\n\tMinifyWhitespace  bool\n\tMinifyIdentifiers bool\n\tMinifySyntax      bool\n\tProfilerNames     bool\n\tCodeSplitting     bool\n\tWatchMode         bool\n\tAllowOverwrite    bool\n\tLegalComments     LegalComments\n\n\tLogPathStyle       logger.PathStyle\n\tCodePathStyle      logger.PathStyle\n\tMetafilePathStyle  logger.PathStyle\n\tSourcemapPathStyle logger.PathStyle\n\n\t// If true, make sure to generate a single file that can be written to stdout\n\tWriteToStdout bool\n\n\t// Large bundles minify the metafile JSON to reduce its size\n\tMetafileFormat MetafileFormat\n\n\tOmitRuntimeForTests    bool\n\tOmitJSXRuntimeForTests bool\n\tASCIIOnly              bool\n\tKeepNames              bool\n\tIgnoreDCEAnnotations   bool\n\tTreeShaking            bool\n\tDropDebugger           bool\n\tMangleQuoted           bool\n\tPlatform               Platform\n\tOutputFormat           Format\n\tNeedsMetafile          bool\n\tSourceMap              SourceMap\n\tExcludeSourcesContent  bool\n}\n\ntype TSImportsNotUsedAsValues uint8\n\nconst (\n\tTSImportsNotUsedAsValues_None TSImportsNotUsedAsValues = iota\n\tTSImportsNotUsedAsValues_Remove\n\tTSImportsNotUsedAsValues_Preserve\n\tTSImportsNotUsedAsValues_Error\n)\n\n// These flags represent the following separate \"tsconfig.json\" settings:\n//\n// - importsNotUsedAsValues\n// - preserveValueImports\n// - verbatimModuleSyntax\n//\n// TypeScript prefers for people to use \"verbatimModuleSyntax\" and has\n// deprecated the other two settings, but we must still support them.\n// All settings are combined into these two behavioral flags for us.\ntype TSUnusedImportFlags uint8\n\n// With !TSUnusedImport_KeepStmt && !TSUnusedImport_KeepValues:\n//\n//\t\"import 'foo'\"                      => \"import 'foo'\"\n//\t\"import * as unused from 'foo'\"     => \"\"\n//\t\"import { unused } from 'foo'\"      => \"\"\n//\t\"import { type unused } from 'foo'\" => \"\"\n//\n// With TSUnusedImport_KeepStmt && !TSUnusedImport_KeepValues:\n//\n//\t\"import 'foo'\"                      => \"import 'foo'\"\n//\t\"import * as unused from 'foo'\"     => \"import 'foo'\"\n//\t\"import { unused } from 'foo'\"      => \"import 'foo'\"\n//\t\"import { type unused } from 'foo'\" => \"import 'foo'\"\n//\n// With !TSUnusedImport_KeepStmt && TSUnusedImport_KeepValues:\n//\n//\t\"import 'foo'\"                      => \"import 'foo'\"\n//\t\"import * as unused from 'foo'\"     => \"import * as unused from 'foo'\"\n//\t\"import { unused } from 'foo'\"      => \"import { unused } from 'foo'\"\n//\t\"import { type unused } from 'foo'\" => \"\"\n//\n// With TSUnusedImport_KeepStmt && TSUnusedImport_KeepValues:\n//\n//\t\"import 'foo'\"                      => \"import 'foo'\"\n//\t\"import * as unused from 'foo'\"     => \"import * as unused from 'foo'\"\n//\t\"import { unused } from 'foo'\"      => \"import { unused } from 'foo'\"\n//\t\"import { type unused } from 'foo'\" => \"import {} from 'foo'\"\nconst (\n\tTSUnusedImport_KeepStmt   TSUnusedImportFlags = 1 << iota // \"importsNotUsedAsValues\" != \"remove\"\n\tTSUnusedImport_KeepValues                                 // \"preserveValueImports\" == true\n)\n\ntype TSTarget uint8\n\nconst (\n\tTSTargetUnspecified     TSTarget = iota\n\tTSTargetBelowES2022              // \"useDefineForClassFields\" defaults to false\n\tTSTargetAtOrAboveES2022          // \"useDefineForClassFields\" defaults to true\n)\n\ntype TSAlwaysStrict struct {\n\t// This information is only used for error messages\n\tName   string\n\tSource logger.Source\n\tRange  logger.Range\n\n\t// This information can affect code transformation\n\tValue bool\n}\n\ntype PathPlaceholder uint8\n\nconst (\n\tNoPlaceholder PathPlaceholder = iota\n\n\t// The relative path from the original parent directory to the configured\n\t// \"outbase\" directory, or to the lowest common ancestor directory\n\tDirPlaceholder\n\n\t// The original name of the file, or the manual chunk name, or the name of\n\t// the type of output file (\"entry\" or \"chunk\" or \"asset\")\n\tNamePlaceholder\n\n\t// A hash of the contents of this file, and the contents and output paths of\n\t// all dependencies (except for their hash placeholders)\n\tHashPlaceholder\n\n\t// The original extension of the file, or the name of the output file\n\t// (e.g. \"css\", \"svg\", \"png\")\n\tExtPlaceholder\n)\n\ntype PathTemplate struct {\n\tData        string\n\tPlaceholder PathPlaceholder\n}\n\ntype PathPlaceholders struct {\n\tDir  *string\n\tName *string\n\tHash *string\n\tExt  *string\n}\n\nfunc (placeholders PathPlaceholders) Get(placeholder PathPlaceholder) *string {\n\tswitch placeholder {\n\tcase DirPlaceholder:\n\t\treturn placeholders.Dir\n\tcase NamePlaceholder:\n\t\treturn placeholders.Name\n\tcase HashPlaceholder:\n\t\treturn placeholders.Hash\n\tcase ExtPlaceholder:\n\t\treturn placeholders.Ext\n\t}\n\treturn nil\n}\n\nfunc TemplateToString(template []PathTemplate) string {\n\tif len(template) == 1 && template[0].Placeholder == NoPlaceholder {\n\t\t// Avoid allocations in this case\n\t\treturn template[0].Data\n\t}\n\tsb := strings.Builder{}\n\tfor _, part := range template {\n\t\tsb.WriteString(part.Data)\n\t\tswitch part.Placeholder {\n\t\tcase DirPlaceholder:\n\t\t\tsb.WriteString(\"[dir]\")\n\t\tcase NamePlaceholder:\n\t\t\tsb.WriteString(\"[name]\")\n\t\tcase HashPlaceholder:\n\t\t\tsb.WriteString(\"[hash]\")\n\t\tcase ExtPlaceholder:\n\t\t\tsb.WriteString(\"[ext]\")\n\t\t}\n\t}\n\treturn sb.String()\n}\n\nfunc HasPlaceholder(template []PathTemplate, placeholder PathPlaceholder) bool {\n\tfor _, part := range template {\n\t\tif part.Placeholder == placeholder {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc SubstituteTemplate(template []PathTemplate, placeholders PathPlaceholders) []PathTemplate {\n\t// Don't allocate if no substitution is possible and the template is already minimal\n\tshouldSubstitute := false\n\tfor i, part := range template {\n\t\tif placeholders.Get(part.Placeholder) != nil || (part.Placeholder == NoPlaceholder && i+1 < len(template)) {\n\t\t\tshouldSubstitute = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !shouldSubstitute {\n\t\treturn template\n\t}\n\n\t// Otherwise, substitute and merge as appropriate\n\tresult := make([]PathTemplate, 0, len(template))\n\tfor _, part := range template {\n\t\tif sub := placeholders.Get(part.Placeholder); sub != nil {\n\t\t\tpart.Data += *sub\n\t\t\tpart.Placeholder = NoPlaceholder\n\t\t}\n\t\tif last := len(result) - 1; last >= 0 && result[last].Placeholder == NoPlaceholder {\n\t\t\tlast := &result[last]\n\t\t\tlast.Data += part.Data\n\t\t\tlast.Placeholder = part.Placeholder\n\t\t} else {\n\t\t\tresult = append(result, part)\n\t\t}\n\t}\n\treturn result\n}\n\nfunc ShouldCallRuntimeRequire(mode Mode, outputFormat Format) bool {\n\treturn mode == ModeBundle && outputFormat != FormatCommonJS\n}\n\ntype InjectedDefine struct {\n\tData   js_ast.E\n\tName   string\n\tSource logger.Source\n}\n\ntype InjectedFile struct {\n\tExports      []InjectableExport\n\tDefineName   string // For injected files generated when you \"--define\" a non-literal\n\tSource       logger.Source\n\tIsCopyLoader bool // If you set the loader to \"copy\" (see https://github.com/evanw/esbuild/issues/3041)\n}\n\ntype InjectableExport struct {\n\tAlias string\n\tLoc   logger.Loc\n}\n\nvar filterMutex sync.Mutex\nvar filterCache map[string]*regexp.Regexp\n\nfunc compileFilter(filter string) (result *regexp.Regexp) {\n\tif filter == \"\" {\n\t\t// Must provide a filter\n\t\treturn nil\n\t}\n\tok := false\n\n\t// Cache hit?\n\t(func() {\n\t\tfilterMutex.Lock()\n\t\tdefer filterMutex.Unlock()\n\t\tif filterCache != nil {\n\t\t\tresult, ok = filterCache[filter]\n\t\t}\n\t})()\n\tif ok {\n\t\treturn\n\t}\n\n\t// Cache miss\n\tresult, err := regexp.Compile(filter)\n\tif err != nil {\n\t\treturn nil\n\t}\n\n\t// Cache for next time\n\tfilterMutex.Lock()\n\tdefer filterMutex.Unlock()\n\tif filterCache == nil {\n\t\tfilterCache = make(map[string]*regexp.Regexp)\n\t}\n\tfilterCache[filter] = result\n\treturn\n}\n\nfunc CompileFilterForPlugin(pluginName string, kind string, filter string) (*regexp.Regexp, error) {\n\tif filter == \"\" {\n\t\treturn nil, fmt.Errorf(\"[%s] %q is missing a filter\", pluginName, kind)\n\t}\n\n\tresult := compileFilter(filter)\n\tif result == nil {\n\t\treturn nil, fmt.Errorf(\"[%s] %q filter is not a valid Go regular expression: %q\", pluginName, kind, filter)\n\t}\n\n\treturn result, nil\n}\n\nfunc PluginAppliesToPath(path logger.Path, filter *regexp.Regexp, namespace string) bool {\n\treturn (namespace == \"\" || path.Namespace == namespace) && filter.MatchString(path.Text)\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Plugin API\n\ntype Plugin struct {\n\tName      string\n\tOnStart   []OnStart\n\tOnResolve []OnResolve\n\tOnLoad    []OnLoad\n}\n\ntype OnStart struct {\n\tCallback func() OnStartResult\n\tName     string\n}\n\ntype OnStartResult struct {\n\tThrownError error\n\tMsgs        []logger.Msg\n}\n\ntype OnResolve struct {\n\tFilter    *regexp.Regexp\n\tCallback  func(OnResolveArgs) OnResolveResult\n\tName      string\n\tNamespace string\n}\n\ntype OnResolveArgs struct {\n\tPath       string\n\tResolveDir string\n\tPluginData interface{}\n\tImporter   logger.Path\n\tKind       ast.ImportKind\n\tWith       logger.ImportAttributes\n}\n\ntype OnResolveResult struct {\n\tPluginName string\n\n\tMsgs        []logger.Msg\n\tThrownError error\n\n\tAbsWatchFiles []string\n\tAbsWatchDirs  []string\n\n\tPluginData       interface{}\n\tPath             logger.Path\n\tExternal         bool\n\tIsSideEffectFree bool\n}\n\ntype OnLoad struct {\n\tFilter    *regexp.Regexp\n\tCallback  func(OnLoadArgs) OnLoadResult\n\tName      string\n\tNamespace string\n}\n\ntype OnLoadArgs struct {\n\tPluginData interface{}\n\tPath       logger.Path\n}\n\ntype OnLoadResult struct {\n\tPluginName string\n\n\tContents      *string\n\tAbsResolveDir string\n\tPluginData    interface{}\n\n\tMsgs        []logger.Msg\n\tThrownError error\n\n\tAbsWatchFiles []string\n\tAbsWatchDirs  []string\n\n\tLoader Loader\n}\n\nfunc PrettyPrintTargetEnvironment(originalTargetEnv string, unsupportedJSFeatureOverridesMask compat.JSFeature) (where string) {\n\twhere = \"the configured target environment\"\n\toverrides := \"\"\n\tif unsupportedJSFeatureOverridesMask != 0 {\n\t\tcount := 0\n\t\tmask := unsupportedJSFeatureOverridesMask\n\t\tfor mask != 0 {\n\t\t\tif (mask & 1) != 0 {\n\t\t\t\tcount++\n\t\t\t}\n\t\t\tmask >>= 1\n\t\t}\n\t\ts := \"s\"\n\t\tif count == 1 {\n\t\t\ts = \"\"\n\t\t}\n\t\toverrides = fmt.Sprintf(\" + %d override%s\", count, s)\n\t}\n\tif originalTargetEnv != \"\" {\n\t\twhere = fmt.Sprintf(\"%s (%s%s)\", where, originalTargetEnv, overrides)\n\t}\n\treturn\n}\n\ntype MetafileFormat uint8\n\nconst (\n\tUnminifiedMetafile MetafileFormat = iota\n\tMinifiedMetafile\n)\n\nfunc (mf MetafileFormat) MaybeRemoveWhitespace(fmt string) string {\n\tif mf == MinifiedMetafile {\n\t\tresultLen := 0\n\t\tfor i := 0; i < len(fmt); i++ {\n\t\t\tif c := fmt[i]; c != ' ' && c != '\\n' {\n\t\t\t\tresultLen++\n\t\t\t}\n\t\t}\n\t\tvar result strings.Builder\n\t\tresult.Grow(resultLen)\n\t\tfor i := 0; i < len(fmt); i++ {\n\t\t\tif c := fmt[i]; c != ' ' && c != '\\n' {\n\t\t\t\tresult.WriteByte(c)\n\t\t\t}\n\t\t}\n\t\treturn result.String()\n\t}\n\treturn fmt\n}\n"
  },
  {
    "path": "internal/config/globals.go",
    "content": "package config\n\nimport (\n\t\"math\"\n\t\"sync\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n)\n\nvar processedGlobalsMutex sync.Mutex\nvar processedGlobals *ProcessedDefines\n\n// If something is in this list, then a direct identifier expression or property\n// access chain matching this will be assumed to have no side effects and will\n// be removed.\n//\n// This also means code is allowed to be reordered past things in this list. For\n// example, if \"console.log\" is in this list, permitting reordering allows for\n// \"if (a) console.log(b); else console.log(c)\" to be reordered and transformed\n// into \"console.log(a ? b : c)\". Notice that \"a\" and \"console.log\" are in a\n// different order, which can only happen if evaluating the \"console.log\"\n// property access can be assumed to not change the value of \"a\".\n//\n// Note that membership in this list says nothing about whether calling any of\n// these functions has any side effects. It only says something about\n// referencing these function without calling them.\nvar knownGlobals = [][]string{\n\t// Array: Static methods\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#static_methods\n\t{\"Array\", \"from\"},\n\t{\"Array\", \"fromAsync\"},\n\t{\"Array\", \"isArray\"},\n\t{\"Array\", \"of\"},\n\n\t// RegExp: Static methods\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#static_methods\n\t{\"RegExp\", \"escape\"},\n\n\t// Map: Static methods\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#static_methods\n\t{\"Map\", \"groupBy\"},\n\n\t// Object: Static methods\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#static_methods\n\t{\"Object\", \"assign\"},\n\t{\"Object\", \"create\"},\n\t{\"Object\", \"defineProperties\"},\n\t{\"Object\", \"defineProperty\"},\n\t{\"Object\", \"entries\"},\n\t{\"Object\", \"freeze\"},\n\t{\"Object\", \"fromEntries\"},\n\t{\"Object\", \"getOwnPropertyDescriptor\"},\n\t{\"Object\", \"getOwnPropertyDescriptors\"},\n\t{\"Object\", \"getOwnPropertyNames\"},\n\t{\"Object\", \"getOwnPropertySymbols\"},\n\t{\"Object\", \"getPrototypeOf\"},\n\t{\"Object\", \"is\"},\n\t{\"Object\", \"isExtensible\"},\n\t{\"Object\", \"isFrozen\"},\n\t{\"Object\", \"isSealed\"},\n\t{\"Object\", \"keys\"},\n\t{\"Object\", \"preventExtensions\"},\n\t{\"Object\", \"seal\"},\n\t{\"Object\", \"setPrototypeOf\"},\n\t{\"Object\", \"values\"},\n\n\t// Object: Instance methods\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#instance_methods\n\t{\"Object\", \"prototype\", \"__defineGetter__\"},\n\t{\"Object\", \"prototype\", \"__defineSetter__\"},\n\t{\"Object\", \"prototype\", \"__lookupGetter__\"},\n\t{\"Object\", \"prototype\", \"__lookupSetter__\"},\n\t{\"Object\", \"prototype\", \"hasOwnProperty\"},\n\t{\"Object\", \"prototype\", \"isPrototypeOf\"},\n\t{\"Object\", \"prototype\", \"propertyIsEnumerable\"},\n\t{\"Object\", \"prototype\", \"toLocaleString\"},\n\t{\"Object\", \"prototype\", \"toString\"},\n\t{\"Object\", \"prototype\", \"unwatch\"},\n\t{\"Object\", \"prototype\", \"valueOf\"},\n\t{\"Object\", \"prototype\", \"watch\"},\n\n\t// Symbol: Static properties\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#static_properties\n\t{\"Symbol\", \"asyncDispose\"},\n\t{\"Symbol\", \"asyncIterator\"},\n\t{\"Symbol\", \"dispose\"},\n\t{\"Symbol\", \"hasInstance\"},\n\t{\"Symbol\", \"isConcatSpreadable\"},\n\t{\"Symbol\", \"iterator\"},\n\t{\"Symbol\", \"match\"},\n\t{\"Symbol\", \"matchAll\"},\n\t{\"Symbol\", \"replace\"},\n\t{\"Symbol\", \"search\"},\n\t{\"Symbol\", \"species\"},\n\t{\"Symbol\", \"split\"},\n\t{\"Symbol\", \"toPrimitive\"},\n\t{\"Symbol\", \"toStringTag\"},\n\t{\"Symbol\", \"unscopables\"},\n\n\t// Math: Static properties\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math#static_properties\n\t{\"Math\", \"E\"},\n\t{\"Math\", \"LN10\"},\n\t{\"Math\", \"LN2\"},\n\t{\"Math\", \"LOG10E\"},\n\t{\"Math\", \"LOG2E\"},\n\t{\"Math\", \"PI\"},\n\t{\"Math\", \"SQRT1_2\"},\n\t{\"Math\", \"SQRT2\"},\n\n\t// Math: Static methods\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math#static_methods\n\t{\"Math\", \"abs\"},\n\t{\"Math\", \"acos\"},\n\t{\"Math\", \"acosh\"},\n\t{\"Math\", \"asin\"},\n\t{\"Math\", \"asinh\"},\n\t{\"Math\", \"atan\"},\n\t{\"Math\", \"atan2\"},\n\t{\"Math\", \"atanh\"},\n\t{\"Math\", \"cbrt\"},\n\t{\"Math\", \"ceil\"},\n\t{\"Math\", \"clz32\"},\n\t{\"Math\", \"cos\"},\n\t{\"Math\", \"cosh\"},\n\t{\"Math\", \"exp\"},\n\t{\"Math\", \"expm1\"},\n\t{\"Math\", \"floor\"},\n\t{\"Math\", \"fround\"},\n\t{\"Math\", \"hypot\"},\n\t{\"Math\", \"imul\"},\n\t{\"Math\", \"log\"},\n\t{\"Math\", \"log10\"},\n\t{\"Math\", \"log1p\"},\n\t{\"Math\", \"log2\"},\n\t{\"Math\", \"max\"},\n\t{\"Math\", \"min\"},\n\t{\"Math\", \"pow\"},\n\t{\"Math\", \"random\"},\n\t{\"Math\", \"round\"},\n\t{\"Math\", \"sign\"},\n\t{\"Math\", \"sin\"},\n\t{\"Math\", \"sinh\"},\n\t{\"Math\", \"sqrt\"},\n\t{\"Math\", \"tan\"},\n\t{\"Math\", \"tanh\"},\n\t{\"Math\", \"trunc\"},\n\n\t// Reflect: Static methods\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect#static_methods\n\t{\"Reflect\", \"apply\"},\n\t{\"Reflect\", \"construct\"},\n\t{\"Reflect\", \"defineProperty\"},\n\t{\"Reflect\", \"deleteProperty\"},\n\t{\"Reflect\", \"get\"},\n\t{\"Reflect\", \"getOwnPropertyDescriptor\"},\n\t{\"Reflect\", \"getPrototypeOf\"},\n\t{\"Reflect\", \"has\"},\n\t{\"Reflect\", \"isExtensible\"},\n\t{\"Reflect\", \"ownKeys\"},\n\t{\"Reflect\", \"preventExtensions\"},\n\t{\"Reflect\", \"set\"},\n\t{\"Reflect\", \"setPrototypeOf\"},\n\n\t// JSON: Static methods\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON#static_methods\n\t{\"JSON\", \"parse\"},\n\t{\"JSON\", \"stringify\"},\n\n\t// TypedArray: Static methods\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#static_methods\n\t{\"BigInt64Array\", \"from\"},\n\t{\"BigInt64Array\", \"of\"},\n\t{\"BigUint64Array\", \"from\"},\n\t{\"BigUint64Array\", \"of\"},\n\t{\"Float16Array\", \"from\"},\n\t{\"Float16Array\", \"of\"},\n\t{\"Float32Array\", \"from\"},\n\t{\"Float32Array\", \"of\"},\n\t{\"Float64Array\", \"from\"},\n\t{\"Float64Array\", \"of\"},\n\t{\"Int16Array\", \"from\"},\n\t{\"Int16Array\", \"of\"},\n\t{\"Int32Array\", \"from\"},\n\t{\"Int32Array\", \"of\"},\n\t{\"Int8Array\", \"from\"},\n\t{\"Int8Array\", \"of\"},\n\t{\"Uint16Array\", \"from\"},\n\t{\"Uint16Array\", \"of\"},\n\t{\"Uint32Array\", \"from\"},\n\t{\"Uint32Array\", \"of\"},\n\t{\"Uint8Array\", \"from\"},\n\t{\"Uint8Array\", \"fromBase64\"},\n\t{\"Uint8Array\", \"fromHex\"},\n\t{\"Uint8Array\", \"of\"},\n\t{\"Uint8ClampedArray\", \"from\"},\n\t{\"Uint8ClampedArray\", \"of\"},\n\n\t// Other globals present in both the browser and node. This should include at\n\t// least the following properties:\n\t// https://tc39.es/ecma262/multipage/global-object.html#sec-constructor-properties-of-the-global-object\n\t//\n\t// Exceptions:\n\t// - Don't include \"eval\" because it has special behavior\n\t// - Don't include \"NaN\", \"Infinity\", and \"undefined\" because esbuild treats\n\t//   these as automatically-inlined constants instead of identifiers\n\t{\"AbortController\"},\n\t{\"AbortSignal\"},\n\t{\"AggregateError\"},\n\t{\"Array\"},\n\t{\"ArrayBuffer\"},\n\t{\"Atomics\"},\n\t{\"BigInt\"},\n\t{\"BigInt64Array\"},\n\t{\"BigUint64Array\"},\n\t{\"Boolean\"},\n\t{\"DataView\"},\n\t{\"Date\"},\n\t{\"Error\"},\n\t{\"EvalError\"},\n\t{\"Event\"},\n\t{\"EventTarget\"},\n\t{\"FinalizationRegistry\"},\n\t{\"Float16Array\"},\n\t{\"Float32Array\"},\n\t{\"Float64Array\"},\n\t{\"Function\"},\n\t{\"Int16Array\"},\n\t{\"Int32Array\"},\n\t{\"Int8Array\"},\n\t{\"Intl\"},\n\t{\"Iterator\"},\n\t{\"JSON\"},\n\t{\"Map\"},\n\t{\"Math\"},\n\t{\"MessageChannel\"},\n\t{\"MessageEvent\"},\n\t{\"MessagePort\"},\n\t{\"Number\"},\n\t{\"Object\"},\n\t{\"Promise\"},\n\t{\"Proxy\"},\n\t{\"RangeError\"},\n\t{\"ReferenceError\"},\n\t{\"Reflect\"},\n\t{\"RegExp\"},\n\t{\"Set\"},\n\t{\"SharedArrayBuffer\"},\n\t{\"String\"},\n\t{\"Symbol\"},\n\t{\"SyntaxError\"},\n\t{\"TextDecoder\"},\n\t{\"TextEncoder\"},\n\t{\"TypeError\"},\n\t{\"URIError\"},\n\t{\"URL\"},\n\t{\"URLSearchParams\"},\n\t{\"Uint16Array\"},\n\t{\"Uint32Array\"},\n\t{\"Uint8Array\"},\n\t{\"Uint8ClampedArray\"},\n\t{\"WeakMap\"},\n\t{\"WeakRef\"},\n\t{\"WeakSet\"},\n\t{\"WebAssembly\"},\n\t{\"clearInterval\"},\n\t{\"clearTimeout\"},\n\t{\"console\"},\n\t{\"decodeURI\"},\n\t{\"decodeURIComponent\"},\n\t{\"encodeURI\"},\n\t{\"encodeURIComponent\"},\n\t{\"escape\"},\n\t{\"globalThis\"},\n\t{\"isFinite\"},\n\t{\"isNaN\"},\n\t{\"parseFloat\"},\n\t{\"parseInt\"},\n\t{\"queueMicrotask\"},\n\t{\"setInterval\"},\n\t{\"setTimeout\"},\n\t{\"unescape\"},\n\n\t// Console method references are assumed to have no side effects\n\t// https://developer.mozilla.org/en-US/docs/Web/API/console\n\t{\"console\", \"assert\"},\n\t{\"console\", \"clear\"},\n\t{\"console\", \"count\"},\n\t{\"console\", \"countReset\"},\n\t{\"console\", \"debug\"},\n\t{\"console\", \"dir\"},\n\t{\"console\", \"dirxml\"},\n\t{\"console\", \"error\"},\n\t{\"console\", \"group\"},\n\t{\"console\", \"groupCollapsed\"},\n\t{\"console\", \"groupEnd\"},\n\t{\"console\", \"info\"},\n\t{\"console\", \"log\"},\n\t{\"console\", \"table\"},\n\t{\"console\", \"time\"},\n\t{\"console\", \"timeEnd\"},\n\t{\"console\", \"timeLog\"},\n\t{\"console\", \"trace\"},\n\t{\"console\", \"warn\"},\n\n\t// CSSOM APIs\n\t{\"CSSAnimation\"},\n\t{\"CSSFontFaceRule\"},\n\t{\"CSSImportRule\"},\n\t{\"CSSKeyframeRule\"},\n\t{\"CSSKeyframesRule\"},\n\t{\"CSSMediaRule\"},\n\t{\"CSSNamespaceRule\"},\n\t{\"CSSPageRule\"},\n\t{\"CSSRule\"},\n\t{\"CSSRuleList\"},\n\t{\"CSSStyleDeclaration\"},\n\t{\"CSSStyleRule\"},\n\t{\"CSSStyleSheet\"},\n\t{\"CSSSupportsRule\"},\n\t{\"CSSTransition\"},\n\n\t// SVG DOM\n\t{\"SVGAElement\"},\n\t{\"SVGAngle\"},\n\t{\"SVGAnimateElement\"},\n\t{\"SVGAnimateMotionElement\"},\n\t{\"SVGAnimateTransformElement\"},\n\t{\"SVGAnimatedAngle\"},\n\t{\"SVGAnimatedBoolean\"},\n\t{\"SVGAnimatedEnumeration\"},\n\t{\"SVGAnimatedInteger\"},\n\t{\"SVGAnimatedLength\"},\n\t{\"SVGAnimatedLengthList\"},\n\t{\"SVGAnimatedNumber\"},\n\t{\"SVGAnimatedNumberList\"},\n\t{\"SVGAnimatedPreserveAspectRatio\"},\n\t{\"SVGAnimatedRect\"},\n\t{\"SVGAnimatedString\"},\n\t{\"SVGAnimatedTransformList\"},\n\t{\"SVGAnimationElement\"},\n\t{\"SVGCircleElement\"},\n\t{\"SVGClipPathElement\"},\n\t{\"SVGComponentTransferFunctionElement\"},\n\t{\"SVGDefsElement\"},\n\t{\"SVGDescElement\"},\n\t{\"SVGElement\"},\n\t{\"SVGEllipseElement\"},\n\t{\"SVGFEBlendElement\"},\n\t{\"SVGFEColorMatrixElement\"},\n\t{\"SVGFEComponentTransferElement\"},\n\t{\"SVGFECompositeElement\"},\n\t{\"SVGFEConvolveMatrixElement\"},\n\t{\"SVGFEDiffuseLightingElement\"},\n\t{\"SVGFEDisplacementMapElement\"},\n\t{\"SVGFEDistantLightElement\"},\n\t{\"SVGFEDropShadowElement\"},\n\t{\"SVGFEFloodElement\"},\n\t{\"SVGFEFuncAElement\"},\n\t{\"SVGFEFuncBElement\"},\n\t{\"SVGFEFuncGElement\"},\n\t{\"SVGFEFuncRElement\"},\n\t{\"SVGFEGaussianBlurElement\"},\n\t{\"SVGFEImageElement\"},\n\t{\"SVGFEMergeElement\"},\n\t{\"SVGFEMergeNodeElement\"},\n\t{\"SVGFEMorphologyElement\"},\n\t{\"SVGFEOffsetElement\"},\n\t{\"SVGFEPointLightElement\"},\n\t{\"SVGFESpecularLightingElement\"},\n\t{\"SVGFESpotLightElement\"},\n\t{\"SVGFETileElement\"},\n\t{\"SVGFETurbulenceElement\"},\n\t{\"SVGFilterElement\"},\n\t{\"SVGForeignObjectElement\"},\n\t{\"SVGGElement\"},\n\t{\"SVGGeometryElement\"},\n\t{\"SVGGradientElement\"},\n\t{\"SVGGraphicsElement\"},\n\t{\"SVGImageElement\"},\n\t{\"SVGLength\"},\n\t{\"SVGLengthList\"},\n\t{\"SVGLineElement\"},\n\t{\"SVGLinearGradientElement\"},\n\t{\"SVGMPathElement\"},\n\t{\"SVGMarkerElement\"},\n\t{\"SVGMaskElement\"},\n\t{\"SVGMatrix\"},\n\t{\"SVGMetadataElement\"},\n\t{\"SVGNumber\"},\n\t{\"SVGNumberList\"},\n\t{\"SVGPathElement\"},\n\t{\"SVGPatternElement\"},\n\t{\"SVGPoint\"},\n\t{\"SVGPointList\"},\n\t{\"SVGPolygonElement\"},\n\t{\"SVGPolylineElement\"},\n\t{\"SVGPreserveAspectRatio\"},\n\t{\"SVGRadialGradientElement\"},\n\t{\"SVGRect\"},\n\t{\"SVGRectElement\"},\n\t{\"SVGSVGElement\"},\n\t{\"SVGScriptElement\"},\n\t{\"SVGSetElement\"},\n\t{\"SVGStopElement\"},\n\t{\"SVGStringList\"},\n\t{\"SVGStyleElement\"},\n\t{\"SVGSwitchElement\"},\n\t{\"SVGSymbolElement\"},\n\t{\"SVGTSpanElement\"},\n\t{\"SVGTextContentElement\"},\n\t{\"SVGTextElement\"},\n\t{\"SVGTextPathElement\"},\n\t{\"SVGTextPositioningElement\"},\n\t{\"SVGTitleElement\"},\n\t{\"SVGTransform\"},\n\t{\"SVGTransformList\"},\n\t{\"SVGUnitTypes\"},\n\t{\"SVGUseElement\"},\n\t{\"SVGViewElement\"},\n\n\t// Other browser APIs\n\t//\n\t// This list contains all globals present in modern versions of Chrome, Safari,\n\t// and Firefox except for the following properties, since they have a side effect\n\t// of triggering layout (https://gist.github.com/paulirish/5d52fb081b3570c81e3a):\n\t//\n\t//   - scrollX\n\t//   - scrollY\n\t//   - innerWidth\n\t//   - innerHeight\n\t//   - pageXOffset\n\t//   - pageYOffset\n\t//\n\t// The following globals have also been removed since they sometimes throw an\n\t// exception when accessed, which is a side effect (for more information see\n\t// https://stackoverflow.com/a/33047477):\n\t//\n\t//   - localStorage\n\t//   - sessionStorage\n\t//\n\t{\"AnalyserNode\"},\n\t{\"Animation\"},\n\t{\"AnimationEffect\"},\n\t{\"AnimationEvent\"},\n\t{\"AnimationPlaybackEvent\"},\n\t{\"AnimationTimeline\"},\n\t{\"Attr\"},\n\t{\"Audio\"},\n\t{\"AudioBuffer\"},\n\t{\"AudioBufferSourceNode\"},\n\t{\"AudioDestinationNode\"},\n\t{\"AudioListener\"},\n\t{\"AudioNode\"},\n\t{\"AudioParam\"},\n\t{\"AudioProcessingEvent\"},\n\t{\"AudioScheduledSourceNode\"},\n\t{\"BarProp\"},\n\t{\"BeforeUnloadEvent\"},\n\t{\"BiquadFilterNode\"},\n\t{\"Blob\"},\n\t{\"BlobEvent\"},\n\t{\"ByteLengthQueuingStrategy\"},\n\t{\"CDATASection\"},\n\t{\"CSS\"},\n\t{\"CanvasGradient\"},\n\t{\"CanvasPattern\"},\n\t{\"CanvasRenderingContext2D\"},\n\t{\"ChannelMergerNode\"},\n\t{\"ChannelSplitterNode\"},\n\t{\"CharacterData\"},\n\t{\"ClipboardEvent\"},\n\t{\"CloseEvent\"},\n\t{\"Comment\"},\n\t{\"CompositionEvent\"},\n\t{\"ConvolverNode\"},\n\t{\"CountQueuingStrategy\"},\n\t{\"Crypto\"},\n\t{\"CustomElementRegistry\"},\n\t{\"CustomEvent\"},\n\t{\"DOMException\"},\n\t{\"DOMImplementation\"},\n\t{\"DOMMatrix\"},\n\t{\"DOMMatrixReadOnly\"},\n\t{\"DOMParser\"},\n\t{\"DOMPoint\"},\n\t{\"DOMPointReadOnly\"},\n\t{\"DOMQuad\"},\n\t{\"DOMRect\"},\n\t{\"DOMRectList\"},\n\t{\"DOMRectReadOnly\"},\n\t{\"DOMStringList\"},\n\t{\"DOMStringMap\"},\n\t{\"DOMTokenList\"},\n\t{\"DataTransfer\"},\n\t{\"DataTransferItem\"},\n\t{\"DataTransferItemList\"},\n\t{\"DelayNode\"},\n\t{\"Document\"},\n\t{\"DocumentFragment\"},\n\t{\"DocumentTimeline\"},\n\t{\"DocumentType\"},\n\t{\"DragEvent\"},\n\t{\"DynamicsCompressorNode\"},\n\t{\"Element\"},\n\t{\"ErrorEvent\"},\n\t{\"EventSource\"},\n\t{\"File\"},\n\t{\"FileList\"},\n\t{\"FileReader\"},\n\t{\"FocusEvent\"},\n\t{\"FontFace\"},\n\t{\"FormData\"},\n\t{\"GainNode\"},\n\t{\"Gamepad\"},\n\t{\"GamepadButton\"},\n\t{\"GamepadEvent\"},\n\t{\"Geolocation\"},\n\t{\"GeolocationPositionError\"},\n\t{\"HTMLAllCollection\"},\n\t{\"HTMLAnchorElement\"},\n\t{\"HTMLAreaElement\"},\n\t{\"HTMLAudioElement\"},\n\t{\"HTMLBRElement\"},\n\t{\"HTMLBaseElement\"},\n\t{\"HTMLBodyElement\"},\n\t{\"HTMLButtonElement\"},\n\t{\"HTMLCanvasElement\"},\n\t{\"HTMLCollection\"},\n\t{\"HTMLDListElement\"},\n\t{\"HTMLDataElement\"},\n\t{\"HTMLDataListElement\"},\n\t{\"HTMLDetailsElement\"},\n\t{\"HTMLDirectoryElement\"},\n\t{\"HTMLDivElement\"},\n\t{\"HTMLDocument\"},\n\t{\"HTMLElement\"},\n\t{\"HTMLEmbedElement\"},\n\t{\"HTMLFieldSetElement\"},\n\t{\"HTMLFontElement\"},\n\t{\"HTMLFormControlsCollection\"},\n\t{\"HTMLFormElement\"},\n\t{\"HTMLFrameElement\"},\n\t{\"HTMLFrameSetElement\"},\n\t{\"HTMLHRElement\"},\n\t{\"HTMLHeadElement\"},\n\t{\"HTMLHeadingElement\"},\n\t{\"HTMLHtmlElement\"},\n\t{\"HTMLIFrameElement\"},\n\t{\"HTMLImageElement\"},\n\t{\"HTMLInputElement\"},\n\t{\"HTMLLIElement\"},\n\t{\"HTMLLabelElement\"},\n\t{\"HTMLLegendElement\"},\n\t{\"HTMLLinkElement\"},\n\t{\"HTMLMapElement\"},\n\t{\"HTMLMarqueeElement\"},\n\t{\"HTMLMediaElement\"},\n\t{\"HTMLMenuElement\"},\n\t{\"HTMLMetaElement\"},\n\t{\"HTMLMeterElement\"},\n\t{\"HTMLModElement\"},\n\t{\"HTMLOListElement\"},\n\t{\"HTMLObjectElement\"},\n\t{\"HTMLOptGroupElement\"},\n\t{\"HTMLOptionElement\"},\n\t{\"HTMLOptionsCollection\"},\n\t{\"HTMLOutputElement\"},\n\t{\"HTMLParagraphElement\"},\n\t{\"HTMLParamElement\"},\n\t{\"HTMLPictureElement\"},\n\t{\"HTMLPreElement\"},\n\t{\"HTMLProgressElement\"},\n\t{\"HTMLQuoteElement\"},\n\t{\"HTMLScriptElement\"},\n\t{\"HTMLSelectElement\"},\n\t{\"HTMLSlotElement\"},\n\t{\"HTMLSourceElement\"},\n\t{\"HTMLSpanElement\"},\n\t{\"HTMLStyleElement\"},\n\t{\"HTMLTableCaptionElement\"},\n\t{\"HTMLTableCellElement\"},\n\t{\"HTMLTableColElement\"},\n\t{\"HTMLTableElement\"},\n\t{\"HTMLTableRowElement\"},\n\t{\"HTMLTableSectionElement\"},\n\t{\"HTMLTemplateElement\"},\n\t{\"HTMLTextAreaElement\"},\n\t{\"HTMLTimeElement\"},\n\t{\"HTMLTitleElement\"},\n\t{\"HTMLTrackElement\"},\n\t{\"HTMLUListElement\"},\n\t{\"HTMLUnknownElement\"},\n\t{\"HTMLVideoElement\"},\n\t{\"HashChangeEvent\"},\n\t{\"Headers\"},\n\t{\"History\"},\n\t{\"IDBCursor\"},\n\t{\"IDBCursorWithValue\"},\n\t{\"IDBDatabase\"},\n\t{\"IDBFactory\"},\n\t{\"IDBIndex\"},\n\t{\"IDBKeyRange\"},\n\t{\"IDBObjectStore\"},\n\t{\"IDBOpenDBRequest\"},\n\t{\"IDBRequest\"},\n\t{\"IDBTransaction\"},\n\t{\"IDBVersionChangeEvent\"},\n\t{\"Image\"},\n\t{\"ImageData\"},\n\t{\"InputEvent\"},\n\t{\"IntersectionObserver\"},\n\t{\"IntersectionObserverEntry\"},\n\t{\"KeyboardEvent\"},\n\t{\"KeyframeEffect\"},\n\t{\"Location\"},\n\t{\"MediaCapabilities\"},\n\t{\"MediaElementAudioSourceNode\"},\n\t{\"MediaEncryptedEvent\"},\n\t{\"MediaError\"},\n\t{\"MediaList\"},\n\t{\"MediaQueryList\"},\n\t{\"MediaQueryListEvent\"},\n\t{\"MediaRecorder\"},\n\t{\"MediaSource\"},\n\t{\"MediaStream\"},\n\t{\"MediaStreamAudioDestinationNode\"},\n\t{\"MediaStreamAudioSourceNode\"},\n\t{\"MediaStreamTrack\"},\n\t{\"MediaStreamTrackEvent\"},\n\t{\"MimeType\"},\n\t{\"MimeTypeArray\"},\n\t{\"MouseEvent\"},\n\t{\"MutationEvent\"},\n\t{\"MutationObserver\"},\n\t{\"MutationRecord\"},\n\t{\"NamedNodeMap\"},\n\t{\"Navigator\"},\n\t{\"Node\"},\n\t{\"NodeFilter\"},\n\t{\"NodeIterator\"},\n\t{\"NodeList\"},\n\t{\"Notification\"},\n\t{\"OfflineAudioCompletionEvent\"},\n\t{\"Option\"},\n\t{\"OscillatorNode\"},\n\t{\"PageTransitionEvent\"},\n\t{\"Path2D\"},\n\t{\"Performance\"},\n\t{\"PerformanceEntry\"},\n\t{\"PerformanceMark\"},\n\t{\"PerformanceMeasure\"},\n\t{\"PerformanceNavigation\"},\n\t{\"PerformanceObserver\"},\n\t{\"PerformanceObserverEntryList\"},\n\t{\"PerformanceResourceTiming\"},\n\t{\"PerformanceTiming\"},\n\t{\"PeriodicWave\"},\n\t{\"Plugin\"},\n\t{\"PluginArray\"},\n\t{\"PointerEvent\"},\n\t{\"PopStateEvent\"},\n\t{\"ProcessingInstruction\"},\n\t{\"ProgressEvent\"},\n\t{\"PromiseRejectionEvent\"},\n\t{\"RTCCertificate\"},\n\t{\"RTCDTMFSender\"},\n\t{\"RTCDTMFToneChangeEvent\"},\n\t{\"RTCDataChannel\"},\n\t{\"RTCDataChannelEvent\"},\n\t{\"RTCIceCandidate\"},\n\t{\"RTCPeerConnection\"},\n\t{\"RTCPeerConnectionIceEvent\"},\n\t{\"RTCRtpReceiver\"},\n\t{\"RTCRtpSender\"},\n\t{\"RTCRtpTransceiver\"},\n\t{\"RTCSessionDescription\"},\n\t{\"RTCStatsReport\"},\n\t{\"RTCTrackEvent\"},\n\t{\"RadioNodeList\"},\n\t{\"Range\"},\n\t{\"ReadableStream\"},\n\t{\"Request\"},\n\t{\"ResizeObserver\"},\n\t{\"ResizeObserverEntry\"},\n\t{\"Response\"},\n\t{\"Screen\"},\n\t{\"ScriptProcessorNode\"},\n\t{\"SecurityPolicyViolationEvent\"},\n\t{\"Selection\"},\n\t{\"ShadowRoot\"},\n\t{\"SourceBuffer\"},\n\t{\"SourceBufferList\"},\n\t{\"SpeechSynthesisEvent\"},\n\t{\"SpeechSynthesisUtterance\"},\n\t{\"StaticRange\"},\n\t{\"Storage\"},\n\t{\"StorageEvent\"},\n\t{\"StyleSheet\"},\n\t{\"StyleSheetList\"},\n\t{\"Text\"},\n\t{\"TextMetrics\"},\n\t{\"TextTrack\"},\n\t{\"TextTrackCue\"},\n\t{\"TextTrackCueList\"},\n\t{\"TextTrackList\"},\n\t{\"TimeRanges\"},\n\t{\"TrackEvent\"},\n\t{\"TransitionEvent\"},\n\t{\"TreeWalker\"},\n\t{\"UIEvent\"},\n\t{\"VTTCue\"},\n\t{\"ValidityState\"},\n\t{\"VisualViewport\"},\n\t{\"WaveShaperNode\"},\n\t{\"WebGLActiveInfo\"},\n\t{\"WebGLBuffer\"},\n\t{\"WebGLContextEvent\"},\n\t{\"WebGLFramebuffer\"},\n\t{\"WebGLProgram\"},\n\t{\"WebGLQuery\"},\n\t{\"WebGLRenderbuffer\"},\n\t{\"WebGLRenderingContext\"},\n\t{\"WebGLSampler\"},\n\t{\"WebGLShader\"},\n\t{\"WebGLShaderPrecisionFormat\"},\n\t{\"WebGLSync\"},\n\t{\"WebGLTexture\"},\n\t{\"WebGLUniformLocation\"},\n\t{\"WebKitCSSMatrix\"},\n\t{\"WebSocket\"},\n\t{\"WheelEvent\"},\n\t{\"Window\"},\n\t{\"Worker\"},\n\t{\"XMLDocument\"},\n\t{\"XMLHttpRequest\"},\n\t{\"XMLHttpRequestEventTarget\"},\n\t{\"XMLHttpRequestUpload\"},\n\t{\"XMLSerializer\"},\n\t{\"XPathEvaluator\"},\n\t{\"XPathExpression\"},\n\t{\"XPathResult\"},\n\t{\"XSLTProcessor\"},\n\t{\"alert\"},\n\t{\"atob\"},\n\t{\"blur\"},\n\t{\"btoa\"},\n\t{\"cancelAnimationFrame\"},\n\t{\"captureEvents\"},\n\t{\"close\"},\n\t{\"closed\"},\n\t{\"confirm\"},\n\t{\"customElements\"},\n\t{\"devicePixelRatio\"},\n\t{\"document\"},\n\t{\"event\"},\n\t{\"fetch\"},\n\t{\"find\"},\n\t{\"focus\"},\n\t{\"frameElement\"},\n\t{\"frames\"},\n\t{\"getComputedStyle\"},\n\t{\"getSelection\"},\n\t{\"history\"},\n\t{\"indexedDB\"},\n\t{\"isSecureContext\"},\n\t{\"length\"},\n\t{\"location\"},\n\t{\"locationbar\"},\n\t{\"matchMedia\"},\n\t{\"menubar\"},\n\t{\"moveBy\"},\n\t{\"moveTo\"},\n\t{\"name\"},\n\t{\"navigator\"},\n\t{\"onabort\"},\n\t{\"onafterprint\"},\n\t{\"onanimationend\"},\n\t{\"onanimationiteration\"},\n\t{\"onanimationstart\"},\n\t{\"onbeforeprint\"},\n\t{\"onbeforeunload\"},\n\t{\"onblur\"},\n\t{\"oncanplay\"},\n\t{\"oncanplaythrough\"},\n\t{\"onchange\"},\n\t{\"onclick\"},\n\t{\"oncontextmenu\"},\n\t{\"oncuechange\"},\n\t{\"ondblclick\"},\n\t{\"ondrag\"},\n\t{\"ondragend\"},\n\t{\"ondragenter\"},\n\t{\"ondragleave\"},\n\t{\"ondragover\"},\n\t{\"ondragstart\"},\n\t{\"ondrop\"},\n\t{\"ondurationchange\"},\n\t{\"onemptied\"},\n\t{\"onended\"},\n\t{\"onerror\"},\n\t{\"onfocus\"},\n\t{\"ongotpointercapture\"},\n\t{\"onhashchange\"},\n\t{\"oninput\"},\n\t{\"oninvalid\"},\n\t{\"onkeydown\"},\n\t{\"onkeypress\"},\n\t{\"onkeyup\"},\n\t{\"onlanguagechange\"},\n\t{\"onload\"},\n\t{\"onloadeddata\"},\n\t{\"onloadedmetadata\"},\n\t{\"onloadstart\"},\n\t{\"onlostpointercapture\"},\n\t{\"onmessage\"},\n\t{\"onmousedown\"},\n\t{\"onmouseenter\"},\n\t{\"onmouseleave\"},\n\t{\"onmousemove\"},\n\t{\"onmouseout\"},\n\t{\"onmouseover\"},\n\t{\"onmouseup\"},\n\t{\"onoffline\"},\n\t{\"ononline\"},\n\t{\"onpagehide\"},\n\t{\"onpageshow\"},\n\t{\"onpause\"},\n\t{\"onplay\"},\n\t{\"onplaying\"},\n\t{\"onpointercancel\"},\n\t{\"onpointerdown\"},\n\t{\"onpointerenter\"},\n\t{\"onpointerleave\"},\n\t{\"onpointermove\"},\n\t{\"onpointerout\"},\n\t{\"onpointerover\"},\n\t{\"onpointerup\"},\n\t{\"onpopstate\"},\n\t{\"onprogress\"},\n\t{\"onratechange\"},\n\t{\"onrejectionhandled\"},\n\t{\"onreset\"},\n\t{\"onresize\"},\n\t{\"onscroll\"},\n\t{\"onseeked\"},\n\t{\"onseeking\"},\n\t{\"onselect\"},\n\t{\"onstalled\"},\n\t{\"onstorage\"},\n\t{\"onsubmit\"},\n\t{\"onsuspend\"},\n\t{\"ontimeupdate\"},\n\t{\"ontoggle\"},\n\t{\"ontransitioncancel\"},\n\t{\"ontransitionend\"},\n\t{\"ontransitionrun\"},\n\t{\"ontransitionstart\"},\n\t{\"onunhandledrejection\"},\n\t{\"onunload\"},\n\t{\"onvolumechange\"},\n\t{\"onwaiting\"},\n\t{\"onwebkitanimationend\"},\n\t{\"onwebkitanimationiteration\"},\n\t{\"onwebkitanimationstart\"},\n\t{\"onwebkittransitionend\"},\n\t{\"onwheel\"},\n\t{\"open\"},\n\t{\"opener\"},\n\t{\"origin\"},\n\t{\"outerHeight\"},\n\t{\"outerWidth\"},\n\t{\"parent\"},\n\t{\"performance\"},\n\t{\"personalbar\"},\n\t{\"postMessage\"},\n\t{\"print\"},\n\t{\"prompt\"},\n\t{\"releaseEvents\"},\n\t{\"requestAnimationFrame\"},\n\t{\"resizeBy\"},\n\t{\"resizeTo\"},\n\t{\"screen\"},\n\t{\"screenLeft\"},\n\t{\"screenTop\"},\n\t{\"screenX\"},\n\t{\"screenY\"},\n\t{\"scroll\"},\n\t{\"scrollBy\"},\n\t{\"scrollTo\"},\n\t{\"scrollbars\"},\n\t{\"self\"},\n\t{\"speechSynthesis\"},\n\t{\"status\"},\n\t{\"statusbar\"},\n\t{\"stop\"},\n\t{\"toolbar\"},\n\t{\"top\"},\n\t{\"webkitURL\"},\n\t{\"window\"},\n}\n\n// We currently only support compile-time replacement with certain expressions:\n//\n//   - Primitive literals\n//   - Identifiers\n//   - \"Entity names\" which are identifiers followed by property accesses\n//\n// We don't support arbitrary expressions because arbitrary expressions may\n// require the full AST. For example, there could be \"import()\" or \"require()\"\n// expressions that need an import record. We also need to re-generate some\n// nodes such as identifiers within the injected context so that they can\n// bind to symbols in that context. Other expressions such as \"this\" may\n// also be contextual.\ntype DefineExpr struct {\n\tConstant            js_ast.E\n\tParts               []string\n\tInjectedDefineIndex ast.Index32\n}\n\ntype DefineData struct {\n\tKeyParts   []string\n\tDefineExpr *DefineExpr\n\tFlags      DefineFlags\n}\n\ntype DefineFlags uint8\n\nconst (\n\t// True if accessing this value is known to not have any side effects. For\n\t// example, a bare reference to \"Object.create\" can be removed because it\n\t// does not have any observable side effects.\n\tCanBeRemovedIfUnused DefineFlags = 1 << iota\n\n\t// True if a call to this value is known to not have any side effects. For\n\t// example, a bare call to \"Object()\" can be removed because it does not\n\t// have any observable side effects.\n\tCallCanBeUnwrappedIfUnused\n\n\t// If true, the user has indicated that every direct calls to a property on\n\t// this object and all of that call's arguments are to be removed from the\n\t// output, even when the arguments have side effects. This is used to\n\t// implement the \"--drop:console\" flag.\n\tMethodCallsMustBeReplacedWithUndefined\n\n\t// Symbol values are known to not have side effects when used as property\n\t// names in class declarations and object literals.\n\tIsSymbolInstance\n)\n\nfunc (flags DefineFlags) Has(flag DefineFlags) bool {\n\treturn (flags & flag) != 0\n}\n\nfunc mergeDefineData(old DefineData, new DefineData) DefineData {\n\tnew.Flags |= old.Flags\n\treturn new\n}\n\ntype ProcessedDefines struct {\n\tIdentifierDefines map[string]DefineData\n\tDotDefines        map[string][]DefineData\n}\n\n// This transformation is expensive, so we only want to do it once. Make sure\n// to only call processDefines() once per compilation. Unfortunately Golang\n// doesn't have an efficient way to copy a map and the overhead of copying\n// all of the properties into a new map once for every new parser noticeably\n// slows down our benchmarks.\nfunc ProcessDefines(userDefines []DefineData) ProcessedDefines {\n\t// Optimization: reuse known globals if there are no user-specified defines\n\thasUserDefines := len(userDefines) != 0\n\tif !hasUserDefines {\n\t\tprocessedGlobalsMutex.Lock()\n\t\tif processedGlobals != nil {\n\t\t\tdefer processedGlobalsMutex.Unlock()\n\t\t\treturn *processedGlobals\n\t\t}\n\t\tprocessedGlobalsMutex.Unlock()\n\t}\n\n\tresult := ProcessedDefines{\n\t\tIdentifierDefines: make(map[string]DefineData),\n\t\tDotDefines:        make(map[string][]DefineData),\n\t}\n\n\t// Mark these property accesses as free of side effects. That means they can\n\t// be removed if their result is unused. We can't just remove all unused\n\t// property accesses since property accesses can have side effects. For\n\t// example, the property access \"a.b.c\" has the side effect of throwing an\n\t// exception if \"a.b\" is undefined.\n\tfor _, parts := range knownGlobals {\n\t\ttail := parts[len(parts)-1]\n\t\tif len(parts) == 1 {\n\t\t\tresult.IdentifierDefines[tail] = DefineData{Flags: CanBeRemovedIfUnused}\n\t\t} else {\n\t\t\tflags := CanBeRemovedIfUnused\n\n\t\t\t// All properties on the \"Symbol\" global are currently symbol instances\n\t\t\t// (i.e. \"typeof Symbol.iterator === 'symbol'\"). This is used to avoid\n\t\t\t// treating properties with these names as having side effects.\n\t\t\tif parts[0] == \"Symbol\" {\n\t\t\t\tflags |= IsSymbolInstance\n\t\t\t}\n\n\t\t\tresult.DotDefines[tail] = append(result.DotDefines[tail], DefineData{KeyParts: parts, Flags: flags})\n\t\t}\n\t}\n\n\t// Swap in certain literal values because those can be constant folded\n\tresult.IdentifierDefines[\"undefined\"] = DefineData{\n\t\tDefineExpr: &DefineExpr{Constant: js_ast.EUndefinedShared},\n\t}\n\tresult.IdentifierDefines[\"NaN\"] = DefineData{\n\t\tDefineExpr: &DefineExpr{Constant: &js_ast.ENumber{Value: math.NaN()}},\n\t}\n\tresult.IdentifierDefines[\"Infinity\"] = DefineData{\n\t\tDefineExpr: &DefineExpr{Constant: &js_ast.ENumber{Value: math.Inf(1)}},\n\t}\n\n\t// Then copy the user-specified defines in afterwards, which will overwrite\n\t// any known globals above.\n\tfor _, data := range userDefines {\n\t\t// Identifier defines are special-cased\n\t\tif len(data.KeyParts) == 1 {\n\t\t\tname := data.KeyParts[0]\n\t\t\tresult.IdentifierDefines[name] = mergeDefineData(result.IdentifierDefines[name], data)\n\t\t\tcontinue\n\t\t}\n\n\t\ttail := data.KeyParts[len(data.KeyParts)-1]\n\t\tdotDefines := result.DotDefines[tail]\n\t\tfound := false\n\n\t\t// Try to merge with existing dot defines first\n\t\tfor i, define := range dotDefines {\n\t\t\tif helpers.StringArraysEqual(data.KeyParts, define.KeyParts) {\n\t\t\t\tdotDefines[i] = mergeDefineData(dotDefines[i], data)\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif !found {\n\t\t\tdotDefines = append(dotDefines, data)\n\t\t}\n\t\tresult.DotDefines[tail] = dotDefines\n\t}\n\n\t// Potentially cache the result for next time\n\tif !hasUserDefines {\n\t\tprocessedGlobalsMutex.Lock()\n\t\tdefer processedGlobalsMutex.Unlock()\n\t\tif processedGlobals == nil {\n\t\t\tprocessedGlobals = &result\n\t\t}\n\t}\n\treturn result\n}\n"
  },
  {
    "path": "internal/css_ast/css_ast.go",
    "content": "package css_ast\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\n// CSS syntax comes in two layers: a minimal syntax that generally accepts\n// anything that looks vaguely like CSS, and a large set of built-in rules\n// (the things browsers actually interpret). That way CSS parsers can read\n// unknown rules and skip over them without having to stop due to errors.\n//\n// This AST format is mostly just the minimal syntax. It parses unknown rules\n// into a tree with enough information that it can write them back out again.\n// There are some additional layers of syntax including selectors and @-rules\n// which allow for better pretty-printing and minification.\n//\n// Most of the AST just references ranges of the original file by keeping the\n// original \"Token\" values around from the lexer. This is a memory-efficient\n// representation that helps provide good parsing and printing performance.\n\ntype AST struct {\n\tSymbols              []ast.Symbol\n\tCharFreq             *ast.CharFreq\n\tImportRecords        []ast.ImportRecord\n\tRules                []Rule\n\tSourceMapComment     logger.Span\n\tApproximateLineCount int32\n\tLocalSymbols         []ast.LocRef\n\tLocalScope           map[string]ast.LocRef\n\tGlobalScope          map[string]ast.LocRef\n\tComposes             map[ast.Ref]*Composes\n\n\t// These contain all layer names in the file. It can be used to replace the\n\t// layer-related side effects of importing this file. They are split into two\n\t// groups (those before and after \"@import\" rules) so that the linker can put\n\t// them in the right places.\n\tLayersPreImport  [][]string\n\tLayersPostImport [][]string\n}\n\ntype Composes struct {\n\t// Note that each of these can be either local or global. Local examples:\n\t//\n\t//   .foo { composes: bar }\n\t//   .bar { color: red }\n\t//\n\t// Global examples:\n\t//\n\t//   .foo { composes: bar from global }\n\t//   .foo :global { composes: bar }\n\t//   .foo { :global { composes: bar } }\n\t//   :global .bar { color: red }\n\t//\n\tNames []ast.LocRef\n\n\t// Each of these is local in another file. For example:\n\t//\n\t//   .foo { composes: bar from \"bar.css\" }\n\t//   .foo { composes: bar from url(bar.css) }\n\t//\n\tImportedNames []ImportedComposesName\n\n\t// This tracks what CSS properties each class uses so that we can warn when\n\t// \"composes\" is used incorrectly to compose two classes from separate files\n\t// that declare the same CSS properties.\n\tProperties map[string]logger.Loc\n}\n\ntype ImportedComposesName struct {\n\tAlias             string\n\tAliasLoc          logger.Loc\n\tImportRecordIndex uint32\n}\n\n// We create a lot of tokens, so make sure this layout is memory-efficient.\n// The layout here isn't optimal because it biases for convenience (e.g.\n// \"string\" could be shorter) but at least the ordering of fields was\n// deliberately chosen to minimize size.\ntype Token struct {\n\t// Contains the child tokens for component values that are simple blocks.\n\t// These are either \"(\", \"{\", \"[\", or function tokens. The closing token is\n\t// implicit and is not stored.\n\tChildren *[]Token // 8 bytes\n\n\t// This is the raw contents of the token most of the time. However, it\n\t// contains the decoded string contents for \"TString\" tokens.\n\tText string // 16 bytes\n\n\t// The source location at the start of the token\n\tLoc logger.Loc // 4 bytes\n\n\t// URL tokens have an associated import record at the top-level of the AST.\n\t// This index points to that import record.\n\t//\n\t// Symbol tokens have an associated symbol. This index is the \"InnerIndex\"\n\t// of the \"Ref\" for this symbol. The \"SourceIndex\" for the \"Ref\" is just\n\t// the source index of the file for this AST.\n\tPayloadIndex uint32 // 4 bytes\n\n\t// The division between the number and the unit for \"TDimension\" tokens.\n\tUnitOffset uint16 // 2 bytes\n\n\t// This will never be \"TWhitespace\" because whitespace isn't stored as a\n\t// token directly. Instead it is stored in \"HasWhitespaceAfter\" on the\n\t// previous token. This is to make it easier to pattern-match against\n\t// tokens when handling CSS rules, since whitespace almost always doesn't\n\t// matter. That way you can pattern match against e.g. \"rgb(r, g, b)\" and\n\t// not have to handle all possible combinations of embedded whitespace\n\t// tokens.\n\t//\n\t// There is one exception to this: when in verbatim whitespace mode and\n\t// the token list is non-empty and is only whitespace tokens. In that case\n\t// a single whitespace token is emitted. This is because otherwise there\n\t// would be no tokens to attach the whitespace before/after flags to.\n\tKind css_lexer.T // 1 byte\n\n\t// These flags indicate the presence of a \"TWhitespace\" token before or after\n\t// this token. There should be whitespace printed between two tokens if either\n\t// token indicates that there should be whitespace. Note that whitespace may\n\t// be altered by processing in certain situations (e.g. minification).\n\tWhitespace WhitespaceFlags // 1 byte\n}\n\ntype WhitespaceFlags uint8\n\nconst (\n\tWhitespaceBefore WhitespaceFlags = 1 << iota\n\tWhitespaceAfter\n)\n\n// This is necessary when comparing tokens between two different files\ntype CrossFileEqualityCheck struct {\n\tImportRecordsA []ast.ImportRecord\n\tImportRecordsB []ast.ImportRecord\n\tSymbols        ast.SymbolMap\n\tSourceIndexA   uint32\n\tSourceIndexB   uint32\n}\n\nfunc (check *CrossFileEqualityCheck) RefsAreEquivalent(a ast.Ref, b ast.Ref) bool {\n\tif a == b {\n\t\treturn true\n\t}\n\tif check == nil || check.Symbols.SymbolsForSource == nil {\n\t\treturn false\n\t}\n\ta = ast.FollowSymbols(check.Symbols, a)\n\tb = ast.FollowSymbols(check.Symbols, b)\n\tif a == b {\n\t\treturn true\n\t}\n\tsymbolA := check.Symbols.Get(a)\n\tsymbolB := check.Symbols.Get(b)\n\treturn symbolA.Kind == ast.SymbolGlobalCSS && symbolB.Kind == ast.SymbolGlobalCSS && symbolA.OriginalName == symbolB.OriginalName\n}\n\nfunc (a Token) Equal(b Token, check *CrossFileEqualityCheck) bool {\n\tif a.Kind == b.Kind && a.Text == b.Text && a.Whitespace == b.Whitespace {\n\t\t// URLs should be compared based on the text of the associated import record\n\t\t// (which is what will actually be printed) instead of the original text\n\t\tif a.Kind == css_lexer.TURL {\n\t\t\tif check == nil {\n\t\t\t\t// If both tokens are in the same file, just compare the index\n\t\t\t\tif a.PayloadIndex != b.PayloadIndex {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If the tokens come from separate files, compare the import records\n\t\t\t\t// themselves instead of comparing the indices. This can happen when\n\t\t\t\t// the linker runs a \"DuplicateRuleRemover\" during bundling. This\n\t\t\t\t// doesn't compare the source indices because at this point during\n\t\t\t\t// linking, paths inside the bundle (e.g. due to the \"copy\" loader)\n\t\t\t\t// should have already been converted into text (e.g. the \"unique key\"\n\t\t\t\t// string).\n\t\t\t\tif check.ImportRecordsA[a.PayloadIndex].Path.Text !=\n\t\t\t\t\tcheck.ImportRecordsB[b.PayloadIndex].Path.Text {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Symbols should be compared based on the symbol reference instead of the\n\t\t// original text\n\t\tif a.Kind == css_lexer.TSymbol {\n\t\t\tif check == nil {\n\t\t\t\t// If both tokens are in the same file, just compare the index\n\t\t\t\tif a.PayloadIndex != b.PayloadIndex {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If the tokens come from separate files, compare the symbols themselves\n\t\t\t\trefA := ast.Ref{SourceIndex: check.SourceIndexA, InnerIndex: a.PayloadIndex}\n\t\t\t\trefB := ast.Ref{SourceIndex: check.SourceIndexB, InnerIndex: b.PayloadIndex}\n\t\t\t\tif !check.RefsAreEquivalent(refA, refB) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif a.Children == nil && b.Children == nil {\n\t\t\treturn true\n\t\t}\n\n\t\tif a.Children != nil && b.Children != nil && TokensEqual(*a.Children, *b.Children, check) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc TokensEqual(a []Token, b []Token, check *CrossFileEqualityCheck) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor i, ai := range a {\n\t\tif !ai.Equal(b[i], check) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc HashTokens(hash uint32, tokens []Token) uint32 {\n\thash = helpers.HashCombine(hash, uint32(len(tokens)))\n\n\tfor _, t := range tokens {\n\t\thash = helpers.HashCombine(hash, uint32(t.Kind))\n\t\tif t.Kind != css_lexer.TURL {\n\t\t\thash = helpers.HashCombineString(hash, t.Text)\n\t\t}\n\t\tif t.Children != nil {\n\t\t\thash = HashTokens(hash, *t.Children)\n\t\t}\n\t}\n\n\treturn hash\n}\n\nfunc (a Token) EqualIgnoringWhitespace(b Token) bool {\n\tif a.Kind == b.Kind && a.Text == b.Text && a.PayloadIndex == b.PayloadIndex {\n\t\tif a.Children == nil && b.Children == nil {\n\t\t\treturn true\n\t\t}\n\n\t\tif a.Children != nil && b.Children != nil && TokensEqualIgnoringWhitespace(*a.Children, *b.Children) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc TokensEqualIgnoringWhitespace(a []Token, b []Token) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor i, c := range a {\n\t\tif !c.EqualIgnoringWhitespace(b[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc TokensAreCommaSeparated(tokens []Token) bool {\n\tif n := len(tokens); (n & 1) != 0 {\n\t\tfor i := 1; i < n; i += 2 {\n\t\t\tif tokens[i].Kind != css_lexer.TComma {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n\ntype PercentageFlags uint8\n\nconst (\n\tAllowPercentageBelow0 PercentageFlags = 1 << iota\n\tAllowPercentageAbove100\n\tAllowAnyPercentage = AllowPercentageBelow0 | AllowPercentageAbove100\n)\n\nfunc (t Token) NumberOrFractionForPercentage(percentReferenceRange float64, flags PercentageFlags) (float64, bool) {\n\tswitch t.Kind {\n\tcase css_lexer.TNumber:\n\t\tif f, err := strconv.ParseFloat(t.Text, 64); err == nil {\n\t\t\treturn f, true\n\t\t}\n\n\tcase css_lexer.TPercentage:\n\t\tif f, err := strconv.ParseFloat(t.PercentageValue(), 64); err == nil {\n\t\t\tif (flags&AllowPercentageBelow0) == 0 && f < 0 {\n\t\t\t\treturn 0, true\n\t\t\t}\n\t\t\tif (flags&AllowPercentageAbove100) == 0 && f > 100 {\n\t\t\t\treturn percentReferenceRange, true\n\t\t\t}\n\t\t\treturn f / 100 * percentReferenceRange, true\n\t\t}\n\t}\n\n\treturn 0, false\n}\n\nfunc (t Token) ClampedFractionForPercentage() (float64, bool) {\n\tif t.Kind == css_lexer.TPercentage {\n\t\tif f, err := strconv.ParseFloat(t.PercentageValue(), 64); err == nil {\n\t\t\tif f < 0 {\n\t\t\t\treturn 0, true\n\t\t\t}\n\t\t\tif f > 100 {\n\t\t\t\treturn 1, true\n\t\t\t}\n\t\t\treturn f / 100, true\n\t\t}\n\t}\n\n\treturn 0, false\n}\n\n// https://drafts.csswg.org/css-values-3/#lengths\n// For zero lengths the unit identifier is optional\n// (i.e. can be syntactically represented as the <number> 0).\nfunc (t *Token) TurnLengthIntoNumberIfZero() bool {\n\tif t.Kind == css_lexer.TDimension && t.DimensionValue() == \"0\" {\n\t\tt.Kind = css_lexer.TNumber\n\t\tt.Text = \"0\"\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (t *Token) TurnLengthOrPercentageIntoNumberIfZero() bool {\n\tif t.Kind == css_lexer.TPercentage && t.PercentageValue() == \"0\" {\n\t\tt.Kind = css_lexer.TNumber\n\t\tt.Text = \"0\"\n\t\treturn true\n\t}\n\treturn t.TurnLengthIntoNumberIfZero()\n}\n\nfunc (t Token) PercentageValue() string {\n\treturn t.Text[:len(t.Text)-1]\n}\n\nfunc (t Token) DimensionValue() string {\n\treturn t.Text[:t.UnitOffset]\n}\n\nfunc (t Token) DimensionUnit() string {\n\treturn t.Text[t.UnitOffset:]\n}\n\nfunc (t Token) DimensionUnitIsSafeLength() bool {\n\tswitch strings.ToLower(t.DimensionUnit()) {\n\t// These units can be reasonably expected to be supported everywhere.\n\t// Information used: https://developer.mozilla.org/en-US/docs/Web/CSS/length\n\tcase \"cm\", \"em\", \"in\", \"mm\", \"pc\", \"pt\", \"px\":\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (t Token) IsZero() bool {\n\treturn t.Kind == css_lexer.TNumber && t.Text == \"0\"\n}\n\nfunc (t Token) IsOne() bool {\n\treturn t.Kind == css_lexer.TNumber && t.Text == \"1\"\n}\n\nfunc (t Token) IsAngle() bool {\n\tif t.Kind == css_lexer.TDimension {\n\t\tunit := strings.ToLower(t.DimensionUnit())\n\t\treturn unit == \"deg\" || unit == \"grad\" || unit == \"rad\" || unit == \"turn\"\n\t}\n\treturn false\n}\n\nfunc CloneTokensWithoutImportRecords(tokensIn []Token) (tokensOut []Token) {\n\tfor _, t := range tokensIn {\n\t\tif t.Children != nil {\n\t\t\tchildren := CloneTokensWithoutImportRecords(*t.Children)\n\t\t\tt.Children = &children\n\t\t}\n\t\ttokensOut = append(tokensOut, t)\n\t}\n\treturn\n}\n\nfunc CloneTokensWithImportRecords(\n\ttokensIn []Token, importRecordsIn []ast.ImportRecord,\n\ttokensOut []Token, importRecordsOut []ast.ImportRecord,\n) ([]Token, []ast.ImportRecord) {\n\t// Preallocate the output array if we can\n\tif tokensOut == nil {\n\t\ttokensOut = make([]Token, 0, len(tokensIn))\n\t}\n\n\tfor _, t := range tokensIn {\n\t\t// Clear the source mapping if this token is being used in another file\n\t\tt.Loc.Start = 0\n\n\t\t// If this is a URL token, also clone the import record\n\t\tif t.Kind == css_lexer.TURL {\n\t\t\timportRecordIndex := uint32(len(importRecordsOut))\n\t\t\timportRecordsOut = append(importRecordsOut, importRecordsIn[t.PayloadIndex])\n\t\t\tt.PayloadIndex = importRecordIndex\n\t\t}\n\n\t\t// Also search for URL tokens in this token's children\n\t\tif t.Children != nil {\n\t\t\tvar children []Token\n\t\t\tchildren, importRecordsOut = CloneTokensWithImportRecords(*t.Children, importRecordsIn, children, importRecordsOut)\n\t\t\tt.Children = &children\n\t\t}\n\n\t\ttokensOut = append(tokensOut, t)\n\t}\n\n\treturn tokensOut, importRecordsOut\n}\n\nfunc CloneMediaQueriesWithImportRecords(\n\tqueriesIn []MediaQuery, importRecordsIn []ast.ImportRecord,\n\tqueriesOut []MediaQuery, importRecordsOut []ast.ImportRecord,\n) ([]MediaQuery, []ast.ImportRecord) {\n\t// Preallocate the output array if we can\n\tif queriesOut == nil {\n\t\tqueriesOut = make([]MediaQuery, 0, len(queriesIn))\n\t}\n\n\t// Recursively clone each query\n\tfor _, query := range queriesIn {\n\t\tquery.Data, importRecordsOut = query.Data.CloneWithImportRecords(importRecordsIn, importRecordsOut)\n\t\tqueriesOut = append(queriesOut, query)\n\t}\n\n\treturn queriesOut, importRecordsOut\n}\n\ntype Rule struct {\n\tData R\n\tLoc  logger.Loc\n}\n\ntype R interface {\n\tEqual(rule R, check *CrossFileEqualityCheck) bool\n\tHash() (uint32, bool)\n}\n\nfunc RulesEqual(a []Rule, b []Rule, check *CrossFileEqualityCheck) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor i, ai := range a {\n\t\tif !ai.Data.Equal(b[i].Data, check) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc HashRules(hash uint32, rules []Rule) uint32 {\n\thash = helpers.HashCombine(hash, uint32(len(rules)))\n\tfor _, child := range rules {\n\t\tif childHash, ok := child.Data.Hash(); ok {\n\t\t\thash = helpers.HashCombine(hash, childHash)\n\t\t} else {\n\t\t\thash = helpers.HashCombine(hash, 0)\n\t\t}\n\t}\n\treturn hash\n}\n\ntype RAtCharset struct {\n\tEncoding string\n}\n\nfunc (a *RAtCharset) Equal(rule R, check *CrossFileEqualityCheck) bool {\n\tb, ok := rule.(*RAtCharset)\n\treturn ok && a.Encoding == b.Encoding\n}\n\nfunc (r *RAtCharset) Hash() (uint32, bool) {\n\thash := uint32(1)\n\thash = helpers.HashCombineString(hash, r.Encoding)\n\treturn hash, true\n}\n\ntype ImportConditions struct {\n\t// The syntax for \"@import\" has been extended with optional conditions that\n\t// behave as if the imported file was wrapped in a \"@layer\", \"@supports\",\n\t// and/or \"@media\" rule. The possible syntax combinations are as follows:\n\t//\n\t//   @import url(...);\n\t//   @import url(...) layer;\n\t//   @import url(...) layer(layer-name);\n\t//   @import url(...) layer(layer-name) supports(supports-condition);\n\t//   @import url(...) layer(layer-name) supports(supports-condition) list-of-media-queries;\n\t//   @import url(...) layer(layer-name) list-of-media-queries;\n\t//   @import url(...) supports(supports-condition);\n\t//   @import url(...) supports(supports-condition) list-of-media-queries;\n\t//   @import url(...) list-of-media-queries;\n\t//\n\t// From: https://developer.mozilla.org/en-US/docs/Web/CSS/@import#syntax\n\tQueries []MediaQuery\n\n\t// These two fields will only ever have zero or one tokens. However, they are\n\t// implemented as arrays for convenience because most of esbuild's helper\n\t// functions that operate on tokens take arrays instead of individual tokens.\n\tLayers   []Token\n\tSupports []Token\n}\n\nfunc (c *ImportConditions) CloneWithImportRecords(importRecordsIn []ast.ImportRecord, importRecordsOut []ast.ImportRecord) (ImportConditions, []ast.ImportRecord) {\n\tresult := ImportConditions{}\n\tresult.Layers, importRecordsOut = CloneTokensWithImportRecords(c.Layers, importRecordsIn, nil, importRecordsOut)\n\tresult.Supports, importRecordsOut = CloneTokensWithImportRecords(c.Supports, importRecordsIn, nil, importRecordsOut)\n\tresult.Queries, importRecordsOut = CloneMediaQueriesWithImportRecords(c.Queries, importRecordsIn, nil, importRecordsOut)\n\treturn result, importRecordsOut\n}\n\ntype RAtImport struct {\n\tImportConditions  *ImportConditions\n\tImportRecordIndex uint32\n}\n\nfunc (*RAtImport) Equal(rule R, check *CrossFileEqualityCheck) bool {\n\treturn false\n}\n\nfunc (r *RAtImport) Hash() (uint32, bool) {\n\treturn 0, false\n}\n\ntype RAtKeyframes struct {\n\tAtToken       string\n\tName          ast.LocRef\n\tBlocks        []KeyframeBlock\n\tCloseBraceLoc logger.Loc\n}\n\ntype KeyframeBlock struct {\n\tSelectors     []string\n\tRules         []Rule\n\tLoc           logger.Loc\n\tCloseBraceLoc logger.Loc\n}\n\nfunc (a *RAtKeyframes) Equal(rule R, check *CrossFileEqualityCheck) bool {\n\tif b, ok := rule.(*RAtKeyframes); ok && strings.EqualFold(a.AtToken, b.AtToken) && check.RefsAreEquivalent(a.Name.Ref, b.Name.Ref) && len(a.Blocks) == len(b.Blocks) {\n\t\tfor i, ai := range a.Blocks {\n\t\t\tbi := b.Blocks[i]\n\t\t\tif len(ai.Selectors) != len(bi.Selectors) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfor j, aj := range ai.Selectors {\n\t\t\t\tif aj != bi.Selectors[j] {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !RulesEqual(ai.Rules, bi.Rules, check) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (r *RAtKeyframes) Hash() (uint32, bool) {\n\thash := uint32(2)\n\thash = helpers.HashCombineString(hash, r.AtToken)\n\thash = helpers.HashCombine(hash, uint32(len(r.Blocks)))\n\tfor _, block := range r.Blocks {\n\t\thash = helpers.HashCombine(hash, uint32(len(block.Selectors)))\n\t\tfor _, sel := range block.Selectors {\n\t\t\thash = helpers.HashCombineString(hash, sel)\n\t\t}\n\t\thash = HashRules(hash, block.Rules)\n\t}\n\treturn hash, true\n}\n\ntype RKnownAt struct {\n\tAtToken       string\n\tPrelude       []Token\n\tRules         []Rule\n\tCloseBraceLoc logger.Loc\n}\n\nfunc (a *RKnownAt) Equal(rule R, check *CrossFileEqualityCheck) bool {\n\tb, ok := rule.(*RKnownAt)\n\treturn ok && strings.EqualFold(a.AtToken, b.AtToken) && TokensEqual(a.Prelude, b.Prelude, check) && RulesEqual(a.Rules, b.Rules, check)\n}\n\nfunc (r *RKnownAt) Hash() (uint32, bool) {\n\thash := uint32(3)\n\thash = helpers.HashCombineString(hash, r.AtToken)\n\thash = HashTokens(hash, r.Prelude)\n\thash = HashRules(hash, r.Rules)\n\treturn hash, true\n}\n\ntype RUnknownAt struct {\n\tAtToken string\n\tPrelude []Token\n\tBlock   []Token\n}\n\nfunc (a *RUnknownAt) Equal(rule R, check *CrossFileEqualityCheck) bool {\n\tb, ok := rule.(*RUnknownAt)\n\treturn ok && strings.EqualFold(a.AtToken, b.AtToken) && TokensEqual(a.Prelude, b.Prelude, check) && TokensEqual(a.Block, b.Block, check)\n}\n\nfunc (r *RUnknownAt) Hash() (uint32, bool) {\n\thash := uint32(4)\n\thash = helpers.HashCombineString(hash, r.AtToken)\n\thash = HashTokens(hash, r.Prelude)\n\thash = HashTokens(hash, r.Block)\n\treturn hash, true\n}\n\ntype RSelector struct {\n\tSelectors     []ComplexSelector\n\tRules         []Rule\n\tCloseBraceLoc logger.Loc\n}\n\nfunc (a *RSelector) Equal(rule R, check *CrossFileEqualityCheck) bool {\n\tb, ok := rule.(*RSelector)\n\treturn ok && ComplexSelectorsEqual(a.Selectors, b.Selectors, check) && RulesEqual(a.Rules, b.Rules, check)\n}\n\nfunc (r *RSelector) Hash() (uint32, bool) {\n\thash := uint32(5)\n\thash = helpers.HashCombine(hash, uint32(len(r.Selectors)))\n\thash = HashComplexSelectors(hash, r.Selectors)\n\thash = HashRules(hash, r.Rules)\n\treturn hash, true\n}\n\ntype RQualified struct {\n\tPrelude       []Token\n\tRules         []Rule\n\tCloseBraceLoc logger.Loc\n}\n\nfunc (a *RQualified) Equal(rule R, check *CrossFileEqualityCheck) bool {\n\tb, ok := rule.(*RQualified)\n\treturn ok && TokensEqual(a.Prelude, b.Prelude, check) && RulesEqual(a.Rules, b.Rules, check)\n}\n\nfunc (r *RQualified) Hash() (uint32, bool) {\n\thash := uint32(6)\n\thash = HashTokens(hash, r.Prelude)\n\thash = HashRules(hash, r.Rules)\n\treturn hash, true\n}\n\ntype RDeclaration struct {\n\tKeyText   string\n\tValue     []Token\n\tKeyRange  logger.Range\n\tKey       D // Compare using this instead of \"Key\" for speed\n\tImportant bool\n}\n\nfunc (a *RDeclaration) Equal(rule R, check *CrossFileEqualityCheck) bool {\n\tb, ok := rule.(*RDeclaration)\n\treturn ok && a.KeyText == b.KeyText && TokensEqual(a.Value, b.Value, check) && a.Important == b.Important\n}\n\nfunc (r *RDeclaration) Hash() (uint32, bool) {\n\tvar hash uint32\n\tif r.Key == DUnknown {\n\t\tif r.Important {\n\t\t\thash = uint32(7)\n\t\t} else {\n\t\t\thash = uint32(8)\n\t\t}\n\t\thash = helpers.HashCombineString(hash, r.KeyText)\n\t} else {\n\t\tif r.Important {\n\t\t\thash = uint32(9)\n\t\t} else {\n\t\t\thash = uint32(10)\n\t\t}\n\t\thash = helpers.HashCombine(hash, uint32(r.Key))\n\t}\n\thash = HashTokens(hash, r.Value)\n\treturn hash, true\n}\n\ntype RBadDeclaration struct {\n\tTokens []Token\n}\n\nfunc (a *RBadDeclaration) Equal(rule R, check *CrossFileEqualityCheck) bool {\n\tb, ok := rule.(*RBadDeclaration)\n\treturn ok && TokensEqual(a.Tokens, b.Tokens, check)\n}\n\nfunc (r *RBadDeclaration) Hash() (uint32, bool) {\n\thash := uint32(7)\n\thash = HashTokens(hash, r.Tokens)\n\treturn hash, true\n}\n\ntype RComment struct {\n\tText string\n}\n\nfunc (a *RComment) Equal(rule R, check *CrossFileEqualityCheck) bool {\n\tb, ok := rule.(*RComment)\n\treturn ok && a.Text == b.Text\n}\n\nfunc (r *RComment) Hash() (uint32, bool) {\n\thash := uint32(8)\n\thash = helpers.HashCombineString(hash, r.Text)\n\treturn hash, true\n}\n\ntype RAtLayer struct {\n\tNames         [][]string\n\tRules         []Rule\n\tCloseBraceLoc logger.Loc\n}\n\nfunc (a *RAtLayer) Equal(rule R, check *CrossFileEqualityCheck) bool {\n\tif b, ok := rule.(*RAtLayer); ok && len(a.Names) == len(b.Names) && len(a.Rules) == len(b.Rules) {\n\t\tfor i, ai := range a.Names {\n\t\t\tbi := b.Names[i]\n\t\t\tif len(ai) != len(bi) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfor j, aj := range ai {\n\t\t\t\tif aj != bi[j] {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif !RulesEqual(a.Rules, b.Rules, check) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (r *RAtLayer) Hash() (uint32, bool) {\n\thash := uint32(9)\n\thash = helpers.HashCombine(hash, uint32(len(r.Names)))\n\tfor _, parts := range r.Names {\n\t\thash = helpers.HashCombine(hash, uint32(len(parts)))\n\t\tfor _, part := range parts {\n\t\t\thash = helpers.HashCombineString(hash, part)\n\t\t}\n\t}\n\thash = HashRules(hash, r.Rules)\n\treturn hash, true\n}\n\ntype RAtMedia struct {\n\tQueries       []MediaQuery\n\tRules         []Rule\n\tCloseBraceLoc logger.Loc\n}\n\nfunc (a *RAtMedia) Equal(rule R, check *CrossFileEqualityCheck) bool {\n\tb, ok := rule.(*RAtMedia)\n\treturn ok && MediaQueriesEqual(a.Queries, b.Queries, check) && RulesEqual(a.Rules, b.Rules, check)\n}\n\nfunc (r *RAtMedia) Hash() (uint32, bool) {\n\thash := uint32(10)\n\thash = HashMediaQueries(hash, r.Queries)\n\thash = HashRules(hash, r.Rules)\n\treturn hash, true\n}\n\ntype MediaQuery struct {\n\tLoc  logger.Loc\n\tData MQ\n}\n\ntype MQ interface {\n\tEqual(query MQ, check *CrossFileEqualityCheck) bool\n\tEqualIgnoringWhitespace(query MQ) bool\n\tHash() uint32\n\tCloneWithImportRecords(importRecordsIn []ast.ImportRecord, importRecordsOut []ast.ImportRecord) (MQ, []ast.ImportRecord)\n}\n\nfunc MediaQueriesEqual(a []MediaQuery, b []MediaQuery, check *CrossFileEqualityCheck) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor i, ai := range a {\n\t\tif !ai.Data.Equal(b[i].Data, check) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc MediaQueriesEqualIgnoringWhitespace(a []MediaQuery, b []MediaQuery) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor i, ai := range a {\n\t\tif !ai.Data.EqualIgnoringWhitespace(b[i].Data) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc HashMediaQueries(hash uint32, queries []MediaQuery) uint32 {\n\thash = helpers.HashCombine(hash, uint32(len(queries)))\n\tfor _, q := range queries {\n\t\thash = helpers.HashCombine(hash, q.Data.Hash())\n\t}\n\treturn hash\n}\n\ntype MQTypeOp uint8\n\nconst (\n\tMQTypeOpNone MQTypeOp = iota\n\tMQTypeOpNot\n\tMQTypeOpOnly\n)\n\ntype MQType struct {\n\tOp        MQTypeOp\n\tType      string\n\tAndOrNull MediaQuery\n}\n\nfunc (q *MQType) Equal(query MQ, check *CrossFileEqualityCheck) bool {\n\tif p, ok := query.(*MQType); ok && q.Op == p.Op && q.Type == p.Type {\n\t\treturn (q.AndOrNull.Data == nil && p.AndOrNull.Data == nil) ||\n\t\t\t(q.AndOrNull.Data != nil && p.AndOrNull.Data != nil && q.AndOrNull.Data.Equal(p.AndOrNull.Data, check))\n\t}\n\treturn false\n}\n\nfunc (q *MQType) EqualIgnoringWhitespace(query MQ) bool {\n\tif p, ok := query.(*MQType); ok && q.Op == p.Op && q.Type == p.Type {\n\t\treturn (q.AndOrNull.Data == nil && p.AndOrNull.Data == nil) ||\n\t\t\t(q.AndOrNull.Data != nil && p.AndOrNull.Data != nil && q.AndOrNull.Data.EqualIgnoringWhitespace(p.AndOrNull.Data))\n\t}\n\treturn false\n}\n\nfunc (q *MQType) Hash() uint32 {\n\thash := uint32(0)\n\thash = helpers.HashCombine(hash, uint32(q.Op))\n\thash = helpers.HashCombineString(hash, q.Type)\n\tif q.AndOrNull.Data != nil {\n\t\thash = helpers.HashCombine(hash, q.AndOrNull.Data.Hash())\n\t}\n\treturn hash\n}\n\nfunc (q *MQType) CloneWithImportRecords(importRecordsIn []ast.ImportRecord, importRecordsOut []ast.ImportRecord) (MQ, []ast.ImportRecord) {\n\tvar andOrNull MQ\n\tif q.AndOrNull.Data != nil {\n\t\tandOrNull, importRecordsOut = q.AndOrNull.Data.CloneWithImportRecords(importRecordsIn, importRecordsOut)\n\t}\n\treturn &MQType{Op: q.Op, Type: q.Type, AndOrNull: MediaQuery{Data: andOrNull}}, importRecordsOut\n}\n\ntype MQNot struct {\n\tInner MediaQuery\n}\n\nfunc (q *MQNot) Equal(query MQ, check *CrossFileEqualityCheck) bool {\n\tp, ok := query.(*MQNot)\n\treturn ok && q.Inner.Data.Equal(p.Inner.Data, check)\n}\n\nfunc (q *MQNot) EqualIgnoringWhitespace(query MQ) bool {\n\tp, ok := query.(*MQNot)\n\treturn ok && q.Inner.Data.EqualIgnoringWhitespace(p.Inner.Data)\n}\n\nfunc (q *MQNot) Hash() uint32 {\n\thash := uint32(1)\n\thash = helpers.HashCombine(hash, q.Inner.Data.Hash())\n\treturn hash\n}\n\nfunc (q *MQNot) CloneWithImportRecords(importRecordsIn []ast.ImportRecord, importRecordsOut []ast.ImportRecord) (MQ, []ast.ImportRecord) {\n\tinner, importRecordsOut := q.Inner.Data.CloneWithImportRecords(importRecordsIn, importRecordsOut)\n\treturn &MQNot{Inner: MediaQuery{Data: inner}}, importRecordsOut\n}\n\ntype MQBinaryOp uint8\n\nconst (\n\tMQBinaryOpAnd MQBinaryOp = iota\n\tMQBinaryOpOr\n)\n\ntype MQBinary struct {\n\tOp    MQBinaryOp\n\tTerms []MediaQuery\n}\n\nfunc (q *MQBinary) Equal(query MQ, check *CrossFileEqualityCheck) bool {\n\tp, ok := query.(*MQBinary)\n\treturn ok && q.Op == p.Op && MediaQueriesEqual(q.Terms, p.Terms, check)\n}\n\nfunc (q *MQBinary) EqualIgnoringWhitespace(query MQ) bool {\n\tp, ok := query.(*MQBinary)\n\treturn ok && q.Op == p.Op && MediaQueriesEqualIgnoringWhitespace(q.Terms, p.Terms)\n}\n\nfunc (q *MQBinary) Hash() uint32 {\n\thash := uint32(2)\n\thash = helpers.HashCombine(hash, uint32(q.Op))\n\thash = HashMediaQueries(hash, q.Terms)\n\treturn hash\n}\n\nfunc (q *MQBinary) CloneWithImportRecords(importRecordsIn []ast.ImportRecord, importRecordsOut []ast.ImportRecord) (MQ, []ast.ImportRecord) {\n\tterms := make([]MediaQuery, 0, len(q.Terms))\n\tfor _, term := range q.Terms {\n\t\tvar clone MQ\n\t\tclone, importRecordsOut = term.Data.CloneWithImportRecords(importRecordsIn, importRecordsOut)\n\t\tterms = append(terms, MediaQuery{Data: clone})\n\t}\n\treturn &MQBinary{Op: q.Op, Terms: terms}, importRecordsOut\n}\n\ntype MQArbitraryTokens struct {\n\tTokens []Token\n}\n\nfunc (q *MQArbitraryTokens) Equal(query MQ, check *CrossFileEqualityCheck) bool {\n\tp, ok := query.(*MQArbitraryTokens)\n\treturn ok && TokensEqual(q.Tokens, p.Tokens, check)\n}\n\nfunc (q *MQArbitraryTokens) EqualIgnoringWhitespace(query MQ) bool {\n\tp, ok := query.(*MQArbitraryTokens)\n\treturn ok && TokensEqualIgnoringWhitespace(q.Tokens, p.Tokens)\n}\n\nfunc (q *MQArbitraryTokens) Hash() uint32 {\n\thash := uint32(3)\n\thash = HashTokens(hash, q.Tokens)\n\treturn hash\n}\n\nfunc (q *MQArbitraryTokens) CloneWithImportRecords(importRecordsIn []ast.ImportRecord, importRecordsOut []ast.ImportRecord) (MQ, []ast.ImportRecord) {\n\ttokens, importRecordsOut := CloneTokensWithImportRecords(q.Tokens, importRecordsIn, nil, importRecordsOut)\n\treturn &MQArbitraryTokens{Tokens: tokens}, importRecordsOut\n}\n\ntype MQPlainOrBoolean struct {\n\tName       string\n\tValueOrNil []Token\n}\n\nfunc (q *MQPlainOrBoolean) Equal(query MQ, check *CrossFileEqualityCheck) bool {\n\tp, ok := query.(*MQPlainOrBoolean)\n\treturn ok && q.Name == p.Name && TokensEqual(q.ValueOrNil, p.ValueOrNil, check)\n}\n\nfunc (q *MQPlainOrBoolean) EqualIgnoringWhitespace(query MQ) bool {\n\tp, ok := query.(*MQPlainOrBoolean)\n\treturn ok && q.Name == p.Name && TokensEqualIgnoringWhitespace(q.ValueOrNil, p.ValueOrNil)\n}\n\nfunc (q *MQPlainOrBoolean) Hash() uint32 {\n\thash := uint32(4)\n\thash = helpers.HashCombineString(hash, q.Name)\n\thash = HashTokens(hash, q.ValueOrNil)\n\treturn hash\n}\n\nfunc (q *MQPlainOrBoolean) CloneWithImportRecords(importRecordsIn []ast.ImportRecord, importRecordsOut []ast.ImportRecord) (MQ, []ast.ImportRecord) {\n\tvar valueOrNil []Token\n\tif q.ValueOrNil != nil {\n\t\tvalueOrNil, importRecordsOut = CloneTokensWithImportRecords(q.ValueOrNil, importRecordsIn, nil, importRecordsOut)\n\t}\n\treturn &MQPlainOrBoolean{Name: q.Name, ValueOrNil: valueOrNil}, importRecordsOut\n}\n\ntype MQRange struct {\n\tBefore    []Token\n\tName      string\n\tAfter     []Token\n\tNameLoc   logger.Loc\n\tBeforeCmp MQCmp\n\tAfterCmp  MQCmp\n}\n\nfunc (q *MQRange) Equal(query MQ, check *CrossFileEqualityCheck) bool {\n\tp, ok := query.(*MQRange)\n\treturn ok && q.BeforeCmp == p.BeforeCmp && q.AfterCmp == p.AfterCmp && q.Name == p.Name &&\n\t\tTokensEqual(q.Before, p.Before, check) && TokensEqual(q.After, p.After, check)\n}\n\nfunc (q *MQRange) EqualIgnoringWhitespace(query MQ) bool {\n\tp, ok := query.(*MQRange)\n\treturn ok && q.BeforeCmp == p.BeforeCmp && q.AfterCmp == p.AfterCmp && q.Name == p.Name &&\n\t\tTokensEqualIgnoringWhitespace(q.Before, p.Before) && TokensEqualIgnoringWhitespace(q.After, p.After)\n}\n\nfunc (q *MQRange) Hash() uint32 {\n\thash := uint32(5)\n\thash = HashTokens(hash, q.Before)\n\thash = helpers.HashCombine(hash, uint32(q.BeforeCmp))\n\thash = helpers.HashCombineString(hash, q.Name)\n\thash = helpers.HashCombine(hash, uint32(q.AfterCmp))\n\thash = HashTokens(hash, q.After)\n\treturn hash\n}\n\nfunc (q *MQRange) CloneWithImportRecords(importRecordsIn []ast.ImportRecord, importRecordsOut []ast.ImportRecord) (MQ, []ast.ImportRecord) {\n\tbefore, importRecordsOut := CloneTokensWithImportRecords(q.Before, importRecordsIn, nil, importRecordsOut)\n\tafter, importRecordsOut := CloneTokensWithImportRecords(q.After, importRecordsIn, nil, importRecordsOut)\n\treturn &MQRange{\n\t\tBefore:    before,\n\t\tBeforeCmp: q.BeforeCmp,\n\t\tName:      q.Name,\n\t\tAfterCmp:  q.AfterCmp,\n\t\tAfter:     after,\n\t}, importRecordsOut\n}\n\ntype MQCmp uint8\n\nconst (\n\tMQCmpNone MQCmp = iota\n\tMQCmpEq\n\tMQCmpLt\n\tMQCmpLe\n\tMQCmpGt\n\tMQCmpGe\n)\n\nfunc (cmp MQCmp) String() string {\n\tswitch cmp {\n\tcase MQCmpLt:\n\t\treturn \"<\"\n\tcase MQCmpLe:\n\t\treturn \"<=\"\n\tcase MQCmpGt:\n\t\treturn \">\"\n\tcase MQCmpGe:\n\t\treturn \">=\"\n\t}\n\treturn \"=\"\n}\n\nfunc (cmp MQCmp) Dir() int {\n\tswitch cmp {\n\tcase MQCmpLt, MQCmpLe:\n\t\treturn -1\n\tcase MQCmpGt, MQCmpGe:\n\t\treturn 1\n\t}\n\treturn 0\n}\n\nfunc (cmp MQCmp) Flip() MQCmp {\n\tswitch cmp {\n\tcase MQCmpLt:\n\t\treturn MQCmpGe\n\tcase MQCmpLe:\n\t\treturn MQCmpGt\n\tcase MQCmpGt:\n\t\treturn MQCmpLe\n\tcase MQCmpGe:\n\t\treturn MQCmpLt\n\t}\n\treturn cmp\n}\n\nfunc (cmp MQCmp) Reverse() MQCmp {\n\tswitch cmp {\n\tcase MQCmpLt:\n\t\treturn MQCmpGt\n\tcase MQCmpLe:\n\t\treturn MQCmpGe\n\tcase MQCmpGt:\n\t\treturn MQCmpLt\n\tcase MQCmpGe:\n\t\treturn MQCmpLe\n\t}\n\treturn cmp\n}\n\ntype RAtScope struct {\n\tStart         []ComplexSelector\n\tEnd           []ComplexSelector\n\tRules         []Rule\n\tCloseBraceLoc logger.Loc\n}\n\nfunc (a *RAtScope) Equal(rule R, check *CrossFileEqualityCheck) bool {\n\tb, ok := rule.(*RAtScope)\n\treturn ok && ComplexSelectorsEqual(a.Start, b.Start, check) && ComplexSelectorsEqual(a.End, b.End, check) && RulesEqual(a.Rules, b.Rules, check)\n}\n\nfunc (r *RAtScope) Hash() (uint32, bool) {\n\thash := uint32(11)\n\thash = HashComplexSelectors(hash, r.Start)\n\thash = HashComplexSelectors(hash, r.End)\n\thash = HashRules(hash, r.Rules)\n\treturn hash, true\n}\n\ntype ComplexSelector struct {\n\tSelectors []CompoundSelector\n}\n\nfunc ComplexSelectorsEqual(a []ComplexSelector, b []ComplexSelector, check *CrossFileEqualityCheck) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor i, ai := range a {\n\t\tif !ai.Equal(b[i], check) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc HashComplexSelectors(hash uint32, selectors []ComplexSelector) uint32 {\n\tfor _, complex := range selectors {\n\t\thash = helpers.HashCombine(hash, uint32(len(complex.Selectors)))\n\t\tfor _, sel := range complex.Selectors {\n\t\t\tif sel.TypeSelector != nil {\n\t\t\t\thash = helpers.HashCombineString(hash, sel.TypeSelector.Name.Text)\n\t\t\t} else {\n\t\t\t\thash = helpers.HashCombine(hash, 0)\n\t\t\t}\n\t\t\thash = helpers.HashCombine(hash, uint32(len(sel.SubclassSelectors)))\n\t\t\tfor _, ss := range sel.SubclassSelectors {\n\t\t\t\thash = helpers.HashCombine(hash, ss.Data.Hash())\n\t\t\t}\n\t\t\thash = helpers.HashCombine(hash, uint32(sel.Combinator.Byte))\n\t\t}\n\t}\n\treturn hash\n}\n\nfunc (s ComplexSelector) Clone() ComplexSelector {\n\tclone := ComplexSelector{Selectors: make([]CompoundSelector, len(s.Selectors))}\n\tfor i, sel := range s.Selectors {\n\t\tclone.Selectors[i] = sel.Clone()\n\t}\n\treturn clone\n}\n\nfunc (sel ComplexSelector) ContainsNestingCombinator() bool {\n\tfor _, inner := range sel.Selectors {\n\t\tif len(inner.NestingSelectorLocs) > 0 {\n\t\t\treturn true\n\t\t}\n\t\tfor _, ss := range inner.SubclassSelectors {\n\t\t\tif pseudo, ok := ss.Data.(*SSPseudoClassWithSelectorList); ok {\n\t\t\t\tfor _, nested := range pseudo.Selectors {\n\t\t\t\t\tif nested.ContainsNestingCombinator() {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (sel ComplexSelector) IsRelative() bool {\n\t// https://www.w3.org/TR/css-nesting-1/#syntax\n\t// \"If a selector in the <relative-selector-list> does not start with a\n\t// combinator but does contain the nesting selector, it is interpreted\n\t// as a non-relative selector.\"\n\tif sel.Selectors[0].Combinator.Byte == 0 && sel.ContainsNestingCombinator() {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc tokensContainAmpersandRecursive(tokens []Token) bool {\n\tfor _, t := range tokens {\n\t\tif t.Kind == css_lexer.TDelimAmpersand {\n\t\t\treturn true\n\t\t}\n\t\tif children := t.Children; children != nil && tokensContainAmpersandRecursive(*children) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (sel ComplexSelector) UsesPseudoElement() bool {\n\tfor _, sel := range sel.Selectors {\n\t\tfor _, ss := range sel.SubclassSelectors {\n\t\t\tif class, ok := ss.Data.(*SSPseudoClass); ok {\n\t\t\t\tif class.IsElement {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\n\t\t\t\t// https://www.w3.org/TR/selectors-4/#single-colon-pseudos\n\t\t\t\t// The four Level 2 pseudo-elements (::before, ::after, ::first-line,\n\t\t\t\t// and ::first-letter) may, for legacy reasons, be represented using\n\t\t\t\t// the <pseudo-class-selector> grammar, with only a single \":\"\n\t\t\t\t// character at their start.\n\t\t\t\tswitch class.Name {\n\t\t\t\tcase \"before\", \"after\", \"first-line\", \"first-letter\":\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (a ComplexSelector) Equal(b ComplexSelector, check *CrossFileEqualityCheck) bool {\n\tif len(a.Selectors) != len(b.Selectors) {\n\t\treturn false\n\t}\n\n\tfor i, ai := range a.Selectors {\n\t\tbi := b.Selectors[i]\n\t\tif len(ai.NestingSelectorLocs) != len(bi.NestingSelectorLocs) || ai.Combinator.Byte != bi.Combinator.Byte {\n\t\t\treturn false\n\t\t}\n\n\t\tif ats, bts := ai.TypeSelector, bi.TypeSelector; (ats == nil) != (bts == nil) {\n\t\t\treturn false\n\t\t} else if ats != nil && bts != nil && !ats.Equal(*bts) {\n\t\t\treturn false\n\t\t}\n\n\t\tif len(ai.SubclassSelectors) != len(bi.SubclassSelectors) {\n\t\t\treturn false\n\t\t}\n\t\tfor j, aj := range ai.SubclassSelectors {\n\t\t\tif !aj.Data.Equal(bi.SubclassSelectors[j].Data, check) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true\n}\n\ntype Combinator struct {\n\tLoc  logger.Loc\n\tByte uint8 // Optional, may be 0 for no combinator\n}\n\ntype CompoundSelector struct {\n\tTypeSelector        *NamespacedName\n\tSubclassSelectors   []SubclassSelector\n\tNestingSelectorLocs []logger.Loc // \"&\" vs. \"&&\" is different specificity\n\tCombinator          Combinator   // Optional, may be 0\n\n\t// If this is true, this is a \"&\" that was generated by a bare \":local\" or \":global\"\n\tWasEmptyFromLocalOrGlobal bool\n}\n\nfunc (sel CompoundSelector) IsSingleAmpersand() bool {\n\treturn len(sel.NestingSelectorLocs) == 1 && sel.Combinator.Byte == 0 && sel.TypeSelector == nil && len(sel.SubclassSelectors) == 0\n}\n\nfunc (sel CompoundSelector) IsInvalidBecauseEmpty() bool {\n\treturn len(sel.NestingSelectorLocs) == 0 && sel.TypeSelector == nil && len(sel.SubclassSelectors) == 0\n}\n\nfunc (sel CompoundSelector) Range() (r logger.Range) {\n\tif sel.Combinator.Byte != 0 {\n\t\tr = logger.Range{Loc: sel.Combinator.Loc, Len: 1}\n\t}\n\tif sel.TypeSelector != nil {\n\t\tr.ExpandBy(sel.TypeSelector.Range())\n\t}\n\tfor _, loc := range sel.NestingSelectorLocs {\n\t\tr.ExpandBy(logger.Range{Loc: loc, Len: 1})\n\t}\n\tif len(sel.SubclassSelectors) > 0 {\n\t\tfor _, ss := range sel.SubclassSelectors {\n\t\t\tr.ExpandBy(ss.Range)\n\t\t}\n\t}\n\treturn\n}\n\nfunc (sel CompoundSelector) Clone() CompoundSelector {\n\tclone := sel\n\n\tif sel.TypeSelector != nil {\n\t\tt := sel.TypeSelector.Clone()\n\t\tclone.TypeSelector = &t\n\t}\n\n\tif sel.SubclassSelectors != nil {\n\t\tselectors := make([]SubclassSelector, len(sel.SubclassSelectors))\n\t\tfor i, ss := range sel.SubclassSelectors {\n\t\t\tss.Data = ss.Data.Clone()\n\t\t\tselectors[i] = ss\n\t\t}\n\t\tclone.SubclassSelectors = selectors\n\t}\n\n\treturn clone\n}\n\ntype NameToken struct {\n\tText  string\n\tRange logger.Range\n\tKind  css_lexer.T\n}\n\nfunc (a NameToken) Equal(b NameToken) bool {\n\treturn a.Text == b.Text && a.Kind == b.Kind\n}\n\ntype NamespacedName struct {\n\t// If present, this is an identifier or \"*\" and is followed by a \"|\" character\n\tNamespacePrefix *NameToken\n\n\t// This is an identifier or \"*\"\n\tName NameToken\n}\n\nfunc (n NamespacedName) Range() logger.Range {\n\tif n.NamespacePrefix != nil {\n\t\tloc := n.NamespacePrefix.Range.Loc\n\t\treturn logger.Range{Loc: loc, Len: n.Name.Range.End() - loc.Start}\n\t}\n\treturn n.Name.Range\n}\n\nfunc (n NamespacedName) Clone() NamespacedName {\n\tclone := n\n\tif n.NamespacePrefix != nil {\n\t\tprefix := *n.NamespacePrefix\n\t\tclone.NamespacePrefix = &prefix\n\t}\n\treturn clone\n}\n\nfunc (a NamespacedName) Equal(b NamespacedName) bool {\n\treturn a.Name.Equal(b.Name) && (a.NamespacePrefix == nil) == (b.NamespacePrefix == nil) &&\n\t\t(a.NamespacePrefix == nil || b.NamespacePrefix == nil || a.NamespacePrefix.Equal(b.Name))\n}\n\ntype SubclassSelector struct {\n\tData  SS\n\tRange logger.Range\n}\n\ntype SS interface {\n\tEqual(ss SS, check *CrossFileEqualityCheck) bool\n\tHash() uint32\n\tClone() SS\n}\n\ntype SSHash struct {\n\tName ast.LocRef\n}\n\nfunc (a *SSHash) Equal(ss SS, check *CrossFileEqualityCheck) bool {\n\tb, ok := ss.(*SSHash)\n\treturn ok && check.RefsAreEquivalent(a.Name.Ref, b.Name.Ref)\n}\n\nfunc (ss *SSHash) Hash() uint32 {\n\thash := uint32(1)\n\treturn hash\n}\n\nfunc (ss *SSHash) Clone() SS {\n\tclone := *ss\n\treturn &clone\n}\n\ntype SSClass struct {\n\tName ast.LocRef\n}\n\nfunc (a *SSClass) Equal(ss SS, check *CrossFileEqualityCheck) bool {\n\tb, ok := ss.(*SSClass)\n\treturn ok && check.RefsAreEquivalent(a.Name.Ref, b.Name.Ref)\n}\n\nfunc (ss *SSClass) Hash() uint32 {\n\thash := uint32(2)\n\treturn hash\n}\n\nfunc (ss *SSClass) Clone() SS {\n\tclone := *ss\n\treturn &clone\n}\n\ntype SSAttribute struct {\n\tMatcherOp       string // Either \"\" or one of: \"=\" \"~=\" \"|=\" \"^=\" \"$=\" \"*=\"\n\tMatcherValue    string\n\tNamespacedName  NamespacedName\n\tMatcherModifier byte // Either 0 or one of: 'i' 'I' 's' 'S'\n}\n\nfunc (a *SSAttribute) Equal(ss SS, check *CrossFileEqualityCheck) bool {\n\tb, ok := ss.(*SSAttribute)\n\treturn ok && a.NamespacedName.Equal(b.NamespacedName) && a.MatcherOp == b.MatcherOp &&\n\t\ta.MatcherValue == b.MatcherValue && a.MatcherModifier == b.MatcherModifier\n}\n\nfunc (ss *SSAttribute) Hash() uint32 {\n\thash := uint32(3)\n\thash = helpers.HashCombineString(hash, ss.NamespacedName.Name.Text)\n\thash = helpers.HashCombineString(hash, ss.MatcherOp)\n\thash = helpers.HashCombineString(hash, ss.MatcherValue)\n\treturn hash\n}\n\nfunc (ss *SSAttribute) Clone() SS {\n\tclone := *ss\n\tclone.NamespacedName = ss.NamespacedName.Clone()\n\treturn &clone\n}\n\ntype SSPseudoClass struct {\n\tName      string\n\tArgs      []Token\n\tIsElement bool // If true, this is prefixed by \"::\" instead of \":\"\n}\n\nfunc (a *SSPseudoClass) Equal(ss SS, check *CrossFileEqualityCheck) bool {\n\tb, ok := ss.(*SSPseudoClass)\n\treturn ok && a.Name == b.Name && TokensEqual(a.Args, b.Args, check) && a.IsElement == b.IsElement\n}\n\nfunc (ss *SSPseudoClass) Hash() uint32 {\n\thash := uint32(4)\n\thash = helpers.HashCombineString(hash, ss.Name)\n\thash = HashTokens(hash, ss.Args)\n\treturn hash\n}\n\nfunc (ss *SSPseudoClass) Clone() SS {\n\tclone := *ss\n\tif ss.Args != nil {\n\t\tss.Args = CloneTokensWithoutImportRecords(ss.Args)\n\t}\n\treturn &clone\n}\n\ntype PseudoClassKind uint8\n\nconst (\n\tPseudoClassGlobal PseudoClassKind = iota\n\tPseudoClassHas\n\tPseudoClassIs\n\tPseudoClassLocal\n\tPseudoClassNot\n\tPseudoClassNthChild\n\tPseudoClassNthLastChild\n\tPseudoClassNthLastOfType\n\tPseudoClassNthOfType\n\tPseudoClassWhere\n)\n\nfunc (kind PseudoClassKind) HasNthIndex() bool {\n\treturn kind >= PseudoClassNthChild && kind <= PseudoClassNthOfType\n}\n\nfunc (kind PseudoClassKind) String() string {\n\tswitch kind {\n\tcase PseudoClassGlobal:\n\t\treturn \"global\"\n\tcase PseudoClassHas:\n\t\treturn \"has\"\n\tcase PseudoClassIs:\n\t\treturn \"is\"\n\tcase PseudoClassLocal:\n\t\treturn \"local\"\n\tcase PseudoClassNot:\n\t\treturn \"not\"\n\tcase PseudoClassNthChild:\n\t\treturn \"nth-child\"\n\tcase PseudoClassNthLastChild:\n\t\treturn \"nth-last-child\"\n\tcase PseudoClassNthLastOfType:\n\t\treturn \"nth-last-of-type\"\n\tcase PseudoClassNthOfType:\n\t\treturn \"nth-of-type\"\n\tcase PseudoClassWhere:\n\t\treturn \"where\"\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\n// This is the \"An+B\" syntax\ntype NthIndex struct {\n\tA string\n\tB string // May be \"even\" or \"odd\"\n}\n\nfunc (index *NthIndex) Minify() {\n\t// \"even\" => \"2n\"\n\tif index.B == \"even\" {\n\t\tindex.A = \"2\"\n\t\tindex.B = \"\"\n\t\treturn\n\t}\n\n\t// \"2n+1\" => \"odd\"\n\tif index.A == \"2\" && index.B == \"1\" {\n\t\tindex.A = \"\"\n\t\tindex.B = \"odd\"\n\t\treturn\n\t}\n\n\t// \"0n+1\" => \"1\"\n\tif index.A == \"0\" {\n\t\tindex.A = \"\"\n\t\tif index.B == \"\" {\n\t\t\t// \"0n\" => \"0\"\n\t\t\tindex.B = \"0\"\n\t\t}\n\t\treturn\n\t}\n\n\t// \"1n+0\" => \"1n\"\n\tif index.B == \"0\" && index.A != \"\" {\n\t\tindex.B = \"\"\n\t}\n}\n\n// See https://drafts.csswg.org/selectors/#grouping\ntype SSPseudoClassWithSelectorList struct {\n\tSelectors []ComplexSelector\n\tIndex     NthIndex\n\tKind      PseudoClassKind\n}\n\nfunc (a *SSPseudoClassWithSelectorList) Equal(ss SS, check *CrossFileEqualityCheck) bool {\n\tb, ok := ss.(*SSPseudoClassWithSelectorList)\n\treturn ok && a.Kind == b.Kind && a.Index == b.Index && ComplexSelectorsEqual(a.Selectors, b.Selectors, check)\n}\n\nfunc (ss *SSPseudoClassWithSelectorList) Hash() uint32 {\n\thash := uint32(5)\n\thash = helpers.HashCombine(hash, uint32(ss.Kind))\n\thash = helpers.HashCombineString(hash, ss.Index.A)\n\thash = helpers.HashCombineString(hash, ss.Index.B)\n\thash = HashComplexSelectors(hash, ss.Selectors)\n\treturn hash\n}\n\nfunc (ss *SSPseudoClassWithSelectorList) Clone() SS {\n\tclone := *ss\n\tclone.Selectors = make([]ComplexSelector, len(ss.Selectors))\n\tfor i, sel := range ss.Selectors {\n\t\tclone.Selectors[i] = sel.Clone()\n\t}\n\treturn &clone\n}\n"
  },
  {
    "path": "internal/css_ast/css_decl_table.go",
    "content": "package css_ast\n\nimport (\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/evanw/esbuild/internal/helpers\"\n)\n\ntype D uint16\n\nconst (\n\tDUnknown D = iota\n\tDAlignContent\n\tDAlignItems\n\tDAlignSelf\n\tDAlignmentBaseline\n\tDAll\n\tDAnimation\n\tDAnimationDelay\n\tDAnimationDirection\n\tDAnimationDuration\n\tDAnimationFillMode\n\tDAnimationIterationCount\n\tDAnimationName\n\tDAnimationPlayState\n\tDAnimationTimingFunction\n\tDAppearance\n\tDBackdropFilter\n\tDBackfaceVisibility\n\tDBackground\n\tDBackgroundAttachment\n\tDBackgroundClip\n\tDBackgroundColor\n\tDBackgroundImage\n\tDBackgroundOrigin\n\tDBackgroundPosition\n\tDBackgroundPositionX\n\tDBackgroundPositionY\n\tDBackgroundRepeat\n\tDBackgroundSize\n\tDBaselineShift\n\tDBlockSize\n\tDBorder\n\tDBorderBlockEnd\n\tDBorderBlockEndColor\n\tDBorderBlockEndStyle\n\tDBorderBlockEndWidth\n\tDBorderBlockStart\n\tDBorderBlockStartColor\n\tDBorderBlockStartStyle\n\tDBorderBlockStartWidth\n\tDBorderBottom\n\tDBorderBottomColor\n\tDBorderBottomLeftRadius\n\tDBorderBottomRightRadius\n\tDBorderBottomStyle\n\tDBorderBottomWidth\n\tDBorderCollapse\n\tDBorderColor\n\tDBorderImage\n\tDBorderImageOutset\n\tDBorderImageRepeat\n\tDBorderImageSlice\n\tDBorderImageSource\n\tDBorderImageWidth\n\tDBorderInlineEnd\n\tDBorderInlineEndColor\n\tDBorderInlineEndStyle\n\tDBorderInlineEndWidth\n\tDBorderInlineStart\n\tDBorderInlineStartColor\n\tDBorderInlineStartStyle\n\tDBorderInlineStartWidth\n\tDBorderLeft\n\tDBorderLeftColor\n\tDBorderLeftStyle\n\tDBorderLeftWidth\n\tDBorderRadius\n\tDBorderRight\n\tDBorderRightColor\n\tDBorderRightStyle\n\tDBorderRightWidth\n\tDBorderSpacing\n\tDBorderStyle\n\tDBorderTop\n\tDBorderTopColor\n\tDBorderTopLeftRadius\n\tDBorderTopRightRadius\n\tDBorderTopStyle\n\tDBorderTopWidth\n\tDBorderWidth\n\tDBottom\n\tDBoxDecorationBreak\n\tDBoxShadow\n\tDBoxSizing\n\tDBreakAfter\n\tDBreakBefore\n\tDBreakInside\n\tDCaptionSide\n\tDCaretColor\n\tDClear\n\tDClip\n\tDClipPath\n\tDClipRule\n\tDColor\n\tDColorInterpolation\n\tDColorInterpolationFilters\n\tDColumnCount\n\tDColumnFill\n\tDColumnGap\n\tDColumnRule\n\tDColumnRuleColor\n\tDColumnRuleStyle\n\tDColumnRuleWidth\n\tDColumnSpan\n\tDColumnWidth\n\tDColumns\n\tDComposes\n\tDContainer\n\tDContainerName\n\tDContainerType\n\tDContent\n\tDCounterIncrement\n\tDCounterReset\n\tDCssFloat\n\tDCssText\n\tDCursor\n\tDDirection\n\tDDisplay\n\tDDominantBaseline\n\tDEmptyCells\n\tDFill\n\tDFillOpacity\n\tDFillRule\n\tDFilter\n\tDFlex\n\tDFlexBasis\n\tDFlexDirection\n\tDFlexFlow\n\tDFlexGrow\n\tDFlexShrink\n\tDFlexWrap\n\tDFloat\n\tDFloodColor\n\tDFloodOpacity\n\tDFont\n\tDFontFamily\n\tDFontFeatureSettings\n\tDFontKerning\n\tDFontSize\n\tDFontSizeAdjust\n\tDFontStretch\n\tDFontStyle\n\tDFontSynthesis\n\tDFontVariant\n\tDFontVariantCaps\n\tDFontVariantEastAsian\n\tDFontVariantLigatures\n\tDFontVariantNumeric\n\tDFontVariantPosition\n\tDFontWeight\n\tDGap\n\tDGlyphOrientationVertical\n\tDGrid\n\tDGridArea\n\tDGridAutoColumns\n\tDGridAutoFlow\n\tDGridAutoRows\n\tDGridColumn\n\tDGridColumnEnd\n\tDGridColumnGap\n\tDGridColumnStart\n\tDGridGap\n\tDGridRow\n\tDGridRowEnd\n\tDGridRowGap\n\tDGridRowStart\n\tDGridTemplate\n\tDGridTemplateAreas\n\tDGridTemplateColumns\n\tDGridTemplateRows\n\tDHeight\n\tDHyphens\n\tDImageOrientation\n\tDImageRendering\n\tDInitialLetter\n\tDInlineSize\n\tDInset\n\tDJustifyContent\n\tDJustifyItems\n\tDJustifySelf\n\tDLeft\n\tDLetterSpacing\n\tDLightingColor\n\tDLineBreak\n\tDLineHeight\n\tDListStyle\n\tDListStyleImage\n\tDListStylePosition\n\tDListStyleType\n\tDMargin\n\tDMarginBlockEnd\n\tDMarginBlockStart\n\tDMarginBottom\n\tDMarginInlineEnd\n\tDMarginInlineStart\n\tDMarginLeft\n\tDMarginRight\n\tDMarginTop\n\tDMarker\n\tDMarkerEnd\n\tDMarkerMid\n\tDMarkerStart\n\tDMask\n\tDMaskComposite\n\tDMaskImage\n\tDMaskOrigin\n\tDMaskPosition\n\tDMaskRepeat\n\tDMaskSize\n\tDMaskType\n\tDMaxBlockSize\n\tDMaxHeight\n\tDMaxInlineSize\n\tDMaxWidth\n\tDMinBlockSize\n\tDMinHeight\n\tDMinInlineSize\n\tDMinWidth\n\tDObjectFit\n\tDObjectPosition\n\tDOpacity\n\tDOrder\n\tDOrphans\n\tDOutline\n\tDOutlineColor\n\tDOutlineOffset\n\tDOutlineStyle\n\tDOutlineWidth\n\tDOverflow\n\tDOverflowAnchor\n\tDOverflowWrap\n\tDOverflowX\n\tDOverflowY\n\tDOverscrollBehavior\n\tDOverscrollBehaviorBlock\n\tDOverscrollBehaviorInline\n\tDOverscrollBehaviorX\n\tDOverscrollBehaviorY\n\tDPadding\n\tDPaddingBlockEnd\n\tDPaddingBlockStart\n\tDPaddingBottom\n\tDPaddingInlineEnd\n\tDPaddingInlineStart\n\tDPaddingLeft\n\tDPaddingRight\n\tDPaddingTop\n\tDPageBreakAfter\n\tDPageBreakBefore\n\tDPageBreakInside\n\tDPaintOrder\n\tDPerspective\n\tDPerspectiveOrigin\n\tDPlaceContent\n\tDPlaceItems\n\tDPlaceSelf\n\tDPointerEvents\n\tDPosition\n\tDPrintColorAdjust\n\tDQuotes\n\tDResize\n\tDRight\n\tDRotate\n\tDRowGap\n\tDRubyAlign\n\tDRubyPosition\n\tDScale\n\tDScrollBehavior\n\tDShapeRendering\n\tDStopColor\n\tDStopOpacity\n\tDStroke\n\tDStrokeDasharray\n\tDStrokeDashoffset\n\tDStrokeLinecap\n\tDStrokeLinejoin\n\tDStrokeMiterlimit\n\tDStrokeOpacity\n\tDStrokeWidth\n\tDTabSize\n\tDTableLayout\n\tDTextAlign\n\tDTextAlignLast\n\tDTextAnchor\n\tDTextCombineUpright\n\tDTextDecoration\n\tDTextDecorationColor\n\tDTextDecorationLine\n\tDTextDecorationSkip\n\tDTextDecorationStyle\n\tDTextEmphasis\n\tDTextEmphasisColor\n\tDTextEmphasisPosition\n\tDTextEmphasisStyle\n\tDTextIndent\n\tDTextJustify\n\tDTextOrientation\n\tDTextOverflow\n\tDTextRendering\n\tDTextShadow\n\tDTextSizeAdjust\n\tDTextTransform\n\tDTextUnderlinePosition\n\tDTop\n\tDTouchAction\n\tDTransform\n\tDTransformBox\n\tDTransformOrigin\n\tDTransformStyle\n\tDTransition\n\tDTransitionDelay\n\tDTransitionDuration\n\tDTransitionProperty\n\tDTransitionTimingFunction\n\tDTranslate\n\tDUnicodeBidi\n\tDUserSelect\n\tDVerticalAlign\n\tDVisibility\n\tDWhiteSpace\n\tDWidows\n\tDWidth\n\tDWillChange\n\tDWordBreak\n\tDWordSpacing\n\tDWordWrap\n\tDWritingMode\n\tDZIndex\n\tDZoom\n)\n\nvar KnownDeclarations = map[string]D{\n\t\"align-content\":               DAlignContent,\n\t\"align-items\":                 DAlignItems,\n\t\"align-self\":                  DAlignSelf,\n\t\"alignment-baseline\":          DAlignmentBaseline,\n\t\"all\":                         DAll,\n\t\"animation\":                   DAnimation,\n\t\"animation-delay\":             DAnimationDelay,\n\t\"animation-direction\":         DAnimationDirection,\n\t\"animation-duration\":          DAnimationDuration,\n\t\"animation-fill-mode\":         DAnimationFillMode,\n\t\"animation-iteration-count\":   DAnimationIterationCount,\n\t\"animation-name\":              DAnimationName,\n\t\"animation-play-state\":        DAnimationPlayState,\n\t\"animation-timing-function\":   DAnimationTimingFunction,\n\t\"appearance\":                  DAppearance,\n\t\"backdrop-filter\":             DBackdropFilter,\n\t\"backface-visibility\":         DBackfaceVisibility,\n\t\"background\":                  DBackground,\n\t\"background-attachment\":       DBackgroundAttachment,\n\t\"background-clip\":             DBackgroundClip,\n\t\"background-color\":            DBackgroundColor,\n\t\"background-image\":            DBackgroundImage,\n\t\"background-origin\":           DBackgroundOrigin,\n\t\"background-position\":         DBackgroundPosition,\n\t\"background-position-x\":       DBackgroundPositionX,\n\t\"background-position-y\":       DBackgroundPositionY,\n\t\"background-repeat\":           DBackgroundRepeat,\n\t\"background-size\":             DBackgroundSize,\n\t\"baseline-shift\":              DBaselineShift,\n\t\"block-size\":                  DBlockSize,\n\t\"border\":                      DBorder,\n\t\"border-block-end\":            DBorderBlockEnd,\n\t\"border-block-end-color\":      DBorderBlockEndColor,\n\t\"border-block-end-style\":      DBorderBlockEndStyle,\n\t\"border-block-end-width\":      DBorderBlockEndWidth,\n\t\"border-block-start\":          DBorderBlockStart,\n\t\"border-block-start-color\":    DBorderBlockStartColor,\n\t\"border-block-start-style\":    DBorderBlockStartStyle,\n\t\"border-block-start-width\":    DBorderBlockStartWidth,\n\t\"border-bottom\":               DBorderBottom,\n\t\"border-bottom-color\":         DBorderBottomColor,\n\t\"border-bottom-left-radius\":   DBorderBottomLeftRadius,\n\t\"border-bottom-right-radius\":  DBorderBottomRightRadius,\n\t\"border-bottom-style\":         DBorderBottomStyle,\n\t\"border-bottom-width\":         DBorderBottomWidth,\n\t\"border-collapse\":             DBorderCollapse,\n\t\"border-color\":                DBorderColor,\n\t\"border-image\":                DBorderImage,\n\t\"border-image-outset\":         DBorderImageOutset,\n\t\"border-image-repeat\":         DBorderImageRepeat,\n\t\"border-image-slice\":          DBorderImageSlice,\n\t\"border-image-source\":         DBorderImageSource,\n\t\"border-image-width\":          DBorderImageWidth,\n\t\"border-inline-end\":           DBorderInlineEnd,\n\t\"border-inline-end-color\":     DBorderInlineEndColor,\n\t\"border-inline-end-style\":     DBorderInlineEndStyle,\n\t\"border-inline-end-width\":     DBorderInlineEndWidth,\n\t\"border-inline-start\":         DBorderInlineStart,\n\t\"border-inline-start-color\":   DBorderInlineStartColor,\n\t\"border-inline-start-style\":   DBorderInlineStartStyle,\n\t\"border-inline-start-width\":   DBorderInlineStartWidth,\n\t\"border-left\":                 DBorderLeft,\n\t\"border-left-color\":           DBorderLeftColor,\n\t\"border-left-style\":           DBorderLeftStyle,\n\t\"border-left-width\":           DBorderLeftWidth,\n\t\"border-radius\":               DBorderRadius,\n\t\"border-right\":                DBorderRight,\n\t\"border-right-color\":          DBorderRightColor,\n\t\"border-right-style\":          DBorderRightStyle,\n\t\"border-right-width\":          DBorderRightWidth,\n\t\"border-spacing\":              DBorderSpacing,\n\t\"border-style\":                DBorderStyle,\n\t\"border-top\":                  DBorderTop,\n\t\"border-top-color\":            DBorderTopColor,\n\t\"border-top-left-radius\":      DBorderTopLeftRadius,\n\t\"border-top-right-radius\":     DBorderTopRightRadius,\n\t\"border-top-style\":            DBorderTopStyle,\n\t\"border-top-width\":            DBorderTopWidth,\n\t\"border-width\":                DBorderWidth,\n\t\"bottom\":                      DBottom,\n\t\"box-decoration-break\":        DBoxDecorationBreak,\n\t\"box-shadow\":                  DBoxShadow,\n\t\"box-sizing\":                  DBoxSizing,\n\t\"break-after\":                 DBreakAfter,\n\t\"break-before\":                DBreakBefore,\n\t\"break-inside\":                DBreakInside,\n\t\"caption-side\":                DCaptionSide,\n\t\"caret-color\":                 DCaretColor,\n\t\"clear\":                       DClear,\n\t\"clip\":                        DClip,\n\t\"clip-path\":                   DClipPath,\n\t\"clip-rule\":                   DClipRule,\n\t\"color\":                       DColor,\n\t\"color-interpolation\":         DColorInterpolation,\n\t\"color-interpolation-filters\": DColorInterpolationFilters,\n\t\"column-count\":                DColumnCount,\n\t\"column-fill\":                 DColumnFill,\n\t\"column-gap\":                  DColumnGap,\n\t\"column-rule\":                 DColumnRule,\n\t\"column-rule-color\":           DColumnRuleColor,\n\t\"column-rule-style\":           DColumnRuleStyle,\n\t\"column-rule-width\":           DColumnRuleWidth,\n\t\"column-span\":                 DColumnSpan,\n\t\"column-width\":                DColumnWidth,\n\t\"columns\":                     DColumns,\n\t\"composes\":                    DComposes,\n\t\"container\":                   DContainer,\n\t\"container-name\":              DContainerName,\n\t\"container-type\":              DContainerType,\n\t\"content\":                     DContent,\n\t\"counter-increment\":           DCounterIncrement,\n\t\"counter-reset\":               DCounterReset,\n\t\"css-float\":                   DCssFloat,\n\t\"css-text\":                    DCssText,\n\t\"cursor\":                      DCursor,\n\t\"direction\":                   DDirection,\n\t\"display\":                     DDisplay,\n\t\"dominant-baseline\":           DDominantBaseline,\n\t\"empty-cells\":                 DEmptyCells,\n\t\"fill\":                        DFill,\n\t\"fill-opacity\":                DFillOpacity,\n\t\"fill-rule\":                   DFillRule,\n\t\"filter\":                      DFilter,\n\t\"flex\":                        DFlex,\n\t\"flex-basis\":                  DFlexBasis,\n\t\"flex-direction\":              DFlexDirection,\n\t\"flex-flow\":                   DFlexFlow,\n\t\"flex-grow\":                   DFlexGrow,\n\t\"flex-shrink\":                 DFlexShrink,\n\t\"flex-wrap\":                   DFlexWrap,\n\t\"float\":                       DFloat,\n\t\"flood-color\":                 DFloodColor,\n\t\"flood-opacity\":               DFloodOpacity,\n\t\"font\":                        DFont,\n\t\"font-family\":                 DFontFamily,\n\t\"font-feature-settings\":       DFontFeatureSettings,\n\t\"font-kerning\":                DFontKerning,\n\t\"font-size\":                   DFontSize,\n\t\"font-size-adjust\":            DFontSizeAdjust,\n\t\"font-stretch\":                DFontStretch,\n\t\"font-style\":                  DFontStyle,\n\t\"font-synthesis\":              DFontSynthesis,\n\t\"font-variant\":                DFontVariant,\n\t\"font-variant-caps\":           DFontVariantCaps,\n\t\"font-variant-east-asian\":     DFontVariantEastAsian,\n\t\"font-variant-ligatures\":      DFontVariantLigatures,\n\t\"font-variant-numeric\":        DFontVariantNumeric,\n\t\"font-variant-position\":       DFontVariantPosition,\n\t\"font-weight\":                 DFontWeight,\n\t\"gap\":                         DGap,\n\t\"glyph-orientation-vertical\":  DGlyphOrientationVertical,\n\t\"grid\":                        DGrid,\n\t\"grid-area\":                   DGridArea,\n\t\"grid-auto-columns\":           DGridAutoColumns,\n\t\"grid-auto-flow\":              DGridAutoFlow,\n\t\"grid-auto-rows\":              DGridAutoRows,\n\t\"grid-column\":                 DGridColumn,\n\t\"grid-column-end\":             DGridColumnEnd,\n\t\"grid-column-gap\":             DGridColumnGap,\n\t\"grid-column-start\":           DGridColumnStart,\n\t\"grid-gap\":                    DGridGap,\n\t\"grid-row\":                    DGridRow,\n\t\"grid-row-end\":                DGridRowEnd,\n\t\"grid-row-gap\":                DGridRowGap,\n\t\"grid-row-start\":              DGridRowStart,\n\t\"grid-template\":               DGridTemplate,\n\t\"grid-template-areas\":         DGridTemplateAreas,\n\t\"grid-template-columns\":       DGridTemplateColumns,\n\t\"grid-template-rows\":          DGridTemplateRows,\n\t\"height\":                      DHeight,\n\t\"hyphens\":                     DHyphens,\n\t\"image-orientation\":           DImageOrientation,\n\t\"image-rendering\":             DImageRendering,\n\t\"initial-letter\":              DInitialLetter,\n\t\"inline-size\":                 DInlineSize,\n\t\"inset\":                       DInset,\n\t\"justify-content\":             DJustifyContent,\n\t\"justify-items\":               DJustifyItems,\n\t\"justify-self\":                DJustifySelf,\n\t\"left\":                        DLeft,\n\t\"letter-spacing\":              DLetterSpacing,\n\t\"lighting-color\":              DLightingColor,\n\t\"line-break\":                  DLineBreak,\n\t\"line-height\":                 DLineHeight,\n\t\"list-style\":                  DListStyle,\n\t\"list-style-image\":            DListStyleImage,\n\t\"list-style-position\":         DListStylePosition,\n\t\"list-style-type\":             DListStyleType,\n\t\"margin\":                      DMargin,\n\t\"margin-block-end\":            DMarginBlockEnd,\n\t\"margin-block-start\":          DMarginBlockStart,\n\t\"margin-bottom\":               DMarginBottom,\n\t\"margin-inline-end\":           DMarginInlineEnd,\n\t\"margin-inline-start\":         DMarginInlineStart,\n\t\"margin-left\":                 DMarginLeft,\n\t\"margin-right\":                DMarginRight,\n\t\"margin-top\":                  DMarginTop,\n\t\"marker\":                      DMarker,\n\t\"marker-end\":                  DMarkerEnd,\n\t\"marker-mid\":                  DMarkerMid,\n\t\"marker-start\":                DMarkerStart,\n\t\"mask\":                        DMask,\n\t\"mask-composite\":              DMaskComposite,\n\t\"mask-image\":                  DMaskImage,\n\t\"mask-origin\":                 DMaskOrigin,\n\t\"mask-position\":               DMaskPosition,\n\t\"mask-repeat\":                 DMaskRepeat,\n\t\"mask-size\":                   DMaskSize,\n\t\"mask-type\":                   DMaskType,\n\t\"max-block-size\":              DMaxBlockSize,\n\t\"max-height\":                  DMaxHeight,\n\t\"max-inline-size\":             DMaxInlineSize,\n\t\"max-width\":                   DMaxWidth,\n\t\"min-block-size\":              DMinBlockSize,\n\t\"min-height\":                  DMinHeight,\n\t\"min-inline-size\":             DMinInlineSize,\n\t\"min-width\":                   DMinWidth,\n\t\"object-fit\":                  DObjectFit,\n\t\"object-position\":             DObjectPosition,\n\t\"opacity\":                     DOpacity,\n\t\"order\":                       DOrder,\n\t\"orphans\":                     DOrphans,\n\t\"outline\":                     DOutline,\n\t\"outline-color\":               DOutlineColor,\n\t\"outline-offset\":              DOutlineOffset,\n\t\"outline-style\":               DOutlineStyle,\n\t\"outline-width\":               DOutlineWidth,\n\t\"overflow\":                    DOverflow,\n\t\"overflow-anchor\":             DOverflowAnchor,\n\t\"overflow-wrap\":               DOverflowWrap,\n\t\"overflow-x\":                  DOverflowX,\n\t\"overflow-y\":                  DOverflowY,\n\t\"overscroll-behavior\":         DOverscrollBehavior,\n\t\"overscroll-behavior-block\":   DOverscrollBehaviorBlock,\n\t\"overscroll-behavior-inline\":  DOverscrollBehaviorInline,\n\t\"overscroll-behavior-x\":       DOverscrollBehaviorX,\n\t\"overscroll-behavior-y\":       DOverscrollBehaviorY,\n\t\"padding\":                     DPadding,\n\t\"padding-block-end\":           DPaddingBlockEnd,\n\t\"padding-block-start\":         DPaddingBlockStart,\n\t\"padding-bottom\":              DPaddingBottom,\n\t\"padding-inline-end\":          DPaddingInlineEnd,\n\t\"padding-inline-start\":        DPaddingInlineStart,\n\t\"padding-left\":                DPaddingLeft,\n\t\"padding-right\":               DPaddingRight,\n\t\"padding-top\":                 DPaddingTop,\n\t\"page-break-after\":            DPageBreakAfter,\n\t\"page-break-before\":           DPageBreakBefore,\n\t\"page-break-inside\":           DPageBreakInside,\n\t\"paint-order\":                 DPaintOrder,\n\t\"perspective\":                 DPerspective,\n\t\"perspective-origin\":          DPerspectiveOrigin,\n\t\"place-content\":               DPlaceContent,\n\t\"place-items\":                 DPlaceItems,\n\t\"place-self\":                  DPlaceSelf,\n\t\"pointer-events\":              DPointerEvents,\n\t\"position\":                    DPosition,\n\t\"print-color-adjust\":          DPrintColorAdjust,\n\t\"quotes\":                      DQuotes,\n\t\"resize\":                      DResize,\n\t\"right\":                       DRight,\n\t\"rotate\":                      DRotate,\n\t\"row-gap\":                     DRowGap,\n\t\"ruby-align\":                  DRubyAlign,\n\t\"ruby-position\":               DRubyPosition,\n\t\"scale\":                       DScale,\n\t\"scroll-behavior\":             DScrollBehavior,\n\t\"shape-rendering\":             DShapeRendering,\n\t\"stop-color\":                  DStopColor,\n\t\"stop-opacity\":                DStopOpacity,\n\t\"stroke\":                      DStroke,\n\t\"stroke-dasharray\":            DStrokeDasharray,\n\t\"stroke-dashoffset\":           DStrokeDashoffset,\n\t\"stroke-linecap\":              DStrokeLinecap,\n\t\"stroke-linejoin\":             DStrokeLinejoin,\n\t\"stroke-miterlimit\":           DStrokeMiterlimit,\n\t\"stroke-opacity\":              DStrokeOpacity,\n\t\"stroke-width\":                DStrokeWidth,\n\t\"tab-size\":                    DTabSize,\n\t\"table-layout\":                DTableLayout,\n\t\"text-align\":                  DTextAlign,\n\t\"text-align-last\":             DTextAlignLast,\n\t\"text-anchor\":                 DTextAnchor,\n\t\"text-combine-upright\":        DTextCombineUpright,\n\t\"text-decoration\":             DTextDecoration,\n\t\"text-decoration-color\":       DTextDecorationColor,\n\t\"text-decoration-line\":        DTextDecorationLine,\n\t\"text-decoration-skip\":        DTextDecorationSkip,\n\t\"text-decoration-style\":       DTextDecorationStyle,\n\t\"text-emphasis\":               DTextEmphasis,\n\t\"text-emphasis-color\":         DTextEmphasisColor,\n\t\"text-emphasis-position\":      DTextEmphasisPosition,\n\t\"text-emphasis-style\":         DTextEmphasisStyle,\n\t\"text-indent\":                 DTextIndent,\n\t\"text-justify\":                DTextJustify,\n\t\"text-orientation\":            DTextOrientation,\n\t\"text-overflow\":               DTextOverflow,\n\t\"text-rendering\":              DTextRendering,\n\t\"text-shadow\":                 DTextShadow,\n\t\"text-size-adjust\":            DTextSizeAdjust,\n\t\"text-transform\":              DTextTransform,\n\t\"text-underline-position\":     DTextUnderlinePosition,\n\t\"top\":                         DTop,\n\t\"touch-action\":                DTouchAction,\n\t\"transform\":                   DTransform,\n\t\"transform-box\":               DTransformBox,\n\t\"transform-origin\":            DTransformOrigin,\n\t\"transform-style\":             DTransformStyle,\n\t\"transition\":                  DTransition,\n\t\"transition-delay\":            DTransitionDelay,\n\t\"transition-duration\":         DTransitionDuration,\n\t\"transition-property\":         DTransitionProperty,\n\t\"transition-timing-function\":  DTransitionTimingFunction,\n\t\"translate\":                   DTranslate,\n\t\"unicode-bidi\":                DUnicodeBidi,\n\t\"user-select\":                 DUserSelect,\n\t\"vertical-align\":              DVerticalAlign,\n\t\"visibility\":                  DVisibility,\n\t\"white-space\":                 DWhiteSpace,\n\t\"widows\":                      DWidows,\n\t\"width\":                       DWidth,\n\t\"will-change\":                 DWillChange,\n\t\"word-break\":                  DWordBreak,\n\t\"word-spacing\":                DWordSpacing,\n\t\"word-wrap\":                   DWordWrap,\n\t\"writing-mode\":                DWritingMode,\n\t\"z-index\":                     DZIndex,\n\t\"zoom\":                        DZoom,\n}\n\nvar typoDetector *helpers.TypoDetector\nvar typoDetectorMutex sync.Mutex\n\nfunc MaybeCorrectDeclarationTypo(text string) (string, bool) {\n\t// Ignore CSS variables, which should not be corrected to CSS properties\n\tif strings.HasPrefix(text, \"--\") {\n\t\treturn \"\", false\n\t}\n\n\ttypoDetectorMutex.Lock()\n\tdefer typoDetectorMutex.Unlock()\n\n\t// Lazily-initialize the typo detector for speed when it's not needed\n\tif typoDetector == nil {\n\t\tvalid := make([]string, 0, len(KnownDeclarations))\n\t\tfor key := range KnownDeclarations {\n\t\t\tvalid = append(valid, key)\n\t\t}\n\t\tdetector := helpers.MakeTypoDetector(valid)\n\t\ttypoDetector = &detector\n\t}\n\n\treturn typoDetector.MaybeCorrectTypo(text)\n}\n"
  },
  {
    "path": "internal/css_lexer/css_lexer.go",
    "content": "package css_lexer\n\nimport (\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\n// The lexer converts a source file to a stream of tokens. Unlike esbuild's\n// JavaScript lexer, this CSS lexer runs to completion before the CSS parser\n// begins, resulting in a single array of all tokens in the file.\n\ntype T uint8\n\nconst eof = -1\n\nconst (\n\tTEndOfFile T = iota\n\n\tTAtKeyword\n\tTUnterminatedString\n\tTBadURL\n\tTCDC // \"-->\"\n\tTCDO // \"<!--\"\n\tTCloseBrace\n\tTCloseBracket\n\tTCloseParen\n\tTColon\n\tTComma\n\tTDelim\n\tTDelimAmpersand\n\tTDelimAsterisk\n\tTDelimBar\n\tTDelimCaret\n\tTDelimDollar\n\tTDelimDot\n\tTDelimEquals\n\tTDelimExclamation\n\tTDelimGreaterThan\n\tTDelimLessThan\n\tTDelimMinus\n\tTDelimPlus\n\tTDelimSlash\n\tTDelimTilde\n\tTDimension\n\tTFunction\n\tTHash\n\tTIdent\n\tTNumber\n\tTOpenBrace\n\tTOpenBracket\n\tTOpenParen\n\tTPercentage\n\tTSemicolon\n\tTString\n\tTURL\n\tTWhitespace\n\n\t// This is never something that the lexer generates directly. Instead this is\n\t// an esbuild-specific token for global/local names that \"TIdent\" tokens may\n\t// be changed into.\n\tTSymbol\n)\n\nvar tokenToString = []string{\n\t\"end of file\",\n\t\"@-keyword\",\n\t\"bad string token\",\n\t\"bad URL token\",\n\t\"\\\"-->\\\"\",\n\t\"\\\"<!--\\\"\",\n\t\"\\\"}\\\"\",\n\t\"\\\"]\\\"\",\n\t\"\\\")\\\"\",\n\t\"\\\":\\\"\",\n\t\"\\\",\\\"\",\n\t\"delimiter\",\n\t\"\\\"&\\\"\",\n\t\"\\\"*\\\"\",\n\t\"\\\"|\\\"\",\n\t\"\\\"^\\\"\",\n\t\"\\\"$\\\"\",\n\t\"\\\".\\\"\",\n\t\"\\\"=\\\"\",\n\t\"\\\"!\\\"\",\n\t\"\\\">\\\"\",\n\t\"\\\"<\\\"\",\n\t\"\\\"-\\\"\",\n\t\"\\\"+\\\"\",\n\t\"\\\"/\\\"\",\n\t\"\\\"~\\\"\",\n\t\"dimension\",\n\t\"function token\",\n\t\"hash token\",\n\t\"identifier\",\n\t\"number\",\n\t\"\\\"{\\\"\",\n\t\"\\\"[\\\"\",\n\t\"\\\"(\\\"\",\n\t\"percentage\",\n\t\"\\\";\\\"\",\n\t\"string token\",\n\t\"URL token\",\n\t\"whitespace\",\n\n\t\"identifier\",\n}\n\nfunc (t T) String() string {\n\treturn tokenToString[t]\n}\n\nfunc (t T) IsNumeric() bool {\n\treturn t == TNumber || t == TPercentage || t == TDimension\n}\n\ntype TokenFlags uint8\n\nconst (\n\tIsID TokenFlags = 1 << iota\n\tDidWarnAboutSingleLineComment\n)\n\n// This token struct is designed to be memory-efficient. It just references a\n// range in the input file instead of directly containing the substring of text\n// since a range takes up less memory than a string.\ntype Token struct {\n\tRange      logger.Range // 8 bytes\n\tUnitOffset uint16       // 2 bytes\n\tKind       T            // 1 byte\n\tFlags      TokenFlags   // 1 byte\n}\n\nfunc (token Token) DecodedText(contents string) string {\n\traw := contents[token.Range.Loc.Start:token.Range.End()]\n\n\tswitch token.Kind {\n\tcase TIdent, TDimension:\n\t\treturn decodeEscapesInToken(raw)\n\n\tcase TAtKeyword, THash:\n\t\treturn decodeEscapesInToken(raw[1:])\n\n\tcase TFunction:\n\t\treturn decodeEscapesInToken(raw[:len(raw)-1])\n\n\tcase TString:\n\t\treturn decodeEscapesInToken(raw[1 : len(raw)-1])\n\n\tcase TURL:\n\t\tstart := 4\n\t\tend := len(raw)\n\n\t\t// Note: URL tokens with syntax errors may not have a trailing \")\"\n\t\tif raw[end-1] == ')' {\n\t\t\tend--\n\t\t}\n\n\t\t// Trim leading and trailing whitespace\n\t\tfor start < end && isWhitespace(rune(raw[start])) {\n\t\t\tstart++\n\t\t}\n\t\tfor start < end && isWhitespace(rune(raw[end-1])) {\n\t\t\tend--\n\t\t}\n\n\t\treturn decodeEscapesInToken(raw[start:end])\n\t}\n\n\treturn raw\n}\n\ntype lexer struct {\n\tOptions\n\tlog                     logger.Log\n\tsource                  logger.Source\n\tallComments             []logger.Range\n\tlegalCommentsBefore     []Comment\n\tsourceMappingURL        logger.Span\n\ttracker                 logger.LineColumnTracker\n\tapproximateNewlineCount int\n\tcurrent                 int\n\toldSingleLineCommentEnd logger.Loc\n\tcodePoint               rune\n\tToken                   Token\n}\n\ntype Comment struct {\n\tText            string\n\tLoc             logger.Loc\n\tTokenIndexAfter uint32\n}\n\ntype TokenizeResult struct {\n\tTokens               []Token\n\tAllComments          []logger.Range\n\tLegalComments        []Comment\n\tSourceMapComment     logger.Span\n\tApproximateLineCount int32\n}\n\ntype Options struct {\n\tRecordAllComments bool\n}\n\nfunc Tokenize(log logger.Log, source logger.Source, options Options) TokenizeResult {\n\tlexer := lexer{\n\t\tOptions: options,\n\t\tlog:     log,\n\t\tsource:  source,\n\t\ttracker: logger.MakeLineColumnTracker(&source),\n\t}\n\tlexer.step()\n\n\t// The U+FEFF character is usually a zero-width non-breaking space. However,\n\t// when it's used at the start of a text stream it is called a BOM (byte order\n\t// mark) instead and indicates that the text stream is UTF-8 encoded. This is\n\t// problematic for us because CSS does not treat U+FEFF as whitespace. Only\n\t// \" \\t\\r\\n\\f\" characters are treated as whitespace. Skip over the BOM if it\n\t// is present so it doesn't cause us trouble when we try to parse it.\n\tif lexer.codePoint == '\\uFEFF' {\n\t\tlexer.step()\n\t}\n\n\tlexer.next()\n\tvar tokens []Token\n\tvar legalComments []Comment\n\tfor lexer.Token.Kind != TEndOfFile {\n\t\tif lexer.legalCommentsBefore != nil {\n\t\t\tfor _, comment := range lexer.legalCommentsBefore {\n\t\t\t\tcomment.TokenIndexAfter = uint32(len(tokens))\n\t\t\t\tlegalComments = append(legalComments, comment)\n\t\t\t}\n\t\t\tlexer.legalCommentsBefore = nil\n\t\t}\n\t\ttokens = append(tokens, lexer.Token)\n\t\tlexer.next()\n\t}\n\tif lexer.legalCommentsBefore != nil {\n\t\tfor _, comment := range lexer.legalCommentsBefore {\n\t\t\tcomment.TokenIndexAfter = uint32(len(tokens))\n\t\t\tlegalComments = append(legalComments, comment)\n\t\t}\n\t\tlexer.legalCommentsBefore = nil\n\t}\n\treturn TokenizeResult{\n\t\tTokens:               tokens,\n\t\tAllComments:          lexer.allComments,\n\t\tLegalComments:        legalComments,\n\t\tApproximateLineCount: int32(lexer.approximateNewlineCount) + 1,\n\t\tSourceMapComment:     lexer.sourceMappingURL,\n\t}\n}\n\nfunc (lexer *lexer) step() {\n\tcodePoint, width := utf8.DecodeRuneInString(lexer.source.Contents[lexer.current:])\n\n\t// Use -1 to indicate the end of the file\n\tif width == 0 {\n\t\tcodePoint = eof\n\t}\n\n\t// Track the approximate number of newlines in the file so we can preallocate\n\t// the line offset table in the printer for source maps. The line offset table\n\t// is the #1 highest allocation in the heap profile, so this is worth doing.\n\t// This count is approximate because it handles \"\\n\" and \"\\r\\n\" (the common\n\t// cases) but not \"\\r\" or \"\\u2028\" or \"\\u2029\". Getting this wrong is harmless\n\t// because it's only a preallocation. The array will just grow if it's too small.\n\tif codePoint == '\\n' {\n\t\tlexer.approximateNewlineCount++\n\t}\n\n\tlexer.codePoint = codePoint\n\tlexer.Token.Range.Len = int32(lexer.current) - lexer.Token.Range.Loc.Start\n\tlexer.current += width\n}\n\nfunc (lexer *lexer) next() {\n\t// Reference: https://www.w3.org/TR/css-syntax-3/\n\n\tfor {\n\t\tlexer.Token = Token{Range: logger.Range{Loc: logger.Loc{Start: lexer.Token.Range.End()}}}\n\n\t\tswitch lexer.codePoint {\n\t\tcase eof:\n\t\t\tlexer.Token.Kind = TEndOfFile\n\n\t\tcase '/':\n\t\t\tlexer.step()\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '*':\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.consumeToEndOfMultiLineComment(lexer.Token.Range)\n\t\t\t\tcontinue\n\t\t\tcase '/':\n\t\t\t\t// Warn when people use \"//\" comments, which are invalid in CSS\n\t\t\t\tloc := lexer.Token.Range.Loc\n\t\t\t\tif loc.Start >= lexer.oldSingleLineCommentEnd.Start {\n\t\t\t\t\tcontents := lexer.source.Contents\n\t\t\t\t\tend := lexer.current\n\t\t\t\t\tfor end < len(contents) && !isNewline(rune(contents[end])) {\n\t\t\t\t\t\tend++\n\t\t\t\t\t}\n\t\t\t\t\tlexer.log.AddID(logger.MsgID_CSS_JSCommentInCSS, logger.Warning, &lexer.tracker, logger.Range{Loc: loc, Len: 2},\n\t\t\t\t\t\t\"Comments in CSS use \\\"/* ... */\\\" instead of \\\"//\\\"\")\n\t\t\t\t\tlexer.oldSingleLineCommentEnd.Start = int32(end)\n\t\t\t\t\tlexer.Token.Flags |= DidWarnAboutSingleLineComment\n\t\t\t\t}\n\t\t\t}\n\t\t\tlexer.Token.Kind = TDelimSlash\n\n\t\tcase ' ', '\\t', '\\n', '\\r', '\\f':\n\t\t\tlexer.step()\n\t\t\tfor {\n\t\t\t\tif isWhitespace(lexer.codePoint) {\n\t\t\t\t\tlexer.step()\n\t\t\t\t} else if lexer.codePoint == '/' && lexer.current < len(lexer.source.Contents) && lexer.source.Contents[lexer.current] == '*' {\n\t\t\t\t\tstartRange := logger.Range{Loc: logger.Loc{Start: lexer.Token.Range.End()}, Len: 2}\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.consumeToEndOfMultiLineComment(startRange)\n\t\t\t\t} else {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tlexer.Token.Kind = TWhitespace\n\n\t\tcase '\"', '\\'':\n\t\t\tlexer.Token.Kind = lexer.consumeString()\n\n\t\tcase '#':\n\t\t\tlexer.step()\n\t\t\tif IsNameContinue(lexer.codePoint) || lexer.isValidEscape() {\n\t\t\t\tlexer.Token.Kind = THash\n\t\t\t\tif lexer.wouldStartIdentifier() {\n\t\t\t\t\tlexer.Token.Flags |= IsID\n\t\t\t\t}\n\t\t\t\tlexer.consumeName()\n\t\t\t} else {\n\t\t\t\tlexer.Token.Kind = TDelim\n\t\t\t}\n\n\t\tcase '(':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TOpenParen\n\n\t\tcase ')':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TCloseParen\n\n\t\tcase '[':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TOpenBracket\n\n\t\tcase ']':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TCloseBracket\n\n\t\tcase '{':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TOpenBrace\n\n\t\tcase '}':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TCloseBrace\n\n\t\tcase ',':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TComma\n\n\t\tcase ':':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TColon\n\n\t\tcase ';':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TSemicolon\n\n\t\tcase '+':\n\t\t\tif lexer.wouldStartNumber() {\n\t\t\t\tlexer.Token.Kind = lexer.consumeNumeric()\n\t\t\t} else {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token.Kind = TDelimPlus\n\t\t\t}\n\n\t\tcase '.':\n\t\t\tif lexer.wouldStartNumber() {\n\t\t\t\tlexer.Token.Kind = lexer.consumeNumeric()\n\t\t\t} else {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token.Kind = TDelimDot\n\t\t\t}\n\n\t\tcase '-':\n\t\t\tif lexer.wouldStartNumber() {\n\t\t\t\tlexer.Token.Kind = lexer.consumeNumeric()\n\t\t\t} else if lexer.current+2 <= len(lexer.source.Contents) && lexer.source.Contents[lexer.current:lexer.current+2] == \"->\" {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token.Kind = TCDC\n\t\t\t} else if lexer.wouldStartIdentifier() {\n\t\t\t\tlexer.Token.Kind = lexer.consumeIdentLike()\n\t\t\t} else {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token.Kind = TDelimMinus\n\t\t\t}\n\n\t\tcase '<':\n\t\t\tif lexer.current+3 <= len(lexer.source.Contents) && lexer.source.Contents[lexer.current:lexer.current+3] == \"!--\" {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token.Kind = TCDO\n\t\t\t} else {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token.Kind = TDelimLessThan\n\t\t\t}\n\n\t\tcase '@':\n\t\t\tlexer.step()\n\t\t\tif lexer.wouldStartIdentifier() {\n\t\t\t\tlexer.consumeName()\n\t\t\t\tlexer.Token.Kind = TAtKeyword\n\t\t\t} else {\n\t\t\t\tlexer.Token.Kind = TDelim\n\t\t\t}\n\n\t\tcase '\\\\':\n\t\t\tif lexer.isValidEscape() {\n\t\t\t\tlexer.Token.Kind = lexer.consumeIdentLike()\n\t\t\t} else {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.log.AddError(&lexer.tracker, lexer.Token.Range, \"Invalid escape\")\n\t\t\t\tlexer.Token.Kind = TDelim\n\t\t\t}\n\n\t\tcase '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':\n\t\t\tlexer.Token.Kind = lexer.consumeNumeric()\n\n\t\tcase '>':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimGreaterThan\n\n\t\tcase '~':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimTilde\n\n\t\tcase '&':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimAmpersand\n\n\t\tcase '*':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimAsterisk\n\n\t\tcase '|':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimBar\n\n\t\tcase '!':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimExclamation\n\n\t\tcase '=':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimEquals\n\n\t\tcase '^':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimCaret\n\n\t\tcase '$':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimDollar\n\n\t\tdefault:\n\t\t\tif IsNameStart(lexer.codePoint) {\n\t\t\t\tlexer.Token.Kind = lexer.consumeIdentLike()\n\t\t\t} else {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token.Kind = TDelim\n\t\t\t}\n\t\t}\n\n\t\treturn\n\t}\n}\n\nfunc (lexer *lexer) consumeToEndOfMultiLineComment(startRange logger.Range) {\n\tstartOfSourceMappingURL := 0\n\tisLegalComment := false\n\n\tswitch lexer.codePoint {\n\tcase '#', '@':\n\t\t// Keep track of the contents of the \"sourceMappingURL=\" comment\n\t\tif strings.HasPrefix(lexer.source.Contents[lexer.current:], \" sourceMappingURL=\") {\n\t\t\tstartOfSourceMappingURL = lexer.current + len(\" sourceMappingURL=\")\n\t\t}\n\n\tcase '!':\n\t\t// Remember if this is a legal comment\n\t\tisLegalComment = true\n\t}\n\n\tfor {\n\t\tswitch lexer.codePoint {\n\t\tcase '*':\n\t\t\tendOfSourceMappingURL := lexer.current - 1\n\t\t\tlexer.step()\n\t\t\tif lexer.codePoint == '/' {\n\t\t\t\tcommentEnd := lexer.current\n\t\t\t\tlexer.step()\n\n\t\t\t\t// Record the source mapping URL\n\t\t\t\tif startOfSourceMappingURL != 0 {\n\t\t\t\t\tr := logger.Range{Loc: logger.Loc{Start: int32(startOfSourceMappingURL)}}\n\t\t\t\t\ttext := lexer.source.Contents[startOfSourceMappingURL:endOfSourceMappingURL]\n\t\t\t\t\tfor int(r.Len) < len(text) && !isWhitespace(rune(text[r.Len])) {\n\t\t\t\t\t\tr.Len++\n\t\t\t\t\t}\n\t\t\t\t\tlexer.sourceMappingURL = logger.Span{Text: text[:r.Len], Range: r}\n\t\t\t\t}\n\n\t\t\t\t// Record all comments\n\t\t\t\tcommentRange := logger.Range{Loc: startRange.Loc, Len: int32(commentEnd) - startRange.Loc.Start}\n\t\t\t\tif lexer.RecordAllComments {\n\t\t\t\t\tlexer.allComments = append(lexer.allComments, commentRange)\n\t\t\t\t}\n\n\t\t\t\t// Record legal comments\n\t\t\t\tif text := lexer.source.Contents[startRange.Loc.Start:commentEnd]; isLegalComment || containsAtPreserveOrAtLicense(text) {\n\t\t\t\t\ttext = lexer.source.CommentTextWithoutIndent(commentRange)\n\t\t\t\t\tlexer.legalCommentsBefore = append(lexer.legalCommentsBefore, Comment{Loc: startRange.Loc, Text: text})\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\tcase eof: // This indicates the end of the file\n\t\t\tlexer.log.AddErrorWithNotes(&lexer.tracker, logger.Range{Loc: logger.Loc{Start: lexer.Token.Range.End()}},\n\t\t\t\t\"Expected \\\"*/\\\" to terminate multi-line comment\",\n\t\t\t\t[]logger.MsgData{lexer.tracker.MsgData(startRange, \"The multi-line comment starts here:\")})\n\t\t\treturn\n\n\t\tdefault:\n\t\t\tlexer.step()\n\t\t}\n\t}\n}\n\nfunc containsAtPreserveOrAtLicense(text string) bool {\n\tfor i, c := range text {\n\t\tif c == '@' && (strings.HasPrefix(text[i+1:], \"preserve\") || strings.HasPrefix(text[i+1:], \"license\")) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (lexer *lexer) isValidEscape() bool {\n\tif lexer.codePoint != '\\\\' {\n\t\treturn false\n\t}\n\tc, _ := utf8.DecodeRuneInString(lexer.source.Contents[lexer.current:])\n\treturn !isNewline(c)\n}\n\nfunc (lexer *lexer) wouldStartIdentifier() bool {\n\tif IsNameStart(lexer.codePoint) {\n\t\treturn true\n\t}\n\n\tif lexer.codePoint == '-' {\n\t\tc, width := utf8.DecodeRuneInString(lexer.source.Contents[lexer.current:])\n\t\tif c == utf8.RuneError && width <= 1 {\n\t\t\treturn false // Decoding error\n\t\t}\n\t\tif IsNameStart(c) || c == '-' {\n\t\t\treturn true\n\t\t}\n\t\tif c == '\\\\' {\n\t\t\tc2, _ := utf8.DecodeRuneInString(lexer.source.Contents[lexer.current+width:])\n\t\t\treturn !isNewline(c2)\n\t\t}\n\t\treturn false\n\t}\n\n\treturn lexer.isValidEscape()\n}\n\nfunc WouldStartIdentifierWithoutEscapes(text string) bool {\n\tc, width := utf8.DecodeRuneInString(text)\n\tif c == utf8.RuneError && width <= 1 {\n\t\treturn false // Decoding error\n\t}\n\tif IsNameStart(c) {\n\t\treturn true\n\t}\n\n\tif c == '-' {\n\t\tc2, width2 := utf8.DecodeRuneInString(text[width:])\n\t\tif c2 == utf8.RuneError && width2 <= 1 {\n\t\t\treturn false // Decoding error\n\t\t}\n\t\tif IsNameStart(c2) || c2 == '-' {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc RangeOfIdentifier(source logger.Source, loc logger.Loc) logger.Range {\n\ttext := source.Contents[loc.Start:]\n\tif len(text) == 0 {\n\t\treturn logger.Range{Loc: loc, Len: 0}\n\t}\n\n\ti := 0\n\tn := len(text)\n\n\tfor {\n\t\tc, width := utf8.DecodeRuneInString(text[i:])\n\t\tif IsNameContinue(c) {\n\t\t\ti += width\n\t\t\tcontinue\n\t\t}\n\n\t\t// Handle an escape\n\t\tif c == '\\\\' && i+1 < n && !isNewline(rune(text[i+1])) {\n\t\t\ti += width // Skip the backslash\n\t\t\tc, width = utf8.DecodeRuneInString(text[i:])\n\t\t\tif _, ok := isHex(c); ok {\n\t\t\t\ti += width\n\t\t\t\tc, width = utf8.DecodeRuneInString(text[i:])\n\t\t\t\tfor j := 0; j < 5; j++ {\n\t\t\t\t\tif _, ok := isHex(c); !ok {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\ti += width\n\t\t\t\t\tc, width = utf8.DecodeRuneInString(text[i:])\n\t\t\t\t}\n\t\t\t\tif isWhitespace(c) {\n\t\t\t\t\ti += width\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tbreak\n\t}\n\n\t// Don't end with a whitespace\n\tif i > 0 && isWhitespace(rune(text[i-1])) {\n\t\ti--\n\t}\n\n\treturn logger.Range{Loc: loc, Len: int32(i)}\n}\n\nfunc (lexer *lexer) wouldStartNumber() bool {\n\tif lexer.codePoint >= '0' && lexer.codePoint <= '9' {\n\t\treturn true\n\t} else if lexer.codePoint == '.' {\n\t\tcontents := lexer.source.Contents\n\t\tif lexer.current < len(contents) {\n\t\t\tc := contents[lexer.current]\n\t\t\treturn c >= '0' && c <= '9'\n\t\t}\n\t} else if lexer.codePoint == '+' || lexer.codePoint == '-' {\n\t\tcontents := lexer.source.Contents\n\t\tn := len(contents)\n\t\tif lexer.current < n {\n\t\t\tc := contents[lexer.current]\n\t\t\tif c >= '0' && c <= '9' {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif c == '.' && lexer.current+1 < n {\n\t\t\t\tc = contents[lexer.current+1]\n\t\t\t\treturn c >= '0' && c <= '9'\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\n// Note: This function is hot in profiles\nfunc (lexer *lexer) consumeName() string {\n\t// Common case: no escapes, identifier is a substring of the input. Doing this\n\t// in a tight loop that avoids UTF-8 decoding and that increments a single\n\t// number instead of doing \"step()\" is noticeably faster. For example, doing\n\t// this sped up end-to-end parsing and printing of a large CSS file from 97ms\n\t// to 84ms (around 15% faster).\n\tcontents := lexer.source.Contents\n\tif IsNameContinue(lexer.codePoint) {\n\t\tn := len(contents)\n\t\ti := lexer.current\n\t\tfor i < n && IsNameContinue(rune(contents[i])) {\n\t\t\ti++\n\t\t}\n\t\tlexer.current = i\n\t\tlexer.step()\n\t}\n\traw := contents[lexer.Token.Range.Loc.Start:lexer.Token.Range.End()]\n\tif !lexer.isValidEscape() {\n\t\treturn raw\n\t}\n\n\t// Uncommon case: escapes, identifier is allocated\n\tsb := strings.Builder{}\n\tsb.WriteString(raw)\n\tsb.WriteRune(lexer.consumeEscape())\n\tfor {\n\t\tif IsNameContinue(lexer.codePoint) {\n\t\t\tsb.WriteRune(lexer.codePoint)\n\t\t\tlexer.step()\n\t\t} else if lexer.isValidEscape() {\n\t\t\tsb.WriteRune(lexer.consumeEscape())\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn sb.String()\n}\n\nfunc (lexer *lexer) consumeEscape() rune {\n\tlexer.step() // Skip the backslash\n\tc := lexer.codePoint\n\n\tif hex, ok := isHex(c); ok {\n\t\tlexer.step()\n\t\tfor i := 0; i < 5; i++ {\n\t\t\tif next, ok := isHex(lexer.codePoint); ok {\n\t\t\t\tlexer.step()\n\t\t\t\thex = hex*16 + next\n\t\t\t} else {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif isWhitespace(lexer.codePoint) {\n\t\t\tlexer.step()\n\t\t}\n\t\tif hex == 0 || (hex >= 0xD800 && hex <= 0xDFFF) || hex > 0x10FFFF {\n\t\t\treturn utf8.RuneError\n\t\t}\n\t\treturn rune(hex)\n\t}\n\n\tif c == eof {\n\t\treturn utf8.RuneError\n\t}\n\n\tlexer.step()\n\treturn c\n}\n\nfunc (lexer *lexer) consumeIdentLike() T {\n\tname := lexer.consumeName()\n\n\tif lexer.codePoint == '(' {\n\t\tmatchingLoc := logger.Loc{Start: lexer.Token.Range.End()}\n\t\tlexer.step()\n\t\tif len(name) == 3 {\n\t\t\tu, r, l := name[0], name[1], name[2]\n\t\t\tif (u == 'u' || u == 'U') && (r == 'r' || r == 'R') && (l == 'l' || l == 'L') {\n\t\t\t\t// Save state\n\t\t\t\tapproximateNewlineCount := lexer.approximateNewlineCount\n\t\t\t\tcodePoint := lexer.codePoint\n\t\t\t\ttokenRangeLen := lexer.Token.Range.Len\n\t\t\t\tcurrent := lexer.current\n\n\t\t\t\t// Check to see if this is a URL token instead of a function\n\t\t\t\tfor isWhitespace(lexer.codePoint) {\n\t\t\t\t\tlexer.step()\n\t\t\t\t}\n\t\t\t\tif lexer.codePoint != '\"' && lexer.codePoint != '\\'' {\n\t\t\t\t\treturn lexer.consumeURL(matchingLoc)\n\t\t\t\t}\n\n\t\t\t\t// Restore state (i.e. backtrack)\n\t\t\t\tlexer.approximateNewlineCount = approximateNewlineCount\n\t\t\t\tlexer.codePoint = codePoint\n\t\t\t\tlexer.Token.Range.Len = tokenRangeLen\n\t\t\t\tlexer.current = current\n\t\t\t}\n\t\t}\n\t\treturn TFunction\n\t}\n\n\treturn TIdent\n}\n\nfunc (lexer *lexer) consumeURL(matchingLoc logger.Loc) T {\nvalidURL:\n\tfor {\n\t\tswitch lexer.codePoint {\n\t\tcase ')':\n\t\t\tlexer.step()\n\t\t\treturn TURL\n\n\t\tcase eof:\n\t\t\tloc := logger.Loc{Start: lexer.Token.Range.End()}\n\t\t\tlexer.log.AddIDWithNotes(logger.MsgID_CSS_CSSSyntaxError, logger.Warning, &lexer.tracker, logger.Range{Loc: loc}, \"Expected \\\")\\\" to end URL token\",\n\t\t\t\t[]logger.MsgData{lexer.tracker.MsgData(logger.Range{Loc: matchingLoc, Len: 1}, \"The unbalanced \\\"(\\\" is here:\")})\n\t\t\treturn TURL\n\n\t\tcase ' ', '\\t', '\\n', '\\r', '\\f':\n\t\t\tlexer.step()\n\t\t\tfor isWhitespace(lexer.codePoint) {\n\t\t\t\tlexer.step()\n\t\t\t}\n\t\t\tif lexer.codePoint != ')' {\n\t\t\t\tloc := logger.Loc{Start: lexer.Token.Range.End()}\n\t\t\t\tlexer.log.AddIDWithNotes(logger.MsgID_CSS_CSSSyntaxError, logger.Warning, &lexer.tracker, logger.Range{Loc: loc}, \"Expected \\\")\\\" to end URL token\",\n\t\t\t\t\t[]logger.MsgData{lexer.tracker.MsgData(logger.Range{Loc: matchingLoc, Len: 1}, \"The unbalanced \\\"(\\\" is here:\")})\n\t\t\t\tif lexer.codePoint == eof {\n\t\t\t\t\treturn TURL\n\t\t\t\t}\n\t\t\t\tbreak validURL\n\t\t\t}\n\t\t\tlexer.step()\n\t\t\treturn TURL\n\n\t\tcase '\"', '\\'', '(':\n\t\t\tr := logger.Range{Loc: logger.Loc{Start: lexer.Token.Range.End()}, Len: 1}\n\t\t\tlexer.log.AddIDWithNotes(logger.MsgID_CSS_CSSSyntaxError, logger.Warning, &lexer.tracker, r, \"Expected \\\")\\\" to end URL token\",\n\t\t\t\t[]logger.MsgData{lexer.tracker.MsgData(logger.Range{Loc: matchingLoc, Len: 1}, \"The unbalanced \\\"(\\\" is here:\")})\n\t\t\tbreak validURL\n\n\t\tcase '\\\\':\n\t\t\tif !lexer.isValidEscape() {\n\t\t\t\tr := logger.Range{Loc: logger.Loc{Start: lexer.Token.Range.End()}, Len: 1}\n\t\t\t\tlexer.log.AddID(logger.MsgID_CSS_CSSSyntaxError, logger.Warning, &lexer.tracker, r, \"Invalid escape\")\n\t\t\t\tbreak validURL\n\t\t\t}\n\t\t\tlexer.consumeEscape()\n\n\t\tdefault:\n\t\t\tif isNonPrintable(lexer.codePoint) {\n\t\t\t\tr := logger.Range{Loc: logger.Loc{Start: lexer.Token.Range.End()}, Len: 1}\n\t\t\t\tlexer.log.AddID(logger.MsgID_CSS_CSSSyntaxError, logger.Warning, &lexer.tracker, r, \"Unexpected non-printable character in URL token\")\n\t\t\t\tbreak validURL\n\t\t\t}\n\t\t\tlexer.step()\n\t\t}\n\t}\n\n\t// Consume the remnants of a bad url\n\tfor {\n\t\tswitch lexer.codePoint {\n\t\tcase ')', eof:\n\t\t\tlexer.step()\n\t\t\treturn TBadURL\n\n\t\tcase '\\\\':\n\t\t\tif lexer.isValidEscape() {\n\t\t\t\tlexer.consumeEscape()\n\t\t\t}\n\t\t}\n\t\tlexer.step()\n\t}\n}\n\nfunc (lexer *lexer) consumeString() T {\n\tquote := lexer.codePoint\n\tlexer.step()\n\n\tfor {\n\t\tswitch lexer.codePoint {\n\t\tcase '\\\\':\n\t\t\tlexer.step()\n\n\t\t\t// Handle Windows CRLF\n\t\t\tif lexer.codePoint == '\\r' {\n\t\t\t\tlexer.step()\n\t\t\t\tif lexer.codePoint == '\\n' {\n\t\t\t\t\tlexer.step()\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Otherwise, fall through to ignore the character after the backslash\n\n\t\tcase eof, '\\n', '\\r', '\\f':\n\t\t\tlexer.log.AddID(logger.MsgID_CSS_CSSSyntaxError, logger.Warning, &lexer.tracker,\n\t\t\t\tlogger.Range{Loc: logger.Loc{Start: lexer.Token.Range.End()}},\n\t\t\t\t\"Unterminated string token\")\n\t\t\treturn TUnterminatedString\n\n\t\tcase quote:\n\t\t\tlexer.step()\n\t\t\treturn TString\n\t\t}\n\t\tlexer.step()\n\t}\n}\n\nfunc (lexer *lexer) consumeNumeric() T {\n\t// Skip over leading sign\n\tif lexer.codePoint == '+' || lexer.codePoint == '-' {\n\t\tlexer.step()\n\t}\n\n\t// Skip over leading digits\n\tfor lexer.codePoint >= '0' && lexer.codePoint <= '9' {\n\t\tlexer.step()\n\t}\n\n\t// Skip over digits after dot\n\tif lexer.codePoint == '.' {\n\t\tlexer.step()\n\t\tfor lexer.codePoint >= '0' && lexer.codePoint <= '9' {\n\t\t\tlexer.step()\n\t\t}\n\t}\n\n\t// Skip over exponent\n\tif lexer.codePoint == 'e' || lexer.codePoint == 'E' {\n\t\tcontents := lexer.source.Contents\n\n\t\t// Look ahead before advancing to make sure this is an exponent, not a unit\n\t\tif lexer.current < len(contents) {\n\t\t\tc := contents[lexer.current]\n\t\t\tif (c == '+' || c == '-') && lexer.current+1 < len(contents) {\n\t\t\t\tc = contents[lexer.current+1]\n\t\t\t}\n\n\t\t\t// Only consume this if it's an exponent\n\t\t\tif c >= '0' && c <= '9' {\n\t\t\t\tlexer.step()\n\t\t\t\tif lexer.codePoint == '+' || lexer.codePoint == '-' {\n\t\t\t\t\tlexer.step()\n\t\t\t\t}\n\t\t\t\tfor lexer.codePoint >= '0' && lexer.codePoint <= '9' {\n\t\t\t\t\tlexer.step()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Determine the numeric type\n\tif lexer.wouldStartIdentifier() {\n\t\tlexer.Token.UnitOffset = uint16(lexer.Token.Range.Len)\n\t\tlexer.consumeName()\n\t\treturn TDimension\n\t}\n\tif lexer.codePoint == '%' {\n\t\tlexer.step()\n\t\treturn TPercentage\n\t}\n\treturn TNumber\n}\n\nfunc IsNameStart(c rune) bool {\n\treturn (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c >= 0x80 || c == '\\x00'\n}\n\nfunc IsNameContinue(c rune) bool {\n\treturn IsNameStart(c) || (c >= '0' && c <= '9') || c == '-'\n}\n\nfunc isNewline(c rune) bool {\n\tswitch c {\n\tcase '\\n', '\\r', '\\f':\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc isWhitespace(c rune) bool {\n\tswitch c {\n\tcase ' ', '\\t', '\\n', '\\r', '\\f':\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc isHex(c rune) (int, bool) {\n\tif c >= '0' && c <= '9' {\n\t\treturn int(c - '0'), true\n\t}\n\tif c >= 'a' && c <= 'f' {\n\t\treturn int(c + (10 - 'a')), true\n\t}\n\tif c >= 'A' && c <= 'F' {\n\t\treturn int(c + (10 - 'A')), true\n\t}\n\treturn 0, false\n}\n\nfunc isNonPrintable(c rune) bool {\n\treturn c <= 0x08 || c == 0x0B || (c >= 0x0E && c <= 0x1F) || c == 0x7F\n}\n\nfunc decodeEscapesInToken(inner string) string {\n\ti := 0\n\n\tfor i < len(inner) {\n\t\tif c := inner[i]; c == '\\\\' || c == '\\x00' {\n\t\t\tbreak\n\t\t}\n\t\ti++\n\t}\n\n\tif i == len(inner) {\n\t\treturn inner\n\t}\n\n\tsb := strings.Builder{}\n\tsb.WriteString(inner[:i])\n\tinner = inner[i:]\n\n\tfor len(inner) > 0 {\n\t\tc, width := utf8.DecodeRuneInString(inner)\n\t\tinner = inner[width:]\n\n\t\tif c != '\\\\' {\n\t\t\tif c == '\\x00' {\n\t\t\t\tc = utf8.RuneError\n\t\t\t}\n\t\t\tsb.WriteRune(c)\n\t\t\tcontinue\n\t\t}\n\n\t\tif len(inner) == 0 {\n\t\t\tsb.WriteRune(utf8.RuneError)\n\t\t\tcontinue\n\t\t}\n\n\t\tc, width = utf8.DecodeRuneInString(inner)\n\t\tinner = inner[width:]\n\t\thex, ok := isHex(c)\n\n\t\tif !ok {\n\t\t\tif c == '\\n' || c == '\\f' {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Handle Windows CRLF\n\t\t\tif c == '\\r' {\n\t\t\t\tc, width = utf8.DecodeRuneInString(inner)\n\t\t\t\tif c == '\\n' {\n\t\t\t\t\tinner = inner[width:]\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// If we get here, this is not a valid escape. However, this is still\n\t\t\t// allowed. In this case the backslash is just ignored.\n\t\t\tsb.WriteRune(c)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Parse up to five additional hex characters (so six in total)\n\t\tfor i := 0; i < 5 && len(inner) > 0; i++ {\n\t\t\tc, width = utf8.DecodeRuneInString(inner)\n\t\t\tif next, ok := isHex(c); ok {\n\t\t\t\tinner = inner[width:]\n\t\t\t\thex = hex*16 + next\n\t\t\t} else {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif len(inner) > 0 {\n\t\t\tc, width = utf8.DecodeRuneInString(inner)\n\t\t\tif isWhitespace(c) {\n\t\t\t\tinner = inner[width:]\n\t\t\t}\n\t\t}\n\n\t\tif hex == 0 || (hex >= 0xD800 && hex <= 0xDFFF) || hex > 0x10FFFF {\n\t\t\tsb.WriteRune(utf8.RuneError)\n\t\t\tcontinue\n\t\t}\n\n\t\tsb.WriteRune(rune(hex))\n\t}\n\n\treturn sb.String()\n}\n"
  },
  {
    "path": "internal/css_lexer/css_lexer_test.go",
    "content": "package css_lexer\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/test\"\n)\n\nfunc lexToken(contents string) (T, string) {\n\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\tresult := Tokenize(log, test.SourceForTest(contents), Options{})\n\tif len(result.Tokens) > 0 {\n\t\tt := result.Tokens[0]\n\t\treturn t.Kind, t.DecodedText(contents)\n\t}\n\treturn TEndOfFile, \"\"\n}\n\nfunc lexerError(contents string) string {\n\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\tTokenize(log, test.SourceForTest(contents), Options{})\n\tvar text strings.Builder\n\tfor _, msg := range log.Done() {\n\t\ttext.WriteString(msg.String(logger.OutputOptions{}, logger.TerminalInfo{}))\n\t}\n\treturn text.String()\n}\n\nfunc TestTokens(t *testing.T) {\n\texpected := []struct {\n\t\tcontents string\n\t\ttext     string\n\t\ttoken    T\n\t}{\n\t\t{\"\", \"end of file\", TEndOfFile},\n\t\t{\"@media\", \"@-keyword\", TAtKeyword},\n\t\t{\"url(x y\", \"bad URL token\", TBadURL},\n\t\t{\"-->\", \"\\\"-->\\\"\", TCDC},\n\t\t{\"<!--\", \"\\\"<!--\\\"\", TCDO},\n\t\t{\"}\", \"\\\"}\\\"\", TCloseBrace},\n\t\t{\"]\", \"\\\"]\\\"\", TCloseBracket},\n\t\t{\")\", \"\\\")\\\"\", TCloseParen},\n\t\t{\":\", \"\\\":\\\"\", TColon},\n\t\t{\",\", \"\\\",\\\"\", TComma},\n\t\t{\"?\", \"delimiter\", TDelim},\n\t\t{\"&\", \"\\\"&\\\"\", TDelimAmpersand},\n\t\t{\"*\", \"\\\"*\\\"\", TDelimAsterisk},\n\t\t{\"|\", \"\\\"|\\\"\", TDelimBar},\n\t\t{\"^\", \"\\\"^\\\"\", TDelimCaret},\n\t\t{\"$\", \"\\\"$\\\"\", TDelimDollar},\n\t\t{\".\", \"\\\".\\\"\", TDelimDot},\n\t\t{\"=\", \"\\\"=\\\"\", TDelimEquals},\n\t\t{\"!\", \"\\\"!\\\"\", TDelimExclamation},\n\t\t{\">\", \"\\\">\\\"\", TDelimGreaterThan},\n\t\t{\"+\", \"\\\"+\\\"\", TDelimPlus},\n\t\t{\"/\", \"\\\"/\\\"\", TDelimSlash},\n\t\t{\"~\", \"\\\"~\\\"\", TDelimTilde},\n\t\t{\"1px\", \"dimension\", TDimension},\n\t\t{\"max(\", \"function token\", TFunction},\n\t\t{\"#name\", \"hash token\", THash},\n\t\t{\"name\", \"identifier\", TIdent},\n\t\t{\"123\", \"number\", TNumber},\n\t\t{\"{\", \"\\\"{\\\"\", TOpenBrace},\n\t\t{\"[\", \"\\\"[\\\"\", TOpenBracket},\n\t\t{\"(\", \"\\\"(\\\"\", TOpenParen},\n\t\t{\"50%\", \"percentage\", TPercentage},\n\t\t{\";\", \"\\\";\\\"\", TSemicolon},\n\t\t{\"'abc'\", \"string token\", TString},\n\t\t{\"url(test)\", \"URL token\", TURL},\n\t\t{\" \", \"whitespace\", TWhitespace},\n\t}\n\n\tfor _, it := range expected {\n\t\tcontents := it.contents\n\t\ttoken := it.token\n\t\tt.Run(contents, func(t *testing.T) {\n\t\t\tkind, _ := lexToken(contents)\n\t\t\ttest.AssertEqual(t, kind, token)\n\t\t})\n\t}\n}\n\nfunc TestStringParsing(t *testing.T) {\n\tcontentsOfStringToken := func(contents string) string {\n\t\tt.Helper()\n\t\tkind, text := lexToken(contents)\n\t\ttest.AssertEqual(t, kind, TString)\n\t\treturn text\n\t}\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"foo\\\"\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\oo\\\"\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\\\\"o\\\"\"), \"f\\\"o\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\\\\\o\\\"\"), \"f\\\\o\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\\\no\\\"\"), \"fo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\\\ro\\\"\"), \"fo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\\\r\\no\\\"\"), \"fo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\\\fo\\\"\"), \"fo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\6fo\\\"\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\6f o\\\"\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\6f  o\\\"\"), \"fo o\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\fffffffo\\\"\"), \"f\\uFFFDfo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\10abcdeo\\\"\"), \"f\\U0010ABCDeo\")\n}\n\nfunc TestURLParsing(t *testing.T) {\n\tcontentsOfURLToken := func(expected T, contents string) string {\n\t\tt.Helper()\n\t\tkind, text := lexToken(contents)\n\t\ttest.AssertEqual(t, kind, expected)\n\t\treturn text\n\t}\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(foo)\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(  foo\\t\\t)\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(f\\\\oo)\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(f\\\\\\\"o)\"), \"f\\\"o\")\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(f\\\\'o)\"), \"f'o\")\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(f\\\\)o)\"), \"f)o\")\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(f\\\\6fo)\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(f\\\\6f o)\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfURLToken(TBadURL, \"url(f\\\\6f  o)\"), \"url(f\\\\6f  o)\")\n}\n\nfunc TestComment(t *testing.T) {\n\ttest.AssertEqualWithDiff(t, lexerError(\"/*\"), \"<stdin>: ERROR: Expected \\\"*/\\\" to terminate multi-line comment\\n<stdin>: NOTE: The multi-line comment starts here:\\n\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"/*/\"), \"<stdin>: ERROR: Expected \\\"*/\\\" to terminate multi-line comment\\n<stdin>: NOTE: The multi-line comment starts here:\\n\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"/**/\"), \"\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"//\"), \"<stdin>: WARNING: Comments in CSS use \\\"/* ... */\\\" instead of \\\"//\\\"\\n\")\n}\n\nfunc TestString(t *testing.T) {\n\ttest.AssertEqualWithDiff(t, lexerError(\"'\"), \"<stdin>: WARNING: Unterminated string token\\n\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"\\\"\"), \"<stdin>: WARNING: Unterminated string token\\n\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"'\\\\'\"), \"<stdin>: WARNING: Unterminated string token\\n\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"\\\"\\\\\\\"\"), \"<stdin>: WARNING: Unterminated string token\\n\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"''\"), \"\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"\\\"\\\"\"), \"\")\n}\n\nfunc TestBOM(t *testing.T) {\n\t// A byte order mark should not be parsed as an identifier\n\tkind, _ := lexToken(\"\\uFEFF.\")\n\ttest.AssertEqual(t, kind, TDelimDot)\n}\n"
  },
  {
    "path": "internal/css_parser/css_color_spaces.go",
    "content": "package css_parser\n\nimport (\n\t\"math\"\n\n\t\"github.com/evanw/esbuild/internal/helpers\"\n)\n\n// Wrap float64 math to avoid compiler optimizations that break determinism\ntype F64 = helpers.F64\n\n// Reference: https://drafts.csswg.org/css-color/#color-conversion-code\n\ntype colorSpace uint8\n\nconst (\n\tcolorSpace_a98_rgb colorSpace = iota\n\tcolorSpace_display_p3\n\tcolorSpace_hsl\n\tcolorSpace_hwb\n\tcolorSpace_lab\n\tcolorSpace_lch\n\tcolorSpace_oklab\n\tcolorSpace_oklch\n\tcolorSpace_prophoto_rgb\n\tcolorSpace_rec2020\n\tcolorSpace_srgb\n\tcolorSpace_srgb_linear\n\tcolorSpace_xyz\n\tcolorSpace_xyz_d50\n\tcolorSpace_xyz_d65\n)\n\nfunc (colorSpace colorSpace) isPolar() bool {\n\tswitch colorSpace {\n\tcase colorSpace_hsl, colorSpace_hwb, colorSpace_lch, colorSpace_oklch:\n\t\treturn true\n\t}\n\treturn false\n}\n\ntype hueMethod uint8\n\nconst (\n\tshorterHue hueMethod = iota\n\tlongerHue\n\tincreasingHue\n\tdecreasingHue\n)\n\nfunc lin_srgb(r F64, g F64, b F64) (F64, F64, F64) {\n\tf := func(val F64) F64 {\n\t\tif abs := val.Abs(); abs.Value() < 0.04045 {\n\t\t\treturn val.DivConst(12.92)\n\t\t} else {\n\t\t\treturn abs.AddConst(0.055).DivConst(1.055).PowConst(2.4).WithSignFrom(val)\n\t\t}\n\t}\n\treturn f(r), f(g), f(b)\n}\n\nfunc gam_srgb(r F64, g F64, b F64) (F64, F64, F64) {\n\tf := func(val F64) F64 {\n\t\tif abs := val.Abs(); abs.Value() > 0.0031308 {\n\t\t\treturn abs.PowConst(1 / 2.4).MulConst(1.055).SubConst(0.055).WithSignFrom(val)\n\t\t} else {\n\t\t\treturn val.MulConst(12.92)\n\t\t}\n\t}\n\treturn f(r), f(g), f(b)\n}\n\nfunc lin_srgb_to_xyz(r F64, g F64, b F64) (F64, F64, F64) {\n\tM := [9]float64{\n\t\t506752.0 / 1228815, 87881.0 / 245763, 12673.0 / 70218,\n\t\t87098.0 / 409605, 175762.0 / 245763, 12673.0 / 175545,\n\t\t7918.0 / 409605, 87881.0 / 737289, 1001167.0 / 1053270,\n\t}\n\treturn multiplyMatrices(M, r, g, b)\n}\n\nfunc xyz_to_lin_srgb(x F64, y F64, z F64) (F64, F64, F64) {\n\tM := [9]float64{\n\t\t12831.0 / 3959, -329.0 / 214, -1974.0 / 3959,\n\t\t-851781.0 / 878810, 1648619.0 / 878810, 36519.0 / 878810,\n\t\t705.0 / 12673, -2585.0 / 12673, 705.0 / 667,\n\t}\n\treturn multiplyMatrices(M, x, y, z)\n}\n\nfunc lin_p3(r F64, g F64, b F64) (F64, F64, F64) {\n\treturn lin_srgb(r, g, b)\n}\n\nfunc gam_p3(r F64, g F64, b F64) (F64, F64, F64) {\n\treturn gam_srgb(r, g, b)\n}\n\nfunc lin_p3_to_xyz(r F64, g F64, b F64) (F64, F64, F64) {\n\tM := [9]float64{\n\t\t608311.0 / 1250200, 189793.0 / 714400, 198249.0 / 1000160,\n\t\t35783.0 / 156275, 247089.0 / 357200, 198249.0 / 2500400,\n\t\t0.0 / 1, 32229.0 / 714400, 5220557.0 / 5000800,\n\t}\n\treturn multiplyMatrices(M, r, g, b)\n}\n\nfunc xyz_to_lin_p3(x F64, y F64, z F64) (F64, F64, F64) {\n\tM := [9]float64{\n\t\t446124.0 / 178915, -333277.0 / 357830, -72051.0 / 178915,\n\t\t-14852.0 / 17905, 63121.0 / 35810, 423.0 / 17905,\n\t\t11844.0 / 330415, -50337.0 / 660830, 316169.0 / 330415,\n\t}\n\treturn multiplyMatrices(M, x, y, z)\n}\n\nfunc lin_prophoto(r F64, g F64, b F64) (F64, F64, F64) {\n\tf := func(val F64) F64 {\n\t\tconst Et2 = 16.0 / 512\n\t\tif abs := val.Abs(); abs.Value() <= Et2 {\n\t\t\treturn val.DivConst(16)\n\t\t} else {\n\t\t\treturn abs.PowConst(1.8).WithSignFrom(val)\n\t\t}\n\t}\n\treturn f(r), f(g), f(b)\n}\n\nfunc gam_prophoto(r F64, g F64, b F64) (F64, F64, F64) {\n\tf := func(val F64) F64 {\n\t\tconst Et = 1.0 / 512\n\t\tif abs := val.Abs(); abs.Value() >= Et {\n\t\t\treturn abs.PowConst(1 / 1.8).WithSignFrom(val)\n\t\t} else {\n\t\t\treturn val.MulConst(16)\n\t\t}\n\t}\n\treturn f(r), f(g), f(b)\n}\n\nfunc lin_prophoto_to_xyz(r F64, g F64, b F64) (F64, F64, F64) {\n\tM := [9]float64{\n\t\t0.7977604896723027, 0.13518583717574031, 0.0313493495815248,\n\t\t0.2880711282292934, 0.7118432178101014, 0.00008565396060525902,\n\t\t0.0, 0.0, 0.8251046025104601,\n\t}\n\treturn multiplyMatrices(M, r, g, b)\n}\n\nfunc xyz_to_lin_prophoto(x F64, y F64, z F64) (F64, F64, F64) {\n\tM := [9]float64{\n\t\t1.3457989731028281, -0.25558010007997534, -0.05110628506753401,\n\t\t-0.5446224939028347, 1.5082327413132781, 0.02053603239147973,\n\t\t0.0, 0.0, 1.2119675456389454,\n\t}\n\treturn multiplyMatrices(M, x, y, z)\n}\n\nfunc lin_a98rgb(r F64, g F64, b F64) (F64, F64, F64) {\n\tf := func(val F64) F64 {\n\t\treturn val.Abs().PowConst(563.0 / 256).WithSignFrom(val)\n\t}\n\treturn f(r), f(g), f(b)\n}\n\nfunc gam_a98rgb(r F64, g F64, b F64) (F64, F64, F64) {\n\tf := func(val F64) F64 {\n\t\treturn val.Abs().PowConst(256.0 / 563).WithSignFrom(val)\n\t}\n\treturn f(r), f(g), f(b)\n}\n\nfunc lin_a98rgb_to_xyz(r F64, g F64, b F64) (F64, F64, F64) {\n\tM := [9]float64{\n\t\t573536.0 / 994567, 263643.0 / 1420810, 187206.0 / 994567,\n\t\t591459.0 / 1989134, 6239551.0 / 9945670, 374412.0 / 4972835,\n\t\t53769.0 / 1989134, 351524.0 / 4972835, 4929758.0 / 4972835,\n\t}\n\treturn multiplyMatrices(M, r, g, b)\n}\n\nfunc xyz_to_lin_a98rgb(x F64, y F64, z F64) (F64, F64, F64) {\n\tM := [9]float64{\n\t\t1829569.0 / 896150, -506331.0 / 896150, -308931.0 / 896150,\n\t\t-851781.0 / 878810, 1648619.0 / 878810, 36519.0 / 878810,\n\t\t16779.0 / 1248040, -147721.0 / 1248040, 1266979.0 / 1248040,\n\t}\n\treturn multiplyMatrices(M, x, y, z)\n}\n\nfunc lin_2020(r F64, g F64, b F64) (F64, F64, F64) {\n\tf := func(val F64) F64 {\n\t\tconst α = 1.09929682680944\n\t\tconst β = 0.018053968510807\n\t\tif abs := val.Abs(); abs.Value() < β*4.5 {\n\t\t\treturn val.DivConst(4.5)\n\t\t} else {\n\t\t\treturn abs.AddConst(α - 1).DivConst(α).PowConst(1 / 0.45).WithSignFrom(val)\n\t\t}\n\t}\n\treturn f(r), f(g), f(b)\n}\n\nfunc gam_2020(r F64, g F64, b F64) (F64, F64, F64) {\n\tf := func(val F64) F64 {\n\t\tconst α = 1.09929682680944\n\t\tconst β = 0.018053968510807\n\t\tif abs := val.Abs(); abs.Value() > β {\n\t\t\treturn abs.PowConst(0.45).MulConst(α).SubConst(α - 1).WithSignFrom(val)\n\t\t} else {\n\t\t\treturn val.MulConst(4.5)\n\t\t}\n\t}\n\treturn f(r), f(g), f(b)\n}\n\nfunc lin_2020_to_xyz(r F64, g F64, b F64) (F64, F64, F64) {\n\tvar M = [9]float64{\n\t\t63426534.0 / 99577255, 20160776.0 / 139408157, 47086771.0 / 278816314,\n\t\t26158966.0 / 99577255, 472592308.0 / 697040785, 8267143.0 / 139408157,\n\t\t0.0 / 1, 19567812.0 / 697040785, 295819943.0 / 278816314,\n\t}\n\treturn multiplyMatrices(M, r, g, b)\n}\n\nfunc xyz_to_lin_2020(x F64, y F64, z F64) (F64, F64, F64) {\n\tM := [9]float64{\n\t\t30757411.0 / 17917100, -6372589.0 / 17917100, -4539589.0 / 17917100,\n\t\t-19765991.0 / 29648200, 47925759.0 / 29648200, 467509.0 / 29648200,\n\t\t792561.0 / 44930125, -1921689.0 / 44930125, 42328811.0 / 44930125,\n\t}\n\treturn multiplyMatrices(M, x, y, z)\n}\n\nfunc d65_to_d50(x F64, y F64, z F64) (F64, F64, F64) {\n\tM := [9]float64{\n\t\t1.0479297925449969, 0.022946870601609652, -0.05019226628920524,\n\t\t0.02962780877005599, 0.9904344267538799, -0.017073799063418826,\n\t\t-0.009243040646204504, 0.015055191490298152, 0.7518742814281371,\n\t}\n\treturn multiplyMatrices(M, x, y, z)\n}\n\nfunc d50_to_d65(x F64, y F64, z F64) (F64, F64, F64) {\n\tM := [9]float64{\n\t\t0.955473421488075, -0.02309845494876471, 0.06325924320057072,\n\t\t-0.0283697093338637, 1.0099953980813041, 0.021041441191917323,\n\t\t0.012314014864481998, -0.020507649298898964, 1.330365926242124,\n\t}\n\treturn multiplyMatrices(M, x, y, z)\n}\n\nconst d50_x = 0.3457 / 0.3585\nconst d50_z = (1.0 - 0.3457 - 0.3585) / 0.3585\n\nfunc xyz_to_lab(x F64, y F64, z F64) (F64, F64, F64) {\n\tconst ε = 216.0 / 24389\n\tconst κ = 24389.0 / 27\n\n\tx = x.DivConst(d50_x)\n\tz = z.DivConst(d50_z)\n\n\tvar f0, f1, f2 F64\n\tif x.Value() > ε {\n\t\tf0 = x.Cbrt()\n\t} else {\n\t\tf0 = x.MulConst(κ).AddConst(16).DivConst(116)\n\t}\n\tif y.Value() > ε {\n\t\tf1 = y.Cbrt()\n\t} else {\n\t\tf1 = y.MulConst(κ).AddConst(16).DivConst(116)\n\t}\n\tif z.Value() > ε {\n\t\tf2 = z.Cbrt()\n\t} else {\n\t\tf2 = z.MulConst(κ).AddConst(16).DivConst(116)\n\t}\n\n\treturn f1.MulConst(116).SubConst(16),\n\t\tf0.Sub(f1).MulConst(500),\n\t\tf1.Sub(f2).MulConst(200)\n}\n\nfunc lab_to_xyz(l F64, a F64, b F64) (x F64, y F64, z F64) {\n\tconst κ = 24389.0 / 27\n\tconst ε = 216.0 / 24389\n\n\tf1 := l.AddConst(16).DivConst(116)\n\tf0 := a.DivConst(500).Add(f1)\n\tf2 := f1.Sub(b.DivConst(200))\n\n\tf0_3 := f0.Cubed()\n\tf2_3 := f2.Cubed()\n\n\tif f0_3.Value() > ε {\n\t\tx = f0_3\n\t} else {\n\t\tx = f0.MulConst(116).SubConst(16).DivConst(κ)\n\t}\n\tif l.Value() > κ*ε {\n\t\ty = l.AddConst(16).DivConst(116)\n\t\ty = y.Cubed()\n\t} else {\n\t\ty = l.DivConst(κ)\n\t}\n\tif f2_3.Value() > ε {\n\t\tz = f2_3\n\t} else {\n\t\tz = f2.MulConst(116).SubConst(16).DivConst(κ)\n\t}\n\n\treturn x.MulConst(d50_x), y, z.MulConst(d50_z)\n}\n\nfunc lab_to_lch(l F64, a F64, b F64) (F64, F64, F64) {\n\thue := b.Atan2(a).MulConst(180 / math.Pi)\n\tif hue.Value() < 0 {\n\t\thue = hue.AddConst(360)\n\t}\n\treturn l,\n\t\ta.Squared().Add(b.Squared()).Sqrt(),\n\t\thue\n}\n\nfunc lch_to_lab(l F64, c F64, h F64) (F64, F64, F64) {\n\treturn l,\n\t\th.MulConst(math.Pi / 180).Cos().Mul(c),\n\t\th.MulConst(math.Pi / 180).Sin().Mul(c)\n}\n\nfunc xyz_to_oklab(x F64, y F64, z F64) (F64, F64, F64) {\n\tXYZtoLMS := [9]float64{\n\t\t0.8190224432164319, 0.3619062562801221, -0.12887378261216414,\n\t\t0.0329836671980271, 0.9292868468965546, 0.03614466816999844,\n\t\t0.048177199566046255, 0.26423952494422764, 0.6335478258136937,\n\t}\n\tLMStoOKLab := [9]float64{\n\t\t0.2104542553, 0.7936177850, -0.0040720468,\n\t\t1.9779984951, -2.4285922050, 0.4505937099,\n\t\t0.0259040371, 0.7827717662, -0.8086757660,\n\t}\n\tl, m, s := multiplyMatrices(XYZtoLMS, x, y, z)\n\treturn multiplyMatrices(LMStoOKLab, l.Cbrt(), m.Cbrt(), s.Cbrt())\n}\n\nfunc oklab_to_xyz(l F64, a F64, b F64) (F64, F64, F64) {\n\tLMStoXYZ := [9]float64{\n\t\t1.2268798733741557, -0.5578149965554813, 0.28139105017721583,\n\t\t-0.04057576262431372, 1.1122868293970594, -0.07171106666151701,\n\t\t-0.07637294974672142, -0.4214933239627914, 1.5869240244272418,\n\t}\n\tOKLabtoLMS := [9]float64{\n\t\t0.99999999845051981432, 0.39633779217376785678, 0.21580375806075880339,\n\t\t1.0000000088817607767, -0.1055613423236563494, -0.063854174771705903402,\n\t\t1.0000000546724109177, -0.089484182094965759684, -1.2914855378640917399,\n\t}\n\tl, m, s := multiplyMatrices(OKLabtoLMS, l, a, b)\n\treturn multiplyMatrices(LMStoXYZ, l.Cubed(), m.Cubed(), s.Cubed())\n}\n\nfunc oklab_to_oklch(l F64, a F64, b F64) (F64, F64, F64) {\n\treturn lab_to_lch(l, a, b)\n}\n\nfunc oklch_to_oklab(l F64, c F64, h F64) (F64, F64, F64) {\n\treturn lch_to_lab(l, c, h)\n}\n\nfunc multiplyMatrices(A [9]float64, b0 F64, b1 F64, b2 F64) (F64, F64, F64) {\n\treturn b0.MulConst(A[0]).Add(b1.MulConst(A[1])).Add(b2.MulConst(A[2])),\n\t\tb0.MulConst(A[3]).Add(b1.MulConst(A[4])).Add(b2.MulConst(A[5])),\n\t\tb0.MulConst(A[6]).Add(b1.MulConst(A[7])).Add(b2.MulConst(A[8]))\n}\n\nfunc delta_eok(L1 F64, a1 F64, b1 F64, L2 F64, a2 F64, b2 F64) F64 {\n\tΔL_sq := L1.Sub(L2).Squared()\n\tΔa_sq := a1.Sub(a2).Squared()\n\tΔb_sq := b1.Sub(b2).Squared()\n\treturn ΔL_sq.Add(Δa_sq).Add(Δb_sq).Sqrt()\n}\n\nfunc gamut_mapping_xyz_to_srgb(x F64, y F64, z F64) (F64, F64, F64) {\n\torigin_l, origin_c, origin_h := oklab_to_oklch(xyz_to_oklab(x, y, z))\n\n\tif origin_l.Value() >= 1 || origin_l.Value() <= 0 {\n\t\treturn origin_l, origin_l, origin_l\n\t}\n\n\toklch_to_srgb := func(l F64, c F64, h F64) (F64, F64, F64) {\n\t\tl, a, b := oklch_to_oklab(l, c, h)\n\t\tx, y, z := oklab_to_xyz(l, a, b)\n\t\tr, g, b := xyz_to_lin_srgb(x, y, z)\n\t\treturn gam_srgb(r, g, b)\n\t}\n\n\tsrgb_to_oklab := func(r F64, g F64, b F64) (F64, F64, F64) {\n\t\tr, g, b = lin_srgb(r, g, b)\n\t\tx, y, z := lin_srgb_to_xyz(r, g, b)\n\t\treturn xyz_to_oklab(x, y, z)\n\t}\n\n\tinGamut := func(r F64, g F64, b F64) bool {\n\t\treturn r.Value() >= 0 && r.Value() <= 1 &&\n\t\t\tg.Value() >= 0 && g.Value() <= 1 &&\n\t\t\tb.Value() >= 0 && b.Value() <= 1\n\t}\n\n\tr, g, b := oklch_to_srgb(origin_l, origin_c, origin_h)\n\tif inGamut(r, g, b) {\n\t\treturn r, g, b\n\t}\n\n\tconst JND = 0.02\n\tconst epsilon = 0.0001\n\tmin := helpers.NewF64(0.0)\n\tmax := origin_c\n\n\tclip := func(x F64) F64 {\n\t\tif x.Value() < 0 {\n\t\t\treturn helpers.NewF64(0)\n\t\t}\n\t\tif x.Value() > 1 {\n\t\t\treturn helpers.NewF64(1)\n\t\t}\n\t\treturn x\n\t}\n\n\tfor max.Sub(min).Value() > epsilon {\n\t\tchroma := min.Add(max).DivConst(2)\n\t\torigin_c = chroma\n\n\t\tr, g, b = oklch_to_srgb(origin_l, origin_c, origin_h)\n\t\tif inGamut(r, g, b) {\n\t\t\tmin = chroma\n\t\t\tcontinue\n\t\t}\n\n\t\tclipped_r, clipped_g, clipped_b := clip(r), clip(g), clip(b)\n\t\tL1, a1, b1 := srgb_to_oklab(clipped_r, clipped_b, clipped_g)\n\t\tL2, a2, b2 := srgb_to_oklab(r, g, b)\n\t\tE := delta_eok(L1, a1, b1, L2, a2, b2)\n\t\tif E.Value() < JND {\n\t\t\treturn clipped_r, clipped_g, clipped_b\n\t\t}\n\n\t\tmax = chroma\n\t}\n\n\treturn r, g, b\n}\n\nfunc hsl_to_rgb(hue F64, sat F64, light F64) (F64, F64, F64) {\n\thue = hue.DivConst(360)\n\thue = hue.Sub(hue.Floor())\n\thue = hue.MulConst(360)\n\n\tsat = sat.DivConst(100)\n\tlight = light.DivConst(100)\n\n\tf := func(n float64) F64 {\n\t\tk := hue.DivConst(30).AddConst(n)\n\t\tk = k.DivConst(12)\n\t\tk = k.Sub(k.Floor())\n\t\tk = k.MulConst(12)\n\t\ta := helpers.Min2(light, light.Neg().AddConst(1)).Mul(sat)\n\t\treturn light.Sub(helpers.Max2(helpers.NewF64(-1), helpers.Min3(k.SubConst(3), k.Neg().AddConst(9), helpers.NewF64(1))).Mul(a))\n\t}\n\n\treturn f(0), f(8), f(4)\n}\n\nfunc rgb_to_hsl(red F64, green F64, blue F64) (F64, F64, F64) {\n\tmax := helpers.Max3(red, green, blue)\n\tmin := helpers.Min3(red, green, blue)\n\thue, sat, light := helpers.NewF64(math.NaN()), helpers.NewF64(0.0), min.Add(max).DivConst(2)\n\td := max.Sub(min)\n\n\tif d.Value() != 0 {\n\t\tif div := helpers.Min2(light, light.Neg().AddConst(1)); div.Value() != 0 {\n\t\t\tsat = max.Sub(light).Div(div)\n\t\t}\n\n\t\tswitch max {\n\t\tcase red:\n\t\t\thue = green.Sub(blue).Div(d)\n\t\t\tif green.Value() < blue.Value() {\n\t\t\t\thue = hue.AddConst(6)\n\t\t\t}\n\t\tcase green:\n\t\t\thue = blue.Sub(red).Div(d).AddConst(2)\n\t\tcase blue:\n\t\t\thue = red.Sub(green).Div(d).AddConst(4)\n\t\t}\n\n\t\thue = hue.MulConst(60)\n\t}\n\n\treturn hue, sat.MulConst(100), light.MulConst(100)\n}\n\nfunc hwb_to_rgb(hue F64, white F64, black F64) (F64, F64, F64) {\n\twhite = white.DivConst(100)\n\tblack = black.DivConst(100)\n\tif white.Add(black).Value() >= 1 {\n\t\tgray := white.Div(white.Add(black))\n\t\treturn gray, gray, gray\n\t}\n\tdelta := white.Add(black).Neg().AddConst(1)\n\tr, g, b := hsl_to_rgb(hue, helpers.NewF64(100), helpers.NewF64(50))\n\tr = delta.Mul(r).Add(white)\n\tg = delta.Mul(g).Add(white)\n\tb = delta.Mul(b).Add(white)\n\treturn r, g, b\n}\n\nfunc rgb_to_hwb(red F64, green F64, blue F64) (F64, F64, F64) {\n\th, _, _ := rgb_to_hsl(red, green, blue)\n\twhite := helpers.Min3(red, green, blue)\n\tblack := helpers.Max3(red, green, blue).Neg().AddConst(1)\n\treturn h, white.MulConst(100), black.MulConst(100)\n}\n\nfunc xyz_to_colorSpace(x F64, y F64, z F64, colorSpace colorSpace) (F64, F64, F64) {\n\tswitch colorSpace {\n\tcase colorSpace_a98_rgb:\n\t\treturn gam_a98rgb(xyz_to_lin_a98rgb(x, y, z))\n\n\tcase colorSpace_display_p3:\n\t\treturn gam_p3(xyz_to_lin_p3(x, y, z))\n\n\tcase colorSpace_hsl:\n\t\treturn rgb_to_hsl(gam_srgb(xyz_to_lin_srgb(x, y, z)))\n\n\tcase colorSpace_hwb:\n\t\treturn rgb_to_hwb(gam_srgb(xyz_to_lin_srgb(x, y, z)))\n\n\tcase colorSpace_lab:\n\t\treturn xyz_to_lab(d65_to_d50(x, y, z))\n\n\tcase colorSpace_lch:\n\t\treturn lab_to_lch(xyz_to_lab(d65_to_d50(x, y, z)))\n\n\tcase colorSpace_oklab:\n\t\treturn xyz_to_oklab(x, y, z)\n\n\tcase colorSpace_oklch:\n\t\treturn oklab_to_oklch(xyz_to_oklab(x, y, z))\n\n\tcase colorSpace_prophoto_rgb:\n\t\treturn gam_prophoto(xyz_to_lin_prophoto(d65_to_d50(x, y, z)))\n\n\tcase colorSpace_rec2020:\n\t\treturn gam_2020(xyz_to_lin_2020(x, y, z))\n\n\tcase colorSpace_srgb:\n\t\treturn gam_srgb(xyz_to_lin_srgb(x, y, z))\n\n\tcase colorSpace_srgb_linear:\n\t\treturn xyz_to_lin_srgb(x, y, z)\n\n\tcase colorSpace_xyz, colorSpace_xyz_d65:\n\t\treturn x, y, z\n\n\tcase colorSpace_xyz_d50:\n\t\treturn d65_to_d50(x, y, z)\n\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\nfunc colorSpace_to_xyz(v0 F64, v1 F64, v2 F64, colorSpace colorSpace) (F64, F64, F64) {\n\tswitch colorSpace {\n\tcase colorSpace_a98_rgb:\n\t\treturn lin_a98rgb_to_xyz(lin_a98rgb(v0, v1, v2))\n\n\tcase colorSpace_display_p3:\n\t\treturn lin_p3_to_xyz(lin_p3(v0, v1, v2))\n\n\tcase colorSpace_hsl:\n\t\treturn lin_srgb_to_xyz(lin_srgb(hsl_to_rgb(v0, v1, v2)))\n\n\tcase colorSpace_hwb:\n\t\treturn lin_srgb_to_xyz(lin_srgb(hwb_to_rgb(v0, v1, v2)))\n\n\tcase colorSpace_lab:\n\t\treturn d50_to_d65(lab_to_xyz(v0, v1, v2))\n\n\tcase colorSpace_lch:\n\t\treturn d50_to_d65(lab_to_xyz(lch_to_lab(v0, v1, v2)))\n\n\tcase colorSpace_oklab:\n\t\treturn oklab_to_xyz(v0, v1, v2)\n\n\tcase colorSpace_oklch:\n\t\treturn oklab_to_xyz(oklch_to_oklab(v0, v1, v2))\n\n\tcase colorSpace_prophoto_rgb:\n\t\treturn d50_to_d65(lin_prophoto_to_xyz(lin_prophoto(v0, v1, v2)))\n\n\tcase colorSpace_rec2020:\n\t\treturn lin_2020_to_xyz(lin_2020(v0, v1, v2))\n\n\tcase colorSpace_srgb:\n\t\treturn lin_srgb_to_xyz(lin_srgb(v0, v1, v2))\n\n\tcase colorSpace_srgb_linear:\n\t\treturn lin_srgb_to_xyz(v0, v1, v2)\n\n\tcase colorSpace_xyz, colorSpace_xyz_d65:\n\t\treturn v0, v1, v2\n\n\tcase colorSpace_xyz_d50:\n\t\treturn d50_to_d65(v0, v1, v2)\n\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n"
  },
  {
    "path": "internal/css_parser/css_decls.go",
    "content": "package css_parser\n\nimport (\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\nfunc (p *parser) commaToken(loc logger.Loc) css_ast.Token {\n\tt := css_ast.Token{\n\t\tLoc:  loc,\n\t\tKind: css_lexer.TComma,\n\t\tText: \",\",\n\t}\n\tif !p.options.minifyWhitespace {\n\t\tt.Whitespace = css_ast.WhitespaceAfter\n\t}\n\treturn t\n}\n\nfunc expandTokenQuad(tokens []css_ast.Token, allowedIdent string) (result [4]css_ast.Token, ok bool) {\n\tn := len(tokens)\n\tif n < 1 || n > 4 {\n\t\treturn\n\t}\n\n\t// Don't do this if we encounter any unexpected tokens such as \"var()\"\n\tfor i := 0; i < n; i++ {\n\t\tif t := tokens[i]; !t.Kind.IsNumeric() && (t.Kind != css_lexer.TIdent || allowedIdent == \"\" || t.Text != allowedIdent) {\n\t\t\treturn\n\t\t}\n\t}\n\n\tresult[0] = tokens[0]\n\tif n > 1 {\n\t\tresult[1] = tokens[1]\n\t} else {\n\t\tresult[1] = result[0]\n\t}\n\tif n > 2 {\n\t\tresult[2] = tokens[2]\n\t} else {\n\t\tresult[2] = result[0]\n\t}\n\tif n > 3 {\n\t\tresult[3] = tokens[3]\n\t} else {\n\t\tresult[3] = result[1]\n\t}\n\n\tok = true\n\treturn\n}\n\nfunc compactTokenQuad(a css_ast.Token, b css_ast.Token, c css_ast.Token, d css_ast.Token, minifyWhitespace bool) []css_ast.Token {\n\ttokens := []css_ast.Token{a, b, c, d}\n\tif tokens[3].EqualIgnoringWhitespace(tokens[1]) {\n\t\tif tokens[2].EqualIgnoringWhitespace(tokens[0]) {\n\t\t\tif tokens[1].EqualIgnoringWhitespace(tokens[0]) {\n\t\t\t\ttokens = tokens[:1]\n\t\t\t} else {\n\t\t\t\ttokens = tokens[:2]\n\t\t\t}\n\t\t} else {\n\t\t\ttokens = tokens[:3]\n\t\t}\n\t}\n\tfor i := range tokens {\n\t\tvar whitespace css_ast.WhitespaceFlags\n\t\tif !minifyWhitespace || i > 0 {\n\t\t\twhitespace |= css_ast.WhitespaceBefore\n\t\t}\n\t\tif i+1 < len(tokens) {\n\t\t\twhitespace |= css_ast.WhitespaceAfter\n\t\t}\n\t\ttokens[i].Whitespace = whitespace\n\t}\n\treturn tokens\n}\n\nfunc (p *parser) processDeclarations(rules []css_ast.Rule, composesContext *composesContext) (rewrittenRules []css_ast.Rule) {\n\tmargin := boxTracker{key: css_ast.DMargin, keyText: \"margin\", allowAuto: true}\n\tpadding := boxTracker{key: css_ast.DPadding, keyText: \"padding\", allowAuto: false}\n\tinset := boxTracker{key: css_ast.DInset, keyText: \"inset\", allowAuto: true}\n\tborderRadius := borderRadiusTracker{}\n\trewrittenRules = make([]css_ast.Rule, 0, len(rules))\n\tdidWarnAboutComposes := false\n\twouldClipColorFlag := false\n\tvar declarationKeys map[string]struct{}\n\n\t// Don't automatically generate the \"inset\" property if it's not supported\n\tif p.options.unsupportedCSSFeatures.Has(compat.InsetProperty) {\n\t\tinset.key = css_ast.DUnknown\n\t\tinset.keyText = \"\"\n\t}\n\n\t// If this is a local class selector, track which CSS properties it declares.\n\t// This is used to warn when CSS \"composes\" is used incorrectly.\n\tif composesContext != nil {\n\t\tfor _, ref := range composesContext.parentRefs {\n\t\t\tcomposes, ok := p.composes[ref]\n\t\t\tif !ok {\n\t\t\t\tcomposes = &css_ast.Composes{}\n\t\t\t\tp.composes[ref] = composes\n\t\t\t}\n\t\t\tproperties := composes.Properties\n\t\t\tif properties == nil {\n\t\t\t\tproperties = make(map[string]logger.Loc)\n\t\t\t\tcomposes.Properties = properties\n\t\t\t}\n\t\t\tfor _, rule := range rules {\n\t\t\t\tif decl, ok := rule.Data.(*css_ast.RDeclaration); ok && decl.Key != css_ast.DComposes {\n\t\t\t\t\tproperties[decl.KeyText] = decl.KeyRange.Loc\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfor i := 0; i < len(rules); i++ {\n\t\trule := rules[i]\n\t\trewrittenRules = append(rewrittenRules, rule)\n\t\tdecl, ok := rule.Data.(*css_ast.RDeclaration)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\t// If the previous loop iteration would have clipped a color, we will\n\t\t// duplicate it and insert the clipped copy before the unclipped copy\n\t\tvar wouldClipColor *bool\n\t\tif wouldClipColorFlag {\n\t\t\twouldClipColorFlag = false\n\t\t\tclone := *decl\n\t\t\tclone.Value = css_ast.CloneTokensWithoutImportRecords(clone.Value)\n\t\t\tdecl = &clone\n\t\t\trule.Data = decl\n\t\t\tn := len(rewrittenRules) - 2\n\t\t\trewrittenRules = append(rewrittenRules[:n], rule, rewrittenRules[n])\n\t\t} else {\n\t\t\twouldClipColor = &wouldClipColorFlag\n\t\t}\n\n\t\tswitch decl.Key {\n\t\tcase css_ast.DComposes:\n\t\t\t// Only process \"composes\" directives if we're in \"local-css\" or\n\t\t\t// \"global-css\" mode. In these cases, \"composes\" directives will always\n\t\t\t// be removed (because they are being processed) even if they contain\n\t\t\t// errors. Otherwise we leave \"composes\" directives there untouched and\n\t\t\t// don't check them for errors.\n\t\t\tif p.options.symbolMode != symbolModeDisabled {\n\t\t\t\tif composesContext == nil {\n\t\t\t\t\tif !didWarnAboutComposes {\n\t\t\t\t\t\tdidWarnAboutComposes = true\n\t\t\t\t\t\tp.log.AddID(logger.MsgID_CSS_CSSSyntaxError, logger.Warning, &p.tracker, decl.KeyRange, \"\\\"composes\\\" is not valid here\")\n\t\t\t\t\t}\n\t\t\t\t} else if composesContext.problemRange.Len > 0 {\n\t\t\t\t\tif !didWarnAboutComposes {\n\t\t\t\t\t\tdidWarnAboutComposes = true\n\t\t\t\t\t\tp.log.AddIDWithNotes(logger.MsgID_CSS_CSSSyntaxError, logger.Warning, &p.tracker, decl.KeyRange, \"\\\"composes\\\" only works inside single class selectors\",\n\t\t\t\t\t\t\t[]logger.MsgData{p.tracker.MsgData(composesContext.problemRange, \"The parent selector is not a single class selector because of the syntax here:\")})\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tp.handleComposesPragma(*composesContext, decl.Value)\n\t\t\t\t}\n\t\t\t\trewrittenRules = rewrittenRules[:len(rewrittenRules)-1]\n\t\t\t}\n\n\t\tcase css_ast.DBackground:\n\t\t\tfor i, t := range decl.Value {\n\t\t\t\tt = p.lowerAndMinifyColor(t, wouldClipColor)\n\t\t\t\tt = p.lowerAndMinifyGradient(t, wouldClipColor)\n\t\t\t\tdecl.Value[i] = t\n\t\t\t}\n\n\t\tcase css_ast.DBackgroundImage,\n\t\t\tcss_ast.DBorderImage,\n\t\t\tcss_ast.DMaskImage:\n\n\t\t\tfor i, t := range decl.Value {\n\t\t\t\tt = p.lowerAndMinifyGradient(t, wouldClipColor)\n\t\t\t\tdecl.Value[i] = t\n\t\t\t}\n\n\t\tcase css_ast.DBackgroundColor,\n\t\t\tcss_ast.DBorderBlockEndColor,\n\t\t\tcss_ast.DBorderBlockStartColor,\n\t\t\tcss_ast.DBorderBottomColor,\n\t\t\tcss_ast.DBorderColor,\n\t\t\tcss_ast.DBorderInlineEndColor,\n\t\t\tcss_ast.DBorderInlineStartColor,\n\t\t\tcss_ast.DBorderLeftColor,\n\t\t\tcss_ast.DBorderRightColor,\n\t\t\tcss_ast.DBorderTopColor,\n\t\t\tcss_ast.DCaretColor,\n\t\t\tcss_ast.DColor,\n\t\t\tcss_ast.DColumnRuleColor,\n\t\t\tcss_ast.DFill,\n\t\t\tcss_ast.DFloodColor,\n\t\t\tcss_ast.DLightingColor,\n\t\t\tcss_ast.DOutlineColor,\n\t\t\tcss_ast.DStopColor,\n\t\t\tcss_ast.DStroke,\n\t\t\tcss_ast.DTextDecorationColor,\n\t\t\tcss_ast.DTextEmphasisColor:\n\n\t\t\tif len(decl.Value) == 1 {\n\t\t\t\tdecl.Value[0] = p.lowerAndMinifyColor(decl.Value[0], wouldClipColor)\n\t\t\t}\n\n\t\tcase css_ast.DTransform:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tdecl.Value = p.mangleTransforms(decl.Value)\n\t\t\t}\n\n\t\tcase css_ast.DBoxShadow:\n\t\t\tdecl.Value = p.lowerAndMangleBoxShadows(decl.Value, wouldClipColor)\n\n\t\t// Container name\n\t\tcase css_ast.DContainer:\n\t\t\tp.processContainerShorthand(decl.Value)\n\t\tcase css_ast.DContainerName:\n\t\t\tp.processContainerName(decl.Value)\n\n\t\t// Animation name\n\t\tcase css_ast.DAnimation:\n\t\t\tp.processAnimationShorthand(decl.Value)\n\t\tcase css_ast.DAnimationName:\n\t\t\tp.processAnimationName(decl.Value)\n\n\t\t// List style\n\t\tcase css_ast.DListStyle:\n\t\t\tp.processListStyleShorthand(decl.Value)\n\t\tcase css_ast.DListStyleType:\n\t\t\tif len(decl.Value) == 1 {\n\t\t\t\tp.processListStyleType(&decl.Value[0])\n\t\t\t}\n\n\t\t// Font\n\t\tcase css_ast.DFont:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tdecl.Value = p.mangleFont(decl.Value)\n\t\t\t}\n\t\tcase css_ast.DFontFamily:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tif value, ok := p.mangleFontFamily(decl.Value); ok {\n\t\t\t\t\tdecl.Value = value\n\t\t\t\t}\n\t\t\t}\n\t\tcase css_ast.DFontWeight:\n\t\t\tif len(decl.Value) == 1 && p.options.minifySyntax {\n\t\t\t\tdecl.Value[0] = p.mangleFontWeight(decl.Value[0])\n\t\t\t}\n\n\t\t// Margin\n\t\tcase css_ast.DMargin:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tmargin.mangleSides(rewrittenRules, decl, p.options.minifyWhitespace)\n\t\t\t}\n\t\tcase css_ast.DMarginTop:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tmargin.mangleSide(rewrittenRules, decl, p.options.minifyWhitespace, boxTop)\n\t\t\t}\n\t\tcase css_ast.DMarginRight:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tmargin.mangleSide(rewrittenRules, decl, p.options.minifyWhitespace, boxRight)\n\t\t\t}\n\t\tcase css_ast.DMarginBottom:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tmargin.mangleSide(rewrittenRules, decl, p.options.minifyWhitespace, boxBottom)\n\t\t\t}\n\t\tcase css_ast.DMarginLeft:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tmargin.mangleSide(rewrittenRules, decl, p.options.minifyWhitespace, boxLeft)\n\t\t\t}\n\n\t\t// Padding\n\t\tcase css_ast.DPadding:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tpadding.mangleSides(rewrittenRules, decl, p.options.minifyWhitespace)\n\t\t\t}\n\t\tcase css_ast.DPaddingTop:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tpadding.mangleSide(rewrittenRules, decl, p.options.minifyWhitespace, boxTop)\n\t\t\t}\n\t\tcase css_ast.DPaddingRight:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tpadding.mangleSide(rewrittenRules, decl, p.options.minifyWhitespace, boxRight)\n\t\t\t}\n\t\tcase css_ast.DPaddingBottom:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tpadding.mangleSide(rewrittenRules, decl, p.options.minifyWhitespace, boxBottom)\n\t\t\t}\n\t\tcase css_ast.DPaddingLeft:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tpadding.mangleSide(rewrittenRules, decl, p.options.minifyWhitespace, boxLeft)\n\t\t\t}\n\n\t\t// Inset\n\t\tcase css_ast.DInset:\n\t\t\tif p.options.unsupportedCSSFeatures.Has(compat.InsetProperty) {\n\t\t\t\tif decls, ok := p.lowerInset(rule.Loc, decl); ok {\n\t\t\t\t\trewrittenRules = rewrittenRules[:len(rewrittenRules)-1]\n\t\t\t\t\tfor i := range decls {\n\t\t\t\t\t\trewrittenRules = append(rewrittenRules, decls[i])\n\t\t\t\t\t\tif p.options.minifySyntax {\n\t\t\t\t\t\t\tinset.mangleSide(rewrittenRules, decls[i].Data.(*css_ast.RDeclaration), p.options.minifyWhitespace, i)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tinset.mangleSides(rewrittenRules, decl, p.options.minifyWhitespace)\n\t\t\t}\n\t\tcase css_ast.DTop:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tinset.mangleSide(rewrittenRules, decl, p.options.minifyWhitespace, boxTop)\n\t\t\t}\n\t\tcase css_ast.DRight:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tinset.mangleSide(rewrittenRules, decl, p.options.minifyWhitespace, boxRight)\n\t\t\t}\n\t\tcase css_ast.DBottom:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tinset.mangleSide(rewrittenRules, decl, p.options.minifyWhitespace, boxBottom)\n\t\t\t}\n\t\tcase css_ast.DLeft:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tinset.mangleSide(rewrittenRules, decl, p.options.minifyWhitespace, boxLeft)\n\t\t\t}\n\n\t\t// Border radius\n\t\tcase css_ast.DBorderRadius:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tborderRadius.mangleCorners(rewrittenRules, decl, p.options.minifyWhitespace)\n\t\t\t}\n\t\tcase css_ast.DBorderTopLeftRadius:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tborderRadius.mangleCorner(rewrittenRules, decl, p.options.minifyWhitespace, borderRadiusTopLeft)\n\t\t\t}\n\t\tcase css_ast.DBorderTopRightRadius:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tborderRadius.mangleCorner(rewrittenRules, decl, p.options.minifyWhitespace, borderRadiusTopRight)\n\t\t\t}\n\t\tcase css_ast.DBorderBottomRightRadius:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tborderRadius.mangleCorner(rewrittenRules, decl, p.options.minifyWhitespace, borderRadiusBottomRight)\n\t\t\t}\n\t\tcase css_ast.DBorderBottomLeftRadius:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tborderRadius.mangleCorner(rewrittenRules, decl, p.options.minifyWhitespace, borderRadiusBottomLeft)\n\t\t\t}\n\t\t}\n\n\t\tif prefixes, ok := p.options.cssPrefixData[decl.Key]; ok {\n\t\t\tif declarationKeys == nil {\n\t\t\t\t// Only generate this map if it's needed\n\t\t\t\tdeclarationKeys = make(map[string]struct{})\n\t\t\t\tfor _, rule := range rules {\n\t\t\t\t\tif decl, ok := rule.Data.(*css_ast.RDeclaration); ok {\n\t\t\t\t\t\tdeclarationKeys[decl.KeyText] = struct{}{}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (prefixes & compat.WebkitPrefix) != 0 {\n\t\t\t\trewrittenRules = p.insertPrefixedDeclaration(rewrittenRules, \"-webkit-\", rule.Loc, decl, declarationKeys)\n\t\t\t}\n\t\t\tif (prefixes & compat.KhtmlPrefix) != 0 {\n\t\t\t\trewrittenRules = p.insertPrefixedDeclaration(rewrittenRules, \"-khtml-\", rule.Loc, decl, declarationKeys)\n\t\t\t}\n\t\t\tif (prefixes & compat.MozPrefix) != 0 {\n\t\t\t\trewrittenRules = p.insertPrefixedDeclaration(rewrittenRules, \"-moz-\", rule.Loc, decl, declarationKeys)\n\t\t\t}\n\t\t\tif (prefixes & compat.MsPrefix) != 0 {\n\t\t\t\trewrittenRules = p.insertPrefixedDeclaration(rewrittenRules, \"-ms-\", rule.Loc, decl, declarationKeys)\n\t\t\t}\n\t\t\tif (prefixes & compat.OPrefix) != 0 {\n\t\t\t\trewrittenRules = p.insertPrefixedDeclaration(rewrittenRules, \"-o-\", rule.Loc, decl, declarationKeys)\n\t\t\t}\n\t\t}\n\n\t\t// If this loop iteration would have clipped a color, the out-of-gamut\n\t\t// colors will not be clipped and this flag will be set. We then set up the\n\t\t// next iteration of the loop to duplicate this rule and process it again\n\t\t// with color clipping enabled.\n\t\tif wouldClipColorFlag {\n\t\t\tif p.options.unsupportedCSSFeatures.Has(compat.ColorFunctions) {\n\t\t\t\t// Only do this if there was no previous instance of that property so\n\t\t\t\t// we avoid overwriting any manually-specified fallback values\n\t\t\t\tfor j := len(rewrittenRules) - 2; j >= 0; j-- {\n\t\t\t\t\tif prev, ok := rewrittenRules[j].Data.(*css_ast.RDeclaration); ok && prev.Key == decl.Key {\n\t\t\t\t\t\twouldClipColorFlag = false\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif wouldClipColorFlag {\n\t\t\t\t\t// If the code above would have clipped a color outside of the sRGB gamut,\n\t\t\t\t\t// process this rule again so we can generate the clipped version next time\n\t\t\t\t\ti -= 1\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\twouldClipColorFlag = false\n\t\t}\n\t}\n\n\t// Compact removed rules\n\tif p.options.minifySyntax {\n\t\tend := 0\n\t\tfor _, rule := range rewrittenRules {\n\t\t\tif rule.Data != nil {\n\t\t\t\trewrittenRules[end] = rule\n\t\t\t\tend++\n\t\t\t}\n\t\t}\n\t\trewrittenRules = rewrittenRules[:end]\n\t}\n\n\treturn\n}\n\nfunc (p *parser) insertPrefixedDeclaration(rules []css_ast.Rule, prefix string, loc logger.Loc, decl *css_ast.RDeclaration, declarationKeys map[string]struct{}) []css_ast.Rule {\n\tkeyText := prefix + decl.KeyText\n\n\t// Don't insert a prefixed declaration if there already is one\n\tif _, ok := declarationKeys[keyText]; ok {\n\t\t// We found a previous declaration with a matching prefixed property.\n\t\t// The value is ignored, which matches the behavior of \"autoprefixer\".\n\t\treturn rules\n\t}\n\n\t// Additional special cases for when the prefix applies\n\tswitch decl.Key {\n\tcase css_ast.DBackgroundClip:\n\t\t// The prefix is only needed for \"background-clip: text\"\n\t\tif len(decl.Value) != 1 || decl.Value[0].Kind != css_lexer.TIdent || !strings.EqualFold(decl.Value[0].Text, \"text\") {\n\t\t\treturn rules\n\t\t}\n\n\tcase css_ast.DPosition:\n\t\t// The prefix is only needed for \"position: sticky\"\n\t\tif len(decl.Value) != 1 || decl.Value[0].Kind != css_lexer.TIdent || !strings.EqualFold(decl.Value[0].Text, \"sticky\") {\n\t\t\treturn rules\n\t\t}\n\n\tcase css_ast.DWidth, css_ast.DMinWidth, css_ast.DMaxWidth,\n\t\tcss_ast.DHeight, css_ast.DMinHeight, css_ast.DMaxHeight:\n\t\t// The prefix is only needed for \"width: stretch\"\n\t\tif len(decl.Value) != 1 || decl.Value[0].Kind != css_lexer.TIdent || !strings.EqualFold(decl.Value[0].Text, \"stretch\") {\n\t\t\treturn rules\n\t\t}\n\t}\n\n\tvalue := css_ast.CloneTokensWithoutImportRecords(decl.Value)\n\n\t// Additional special cases for how to transform the contents\n\tswitch decl.Key {\n\tcase css_ast.DPosition:\n\t\t// The prefix applies to the value, not the property\n\t\tkeyText = decl.KeyText\n\t\tvalue[0].Text = \"-webkit-sticky\"\n\n\tcase css_ast.DWidth, css_ast.DMinWidth, css_ast.DMaxWidth,\n\t\tcss_ast.DHeight, css_ast.DMinHeight, css_ast.DMaxHeight:\n\t\t// The prefix applies to the value, not the property\n\t\tkeyText = decl.KeyText\n\n\t\t// This currently only applies to \"stretch\" (already checked above)\n\t\tswitch prefix {\n\t\tcase \"-webkit-\":\n\t\t\tvalue[0].Text = \"-webkit-fill-available\"\n\t\tcase \"-moz-\":\n\t\t\tvalue[0].Text = \"-moz-available\"\n\t\t}\n\n\tcase css_ast.DUserSelect:\n\t\t// The prefix applies to the value as well as the property\n\t\tif prefix == \"-moz-\" && len(value) == 1 && value[0].Kind == css_lexer.TIdent && strings.EqualFold(value[0].Text, \"none\") {\n\t\t\tvalue[0].Text = \"-moz-none\"\n\t\t}\n\n\tcase css_ast.DMaskComposite:\n\t\t// WebKit uses different names for these values\n\t\tif prefix == \"-webkit-\" {\n\t\t\tfor i, token := range value {\n\t\t\t\tif token.Kind == css_lexer.TIdent {\n\t\t\t\t\tswitch token.Text {\n\t\t\t\t\tcase \"add\":\n\t\t\t\t\t\tvalue[i].Text = \"source-over\"\n\t\t\t\t\tcase \"subtract\":\n\t\t\t\t\t\tvalue[i].Text = \"source-out\"\n\t\t\t\t\tcase \"intersect\":\n\t\t\t\t\t\tvalue[i].Text = \"source-in\"\n\t\t\t\t\tcase \"exclude\":\n\t\t\t\t\t\tvalue[i].Text = \"xor\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// If we didn't change the key, manually search for a previous duplicate rule\n\tif keyText == decl.KeyText {\n\t\tfor _, rule := range rules {\n\t\t\tif prevDecl, ok := rule.Data.(*css_ast.RDeclaration); ok && prevDecl.KeyText == keyText && css_ast.TokensEqual(prevDecl.Value, value, nil) {\n\t\t\t\treturn rules\n\t\t\t}\n\t\t}\n\t}\n\n\t// Overwrite the latest declaration with the prefixed declaration\n\trules[len(rules)-1] = css_ast.Rule{Loc: loc, Data: &css_ast.RDeclaration{\n\t\tKeyText:   keyText,\n\t\tKeyRange:  decl.KeyRange,\n\t\tValue:     value,\n\t\tImportant: decl.Important,\n\t}}\n\n\t// Re-add the latest declaration after the inserted declaration\n\trules = append(rules, css_ast.Rule{Loc: loc, Data: decl})\n\treturn rules\n}\n\nfunc (p *parser) lowerInset(loc logger.Loc, decl *css_ast.RDeclaration) ([]css_ast.Rule, bool) {\n\tif tokens, ok := expandTokenQuad(decl.Value, \"\"); ok {\n\t\tmask := ^css_ast.WhitespaceAfter\n\t\tif p.options.minifyWhitespace {\n\t\t\tmask = 0\n\t\t}\n\t\tfor i := range tokens {\n\t\t\ttokens[i].Whitespace &= mask\n\t\t}\n\t\treturn []css_ast.Rule{\n\t\t\t{Loc: loc, Data: &css_ast.RDeclaration{\n\t\t\t\tKeyText:   \"top\",\n\t\t\t\tKeyRange:  decl.KeyRange,\n\t\t\t\tKey:       css_ast.DTop,\n\t\t\t\tValue:     tokens[0:1],\n\t\t\t\tImportant: decl.Important,\n\t\t\t}},\n\t\t\t{Loc: loc, Data: &css_ast.RDeclaration{\n\t\t\t\tKeyText:   \"right\",\n\t\t\t\tKeyRange:  decl.KeyRange,\n\t\t\t\tKey:       css_ast.DRight,\n\t\t\t\tValue:     tokens[1:2],\n\t\t\t\tImportant: decl.Important,\n\t\t\t}},\n\t\t\t{Loc: loc, Data: &css_ast.RDeclaration{\n\t\t\t\tKeyText:   \"bottom\",\n\t\t\t\tKeyRange:  decl.KeyRange,\n\t\t\t\tKey:       css_ast.DBottom,\n\t\t\t\tValue:     tokens[2:3],\n\t\t\t\tImportant: decl.Important,\n\t\t\t}},\n\t\t\t{Loc: loc, Data: &css_ast.RDeclaration{\n\t\t\t\tKeyText:   \"left\",\n\t\t\t\tKeyRange:  decl.KeyRange,\n\t\t\t\tKey:       css_ast.DLeft,\n\t\t\t\tValue:     tokens[3:4],\n\t\t\t\tImportant: decl.Important,\n\t\t\t}},\n\t\t}, true\n\t}\n\treturn nil, false\n}\n"
  },
  {
    "path": "internal/css_parser/css_decls_animation.go",
    "content": "package css_parser\n\nimport (\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n)\n\n// Scan for animation names in the \"animation\" shorthand property\nfunc (p *parser) processAnimationShorthand(tokens []css_ast.Token) {\n\ttype foundFlags struct {\n\t\ttimingFunction bool\n\t\titerationCount bool\n\t\tdirection      bool\n\t\tfillMode       bool\n\t\tplayState      bool\n\t\tname           bool\n\t}\n\n\tfound := foundFlags{}\n\n\tfor i, t := range tokens {\n\t\tswitch t.Kind {\n\t\tcase css_lexer.TComma:\n\t\t\t// Reset the flags when we encounter a comma\n\t\t\tfound = foundFlags{}\n\n\t\tcase css_lexer.TNumber:\n\t\t\tif !found.iterationCount {\n\t\t\t\tfound.iterationCount = true\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tcase css_lexer.TIdent:\n\t\t\tif !found.timingFunction {\n\t\t\t\tswitch strings.ToLower(t.Text) {\n\t\t\t\tcase \"linear\", \"ease\", \"ease-in\", \"ease-out\", \"ease-in-out\", \"step-start\", \"step-end\":\n\t\t\t\t\tfound.timingFunction = true\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !found.iterationCount && strings.ToLower(t.Text) == \"infinite\" {\n\t\t\t\tfound.iterationCount = true\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif !found.direction {\n\t\t\t\tswitch strings.ToLower(t.Text) {\n\t\t\t\tcase \"normal\", \"reverse\", \"alternate\", \"alternate-reverse\":\n\t\t\t\t\tfound.direction = true\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !found.fillMode {\n\t\t\t\tswitch strings.ToLower(t.Text) {\n\t\t\t\tcase \"none\", \"forwards\", \"backwards\", \"both\":\n\t\t\t\t\tfound.fillMode = true\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !found.playState {\n\t\t\t\tswitch strings.ToLower(t.Text) {\n\t\t\t\tcase \"running\", \"paused\":\n\t\t\t\t\tfound.playState = true\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !found.name {\n\t\t\t\tp.handleSingleAnimationName(&tokens[i])\n\t\t\t\tfound.name = true\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tcase css_lexer.TString:\n\t\t\tif !found.name {\n\t\t\t\tp.handleSingleAnimationName(&tokens[i])\n\t\t\t\tfound.name = true\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (p *parser) processAnimationName(tokens []css_ast.Token) {\n\tfor i, t := range tokens {\n\t\tif t.Kind == css_lexer.TIdent || t.Kind == css_lexer.TString {\n\t\t\tp.handleSingleAnimationName(&tokens[i])\n\t\t}\n\t}\n}\n\nfunc (p *parser) handleSingleAnimationName(token *css_ast.Token) {\n\t// Do not transform CSS keywords into symbols because they have special\n\t// meaning in declarations. For example, \"animation-name: none\" clears\n\t// the animation name. It does not set it to the animation named \"none\".\n\t// You need to use \"animation-name: 'none'\" to do that.\n\t//\n\t// Also don't transform strings containing CSS keywords into global symbols\n\t// because global symbols are passed through without being renamed, which\n\t// will print them as keywords. However, we still want to unconditionally\n\t// transform strings into local symbols because local symbols are always\n\t// renamed, so they will never be printed as keywords.\n\tif (token.Kind == css_lexer.TIdent || (token.Kind == css_lexer.TString && !p.makeLocalSymbols)) && isInvalidAnimationName(token.Text) {\n\t\treturn\n\t}\n\n\ttoken.Kind = css_lexer.TSymbol\n\ttoken.PayloadIndex = p.symbolForName(token.Loc, token.Text).Ref.InnerIndex\n}\n\nfunc isInvalidAnimationName(text string) bool {\n\tlower := strings.ToLower(text)\n\treturn lower == \"none\" || cssWideAndReservedKeywords[lower]\n}\n"
  },
  {
    "path": "internal/css_parser/css_decls_border_radius.go",
    "content": "package css_parser\n\nimport (\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\nconst (\n\tborderRadiusTopLeft = iota\n\tborderRadiusTopRight\n\tborderRadiusBottomRight\n\tborderRadiusBottomLeft\n)\n\ntype borderRadiusCorner struct {\n\tfirstToken    css_ast.Token\n\tsecondToken   css_ast.Token\n\tunitSafety    unitSafetyTracker\n\truleIndex     uint32 // The index of the originating rule in the rules array\n\twasSingleRule bool   // True if the originating rule was just for this side\n}\n\ntype borderRadiusTracker struct {\n\tcorners   [4]borderRadiusCorner\n\timportant bool // True if all active rules were flagged as \"!important\"\n}\n\nfunc (borderRadius *borderRadiusTracker) updateCorner(rules []css_ast.Rule, corner int, new borderRadiusCorner) {\n\tif old := borderRadius.corners[corner]; old.firstToken.Kind != css_lexer.TEndOfFile &&\n\t\t(!new.wasSingleRule || old.wasSingleRule) &&\n\t\told.unitSafety.status == unitSafe && new.unitSafety.status == unitSafe {\n\t\trules[old.ruleIndex] = css_ast.Rule{}\n\t}\n\tborderRadius.corners[corner] = new\n}\n\nfunc (borderRadius *borderRadiusTracker) mangleCorners(rules []css_ast.Rule, decl *css_ast.RDeclaration, minifyWhitespace bool) {\n\t// Reset if we see a change in the \"!important\" flag\n\tif borderRadius.important != decl.Important {\n\t\tborderRadius.corners = [4]borderRadiusCorner{}\n\t\tborderRadius.important = decl.Important\n\t}\n\n\ttokens := decl.Value\n\tbeforeSplit := len(tokens)\n\tafterSplit := len(tokens)\n\n\t// Search for the single slash if present\n\tfor i, t := range tokens {\n\t\tif t.Kind == css_lexer.TDelimSlash {\n\t\t\tif beforeSplit == len(tokens) {\n\t\t\t\tbeforeSplit = i\n\t\t\t\tafterSplit = i + 1\n\t\t\t} else {\n\t\t\t\t// Multiple slashes are an error\n\t\t\t\tborderRadius.corners = [4]borderRadiusCorner{}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Use a single tracker for the whole rule\n\tunitSafety := unitSafetyTracker{}\n\tfor _, t := range tokens[:beforeSplit] {\n\t\tunitSafety.includeUnitOf(t)\n\t}\n\tfor _, t := range tokens[afterSplit:] {\n\t\tunitSafety.includeUnitOf(t)\n\t}\n\n\tfirstRadii, firstRadiiOk := expandTokenQuad(tokens[:beforeSplit], \"\")\n\tlastRadii, lastRadiiOk := expandTokenQuad(tokens[afterSplit:], \"\")\n\n\t// Stop now if the pattern wasn't matched\n\tif !firstRadiiOk || (beforeSplit < afterSplit && !lastRadiiOk) {\n\t\tborderRadius.corners = [4]borderRadiusCorner{}\n\t\treturn\n\t}\n\n\t// Handle the first radii\n\tfor corner, t := range firstRadii {\n\t\tif unitSafety.status == unitSafe {\n\t\t\tt.TurnLengthIntoNumberIfZero()\n\t\t}\n\t\tborderRadius.updateCorner(rules, corner, borderRadiusCorner{\n\t\t\tfirstToken:  t,\n\t\t\tsecondToken: t,\n\t\t\tunitSafety:  unitSafety,\n\t\t\truleIndex:   uint32(len(rules) - 1),\n\t\t})\n\t}\n\n\t// Handle the last radii\n\tif lastRadiiOk {\n\t\tfor corner, t := range lastRadii {\n\t\t\tif unitSafety.status == unitSafe {\n\t\t\t\tt.TurnLengthIntoNumberIfZero()\n\t\t\t}\n\t\t\tborderRadius.corners[corner].secondToken = t\n\t\t}\n\t}\n\n\t// Success\n\tborderRadius.compactRules(rules, decl.KeyRange, minifyWhitespace)\n}\n\nfunc (borderRadius *borderRadiusTracker) mangleCorner(rules []css_ast.Rule, decl *css_ast.RDeclaration, minifyWhitespace bool, corner int) {\n\t// Reset if we see a change in the \"!important\" flag\n\tif borderRadius.important != decl.Important {\n\t\tborderRadius.corners = [4]borderRadiusCorner{}\n\t\tborderRadius.important = decl.Important\n\t}\n\n\tif tokens := decl.Value; (len(tokens) == 1 && tokens[0].Kind.IsNumeric()) ||\n\t\t(len(tokens) == 2 && tokens[0].Kind.IsNumeric() && tokens[1].Kind.IsNumeric()) {\n\t\tfirstToken := tokens[0]\n\t\tsecondToken := firstToken\n\t\tif len(tokens) == 2 {\n\t\t\tsecondToken = tokens[1]\n\t\t}\n\n\t\t// Check to see if these units are safe to use in every browser\n\t\tunitSafety := unitSafetyTracker{}\n\t\tunitSafety.includeUnitOf(firstToken)\n\t\tunitSafety.includeUnitOf(secondToken)\n\n\t\t// Only collapse \"0unit\" into \"0\" if the unit is safe\n\t\tif unitSafety.status == unitSafe && firstToken.TurnLengthIntoNumberIfZero() {\n\t\t\ttokens[0] = firstToken\n\t\t}\n\t\tif len(tokens) == 2 {\n\t\t\tif unitSafety.status == unitSafe && secondToken.TurnLengthIntoNumberIfZero() {\n\t\t\t\ttokens[1] = secondToken\n\t\t\t}\n\n\t\t\t// If both tokens are equal, merge them into one\n\t\t\tif firstToken.EqualIgnoringWhitespace(secondToken) {\n\t\t\t\ttokens[0].Whitespace &= ^css_ast.WhitespaceAfter\n\t\t\t\tdecl.Value = tokens[:1]\n\t\t\t}\n\t\t}\n\n\t\tborderRadius.updateCorner(rules, corner, borderRadiusCorner{\n\t\t\tfirstToken:    firstToken,\n\t\t\tsecondToken:   secondToken,\n\t\t\tunitSafety:    unitSafety,\n\t\t\truleIndex:     uint32(len(rules) - 1),\n\t\t\twasSingleRule: true,\n\t\t})\n\t\tborderRadius.compactRules(rules, decl.KeyRange, minifyWhitespace)\n\t} else {\n\t\tborderRadius.corners = [4]borderRadiusCorner{}\n\t}\n}\n\nfunc (borderRadius *borderRadiusTracker) compactRules(rules []css_ast.Rule, keyRange logger.Range, minifyWhitespace bool) {\n\t// All tokens must be present\n\tif eof := css_lexer.TEndOfFile; borderRadius.corners[0].firstToken.Kind == eof || borderRadius.corners[1].firstToken.Kind == eof ||\n\t\tborderRadius.corners[2].firstToken.Kind == eof || borderRadius.corners[3].firstToken.Kind == eof {\n\t\treturn\n\t}\n\n\t// All tokens must have the same unit\n\tfor _, side := range borderRadius.corners[1:] {\n\t\tif !side.unitSafety.isSafeWith(borderRadius.corners[0].unitSafety) {\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Generate the most minimal representation\n\ttokens := compactTokenQuad(\n\t\tborderRadius.corners[0].firstToken,\n\t\tborderRadius.corners[1].firstToken,\n\t\tborderRadius.corners[2].firstToken,\n\t\tborderRadius.corners[3].firstToken,\n\t\tminifyWhitespace,\n\t)\n\tsecondTokens := compactTokenQuad(\n\t\tborderRadius.corners[0].secondToken,\n\t\tborderRadius.corners[1].secondToken,\n\t\tborderRadius.corners[2].secondToken,\n\t\tborderRadius.corners[3].secondToken,\n\t\tminifyWhitespace,\n\t)\n\tif !css_ast.TokensEqualIgnoringWhitespace(tokens, secondTokens) {\n\t\tvar whitespace css_ast.WhitespaceFlags\n\t\tif !minifyWhitespace {\n\t\t\twhitespace = css_ast.WhitespaceBefore | css_ast.WhitespaceAfter\n\t\t}\n\t\ttokens = append(tokens, css_ast.Token{\n\t\t\tLoc:        tokens[len(tokens)-1].Loc,\n\t\t\tKind:       css_lexer.TDelimSlash,\n\t\t\tText:       \"/\",\n\t\t\tWhitespace: whitespace,\n\t\t})\n\t\ttokens = append(tokens, secondTokens...)\n\t}\n\n\t// Remove all of the existing declarations\n\tvar minLoc logger.Loc\n\tfor i, corner := range borderRadius.corners {\n\t\tif loc := rules[corner.ruleIndex].Loc; i == 0 || loc.Start < minLoc.Start {\n\t\t\tminLoc = loc\n\t\t}\n\t\trules[corner.ruleIndex] = css_ast.Rule{}\n\t}\n\n\t// Insert the combined declaration where the last rule was\n\trules[borderRadius.corners[3].ruleIndex] = css_ast.Rule{Loc: minLoc, Data: &css_ast.RDeclaration{\n\t\tKey:       css_ast.DBorderRadius,\n\t\tKeyText:   \"border-radius\",\n\t\tValue:     tokens,\n\t\tKeyRange:  keyRange,\n\t\tImportant: borderRadius.important,\n\t}}\n}\n"
  },
  {
    "path": "internal/css_parser/css_decls_box.go",
    "content": "package css_parser\n\nimport (\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\nconst (\n\tboxTop = iota\n\tboxRight\n\tboxBottom\n\tboxLeft\n)\n\ntype boxSide struct {\n\ttoken         css_ast.Token\n\tunitSafety    unitSafetyTracker\n\truleIndex     uint32 // The index of the originating rule in the rules array\n\twasSingleRule bool   // True if the originating rule was just for this side\n}\n\ntype boxTracker struct {\n\tkeyText   string\n\tsides     [4]boxSide\n\tallowAuto bool // If true, allow the \"auto\" keyword\n\timportant bool // True if all active rules were flagged as \"!important\"\n\tkey       css_ast.D\n}\n\ntype unitSafetyStatus uint8\n\nconst (\n\tunitSafe         unitSafetyStatus = iota // \"margin: 0 1px 2cm 3%;\"\n\tunitUnsafeSingle                         // \"margin: 0 1vw 2vw 3vw;\"\n\tunitUnsafeMixed                          // \"margin: 0 1vw 2vh 3ch;\"\n)\n\n// We can only compact rules together if they have the same unit safety level.\n// We want to avoid a situation where the browser treats some of the original\n// rules as valid and others as invalid.\n//\n//\tSafe:\n//\t  top: 1px; left: 0; bottom: 1px; right: 0;\n//\t  top: 1Q; left: 2Q; bottom: 3Q; right: 4Q;\n//\n//\tUnsafe:\n//\t  top: 1vh; left: 2vw; bottom: 3vh; right: 4vw;\n//\t  top: 1Q; left: 2Q; bottom: 3Q; right: 0;\n//\t  inset: 1Q 0 0 0; top: 0;\ntype unitSafetyTracker struct {\n\tunit   string\n\tstatus unitSafetyStatus\n}\n\nfunc (a unitSafetyTracker) isSafeWith(b unitSafetyTracker) bool {\n\treturn a.status == b.status && a.status != unitUnsafeMixed && (a.status != unitUnsafeSingle || a.unit == b.unit)\n}\n\nfunc (t *unitSafetyTracker) includeUnitOf(token css_ast.Token) {\n\tswitch token.Kind {\n\tcase css_lexer.TNumber:\n\t\tif token.Text == \"0\" {\n\t\t\treturn\n\t\t}\n\n\tcase css_lexer.TPercentage:\n\t\treturn\n\n\tcase css_lexer.TDimension:\n\t\tif token.DimensionUnitIsSafeLength() {\n\t\t\treturn\n\t\t} else if unit := token.DimensionUnit(); t.status == unitSafe {\n\t\t\tt.status = unitUnsafeSingle\n\t\t\tt.unit = unit\n\t\t\treturn\n\t\t} else if t.status == unitUnsafeSingle && t.unit == unit {\n\t\t\treturn\n\t\t}\n\t}\n\n\tt.status = unitUnsafeMixed\n}\n\nfunc (box *boxTracker) updateSide(rules []css_ast.Rule, side int, new boxSide) {\n\tif old := box.sides[side]; old.token.Kind != css_lexer.TEndOfFile &&\n\t\t(!new.wasSingleRule || old.wasSingleRule) &&\n\t\told.unitSafety.status == unitSafe && new.unitSafety.status == unitSafe {\n\t\trules[old.ruleIndex] = css_ast.Rule{}\n\t}\n\tbox.sides[side] = new\n}\n\nfunc (box *boxTracker) mangleSides(rules []css_ast.Rule, decl *css_ast.RDeclaration, minifyWhitespace bool) {\n\t// Reset if we see a change in the \"!important\" flag\n\tif box.important != decl.Important {\n\t\tbox.sides = [4]boxSide{}\n\t\tbox.important = decl.Important\n\t}\n\n\tallowedIdent := \"\"\n\tif box.allowAuto {\n\t\tallowedIdent = \"auto\"\n\t}\n\tif quad, ok := expandTokenQuad(decl.Value, allowedIdent); ok {\n\t\t// Use a single tracker for the whole rule\n\t\tunitSafety := unitSafetyTracker{}\n\t\tfor _, t := range quad {\n\t\t\tif !box.allowAuto || t.Kind.IsNumeric() {\n\t\t\t\tunitSafety.includeUnitOf(t)\n\t\t\t}\n\t\t}\n\t\tfor side, t := range quad {\n\t\t\tif unitSafety.status == unitSafe {\n\t\t\t\tt.TurnLengthIntoNumberIfZero()\n\t\t\t}\n\t\t\tbox.updateSide(rules, side, boxSide{\n\t\t\t\ttoken:      t,\n\t\t\t\truleIndex:  uint32(len(rules) - 1),\n\t\t\t\tunitSafety: unitSafety,\n\t\t\t})\n\t\t}\n\t\tbox.compactRules(rules, decl.KeyRange, minifyWhitespace)\n\t} else {\n\t\tbox.sides = [4]boxSide{}\n\t}\n}\n\nfunc (box *boxTracker) mangleSide(rules []css_ast.Rule, decl *css_ast.RDeclaration, minifyWhitespace bool, side int) {\n\t// Reset if we see a change in the \"!important\" flag\n\tif box.important != decl.Important {\n\t\tbox.sides = [4]boxSide{}\n\t\tbox.important = decl.Important\n\t}\n\n\tif tokens := decl.Value; len(tokens) == 1 {\n\t\tif t := tokens[0]; t.Kind.IsNumeric() || (t.Kind == css_lexer.TIdent && box.allowAuto && strings.EqualFold(t.Text, \"auto\")) {\n\t\t\tunitSafety := unitSafetyTracker{}\n\t\t\tif !box.allowAuto || t.Kind.IsNumeric() {\n\t\t\t\tunitSafety.includeUnitOf(t)\n\t\t\t}\n\t\t\tif unitSafety.status == unitSafe && t.TurnLengthIntoNumberIfZero() {\n\t\t\t\ttokens[0] = t\n\t\t\t}\n\t\t\tbox.updateSide(rules, side, boxSide{\n\t\t\t\ttoken:         t,\n\t\t\t\truleIndex:     uint32(len(rules) - 1),\n\t\t\t\twasSingleRule: true,\n\t\t\t\tunitSafety:    unitSafety,\n\t\t\t})\n\t\t\tbox.compactRules(rules, decl.KeyRange, minifyWhitespace)\n\t\t\treturn\n\t\t}\n\t}\n\n\tbox.sides = [4]boxSide{}\n}\n\nfunc (box *boxTracker) compactRules(rules []css_ast.Rule, keyRange logger.Range, minifyWhitespace bool) {\n\t// Don't compact if the shorthand form is unsupported\n\tif box.key == css_ast.DUnknown {\n\t\treturn\n\t}\n\n\t// All tokens must be present\n\tif eof := css_lexer.TEndOfFile; box.sides[0].token.Kind == eof || box.sides[1].token.Kind == eof ||\n\t\tbox.sides[2].token.Kind == eof || box.sides[3].token.Kind == eof {\n\t\treturn\n\t}\n\n\t// All tokens must have the same unit\n\tfor _, side := range box.sides[1:] {\n\t\tif !side.unitSafety.isSafeWith(box.sides[0].unitSafety) {\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Generate the most minimal representation\n\ttokens := compactTokenQuad(\n\t\tbox.sides[0].token,\n\t\tbox.sides[1].token,\n\t\tbox.sides[2].token,\n\t\tbox.sides[3].token,\n\t\tminifyWhitespace,\n\t)\n\n\t// Remove all of the existing declarations\n\tvar minLoc logger.Loc\n\tfor i, side := range box.sides {\n\t\tif loc := rules[side.ruleIndex].Loc; i == 0 || loc.Start < minLoc.Start {\n\t\t\tminLoc = loc\n\t\t}\n\t\trules[side.ruleIndex] = css_ast.Rule{}\n\t}\n\n\t// Insert the combined declaration where the last rule was\n\trules[box.sides[3].ruleIndex] = css_ast.Rule{Loc: minLoc, Data: &css_ast.RDeclaration{\n\t\tKey:       box.key,\n\t\tKeyText:   box.keyText,\n\t\tValue:     tokens,\n\t\tKeyRange:  keyRange,\n\t\tImportant: box.important,\n\t}}\n}\n"
  },
  {
    "path": "internal/css_parser/css_decls_box_shadow.go",
    "content": "package css_parser\n\nimport (\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n)\n\nfunc (p *parser) lowerAndMangleBoxShadow(tokens []css_ast.Token, wouldClipColor *bool) []css_ast.Token {\n\tinsetCount := 0\n\tcolorCount := 0\n\tnumbersBegin := 0\n\tnumbersCount := 0\n\tnumbersDone := false\n\tfoundUnexpectedToken := false\n\n\tfor i, t := range tokens {\n\t\tif t.Kind == css_lexer.TNumber || t.Kind == css_lexer.TDimension {\n\t\t\tif numbersDone {\n\t\t\t\t// Track if we found a non-number in between two numbers\n\t\t\t\tfoundUnexpectedToken = true\n\t\t\t}\n\t\t\tif p.options.minifySyntax && t.TurnLengthIntoNumberIfZero() {\n\t\t\t\t// \"0px\" => \"0\"\n\t\t\t\ttokens[i] = t\n\t\t\t}\n\t\t\tif numbersCount == 0 {\n\t\t\t\t// Track the index of the first number\n\t\t\t\tnumbersBegin = i\n\t\t\t}\n\t\t\tnumbersCount++\n\t\t} else {\n\t\t\tif numbersCount != 0 {\n\t\t\t\t// Track when we find a non-number after a number\n\t\t\t\tnumbersDone = true\n\t\t\t}\n\n\t\t\tif looksLikeColor(t) {\n\t\t\t\tcolorCount++\n\t\t\t\ttokens[i] = p.lowerAndMinifyColor(t, wouldClipColor)\n\t\t\t} else if t.Kind == css_lexer.TIdent && strings.EqualFold(t.Text, \"inset\") {\n\t\t\t\tinsetCount++\n\t\t\t} else {\n\t\t\t\t// Track if we found a token other than a number, a color, or \"inset\"\n\t\t\t\tfoundUnexpectedToken = true\n\t\t\t}\n\t\t}\n\t}\n\n\t// If everything looks like a valid rule, trim trailing zeros off the numbers.\n\t// There are three valid configurations of numbers:\n\t//\n\t//   offset-x | offset-y\n\t//   offset-x | offset-y | blur-radius\n\t//   offset-x | offset-y | blur-radius | spread-radius\n\t//\n\t// If omitted, blur-radius and spread-radius are implied to be zero.\n\tif p.options.minifySyntax && insetCount <= 1 && colorCount <= 1 && numbersCount > 2 && numbersCount <= 4 && !foundUnexpectedToken {\n\t\tnumbersEnd := numbersBegin + numbersCount\n\t\tfor numbersCount > 2 && tokens[numbersBegin+numbersCount-1].IsZero() {\n\t\t\tnumbersCount--\n\t\t}\n\t\ttokens = append(tokens[:numbersBegin+numbersCount], tokens[numbersEnd:]...)\n\t}\n\n\t// Set the whitespace flags\n\tfor i := range tokens {\n\t\tvar whitespace css_ast.WhitespaceFlags\n\t\tif i > 0 || !p.options.minifyWhitespace {\n\t\t\twhitespace |= css_ast.WhitespaceBefore\n\t\t}\n\t\tif i+1 < len(tokens) {\n\t\t\twhitespace |= css_ast.WhitespaceAfter\n\t\t}\n\t\ttokens[i].Whitespace = whitespace\n\t}\n\treturn tokens\n}\n\nfunc (p *parser) lowerAndMangleBoxShadows(tokens []css_ast.Token, wouldClipColor *bool) []css_ast.Token {\n\tn := len(tokens)\n\tend := 0\n\ti := 0\n\n\tfor i < n {\n\t\t// Find the comma or the end of the token list\n\t\tcomma := i\n\t\tfor comma < n && tokens[comma].Kind != css_lexer.TComma {\n\t\t\tcomma++\n\t\t}\n\n\t\t// Mangle this individual shadow\n\t\tend += copy(tokens[end:], p.lowerAndMangleBoxShadow(tokens[i:comma], wouldClipColor))\n\n\t\t// Skip over the comma\n\t\tif comma < n {\n\t\t\ttokens[end] = tokens[comma]\n\t\t\tend++\n\t\t\tcomma++\n\t\t}\n\t\ti = comma\n\t}\n\n\treturn tokens[:end]\n}\n"
  },
  {
    "path": "internal/css_parser/css_decls_color.go",
    "content": "package css_parser\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n)\n\n// These names are shorter than their hex codes\nvar shortColorName = map[uint32]string{\n\t0x000080ff: \"navy\",\n\t0x008000ff: \"green\",\n\t0x008080ff: \"teal\",\n\t0x4b0082ff: \"indigo\",\n\t0x800000ff: \"maroon\",\n\t0x800080ff: \"purple\",\n\t0x808000ff: \"olive\",\n\t0x808080ff: \"gray\",\n\t0xa0522dff: \"sienna\",\n\t0xa52a2aff: \"brown\",\n\t0xc0c0c0ff: \"silver\",\n\t0xcd853fff: \"peru\",\n\t0xd2b48cff: \"tan\",\n\t0xda70d6ff: \"orchid\",\n\t0xdda0ddff: \"plum\",\n\t0xee82eeff: \"violet\",\n\t0xf0e68cff: \"khaki\",\n\t0xf0ffffff: \"azure\",\n\t0xf5deb3ff: \"wheat\",\n\t0xf5f5dcff: \"beige\",\n\t0xfa8072ff: \"salmon\",\n\t0xfaf0e6ff: \"linen\",\n\t0xff0000ff: \"red\",\n\t0xff6347ff: \"tomato\",\n\t0xff7f50ff: \"coral\",\n\t0xffa500ff: \"orange\",\n\t0xffc0cbff: \"pink\",\n\t0xffd700ff: \"gold\",\n\t0xffe4c4ff: \"bisque\",\n\t0xfffafaff: \"snow\",\n\t0xfffff0ff: \"ivory\",\n}\n\nvar colorNameToHex = map[string]uint32{\n\t\"black\":                0x000000ff,\n\t\"silver\":               0xc0c0c0ff,\n\t\"gray\":                 0x808080ff,\n\t\"white\":                0xffffffff,\n\t\"maroon\":               0x800000ff,\n\t\"red\":                  0xff0000ff,\n\t\"purple\":               0x800080ff,\n\t\"fuchsia\":              0xff00ffff,\n\t\"green\":                0x008000ff,\n\t\"lime\":                 0x00ff00ff,\n\t\"olive\":                0x808000ff,\n\t\"yellow\":               0xffff00ff,\n\t\"navy\":                 0x000080ff,\n\t\"blue\":                 0x0000ffff,\n\t\"teal\":                 0x008080ff,\n\t\"aqua\":                 0x00ffffff,\n\t\"orange\":               0xffa500ff,\n\t\"aliceblue\":            0xf0f8ffff,\n\t\"antiquewhite\":         0xfaebd7ff,\n\t\"aquamarine\":           0x7fffd4ff,\n\t\"azure\":                0xf0ffffff,\n\t\"beige\":                0xf5f5dcff,\n\t\"bisque\":               0xffe4c4ff,\n\t\"blanchedalmond\":       0xffebcdff,\n\t\"blueviolet\":           0x8a2be2ff,\n\t\"brown\":                0xa52a2aff,\n\t\"burlywood\":            0xdeb887ff,\n\t\"cadetblue\":            0x5f9ea0ff,\n\t\"chartreuse\":           0x7fff00ff,\n\t\"chocolate\":            0xd2691eff,\n\t\"coral\":                0xff7f50ff,\n\t\"cornflowerblue\":       0x6495edff,\n\t\"cornsilk\":             0xfff8dcff,\n\t\"crimson\":              0xdc143cff,\n\t\"cyan\":                 0x00ffffff,\n\t\"darkblue\":             0x00008bff,\n\t\"darkcyan\":             0x008b8bff,\n\t\"darkgoldenrod\":        0xb8860bff,\n\t\"darkgray\":             0xa9a9a9ff,\n\t\"darkgreen\":            0x006400ff,\n\t\"darkgrey\":             0xa9a9a9ff,\n\t\"darkkhaki\":            0xbdb76bff,\n\t\"darkmagenta\":          0x8b008bff,\n\t\"darkolivegreen\":       0x556b2fff,\n\t\"darkorange\":           0xff8c00ff,\n\t\"darkorchid\":           0x9932ccff,\n\t\"darkred\":              0x8b0000ff,\n\t\"darksalmon\":           0xe9967aff,\n\t\"darkseagreen\":         0x8fbc8fff,\n\t\"darkslateblue\":        0x483d8bff,\n\t\"darkslategray\":        0x2f4f4fff,\n\t\"darkslategrey\":        0x2f4f4fff,\n\t\"darkturquoise\":        0x00ced1ff,\n\t\"darkviolet\":           0x9400d3ff,\n\t\"deeppink\":             0xff1493ff,\n\t\"deepskyblue\":          0x00bfffff,\n\t\"dimgray\":              0x696969ff,\n\t\"dimgrey\":              0x696969ff,\n\t\"dodgerblue\":           0x1e90ffff,\n\t\"firebrick\":            0xb22222ff,\n\t\"floralwhite\":          0xfffaf0ff,\n\t\"forestgreen\":          0x228b22ff,\n\t\"gainsboro\":            0xdcdcdcff,\n\t\"ghostwhite\":           0xf8f8ffff,\n\t\"gold\":                 0xffd700ff,\n\t\"goldenrod\":            0xdaa520ff,\n\t\"greenyellow\":          0xadff2fff,\n\t\"grey\":                 0x808080ff,\n\t\"honeydew\":             0xf0fff0ff,\n\t\"hotpink\":              0xff69b4ff,\n\t\"indianred\":            0xcd5c5cff,\n\t\"indigo\":               0x4b0082ff,\n\t\"ivory\":                0xfffff0ff,\n\t\"khaki\":                0xf0e68cff,\n\t\"lavender\":             0xe6e6faff,\n\t\"lavenderblush\":        0xfff0f5ff,\n\t\"lawngreen\":            0x7cfc00ff,\n\t\"lemonchiffon\":         0xfffacdff,\n\t\"lightblue\":            0xadd8e6ff,\n\t\"lightcoral\":           0xf08080ff,\n\t\"lightcyan\":            0xe0ffffff,\n\t\"lightgoldenrodyellow\": 0xfafad2ff,\n\t\"lightgray\":            0xd3d3d3ff,\n\t\"lightgreen\":           0x90ee90ff,\n\t\"lightgrey\":            0xd3d3d3ff,\n\t\"lightpink\":            0xffb6c1ff,\n\t\"lightsalmon\":          0xffa07aff,\n\t\"lightseagreen\":        0x20b2aaff,\n\t\"lightskyblue\":         0x87cefaff,\n\t\"lightslategray\":       0x778899ff,\n\t\"lightslategrey\":       0x778899ff,\n\t\"lightsteelblue\":       0xb0c4deff,\n\t\"lightyellow\":          0xffffe0ff,\n\t\"limegreen\":            0x32cd32ff,\n\t\"linen\":                0xfaf0e6ff,\n\t\"magenta\":              0xff00ffff,\n\t\"mediumaquamarine\":     0x66cdaaff,\n\t\"mediumblue\":           0x0000cdff,\n\t\"mediumorchid\":         0xba55d3ff,\n\t\"mediumpurple\":         0x9370dbff,\n\t\"mediumseagreen\":       0x3cb371ff,\n\t\"mediumslateblue\":      0x7b68eeff,\n\t\"mediumspringgreen\":    0x00fa9aff,\n\t\"mediumturquoise\":      0x48d1ccff,\n\t\"mediumvioletred\":      0xc71585ff,\n\t\"midnightblue\":         0x191970ff,\n\t\"mintcream\":            0xf5fffaff,\n\t\"mistyrose\":            0xffe4e1ff,\n\t\"moccasin\":             0xffe4b5ff,\n\t\"navajowhite\":          0xffdeadff,\n\t\"oldlace\":              0xfdf5e6ff,\n\t\"olivedrab\":            0x6b8e23ff,\n\t\"orangered\":            0xff4500ff,\n\t\"orchid\":               0xda70d6ff,\n\t\"palegoldenrod\":        0xeee8aaff,\n\t\"palegreen\":            0x98fb98ff,\n\t\"paleturquoise\":        0xafeeeeff,\n\t\"palevioletred\":        0xdb7093ff,\n\t\"papayawhip\":           0xffefd5ff,\n\t\"peachpuff\":            0xffdab9ff,\n\t\"peru\":                 0xcd853fff,\n\t\"pink\":                 0xffc0cbff,\n\t\"plum\":                 0xdda0ddff,\n\t\"powderblue\":           0xb0e0e6ff,\n\t\"rosybrown\":            0xbc8f8fff,\n\t\"royalblue\":            0x4169e1ff,\n\t\"saddlebrown\":          0x8b4513ff,\n\t\"salmon\":               0xfa8072ff,\n\t\"sandybrown\":           0xf4a460ff,\n\t\"seagreen\":             0x2e8b57ff,\n\t\"seashell\":             0xfff5eeff,\n\t\"sienna\":               0xa0522dff,\n\t\"skyblue\":              0x87ceebff,\n\t\"slateblue\":            0x6a5acdff,\n\t\"slategray\":            0x708090ff,\n\t\"slategrey\":            0x708090ff,\n\t\"snow\":                 0xfffafaff,\n\t\"springgreen\":          0x00ff7fff,\n\t\"steelblue\":            0x4682b4ff,\n\t\"tan\":                  0xd2b48cff,\n\t\"thistle\":              0xd8bfd8ff,\n\t\"tomato\":               0xff6347ff,\n\t\"turquoise\":            0x40e0d0ff,\n\t\"violet\":               0xee82eeff,\n\t\"wheat\":                0xf5deb3ff,\n\t\"whitesmoke\":           0xf5f5f5ff,\n\t\"yellowgreen\":          0x9acd32ff,\n\t\"rebeccapurple\":        0x663399ff,\n}\n\nfunc parseHex(text string) (uint32, bool) {\n\thex := uint32(0)\n\tfor _, c := range text {\n\t\thex <<= 4\n\t\tswitch {\n\t\tcase c >= '0' && c <= '9':\n\t\t\thex |= uint32(c) - '0'\n\t\tcase c >= 'a' && c <= 'f':\n\t\t\thex |= uint32(c) - ('a' - 10)\n\t\tcase c >= 'A' && c <= 'F':\n\t\t\thex |= uint32(c) - ('A' - 10)\n\t\tdefault:\n\t\t\treturn 0, false\n\t\t}\n\t}\n\treturn hex, true\n}\n\n// 0xAABBCCDD => 0xABCD\nfunc compactHex(v uint32) uint32 {\n\treturn ((v & 0x0FF00000) >> 12) | ((v & 0x00000FF0) >> 4)\n}\n\n// 0xABCD => 0xAABBCCDD\nfunc expandHex(v uint32) uint32 {\n\treturn ((v & 0xF000) << 16) | ((v & 0xFF00) << 12) | ((v & 0x0FF0) << 8) | ((v & 0x00FF) << 4) | (v & 0x000F)\n}\n\nfunc hexR(v uint32) int { return int(v >> 24) }\nfunc hexG(v uint32) int { return int((v >> 16) & 255) }\nfunc hexB(v uint32) int { return int((v >> 8) & 255) }\nfunc hexA(v uint32) int { return int(v & 255) }\n\nfunc floatToStringForColor(a float64) string {\n\ttext := fmt.Sprintf(\"%.03f\", a)\n\tfor text[len(text)-1] == '0' {\n\t\ttext = text[:len(text)-1]\n\t}\n\tif text[len(text)-1] == '.' {\n\t\ttext = text[:len(text)-1]\n\t}\n\treturn text\n}\n\nfunc degreesForAngle(token css_ast.Token) (float64, bool) {\n\tswitch token.Kind {\n\tcase css_lexer.TNumber:\n\t\tif value, err := strconv.ParseFloat(token.Text, 64); err == nil {\n\t\t\treturn value, true\n\t\t}\n\n\tcase css_lexer.TDimension:\n\t\tif value, err := strconv.ParseFloat(token.DimensionValue(), 64); err == nil {\n\t\t\tswitch token.DimensionUnit() {\n\t\t\tcase \"deg\":\n\t\t\t\treturn value, true\n\t\t\tcase \"grad\":\n\t\t\t\treturn value * (360.0 / 400.0), true\n\t\t\tcase \"rad\":\n\t\t\t\treturn value * (180.0 / math.Pi), true\n\t\t\tcase \"turn\":\n\t\t\t\treturn value * 360.0, true\n\t\t\t}\n\t\t}\n\t}\n\treturn 0, false\n}\n\nfunc lowerAlphaPercentageToNumber(token css_ast.Token) css_ast.Token {\n\tif token.Kind == css_lexer.TPercentage {\n\t\tif value, err := strconv.ParseFloat(token.Text[:len(token.Text)-1], 64); err == nil {\n\t\t\ttoken.Kind = css_lexer.TNumber\n\t\t\ttoken.Text = floatToStringForColor(value / 100.0)\n\t\t}\n\t}\n\treturn token\n}\n\n// Convert newer color syntax to older color syntax for older browsers\nfunc (p *parser) lowerAndMinifyColor(token css_ast.Token, wouldClipColor *bool) css_ast.Token {\n\ttext := token.Text\n\n\tswitch token.Kind {\n\tcase css_lexer.THash:\n\t\tif p.options.unsupportedCSSFeatures.Has(compat.HexRGBA) {\n\t\t\tswitch len(text) {\n\t\t\tcase 4:\n\t\t\t\t// \"#1234\" => \"rgba(1, 2, 3, 0.004)\"\n\t\t\t\tif hex, ok := parseHex(text); ok {\n\t\t\t\t\thex = expandHex(hex)\n\t\t\t\t\treturn p.tryToGenerateColor(token, parsedColor{hex: hex}, nil)\n\t\t\t\t}\n\n\t\t\tcase 8:\n\t\t\t\t// \"#12345678\" => \"rgba(18, 52, 86, 0.47)\"\n\t\t\t\tif hex, ok := parseHex(text); ok {\n\t\t\t\t\treturn p.tryToGenerateColor(token, parsedColor{hex: hex}, nil)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\tcase css_lexer.TIdent:\n\t\tif p.options.unsupportedCSSFeatures.Has(compat.RebeccaPurple) && strings.EqualFold(text, \"rebeccapurple\") {\n\t\t\ttoken.Kind = css_lexer.THash\n\t\t\ttoken.Text = \"663399\"\n\t\t}\n\n\tcase css_lexer.TFunction:\n\t\tswitch strings.ToLower(text) {\n\t\tcase \"rgb\", \"rgba\", \"hsl\", \"hsla\":\n\t\t\tif p.options.unsupportedCSSFeatures.Has(compat.Modern_RGB_HSL) {\n\t\t\t\targs := *token.Children\n\t\t\t\tremoveAlpha := false\n\t\t\t\taddAlpha := false\n\n\t\t\t\t// \"hsl(1deg, 2%, 3%)\" => \"hsl(1, 2%, 3%)\"\n\t\t\t\tif (text == \"hsl\" || text == \"hsla\") && len(args) > 0 {\n\t\t\t\t\tif degrees, ok := degreesForAngle(args[0]); ok {\n\t\t\t\t\t\targs[0].Kind = css_lexer.TNumber\n\t\t\t\t\t\targs[0].Text = floatToStringForColor(degrees)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// These check for \"IsNumeric\" to reject \"var()\" since a single \"var()\"\n\t\t\t\t// can substitute for multiple tokens and that messes up pattern matching\n\t\t\t\tswitch len(args) {\n\t\t\t\tcase 3:\n\t\t\t\t\t// \"rgba(1 2 3)\" => \"rgb(1, 2, 3)\"\n\t\t\t\t\t// \"hsla(1 2% 3%)\" => \"hsl(1, 2%, 3%)\"\n\t\t\t\t\tif args[0].Kind.IsNumeric() && args[1].Kind.IsNumeric() && args[2].Kind.IsNumeric() {\n\t\t\t\t\t\tremoveAlpha = true\n\t\t\t\t\t\targs[0].Whitespace = 0\n\t\t\t\t\t\targs[1].Whitespace = 0\n\t\t\t\t\t\tcommaToken := p.commaToken(token.Loc)\n\t\t\t\t\t\ttoken.Children = &[]css_ast.Token{\n\t\t\t\t\t\t\targs[0], commaToken,\n\t\t\t\t\t\t\targs[1], commaToken,\n\t\t\t\t\t\t\targs[2],\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase 5:\n\t\t\t\t\t// \"rgba(1, 2, 3)\" => \"rgb(1, 2, 3)\"\n\t\t\t\t\t// \"hsla(1, 2%, 3%)\" => \"hsl(1%, 2%, 3%)\"\n\t\t\t\t\tif args[0].Kind.IsNumeric() && args[1].Kind == css_lexer.TComma &&\n\t\t\t\t\t\targs[2].Kind.IsNumeric() && args[3].Kind == css_lexer.TComma &&\n\t\t\t\t\t\targs[4].Kind.IsNumeric() {\n\t\t\t\t\t\tremoveAlpha = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\t// \"rgb(1 2 3 / 4%)\" => \"rgba(1, 2, 3, 0.04)\"\n\t\t\t\t\t// \"hsl(1 2% 3% / 4%)\" => \"hsla(1, 2%, 3%, 0.04)\"\n\t\t\t\t\tif args[0].Kind.IsNumeric() && args[1].Kind.IsNumeric() && args[2].Kind.IsNumeric() &&\n\t\t\t\t\t\targs[3].Kind == css_lexer.TDelimSlash && args[4].Kind.IsNumeric() {\n\t\t\t\t\t\taddAlpha = true\n\t\t\t\t\t\targs[0].Whitespace = 0\n\t\t\t\t\t\targs[1].Whitespace = 0\n\t\t\t\t\t\targs[2].Whitespace = 0\n\t\t\t\t\t\tcommaToken := p.commaToken(token.Loc)\n\t\t\t\t\t\ttoken.Children = &[]css_ast.Token{\n\t\t\t\t\t\t\targs[0], commaToken,\n\t\t\t\t\t\t\targs[1], commaToken,\n\t\t\t\t\t\t\targs[2], commaToken,\n\t\t\t\t\t\t\tlowerAlphaPercentageToNumber(args[4]),\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase 7:\n\t\t\t\t\t// \"rgb(1%, 2%, 3%, 4%)\" => \"rgba(1%, 2%, 3%, 0.04)\"\n\t\t\t\t\t// \"hsl(1, 2%, 3%, 4%)\" => \"hsla(1, 2%, 3%, 0.04)\"\n\t\t\t\t\tif args[0].Kind.IsNumeric() && args[1].Kind == css_lexer.TComma &&\n\t\t\t\t\t\targs[2].Kind.IsNumeric() && args[3].Kind == css_lexer.TComma &&\n\t\t\t\t\t\targs[4].Kind.IsNumeric() && args[5].Kind == css_lexer.TComma &&\n\t\t\t\t\t\targs[6].Kind.IsNumeric() {\n\t\t\t\t\t\taddAlpha = true\n\t\t\t\t\t\targs[6] = lowerAlphaPercentageToNumber(args[6])\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif removeAlpha {\n\t\t\t\t\tif strings.EqualFold(text, \"rgba\") {\n\t\t\t\t\t\ttoken.Text = \"rgb\"\n\t\t\t\t\t} else if strings.EqualFold(text, \"hsla\") {\n\t\t\t\t\t\ttoken.Text = \"hsl\"\n\t\t\t\t\t}\n\t\t\t\t} else if addAlpha {\n\t\t\t\t\tif strings.EqualFold(text, \"rgb\") {\n\t\t\t\t\t\ttoken.Text = \"rgba\"\n\t\t\t\t\t} else if strings.EqualFold(text, \"hsl\") {\n\t\t\t\t\t\ttoken.Text = \"hsla\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase \"hwb\":\n\t\t\tif p.options.unsupportedCSSFeatures.Has(compat.HWB) {\n\t\t\t\tif color, ok := parseColor(token); ok {\n\t\t\t\t\treturn p.tryToGenerateColor(token, color, wouldClipColor)\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase \"color\", \"lab\", \"lch\", \"oklab\", \"oklch\":\n\t\t\tif p.options.unsupportedCSSFeatures.Has(compat.ColorFunctions) {\n\t\t\t\tif color, ok := parseColor(token); ok {\n\t\t\t\t\treturn p.tryToGenerateColor(token, color, wouldClipColor)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// When minifying, try to parse the color and print it back out. This minifies\n\t// the color because we always print it out using the shortest encoding.\n\tif p.options.minifySyntax {\n\t\tif hex, ok := parseColor(token); ok {\n\t\t\ttoken = p.tryToGenerateColor(token, hex, wouldClipColor)\n\t\t}\n\t}\n\n\treturn token\n}\n\ntype parsedColor struct {\n\tx, y, z       F64    // color if hasColorSpace == true\n\thex           uint32 // color and alpha if hasColorSpace == false, alpha if hasColorSpace == true\n\thasColorSpace bool\n}\n\nfunc looksLikeColor(token css_ast.Token) bool {\n\tswitch token.Kind {\n\tcase css_lexer.TIdent:\n\t\tif _, ok := colorNameToHex[strings.ToLower(token.Text)]; ok {\n\t\t\treturn true\n\t\t}\n\n\tcase css_lexer.THash:\n\t\tswitch len(token.Text) {\n\t\tcase 3, 4, 6, 8:\n\t\t\tif _, ok := parseHex(token.Text); ok {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\n\tcase css_lexer.TFunction:\n\t\tswitch strings.ToLower(token.Text) {\n\t\tcase\n\t\t\t\"color-mix\",\n\t\t\t\"color\",\n\t\t\t\"hsl\",\n\t\t\t\"hsla\",\n\t\t\t\"hwb\",\n\t\t\t\"lab\",\n\t\t\t\"lch\",\n\t\t\t\"oklab\",\n\t\t\t\"oklch\",\n\t\t\t\"rgb\",\n\t\t\t\"rgba\":\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc parseColor(token css_ast.Token) (parsedColor, bool) {\n\ttext := token.Text\n\n\tswitch token.Kind {\n\tcase css_lexer.TIdent:\n\t\tif hex, ok := colorNameToHex[strings.ToLower(text)]; ok {\n\t\t\treturn parsedColor{hex: hex}, true\n\t\t}\n\n\tcase css_lexer.THash:\n\t\tswitch len(text) {\n\t\tcase 3:\n\t\t\t// \"#123\"\n\t\t\tif hex, ok := parseHex(text); ok {\n\t\t\t\treturn parsedColor{hex: (expandHex(hex) << 8) | 0xFF}, true\n\t\t\t}\n\n\t\tcase 4:\n\t\t\t// \"#1234\"\n\t\t\tif hex, ok := parseHex(text); ok {\n\t\t\t\treturn parsedColor{hex: expandHex(hex)}, true\n\t\t\t}\n\n\t\tcase 6:\n\t\t\t// \"#112233\"\n\t\t\tif hex, ok := parseHex(text); ok {\n\t\t\t\treturn parsedColor{hex: (hex << 8) | 0xFF}, true\n\t\t\t}\n\n\t\tcase 8:\n\t\t\t// \"#11223344\"\n\t\t\tif hex, ok := parseHex(text); ok {\n\t\t\t\treturn parsedColor{hex: hex}, true\n\t\t\t}\n\t\t}\n\n\tcase css_lexer.TFunction:\n\t\tlowerText := strings.ToLower(text)\n\t\tswitch lowerText {\n\t\tcase \"rgb\", \"rgba\":\n\t\t\targs := *token.Children\n\t\t\tvar r, g, b, a css_ast.Token\n\n\t\t\tswitch len(args) {\n\t\t\tcase 3:\n\t\t\t\t// \"rgb(1 2 3)\"\n\t\t\t\tr, g, b = args[0], args[1], args[2]\n\n\t\t\tcase 5:\n\t\t\t\t// \"rgba(1, 2, 3)\"\n\t\t\t\tif args[1].Kind == css_lexer.TComma && args[3].Kind == css_lexer.TComma {\n\t\t\t\t\tr, g, b = args[0], args[2], args[4]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// \"rgb(1 2 3 / 4%)\"\n\t\t\t\tif args[3].Kind == css_lexer.TDelimSlash {\n\t\t\t\t\tr, g, b, a = args[0], args[1], args[2], args[4]\n\t\t\t\t}\n\n\t\t\tcase 7:\n\t\t\t\t// \"rgb(1%, 2%, 3%, 4%)\"\n\t\t\t\tif args[1].Kind == css_lexer.TComma && args[3].Kind == css_lexer.TComma && args[5].Kind == css_lexer.TComma {\n\t\t\t\t\tr, g, b, a = args[0], args[2], args[4], args[6]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif r, ok := parseColorByte(r, 1); ok {\n\t\t\t\tif g, ok := parseColorByte(g, 1); ok {\n\t\t\t\t\tif b, ok := parseColorByte(b, 1); ok {\n\t\t\t\t\t\tif a, ok := parseAlphaByte(a); ok {\n\t\t\t\t\t\t\treturn parsedColor{hex: (r << 24) | (g << 16) | (b << 8) | a}, true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase \"hsl\", \"hsla\":\n\t\t\targs := *token.Children\n\t\t\tvar h, s, l, a css_ast.Token\n\n\t\t\tswitch len(args) {\n\t\t\tcase 3:\n\t\t\t\t// \"hsl(1 2 3)\"\n\t\t\t\th, s, l = args[0], args[1], args[2]\n\n\t\t\tcase 5:\n\t\t\t\t// \"hsla(1, 2, 3)\"\n\t\t\t\tif args[1].Kind == css_lexer.TComma && args[3].Kind == css_lexer.TComma {\n\t\t\t\t\th, s, l = args[0], args[2], args[4]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// \"hsl(1 2 3 / 4%)\"\n\t\t\t\tif args[3].Kind == css_lexer.TDelimSlash {\n\t\t\t\t\th, s, l, a = args[0], args[1], args[2], args[4]\n\t\t\t\t}\n\n\t\t\tcase 7:\n\t\t\t\t// \"hsl(1%, 2%, 3%, 4%)\"\n\t\t\t\tif args[1].Kind == css_lexer.TComma && args[3].Kind == css_lexer.TComma && args[5].Kind == css_lexer.TComma {\n\t\t\t\t\th, s, l, a = args[0], args[2], args[4], args[6]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// HSL => RGB\n\t\t\tif h, ok := degreesForAngle(h); ok {\n\t\t\t\tif s, ok := s.ClampedFractionForPercentage(); ok {\n\t\t\t\t\tif l, ok := l.ClampedFractionForPercentage(); ok {\n\t\t\t\t\t\tif a, ok := parseAlphaByte(a); ok {\n\t\t\t\t\t\t\tr, g, b := hslToRgb(helpers.NewF64(h), helpers.NewF64(s), helpers.NewF64(l))\n\t\t\t\t\t\t\treturn parsedColor{hex: packRGBA(r, g, b, a)}, true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase \"hwb\":\n\t\t\targs := *token.Children\n\t\t\tvar h, s, l, a css_ast.Token\n\n\t\t\tswitch len(args) {\n\t\t\tcase 3:\n\t\t\t\t// \"hwb(1 2 3)\"\n\t\t\t\th, s, l = args[0], args[1], args[2]\n\n\t\t\tcase 5:\n\t\t\t\t// \"hwb(1 2 3 / 4%)\"\n\t\t\t\tif args[3].Kind == css_lexer.TDelimSlash {\n\t\t\t\t\th, s, l, a = args[0], args[1], args[2], args[4]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// HWB => RGB\n\t\t\tif h, ok := degreesForAngle(h); ok {\n\t\t\t\tif white, ok := s.ClampedFractionForPercentage(); ok {\n\t\t\t\t\tif black, ok := l.ClampedFractionForPercentage(); ok {\n\t\t\t\t\t\tif a, ok := parseAlphaByte(a); ok {\n\t\t\t\t\t\t\tr, g, b := hwbToRgb(helpers.NewF64(h), helpers.NewF64(white), helpers.NewF64(black))\n\t\t\t\t\t\t\treturn parsedColor{hex: packRGBA(r, g, b, a)}, true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase \"color\":\n\t\t\targs := *token.Children\n\t\t\tvar colorSpace, alpha css_ast.Token\n\n\t\t\tswitch len(args) {\n\t\t\tcase 4:\n\t\t\t\t// \"color(xyz 1 2 3)\"\n\t\t\t\tcolorSpace = args[0]\n\n\t\t\tcase 6:\n\t\t\t\t// \"color(xyz 1 2 3 / 50%)\"\n\t\t\t\tif args[4].Kind == css_lexer.TDelimSlash {\n\t\t\t\t\tcolorSpace, alpha = args[0], args[5]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif colorSpace.Kind == css_lexer.TIdent {\n\t\t\t\tif v0, ok := args[1].NumberOrFractionForPercentage(1, 0); ok {\n\t\t\t\t\tif v1, ok := args[2].NumberOrFractionForPercentage(1, 0); ok {\n\t\t\t\t\t\tif v2, ok := args[3].NumberOrFractionForPercentage(1, 0); ok {\n\t\t\t\t\t\t\tif a, ok := parseAlphaByte(alpha); ok {\n\t\t\t\t\t\t\t\tv0, v1, v2 := helpers.NewF64(v0), helpers.NewF64(v1), helpers.NewF64(v2)\n\t\t\t\t\t\t\t\tswitch strings.ToLower(colorSpace.Text) {\n\t\t\t\t\t\t\t\tcase \"a98-rgb\":\n\t\t\t\t\t\t\t\t\tr, g, b := lin_a98rgb(v0, v1, v2)\n\t\t\t\t\t\t\t\t\tx, y, z := lin_a98rgb_to_xyz(r, g, b)\n\t\t\t\t\t\t\t\t\treturn parsedColor{hasColorSpace: true, x: x, y: y, z: z, hex: a}, true\n\n\t\t\t\t\t\t\t\tcase \"display-p3\":\n\t\t\t\t\t\t\t\t\tr, g, b := lin_p3(v0, v1, v2)\n\t\t\t\t\t\t\t\t\tx, y, z := lin_p3_to_xyz(r, g, b)\n\t\t\t\t\t\t\t\t\treturn parsedColor{hasColorSpace: true, x: x, y: y, z: z, hex: a}, true\n\n\t\t\t\t\t\t\t\tcase \"prophoto-rgb\":\n\t\t\t\t\t\t\t\t\tr, g, b := lin_prophoto(v0, v1, v2)\n\t\t\t\t\t\t\t\t\tx, y, z := lin_prophoto_to_xyz(r, g, b)\n\t\t\t\t\t\t\t\t\tx, y, z = d50_to_d65(x, y, z)\n\t\t\t\t\t\t\t\t\treturn parsedColor{hasColorSpace: true, x: x, y: y, z: z, hex: a}, true\n\n\t\t\t\t\t\t\t\tcase \"rec2020\":\n\t\t\t\t\t\t\t\t\tr, g, b := lin_2020(v0, v1, v2)\n\t\t\t\t\t\t\t\t\tx, y, z := lin_2020_to_xyz(r, g, b)\n\t\t\t\t\t\t\t\t\treturn parsedColor{hasColorSpace: true, x: x, y: y, z: z, hex: a}, true\n\n\t\t\t\t\t\t\t\tcase \"srgb\":\n\t\t\t\t\t\t\t\t\tr, g, b := lin_srgb(v0, v1, v2)\n\t\t\t\t\t\t\t\t\tx, y, z := lin_srgb_to_xyz(r, g, b)\n\t\t\t\t\t\t\t\t\treturn parsedColor{hasColorSpace: true, x: x, y: y, z: z, hex: a}, true\n\n\t\t\t\t\t\t\t\tcase \"srgb-linear\":\n\t\t\t\t\t\t\t\t\tx, y, z := lin_srgb_to_xyz(v0, v1, v2)\n\t\t\t\t\t\t\t\t\treturn parsedColor{hasColorSpace: true, x: x, y: y, z: z, hex: a}, true\n\n\t\t\t\t\t\t\t\tcase \"xyz\", \"xyz-d65\":\n\t\t\t\t\t\t\t\t\treturn parsedColor{hasColorSpace: true, x: v0, y: v1, z: v2, hex: a}, true\n\n\t\t\t\t\t\t\t\tcase \"xyz-d50\":\n\t\t\t\t\t\t\t\t\tx, y, z := d50_to_d65(v0, v1, v2)\n\t\t\t\t\t\t\t\t\treturn parsedColor{hasColorSpace: true, x: x, y: y, z: z, hex: a}, true\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase \"lab\", \"lch\", \"oklab\", \"oklch\":\n\t\t\targs := *token.Children\n\t\t\tvar v0, v1, v2, alpha css_ast.Token\n\n\t\t\tswitch len(args) {\n\t\t\tcase 3:\n\t\t\t\t// \"lab(1 2 3)\"\n\t\t\t\tv0, v1, v2 = args[0], args[1], args[2]\n\n\t\t\tcase 5:\n\t\t\t\t// \"lab(1 2 3 / 50%)\"\n\t\t\t\tif args[3].Kind == css_lexer.TDelimSlash {\n\t\t\t\t\tv0, v1, v2, alpha = args[0], args[1], args[2], args[4]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif v0.Kind != css_lexer.T(0) {\n\t\t\t\tif alpha, ok := parseAlphaByte(alpha); ok {\n\t\t\t\t\tswitch lowerText {\n\t\t\t\t\tcase \"lab\":\n\t\t\t\t\t\tif v0, ok := v0.NumberOrFractionForPercentage(100, 0); ok {\n\t\t\t\t\t\t\tif v1, ok := v1.NumberOrFractionForPercentage(125, css_ast.AllowAnyPercentage); ok {\n\t\t\t\t\t\t\t\tif v2, ok := v2.NumberOrFractionForPercentage(125, css_ast.AllowAnyPercentage); ok {\n\t\t\t\t\t\t\t\t\tv0, v1, v2 := helpers.NewF64(v0), helpers.NewF64(v1), helpers.NewF64(v2)\n\t\t\t\t\t\t\t\t\tx, y, z := lab_to_xyz(v0, v1, v2)\n\t\t\t\t\t\t\t\t\tx, y, z = d50_to_d65(x, y, z)\n\t\t\t\t\t\t\t\t\treturn parsedColor{hasColorSpace: true, x: x, y: y, z: z, hex: alpha}, true\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase \"lch\":\n\t\t\t\t\t\tif v0, ok := v0.NumberOrFractionForPercentage(100, 0); ok {\n\t\t\t\t\t\t\tif v1, ok := v1.NumberOrFractionForPercentage(125, css_ast.AllowPercentageAbove100); ok {\n\t\t\t\t\t\t\t\tif v2, ok := degreesForAngle(v2); ok {\n\t\t\t\t\t\t\t\t\tv0, v1, v2 := helpers.NewF64(v0), helpers.NewF64(v1), helpers.NewF64(v2)\n\t\t\t\t\t\t\t\t\tl, a, b := lch_to_lab(v0, v1, v2)\n\t\t\t\t\t\t\t\t\tx, y, z := lab_to_xyz(l, a, b)\n\t\t\t\t\t\t\t\t\tx, y, z = d50_to_d65(x, y, z)\n\t\t\t\t\t\t\t\t\treturn parsedColor{hasColorSpace: true, x: x, y: y, z: z, hex: alpha}, true\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase \"oklab\":\n\t\t\t\t\t\tif v0, ok := v0.NumberOrFractionForPercentage(1, 0); ok {\n\t\t\t\t\t\t\tif v1, ok := v1.NumberOrFractionForPercentage(0.4, css_ast.AllowAnyPercentage); ok {\n\t\t\t\t\t\t\t\tif v2, ok := v2.NumberOrFractionForPercentage(0.4, css_ast.AllowAnyPercentage); ok {\n\t\t\t\t\t\t\t\t\tv0, v1, v2 := helpers.NewF64(v0), helpers.NewF64(v1), helpers.NewF64(v2)\n\t\t\t\t\t\t\t\t\tx, y, z := oklab_to_xyz(v0, v1, v2)\n\t\t\t\t\t\t\t\t\treturn parsedColor{hasColorSpace: true, x: x, y: y, z: z, hex: alpha}, true\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase \"oklch\":\n\t\t\t\t\t\tif v0, ok := v0.NumberOrFractionForPercentage(1, 0); ok {\n\t\t\t\t\t\t\tif v1, ok := v1.NumberOrFractionForPercentage(0.4, css_ast.AllowPercentageAbove100); ok {\n\t\t\t\t\t\t\t\tif v2, ok := degreesForAngle(v2); ok {\n\t\t\t\t\t\t\t\t\tv0, v1, v2 := helpers.NewF64(v0), helpers.NewF64(v1), helpers.NewF64(v2)\n\t\t\t\t\t\t\t\t\tl, a, b := oklch_to_oklab(v0, v1, v2)\n\t\t\t\t\t\t\t\t\tx, y, z := oklab_to_xyz(l, a, b)\n\t\t\t\t\t\t\t\t\treturn parsedColor{hasColorSpace: true, x: x, y: y, z: z, hex: alpha}, true\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn parsedColor{}, false\n}\n\n// Reference: https://drafts.csswg.org/css-color/#hwb-to-rgb\nfunc hwbToRgb(hue F64, white F64, black F64) (r F64, g F64, b F64) {\n\tif white.Add(black).Value() >= 1 {\n\t\tgray := white.Div(white.Add(black))\n\t\treturn gray, gray, gray\n\t}\n\tdelta := white.Add(black).Neg().AddConst(1)\n\tr, g, b = hslToRgb(hue, helpers.NewF64(1), helpers.NewF64(0.5))\n\tr = delta.Mul(r).Add(white)\n\tg = delta.Mul(g).Add(white)\n\tb = delta.Mul(b).Add(white)\n\treturn\n}\n\n// Reference https://drafts.csswg.org/css-color/#hsl-to-rgb\nfunc hslToRgb(hue F64, sat F64, light F64) (r F64, g F64, b F64) {\n\thue = hue.DivConst(360.0)\n\tvar t2 F64\n\tif light.Value() <= 0.5 {\n\t\tt2 = sat.AddConst(1).Mul(light)\n\t} else {\n\t\tt2 = light.Add(sat).Sub(light.Mul(sat))\n\t}\n\tt1 := light.MulConst(2).Sub(t2)\n\tr = hueToRgb(t1, t2, hue.AddConst(1.0/3.0))\n\tg = hueToRgb(t1, t2, hue)\n\tb = hueToRgb(t1, t2, hue.SubConst(1.0/3.0))\n\treturn\n}\n\nfunc hueToRgb(t1 F64, t2 F64, hue F64) F64 {\n\thue = hue.Sub(hue.Floor())\n\thue = hue.MulConst(6)\n\tvar f F64\n\tif hue.Value() < 1 {\n\t\tf = helpers.Lerp(t1, t2, hue)\n\t} else if hue.Value() < 3 {\n\t\tf = t2\n\t} else if hue.Value() < 4 {\n\t\tf = helpers.Lerp(t1, t2, hue.Neg().AddConst(4))\n\t} else {\n\t\tf = t1\n\t}\n\treturn f\n}\n\nfunc packRGBA(rf F64, gf F64, bf F64, a uint32) uint32 {\n\tr := floatToByte(rf.Value())\n\tg := floatToByte(gf.Value())\n\tb := floatToByte(bf.Value())\n\treturn (r << 24) | (g << 16) | (b << 8) | a\n}\n\nfunc floatToByte(f float64) uint32 {\n\ti := int(math.Round(f * 255))\n\tif i < 0 {\n\t\ti = 0\n\t} else if i > 255 {\n\t\ti = 255\n\t}\n\treturn uint32(i)\n}\n\nfunc parseAlphaByte(token css_ast.Token) (uint32, bool) {\n\tif token.Kind == css_lexer.T(0) {\n\t\treturn 255, true\n\t}\n\treturn parseColorByte(token, 255)\n}\n\nfunc parseColorByte(token css_ast.Token, scale float64) (uint32, bool) {\n\tvar i int\n\tvar ok bool\n\n\tswitch token.Kind {\n\tcase css_lexer.TNumber:\n\t\tif f, err := strconv.ParseFloat(token.Text, 64); err == nil {\n\t\t\ti = int(math.Round(f * scale))\n\t\t\tok = true\n\t\t}\n\n\tcase css_lexer.TPercentage:\n\t\tif f, err := strconv.ParseFloat(token.PercentageValue(), 64); err == nil {\n\t\t\ti = int(math.Round(f * (255.0 / 100.0)))\n\t\t\tok = true\n\t\t}\n\t}\n\n\tif i < 0 {\n\t\ti = 0\n\t} else if i > 255 {\n\t\ti = 255\n\t}\n\treturn uint32(i), ok\n}\n\nfunc tryToConvertToHexWithoutClipping(x F64, y F64, z F64, a uint32) (uint32, bool) {\n\tr, g, b := gam_srgb(xyz_to_lin_srgb(x, y, z))\n\tif r.Value() < -0.5/255 || r.Value() > 255.5/255 ||\n\t\tg.Value() < -0.5/255 || g.Value() > 255.5/255 ||\n\t\tb.Value() < -0.5/255 || b.Value() > 255.5/255 {\n\t\treturn 0, false\n\t}\n\treturn packRGBA(r, g, b, a), true\n}\n\nfunc (p *parser) tryToGenerateColor(token css_ast.Token, color parsedColor, wouldClipColor *bool) css_ast.Token {\n\t// Note: Do NOT remove color information from fully transparent colors.\n\t// Safari behaves differently than other browsers for color interpolation:\n\t// https://css-tricks.com/thing-know-gradients-transparent-black/\n\n\t// Attempt to convert other color spaces to sRGB, and only continue if the\n\t// result (rounded to the nearest byte) will be in the 0-to-1 sRGB range\n\tvar hex uint32\n\tif !color.hasColorSpace {\n\t\thex = color.hex\n\t} else if result, ok := tryToConvertToHexWithoutClipping(color.x, color.y, color.z, color.hex); ok {\n\t\thex = result\n\t} else if wouldClipColor != nil {\n\t\t*wouldClipColor = true\n\t\treturn token\n\t} else {\n\t\tr, g, b := gamut_mapping_xyz_to_srgb(color.x, color.y, color.z)\n\t\thex = packRGBA(r, g, b, color.hex)\n\t}\n\n\tif hexA(hex) == 255 {\n\t\ttoken.Children = nil\n\t\tif name, ok := shortColorName[hex]; ok && p.options.minifySyntax {\n\t\t\ttoken.Kind = css_lexer.TIdent\n\t\t\ttoken.Text = name\n\t\t} else {\n\t\t\ttoken.Kind = css_lexer.THash\n\t\t\thex >>= 8\n\t\t\tcompact := compactHex(hex)\n\t\t\tif p.options.minifySyntax && hex == expandHex(compact) {\n\t\t\t\ttoken.Text = fmt.Sprintf(\"%03x\", compact)\n\t\t\t} else {\n\t\t\t\ttoken.Text = fmt.Sprintf(\"%06x\", hex)\n\t\t\t}\n\t\t}\n\t} else if !p.options.unsupportedCSSFeatures.Has(compat.HexRGBA) {\n\t\ttoken.Children = nil\n\t\ttoken.Kind = css_lexer.THash\n\t\tcompact := compactHex(hex)\n\t\tif p.options.minifySyntax && hex == expandHex(compact) {\n\t\t\ttoken.Text = fmt.Sprintf(\"%04x\", compact)\n\t\t} else {\n\t\t\ttoken.Text = fmt.Sprintf(\"%08x\", hex)\n\t\t}\n\t} else {\n\t\ttoken.Kind = css_lexer.TFunction\n\t\ttoken.Text = \"rgba\"\n\t\tcommaToken := p.commaToken(token.Loc)\n\t\tindex := hexA(hex) * 4\n\t\talpha := alphaFractionTable[index : index+4]\n\t\tif space := strings.IndexByte(alpha, ' '); space != -1 {\n\t\t\talpha = alpha[:space]\n\t\t}\n\t\ttoken.Children = &[]css_ast.Token{\n\t\t\t{Loc: token.Loc, Kind: css_lexer.TNumber, Text: strconv.Itoa(hexR(hex))}, commaToken,\n\t\t\t{Loc: token.Loc, Kind: css_lexer.TNumber, Text: strconv.Itoa(hexG(hex))}, commaToken,\n\t\t\t{Loc: token.Loc, Kind: css_lexer.TNumber, Text: strconv.Itoa(hexB(hex))}, commaToken,\n\t\t\t{Loc: token.Loc, Kind: css_lexer.TNumber, Text: alpha},\n\t\t}\n\t}\n\n\treturn token\n}\n\n// Every four characters in this table is the fraction for that index\nconst alphaFractionTable string = \"\" +\n\t\"0   .004.008.01 .016.02 .024.027.03 .035.04 .043.047.05 .055.06 \" +\n\t\".063.067.07 .075.08 .082.086.09 .094.098.1  .106.11 .114.118.12 \" +\n\t\".125.13 .133.137.14 .145.15 .153.157.16 .165.17 .173.176.18 .184\" +\n\t\".19 .192.196.2  .204.208.21 .216.22 .224.227.23 .235.24 .243.247\" +\n\t\".25 .255.26 .263.267.27 .275.28 .282.286.29 .294.298.3  .306.31 \" +\n\t\".314.318.32 .325.33 .333.337.34 .345.35 .353.357.36 .365.37 .373\" +\n\t\".376.38 .384.39 .392.396.4  .404.408.41 .416.42 .424.427.43 .435\" +\n\t\".44 .443.447.45 .455.46 .463.467.47 .475.48 .482.486.49 .494.498\" +\n\t\".5  .506.51 .514.518.52 .525.53 .533.537.54 .545.55 .553.557.56 \" +\n\t\".565.57 .573.576.58 .584.59 .592.596.6  .604.608.61 .616.62 .624\" +\n\t\".627.63 .635.64 .643.647.65 .655.66 .663.667.67 .675.68 .682.686\" +\n\t\".69 .694.698.7  .706.71 .714.718.72 .725.73 .733.737.74 .745.75 \" +\n\t\".753.757.76 .765.77 .773.776.78 .784.79 .792.796.8  .804.808.81 \" +\n\t\".816.82 .824.827.83 .835.84 .843.847.85 .855.86 .863.867.87 .875\" +\n\t\".88 .882.886.89 .894.898.9  .906.91 .914.918.92 .925.93 .933.937\" +\n\t\".94 .945.95 .953.957.96 .965.97 .973.976.98 .984.99 .992.9961   \"\n"
  },
  {
    "path": "internal/css_parser/css_decls_composes.go",
    "content": "package css_parser\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\ntype composesContext struct {\n\tparentRefs   []ast.Ref\n\tparentRange  logger.Range\n\tproblemRange logger.Range\n}\n\nfunc (p *parser) handleComposesPragma(context composesContext, tokens []css_ast.Token) {\n\ttype nameWithLoc struct {\n\t\tloc  logger.Loc\n\t\ttext string\n\t}\n\tvar names []nameWithLoc\n\tfromGlobal := false\n\n\tfor i, t := range tokens {\n\t\tif t.Kind == css_lexer.TIdent {\n\t\t\t// Check for a \"from\" clause at the end\n\t\t\tif strings.EqualFold(t.Text, \"from\") && i+2 == len(tokens) {\n\t\t\t\tlast := tokens[i+1]\n\n\t\t\t\t// A string or a URL is an external file\n\t\t\t\tif last.Kind == css_lexer.TString || last.Kind == css_lexer.TURL {\n\t\t\t\t\tvar importRecordIndex uint32\n\t\t\t\t\tif last.Kind == css_lexer.TString {\n\t\t\t\t\t\timportRecordIndex = uint32(len(p.importRecords))\n\t\t\t\t\t\tp.importRecords = append(p.importRecords, ast.ImportRecord{\n\t\t\t\t\t\t\tKind:  ast.ImportComposesFrom,\n\t\t\t\t\t\t\tPath:  logger.Path{Text: last.Text},\n\t\t\t\t\t\t\tRange: p.source.RangeOfString(last.Loc),\n\t\t\t\t\t\t})\n\t\t\t\t\t} else {\n\t\t\t\t\t\timportRecordIndex = last.PayloadIndex\n\t\t\t\t\t\tp.importRecords[importRecordIndex].Kind = ast.ImportComposesFrom\n\t\t\t\t\t}\n\t\t\t\t\tfor _, parentRef := range context.parentRefs {\n\t\t\t\t\t\tcomposes := p.composes[parentRef]\n\t\t\t\t\t\tfor _, name := range names {\n\t\t\t\t\t\t\tcomposes.ImportedNames = append(composes.ImportedNames, css_ast.ImportedComposesName{\n\t\t\t\t\t\t\t\tImportRecordIndex: importRecordIndex,\n\t\t\t\t\t\t\t\tAlias:             name.text,\n\t\t\t\t\t\t\t\tAliasLoc:          name.loc,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// An identifier must be \"global\"\n\t\t\t\tif last.Kind == css_lexer.TIdent {\n\t\t\t\t\tif strings.EqualFold(last.Text, \"global\") {\n\t\t\t\t\t\tfromGlobal = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\tp.log.AddID(logger.MsgID_CSS_CSSSyntaxError, logger.Warning, &p.tracker, css_lexer.RangeOfIdentifier(p.source, last.Loc),\n\t\t\t\t\t\tfmt.Sprintf(\"\\\"composes\\\" declaration uses invalid location %q\", last.Text))\n\t\t\t\t\tp.prevError = t.Loc\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tnames = append(names, nameWithLoc{t.Loc, t.Text})\n\t\t\tcontinue\n\t\t}\n\n\t\t// Any unexpected tokens are a syntax error\n\t\tvar text string\n\t\tswitch t.Kind {\n\t\tcase css_lexer.TURL, css_lexer.TBadURL, css_lexer.TString, css_lexer.TUnterminatedString:\n\t\t\ttext = fmt.Sprintf(\"Unexpected %s\", t.Kind.String())\n\t\tdefault:\n\t\t\ttext = fmt.Sprintf(\"Unexpected %q\", t.Text)\n\t\t}\n\t\tp.log.AddID(logger.MsgID_CSS_CSSSyntaxError, logger.Warning, &p.tracker, logger.Range{Loc: t.Loc}, text)\n\t\tp.prevError = t.Loc\n\t\treturn\n\t}\n\n\t// If we get here, all of these names are not references to another file\n\told := p.makeLocalSymbols\n\tif fromGlobal {\n\t\tp.makeLocalSymbols = false\n\t}\n\tfor _, parentRef := range context.parentRefs {\n\t\tcomposes := p.composes[parentRef]\n\t\tfor _, name := range names {\n\t\t\tcomposes.Names = append(composes.Names, p.symbolForName(name.loc, name.text))\n\t\t}\n\t}\n\tp.makeLocalSymbols = old\n}\n"
  },
  {
    "path": "internal/css_parser/css_decls_container.go",
    "content": "package css_parser\n\nimport (\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n)\n\n// Scan for container names in the \"container\" shorthand property\nfunc (p *parser) processContainerShorthand(tokens []css_ast.Token) {\n\t// Validate the syntax\n\tfor i, t := range tokens {\n\t\tif t.Kind == css_lexer.TIdent {\n\t\t\tcontinue\n\t\t}\n\t\tif t.Kind == css_lexer.TDelimSlash && i+2 == len(tokens) && tokens[i+1].Kind == css_lexer.TIdent {\n\t\t\tbreak\n\t\t}\n\t\treturn\n\t}\n\n\t// Convert any local names\n\tfor i, t := range tokens {\n\t\tif t.Kind != css_lexer.TIdent {\n\t\t\tbreak\n\t\t}\n\t\tp.handleSingleContainerName(&tokens[i])\n\t}\n}\n\nfunc (p *parser) processContainerName(tokens []css_ast.Token) {\n\t// Validate the syntax\n\tfor _, t := range tokens {\n\t\tif t.Kind != css_lexer.TIdent {\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Convert any local names\n\tfor i := range tokens {\n\t\tp.handleSingleContainerName(&tokens[i])\n\t}\n}\n\nfunc (p *parser) handleSingleContainerName(token *css_ast.Token) {\n\tif lower := strings.ToLower(token.Text); lower == \"none\" || cssWideAndReservedKeywords[lower] {\n\t\treturn\n\t}\n\n\ttoken.Kind = css_lexer.TSymbol\n\ttoken.PayloadIndex = p.symbolForName(token.Loc, token.Text).Ref.InnerIndex\n}\n"
  },
  {
    "path": "internal/css_parser/css_decls_font.go",
    "content": "package css_parser\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n)\n\n// Specification: https://drafts.csswg.org/css-fonts/#font-prop\n// [ <font-style> || <font-variant-css2> || <font-weight> || <font-stretch-css3> ]? <font-size> [ / <line-height> ]? <font-family>\nfunc (p *parser) mangleFont(tokens []css_ast.Token) []css_ast.Token {\n\tvar result []css_ast.Token\n\n\t// Scan up to the font size\n\tpos := 0\n\tfor ; pos < len(tokens); pos++ {\n\t\ttoken := tokens[pos]\n\t\tif isFontSize(token) {\n\t\t\tbreak\n\t\t}\n\n\t\tswitch token.Kind {\n\t\tcase css_lexer.TIdent:\n\t\t\tswitch strings.ToLower(token.Text) {\n\t\t\tcase \"normal\":\n\t\t\t\t// \"All subproperties of the font property are first reset to their initial values\"\n\t\t\t\t// This implies that \"normal\" doesn't do anything. Also all of the optional values\n\t\t\t\t// contain \"normal\" as an option and they are unordered so it's impossible to say\n\t\t\t\t// what property \"normal\" corresponds to. Just drop these tokens to save space.\n\t\t\t\tcontinue\n\n\t\t\t// <font-style>\n\t\t\tcase \"italic\":\n\t\t\tcase \"oblique\":\n\t\t\t\tif pos+1 < len(tokens) && tokens[pos+1].IsAngle() {\n\t\t\t\t\tresult = append(result, token, tokens[pos+1])\n\t\t\t\t\tpos++\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t// <font-variant-css2>\n\t\t\tcase \"small-caps\":\n\n\t\t\t// <font-weight>\n\t\t\tcase \"bold\", \"bolder\", \"lighter\":\n\t\t\t\tresult = append(result, p.mangleFontWeight(token))\n\t\t\t\tcontinue\n\n\t\t\t// <font-stretch-css3>\n\t\t\tcase \"ultra-condensed\", \"extra-condensed\", \"condensed\", \"semi-condensed\",\n\t\t\t\t\"semi-expanded\", \"expanded\", \"extra-expanded\", \"ultra-expanded\":\n\n\t\t\tdefault:\n\t\t\t\t// All other tokens are unrecognized, so we bail if we hit one\n\t\t\t\treturn tokens\n\t\t\t}\n\t\t\tresult = append(result, token)\n\n\t\tcase css_lexer.TNumber:\n\t\t\t// \"Only values greater than or equal to 1, and less than or equal to\n\t\t\t// 1000, are valid, and all other values are invalid.\"\n\t\t\tif value, err := strconv.ParseFloat(token.Text, 64); err != nil || value < 1 || value > 1000 {\n\t\t\t\treturn tokens\n\t\t\t}\n\t\t\tresult = append(result, token)\n\n\t\tdefault:\n\t\t\t// All other tokens are unrecognized, so we bail if we hit one\n\t\t\treturn tokens\n\t\t}\n\t}\n\n\t// <font-size>\n\tif pos == len(tokens) {\n\t\treturn tokens\n\t}\n\tresult = append(result, tokens[pos])\n\tpos++\n\n\t// / <line-height>\n\tif pos < len(tokens) && tokens[pos].Kind == css_lexer.TDelimSlash {\n\t\tif pos+1 == len(tokens) {\n\t\t\treturn tokens\n\t\t}\n\t\tresult = append(result, tokens[pos], tokens[pos+1])\n\t\tpos += 2\n\n\t\t// Remove the whitespace around the \"/\" character\n\t\tif p.options.minifyWhitespace {\n\t\t\tresult[len(result)-3].Whitespace &= ^css_ast.WhitespaceAfter\n\t\t\tresult[len(result)-2].Whitespace = 0\n\t\t\tresult[len(result)-1].Whitespace &= ^css_ast.WhitespaceBefore\n\t\t}\n\t}\n\n\t// <font-family>\n\tif family, ok := p.mangleFontFamily(tokens[pos:]); ok {\n\t\tif len(result) > 0 && len(family) > 0 && family[0].Kind != css_lexer.TString {\n\t\t\tfamily[0].Whitespace |= css_ast.WhitespaceBefore\n\t\t}\n\t\treturn append(result, family...)\n\t}\n\treturn tokens\n}\n\nvar fontSizeKeywords = map[string]bool{\n\t// <absolute-size>: https://drafts.csswg.org/css-fonts/#valdef-font-size-absolute-size\n\t\"xx-small\":  true,\n\t\"x-small\":   true,\n\t\"small\":     true,\n\t\"medium\":    true,\n\t\"large\":     true,\n\t\"x-large\":   true,\n\t\"xx-large\":  true,\n\t\"xxx-large\": true,\n\n\t// <relative-size>: https://drafts.csswg.org/css-fonts/#valdef-font-size-relative-size\n\t\"larger\":  true,\n\t\"smaller\": true,\n}\n\n// Specification: https://drafts.csswg.org/css-fonts/#font-size-prop\nfunc isFontSize(token css_ast.Token) bool {\n\t// <length-percentage>\n\tif token.Kind == css_lexer.TDimension || token.Kind == css_lexer.TPercentage {\n\t\treturn true\n\t}\n\n\t// <absolute-size> or <relative-size>\n\tif token.Kind == css_lexer.TIdent {\n\t\t_, ok := fontSizeKeywords[strings.ToLower(token.Text)]\n\t\treturn ok\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "internal/css_parser/css_decls_font_family.go",
    "content": "package css_parser\n\nimport (\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n)\n\n// These keywords usually require special handling when parsing.\n\n// Declaring a property to have these values explicitly specifies a particular\n// defaulting behavior instead of setting the property to that identifier value.\n// As specified in CSS Values and Units Level 3, all CSS properties can accept\n// these values.\n//\n// For example, \"font-family: 'inherit'\" sets the font family to the font named\n// \"inherit\" while \"font-family: inherit\" sets the font family to the inherited\n// value.\n//\n// Note that other CSS specifications can define additional CSS-wide keywords,\n// which we should copy here whenever new ones are created so we can quote those\n// identifiers to avoid collisions with any newly-created CSS-wide keywords.\nvar cssWideAndReservedKeywords = map[string]bool{\n\t// CSS Values and Units Level 3: https://drafts.csswg.org/css-values-3/#common-keywords\n\t\"initial\": true, // CSS-wide keyword\n\t\"inherit\": true, // CSS-wide keyword\n\t\"unset\":   true, // CSS-wide keyword\n\t\"default\": true, // CSS reserved keyword\n\n\t// CSS Cascading and Inheritance Level 5: https://drafts.csswg.org/css-cascade-5/#defaulting-keywords\n\t\"revert\":       true, // Cascade-dependent keyword\n\t\"revert-layer\": true, // Cascade-dependent keyword\n}\n\n// Font family names that happen to be the same as a keyword value must be\n// quoted to prevent confusion with the keywords with the same names. UAs must\n// not consider these keywords as matching the <family-name> type.\n// Specification: https://drafts.csswg.org/css-fonts/#generic-font-families\nvar genericFamilyNames = map[string]bool{\n\t\"serif\":         true,\n\t\"sans-serif\":    true,\n\t\"cursive\":       true,\n\t\"fantasy\":       true,\n\t\"monospace\":     true,\n\t\"system-ui\":     true,\n\t\"emoji\":         true,\n\t\"math\":          true,\n\t\"fangsong\":      true,\n\t\"ui-serif\":      true,\n\t\"ui-sans-serif\": true,\n\t\"ui-monospace\":  true,\n\t\"ui-rounded\":    true,\n}\n\n// Specification: https://drafts.csswg.org/css-fonts/#font-family-prop\nfunc (p *parser) mangleFontFamily(tokens []css_ast.Token) ([]css_ast.Token, bool) {\n\tresult, rest, ok := p.mangleFamilyNameOrGenericName(nil, tokens)\n\tif !ok {\n\t\treturn nil, false\n\t}\n\n\tfor len(rest) > 0 && rest[0].Kind == css_lexer.TComma {\n\t\tresult, rest, ok = p.mangleFamilyNameOrGenericName(append(result, rest[0]), rest[1:])\n\t\tif !ok {\n\t\t\treturn nil, false\n\t\t}\n\t}\n\n\tif len(rest) > 0 {\n\t\treturn nil, false\n\t}\n\n\treturn result, true\n}\n\nfunc (p *parser) mangleFamilyNameOrGenericName(result []css_ast.Token, tokens []css_ast.Token) ([]css_ast.Token, []css_ast.Token, bool) {\n\tif len(tokens) > 0 {\n\t\tt := tokens[0]\n\n\t\t// Handle <generic-family>\n\t\tif t.Kind == css_lexer.TIdent && genericFamilyNames[t.Text] {\n\t\t\treturn append(result, t), tokens[1:], true\n\t\t}\n\n\t\t// Handle <family-name>\n\t\tif t.Kind == css_lexer.TString {\n\t\t\t// \"If a sequence of identifiers is given as a <family-name>, the computed\n\t\t\t// value is the name converted to a string by joining all the identifiers\n\t\t\t// in the sequence by single spaces.\"\n\t\t\t//\n\t\t\t// More information: https://mathiasbynens.be/notes/unquoted-font-family\n\t\t\tnames := strings.Split(t.Text, \" \")\n\t\t\tfor _, name := range names {\n\t\t\t\tif !isValidCustomIdent(name, genericFamilyNames) {\n\t\t\t\t\treturn append(result, t), tokens[1:], true\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor i, name := range names {\n\t\t\t\tvar whitespace css_ast.WhitespaceFlags\n\t\t\t\tif i != 0 || !p.options.minifyWhitespace {\n\t\t\t\t\twhitespace = css_ast.WhitespaceBefore\n\t\t\t\t}\n\t\t\t\tresult = append(result, css_ast.Token{\n\t\t\t\t\tLoc:        t.Loc,\n\t\t\t\t\tKind:       css_lexer.TIdent,\n\t\t\t\t\tText:       name,\n\t\t\t\t\tWhitespace: whitespace,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn result, tokens[1:], true\n\t\t}\n\n\t\t// \"Font family names other than generic families must either be given\n\t\t// quoted as <string>s, or unquoted as a sequence of one or more\n\t\t// <custom-ident>.\"\n\t\tif t.Kind == css_lexer.TIdent {\n\t\t\tfor {\n\t\t\t\tif !isValidCustomIdent(t.Text, genericFamilyNames) {\n\t\t\t\t\treturn nil, nil, false\n\t\t\t\t}\n\t\t\t\tresult = append(result, t)\n\t\t\t\ttokens = tokens[1:]\n\t\t\t\tif len(tokens) == 0 || tokens[0].Kind != css_lexer.TIdent {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tt = tokens[0]\n\t\t\t}\n\t\t\treturn result, tokens, true\n\t\t}\n\t}\n\n\t// Anything other than the cases listed above causes us to bail\n\treturn nil, nil, false\n}\n\n// Specification: https://drafts.csswg.org/css-values-4/#custom-idents\nfunc isValidCustomIdent(text string, predefinedKeywords map[string]bool) bool {\n\tloweredText := strings.ToLower(text)\n\n\tif predefinedKeywords[loweredText] {\n\t\treturn false\n\t}\n\tif cssWideAndReservedKeywords[loweredText] {\n\t\treturn false\n\t}\n\tif loweredText == \"\" {\n\t\treturn false\n\t}\n\n\t// validate if it contains characters which needs to be escaped\n\tif !css_lexer.WouldStartIdentifierWithoutEscapes(text) {\n\t\treturn false\n\t}\n\tfor _, c := range text {\n\t\tif !css_lexer.IsNameContinue(c) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n"
  },
  {
    "path": "internal/css_parser/css_decls_font_weight.go",
    "content": "package css_parser\n\nimport (\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n)\n\nfunc (p *parser) mangleFontWeight(token css_ast.Token) css_ast.Token {\n\tif token.Kind != css_lexer.TIdent {\n\t\treturn token\n\t}\n\n\tswitch strings.ToLower(token.Text) {\n\tcase \"normal\":\n\t\ttoken.Text = \"400\"\n\t\ttoken.Kind = css_lexer.TNumber\n\tcase \"bold\":\n\t\ttoken.Text = \"700\"\n\t\ttoken.Kind = css_lexer.TNumber\n\t}\n\n\treturn token\n}\n"
  },
  {
    "path": "internal/css_parser/css_decls_gradient.go",
    "content": "package css_parser\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\ntype gradientKind uint8\n\nconst (\n\tlinearGradient gradientKind = iota\n\tradialGradient\n\tconicGradient\n)\n\ntype parsedGradient struct {\n\tleadingTokens []css_ast.Token\n\tcolorStops    []colorStop\n\tkind          gradientKind\n\trepeating     bool\n}\n\ntype colorStop struct {\n\tpositions []css_ast.Token\n\tcolor     css_ast.Token\n\tmidpoint  css_ast.Token // Absent if \"midpoint.Kind == css_lexer.T(0)\"\n}\n\nfunc parseGradient(token css_ast.Token) (gradient parsedGradient, success bool) {\n\tif token.Kind != css_lexer.TFunction {\n\t\treturn\n\t}\n\n\tswitch strings.ToLower(token.Text) {\n\tcase \"linear-gradient\":\n\t\tgradient.kind = linearGradient\n\n\tcase \"radial-gradient\":\n\t\tgradient.kind = radialGradient\n\n\tcase \"conic-gradient\":\n\t\tgradient.kind = conicGradient\n\n\tcase \"repeating-linear-gradient\":\n\t\tgradient.kind = linearGradient\n\t\tgradient.repeating = true\n\n\tcase \"repeating-radial-gradient\":\n\t\tgradient.kind = radialGradient\n\t\tgradient.repeating = true\n\n\tcase \"repeating-conic-gradient\":\n\t\tgradient.kind = conicGradient\n\t\tgradient.repeating = true\n\n\tdefault:\n\t\treturn\n\t}\n\n\t// Bail if any token is a \"var()\" since it may introduce commas\n\ttokens := *token.Children\n\tfor _, t := range tokens {\n\t\tif t.Kind == css_lexer.TFunction && strings.EqualFold(t.Text, \"var\") {\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Try to strip the initial tokens\n\tif len(tokens) > 0 && !looksLikeColor(tokens[0]) {\n\t\ti := 0\n\t\tfor i < len(tokens) && tokens[i].Kind != css_lexer.TComma {\n\t\t\ti++\n\t\t}\n\t\tgradient.leadingTokens = tokens[:i]\n\t\tif i < len(tokens) {\n\t\t\ttokens = tokens[i+1:]\n\t\t} else {\n\t\t\ttokens = nil\n\t\t}\n\t}\n\n\t// Try to parse the color stops\n\tfor len(tokens) > 0 {\n\t\t// Parse the color\n\t\tcolor := tokens[0]\n\t\tif !looksLikeColor(color) {\n\t\t\treturn\n\t\t}\n\t\ttokens = tokens[1:]\n\n\t\t// Parse up to two positions\n\t\tvar positions []css_ast.Token\n\t\tfor len(positions) < 2 && len(tokens) > 0 {\n\t\t\tposition := tokens[0]\n\t\t\tif position.Kind.IsNumeric() || (position.Kind == css_lexer.TFunction && strings.EqualFold(position.Text, \"calc\")) {\n\t\t\t\tpositions = append(positions, position)\n\t\t\t} else {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ttokens = tokens[1:]\n\t\t}\n\n\t\t// Parse the comma\n\t\tvar midpoint css_ast.Token\n\t\tif len(tokens) > 0 {\n\t\t\tif tokens[0].Kind != css_lexer.TComma {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttokens = tokens[1:]\n\t\t\tif len(tokens) == 0 {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Parse the midpoint, if any\n\t\t\tif len(tokens) > 0 && tokens[0].Kind.IsNumeric() {\n\t\t\t\tmidpoint = tokens[0]\n\t\t\t\ttokens = tokens[1:]\n\n\t\t\t\t// Followed by a mandatory comma\n\t\t\t\tif len(tokens) == 0 || tokens[0].Kind != css_lexer.TComma {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\ttokens = tokens[1:]\n\t\t\t}\n\t\t}\n\n\t\t// Add the color stop\n\t\tgradient.colorStops = append(gradient.colorStops, colorStop{\n\t\t\tcolor:     color,\n\t\t\tpositions: positions,\n\t\t\tmidpoint:  midpoint,\n\t\t})\n\t}\n\n\tsuccess = true\n\treturn\n}\n\nfunc (p *parser) generateGradient(token css_ast.Token, gradient parsedGradient) css_ast.Token {\n\tvar children []css_ast.Token\n\tcommaToken := p.commaToken(token.Loc)\n\n\tchildren = append(children, gradient.leadingTokens...)\n\tfor _, stop := range gradient.colorStops {\n\t\tif len(children) > 0 {\n\t\t\tchildren = append(children, commaToken)\n\t\t}\n\t\tif len(stop.positions) == 0 && stop.midpoint.Kind == css_lexer.T(0) {\n\t\t\tstop.color.Whitespace &= ^css_ast.WhitespaceAfter\n\t\t}\n\t\tchildren = append(children, stop.color)\n\t\tchildren = append(children, stop.positions...)\n\t\tif stop.midpoint.Kind != css_lexer.T(0) {\n\t\t\tchildren = append(children, commaToken, stop.midpoint)\n\t\t}\n\t}\n\n\ttoken.Children = &children\n\treturn token\n}\n\nfunc (p *parser) lowerAndMinifyGradient(token css_ast.Token, wouldClipColor *bool) css_ast.Token {\n\tgradient, ok := parseGradient(token)\n\tif !ok {\n\t\treturn token\n\t}\n\n\tlowerMidpoints := p.options.unsupportedCSSFeatures.Has(compat.GradientMidpoints)\n\tlowerColorSpaces := p.options.unsupportedCSSFeatures.Has(compat.ColorFunctions)\n\tlowerInterpolation := p.options.unsupportedCSSFeatures.Has(compat.GradientInterpolation)\n\n\t// Assume that if the browser doesn't support color spaces in gradients, then\n\t// it doesn't correctly interpolate non-sRGB colors even when a color space\n\t// is not specified. This is the case for Firefox 120, for example, which has\n\t// support for the \"color()\" syntax but not for color spaces in gradients.\n\t// There is no entry in our feature support matrix for this edge case so we\n\t// make this assumption instead.\n\t//\n\t// Note that this edge case means we have to _replace_ the original gradient\n\t// with the expanded one instead of inserting a fallback before it. Otherwise\n\t// Firefox 120 would use the original gradient instead of the fallback because\n\t// it supports the syntax, but just renders it incorrectly.\n\tif lowerInterpolation {\n\t\tlowerColorSpaces = true\n\t}\n\n\t// Potentially expand the gradient to handle unsupported features\n\tdidExpand := false\n\tif lowerMidpoints || lowerColorSpaces || lowerInterpolation {\n\t\tif colorStops, ok := tryToParseColorStops(gradient); ok {\n\t\t\thasColorSpace := false\n\t\t\thasMidpoint := false\n\t\t\tfor _, stop := range colorStops {\n\t\t\t\tif stop.hasColorSpace {\n\t\t\t\t\thasColorSpace = true\n\t\t\t\t}\n\t\t\t\tif stop.midpoint != nil {\n\t\t\t\t\thasMidpoint = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tremaining, colorSpace, hueMethod, hasInterpolation := removeColorInterpolation(gradient.leadingTokens)\n\t\t\tif (hasInterpolation && lowerInterpolation) || (hasColorSpace && lowerColorSpaces) || (hasMidpoint && lowerMidpoints) {\n\t\t\t\tif hasInterpolation {\n\t\t\t\t\ttryToExpandGradient(token.Loc, &gradient, colorStops, remaining, colorSpace, hueMethod)\n\t\t\t\t} else {\n\t\t\t\t\tif hasColorSpace {\n\t\t\t\t\t\tcolorSpace = colorSpace_oklab\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcolorSpace = colorSpace_srgb\n\t\t\t\t\t}\n\t\t\t\t\ttryToExpandGradient(token.Loc, &gradient, colorStops, gradient.leadingTokens, colorSpace, shorterHue)\n\t\t\t\t}\n\t\t\t\tdidExpand = true\n\t\t\t}\n\t\t}\n\t}\n\n\t// Lower all colors in the gradient stop\n\tfor i, stop := range gradient.colorStops {\n\t\tgradient.colorStops[i].color = p.lowerAndMinifyColor(stop.color, wouldClipColor)\n\t}\n\n\tif p.options.unsupportedCSSFeatures.Has(compat.GradientDoublePosition) {\n\t\t// Replace double positions with duplicated single positions\n\t\tfor _, stop := range gradient.colorStops {\n\t\t\tif len(stop.positions) > 1 {\n\t\t\t\tgradient.colorStops = switchToSinglePositions(gradient.colorStops)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t} else if p.options.minifySyntax {\n\t\t// Replace duplicated single positions with double positions\n\t\tfor i, stop := range gradient.colorStops {\n\t\t\tif i > 0 && len(stop.positions) == 1 {\n\t\t\t\tif prev := gradient.colorStops[i-1]; len(prev.positions) == 1 && prev.midpoint.Kind == css_lexer.T(0) &&\n\t\t\t\t\tcss_ast.TokensEqual([]css_ast.Token{prev.color}, []css_ast.Token{stop.color}, nil) {\n\t\t\t\t\tgradient.colorStops = switchToDoublePositions(gradient.colorStops)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif p.options.minifySyntax || didExpand {\n\t\tgradient.colorStops = removeImpliedPositions(gradient.kind, gradient.colorStops)\n\t}\n\n\treturn p.generateGradient(token, gradient)\n}\n\nfunc removeImpliedPositions(kind gradientKind, colorStops []colorStop) []colorStop {\n\tif len(colorStops) == 0 {\n\t\treturn colorStops\n\t}\n\n\tpositions := make([]valueWithUnit, len(colorStops))\n\tfor i, stop := range colorStops {\n\t\tif len(stop.positions) == 1 {\n\t\t\tif pos, ok := tryToParseValue(stop.positions[0], kind); ok {\n\t\t\t\tpositions[i] = pos\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tpositions[i].value = helpers.NewF64(math.NaN())\n\t}\n\n\tstart := 0\n\tfor start < len(colorStops) {\n\t\tif startPos := positions[start]; !startPos.value.IsNaN() {\n\t\t\tend := start + 1\n\t\trun:\n\t\t\tfor colorStops[end-1].midpoint.Kind == css_lexer.T(0) && end < len(colorStops) {\n\t\t\t\tendPos := positions[end]\n\t\t\t\tif endPos.value.IsNaN() || endPos.unit != startPos.unit {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// Check that all values in this run are implied. Interpolation is done\n\t\t\t\t// using the start and end positions instead of the first and second\n\t\t\t\t// positions because it's more accurate.\n\t\t\t\tfor i := start + 1; i < end; i++ {\n\t\t\t\t\tt := helpers.NewF64(float64(i - start)).DivConst(float64(end - start))\n\t\t\t\t\timpliedValue := helpers.Lerp(startPos.value, endPos.value, t)\n\t\t\t\t\tif positions[i].value.Sub(impliedValue).Abs().Value() > 0.01 {\n\t\t\t\t\t\tbreak run\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tend++\n\t\t\t}\n\n\t\t\t// Clear out all implied values\n\t\t\tif end-start > 1 {\n\t\t\t\tfor i := start + 1; i+1 < end; i++ {\n\t\t\t\t\tcolorStops[i].positions = nil\n\t\t\t\t}\n\t\t\t\tstart = end - 1\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tstart++\n\t}\n\n\tif first := colorStops[0].positions; len(first) == 1 &&\n\t\t((first[0].Kind == css_lexer.TPercentage && first[0].PercentageValue() == \"0\") ||\n\t\t\t(first[0].Kind == css_lexer.TDimension && first[0].DimensionValue() == \"0\")) {\n\t\tcolorStops[0].positions = nil\n\t}\n\n\tif last := colorStops[len(colorStops)-1].positions; len(last) == 1 &&\n\t\tlast[0].Kind == css_lexer.TPercentage && last[0].PercentageValue() == \"100\" {\n\t\tcolorStops[len(colorStops)-1].positions = nil\n\t}\n\n\treturn colorStops\n}\n\nfunc switchToSinglePositions(double []colorStop) (single []colorStop) {\n\tfor _, stop := range double {\n\t\tfor i := range stop.positions {\n\t\t\tstop.positions[i].Whitespace = css_ast.WhitespaceBefore\n\t\t}\n\t\tfor len(stop.positions) > 1 {\n\t\t\tclone := stop\n\t\t\tclone.positions = stop.positions[:1]\n\t\t\tclone.midpoint = css_ast.Token{}\n\t\t\tsingle = append(single, clone)\n\t\t\tstop.positions = stop.positions[1:]\n\t\t}\n\t\tsingle = append(single, stop)\n\t}\n\treturn\n}\n\nfunc switchToDoublePositions(single []colorStop) (double []colorStop) {\n\tfor i := 0; i < len(single); i++ {\n\t\tstop := single[i]\n\t\tif i+1 < len(single) && len(stop.positions) == 1 && stop.midpoint.Kind == css_lexer.T(0) {\n\t\t\tif next := single[i+1]; len(next.positions) == 1 &&\n\t\t\t\tcss_ast.TokensEqual([]css_ast.Token{stop.color}, []css_ast.Token{next.color}, nil) {\n\t\t\t\tdouble = append(double, colorStop{\n\t\t\t\t\tcolor:     stop.color,\n\t\t\t\t\tpositions: []css_ast.Token{stop.positions[0], next.positions[0]},\n\t\t\t\t\tmidpoint:  next.midpoint,\n\t\t\t\t})\n\t\t\t\ti++\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tdouble = append(double, stop)\n\t}\n\treturn\n}\n\nfunc removeColorInterpolation(tokens []css_ast.Token) ([]css_ast.Token, colorSpace, hueMethod, bool) {\n\tfor i := 0; i+1 < len(tokens); i++ {\n\t\tif in := tokens[i]; in.Kind == css_lexer.TIdent && strings.EqualFold(in.Text, \"in\") {\n\t\t\tif space := tokens[i+1]; space.Kind == css_lexer.TIdent {\n\t\t\t\tvar colorSpace colorSpace\n\t\t\t\thueMethod := shorterHue\n\t\t\t\tstart := i\n\t\t\t\tend := i + 2\n\n\t\t\t\t// Parse the color space\n\t\t\t\tswitch strings.ToLower(space.Text) {\n\t\t\t\tcase \"a98-rgb\":\n\t\t\t\t\tcolorSpace = colorSpace_a98_rgb\n\t\t\t\tcase \"display-p3\":\n\t\t\t\t\tcolorSpace = colorSpace_display_p3\n\t\t\t\tcase \"hsl\":\n\t\t\t\t\tcolorSpace = colorSpace_hsl\n\t\t\t\tcase \"hwb\":\n\t\t\t\t\tcolorSpace = colorSpace_hwb\n\t\t\t\tcase \"lab\":\n\t\t\t\t\tcolorSpace = colorSpace_lab\n\t\t\t\tcase \"lch\":\n\t\t\t\t\tcolorSpace = colorSpace_lch\n\t\t\t\tcase \"oklab\":\n\t\t\t\t\tcolorSpace = colorSpace_oklab\n\t\t\t\tcase \"oklch\":\n\t\t\t\t\tcolorSpace = colorSpace_oklch\n\t\t\t\tcase \"prophoto-rgb\":\n\t\t\t\t\tcolorSpace = colorSpace_prophoto_rgb\n\t\t\t\tcase \"rec2020\":\n\t\t\t\t\tcolorSpace = colorSpace_rec2020\n\t\t\t\tcase \"srgb\":\n\t\t\t\t\tcolorSpace = colorSpace_srgb\n\t\t\t\tcase \"srgb-linear\":\n\t\t\t\t\tcolorSpace = colorSpace_srgb_linear\n\t\t\t\tcase \"xyz\":\n\t\t\t\t\tcolorSpace = colorSpace_xyz\n\t\t\t\tcase \"xyz-d50\":\n\t\t\t\t\tcolorSpace = colorSpace_xyz_d50\n\t\t\t\tcase \"xyz-d65\":\n\t\t\t\t\tcolorSpace = colorSpace_xyz_d65\n\t\t\t\tdefault:\n\t\t\t\t\treturn nil, 0, 0, false\n\t\t\t\t}\n\n\t\t\t\t// Parse the optional hue mode for polar color spaces\n\t\t\t\tif colorSpace.isPolar() && i+3 < len(tokens) {\n\t\t\t\t\tif hue := tokens[i+3]; hue.Kind == css_lexer.TIdent && strings.EqualFold(hue.Text, \"hue\") {\n\t\t\t\t\t\tif method := tokens[i+2]; method.Kind == css_lexer.TIdent {\n\t\t\t\t\t\t\tswitch strings.ToLower(method.Text) {\n\t\t\t\t\t\t\tcase \"shorter\":\n\t\t\t\t\t\t\t\thueMethod = shorterHue\n\t\t\t\t\t\t\tcase \"longer\":\n\t\t\t\t\t\t\t\thueMethod = longerHue\n\t\t\t\t\t\t\tcase \"increasing\":\n\t\t\t\t\t\t\t\thueMethod = increasingHue\n\t\t\t\t\t\t\tcase \"decreasing\":\n\t\t\t\t\t\t\t\thueMethod = decreasingHue\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\treturn nil, 0, 0, false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tend = i + 4\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Remove all parsed tokens\n\t\t\t\tremaining := append(append([]css_ast.Token{}, tokens[:start]...), tokens[end:]...)\n\t\t\t\tif n := len(remaining); n > 0 {\n\t\t\t\t\tremaining[0].Whitespace &= ^css_ast.WhitespaceBefore\n\t\t\t\t\tremaining[n-1].Whitespace &= ^css_ast.WhitespaceAfter\n\t\t\t\t}\n\t\t\t\treturn remaining, colorSpace, hueMethod, true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil, 0, 0, false\n}\n\ntype valueWithUnit struct {\n\tunit  string\n\tvalue F64\n}\n\ntype parsedColorStop struct {\n\t// Position information (may be a sum of two different units)\n\tpositionTerms []valueWithUnit\n\n\t// Color midpoint (a.k.a. transition hint) information\n\tmidpoint *valueWithUnit\n\n\t// Non-premultiplied color information in XYZ space\n\tx, y, z, alpha F64\n\n\t// Non-premultiplied color information in sRGB space\n\tr, g, b F64\n\n\t// Premultiplied color information in the interpolation color space\n\tv0, v1, v2 F64\n\n\t// True if the original color has a color space\n\thasColorSpace bool\n}\n\nfunc tryToParseColorStops(gradient parsedGradient) ([]parsedColorStop, bool) {\n\tvar colorStops []parsedColorStop\n\n\tfor _, stop := range gradient.colorStops {\n\t\tcolor, ok := parseColor(stop.color)\n\t\tif !ok {\n\t\t\treturn nil, false\n\t\t}\n\t\tvar r, g, b F64\n\t\tif !color.hasColorSpace {\n\t\t\tr = helpers.NewF64(float64(hexR(color.hex))).DivConst(255)\n\t\t\tg = helpers.NewF64(float64(hexG(color.hex))).DivConst(255)\n\t\t\tb = helpers.NewF64(float64(hexB(color.hex))).DivConst(255)\n\t\t\tcolor.x, color.y, color.z = lin_srgb_to_xyz(lin_srgb(r, g, b))\n\t\t} else {\n\t\t\tr, g, b = gam_srgb(xyz_to_lin_srgb(color.x, color.y, color.z))\n\t\t}\n\t\tparsedStop := parsedColorStop{\n\t\t\tx:             color.x,\n\t\t\ty:             color.y,\n\t\t\tz:             color.z,\n\t\t\tr:             r,\n\t\t\tg:             g,\n\t\t\tb:             b,\n\t\t\talpha:         helpers.NewF64(float64(hexA(color.hex))).DivConst(255),\n\t\t\thasColorSpace: color.hasColorSpace,\n\t\t}\n\n\t\tfor i, position := range stop.positions {\n\t\t\tif position, ok := tryToParseValue(position, gradient.kind); ok {\n\t\t\t\tparsedStop.positionTerms = []valueWithUnit{position}\n\t\t\t} else {\n\t\t\t\treturn nil, false\n\t\t\t}\n\n\t\t\t// Expand double positions\n\t\t\tif i+1 < len(stop.positions) {\n\t\t\t\tcolorStops = append(colorStops, parsedStop)\n\t\t\t}\n\t\t}\n\n\t\tif stop.midpoint.Kind != css_lexer.T(0) {\n\t\t\tif midpoint, ok := tryToParseValue(stop.midpoint, gradient.kind); ok {\n\t\t\t\tparsedStop.midpoint = &midpoint\n\t\t\t} else {\n\t\t\t\treturn nil, false\n\t\t\t}\n\t\t}\n\n\t\tcolorStops = append(colorStops, parsedStop)\n\t}\n\n\t// Automatically fill in missing positions\n\tif len(colorStops) > 0 {\n\t\ttype stopInfo struct {\n\t\t\tfromPos   valueWithUnit\n\t\t\ttoPos     valueWithUnit\n\t\t\tfromCount int32\n\t\t\ttoCount   int32\n\t\t}\n\n\t\t// Fill in missing positions for the endpoints first\n\t\tif first := &colorStops[0]; len(first.positionTerms) == 0 {\n\t\t\tfirst.positionTerms = []valueWithUnit{{value: helpers.NewF64(0), unit: \"%\"}}\n\t\t}\n\t\tif last := &colorStops[len(colorStops)-1]; len(last.positionTerms) == 0 {\n\t\t\tlast.positionTerms = []valueWithUnit{{value: helpers.NewF64(100), unit: \"%\"}}\n\t\t}\n\n\t\t// Set all positions to be greater than the position before them\n\t\tfor i, stop := range colorStops {\n\t\t\tvar prevPos valueWithUnit\n\t\t\tfor j := i - 1; j >= 0; j-- {\n\t\t\t\tprev := colorStops[j]\n\t\t\t\tif prev.midpoint != nil {\n\t\t\t\t\tprevPos = *prev.midpoint\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif len(prev.positionTerms) == 1 {\n\t\t\t\t\tprevPos = prev.positionTerms[0]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(stop.positionTerms) == 1 {\n\t\t\t\tif prevPos.unit == stop.positionTerms[0].unit {\n\t\t\t\t\tstop.positionTerms[0].value = helpers.Max2(prevPos.value, stop.positionTerms[0].value)\n\t\t\t\t}\n\t\t\t\tprevPos = stop.positionTerms[0]\n\t\t\t}\n\t\t\tif stop.midpoint != nil && prevPos.unit == stop.midpoint.unit {\n\t\t\t\tstop.midpoint.value = helpers.Max2(prevPos.value, stop.midpoint.value)\n\t\t\t}\n\t\t}\n\n\t\t// Scan over all other stops with missing positions\n\t\tinfos := make([]stopInfo, len(colorStops))\n\t\tfor i, stop := range colorStops {\n\t\t\tif len(stop.positionTerms) == 1 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tinfo := &infos[i]\n\n\t\t\t// Scan backward\n\t\t\tfor from := i - 1; from >= 0; from-- {\n\t\t\t\tfromStop := colorStops[from]\n\t\t\t\tinfo.fromCount++\n\t\t\t\tif fromStop.midpoint != nil {\n\t\t\t\t\tinfo.fromPos = *fromStop.midpoint\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif len(fromStop.positionTerms) == 1 {\n\t\t\t\t\tinfo.fromPos = fromStop.positionTerms[0]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Scan forward\n\t\t\tfor to := i; to < len(colorStops); to++ {\n\t\t\t\tinfo.toCount++\n\t\t\t\tif toStop := colorStops[to]; toStop.midpoint != nil {\n\t\t\t\t\tinfo.toPos = *toStop.midpoint\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif to+1 < len(colorStops) {\n\t\t\t\t\tif toStop := colorStops[to+1]; len(toStop.positionTerms) == 1 {\n\t\t\t\t\t\tinfo.toPos = toStop.positionTerms[0]\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Then fill in all other missing positions\n\t\tfor i, stop := range colorStops {\n\t\t\tif len(stop.positionTerms) != 1 {\n\t\t\t\tinfo := infos[i]\n\t\t\t\tt := helpers.NewF64(float64(info.fromCount)).DivConst(float64(info.fromCount + info.toCount))\n\t\t\t\tif info.fromPos.unit == info.toPos.unit {\n\t\t\t\t\tcolorStops[i].positionTerms = []valueWithUnit{{\n\t\t\t\t\t\tvalue: helpers.Lerp(info.fromPos.value, info.toPos.value, t),\n\t\t\t\t\t\tunit:  info.fromPos.unit,\n\t\t\t\t\t}}\n\t\t\t\t} else {\n\t\t\t\t\tcolorStops[i].positionTerms = []valueWithUnit{{\n\t\t\t\t\t\tvalue: t.Neg().AddConst(1).Mul(info.fromPos.value),\n\t\t\t\t\t\tunit:  info.fromPos.unit,\n\t\t\t\t\t}, {\n\t\t\t\t\t\tvalue: t.Mul(info.toPos.value),\n\t\t\t\t\t\tunit:  info.toPos.unit,\n\t\t\t\t\t}}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Midpoints are only supported if they use the same units as their neighbors\n\t\tfor i, stop := range colorStops {\n\t\t\tif stop.midpoint != nil {\n\t\t\t\tnext := colorStops[i+1]\n\t\t\t\tif len(stop.positionTerms) != 1 || stop.midpoint.unit != stop.positionTerms[0].unit ||\n\t\t\t\t\tlen(next.positionTerms) != 1 || stop.midpoint.unit != next.positionTerms[0].unit {\n\t\t\t\t\treturn nil, false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn colorStops, true\n}\n\nfunc tryToParseValue(token css_ast.Token, kind gradientKind) (result valueWithUnit, success bool) {\n\tif kind == conicGradient {\n\t\t// <angle-percentage>\n\t\tswitch token.Kind {\n\t\tcase css_lexer.TDimension:\n\t\t\tdegrees, ok := degreesForAngle(token)\n\t\t\tif !ok {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tresult.value = helpers.NewF64(degrees).MulConst(100.0 / 360)\n\t\t\tresult.unit = \"%\"\n\n\t\tcase css_lexer.TPercentage:\n\t\t\tpercent, err := strconv.ParseFloat(token.PercentageValue(), 64)\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tresult.value = helpers.NewF64(percent)\n\t\t\tresult.unit = \"%\"\n\n\t\tdefault:\n\t\t\treturn\n\t\t}\n\t} else {\n\t\t// <length-percentage>\n\t\tswitch token.Kind {\n\t\tcase css_lexer.TNumber:\n\t\t\tzero, err := strconv.ParseFloat(token.Text, 64)\n\t\t\tif err != nil || zero != 0 {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tresult.value = helpers.NewF64(0)\n\t\t\tresult.unit = \"%\"\n\n\t\tcase css_lexer.TDimension:\n\t\t\tdimensionValue, err := strconv.ParseFloat(token.DimensionValue(), 64)\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tresult.value = helpers.NewF64(dimensionValue)\n\t\t\tresult.unit = token.DimensionUnit()\n\n\t\tcase css_lexer.TPercentage:\n\t\t\tpercentageValue, err := strconv.ParseFloat(token.PercentageValue(), 64)\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tresult.value = helpers.NewF64(percentageValue)\n\t\t\tresult.unit = \"%\"\n\n\t\tdefault:\n\t\t\treturn\n\t\t}\n\t}\n\n\tsuccess = true\n\treturn\n}\n\nfunc tryToExpandGradient(\n\tloc logger.Loc,\n\tgradient *parsedGradient,\n\tcolorStops []parsedColorStop,\n\tremaining []css_ast.Token,\n\tcolorSpace colorSpace,\n\thueMethod hueMethod,\n) bool {\n\t// Convert color stops into the interpolation color space\n\tfor i := range colorStops {\n\t\tstop := &colorStops[i]\n\t\tv0, v1, v2 := xyz_to_colorSpace(stop.x, stop.y, stop.z, colorSpace)\n\t\tstop.v0, stop.v1, stop.v2 = premultiply(v0, v1, v2, stop.alpha, colorSpace)\n\t}\n\n\tvar newColorStops []colorStop\n\tvar generateColorStops func(\n\t\tint, parsedColorStop, parsedColorStop,\n\t\tF64, F64, F64, F64, F64, F64, F64, F64,\n\t\tF64, F64, F64, F64, F64, F64, F64, F64,\n\t)\n\n\tgenerateColorStops = func(\n\t\tdepth int,\n\t\tfrom parsedColorStop, to parsedColorStop,\n\t\tprevX, prevY, prevZ, prevR, prevG, prevB, prevA, prevT F64,\n\t\tnextX, nextY, nextZ, nextR, nextG, nextB, nextA, nextT F64,\n\t) {\n\t\tif depth > 4 {\n\t\t\treturn\n\t\t}\n\n\t\tt := prevT.Add(nextT).DivConst(2)\n\t\tpositionT := t\n\n\t\t// Handle midpoints (which we have already checked uses the same units)\n\t\tif from.midpoint != nil {\n\t\t\tfromPos := from.positionTerms[0].value\n\t\t\ttoPos := to.positionTerms[0].value\n\t\t\tstopPos := helpers.Lerp(fromPos, toPos, t)\n\t\t\tH := from.midpoint.value.Sub(fromPos).Div(toPos.Sub(fromPos))\n\t\t\tP := stopPos.Sub(fromPos).Div(toPos.Sub(fromPos))\n\t\t\tif H.Value() <= 0 {\n\t\t\t\tpositionT = helpers.NewF64(1)\n\t\t\t} else if H.Value() >= 1 {\n\t\t\t\tpositionT = helpers.NewF64(0)\n\t\t\t} else {\n\t\t\t\tpositionT = P.Pow(helpers.NewF64(-1).Div(H.Log2()))\n\t\t\t}\n\t\t}\n\n\t\tv0, v1, v2 := interpolateColors(from.v0, from.v1, from.v2, to.v0, to.v1, to.v2, colorSpace, hueMethod, positionT)\n\t\ta := helpers.Lerp(from.alpha, to.alpha, positionT)\n\t\tv0, v1, v2 = unpremultiply(v0, v1, v2, a, colorSpace)\n\t\tx, y, z := colorSpace_to_xyz(v0, v1, v2, colorSpace)\n\n\t\t// Stop when the color is similar enough to the sRGB midpoint\n\t\tconst epsilon = 4.0 / 255\n\t\tr, g, b := gam_srgb(xyz_to_lin_srgb(x, y, z))\n\t\tdr := r.Mul(a).Sub(prevR.Mul(prevA).Add(nextR.Mul(nextA)).DivConst(2))\n\t\tdg := g.Mul(a).Sub(prevG.Mul(prevA).Add(nextG.Mul(nextA)).DivConst(2))\n\t\tdb := b.Mul(a).Sub(prevB.Mul(prevA).Add(nextB.Mul(nextA)).DivConst(2))\n\t\tif d := dr.Squared().Add(dg.Squared()).Add(db.Squared()); d.Value() < epsilon*epsilon {\n\t\t\treturn\n\t\t}\n\n\t\t// Recursive split before this stop\n\t\tgenerateColorStops(depth+1, from, to,\n\t\t\tprevX, prevY, prevZ, prevR, prevG, prevB, prevA, prevT,\n\t\t\tx, y, z, r, g, b, a, t)\n\n\t\t// Generate this stop\n\t\tcolor := makeColorToken(loc, x, y, z, a)\n\t\tpositionTerms := interpolatePositions(from.positionTerms, to.positionTerms, t)\n\t\tposition := makePositionToken(loc, positionTerms)\n\t\tposition.Whitespace = css_ast.WhitespaceBefore\n\t\tnewColorStops = append(newColorStops, colorStop{\n\t\t\tcolor:     color,\n\t\t\tpositions: []css_ast.Token{position},\n\t\t})\n\n\t\t// Recursive split after this stop\n\t\tgenerateColorStops(depth+1, from, to,\n\t\t\tx, y, z, r, g, b, a, t,\n\t\t\tnextX, nextY, nextZ, nextR, nextG, nextB, nextA, nextT)\n\t}\n\n\tfor i, stop := range colorStops {\n\t\tcolor := makeColorToken(loc, stop.x, stop.y, stop.z, stop.alpha)\n\t\tposition := makePositionToken(loc, stop.positionTerms)\n\t\tposition.Whitespace = css_ast.WhitespaceBefore\n\t\tnewColorStops = append(newColorStops, colorStop{\n\t\t\tcolor:     color,\n\t\t\tpositions: []css_ast.Token{position},\n\t\t})\n\n\t\t// Generate new color stops in between as needed\n\t\tif i+1 < len(colorStops) {\n\t\t\tnext := colorStops[i+1]\n\t\t\tgenerateColorStops(0, stop, next,\n\t\t\t\tstop.x, stop.y, stop.z, stop.r, stop.g, stop.b, stop.alpha, helpers.NewF64(0),\n\t\t\t\tnext.x, next.y, next.z, next.r, next.g, next.b, next.alpha, helpers.NewF64(1))\n\t\t}\n\t}\n\n\tgradient.leadingTokens = remaining\n\tgradient.colorStops = newColorStops\n\treturn true\n}\n\nfunc formatFloat(value F64, decimals int) string {\n\treturn strings.TrimSuffix(strings.TrimRight(strconv.FormatFloat(value.Value(), 'f', decimals, 64), \"0\"), \".\")\n}\n\nfunc makeDimensionOrPercentToken(loc logger.Loc, value F64, unit string) (token css_ast.Token) {\n\ttoken.Loc = loc\n\ttoken.Text = formatFloat(value, 2)\n\tif unit == \"%\" {\n\t\ttoken.Kind = css_lexer.TPercentage\n\t} else {\n\t\ttoken.Kind = css_lexer.TDimension\n\t\ttoken.UnitOffset = uint16(len(token.Text))\n\t}\n\ttoken.Text += unit\n\treturn\n}\n\nfunc makePositionToken(loc logger.Loc, positionTerms []valueWithUnit) css_ast.Token {\n\tif len(positionTerms) == 1 {\n\t\treturn makeDimensionOrPercentToken(loc, positionTerms[0].value, positionTerms[0].unit)\n\t}\n\n\tchildren := make([]css_ast.Token, 0, 1+2*len(positionTerms))\n\tfor i, term := range positionTerms {\n\t\tif i > 0 {\n\t\t\tchildren = append(children, css_ast.Token{\n\t\t\t\tLoc:        loc,\n\t\t\t\tKind:       css_lexer.TDelimPlus,\n\t\t\t\tText:       \"+\",\n\t\t\t\tWhitespace: css_ast.WhitespaceBefore | css_ast.WhitespaceAfter,\n\t\t\t})\n\t\t}\n\t\tchildren = append(children, makeDimensionOrPercentToken(loc, term.value, term.unit))\n\t}\n\n\treturn css_ast.Token{\n\t\tLoc:      loc,\n\t\tKind:     css_lexer.TFunction,\n\t\tText:     \"calc\",\n\t\tChildren: &children,\n\t}\n}\n\nfunc makeColorToken(loc logger.Loc, x F64, y F64, z F64, a F64) (color css_ast.Token) {\n\tcolor.Loc = loc\n\talpha := uint32(a.MulConst(255).Round().Value())\n\tif hex, ok := tryToConvertToHexWithoutClipping(x, y, z, alpha); ok {\n\t\tcolor.Kind = css_lexer.THash\n\t\tif alpha == 255 {\n\t\t\tcolor.Text = fmt.Sprintf(\"%06x\", hex>>8)\n\t\t} else {\n\t\t\tcolor.Text = fmt.Sprintf(\"%08x\", hex)\n\t\t}\n\t} else {\n\t\tchildren := []css_ast.Token{\n\t\t\t{\n\t\t\t\tLoc:        loc,\n\t\t\t\tKind:       css_lexer.TIdent,\n\t\t\t\tText:       \"xyz\",\n\t\t\t\tWhitespace: css_ast.WhitespaceAfter,\n\t\t\t},\n\t\t\t{\n\t\t\t\tLoc:        loc,\n\t\t\t\tKind:       css_lexer.TNumber,\n\t\t\t\tText:       formatFloat(x, 3),\n\t\t\t\tWhitespace: css_ast.WhitespaceBefore | css_ast.WhitespaceAfter,\n\t\t\t},\n\t\t\t{\n\t\t\t\tLoc:        loc,\n\t\t\t\tKind:       css_lexer.TNumber,\n\t\t\t\tText:       formatFloat(y, 3),\n\t\t\t\tWhitespace: css_ast.WhitespaceBefore | css_ast.WhitespaceAfter,\n\t\t\t},\n\t\t\t{\n\t\t\t\tLoc:        loc,\n\t\t\t\tKind:       css_lexer.TNumber,\n\t\t\t\tText:       formatFloat(z, 3),\n\t\t\t\tWhitespace: css_ast.WhitespaceBefore,\n\t\t\t},\n\t\t}\n\t\tif a.Value() < 1 {\n\t\t\tchildren = append(children,\n\t\t\t\tcss_ast.Token{\n\t\t\t\t\tLoc:        loc,\n\t\t\t\t\tKind:       css_lexer.TDelimSlash,\n\t\t\t\t\tText:       \"/\",\n\t\t\t\t\tWhitespace: css_ast.WhitespaceBefore | css_ast.WhitespaceAfter,\n\t\t\t\t},\n\t\t\t\tcss_ast.Token{\n\t\t\t\t\tLoc:        loc,\n\t\t\t\t\tKind:       css_lexer.TNumber,\n\t\t\t\t\tText:       formatFloat(a, 3),\n\t\t\t\t\tWhitespace: css_ast.WhitespaceBefore,\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t\tcolor.Kind = css_lexer.TFunction\n\t\tcolor.Text = \"color\"\n\t\tcolor.Children = &children\n\t}\n\treturn\n}\n\nfunc interpolateHues(a, b, t F64, hueMethod hueMethod) F64 {\n\ta = a.DivConst(360)\n\tb = b.DivConst(360)\n\ta = a.Sub(a.Floor())\n\tb = b.Sub(b.Floor())\n\n\tswitch hueMethod {\n\tcase shorterHue:\n\t\tdelta := b.Sub(a)\n\t\tif delta.Value() > 0.5 {\n\t\t\ta = a.AddConst(1)\n\t\t}\n\t\tif delta.Value() < -0.5 {\n\t\t\tb = b.AddConst(1)\n\t\t}\n\n\tcase longerHue:\n\t\tdelta := b.Sub(a)\n\t\tif delta.Value() > 0 && delta.Value() < 0.5 {\n\t\t\ta = a.AddConst(1)\n\t\t}\n\t\tif delta.Value() > -0.5 && delta.Value() <= 0 {\n\t\t\tb = b.AddConst(1)\n\t\t}\n\n\tcase increasingHue:\n\t\tif b.Value() < a.Value() {\n\t\t\tb = b.AddConst(1)\n\t\t}\n\n\tcase decreasingHue:\n\t\tif a.Value() < b.Value() {\n\t\t\ta = a.AddConst(1)\n\t\t}\n\t}\n\n\treturn helpers.Lerp(a, b, t).MulConst(360)\n}\n\nfunc interpolateColors(\n\ta0, a1, a2 F64, b0, b1, b2 F64,\n\tcolorSpace colorSpace, hueMethod hueMethod, t F64,\n) (v0 F64, v1 F64, v2 F64) {\n\tv1 = helpers.Lerp(a1, b1, t)\n\n\tswitch colorSpace {\n\tcase colorSpace_hsl, colorSpace_hwb:\n\t\tv2 = helpers.Lerp(a2, b2, t)\n\t\tv0 = interpolateHues(a0, b0, t, hueMethod)\n\n\tcase colorSpace_lch, colorSpace_oklch:\n\t\tv0 = helpers.Lerp(a0, b0, t)\n\t\tv2 = interpolateHues(a2, b2, t, hueMethod)\n\n\tdefault:\n\t\tv0 = helpers.Lerp(a0, b0, t)\n\t\tv2 = helpers.Lerp(a2, b2, t)\n\t}\n\n\treturn v0, v1, v2\n}\n\nfunc interpolatePositions(a []valueWithUnit, b []valueWithUnit, t F64) (result []valueWithUnit) {\n\tfindUnit := func(unit string) int {\n\t\tfor i, x := range result {\n\t\t\tif x.unit == unit {\n\t\t\t\treturn i\n\t\t\t}\n\t\t}\n\t\tresult = append(result, valueWithUnit{unit: unit})\n\t\treturn len(result) - 1\n\t}\n\n\t// \"result += a * (1 - t)\"\n\tfor _, term := range a {\n\t\tptr := &result[findUnit(term.unit)]\n\t\tptr.value = t.Neg().AddConst(1).Mul(term.value).Add(ptr.value)\n\t}\n\n\t// \"result += b * t\"\n\tfor _, term := range b {\n\t\tptr := &result[findUnit(term.unit)]\n\t\tptr.value = t.Mul(term.value).Add(ptr.value)\n\t}\n\n\t// Remove an extra zero value for neatness. We don't remove all\n\t// of them because it may be important to retain a single zero.\n\tif len(result) > 1 {\n\t\tfor i, term := range result {\n\t\t\tif term.value.Value() == 0 {\n\t\t\t\tcopy(result[i:], result[i+1:])\n\t\t\t\tresult = result[:len(result)-1]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc premultiply(v0, v1, v2, alpha F64, colorSpace colorSpace) (F64, F64, F64) {\n\tif alpha.Value() < 1 {\n\t\tswitch colorSpace {\n\t\tcase colorSpace_hsl, colorSpace_hwb:\n\t\t\tv2 = v2.Mul(alpha)\n\t\tcase colorSpace_lch, colorSpace_oklch:\n\t\t\tv0 = v0.Mul(alpha)\n\t\tdefault:\n\t\t\tv0 = v0.Mul(alpha)\n\t\t\tv2 = v2.Mul(alpha)\n\t\t}\n\t\tv1 = v1.Mul(alpha)\n\t}\n\treturn v0, v1, v2\n}\n\nfunc unpremultiply(v0, v1, v2, alpha F64, colorSpace colorSpace) (F64, F64, F64) {\n\tif alpha.Value() > 0 && alpha.Value() < 1 {\n\t\tswitch colorSpace {\n\t\tcase colorSpace_hsl, colorSpace_hwb:\n\t\t\tv2 = v2.Div(alpha)\n\t\tcase colorSpace_lch, colorSpace_oklch:\n\t\t\tv0 = v0.Div(alpha)\n\t\tdefault:\n\t\t\tv0 = v0.Div(alpha)\n\t\t\tv2 = v2.Div(alpha)\n\t\t}\n\t\tv1 = v1.Div(alpha)\n\t}\n\treturn v0, v1, v2\n}\n"
  },
  {
    "path": "internal/css_parser/css_decls_list_style.go",
    "content": "package css_parser\n\nimport (\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n)\n\n// list-style-image: <image> | none\n// <image>: <url> | <gradient>\n// <url>: <url()> | <src()>\n// <gradient>: <linear-gradient()> | <repeating-linear-gradient()> | <radial-gradient()> | <repeating-radial-gradient()>\n//\n// list-style-type: <counter-style> | <string> | none (where the string is a literal bullet marker)\n// <counter-style>: <counter-style-name> | <symbols()>\n// <counter-style-name>: not: decimal | disc | square | circle | disclosure-open | disclosure-closed | <wide keyword>\n// when parsing a <custom-ident> with conflicts, only parse one if no other thing can claim it\n\nfunc (p *parser) processListStyleShorthand(tokens []css_ast.Token) {\n\tif len(tokens) < 1 || len(tokens) > 3 {\n\t\treturn\n\t}\n\n\tfoundImage := false\n\tfoundPosition := false\n\ttypeIndex := -1\n\tnoneCount := 0\n\n\tfor i, t := range tokens {\n\t\tswitch t.Kind {\n\t\tcase css_lexer.TString:\n\t\t\t// \"list-style-type\" is definitely not a <custom-ident>\n\t\t\treturn\n\n\t\tcase css_lexer.TURL:\n\t\t\tif !foundImage {\n\t\t\t\tfoundImage = true\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tcase css_lexer.TFunction:\n\t\t\tif !foundImage {\n\t\t\t\tswitch strings.ToLower(t.Text) {\n\t\t\t\tcase \"src\", \"linear-gradient\", \"repeating-linear-gradient\", \"radial-gradient\", \"radial-linear-gradient\":\n\t\t\t\t\tfoundImage = true\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase css_lexer.TIdent:\n\t\t\tlower := strings.ToLower(t.Text)\n\n\t\t\t// Note: If \"none\" is present, it's ambiguous whether it applies to\n\t\t\t// \"list-style-image\" or \"list-style-type\". To resolve ambiguity it's\n\t\t\t// applied at the end to whichever property isn't otherwise set.\n\t\t\tif lower == \"none\" {\n\t\t\t\tnoneCount++\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif !foundPosition && (lower == \"inside\" || lower == \"outside\") {\n\t\t\t\tfoundPosition = true\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif typeIndex == -1 {\n\t\t\t\tif cssWideAndReservedKeywords[lower] || predefinedCounterStyles[lower] {\n\t\t\t\t\t// \"list-style-type\" is definitely not a <custom-ident>\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\ttypeIndex = i\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Bail if we hit an unexpected token\n\t\treturn\n\t}\n\n\tif typeIndex != -1 {\n\t\t// The first \"none\" applies to \"list-style-image\" if it's missing\n\t\tif !foundImage && noneCount > 0 {\n\t\t\tnoneCount--\n\t\t}\n\n\t\tif noneCount > 0 {\n\t\t\t// \"list-style-type\" is \"none\", not a <custom-ident>\n\t\t\treturn\n\t\t}\n\n\t\tif t := &tokens[typeIndex]; t.Kind == css_lexer.TIdent {\n\t\t\tt.Kind = css_lexer.TSymbol\n\t\t\tt.PayloadIndex = p.symbolForName(t.Loc, t.Text).Ref.InnerIndex\n\t\t}\n\t}\n}\n\nfunc (p *parser) processListStyleType(t *css_ast.Token) {\n\tif t.Kind == css_lexer.TIdent {\n\t\tif lower := strings.ToLower(t.Text); lower != \"none\" && !cssWideAndReservedKeywords[lower] && !predefinedCounterStyles[lower] {\n\t\t\tt.Kind = css_lexer.TSymbol\n\t\t\tt.PayloadIndex = p.symbolForName(t.Loc, t.Text).Ref.InnerIndex\n\t\t}\n\t}\n}\n\n// https://drafts.csswg.org/css-counter-styles-3/#predefined-counters\nvar predefinedCounterStyles = map[string]bool{\n\t// 6.1. Numeric:\n\t\"arabic-indic\":         true,\n\t\"armenian\":             true,\n\t\"bengali\":              true,\n\t\"cambodian\":            true,\n\t\"cjk-decimal\":          true,\n\t\"decimal-leading-zero\": true,\n\t\"decimal\":              true,\n\t\"devanagari\":           true,\n\t\"georgian\":             true,\n\t\"gujarati\":             true,\n\t\"gurmukhi\":             true,\n\t\"hebrew\":               true,\n\t\"kannada\":              true,\n\t\"khmer\":                true,\n\t\"lao\":                  true,\n\t\"lower-armenian\":       true,\n\t\"lower-roman\":          true,\n\t\"malayalam\":            true,\n\t\"mongolian\":            true,\n\t\"myanmar\":              true,\n\t\"oriya\":                true,\n\t\"persian\":              true,\n\t\"tamil\":                true,\n\t\"telugu\":               true,\n\t\"thai\":                 true,\n\t\"tibetan\":              true,\n\t\"upper-armenian\":       true,\n\t\"upper-roman\":          true,\n\n\t// 6.2. Alphabetic:\n\t\"hiragana-iroha\": true,\n\t\"hiragana\":       true,\n\t\"katakana-iroha\": true,\n\t\"katakana\":       true,\n\t\"lower-alpha\":    true,\n\t\"lower-greek\":    true,\n\t\"lower-latin\":    true,\n\t\"upper-alpha\":    true,\n\t\"upper-latin\":    true,\n\n\t// 6.3. Symbolic:\n\t\"circle\":            true,\n\t\"disc\":              true,\n\t\"disclosure-closed\": true,\n\t\"disclosure-open\":   true,\n\t\"square\":            true,\n\n\t// 6.4. Fixed:\n\t\"cjk-earthly-branch\": true,\n\t\"cjk-heavenly-stem\":  true,\n\n\t// 7.1.1. Japanese:\n\t\"japanese-formal\":   true,\n\t\"japanese-informal\": true,\n\n\t// 7.1.2. Korean:\n\t\"korean-hangul-formal\":  true,\n\t\"korean-hanja-formal\":   true,\n\t\"korean-hanja-informal\": true,\n\n\t// 7.1.3. Chinese:\n\t\"simp-chinese-formal\":   true,\n\t\"simp-chinese-informal\": true,\n\t\"trad-chinese-formal\":   true,\n\t\"trad-chinese-informal\": true,\n\n\t// 7.2. Ethiopic Numeric Counter Style:\n\t\"ethiopic-numeric\": true,\n}\n"
  },
  {
    "path": "internal/css_parser/css_decls_transform.go",
    "content": "package css_parser\n\nimport (\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n)\n\nfunc turnPercentIntoNumberIfShorter(t *css_ast.Token) {\n\tif t.Kind == css_lexer.TPercentage {\n\t\tif shifted, ok := shiftDot(t.PercentageValue(), -2); ok && len(shifted) < len(t.Text) {\n\t\t\tt.Kind = css_lexer.TNumber\n\t\t\tt.Text = shifted\n\t\t}\n\t}\n}\n\n// https://www.w3.org/TR/css-transforms-1/#two-d-transform-functions\n// https://drafts.csswg.org/css-transforms-2/#transform-functions\nfunc (p *parser) mangleTransforms(tokens []css_ast.Token) []css_ast.Token {\n\tfor i := range tokens {\n\t\tif token := &tokens[i]; token.Kind == css_lexer.TFunction {\n\t\t\tif args := *token.Children; css_ast.TokensAreCommaSeparated(args) {\n\t\t\t\tn := len(args)\n\n\t\t\t\tswitch strings.ToLower(token.Text) {\n\t\t\t\t////////////////////////////////////////////////////////////////////////////////\n\t\t\t\t// 2D transforms\n\n\t\t\t\tcase \"matrix\":\n\t\t\t\t\t// specifies a 2D transformation in the form of a transformation\n\t\t\t\t\t// matrix of the six values a, b, c, d, e, f.\n\t\t\t\t\tif n == 11 {\n\t\t\t\t\t\t// | a c 0 e |\n\t\t\t\t\t\t// | b d 0 f |\n\t\t\t\t\t\t// | 0 0 1 0 |\n\t\t\t\t\t\t// | 0 0 0 1 |\n\t\t\t\t\t\ta, b, c, d, e, f := args[0], args[2], args[4], args[6], args[8], args[10]\n\t\t\t\t\t\tif b.IsZero() && c.IsZero() && e.IsZero() && f.IsZero() {\n\t\t\t\t\t\t\t// | a 0 0 0 |\n\t\t\t\t\t\t\t// | 0 d 0 0 |\n\t\t\t\t\t\t\t// | 0 0 1 0 |\n\t\t\t\t\t\t\t// | 0 0 0 1 |\n\t\t\t\t\t\t\tif a.EqualIgnoringWhitespace(d) {\n\t\t\t\t\t\t\t\t// \"matrix(a, 0, 0, a, 0, 0)\" => \"scale(a)\"\n\t\t\t\t\t\t\t\ttoken.Text = \"scale\"\n\t\t\t\t\t\t\t\t*token.Children = args[:1]\n\t\t\t\t\t\t\t} else if d.IsOne() {\n\t\t\t\t\t\t\t\t// \"matrix(a, 0, 0, 1, 0, 0)\" => \"scaleX(a)\"\n\t\t\t\t\t\t\t\ttoken.Text = \"scaleX\"\n\t\t\t\t\t\t\t\t*token.Children = args[:1]\n\t\t\t\t\t\t\t} else if a.IsOne() {\n\t\t\t\t\t\t\t\t// \"matrix(1, 0, 0, d, 0, 0)\" => \"scaleY(d)\"\n\t\t\t\t\t\t\t\ttoken.Text = \"scaleY\"\n\t\t\t\t\t\t\t\t*token.Children = args[6:7]\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// \"matrix(a, 0, 0, d, 0, 0)\" => \"scale(a, d)\"\n\t\t\t\t\t\t\t\ttoken.Text = \"scale\"\n\t\t\t\t\t\t\t\t*token.Children = append(args[:2], d)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Note: A \"matrix\" cannot be directly converted into a \"translate\"\n\t\t\t\t\t\t\t// because \"translate\" requires units while \"matrix\" requires no\n\t\t\t\t\t\t\t// units. I'm not sure exactly what the semantics are so I'm not\n\t\t\t\t\t\t\t// sure if you can just add \"px\" or not. Even if that did work,\n\t\t\t\t\t\t\t// you still couldn't substitute values containing \"var()\" since\n\t\t\t\t\t\t\t// units would still not be substituted in that case.\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"translate\":\n\t\t\t\t\t// specifies a 2D translation by the vector [tx, ty], where tx is the\n\t\t\t\t\t// first translation-value parameter and ty is the optional second\n\t\t\t\t\t// translation-value parameter. If <ty> is not provided, ty has zero\n\t\t\t\t\t// as a value.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthOrPercentageIntoNumberIfZero()\n\t\t\t\t\t} else if n == 3 {\n\t\t\t\t\t\ttx, ty := &args[0], &args[2]\n\t\t\t\t\t\ttx.TurnLengthOrPercentageIntoNumberIfZero()\n\t\t\t\t\t\tty.TurnLengthOrPercentageIntoNumberIfZero()\n\t\t\t\t\t\tif ty.IsZero() {\n\t\t\t\t\t\t\t// \"translate(tx, 0)\" => \"translate(tx)\"\n\t\t\t\t\t\t\t*token.Children = args[:1]\n\t\t\t\t\t\t} else if tx.IsZero() {\n\t\t\t\t\t\t\t// \"translate(0, ty)\" => \"translateY(ty)\"\n\t\t\t\t\t\t\ttoken.Text = \"translateY\"\n\t\t\t\t\t\t\t*token.Children = args[2:]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"translatex\":\n\t\t\t\t\t// specifies a translation by the given amount in the X direction.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\t// \"translateX(tx)\" => \"translate(tx)\"\n\t\t\t\t\t\ttoken.Text = \"translate\"\n\t\t\t\t\t\targs[0].TurnLengthOrPercentageIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\tcase \"translatey\":\n\t\t\t\t\t// specifies a translation by the given amount in the Y direction.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthOrPercentageIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\tcase \"scale\":\n\t\t\t\t\t// specifies a 2D scale operation by the [sx,sy] scaling vector\n\t\t\t\t\t// described by the 2 parameters. If the second parameter is not\n\t\t\t\t\t// provided, it takes a value equal to the first. For example,\n\t\t\t\t\t// scale(1, 1) would leave an element unchanged, while scale(2, 2)\n\t\t\t\t\t// would cause it to appear twice as long in both the X and Y axes,\n\t\t\t\t\t// or four times its typical geometric size.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(&args[0])\n\t\t\t\t\t} else if n == 3 {\n\t\t\t\t\t\tsx, sy := &args[0], &args[2]\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(sx)\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(sy)\n\t\t\t\t\t\tif sx.EqualIgnoringWhitespace(*sy) {\n\t\t\t\t\t\t\t// \"scale(s, s)\" => \"scale(s)\"\n\t\t\t\t\t\t\t*token.Children = args[:1]\n\t\t\t\t\t\t} else if sy.IsOne() {\n\t\t\t\t\t\t\t// \"scale(s, 1)\" => \"scaleX(s)\"\n\t\t\t\t\t\t\ttoken.Text = \"scaleX\"\n\t\t\t\t\t\t\t*token.Children = args[:1]\n\t\t\t\t\t\t} else if sx.IsOne() {\n\t\t\t\t\t\t\t// \"scale(1, s)\" => \"scaleY(s)\"\n\t\t\t\t\t\t\ttoken.Text = \"scaleY\"\n\t\t\t\t\t\t\t*token.Children = args[2:]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"scalex\":\n\t\t\t\t\t// specifies a 2D scale operation using the [sx,1] scaling vector,\n\t\t\t\t\t// where sx is given as the parameter.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(&args[0])\n\t\t\t\t\t}\n\n\t\t\t\tcase \"scaley\":\n\t\t\t\t\t// specifies a 2D scale operation using the [1,sy] scaling vector,\n\t\t\t\t\t// where sy is given as the parameter.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(&args[0])\n\t\t\t\t\t}\n\n\t\t\t\tcase \"rotate\":\n\t\t\t\t\t// specifies a 2D rotation by the angle specified in the parameter\n\t\t\t\t\t// about the origin of the element, as defined by the\n\t\t\t\t\t// transform-origin property. For example, rotate(90deg) would\n\t\t\t\t\t// cause elements to appear rotated one-quarter of a turn in the\n\t\t\t\t\t// clockwise direction.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\t// Note: This is considered a 2D transform even though it's specified\n\t\t\t\t// in terms of a 3D transform because it doesn't trigger Safari's 3D\n\t\t\t\t// transform bugs.\n\t\t\t\tcase \"rotatez\":\n\t\t\t\t\t// same as rotate3d(0, 0, 1, <angle>), which is a 3d transform\n\t\t\t\t\t// equivalent to the 2d transform rotate(<angle>).\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\t// \"rotateZ(angle)\" => \"rotate(angle)\"\n\t\t\t\t\t\ttoken.Text = \"rotate\"\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\tcase \"skew\":\n\t\t\t\t\t// specifies a 2D skew by [ax,ay] for X and Y. If the second\n\t\t\t\t\t// parameter is not provided, it has a zero value.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t} else if n == 3 {\n\t\t\t\t\t\tax, ay := &args[0], &args[2]\n\t\t\t\t\t\tax.TurnLengthIntoNumberIfZero()\n\t\t\t\t\t\tay.TurnLengthIntoNumberIfZero()\n\t\t\t\t\t\tif ay.IsZero() {\n\t\t\t\t\t\t\t// \"skew(ax, 0)\" => \"skew(ax)\"\n\t\t\t\t\t\t\t*token.Children = args[:1]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"skewx\":\n\t\t\t\t\t// specifies a 2D skew transformation along the X axis by the given\n\t\t\t\t\t// angle.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\t// \"skewX(ax)\" => \"skew(ax)\"\n\t\t\t\t\t\ttoken.Text = \"skew\"\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\tcase \"skewy\":\n\t\t\t\t\t// specifies a 2D skew transformation along the Y axis by the given\n\t\t\t\t\t// angle.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\t\t////////////////////////////////////////////////////////////////////////////////\n\t\t\t\t\t// 3D transforms\n\n\t\t\t\t\t// Note: Safari has a bug where 3D transforms render differently than\n\t\t\t\t\t// other transforms. This means we should not minify a 3D transform\n\t\t\t\t\t// into a 2D transform or it will cause a rendering difference in\n\t\t\t\t\t// Safari.\n\n\t\t\t\tcase \"matrix3d\":\n\t\t\t\t\t// specifies a 3D transformation as a 4x4 homogeneous matrix of 16\n\t\t\t\t\t// values in column-major order.\n\t\t\t\t\tif n == 31 {\n\t\t\t\t\t\t// | m0 m4 m8  m12 |\n\t\t\t\t\t\t// | m1 m5 m9  m13 |\n\t\t\t\t\t\t// | m2 m6 m10 m14 |\n\t\t\t\t\t\t// | m3 m7 m11 m15 |\n\t\t\t\t\t\tmask := uint32(0)\n\t\t\t\t\t\tfor i := 0; i < 16; i++ {\n\t\t\t\t\t\t\tif arg := args[i*2]; arg.IsZero() {\n\t\t\t\t\t\t\t\tmask |= 1 << i\n\t\t\t\t\t\t\t} else if arg.IsOne() {\n\t\t\t\t\t\t\t\tmask |= (1 << 16) << i\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst onlyScale = 0b1000_0000_0000_0000_0111_1011_1101_1110\n\t\t\t\t\t\tif (mask & onlyScale) == onlyScale {\n\t\t\t\t\t\t\t// | m0 0  0   0 |\n\t\t\t\t\t\t\t// | 0  m5 0   0 |\n\t\t\t\t\t\t\t// | 0  0  m10 0 |\n\t\t\t\t\t\t\t// | 0  0  0   1 |\n\t\t\t\t\t\t\tsx, sy := args[0], args[10]\n\t\t\t\t\t\t\tif sx.IsOne() && sy.IsOne() {\n\t\t\t\t\t\t\t\ttoken.Text = \"scaleZ\"\n\t\t\t\t\t\t\t\t*token.Children = args[20:21]\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ttoken.Text = \"scale3d\"\n\t\t\t\t\t\t\t\t*token.Children = append(append(args[0:2], args[10:12]...), args[20])\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Note: A \"matrix3d\" cannot be directly converted into a \"translate3d\"\n\t\t\t\t\t\t// because \"translate3d\" requires units while \"matrix3d\" requires no\n\t\t\t\t\t\t// units. I'm not sure exactly what the semantics are so I'm not\n\t\t\t\t\t\t// sure if you can just add \"px\" or not. Even if that did work,\n\t\t\t\t\t\t// you still couldn't substitute values containing \"var()\" since\n\t\t\t\t\t\t// units would still not be substituted in that case.\n\t\t\t\t\t}\n\n\t\t\t\tcase \"translate3d\":\n\t\t\t\t\t// specifies a 3D translation by the vector [tx,ty,tz], with tx,\n\t\t\t\t\t// ty and tz being the first, second and third translation-value\n\t\t\t\t\t// parameters respectively.\n\t\t\t\t\tif n == 5 {\n\t\t\t\t\t\ttx, ty, tz := &args[0], &args[2], &args[4]\n\t\t\t\t\t\ttx.TurnLengthOrPercentageIntoNumberIfZero()\n\t\t\t\t\t\tty.TurnLengthOrPercentageIntoNumberIfZero()\n\t\t\t\t\t\ttz.TurnLengthIntoNumberIfZero()\n\t\t\t\t\t\tif tx.IsZero() && ty.IsZero() {\n\t\t\t\t\t\t\t// \"translate3d(0, 0, tz)\" => \"translateZ(tz)\"\n\t\t\t\t\t\t\ttoken.Text = \"translateZ\"\n\t\t\t\t\t\t\t*token.Children = args[4:]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"translatez\":\n\t\t\t\t\t// specifies a 3D translation by the vector [0,0,tz] with the given\n\t\t\t\t\t// amount in the Z direction.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\tcase \"scale3d\":\n\t\t\t\t\t// specifies a 3D scale operation by the [sx,sy,sz] scaling vector\n\t\t\t\t\t// described by the 3 parameters.\n\t\t\t\t\tif n == 5 {\n\t\t\t\t\t\tsx, sy, sz := &args[0], &args[2], &args[4]\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(sx)\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(sy)\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(sz)\n\t\t\t\t\t\tif sx.IsOne() && sy.IsOne() {\n\t\t\t\t\t\t\t// \"scale3d(1, 1, sz)\" => \"scaleZ(sz)\"\n\t\t\t\t\t\t\ttoken.Text = \"scaleZ\"\n\t\t\t\t\t\t\t*token.Children = args[4:]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"scalez\":\n\t\t\t\t\t// specifies a 3D scale operation using the [1,1,sz] scaling vector,\n\t\t\t\t\t// where sz is given as the parameter.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(&args[0])\n\t\t\t\t\t}\n\n\t\t\t\tcase \"rotate3d\":\n\t\t\t\t\t// specifies a 3D rotation by the angle specified in last parameter\n\t\t\t\t\t// about the [x,y,z] direction vector described by the first three\n\t\t\t\t\t// parameters. A direction vector that cannot be normalized, such as\n\t\t\t\t\t// [0,0,0], will cause the rotation to not be applied.\n\t\t\t\t\tif n == 7 {\n\t\t\t\t\t\tx, y, z, angle := &args[0], &args[2], &args[4], &args[6]\n\t\t\t\t\t\tangle.TurnLengthIntoNumberIfZero()\n\t\t\t\t\t\tif x.IsOne() && y.IsZero() && z.IsZero() {\n\t\t\t\t\t\t\t// \"rotate3d(1, 0, 0, angle)\" => \"rotateX(angle)\"\n\t\t\t\t\t\t\ttoken.Text = \"rotateX\"\n\t\t\t\t\t\t\t*token.Children = args[6:]\n\t\t\t\t\t\t} else if x.IsZero() && y.IsOne() && z.IsZero() {\n\t\t\t\t\t\t\t// \"rotate3d(0, 1, 0, angle)\" => \"rotateY(angle)\"\n\t\t\t\t\t\t\ttoken.Text = \"rotateY\"\n\t\t\t\t\t\t\t*token.Children = args[6:]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"rotatex\":\n\t\t\t\t\t// same as rotate3d(1, 0, 0, <angle>).\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\tcase \"rotatey\":\n\t\t\t\t\t// same as rotate3d(0, 1, 0, <angle>).\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\tcase \"perspective\":\n\t\t\t\t\t// specifies a perspective projection matrix. This matrix scales\n\t\t\t\t\t// points in X and Y based on their Z value, scaling points with\n\t\t\t\t\t// positive Z values away from the origin, and those with negative Z\n\t\t\t\t\t// values towards the origin. Points on the z=0 plane are unchanged.\n\t\t\t\t\t// The parameter represents the distance of the z=0 plane from the\n\t\t\t\t\t// viewer.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Trim whitespace at the ends\n\t\t\t\tif args := *token.Children; len(args) > 0 {\n\t\t\t\t\targs[0].Whitespace &= ^css_ast.WhitespaceBefore\n\t\t\t\t\targs[len(args)-1].Whitespace &= ^css_ast.WhitespaceAfter\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn tokens\n}\n"
  },
  {
    "path": "internal/css_parser/css_nesting.go",
    "content": "package css_parser\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\nfunc (p *parser) lowerNestingInRule(rule css_ast.Rule, results []css_ast.Rule) []css_ast.Rule {\n\tswitch r := rule.Data.(type) {\n\tcase *css_ast.RSelector:\n\t\tscope := func(loc logger.Loc) css_ast.ComplexSelector {\n\t\t\treturn css_ast.ComplexSelector{\n\t\t\t\tSelectors: []css_ast.CompoundSelector{{\n\t\t\t\t\tSubclassSelectors: []css_ast.SubclassSelector{{\n\t\t\t\t\t\tRange: logger.Range{Loc: loc},\n\t\t\t\t\t\tData:  &css_ast.SSPseudoClass{Name: \"scope\"},\n\t\t\t\t\t}},\n\t\t\t\t}},\n\t\t\t}\n\t\t}\n\n\t\tparentSelectorsWithPseudo := make([]css_ast.ComplexSelector, 0, len(r.Selectors))\n\t\tparentSelectorsNoPseudo := make([]css_ast.ComplexSelector, 0, len(r.Selectors))\n\t\tfor i, sel := range r.Selectors {\n\t\t\t// Top-level \"&\" should be replaced with \":scope\" to avoid recursion.\n\t\t\t// From https://www.w3.org/TR/css-nesting-1/#nest-selector:\n\t\t\t//\n\t\t\t//   \"When used in the selector of a nested style rule, the nesting\n\t\t\t//   selector represents the elements matched by the parent rule. When\n\t\t\t//   used in any other context, it represents the same elements as\n\t\t\t//   :scope in that context (unless otherwise defined).\"\n\t\t\t//\n\t\t\tsubstituted := make([]css_ast.CompoundSelector, 0, len(sel.Selectors))\n\t\t\tfor _, x := range sel.Selectors {\n\t\t\t\tsubstituted = p.substituteAmpersandsInCompoundSelector(x, scope, substituted, keepLeadingCombinator)\n\t\t\t}\n\t\t\tr.Selectors[i] = css_ast.ComplexSelector{Selectors: substituted}\n\n\t\t\t// Filter out pseudo elements because they are ignored by nested style\n\t\t\t// rules. This is because pseudo-elements are not valid within :is():\n\t\t\t// https://www.w3.org/TR/selectors-4/#matches-pseudo. This restriction\n\t\t\t// may be relaxed in the future, but this restriction has shipped so\n\t\t\t// we're stuck with it: https://github.com/w3c/csswg-drafts/issues/7433.\n\t\t\t//\n\t\t\t// Note: This is only for the parent selector list that is used to\n\t\t\t// substitute \"&\" within child rules. Do not filter out the pseudo\n\t\t\t// element from the top-level selector list.\n\t\t\tif !sel.UsesPseudoElement() {\n\t\t\t\tparentSelectorsNoPseudo = append(parentSelectorsNoPseudo, css_ast.ComplexSelector{Selectors: substituted})\n\t\t\t}\n\n\t\t\t// This filtering is only done conditionally because it seems to only\n\t\t\t// apply sometimes. Specifically it doesn't seem to apply when the\n\t\t\t// nested rule is an at-rule. So we use the unfiltered list in that\n\t\t\t// case. See: https://github.com/evanw/esbuild/issues/4265\n\t\t\tparentSelectorsWithPseudo = append(parentSelectorsWithPseudo, css_ast.ComplexSelector{Selectors: substituted})\n\t\t}\n\n\t\t// Emit this selector before its nested children\n\t\tstart := len(results)\n\t\tresults = append(results, rule)\n\n\t\t// Lower all children and filter out ones that become empty\n\t\tcontext := lowerNestingContext{\n\t\t\tparentSelectorsWithPseudo: parentSelectorsWithPseudo,\n\t\t\tparentSelectorsNoPseudo:   parentSelectorsNoPseudo,\n\t\t\tloweredRules:              results,\n\t\t}\n\t\tr.Rules = p.lowerNestingInRulesAndReturnRemaining(r.Rules, &context)\n\n\t\t// Omit this selector entirely if it's now empty\n\t\tif len(r.Rules) == 0 {\n\t\t\tcopy(context.loweredRules[start:], context.loweredRules[start+1:])\n\t\t\tcontext.loweredRules = context.loweredRules[:len(context.loweredRules)-1]\n\t\t}\n\t\treturn context.loweredRules\n\n\tcase *css_ast.RKnownAt:\n\t\tvar rules []css_ast.Rule\n\t\tfor _, child := range r.Rules {\n\t\t\trules = p.lowerNestingInRule(child, rules)\n\t\t}\n\t\tr.Rules = rules\n\n\tcase *css_ast.RAtLayer:\n\t\tvar rules []css_ast.Rule\n\t\tfor _, child := range r.Rules {\n\t\t\trules = p.lowerNestingInRule(child, rules)\n\t\t}\n\t\tr.Rules = rules\n\n\tcase *css_ast.RAtMedia:\n\t\tvar rules []css_ast.Rule\n\t\tfor _, child := range r.Rules {\n\t\t\trules = p.lowerNestingInRule(child, rules)\n\t\t}\n\t\tr.Rules = rules\n\t}\n\n\treturn append(results, rule)\n}\n\n// Lower all children and filter out ones that become empty\nfunc (p *parser) lowerNestingInRulesAndReturnRemaining(rules []css_ast.Rule, context *lowerNestingContext) []css_ast.Rule {\n\tn := 0\n\tfor _, child := range rules {\n\t\tchild = p.lowerNestingInRuleWithContext(child, context)\n\t\tif child.Data != nil {\n\t\t\trules[n] = child\n\t\t\tn++\n\t\t}\n\t}\n\treturn rules[:n]\n}\n\nfunc compoundSelectorTermCount(sel css_ast.CompoundSelector) int {\n\tcount := 0\n\tfor _, ss := range sel.SubclassSelectors {\n\t\tcount++\n\t\tif list, ok := ss.Data.(*css_ast.SSPseudoClassWithSelectorList); ok {\n\t\t\tcount += complexSelectorTermCount(list.Selectors)\n\t\t}\n\t}\n\treturn count\n}\n\nfunc complexSelectorTermCount(selectors []css_ast.ComplexSelector) int {\n\tcount := 0\n\tfor _, sel := range selectors {\n\t\tfor _, inner := range sel.Selectors {\n\t\t\tcount += compoundSelectorTermCount(inner)\n\t\t}\n\t}\n\treturn count\n}\n\nfunc (p *parser) addExpansionError(loc logger.Loc, n int) {\n\tp.log.AddErrorWithNotes(&p.tracker, logger.Range{Loc: loc}, \"CSS nesting is causing too much expansion\",\n\t\t[]logger.MsgData{{Text: fmt.Sprintf(\"CSS nesting expansion was terminated because a rule was generated with %d selectors. \"+\n\t\t\t\"This limit exists to prevent esbuild from using too much time and/or memory. \"+\n\t\t\t\"Please change your CSS to use fewer levels of nesting.\", n)}})\n}\n\ntype lowerNestingContext struct {\n\tparentSelectorsWithPseudo []css_ast.ComplexSelector\n\tparentSelectorsNoPseudo   []css_ast.ComplexSelector\n\tloweredRules              []css_ast.Rule\n}\n\nfunc (p *parser) lowerNestingInRuleWithContext(rule css_ast.Rule, context *lowerNestingContext) css_ast.Rule {\n\tswitch r := rule.Data.(type) {\n\tcase *css_ast.RSelector:\n\t\toldSelectorsLen := len(r.Selectors)\n\t\toldSelectorsComplexity := complexSelectorTermCount(r.Selectors)\n\n\t\t// \"a { & b {} }\" => \"a b {}\"\n\t\t// \"a { &b {} }\" => \"a:is(b) {}\"\n\t\t// \"a { &:hover {} }\" => \"a:hover {}\"\n\t\t// \".x { &b {} }\" => \"b.x {}\"\n\t\t// \"a, b { .c, d {} }\" => \":is(a, b) :is(.c, d) {}\"\n\t\t// \"a, b { &.c, & d, e & {} }\" => \":is(a, b).c, :is(a, b) d, e :is(a, b) {}\"\n\n\t\t// Pass 1: Canonicalize and analyze our selectors\n\t\tfor i := range r.Selectors {\n\t\t\tsel := &r.Selectors[i]\n\n\t\t\t// Inject the implicit \"&\" now for simplicity later on\n\t\t\tif sel.IsRelative() {\n\t\t\t\tsel.Selectors = append([]css_ast.CompoundSelector{{NestingSelectorLocs: []logger.Loc{rule.Loc}}}, sel.Selectors...)\n\t\t\t}\n\t\t}\n\n\t\t// Pass 2: Substitute \"&\" for the parent selector\n\t\tif !p.options.unsupportedCSSFeatures.Has(compat.IsPseudoClass) || len(context.parentSelectorsNoPseudo) <= 1 {\n\t\t\t// If we can use \":is\", or we don't have to because there's only one\n\t\t\t// parent selector, or we are using \":is()\" to match zero parent selectors\n\t\t\t// (even if \":is\" is unsupported), then substituting \"&\" for the parent\n\t\t\t// selector is easy.\n\t\t\tfor i := range r.Selectors {\n\t\t\t\tcomplex := &r.Selectors[i]\n\t\t\t\tresults := make([]css_ast.CompoundSelector, 0, len(complex.Selectors))\n\t\t\t\tparent := p.multipleComplexSelectorsToSingleComplexSelector(context.parentSelectorsNoPseudo)\n\t\t\t\tfor _, compound := range complex.Selectors {\n\t\t\t\t\tresults = p.substituteAmpersandsInCompoundSelector(compound, parent, results, keepLeadingCombinator)\n\t\t\t\t}\n\t\t\t\tcomplex.Selectors = results\n\t\t\t}\n\t\t} else {\n\t\t\t// Otherwise if we can't use \":is\", the transform is more complicated.\n\t\t\t// Avoiding \":is\" can lead to a combinatorial explosion of cases so we\n\t\t\t// want to avoid this if possible. For example:\n\t\t\t//\n\t\t\t//   .first, .second, .third {\n\t\t\t//     & > & {\n\t\t\t//       color: red;\n\t\t\t//     }\n\t\t\t//   }\n\t\t\t//\n\t\t\t// If we can use \":is\" (the easy case above) then we can do this:\n\t\t\t//\n\t\t\t//   :is(.first, .second, .third) > :is(.first, .second, .third) {\n\t\t\t//     color: red;\n\t\t\t//   }\n\t\t\t//\n\t\t\t// But if we can't use \":is\" then we have to do this instead:\n\t\t\t//\n\t\t\t//   .first > .first,\n\t\t\t//   .first > .second,\n\t\t\t//   .first > .third,\n\t\t\t//   .second > .first,\n\t\t\t//   .second > .second,\n\t\t\t//   .second > .third,\n\t\t\t//   .third > .first,\n\t\t\t//   .third > .second,\n\t\t\t//   .third > .third {\n\t\t\t//     color: red;\n\t\t\t//   }\n\t\t\t//\n\t\t\t// That combinatorial explosion is what the loop below implements. Note\n\t\t\t// that PostCSS's implementation of nesting gets this wrong. It generates\n\t\t\t// this instead:\n\t\t\t//\n\t\t\t//   .first > .first,\n\t\t\t//   .second > .second,\n\t\t\t//   .third > .third {\n\t\t\t//     color: red;\n\t\t\t//   }\n\t\t\t//\n\t\t\t// That's not equivalent, so that's an incorrect transformation.\n\t\t\tvar selectors []css_ast.ComplexSelector\n\t\t\tvar indices []int\n\t\t\tfor {\n\t\t\t\t// Every time we encounter another \"&\", add another dimension\n\t\t\t\toffset := 0\n\t\t\t\tparent := func(loc logger.Loc) css_ast.ComplexSelector {\n\t\t\t\t\tif offset == len(indices) {\n\t\t\t\t\t\tindices = append(indices, 0)\n\t\t\t\t\t}\n\t\t\t\t\tindex := indices[offset]\n\t\t\t\t\toffset++\n\t\t\t\t\treturn context.parentSelectorsNoPseudo[index]\n\t\t\t\t}\n\n\t\t\t\t// Do the substitution for this particular combination\n\t\t\t\tfor i := range r.Selectors {\n\t\t\t\t\tcomplex := r.Selectors[i]\n\t\t\t\t\tresults := make([]css_ast.CompoundSelector, 0, len(complex.Selectors))\n\t\t\t\t\tfor _, compound := range complex.Selectors {\n\t\t\t\t\t\tresults = p.substituteAmpersandsInCompoundSelector(compound, parent, results, keepLeadingCombinator)\n\t\t\t\t\t}\n\t\t\t\t\tcomplex.Selectors = results\n\t\t\t\t\tselectors = append(selectors, complex)\n\t\t\t\t\toffset = 0\n\t\t\t\t}\n\n\t\t\t\t// Do addition with carry on the indices across dimensions\n\t\t\t\tcarry := len(indices)\n\t\t\t\tfor carry > 0 {\n\t\t\t\t\tindex := &indices[carry-1]\n\t\t\t\t\tif *index+1 < len(context.parentSelectorsNoPseudo) {\n\t\t\t\t\t\t*index++\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\t*index = 0\n\t\t\t\t\tcarry--\n\t\t\t\t}\n\t\t\t\tif carry == 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tr.Selectors = selectors\n\t\t}\n\n\t\t// Put limits on the combinatorial explosion to avoid using too much time and/or memory\n\t\tif n := len(r.Selectors); n > oldSelectorsLen && n > 0xFF00 {\n\t\t\tp.addExpansionError(rule.Loc, n)\n\t\t\treturn css_ast.Rule{}\n\t\t}\n\t\tif n := complexSelectorTermCount(r.Selectors); n > oldSelectorsComplexity && n > 0xFF00 {\n\t\t\tp.addExpansionError(rule.Loc, n)\n\t\t\treturn css_ast.Rule{}\n\t\t}\n\n\t\t// Lower all child rules using our newly substituted selector\n\t\tcontext.loweredRules = p.lowerNestingInRule(rule, context.loweredRules)\n\t\treturn css_ast.Rule{}\n\n\tcase *css_ast.RKnownAt:\n\t\tchildContext := lowerNestingContext{\n\t\t\tparentSelectorsWithPseudo: context.parentSelectorsWithPseudo,\n\t\t\tparentSelectorsNoPseudo:   context.parentSelectorsNoPseudo,\n\t\t}\n\t\tr.Rules = p.lowerNestingInRulesAndReturnRemaining(r.Rules, &childContext)\n\n\t\t// \"div { @supports (color: red) { color: red } }\" \"@supports (color: red) { div { color: red } }\"\n\t\tif len(r.Rules) > 0 {\n\t\t\tchildContext.loweredRules = append([]css_ast.Rule{{Loc: rule.Loc, Data: &css_ast.RSelector{\n\t\t\t\tSelectors: context.parentSelectorsWithPseudo,\n\t\t\t\tRules:     r.Rules,\n\t\t\t}}}, childContext.loweredRules...)\n\t\t}\n\n\t\t// \"div { @supports (color: red) { &:hover { color: red } } }\" \"@supports (color: red) { div:hover { color: red } }\"\n\t\tif len(childContext.loweredRules) > 0 {\n\t\t\tr.Rules = childContext.loweredRules\n\t\t\tcontext.loweredRules = append(context.loweredRules, rule)\n\t\t}\n\n\t\treturn css_ast.Rule{}\n\n\tcase *css_ast.RAtMedia:\n\t\tchildContext := lowerNestingContext{\n\t\t\tparentSelectorsWithPseudo: context.parentSelectorsWithPseudo,\n\t\t\tparentSelectorsNoPseudo:   context.parentSelectorsNoPseudo,\n\t\t}\n\t\tr.Rules = p.lowerNestingInRulesAndReturnRemaining(r.Rules, &childContext)\n\n\t\t// \"div { @media screen { color: red } }\" \"@media screen { div { color: red } }\"\n\t\tif len(r.Rules) > 0 {\n\t\t\tchildContext.loweredRules = append([]css_ast.Rule{{Loc: rule.Loc, Data: &css_ast.RSelector{\n\t\t\t\tSelectors: context.parentSelectorsWithPseudo,\n\t\t\t\tRules:     r.Rules,\n\t\t\t}}}, childContext.loweredRules...)\n\t\t}\n\n\t\t// \"div { @media screen { &:hover { color: red } } }\" \"@media screen { div:hover { color: red } }\"\n\t\tif len(childContext.loweredRules) > 0 {\n\t\t\tr.Rules = childContext.loweredRules\n\t\t\tcontext.loweredRules = append(context.loweredRules, rule)\n\t\t}\n\n\t\treturn css_ast.Rule{}\n\n\tcase *css_ast.RAtLayer:\n\t\t// Lower all children and filter out ones that become empty\n\t\tchildContext := lowerNestingContext{\n\t\t\tparentSelectorsWithPseudo: context.parentSelectorsWithPseudo,\n\t\t\tparentSelectorsNoPseudo:   context.parentSelectorsNoPseudo,\n\t\t}\n\t\tr.Rules = p.lowerNestingInRulesAndReturnRemaining(r.Rules, &childContext)\n\n\t\t// \"div { @layer foo { color: red } }\" \"@layer foo { div { color: red } }\"\n\t\tif len(r.Rules) > 0 {\n\t\t\tchildContext.loweredRules = append([]css_ast.Rule{{Loc: rule.Loc, Data: &css_ast.RSelector{\n\t\t\t\tSelectors: context.parentSelectorsWithPseudo,\n\t\t\t\tRules:     r.Rules,\n\t\t\t}}}, childContext.loweredRules...)\n\t\t}\n\n\t\t// \"div { @layer foo { &:hover { color: red } } }\" \"@layer foo { div:hover { color: red } }\"\n\t\t// \"div { @layer foo {} }\" => \"@layer foo {}\" (layers have side effects, so don't remove empty ones)\n\t\tr.Rules = childContext.loweredRules\n\t\tcontext.loweredRules = append(context.loweredRules, rule)\n\t\treturn css_ast.Rule{}\n\t}\n\n\treturn rule\n}\n\ntype leadingCombinatorStrip uint8\n\nconst (\n\tkeepLeadingCombinator leadingCombinatorStrip = iota\n\tstripLeadingCombinator\n)\n\nfunc (p *parser) substituteAmpersandsInCompoundSelector(\n\tsel css_ast.CompoundSelector,\n\treplacementFn func(logger.Loc) css_ast.ComplexSelector,\n\tresults []css_ast.CompoundSelector,\n\tstrip leadingCombinatorStrip,\n) []css_ast.CompoundSelector {\n\tfor _, nestingSelectorLoc := range sel.NestingSelectorLocs {\n\t\treplacement := replacementFn(nestingSelectorLoc)\n\n\t\t// Convert the replacement to a single compound selector\n\t\tvar single css_ast.CompoundSelector\n\t\tif sel.Combinator.Byte == 0 && (len(replacement.Selectors) == 1 || len(results) == 0) {\n\t\t\t// \".foo { :hover & {} }\" => \":hover .foo {}\"\n\t\t\t// \".foo .bar { &:hover {} }\" => \".foo .bar:hover {}\"\n\t\t\tlast := len(replacement.Selectors) - 1\n\t\t\tresults = append(results, replacement.Selectors[:last]...)\n\t\t\tsingle = replacement.Selectors[last]\n\t\t\tif strip == stripLeadingCombinator {\n\t\t\t\tsingle.Combinator = css_ast.Combinator{}\n\t\t\t}\n\t\t\tsel.Combinator = single.Combinator\n\t\t} else if len(replacement.Selectors) == 1 {\n\t\t\t// \".foo { > &:hover {} }\" => \".foo > .foo:hover {}\"\n\t\t\tsingle = replacement.Selectors[0]\n\t\t\tif strip == stripLeadingCombinator {\n\t\t\t\tsingle.Combinator = css_ast.Combinator{}\n\t\t\t}\n\t\t} else {\n\t\t\t// \".foo .bar { :hover & {} }\" => \":hover :is(.foo .bar) {}\"\n\t\t\t// \".foo .bar { > &:hover {} }\" => \".foo .bar > :is(.foo .bar):hover {}\"\n\t\t\tp.reportNestingWithGeneratedPseudoClassIs(nestingSelectorLoc)\n\t\t\tsingle = css_ast.CompoundSelector{\n\t\t\t\tSubclassSelectors: []css_ast.SubclassSelector{{\n\t\t\t\t\tRange: logger.Range{Loc: nestingSelectorLoc},\n\t\t\t\t\tData: &css_ast.SSPseudoClassWithSelectorList{\n\t\t\t\t\t\tKind:      css_ast.PseudoClassIs,\n\t\t\t\t\t\tSelectors: []css_ast.ComplexSelector{replacement.Clone()},\n\t\t\t\t\t},\n\t\t\t\t}},\n\t\t\t}\n\t\t}\n\n\t\tvar subclassSelectorPrefix []css_ast.SubclassSelector\n\n\t\t// Insert the type selector\n\t\tif single.TypeSelector != nil {\n\t\t\tif sel.TypeSelector != nil {\n\t\t\t\tp.reportNestingWithGeneratedPseudoClassIs(nestingSelectorLoc)\n\t\t\t\tsubclassSelectorPrefix = append(subclassSelectorPrefix, css_ast.SubclassSelector{\n\t\t\t\t\tRange: sel.TypeSelector.Range(),\n\t\t\t\t\tData: &css_ast.SSPseudoClassWithSelectorList{\n\t\t\t\t\t\tKind:      css_ast.PseudoClassIs,\n\t\t\t\t\t\tSelectors: []css_ast.ComplexSelector{{Selectors: []css_ast.CompoundSelector{{TypeSelector: sel.TypeSelector}}}},\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}\n\t\t\tsel.TypeSelector = single.TypeSelector\n\t\t}\n\n\t\t// Insert the subclass selectors\n\t\tsubclassSelectorPrefix = append(subclassSelectorPrefix, single.SubclassSelectors...)\n\n\t\t// Write the changes back\n\t\tif len(subclassSelectorPrefix) > 0 {\n\t\t\tsel.SubclassSelectors = append(subclassSelectorPrefix, sel.SubclassSelectors...)\n\t\t}\n\t}\n\tsel.NestingSelectorLocs = nil\n\n\t// \"div { :is(&.foo) {} }\" => \":is(div.foo) {}\"\n\tfor _, ss := range sel.SubclassSelectors {\n\t\tif class, ok := ss.Data.(*css_ast.SSPseudoClassWithSelectorList); ok {\n\t\t\touter := make([]css_ast.ComplexSelector, 0, len(class.Selectors))\n\t\t\tfor _, complex := range class.Selectors {\n\t\t\t\tinner := make([]css_ast.CompoundSelector, 0, len(complex.Selectors))\n\t\t\t\tfor _, sel := range complex.Selectors {\n\t\t\t\t\tinner = p.substituteAmpersandsInCompoundSelector(sel, replacementFn, inner, stripLeadingCombinator)\n\t\t\t\t}\n\t\t\t\touter = append(outer, css_ast.ComplexSelector{Selectors: inner})\n\t\t\t}\n\t\t\tclass.Selectors = outer\n\t\t}\n\t}\n\n\treturn append(results, sel)\n}\n\n// Turn the list of selectors into a single selector by wrapping lists\n// without a single element with \":is(...)\". Note that this may result\n// in an empty \":is()\" selector (which matches nothing).\nfunc (p *parser) multipleComplexSelectorsToSingleComplexSelector(selectors []css_ast.ComplexSelector) func(logger.Loc) css_ast.ComplexSelector {\n\tif len(selectors) == 1 {\n\t\treturn func(logger.Loc) css_ast.ComplexSelector {\n\t\t\treturn selectors[0]\n\t\t}\n\t}\n\n\tvar leadingCombinator css_ast.Combinator\n\tclones := make([]css_ast.ComplexSelector, len(selectors))\n\n\tfor i, sel := range selectors {\n\t\t// \"> a, > b\" => \"> :is(a, b)\" (the caller should have already checked that all leading combinators are the same)\n\t\tleadingCombinator = sel.Selectors[0].Combinator\n\t\tclones[i] = sel.Clone()\n\t}\n\n\treturn func(loc logger.Loc) css_ast.ComplexSelector {\n\t\treturn css_ast.ComplexSelector{\n\t\t\tSelectors: []css_ast.CompoundSelector{{\n\t\t\t\tCombinator: leadingCombinator,\n\t\t\t\tSubclassSelectors: []css_ast.SubclassSelector{{\n\t\t\t\t\tRange: logger.Range{Loc: loc},\n\t\t\t\t\tData: &css_ast.SSPseudoClassWithSelectorList{\n\t\t\t\t\t\tKind:      css_ast.PseudoClassIs,\n\t\t\t\t\t\tSelectors: clones,\n\t\t\t\t\t},\n\t\t\t\t}},\n\t\t\t}},\n\t\t}\n\t}\n}\n\nfunc (p *parser) reportNestingWithGeneratedPseudoClassIs(nestingSelectorLoc logger.Loc) {\n\tif p.options.unsupportedCSSFeatures.Has(compat.IsPseudoClass) {\n\t\t_, didWarn := p.nestingWarnings[nestingSelectorLoc]\n\t\tif didWarn {\n\t\t\t// Only warn at each location once\n\t\t\treturn\n\t\t}\n\t\tif p.nestingWarnings == nil {\n\t\t\tp.nestingWarnings = make(map[logger.Loc]struct{})\n\t\t}\n\t\tp.nestingWarnings[nestingSelectorLoc] = struct{}{}\n\t\ttext := \"Transforming this CSS nesting syntax is not supported in the configured target environment\"\n\t\tif p.options.originalTargetEnv != \"\" {\n\t\t\ttext = fmt.Sprintf(\"%s (%s)\", text, p.options.originalTargetEnv)\n\t\t}\n\t\tr := logger.Range{Loc: nestingSelectorLoc, Len: 1}\n\t\tp.log.AddIDWithNotes(logger.MsgID_CSS_UnsupportedCSSNesting, logger.Warning, &p.tracker, r, text, []logger.MsgData{{\n\t\t\tText: \"The nesting transform for this case must generate an \\\":is(...)\\\" but the configured target environment does not support the \\\":is\\\" pseudo-class.\"}})\n\t}\n}\n"
  },
  {
    "path": "internal/css_parser/css_parser.go",
    "content": "package css_parser\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\n// This is mostly a normal CSS parser with one exception: the addition of\n// support for parsing https://drafts.csswg.org/css-nesting-1/.\n\ntype parser struct {\n\tlog               logger.Log\n\tsource            logger.Source\n\ttokens            []css_lexer.Token\n\tallComments       []logger.Range\n\tlegalComments     []css_lexer.Comment\n\tstack             []css_lexer.T\n\timportRecords     []ast.ImportRecord\n\tsymbols           []ast.Symbol\n\tcomposes          map[ast.Ref]*css_ast.Composes\n\tlocalSymbols      []ast.LocRef\n\tlocalScope        map[string]ast.LocRef\n\tglobalScope       map[string]ast.LocRef\n\tnestingWarnings   map[logger.Loc]struct{}\n\ttracker           logger.LineColumnTracker\n\tenclosingAtMedia  [][]css_ast.MediaQuery\n\tlayersPreImport   [][]string\n\tlayersPostImport  [][]string\n\tenclosingLayer    []string\n\tanonLayerCount    int\n\tindex             int\n\tlegalCommentIndex int\n\tinSelectorSubtree int\n\tprevError         logger.Loc\n\toptions           Options\n\tnestingIsPresent  bool\n\tmakeLocalSymbols  bool\n\thasSeenAtImport   bool\n}\n\ntype Options struct {\n\tcssPrefixData map[css_ast.D]compat.CSSPrefix\n\n\t// This is an embedded struct. Always access these directly instead of off\n\t// the name \"optionsThatSupportStructuralEquality\". This is only grouped like\n\t// this to make the equality comparison easier and safer (and hopefully faster).\n\toptionsThatSupportStructuralEquality\n}\n\ntype symbolMode uint8\n\nconst (\n\tsymbolModeDisabled symbolMode = iota\n\tsymbolModeGlobal\n\tsymbolModeLocal\n)\n\ntype optionsThatSupportStructuralEquality struct {\n\toriginalTargetEnv      string\n\tunsupportedCSSFeatures compat.CSSFeature\n\tminifySyntax           bool\n\tminifyWhitespace       bool\n\tminifyIdentifiers      bool\n\tsymbolMode             symbolMode\n}\n\nfunc OptionsFromConfig(loader config.Loader, options *config.Options) Options {\n\tvar symbolMode symbolMode\n\tswitch loader {\n\tcase config.LoaderGlobalCSS:\n\t\tsymbolMode = symbolModeGlobal\n\tcase config.LoaderLocalCSS:\n\t\tsymbolMode = symbolModeLocal\n\t}\n\n\treturn Options{\n\t\tcssPrefixData: options.CSSPrefixData,\n\n\t\toptionsThatSupportStructuralEquality: optionsThatSupportStructuralEquality{\n\t\t\tminifySyntax:           options.MinifySyntax,\n\t\t\tminifyWhitespace:       options.MinifyWhitespace,\n\t\t\tminifyIdentifiers:      options.MinifyIdentifiers,\n\t\t\tunsupportedCSSFeatures: options.UnsupportedCSSFeatures,\n\t\t\toriginalTargetEnv:      options.OriginalTargetEnv,\n\t\t\tsymbolMode:             symbolMode,\n\t\t},\n\t}\n}\n\nfunc (a *Options) Equal(b *Options) bool {\n\t// Compare \"optionsThatSupportStructuralEquality\"\n\tif a.optionsThatSupportStructuralEquality != b.optionsThatSupportStructuralEquality {\n\t\treturn false\n\t}\n\n\t// Compare \"cssPrefixData\"\n\tif len(a.cssPrefixData) != len(b.cssPrefixData) {\n\t\treturn false\n\t}\n\tfor k, va := range a.cssPrefixData {\n\t\tvb, ok := b.cssPrefixData[k]\n\t\tif !ok || va != vb {\n\t\t\treturn false\n\t\t}\n\t}\n\tfor k := range b.cssPrefixData {\n\t\tif _, ok := b.cssPrefixData[k]; !ok {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc Parse(log logger.Log, source logger.Source, options Options) css_ast.AST {\n\tresult := css_lexer.Tokenize(log, source, css_lexer.Options{\n\t\tRecordAllComments: options.minifyIdentifiers,\n\t})\n\tp := parser{\n\t\tlog:              log,\n\t\tsource:           source,\n\t\ttracker:          logger.MakeLineColumnTracker(&source),\n\t\toptions:          options,\n\t\ttokens:           result.Tokens,\n\t\tallComments:      result.AllComments,\n\t\tlegalComments:    result.LegalComments,\n\t\tprevError:        logger.Loc{Start: -1},\n\t\tcomposes:         make(map[ast.Ref]*css_ast.Composes),\n\t\tlocalScope:       make(map[string]ast.LocRef),\n\t\tglobalScope:      make(map[string]ast.LocRef),\n\t\tmakeLocalSymbols: options.symbolMode == symbolModeLocal,\n\t}\n\trules := p.parseListOfRules(ruleContext{\n\t\tisTopLevel:     true,\n\t\tparseSelectors: true,\n\t})\n\tp.expect(css_lexer.TEndOfFile)\n\treturn css_ast.AST{\n\t\tRules:                rules,\n\t\tCharFreq:             p.computeCharacterFrequency(),\n\t\tSymbols:              p.symbols,\n\t\tImportRecords:        p.importRecords,\n\t\tApproximateLineCount: result.ApproximateLineCount,\n\t\tSourceMapComment:     result.SourceMapComment,\n\t\tLocalSymbols:         p.localSymbols,\n\t\tLocalScope:           p.localScope,\n\t\tGlobalScope:          p.globalScope,\n\t\tComposes:             p.composes,\n\t\tLayersPreImport:      p.layersPreImport,\n\t\tLayersPostImport:     p.layersPostImport,\n\t}\n}\n\n// Compute a character frequency histogram for everything that's not a bound\n// symbol. This is used to modify how minified names are generated for slightly\n// better gzip compression. Even though it's a very small win, we still do it\n// because it's simple to do and very cheap to compute.\nfunc (p *parser) computeCharacterFrequency() *ast.CharFreq {\n\tif !p.options.minifyIdentifiers {\n\t\treturn nil\n\t}\n\n\t// Add everything in the file to the histogram\n\tcharFreq := &ast.CharFreq{}\n\tcharFreq.Scan(p.source.Contents, 1)\n\n\t// Subtract out all comments\n\tfor _, commentRange := range p.allComments {\n\t\tcharFreq.Scan(p.source.TextForRange(commentRange), -1)\n\t}\n\n\t// Subtract out all import paths\n\tfor _, record := range p.importRecords {\n\t\tif !record.SourceIndex.IsValid() {\n\t\t\tcharFreq.Scan(record.Path.Text, -1)\n\t\t}\n\t}\n\n\t// Subtract out all symbols that will be minified\n\tfor _, symbol := range p.symbols {\n\t\tif symbol.Kind == ast.SymbolLocalCSS {\n\t\t\tcharFreq.Scan(symbol.OriginalName, -int32(symbol.UseCountEstimate))\n\t\t}\n\t}\n\n\treturn charFreq\n}\n\nfunc (p *parser) advance() {\n\tif p.index < len(p.tokens) {\n\t\tp.index++\n\t}\n}\n\nfunc (p *parser) at(index int) css_lexer.Token {\n\tif index < len(p.tokens) {\n\t\treturn p.tokens[index]\n\t}\n\treturn css_lexer.Token{\n\t\tKind:  css_lexer.TEndOfFile,\n\t\tRange: logger.Range{Loc: logger.Loc{Start: int32(len(p.source.Contents))}},\n\t}\n}\n\nfunc (p *parser) current() css_lexer.Token {\n\treturn p.at(p.index)\n}\n\nfunc (p *parser) next() css_lexer.Token {\n\treturn p.at(p.index + 1)\n}\n\nfunc (p *parser) raw() string {\n\tt := p.current()\n\treturn p.source.Contents[t.Range.Loc.Start:t.Range.End()]\n}\n\nfunc (p *parser) decoded() string {\n\treturn p.current().DecodedText(p.source.Contents)\n}\n\nfunc (p *parser) peek(kind css_lexer.T) bool {\n\treturn kind == p.current().Kind\n}\n\nfunc (p *parser) eat(kind css_lexer.T) bool {\n\tif p.peek(kind) {\n\t\tp.advance()\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (p *parser) expect(kind css_lexer.T) bool {\n\treturn p.expectWithMatchingLoc(kind, logger.Loc{Start: -1})\n}\n\nfunc (p *parser) expectWithMatchingLoc(kind css_lexer.T, matchingLoc logger.Loc) bool {\n\tif p.eat(kind) {\n\t\treturn true\n\t}\n\tt := p.current()\n\tif (t.Flags & css_lexer.DidWarnAboutSingleLineComment) != 0 {\n\t\treturn false\n\t}\n\n\tvar text string\n\tvar suggestion string\n\tvar notes []logger.MsgData\n\n\texpected := kind.String()\n\tif strings.HasPrefix(expected, \"\\\"\") && strings.HasSuffix(expected, \"\\\"\") {\n\t\tsuggestion = expected[1 : len(expected)-1]\n\t}\n\n\tif (kind == css_lexer.TSemicolon || kind == css_lexer.TColon) && p.index > 0 && p.at(p.index-1).Kind == css_lexer.TWhitespace {\n\t\t// Have a nice error message for forgetting a trailing semicolon or colon\n\t\ttext = fmt.Sprintf(\"Expected %s\", expected)\n\t\tt = p.at(p.index - 1)\n\t} else if (kind == css_lexer.TCloseBrace || kind == css_lexer.TCloseBracket || kind == css_lexer.TCloseParen) &&\n\t\tmatchingLoc.Start != -1 && int(matchingLoc.Start)+1 <= len(p.source.Contents) {\n\t\t// Have a nice error message for forgetting a closing brace/bracket/parenthesis\n\t\tc := p.source.Contents[matchingLoc.Start : matchingLoc.Start+1]\n\t\ttext = fmt.Sprintf(\"Expected %s to go with %q\", expected, c)\n\t\tnotes = append(notes, p.tracker.MsgData(logger.Range{Loc: matchingLoc, Len: 1}, fmt.Sprintf(\"The unbalanced %q is here:\", c)))\n\t} else {\n\t\tswitch t.Kind {\n\t\tcase css_lexer.TEndOfFile, css_lexer.TWhitespace:\n\t\t\ttext = fmt.Sprintf(\"Expected %s but found %s\", expected, t.Kind.String())\n\t\t\tt.Range.Len = 0\n\t\tcase css_lexer.TBadURL, css_lexer.TUnterminatedString:\n\t\t\ttext = fmt.Sprintf(\"Expected %s but found %s\", expected, t.Kind.String())\n\t\tdefault:\n\t\t\ttext = fmt.Sprintf(\"Expected %s but found %q\", expected, p.raw())\n\t\t}\n\t}\n\n\tif t.Range.Loc.Start > p.prevError.Start {\n\t\tdata := p.tracker.MsgData(t.Range, text)\n\t\tdata.Location.Suggestion = suggestion\n\t\tp.log.AddMsgID(logger.MsgID_CSS_CSSSyntaxError, logger.Msg{Kind: logger.Warning, Data: data, Notes: notes})\n\t\tp.prevError = t.Range.Loc\n\t}\n\treturn false\n}\n\nfunc (p *parser) unexpected() {\n\tif t := p.current(); t.Range.Loc.Start > p.prevError.Start && (t.Flags&css_lexer.DidWarnAboutSingleLineComment) == 0 {\n\t\tvar text string\n\t\tswitch t.Kind {\n\t\tcase css_lexer.TEndOfFile, css_lexer.TWhitespace:\n\t\t\ttext = fmt.Sprintf(\"Unexpected %s\", t.Kind.String())\n\t\t\tt.Range.Len = 0\n\t\tcase css_lexer.TBadURL, css_lexer.TUnterminatedString:\n\t\t\ttext = fmt.Sprintf(\"Unexpected %s\", t.Kind.String())\n\t\tdefault:\n\t\t\ttext = fmt.Sprintf(\"Unexpected %q\", p.raw())\n\t\t}\n\t\tp.log.AddID(logger.MsgID_CSS_CSSSyntaxError, logger.Warning, &p.tracker, t.Range, text)\n\t\tp.prevError = t.Range.Loc\n\t}\n}\n\nfunc (p *parser) symbolForName(loc logger.Loc, name string) ast.LocRef {\n\tvar kind ast.SymbolKind\n\tvar scope map[string]ast.LocRef\n\n\tif p.makeLocalSymbols {\n\t\tkind = ast.SymbolLocalCSS\n\t\tscope = p.localScope\n\t} else {\n\t\tkind = ast.SymbolGlobalCSS\n\t\tscope = p.globalScope\n\t}\n\n\tentry, ok := scope[name]\n\tif !ok {\n\t\tentry = ast.LocRef{\n\t\t\tLoc: loc,\n\t\t\tRef: ast.Ref{\n\t\t\t\tSourceIndex: p.source.Index,\n\t\t\t\tInnerIndex:  uint32(len(p.symbols)),\n\t\t\t},\n\t\t}\n\t\tp.symbols = append(p.symbols, ast.Symbol{\n\t\t\tKind:         kind,\n\t\t\tOriginalName: name,\n\t\t\tLink:         ast.InvalidRef,\n\t\t})\n\t\tscope[name] = entry\n\t\tif kind == ast.SymbolLocalCSS {\n\t\t\tp.localSymbols = append(p.localSymbols, entry)\n\t\t}\n\t}\n\n\tp.symbols[entry.Ref.InnerIndex].UseCountEstimate++\n\treturn entry\n}\n\nfunc (p *parser) recordAtLayerRule(layers [][]string) {\n\tif p.anonLayerCount > 0 {\n\t\treturn\n\t}\n\n\tfor _, layer := range layers {\n\t\tif len(p.enclosingLayer) > 0 {\n\t\t\tclone := make([]string, 0, len(p.enclosingLayer)+len(layer))\n\t\t\tlayer = append(append(clone, p.enclosingLayer...), layer...)\n\t\t}\n\t\tp.layersPostImport = append(p.layersPostImport, layer)\n\t}\n}\n\ntype ruleContext struct {\n\tisTopLevel     bool\n\tparseSelectors bool\n}\n\nfunc (p *parser) parseListOfRules(context ruleContext) []css_ast.Rule {\n\tatRuleContext := atRuleContext{}\n\tif context.isTopLevel {\n\t\tatRuleContext.charsetValidity = atRuleValid\n\t\tatRuleContext.importValidity = atRuleValid\n\t\tatRuleContext.isTopLevel = true\n\t}\n\trules := []css_ast.Rule{}\n\tdidFindAtImport := false\n\nloop:\n\tfor {\n\t\tif context.isTopLevel {\n\t\t\tp.nestingIsPresent = false\n\t\t}\n\n\t\t// If there are any legal comments immediately before the current token,\n\t\t// turn them all into comment rules and append them to the current rule list\n\t\tfor p.legalCommentIndex < len(p.legalComments) {\n\t\t\tcomment := p.legalComments[p.legalCommentIndex]\n\t\t\tif comment.TokenIndexAfter > uint32(p.index) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif comment.TokenIndexAfter == uint32(p.index) {\n\t\t\t\trules = append(rules, css_ast.Rule{Loc: comment.Loc, Data: &css_ast.RComment{Text: comment.Text}})\n\t\t\t}\n\t\t\tp.legalCommentIndex++\n\t\t}\n\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.TEndOfFile:\n\t\t\tbreak loop\n\n\t\tcase css_lexer.TCloseBrace:\n\t\t\tif !context.isTopLevel {\n\t\t\t\tbreak loop\n\t\t\t}\n\n\t\tcase css_lexer.TWhitespace:\n\t\t\tp.advance()\n\t\t\tcontinue\n\n\t\tcase css_lexer.TAtKeyword:\n\t\t\trule := p.parseAtRule(atRuleContext)\n\n\t\t\t// Disallow \"@charset\" and \"@import\" after other rules\n\t\t\tif context.isTopLevel {\n\t\t\t\tswitch r := rule.Data.(type) {\n\t\t\t\tcase *css_ast.RAtCharset:\n\t\t\t\t\t// This doesn't invalidate anything because it always comes first\n\n\t\t\t\tcase *css_ast.RAtImport:\n\t\t\t\t\tdidFindAtImport = true\n\t\t\t\t\tif atRuleContext.charsetValidity == atRuleValid {\n\t\t\t\t\t\tatRuleContext.afterLoc = rule.Loc\n\t\t\t\t\t\tatRuleContext.charsetValidity = atRuleInvalidAfter\n\t\t\t\t\t}\n\n\t\t\t\tcase *css_ast.RAtLayer:\n\t\t\t\t\tif atRuleContext.charsetValidity == atRuleValid {\n\t\t\t\t\t\tatRuleContext.afterLoc = rule.Loc\n\t\t\t\t\t\tatRuleContext.charsetValidity = atRuleInvalidAfter\n\t\t\t\t\t}\n\n\t\t\t\t\t// From the specification: \"Note: No @layer rules are allowed between\n\t\t\t\t\t// @import and @namespace rules. Any @layer rule that comes after an\n\t\t\t\t\t// @import or @namespace rule will cause any subsequent @import or\n\t\t\t\t\t// @namespace rules to be ignored.\"\n\t\t\t\t\tif atRuleContext.importValidity == atRuleValid && (r.Rules != nil || didFindAtImport) {\n\t\t\t\t\t\tatRuleContext.afterLoc = rule.Loc\n\t\t\t\t\t\tatRuleContext.charsetValidity = atRuleInvalidAfter\n\t\t\t\t\t\tatRuleContext.importValidity = atRuleInvalidAfter\n\t\t\t\t\t}\n\n\t\t\t\tdefault:\n\t\t\t\t\tif atRuleContext.importValidity == atRuleValid {\n\t\t\t\t\t\tatRuleContext.afterLoc = rule.Loc\n\t\t\t\t\t\tatRuleContext.charsetValidity = atRuleInvalidAfter\n\t\t\t\t\t\tatRuleContext.importValidity = atRuleInvalidAfter\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Lower CSS nesting if it's not supported (but only at the top level)\n\t\t\tif p.nestingIsPresent && p.options.unsupportedCSSFeatures.Has(compat.Nesting) && context.isTopLevel {\n\t\t\t\trules = p.lowerNestingInRule(rule, rules)\n\t\t\t} else {\n\t\t\t\trules = append(rules, rule)\n\t\t\t}\n\t\t\tcontinue\n\n\t\tcase css_lexer.TCDO, css_lexer.TCDC:\n\t\t\tif context.isTopLevel {\n\t\t\t\tp.advance()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif atRuleContext.importValidity == atRuleValid {\n\t\t\tatRuleContext.afterLoc = p.current().Range.Loc\n\t\t\tatRuleContext.charsetValidity = atRuleInvalidAfter\n\t\t\tatRuleContext.importValidity = atRuleInvalidAfter\n\t\t}\n\n\t\t// Note: CSS recently changed to parse and discard declarations\n\t\t// here instead of treating them as the start of a qualified rule.\n\t\t// See also: https://github.com/w3c/csswg-drafts/issues/8834\n\t\tif !context.isTopLevel {\n\t\t\tif scan, index := p.scanForEndOfRule(); scan == endOfRuleSemicolon {\n\t\t\t\ttokens := p.convertTokens(p.tokens[p.index:index])\n\t\t\t\trules = append(rules, css_ast.Rule{Loc: p.current().Range.Loc, Data: &css_ast.RBadDeclaration{Tokens: tokens}})\n\t\t\t\tp.index = index + 1\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tvar rule css_ast.Rule\n\t\tif context.parseSelectors {\n\t\t\trule = p.parseSelectorRule(context.isTopLevel, parseSelectorOpts{})\n\t\t} else {\n\t\t\trule = p.parseQualifiedRule(parseQualifiedRuleOpts{isTopLevel: context.isTopLevel})\n\t\t}\n\n\t\t// Lower CSS nesting if it's not supported (but only at the top level)\n\t\tif p.nestingIsPresent && p.options.unsupportedCSSFeatures.Has(compat.Nesting) && context.isTopLevel {\n\t\t\trules = p.lowerNestingInRule(rule, rules)\n\t\t} else {\n\t\t\trules = append(rules, rule)\n\t\t}\n\t}\n\n\tif p.options.minifySyntax {\n\t\trules = p.mangleRules(rules, context.isTopLevel)\n\t}\n\treturn rules\n}\n\ntype listOfDeclarationsOpts struct {\n\tcomposesContext      *composesContext\n\tcanInlineNoOpNesting bool\n}\n\nfunc (p *parser) parseListOfDeclarations(opts listOfDeclarationsOpts) (list []css_ast.Rule) {\n\tlist = []css_ast.Rule{}\n\tfoundNesting := false\n\n\tfor {\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.TWhitespace, css_lexer.TSemicolon:\n\t\t\tp.advance()\n\n\t\tcase css_lexer.TEndOfFile, css_lexer.TCloseBrace:\n\t\t\tlist = p.processDeclarations(list, opts.composesContext)\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tlist = p.mangleRules(list, false /* isTopLevel */)\n\n\t\t\t\t// Pull out all unnecessarily-nested declarations and stick them at the end\n\t\t\t\tif opts.canInlineNoOpNesting {\n\t\t\t\t\t// \"a { & { x: y } }\" => \"a { x: y }\"\n\t\t\t\t\t// \"a { & { b: c } d: e }\" => \"a { d: e; b: c }\"\n\t\t\t\t\tif foundNesting {\n\t\t\t\t\t\tvar inlineDecls []css_ast.Rule\n\t\t\t\t\t\tn := 0\n\t\t\t\t\t\tfor _, rule := range list {\n\t\t\t\t\t\t\tif rule, ok := rule.Data.(*css_ast.RSelector); ok && len(rule.Selectors) == 1 {\n\t\t\t\t\t\t\t\tif sel := rule.Selectors[0]; len(sel.Selectors) == 1 && sel.Selectors[0].IsSingleAmpersand() {\n\t\t\t\t\t\t\t\t\tinlineDecls = append(inlineDecls, rule.Rules...)\n\t\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlist[n] = rule\n\t\t\t\t\t\t\tn++\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlist = append(list[:n], inlineDecls...)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// \"a, b::before { & { x: y } }\" => \"a, b::before { & { x: y } }\"\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn\n\n\t\tcase css_lexer.TAtKeyword:\n\t\t\tif p.inSelectorSubtree > 0 {\n\t\t\t\tp.nestingIsPresent = true\n\t\t\t}\n\t\t\tlist = append(list, p.parseAtRule(atRuleContext{\n\t\t\t\tisDeclarationList:    true,\n\t\t\t\tcanInlineNoOpNesting: opts.canInlineNoOpNesting,\n\t\t\t}))\n\n\t\t// Reference: https://drafts.csswg.org/css-nesting-1/\n\t\tdefault:\n\t\t\tif scan, _ := p.scanForEndOfRule(); scan == endOfRuleOpenBrace {\n\t\t\t\tp.nestingIsPresent = true\n\t\t\t\tfoundNesting = true\n\t\t\t\trule := p.parseSelectorRule(false, parseSelectorOpts{\n\t\t\t\t\tisDeclarationContext: true,\n\t\t\t\t\tcomposesContext:      opts.composesContext,\n\t\t\t\t})\n\n\t\t\t\t// If this rule was a single \":global\" or \":local\", inline it here. This\n\t\t\t\t// is handled differently than a bare \"&\" with normal CSS nesting because\n\t\t\t\t// that would be inlined at the end of the parent rule's body instead,\n\t\t\t\t// which is probably unexpected (e.g. it would trip people up when trying\n\t\t\t\t// to write rules in a specific order).\n\t\t\t\tif sel, ok := rule.Data.(*css_ast.RSelector); ok && len(sel.Selectors) == 1 {\n\t\t\t\t\tif first := sel.Selectors[0]; len(first.Selectors) == 1 {\n\t\t\t\t\t\tif first := first.Selectors[0]; first.WasEmptyFromLocalOrGlobal && first.IsSingleAmpersand() {\n\t\t\t\t\t\t\tlist = append(list, sel.Rules...)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlist = append(list, rule)\n\t\t\t} else {\n\t\t\t\tlist = append(list, p.parseDeclaration())\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (p *parser) mangleRules(rules []css_ast.Rule, isTopLevel bool) []css_ast.Rule {\n\t// Remove empty rules\n\tmangledRules := make([]css_ast.Rule, 0, len(rules))\n\tvar prevNonComment css_ast.R\nnext:\n\tfor _, rule := range rules {\n\t\tnextNonComment := rule.Data\n\n\t\tswitch r := rule.Data.(type) {\n\t\tcase *css_ast.RAtKeyframes:\n\t\t\t// Do not remove empty \"@keyframe foo {}\" rules. Even empty rules still\n\t\t\t// dispatch JavaScript animation events, so removing them changes\n\t\t\t// behavior: https://bugzilla.mozilla.org/show_bug.cgi?id=1004377.\n\n\t\tcase *css_ast.RAtLayer:\n\t\t\tif len(r.Rules) == 0 && len(r.Names) > 0 {\n\t\t\t\t// Do not remove empty \"@layer foo {}\" rules. The specification says:\n\t\t\t\t// \"Cascade layers are sorted by the order in which they first are\n\t\t\t\t// declared, with nested layers grouped within their parent layers\n\t\t\t\t// before any unlayered rules.\" So removing empty rules could change\n\t\t\t\t// the order in which they are first declared, and is therefore invalid.\n\t\t\t\t//\n\t\t\t\t// We can turn \"@layer foo {}\" into \"@layer foo;\" to be shorter. But\n\t\t\t\t// don't collapse anonymous \"@layer {}\" into \"@layer;\" because that is\n\t\t\t\t// a syntax error.\n\t\t\t\tr.Rules = nil\n\t\t\t} else if len(r.Rules) == 1 && len(r.Names) == 1 {\n\t\t\t\t// Only collapse layers if each layer has exactly one name\n\t\t\t\tif r2, ok := r.Rules[0].Data.(*css_ast.RAtLayer); ok && len(r2.Names) == 1 {\n\t\t\t\t\t// \"@layer a { @layer b {} }\" => \"@layer a.b;\"\n\t\t\t\t\t// \"@layer a { @layer b { c {} } }\" => \"@layer a.b { c {} }\"\n\t\t\t\t\tr.Names[0] = append(r.Names[0], r2.Names[0]...)\n\t\t\t\t\tr.Rules = r2.Rules\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *css_ast.RKnownAt:\n\t\t\tif len(r.Rules) == 0 && atKnownRuleCanBeRemovedIfEmpty[r.AtToken] {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tcase *css_ast.RAtMedia:\n\t\t\tif len(r.Rules) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Unwrap \"@media\" rules that duplicate conditions from a parent \"@media\"\n\t\t\t// rule. This is unlikely to be authored manually but can be automatically\n\t\t\t// generated when using a CSS framework such as Tailwind.\n\t\t\t//\n\t\t\t//   @media (min-width: 1024px) {\n\t\t\t//     .md\\:class {\n\t\t\t//       color: red;\n\t\t\t//     }\n\t\t\t//     @media (min-width: 1024px) {\n\t\t\t//       .md\\:class {\n\t\t\t//         color: red;\n\t\t\t//       }\n\t\t\t//     }\n\t\t\t//   }\n\t\t\t//\n\t\t\t// This converts that code into the following:\n\t\t\t//\n\t\t\t//   @media (min-width: 1024px) {\n\t\t\t//     .md\\:class {\n\t\t\t//       color: red;\n\t\t\t//     }\n\t\t\t//     .md\\:class {\n\t\t\t//       color: red;\n\t\t\t//     }\n\t\t\t//   }\n\t\t\t//\n\t\t\t// Which can then be mangled further.\n\t\t\tfor _, queries := range p.enclosingAtMedia {\n\t\t\t\tif css_ast.MediaQueriesEqual(r.Queries, queries, nil) {\n\t\t\t\t\tmangledRules = append(mangledRules, r.Rules...)\n\t\t\t\t\tcontinue next\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *css_ast.RSelector:\n\t\t\tif len(r.Rules) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Merge adjacent selectors with the same content\n\t\t\t// \"a { color: red; } b { color: red; }\" => \"a, b { color: red; }\"\n\t\t\tif prevNonComment != nil {\n\t\t\t\tif r, ok := rule.Data.(*css_ast.RSelector); ok {\n\t\t\t\t\tif prev, ok := prevNonComment.(*css_ast.RSelector); ok && css_ast.RulesEqual(r.Rules, prev.Rules, nil) &&\n\t\t\t\t\t\tisSafeSelectors(r.Selectors) && isSafeSelectors(prev.Selectors) {\n\t\t\t\t\tnextSelector:\n\t\t\t\t\t\tfor _, sel := range r.Selectors {\n\t\t\t\t\t\t\tfor _, prevSel := range prev.Selectors {\n\t\t\t\t\t\t\t\tif sel.Equal(prevSel, nil) {\n\t\t\t\t\t\t\t\t\t// Don't add duplicate selectors more than once\n\t\t\t\t\t\t\t\t\tcontinue nextSelector\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tprev.Selectors = append(prev.Selectors, sel)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *css_ast.RComment:\n\t\t\tnextNonComment = nil\n\t\t}\n\n\t\tif nextNonComment != nil {\n\t\t\tprevNonComment = nextNonComment\n\t\t}\n\n\t\tmangledRules = append(mangledRules, rule)\n\t}\n\n\t// Mangle non-top-level rules using a back-to-front pass. Top-level rules\n\t// will be mangled by the linker instead for cross-file rule mangling.\n\tif !isTopLevel {\n\t\tremover := MakeDeadRuleMangler(ast.SymbolMap{})\n\t\tmangledRules = remover.RemoveDeadRulesInPlace(p.source.Index, mangledRules, p.importRecords)\n\t}\n\n\treturn mangledRules\n}\n\ntype ruleEntry struct {\n\tdata        css_ast.R\n\tcallCounter uint32\n}\n\ntype hashEntry struct {\n\trules []ruleEntry\n}\n\ntype callEntry struct {\n\timportRecords []ast.ImportRecord\n\tsourceIndex   uint32\n}\n\ntype DeadRuleRemover struct {\n\tentries map[uint32]hashEntry\n\tcalls   []callEntry\n\tcheck   css_ast.CrossFileEqualityCheck\n}\n\nfunc MakeDeadRuleMangler(symbols ast.SymbolMap) DeadRuleRemover {\n\treturn DeadRuleRemover{\n\t\tentries: make(map[uint32]hashEntry),\n\t\tcheck:   css_ast.CrossFileEqualityCheck{Symbols: symbols},\n\t}\n}\n\nfunc (remover *DeadRuleRemover) RemoveDeadRulesInPlace(sourceIndex uint32, rules []css_ast.Rule, importRecords []ast.ImportRecord) []css_ast.Rule {\n\t// The caller may call this function multiple times, each with a different\n\t// set of import records. Remember each set of import records for equality\n\t// checks later.\n\tcallCounter := uint32(len(remover.calls))\n\tremover.calls = append(remover.calls, callEntry{importRecords, sourceIndex})\n\n\t// Remove duplicate rules, scanning from the back so we keep the last\n\t// duplicate. Note that the linker calls this, so we do not want to do\n\t// anything that modifies the rules themselves. One reason is that ASTs\n\t// are immutable at the linking stage. Another reason is that merging\n\t// CSS ASTs from separate files will mess up source maps because a single\n\t// AST cannot simultaneously represent offsets from multiple files.\n\tn := len(rules)\n\tstart := n\nskipRule:\n\tfor i := n - 1; i >= 0; i-- {\n\t\trule := rules[i]\n\n\t\t// Remove rules with selectors that don't apply to anything (e.g. \":is()\")\n\t\tif r, ok := rule.Data.(*css_ast.RSelector); ok && allSelectorsAreDead(r.Selectors) {\n\t\t\tcontinue skipRule\n\t\t}\n\n\t\t// For duplicate rules, omit all but the last copy\n\t\tif hash, ok := rule.Data.Hash(); ok {\n\t\t\tentry := remover.entries[hash]\n\t\t\tfor _, current := range entry.rules {\n\t\t\t\tvar check *css_ast.CrossFileEqualityCheck\n\n\t\t\t\t// If this rule was from another file, then pass along both arrays\n\t\t\t\t// of import records so that the equality check for \"url()\" tokens\n\t\t\t\t// can use them to check for equality.\n\t\t\t\tif current.callCounter != callCounter {\n\t\t\t\t\t// Reuse the same memory allocation\n\t\t\t\t\tcheck = &remover.check\n\t\t\t\t\tcall := remover.calls[current.callCounter]\n\t\t\t\t\tcheck.ImportRecordsA = importRecords\n\t\t\t\t\tcheck.ImportRecordsB = call.importRecords\n\t\t\t\t\tcheck.SourceIndexA = sourceIndex\n\t\t\t\t\tcheck.SourceIndexB = call.sourceIndex\n\t\t\t\t}\n\n\t\t\t\tif rule.Data.Equal(current.data, check) {\n\t\t\t\t\tcontinue skipRule\n\t\t\t\t}\n\t\t\t}\n\t\t\tentry.rules = append(entry.rules, ruleEntry{\n\t\t\t\tdata:        rule.Data,\n\t\t\t\tcallCounter: callCounter,\n\t\t\t})\n\t\t\tremover.entries[hash] = entry\n\t\t}\n\n\t\tstart--\n\t\trules[start] = rule\n\t}\n\n\treturn rules[start:]\n}\n\nfunc containsDeadSelectors(selectors []css_ast.CompoundSelector) bool {\n\tfor _, sel := range selectors {\n\t\tfor _, ss := range sel.SubclassSelectors {\n\t\t\tif pseudo, ok := ss.Data.(*css_ast.SSPseudoClassWithSelectorList); ok && len(pseudo.Selectors) == 0 &&\n\t\t\t\t(pseudo.Kind == css_ast.PseudoClassIs || pseudo.Kind == css_ast.PseudoClassWhere) {\n\t\t\t\t// \":is()\" and \":where()\" never match anything when empty\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc allSelectorsAreDead(selectors []css_ast.ComplexSelector) bool {\n\tfor _, sel := range selectors {\n\t\tif !containsDeadSelectors(sel.Selectors) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Reference: https://developer.mozilla.org/en-US/docs/Web/HTML/Element\nvar nonDeprecatedElementsSupportedByIE7 = map[string]bool{\n\t\"a\":          true,\n\t\"abbr\":       true,\n\t\"address\":    true,\n\t\"area\":       true,\n\t\"b\":          true,\n\t\"base\":       true,\n\t\"blockquote\": true,\n\t\"body\":       true,\n\t\"br\":         true,\n\t\"button\":     true,\n\t\"caption\":    true,\n\t\"cite\":       true,\n\t\"code\":       true,\n\t\"col\":        true,\n\t\"colgroup\":   true,\n\t\"dd\":         true,\n\t\"del\":        true,\n\t\"dfn\":        true,\n\t\"div\":        true,\n\t\"dl\":         true,\n\t\"dt\":         true,\n\t\"em\":         true,\n\t\"embed\":      true,\n\t\"fieldset\":   true,\n\t\"form\":       true,\n\t\"h1\":         true,\n\t\"h2\":         true,\n\t\"h3\":         true,\n\t\"h4\":         true,\n\t\"h5\":         true,\n\t\"h6\":         true,\n\t\"head\":       true,\n\t\"hr\":         true,\n\t\"html\":       true,\n\t\"i\":          true,\n\t\"iframe\":     true,\n\t\"img\":        true,\n\t\"input\":      true,\n\t\"ins\":        true,\n\t\"kbd\":        true,\n\t\"label\":      true,\n\t\"legend\":     true,\n\t\"li\":         true,\n\t\"link\":       true,\n\t\"map\":        true,\n\t\"menu\":       true,\n\t\"meta\":       true,\n\t\"noscript\":   true,\n\t\"object\":     true,\n\t\"ol\":         true,\n\t\"optgroup\":   true,\n\t\"option\":     true,\n\t\"p\":          true,\n\t\"param\":      true,\n\t\"pre\":        true,\n\t\"q\":          true,\n\t\"ruby\":       true,\n\t\"s\":          true,\n\t\"samp\":       true,\n\t\"script\":     true,\n\t\"select\":     true,\n\t\"small\":      true,\n\t\"span\":       true,\n\t\"strong\":     true,\n\t\"style\":      true,\n\t\"sub\":        true,\n\t\"sup\":        true,\n\t\"table\":      true,\n\t\"tbody\":      true,\n\t\"td\":         true,\n\t\"textarea\":   true,\n\t\"tfoot\":      true,\n\t\"th\":         true,\n\t\"thead\":      true,\n\t\"title\":      true,\n\t\"tr\":         true,\n\t\"u\":          true,\n\t\"ul\":         true,\n\t\"var\":        true,\n}\n\n// This only returns true if all of these selectors are considered \"safe\" which\n// means that they are very likely to work in any browser a user might reasonably\n// be using. We do NOT want to merge adjacent qualified rules with the same body\n// if any of the selectors are unsafe, since then browsers which don't support\n// that particular feature would ignore the entire merged qualified rule:\n//\n//\tInput:\n//\t  a { color: red }\n//\t  b { color: red }\n//\t  input::-moz-placeholder { color: red }\n//\n//\tValid output:\n//\t  a, b { color: red }\n//\t  input::-moz-placeholder { color: red }\n//\n//\tInvalid output:\n//\t  a, b, input::-moz-placeholder { color: red }\n//\n// This considers IE 7 and above to be a browser that a user could possibly use.\n// Versions of IE less than 6 are not considered.\nfunc isSafeSelectors(complexSelectors []css_ast.ComplexSelector) bool {\n\tfor _, complex := range complexSelectors {\n\t\tfor _, compound := range complex.Selectors {\n\t\t\tif len(compound.NestingSelectorLocs) > 0 {\n\t\t\t\t// Bail because this is an extension: https://drafts.csswg.org/css-nesting-1/\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tif compound.Combinator.Byte != 0 {\n\t\t\t\t// \"Before Internet Explorer 10, the combinator only works in standards mode\"\n\t\t\t\t// Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tif compound.TypeSelector != nil {\n\t\t\t\tif compound.TypeSelector.NamespacePrefix != nil {\n\t\t\t\t\t// Bail if we hit a namespace, which doesn't work in IE before version 9\n\t\t\t\t\t// Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/Type_selectors\n\t\t\t\t\treturn false\n\t\t\t\t}\n\n\t\t\t\tif compound.TypeSelector.Name.Kind == css_lexer.TIdent && !nonDeprecatedElementsSupportedByIE7[compound.TypeSelector.Name.Text] {\n\t\t\t\t\t// Bail if this element is either deprecated or not supported in IE 7\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor _, ss := range compound.SubclassSelectors {\n\t\t\t\tswitch s := ss.Data.(type) {\n\t\t\t\tcase *css_ast.SSAttribute:\n\t\t\t\t\tif s.MatcherModifier != 0 {\n\t\t\t\t\t\t// Bail if we hit a case modifier, which doesn't work in IE at all\n\t\t\t\t\t\t// Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\n\t\t\t\tcase *css_ast.SSPseudoClass:\n\t\t\t\t\t// Bail if this pseudo class doesn't match a hard-coded list that's\n\t\t\t\t\t// known to work everywhere. For example, \":focus\" doesn't work in IE 7.\n\t\t\t\t\t// Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes\n\t\t\t\t\tif s.Args == nil && !s.IsElement {\n\t\t\t\t\t\tswitch s.Name {\n\t\t\t\t\t\tcase \"active\", \"first-child\", \"hover\", \"link\", \"visited\":\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn false\n\n\t\t\t\tcase *css_ast.SSPseudoClassWithSelectorList:\n\t\t\t\t\t// These definitely don't work in IE 7\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (p *parser) parseURLOrString() (string, logger.Range, bool) {\n\tt := p.current()\n\tswitch t.Kind {\n\tcase css_lexer.TString:\n\t\ttext := p.decoded()\n\t\tp.advance()\n\t\treturn text, t.Range, true\n\n\tcase css_lexer.TURL:\n\t\ttext := p.decoded()\n\t\tp.advance()\n\t\treturn text, t.Range, true\n\n\tcase css_lexer.TFunction:\n\t\tif strings.EqualFold(p.decoded(), \"url\") {\n\t\t\tmatchingLoc := logger.Loc{Start: p.current().Range.End() - 1}\n\t\t\ti := p.index + 1\n\n\t\t\t// Skip over whitespace\n\t\t\tfor p.at(i).Kind == css_lexer.TWhitespace {\n\t\t\t\ti++\n\t\t\t}\n\n\t\t\t// Consume a string\n\t\t\tif p.at(i).Kind == css_lexer.TString {\n\t\t\t\tstringIndex := i\n\t\t\t\ti++\n\n\t\t\t\t// Skip over whitespace\n\t\t\t\tfor p.at(i).Kind == css_lexer.TWhitespace {\n\t\t\t\t\ti++\n\t\t\t\t}\n\n\t\t\t\t// Consume a closing parenthesis\n\t\t\t\tif close := p.at(i).Kind; close == css_lexer.TCloseParen || close == css_lexer.TEndOfFile {\n\t\t\t\t\tt := p.at(stringIndex)\n\t\t\t\t\ttext := t.DecodedText(p.source.Contents)\n\t\t\t\t\tp.index = i\n\t\t\t\t\tp.expectWithMatchingLoc(css_lexer.TCloseParen, matchingLoc)\n\t\t\t\t\treturn text, t.Range, true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn \"\", logger.Range{}, false\n}\n\nfunc (p *parser) expectURLOrString() (url string, r logger.Range, ok bool) {\n\turl, r, ok = p.parseURLOrString()\n\tif !ok {\n\t\tp.expect(css_lexer.TURL)\n\t}\n\treturn\n}\n\ntype atRuleKind uint8\n\nconst (\n\tatRuleUnknown atRuleKind = iota\n\tatRuleDeclarations\n\tatRuleInheritContext\n\tatRuleQualifiedOrEmpty\n\tatRuleEmpty\n)\n\nvar specialAtRules = map[string]atRuleKind{\n\t\"media\":    atRuleInheritContext,\n\t\"supports\": atRuleInheritContext,\n\n\t\"font-face\": atRuleDeclarations,\n\t\"page\":      atRuleDeclarations,\n\n\t// These go inside \"@page\": https://www.w3.org/TR/css-page-3/#syntax-page-selector\n\t\"bottom-center\":       atRuleDeclarations,\n\t\"bottom-left-corner\":  atRuleDeclarations,\n\t\"bottom-left\":         atRuleDeclarations,\n\t\"bottom-right-corner\": atRuleDeclarations,\n\t\"bottom-right\":        atRuleDeclarations,\n\t\"left-bottom\":         atRuleDeclarations,\n\t\"left-middle\":         atRuleDeclarations,\n\t\"left-top\":            atRuleDeclarations,\n\t\"right-bottom\":        atRuleDeclarations,\n\t\"right-middle\":        atRuleDeclarations,\n\t\"right-top\":           atRuleDeclarations,\n\t\"top-center\":          atRuleDeclarations,\n\t\"top-left-corner\":     atRuleDeclarations,\n\t\"top-left\":            atRuleDeclarations,\n\t\"top-right-corner\":    atRuleDeclarations,\n\t\"top-right\":           atRuleDeclarations,\n\n\t// These properties are very deprecated and appear to only be useful for\n\t// mobile versions of internet explorer (which may no longer exist?), but\n\t// they are used by the https://ant.design/ design system so we recognize\n\t// them to avoid the warning.\n\t//\n\t//   Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/@viewport\n\t//   Discussion: https://github.com/w3c/csswg-drafts/issues/4766\n\t//\n\t\"viewport\":     atRuleDeclarations,\n\t\"-ms-viewport\": atRuleDeclarations,\n\n\t// This feature has been removed from the web because it's actively harmful.\n\t// However, there is one exception where \"@-moz-document url-prefix() {\" is\n\t// accepted by Firefox to basically be an \"if Firefox\" conditional rule.\n\t//\n\t//   Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/@document\n\t//   Discussion: https://bugzilla.mozilla.org/show_bug.cgi?id=1035091\n\t//\n\t\"document\":      atRuleInheritContext,\n\t\"-moz-document\": atRuleInheritContext,\n\n\t// This is a new feature that changes how the CSS rule cascade works. It can\n\t// end in either a \"{}\" block or a \";\" rule terminator so we need this special\n\t// case to support both.\n\t//\n\t//   Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/@layer\n\t//   Motivation: https://developer.chrome.com/blog/cascade-layers/\n\t//\n\t\"layer\": atRuleQualifiedOrEmpty,\n\n\t// Reference: https://drafts.csswg.org/css-cascade-6/#scoped-styles\n\t\"scope\": atRuleInheritContext,\n\n\t// Reference: https://drafts.csswg.org/css-fonts-4/#font-palette-values\n\t\"font-palette-values\": atRuleDeclarations,\n\n\t// Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/@counter-style\n\t// Reference: https://drafts.csswg.org/css-counter-styles/#the-counter-style-rule\n\t\"counter-style\": atRuleDeclarations,\n\n\t// Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/@font-feature-values\n\t// Reference: https://drafts.csswg.org/css-fonts/#font-feature-values\n\t\"font-feature-values\": atRuleDeclarations,\n\t\"annotation\":          atRuleDeclarations,\n\t\"character-variant\":   atRuleDeclarations,\n\t\"historical-forms\":    atRuleDeclarations,\n\t\"ornaments\":           atRuleDeclarations,\n\t\"styleset\":            atRuleDeclarations,\n\t\"stylistic\":           atRuleDeclarations,\n\t\"swash\":               atRuleDeclarations,\n\n\t// Container Queries\n\t// Reference: https://drafts.csswg.org/css-contain-3/#container-rule\n\t\"container\": atRuleInheritContext,\n\n\t// Defining before-change style: the @starting-style rule\n\t// Reference: https://drafts.csswg.org/css-transitions-2/#defining-before-change-style-the-starting-style-rule\n\t\"starting-style\": atRuleInheritContext,\n\n\t// Anchor Positioning\n\t// Reference: https://drafts.csswg.org/css-anchor-position-1/#at-ruledef-position-try\n\t\"position-try\": atRuleDeclarations,\n\n\t// @view-transition\n\t// Reference: https://drafts.csswg.org/css-view-transitions-2/#view-transition-rule\n\t\"view-transition\": atRuleDeclarations,\n}\n\nvar atKnownRuleCanBeRemovedIfEmpty = map[string]bool{\n\t\"media\":     true,\n\t\"supports\":  true,\n\t\"font-face\": true,\n\t\"page\":      true,\n\n\t// https://www.w3.org/TR/css-page-3/#syntax-page-selector\n\t\"bottom-center\":       true,\n\t\"bottom-left-corner\":  true,\n\t\"bottom-left\":         true,\n\t\"bottom-right-corner\": true,\n\t\"bottom-right\":        true,\n\t\"left-bottom\":         true,\n\t\"left-middle\":         true,\n\t\"left-top\":            true,\n\t\"right-bottom\":        true,\n\t\"right-middle\":        true,\n\t\"right-top\":           true,\n\t\"top-center\":          true,\n\t\"top-left-corner\":     true,\n\t\"top-left\":            true,\n\t\"top-right-corner\":    true,\n\t\"top-right\":           true,\n\n\t// https://drafts.csswg.org/css-cascade-6/#scoped-styles\n\t\"scope\": true,\n\n\t// https://drafts.csswg.org/css-fonts-4/#font-palette-values\n\t\"font-palette-values\": true,\n\n\t// https://drafts.csswg.org/css-contain-3/#container-rule\n\t\"container\": true,\n}\n\ntype atRuleValidity uint8\n\nconst (\n\tatRuleInvalid atRuleValidity = iota\n\tatRuleValid\n\tatRuleInvalidAfter\n)\n\ntype atRuleContext struct {\n\tafterLoc             logger.Loc\n\tcharsetValidity      atRuleValidity\n\timportValidity       atRuleValidity\n\tcanInlineNoOpNesting bool\n\tisDeclarationList    bool\n\tisTopLevel           bool\n}\n\nfunc (p *parser) parseAtRule(context atRuleContext) css_ast.Rule {\n\t// Parse the name\n\tatToken := p.decoded()\n\tatRange := p.current().Range\n\tlowerAtToken := strings.ToLower(atToken)\n\tkind := specialAtRules[lowerAtToken]\n\tp.advance()\n\n\t// Parse the prelude\n\tpreludeStart := p.index\nabortRuleParser:\n\tswitch lowerAtToken {\n\tcase \"charset\":\n\t\tswitch context.charsetValidity {\n\t\tcase atRuleInvalid:\n\t\t\tp.log.AddID(logger.MsgID_CSS_InvalidAtCharset, logger.Warning, &p.tracker, atRange, \"\\\"@charset\\\" must be the first rule in the file\")\n\n\t\tcase atRuleInvalidAfter:\n\t\t\tp.log.AddIDWithNotes(logger.MsgID_CSS_InvalidAtCharset, logger.Warning, &p.tracker, atRange,\n\t\t\t\t\"\\\"@charset\\\" must be the first rule in the file\",\n\t\t\t\t[]logger.MsgData{p.tracker.MsgData(logger.Range{Loc: context.afterLoc},\n\t\t\t\t\t\"This rule cannot come before a \\\"@charset\\\" rule\")})\n\n\t\tcase atRuleValid:\n\t\t\tkind = atRuleEmpty\n\t\t\tp.expect(css_lexer.TWhitespace)\n\t\t\tif p.peek(css_lexer.TString) {\n\t\t\t\tencoding := p.decoded()\n\t\t\t\tif !strings.EqualFold(encoding, \"UTF-8\") {\n\t\t\t\t\tp.log.AddID(logger.MsgID_CSS_UnsupportedAtCharset, logger.Warning, &p.tracker, p.current().Range,\n\t\t\t\t\t\tfmt.Sprintf(\"\\\"UTF-8\\\" will be used instead of unsupported charset %q\", encoding))\n\t\t\t\t}\n\t\t\t\tp.advance()\n\t\t\t\tp.expect(css_lexer.TSemicolon)\n\t\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RAtCharset{Encoding: encoding}}\n\t\t\t}\n\t\t\tp.expect(css_lexer.TString)\n\t\t}\n\n\tcase \"import\":\n\t\tswitch context.importValidity {\n\t\tcase atRuleInvalid:\n\t\t\tp.log.AddID(logger.MsgID_CSS_InvalidAtImport, logger.Warning, &p.tracker, atRange, \"\\\"@import\\\" is only valid at the top level\")\n\n\t\tcase atRuleInvalidAfter:\n\t\t\tp.log.AddIDWithNotes(logger.MsgID_CSS_InvalidAtImport, logger.Warning, &p.tracker, atRange,\n\t\t\t\t\"All \\\"@import\\\" rules must come first\",\n\t\t\t\t[]logger.MsgData{p.tracker.MsgData(logger.Range{Loc: context.afterLoc},\n\t\t\t\t\t\"This rule cannot come before an \\\"@import\\\" rule\")})\n\n\t\tcase atRuleValid:\n\t\t\tkind = atRuleEmpty\n\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\tif path, r, ok := p.expectURLOrString(); ok {\n\t\t\t\tvar conditions css_ast.ImportConditions\n\t\t\t\timportConditionsStart := p.index\n\n\t\t\t\t// Parse the optional \"layer()\"\n\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t\tif (p.peek(css_lexer.TIdent) || p.peek(css_lexer.TFunction)) && strings.EqualFold(p.decoded(), \"layer\") {\n\t\t\t\t\tp.parseComponentValue()\n\t\t\t\t\tconditions.Layers = p.convertTokens(p.tokens[importConditionsStart:p.index])\n\t\t\t\t\timportConditionsStart = p.index\n\n\t\t\t\t\t// Remove leading and trailing whitespace\n\t\t\t\t\tif len(conditions.Layers) > 0 {\n\t\t\t\t\t\tconditions.Layers[0].Whitespace &= ^(css_ast.WhitespaceBefore | css_ast.WhitespaceAfter)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Parse the optional \"supports()\"\n\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t\tif p.peek(css_lexer.TFunction) && strings.EqualFold(p.decoded(), \"supports\") {\n\t\t\t\t\tp.parseComponentValue()\n\t\t\t\t\tconditions.Supports = p.convertTokens(p.tokens[importConditionsStart:p.index])\n\t\t\t\t\timportConditionsStart = p.index\n\n\t\t\t\t\t// Remove leading and trailing whitespace\n\t\t\t\t\tif len(conditions.Supports) > 0 {\n\t\t\t\t\t\tconditions.Supports[0].Whitespace &= ^(css_ast.WhitespaceBefore | css_ast.WhitespaceAfter)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Parse the optional media query list\n\t\t\t\tconditions.Queries = p.parseMediaQueryListUntil(func(kind css_lexer.T) bool {\n\t\t\t\t\treturn kind == css_lexer.TSemicolon || kind == css_lexer.TOpenBrace ||\n\t\t\t\t\t\tkind == css_lexer.TCloseBrace || kind == css_lexer.TEndOfFile\n\t\t\t\t})\n\t\t\t\tif p.peek(css_lexer.TOpenBrace) {\n\t\t\t\t\tbreak // Avoid parsing an invalid \"@import\" rule\n\t\t\t\t}\n\n\t\t\t\t// Check whether any import conditions are present\n\t\t\t\tvar importConditions *css_ast.ImportConditions\n\t\t\t\tif len(conditions.Layers) > 0 || len(conditions.Supports) > 0 || len(conditions.Queries) > 0 {\n\t\t\t\t\timportConditions = &conditions\n\t\t\t\t}\n\n\t\t\t\tp.expect(css_lexer.TSemicolon)\n\t\t\t\timportRecordIndex := uint32(len(p.importRecords))\n\t\t\t\tp.importRecords = append(p.importRecords, ast.ImportRecord{\n\t\t\t\t\tKind:  ast.ImportAt,\n\t\t\t\t\tPath:  logger.Path{Text: path},\n\t\t\t\t\tRange: r,\n\t\t\t\t})\n\n\t\t\t\t// Fill in the pre-import layers once we see the first \"@import\"\n\t\t\t\tif !p.hasSeenAtImport {\n\t\t\t\t\tp.hasSeenAtImport = true\n\t\t\t\t\tp.layersPreImport = p.layersPostImport\n\t\t\t\t\tp.layersPostImport = nil\n\t\t\t\t}\n\n\t\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RAtImport{\n\t\t\t\t\tImportRecordIndex: importRecordIndex,\n\t\t\t\t\tImportConditions:  importConditions,\n\t\t\t\t}}\n\t\t\t}\n\t\t}\n\n\tcase \"keyframes\", \"-webkit-keyframes\", \"-moz-keyframes\", \"-ms-keyframes\", \"-o-keyframes\":\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tnameLoc := p.current().Range.Loc\n\t\tvar name string\n\n\t\tif p.peek(css_lexer.TIdent) {\n\t\t\tname = p.decoded()\n\t\t\tif isInvalidAnimationName(name) {\n\t\t\t\tmsg := logger.Msg{\n\t\t\t\t\tID:    logger.MsgID_CSS_CSSSyntaxError,\n\t\t\t\t\tKind:  logger.Warning,\n\t\t\t\t\tData:  p.tracker.MsgData(p.current().Range, fmt.Sprintf(\"Cannot use %q as a name for \\\"@keyframes\\\" without quotes\", name)),\n\t\t\t\t\tNotes: []logger.MsgData{{Text: fmt.Sprintf(\"You can put %q in quotes to prevent it from becoming a CSS keyword.\", name)}},\n\t\t\t\t}\n\t\t\t\tmsg.Data.Location.Suggestion = fmt.Sprintf(\"%q\", name)\n\t\t\t\tp.log.AddMsg(msg)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.advance()\n\t\t} else if p.peek(css_lexer.TString) {\n\t\t\t// Note: Strings as names is allowed in the CSS specification and works in\n\t\t\t// Firefox and Safari but Chrome has strangely decided to deliberately not\n\t\t\t// support this. We always turn all string names into identifiers to avoid\n\t\t\t// them silently breaking in Chrome.\n\t\t\tname = p.decoded()\n\t\t\tp.advance()\n\t\t\tif !p.makeLocalSymbols && isInvalidAnimationName(name) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t} else if !p.expect(css_lexer.TIdent) {\n\t\t\tbreak\n\t\t}\n\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tblockStart := p.index\n\n\t\tmatchingLoc := p.current().Range.Loc\n\t\tif p.expect(css_lexer.TOpenBrace) {\n\t\t\tvar blocks []css_ast.KeyframeBlock\n\n\t\tbadSyntax:\n\t\t\tfor {\n\t\t\t\tswitch p.current().Kind {\n\t\t\t\tcase css_lexer.TWhitespace:\n\t\t\t\t\tp.advance()\n\t\t\t\t\tcontinue\n\n\t\t\t\tcase css_lexer.TCloseBrace:\n\t\t\t\t\tcloseBraceLoc := p.current().Range.Loc\n\t\t\t\t\tp.advance()\n\t\t\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RAtKeyframes{\n\t\t\t\t\t\tAtToken:       atToken,\n\t\t\t\t\t\tName:          p.symbolForName(nameLoc, name),\n\t\t\t\t\t\tBlocks:        blocks,\n\t\t\t\t\t\tCloseBraceLoc: closeBraceLoc,\n\t\t\t\t\t}}\n\n\t\t\t\tcase css_lexer.TEndOfFile:\n\t\t\t\t\tbreak badSyntax\n\n\t\t\t\tcase css_lexer.TOpenBrace:\n\t\t\t\t\tp.expect(css_lexer.TPercentage)\n\t\t\t\t\tbreak badSyntax\n\n\t\t\t\tdefault:\n\t\t\t\t\tvar selectors []string\n\t\t\t\t\tvar firstSelectorLoc logger.Loc\n\n\t\t\t\tselectors:\n\t\t\t\t\tfor {\n\t\t\t\t\t\tt := p.current()\n\t\t\t\t\t\tswitch t.Kind {\n\t\t\t\t\t\tcase css_lexer.TWhitespace:\n\t\t\t\t\t\t\tp.advance()\n\t\t\t\t\t\t\tcontinue\n\n\t\t\t\t\t\tcase css_lexer.TOpenBrace:\n\t\t\t\t\t\t\tblockMatchingLoc := p.current().Range.Loc\n\t\t\t\t\t\t\tp.advance()\n\t\t\t\t\t\t\trules := p.parseListOfDeclarations(listOfDeclarationsOpts{})\n\t\t\t\t\t\t\tcloseBraceLoc := p.current().Range.Loc\n\t\t\t\t\t\t\tif !p.expectWithMatchingLoc(css_lexer.TCloseBrace, blockMatchingLoc) {\n\t\t\t\t\t\t\t\tcloseBraceLoc = logger.Loc{}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// \"@keyframes { from {} to { color: red } }\" => \"@keyframes { to { color: red } }\"\n\t\t\t\t\t\t\tif !p.options.minifySyntax || len(rules) > 0 {\n\t\t\t\t\t\t\t\tblocks = append(blocks, css_ast.KeyframeBlock{\n\t\t\t\t\t\t\t\t\tSelectors:     selectors,\n\t\t\t\t\t\t\t\t\tRules:         rules,\n\t\t\t\t\t\t\t\t\tLoc:           firstSelectorLoc,\n\t\t\t\t\t\t\t\t\tCloseBraceLoc: closeBraceLoc,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak selectors\n\n\t\t\t\t\t\tcase css_lexer.TCloseBrace, css_lexer.TEndOfFile:\n\t\t\t\t\t\t\tp.expect(css_lexer.TOpenBrace)\n\t\t\t\t\t\t\tbreak badSyntax\n\n\t\t\t\t\t\tcase css_lexer.TIdent, css_lexer.TPercentage:\n\t\t\t\t\t\t\tif firstSelectorLoc.Start == 0 {\n\t\t\t\t\t\t\t\tfirstSelectorLoc = p.current().Range.Loc\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttext := p.decoded()\n\t\t\t\t\t\t\tif t.Kind == css_lexer.TIdent {\n\t\t\t\t\t\t\t\tif strings.EqualFold(text, \"from\") {\n\t\t\t\t\t\t\t\t\tif p.options.minifySyntax {\n\t\t\t\t\t\t\t\t\t\ttext = \"0%\" // \"0%\" is equivalent to but shorter than \"from\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else if !strings.EqualFold(text, \"to\") {\n\t\t\t\t\t\t\t\t\tp.expect(css_lexer.TPercentage)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if p.options.minifySyntax && text == \"100%\" {\n\t\t\t\t\t\t\t\ttext = \"to\" // \"to\" is equivalent to but shorter than \"100%\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tselectors = append(selectors, text)\n\t\t\t\t\t\t\tp.advance()\n\n\t\t\t\t\t\t\t// Keyframe selectors are comma-separated\n\t\t\t\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t\t\t\t\tif p.eat(css_lexer.TComma) {\n\t\t\t\t\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t\t\t\t\t\tif k := p.current().Kind; k != css_lexer.TIdent && k != css_lexer.TPercentage {\n\t\t\t\t\t\t\t\t\tp.expect(css_lexer.TPercentage)\n\t\t\t\t\t\t\t\t\tbreak badSyntax\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if k := p.current().Kind; k != css_lexer.TOpenBrace && k != css_lexer.TCloseBrace && k != css_lexer.TEndOfFile {\n\t\t\t\t\t\t\t\tp.expect(css_lexer.TComma)\n\t\t\t\t\t\t\t\tbreak badSyntax\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tp.expect(css_lexer.TPercentage)\n\t\t\t\t\t\t\tbreak badSyntax\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Otherwise, finish parsing the body and return an unknown rule\n\t\t\tfor !p.peek(css_lexer.TCloseBrace) && !p.peek(css_lexer.TEndOfFile) {\n\t\t\t\tp.parseComponentValue()\n\t\t\t}\n\t\t\tp.expectWithMatchingLoc(css_lexer.TCloseBrace, matchingLoc)\n\t\t\tprelude := p.convertTokens(p.tokens[preludeStart:blockStart])\n\t\t\tblock, _ := p.convertTokensHelper(p.tokens[blockStart:p.index], css_lexer.TEndOfFile, convertTokensOpts{allowImports: true})\n\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RUnknownAt{AtToken: atToken, Prelude: prelude, Block: block}}\n\t\t}\n\n\tcase \"layer\":\n\t\t// Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/@layer\n\n\t\t// Read the layer name list\n\t\tvar names [][]string\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tif p.peek(css_lexer.TIdent) {\n\t\t\tfor {\n\t\t\t\tident, ok := p.expectValidLayerNameIdent()\n\t\t\t\tif !ok {\n\t\t\t\t\tbreak abortRuleParser\n\t\t\t\t}\n\t\t\t\tname := []string{ident}\n\t\t\t\tfor {\n\t\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t\t\tif !p.eat(css_lexer.TDelimDot) {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t\t\tident, ok := p.expectValidLayerNameIdent()\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\tbreak abortRuleParser\n\t\t\t\t\t}\n\t\t\t\t\tname = append(name, ident)\n\t\t\t\t}\n\t\t\t\tnames = append(names, name)\n\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t\tif !p.eat(css_lexer.TComma) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t}\n\t\t}\n\n\t\t// Read the optional block\n\t\tmatchingLoc := p.current().Range.Loc\n\t\tif len(names) <= 1 && p.eat(css_lexer.TOpenBrace) {\n\t\t\tp.recordAtLayerRule(names)\n\t\t\toldEnclosingLayer := p.enclosingLayer\n\t\t\tif len(names) == 1 {\n\t\t\t\tp.enclosingLayer = append(p.enclosingLayer, names[0]...)\n\t\t\t} else {\n\t\t\t\tp.anonLayerCount++\n\t\t\t}\n\n\t\t\t// Parse the block for this rule\n\t\t\tvar rules []css_ast.Rule\n\t\t\tif context.isDeclarationList {\n\t\t\t\trules = p.parseListOfDeclarations(listOfDeclarationsOpts{\n\t\t\t\t\tcanInlineNoOpNesting: context.canInlineNoOpNesting,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\trules = p.parseListOfRules(ruleContext{\n\t\t\t\t\tparseSelectors: true,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif len(names) != 1 {\n\t\t\t\tp.anonLayerCount--\n\t\t\t}\n\t\t\tp.enclosingLayer = oldEnclosingLayer\n\t\t\tcloseBraceLoc := p.current().Range.Loc\n\t\t\tif !p.expectWithMatchingLoc(css_lexer.TCloseBrace, matchingLoc) {\n\t\t\t\tcloseBraceLoc = logger.Loc{}\n\t\t\t}\n\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RAtLayer{Names: names, Rules: rules, CloseBraceLoc: closeBraceLoc}}\n\t\t}\n\n\t\t// Handle lack of a block\n\t\tif len(names) >= 1 && p.eat(css_lexer.TSemicolon) {\n\t\t\tp.recordAtLayerRule(names)\n\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RAtLayer{Names: names}}\n\t\t}\n\n\t\t// Otherwise there's some kind of syntax error\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.TEndOfFile:\n\t\t\tp.expect(css_lexer.TSemicolon)\n\t\t\tp.recordAtLayerRule(names)\n\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RAtLayer{Names: names}}\n\n\t\tcase css_lexer.TCloseBrace:\n\t\t\tp.expect(css_lexer.TSemicolon)\n\t\t\tif !context.isTopLevel {\n\t\t\t\tp.recordAtLayerRule(names)\n\t\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RAtLayer{Names: names}}\n\t\t\t}\n\n\t\tcase css_lexer.TOpenBrace:\n\t\t\tp.expect(css_lexer.TSemicolon)\n\n\t\tdefault:\n\t\t\tp.unexpected()\n\t\t}\n\n\tcase \"media\":\n\t\tqueries := p.parseMediaQueryListUntil(func(kind css_lexer.T) bool {\n\t\t\treturn kind == css_lexer.TOpenBrace\n\t\t})\n\n\t\t// Expect a block after the query\n\t\tmatchingLoc := p.current().Range.Loc\n\t\tif !p.expect(css_lexer.TOpenBrace) {\n\t\t\tbreak\n\t\t}\n\n\t\t// Push the \"@media\" conditions\n\t\tp.enclosingAtMedia = append(p.enclosingAtMedia, queries)\n\n\t\t// Parse the block for this rule\n\t\tvar rules []css_ast.Rule\n\t\tif context.isDeclarationList {\n\t\t\trules = p.parseListOfDeclarations(listOfDeclarationsOpts{\n\t\t\t\tcanInlineNoOpNesting: context.canInlineNoOpNesting,\n\t\t\t})\n\t\t} else {\n\t\t\trules = p.parseListOfRules(ruleContext{\n\t\t\t\tparseSelectors: true,\n\t\t\t})\n\t\t}\n\n\t\t// Pop the \"@media\" conditions\n\t\tp.enclosingAtMedia = p.enclosingAtMedia[:len(p.enclosingAtMedia)-1]\n\n\t\tcloseBraceLoc := p.current().Range.Loc\n\t\tif !p.expectWithMatchingLoc(css_lexer.TCloseBrace, matchingLoc) {\n\t\t\tcloseBraceLoc = logger.Loc{}\n\t\t}\n\n\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RAtMedia{Queries: queries, Rules: rules, CloseBraceLoc: closeBraceLoc}}\n\n\tcase \"scope\":\n\t\tvar ok bool\n\n\t\t// Parse the start limit\n\t\tvar start []css_ast.ComplexSelector\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tif p.eat(css_lexer.TOpenParen) {\n\t\t\tif start, ok = p.parseSelectorList(parseSelectorOpts{stopOnCloseParen: true}); !ok || !p.expect(css_lexer.TCloseParen) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t}\n\n\t\t// Parse the end limit\n\t\tvar end []css_ast.ComplexSelector\n\t\tif strings.EqualFold(p.decoded(), \"to\") && p.eat(css_lexer.TIdent) {\n\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\tif !p.expect(css_lexer.TOpenParen) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif end, ok = p.parseSelectorList(parseSelectorOpts{stopOnCloseParen: true}); !ok || !p.expect(css_lexer.TCloseParen) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tp.eat(css_lexer.TWhitespace)\n\n\t\t// Expect a block after the query\n\t\tmatchingLoc := p.current().Range.Loc\n\t\tif !p.expect(css_lexer.TOpenBrace) {\n\t\t\tbreak\n\t\t}\n\n\t\t// Parse the block for this rule\n\t\tvar rules []css_ast.Rule\n\t\tif context.isDeclarationList {\n\t\t\trules = p.parseListOfDeclarations(listOfDeclarationsOpts{\n\t\t\t\tcanInlineNoOpNesting: context.canInlineNoOpNesting,\n\t\t\t})\n\t\t} else {\n\t\t\trules = p.parseListOfRules(ruleContext{\n\t\t\t\tparseSelectors: true,\n\t\t\t})\n\t\t}\n\n\t\tcloseBraceLoc := p.current().Range.Loc\n\t\tif !p.expectWithMatchingLoc(css_lexer.TCloseBrace, matchingLoc) {\n\t\t\tcloseBraceLoc = logger.Loc{}\n\t\t}\n\n\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RAtScope{Start: start, End: end, Rules: rules, CloseBraceLoc: closeBraceLoc}}\n\n\tdefault:\n\t\tif kind == atRuleUnknown && lowerAtToken == \"namespace\" {\n\t\t\t// CSS namespaces are a weird feature that appears to only really be\n\t\t\t// useful for styling XML. And the world has moved on from XHTML to\n\t\t\t// HTML5 so pretty much no one uses CSS namespaces anymore. They are\n\t\t\t// also complicated to support in a bundler because CSS namespaces are\n\t\t\t// file-scoped, which means:\n\t\t\t//\n\t\t\t// * Default namespaces can be different in different files, in which\n\t\t\t//   case some default namespaces would have to be converted to prefixed\n\t\t\t//   namespaces to avoid collisions.\n\t\t\t//\n\t\t\t// * Prefixed namespaces from different files can use the same name, in\n\t\t\t//   which case some prefixed namespaces would need to be renamed to\n\t\t\t//   avoid collisions.\n\t\t\t//\n\t\t\t// Instead of implementing all of that for an extremely obscure feature,\n\t\t\t// CSS namespaces are just explicitly not supported.\n\t\t\tp.log.AddID(logger.MsgID_CSS_UnsupportedAtNamespace, logger.Warning, &p.tracker, atRange, \"\\\"@namespace\\\" rules are not supported\")\n\t\t}\n\t}\n\n\t// Parse an unknown prelude\n\tp.index = preludeStart\nprelude:\n\tfor {\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.TOpenBrace, css_lexer.TEndOfFile:\n\t\t\tbreak prelude\n\n\t\tcase css_lexer.TSemicolon, css_lexer.TCloseBrace:\n\t\t\tprelude := p.convertTokens(p.tokens[preludeStart:p.index])\n\n\t\t\tswitch kind {\n\t\t\tcase atRuleQualifiedOrEmpty:\n\t\t\t\t// Parse a known at rule below\n\t\t\t\tbreak prelude\n\n\t\t\tcase atRuleEmpty, atRuleUnknown:\n\t\t\t\t// Parse an unknown at rule\n\t\t\t\tp.expect(css_lexer.TSemicolon)\n\t\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RUnknownAt{AtToken: atToken, Prelude: prelude}}\n\n\t\t\tdefault:\n\t\t\t\t// Report an error for rules that should have blocks\n\t\t\t\tp.expect(css_lexer.TOpenBrace)\n\t\t\t\tp.eat(css_lexer.TSemicolon)\n\t\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RUnknownAt{AtToken: atToken, Prelude: prelude}}\n\t\t\t}\n\n\t\tdefault:\n\t\t\tp.parseComponentValue()\n\t\t}\n\t}\n\tprelude := p.convertTokens(p.tokens[preludeStart:p.index])\n\tblockStart := p.index\n\n\tswitch kind {\n\tcase atRuleEmpty:\n\t\t// Report an error for rules that shouldn't have blocks\n\t\tp.expect(css_lexer.TSemicolon)\n\t\tp.parseBlock(css_lexer.TOpenBrace, css_lexer.TCloseBrace)\n\t\tblock := p.convertTokens(p.tokens[blockStart:p.index])\n\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RUnknownAt{AtToken: atToken, Prelude: prelude, Block: block}}\n\n\tcase atRuleDeclarations:\n\t\t// Parse known rules whose blocks always consist of declarations\n\t\tmatchingLoc := p.current().Range.Loc\n\t\tp.expect(css_lexer.TOpenBrace)\n\t\trules := p.parseListOfDeclarations(listOfDeclarationsOpts{})\n\t\tcloseBraceLoc := p.current().Range.Loc\n\t\tif !p.expectWithMatchingLoc(css_lexer.TCloseBrace, matchingLoc) {\n\t\t\tcloseBraceLoc = logger.Loc{}\n\t\t}\n\n\t\t// Handle local names for \"@counter-style\"\n\t\tif len(prelude) == 1 && lowerAtToken == \"counter-style\" {\n\t\t\tif t := &prelude[0]; t.Kind == css_lexer.TIdent {\n\t\t\t\tt.Kind = css_lexer.TSymbol\n\t\t\t\tt.PayloadIndex = p.symbolForName(t.Loc, t.Text).Ref.InnerIndex\n\t\t\t}\n\t\t}\n\n\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RKnownAt{AtToken: atToken, Prelude: prelude, Rules: rules, CloseBraceLoc: closeBraceLoc}}\n\n\tcase atRuleInheritContext:\n\t\t// Parse known rules whose blocks consist of whatever the current context is\n\t\tmatchingLoc := p.current().Range.Loc\n\t\tp.expect(css_lexer.TOpenBrace)\n\n\t\t// Parse the block for this rule\n\t\tvar rules []css_ast.Rule\n\t\tif context.isDeclarationList {\n\t\t\trules = p.parseListOfDeclarations(listOfDeclarationsOpts{\n\t\t\t\tcanInlineNoOpNesting: context.canInlineNoOpNesting,\n\t\t\t})\n\t\t} else {\n\t\t\trules = p.parseListOfRules(ruleContext{\n\t\t\t\tparseSelectors: true,\n\t\t\t})\n\t\t}\n\n\t\tcloseBraceLoc := p.current().Range.Loc\n\t\tif !p.expectWithMatchingLoc(css_lexer.TCloseBrace, matchingLoc) {\n\t\t\tcloseBraceLoc = logger.Loc{}\n\t\t}\n\n\t\t// Handle local names for \"@container\"\n\t\tif len(prelude) >= 1 && lowerAtToken == \"container\" {\n\t\t\tif t := &prelude[0]; t.Kind == css_lexer.TIdent && !strings.EqualFold(t.Text, \"not\") {\n\t\t\t\tt.Kind = css_lexer.TSymbol\n\t\t\t\tt.PayloadIndex = p.symbolForName(t.Loc, t.Text).Ref.InnerIndex\n\t\t\t}\n\t\t}\n\n\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RKnownAt{AtToken: atToken, Prelude: prelude, Rules: rules, CloseBraceLoc: closeBraceLoc}}\n\n\tcase atRuleQualifiedOrEmpty:\n\t\tmatchingLoc := p.current().Range.Loc\n\t\tif p.eat(css_lexer.TOpenBrace) {\n\t\t\trules := p.parseListOfRules(ruleContext{\n\t\t\t\tparseSelectors: true,\n\t\t\t})\n\t\t\tcloseBraceLoc := p.current().Range.Loc\n\t\t\tif !p.expectWithMatchingLoc(css_lexer.TCloseBrace, matchingLoc) {\n\t\t\t\tcloseBraceLoc = logger.Loc{}\n\t\t\t}\n\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RKnownAt{AtToken: atToken, Prelude: prelude, Rules: rules, CloseBraceLoc: closeBraceLoc}}\n\t\t}\n\t\tp.expect(css_lexer.TSemicolon)\n\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RKnownAt{AtToken: atToken, Prelude: prelude}}\n\n\tdefault:\n\t\t// Otherwise, parse an unknown rule\n\t\tp.parseBlock(css_lexer.TOpenBrace, css_lexer.TCloseBrace)\n\t\tblock, _ := p.convertTokensHelper(p.tokens[blockStart:p.index], css_lexer.TEndOfFile, convertTokensOpts{allowImports: true})\n\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RUnknownAt{AtToken: atToken, Prelude: prelude, Block: block}}\n\t}\n}\n\nfunc (p *parser) expectValidLayerNameIdent() (string, bool) {\n\tr := p.current().Range\n\ttext := p.decoded()\n\tif !p.expect(css_lexer.TIdent) {\n\t\treturn \"\", false\n\t}\n\tswitch text {\n\tcase \"initial\", \"inherit\", \"unset\":\n\t\tp.log.AddID(logger.MsgID_CSS_InvalidAtLayer, logger.Warning, &p.tracker, r, fmt.Sprintf(\"%q cannot be used as a layer name\", text))\n\t\tp.prevError = r.Loc\n\t\treturn \"\", false\n\t}\n\treturn text, true\n}\n\nfunc (p *parser) convertTokens(tokens []css_lexer.Token) []css_ast.Token {\n\tresult, _ := p.convertTokensHelper(tokens, css_lexer.TEndOfFile, convertTokensOpts{})\n\treturn result\n}\n\ntype convertTokensOpts struct {\n\tallowImports         bool\n\tverbatimWhitespace   bool\n\tisInsideCalcFunction bool\n}\n\nfunc (p *parser) convertTokensHelper(tokens []css_lexer.Token, close css_lexer.T, opts convertTokensOpts) ([]css_ast.Token, []css_lexer.Token) {\n\tresult := []css_ast.Token{}\n\tvar nextWhitespace css_ast.WhitespaceFlags\n\n\t// Enable verbatim whitespace mode when the first two non-whitespace tokens\n\t// are a CSS variable name followed by a colon. This is because it could be\n\t// a form of CSS variable usage, and removing whitespace could potentially\n\t// break this usage. For example, the following CSS is ignored by Chrome if\n\t// the whitespace isn't preserved:\n\t//\n\t//   @supports (--foo: ) {\n\t//     html { background: green; }\n\t//   }\n\t//\n\t// Strangely whitespace removal doesn't cause the declaration to be ignored\n\t// in Firefox or Safari, so there's definitely a browser bug somewhere.\n\tif !opts.verbatimWhitespace {\n\t\tfor i, t := range tokens {\n\t\t\tif t.Kind == css_lexer.TWhitespace {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif t.Kind == css_lexer.TIdent && strings.HasPrefix(t.DecodedText(p.source.Contents), \"--\") {\n\t\t\t\tfor _, t := range tokens[i+1:] {\n\t\t\t\t\tif t.Kind == css_lexer.TWhitespace {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif t.Kind == css_lexer.TColon {\n\t\t\t\t\t\topts.verbatimWhitespace = true\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\nloop:\n\tfor len(tokens) > 0 {\n\t\tt := tokens[0]\n\t\ttokens = tokens[1:]\n\t\tif t.Kind == close {\n\t\t\tbreak loop\n\t\t}\n\t\ttoken := css_ast.Token{\n\t\t\tLoc:        t.Range.Loc,\n\t\t\tKind:       t.Kind,\n\t\t\tText:       t.DecodedText(p.source.Contents),\n\t\t\tWhitespace: nextWhitespace,\n\t\t}\n\t\tnextWhitespace = 0\n\n\t\t// Warn about invalid \"+\" and \"-\" operators that break the containing \"calc()\"\n\t\tif opts.isInsideCalcFunction && t.Kind.IsNumeric() && len(result) > 0 && result[len(result)-1].Kind.IsNumeric() &&\n\t\t\t(strings.HasPrefix(token.Text, \"+\") || strings.HasPrefix(token.Text, \"-\")) {\n\t\t\t// \"calc(1+2)\" and \"calc(1-2)\" are invalid\n\t\t\tp.log.AddID(logger.MsgID_CSS_InvalidCalc, logger.Warning, &p.tracker, logger.Range{Loc: t.Range.Loc, Len: 1},\n\t\t\t\tfmt.Sprintf(\"The %q operator only works if there is whitespace on both sides\", token.Text[:1]))\n\t\t}\n\n\t\tswitch t.Kind {\n\t\tcase css_lexer.TWhitespace:\n\t\t\tif last := len(result) - 1; last >= 0 {\n\t\t\t\tresult[last].Whitespace |= css_ast.WhitespaceAfter\n\t\t\t}\n\t\t\tnextWhitespace = css_ast.WhitespaceBefore\n\t\t\tcontinue\n\n\t\tcase css_lexer.TDelimPlus, css_lexer.TDelimMinus:\n\t\t\t// Warn about invalid \"+\" and \"-\" operators that break the containing \"calc()\"\n\t\t\tif opts.isInsideCalcFunction && len(tokens) > 0 {\n\t\t\t\tif len(result) == 0 || result[len(result)-1].Kind == css_lexer.TComma {\n\t\t\t\t\t// \"calc(-(1 + 2))\" is invalid\n\t\t\t\t\tp.log.AddID(logger.MsgID_CSS_InvalidCalc, logger.Warning, &p.tracker, t.Range,\n\t\t\t\t\t\tfmt.Sprintf(\"%q can only be used as an infix operator, not a prefix operator\", token.Text))\n\t\t\t\t} else if token.Whitespace != css_ast.WhitespaceBefore || tokens[0].Kind != css_lexer.TWhitespace {\n\t\t\t\t\t// \"calc(1- 2)\" and \"calc(1 -(2))\" are invalid\n\t\t\t\t\tp.log.AddID(logger.MsgID_CSS_InvalidCalc, logger.Warning, &p.tracker, t.Range,\n\t\t\t\t\t\tfmt.Sprintf(\"The %q operator only works if there is whitespace on both sides\", token.Text))\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase css_lexer.TNumber:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tif text, ok := mangleNumber(token.Text); ok {\n\t\t\t\t\ttoken.Text = text\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase css_lexer.TPercentage:\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tif text, ok := mangleNumber(token.PercentageValue()); ok {\n\t\t\t\t\ttoken.Text = text + \"%\"\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase css_lexer.TDimension:\n\t\t\ttoken.UnitOffset = t.UnitOffset\n\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tif text, ok := mangleNumber(token.DimensionValue()); ok {\n\t\t\t\t\ttoken.Text = text + token.DimensionUnit()\n\t\t\t\t\ttoken.UnitOffset = uint16(len(text))\n\t\t\t\t}\n\n\t\t\t\tif value, unit, ok := mangleDimension(token.DimensionValue(), token.DimensionUnit()); ok {\n\t\t\t\t\ttoken.Text = value + unit\n\t\t\t\t\ttoken.UnitOffset = uint16(len(value))\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase css_lexer.TURL:\n\t\t\ttoken.PayloadIndex = uint32(len(p.importRecords))\n\t\t\tvar flags ast.ImportRecordFlags\n\t\t\tif !opts.allowImports {\n\t\t\t\tflags |= ast.IsUnused\n\t\t\t}\n\t\t\tp.importRecords = append(p.importRecords, ast.ImportRecord{\n\t\t\t\tKind:  ast.ImportURL,\n\t\t\t\tPath:  logger.Path{Text: token.Text},\n\t\t\t\tRange: t.Range,\n\t\t\t\tFlags: flags,\n\t\t\t})\n\t\t\ttoken.Text = \"\"\n\n\t\tcase css_lexer.TFunction:\n\t\t\tvar nested []css_ast.Token\n\t\t\toriginal := tokens\n\t\t\tnestedOpts := opts\n\t\t\tif strings.EqualFold(token.Text, \"var\") {\n\t\t\t\t// CSS variables require verbatim whitespace for correctness\n\t\t\t\tnestedOpts.verbatimWhitespace = true\n\t\t\t}\n\t\t\tif strings.EqualFold(token.Text, \"calc\") {\n\t\t\t\tnestedOpts.isInsideCalcFunction = true\n\t\t\t}\n\t\t\tnested, tokens = p.convertTokensHelper(tokens, css_lexer.TCloseParen, nestedOpts)\n\t\t\ttoken.Children = &nested\n\n\t\t\t// Apply \"calc\" simplification rules when minifying\n\t\t\tif p.options.minifySyntax && strings.EqualFold(token.Text, \"calc\") {\n\t\t\t\ttoken = p.tryToReduceCalcExpression(token)\n\t\t\t}\n\n\t\t\t// Treat a URL function call with a string just like a URL token\n\t\t\tif strings.EqualFold(token.Text, \"url\") && len(nested) == 1 && nested[0].Kind == css_lexer.TString {\n\t\t\t\ttoken.Kind = css_lexer.TURL\n\t\t\t\ttoken.Text = \"\"\n\t\t\t\ttoken.Children = nil\n\t\t\t\ttoken.PayloadIndex = uint32(len(p.importRecords))\n\t\t\t\tvar flags ast.ImportRecordFlags\n\t\t\t\tif !opts.allowImports {\n\t\t\t\t\tflags |= ast.IsUnused\n\t\t\t\t}\n\t\t\t\tp.importRecords = append(p.importRecords, ast.ImportRecord{\n\t\t\t\t\tKind:  ast.ImportURL,\n\t\t\t\t\tPath:  logger.Path{Text: nested[0].Text},\n\t\t\t\t\tRange: original[0].Range,\n\t\t\t\t\tFlags: flags,\n\t\t\t\t})\n\t\t\t}\n\n\t\tcase css_lexer.TOpenParen:\n\t\t\tvar nested []css_ast.Token\n\t\t\tnested, tokens = p.convertTokensHelper(tokens, css_lexer.TCloseParen, opts)\n\t\t\ttoken.Children = &nested\n\n\t\tcase css_lexer.TOpenBrace:\n\t\t\tvar nested []css_ast.Token\n\t\t\tnested, tokens = p.convertTokensHelper(tokens, css_lexer.TCloseBrace, opts)\n\n\t\t\t// Pretty-printing: insert leading and trailing whitespace when not minifying\n\t\t\tif !opts.verbatimWhitespace && !p.options.minifyWhitespace && len(nested) > 0 {\n\t\t\t\tnested[0].Whitespace |= css_ast.WhitespaceBefore\n\t\t\t\tnested[len(nested)-1].Whitespace |= css_ast.WhitespaceAfter\n\t\t\t}\n\n\t\t\ttoken.Children = &nested\n\n\t\tcase css_lexer.TOpenBracket:\n\t\t\tvar nested []css_ast.Token\n\t\t\tnested, tokens = p.convertTokensHelper(tokens, css_lexer.TCloseBracket, opts)\n\t\t\ttoken.Children = &nested\n\t\t}\n\n\t\tresult = append(result, token)\n\t}\n\n\tif !opts.verbatimWhitespace {\n\t\tfor i := range result {\n\t\t\ttoken := &result[i]\n\n\t\t\t// Always remove leading and trailing whitespace\n\t\t\tif i == 0 {\n\t\t\t\ttoken.Whitespace &= ^css_ast.WhitespaceBefore\n\t\t\t}\n\t\t\tif i+1 == len(result) {\n\t\t\t\ttoken.Whitespace &= ^css_ast.WhitespaceAfter\n\t\t\t}\n\n\t\t\tswitch token.Kind {\n\t\t\tcase css_lexer.TComma:\n\t\t\t\t// Assume that whitespace can always be removed before a comma\n\t\t\t\ttoken.Whitespace &= ^css_ast.WhitespaceBefore\n\t\t\t\tif i > 0 {\n\t\t\t\t\tresult[i-1].Whitespace &= ^css_ast.WhitespaceAfter\n\t\t\t\t}\n\n\t\t\t\t// Assume whitespace can always be added after a comma\n\t\t\t\tif p.options.minifyWhitespace {\n\t\t\t\t\ttoken.Whitespace &= ^css_ast.WhitespaceAfter\n\t\t\t\t\tif i+1 < len(result) {\n\t\t\t\t\t\tresult[i+1].Whitespace &= ^css_ast.WhitespaceBefore\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttoken.Whitespace |= css_ast.WhitespaceAfter\n\t\t\t\t\tif i+1 < len(result) {\n\t\t\t\t\t\tresult[i+1].Whitespace |= css_ast.WhitespaceBefore\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Insert an explicit whitespace token if we're in verbatim mode and all\n\t// tokens were whitespace. In this case there is no token to attach the\n\t// whitespace before/after flags so this is the only way to represent this.\n\t// This is the only case where this function generates an explicit whitespace\n\t// token. It represents whitespace as flags in all other cases.\n\tif opts.verbatimWhitespace && len(result) == 0 && nextWhitespace == css_ast.WhitespaceBefore {\n\t\tresult = append(result, css_ast.Token{\n\t\t\tKind: css_lexer.TWhitespace,\n\t\t})\n\t}\n\n\treturn result, tokens\n}\n\nfunc shiftDot(text string, dotOffset int) (string, bool) {\n\t// This doesn't handle numbers with exponents\n\tif strings.ContainsAny(text, \"eE\") {\n\t\treturn \"\", false\n\t}\n\n\t// Handle a leading sign\n\tsign := \"\"\n\tif len(text) > 0 && (text[0] == '-' || text[0] == '+') {\n\t\tsign = text[:1]\n\t\ttext = text[1:]\n\t}\n\n\t// Remove the dot\n\tdot := strings.IndexByte(text, '.')\n\tif dot == -1 {\n\t\tdot = len(text)\n\t} else {\n\t\ttext = text[:dot] + text[dot+1:]\n\t}\n\n\t// Move the dot\n\tdot += dotOffset\n\n\t// Remove any leading zeros before the dot\n\tfor len(text) > 0 && dot > 0 && text[0] == '0' {\n\t\ttext = text[1:]\n\t\tdot--\n\t}\n\n\t// Remove any trailing zeros after the dot\n\tfor len(text) > 0 && len(text) > dot && text[len(text)-1] == '0' {\n\t\ttext = text[:len(text)-1]\n\t}\n\n\t// Does this number have no fractional component?\n\tif dot >= len(text) {\n\t\ttrailingZeros := strings.Repeat(\"0\", dot-len(text))\n\t\treturn fmt.Sprintf(\"%s%s%s\", sign, text, trailingZeros), true\n\t}\n\n\t// Potentially add leading zeros\n\tif dot < 0 {\n\t\ttext = strings.Repeat(\"0\", -dot) + text\n\t\tdot = 0\n\t}\n\n\t// Insert the dot again\n\treturn fmt.Sprintf(\"%s%s.%s\", sign, text[:dot], text[dot:]), true\n}\n\nfunc mangleDimension(value string, unit string) (string, string, bool) {\n\tconst msLen = 2\n\tconst sLen = 1\n\n\t// Mangle times: https://developer.mozilla.org/en-US/docs/Web/CSS/time\n\tif strings.EqualFold(unit, \"ms\") {\n\t\tif shifted, ok := shiftDot(value, -3); ok && len(shifted)+sLen < len(value)+msLen {\n\t\t\t// Convert \"ms\" to \"s\" if shorter\n\t\t\treturn shifted, \"s\", true\n\t\t}\n\t}\n\tif strings.EqualFold(unit, \"s\") {\n\t\tif shifted, ok := shiftDot(value, 3); ok && len(shifted)+msLen < len(value)+sLen {\n\t\t\t// Convert \"s\" to \"ms\" if shorter\n\t\t\treturn shifted, \"ms\", true\n\t\t}\n\t}\n\n\treturn \"\", \"\", false\n}\n\nfunc mangleNumber(t string) (string, bool) {\n\toriginal := t\n\n\tif dot := strings.IndexByte(t, '.'); dot != -1 {\n\t\t// Remove trailing zeros\n\t\tfor len(t) > 0 && t[len(t)-1] == '0' {\n\t\t\tt = t[:len(t)-1]\n\t\t}\n\n\t\t// Remove the decimal point if it's unnecessary\n\t\tif dot+1 == len(t) {\n\t\t\tt = t[:dot]\n\t\t\tif t == \"\" || t == \"+\" || t == \"-\" {\n\t\t\t\tt += \"0\"\n\t\t\t}\n\t\t} else {\n\t\t\t// Remove a leading zero\n\t\t\tif len(t) >= 3 && t[0] == '0' && t[1] == '.' && t[2] >= '0' && t[2] <= '9' {\n\t\t\t\tt = t[1:]\n\t\t\t} else if len(t) >= 4 && (t[0] == '+' || t[0] == '-') && t[1] == '0' && t[2] == '.' && t[3] >= '0' && t[3] <= '9' {\n\t\t\t\tt = t[0:1] + t[2:]\n\t\t\t}\n\t\t}\n\t}\n\n\treturn t, t != original\n}\n\nfunc (p *parser) parseSelectorRule(isTopLevel bool, opts parseSelectorOpts) css_ast.Rule {\n\t// Save and restore the local symbol state in case there are any bare\n\t// \":global\" or \":local\" annotations. The effect of these should be scoped\n\t// to within the selector rule.\n\tlocal := p.makeLocalSymbols\n\tpreludeStart := p.index\n\n\t// Try parsing the prelude as a selector list\n\tif list, ok := p.parseSelectorList(opts); ok {\n\t\tcanInlineNoOpNesting := true\n\t\tfor _, sel := range list {\n\t\t\t// We cannot transform the CSS \"a, b::before { & { color: red } }\" into\n\t\t\t// \"a, b::before { color: red }\" because it's basically equivalent to\n\t\t\t// \":is(a, b::before) { color: red }\" which only applies to \"a\", not to\n\t\t\t// \"b::before\" because pseudo-elements are not valid within :is():\n\t\t\t// https://www.w3.org/TR/selectors-4/#matches-pseudo. This restriction\n\t\t\t// may be relaxed in the future, but this restriction hash shipped so\n\t\t\t// we're stuck with it: https://github.com/w3c/csswg-drafts/issues/7433.\n\t\t\tif sel.UsesPseudoElement() {\n\t\t\t\tcanInlineNoOpNesting = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tselector := css_ast.RSelector{Selectors: list}\n\t\tmatchingLoc := p.current().Range.Loc\n\t\tif p.expect(css_lexer.TOpenBrace) {\n\t\t\tp.inSelectorSubtree++\n\t\t\tdeclOpts := listOfDeclarationsOpts{\n\t\t\t\tcanInlineNoOpNesting: canInlineNoOpNesting,\n\t\t\t}\n\n\t\t\t// Prepare for \"composes\" declarations\n\t\t\tif opts.composesContext != nil && len(list) == 1 && len(list[0].Selectors) == 1 && list[0].Selectors[0].IsSingleAmpersand() {\n\t\t\t\t// Support code like this:\n\t\t\t\t//\n\t\t\t\t//   .foo {\n\t\t\t\t//     :local { composes: bar }\n\t\t\t\t//     :global { composes: baz }\n\t\t\t\t//   }\n\t\t\t\t//\n\t\t\t\tdeclOpts.composesContext = opts.composesContext\n\t\t\t} else {\n\t\t\t\tcomposesContext := composesContext{parentRange: list[0].Selectors[0].Range()}\n\t\t\t\tif opts.composesContext != nil {\n\t\t\t\t\tcomposesContext.problemRange = opts.composesContext.parentRange\n\t\t\t\t}\n\t\t\t\tfor _, sel := range list {\n\t\t\t\t\tfirst := sel.Selectors[0]\n\t\t\t\t\tif first.Combinator.Byte != 0 {\n\t\t\t\t\t\tcomposesContext.problemRange = logger.Range{Loc: first.Combinator.Loc, Len: 1}\n\t\t\t\t\t} else if first.TypeSelector != nil {\n\t\t\t\t\t\tcomposesContext.problemRange = first.TypeSelector.Range()\n\t\t\t\t\t} else if len(first.NestingSelectorLocs) > 0 {\n\t\t\t\t\t\tcomposesContext.problemRange = logger.Range{Loc: first.NestingSelectorLocs[0], Len: 1}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor i, ss := range first.SubclassSelectors {\n\t\t\t\t\t\t\tclass, ok := ss.Data.(*css_ast.SSClass)\n\t\t\t\t\t\t\tif i > 0 || !ok {\n\t\t\t\t\t\t\t\tcomposesContext.problemRange = ss.Range\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomposesContext.parentRefs = append(composesContext.parentRefs, class.Name.Ref)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif composesContext.problemRange.Len > 0 {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tif len(sel.Selectors) > 1 {\n\t\t\t\t\t\tcomposesContext.problemRange = sel.Selectors[1].Range()\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdeclOpts.composesContext = &composesContext\n\t\t\t}\n\n\t\t\tselector.Rules = p.parseListOfDeclarations(declOpts)\n\t\t\tp.inSelectorSubtree--\n\t\t\tcloseBraceLoc := p.current().Range.Loc\n\t\t\tif p.expectWithMatchingLoc(css_lexer.TCloseBrace, matchingLoc) {\n\t\t\t\tselector.CloseBraceLoc = closeBraceLoc\n\t\t\t}\n\t\t\tp.makeLocalSymbols = local\n\t\t\treturn css_ast.Rule{Loc: p.tokens[preludeStart].Range.Loc, Data: &selector}\n\t\t}\n\t}\n\n\tp.makeLocalSymbols = local\n\tp.index = preludeStart\n\n\t// Otherwise, parse a generic qualified rule\n\treturn p.parseQualifiedRule(parseQualifiedRuleOpts{\n\t\tisAlreadyInvalid:     true,\n\t\tisTopLevel:           isTopLevel,\n\t\tisDeclarationContext: opts.isDeclarationContext,\n\t})\n}\n\ntype parseQualifiedRuleOpts struct {\n\tisAlreadyInvalid     bool\n\tisTopLevel           bool\n\tisDeclarationContext bool\n}\n\nfunc (p *parser) parseQualifiedRule(opts parseQualifiedRuleOpts) css_ast.Rule {\n\tpreludeStart := p.index\n\tpreludeLoc := p.current().Range.Loc\n\nloop:\n\tfor {\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.TOpenBrace, css_lexer.TEndOfFile:\n\t\t\tbreak loop\n\n\t\tcase css_lexer.TCloseBrace:\n\t\t\tif !opts.isTopLevel {\n\t\t\t\tbreak loop\n\t\t\t}\n\n\t\tcase css_lexer.TSemicolon:\n\t\t\tif opts.isDeclarationContext {\n\t\t\t\treturn css_ast.Rule{Loc: preludeLoc, Data: &css_ast.RBadDeclaration{\n\t\t\t\t\tTokens: p.convertTokens(p.tokens[preludeStart:p.index]),\n\t\t\t\t}}\n\t\t\t}\n\t\t}\n\n\t\tp.parseComponentValue()\n\t}\n\n\tqualified := css_ast.RQualified{\n\t\tPrelude: p.convertTokens(p.tokens[preludeStart:p.index]),\n\t}\n\n\tmatchingLoc := p.current().Range.Loc\n\tif p.eat(css_lexer.TOpenBrace) {\n\t\tqualified.Rules = p.parseListOfDeclarations(listOfDeclarationsOpts{})\n\t\tcloseBraceLoc := p.current().Range.Loc\n\t\tif p.expectWithMatchingLoc(css_lexer.TCloseBrace, matchingLoc) {\n\t\t\tqualified.CloseBraceLoc = closeBraceLoc\n\t\t}\n\t} else if !opts.isAlreadyInvalid {\n\t\tp.expect(css_lexer.TOpenBrace)\n\t}\n\n\treturn css_ast.Rule{Loc: preludeLoc, Data: &qualified}\n}\n\ntype endOfRuleScan uint8\n\nconst (\n\tendOfRuleUnknown endOfRuleScan = iota\n\tendOfRuleSemicolon\n\tendOfRuleOpenBrace\n)\n\n// Note: This was a late change to the CSS nesting syntax.\n// See also: https://github.com/w3c/csswg-drafts/issues/7961\nfunc (p *parser) scanForEndOfRule() (endOfRuleScan, int) {\n\tvar initialStack [4]css_lexer.T\n\tstack := initialStack[:0]\n\n\tfor i, t := range p.tokens[p.index:] {\n\t\tswitch t.Kind {\n\t\tcase css_lexer.TSemicolon:\n\t\t\tif len(stack) == 0 {\n\t\t\t\treturn endOfRuleSemicolon, p.index + i\n\t\t\t}\n\n\t\tcase css_lexer.TFunction, css_lexer.TOpenParen:\n\t\t\tstack = append(stack, css_lexer.TCloseParen)\n\n\t\tcase css_lexer.TOpenBracket:\n\t\t\tstack = append(stack, css_lexer.TCloseBracket)\n\n\t\tcase css_lexer.TOpenBrace:\n\t\t\tif len(stack) == 0 {\n\t\t\t\treturn endOfRuleOpenBrace, p.index + i\n\t\t\t}\n\t\t\tstack = append(stack, css_lexer.TCloseBrace)\n\n\t\tcase css_lexer.TCloseParen, css_lexer.TCloseBracket:\n\t\t\tif n := len(stack); n > 0 && t.Kind == stack[n-1] {\n\t\t\t\tstack = stack[:n-1]\n\t\t\t}\n\n\t\tcase css_lexer.TCloseBrace:\n\t\t\tif n := len(stack); n > 0 && t.Kind == stack[n-1] {\n\t\t\t\tstack = stack[:n-1]\n\t\t\t} else {\n\t\t\t\treturn endOfRuleUnknown, -1\n\t\t\t}\n\t\t}\n\t}\n\n\treturn endOfRuleUnknown, -1\n}\n\nfunc (p *parser) parseDeclaration() css_ast.Rule {\n\t// Parse the key\n\tkeyStart := p.index\n\tkeyRange := p.tokens[keyStart].Range\n\tkeyIsIdent := p.expect(css_lexer.TIdent)\n\tok := false\n\tif keyIsIdent {\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tok = p.eat(css_lexer.TColon)\n\t}\n\n\t// Parse the value\n\tvalueStart := p.index\nstop:\n\tfor {\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.TEndOfFile, css_lexer.TSemicolon, css_lexer.TCloseBrace:\n\t\t\tbreak stop\n\n\t\tdefault:\n\t\t\tp.parseComponentValue()\n\t\t}\n\t}\n\n\t// Stop now if this is not a valid declaration\n\tif !ok {\n\t\tif keyIsIdent {\n\t\t\tif end := keyRange.End(); end > p.prevError.Start {\n\t\t\t\tp.prevError.Start = end\n\t\t\t\tdata := p.tracker.MsgData(logger.Range{Loc: logger.Loc{Start: end}}, \"Expected \\\":\\\"\")\n\t\t\t\tdata.Location.Suggestion = \":\"\n\t\t\t\tp.log.AddMsgID(logger.MsgID_CSS_CSSSyntaxError, logger.Msg{\n\t\t\t\t\tKind: logger.Warning,\n\t\t\t\t\tData: data,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\treturn css_ast.Rule{Loc: keyRange.Loc, Data: &css_ast.RBadDeclaration{\n\t\t\tTokens: p.convertTokens(p.tokens[keyStart:p.index]),\n\t\t}}\n\t}\n\n\tkeyToken := p.tokens[keyStart]\n\tkeyText := keyToken.DecodedText(p.source.Contents)\n\tvalue := p.tokens[valueStart:p.index]\n\tverbatimWhitespace := strings.HasPrefix(keyText, \"--\")\n\n\t// Remove trailing \"!important\"\n\timportant := false\n\ti := len(value) - 1\n\tif i >= 0 && value[i].Kind == css_lexer.TWhitespace {\n\t\ti--\n\t}\n\tif i >= 0 && value[i].Kind == css_lexer.TIdent && strings.EqualFold(value[i].DecodedText(p.source.Contents), \"important\") {\n\t\ti--\n\t\tif i >= 0 && value[i].Kind == css_lexer.TWhitespace {\n\t\t\ti--\n\t\t}\n\t\tif i >= 0 && value[i].Kind == css_lexer.TDelimExclamation {\n\t\t\tvalue = value[:i]\n\t\t\timportant = true\n\t\t}\n\t}\n\n\tresult, _ := p.convertTokensHelper(value, css_lexer.TEndOfFile, convertTokensOpts{\n\t\tallowImports: true,\n\n\t\t// CSS variables require verbatim whitespace for correctness\n\t\tverbatimWhitespace: verbatimWhitespace,\n\t})\n\n\t// Insert or remove whitespace before the first token\n\tif !verbatimWhitespace && len(result) > 0 {\n\t\tif p.options.minifyWhitespace {\n\t\t\tresult[0].Whitespace &= ^css_ast.WhitespaceBefore\n\t\t} else {\n\t\t\tresult[0].Whitespace |= css_ast.WhitespaceBefore\n\t\t}\n\t}\n\n\tlowerKeyText := strings.ToLower(keyText)\n\tkey := css_ast.KnownDeclarations[lowerKeyText]\n\n\t// Attempt to point out trivial typos\n\tif key == css_ast.DUnknown {\n\t\tif corrected, ok := css_ast.MaybeCorrectDeclarationTypo(lowerKeyText); ok {\n\t\t\tdata := p.tracker.MsgData(keyToken.Range, fmt.Sprintf(\"%q is not a known CSS property\", keyText))\n\t\t\tdata.Location.Suggestion = corrected\n\t\t\tp.log.AddMsgID(logger.MsgID_CSS_UnsupportedCSSProperty, logger.Msg{Kind: logger.Warning, Data: data,\n\t\t\t\tNotes: []logger.MsgData{{Text: fmt.Sprintf(\"Did you mean %q instead?\", corrected)}}})\n\t\t}\n\t}\n\n\treturn css_ast.Rule{Loc: keyRange.Loc, Data: &css_ast.RDeclaration{\n\t\tKey:       key,\n\t\tKeyText:   keyText,\n\t\tKeyRange:  keyToken.Range,\n\t\tValue:     result,\n\t\tImportant: important,\n\t}}\n}\n\nfunc (p *parser) parseComponentValue() {\n\tswitch p.current().Kind {\n\tcase css_lexer.TFunction:\n\t\tp.parseBlock(css_lexer.TFunction, css_lexer.TCloseParen)\n\n\tcase css_lexer.TOpenParen:\n\t\tp.parseBlock(css_lexer.TOpenParen, css_lexer.TCloseParen)\n\n\tcase css_lexer.TOpenBrace:\n\t\tp.parseBlock(css_lexer.TOpenBrace, css_lexer.TCloseBrace)\n\n\tcase css_lexer.TOpenBracket:\n\t\tp.parseBlock(css_lexer.TOpenBracket, css_lexer.TCloseBracket)\n\n\tcase css_lexer.TEndOfFile:\n\t\tp.unexpected()\n\n\tdefault:\n\t\tp.advance()\n\t}\n}\n\nfunc (p *parser) parseBlock(open css_lexer.T, close css_lexer.T) {\n\tcurrent := p.current()\n\tmatchingStart := current.Range.End() - 1\n\tif p.expect(open) {\n\t\tfor !p.eat(close) {\n\t\t\tif p.peek(css_lexer.TEndOfFile) {\n\t\t\t\tp.expectWithMatchingLoc(close, logger.Loc{Start: matchingStart})\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tp.parseComponentValue()\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "internal/css_parser/css_parser_media.go",
    "content": "package css_parser\n\nimport (\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\n// Reference: https://drafts.csswg.org/mediaqueries-4/\nfunc (p *parser) parseMediaQueryListUntil(stop func(css_lexer.T) bool) []css_ast.MediaQuery {\n\tvar queries []css_ast.MediaQuery\n\tp.eat(css_lexer.TWhitespace)\n\tfor !p.peek(css_lexer.TEndOfFile) && !stop(p.current().Kind) {\n\t\tstart := p.index\n\t\tquery, ok := p.parseMediaQuery()\n\t\tif !ok {\n\t\t\t// If parsing failed, parse an arbitrary sequence of tokens instead\n\t\t\tp.index = start\n\t\t\tloc := p.current().Range.Loc\n\t\t\tfor !p.peek(css_lexer.TEndOfFile) && !stop(p.current().Kind) && !p.peek(css_lexer.TComma) {\n\t\t\t\tp.parseComponentValue()\n\t\t\t}\n\t\t\ttokens := p.convertTokens(p.tokens[start:p.index])\n\t\t\tquery = css_ast.MediaQuery{Loc: loc, Data: &css_ast.MQArbitraryTokens{Tokens: tokens}}\n\t\t}\n\t\tqueries = append(queries, query)\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tif !p.eat(css_lexer.TComma) {\n\t\t\tbreak\n\t\t}\n\t\tp.eat(css_lexer.TWhitespace)\n\t}\n\treturn queries\n}\n\nfunc (p *parser) parseMediaQuery() (css_ast.MediaQuery, bool) {\n\tloc := p.current().Range.Loc\n\n\t// Check for a media condition first\n\tif p.looksLikeMediaCondition() {\n\t\treturn p.parseMediaCondition(mediaWithOr)\n\t}\n\n\t// Parse the media type and potentially the leading \"not\" or \"only\" keyword\n\tmediaType := p.decoded()\n\tif !p.peek(css_lexer.TIdent) {\n\t\tp.expect(css_lexer.TIdent)\n\t\treturn css_ast.MediaQuery{}, false\n\t}\n\top := css_ast.MQTypeOpNone\n\tif strings.EqualFold(mediaType, \"not\") {\n\t\top = css_ast.MQTypeOpNot\n\t} else if strings.EqualFold(mediaType, \"only\") {\n\t\top = css_ast.MQTypeOpOnly\n\t}\n\tif op != css_ast.MQTypeOpNone {\n\t\tp.advance()\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tmediaType = p.decoded()\n\t\tif !p.peek(css_lexer.TIdent) {\n\t\t\tp.expect(css_lexer.TIdent)\n\t\t\treturn css_ast.MediaQuery{}, false\n\t\t}\n\t}\n\n\t// The <media-type> production does not include the keywords \"only\", \"not\", \"and\", \"or\", and \"layer\".\n\tif strings.EqualFold(mediaType, \"only\") ||\n\t\tstrings.EqualFold(mediaType, \"not\") ||\n\t\tstrings.EqualFold(mediaType, \"and\") ||\n\t\tstrings.EqualFold(mediaType, \"or\") ||\n\t\tstrings.EqualFold(mediaType, \"layer\") {\n\t\tp.unexpected()\n\t\treturn css_ast.MediaQuery{}, false\n\t}\n\tp.advance()\n\tp.eat(css_lexer.TWhitespace)\n\n\t// Potentially parse a chain of \"and\" operators\n\tvar andOrNull css_ast.MediaQuery\n\tif p.peek(css_lexer.TIdent) && strings.EqualFold(p.decoded(), \"and\") {\n\t\tp.advance()\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tvar ok bool\n\t\tandOrNull, ok = p.parseMediaCondition(mediaWithoutOr)\n\t\tif !ok {\n\t\t\treturn css_ast.MediaQuery{}, false\n\t\t}\n\t}\n\n\treturn css_ast.MediaQuery{Loc: loc, Data: &css_ast.MQType{Op: op, Type: mediaType, AndOrNull: andOrNull}}, true\n}\n\nfunc (p *parser) looksLikeMediaCondition() bool {\n\tkind := p.current().Kind\n\treturn kind == css_lexer.TOpenParen || kind == css_lexer.TFunction ||\n\t\t(kind == css_lexer.TIdent && strings.EqualFold(p.decoded(), \"not\") &&\n\t\t\tp.next().Kind == css_lexer.TWhitespace &&\n\t\t\tp.at(p.index+2).Kind == css_lexer.TOpenParen)\n}\n\ntype mediaOr uint8\n\nconst (\n\tmediaWithOr mediaOr = iota\n\tmediaWithoutOr\n)\n\nfunc (p *parser) parseMediaCondition(or mediaOr) (css_ast.MediaQuery, bool) {\n\tloc := p.current().Range.Loc\n\n\t// Handle a leading \"not\"\n\tif p.peek(css_lexer.TIdent) && strings.EqualFold(p.decoded(), \"not\") {\n\t\tp.advance()\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tif inner, ok := p.parseMediaInParens(); !ok {\n\t\t\treturn css_ast.MediaQuery{}, false\n\t\t} else {\n\t\t\treturn p.maybeSimplifyMediaNot(loc, inner), true\n\t\t}\n\t}\n\n\t// Parse the first term\n\tfirst, ok := p.parseMediaInParens()\n\tif !ok {\n\t\treturn css_ast.MediaQuery{}, false\n\t}\n\tp.eat(css_lexer.TWhitespace)\n\n\t// Potentially parse a chain of \"and\" or \"or\" operators\n\tif p.peek(css_lexer.TIdent) {\n\t\tif keyword := p.decoded(); strings.EqualFold(keyword, \"and\") || (or == mediaWithOr && strings.EqualFold(keyword, \"or\")) {\n\t\t\top := css_ast.MQBinaryOpAnd\n\t\t\tif len(keyword) == 2 {\n\t\t\t\top = css_ast.MQBinaryOpOr\n\t\t\t}\n\t\t\tinner := p.appendMediaTerm([]css_ast.MediaQuery{}, first, op)\n\t\t\tfor {\n\t\t\t\tp.advance()\n\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t\tnext, ok := p.parseMediaInParens()\n\t\t\t\tif !ok {\n\t\t\t\t\treturn css_ast.MediaQuery{}, false\n\t\t\t\t}\n\t\t\t\tinner = p.appendMediaTerm(inner, next, op)\n\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t\tif !p.peek(css_lexer.TIdent) || !strings.EqualFold(p.decoded(), keyword) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn css_ast.MediaQuery{Loc: loc, Data: &css_ast.MQBinary{Op: op, Terms: inner}}, true\n\t\t}\n\t}\n\n\treturn first, true\n}\n\nfunc (p *parser) appendMediaTerm(inner []css_ast.MediaQuery, term css_ast.MediaQuery, op css_ast.MQBinaryOp) []css_ast.MediaQuery {\n\t// \"(a and b) and c\" => \"a and b and c\"\n\t// \"(a or b) or c\" => \"a or b or c\"\n\tif binary, ok := term.Data.(*css_ast.MQBinary); ok && binary.Op == op && p.options.minifySyntax {\n\t\treturn append(inner, binary.Terms...)\n\t} else {\n\t\treturn append(inner, term)\n\t}\n}\n\nfunc (p *parser) parseMediaInParens() (css_ast.MediaQuery, bool) {\n\tp.eat(css_lexer.TWhitespace)\n\tstart := p.index\n\n\t// Consume the opening token\n\tisFunction := p.eat(css_lexer.TFunction)\n\tif !isFunction && !p.expect(css_lexer.TOpenParen) {\n\t\treturn css_ast.MediaQuery{}, false\n\t}\n\tp.eat(css_lexer.TWhitespace)\n\n\t// Handle a media condition\n\tif !isFunction && p.looksLikeMediaCondition() {\n\t\tif inner, ok := p.parseMediaCondition(mediaWithOr); !ok {\n\t\t\treturn css_ast.MediaQuery{}, false\n\t\t} else {\n\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\tif !p.expect(css_lexer.TCloseParen) {\n\t\t\t\treturn css_ast.MediaQuery{}, false\n\t\t\t}\n\t\t\treturn inner, ok\n\t\t}\n\t}\n\n\t// Scan over the remaining tokens\n\tfor !p.peek(css_lexer.TCloseParen) && !p.peek(css_lexer.TEndOfFile) {\n\t\tp.parseComponentValue()\n\t}\n\tend := p.index\n\tif !p.expect(css_lexer.TCloseParen) {\n\t\treturn css_ast.MediaQuery{}, false\n\t}\n\ttokens := p.convertTokens(p.tokens[start:end])\n\tloc := tokens[0].Loc\n\n\t// Potentially pattern-match the tokens inside the parentheses\n\tif !isFunction && len(tokens) == 1 {\n\t\tif children := tokens[0].Children; children != nil {\n\t\t\tif term, ok := parsePlainOrBooleanMediaFeature(*children); ok {\n\t\t\t\treturn css_ast.MediaQuery{Loc: loc, Data: term}, true\n\t\t\t}\n\t\t\tif term, ok := parseRangeMediaFeature(*children); ok {\n\t\t\t\tif p.options.unsupportedCSSFeatures.Has(compat.MediaRange) {\n\t\t\t\t\tvar terms []css_ast.MediaQuery\n\t\t\t\t\tif term.BeforeCmp != css_ast.MQCmpNone {\n\t\t\t\t\t\tterms = append(terms, lowerMediaRange(term.NameLoc, term.Name, term.BeforeCmp.Reverse(), term.Before))\n\t\t\t\t\t}\n\t\t\t\t\tif term.AfterCmp != css_ast.MQCmpNone {\n\t\t\t\t\t\tterms = append(terms, lowerMediaRange(term.NameLoc, term.Name, term.AfterCmp, term.After))\n\t\t\t\t\t}\n\t\t\t\t\tif len(terms) == 1 {\n\t\t\t\t\t\treturn terms[0], true\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn css_ast.MediaQuery{Loc: loc, Data: &css_ast.MQBinary{Op: css_ast.MQBinaryOpAnd, Terms: terms}}, true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn css_ast.MediaQuery{Loc: loc, Data: term}, true\n\t\t\t}\n\t\t}\n\t}\n\treturn css_ast.MediaQuery{Loc: loc, Data: &css_ast.MQArbitraryTokens{Tokens: tokens}}, true\n}\n\nfunc lowerMediaRange(loc logger.Loc, name string, cmp css_ast.MQCmp, value []css_ast.Token) css_ast.MediaQuery {\n\tswitch cmp {\n\tcase css_ast.MQCmpLe:\n\t\t// \"foo <= 123\" => \"max-foo: 123\"\n\t\treturn css_ast.MediaQuery{Loc: loc, Data: &css_ast.MQPlainOrBoolean{Name: \"max-\" + name, ValueOrNil: value}}\n\n\tcase css_ast.MQCmpGe:\n\t\t// \"foo >= 123\" => \"min-foo: 123\"\n\t\treturn css_ast.MediaQuery{Loc: loc, Data: &css_ast.MQPlainOrBoolean{Name: \"min-\" + name, ValueOrNil: value}}\n\n\tcase css_ast.MQCmpLt:\n\t\t// \"foo < 123\" => \"not (min-foo: 123)\"\n\t\treturn css_ast.MediaQuery{Loc: loc, Data: &css_ast.MQNot{\n\t\t\tInner: css_ast.MediaQuery{Loc: loc, Data: &css_ast.MQPlainOrBoolean{Name: \"min-\" + name, ValueOrNil: value}},\n\t\t}}\n\n\tcase css_ast.MQCmpGt:\n\t\t// \"foo > 123\" => \"not (max-foo: 123)\"\n\t\treturn css_ast.MediaQuery{Loc: loc, Data: &css_ast.MQNot{\n\t\t\tInner: css_ast.MediaQuery{Loc: loc, Data: &css_ast.MQPlainOrBoolean{Name: \"max-\" + name, ValueOrNil: value}},\n\t\t}}\n\n\tdefault:\n\t\t// \"foo = 123\" => \"foo: 123\"\n\t\treturn css_ast.MediaQuery{Loc: loc, Data: &css_ast.MQPlainOrBoolean{Name: name, ValueOrNil: value}}\n\t}\n}\n\nfunc parsePlainOrBooleanMediaFeature(tokens []css_ast.Token) (*css_ast.MQPlainOrBoolean, bool) {\n\tif len(tokens) == 1 && tokens[0].Kind == css_lexer.TIdent {\n\t\treturn &css_ast.MQPlainOrBoolean{Name: tokens[0].Text}, true\n\t}\n\tif len(tokens) >= 3 && tokens[0].Kind == css_lexer.TIdent && tokens[1].Kind == css_lexer.TColon {\n\t\tif value, rest := scanMediaValue(tokens[2:]); len(rest) == 0 {\n\t\t\treturn &css_ast.MQPlainOrBoolean{Name: tokens[0].Text, ValueOrNil: value}, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\nfunc parseRangeMediaFeature(tokens []css_ast.Token) (*css_ast.MQRange, bool) {\n\tif first, tokens := scanMediaValue(tokens); len(first) > 0 {\n\t\tif firstCmp, tokens := scanMediaComparison(tokens); firstCmp != css_ast.MQCmpNone {\n\t\t\tif second, tokens := scanMediaValue(tokens); len(second) > 0 {\n\t\t\t\tif len(tokens) == 0 {\n\t\t\t\t\tif name, nameLoc, ok := isSingleIdent(first); ok {\n\t\t\t\t\t\treturn &css_ast.MQRange{\n\t\t\t\t\t\t\tName:     name,\n\t\t\t\t\t\t\tNameLoc:  nameLoc,\n\t\t\t\t\t\t\tAfterCmp: firstCmp,\n\t\t\t\t\t\t\tAfter:    second,\n\t\t\t\t\t\t}, true\n\t\t\t\t\t} else if name, nameLoc, ok := isSingleIdent(second); ok {\n\t\t\t\t\t\treturn &css_ast.MQRange{\n\t\t\t\t\t\t\tBefore:    first,\n\t\t\t\t\t\t\tBeforeCmp: firstCmp,\n\t\t\t\t\t\t\tName:      name,\n\t\t\t\t\t\t\tNameLoc:   nameLoc,\n\t\t\t\t\t\t}, true\n\t\t\t\t\t}\n\t\t\t\t} else if name, nameLoc, ok := isSingleIdent(second); ok {\n\t\t\t\t\tif secondCmp, tokens := scanMediaComparison(tokens); secondCmp != css_ast.MQCmpNone {\n\t\t\t\t\t\tif f, s := firstCmp.Dir(), secondCmp.Dir(); (f < 0 && s < 0) || (f > 0 && s > 0) {\n\t\t\t\t\t\t\tif third, tokens := scanMediaValue(tokens); len(third) > 0 && len(tokens) == 0 {\n\t\t\t\t\t\t\t\treturn &css_ast.MQRange{\n\t\t\t\t\t\t\t\t\tBefore:    first,\n\t\t\t\t\t\t\t\t\tBeforeCmp: firstCmp,\n\t\t\t\t\t\t\t\t\tName:      name,\n\t\t\t\t\t\t\t\t\tNameLoc:   nameLoc,\n\t\t\t\t\t\t\t\t\tAfterCmp:  secondCmp,\n\t\t\t\t\t\t\t\t\tAfter:     third,\n\t\t\t\t\t\t\t\t}, true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, false\n}\n\nfunc (p *parser) maybeSimplifyMediaNot(loc logger.Loc, inner css_ast.MediaQuery) css_ast.MediaQuery {\n\tif p.options.minifySyntax {\n\t\tswitch data := inner.Data.(type) {\n\t\tcase *css_ast.MQNot:\n\t\t\t// \"not (not a)\" => \"a\"\n\t\t\t// \"not (not (not a))\" => \"not a\"\n\t\t\treturn data.Inner\n\n\t\tcase *css_ast.MQBinary:\n\t\t\t// \"not ((not a) and (not b))\" => \"a or b\"\n\t\t\t// \"not ((not a) or (not b))\" => \"a and b\"\n\t\t\tterms := make([]css_ast.MediaQuery, 0, len(data.Terms))\n\t\t\tfor _, term := range data.Terms {\n\t\t\t\tif not, ok := term.Data.(*css_ast.MQNot); ok {\n\t\t\t\t\tterms = append(terms, not.Inner)\n\t\t\t\t} else {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(terms) == len(data.Terms) {\n\t\t\t\tdata.Op ^= 1\n\t\t\t\tdata.Terms = terms\n\t\t\t\treturn inner\n\t\t\t}\n\n\t\tcase *css_ast.MQRange:\n\t\t\tif (data.BeforeCmp == css_ast.MQCmpNone && data.AfterCmp != css_ast.MQCmpEq) ||\n\t\t\t\t(data.AfterCmp == css_ast.MQCmpNone && data.BeforeCmp != css_ast.MQCmpEq) {\n\t\t\t\tdata.BeforeCmp = data.BeforeCmp.Flip()\n\t\t\t\tdata.AfterCmp = data.AfterCmp.Flip()\n\t\t\t\treturn inner\n\t\t\t}\n\t\t}\n\t}\n\treturn css_ast.MediaQuery{Loc: loc, Data: &css_ast.MQNot{Inner: inner}}\n}\n\nfunc isSingleIdent(tokens []css_ast.Token) (string, logger.Loc, bool) {\n\tif len(tokens) == 1 && tokens[0].Kind == css_lexer.TIdent {\n\t\treturn tokens[0].Text, tokens[0].Loc, true\n\t} else {\n\t\treturn \"\", logger.Loc{}, false\n\t}\n}\n\nfunc scanMediaComparison(tokens []css_ast.Token) (css_ast.MQCmp, []css_ast.Token) {\n\tif len(tokens) >= 1 {\n\t\tswitch tokens[0].Kind {\n\t\tcase css_lexer.TDelimEquals:\n\t\t\treturn css_ast.MQCmpEq, tokens[1:]\n\n\t\tcase css_lexer.TDelimLessThan:\n\t\t\t// Handle \"<=\" or \"<\"\n\t\t\tif len(tokens) >= 2 && tokens[1].Kind == css_lexer.TDelimEquals &&\n\t\t\t\t((tokens[0].Whitespace&css_ast.WhitespaceAfter)|(tokens[1].Whitespace&css_ast.WhitespaceBefore)) == 0 {\n\t\t\t\treturn css_ast.MQCmpLe, tokens[2:]\n\t\t\t}\n\t\t\treturn css_ast.MQCmpLt, tokens[1:]\n\n\t\tcase css_lexer.TDelimGreaterThan:\n\t\t\t// Handle \">=\" or \">\"\n\t\t\tif len(tokens) >= 2 && tokens[1].Kind == css_lexer.TDelimEquals &&\n\t\t\t\t((tokens[0].Whitespace&css_ast.WhitespaceAfter)|(tokens[1].Whitespace&css_ast.WhitespaceBefore)) == 0 {\n\t\t\t\treturn css_ast.MQCmpGe, tokens[2:]\n\t\t\t}\n\t\t\treturn css_ast.MQCmpGt, tokens[1:]\n\t\t}\n\t}\n\n\treturn css_ast.MQCmpNone, tokens\n}\n\nfunc scanMediaValue(tokens []css_ast.Token) ([]css_ast.Token, []css_ast.Token) {\n\tn := 0\n\n\tif len(tokens) >= 1 {\n\t\tswitch tokens[0].Kind {\n\t\tcase css_lexer.TDimension, css_lexer.TIdent:\n\t\t\tn = 1\n\n\t\tcase css_lexer.TNumber:\n\t\t\t// Potentially recognize a ratio which is \"<number> / <number>\"\n\t\t\tif len(tokens) >= 3 && tokens[1].Kind == css_lexer.TDelimSlash && tokens[2].Kind == css_lexer.TNumber {\n\t\t\t\tn = 3\n\t\t\t} else {\n\t\t\t\tn = 1\n\t\t\t}\n\t\t}\n\t}\n\n\t// Trim whitespace at the endpoints\n\tif n > 0 {\n\t\ttokens[0].Whitespace &= ^css_ast.WhitespaceBefore\n\t\ttokens[n-1].Whitespace &= ^css_ast.WhitespaceAfter\n\t}\n\n\treturn tokens[:n], tokens[n:]\n}\n"
  },
  {
    "path": "internal/css_parser/css_parser_selector.go",
    "content": "package css_parser\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\ntype parseSelectorOpts struct {\n\tcomposesContext         *composesContext\n\tpseudoClassKind         css_ast.PseudoClassKind\n\tisDeclarationContext    bool\n\tstopOnCloseParen        bool\n\tonlyOneComplexSelector  bool\n\tisForgivingSelectorList bool\n\tnoLeadingCombinator     bool\n}\n\nfunc (p *parser) parseSelectorList(opts parseSelectorOpts) (list []css_ast.ComplexSelector, ok bool) {\n\t// Potentially parse an empty list for \":is()\" and \":where()\"\n\tif opts.isForgivingSelectorList && opts.stopOnCloseParen && p.peek(css_lexer.TCloseParen) {\n\t\tok = true\n\t\treturn\n\t}\n\n\t// Parse the first selector\n\tsel, good := p.parseComplexSelector(parseComplexSelectorOpts{\n\t\tparseSelectorOpts: opts,\n\t\tisFirst:           true,\n\t})\n\tif !good {\n\t\treturn\n\t}\n\tlist = p.flattenLocalAndGlobalSelectors(list, sel)\n\n\t// Parse the remaining selectors\n\tif opts.onlyOneComplexSelector {\n\t\tif t := p.current(); t.Kind == css_lexer.TComma {\n\t\t\tp.prevError = t.Range.Loc\n\t\t\tkind := fmt.Sprintf(\":%s(...)\", opts.pseudoClassKind.String())\n\t\t\tp.log.AddIDWithNotes(logger.MsgID_CSS_CSSSyntaxError, logger.Warning, &p.tracker, t.Range,\n\t\t\t\tfmt.Sprintf(\"Unexpected \\\",\\\" inside %q\", kind),\n\t\t\t\t[]logger.MsgData{{Text: fmt.Sprintf(\"Different CSS tools behave differently in this case, so esbuild doesn't allow it. \"+\n\t\t\t\t\t\"Either remove this comma or split this selector up into multiple comma-separated %q selectors instead.\", kind)}})\n\t\t\treturn\n\t\t}\n\t} else {\n\tskip:\n\t\tfor {\n\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\tif !p.eat(css_lexer.TComma) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\tsel, good := p.parseComplexSelector(parseComplexSelectorOpts{\n\t\t\t\tparseSelectorOpts: opts,\n\t\t\t})\n\t\t\tif !good {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Omit duplicate selectors\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tfor _, existing := range list {\n\t\t\t\t\tif sel.Equal(existing, nil) {\n\t\t\t\t\t\tcontinue skip\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlist = p.flattenLocalAndGlobalSelectors(list, sel)\n\t\t}\n\t}\n\n\t// Remove the leading ampersand when minifying and it can be implied:\n\t//\n\t//   \"a { & b {} }\" => \"a { b {} }\"\n\t//\n\t// It can't be implied if it's not at the beginning, if there are multiple of\n\t// them, or if the selector list is inside of a pseudo-class selector:\n\t//\n\t//   \"a { b & {} }\"\n\t//   \"a { & b & {} }\"\n\t//   \"a { :has(& b) {} }\"\n\t//\n\tif p.options.minifySyntax && !opts.stopOnCloseParen {\n\t\tfor i := 1; i < len(list); i++ {\n\t\t\tif analyzeLeadingAmpersand(list[i], opts.isDeclarationContext) != cannotRemoveLeadingAmpersand {\n\t\t\t\tlist[i].Selectors = list[i].Selectors[1:]\n\t\t\t}\n\t\t}\n\n\t\tswitch analyzeLeadingAmpersand(list[0], opts.isDeclarationContext) {\n\t\tcase canAlwaysRemoveLeadingAmpersand:\n\t\t\tlist[0].Selectors = list[0].Selectors[1:]\n\n\t\tcase canRemoveLeadingAmpersandIfNotFirst:\n\t\t\tfor i := 1; i < len(list); i++ {\n\t\t\t\tif sel := list[i].Selectors[0]; len(sel.NestingSelectorLocs) == 0 && (sel.Combinator.Byte != 0 || sel.TypeSelector == nil) {\n\t\t\t\t\tlist[0].Selectors = list[0].Selectors[1:]\n\t\t\t\t\tlist[0], list[i] = list[i], list[0]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tok = true\n\treturn\n}\n\nfunc mergeCompoundSelectors(target *css_ast.CompoundSelector, source css_ast.CompoundSelector) {\n\t// \".foo:local(&)\" => \"&.foo\"\n\tif len(source.NestingSelectorLocs) > 0 && len(target.NestingSelectorLocs) == 0 {\n\t\ttarget.NestingSelectorLocs = source.NestingSelectorLocs\n\t}\n\n\tif source.TypeSelector != nil {\n\t\tif target.TypeSelector == nil {\n\t\t\t// \".foo:local(div)\" => \"div.foo\"\n\t\t\ttarget.TypeSelector = source.TypeSelector\n\t\t} else {\n\t\t\t// \"div:local(span)\" => \"div:is(span)\"\n\t\t\t//\n\t\t\t// Note: All other implementations of this (Lightning CSS, PostCSS, and\n\t\t\t// Webpack) do something really weird here. They do this instead:\n\t\t\t//\n\t\t\t// \"div:local(span)\" => \"divspan\"\n\t\t\t//\n\t\t\t// But that just seems so obviously wrong that I'm not going to do that.\n\t\t\ttarget.SubclassSelectors = append(target.SubclassSelectors, css_ast.SubclassSelector{\n\t\t\t\tRange: source.TypeSelector.Range(),\n\t\t\t\tData: &css_ast.SSPseudoClassWithSelectorList{\n\t\t\t\t\tKind:      css_ast.PseudoClassIs,\n\t\t\t\t\tSelectors: []css_ast.ComplexSelector{{Selectors: []css_ast.CompoundSelector{{TypeSelector: source.TypeSelector}}}},\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t}\n\n\t// \".foo:local(.bar)\" => \".foo.bar\"\n\ttarget.SubclassSelectors = append(target.SubclassSelectors, source.SubclassSelectors...)\n}\n\nfunc containsLocalOrGlobalSelector(sel css_ast.ComplexSelector) bool {\n\tfor _, s := range sel.Selectors {\n\t\tfor _, ss := range s.SubclassSelectors {\n\t\t\tswitch pseudo := ss.Data.(type) {\n\t\t\tcase *css_ast.SSPseudoClass:\n\t\t\t\tif pseudo.Name == \"global\" || pseudo.Name == \"local\" {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\n\t\t\tcase *css_ast.SSPseudoClassWithSelectorList:\n\t\t\t\tif pseudo.Kind == css_ast.PseudoClassGlobal || pseudo.Kind == css_ast.PseudoClassLocal {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\n// This handles the \":local()\" and \":global()\" annotations from CSS modules\nfunc (p *parser) flattenLocalAndGlobalSelectors(list []css_ast.ComplexSelector, sel css_ast.ComplexSelector) []css_ast.ComplexSelector {\n\t// Only do the work to flatten the whole list if there's a \":local\" or a \":global\"\n\tif p.options.symbolMode != symbolModeDisabled && containsLocalOrGlobalSelector(sel) {\n\t\tvar selectors []css_ast.CompoundSelector\n\n\t\tfor _, s := range sel.Selectors {\n\t\t\toldSubclassSelectors := s.SubclassSelectors\n\t\t\ts.SubclassSelectors = make([]css_ast.SubclassSelector, 0, len(oldSubclassSelectors))\n\n\t\t\tfor _, ss := range oldSubclassSelectors {\n\t\t\t\tswitch pseudo := ss.Data.(type) {\n\t\t\t\tcase *css_ast.SSPseudoClass:\n\t\t\t\t\tif pseudo.Name == \"global\" || pseudo.Name == \"local\" {\n\t\t\t\t\t\t// Remove bare \":global\" and \":local\" pseudo-classes\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\tcase *css_ast.SSPseudoClassWithSelectorList:\n\t\t\t\t\tif pseudo.Kind == css_ast.PseudoClassGlobal || pseudo.Kind == css_ast.PseudoClassLocal {\n\t\t\t\t\t\tinner := pseudo.Selectors[0].Selectors\n\n\t\t\t\t\t\t// Replace this pseudo-class with all inner compound selectors.\n\t\t\t\t\t\t// The first inner compound selector is merged with the compound\n\t\t\t\t\t\t// selector before it and the last inner compound selector is\n\t\t\t\t\t\t// merged with the compound selector after it:\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// \"div:local(.a .b):hover\" => \"div.a b:hover\"\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// This behavior is really strange since this is not how anything\n\t\t\t\t\t\t// involving pseudo-classes in real CSS works at all. However, all\n\t\t\t\t\t\t// other implementations (Lightning CSS, PostCSS, and Webpack) are\n\t\t\t\t\t\t// consistent with this strange behavior, so we do it too.\n\t\t\t\t\t\tif inner[0].Combinator.Byte == 0 {\n\t\t\t\t\t\t\tmergeCompoundSelectors(&s, inner[0])\n\t\t\t\t\t\t\tinner = inner[1:]\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// \"div:local(+ .foo):hover\" => \"div + .foo:hover\"\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif n := len(inner); n > 0 {\n\t\t\t\t\t\t\tif !s.IsInvalidBecauseEmpty() {\n\t\t\t\t\t\t\t\t// Don't add this selector if it consisted only of a bare \":global\" or \":local\"\n\t\t\t\t\t\t\t\tselectors = append(selectors, s)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tselectors = append(selectors, inner[:n-1]...)\n\t\t\t\t\t\t\ts = inner[n-1]\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\ts.SubclassSelectors = append(s.SubclassSelectors, ss)\n\t\t\t}\n\n\t\t\tif !s.IsInvalidBecauseEmpty() {\n\t\t\t\t// Don't add this selector if it consisted only of a bare \":global\" or \":local\"\n\t\t\t\tselectors = append(selectors, s)\n\t\t\t}\n\t\t}\n\n\t\tif len(selectors) == 0 {\n\t\t\t// Treat a bare \":global\" or \":local\" as a bare \"&\" nesting selector\n\t\t\tselectors = append(selectors, css_ast.CompoundSelector{\n\t\t\t\tNestingSelectorLocs:       []logger.Loc{sel.Selectors[0].Range().Loc},\n\t\t\t\tWasEmptyFromLocalOrGlobal: true,\n\t\t\t})\n\n\t\t\t// Make sure we report that nesting is present so that it can be lowered\n\t\t\tp.nestingIsPresent = true\n\t\t}\n\n\t\tsel.Selectors = selectors\n\t}\n\n\treturn append(list, sel)\n}\n\ntype leadingAmpersand uint8\n\nconst (\n\tcannotRemoveLeadingAmpersand leadingAmpersand = iota\n\tcanAlwaysRemoveLeadingAmpersand\n\tcanRemoveLeadingAmpersandIfNotFirst\n)\n\nfunc analyzeLeadingAmpersand(sel css_ast.ComplexSelector, isDeclarationContext bool) leadingAmpersand {\n\tif len(sel.Selectors) > 1 {\n\t\tif first := sel.Selectors[0]; first.IsSingleAmpersand() {\n\t\t\tif second := sel.Selectors[1]; second.Combinator.Byte == 0 && len(second.NestingSelectorLocs) > 0 {\n\t\t\t\t// \".foo { & &.bar {} }\" => \".foo { & &.bar {} }\"\n\t\t\t} else if second.Combinator.Byte != 0 || second.TypeSelector == nil || !isDeclarationContext {\n\t\t\t\t// \"& + div {}\" => \"+ div {}\"\n\t\t\t\t// \"& div {}\" => \"div {}\"\n\t\t\t\t// \".foo { & + div {} }\" => \".foo { + div {} }\"\n\t\t\t\t// \".foo { & + &.bar {} }\" => \".foo { + &.bar {} }\"\n\t\t\t\t// \".foo { & :hover {} }\" => \".foo { :hover {} }\"\n\t\t\t\treturn canAlwaysRemoveLeadingAmpersand\n\t\t\t} else {\n\t\t\t\t// \".foo { & div {} }\"\n\t\t\t\t// \".foo { .bar, & div {} }\" => \".foo { .bar, div {} }\"\n\t\t\t\treturn canRemoveLeadingAmpersandIfNotFirst\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// \"& {}\" => \"& {}\"\n\t}\n\treturn cannotRemoveLeadingAmpersand\n}\n\ntype parseComplexSelectorOpts struct {\n\tparseSelectorOpts\n\tisFirst bool\n}\n\nfunc (p *parser) parseComplexSelector(opts parseComplexSelectorOpts) (result css_ast.ComplexSelector, ok bool) {\n\t// This is an extension: https://drafts.csswg.org/css-nesting-1/\n\tvar combinator css_ast.Combinator\n\tif !opts.noLeadingCombinator {\n\t\tcombinator = p.parseCombinator()\n\t\tif combinator.Byte != 0 {\n\t\t\tp.nestingIsPresent = true\n\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t}\n\t}\n\n\t// Parent\n\tsel, good := p.parseCompoundSelector(parseComplexSelectorOpts{\n\t\tparseSelectorOpts: opts.parseSelectorOpts,\n\t\tisFirst:           opts.isFirst,\n\t})\n\tif !good {\n\t\treturn\n\t}\n\tsel.Combinator = combinator\n\tresult.Selectors = append(result.Selectors, sel)\n\n\tstop := css_lexer.TOpenBrace\n\tif opts.stopOnCloseParen {\n\t\tstop = css_lexer.TCloseParen\n\t}\n\tfor {\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tif p.peek(css_lexer.TEndOfFile) || p.peek(css_lexer.TComma) || p.peek(stop) {\n\t\t\tbreak\n\t\t}\n\n\t\t// Optional combinator\n\t\tcombinator := p.parseCombinator()\n\t\tif combinator.Byte != 0 {\n\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t}\n\n\t\t// Child\n\t\tsel, good := p.parseCompoundSelector(parseComplexSelectorOpts{\n\t\t\tparseSelectorOpts: opts.parseSelectorOpts,\n\t\t})\n\t\tif !good {\n\t\t\treturn\n\t\t}\n\t\tsel.Combinator = combinator\n\t\tresult.Selectors = append(result.Selectors, sel)\n\t}\n\n\tok = true\n\treturn\n}\n\nfunc (p *parser) nameToken() css_ast.NameToken {\n\tt := p.current()\n\treturn css_ast.NameToken{\n\t\tKind:  t.Kind,\n\t\tRange: t.Range,\n\t\tText:  p.decoded(),\n\t}\n}\n\nfunc (p *parser) parseCompoundSelector(opts parseComplexSelectorOpts) (sel css_ast.CompoundSelector, ok bool) {\n\tstartLoc := p.current().Range.Loc\n\n\t// This is an extension: https://drafts.csswg.org/css-nesting-1/\n\thasLeadingNestingSelector := p.peek(css_lexer.TDelimAmpersand)\n\tif hasLeadingNestingSelector {\n\t\tp.nestingIsPresent = true\n\t\tsel.NestingSelectorLocs = append(sel.NestingSelectorLocs, startLoc)\n\t\tp.advance()\n\t}\n\n\t// Parse the type selector\n\ttypeSelectorLoc := p.current().Range.Loc\n\tswitch p.current().Kind {\n\tcase css_lexer.TDelimBar, css_lexer.TIdent, css_lexer.TDelimAsterisk:\n\t\tnsName := css_ast.NamespacedName{}\n\t\tif !p.peek(css_lexer.TDelimBar) {\n\t\t\tnsName.Name = p.nameToken()\n\t\t\tp.advance()\n\t\t} else {\n\t\t\t// Hack: Create an empty \"identifier\" to represent this\n\t\t\tnsName.Name.Kind = css_lexer.TIdent\n\t\t}\n\t\tif p.eat(css_lexer.TDelimBar) {\n\t\t\tif !p.peek(css_lexer.TIdent) && !p.peek(css_lexer.TDelimAsterisk) {\n\t\t\t\tp.expect(css_lexer.TIdent)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tprefix := nsName.Name\n\t\t\tnsName.NamespacePrefix = &prefix\n\t\t\tnsName.Name = p.nameToken()\n\t\t\tp.advance()\n\t\t}\n\t\tsel.TypeSelector = &nsName\n\t}\n\n\t// Parse the subclass selectors\nsubclassSelectors:\n\tfor {\n\t\tsubclassToken := p.current()\n\n\t\tswitch subclassToken.Kind {\n\t\tcase css_lexer.THash:\n\t\t\tif (subclassToken.Flags & css_lexer.IsID) == 0 {\n\t\t\t\tbreak subclassSelectors\n\t\t\t}\n\t\t\tnameLoc := logger.Loc{Start: subclassToken.Range.Loc.Start + 1}\n\t\t\tname := p.decoded()\n\t\t\tsel.SubclassSelectors = append(sel.SubclassSelectors, css_ast.SubclassSelector{\n\t\t\t\tRange: subclassToken.Range,\n\t\t\t\tData: &css_ast.SSHash{\n\t\t\t\t\tName: p.symbolForName(nameLoc, name),\n\t\t\t\t},\n\t\t\t})\n\t\t\tp.advance()\n\n\t\tcase css_lexer.TDelimDot:\n\t\t\tp.advance()\n\t\t\tnameRange := p.current().Range\n\t\t\tname := p.decoded()\n\t\t\tsel.SubclassSelectors = append(sel.SubclassSelectors, css_ast.SubclassSelector{\n\t\t\t\tRange: logger.Range{Loc: subclassToken.Range.Loc, Len: nameRange.End() - subclassToken.Range.Loc.Start},\n\t\t\t\tData: &css_ast.SSClass{\n\t\t\t\t\tName: p.symbolForName(nameRange.Loc, name),\n\t\t\t\t},\n\t\t\t})\n\t\t\tif !p.expect(css_lexer.TIdent) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\tcase css_lexer.TOpenBracket:\n\t\t\tattr, r := p.parseAttributeSelector()\n\t\t\tif r.Len == 0 {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsel.SubclassSelectors = append(sel.SubclassSelectors, css_ast.SubclassSelector{\n\t\t\t\tRange: r,\n\t\t\t\tData:  &attr,\n\t\t\t})\n\n\t\tcase css_lexer.TColon:\n\t\t\tif p.next().Kind == css_lexer.TColon {\n\t\t\t\t// Special-case the start of the pseudo-element selector section\n\t\t\t\tfor p.peek(css_lexer.TColon) {\n\t\t\t\t\tfirstColonLoc := p.current().Range.Loc\n\t\t\t\t\tisElement := p.next().Kind == css_lexer.TColon\n\t\t\t\t\tif isElement {\n\t\t\t\t\t\tp.advance()\n\t\t\t\t\t}\n\t\t\t\t\tpseudo, r := p.parsePseudoClassSelector(firstColonLoc, isElement)\n\n\t\t\t\t\t// https://www.w3.org/TR/selectors-4/#single-colon-pseudos\n\t\t\t\t\t// The four Level 2 pseudo-elements (::before, ::after, ::first-line,\n\t\t\t\t\t// and ::first-letter) may, for legacy reasons, be represented using\n\t\t\t\t\t// the <pseudo-class-selector> grammar, with only a single \":\"\n\t\t\t\t\t// character at their start.\n\t\t\t\t\tif p.options.minifySyntax && isElement {\n\t\t\t\t\t\tif pseudo, ok := pseudo.(*css_ast.SSPseudoClass); ok && len(pseudo.Args) == 0 {\n\t\t\t\t\t\t\tswitch pseudo.Name {\n\t\t\t\t\t\t\tcase \"before\", \"after\", \"first-line\", \"first-letter\":\n\t\t\t\t\t\t\t\tpseudo.IsElement = false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tsel.SubclassSelectors = append(sel.SubclassSelectors, css_ast.SubclassSelector{\n\t\t\t\t\t\tRange: r,\n\t\t\t\t\t\tData:  pseudo,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tbreak subclassSelectors\n\t\t\t}\n\n\t\t\tpseudo, r := p.parsePseudoClassSelector(subclassToken.Range.Loc, false)\n\t\t\tsel.SubclassSelectors = append(sel.SubclassSelectors, css_ast.SubclassSelector{\n\t\t\t\tRange: r,\n\t\t\t\tData:  pseudo,\n\t\t\t})\n\n\t\tcase css_lexer.TDelimAmpersand:\n\t\t\t// This is an extension: https://drafts.csswg.org/css-nesting-1/\n\t\t\tp.nestingIsPresent = true\n\t\t\tsel.NestingSelectorLocs = append(sel.NestingSelectorLocs, subclassToken.Range.Loc)\n\t\t\tp.advance()\n\n\t\tdefault:\n\t\t\tbreak subclassSelectors\n\t\t}\n\t}\n\n\t// The compound selector must be non-empty\n\tif sel.IsInvalidBecauseEmpty() {\n\t\tp.unexpected()\n\t\treturn\n\t}\n\n\t// Note: \"&div {}\" was originally valid, but is now an invalid selector:\n\t// https://github.com/w3c/csswg-drafts/issues/8662#issuecomment-1514977935.\n\t// This is because SASS already uses that syntax to mean something very\n\t// different, so that syntax has been removed to avoid mistakes.\n\tif hasLeadingNestingSelector && sel.TypeSelector != nil {\n\t\tr := logger.Range{Loc: typeSelectorLoc, Len: p.at(p.index-1).Range.End() - typeSelectorLoc.Start}\n\t\ttext := sel.TypeSelector.Name.Text\n\t\tif sel.TypeSelector.NamespacePrefix != nil {\n\t\t\ttext = fmt.Sprintf(\"%s|%s\", sel.TypeSelector.NamespacePrefix.Text, text)\n\t\t}\n\t\tvar howToFix string\n\t\tsuggestion := p.source.TextForRange(r)\n\t\tif opts.isFirst {\n\t\t\tsuggestion = fmt.Sprintf(\":is(%s)\", suggestion)\n\t\t\thowToFix = \"You can wrap this selector in \\\":is(...)\\\" as a workaround. \"\n\t\t} else {\n\t\t\tr = logger.Range{Loc: startLoc, Len: r.End() - startLoc.Start}\n\t\t\tsuggestion += \"&\"\n\t\t\thowToFix = \"You can move the \\\"&\\\" to the end of this selector as a workaround. \"\n\t\t}\n\t\tmsg := logger.Msg{\n\t\t\tKind: logger.Warning,\n\t\t\tData: p.tracker.MsgData(r, fmt.Sprintf(\"Cannot use type selector %q directly after nesting selector \\\"&\\\"\", text)),\n\t\t\tNotes: []logger.MsgData{{Text: \"CSS nesting syntax does not allow the \\\"&\\\" selector to come before a type selector. \" +\n\t\t\t\thowToFix +\n\t\t\t\t\"This restriction exists to avoid problems with SASS nesting, where the same syntax means something very different \" +\n\t\t\t\t\"that has no equivalent in real CSS (appending a suffix to the parent selector).\"}},\n\t\t}\n\t\tmsg.Data.Location.Suggestion = suggestion\n\t\tp.log.AddMsgID(logger.MsgID_CSS_CSSSyntaxError, msg)\n\t\treturn\n\t}\n\n\t// The type selector must always come first\n\tswitch p.current().Kind {\n\tcase css_lexer.TDelimBar, css_lexer.TIdent, css_lexer.TDelimAsterisk:\n\t\tp.unexpected()\n\t\treturn\n\t}\n\n\tok = true\n\treturn\n}\n\nfunc (p *parser) parseAttributeSelector() (attr css_ast.SSAttribute, r logger.Range) {\n\tmatchingLoc := p.current().Range.Loc\n\tp.advance()\n\n\t// Parse the namespaced name\n\tswitch p.current().Kind {\n\tcase css_lexer.TDelimBar, css_lexer.TDelimAsterisk:\n\t\t// \"[|x]\"\n\t\t// \"[*|x]\"\n\t\tif p.peek(css_lexer.TDelimAsterisk) {\n\t\t\tprefix := p.nameToken()\n\t\t\tp.advance()\n\t\t\tattr.NamespacedName.NamespacePrefix = &prefix\n\t\t} else {\n\t\t\t// \"[|attr]\" is equivalent to \"[attr]\". From the specification:\n\t\t\t// \"In keeping with the Namespaces in the XML recommendation, default\n\t\t\t// namespaces do not apply to attributes, therefore attribute selectors\n\t\t\t// without a namespace component apply only to attributes that have no\n\t\t\t// namespace (equivalent to |attr).\"\n\t\t}\n\t\tif !p.expect(css_lexer.TDelimBar) {\n\t\t\treturn\n\t\t}\n\t\tattr.NamespacedName.Name = p.nameToken()\n\t\tif !p.expect(css_lexer.TIdent) {\n\t\t\treturn\n\t\t}\n\n\tdefault:\n\t\t// \"[x]\"\n\t\t// \"[x|y]\"\n\t\tattr.NamespacedName.Name = p.nameToken()\n\t\tif !p.expect(css_lexer.TIdent) {\n\t\t\treturn\n\t\t}\n\t\tif p.next().Kind != css_lexer.TDelimEquals && p.eat(css_lexer.TDelimBar) {\n\t\t\tprefix := attr.NamespacedName.Name\n\t\t\tattr.NamespacedName.NamespacePrefix = &prefix\n\t\t\tattr.NamespacedName.Name = p.nameToken()\n\t\t\tif !p.expect(css_lexer.TIdent) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Parse the optional matcher operator\n\tp.eat(css_lexer.TWhitespace)\n\tif p.eat(css_lexer.TDelimEquals) {\n\t\tattr.MatcherOp = \"=\"\n\t} else {\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.TDelimTilde:\n\t\t\tattr.MatcherOp = \"~=\"\n\t\tcase css_lexer.TDelimBar:\n\t\t\tattr.MatcherOp = \"|=\"\n\t\tcase css_lexer.TDelimCaret:\n\t\t\tattr.MatcherOp = \"^=\"\n\t\tcase css_lexer.TDelimDollar:\n\t\t\tattr.MatcherOp = \"$=\"\n\t\tcase css_lexer.TDelimAsterisk:\n\t\t\tattr.MatcherOp = \"*=\"\n\t\t}\n\t\tif attr.MatcherOp != \"\" {\n\t\t\tp.advance()\n\t\t\tif !p.expect(css_lexer.TDelimEquals) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Parse the optional matcher value\n\tif attr.MatcherOp != \"\" {\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tif !p.peek(css_lexer.TString) && !p.peek(css_lexer.TIdent) {\n\t\t\tp.unexpected()\n\t\t}\n\t\tattr.MatcherValue = p.decoded()\n\t\tp.advance()\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tif p.peek(css_lexer.TIdent) {\n\t\t\tif modifier := p.decoded(); len(modifier) == 1 {\n\t\t\t\tif c := modifier[0]; c == 'i' || c == 'I' || c == 's' || c == 'S' {\n\t\t\t\t\tattr.MatcherModifier = c\n\t\t\t\t\tp.advance()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tcloseRange := p.current().Range\n\tif !p.expectWithMatchingLoc(css_lexer.TCloseBracket, matchingLoc) {\n\t\tcloseRange.Len = 0\n\t}\n\tr = logger.Range{Loc: matchingLoc, Len: closeRange.End() - matchingLoc.Start}\n\treturn\n}\n\nfunc (p *parser) parsePseudoClassSelector(loc logger.Loc, isElement bool) (css_ast.SS, logger.Range) {\n\tp.advance()\n\n\tif p.peek(css_lexer.TFunction) {\n\t\ttext := p.decoded()\n\t\tmatchingLoc := logger.Loc{Start: p.current().Range.End() - 1}\n\t\tp.advance()\n\n\t\t// Potentially parse a pseudo-class with a selector list\n\t\tif !isElement {\n\t\t\tvar kind css_ast.PseudoClassKind\n\t\t\tlocal := p.makeLocalSymbols\n\t\t\tok := true\n\t\t\tswitch text {\n\t\t\tcase \"global\":\n\t\t\t\tkind = css_ast.PseudoClassGlobal\n\t\t\t\tif p.options.symbolMode != symbolModeDisabled {\n\t\t\t\t\tlocal = false\n\t\t\t\t}\n\t\t\tcase \"has\":\n\t\t\t\tkind = css_ast.PseudoClassHas\n\t\t\tcase \"is\":\n\t\t\t\tkind = css_ast.PseudoClassIs\n\t\t\tcase \"local\":\n\t\t\t\tkind = css_ast.PseudoClassLocal\n\t\t\t\tif p.options.symbolMode != symbolModeDisabled {\n\t\t\t\t\tlocal = true\n\t\t\t\t}\n\t\t\tcase \"not\":\n\t\t\t\tkind = css_ast.PseudoClassNot\n\t\t\tcase \"nth-child\":\n\t\t\t\tkind = css_ast.PseudoClassNthChild\n\t\t\tcase \"nth-last-child\":\n\t\t\t\tkind = css_ast.PseudoClassNthLastChild\n\t\t\tcase \"nth-of-type\":\n\t\t\t\tkind = css_ast.PseudoClassNthOfType\n\t\t\tcase \"nth-last-of-type\":\n\t\t\t\tkind = css_ast.PseudoClassNthLastOfType\n\t\t\tcase \"where\":\n\t\t\t\tkind = css_ast.PseudoClassWhere\n\t\t\tdefault:\n\t\t\t\tok = false\n\t\t\t}\n\t\t\tif ok {\n\t\t\t\told := p.index\n\t\t\t\tif kind.HasNthIndex() {\n\t\t\t\t\tp.eat(css_lexer.TWhitespace)\n\n\t\t\t\t\t// Parse the \"An+B\" syntax\n\t\t\t\t\tif index, ok := p.parseNthIndex(); ok {\n\t\t\t\t\t\tvar selectors []css_ast.ComplexSelector\n\n\t\t\t\t\t\t// Parse the optional \"of\" clause\n\t\t\t\t\t\tif (kind == css_ast.PseudoClassNthChild || kind == css_ast.PseudoClassNthLastChild) &&\n\t\t\t\t\t\t\tp.peek(css_lexer.TIdent) && strings.EqualFold(p.decoded(), \"of\") {\n\t\t\t\t\t\t\tp.advance()\n\t\t\t\t\t\t\tp.eat(css_lexer.TWhitespace)\n\n\t\t\t\t\t\t\t// Contain the effects of \":local\" and \":global\"\n\t\t\t\t\t\t\toldLocal := p.makeLocalSymbols\n\t\t\t\t\t\t\tselectors, ok = p.parseSelectorList(parseSelectorOpts{\n\t\t\t\t\t\t\t\tstopOnCloseParen:    true,\n\t\t\t\t\t\t\t\tnoLeadingCombinator: true,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tp.makeLocalSymbols = oldLocal\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// \"2n+0\" => \"2n\"\n\t\t\t\t\t\tif p.options.minifySyntax {\n\t\t\t\t\t\t\tindex.Minify()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Match the closing \")\"\n\t\t\t\t\t\tif ok {\n\t\t\t\t\t\t\tcloseRange := p.current().Range\n\t\t\t\t\t\t\tif !p.expectWithMatchingLoc(css_lexer.TCloseParen, matchingLoc) {\n\t\t\t\t\t\t\t\tcloseRange.Len = 0\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn &css_ast.SSPseudoClassWithSelectorList{Kind: kind, Selectors: selectors, Index: index},\n\t\t\t\t\t\t\t\tlogger.Range{Loc: loc, Len: closeRange.End() - loc.Start}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tp.eat(css_lexer.TWhitespace)\n\n\t\t\t\t\t// \":local\" forces local names and \":global\" forces global names\n\t\t\t\t\toldLocal := p.makeLocalSymbols\n\t\t\t\t\tp.makeLocalSymbols = local\n\t\t\t\t\tselectors, ok := p.parseSelectorList(parseSelectorOpts{\n\t\t\t\t\t\tpseudoClassKind:         kind,\n\t\t\t\t\t\tstopOnCloseParen:        true,\n\t\t\t\t\t\tonlyOneComplexSelector:  kind == css_ast.PseudoClassGlobal || kind == css_ast.PseudoClassLocal,\n\t\t\t\t\t\tisForgivingSelectorList: kind == css_ast.PseudoClassIs || kind == css_ast.PseudoClassWhere,\n\t\t\t\t\t})\n\t\t\t\t\tp.makeLocalSymbols = oldLocal\n\n\t\t\t\t\t// Match the closing \")\"\n\t\t\t\t\tif ok {\n\t\t\t\t\t\tcloseRange := p.current().Range\n\t\t\t\t\t\tif !p.expectWithMatchingLoc(css_lexer.TCloseParen, matchingLoc) {\n\t\t\t\t\t\t\tcloseRange.Len = 0\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn &css_ast.SSPseudoClassWithSelectorList{Kind: kind, Selectors: selectors},\n\t\t\t\t\t\t\tlogger.Range{Loc: loc, Len: closeRange.End() - loc.Start}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tp.index = old\n\t\t\t}\n\t\t}\n\n\t\targs := p.convertTokens(p.parseAnyValue())\n\t\tcloseRange := p.current().Range\n\t\tif !p.expectWithMatchingLoc(css_lexer.TCloseParen, matchingLoc) {\n\t\t\tcloseRange.Len = 0\n\t\t}\n\t\treturn &css_ast.SSPseudoClass{IsElement: isElement, Name: text, Args: args},\n\t\t\tlogger.Range{Loc: loc, Len: closeRange.End() - loc.Start}\n\t}\n\n\tnameRange := p.current().Range\n\tname := p.decoded()\n\tsel := css_ast.SSPseudoClass{IsElement: isElement}\n\tif p.expect(css_lexer.TIdent) {\n\t\tsel.Name = name\n\n\t\t// \":local .local_name :global .global_name {}\"\n\t\t// \":local { .local_name { :global { .global_name {} } }\"\n\t\tif p.options.symbolMode != symbolModeDisabled {\n\t\t\tswitch name {\n\t\t\tcase \"local\":\n\t\t\t\tp.makeLocalSymbols = true\n\t\t\tcase \"global\":\n\t\t\t\tp.makeLocalSymbols = false\n\t\t\t}\n\t\t}\n\t} else {\n\t\tnameRange.Len = 0\n\t}\n\treturn &sel, logger.Range{Loc: loc, Len: nameRange.End() - loc.Start}\n}\n\nfunc (p *parser) parseAnyValue() []css_lexer.Token {\n\t// Reference: https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value\n\n\tp.stack = p.stack[:0] // Reuse allocated memory\n\tstart := p.index\n\nloop:\n\tfor {\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.TCloseParen, css_lexer.TCloseBracket, css_lexer.TCloseBrace:\n\t\t\tlast := len(p.stack) - 1\n\t\t\tif last < 0 || !p.peek(p.stack[last]) {\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tp.stack = p.stack[:last]\n\n\t\tcase css_lexer.TSemicolon, css_lexer.TDelimExclamation:\n\t\t\tif len(p.stack) == 0 {\n\t\t\t\tbreak loop\n\t\t\t}\n\n\t\tcase css_lexer.TOpenParen, css_lexer.TFunction:\n\t\t\tp.stack = append(p.stack, css_lexer.TCloseParen)\n\n\t\tcase css_lexer.TOpenBracket:\n\t\t\tp.stack = append(p.stack, css_lexer.TCloseBracket)\n\n\t\tcase css_lexer.TOpenBrace:\n\t\t\tp.stack = append(p.stack, css_lexer.TCloseBrace)\n\n\t\tcase css_lexer.TEndOfFile:\n\t\t\tbreak loop\n\t\t}\n\n\t\tp.advance()\n\t}\n\n\ttokens := p.tokens[start:p.index]\n\tif len(tokens) == 0 {\n\t\tp.unexpected()\n\t}\n\treturn tokens\n}\n\nfunc (p *parser) parseCombinator() css_ast.Combinator {\n\tt := p.current()\n\n\tswitch t.Kind {\n\tcase css_lexer.TDelimGreaterThan:\n\t\tp.advance()\n\t\treturn css_ast.Combinator{Loc: t.Range.Loc, Byte: '>'}\n\n\tcase css_lexer.TDelimPlus:\n\t\tp.advance()\n\t\treturn css_ast.Combinator{Loc: t.Range.Loc, Byte: '+'}\n\n\tcase css_lexer.TDelimTilde:\n\t\tp.advance()\n\t\treturn css_ast.Combinator{Loc: t.Range.Loc, Byte: '~'}\n\n\tdefault:\n\t\treturn css_ast.Combinator{}\n\t}\n}\n\nfunc parseInteger(text string) (string, bool) {\n\tn := len(text)\n\tif n == 0 {\n\t\treturn \"\", false\n\t}\n\n\t// Trim leading zeros\n\tstart := 0\n\tfor start < n && text[start] == '0' {\n\t\tstart++\n\t}\n\n\t// Make sure remaining characters are digits\n\tif start == n {\n\t\treturn \"0\", true\n\t}\n\tfor i := start; i < n; i++ {\n\t\tif c := text[i]; c < '0' || c > '9' {\n\t\t\treturn \"\", false\n\t\t}\n\t}\n\treturn text[start:], true\n}\n\nfunc (p *parser) parseNthIndex() (css_ast.NthIndex, bool) {\n\ttype sign uint8\n\tconst (\n\t\tnone sign = iota\n\t\tnegative\n\t\tpositive\n\t)\n\n\t// Reference: https://drafts.csswg.org/css-syntax-3/#anb-microsyntax\n\tt0 := p.current()\n\ttext0 := p.decoded()\n\n\t// Handle \"even\" and \"odd\"\n\tif t0.Kind == css_lexer.TIdent && (text0 == \"even\" || text0 == \"odd\") {\n\t\tp.advance()\n\t\tp.eat(css_lexer.TWhitespace)\n\t\treturn css_ast.NthIndex{B: text0}, true\n\t}\n\n\t// Handle a single number\n\tif t0.Kind == css_lexer.TNumber {\n\t\tbNeg := false\n\t\tif strings.HasPrefix(text0, \"-\") {\n\t\t\tbNeg = true\n\t\t\ttext0 = text0[1:]\n\t\t} else {\n\t\t\ttext0 = strings.TrimPrefix(text0, \"+\")\n\t\t}\n\t\tif b, ok := parseInteger(text0); ok {\n\t\t\tif bNeg {\n\t\t\t\tb = \"-\" + b\n\t\t\t}\n\t\t\tp.advance()\n\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\treturn css_ast.NthIndex{B: b}, true\n\t\t}\n\t\tp.unexpected()\n\t\treturn css_ast.NthIndex{}, false\n\t}\n\n\taSign := none\n\tif p.eat(css_lexer.TDelimPlus) {\n\t\taSign = positive\n\t\tt0 = p.current()\n\t\ttext0 = p.decoded()\n\t}\n\n\t// Everything from here must be able to contain an \"n\"\n\tif t0.Kind != css_lexer.TIdent && t0.Kind != css_lexer.TDimension {\n\t\tp.unexpected()\n\t\treturn css_ast.NthIndex{}, false\n\t}\n\n\t// Check for a leading sign\n\tif aSign == none {\n\t\tif strings.HasPrefix(text0, \"-\") {\n\t\t\taSign = negative\n\t\t\ttext0 = text0[1:]\n\t\t} else {\n\t\t\ttext0 = strings.TrimPrefix(text0, \"+\")\n\t\t}\n\t}\n\n\t// The string must contain an \"n\"\n\tn := strings.IndexByte(text0, 'n')\n\tif n < 0 {\n\t\tp.unexpected()\n\t\treturn css_ast.NthIndex{}, false\n\t}\n\n\t// Parse the number before the \"n\"\n\tvar a string\n\tif n == 0 {\n\t\tif aSign == negative {\n\t\t\ta = \"-1\"\n\t\t} else {\n\t\t\ta = \"1\"\n\t\t}\n\t} else if aInt, ok := parseInteger(text0[:n]); ok {\n\t\tif aSign == negative {\n\t\t\taInt = \"-\" + aInt\n\t\t}\n\t\ta = aInt\n\t} else {\n\t\tp.unexpected()\n\t\treturn css_ast.NthIndex{}, false\n\t}\n\ttext0 = text0[n+1:]\n\n\t// Parse the stuff after the \"n\"\n\tbSign := none\n\tif strings.HasPrefix(text0, \"-\") {\n\t\ttext0 = text0[1:]\n\t\tif b, ok := parseInteger(text0); ok {\n\t\t\tp.advance()\n\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\treturn css_ast.NthIndex{A: a, B: \"-\" + b}, true\n\t\t}\n\t\tbSign = negative\n\t}\n\tif text0 != \"\" {\n\t\tp.unexpected()\n\t\treturn css_ast.NthIndex{}, false\n\t}\n\tp.advance()\n\tp.eat(css_lexer.TWhitespace)\n\n\t// Parse an optional sign delimiter\n\tif bSign == none {\n\t\tif p.eat(css_lexer.TDelimMinus) {\n\t\t\tbSign = negative\n\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t} else if p.eat(css_lexer.TDelimPlus) {\n\t\t\tbSign = positive\n\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t}\n\t}\n\n\t// Parse an optional trailing number\n\tt1 := p.current()\n\ttext1 := p.decoded()\n\tif t1.Kind == css_lexer.TNumber {\n\t\tif bSign == none {\n\t\t\tif strings.HasPrefix(text1, \"-\") {\n\t\t\t\tbSign = negative\n\t\t\t\ttext1 = text1[1:]\n\t\t\t} else if strings.HasPrefix(text1, \"+\") {\n\t\t\t\ttext1 = text1[1:]\n\t\t\t}\n\t\t}\n\t\tif b, ok := parseInteger(text1); ok {\n\t\t\tif bSign == negative {\n\t\t\t\tb = \"-\" + b\n\t\t\t}\n\t\t\tp.advance()\n\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\treturn css_ast.NthIndex{A: a, B: b}, true\n\t\t}\n\t}\n\n\t// If there is a trailing sign, then there must also be a trailing number\n\tif bSign != none {\n\t\tp.expect(css_lexer.TNumber)\n\t\treturn css_ast.NthIndex{}, false\n\t}\n\n\treturn css_ast.NthIndex{A: a}, true\n}\n"
  },
  {
    "path": "internal/css_parser/css_parser_test.go",
    "content": "package css_parser\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/css_printer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/test\"\n)\n\nfunc expectPrintedCommon(t *testing.T, name string, contents string, expected string, expectedLog string, loader config.Loader, options config.Options) {\n\tt.Helper()\n\tt.Run(name, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\t\ttree := Parse(log, test.SourceForTest(contents), OptionsFromConfig(loader, &options))\n\t\tmsgs := log.Done()\n\t\tvar text strings.Builder\n\t\tfor _, msg := range msgs {\n\t\t\ttext.WriteString(msg.String(logger.OutputOptions{}, logger.TerminalInfo{}))\n\t\t}\n\t\ttest.AssertEqualWithDiff(t, text.String(), expectedLog)\n\t\tsymbols := ast.NewSymbolMap(1)\n\t\tsymbols.SymbolsForSource[0] = tree.Symbols\n\t\tresult := css_printer.Print(tree, symbols, css_printer.Options{\n\t\t\tMinifyWhitespace: options.MinifyWhitespace,\n\t\t})\n\t\ttest.AssertEqualWithDiff(t, string(result.CSS), expected)\n\t})\n}\n\nfunc expectPrinted(t *testing.T, contents string, expected string, expectedLog string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, contents, expected, expectedLog, config.LoaderCSS, config.Options{})\n}\n\nfunc expectPrintedLocal(t *testing.T, contents string, expected string, expectedLog string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [local]\", contents, expected, expectedLog, config.LoaderLocalCSS, config.Options{})\n}\n\nfunc expectPrintedLower(t *testing.T, contents string, expected string, expectedLog string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [lower]\", contents, expected, expectedLog, config.LoaderCSS, config.Options{\n\t\tUnsupportedCSSFeatures: ^compat.CSSFeature(0),\n\t})\n}\n\nfunc expectPrintedLowerUnsupported(t *testing.T, unsupportedCSSFeatures compat.CSSFeature, contents string, expected string, expectedLog string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [lower]\", contents, expected, expectedLog, config.LoaderCSS, config.Options{\n\t\tUnsupportedCSSFeatures: unsupportedCSSFeatures,\n\t})\n}\n\nfunc expectPrintedWithAllPrefixes(t *testing.T, contents string, expected string, expectedLog string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [prefixed]\", contents, expected, expectedLog, config.LoaderCSS, config.Options{\n\t\tCSSPrefixData: compat.CSSPrefixData(map[compat.Engine]compat.Semver{\n\t\t\tcompat.Chrome:  {Parts: []int{0}},\n\t\t\tcompat.Edge:    {Parts: []int{0}},\n\t\t\tcompat.Firefox: {Parts: []int{0}},\n\t\t\tcompat.IE:      {Parts: []int{0}},\n\t\t\tcompat.IOS:     {Parts: []int{0}},\n\t\t\tcompat.Opera:   {Parts: []int{0}},\n\t\t\tcompat.Safari:  {Parts: []int{0}},\n\t\t}),\n\t})\n}\n\nfunc expectPrintedMinify(t *testing.T, contents string, expected string, expectedLog string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [minify]\", contents, expected, expectedLog, config.LoaderCSS, config.Options{\n\t\tMinifyWhitespace: true,\n\t})\n}\n\nfunc expectPrintedMangle(t *testing.T, contents string, expected string, expectedLog string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [mangle]\", contents, expected, expectedLog, config.LoaderCSS, config.Options{\n\t\tMinifySyntax: true,\n\t})\n}\n\nfunc expectPrintedLowerMangle(t *testing.T, contents string, expected string, expectedLog string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [lower, mangle]\", contents, expected, expectedLog, config.LoaderCSS, config.Options{\n\t\tUnsupportedCSSFeatures: ^compat.CSSFeature(0),\n\t\tMinifySyntax:           true,\n\t})\n}\n\nfunc expectPrintedMangleMinify(t *testing.T, contents string, expected string, expectedLog string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [mangle, minify]\", contents, expected, expectedLog, config.LoaderCSS, config.Options{\n\t\tMinifySyntax:     true,\n\t\tMinifyWhitespace: true,\n\t})\n}\n\nfunc expectPrintedLowerMinify(t *testing.T, contents string, expected string, expectedLog string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [lower, minify]\", contents, expected, expectedLog, config.LoaderCSS, config.Options{\n\t\tUnsupportedCSSFeatures: ^compat.CSSFeature(0),\n\t\tMinifyWhitespace:       true,\n\t})\n}\n\nfunc TestSingleLineComment(t *testing.T) {\n\texpectPrinted(t, \"a, // a\\nb // b\\n{}\", \"a, // a b // b {\\n}\\n\",\n\t\t\"<stdin>: WARNING: Comments in CSS use \\\"/* ... */\\\" instead of \\\"//\\\"\\n\"+\n\t\t\t\"<stdin>: WARNING: Comments in CSS use \\\"/* ... */\\\" instead of \\\"//\\\"\\n\")\n\texpectPrinted(t, \"a, ///// a /////\\n{}\", \"a, ///// a ///// {\\n}\\n\",\n\t\t\"<stdin>: WARNING: Comments in CSS use \\\"/* ... */\\\" instead of \\\"//\\\"\\n\")\n}\n\nfunc TestEscapes(t *testing.T) {\n\t// TIdent\n\texpectPrinted(t, \"a { value: id\\\\65nt }\", \"a {\\n  value: ident;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: \\\\69 dent }\", \"a {\\n  value: ident;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: \\\\69dent }\", \"a {\\n  value: \\u69DEnt;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: \\\\2cx }\", \"a {\\n  value: \\\\,x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: \\\\,x }\", \"a {\\n  value: \\\\,x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: x\\\\2c }\", \"a {\\n  value: x\\\\,;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: x\\\\, }\", \"a {\\n  value: x\\\\,;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: x\\\\0 }\", \"a {\\n  value: x\\uFFFD;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: x\\\\1 }\", \"a {\\n  value: x\\\\\\x01;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: x\\x00 }\", \"a {\\n  value: x\\uFFFD;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: x\\x01 }\", \"a {\\n  value: x\\x01;\\n}\\n\", \"\")\n\n\t// THash\n\texpectPrinted(t, \"a { value: #0h\\\\61sh }\", \"a {\\n  value: #0hash;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: #\\\\30hash }\", \"a {\\n  value: #0hash;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: #\\\\2cx }\", \"a {\\n  value: #\\\\,x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: #\\\\,x }\", \"a {\\n  value: #\\\\,x;\\n}\\n\", \"\")\n\n\t// THashID\n\texpectPrinted(t, \"a { value: #h\\\\61sh }\", \"a {\\n  value: #hash;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: #\\\\68 ash }\", \"a {\\n  value: #hash;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: #\\\\68ash }\", \"a {\\n  value: #\\u068Ash;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: #x\\\\2c }\", \"a {\\n  value: #x\\\\,;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: #x\\\\, }\", \"a {\\n  value: #x\\\\,;\\n}\\n\", \"\")\n\n\t// TFunction\n\texpectPrinted(t, \"a { value: f\\\\6e() }\", \"a {\\n  value: fn();\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: \\\\66n() }\", \"a {\\n  value: fn();\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: \\\\2cx() }\", \"a {\\n  value: \\\\,x();\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: \\\\,x() }\", \"a {\\n  value: \\\\,x();\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: x\\\\2c() }\", \"a {\\n  value: x\\\\,();\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: x\\\\,() }\", \"a {\\n  value: x\\\\,();\\n}\\n\", \"\")\n\n\t// TString\n\texpectPrinted(t, \"a { value: 'a\\\\62 c' }\", \"a {\\n  value: \\\"abc\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 'a\\\\62c' }\", \"a {\\n  value: \\\"a\\u062C\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: '\\\\61 bc' }\", \"a {\\n  value: \\\"abc\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: '\\\\61bc' }\", \"a {\\n  value: \\\"\\u61BC\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: '\\\\2c' }\", \"a {\\n  value: \\\",\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: '\\\\,' }\", \"a {\\n  value: \\\",\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: '\\\\0' }\", \"a {\\n  value: \\\"\\uFFFD\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: '\\\\1' }\", \"a {\\n  value: \\\"\\x01\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: '\\x00' }\", \"a {\\n  value: \\\"\\uFFFD\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: '\\x01' }\", \"a {\\n  value: \\\"\\x01\\\";\\n}\\n\", \"\")\n\n\t// TURL\n\texpectPrinted(t, \"a { value: url(a\\\\62 c) }\", \"a {\\n  value: url(abc);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: url(a\\\\62c) }\", \"a {\\n  value: url(a\\u062C);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: url(\\\\61 bc) }\", \"a {\\n  value: url(abc);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: url(\\\\61bc) }\", \"a {\\n  value: url(\\u61BC);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: url(\\\\2c) }\", \"a {\\n  value: url(,);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: url(\\\\,) }\", \"a {\\n  value: url(,);\\n}\\n\", \"\")\n\n\t// TAtKeyword\n\texpectPrinted(t, \"a { value: @k\\\\65yword }\", \"a {\\n  value: @keyword;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: @\\\\6b eyword }\", \"a {\\n  value: @keyword;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: @\\\\6beyword }\", \"a {\\n  value: @\\u06BEyword;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: @\\\\2cx }\", \"a {\\n  value: @\\\\,x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: @\\\\,x }\", \"a {\\n  value: @\\\\,x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: @x\\\\2c }\", \"a {\\n  value: @x\\\\,;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: @x\\\\, }\", \"a {\\n  value: @x\\\\,;\\n}\\n\", \"\")\n\n\t// TDimension\n\texpectPrinted(t, \"a { value: 10\\\\65m }\", \"a {\\n  value: 10em;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10p\\\\32x }\", \"a {\\n  value: 10p2x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10e\\\\32x }\", \"a {\\n  value: 10\\\\65 2x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10e-\\\\32x }\", \"a {\\n  value: 10\\\\65-2x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10E\\\\32x }\", \"a {\\n  value: 10\\\\45 2x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10E-\\\\32x }\", \"a {\\n  value: 10\\\\45-2x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10e1e\\\\32x }\", \"a {\\n  value: 10e1e2x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10e1e-\\\\32x }\", \"a {\\n  value: 10e1e-2x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10e1E\\\\32x }\", \"a {\\n  value: 10e1E2x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10e1E-\\\\32x }\", \"a {\\n  value: 10e1E-2x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10E1e\\\\32x }\", \"a {\\n  value: 10E1e2x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10E1e-\\\\32x }\", \"a {\\n  value: 10E1e-2x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10E1E\\\\32x }\", \"a {\\n  value: 10E1E2x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10E1E-\\\\32x }\", \"a {\\n  value: 10E1E-2x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10\\\\32x }\", \"a {\\n  value: 10\\\\32x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10\\\\2cx }\", \"a {\\n  value: 10\\\\,x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10\\\\,x }\", \"a {\\n  value: 10\\\\,x;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10x\\\\2c }\", \"a {\\n  value: 10x\\\\,;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { value: 10x\\\\, }\", \"a {\\n  value: 10x\\\\,;\\n}\\n\", \"\")\n\n\t// This must remain unescaped. See https://github.com/evanw/esbuild/issues/2677\n\texpectPrinted(t, \"@font-face { unicode-range: U+0e2e-0e2f }\", \"@font-face {\\n  unicode-range: U+0e2e-0e2f;\\n}\\n\", \"\")\n\n\t// RDeclaration\n\tcolorWarning := \"<stdin>: WARNING: \\\",olor\\\" is not a known CSS property\\nNOTE: Did you mean \\\"color\\\" instead?\\n\"\n\texpectPrintedMangle(t, \"a { c\\\\6flor: #f00 }\", \"a {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { \\\\63olor: #f00 }\", \"a {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { \\\\2color: #f00 }\", \"a {\\n  \\\\,olor: #f00;\\n}\\n\", colorWarning)\n\texpectPrintedMangle(t, \"a { \\\\,olor: #f00 }\", \"a {\\n  \\\\,olor: #f00;\\n}\\n\", colorWarning)\n\n\t// RUnknownAt\n\texpectPrinted(t, \"@unknown;\", \"@unknown;\\n\", \"\")\n\texpectPrinted(t, \"@u\\\\6eknown;\", \"@unknown;\\n\", \"\")\n\texpectPrinted(t, \"@\\\\75nknown;\", \"@unknown;\\n\", \"\")\n\texpectPrinted(t, \"@u\\\\2cnknown;\", \"@u\\\\,nknown;\\n\", \"\")\n\texpectPrinted(t, \"@u\\\\,nknown;\", \"@u\\\\,nknown;\\n\", \"\")\n\texpectPrinted(t, \"@\\\\2cunknown;\", \"@\\\\,unknown;\\n\", \"\")\n\texpectPrinted(t, \"@\\\\,unknown;\", \"@\\\\,unknown;\\n\", \"\")\n\n\t// RAtKeyframes\n\texpectPrinted(t, \"@k\\\\65yframes abc { from {} }\", \"@keyframes abc {\\n  from {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes \\\\61 bc { from {} }\", \"@keyframes abc {\\n  from {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes a\\\\62 c { from {} }\", \"@keyframes abc {\\n  from {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes abc { \\\\66rom {} }\", \"@keyframes abc {\\n  from {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes a\\\\2c c { \\\\66rom {} }\", \"@keyframes a\\\\,c {\\n  from {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes a\\\\,c { \\\\66rom {} }\", \"@keyframes a\\\\,c {\\n  from {\\n  }\\n}\\n\", \"\")\n\n\t// RAtNamespace\n\tnamespaceWarning := \"<stdin>: WARNING: \\\"@namespace\\\" rules are not supported\\n\"\n\texpectPrinted(t, \"@n\\\\61mespace ns 'path';\", \"@namespace ns \\\"path\\\";\\n\", namespaceWarning)\n\texpectPrinted(t, \"@namespace \\\\6es 'path';\", \"@namespace ns \\\"path\\\";\\n\", namespaceWarning)\n\texpectPrinted(t, \"@namespace ns 'p\\\\61th';\", \"@namespace ns \\\"path\\\";\\n\", namespaceWarning)\n\texpectPrinted(t, \"@namespace \\\\2cs 'p\\\\61th';\", \"@namespace \\\\,s \\\"path\\\";\\n\", namespaceWarning)\n\texpectPrinted(t, \"@namespace \\\\,s 'p\\\\61th';\", \"@namespace \\\\,s \\\"path\\\";\\n\", namespaceWarning)\n\n\t// CompoundSelector\n\texpectPrinted(t, \"* {}\", \"* {\\n}\\n\", \"\")\n\texpectPrinted(t, \"*|div {}\", \"*|div {\\n}\\n\", \"\")\n\texpectPrinted(t, \"\\\\2a {}\", \"\\\\* {\\n}\\n\", \"\")\n\texpectPrinted(t, \"\\\\2a|div {}\", \"\\\\*|div {\\n}\\n\", \"\")\n\texpectPrinted(t, \"\\\\2d {}\", \"\\\\- {\\n}\\n\", \"\")\n\texpectPrinted(t, \"\\\\2d- {}\", \"-- {\\n}\\n\", \"\")\n\texpectPrinted(t, \"-\\\\2d {}\", \"-- {\\n}\\n\", \"\")\n\texpectPrinted(t, \"\\\\2d 123 {}\", \"\\\\-123 {\\n}\\n\", \"\")\n\n\t// SSHash\n\texpectPrinted(t, \"#h\\\\61sh {}\", \"#hash {\\n}\\n\", \"\")\n\texpectPrinted(t, \"#\\\\2chash {}\", \"#\\\\,hash {\\n}\\n\", \"\")\n\texpectPrinted(t, \"#\\\\,hash {}\", \"#\\\\,hash {\\n}\\n\", \"\")\n\texpectPrinted(t, \"#\\\\2d {}\", \"#\\\\- {\\n}\\n\", \"\")\n\texpectPrinted(t, \"#\\\\2d- {}\", \"#-- {\\n}\\n\", \"\")\n\texpectPrinted(t, \"#-\\\\2d {}\", \"#-- {\\n}\\n\", \"\")\n\texpectPrinted(t, \"#\\\\2d 123 {}\", \"#\\\\-123 {\\n}\\n\", \"\")\n\texpectPrinted(t, \"#\\\\61hash {}\", \"#ahash {\\n}\\n\", \"\")\n\texpectPrinted(t, \"#\\\\30hash {}\", \"#\\\\30hash {\\n}\\n\", \"\")\n\texpectPrinted(t, \"#0\\\\2chash {}\", \"#0\\\\,hash {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"#0\\\\\\\\2chash\\\"\\n\")\n\texpectPrinted(t, \"#0\\\\,hash {}\", \"#0\\\\,hash {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"#0\\\\\\\\,hash\\\"\\n\")\n\n\t// SSClass\n\texpectPrinted(t, \".cl\\\\61ss {}\", \".class {\\n}\\n\", \"\")\n\texpectPrinted(t, \".\\\\2c class {}\", \".\\\\,class {\\n}\\n\", \"\")\n\texpectPrinted(t, \".\\\\,class {}\", \".\\\\,class {\\n}\\n\", \"\")\n\n\t// SSPseudoClass\n\texpectPrinted(t, \":pseudocl\\\\61ss {}\", \":pseudoclass {\\n}\\n\", \"\")\n\texpectPrinted(t, \":pseudo\\\\2c class {}\", \":pseudo\\\\,class {\\n}\\n\", \"\")\n\texpectPrinted(t, \":pseudo\\\\,class {}\", \":pseudo\\\\,class {\\n}\\n\", \"\")\n\texpectPrinted(t, \":pseudo(cl\\\\61ss) {}\", \":pseudo(class) {\\n}\\n\", \"\")\n\texpectPrinted(t, \":pseudo(cl\\\\2css) {}\", \":pseudo(cl\\\\,ss) {\\n}\\n\", \"\")\n\texpectPrinted(t, \":pseudo(cl\\\\,ss) {}\", \":pseudo(cl\\\\,ss) {\\n}\\n\", \"\")\n\n\t// SSAttribute\n\texpectPrinted(t, \"[\\\\61ttr] {}\", \"[attr] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[\\\\2c attr] {}\", \"[\\\\,attr] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[\\\\,attr] {}\", \"[\\\\,attr] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[attr\\\\7e=x] {}\", \"[attr\\\\~=x] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[attr\\\\~=x] {}\", \"[attr\\\\~=x] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[attr=\\\\2c] {}\", \"[attr=\\\",\\\"] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[attr=\\\\,] {}\", \"[attr=\\\",\\\"] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[attr=\\\"-\\\"] {}\", \"[attr=\\\"-\\\"] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[attr=\\\"--\\\"] {}\", \"[attr=--] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[attr=\\\"-a\\\"] {}\", \"[attr=-a] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[\\\\6es|attr] {}\", \"[ns|attr] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[ns|\\\\61ttr] {}\", \"[ns|attr] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[\\\\2cns|attr] {}\", \"[\\\\,ns|attr] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[ns|\\\\2c attr] {}\", \"[ns|\\\\,attr] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[*|attr] {}\", \"[*|attr] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[\\\\2a|attr] {}\", \"[\\\\*|attr] {\\n}\\n\", \"\")\n}\n\nfunc TestString(t *testing.T) {\n\texpectPrinted(t, \"a:after { content: 'a\\\\\\rb' }\", \"a:after {\\n  content: \\\"ab\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"a:after { content: 'a\\\\\\nb' }\", \"a:after {\\n  content: \\\"ab\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"a:after { content: 'a\\\\\\fb' }\", \"a:after {\\n  content: \\\"ab\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"a:after { content: 'a\\\\\\r\\nb' }\", \"a:after {\\n  content: \\\"ab\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"a:after { content: 'a\\\\62 c' }\", \"a:after {\\n  content: \\\"abc\\\";\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a:after { content: '\\r' }\", \"a:after {\\n  content: '\\n  ' }\\n  ;\\n}\\n\",\n\t\t`<stdin>: WARNING: Unterminated string token\n<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n<stdin>: WARNING: Unterminated string token\n`)\n\texpectPrinted(t, \"a:after { content: '\\n' }\", \"a:after {\\n  content: '\\n  ' }\\n  ;\\n}\\n\",\n\t\t`<stdin>: WARNING: Unterminated string token\n<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n<stdin>: WARNING: Unterminated string token\n`)\n\texpectPrinted(t, \"a:after { content: '\\f' }\", \"a:after {\\n  content: '\\n  ' }\\n  ;\\n}\\n\",\n\t\t`<stdin>: WARNING: Unterminated string token\n<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n<stdin>: WARNING: Unterminated string token\n`)\n\texpectPrinted(t, \"a:after { content: '\\r\\n' }\", \"a:after {\\n  content: '\\n  ' }\\n  ;\\n}\\n\",\n\t\t`<stdin>: WARNING: Unterminated string token\n<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n<stdin>: WARNING: Unterminated string token\n`)\n\n\texpectPrinted(t, \"a:after { content: '\\\\1010101' }\", \"a:after {\\n  content: \\\"\\U001010101\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"a:after { content: '\\\\invalid' }\", \"a:after {\\n  content: \\\"invalid\\\";\\n}\\n\", \"\")\n}\n\nfunc TestNumber(t *testing.T) {\n\tfor _, ext := range []string{\"\", \"%\", \"px+\"} {\n\t\texpectPrinted(t, \"a { width: .0\"+ext+\"; }\", \"a {\\n  width: .0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { width: .00\"+ext+\"; }\", \"a {\\n  width: .00\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { width: .10\"+ext+\"; }\", \"a {\\n  width: .10\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { width: 0.\"+ext+\"; }\", \"a {\\n  width: 0.\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { width: 0.0\"+ext+\"; }\", \"a {\\n  width: 0.0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { width: 0.1\"+ext+\"; }\", \"a {\\n  width: 0.1\"+ext+\";\\n}\\n\", \"\")\n\n\t\texpectPrinted(t, \"a { width: +.0\"+ext+\"; }\", \"a {\\n  width: +.0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { width: +.00\"+ext+\"; }\", \"a {\\n  width: +.00\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { width: +.10\"+ext+\"; }\", \"a {\\n  width: +.10\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { width: +0.\"+ext+\"; }\", \"a {\\n  width: +0.\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { width: +0.0\"+ext+\"; }\", \"a {\\n  width: +0.0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { width: +0.1\"+ext+\"; }\", \"a {\\n  width: +0.1\"+ext+\";\\n}\\n\", \"\")\n\n\t\texpectPrinted(t, \"a { width: -.0\"+ext+\"; }\", \"a {\\n  width: -.0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { width: -.00\"+ext+\"; }\", \"a {\\n  width: -.00\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { width: -.10\"+ext+\"; }\", \"a {\\n  width: -.10\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { width: -0.\"+ext+\"; }\", \"a {\\n  width: -0.\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { width: -0.0\"+ext+\"; }\", \"a {\\n  width: -0.0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { width: -0.1\"+ext+\"; }\", \"a {\\n  width: -0.1\"+ext+\";\\n}\\n\", \"\")\n\n\t\texpectPrintedMangle(t, \"a { width: .0\"+ext+\"; }\", \"a {\\n  width: 0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { width: .00\"+ext+\"; }\", \"a {\\n  width: 0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { width: .10\"+ext+\"; }\", \"a {\\n  width: .1\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { width: 0.\"+ext+\"; }\", \"a {\\n  width: 0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { width: 0.0\"+ext+\"; }\", \"a {\\n  width: 0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { width: 0.1\"+ext+\"; }\", \"a {\\n  width: .1\"+ext+\";\\n}\\n\", \"\")\n\n\t\texpectPrintedMangle(t, \"a { width: +.0\"+ext+\"; }\", \"a {\\n  width: +0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { width: +.00\"+ext+\"; }\", \"a {\\n  width: +0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { width: +.10\"+ext+\"; }\", \"a {\\n  width: +.1\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { width: +0.\"+ext+\"; }\", \"a {\\n  width: +0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { width: +0.0\"+ext+\"; }\", \"a {\\n  width: +0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { width: +0.1\"+ext+\"; }\", \"a {\\n  width: +.1\"+ext+\";\\n}\\n\", \"\")\n\n\t\texpectPrintedMangle(t, \"a { width: -.0\"+ext+\"; }\", \"a {\\n  width: -0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { width: -.00\"+ext+\"; }\", \"a {\\n  width: -0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { width: -.10\"+ext+\"; }\", \"a {\\n  width: -.1\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { width: -0.\"+ext+\"; }\", \"a {\\n  width: -0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { width: -0.0\"+ext+\"; }\", \"a {\\n  width: -0\"+ext+\";\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { width: -0.1\"+ext+\"; }\", \"a {\\n  width: -.1\"+ext+\";\\n}\\n\", \"\")\n\t}\n}\n\nfunc TestURL(t *testing.T) {\n\texpectPrinted(t, \"a { background: url(foo.png) }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url('foo.png') }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url(\\\"foo.png\\\") }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url(\\\"foo.png\\\" ) }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url(\\\"foo.png\\\"\\t) }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url(\\\"foo.png\\\"\\r) }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url(\\\"foo.png\\\"\\n) }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url(\\\"foo.png\\\"\\f) }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url(\\\"foo.png\\\"\\r\\n) }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url( \\\"foo.png\\\") }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url(\\t\\\"foo.png\\\") }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url(\\r\\\"foo.png\\\") }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url(\\n\\\"foo.png\\\") }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url(\\f\\\"foo.png\\\") }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url(\\r\\n\\\"foo.png\\\") }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url( \\\"foo.png\\\" ) }\", \"a {\\n  background: url(foo.png);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url(\\\"foo.png\\\" extra-stuff) }\", \"a {\\n  background: url(\\\"foo.png\\\" extra-stuff);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { background: url( \\\"foo.png\\\" extra-stuff ) }\", \"a {\\n  background: url(\\\"foo.png\\\" extra-stuff);\\n}\\n\", \"\")\n}\n\nfunc TestHexColor(t *testing.T) {\n\t// \"#RGBA\"\n\n\texpectPrinted(t, \"a { color: #1234 }\", \"a {\\n  color: #1234;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #123f }\", \"a {\\n  color: #123f;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #abcd }\", \"a {\\n  color: #abcd;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #abcf }\", \"a {\\n  color: #abcf;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #ABCD }\", \"a {\\n  color: #ABCD;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #ABCF }\", \"a {\\n  color: #ABCF;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { color: #1234 }\", \"a {\\n  color: #1234;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #123f }\", \"a {\\n  color: #123;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #abcd }\", \"a {\\n  color: #abcd;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #abcf }\", \"a {\\n  color: #abc;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #ABCD }\", \"a {\\n  color: #abcd;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #ABCF }\", \"a {\\n  color: #abc;\\n}\\n\", \"\")\n\n\t// \"#RRGGBB\"\n\n\texpectPrinted(t, \"a { color: #112233 }\", \"a {\\n  color: #112233;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #122233 }\", \"a {\\n  color: #122233;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #112333 }\", \"a {\\n  color: #112333;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #112234 }\", \"a {\\n  color: #112234;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { color: #112233 }\", \"a {\\n  color: #123;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #122233 }\", \"a {\\n  color: #122233;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #112333 }\", \"a {\\n  color: #112333;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #112234 }\", \"a {\\n  color: #112234;\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a { color: #aabbcc }\", \"a {\\n  color: #aabbcc;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #abbbcc }\", \"a {\\n  color: #abbbcc;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #aabccc }\", \"a {\\n  color: #aabccc;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #aabbcd }\", \"a {\\n  color: #aabbcd;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { color: #aabbcc }\", \"a {\\n  color: #abc;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #abbbcc }\", \"a {\\n  color: #abbbcc;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #aabccc }\", \"a {\\n  color: #aabccc;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #aabbcd }\", \"a {\\n  color: #aabbcd;\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a { color: #AABBCC }\", \"a {\\n  color: #AABBCC;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #ABBBCC }\", \"a {\\n  color: #ABBBCC;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #AABCCC }\", \"a {\\n  color: #AABCCC;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #AABBCD }\", \"a {\\n  color: #AABBCD;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { color: #AABBCC }\", \"a {\\n  color: #abc;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #ABBBCC }\", \"a {\\n  color: #abbbcc;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #AABCCC }\", \"a {\\n  color: #aabccc;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #AABBCD }\", \"a {\\n  color: #aabbcd;\\n}\\n\", \"\")\n\n\t// \"#RRGGBBAA\"\n\n\texpectPrinted(t, \"a { color: #11223344 }\", \"a {\\n  color: #11223344;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #12223344 }\", \"a {\\n  color: #12223344;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #11233344 }\", \"a {\\n  color: #11233344;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #11223444 }\", \"a {\\n  color: #11223444;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #11223345 }\", \"a {\\n  color: #11223345;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { color: #11223344 }\", \"a {\\n  color: #1234;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #12223344 }\", \"a {\\n  color: #12223344;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #11233344 }\", \"a {\\n  color: #11233344;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #11223444 }\", \"a {\\n  color: #11223444;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #11223345 }\", \"a {\\n  color: #11223345;\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a { color: #aabbccdd }\", \"a {\\n  color: #aabbccdd;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #abbbccdd }\", \"a {\\n  color: #abbbccdd;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #aabcccdd }\", \"a {\\n  color: #aabcccdd;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #aabbcddd }\", \"a {\\n  color: #aabbcddd;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #aabbccde }\", \"a {\\n  color: #aabbccde;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { color: #aabbccdd }\", \"a {\\n  color: #abcd;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #abbbccdd }\", \"a {\\n  color: #abbbccdd;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #aabcccdd }\", \"a {\\n  color: #aabcccdd;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #aabbcddd }\", \"a {\\n  color: #aabbcddd;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #aabbccde }\", \"a {\\n  color: #aabbccde;\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a { color: #AABBCCDD }\", \"a {\\n  color: #AABBCCDD;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #ABBBCCDD }\", \"a {\\n  color: #ABBBCCDD;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #AABCCCDD }\", \"a {\\n  color: #AABCCCDD;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #AABBCDDD }\", \"a {\\n  color: #AABBCDDD;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #AABBCCDE }\", \"a {\\n  color: #AABBCCDE;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { color: #AABBCCDD }\", \"a {\\n  color: #abcd;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #ABBBCCDD }\", \"a {\\n  color: #abbbccdd;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #AABCCCDD }\", \"a {\\n  color: #aabcccdd;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #AABBCDDD }\", \"a {\\n  color: #aabbcddd;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #AABBCCDE }\", \"a {\\n  color: #aabbccde;\\n}\\n\", \"\")\n\n\t// \"#RRGGBBFF\"\n\n\texpectPrinted(t, \"a { color: #112233ff }\", \"a {\\n  color: #112233ff;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #122233ff }\", \"a {\\n  color: #122233ff;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #112333ff }\", \"a {\\n  color: #112333ff;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #112234ff }\", \"a {\\n  color: #112234ff;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #112233ef }\", \"a {\\n  color: #112233ef;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { color: #112233ff }\", \"a {\\n  color: #123;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #122233ff }\", \"a {\\n  color: #122233;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #112333ff }\", \"a {\\n  color: #112333;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #112234ff }\", \"a {\\n  color: #112234;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #112233ef }\", \"a {\\n  color: #112233ef;\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a { color: #aabbccff }\", \"a {\\n  color: #aabbccff;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #abbbccff }\", \"a {\\n  color: #abbbccff;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #aabcccff }\", \"a {\\n  color: #aabcccff;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #aabbcdff }\", \"a {\\n  color: #aabbcdff;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #aabbccef }\", \"a {\\n  color: #aabbccef;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { color: #aabbccff }\", \"a {\\n  color: #abc;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #abbbccff }\", \"a {\\n  color: #abbbcc;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #aabcccff }\", \"a {\\n  color: #aabccc;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #aabbcdff }\", \"a {\\n  color: #aabbcd;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #aabbccef }\", \"a {\\n  color: #aabbccef;\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a { color: #AABBCCFF }\", \"a {\\n  color: #AABBCCFF;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #ABBBCCFF }\", \"a {\\n  color: #ABBBCCFF;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #AABCCCFF }\", \"a {\\n  color: #AABCCCFF;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #AABBCDFF }\", \"a {\\n  color: #AABBCDFF;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #AABBCCEF }\", \"a {\\n  color: #AABBCCEF;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { color: #AABBCCFF }\", \"a {\\n  color: #abc;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #ABBBCCFF }\", \"a {\\n  color: #abbbcc;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #AABCCCFF }\", \"a {\\n  color: #aabccc;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #AABBCDFF }\", \"a {\\n  color: #aabbcd;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #AABBCCEF }\", \"a {\\n  color: #aabbccef;\\n}\\n\", \"\")\n}\n\nfunc TestColorFunctions(t *testing.T) {\n\texpectPrinted(t, \"a { color: color(display-p3 0.5 0.0 0.0%) }\", \"a {\\n  color: color(display-p3 0.5 0.0 0.0%);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: color(display-p3 0.5 0.0 0.0% / 0.5) }\", \"a {\\n  color: color(display-p3 0.5 0.0 0.0% / 0.5);\\n}\\n\", \"\")\n\n\t// Check minification of tokens\n\texpectPrintedMangle(t, \"a { color: color(display-p3 0.5 0.0 0.0%) }\", \"a {\\n  color: color(display-p3 .5 0 0%);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: color(display-p3 0.5 0.0 0.0% / 0.5) }\", \"a {\\n  color: color(display-p3 .5 0 0% / .5);\\n}\\n\", \"\")\n\n\t// Check out-of-range colors\n\texpectPrintedLower(t, \"a { before: 0; color: color(display-p3 1 0 0); after: 1 }\",\n\t\t\"a {\\n  before: 0;\\n  color: #ff0f0e;\\n  color: color(display-p3 1 0 0);\\n  after: 1;\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"a { before: 0; color: color(display-p3 1 0 0); after: 1 }\",\n\t\t\"a {\\n  before: 0;\\n  color: #ff0f0e;\\n  color: color(display-p3 1 0 0);\\n  after: 1;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { before: 0; color: color(display-p3 1 0 0 / 0.5); after: 1 }\",\n\t\t\"a {\\n  before: 0;\\n  color: rgba(255, 15, 14, .5);\\n  color: color(display-p3 1 0 0 / 0.5);\\n  after: 1;\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"a { before: 0; color: color(display-p3 1 0 0 / 0.5); after: 1 }\",\n\t\t\"a {\\n  before: 0;\\n  color: rgba(255, 15, 14, .5);\\n  color: color(display-p3 1 0 0 / .5);\\n  after: 1;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { before: 0; background: color(display-p3 1 0 0); after: 1 }\",\n\t\t\"a {\\n  before: 0;\\n  background: #ff0f0e;\\n  background: color(display-p3 1 0 0);\\n  after: 1;\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"a { before: 0; background: color(display-p3 1 0 0); after: 1 }\",\n\t\t\"a {\\n  before: 0;\\n  background: #ff0f0e;\\n  background: color(display-p3 1 0 0);\\n  after: 1;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { before: 0; background: color(display-p3 1 0 0 / 0.5); after: 1 }\",\n\t\t\"a {\\n  before: 0;\\n  background: rgba(255, 15, 14, .5);\\n  background: color(display-p3 1 0 0 / 0.5);\\n  after: 1;\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"a { before: 0; background: color(display-p3 1 0 0 / 0.5); after: 1 }\",\n\t\t\"a {\\n  before: 0;\\n  background: rgba(255, 15, 14, .5);\\n  background: color(display-p3 1 0 0 / .5);\\n  after: 1;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { before: 0; box-shadow: 1px color(display-p3 1 0 0); after: 1 }\",\n\t\t\"a {\\n  before: 0;\\n  box-shadow: 1px #ff0f0e;\\n  box-shadow: 1px color(display-p3 1 0 0);\\n  after: 1;\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"a { before: 0; box-shadow: 1px color(display-p3 1 0 0); after: 1 }\",\n\t\t\"a {\\n  before: 0;\\n  box-shadow: 1px #ff0f0e;\\n  box-shadow: 1px color(display-p3 1 0 0);\\n  after: 1;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { before: 0; box-shadow: 1px color(display-p3 1 0 0 / 0.5); after: 1 }\",\n\t\t\"a {\\n  before: 0;\\n  box-shadow: 1px rgba(255, 15, 14, .5);\\n  box-shadow: 1px color(display-p3 1 0 0 / 0.5);\\n  after: 1;\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"a { before: 0; box-shadow: 1px color(display-p3 1 0 0 / 0.5); after: 1 }\",\n\t\t\"a {\\n  before: 0;\\n  box-shadow: 1px rgba(255, 15, 14, .5);\\n  box-shadow: 1px color(display-p3 1 0 0 / .5);\\n  after: 1;\\n}\\n\", \"\")\n\n\t// Don't insert a fallback after a previous instance of the same property\n\texpectPrintedLower(t, \"a { color: red; color: color(display-p3 1 0 0) }\",\n\t\t\"a {\\n  color: red;\\n  color: color(display-p3 1 0 0);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(display-p3 1 0 0); color: color(display-p3 0 1 0) }\",\n\t\t\"a {\\n  color: #ff0f0e;\\n  color: color(display-p3 1 0 0);\\n  color: color(display-p3 0 1 0);\\n}\\n\", \"\")\n\n\t// Check case sensitivity\n\texpectPrintedLower(t, \"a { color: color(srgb 0.87 0.98 0.807) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"A { Color: Color(Srgb 0.87 0.98 0.807) }\", \"A {\\n  Color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"A { COLOR: COLOR(SRGB 0.87 0.98 0.807) }\", \"A {\\n  COLOR: #deface;\\n}\\n\", \"\")\n\n\t// Check in-range colors in various color spaces\n\texpectPrintedLower(t, \"a { color: color(a98-rgb 0.9 0.98 0.81) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(a98-rgb 90% 98% 81%) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(display-p3 0.89 0.977 0.823) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(display-p3 89% 97.7% 82.3%) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(prophoto-rgb 0.877 0.959 0.793) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(prophoto-rgb 87.7% 95.9% 79.3%) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(rec2020 0.895 0.968 0.805) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(rec2020 89.5% 96.8% 80.5%) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(srgb 0.87 0.98 0.807) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(srgb 87% 98% 80.7%) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(srgb-linear 0.73 0.96 0.62) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(srgb-linear 73% 96% 62%) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(xyz 0.754 0.883 0.715) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(xyz 75.4% 88.3% 71.5%) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(xyz-d50 0.773 0.883 0.545) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(xyz-d50 77.3% 88.3% 54.5%) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(xyz-d65 0.754 0.883 0.715) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: color(xyz-d65 75.4% 88.3% 71.5%) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\n\t// Check color functions with unusual percent reference ranges\n\texpectPrintedLower(t, \"a { color: lab(95.38 -15 18) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: lab(95.38% -15 18) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: lab(95.38 -12% 18) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: lab(95.38% -15 14.4%) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: lch(95.38 23.57 130.22) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: lch(95.38% 23.57 130.22) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: lch(95.38 19% 130.22) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: lch(95.38 23.57 0.362turn) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: oklab(0.953 -0.045 0.046) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: oklab(95.3% -0.045 0.046) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: oklab(0.953 -11.2% 0.046) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: oklab(0.953 -0.045 11.5%) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: oklch(0.953 0.064 134) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: oklch(95.3% 0.064 134) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: oklch(0.953 16% 134) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: oklch(0.953 0.064 0.372turn) }\", \"a {\\n  color: #deface;\\n}\\n\", \"\")\n\n\t// Test alpha\n\texpectPrintedLower(t, \"a { color: color(srgb 0.87 0.98 0.807 / 0.5) }\", \"a {\\n  color: rgba(222, 250, 206, .5);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: lab(95.38 -15 18 / 0.5) }\", \"a {\\n  color: rgba(222, 250, 206, .5);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: lch(95.38 23.57 130.22 / 0.5) }\", \"a {\\n  color: rgba(222, 250, 206, .5);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: oklab(0.953 -0.045 0.046 / 0.5) }\", \"a {\\n  color: rgba(222, 250, 206, .5);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: oklch(0.953 0.064 134 / 0.5) }\", \"a {\\n  color: rgba(222, 250, 206, .5);\\n}\\n\", \"\")\n}\n\nfunc TestColorNames(t *testing.T) {\n\texpectPrinted(t, \"a { color: #f00 }\", \"a {\\n  color: #f00;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #f00f }\", \"a {\\n  color: #f00f;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #ff0000 }\", \"a {\\n  color: #ff0000;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: #ff0000ff }\", \"a {\\n  color: #ff0000ff;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { color: #f00 }\", \"a {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #f00e }\", \"a {\\n  color: #f00e;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #f00f }\", \"a {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #ff0000 }\", \"a {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #ff0000ef }\", \"a {\\n  color: #ff0000ef;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #ff0000ff }\", \"a {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #ffc0cb }\", \"a {\\n  color: pink;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #ffc0cbef }\", \"a {\\n  color: #ffc0cbef;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: #ffc0cbff }\", \"a {\\n  color: pink;\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a { color: white }\", \"a {\\n  color: white;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { color: tUrQuOiSe }\", \"a {\\n  color: tUrQuOiSe;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { color: white }\", \"a {\\n  color: #fff;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: tUrQuOiSe }\", \"a {\\n  color: #40e0d0;\\n}\\n\", \"\")\n}\n\nfunc TestColorRGBA(t *testing.T) {\n\texpectPrintedMangle(t, \"a { color: rgba(1 2 3 / 0.5) }\", \"a {\\n  color: #01020380;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: rgba(1 2 3 / 50%) }\", \"a {\\n  color: #0102037f;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: rgba(1, 2, 3, 0.5) }\", \"a {\\n  color: #01020380;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: rgba(1, 2, 3, 50%) }\", \"a {\\n  color: #0102037f;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: rgba(1% 2% 3% / 0.5) }\", \"a {\\n  color: #03050880;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: rgba(1% 2% 3% / 50%) }\", \"a {\\n  color: #0305087f;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: rgba(1%, 2%, 3%, 0.5) }\", \"a {\\n  color: #03050880;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: rgba(1%, 2%, 3%, 50%) }\", \"a {\\n  color: #0305087f;\\n}\\n\", \"\")\n\n\texpectPrintedLowerMangle(t, \"a { color: rgb(1, 2, 3, 0.4) }\", \"a {\\n  color: rgba(1, 2, 3, .4);\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"a { color: rgba(1, 2, 3, 40%) }\", \"a {\\n  color: rgba(1, 2, 3, .4);\\n}\\n\", \"\")\n\n\texpectPrintedLowerMangle(t, \"a { color: rgb(var(--x) var(--y) var(--z)) }\", \"a {\\n  color: rgb(var(--x) var(--y) var(--z));\\n}\\n\", \"\")\n}\n\nfunc TestColorHSLA(t *testing.T) {\n\texpectPrintedMangle(t, \".red { color: hsl(0, 100%, 50%) }\", \".red {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \".orange { color: hsl(30deg, 100%, 50%) }\", \".orange {\\n  color: #ff8000;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \".yellow { color: hsl(60 100% 50%) }\", \".yellow {\\n  color: #ff0;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \".green { color: hsl(120, 100%, 50%) }\", \".green {\\n  color: #0f0;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \".cyan { color: hsl(200grad, 100%, 50%) }\", \".cyan {\\n  color: #0ff;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \".blue { color: hsl(240, 100%, 50%) }\", \".blue {\\n  color: #00f;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \".purple { color: hsl(0.75turn 100% 50%) }\", \".purple {\\n  color: #7f00ff;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \".magenta { color: hsl(300, 100%, 50%) }\", \".magenta {\\n  color: #f0f;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { color: hsl(30 25% 50% / 50%) }\", \"a {\\n  color: #9f80607f;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: hsla(30 25% 50% / 50%) }\", \"a {\\n  color: #9f80607f;\\n}\\n\", \"\")\n\n\texpectPrintedLowerMangle(t, \"a { color: hsl(1, 2%, 3%, 0.4) }\", \"a {\\n  color: rgba(8, 8, 7, .4);\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"a { color: hsla(1, 2%, 3%, 40%) }\", \"a {\\n  color: rgba(8, 8, 7, .4);\\n}\\n\", \"\")\n\n\texpectPrintedLowerMangle(t, \"a { color: hsl(var(--x) var(--y) var(--z)) }\", \"a {\\n  color: hsl(var(--x) var(--y) var(--z));\\n}\\n\", \"\")\n}\n\nfunc TestLowerColor(t *testing.T) {\n\texpectPrintedLower(t, \"a { color: rebeccapurple }\", \"a {\\n  color: #663399;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: ReBeCcApUrPlE }\", \"a {\\n  color: #663399;\\n}\\n\", \"\")\n\n\texpectPrintedLower(t, \"a { color: #0123 }\", \"a {\\n  color: rgba(0, 17, 34, .2);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: #1230 }\", \"a {\\n  color: rgba(17, 34, 51, 0);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: #1234 }\", \"a {\\n  color: rgba(17, 34, 51, .267);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: #123f }\", \"a {\\n  color: #112233;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: #12345678 }\", \"a {\\n  color: rgba(18, 52, 86, .47);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: #ff00007f }\", \"a {\\n  color: rgba(255, 0, 0, .498);\\n}\\n\", \"\")\n\n\texpectPrintedLower(t, \"a { color: rgb(1 2 3) }\", \"a {\\n  color: rgb(1, 2, 3);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: hsl(1 2% 3%) }\", \"a {\\n  color: hsl(1, 2%, 3%);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: rgba(1% 2% 3%) }\", \"a {\\n  color: rgb(1%, 2%, 3%);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: hsla(1deg 2% 3%) }\", \"a {\\n  color: hsl(1, 2%, 3%);\\n}\\n\", \"\")\n\n\texpectPrintedLower(t, \"a { color: hsla(200grad 2% 3%) }\", \"a {\\n  color: hsl(180, 2%, 3%);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: hsla(6.28319rad 2% 3%) }\", \"a {\\n  color: hsl(360, 2%, 3%);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: hsla(0.5turn 2% 3%) }\", \"a {\\n  color: hsl(180, 2%, 3%);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: hsla(+200grad 2% 3%) }\", \"a {\\n  color: hsl(180, 2%, 3%);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: hsla(-200grad 2% 3%) }\", \"a {\\n  color: hsl(-180, 2%, 3%);\\n}\\n\", \"\")\n\n\texpectPrintedLower(t, \"a { color: rgb(1 2 3 / 4) }\", \"a {\\n  color: rgba(1, 2, 3, 4);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: RGB(1 2 3 / 4) }\", \"a {\\n  color: rgba(1, 2, 3, 4);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: rgba(1% 2% 3% / 4%) }\", \"a {\\n  color: rgba(1%, 2%, 3%, 0.04);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: RGBA(1% 2% 3% / 4%) }\", \"a {\\n  color: RGBA(1%, 2%, 3%, 0.04);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: hsl(1 2% 3% / 4) }\", \"a {\\n  color: hsla(1, 2%, 3%, 4);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: HSL(1 2% 3% / 4) }\", \"a {\\n  color: hsla(1, 2%, 3%, 4);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: hsla(1 2% 3% / 4%) }\", \"a {\\n  color: hsla(1, 2%, 3%, 0.04);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: HSLA(1 2% 3% / 4%) }\", \"a {\\n  color: HSLA(1, 2%, 3%, 0.04);\\n}\\n\", \"\")\n\n\texpectPrintedLower(t, \"a { color: rgb(1, 2, 3, 4) }\", \"a {\\n  color: rgba(1, 2, 3, 4);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: rgba(1%, 2%, 3%, 4%) }\", \"a {\\n  color: rgba(1%, 2%, 3%, 0.04);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: rgb(1%, 2%, 3%, 0.4%) }\", \"a {\\n  color: rgba(1%, 2%, 3%, 0.004);\\n}\\n\", \"\")\n\n\texpectPrintedLower(t, \"a { color: hsl(1, 2%, 3%, 4) }\", \"a {\\n  color: hsla(1, 2%, 3%, 4);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: hsla(1deg, 2%, 3%, 4%) }\", \"a {\\n  color: hsla(1, 2%, 3%, 0.04);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: hsl(1deg, 2%, 3%, 0.4%) }\", \"a {\\n  color: hsla(1, 2%, 3%, 0.004);\\n}\\n\", \"\")\n\n\texpectPrintedLower(t, \"a { color: hwb(90deg 20% 40%) }\", \"a {\\n  color: #669933;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: HWB(90deg 20% 40%) }\", \"a {\\n  color: #669933;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: hwb(90deg 20% 40% / 0.2) }\", \"a {\\n  color: rgba(102, 153, 51, .2);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: hwb(1deg 40% 80%) }\", \"a {\\n  color: #555555;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: hwb(1deg 9000% 50%) }\", \"a {\\n  color: #aaaaaa;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: hwb(1deg 9000% 50% / 0.6) }\", \"a {\\n  color: rgba(170, 170, 170, .6);\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { color: hwb(90deg, 20%, 40%) }\", \"a {\\n  color: hwb(90deg, 20%, 40%);\\n}\\n\", \"\") // This is invalid\n\texpectPrintedLower(t, \"a { color: hwb(none 20% 40%) }\", \"a {\\n  color: hwb(none 20% 40%);\\n}\\n\", \"\")       // Interpolation\n\texpectPrintedLower(t, \"a { color: hwb(90deg none 40%) }\", \"a {\\n  color: hwb(90deg none 40%);\\n}\\n\", \"\")   // Interpolation\n\texpectPrintedLower(t, \"a { color: hwb(90deg 20% none) }\", \"a {\\n  color: hwb(90deg 20% none);\\n}\\n\", \"\")   // Interpolation\n\n\texpectPrintedMangle(t, \"a { color: hwb(90deg 20% 40%) }\", \"a {\\n  color: #693;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: hwb(0.75turn 20% 40% / 0.75) }\", \"a {\\n  color: #663399bf;\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"a { color: hwb(90deg 20% 40%) }\", \"a {\\n  color: #693;\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"a { color: hwb(0.75turn 20% 40% / 0.75) }\", \"a {\\n  color: rgba(102, 51, 153, .75);\\n}\\n\", \"\")\n}\n\nfunc TestBackground(t *testing.T) {\n\texpectPrinted(t, \"a { background: #11223344 }\", \"a {\\n  background: #11223344;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { background: #11223344 }\", \"a {\\n  background: #1234;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { background: #11223344 }\", \"a {\\n  background: rgba(17, 34, 51, .267);\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a { background: border-box #11223344 }\", \"a {\\n  background: border-box #11223344;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { background: border-box #11223344 }\", \"a {\\n  background: border-box #1234;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { background: border-box #11223344 }\", \"a {\\n  background: border-box rgba(17, 34, 51, .267);\\n}\\n\", \"\")\n}\n\nfunc TestGradient(t *testing.T) {\n\tgradientKinds := []string{\n\t\t\"linear-gradient\",\n\t\t\"radial-gradient\",\n\t\t\"conic-gradient\",\n\t\t\"repeating-linear-gradient\",\n\t\t\"repeating-radial-gradient\",\n\t\t\"repeating-conic-gradient\",\n\t}\n\n\tfor _, gradient := range gradientKinds {\n\t\tvar code string\n\n\t\t// Different properties\n\t\texpectPrinted(t, \"a { background: \"+gradient+\"(red, blue) }\", \"a {\\n  background: \"+gradient+\"(red, blue);\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { background-image: \"+gradient+\"(red, blue) }\", \"a {\\n  background-image: \"+gradient+\"(red, blue);\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { border-image: \"+gradient+\"(red, blue) }\", \"a {\\n  border-image: \"+gradient+\"(red, blue);\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { mask-image: \"+gradient+\"(red, blue) }\", \"a {\\n  mask-image: \"+gradient+\"(red, blue);\\n}\\n\", \"\")\n\n\t\t// Basic\n\t\tcode = \"a { background: \" + gradient + \"(yellow, #11223344) }\"\n\t\texpectPrinted(t, code, \"a {\\n  background: \"+gradient+\"(yellow, #11223344);\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, code, \"a {\\n  background: \"+gradient+\"(#ff0, #1234);\\n}\\n\", \"\")\n\t\texpectPrintedMinify(t, code, \"a{background:\"+gradient+\"(yellow,#11223344)}\", \"\")\n\t\texpectPrintedLowerUnsupported(t, compat.HexRGBA, code,\n\t\t\t\"a {\\n  background: \"+gradient+\"(yellow, rgba(17, 34, 51, .267));\\n}\\n\", \"\")\n\n\t\t// Basic with positions\n\t\tcode = \"a { background: \" + gradient + \"(yellow 10%, #11223344 90%) }\"\n\t\texpectPrinted(t, code, \"a {\\n  background: \"+gradient+\"(yellow 10%, #11223344 90%);\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, code, \"a {\\n  background: \"+gradient+\"(#ff0 10%, #1234 90%);\\n}\\n\", \"\")\n\t\texpectPrintedMinify(t, code, \"a{background:\"+gradient+\"(yellow 10%,#11223344 90%)}\", \"\")\n\t\texpectPrintedLowerUnsupported(t, compat.HexRGBA, code,\n\t\t\t\"a {\\n  background: \"+gradient+\"(yellow 10%, rgba(17, 34, 51, .267) 90%);\\n}\\n\", \"\")\n\n\t\t// Basic with hints\n\t\tcode = \"a { background: \" + gradient + \"(yellow, 25%, #11223344) }\"\n\t\texpectPrinted(t, code, \"a {\\n  background:\\n    \"+gradient+\"(\\n      yellow,\\n      25%,\\n      #11223344);\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, code, \"a {\\n  background:\\n    \"+gradient+\"(\\n      #ff0,\\n      25%,\\n      #1234);\\n}\\n\", \"\")\n\t\texpectPrintedMinify(t, code, \"a{background:\"+gradient+\"(yellow,25%,#11223344)}\", \"\")\n\t\texpectPrintedLowerUnsupported(t, compat.HexRGBA, code,\n\t\t\t\"a {\\n  background:\\n    \"+gradient+\"(\\n      yellow,\\n      25%,\\n      rgba(17, 34, 51, .267));\\n}\\n\", \"\")\n\t\texpectPrintedLowerUnsupported(t, compat.GradientMidpoints, code,\n\t\t\t\"a {\\n  background:\\n    \"+gradient+\"(\\n      #ffff00,\\n      #f2f303de,\\n      #eced04d0 6.25%,\\n      \"+\n\t\t\t\t\"#e1e306bd 12.5%,\\n      #cdd00ba2 25%,\\n      #a2a8147b,\\n      #6873205d,\\n      #11223344);\\n}\\n\", \"\")\n\n\t\t// Double positions\n\t\tcode = \"a { background: \" + gradient + \"(green, red 10%, red 20%, yellow 70% 80%, black) }\"\n\t\texpectPrinted(t, code, \"a {\\n  background:\\n    \"+gradient+\"(\\n      green,\\n      red 10%,\\n      \"+\n\t\t\t\"red 20%,\\n      yellow 70% 80%,\\n      black);\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, code, \"a {\\n  background:\\n    \"+gradient+\"(\\n      green,\\n      \"+\n\t\t\t\"red 10% 20%,\\n      #ff0 70% 80%,\\n      #000);\\n}\\n\", \"\")\n\t\texpectPrintedMinify(t, code, \"a{background:\"+gradient+\"(green,red 10%,red 20%,yellow 70% 80%,black)}\", \"\")\n\t\texpectPrintedLowerUnsupported(t, compat.GradientDoublePosition, code,\n\t\t\t\"a {\\n  background:\\n    \"+gradient+\"(\\n      green,\\n      red 10%,\\n      red 20%,\\n      \"+\n\t\t\t\t\"yellow 70%,\\n      yellow 80%,\\n      black);\\n}\\n\", \"\")\n\n\t\t// Double positions with hints\n\t\tcode = \"a { background: \" + gradient + \"(green, red 10%, red 20%, 30%, yellow 70% 80%, 85%, black) }\"\n\t\texpectPrinted(t, code, \"a {\\n  background:\\n    \"+gradient+\"(\\n      green,\\n      red 10%,\\n      red 20%,\\n      \"+\n\t\t\t\"30%,\\n      yellow 70% 80%,\\n      85%,\\n      black);\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, code, \"a {\\n  background:\\n    \"+gradient+\"(\\n      green,\\n      red 10% 20%,\\n      \"+\n\t\t\t\"30%,\\n      #ff0 70% 80%,\\n      85%,\\n      #000);\\n}\\n\", \"\")\n\t\texpectPrintedMinify(t, code, \"a{background:\"+gradient+\"(green,red 10%,red 20%,30%,yellow 70% 80%,85%,black)}\", \"\")\n\t\texpectPrintedLowerUnsupported(t, compat.GradientDoublePosition, code,\n\t\t\t\"a {\\n  background:\\n    \"+gradient+\"(\\n      green,\\n      red 10%,\\n      red 20%,\\n      30%,\\n      \"+\n\t\t\t\t\"yellow 70%,\\n      yellow 80%,\\n      85%,\\n      black);\\n}\\n\", \"\")\n\n\t\t// Non-double positions with hints\n\t\tcode = \"a { background: \" + gradient + \"(green, red 10%, 1%, red 20%, black) }\"\n\t\texpectPrinted(t, code, \"a {\\n  background:\\n    \"+gradient+\"(\\n      green,\\n      red 10%,\\n      1%,\\n      \"+\n\t\t\t\"red 20%,\\n      black);\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, code, \"a {\\n  background:\\n    \"+gradient+\"(\\n      green,\\n      red 10%,\\n      \"+\n\t\t\t\"1%,\\n      red 20%,\\n      #000);\\n}\\n\", \"\")\n\t\texpectPrintedMinify(t, code, \"a{background:\"+gradient+\"(green,red 10%,1%,red 20%,black)}\", \"\")\n\t\texpectPrintedLowerUnsupported(t, compat.GradientDoublePosition, code,\n\t\t\t\"a {\\n  background:\\n    \"+gradient+\"(\\n      green,\\n      red 10%,\\n      1%,\\n      red 20%,\\n      black);\\n}\\n\", \"\")\n\n\t\t// Out-of-gamut colors\n\t\tcode = \"a { background: \" + gradient + \"(yellow, color(display-p3 1 0 0)) }\"\n\t\texpectPrinted(t, code, \"a {\\n  background: \"+gradient+\"(yellow, color(display-p3 1 0 0));\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, code, \"a {\\n  background: \"+gradient+\"(#ff0, color(display-p3 1 0 0));\\n}\\n\", \"\")\n\t\texpectPrintedMinify(t, code, \"a{background:\"+gradient+\"(yellow,color(display-p3 1 0 0))}\", \"\")\n\t\texpectPrintedLowerUnsupported(t, compat.ColorFunctions, code,\n\t\t\t\"a {\\n  background:\\n    \"+gradient+\"(\\n      #ffff00,\\n      #ffe971,\\n      #ffd472 25%,\\n      \"+\n\t\t\t\t\"#ffab5f,\\n      #ff7b45 75%,\\n      #ff5e38 87.5%,\\n      #ff5534,\\n      #ff4c30,\\n      \"+\n\t\t\t\t\"#ff412c,\\n      #ff0e0e);\\n  \"+\n\t\t\t\t\"background:\\n    \"+gradient+\"(\\n      #ffff00,\\n      color(xyz 0.734 0.805 0.111),\\n      \"+\n\t\t\t\t\"color(xyz 0.699 0.693 0.087) 25%,\\n      color(xyz 0.627 0.501 0.048),\\n      \"+\n\t\t\t\t\"color(xyz 0.556 0.348 0.019) 75%,\\n      color(xyz 0.521 0.284 0.009) 87.5%,\\n      \"+\n\t\t\t\t\"color(xyz 0.512 0.27 0.006),\\n      color(xyz 0.504 0.256 0.004),\\n      \"+\n\t\t\t\t\"color(xyz 0.495 0.242 0.002),\\n      color(xyz 0.487 0.229 0));\\n}\\n\", \"\")\n\n\t\t// Whitespace\n\t\tcode = \"a { background: \" + gradient + \"(color-mix(in lab,red,green)calc(1px)calc(2px),color-mix(in lab,blue,red)calc(98%)calc(99%)) }\"\n\t\texpectPrinted(t, code, \"a {\\n  background: \"+gradient+\n\t\t\t\"(color-mix(in lab, red, green)calc(1px)calc(2px), color-mix(in lab, blue, red)calc(98%)calc(99%));\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, code, \"a {\\n  background: \"+gradient+\n\t\t\t\"(color-mix(in lab, red, green) 1px 2px, color-mix(in lab, blue, red) 98% 99%);\\n}\\n\", \"\")\n\t\texpectPrintedMinify(t, code, \"a{background:\"+gradient+\n\t\t\t\"(color-mix(in lab,red,green)calc(1px)calc(2px),color-mix(in lab,blue,red)calc(98%)calc(99%))}\", \"\")\n\t\texpectPrintedLowerUnsupported(t, compat.GradientDoublePosition, code, \"a {\\n  background:\\n    \"+gradient+\n\t\t\t\"(\\n      color-mix(in lab, red, green) calc(1px),\\n      color-mix(in lab, red, green) calc(2px),\"+\n\t\t\t\"\\n      color-mix(in lab, blue, red) calc(98%),\\n      color-mix(in lab, blue, red) calc(99%));\\n}\\n\", \"\")\n\t\texpectPrintedLowerMangle(t, code, \"a {\\n  background:\\n    \"+gradient+\n\t\t\t\"(\\n      color-mix(in lab, red, green) 1px,\\n      color-mix(in lab, red, green) 2px,\"+\n\t\t\t\"\\n      color-mix(in lab, blue, red) 98%,\\n      color-mix(in lab, blue, red) 99%);\\n}\\n\", \"\")\n\n\t\t// Color space interpolation\n\t\texpectPrintedLowerUnsupported(t, compat.GradientInterpolation,\n\t\t\t\"a { background: \"+gradient+\"(in srgb, red, green) }\",\n\t\t\t\"a {\\n  background: \"+gradient+\"(#ff0000, #008000);\\n}\\n\", \"\")\n\t\texpectPrintedLowerUnsupported(t, compat.GradientInterpolation,\n\t\t\t\"a { background: \"+gradient+\"(in srgb-linear, red, green) }\",\n\t\t\t\"a {\\n  background:\\n    \"+gradient+\"(\\n      #ff0000,\\n      #fb1300,\\n      #f81f00 6.25%,\\n      \"+\n\t\t\t\t\"#f02e00 12.5%,\\n      #e14200 25%,\\n      #bc5c00,\\n      #897000 75%,\\n      #637800 87.5%,\\n      \"+\n\t\t\t\t\"#477c00 93.75%,\\n      #317e00,\\n      #008000);\\n}\\n\", \"\")\n\t\texpectPrintedLowerUnsupported(t, compat.GradientInterpolation,\n\t\t\t\"a { background: \"+gradient+\"(in lab, red, green) }\",\n\t\t\t\"a {\\n  background:\\n    \"+gradient+\"(\\n      #ff0000,\\n      color(xyz 0.396 0.211 0.019),\\n      \"+\n\t\t\t\t\"color(xyz 0.38 0.209 0.02) 6.25%,\\n      color(xyz 0.35 0.205 0.02) 12.5%,\\n      \"+\n\t\t\t\t\"color(xyz 0.294 0.198 0.02) 25%,\\n      color(xyz 0.2 0.183 0.022),\\n      \"+\n\t\t\t\t\"color(xyz 0.129 0.168 0.024) 75%,\\n      color(xyz 0.101 0.161 0.025) 87.5%,\\n      \"+\n\t\t\t\t\"color(xyz 0.089 0.158 0.025) 93.75%,\\n      color(xyz 0.083 0.156 0.025),\\n      #008000);\\n}\\n\", \"\")\n\n\t\t// Hue interpolation\n\t\texpectPrintedLowerUnsupported(t, compat.GradientInterpolation,\n\t\t\t\"a { background: \"+gradient+\"(in hsl shorter hue, red, green) }\",\n\t\t\t\"a {\\n  background:\\n    \"+gradient+\"(\\n      #ff0000,\\n      #df7000,\\n      \"+\n\t\t\t\t\"#bfbf00,\\n      #50a000,\\n      #008000);\\n}\\n\", \"\")\n\t\texpectPrintedLowerUnsupported(t, compat.GradientInterpolation,\n\t\t\t\"a { background: \"+gradient+\"(in hsl longer hue, red, green) }\",\n\t\t\t\"a {\\n  background:\\n    \"+gradient+\"(\\n      #ff0000,\\n      #ef0078,\\n      \"+\n\t\t\t\t\"#df00df,\\n      #6800cf,\\n      #0000c0,\\n      #0058b0,\\n      \"+\n\t\t\t\t\"#00a0a0,\\n      #009048,\\n      #008000);\\n}\\n\", \"\")\n\t}\n}\n\nfunc TestDeclaration(t *testing.T) {\n\texpectPrinted(t, \".decl {}\", \".decl {\\n}\\n\", \"\")\n\texpectPrinted(t, \".decl { a: b }\", \".decl {\\n  a: b;\\n}\\n\", \"\")\n\texpectPrinted(t, \".decl { a: b; }\", \".decl {\\n  a: b;\\n}\\n\", \"\")\n\texpectPrinted(t, \".decl { a: b; c: d }\", \".decl {\\n  a: b;\\n  c: d;\\n}\\n\", \"\")\n\texpectPrinted(t, \".decl { a: b; c: d; }\", \".decl {\\n  a: b;\\n  c: d;\\n}\\n\", \"\")\n\texpectPrinted(t, \".decl { a { b: c; } }\", \".decl {\\n  a {\\n    b: c;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \".decl { & a { b: c; } }\", \".decl {\\n  & a {\\n    b: c;\\n  }\\n}\\n\", \"\")\n\n\t// See http://browserhacks.com/\n\texpectPrinted(t, \".selector { (;property: value;); }\", \".selector {\\n  (;property: value;);\\n}\\n\", \"<stdin>: WARNING: Expected identifier but found \\\"(\\\"\\n\")\n\texpectPrinted(t, \".selector { [;property: value;]; }\", \".selector {\\n  [;property: value;];\\n}\\n\", \"<stdin>: WARNING: Expected identifier but found \\\"[\\\"\\n\")\n\texpectPrinted(t, \".selector, {}\", \".selector, {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"{\\\"\\n\")\n\texpectPrinted(t, \".selector\\\\ {}\", \".selector\\\\  {\\n}\\n\", \"\")\n\texpectPrinted(t, \".selector { property: value\\\\9; }\", \".selector {\\n  property: value\\\\\\t;\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media \\\\0screen\\\\,screen\\\\9 {}\", \"@media \\uFFFDscreen\\\\,screen\\\\\\t {\\n}\\n\", \"\")\n}\n\nfunc TestSelector(t *testing.T) {\n\texpectPrinted(t, \"a{}\", \"a {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a {}\", \"a {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a b {}\", \"a b {\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a/**/b {}\", \"ab {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"b\\\"\\n\")\n\texpectPrinted(t, \"a/**/.b {}\", \"a.b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a/**/:b {}\", \"a:b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a/**/[b] {}\", \"a[b] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a>/**/b {}\", \"a > b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a+/**/b {}\", \"a + b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a~/**/b {}\", \"a ~ b {\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"[b]{}\", \"[b] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b] {}\", \"[b] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a[b] {}\", \"a[b] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a [b] {}\", \"a [b] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[] {}\", \"[] {\\n}\\n\", \"<stdin>: WARNING: Expected identifier but found \\\"]\\\"\\n\")\n\texpectPrinted(t, \"[b {}\", \"[b] {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"]\\\" to go with \\\"[\\\"\\n<stdin>: NOTE: The unbalanced \\\"[\\\" is here:\\n\")\n\texpectPrinted(t, \"[b]] {}\", \"[b]] {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"]\\\"\\n\")\n\texpectPrinted(t, \"a[b {}\", \"a[b] {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"]\\\" to go with \\\"[\\\"\\n<stdin>: NOTE: The unbalanced \\\"[\\\" is here:\\n\")\n\texpectPrinted(t, \"a[b]] {}\", \"a[b]] {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"]\\\"\\n\")\n\texpectPrinted(t, \"[b]a {}\", \"[b]a {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"a\\\"\\n\")\n\n\texpectPrinted(t, \"[|b]{}\", \"[b] {\\n}\\n\", \"\") // \"[|b]\" is equivalent to \"[b]\"\n\texpectPrinted(t, \"[*|b]{}\", \"[*|b] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[a|b]{}\", \"[a|b] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[a|b|=\\\"c\\\"]{}\", \"[a|b|=c] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[a|b |= \\\"c\\\"]{}\", \"[a|b|=c] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[a||b] {}\", \"[a||b] {\\n}\\n\", \"<stdin>: WARNING: Expected identifier but found \\\"|\\\"\\n\")\n\texpectPrinted(t, \"[* | b] {}\", \"[* | b] {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"|\\\" but found whitespace\\n\")\n\texpectPrinted(t, \"[a | b] {}\", \"[a | b] {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"=\\\" but found whitespace\\n\")\n\n\texpectPrinted(t, \"[b=\\\"c\\\"] {}\", \"[b=c] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b=\\\"c d\\\"] {}\", \"[b=\\\"c d\\\"] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b=\\\"0c\\\"] {}\", \"[b=\\\"0c\\\"] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b~=\\\"c\\\"] {}\", \"[b~=c] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b^=\\\"c\\\"] {}\", \"[b^=c] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b$=\\\"c\\\"] {}\", \"[b$=c] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b*=\\\"c\\\"] {}\", \"[b*=c] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b|=\\\"c\\\"] {}\", \"[b|=c] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b?=\\\"c\\\"] {}\", \"[b?=\\\"c\\\"] {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"]\\\" to go with \\\"[\\\"\\n<stdin>: NOTE: The unbalanced \\\"[\\\" is here:\\n\")\n\n\texpectPrinted(t, \"[b = \\\"c\\\"] {}\", \"[b=c] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b ~= \\\"c\\\"] {}\", \"[b~=c] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b ^= \\\"c\\\"] {}\", \"[b^=c] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b $= \\\"c\\\"] {}\", \"[b$=c] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b *= \\\"c\\\"] {}\", \"[b*=c] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b |= \\\"c\\\"] {}\", \"[b|=c] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b ?= \\\"c\\\"] {}\", \"[b ?= \\\"c\\\"] {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"]\\\" to go with \\\"[\\\"\\n<stdin>: NOTE: The unbalanced \\\"[\\\" is here:\\n\")\n\n\texpectPrinted(t, \"[b = \\\"c\\\" i] {}\", \"[b=c i] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b = \\\"c\\\" I] {}\", \"[b=c I] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b = \\\"c\\\" s] {}\", \"[b=c s] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b = \\\"c\\\" S] {}\", \"[b=c S] {\\n}\\n\", \"\")\n\texpectPrinted(t, \"[b i] {}\", \"[b i] {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"]\\\" to go with \\\"[\\\"\\n<stdin>: NOTE: The unbalanced \\\"[\\\" is here:\\n\")\n\texpectPrinted(t, \"[b I] {}\", \"[b I] {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"]\\\" to go with \\\"[\\\"\\n<stdin>: NOTE: The unbalanced \\\"[\\\" is here:\\n\")\n\texpectPrinted(t, \"[b s] {}\", \"[b s] {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"]\\\" to go with \\\"[\\\"\\n<stdin>: NOTE: The unbalanced \\\"[\\\" is here:\\n\")\n\texpectPrinted(t, \"[b S] {}\", \"[b S] {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"]\\\" to go with \\\"[\\\"\\n<stdin>: NOTE: The unbalanced \\\"[\\\" is here:\\n\")\n\n\texpectPrinted(t, \"|b {}\", \"|b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"|* {}\", \"|* {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a|b {}\", \"a|b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a|* {}\", \"a|* {\\n}\\n\", \"\")\n\texpectPrinted(t, \"*|b {}\", \"*|b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"*|* {}\", \"*|* {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a||b {}\", \"a||b {\\n}\\n\", \"<stdin>: WARNING: Expected identifier but found \\\"|\\\"\\n\")\n\n\texpectPrinted(t, \"a+b {}\", \"a + b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a>b {}\", \"a > b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a+b {}\", \"a + b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a~b {}\", \"a ~ b {\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a + b {}\", \"a + b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a > b {}\", \"a > b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a + b {}\", \"a + b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a ~ b {}\", \"a ~ b {\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"::b {}\", \"::b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"*::b {}\", \"*::b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a::b {}\", \"a::b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"::b(c) {}\", \"::b(c) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"*::b(c) {}\", \"*::b(c) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a::b(c) {}\", \"a::b(c) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a:b:c {}\", \"a:b:c {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a:b(:c) {}\", \"a:b(:c) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a: b {}\", \"a: b {\\n}\\n\", \"<stdin>: WARNING: Expected identifier but found whitespace\\n\")\n\texpectPrinted(t, \":is(a)b {}\", \":is(a)b {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"b\\\"\\n\")\n\texpectPrinted(t, \"a:b( c ) {}\", \"a:b(c) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a:b( c , d ) {}\", \"a:b(c, d) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a:is( c ) {}\", \"a:is(c) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"a:is( c , d ) {}\", \"a:is(c, d) {\\n}\\n\", \"\")\n\n\t// Check an empty <forgiving-selector-list> (see https://github.com/evanw/esbuild/issues/4232)\n\texpectPrinted(t, \":is() {}\", \":is() {\\n}\\n\", \"\")\n\texpectPrinted(t, \":where() {}\", \":where() {\\n}\\n\", \"\")\n\texpectPrinted(t, \":not(:is()) {}\", \":not(:is()) {\\n}\\n\", \"\")\n\texpectPrinted(t, \":not(:where()) {}\", \":not(:where()) {\\n}\\n\", \"\")\n\texpectPrinted(t, \":not() {}\", \":not() {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\")\\\"\\n\")\n\n\t// These test cases previously caused a hang (see https://github.com/evanw/esbuild/issues/2276)\n\texpectPrinted(t, \":x(\", \":x() {\\n}\\n\", \"<stdin>: WARNING: Unexpected end of file\\n\")\n\texpectPrinted(t, \":x( {}\", \":x({}) {\\n}\\n\", \"<stdin>: WARNING: Expected \\\")\\\" to go with \\\"(\\\"\\n<stdin>: NOTE: The unbalanced \\\"(\\\" is here:\\n\")\n\texpectPrinted(t, \":x(, :y() {}\", \":x(, :y() {}) {\\n}\\n\", \"<stdin>: WARNING: Expected \\\")\\\" to go with \\\"(\\\"\\n<stdin>: NOTE: The unbalanced \\\"(\\\" is here:\\n\")\n\n\texpectPrinted(t, \"#id {}\", \"#id {\\n}\\n\", \"\")\n\texpectPrinted(t, \"#--0 {}\", \"#--0 {\\n}\\n\", \"\")\n\texpectPrinted(t, \"#\\\\-0 {}\", \"#\\\\-0 {\\n}\\n\", \"\")\n\texpectPrinted(t, \"#\\\\30 {}\", \"#\\\\30  {\\n}\\n\", \"\")\n\texpectPrinted(t, \"div#id {}\", \"div#id {\\n}\\n\", \"\")\n\texpectPrinted(t, \"div#--0 {}\", \"div#--0 {\\n}\\n\", \"\")\n\texpectPrinted(t, \"div#\\\\-0 {}\", \"div#\\\\-0 {\\n}\\n\", \"\")\n\texpectPrinted(t, \"div#\\\\30 {}\", \"div#\\\\30  {\\n}\\n\", \"\")\n\texpectPrinted(t, \"#0 {}\", \"#0 {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"#0\\\"\\n\")\n\texpectPrinted(t, \"#-0 {}\", \"#-0 {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"#-0\\\"\\n\")\n\texpectPrinted(t, \"div#0 {}\", \"div#0 {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"#0\\\"\\n\")\n\texpectPrinted(t, \"div#-0 {}\", \"div#-0 {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"#-0\\\"\\n\")\n\n\texpectPrinted(t, \"div::before::after::selection::first-line::first-letter {color:red}\",\n\t\t\"div::before::after::selection::first-line::first-letter {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div::before::after::selection::first-line::first-letter {color:red}\",\n\t\t\"div:before:after::selection:first-line:first-letter {\\n  color: red;\\n}\\n\", \"\")\n\n\t// Make sure '-' and '\\\\' consume an ident-like token instead of a name\n\texpectPrinted(t, \"_:-ms-lang(x) {}\", \"_:-ms-lang(x) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"_:\\\\ms-lang(x) {}\", \"_:ms-lang(x) {\\n}\\n\", \"\")\n\n\texpectPrinted(t, \":local(a, b) {}\", \":local(a, b) {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\",\\\" inside \\\":local(...)\\\"\\n\"+\n\t\t\"NOTE: Different CSS tools behave differently in this case, so esbuild doesn't allow it. Either remove \"+\n\t\t\"this comma or split this selector up into multiple comma-separated \\\":local(...)\\\" selectors instead.\\n\")\n\texpectPrinted(t, \":global(a, b) {}\", \":global(a, b) {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\",\\\" inside \\\":global(...)\\\"\\n\"+\n\t\t\"NOTE: Different CSS tools behave differently in this case, so esbuild doesn't allow it. Either remove \"+\n\t\t\"this comma or split this selector up into multiple comma-separated \\\":global(...)\\\" selectors instead.\\n\")\n}\n\nfunc TestNestedSelector(t *testing.T) {\n\tsassWarningWrap := \"NOTE: CSS nesting syntax does not allow the \\\"&\\\" selector to come before \" +\n\t\t\"a type selector. You can wrap this selector in \\\":is(...)\\\" as a workaround. \" +\n\t\t\"This restriction exists to avoid problems with SASS nesting, where the same syntax \" +\n\t\t\"means something very different that has no equivalent in real CSS (appending a suffix to the parent selector).\\n\"\n\tsassWarningMove := \"NOTE: CSS nesting syntax does not allow the \\\"&\\\" selector to come before \" +\n\t\t\"a type selector. You can move the \\\"&\\\" to the end of this selector as a workaround. \" +\n\t\t\"This restriction exists to avoid problems with SASS nesting, where the same syntax \" +\n\t\t\"means something very different that has no equivalent in real CSS (appending a suffix to the parent selector).\\n\"\n\n\texpectPrinted(t, \"& {}\", \"& {\\n}\\n\", \"\")\n\texpectPrinted(t, \"& b {}\", \"& b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"&:b {}\", \"&:b {\\n}\\n\", \"\")\n\texpectPrinted(t, \"&* {}\", \"&* {\\n}\\n\", \"<stdin>: WARNING: Cannot use type selector \\\"*\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningWrap)\n\texpectPrinted(t, \"&|b {}\", \"&|b {\\n}\\n\", \"<stdin>: WARNING: Cannot use type selector \\\"|b\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningWrap)\n\texpectPrinted(t, \"&*|b {}\", \"&*|b {\\n}\\n\", \"<stdin>: WARNING: Cannot use type selector \\\"*|b\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningWrap)\n\texpectPrinted(t, \"&a|b {}\", \"&a|b {\\n}\\n\", \"<stdin>: WARNING: Cannot use type selector \\\"a|b\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningWrap)\n\texpectPrinted(t, \"&[a] {}\", \"&[a] {\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a { & {} }\", \"a {\\n  & {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { & b {} }\", \"a {\\n  & b {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { &:b {} }\", \"a {\\n  &:b {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { &* {} }\", \"a {\\n  &* {\\n  }\\n}\\n\", \"<stdin>: WARNING: Cannot use type selector \\\"*\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningWrap)\n\texpectPrinted(t, \"a { &|b {} }\", \"a {\\n  &|b {\\n  }\\n}\\n\", \"<stdin>: WARNING: Cannot use type selector \\\"|b\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningWrap)\n\texpectPrinted(t, \"a { &*|b {} }\", \"a {\\n  &*|b {\\n  }\\n}\\n\", \"<stdin>: WARNING: Cannot use type selector \\\"*|b\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningWrap)\n\texpectPrinted(t, \"a { &a|b {} }\", \"a {\\n  &a|b {\\n  }\\n}\\n\", \"<stdin>: WARNING: Cannot use type selector \\\"a|b\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningWrap)\n\texpectPrinted(t, \"a { &[b] {} }\", \"a {\\n  &[b] {\\n  }\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a { && {} }\", \"a {\\n  && {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { & + & {} }\", \"a {\\n  & + & {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { & > & {} }\", \"a {\\n  & > & {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { & ~ & {} }\", \"a {\\n  & ~ & {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { & + c& {} }\", \"a {\\n  & + c& {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { .b& + & {} }\", \"a {\\n  &.b + & {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { .b& + c& {} }\", \"a {\\n  &.b + c& {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { & + & > & ~ & {} }\", \"a {\\n  & + & > & ~ & {\\n  }\\n}\\n\", \"\")\n\n\t// CSS nesting works for all tokens except identifiers and functions\n\texpectPrinted(t, \"a { .b {} }\", \"a {\\n  .b {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { #b {} }\", \"a {\\n  #b {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { :b {} }\", \"a {\\n  :b {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { [b] {} }\", \"a {\\n  [b] {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { * {} }\", \"a {\\n  * {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { |b {} }\", \"a {\\n  |b {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { >b {} }\", \"a {\\n  > b {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { +b {} }\", \"a {\\n  + b {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { ~b {} }\", \"a {\\n  ~ b {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { b {} }\", \"a {\\n  b {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { b() {} }\", \"a {\\n  b() {\\n  }\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"b(\\\"\\n\")\n\n\t// Note: CSS nesting no longer requires each complex selector to contain \"&\"\n\texpectPrinted(t, \"a { & b, c {} }\", \"a {\\n  & b,\\n  c {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { & b, & c {} }\", \"a {\\n  & b,\\n  & c {\\n  }\\n}\\n\", \"\")\n\n\t// Note: CSS nesting no longer requires the rule to be nested inside a parent\n\t// (instead un-nested CSS nesting refers to \":scope\" or to \":root\")\n\texpectPrinted(t, \"& b, c {}\", \"& b,\\nc {\\n}\\n\", \"\")\n\texpectPrinted(t, \"& b, & c {}\", \"& b,\\n& c {\\n}\\n\", \"\")\n\texpectPrinted(t, \"b & {}\", \"b & {\\n}\\n\", \"\")\n\texpectPrinted(t, \"b &, c {}\", \"b &,\\nc {\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a { .b & { color: red } }\", \"a {\\n  .b & {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { .b& { color: red } }\", \"a {\\n  &.b {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { .b&[c] { color: red } }\", \"a {\\n  &.b[c] {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { &[c] { color: red } }\", \"a {\\n  &[c] {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { [c]& { color: red } }\", \"a {\\n  &[c] {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMinify(t, \"a { .b & { color: red } }\", \"a{.b &{color:red}}\", \"\")\n\texpectPrintedMinify(t, \"a { .b& { color: red } }\", \"a{&.b{color:red}}\", \"\")\n\n\t// Nested at-rules\n\texpectPrinted(t, \"a { @media screen { color: red } }\", \"a {\\n  @media screen {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { @media screen { .b { color: green } color: red } }\",\n\t\t\"a {\\n  @media screen {\\n    .b {\\n      color: green;\\n    }\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { @media screen { color: red; .b { color: green } } }\",\n\t\t\"a {\\n  @media screen {\\n    color: red;\\n    .b {\\n      color: green;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"html { @layer base { block-size: 100%; @layer support { & body { min-block-size: 100%; } } } }\",\n\t\t\"html {\\n  @layer base {\\n    block-size: 100%;\\n    @layer support {\\n      & body {\\n        min-block-size: 100%;\\n      }\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \".card { aspect-ratio: 3/4; @scope (&) { :scope { border: 1px solid white } } }\",\n\t\t\".card {\\n  aspect-ratio: 3/4;\\n  @scope (&) {\\n    :scope {\\n      border: 1px solid white;\\n    }\\n  }\\n}\\n\", \"\")\n\n\t// Minify an implicit leading \"&\"\n\texpectPrintedMangle(t, \"& { color: red }\", \"& {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"& a { color: red }\", \"a {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"& a, & b { color: red }\", \"a,\\nb {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"& a, b { color: red }\", \"a,\\nb {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a, & b { color: red }\", \"a,\\nb {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"& &a { color: red }\", \"& &a {\\n  color: red;\\n}\\n\", \"<stdin>: WARNING: Cannot use type selector \\\"a\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningMove)\n\texpectPrintedMangle(t, \"& .x { color: red }\", \".x {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"& &.x { color: red }\", \"& &.x {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"& + a { color: red }\", \"+ a {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"& + a& { color: red }\", \"+ a& {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"&.x { color: red }\", \"&.x {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a & { color: red }\", \"a & {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \".x & { color: red }\", \".x & {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { & a { color: red } }\", \"div {\\n  & a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { & .x { color: red } }\", \"div {\\n  .x {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { & .x, & a { color: red } }\", \"div {\\n  .x,\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { .x, & a { color: red } }\", \"div {\\n  .x,\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { & a& { color: red } }\", \"div {\\n  & a& {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { & .x { color: red } }\", \"div {\\n  .x {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { & &.x { color: red } }\", \"div {\\n  & &.x {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { & + a { color: red } }\", \"div {\\n  + a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { & + a& { color: red } }\", \"div {\\n  + a& {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { .x & { color: red } }\", \"div {\\n  .x & {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen { & div { color: red } }\", \"@media screen {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { @media screen { & div { color: red } } }\", \"a {\\n  @media screen {\\n    & div {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { :has(& b) { color: red } }\", \"a {\\n  :has(& b) {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { :has(& + b) { color: red } }\", \"a {\\n  :has(& + b) {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\t// Reorder selectors to enable removing \"&\"\n\texpectPrintedMangle(t, \"reorder { & first, .second { color: red } }\", \"reorder {\\n  .second,\\n  first {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"reorder { & first, & .second { color: red } }\", \"reorder {\\n  .second,\\n  first {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"reorder { & first, #second { color: red } }\", \"reorder {\\n  #second,\\n  first {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"reorder { & first, [second] { color: red } }\", \"reorder {\\n  [second],\\n  first {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"reorder { & first, :second { color: red } }\", \"reorder {\\n  :second,\\n  first {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"reorder { & first, + second { color: red } }\", \"reorder {\\n  + second,\\n  first {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"reorder { & first, ~ second { color: red } }\", \"reorder {\\n  ~ second,\\n  first {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"reorder { & first, > second { color: red } }\", \"reorder {\\n  > second,\\n  first {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"reorder { & first, second, .third { color: red } }\", \"reorder {\\n  .third,\\n  second,\\n  first {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\t// Inline no-op nesting\n\texpectPrintedMangle(t, \"div { & { color: red } }\", \"div {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { && { color: red } }\", \"div {\\n  && {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { zoom: 2; & { color: red } }\", \"div {\\n  zoom: 2;\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { zoom: 2; && { color: red } }\", \"div {\\n  zoom: 2;\\n  && {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { &, & { color: red } zoom: 2 }\", \"div {\\n  zoom: 2;\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { &, && { color: red } zoom: 2 }\", \"div {\\n  &,\\n  && {\\n    color: red;\\n  }\\n  zoom: 2;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { &&, & { color: red } zoom: 2 }\", \"div {\\n  &&,\\n  & {\\n    color: red;\\n  }\\n  zoom: 2;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { a: 1; & { b: 4 } b: 2; && { c: 5 } c: 3 }\", \"div {\\n  a: 1;\\n  b: 2;\\n  && {\\n    c: 5;\\n  }\\n  c: 3;\\n  b: 4;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { .b { x: 1 } & { x: 2 } }\", \"div {\\n  .b {\\n    x: 1;\\n  }\\n  x: 2;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div { & { & { & { color: red } } & { & { zoom: 2 } } } }\", \"div {\\n  color: red;\\n  zoom: 2;\\n}\\n\", \"\")\n\n\t// Cannot inline no-op nesting with pseudo-elements (https://github.com/w3c/csswg-drafts/issues/7433)\n\texpectPrintedMangle(t, \"div, span:hover { & { color: red } }\", \"div,\\nspan:hover {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div, span::before { & { color: red } }\", \"div,\\nspan:before {\\n  & {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div, span:before { & { color: red } }\", \"div,\\nspan:before {\\n  & {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div, span::after { & { color: red } }\", \"div,\\nspan:after {\\n  & {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div, span:after { & { color: red } }\", \"div,\\nspan:after {\\n  & {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div, span::first-line { & { color: red } }\", \"div,\\nspan:first-line {\\n  & {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div, span:first-line { & { color: red } }\", \"div,\\nspan:first-line {\\n  & {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div, span::first-letter { & { color: red } }\", \"div,\\nspan:first-letter {\\n  & {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div, span:first-letter { & { color: red } }\", \"div,\\nspan:first-letter {\\n  & {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div, span::pseudo { & { color: red } }\", \"div,\\nspan::pseudo {\\n  & {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div, span:hover { @layer foo { & { color: red } } }\", \"div,\\nspan:hover {\\n  @layer foo {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div, span:hover { @media screen { & { color: red } } }\", \"div,\\nspan:hover {\\n  @media screen {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div, span::pseudo { @layer foo { & { color: red } } }\", \"div,\\nspan::pseudo {\\n  @layer foo {\\n    & {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"div, span::pseudo { @media screen { & { color: red } } }\", \"div,\\nspan::pseudo {\\n  @media screen {\\n    & {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\n\t// Lowering tests for nesting\n\tnestingWarningIs := \"<stdin>: WARNING: Transforming this CSS nesting syntax is not supported in the configured target environment\\n\" +\n\t\t\"NOTE: The nesting transform for this case must generate an \\\":is(...)\\\" but the configured target environment does not support the \\\":is\\\" pseudo-class.\\n\"\n\tnesting := compat.Nesting\n\teverything := ^compat.CSSFeature(0)\n\texpectPrintedLowerUnsupported(t, nesting, \".foo { .bar { color: red } }\", \".foo .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo { &.bar { color: red } }\", \".foo.bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo { & .bar { color: red } }\", \".foo .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo .bar { .baz { color: red } }\", \".foo .bar .baz {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo .bar { &.baz { color: red } }\", \".foo .bar.baz {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo .bar { & .baz { color: red } }\", \".foo .bar .baz {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo .bar { & > .baz { color: red } }\", \".foo .bar > .baz {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo .bar { .baz & { color: red } }\", \".baz :is(.foo .bar) {\\n  color: red;\\n}\\n\", \"\") // NOT the same as \".baz .foo .bar\n\texpectPrintedLowerUnsupported(t, nesting, \".foo .bar { & .baz & { color: red } }\", \".foo .bar .baz :is(.foo .bar) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo, .bar { .baz & { color: red } }\", \".baz :is(.foo, .bar) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \".foo, .bar { .baz & { color: red } }\", \".baz .foo,\\n.baz .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo, [bar~='abc'] { .baz { color: red } }\", \":is(.foo, [bar~=abc]) .baz {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \".foo, [bar~='abc'] { .baz { color: red } }\", \".foo .baz,\\n[bar~=abc] .baz {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo, [bar~='a b c'] { .baz { color: red } }\", \":is(.foo, [bar~=\\\"a b c\\\"]) .baz {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \".foo, [bar~='a b c'] { .baz { color: red } }\", \".foo .baz,\\n[bar~=\\\"a b c\\\"] .baz {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".baz { .foo, .bar { color: red } }\", \".baz .foo,\\n.baz .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \".baz { .foo, .bar { color: red } }\", \".baz .foo,\\n.baz .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".baz { .foo, & .bar { color: red } }\", \".baz .foo,\\n.baz .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \".baz { .foo, & .bar { color: red } }\", \".baz .foo,\\n.baz .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".baz { & .foo, .bar { color: red } }\", \".baz .foo,\\n.baz .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \".baz { & .foo, .bar { color: red } }\", \".baz .foo,\\n.baz .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".baz { & .foo, & .bar { color: red } }\", \".baz .foo,\\n.baz .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \".baz { & .foo, & .bar { color: red } }\", \".baz .foo,\\n.baz .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".baz { .foo, &.bar { color: red } }\", \".baz .foo,\\n.baz.bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \".baz { &.foo, .bar { color: red } }\", \".baz.foo,\\n.baz .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".baz { &.foo, &.bar { color: red } }\", \".baz.foo,\\n.baz.bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \".baz { &.foo, &.bar { color: red } }\", \".baz.foo,\\n.baz.bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo { color: blue; & .bar { color: red } }\", \".foo {\\n  color: blue;\\n}\\n.foo .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo { & .bar { color: red } color: blue }\", \".foo {\\n  color: blue;\\n}\\n.foo .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo { color: blue; & .bar { color: red } zoom: 2 }\", \".foo {\\n  color: blue;\\n  zoom: 2;\\n}\\n.foo .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".a, .b { .c, .d { color: red } }\", \":is(.a, .b) .c,\\n:is(.a, .b) .d {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \".a, .b { .c, .d { color: red } }\", \".a .c,\\n.a .d,\\n.b .c,\\n.b .d {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".a, .b { & > & { color: red } }\", \":is(.a, .b) > :is(.a, .b) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \".a, .b { & > & { color: red } }\", \".a > .a,\\n.a > .b,\\n.b > .a,\\n.b > .b {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".a { color: red; > .b { color: green; > .c { color: blue } } }\", \".a {\\n  color: red;\\n}\\n.a > .b {\\n  color: green;\\n}\\n.a > .b > .c {\\n  color: blue;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"> .a { color: red; > .b { color: green; > .c { color: blue } } }\", \"> .a {\\n  color: red;\\n}\\n> .a > .b {\\n  color: green;\\n}\\n> .a > .b > .c {\\n  color: blue;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo, .bar, .foo:before, .bar:after { &:hover { color: red } }\", \":is(.foo, .bar):hover {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \".foo, .bar, .foo:before, .bar:after { &:hover { color: red } }\", \".foo:hover,\\n.bar:hover {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo, .bar:before { &:hover { color: red } }\", \".foo:hover {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo, .bar:before { :hover & { color: red } }\", \":hover .foo {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".bar:before { &:hover { color: red } }\", \":is():hover {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".bar:before { :hover & { color: red } }\", \":hover :is() {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo { &:after, & .bar { color: red } }\", \".foo:after,\\n.foo .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo { & .bar, &:after { color: red } }\", \".foo .bar,\\n.foo:after {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".xy { :where(&.foo) { color: red } }\", \":where(.xy.foo) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"div { :where(&.foo) { color: red } }\", \":where(div.foo) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".xy { :where(.foo&) { color: red } }\", \":where(.xy.foo) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"div { :where(.foo&) { color: red } }\", \":where(div.foo) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".xy { :where([href]&) { color: red } }\", \":where(.xy[href]) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"div { :where([href]&) { color: red } }\", \":where(div[href]) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".xy { :where(:hover&) { color: red } }\", \":where(.xy:hover) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"div { :where(:hover&) { color: red } }\", \":where(div:hover) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".xy { :where(:is(.foo)&) { color: red } }\", \":where(.xy:is(.foo)) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"div { :where(:is(.foo)&) { color: red } }\", \":where(div:is(.foo)) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".xy { :where(.foo + &) { color: red } }\", \":where(.foo + .xy) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"div { :where(.foo + &) { color: red } }\", \":where(.foo + div) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".xy { :where(&, span:is(.foo &)) { color: red } }\", \":where(.xy, span:is(.foo .xy)) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"div { :where(&, span:is(.foo &)) { color: red } }\", \":where(div, span:is(.foo div)) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"&, a { color: red }\", \":scope,\\na {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"&, a { .b { color: red } }\", \":is(:scope, a) .b {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \"&, a { .b { color: red } }\", \":scope .b,\\na .b {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"&, a { .b { .c { color: red } } }\", \":is(:scope, a) .b .c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \"&, a { .b { .c { color: red } } }\", \":scope .b .c,\\na .b .c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a { > b, > c { color: red } }\", \"a > b,\\na > c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \"a { > b, > c { color: red } }\", \"a > b,\\na > c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a { > b, + c { color: red } }\", \"a > b,\\na + c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a { & > b, & > c { color: red } }\", \"a > b,\\na > c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \"a { & > b, & > c { color: red } }\", \"a > b,\\na > c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a { & > b, & + c { color: red } }\", \"a > b,\\na + c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a { > b&, > c& { color: red } }\", \"a > a:is(b),\\na > a:is(c) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \"a { > b&, > c& { color: red } }\", \"a > a:is(b),\\na > a:is(c) {\\n  color: red;\\n}\\n\", nestingWarningIs+nestingWarningIs)\n\texpectPrintedLowerUnsupported(t, nesting, \"a { > b&, + c& { color: red } }\", \"a > a:is(b),\\na + a:is(c) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a { > &.b, > &.c { color: red } }\", \"a > a.b,\\na > a.c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \"a { > &.b, > &.c { color: red } }\", \"a > a.b,\\na > a.c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a { > &.b, + &.c { color: red } }\", \"a > a.b,\\na + a.c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".a { > b&, > c& { color: red } }\", \".a > b.a,\\n.a > c.a {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \".a { > b&, > c& { color: red } }\", \".a > b.a,\\n.a > c.a {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".a { > b&, + c& { color: red } }\", \".a > b.a,\\n.a + c.a {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".a { > &.b, > &.c { color: red } }\", \".a > .a.b,\\n.a > .a.c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \".a { > &.b, > &.c { color: red } }\", \".a > .a.b,\\n.a > .a.c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".a { > &.b, + &.c { color: red } }\", \".a > .a.b,\\n.a + .a.c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"~ .a { > &.b, > &.c { color: red } }\", \"~ .a > .a.b,\\n~ .a > .a.c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \"~ .a { > &.b, > &.c { color: red } }\", \"~ .a > .a.b,\\n~ .a > .a.c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"~ .a { > &.b, + &.c { color: red } }\", \"~ .a > .a.b,\\n~ .a + .a.c {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo .bar { > &.a, > &.b { color: red } }\", \".foo .bar > :is(.foo .bar).a,\\n.foo .bar > :is(.foo .bar).b {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, everything, \".foo .bar { > &.a, > &.b { color: red } }\", \".foo .bar > :is(.foo .bar).a,\\n.foo .bar > :is(.foo .bar).b {\\n  color: red;\\n}\\n\", nestingWarningIs+nestingWarningIs)\n\texpectPrintedLowerUnsupported(t, nesting, \".foo .bar { > &.a, + &.b { color: red } }\", \".foo .bar > :is(.foo .bar).a,\\n.foo .bar + :is(.foo .bar).b {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".demo { .lg { &.triangle, &.circle { color: red } } }\", \".demo .lg.triangle,\\n.demo .lg.circle {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".demo { .lg { .triangle, .circle { color: red } } }\", \".demo .lg .triangle,\\n.demo .lg .circle {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".card { .featured & & & { color: red } }\", \".featured .card .card .card {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".a :has(> .c) { .b & { color: red } }\", \".b :is(.a :has(> .c)) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a { :has(&) { color: red } }\", \":has(a) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a { :has(> &) { color: red } }\", \":has(> a) {\\n  color: red;\\n}\\n\", \"\")\n\n\t// Duplicate \"&\" may be used to increase specificity\n\texpectPrintedLowerUnsupported(t, nesting, \".foo { &&&.bar { color: red } }\", \".foo.foo.foo.bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo { &&& .bar { color: red } }\", \".foo.foo.foo .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo { .bar&&& { color: red } }\", \".foo.foo.foo.bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo { .bar &&& { color: red } }\", \".bar .foo.foo.foo {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo { &.bar&.baz& { color: red } }\", \".foo.foo.foo.bar.baz {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a { &&&.bar { color: red } }\", \"a:is(a):is(a).bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a { &&& .bar { color: red } }\", \"a:is(a):is(a) .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a { .bar&&& { color: red } }\", \"a:is(a):is(a).bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a { .bar &&& { color: red } }\", \".bar a:is(a):is(a) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a { &.bar&.baz& { color: red } }\", \"a:is(a):is(a).bar.baz {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a, b { &&&.bar { color: red } }\", \":is(a, b):is(a, b):is(a, b).bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a, b { &&& .bar { color: red } }\", \":is(a, b):is(a, b):is(a, b) .bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a, b { .bar&&& { color: red } }\", \":is(a, b):is(a, b):is(a, b).bar {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a, b { .bar &&& { color: red } }\", \".bar :is(a, b):is(a, b):is(a, b) {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \"a, b { &.bar&.baz& { color: red } }\", \":is(a, b):is(a, b):is(a, b).bar.baz {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLowerUnsupported(t, nesting, \".foo { &, &&.bar, &&& .baz { color: red } }\", \".foo,\\n.foo.foo.bar,\\n.foo.foo.foo .baz {\\n  color: red;\\n}\\n\", \"\")\n\n\t// These are invalid SASS-style nested suffixes\n\texpectPrintedLower(t, \".card { &--header { color: red } }\", \".card {\\n  &--header {\\n    color: red;\\n  }\\n}\\n\",\n\t\t\"<stdin>: WARNING: Cannot use type selector \\\"--header\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningWrap)\n\texpectPrintedLower(t, \".card { &__header { color: red } }\", \".card {\\n  &__header {\\n    color: red;\\n  }\\n}\\n\",\n\t\t\"<stdin>: WARNING: Cannot use type selector \\\"__header\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningWrap)\n\texpectPrintedLower(t, \".card { .nav &--header { color: red } }\", \".card {\\n  .nav &--header {\\n    color: red;\\n  }\\n}\\n\",\n\t\t\"<stdin>: WARNING: Cannot use type selector \\\"--header\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningMove)\n\texpectPrintedLower(t, \".card { .nav &__header { color: red } }\", \".card {\\n  .nav &__header {\\n    color: red;\\n  }\\n}\\n\",\n\t\t\"<stdin>: WARNING: Cannot use type selector \\\"__header\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningMove)\n\texpectPrinted(t, \".card { &__header { color: red } }\", \".card {\\n  &__header {\\n    color: red;\\n  }\\n}\\n\",\n\t\t\"<stdin>: WARNING: Cannot use type selector \\\"__header\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningWrap)\n\texpectPrinted(t, \".card { .nav &__header { color: red } }\", \".card {\\n  .nav &__header {\\n    color: red;\\n  }\\n}\\n\",\n\t\t\"<stdin>: WARNING: Cannot use type selector \\\"__header\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningMove)\n\texpectPrinted(t, \".card { .nav, &__header { color: red } }\", \".card {\\n  .nav, &__header {\\n    color: red;\\n  }\\n}\\n\",\n\t\t\"<stdin>: WARNING: Cannot use type selector \\\"__header\\\" directly after nesting selector \\\"&\\\"\\n\"+sassWarningMove)\n\n\t// Check pseudo-elements (those coming through \"&\" must be dropped)\n\texpectPrintedLower(t, \"a, b::before { &.foo { color: red } }\", \"a.foo {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a, b::before { & .foo { color: red } }\", \"a .foo {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { &.foo, &::before { color: red } }\", \"a.foo,\\na::before {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { & .foo, & ::before { color: red } }\", \"a .foo,\\na ::before {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a, b::before { color: blue; &.foo, &::after { color: red } }\", \"a,\\nb::before {\\n  color: blue;\\n}\\na.foo,\\na::after {\\n  color: red;\\n}\\n\", \"\")\n\n\t// Test at-rules\n\texpectPrintedLower(t, \".foo { @media screen {} }\", \"\", \"\")\n\texpectPrintedLower(t, \".foo { @media screen { color: red } }\", \"@media screen {\\n  .foo {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \".foo { @media screen { &:hover { color: red } } }\", \"@media screen {\\n  .foo:hover {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \".foo { @media screen { :hover { color: red } } }\", \"@media screen {\\n  .foo :hover {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \".foo, .bar { @media screen { color: red } }\", \"@media screen {\\n  .foo,\\n  .bar {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \".foo, .bar { @media screen { &:hover { color: red } } }\", \"@media screen {\\n  .foo:hover,\\n  .bar:hover {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \".foo, .bar { @media screen { :hover { color: red } } }\", \"@media screen {\\n  .foo :hover,\\n  .bar :hover {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \".foo { @layer xyz {} }\", \"@layer xyz;\\n\", \"\")\n\texpectPrintedLower(t, \".foo { @layer xyz { color: red } }\", \"@layer xyz {\\n  .foo {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \".foo { @layer xyz { &:hover { color: red } } }\", \"@layer xyz {\\n  .foo:hover {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \".foo { @layer xyz { :hover { color: red } } }\", \"@layer xyz {\\n  .foo :hover {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \".foo, .bar { @layer xyz { color: red } }\", \"@layer xyz {\\n  .foo,\\n  .bar {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \".foo, .bar { @layer xyz { &:hover { color: red } } }\", \"@layer xyz {\\n  .foo:hover,\\n  .bar:hover {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \".foo, .bar { @layer xyz { :hover { color: red } } }\", \"@layer xyz {\\n  .foo :hover,\\n  .bar :hover {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media screen { @media (min-width: 900px) { a, b { &:hover { color: red } } } }\",\n\t\t\"@media screen {\\n  @media (min-width: 900px) {\\n    a:hover,\\n    b:hover {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@supports (display: flex) { @supports selector(h2 > p) { a, b { &:hover { color: red } } } }\",\n\t\t\"@supports (display: flex) {\\n  @supports selector(h2 > p) {\\n    a:hover,\\n    b:hover {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@layer foo { @layer bar { a, b { &:hover { color: red } } } }\",\n\t\t\"@layer foo {\\n  @layer bar {\\n    a:hover,\\n    b:hover {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \".card { @supports (selector(&)) { &:hover { color: red } } }\",\n\t\t\"@supports (selector(&)) {\\n  .card:hover {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"html { @layer base { color: blue; @layer support { & body { color: red } } } }\",\n\t\t\"@layer base {\\n  html {\\n    color: blue;\\n  }\\n  @layer support {\\n    html body {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\n\t// https://github.com/w3c/csswg-drafts/issues/7961#issuecomment-1549874958\n\texpectPrinted(t, \"@media screen { a { x: y } x: y; b { x: y } }\", \"@media screen {\\n  a {\\n    x: y;\\n  }\\n  x: y;\\n  b {\\n    x: y;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \":root { @media screen { a { x: y } x: y; b { x: y } } }\", \":root {\\n  @media screen {\\n    a {\\n      x: y;\\n    }\\n    x: y;\\n    b {\\n      x: y;\\n    }\\n  }\\n}\\n\", \"\")\n\n\t// Nested at-rules work with pseudo-elements while nested \"&\" rules do not\n\t// See: https://github.com/evanw/esbuild/issues/4265\n\texpectPrintedLower(t, \"::placeholder { color: red; body & { color: green } }\",\n\t\t\"::placeholder {\\n  color: red;\\n}\\nbody :is() {\\n  color: green;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"::placeholder { color: red; @supports (color: green) { color: green } }\",\n\t\t\"::placeholder {\\n  color: red;\\n}\\n@supports (color: green) {\\n  ::placeholder {\\n    color: green;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"::placeholder { opacity: 0.5; @layer base { color: green } }\",\n\t\t\"::placeholder {\\n  opacity: 0.5;\\n}\\n@layer base {\\n  ::placeholder {\\n    color: green;\\n  }\\n}\\n\", \"\")\n}\n\nfunc TestBadQualifiedRules(t *testing.T) {\n\texpectPrinted(t, \"$bad: rule;\", \"$bad: rule; {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"$\\\"\\n\")\n\texpectPrinted(t, \"$bad: rule; div { color: red }\", \"$bad: rule; div {\\n  color: red;\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"$\\\"\\n\")\n\texpectPrinted(t, \"$bad { color: red }\", \"$bad {\\n  color: red;\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"$\\\"\\n\")\n\texpectPrinted(t, \"a { div.major { color: blue } color: red }\", \"a {\\n  div.major {\\n    color: blue;\\n  }\\n  color: red;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { div:hover { color: blue } color: red }\", \"a {\\n  div:hover {\\n    color: blue;\\n  }\\n  color: red;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { div:hover { color: blue }; color: red }\", \"a {\\n  div:hover {\\n    color: blue;\\n  }\\n  color: red;\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { div:hover { color: blue } ; color: red }\", \"a {\\n  div:hover {\\n    color: blue;\\n  }\\n  color: red;\\n}\\n\", \"\")\n\texpectPrinted(t, \"! { x: y; }\", \"! {\\n  x: y;\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"!\\\"\\n\")\n\texpectPrinted(t, \"! { x: {} }\", \"! {\\n  x: {\\n  }\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"!\\\"\\n<stdin>: WARNING: Expected identifier but found whitespace\\n\")\n\texpectPrinted(t, \"a { *width: 100%; height: 1px }\", \"a {\\n  *width: 100%;\\n  height: 1px;\\n}\\n\", \"<stdin>: WARNING: Expected identifier but found \\\"*\\\"\\n\")\n\texpectPrinted(t, \"a { garbage; height: 1px }\", \"a {\\n  garbage;\\n  height: 1px;\\n}\\n\", \"<stdin>: WARNING: Expected \\\":\\\"\\n\")\n\texpectPrinted(t, \"a { !; height: 1px }\", \"a {\\n  !;\\n  height: 1px;\\n}\\n\", \"<stdin>: WARNING: Expected identifier but found \\\"!\\\"\\n\")\n}\n\nfunc TestAtRule(t *testing.T) {\n\texpectPrinted(t, \"@unknown\", \"@unknown;\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found end of file\\n\")\n\texpectPrinted(t, \"@unknown;\", \"@unknown;\\n\", \"\")\n\texpectPrinted(t, \"@unknown{}\", \"@unknown {}\\n\", \"\")\n\texpectPrinted(t, \"@unknown x;\", \"@unknown x;\\n\", \"\")\n\texpectPrinted(t, \"@unknown{\\na: b;\\nc: d;\\n}\", \"@unknown { a: b; c: d; }\\n\", \"\")\n\n\texpectPrinted(t, \"@unknown\", \"@unknown;\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found end of file\\n\")\n\texpectPrinted(t, \"@\", \"@ {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"@\\\"\\n\")\n\texpectPrinted(t, \"@;\", \"@; {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"@\\\"\\n\")\n\texpectPrinted(t, \"@{}\", \"@ {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"@\\\"\\n\")\n\n\texpectPrinted(t, \"@viewport { width: 100vw }\", \"@viewport {\\n  width: 100vw;\\n}\\n\", \"\")\n\texpectPrinted(t, \"@-ms-viewport { width: 100vw }\", \"@-ms-viewport {\\n  width: 100vw;\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"@document url(\\\"https://www.example.com/\\\") { h1 { color: green } }\",\n\t\t\"@document url(https://www.example.com/) {\\n  h1 {\\n    color: green;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@-moz-document url-prefix() { h1 { color: green } }\",\n\t\t\"@-moz-document url-prefix() {\\n  h1 {\\n    color: green;\\n  }\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"@media foo { bar }\", \"@media foo {\\n  bar {\\n  }\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"}\\\"\\n\")\n\texpectPrinted(t, \"@media foo { bar {}\", \"@media foo {\\n  bar {\\n  }\\n}\\n\", \"<stdin>: WARNING: Expected \\\"}\\\" to go with \\\"{\\\"\\n<stdin>: NOTE: The unbalanced \\\"{\\\" is here:\\n\")\n\texpectPrinted(t, \"@media foo {\", \"@media foo {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"}\\\" to go with \\\"{\\\"\\n<stdin>: NOTE: The unbalanced \\\"{\\\" is here:\\n\")\n\texpectPrinted(t, \"@media foo\", \"@media foo {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found end of file\\n\")\n\texpectPrinted(t, \"@media\", \"@media {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found end of file\\n\")\n\n\t// https://www.w3.org/TR/css-page-3/#syntax-page-selector\n\texpectPrinted(t, `\n\t\t@page :first { margin: 0 }\n\t\t@page {\n\t\t\t@top-left-corner { content: 'tlc' }\n\t\t\t@top-left { content: 'tl' }\n\t\t\t@top-center { content: 'tc' }\n\t\t\t@top-right { content: 'tr' }\n\t\t\t@top-right-corner { content: 'trc' }\n\t\t\t@bottom-left-corner { content: 'blc' }\n\t\t\t@bottom-left { content: 'bl' }\n\t\t\t@bottom-center { content: 'bc' }\n\t\t\t@bottom-right { content: 'br' }\n\t\t\t@bottom-right-corner { content: 'brc' }\n\t\t\t@left-top { content: 'lt' }\n\t\t\t@left-middle { content: 'lm' }\n\t\t\t@left-bottom { content: 'lb' }\n\t\t\t@right-top { content: 'rt' }\n\t\t\t@right-middle { content: 'rm' }\n\t\t\t@right-bottom { content: 'rb' }\n\t\t}\n\t`, `@page :first {\n  margin: 0;\n}\n@page {\n  @top-left-corner {\n    content: \"tlc\";\n  }\n  @top-left {\n    content: \"tl\";\n  }\n  @top-center {\n    content: \"tc\";\n  }\n  @top-right {\n    content: \"tr\";\n  }\n  @top-right-corner {\n    content: \"trc\";\n  }\n  @bottom-left-corner {\n    content: \"blc\";\n  }\n  @bottom-left {\n    content: \"bl\";\n  }\n  @bottom-center {\n    content: \"bc\";\n  }\n  @bottom-right {\n    content: \"br\";\n  }\n  @bottom-right-corner {\n    content: \"brc\";\n  }\n  @left-top {\n    content: \"lt\";\n  }\n  @left-middle {\n    content: \"lm\";\n  }\n  @left-bottom {\n    content: \"lb\";\n  }\n  @right-top {\n    content: \"rt\";\n  }\n  @right-middle {\n    content: \"rm\";\n  }\n  @right-bottom {\n    content: \"rb\";\n  }\n}\n`, \"\")\n\n\t// https://drafts.csswg.org/css-fonts-4/#font-palette-values\n\texpectPrinted(t, `\n\t\t@font-palette-values --Augusta {\n\t\t\tfont-family: Handover Sans;\n\t\t\tbase-palette: 3;\n\t\t\toverride-colors: 1 rgb(43, 12, 9), 2 #000, 3 var(--highlight)\n\t\t}\n\t`, `@font-palette-values --Augusta {\n  font-family: Handover Sans;\n  base-palette: 3;\n  override-colors:\n    1 rgb(43, 12, 9),\n    2 #000,\n    3 var(--highlight);\n}\n`, \"\")\n\n\t// https://drafts.csswg.org/css-contain-3/#container-rule\n\texpectPrinted(t, `\n\t\t@container my-layout (inline-size > 45em) {\n\t\t\t.foo {\n\t\t\t\tcolor: skyblue;\n\t\t\t}\n\t\t}\n\t`, `@container my-layout (inline-size > 45em) {\n  .foo {\n    color: skyblue;\n  }\n}\n`, \"\")\n\texpectPrintedMinify(t, `@container card ( inline-size > 30em ) and style( --responsive = true ) {\n\t.foo {\n\t\tcolor: skyblue;\n\t}\n}`, \"@container card (inline-size > 30em) and style(--responsive = true){.foo{color:skyblue}}\", \"\")\n\texpectPrintedMangleMinify(t, `@supports ( container-type: size ) {\n\t@container ( width <= 150px ) {\n\t\t#inner {\n\t\t\tbackground-color: skyblue;\n\t\t}\n\t}\n}`, \"@supports (container-type: size){@container (width <= 150px){#inner{background-color:#87ceeb}}}\", \"\")\n\n\t// https://drafts.csswg.org/css-view-transitions-2/#view-transition-rule\n\texpectPrinted(t, \"@view-transition { navigation: auto; types: check; }\", `@view-transition {\n  navigation: auto;\n  types: check;\n}\n`, \"\")\n\texpectPrintedMinify(t, `@view-transition {\n\tnavigation: auto;\n\ttypes: check;\n}`, \"@view-transition{navigation:auto;types:check}\", \"\")\n\n\t// https://drafts.csswg.org/css-transitions-2/#defining-before-change-style-the-starting-style-rule\n\texpectPrinted(t, `\n\t\t@starting-style {\n\t\t\th1 {\n\t\t\t\tbackground-color: transparent;\n\t\t\t}\n\t\t\t@layer foo {\n\t\t\t\tdiv {\n\t\t\t\t\theight: 100px;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t`, `@starting-style {\n  h1 {\n    background-color: transparent;\n  }\n  @layer foo {\n    div {\n      height: 100px;\n    }\n  }\n}\n`, \"\")\n\n\texpectPrintedMinify(t, `@starting-style {\n\th1 {\n\t\tbackground-color: transparent;\n\t}\n}`, \"@starting-style{h1{background-color:transparent}}\", \"\")\n\n\t// https://drafts.csswg.org/css-counter-styles/#the-counter-style-rule\n\texpectPrinted(t, `\n\t\t@counter-style box-corner {\n\t\t\tsystem: fixed;\n\t\t\tsymbols: ◰ ◳ ◲ ◱;\n\t\t\tsuffix: ': '\n\t\t}\n\t`, `@counter-style box-corner {\n  system: fixed;\n  symbols: ◰ ◳ ◲ ◱;\n  suffix: \": \";\n}\n`, \"\")\n\n\t// https://drafts.csswg.org/css-fonts/#font-feature-values\n\texpectPrinted(t, `\n\t\t@font-feature-values Roboto {\n\t\t\tfont-display: swap;\n\t\t}\n\t`, `@font-feature-values Roboto {\n  font-display: swap;\n}\n`, \"\")\n\texpectPrinted(t, `\n\t\t@font-feature-values Bongo {\n\t\t\t@swash { ornate: 1 }\n\t\t}\n\t`, `@font-feature-values Bongo {\n  @swash {\n    ornate: 1;\n  }\n}\n`, \"\")\n\n\t// https://drafts.csswg.org/css-anchor-position-1/#at-ruledef-position-try\n\texpectPrinted(t, `@position-try --foo { top: 0 }`,\n\t\t`@position-try --foo {\n  top: 0;\n}\n`, \"\")\n\texpectPrintedMinify(t, `@position-try --foo { top: 0; }`, `@position-try --foo{top:0}`, \"\")\n}\n\nfunc TestAtCharset(t *testing.T) {\n\texpectPrinted(t, \"@charset \\\"UTF-8\\\";\", \"@charset \\\"UTF-8\\\";\\n\", \"\")\n\texpectPrinted(t, \"@charset 'UTF-8';\", \"@charset \\\"UTF-8\\\";\\n\", \"\")\n\texpectPrinted(t, \"@charset \\\"utf-8\\\";\", \"@charset \\\"utf-8\\\";\\n\", \"\")\n\texpectPrinted(t, \"@charset \\\"Utf-8\\\";\", \"@charset \\\"Utf-8\\\";\\n\", \"\")\n\texpectPrinted(t, \"@charset \\\"US-ASCII\\\";\", \"@charset \\\"US-ASCII\\\";\\n\", \"<stdin>: WARNING: \\\"UTF-8\\\" will be used instead of unsupported charset \\\"US-ASCII\\\"\\n\")\n\texpectPrinted(t, \"@charset;\", \"@charset;\\n\", \"<stdin>: WARNING: Expected whitespace but found \\\";\\\"\\n\")\n\texpectPrinted(t, \"@charset ;\", \"@charset;\\n\", \"<stdin>: WARNING: Expected string token but found \\\";\\\"\\n\")\n\texpectPrinted(t, \"@charset\\\"UTF-8\\\";\", \"@charset \\\"UTF-8\\\";\\n\", \"<stdin>: WARNING: Expected whitespace but found \\\"\\\\\\\"UTF-8\\\\\\\"\\\"\\n\")\n\texpectPrinted(t, \"@charset \\\"UTF-8\\\"\", \"@charset \\\"UTF-8\\\";\\n\", \"<stdin>: WARNING: Expected \\\";\\\" but found end of file\\n\")\n\texpectPrinted(t, \"@charset url(UTF-8);\", \"@charset url(UTF-8);\\n\", \"<stdin>: WARNING: Expected string token but found \\\"url(UTF-8)\\\"\\n\")\n\texpectPrinted(t, \"@charset url(\\\"UTF-8\\\");\", \"@charset url(UTF-8);\\n\", \"<stdin>: WARNING: Expected string token but found \\\"url(\\\"\\n\")\n\texpectPrinted(t, \"@charset \\\"UTF-8\\\" \", \"@charset \\\"UTF-8\\\";\\n\", \"<stdin>: WARNING: Expected \\\";\\\" but found whitespace\\n\")\n\texpectPrinted(t, \"@charset \\\"UTF-8\\\"{}\", \"@charset \\\"UTF-8\\\";\\n {\\n}\\n\", \"<stdin>: WARNING: Expected \\\";\\\" but found \\\"{\\\"\\n\")\n}\n\nfunc TestAtImport(t *testing.T) {\n\texpectPrinted(t, \"@import\\\"foo.css\\\";\", \"@import \\\"foo.css\\\";\\n\", \"\")\n\texpectPrinted(t, \"@import \\\"foo.css\\\";\", \"@import \\\"foo.css\\\";\\n\", \"\")\n\texpectPrinted(t, \"@import \\\"foo.css\\\" ;\", \"@import \\\"foo.css\\\";\\n\", \"\")\n\texpectPrinted(t, \"@import url();\", \"@import \\\"\\\";\\n\", \"\")\n\texpectPrinted(t, \"@import url(foo.css);\", \"@import \\\"foo.css\\\";\\n\", \"\")\n\texpectPrinted(t, \"@import url(foo.css) ;\", \"@import \\\"foo.css\\\";\\n\", \"\")\n\texpectPrinted(t, \"@import url( foo.css );\", \"@import \\\"foo.css\\\";\\n\", \"\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\");\", \"@import \\\"foo.css\\\";\\n\", \"\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\") ;\", \"@import \\\"foo.css\\\";\\n\", \"\")\n\texpectPrinted(t, \"@import url( \\\"foo.css\\\" );\", \"@import \\\"foo.css\\\";\\n\", \"\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\") print;\", \"@import \\\"foo.css\\\" print;\\n\", \"\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\") screen and (orientation:landscape);\", \"@import \\\"foo.css\\\" screen and (orientation: landscape);\\n\", \"\")\n\n\texpectPrinted(t, \"@import;\", \"@import;\\n\", \"<stdin>: WARNING: Expected URL token but found \\\";\\\"\\n\")\n\texpectPrinted(t, \"@import ;\", \"@import;\\n\", \"<stdin>: WARNING: Expected URL token but found \\\";\\\"\\n\")\n\texpectPrinted(t, \"@import \\\"foo.css\\\"\", \"@import \\\"foo.css\\\";\\n\", \"<stdin>: WARNING: Expected \\\";\\\" but found end of file\\n\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\" extra-stuff);\", \"@import url(\\\"foo.css\\\" extra-stuff);\\n\", \"<stdin>: WARNING: Expected URL token but found \\\"url(\\\"\\n\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\";\", \"@import url(\\\"foo.css\\\";);\\n\",\n\t\t\"<stdin>: WARNING: Expected URL token but found \\\"url(\\\"\\n<stdin>: WARNING: Expected \\\")\\\" to go with \\\"(\\\"\\n<stdin>: NOTE: The unbalanced \\\"(\\\" is here:\\n\")\n\texpectPrinted(t, \"@import noturl(\\\"foo.css\\\");\", \"@import noturl(\\\"foo.css\\\");\\n\", \"<stdin>: WARNING: Expected URL token but found \\\"noturl(\\\"\\n\")\n\texpectPrinted(t, \"@import url(foo.css\", \"@import \\\"foo.css\\\";\\n\", `<stdin>: WARNING: Expected \")\" to end URL token\n<stdin>: NOTE: The unbalanced \"(\" is here:\n<stdin>: WARNING: Expected \";\" but found end of file\n`)\n\n\texpectPrinted(t, \"@import \\\"foo.css\\\" {}\", \"@import \\\"foo.css\\\" {}\\n\", \"<stdin>: WARNING: Expected \\\";\\\"\\n\")\n\texpectPrinted(t, \"@import \\\"foo\\\"\\na { color: red }\\nb { color: blue }\", \"@import \\\"foo\\\" a { color: red }\\nb {\\n  color: blue;\\n}\\n\", \"<stdin>: WARNING: Expected \\\";\\\"\\n\")\n\n\texpectPrinted(t, \"a { @import \\\"foo.css\\\" }\", \"a {\\n  @import \\\"foo.css\\\";\\n}\\n\", \"<stdin>: WARNING: \\\"@import\\\" is only valid at the top level\\n<stdin>: WARNING: Expected \\\";\\\"\\n\")\n}\n\nfunc TestLowerAtImportMediaRange(t *testing.T) {\n\texpectPrinted(t, \"@import \\\"foo.css\\\" (1px<=width<=2px);\", \"@import \\\"foo.css\\\" (1px <= width <= 2px);\\n\", \"\")\n\texpectPrintedLower(t, \"@import \\\"foo.css\\\" (1px<=width<=2px);\", \"@import \\\"foo.css\\\" (min-width: 1px) and (max-width: 2px);\\n\", \"\")\n}\n\nfunc TestLegalComment(t *testing.T) {\n\texpectPrinted(t, \"/*!*/@import \\\"x\\\";\", \"/*!*/\\n@import \\\"x\\\";\\n\", \"\")\n\texpectPrinted(t, \"/*!*/@charset \\\"UTF-8\\\";\", \"/*!*/\\n@charset \\\"UTF-8\\\";\\n\", \"\")\n\texpectPrinted(t, \"/*!*/ @import \\\"x\\\";\", \"/*!*/\\n@import \\\"x\\\";\\n\", \"\")\n\texpectPrinted(t, \"/*!*/ @charset \\\"UTF-8\\\";\", \"/*!*/\\n@charset \\\"UTF-8\\\";\\n\", \"\")\n\texpectPrinted(t, \"/*!*/ @charset \\\"UTF-8\\\"; @import \\\"x\\\";\", \"/*!*/\\n@charset \\\"UTF-8\\\";\\n@import \\\"x\\\";\\n\", \"\")\n\texpectPrinted(t, \"/*!*/ @import \\\"x\\\"; @charset \\\"UTF-8\\\";\", \"/*!*/\\n@import \\\"x\\\";\\n@charset \\\"UTF-8\\\";\\n\",\n\t\t\"<stdin>: WARNING: \\\"@charset\\\" must be the first rule in the file\\n\"+\n\t\t\t\"<stdin>: NOTE: This rule cannot come before a \\\"@charset\\\" rule\\n\")\n\n\texpectPrinted(t, \"@import \\\"x\\\";/*!*/\", \"@import \\\"x\\\";\\n/*!*/\\n\", \"\")\n\texpectPrinted(t, \"@charset \\\"UTF-8\\\";/*!*/\", \"@charset \\\"UTF-8\\\";\\n/*!*/\\n\", \"\")\n\texpectPrinted(t, \"@import \\\"x\\\"; /*!*/\", \"@import \\\"x\\\";\\n/*!*/\\n\", \"\")\n\texpectPrinted(t, \"@charset \\\"UTF-8\\\"; /*!*/\", \"@charset \\\"UTF-8\\\";\\n/*!*/\\n\", \"\")\n\n\texpectPrinted(t, \"/*! before */ a { --b: var(--c, /*!*/ /*!*/); } /*! after */\\n\", \"/*! before */\\na {\\n  --b: var(--c, );\\n}\\n/*! after */\\n\", \"\")\n}\n\nfunc TestAtKeyframes(t *testing.T) {\n\texpectPrinted(t, \"@keyframes {}\", \"@keyframes {}\\n\", \"<stdin>: WARNING: Expected identifier but found \\\"{\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name{}\", \"@keyframes name {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes name {}\", \"@keyframes name {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes name{0%,50%{color:red}25%,75%{color:blue}}\",\n\t\t\"@keyframes name {\\n  0%, 50% {\\n    color: red;\\n  }\\n  25%, 75% {\\n    color: blue;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes name { 0%, 50% { color: red } 25%, 75% { color: blue } }\",\n\t\t\"@keyframes name {\\n  0%, 50% {\\n    color: red;\\n  }\\n  25%, 75% {\\n    color: blue;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes name{from{color:red}to{color:blue}}\",\n\t\t\"@keyframes name {\\n  from {\\n    color: red;\\n  }\\n  to {\\n    color: blue;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes name { from { color: red } to { color: blue } }\",\n\t\t\"@keyframes name {\\n  from {\\n    color: red;\\n  }\\n  to {\\n    color: blue;\\n  }\\n}\\n\", \"\")\n\n\t// Note: Strings as names is allowed in the CSS specification and works in\n\t// Firefox and Safari but Chrome has strangely decided to deliberately not\n\t// support this. We always turn all string names into identifiers to avoid\n\t// them silently breaking in Chrome.\n\texpectPrinted(t, \"@keyframes 'name' {}\", \"@keyframes name {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes 'name 2' {}\", \"@keyframes name\\\\ 2 {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes 'none' {}\", \"@keyframes \\\"none\\\" {}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes 'None' {}\", \"@keyframes \\\"None\\\" {}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes 'unset' {}\", \"@keyframes \\\"unset\\\" {}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes 'revert' {}\", \"@keyframes \\\"revert\\\" {}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes None {}\", \"@keyframes None {}\\n\",\n\t\t\"<stdin>: WARNING: Cannot use \\\"None\\\" as a name for \\\"@keyframes\\\" without quotes\\n\"+\n\t\t\t\"NOTE: You can put \\\"None\\\" in quotes to prevent it from becoming a CSS keyword.\\n\")\n\texpectPrinted(t, \"@keyframes REVERT {}\", \"@keyframes REVERT {}\\n\",\n\t\t\"<stdin>: WARNING: Cannot use \\\"REVERT\\\" as a name for \\\"@keyframes\\\" without quotes\\n\"+\n\t\t\t\"NOTE: You can put \\\"REVERT\\\" in quotes to prevent it from becoming a CSS keyword.\\n\")\n\n\texpectPrinted(t, \"@keyframes name { from { color: red } }\", \"@keyframes name {\\n  from {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes name { 100% { color: red } }\", \"@keyframes name {\\n  100% {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@keyframes name { from { color: red } }\", \"@keyframes name {\\n  0% {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@keyframes name { 100% { color: red } }\", \"@keyframes name {\\n  to {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"@-webkit-keyframes name {}\", \"@-webkit-keyframes name {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@-moz-keyframes name {}\", \"@-moz-keyframes name {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@-ms-keyframes name {}\", \"@-ms-keyframes name {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@-o-keyframes name {}\", \"@-o-keyframes name {\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"@keyframes {}\", \"@keyframes {}\\n\", \"<stdin>: WARNING: Expected identifier but found \\\"{\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name { 0% 100% {} }\", \"@keyframes name { 0% 100% {} }\\n\", \"<stdin>: WARNING: Expected \\\",\\\" but found \\\"100%\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name { {} 0% {} }\", \"@keyframes name { {} 0% {} }\\n\", \"<stdin>: WARNING: Expected percentage but found \\\"{\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name { 100 {} }\", \"@keyframes name { 100 {} }\\n\", \"<stdin>: WARNING: Expected percentage but found \\\"100\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name { into {} }\", \"@keyframes name {\\n  into {\\n  }\\n}\\n\", \"<stdin>: WARNING: Expected percentage but found \\\"into\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name { 1,2 {} }\", \"@keyframes name { 1, 2 {} }\\n\", \"<stdin>: WARNING: Expected percentage but found \\\"1\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name { 1, 2 {} }\", \"@keyframes name { 1, 2 {} }\\n\", \"<stdin>: WARNING: Expected percentage but found \\\"1\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name { 1 ,2 {} }\", \"@keyframes name { 1, 2 {} }\\n\", \"<stdin>: WARNING: Expected percentage but found \\\"1\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name { 1%, {} }\", \"@keyframes name { 1%, {} }\\n\", \"<stdin>: WARNING: Expected percentage but found \\\"{\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name { 1%, x {} }\", \"@keyframes name {\\n  1%, x {\\n  }\\n}\\n\", \"<stdin>: WARNING: Expected percentage but found \\\"x\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name { 1%, ! {} }\", \"@keyframes name { 1%, ! {} }\\n\", \"<stdin>: WARNING: Expected percentage but found \\\"!\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name { .x {} }\", \"@keyframes name { .x {} }\\n\", \"<stdin>: WARNING: Expected percentage but found \\\".\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name { {} }\", \"@keyframes name { {} }\\n\", \"<stdin>: WARNING: Expected percentage but found \\\"{\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name { 1% }\", \"@keyframes name { 1% }\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found \\\"}\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name { 1%\", \"@keyframes name { 1% }\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found end of file\\n\")\n\texpectPrinted(t, \"@keyframes name { 1%,,2% {} }\", \"@keyframes name { 1%,, 2% {} }\\n\", \"<stdin>: WARNING: Expected percentage but found \\\",\\\"\\n\")\n\texpectPrinted(t, \"@keyframes name {\", \"@keyframes name {}\\n\", \"<stdin>: WARNING: Expected \\\"}\\\" to go with \\\"{\\\"\\n<stdin>: NOTE: The unbalanced \\\"{\\\" is here:\\n\")\n\n\texpectPrinted(t, \"@keyframes x { 1%, {} } @keyframes z { 1% {} }\", \"@keyframes x { 1%, {} }\\n@keyframes z {\\n  1% {\\n  }\\n}\\n\", \"<stdin>: WARNING: Expected percentage but found \\\"{\\\"\\n\")\n\texpectPrinted(t, \"@keyframes x { .y {} } @keyframes z { 1% {} }\", \"@keyframes x { .y {} }\\n@keyframes z {\\n  1% {\\n  }\\n}\\n\", \"<stdin>: WARNING: Expected percentage but found \\\".\\\"\\n\")\n\texpectPrinted(t, \"@keyframes x { x {} } @keyframes z { 1% {} }\", \"@keyframes x {\\n  x {\\n  }\\n}\\n@keyframes z {\\n  1% {\\n  }\\n}\\n\", \"<stdin>: WARNING: Expected percentage but found \\\"x\\\"\\n\")\n\texpectPrinted(t, \"@keyframes x { {} } @keyframes z { 1% {} }\", \"@keyframes x { {} }\\n@keyframes z {\\n  1% {\\n  }\\n}\\n\", \"<stdin>: WARNING: Expected percentage but found \\\"{\\\"\\n\")\n\texpectPrinted(t, \"@keyframes x { 1% {}\", \"@keyframes x { 1% {} }\\n\", \"<stdin>: WARNING: Expected \\\"}\\\" to go with \\\"{\\\"\\n<stdin>: NOTE: The unbalanced \\\"{\\\" is here:\\n\")\n\texpectPrinted(t, \"@keyframes x { 1% {\", \"@keyframes x { 1% {} }\\n\", \"<stdin>: WARNING: Expected \\\"}\\\" to go with \\\"{\\\"\\n<stdin>: NOTE: The unbalanced \\\"{\\\" is here:\\n\")\n\texpectPrinted(t, \"@keyframes x { 1%\", \"@keyframes x { 1% }\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found end of file\\n\")\n\texpectPrinted(t, \"@keyframes x {\", \"@keyframes x {}\\n\", \"<stdin>: WARNING: Expected \\\"}\\\" to go with \\\"{\\\"\\n<stdin>: NOTE: The unbalanced \\\"{\\\" is here:\\n\")\n}\n\nfunc TestAnimationName(t *testing.T) {\n\t// Note: Strings as names is allowed in the CSS specification and works in\n\t// Firefox and Safari but Chrome has strangely decided to deliberately not\n\t// support this. We always turn all string names into identifiers to avoid\n\t// them silently breaking in Chrome.\n\texpectPrinted(t, \"div { animation-name: 'name' }\", \"div {\\n  animation-name: name;\\n}\\n\", \"\")\n\texpectPrinted(t, \"div { animation-name: 'name 2' }\", \"div {\\n  animation-name: name\\\\ 2;\\n}\\n\", \"\")\n\texpectPrinted(t, \"div { animation-name: 'none' }\", \"div {\\n  animation-name: \\\"none\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"div { animation-name: 'None' }\", \"div {\\n  animation-name: \\\"None\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"div { animation-name: 'unset' }\", \"div {\\n  animation-name: \\\"unset\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"div { animation-name: 'revert' }\", \"div {\\n  animation-name: \\\"revert\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"div { animation-name: none }\", \"div {\\n  animation-name: none;\\n}\\n\", \"\")\n\texpectPrinted(t, \"div { animation-name: unset }\", \"div {\\n  animation-name: unset;\\n}\\n\", \"\")\n\texpectPrinted(t, \"div { animation: 2s linear 'name 2', 3s infinite 'name 3' }\", \"div {\\n  animation: 2s linear name\\\\ 2, 3s infinite name\\\\ 3;\\n}\\n\", \"\")\n}\n\nfunc TestAtRuleValidation(t *testing.T) {\n\texpectPrinted(t, \"a {} b {} c {} @charset \\\"UTF-8\\\";\", \"a {\\n}\\nb {\\n}\\nc {\\n}\\n@charset \\\"UTF-8\\\";\\n\",\n\t\t\"<stdin>: WARNING: \\\"@charset\\\" must be the first rule in the file\\n\"+\n\t\t\t\"<stdin>: NOTE: This rule cannot come before a \\\"@charset\\\" rule\\n\")\n\n\texpectPrinted(t, \"a {} b {} c {} @import \\\"foo\\\";\", \"a {\\n}\\nb {\\n}\\nc {\\n}\\n@import \\\"foo\\\";\\n\",\n\t\t\"<stdin>: WARNING: All \\\"@import\\\" rules must come first\\n\"+\n\t\t\t\"<stdin>: NOTE: This rule cannot come before an \\\"@import\\\" rule\\n\")\n}\n\nfunc TestAtLayer(t *testing.T) {\n\texpectPrinted(t, \"@layer a, b;\", \"@layer a, b;\\n\", \"\")\n\texpectPrinted(t, \"@layer a {}\", \"@layer a {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@layer {}\", \"@layer {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@layer a, b {}\", \"@layer a, b {\\n}\\n\", \"<stdin>: WARNING: Expected \\\";\\\"\\n\")\n\texpectPrinted(t, \"@layer;\", \"@layer;\\n\", \"<stdin>: WARNING: Unexpected \\\";\\\"\\n\")\n\texpectPrinted(t, \"@layer , b {}\", \"@layer , b {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\",\\\"\\n\")\n\texpectPrinted(t, \"@layer a\", \"@layer a;\\n\", \"<stdin>: WARNING: Expected \\\";\\\" but found end of file\\n\")\n\texpectPrinted(t, \"@layer a { @layer b }\", \"@layer a {\\n  @layer b;\\n}\\n\", \"<stdin>: WARNING: Expected \\\";\\\"\\n\")\n\texpectPrinted(t, \"@layer a b\", \"@layer a b;\\n\", \"<stdin>: WARNING: Unexpected \\\"b\\\"\\n<stdin>: WARNING: Expected \\\";\\\" but found end of file\\n\")\n\texpectPrinted(t, \"@layer a b ;\", \"@layer a b;\\n\", \"<stdin>: WARNING: Unexpected \\\"b\\\"\\n\")\n\texpectPrinted(t, \"@layer a b {}\", \"@layer a b {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"b\\\"\\n\")\n\n\texpectPrinted(t, \"@layer a, b;\", \"@layer a, b;\\n\", \"\")\n\texpectPrinted(t, \"@layer a {}\", \"@layer a {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@layer {}\", \"@layer {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@layer foo { div { color: red } }\", \"@layer foo {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\t// Check semicolon error recovery\n\texpectPrinted(t, \"@layer\", \"@layer;\\n\", \"<stdin>: WARNING: Expected \\\";\\\" but found end of file\\n\")\n\texpectPrinted(t, \"@layer a\", \"@layer a;\\n\", \"<stdin>: WARNING: Expected \\\";\\\" but found end of file\\n\")\n\texpectPrinted(t, \"@layer a { @layer }\", \"@layer a {\\n  @layer;\\n}\\n\", \"<stdin>: WARNING: Expected \\\";\\\"\\n\")\n\texpectPrinted(t, \"@layer a { @layer b }\", \"@layer a {\\n  @layer b;\\n}\\n\", \"<stdin>: WARNING: Expected \\\";\\\"\\n\")\n\texpectPrintedMangle(t, \"@layer\", \"@layer;\\n\", \"<stdin>: WARNING: Expected \\\";\\\" but found end of file\\n\")\n\texpectPrintedMangle(t, \"@layer a\", \"@layer a;\\n\", \"<stdin>: WARNING: Expected \\\";\\\" but found end of file\\n\")\n\texpectPrintedMangle(t, \"@layer a { @layer }\", \"@layer a {\\n  @layer;\\n}\\n\", \"<stdin>: WARNING: Expected \\\";\\\"\\n\")\n\texpectPrintedMangle(t, \"@layer a { @layer b }\", \"@layer a.b;\\n\", \"<stdin>: WARNING: Expected \\\";\\\"\\n\")\n\n\t// Check mangling\n\texpectPrintedMangle(t, \"@layer foo { div {} }\", \"@layer foo;\\n\", \"\")\n\texpectPrintedMangle(t, \"@layer foo { div { color: yellow } }\", \"@layer foo {\\n  div {\\n    color: #ff0;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@layer a { @layer b {} }\", \"@layer a.b;\\n\", \"\")\n\texpectPrintedMangle(t, \"@layer a { @layer {} }\", \"@layer a {\\n  @layer {\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@layer { @layer a {} }\", \"@layer {\\n  @layer a;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@layer a.b { @layer c.d {} }\", \"@layer a.b.c.d;\\n\", \"\")\n\texpectPrintedMangle(t, \"@layer a.b { @layer c.d {} @layer e.f {} }\", \"@layer a.b {\\n  @layer c.d;\\n  @layer e.f;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@layer a.b { @layer c.d { e { f: g } } }\", \"@layer a.b.c.d {\\n  e {\\n    f: g;\\n  }\\n}\\n\", \"\")\n\n\t// Invalid layer names should not be merged, since that causes the rule to\n\t// become invalid. It would be a change in semantics if we merged an invalid\n\t// rule with a valid rule since then the other valid rule would be invalid.\n\tinitial := \"<stdin>: WARNING: \\\"initial\\\" cannot be used as a layer name\\n\"\n\tinherit := \"<stdin>: WARNING: \\\"inherit\\\" cannot be used as a layer name\\n\"\n\tunset := \"<stdin>: WARNING: \\\"unset\\\" cannot be used as a layer name\\n\"\n\texpectPrinted(t, \"@layer foo { @layer initial; }\", \"@layer foo {\\n  @layer initial;\\n}\\n\", initial)\n\texpectPrinted(t, \"@layer foo { @layer inherit; }\", \"@layer foo {\\n  @layer inherit;\\n}\\n\", inherit)\n\texpectPrinted(t, \"@layer foo { @layer unset; }\", \"@layer foo {\\n  @layer unset;\\n}\\n\", unset)\n\texpectPrinted(t, \"@layer initial { @layer foo; }\", \"@layer initial {\\n  @layer foo;\\n}\\n\", initial)\n\texpectPrinted(t, \"@layer inherit { @layer foo; }\", \"@layer inherit {\\n  @layer foo;\\n}\\n\", inherit)\n\texpectPrinted(t, \"@layer unset { @layer foo; }\", \"@layer unset {\\n  @layer foo;\\n}\\n\", unset)\n\texpectPrintedMangle(t, \"@layer foo { @layer initial { a { b: c } } }\", \"@layer foo {\\n  @layer initial {\\n    a {\\n      b: c;\\n    }\\n  }\\n}\\n\", initial)\n\texpectPrintedMangle(t, \"@layer initial { @layer foo { a { b: c } } }\", \"@layer initial {\\n  @layer foo {\\n    a {\\n      b: c;\\n    }\\n  }\\n}\\n\", initial)\n\n\t// Order matters here. Do not drop the first \"@layer a;\" or the order will be changed.\n\texpectPrintedMangle(t, \"@layer a; @layer b; @layer a;\", \"@layer a;\\n@layer b;\\n@layer a;\\n\", \"\")\n\n\t// Validate ordering with \"@layer\" and \"@import\"\n\texpectPrinted(t, \"@layer a; @import url(b);\", \"@layer a;\\n@import \\\"b\\\";\\n\", \"\")\n\texpectPrinted(t, \"@layer a; @layer b; @import url(c);\", \"@layer a;\\n@layer b;\\n@import \\\"c\\\";\\n\", \"\")\n\texpectPrinted(t, \"@layer a {} @import url(b);\", \"@layer a {\\n}\\n@import url(b);\\n\",\n\t\t\"<stdin>: WARNING: All \\\"@import\\\" rules must come first\\n<stdin>: NOTE: This rule cannot come before an \\\"@import\\\" rule\\n\")\n\texpectPrinted(t, \"@import url(a); @layer b; @import url(c);\", \"@import \\\"a\\\";\\n@layer b;\\n@import url(c);\\n\",\n\t\t\"<stdin>: WARNING: All \\\"@import\\\" rules must come first\\n<stdin>: NOTE: This rule cannot come before an \\\"@import\\\" rule\\n\")\n\texpectPrinted(t, \"@layer a; @charset \\\"UTF-8\\\";\", \"@layer a;\\n@charset \\\"UTF-8\\\";\\n\",\n\t\t\"<stdin>: WARNING: \\\"@charset\\\" must be the first rule in the file\\n<stdin>: NOTE: This rule cannot come before a \\\"@charset\\\" rule\\n\")\n}\n\nfunc TestEmptyRule(t *testing.T) {\n\texpectPrinted(t, \"div {}\", \"div {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media screen {}\", \"@media screen {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@page { @top-left {} }\", \"@page {\\n  @top-left {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes test { from {} to {} }\", \"@keyframes test {\\n  from {\\n  }\\n  to {\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"div {}\", \"\", \"\")\n\texpectPrintedMangle(t, \"@media screen {}\", \"\", \"\")\n\texpectPrintedMangle(t, \"@page { @top-left {} }\", \"\", \"\")\n\texpectPrintedMangle(t, \"@keyframes test { from {} to {} }\", \"@keyframes test {\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"$invalid {}\", \"$invalid {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"$\\\"\\n\")\n\texpectPrinted(t, \"@page { color: red; @top-left {} }\", \"@page {\\n  color: red;\\n  @top-left {\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes test { from {} to { color: red } }\", \"@keyframes test {\\n  from {\\n  }\\n  to {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@keyframes test { from { color: red } to {} }\", \"@keyframes test {\\n  from {\\n    color: red;\\n  }\\n  to {\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"$invalid {}\", \"$invalid {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"$\\\"\\n\")\n\texpectPrintedMangle(t, \"@page { color: red; @top-left {} }\", \"@page {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@keyframes test { from {} to { color: red } }\", \"@keyframes test {\\n  to {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@keyframes test { from { color: red } to {} }\", \"@keyframes test {\\n  0% {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedMangleMinify(t, \"$invalid {}\", \"$invalid{}\", \"<stdin>: WARNING: Unexpected \\\"$\\\"\\n\")\n\texpectPrintedMangleMinify(t, \"@page { color: red; @top-left {} }\", \"@page{color:red}\", \"\")\n\texpectPrintedMangleMinify(t, \"@keyframes test { from {} to { color: red } }\", \"@keyframes test{to{color:red}}\", \"\")\n\texpectPrintedMangleMinify(t, \"@keyframes test { from { color: red } to {} }\", \"@keyframes test{0%{color:red}}\", \"\")\n\n\texpectPrinted(t, \"invalid\", \"invalid {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found end of file\\n\")\n\texpectPrinted(t, \"invalid }\", \"invalid } {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"}\\\"\\n\")\n}\n\nfunc TestMarginAndPaddingAndInset(t *testing.T) {\n\tfor _, x := range []string{\"margin\", \"padding\", \"inset\"} {\n\t\txTop := x + \"-top\"\n\t\txRight := x + \"-right\"\n\t\txBottom := x + \"-bottom\"\n\t\txLeft := x + \"-left\"\n\t\tif x == \"inset\" {\n\t\t\txTop = \"top\"\n\t\t\txRight = \"right\"\n\t\t\txBottom = \"bottom\"\n\t\t\txLeft = \"left\"\n\t\t}\n\n\t\texpectPrinted(t, \"a { \"+x+\": 0 1px 0 1px }\", \"a {\\n  \"+x+\": 0 1px 0 1px;\\n}\\n\", \"\")\n\t\texpectPrinted(t, \"a { \"+x+\": 0 1px 0px 1px }\", \"a {\\n  \"+x+\": 0 1px 0px 1px;\\n}\\n\", \"\")\n\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 0px }\", \"a {\\n  \"+xTop+\": 0;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xRight+\": 0px }\", \"a {\\n  \"+xRight+\": 0;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xBottom+\": 0px }\", \"a {\\n  \"+xBottom+\": 0;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 0px }\", \"a {\\n  \"+xLeft+\": 0;\\n}\\n\", \"\")\n\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 1px }\", \"a {\\n  \"+xTop+\": 1px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xRight+\": 1px }\", \"a {\\n  \"+xRight+\": 1px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xBottom+\": 1px }\", \"a {\\n  \"+xBottom+\": 1px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px }\", \"a {\\n  \"+xLeft+\": 1px;\\n}\\n\", \"\")\n\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 0 0 }\", \"a {\\n  \"+x+\": 0 1px 0 0;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 2px 1px }\", \"a {\\n  \"+x+\": 0 1px 2px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 0 1px }\", \"a {\\n  \"+x+\": 0 1px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 0 0 0 }\", \"a {\\n  \"+x+\": 0;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 0 0 0 !important }\", \"a {\\n  \"+x+\": 0 !important;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 0px 1px }\", \"a {\\n  \"+x+\": 0 1px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1 0px 1px }\", \"a {\\n  \"+x+\": 0 1 0px 1px;\\n}\\n\", \"\")\n\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px; \"+xTop+\": 5px }\", \"a {\\n  \"+x+\": 5px 2px 3px 4px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px; \"+xRight+\": 5px }\", \"a {\\n  \"+x+\": 1px 5px 3px 4px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px; \"+xBottom+\": 5px }\", \"a {\\n  \"+x+\": 1px 2px 5px 4px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px; \"+xLeft+\": 5px }\", \"a {\\n  \"+x+\": 1px 2px 3px 5px;\\n}\\n\", \"\")\n\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 5px; \"+x+\": 1px 2px 3px 4px }\", \"a {\\n  \"+x+\": 1px 2px 3px 4px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xRight+\": 5px; \"+x+\": 1px 2px 3px 4px }\", \"a {\\n  \"+x+\": 1px 2px 3px 4px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xBottom+\": 5px; \"+x+\": 1px 2px 3px 4px }\", \"a {\\n  \"+x+\": 1px 2px 3px 4px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 5px; \"+x+\": 1px 2px 3px 4px }\", \"a {\\n  \"+x+\": 1px 2px 3px 4px;\\n}\\n\", \"\")\n\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 1px; \"+xTop+\": 2px }\", \"a {\\n  \"+xTop+\": 2px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xRight+\": 1px; \"+xRight+\": 2px }\", \"a {\\n  \"+xRight+\": 2px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xBottom+\": 1px; \"+xBottom+\": 2px }\", \"a {\\n  \"+xBottom+\": 2px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px; \"+xLeft+\": 2px }\", \"a {\\n  \"+xLeft+\": 2px;\\n}\\n\", \"\")\n\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px; \"+x+\": 2px !important }\",\n\t\t\t\"a {\\n  \"+x+\": 1px;\\n  \"+x+\": 2px !important;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 1px; \"+xTop+\": 2px !important }\",\n\t\t\t\"a {\\n  \"+xTop+\": 1px;\\n  \"+xTop+\": 2px !important;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xRight+\": 1px; \"+xRight+\": 2px !important }\",\n\t\t\t\"a {\\n  \"+xRight+\": 1px;\\n  \"+xRight+\": 2px !important;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xBottom+\": 1px; \"+xBottom+\": 2px !important }\",\n\t\t\t\"a {\\n  \"+xBottom+\": 1px;\\n  \"+xBottom+\": 2px !important;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px; \"+xLeft+\": 2px !important }\",\n\t\t\t\"a {\\n  \"+xLeft+\": 1px;\\n  \"+xLeft+\": 2px !important;\\n}\\n\", \"\")\n\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px !important; \"+x+\": 2px }\",\n\t\t\t\"a {\\n  \"+x+\": 1px !important;\\n  \"+x+\": 2px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 1px !important; \"+xTop+\": 2px }\",\n\t\t\t\"a {\\n  \"+xTop+\": 1px !important;\\n  \"+xTop+\": 2px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xRight+\": 1px !important; \"+xRight+\": 2px }\",\n\t\t\t\"a {\\n  \"+xRight+\": 1px !important;\\n  \"+xRight+\": 2px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xBottom+\": 1px !important; \"+xBottom+\": 2px }\",\n\t\t\t\"a {\\n  \"+xBottom+\": 1px !important;\\n  \"+xBottom+\": 2px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px !important; \"+xLeft+\": 2px }\",\n\t\t\t\"a {\\n  \"+xLeft+\": 1px !important;\\n  \"+xLeft+\": 2px;\\n}\\n\", \"\")\n\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 1px; \"+xTop+\": }\", \"a {\\n  \"+xTop+\": 1px;\\n  \"+xTop+\":;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 1px; \"+xTop+\": 2px 3px }\", \"a {\\n  \"+xTop+\": 1px;\\n  \"+xTop+\": 2px 3px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px; \"+xLeft+\": -4px; \"+xRight+\": -2px }\", \"a {\\n  \"+x+\": 1px -2px 3px -4px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px; \"+xTop+\": 5px }\", \"a {\\n  \"+x+\": 5px 2px 1px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px; \"+xTop+\": 5px }\", \"a {\\n  \"+x+\": 5px 1px 1px;\\n}\\n\", \"\")\n\n\t\t// This doesn't collapse because if the \"calc\" has an error it\n\t\t// will be ignored and the original rule will show through\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px; \"+xRight+\": calc(1px + var(--x)) }\",\n\t\t\t\"a {\\n  \"+x+\": 1px 2px 3px 4px;\\n  \"+xRight+\": calc(1px + var(--x));\\n}\\n\", \"\")\n\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px; \"+xRight+\": 2px; \"+xTop+\": 3px; \"+xBottom+\": 4px }\", \"a {\\n  \"+x+\": 3px 2px 4px 1px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px; \"+xRight+\": 5px !important }\",\n\t\t\t\"a {\\n  \"+x+\": 1px 2px 3px 4px;\\n  \"+xRight+\": 5px !important;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px !important; \"+xRight+\": 5px }\",\n\t\t\t\"a {\\n  \"+x+\": 1px 2px 3px 4px !important;\\n  \"+xRight+\": 5px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px !important; \"+xRight+\": 2px; \"+xTop+\": 3px !important; \"+xBottom+\": 4px }\",\n\t\t\t\"a {\\n  \"+xLeft+\": 1px !important;\\n  \"+xRight+\": 2px;\\n  \"+xTop+\": 3px !important;\\n  \"+xBottom+\": 4px;\\n}\\n\", \"\")\n\n\t\t// This should not be changed because \"--x\" and \"--z\" could be empty\n\t\texpectPrintedMangle(t, \"a { \"+x+\": var(--x) var(--y) var(--z) var(--y) }\", \"a {\\n  \"+x+\": var(--x) var(--y) var(--z) var(--y);\\n}\\n\", \"\")\n\n\t\t// Don't merge different units\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px; \"+x+\": 2px; }\", \"a {\\n  \"+x+\": 2px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px; \"+x+\": 2vw; }\", \"a {\\n  \"+x+\": 1px;\\n  \"+x+\": 2vw;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px; \"+xLeft+\": 2px; }\", \"a {\\n  \"+xLeft+\": 2px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px; \"+xLeft+\": 2vw; }\", \"a {\\n  \"+xLeft+\": 1px;\\n  \"+xLeft+\": 2vw;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 2cm 3%; \"+x+\": 4px; }\", \"a {\\n  \"+x+\": 4px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 2cm 3%; \"+x+\": 4vw; }\", \"a {\\n  \"+x+\": 0 1px 2cm 3%;\\n  \"+x+\": 4vw;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 2cm 3%; \"+xLeft+\": 4px; }\", \"a {\\n  \"+x+\": 0 1px 2cm 4px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 2cm 3%; \"+xLeft+\": 4vw; }\", \"a {\\n  \"+x+\": 0 1px 2cm 3%;\\n  \"+xLeft+\": 4vw;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1Q; \"+xRight+\": 2Q; \"+xTop+\": 3Q; \"+xBottom+\": 4Q; }\", \"a {\\n  \"+x+\": 3Q 2Q 4Q 1Q;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1Q; \"+xRight+\": 2Q; \"+xTop+\": 3Q; \"+xBottom+\": 0; }\",\n\t\t\t\"a {\\n  \"+xLeft+\": 1Q;\\n  \"+xRight+\": 2Q;\\n  \"+xTop+\": 3Q;\\n  \"+xBottom+\": 0;\\n}\\n\", \"\")\n\t}\n\n\t// \"auto\" is the only keyword allowed in a quad, and only for \"margin\" and \"inset\" not for \"padding\"\n\texpectPrintedMangle(t, \"a { margin: 1px auto 3px 4px; margin-left: auto }\", \"a {\\n  margin: 1px auto 3px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { inset: 1px auto 3px 4px; left: auto }\", \"a {\\n  inset: 1px auto 3px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { padding: 1px auto 3px 4px; padding-left: auto }\", \"a {\\n  padding: 1px auto 3px 4px;\\n  padding-left: auto;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { margin: auto; margin-left: 1px }\", \"a {\\n  margin: auto auto auto 1px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { inset: auto; left: 1px }\", \"a {\\n  inset: auto auto auto 1px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { padding: auto; padding-left: 1px }\", \"a {\\n  padding: auto;\\n  padding-left: 1px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { margin: inherit; margin-left: 1px }\", \"a {\\n  margin: inherit;\\n  margin-left: 1px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { inset: inherit; left: 1px }\", \"a {\\n  inset: inherit;\\n  left: 1px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { padding: inherit; padding-left: 1px }\", \"a {\\n  padding: inherit;\\n  padding-left: 1px;\\n}\\n\", \"\")\n\n\texpectPrintedLowerMangle(t, \"a { top: 0; right: 0; bottom: 0; left: 0; }\", \"a {\\n  top: 0;\\n  right: 0;\\n  bottom: 0;\\n  left: 0;\\n}\\n\", \"\")\n\n\t// \"inset\" should be expanded when not supported\n\texpectPrintedLower(t, \"a { inset: 0; }\", \"a {\\n  top: 0;\\n  right: 0;\\n  bottom: 0;\\n  left: 0;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { inset: 0px; }\", \"a {\\n  top: 0px;\\n  right: 0px;\\n  bottom: 0px;\\n  left: 0px;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { inset: 1px 2px; }\", \"a {\\n  top: 1px;\\n  right: 2px;\\n  bottom: 1px;\\n  left: 2px;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { inset: 1px 2px 3px; }\", \"a {\\n  top: 1px;\\n  right: 2px;\\n  bottom: 3px;\\n  left: 2px;\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"a { inset: 1px 2px 3px 4px; }\", \"a {\\n  top: 1px;\\n  right: 2px;\\n  bottom: 3px;\\n  left: 4px;\\n}\\n\", \"\")\n\n\t// When \"inset\" isn't supported, other mangling should still work\n\texpectPrintedLowerMangle(t, \"a { top: 0px; }\", \"a {\\n  top: 0;\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"a { right: 0px; }\", \"a {\\n  right: 0;\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"a { bottom: 0px; }\", \"a {\\n  bottom: 0;\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"a { left: 0px; }\", \"a {\\n  left: 0;\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"a { inset: 0px; }\", \"a {\\n  top: 0;\\n  right: 0;\\n  bottom: 0;\\n  left: 0;\\n}\\n\", \"\")\n\n\t// When \"inset\" isn't supported, whitespace minifying should still work\n\texpectPrintedLowerMinify(t, \"a { top: 0px; }\", \"a{top:0px}\", \"\")\n\texpectPrintedLowerMinify(t, \"a { right: 0px; }\", \"a{right:0px}\", \"\")\n\texpectPrintedLowerMinify(t, \"a { bottom: 0px; }\", \"a{bottom:0px}\", \"\")\n\texpectPrintedLowerMinify(t, \"a { left: 0px; }\", \"a{left:0px}\", \"\")\n\texpectPrintedLowerMinify(t, \"a { inset: 0px; }\", \"a{top:0px;right:0px;bottom:0px;left:0px}\", \"\")\n\texpectPrintedLowerMinify(t, \"a { inset: 1px 2px; }\", \"a{top:1px;right:2px;bottom:1px;left:2px}\", \"\")\n\texpectPrintedLowerMinify(t, \"a { inset: 1px 2px 3px; }\", \"a{top:1px;right:2px;bottom:3px;left:2px}\", \"\")\n\texpectPrintedLowerMinify(t, \"a { inset: 1px 2px 3px 4px; }\", \"a{top:1px;right:2px;bottom:3px;left:4px}\", \"\")\n}\n\nfunc TestBorderRadius(t *testing.T) {\n\texpectPrinted(t, \"a { border-top-left-radius: 0 0 }\", \"a {\\n  border-top-left-radius: 0 0;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 0 0 }\", \"a {\\n  border-top-left-radius: 0;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 0 0px }\", \"a {\\n  border-top-left-radius: 0;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 0 1px }\", \"a {\\n  border-top-left-radius: 0 1px;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 0; border-radius: 1px }\", \"a {\\n  border-radius: 1px;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { border-radius: 1px 2px 3px 4px }\", \"a {\\n  border-radius: 1px 2px 3px 4px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 1px 2px 1px 3px }\", \"a {\\n  border-radius: 1px 2px 1px 3px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 1px 2px 3px 2px }\", \"a {\\n  border-radius: 1px 2px 3px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 1px 2px 1px 2px }\", \"a {\\n  border-radius: 1px 2px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 1px 1px 1px 1px }\", \"a {\\n  border-radius: 1px;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { border-radius: 0/1px 2px 3px 4px }\", \"a {\\n  border-radius: 0 / 1px 2px 3px 4px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 0/1px 2px 1px 3px }\", \"a {\\n  border-radius: 0 / 1px 2px 1px 3px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 0/1px 2px 3px 2px }\", \"a {\\n  border-radius: 0 / 1px 2px 3px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 0/1px 2px 1px 2px }\", \"a {\\n  border-radius: 0 / 1px 2px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 0/1px 1px 1px 1px }\", \"a {\\n  border-radius: 0 / 1px;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { border-radius: 1px 2px; border-top-left-radius: 3px; }\", \"a {\\n  border-radius: 3px 2px 1px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 1px; border-top-left-radius: 3px; }\", \"a {\\n  border-radius: 3px 1px 1px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 0/1px; border-top-left-radius: 3px; }\", \"a {\\n  border-radius: 3px 0 0 / 3px 1px 1px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 0/1px 2px; border-top-left-radius: 3px; }\", \"a {\\n  border-radius: 3px 0 0 / 3px 2px 1px;\\n}\\n\", \"\")\n\n\tfor _, x := range []string{\"\", \"-top-left\", \"-top-right\", \"-bottom-left\", \"-bottom-right\"} {\n\t\ty := \"border\" + x + \"-radius\"\n\t\texpectPrintedMangle(t, \"a { \"+y+\": 1px; \"+y+\": 2px }\",\n\t\t\t\"a {\\n  \"+y+\": 2px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+y+\": 1px !important; \"+y+\": 2px }\",\n\t\t\t\"a {\\n  \"+y+\": 1px !important;\\n  \"+y+\": 2px;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+y+\": 1px; \"+y+\": 2px !important }\",\n\t\t\t\"a {\\n  \"+y+\": 1px;\\n  \"+y+\": 2px !important;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { \"+y+\": 1px !important; \"+y+\": 2px !important }\",\n\t\t\t\"a {\\n  \"+y+\": 2px !important;\\n}\\n\", \"\")\n\n\t\texpectPrintedMangle(t, \"a { border-radius: 1px; \"+y+\": 2px !important; }\",\n\t\t\t\"a {\\n  border-radius: 1px;\\n  \"+y+\": 2px !important;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \"a { border-radius: 1px !important; \"+y+\": 2px; }\",\n\t\t\t\"a {\\n  border-radius: 1px !important;\\n  \"+y+\": 2px;\\n}\\n\", \"\")\n\t}\n\n\texpectPrintedMangle(t, \"a { border-top-left-radius: ; border-radius: 1px }\",\n\t\t\"a {\\n  border-top-left-radius:;\\n  border-radius: 1px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 1px; border-radius: / }\",\n\t\t\"a {\\n  border-top-left-radius: 1px;\\n  border-radius: /;\\n}\\n\", \"\")\n\n\texpectPrintedMangleMinify(t, \"a { border-radius: 1px 2px 3px 4px; border-top-right-radius: 5px; }\", \"a{border-radius:1px 5px 3px 4px}\", \"\")\n\texpectPrintedMangleMinify(t, \"a { border-radius: 1px 2px 3px 4px; border-top-right-radius: 5px 6px; }\", \"a{border-radius:1px 5px 3px 4px/1px 6px 3px 4px}\", \"\")\n\n\t// These should not be changed because \"--x\" and \"--z\" could be empty\n\texpectPrintedMangle(t, \"a { border-radius: var(--x) var(--y) var(--z) var(--y) }\", \"a {\\n  border-radius: var(--x) var(--y) var(--z) var(--y);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 0 / var(--x) var(--y) var(--z) var(--y) }\", \"a {\\n  border-radius: 0 / var(--x) var(--y) var(--z) var(--y);\\n}\\n\", \"\")\n\n\t// \"inherit\" should not be merged\n\texpectPrintedMangle(t, \"a { border-radius: 1px; border-top-left-radius: 0 }\", \"a {\\n  border-radius: 0 1px 1px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: inherit; border-top-left-radius: 0 }\", \"a {\\n  border-radius: inherit;\\n  border-top-left-radius: 0;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 0; border-top-left-radius: inherit }\", \"a {\\n  border-radius: 0;\\n  border-top-left-radius: inherit;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 0; border-radius: inherit }\", \"a {\\n  border-top-left-radius: 0;\\n  border-radius: inherit;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: inherit; border-radius: 0 }\", \"a {\\n  border-top-left-radius: inherit;\\n  border-radius: 0;\\n}\\n\", \"\")\n\n\t// Don't merge different units\n\texpectPrintedMangle(t, \"a { border-radius: 1px; border-radius: 2px; }\", \"a {\\n  border-radius: 2px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 1px; border-top-left-radius: 2px; }\", \"a {\\n  border-radius: 2px 1px 1px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 1px; border-radius: 2px; }\", \"a {\\n  border-radius: 2px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 1px; border-top-left-radius: 2px; }\", \"a {\\n  border-top-left-radius: 2px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 1rem; border-radius: 1vw; }\", \"a {\\n  border-radius: 1rem;\\n  border-radius: 1vw;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 1rem; border-top-left-radius: 1vw; }\", \"a {\\n  border-radius: 1rem;\\n  border-top-left-radius: 1vw;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 1rem; border-radius: 1vw; }\", \"a {\\n  border-top-left-radius: 1rem;\\n  border-radius: 1vw;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 1rem; border-top-left-radius: 1vw; }\", \"a {\\n  border-top-left-radius: 1rem;\\n  border-top-left-radius: 1vw;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 0; border-top-left-radius: 2px; }\", \"a {\\n  border-radius: 2px 0 0;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { border-radius: 0; border-top-left-radius: 2rem; }\", \"a {\\n  border-radius: 0;\\n  border-top-left-radius: 2rem;\\n}\\n\", \"\")\n}\n\nfunc TestBoxShadow(t *testing.T) {\n\texpectPrinted(t, \"a { box-shadow: inset 0px 0px 0px 0px black }\", \"a {\\n  box-shadow: inset 0px 0px 0px 0px black;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { box-shadow: 0px 0px 0px 0px inset black }\", \"a {\\n  box-shadow: 0 0 inset #000;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { box-shadow: 0px 0px 0px 0px black inset }\", \"a {\\n  box-shadow: 0 0 #000 inset;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { box-shadow: black 0px 0px 0px 0px inset }\", \"a {\\n  box-shadow: #000 0 0 inset;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { box-shadow: inset 0px 0px 0px 0px black }\", \"a {\\n  box-shadow: inset 0 0 #000;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { box-shadow: inset black 0px 0px 0px 0px }\", \"a {\\n  box-shadow: inset #000 0 0;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { box-shadow: black inset 0px 0px 0px 0px }\", \"a {\\n  box-shadow: #000 inset 0 0;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { box-shadow: yellow 1px 0px 0px 1px inset }\", \"a {\\n  box-shadow: #ff0 1px 0 0 1px inset;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { box-shadow: yellow 1px 0px 1px 0px inset }\", \"a {\\n  box-shadow: #ff0 1px 0 1px inset;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { box-shadow: rebeccapurple, yellow, black }\", \"a {\\n  box-shadow:\\n    #639,\\n    #ff0,\\n    #000;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { box-shadow: 0px 0px 0px var(--foo) black }\", \"a {\\n  box-shadow: 0 0 0 var(--foo) #000;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { box-shadow: 0px 0px 0px 0px var(--foo) black }\", \"a {\\n  box-shadow: 0 0 0 0 var(--foo) #000;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { box-shadow: calc(1px + var(--foo)) 0px 0px 0px black }\", \"a {\\n  box-shadow: calc(1px + var(--foo)) 0 0 0 #000;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { box-shadow: inset 0px 0px 0px 0px 0px magenta; }\", \"a {\\n  box-shadow: inset 0 0 0 0 0 #f0f;\\n}\\n\", \"\")\n\texpectPrintedMangleMinify(t, \"a { box-shadow: rebeccapurple , yellow , black }\", \"a{box-shadow:#639,#ff0,#000}\", \"\")\n\texpectPrintedMangleMinify(t, \"a { box-shadow: rgb(255, 0, 17) 0 0 1 inset }\", \"a{box-shadow:#f01 0 0 1 inset}\", \"\")\n}\n\nfunc TestMangleTime(t *testing.T) {\n\texpectPrintedMangle(t, \"a { animation: b 1s }\", \"a {\\n  animation: b 1s;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 1.s }\", \"a {\\n  animation: b 1s;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 1.0s }\", \"a {\\n  animation: b 1s;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 1.02s }\", \"a {\\n  animation: b 1.02s;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b .1s }\", \"a {\\n  animation: b .1s;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b .01s }\", \"a {\\n  animation: b .01s;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b .001s }\", \"a {\\n  animation: b 1ms;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b .0012s }\", \"a {\\n  animation: b 1.2ms;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b -.001s }\", \"a {\\n  animation: b -1ms;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b -.0012s }\", \"a {\\n  animation: b -1.2ms;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b .0001s }\", \"a {\\n  animation: b .1ms;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b .00012s }\", \"a {\\n  animation: b .12ms;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b .000123s }\", \"a {\\n  animation: b .123ms;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b .01S }\", \"a {\\n  animation: b .01S;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b .001S }\", \"a {\\n  animation: b 1ms;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { animation: b 1ms }\", \"a {\\n  animation: b 1ms;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 10ms }\", \"a {\\n  animation: b 10ms;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 100ms }\", \"a {\\n  animation: b .1s;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 120ms }\", \"a {\\n  animation: b .12s;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 123ms }\", \"a {\\n  animation: b 123ms;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 1000ms }\", \"a {\\n  animation: b 1s;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 1200ms }\", \"a {\\n  animation: b 1.2s;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 1230ms }\", \"a {\\n  animation: b 1.23s;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 1234ms }\", \"a {\\n  animation: b 1234ms;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b -100ms }\", \"a {\\n  animation: b -.1s;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b -120ms }\", \"a {\\n  animation: b -.12s;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 120mS }\", \"a {\\n  animation: b .12s;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 120Ms }\", \"a {\\n  animation: b .12s;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 123mS }\", \"a {\\n  animation: b 123mS;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 123Ms }\", \"a {\\n  animation: b 123Ms;\\n}\\n\", \"\")\n\n\t// Mangling times with exponents is not currently supported\n\texpectPrintedMangle(t, \"a { animation: b 1e3ms }\", \"a {\\n  animation: b 1e3ms;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { animation: b 1E3ms }\", \"a {\\n  animation: b 1E3ms;\\n}\\n\", \"\")\n}\n\nfunc TestCalc(t *testing.T) {\n\texpectPrinted(t, \"a { b: calc(+(2)) }\", \"a {\\n  b: calc(+(2));\\n}\\n\", \"<stdin>: WARNING: \\\"+\\\" can only be used as an infix operator, not a prefix operator\\n\")\n\texpectPrinted(t, \"a { b: calc(-(2)) }\", \"a {\\n  b: calc(-(2));\\n}\\n\", \"<stdin>: WARNING: \\\"-\\\" can only be used as an infix operator, not a prefix operator\\n\")\n\texpectPrinted(t, \"a { b: calc(*(2)) }\", \"a {\\n  b: calc(*(2));\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { b: calc(/(2)) }\", \"a {\\n  b: calc(/(2));\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a { b: calc(1 + 2) }\", \"a {\\n  b: calc(1 + 2);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { b: calc(1 - 2) }\", \"a {\\n  b: calc(1 - 2);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { b: calc(1 * 2) }\", \"a {\\n  b: calc(1 * 2);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { b: calc(1 / 2) }\", \"a {\\n  b: calc(1 / 2);\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a { b: calc(1+ 2) }\", \"a {\\n  b: calc(1+ 2);\\n}\\n\", \"<stdin>: WARNING: The \\\"+\\\" operator only works if there is whitespace on both sides\\n\")\n\texpectPrinted(t, \"a { b: calc(1- 2) }\", \"a {\\n  b: calc(1- 2);\\n}\\n\", \"<stdin>: WARNING: The \\\"-\\\" operator only works if there is whitespace on both sides\\n\")\n\texpectPrinted(t, \"a { b: calc(1* 2) }\", \"a {\\n  b: calc(1* 2);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { b: calc(1/ 2) }\", \"a {\\n  b: calc(1/ 2);\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a { b: calc(1 +2) }\", \"a {\\n  b: calc(1 +2);\\n}\\n\", \"<stdin>: WARNING: The \\\"+\\\" operator only works if there is whitespace on both sides\\n\")\n\texpectPrinted(t, \"a { b: calc(1 -2) }\", \"a {\\n  b: calc(1 -2);\\n}\\n\", \"<stdin>: WARNING: The \\\"-\\\" operator only works if there is whitespace on both sides\\n\")\n\texpectPrinted(t, \"a { b: calc(1 *2) }\", \"a {\\n  b: calc(1 *2);\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { b: calc(1 /2) }\", \"a {\\n  b: calc(1 /2);\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"a { b: calc(1 +(2)) }\", \"a {\\n  b: calc(1 +(2));\\n}\\n\", \"<stdin>: WARNING: The \\\"+\\\" operator only works if there is whitespace on both sides\\n\")\n\texpectPrinted(t, \"a { b: calc(1 -(2)) }\", \"a {\\n  b: calc(1 -(2));\\n}\\n\", \"<stdin>: WARNING: The \\\"-\\\" operator only works if there is whitespace on both sides\\n\")\n\texpectPrinted(t, \"a { b: calc(1 *(2)) }\", \"a {\\n  b: calc(1 *(2));\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { b: calc(1 /(2)) }\", \"a {\\n  b: calc(1 /(2));\\n}\\n\", \"\")\n}\n\nfunc TestMinifyCalc(t *testing.T) {\n\texpectPrintedMangleMinify(t, \"a { b: calc(x + y) }\", \"a{b:calc(x + y)}\", \"\")\n\texpectPrintedMangleMinify(t, \"a { b: calc(x - y) }\", \"a{b:calc(x - y)}\", \"\")\n\texpectPrintedMangleMinify(t, \"a { b: calc(x * y) }\", \"a{b:calc(x*y)}\", \"\")\n\texpectPrintedMangleMinify(t, \"a { b: calc(x / y) }\", \"a{b:calc(x/y)}\", \"\")\n}\n\nfunc TestMangleCalc(t *testing.T) {\n\texpectPrintedMangle(t, \"a { b: calc(1) }\", \"a {\\n  b: 1;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc((1)) }\", \"a {\\n  b: 1;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(calc(1)) }\", \"a {\\n  b: 1;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(x + y * z) }\", \"a {\\n  b: calc(x + y * z);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(x * y + z) }\", \"a {\\n  b: calc(x * y + z);\\n}\\n\", \"\")\n\n\t// Test sum\n\texpectPrintedMangle(t, \"a { b: calc(2 + 3) }\", \"a {\\n  b: 5;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(6 - 2) }\", \"a {\\n  b: 4;\\n}\\n\", \"\")\n\n\t// Test product\n\texpectPrintedMangle(t, \"a { b: calc(2 * 3) }\", \"a {\\n  b: 6;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(6 / 2) }\", \"a {\\n  b: 3;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(2px * 3 + 4px * 5) }\", \"a {\\n  b: 26px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(2 * 3px + 4 * 5px) }\", \"a {\\n  b: 26px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(2px * 3 - 4px * 5) }\", \"a {\\n  b: -14px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(2 * 3px - 4 * 5px) }\", \"a {\\n  b: -14px;\\n}\\n\", \"\")\n\n\t// Test negation\n\texpectPrintedMangle(t, \"a { b: calc(x + 1) }\", \"a {\\n  b: calc(x + 1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(x - 1) }\", \"a {\\n  b: calc(x - 1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(x + -1) }\", \"a {\\n  b: calc(x - 1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(x - -1) }\", \"a {\\n  b: calc(x + 1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(1 + x) }\", \"a {\\n  b: calc(1 + x);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(1 - x) }\", \"a {\\n  b: calc(1 - x);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(-1 + x) }\", \"a {\\n  b: calc(-1 + x);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(-1 - x) }\", \"a {\\n  b: calc(-1 - x);\\n}\\n\", \"\")\n\n\t// Test inversion\n\texpectPrintedMangle(t, \"a { b: calc(x * 4) }\", \"a {\\n  b: calc(x * 4);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(x / 4) }\", \"a {\\n  b: calc(x / 4);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(x * 0.25) }\", \"a {\\n  b: calc(x / 4);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(x / 0.25) }\", \"a {\\n  b: calc(x * 4);\\n}\\n\", \"\")\n\n\t// Test operator precedence\n\texpectPrintedMangle(t, \"a { b: calc((a + b) + c) }\", \"a {\\n  b: calc(a + b + c);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(a + (b + c)) }\", \"a {\\n  b: calc(a + b + c);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc((a - b) - c) }\", \"a {\\n  b: calc(a - b - c);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(a - (b - c)) }\", \"a {\\n  b: calc(a - (b - c));\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc((a * b) * c) }\", \"a {\\n  b: calc(a * b * c);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(a * (b * c)) }\", \"a {\\n  b: calc(a * b * c);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc((a / b) / c) }\", \"a {\\n  b: calc(a / b / c);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(a / (b / c)) }\", \"a {\\n  b: calc(a / (b / c));\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(a + b * c / d - e) }\", \"a {\\n  b: calc(a + b * c / d - e);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc((a + ((b * c) / d)) - e) }\", \"a {\\n  b: calc(a + b * c / d - e);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc((a + b) * c / (d - e)) }\", \"a {\\n  b: calc((a + b) * c / (d - e));\\n}\\n\", \"\")\n\n\t// Using \"var()\" should bail because it can expand to any number of tokens\n\texpectPrintedMangle(t, \"a { b: calc(1px - x + 2px) }\", \"a {\\n  b: calc(3px - x);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(1px - var(x) + 2px) }\", \"a {\\n  b: calc(1px - var(x) + 2px);\\n}\\n\", \"\")\n\n\t// Test values that can't be accurately represented as decimals\n\texpectPrintedMangle(t, \"a { b: calc(100% / 1) }\", \"a {\\n  b: 100%;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 2) }\", \"a {\\n  b: 50%;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 3) }\", \"a {\\n  b: calc(100% / 3);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 4) }\", \"a {\\n  b: 25%;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 5) }\", \"a {\\n  b: 20%;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 6) }\", \"a {\\n  b: calc(100% / 6);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 7) }\", \"a {\\n  b: calc(100% / 7);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 8) }\", \"a {\\n  b: 12.5%;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 9) }\", \"a {\\n  b: calc(100% / 9);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 10) }\", \"a {\\n  b: 10%;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 100) }\", \"a {\\n  b: 1%;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 1000) }\", \"a {\\n  b: .1%;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 10000) }\", \"a {\\n  b: .01%;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 100000) }\", \"a {\\n  b: .001%;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 1000000) }\", \"a {\\n  b: calc(100% / 1000000);\\n}\\n\", \"\") // This actually ends up as \"100% * (1 / 1000000)\" which is less precise\n\texpectPrintedMangle(t, \"a { b: calc(100% / -1000000) }\", \"a {\\n  b: calc(100% / -1000000);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / -100000) }\", \"a {\\n  b: -.001%;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(3 * (2px + 1em / 7)) }\", \"a {\\n  b: calc(3 * (2px + 1em / 7));\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(3 * (2px + 1em / 8)) }\", \"a {\\n  b: calc(3 * (2px + .125em));\\n}\\n\", \"\")\n\n\t// Non-finite numbers\n\texpectPrintedMangle(t, \"a { b: calc(0px / 0) }\", \"a {\\n  b: calc(0px / 0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(1px / 0) }\", \"a {\\n  b: calc(1px / 0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(-1px / 0) }\", \"a {\\n  b: calc(-1px / 0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(nan) }\", \"a {\\n  b: calc(nan);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(infinity) }\", \"a {\\n  b: calc(infinity);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(-infinity) }\", \"a {\\n  b: calc(-infinity);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(1px / nan) }\", \"a {\\n  b: calc(1px / nan);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(1px / infinity) }\", \"a {\\n  b: 0px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { b: calc(1px / -infinity) }\", \"a {\\n  b: -0px;\\n}\\n\", \"\")\n}\n\nfunc TestTransform(t *testing.T) {\n\texpectPrintedMangle(t, \"a { transform: matrix(1, 0, 0, 1, 0, 0) }\", \"a {\\n  transform: scale(1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: matrix(2, 0, 0, 1, 0, 0) }\", \"a {\\n  transform: scaleX(2);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: matrix(1, 0, 0, 2, 0, 0) }\", \"a {\\n  transform: scaleY(2);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: matrix(2, 0, 0, 3, 0, 0) }\", \"a {\\n  transform: scale(2, 3);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: matrix(2, 0, 0, 2, 0, 0) }\", \"a {\\n  transform: scale(2);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: matrix(1, 0, 0, 1, 1, 2) }\",\n\t\t\"a {\\n  transform:\\n    matrix(\\n      1, 0,\\n      0, 1,\\n      1, 2);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: translate(0, 0) }\", \"a {\\n  transform: translate(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate(0px, 0px) }\", \"a {\\n  transform: translate(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate(0%, 0%) }\", \"a {\\n  transform: translate(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate(1px, 0) }\", \"a {\\n  transform: translate(1px);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate(1px, 0px) }\", \"a {\\n  transform: translate(1px);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate(1px, 0%) }\", \"a {\\n  transform: translate(1px);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate(0, 1px) }\", \"a {\\n  transform: translateY(1px);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate(0px, 1px) }\", \"a {\\n  transform: translateY(1px);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate(0%, 1px) }\", \"a {\\n  transform: translateY(1px);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate(1px, 2px) }\", \"a {\\n  transform: translate(1px, 2px);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate(40%, 60%) }\", \"a {\\n  transform: translate(40%, 60%);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: translateX(0) }\", \"a {\\n  transform: translate(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translateX(0px) }\", \"a {\\n  transform: translate(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translateX(0%) }\", \"a {\\n  transform: translate(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translateX(1px) }\", \"a {\\n  transform: translate(1px);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translateX(50%) }\", \"a {\\n  transform: translate(50%);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: translateY(0) }\", \"a {\\n  transform: translateY(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translateY(0px) }\", \"a {\\n  transform: translateY(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translateY(0%) }\", \"a {\\n  transform: translateY(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translateY(1px) }\", \"a {\\n  transform: translateY(1px);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translateY(50%) }\", \"a {\\n  transform: translateY(50%);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: scale(1) }\", \"a {\\n  transform: scale(1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale(100%) }\", \"a {\\n  transform: scale(1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale(10%) }\", \"a {\\n  transform: scale(.1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale(99%) }\", \"a {\\n  transform: scale(99%);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale(1, 1) }\", \"a {\\n  transform: scale(1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale(100%, 1) }\", \"a {\\n  transform: scale(1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale(10%, 0.1) }\", \"a {\\n  transform: scale(.1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale(99%, 0.99) }\", \"a {\\n  transform: scale(99%, .99);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale(60%, 40%) }\", \"a {\\n  transform: scale(.6, .4);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale(3, 1) }\", \"a {\\n  transform: scaleX(3);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale(300%, 1) }\", \"a {\\n  transform: scaleX(3);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale(1, 3) }\", \"a {\\n  transform: scaleY(3);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale(1, 300%) }\", \"a {\\n  transform: scaleY(3);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: scaleX(1) }\", \"a {\\n  transform: scaleX(1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scaleX(2) }\", \"a {\\n  transform: scaleX(2);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scaleX(300%) }\", \"a {\\n  transform: scaleX(3);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scaleX(99%) }\", \"a {\\n  transform: scaleX(99%);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: scaleY(1) }\", \"a {\\n  transform: scaleY(1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scaleY(2) }\", \"a {\\n  transform: scaleY(2);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scaleY(300%) }\", \"a {\\n  transform: scaleY(3);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scaleY(99%) }\", \"a {\\n  transform: scaleY(99%);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: rotate(0) }\", \"a {\\n  transform: rotate(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: rotate(0deg) }\", \"a {\\n  transform: rotate(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: rotate(1deg) }\", \"a {\\n  transform: rotate(1deg);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: skew(0) }\", \"a {\\n  transform: skew(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: skew(0deg) }\", \"a {\\n  transform: skew(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: skew(1deg) }\", \"a {\\n  transform: skew(1deg);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: skew(1deg, 0) }\", \"a {\\n  transform: skew(1deg);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: skew(1deg, 0deg) }\", \"a {\\n  transform: skew(1deg);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: skew(0, 1deg) }\", \"a {\\n  transform: skew(0, 1deg);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: skew(0deg, 1deg) }\", \"a {\\n  transform: skew(0, 1deg);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: skew(1deg, 2deg) }\", \"a {\\n  transform: skew(1deg, 2deg);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: skewX(0) }\", \"a {\\n  transform: skew(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: skewX(0deg) }\", \"a {\\n  transform: skew(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: skewX(1deg) }\", \"a {\\n  transform: skew(1deg);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: skewY(0) }\", \"a {\\n  transform: skewY(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: skewY(0deg) }\", \"a {\\n  transform: skewY(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: skewY(1deg) }\", \"a {\\n  transform: skewY(1deg);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2) }\",\n\t\t\"a {\\n  transform:\\n    matrix3d(\\n      1, 0, 0, 0,\\n      0, 1, 0, 0,\\n      0, 0, 1, 0,\\n      0, 0, 0, 2);\\n}\\n\", \"\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 3, 4, 1) }\",\n\t\t\"a {\\n  transform:\\n    matrix3d(\\n      1, 0, 0, 0,\\n      0, 1, 0, 0,\\n      0, 0, 1, 0,\\n      2, 3, 4, 1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform:\\n    matrix3d(\\n      1, 0, 1, 0,\\n      0, 1, 0, 0,\\n      1, 0, 1, 0,\\n      0, 0, 0, 1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform: scaleZ(1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform: scale3d(2, 1, 1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform: scale3d(1, 2, 1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform: scale3d(2, 2, 1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform: scale3d(2, 3, 1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform: scaleZ(2);\\n}\\n\", \"\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform: scale3d(1, 2, 3);\\n}\\n\", \"\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(2, 3, 0, 0, 4, 5, 0, 0, 0, 0, 1, 0, 6, 7, 0, 1) }\",\n\t\t\"a {\\n  transform:\\n    matrix3d(\\n      2, 3, 0, 0,\\n      4, 5, 0, 0,\\n      0, 0, 1, 0,\\n      6, 7, 0, 1);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: translate3d(0, 0, 0) }\", \"a {\\n  transform: translateZ(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(0%, 0%, 0) }\", \"a {\\n  transform: translateZ(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(0px, 0px, 0px) }\", \"a {\\n  transform: translateZ(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(1px, 0px, 0px) }\", \"a {\\n  transform: translate3d(1px, 0, 0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(0px, 1px, 0px) }\", \"a {\\n  transform: translate3d(0, 1px, 0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(0px, 0px, 1px) }\", \"a {\\n  transform: translateZ(1px);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(1px, 2px, 3px) }\", \"a {\\n  transform: translate3d(1px, 2px, 3px);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(1px, 0, 3px) }\", \"a {\\n  transform: translate3d(1px, 0, 3px);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(0, 2px, 3px) }\", \"a {\\n  transform: translate3d(0, 2px, 3px);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(1px, 2px, 0px) }\", \"a {\\n  transform: translate3d(1px, 2px, 0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(40%, 60%, 0px) }\", \"a {\\n  transform: translate3d(40%, 60%, 0);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: translateZ(0) }\", \"a {\\n  transform: translateZ(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translateZ(0px) }\", \"a {\\n  transform: translateZ(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: translateZ(1px) }\", \"a {\\n  transform: translateZ(1px);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: scale3d(1, 1, 1) }\", \"a {\\n  transform: scaleZ(1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(2, 1, 1) }\", \"a {\\n  transform: scale3d(2, 1, 1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(1, 2, 1) }\", \"a {\\n  transform: scale3d(1, 2, 1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(1, 1, 2) }\", \"a {\\n  transform: scaleZ(2);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(1, 2, 3) }\", \"a {\\n  transform: scale3d(1, 2, 3);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(2, 3, 1) }\", \"a {\\n  transform: scale3d(2, 3, 1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(2, 2, 1) }\", \"a {\\n  transform: scale3d(2, 2, 1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(3, 300%, 100.00%) }\", \"a {\\n  transform: scale3d(3, 3, 1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(1%, 2%, 3%) }\", \"a {\\n  transform: scale3d(1%, 2%, 3%);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: scaleZ(1) }\", \"a {\\n  transform: scaleZ(1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scaleZ(100%) }\", \"a {\\n  transform: scaleZ(1);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scaleZ(2) }\", \"a {\\n  transform: scaleZ(2);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scaleZ(200%) }\", \"a {\\n  transform: scaleZ(2);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: scaleZ(99%) }\", \"a {\\n  transform: scaleZ(99%);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: rotate3d(0, 0, 0, 0) }\", \"a {\\n  transform: rotate3d(0, 0, 0, 0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: rotate3d(0, 0, 0, 0deg) }\", \"a {\\n  transform: rotate3d(0, 0, 0, 0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: rotate3d(0, 0, 0, 45deg) }\", \"a {\\n  transform: rotate3d(0, 0, 0, 45deg);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: rotate3d(1, 0, 0, 45deg) }\", \"a {\\n  transform: rotateX(45deg);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: rotate3d(0, 1, 0, 45deg) }\", \"a {\\n  transform: rotateY(45deg);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: rotate3d(0, 0, 1, 45deg) }\", \"a {\\n  transform: rotate3d(0, 0, 1, 45deg);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: rotateX(0) }\", \"a {\\n  transform: rotateX(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: rotateX(0deg) }\", \"a {\\n  transform: rotateX(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: rotateX(1deg) }\", \"a {\\n  transform: rotateX(1deg);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: rotateY(0) }\", \"a {\\n  transform: rotateY(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: rotateY(0deg) }\", \"a {\\n  transform: rotateY(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: rotateY(1deg) }\", \"a {\\n  transform: rotateY(1deg);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: rotateZ(0) }\", \"a {\\n  transform: rotate(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: rotateZ(0deg) }\", \"a {\\n  transform: rotate(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: rotateZ(1deg) }\", \"a {\\n  transform: rotate(1deg);\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { transform: perspective(0) }\", \"a {\\n  transform: perspective(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: perspective(0px) }\", \"a {\\n  transform: perspective(0);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { transform: perspective(1px) }\", \"a {\\n  transform: perspective(1px);\\n}\\n\", \"\")\n}\n\nfunc TestMangleAlpha(t *testing.T) {\n\talphas := []string{\n\t\t\"0\", \".004\", \".008\", \".01\", \".016\", \".02\", \".024\", \".027\", \".03\", \".035\", \".04\", \".043\", \".047\", \".05\", \".055\", \".06\",\n\t\t\".063\", \".067\", \".07\", \".075\", \".08\", \".082\", \".086\", \".09\", \".094\", \".098\", \".1\", \".106\", \".11\", \".114\", \".118\", \".12\",\n\t\t\".125\", \".13\", \".133\", \".137\", \".14\", \".145\", \".15\", \".153\", \".157\", \".16\", \".165\", \".17\", \".173\", \".176\", \".18\", \".184\",\n\t\t\".19\", \".192\", \".196\", \".2\", \".204\", \".208\", \".21\", \".216\", \".22\", \".224\", \".227\", \".23\", \".235\", \".24\", \".243\", \".247\",\n\t\t\".25\", \".255\", \".26\", \".263\", \".267\", \".27\", \".275\", \".28\", \".282\", \".286\", \".29\", \".294\", \".298\", \".3\", \".306\", \".31\",\n\t\t\".314\", \".318\", \".32\", \".325\", \".33\", \".333\", \".337\", \".34\", \".345\", \".35\", \".353\", \".357\", \".36\", \".365\", \".37\", \".373\",\n\t\t\".376\", \".38\", \".384\", \".39\", \".392\", \".396\", \".4\", \".404\", \".408\", \".41\", \".416\", \".42\", \".424\", \".427\", \".43\", \".435\",\n\t\t\".44\", \".443\", \".447\", \".45\", \".455\", \".46\", \".463\", \".467\", \".47\", \".475\", \".48\", \".482\", \".486\", \".49\", \".494\", \".498\",\n\t\t\".5\", \".506\", \".51\", \".514\", \".518\", \".52\", \".525\", \".53\", \".533\", \".537\", \".54\", \".545\", \".55\", \".553\", \".557\", \".56\",\n\t\t\".565\", \".57\", \".573\", \".576\", \".58\", \".584\", \".59\", \".592\", \".596\", \".6\", \".604\", \".608\", \".61\", \".616\", \".62\", \".624\",\n\t\t\".627\", \".63\", \".635\", \".64\", \".643\", \".647\", \".65\", \".655\", \".66\", \".663\", \".667\", \".67\", \".675\", \".68\", \".682\", \".686\",\n\t\t\".69\", \".694\", \".698\", \".7\", \".706\", \".71\", \".714\", \".718\", \".72\", \".725\", \".73\", \".733\", \".737\", \".74\", \".745\", \".75\",\n\t\t\".753\", \".757\", \".76\", \".765\", \".77\", \".773\", \".776\", \".78\", \".784\", \".79\", \".792\", \".796\", \".8\", \".804\", \".808\", \".81\",\n\t\t\".816\", \".82\", \".824\", \".827\", \".83\", \".835\", \".84\", \".843\", \".847\", \".85\", \".855\", \".86\", \".863\", \".867\", \".87\", \".875\",\n\t\t\".88\", \".882\", \".886\", \".89\", \".894\", \".898\", \".9\", \".906\", \".91\", \".914\", \".918\", \".92\", \".925\", \".93\", \".933\", \".937\",\n\t\t\".94\", \".945\", \".95\", \".953\", \".957\", \".96\", \".965\", \".97\", \".973\", \".976\", \".98\", \".984\", \".99\", \".992\", \".996\",\n\t}\n\n\tfor i, alpha := range alphas {\n\t\texpectPrintedLowerMangle(t, fmt.Sprintf(\"a { color: #%08X }\", i), \"a {\\n  color: rgba(0, 0, 0, \"+alpha+\");\\n}\\n\", \"\")\n\t}\n\n\t// An alpha value of 100% does not use \"rgba(...)\"\n\texpectPrintedLowerMangle(t, \"a { color: #000000FF }\", \"a {\\n  color: #000;\\n}\\n\", \"\")\n}\n\nfunc TestMangleDeadSelectors(t *testing.T) {\n\texpectPrinted(t, \"a { b { color: red } }\", \"a {\\n  b {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { :is() { color: red } }\", \"a {\\n  :is() {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { :where() { color: red } }\", \"a {\\n  :where() {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\t// Trimming away \":is()\" can be relevant for automatically-generated style\n\t// rules that are the result of a CSS nesting transform. For more info see\n\t// https://github.com/evanw/esbuild/issues/4265\n\texpectPrintedMangle(t, \"a { color: green; :is() { color: red } }\", \"a {\\n  color: green;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: green; :where() { color: red } }\", \"a {\\n  color: green;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: green; div + :is() { color: red } }\", \"a {\\n  color: green;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: green; div + :where() { color: red } }\", \"a {\\n  color: green;\\n}\\n\", \"\")\n\n\t// Note: Style rules use an unforgiving selector list, so we can't trivially\n\t// trim away known dead selectors from the list to keep the remaining\n\t// selectors (\"b\" in the case below). Other parts of the known dead selector\n\t// may be invalid, which would then render the whole style rule invalid.\n\texpectPrintedMangle(t, \"a { color: green; b, :foo :is() { color: red } }\", \"a {\\n  color: green;\\n  b,\\n  :foo :is() {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: green; b, :foo :where() { color: red } }\", \"a {\\n  color: green;\\n  b,\\n  :foo :where() {\\n    color: red;\\n  }\\n}\\n\", \"\")\n}\n\nfunc TestMangleDuplicateSelectors(t *testing.T) {\n\texpectPrinted(t, \"a, a { color: red }\", \"a,\\na {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a, a { color: red }\", \"a {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a, b { color: red }\", \"a,\\nb {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a, a.foo, a.foo, a.bar, a { color: red }\", \"a,\\na.foo,\\na.bar {\\n  color: red;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"@media screen { a, a { color: red } }\", \"@media screen {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen { a, b { color: red } }\", \"@media screen {\\n  a,\\n  b {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen { a, a.foo, a.foo, a.bar, a { color: red } }\", \"@media screen {\\n  a,\\n  a.foo,\\n  a.bar {\\n    color: red;\\n  }\\n}\\n\", \"\")\n}\n\nfunc TestMangleDuplicateSelectorRules(t *testing.T) {\n\texpectPrinted(t, \"a { color: red } b { color: red }\", \"a {\\n  color: red;\\n}\\nb {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } b { color: red }\", \"a,\\nb {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } div {} b { color: red }\", \"a,\\nb {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } div { color: red } b { color: red }\", \"a,\\ndiv,\\nb {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } div { color: red } a { color: red }\", \"a,\\ndiv {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } div { color: blue } b { color: red }\", \"a {\\n  color: red;\\n}\\ndiv {\\n  color: #00f;\\n}\\nb {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } div { color: blue } a { color: red }\", \"a {\\n  color: red;\\n}\\ndiv {\\n  color: #00f;\\n}\\na {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red; color: red } b { color: red }\", \"a,\\nb {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } b { color: red; color: red }\", \"a,\\nb {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } b { color: blue }\", \"a {\\n  color: red;\\n}\\nb {\\n  color: #00f;\\n}\\n\", \"\")\n\n\t// Do not merge duplicates if they are \"unsafe\"\n\texpectPrintedMangle(t, \"a { color: red } unknown { color: red }\", \"a {\\n  color: red;\\n}\\nunknown {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"unknown { color: red } a { color: red }\", \"unknown {\\n  color: red;\\n}\\na {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } video { color: red }\", \"a {\\n  color: red;\\n}\\nvideo {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"video { color: red } a { color: red }\", \"video {\\n  color: red;\\n}\\na {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } a:last-child { color: red }\", \"a {\\n  color: red;\\n}\\na:last-child {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } a[b=c i] { color: red }\", \"a {\\n  color: red;\\n}\\na[b=c i] {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } & { color: red }\", \"a {\\n  color: red;\\n}\\n& {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } a + b { color: red }\", \"a {\\n  color: red;\\n}\\na + b {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } a|b { color: red }\", \"a {\\n  color: red;\\n}\\na|b {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } a::hover { color: red }\", \"a {\\n  color: red;\\n}\\na::hover {\\n  color: red;\\n}\\n\", \"\")\n\n\t// Still merge duplicates if they are \"safe\"\n\texpectPrintedMangle(t, \"a { color: red } a:hover { color: red }\", \"a,\\na:hover {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } a[b=c] { color: red }\", \"a,\\na[b=c] {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } a#id { color: red }\", \"a,\\na#id {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { color: red } a.cls { color: red }\", \"a,\\na.cls {\\n  color: red;\\n}\\n\", \"\")\n\n\t// Skip over comments\n\texpectPrintedMangle(t, \"c { color: green } a { color: red } /*!x*/ /*!y*/ b { color: blue }\", \"c {\\n  color: green;\\n}\\na {\\n  color: red;\\n}\\n/*!x*/\\n/*!y*/\\nb {\\n  color: #00f;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"c { color: green } a { color: red } /*!x*/ /*!y*/ b { color: red }\", \"c {\\n  color: green;\\n}\\na,\\nb {\\n  color: red;\\n}\\n/*!x*/\\n/*!y*/\\n\", \"\")\n\texpectPrintedMangle(t, \"c { color: green } a { color: red } /*!x*/ /*!y*/ a { color: red }\", \"c {\\n  color: green;\\n}\\na {\\n  color: red;\\n}\\n/*!x*/\\n/*!y*/\\n\", \"\")\n}\n\nfunc TestAtMedia(t *testing.T) {\n\texpectPrinted(t, \"@media screen{}\", \"@media screen {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media not screen{}\", \"@media not screen {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media only screen{}\", \"@media only screen {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (color) {}\", \"@media (color) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (((color))) {}\", \"@media (color) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media screen and (color) {}\", \"@media screen and (color) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media not screen and (color) and (opacity) {}\", \"@media not screen and (color) and (opacity) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media( color )and ( opacity ){}\", \"@media (color) and (opacity) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media test( general , enclosed ) {}\", \"@media test(general, enclosed) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (width:1px) {}\", \"@media (width: 1px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media ( width: 1px ) {}\", \"@media (width: 1px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media ( width :1px ) {}\", \"@media (width: 1px) {\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"@media not (color) {}\", \"@media not (color) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media not (not (not (color))) {}\", \"@media not (not (not (color))) {\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"@media (resolution >= calc(3x - 1x)) { a { color: red } }\", \"@media (resolution >= calc(3x - 1x)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media (resolution >= calc(3x - 1x)) { a { color: red } }\", \"@media (resolution >= 2x) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"@media (width=1px) {}\", \"@media (width = 1px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (width<1px) {}\", \"@media (width < 1px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (width<=1px) {}\", \"@media (width <= 1px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (width>1px) {}\", \"@media (width > 1px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (width>=1px) {}\", \"@media (width >= 1px) {\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"@media (1px=width) {}\", \"@media (1px = width) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (1px<width) {}\", \"@media (1px < width) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (1px<=width) {}\", \"@media (1px <= width) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (1px>width) {}\", \"@media (1px > width) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (1px>=width) {}\", \"@media (1px >= width) {\\n}\\n\", \"\")\n\n\t// No whitespace is allowed between the \"<\" or \">\" <delim-token>s and the following \"=\" <delim-token>, if it's present.\n\texpectPrinted(t, \"@media (width <=1px) {}\", \"@media (width <= 1px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (width<= 1px) {}\", \"@media (width <= 1px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (width< =1px) {}\", \"@media (width< =1px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (width >=1px) {}\", \"@media (width >= 1px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (width>= 1px) {}\", \"@media (width >= 1px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (width> =1px) {}\", \"@media (width> =1px) {\\n}\\n\", \"\")\n\n\t// Valid three-part ranges\n\texpectPrinted(t, \"@media (1px<width<2px) {}\", \"@media (1px < width < 2px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (1px<width<=2px) {}\", \"@media (1px < width <= 2px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (1px<=width<2px) {}\", \"@media (1px <= width < 2px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (1px<=width<=2px) {}\", \"@media (1px <= width <= 2px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (1px>width>2px) {}\", \"@media (1px > width > 2px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (1px>width>=2px) {}\", \"@media (1px > width >= 2px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (1px>=width>2px) {}\", \"@media (1px >= width > 2px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (1px>=width>=2px) {}\", \"@media (1px >= width >= 2px) {\\n}\\n\", \"\")\n\n\t// Invalid three-part ranges\n\texpectPrinted(t, \"@media (1px=width=2px) {}\", \"@media (1px=width=2px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (1px<width>2px) {}\", \"@media (1px<width>2px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (1px>width<2px) {}\", \"@media (1px>width<2px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (1px<=width>=2px) {}\", \"@media (1px<=width>=2px) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (1px>=width<=2px) {}\", \"@media (1px>=width<=2px) {\\n}\\n\", \"\")\n\n\t// Preserve invalid syntax and valid syntax in the same rule\n\texpectPrinted(t, \"@media junk(a<b),(a<b),junk(a<b) {}\", \"@media junk(a<b), (a < b), junk(a<b) {\\n}\\n\", \"\")\n\n\t// Whitespace is required between a \"not\", \"and\", or \"or\" keyword and the following \"(\" character, because without it that would instead parse as a <function-token>.\n\texpectPrinted(t, \"@media not(color) {}\", \"@media not(color) {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media( color )or( opacity ){}\", \"@media (color)or(opacity) {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found \\\"or(\\\"\\n\")\n\texpectPrinted(t, \"@media( color )and( opacity ){}\", \"@media (color)and(opacity) {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found \\\"and(\\\"\\n\")\n\n\t// Tests from https://drafts.csswg.org/mediaqueries-4/#error-handling\n\texpectPrinted(t, \"@media (example, all,), speech {}\", \"@media (example, all, ), speech {\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media &test, speech {}\", \"@media &test, speech {\\n}\\n\", \"<stdin>: WARNING: Expected identifier but found \\\"&\\\"\\n\")\n\texpectPrinted(t, \"@media (example, speech {}\", \"@media (example, speech {}) {\\n}\\n\", \"<stdin>: WARNING: Expected \\\")\\\" but found end of file\\n\")\n\texpectPrinted(t, \"@media test;,all { body { background: lime } }\", \"@media test;\\n, all {\\n  body {\\n    background: lime;\\n  }\\n}\\n\",\n\t\t\"<stdin>: WARNING: Expected \\\"{\\\" but found \\\";\\\"\\n<stdin>: WARNING: Unexpected \\\",\\\"\\n\")\n\texpectPrinted(t, \"@media and { div { color: red } }\", \"@media and {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"and\\\"\\n\")\n\texpectPrinted(t, \"@media or { div { color: red } }\", \"@media or {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"or\\\"\\n\")\n\texpectPrinted(t, \"@media not { div { color: red } }\", \"@media not {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"<stdin>: WARNING: Expected identifier but found \\\"{\\\"\\n\")\n\texpectPrinted(t, \"@media only { div { color: red } }\", \"@media only {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"<stdin>: WARNING: Expected identifier but found \\\"{\\\"\\n\")\n\texpectPrinted(t, \"@media not and { div { color: red } }\", \"@media not and {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"and\\\"\\n\")\n\texpectPrinted(t, \"@media not or { div { color: red } }\", \"@media not or {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"or\\\"\\n\")\n\texpectPrinted(t, \"@media not not { div { color: red } }\", \"@media not not {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"not\\\"\\n\")\n\texpectPrinted(t, \"@media not only { div { color: red } }\", \"@media not only {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"only\\\"\\n\")\n\texpectPrinted(t, \"@media screen and (min-width: 480px) screen and (device-width: 768px) {}\",\n\t\t\"@media screen and (min-width: 480px) screen and (device-width: 768px) {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found \\\"screen\\\"\\n\")\n\texpectPrinted(t, \"@media layer { div { color: red } }\", \"@media layer {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"layer\\\"\\n\")\n\texpectPrinted(t, \"@media not layer { div { color: red } }\", \"@media not layer {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"layer\\\"\\n\")\n\n\texpectPrinted(t, \"@media screen or (color) {}\", \"@media screen or (color) {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found \\\"or\\\"\\n\")\n\texpectPrinted(t, \"@media screen and (color) or (opacity) {}\", \"@media screen and (color) or (opacity) {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found \\\"or\\\"\\n\")\n\texpectPrinted(t, \"@media (color) and (opacity) or (width) {}\", \"@media (color) and (opacity) or (width) {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found \\\"or\\\"\\n\")\n\texpectPrinted(t, \"@media (color) or (opacity) and (width) {}\", \"@media (color) or (opacity) and (width) {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found \\\"and\\\"\\n\")\n\texpectPrinted(t, \"@media not (color) and (opacity) {}\", \"@media not (color) and (opacity) {\\n}\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found \\\"and\\\"\\n\")\n\texpectPrinted(t, \"@media not (not (color) and (opacity)) {}\", \"@media not (not (color) and (opacity)) {\\n}\\n\", \"<stdin>: WARNING: Expected \\\")\\\" but found \\\"and\\\"\\n\")\n}\n\nfunc TestMangleAtMedia(t *testing.T) {\n\texpectPrinted(t, \"@media screen { @media screen { a { color: red } } }\", \"@media screen {\\n  @media screen {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen { @media screen { a { color: red } } }\", \"@media screen {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen { @media not print { a { color: red } } }\", \"@media screen {\\n  @media not print {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen { @media not print { @media screen { a { color: red } } } }\", \"@media screen {\\n  @media not print {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen { a { color: red } @media screen { a { color: red } } }\", \"@media screen {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen { a { color: red } @media screen { a { color: blue } } }\", \"@media screen {\\n  a {\\n    color: red;\\n  }\\n  a {\\n    color: #00f;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen { .a { color: red; @media screen { .b { color: blue } } } }\", \"@media screen {\\n  .a {\\n    color: red;\\n    .b {\\n      color: #00f;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen { a { color: red } } @media screen { b { color: red } }\", \"@media screen {\\n  a {\\n    color: red;\\n  }\\n}\\n@media screen {\\n  b {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"@media ((a) and (b)) and (c) { a { color: red } }\", \"@media ((a) and (b)) and (c) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media ((a) or (b)) or (c) { a { color: red } }\", \"@media ((a) or (b)) or (c) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (a) and ((b) and (c)) { a { color: red } }\", \"@media (a) and ((b) and (c)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@media (a) or ((b) or (c)) { a { color: red } }\", \"@media (a) or ((b) or (c)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"@media ((a) and (b)) and (c) { a { color: red } }\", \"@media (a) and (b) and (c) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media ((a) or (b)) or (c) { a { color: red } }\", \"@media (a) or (b) or (c) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media (a) and ((b) and (c)) { a { color: red } }\", \"@media (a) and (b) and (c) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media (a) or ((b) or (c)) { a { color: red } }\", \"@media (a) or (b) or (c) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"@media ((a) and (b)) or (c) { a { color: red } }\", \"@media ((a) and (b)) or (c) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media ((a) or (b)) and (c) { a { color: red } }\", \"@media ((a) or (b)) and (c) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media (a) and ((b) or (c)) { a { color: red } }\", \"@media (a) and ((b) or (c)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media (a) or ((b) and (c)) { a { color: red } }\", \"@media (a) or ((b) and (c)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"@media screen and (((a) and (b)) and (c)) { a { color: red } }\", \"@media screen and (a) and (b) and (c) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen and (((a) or (b)) or (c)) { a { color: red } }\", \"@media screen and ((a) or (b) or (c)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen and ((a) and ((b) and (c))) { a { color: red } }\", \"@media screen and (a) and (b) and (c) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen and ((a) or ((b) or (c))) { a { color: red } }\", \"@media screen and ((a) or (b) or (c)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"@media screen and (((a) and (b)) or (c)) { a { color: red } }\", \"@media screen and (((a) and (b)) or (c)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen and (((a) or (b)) and (c)) { a { color: red } }\", \"@media screen and ((a) or (b)) and (c) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen and ((a) and ((b) or (c))) { a { color: red } }\", \"@media screen and (a) and ((b) or (c)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media screen and ((a) or ((b) and (c))) { a { color: red } }\", \"@media screen and ((a) or ((b) and (c))) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"@media not (not (color)) { a { color: red } }\", \"@media (color) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media not (not (not (color))) { a { color: red } }\", \"@media not (color) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media not (not (not (not (color)))) { a { color: red } }\", \"@media (color) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"@media not ((a) and (not (b))) { a { color: red } }\", \"@media not ((a) and (not (b))) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media not ((a) or (not (b))) { a { color: red } }\", \"@media not ((a) or (not (b))) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media not ((not (a)) and (b)) { a { color: red } }\", \"@media not ((not (a)) and (b)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media not ((not (a)) or (b)) { a { color: red } }\", \"@media not ((not (a)) or (b)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media not ((not (a)) and (not (b))) { a { color: red } }\", \"@media (a) or (b) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media not ((not (a)) or (not (b))) { a { color: red } }\", \"@media (a) and (b) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"@media not (width = 1px) { a { color: red } }\", \"@media not (width = 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media not (1px < width < 2px) { a { color: red } }\", \"@media not (1px < width < 2px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media not (2px > width > 1px) { a { color: red } }\", \"@media not (2px > width > 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"@media not (width < 1px) { a { color: red } }\", \"@media (width >= 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media not (width <= 1px) { a { color: red } }\", \"@media (width > 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media not (width > 1px) { a { color: red } }\", \"@media (width <= 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media not (width >= 1px) { a { color: red } }\", \"@media (width < 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"@media not (1px < width) { a { color: red } }\", \"@media (1px >= width) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media not (1px <= width) { a { color: red } }\", \"@media (1px > width) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media not (1px > width) { a { color: red } }\", \"@media (1px <= width) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"@media not (1px >= width) { a { color: red } }\", \"@media (1px < width) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\t// Merge\n\texpectPrintedMangle(t, \"b { @media (x) { a { color: red } } @media (x) { a { color: red } } }\",\n\t\t\"b {\\n  @media (x) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media (x: y) { a { color: red } } @media (x: y) { a { color: red } } }\",\n\t\t\"b {\\n  @media (x: y) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media (x < y > z) { a { color: red } } @media (x < y > z) { a { color: red } } }\",\n\t\t\"b {\\n  @media (x < y > z) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media (x) or (y) { a { color: red } } @media (x) or (y) { a { color: red } } }\",\n\t\t\"b {\\n  @media (x) or (y) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media (x) and (y) { a { color: red } } @media (x) and (y) { a { color: red } } }\",\n\t\t\"b {\\n  @media (x) and (y) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media not (x) { a { color: red } } @media not (x) { a { color: red } } }\",\n\t\t\"b {\\n  @media not (x) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media screen and (x) { a { color: red } } @media screen and (x) { a { color: red } } }\",\n\t\t\"b {\\n  @media screen and (x) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media screen and (x ? y) { a { color: red } } @media screen and (x ? y) { a { color: red } } }\",\n\t\t\"b {\\n  @media screen and (x ? y) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\n\t// Don't merge\n\texpectPrintedMangle(t, \"b { @media (x) { a { color: red } } @media (y) { a { color: red } } }\",\n\t\t\"b {\\n  @media (x) {\\n    a {\\n      color: red;\\n    }\\n  }\\n  @media (y) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media (x: y) { a { color: red } } @media (x: z) { a { color: red } } }\",\n\t\t\"b {\\n  @media (x: y) {\\n    a {\\n      color: red;\\n    }\\n  }\\n  @media (x: z) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media (x < y > z) { a { color: red } } @media (x < y < z) { a { color: red } } }\",\n\t\t\"b {\\n  @media (x < y > z) {\\n    a {\\n      color: red;\\n    }\\n  }\\n  @media (x < y < z) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media (x < y > z) { a { color: red } } @media (x > y > z) { a { color: red } } }\",\n\t\t\"b {\\n  @media (x < y > z) {\\n    a {\\n      color: red;\\n    }\\n  }\\n  @media (x > y > z) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media (x) or (y) { a { color: red } } @media (x) and (y) { a { color: red } } }\",\n\t\t\"b {\\n  @media (x) or (y) {\\n    a {\\n      color: red;\\n    }\\n  }\\n  @media (x) and (y) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media (x) { a { color: red } } @media not (x) { a { color: red } } }\",\n\t\t\"b {\\n  @media (x) {\\n    a {\\n      color: red;\\n    }\\n  }\\n  @media not (x) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media (x) { a { color: red } } @media screen and (x) { a { color: red } } }\",\n\t\t\"b {\\n  @media (x) {\\n    a {\\n      color: red;\\n    }\\n  }\\n  @media screen and (x) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media screen and (x) { a { color: red } } @media print and (x) { a { color: red } } }\",\n\t\t\"b {\\n  @media screen and (x) {\\n    a {\\n      color: red;\\n    }\\n  }\\n  @media print and (x) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media screen and (x) { a { color: red } } @media not screen and (x) { a { color: red } } }\",\n\t\t\"b {\\n  @media screen and (x) {\\n    a {\\n      color: red;\\n    }\\n  }\\n  @media not screen and (x) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media screen and (x) { a { color: red } } @media screen and (y) { a { color: red } } }\",\n\t\t\"b {\\n  @media screen and (x) {\\n    a {\\n      color: red;\\n    }\\n  }\\n  @media screen and (y) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"b { @media screen and (x) { a { color: red } } @media screen and (x) and (x) { a { color: red } } }\",\n\t\t\"b {\\n  @media screen and (x) {\\n    a {\\n      color: red;\\n    }\\n  }\\n  @media screen and (x) and (x) {\\n    a {\\n      color: red;\\n    }\\n  }\\n}\\n\", \"\")\n}\n\nfunc TestLowerAtMediaRange(t *testing.T) {\n\texpectPrintedLower(t, \"@media (width = 1px) { a { color: red } }\", \"@media (width: 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedLower(t, \"@media (width < 1px) { a { color: red } }\", \"@media not (min-width: 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media (width <= 1px) { a { color: red } }\", \"@media (max-width: 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media (width > 1px) { a { color: red } }\", \"@media not (max-width: 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media (width >= 1px) { a { color: red } }\", \"@media (min-width: 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedLower(t, \"@media (1px > width) { a { color: red } }\", \"@media not (min-width: 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media (1px >= width) { a { color: red } }\", \"@media (max-width: 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media (1px < width) { a { color: red } }\", \"@media not (max-width: 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media (1px <= width) { a { color: red } }\", \"@media (min-width: 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedLower(t, \"@media (1px < width < 2px) { a { color: red } }\", \"@media (not (max-width: 1px)) and (not (min-width: 2px)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media (2px > width > 1px) { a { color: red } }\", \"@media (not (min-width: 2px)) and (not (max-width: 1px)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media (1px <= width <= 2px) { a { color: red } }\", \"@media (min-width: 1px) and (max-width: 2px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media (2px >= width >= 1px) { a { color: red } }\", \"@media (max-width: 2px) and (min-width: 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedLower(t, \"@media (1px < width <= 2px) { a { color: red } }\", \"@media (not (max-width: 1px)) and (max-width: 2px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media (2px > width >= 1px) { a { color: red } }\", \"@media (not (min-width: 2px)) and (min-width: 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media (1px <= width < 2px) { a { color: red } }\", \"@media (min-width: 1px) and (not (min-width: 2px)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media (2px >= width > 1px) { a { color: red } }\", \"@media (max-width: 2px) and (not (max-width: 1px)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedLower(t, \"@media not (1px < width < 2px) { a { color: red } }\", \"@media not ((not (max-width: 1px)) and (not (min-width: 2px))) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media not (2px > width > 1px) { a { color: red } }\", \"@media not ((not (min-width: 2px)) and (not (max-width: 1px))) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media not (1px <= width <= 2px) { a { color: red } }\", \"@media not ((min-width: 1px) and (max-width: 2px)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLower(t, \"@media not (2px >= width >= 1px) { a { color: red } }\", \"@media not ((max-width: 2px) and (min-width: 1px)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrintedLowerMangle(t, \"@media not (1px < width < 2px) { a { color: red } }\", \"@media (max-width: 1px) or (min-width: 2px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"@media not (2px > width > 1px) { a { color: red } }\", \"@media (min-width: 2px) or (max-width: 1px) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"@media not (1px <= width <= 2px) { a { color: red } }\", \"@media not ((min-width: 1px) and (max-width: 2px)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLowerMangle(t, \"@media not (2px >= width >= 1px) { a { color: red } }\", \"@media not ((max-width: 2px) and (min-width: 1px)) {\\n  a {\\n    color: red;\\n  }\\n}\\n\", \"\")\n}\n\nfunc TestAtScope(t *testing.T) {\n\texpectPrinted(t, \"@scope { div { color: red } }\", \"@scope {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@scope (a) { div { color: red } }\", \"@scope (a) {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@scope to (a) { div { color: red } }\", \"@scope to (a) {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@scope(a)to (b){ div { color: red } }\", \"@scope (a) to (b) {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@scope (a>*) to (~b) { div { color: red } }\", \"@scope (a > *) to (~ b) {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrinted(t, \"@scope (a,b) to (c,d) { div { color: red } }\", \"@scope (a, b) to (c, d) {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\n\texpectPrinted(t, \"@scope a { div { color: red } }\", \"@scope a {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"<stdin>: WARNING: Expected \\\"{\\\" but found \\\"a\\\"\\n\")\n\texpectPrinted(t, \"@scope to a { div { color: red } }\", \"@scope to a {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"<stdin>: WARNING: Expected \\\"(\\\" but found \\\"a\\\"\\n\")\n\texpectPrinted(t, \"@scope (a) to b { div { color: red } }\", \"@scope (a) to b {\\n  div {\\n    color: red;\\n  }\\n}\\n\", \"<stdin>: WARNING: Expected \\\"(\\\" but found \\\"b\\\"\\n\")\n\n\twarning := \"<stdin>: WARNING: Unexpected \\\"{\\\"\\n<stdin>: WARNING: Expected \\\")\\\" to go with \\\"(\\\"\\n<stdin>: NOTE: The unbalanced \\\"(\\\" is here:\\n\"\n\texpectPrinted(t, \"@scope (a { div { color: red } }\", \"@scope (a { div { color: red } }) {\\n}\\n\", warning)\n\texpectPrinted(t, \"@scope to (a { div { color: red } }\", \"@scope to (a { div { color: red } }) {\\n}\\n\", warning)\n}\n\nfunc TestFontWeight(t *testing.T) {\n\texpectPrintedMangle(t, \"a { font-weight: normal }\", \"a {\\n  font-weight: 400;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font-weight: bold }\", \"a {\\n  font-weight: 700;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font-weight: 400 }\", \"a {\\n  font-weight: 400;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font-weight: bolder }\", \"a {\\n  font-weight: bolder;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font-weight: var(--var) }\", \"a {\\n  font-weight: var(--var);\\n}\\n\", \"\")\n\n\texpectPrintedMangleMinify(t, \"a { font-weight: normal }\", \"a{font-weight:400}\", \"\")\n}\n\nfunc TestFontFamily(t *testing.T) {\n\texpectPrintedMangle(t, \"a {font-family: aaa }\", \"a {\\n  font-family: aaa;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a {font-family: serif }\", \"a {\\n  font-family: serif;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a {font-family: 'serif' }\", \"a {\\n  font-family: \\\"serif\\\";\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a {font-family: aaa bbb, serif }\", \"a {\\n  font-family: aaa bbb, serif;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa', serif }\", \"a {\\n  font-family: aaa, serif;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a {font-family: '\\\"', serif }\", \"a {\\n  font-family: '\\\"', serif;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa ', serif }\", \"a {\\n  font-family: \\\"aaa \\\", serif;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa bbb', serif }\", \"a {\\n  font-family: aaa bbb, serif;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa bbb', 'ccc ddd' }\", \"a {\\n  font-family: aaa bbb, ccc ddd;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa  bbb', serif }\", \"a {\\n  font-family: \\\"aaa  bbb\\\", serif;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa serif' }\", \"a {\\n  font-family: \\\"aaa serif\\\";\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa bbb', var(--var) }\", \"a {\\n  font-family: \\\"aaa bbb\\\", var(--var);\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa bbb', }\", \"a {\\n  font-family: \\\"aaa bbb\\\", ;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a {font-family: , 'aaa bbb' }\", \"a {\\n  font-family: , \\\"aaa bbb\\\";\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa',, 'bbb' }\", \"a {\\n  font-family:\\n    \\\"aaa\\\",,\\n    \\\"bbb\\\";\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa bbb', x serif }\", \"a {\\n  font-family: \\\"aaa bbb\\\", x serif;\\n}\\n\", \"\")\n\n\texpectPrintedMangleMinify(t, \"a {font-family: 'aaa bbb', serif }\", \"a{font-family:aaa bbb,serif}\", \"\")\n\texpectPrintedMangleMinify(t, \"a {font-family: 'aaa bbb', 'ccc ddd' }\", \"a{font-family:aaa bbb,ccc ddd}\", \"\")\n\texpectPrintedMangleMinify(t, \"a {font-family: 'initial', serif;}\", \"a{font-family:\\\"initial\\\",serif}\", \"\")\n\texpectPrintedMangleMinify(t, \"a {font-family: 'inherit', serif;}\", \"a{font-family:\\\"inherit\\\",serif}\", \"\")\n\texpectPrintedMangleMinify(t, \"a {font-family: 'unset', serif;}\", \"a{font-family:\\\"unset\\\",serif}\", \"\")\n\texpectPrintedMangleMinify(t, \"a {font-family: 'revert', serif;}\", \"a{font-family:\\\"revert\\\",serif}\", \"\")\n\texpectPrintedMangleMinify(t, \"a {font-family: 'revert-layer', 'Segoe UI', serif;}\", \"a{font-family:\\\"revert-layer\\\",Segoe UI,serif}\", \"\")\n\texpectPrintedMangleMinify(t, \"a {font-family: 'default', serif;}\", \"a{font-family:\\\"default\\\",serif}\", \"\")\n}\n\nfunc TestFont(t *testing.T) {\n\texpectPrintedMangle(t, \"a { font: caption }\", \"a {\\n  font: caption;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font: normal 1px }\", \"a {\\n  font: normal 1px;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font: normal bold }\", \"a {\\n  font: normal bold;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font: 1rem 'aaa bbb' }\", \"a {\\n  font: 1rem aaa bbb;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font: 1rem/1.2 'aaa bbb' }\", \"a {\\n  font: 1rem/1.2 aaa bbb;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font: normal 1rem 'aaa bbb' }\", \"a {\\n  font: 1rem aaa bbb;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font: normal 1rem 'aaa bbb', serif }\", \"a {\\n  font: 1rem aaa bbb, serif;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font: italic small-caps bold ultra-condensed 1rem/1.2 'aaa bbb' }\", \"a {\\n  font: italic small-caps 700 ultra-condensed 1rem/1.2 aaa bbb;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font: oblique 1px 'aaa bbb' }\", \"a {\\n  font: oblique 1px aaa bbb;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font: oblique 45deg 1px 'aaa bbb' }\", \"a {\\n  font: oblique 45deg 1px aaa bbb;\\n}\\n\", \"\")\n\n\texpectPrintedMangle(t, \"a { font: var(--var) 'aaa bbb' }\", \"a {\\n  font: var(--var) \\\"aaa bbb\\\";\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font: normal var(--var) 'aaa bbb' }\", \"a {\\n  font: normal var(--var) \\\"aaa bbb\\\";\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font: normal 1rem var(--var), 'aaa bbb' }\", \"a {\\n  font: normal 1rem var(--var), \\\"aaa bbb\\\";\\n}\\n\", \"\")\n\n\texpectPrintedMangleMinify(t, \"a { font: italic small-caps bold ultra-condensed 1rem/1.2 'aaa bbb' }\", \"a{font:italic small-caps 700 ultra-condensed 1rem/1.2 aaa bbb}\", \"\")\n\texpectPrintedMangleMinify(t, \"a { font: italic small-caps bold ultra-condensed 1rem / 1.2 'aaa bbb' }\", \"a{font:italic small-caps 700 ultra-condensed 1rem/1.2 aaa bbb}\", \"\")\n\n\t// See: https://github.com/evanw/esbuild/issues/3452\n\texpectPrinted(t, \"a { font: 10px'foo' }\", \"a {\\n  font: 10px\\\"foo\\\";\\n}\\n\", \"\")\n\texpectPrinted(t, \"a { font: 10px'123' }\", \"a {\\n  font: 10px\\\"123\\\";\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font: 10px'foo' }\", \"a {\\n  font: 10px foo;\\n}\\n\", \"\")\n\texpectPrintedMangle(t, \"a { font: 10px'123' }\", \"a {\\n  font: 10px\\\"123\\\";\\n}\\n\", \"\")\n\texpectPrintedMangleMinify(t, \"a { font: 10px'foo' }\", \"a{font:10px foo}\", \"\")\n\texpectPrintedMangleMinify(t, \"a { font: 10px'123' }\", \"a{font:10px\\\"123\\\"}\", \"\")\n}\n\nfunc TestWarningUnexpectedCloseBrace(t *testing.T) {\n\texpectPrinted(t, \".red {\\n  color: red;\\n}\\n}\\n.blue {\\n  color: blue;\\n}\\n.green {\\n color: green;\\n}\\n\",\n\t\t`.red {\n  color: red;\n}\n} .blue {\n  color: blue;\n}\n.green {\n  color: green;\n}\n`,\n\t\t`<stdin>: WARNING: Unexpected \"}\"\n`)\n}\n\nfunc TestPropertyTypoWarning(t *testing.T) {\n\texpectPrinted(t, \"a { z-idnex: 0 }\", \"a {\\n  z-idnex: 0;\\n}\\n\", \"<stdin>: WARNING: \\\"z-idnex\\\" is not a known CSS property\\nNOTE: Did you mean \\\"z-index\\\" instead?\\n\")\n\texpectPrinted(t, \"a { x-index: 0 }\", \"a {\\n  x-index: 0;\\n}\\n\", \"<stdin>: WARNING: \\\"x-index\\\" is not a known CSS property\\nNOTE: Did you mean \\\"z-index\\\" instead?\\n\")\n\n\t// CSS variables should not be corrected\n\texpectPrinted(t, \"a { --index: 0 }\", \"a {\\n  --index: 0 ;\\n}\\n\", \"\")\n\n\t// Short names should not be corrected (\"alt\" is actually valid in WebKit, and should not become \"all\")\n\texpectPrinted(t, \"a { alt: \\\"\\\" }\", \"a {\\n  alt: \\\"\\\";\\n}\\n\", \"\")\n}\n\nfunc TestParseErrorRecovery(t *testing.T) {\n\texpectPrinted(t, \"x { y: z\", \"x {\\n  y: z;\\n}\\n\", \"<stdin>: WARNING: Expected \\\"}\\\" to go with \\\"{\\\"\\n<stdin>: NOTE: The unbalanced \\\"{\\\" is here:\\n\")\n\texpectPrinted(t, \"x { y: (\", \"x {\\n  y: ();\\n}\\n\", \"<stdin>: WARNING: Expected \\\")\\\" to go with \\\"(\\\"\\n<stdin>: NOTE: The unbalanced \\\"(\\\" is here:\\n\")\n\texpectPrinted(t, \"x { y: [\", \"x {\\n  y: [];\\n}\\n\", \"<stdin>: WARNING: Expected \\\"]\\\" to go with \\\"[\\\"\\n<stdin>: NOTE: The unbalanced \\\"[\\\" is here:\\n\")\n\texpectPrinted(t, \"x { y: {\", \"x {\\n  y: {\\n  }\\n}\\n\",\n\t\t\"<stdin>: WARNING: Expected identifier but found whitespace\\n<stdin>: WARNING: Expected \\\"}\\\" to go with \\\"{\\\"\\n<stdin>: NOTE: The unbalanced \\\"{\\\" is here:\\n\")\n\texpectPrinted(t, \"x { y: z(\", \"x {\\n  y: z();\\n}\\n\", \"<stdin>: WARNING: Expected \\\")\\\" to go with \\\"(\\\"\\n<stdin>: NOTE: The unbalanced \\\"(\\\" is here:\\n\")\n\texpectPrinted(t, \"x { y: z(abc\", \"x {\\n  y: z(abc);\\n}\\n\", \"<stdin>: WARNING: Expected \\\")\\\" to go with \\\"(\\\"\\n<stdin>: NOTE: The unbalanced \\\"(\\\" is here:\\n\")\n\texpectPrinted(t, \"x { y: url(\", \"x {\\n  y: url();\\n}\\n\",\n\t\t\"<stdin>: WARNING: Expected \\\")\\\" to end URL token\\n<stdin>: NOTE: The unbalanced \\\"(\\\" is here:\\n<stdin>: WARNING: Expected \\\"}\\\" to go with \\\"{\\\"\\n<stdin>: NOTE: The unbalanced \\\"{\\\" is here:\\n\")\n\texpectPrinted(t, \"x { y: url(abc\", \"x {\\n  y: url(abc);\\n}\\n\",\n\t\t\"<stdin>: WARNING: Expected \\\")\\\" to end URL token\\n<stdin>: NOTE: The unbalanced \\\"(\\\" is here:\\n<stdin>: WARNING: Expected \\\"}\\\" to go with \\\"{\\\"\\n<stdin>: NOTE: The unbalanced \\\"{\\\" is here:\\n\")\n\texpectPrinted(t, \"x { y: url(; }\", \"x {\\n  y: url(; };\\n}\\n\",\n\t\t\"<stdin>: WARNING: Expected \\\")\\\" to end URL token\\n<stdin>: NOTE: The unbalanced \\\"(\\\" is here:\\n<stdin>: WARNING: Expected \\\"}\\\" to go with \\\"{\\\"\\n<stdin>: NOTE: The unbalanced \\\"{\\\" is here:\\n\")\n\texpectPrinted(t, \"x { y: url(abc;\", \"x {\\n  y: url(abc;);\\n}\\n\",\n\t\t\"<stdin>: WARNING: Expected \\\")\\\" to end URL token\\n<stdin>: NOTE: The unbalanced \\\"(\\\" is here:\\n<stdin>: WARNING: Expected \\\"}\\\" to go with \\\"{\\\"\\n<stdin>: NOTE: The unbalanced \\\"{\\\" is here:\\n\")\n\texpectPrinted(t, \"/* @license */ x {} /* @preserve\", \"/* @license */\\nx {\\n}\\n\",\n\t\t\"<stdin>: ERROR: Expected \\\"*/\\\" to terminate multi-line comment\\n<stdin>: NOTE: The multi-line comment starts here:\\n\")\n\texpectPrinted(t, \"a { b: c; d: 'e\\n f: g; h: i }\", \"a {\\n  b: c;\\n  d: 'e\\n  f: g;\\n  h: i;\\n}\\n\", \"<stdin>: WARNING: Unterminated string token\\n\")\n\texpectPrintedMinify(t, \"a { b: c; d: 'e\\n f: g; h: i }\", \"a{b:c;d:'e\\nf: g;h:i}\", \"<stdin>: WARNING: Unterminated string token\\n\")\n}\n\nfunc TestPrefixInsertion(t *testing.T) {\n\t// General \"-webkit-\" tests\n\tfor _, key := range []string{\n\t\t\"backdrop-filter\",\n\t\t\"box-decoration-break\",\n\t\t\"clip-path\",\n\t\t\"font-kerning\",\n\t\t\"initial-letter\",\n\t\t\"mask\",\n\t\t\"mask-image\",\n\t\t\"mask-origin\",\n\t\t\"mask-position\",\n\t\t\"mask-repeat\",\n\t\t\"mask-size\",\n\t\t\"print-color-adjust\",\n\t\t\"text-decoration-skip\",\n\t\t\"text-emphasis-color\",\n\t\t\"text-emphasis-position\",\n\t\t\"text-emphasis-style\",\n\t\t\"text-orientation\",\n\t} {\n\t\texpectPrintedWithAllPrefixes(t,\n\t\t\t\"a { \"+key+\": url(x.png) }\",\n\t\t\t\"a {\\n  -webkit-\"+key+\": url(x.png);\\n  \"+key+\": url(x.png);\\n}\\n\", \"\")\n\n\t\texpectPrintedWithAllPrefixes(t,\n\t\t\t\"a { before: value; \"+key+\": url(x.png) }\",\n\t\t\t\"a {\\n  before: value;\\n  -webkit-\"+key+\": url(x.png);\\n  \"+key+\": url(x.png);\\n}\\n\", \"\")\n\n\t\texpectPrintedWithAllPrefixes(t,\n\t\t\t\"a { \"+key+\": url(x.png); after: value }\",\n\t\t\t\"a {\\n  -webkit-\"+key+\": url(x.png);\\n  \"+key+\": url(x.png);\\n  after: value;\\n}\\n\", \"\")\n\n\t\texpectPrintedWithAllPrefixes(t,\n\t\t\t\"a { before: value; \"+key+\": url(x.png); after: value }\",\n\t\t\t\"a {\\n  before: value;\\n  -webkit-\"+key+\": url(x.png);\\n  \"+key+\": url(x.png);\\n  after: value;\\n}\\n\", \"\")\n\n\t\texpectPrintedWithAllPrefixes(t,\n\t\t\t\"a {\\n  -webkit-\"+key+\": url(x.png);\\n  \"+key+\": url(y.png);\\n}\\n\",\n\t\t\t\"a {\\n  -webkit-\"+key+\": url(x.png);\\n  \"+key+\": url(y.png);\\n}\\n\", \"\")\n\n\t\texpectPrintedWithAllPrefixes(t,\n\t\t\t\"a {\\n  \"+key+\": url(y.png);\\n  -webkit-\"+key+\": url(x.png);\\n}\\n\",\n\t\t\t\"a {\\n  \"+key+\": url(y.png);\\n  -webkit-\"+key+\": url(x.png);\\n}\\n\", \"\")\n\n\t\texpectPrintedWithAllPrefixes(t,\n\t\t\t\"a { \"+key+\": url(x.png); \"+key+\": url(y.png) }\",\n\t\t\t\"a {\\n  -webkit-\"+key+\": url(x.png);\\n  \"+key+\": url(x.png);\\n  -webkit-\"+key+\": url(y.png);\\n  \"+key+\": url(y.png);\\n}\\n\", \"\")\n\t}\n\n\t// Special-case tests\n\texpectPrintedWithAllPrefixes(t, \"a { appearance: none }\", \"a {\\n  -webkit-appearance: none;\\n  -moz-appearance: none;\\n  appearance: none;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t, \"a { background-clip: not-text }\", \"a {\\n  background-clip: not-text;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t, \"a { background-clip: text !important }\",\n\t\t\"a {\\n  -webkit-background-clip: text !important;\\n  -ms-background-clip: text !important;\\n  background-clip: text !important;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t, \"a { background-clip: text }\", \"a {\\n  -webkit-background-clip: text;\\n  -ms-background-clip: text;\\n  background-clip: text;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t, \"a { hyphens: auto }\", \"a {\\n  -webkit-hyphens: auto;\\n  -moz-hyphens: auto;\\n  -ms-hyphens: auto;\\n  hyphens: auto;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t, \"a { position: absolute }\", \"a {\\n  position: absolute;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t, \"a { position: sticky !important }\", \"a {\\n  position: -webkit-sticky !important;\\n  position: sticky !important;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t, \"a { position: sticky }\", \"a {\\n  position: -webkit-sticky;\\n  position: sticky;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t, \"a { tab-size: 2 }\", \"a {\\n  -moz-tab-size: 2;\\n  -o-tab-size: 2;\\n  tab-size: 2;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t, \"a { text-decoration-color: none }\", \"a {\\n  -webkit-text-decoration-color: none;\\n  -moz-text-decoration-color: none;\\n  text-decoration-color: none;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t, \"a { text-decoration-line: none }\", \"a {\\n  -webkit-text-decoration-line: none;\\n  -moz-text-decoration-line: none;\\n  text-decoration-line: none;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t, \"a { text-size-adjust: none }\", \"a {\\n  -webkit-text-size-adjust: none;\\n  -ms-text-size-adjust: none;\\n  text-size-adjust: none;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t, \"a { user-select: none }\",\n\t\t\"a {\\n  -webkit-user-select: none;\\n  -khtml-user-select: none;\\n  -moz-user-select: -moz-none;\\n  -ms-user-select: none;\\n  user-select: none;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t, \"a { mask-composite: add, subtract, intersect, exclude }\",\n\t\t\"a {\\n  -webkit-mask-composite:\\n    source-over,\\n    source-out,\\n    source-in,\\n    xor;\\n  mask-composite:\\n    add,\\n    subtract,\\n    intersect,\\n    exclude;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t, \"a { width: stretch }\",\n\t\t\"a {\\n  width: -webkit-fill-available;\\n  width: stretch;\\n}\\n\", \"\")\n\n\t// Check that we insert prefixed rules each time an unprefixed rule is\n\t// encountered. This matches the behavior of the popular \"autoprefixer\" tool.\n\texpectPrintedWithAllPrefixes(t,\n\t\t\"a { before: value; mask-image: a; middle: value; mask-image: b; after: value }\",\n\t\t\"a {\\n  before: value;\\n  -webkit-mask-image: a;\\n  mask-image: a;\\n  middle: value;\\n  -webkit-mask-image: b;\\n  mask-image: b;\\n  after: value;\\n}\\n\", \"\")\n\n\t// Test that we don't insert duplicated rules when source code is processed\n\t// twice. This matches the behavior of the popular \"autoprefixer\" tool.\n\texpectPrintedWithAllPrefixes(t,\n\t\t\"a { before: value; -webkit-text-size-adjust: 1; -ms-text-size-adjust: 2; text-size-adjust: 3; after: value }\",\n\t\t\"a {\\n  before: value;\\n  -webkit-text-size-adjust: 1;\\n  -ms-text-size-adjust: 2;\\n  text-size-adjust: 3;\\n  after: value;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t,\n\t\t\"a { before: value; -webkit-text-size-adjust: 1; text-size-adjust: 3; after: value }\",\n\t\t\"a {\\n  before: value;\\n  -webkit-text-size-adjust: 1;\\n  -ms-text-size-adjust: 3;\\n  text-size-adjust: 3;\\n  after: value;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t,\n\t\t\"a { before: value; -ms-text-size-adjust: 2; text-size-adjust: 3; after: value }\",\n\t\t\"a {\\n  before: value;\\n  -ms-text-size-adjust: 2;\\n  -webkit-text-size-adjust: 3;\\n  text-size-adjust: 3;\\n  after: value;\\n}\\n\", \"\")\n\texpectPrintedWithAllPrefixes(t, \"a { width: -webkit-fill-available; width: stretch }\",\n\t\t\"a {\\n  width: -webkit-fill-available;\\n  width: stretch;\\n}\\n\", \"\")\n}\n\nfunc TestNthChild(t *testing.T) {\n\tfor _, nth := range []string{\"nth-child\", \"nth-last-child\"} {\n\t\texpectPrinted(t, \":\"+nth+\"(x) {}\", \":\"+nth+\"(x) {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"x\\\"\\n\")\n\t\texpectPrinted(t, \":\"+nth+\"(1e2) {}\", \":\"+nth+\"(1e2) {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"1e2\\\"\\n\")\n\t\texpectPrinted(t, \":\"+nth+\"(-n-) {}\", \":\"+nth+\"(-n-) {\\n}\\n\", \"<stdin>: WARNING: Expected number but found \\\")\\\"\\n\")\n\t\texpectPrinted(t, \":\"+nth+\"(-nn) {}\", \":\"+nth+\"(-nn) {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"-nn\\\"\\n\")\n\t\texpectPrinted(t, \":\"+nth+\"(-n-n) {}\", \":\"+nth+\"(-n-n) {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"-n-n\\\"\\n\")\n\t\texpectPrinted(t, \":\"+nth+\"(-2n-) {}\", \":\"+nth+\"(-2n-) {\\n}\\n\", \"<stdin>: WARNING: Expected number but found \\\")\\\"\\n\")\n\t\texpectPrinted(t, \":\"+nth+\"(-2n-2n) {}\", \":\"+nth+\"(-2n-2n) {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"-2n-2n\\\"\\n\")\n\t\texpectPrinted(t, \":\"+nth+\"(+) {}\", \":\"+nth+\"(+) {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\")\\\"\\n\")\n\t\texpectPrinted(t, \":\"+nth+\"(-) {}\", \":\"+nth+\"(-) {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"-\\\"\\n\")\n\t\texpectPrinted(t, \":\"+nth+\"(+ 2) {}\", \":\"+nth+\"(+ 2) {\\n}\\n\", \"<stdin>: WARNING: Unexpected whitespace\\n\")\n\t\texpectPrinted(t, \":\"+nth+\"(- 2) {}\", \":\"+nth+\"(- 2) {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"-\\\"\\n\")\n\n\t\texpectPrinted(t, \":\"+nth+\"(0) {}\", \":\"+nth+\"(0) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(0 ) {}\", \":\"+nth+\"(0) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"( 0) {}\", \":\"+nth+\"(0) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(00) {}\", \":\"+nth+\"(0) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(01) {}\", \":\"+nth+\"(1) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(0n) {}\", \":\"+nth+\"(0n) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(n) {}\", \":\"+nth+\"(n) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(-n) {}\", \":\"+nth+\"(-n) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(1n) {}\", \":\"+nth+\"(n) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(-1n) {}\", \":\"+nth+\"(-n) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(2n) {}\", \":\"+nth+\"(2n) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(-2n) {}\", \":\"+nth+\"(-2n) {\\n}\\n\", \"\")\n\n\t\texpectPrinted(t, \":\"+nth+\"(odd) {}\", \":\"+nth+\"(odd) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(odd ) {}\", \":\"+nth+\"(odd) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"( odd) {}\", \":\"+nth+\"(odd) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(even) {}\", \":\"+nth+\"(even) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(even ) {}\", \":\"+nth+\"(even) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"( even) {}\", \":\"+nth+\"(even) {\\n}\\n\", \"\")\n\n\t\texpectPrinted(t, \":\"+nth+\"(n+3) {}\", \":\"+nth+\"(n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(n-3) {}\", \":\"+nth+\"(n-3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(n +3) {}\", \":\"+nth+\"(n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(n -3) {}\", \":\"+nth+\"(n-3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(n+ 3) {}\", \":\"+nth+\"(n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(n- 3) {}\", \":\"+nth+\"(n-3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"( n + 3 ) {}\", \":\"+nth+\"(n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"( n - 3 ) {}\", \":\"+nth+\"(n-3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(+n+3) {}\", \":\"+nth+\"(n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(+n-3) {}\", \":\"+nth+\"(n-3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(-n+3) {}\", \":\"+nth+\"(-n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(-n-3) {}\", \":\"+nth+\"(-n-3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"( +n + 3 ) {}\", \":\"+nth+\"(n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"( +n - 3 ) {}\", \":\"+nth+\"(n-3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"( -n + 3 ) {}\", \":\"+nth+\"(-n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"( -n - 3 ) {}\", \":\"+nth+\"(-n-3) {\\n}\\n\", \"\")\n\n\t\texpectPrinted(t, \":\"+nth+\"(2n+3) {}\", \":\"+nth+\"(2n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(2n-3) {}\", \":\"+nth+\"(2n-3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(2n +3) {}\", \":\"+nth+\"(2n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(2n -3) {}\", \":\"+nth+\"(2n-3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(2n+ 3) {}\", \":\"+nth+\"(2n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(2n- 3) {}\", \":\"+nth+\"(2n-3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"( 2n + 3 ) {}\", \":\"+nth+\"(2n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"( 2n - 3 ) {}\", \":\"+nth+\"(2n-3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(+2n+3) {}\", \":\"+nth+\"(2n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(+2n-3) {}\", \":\"+nth+\"(2n-3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(-2n+3) {}\", \":\"+nth+\"(-2n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(-2n-3) {}\", \":\"+nth+\"(-2n-3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"( +2n + 3 ) {}\", \":\"+nth+\"(2n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"( +2n - 3 ) {}\", \":\"+nth+\"(2n-3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"( -2n + 3 ) {}\", \":\"+nth+\"(-2n+3) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"( -2n - 3 ) {}\", \":\"+nth+\"(-2n-3) {\\n}\\n\", \"\")\n\n\t\texpectPrinted(t, \":\"+nth+\"(2n of + .foo) {}\", \":\"+nth+\"(2n of + .foo) {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"+\\\"\\n\")\n\t\texpectPrinted(t, \":\"+nth+\"(2n of .foo, ~.bar) {}\", \":\"+nth+\"(2n of .foo, ~.bar) {\\n}\\n\", \"<stdin>: WARNING: Unexpected \\\"~\\\"\\n\")\n\t\texpectPrinted(t, \":\"+nth+\"(2n of .foo) {}\", \":\"+nth+\"(2n of .foo) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(2n of.foo+.bar) {}\", \":\"+nth+\"(2n of .foo + .bar) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(2n of[href]) {}\", \":\"+nth+\"(2n of [href]) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(2n of.foo,.bar) {}\", \":\"+nth+\"(2n of .foo, .bar) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(2n of .foo, .bar) {}\", \":\"+nth+\"(2n of .foo, .bar) {\\n}\\n\", \"\")\n\t\texpectPrinted(t, \":\"+nth+\"(2n of .foo , .bar ) {}\", \":\"+nth+\"(2n of .foo, .bar) {\\n}\\n\", \"\")\n\n\t\texpectPrintedMinify(t, \":\"+nth+\"(2n of [foo] , [bar] ) {}\", \":\"+nth+\"(2n of[foo],[bar]){}\", \"\")\n\t\texpectPrintedMinify(t, \":\"+nth+\"(2n of .foo , .bar ) {}\", \":\"+nth+\"(2n of.foo,.bar){}\", \"\")\n\t\texpectPrintedMinify(t, \":\"+nth+\"(2n of #foo , #bar ) {}\", \":\"+nth+\"(2n of#foo,#bar){}\", \"\")\n\t\texpectPrintedMinify(t, \":\"+nth+\"(2n of :foo , :bar ) {}\", \":\"+nth+\"(2n of:foo,:bar){}\", \"\")\n\t\texpectPrintedMinify(t, \":\"+nth+\"(2n of div , span ) {}\", \":\"+nth+\"(2n of div,span){}\", \"\")\n\n\t\texpectPrintedMangle(t, \":\"+nth+\"(even) { color: red }\", \":\"+nth+\"(2n) {\\n  color: red;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \":\"+nth+\"(2n+1) { color: red }\", \":\"+nth+\"(odd) {\\n  color: red;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \":\"+nth+\"(0n) { color: red }\", \":\"+nth+\"(0) {\\n  color: red;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \":\"+nth+\"(0n+0) { color: red }\", \":\"+nth+\"(0) {\\n  color: red;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \":\"+nth+\"(1n+0) { color: red }\", \":\"+nth+\"(n) {\\n  color: red;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \":\"+nth+\"(0n-2) { color: red }\", \":\"+nth+\"(-2) {\\n  color: red;\\n}\\n\", \"\")\n\t\texpectPrintedMangle(t, \":\"+nth+\"(0n+2) { color: red }\", \":\"+nth+\"(2) {\\n  color: red;\\n}\\n\", \"\")\n\t}\n\n\tfor _, nth := range []string{\"nth-of-type\", \"nth-last-of-type\"} {\n\t\texpectPrinted(t, \":\"+nth+\"(2n of .foo) {}\", \":\"+nth+\"(2n of .foo) {\\n}\\n\",\n\t\t\t\"<stdin>: WARNING: Expected \\\")\\\" to go with \\\"(\\\"\\n<stdin>: NOTE: The unbalanced \\\"(\\\" is here:\\n\")\n\t\texpectPrinted(t, \":\"+nth+\"(+2n + 1) {}\", \":\"+nth+\"(2n+1) {\\n}\\n\", \"\")\n\t}\n}\n\nfunc TestComposes(t *testing.T) {\n\texpectPrinted(t, \".foo { composes: bar; color: red }\", \".foo {\\n  composes: bar;\\n  color: red;\\n}\\n\", \"\")\n\texpectPrinted(t, \".foo .bar { composes: bar; color: red }\", \".foo .bar {\\n  composes: bar;\\n  color: red;\\n}\\n\", \"\")\n\texpectPrinted(t, \".foo, .bar { composes: bar; color: red }\", \".foo,\\n.bar {\\n  composes: bar;\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLocal(t, \".foo { composes: bar; color: red }\", \".foo {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLocal(t, \".foo { composes: bar baz; color: red }\", \".foo {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLocal(t, \".foo { composes: bar from global; color: red }\", \".foo {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLocal(t, \".foo { composes: bar from \\\"file.css\\\"; color: red }\", \".foo {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLocal(t, \".foo { composes: bar from url(file.css); color: red }\", \".foo {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLocal(t, \".foo { & { composes: bar; color: red } }\", \".foo {\\n  & {\\n    color: red;\\n  }\\n}\\n\", \"\")\n\texpectPrintedLocal(t, \".foo { :local { composes: bar; color: red } }\", \".foo {\\n  color: red;\\n}\\n\", \"\")\n\texpectPrintedLocal(t, \".foo { :global { composes: bar; color: red } }\", \".foo {\\n  color: red;\\n}\\n\", \"\")\n\n\texpectPrinted(t, \".foo, .bar { composes: bar from github }\", \".foo,\\n.bar {\\n  composes: bar from github;\\n}\\n\", \"\")\n\texpectPrintedLocal(t, \".foo { composes: bar from github }\", \".foo {\\n}\\n\", \"<stdin>: WARNING: \\\"composes\\\" declaration uses invalid location \\\"github\\\"\\n\")\n\n\tbadComposes := \"<stdin>: WARNING: \\\"composes\\\" only works inside single class selectors\\n\" +\n\t\t\"<stdin>: NOTE: The parent selector is not a single class selector because of the syntax here:\\n\"\n\texpectPrintedLocal(t, \"& { composes: bar; color: red }\", \"& {\\n  color: red;\\n}\\n\", badComposes)\n\texpectPrintedLocal(t, \".foo& { composes: bar; color: red }\", \"&.foo {\\n  color: red;\\n}\\n\", badComposes)\n\texpectPrintedLocal(t, \".foo.bar { composes: bar; color: red }\", \".foo.bar {\\n  color: red;\\n}\\n\", badComposes)\n\texpectPrintedLocal(t, \".foo:hover { composes: bar; color: red }\", \".foo:hover {\\n  color: red;\\n}\\n\", badComposes)\n\texpectPrintedLocal(t, \".foo[href] { composes: bar; color: red }\", \".foo[href] {\\n  color: red;\\n}\\n\", badComposes)\n\texpectPrintedLocal(t, \".foo .bar { composes: bar; color: red }\", \".foo .bar {\\n  color: red;\\n}\\n\", badComposes)\n\texpectPrintedLocal(t, \".foo, div { composes: bar; color: red }\", \".foo,\\ndiv {\\n  color: red;\\n}\\n\", badComposes)\n\texpectPrintedLocal(t, \".foo { .bar { composes: foo; color: red } }\", \".foo {\\n  .bar {\\n    color: red;\\n  }\\n}\\n\", badComposes)\n}\n"
  },
  {
    "path": "internal/css_parser/css_reduce_calc.go",
    "content": "package css_parser\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\nfunc (p *parser) tryToReduceCalcExpression(token css_ast.Token) css_ast.Token {\n\tif term := tryToParseCalcTerm(*token.Children); term != nil {\n\t\twhitespace := css_ast.WhitespaceBefore | css_ast.WhitespaceAfter\n\t\tif p.options.minifyWhitespace {\n\t\t\twhitespace = 0\n\t\t}\n\t\tterm = term.partiallySimplify()\n\t\tif result, ok := term.convertToToken(whitespace); ok {\n\t\t\tif result.Kind == css_lexer.TOpenParen {\n\t\t\t\tresult.Kind = css_lexer.TFunction\n\t\t\t\tresult.Text = \"calc\"\n\t\t\t}\n\t\t\tresult.Loc = token.Loc\n\t\t\tresult.Whitespace = css_ast.WhitespaceBefore | css_ast.WhitespaceAfter\n\t\t\treturn result\n\t\t}\n\t}\n\treturn token\n}\n\ntype calcTermWithOp struct {\n\tdata  calcTerm\n\topLoc logger.Loc\n}\n\n// See: https://www.w3.org/TR/css-values-4/#calc-internal\ntype calcTerm interface {\n\tconvertToToken(whitespace css_ast.WhitespaceFlags) (css_ast.Token, bool)\n\tpartiallySimplify() calcTerm\n}\n\ntype calcSum struct {\n\tterms []calcTermWithOp\n}\n\ntype calcProduct struct {\n\tterms []calcTermWithOp\n}\n\ntype calcNegate struct {\n\tterm calcTermWithOp\n}\n\ntype calcInvert struct {\n\tterm calcTermWithOp\n}\n\ntype calcNumeric struct {\n\tunit   string\n\tnumber float64\n\tloc    logger.Loc\n}\n\ntype calcValue struct {\n\ttoken                css_ast.Token\n\tisInvalidPlusOrMinus bool\n}\n\nfunc floatToStringForCalc(a float64) (string, bool) {\n\t// Handle non-finite cases\n\tif math.IsNaN(a) || math.IsInf(a, 0) {\n\t\treturn \"\", false\n\t}\n\n\t// Print the number as a string\n\ttext := fmt.Sprintf(\"%.05f\", a)\n\tfor text[len(text)-1] == '0' {\n\t\ttext = text[:len(text)-1]\n\t}\n\tif text[len(text)-1] == '.' {\n\t\ttext = text[:len(text)-1]\n\t}\n\tif strings.HasPrefix(text, \"0.\") {\n\t\ttext = text[1:]\n\t} else if strings.HasPrefix(text, \"-0.\") {\n\t\ttext = \"-\" + text[2:]\n\t}\n\n\t// Bail if the number is not exactly represented\n\tif number, err := strconv.ParseFloat(text, 64); err != nil || number != a {\n\t\treturn \"\", false\n\t}\n\n\treturn text, true\n}\n\nfunc (c *calcSum) convertToToken(whitespace css_ast.WhitespaceFlags) (css_ast.Token, bool) {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-serialize\n\ttokens := make([]css_ast.Token, 0, len(c.terms)*2)\n\n\t// ALGORITHM DEVIATION: Avoid parenthesizing product nodes inside sum nodes\n\tif product, ok := c.terms[0].data.(*calcProduct); ok {\n\t\ttoken, ok := product.convertToToken(whitespace)\n\t\tif !ok {\n\t\t\treturn css_ast.Token{}, false\n\t\t}\n\t\ttokens = append(tokens, *token.Children...)\n\t} else {\n\t\ttoken, ok := c.terms[0].data.convertToToken(whitespace)\n\t\tif !ok {\n\t\t\treturn css_ast.Token{}, false\n\t\t}\n\t\ttokens = append(tokens, token)\n\t}\n\n\tfor _, term := range c.terms[1:] {\n\t\t// If child is a Negate node, append \" - \" to s, then serialize the Negate’s child and append the result to s.\n\t\tif negate, ok := term.data.(*calcNegate); ok {\n\t\t\ttoken, ok := negate.term.data.convertToToken(whitespace)\n\t\t\tif !ok {\n\t\t\t\treturn css_ast.Token{}, false\n\t\t\t}\n\t\t\ttokens = append(tokens, css_ast.Token{\n\t\t\t\tLoc:        term.opLoc,\n\t\t\t\tKind:       css_lexer.TDelimMinus,\n\t\t\t\tText:       \"-\",\n\t\t\t\tWhitespace: css_ast.WhitespaceBefore | css_ast.WhitespaceAfter,\n\t\t\t}, token)\n\t\t\tcontinue\n\t\t}\n\n\t\t// If child is a negative numeric value, append \" - \" to s, then serialize the negation of child as normal and append the result to s.\n\t\tif numeric, ok := term.data.(*calcNumeric); ok && numeric.number < 0 {\n\t\t\tclone := *numeric\n\t\t\tclone.number = -clone.number\n\t\t\ttoken, ok := clone.convertToToken(whitespace)\n\t\t\tif !ok {\n\t\t\t\treturn css_ast.Token{}, false\n\t\t\t}\n\t\t\ttokens = append(tokens, css_ast.Token{\n\t\t\t\tLoc:        term.opLoc,\n\t\t\t\tKind:       css_lexer.TDelimMinus,\n\t\t\t\tText:       \"-\",\n\t\t\t\tWhitespace: css_ast.WhitespaceBefore | css_ast.WhitespaceAfter,\n\t\t\t}, token)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Otherwise, append \" + \" to s, then serialize child and append the result to s.\n\t\ttokens = append(tokens, css_ast.Token{\n\t\t\tLoc:        term.opLoc,\n\t\t\tKind:       css_lexer.TDelimPlus,\n\t\t\tText:       \"+\",\n\t\t\tWhitespace: css_ast.WhitespaceBefore | css_ast.WhitespaceAfter,\n\t\t})\n\n\t\t// ALGORITHM DEVIATION: Avoid parenthesizing product nodes inside sum nodes\n\t\tif product, ok := term.data.(*calcProduct); ok {\n\t\t\ttoken, ok := product.convertToToken(whitespace)\n\t\t\tif !ok {\n\t\t\t\treturn css_ast.Token{}, false\n\t\t\t}\n\t\t\ttokens = append(tokens, *token.Children...)\n\t\t} else {\n\t\t\ttoken, ok := term.data.convertToToken(whitespace)\n\t\t\tif !ok {\n\t\t\t\treturn css_ast.Token{}, false\n\t\t\t}\n\t\t\ttokens = append(tokens, token)\n\t\t}\n\t}\n\n\treturn css_ast.Token{\n\t\tLoc:      tokens[0].Loc,\n\t\tKind:     css_lexer.TOpenParen,\n\t\tText:     \"(\",\n\t\tChildren: &tokens,\n\t}, true\n}\n\nfunc (c *calcProduct) convertToToken(whitespace css_ast.WhitespaceFlags) (css_ast.Token, bool) {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-serialize\n\ttokens := make([]css_ast.Token, 0, len(c.terms)*2)\n\ttoken, ok := c.terms[0].data.convertToToken(whitespace)\n\tif !ok {\n\t\treturn css_ast.Token{}, false\n\t}\n\ttokens = append(tokens, token)\n\n\tfor _, term := range c.terms[1:] {\n\t\t// If child is an Invert node, append \" / \" to s, then serialize the Invert’s child and append the result to s.\n\t\tif invert, ok := term.data.(*calcInvert); ok {\n\t\t\ttoken, ok := invert.term.data.convertToToken(whitespace)\n\t\t\tif !ok {\n\t\t\t\treturn css_ast.Token{}, false\n\t\t\t}\n\t\t\ttokens = append(tokens, css_ast.Token{\n\t\t\t\tLoc:        term.opLoc,\n\t\t\t\tKind:       css_lexer.TDelimSlash,\n\t\t\t\tText:       \"/\",\n\t\t\t\tWhitespace: whitespace,\n\t\t\t}, token)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Otherwise, append \" * \" to s, then serialize child and append the result to s.\n\t\ttoken, ok := term.data.convertToToken(whitespace)\n\t\tif !ok {\n\t\t\treturn css_ast.Token{}, false\n\t\t}\n\t\ttokens = append(tokens, css_ast.Token{\n\t\t\tLoc:        term.opLoc,\n\t\t\tKind:       css_lexer.TDelimAsterisk,\n\t\t\tText:       \"*\",\n\t\t\tWhitespace: whitespace,\n\t\t}, token)\n\t}\n\n\treturn css_ast.Token{\n\t\tLoc:      tokens[0].Loc,\n\t\tKind:     css_lexer.TOpenParen,\n\t\tText:     \"(\",\n\t\tChildren: &tokens,\n\t}, true\n}\n\nfunc (c *calcNegate) convertToToken(whitespace css_ast.WhitespaceFlags) (css_ast.Token, bool) {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-serialize\n\ttoken, ok := c.term.data.convertToToken(whitespace)\n\tif !ok {\n\t\treturn css_ast.Token{}, false\n\t}\n\treturn css_ast.Token{\n\t\tKind: css_lexer.TOpenParen,\n\t\tText: \"(\",\n\t\tChildren: &[]css_ast.Token{\n\t\t\t{Loc: c.term.opLoc, Kind: css_lexer.TNumber, Text: \"-1\"},\n\t\t\t{Loc: c.term.opLoc, Kind: css_lexer.TDelimSlash, Text: \"*\", Whitespace: css_ast.WhitespaceBefore | css_ast.WhitespaceAfter},\n\t\t\ttoken,\n\t\t},\n\t}, true\n}\n\nfunc (c *calcInvert) convertToToken(whitespace css_ast.WhitespaceFlags) (css_ast.Token, bool) {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-serialize\n\ttoken, ok := c.term.data.convertToToken(whitespace)\n\tif !ok {\n\t\treturn css_ast.Token{}, false\n\t}\n\treturn css_ast.Token{\n\t\tKind: css_lexer.TOpenParen,\n\t\tText: \"(\",\n\t\tChildren: &[]css_ast.Token{\n\t\t\t{Loc: c.term.opLoc, Kind: css_lexer.TNumber, Text: \"1\"},\n\t\t\t{Loc: c.term.opLoc, Kind: css_lexer.TDelimSlash, Text: \"/\", Whitespace: css_ast.WhitespaceBefore | css_ast.WhitespaceAfter},\n\t\t\ttoken,\n\t\t},\n\t}, true\n}\n\nfunc (c *calcNumeric) convertToToken(whitespace css_ast.WhitespaceFlags) (css_ast.Token, bool) {\n\ttext, ok := floatToStringForCalc(c.number)\n\tif !ok {\n\t\treturn css_ast.Token{}, false\n\t}\n\tif c.unit == \"\" {\n\t\treturn css_ast.Token{\n\t\t\tLoc:  c.loc,\n\t\t\tKind: css_lexer.TNumber,\n\t\t\tText: text,\n\t\t}, true\n\t}\n\tif c.unit == \"%\" {\n\t\treturn css_ast.Token{\n\t\t\tLoc:  c.loc,\n\t\t\tKind: css_lexer.TPercentage,\n\t\t\tText: text + \"%\",\n\t\t}, true\n\t}\n\treturn css_ast.Token{\n\t\tLoc:        c.loc,\n\t\tKind:       css_lexer.TDimension,\n\t\tText:       text + c.unit,\n\t\tUnitOffset: uint16(len(text)),\n\t}, true\n}\n\nfunc (c *calcValue) convertToToken(whitespace css_ast.WhitespaceFlags) (css_ast.Token, bool) {\n\tt := c.token\n\tt.Whitespace = 0\n\treturn t, true\n}\n\nfunc (c *calcSum) partiallySimplify() calcTerm {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-simplification\n\n\t// For each of root’s children that are Sum nodes, replace them with their children.\n\tterms := make([]calcTermWithOp, 0, len(c.terms))\n\tfor _, term := range c.terms {\n\t\tterm.data = term.data.partiallySimplify()\n\t\tif sum, ok := term.data.(*calcSum); ok {\n\t\t\tterms = append(terms, sum.terms...)\n\t\t} else {\n\t\t\tterms = append(terms, term)\n\t\t}\n\t}\n\n\t// For each set of root’s children that are numeric values with identical units, remove\n\t// those children and replace them with a single numeric value containing the sum of the\n\t// removed nodes, and with the same unit. (E.g. combine numbers, combine percentages,\n\t// combine px values, etc.)\n\tfor i := 0; i < len(terms); i++ {\n\t\tterm := terms[i]\n\t\tif numeric, ok := term.data.(*calcNumeric); ok {\n\t\t\tend := i + 1\n\t\t\tfor j := end; j < len(terms); j++ {\n\t\t\t\tterm2 := terms[j]\n\t\t\t\tif numeric2, ok := term2.data.(*calcNumeric); ok && strings.EqualFold(numeric2.unit, numeric.unit) {\n\t\t\t\t\tnumeric.number += numeric2.number\n\t\t\t\t} else {\n\t\t\t\t\tterms[end] = term2\n\t\t\t\t\tend++\n\t\t\t\t}\n\t\t\t}\n\t\t\tterms = terms[:end]\n\t\t}\n\t}\n\n\t// If root has only a single child at this point, return the child.\n\tif len(terms) == 1 {\n\t\treturn terms[0].data\n\t}\n\n\t// Otherwise, return root.\n\tc.terms = terms\n\treturn c\n}\n\nfunc (c *calcProduct) partiallySimplify() calcTerm {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-simplification\n\n\t// For each of root’s children that are Product nodes, replace them with their children.\n\tterms := make([]calcTermWithOp, 0, len(c.terms))\n\tfor _, term := range c.terms {\n\t\tterm.data = term.data.partiallySimplify()\n\t\tif product, ok := term.data.(*calcProduct); ok {\n\t\t\tterms = append(terms, product.terms...)\n\t\t} else {\n\t\t\tterms = append(terms, term)\n\t\t}\n\t}\n\n\t// If root has multiple children that are numbers (not percentages or dimensions), remove\n\t// them and replace them with a single number containing the product of the removed nodes.\n\tfor i, term := range terms {\n\t\tif numeric, ok := term.data.(*calcNumeric); ok && numeric.unit == \"\" {\n\t\t\tend := i + 1\n\t\t\tfor j := end; j < len(terms); j++ {\n\t\t\t\tterm2 := terms[j]\n\t\t\t\tif numeric2, ok := term2.data.(*calcNumeric); ok && numeric2.unit == \"\" {\n\t\t\t\t\tnumeric.number *= numeric2.number\n\t\t\t\t} else {\n\t\t\t\t\tterms[end] = term2\n\t\t\t\t\tend++\n\t\t\t\t}\n\t\t\t}\n\t\t\tterms = terms[:end]\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// If root contains only numeric values and/or Invert nodes containing numeric values,\n\t// and multiplying the types of all the children (noting that the type of an Invert\n\t// node is the inverse of its child’s type) results in a type that matches any of the\n\t// types that a math function can resolve to, return the result of multiplying all the\n\t// values of the children (noting that the value of an Invert node is the reciprocal\n\t// of its child’s value), expressed in the result’s canonical unit.\n\tif len(terms) == 2 {\n\t\t// Right now, only handle the case of two numbers, one of which has no unit\n\t\tif first, ok := terms[0].data.(*calcNumeric); ok {\n\t\t\tif second, ok := terms[1].data.(*calcNumeric); ok {\n\t\t\t\tif first.unit == \"\" {\n\t\t\t\t\tsecond.number *= first.number\n\t\t\t\t\treturn second\n\t\t\t\t}\n\t\t\t\tif second.unit == \"\" {\n\t\t\t\t\tfirst.number *= second.number\n\t\t\t\t\treturn first\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// ALGORITHM DEVIATION: Divide instead of multiply if the reciprocal is shorter\n\tfor i := 1; i < len(terms); i++ {\n\t\tif numeric, ok := terms[i].data.(*calcNumeric); ok {\n\t\t\treciprocal := 1 / numeric.number\n\t\t\tif multiply, ok := floatToStringForCalc(numeric.number); ok {\n\t\t\t\tif divide, ok := floatToStringForCalc(reciprocal); ok && len(divide) < len(multiply) {\n\t\t\t\t\tnumeric.number = reciprocal\n\t\t\t\t\tterms[i].data = &calcInvert{term: calcTermWithOp{\n\t\t\t\t\t\tdata:  numeric,\n\t\t\t\t\t\topLoc: terms[i].opLoc,\n\t\t\t\t\t}}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// If root has only a single child at this point, return the child.\n\tif len(terms) == 1 {\n\t\treturn terms[0].data\n\t}\n\n\t// Otherwise, return root.\n\tc.terms = terms\n\treturn c\n}\n\nfunc (c *calcNegate) partiallySimplify() calcTerm {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-simplification\n\n\tc.term.data = c.term.data.partiallySimplify()\n\n\t// If root’s child is a numeric value, return an equivalent numeric value, but with the value negated (0 - value).\n\tif numeric, ok := c.term.data.(*calcNumeric); ok {\n\t\tnumeric.number = -numeric.number\n\t\treturn numeric\n\t}\n\n\t// If root’s child is a Negate node, return the child’s child.\n\tif negate, ok := c.term.data.(*calcNegate); ok {\n\t\treturn negate.term.data\n\t}\n\n\treturn c\n}\n\nfunc (c *calcInvert) partiallySimplify() calcTerm {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-simplification\n\n\tc.term.data = c.term.data.partiallySimplify()\n\n\t// If root’s child is a number (not a percentage or dimension) return the reciprocal of the child’s value.\n\tif numeric, ok := c.term.data.(*calcNumeric); ok && numeric.unit == \"\" {\n\t\tnumeric.number = 1 / numeric.number\n\t\treturn numeric\n\t}\n\n\t// If root’s child is an Invert node, return the child’s child.\n\tif invert, ok := c.term.data.(*calcInvert); ok {\n\t\treturn invert.term.data\n\t}\n\n\treturn c\n}\n\nfunc (c *calcNumeric) partiallySimplify() calcTerm {\n\treturn c\n}\n\nfunc (c *calcValue) partiallySimplify() calcTerm {\n\treturn c\n}\n\nfunc tryToParseCalcTerm(tokens []css_ast.Token) calcTerm {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-internal\n\tterms := make([]calcTermWithOp, len(tokens))\n\n\tfor i, token := range tokens {\n\t\tvar term calcTerm\n\t\tif token.Kind == css_lexer.TFunction && strings.EqualFold(token.Text, \"var\") {\n\t\t\t// Using \"var()\" should bail because it can expand to any number of tokens\n\t\t\treturn nil\n\t\t} else if token.Kind == css_lexer.TOpenParen || (token.Kind == css_lexer.TFunction && strings.EqualFold(token.Text, \"calc\")) {\n\t\t\tterm = tryToParseCalcTerm(*token.Children)\n\t\t\tif term == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t} else if token.Kind == css_lexer.TNumber {\n\t\t\tif number, err := strconv.ParseFloat(token.Text, 64); err == nil {\n\t\t\t\tterm = &calcNumeric{loc: token.Loc, number: number}\n\t\t\t} else {\n\t\t\t\tterm = &calcValue{token: token}\n\t\t\t}\n\t\t} else if token.Kind == css_lexer.TPercentage {\n\t\t\tif number, err := strconv.ParseFloat(token.PercentageValue(), 64); err == nil {\n\t\t\t\tterm = &calcNumeric{loc: token.Loc, number: number, unit: \"%\"}\n\t\t\t} else {\n\t\t\t\tterm = &calcValue{token: token}\n\t\t\t}\n\t\t} else if token.Kind == css_lexer.TDimension {\n\t\t\tif number, err := strconv.ParseFloat(token.DimensionValue(), 64); err == nil {\n\t\t\t\tterm = &calcNumeric{loc: token.Loc, number: number, unit: token.DimensionUnit()}\n\t\t\t} else {\n\t\t\t\tterm = &calcValue{token: token}\n\t\t\t}\n\t\t} else if token.Kind == css_lexer.TIdent && strings.EqualFold(token.Text, \"Infinity\") {\n\t\t\tterm = &calcNumeric{loc: token.Loc, number: math.Inf(1)}\n\t\t} else if token.Kind == css_lexer.TIdent && strings.EqualFold(token.Text, \"-Infinity\") {\n\t\t\tterm = &calcNumeric{loc: token.Loc, number: math.Inf(-1)}\n\t\t} else if token.Kind == css_lexer.TIdent && strings.EqualFold(token.Text, \"NaN\") {\n\t\t\tterm = &calcNumeric{loc: token.Loc, number: math.NaN()}\n\t\t} else {\n\t\t\tterm = &calcValue{\n\t\t\t\ttoken: token,\n\n\t\t\t\t// From the specification: \"In addition, whitespace is required on both sides of the\n\t\t\t\t// + and - operators. (The * and / operators can be used without white space around them.)\"\n\t\t\t\tisInvalidPlusOrMinus: i > 0 && i+1 < len(tokens) &&\n\t\t\t\t\t(token.Kind == css_lexer.TDelimPlus || token.Kind == css_lexer.TDelimMinus) &&\n\t\t\t\t\t(((token.Whitespace&css_ast.WhitespaceBefore) == 0 && (tokens[i-1].Whitespace&css_ast.WhitespaceAfter) == 0) ||\n\t\t\t\t\t\t(token.Whitespace&css_ast.WhitespaceAfter) == 0 && (tokens[i+1].Whitespace&css_ast.WhitespaceBefore) == 0),\n\t\t\t}\n\t\t}\n\t\tterms[i].data = term\n\t}\n\n\t// Collect children into Product and Invert nodes\n\tfirst := 1\n\tfor first+1 < len(terms) {\n\t\t// If this is a \"*\" or \"/\" operator\n\t\tif value, ok := terms[first].data.(*calcValue); ok && (value.token.Kind == css_lexer.TDelimAsterisk || value.token.Kind == css_lexer.TDelimSlash) {\n\t\t\t// Scan over the run\n\t\t\tlast := first\n\t\t\tfor last+3 < len(terms) {\n\t\t\t\tif value, ok := terms[last+2].data.(*calcValue); ok && (value.token.Kind == css_lexer.TDelimAsterisk || value.token.Kind == css_lexer.TDelimSlash) {\n\t\t\t\t\tlast += 2\n\t\t\t\t} else {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Generate a node for the run\n\t\t\tproduct := calcProduct{terms: make([]calcTermWithOp, (last-first)/2+2)}\n\t\t\tfor i := range product.terms {\n\t\t\t\tterm := terms[first+i*2-1]\n\t\t\t\tif i > 0 {\n\t\t\t\t\top := terms[first+i*2-2].data.(*calcValue).token\n\t\t\t\t\tterm.opLoc = op.Loc\n\t\t\t\t\tif op.Kind == css_lexer.TDelimSlash {\n\t\t\t\t\t\tterm.data = &calcInvert{term: term}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tproduct.terms[i] = term\n\t\t\t}\n\n\t\t\t// Replace the run with a single node\n\t\t\tterms[first-1].data = &product\n\t\t\tterms = append(terms[:first], terms[last+2:]...)\n\t\t\tcontinue\n\t\t}\n\n\t\tfirst++\n\t}\n\n\t// Collect children into Sum and Negate nodes\n\tfirst = 1\n\tfor first+1 < len(terms) {\n\t\t// If this is a \"+\" or \"-\" operator\n\t\tif value, ok := terms[first].data.(*calcValue); ok && !value.isInvalidPlusOrMinus &&\n\t\t\t(value.token.Kind == css_lexer.TDelimPlus || value.token.Kind == css_lexer.TDelimMinus) {\n\t\t\t// Scan over the run\n\t\t\tlast := first\n\t\t\tfor last+3 < len(terms) {\n\t\t\t\tif value, ok := terms[last+2].data.(*calcValue); ok && !value.isInvalidPlusOrMinus &&\n\t\t\t\t\t(value.token.Kind == css_lexer.TDelimPlus || value.token.Kind == css_lexer.TDelimMinus) {\n\t\t\t\t\tlast += 2\n\t\t\t\t} else {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Generate a node for the run\n\t\t\tsum := calcSum{terms: make([]calcTermWithOp, (last-first)/2+2)}\n\t\t\tfor i := range sum.terms {\n\t\t\t\tterm := terms[first+i*2-1]\n\t\t\t\tif i > 0 {\n\t\t\t\t\top := terms[first+i*2-2].data.(*calcValue).token\n\t\t\t\t\tterm.opLoc = op.Loc\n\t\t\t\t\tif op.Kind == css_lexer.TDelimMinus {\n\t\t\t\t\t\tterm.data = &calcNegate{term: term}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsum.terms[i] = term\n\t\t\t}\n\n\t\t\t// Replace the run with a single node\n\t\t\tterms[first-1].data = &sum\n\t\t\tterms = append(terms[:first], terms[last+2:]...)\n\t\t\tcontinue\n\t\t}\n\n\t\tfirst++\n\t}\n\n\t// This only succeeds if everything reduces to a single term\n\tif len(terms) == 1 {\n\t\treturn terms[0].data\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "internal/css_printer/css_printer.go",
    "content": "package css_printer\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/sourcemap\"\n)\n\nconst quoteForURL byte = 0\n\ntype printer struct {\n\toptions                Options\n\tsymbols                ast.SymbolMap\n\timportRecords          []ast.ImportRecord\n\tcss                    []byte\n\thasLegalComment        map[string]struct{}\n\textractedLegalComments []string\n\tjsonMetadataImports    []string\n\tbuilder                sourcemap.ChunkBuilder\n\toldLineStart           int\n\toldLineEnd             int\n}\n\ntype Options struct {\n\t// This will be present if the input file had a source map. In that case we\n\t// want to map all the way back to the original input file(s).\n\tInputSourceMap *sourcemap.SourceMap\n\n\t// If we're writing out a source map, this table of line start indices lets\n\t// us do binary search on to figure out what line a given AST node came from\n\tLineOffsetTables []sourcemap.LineOffsetTable\n\n\t// Local symbol renaming results go here\n\tLocalNames map[ast.Ref]string\n\n\tLineLimit           int\n\tInputSourceIndex    uint32\n\tUnsupportedFeatures compat.CSSFeature\n\tMinifyWhitespace    bool\n\tASCIIOnly           bool\n\tSourceMap           config.SourceMap\n\tAddSourceMappings   bool\n\tLegalComments       config.LegalComments\n\tNeedsMetafile       bool\n\tMetafileFormat      config.MetafileFormat\n}\n\ntype PrintResult struct {\n\tCSS                    []byte\n\tExtractedLegalComments []string\n\tJSONMetadataImports    []string\n\n\t// This source map chunk just contains the VLQ-encoded offsets for the \"CSS\"\n\t// field above. It's not a full source map. The bundler will be joining many\n\t// source map chunks together to form the final source map.\n\tSourceMapChunk sourcemap.Chunk\n}\n\nfunc Print(tree css_ast.AST, symbols ast.SymbolMap, options Options) PrintResult {\n\tp := printer{\n\t\toptions:       options,\n\t\tsymbols:       symbols,\n\t\timportRecords: tree.ImportRecords,\n\t\tbuilder:       sourcemap.MakeChunkBuilder(options.InputSourceMap, options.LineOffsetTables, options.ASCIIOnly),\n\t}\n\tfor _, rule := range tree.Rules {\n\t\tp.printRule(rule, 0, false)\n\t}\n\tresult := PrintResult{\n\t\tCSS:                    p.css,\n\t\tExtractedLegalComments: p.extractedLegalComments,\n\t\tJSONMetadataImports:    p.jsonMetadataImports,\n\t}\n\tif options.SourceMap != config.SourceMapNone {\n\t\t// This is expensive. Only do this if it's necessary. For example, skipping\n\t\t// this if it's not needed sped up end-to-end parsing and printing of a\n\t\t// large CSS file from 66ms to 52ms (around 25% faster).\n\t\tresult.SourceMapChunk = p.builder.GenerateChunk(p.css)\n\t}\n\treturn result\n}\n\nfunc (p *printer) recordImportPathForMetafile(importRecordIndex uint32) {\n\tif p.options.NeedsMetafile {\n\t\trecord := p.importRecords[importRecordIndex]\n\t\texternal := \"\"\n\t\tif (record.Flags & ast.ShouldNotBeExternalInMetafile) == 0 {\n\t\t\texternal = p.options.MetafileFormat.MaybeRemoveWhitespace(\",\\n          \\\"external\\\": true\")\n\t\t}\n\t\tp.jsonMetadataImports = append(p.jsonMetadataImports, fmt.Sprintf(\n\t\t\tp.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n        {\\n          \\\"path\\\": %s,\\n          \\\"kind\\\": %s%s\\n        }\"),\n\t\t\thelpers.QuoteForJSON(record.Path.Text, p.options.ASCIIOnly),\n\t\t\thelpers.QuoteForJSON(record.Kind.StringForMetafile(), p.options.ASCIIOnly),\n\t\t\texternal))\n\t}\n}\n\nfunc (p *printer) printRule(rule css_ast.Rule, indent int32, omitTrailingSemicolon bool) {\n\tif r, ok := rule.Data.(*css_ast.RComment); ok {\n\t\tswitch p.options.LegalComments {\n\t\tcase config.LegalCommentsNone:\n\t\t\treturn\n\n\t\tcase config.LegalCommentsEndOfFile,\n\t\t\tconfig.LegalCommentsLinkedWithComment,\n\t\t\tconfig.LegalCommentsExternalWithoutComment:\n\n\t\t\t// Don't record the same legal comment more than once per file\n\t\t\tif p.hasLegalComment == nil {\n\t\t\t\tp.hasLegalComment = make(map[string]struct{})\n\t\t\t} else if _, ok := p.hasLegalComment[r.Text]; ok {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tp.hasLegalComment[r.Text] = struct{}{}\n\t\t\tp.extractedLegalComments = append(p.extractedLegalComments, r.Text)\n\t\t\treturn\n\t\t}\n\t}\n\n\tif p.options.LineLimit > 0 {\n\t\tp.printNewlinePastLineLimit(indent)\n\t}\n\n\tif p.options.AddSourceMappings {\n\t\tshouldPrintMapping := true\n\t\tif indent == 0 || p.options.MinifyWhitespace {\n\t\t\tswitch rule.Data.(type) {\n\t\t\tcase *css_ast.RSelector, *css_ast.RQualified, *css_ast.RBadDeclaration:\n\t\t\t\t// These rules will begin with a potentially more accurate mapping. We\n\t\t\t\t// shouldn't print a mapping here if there's no indent in between this\n\t\t\t\t// mapping and the rule.\n\t\t\t\tshouldPrintMapping = false\n\t\t\t}\n\t\t}\n\t\tif shouldPrintMapping {\n\t\t\tp.builder.AddSourceMapping(rule.Loc, \"\", p.css)\n\t\t}\n\t}\n\n\tif !p.options.MinifyWhitespace {\n\t\tp.printIndent(indent)\n\t}\n\n\tswitch r := rule.Data.(type) {\n\tcase *css_ast.RAtCharset:\n\t\t// It's not valid to remove the space in between these two tokens\n\t\tp.print(\"@charset \")\n\n\t\t// It's not valid to print the string with single quotes\n\t\tp.printQuotedWithQuote(r.Encoding, '\"', 0)\n\t\tp.print(\";\")\n\n\tcase *css_ast.RAtImport:\n\t\tif p.options.MinifyWhitespace {\n\t\t\tp.print(\"@import\")\n\t\t} else {\n\t\t\tp.print(\"@import \")\n\t\t}\n\t\trecord := p.importRecords[r.ImportRecordIndex]\n\t\tvar flags printQuotedFlags\n\t\tif record.Flags.Has(ast.ContainsUniqueKey) {\n\t\t\tflags |= printQuotedNoWrap\n\t\t}\n\t\tp.printQuoted(record.Path.Text, flags)\n\t\tp.recordImportPathForMetafile(r.ImportRecordIndex)\n\t\tif conditions := r.ImportConditions; conditions != nil {\n\t\t\tspace := !p.options.MinifyWhitespace\n\t\t\tif len(conditions.Layers) > 0 {\n\t\t\t\tif space {\n\t\t\t\t\tp.print(\" \")\n\t\t\t\t}\n\t\t\t\tp.printTokens(conditions.Layers, printTokensOpts{})\n\t\t\t\tspace = true\n\t\t\t}\n\t\t\tif len(conditions.Supports) > 0 {\n\t\t\t\tif space {\n\t\t\t\t\tp.print(\" \")\n\t\t\t\t}\n\t\t\t\tp.printTokens(conditions.Supports, printTokensOpts{})\n\t\t\t\tspace = true\n\t\t\t}\n\t\t\tif len(conditions.Queries) > 0 {\n\t\t\t\tif space {\n\t\t\t\t\tp.print(\" \")\n\t\t\t\t}\n\t\t\t\tfor i, query := range conditions.Queries {\n\t\t\t\t\tif i > 0 {\n\t\t\t\t\t\tif p.options.MinifyWhitespace {\n\t\t\t\t\t\t\tp.print(\",\")\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tp.print(\", \")\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tp.printMediaQuery(query, 0)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tp.print(\";\")\n\n\tcase *css_ast.RAtKeyframes:\n\t\tp.print(\"@\")\n\t\tp.printIdent(r.AtToken, identNormal, mayNeedWhitespaceAfter)\n\t\tp.print(\" \")\n\t\tp.printSymbol(r.Name.Loc, r.Name.Ref, identNormal, canDiscardWhitespaceAfter)\n\t\tif !p.options.MinifyWhitespace {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tif p.options.MinifyWhitespace {\n\t\t\tp.print(\"{\")\n\t\t} else {\n\t\t\tp.print(\"{\\n\")\n\t\t}\n\t\tindent++\n\t\tfor _, block := range r.Blocks {\n\t\t\tif p.options.AddSourceMappings {\n\t\t\t\tp.builder.AddSourceMapping(block.Loc, \"\", p.css)\n\t\t\t}\n\t\t\tif !p.options.MinifyWhitespace {\n\t\t\t\tp.printIndent(indent)\n\t\t\t}\n\t\t\tfor i, sel := range block.Selectors {\n\t\t\t\tif i > 0 {\n\t\t\t\t\tif p.options.MinifyWhitespace {\n\t\t\t\t\t\tp.print(\",\")\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.print(\", \")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tp.print(sel)\n\t\t\t}\n\t\t\tif !p.options.MinifyWhitespace {\n\t\t\t\tp.print(\" \")\n\t\t\t}\n\t\t\tp.printRuleBlock(block.Rules, indent, block.CloseBraceLoc)\n\t\t\tif !p.options.MinifyWhitespace {\n\t\t\t\tp.print(\"\\n\")\n\t\t\t}\n\t\t}\n\t\tindent--\n\t\tif p.options.AddSourceMappings && r.CloseBraceLoc.Start != 0 {\n\t\t\tp.builder.AddSourceMapping(r.CloseBraceLoc, \"\", p.css)\n\t\t}\n\t\tif !p.options.MinifyWhitespace {\n\t\t\tp.printIndent(indent)\n\t\t}\n\t\tp.print(\"}\")\n\n\tcase *css_ast.RKnownAt:\n\t\tp.print(\"@\")\n\t\twhitespace := mayNeedWhitespaceAfter\n\t\tif len(r.Prelude) == 0 {\n\t\t\twhitespace = canDiscardWhitespaceAfter\n\t\t}\n\t\tp.printIdent(r.AtToken, identNormal, whitespace)\n\t\tif (!p.options.MinifyWhitespace && r.Rules != nil) || len(r.Prelude) > 0 {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tp.printTokens(r.Prelude, printTokensOpts{})\n\t\tif r.Rules == nil {\n\t\t\tp.print(\";\")\n\t\t} else {\n\t\t\tif !p.options.MinifyWhitespace && len(r.Prelude) > 0 {\n\t\t\t\tp.print(\" \")\n\t\t\t}\n\t\t\tp.printRuleBlock(r.Rules, indent, r.CloseBraceLoc)\n\t\t}\n\n\tcase *css_ast.RUnknownAt:\n\t\tp.print(\"@\")\n\t\twhitespace := mayNeedWhitespaceAfter\n\t\tif len(r.Prelude) == 0 {\n\t\t\twhitespace = canDiscardWhitespaceAfter\n\t\t}\n\t\tp.printIdent(r.AtToken, identNormal, whitespace)\n\t\tif (!p.options.MinifyWhitespace && len(r.Block) != 0) || len(r.Prelude) > 0 {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tp.printTokens(r.Prelude, printTokensOpts{})\n\t\tif !p.options.MinifyWhitespace && len(r.Block) != 0 && len(r.Prelude) > 0 {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tif len(r.Block) == 0 {\n\t\t\tp.print(\";\")\n\t\t} else {\n\t\t\tp.printTokens(r.Block, printTokensOpts{})\n\t\t}\n\n\tcase *css_ast.RSelector:\n\t\tp.printComplexSelectors(r.Selectors, indent, layoutMultiLine)\n\t\tif !p.options.MinifyWhitespace {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tp.printRuleBlock(r.Rules, indent, r.CloseBraceLoc)\n\n\tcase *css_ast.RQualified:\n\t\thasWhitespaceAfter := p.printTokens(r.Prelude, printTokensOpts{})\n\t\tif !hasWhitespaceAfter && !p.options.MinifyWhitespace {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tp.printRuleBlock(r.Rules, indent, r.CloseBraceLoc)\n\n\tcase *css_ast.RDeclaration:\n\t\tp.printIdent(r.KeyText, identNormal, canDiscardWhitespaceAfter)\n\t\tp.print(\":\")\n\t\thasWhitespaceAfter := p.printTokens(r.Value, printTokensOpts{\n\t\t\tindent:        indent,\n\t\t\tisDeclaration: true,\n\t\t})\n\t\tif r.Important {\n\t\t\tif !hasWhitespaceAfter && !p.options.MinifyWhitespace && len(r.Value) > 0 {\n\t\t\t\tp.print(\" \")\n\t\t\t}\n\t\t\tp.print(\"!important\")\n\t\t}\n\t\tif !omitTrailingSemicolon {\n\t\t\tp.print(\";\")\n\t\t}\n\n\tcase *css_ast.RBadDeclaration:\n\t\tp.printTokens(r.Tokens, printTokensOpts{})\n\t\tif !omitTrailingSemicolon {\n\t\t\tp.print(\";\")\n\t\t}\n\n\tcase *css_ast.RComment:\n\t\tp.printIndentedComment(indent, r.Text)\n\n\tcase *css_ast.RAtLayer:\n\t\tp.print(\"@layer\")\n\t\tfor i, parts := range r.Names {\n\t\t\tif i == 0 {\n\t\t\t\tp.print(\" \")\n\t\t\t} else if !p.options.MinifyWhitespace {\n\t\t\t\tp.print(\", \")\n\t\t\t} else {\n\t\t\t\tp.print(\",\")\n\t\t\t}\n\t\t\tp.print(strings.Join(parts, \".\"))\n\t\t}\n\t\tif r.Rules == nil {\n\t\t\tp.print(\";\")\n\t\t} else {\n\t\t\tif !p.options.MinifyWhitespace {\n\t\t\t\tp.print(\" \")\n\t\t\t}\n\t\t\tp.printRuleBlock(r.Rules, indent, r.CloseBraceLoc)\n\t\t}\n\n\tcase *css_ast.RAtMedia:\n\t\tp.print(\"@media\")\n\t\tvar flags mqFlags\n\t\tif p.options.MinifyWhitespace {\n\t\t\tflags = mqAfterIdentifier\n\t\t} else {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tfor i, query := range r.Queries {\n\t\t\tif i > 0 {\n\t\t\t\tif p.options.MinifyWhitespace {\n\t\t\t\t\tp.print(\",\")\n\t\t\t\t} else {\n\t\t\t\t\tp.print(\", \")\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.printMediaQuery(query, flags)\n\t\t\tflags = 0\n\t\t}\n\t\tif !p.options.MinifyWhitespace && len(r.Queries) > 0 {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tp.printRuleBlock(r.Rules, indent, r.CloseBraceLoc)\n\n\tcase *css_ast.RAtScope:\n\t\tp.print(\"@scope\")\n\t\tif len(r.Start) > 0 {\n\t\t\tif p.options.MinifyWhitespace {\n\t\t\t\tp.print(\"(\")\n\t\t\t} else {\n\t\t\t\tp.print(\" (\")\n\t\t\t}\n\t\t\tp.printComplexSelectors(r.Start, indent, layoutSingleLine)\n\t\t\tp.print(\")\")\n\t\t}\n\t\tif len(r.End) > 0 {\n\t\t\tif p.options.MinifyWhitespace {\n\t\t\t\tp.print(\"to (\")\n\t\t\t} else {\n\t\t\t\tp.print(\" to (\")\n\t\t\t}\n\t\t\tp.printComplexSelectors(r.End, indent, layoutSingleLine)\n\t\t\tp.print(\")\")\n\t\t}\n\t\tif !p.options.MinifyWhitespace {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tp.printRuleBlock(r.Rules, indent, r.CloseBraceLoc)\n\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n\n\tif !p.options.MinifyWhitespace {\n\t\tp.print(\"\\n\")\n\t}\n}\n\ntype mqFlags uint8\n\nconst (\n\tmqNeedsParens mqFlags = 1 << iota\n\tmqAfterIdentifier\n)\n\nfunc (p *printer) printMediaQuery(query css_ast.MediaQuery, flags mqFlags) {\n\tif q, ok := query.Data.(*css_ast.MQArbitraryTokens); ok {\n\t\tif (flags & mqAfterIdentifier) != 0 {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tp.printTokens(q.Tokens, printTokensOpts{})\n\t\treturn\n\t}\n\n\tswitch q := query.Data.(type) {\n\tcase *css_ast.MQType:\n\t\tif (flags & mqAfterIdentifier) != 0 {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tif p.options.AddSourceMappings {\n\t\t\tp.builder.AddSourceMapping(query.Loc, \"\", p.css)\n\t\t}\n\t\tswitch q.Op {\n\t\tcase css_ast.MQTypeOpNot:\n\t\t\tp.print(\"not \")\n\t\tcase css_ast.MQTypeOpOnly:\n\t\t\tp.print(\"only \")\n\t\t}\n\t\tp.printIdent(q.Type, identNormal, 0)\n\t\tif q.AndOrNull.Data != nil {\n\t\t\tp.print(\" and \")\n\t\t\tvar flags mqFlags\n\t\t\tif binary, ok := q.AndOrNull.Data.(*css_ast.MQBinary); ok && binary.Op == css_ast.MQBinaryOpOr {\n\t\t\t\tflags = mqNeedsParens\n\t\t\t}\n\t\t\tp.printMediaQuery(q.AndOrNull, flags)\n\t\t}\n\n\tcase *css_ast.MQNot:\n\t\tif (flags & mqNeedsParens) != 0 {\n\t\t\tp.print(\"(\")\n\t\t} else if (flags & mqAfterIdentifier) != 0 {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tif p.options.AddSourceMappings {\n\t\t\tp.builder.AddSourceMapping(query.Loc, \"\", p.css)\n\t\t}\n\t\tp.print(\"not \")\n\t\tp.printMediaQuery(q.Inner, mqNeedsParens)\n\t\tif (flags & mqNeedsParens) != 0 {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *css_ast.MQBinary:\n\t\tif (flags & mqNeedsParens) != 0 {\n\t\t\tp.print(\"(\")\n\t\t}\n\t\tfor i, inner := range q.Terms {\n\t\t\tif i > 0 {\n\t\t\t\tif !p.options.MinifyWhitespace {\n\t\t\t\t\tp.print(\" \")\n\t\t\t\t}\n\t\t\t\tswitch q.Op {\n\t\t\t\tcase css_ast.MQBinaryOpAnd:\n\t\t\t\t\tp.print(\"and \")\n\t\t\t\tcase css_ast.MQBinaryOpOr:\n\t\t\t\t\tp.print(\"or \")\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.printMediaQuery(inner, mqNeedsParens)\n\t\t}\n\t\tif (flags & mqNeedsParens) != 0 {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *css_ast.MQPlainOrBoolean:\n\t\tp.print(\"(\")\n\t\tif p.options.AddSourceMappings {\n\t\t\tp.builder.AddSourceMapping(query.Loc, \"\", p.css)\n\t\t}\n\t\tp.printIdent(q.Name, identNormal, 0)\n\t\tif q.ValueOrNil != nil {\n\t\t\tif p.options.MinifyWhitespace {\n\t\t\t\tp.print(\":\")\n\t\t\t} else {\n\t\t\t\tp.print(\": \")\n\t\t\t}\n\t\t\tp.printTokens(q.ValueOrNil, printTokensOpts{})\n\t\t}\n\t\tp.print(\")\")\n\n\tcase *css_ast.MQRange:\n\t\tspace := \" \"\n\t\tif p.options.MinifyWhitespace {\n\t\t\tspace = \"\"\n\t\t}\n\t\tp.print(\"(\")\n\t\tif q.BeforeCmp != css_ast.MQCmpNone {\n\t\t\tp.printTokens(q.Before, printTokensOpts{})\n\t\t\tp.print(space)\n\t\t\tp.print(q.BeforeCmp.String())\n\t\t\tp.print(space)\n\t\t}\n\t\tif p.options.AddSourceMappings {\n\t\t\tp.builder.AddSourceMapping(q.NameLoc, \"\", p.css)\n\t\t}\n\t\tp.printIdent(q.Name, identNormal, 0)\n\t\tif q.AfterCmp != css_ast.MQCmpNone {\n\t\t\tp.print(space)\n\t\t\tp.print(q.AfterCmp.String())\n\t\t\tp.print(space)\n\t\t\tp.printTokens(q.After, printTokensOpts{})\n\t\t}\n\t\tp.print(\")\")\n\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\nfunc (p *printer) printIndentedComment(indent int32, text string) {\n\t// Avoid generating a comment containing the character sequence \"</style\"\n\tif !p.options.UnsupportedFeatures.Has(compat.InlineStyle) {\n\t\ttext = helpers.EscapeClosingTag(text, \"/style\")\n\t}\n\n\t// Re-indent multi-line comments\n\tfor {\n\t\tnewline := strings.IndexByte(text, '\\n')\n\t\tif newline == -1 {\n\t\t\tbreak\n\t\t}\n\t\tp.print(text[:newline+1])\n\t\tif !p.options.MinifyWhitespace {\n\t\t\tp.printIndent(indent)\n\t\t}\n\t\ttext = text[newline+1:]\n\t}\n\tp.print(text)\n}\n\nfunc (p *printer) printRuleBlock(rules []css_ast.Rule, indent int32, closeBraceLoc logger.Loc) {\n\tif p.options.MinifyWhitespace {\n\t\tp.print(\"{\")\n\t} else {\n\t\tp.print(\"{\\n\")\n\t}\n\n\tfor i, decl := range rules {\n\t\tomitTrailingSemicolon := p.options.MinifyWhitespace && i+1 == len(rules)\n\t\tp.printRule(decl, indent+1, omitTrailingSemicolon)\n\t}\n\n\tif p.options.AddSourceMappings && closeBraceLoc.Start != 0 {\n\t\tp.builder.AddSourceMapping(closeBraceLoc, \"\", p.css)\n\t}\n\tif !p.options.MinifyWhitespace {\n\t\tp.printIndent(indent)\n\t}\n\tp.print(\"}\")\n}\n\ntype selectorLayout uint8\n\nconst (\n\tlayoutMultiLine selectorLayout = iota\n\tlayoutSingleLine\n)\n\nfunc (p *printer) printComplexSelectors(selectors []css_ast.ComplexSelector, indent int32, layout selectorLayout) {\n\tfor i, complex := range selectors {\n\t\tif i > 0 {\n\t\t\tif p.options.MinifyWhitespace {\n\t\t\t\tp.print(\",\")\n\t\t\t\tif p.options.LineLimit > 0 {\n\t\t\t\t\tp.printNewlinePastLineLimit(indent)\n\t\t\t\t}\n\t\t\t} else if layout == layoutMultiLine {\n\t\t\t\tp.print(\",\\n\")\n\t\t\t\tp.printIndent(indent)\n\t\t\t} else {\n\t\t\t\tp.print(\", \")\n\t\t\t}\n\t\t}\n\n\t\tfor j, compound := range complex.Selectors {\n\t\t\tp.printCompoundSelector(compound, j == 0, indent)\n\t\t}\n\t}\n}\n\nfunc (p *printer) printCompoundSelector(sel css_ast.CompoundSelector, isFirst bool, indent int32) {\n\tif !isFirst && sel.Combinator.Byte == 0 {\n\t\t// A space is required in between compound selectors if there is no\n\t\t// combinator in the middle. It's fine to convert \"a + b\" into \"a+b\"\n\t\t// but not to convert \"a b\" into \"ab\".\n\t\tif p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit(indent) {\n\t\t\tp.print(\" \")\n\t\t}\n\t}\n\n\tif sel.Combinator.Byte != 0 {\n\t\tif !isFirst && !p.options.MinifyWhitespace {\n\t\t\tp.print(\" \")\n\t\t}\n\n\t\tif p.options.AddSourceMappings {\n\t\t\tp.builder.AddSourceMapping(sel.Combinator.Loc, \"\", p.css)\n\t\t}\n\t\tp.css = append(p.css, sel.Combinator.Byte)\n\n\t\tif (p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit(indent)) && !p.options.MinifyWhitespace {\n\t\t\tp.print(\" \")\n\t\t}\n\t}\n\n\tif sel.TypeSelector != nil {\n\t\twhitespace := mayNeedWhitespaceAfter\n\t\tif len(sel.SubclassSelectors) > 0 {\n\t\t\t// There is no chance of whitespace before a subclass selector or pseudo\n\t\t\t// class selector\n\t\t\twhitespace = canDiscardWhitespaceAfter\n\t\t}\n\t\tp.printNamespacedName(*sel.TypeSelector, whitespace)\n\t}\n\n\tfor _, loc := range sel.NestingSelectorLocs {\n\t\tif p.options.AddSourceMappings {\n\t\t\tp.builder.AddSourceMapping(loc, \"\", p.css)\n\t\t}\n\n\t\tp.print(\"&\")\n\t}\n\n\tfor i, ss := range sel.SubclassSelectors {\n\t\twhitespace := mayNeedWhitespaceAfter\n\n\t\t// There is no chance of whitespace between subclass selectors\n\t\tif i+1 < len(sel.SubclassSelectors) {\n\t\t\twhitespace = canDiscardWhitespaceAfter\n\t\t}\n\n\t\tif p.options.AddSourceMappings {\n\t\t\tp.builder.AddSourceMapping(ss.Range.Loc, \"\", p.css)\n\t\t}\n\n\t\tswitch s := ss.Data.(type) {\n\t\tcase *css_ast.SSHash:\n\t\t\tp.print(\"#\")\n\n\t\t\t// This deliberately does not use identHash. From the specification:\n\t\t\t// \"In <id-selector>, the <hash-token>'s value must be an identifier.\"\n\t\t\tp.printSymbol(s.Name.Loc, s.Name.Ref, identNormal, whitespace)\n\n\t\tcase *css_ast.SSClass:\n\t\t\tp.print(\".\")\n\t\t\tp.printSymbol(s.Name.Loc, s.Name.Ref, identNormal, whitespace)\n\n\t\tcase *css_ast.SSAttribute:\n\t\t\tp.print(\"[\")\n\t\t\tp.printNamespacedName(s.NamespacedName, canDiscardWhitespaceAfter)\n\t\t\tif s.MatcherOp != \"\" {\n\t\t\t\tp.print(s.MatcherOp)\n\t\t\t\tprintAsIdent := false\n\n\t\t\t\t// Print the value as an identifier if it's possible\n\t\t\t\tif css_lexer.WouldStartIdentifierWithoutEscapes(s.MatcherValue) {\n\t\t\t\t\tprintAsIdent = true\n\t\t\t\t\tfor _, c := range s.MatcherValue {\n\t\t\t\t\t\tif !css_lexer.IsNameContinue(c) {\n\t\t\t\t\t\t\tprintAsIdent = false\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif printAsIdent {\n\t\t\t\t\tp.printIdent(s.MatcherValue, identNormal, canDiscardWhitespaceAfter)\n\t\t\t\t} else {\n\t\t\t\t\tp.printQuoted(s.MatcherValue, 0)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif s.MatcherModifier != 0 {\n\t\t\t\tp.print(\" \")\n\t\t\t\tp.print(string(rune(s.MatcherModifier)))\n\t\t\t}\n\t\t\tp.print(\"]\")\n\n\t\tcase *css_ast.SSPseudoClass:\n\t\t\tp.printPseudoClassSelector(*s, whitespace)\n\n\t\tcase *css_ast.SSPseudoClassWithSelectorList:\n\t\t\tp.print(\":\")\n\t\t\tp.print(s.Kind.String())\n\t\t\tp.print(\"(\")\n\t\t\tif s.Index.A != \"\" || s.Index.B != \"\" {\n\t\t\t\tp.printNthIndex(s.Index)\n\t\t\t\tif len(s.Selectors) > 0 {\n\t\t\t\t\tif p.options.MinifyWhitespace && s.Selectors[0].Selectors[0].TypeSelector == nil {\n\t\t\t\t\t\tp.print(\" of\")\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.print(\" of \")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.printComplexSelectors(s.Selectors, indent, layoutSingleLine)\n\t\t\tp.print(\")\")\n\n\t\tdefault:\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\t}\n}\n\nfunc (p *printer) printNthIndex(index css_ast.NthIndex) {\n\tif index.A != \"\" {\n\t\tif index.A == \"-1\" {\n\t\t\tp.print(\"-\")\n\t\t} else if index.A != \"1\" {\n\t\t\tp.print(index.A)\n\t\t}\n\t\tp.print(\"n\")\n\t\tif index.B != \"\" {\n\t\t\tif !strings.HasPrefix(index.B, \"-\") {\n\t\t\t\tp.print(\"+\")\n\t\t\t}\n\t\t\tp.print(index.B)\n\t\t}\n\t} else if index.B != \"\" {\n\t\tp.print(index.B)\n\t}\n}\n\nfunc (p *printer) printNamespacedName(nsName css_ast.NamespacedName, whitespace trailingWhitespace) {\n\tif prefix := nsName.NamespacePrefix; prefix != nil {\n\t\tif p.options.AddSourceMappings {\n\t\t\tp.builder.AddSourceMapping(prefix.Range.Loc, \"\", p.css)\n\t\t}\n\n\t\tswitch prefix.Kind {\n\t\tcase css_lexer.TIdent:\n\t\t\tp.printIdent(prefix.Text, identNormal, canDiscardWhitespaceAfter)\n\t\tcase css_lexer.TDelimAsterisk:\n\t\t\tp.print(\"*\")\n\t\tdefault:\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\n\t\tp.print(\"|\")\n\t}\n\n\tif p.options.AddSourceMappings {\n\t\tp.builder.AddSourceMapping(nsName.Name.Range.Loc, \"\", p.css)\n\t}\n\n\tswitch nsName.Name.Kind {\n\tcase css_lexer.TIdent:\n\t\tp.printIdent(nsName.Name.Text, identNormal, whitespace)\n\tcase css_lexer.TDelimAsterisk:\n\t\tp.print(\"*\")\n\tcase css_lexer.TDelimAmpersand:\n\t\tp.print(\"&\")\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\nfunc (p *printer) printPseudoClassSelector(pseudo css_ast.SSPseudoClass, whitespace trailingWhitespace) {\n\tif pseudo.IsElement {\n\t\tp.print(\"::\")\n\t} else {\n\t\tp.print(\":\")\n\t}\n\n\t// This checks for \"nil\" so we can distinguish \":is()\" from \":is\"\n\tif pseudo.Args != nil {\n\t\tp.printIdent(pseudo.Name, identNormal, canDiscardWhitespaceAfter)\n\t\tp.print(\"(\")\n\t\tp.printTokens(pseudo.Args, printTokensOpts{})\n\t\tp.print(\")\")\n\t} else {\n\t\tp.printIdent(pseudo.Name, identNormal, whitespace)\n\t}\n}\n\nfunc (p *printer) print(text string) {\n\tp.css = append(p.css, text...)\n}\n\nfunc bestQuoteCharForString(text string, forURL bool) byte {\n\tforURLCost := 0\n\tsingleCost := 2\n\tdoubleCost := 2\n\n\tfor _, c := range text {\n\t\tswitch c {\n\t\tcase '\\'':\n\t\t\tforURLCost++\n\t\t\tsingleCost++\n\n\t\tcase '\"':\n\t\t\tforURLCost++\n\t\t\tdoubleCost++\n\n\t\tcase '(', ')', ' ', '\\t':\n\t\t\tforURLCost++\n\n\t\tcase '\\\\', '\\n', '\\r', '\\f':\n\t\t\tforURLCost++\n\t\t\tsingleCost++\n\t\t\tdoubleCost++\n\t\t}\n\t}\n\n\t// Quotes can sometimes be omitted for URL tokens\n\tif forURL && forURLCost < singleCost && forURLCost < doubleCost {\n\t\treturn quoteForURL\n\t}\n\n\t// Prefer double quotes to single quotes if there is no cost difference\n\tif singleCost < doubleCost {\n\t\treturn '\\''\n\t}\n\n\treturn '\"'\n}\n\ntype printQuotedFlags uint8\n\nconst (\n\tprintQuotedNoWrap printQuotedFlags = 1 << iota\n)\n\nfunc (p *printer) printQuoted(text string, flags printQuotedFlags) {\n\tp.printQuotedWithQuote(text, bestQuoteCharForString(text, false), flags)\n}\n\ntype escapeKind uint8\n\nconst (\n\tescapeNone escapeKind = iota\n\tescapeBackslash\n\tescapeHex\n)\n\nfunc (p *printer) printWithEscape(c rune, escape escapeKind, remainingText string, mayNeedWhitespaceAfter bool) {\n\tvar temp [utf8.UTFMax]byte\n\n\tif escape == escapeBackslash && ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {\n\t\t// Hexadecimal characters cannot use a plain backslash escape\n\t\tescape = escapeHex\n\t}\n\n\tswitch escape {\n\tcase escapeNone:\n\t\twidth := utf8.EncodeRune(temp[:], c)\n\t\tp.css = append(p.css, temp[:width]...)\n\n\tcase escapeBackslash:\n\t\tp.css = append(p.css, '\\\\')\n\t\twidth := utf8.EncodeRune(temp[:], c)\n\t\tp.css = append(p.css, temp[:width]...)\n\n\tcase escapeHex:\n\t\ttext := fmt.Sprintf(\"\\\\%x\", c)\n\t\tp.css = append(p.css, text...)\n\n\t\t// Make sure the next character is not interpreted as part of the escape sequence\n\t\tif len(text) < 1+6 {\n\t\t\tif next := utf8.RuneLen(c); next < len(remainingText) {\n\t\t\t\tc = rune(remainingText[next])\n\t\t\t\tif c == ' ' || c == '\\t' || (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') {\n\t\t\t\t\tp.css = append(p.css, ' ')\n\t\t\t\t}\n\t\t\t} else if mayNeedWhitespaceAfter {\n\t\t\t\t// If the last character is a hexadecimal escape, print a space afterwards\n\t\t\t\t// for the escape sequence to consume. That way we're sure it won't\n\t\t\t\t// accidentally consume a semantically significant space afterward.\n\t\t\t\tp.css = append(p.css, ' ')\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Note: This function is hot in profiles\nfunc (p *printer) printQuotedWithQuote(text string, quote byte, flags printQuotedFlags) {\n\tif quote != quoteForURL {\n\t\tp.css = append(p.css, quote)\n\t}\n\n\tn := len(text)\n\ti := 0\n\trunStart := 0\n\n\t// Only compute the line length if necessary\n\tvar startLineLength int\n\twrapLongLines := false\n\tif p.options.LineLimit > 0 && quote != quoteForURL && (flags&printQuotedNoWrap) == 0 {\n\t\tstartLineLength = p.currentLineLength()\n\t\tif startLineLength > p.options.LineLimit {\n\t\t\tstartLineLength = p.options.LineLimit\n\t\t}\n\t\twrapLongLines = true\n\t}\n\n\tfor i < n {\n\t\t// Wrap long lines that are over the limit using escaped newlines\n\t\tif wrapLongLines && startLineLength+i >= p.options.LineLimit {\n\t\t\tif runStart < i {\n\t\t\t\tp.css = append(p.css, text[runStart:i]...)\n\t\t\t\trunStart = i\n\t\t\t}\n\t\t\tp.css = append(p.css, \"\\\\\\n\"...)\n\t\t\tstartLineLength -= p.options.LineLimit\n\t\t}\n\n\t\tc, width := utf8.DecodeRuneInString(text[i:])\n\t\tescape := escapeNone\n\n\t\tswitch c {\n\t\tcase '\\x00', '\\r', '\\n', '\\f':\n\t\t\t// Use a hexadecimal escape for characters that would be invalid escapes\n\t\t\tescape = escapeHex\n\n\t\tcase '\\\\', rune(quote):\n\t\t\tescape = escapeBackslash\n\n\t\tcase '(', ')', ' ', '\\t', '\"', '\\'':\n\t\t\t// These characters must be escaped in URL tokens\n\t\t\tif quote == quoteForURL {\n\t\t\t\tescape = escapeBackslash\n\t\t\t}\n\n\t\tcase '/':\n\t\t\t// Avoid generating the sequence \"</style\" in CSS code\n\t\t\tif !p.options.UnsupportedFeatures.Has(compat.InlineStyle) && i >= 1 && text[i-1] == '<' && i+6 <= len(text) && strings.EqualFold(text[i+1:i+6], \"style\") {\n\t\t\t\tescape = escapeBackslash\n\t\t\t}\n\n\t\tdefault:\n\t\t\tif (p.options.ASCIIOnly && c >= 0x80) || c == '\\uFEFF' {\n\t\t\t\tescape = escapeHex\n\t\t\t}\n\t\t}\n\n\t\tif escape != escapeNone {\n\t\t\tif runStart < i {\n\t\t\t\tp.css = append(p.css, text[runStart:i]...)\n\t\t\t}\n\t\t\tp.printWithEscape(c, escape, text[i:], false)\n\t\t\trunStart = i + width\n\t\t}\n\t\ti += width\n\t}\n\n\tif runStart < n {\n\t\tp.css = append(p.css, text[runStart:]...)\n\t}\n\n\tif quote != quoteForURL {\n\t\tp.css = append(p.css, quote)\n\t}\n}\n\nfunc (p *printer) currentLineLength() int {\n\tcss := p.css\n\tn := len(css)\n\tstop := p.oldLineEnd\n\n\t// Update \"oldLineStart\" to the start of the current line\n\tfor i := n; i > stop; i-- {\n\t\tif c := css[i-1]; c == '\\r' || c == '\\n' {\n\t\t\tp.oldLineStart = i\n\t\t\tbreak\n\t\t}\n\t}\n\n\tp.oldLineEnd = n\n\treturn n - p.oldLineStart\n}\n\nfunc (p *printer) printNewlinePastLineLimit(indent int32) bool {\n\tif p.currentLineLength() < p.options.LineLimit {\n\t\treturn false\n\t}\n\tp.print(\"\\n\")\n\tif !p.options.MinifyWhitespace {\n\t\tp.printIndent(indent)\n\t}\n\treturn true\n}\n\ntype identMode uint8\n\nconst (\n\tidentNormal identMode = iota\n\tidentHash\n\tidentDimensionUnit\n\tidentDimensionUnitAfterExponent\n)\n\ntype trailingWhitespace uint8\n\nconst (\n\tmayNeedWhitespaceAfter trailingWhitespace = iota\n\tcanDiscardWhitespaceAfter\n)\n\n// Note: This function is hot in profiles\nfunc (p *printer) printIdent(text string, mode identMode, whitespace trailingWhitespace) {\n\tn := len(text)\n\n\t// Special escape behavior for the first character\n\tinitialEscape := escapeNone\n\tswitch mode {\n\tcase identNormal:\n\t\tif !css_lexer.WouldStartIdentifierWithoutEscapes(text) {\n\t\t\tinitialEscape = escapeBackslash\n\t\t}\n\tcase identDimensionUnit, identDimensionUnitAfterExponent:\n\t\tif !css_lexer.WouldStartIdentifierWithoutEscapes(text) {\n\t\t\tinitialEscape = escapeBackslash\n\t\t} else if n > 0 {\n\t\t\tif c := text[0]; c >= '0' && c <= '9' {\n\t\t\t\t// Unit: \"2x\"\n\t\t\t\tinitialEscape = escapeHex\n\t\t\t} else if (c == 'e' || c == 'E') && mode != identDimensionUnitAfterExponent {\n\t\t\t\tif n >= 2 && text[1] >= '0' && text[1] <= '9' {\n\t\t\t\t\t// Unit: \"e2x\"\n\t\t\t\t\tinitialEscape = escapeHex\n\t\t\t\t} else if n >= 3 && text[1] == '-' && text[2] >= '0' && text[2] <= '9' {\n\t\t\t\t\t// Unit: \"e-2x\"\n\t\t\t\t\tinitialEscape = escapeHex\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Fast path: the identifier does not need to be escaped. This fast path is\n\t// important for performance. For example, doing this sped up end-to-end\n\t// parsing and printing of a large CSS file from 84ms to 66ms (around 25%\n\t// faster).\n\tif initialEscape == escapeNone {\n\t\tfor i := 0; i < n; i++ {\n\t\t\tif c := text[i]; c >= 0x80 || !css_lexer.IsNameContinue(rune(c)) {\n\t\t\t\tgoto slowPath\n\t\t\t}\n\t\t}\n\t\tp.css = append(p.css, text...)\n\t\treturn\n\tslowPath:\n\t}\n\n\t// Slow path: the identifier needs to be escaped\n\tfor i, c := range text {\n\t\tescape := escapeNone\n\n\t\tif p.options.ASCIIOnly && c >= 0x80 {\n\t\t\tescape = escapeHex\n\t\t} else if c == '\\r' || c == '\\n' || c == '\\f' || c == '\\uFEFF' {\n\t\t\t// Use a hexadecimal escape for characters that would be invalid escapes\n\t\t\tescape = escapeHex\n\t\t} else {\n\t\t\t// Escape non-identifier characters\n\t\t\tif !css_lexer.IsNameContinue(c) {\n\t\t\t\tescape = escapeBackslash\n\t\t\t}\n\n\t\t\t// Special escape behavior for the first character\n\t\t\tif i == 0 && initialEscape != escapeNone {\n\t\t\t\tescape = initialEscape\n\t\t\t}\n\t\t}\n\n\t\t// If the last character is a hexadecimal escape, print a space afterwards\n\t\t// for the escape sequence to consume. That way we're sure it won't\n\t\t// accidentally consume a semantically significant space afterward.\n\t\tmayNeedWhitespaceAfter := whitespace == mayNeedWhitespaceAfter && escape != escapeNone && i+utf8.RuneLen(c) == n\n\t\tp.printWithEscape(c, escape, text[i:], mayNeedWhitespaceAfter)\n\t}\n}\n\nfunc (p *printer) printSymbol(loc logger.Loc, ref ast.Ref, mode identMode, whitespace trailingWhitespace) {\n\tref = ast.FollowSymbols(p.symbols, ref)\n\toriginalName := p.symbols.Get(ref).OriginalName\n\tname, ok := p.options.LocalNames[ref]\n\tif !ok {\n\t\tname = originalName\n\t}\n\tif p.options.AddSourceMappings {\n\t\tif originalName == name {\n\t\t\toriginalName = \"\"\n\t\t}\n\t\tp.builder.AddSourceMapping(loc, originalName, p.css)\n\t}\n\tp.printIdent(name, mode, whitespace)\n}\n\nfunc (p *printer) printIndent(indent int32) {\n\tn := int(indent)\n\tif p.options.LineLimit > 0 && n*2 >= p.options.LineLimit {\n\t\tn = p.options.LineLimit / 2\n\t}\n\tfor i := 0; i < n; i++ {\n\t\tp.css = append(p.css, \"  \"...)\n\t}\n}\n\ntype printTokensOpts struct {\n\tindent               int32\n\tmultiLineCommaPeriod uint8\n\tisDeclaration        bool\n}\n\nfunc functionMultiLineCommaPeriod(token css_ast.Token) uint8 {\n\tif token.Kind == css_lexer.TFunction {\n\t\tcommaCount := 0\n\t\tfor _, t := range *token.Children {\n\t\t\tif t.Kind == css_lexer.TComma {\n\t\t\t\tcommaCount++\n\t\t\t}\n\t\t}\n\n\t\tswitch strings.ToLower(token.Text) {\n\t\tcase \"linear-gradient\", \"radial-gradient\", \"conic-gradient\",\n\t\t\t\"repeating-linear-gradient\", \"repeating-radial-gradient\", \"repeating-conic-gradient\":\n\t\t\tif commaCount >= 2 {\n\t\t\t\treturn 1\n\t\t\t}\n\n\t\tcase \"matrix\":\n\t\t\tif commaCount == 5 {\n\t\t\t\treturn 2\n\t\t\t}\n\n\t\tcase \"matrix3d\":\n\t\t\tif commaCount == 15 {\n\t\t\t\treturn 4\n\t\t\t}\n\t\t}\n\t}\n\treturn 0\n}\n\nfunc (p *printer) printTokens(tokens []css_ast.Token, opts printTokensOpts) bool {\n\thasWhitespaceAfter := len(tokens) > 0 && (tokens[0].Whitespace&css_ast.WhitespaceBefore) != 0\n\n\t// Pretty-print long comma-separated declarations of 3 or more items\n\tcommaPeriod := int(opts.multiLineCommaPeriod)\n\tif !p.options.MinifyWhitespace && opts.isDeclaration {\n\t\tcommaCount := 0\n\t\tfor _, t := range tokens {\n\t\t\tif t.Kind == css_lexer.TComma {\n\t\t\t\tcommaCount++\n\t\t\t\tif commaCount >= 2 {\n\t\t\t\t\tcommaPeriod = 1\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif t.Kind == css_lexer.TFunction && functionMultiLineCommaPeriod(t) > 0 {\n\t\t\t\tcommaPeriod = 1\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tcommaCount := 0\n\tfor i, t := range tokens {\n\t\tif t.Kind == css_lexer.TComma {\n\t\t\tcommaCount++\n\t\t}\n\t\tif t.Kind == css_lexer.TWhitespace {\n\t\t\thasWhitespaceAfter = true\n\t\t\tcontinue\n\t\t}\n\t\tif hasWhitespaceAfter {\n\t\t\tif commaPeriod > 0 && (i == 0 || (tokens[i-1].Kind == css_lexer.TComma && commaCount%commaPeriod == 0)) {\n\t\t\t\tp.print(\"\\n\")\n\t\t\t\tp.printIndent(opts.indent + 1)\n\t\t\t} else if p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit(opts.indent+1) {\n\t\t\t\tp.print(\" \")\n\t\t\t}\n\t\t}\n\t\thasWhitespaceAfter = (t.Whitespace&css_ast.WhitespaceAfter) != 0 ||\n\t\t\t(i+1 < len(tokens) && (tokens[i+1].Whitespace&css_ast.WhitespaceBefore) != 0)\n\n\t\twhitespace := mayNeedWhitespaceAfter\n\t\tif !hasWhitespaceAfter {\n\t\t\twhitespace = canDiscardWhitespaceAfter\n\t\t}\n\n\t\tif p.options.AddSourceMappings {\n\t\t\tp.builder.AddSourceMapping(t.Loc, \"\", p.css)\n\t\t}\n\n\t\tswitch t.Kind {\n\t\tcase css_lexer.TIdent:\n\t\t\tp.printIdent(t.Text, identNormal, whitespace)\n\n\t\tcase css_lexer.TSymbol:\n\t\t\tref := ast.Ref{SourceIndex: p.options.InputSourceIndex, InnerIndex: t.PayloadIndex}\n\t\t\tp.printSymbol(t.Loc, ref, identNormal, whitespace)\n\n\t\tcase css_lexer.TFunction:\n\t\t\tp.printIdent(t.Text, identNormal, whitespace)\n\t\t\tp.print(\"(\")\n\n\t\tcase css_lexer.TDimension:\n\t\t\tvalue := t.DimensionValue()\n\t\t\tp.print(value)\n\t\t\tmode := identDimensionUnit\n\t\t\tif strings.ContainsAny(value, \"eE\") {\n\t\t\t\tmode = identDimensionUnitAfterExponent\n\t\t\t}\n\t\t\tp.printIdent(t.DimensionUnit(), mode, whitespace)\n\n\t\tcase css_lexer.TAtKeyword:\n\t\t\tp.print(\"@\")\n\t\t\tp.printIdent(t.Text, identNormal, whitespace)\n\n\t\tcase css_lexer.THash:\n\t\t\tp.print(\"#\")\n\t\t\tp.printIdent(t.Text, identHash, whitespace)\n\n\t\tcase css_lexer.TString:\n\t\t\tp.printQuoted(t.Text, 0)\n\n\t\tcase css_lexer.TURL:\n\t\t\trecord := p.importRecords[t.PayloadIndex]\n\t\t\ttext := record.Path.Text\n\t\t\ttryToAvoidQuote := true\n\t\t\tvar flags printQuotedFlags\n\t\t\tif record.Flags.Has(ast.ContainsUniqueKey) {\n\t\t\t\tflags |= printQuotedNoWrap\n\n\t\t\t\t// If the caller will be substituting a path here later using string\n\t\t\t\t// substitution, then we can't be sure that it will form a valid URL\n\t\t\t\t// token when unquoted (e.g. it may contain spaces). So we need to\n\t\t\t\t// quote the unique key here just in case. For more info see this\n\t\t\t\t// issue: https://github.com/evanw/esbuild/issues/3410\n\t\t\t\ttryToAvoidQuote = false\n\t\t\t} else if p.options.LineLimit > 0 && p.currentLineLength()+len(text) >= p.options.LineLimit {\n\t\t\t\ttryToAvoidQuote = false\n\t\t\t}\n\t\t\tp.print(\"url(\")\n\t\t\tp.printQuotedWithQuote(text, bestQuoteCharForString(text, tryToAvoidQuote), flags)\n\t\t\tp.print(\")\")\n\t\t\tp.recordImportPathForMetafile(t.PayloadIndex)\n\n\t\tcase css_lexer.TUnterminatedString:\n\t\t\t// We must end this with a newline so that this string stays unterminated\n\t\t\tp.print(t.Text)\n\t\t\tp.print(\"\\n\")\n\t\t\tif !p.options.MinifyWhitespace {\n\t\t\t\tp.printIndent(opts.indent)\n\t\t\t}\n\t\t\thasWhitespaceAfter = false\n\n\t\tdefault:\n\t\t\tp.print(t.Text)\n\t\t}\n\n\t\tif t.Children != nil {\n\t\t\tchildCommaPeriod := uint8(0)\n\n\t\t\tif commaPeriod > 0 && opts.isDeclaration {\n\t\t\t\tchildCommaPeriod = functionMultiLineCommaPeriod(t)\n\t\t\t}\n\n\t\t\tif childCommaPeriod > 0 {\n\t\t\t\topts.indent++\n\t\t\t\tif !p.options.MinifyWhitespace {\n\t\t\t\t\tp.print(\"\\n\")\n\t\t\t\t\tp.printIndent(opts.indent + 1)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.printTokens(*t.Children, printTokensOpts{\n\t\t\t\tindent:               opts.indent,\n\t\t\t\tmultiLineCommaPeriod: childCommaPeriod,\n\t\t\t})\n\n\t\t\tif childCommaPeriod > 0 {\n\t\t\t\topts.indent--\n\t\t\t}\n\n\t\t\tswitch t.Kind {\n\t\t\tcase css_lexer.TFunction:\n\t\t\t\tp.print(\")\")\n\n\t\t\tcase css_lexer.TOpenParen:\n\t\t\t\tp.print(\")\")\n\n\t\t\tcase css_lexer.TOpenBrace:\n\t\t\t\tp.print(\"}\")\n\n\t\t\tcase css_lexer.TOpenBracket:\n\t\t\t\tp.print(\"]\")\n\t\t\t}\n\t\t}\n\t}\n\tif hasWhitespaceAfter {\n\t\tp.print(\" \")\n\t}\n\treturn hasWhitespaceAfter\n}\n"
  },
  {
    "path": "internal/css_printer/css_printer_test.go",
    "content": "package css_printer\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/css_parser\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/test\"\n)\n\nfunc expectPrintedCommon(t *testing.T, name string, contents string, expected string, options Options) {\n\tt.Helper()\n\tt.Run(name, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\t\ttree := css_parser.Parse(log, test.SourceForTest(contents), css_parser.OptionsFromConfig(config.LoaderCSS, &config.Options{\n\t\t\tMinifyWhitespace: options.MinifyWhitespace,\n\t\t}))\n\t\tmsgs := log.Done()\n\t\tvar text strings.Builder\n\t\tfor _, msg := range msgs {\n\t\t\tif msg.Kind == logger.Error {\n\t\t\t\ttext.WriteString(msg.String(logger.OutputOptions{}, logger.TerminalInfo{}))\n\t\t\t}\n\t\t}\n\t\ttest.AssertEqualWithDiff(t, text.String(), \"\")\n\t\tsymbols := ast.NewSymbolMap(1)\n\t\tsymbols.SymbolsForSource[0] = tree.Symbols\n\t\tresult := Print(tree, symbols, options)\n\t\ttest.AssertEqualWithDiff(t, string(result.CSS), expected)\n\t})\n}\n\nfunc expectPrinted(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, contents, expected, Options{})\n}\n\nfunc expectPrintedMinify(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [minified]\", contents, expected, Options{\n\t\tMinifyWhitespace: true,\n\t})\n}\n\nfunc expectPrintedASCII(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [ascii]\", contents, expected, Options{\n\t\tASCIIOnly: true,\n\t})\n}\n\nfunc expectPrintedString(t *testing.T, stringValue string, expected string) {\n\tt.Helper()\n\tt.Run(stringValue, func(t *testing.T) {\n\t\tt.Helper()\n\t\tp := printer{}\n\t\tp.printQuoted(stringValue, 0)\n\t\ttest.AssertEqualWithDiff(t, string(p.css), expected)\n\t})\n}\n\nfunc TestStringQuote(t *testing.T) {\n\texpectPrintedString(t, \"\", \"\\\"\\\"\")\n\texpectPrintedString(t, \"foo\", \"\\\"foo\\\"\")\n\texpectPrintedString(t, \"f\\\"o\", \"'f\\\"o'\")\n\texpectPrintedString(t, \"f'\\\"'o\", \"\\\"f'\\\\\\\"'o\\\"\")\n\texpectPrintedString(t, \"f\\\"'\\\"o\", \"'f\\\"\\\\'\\\"o'\")\n\texpectPrintedString(t, \"f\\\\o\", \"\\\"f\\\\\\\\o\\\"\")\n\texpectPrintedString(t, \"f\\ro\", \"\\\"f\\\\do\\\"\")\n\texpectPrintedString(t, \"f\\no\", \"\\\"f\\\\ao\\\"\")\n\texpectPrintedString(t, \"f\\fo\", \"\\\"f\\\\co\\\"\")\n\texpectPrintedString(t, \"f\\r\\no\", \"\\\"f\\\\d\\\\ao\\\"\")\n\texpectPrintedString(t, \"f\\r0\", \"\\\"f\\\\d 0\\\"\")\n\texpectPrintedString(t, \"f\\n0\", \"\\\"f\\\\a 0\\\"\")\n\texpectPrintedString(t, \"f\\n \", \"\\\"f\\\\a  \\\"\")\n\texpectPrintedString(t, \"f\\n\\t\", \"\\\"f\\\\a \\t\\\"\")\n\texpectPrintedString(t, \"f\\nf\", \"\\\"f\\\\a f\\\"\")\n\texpectPrintedString(t, \"f\\nF\", \"\\\"f\\\\a F\\\"\")\n\texpectPrintedString(t, \"f\\ng\", \"\\\"f\\\\ag\\\"\")\n\texpectPrintedString(t, \"f\\nG\", \"\\\"f\\\\aG\\\"\")\n\texpectPrintedString(t, \"f\\x01o\", \"\\\"f\\x01o\\\"\")\n\texpectPrintedString(t, \"f\\to\", \"\\\"f\\to\\\"\")\n\n\texpectPrintedString(t, \"</script>\", \"\\\"</script>\\\"\")\n\texpectPrintedString(t, \"</style>\", \"\\\"<\\\\/style>\\\"\")\n\texpectPrintedString(t, \"</style\", \"\\\"<\\\\/style\\\"\")\n\texpectPrintedString(t, \"</STYLE\", \"\\\"<\\\\/STYLE\\\"\")\n\texpectPrintedString(t, \"</StYlE\", \"\\\"<\\\\/StYlE\\\"\")\n\texpectPrintedString(t, \">/style\", \"\\\">/style\\\"\")\n\texpectPrintedString(t, \">/STYLE\", \"\\\">/STYLE\\\"\")\n\texpectPrintedString(t, \">/StYlE\", \"\\\">/StYlE\\\"\")\n}\n\nfunc TestURLQuote(t *testing.T) {\n\texpectPrinted(t, \"* { background: url('foo') }\", \"* {\\n  background: url(foo);\\n}\\n\")\n\texpectPrinted(t, \"* { background: url('f o') }\", \"* {\\n  background: url(f\\\\ o);\\n}\\n\")\n\texpectPrinted(t, \"* { background: url('f  o') }\", \"* {\\n  background: url(\\\"f  o\\\");\\n}\\n\")\n\texpectPrinted(t, \"* { background: url('foo)') }\", \"* {\\n  background: url(foo\\\\));\\n}\\n\")\n\texpectPrinted(t, \"* { background: url('(foo') }\", \"* {\\n  background: url(\\\\(foo);\\n}\\n\")\n\texpectPrinted(t, \"* { background: url('(foo)') }\", \"* {\\n  background: url(\\\"(foo)\\\");\\n}\\n\")\n\texpectPrinted(t, \"* { background: url('\\\"foo\\\"') }\", \"* {\\n  background: url('\\\"foo\\\"');\\n}\\n\")\n}\n\nfunc TestImportant(t *testing.T) {\n\texpectPrinted(t, \"a { b: c!important }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c!important; }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c! important }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c! important; }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c ! important }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c ! important; }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c !IMPORTANT; }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c !ImPoRtAnT; }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrintedMinify(t, \"a { b: c !important }\", \"a{b:c!important}\")\n}\n\nfunc TestSelector(t *testing.T) {\n\texpectPrintedMinify(t, \"a + b c > d ~ e{}\", \"a+b c>d~e{}\")\n\n\texpectPrinted(t, \":unknown( x (a+b), 'c' ) {}\", \":unknown(x (a+b), \\\"c\\\") {\\n}\\n\")\n\texpectPrinted(t, \":unknown( x (a-b), 'c' ) {}\", \":unknown(x (a-b), \\\"c\\\") {\\n}\\n\")\n\texpectPrinted(t, \":unknown( x (a,b), 'c' ) {}\", \":unknown(x (a, b), \\\"c\\\") {\\n}\\n\")\n\texpectPrinted(t, \":unknown( x ( a + b ), 'c' ) {}\", \":unknown(x (a + b), \\\"c\\\") {\\n}\\n\")\n\texpectPrinted(t, \":unknown( x ( a - b ), 'c' ) {}\", \":unknown(x (a - b), \\\"c\\\") {\\n}\\n\")\n\texpectPrinted(t, \":unknown( x ( a , b ), 'c' ) {}\", \":unknown(x (a, b), \\\"c\\\") {\\n}\\n\")\n\n\texpectPrintedMinify(t, \":unknown( x (a+b), 'c' ) {}\", \":unknown(x (a+b),\\\"c\\\"){}\")\n\texpectPrintedMinify(t, \":unknown( x (a-b), 'c' ) {}\", \":unknown(x (a-b),\\\"c\\\"){}\")\n\texpectPrintedMinify(t, \":unknown( x (a,b), 'c' ) {}\", \":unknown(x (a,b),\\\"c\\\"){}\")\n\texpectPrintedMinify(t, \":unknown( x ( a + b ), 'c' ) {}\", \":unknown(x (a + b),\\\"c\\\"){}\")\n\texpectPrintedMinify(t, \":unknown( x ( a - b ), 'c' ) {}\", \":unknown(x (a - b),\\\"c\\\"){}\")\n\texpectPrintedMinify(t, \":unknown( x ( a , b ), 'c' ) {}\", \":unknown(x (a,b),\\\"c\\\"){}\")\n\n\t// \":foo()\" is a parse error, but should ideally still be preserved so they don't accidentally become valid\n\texpectPrinted(t, \":is {}\", \":is {\\n}\\n\")\n\texpectPrinted(t, \":is() {}\", \":is() {\\n}\\n\")\n\texpectPrinted(t, \":hover {}\", \":hover {\\n}\\n\")\n\texpectPrinted(t, \":hover() {}\", \":hover() {\\n}\\n\")\n\texpectPrintedMinify(t, \":is {}\", \":is{}\")\n\texpectPrintedMinify(t, \":is() {}\", \":is(){}\")\n\texpectPrintedMinify(t, \":hover {}\", \":hover{}\")\n\texpectPrintedMinify(t, \":hover() {}\", \":hover(){}\")\n}\n\nfunc TestNestedSelector(t *testing.T) {\n\texpectPrintedMinify(t, \"a { &b {} }\", \"a{&b{}}\")\n\texpectPrintedMinify(t, \"a { & b {} }\", \"a{& b{}}\")\n\texpectPrintedMinify(t, \"a { & :b {} }\", \"a{& :b{}}\")\n\texpectPrintedMinify(t, \"& a & b & c {}\", \"& a & b & c{}\")\n}\n\nfunc TestBadQualifiedRules(t *testing.T) {\n\texpectPrinted(t, \";\", \"; {\\n}\\n\")\n\texpectPrinted(t, \"$bad: rule;\", \"$bad: rule; {\\n}\\n\")\n\texpectPrinted(t, \"a {}; b {};\", \"a {\\n}\\n; b {\\n}\\n; {\\n}\\n\")\n\texpectPrinted(t, \"a { div.major { color: blue } color: red }\", \"a {\\n  div.major {\\n    color: blue;\\n  }\\n  color: red;\\n}\\n\")\n\texpectPrinted(t, \"a { div:hover { color: blue } color: red }\", \"a {\\n  div:hover {\\n    color: blue;\\n  }\\n  color: red;\\n}\\n\")\n\texpectPrinted(t, \"a { div:hover { color: blue }; color: red }\", \"a {\\n  div:hover {\\n    color: blue;\\n  }\\n  color: red;\\n}\\n\")\n\n\texpectPrinted(t, \"$bad{ color: red }\", \"$bad {\\n  color: red;\\n}\\n\")\n\texpectPrinted(t, \"$bad { color: red }\", \"$bad {\\n  color: red;\\n}\\n\")\n\texpectPrinted(t, \"$bad foo{ color: red }\", \"$bad foo {\\n  color: red;\\n}\\n\")\n\texpectPrinted(t, \"$bad foo { color: red }\", \"$bad foo {\\n  color: red;\\n}\\n\")\n\n\texpectPrintedMinify(t, \"$bad{ color: red }\", \"$bad{color:red}\")\n\texpectPrintedMinify(t, \"$bad { color: red }\", \"$bad{color:red}\")\n\texpectPrintedMinify(t, \"$bad foo{ color: red }\", \"$bad foo{color:red}\")\n\texpectPrintedMinify(t, \"$bad foo { color: red }\", \"$bad foo{color:red}\")\n}\n\nfunc TestDeclaration(t *testing.T) {\n\texpectPrinted(t, \"* { unknown: x (a+b) }\", \"* {\\n  unknown: x (a+b);\\n}\\n\")\n\texpectPrinted(t, \"* { unknown: x (a-b) }\", \"* {\\n  unknown: x (a-b);\\n}\\n\")\n\texpectPrinted(t, \"* { unknown: x (a,b) }\", \"* {\\n  unknown: x (a, b);\\n}\\n\")\n\texpectPrinted(t, \"* { unknown: x ( a + b ) }\", \"* {\\n  unknown: x (a + b);\\n}\\n\")\n\texpectPrinted(t, \"* { unknown: x ( a - b ) }\", \"* {\\n  unknown: x (a - b);\\n}\\n\")\n\texpectPrinted(t, \"* { unknown: x ( a , b ) }\", \"* {\\n  unknown: x (a, b);\\n}\\n\")\n\n\texpectPrintedMinify(t, \"* { unknown: x (a+b) }\", \"*{unknown:x (a+b)}\")\n\texpectPrintedMinify(t, \"* { unknown: x (a-b) }\", \"*{unknown:x (a-b)}\")\n\texpectPrintedMinify(t, \"* { unknown: x (a,b) }\", \"*{unknown:x (a,b)}\")\n\texpectPrintedMinify(t, \"* { unknown: x ( a + b ) }\", \"*{unknown:x (a + b)}\")\n\texpectPrintedMinify(t, \"* { unknown: x ( a - b ) }\", \"*{unknown:x (a - b)}\")\n\texpectPrintedMinify(t, \"* { unknown: x ( a , b ) }\", \"*{unknown:x (a,b)}\")\n\n\t// Pretty-print long lists in declarations\n\texpectPrinted(t, \"a { b: c, d }\", \"a {\\n  b: c, d;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c, (d, e) }\", \"a {\\n  b: c, (d, e);\\n}\\n\")\n\texpectPrinted(t, \"a { b: c, d, e }\", \"a {\\n  b:\\n    c,\\n    d,\\n    e;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c, (d, e), f }\", \"a {\\n  b:\\n    c,\\n    (d, e),\\n    f;\\n}\\n\")\n\n\texpectPrintedMinify(t, \"a { b: c, d }\", \"a{b:c,d}\")\n\texpectPrintedMinify(t, \"a { b: c, (d, e) }\", \"a{b:c,(d,e)}\")\n\texpectPrintedMinify(t, \"a { b: c, d, e }\", \"a{b:c,d,e}\")\n\texpectPrintedMinify(t, \"a { b: c, (d, e), f }\", \"a{b:c,(d,e),f}\")\n}\n\nfunc TestVerbatimWhitespace(t *testing.T) {\n\texpectPrinted(t, \"*{--x:}\", \"* {\\n  --x:;\\n}\\n\")\n\texpectPrinted(t, \"*{--x: }\", \"* {\\n  --x: ;\\n}\\n\")\n\texpectPrinted(t, \"* { --x:; }\", \"* {\\n  --x:;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: ; }\", \"* {\\n  --x: ;\\n}\\n\")\n\n\texpectPrintedMinify(t, \"*{--x:}\", \"*{--x:}\")\n\texpectPrintedMinify(t, \"*{--x: }\", \"*{--x: }\")\n\texpectPrintedMinify(t, \"* { --x:; }\", \"*{--x:}\")\n\texpectPrintedMinify(t, \"* { --x: ; }\", \"*{--x: }\")\n\n\texpectPrinted(t, \"*{--x:!important}\", \"* {\\n  --x:!important;\\n}\\n\")\n\texpectPrinted(t, \"*{--x: !important}\", \"* {\\n  --x: !important;\\n}\\n\")\n\texpectPrinted(t, \"*{ --x:!important }\", \"* {\\n  --x:!important;\\n}\\n\")\n\texpectPrinted(t, \"*{ --x: !important }\", \"* {\\n  --x: !important;\\n}\\n\")\n\texpectPrinted(t, \"* { --x:!important; }\", \"* {\\n  --x:!important;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: !important; }\", \"* {\\n  --x: !important;\\n}\\n\")\n\texpectPrinted(t, \"* { --x:! important ; }\", \"* {\\n  --x:!important;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: ! important ; }\", \"* {\\n  --x: !important;\\n}\\n\")\n\n\texpectPrintedMinify(t, \"*{--x:!important}\", \"*{--x:!important}\")\n\texpectPrintedMinify(t, \"*{--x: !important}\", \"*{--x: !important}\")\n\texpectPrintedMinify(t, \"*{ --x:!important }\", \"*{--x:!important}\")\n\texpectPrintedMinify(t, \"*{ --x: !important }\", \"*{--x: !important}\")\n\texpectPrintedMinify(t, \"* { --x:!important; }\", \"*{--x:!important}\")\n\texpectPrintedMinify(t, \"* { --x: !important; }\", \"*{--x: !important}\")\n\texpectPrintedMinify(t, \"* { --x:! important ; }\", \"*{--x:!important}\")\n\texpectPrintedMinify(t, \"* { --x: ! important ; }\", \"*{--x: !important}\")\n\n\texpectPrinted(t, \"* { --x:y; }\", \"* {\\n  --x:y;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: y; }\", \"* {\\n  --x: y;\\n}\\n\")\n\texpectPrinted(t, \"* { --x:y ; }\", \"* {\\n  --x:y ;\\n}\\n\")\n\texpectPrinted(t, \"* { --x:y, ; }\", \"* {\\n  --x:y, ;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: var(y,); }\", \"* {\\n  --x: var(y,);\\n}\\n\")\n\texpectPrinted(t, \"* { --x: var(y, ); }\", \"* {\\n  --x: var(y, );\\n}\\n\")\n\n\texpectPrintedMinify(t, \"* { --x:y; }\", \"*{--x:y}\")\n\texpectPrintedMinify(t, \"* { --x: y; }\", \"*{--x: y}\")\n\texpectPrintedMinify(t, \"* { --x:y ; }\", \"*{--x:y }\")\n\texpectPrintedMinify(t, \"* { --x:y, ; }\", \"*{--x:y, }\")\n\texpectPrintedMinify(t, \"* { --x: var(y,); }\", \"*{--x: var(y,)}\")\n\texpectPrintedMinify(t, \"* { --x: var(y, ); }\", \"*{--x: var(y, )}\")\n\n\texpectPrinted(t, \"* { --x:(y); }\", \"* {\\n  --x:(y);\\n}\\n\")\n\texpectPrinted(t, \"* { --x:(y) ; }\", \"* {\\n  --x:(y) ;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: (y); }\", \"* {\\n  --x: (y);\\n}\\n\")\n\texpectPrinted(t, \"* { --x:(y ); }\", \"* {\\n  --x:(y );\\n}\\n\")\n\texpectPrinted(t, \"* { --x:( y); }\", \"* {\\n  --x:( y);\\n}\\n\")\n\n\texpectPrintedMinify(t, \"* { --x:(y); }\", \"*{--x:(y)}\")\n\texpectPrintedMinify(t, \"* { --x:(y) ; }\", \"*{--x:(y) }\")\n\texpectPrintedMinify(t, \"* { --x: (y); }\", \"*{--x: (y)}\")\n\texpectPrintedMinify(t, \"* { --x:(y ); }\", \"*{--x:(y )}\")\n\texpectPrintedMinify(t, \"* { --x:( y); }\", \"*{--x:( y)}\")\n\n\texpectPrinted(t, \"* { --x:f(y); }\", \"* {\\n  --x:f(y);\\n}\\n\")\n\texpectPrinted(t, \"* { --x:f(y) ; }\", \"* {\\n  --x:f(y) ;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: f(y); }\", \"* {\\n  --x: f(y);\\n}\\n\")\n\texpectPrinted(t, \"* { --x:f(y ); }\", \"* {\\n  --x:f(y );\\n}\\n\")\n\texpectPrinted(t, \"* { --x:f( y); }\", \"* {\\n  --x:f( y);\\n}\\n\")\n\n\texpectPrintedMinify(t, \"* { --x:f(y); }\", \"*{--x:f(y)}\")\n\texpectPrintedMinify(t, \"* { --x:f(y) ; }\", \"*{--x:f(y) }\")\n\texpectPrintedMinify(t, \"* { --x: f(y); }\", \"*{--x: f(y)}\")\n\texpectPrintedMinify(t, \"* { --x:f(y ); }\", \"*{--x:f(y )}\")\n\texpectPrintedMinify(t, \"* { --x:f( y); }\", \"*{--x:f( y)}\")\n\n\texpectPrinted(t, \"* { --x:[y]; }\", \"* {\\n  --x:[y];\\n}\\n\")\n\texpectPrinted(t, \"* { --x:[y] ; }\", \"* {\\n  --x:[y] ;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: [y]; }\", \"* {\\n  --x: [y];\\n}\\n\")\n\texpectPrinted(t, \"* { --x:[y ]; }\", \"* {\\n  --x:[y ];\\n}\\n\")\n\texpectPrinted(t, \"* { --x:[ y]; }\", \"* {\\n  --x:[ y];\\n}\\n\")\n\n\texpectPrintedMinify(t, \"* { --x:[y]; }\", \"*{--x:[y]}\")\n\texpectPrintedMinify(t, \"* { --x:[y] ; }\", \"*{--x:[y] }\")\n\texpectPrintedMinify(t, \"* { --x: [y]; }\", \"*{--x: [y]}\")\n\texpectPrintedMinify(t, \"* { --x:[y ]; }\", \"*{--x:[y ]}\")\n\texpectPrintedMinify(t, \"* { --x:[ y]; }\", \"*{--x:[ y]}\")\n\n\t// Note: These cases now behave like qualified rules\n\texpectPrinted(t, \"* { --x:{y}; }\", \"* {\\n  --x: {\\n    y;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"* { --x:{y} ; }\", \"* {\\n  --x: {\\n    y;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"* { --x: {y}; }\", \"* {\\n  --x: {\\n    y;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"* { --x:{y }; }\", \"* {\\n  --x: {\\n    y;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"* { --x:{ y}; }\", \"* {\\n  --x: {\\n    y;\\n  }\\n}\\n\")\n\n\t// Note: These cases now behave like qualified rules\n\texpectPrintedMinify(t, \"* { --x:{y}; }\", \"*{--x:{y}}\")\n\texpectPrintedMinify(t, \"* { --x:{y} ; }\", \"*{--x:{y}}\")\n\texpectPrintedMinify(t, \"* { --x: {y}; }\", \"*{--x:{y}}\")\n\texpectPrintedMinify(t, \"* { --x:{y }; }\", \"*{--x:{y}}\")\n\texpectPrintedMinify(t, \"* { --x:{ y}; }\", \"*{--x:{y}}\")\n\n\texpectPrintedMinify(t, \"@supports ( --x : y , z ) { a { color: red; } }\", \"@supports ( --x : y , z ){a{color:red}}\")\n\texpectPrintedMinify(t, \"@supports ( --x : ) { a { color: red; } }\", \"@supports ( --x : ){a{color:red}}\")\n\texpectPrintedMinify(t, \"@supports (--x: ) { a { color: red; } }\", \"@supports (--x: ){a{color:red}}\")\n\texpectPrintedMinify(t, \"@supports ( --x y , z ) { a { color: red; } }\", \"@supports (--x y,z){a{color:red}}\")\n\texpectPrintedMinify(t, \"@supports ( --x ) { a { color: red; } }\", \"@supports (--x){a{color:red}}\")\n\texpectPrintedMinify(t, \"@supports ( ) { a { color: red; } }\", \"@supports (){a{color:red}}\")\n\texpectPrintedMinify(t, \"@supports ( . --x : y , z ) { a { color: red; } }\", \"@supports (. --x : y,z){a{color:red}}\")\n}\n\nfunc TestAtRule(t *testing.T) {\n\texpectPrintedMinify(t, \"@unknown;\", \"@unknown;\")\n\texpectPrintedMinify(t, \"@unknown x;\", \"@unknown x;\")\n\texpectPrintedMinify(t, \"@unknown{}\", \"@unknown{}\")\n\texpectPrintedMinify(t, \"@unknown{\\na: b;\\nc: d;\\n}\", \"@unknown{a: b; c: d;}\")\n\n\texpectPrinted(t, \"@unknown x{}\", \"@unknown x {}\\n\")\n\texpectPrinted(t, \"@unknown x {}\", \"@unknown x {}\\n\")\n\texpectPrintedMinify(t, \"@unknown x{}\", \"@unknown x{}\")\n\texpectPrintedMinify(t, \"@unknown x {}\", \"@unknown x{}\")\n\n\texpectPrinted(t, \"@unknown x ( a + b ) ;\", \"@unknown x (a + b);\\n\")\n\texpectPrinted(t, \"@unknown x ( a - b ) ;\", \"@unknown x (a - b);\\n\")\n\texpectPrinted(t, \"@unknown x ( a , b ) ;\", \"@unknown x (a, b);\\n\")\n\texpectPrintedMinify(t, \"@unknown x ( a + b ) ;\", \"@unknown x (a + b);\")\n\texpectPrintedMinify(t, \"@unknown x ( a - b ) ;\", \"@unknown x (a - b);\")\n\texpectPrintedMinify(t, \"@unknown x ( a , b ) ;\", \"@unknown x (a,b);\")\n}\n\nfunc TestAtCharset(t *testing.T) {\n\texpectPrinted(t, \"@charset \\\"UTF-8\\\";\", \"@charset \\\"UTF-8\\\";\\n\")\n\texpectPrintedMinify(t, \"@charset \\\"UTF-8\\\";\", \"@charset \\\"UTF-8\\\";\")\n}\n\nfunc TestAtImport(t *testing.T) {\n\texpectPrinted(t, \"@import\\\"foo.css\\\";\", \"@import \\\"foo.css\\\";\\n\")\n\texpectPrinted(t, \"@import \\\"foo.css\\\";\", \"@import \\\"foo.css\\\";\\n\")\n\texpectPrinted(t, \"@import url(foo.css);\", \"@import \\\"foo.css\\\";\\n\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\");\", \"@import \\\"foo.css\\\";\\n\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\") (a < 1);\", \"@import \\\"foo.css\\\" (a < 1);\\n\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\") supports(foo) (a < 1);\", \"@import \\\"foo.css\\\" supports(foo) (a < 1);\\n\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\") layer;\", \"@import \\\"foo.css\\\" layer;\\n\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\") layer (a < 1);\", \"@import \\\"foo.css\\\" layer (a < 1);\\n\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\") layer supports(foo);\", \"@import \\\"foo.css\\\" layer supports(foo);\\n\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\") layer supports(foo) (a < 1);\", \"@import \\\"foo.css\\\" layer supports(foo) (a < 1);\\n\")\n\n\texpectPrintedMinify(t, \"@import\\\"foo.css\\\";\", \"@import\\\"foo.css\\\";\")\n\texpectPrintedMinify(t, \"@import \\\"foo.css\\\";\", \"@import\\\"foo.css\\\";\")\n\texpectPrintedMinify(t, \"@import url(foo.css);\", \"@import\\\"foo.css\\\";\")\n\texpectPrintedMinify(t, \"@import url(\\\"foo.css\\\");\", \"@import\\\"foo.css\\\";\")\n\texpectPrintedMinify(t, \"@import url(\\\"foo.css\\\") (a < 1);\", \"@import\\\"foo.css\\\"(a<1);\")\n\texpectPrintedMinify(t, \"@import url(\\\"foo.css\\\") supports(foo) (a < 1);\", \"@import\\\"foo.css\\\"supports(foo) (a<1);\")\n\texpectPrintedMinify(t, \"@import url(\\\"foo.css\\\") layer;\", \"@import\\\"foo.css\\\"layer;\")\n\texpectPrintedMinify(t, \"@import url(\\\"foo.css\\\") layer (a < 1);\", \"@import\\\"foo.css\\\"layer (a<1);\")\n\texpectPrintedMinify(t, \"@import url(\\\"foo.css\\\") layer supports(foo);\", \"@import\\\"foo.css\\\"layer supports(foo);\")\n\texpectPrintedMinify(t, \"@import url(\\\"foo.css\\\") layer supports(foo) (a < 1);\", \"@import\\\"foo.css\\\"layer supports(foo) (a<1);\")\n}\n\nfunc TestAtKeyframes(t *testing.T) {\n\texpectPrintedMinify(t, \"@keyframes name { 0%, 50% { color: red } 25%, 75% { color: blue } }\",\n\t\t\"@keyframes name{0%,50%{color:red}25%,75%{color:blue}}\")\n\texpectPrintedMinify(t, \"@keyframes name { from { color: red } to { color: blue } }\",\n\t\t\"@keyframes name{from{color:red}to{color:blue}}\")\n}\n\nfunc TestAtMedia(t *testing.T) {\n\texpectPrinted(t, \"@media screen { div { color: red } }\", \"@media screen {\\n  div {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@media screen{div{color:red}}\", \"@media screen {\\n  div {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMinify(t, \"@media screen { div { color: red } }\", \"@media screen{div{color:red}}\")\n\texpectPrintedMinify(t, \"@media screen{div{color:red}}\", \"@media screen{div{color:red}}\")\n\n\texpectPrintedMinify(t, \"@media (a) {div{color:red}}\", \"@media(a){div{color:red}}\")\n\texpectPrintedMinify(t, \"@media (a) or (b) {div{color:red}}\", \"@media(a)or (b){div{color:red}}\")\n\texpectPrintedMinify(t, \"@media (a) and (b) {div{color:red}}\", \"@media(a)and (b){div{color:red}}\")\n\texpectPrintedMinify(t, \"@media not a {div{color:red}}\", \"@media not a{div{color:red}}\")\n\texpectPrintedMinify(t, \"@media not a and (b) and (c) {div{color:red}}\", \"@media not a and (b)and (c){div{color:red}}\")\n\texpectPrintedMinify(t, \"@media not (a) {div{color:red}}\", \"@media not (a){div{color:red}}\")\n\texpectPrintedMinify(t, \"@media not ( (a) or (b) ) {div{color:red}}\", \"@media not ((a)or (b)){div{color:red}}\")\n\texpectPrintedMinify(t, \"@media not ( (a) and (b) ) {div{color:red}}\", \"@media not ((a)and (b)){div{color:red}}\")\n\n\texpectPrintedMinify(t, \"@media (width < 2px) {div{color:red}}\", \"@media(width<2px){div{color:red}}\")\n\texpectPrintedMinify(t, \"@media (1px < width) {div{color:red}}\", \"@media(1px<width){div{color:red}}\")\n\texpectPrintedMinify(t, \"@media (1px < width < 2px) {div{color:red}}\", \"@media(1px<width<2px){div{color:red}}\")\n\texpectPrintedMinify(t, \"@media junk(1, 2, 3) {div{color:red}}\", \"@media junk(1,2,3){div{color:red}}\")\n}\n\nfunc TestAtScope(t *testing.T) {\n\texpectPrinted(t, \"@scope { div { color: red } }\", \"@scope {\\n  div {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@scope (a, .b) to (c > *) { div { color: red } }\", \"@scope (a, .b) to (c > *) {\\n  div {\\n    color: red;\\n  }\\n}\\n\")\n\n\texpectPrintedMinify(t, \"@scope { div { color: red } }\", \"@scope{div{color:red}}\")\n\texpectPrintedMinify(t, \"@scope (a, .b) to (c > *) { div { color: red } }\", \"@scope(a,.b)to (c>*){div{color:red}}\")\n}\n\nfunc TestAtFontFace(t *testing.T) {\n\texpectPrinted(t, \"@font-face { font-family: 'Open Sans'; src: url('OpenSans.woff') format('woff') }\",\n\t\t\"@font-face {\\n  font-family: \\\"Open Sans\\\";\\n  src: url(OpenSans.woff) format(\\\"woff\\\");\\n}\\n\")\n\texpectPrintedMinify(t, \"@font-face { font-family: 'Open Sans'; src: url('OpenSans.woff') format('woff') }\",\n\t\t\"@font-face{font-family:\\\"Open Sans\\\";src:url(OpenSans.woff) format(\\\"woff\\\")}\")\n}\n\nfunc TestAtPage(t *testing.T) {\n\texpectPrinted(t, \"@page { margin: 1cm }\", \"@page {\\n  margin: 1cm;\\n}\\n\")\n\texpectPrinted(t, \"@page :first { margin: 1cm }\", \"@page :first {\\n  margin: 1cm;\\n}\\n\")\n\texpectPrintedMinify(t, \"@page { margin: 1cm }\", \"@page{margin:1cm}\")\n\texpectPrintedMinify(t, \"@page :first { margin: 1cm }\", \"@page :first{margin:1cm}\")\n}\n\nfunc TestMsGridColumnsWhitespace(t *testing.T) {\n\t// Must not insert a space between the \"]\" and the \"(\"\n\texpectPrinted(t, \"div { -ms-grid-columns: (1fr)[3] }\", \"div {\\n  -ms-grid-columns: (1fr)[3];\\n}\\n\")\n\texpectPrinted(t, \"div { -ms-grid-columns: 1fr (20px 1fr)[3] }\", \"div {\\n  -ms-grid-columns: 1fr (20px 1fr)[3];\\n}\\n\")\n\texpectPrintedMinify(t, \"div { -ms-grid-columns: (1fr)[3] }\", \"div{-ms-grid-columns:(1fr)[3]}\")\n\texpectPrintedMinify(t, \"div { -ms-grid-columns: 1fr (20px 1fr)[3] }\", \"div{-ms-grid-columns:1fr (20px 1fr)[3]}\")\n}\n\nfunc TestASCII(t *testing.T) {\n\texpectPrintedASCII(t, \"* { background: url(🐈) }\", \"* {\\n  background: url(\\\\1f408);\\n}\\n\")\n\texpectPrintedASCII(t, \"* { background: url(🐈6) }\", \"* {\\n  background: url(\\\\1f408 6);\\n}\\n\")\n\texpectPrintedASCII(t, \"* { background: url('🐈') }\", \"* {\\n  background: url(\\\\1f408);\\n}\\n\")\n\texpectPrintedASCII(t, \"* { background: url('🐈6') }\", \"* {\\n  background: url(\\\\1f408 6);\\n}\\n\")\n\texpectPrintedASCII(t, \"* { background: url('(🐈)') }\", \"* {\\n  background: url(\\\"(\\\\1f408)\\\");\\n}\\n\")\n\texpectPrintedASCII(t, \"* { background: url('(🐈6)') }\", \"* {\\n  background: url(\\\"(\\\\1f408 6)\\\");\\n}\\n\")\n\n\texpectPrintedASCII(t, \"div { 🐈: 🐈('🐈') }\", \"div {\\n  \\\\1f408: \\\\1f408(\\\"\\\\1f408\\\");\\n}\\n\")\n\texpectPrintedASCII(t, \"div { 🐈 : 🐈 ('🐈 ') }\", \"div {\\n  \\\\1f408: \\\\1f408  (\\\"\\\\1f408  \\\");\\n}\\n\")\n\texpectPrintedASCII(t, \"div { 🐈6: 🐈6('🐈6') }\", \"div {\\n  \\\\1f408 6: \\\\1f408 6(\\\"\\\\1f408 6\\\");\\n}\\n\")\n\n\texpectPrintedASCII(t, \"@🐈;\", \"@\\\\1f408;\\n\")\n\texpectPrintedASCII(t, \"@🐈 {}\", \"@\\\\1f408 {}\\n\")\n\texpectPrintedASCII(t, \"@🐈 x {}\", \"@\\\\1f408  x {}\\n\")\n\n\texpectPrintedASCII(t, \"#🐈#x {}\", \"#\\\\1f408#x {\\n}\\n\")\n\texpectPrintedASCII(t, \"#🐈 #x {}\", \"#\\\\1f408  #x {\\n}\\n\")\n\texpectPrintedASCII(t, \"#🐈::x {}\", \"#\\\\1f408::x {\\n}\\n\")\n\texpectPrintedASCII(t, \"#🐈 ::x {}\", \"#\\\\1f408  ::x {\\n}\\n\")\n\n\texpectPrintedASCII(t, \".🐈.x {}\", \".\\\\1f408.x {\\n}\\n\")\n\texpectPrintedASCII(t, \".🐈 .x {}\", \".\\\\1f408  .x {\\n}\\n\")\n\texpectPrintedASCII(t, \".🐈::x {}\", \".\\\\1f408::x {\\n}\\n\")\n\texpectPrintedASCII(t, \".🐈 ::x {}\", \".\\\\1f408  ::x {\\n}\\n\")\n\n\texpectPrintedASCII(t, \"🐈|🐈.x {}\", \"\\\\1f408|\\\\1f408.x {\\n}\\n\")\n\texpectPrintedASCII(t, \"🐈|🐈 .x {}\", \"\\\\1f408|\\\\1f408  .x {\\n}\\n\")\n\texpectPrintedASCII(t, \"🐈|🐈::x {}\", \"\\\\1f408|\\\\1f408::x {\\n}\\n\")\n\texpectPrintedASCII(t, \"🐈|🐈 ::x {}\", \"\\\\1f408|\\\\1f408  ::x {\\n}\\n\")\n\n\texpectPrintedASCII(t, \"::🐈:x {}\", \"::\\\\1f408:x {\\n}\\n\")\n\texpectPrintedASCII(t, \"::🐈 :x {}\", \"::\\\\1f408  :x {\\n}\\n\")\n\n\texpectPrintedASCII(t, \"[🐈] {}\", \"[\\\\1f408] {\\n}\\n\")\n\texpectPrintedASCII(t, \"[🐈=🐈] {}\", \"[\\\\1f408=\\\\1f408] {\\n}\\n\")\n\texpectPrintedASCII(t, \"[🐈|🐈=🐈] {}\", \"[\\\\1f408|\\\\1f408=\\\\1f408] {\\n}\\n\")\n\n\t// A space must be consumed after an escaped code point even with six digits\n\texpectPrintedASCII(t, \".\\\\10FFF abc:after { content: '\\\\10FFF abc' }\", \".\\\\10fff abc:after {\\n  content: \\\"\\\\10fff abc\\\";\\n}\\n\")\n\texpectPrintedASCII(t, \".\\U00010FFFabc:after { content: '\\U00010FFFabc' }\", \".\\\\10fff abc:after {\\n  content: \\\"\\\\10fff abc\\\";\\n}\\n\")\n\texpectPrintedASCII(t, \".\\\\10FFFFabc:after { content: '\\\\10FFFFabc' }\", \".\\\\10ffffabc:after {\\n  content: \\\"\\\\10ffffabc\\\";\\n}\\n\")\n\texpectPrintedASCII(t, \".\\\\10FFFF abc:after { content: '\\\\10FFFF abc' }\", \".\\\\10ffffabc:after {\\n  content: \\\"\\\\10ffffabc\\\";\\n}\\n\")\n\texpectPrintedASCII(t, \".\\U0010FFFFabc:after { content: '\\U0010FFFFabc' }\", \".\\\\10ffffabc:after {\\n  content: \\\"\\\\10ffffabc\\\";\\n}\\n\")\n\n\t// This character should always be escaped\n\texpectPrinted(t, \".\\\\FEFF:after { content: '\\uFEFF' }\", \".\\\\feff:after {\\n  content: \\\"\\\\feff\\\";\\n}\\n\")\n}\n"
  },
  {
    "path": "internal/fs/error_other.go",
    "content": "//go:build (!js || !wasm) && !windows\n// +build !js !wasm\n// +build !windows\n\npackage fs\n\nfunc is_ERROR_INVALID_NAME(err error) bool {\n\treturn false\n}\n"
  },
  {
    "path": "internal/fs/error_wasm+windows.go",
    "content": "//go:build (js && wasm) || windows\n// +build js,wasm windows\n\npackage fs\n\nimport \"syscall\"\n\n// This check is here in a conditionally-compiled file because Go's standard\n// library for Plan 9 doesn't define a type called \"syscall.Errno\". Plan 9 is\n// not a supported operating system but someone wanted to be able to compile\n// esbuild for Plan 9 anyway.\nfunc is_ERROR_INVALID_NAME(err error) bool {\n\t// This has been copied from golang.org/x/sys/windows\n\tconst ERROR_INVALID_NAME syscall.Errno = 123\n\n\treturn err == ERROR_INVALID_NAME\n}\n"
  },
  {
    "path": "internal/fs/filepath.go",
    "content": "// Code in this file has been forked from the \"filepath\" module in the Go\n// source code to work around bugs with the WebAssembly build target. More\n// information about why here: https://github.com/golang/go/issues/43768.\n\n////////////////////////////////////////////////////////////////////////////////\n\n// Copyright (c) 2009 The Go Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//    * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//    * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//    * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage fs\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"strings\"\n\t\"syscall\"\n)\n\ntype goFilepath struct {\n\tcwd           string\n\tisWindows     bool\n\tpathSeparator byte\n}\n\nfunc isSlash(c uint8) bool {\n\treturn c == '\\\\' || c == '/'\n}\n\n// reservedNames lists reserved Windows names. Search for PRN in\n// https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file\n// for details.\nvar reservedNames = []string{\n\t\"CON\", \"PRN\", \"AUX\", \"NUL\",\n\t\"COM1\", \"COM2\", \"COM3\", \"COM4\", \"COM5\", \"COM6\", \"COM7\", \"COM8\", \"COM9\",\n\t\"LPT1\", \"LPT2\", \"LPT3\", \"LPT4\", \"LPT5\", \"LPT6\", \"LPT7\", \"LPT8\", \"LPT9\",\n}\n\n// isReservedName returns true, if path is Windows reserved name.\n// See reservedNames for the full list.\nfunc isReservedName(path string) bool {\n\tif len(path) == 0 {\n\t\treturn false\n\t}\n\tfor _, reserved := range reservedNames {\n\t\tif strings.EqualFold(path, reserved) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// IsAbs reports whether the path is absolute.\nfunc (fp goFilepath) isAbs(path string) bool {\n\tif !fp.isWindows {\n\t\treturn strings.HasPrefix(path, \"/\")\n\t}\n\tif isReservedName(path) {\n\t\treturn true\n\t}\n\tl := fp.volumeNameLen(path)\n\tif l == 0 {\n\t\treturn false\n\t}\n\tpath = path[l:]\n\tif path == \"\" {\n\t\treturn false\n\t}\n\treturn isSlash(path[0])\n}\n\n// Abs returns an absolute representation of path.\n// If the path is not absolute it will be joined with the current\n// working directory to turn it into an absolute path. The absolute\n// path name for a given file is not guaranteed to be unique.\n// Abs calls Clean on the result.\nfunc (fp goFilepath) abs(path string) (string, error) {\n\tif fp.isAbs(path) {\n\t\treturn fp.clean(path), nil\n\t}\n\treturn fp.join([]string{fp.cwd, path}), nil\n}\n\n// IsPathSeparator reports whether c is a directory separator character.\nfunc (fp goFilepath) isPathSeparator(c uint8) bool {\n\treturn c == '/' || (fp.isWindows && c == '\\\\')\n}\n\n// volumeNameLen returns length of the leading volume name on Windows.\n// It returns 0 elsewhere.\nfunc (fp goFilepath) volumeNameLen(path string) int {\n\tif !fp.isWindows {\n\t\treturn 0\n\t}\n\tif len(path) < 2 {\n\t\treturn 0\n\t}\n\t// with drive letter\n\tc := path[0]\n\tif path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {\n\t\treturn 2\n\t}\n\t// is it UNC? https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx\n\tif l := len(path); l >= 5 && isSlash(path[0]) && isSlash(path[1]) &&\n\t\t!isSlash(path[2]) && path[2] != '.' {\n\t\t// first, leading `\\\\` and next shouldn't be `\\`. its server name.\n\t\tfor n := 3; n < l-1; n++ {\n\t\t\t// second, next '\\' shouldn't be repeated.\n\t\t\tif isSlash(path[n]) {\n\t\t\t\tn++\n\t\t\t\t// third, following something characters. its share name.\n\t\t\t\tif !isSlash(path[n]) {\n\t\t\t\t\tif path[n] == '.' {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tfor ; n < l; n++ {\n\t\t\t\t\t\tif isSlash(path[n]) {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn n\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn 0\n}\n\n// EvalSymlinks returns the path name after the evaluation of any symbolic\n// links.\n// If path is relative the result will be relative to the current directory,\n// unless one of the components is an absolute symbolic link.\n// EvalSymlinks calls Clean on the result.\nfunc (fp goFilepath) evalSymlinks(path string) (string, error) {\n\tvolLen := fp.volumeNameLen(path)\n\tpathSeparator := string(fp.pathSeparator)\n\n\tif volLen < len(path) && fp.isPathSeparator(path[volLen]) {\n\t\tvolLen++\n\t}\n\tvol := path[:volLen]\n\tdest := vol\n\tlinksWalked := 0\n\tfor start, end := volLen, volLen; start < len(path); start = end {\n\t\tfor start < len(path) && fp.isPathSeparator(path[start]) {\n\t\t\tstart++\n\t\t}\n\t\tend = start\n\t\tfor end < len(path) && !fp.isPathSeparator(path[end]) {\n\t\t\tend++\n\t\t}\n\n\t\t// On Windows, \".\" can be a symlink.\n\t\t// We look it up, and use the value if it is absolute.\n\t\t// If not, we just return \".\".\n\t\tisWindowsDot := fp.isWindows && path[fp.volumeNameLen(path):] == \".\"\n\n\t\t// The next path component is in path[start:end].\n\t\tif end == start {\n\t\t\t// No more path components.\n\t\t\tbreak\n\t\t} else if path[start:end] == \".\" && !isWindowsDot {\n\t\t\t// Ignore path component \".\".\n\t\t\tcontinue\n\t\t} else if path[start:end] == \"..\" {\n\t\t\t// Back up to previous component if possible.\n\t\t\t// Note that volLen includes any leading slash.\n\n\t\t\t// Set r to the index of the last slash in dest,\n\t\t\t// after the volume.\n\t\t\tvar r int\n\t\t\tfor r = len(dest) - 1; r >= volLen; r-- {\n\t\t\t\tif fp.isPathSeparator(dest[r]) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif r < volLen || dest[r+1:] == \"..\" {\n\t\t\t\t// Either path has no slashes\n\t\t\t\t// (it's empty or just \"C:\")\n\t\t\t\t// or it ends in a \"..\" we had to keep.\n\t\t\t\t// Either way, keep this \"..\".\n\t\t\t\tif len(dest) > volLen {\n\t\t\t\t\tdest += pathSeparator\n\t\t\t\t}\n\t\t\t\tdest += \"..\"\n\t\t\t} else {\n\t\t\t\t// Discard everything since the last slash.\n\t\t\t\tdest = dest[:r]\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Ordinary path component. Add it to result.\n\n\t\tif len(dest) > fp.volumeNameLen(dest) && !fp.isPathSeparator(dest[len(dest)-1]) {\n\t\t\tdest += pathSeparator\n\t\t}\n\n\t\tdest += path[start:end]\n\n\t\t// Resolve symlink.\n\n\t\tfi, err := os.Lstat(dest)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\tif fi.Mode()&os.ModeSymlink == 0 {\n\t\t\tif !fi.Mode().IsDir() && end < len(path) {\n\t\t\t\treturn \"\", syscall.ENOTDIR\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Found symlink.\n\n\t\tlinksWalked++\n\t\tif linksWalked > 255 {\n\t\t\treturn \"\", errors.New(\"EvalSymlinks: too many links\")\n\t\t}\n\n\t\tlink, err := os.Readlink(dest)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\tif isWindowsDot && !fp.isAbs(link) {\n\t\t\t// On Windows, if \".\" is a relative symlink,\n\t\t\t// just return \".\".\n\t\t\tbreak\n\t\t}\n\n\t\tpath = link + path[end:]\n\n\t\tv := fp.volumeNameLen(link)\n\t\tif v > 0 {\n\t\t\t// Symlink to drive name is an absolute path.\n\t\t\tif v < len(link) && fp.isPathSeparator(link[v]) {\n\t\t\t\tv++\n\t\t\t}\n\t\t\tvol = link[:v]\n\t\t\tdest = vol\n\t\t\tend = len(vol)\n\t\t} else if len(link) > 0 && fp.isPathSeparator(link[0]) {\n\t\t\t// Symlink to absolute path.\n\t\t\tdest = link[:1]\n\t\t\tend = 1\n\t\t} else {\n\t\t\t// Symlink to relative path; replace last\n\t\t\t// path component in dest.\n\t\t\tvar r int\n\t\t\tfor r = len(dest) - 1; r >= volLen; r-- {\n\t\t\t\tif fp.isPathSeparator(dest[r]) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif r < volLen {\n\t\t\t\tdest = vol\n\t\t\t} else {\n\t\t\t\tdest = dest[:r]\n\t\t\t}\n\t\t\tend = 0\n\t\t}\n\t}\n\treturn fp.clean(dest), nil\n}\n\n// A lazybuf is a lazily constructed path buffer.\n// It supports append, reading previously appended bytes,\n// and retrieving the final string. It does not allocate a buffer\n// to hold the output until that output diverges from s.\ntype lazybuf struct {\n\tpath       string\n\tvolAndPath string\n\tbuf        []byte\n\tw          int\n\tvolLen     int\n}\n\nfunc (b *lazybuf) index(i int) byte {\n\tif b.buf != nil {\n\t\treturn b.buf[i]\n\t}\n\treturn b.path[i]\n}\n\nfunc (b *lazybuf) append(c byte) {\n\tif b.buf == nil {\n\t\tif b.w < len(b.path) && b.path[b.w] == c {\n\t\t\tb.w++\n\t\t\treturn\n\t\t}\n\t\tb.buf = make([]byte, len(b.path))\n\t\tcopy(b.buf, b.path[:b.w])\n\t}\n\tb.buf[b.w] = c\n\tb.w++\n}\n\nfunc (b *lazybuf) string() string {\n\tif b.buf == nil {\n\t\treturn b.volAndPath[:b.volLen+b.w]\n\t}\n\treturn b.volAndPath[:b.volLen] + string(b.buf[:b.w])\n}\n\n// FromSlash returns the result of replacing each slash ('/') character\n// in path with a separator character. Multiple slashes are replaced\n// by multiple separators.\nfunc (fp goFilepath) fromSlash(path string) string {\n\tif !fp.isWindows {\n\t\treturn path\n\t}\n\treturn strings.ReplaceAll(path, \"/\", \"\\\\\")\n}\n\n// Clean returns the shortest path name equivalent to path\n// by purely lexical processing. It applies the following rules\n// iteratively until no further processing can be done:\n//\n//  1. Replace multiple Separator elements with a single one.\n//  2. Eliminate each . path name element (the current directory).\n//  3. Eliminate each inner .. path name element (the parent directory)\n//     along with the non-.. element that precedes it.\n//  4. Eliminate .. elements that begin a rooted path:\n//     that is, replace \"/..\" by \"/\" at the beginning of a path,\n//     assuming Separator is '/'.\n//\n// The returned path ends in a slash only if it represents a root directory,\n// such as \"/\" on Unix or `C:\\` on Windows.\n//\n// Finally, any occurrences of slash are replaced by Separator.\n//\n// If the result of this process is an empty string, Clean\n// returns the string \".\".\n//\n// See also Rob Pike, \"Lexical File Names in Plan 9 or\n// Getting Dot-Dot Right,\"\n// https://9p.io/sys/doc/lexnames.html\nfunc (fp goFilepath) clean(path string) string {\n\toriginalPath := path\n\tvolLen := fp.volumeNameLen(path)\n\tpath = path[volLen:]\n\tif path == \"\" {\n\t\tif volLen > 1 && originalPath[1] != ':' {\n\t\t\t// should be UNC\n\t\t\treturn fp.fromSlash(originalPath)\n\t\t}\n\t\treturn originalPath + \".\"\n\t}\n\trooted := fp.isPathSeparator(path[0])\n\n\t// Invariants:\n\t//\treading from path; r is index of next byte to process.\n\t//\twriting to buf; w is index of next byte to write.\n\t//\tdotdot is index in buf where .. must stop, either because\n\t//\t\tit is the leading slash or it is a leading ../../.. prefix.\n\tn := len(path)\n\tout := lazybuf{path: path, volAndPath: originalPath, volLen: volLen}\n\tr, dotdot := 0, 0\n\tif rooted {\n\t\tout.append(fp.pathSeparator)\n\t\tr, dotdot = 1, 1\n\t}\n\n\tfor r < n {\n\t\tswitch {\n\t\tcase fp.isPathSeparator(path[r]):\n\t\t\t// empty path element\n\t\t\tr++\n\t\tcase path[r] == '.' && (r+1 == n || fp.isPathSeparator(path[r+1])):\n\t\t\t// . element\n\t\t\tr++\n\t\tcase path[r] == '.' && path[r+1] == '.' && (r+2 == n || fp.isPathSeparator(path[r+2])):\n\t\t\t// .. element: remove to last separator\n\t\t\tr += 2\n\t\t\tswitch {\n\t\t\tcase out.w > dotdot:\n\t\t\t\t// can backtrack\n\t\t\t\tout.w--\n\t\t\t\tfor out.w > dotdot && !fp.isPathSeparator(out.index(out.w)) {\n\t\t\t\t\tout.w--\n\t\t\t\t}\n\t\t\tcase !rooted:\n\t\t\t\t// cannot backtrack, but not rooted, so append .. element.\n\t\t\t\tif out.w > 0 {\n\t\t\t\t\tout.append(fp.pathSeparator)\n\t\t\t\t}\n\t\t\t\tout.append('.')\n\t\t\t\tout.append('.')\n\t\t\t\tdotdot = out.w\n\t\t\t}\n\t\tdefault:\n\t\t\t// real path element.\n\t\t\t// add slash if needed\n\t\t\tif rooted && out.w != 1 || !rooted && out.w != 0 {\n\t\t\t\tout.append(fp.pathSeparator)\n\t\t\t}\n\t\t\t// copy element\n\t\t\tfor ; r < n && !fp.isPathSeparator(path[r]); r++ {\n\t\t\t\tout.append(path[r])\n\t\t\t}\n\t\t}\n\t}\n\n\t// Turn empty string into \".\"\n\tif out.w == 0 {\n\t\tout.append('.')\n\t}\n\n\treturn fp.fromSlash(out.string())\n}\n\n// VolumeName returns leading volume name.\n// Given \"C:\\foo\\bar\" it returns \"C:\" on Windows.\n// Given \"\\\\host\\share\\foo\" it returns \"\\\\host\\share\".\n// On other platforms it returns \"\".\nfunc (fp goFilepath) volumeName(path string) string {\n\treturn path[:fp.volumeNameLen(path)]\n}\n\n// Base returns the last element of path.\n// Trailing path separators are removed before extracting the last element.\n// If the path is empty, Base returns \".\".\n// If the path consists entirely of separators, Base returns a single separator.\nfunc (fp goFilepath) base(path string) string {\n\tif path == \"\" {\n\t\treturn \".\"\n\t}\n\t// Strip trailing slashes.\n\tfor len(path) > 0 && fp.isPathSeparator(path[len(path)-1]) {\n\t\tpath = path[0 : len(path)-1]\n\t}\n\t// Throw away volume name\n\tpath = path[len(fp.volumeName(path)):]\n\t// Find the last element\n\ti := len(path) - 1\n\tfor i >= 0 && !fp.isPathSeparator(path[i]) {\n\t\ti--\n\t}\n\tif i >= 0 {\n\t\tpath = path[i+1:]\n\t}\n\t// If empty now, it had only slashes.\n\tif path == \"\" {\n\t\treturn string(fp.pathSeparator)\n\t}\n\treturn path\n}\n\n// Dir returns all but the last element of path, typically the path's directory.\n// After dropping the final element, Dir calls Clean on the path and trailing\n// slashes are removed.\n// If the path is empty, Dir returns \".\".\n// If the path consists entirely of separators, Dir returns a single separator.\n// The returned path does not end in a separator unless it is the root directory.\nfunc (fp goFilepath) dir(path string) string {\n\tvol := fp.volumeName(path)\n\ti := len(path) - 1\n\tfor i >= len(vol) && !fp.isPathSeparator(path[i]) {\n\t\ti--\n\t}\n\tdir := fp.clean(path[len(vol) : i+1])\n\tif dir == \".\" && len(vol) > 2 {\n\t\t// must be UNC\n\t\treturn vol\n\t}\n\treturn vol + dir\n}\n\n// Ext returns the file name extension used by path.\n// The extension is the suffix beginning at the final dot\n// in the final element of path; it is empty if there is\n// no dot.\nfunc (fp goFilepath) ext(path string) string {\n\tfor i := len(path) - 1; i >= 0 && !fp.isPathSeparator(path[i]); i-- {\n\t\tif path[i] == '.' {\n\t\t\treturn path[i:]\n\t\t}\n\t}\n\treturn \"\"\n}\n\n// Join joins any number of path elements into a single path,\n// separating them with an OS specific Separator. Empty elements\n// are ignored. The result is Cleaned. However, if the argument\n// list is empty or all its elements are empty, Join returns\n// an empty string.\n// On Windows, the result will only be a UNC path if the first\n// non-empty element is a UNC path.\nfunc (fp goFilepath) join(elem []string) string {\n\tfor i, e := range elem {\n\t\tif e != \"\" {\n\t\t\tif fp.isWindows {\n\t\t\t\treturn fp.joinNonEmpty(elem[i:])\n\t\t\t}\n\t\t\treturn fp.clean(strings.Join(elem[i:], string(fp.pathSeparator)))\n\t\t}\n\t}\n\treturn \"\"\n}\n\n// joinNonEmpty is like join, but it assumes that the first element is non-empty.\nfunc (fp goFilepath) joinNonEmpty(elem []string) string {\n\tif len(elem[0]) == 2 && elem[0][1] == ':' {\n\t\t// First element is drive letter without terminating slash.\n\t\t// Keep path relative to current directory on that drive.\n\t\t// Skip empty elements.\n\t\ti := 1\n\t\tfor ; i < len(elem); i++ {\n\t\t\tif elem[i] != \"\" {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\treturn fp.clean(elem[0] + strings.Join(elem[i:], string(fp.pathSeparator)))\n\t}\n\t// The following logic prevents Join from inadvertently creating a\n\t// UNC path on Windows. Unless the first element is a UNC path, Join\n\t// shouldn't create a UNC path. See golang.org/issue/9167.\n\tp := fp.clean(strings.Join(elem, string(fp.pathSeparator)))\n\tif !fp.isUNC(p) {\n\t\treturn p\n\t}\n\t// p == UNC only allowed when the first element is a UNC path.\n\thead := fp.clean(elem[0])\n\tif fp.isUNC(head) {\n\t\treturn p\n\t}\n\t// head + tail == UNC, but joining two non-UNC paths should not result\n\t// in a UNC path. Undo creation of UNC path.\n\ttail := fp.clean(strings.Join(elem[1:], string(fp.pathSeparator)))\n\tif head[len(head)-1] == fp.pathSeparator {\n\t\treturn head + tail\n\t}\n\treturn head + string(fp.pathSeparator) + tail\n}\n\n// isUNC reports whether path is a UNC path.\nfunc (fp goFilepath) isUNC(path string) bool {\n\treturn fp.volumeNameLen(path) > 2\n}\n\n// Rel returns a relative path that is lexically equivalent to targpath when\n// joined to basepath with an intervening separator. That is,\n// Join(basepath, Rel(basepath, targpath)) is equivalent to targpath itself.\n// On success, the returned path will always be relative to basepath,\n// even if basepath and targpath share no elements.\n// An error is returned if targpath can't be made relative to basepath or if\n// knowing the current working directory would be necessary to compute it.\n// Rel calls Clean on the result.\nfunc (fp goFilepath) rel(basepath, targpath string) (string, error) {\n\tbaseVol := fp.volumeName(basepath)\n\ttargVol := fp.volumeName(targpath)\n\tbase := fp.clean(basepath)\n\ttarg := fp.clean(targpath)\n\tif fp.sameWord(targ, base) {\n\t\treturn \".\", nil\n\t}\n\tbase = base[len(baseVol):]\n\ttarg = targ[len(targVol):]\n\tif base == \".\" {\n\t\tbase = \"\"\n\t}\n\t// Can't use IsAbs - `\\a` and `a` are both relative in Windows.\n\tbaseSlashed := len(base) > 0 && base[0] == fp.pathSeparator\n\ttargSlashed := len(targ) > 0 && targ[0] == fp.pathSeparator\n\tif baseSlashed != targSlashed || !fp.sameWord(baseVol, targVol) {\n\t\treturn \"\", errors.New(\"Rel: can't make \" + targpath + \" relative to \" + basepath)\n\t}\n\t// Position base[b0:bi] and targ[t0:ti] at the first differing elements.\n\tbl := len(base)\n\ttl := len(targ)\n\tvar b0, bi, t0, ti int\n\tfor {\n\t\tfor bi < bl && base[bi] != fp.pathSeparator {\n\t\t\tbi++\n\t\t}\n\t\tfor ti < tl && targ[ti] != fp.pathSeparator {\n\t\t\tti++\n\t\t}\n\t\tif !fp.sameWord(targ[t0:ti], base[b0:bi]) {\n\t\t\tbreak\n\t\t}\n\t\tif bi < bl {\n\t\t\tbi++\n\t\t}\n\t\tif ti < tl {\n\t\t\tti++\n\t\t}\n\t\tb0 = bi\n\t\tt0 = ti\n\t}\n\tif base[b0:bi] == \"..\" {\n\t\treturn \"\", errors.New(\"Rel: can't make \" + targpath + \" relative to \" + basepath)\n\t}\n\tif b0 != bl {\n\t\t// Base elements left. Must go up before going down.\n\t\tseps := strings.Count(base[b0:bl], string(fp.pathSeparator))\n\t\tsize := 2 + seps*3\n\t\tif tl != t0 {\n\t\t\tsize += 1 + tl - t0\n\t\t}\n\t\tbuf := make([]byte, size)\n\t\tn := copy(buf, \"..\")\n\t\tfor i := 0; i < seps; i++ {\n\t\t\tbuf[n] = fp.pathSeparator\n\t\t\tcopy(buf[n+1:], \"..\")\n\t\t\tn += 3\n\t\t}\n\t\tif t0 != tl {\n\t\t\tbuf[n] = fp.pathSeparator\n\t\t\tcopy(buf[n+1:], targ[t0:])\n\t\t}\n\t\treturn string(buf), nil\n\t}\n\treturn targ[t0:], nil\n}\n\nfunc (fp goFilepath) sameWord(a, b string) bool {\n\tif !fp.isWindows {\n\t\treturn a == b\n\t}\n\treturn strings.EqualFold(a, b)\n}\n"
  },
  {
    "path": "internal/fs/fs.go",
    "content": "package fs\n\n// Most of esbuild's internals use this file system abstraction instead of\n// using native file system APIs. This lets us easily mock the file system\n// for tests and also implement Yarn's virtual \".zip\" file system overlay.\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"syscall\"\n)\n\ntype EntryKind uint8\n\nconst (\n\tDirEntry  EntryKind = 1\n\tFileEntry EntryKind = 2\n)\n\ntype Entry struct {\n\tsymlink  string\n\tdir      string\n\tbase     string\n\tmutex    sync.Mutex\n\tkind     EntryKind\n\tneedStat bool\n}\n\nfunc (e *Entry) Kind(fs FS) EntryKind {\n\te.mutex.Lock()\n\tdefer e.mutex.Unlock()\n\tif e.needStat {\n\t\te.needStat = false\n\t\te.symlink, e.kind = fs.kind(e.dir, e.base)\n\t}\n\treturn e.kind\n}\n\nfunc (e *Entry) Symlink(fs FS) string {\n\te.mutex.Lock()\n\tdefer e.mutex.Unlock()\n\tif e.needStat {\n\t\te.needStat = false\n\t\te.symlink, e.kind = fs.kind(e.dir, e.base)\n\t}\n\treturn e.symlink\n}\n\ntype accessedEntries struct {\n\twasPresent map[string]bool\n\n\t// If this is nil, \"SortedKeys()\" was not accessed. This means we should\n\t// check for whether this directory has changed or not by seeing if any of\n\t// the entries in the \"wasPresent\" map have changed in \"present or not\"\n\t// status, since the only access was to individual entries via \"Get()\".\n\t//\n\t// If this is non-nil, \"SortedKeys()\" was accessed. This means we should\n\t// check for whether this directory has changed or not by checking the\n\t// \"allEntries\" array for equality with the existing entries list, since the\n\t// code asked for all entries and may have used the presence or absence of\n\t// entries in that list.\n\t//\n\t// The goal of having these two checks is to be as narrow as possible to\n\t// avoid unnecessary rebuilds. If only \"Get()\" is called on a few entries,\n\t// then we won't invalidate the build if random unrelated entries are added\n\t// or removed. But if \"SortedKeys()\" is called, we need to invalidate the\n\t// build if anything about the set of entries in this directory is changed.\n\tallEntries []string\n\n\tmutex sync.Mutex\n}\n\ntype DirEntries struct {\n\tdata            map[string]*Entry\n\taccessedEntries *accessedEntries\n\tdir             string\n}\n\nfunc MakeEmptyDirEntries(dir string) DirEntries {\n\treturn DirEntries{dir: dir, data: make(map[string]*Entry)}\n}\n\ntype DifferentCase struct {\n\tDir    string\n\tQuery  string\n\tActual string\n}\n\nfunc (entries DirEntries) Get(query string) (*Entry, *DifferentCase) {\n\tif entries.data != nil {\n\t\tkey := strings.ToLower(query)\n\t\tentry := entries.data[key]\n\n\t\t// Track whether this specific entry was present or absent for watch mode\n\t\tif accessed := entries.accessedEntries; accessed != nil {\n\t\t\taccessed.mutex.Lock()\n\t\t\taccessed.wasPresent[key] = entry != nil\n\t\t\taccessed.mutex.Unlock()\n\t\t}\n\n\t\tif entry != nil {\n\t\t\tif entry.base != query {\n\t\t\t\treturn entry, &DifferentCase{\n\t\t\t\t\tDir:    entries.dir,\n\t\t\t\t\tQuery:  query,\n\t\t\t\t\tActual: entry.base,\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn entry, nil\n\t\t}\n\t}\n\n\treturn nil, nil\n}\n\n// This function lets you \"peek\" at the number of entries without watch mode\n// considering the number of entries as having been observed. This is used when\n// generating debug log messages to log the number of entries without causing\n// watch mode to rebuild when the number of entries has been changed.\nfunc (entries DirEntries) PeekEntryCount() int {\n\tif entries.data != nil {\n\t\treturn len(entries.data)\n\t}\n\treturn 0\n}\n\nfunc (entries DirEntries) SortedKeys() (keys []string) {\n\tif entries.data != nil {\n\t\tkeys = make([]string, 0, len(entries.data))\n\t\tfor _, entry := range entries.data {\n\t\t\tkeys = append(keys, entry.base)\n\t\t}\n\t\tsort.Strings(keys)\n\n\t\t// Track the exact set of all entries for watch mode\n\t\tif entries.accessedEntries != nil {\n\t\t\tentries.accessedEntries.mutex.Lock()\n\t\t\tentries.accessedEntries.allEntries = keys\n\t\t\tentries.accessedEntries.mutex.Unlock()\n\t\t}\n\n\t\treturn keys\n\t}\n\n\treturn\n}\n\ntype OpenedFile interface {\n\tLen() int\n\tRead(start int, end int) ([]byte, error)\n\tClose() error\n}\n\ntype InMemoryOpenedFile struct {\n\tContents []byte\n}\n\nfunc (f *InMemoryOpenedFile) Len() int {\n\treturn len(f.Contents)\n}\n\nfunc (f *InMemoryOpenedFile) Read(start int, end int) ([]byte, error) {\n\treturn []byte(f.Contents[start:end]), nil\n}\n\nfunc (f *InMemoryOpenedFile) Close() error {\n\treturn nil\n}\n\ntype FS interface {\n\t// The returned map is immutable and is cached across invocations. Do not\n\t// mutate it.\n\tReadDirectory(path string) (entries DirEntries, canonicalError error, originalError error)\n\tReadFile(path string) (contents string, canonicalError error, originalError error)\n\tOpenFile(path string) (result OpenedFile, canonicalError error, originalError error)\n\n\t// This is a key made from the information returned by \"stat\". It is intended\n\t// to be different if the file has been edited, and to otherwise be equal if\n\t// the file has not been edited. It should usually work, but no guarantees.\n\t//\n\t// See https://apenwarr.ca/log/20181113 for more information about why this\n\t// can be broken. For example, writing to a file with mmap on WSL on Windows\n\t// won't change this key. Hopefully this isn't too much of an issue.\n\t//\n\t// Additional reading:\n\t// - https://github.com/npm/npm/pull/20027\n\t// - https://github.com/golang/go/commit/7dea509703eb5ad66a35628b12a678110fbb1f72\n\tModKey(path string) (ModKey, error)\n\n\t// This is part of the interface because the mock interface used for tests\n\t// should not depend on file system behavior (i.e. different slashes for\n\t// Windows) while the real interface should.\n\tIsAbs(path string) bool\n\tAbs(path string) (string, bool)\n\tDir(path string) string\n\tBase(path string) string\n\tExt(path string) string\n\tJoin(parts ...string) string\n\tCwd() string\n\tRel(base string, target string) (string, bool)\n\tEvalSymlinks(path string) (string, bool)\n\n\t// This is used in the implementation of \"Entry\"\n\tkind(dir string, base string) (symlink string, kind EntryKind)\n\n\t// This is a set of all files used and all directories checked. The build\n\t// must be invalidated if any of these watched files change.\n\tWatchData() WatchData\n}\n\ntype WatchData struct {\n\t// These functions return a non-empty path as a string if the file system\n\t// entry has been modified. For files, the returned path is the same as the\n\t// file path. For directories, the returned path is either the directory\n\t// itself or a file in the directory that was changed.\n\tPaths map[string]func() string\n}\n\ntype ModKey struct {\n\t// What gets filled in here is OS-dependent\n\tinode      uint64\n\tsize       int64\n\tmtime_sec  int64\n\tmtime_nsec int64\n\tmode       uint32\n\tuid        uint32\n}\n\n// Some file systems have a time resolution of only a few seconds. If a mtime\n// value is too new, we won't be able to tell if it has been recently modified\n// or not. So we only use mtimes for comparison if they are sufficiently old.\n// Apparently the FAT file system has a resolution of two seconds according to\n// this article: https://en.wikipedia.org/wiki/Stat_(system_call).\nconst modKeySafetyGap = 3 // In seconds\nvar modKeyUnusable = errors.New(\"The modification key is unusable\")\n\n// Limit the number of files open simultaneously to avoid ulimit issues\nvar fileOpenLimit = make(chan bool, 32)\n\nfunc BeforeFileOpen() {\n\t// This will block if the number of open files is already at the limit\n\tfileOpenLimit <- false\n}\n\nfunc AfterFileClose() {\n\t<-fileOpenLimit\n}\n\n// This is a fork of \"os.MkdirAll\" to work around bugs with the WebAssembly\n// build target. More information here: https://github.com/golang/go/issues/43768.\nfunc MkdirAll(fs FS, path string, perm os.FileMode) error {\n\t// Run \"Join\" once to run \"Clean\" on the path, which removes trailing slashes\n\treturn mkdirAll(fs, fs.Join(path), perm)\n}\n\nfunc mkdirAll(fs FS, path string, perm os.FileMode) error {\n\t// Fast path: if we can tell whether path is a directory or file, stop with success or error.\n\tif dir, err := os.Stat(path); err == nil {\n\t\tif dir.IsDir() {\n\t\t\treturn nil\n\t\t}\n\t\treturn &os.PathError{Op: \"mkdir\", Path: path, Err: syscall.ENOTDIR}\n\t}\n\n\t// Slow path: make sure parent exists and then call Mkdir for path.\n\tif parent := fs.Dir(path); parent != path {\n\t\t// Create parent.\n\t\tif err := mkdirAll(fs, parent, perm); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Parent now exists; invoke Mkdir and use its result.\n\tif err := os.Mkdir(path, perm); err != nil {\n\t\t// Handle arguments like \"foo/.\" by\n\t\t// double-checking that directory doesn't exist.\n\t\tdir, err1 := os.Lstat(path)\n\t\tif err1 == nil && dir.IsDir() {\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "internal/fs/fs_mock.go",
    "content": "package fs\n\n// This is a mock implementation of the \"fs\" module for use with tests. It does\n// not actually read from the file system. Instead, it reads from a pre-specified\n// map of file paths to files.\n\nimport (\n\t\"errors\"\n\t\"path\"\n\t\"strings\"\n\t\"syscall\"\n)\n\ntype MockKind uint8\n\nconst (\n\tMockUnix MockKind = iota\n\tMockWindows\n)\n\ntype mockFS struct {\n\tdirs          map[string]DirEntries\n\tfiles         map[string]string\n\tabsWorkingDir string\n\tdefaultVolume string\n\tKind          MockKind\n}\n\nfunc MockFS(input map[string]string, kind MockKind, absWorkingDir string) FS {\n\tdirs := make(map[string]DirEntries)\n\tfiles := make(map[string]string)\n\n\tvar defaultVolume string\n\tif kind == MockWindows {\n\t\t_, defaultVolume = win2unix(absWorkingDir)\n\t}\n\n\tfor k, v := range input {\n\t\tvar volume string\n\t\tfiles[k] = v\n\t\tif kind == MockWindows {\n\t\t\tk, volume = win2unix(k)\n\t\t}\n\t\toriginal := k\n\n\t\t// Build the directory map\n\t\tfor {\n\t\t\tkDir := path.Dir(k)\n\t\t\tkey := kDir\n\t\t\tif kind == MockWindows {\n\t\t\t\tkey = unix2win(key, volume, defaultVolume)\n\t\t\t}\n\t\t\tdir, ok := dirs[key]\n\t\t\tif !ok {\n\t\t\t\tdir = DirEntries{dir: key, data: make(map[string]*Entry)}\n\t\t\t\tdirs[key] = dir\n\t\t\t}\n\t\t\tif kDir == k {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tbase := path.Base(k)\n\t\t\tif k == original {\n\t\t\t\tdir.data[strings.ToLower(base)] = &Entry{kind: FileEntry, base: base}\n\t\t\t} else {\n\t\t\t\tdir.data[strings.ToLower(base)] = &Entry{kind: DirEntry, base: base}\n\t\t\t}\n\t\t\tk = kDir\n\t\t}\n\t}\n\n\treturn &mockFS{dirs, files, absWorkingDir, defaultVolume, kind}\n}\n\nfunc (fs *mockFS) ReadDirectory(path string) (DirEntries, error, error) {\n\tif fs.Kind == MockWindows {\n\t\tpath = strings.ReplaceAll(path, \"/\", \"\\\\\")\n\t}\n\n\tvar slash byte = '/'\n\tif fs.Kind == MockWindows {\n\t\tslash = '\\\\'\n\t}\n\n\t// Trim trailing slashes before lookup\n\tfirstSlash := strings.IndexByte(path, slash)\n\tfor {\n\t\ti := strings.LastIndexByte(path, slash)\n\t\tif i != len(path)-1 || i <= firstSlash {\n\t\t\tbreak\n\t\t}\n\t\tpath = path[:i]\n\t}\n\n\tif dir, ok := fs.dirs[path]; ok {\n\t\treturn dir, nil, nil\n\t}\n\treturn DirEntries{}, syscall.ENOENT, syscall.ENOENT\n}\n\nfunc (fs *mockFS) ReadFile(path string) (string, error, error) {\n\tif fs.Kind == MockWindows {\n\t\tpath = strings.ReplaceAll(path, \"/\", \"\\\\\")\n\t}\n\tif contents, ok := fs.files[path]; ok {\n\t\treturn contents, nil, nil\n\t}\n\treturn \"\", syscall.ENOENT, syscall.ENOENT\n}\n\nfunc (fs *mockFS) OpenFile(path string) (OpenedFile, error, error) {\n\tif fs.Kind == MockWindows {\n\t\tpath = strings.ReplaceAll(path, \"/\", \"\\\\\")\n\t}\n\tif contents, ok := fs.files[path]; ok {\n\t\treturn &InMemoryOpenedFile{Contents: []byte(contents)}, nil, nil\n\t}\n\treturn nil, syscall.ENOENT, syscall.ENOENT\n}\n\nfunc (fs *mockFS) ModKey(path string) (ModKey, error) {\n\treturn ModKey{}, errors.New(\"This is not available during tests\")\n}\n\nfunc win2unix(p string) (result string, volume string) {\n\tif len(p) > 0 && strings.HasPrefix(p[1:], \":\\\\\") {\n\t\tif c := p[0]; (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') {\n\t\t\tvolume = p[0:1]\n\t\t\tp = p[2:]\n\t\t}\n\t}\n\tp = strings.ReplaceAll(p, \"\\\\\", \"/\")\n\treturn p, volume\n}\n\nfunc unix2win(p string, volume string, defaultVolume string) string {\n\tp = strings.ReplaceAll(p, \"/\", \"\\\\\")\n\tif strings.HasPrefix(p, \"\\\\\") {\n\t\tif volume == \"\" {\n\t\t\tvolume = defaultVolume\n\t\t}\n\t\tp = volume + \":\" + p\n\t}\n\treturn p\n}\n\nfunc (fs *mockFS) IsAbs(p string) bool {\n\tif fs.Kind == MockWindows {\n\t\tp, _ = win2unix(p)\n\t}\n\treturn path.IsAbs(p)\n}\n\nfunc (fs *mockFS) Abs(p string) (string, bool) {\n\tvar volume string\n\tif fs.Kind == MockWindows {\n\t\tp, volume = win2unix(p)\n\t}\n\n\tp = path.Clean(path.Join(\"/\", p))\n\n\tif fs.Kind == MockWindows {\n\t\tp = unix2win(p, volume, fs.defaultVolume)\n\t}\n\n\treturn p, true\n}\n\nfunc (fs *mockFS) Dir(p string) string {\n\tvar volume string\n\tif fs.Kind == MockWindows {\n\t\tp, volume = win2unix(p)\n\t}\n\n\tp = path.Dir(p)\n\n\tif fs.Kind == MockWindows {\n\t\tp = unix2win(p, volume, fs.defaultVolume)\n\t}\n\n\treturn p\n}\n\nfunc (fs *mockFS) Base(p string) string {\n\tvar volume string\n\tif fs.Kind == MockWindows {\n\t\tp, volume = win2unix(p)\n\t}\n\n\tp = path.Base(p)\n\n\tif fs.Kind == MockWindows && p == \"/\" {\n\t\tp = volume + \":\\\\\"\n\t}\n\n\treturn p\n}\n\nfunc (fs *mockFS) Ext(p string) string {\n\tif fs.Kind == MockWindows {\n\t\tp, _ = win2unix(p)\n\t}\n\n\treturn path.Ext(p)\n}\n\nfunc (fs *mockFS) Join(parts ...string) string {\n\tvar volume string\n\tif fs.Kind == MockWindows {\n\t\tconverted := make([]string, len(parts))\n\t\tfor i, part := range parts {\n\t\t\tvar v string\n\t\t\tconverted[i], v = win2unix(part)\n\t\t\tif i == 0 {\n\t\t\t\tvolume = v\n\t\t\t}\n\t\t}\n\t\tparts = converted\n\t}\n\n\tp := path.Clean(path.Join(parts...))\n\n\tif fs.Kind == MockWindows {\n\t\tp = unix2win(p, volume, fs.defaultVolume)\n\t}\n\n\treturn p\n}\n\nfunc (fs *mockFS) Cwd() string {\n\treturn fs.absWorkingDir\n}\n\nfunc splitOnSlash(path string) (string, string) {\n\tif slash := strings.IndexByte(path, '/'); slash != -1 {\n\t\treturn path[:slash], path[slash+1:]\n\t}\n\treturn path, \"\"\n}\n\nfunc (fs *mockFS) Rel(base string, target string) (string, bool) {\n\tvar volume string\n\tif fs.Kind == MockWindows {\n\t\tvar v string\n\t\tbase, volume = win2unix(base)\n\t\ttarget, v = win2unix(target)\n\t\tif volume == \"\" {\n\t\t\tvolume = fs.defaultVolume\n\t\t}\n\t\tif v == \"\" {\n\t\t\tv = fs.defaultVolume\n\t\t}\n\t\tif strings.ToUpper(v) != strings.ToUpper(volume) {\n\t\t\treturn \"\", false\n\t\t}\n\t}\n\n\tbase = path.Clean(base)\n\ttarget = path.Clean(target)\n\n\t// Go's implementation does these checks\n\tif base == target {\n\t\treturn \".\", true\n\t}\n\tif base == \".\" {\n\t\tbase = \"\"\n\t}\n\n\t// Go's implementation fails when this condition is false. I believe this is\n\t// because of this part of the contract, from Go's documentation: \"An error\n\t// is returned if targpath can't be made relative to basepath or if knowing\n\t// the current working directory would be necessary to compute it.\"\n\tif (len(base) > 0 && base[0] == '/') != (len(target) > 0 && target[0] == '/') {\n\t\treturn \"\", false\n\t}\n\n\t// Find the common parent directory\n\tfor {\n\t\tbHead, bTail := splitOnSlash(base)\n\t\ttHead, tTail := splitOnSlash(target)\n\t\tif bHead != tHead {\n\t\t\tbreak\n\t\t}\n\t\tbase = bTail\n\t\ttarget = tTail\n\t}\n\n\t// Stop now if base is a subpath of target\n\tif base == \"\" {\n\t\tif fs.Kind == MockWindows {\n\t\t\ttarget = unix2win(target, volume, fs.defaultVolume)\n\t\t}\n\t\treturn target, true\n\t}\n\n\t// Traverse up to the common parent\n\tcommonParent := strings.Repeat(\"../\", strings.Count(base, \"/\")+1)\n\n\t// Stop now if target is a subpath of base\n\tif target == \"\" {\n\t\ttarget = commonParent[:len(commonParent)-1]\n\t\tif fs.Kind == MockWindows {\n\t\t\ttarget = unix2win(target, volume, fs.defaultVolume)\n\t\t}\n\t\treturn target, true\n\t}\n\n\t// Otherwise, down to the parent\n\ttarget = commonParent + target\n\tif fs.Kind == MockWindows {\n\t\ttarget = unix2win(target, volume, fs.defaultVolume)\n\t}\n\treturn target, true\n}\n\nfunc (fs *mockFS) EvalSymlinks(path string) (string, bool) {\n\treturn \"\", false\n}\n\nfunc (fs *mockFS) kind(dir string, base string) (symlink string, kind EntryKind) {\n\tpanic(\"This should never be called\")\n}\n\nfunc (fs *mockFS) WatchData() WatchData {\n\tpanic(\"This should never be called\")\n}\n"
  },
  {
    "path": "internal/fs/fs_mock_test.go",
    "content": "package fs\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n)\n\nfunc TestMockFSBasicUnix(t *testing.T) {\n\tfs := MockFS(map[string]string{\n\t\t\"/README.md\":    \"// README.md\",\n\t\t\"/package.json\": \"// package.json\",\n\t\t\"/src/index.js\": \"// src/index.js\",\n\t\t\"/src/util.js\":  \"// src/util.js\",\n\t}, MockUnix, \"/\")\n\n\t// Test a missing file\n\t_, err, _ := fs.ReadFile(\"/missing.txt\")\n\tif err == nil {\n\t\tt.Fatal(\"Unexpectedly found /missing.txt\")\n\t}\n\n\t// Test an existing file\n\treadme, err, _ := fs.ReadFile(\"/README.md\")\n\tif err != nil {\n\t\tt.Fatal(\"Expected to find /README.md\")\n\t}\n\tif readme != \"// README.md\" {\n\t\tt.Fatalf(\"Incorrect contents for /README.md: %q\", readme)\n\t}\n\n\t// Test an existing nested file\n\tindex, err, _ := fs.ReadFile(\"/src/index.js\")\n\tif err != nil {\n\t\tt.Fatal(\"Expected to find /src/index.js\")\n\t}\n\tif index != \"// src/index.js\" {\n\t\tt.Fatalf(\"Incorrect contents for /src/index.js: %q\", index)\n\t}\n\n\t// Test a missing directory\n\t_, err, _ = fs.ReadDirectory(\"/missing\")\n\tif err == nil {\n\t\tt.Fatal(\"Unexpectedly found /missing\")\n\t}\n\n\t// Test a nested directory\n\tsrc, err, _ := fs.ReadDirectory(\"/src\")\n\tif err != nil {\n\t\tt.Fatal(\"Expected to find /src\")\n\t}\n\tindexEntry, _ := src.Get(\"index.js\")\n\tutilEntry, _ := src.Get(\"util.js\")\n\tif len(src.data) != 2 ||\n\t\tindexEntry == nil || indexEntry.Kind(fs) != FileEntry ||\n\t\tutilEntry == nil || utilEntry.Kind(fs) != FileEntry {\n\t\tt.Fatalf(\"Incorrect contents for /src: %v\", src)\n\t}\n\n\t// Test the top-level directory\n\tslash, err, _ := fs.ReadDirectory(\"/\")\n\tif err != nil {\n\t\tt.Fatal(\"Expected to find /\")\n\t}\n\tsrcEntry, _ := slash.Get(\"src\")\n\treadmeEntry, _ := slash.Get(\"README.md\")\n\tpackageEntry, _ := slash.Get(\"package.json\")\n\tif len(slash.data) != 3 ||\n\t\tsrcEntry == nil || srcEntry.Kind(fs) != DirEntry ||\n\t\treadmeEntry == nil || readmeEntry.Kind(fs) != FileEntry ||\n\t\tpackageEntry == nil || packageEntry.Kind(fs) != FileEntry {\n\t\tt.Fatalf(\"Incorrect contents for /: %v\", slash)\n\t}\n}\n\nfunc TestMockFSBasicWindows(t *testing.T) {\n\tfs := MockFS(map[string]string{\n\t\t\"C:\\\\README.md\":       \"// README.md\",\n\t\t\"C:\\\\package.json\":    \"// package.json\",\n\t\t\"C:\\\\src\\\\index.js\":   \"// src/index.js\",\n\t\t\"C:\\\\src\\\\util.js\":    \"// src/util.js\",\n\t\t\"D:\\\\other\\\\file.txt\": \"// other/file.txt\",\n\t}, MockWindows, \"C:\\\\\")\n\n\t// Test a missing file\n\t_, err, _ := fs.ReadFile(\"C:\\\\missing.txt\")\n\tif err == nil {\n\t\tt.Fatal(\"Unexpectedly found C:\\\\missing.txt\")\n\t}\n\n\t// Test an existing file\n\treadme, err, _ := fs.ReadFile(\"C:\\\\README.md\")\n\tif err != nil {\n\t\tt.Fatal(\"Expected to find C:\\\\README.md\")\n\t}\n\tif readme != \"// README.md\" {\n\t\tt.Fatalf(\"Incorrect contents for C:\\\\README.md: %q\", readme)\n\t}\n\n\t// Test an existing nested file\n\tindex, err, _ := fs.ReadFile(\"C:\\\\src\\\\index.js\")\n\tif err != nil {\n\t\tt.Fatal(\"Expected to find C:\\\\src\\\\index.js\")\n\t}\n\tif index != \"// src/index.js\" {\n\t\tt.Fatalf(\"Incorrect contents for C:\\\\src\\\\index.js: %q\", index)\n\t}\n\n\t// Test an existing nested file on another drive\n\tfile, err, _ := fs.ReadFile(\"D:\\\\other\\\\file.txt\")\n\tif err != nil {\n\t\tt.Fatal(\"Expected to find D:\\\\other\\\\file.txt\")\n\t}\n\tif file != \"// other/file.txt\" {\n\t\tt.Fatalf(\"Incorrect contents for D:\\\\other/file.txt: %q\", file)\n\t}\n\n\t// Should not find a file on another drive\n\t_, err, _ = fs.ReadFile(\"C:\\\\other\\\\file.txt\")\n\tif err == nil {\n\t\tt.Fatal(\"Unexpectedly found C:\\\\other\\\\file.txt\")\n\t}\n\n\t// Test a missing directory\n\t_, err, _ = fs.ReadDirectory(\"C:\\\\missing\")\n\tif err == nil {\n\t\tt.Fatal(\"Unexpectedly found C:\\\\missing\")\n\t}\n\n\t// Test a nested directory\n\tsrc, err, _ := fs.ReadDirectory(\"C:\\\\src\")\n\tif err != nil {\n\t\tt.Fatal(\"Expected to find C:\\\\src\")\n\t}\n\tindexEntry, _ := src.Get(\"index.js\")\n\tutilEntry, _ := src.Get(\"util.js\")\n\tif len(src.data) != 2 ||\n\t\tindexEntry == nil || indexEntry.Kind(fs) != FileEntry ||\n\t\tutilEntry == nil || utilEntry.Kind(fs) != FileEntry {\n\t\tt.Fatalf(\"Incorrect contents for C:\\\\src: %v\", src)\n\t}\n\n\t// Test a nested directory on another drive\n\tother, err, _ := fs.ReadDirectory(\"D:\\\\other\")\n\tif err != nil {\n\t\tt.Fatal(\"Expected to find D:\\\\other\")\n\t}\n\tfileEntry, _ := other.Get(\"file.txt\")\n\tif len(other.data) != 1 ||\n\t\tfileEntry == nil || fileEntry.Kind(fs) != FileEntry {\n\t\tt.Fatalf(\"Incorrect contents for D:\\\\other: %v\", other)\n\t}\n\n\t// Test the top-level directory\n\tslash, err, _ := fs.ReadDirectory(\"C:\\\\\")\n\tif err != nil {\n\t\tt.Fatal(\"Expected to find C:\\\\\")\n\t}\n\tsrcEntry, _ := slash.Get(\"src\")\n\treadmeEntry, _ := slash.Get(\"README.md\")\n\tpackageEntry, _ := slash.Get(\"package.json\")\n\tif len(slash.data) != 3 ||\n\t\tsrcEntry == nil || srcEntry.Kind(fs) != DirEntry ||\n\t\treadmeEntry == nil || readmeEntry.Kind(fs) != FileEntry ||\n\t\tpackageEntry == nil || packageEntry.Kind(fs) != FileEntry {\n\t\tt.Fatalf(\"Incorrect contents for C:\\\\: %v\", slash)\n\t}\n}\n\nfunc TestMockFSRelUnix(t *testing.T) {\n\tfs := MockFS(map[string]string{}, MockUnix, \"/\")\n\n\texpect := func(a string, b string, c string) {\n\t\tt.Helper()\n\t\tt.Run(fmt.Sprintf(\"Rel(%q, %q) == %q\", a, b, c), func(t *testing.T) {\n\t\t\tt.Helper()\n\t\t\trel, ok := fs.Rel(a, b)\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"!ok\")\n\t\t\t}\n\t\t\tif rel != c {\n\t\t\t\tt.Fatalf(\"Expected %q, got %q\", c, rel)\n\t\t\t}\n\t\t})\n\t}\n\n\texpect(\"/a/b\", \"/a/b\", \".\")\n\texpect(\"/a/b\", \"/a/b/c\", \"c\")\n\texpect(\"/a/b\", \"/a/b/c/d\", \"c/d\")\n\texpect(\"/a/b/c\", \"/a/b\", \"..\")\n\texpect(\"/a/b/c/d\", \"/a/b\", \"../..\")\n\texpect(\"/a/b/c\", \"/a/b/x\", \"../x\")\n\texpect(\"/a/b/c/d\", \"/a/b/x\", \"../../x\")\n\texpect(\"/a/b/c\", \"/a/b/x/y\", \"../x/y\")\n\texpect(\"/a/b/c/d\", \"/a/b/x/y\", \"../../x/y\")\n\n\texpect(\"a/b\", \"a/c\", \"../c\")\n\texpect(\"./a/b\", \"./a/c\", \"../c\")\n\texpect(\".\", \"./a/b\", \"a/b\")\n\texpect(\".\", \".//a/b\", \"a/b\")\n\texpect(\".\", \"././a/b\", \"a/b\")\n\texpect(\".\", \"././/a/b\", \"a/b\")\n}\n\nfunc TestMockFSRelWindows(t *testing.T) {\n\tfs := MockFS(map[string]string{}, MockWindows, \"C:\\\\\")\n\n\texpect := func(a string, b string, works bool, c string) {\n\t\tt.Helper()\n\t\tt.Run(fmt.Sprintf(\"Rel(%q, %q) == %q\", a, b, c), func(t *testing.T) {\n\t\t\tt.Helper()\n\t\t\trel, ok := fs.Rel(a, b)\n\t\t\tif works {\n\t\t\t\tif !ok {\n\t\t\t\t\tt.Fatalf(\"!ok\")\n\t\t\t\t}\n\t\t\t\tif rel != c {\n\t\t\t\t\tt.Fatalf(\"Expected %q, got %q\", c, rel)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ok {\n\t\t\t\t\tt.Fatalf(\"ok\")\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n\n\texpect(\"C:\\\\a\\\\b\", \"C:\\\\a\\\\b\", true, \".\")\n\texpect(\"C:\\\\a\\\\b\", \"C:\\\\a\\\\b\\\\c\", true, \"c\")\n\texpect(\"C:\\\\a\\\\b\", \"C:\\\\a\\\\b\\\\c\\\\d\", true, \"c\\\\d\")\n\texpect(\"C:\\\\a\\\\b\\\\c\", \"C:\\\\a\\\\b\", true, \"..\")\n\texpect(\"C:\\\\a\\\\b\\\\c\\\\d\", \"C:\\\\a\\\\b\", true, \"..\\\\..\")\n\texpect(\"C:\\\\a\\\\b\\\\c\", \"C:\\\\a\\\\b\\\\x\", true, \"..\\\\x\")\n\texpect(\"C:\\\\a\\\\b\\\\c\\\\d\", \"C:\\\\a\\\\b\\\\x\", true, \"..\\\\..\\\\x\")\n\texpect(\"C:\\\\a\\\\b\\\\c\", \"C:\\\\a\\\\b\\\\x\\\\y\", true, \"..\\\\x\\\\y\")\n\texpect(\"C:\\\\a\\\\b\\\\c\\\\d\", \"C:\\\\a\\\\b\\\\x\\\\y\", true, \"..\\\\..\\\\x\\\\y\")\n\n\texpect(\"a\\\\b\", \"a\\\\c\", true, \"..\\\\c\")\n\texpect(\".\\\\a\\\\b\", \".\\\\a\\\\c\", true, \"..\\\\c\")\n\texpect(\".\", \".\\\\a\\\\b\", true, \"a\\\\b\")\n\texpect(\".\", \".\\\\\\\\a\\\\b\", true, \"a\\\\b\")\n\texpect(\".\", \".\\\\.\\\\a\\\\b\", true, \"a\\\\b\")\n\texpect(\".\", \".\\\\.\\\\\\\\a\\\\b\", true, \"a\\\\b\")\n\n\texpect(\"C:\\\\a\\\\b\", \"\\\\a\\\\b\", true, \".\")\n\texpect(\"\\\\a\", \"\\\\b\", true, \"..\\\\b\")\n\texpect(\"C:\\\\a\", \"D:\\\\a\", false, \"\")\n}\n"
  },
  {
    "path": "internal/fs/fs_real.go",
    "content": "package fs\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"syscall\"\n)\n\ntype realFS struct {\n\t// Stores the file entries for directories we've listed before\n\tentries map[string]entriesOrErr\n\n\t// This stores data that will end up being returned by \"WatchData()\"\n\twatchData map[string]privateWatchData\n\n\t// When building with WebAssembly, the Go compiler doesn't correctly handle\n\t// platform-specific path behavior. Hack around these bugs by compiling\n\t// support for both Unix and Windows paths into all executables and switch\n\t// between them at run-time instead.\n\tfp goFilepath\n\n\tentriesMutex sync.Mutex\n\twatchMutex   sync.Mutex\n\n\t// If true, do not use the \"entries\" cache\n\tdoNotCacheEntries bool\n}\n\ntype entriesOrErr struct {\n\tcanonicalError error\n\toriginalError  error\n\tentries        DirEntries\n}\n\ntype watchState uint8\n\nconst (\n\tstateNone                  watchState = iota\n\tstateDirHasAccessedEntries            // Compare \"accessedEntries\"\n\tstateDirUnreadable                    // Compare directory readability\n\tstateFileHasModKey                    // Compare \"modKey\"\n\tstateFileNeedModKey                   // Need to transition to \"stateFileHasModKey\" or \"stateFileUnusableModKey\" before \"WatchData()\" returns\n\tstateFileMissing                      // Compare file presence\n\tstateFileUnusableModKey               // Compare \"fileContents\"\n)\n\ntype privateWatchData struct {\n\taccessedEntries *accessedEntries\n\tfileContents    string\n\tmodKey          ModKey\n\tstate           watchState\n}\n\ntype RealFSOptions struct {\n\tAbsWorkingDir string\n\tWantWatchData bool\n\tDoNotCache    bool\n}\n\nfunc RealFS(options RealFSOptions) (FS, error) {\n\tvar fp goFilepath\n\tif CheckIfWindows() {\n\t\tfp.isWindows = true\n\t\tfp.pathSeparator = '\\\\'\n\t} else {\n\t\tfp.isWindows = false\n\t\tfp.pathSeparator = '/'\n\t}\n\n\t// Come up with a default working directory if one was not specified\n\tfp.cwd = options.AbsWorkingDir\n\tif fp.cwd == \"\" {\n\t\tif cwd, err := os.Getwd(); err == nil {\n\t\t\tfp.cwd = cwd\n\t\t} else if fp.isWindows {\n\t\t\tfp.cwd = \"C:\\\\\"\n\t\t} else {\n\t\t\tfp.cwd = \"/\"\n\t\t}\n\t} else if !fp.isAbs(fp.cwd) {\n\t\treturn nil, fmt.Errorf(\"The working directory %q is not an absolute path\", fp.cwd)\n\t}\n\n\t// Resolve symlinks in the current working directory. Symlinks are resolved\n\t// when input file paths are converted to absolute paths because we need to\n\t// recognize an input file as unique even if it has multiple symlinks\n\t// pointing to it. The build will generate relative paths from the current\n\t// working directory to the absolute input file paths for error messages,\n\t// so the current working directory should be processed the same way. Not\n\t// doing this causes test failures with esbuild when run from inside a\n\t// symlinked directory.\n\t//\n\t// This deliberately ignores errors due to e.g. infinite loops. If there is\n\t// an error, we will just use the original working directory and likely\n\t// encounter an error later anyway. And if we don't encounter an error\n\t// later, then the current working directory didn't even matter and the\n\t// error is unimportant.\n\tif path, err := fp.evalSymlinks(fp.cwd); err == nil {\n\t\tfp.cwd = path\n\t}\n\n\t// Only allocate memory for watch data if necessary\n\tvar watchData map[string]privateWatchData\n\tif options.WantWatchData {\n\t\twatchData = make(map[string]privateWatchData)\n\t}\n\n\tvar result FS = &realFS{\n\t\tentries:           make(map[string]entriesOrErr),\n\t\tfp:                fp,\n\t\twatchData:         watchData,\n\t\tdoNotCacheEntries: options.DoNotCache,\n\t}\n\n\t// Add a wrapper that lets us traverse into \".zip\" files. This is what yarn\n\t// uses as a package format when in yarn is in its \"PnP\" mode.\n\tresult = &zipFS{\n\t\tinner:    result,\n\t\tzipFiles: make(map[string]*zipFile),\n\t}\n\n\treturn result, nil\n}\n\nfunc (fs *realFS) ReadDirectory(dir string) (entries DirEntries, canonicalError error, originalError error) {\n\tif !fs.doNotCacheEntries {\n\t\t// First, check the cache\n\t\tcached, ok := func() (cached entriesOrErr, ok bool) {\n\t\t\tfs.entriesMutex.Lock()\n\t\t\tdefer fs.entriesMutex.Unlock()\n\t\t\tcached, ok = fs.entries[dir]\n\t\t\treturn\n\t\t}()\n\t\tif ok {\n\t\t\t// Cache hit: stop now\n\t\t\treturn cached.entries, cached.canonicalError, cached.originalError\n\t\t}\n\t}\n\n\t// Cache miss: read the directory entries\n\tnames, canonicalError, originalError := fs.readdir(dir)\n\tentries = DirEntries{dir: dir, data: make(map[string]*Entry)}\n\n\t// Unwrap to get the underlying error\n\tif pathErr, ok := canonicalError.(*os.PathError); ok {\n\t\tcanonicalError = pathErr.Unwrap()\n\t}\n\n\tif canonicalError == nil {\n\t\tfor _, name := range names {\n\t\t\t// Call \"stat\" lazily for performance. The \"@material-ui/icons\" package\n\t\t\t// contains a directory with over 11,000 entries in it and running \"stat\"\n\t\t\t// for each entry was a big performance issue for that package.\n\t\t\tentries.data[strings.ToLower(name)] = &Entry{\n\t\t\t\tdir:      dir,\n\t\t\t\tbase:     name,\n\t\t\t\tneedStat: true,\n\t\t\t}\n\t\t}\n\t}\n\n\t// Store data for watch mode\n\tif fs.watchData != nil {\n\t\tdefer fs.watchMutex.Unlock()\n\t\tfs.watchMutex.Lock()\n\t\tstate := stateDirHasAccessedEntries\n\t\tif canonicalError != nil {\n\t\t\tstate = stateDirUnreadable\n\t\t}\n\t\tentries.accessedEntries = &accessedEntries{wasPresent: make(map[string]bool)}\n\t\tfs.watchData[dir] = privateWatchData{\n\t\t\taccessedEntries: entries.accessedEntries,\n\t\t\tstate:           state,\n\t\t}\n\t}\n\n\t// Update the cache unconditionally. Even if the read failed, we don't want to\n\t// retry again later. The directory is inaccessible so trying again is wasted.\n\tif canonicalError != nil {\n\t\tentries.data = nil\n\t}\n\tif !fs.doNotCacheEntries {\n\t\tfs.entriesMutex.Lock()\n\t\tdefer fs.entriesMutex.Unlock()\n\t\tfs.entries[dir] = entriesOrErr{\n\t\t\tentries:        entries,\n\t\t\tcanonicalError: canonicalError,\n\t\t\toriginalError:  originalError,\n\t\t}\n\t}\n\treturn entries, canonicalError, originalError\n}\n\nfunc (fs *realFS) ReadFile(path string) (contents string, canonicalError error, originalError error) {\n\tBeforeFileOpen()\n\tdefer AfterFileClose()\n\tbuffer, originalError := ioutil.ReadFile(path)\n\tcanonicalError = fs.canonicalizeError(originalError)\n\n\t// Allocate the string once\n\tfileContents := string(buffer)\n\n\t// Store data for watch mode\n\tif fs.watchData != nil {\n\t\tdefer fs.watchMutex.Unlock()\n\t\tfs.watchMutex.Lock()\n\t\tdata, ok := fs.watchData[path]\n\t\tif canonicalError != nil {\n\t\t\tdata.state = stateFileMissing\n\t\t} else if !ok || data.state == stateDirUnreadable {\n\t\t\t// Note: If \"ReadDirectory\" is called before \"ReadFile\" with this same\n\t\t\t// path, then \"data.state\" will be \"stateDirUnreadable\". In that case\n\t\t\t// we want to transition to \"stateFileNeedModKey\" because it's a file.\n\t\t\tdata.state = stateFileNeedModKey\n\t\t}\n\t\tdata.fileContents = fileContents\n\t\tfs.watchData[path] = data\n\t}\n\n\treturn fileContents, canonicalError, originalError\n}\n\ntype realOpenedFile struct {\n\thandle *os.File\n\tlen    int\n}\n\nfunc (f *realOpenedFile) Len() int {\n\treturn f.len\n}\n\nfunc (f *realOpenedFile) Read(start int, end int) ([]byte, error) {\n\tbytes := make([]byte, end-start)\n\tremaining := bytes\n\n\t_, err := f.handle.Seek(int64(start), io.SeekStart)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor len(remaining) > 0 {\n\t\tn, err := f.handle.Read(remaining)\n\t\tif err != nil && n <= 0 {\n\t\t\treturn nil, err\n\t\t}\n\t\tremaining = remaining[n:]\n\t}\n\n\treturn bytes, nil\n}\n\nfunc (f *realOpenedFile) Close() error {\n\treturn f.handle.Close()\n}\n\nfunc (fs *realFS) OpenFile(path string) (OpenedFile, error, error) {\n\tBeforeFileOpen()\n\tdefer AfterFileClose()\n\n\tf, err := os.Open(path)\n\tif err != nil {\n\t\treturn nil, fs.canonicalizeError(err), err\n\t}\n\n\tinfo, err := f.Stat()\n\tif err != nil {\n\t\tf.Close()\n\t\treturn nil, fs.canonicalizeError(err), err\n\t}\n\n\treturn &realOpenedFile{f, int(info.Size())}, nil, nil\n}\n\nfunc (fs *realFS) ModKey(path string) (ModKey, error) {\n\tBeforeFileOpen()\n\tdefer AfterFileClose()\n\tkey, err := modKey(path)\n\n\t// Store data for watch mode\n\tif fs.watchData != nil {\n\t\tdefer fs.watchMutex.Unlock()\n\t\tfs.watchMutex.Lock()\n\t\tdata, ok := fs.watchData[path]\n\t\tif !ok {\n\t\t\tif err == modKeyUnusable {\n\t\t\t\tdata.state = stateFileUnusableModKey\n\t\t\t} else if err != nil {\n\t\t\t\tdata.state = stateFileMissing\n\t\t\t} else {\n\t\t\t\tdata.state = stateFileHasModKey\n\t\t\t}\n\t\t} else if data.state == stateFileNeedModKey {\n\t\t\tdata.state = stateFileHasModKey\n\t\t}\n\t\tdata.modKey = key\n\t\tfs.watchData[path] = data\n\t}\n\n\treturn key, err\n}\n\nfunc (fs *realFS) IsAbs(p string) bool {\n\treturn fs.fp.isAbs(p)\n}\n\nfunc (fs *realFS) Abs(p string) (string, bool) {\n\tabs, err := fs.fp.abs(p)\n\treturn abs, err == nil\n}\n\nfunc (fs *realFS) Dir(p string) string {\n\treturn fs.fp.dir(p)\n}\n\nfunc (fs *realFS) Base(p string) string {\n\treturn fs.fp.base(p)\n}\n\nfunc (fs *realFS) Ext(p string) string {\n\treturn fs.fp.ext(p)\n}\n\nfunc (fs *realFS) Join(parts ...string) string {\n\treturn fs.fp.clean(fs.fp.join(parts))\n}\n\nfunc (fs *realFS) Cwd() string {\n\treturn fs.fp.cwd\n}\n\nfunc (fs *realFS) Rel(base string, target string) (string, bool) {\n\tif rel, err := fs.fp.rel(base, target); err == nil {\n\t\treturn rel, true\n\t}\n\treturn \"\", false\n}\n\nfunc (fs *realFS) EvalSymlinks(path string) (string, bool) {\n\tif path, err := fs.fp.evalSymlinks(path); err == nil {\n\t\treturn path, true\n\t}\n\treturn \"\", false\n}\n\nfunc (fs *realFS) readdir(dirname string) (entries []string, canonicalError error, originalError error) {\n\tBeforeFileOpen()\n\tdefer AfterFileClose()\n\tf, originalError := os.Open(dirname)\n\tcanonicalError = fs.canonicalizeError(originalError)\n\n\t// Stop now if there was an error\n\tif canonicalError != nil {\n\t\treturn nil, canonicalError, originalError\n\t}\n\n\tdefer f.Close()\n\tentries, originalError = f.Readdirnames(-1)\n\tcanonicalError = originalError\n\n\t// Unwrap to get the underlying error\n\tif syscallErr, ok := canonicalError.(*os.SyscallError); ok {\n\t\tcanonicalError = syscallErr.Unwrap()\n\t}\n\n\t// Don't convert ENOTDIR to ENOENT here. ENOTDIR is a legitimate error\n\t// condition for Readdirnames() on non-Windows platforms.\n\n\t// Go's WebAssembly implementation returns EINVAL instead of ENOTDIR if we\n\t// call \"readdir\" on a file. Canonicalize this to ENOTDIR so esbuild's path\n\t// resolution code continues traversing instead of failing with an error.\n\t// https://github.com/golang/go/blob/2449bbb5e614954ce9e99c8a481ea2ee73d72d61/src/syscall/fs_js.go#L144\n\tif pathErr, ok := canonicalError.(*os.PathError); ok && pathErr.Unwrap() == syscall.EINVAL {\n\t\tcanonicalError = syscall.ENOTDIR\n\t}\n\n\treturn entries, canonicalError, originalError\n}\n\nfunc (fs *realFS) canonicalizeError(err error) error {\n\t// Unwrap to get the underlying error\n\tif pathErr, ok := err.(*os.PathError); ok {\n\t\terr = pathErr.Unwrap()\n\t}\n\n\t// Windows is much more restrictive than Unix about file names. If a file name\n\t// is invalid, it will return ERROR_INVALID_NAME. Treat this as ENOENT (i.e.\n\t// \"the file does not exist\") so that the resolver continues trying to resolve\n\t// the path on this failure instead of aborting with an error.\n\tif fs.fp.isWindows && is_ERROR_INVALID_NAME(err) {\n\t\terr = syscall.ENOENT\n\t}\n\n\t// Windows returns ENOTDIR here even though nothing we've done yet has asked\n\t// for a directory. This really means ENOENT on Windows. Return ENOENT here\n\t// so callers that check for ENOENT will successfully detect this file as\n\t// missing.\n\tif err == syscall.ENOTDIR {\n\t\terr = syscall.ENOENT\n\t}\n\n\treturn err\n}\n\nfunc (fs *realFS) kind(dir string, base string) (symlink string, kind EntryKind) {\n\tentryPath := fs.fp.join([]string{dir, base})\n\n\t// Use \"lstat\" since we want information about symbolic links\n\tBeforeFileOpen()\n\tdefer AfterFileClose()\n\tstat, err := os.Lstat(entryPath)\n\tif err != nil {\n\t\treturn\n\t}\n\tmode := stat.Mode()\n\n\t// Follow symlinks now so the cache contains the translation\n\tif (mode & os.ModeSymlink) != 0 {\n\t\tlink, err := fs.fp.evalSymlinks(entryPath)\n\t\tif err != nil {\n\t\t\treturn // Skip over this entry\n\t\t}\n\n\t\t// Re-run \"lstat\" on the symlink target to see if it's a file or not\n\t\tstat2, err2 := os.Lstat(link)\n\t\tif err2 != nil {\n\t\t\treturn // Skip over this entry\n\t\t}\n\t\tmode = stat2.Mode()\n\t\tif (mode & os.ModeSymlink) != 0 {\n\t\t\treturn // This should no longer be a symlink, so this is unexpected\n\t\t}\n\t\tsymlink = link\n\t}\n\n\t// We consider the entry either a directory or a file\n\tif (mode & os.ModeDir) != 0 {\n\t\tkind = DirEntry\n\t} else {\n\t\tkind = FileEntry\n\t}\n\treturn\n}\n\nfunc (fs *realFS) WatchData() WatchData {\n\tpaths := make(map[string]func() string)\n\n\tfor path, data := range fs.watchData {\n\t\t// Each closure below needs its own copy of these loop variables\n\t\tpath := path\n\t\tdata := data\n\n\t\t// Each function should return true if the state has been changed\n\t\tif data.state == stateFileNeedModKey {\n\t\t\tkey, err := modKey(path)\n\t\t\tif err == modKeyUnusable {\n\t\t\t\tdata.state = stateFileUnusableModKey\n\t\t\t} else if err != nil {\n\t\t\t\tdata.state = stateFileMissing\n\t\t\t} else {\n\t\t\t\tdata.state = stateFileHasModKey\n\t\t\t\tdata.modKey = key\n\t\t\t}\n\t\t}\n\n\t\tswitch data.state {\n\t\tcase stateDirUnreadable:\n\t\t\tpaths[path] = func() string {\n\t\t\t\t_, err, _ := fs.readdir(path)\n\t\t\t\tif err == nil {\n\t\t\t\t\treturn path\n\t\t\t\t}\n\t\t\t\treturn \"\"\n\t\t\t}\n\n\t\tcase stateDirHasAccessedEntries:\n\t\t\tpaths[path] = func() string {\n\t\t\t\tnames, err, _ := fs.readdir(path)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn path\n\t\t\t\t}\n\t\t\t\tdata.accessedEntries.mutex.Lock()\n\t\t\t\tdefer data.accessedEntries.mutex.Unlock()\n\t\t\t\tif allEntries := data.accessedEntries.allEntries; allEntries != nil {\n\t\t\t\t\t// Check all entries\n\t\t\t\t\tif len(names) != len(allEntries) {\n\t\t\t\t\t\treturn path\n\t\t\t\t\t}\n\t\t\t\t\tsort.Strings(names)\n\t\t\t\t\tfor i, s := range names {\n\t\t\t\t\t\tif s != allEntries[i] {\n\t\t\t\t\t\t\treturn path\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Check individual entries\n\t\t\t\t\tlookup := make(map[string]string, len(names))\n\t\t\t\t\tfor _, name := range names {\n\t\t\t\t\t\tlookup[strings.ToLower(name)] = name\n\t\t\t\t\t}\n\t\t\t\t\tfor name, wasPresent := range data.accessedEntries.wasPresent {\n\t\t\t\t\t\tif originalName, isPresent := lookup[name]; wasPresent != isPresent {\n\t\t\t\t\t\t\treturn fs.Join(path, originalName)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn \"\"\n\t\t\t}\n\n\t\tcase stateFileMissing:\n\t\t\tpaths[path] = func() string {\n\t\t\t\tif info, err := os.Stat(path); err == nil && !info.IsDir() {\n\t\t\t\t\treturn path\n\t\t\t\t}\n\t\t\t\treturn \"\"\n\t\t\t}\n\n\t\tcase stateFileHasModKey:\n\t\t\tpaths[path] = func() string {\n\t\t\t\tif key, err := modKey(path); err != nil || key != data.modKey {\n\t\t\t\t\treturn path\n\t\t\t\t}\n\t\t\t\treturn \"\"\n\t\t\t}\n\n\t\tcase stateFileUnusableModKey:\n\t\t\tpaths[path] = func() string {\n\t\t\t\tif buffer, err := ioutil.ReadFile(path); err != nil || string(buffer) != data.fileContents {\n\t\t\t\t\treturn path\n\t\t\t\t}\n\t\t\t\treturn \"\"\n\t\t\t}\n\t\t}\n\t}\n\n\treturn WatchData{\n\t\tPaths: paths,\n\t}\n}\n"
  },
  {
    "path": "internal/fs/fs_zip.go",
    "content": "package fs\n\n// The Yarn package manager (https://yarnpkg.com/) has a custom installation\n// strategy called \"Plug'n'Play\" where they install packages as zip files\n// instead of directory trees, and then modify node to treat zip files like\n// directories. This reduces package installation time because Yarn now only\n// has to copy a single file per package instead of a whole directory tree.\n// However, it introduces overhead at run-time because the virtual file system\n// is written in JavaScript.\n//\n// This file contains esbuild's implementation of the behavior that treats zip\n// files like directories. It implements the \"FS\" interface and wraps an inner\n// \"FS\" interface that treats zip files like files. That way it can run both on\n// a real file system and a mock file system.\n//\n// This file also implements another Yarn-specific behavior where certain paths\n// containing the special path segments \"__virtual__\" or \"$$virtual\" have some\n// unusual behavior. See the code below for details.\n\nimport (\n\t\"archive/zip\"\n\t\"io/ioutil\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"syscall\"\n)\n\ntype zipFS struct {\n\tinner FS\n\n\tzipFilesMutex sync.Mutex\n\tzipFiles      map[string]*zipFile\n}\n\ntype zipFile struct {\n\treader *zip.ReadCloser\n\terr    error\n\n\tdirs  map[string]*compressedDir\n\tfiles map[string]*compressedFile\n\twait  sync.WaitGroup\n}\n\ntype compressedDir struct {\n\tentries map[string]EntryKind\n\tpath    string\n\n\t// Compatible entries are decoded lazily\n\tmutex      sync.Mutex\n\tdirEntries DirEntries\n}\n\ntype compressedFile struct {\n\tcompressed *zip.File\n\n\t// The file is decompressed lazily\n\tmutex    sync.Mutex\n\tcontents string\n\terr      error\n\twasRead  bool\n}\n\nfunc (fs *zipFS) checkForZip(path string, kind EntryKind) (*zipFile, string) {\n\tvar zipPath string\n\tvar pathTail string\n\n\t// Do a quick check for a \".zip\" in the path at all\n\tpath = strings.ReplaceAll(path, \"\\\\\", \"/\")\n\tif i := strings.Index(path, \".zip/\"); i != -1 {\n\t\tzipPath = path[:i+len(\".zip\")]\n\t\tpathTail = path[i+len(\".zip/\"):]\n\t} else if kind == DirEntry && strings.HasSuffix(path, \".zip\") {\n\t\tzipPath = path\n\t} else {\n\t\treturn nil, \"\"\n\t}\n\n\t// If there is one, then check whether it's a file on the file system or not\n\tfs.zipFilesMutex.Lock()\n\tarchive := fs.zipFiles[zipPath]\n\tif archive != nil {\n\t\tfs.zipFilesMutex.Unlock()\n\t\tarchive.wait.Wait()\n\t} else {\n\t\tarchive = &zipFile{}\n\t\tarchive.wait.Add(1)\n\t\tfs.zipFiles[zipPath] = archive\n\t\tfs.zipFilesMutex.Unlock()\n\t\tdefer archive.wait.Done()\n\n\t\t// Try reading the zip archive if it's not in the cache\n\t\ttryToReadZipArchive(zipPath, archive)\n\t}\n\n\tif archive.err != nil {\n\t\treturn nil, \"\"\n\t}\n\treturn archive, pathTail\n}\n\nfunc tryToReadZipArchive(zipPath string, archive *zipFile) {\n\treader, err := zip.OpenReader(zipPath)\n\tif err != nil {\n\t\tarchive.err = err\n\t\treturn\n\t}\n\n\tdirs := make(map[string]*compressedDir)\n\tfiles := make(map[string]*compressedFile)\n\tseeds := []string{}\n\n\t// Build an index of all files in the archive\n\tfor _, file := range reader.File {\n\t\tbaseName := strings.TrimSuffix(file.Name, \"/\")\n\t\tdirPath := \"\"\n\t\tif slash := strings.LastIndexByte(baseName, '/'); slash != -1 {\n\t\t\tdirPath = baseName[:slash]\n\t\t\tbaseName = baseName[slash+1:]\n\t\t}\n\t\tif file.FileInfo().IsDir() {\n\t\t\t// Handle a directory\n\t\t\tlowerDir := strings.ToLower(dirPath)\n\t\t\tif _, ok := dirs[lowerDir]; !ok {\n\t\t\t\tdir := &compressedDir{\n\t\t\t\t\tpath:    dirPath,\n\t\t\t\t\tentries: make(map[string]EntryKind),\n\t\t\t\t}\n\n\t\t\t\t// List the same directory both with and without the slash\n\t\t\t\tdirs[lowerDir] = dir\n\t\t\t\tdirs[lowerDir+\"/\"] = dir\n\t\t\t\tseeds = append(seeds, lowerDir)\n\t\t\t}\n\t\t} else {\n\t\t\t// Handle a file\n\t\t\tfiles[strings.ToLower(file.Name)] = &compressedFile{compressed: file}\n\t\t\tlowerDir := strings.ToLower(dirPath)\n\t\t\tdir, ok := dirs[lowerDir]\n\t\t\tif !ok {\n\t\t\t\tdir = &compressedDir{\n\t\t\t\t\tpath:    dirPath,\n\t\t\t\t\tentries: make(map[string]EntryKind),\n\t\t\t\t}\n\n\t\t\t\t// List the same directory both with and without the slash\n\t\t\t\tdirs[lowerDir] = dir\n\t\t\t\tdirs[lowerDir+\"/\"] = dir\n\t\t\t\tseeds = append(seeds, lowerDir)\n\t\t\t}\n\t\t\tdir.entries[baseName] = FileEntry\n\t\t}\n\t}\n\n\t// Populate child directories\n\tfor _, baseName := range seeds {\n\t\tfor baseName != \"\" {\n\t\t\tdirPath := \"\"\n\t\t\tif slash := strings.LastIndexByte(baseName, '/'); slash != -1 {\n\t\t\t\tdirPath = baseName[:slash]\n\t\t\t\tbaseName = baseName[slash+1:]\n\t\t\t}\n\t\t\tlowerDir := strings.ToLower(dirPath)\n\t\t\tdir, ok := dirs[lowerDir]\n\t\t\tif !ok {\n\t\t\t\tdir = &compressedDir{\n\t\t\t\t\tpath:    dirPath,\n\t\t\t\t\tentries: make(map[string]EntryKind),\n\t\t\t\t}\n\n\t\t\t\t// List the same directory both with and without the slash\n\t\t\t\tdirs[lowerDir] = dir\n\t\t\t\tdirs[lowerDir+\"/\"] = dir\n\t\t\t}\n\t\t\tdir.entries[baseName] = DirEntry\n\t\t\tbaseName = dirPath\n\t\t}\n\t}\n\n\tarchive.dirs = dirs\n\tarchive.files = files\n\tarchive.reader = reader\n}\n\nfunc (fs *zipFS) ReadDirectory(path string) (entries DirEntries, canonicalError error, originalError error) {\n\tpath = mangleYarnPnPVirtualPath(path)\n\n\tentries, canonicalError, originalError = fs.inner.ReadDirectory(path)\n\n\t// Only continue if reading this path as a directory caused an error that's\n\t// consistent with trying to read a zip file as a directory. Note that EINVAL\n\t// is produced by the file system in Go's WebAssembly implementation.\n\tif canonicalError != syscall.ENOENT && canonicalError != syscall.ENOTDIR && canonicalError != syscall.EINVAL {\n\t\treturn\n\t}\n\n\t// If the directory doesn't exist, try reading from an enclosing zip archive\n\tzip, pathTail := fs.checkForZip(path, DirEntry)\n\tif zip == nil {\n\t\treturn\n\t}\n\n\t// Does the zip archive have this directory?\n\tdir, ok := zip.dirs[strings.ToLower(pathTail)]\n\tif !ok {\n\t\treturn DirEntries{}, syscall.ENOENT, syscall.ENOENT\n\t}\n\n\t// Check whether it has already been converted\n\tdir.mutex.Lock()\n\tdefer dir.mutex.Unlock()\n\tif dir.dirEntries.data != nil {\n\t\treturn dir.dirEntries, nil, nil\n\t}\n\n\t// Otherwise, fill in the entries\n\tdir.dirEntries = DirEntries{dir: path, data: make(map[string]*Entry, len(dir.entries))}\n\tfor name, kind := range dir.entries {\n\t\tdir.dirEntries.data[strings.ToLower(name)] = &Entry{\n\t\t\tdir:  path,\n\t\t\tbase: name,\n\t\t\tkind: kind,\n\t\t}\n\t}\n\n\treturn dir.dirEntries, nil, nil\n}\n\nfunc (fs *zipFS) ReadFile(path string) (contents string, canonicalError error, originalError error) {\n\tpath = mangleYarnPnPVirtualPath(path)\n\n\tcontents, canonicalError, originalError = fs.inner.ReadFile(path)\n\tif canonicalError != syscall.ENOENT {\n\t\treturn\n\t}\n\n\t// If the file doesn't exist, try reading from an enclosing zip archive\n\tzip, pathTail := fs.checkForZip(path, FileEntry)\n\tif zip == nil {\n\t\treturn\n\t}\n\n\t// Does the zip archive have this file?\n\tfile, ok := zip.files[strings.ToLower(pathTail)]\n\tif !ok {\n\t\treturn \"\", syscall.ENOENT, syscall.ENOENT\n\t}\n\n\t// Check whether it has already been read\n\tfile.mutex.Lock()\n\tdefer file.mutex.Unlock()\n\tif file.wasRead {\n\t\treturn file.contents, file.err, file.err\n\t}\n\tfile.wasRead = true\n\n\t// If not, try to open it\n\treader, err := file.compressed.Open()\n\tif err != nil {\n\t\tfile.err = err\n\t\treturn \"\", err, err\n\t}\n\tdefer reader.Close()\n\n\t// Then try to read it\n\tbytes, err := ioutil.ReadAll(reader)\n\tif err != nil {\n\t\tfile.err = err\n\t\treturn \"\", err, err\n\t}\n\n\tfile.contents = string(bytes)\n\treturn file.contents, nil, nil\n}\n\nfunc (fs *zipFS) OpenFile(path string) (result OpenedFile, canonicalError error, originalError error) {\n\tpath = mangleYarnPnPVirtualPath(path)\n\n\tresult, canonicalError, originalError = fs.inner.OpenFile(path)\n\treturn\n}\n\nfunc (fs *zipFS) ModKey(path string) (modKey ModKey, err error) {\n\tpath = mangleYarnPnPVirtualPath(path)\n\n\tmodKey, err = fs.inner.ModKey(path)\n\treturn\n}\n\nfunc (fs *zipFS) IsAbs(path string) bool {\n\treturn fs.inner.IsAbs(path)\n}\n\nfunc (fs *zipFS) Abs(path string) (string, bool) {\n\treturn fs.inner.Abs(path)\n}\n\nfunc (fs *zipFS) Dir(path string) string {\n\tif prefix, suffix, ok := ParseYarnPnPVirtualPath(path); ok && suffix == \"\" {\n\t\treturn prefix\n\t}\n\treturn fs.inner.Dir(path)\n}\n\nfunc (fs *zipFS) Base(path string) string {\n\treturn fs.inner.Base(path)\n}\n\nfunc (fs *zipFS) Ext(path string) string {\n\treturn fs.inner.Ext(path)\n}\n\nfunc (fs *zipFS) Join(parts ...string) string {\n\treturn fs.inner.Join(parts...)\n}\n\nfunc (fs *zipFS) Cwd() string {\n\treturn fs.inner.Cwd()\n}\n\nfunc (fs *zipFS) Rel(base string, target string) (string, bool) {\n\treturn fs.inner.Rel(base, target)\n}\n\nfunc (fs *zipFS) EvalSymlinks(path string) (string, bool) {\n\treturn fs.inner.EvalSymlinks(path)\n}\n\nfunc (fs *zipFS) kind(dir string, base string) (symlink string, kind EntryKind) {\n\treturn fs.inner.kind(dir, base)\n}\n\nfunc (fs *zipFS) WatchData() WatchData {\n\treturn fs.inner.WatchData()\n}\n\nfunc ParseYarnPnPVirtualPath(path string) (string, string, bool) {\n\ti := 0\n\n\tfor {\n\t\tstart := i\n\t\tslash := strings.IndexAny(path[i:], \"/\\\\\")\n\t\tif slash == -1 {\n\t\t\tbreak\n\t\t}\n\t\ti += slash + 1\n\n\t\t// Replace the segments \"__virtual__/<segment>/<n>\" with N times the \"..\"\n\t\t// operation. Note: The \"__virtual__\" folder name appeared with Yarn 3.0.\n\t\t// Earlier releases used \"$$virtual\", but it was changed after discovering\n\t\t// that this pattern triggered bugs in software where paths were used as\n\t\t// either regexps or replacement. For example, \"$$\" found in the second\n\t\t// parameter of \"String.prototype.replace\" silently turned into \"$\".\n\t\tif segment := path[start : i-1]; segment == \"__virtual__\" || segment == \"$$virtual\" {\n\t\t\tif slash := strings.IndexAny(path[i:], \"/\\\\\"); slash != -1 {\n\t\t\t\tvar count string\n\t\t\t\tvar suffix string\n\t\t\t\tj := i + slash + 1\n\n\t\t\t\t// Find the range of the count\n\t\t\t\tif slash := strings.IndexAny(path[j:], \"/\\\\\"); slash != -1 {\n\t\t\t\t\tcount = path[j : j+slash]\n\t\t\t\t\tsuffix = path[j+slash:]\n\t\t\t\t} else {\n\t\t\t\t\tcount = path[j:]\n\t\t\t\t}\n\n\t\t\t\t// Parse the count\n\t\t\t\tif n, err := strconv.ParseInt(count, 10, 64); err == nil {\n\t\t\t\t\tprefix := path[:start]\n\n\t\t\t\t\t// Apply N times the \"..\" operator\n\t\t\t\t\tfor n > 0 && (strings.HasSuffix(prefix, \"/\") || strings.HasSuffix(prefix, \"\\\\\")) {\n\t\t\t\t\t\tslash := strings.LastIndexAny(prefix[:len(prefix)-1], \"/\\\\\")\n\t\t\t\t\t\tif slash == -1 {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tprefix = prefix[:slash+1]\n\t\t\t\t\t\tn--\n\t\t\t\t\t}\n\n\t\t\t\t\t// Make sure the prefix and suffix work well when joined together\n\t\t\t\t\tif suffix == \"\" && strings.IndexAny(prefix, \"/\\\\\") != strings.LastIndexAny(prefix, \"/\\\\\") {\n\t\t\t\t\t\tprefix = prefix[:len(prefix)-1]\n\t\t\t\t\t} else if prefix == \"\" {\n\t\t\t\t\t\tprefix = \".\"\n\t\t\t\t\t} else if strings.HasPrefix(suffix, \"/\") || strings.HasPrefix(suffix, \"\\\\\") {\n\t\t\t\t\t\tsuffix = suffix[1:]\n\t\t\t\t\t}\n\n\t\t\t\t\treturn prefix, suffix, true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn \"\", \"\", false\n}\n\nfunc mangleYarnPnPVirtualPath(path string) string {\n\tif prefix, suffix, ok := ParseYarnPnPVirtualPath(path); ok {\n\t\treturn prefix + suffix\n\t}\n\treturn path\n}\n"
  },
  {
    "path": "internal/fs/iswin_other.go",
    "content": "//go:build (!js || !wasm) && !windows\n// +build !js !wasm\n// +build !windows\n\npackage fs\n\nfunc CheckIfWindows() bool {\n\treturn false\n}\n"
  },
  {
    "path": "internal/fs/iswin_wasm.go",
    "content": "//go:build js && wasm\n// +build js,wasm\n\npackage fs\n\nimport (\n\t\"os\"\n)\n\nvar checkedIfWindows bool\nvar cachedIfWindows bool\n\nfunc CheckIfWindows() bool {\n\tif !checkedIfWindows {\n\t\tcheckedIfWindows = true\n\n\t\t// Hack: Assume that we're on Windows if we're running WebAssembly and\n\t\t// the \"C:\\\\\" directory exists. This is a workaround for a bug in Go's\n\t\t// WebAssembly support: https://github.com/golang/go/issues/43768.\n\t\t_, err := os.Stat(\"C:\\\\\")\n\t\tcachedIfWindows = err == nil\n\t}\n\n\treturn cachedIfWindows\n}\n"
  },
  {
    "path": "internal/fs/iswin_windows.go",
    "content": "//go:build windows\n// +build windows\n\npackage fs\n\nfunc CheckIfWindows() bool {\n\treturn true\n}\n"
  },
  {
    "path": "internal/fs/modkey_other.go",
    "content": "//go:build !darwin && !freebsd && !linux\n// +build !darwin,!freebsd,!linux\n\npackage fs\n\nimport (\n\t\"os\"\n\t\"time\"\n)\n\nvar zeroTime time.Time\n\nfunc modKey(path string) (ModKey, error) {\n\tinfo, err := os.Stat(path)\n\tif err != nil {\n\t\treturn ModKey{}, err\n\t}\n\n\t// We can't detect changes if the file system zeros out the modification time\n\tmtime := info.ModTime()\n\tif mtime == zeroTime || mtime.Unix() == 0 {\n\t\treturn ModKey{}, modKeyUnusable\n\t}\n\n\t// Don't generate a modification key if the file is too new\n\tif mtime.Add(modKeySafetyGap * time.Second).After(time.Now()) {\n\t\treturn ModKey{}, modKeyUnusable\n\t}\n\n\treturn ModKey{\n\t\tsize:      info.Size(),\n\t\tmtime_sec: mtime.Unix(),\n\t\tmode:      uint32(info.Mode()),\n\t}, nil\n}\n"
  },
  {
    "path": "internal/fs/modkey_unix.go",
    "content": "//go:build darwin || freebsd || linux\n// +build darwin freebsd linux\n\npackage fs\n\nimport (\n\t\"time\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc modKey(path string) (ModKey, error) {\n\tstat := unix.Stat_t{}\n\tif err := unix.Stat(path, &stat); err != nil {\n\t\treturn ModKey{}, err\n\t}\n\n\t// We can't detect changes if the file system zeros out the modification time\n\tif stat.Mtim.Sec == 0 && stat.Mtim.Nsec == 0 {\n\t\treturn ModKey{}, modKeyUnusable\n\t}\n\n\t// Don't generate a modification key if the file is too new\n\tnow, err := unix.TimeToTimespec(time.Now())\n\tif err != nil {\n\t\treturn ModKey{}, err\n\t}\n\tmtimeSec := stat.Mtim.Sec + modKeySafetyGap\n\tif mtimeSec > now.Sec || (mtimeSec == now.Sec && stat.Mtim.Nsec > now.Nsec) {\n\t\treturn ModKey{}, modKeyUnusable\n\t}\n\n\treturn ModKey{\n\t\tinode:      stat.Ino,\n\t\tsize:       stat.Size,\n\t\tmtime_sec:  int64(stat.Mtim.Sec),\n\t\tmtime_nsec: int64(stat.Mtim.Nsec),\n\t\tmode:       uint32(stat.Mode),\n\t\tuid:        stat.Uid,\n\t}, nil\n}\n"
  },
  {
    "path": "internal/graph/graph.go",
    "content": "package graph\n\n// This graph represents the set of files that the linker operates on. Each\n// linker has a separate one of these graphs (there is one linker when code\n// splitting is on, but one linker per entry point when code splitting is off).\n//\n// The input data to the linker constructor must be considered immutable because\n// it's shared between linker invocations and is also stored in the cache for\n// incremental builds.\n//\n// The linker constructor makes a shallow clone of the input data and is careful\n// to pre-clone ahead of time the AST fields that it may modify. The Go language\n// doesn't have any type system features for immutability so this has to be\n// manually enforced. Please be careful.\n\nimport (\n\t\"sort\"\n\t\"sync\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/runtime\"\n)\n\ntype entryPointKind uint8\n\nconst (\n\tentryPointNone entryPointKind = iota\n\tentryPointUserSpecified\n\tentryPointDynamicImport\n)\n\ntype LinkerFile struct {\n\t// This holds all entry points that can reach this file. It will be used to\n\t// assign the parts in this file to a chunk.\n\tEntryBits helpers.BitSet\n\n\t// This is lazily-allocated because it's only needed if there are warnings\n\t// logged, which should be relatively rare.\n\tlazyLineColumnTracker *logger.LineColumnTracker\n\n\tInputFile InputFile\n\n\t// The minimum number of links in the module graph to get from an entry point\n\t// to this file\n\tDistanceFromEntryPoint uint32\n\n\t// If \"entryPointKind\" is not \"entryPointNone\", this is the index of the\n\t// corresponding entry point chunk.\n\tEntryPointChunkIndex uint32\n\n\t// This file is an entry point if and only if this is not \"entryPointNone\".\n\t// Note that dynamically-imported files are allowed to also be specified by\n\t// the user as top-level entry points, so some dynamically-imported files\n\t// may be \"entryPointUserSpecified\" instead of \"entryPointDynamicImport\".\n\tentryPointKind entryPointKind\n\n\t// This is true if this file has been marked as live by the tree shaking\n\t// algorithm.\n\tIsLive bool\n}\n\nfunc (f *LinkerFile) IsEntryPoint() bool {\n\treturn f.entryPointKind != entryPointNone\n}\n\nfunc (f *LinkerFile) IsUserSpecifiedEntryPoint() bool {\n\treturn f.entryPointKind == entryPointUserSpecified\n}\n\n// Note: This is not guarded by a mutex. Make sure this isn't called from a\n// parallel part of the code.\nfunc (f *LinkerFile) LineColumnTracker() *logger.LineColumnTracker {\n\tif f.lazyLineColumnTracker == nil {\n\t\ttracker := logger.MakeLineColumnTracker(&f.InputFile.Source)\n\t\tf.lazyLineColumnTracker = &tracker\n\t}\n\treturn f.lazyLineColumnTracker\n}\n\ntype EntryPoint struct {\n\t// This may be an absolute path or a relative path. If absolute, it will\n\t// eventually be turned into a relative path by computing the path relative\n\t// to the \"outbase\" directory. Then this relative path will be joined onto\n\t// the \"outdir\" directory to form the final output path for this entry point.\n\tOutputPath string\n\n\t// This is the source index of the entry point. This file must have a valid\n\t// entry point kind (i.e. not \"none\").\n\tSourceIndex uint32\n\n\t// Manually specified output paths are ignored when computing the default\n\t// \"outbase\" directory, which is computed as the lowest common ancestor of\n\t// all automatically generated output paths.\n\tOutputPathWasAutoGenerated bool\n}\n\ntype LinkerGraph struct {\n\tFiles       []LinkerFile\n\tentryPoints []EntryPoint\n\tSymbols     ast.SymbolMap\n\n\t// This is for cross-module inlining of TypeScript enum constants\n\tTSEnums map[ast.Ref]map[string]js_ast.TSEnumValue\n\n\t// This is for cross-module inlining of detected inlinable constants\n\tConstValues map[ast.Ref]js_ast.ConstValue\n\n\t// We should avoid traversing all files in the bundle, because the linker\n\t// should be able to run a linking operation on a large bundle where only\n\t// a few files are needed (e.g. an incremental compilation scenario). This\n\t// holds all files that could possibly be reached through the entry points.\n\t// If you need to iterate over all files in the linking operation, iterate\n\t// over this array. This array is also sorted in a deterministic ordering\n\t// to help ensure deterministic builds (source indices are random).\n\tReachableFiles []uint32\n\n\t// This maps from unstable source index to stable reachable file index. This\n\t// is useful as a deterministic key for sorting if you need to sort something\n\t// containing a source index (such as \"ast.Ref\" symbol references).\n\tStableSourceIndices []uint32\n}\n\nfunc CloneLinkerGraph(\n\tinputFiles []InputFile,\n\treachableFiles []uint32,\n\toriginalEntryPoints []EntryPoint,\n\tcodeSplitting bool,\n) LinkerGraph {\n\tentryPoints := append([]EntryPoint{}, originalEntryPoints...)\n\tsymbols := ast.NewSymbolMap(len(inputFiles))\n\tfiles := make([]LinkerFile, len(inputFiles))\n\n\t// Mark all entry points so we don't add them again for import() expressions\n\tfor _, entryPoint := range entryPoints {\n\t\tfiles[entryPoint.SourceIndex].entryPointKind = entryPointUserSpecified\n\t}\n\n\t// Clone various things since we may mutate them later. Do this in parallel\n\t// for a speedup (around ~2x faster for this function in the three.js\n\t// benchmark on a 6-core laptop).\n\tvar dynamicImportEntryPoints []uint32\n\tvar dynamicImportEntryPointsMutex sync.Mutex\n\twaitGroup := sync.WaitGroup{}\n\twaitGroup.Add(len(reachableFiles))\n\tstableSourceIndices := make([]uint32, len(inputFiles))\n\tfor stableIndex, sourceIndex := range reachableFiles {\n\t\t// Create a way to convert source indices to a stable ordering\n\t\tstableSourceIndices[sourceIndex] = uint32(stableIndex)\n\n\t\tgo func(sourceIndex uint32) {\n\t\t\tfile := &files[sourceIndex]\n\t\t\tfile.InputFile = inputFiles[sourceIndex]\n\n\t\t\tswitch repr := file.InputFile.Repr.(type) {\n\t\t\tcase *JSRepr:\n\t\t\t\t// Clone the representation\n\t\t\t\t{\n\t\t\t\t\tclone := *repr\n\t\t\t\t\trepr = &clone\n\t\t\t\t\tfile.InputFile.Repr = repr\n\t\t\t\t}\n\n\t\t\t\t// Clone the symbol map\n\t\t\t\tfileSymbols := append([]ast.Symbol{}, repr.AST.Symbols...)\n\t\t\t\tsymbols.SymbolsForSource[sourceIndex] = fileSymbols\n\t\t\t\trepr.AST.Symbols = nil\n\n\t\t\t\t// Clone the parts\n\t\t\t\trepr.AST.Parts = append([]js_ast.Part{}, repr.AST.Parts...)\n\t\t\t\tfor i := range repr.AST.Parts {\n\t\t\t\t\tpart := &repr.AST.Parts[i]\n\t\t\t\t\tclone := make(map[ast.Ref]js_ast.SymbolUse, len(part.SymbolUses))\n\t\t\t\t\tfor ref, uses := range part.SymbolUses {\n\t\t\t\t\t\tclone[ref] = uses\n\t\t\t\t\t}\n\t\t\t\t\tpart.SymbolUses = clone\n\t\t\t\t}\n\n\t\t\t\t// Clone the import records\n\t\t\t\trepr.AST.ImportRecords = append([]ast.ImportRecord{}, repr.AST.ImportRecords...)\n\n\t\t\t\t// Add dynamic imports as additional entry points if code splitting is active\n\t\t\t\tif codeSplitting {\n\t\t\t\t\tfor importRecordIndex := range repr.AST.ImportRecords {\n\t\t\t\t\t\tif record := &repr.AST.ImportRecords[importRecordIndex]; record.SourceIndex.IsValid() && record.Kind == ast.ImportDynamic {\n\t\t\t\t\t\t\tdynamicImportEntryPointsMutex.Lock()\n\t\t\t\t\t\t\tdynamicImportEntryPoints = append(dynamicImportEntryPoints, record.SourceIndex.GetIndex())\n\t\t\t\t\t\t\tdynamicImportEntryPointsMutex.Unlock()\n\n\t\t\t\t\t\t\t// Remove import assertions for dynamic imports of additional\n\t\t\t\t\t\t\t// entry points so that they don't mess with the run-time behavior.\n\t\t\t\t\t\t\t// For example, \"import('./foo.json', { assert: { type: 'json' } })\"\n\t\t\t\t\t\t\t// will likely be converted into an import of a JavaScript file and\n\t\t\t\t\t\t\t// leaving the import assertion there will prevent it from working.\n\t\t\t\t\t\t\trecord.AssertOrWith = nil\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Clone the import map\n\t\t\t\tnamedImports := make(map[ast.Ref]js_ast.NamedImport, len(repr.AST.NamedImports))\n\t\t\t\tfor k, v := range repr.AST.NamedImports {\n\t\t\t\t\tnamedImports[k] = v\n\t\t\t\t}\n\t\t\t\trepr.AST.NamedImports = namedImports\n\n\t\t\t\t// Clone the export map\n\t\t\t\tresolvedExports := make(map[string]ExportData)\n\t\t\t\tfor alias, name := range repr.AST.NamedExports {\n\t\t\t\t\tresolvedExports[alias] = ExportData{\n\t\t\t\t\t\tRef:         name.Ref,\n\t\t\t\t\t\tSourceIndex: sourceIndex,\n\t\t\t\t\t\tNameLoc:     name.AliasLoc,\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Clone the top-level scope so we can generate more variables\n\t\t\t\t{\n\t\t\t\t\tnew := &js_ast.Scope{}\n\t\t\t\t\t*new = *repr.AST.ModuleScope\n\t\t\t\t\tnew.Generated = append([]ast.Ref{}, new.Generated...)\n\t\t\t\t\trepr.AST.ModuleScope = new\n\t\t\t\t}\n\n\t\t\t\t// Also associate some default metadata with the file\n\t\t\t\trepr.Meta.ResolvedExports = resolvedExports\n\t\t\t\trepr.Meta.IsProbablyTypeScriptType = make(map[ast.Ref]bool)\n\t\t\t\trepr.Meta.ImportsToBind = make(map[ast.Ref]ImportData)\n\n\t\t\tcase *CSSRepr:\n\t\t\t\t// Clone the representation\n\t\t\t\t{\n\t\t\t\t\tclone := *repr\n\t\t\t\t\trepr = &clone\n\t\t\t\t\tfile.InputFile.Repr = repr\n\t\t\t\t}\n\n\t\t\t\t// Clone the symbol map\n\t\t\t\tfileSymbols := append([]ast.Symbol{}, repr.AST.Symbols...)\n\t\t\t\tsymbols.SymbolsForSource[sourceIndex] = fileSymbols\n\t\t\t\trepr.AST.Symbols = nil\n\n\t\t\t\t// Clone the import records\n\t\t\t\trepr.AST.ImportRecords = append([]ast.ImportRecord{}, repr.AST.ImportRecords...)\n\t\t\t}\n\n\t\t\t// All files start off as far as possible from an entry point\n\t\t\tfile.DistanceFromEntryPoint = ^uint32(0)\n\t\t\twaitGroup.Done()\n\t\t}(sourceIndex)\n\t}\n\twaitGroup.Wait()\n\n\t// Process dynamic entry points after merging control flow again\n\tstableEntryPoints := make([]int, 0, len(dynamicImportEntryPoints))\n\tfor _, sourceIndex := range dynamicImportEntryPoints {\n\t\tif otherFile := &files[sourceIndex]; otherFile.entryPointKind == entryPointNone {\n\t\t\tstableEntryPoints = append(stableEntryPoints, int(stableSourceIndices[sourceIndex]))\n\t\t\totherFile.entryPointKind = entryPointDynamicImport\n\t\t}\n\t}\n\n\t// Make sure to add dynamic entry points in a deterministic order\n\tsort.Ints(stableEntryPoints)\n\tfor _, stableIndex := range stableEntryPoints {\n\t\tentryPoints = append(entryPoints, EntryPoint{SourceIndex: reachableFiles[stableIndex]})\n\t}\n\n\t// Do a final quick pass over all files\n\tvar tsEnums map[ast.Ref]map[string]js_ast.TSEnumValue\n\tvar constValues map[ast.Ref]js_ast.ConstValue\n\tbitCount := uint(len(entryPoints))\n\tfor _, sourceIndex := range reachableFiles {\n\t\tfile := &files[sourceIndex]\n\n\t\t// Allocate the entry bit set now that the number of entry points is known\n\t\tfile.EntryBits = helpers.NewBitSet(bitCount)\n\n\t\t// Merge TypeScript enums together into one big map. There likely aren't\n\t\t// too many enum definitions relative to the overall size of the code so\n\t\t// it should be fine to just merge them together in serial.\n\t\tif repr, ok := file.InputFile.Repr.(*JSRepr); ok && repr.AST.TSEnums != nil {\n\t\t\tif tsEnums == nil {\n\t\t\t\ttsEnums = make(map[ast.Ref]map[string]js_ast.TSEnumValue)\n\t\t\t}\n\t\t\tfor ref, enum := range repr.AST.TSEnums {\n\t\t\t\ttsEnums[ref] = enum\n\t\t\t}\n\t\t}\n\n\t\t// Also merge const values into one big map as well\n\t\tif repr, ok := file.InputFile.Repr.(*JSRepr); ok && repr.AST.ConstValues != nil {\n\t\t\tif constValues == nil {\n\t\t\t\tconstValues = make(map[ast.Ref]js_ast.ConstValue)\n\t\t\t}\n\t\t\tfor ref, value := range repr.AST.ConstValues {\n\t\t\t\tconstValues[ref] = value\n\t\t\t}\n\t\t}\n\t}\n\n\treturn LinkerGraph{\n\t\tSymbols:             symbols,\n\t\tTSEnums:             tsEnums,\n\t\tConstValues:         constValues,\n\t\tentryPoints:         entryPoints,\n\t\tFiles:               files,\n\t\tReachableFiles:      reachableFiles,\n\t\tStableSourceIndices: stableSourceIndices,\n\t}\n}\n\n// Prevent packages that depend on us from adding or removing entry points\nfunc (g *LinkerGraph) EntryPoints() []EntryPoint {\n\treturn g.entryPoints\n}\n\nfunc (g *LinkerGraph) AddPartToFile(sourceIndex uint32, part js_ast.Part) uint32 {\n\t// Invariant: this map is never null\n\tif part.SymbolUses == nil {\n\t\tpart.SymbolUses = make(map[ast.Ref]js_ast.SymbolUse)\n\t}\n\n\trepr := g.Files[sourceIndex].InputFile.Repr.(*JSRepr)\n\tpartIndex := uint32(len(repr.AST.Parts))\n\trepr.AST.Parts = append(repr.AST.Parts, part)\n\n\t// Invariant: the parts for all top-level symbols can be found in the file-level map\n\tfor _, declaredSymbol := range part.DeclaredSymbols {\n\t\tif declaredSymbol.IsTopLevel {\n\t\t\t// Check for an existing overlay\n\t\t\tpartIndices, ok := repr.Meta.TopLevelSymbolToPartsOverlay[declaredSymbol.Ref]\n\n\t\t\t// If missing, initialize using the original values from the parser\n\t\t\tif !ok {\n\t\t\t\tpartIndices = append(partIndices, repr.AST.TopLevelSymbolToPartsFromParser[declaredSymbol.Ref]...)\n\t\t\t}\n\n\t\t\t// Add this part to the overlay\n\t\t\tpartIndices = append(partIndices, partIndex)\n\t\t\tif repr.Meta.TopLevelSymbolToPartsOverlay == nil {\n\t\t\t\trepr.Meta.TopLevelSymbolToPartsOverlay = make(map[ast.Ref][]uint32)\n\t\t\t}\n\t\t\trepr.Meta.TopLevelSymbolToPartsOverlay[declaredSymbol.Ref] = partIndices\n\t\t}\n\t}\n\n\treturn partIndex\n}\n\nfunc (g *LinkerGraph) GenerateNewSymbol(sourceIndex uint32, kind ast.SymbolKind, originalName string) ast.Ref {\n\tsourceSymbols := &g.Symbols.SymbolsForSource[sourceIndex]\n\n\tref := ast.Ref{\n\t\tSourceIndex: sourceIndex,\n\t\tInnerIndex:  uint32(len(*sourceSymbols)),\n\t}\n\n\t*sourceSymbols = append(*sourceSymbols, ast.Symbol{\n\t\tKind:         kind,\n\t\tOriginalName: originalName,\n\t\tLink:         ast.InvalidRef,\n\t})\n\n\tgenerated := &g.Files[sourceIndex].InputFile.Repr.(*JSRepr).AST.ModuleScope.Generated\n\t*generated = append(*generated, ref)\n\treturn ref\n}\n\nfunc (g *LinkerGraph) GenerateSymbolImportAndUse(\n\tsourceIndex uint32,\n\tpartIndex uint32,\n\tref ast.Ref,\n\tuseCount uint32,\n\tsourceIndexToImportFrom uint32,\n) {\n\tif useCount == 0 {\n\t\treturn\n\t}\n\n\trepr := g.Files[sourceIndex].InputFile.Repr.(*JSRepr)\n\tpart := &repr.AST.Parts[partIndex]\n\n\t// Mark this symbol as used by this part\n\tuse := part.SymbolUses[ref]\n\tuse.CountEstimate += useCount\n\tpart.SymbolUses[ref] = use\n\n\t// Uphold invariants about the CommonJS \"exports\" and \"module\" symbols\n\tif ref == repr.AST.ExportsRef {\n\t\trepr.AST.UsesExportsRef = true\n\t}\n\tif ref == repr.AST.ModuleRef {\n\t\trepr.AST.UsesModuleRef = true\n\t}\n\n\t// Track that this specific symbol was imported\n\tif sourceIndexToImportFrom != sourceIndex {\n\t\trepr.Meta.ImportsToBind[ref] = ImportData{\n\t\t\tSourceIndex: sourceIndexToImportFrom,\n\t\t\tRef:         ref,\n\t\t}\n\t}\n\n\t// Pull in all parts that declare this symbol\n\ttargetRepr := g.Files[sourceIndexToImportFrom].InputFile.Repr.(*JSRepr)\n\tfor _, partIndex := range targetRepr.TopLevelSymbolToParts(ref) {\n\t\tpart.Dependencies = append(part.Dependencies, js_ast.Dependency{\n\t\t\tSourceIndex: sourceIndexToImportFrom,\n\t\t\tPartIndex:   partIndex,\n\t\t})\n\t}\n}\n\nfunc (g *LinkerGraph) GenerateRuntimeSymbolImportAndUse(\n\tsourceIndex uint32,\n\tpartIndex uint32,\n\tname string,\n\tuseCount uint32,\n) {\n\tif useCount == 0 {\n\t\treturn\n\t}\n\n\truntimeRepr := g.Files[runtime.SourceIndex].InputFile.Repr.(*JSRepr)\n\tref := runtimeRepr.AST.NamedExports[name].Ref\n\tg.GenerateSymbolImportAndUse(sourceIndex, partIndex, ref, useCount, runtime.SourceIndex)\n}\n"
  },
  {
    "path": "internal/graph/input.go",
    "content": "package graph\n\n// The code in this file mainly represents data that passes from the scan phase\n// to the compile phase of the bundler. There is currently one exception: the\n// \"meta\" member of the JavaScript file representation. That could have been\n// stored separately but is stored together for convenience and to avoid an\n// extra level of indirection. Instead it's kept in a separate type to keep\n// things organized.\n\nimport (\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/resolver\"\n\t\"github.com/evanw/esbuild/internal/sourcemap\"\n)\n\ntype InputFile struct {\n\tRepr           InputFileRepr\n\tInputSourceMap *sourcemap.SourceMap\n\n\t// If this file ends up being used in the bundle, these are additional files\n\t// that must be written to the output directory. It's used by the \"file\" and\n\t// \"copy\" loaders.\n\tAdditionalFiles            []OutputFile\n\tUniqueKeyForAdditionalFile string\n\n\tSideEffects SideEffects\n\tSource      logger.Source\n\tLoader      config.Loader\n\n\tOmitFromSourceMapsAndMetafile bool\n}\n\ntype OutputFile struct {\n\t// If \"AbsMetadataFile\" is present, this will be filled out with information\n\t// about this file in JSON format. This is a partial JSON file that will be\n\t// fully assembled later.\n\tJSONMetadataChunk string\n\n\tAbsPath      string\n\tContents     []byte\n\tIsExecutable bool\n}\n\ntype SideEffects struct {\n\t// This is optional additional information for use in error messages\n\tData *resolver.SideEffectsData\n\n\tKind SideEffectsKind\n}\n\ntype SideEffectsKind uint8\n\nconst (\n\t// The default value conservatively considers all files to have side effects.\n\tHasSideEffects SideEffectsKind = iota\n\n\t// This file was listed as not having side effects by a \"package.json\"\n\t// file in one of our containing directories with a \"sideEffects\" field.\n\tNoSideEffects_PackageJSON\n\n\t// This file is considered to have no side effects because the AST was empty\n\t// after parsing finished. This should be the case for \".d.ts\" files.\n\tNoSideEffects_EmptyAST\n\n\t// This file was loaded using a data-oriented loader (e.g. \"text\") that is\n\t// known to not have side effects.\n\tNoSideEffects_PureData\n\n\t// Same as above but it came from a plugin. We don't want to warn about\n\t// unused imports to these files since running the plugin is a side effect.\n\t// Removing the import would not call the plugin which is observable.\n\tNoSideEffects_PureData_FromPlugin\n)\n\ntype InputFileRepr interface {\n\tImportRecords() *[]ast.ImportRecord\n}\n\ntype JSRepr struct {\n\tMeta JSReprMeta\n\tAST  js_ast.AST\n\n\t// If present, this is the CSS file that this JavaScript stub corresponds to.\n\t// A JavaScript stub is automatically generated for a CSS file when it's\n\t// imported from a JavaScript file.\n\tCSSSourceIndex ast.Index32\n}\n\nfunc (repr *JSRepr) ImportRecords() *[]ast.ImportRecord {\n\treturn &repr.AST.ImportRecords\n}\n\nfunc (repr *JSRepr) TopLevelSymbolToParts(ref ast.Ref) []uint32 {\n\t// Overlay the mutable map from the linker\n\tif parts, ok := repr.Meta.TopLevelSymbolToPartsOverlay[ref]; ok {\n\t\treturn parts\n\t}\n\n\t// Fall back to the immutable map from the parser\n\treturn repr.AST.TopLevelSymbolToPartsFromParser[ref]\n}\n\ntype CSSRepr struct {\n\tAST css_ast.AST\n\n\t// If present, this is the JavaScript stub corresponding to this CSS file.\n\t// A JavaScript stub is automatically generated for a CSS file when it's\n\t// imported from a JavaScript file.\n\tJSSourceIndex ast.Index32\n}\n\nfunc (repr *CSSRepr) ImportRecords() *[]ast.ImportRecord {\n\treturn &repr.AST.ImportRecords\n}\n\ntype CopyRepr struct {\n\t// The URL that replaces the contents of any import record paths for this file\n\tURLForCode string\n}\n\nfunc (repr *CopyRepr) ImportRecords() *[]ast.ImportRecord {\n\treturn nil\n}\n"
  },
  {
    "path": "internal/graph/meta.go",
    "content": "package graph\n\n// The code in this file represents data that is required by the compile phase\n// of the bundler but that is not required by the scan phase.\n\nimport (\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\ntype WrapKind uint8\n\nconst (\n\tWrapNone WrapKind = iota\n\n\t// The module will be bundled CommonJS-style like this:\n\t//\n\t//   // foo.ts\n\t//   let require_foo = __commonJS((exports, module) => {\n\t//     exports.foo = 123;\n\t//   });\n\t//\n\t//   // bar.ts\n\t//   let foo = flag ? require_foo() : null;\n\t//\n\tWrapCJS\n\n\t// The module will be bundled ESM-style like this:\n\t//\n\t//   // foo.ts\n\t//   var foo, foo_exports = {};\n\t//   __export(foo_exports, {\n\t//     foo: () => foo\n\t//   });\n\t//   let init_foo = __esm(() => {\n\t//     foo = 123;\n\t//   });\n\t//\n\t//   // bar.ts\n\t//   let foo = flag ? (init_foo(), __toCommonJS(foo_exports)) : null;\n\t//\n\tWrapESM\n)\n\n// This contains linker-specific metadata corresponding to a \"file\" struct\n// from the initial scan phase of the bundler. It's separated out because it's\n// conceptually only used for a single linking operation and because multiple\n// linking operations may be happening in parallel with different metadata for\n// the same file.\ntype JSReprMeta struct {\n\t// This is only for TypeScript files. If an import symbol is in this map, it\n\t// means the import couldn't be found and doesn't actually exist. This is not\n\t// an error in TypeScript because the import is probably just a type.\n\t//\n\t// Normally we remove all unused imports for TypeScript files during parsing,\n\t// which automatically removes type-only imports. But there are certain re-\n\t// export situations where it's impossible to tell if an import is a type or\n\t// not:\n\t//\n\t//   import {typeOrNotTypeWhoKnows} from 'path';\n\t//   export {typeOrNotTypeWhoKnows};\n\t//\n\t// Really people should be using the TypeScript \"isolatedModules\" flag with\n\t// bundlers like this one that compile TypeScript files independently without\n\t// type checking. That causes the TypeScript type checker to emit the error\n\t// \"Re-exporting a type when the '--isolatedModules' flag is provided requires\n\t// using 'export type'.\" But we try to be robust to such code anyway.\n\tIsProbablyTypeScriptType map[ast.Ref]bool\n\n\t// Imports are matched with exports in a separate pass from when the matched\n\t// exports are actually bound to the imports. Here \"binding\" means adding non-\n\t// local dependencies on the parts in the exporting file that declare the\n\t// exported symbol to all parts in the importing file that use the imported\n\t// symbol.\n\t//\n\t// This must be a separate pass because of the \"probably TypeScript type\"\n\t// check above. We can't generate the part for the export namespace until\n\t// we've matched imports with exports because the generated code must omit\n\t// type-only imports in the export namespace code. And we can't bind exports\n\t// to imports until the part for the export namespace is generated since that\n\t// part needs to participate in the binding.\n\t//\n\t// This array holds the deferred imports to bind so the pass can be split\n\t// into two separate passes.\n\tImportsToBind map[ast.Ref]ImportData\n\n\t// This includes both named exports and re-exports.\n\t//\n\t// Named exports come from explicit export statements in the original file,\n\t// and are copied from the \"NamedExports\" field in the AST.\n\t//\n\t// Re-exports come from other files and are the result of resolving export\n\t// star statements (i.e. \"export * from 'foo'\").\n\tResolvedExports     map[string]ExportData\n\tResolvedExportStar  *ExportData\n\tResolvedExportTypos *helpers.TypoDetector\n\n\t// Never iterate over \"resolvedExports\" directly. Instead, iterate over this\n\t// array. Some exports in that map aren't meant to end up in generated code.\n\t// This array excludes these exports and is also sorted, which avoids non-\n\t// determinism due to random map iteration order.\n\tSortedAndFilteredExportAliases []string\n\n\t// This is merged on top of the corresponding map from the parser in the AST.\n\t// You should call \"TopLevelSymbolToParts\" to access this instead of accessing\n\t// it directly.\n\tTopLevelSymbolToPartsOverlay map[ast.Ref][]uint32\n\n\t// If this is an entry point, this array holds a reference to one free\n\t// temporary symbol for each entry in \"sortedAndFilteredExportAliases\".\n\t// These may be needed to store copies of CommonJS re-exports in ESM.\n\tCJSExportCopies []ast.Ref\n\n\t// The index of the automatically-generated part used to represent the\n\t// CommonJS or ESM wrapper. This part is empty and is only useful for tree\n\t// shaking and code splitting. The wrapper can't be inserted into the part\n\t// because the wrapper contains other parts, which can't be represented by\n\t// the current part system. Only wrapped files have one of these.\n\tWrapperPartIndex ast.Index32\n\n\t// The index of the automatically-generated part used to handle entry point\n\t// specific stuff. If a certain part is needed by the entry point, it's added\n\t// as a dependency of this part. This is important for parts that are marked\n\t// as removable when unused and that are not used by anything else. Only\n\t// entry point files have one of these.\n\tEntryPointPartIndex ast.Index32\n\n\t// This is true if this file is affected by top-level await, either by having\n\t// a top-level await inside this file or by having an import/export statement\n\t// that transitively imports such a file. It is forbidden to call \"require()\"\n\t// on these files since they are evaluated asynchronously.\n\tIsAsyncOrHasAsyncDependency bool\n\n\tWrap WrapKind\n\n\t// If true, we need to insert \"var exports = {};\". This is the case for ESM\n\t// files when the import namespace is captured via \"import * as\" and also\n\t// when they are the target of a \"require()\" call.\n\tNeedsExportsVariable bool\n\n\t// If true, the \"__export(exports, { ... })\" call will be force-included even\n\t// if there are no parts that reference \"exports\". Otherwise this call will\n\t// be removed due to the tree shaking pass. This is used when for entry point\n\t// files when code related to the current output format needs to reference\n\t// the \"exports\" variable.\n\tForceIncludeExportsForEntryPoint bool\n\n\t// This is set when we need to pull in the \"__export\" symbol in to the part\n\t// at \"nsExportPartIndex\". This can't be done in \"createExportsForFile\"\n\t// because of concurrent map hazards. Instead, it must be done later.\n\tNeedsExportSymbolFromRuntime bool\n\n\t// Wrapped files must also ensure that their dependencies are wrapped. This\n\t// flag is used during the traversal that enforces this invariant, and is used\n\t// to detect when the fixed point has been reached.\n\tDidWrapDependencies bool\n}\n\ntype ImportData struct {\n\t// This is an array of intermediate statements that re-exported this symbol\n\t// in a chain before getting to the final symbol. This can be done either with\n\t// \"export * from\" or \"export {} from\". If this is done with \"export * from\"\n\t// then this may not be the result of a single chain but may instead form\n\t// a diamond shape if this same symbol was re-exported multiple times from\n\t// different files.\n\tReExports []js_ast.Dependency\n\n\tNameLoc     logger.Loc // Optional, goes with sourceIndex, ignore if zero\n\tRef         ast.Ref\n\tSourceIndex uint32\n}\n\ntype ExportData struct {\n\t// Export star resolution happens first before import resolution. That means\n\t// it cannot yet determine if duplicate names from export star resolution are\n\t// ambiguous (point to different symbols) or not (point to the same symbol).\n\t// This issue can happen in the following scenario:\n\t//\n\t//   // entry.js\n\t//   export * from './a'\n\t//   export * from './b'\n\t//\n\t//   // a.js\n\t//   export * from './c'\n\t//\n\t//   // b.js\n\t//   export {x} from './c'\n\t//\n\t//   // c.js\n\t//   export let x = 1, y = 2\n\t//\n\t// In this case \"entry.js\" should have two exports \"x\" and \"y\", neither of\n\t// which are ambiguous. To handle this case, ambiguity resolution must be\n\t// deferred until import resolution time. That is done using this array.\n\tPotentiallyAmbiguousExportStarRefs []ImportData\n\n\tRef ast.Ref\n\n\t// This is the file that the named export above came from. This will be\n\t// different from the file that contains this object if this is a re-export.\n\tNameLoc     logger.Loc // Optional, goes with sourceIndex, ignore if zero\n\tSourceIndex uint32\n}\n"
  },
  {
    "path": "internal/helpers/bitset.go",
    "content": "package helpers\n\nimport \"bytes\"\n\ntype BitSet struct {\n\tentries []byte\n}\n\nfunc NewBitSet(bitCount uint) BitSet {\n\treturn BitSet{make([]byte, (bitCount+7)/8)}\n}\n\nfunc (bs BitSet) HasBit(bit uint) bool {\n\treturn (bs.entries[bit/8] & (1 << (bit & 7))) != 0\n}\n\nfunc (bs BitSet) SetBit(bit uint) {\n\tbs.entries[bit/8] |= 1 << (bit & 7)\n}\n\nfunc (bs BitSet) Equals(other BitSet) bool {\n\treturn bytes.Equal(bs.entries, other.entries)\n}\n\nfunc (bs BitSet) String() string {\n\treturn string(bs.entries)\n}\n"
  },
  {
    "path": "internal/helpers/comment.go",
    "content": "package helpers\n\nimport (\n\t\"strings\"\n)\n\nfunc EscapeClosingTag(text string, slashTag string) string {\n\tif slashTag == \"\" {\n\t\treturn text\n\t}\n\ti := strings.Index(text, \"</\")\n\tif i < 0 {\n\t\treturn text\n\t}\n\tvar b strings.Builder\n\tfor {\n\t\tb.WriteString(text[:i+1])\n\t\ttext = text[i+1:]\n\t\tif len(text) >= len(slashTag) && strings.EqualFold(text[:len(slashTag)], slashTag) {\n\t\t\tb.WriteByte('\\\\')\n\t\t}\n\t\ti = strings.Index(text, \"</\")\n\t\tif i < 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\tb.WriteString(text)\n\treturn b.String()\n}\n"
  },
  {
    "path": "internal/helpers/dataurl.go",
    "content": "package helpers\n\nimport (\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\n// Returns the shorter of either a base64-encoded or percent-escaped data URL\nfunc EncodeStringAsShortestDataURL(mimeType string, text string) string {\n\tencoded := base64.StdEncoding.EncodeToString([]byte(text))\n\turl := fmt.Sprintf(\"data:%s;base64,%s\", mimeType, encoded)\n\tif percentURL, ok := EncodeStringAsPercentEscapedDataURL(mimeType, text); ok && len(percentURL) < len(url) {\n\t\treturn percentURL\n\t}\n\treturn url\n}\n\n// See \"scripts/dataurl-escapes.html\" for how this was derived\nfunc EncodeStringAsPercentEscapedDataURL(mimeType string, text string) (string, bool) {\n\thex := \"0123456789ABCDEF\"\n\tsb := strings.Builder{}\n\tn := len(text)\n\ti := 0\n\trunStart := 0\n\tsb.WriteString(\"data:\")\n\tsb.WriteString(mimeType)\n\tsb.WriteByte(',')\n\n\t// Scan for trailing characters that need to be escaped\n\ttrailingStart := n\n\tfor trailingStart > 0 {\n\t\tif c := text[trailingStart-1]; c > 0x20 || c == '\\t' || c == '\\n' || c == '\\r' {\n\t\t\tbreak\n\t\t}\n\t\ttrailingStart--\n\t}\n\n\tfor i < n {\n\t\tc, width := utf8.DecodeRuneInString(text[i:])\n\n\t\t// We can't encode invalid UTF-8 data\n\t\tif c == utf8.RuneError && width == 1 {\n\t\t\treturn \"\", false\n\t\t}\n\n\t\t// Escape this character if needed\n\t\tif c == '\\t' || c == '\\n' || c == '\\r' || c == '#' || i >= trailingStart ||\n\t\t\t(c == '%' && i+2 < n && isHex(text[i+1]) && isHex(text[i+2])) {\n\t\t\tif runStart < i {\n\t\t\t\tsb.WriteString(text[runStart:i])\n\t\t\t}\n\t\t\tsb.WriteByte('%')\n\t\t\tsb.WriteByte(hex[c>>4])\n\t\t\tsb.WriteByte(hex[c&15])\n\t\t\trunStart = i + width\n\t\t}\n\n\t\ti += width\n\t}\n\n\tif runStart < n {\n\t\tsb.WriteString(text[runStart:])\n\t}\n\n\treturn sb.String(), true\n}\n\nfunc isHex(c byte) bool {\n\treturn c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F'\n}\n"
  },
  {
    "path": "internal/helpers/dataurl_test.go",
    "content": "package helpers_test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/helpers\"\n)\n\nfunc TestEncodeDataURL(t *testing.T) {\n\tcheck := func(raw string, expected string) {\n\t\turl, ok := helpers.EncodeStringAsPercentEscapedDataURL(\"text/plain\", raw)\n\t\tif !ok {\n\t\t\tt.Fatalf(\"Failed to encode %q\", raw)\n\t\t} else if url != expected {\n\t\t\tt.Fatalf(\"Got %q but expected %q\", url, expected)\n\t\t}\n\t}\n\n\tfor i := 0; i <= 0xFF; i++ {\n\t\talwaysEscape := i == '\\t' || i == '\\r' || i == '\\n' || i == '#'\n\t\ttrailingEscape := i <= 0x20 || i == '#'\n\n\t\tif trailingEscape {\n\t\t\tcheck(string(rune(i)), fmt.Sprintf(\"data:text/plain,%%%02X\", i))\n\t\t\tcheck(\"foo\"+string(rune(i)), fmt.Sprintf(\"data:text/plain,foo%%%02X\", i))\n\t\t} else {\n\t\t\tcheck(string(rune(i)), fmt.Sprintf(\"data:text/plain,%c\", i))\n\t\t\tcheck(\"foo\"+string(rune(i)), fmt.Sprintf(\"data:text/plain,foo%c\", i))\n\t\t}\n\n\t\tif alwaysEscape {\n\t\t\tcheck(string(rune(i))+\"foo\", fmt.Sprintf(\"data:text/plain,%%%02Xfoo\", i))\n\t\t} else {\n\t\t\tcheck(string(rune(i))+\"foo\", fmt.Sprintf(\"data:text/plain,%cfoo\", i))\n\t\t}\n\t}\n\n\t// Test leading vs. trailing\n\tcheck(\" \\t \", \"data:text/plain, %09%20\")\n\tcheck(\" \\n \", \"data:text/plain, %0A%20\")\n\tcheck(\" \\r \", \"data:text/plain, %0D%20\")\n\tcheck(\" # \", \"data:text/plain, %23%20\")\n\tcheck(\"\\x08#\\x08\", \"data:text/plain,\\x08%23%08\")\n\n\t// Only \"%\" symbols that could form an escape need to be escaped\n\tcheck(\"%, %3, %33, %333\", \"data:text/plain,%, %3, %2533, %25333\")\n}\n"
  },
  {
    "path": "internal/helpers/float.go",
    "content": "package helpers\n\nimport \"math\"\n\n// This wraps float64 math operations. Why does this exist? The Go compiler\n// contains some optimizations to take advantage of \"fused multiply and add\"\n// (FMA) instructions on certain processors. These instructions lead to\n// different output on those processors, which means esbuild's output is no\n// longer deterministic across all platforms. From the Go specification itself\n// (https://go.dev/ref/spec#Floating_point_operators):\n//\n//\tAn implementation may combine multiple floating-point operations into a\n//\tsingle fused operation, possibly across statements, and produce a result\n//\tthat differs from the value obtained by executing and rounding the\n//\tinstructions individually. An explicit floating-point type conversion\n//\trounds to the precision of the target type, preventing fusion that would\n//\tdiscard that rounding.\n//\n//\tFor instance, some architectures provide a \"fused multiply and add\" (FMA)\n//\tinstruction that computes x*y + z without rounding the intermediate result\n//\tx*y.\n//\n// Therefore we need to add explicit type conversions such as \"float64(x)\" to\n// prevent optimizations that break correctness. Rather than adding them on a\n// case-by-case basis as real correctness issues are discovered, we instead\n// preemptively force them to be added everywhere by using this wrapper type\n// for all floating-point math.\ntype F64 struct {\n\tvalue float64\n}\n\nfunc NewF64(a float64) F64 {\n\treturn F64{value: float64(a)}\n}\n\nfunc (a F64) Value() float64 {\n\treturn a.value\n}\n\nfunc (a F64) IsNaN() bool {\n\treturn math.IsNaN(a.value)\n}\n\nfunc (a F64) Neg() F64 {\n\treturn NewF64(-a.value)\n}\n\nfunc (a F64) Abs() F64 {\n\treturn NewF64(math.Abs(a.value))\n}\n\nfunc (a F64) Sin() F64 {\n\treturn NewF64(math.Sin(a.value))\n}\n\nfunc (a F64) Cos() F64 {\n\treturn NewF64(math.Cos(a.value))\n}\n\nfunc (a F64) Log2() F64 {\n\treturn NewF64(math.Log2(a.value))\n}\n\nfunc (a F64) Round() F64 {\n\treturn NewF64(math.Round(a.value))\n}\n\nfunc (a F64) Floor() F64 {\n\treturn NewF64(math.Floor(a.value))\n}\n\nfunc (a F64) Ceil() F64 {\n\treturn NewF64(math.Ceil(a.value))\n}\n\nfunc (a F64) Squared() F64 {\n\treturn a.Mul(a)\n}\n\nfunc (a F64) Cubed() F64 {\n\treturn a.Mul(a).Mul(a)\n}\n\nfunc (a F64) Sqrt() F64 {\n\treturn NewF64(math.Sqrt(a.value))\n}\n\nfunc (a F64) Cbrt() F64 {\n\treturn NewF64(math.Cbrt(a.value))\n}\n\nfunc (a F64) Add(b F64) F64 {\n\treturn NewF64(a.value + b.value)\n}\n\nfunc (a F64) AddConst(b float64) F64 {\n\treturn NewF64(a.value + b)\n}\n\nfunc (a F64) Sub(b F64) F64 {\n\treturn NewF64(a.value - b.value)\n}\n\nfunc (a F64) SubConst(b float64) F64 {\n\treturn NewF64(a.value - b)\n}\n\nfunc (a F64) Mul(b F64) F64 {\n\treturn NewF64(a.value * b.value)\n}\n\nfunc (a F64) MulConst(b float64) F64 {\n\treturn NewF64(a.value * b)\n}\n\nfunc (a F64) Div(b F64) F64 {\n\treturn NewF64(a.value / b.value)\n}\n\nfunc (a F64) DivConst(b float64) F64 {\n\treturn NewF64(a.value / b)\n}\n\nfunc (a F64) Pow(b F64) F64 {\n\treturn NewF64(math.Pow(a.value, b.value))\n}\n\nfunc (a F64) PowConst(b float64) F64 {\n\treturn NewF64(math.Pow(a.value, b))\n}\n\nfunc (a F64) Atan2(b F64) F64 {\n\treturn NewF64(math.Atan2(a.value, b.value))\n}\n\nfunc (a F64) WithSignFrom(b F64) F64 {\n\treturn NewF64(math.Copysign(a.value, b.value))\n}\n\nfunc Min2(a F64, b F64) F64 {\n\treturn NewF64(math.Min(a.value, b.value))\n}\n\nfunc Max2(a F64, b F64) F64 {\n\treturn NewF64(math.Max(a.value, b.value))\n}\n\nfunc Min3(a F64, b F64, c F64) F64 {\n\treturn NewF64(math.Min(math.Min(a.value, b.value), c.value))\n}\n\nfunc Max3(a F64, b F64, c F64) F64 {\n\treturn NewF64(math.Max(math.Max(a.value, b.value), c.value))\n}\n\nfunc Lerp(a F64, b F64, t F64) F64 {\n\treturn b.Sub(a).Mul(t).Add(a)\n}\n"
  },
  {
    "path": "internal/helpers/glob.go",
    "content": "package helpers\n\nimport \"strings\"\n\ntype GlobWildcard uint8\n\nconst (\n\tGlobNone GlobWildcard = iota\n\tGlobAllExceptSlash\n\tGlobAllIncludingSlash\n)\n\ntype GlobPart struct {\n\tPrefix   string\n\tWildcard GlobWildcard\n}\n\n// The returned array will always be at least one element. If there are no\n// wildcards then it will be exactly one element, and if there are wildcards\n// then it will be more than one element.\nfunc ParseGlobPattern(text string) (pattern []GlobPart) {\n\tfor {\n\t\tstar := strings.IndexByte(text, '*')\n\t\tif star < 0 {\n\t\t\tpattern = append(pattern, GlobPart{Prefix: text})\n\t\t\tbreak\n\t\t}\n\t\tcount := 1\n\t\tfor star+count < len(text) && text[star+count] == '*' {\n\t\t\tcount++\n\t\t}\n\t\twildcard := GlobAllExceptSlash\n\n\t\t// Allow both \"/\" and \"\\\" as slashes\n\t\tif count > 1 && (star == 0 || text[star-1] == '/' || text[star-1] == '\\\\') &&\n\t\t\t(star+count == len(text) || text[star+count] == '/' || text[star+count] == '\\\\') {\n\t\t\twildcard = GlobAllIncludingSlash // A \"globstar\" path segment\n\t\t}\n\n\t\tpattern = append(pattern, GlobPart{Prefix: text[:star], Wildcard: wildcard})\n\t\ttext = text[star+count:]\n\t}\n\treturn\n}\n\nfunc GlobPatternToString(pattern []GlobPart) string {\n\tsb := strings.Builder{}\n\tfor _, part := range pattern {\n\t\tsb.WriteString(part.Prefix)\n\t\tswitch part.Wildcard {\n\t\tcase GlobAllExceptSlash:\n\t\t\tsb.WriteByte('*')\n\t\tcase GlobAllIncludingSlash:\n\t\t\tsb.WriteString(\"**\")\n\t\t}\n\t}\n\treturn sb.String()\n}\n"
  },
  {
    "path": "internal/helpers/hash.go",
    "content": "package helpers\n\n// From: http://boost.sourceforge.net/doc/html/boost/hash_combine.html\nfunc HashCombine(seed uint32, hash uint32) uint32 {\n\treturn seed ^ (hash + 0x9e3779b9 + (seed << 6) + (seed >> 2))\n}\n\nfunc HashCombineString(seed uint32, text string) uint32 {\n\tseed = HashCombine(seed, uint32(len(text)))\n\tfor _, c := range text {\n\t\tseed = HashCombine(seed, uint32(c))\n\t}\n\treturn seed\n}\n"
  },
  {
    "path": "internal/helpers/joiner.go",
    "content": "package helpers\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n)\n\n// This provides an efficient way to join lots of big string and byte slices\n// together. It avoids the cost of repeatedly reallocating as the buffer grows\n// by measuring exactly how big the buffer should be and then allocating once.\n// This is a measurable speedup.\ntype Joiner struct {\n\tstrings  []joinerString\n\tbytes    []joinerBytes\n\tlength   uint32\n\tlastByte byte\n}\n\ntype joinerString struct {\n\tdata   string\n\toffset uint32\n}\n\ntype joinerBytes struct {\n\tdata   []byte\n\toffset uint32\n}\n\nfunc (j *Joiner) AddString(data string) {\n\tif len(data) > 0 {\n\t\tj.lastByte = data[len(data)-1]\n\t}\n\tj.strings = append(j.strings, joinerString{data, j.length})\n\tj.length += uint32(len(data))\n}\n\nfunc (j *Joiner) AddBytes(data []byte) {\n\tif len(data) > 0 {\n\t\tj.lastByte = data[len(data)-1]\n\t}\n\tj.bytes = append(j.bytes, joinerBytes{data, j.length})\n\tj.length += uint32(len(data))\n}\n\nfunc (j *Joiner) LastByte() byte {\n\treturn j.lastByte\n}\n\nfunc (j *Joiner) Length() uint32 {\n\treturn j.length\n}\n\nfunc (j *Joiner) EnsureNewlineAtEnd() {\n\tif j.length > 0 && j.lastByte != '\\n' {\n\t\tj.AddString(\"\\n\")\n\t}\n}\n\nfunc (j *Joiner) Done() []byte {\n\tif len(j.strings) == 0 && len(j.bytes) == 1 && j.bytes[0].offset == 0 {\n\t\t// No need to allocate if there was only a single byte array written\n\t\treturn j.bytes[0].data\n\t}\n\tbuffer := make([]byte, j.length)\n\tfor _, item := range j.strings {\n\t\tcopy(buffer[item.offset:], item.data)\n\t}\n\tfor _, item := range j.bytes {\n\t\tcopy(buffer[item.offset:], item.data)\n\t}\n\treturn buffer\n}\n\nfunc (j *Joiner) Contains(s string, b []byte) bool {\n\tfor _, item := range j.strings {\n\t\tif strings.Contains(item.data, s) {\n\t\t\treturn true\n\t\t}\n\t}\n\tfor _, item := range j.bytes {\n\t\tif bytes.Contains(item.data, b) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "internal/helpers/mime.go",
    "content": "package helpers\n\nimport \"strings\"\n\nvar builtinTypesLower = map[string]string{\n\t// Text\n\t\".css\":      \"text/css; charset=utf-8\",\n\t\".htm\":      \"text/html; charset=utf-8\",\n\t\".html\":     \"text/html; charset=utf-8\",\n\t\".js\":       \"text/javascript; charset=utf-8\",\n\t\".json\":     \"application/json; charset=utf-8\",\n\t\".markdown\": \"text/markdown; charset=utf-8\",\n\t\".md\":       \"text/markdown; charset=utf-8\",\n\t\".mjs\":      \"text/javascript; charset=utf-8\",\n\t\".xhtml\":    \"application/xhtml+xml; charset=utf-8\",\n\t\".xml\":      \"text/xml; charset=utf-8\",\n\n\t// Images\n\t\".avif\": \"image/avif\",\n\t\".gif\":  \"image/gif\",\n\t\".jpeg\": \"image/jpeg\",\n\t\".jpg\":  \"image/jpeg\",\n\t\".png\":  \"image/png\",\n\t\".svg\":  \"image/svg+xml\",\n\t\".webp\": \"image/webp\",\n\n\t// Fonts\n\t\".eot\":   \"application/vnd.ms-fontobject\",\n\t\".otf\":   \"font/otf\",\n\t\".sfnt\":  \"font/sfnt\",\n\t\".ttf\":   \"font/ttf\",\n\t\".woff\":  \"font/woff\",\n\t\".woff2\": \"font/woff2\",\n\n\t// Other\n\t\".pdf\":         \"application/pdf\",\n\t\".wasm\":        \"application/wasm\",\n\t\".webmanifest\": \"application/manifest+json\",\n}\n\n// This is used instead of Go's built-in \"mime.TypeByExtension\" function because\n// that function is broken on Windows: https://github.com/golang/go/issues/32350.\nfunc MimeTypeByExtension(ext string) string {\n\tcontentType := builtinTypesLower[ext]\n\tif contentType == \"\" {\n\t\tcontentType = builtinTypesLower[strings.ToLower(ext)]\n\t}\n\treturn contentType\n}\n"
  },
  {
    "path": "internal/helpers/path.go",
    "content": "package helpers\n\nimport (\n\t\"net/url\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/fs\"\n)\n\nfunc IsInsideNodeModules(path string) bool {\n\tfor {\n\t\t// This is written in a platform-independent manner because it's run on\n\t\t// user-specified paths which can be arbitrary non-file-system things. So\n\t\t// for example Windows paths may end up being used on Unix or URLs may end\n\t\t// up being used on Windows. Be consistently agnostic to which kind of\n\t\t// slash is used on all platforms.\n\t\tslash := strings.LastIndexAny(path, \"/\\\\\")\n\t\tif slash == -1 {\n\t\t\treturn false\n\t\t}\n\t\tdir, base := path[:slash], path[slash+1:]\n\t\tif base == \"node_modules\" {\n\t\t\treturn true\n\t\t}\n\t\tpath = dir\n\t}\n}\n\nfunc IsFileURL(fileURL *url.URL) bool {\n\treturn fileURL.Scheme == \"file\" && (fileURL.Host == \"\" || fileURL.Host == \"localhost\") && strings.HasPrefix(fileURL.Path, \"/\")\n}\n\nfunc FileURLFromFilePath(filePath string) *url.URL {\n\t// Append a trailing slash so that resolving the URL includes the trailing\n\t// directory, and turn Windows-style paths with volumes into URL-style paths:\n\t//\n\t//   \"/Users/User/Desktop\" => \"/Users/User/Desktop/\"\n\t//   \"C:\\\\Users\\\\User\\\\Desktop\" => \"/C:/Users/User/Desktop/\"\n\t//\n\tfilePath = strings.ReplaceAll(filePath, \"\\\\\", \"/\")\n\tif !strings.HasPrefix(filePath, \"/\") {\n\t\tfilePath = \"/\" + filePath\n\t}\n\n\treturn &url.URL{Scheme: \"file\", Path: filePath}\n}\n\nfunc FilePathFromFileURL(fs fs.FS, fileURL *url.URL) string {\n\tpath := fileURL.Path\n\n\t// Convert URL-style paths back into Windows-style paths if needed:\n\t//\n\t//   \"/C:/Users/User/foo.js.map\" => \"C:\\\\Users\\\\User\\\\foo.js.map\"\n\t//\n\tif !strings.HasPrefix(fs.Cwd(), \"/\") {\n\t\tpath = strings.TrimPrefix(path, \"/\")\n\t\tpath = strings.ReplaceAll(path, \"/\", \"\\\\\") // This is needed for \"filepath.Rel()\" to work\n\t}\n\n\treturn path\n}\n"
  },
  {
    "path": "internal/helpers/quote.go",
    "content": "package helpers\n\nimport \"unicode/utf8\"\n\nconst hexChars = \"0123456789ABCDEF\"\nconst firstASCII = 0x20\nconst lastASCII = 0x7E\nconst firstHighSurrogate = 0xD800\nconst firstLowSurrogate = 0xDC00\nconst lastLowSurrogate = 0xDFFF\n\nfunc canPrintWithoutEscape(c rune, asciiOnly bool) bool {\n\tif c <= lastASCII {\n\t\treturn c >= firstASCII && c != '\\\\' && c != '\"'\n\t} else {\n\t\treturn !asciiOnly && c != '\\uFEFF' && (c < firstHighSurrogate || c > lastLowSurrogate)\n\t}\n}\n\nfunc QuoteSingle(text string, asciiOnly bool) []byte {\n\treturn internalQuote(text, asciiOnly, '\\'')\n}\n\nfunc QuoteForJSON(text string, asciiOnly bool) []byte {\n\treturn internalQuote(text, asciiOnly, '\"')\n}\n\nfunc internalQuote(text string, asciiOnly bool, quoteChar byte) []byte {\n\t// Estimate the required length\n\tlenEstimate := 2\n\tfor _, c := range text {\n\t\tif canPrintWithoutEscape(c, asciiOnly) {\n\t\t\tlenEstimate += utf8.RuneLen(c)\n\t\t} else {\n\t\t\tswitch c {\n\t\t\tcase '\\b', '\\f', '\\n', '\\r', '\\t', '\\\\':\n\t\t\t\tlenEstimate += 2\n\t\t\tcase '\"':\n\t\t\t\tif quoteChar == '\"' {\n\t\t\t\t\tlenEstimate += 2\n\t\t\t\t}\n\t\t\tcase '\\'':\n\t\t\t\tif quoteChar == '\\'' {\n\t\t\t\t\tlenEstimate += 2\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tif c <= 0xFFFF {\n\t\t\t\t\tlenEstimate += 6\n\t\t\t\t} else {\n\t\t\t\t\tlenEstimate += 12\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Preallocate the array\n\tbytes := make([]byte, 0, lenEstimate)\n\ti := 0\n\tn := len(text)\n\tbytes = append(bytes, quoteChar)\n\n\tfor i < n {\n\t\tc, width := DecodeWTF8Rune(text[i:])\n\n\t\t// Fast path: a run of characters that don't need escaping\n\t\tif canPrintWithoutEscape(c, asciiOnly) {\n\t\t\tstart := i\n\t\t\ti += width\n\t\t\tfor i < n {\n\t\t\t\tc, width = DecodeWTF8Rune(text[i:])\n\t\t\t\tif !canPrintWithoutEscape(c, asciiOnly) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ti += width\n\t\t\t}\n\t\t\tbytes = append(bytes, text[start:i]...)\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch c {\n\t\tcase '\\b':\n\t\t\tbytes = append(bytes, \"\\\\b\"...)\n\t\t\ti++\n\n\t\tcase '\\f':\n\t\t\tbytes = append(bytes, \"\\\\f\"...)\n\t\t\ti++\n\n\t\tcase '\\n':\n\t\t\tbytes = append(bytes, \"\\\\n\"...)\n\t\t\ti++\n\n\t\tcase '\\r':\n\t\t\tbytes = append(bytes, \"\\\\r\"...)\n\t\t\ti++\n\n\t\tcase '\\t':\n\t\t\tbytes = append(bytes, \"\\\\t\"...)\n\t\t\ti++\n\n\t\tcase '\\\\':\n\t\t\tbytes = append(bytes, \"\\\\\\\\\"...)\n\t\t\ti++\n\n\t\tcase '\"':\n\t\t\tif quoteChar == '\"' {\n\t\t\t\tbytes = append(bytes, \"\\\\\\\"\"...)\n\t\t\t} else {\n\t\t\t\tbytes = append(bytes, '\"')\n\t\t\t}\n\t\t\ti++\n\n\t\tcase '\\'':\n\t\t\tif quoteChar == '\\'' {\n\t\t\t\tbytes = append(bytes, \"\\\\'\"...)\n\t\t\t} else {\n\t\t\t\tbytes = append(bytes, '\\'')\n\t\t\t}\n\t\t\ti++\n\n\t\tdefault:\n\t\t\ti += width\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tbytes = append(\n\t\t\t\t\tbytes,\n\t\t\t\t\t'\\\\', 'u', hexChars[c>>12], hexChars[(c>>8)&15], hexChars[(c>>4)&15], hexChars[c&15],\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tc -= 0x10000\n\t\t\t\tlo := firstHighSurrogate + ((c >> 10) & 0x3FF)\n\t\t\t\thi := firstLowSurrogate + (c & 0x3FF)\n\t\t\t\tbytes = append(\n\t\t\t\t\tbytes,\n\t\t\t\t\t'\\\\', 'u', hexChars[lo>>12], hexChars[(lo>>8)&15], hexChars[(lo>>4)&15], hexChars[lo&15],\n\t\t\t\t\t'\\\\', 'u', hexChars[hi>>12], hexChars[(hi>>8)&15], hexChars[(hi>>4)&15], hexChars[hi&15],\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn append(bytes, quoteChar)\n}\n"
  },
  {
    "path": "internal/helpers/serializer.go",
    "content": "package helpers\n\nimport \"sync\"\n\n// Each call to \"Enter(i)\" doesn't start until \"Leave(i-1)\" is called\ntype Serializer struct {\n\tflags []sync.WaitGroup\n}\n\nfunc MakeSerializer(count int) Serializer {\n\tflags := make([]sync.WaitGroup, count)\n\tfor i := 0; i < count; i++ {\n\t\tflags[i].Add(1)\n\t}\n\treturn Serializer{flags: flags}\n}\n\nfunc (s *Serializer) Enter(i int) {\n\tif i > 0 {\n\t\ts.flags[i-1].Wait()\n\t}\n}\n\nfunc (s *Serializer) Leave(i int) {\n\ts.flags[i].Done()\n}\n"
  },
  {
    "path": "internal/helpers/stack.go",
    "content": "package helpers\n\nimport (\n\t\"runtime/debug\"\n\t\"strings\"\n)\n\nfunc PrettyPrintedStack() string {\n\tlines := strings.Split(strings.TrimSpace(string(debug.Stack())), \"\\n\")\n\n\t// Strip the first \"goroutine\" line\n\tif len(lines) > 0 {\n\t\tif first := lines[0]; strings.HasPrefix(first, \"goroutine \") && strings.HasSuffix(first, \":\") {\n\t\t\tlines = lines[1:]\n\t\t}\n\t}\n\n\tsb := strings.Builder{}\n\n\tfor _, line := range lines {\n\t\t// Indented lines are source locations\n\t\tif strings.HasPrefix(line, \"\\t\") {\n\t\t\tline = line[1:]\n\t\t\tline = strings.TrimPrefix(line, \"github.com/evanw/esbuild/\")\n\t\t\tif offset := strings.LastIndex(line, \" +0x\"); offset != -1 {\n\t\t\t\tline = line[:offset]\n\t\t\t}\n\t\t\tsb.WriteString(\" (\")\n\t\t\tsb.WriteString(line)\n\t\t\tsb.WriteString(\")\")\n\t\t\tcontinue\n\t\t}\n\n\t\t// Other lines are function calls\n\t\tif sb.Len() > 0 {\n\t\t\tsb.WriteByte('\\n')\n\t\t}\n\t\tif strings.HasSuffix(line, \")\") {\n\t\t\tif paren := strings.LastIndexByte(line, '('); paren != -1 {\n\t\t\t\tline = line[:paren]\n\t\t\t}\n\t\t}\n\t\tif slash := strings.LastIndexByte(line, '/'); slash != -1 {\n\t\t\tline = line[slash+1:]\n\t\t}\n\t\tsb.WriteString(line)\n\t}\n\n\treturn sb.String()\n}\n"
  },
  {
    "path": "internal/helpers/strings.go",
    "content": "package helpers\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc StringArraysEqual(a []string, b []string) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor i, x := range a {\n\t\tif x != b[i] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc StringArrayArraysEqual(a [][]string, b [][]string) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor i, x := range a {\n\t\tif !StringArraysEqual(x, b[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc StringArrayToQuotedCommaSeparatedString(a []string) string {\n\tsb := strings.Builder{}\n\tfor i, str := range a {\n\t\tif i > 0 {\n\t\t\tsb.WriteString(\", \")\n\t\t}\n\t\tsb.WriteString(fmt.Sprintf(\"%q\", str))\n\t}\n\treturn sb.String()\n}\n"
  },
  {
    "path": "internal/helpers/timer.go",
    "content": "package helpers\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\ntype Timer struct {\n\tdata  []timerData\n\tmutex sync.Mutex\n}\n\ntype timerData struct {\n\ttime  time.Time\n\tname  string\n\tisEnd bool\n}\n\nfunc (t *Timer) Begin(name string) {\n\tif t != nil {\n\t\tt.data = append(t.data, timerData{\n\t\t\tname: name,\n\t\t\ttime: time.Now(),\n\t\t})\n\t}\n}\n\nfunc (t *Timer) End(name string) {\n\tif t != nil {\n\t\tt.data = append(t.data, timerData{\n\t\t\tname:  name,\n\t\t\ttime:  time.Now(),\n\t\t\tisEnd: true,\n\t\t})\n\t}\n}\n\nfunc (t *Timer) Fork() *Timer {\n\tif t != nil {\n\t\treturn &Timer{}\n\t}\n\treturn nil\n}\n\nfunc (t *Timer) Join(other *Timer) {\n\tif t != nil && other != nil {\n\t\tt.mutex.Lock()\n\t\tdefer t.mutex.Unlock()\n\t\tt.data = append(t.data, other.data...)\n\t}\n}\n\nfunc (t *Timer) Log(log logger.Log) {\n\tif t == nil {\n\t\treturn\n\t}\n\n\ttype pair struct {\n\t\ttimerData\n\t\tindex uint32\n\t}\n\n\tvar notes []logger.MsgData\n\tvar stack []pair\n\tindent := 0\n\n\tfor _, item := range t.data {\n\t\tif !item.isEnd {\n\t\t\ttop := pair{timerData: item, index: uint32(len(notes))}\n\t\t\tnotes = append(notes, logger.MsgData{DisableMaximumWidth: true})\n\t\t\tstack = append(stack, top)\n\t\t\tindent++\n\t\t} else {\n\t\t\tindent--\n\t\t\tlast := len(stack) - 1\n\t\t\ttop := stack[last]\n\t\t\tstack = stack[:last]\n\t\t\tif item.name != top.name {\n\t\t\t\tpanic(\"Internal error\")\n\t\t\t}\n\t\t\tnotes[top.index].Text = fmt.Sprintf(\"%s%s: %dms\",\n\t\t\t\tstrings.Repeat(\"  \", indent),\n\t\t\t\ttop.name,\n\t\t\t\titem.time.Sub(top.time).Milliseconds())\n\t\t}\n\t}\n\n\tlog.AddIDWithNotes(logger.MsgID_None, logger.Info, nil, logger.Range{},\n\t\t\"Timing information (times may not nest hierarchically due to parallelism)\", notes)\n}\n"
  },
  {
    "path": "internal/helpers/typos.go",
    "content": "package helpers\n\nimport \"unicode/utf8\"\n\ntype TypoDetector struct {\n\toneCharTypos map[string]string\n}\n\nfunc MakeTypoDetector(valid []string) TypoDetector {\n\tdetector := TypoDetector{oneCharTypos: make(map[string]string)}\n\n\t// Add all combinations of each valid word with one character missing\n\tfor _, correct := range valid {\n\t\tif len(correct) > 3 {\n\t\t\tfor i, ch := range correct {\n\t\t\t\tdetector.oneCharTypos[correct[:i]+correct[i+utf8.RuneLen(ch):]] = correct\n\t\t\t}\n\t\t}\n\t}\n\n\treturn detector\n}\n\nfunc (detector TypoDetector) MaybeCorrectTypo(typo string) (string, bool) {\n\t// Check for a single deleted character\n\tif corrected, ok := detector.oneCharTypos[typo]; ok {\n\t\treturn corrected, true\n\t}\n\n\t// Check for a single misplaced character\n\tfor i, ch := range typo {\n\t\tif corrected, ok := detector.oneCharTypos[typo[:i]+typo[i+utf8.RuneLen(ch):]]; ok {\n\t\t\treturn corrected, true\n\t\t}\n\t}\n\n\treturn \"\", false\n}\n"
  },
  {
    "path": "internal/helpers/utf.go",
    "content": "package helpers\n\nimport (\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\nfunc ContainsNonBMPCodePoint(text string) bool {\n\tfor _, c := range text {\n\t\tif c > 0xFFFF {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// This does \"ContainsNonBMPCodePoint(UTF16ToString(text))\" without any allocations\nfunc ContainsNonBMPCodePointUTF16(text []uint16) bool {\n\tif n := len(text); n > 0 {\n\t\tfor i, c := range text[:n-1] {\n\t\t\t// Check for a high surrogate\n\t\t\tif c >= 0xD800 && c <= 0xDBFF {\n\t\t\t\t// Check for a low surrogate\n\t\t\t\tif c2 := text[i+1]; c2 >= 0xDC00 && c2 <= 0xDFFF {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc StringToUTF16(text string) []uint16 {\n\tdecoded := make([]uint16, 0, len(text))\n\tfor _, c := range text {\n\t\tif c <= 0xFFFF {\n\t\t\tdecoded = append(decoded, uint16(c))\n\t\t} else {\n\t\t\tc -= 0x10000\n\t\t\tdecoded = append(decoded, uint16(0xD800+((c>>10)&0x3FF)), uint16(0xDC00+(c&0x3FF)))\n\t\t}\n\t}\n\treturn decoded\n}\n\nfunc UTF16ToString(text []uint16) string {\n\tvar temp [utf8.UTFMax]byte\n\tb := strings.Builder{}\n\tn := len(text)\n\tfor i := 0; i < n; i++ {\n\t\tr1 := rune(text[i])\n\t\tif r1 >= 0xD800 && r1 <= 0xDBFF && i+1 < n {\n\t\t\tif r2 := rune(text[i+1]); r2 >= 0xDC00 && r2 <= 0xDFFF {\n\t\t\t\tr1 = (r1-0xD800)<<10 | (r2 - 0xDC00) + 0x10000\n\t\t\t\ti++\n\t\t\t}\n\t\t}\n\t\twidth := encodeWTF8Rune(temp[:], r1)\n\t\tb.Write(temp[:width])\n\t}\n\treturn b.String()\n}\n\nfunc UTF16ToStringWithValidation(text []uint16) (string, uint16, bool) {\n\tvar temp [utf8.UTFMax]byte\n\tb := strings.Builder{}\n\tn := len(text)\n\tfor i := 0; i < n; i++ {\n\t\tr1 := rune(text[i])\n\t\tif r1 >= 0xD800 && r1 <= 0xDBFF {\n\t\t\tif i+1 < n {\n\t\t\t\tif r2 := rune(text[i+1]); r2 >= 0xDC00 && r2 <= 0xDFFF {\n\t\t\t\t\tr1 = (r1-0xD800)<<10 | (r2 - 0xDC00) + 0x10000\n\t\t\t\t\ti++\n\t\t\t\t} else {\n\t\t\t\t\treturn \"\", uint16(r1), false\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn \"\", uint16(r1), false\n\t\t\t}\n\t\t} else if r1 >= 0xDC00 && r1 <= 0xDFFF {\n\t\t\treturn \"\", uint16(r1), false\n\t\t}\n\t\twidth := encodeWTF8Rune(temp[:], r1)\n\t\tb.Write(temp[:width])\n\t}\n\treturn b.String(), 0, true\n}\n\n// Does \"UTF16ToString(text) == str\" without a temporary allocation\nfunc UTF16EqualsString(text []uint16, str string) bool {\n\tif len(text) > len(str) {\n\t\t// Strings can't be equal if UTF-16 encoding is longer than UTF-8 encoding\n\t\treturn false\n\t}\n\tvar temp [utf8.UTFMax]byte\n\tn := len(text)\n\tj := 0\n\tfor i := 0; i < n; i++ {\n\t\tr1 := rune(text[i])\n\t\tif r1 >= 0xD800 && r1 <= 0xDBFF && i+1 < n {\n\t\t\tif r2 := rune(text[i+1]); r2 >= 0xDC00 && r2 <= 0xDFFF {\n\t\t\t\tr1 = (r1-0xD800)<<10 | (r2 - 0xDC00) + 0x10000\n\t\t\t\ti++\n\t\t\t}\n\t\t}\n\t\twidth := encodeWTF8Rune(temp[:], r1)\n\t\tif j+width > len(str) {\n\t\t\treturn false\n\t\t}\n\t\tfor k := 0; k < width; k++ {\n\t\t\tif temp[k] != str[j] {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tj++\n\t\t}\n\t}\n\treturn j == len(str)\n}\n\nfunc UTF16EqualsUTF16(a []uint16, b []uint16) bool {\n\tif len(a) == len(b) {\n\t\tfor i, c := range a {\n\t\t\tif c != b[i] {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n\n// This is a clone of \"utf8.EncodeRune\" that has been modified to encode using\n// WTF-8 instead. See https://simonsapin.github.io/wtf-8/ for more info.\nfunc encodeWTF8Rune(p []byte, r rune) int {\n\t// Negative values are erroneous. Making it unsigned addresses the problem.\n\tswitch i := uint32(r); {\n\tcase i <= 0x7F:\n\t\tp[0] = byte(r)\n\t\treturn 1\n\tcase i <= 0x7FF:\n\t\t_ = p[1] // eliminate bounds checks\n\t\tp[0] = 0xC0 | byte(r>>6)\n\t\tp[1] = 0x80 | byte(r)&0x3F\n\t\treturn 2\n\tcase i > utf8.MaxRune:\n\t\tr = utf8.RuneError\n\t\tfallthrough\n\tcase i <= 0xFFFF:\n\t\t_ = p[2] // eliminate bounds checks\n\t\tp[0] = 0xE0 | byte(r>>12)\n\t\tp[1] = 0x80 | byte(r>>6)&0x3F\n\t\tp[2] = 0x80 | byte(r)&0x3F\n\t\treturn 3\n\tdefault:\n\t\t_ = p[3] // eliminate bounds checks\n\t\tp[0] = 0xF0 | byte(r>>18)\n\t\tp[1] = 0x80 | byte(r>>12)&0x3F\n\t\tp[2] = 0x80 | byte(r>>6)&0x3F\n\t\tp[3] = 0x80 | byte(r)&0x3F\n\t\treturn 4\n\t}\n}\n\n// This is a clone of \"utf8.DecodeRuneInString\" that has been modified to\n// decode using WTF-8 instead. See https://simonsapin.github.io/wtf-8/ for\n// more info.\nfunc DecodeWTF8Rune(s string) (rune, int) {\n\tn := len(s)\n\tif n < 1 {\n\t\treturn utf8.RuneError, 0\n\t}\n\n\ts0 := s[0]\n\tif s0 < 0x80 {\n\t\treturn rune(s0), 1\n\t}\n\n\tvar sz int\n\tif (s0 & 0xE0) == 0xC0 {\n\t\tsz = 2\n\t} else if (s0 & 0xF0) == 0xE0 {\n\t\tsz = 3\n\t} else if (s0 & 0xF8) == 0xF0 {\n\t\tsz = 4\n\t} else {\n\t\treturn utf8.RuneError, 1\n\t}\n\n\tif n < sz {\n\t\treturn utf8.RuneError, 0\n\t}\n\n\ts1 := s[1]\n\tif (s1 & 0xC0) != 0x80 {\n\t\treturn utf8.RuneError, 1\n\t}\n\n\tif sz == 2 {\n\t\tcp := rune(s0&0x1F)<<6 | rune(s1&0x3F)\n\t\tif cp < 0x80 {\n\t\t\treturn utf8.RuneError, 1\n\t\t}\n\t\treturn cp, 2\n\t}\n\ts2 := s[2]\n\n\tif (s2 & 0xC0) != 0x80 {\n\t\treturn utf8.RuneError, 1\n\t}\n\n\tif sz == 3 {\n\t\tcp := rune(s0&0x0F)<<12 | rune(s1&0x3F)<<6 | rune(s2&0x3F)\n\t\tif cp < 0x0800 {\n\t\t\treturn utf8.RuneError, 1\n\t\t}\n\t\treturn cp, 3\n\t}\n\ts3 := s[3]\n\n\tif (s3 & 0xC0) != 0x80 {\n\t\treturn utf8.RuneError, 1\n\t}\n\n\tcp := rune(s0&0x07)<<18 | rune(s1&0x3F)<<12 | rune(s2&0x3F)<<6 | rune(s3&0x3F)\n\tif cp < 0x010000 || cp > 0x10FFFF {\n\t\treturn utf8.RuneError, 1\n\t}\n\treturn cp, 4\n}\n"
  },
  {
    "path": "internal/helpers/waitgroup.go",
    "content": "package helpers\n\nimport \"sync/atomic\"\n\n// Go's \"sync.WaitGroup\" is not thread-safe. Specifically it's not safe to call\n// \"Add\" concurrently with \"Wait\", which is problematic because we have a case\n// where we would like to do that.\n//\n// This is a simple alternative implementation of \"sync.WaitGroup\" that is\n// thread-safe and that works for our purposes. We don't need to worry about\n// multiple waiters so the implementation can be very simple.\ntype ThreadSafeWaitGroup struct {\n\tcounter int32\n\tchannel chan struct{}\n}\n\nfunc MakeThreadSafeWaitGroup() *ThreadSafeWaitGroup {\n\treturn &ThreadSafeWaitGroup{\n\t\tchannel: make(chan struct{}, 1),\n\t}\n}\n\nfunc (wg *ThreadSafeWaitGroup) Add(delta int32) {\n\tif counter := atomic.AddInt32(&wg.counter, delta); counter == 0 {\n\t\twg.channel <- struct{}{}\n\t} else if counter < 0 {\n\t\tpanic(\"sync: negative WaitGroup counter\")\n\t}\n}\n\nfunc (wg *ThreadSafeWaitGroup) Done() {\n\twg.Add(-1)\n}\n\nfunc (wg *ThreadSafeWaitGroup) Wait() {\n\t<-wg.channel\n}\n"
  },
  {
    "path": "internal/js_ast/js_ast.go",
    "content": "package js_ast\n\nimport (\n\t\"strconv\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\n// Every module (i.e. file) is parsed into a separate AST data structure. For\n// efficiency, the parser also resolves all scopes and binds all symbols in the\n// tree.\n//\n// Identifiers in the tree are referenced by a Ref, which is a pointer into the\n// symbol table for the file. The symbol table is stored as a top-level field\n// in the AST so it can be accessed without traversing the tree. For example,\n// a renaming pass can iterate over the symbol table without touching the tree.\n//\n// Parse trees are intended to be immutable. That makes it easy to build an\n// incremental compiler with a \"watch\" mode that can avoid re-parsing files\n// that have already been parsed. Any passes that operate on an AST after it\n// has been parsed should create a copy of the mutated parts of the tree\n// instead of mutating the original tree.\n\ntype L uint8\n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence\nconst (\n\tLLowest L = iota\n\tLComma\n\tLSpread\n\tLYield\n\tLAssign\n\tLConditional\n\tLNullishCoalescing\n\tLLogicalOr\n\tLLogicalAnd\n\tLBitwiseOr\n\tLBitwiseXor\n\tLBitwiseAnd\n\tLEquals\n\tLCompare\n\tLShift\n\tLAdd\n\tLMultiply\n\tLExponentiation\n\tLPrefix\n\tLPostfix\n\tLNew\n\tLCall\n\tLMember\n)\n\ntype OpCode uint8\n\nfunc (op OpCode) IsPrefix() bool {\n\treturn op < UnOpPostDec\n}\n\nfunc (op OpCode) UnaryAssignTarget() AssignTarget {\n\tif op >= UnOpPreDec && op <= UnOpPostInc {\n\t\treturn AssignTargetUpdate\n\t}\n\treturn AssignTargetNone\n}\n\nfunc (op OpCode) IsLeftAssociative() bool {\n\treturn op >= BinOpAdd && op < BinOpComma && op != BinOpPow\n}\n\nfunc (op OpCode) IsRightAssociative() bool {\n\treturn op >= BinOpAssign || op == BinOpPow\n}\n\nfunc (op OpCode) BinaryAssignTarget() AssignTarget {\n\tif op == BinOpAssign {\n\t\treturn AssignTargetReplace\n\t}\n\tif op > BinOpAssign {\n\t\treturn AssignTargetUpdate\n\t}\n\treturn AssignTargetNone\n}\n\nfunc (op OpCode) IsShortCircuit() bool {\n\tswitch op {\n\tcase BinOpLogicalOr, BinOpLogicalOrAssign,\n\t\tBinOpLogicalAnd, BinOpLogicalAndAssign,\n\t\tBinOpNullishCoalescing, BinOpNullishCoalescingAssign:\n\t\treturn true\n\t}\n\treturn false\n}\n\ntype AssignTarget uint8\n\nconst (\n\tAssignTargetNone    AssignTarget = iota\n\tAssignTargetReplace              // \"a = b\"\n\tAssignTargetUpdate               // \"a += b\"\n)\n\n// If you add a new token, remember to add it to \"OpTable\" too\nconst (\n\t// Prefix\n\tUnOpPos OpCode = iota\n\tUnOpNeg\n\tUnOpCpl\n\tUnOpNot\n\tUnOpVoid\n\tUnOpTypeof\n\tUnOpDelete\n\n\t// Prefix update\n\tUnOpPreDec\n\tUnOpPreInc\n\n\t// Postfix update\n\tUnOpPostDec\n\tUnOpPostInc\n\n\t// Left-associative\n\tBinOpAdd\n\tBinOpSub\n\tBinOpMul\n\tBinOpDiv\n\tBinOpRem\n\tBinOpPow\n\tBinOpLt\n\tBinOpLe\n\tBinOpGt\n\tBinOpGe\n\tBinOpIn\n\tBinOpInstanceof\n\tBinOpShl\n\tBinOpShr\n\tBinOpUShr\n\tBinOpLooseEq\n\tBinOpLooseNe\n\tBinOpStrictEq\n\tBinOpStrictNe\n\tBinOpNullishCoalescing\n\tBinOpLogicalOr\n\tBinOpLogicalAnd\n\tBinOpBitwiseOr\n\tBinOpBitwiseAnd\n\tBinOpBitwiseXor\n\n\t// Non-associative\n\tBinOpComma\n\n\t// Right-associative\n\tBinOpAssign\n\tBinOpAddAssign\n\tBinOpSubAssign\n\tBinOpMulAssign\n\tBinOpDivAssign\n\tBinOpRemAssign\n\tBinOpPowAssign\n\tBinOpShlAssign\n\tBinOpShrAssign\n\tBinOpUShrAssign\n\tBinOpBitwiseOrAssign\n\tBinOpBitwiseAndAssign\n\tBinOpBitwiseXorAssign\n\tBinOpNullishCoalescingAssign\n\tBinOpLogicalOrAssign\n\tBinOpLogicalAndAssign\n)\n\ntype OpTableEntry struct {\n\tText      string\n\tLevel     L\n\tIsKeyword bool\n}\n\nvar OpTable = []OpTableEntry{\n\t// Prefix\n\t{\"+\", LPrefix, false},\n\t{\"-\", LPrefix, false},\n\t{\"~\", LPrefix, false},\n\t{\"!\", LPrefix, false},\n\t{\"void\", LPrefix, true},\n\t{\"typeof\", LPrefix, true},\n\t{\"delete\", LPrefix, true},\n\n\t// Prefix update\n\t{\"--\", LPrefix, false},\n\t{\"++\", LPrefix, false},\n\n\t// Postfix update\n\t{\"--\", LPostfix, false},\n\t{\"++\", LPostfix, false},\n\n\t// Left-associative\n\t{\"+\", LAdd, false},\n\t{\"-\", LAdd, false},\n\t{\"*\", LMultiply, false},\n\t{\"/\", LMultiply, false},\n\t{\"%\", LMultiply, false},\n\t{\"**\", LExponentiation, false}, // Right-associative\n\t{\"<\", LCompare, false},\n\t{\"<=\", LCompare, false},\n\t{\">\", LCompare, false},\n\t{\">=\", LCompare, false},\n\t{\"in\", LCompare, true},\n\t{\"instanceof\", LCompare, true},\n\t{\"<<\", LShift, false},\n\t{\">>\", LShift, false},\n\t{\">>>\", LShift, false},\n\t{\"==\", LEquals, false},\n\t{\"!=\", LEquals, false},\n\t{\"===\", LEquals, false},\n\t{\"!==\", LEquals, false},\n\t{\"??\", LNullishCoalescing, false},\n\t{\"||\", LLogicalOr, false},\n\t{\"&&\", LLogicalAnd, false},\n\t{\"|\", LBitwiseOr, false},\n\t{\"&\", LBitwiseAnd, false},\n\t{\"^\", LBitwiseXor, false},\n\n\t// Non-associative\n\t{\",\", LComma, false},\n\n\t// Right-associative\n\t{\"=\", LAssign, false},\n\t{\"+=\", LAssign, false},\n\t{\"-=\", LAssign, false},\n\t{\"*=\", LAssign, false},\n\t{\"/=\", LAssign, false},\n\t{\"%=\", LAssign, false},\n\t{\"**=\", LAssign, false},\n\t{\"<<=\", LAssign, false},\n\t{\">>=\", LAssign, false},\n\t{\">>>=\", LAssign, false},\n\t{\"|=\", LAssign, false},\n\t{\"&=\", LAssign, false},\n\t{\"^=\", LAssign, false},\n\t{\"??=\", LAssign, false},\n\t{\"||=\", LAssign, false},\n\t{\"&&=\", LAssign, false},\n}\n\ntype Decorator struct {\n\tValue            Expr\n\tAtLoc            logger.Loc\n\tOmitNewlineAfter bool\n}\n\ntype PropertyKind uint8\n\nconst (\n\tPropertyField PropertyKind = iota\n\tPropertyMethod\n\tPropertyGetter\n\tPropertySetter\n\tPropertyAutoAccessor\n\tPropertySpread\n\tPropertyDeclareOrAbstract\n\tPropertyClassStaticBlock\n)\n\n// This returns true if and only if this property matches the \"MethodDefinition\"\n// grammar from the specification. That means it's one of the following forms:\n//\n//\tfoo() {}\n//\t*foo() {}\n//\tasync foo() {}\n//\tasync *foo() {}\n//\tget foo() {}\n//\tset foo(_) {}\n//\n// If this returns true, the \"ValueOrNil\" field of the property is always an\n// \"EFunction\" expression and it is always printed as a method.\nfunc (kind PropertyKind) IsMethodDefinition() bool {\n\treturn kind == PropertyMethod || kind == PropertyGetter || kind == PropertySetter\n}\n\ntype ClassStaticBlock struct {\n\tBlock SBlock\n\tLoc   logger.Loc\n}\n\ntype PropertyFlags uint8\n\nconst (\n\tPropertyIsComputed PropertyFlags = 1 << iota\n\tPropertyIsStatic\n\tPropertyWasShorthand\n\tPropertyPreferQuotedKey\n)\n\nfunc (flags PropertyFlags) Has(flag PropertyFlags) bool {\n\treturn (flags & flag) != 0\n}\n\ntype Property struct {\n\tClassStaticBlock *ClassStaticBlock\n\n\tKey Expr\n\n\t// This is omitted for class fields\n\tValueOrNil Expr\n\n\t// This is used when parsing a pattern that uses default values:\n\t//\n\t//   [a = 1] = [];\n\t//   ({a = 1} = {});\n\t//\n\t// It's also used for class fields:\n\t//\n\t//   class Foo { a = 1 }\n\t//\n\tInitializerOrNil Expr\n\n\tDecorators []Decorator\n\n\tLoc             logger.Loc\n\tCloseBracketLoc logger.Loc\n\tKind            PropertyKind\n\tFlags           PropertyFlags\n}\n\ntype PropertyBinding struct {\n\tKey               Expr\n\tValue             Binding\n\tDefaultValueOrNil Expr\n\tLoc               logger.Loc\n\tCloseBracketLoc   logger.Loc\n\tIsComputed        bool\n\tIsSpread          bool\n\tPreferQuotedKey   bool\n}\n\ntype Arg struct {\n\tBinding      Binding\n\tDefaultOrNil Expr\n\tDecorators   []Decorator\n\n\t// \"constructor(public x: boolean) {}\"\n\tIsTypeScriptCtorField bool\n}\n\ntype Fn struct {\n\tName         *ast.LocRef\n\tArgs         []Arg\n\tBody         FnBody\n\tArgumentsRef ast.Ref\n\tOpenParenLoc logger.Loc\n\n\tIsAsync     bool\n\tIsGenerator bool\n\tHasRestArg  bool\n\tHasIfScope  bool\n\n\t// See: https://github.com/rollup/rollup/pull/5024\n\tHasNoSideEffectsComment bool\n\n\t// This is true if the function is a method\n\tIsUniqueFormalParameters bool\n}\n\ntype FnBody struct {\n\tBlock SBlock\n\tLoc   logger.Loc\n}\n\ntype Class struct {\n\tDecorators    []Decorator\n\tName          *ast.LocRef\n\tExtendsOrNil  Expr\n\tProperties    []Property\n\tClassKeyword  logger.Range\n\tBodyLoc       logger.Loc\n\tCloseBraceLoc logger.Loc\n\n\t// If true, JavaScript decorators (i.e. not TypeScript experimental\n\t// decorators) should be lowered. This is the case either if JavaScript\n\t// decorators are not supported in the configured target environment, or\n\t// if \"useDefineForClassFields\" is set to false and this class has\n\t// decorators on it. Note that this flag is not necessarily set to true if\n\t// \"useDefineForClassFields\" is false and a class has an \"accessor\" even\n\t// though the accessor feature comes from the decorator specification.\n\tShouldLowerStandardDecorators bool\n\n\t// If true, property field initializers cannot be assumed to have no side\n\t// effects. For example:\n\t//\n\t//   class Foo {\n\t//     static set foo(x) { importantSideEffect(x) }\n\t//   }\n\t//   class Bar extends Foo {\n\t//     foo = 1\n\t//   }\n\t//\n\t// This happens in TypeScript when \"useDefineForClassFields\" is disabled\n\t// because TypeScript (and esbuild) transforms the above class into this:\n\t//\n\t//   class Foo {\n\t//     static set foo(x) { importantSideEffect(x); }\n\t//   }\n\t//   class Bar extends Foo {\n\t//   }\n\t//   Bar.foo = 1;\n\t//\n\tUseDefineForClassFields bool\n}\n\ntype ArrayBinding struct {\n\tBinding           Binding\n\tDefaultValueOrNil Expr\n\tLoc               logger.Loc\n}\n\ntype Binding struct {\n\tData B\n\tLoc  logger.Loc\n}\n\n// This interface is never called. Its purpose is to encode a variant type in\n// Go's type system.\ntype B interface{ isBinding() }\n\nfunc (*BMissing) isBinding()    {}\nfunc (*BIdentifier) isBinding() {}\nfunc (*BArray) isBinding()      {}\nfunc (*BObject) isBinding()     {}\n\ntype BMissing struct{}\n\ntype BIdentifier struct{ Ref ast.Ref }\n\ntype BArray struct {\n\tItems           []ArrayBinding\n\tCloseBracketLoc logger.Loc\n\tHasSpread       bool\n\tIsSingleLine    bool\n}\n\ntype BObject struct {\n\tProperties    []PropertyBinding\n\tCloseBraceLoc logger.Loc\n\tIsSingleLine  bool\n}\n\ntype Expr struct {\n\tData E\n\tLoc  logger.Loc\n}\n\n// This interface is never called. Its purpose is to encode a variant type in\n// Go's type system.\ntype E interface{ isExpr() }\n\nfunc (*EArray) isExpr()                {}\nfunc (*EUnary) isExpr()                {}\nfunc (*EBinary) isExpr()               {}\nfunc (*EBoolean) isExpr()              {}\nfunc (*ESuper) isExpr()                {}\nfunc (*ENull) isExpr()                 {}\nfunc (*EUndefined) isExpr()            {}\nfunc (*EThis) isExpr()                 {}\nfunc (*ENew) isExpr()                  {}\nfunc (*ENewTarget) isExpr()            {}\nfunc (*EImportMeta) isExpr()           {}\nfunc (*ECall) isExpr()                 {}\nfunc (*EDot) isExpr()                  {}\nfunc (*EIndex) isExpr()                {}\nfunc (*EArrow) isExpr()                {}\nfunc (*EFunction) isExpr()             {}\nfunc (*EClass) isExpr()                {}\nfunc (*EIdentifier) isExpr()           {}\nfunc (*EImportIdentifier) isExpr()     {}\nfunc (*EPrivateIdentifier) isExpr()    {}\nfunc (*ENameOfSymbol) isExpr()         {}\nfunc (*EJSXElement) isExpr()           {}\nfunc (*EJSXText) isExpr()              {}\nfunc (*EMissing) isExpr()              {}\nfunc (*ENumber) isExpr()               {}\nfunc (*EBigInt) isExpr()               {}\nfunc (*EObject) isExpr()               {}\nfunc (*ESpread) isExpr()               {}\nfunc (*EString) isExpr()               {}\nfunc (*ETemplate) isExpr()             {}\nfunc (*ERegExp) isExpr()               {}\nfunc (*EInlinedEnum) isExpr()          {}\nfunc (*EAnnotation) isExpr()           {}\nfunc (*EAwait) isExpr()                {}\nfunc (*EYield) isExpr()                {}\nfunc (*EIf) isExpr()                   {}\nfunc (*ERequireString) isExpr()        {}\nfunc (*ERequireResolveString) isExpr() {}\nfunc (*EImportString) isExpr()         {}\nfunc (*EImportCall) isExpr()           {}\n\ntype EArray struct {\n\tItems            []Expr\n\tCommaAfterSpread logger.Loc\n\tCloseBracketLoc  logger.Loc\n\tIsSingleLine     bool\n\tIsParenthesized  bool\n}\n\ntype EUnary struct {\n\tValue Expr\n\tOp    OpCode\n\n\t// The expression \"typeof (0, x)\" must not become \"typeof x\" if \"x\"\n\t// is unbound because that could suppress a ReferenceError from \"x\".\n\t//\n\t// Also if we know a typeof operator was originally an identifier, then\n\t// we know that this typeof operator always has no side effects (even if\n\t// we consider the identifier by itself to have a side effect).\n\t//\n\t// Note that there *is* actually a case where \"typeof x\" can throw an error:\n\t// when \"x\" is being referenced inside of its TDZ (temporal dead zone). TDZ\n\t// checks are not yet handled correctly by esbuild, so this possibility is\n\t// currently ignored.\n\tWasOriginallyTypeofIdentifier bool\n\n\t// Similarly the expression \"delete (0, x)\" must not become \"delete x\"\n\t// because that syntax is invalid in strict mode. We also need to make sure\n\t// we don't accidentally change the return value:\n\t//\n\t//   Returns false:\n\t//     \"var a; delete (a)\"\n\t//     \"var a = Object.freeze({b: 1}); delete (a.b)\"\n\t//     \"var a = Object.freeze({b: 1}); delete (a?.b)\"\n\t//     \"var a = Object.freeze({b: 1}); delete (a['b'])\"\n\t//     \"var a = Object.freeze({b: 1}); delete (a?.['b'])\"\n\t//\n\t//   Returns true:\n\t//     \"var a; delete (0, a)\"\n\t//     \"var a = Object.freeze({b: 1}); delete (true && a.b)\"\n\t//     \"var a = Object.freeze({b: 1}); delete (false || a?.b)\"\n\t//     \"var a = Object.freeze({b: 1}); delete (null ?? a?.['b'])\"\n\t//     \"var a = Object.freeze({b: 1}); delete (true ? a['b'] : a['b'])\"\n\t//\n\tWasOriginallyDeleteOfIdentifierOrPropertyAccess bool\n}\n\ntype EBinary struct {\n\tLeft  Expr\n\tRight Expr\n\tOp    OpCode\n}\n\ntype EBoolean struct{ Value bool }\n\ntype EMissing struct{}\n\ntype ESuper struct{}\n\ntype ENull struct{}\n\ntype EUndefined struct{}\n\ntype EThis struct{}\n\ntype ENewTarget struct {\n\tRange logger.Range\n}\n\ntype EImportMeta struct {\n\tRangeLen int32\n}\n\n// These help reduce unnecessary memory allocations\nvar BMissingShared = &BMissing{}\nvar EMissingShared = &EMissing{}\nvar ENullShared = &ENull{}\nvar ESuperShared = &ESuper{}\nvar EThisShared = &EThis{}\nvar EUndefinedShared = &EUndefined{}\nvar SDebuggerShared = &SDebugger{}\nvar SEmptyShared = &SEmpty{}\nvar STypeScriptShared = &STypeScript{}\nvar STypeScriptSharedWasDeclareClass = &STypeScript{WasDeclareClass: true}\n\ntype ENew struct {\n\tTarget Expr\n\tArgs   []Expr\n\n\tCloseParenLoc logger.Loc\n\tIsMultiLine   bool\n\n\t// True if there is a comment containing \"@__PURE__\" or \"#__PURE__\" preceding\n\t// this call expression. See the comment inside ECall for more details.\n\tCanBeUnwrappedIfUnused bool\n}\n\ntype CallKind uint8\n\nconst (\n\tNormalCall CallKind = iota\n\tDirectEval\n\tTargetWasOriginallyPropertyAccess\n)\n\ntype OptionalChain uint8\n\nconst (\n\t// \"a.b\"\n\tOptionalChainNone OptionalChain = iota\n\n\t// \"a?.b\"\n\tOptionalChainStart\n\n\t// \"a?.b.c\" => \".c\" is OptionalChainContinue\n\t// \"(a?.b).c\" => \".c\" is OptionalChainNone\n\tOptionalChainContinue\n)\n\ntype ECall struct {\n\tTarget        Expr\n\tArgs          []Expr\n\tCloseParenLoc logger.Loc\n\tOptionalChain OptionalChain\n\tKind          CallKind\n\tIsMultiLine   bool\n\n\t// True if there is a comment containing \"@__PURE__\" or \"#__PURE__\" preceding\n\t// this call expression. This is an annotation used for tree shaking, and\n\t// means that the call can be removed if it's unused. It does not mean the\n\t// call is pure (e.g. it may still return something different if called twice).\n\t//\n\t// Note that the arguments are not considered to be part of the call. If the\n\t// call itself is removed due to this annotation, the arguments must remain\n\t// if they have side effects.\n\tCanBeUnwrappedIfUnused bool\n}\n\nfunc (a *ECall) HasSameFlagsAs(b *ECall) bool {\n\treturn a.OptionalChain == b.OptionalChain &&\n\t\ta.Kind == b.Kind &&\n\t\ta.CanBeUnwrappedIfUnused == b.CanBeUnwrappedIfUnused\n}\n\ntype EDot struct {\n\tTarget        Expr\n\tName          string\n\tNameLoc       logger.Loc\n\tOptionalChain OptionalChain\n\n\t// If true, this property access is known to be free of side-effects. That\n\t// means it can be removed if the resulting value isn't used.\n\tCanBeRemovedIfUnused bool\n\n\t// If true, this property access is a function that, when called, can be\n\t// unwrapped if the resulting value is unused. Unwrapping means discarding\n\t// the call target but keeping any arguments with side effects.\n\tCallCanBeUnwrappedIfUnused bool\n\n\t// Symbol values are known to not have side effects when used as property\n\t// names in class declarations and object literals.\n\tIsSymbolInstance bool\n}\n\nfunc (a *EDot) HasSameFlagsAs(b *EDot) bool {\n\treturn a.OptionalChain == b.OptionalChain &&\n\t\ta.CanBeRemovedIfUnused == b.CanBeRemovedIfUnused &&\n\t\ta.CallCanBeUnwrappedIfUnused == b.CallCanBeUnwrappedIfUnused &&\n\t\ta.IsSymbolInstance == b.IsSymbolInstance\n}\n\ntype EIndex struct {\n\tTarget          Expr\n\tIndex           Expr\n\tCloseBracketLoc logger.Loc\n\tOptionalChain   OptionalChain\n\n\t// If true, this property access is known to be free of side-effects. That\n\t// means it can be removed if the resulting value isn't used.\n\tCanBeRemovedIfUnused bool\n\n\t// If true, this property access is a function that, when called, can be\n\t// unwrapped if the resulting value is unused. Unwrapping means discarding\n\t// the call target but keeping any arguments with side effects.\n\tCallCanBeUnwrappedIfUnused bool\n\n\t// Symbol values are known to not have side effects when used as property\n\t// names in class declarations and object literals.\n\tIsSymbolInstance bool\n}\n\nfunc (a *EIndex) HasSameFlagsAs(b *EIndex) bool {\n\treturn a.OptionalChain == b.OptionalChain &&\n\t\ta.CanBeRemovedIfUnused == b.CanBeRemovedIfUnused &&\n\t\ta.CallCanBeUnwrappedIfUnused == b.CallCanBeUnwrappedIfUnused &&\n\t\ta.IsSymbolInstance == b.IsSymbolInstance\n}\n\ntype EArrow struct {\n\tArgs []Arg\n\tBody FnBody\n\n\tIsAsync    bool\n\tHasRestArg bool\n\tPreferExpr bool // Use shorthand if true and \"Body\" is a single return statement\n\n\t// V8 uses parentheses as an optimization hint: https://v8.dev/blog/preparser#pife\n\tIsParenthesized bool\n\n\t// See: https://github.com/rollup/rollup/pull/5024\n\tHasNoSideEffectsComment bool\n}\n\ntype EFunction struct {\n\tFn Fn\n\n\t// V8 uses parentheses as an optimization hint: https://v8.dev/blog/preparser#pife\n\tIsParenthesized bool\n}\n\ntype EClass struct{ Class Class }\n\ntype EIdentifier struct {\n\tRef ast.Ref\n\n\t// If we're inside a \"with\" statement, this identifier may be a property\n\t// access. In that case it would be incorrect to remove this identifier since\n\t// the property access may be a getter or setter with side effects.\n\tMustKeepDueToWithStmt bool\n\n\t// If true, this identifier is known to not have a side effect (i.e. to not\n\t// throw an exception) when referenced. If false, this identifier may or may\n\t// not have side effects when referenced. This is used to allow the removal\n\t// of known globals such as \"Object\" if they aren't used.\n\tCanBeRemovedIfUnused bool\n\n\t// If true, this identifier represents a function that, when called, can be\n\t// unwrapped if the resulting value is unused. Unwrapping means discarding\n\t// the call target but keeping any arguments with side effects.\n\tCallCanBeUnwrappedIfUnused bool\n}\n\n// This is similar to an EIdentifier but it represents a reference to an ES6\n// import item.\n//\n// Depending on how the code is linked, the file containing this EImportIdentifier\n// may or may not be in the same module group as the file it was imported from.\n//\n// If it's the same module group than we can just merge the import item symbol\n// with the corresponding symbol that was imported, effectively renaming them\n// to be the same thing and statically binding them together.\n//\n// But if it's a different module group, then the import must be dynamically\n// evaluated using a property access off the corresponding namespace symbol,\n// which represents the result of a require() call.\n//\n// It's stored as a separate type so it's not easy to confuse with a plain\n// identifier. For example, it'd be bad if code trying to convert \"{x: x}\" into\n// \"{x}\" shorthand syntax wasn't aware that the \"x\" in this case is actually\n// \"{x: importedNamespace.x}\". This separate type forces code to opt-in to\n// doing this instead of opt-out.\ntype EImportIdentifier struct {\n\tRef             ast.Ref\n\tPreferQuotedKey bool\n\n\t// If true, this was originally an identifier expression such as \"foo\". If\n\t// false, this could potentially have been a member access expression such\n\t// as \"ns.foo\" off of an imported namespace object.\n\tWasOriginallyIdentifier bool\n}\n\n// This is similar to EIdentifier but it represents class-private fields and\n// methods. It can be used where computed properties can be used, such as\n// EIndex and Property.\ntype EPrivateIdentifier struct {\n\tRef ast.Ref\n}\n\n// This represents an internal property name that can be mangled. The symbol\n// referenced by this expression should be a \"SymbolMangledProp\" symbol.\ntype ENameOfSymbol struct {\n\tRef                   ast.Ref\n\tHasPropertyKeyComment bool // If true, a preceding comment contains \"@__KEY__\"\n}\n\ntype EJSXElement struct {\n\tTagOrNil   Expr\n\tProperties []Property\n\n\t// Note: This array may contain nil entries. Be careful about nil entries\n\t// when iterating over this array.\n\t//\n\t// Each nil entry corresponds to the \"JSXChildExpression_opt\" part of the\n\t// grammar (https://facebook.github.io/jsx/#prod-JSXChild):\n\t//\n\t//   JSXChild :\n\t//       JSXText\n\t//       JSXElement\n\t//       JSXFragment\n\t//       { JSXChildExpression_opt }\n\t//\n\t// This is the \"{}\" part in \"<a>{}</a>\". We allow this because some people\n\t// put comments there and then expect to be able to process them from\n\t// esbuild's output. These absent AST nodes are completely omitted when\n\t// JSX is transformed to JS. They are only present when JSX preservation is\n\t// enabled.\n\tNullableChildren []Expr\n\n\tCloseLoc        logger.Loc\n\tIsTagSingleLine bool\n}\n\n// The JSX specification doesn't say how JSX text is supposed to be interpreted\n// so our \"preserve\" JSX transform should reproduce the original source code\n// verbatim. One reason why this matters is because there is no canonical way\n// to interpret JSX text (Babel and TypeScript differ in what newlines mean).\n// Another reason is that some people want to do custom things such as this:\n// https://github.com/evanw/esbuild/issues/3605\ntype EJSXText struct {\n\tRaw string\n}\n\ntype ENumber struct{ Value float64 }\n\ntype EBigInt struct{ Value string }\n\ntype EObject struct {\n\tProperties       []Property\n\tCommaAfterSpread logger.Loc\n\tCloseBraceLoc    logger.Loc\n\tIsSingleLine     bool\n\tIsParenthesized  bool\n}\n\ntype ESpread struct{ Value Expr }\n\n// This is used for both strings and no-substitution template literals to reduce\n// the number of cases that need to be checked for string optimization code\ntype EString struct {\n\tValue                 []uint16\n\tLegacyOctalLoc        logger.Loc\n\tPreferTemplate        bool\n\tHasPropertyKeyComment bool // If true, a preceding comment contains \"@__KEY__\"\n\tContainsUniqueKey     bool // If true, this string must not be wrapped\n}\n\ntype TemplatePart struct {\n\tValue      Expr\n\tTailRaw    string   // Only use when \"TagOrNil\" is not nil\n\tTailCooked []uint16 // Only use when \"TagOrNil\" is nil\n\tTailLoc    logger.Loc\n}\n\ntype ETemplate struct {\n\tTagOrNil       Expr\n\tHeadRaw        string   // Only use when \"TagOrNil\" is not nil\n\tHeadCooked     []uint16 // Only use when \"TagOrNil\" is nil\n\tParts          []TemplatePart\n\tHeadLoc        logger.Loc\n\tLegacyOctalLoc logger.Loc\n\n\t// True if this is a tagged template literal with a comment that indicates\n\t// this function call can be removed if the result is unused. Note that the\n\t// arguments are not considered to be part of the call. If the call itself\n\t// is removed due to this annotation, the arguments must remain if they have\n\t// side effects (including the string conversions).\n\tCanBeUnwrappedIfUnused bool\n\n\t// If the tag is present, it is expected to be a function and is called. If\n\t// the tag is a syntactic property access, then the value for \"this\" in the\n\t// function call is the object whose property was accessed (e.g. in \"a.b``\"\n\t// the value for \"this\" in \"a.b\" is \"a\"). We need to ensure that if \"a``\"\n\t// ever becomes \"b.c``\" later on due to optimizations, it is written as\n\t// \"(0, b.c)``\" to avoid a behavior change.\n\tTagWasOriginallyPropertyAccess bool\n}\n\ntype ERegExp struct{ Value string }\n\ntype EInlinedEnum struct {\n\tValue   Expr\n\tComment string\n}\n\ntype AnnotationFlags uint8\n\nconst (\n\t// This is sort of like an IIFE with a \"/* @__PURE__ */\" comment except it's an\n\t// inline annotation on an expression itself without the nested scope. Sometimes\n\t// we can't easily introduce a new scope (e.g. if the expression uses \"await\").\n\tCanBeRemovedIfUnusedFlag AnnotationFlags = 1 << iota\n)\n\nfunc (flags AnnotationFlags) Has(flag AnnotationFlags) bool {\n\treturn (flags & flag) != 0\n}\n\ntype EAnnotation struct {\n\tValue Expr\n\tFlags AnnotationFlags\n}\n\ntype EAwait struct {\n\tValue Expr\n}\n\ntype EYield struct {\n\tValueOrNil Expr\n\tIsStar     bool\n}\n\ntype EIf struct {\n\tTest Expr\n\tYes  Expr\n\tNo   Expr\n}\n\ntype ERequireString struct {\n\tImportRecordIndex uint32\n\tCloseParenLoc     logger.Loc\n}\n\ntype ERequireResolveString struct {\n\tImportRecordIndex uint32\n\tCloseParenLoc     logger.Loc\n}\n\ntype EImportString struct {\n\tImportRecordIndex uint32\n\tCloseParenLoc     logger.Loc\n}\n\ntype EImportCall struct {\n\tExpr          Expr\n\tOptionsOrNil  Expr\n\tCloseParenLoc logger.Loc\n\tPhase         ast.ImportPhase\n}\n\ntype Stmt struct {\n\tData S\n\tLoc  logger.Loc\n}\n\n// This interface is never called. Its purpose is to encode a variant type in\n// Go's type system.\ntype S interface{ isStmt() }\n\nfunc (*SBlock) isStmt()         {}\nfunc (*SComment) isStmt()       {}\nfunc (*SDebugger) isStmt()      {}\nfunc (*SDirective) isStmt()     {}\nfunc (*SEmpty) isStmt()         {}\nfunc (*STypeScript) isStmt()    {}\nfunc (*SExportClause) isStmt()  {}\nfunc (*SExportFrom) isStmt()    {}\nfunc (*SExportDefault) isStmt() {}\nfunc (*SExportStar) isStmt()    {}\nfunc (*SExportEquals) isStmt()  {}\nfunc (*SLazyExport) isStmt()    {}\nfunc (*SExpr) isStmt()          {}\nfunc (*SEnum) isStmt()          {}\nfunc (*SNamespace) isStmt()     {}\nfunc (*SFunction) isStmt()      {}\nfunc (*SClass) isStmt()         {}\nfunc (*SLabel) isStmt()         {}\nfunc (*SIf) isStmt()            {}\nfunc (*SFor) isStmt()           {}\nfunc (*SForIn) isStmt()         {}\nfunc (*SForOf) isStmt()         {}\nfunc (*SDoWhile) isStmt()       {}\nfunc (*SWhile) isStmt()         {}\nfunc (*SWith) isStmt()          {}\nfunc (*STry) isStmt()           {}\nfunc (*SSwitch) isStmt()        {}\nfunc (*SImport) isStmt()        {}\nfunc (*SReturn) isStmt()        {}\nfunc (*SThrow) isStmt()         {}\nfunc (*SLocal) isStmt()         {}\nfunc (*SBreak) isStmt()         {}\nfunc (*SContinue) isStmt()      {}\n\ntype SBlock struct {\n\tStmts         []Stmt\n\tCloseBraceLoc logger.Loc\n}\n\ntype SEmpty struct{}\n\n// This is a stand-in for a TypeScript type declaration\ntype STypeScript struct {\n\tWasDeclareClass bool\n}\n\ntype SComment struct {\n\tText           string\n\tIsLegalComment bool\n}\n\ntype SDebugger struct{}\n\ntype SDirective struct {\n\tValue          []uint16\n\tLegacyOctalLoc logger.Loc\n}\n\ntype SExportClause struct {\n\tItems        []ClauseItem\n\tIsSingleLine bool\n}\n\ntype SExportFrom struct {\n\tItems             []ClauseItem\n\tNamespaceRef      ast.Ref\n\tImportRecordIndex uint32\n\tIsSingleLine      bool\n}\n\ntype SExportDefault struct {\n\tValue       Stmt // May be a SExpr or SFunction or SClass\n\tDefaultName ast.LocRef\n}\n\ntype ExportStarAlias struct {\n\t// Although this alias name starts off as being the same as the statement's\n\t// namespace symbol, it may diverge if the namespace symbol name is minified.\n\t// The original alias name is preserved here to avoid this scenario.\n\tOriginalName string\n\n\tLoc logger.Loc\n}\n\ntype SExportStar struct {\n\tAlias             *ExportStarAlias\n\tNamespaceRef      ast.Ref\n\tImportRecordIndex uint32\n}\n\n// This is an \"export = value;\" statement in TypeScript\ntype SExportEquals struct {\n\tValue Expr\n}\n\n// The decision of whether to export an expression using \"module.exports\" or\n// \"export default\" is deferred until linking using this statement kind\ntype SLazyExport struct {\n\tValue Expr\n}\n\ntype SExpr struct {\n\tValue Expr\n\n\t// This is set to true for automatically-generated expressions that are part\n\t// of class syntax lowering. A single class declaration may end up with many\n\t// generated expressions after it (e.g. class field initializations, a call\n\t// to keep the original value of the \"name\" property). When this happens we\n\t// can't tell that the class is side-effect free anymore because all of these\n\t// methods mutate the class. We use this annotation for that instead.\n\tIsFromClassOrFnThatCanBeRemovedIfUnused bool\n}\n\ntype EnumValue struct {\n\tValueOrNil Expr\n\tName       []uint16\n\tRef        ast.Ref\n\tLoc        logger.Loc\n}\n\ntype SEnum struct {\n\tValues   []EnumValue\n\tName     ast.LocRef\n\tArg      ast.Ref\n\tIsExport bool\n}\n\ntype SNamespace struct {\n\tStmts    []Stmt\n\tName     ast.LocRef\n\tArg      ast.Ref\n\tIsExport bool\n}\n\ntype SFunction struct {\n\tFn       Fn\n\tIsExport bool\n}\n\ntype SClass struct {\n\tClass    Class\n\tIsExport bool\n}\n\ntype SLabel struct {\n\tStmt             Stmt\n\tName             ast.LocRef\n\tIsSingleLineStmt bool\n}\n\ntype SIf struct {\n\tTest            Expr\n\tYes             Stmt\n\tNoOrNil         Stmt\n\tIsSingleLineYes bool\n\tIsSingleLineNo  bool\n}\n\ntype SFor struct {\n\tInitOrNil         Stmt // May be a SConst, SLet, SVar, or SExpr\n\tTestOrNil         Expr\n\tUpdateOrNil       Expr\n\tBody              Stmt\n\tIsSingleLineBody  bool\n\tIsLoweredForAwait bool\n}\n\ntype SForIn struct {\n\tInit             Stmt // May be a SConst, SLet, SVar, or SExpr\n\tValue            Expr\n\tBody             Stmt\n\tIsSingleLineBody bool\n}\n\ntype SForOf struct {\n\tInit             Stmt // May be a SConst, SLet, SVar, or SExpr\n\tValue            Expr\n\tBody             Stmt\n\tAwait            logger.Range\n\tIsSingleLineBody bool\n}\n\ntype SDoWhile struct {\n\tBody Stmt\n\tTest Expr\n}\n\ntype SWhile struct {\n\tTest             Expr\n\tBody             Stmt\n\tIsSingleLineBody bool\n}\n\ntype SWith struct {\n\tValue            Expr\n\tBody             Stmt\n\tBodyLoc          logger.Loc\n\tIsSingleLineBody bool\n}\n\ntype Catch struct {\n\tBindingOrNil Binding\n\tBlock        SBlock\n\tLoc          logger.Loc\n\tBlockLoc     logger.Loc\n}\n\ntype Finally struct {\n\tBlock SBlock\n\tLoc   logger.Loc\n}\n\ntype STry struct {\n\tCatch    *Catch\n\tFinally  *Finally\n\tBlock    SBlock\n\tBlockLoc logger.Loc\n}\n\ntype Case struct {\n\tValueOrNil Expr // If this is nil, this is \"default\" instead of \"case\"\n\tBody       []Stmt\n\tLoc        logger.Loc\n}\n\ntype SSwitch struct {\n\tTest          Expr\n\tCases         []Case\n\tBodyLoc       logger.Loc\n\tCloseBraceLoc logger.Loc\n}\n\n// This object represents all of these types of import statements:\n//\n//\timport 'path'\n//\timport {item1, item2} from 'path'\n//\timport * as ns from 'path'\n//\timport defaultItem, {item1, item2} from 'path'\n//\timport defaultItem, * as ns from 'path'\n//\n// Many parts are optional and can be combined in different ways. The only\n// restriction is that you cannot have both a clause and a star namespace.\ntype SImport struct {\n\tDefaultName *ast.LocRef\n\tItems       *[]ClauseItem\n\tStarNameLoc *logger.Loc\n\n\t// If this is a star import: This is a Ref for the namespace symbol. The Loc\n\t// for the symbol is StarLoc.\n\t//\n\t// Otherwise: This is an auto-generated Ref for the namespace representing\n\t// the imported file. In this case StarLoc is nil. The NamespaceRef is used\n\t// when converting this module to a CommonJS module.\n\tNamespaceRef ast.Ref\n\n\tImportRecordIndex uint32\n\tIsSingleLine      bool\n}\n\ntype SReturn struct {\n\tValueOrNil Expr\n}\n\ntype SThrow struct {\n\tValue Expr\n}\n\ntype LocalKind uint8\n\nconst (\n\tLocalVar LocalKind = iota\n\tLocalLet\n\tLocalConst\n\tLocalUsing\n\tLocalAwaitUsing\n)\n\nfunc (kind LocalKind) IsUsing() bool {\n\treturn kind >= LocalUsing\n}\n\ntype SLocal struct {\n\tDecls    []Decl\n\tKind     LocalKind\n\tIsExport bool\n\n\t// The TypeScript compiler doesn't generate code for \"import foo = bar\"\n\t// statements where the import is never used.\n\tWasTSImportEquals bool\n}\n\ntype SBreak struct {\n\tLabel *ast.LocRef\n}\n\ntype SContinue struct {\n\tLabel *ast.LocRef\n}\n\ntype ClauseItem struct {\n\tAlias string\n\n\t// This is the original name of the symbol stored in \"Name\". It's needed for\n\t// \"SExportClause\" statements such as this:\n\t//\n\t//   export {foo as bar} from 'path'\n\t//\n\t// In this case both \"foo\" and \"bar\" are aliases because it's a re-export.\n\t// We need to preserve both aliases in case the symbol is renamed. In this\n\t// example, \"foo\" is \"OriginalName\" and \"bar\" is \"Alias\".\n\tOriginalName string\n\n\tAliasLoc logger.Loc\n\tName     ast.LocRef\n}\n\ntype Decl struct {\n\tBinding    Binding\n\tValueOrNil Expr\n}\n\ntype ScopeKind uint8\n\nconst (\n\tScopeBlock ScopeKind = iota\n\tScopeWith\n\tScopeLabel\n\tScopeClassName\n\tScopeClassBody\n\tScopeCatchBinding\n\n\t// The scopes below stop hoisted variables from extending into parent scopes\n\tScopeEntry // This is a module, TypeScript enum, or TypeScript namespace\n\tScopeFunctionArgs\n\tScopeFunctionBody\n\tScopeClassStaticInit\n)\n\nfunc (kind ScopeKind) StopsHoisting() bool {\n\treturn kind >= ScopeEntry\n}\n\ntype ScopeMember struct {\n\tRef ast.Ref\n\tLoc logger.Loc\n}\n\ntype Scope struct {\n\t// This will be non-nil if this is a TypeScript \"namespace\" or \"enum\"\n\tTSNamespace *TSNamespaceScope\n\n\tParent    *Scope\n\tChildren  []*Scope\n\tMembers   map[string]ScopeMember\n\tReplaced  []ScopeMember\n\tGenerated []ast.Ref\n\n\t// The location of the \"use strict\" directive for ExplicitStrictMode\n\tUseStrictLoc logger.Loc\n\n\t// This is used to store the ref of the label symbol for ScopeLabel scopes.\n\tLabel           ast.LocRef\n\tLabelStmtIsLoop bool\n\n\t// If a scope contains a direct eval() expression, then none of the symbols\n\t// inside that scope can be renamed. We conservatively assume that the\n\t// evaluated code might reference anything that it has access to.\n\tContainsDirectEval bool\n\n\t// This is to help forbid \"arguments\" inside class body scopes\n\tForbidArguments bool\n\n\t// As a special case, we enable constant propagation for any chain of \"const\"\n\t// declarations at the start of a statement list. This special case doesn't\n\t// have any TDZ considerations because no other statements come before it.\n\tIsAfterConstLocalPrefix bool\n\n\tStrictMode StrictModeKind\n\tKind       ScopeKind\n}\n\ntype StrictModeKind uint8\n\nconst (\n\tSloppyMode StrictModeKind = iota\n\tExplicitStrictMode\n\tImplicitStrictModeClass\n\tImplicitStrictModeESM\n\tImplicitStrictModeTSAlwaysStrict\n\tImplicitStrictModeJSXAutomaticRuntime\n)\n\nfunc (s *Scope) RecursiveSetStrictMode(kind StrictModeKind) {\n\tif s.StrictMode == SloppyMode {\n\t\ts.StrictMode = kind\n\t\tfor _, child := range s.Children {\n\t\t\tchild.RecursiveSetStrictMode(kind)\n\t\t}\n\t}\n}\n\n// This is for TypeScript \"enum\" and \"namespace\" blocks. Each block can\n// potentially be instantiated multiple times. The exported members of each\n// block are merged into a single namespace while the non-exported code is\n// still scoped to just within that block:\n//\n//\tlet x = 1;\n//\tnamespace Foo {\n//\t  let x = 2;\n//\t  export let y = 3;\n//\t}\n//\tnamespace Foo {\n//\t  console.log(x); // 1\n//\t  console.log(y); // 3\n//\t}\n//\n// Doing this also works inside an enum:\n//\n//\tenum Foo {\n//\t  A = 3,\n//\t  B = A + 1,\n//\t}\n//\tenum Foo {\n//\t  C = A + 2,\n//\t}\n//\tconsole.log(Foo.B) // 4\n//\tconsole.log(Foo.C) // 5\n//\n// This is a form of identifier lookup that works differently than the\n// hierarchical scope-based identifier lookup in JavaScript. Lookup now needs\n// to search sibling scopes in addition to parent scopes. This is accomplished\n// by sharing the map of exported members between all matching sibling scopes.\ntype TSNamespaceScope struct {\n\t// This is shared between all sibling namespace blocks\n\tExportedMembers TSNamespaceMembers\n\n\t// This is a lazily-generated map of identifiers that actually represent\n\t// property accesses to this namespace's properties. For example:\n\t//\n\t//   namespace x {\n\t//     export let y = 123\n\t//   }\n\t//   namespace x {\n\t//     export let z = y\n\t//   }\n\t//\n\t// This should be compiled into the following code:\n\t//\n\t//   var x;\n\t//   (function(x2) {\n\t//     x2.y = 123;\n\t//   })(x || (x = {}));\n\t//   (function(x3) {\n\t//     x3.z = x3.y;\n\t//   })(x || (x = {}));\n\t//\n\t// When we try to find the symbol \"y\", we instead return one of these lazily\n\t// generated proxy symbols that represent the property access \"x3.y\". This\n\t// map is unique per namespace block because \"x3\" is the argument symbol that\n\t// is specific to that particular namespace block.\n\tLazilyGeneratedProperyAccesses map[string]ast.Ref\n\n\t// This is specific to this namespace block. It's the argument of the\n\t// immediately-invoked function expression that the namespace block is\n\t// compiled into:\n\t//\n\t//   var ns;\n\t//   (function (ns2) {\n\t//     ns2.x = 123;\n\t//   })(ns || (ns = {}));\n\t//\n\t// This variable is \"ns2\" in the above example. It's the symbol to use when\n\t// generating property accesses off of this namespace when it's in scope.\n\tArgRef ast.Ref\n\n\t// Even though enums are like namespaces and both enums and namespaces allow\n\t// implicit references to properties of sibling scopes, they behave like\n\t// separate, er, namespaces. Implicit references only work namespace-to-\n\t// namespace and enum-to-enum. They do not work enum-to-namespace. And I'm\n\t// not sure what's supposed to happen for the namespace-to-enum case because\n\t// the compiler crashes: https://github.com/microsoft/TypeScript/issues/46891.\n\t// So basically these both work:\n\t//\n\t//   enum a { b = 1 }\n\t//   enum a { c = b }\n\t//\n\t//   namespace x { export let y = 1 }\n\t//   namespace x { export let z = y }\n\t//\n\t// This doesn't work:\n\t//\n\t//   enum a { b = 1 }\n\t//   namespace a { export let c = b }\n\t//\n\t// And this crashes the TypeScript compiler:\n\t//\n\t//   namespace a { export let b = 1 }\n\t//   enum a { c = b }\n\t//\n\t// Therefore we only allow enum/enum and namespace/namespace interactions.\n\tIsEnumScope bool\n}\n\ntype TSNamespaceMembers map[string]TSNamespaceMember\n\ntype TSNamespaceMember struct {\n\tData        TSNamespaceMemberData\n\tLoc         logger.Loc\n\tIsEnumValue bool\n}\n\ntype TSNamespaceMemberData interface {\n\tisTSNamespaceMember()\n}\n\nfunc (TSNamespaceMemberProperty) isTSNamespaceMember()   {}\nfunc (TSNamespaceMemberNamespace) isTSNamespaceMember()  {}\nfunc (TSNamespaceMemberEnumNumber) isTSNamespaceMember() {}\nfunc (TSNamespaceMemberEnumString) isTSNamespaceMember() {}\n\n// \"namespace ns { export let it }\"\ntype TSNamespaceMemberProperty struct{}\n\n// \"namespace ns { export namespace it {} }\"\ntype TSNamespaceMemberNamespace struct {\n\tExportedMembers TSNamespaceMembers\n}\n\n// \"enum ns { it }\"\ntype TSNamespaceMemberEnumNumber struct {\n\tValue float64\n}\n\n// \"enum ns { it = 'it' }\"\ntype TSNamespaceMemberEnumString struct {\n\tValue []uint16\n}\n\ntype ExportsKind uint8\n\nconst (\n\t// This file doesn't have any kind of export, so it's impossible to say what\n\t// kind of file this is. An empty file is in this category, for example.\n\tExportsNone ExportsKind = iota\n\n\t// The exports are stored on \"module\" and/or \"exports\". Calling \"require()\"\n\t// on this module returns \"module.exports\". All imports to this module are\n\t// allowed but may return undefined.\n\tExportsCommonJS\n\n\t// All export names are known explicitly. Calling \"require()\" on this module\n\t// generates an exports object (stored in \"exports\") with getters for the\n\t// export names. Named imports to this module are only allowed if they are\n\t// in the set of export names.\n\tExportsESM\n\n\t// Some export names are known explicitly, but others fall back to a dynamic\n\t// run-time object. This is necessary when using the \"export * from\" syntax\n\t// with either a CommonJS module or an external module (i.e. a module whose\n\t// export names are not known at compile-time).\n\t//\n\t// Calling \"require()\" on this module generates an exports object (stored in\n\t// \"exports\") with getters for the export names. All named imports to this\n\t// module are allowed. Direct named imports reference the corresponding export\n\t// directly. Other imports go through property accesses on \"exports\".\n\tExportsESMWithDynamicFallback\n)\n\nfunc (kind ExportsKind) IsDynamic() bool {\n\treturn kind == ExportsCommonJS || kind == ExportsESMWithDynamicFallback\n}\n\ntype ModuleType uint8\n\nconst (\n\tModuleUnknown ModuleType = iota\n\n\t// \".cjs\" or \".cts\" or \"type: commonjs\" in package.json\n\tModuleCommonJS_CJS\n\tModuleCommonJS_CTS\n\tModuleCommonJS_PackageJSON\n\n\t// \".mjs\" or \".mts\" or \"type: module\" in package.json\n\tModuleESM_MJS\n\tModuleESM_MTS\n\tModuleESM_PackageJSON\n)\n\nfunc (mt ModuleType) IsCommonJS() bool {\n\treturn mt >= ModuleCommonJS_CJS && mt <= ModuleCommonJS_PackageJSON\n}\n\nfunc (mt ModuleType) IsESM() bool {\n\treturn mt >= ModuleESM_MJS && mt <= ModuleESM_PackageJSON\n}\n\ntype ModuleTypeData struct {\n\tSource *logger.Source\n\tRange  logger.Range\n\tType   ModuleType\n}\n\n// This is the index to the automatically-generated part containing code that\n// calls \"__export(exports, { ... getters ... })\". This is used to generate\n// getters on an exports object for ES6 export statements, and is both for\n// ES6 star imports and CommonJS-style modules. All files have one of these,\n// although it may contain no statements if there is nothing to export.\nconst NSExportPartIndex = uint32(0)\n\ntype AST struct {\n\tModuleTypeData ModuleTypeData\n\tParts          []Part\n\tSymbols        []ast.Symbol\n\tExprComments   map[logger.Loc][]string\n\tModuleScope    *Scope\n\tCharFreq       *ast.CharFreq\n\n\t// This is internal-only data used for the implementation of Yarn PnP\n\tManifestForYarnPnP Expr\n\n\tHashbang   string\n\tDirectives []string\n\tURLForCSS  string\n\n\t// Note: If you're in the linker, do not use this map directly. This map is\n\t// filled in by the parser and is considered immutable. For performance reasons,\n\t// the linker doesn't mutate this map (cloning a map is slow in Go). Instead the\n\t// linker super-imposes relevant information on top in a method call. You should\n\t// call \"TopLevelSymbolToParts\" instead.\n\tTopLevelSymbolToPartsFromParser map[ast.Ref][]uint32\n\n\t// This contains all top-level exported TypeScript enum constants. It exists\n\t// to enable cross-module inlining of constant enums.\n\tTSEnums map[ast.Ref]map[string]TSEnumValue\n\n\t// This contains the values of all detected inlinable constants. It exists\n\t// to enable cross-module inlining of these constants.\n\tConstValues map[ast.Ref]ConstValue\n\n\t// Properties in here are represented as symbols instead of strings, which\n\t// allows them to be renamed to smaller names.\n\tMangledProps map[string]ast.Ref\n\n\t// Properties in here are existing non-mangled properties in the source code\n\t// and must not be used when generating mangled names to avoid a collision.\n\tReservedProps map[string]bool\n\n\t// These are stored at the AST level instead of on individual AST nodes so\n\t// they can be manipulated efficiently without a full AST traversal\n\tImportRecords []ast.ImportRecord\n\n\t// These are used when bundling. They are filled in during the parser pass\n\t// since we already have to traverse the AST then anyway and the parser pass\n\t// is conveniently fully parallelized.\n\tNamedImports            map[ast.Ref]NamedImport\n\tNamedExports            map[string]NamedExport\n\tExportStarImportRecords []uint32\n\n\tSourceMapComment logger.Span\n\n\t// This is a list of ES6 features. They are ranges instead of booleans so\n\t// that they can be used in log messages. Check to see if \"Len > 0\".\n\tExportKeyword            logger.Range // Does not include TypeScript-specific syntax\n\tTopLevelAwaitKeyword     logger.Range\n\tLiveTopLevelAwaitKeyword logger.Range // Excludes top-level await in dead branches\n\n\tExportsRef ast.Ref\n\tModuleRef  ast.Ref\n\tWrapperRef ast.Ref\n\n\tApproximateLineCount  int32\n\tNestedScopeSlotCounts ast.SlotCounts\n\tHasLazyExport         bool\n\n\t// This is a list of CommonJS features. When a file uses CommonJS features,\n\t// it's not a candidate for \"flat bundling\" and must be wrapped in its own\n\t// closure. Note that this also includes top-level \"return\" but these aren't\n\t// here because only the parser checks those.\n\tUsesExportsRef bool\n\tUsesModuleRef  bool\n\tExportsKind    ExportsKind\n}\n\ntype TSEnumValue struct {\n\tString []uint16 // Use this if it's not nil\n\tNumber float64  // Use this if \"String\" is nil\n}\n\ntype ConstValueKind uint8\n\nconst (\n\tConstValueNone ConstValueKind = iota\n\tConstValueNull\n\tConstValueUndefined\n\tConstValueTrue\n\tConstValueFalse\n\tConstValueNumber\n\tConstValueString\n)\n\ntype ConstValue struct {\n\tNumber float64  // Use this for \"ConstValueNumber\"\n\tString []uint16 // Use this for \"ConstValueString\"\n\tKind   ConstValueKind\n}\n\nfunc ExprToConstValue(expr Expr) ConstValue {\n\tswitch v := expr.Data.(type) {\n\tcase *ENull:\n\t\treturn ConstValue{Kind: ConstValueNull}\n\n\tcase *EUndefined:\n\t\treturn ConstValue{Kind: ConstValueUndefined}\n\n\tcase *EBoolean:\n\t\tif v.Value {\n\t\t\treturn ConstValue{Kind: ConstValueTrue}\n\t\t} else {\n\t\t\treturn ConstValue{Kind: ConstValueFalse}\n\t\t}\n\n\tcase *ENumber:\n\t\t// Inline integers and other small numbers. Don't inline large\n\t\t// real numbers because people may not want them to be inlined\n\t\t// as it will increase the minified code size by too much.\n\t\tif asInt := int64(v.Value); v.Value == float64(asInt) || len(strconv.FormatFloat(v.Value, 'g', -1, 64)) <= 8 {\n\t\t\treturn ConstValue{Kind: ConstValueNumber, Number: v.Value}\n\t\t}\n\n\tcase *EString:\n\t\t// Deliberately only inline small strings. We don't want to always\n\t\t// inline all strings because they can be arbitrarily long.\n\t\tif len(v.Value) <= 3 {\n\t\t\treturn ConstValue{Kind: ConstValueString, String: v.Value}\n\t\t}\n\n\tcase *EBigInt:\n\t\t// I'm deliberately not inlining bigints here for the same reason (they can\n\t\t// be arbitrarily long).\n\t}\n\n\treturn ConstValue{}\n}\n\nfunc ConstValueToExpr(loc logger.Loc, value ConstValue) Expr {\n\tswitch value.Kind {\n\tcase ConstValueNull:\n\t\treturn Expr{Loc: loc, Data: ENullShared}\n\n\tcase ConstValueUndefined:\n\t\treturn Expr{Loc: loc, Data: EUndefinedShared}\n\n\tcase ConstValueTrue:\n\t\treturn Expr{Loc: loc, Data: &EBoolean{Value: true}}\n\n\tcase ConstValueFalse:\n\t\treturn Expr{Loc: loc, Data: &EBoolean{Value: false}}\n\n\tcase ConstValueNumber:\n\t\treturn Expr{Loc: loc, Data: &ENumber{Value: value.Number}}\n\n\tcase ConstValueString:\n\t\treturn Expr{Loc: loc, Data: &EString{Value: value.String}}\n\t}\n\n\tpanic(\"Internal error: invalid constant value\")\n}\n\ntype NamedImport struct {\n\tAlias string\n\n\t// Parts within this file that use this import\n\tLocalPartsWithUses []uint32\n\n\tAliasLoc          logger.Loc\n\tNamespaceRef      ast.Ref\n\tImportRecordIndex uint32\n\n\t// If true, the alias refers to the entire export namespace object of a\n\t// module. This is no longer represented as an alias called \"*\" because of\n\t// the upcoming \"Arbitrary module namespace identifier names\" feature:\n\t// https://github.com/tc39/ecma262/pull/2154\n\tAliasIsStar bool\n\n\t// It's useful to flag exported imports because if they are in a TypeScript\n\t// file, we can't tell if they are a type or a value.\n\tIsExported bool\n}\n\ntype NamedExport struct {\n\tRef      ast.Ref\n\tAliasLoc logger.Loc\n}\n\n// Each file is made up of multiple parts, and each part consists of one or\n// more top-level statements. Parts are used for tree shaking and code\n// splitting analysis. Individual parts of a file can be discarded by tree\n// shaking and can be assigned to separate chunks (i.e. output files) by code\n// splitting.\ntype Part struct {\n\tStmts  []Stmt\n\tScopes []*Scope\n\n\t// Each is an index into the file-level import record list\n\tImportRecordIndices []uint32\n\n\t// All symbols that are declared in this part. Note that a given symbol may\n\t// have multiple declarations, and so may end up being declared in multiple\n\t// parts (e.g. multiple \"var\" declarations with the same name). Also note\n\t// that this list isn't deduplicated and may contain duplicates.\n\tDeclaredSymbols []DeclaredSymbol\n\n\t// An estimate of the number of uses of all symbols used within this part.\n\tSymbolUses map[ast.Ref]SymbolUse\n\n\t// An estimate of the number of uses of all symbols used as the target of\n\t// function calls within this part.\n\tSymbolCallUses map[ast.Ref]SymbolCallUse\n\n\t// This tracks property accesses off of imported symbols. We don't know\n\t// during parsing if an imported symbol is going to be an inlined enum\n\t// value or not. This is only known during linking. So we defer adding\n\t// a dependency on these imported symbols until we know whether the\n\t// property access is an inlined enum value or not.\n\tImportSymbolPropertyUses map[ast.Ref]map[string]SymbolUse\n\n\t// The indices of the other parts in this file that are needed if this part\n\t// is needed.\n\tDependencies []Dependency\n\n\t// If true, this part can be removed if none of the declared symbols are\n\t// used. If the file containing this part is imported, then all parts that\n\t// don't have this flag enabled must be included.\n\tCanBeRemovedIfUnused bool\n\n\t// This is used for generated parts that we don't want to be present if they\n\t// aren't needed. This enables tree shaking for these parts even if global\n\t// tree shaking isn't enabled.\n\tForceTreeShaking bool\n\n\t// This is true if this file has been marked as live by the tree shaking\n\t// algorithm.\n\tIsLive bool\n}\n\ntype Dependency struct {\n\tSourceIndex uint32\n\tPartIndex   uint32\n}\n\ntype DeclaredSymbol struct {\n\tRef        ast.Ref\n\tIsTopLevel bool\n}\n\ntype SymbolUse struct {\n\tCountEstimate uint32\n}\n\ntype SymbolCallUse struct {\n\tCallCountEstimate                   uint32\n\tSingleArgNonSpreadCallCountEstimate uint32\n}\n\n// For readability, the names of certain automatically-generated symbols are\n// derived from the file name. For example, instead of the CommonJS wrapper for\n// a file being called something like \"require273\" it can be called something\n// like \"require_react\" instead. This function generates the part of these\n// identifiers that's specific to the file path. It can take both an absolute\n// path (OS-specific) and a path in the source code (OS-independent).\n//\n// Note that these generated names do not at all relate to the correctness of\n// the code as far as avoiding symbol name collisions. These names still go\n// through the renaming logic that all other symbols go through to avoid name\n// collisions.\nfunc GenerateNonUniqueNameFromPath(path string) string {\n\t// Get the file name without the extension\n\tdir, base, _ := logger.PlatformIndependentPathDirBaseExt(path)\n\n\t// If the name is \"index\", use the directory name instead. This is because\n\t// many packages in npm use the file name \"index.js\" because it triggers\n\t// node's implicit module resolution rules that allows you to import it by\n\t// just naming the directory.\n\tif base == \"index\" {\n\t\t_, dirBase, _ := logger.PlatformIndependentPathDirBaseExt(dir)\n\t\tif dirBase != \"\" {\n\t\t\tbase = dirBase\n\t\t}\n\t}\n\n\treturn EnsureValidIdentifier(base)\n}\n\nfunc EnsureValidIdentifier(base string) string {\n\t// Convert it to an ASCII identifier. Note: If you change this to a non-ASCII\n\t// identifier, you're going to potentially cause trouble with non-BMP code\n\t// points in target environments that don't support bracketed Unicode escapes.\n\tbytes := []byte{}\n\tneedsGap := false\n\tfor _, c := range base {\n\t\tif (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (len(bytes) > 0 && c >= '0' && c <= '9') {\n\t\t\tif needsGap {\n\t\t\t\tbytes = append(bytes, '_')\n\t\t\t\tneedsGap = false\n\t\t\t}\n\t\t\tbytes = append(bytes, byte(c))\n\t\t} else if len(bytes) > 0 {\n\t\t\tneedsGap = true\n\t\t}\n\t}\n\n\t// Make sure the name isn't empty\n\tif len(bytes) == 0 {\n\t\treturn \"_\"\n\t}\n\treturn string(bytes)\n}\n"
  },
  {
    "path": "internal/js_ast/js_ast_helpers.go",
    "content": "package js_ast\n\nimport (\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\ntype HelperContext struct {\n\tisUnbound func(ast.Ref) bool\n}\n\nfunc MakeHelperContext(isUnbound func(ast.Ref) bool) HelperContext {\n\treturn HelperContext{\n\t\tisUnbound: isUnbound,\n\t}\n}\n\n// If this returns true, then calling this expression captures the target of\n// the property access as \"this\" when calling the function in the property.\nfunc IsPropertyAccess(expr Expr) bool {\n\tswitch expr.Data.(type) {\n\tcase *EDot, *EIndex:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc IsOptionalChain(value Expr) bool {\n\tswitch e := value.Data.(type) {\n\tcase *EDot:\n\t\treturn e.OptionalChain != OptionalChainNone\n\tcase *EIndex:\n\t\treturn e.OptionalChain != OptionalChainNone\n\tcase *ECall:\n\t\treturn e.OptionalChain != OptionalChainNone\n\t}\n\treturn false\n}\n\nfunc Assign(a Expr, b Expr) Expr {\n\treturn Expr{Loc: a.Loc, Data: &EBinary{Op: BinOpAssign, Left: a, Right: b}}\n}\n\nfunc AssignStmt(a Expr, b Expr) Stmt {\n\treturn Stmt{Loc: a.Loc, Data: &SExpr{Value: Assign(a, b)}}\n}\n\n// Wraps the provided expression in the \"!\" prefix operator. The expression\n// will potentially be simplified to avoid generating unnecessary extra \"!\"\n// operators. For example, calling this with \"!!x\" will return \"!x\" instead\n// of returning \"!!!x\".\nfunc Not(expr Expr) Expr {\n\tif result, ok := MaybeSimplifyNot(expr); ok {\n\t\treturn result\n\t}\n\treturn Expr{Loc: expr.Loc, Data: &EUnary{Op: UnOpNot, Value: expr}}\n}\n\n// The given \"expr\" argument should be the operand of a \"!\" prefix operator\n// (i.e. the \"x\" in \"!x\"). This returns a simplified expression for the\n// whole operator (i.e. the \"!x\") if it can be simplified, or false if not.\n// It's separate from \"Not()\" above to avoid allocation on failure in case\n// that is undesired.\n//\n// This function intentionally avoids mutating the input AST so it can be\n// called after the AST has been frozen (i.e. after parsing ends).\nfunc MaybeSimplifyNot(expr Expr) (Expr, bool) {\n\tswitch e := expr.Data.(type) {\n\tcase *EAnnotation:\n\t\treturn MaybeSimplifyNot(e.Value)\n\n\tcase *EInlinedEnum:\n\t\tif value, ok := MaybeSimplifyNot(e.Value); ok {\n\t\t\treturn value, true\n\t\t}\n\n\tcase *ENull, *EUndefined:\n\t\treturn Expr{Loc: expr.Loc, Data: &EBoolean{Value: true}}, true\n\n\tcase *EBoolean:\n\t\treturn Expr{Loc: expr.Loc, Data: &EBoolean{Value: !e.Value}}, true\n\n\tcase *ENumber:\n\t\treturn Expr{Loc: expr.Loc, Data: &EBoolean{Value: e.Value == 0 || math.IsNaN(e.Value)}}, true\n\n\tcase *EBigInt:\n\t\tif equal, ok := CheckEqualityBigInt(e.Value, \"0\"); ok {\n\t\t\treturn Expr{Loc: expr.Loc, Data: &EBoolean{Value: equal}}, true\n\t\t}\n\n\tcase *EString:\n\t\treturn Expr{Loc: expr.Loc, Data: &EBoolean{Value: len(e.Value) == 0}}, true\n\n\tcase *EFunction, *EArrow, *ERegExp:\n\t\treturn Expr{Loc: expr.Loc, Data: &EBoolean{Value: false}}, true\n\n\tcase *EUnary:\n\t\t// \"!!!a\" => \"!a\"\n\t\tif e.Op == UnOpNot && KnownPrimitiveType(e.Value.Data) == PrimitiveBoolean {\n\t\t\treturn e.Value, true\n\t\t}\n\n\tcase *EBinary:\n\t\t// Make sure that these transformations are all safe for special values.\n\t\t// For example, \"!(a < b)\" is not the same as \"a >= b\" if a and/or b are\n\t\t// NaN (or undefined, or null, or possibly other problem cases too).\n\t\tswitch e.Op {\n\t\tcase BinOpLooseEq:\n\t\t\t// \"!(a == b)\" => \"a != b\"\n\t\t\treturn Expr{Loc: expr.Loc, Data: &EBinary{Op: BinOpLooseNe, Left: e.Left, Right: e.Right}}, true\n\n\t\tcase BinOpLooseNe:\n\t\t\t// \"!(a != b)\" => \"a == b\"\n\t\t\treturn Expr{Loc: expr.Loc, Data: &EBinary{Op: BinOpLooseEq, Left: e.Left, Right: e.Right}}, true\n\n\t\tcase BinOpStrictEq:\n\t\t\t// \"!(a === b)\" => \"a !== b\"\n\t\t\treturn Expr{Loc: expr.Loc, Data: &EBinary{Op: BinOpStrictNe, Left: e.Left, Right: e.Right}}, true\n\n\t\tcase BinOpStrictNe:\n\t\t\t// \"!(a !== b)\" => \"a === b\"\n\t\t\treturn Expr{Loc: expr.Loc, Data: &EBinary{Op: BinOpStrictEq, Left: e.Left, Right: e.Right}}, true\n\n\t\tcase BinOpComma:\n\t\t\t// \"!(a, b)\" => \"a, !b\"\n\t\t\treturn Expr{Loc: expr.Loc, Data: &EBinary{Op: BinOpComma, Left: e.Left, Right: Not(e.Right)}}, true\n\t\t}\n\t}\n\n\treturn Expr{}, false\n}\n\n// This function intentionally avoids mutating the input AST so it can be\n// called after the AST has been frozen (i.e. after parsing ends).\nfunc MaybeSimplifyEqualityComparison(loc logger.Loc, e *EBinary, unsupportedFeatures compat.JSFeature) (Expr, bool) {\n\tvalue, primitive := e.Left, e.Right\n\n\t// Detect when the primitive comes first and flip the order of our checks\n\tif IsPrimitiveLiteral(value.Data) {\n\t\tvalue, primitive = primitive, value\n\t}\n\n\t// \"!x === true\" => \"!x\"\n\t// \"!x === false\" => \"!!x\"\n\t// \"!x !== true\" => \"!!x\"\n\t// \"!x !== false\" => \"!x\"\n\tif boolean, ok := primitive.Data.(*EBoolean); ok && KnownPrimitiveType(value.Data) == PrimitiveBoolean {\n\t\tif boolean.Value == (e.Op == BinOpLooseNe || e.Op == BinOpStrictNe) {\n\t\t\treturn Not(value), true\n\t\t} else {\n\t\t\treturn value, true\n\t\t}\n\t}\n\n\t// \"typeof x != 'undefined'\" => \"typeof x < 'u'\"\n\t// \"typeof x == 'undefined'\" => \"typeof x > 'u'\"\n\tif !unsupportedFeatures.Has(compat.TypeofExoticObjectIsObject) {\n\t\t// Only do this optimization if we know that the \"typeof\" operator won't\n\t\t// return something random. The only case of this happening was Internet\n\t\t// Explorer returning \"unknown\" for some objects, which messes with this\n\t\t// optimization. So we don't do this when targeting Internet Explorer.\n\t\tif typeof, ok := value.Data.(*EUnary); ok && typeof.Op == UnOpTypeof {\n\t\t\tif str, ok := primitive.Data.(*EString); ok && helpers.UTF16EqualsString(str.Value, \"undefined\") {\n\t\t\t\tflip := value == e.Right\n\t\t\t\top := BinOpLt\n\t\t\t\tif (e.Op == BinOpLooseEq || e.Op == BinOpStrictEq) != flip {\n\t\t\t\t\top = BinOpGt\n\t\t\t\t}\n\t\t\t\tprimitive.Data = &EString{Value: []uint16{'u'}}\n\t\t\t\tif flip {\n\t\t\t\t\tvalue, primitive = primitive, value\n\t\t\t\t}\n\t\t\t\treturn Expr{Loc: loc, Data: &EBinary{Op: op, Left: value, Right: primitive}}, true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn Expr{}, false\n}\n\nfunc IsSymbolInstance(data E) bool {\n\tswitch e := data.(type) {\n\tcase *EDot:\n\t\treturn e.IsSymbolInstance\n\n\tcase *EIndex:\n\t\treturn e.IsSymbolInstance\n\t}\n\treturn false\n}\n\nfunc IsPrimitiveLiteral(data E) bool {\n\tswitch e := data.(type) {\n\tcase *EAnnotation:\n\t\treturn IsPrimitiveLiteral(e.Value.Data)\n\n\tcase *EInlinedEnum:\n\t\treturn IsPrimitiveLiteral(e.Value.Data)\n\n\tcase *ENull, *EUndefined, *EString, *EBoolean, *ENumber, *EBigInt:\n\t\treturn true\n\t}\n\treturn false\n}\n\ntype PrimitiveType uint8\n\nconst (\n\tPrimitiveUnknown PrimitiveType = iota\n\tPrimitiveMixed\n\tPrimitiveNull\n\tPrimitiveUndefined\n\tPrimitiveBoolean\n\tPrimitiveNumber\n\tPrimitiveString\n\tPrimitiveBigInt\n)\n\n// This can be used when the returned type is either one or the other\nfunc MergedKnownPrimitiveTypes(a Expr, b Expr) PrimitiveType {\n\tx := KnownPrimitiveType(a.Data)\n\tif x == PrimitiveUnknown {\n\t\treturn PrimitiveUnknown\n\t}\n\n\ty := KnownPrimitiveType(b.Data)\n\tif y == PrimitiveUnknown {\n\t\treturn PrimitiveUnknown\n\t}\n\n\tif x == y {\n\t\treturn x\n\t}\n\treturn PrimitiveMixed // Definitely some kind of primitive\n}\n\n// Note: This function does not say whether the expression is side-effect free\n// or not. For example, the expression \"++x\" always returns a primitive.\nfunc KnownPrimitiveType(expr E) PrimitiveType {\n\tswitch e := expr.(type) {\n\tcase *EAnnotation:\n\t\treturn KnownPrimitiveType(e.Value.Data)\n\n\tcase *EInlinedEnum:\n\t\treturn KnownPrimitiveType(e.Value.Data)\n\n\tcase *ENull:\n\t\treturn PrimitiveNull\n\n\tcase *EUndefined:\n\t\treturn PrimitiveUndefined\n\n\tcase *EBoolean:\n\t\treturn PrimitiveBoolean\n\n\tcase *ENumber:\n\t\treturn PrimitiveNumber\n\n\tcase *EString:\n\t\treturn PrimitiveString\n\n\tcase *EBigInt:\n\t\treturn PrimitiveBigInt\n\n\tcase *ETemplate:\n\t\tif e.TagOrNil.Data == nil {\n\t\t\treturn PrimitiveString\n\t\t}\n\n\tcase *EIf:\n\t\treturn MergedKnownPrimitiveTypes(e.Yes, e.No)\n\n\tcase *EUnary:\n\t\tswitch e.Op {\n\t\tcase UnOpVoid:\n\t\t\treturn PrimitiveUndefined\n\n\t\tcase UnOpTypeof:\n\t\t\treturn PrimitiveString\n\n\t\tcase UnOpNot, UnOpDelete:\n\t\t\treturn PrimitiveBoolean\n\n\t\tcase UnOpPos:\n\t\t\treturn PrimitiveNumber // Cannot be bigint because that throws an exception\n\n\t\tcase UnOpNeg, UnOpCpl:\n\t\t\tvalue := KnownPrimitiveType(e.Value.Data)\n\t\t\tif value == PrimitiveBigInt {\n\t\t\t\treturn PrimitiveBigInt\n\t\t\t}\n\t\t\tif value != PrimitiveUnknown && value != PrimitiveMixed {\n\t\t\t\treturn PrimitiveNumber\n\t\t\t}\n\t\t\treturn PrimitiveMixed // Can be number or bigint\n\n\t\tcase UnOpPreDec, UnOpPreInc, UnOpPostDec, UnOpPostInc:\n\t\t\treturn PrimitiveMixed // Can be number or bigint\n\t\t}\n\n\tcase *EBinary:\n\t\tswitch e.Op {\n\t\tcase BinOpStrictEq, BinOpStrictNe, BinOpLooseEq, BinOpLooseNe,\n\t\t\tBinOpLt, BinOpGt, BinOpLe, BinOpGe,\n\t\t\tBinOpInstanceof, BinOpIn:\n\t\t\treturn PrimitiveBoolean\n\n\t\tcase BinOpLogicalOr, BinOpLogicalAnd:\n\t\t\treturn MergedKnownPrimitiveTypes(e.Left, e.Right)\n\n\t\tcase BinOpNullishCoalescing:\n\t\t\tleft := KnownPrimitiveType(e.Left.Data)\n\t\t\tright := KnownPrimitiveType(e.Right.Data)\n\t\t\tif left == PrimitiveNull || left == PrimitiveUndefined {\n\t\t\t\treturn right\n\t\t\t}\n\t\t\tif left != PrimitiveUnknown {\n\t\t\t\tif left != PrimitiveMixed {\n\t\t\t\t\treturn left // Definitely not null or undefined\n\t\t\t\t}\n\t\t\t\tif right != PrimitiveUnknown {\n\t\t\t\t\treturn PrimitiveMixed // Definitely some kind of primitive\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase BinOpAdd:\n\t\t\tleft := KnownPrimitiveType(e.Left.Data)\n\t\t\tright := KnownPrimitiveType(e.Right.Data)\n\t\t\tif left == PrimitiveString || right == PrimitiveString {\n\t\t\t\treturn PrimitiveString\n\t\t\t}\n\t\t\tif left == PrimitiveBigInt && right == PrimitiveBigInt {\n\t\t\t\treturn PrimitiveBigInt\n\t\t\t}\n\t\t\tif left != PrimitiveUnknown && left != PrimitiveMixed && left != PrimitiveBigInt &&\n\t\t\t\tright != PrimitiveUnknown && right != PrimitiveMixed && right != PrimitiveBigInt {\n\t\t\t\treturn PrimitiveNumber\n\t\t\t}\n\t\t\treturn PrimitiveMixed // Can be number or bigint or string (or an exception)\n\n\t\tcase BinOpAddAssign:\n\t\t\tright := KnownPrimitiveType(e.Right.Data)\n\t\t\tif right == PrimitiveString {\n\t\t\t\treturn PrimitiveString\n\t\t\t}\n\t\t\treturn PrimitiveMixed // Can be number or bigint or string (or an exception)\n\n\t\tcase\n\t\t\tBinOpSub, BinOpSubAssign,\n\t\t\tBinOpMul, BinOpMulAssign,\n\t\t\tBinOpDiv, BinOpDivAssign,\n\t\t\tBinOpRem, BinOpRemAssign,\n\t\t\tBinOpPow, BinOpPowAssign,\n\t\t\tBinOpBitwiseAnd, BinOpBitwiseAndAssign,\n\t\t\tBinOpBitwiseOr, BinOpBitwiseOrAssign,\n\t\t\tBinOpBitwiseXor, BinOpBitwiseXorAssign,\n\t\t\tBinOpShl, BinOpShlAssign,\n\t\t\tBinOpShr, BinOpShrAssign,\n\t\t\tBinOpUShr, BinOpUShrAssign:\n\t\t\treturn PrimitiveMixed // Can be number or bigint (or an exception)\n\n\t\tcase BinOpAssign, BinOpComma:\n\t\t\treturn KnownPrimitiveType(e.Right.Data)\n\t\t}\n\t}\n\n\treturn PrimitiveUnknown\n}\n\nfunc CanChangeStrictToLoose(a Expr, b Expr) bool {\n\tx := KnownPrimitiveType(a.Data)\n\ty := KnownPrimitiveType(b.Data)\n\treturn x == y && x != PrimitiveUnknown && x != PrimitiveMixed\n}\n\n// Returns true if the result of the \"typeof\" operator on this expression is\n// statically determined and this expression has no side effects (i.e. can be\n// removed without consequence).\nfunc TypeofWithoutSideEffects(data E) (string, bool) {\n\tswitch e := data.(type) {\n\tcase *EAnnotation:\n\t\tif e.Flags.Has(CanBeRemovedIfUnusedFlag) {\n\t\t\treturn TypeofWithoutSideEffects(e.Value.Data)\n\t\t}\n\n\tcase *EInlinedEnum:\n\t\treturn TypeofWithoutSideEffects(e.Value.Data)\n\n\tcase *ENull:\n\t\treturn \"object\", true\n\n\tcase *EUndefined:\n\t\treturn \"undefined\", true\n\n\tcase *EBoolean:\n\t\treturn \"boolean\", true\n\n\tcase *ENumber:\n\t\treturn \"number\", true\n\n\tcase *EBigInt:\n\t\treturn \"bigint\", true\n\n\tcase *EString:\n\t\treturn \"string\", true\n\n\tcase *EFunction, *EArrow:\n\t\treturn \"function\", true\n\t}\n\n\treturn \"\", false\n}\n\n// The goal of this function is to \"rotate\" the AST if it's possible to use the\n// left-associative property of the operator to avoid unnecessary parentheses.\n//\n// When using this, make absolutely sure that the operator is actually\n// associative. For example, the \"+\" operator is not associative for\n// floating-point numbers.\n//\n// This function intentionally avoids mutating the input AST so it can be\n// called after the AST has been frozen (i.e. after parsing ends).\nfunc JoinWithLeftAssociativeOp(op OpCode, a Expr, b Expr) Expr {\n\t// \"(a, b) op c\" => \"a, b op c\"\n\tif comma, ok := a.Data.(*EBinary); ok && comma.Op == BinOpComma {\n\t\t// Don't mutate the original AST\n\t\tclone := *comma\n\t\tclone.Right = JoinWithLeftAssociativeOp(op, clone.Right, b)\n\t\treturn Expr{Loc: a.Loc, Data: &clone}\n\t}\n\n\t// \"a op (b op c)\" => \"(a op b) op c\"\n\t// \"a op (b op (c op d))\" => \"((a op b) op c) op d\"\n\tfor {\n\t\tif binary, ok := b.Data.(*EBinary); ok && binary.Op == op {\n\t\t\ta = JoinWithLeftAssociativeOp(op, a, binary.Left)\n\t\t\tb = binary.Right\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// \"a op b\" => \"a op b\"\n\t// \"(a op b) op c\" => \"(a op b) op c\"\n\treturn Expr{Loc: a.Loc, Data: &EBinary{Op: op, Left: a, Right: b}}\n}\n\nfunc JoinWithComma(a Expr, b Expr) Expr {\n\tif a.Data == nil {\n\t\treturn b\n\t}\n\tif b.Data == nil {\n\t\treturn a\n\t}\n\treturn Expr{Loc: a.Loc, Data: &EBinary{Op: BinOpComma, Left: a, Right: b}}\n}\n\nfunc JoinAllWithComma(all []Expr) (result Expr) {\n\tfor _, value := range all {\n\t\tresult = JoinWithComma(result, value)\n\t}\n\treturn\n}\n\nfunc ConvertBindingToExpr(binding Binding, wrapIdentifier func(logger.Loc, ast.Ref) Expr) Expr {\n\tloc := binding.Loc\n\n\tswitch b := binding.Data.(type) {\n\tcase *BMissing:\n\t\treturn Expr{Loc: loc, Data: &EMissing{}}\n\n\tcase *BIdentifier:\n\t\tif wrapIdentifier != nil {\n\t\t\treturn wrapIdentifier(loc, b.Ref)\n\t\t}\n\t\treturn Expr{Loc: loc, Data: &EIdentifier{Ref: b.Ref}}\n\n\tcase *BArray:\n\t\texprs := make([]Expr, len(b.Items))\n\t\tfor i, item := range b.Items {\n\t\t\texpr := ConvertBindingToExpr(item.Binding, wrapIdentifier)\n\t\t\tif b.HasSpread && i+1 == len(b.Items) {\n\t\t\t\texpr = Expr{Loc: expr.Loc, Data: &ESpread{Value: expr}}\n\t\t\t} else if item.DefaultValueOrNil.Data != nil {\n\t\t\t\texpr = Assign(expr, item.DefaultValueOrNil)\n\t\t\t}\n\t\t\texprs[i] = expr\n\t\t}\n\t\treturn Expr{Loc: loc, Data: &EArray{\n\t\t\tItems:        exprs,\n\t\t\tIsSingleLine: b.IsSingleLine,\n\t\t}}\n\n\tcase *BObject:\n\t\tproperties := make([]Property, len(b.Properties))\n\t\tfor i, property := range b.Properties {\n\t\t\tvalue := ConvertBindingToExpr(property.Value, wrapIdentifier)\n\t\t\tkind := PropertyField\n\t\t\tif property.IsSpread {\n\t\t\t\tkind = PropertySpread\n\t\t\t}\n\t\t\tvar flags PropertyFlags\n\t\t\tif property.IsComputed {\n\t\t\t\tflags |= PropertyIsComputed\n\t\t\t}\n\t\t\tproperties[i] = Property{\n\t\t\t\tKind:             kind,\n\t\t\t\tFlags:            flags,\n\t\t\t\tKey:              property.Key,\n\t\t\t\tValueOrNil:       value,\n\t\t\t\tInitializerOrNil: property.DefaultValueOrNil,\n\t\t\t}\n\t\t}\n\t\treturn Expr{Loc: loc, Data: &EObject{\n\t\t\tProperties:   properties,\n\t\t\tIsSingleLine: b.IsSingleLine,\n\t\t}}\n\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\n// This will return a nil expression if the expression can be totally removed.\n//\n// This function intentionally avoids mutating the input AST so it can be\n// called after the AST has been frozen (i.e. after parsing ends).\nfunc (ctx HelperContext) SimplifyUnusedExpr(expr Expr, unsupportedFeatures compat.JSFeature) Expr {\n\tswitch e := expr.Data.(type) {\n\tcase *EAnnotation:\n\t\tif e.Flags.Has(CanBeRemovedIfUnusedFlag) {\n\t\t\treturn Expr{}\n\t\t}\n\n\tcase *EInlinedEnum:\n\t\treturn ctx.SimplifyUnusedExpr(e.Value, unsupportedFeatures)\n\n\tcase *ENull, *EUndefined, *EMissing, *EBoolean, *ENumber, *EBigInt,\n\t\t*EString, *EThis, *ERegExp, *EFunction, *EArrow, *EImportMeta:\n\t\treturn Expr{}\n\n\tcase *EDot:\n\t\tif e.CanBeRemovedIfUnused {\n\t\t\treturn Expr{}\n\t\t}\n\n\tcase *EIdentifier:\n\t\tif e.MustKeepDueToWithStmt {\n\t\t\tbreak\n\t\t}\n\t\tif e.CanBeRemovedIfUnused || !ctx.isUnbound(e.Ref) {\n\t\t\treturn Expr{}\n\t\t}\n\n\tcase *ETemplate:\n\t\tif e.TagOrNil.Data == nil {\n\t\t\tvar comma Expr\n\t\t\tvar templateLoc logger.Loc\n\t\t\tvar template *ETemplate\n\t\t\tfor _, part := range e.Parts {\n\t\t\t\t// If we know this value is some kind of primitive, then we know that\n\t\t\t\t// \"ToString\" has no side effects and can be avoided.\n\t\t\t\tif KnownPrimitiveType(part.Value.Data) != PrimitiveUnknown {\n\t\t\t\t\tif template != nil {\n\t\t\t\t\t\tcomma = JoinWithComma(comma, Expr{Loc: templateLoc, Data: template})\n\t\t\t\t\t\ttemplate = nil\n\t\t\t\t\t}\n\t\t\t\t\tcomma = JoinWithComma(comma, ctx.SimplifyUnusedExpr(part.Value, unsupportedFeatures))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Make sure \"ToString\" is still evaluated on the value. We can't use\n\t\t\t\t// string addition here because that may evaluate \"ValueOf\" instead.\n\t\t\t\tif template == nil {\n\t\t\t\t\ttemplate = &ETemplate{}\n\t\t\t\t\ttemplateLoc = part.Value.Loc\n\t\t\t\t}\n\t\t\t\ttemplate.Parts = append(template.Parts, TemplatePart{Value: part.Value})\n\t\t\t}\n\t\t\tif template != nil {\n\t\t\t\tcomma = JoinWithComma(comma, Expr{Loc: templateLoc, Data: template})\n\t\t\t}\n\t\t\treturn comma\n\t\t} else if e.CanBeUnwrappedIfUnused {\n\t\t\t// If the function call was annotated as being able to be removed if the\n\t\t\t// result is unused, then we can remove it and just keep the arguments.\n\t\t\t// Note that there are no implicit \"ToString\" operations for tagged\n\t\t\t// template literals.\n\t\t\tvar comma Expr\n\t\t\tfor _, part := range e.Parts {\n\t\t\t\tcomma = JoinWithComma(comma, ctx.SimplifyUnusedExpr(part.Value, unsupportedFeatures))\n\t\t\t}\n\t\t\treturn comma\n\t\t}\n\n\tcase *EArray:\n\t\t// Arrays with \"...\" spread expressions can't be unwrapped because the\n\t\t// \"...\" triggers code evaluation via iterators. In that case, just trim\n\t\t// the other items instead and leave the array expression there.\n\t\tfor _, spread := range e.Items {\n\t\t\tif _, ok := spread.Data.(*ESpread); ok {\n\t\t\t\titems := make([]Expr, 0, len(e.Items))\n\t\t\t\tfor _, item := range e.Items {\n\t\t\t\t\titem = ctx.SimplifyUnusedExpr(item, unsupportedFeatures)\n\t\t\t\t\tif item.Data != nil {\n\t\t\t\t\t\titems = append(items, item)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Don't mutate the original AST\n\t\t\t\tclone := *e\n\t\t\t\tclone.Items = items\n\t\t\t\treturn Expr{Loc: expr.Loc, Data: &clone}\n\t\t\t}\n\t\t}\n\n\t\t// Otherwise, the array can be completely removed. We only need to keep any\n\t\t// array items with side effects. Apply this simplification recursively.\n\t\tvar result Expr\n\t\tfor _, item := range e.Items {\n\t\t\tresult = JoinWithComma(result, ctx.SimplifyUnusedExpr(item, unsupportedFeatures))\n\t\t}\n\t\treturn result\n\n\tcase *EObject:\n\t\t// Objects with \"...\" spread expressions can't be unwrapped because the\n\t\t// \"...\" triggers code evaluation via getters. In that case, just trim\n\t\t// the other items instead and leave the object expression there.\n\t\tfor _, spread := range e.Properties {\n\t\t\tif spread.Kind == PropertySpread {\n\t\t\t\tproperties := make([]Property, 0, len(e.Properties))\n\t\t\t\tfor _, property := range e.Properties {\n\t\t\t\t\t// Spread properties must always be evaluated\n\t\t\t\t\tif property.Kind != PropertySpread {\n\t\t\t\t\t\tvalue := ctx.SimplifyUnusedExpr(property.ValueOrNil, unsupportedFeatures)\n\t\t\t\t\t\tif value.Data != nil {\n\t\t\t\t\t\t\t// Keep the value\n\t\t\t\t\t\t\tproperty.ValueOrNil = value\n\t\t\t\t\t\t} else if !property.Flags.Has(PropertyIsComputed) {\n\t\t\t\t\t\t\t// Skip this property if the key doesn't need to be computed\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Replace values without side effects with \"0\" because it's short\n\t\t\t\t\t\t\tproperty.ValueOrNil.Data = &ENumber{}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tproperties = append(properties, property)\n\t\t\t\t}\n\n\t\t\t\t// Don't mutate the original AST\n\t\t\t\tclone := *e\n\t\t\t\tclone.Properties = properties\n\t\t\t\treturn Expr{Loc: expr.Loc, Data: &clone}\n\t\t\t}\n\t\t}\n\n\t\t// Otherwise, the object can be completely removed. We only need to keep any\n\t\t// object properties with side effects. Apply this simplification recursively.\n\t\tvar result Expr\n\t\tfor _, property := range e.Properties {\n\t\t\tif property.Flags.Has(PropertyIsComputed) {\n\t\t\t\t// Make sure \"ToString\" is still evaluated on the key\n\t\t\t\tresult = JoinWithComma(result, Expr{Loc: property.Key.Loc, Data: &EBinary{\n\t\t\t\t\tOp:    BinOpAdd,\n\t\t\t\t\tLeft:  property.Key,\n\t\t\t\t\tRight: Expr{Loc: property.Key.Loc, Data: &EString{}},\n\t\t\t\t}})\n\t\t\t}\n\t\t\tresult = JoinWithComma(result, ctx.SimplifyUnusedExpr(property.ValueOrNil, unsupportedFeatures))\n\t\t}\n\t\treturn result\n\n\tcase *EIf:\n\t\tyes := ctx.SimplifyUnusedExpr(e.Yes, unsupportedFeatures)\n\t\tno := ctx.SimplifyUnusedExpr(e.No, unsupportedFeatures)\n\n\t\t// \"foo() ? 1 : 2\" => \"foo()\"\n\t\tif yes.Data == nil && no.Data == nil {\n\t\t\treturn ctx.SimplifyUnusedExpr(e.Test, unsupportedFeatures)\n\t\t}\n\n\t\t// \"foo() ? 1 : bar()\" => \"foo() || bar()\"\n\t\tif yes.Data == nil {\n\t\t\treturn JoinWithLeftAssociativeOp(BinOpLogicalOr, e.Test, no)\n\t\t}\n\n\t\t// \"foo() ? bar() : 2\" => \"foo() && bar()\"\n\t\tif no.Data == nil {\n\t\t\treturn JoinWithLeftAssociativeOp(BinOpLogicalAnd, e.Test, yes)\n\t\t}\n\n\t\tif yes != e.Yes || no != e.No {\n\t\t\treturn Expr{Loc: expr.Loc, Data: &EIf{Test: e.Test, Yes: yes, No: no}}\n\t\t}\n\n\tcase *EUnary:\n\t\tswitch e.Op {\n\t\t// These operators must not have any type conversions that can execute code\n\t\t// such as \"toString\" or \"valueOf\". They must also never throw any exceptions.\n\t\tcase UnOpVoid, UnOpNot:\n\t\t\treturn ctx.SimplifyUnusedExpr(e.Value, unsupportedFeatures)\n\n\t\tcase UnOpNeg:\n\t\t\tif _, ok := e.Value.Data.(*EBigInt); ok {\n\t\t\t\t// Consider negated bigints to have no side effects\n\t\t\t\treturn Expr{}\n\t\t\t}\n\n\t\tcase UnOpTypeof:\n\t\t\tif _, ok := e.Value.Data.(*EIdentifier); ok && e.WasOriginallyTypeofIdentifier {\n\t\t\t\t// \"typeof x\" must not be transformed into if \"x\" since doing so could\n\t\t\t\t// cause an exception to be thrown. Instead we can just remove it since\n\t\t\t\t// \"typeof x\" is special-cased in the standard to never throw.\n\t\t\t\treturn Expr{}\n\t\t\t}\n\t\t\treturn ctx.SimplifyUnusedExpr(e.Value, unsupportedFeatures)\n\t\t}\n\n\tcase *EBinary:\n\t\tleft := e.Left\n\t\tright := e.Right\n\n\t\tswitch e.Op {\n\t\t// These operators must not have any type conversions that can execute code\n\t\t// such as \"toString\" or \"valueOf\". They must also never throw any exceptions.\n\t\tcase BinOpStrictEq, BinOpStrictNe, BinOpComma:\n\t\t\treturn JoinWithComma(ctx.SimplifyUnusedExpr(left, unsupportedFeatures), ctx.SimplifyUnusedExpr(right, unsupportedFeatures))\n\n\t\t// We can simplify \"==\" and \"!=\" even though they can call \"toString\" and/or\n\t\t// \"valueOf\" if we can statically determine that the types of both sides are\n\t\t// primitives. In that case there won't be any chance for user-defined\n\t\t// \"toString\" and/or \"valueOf\" to be called.\n\t\tcase BinOpLooseEq, BinOpLooseNe:\n\t\t\tif MergedKnownPrimitiveTypes(left, right) != PrimitiveUnknown {\n\t\t\t\treturn JoinWithComma(ctx.SimplifyUnusedExpr(left, unsupportedFeatures), ctx.SimplifyUnusedExpr(right, unsupportedFeatures))\n\t\t\t}\n\n\t\tcase BinOpLogicalAnd, BinOpLogicalOr, BinOpNullishCoalescing:\n\t\t\t// If this is a boolean logical operation and the result is unused, then\n\t\t\t// we know the left operand will only be used for its boolean value and\n\t\t\t// can be simplified under that assumption\n\t\t\tif e.Op != BinOpNullishCoalescing {\n\t\t\t\tleft = ctx.SimplifyBooleanExpr(left)\n\t\t\t}\n\n\t\t\t// Preserve short-circuit behavior: the left expression is only unused if\n\t\t\t// the right expression can be completely removed. Otherwise, the left\n\t\t\t// expression is important for the branch.\n\t\t\tright = ctx.SimplifyUnusedExpr(right, unsupportedFeatures)\n\t\t\tif right.Data == nil {\n\t\t\t\treturn ctx.SimplifyUnusedExpr(left, unsupportedFeatures)\n\t\t\t}\n\n\t\t\t// Try to take advantage of the optional chain operator to shorten code\n\t\t\tif !unsupportedFeatures.Has(compat.OptionalChain) {\n\t\t\t\tif binary, ok := left.Data.(*EBinary); ok {\n\t\t\t\t\t// \"a != null && a.b()\" => \"a?.b()\"\n\t\t\t\t\t// \"a == null || a.b()\" => \"a?.b()\"\n\t\t\t\t\tif (binary.Op == BinOpLooseNe && e.Op == BinOpLogicalAnd) || (binary.Op == BinOpLooseEq && e.Op == BinOpLogicalOr) {\n\t\t\t\t\t\tvar test Expr\n\t\t\t\t\t\tif _, ok := binary.Right.Data.(*ENull); ok {\n\t\t\t\t\t\t\ttest = binary.Left\n\t\t\t\t\t\t} else if _, ok := binary.Left.Data.(*ENull); ok {\n\t\t\t\t\t\t\ttest = binary.Right\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Note: Technically unbound identifiers can refer to a getter on\n\t\t\t\t\t\t// the global object and that getter can have side effects that can\n\t\t\t\t\t\t// be observed if we run that getter once instead of twice. But this\n\t\t\t\t\t\t// seems like terrible coding practice and very unlikely to come up\n\t\t\t\t\t\t// in real software, so we deliberately ignore this possibility and\n\t\t\t\t\t\t// optimize for size instead of for this obscure edge case.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// If this is ever changed, then we must also pessimize the lowering\n\t\t\t\t\t\t// of \"foo?.bar\" to save the value of \"foo\" to ensure that it's only\n\t\t\t\t\t\t// evaluated once. Specifically \"foo?.bar\" would have to expand to:\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//   var _a;\n\t\t\t\t\t\t//   (_a = foo) == null ? void 0 : _a.bar;\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// instead of:\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//   foo == null ? void 0 : foo.bar;\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// Babel does the first one while TypeScript does the second one.\n\t\t\t\t\t\t// Since TypeScript doesn't handle this extreme edge case and\n\t\t\t\t\t\t// TypeScript is very widely used, I think it's fine for us to not\n\t\t\t\t\t\t// handle this edge case either.\n\t\t\t\t\t\tif id, ok := test.Data.(*EIdentifier); ok && !id.MustKeepDueToWithStmt && TryToInsertOptionalChain(test, right) {\n\t\t\t\t\t\t\treturn right\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase BinOpAdd:\n\t\t\tif result, isStringAddition := simplifyUnusedStringAdditionChain(expr); isStringAddition {\n\t\t\t\treturn result\n\t\t\t}\n\t\t}\n\n\t\tif left != e.Left || right != e.Right {\n\t\t\treturn Expr{Loc: expr.Loc, Data: &EBinary{Op: e.Op, Left: left, Right: right}}\n\t\t}\n\n\tcase *ECall:\n\t\t// A call that has been marked \"__PURE__\" can be removed if all arguments\n\t\t// can be removed. The annotation causes us to ignore the target.\n\t\tif e.CanBeUnwrappedIfUnused {\n\t\t\tvar result Expr\n\t\t\tfor _, arg := range e.Args {\n\t\t\t\tif _, ok := arg.Data.(*ESpread); ok {\n\t\t\t\t\targ.Data = &EArray{Items: []Expr{arg}, IsSingleLine: true}\n\t\t\t\t}\n\t\t\t\tresult = JoinWithComma(result, ctx.SimplifyUnusedExpr(arg, unsupportedFeatures))\n\t\t\t}\n\t\t\treturn result\n\t\t}\n\n\t\t// Attempt to shorten IIFEs\n\t\tif len(e.Args) == 0 {\n\t\t\tswitch target := e.Target.Data.(type) {\n\t\t\tcase *EFunction:\n\t\t\t\tif len(target.Fn.Args) != 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// Just delete \"(function() {})()\" completely\n\t\t\t\tif len(target.Fn.Body.Block.Stmts) == 0 {\n\t\t\t\t\treturn Expr{}\n\t\t\t\t}\n\n\t\t\tcase *EArrow:\n\t\t\t\tif len(target.Args) != 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// Just delete \"(() => {})()\" completely\n\t\t\t\tif len(target.Body.Block.Stmts) == 0 {\n\t\t\t\t\treturn Expr{}\n\t\t\t\t}\n\n\t\t\t\tif len(target.Body.Block.Stmts) == 1 {\n\t\t\t\t\tswitch s := target.Body.Block.Stmts[0].Data.(type) {\n\t\t\t\t\tcase *SExpr:\n\t\t\t\t\t\tif !target.IsAsync {\n\t\t\t\t\t\t\t// Replace \"(() => { foo() })()\" with \"foo()\"\n\t\t\t\t\t\t\treturn s.Value\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Replace \"(async () => { foo() })()\" with \"(async () => foo())()\"\n\t\t\t\t\t\t\tclone := *target\n\t\t\t\t\t\t\tclone.Body.Block.Stmts[0].Data = &SReturn{ValueOrNil: s.Value}\n\t\t\t\t\t\t\tclone.PreferExpr = true\n\t\t\t\t\t\t\treturn Expr{Loc: expr.Loc, Data: &ECall{Target: Expr{Loc: e.Target.Loc, Data: &clone}}}\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase *SReturn:\n\t\t\t\t\t\tif !target.IsAsync {\n\t\t\t\t\t\t\t// Replace \"(() => foo())()\" with \"foo()\"\n\t\t\t\t\t\t\treturn s.ValueOrNil\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\tcase *ENew:\n\t\t// A constructor call that has been marked \"__PURE__\" can be removed if all\n\t\t// arguments can be removed. The annotation causes us to ignore the target.\n\t\tif e.CanBeUnwrappedIfUnused {\n\t\t\tvar result Expr\n\t\t\tfor _, arg := range e.Args {\n\t\t\t\tif _, ok := arg.Data.(*ESpread); ok {\n\t\t\t\t\targ.Data = &EArray{Items: []Expr{arg}, IsSingleLine: true}\n\t\t\t\t}\n\t\t\t\tresult = JoinWithComma(result, ctx.SimplifyUnusedExpr(arg, unsupportedFeatures))\n\t\t\t}\n\t\t\treturn result\n\t\t}\n\t}\n\n\treturn expr\n}\n\n// This function intentionally avoids mutating the input AST so it can be\n// called after the AST has been frozen (i.e. after parsing ends).\nfunc simplifyUnusedStringAdditionChain(expr Expr) (Expr, bool) {\n\tswitch e := expr.Data.(type) {\n\tcase *EString:\n\t\t// \"'x' + y\" => \"'' + y\"\n\t\treturn Expr{Loc: expr.Loc, Data: &EString{}}, true\n\n\tcase *EBinary:\n\t\tif e.Op == BinOpAdd {\n\t\t\tleft, leftIsStringAddition := simplifyUnusedStringAdditionChain(e.Left)\n\n\t\t\tif right, rightIsString := e.Right.Data.(*EString); rightIsString {\n\t\t\t\t// \"('' + x) + 'y'\" => \"'' + x\"\n\t\t\t\tif leftIsStringAddition {\n\t\t\t\t\treturn left, true\n\t\t\t\t}\n\n\t\t\t\t// \"x + 'y'\" => \"x + ''\"\n\t\t\t\tif !leftIsStringAddition && len(right.Value) > 0 {\n\t\t\t\t\treturn Expr{Loc: expr.Loc, Data: &EBinary{\n\t\t\t\t\t\tOp:    BinOpAdd,\n\t\t\t\t\t\tLeft:  left,\n\t\t\t\t\t\tRight: Expr{Loc: e.Right.Loc, Data: &EString{}},\n\t\t\t\t\t}}, true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Don't mutate the original AST\n\t\t\tif left != e.Left {\n\t\t\t\texpr.Data = &EBinary{Op: BinOpAdd, Left: left, Right: e.Right}\n\t\t\t}\n\n\t\t\treturn expr, leftIsStringAddition\n\t\t}\n\t}\n\n\treturn expr, false\n}\n\nfunc ToInt32(f float64) int32 {\n\t// The easy way\n\ti := int32(f)\n\tif float64(i) == f {\n\t\treturn i\n\t}\n\n\t// Special-case non-finite numbers (casting them is unspecified behavior in Go)\n\tif math.IsNaN(f) || math.IsInf(f, 0) {\n\t\treturn 0\n\t}\n\n\t// The hard way\n\ti = int32(uint32(math.Mod(math.Abs(f), 4294967296)))\n\tif math.Signbit(f) {\n\t\treturn -i\n\t}\n\treturn i\n}\n\nfunc ToUint32(f float64) uint32 {\n\treturn uint32(ToInt32(f))\n}\n\n// If this returns true, we know the result can't be NaN\nfunc isInt32OrUint32(data E) bool {\n\tswitch e := data.(type) {\n\tcase *EBinary:\n\t\tswitch e.Op {\n\t\tcase BinOpUShr: // This is the only bitwise operator that can't return a bigint (because it throws instead)\n\t\t\treturn true\n\n\t\tcase BinOpLogicalOr, BinOpLogicalAnd:\n\t\t\treturn isInt32OrUint32(e.Left.Data) && isInt32OrUint32(e.Right.Data)\n\t\t}\n\n\tcase *EIf:\n\t\treturn isInt32OrUint32(e.Yes.Data) && isInt32OrUint32(e.No.Data)\n\t}\n\treturn false\n}\n\nfunc ToNumberWithoutSideEffects(data E) (float64, bool) {\n\tswitch e := data.(type) {\n\tcase *EAnnotation:\n\t\treturn ToNumberWithoutSideEffects(e.Value.Data)\n\n\tcase *EInlinedEnum:\n\t\treturn ToNumberWithoutSideEffects(e.Value.Data)\n\n\tcase *ENull:\n\t\treturn 0, true\n\n\tcase *EUndefined, *ERegExp:\n\t\treturn math.NaN(), true\n\n\tcase *EArray:\n\t\tif len(e.Items) == 0 {\n\t\t\t// \"+[]\" => \"0\"\n\t\t\treturn 0, true\n\t\t}\n\n\tcase *EObject:\n\t\tif len(e.Properties) == 0 {\n\t\t\t// \"+{}\" => \"NaN\"\n\t\t\treturn math.NaN(), true\n\t\t}\n\n\tcase *EBoolean:\n\t\tif e.Value {\n\t\t\treturn 1, true\n\t\t} else {\n\t\t\treturn 0, true\n\t\t}\n\n\tcase *ENumber:\n\t\treturn e.Value, true\n\n\tcase *EString:\n\t\t// \"+''\" => \"0\"\n\t\tif len(e.Value) == 0 {\n\t\t\treturn 0, true\n\t\t}\n\n\t\t// \"+'1'\" => \"1\"\n\t\tif num, ok := StringToEquivalentNumberValue(e.Value); ok {\n\t\t\treturn num, true\n\t\t}\n\t}\n\n\treturn 0, false\n}\n\nfunc ToStringWithoutSideEffects(data E) (string, bool) {\n\tswitch e := data.(type) {\n\tcase *ENull:\n\t\treturn \"null\", true\n\n\tcase *EUndefined:\n\t\treturn \"undefined\", true\n\n\tcase *EBoolean:\n\t\tif e.Value {\n\t\t\treturn \"true\", true\n\t\t} else {\n\t\t\treturn \"false\", true\n\t\t}\n\n\tcase *EBigInt:\n\t\t// Only do this if there is no radix\n\t\tif len(e.Value) < 2 || e.Value[0] != '0' {\n\t\t\treturn e.Value, true\n\t\t}\n\n\tcase *ENumber:\n\t\tif str, ok := TryToStringOnNumberSafely(e.Value, 10); ok {\n\t\t\treturn str, true\n\t\t}\n\n\tcase *ERegExp:\n\t\treturn e.Value, true\n\n\tcase *EDot:\n\t\t// This is dumb but some JavaScript obfuscators use this to generate string literals\n\t\tif e.Name == \"constructor\" {\n\t\t\tswitch e.Target.Data.(type) {\n\t\t\tcase *EString:\n\t\t\t\treturn \"function String() { [native code] }\", true\n\n\t\t\tcase *ERegExp:\n\t\t\t\treturn \"function RegExp() { [native code] }\", true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn \"\", false\n}\n\nfunc extractNumericValue(data E) (float64, bool) {\n\tswitch e := data.(type) {\n\tcase *EAnnotation:\n\t\treturn extractNumericValue(e.Value.Data)\n\n\tcase *EInlinedEnum:\n\t\treturn extractNumericValue(e.Value.Data)\n\n\tcase *ENumber:\n\t\treturn e.Value, true\n\t}\n\n\treturn 0, false\n}\n\nfunc extractNumericValues(left Expr, right Expr) (float64, float64, bool) {\n\tif a, ok := extractNumericValue(left.Data); ok {\n\t\tif b, ok := extractNumericValue(right.Data); ok {\n\t\t\treturn a, b, true\n\t\t}\n\t}\n\treturn 0, 0, false\n}\n\nfunc extractStringValue(data E) ([]uint16, bool) {\n\tswitch e := data.(type) {\n\tcase *EAnnotation:\n\t\treturn extractStringValue(e.Value.Data)\n\n\tcase *EInlinedEnum:\n\t\treturn extractStringValue(e.Value.Data)\n\n\tcase *EString:\n\t\treturn e.Value, true\n\t}\n\n\treturn nil, false\n}\n\nfunc extractStringValues(left Expr, right Expr) ([]uint16, []uint16, bool) {\n\tif a, ok := extractStringValue(left.Data); ok {\n\t\tif b, ok := extractStringValue(right.Data); ok {\n\t\t\treturn a, b, true\n\t\t}\n\t}\n\treturn nil, nil, false\n}\n\nfunc stringCompareUCS2(a []uint16, b []uint16) int {\n\tvar n int\n\tif len(a) < len(b) {\n\t\tn = len(a)\n\t} else {\n\t\tn = len(b)\n\t}\n\tfor i := 0; i < n; i++ {\n\t\tif delta := int(a[i]) - int(b[i]); delta != 0 {\n\t\t\treturn delta\n\t\t}\n\t}\n\treturn len(a) - len(b)\n}\n\nfunc approximatePrintedIntCharCount(intValue float64) int {\n\tcount := 1 + (int)(math.Max(0, math.Floor(math.Log10(math.Abs(intValue)))))\n\tif intValue < 0 {\n\t\tcount++\n\t}\n\treturn count\n}\n\nfunc ShouldFoldBinaryOperatorWhenMinifying(binary *EBinary) bool {\n\tswitch binary.Op {\n\tcase\n\t\t// Equality tests should always result in smaller code when folded\n\t\tBinOpLooseEq,\n\t\tBinOpLooseNe,\n\t\tBinOpStrictEq,\n\t\tBinOpStrictNe,\n\n\t\t// Minification always folds right signed shift operations since they are\n\t\t// unlikely to result in larger output. Note: \">>>\" could result in\n\t\t// bigger output such as \"-1 >>> 0\" becoming \"4294967295\".\n\t\tBinOpShr,\n\n\t\t// Minification always folds the following bitwise operations since they\n\t\t// are unlikely to result in larger output.\n\t\tBinOpBitwiseAnd,\n\t\tBinOpBitwiseOr,\n\t\tBinOpBitwiseXor,\n\t\tBinOpLt,\n\t\tBinOpGt,\n\t\tBinOpLe,\n\t\tBinOpGe:\n\t\treturn true\n\n\tcase BinOpAdd:\n\t\t// Addition of small-ish integers can definitely be folded without issues\n\t\t// \"1 + 2\" => \"3\"\n\t\tif left, right, ok := extractNumericValues(binary.Left, binary.Right); ok &&\n\t\t\tleft == math.Trunc(left) && math.Abs(left) <= 0xFFFF_FFFF &&\n\t\t\tright == math.Trunc(right) && math.Abs(right) <= 0xFFFF_FFFF {\n\t\t\treturn true\n\t\t}\n\n\t\t// String addition should pretty much always be more compact when folded\n\t\tif _, _, ok := extractStringValues(binary.Left, binary.Right); ok {\n\t\t\treturn true\n\t\t}\n\n\tcase BinOpSub:\n\t\t// Subtraction of small-ish integers can definitely be folded without issues\n\t\t// \"3 - 1\" => \"2\"\n\t\tif left, right, ok := extractNumericValues(binary.Left, binary.Right); ok &&\n\t\t\tleft == math.Trunc(left) && math.Abs(left) <= 0xFFFF_FFFF &&\n\t\t\tright == math.Trunc(right) && math.Abs(right) <= 0xFFFF_FFFF {\n\t\t\treturn true\n\t\t}\n\n\tcase BinOpMul:\n\t\t// Allow multiplication of small-ish integers to be folded\n\t\t// \"1 * 2\" => \"3\"\n\t\tif left, right, ok := extractNumericValues(binary.Left, binary.Right); ok &&\n\t\t\tleft == math.Trunc(left) && math.Abs(left) <= 0xFF &&\n\t\t\tright == math.Trunc(right) && math.Abs(right) <= 0xFF {\n\t\t\treturn true\n\t\t}\n\n\tcase BinOpDiv:\n\t\t// \"0/0\" => \"NaN\"\n\t\t// \"1/0\" => \"Infinity\"\n\t\t// \"1/-0\" => \"-Infinity\"\n\t\tif _, right, ok := extractNumericValues(binary.Left, binary.Right); ok && right == 0 {\n\t\t\treturn true\n\t\t}\n\n\tcase BinOpShl:\n\t\t// \"1 << 3\" => \"8\"\n\t\t// \"1 << 24\" => \"1 << 24\" (since \"1<<24\" is shorter than \"16777216\")\n\t\tif left, right, ok := extractNumericValues(binary.Left, binary.Right); ok {\n\t\t\tleftLen := approximatePrintedIntCharCount(left)\n\t\t\trightLen := approximatePrintedIntCharCount(right)\n\t\t\tresultLen := approximatePrintedIntCharCount(float64(ToInt32(left) << (ToUint32(right) & 31)))\n\t\t\treturn resultLen <= leftLen+2+rightLen\n\t\t}\n\n\tcase BinOpUShr:\n\t\t// \"10 >>> 1\" => \"5\"\n\t\t// \"-1 >>> 0\" => \"-1 >>> 0\" (since \"-1>>>0\" is shorter than \"4294967295\")\n\t\tif left, right, ok := extractNumericValues(binary.Left, binary.Right); ok {\n\t\t\tleftLen := approximatePrintedIntCharCount(left)\n\t\t\trightLen := approximatePrintedIntCharCount(right)\n\t\t\tresultLen := approximatePrintedIntCharCount(float64(ToUint32(left) >> (ToUint32(right) & 31)))\n\t\t\treturn resultLen <= leftLen+3+rightLen\n\t\t}\n\n\tcase BinOpLogicalAnd, BinOpLogicalOr, BinOpNullishCoalescing:\n\t\tif IsPrimitiveLiteral(binary.Left.Data) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// This function intentionally avoids mutating the input AST so it can be\n// called after the AST has been frozen (i.e. after parsing ends).\nfunc FoldBinaryOperator(loc logger.Loc, e *EBinary) Expr {\n\tswitch e.Op {\n\tcase BinOpAdd:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &ENumber{Value: left + right}}\n\t\t}\n\t\tif left, right, ok := extractStringValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &EString{Value: joinStrings(left, right)}}\n\t\t}\n\n\tcase BinOpSub:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &ENumber{Value: left - right}}\n\t\t}\n\n\tcase BinOpMul:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &ENumber{Value: left * right}}\n\t\t}\n\n\tcase BinOpDiv:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &ENumber{Value: left / right}}\n\t\t}\n\n\tcase BinOpRem:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &ENumber{Value: math.Mod(left, right)}}\n\t\t}\n\n\tcase BinOpPow:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &ENumber{Value: math.Pow(left, right)}}\n\t\t}\n\n\tcase BinOpShl:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &ENumber{Value: float64(ToInt32(left) << (ToUint32(right) & 31))}}\n\t\t}\n\n\tcase BinOpShr:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &ENumber{Value: float64(ToInt32(left) >> (ToUint32(right) & 31))}}\n\t\t}\n\n\tcase BinOpUShr:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &ENumber{Value: float64(ToUint32(left) >> (ToUint32(right) & 31))}}\n\t\t}\n\n\tcase BinOpBitwiseAnd:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &ENumber{Value: float64(ToInt32(left) & ToInt32(right))}}\n\t\t}\n\n\tcase BinOpBitwiseOr:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &ENumber{Value: float64(ToInt32(left) | ToInt32(right))}}\n\t\t}\n\n\tcase BinOpBitwiseXor:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &ENumber{Value: float64(ToInt32(left) ^ ToInt32(right))}}\n\t\t}\n\n\tcase BinOpLt:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &EBoolean{Value: left < right}}\n\t\t}\n\t\tif left, right, ok := extractStringValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &EBoolean{Value: stringCompareUCS2(left, right) < 0}}\n\t\t}\n\n\tcase BinOpGt:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &EBoolean{Value: left > right}}\n\t\t}\n\t\tif left, right, ok := extractStringValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &EBoolean{Value: stringCompareUCS2(left, right) > 0}}\n\t\t}\n\n\tcase BinOpLe:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &EBoolean{Value: left <= right}}\n\t\t}\n\t\tif left, right, ok := extractStringValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &EBoolean{Value: stringCompareUCS2(left, right) <= 0}}\n\t\t}\n\n\tcase BinOpGe:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &EBoolean{Value: left >= right}}\n\t\t}\n\t\tif left, right, ok := extractStringValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &EBoolean{Value: stringCompareUCS2(left, right) >= 0}}\n\t\t}\n\n\tcase BinOpLooseEq, BinOpStrictEq:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &EBoolean{Value: left == right}}\n\t\t}\n\t\tif left, right, ok := extractStringValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &EBoolean{Value: stringCompareUCS2(left, right) == 0}}\n\t\t}\n\n\tcase BinOpLooseNe, BinOpStrictNe:\n\t\tif left, right, ok := extractNumericValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &EBoolean{Value: left != right}}\n\t\t}\n\t\tif left, right, ok := extractStringValues(e.Left, e.Right); ok {\n\t\t\treturn Expr{Loc: loc, Data: &EBoolean{Value: stringCompareUCS2(left, right) != 0}}\n\t\t}\n\n\tcase BinOpLogicalAnd:\n\t\tif boolean, sideEffects, ok := ToBooleanWithSideEffects(e.Left.Data); ok {\n\t\t\tif !boolean {\n\t\t\t\treturn e.Left\n\t\t\t} else if sideEffects == NoSideEffects {\n\t\t\t\treturn e.Right\n\t\t\t}\n\t\t}\n\n\tcase BinOpLogicalOr:\n\t\tif boolean, sideEffects, ok := ToBooleanWithSideEffects(e.Left.Data); ok {\n\t\t\tif boolean {\n\t\t\t\treturn e.Left\n\t\t\t} else if sideEffects == NoSideEffects {\n\t\t\t\treturn e.Right\n\t\t\t}\n\t\t}\n\n\tcase BinOpNullishCoalescing:\n\t\tif isNullOrUndefined, sideEffects, ok := ToNullOrUndefinedWithSideEffects(e.Left.Data); ok {\n\t\t\tif !isNullOrUndefined {\n\t\t\t\treturn e.Left\n\t\t\t} else if sideEffects == NoSideEffects {\n\t\t\t\treturn e.Right\n\t\t\t}\n\t\t}\n\t}\n\n\treturn Expr{}\n}\n\nfunc IsBinaryNullAndUndefined(left Expr, right Expr, op OpCode) (Expr, Expr, bool) {\n\tif a, ok := left.Data.(*EBinary); ok && a.Op == op {\n\t\tif b, ok := right.Data.(*EBinary); ok && b.Op == op {\n\t\t\tidA, eqA := a.Left, a.Right\n\t\t\tidB, eqB := b.Left, b.Right\n\n\t\t\t// Detect when the identifier comes second and flip the order of our checks\n\t\t\tif _, ok := eqA.Data.(*EIdentifier); ok {\n\t\t\t\tidA, eqA = eqA, idA\n\t\t\t}\n\t\t\tif _, ok := eqB.Data.(*EIdentifier); ok {\n\t\t\t\tidB, eqB = eqB, idB\n\t\t\t}\n\n\t\t\tif idA, ok := idA.Data.(*EIdentifier); ok {\n\t\t\t\tif idB, ok := idB.Data.(*EIdentifier); ok && idA.Ref == idB.Ref {\n\t\t\t\t\t// \"a === null || a === void 0\"\n\t\t\t\t\tif _, ok := eqA.Data.(*ENull); ok {\n\t\t\t\t\t\tif _, ok := eqB.Data.(*EUndefined); ok {\n\t\t\t\t\t\t\treturn a.Left, a.Right, true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// \"a === void 0 || a === null\"\n\t\t\t\t\tif _, ok := eqA.Data.(*EUndefined); ok {\n\t\t\t\t\t\tif _, ok := eqB.Data.(*ENull); ok {\n\t\t\t\t\t\t\treturn b.Left, b.Right, true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn Expr{}, Expr{}, false\n}\n\nfunc CheckEqualityBigInt(a string, b string) (equal bool, ok bool) {\n\t// Equal literals are always equal\n\tif a == b {\n\t\treturn true, true\n\t}\n\n\t// Unequal literals are unequal if neither has a radix. Leading zeros are\n\t// disallowed in bigint literals without a radix, so in this case we know\n\t// each value is in canonical form.\n\tif (len(a) < 2 || a[0] != '0') && (len(b) < 2 || b[0] != '0') {\n\t\treturn false, true\n\t}\n\n\treturn false, false\n}\n\ntype EqualityKind uint8\n\nconst (\n\tLooseEquality EqualityKind = iota\n\tStrictEquality\n)\n\n// Returns \"equal, ok\". If \"ok\" is false, then nothing is known about the two\n// values. If \"ok\" is true, the equality or inequality of the two values is\n// stored in \"equal\".\nfunc CheckEqualityIfNoSideEffects(left E, right E, kind EqualityKind) (equal bool, ok bool) {\n\tif r, ok := right.(*EInlinedEnum); ok {\n\t\treturn CheckEqualityIfNoSideEffects(left, r.Value.Data, kind)\n\t}\n\n\tswitch l := left.(type) {\n\tcase *EInlinedEnum:\n\t\treturn CheckEqualityIfNoSideEffects(l.Value.Data, right, kind)\n\n\tcase *ENull:\n\t\tswitch right.(type) {\n\t\tcase *ENull:\n\t\t\t// \"null === null\" is true\n\t\t\treturn true, true\n\n\t\tcase *EUndefined:\n\t\t\t// \"null == undefined\" is true\n\t\t\t// \"null === undefined\" is false\n\t\t\treturn kind == LooseEquality, true\n\n\t\tdefault:\n\t\t\tif IsPrimitiveLiteral(right) {\n\t\t\t\t// \"null == (not null or undefined)\" is false\n\t\t\t\treturn false, true\n\t\t\t}\n\t\t}\n\n\tcase *EUndefined:\n\t\tswitch right.(type) {\n\t\tcase *EUndefined:\n\t\t\t// \"undefined === undefined\" is true\n\t\t\treturn true, true\n\n\t\tcase *ENull:\n\t\t\t// \"undefined == null\" is true\n\t\t\t// \"undefined === null\" is false\n\t\t\treturn kind == LooseEquality, true\n\n\t\tdefault:\n\t\t\tif IsPrimitiveLiteral(right) {\n\t\t\t\t// \"undefined == (not null or undefined)\" is false\n\t\t\t\treturn false, true\n\t\t\t}\n\t\t}\n\n\tcase *EBoolean:\n\t\tswitch r := right.(type) {\n\t\tcase *EBoolean:\n\t\t\t// \"false === false\" is true\n\t\t\t// \"false === true\" is false\n\t\t\treturn l.Value == r.Value, true\n\n\t\tcase *ENumber:\n\t\t\tif kind == LooseEquality {\n\t\t\t\tif l.Value {\n\t\t\t\t\t// \"true == 1\" is true\n\t\t\t\t\treturn r.Value == 1, true\n\t\t\t\t} else {\n\t\t\t\t\t// \"false == 0\" is true\n\t\t\t\t\treturn r.Value == 0, true\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// \"true === 1\" is false\n\t\t\t\t// \"false === 0\" is false\n\t\t\t\treturn false, true\n\t\t\t}\n\n\t\tcase *ENull, *EUndefined:\n\t\t\t// \"(not null or undefined) == undefined\" is false\n\t\t\treturn false, true\n\n\t\tdefault:\n\t\t\tif kind == StrictEquality && IsPrimitiveLiteral(right) {\n\t\t\t\t// \"boolean === (not boolean)\" is false\n\t\t\t\treturn false, true\n\t\t\t}\n\t\t}\n\n\tcase *ENumber:\n\t\tswitch r := right.(type) {\n\t\tcase *ENumber:\n\t\t\t// \"0 === 0\" is true\n\t\t\t// \"0 === 1\" is false\n\t\t\treturn l.Value == r.Value, true\n\n\t\tcase *EBoolean:\n\t\t\tif kind == LooseEquality {\n\t\t\t\tif r.Value {\n\t\t\t\t\t// \"1 == true\" is true\n\t\t\t\t\treturn l.Value == 1, true\n\t\t\t\t} else {\n\t\t\t\t\t// \"0 == false\" is true\n\t\t\t\t\treturn l.Value == 0, true\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// \"1 === true\" is false\n\t\t\t\t// \"0 === false\" is false\n\t\t\t\treturn false, true\n\t\t\t}\n\n\t\tcase *ENull, *EUndefined:\n\t\t\t// \"(not null or undefined) == undefined\" is false\n\t\t\treturn false, true\n\n\t\tdefault:\n\t\t\tif kind == StrictEquality && IsPrimitiveLiteral(right) {\n\t\t\t\t// \"number === (not number)\" is false\n\t\t\t\treturn false, true\n\t\t\t}\n\t\t}\n\n\tcase *EBigInt:\n\t\tswitch r := right.(type) {\n\t\tcase *EBigInt:\n\t\t\t// \"0n === 0n\" is true\n\t\t\t// \"0n === 1n\" is false\n\t\t\treturn CheckEqualityBigInt(l.Value, r.Value)\n\n\t\tcase *ENull, *EUndefined:\n\t\t\t// \"(not null or undefined) == undefined\" is false\n\t\t\treturn false, true\n\n\t\tdefault:\n\t\t\tif kind == StrictEquality && IsPrimitiveLiteral(right) {\n\t\t\t\t// \"bigint === (not bigint)\" is false\n\t\t\t\treturn false, true\n\t\t\t}\n\t\t}\n\n\tcase *EString:\n\t\tswitch r := right.(type) {\n\t\tcase *EString:\n\t\t\t// \"'a' === 'a'\" is true\n\t\t\t// \"'a' === 'b'\" is false\n\t\t\treturn helpers.UTF16EqualsUTF16(l.Value, r.Value), true\n\n\t\tcase *ENull, *EUndefined:\n\t\t\t// \"(not null or undefined) == undefined\" is false\n\t\t\treturn false, true\n\n\t\tdefault:\n\t\t\tif kind == StrictEquality && IsPrimitiveLiteral(right) {\n\t\t\t\t// \"string === (not string)\" is false\n\t\t\t\treturn false, true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false, false\n}\n\nfunc ValuesLookTheSame(left E, right E) bool {\n\tif b, ok := right.(*EInlinedEnum); ok {\n\t\treturn ValuesLookTheSame(left, b.Value.Data)\n\t}\n\n\tswitch a := left.(type) {\n\tcase *EInlinedEnum:\n\t\treturn ValuesLookTheSame(a.Value.Data, right)\n\n\tcase *EIdentifier:\n\t\tif b, ok := right.(*EIdentifier); ok && a.Ref == b.Ref {\n\t\t\treturn true\n\t\t}\n\n\tcase *EDot:\n\t\tif b, ok := right.(*EDot); ok && a.HasSameFlagsAs(b) &&\n\t\t\ta.Name == b.Name && ValuesLookTheSame(a.Target.Data, b.Target.Data) {\n\t\t\treturn true\n\t\t}\n\n\tcase *EIndex:\n\t\tif b, ok := right.(*EIndex); ok && a.HasSameFlagsAs(b) &&\n\t\t\tValuesLookTheSame(a.Target.Data, b.Target.Data) && ValuesLookTheSame(a.Index.Data, b.Index.Data) {\n\t\t\treturn true\n\t\t}\n\n\tcase *EIf:\n\t\tif b, ok := right.(*EIf); ok && ValuesLookTheSame(a.Test.Data, b.Test.Data) &&\n\t\t\tValuesLookTheSame(a.Yes.Data, b.Yes.Data) && ValuesLookTheSame(a.No.Data, b.No.Data) {\n\t\t\treturn true\n\t\t}\n\n\tcase *EUnary:\n\t\tif b, ok := right.(*EUnary); ok && a.Op == b.Op && ValuesLookTheSame(a.Value.Data, b.Value.Data) {\n\t\t\treturn true\n\t\t}\n\n\tcase *EBinary:\n\t\tif b, ok := right.(*EBinary); ok && a.Op == b.Op && ValuesLookTheSame(a.Left.Data, b.Left.Data) &&\n\t\t\tValuesLookTheSame(a.Right.Data, b.Right.Data) {\n\t\t\treturn true\n\t\t}\n\n\tcase *ECall:\n\t\tif b, ok := right.(*ECall); ok && a.HasSameFlagsAs(b) &&\n\t\t\tlen(a.Args) == len(b.Args) && ValuesLookTheSame(a.Target.Data, b.Target.Data) {\n\t\t\tfor i := range a.Args {\n\t\t\t\tif !ValuesLookTheSame(a.Args[i].Data, b.Args[i].Data) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\n\t// Special-case to distinguish between negative an non-negative zero when mangling\n\t// \"a ? -0 : 0\" => \"a ? -0 : 0\"\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness\n\tcase *ENumber:\n\t\tb, ok := right.(*ENumber)\n\t\tif ok && a.Value == 0 && b.Value == 0 && math.Signbit(a.Value) != math.Signbit(b.Value) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tequal, ok := CheckEqualityIfNoSideEffects(left, right, StrictEquality)\n\treturn ok && equal\n}\n\nfunc TryToInsertOptionalChain(test Expr, expr Expr) bool {\n\tswitch e := expr.Data.(type) {\n\tcase *EDot:\n\t\tif ValuesLookTheSame(test.Data, e.Target.Data) {\n\t\t\te.OptionalChain = OptionalChainStart\n\t\t\treturn true\n\t\t}\n\t\tif TryToInsertOptionalChain(test, e.Target) {\n\t\t\tif e.OptionalChain == OptionalChainNone {\n\t\t\t\te.OptionalChain = OptionalChainContinue\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\n\tcase *EIndex:\n\t\tif ValuesLookTheSame(test.Data, e.Target.Data) {\n\t\t\te.OptionalChain = OptionalChainStart\n\t\t\treturn true\n\t\t}\n\t\tif TryToInsertOptionalChain(test, e.Target) {\n\t\t\tif e.OptionalChain == OptionalChainNone {\n\t\t\t\te.OptionalChain = OptionalChainContinue\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\n\tcase *ECall:\n\t\tif ValuesLookTheSame(test.Data, e.Target.Data) {\n\t\t\te.OptionalChain = OptionalChainStart\n\t\t\treturn true\n\t\t}\n\t\tif TryToInsertOptionalChain(test, e.Target) {\n\t\t\tif e.OptionalChain == OptionalChainNone {\n\t\t\t\te.OptionalChain = OptionalChainContinue\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc joinStrings(a []uint16, b []uint16) []uint16 {\n\tdata := make([]uint16, len(a)+len(b))\n\tcopy(data[:len(a)], a)\n\tcopy(data[len(a):], b)\n\treturn data\n}\n\n// String concatenation with numbers is required by the TypeScript compiler for\n// \"constant expression\" handling in enums. However, we don't want to introduce\n// correctness bugs by accidentally stringifying a number differently than how\n// a real JavaScript VM would do it. So we are conservative and we only do this\n// when we know it'll be the same result.\nfunc TryToStringOnNumberSafely(n float64, radix int) (string, bool) {\n\tif i := int32(n); float64(i) == n {\n\t\treturn strconv.FormatInt(int64(i), radix), true\n\t}\n\tif math.IsNaN(n) {\n\t\treturn \"NaN\", true\n\t}\n\tif math.IsInf(n, 1) {\n\t\treturn \"Infinity\", true\n\t}\n\tif math.IsInf(n, -1) {\n\t\treturn \"-Infinity\", true\n\t}\n\treturn \"\", false\n}\n\n// Note: We don't know if this is string addition yet at this point\nfunc foldAdditionPreProcess(expr Expr) Expr {\n\tswitch e := expr.Data.(type) {\n\tcase *EInlinedEnum:\n\t\t// \"See through\" inline enum constants\n\t\texpr = e.Value\n\n\tcase *EArray:\n\t\t// \"[] + x\" => \"'' + x\"\n\t\t// \"[1,2] + x\" => \"'1,2' + x\"\n\t\titems := make([]string, 0, len(e.Items))\n\t\tfor _, item := range e.Items {\n\t\t\tswitch item.Data.(type) {\n\t\t\tcase *EUndefined, *ENull:\n\t\t\t\titems = append(items, \"\")\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif str, ok := ToStringWithoutSideEffects(item.Data); ok {\n\t\t\t\titem.Data = &EString{Value: helpers.StringToUTF16(str)}\n\t\t\t}\n\t\t\tstr, ok := item.Data.(*EString)\n\t\t\tif !ok {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\titems = append(items, helpers.UTF16ToString(str.Value))\n\t\t}\n\t\tif len(items) == len(e.Items) {\n\t\t\texpr.Data = &EString{Value: helpers.StringToUTF16(strings.Join(items, \",\"))}\n\t\t}\n\n\tcase *EObject:\n\t\t// \"{} + x\" => \"'[object Object]' + x\"\n\t\tif len(e.Properties) == 0 {\n\t\t\texpr.Data = &EString{Value: helpers.StringToUTF16(\"[object Object]\")}\n\t\t}\n\t}\n\treturn expr\n}\n\ntype StringAdditionKind uint8\n\nconst (\n\tStringAdditionNormal StringAdditionKind = iota\n\tStringAdditionWithNestedLeft\n)\n\n// This function intentionally avoids mutating the input AST so it can be\n// called after the AST has been frozen (i.e. after parsing ends).\nfunc FoldStringAddition(left Expr, right Expr, kind StringAdditionKind) Expr {\n\tleft = foldAdditionPreProcess(left)\n\tright = foldAdditionPreProcess(right)\n\n\t// Transforming the left operand into a string is not safe if it comes from\n\t// a nested AST node. The following transforms are invalid:\n\t//\n\t//   \"0 + 1 + 'x'\" => \"0 + '1x'\"\n\t//   \"0 + 1 + `${x}`\" => \"0 + `1${x}`\"\n\t//\n\tif kind != StringAdditionWithNestedLeft {\n\t\tswitch right.Data.(type) {\n\t\tcase *EString, *ETemplate:\n\t\t\tif str, ok := ToStringWithoutSideEffects(left.Data); ok {\n\t\t\t\tleft.Data = &EString{Value: helpers.StringToUTF16(str)}\n\t\t\t}\n\t\t}\n\t}\n\n\tswitch l := left.Data.(type) {\n\tcase *EString:\n\t\t// \"'x' + 0\" => \"'x' + '0'\"\n\t\tif str, ok := ToStringWithoutSideEffects(right.Data); ok {\n\t\t\tright.Data = &EString{Value: helpers.StringToUTF16(str)}\n\t\t}\n\n\t\tswitch r := right.Data.(type) {\n\t\tcase *EString:\n\t\t\t// \"'x' + 'y'\" => \"'xy'\"\n\t\t\treturn Expr{Loc: left.Loc, Data: &EString{\n\t\t\t\tValue:          joinStrings(l.Value, r.Value),\n\t\t\t\tPreferTemplate: l.PreferTemplate || r.PreferTemplate,\n\t\t\t}}\n\n\t\tcase *ETemplate:\n\t\t\tif r.TagOrNil.Data == nil {\n\t\t\t\t// \"'x' + `y${z}`\" => \"`xy${z}`\"\n\t\t\t\treturn Expr{Loc: left.Loc, Data: &ETemplate{\n\t\t\t\t\tHeadLoc:    left.Loc,\n\t\t\t\t\tHeadCooked: joinStrings(l.Value, r.HeadCooked),\n\t\t\t\t\tParts:      r.Parts,\n\t\t\t\t}}\n\t\t\t}\n\t\t}\n\n\t\t// \"'' + typeof x\" => \"typeof x\"\n\t\tif len(l.Value) == 0 && KnownPrimitiveType(right.Data) == PrimitiveString {\n\t\t\treturn right\n\t\t}\n\n\tcase *ETemplate:\n\t\tif l.TagOrNil.Data == nil {\n\t\t\t// \"`${x}` + 0\" => \"`${x}` + '0'\"\n\t\t\tif str, ok := ToStringWithoutSideEffects(right.Data); ok {\n\t\t\t\tright.Data = &EString{Value: helpers.StringToUTF16(str)}\n\t\t\t}\n\n\t\t\tswitch r := right.Data.(type) {\n\t\t\tcase *EString:\n\t\t\t\t// \"`${x}y` + 'z'\" => \"`${x}yz`\"\n\t\t\t\tn := len(l.Parts)\n\t\t\t\thead := l.HeadCooked\n\t\t\t\tparts := make([]TemplatePart, n)\n\t\t\t\tif n == 0 {\n\t\t\t\t\thead = joinStrings(head, r.Value)\n\t\t\t\t} else {\n\t\t\t\t\tcopy(parts, l.Parts)\n\t\t\t\t\tparts[n-1].TailCooked = joinStrings(parts[n-1].TailCooked, r.Value)\n\t\t\t\t}\n\t\t\t\treturn Expr{Loc: left.Loc, Data: &ETemplate{\n\t\t\t\t\tHeadLoc:    l.HeadLoc,\n\t\t\t\t\tHeadCooked: head,\n\t\t\t\t\tParts:      parts,\n\t\t\t\t}}\n\n\t\t\tcase *ETemplate:\n\t\t\t\tif r.TagOrNil.Data == nil {\n\t\t\t\t\t// \"`${a}b` + `x${y}`\" => \"`${a}bx${y}`\"\n\t\t\t\t\tn := len(l.Parts)\n\t\t\t\t\thead := l.HeadCooked\n\t\t\t\t\tparts := make([]TemplatePart, n+len(r.Parts))\n\t\t\t\t\tcopy(parts[n:], r.Parts)\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\thead = joinStrings(head, r.HeadCooked)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcopy(parts[:n], l.Parts)\n\t\t\t\t\t\tparts[n-1].TailCooked = joinStrings(parts[n-1].TailCooked, r.HeadCooked)\n\t\t\t\t\t}\n\t\t\t\t\treturn Expr{Loc: left.Loc, Data: &ETemplate{\n\t\t\t\t\t\tHeadLoc:    l.HeadLoc,\n\t\t\t\t\t\tHeadCooked: head,\n\t\t\t\t\t\tParts:      parts,\n\t\t\t\t\t}}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// \"typeof x + ''\" => \"typeof x\"\n\tif r, ok := right.Data.(*EString); ok && len(r.Value) == 0 && KnownPrimitiveType(left.Data) == PrimitiveString {\n\t\treturn left\n\t}\n\n\treturn Expr{}\n}\n\n// \"`a${'b'}c`\" => \"`abc`\"\n//\n// This function intentionally avoids mutating the input AST so it can be\n// called after the AST has been frozen (i.e. after parsing ends).\nfunc InlinePrimitivesIntoTemplate(loc logger.Loc, e *ETemplate) Expr {\n\t// Can't inline strings if there's a custom template tag\n\tif e.TagOrNil.Data != nil {\n\t\treturn Expr{Loc: loc, Data: e}\n\t}\n\n\theadCooked := e.HeadCooked\n\tparts := make([]TemplatePart, 0, len(e.Parts))\n\n\tfor _, part := range e.Parts {\n\t\tif value, ok := part.Value.Data.(*EInlinedEnum); ok {\n\t\t\tpart.Value = value.Value\n\t\t}\n\t\tif str, ok := ToStringWithoutSideEffects(part.Value.Data); ok {\n\t\t\tpart.Value.Data = &EString{Value: helpers.StringToUTF16(str)}\n\t\t}\n\t\tif str, ok := part.Value.Data.(*EString); ok {\n\t\t\tif len(parts) == 0 {\n\t\t\t\theadCooked = append(append(headCooked, str.Value...), part.TailCooked...)\n\t\t\t} else {\n\t\t\t\tprevPart := &parts[len(parts)-1]\n\t\t\t\tprevPart.TailCooked = append(append(prevPart.TailCooked, str.Value...), part.TailCooked...)\n\t\t\t}\n\t\t} else {\n\t\t\tparts = append(parts, part)\n\t\t}\n\t}\n\n\t// Become a plain string if there are no substitutions\n\tif len(parts) == 0 {\n\t\treturn Expr{Loc: loc, Data: &EString{\n\t\t\tValue:          headCooked,\n\t\t\tPreferTemplate: true,\n\t\t}}\n\t}\n\n\treturn Expr{Loc: loc, Data: &ETemplate{\n\t\tHeadLoc:    e.HeadLoc,\n\t\tHeadCooked: headCooked,\n\t\tParts:      parts,\n\t}}\n}\n\ntype SideEffects uint8\n\nconst (\n\tCouldHaveSideEffects SideEffects = iota\n\tNoSideEffects\n)\n\nfunc ToNullOrUndefinedWithSideEffects(data E) (isNullOrUndefined bool, sideEffects SideEffects, ok bool) {\n\tswitch e := data.(type) {\n\tcase *EAnnotation:\n\t\tisNullOrUndefined, sideEffects, ok = ToNullOrUndefinedWithSideEffects(e.Value.Data)\n\t\tif e.Flags.Has(CanBeRemovedIfUnusedFlag) {\n\t\t\tsideEffects = NoSideEffects\n\t\t}\n\t\treturn\n\n\tcase *EInlinedEnum:\n\t\treturn ToNullOrUndefinedWithSideEffects(e.Value.Data)\n\n\t\t// Never null or undefined\n\tcase *EBoolean, *ENumber, *EString, *ERegExp,\n\t\t*EFunction, *EArrow, *EBigInt:\n\t\treturn false, NoSideEffects, true\n\n\t// Never null or undefined\n\tcase *EObject, *EArray, *EClass:\n\t\treturn false, CouldHaveSideEffects, true\n\n\t// Always null or undefined\n\tcase *ENull, *EUndefined:\n\t\treturn true, NoSideEffects, true\n\n\tcase *EUnary:\n\t\tswitch e.Op {\n\t\tcase\n\t\t\t// Always number or bigint\n\t\t\tUnOpPos, UnOpNeg, UnOpCpl,\n\t\t\tUnOpPreDec, UnOpPreInc, UnOpPostDec, UnOpPostInc,\n\t\t\t// Always boolean\n\t\t\tUnOpNot, UnOpDelete:\n\t\t\treturn false, CouldHaveSideEffects, true\n\n\t\t// Always boolean\n\t\tcase UnOpTypeof:\n\t\t\tif e.WasOriginallyTypeofIdentifier {\n\t\t\t\t// Expressions such as \"typeof x\" never have any side effects\n\t\t\t\treturn false, NoSideEffects, true\n\t\t\t}\n\t\t\treturn false, CouldHaveSideEffects, true\n\n\t\t// Always undefined\n\t\tcase UnOpVoid:\n\t\t\treturn true, CouldHaveSideEffects, true\n\t\t}\n\n\tcase *EBinary:\n\t\tswitch e.Op {\n\t\tcase\n\t\t\t// Always string or number or bigint\n\t\t\tBinOpAdd, BinOpAddAssign,\n\t\t\t// Always number or bigint\n\t\t\tBinOpSub, BinOpMul, BinOpDiv, BinOpRem, BinOpPow,\n\t\t\tBinOpSubAssign, BinOpMulAssign, BinOpDivAssign, BinOpRemAssign, BinOpPowAssign,\n\t\t\tBinOpShl, BinOpShr, BinOpUShr,\n\t\t\tBinOpShlAssign, BinOpShrAssign, BinOpUShrAssign,\n\t\t\tBinOpBitwiseOr, BinOpBitwiseAnd, BinOpBitwiseXor,\n\t\t\tBinOpBitwiseOrAssign, BinOpBitwiseAndAssign, BinOpBitwiseXorAssign,\n\t\t\t// Always boolean\n\t\t\tBinOpLt, BinOpLe, BinOpGt, BinOpGe, BinOpIn, BinOpInstanceof,\n\t\t\tBinOpLooseEq, BinOpLooseNe, BinOpStrictEq, BinOpStrictNe:\n\t\t\treturn false, CouldHaveSideEffects, true\n\n\t\tcase BinOpComma:\n\t\t\tif isNullOrUndefined, _, ok := ToNullOrUndefinedWithSideEffects(e.Right.Data); ok {\n\t\t\t\treturn isNullOrUndefined, CouldHaveSideEffects, true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false, NoSideEffects, false\n}\n\nfunc ToBooleanWithSideEffects(data E) (boolean bool, sideEffects SideEffects, ok bool) {\n\tswitch e := data.(type) {\n\tcase *EAnnotation:\n\t\tboolean, sideEffects, ok = ToBooleanWithSideEffects(e.Value.Data)\n\t\tif e.Flags.Has(CanBeRemovedIfUnusedFlag) {\n\t\t\tsideEffects = NoSideEffects\n\t\t}\n\t\treturn\n\n\tcase *EInlinedEnum:\n\t\treturn ToBooleanWithSideEffects(e.Value.Data)\n\n\tcase *ENull, *EUndefined:\n\t\treturn false, NoSideEffects, true\n\n\tcase *EBoolean:\n\t\treturn e.Value, NoSideEffects, true\n\n\tcase *ENumber:\n\t\treturn e.Value != 0 && !math.IsNaN(e.Value), NoSideEffects, true\n\n\tcase *EBigInt:\n\t\tequal, ok := CheckEqualityBigInt(e.Value, \"0\")\n\t\treturn !equal, NoSideEffects, ok\n\n\tcase *EString:\n\t\treturn len(e.Value) > 0, NoSideEffects, true\n\n\tcase *EFunction, *EArrow, *ERegExp:\n\t\treturn true, NoSideEffects, true\n\n\tcase *EObject, *EArray, *EClass:\n\t\treturn true, CouldHaveSideEffects, true\n\n\tcase *EUnary:\n\t\tswitch e.Op {\n\t\tcase UnOpVoid:\n\t\t\treturn false, CouldHaveSideEffects, true\n\n\t\tcase UnOpTypeof:\n\t\t\t// Never an empty string\n\t\t\tif e.WasOriginallyTypeofIdentifier {\n\t\t\t\t// Expressions such as \"typeof x\" never have any side effects\n\t\t\t\treturn true, NoSideEffects, true\n\t\t\t}\n\t\t\treturn true, CouldHaveSideEffects, true\n\n\t\tcase UnOpNot:\n\t\t\tif boolean, SideEffects, ok := ToBooleanWithSideEffects(e.Value.Data); ok {\n\t\t\t\treturn !boolean, SideEffects, true\n\t\t\t}\n\t\t}\n\n\tcase *EBinary:\n\t\tswitch e.Op {\n\t\tcase BinOpLogicalOr:\n\t\t\t// \"anything || truthy\" is truthy\n\t\t\tif boolean, _, ok := ToBooleanWithSideEffects(e.Right.Data); ok && boolean {\n\t\t\t\treturn true, CouldHaveSideEffects, true\n\t\t\t}\n\n\t\tcase BinOpLogicalAnd:\n\t\t\t// \"anything && falsy\" is falsy\n\t\t\tif boolean, _, ok := ToBooleanWithSideEffects(e.Right.Data); ok && !boolean {\n\t\t\t\treturn false, CouldHaveSideEffects, true\n\t\t\t}\n\n\t\tcase BinOpComma:\n\t\t\t// \"anything, truthy/falsy\" is truthy/falsy\n\t\t\tif boolean, _, ok := ToBooleanWithSideEffects(e.Right.Data); ok {\n\t\t\t\treturn boolean, CouldHaveSideEffects, true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false, CouldHaveSideEffects, false\n}\n\n// Simplify syntax when we know it's used inside a boolean context\n//\n// This function intentionally avoids mutating the input AST so it can be\n// called after the AST has been frozen (i.e. after parsing ends).\nfunc (ctx HelperContext) SimplifyBooleanExpr(expr Expr) Expr {\n\tswitch e := expr.Data.(type) {\n\tcase *EUnary:\n\t\tif e.Op == UnOpNot {\n\t\t\t// \"!!a\" => \"a\"\n\t\t\tif e2, ok2 := e.Value.Data.(*EUnary); ok2 && e2.Op == UnOpNot {\n\t\t\t\treturn ctx.SimplifyBooleanExpr(e2.Value)\n\t\t\t}\n\n\t\t\t// \"!!!a\" => \"!a\"\n\t\t\treturn Expr{Loc: expr.Loc, Data: &EUnary{Op: UnOpNot, Value: ctx.SimplifyBooleanExpr(e.Value)}}\n\t\t}\n\n\tcase *EBinary:\n\t\tleft := e.Left\n\t\tright := e.Right\n\n\t\tswitch e.Op {\n\t\tcase BinOpStrictEq, BinOpStrictNe, BinOpLooseEq, BinOpLooseNe:\n\t\t\tif r, ok := extractNumericValue(right.Data); ok && r == 0 && isInt32OrUint32(left.Data) {\n\t\t\t\t// If the left is guaranteed to be an integer (e.g. not NaN,\n\t\t\t\t// Infinity, or a non-numeric value) then a test against zero\n\t\t\t\t// in a boolean context is unnecessary because the value is\n\t\t\t\t// only truthy if it's not zero.\n\t\t\t\tif e.Op == BinOpStrictNe || e.Op == BinOpLooseNe {\n\t\t\t\t\t// \"if ((a >>> b) !== 0)\" => \"if (a >>> b)\"\n\t\t\t\t\treturn left\n\t\t\t\t} else {\n\t\t\t\t\t// \"if ((a >>> b) === 0)\" => \"if (!(a >>> b))\"\n\t\t\t\t\treturn Not(left)\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase BinOpLogicalAnd:\n\t\t\t// \"if (!!a && !!b)\" => \"if (a && b)\"\n\t\t\tleft = ctx.SimplifyBooleanExpr(left)\n\t\t\tright = ctx.SimplifyBooleanExpr(right)\n\n\t\t\tif boolean, SideEffects, ok := ToBooleanWithSideEffects(right.Data); ok && boolean && SideEffects == NoSideEffects {\n\t\t\t\t// \"if (anything && truthyNoSideEffects)\" => \"if (anything)\"\n\t\t\t\treturn left\n\t\t\t}\n\n\t\tcase BinOpLogicalOr:\n\t\t\t// \"if (!!a || !!b)\" => \"if (a || b)\"\n\t\t\tleft = ctx.SimplifyBooleanExpr(left)\n\t\t\tright = ctx.SimplifyBooleanExpr(right)\n\n\t\t\tif boolean, SideEffects, ok := ToBooleanWithSideEffects(right.Data); ok && !boolean && SideEffects == NoSideEffects {\n\t\t\t\t// \"if (anything || falsyNoSideEffects)\" => \"if (anything)\"\n\t\t\t\treturn left\n\t\t\t}\n\t\t}\n\n\t\tif left != e.Left || right != e.Right {\n\t\t\treturn Expr{Loc: expr.Loc, Data: &EBinary{Op: e.Op, Left: left, Right: right}}\n\t\t}\n\n\tcase *EIf:\n\t\t// \"if (a ? !!b : !!c)\" => \"if (a ? b : c)\"\n\t\tyes := ctx.SimplifyBooleanExpr(e.Yes)\n\t\tno := ctx.SimplifyBooleanExpr(e.No)\n\n\t\tif boolean, SideEffects, ok := ToBooleanWithSideEffects(yes.Data); ok && SideEffects == NoSideEffects {\n\t\t\tif boolean {\n\t\t\t\t// \"if (anything1 ? truthyNoSideEffects : anything2)\" => \"if (anything1 || anything2)\"\n\t\t\t\treturn JoinWithLeftAssociativeOp(BinOpLogicalOr, e.Test, no)\n\t\t\t} else {\n\t\t\t\t// \"if (anything1 ? falsyNoSideEffects : anything2)\" => \"if (!anything1 || anything2)\"\n\t\t\t\treturn JoinWithLeftAssociativeOp(BinOpLogicalAnd, Not(e.Test), no)\n\t\t\t}\n\t\t}\n\n\t\tif boolean, SideEffects, ok := ToBooleanWithSideEffects(no.Data); ok && SideEffects == NoSideEffects {\n\t\t\tif boolean {\n\t\t\t\t// \"if (anything1 ? anything2 : truthyNoSideEffects)\" => \"if (!anything1 || anything2)\"\n\t\t\t\treturn JoinWithLeftAssociativeOp(BinOpLogicalOr, Not(e.Test), yes)\n\t\t\t} else {\n\t\t\t\t// \"if (anything1 ? anything2 : falsyNoSideEffects)\" => \"if (anything1 && anything2)\"\n\t\t\t\treturn JoinWithLeftAssociativeOp(BinOpLogicalAnd, e.Test, yes)\n\t\t\t}\n\t\t}\n\n\t\tif yes != e.Yes || no != e.No {\n\t\t\treturn Expr{Loc: expr.Loc, Data: &EIf{Test: e.Test, Yes: yes, No: no}}\n\t\t}\n\n\tdefault:\n\t\t// \"!![]\" => \"true\"\n\t\tif boolean, sideEffects, ok := ToBooleanWithSideEffects(expr.Data); ok && (sideEffects == NoSideEffects || ctx.ExprCanBeRemovedIfUnused(expr)) {\n\t\t\treturn Expr{Loc: expr.Loc, Data: &EBoolean{Value: boolean}}\n\t\t}\n\t}\n\n\treturn expr\n}\n\ntype StmtsCanBeRemovedIfUnusedFlags uint8\n\nconst (\n\tKeepExportClauses StmtsCanBeRemovedIfUnusedFlags = 1 << iota\n\tReturnCanBeRemovedIfUnused\n)\n\nfunc (ctx HelperContext) StmtsCanBeRemovedIfUnused(stmts []Stmt, flags StmtsCanBeRemovedIfUnusedFlags) bool {\n\tfor _, stmt := range stmts {\n\t\tswitch s := stmt.Data.(type) {\n\t\tcase *SFunction, *SEmpty:\n\t\t\t// These never have side effects\n\n\t\tcase *SImport:\n\t\t\t// Let these be removed if they are unused. Note that we also need to\n\t\t\t// check if the imported file is marked as \"sideEffects: false\" before we\n\t\t\t// can remove a SImport statement. Otherwise the import must be kept for\n\t\t\t// its side effects.\n\n\t\tcase *SClass:\n\t\t\tif !ctx.ClassCanBeRemovedIfUnused(s.Class) {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\tcase *SReturn:\n\t\t\tif (flags&ReturnCanBeRemovedIfUnused) == 0 || (s.ValueOrNil.Data != nil && !ctx.ExprCanBeRemovedIfUnused(s.ValueOrNil)) {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\tcase *SExpr:\n\t\t\tif !ctx.ExprCanBeRemovedIfUnused(s.Value) {\n\t\t\t\tif s.IsFromClassOrFnThatCanBeRemovedIfUnused {\n\t\t\t\t\t// This statement was automatically generated when lowering a class\n\t\t\t\t\t// or function that we were able to analyze as having no side effects\n\t\t\t\t\t// before lowering. So we consider it to be removable. The assumption\n\t\t\t\t\t// here is that we are seeing at least all of the statements from the\n\t\t\t\t\t// class lowering operation all at once (although we may possibly be\n\t\t\t\t\t// seeing even more statements than that). Since we're making a binary\n\t\t\t\t\t// all-or-nothing decision about the side effects of these statements,\n\t\t\t\t\t// we can safely consider these to be side-effect free because we\n\t\t\t\t\t// aren't in danger of partially dropping some of the class setup code.\n\t\t\t\t} else {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *SLocal:\n\t\t\t// \"await\" is a side effect because it affects code timing\n\t\t\tif s.Kind == LocalAwaitUsing {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tfor _, decl := range s.Decls {\n\t\t\t\t// Check that the bindings are side-effect free\n\t\t\t\tswitch binding := decl.Binding.Data.(type) {\n\t\t\t\tcase *BIdentifier:\n\t\t\t\t\t// An identifier binding has no side effects\n\n\t\t\t\tcase *BArray:\n\t\t\t\t\t// Destructuring the initializer has no side effects if the\n\t\t\t\t\t// initializer is an array, since we assume the iterator is then\n\t\t\t\t\t// the built-in side-effect free array iterator.\n\t\t\t\t\tif _, ok := decl.ValueOrNil.Data.(*EArray); ok {\n\t\t\t\t\t\tfor _, item := range binding.Items {\n\t\t\t\t\t\t\tif item.DefaultValueOrNil.Data != nil && !ctx.ExprCanBeRemovedIfUnused(item.DefaultValueOrNil) {\n\t\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tswitch item.Binding.Data.(type) {\n\t\t\t\t\t\t\tcase *BIdentifier, *BMissing:\n\t\t\t\t\t\t\t\t// Right now we only handle an array pattern with identifier\n\t\t\t\t\t\t\t\t// bindings or with empty holes (i.e. \"missing\" elements)\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\treturn false\n\n\t\t\t\tdefault:\n\t\t\t\t\t// Consider anything else to potentially have side effects\n\t\t\t\t\treturn false\n\t\t\t\t}\n\n\t\t\t\t// Check that the initializer is side-effect free\n\t\t\t\tif decl.ValueOrNil.Data != nil {\n\t\t\t\t\tif !ctx.ExprCanBeRemovedIfUnused(decl.ValueOrNil) {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\n\t\t\t\t\t// \"using\" declarations are only side-effect free if they are initialized to null or undefined\n\t\t\t\t\tif s.Kind.IsUsing() {\n\t\t\t\t\t\tif t := KnownPrimitiveType(decl.ValueOrNil.Data); t != PrimitiveNull && t != PrimitiveUndefined {\n\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *STry:\n\t\t\tif !ctx.StmtsCanBeRemovedIfUnused(s.Block.Stmts, 0) || (s.Finally != nil && !ctx.StmtsCanBeRemovedIfUnused(s.Finally.Block.Stmts, 0)) {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\tcase *SExportFrom:\n\t\t\t// Exports are tracked separately, so this isn't necessary\n\n\t\tcase *SExportClause:\n\t\t\tif (flags & KeepExportClauses) != 0 {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\tcase *SExportDefault:\n\t\t\tswitch s2 := s.Value.Data.(type) {\n\t\t\tcase *SExpr:\n\t\t\t\tif !ctx.ExprCanBeRemovedIfUnused(s2.Value) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\n\t\t\tcase *SFunction:\n\t\t\t\t// These never have side effects\n\n\t\t\tcase *SClass:\n\t\t\t\tif !ctx.ClassCanBeRemovedIfUnused(s2.Class) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tpanic(\"Internal error\")\n\t\t\t}\n\n\t\tdefault:\n\t\t\t// Assume that all statements not explicitly special-cased here have side\n\t\t\t// effects, and cannot be removed even if unused\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc (ctx HelperContext) ClassCanBeRemovedIfUnused(class Class) bool {\n\tif len(class.Decorators) > 0 {\n\t\treturn false\n\t}\n\n\t// Note: This check is incorrect. Extending a non-constructible object can\n\t// throw an error, which is a side effect:\n\t//\n\t//   async function x() {}\n\t//   class y extends x {}\n\t//\n\t// But refusing to tree-shake every class with a base class is not a useful\n\t// thing for a bundler to do. So we pretend that this edge case doesn't\n\t// exist. At the time of writing, both Rollup and Terser don't consider this\n\t// to be a side effect either.\n\tif class.ExtendsOrNil.Data != nil && !ctx.ExprCanBeRemovedIfUnused(class.ExtendsOrNil) {\n\t\treturn false\n\t}\n\n\tfor _, property := range class.Properties {\n\t\tif property.Kind == PropertyClassStaticBlock {\n\t\t\tif !ctx.StmtsCanBeRemovedIfUnused(property.ClassStaticBlock.Block.Stmts, 0) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif len(property.Decorators) > 0 {\n\t\t\treturn false\n\t\t}\n\n\t\tif property.Flags.Has(PropertyIsComputed) && !IsPrimitiveLiteral(property.Key.Data) && !IsSymbolInstance(property.Key.Data) {\n\t\t\treturn false\n\t\t}\n\n\t\tif property.Kind.IsMethodDefinition() {\n\t\t\tif fn, ok := property.ValueOrNil.Data.(*EFunction); ok {\n\t\t\t\tfor _, arg := range fn.Fn.Args {\n\t\t\t\t\tif len(arg.Decorators) > 0 {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif property.Flags.Has(PropertyIsStatic) {\n\t\t\tif property.ValueOrNil.Data != nil && !ctx.ExprCanBeRemovedIfUnused(property.ValueOrNil) {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tif property.InitializerOrNil.Data != nil && !ctx.ExprCanBeRemovedIfUnused(property.InitializerOrNil) {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\t// Legacy TypeScript static class fields are considered to have side\n\t\t\t// effects because they use assign semantics, not define semantics, and\n\t\t\t// that can trigger getters. For example:\n\t\t\t//\n\t\t\t//   class Foo {\n\t\t\t//     static set foo(x) { importantSideEffect(x) }\n\t\t\t//   }\n\t\t\t//   class Bar extends Foo {\n\t\t\t//     foo = 1\n\t\t\t//   }\n\t\t\t//\n\t\t\t// This happens in TypeScript when \"useDefineForClassFields\" is disabled\n\t\t\t// because TypeScript (and esbuild) transforms the above class into this:\n\t\t\t//\n\t\t\t//   class Foo {\n\t\t\t//     static set foo(x) { importantSideEffect(x); }\n\t\t\t//   }\n\t\t\t//   class Bar extends Foo {\n\t\t\t//   }\n\t\t\t//   Bar.foo = 1;\n\t\t\t//\n\t\t\t// Note that it's not possible to analyze the base class to determine that\n\t\t\t// these assignments are side-effect free. For example:\n\t\t\t//\n\t\t\t//   // Some code that already ran before your code\n\t\t\t//   Object.defineProperty(Object.prototype, 'foo', {\n\t\t\t//     set(x) { imporantSideEffect(x) }\n\t\t\t//   })\n\t\t\t//\n\t\t\t//   // Your code\n\t\t\t//   class Foo {\n\t\t\t//     static foo = 1\n\t\t\t//   }\n\t\t\t//\n\t\t\tif property.Kind == PropertyField && !class.UseDefineForClassFields {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc (ctx HelperContext) ExprCanBeRemovedIfUnused(expr Expr) bool {\n\tswitch e := expr.Data.(type) {\n\tcase *EAnnotation:\n\t\treturn e.Flags.Has(CanBeRemovedIfUnusedFlag)\n\n\tcase *EInlinedEnum:\n\t\treturn ctx.ExprCanBeRemovedIfUnused(e.Value)\n\n\tcase *ENull, *EUndefined, *EMissing, *EBoolean, *ENumber, *EBigInt,\n\t\t*EString, *EThis, *ERegExp, *EFunction, *EArrow, *EImportMeta:\n\t\treturn true\n\n\tcase *EDot:\n\t\treturn e.CanBeRemovedIfUnused\n\n\tcase *EClass:\n\t\treturn ctx.ClassCanBeRemovedIfUnused(e.Class)\n\n\tcase *EIdentifier:\n\t\tif e.MustKeepDueToWithStmt {\n\t\t\treturn false\n\t\t}\n\n\t\t// Unbound identifiers cannot be removed because they can have side effects.\n\t\t// One possible side effect is throwing a ReferenceError if they don't exist.\n\t\t// Another one is a getter with side effects on the global object:\n\t\t//\n\t\t//   Object.defineProperty(globalThis, 'x', {\n\t\t//     get() {\n\t\t//       sideEffect();\n\t\t//     },\n\t\t//   });\n\t\t//\n\t\t// Be very careful about this possibility. It's tempting to treat all\n\t\t// identifier expressions as not having side effects but that's wrong. We\n\t\t// must make sure they have been declared by the code we are currently\n\t\t// compiling before we can tell that they have no side effects.\n\t\t//\n\t\t// Note that we currently ignore ReferenceErrors due to TDZ access. This is\n\t\t// incorrect but proper TDZ analysis is very complicated and would have to\n\t\t// be very conservative, which would inhibit a lot of optimizations of code\n\t\t// inside closures. This may need to be revisited if it proves problematic.\n\t\tif e.CanBeRemovedIfUnused || !ctx.isUnbound(e.Ref) {\n\t\t\treturn true\n\t\t}\n\n\tcase *EImportIdentifier:\n\t\t// References to an ES6 import item are always side-effect free in an\n\t\t// ECMAScript environment.\n\t\t//\n\t\t// They could technically have side effects if the imported module is a\n\t\t// CommonJS module and the import item was translated to a property access\n\t\t// (which esbuild's bundler does) and the property has a getter with side\n\t\t// effects.\n\t\t//\n\t\t// But this is very unlikely and respecting this edge case would mean\n\t\t// disabling tree shaking of all code that references an export from a\n\t\t// CommonJS module. It would also likely violate the expectations of some\n\t\t// developers because the code *looks* like it should be able to be tree\n\t\t// shaken.\n\t\t//\n\t\t// So we deliberately ignore this edge case and always treat import item\n\t\t// references as being side-effect free.\n\t\treturn true\n\n\tcase *EIf:\n\t\treturn ctx.ExprCanBeRemovedIfUnused(e.Test) &&\n\t\t\t((ctx.isSideEffectFreeUnboundIdentifierRef(e.Yes, e.Test, true) || ctx.ExprCanBeRemovedIfUnused(e.Yes)) &&\n\t\t\t\t(ctx.isSideEffectFreeUnboundIdentifierRef(e.No, e.Test, false) || ctx.ExprCanBeRemovedIfUnused(e.No)))\n\n\tcase *EArray:\n\t\tfor _, item := range e.Items {\n\t\t\tif spread, ok := item.Data.(*ESpread); ok {\n\t\t\t\tif _, ok := spread.Value.Data.(*EArray); ok {\n\t\t\t\t\t// Spread of an inline array such as \"[...[x]]\" is side-effect free\n\t\t\t\t\titem = spread.Value\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !ctx.ExprCanBeRemovedIfUnused(item) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\n\tcase *EObject:\n\t\tfor _, property := range e.Properties {\n\t\t\t// The key must still be evaluated if it's computed or a spread\n\t\t\tif property.Kind == PropertySpread {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif property.Flags.Has(PropertyIsComputed) && !IsPrimitiveLiteral(property.Key.Data) && !IsSymbolInstance(property.Key.Data) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif property.ValueOrNil.Data != nil && !ctx.ExprCanBeRemovedIfUnused(property.ValueOrNil) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\n\tcase *ECall:\n\t\tcanCallBeRemoved := e.CanBeUnwrappedIfUnused\n\n\t\t// A call that has been marked \"__PURE__\" can be removed if all arguments\n\t\t// can be removed. The annotation causes us to ignore the target.\n\t\tif canCallBeRemoved {\n\t\t\tfor _, arg := range e.Args {\n\t\t\t\tif !ctx.ExprCanBeRemovedIfUnused(arg) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\n\tcase *ENew:\n\t\t// A constructor call that has been marked \"__PURE__\" can be removed if all\n\t\t// arguments can be removed. The annotation causes us to ignore the target.\n\t\tif e.CanBeUnwrappedIfUnused {\n\t\t\tfor _, arg := range e.Args {\n\t\t\t\tif !ctx.ExprCanBeRemovedIfUnused(arg) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\n\tcase *EUnary:\n\t\tswitch e.Op {\n\t\t// These operators must not have any type conversions that can execute code\n\t\t// such as \"toString\" or \"valueOf\". They must also never throw any exceptions.\n\t\tcase UnOpVoid, UnOpNot:\n\t\t\treturn ctx.ExprCanBeRemovedIfUnused(e.Value)\n\n\t\tcase UnOpNeg:\n\t\t\tif _, ok := e.Value.Data.(*EBigInt); ok {\n\t\t\t\t// Consider negated bigints to have no side effects\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t// The \"typeof\" operator doesn't do any type conversions so it can be removed\n\t\t// if the result is unused and the operand has no side effects. However, it\n\t\t// has a special case where if the operand is an identifier expression such\n\t\t// as \"typeof x\" and \"x\" doesn't exist, no reference error is thrown so the\n\t\t// operation has no side effects.\n\t\tcase UnOpTypeof:\n\t\t\tif _, ok := e.Value.Data.(*EIdentifier); ok && e.WasOriginallyTypeofIdentifier {\n\t\t\t\t// Expressions such as \"typeof x\" never have any side effects\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn ctx.ExprCanBeRemovedIfUnused(e.Value)\n\t\t}\n\n\tcase *EBinary:\n\t\tswitch e.Op {\n\t\t// These operators must not have any type conversions that can execute code\n\t\t// such as \"toString\" or \"valueOf\". They must also never throw any exceptions.\n\t\tcase BinOpStrictEq, BinOpStrictNe, BinOpComma, BinOpNullishCoalescing:\n\t\t\treturn ctx.ExprCanBeRemovedIfUnused(e.Left) && ctx.ExprCanBeRemovedIfUnused(e.Right)\n\n\t\t// Special-case \"||\" to make sure \"typeof x === 'undefined' || x\" can be removed\n\t\tcase BinOpLogicalOr:\n\t\t\treturn ctx.ExprCanBeRemovedIfUnused(e.Left) &&\n\t\t\t\t(ctx.isSideEffectFreeUnboundIdentifierRef(e.Right, e.Left, false) || ctx.ExprCanBeRemovedIfUnused(e.Right))\n\n\t\t// Special-case \"&&\" to make sure \"typeof x !== 'undefined' && x\" can be removed\n\t\tcase BinOpLogicalAnd:\n\t\t\treturn ctx.ExprCanBeRemovedIfUnused(e.Left) &&\n\t\t\t\t(ctx.isSideEffectFreeUnboundIdentifierRef(e.Right, e.Left, true) || ctx.ExprCanBeRemovedIfUnused(e.Right))\n\n\t\t// For \"==\" and \"!=\", pretend the operator was actually \"===\" or \"!==\". If\n\t\t// we know that we can convert it to \"==\" or \"!=\", then we can consider the\n\t\t// operator itself to have no side effects. This matters because our mangle\n\t\t// logic will convert \"typeof x === 'object'\" into \"typeof x == 'object'\"\n\t\t// and since \"typeof x === 'object'\" is considered to be side-effect free,\n\t\t// we must also consider \"typeof x == 'object'\" to be side-effect free.\n\t\tcase BinOpLooseEq, BinOpLooseNe:\n\t\t\treturn CanChangeStrictToLoose(e.Left, e.Right) && ctx.ExprCanBeRemovedIfUnused(e.Left) && ctx.ExprCanBeRemovedIfUnused(e.Right)\n\n\t\t// Special-case \"<\" and \">\" with string, number, or bigint arguments\n\t\tcase BinOpLt, BinOpGt, BinOpLe, BinOpGe:\n\t\t\tleft := KnownPrimitiveType(e.Left.Data)\n\t\t\tswitch left {\n\t\t\tcase PrimitiveString, PrimitiveNumber, PrimitiveBigInt:\n\t\t\t\treturn KnownPrimitiveType(e.Right.Data) == left && ctx.ExprCanBeRemovedIfUnused(e.Left) && ctx.ExprCanBeRemovedIfUnused(e.Right)\n\t\t\t}\n\t\t}\n\n\tcase *ETemplate:\n\t\t// A template can be removed if it has no tag and every value has no side\n\t\t// effects and results in some kind of primitive, since all primitives\n\t\t// have a \"ToString\" operation with no side effects.\n\t\tif e.TagOrNil.Data == nil || e.CanBeUnwrappedIfUnused {\n\t\t\tfor _, part := range e.Parts {\n\t\t\t\tif !ctx.ExprCanBeRemovedIfUnused(part.Value) || KnownPrimitiveType(part.Value.Data) == PrimitiveUnknown {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\t}\n\n\t// Assume all other expression types have side effects and cannot be removed\n\treturn false\n}\n\nfunc (ctx HelperContext) isSideEffectFreeUnboundIdentifierRef(value Expr, guardCondition Expr, isYesBranch bool) bool {\n\tif id, ok := value.Data.(*EIdentifier); ok && ctx.isUnbound(id.Ref) {\n\t\tif binary, ok := guardCondition.Data.(*EBinary); ok {\n\t\t\tswitch binary.Op {\n\t\t\tcase BinOpStrictEq, BinOpStrictNe, BinOpLooseEq, BinOpLooseNe:\n\t\t\t\t// Pattern match for \"typeof x !== <string>\"\n\t\t\t\ttypeof, string := binary.Left, binary.Right\n\t\t\t\tif _, ok := typeof.Data.(*EString); ok {\n\t\t\t\t\ttypeof, string = string, typeof\n\t\t\t\t}\n\t\t\t\tif typeof, ok := typeof.Data.(*EUnary); ok && typeof.Op == UnOpTypeof && typeof.WasOriginallyTypeofIdentifier {\n\t\t\t\t\tif text, ok := string.Data.(*EString); ok {\n\t\t\t\t\t\t// In \"typeof x !== 'undefined' ? x : null\", the reference to \"x\" is side-effect free\n\t\t\t\t\t\t// In \"typeof x === 'object' ? x : null\", the reference to \"x\" is side-effect free\n\t\t\t\t\t\tif (helpers.UTF16EqualsString(text.Value, \"undefined\") == isYesBranch) ==\n\t\t\t\t\t\t\t(binary.Op == BinOpStrictNe || binary.Op == BinOpLooseNe) {\n\t\t\t\t\t\t\tif id2, ok := typeof.Value.Data.(*EIdentifier); ok && id2.Ref == id.Ref {\n\t\t\t\t\t\t\t\treturn true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tcase BinOpLt, BinOpGt, BinOpLe, BinOpGe:\n\t\t\t\t// Pattern match for \"typeof x < <string>\"\n\t\t\t\ttypeof, string := binary.Left, binary.Right\n\t\t\t\tif _, ok := typeof.Data.(*EString); ok {\n\t\t\t\t\ttypeof, string = string, typeof\n\t\t\t\t\tisYesBranch = !isYesBranch\n\t\t\t\t}\n\t\t\t\tif typeof, ok := typeof.Data.(*EUnary); ok && typeof.Op == UnOpTypeof && typeof.WasOriginallyTypeofIdentifier {\n\t\t\t\t\tif text, ok := string.Data.(*EString); ok && helpers.UTF16EqualsString(text.Value, \"u\") {\n\t\t\t\t\t\t// In \"typeof x < 'u' ? x : null\", the reference to \"x\" is side-effect free\n\t\t\t\t\t\t// In \"typeof x > 'u' ? x : null\", the reference to \"x\" is side-effect free\n\t\t\t\t\t\tif isYesBranch == (binary.Op == BinOpLt || binary.Op == BinOpLe) {\n\t\t\t\t\t\t\tif id2, ok := typeof.Value.Data.(*EIdentifier); ok && id2.Ref == id.Ref {\n\t\t\t\t\t\t\t\treturn true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc StringToEquivalentNumberValue(value []uint16) (float64, bool) {\n\tif len(value) > 0 {\n\t\tvar intValue int32\n\t\tisNegative := false\n\t\tstart := 0\n\n\t\tif value[0] == '-' && len(value) > 1 {\n\t\t\tisNegative = true\n\t\t\tstart++\n\t\t}\n\n\t\tfor _, c := range value[start:] {\n\t\t\tif c < '0' || c > '9' {\n\t\t\t\treturn 0, false\n\t\t\t}\n\t\t\tintValue = intValue*10 + int32(c) - '0'\n\t\t}\n\n\t\tif isNegative {\n\t\t\tintValue = -intValue\n\t\t}\n\n\t\tif helpers.UTF16EqualsString(value, strconv.FormatInt(int64(intValue), 10)) {\n\t\t\treturn float64(intValue), true\n\t\t}\n\t}\n\n\treturn 0, false\n}\n\n// This function intentionally avoids mutating the input AST so it can be\n// called after the AST has been frozen (i.e. after parsing ends).\nfunc InlineSpreadsOfArrayLiterals(values []Expr) (results []Expr) {\n\tfor _, value := range values {\n\t\tif spread, ok := value.Data.(*ESpread); ok {\n\t\t\tif array, ok := spread.Value.Data.(*EArray); ok {\n\t\t\t\tfor _, item := range array.Items {\n\t\t\t\t\tif _, ok := item.Data.(*EMissing); ok {\n\t\t\t\t\t\tresults = append(results, Expr{Loc: item.Loc, Data: EUndefinedShared})\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresults = append(results, item)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tresults = append(results, value)\n\t}\n\treturn\n}\n\n// This function intentionally avoids mutating the input AST so it can be\n// called after the AST has been frozen (i.e. after parsing ends).\nfunc MangleObjectSpread(properties []Property) []Property {\n\tvar result []Property\n\tfor _, property := range properties {\n\t\tif property.Kind == PropertySpread {\n\t\t\tswitch v := property.ValueOrNil.Data.(type) {\n\t\t\tcase *EBoolean, *ENull, *EUndefined, *ENumber,\n\t\t\t\t*EBigInt, *ERegExp, *EFunction, *EArrow:\n\t\t\t\t// This value is ignored because it doesn't have any of its own properties\n\t\t\t\tcontinue\n\n\t\t\tcase *EObject:\n\t\t\t\tfor i, p := range v.Properties {\n\t\t\t\t\t// Getters are evaluated at iteration time. The property\n\t\t\t\t\t// descriptor is not inlined into the caller. Since we are not\n\t\t\t\t\t// evaluating code at compile time, just bail if we hit one\n\t\t\t\t\t// and preserve the spread with the remaining properties.\n\t\t\t\t\tif p.Kind == PropertyGetter || p.Kind == PropertySetter {\n\t\t\t\t\t\t// Don't mutate the original AST\n\t\t\t\t\t\tclone := *v\n\t\t\t\t\t\tclone.Properties = v.Properties[i:]\n\t\t\t\t\t\tproperty.ValueOrNil.Data = &clone\n\t\t\t\t\t\tresult = append(result, property)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\t// Also bail if we hit a verbatim \"__proto__\" key. This will\n\t\t\t\t\t// actually set the prototype of the object being spread so\n\t\t\t\t\t// inlining it is not correct.\n\t\t\t\t\tif p.Kind == PropertyField && !p.Flags.Has(PropertyIsComputed) {\n\t\t\t\t\t\tif str, ok := p.Key.Data.(*EString); ok && helpers.UTF16EqualsString(str.Value, \"__proto__\") {\n\t\t\t\t\t\t\t// Don't mutate the original AST\n\t\t\t\t\t\t\tclone := *v\n\t\t\t\t\t\t\tclone.Properties = v.Properties[i:]\n\t\t\t\t\t\t\tproperty.ValueOrNil.Data = &clone\n\t\t\t\t\t\t\tresult = append(result, property)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresult = append(result, p)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tresult = append(result, property)\n\t}\n\treturn result\n}\n\n// This function intentionally avoids mutating the input AST so it can be\n// called after the AST has been frozen (i.e. after parsing ends).\nfunc (ctx HelperContext) MangleIfExpr(loc logger.Loc, e *EIf, unsupportedFeatures compat.JSFeature) Expr {\n\ttest := e.Test\n\tyes := e.Yes\n\tno := e.No\n\n\t// \"(a, b) ? c : d\" => \"a, b ? c : d\"\n\tif comma, ok := test.Data.(*EBinary); ok && comma.Op == BinOpComma {\n\t\treturn JoinWithComma(comma.Left, ctx.MangleIfExpr(comma.Right.Loc, &EIf{\n\t\t\tTest: comma.Right,\n\t\t\tYes:  yes,\n\t\t\tNo:   no,\n\t\t}, unsupportedFeatures))\n\t}\n\n\t// \"!a ? b : c\" => \"a ? c : b\"\n\tif not, ok := test.Data.(*EUnary); ok && not.Op == UnOpNot {\n\t\ttest = not.Value\n\t\tyes, no = no, yes\n\t}\n\n\tif ValuesLookTheSame(yes.Data, no.Data) {\n\t\t// \"/* @__PURE__ */ a() ? b : b\" => \"b\"\n\t\tif ctx.ExprCanBeRemovedIfUnused(test) {\n\t\t\treturn yes\n\t\t}\n\n\t\t// \"a ? b : b\" => \"a, b\"\n\t\treturn JoinWithComma(test, yes)\n\t}\n\n\t// \"a ? true : false\" => \"!!a\"\n\t// \"a ? false : true\" => \"!a\"\n\tif y, ok := yes.Data.(*EBoolean); ok {\n\t\tif n, ok := no.Data.(*EBoolean); ok {\n\t\t\tif y.Value && !n.Value {\n\t\t\t\treturn Not(Not(test))\n\t\t\t}\n\t\t\tif !y.Value && n.Value {\n\t\t\t\treturn Not(test)\n\t\t\t}\n\t\t}\n\t}\n\n\tif id, ok := test.Data.(*EIdentifier); ok {\n\t\t// \"a ? a : b\" => \"a || b\"\n\t\tif id2, ok := yes.Data.(*EIdentifier); ok && id.Ref == id2.Ref {\n\t\t\treturn JoinWithLeftAssociativeOp(BinOpLogicalOr, test, no)\n\t\t}\n\n\t\t// \"a ? b : a\" => \"a && b\"\n\t\tif id2, ok := no.Data.(*EIdentifier); ok && id.Ref == id2.Ref {\n\t\t\treturn JoinWithLeftAssociativeOp(BinOpLogicalAnd, test, yes)\n\t\t}\n\t}\n\n\t// \"a ? b ? c : d : d\" => \"a && b ? c : d\"\n\tif yesIf, ok := yes.Data.(*EIf); ok && ValuesLookTheSame(yesIf.No.Data, no.Data) {\n\t\treturn Expr{Loc: loc, Data: &EIf{Test: JoinWithLeftAssociativeOp(BinOpLogicalAnd, test, yesIf.Test), Yes: yesIf.Yes, No: no}}\n\t}\n\n\t// \"a ? b : c ? b : d\" => \"a || c ? b : d\"\n\tif noIf, ok := no.Data.(*EIf); ok && ValuesLookTheSame(yes.Data, noIf.Yes.Data) {\n\t\treturn Expr{Loc: loc, Data: &EIf{Test: JoinWithLeftAssociativeOp(BinOpLogicalOr, test, noIf.Test), Yes: yes, No: noIf.No}}\n\t}\n\n\t// \"a ? c : (b, c)\" => \"(a || b), c\"\n\tif comma, ok := no.Data.(*EBinary); ok && comma.Op == BinOpComma && ValuesLookTheSame(yes.Data, comma.Right.Data) {\n\t\treturn JoinWithComma(\n\t\t\tJoinWithLeftAssociativeOp(BinOpLogicalOr, test, comma.Left),\n\t\t\tcomma.Right,\n\t\t)\n\t}\n\n\t// \"a ? (b, c) : c\" => \"(a && b), c\"\n\tif comma, ok := yes.Data.(*EBinary); ok && comma.Op == BinOpComma && ValuesLookTheSame(comma.Right.Data, no.Data) {\n\t\treturn JoinWithComma(\n\t\t\tJoinWithLeftAssociativeOp(BinOpLogicalAnd, test, comma.Left),\n\t\t\tcomma.Right,\n\t\t)\n\t}\n\n\t// \"a ? b || c : c\" => \"(a && b) || c\"\n\tif binary, ok := yes.Data.(*EBinary); ok && binary.Op == BinOpLogicalOr &&\n\t\tValuesLookTheSame(binary.Right.Data, no.Data) {\n\t\treturn Expr{Loc: loc, Data: &EBinary{\n\t\t\tOp:    BinOpLogicalOr,\n\t\t\tLeft:  JoinWithLeftAssociativeOp(BinOpLogicalAnd, test, binary.Left),\n\t\t\tRight: binary.Right,\n\t\t}}\n\t}\n\n\t// \"a ? c : b && c\" => \"(a || b) && c\"\n\tif binary, ok := no.Data.(*EBinary); ok && binary.Op == BinOpLogicalAnd &&\n\t\tValuesLookTheSame(yes.Data, binary.Right.Data) {\n\t\treturn Expr{Loc: loc, Data: &EBinary{\n\t\t\tOp:    BinOpLogicalAnd,\n\t\t\tLeft:  JoinWithLeftAssociativeOp(BinOpLogicalOr, test, binary.Left),\n\t\t\tRight: binary.Right,\n\t\t}}\n\t}\n\n\t// \"a ? b(c, d) : b(e, d)\" => \"b(a ? c : e, d)\"\n\tif y, ok := yes.Data.(*ECall); ok && len(y.Args) > 0 {\n\t\tif n, ok := no.Data.(*ECall); ok && len(n.Args) == len(y.Args) &&\n\t\t\ty.HasSameFlagsAs(n) && ValuesLookTheSame(y.Target.Data, n.Target.Data) {\n\t\t\t// Only do this if the condition can be reordered past the call target\n\t\t\t// without side effects. For example, if the test or the call target is\n\t\t\t// an unbound identifier, reordering could potentially mean evaluating\n\t\t\t// the code could throw a different ReferenceError.\n\t\t\tif ctx.ExprCanBeRemovedIfUnused(test) && ctx.ExprCanBeRemovedIfUnused(y.Target) {\n\t\t\t\tsameTailArgs := true\n\t\t\t\tfor i, count := 1, len(y.Args); i < count; i++ {\n\t\t\t\t\tif !ValuesLookTheSame(y.Args[i].Data, n.Args[i].Data) {\n\t\t\t\t\t\tsameTailArgs = false\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif sameTailArgs {\n\t\t\t\t\tyesSpread, yesIsSpread := y.Args[0].Data.(*ESpread)\n\t\t\t\t\tnoSpread, noIsSpread := n.Args[0].Data.(*ESpread)\n\n\t\t\t\t\t// \"a ? b(...c) : b(...e)\" => \"b(...a ? c : e)\"\n\t\t\t\t\tif yesIsSpread && noIsSpread {\n\t\t\t\t\t\t// Don't mutate the original AST\n\t\t\t\t\t\ttemp := EIf{Test: test, Yes: yesSpread.Value, No: noSpread.Value}\n\t\t\t\t\t\tclone := *y\n\t\t\t\t\t\tclone.Args = append([]Expr{}, clone.Args...)\n\t\t\t\t\t\tclone.Args[0] = Expr{Loc: loc, Data: &ESpread{Value: ctx.MangleIfExpr(loc, &temp, unsupportedFeatures)}}\n\t\t\t\t\t\treturn Expr{Loc: loc, Data: &clone}\n\t\t\t\t\t}\n\n\t\t\t\t\t// \"a ? b(c) : b(e)\" => \"b(a ? c : e)\"\n\t\t\t\t\tif !yesIsSpread && !noIsSpread {\n\t\t\t\t\t\t// Don't mutate the original AST\n\t\t\t\t\t\ttemp := EIf{Test: test, Yes: y.Args[0], No: n.Args[0]}\n\t\t\t\t\t\tclone := *y\n\t\t\t\t\t\tclone.Args = append([]Expr{}, clone.Args...)\n\t\t\t\t\t\tclone.Args[0] = ctx.MangleIfExpr(loc, &temp, unsupportedFeatures)\n\t\t\t\t\t\treturn Expr{Loc: loc, Data: &clone}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Try using the \"??\" or \"?.\" operators\n\tif binary, ok := test.Data.(*EBinary); ok {\n\t\tvar check Expr\n\t\tvar whenNull Expr\n\t\tvar whenNonNull Expr\n\n\t\tswitch binary.Op {\n\t\tcase BinOpLooseEq:\n\t\t\tif _, ok := binary.Right.Data.(*ENull); ok {\n\t\t\t\t// \"a == null ? _ : _\"\n\t\t\t\tcheck = binary.Left\n\t\t\t\twhenNull = yes\n\t\t\t\twhenNonNull = no\n\t\t\t} else if _, ok := binary.Left.Data.(*ENull); ok {\n\t\t\t\t// \"null == a ? _ : _\"\n\t\t\t\tcheck = binary.Right\n\t\t\t\twhenNull = yes\n\t\t\t\twhenNonNull = no\n\t\t\t}\n\n\t\tcase BinOpLooseNe:\n\t\t\tif _, ok := binary.Right.Data.(*ENull); ok {\n\t\t\t\t// \"a != null ? _ : _\"\n\t\t\t\tcheck = binary.Left\n\t\t\t\twhenNonNull = yes\n\t\t\t\twhenNull = no\n\t\t\t} else if _, ok := binary.Left.Data.(*ENull); ok {\n\t\t\t\t// \"null != a ? _ : _\"\n\t\t\t\tcheck = binary.Right\n\t\t\t\twhenNonNull = yes\n\t\t\t\twhenNull = no\n\t\t\t}\n\t\t}\n\n\t\tif ctx.ExprCanBeRemovedIfUnused(check) {\n\t\t\t// \"a != null ? a : b\" => \"a ?? b\"\n\t\t\tif !unsupportedFeatures.Has(compat.NullishCoalescing) && ValuesLookTheSame(check.Data, whenNonNull.Data) {\n\t\t\t\treturn JoinWithLeftAssociativeOp(BinOpNullishCoalescing, check, whenNull)\n\t\t\t}\n\n\t\t\t// \"a != null ? a.b.c[d](e) : undefined\" => \"a?.b.c[d](e)\"\n\t\t\tif !unsupportedFeatures.Has(compat.OptionalChain) {\n\t\t\t\tif _, ok := whenNull.Data.(*EUndefined); ok && TryToInsertOptionalChain(check, whenNonNull) {\n\t\t\t\t\treturn whenNonNull\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Don't mutate the original AST\n\tif test != e.Test || yes != e.Yes || no != e.No {\n\t\treturn Expr{Loc: loc, Data: &EIf{Test: test, Yes: yes, No: no}}\n\t}\n\n\treturn Expr{Loc: loc, Data: e}\n}\n\nfunc ForEachIdentifierBindingInDecls(decls []Decl, callback func(loc logger.Loc, b *BIdentifier)) {\n\tfor _, decl := range decls {\n\t\tForEachIdentifierBinding(decl.Binding, callback)\n\t}\n}\n\nfunc ForEachIdentifierBinding(binding Binding, callback func(loc logger.Loc, b *BIdentifier)) {\n\tswitch b := binding.Data.(type) {\n\tcase *BMissing:\n\n\tcase *BIdentifier:\n\t\tcallback(binding.Loc, b)\n\n\tcase *BArray:\n\t\tfor _, item := range b.Items {\n\t\t\tForEachIdentifierBinding(item.Binding, callback)\n\t\t}\n\n\tcase *BObject:\n\t\tfor _, property := range b.Properties {\n\t\t\tForEachIdentifierBinding(property.Value, callback)\n\t\t}\n\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n"
  },
  {
    "path": "internal/js_ast/js_ast_test.go",
    "content": "package js_ast\n\nimport \"testing\"\n\nfunc assertEqual(t *testing.T, a interface{}, b interface{}) {\n\tif a != b {\n\t\tt.Fatalf(\"%s != %s\", a, b)\n\t}\n}\n\nfunc TestGenerateNonUniqueNameFromPath(t *testing.T) {\n\tassertEqual(t, GenerateNonUniqueNameFromPath(\"<stdin>\"), \"stdin\")\n\tassertEqual(t, GenerateNonUniqueNameFromPath(\"foo/bar\"), \"bar\")\n\tassertEqual(t, GenerateNonUniqueNameFromPath(\"foo/bar.js\"), \"bar\")\n\tassertEqual(t, GenerateNonUniqueNameFromPath(\"foo/bar.min.js\"), \"bar_min\")\n\tassertEqual(t, GenerateNonUniqueNameFromPath(\"trailing//slashes//\"), \"slashes\")\n\tassertEqual(t, GenerateNonUniqueNameFromPath(\"path/with/spaces in name.js\"), \"spaces_in_name\")\n\tassertEqual(t, GenerateNonUniqueNameFromPath(\"path\\\\on\\\\windows.js\"), \"windows\")\n\tassertEqual(t, GenerateNonUniqueNameFromPath(\"node_modules/demo-pkg/index.js\"), \"demo_pkg\")\n\tassertEqual(t, GenerateNonUniqueNameFromPath(\"node_modules\\\\demo-pkg\\\\index.js\"), \"demo_pkg\")\n\tassertEqual(t, GenerateNonUniqueNameFromPath(\"123_invalid_identifier.js\"), \"invalid_identifier\")\n\tassertEqual(t, GenerateNonUniqueNameFromPath(\"emoji 🍕 name.js\"), \"emoji_name\")\n}\n"
  },
  {
    "path": "internal/js_ast/js_ident.go",
    "content": "package js_ast\n\nimport (\n\t\"strings\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n)\n\nfunc IsIdentifier(text string) bool {\n\tif len(text) == 0 {\n\t\treturn false\n\t}\n\tfor i, codePoint := range text {\n\t\tif i == 0 {\n\t\t\tif !IsIdentifierStart(codePoint) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t} else {\n\t\t\tif !IsIdentifierContinue(codePoint) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\nfunc IsIdentifierES5AndESNext(text string) bool {\n\tif len(text) == 0 {\n\t\treturn false\n\t}\n\tfor i, codePoint := range text {\n\t\tif i == 0 {\n\t\t\tif !IsIdentifierStartES5AndESNext(codePoint) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t} else {\n\t\t\tif !IsIdentifierContinueES5AndESNext(codePoint) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\nfunc ForceValidIdentifier(prefix string, text string) string {\n\tsb := strings.Builder{}\n\n\t// Private identifiers must be prefixed by \"#\"\n\tif prefix != \"\" {\n\t\tsb.WriteString(prefix)\n\t}\n\n\t// Identifier start\n\tc, width := utf8.DecodeRuneInString(text)\n\ttext = text[width:]\n\tif IsIdentifierStart(c) {\n\t\tsb.WriteRune(c)\n\t} else {\n\t\tsb.WriteRune('_')\n\t}\n\n\t// Identifier continue\n\tfor text != \"\" {\n\t\tc, width := utf8.DecodeRuneInString(text)\n\t\ttext = text[width:]\n\t\tif IsIdentifierContinue(c) {\n\t\t\tsb.WriteRune(c)\n\t\t} else {\n\t\t\tsb.WriteRune('_')\n\t\t}\n\t}\n\n\treturn sb.String()\n}\n\n// This does \"IsIdentifier(UTF16ToString(text))\" without any allocations\nfunc IsIdentifierUTF16(text []uint16) bool {\n\tn := len(text)\n\tif n == 0 {\n\t\treturn false\n\t}\n\tfor i := 0; i < n; i++ {\n\t\tisStart := i == 0\n\t\tr1 := rune(text[i])\n\t\tif r1 >= 0xD800 && r1 <= 0xDBFF && i+1 < n {\n\t\t\tif r2 := rune(text[i+1]); r2 >= 0xDC00 && r2 <= 0xDFFF {\n\t\t\t\tr1 = (r1 << 10) + r2 + (0x10000 - (0xD800 << 10) - 0xDC00)\n\t\t\t\ti++\n\t\t\t}\n\t\t}\n\t\tif isStart {\n\t\t\tif !IsIdentifierStart(r1) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t} else {\n\t\t\tif !IsIdentifierContinue(r1) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\n// This does \"IsIdentifierES5AndESNext(UTF16ToString(text))\" without any allocations\nfunc IsIdentifierES5AndESNextUTF16(text []uint16) bool {\n\tn := len(text)\n\tif n == 0 {\n\t\treturn false\n\t}\n\tfor i := 0; i < n; i++ {\n\t\tisStart := i == 0\n\t\tr1 := rune(text[i])\n\t\tif r1 >= 0xD800 && r1 <= 0xDBFF && i+1 < n {\n\t\t\tif r2 := rune(text[i+1]); r2 >= 0xDC00 && r2 <= 0xDFFF {\n\t\t\t\tr1 = (r1 << 10) + r2 + (0x10000 - (0xD800 << 10) - 0xDC00)\n\t\t\t\ti++\n\t\t\t}\n\t\t}\n\t\tif isStart {\n\t\t\tif !IsIdentifierStartES5AndESNext(r1) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t} else {\n\t\t\tif !IsIdentifierContinueES5AndESNext(r1) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\nfunc IsIdentifierStart(codePoint rune) bool {\n\tswitch codePoint {\n\tcase '_', '$',\n\t\t'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',\n\t\t'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',\n\t\t'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',\n\t\t'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z':\n\t\treturn true\n\t}\n\n\t// All ASCII identifier start code points are listed above\n\tif codePoint < 0x7F {\n\t\treturn false\n\t}\n\n\treturn unicode.Is(idStartES5OrESNext, codePoint)\n}\n\nfunc IsIdentifierContinue(codePoint rune) bool {\n\tswitch codePoint {\n\tcase '_', '$', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n\t\t'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',\n\t\t'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',\n\t\t'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',\n\t\t'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z':\n\t\treturn true\n\t}\n\n\t// All ASCII identifier start code points are listed above\n\tif codePoint < 0x7F {\n\t\treturn false\n\t}\n\n\t// ZWNJ and ZWJ are allowed in identifiers\n\tif codePoint == 0x200C || codePoint == 0x200D {\n\t\treturn true\n\t}\n\n\treturn unicode.Is(idContinueES5OrESNext, codePoint)\n}\n\nfunc IsIdentifierStartES5AndESNext(codePoint rune) bool {\n\tswitch codePoint {\n\tcase '_', '$',\n\t\t'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',\n\t\t'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',\n\t\t'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',\n\t\t'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z':\n\t\treturn true\n\t}\n\n\t// All ASCII identifier start code points are listed above\n\tif codePoint < 0x7F {\n\t\treturn false\n\t}\n\n\treturn unicode.Is(idStartES5AndESNext, codePoint)\n}\n\nfunc IsIdentifierContinueES5AndESNext(codePoint rune) bool {\n\tswitch codePoint {\n\tcase '_', '$', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n\t\t'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',\n\t\t'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',\n\t\t'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',\n\t\t'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z':\n\t\treturn true\n\t}\n\n\t// All ASCII identifier start code points are listed above\n\tif codePoint < 0x7F {\n\t\treturn false\n\t}\n\n\t// ZWNJ and ZWJ are allowed in identifiers\n\tif codePoint == 0x200C || codePoint == 0x200D {\n\t\treturn true\n\t}\n\n\treturn unicode.Is(idContinueES5AndESNext, codePoint)\n}\n\n// See the \"White Space Code Points\" table in the ECMAScript standard\nfunc IsWhitespace(codePoint rune) bool {\n\tswitch codePoint {\n\tcase\n\t\t'\\u0009', // character tabulation\n\t\t'\\u000B', // line tabulation\n\t\t'\\u000C', // form feed\n\t\t'\\u0020', // space\n\t\t'\\u00A0', // no-break space\n\n\t\t// Unicode \"Space_Separator\" code points\n\t\t'\\u1680', // ogham space mark\n\t\t'\\u2000', // en quad\n\t\t'\\u2001', // em quad\n\t\t'\\u2002', // en space\n\t\t'\\u2003', // em space\n\t\t'\\u2004', // three-per-em space\n\t\t'\\u2005', // four-per-em space\n\t\t'\\u2006', // six-per-em space\n\t\t'\\u2007', // figure space\n\t\t'\\u2008', // punctuation space\n\t\t'\\u2009', // thin space\n\t\t'\\u200A', // hair space\n\t\t'\\u202F', // narrow no-break space\n\t\t'\\u205F', // medium mathematical space\n\t\t'\\u3000', // ideographic space\n\n\t\t'\\uFEFF': // zero width non-breaking space\n\t\treturn true\n\n\tdefault:\n\t\treturn false\n\t}\n}\n"
  },
  {
    "path": "internal/js_ast/unicode.go",
    "content": "// This file was automatically generated by gen-unicode-table.js. Do not edit.\npackage js_ast\n\nimport \"unicode\"\n\nvar idStartES5AndESNext = &unicode.RangeTable{\n\tLatinOffset: 117,\n\tR16: []unicode.Range16{\n\t\t{Lo: 0x41, Hi: 0x5a, Stride: 1},\n\t\t{Lo: 0x61, Hi: 0x7a, Stride: 1},\n\t\t{Lo: 0xaa, Hi: 0xaa, Stride: 1},\n\t\t{Lo: 0xb5, Hi: 0xb5, Stride: 1},\n\t\t{Lo: 0xba, Hi: 0xba, Stride: 1},\n\t\t{Lo: 0xc0, Hi: 0xd6, Stride: 1},\n\t\t{Lo: 0xd8, Hi: 0xf6, Stride: 1},\n\t\t{Lo: 0xf8, Hi: 0x21f, Stride: 1},\n\t\t{Lo: 0x222, Hi: 0x233, Stride: 1},\n\t\t{Lo: 0x250, Hi: 0x2ad, Stride: 1},\n\t\t{Lo: 0x2b0, Hi: 0x2b8, Stride: 1},\n\t\t{Lo: 0x2bb, Hi: 0x2c1, Stride: 1},\n\t\t{Lo: 0x2d0, Hi: 0x2d1, Stride: 1},\n\t\t{Lo: 0x2e0, Hi: 0x2e4, Stride: 1},\n\t\t{Lo: 0x2ee, Hi: 0x2ee, Stride: 1},\n\t\t{Lo: 0x37a, Hi: 0x37a, Stride: 1},\n\t\t{Lo: 0x386, Hi: 0x386, Stride: 1},\n\t\t{Lo: 0x388, Hi: 0x38a, Stride: 1},\n\t\t{Lo: 0x38c, Hi: 0x38c, Stride: 1},\n\t\t{Lo: 0x38e, Hi: 0x3a1, Stride: 1},\n\t\t{Lo: 0x3a3, Hi: 0x3ce, Stride: 1},\n\t\t{Lo: 0x3d0, Hi: 0x3d7, Stride: 1},\n\t\t{Lo: 0x3da, Hi: 0x3f3, Stride: 1},\n\t\t{Lo: 0x400, Hi: 0x481, Stride: 1},\n\t\t{Lo: 0x48c, Hi: 0x4c4, Stride: 1},\n\t\t{Lo: 0x4c7, Hi: 0x4c8, Stride: 1},\n\t\t{Lo: 0x4cb, Hi: 0x4cc, Stride: 1},\n\t\t{Lo: 0x4d0, Hi: 0x4f5, Stride: 1},\n\t\t{Lo: 0x4f8, Hi: 0x4f9, Stride: 1},\n\t\t{Lo: 0x531, Hi: 0x556, Stride: 1},\n\t\t{Lo: 0x559, Hi: 0x559, Stride: 1},\n\t\t{Lo: 0x561, Hi: 0x587, Stride: 1},\n\t\t{Lo: 0x5d0, Hi: 0x5ea, Stride: 1},\n\t\t{Lo: 0x5f0, Hi: 0x5f2, Stride: 1},\n\t\t{Lo: 0x621, Hi: 0x63a, Stride: 1},\n\t\t{Lo: 0x640, Hi: 0x64a, Stride: 1},\n\t\t{Lo: 0x671, Hi: 0x6d3, Stride: 1},\n\t\t{Lo: 0x6d5, Hi: 0x6d5, Stride: 1},\n\t\t{Lo: 0x6e5, Hi: 0x6e6, Stride: 1},\n\t\t{Lo: 0x6fa, Hi: 0x6fc, Stride: 1},\n\t\t{Lo: 0x710, Hi: 0x710, Stride: 1},\n\t\t{Lo: 0x712, Hi: 0x72c, Stride: 1},\n\t\t{Lo: 0x780, Hi: 0x7a5, Stride: 1},\n\t\t{Lo: 0x905, Hi: 0x939, Stride: 1},\n\t\t{Lo: 0x93d, Hi: 0x93d, Stride: 1},\n\t\t{Lo: 0x950, Hi: 0x950, Stride: 1},\n\t\t{Lo: 0x958, Hi: 0x961, Stride: 1},\n\t\t{Lo: 0x985, Hi: 0x98c, Stride: 1},\n\t\t{Lo: 0x98f, Hi: 0x990, Stride: 1},\n\t\t{Lo: 0x993, Hi: 0x9a8, Stride: 1},\n\t\t{Lo: 0x9aa, Hi: 0x9b0, Stride: 1},\n\t\t{Lo: 0x9b2, Hi: 0x9b2, Stride: 1},\n\t\t{Lo: 0x9b6, Hi: 0x9b9, Stride: 1},\n\t\t{Lo: 0x9dc, Hi: 0x9dd, Stride: 1},\n\t\t{Lo: 0x9df, Hi: 0x9e1, Stride: 1},\n\t\t{Lo: 0x9f0, Hi: 0x9f1, Stride: 1},\n\t\t{Lo: 0xa05, Hi: 0xa0a, Stride: 1},\n\t\t{Lo: 0xa0f, Hi: 0xa10, Stride: 1},\n\t\t{Lo: 0xa13, Hi: 0xa28, Stride: 1},\n\t\t{Lo: 0xa2a, Hi: 0xa30, Stride: 1},\n\t\t{Lo: 0xa32, Hi: 0xa33, Stride: 1},\n\t\t{Lo: 0xa35, Hi: 0xa36, Stride: 1},\n\t\t{Lo: 0xa38, Hi: 0xa39, Stride: 1},\n\t\t{Lo: 0xa59, Hi: 0xa5c, Stride: 1},\n\t\t{Lo: 0xa5e, Hi: 0xa5e, Stride: 1},\n\t\t{Lo: 0xa72, Hi: 0xa74, Stride: 1},\n\t\t{Lo: 0xa85, Hi: 0xa8b, Stride: 1},\n\t\t{Lo: 0xa8d, Hi: 0xa8d, Stride: 1},\n\t\t{Lo: 0xa8f, Hi: 0xa91, Stride: 1},\n\t\t{Lo: 0xa93, Hi: 0xaa8, Stride: 1},\n\t\t{Lo: 0xaaa, Hi: 0xab0, Stride: 1},\n\t\t{Lo: 0xab2, Hi: 0xab3, Stride: 1},\n\t\t{Lo: 0xab5, Hi: 0xab9, Stride: 1},\n\t\t{Lo: 0xabd, Hi: 0xabd, Stride: 1},\n\t\t{Lo: 0xad0, Hi: 0xad0, Stride: 1},\n\t\t{Lo: 0xae0, Hi: 0xae0, Stride: 1},\n\t\t{Lo: 0xb05, Hi: 0xb0c, Stride: 1},\n\t\t{Lo: 0xb0f, Hi: 0xb10, Stride: 1},\n\t\t{Lo: 0xb13, Hi: 0xb28, Stride: 1},\n\t\t{Lo: 0xb2a, Hi: 0xb30, Stride: 1},\n\t\t{Lo: 0xb32, Hi: 0xb33, Stride: 1},\n\t\t{Lo: 0xb36, Hi: 0xb39, Stride: 1},\n\t\t{Lo: 0xb3d, Hi: 0xb3d, Stride: 1},\n\t\t{Lo: 0xb5c, Hi: 0xb5d, Stride: 1},\n\t\t{Lo: 0xb5f, Hi: 0xb61, Stride: 1},\n\t\t{Lo: 0xb85, Hi: 0xb8a, Stride: 1},\n\t\t{Lo: 0xb8e, Hi: 0xb90, Stride: 1},\n\t\t{Lo: 0xb92, Hi: 0xb95, Stride: 1},\n\t\t{Lo: 0xb99, Hi: 0xb9a, Stride: 1},\n\t\t{Lo: 0xb9c, Hi: 0xb9c, Stride: 1},\n\t\t{Lo: 0xb9e, Hi: 0xb9f, Stride: 1},\n\t\t{Lo: 0xba3, Hi: 0xba4, Stride: 1},\n\t\t{Lo: 0xba8, Hi: 0xbaa, Stride: 1},\n\t\t{Lo: 0xbae, Hi: 0xbb5, Stride: 1},\n\t\t{Lo: 0xbb7, Hi: 0xbb9, Stride: 1},\n\t\t{Lo: 0xc05, Hi: 0xc0c, Stride: 1},\n\t\t{Lo: 0xc0e, Hi: 0xc10, Stride: 1},\n\t\t{Lo: 0xc12, Hi: 0xc28, Stride: 1},\n\t\t{Lo: 0xc2a, Hi: 0xc33, Stride: 1},\n\t\t{Lo: 0xc35, Hi: 0xc39, Stride: 1},\n\t\t{Lo: 0xc60, Hi: 0xc61, Stride: 1},\n\t\t{Lo: 0xc85, Hi: 0xc8c, Stride: 1},\n\t\t{Lo: 0xc8e, Hi: 0xc90, Stride: 1},\n\t\t{Lo: 0xc92, Hi: 0xca8, Stride: 1},\n\t\t{Lo: 0xcaa, Hi: 0xcb3, Stride: 1},\n\t\t{Lo: 0xcb5, Hi: 0xcb9, Stride: 1},\n\t\t{Lo: 0xcde, Hi: 0xcde, Stride: 1},\n\t\t{Lo: 0xce0, Hi: 0xce1, Stride: 1},\n\t\t{Lo: 0xd05, Hi: 0xd0c, Stride: 1},\n\t\t{Lo: 0xd0e, Hi: 0xd10, Stride: 1},\n\t\t{Lo: 0xd12, Hi: 0xd28, Stride: 1},\n\t\t{Lo: 0xd2a, Hi: 0xd39, Stride: 1},\n\t\t{Lo: 0xd60, Hi: 0xd61, Stride: 1},\n\t\t{Lo: 0xd85, Hi: 0xd96, Stride: 1},\n\t\t{Lo: 0xd9a, Hi: 0xdb1, Stride: 1},\n\t\t{Lo: 0xdb3, Hi: 0xdbb, Stride: 1},\n\t\t{Lo: 0xdbd, Hi: 0xdbd, Stride: 1},\n\t\t{Lo: 0xdc0, Hi: 0xdc6, Stride: 1},\n\t\t{Lo: 0xe01, Hi: 0xe30, Stride: 1},\n\t\t{Lo: 0xe32, Hi: 0xe33, Stride: 1},\n\t\t{Lo: 0xe40, Hi: 0xe46, Stride: 1},\n\t\t{Lo: 0xe81, Hi: 0xe82, Stride: 1},\n\t\t{Lo: 0xe84, Hi: 0xe84, Stride: 1},\n\t\t{Lo: 0xe87, Hi: 0xe88, Stride: 1},\n\t\t{Lo: 0xe8a, Hi: 0xe8a, Stride: 1},\n\t\t{Lo: 0xe8d, Hi: 0xe8d, Stride: 1},\n\t\t{Lo: 0xe94, Hi: 0xe97, Stride: 1},\n\t\t{Lo: 0xe99, Hi: 0xe9f, Stride: 1},\n\t\t{Lo: 0xea1, Hi: 0xea3, Stride: 1},\n\t\t{Lo: 0xea5, Hi: 0xea5, Stride: 1},\n\t\t{Lo: 0xea7, Hi: 0xea7, Stride: 1},\n\t\t{Lo: 0xeaa, Hi: 0xeab, Stride: 1},\n\t\t{Lo: 0xead, Hi: 0xeb0, Stride: 1},\n\t\t{Lo: 0xeb2, Hi: 0xeb3, Stride: 1},\n\t\t{Lo: 0xebd, Hi: 0xebd, Stride: 1},\n\t\t{Lo: 0xec0, Hi: 0xec4, Stride: 1},\n\t\t{Lo: 0xec6, Hi: 0xec6, Stride: 1},\n\t\t{Lo: 0xedc, Hi: 0xedd, Stride: 1},\n\t\t{Lo: 0xf00, Hi: 0xf00, Stride: 1},\n\t\t{Lo: 0xf40, Hi: 0xf47, Stride: 1},\n\t\t{Lo: 0xf49, Hi: 0xf6a, Stride: 1},\n\t\t{Lo: 0xf88, Hi: 0xf8b, Stride: 1},\n\t},\n\tR32: []unicode.Range32{\n\t\t{Lo: 0x1000, Hi: 0x1021, Stride: 1},\n\t\t{Lo: 0x1023, Hi: 0x1027, Stride: 1},\n\t\t{Lo: 0x1029, Hi: 0x102a, Stride: 1},\n\t\t{Lo: 0x1050, Hi: 0x1055, Stride: 1},\n\t\t{Lo: 0x10a0, Hi: 0x10c5, Stride: 1},\n\t\t{Lo: 0x10d0, Hi: 0x10f6, Stride: 1},\n\t\t{Lo: 0x1100, Hi: 0x1159, Stride: 1},\n\t\t{Lo: 0x115f, Hi: 0x11a2, Stride: 1},\n\t\t{Lo: 0x11a8, Hi: 0x11f9, Stride: 1},\n\t\t{Lo: 0x1200, Hi: 0x1206, Stride: 1},\n\t\t{Lo: 0x1208, Hi: 0x1246, Stride: 1},\n\t\t{Lo: 0x1248, Hi: 0x1248, Stride: 1},\n\t\t{Lo: 0x124a, Hi: 0x124d, Stride: 1},\n\t\t{Lo: 0x1250, Hi: 0x1256, Stride: 1},\n\t\t{Lo: 0x1258, Hi: 0x1258, Stride: 1},\n\t\t{Lo: 0x125a, Hi: 0x125d, Stride: 1},\n\t\t{Lo: 0x1260, Hi: 0x1286, Stride: 1},\n\t\t{Lo: 0x1288, Hi: 0x1288, Stride: 1},\n\t\t{Lo: 0x128a, Hi: 0x128d, Stride: 1},\n\t\t{Lo: 0x1290, Hi: 0x12ae, Stride: 1},\n\t\t{Lo: 0x12b0, Hi: 0x12b0, Stride: 1},\n\t\t{Lo: 0x12b2, Hi: 0x12b5, Stride: 1},\n\t\t{Lo: 0x12b8, Hi: 0x12be, Stride: 1},\n\t\t{Lo: 0x12c0, Hi: 0x12c0, Stride: 1},\n\t\t{Lo: 0x12c2, Hi: 0x12c5, Stride: 1},\n\t\t{Lo: 0x12c8, Hi: 0x12ce, Stride: 1},\n\t\t{Lo: 0x12d0, Hi: 0x12d6, Stride: 1},\n\t\t{Lo: 0x12d8, Hi: 0x12ee, Stride: 1},\n\t\t{Lo: 0x12f0, Hi: 0x130e, Stride: 1},\n\t\t{Lo: 0x1310, Hi: 0x1310, Stride: 1},\n\t\t{Lo: 0x1312, Hi: 0x1315, Stride: 1},\n\t\t{Lo: 0x1318, Hi: 0x131e, Stride: 1},\n\t\t{Lo: 0x1320, Hi: 0x1346, Stride: 1},\n\t\t{Lo: 0x1348, Hi: 0x135a, Stride: 1},\n\t\t{Lo: 0x13a0, Hi: 0x13f4, Stride: 1},\n\t\t{Lo: 0x1401, Hi: 0x166c, Stride: 1},\n\t\t{Lo: 0x166f, Hi: 0x1676, Stride: 1},\n\t\t{Lo: 0x1681, Hi: 0x169a, Stride: 1},\n\t\t{Lo: 0x16a0, Hi: 0x16ea, Stride: 1},\n\t\t{Lo: 0x1780, Hi: 0x17b3, Stride: 1},\n\t\t{Lo: 0x1820, Hi: 0x1877, Stride: 1},\n\t\t{Lo: 0x1880, Hi: 0x18a8, Stride: 1},\n\t\t{Lo: 0x1e00, Hi: 0x1e9b, Stride: 1},\n\t\t{Lo: 0x1ea0, Hi: 0x1ef9, Stride: 1},\n\t\t{Lo: 0x1f00, Hi: 0x1f15, Stride: 1},\n\t\t{Lo: 0x1f18, Hi: 0x1f1d, Stride: 1},\n\t\t{Lo: 0x1f20, Hi: 0x1f45, Stride: 1},\n\t\t{Lo: 0x1f48, Hi: 0x1f4d, Stride: 1},\n\t\t{Lo: 0x1f50, Hi: 0x1f57, Stride: 1},\n\t\t{Lo: 0x1f59, Hi: 0x1f59, Stride: 1},\n\t\t{Lo: 0x1f5b, Hi: 0x1f5b, Stride: 1},\n\t\t{Lo: 0x1f5d, Hi: 0x1f5d, Stride: 1},\n\t\t{Lo: 0x1f5f, Hi: 0x1f7d, Stride: 1},\n\t\t{Lo: 0x1f80, Hi: 0x1fb4, Stride: 1},\n\t\t{Lo: 0x1fb6, Hi: 0x1fbc, Stride: 1},\n\t\t{Lo: 0x1fbe, Hi: 0x1fbe, Stride: 1},\n\t\t{Lo: 0x1fc2, Hi: 0x1fc4, Stride: 1},\n\t\t{Lo: 0x1fc6, Hi: 0x1fcc, Stride: 1},\n\t\t{Lo: 0x1fd0, Hi: 0x1fd3, Stride: 1},\n\t\t{Lo: 0x1fd6, Hi: 0x1fdb, Stride: 1},\n\t\t{Lo: 0x1fe0, Hi: 0x1fec, Stride: 1},\n\t\t{Lo: 0x1ff2, Hi: 0x1ff4, Stride: 1},\n\t\t{Lo: 0x1ff6, Hi: 0x1ffc, Stride: 1},\n\t\t{Lo: 0x207f, Hi: 0x207f, Stride: 1},\n\t\t{Lo: 0x2102, Hi: 0x2102, Stride: 1},\n\t\t{Lo: 0x2107, Hi: 0x2107, Stride: 1},\n\t\t{Lo: 0x210a, Hi: 0x2113, Stride: 1},\n\t\t{Lo: 0x2115, Hi: 0x2115, Stride: 1},\n\t\t{Lo: 0x2119, Hi: 0x211d, Stride: 1},\n\t\t{Lo: 0x2124, Hi: 0x2124, Stride: 1},\n\t\t{Lo: 0x2126, Hi: 0x2126, Stride: 1},\n\t\t{Lo: 0x2128, Hi: 0x2128, Stride: 1},\n\t\t{Lo: 0x212a, Hi: 0x212d, Stride: 1},\n\t\t{Lo: 0x212f, Hi: 0x2131, Stride: 1},\n\t\t{Lo: 0x2133, Hi: 0x2139, Stride: 1},\n\t\t{Lo: 0x3005, Hi: 0x3006, Stride: 1},\n\t\t{Lo: 0x3031, Hi: 0x3035, Stride: 1},\n\t\t{Lo: 0x3041, Hi: 0x3094, Stride: 1},\n\t\t{Lo: 0x309d, Hi: 0x309e, Stride: 1},\n\t\t{Lo: 0x30a1, Hi: 0x30fa, Stride: 1},\n\t\t{Lo: 0x30fc, Hi: 0x30fe, Stride: 1},\n\t\t{Lo: 0x3105, Hi: 0x312c, Stride: 1},\n\t\t{Lo: 0x3131, Hi: 0x318e, Stride: 1},\n\t\t{Lo: 0x31a0, Hi: 0x31b7, Stride: 1},\n\t\t{Lo: 0x3400, Hi: 0x4db5, Stride: 1},\n\t\t{Lo: 0x4e00, Hi: 0x9fa5, Stride: 1},\n\t\t{Lo: 0xa000, Hi: 0xa48c, Stride: 1},\n\t\t{Lo: 0xac00, Hi: 0xd7a3, Stride: 1},\n\t\t{Lo: 0xf900, Hi: 0xfa2d, Stride: 1},\n\t\t{Lo: 0xfb00, Hi: 0xfb06, Stride: 1},\n\t\t{Lo: 0xfb13, Hi: 0xfb17, Stride: 1},\n\t\t{Lo: 0xfb1d, Hi: 0xfb1d, Stride: 1},\n\t\t{Lo: 0xfb1f, Hi: 0xfb28, Stride: 1},\n\t\t{Lo: 0xfb2a, Hi: 0xfb36, Stride: 1},\n\t\t{Lo: 0xfb38, Hi: 0xfb3c, Stride: 1},\n\t\t{Lo: 0xfb3e, Hi: 0xfb3e, Stride: 1},\n\t\t{Lo: 0xfb40, Hi: 0xfb41, Stride: 1},\n\t\t{Lo: 0xfb43, Hi: 0xfb44, Stride: 1},\n\t\t{Lo: 0xfb46, Hi: 0xfbb1, Stride: 1},\n\t\t{Lo: 0xfbd3, Hi: 0xfd3d, Stride: 1},\n\t\t{Lo: 0xfd50, Hi: 0xfd8f, Stride: 1},\n\t\t{Lo: 0xfd92, Hi: 0xfdc7, Stride: 1},\n\t\t{Lo: 0xfdf0, Hi: 0xfdfb, Stride: 1},\n\t\t{Lo: 0xfe70, Hi: 0xfe72, Stride: 1},\n\t\t{Lo: 0xfe74, Hi: 0xfe74, Stride: 1},\n\t\t{Lo: 0xfe76, Hi: 0xfefc, Stride: 1},\n\t\t{Lo: 0xff21, Hi: 0xff3a, Stride: 1},\n\t\t{Lo: 0xff41, Hi: 0xff5a, Stride: 1},\n\t\t{Lo: 0xff66, Hi: 0xffbe, Stride: 1},\n\t\t{Lo: 0xffc2, Hi: 0xffc7, Stride: 1},\n\t\t{Lo: 0xffca, Hi: 0xffcf, Stride: 1},\n\t\t{Lo: 0xffd2, Hi: 0xffd7, Stride: 1},\n\t\t{Lo: 0xffda, Hi: 0xffdc, Stride: 1},\n\t},\n}\n\nvar idContinueES5AndESNext = &unicode.RangeTable{\n\tLatinOffset: 128,\n\tR16: []unicode.Range16{\n\t\t{Lo: 0x30, Hi: 0x39, Stride: 1},\n\t\t{Lo: 0x41, Hi: 0x5a, Stride: 1},\n\t\t{Lo: 0x5f, Hi: 0x5f, Stride: 1},\n\t\t{Lo: 0x61, Hi: 0x7a, Stride: 1},\n\t\t{Lo: 0xaa, Hi: 0xaa, Stride: 1},\n\t\t{Lo: 0xb5, Hi: 0xb5, Stride: 1},\n\t\t{Lo: 0xba, Hi: 0xba, Stride: 1},\n\t\t{Lo: 0xc0, Hi: 0xd6, Stride: 1},\n\t\t{Lo: 0xd8, Hi: 0xf6, Stride: 1},\n\t\t{Lo: 0xf8, Hi: 0x21f, Stride: 1},\n\t\t{Lo: 0x222, Hi: 0x233, Stride: 1},\n\t\t{Lo: 0x250, Hi: 0x2ad, Stride: 1},\n\t\t{Lo: 0x2b0, Hi: 0x2b8, Stride: 1},\n\t\t{Lo: 0x2bb, Hi: 0x2c1, Stride: 1},\n\t\t{Lo: 0x2d0, Hi: 0x2d1, Stride: 1},\n\t\t{Lo: 0x2e0, Hi: 0x2e4, Stride: 1},\n\t\t{Lo: 0x2ee, Hi: 0x2ee, Stride: 1},\n\t\t{Lo: 0x300, Hi: 0x34e, Stride: 1},\n\t\t{Lo: 0x360, Hi: 0x362, Stride: 1},\n\t\t{Lo: 0x37a, Hi: 0x37a, Stride: 1},\n\t\t{Lo: 0x386, Hi: 0x386, Stride: 1},\n\t\t{Lo: 0x388, Hi: 0x38a, Stride: 1},\n\t\t{Lo: 0x38c, Hi: 0x38c, Stride: 1},\n\t\t{Lo: 0x38e, Hi: 0x3a1, Stride: 1},\n\t\t{Lo: 0x3a3, Hi: 0x3ce, Stride: 1},\n\t\t{Lo: 0x3d0, Hi: 0x3d7, Stride: 1},\n\t\t{Lo: 0x3da, Hi: 0x3f3, Stride: 1},\n\t\t{Lo: 0x400, Hi: 0x481, Stride: 1},\n\t\t{Lo: 0x483, Hi: 0x486, Stride: 1},\n\t\t{Lo: 0x48c, Hi: 0x4c4, Stride: 1},\n\t\t{Lo: 0x4c7, Hi: 0x4c8, Stride: 1},\n\t\t{Lo: 0x4cb, Hi: 0x4cc, Stride: 1},\n\t\t{Lo: 0x4d0, Hi: 0x4f5, Stride: 1},\n\t\t{Lo: 0x4f8, Hi: 0x4f9, Stride: 1},\n\t\t{Lo: 0x531, Hi: 0x556, Stride: 1},\n\t\t{Lo: 0x559, Hi: 0x559, Stride: 1},\n\t\t{Lo: 0x561, Hi: 0x587, Stride: 1},\n\t\t{Lo: 0x591, Hi: 0x5a1, Stride: 1},\n\t\t{Lo: 0x5a3, Hi: 0x5b9, Stride: 1},\n\t\t{Lo: 0x5bb, Hi: 0x5bd, Stride: 1},\n\t\t{Lo: 0x5bf, Hi: 0x5bf, Stride: 1},\n\t\t{Lo: 0x5c1, Hi: 0x5c2, Stride: 1},\n\t\t{Lo: 0x5c4, Hi: 0x5c4, Stride: 1},\n\t\t{Lo: 0x5d0, Hi: 0x5ea, Stride: 1},\n\t\t{Lo: 0x5f0, Hi: 0x5f2, Stride: 1},\n\t\t{Lo: 0x621, Hi: 0x63a, Stride: 1},\n\t\t{Lo: 0x640, Hi: 0x655, Stride: 1},\n\t\t{Lo: 0x660, Hi: 0x669, Stride: 1},\n\t\t{Lo: 0x670, Hi: 0x6d3, Stride: 1},\n\t\t{Lo: 0x6d5, Hi: 0x6dc, Stride: 1},\n\t\t{Lo: 0x6df, Hi: 0x6e8, Stride: 1},\n\t\t{Lo: 0x6ea, Hi: 0x6ed, Stride: 1},\n\t\t{Lo: 0x6f0, Hi: 0x6fc, Stride: 1},\n\t\t{Lo: 0x710, Hi: 0x72c, Stride: 1},\n\t\t{Lo: 0x730, Hi: 0x74a, Stride: 1},\n\t\t{Lo: 0x780, Hi: 0x7b0, Stride: 1},\n\t\t{Lo: 0x901, Hi: 0x903, Stride: 1},\n\t\t{Lo: 0x905, Hi: 0x939, Stride: 1},\n\t\t{Lo: 0x93c, Hi: 0x94d, Stride: 1},\n\t\t{Lo: 0x950, Hi: 0x954, Stride: 1},\n\t\t{Lo: 0x958, Hi: 0x963, Stride: 1},\n\t\t{Lo: 0x966, Hi: 0x96f, Stride: 1},\n\t\t{Lo: 0x981, Hi: 0x983, Stride: 1},\n\t\t{Lo: 0x985, Hi: 0x98c, Stride: 1},\n\t\t{Lo: 0x98f, Hi: 0x990, Stride: 1},\n\t\t{Lo: 0x993, Hi: 0x9a8, Stride: 1},\n\t\t{Lo: 0x9aa, Hi: 0x9b0, Stride: 1},\n\t\t{Lo: 0x9b2, Hi: 0x9b2, Stride: 1},\n\t\t{Lo: 0x9b6, Hi: 0x9b9, Stride: 1},\n\t\t{Lo: 0x9bc, Hi: 0x9bc, Stride: 1},\n\t\t{Lo: 0x9be, Hi: 0x9c4, Stride: 1},\n\t\t{Lo: 0x9c7, Hi: 0x9c8, Stride: 1},\n\t\t{Lo: 0x9cb, Hi: 0x9cd, Stride: 1},\n\t\t{Lo: 0x9d7, Hi: 0x9d7, Stride: 1},\n\t\t{Lo: 0x9dc, Hi: 0x9dd, Stride: 1},\n\t\t{Lo: 0x9df, Hi: 0x9e3, Stride: 1},\n\t\t{Lo: 0x9e6, Hi: 0x9f1, Stride: 1},\n\t\t{Lo: 0xa02, Hi: 0xa02, Stride: 1},\n\t\t{Lo: 0xa05, Hi: 0xa0a, Stride: 1},\n\t\t{Lo: 0xa0f, Hi: 0xa10, Stride: 1},\n\t\t{Lo: 0xa13, Hi: 0xa28, Stride: 1},\n\t\t{Lo: 0xa2a, Hi: 0xa30, Stride: 1},\n\t\t{Lo: 0xa32, Hi: 0xa33, Stride: 1},\n\t\t{Lo: 0xa35, Hi: 0xa36, Stride: 1},\n\t\t{Lo: 0xa38, Hi: 0xa39, Stride: 1},\n\t\t{Lo: 0xa3c, Hi: 0xa3c, Stride: 1},\n\t\t{Lo: 0xa3e, Hi: 0xa42, Stride: 1},\n\t\t{Lo: 0xa47, Hi: 0xa48, Stride: 1},\n\t\t{Lo: 0xa4b, Hi: 0xa4d, Stride: 1},\n\t\t{Lo: 0xa59, Hi: 0xa5c, Stride: 1},\n\t\t{Lo: 0xa5e, Hi: 0xa5e, Stride: 1},\n\t\t{Lo: 0xa66, Hi: 0xa74, Stride: 1},\n\t\t{Lo: 0xa81, Hi: 0xa83, Stride: 1},\n\t\t{Lo: 0xa85, Hi: 0xa8b, Stride: 1},\n\t\t{Lo: 0xa8d, Hi: 0xa8d, Stride: 1},\n\t\t{Lo: 0xa8f, Hi: 0xa91, Stride: 1},\n\t\t{Lo: 0xa93, Hi: 0xaa8, Stride: 1},\n\t\t{Lo: 0xaaa, Hi: 0xab0, Stride: 1},\n\t\t{Lo: 0xab2, Hi: 0xab3, Stride: 1},\n\t\t{Lo: 0xab5, Hi: 0xab9, Stride: 1},\n\t\t{Lo: 0xabc, Hi: 0xac5, Stride: 1},\n\t\t{Lo: 0xac7, Hi: 0xac9, Stride: 1},\n\t\t{Lo: 0xacb, Hi: 0xacd, Stride: 1},\n\t\t{Lo: 0xad0, Hi: 0xad0, Stride: 1},\n\t\t{Lo: 0xae0, Hi: 0xae0, Stride: 1},\n\t\t{Lo: 0xae6, Hi: 0xaef, Stride: 1},\n\t\t{Lo: 0xb01, Hi: 0xb03, Stride: 1},\n\t\t{Lo: 0xb05, Hi: 0xb0c, Stride: 1},\n\t\t{Lo: 0xb0f, Hi: 0xb10, Stride: 1},\n\t\t{Lo: 0xb13, Hi: 0xb28, Stride: 1},\n\t\t{Lo: 0xb2a, Hi: 0xb30, Stride: 1},\n\t\t{Lo: 0xb32, Hi: 0xb33, Stride: 1},\n\t\t{Lo: 0xb36, Hi: 0xb39, Stride: 1},\n\t\t{Lo: 0xb3c, Hi: 0xb43, Stride: 1},\n\t\t{Lo: 0xb47, Hi: 0xb48, Stride: 1},\n\t\t{Lo: 0xb4b, Hi: 0xb4d, Stride: 1},\n\t\t{Lo: 0xb56, Hi: 0xb57, Stride: 1},\n\t\t{Lo: 0xb5c, Hi: 0xb5d, Stride: 1},\n\t\t{Lo: 0xb5f, Hi: 0xb61, Stride: 1},\n\t\t{Lo: 0xb66, Hi: 0xb6f, Stride: 1},\n\t\t{Lo: 0xb82, Hi: 0xb83, Stride: 1},\n\t\t{Lo: 0xb85, Hi: 0xb8a, Stride: 1},\n\t\t{Lo: 0xb8e, Hi: 0xb90, Stride: 1},\n\t\t{Lo: 0xb92, Hi: 0xb95, Stride: 1},\n\t\t{Lo: 0xb99, Hi: 0xb9a, Stride: 1},\n\t\t{Lo: 0xb9c, Hi: 0xb9c, Stride: 1},\n\t\t{Lo: 0xb9e, Hi: 0xb9f, Stride: 1},\n\t\t{Lo: 0xba3, Hi: 0xba4, Stride: 1},\n\t\t{Lo: 0xba8, Hi: 0xbaa, Stride: 1},\n\t\t{Lo: 0xbae, Hi: 0xbb5, Stride: 1},\n\t\t{Lo: 0xbb7, Hi: 0xbb9, Stride: 1},\n\t\t{Lo: 0xbbe, Hi: 0xbc2, Stride: 1},\n\t\t{Lo: 0xbc6, Hi: 0xbc8, Stride: 1},\n\t\t{Lo: 0xbca, Hi: 0xbcd, Stride: 1},\n\t\t{Lo: 0xbd7, Hi: 0xbd7, Stride: 1},\n\t\t{Lo: 0xbe7, Hi: 0xbef, Stride: 1},\n\t\t{Lo: 0xc01, Hi: 0xc03, Stride: 1},\n\t\t{Lo: 0xc05, Hi: 0xc0c, Stride: 1},\n\t\t{Lo: 0xc0e, Hi: 0xc10, Stride: 1},\n\t\t{Lo: 0xc12, Hi: 0xc28, Stride: 1},\n\t\t{Lo: 0xc2a, Hi: 0xc33, Stride: 1},\n\t\t{Lo: 0xc35, Hi: 0xc39, Stride: 1},\n\t\t{Lo: 0xc3e, Hi: 0xc44, Stride: 1},\n\t\t{Lo: 0xc46, Hi: 0xc48, Stride: 1},\n\t\t{Lo: 0xc4a, Hi: 0xc4d, Stride: 1},\n\t\t{Lo: 0xc55, Hi: 0xc56, Stride: 1},\n\t\t{Lo: 0xc60, Hi: 0xc61, Stride: 1},\n\t\t{Lo: 0xc66, Hi: 0xc6f, Stride: 1},\n\t\t{Lo: 0xc82, Hi: 0xc83, Stride: 1},\n\t\t{Lo: 0xc85, Hi: 0xc8c, Stride: 1},\n\t\t{Lo: 0xc8e, Hi: 0xc90, Stride: 1},\n\t\t{Lo: 0xc92, Hi: 0xca8, Stride: 1},\n\t\t{Lo: 0xcaa, Hi: 0xcb3, Stride: 1},\n\t\t{Lo: 0xcb5, Hi: 0xcb9, Stride: 1},\n\t\t{Lo: 0xcbe, Hi: 0xcc4, Stride: 1},\n\t\t{Lo: 0xcc6, Hi: 0xcc8, Stride: 1},\n\t\t{Lo: 0xcca, Hi: 0xccd, Stride: 1},\n\t\t{Lo: 0xcd5, Hi: 0xcd6, Stride: 1},\n\t\t{Lo: 0xcde, Hi: 0xcde, Stride: 1},\n\t\t{Lo: 0xce0, Hi: 0xce1, Stride: 1},\n\t\t{Lo: 0xce6, Hi: 0xcef, Stride: 1},\n\t\t{Lo: 0xd02, Hi: 0xd03, Stride: 1},\n\t\t{Lo: 0xd05, Hi: 0xd0c, Stride: 1},\n\t\t{Lo: 0xd0e, Hi: 0xd10, Stride: 1},\n\t\t{Lo: 0xd12, Hi: 0xd28, Stride: 1},\n\t\t{Lo: 0xd2a, Hi: 0xd39, Stride: 1},\n\t\t{Lo: 0xd3e, Hi: 0xd43, Stride: 1},\n\t\t{Lo: 0xd46, Hi: 0xd48, Stride: 1},\n\t\t{Lo: 0xd4a, Hi: 0xd4d, Stride: 1},\n\t\t{Lo: 0xd57, Hi: 0xd57, Stride: 1},\n\t\t{Lo: 0xd60, Hi: 0xd61, Stride: 1},\n\t\t{Lo: 0xd66, Hi: 0xd6f, Stride: 1},\n\t\t{Lo: 0xd82, Hi: 0xd83, Stride: 1},\n\t\t{Lo: 0xd85, Hi: 0xd96, Stride: 1},\n\t\t{Lo: 0xd9a, Hi: 0xdb1, Stride: 1},\n\t\t{Lo: 0xdb3, Hi: 0xdbb, Stride: 1},\n\t\t{Lo: 0xdbd, Hi: 0xdbd, Stride: 1},\n\t\t{Lo: 0xdc0, Hi: 0xdc6, Stride: 1},\n\t\t{Lo: 0xdca, Hi: 0xdca, Stride: 1},\n\t\t{Lo: 0xdcf, Hi: 0xdd4, Stride: 1},\n\t\t{Lo: 0xdd6, Hi: 0xdd6, Stride: 1},\n\t\t{Lo: 0xdd8, Hi: 0xddf, Stride: 1},\n\t\t{Lo: 0xdf2, Hi: 0xdf3, Stride: 1},\n\t\t{Lo: 0xe01, Hi: 0xe3a, Stride: 1},\n\t\t{Lo: 0xe40, Hi: 0xe4e, Stride: 1},\n\t\t{Lo: 0xe50, Hi: 0xe59, Stride: 1},\n\t\t{Lo: 0xe81, Hi: 0xe82, Stride: 1},\n\t\t{Lo: 0xe84, Hi: 0xe84, Stride: 1},\n\t\t{Lo: 0xe87, Hi: 0xe88, Stride: 1},\n\t\t{Lo: 0xe8a, Hi: 0xe8a, Stride: 1},\n\t\t{Lo: 0xe8d, Hi: 0xe8d, Stride: 1},\n\t\t{Lo: 0xe94, Hi: 0xe97, Stride: 1},\n\t\t{Lo: 0xe99, Hi: 0xe9f, Stride: 1},\n\t\t{Lo: 0xea1, Hi: 0xea3, Stride: 1},\n\t\t{Lo: 0xea5, Hi: 0xea5, Stride: 1},\n\t\t{Lo: 0xea7, Hi: 0xea7, Stride: 1},\n\t\t{Lo: 0xeaa, Hi: 0xeab, Stride: 1},\n\t\t{Lo: 0xead, Hi: 0xeb9, Stride: 1},\n\t\t{Lo: 0xebb, Hi: 0xebd, Stride: 1},\n\t\t{Lo: 0xec0, Hi: 0xec4, Stride: 1},\n\t\t{Lo: 0xec6, Hi: 0xec6, Stride: 1},\n\t\t{Lo: 0xec8, Hi: 0xecd, Stride: 1},\n\t\t{Lo: 0xed0, Hi: 0xed9, Stride: 1},\n\t\t{Lo: 0xedc, Hi: 0xedd, Stride: 1},\n\t\t{Lo: 0xf00, Hi: 0xf00, Stride: 1},\n\t\t{Lo: 0xf18, Hi: 0xf19, Stride: 1},\n\t\t{Lo: 0xf20, Hi: 0xf29, Stride: 1},\n\t\t{Lo: 0xf35, Hi: 0xf35, Stride: 1},\n\t\t{Lo: 0xf37, Hi: 0xf37, Stride: 1},\n\t\t{Lo: 0xf39, Hi: 0xf39, Stride: 1},\n\t\t{Lo: 0xf3e, Hi: 0xf47, Stride: 1},\n\t\t{Lo: 0xf49, Hi: 0xf6a, Stride: 1},\n\t\t{Lo: 0xf71, Hi: 0xf84, Stride: 1},\n\t\t{Lo: 0xf86, Hi: 0xf8b, Stride: 1},\n\t\t{Lo: 0xf90, Hi: 0xf97, Stride: 1},\n\t\t{Lo: 0xf99, Hi: 0xfbc, Stride: 1},\n\t\t{Lo: 0xfc6, Hi: 0xfc6, Stride: 1},\n\t},\n\tR32: []unicode.Range32{\n\t\t{Lo: 0x1000, Hi: 0x1021, Stride: 1},\n\t\t{Lo: 0x1023, Hi: 0x1027, Stride: 1},\n\t\t{Lo: 0x1029, Hi: 0x102a, Stride: 1},\n\t\t{Lo: 0x102c, Hi: 0x1032, Stride: 1},\n\t\t{Lo: 0x1036, Hi: 0x1039, Stride: 1},\n\t\t{Lo: 0x1040, Hi: 0x1049, Stride: 1},\n\t\t{Lo: 0x1050, Hi: 0x1059, Stride: 1},\n\t\t{Lo: 0x10a0, Hi: 0x10c5, Stride: 1},\n\t\t{Lo: 0x10d0, Hi: 0x10f6, Stride: 1},\n\t\t{Lo: 0x1100, Hi: 0x1159, Stride: 1},\n\t\t{Lo: 0x115f, Hi: 0x11a2, Stride: 1},\n\t\t{Lo: 0x11a8, Hi: 0x11f9, Stride: 1},\n\t\t{Lo: 0x1200, Hi: 0x1206, Stride: 1},\n\t\t{Lo: 0x1208, Hi: 0x1246, Stride: 1},\n\t\t{Lo: 0x1248, Hi: 0x1248, Stride: 1},\n\t\t{Lo: 0x124a, Hi: 0x124d, Stride: 1},\n\t\t{Lo: 0x1250, Hi: 0x1256, Stride: 1},\n\t\t{Lo: 0x1258, Hi: 0x1258, Stride: 1},\n\t\t{Lo: 0x125a, Hi: 0x125d, Stride: 1},\n\t\t{Lo: 0x1260, Hi: 0x1286, Stride: 1},\n\t\t{Lo: 0x1288, Hi: 0x1288, Stride: 1},\n\t\t{Lo: 0x128a, Hi: 0x128d, Stride: 1},\n\t\t{Lo: 0x1290, Hi: 0x12ae, Stride: 1},\n\t\t{Lo: 0x12b0, Hi: 0x12b0, Stride: 1},\n\t\t{Lo: 0x12b2, Hi: 0x12b5, Stride: 1},\n\t\t{Lo: 0x12b8, Hi: 0x12be, Stride: 1},\n\t\t{Lo: 0x12c0, Hi: 0x12c0, Stride: 1},\n\t\t{Lo: 0x12c2, Hi: 0x12c5, Stride: 1},\n\t\t{Lo: 0x12c8, Hi: 0x12ce, Stride: 1},\n\t\t{Lo: 0x12d0, Hi: 0x12d6, Stride: 1},\n\t\t{Lo: 0x12d8, Hi: 0x12ee, Stride: 1},\n\t\t{Lo: 0x12f0, Hi: 0x130e, Stride: 1},\n\t\t{Lo: 0x1310, Hi: 0x1310, Stride: 1},\n\t\t{Lo: 0x1312, Hi: 0x1315, Stride: 1},\n\t\t{Lo: 0x1318, Hi: 0x131e, Stride: 1},\n\t\t{Lo: 0x1320, Hi: 0x1346, Stride: 1},\n\t\t{Lo: 0x1348, Hi: 0x135a, Stride: 1},\n\t\t{Lo: 0x1369, Hi: 0x1371, Stride: 1},\n\t\t{Lo: 0x13a0, Hi: 0x13f4, Stride: 1},\n\t\t{Lo: 0x1401, Hi: 0x166c, Stride: 1},\n\t\t{Lo: 0x166f, Hi: 0x1676, Stride: 1},\n\t\t{Lo: 0x1681, Hi: 0x169a, Stride: 1},\n\t\t{Lo: 0x16a0, Hi: 0x16ea, Stride: 1},\n\t\t{Lo: 0x1780, Hi: 0x17d3, Stride: 1},\n\t\t{Lo: 0x17e0, Hi: 0x17e9, Stride: 1},\n\t\t{Lo: 0x1810, Hi: 0x1819, Stride: 1},\n\t\t{Lo: 0x1820, Hi: 0x1877, Stride: 1},\n\t\t{Lo: 0x1880, Hi: 0x18a9, Stride: 1},\n\t\t{Lo: 0x1e00, Hi: 0x1e9b, Stride: 1},\n\t\t{Lo: 0x1ea0, Hi: 0x1ef9, Stride: 1},\n\t\t{Lo: 0x1f00, Hi: 0x1f15, Stride: 1},\n\t\t{Lo: 0x1f18, Hi: 0x1f1d, Stride: 1},\n\t\t{Lo: 0x1f20, Hi: 0x1f45, Stride: 1},\n\t\t{Lo: 0x1f48, Hi: 0x1f4d, Stride: 1},\n\t\t{Lo: 0x1f50, Hi: 0x1f57, Stride: 1},\n\t\t{Lo: 0x1f59, Hi: 0x1f59, Stride: 1},\n\t\t{Lo: 0x1f5b, Hi: 0x1f5b, Stride: 1},\n\t\t{Lo: 0x1f5d, Hi: 0x1f5d, Stride: 1},\n\t\t{Lo: 0x1f5f, Hi: 0x1f7d, Stride: 1},\n\t\t{Lo: 0x1f80, Hi: 0x1fb4, Stride: 1},\n\t\t{Lo: 0x1fb6, Hi: 0x1fbc, Stride: 1},\n\t\t{Lo: 0x1fbe, Hi: 0x1fbe, Stride: 1},\n\t\t{Lo: 0x1fc2, Hi: 0x1fc4, Stride: 1},\n\t\t{Lo: 0x1fc6, Hi: 0x1fcc, Stride: 1},\n\t\t{Lo: 0x1fd0, Hi: 0x1fd3, Stride: 1},\n\t\t{Lo: 0x1fd6, Hi: 0x1fdb, Stride: 1},\n\t\t{Lo: 0x1fe0, Hi: 0x1fec, Stride: 1},\n\t\t{Lo: 0x1ff2, Hi: 0x1ff4, Stride: 1},\n\t\t{Lo: 0x1ff6, Hi: 0x1ffc, Stride: 1},\n\t\t{Lo: 0x203f, Hi: 0x2040, Stride: 1},\n\t\t{Lo: 0x207f, Hi: 0x207f, Stride: 1},\n\t\t{Lo: 0x20d0, Hi: 0x20dc, Stride: 1},\n\t\t{Lo: 0x20e1, Hi: 0x20e1, Stride: 1},\n\t\t{Lo: 0x2102, Hi: 0x2102, Stride: 1},\n\t\t{Lo: 0x2107, Hi: 0x2107, Stride: 1},\n\t\t{Lo: 0x210a, Hi: 0x2113, Stride: 1},\n\t\t{Lo: 0x2115, Hi: 0x2115, Stride: 1},\n\t\t{Lo: 0x2119, Hi: 0x211d, Stride: 1},\n\t\t{Lo: 0x2124, Hi: 0x2124, Stride: 1},\n\t\t{Lo: 0x2126, Hi: 0x2126, Stride: 1},\n\t\t{Lo: 0x2128, Hi: 0x2128, Stride: 1},\n\t\t{Lo: 0x212a, Hi: 0x212d, Stride: 1},\n\t\t{Lo: 0x212f, Hi: 0x2131, Stride: 1},\n\t\t{Lo: 0x2133, Hi: 0x2139, Stride: 1},\n\t\t{Lo: 0x3005, Hi: 0x3006, Stride: 1},\n\t\t{Lo: 0x302a, Hi: 0x302f, Stride: 1},\n\t\t{Lo: 0x3031, Hi: 0x3035, Stride: 1},\n\t\t{Lo: 0x3041, Hi: 0x3094, Stride: 1},\n\t\t{Lo: 0x3099, Hi: 0x309a, Stride: 1},\n\t\t{Lo: 0x309d, Hi: 0x309e, Stride: 1},\n\t\t{Lo: 0x30a1, Hi: 0x30fa, Stride: 1},\n\t\t{Lo: 0x30fc, Hi: 0x30fe, Stride: 1},\n\t\t{Lo: 0x3105, Hi: 0x312c, Stride: 1},\n\t\t{Lo: 0x3131, Hi: 0x318e, Stride: 1},\n\t\t{Lo: 0x31a0, Hi: 0x31b7, Stride: 1},\n\t\t{Lo: 0x3400, Hi: 0x4db5, Stride: 1},\n\t\t{Lo: 0x4e00, Hi: 0x9fa5, Stride: 1},\n\t\t{Lo: 0xa000, Hi: 0xa48c, Stride: 1},\n\t\t{Lo: 0xac00, Hi: 0xd7a3, Stride: 1},\n\t\t{Lo: 0xf900, Hi: 0xfa2d, Stride: 1},\n\t\t{Lo: 0xfb00, Hi: 0xfb06, Stride: 1},\n\t\t{Lo: 0xfb13, Hi: 0xfb17, Stride: 1},\n\t\t{Lo: 0xfb1d, Hi: 0xfb28, Stride: 1},\n\t\t{Lo: 0xfb2a, Hi: 0xfb36, Stride: 1},\n\t\t{Lo: 0xfb38, Hi: 0xfb3c, Stride: 1},\n\t\t{Lo: 0xfb3e, Hi: 0xfb3e, Stride: 1},\n\t\t{Lo: 0xfb40, Hi: 0xfb41, Stride: 1},\n\t\t{Lo: 0xfb43, Hi: 0xfb44, Stride: 1},\n\t\t{Lo: 0xfb46, Hi: 0xfbb1, Stride: 1},\n\t\t{Lo: 0xfbd3, Hi: 0xfd3d, Stride: 1},\n\t\t{Lo: 0xfd50, Hi: 0xfd8f, Stride: 1},\n\t\t{Lo: 0xfd92, Hi: 0xfdc7, Stride: 1},\n\t\t{Lo: 0xfdf0, Hi: 0xfdfb, Stride: 1},\n\t\t{Lo: 0xfe20, Hi: 0xfe23, Stride: 1},\n\t\t{Lo: 0xfe33, Hi: 0xfe34, Stride: 1},\n\t\t{Lo: 0xfe4d, Hi: 0xfe4f, Stride: 1},\n\t\t{Lo: 0xfe70, Hi: 0xfe72, Stride: 1},\n\t\t{Lo: 0xfe74, Hi: 0xfe74, Stride: 1},\n\t\t{Lo: 0xfe76, Hi: 0xfefc, Stride: 1},\n\t\t{Lo: 0xff10, Hi: 0xff19, Stride: 1},\n\t\t{Lo: 0xff21, Hi: 0xff3a, Stride: 1},\n\t\t{Lo: 0xff3f, Hi: 0xff3f, Stride: 1},\n\t\t{Lo: 0xff41, Hi: 0xff5a, Stride: 1},\n\t\t{Lo: 0xff66, Hi: 0xffbe, Stride: 1},\n\t\t{Lo: 0xffc2, Hi: 0xffc7, Stride: 1},\n\t\t{Lo: 0xffca, Hi: 0xffcf, Stride: 1},\n\t\t{Lo: 0xffd2, Hi: 0xffd7, Stride: 1},\n\t\t{Lo: 0xffda, Hi: 0xffdc, Stride: 1},\n\t},\n}\n\nvar idStartES5OrESNext = &unicode.RangeTable{\n\tLatinOffset: 117,\n\tR16: []unicode.Range16{\n\t\t{Lo: 0x41, Hi: 0x5a, Stride: 1},\n\t\t{Lo: 0x61, Hi: 0x7a, Stride: 1},\n\t\t{Lo: 0xaa, Hi: 0xaa, Stride: 1},\n\t\t{Lo: 0xb5, Hi: 0xb5, Stride: 1},\n\t\t{Lo: 0xba, Hi: 0xba, Stride: 1},\n\t\t{Lo: 0xc0, Hi: 0xd6, Stride: 1},\n\t\t{Lo: 0xd8, Hi: 0xf6, Stride: 1},\n\t\t{Lo: 0xf8, Hi: 0x2c1, Stride: 1},\n\t\t{Lo: 0x2c6, Hi: 0x2d1, Stride: 1},\n\t\t{Lo: 0x2e0, Hi: 0x2e4, Stride: 1},\n\t\t{Lo: 0x2ec, Hi: 0x2ec, Stride: 1},\n\t\t{Lo: 0x2ee, Hi: 0x2ee, Stride: 1},\n\t\t{Lo: 0x370, Hi: 0x374, Stride: 1},\n\t\t{Lo: 0x376, Hi: 0x377, Stride: 1},\n\t\t{Lo: 0x37a, Hi: 0x37d, Stride: 1},\n\t\t{Lo: 0x37f, Hi: 0x37f, Stride: 1},\n\t\t{Lo: 0x386, Hi: 0x386, Stride: 1},\n\t\t{Lo: 0x388, Hi: 0x38a, Stride: 1},\n\t\t{Lo: 0x38c, Hi: 0x38c, Stride: 1},\n\t\t{Lo: 0x38e, Hi: 0x3a1, Stride: 1},\n\t\t{Lo: 0x3a3, Hi: 0x3f5, Stride: 1},\n\t\t{Lo: 0x3f7, Hi: 0x481, Stride: 1},\n\t\t{Lo: 0x48a, Hi: 0x52f, Stride: 1},\n\t\t{Lo: 0x531, Hi: 0x556, Stride: 1},\n\t\t{Lo: 0x559, Hi: 0x559, Stride: 1},\n\t\t{Lo: 0x560, Hi: 0x588, Stride: 1},\n\t\t{Lo: 0x5d0, Hi: 0x5ea, Stride: 1},\n\t\t{Lo: 0x5ef, Hi: 0x5f2, Stride: 1},\n\t\t{Lo: 0x620, Hi: 0x64a, Stride: 1},\n\t\t{Lo: 0x66e, Hi: 0x66f, Stride: 1},\n\t\t{Lo: 0x671, Hi: 0x6d3, Stride: 1},\n\t\t{Lo: 0x6d5, Hi: 0x6d5, Stride: 1},\n\t\t{Lo: 0x6e5, Hi: 0x6e6, Stride: 1},\n\t\t{Lo: 0x6ee, Hi: 0x6ef, Stride: 1},\n\t\t{Lo: 0x6fa, Hi: 0x6fc, Stride: 1},\n\t\t{Lo: 0x6ff, Hi: 0x6ff, Stride: 1},\n\t\t{Lo: 0x710, Hi: 0x710, Stride: 1},\n\t\t{Lo: 0x712, Hi: 0x72f, Stride: 1},\n\t\t{Lo: 0x74d, Hi: 0x7a5, Stride: 1},\n\t\t{Lo: 0x7b1, Hi: 0x7b1, Stride: 1},\n\t\t{Lo: 0x7ca, Hi: 0x7ea, Stride: 1},\n\t\t{Lo: 0x7f4, Hi: 0x7f5, Stride: 1},\n\t\t{Lo: 0x7fa, Hi: 0x7fa, Stride: 1},\n\t\t{Lo: 0x800, Hi: 0x815, Stride: 1},\n\t\t{Lo: 0x81a, Hi: 0x81a, Stride: 1},\n\t\t{Lo: 0x824, Hi: 0x824, Stride: 1},\n\t\t{Lo: 0x828, Hi: 0x828, Stride: 1},\n\t\t{Lo: 0x840, Hi: 0x858, Stride: 1},\n\t\t{Lo: 0x860, Hi: 0x86a, Stride: 1},\n\t\t{Lo: 0x870, Hi: 0x887, Stride: 1},\n\t\t{Lo: 0x889, Hi: 0x88e, Stride: 1},\n\t\t{Lo: 0x8a0, Hi: 0x8c9, Stride: 1},\n\t\t{Lo: 0x904, Hi: 0x939, Stride: 1},\n\t\t{Lo: 0x93d, Hi: 0x93d, Stride: 1},\n\t\t{Lo: 0x950, Hi: 0x950, Stride: 1},\n\t\t{Lo: 0x958, Hi: 0x961, Stride: 1},\n\t\t{Lo: 0x971, Hi: 0x980, Stride: 1},\n\t\t{Lo: 0x985, Hi: 0x98c, Stride: 1},\n\t\t{Lo: 0x98f, Hi: 0x990, Stride: 1},\n\t\t{Lo: 0x993, Hi: 0x9a8, Stride: 1},\n\t\t{Lo: 0x9aa, Hi: 0x9b0, Stride: 1},\n\t\t{Lo: 0x9b2, Hi: 0x9b2, Stride: 1},\n\t\t{Lo: 0x9b6, Hi: 0x9b9, Stride: 1},\n\t\t{Lo: 0x9bd, Hi: 0x9bd, Stride: 1},\n\t\t{Lo: 0x9ce, Hi: 0x9ce, Stride: 1},\n\t\t{Lo: 0x9dc, Hi: 0x9dd, Stride: 1},\n\t\t{Lo: 0x9df, Hi: 0x9e1, Stride: 1},\n\t\t{Lo: 0x9f0, Hi: 0x9f1, Stride: 1},\n\t\t{Lo: 0x9fc, Hi: 0x9fc, Stride: 1},\n\t\t{Lo: 0xa05, Hi: 0xa0a, Stride: 1},\n\t\t{Lo: 0xa0f, Hi: 0xa10, Stride: 1},\n\t\t{Lo: 0xa13, Hi: 0xa28, Stride: 1},\n\t\t{Lo: 0xa2a, Hi: 0xa30, Stride: 1},\n\t\t{Lo: 0xa32, Hi: 0xa33, Stride: 1},\n\t\t{Lo: 0xa35, Hi: 0xa36, Stride: 1},\n\t\t{Lo: 0xa38, Hi: 0xa39, Stride: 1},\n\t\t{Lo: 0xa59, Hi: 0xa5c, Stride: 1},\n\t\t{Lo: 0xa5e, Hi: 0xa5e, Stride: 1},\n\t\t{Lo: 0xa72, Hi: 0xa74, Stride: 1},\n\t\t{Lo: 0xa85, Hi: 0xa8d, Stride: 1},\n\t\t{Lo: 0xa8f, Hi: 0xa91, Stride: 1},\n\t\t{Lo: 0xa93, Hi: 0xaa8, Stride: 1},\n\t\t{Lo: 0xaaa, Hi: 0xab0, Stride: 1},\n\t\t{Lo: 0xab2, Hi: 0xab3, Stride: 1},\n\t\t{Lo: 0xab5, Hi: 0xab9, Stride: 1},\n\t\t{Lo: 0xabd, Hi: 0xabd, Stride: 1},\n\t\t{Lo: 0xad0, Hi: 0xad0, Stride: 1},\n\t\t{Lo: 0xae0, Hi: 0xae1, Stride: 1},\n\t\t{Lo: 0xaf9, Hi: 0xaf9, Stride: 1},\n\t\t{Lo: 0xb05, Hi: 0xb0c, Stride: 1},\n\t\t{Lo: 0xb0f, Hi: 0xb10, Stride: 1},\n\t\t{Lo: 0xb13, Hi: 0xb28, Stride: 1},\n\t\t{Lo: 0xb2a, Hi: 0xb30, Stride: 1},\n\t\t{Lo: 0xb32, Hi: 0xb33, Stride: 1},\n\t\t{Lo: 0xb35, Hi: 0xb39, Stride: 1},\n\t\t{Lo: 0xb3d, Hi: 0xb3d, Stride: 1},\n\t\t{Lo: 0xb5c, Hi: 0xb5d, Stride: 1},\n\t\t{Lo: 0xb5f, Hi: 0xb61, Stride: 1},\n\t\t{Lo: 0xb71, Hi: 0xb71, Stride: 1},\n\t\t{Lo: 0xb83, Hi: 0xb83, Stride: 1},\n\t\t{Lo: 0xb85, Hi: 0xb8a, Stride: 1},\n\t\t{Lo: 0xb8e, Hi: 0xb90, Stride: 1},\n\t\t{Lo: 0xb92, Hi: 0xb95, Stride: 1},\n\t\t{Lo: 0xb99, Hi: 0xb9a, Stride: 1},\n\t\t{Lo: 0xb9c, Hi: 0xb9c, Stride: 1},\n\t\t{Lo: 0xb9e, Hi: 0xb9f, Stride: 1},\n\t\t{Lo: 0xba3, Hi: 0xba4, Stride: 1},\n\t\t{Lo: 0xba8, Hi: 0xbaa, Stride: 1},\n\t\t{Lo: 0xbae, Hi: 0xbb9, Stride: 1},\n\t\t{Lo: 0xbd0, Hi: 0xbd0, Stride: 1},\n\t\t{Lo: 0xc05, Hi: 0xc0c, Stride: 1},\n\t\t{Lo: 0xc0e, Hi: 0xc10, Stride: 1},\n\t\t{Lo: 0xc12, Hi: 0xc28, Stride: 1},\n\t\t{Lo: 0xc2a, Hi: 0xc39, Stride: 1},\n\t\t{Lo: 0xc3d, Hi: 0xc3d, Stride: 1},\n\t\t{Lo: 0xc58, Hi: 0xc5a, Stride: 1},\n\t\t{Lo: 0xc5d, Hi: 0xc5d, Stride: 1},\n\t\t{Lo: 0xc60, Hi: 0xc61, Stride: 1},\n\t\t{Lo: 0xc80, Hi: 0xc80, Stride: 1},\n\t\t{Lo: 0xc85, Hi: 0xc8c, Stride: 1},\n\t\t{Lo: 0xc8e, Hi: 0xc90, Stride: 1},\n\t\t{Lo: 0xc92, Hi: 0xca8, Stride: 1},\n\t\t{Lo: 0xcaa, Hi: 0xcb3, Stride: 1},\n\t\t{Lo: 0xcb5, Hi: 0xcb9, Stride: 1},\n\t\t{Lo: 0xcbd, Hi: 0xcbd, Stride: 1},\n\t\t{Lo: 0xcdd, Hi: 0xcde, Stride: 1},\n\t\t{Lo: 0xce0, Hi: 0xce1, Stride: 1},\n\t\t{Lo: 0xcf1, Hi: 0xcf2, Stride: 1},\n\t\t{Lo: 0xd04, Hi: 0xd0c, Stride: 1},\n\t\t{Lo: 0xd0e, Hi: 0xd10, Stride: 1},\n\t\t{Lo: 0xd12, Hi: 0xd3a, Stride: 1},\n\t\t{Lo: 0xd3d, Hi: 0xd3d, Stride: 1},\n\t\t{Lo: 0xd4e, Hi: 0xd4e, Stride: 1},\n\t\t{Lo: 0xd54, Hi: 0xd56, Stride: 1},\n\t\t{Lo: 0xd5f, Hi: 0xd61, Stride: 1},\n\t\t{Lo: 0xd7a, Hi: 0xd7f, Stride: 1},\n\t\t{Lo: 0xd85, Hi: 0xd96, Stride: 1},\n\t\t{Lo: 0xd9a, Hi: 0xdb1, Stride: 1},\n\t\t{Lo: 0xdb3, Hi: 0xdbb, Stride: 1},\n\t\t{Lo: 0xdbd, Hi: 0xdbd, Stride: 1},\n\t\t{Lo: 0xdc0, Hi: 0xdc6, Stride: 1},\n\t\t{Lo: 0xe01, Hi: 0xe30, Stride: 1},\n\t\t{Lo: 0xe32, Hi: 0xe33, Stride: 1},\n\t\t{Lo: 0xe40, Hi: 0xe46, Stride: 1},\n\t\t{Lo: 0xe81, Hi: 0xe82, Stride: 1},\n\t\t{Lo: 0xe84, Hi: 0xe84, Stride: 1},\n\t\t{Lo: 0xe86, Hi: 0xe8a, Stride: 1},\n\t\t{Lo: 0xe8c, Hi: 0xea3, Stride: 1},\n\t\t{Lo: 0xea5, Hi: 0xea5, Stride: 1},\n\t\t{Lo: 0xea7, Hi: 0xeb0, Stride: 1},\n\t\t{Lo: 0xeb2, Hi: 0xeb3, Stride: 1},\n\t\t{Lo: 0xebd, Hi: 0xebd, Stride: 1},\n\t\t{Lo: 0xec0, Hi: 0xec4, Stride: 1},\n\t\t{Lo: 0xec6, Hi: 0xec6, Stride: 1},\n\t\t{Lo: 0xedc, Hi: 0xedf, Stride: 1},\n\t\t{Lo: 0xf00, Hi: 0xf00, Stride: 1},\n\t\t{Lo: 0xf40, Hi: 0xf47, Stride: 1},\n\t\t{Lo: 0xf49, Hi: 0xf6c, Stride: 1},\n\t\t{Lo: 0xf88, Hi: 0xf8c, Stride: 1},\n\t},\n\tR32: []unicode.Range32{\n\t\t{Lo: 0x1000, Hi: 0x102a, Stride: 1},\n\t\t{Lo: 0x103f, Hi: 0x103f, Stride: 1},\n\t\t{Lo: 0x1050, Hi: 0x1055, Stride: 1},\n\t\t{Lo: 0x105a, Hi: 0x105d, Stride: 1},\n\t\t{Lo: 0x1061, Hi: 0x1061, Stride: 1},\n\t\t{Lo: 0x1065, Hi: 0x1066, Stride: 1},\n\t\t{Lo: 0x106e, Hi: 0x1070, Stride: 1},\n\t\t{Lo: 0x1075, Hi: 0x1081, Stride: 1},\n\t\t{Lo: 0x108e, Hi: 0x108e, Stride: 1},\n\t\t{Lo: 0x10a0, Hi: 0x10c5, Stride: 1},\n\t\t{Lo: 0x10c7, Hi: 0x10c7, Stride: 1},\n\t\t{Lo: 0x10cd, Hi: 0x10cd, Stride: 1},\n\t\t{Lo: 0x10d0, Hi: 0x10fa, Stride: 1},\n\t\t{Lo: 0x10fc, Hi: 0x1248, Stride: 1},\n\t\t{Lo: 0x124a, Hi: 0x124d, Stride: 1},\n\t\t{Lo: 0x1250, Hi: 0x1256, Stride: 1},\n\t\t{Lo: 0x1258, Hi: 0x1258, Stride: 1},\n\t\t{Lo: 0x125a, Hi: 0x125d, Stride: 1},\n\t\t{Lo: 0x1260, Hi: 0x1288, Stride: 1},\n\t\t{Lo: 0x128a, Hi: 0x128d, Stride: 1},\n\t\t{Lo: 0x1290, Hi: 0x12b0, Stride: 1},\n\t\t{Lo: 0x12b2, Hi: 0x12b5, Stride: 1},\n\t\t{Lo: 0x12b8, Hi: 0x12be, Stride: 1},\n\t\t{Lo: 0x12c0, Hi: 0x12c0, Stride: 1},\n\t\t{Lo: 0x12c2, Hi: 0x12c5, Stride: 1},\n\t\t{Lo: 0x12c8, Hi: 0x12d6, Stride: 1},\n\t\t{Lo: 0x12d8, Hi: 0x1310, Stride: 1},\n\t\t{Lo: 0x1312, Hi: 0x1315, Stride: 1},\n\t\t{Lo: 0x1318, Hi: 0x135a, Stride: 1},\n\t\t{Lo: 0x1380, Hi: 0x138f, Stride: 1},\n\t\t{Lo: 0x13a0, Hi: 0x13f5, Stride: 1},\n\t\t{Lo: 0x13f8, Hi: 0x13fd, Stride: 1},\n\t\t{Lo: 0x1401, Hi: 0x166c, Stride: 1},\n\t\t{Lo: 0x166f, Hi: 0x167f, Stride: 1},\n\t\t{Lo: 0x1681, Hi: 0x169a, Stride: 1},\n\t\t{Lo: 0x16a0, Hi: 0x16ea, Stride: 1},\n\t\t{Lo: 0x16ee, Hi: 0x16f8, Stride: 1},\n\t\t{Lo: 0x1700, Hi: 0x1711, Stride: 1},\n\t\t{Lo: 0x171f, Hi: 0x1731, Stride: 1},\n\t\t{Lo: 0x1740, Hi: 0x1751, Stride: 1},\n\t\t{Lo: 0x1760, Hi: 0x176c, Stride: 1},\n\t\t{Lo: 0x176e, Hi: 0x1770, Stride: 1},\n\t\t{Lo: 0x1780, Hi: 0x17b3, Stride: 1},\n\t\t{Lo: 0x17d7, Hi: 0x17d7, Stride: 1},\n\t\t{Lo: 0x17dc, Hi: 0x17dc, Stride: 1},\n\t\t{Lo: 0x1820, Hi: 0x1878, Stride: 1},\n\t\t{Lo: 0x1880, Hi: 0x18a8, Stride: 1},\n\t\t{Lo: 0x18aa, Hi: 0x18aa, Stride: 1},\n\t\t{Lo: 0x18b0, Hi: 0x18f5, Stride: 1},\n\t\t{Lo: 0x1900, Hi: 0x191e, Stride: 1},\n\t\t{Lo: 0x1950, Hi: 0x196d, Stride: 1},\n\t\t{Lo: 0x1970, Hi: 0x1974, Stride: 1},\n\t\t{Lo: 0x1980, Hi: 0x19ab, Stride: 1},\n\t\t{Lo: 0x19b0, Hi: 0x19c9, Stride: 1},\n\t\t{Lo: 0x1a00, Hi: 0x1a16, Stride: 1},\n\t\t{Lo: 0x1a20, Hi: 0x1a54, Stride: 1},\n\t\t{Lo: 0x1aa7, Hi: 0x1aa7, Stride: 1},\n\t\t{Lo: 0x1b05, Hi: 0x1b33, Stride: 1},\n\t\t{Lo: 0x1b45, Hi: 0x1b4c, Stride: 1},\n\t\t{Lo: 0x1b83, Hi: 0x1ba0, Stride: 1},\n\t\t{Lo: 0x1bae, Hi: 0x1baf, Stride: 1},\n\t\t{Lo: 0x1bba, Hi: 0x1be5, Stride: 1},\n\t\t{Lo: 0x1c00, Hi: 0x1c23, Stride: 1},\n\t\t{Lo: 0x1c4d, Hi: 0x1c4f, Stride: 1},\n\t\t{Lo: 0x1c5a, Hi: 0x1c7d, Stride: 1},\n\t\t{Lo: 0x1c80, Hi: 0x1c88, Stride: 1},\n\t\t{Lo: 0x1c90, Hi: 0x1cba, Stride: 1},\n\t\t{Lo: 0x1cbd, Hi: 0x1cbf, Stride: 1},\n\t\t{Lo: 0x1ce9, Hi: 0x1cec, Stride: 1},\n\t\t{Lo: 0x1cee, Hi: 0x1cf3, Stride: 1},\n\t\t{Lo: 0x1cf5, Hi: 0x1cf6, Stride: 1},\n\t\t{Lo: 0x1cfa, Hi: 0x1cfa, Stride: 1},\n\t\t{Lo: 0x1d00, Hi: 0x1dbf, Stride: 1},\n\t\t{Lo: 0x1e00, Hi: 0x1f15, Stride: 1},\n\t\t{Lo: 0x1f18, Hi: 0x1f1d, Stride: 1},\n\t\t{Lo: 0x1f20, Hi: 0x1f45, Stride: 1},\n\t\t{Lo: 0x1f48, Hi: 0x1f4d, Stride: 1},\n\t\t{Lo: 0x1f50, Hi: 0x1f57, Stride: 1},\n\t\t{Lo: 0x1f59, Hi: 0x1f59, Stride: 1},\n\t\t{Lo: 0x1f5b, Hi: 0x1f5b, Stride: 1},\n\t\t{Lo: 0x1f5d, Hi: 0x1f5d, Stride: 1},\n\t\t{Lo: 0x1f5f, Hi: 0x1f7d, Stride: 1},\n\t\t{Lo: 0x1f80, Hi: 0x1fb4, Stride: 1},\n\t\t{Lo: 0x1fb6, Hi: 0x1fbc, Stride: 1},\n\t\t{Lo: 0x1fbe, Hi: 0x1fbe, Stride: 1},\n\t\t{Lo: 0x1fc2, Hi: 0x1fc4, Stride: 1},\n\t\t{Lo: 0x1fc6, Hi: 0x1fcc, Stride: 1},\n\t\t{Lo: 0x1fd0, Hi: 0x1fd3, Stride: 1},\n\t\t{Lo: 0x1fd6, Hi: 0x1fdb, Stride: 1},\n\t\t{Lo: 0x1fe0, Hi: 0x1fec, Stride: 1},\n\t\t{Lo: 0x1ff2, Hi: 0x1ff4, Stride: 1},\n\t\t{Lo: 0x1ff6, Hi: 0x1ffc, Stride: 1},\n\t\t{Lo: 0x2071, Hi: 0x2071, Stride: 1},\n\t\t{Lo: 0x207f, Hi: 0x207f, Stride: 1},\n\t\t{Lo: 0x2090, Hi: 0x209c, Stride: 1},\n\t\t{Lo: 0x2102, Hi: 0x2102, Stride: 1},\n\t\t{Lo: 0x2107, Hi: 0x2107, Stride: 1},\n\t\t{Lo: 0x210a, Hi: 0x2113, Stride: 1},\n\t\t{Lo: 0x2115, Hi: 0x2115, Stride: 1},\n\t\t{Lo: 0x2118, Hi: 0x211d, Stride: 1},\n\t\t{Lo: 0x2124, Hi: 0x2124, Stride: 1},\n\t\t{Lo: 0x2126, Hi: 0x2126, Stride: 1},\n\t\t{Lo: 0x2128, Hi: 0x2128, Stride: 1},\n\t\t{Lo: 0x212a, Hi: 0x2139, Stride: 1},\n\t\t{Lo: 0x213c, Hi: 0x213f, Stride: 1},\n\t\t{Lo: 0x2145, Hi: 0x2149, Stride: 1},\n\t\t{Lo: 0x214e, Hi: 0x214e, Stride: 1},\n\t\t{Lo: 0x2160, Hi: 0x2188, Stride: 1},\n\t\t{Lo: 0x2c00, Hi: 0x2ce4, Stride: 1},\n\t\t{Lo: 0x2ceb, Hi: 0x2cee, Stride: 1},\n\t\t{Lo: 0x2cf2, Hi: 0x2cf3, Stride: 1},\n\t\t{Lo: 0x2d00, Hi: 0x2d25, Stride: 1},\n\t\t{Lo: 0x2d27, Hi: 0x2d27, Stride: 1},\n\t\t{Lo: 0x2d2d, Hi: 0x2d2d, Stride: 1},\n\t\t{Lo: 0x2d30, Hi: 0x2d67, Stride: 1},\n\t\t{Lo: 0x2d6f, Hi: 0x2d6f, Stride: 1},\n\t\t{Lo: 0x2d80, Hi: 0x2d96, Stride: 1},\n\t\t{Lo: 0x2da0, Hi: 0x2da6, Stride: 1},\n\t\t{Lo: 0x2da8, Hi: 0x2dae, Stride: 1},\n\t\t{Lo: 0x2db0, Hi: 0x2db6, Stride: 1},\n\t\t{Lo: 0x2db8, Hi: 0x2dbe, Stride: 1},\n\t\t{Lo: 0x2dc0, Hi: 0x2dc6, Stride: 1},\n\t\t{Lo: 0x2dc8, Hi: 0x2dce, Stride: 1},\n\t\t{Lo: 0x2dd0, Hi: 0x2dd6, Stride: 1},\n\t\t{Lo: 0x2dd8, Hi: 0x2dde, Stride: 1},\n\t\t{Lo: 0x3005, Hi: 0x3007, Stride: 1},\n\t\t{Lo: 0x3021, Hi: 0x3029, Stride: 1},\n\t\t{Lo: 0x3031, Hi: 0x3035, Stride: 1},\n\t\t{Lo: 0x3038, Hi: 0x303c, Stride: 1},\n\t\t{Lo: 0x3041, Hi: 0x3096, Stride: 1},\n\t\t{Lo: 0x309b, Hi: 0x309f, Stride: 1},\n\t\t{Lo: 0x30a1, Hi: 0x30fa, Stride: 1},\n\t\t{Lo: 0x30fc, Hi: 0x30ff, Stride: 1},\n\t\t{Lo: 0x3105, Hi: 0x312f, Stride: 1},\n\t\t{Lo: 0x3131, Hi: 0x318e, Stride: 1},\n\t\t{Lo: 0x31a0, Hi: 0x31bf, Stride: 1},\n\t\t{Lo: 0x31f0, Hi: 0x31ff, Stride: 1},\n\t\t{Lo: 0x3400, Hi: 0x4dbf, Stride: 1},\n\t\t{Lo: 0x4e00, Hi: 0xa48c, Stride: 1},\n\t\t{Lo: 0xa4d0, Hi: 0xa4fd, Stride: 1},\n\t\t{Lo: 0xa500, Hi: 0xa60c, Stride: 1},\n\t\t{Lo: 0xa610, Hi: 0xa61f, Stride: 1},\n\t\t{Lo: 0xa62a, Hi: 0xa62b, Stride: 1},\n\t\t{Lo: 0xa640, Hi: 0xa66e, Stride: 1},\n\t\t{Lo: 0xa67f, Hi: 0xa69d, Stride: 1},\n\t\t{Lo: 0xa6a0, Hi: 0xa6ef, Stride: 1},\n\t\t{Lo: 0xa717, Hi: 0xa71f, Stride: 1},\n\t\t{Lo: 0xa722, Hi: 0xa788, Stride: 1},\n\t\t{Lo: 0xa78b, Hi: 0xa7ca, Stride: 1},\n\t\t{Lo: 0xa7d0, Hi: 0xa7d1, Stride: 1},\n\t\t{Lo: 0xa7d3, Hi: 0xa7d3, Stride: 1},\n\t\t{Lo: 0xa7d5, Hi: 0xa7d9, Stride: 1},\n\t\t{Lo: 0xa7f2, Hi: 0xa801, Stride: 1},\n\t\t{Lo: 0xa803, Hi: 0xa805, Stride: 1},\n\t\t{Lo: 0xa807, Hi: 0xa80a, Stride: 1},\n\t\t{Lo: 0xa80c, Hi: 0xa822, Stride: 1},\n\t\t{Lo: 0xa840, Hi: 0xa873, Stride: 1},\n\t\t{Lo: 0xa882, Hi: 0xa8b3, Stride: 1},\n\t\t{Lo: 0xa8f2, Hi: 0xa8f7, Stride: 1},\n\t\t{Lo: 0xa8fb, Hi: 0xa8fb, Stride: 1},\n\t\t{Lo: 0xa8fd, Hi: 0xa8fe, Stride: 1},\n\t\t{Lo: 0xa90a, Hi: 0xa925, Stride: 1},\n\t\t{Lo: 0xa930, Hi: 0xa946, Stride: 1},\n\t\t{Lo: 0xa960, Hi: 0xa97c, Stride: 1},\n\t\t{Lo: 0xa984, Hi: 0xa9b2, Stride: 1},\n\t\t{Lo: 0xa9cf, Hi: 0xa9cf, Stride: 1},\n\t\t{Lo: 0xa9e0, Hi: 0xa9e4, Stride: 1},\n\t\t{Lo: 0xa9e6, Hi: 0xa9ef, Stride: 1},\n\t\t{Lo: 0xa9fa, Hi: 0xa9fe, Stride: 1},\n\t\t{Lo: 0xaa00, Hi: 0xaa28, Stride: 1},\n\t\t{Lo: 0xaa40, Hi: 0xaa42, Stride: 1},\n\t\t{Lo: 0xaa44, Hi: 0xaa4b, Stride: 1},\n\t\t{Lo: 0xaa60, Hi: 0xaa76, Stride: 1},\n\t\t{Lo: 0xaa7a, Hi: 0xaa7a, Stride: 1},\n\t\t{Lo: 0xaa7e, Hi: 0xaaaf, Stride: 1},\n\t\t{Lo: 0xaab1, Hi: 0xaab1, Stride: 1},\n\t\t{Lo: 0xaab5, Hi: 0xaab6, Stride: 1},\n\t\t{Lo: 0xaab9, Hi: 0xaabd, Stride: 1},\n\t\t{Lo: 0xaac0, Hi: 0xaac0, Stride: 1},\n\t\t{Lo: 0xaac2, Hi: 0xaac2, Stride: 1},\n\t\t{Lo: 0xaadb, Hi: 0xaadd, Stride: 1},\n\t\t{Lo: 0xaae0, Hi: 0xaaea, Stride: 1},\n\t\t{Lo: 0xaaf2, Hi: 0xaaf4, Stride: 1},\n\t\t{Lo: 0xab01, Hi: 0xab06, Stride: 1},\n\t\t{Lo: 0xab09, Hi: 0xab0e, Stride: 1},\n\t\t{Lo: 0xab11, Hi: 0xab16, Stride: 1},\n\t\t{Lo: 0xab20, Hi: 0xab26, Stride: 1},\n\t\t{Lo: 0xab28, Hi: 0xab2e, Stride: 1},\n\t\t{Lo: 0xab30, Hi: 0xab5a, Stride: 1},\n\t\t{Lo: 0xab5c, Hi: 0xab69, Stride: 1},\n\t\t{Lo: 0xab70, Hi: 0xabe2, Stride: 1},\n\t\t{Lo: 0xac00, Hi: 0xd7a3, Stride: 1},\n\t\t{Lo: 0xd7b0, Hi: 0xd7c6, Stride: 1},\n\t\t{Lo: 0xd7cb, Hi: 0xd7fb, Stride: 1},\n\t\t{Lo: 0xf900, Hi: 0xfa6d, Stride: 1},\n\t\t{Lo: 0xfa70, Hi: 0xfad9, Stride: 1},\n\t\t{Lo: 0xfb00, Hi: 0xfb06, Stride: 1},\n\t\t{Lo: 0xfb13, Hi: 0xfb17, Stride: 1},\n\t\t{Lo: 0xfb1d, Hi: 0xfb1d, Stride: 1},\n\t\t{Lo: 0xfb1f, Hi: 0xfb28, Stride: 1},\n\t\t{Lo: 0xfb2a, Hi: 0xfb36, Stride: 1},\n\t\t{Lo: 0xfb38, Hi: 0xfb3c, Stride: 1},\n\t\t{Lo: 0xfb3e, Hi: 0xfb3e, Stride: 1},\n\t\t{Lo: 0xfb40, Hi: 0xfb41, Stride: 1},\n\t\t{Lo: 0xfb43, Hi: 0xfb44, Stride: 1},\n\t\t{Lo: 0xfb46, Hi: 0xfbb1, Stride: 1},\n\t\t{Lo: 0xfbd3, Hi: 0xfd3d, Stride: 1},\n\t\t{Lo: 0xfd50, Hi: 0xfd8f, Stride: 1},\n\t\t{Lo: 0xfd92, Hi: 0xfdc7, Stride: 1},\n\t\t{Lo: 0xfdf0, Hi: 0xfdfb, Stride: 1},\n\t\t{Lo: 0xfe70, Hi: 0xfe74, Stride: 1},\n\t\t{Lo: 0xfe76, Hi: 0xfefc, Stride: 1},\n\t\t{Lo: 0xff21, Hi: 0xff3a, Stride: 1},\n\t\t{Lo: 0xff41, Hi: 0xff5a, Stride: 1},\n\t\t{Lo: 0xff66, Hi: 0xffbe, Stride: 1},\n\t\t{Lo: 0xffc2, Hi: 0xffc7, Stride: 1},\n\t\t{Lo: 0xffca, Hi: 0xffcf, Stride: 1},\n\t\t{Lo: 0xffd2, Hi: 0xffd7, Stride: 1},\n\t\t{Lo: 0xffda, Hi: 0xffdc, Stride: 1},\n\t\t{Lo: 0x10000, Hi: 0x1000b, Stride: 1},\n\t\t{Lo: 0x1000d, Hi: 0x10026, Stride: 1},\n\t\t{Lo: 0x10028, Hi: 0x1003a, Stride: 1},\n\t\t{Lo: 0x1003c, Hi: 0x1003d, Stride: 1},\n\t\t{Lo: 0x1003f, Hi: 0x1004d, Stride: 1},\n\t\t{Lo: 0x10050, Hi: 0x1005d, Stride: 1},\n\t\t{Lo: 0x10080, Hi: 0x100fa, Stride: 1},\n\t\t{Lo: 0x10140, Hi: 0x10174, Stride: 1},\n\t\t{Lo: 0x10280, Hi: 0x1029c, Stride: 1},\n\t\t{Lo: 0x102a0, Hi: 0x102d0, Stride: 1},\n\t\t{Lo: 0x10300, Hi: 0x1031f, Stride: 1},\n\t\t{Lo: 0x1032d, Hi: 0x1034a, Stride: 1},\n\t\t{Lo: 0x10350, Hi: 0x10375, Stride: 1},\n\t\t{Lo: 0x10380, Hi: 0x1039d, Stride: 1},\n\t\t{Lo: 0x103a0, Hi: 0x103c3, Stride: 1},\n\t\t{Lo: 0x103c8, Hi: 0x103cf, Stride: 1},\n\t\t{Lo: 0x103d1, Hi: 0x103d5, Stride: 1},\n\t\t{Lo: 0x10400, Hi: 0x1049d, Stride: 1},\n\t\t{Lo: 0x104b0, Hi: 0x104d3, Stride: 1},\n\t\t{Lo: 0x104d8, Hi: 0x104fb, Stride: 1},\n\t\t{Lo: 0x10500, Hi: 0x10527, Stride: 1},\n\t\t{Lo: 0x10530, Hi: 0x10563, Stride: 1},\n\t\t{Lo: 0x10570, Hi: 0x1057a, Stride: 1},\n\t\t{Lo: 0x1057c, Hi: 0x1058a, Stride: 1},\n\t\t{Lo: 0x1058c, Hi: 0x10592, Stride: 1},\n\t\t{Lo: 0x10594, Hi: 0x10595, Stride: 1},\n\t\t{Lo: 0x10597, Hi: 0x105a1, Stride: 1},\n\t\t{Lo: 0x105a3, Hi: 0x105b1, Stride: 1},\n\t\t{Lo: 0x105b3, Hi: 0x105b9, Stride: 1},\n\t\t{Lo: 0x105bb, Hi: 0x105bc, Stride: 1},\n\t\t{Lo: 0x10600, Hi: 0x10736, Stride: 1},\n\t\t{Lo: 0x10740, Hi: 0x10755, Stride: 1},\n\t\t{Lo: 0x10760, Hi: 0x10767, Stride: 1},\n\t\t{Lo: 0x10780, Hi: 0x10785, Stride: 1},\n\t\t{Lo: 0x10787, Hi: 0x107b0, Stride: 1},\n\t\t{Lo: 0x107b2, Hi: 0x107ba, Stride: 1},\n\t\t{Lo: 0x10800, Hi: 0x10805, Stride: 1},\n\t\t{Lo: 0x10808, Hi: 0x10808, Stride: 1},\n\t\t{Lo: 0x1080a, Hi: 0x10835, Stride: 1},\n\t\t{Lo: 0x10837, Hi: 0x10838, Stride: 1},\n\t\t{Lo: 0x1083c, Hi: 0x1083c, Stride: 1},\n\t\t{Lo: 0x1083f, Hi: 0x10855, Stride: 1},\n\t\t{Lo: 0x10860, Hi: 0x10876, Stride: 1},\n\t\t{Lo: 0x10880, Hi: 0x1089e, Stride: 1},\n\t\t{Lo: 0x108e0, Hi: 0x108f2, Stride: 1},\n\t\t{Lo: 0x108f4, Hi: 0x108f5, Stride: 1},\n\t\t{Lo: 0x10900, Hi: 0x10915, Stride: 1},\n\t\t{Lo: 0x10920, Hi: 0x10939, Stride: 1},\n\t\t{Lo: 0x10980, Hi: 0x109b7, Stride: 1},\n\t\t{Lo: 0x109be, Hi: 0x109bf, Stride: 1},\n\t\t{Lo: 0x10a00, Hi: 0x10a00, Stride: 1},\n\t\t{Lo: 0x10a10, Hi: 0x10a13, Stride: 1},\n\t\t{Lo: 0x10a15, Hi: 0x10a17, Stride: 1},\n\t\t{Lo: 0x10a19, Hi: 0x10a35, Stride: 1},\n\t\t{Lo: 0x10a60, Hi: 0x10a7c, Stride: 1},\n\t\t{Lo: 0x10a80, Hi: 0x10a9c, Stride: 1},\n\t\t{Lo: 0x10ac0, Hi: 0x10ac7, Stride: 1},\n\t\t{Lo: 0x10ac9, Hi: 0x10ae4, Stride: 1},\n\t\t{Lo: 0x10b00, Hi: 0x10b35, Stride: 1},\n\t\t{Lo: 0x10b40, Hi: 0x10b55, Stride: 1},\n\t\t{Lo: 0x10b60, Hi: 0x10b72, Stride: 1},\n\t\t{Lo: 0x10b80, Hi: 0x10b91, Stride: 1},\n\t\t{Lo: 0x10c00, Hi: 0x10c48, Stride: 1},\n\t\t{Lo: 0x10c80, Hi: 0x10cb2, Stride: 1},\n\t\t{Lo: 0x10cc0, Hi: 0x10cf2, Stride: 1},\n\t\t{Lo: 0x10d00, Hi: 0x10d23, Stride: 1},\n\t\t{Lo: 0x10e80, Hi: 0x10ea9, Stride: 1},\n\t\t{Lo: 0x10eb0, Hi: 0x10eb1, Stride: 1},\n\t\t{Lo: 0x10f00, Hi: 0x10f1c, Stride: 1},\n\t\t{Lo: 0x10f27, Hi: 0x10f27, Stride: 1},\n\t\t{Lo: 0x10f30, Hi: 0x10f45, Stride: 1},\n\t\t{Lo: 0x10f70, Hi: 0x10f81, Stride: 1},\n\t\t{Lo: 0x10fb0, Hi: 0x10fc4, Stride: 1},\n\t\t{Lo: 0x10fe0, Hi: 0x10ff6, Stride: 1},\n\t\t{Lo: 0x11003, Hi: 0x11037, Stride: 1},\n\t\t{Lo: 0x11071, Hi: 0x11072, Stride: 1},\n\t\t{Lo: 0x11075, Hi: 0x11075, Stride: 1},\n\t\t{Lo: 0x11083, Hi: 0x110af, Stride: 1},\n\t\t{Lo: 0x110d0, Hi: 0x110e8, Stride: 1},\n\t\t{Lo: 0x11103, Hi: 0x11126, Stride: 1},\n\t\t{Lo: 0x11144, Hi: 0x11144, Stride: 1},\n\t\t{Lo: 0x11147, Hi: 0x11147, Stride: 1},\n\t\t{Lo: 0x11150, Hi: 0x11172, Stride: 1},\n\t\t{Lo: 0x11176, Hi: 0x11176, Stride: 1},\n\t\t{Lo: 0x11183, Hi: 0x111b2, Stride: 1},\n\t\t{Lo: 0x111c1, Hi: 0x111c4, Stride: 1},\n\t\t{Lo: 0x111da, Hi: 0x111da, Stride: 1},\n\t\t{Lo: 0x111dc, Hi: 0x111dc, Stride: 1},\n\t\t{Lo: 0x11200, Hi: 0x11211, Stride: 1},\n\t\t{Lo: 0x11213, Hi: 0x1122b, Stride: 1},\n\t\t{Lo: 0x1123f, Hi: 0x11240, Stride: 1},\n\t\t{Lo: 0x11280, Hi: 0x11286, Stride: 1},\n\t\t{Lo: 0x11288, Hi: 0x11288, Stride: 1},\n\t\t{Lo: 0x1128a, Hi: 0x1128d, Stride: 1},\n\t\t{Lo: 0x1128f, Hi: 0x1129d, Stride: 1},\n\t\t{Lo: 0x1129f, Hi: 0x112a8, Stride: 1},\n\t\t{Lo: 0x112b0, Hi: 0x112de, Stride: 1},\n\t\t{Lo: 0x11305, Hi: 0x1130c, Stride: 1},\n\t\t{Lo: 0x1130f, Hi: 0x11310, Stride: 1},\n\t\t{Lo: 0x11313, Hi: 0x11328, Stride: 1},\n\t\t{Lo: 0x1132a, Hi: 0x11330, Stride: 1},\n\t\t{Lo: 0x11332, Hi: 0x11333, Stride: 1},\n\t\t{Lo: 0x11335, Hi: 0x11339, Stride: 1},\n\t\t{Lo: 0x1133d, Hi: 0x1133d, Stride: 1},\n\t\t{Lo: 0x11350, Hi: 0x11350, Stride: 1},\n\t\t{Lo: 0x1135d, Hi: 0x11361, Stride: 1},\n\t\t{Lo: 0x11400, Hi: 0x11434, Stride: 1},\n\t\t{Lo: 0x11447, Hi: 0x1144a, Stride: 1},\n\t\t{Lo: 0x1145f, Hi: 0x11461, Stride: 1},\n\t\t{Lo: 0x11480, Hi: 0x114af, Stride: 1},\n\t\t{Lo: 0x114c4, Hi: 0x114c5, Stride: 1},\n\t\t{Lo: 0x114c7, Hi: 0x114c7, Stride: 1},\n\t\t{Lo: 0x11580, Hi: 0x115ae, Stride: 1},\n\t\t{Lo: 0x115d8, Hi: 0x115db, Stride: 1},\n\t\t{Lo: 0x11600, Hi: 0x1162f, Stride: 1},\n\t\t{Lo: 0x11644, Hi: 0x11644, Stride: 1},\n\t\t{Lo: 0x11680, Hi: 0x116aa, Stride: 1},\n\t\t{Lo: 0x116b8, Hi: 0x116b8, Stride: 1},\n\t\t{Lo: 0x11700, Hi: 0x1171a, Stride: 1},\n\t\t{Lo: 0x11740, Hi: 0x11746, Stride: 1},\n\t\t{Lo: 0x11800, Hi: 0x1182b, Stride: 1},\n\t\t{Lo: 0x118a0, Hi: 0x118df, Stride: 1},\n\t\t{Lo: 0x118ff, Hi: 0x11906, Stride: 1},\n\t\t{Lo: 0x11909, Hi: 0x11909, Stride: 1},\n\t\t{Lo: 0x1190c, Hi: 0x11913, Stride: 1},\n\t\t{Lo: 0x11915, Hi: 0x11916, Stride: 1},\n\t\t{Lo: 0x11918, Hi: 0x1192f, Stride: 1},\n\t\t{Lo: 0x1193f, Hi: 0x1193f, Stride: 1},\n\t\t{Lo: 0x11941, Hi: 0x11941, Stride: 1},\n\t\t{Lo: 0x119a0, Hi: 0x119a7, Stride: 1},\n\t\t{Lo: 0x119aa, Hi: 0x119d0, Stride: 1},\n\t\t{Lo: 0x119e1, Hi: 0x119e1, Stride: 1},\n\t\t{Lo: 0x119e3, Hi: 0x119e3, Stride: 1},\n\t\t{Lo: 0x11a00, Hi: 0x11a00, Stride: 1},\n\t\t{Lo: 0x11a0b, Hi: 0x11a32, Stride: 1},\n\t\t{Lo: 0x11a3a, Hi: 0x11a3a, Stride: 1},\n\t\t{Lo: 0x11a50, Hi: 0x11a50, Stride: 1},\n\t\t{Lo: 0x11a5c, Hi: 0x11a89, Stride: 1},\n\t\t{Lo: 0x11a9d, Hi: 0x11a9d, Stride: 1},\n\t\t{Lo: 0x11ab0, Hi: 0x11af8, Stride: 1},\n\t\t{Lo: 0x11c00, Hi: 0x11c08, Stride: 1},\n\t\t{Lo: 0x11c0a, Hi: 0x11c2e, Stride: 1},\n\t\t{Lo: 0x11c40, Hi: 0x11c40, Stride: 1},\n\t\t{Lo: 0x11c72, Hi: 0x11c8f, Stride: 1},\n\t\t{Lo: 0x11d00, Hi: 0x11d06, Stride: 1},\n\t\t{Lo: 0x11d08, Hi: 0x11d09, Stride: 1},\n\t\t{Lo: 0x11d0b, Hi: 0x11d30, Stride: 1},\n\t\t{Lo: 0x11d46, Hi: 0x11d46, Stride: 1},\n\t\t{Lo: 0x11d60, Hi: 0x11d65, Stride: 1},\n\t\t{Lo: 0x11d67, Hi: 0x11d68, Stride: 1},\n\t\t{Lo: 0x11d6a, Hi: 0x11d89, Stride: 1},\n\t\t{Lo: 0x11d98, Hi: 0x11d98, Stride: 1},\n\t\t{Lo: 0x11ee0, Hi: 0x11ef2, Stride: 1},\n\t\t{Lo: 0x11f02, Hi: 0x11f02, Stride: 1},\n\t\t{Lo: 0x11f04, Hi: 0x11f10, Stride: 1},\n\t\t{Lo: 0x11f12, Hi: 0x11f33, Stride: 1},\n\t\t{Lo: 0x11fb0, Hi: 0x11fb0, Stride: 1},\n\t\t{Lo: 0x12000, Hi: 0x12399, Stride: 1},\n\t\t{Lo: 0x12400, Hi: 0x1246e, Stride: 1},\n\t\t{Lo: 0x12480, Hi: 0x12543, Stride: 1},\n\t\t{Lo: 0x12f90, Hi: 0x12ff0, Stride: 1},\n\t\t{Lo: 0x13000, Hi: 0x1342f, Stride: 1},\n\t\t{Lo: 0x13441, Hi: 0x13446, Stride: 1},\n\t\t{Lo: 0x14400, Hi: 0x14646, Stride: 1},\n\t\t{Lo: 0x16800, Hi: 0x16a38, Stride: 1},\n\t\t{Lo: 0x16a40, Hi: 0x16a5e, Stride: 1},\n\t\t{Lo: 0x16a70, Hi: 0x16abe, Stride: 1},\n\t\t{Lo: 0x16ad0, Hi: 0x16aed, Stride: 1},\n\t\t{Lo: 0x16b00, Hi: 0x16b2f, Stride: 1},\n\t\t{Lo: 0x16b40, Hi: 0x16b43, Stride: 1},\n\t\t{Lo: 0x16b63, Hi: 0x16b77, Stride: 1},\n\t\t{Lo: 0x16b7d, Hi: 0x16b8f, Stride: 1},\n\t\t{Lo: 0x16e40, Hi: 0x16e7f, Stride: 1},\n\t\t{Lo: 0x16f00, Hi: 0x16f4a, Stride: 1},\n\t\t{Lo: 0x16f50, Hi: 0x16f50, Stride: 1},\n\t\t{Lo: 0x16f93, Hi: 0x16f9f, Stride: 1},\n\t\t{Lo: 0x16fe0, Hi: 0x16fe1, Stride: 1},\n\t\t{Lo: 0x16fe3, Hi: 0x16fe3, Stride: 1},\n\t\t{Lo: 0x17000, Hi: 0x187f7, Stride: 1},\n\t\t{Lo: 0x18800, Hi: 0x18cd5, Stride: 1},\n\t\t{Lo: 0x18d00, Hi: 0x18d08, Stride: 1},\n\t\t{Lo: 0x1aff0, Hi: 0x1aff3, Stride: 1},\n\t\t{Lo: 0x1aff5, Hi: 0x1affb, Stride: 1},\n\t\t{Lo: 0x1affd, Hi: 0x1affe, Stride: 1},\n\t\t{Lo: 0x1b000, Hi: 0x1b122, Stride: 1},\n\t\t{Lo: 0x1b132, Hi: 0x1b132, Stride: 1},\n\t\t{Lo: 0x1b150, Hi: 0x1b152, Stride: 1},\n\t\t{Lo: 0x1b155, Hi: 0x1b155, Stride: 1},\n\t\t{Lo: 0x1b164, Hi: 0x1b167, Stride: 1},\n\t\t{Lo: 0x1b170, Hi: 0x1b2fb, Stride: 1},\n\t\t{Lo: 0x1bc00, Hi: 0x1bc6a, Stride: 1},\n\t\t{Lo: 0x1bc70, Hi: 0x1bc7c, Stride: 1},\n\t\t{Lo: 0x1bc80, Hi: 0x1bc88, Stride: 1},\n\t\t{Lo: 0x1bc90, Hi: 0x1bc99, Stride: 1},\n\t\t{Lo: 0x1d400, Hi: 0x1d454, Stride: 1},\n\t\t{Lo: 0x1d456, Hi: 0x1d49c, Stride: 1},\n\t\t{Lo: 0x1d49e, Hi: 0x1d49f, Stride: 1},\n\t\t{Lo: 0x1d4a2, Hi: 0x1d4a2, Stride: 1},\n\t\t{Lo: 0x1d4a5, Hi: 0x1d4a6, Stride: 1},\n\t\t{Lo: 0x1d4a9, Hi: 0x1d4ac, Stride: 1},\n\t\t{Lo: 0x1d4ae, Hi: 0x1d4b9, Stride: 1},\n\t\t{Lo: 0x1d4bb, Hi: 0x1d4bb, Stride: 1},\n\t\t{Lo: 0x1d4bd, Hi: 0x1d4c3, Stride: 1},\n\t\t{Lo: 0x1d4c5, Hi: 0x1d505, Stride: 1},\n\t\t{Lo: 0x1d507, Hi: 0x1d50a, Stride: 1},\n\t\t{Lo: 0x1d50d, Hi: 0x1d514, Stride: 1},\n\t\t{Lo: 0x1d516, Hi: 0x1d51c, Stride: 1},\n\t\t{Lo: 0x1d51e, Hi: 0x1d539, Stride: 1},\n\t\t{Lo: 0x1d53b, Hi: 0x1d53e, Stride: 1},\n\t\t{Lo: 0x1d540, Hi: 0x1d544, Stride: 1},\n\t\t{Lo: 0x1d546, Hi: 0x1d546, Stride: 1},\n\t\t{Lo: 0x1d54a, Hi: 0x1d550, Stride: 1},\n\t\t{Lo: 0x1d552, Hi: 0x1d6a5, Stride: 1},\n\t\t{Lo: 0x1d6a8, Hi: 0x1d6c0, Stride: 1},\n\t\t{Lo: 0x1d6c2, Hi: 0x1d6da, Stride: 1},\n\t\t{Lo: 0x1d6dc, Hi: 0x1d6fa, Stride: 1},\n\t\t{Lo: 0x1d6fc, Hi: 0x1d714, Stride: 1},\n\t\t{Lo: 0x1d716, Hi: 0x1d734, Stride: 1},\n\t\t{Lo: 0x1d736, Hi: 0x1d74e, Stride: 1},\n\t\t{Lo: 0x1d750, Hi: 0x1d76e, Stride: 1},\n\t\t{Lo: 0x1d770, Hi: 0x1d788, Stride: 1},\n\t\t{Lo: 0x1d78a, Hi: 0x1d7a8, Stride: 1},\n\t\t{Lo: 0x1d7aa, Hi: 0x1d7c2, Stride: 1},\n\t\t{Lo: 0x1d7c4, Hi: 0x1d7cb, Stride: 1},\n\t\t{Lo: 0x1df00, Hi: 0x1df1e, Stride: 1},\n\t\t{Lo: 0x1df25, Hi: 0x1df2a, Stride: 1},\n\t\t{Lo: 0x1e030, Hi: 0x1e06d, Stride: 1},\n\t\t{Lo: 0x1e100, Hi: 0x1e12c, Stride: 1},\n\t\t{Lo: 0x1e137, Hi: 0x1e13d, Stride: 1},\n\t\t{Lo: 0x1e14e, Hi: 0x1e14e, Stride: 1},\n\t\t{Lo: 0x1e290, Hi: 0x1e2ad, Stride: 1},\n\t\t{Lo: 0x1e2c0, Hi: 0x1e2eb, Stride: 1},\n\t\t{Lo: 0x1e4d0, Hi: 0x1e4eb, Stride: 1},\n\t\t{Lo: 0x1e7e0, Hi: 0x1e7e6, Stride: 1},\n\t\t{Lo: 0x1e7e8, Hi: 0x1e7eb, Stride: 1},\n\t\t{Lo: 0x1e7ed, Hi: 0x1e7ee, Stride: 1},\n\t\t{Lo: 0x1e7f0, Hi: 0x1e7fe, Stride: 1},\n\t\t{Lo: 0x1e800, Hi: 0x1e8c4, Stride: 1},\n\t\t{Lo: 0x1e900, Hi: 0x1e943, Stride: 1},\n\t\t{Lo: 0x1e94b, Hi: 0x1e94b, Stride: 1},\n\t\t{Lo: 0x1ee00, Hi: 0x1ee03, Stride: 1},\n\t\t{Lo: 0x1ee05, Hi: 0x1ee1f, Stride: 1},\n\t\t{Lo: 0x1ee21, Hi: 0x1ee22, Stride: 1},\n\t\t{Lo: 0x1ee24, Hi: 0x1ee24, Stride: 1},\n\t\t{Lo: 0x1ee27, Hi: 0x1ee27, Stride: 1},\n\t\t{Lo: 0x1ee29, Hi: 0x1ee32, Stride: 1},\n\t\t{Lo: 0x1ee34, Hi: 0x1ee37, Stride: 1},\n\t\t{Lo: 0x1ee39, Hi: 0x1ee39, Stride: 1},\n\t\t{Lo: 0x1ee3b, Hi: 0x1ee3b, Stride: 1},\n\t\t{Lo: 0x1ee42, Hi: 0x1ee42, Stride: 1},\n\t\t{Lo: 0x1ee47, Hi: 0x1ee47, Stride: 1},\n\t\t{Lo: 0x1ee49, Hi: 0x1ee49, Stride: 1},\n\t\t{Lo: 0x1ee4b, Hi: 0x1ee4b, Stride: 1},\n\t\t{Lo: 0x1ee4d, Hi: 0x1ee4f, Stride: 1},\n\t\t{Lo: 0x1ee51, Hi: 0x1ee52, Stride: 1},\n\t\t{Lo: 0x1ee54, Hi: 0x1ee54, Stride: 1},\n\t\t{Lo: 0x1ee57, Hi: 0x1ee57, Stride: 1},\n\t\t{Lo: 0x1ee59, Hi: 0x1ee59, Stride: 1},\n\t\t{Lo: 0x1ee5b, Hi: 0x1ee5b, Stride: 1},\n\t\t{Lo: 0x1ee5d, Hi: 0x1ee5d, Stride: 1},\n\t\t{Lo: 0x1ee5f, Hi: 0x1ee5f, Stride: 1},\n\t\t{Lo: 0x1ee61, Hi: 0x1ee62, Stride: 1},\n\t\t{Lo: 0x1ee64, Hi: 0x1ee64, Stride: 1},\n\t\t{Lo: 0x1ee67, Hi: 0x1ee6a, Stride: 1},\n\t\t{Lo: 0x1ee6c, Hi: 0x1ee72, Stride: 1},\n\t\t{Lo: 0x1ee74, Hi: 0x1ee77, Stride: 1},\n\t\t{Lo: 0x1ee79, Hi: 0x1ee7c, Stride: 1},\n\t\t{Lo: 0x1ee7e, Hi: 0x1ee7e, Stride: 1},\n\t\t{Lo: 0x1ee80, Hi: 0x1ee89, Stride: 1},\n\t\t{Lo: 0x1ee8b, Hi: 0x1ee9b, Stride: 1},\n\t\t{Lo: 0x1eea1, Hi: 0x1eea3, Stride: 1},\n\t\t{Lo: 0x1eea5, Hi: 0x1eea9, Stride: 1},\n\t\t{Lo: 0x1eeab, Hi: 0x1eebb, Stride: 1},\n\t\t{Lo: 0x20000, Hi: 0x2a6df, Stride: 1},\n\t\t{Lo: 0x2a700, Hi: 0x2b739, Stride: 1},\n\t\t{Lo: 0x2b740, Hi: 0x2b81d, Stride: 1},\n\t\t{Lo: 0x2b820, Hi: 0x2cea1, Stride: 1},\n\t\t{Lo: 0x2ceb0, Hi: 0x2ebe0, Stride: 1},\n\t\t{Lo: 0x2ebf0, Hi: 0x2ee5d, Stride: 1},\n\t\t{Lo: 0x2f800, Hi: 0x2fa1d, Stride: 1},\n\t\t{Lo: 0x30000, Hi: 0x3134a, Stride: 1},\n\t\t{Lo: 0x31350, Hi: 0x323af, Stride: 1},\n\t},\n}\n\nvar idContinueES5OrESNext = &unicode.RangeTable{\n\tLatinOffset: 129,\n\tR16: []unicode.Range16{\n\t\t{Lo: 0x30, Hi: 0x39, Stride: 1},\n\t\t{Lo: 0x41, Hi: 0x5a, Stride: 1},\n\t\t{Lo: 0x5f, Hi: 0x5f, Stride: 1},\n\t\t{Lo: 0x61, Hi: 0x7a, Stride: 1},\n\t\t{Lo: 0xaa, Hi: 0xaa, Stride: 1},\n\t\t{Lo: 0xb5, Hi: 0xb5, Stride: 1},\n\t\t{Lo: 0xb7, Hi: 0xb7, Stride: 1},\n\t\t{Lo: 0xba, Hi: 0xba, Stride: 1},\n\t\t{Lo: 0xc0, Hi: 0xd6, Stride: 1},\n\t\t{Lo: 0xd8, Hi: 0xf6, Stride: 1},\n\t\t{Lo: 0xf8, Hi: 0x2c1, Stride: 1},\n\t\t{Lo: 0x2c6, Hi: 0x2d1, Stride: 1},\n\t\t{Lo: 0x2e0, Hi: 0x2e4, Stride: 1},\n\t\t{Lo: 0x2ec, Hi: 0x2ec, Stride: 1},\n\t\t{Lo: 0x2ee, Hi: 0x2ee, Stride: 1},\n\t\t{Lo: 0x300, Hi: 0x374, Stride: 1},\n\t\t{Lo: 0x376, Hi: 0x377, Stride: 1},\n\t\t{Lo: 0x37a, Hi: 0x37d, Stride: 1},\n\t\t{Lo: 0x37f, Hi: 0x37f, Stride: 1},\n\t\t{Lo: 0x386, Hi: 0x38a, Stride: 1},\n\t\t{Lo: 0x38c, Hi: 0x38c, Stride: 1},\n\t\t{Lo: 0x38e, Hi: 0x3a1, Stride: 1},\n\t\t{Lo: 0x3a3, Hi: 0x3f5, Stride: 1},\n\t\t{Lo: 0x3f7, Hi: 0x481, Stride: 1},\n\t\t{Lo: 0x483, Hi: 0x487, Stride: 1},\n\t\t{Lo: 0x48a, Hi: 0x52f, Stride: 1},\n\t\t{Lo: 0x531, Hi: 0x556, Stride: 1},\n\t\t{Lo: 0x559, Hi: 0x559, Stride: 1},\n\t\t{Lo: 0x560, Hi: 0x588, Stride: 1},\n\t\t{Lo: 0x591, Hi: 0x5bd, Stride: 1},\n\t\t{Lo: 0x5bf, Hi: 0x5bf, Stride: 1},\n\t\t{Lo: 0x5c1, Hi: 0x5c2, Stride: 1},\n\t\t{Lo: 0x5c4, Hi: 0x5c5, Stride: 1},\n\t\t{Lo: 0x5c7, Hi: 0x5c7, Stride: 1},\n\t\t{Lo: 0x5d0, Hi: 0x5ea, Stride: 1},\n\t\t{Lo: 0x5ef, Hi: 0x5f2, Stride: 1},\n\t\t{Lo: 0x610, Hi: 0x61a, Stride: 1},\n\t\t{Lo: 0x620, Hi: 0x669, Stride: 1},\n\t\t{Lo: 0x66e, Hi: 0x6d3, Stride: 1},\n\t\t{Lo: 0x6d5, Hi: 0x6dc, Stride: 1},\n\t\t{Lo: 0x6df, Hi: 0x6e8, Stride: 1},\n\t\t{Lo: 0x6ea, Hi: 0x6fc, Stride: 1},\n\t\t{Lo: 0x6ff, Hi: 0x6ff, Stride: 1},\n\t\t{Lo: 0x710, Hi: 0x74a, Stride: 1},\n\t\t{Lo: 0x74d, Hi: 0x7b1, Stride: 1},\n\t\t{Lo: 0x7c0, Hi: 0x7f5, Stride: 1},\n\t\t{Lo: 0x7fa, Hi: 0x7fa, Stride: 1},\n\t\t{Lo: 0x7fd, Hi: 0x7fd, Stride: 1},\n\t\t{Lo: 0x800, Hi: 0x82d, Stride: 1},\n\t\t{Lo: 0x840, Hi: 0x85b, Stride: 1},\n\t\t{Lo: 0x860, Hi: 0x86a, Stride: 1},\n\t\t{Lo: 0x870, Hi: 0x887, Stride: 1},\n\t\t{Lo: 0x889, Hi: 0x88e, Stride: 1},\n\t\t{Lo: 0x898, Hi: 0x8e1, Stride: 1},\n\t\t{Lo: 0x8e3, Hi: 0x963, Stride: 1},\n\t\t{Lo: 0x966, Hi: 0x96f, Stride: 1},\n\t\t{Lo: 0x971, Hi: 0x983, Stride: 1},\n\t\t{Lo: 0x985, Hi: 0x98c, Stride: 1},\n\t\t{Lo: 0x98f, Hi: 0x990, Stride: 1},\n\t\t{Lo: 0x993, Hi: 0x9a8, Stride: 1},\n\t\t{Lo: 0x9aa, Hi: 0x9b0, Stride: 1},\n\t\t{Lo: 0x9b2, Hi: 0x9b2, Stride: 1},\n\t\t{Lo: 0x9b6, Hi: 0x9b9, Stride: 1},\n\t\t{Lo: 0x9bc, Hi: 0x9c4, Stride: 1},\n\t\t{Lo: 0x9c7, Hi: 0x9c8, Stride: 1},\n\t\t{Lo: 0x9cb, Hi: 0x9ce, Stride: 1},\n\t\t{Lo: 0x9d7, Hi: 0x9d7, Stride: 1},\n\t\t{Lo: 0x9dc, Hi: 0x9dd, Stride: 1},\n\t\t{Lo: 0x9df, Hi: 0x9e3, Stride: 1},\n\t\t{Lo: 0x9e6, Hi: 0x9f1, Stride: 1},\n\t\t{Lo: 0x9fc, Hi: 0x9fc, Stride: 1},\n\t\t{Lo: 0x9fe, Hi: 0x9fe, Stride: 1},\n\t\t{Lo: 0xa01, Hi: 0xa03, Stride: 1},\n\t\t{Lo: 0xa05, Hi: 0xa0a, Stride: 1},\n\t\t{Lo: 0xa0f, Hi: 0xa10, Stride: 1},\n\t\t{Lo: 0xa13, Hi: 0xa28, Stride: 1},\n\t\t{Lo: 0xa2a, Hi: 0xa30, Stride: 1},\n\t\t{Lo: 0xa32, Hi: 0xa33, Stride: 1},\n\t\t{Lo: 0xa35, Hi: 0xa36, Stride: 1},\n\t\t{Lo: 0xa38, Hi: 0xa39, Stride: 1},\n\t\t{Lo: 0xa3c, Hi: 0xa3c, Stride: 1},\n\t\t{Lo: 0xa3e, Hi: 0xa42, Stride: 1},\n\t\t{Lo: 0xa47, Hi: 0xa48, Stride: 1},\n\t\t{Lo: 0xa4b, Hi: 0xa4d, Stride: 1},\n\t\t{Lo: 0xa51, Hi: 0xa51, Stride: 1},\n\t\t{Lo: 0xa59, Hi: 0xa5c, Stride: 1},\n\t\t{Lo: 0xa5e, Hi: 0xa5e, Stride: 1},\n\t\t{Lo: 0xa66, Hi: 0xa75, Stride: 1},\n\t\t{Lo: 0xa81, Hi: 0xa83, Stride: 1},\n\t\t{Lo: 0xa85, Hi: 0xa8d, Stride: 1},\n\t\t{Lo: 0xa8f, Hi: 0xa91, Stride: 1},\n\t\t{Lo: 0xa93, Hi: 0xaa8, Stride: 1},\n\t\t{Lo: 0xaaa, Hi: 0xab0, Stride: 1},\n\t\t{Lo: 0xab2, Hi: 0xab3, Stride: 1},\n\t\t{Lo: 0xab5, Hi: 0xab9, Stride: 1},\n\t\t{Lo: 0xabc, Hi: 0xac5, Stride: 1},\n\t\t{Lo: 0xac7, Hi: 0xac9, Stride: 1},\n\t\t{Lo: 0xacb, Hi: 0xacd, Stride: 1},\n\t\t{Lo: 0xad0, Hi: 0xad0, Stride: 1},\n\t\t{Lo: 0xae0, Hi: 0xae3, Stride: 1},\n\t\t{Lo: 0xae6, Hi: 0xaef, Stride: 1},\n\t\t{Lo: 0xaf9, Hi: 0xaff, Stride: 1},\n\t\t{Lo: 0xb01, Hi: 0xb03, Stride: 1},\n\t\t{Lo: 0xb05, Hi: 0xb0c, Stride: 1},\n\t\t{Lo: 0xb0f, Hi: 0xb10, Stride: 1},\n\t\t{Lo: 0xb13, Hi: 0xb28, Stride: 1},\n\t\t{Lo: 0xb2a, Hi: 0xb30, Stride: 1},\n\t\t{Lo: 0xb32, Hi: 0xb33, Stride: 1},\n\t\t{Lo: 0xb35, Hi: 0xb39, Stride: 1},\n\t\t{Lo: 0xb3c, Hi: 0xb44, Stride: 1},\n\t\t{Lo: 0xb47, Hi: 0xb48, Stride: 1},\n\t\t{Lo: 0xb4b, Hi: 0xb4d, Stride: 1},\n\t\t{Lo: 0xb55, Hi: 0xb57, Stride: 1},\n\t\t{Lo: 0xb5c, Hi: 0xb5d, Stride: 1},\n\t\t{Lo: 0xb5f, Hi: 0xb63, Stride: 1},\n\t\t{Lo: 0xb66, Hi: 0xb6f, Stride: 1},\n\t\t{Lo: 0xb71, Hi: 0xb71, Stride: 1},\n\t\t{Lo: 0xb82, Hi: 0xb83, Stride: 1},\n\t\t{Lo: 0xb85, Hi: 0xb8a, Stride: 1},\n\t\t{Lo: 0xb8e, Hi: 0xb90, Stride: 1},\n\t\t{Lo: 0xb92, Hi: 0xb95, Stride: 1},\n\t\t{Lo: 0xb99, Hi: 0xb9a, Stride: 1},\n\t\t{Lo: 0xb9c, Hi: 0xb9c, Stride: 1},\n\t\t{Lo: 0xb9e, Hi: 0xb9f, Stride: 1},\n\t\t{Lo: 0xba3, Hi: 0xba4, Stride: 1},\n\t\t{Lo: 0xba8, Hi: 0xbaa, Stride: 1},\n\t\t{Lo: 0xbae, Hi: 0xbb9, Stride: 1},\n\t\t{Lo: 0xbbe, Hi: 0xbc2, Stride: 1},\n\t\t{Lo: 0xbc6, Hi: 0xbc8, Stride: 1},\n\t\t{Lo: 0xbca, Hi: 0xbcd, Stride: 1},\n\t\t{Lo: 0xbd0, Hi: 0xbd0, Stride: 1},\n\t\t{Lo: 0xbd7, Hi: 0xbd7, Stride: 1},\n\t\t{Lo: 0xbe6, Hi: 0xbef, Stride: 1},\n\t\t{Lo: 0xc00, Hi: 0xc0c, Stride: 1},\n\t\t{Lo: 0xc0e, Hi: 0xc10, Stride: 1},\n\t\t{Lo: 0xc12, Hi: 0xc28, Stride: 1},\n\t\t{Lo: 0xc2a, Hi: 0xc39, Stride: 1},\n\t\t{Lo: 0xc3c, Hi: 0xc44, Stride: 1},\n\t\t{Lo: 0xc46, Hi: 0xc48, Stride: 1},\n\t\t{Lo: 0xc4a, Hi: 0xc4d, Stride: 1},\n\t\t{Lo: 0xc55, Hi: 0xc56, Stride: 1},\n\t\t{Lo: 0xc58, Hi: 0xc5a, Stride: 1},\n\t\t{Lo: 0xc5d, Hi: 0xc5d, Stride: 1},\n\t\t{Lo: 0xc60, Hi: 0xc63, Stride: 1},\n\t\t{Lo: 0xc66, Hi: 0xc6f, Stride: 1},\n\t\t{Lo: 0xc80, Hi: 0xc83, Stride: 1},\n\t\t{Lo: 0xc85, Hi: 0xc8c, Stride: 1},\n\t\t{Lo: 0xc8e, Hi: 0xc90, Stride: 1},\n\t\t{Lo: 0xc92, Hi: 0xca8, Stride: 1},\n\t\t{Lo: 0xcaa, Hi: 0xcb3, Stride: 1},\n\t\t{Lo: 0xcb5, Hi: 0xcb9, Stride: 1},\n\t\t{Lo: 0xcbc, Hi: 0xcc4, Stride: 1},\n\t\t{Lo: 0xcc6, Hi: 0xcc8, Stride: 1},\n\t\t{Lo: 0xcca, Hi: 0xccd, Stride: 1},\n\t\t{Lo: 0xcd5, Hi: 0xcd6, Stride: 1},\n\t\t{Lo: 0xcdd, Hi: 0xcde, Stride: 1},\n\t\t{Lo: 0xce0, Hi: 0xce3, Stride: 1},\n\t\t{Lo: 0xce6, Hi: 0xcef, Stride: 1},\n\t\t{Lo: 0xcf1, Hi: 0xcf3, Stride: 1},\n\t\t{Lo: 0xd00, Hi: 0xd0c, Stride: 1},\n\t\t{Lo: 0xd0e, Hi: 0xd10, Stride: 1},\n\t\t{Lo: 0xd12, Hi: 0xd44, Stride: 1},\n\t\t{Lo: 0xd46, Hi: 0xd48, Stride: 1},\n\t\t{Lo: 0xd4a, Hi: 0xd4e, Stride: 1},\n\t\t{Lo: 0xd54, Hi: 0xd57, Stride: 1},\n\t\t{Lo: 0xd5f, Hi: 0xd63, Stride: 1},\n\t\t{Lo: 0xd66, Hi: 0xd6f, Stride: 1},\n\t\t{Lo: 0xd7a, Hi: 0xd7f, Stride: 1},\n\t\t{Lo: 0xd81, Hi: 0xd83, Stride: 1},\n\t\t{Lo: 0xd85, Hi: 0xd96, Stride: 1},\n\t\t{Lo: 0xd9a, Hi: 0xdb1, Stride: 1},\n\t\t{Lo: 0xdb3, Hi: 0xdbb, Stride: 1},\n\t\t{Lo: 0xdbd, Hi: 0xdbd, Stride: 1},\n\t\t{Lo: 0xdc0, Hi: 0xdc6, Stride: 1},\n\t\t{Lo: 0xdca, Hi: 0xdca, Stride: 1},\n\t\t{Lo: 0xdcf, Hi: 0xdd4, Stride: 1},\n\t\t{Lo: 0xdd6, Hi: 0xdd6, Stride: 1},\n\t\t{Lo: 0xdd8, Hi: 0xddf, Stride: 1},\n\t\t{Lo: 0xde6, Hi: 0xdef, Stride: 1},\n\t\t{Lo: 0xdf2, Hi: 0xdf3, Stride: 1},\n\t\t{Lo: 0xe01, Hi: 0xe3a, Stride: 1},\n\t\t{Lo: 0xe40, Hi: 0xe4e, Stride: 1},\n\t\t{Lo: 0xe50, Hi: 0xe59, Stride: 1},\n\t\t{Lo: 0xe81, Hi: 0xe82, Stride: 1},\n\t\t{Lo: 0xe84, Hi: 0xe84, Stride: 1},\n\t\t{Lo: 0xe86, Hi: 0xe8a, Stride: 1},\n\t\t{Lo: 0xe8c, Hi: 0xea3, Stride: 1},\n\t\t{Lo: 0xea5, Hi: 0xea5, Stride: 1},\n\t\t{Lo: 0xea7, Hi: 0xebd, Stride: 1},\n\t\t{Lo: 0xec0, Hi: 0xec4, Stride: 1},\n\t\t{Lo: 0xec6, Hi: 0xec6, Stride: 1},\n\t\t{Lo: 0xec8, Hi: 0xece, Stride: 1},\n\t\t{Lo: 0xed0, Hi: 0xed9, Stride: 1},\n\t\t{Lo: 0xedc, Hi: 0xedf, Stride: 1},\n\t\t{Lo: 0xf00, Hi: 0xf00, Stride: 1},\n\t\t{Lo: 0xf18, Hi: 0xf19, Stride: 1},\n\t\t{Lo: 0xf20, Hi: 0xf29, Stride: 1},\n\t\t{Lo: 0xf35, Hi: 0xf35, Stride: 1},\n\t\t{Lo: 0xf37, Hi: 0xf37, Stride: 1},\n\t\t{Lo: 0xf39, Hi: 0xf39, Stride: 1},\n\t\t{Lo: 0xf3e, Hi: 0xf47, Stride: 1},\n\t\t{Lo: 0xf49, Hi: 0xf6c, Stride: 1},\n\t\t{Lo: 0xf71, Hi: 0xf84, Stride: 1},\n\t\t{Lo: 0xf86, Hi: 0xf97, Stride: 1},\n\t\t{Lo: 0xf99, Hi: 0xfbc, Stride: 1},\n\t\t{Lo: 0xfc6, Hi: 0xfc6, Stride: 1},\n\t},\n\tR32: []unicode.Range32{\n\t\t{Lo: 0x1000, Hi: 0x1049, Stride: 1},\n\t\t{Lo: 0x1050, Hi: 0x109d, Stride: 1},\n\t\t{Lo: 0x10a0, Hi: 0x10c5, Stride: 1},\n\t\t{Lo: 0x10c7, Hi: 0x10c7, Stride: 1},\n\t\t{Lo: 0x10cd, Hi: 0x10cd, Stride: 1},\n\t\t{Lo: 0x10d0, Hi: 0x10fa, Stride: 1},\n\t\t{Lo: 0x10fc, Hi: 0x1248, Stride: 1},\n\t\t{Lo: 0x124a, Hi: 0x124d, Stride: 1},\n\t\t{Lo: 0x1250, Hi: 0x1256, Stride: 1},\n\t\t{Lo: 0x1258, Hi: 0x1258, Stride: 1},\n\t\t{Lo: 0x125a, Hi: 0x125d, Stride: 1},\n\t\t{Lo: 0x1260, Hi: 0x1288, Stride: 1},\n\t\t{Lo: 0x128a, Hi: 0x128d, Stride: 1},\n\t\t{Lo: 0x1290, Hi: 0x12b0, Stride: 1},\n\t\t{Lo: 0x12b2, Hi: 0x12b5, Stride: 1},\n\t\t{Lo: 0x12b8, Hi: 0x12be, Stride: 1},\n\t\t{Lo: 0x12c0, Hi: 0x12c0, Stride: 1},\n\t\t{Lo: 0x12c2, Hi: 0x12c5, Stride: 1},\n\t\t{Lo: 0x12c8, Hi: 0x12d6, Stride: 1},\n\t\t{Lo: 0x12d8, Hi: 0x1310, Stride: 1},\n\t\t{Lo: 0x1312, Hi: 0x1315, Stride: 1},\n\t\t{Lo: 0x1318, Hi: 0x135a, Stride: 1},\n\t\t{Lo: 0x135d, Hi: 0x135f, Stride: 1},\n\t\t{Lo: 0x1369, Hi: 0x1371, Stride: 1},\n\t\t{Lo: 0x1380, Hi: 0x138f, Stride: 1},\n\t\t{Lo: 0x13a0, Hi: 0x13f5, Stride: 1},\n\t\t{Lo: 0x13f8, Hi: 0x13fd, Stride: 1},\n\t\t{Lo: 0x1401, Hi: 0x166c, Stride: 1},\n\t\t{Lo: 0x166f, Hi: 0x167f, Stride: 1},\n\t\t{Lo: 0x1681, Hi: 0x169a, Stride: 1},\n\t\t{Lo: 0x16a0, Hi: 0x16ea, Stride: 1},\n\t\t{Lo: 0x16ee, Hi: 0x16f8, Stride: 1},\n\t\t{Lo: 0x1700, Hi: 0x1715, Stride: 1},\n\t\t{Lo: 0x171f, Hi: 0x1734, Stride: 1},\n\t\t{Lo: 0x1740, Hi: 0x1753, Stride: 1},\n\t\t{Lo: 0x1760, Hi: 0x176c, Stride: 1},\n\t\t{Lo: 0x176e, Hi: 0x1770, Stride: 1},\n\t\t{Lo: 0x1772, Hi: 0x1773, Stride: 1},\n\t\t{Lo: 0x1780, Hi: 0x17d3, Stride: 1},\n\t\t{Lo: 0x17d7, Hi: 0x17d7, Stride: 1},\n\t\t{Lo: 0x17dc, Hi: 0x17dd, Stride: 1},\n\t\t{Lo: 0x17e0, Hi: 0x17e9, Stride: 1},\n\t\t{Lo: 0x180b, Hi: 0x180d, Stride: 1},\n\t\t{Lo: 0x180f, Hi: 0x1819, Stride: 1},\n\t\t{Lo: 0x1820, Hi: 0x1878, Stride: 1},\n\t\t{Lo: 0x1880, Hi: 0x18aa, Stride: 1},\n\t\t{Lo: 0x18b0, Hi: 0x18f5, Stride: 1},\n\t\t{Lo: 0x1900, Hi: 0x191e, Stride: 1},\n\t\t{Lo: 0x1920, Hi: 0x192b, Stride: 1},\n\t\t{Lo: 0x1930, Hi: 0x193b, Stride: 1},\n\t\t{Lo: 0x1946, Hi: 0x196d, Stride: 1},\n\t\t{Lo: 0x1970, Hi: 0x1974, Stride: 1},\n\t\t{Lo: 0x1980, Hi: 0x19ab, Stride: 1},\n\t\t{Lo: 0x19b0, Hi: 0x19c9, Stride: 1},\n\t\t{Lo: 0x19d0, Hi: 0x19da, Stride: 1},\n\t\t{Lo: 0x1a00, Hi: 0x1a1b, Stride: 1},\n\t\t{Lo: 0x1a20, Hi: 0x1a5e, Stride: 1},\n\t\t{Lo: 0x1a60, Hi: 0x1a7c, Stride: 1},\n\t\t{Lo: 0x1a7f, Hi: 0x1a89, Stride: 1},\n\t\t{Lo: 0x1a90, Hi: 0x1a99, Stride: 1},\n\t\t{Lo: 0x1aa7, Hi: 0x1aa7, Stride: 1},\n\t\t{Lo: 0x1ab0, Hi: 0x1abd, Stride: 1},\n\t\t{Lo: 0x1abf, Hi: 0x1ace, Stride: 1},\n\t\t{Lo: 0x1b00, Hi: 0x1b4c, Stride: 1},\n\t\t{Lo: 0x1b50, Hi: 0x1b59, Stride: 1},\n\t\t{Lo: 0x1b6b, Hi: 0x1b73, Stride: 1},\n\t\t{Lo: 0x1b80, Hi: 0x1bf3, Stride: 1},\n\t\t{Lo: 0x1c00, Hi: 0x1c37, Stride: 1},\n\t\t{Lo: 0x1c40, Hi: 0x1c49, Stride: 1},\n\t\t{Lo: 0x1c4d, Hi: 0x1c7d, Stride: 1},\n\t\t{Lo: 0x1c80, Hi: 0x1c88, Stride: 1},\n\t\t{Lo: 0x1c90, Hi: 0x1cba, Stride: 1},\n\t\t{Lo: 0x1cbd, Hi: 0x1cbf, Stride: 1},\n\t\t{Lo: 0x1cd0, Hi: 0x1cd2, Stride: 1},\n\t\t{Lo: 0x1cd4, Hi: 0x1cfa, Stride: 1},\n\t\t{Lo: 0x1d00, Hi: 0x1f15, Stride: 1},\n\t\t{Lo: 0x1f18, Hi: 0x1f1d, Stride: 1},\n\t\t{Lo: 0x1f20, Hi: 0x1f45, Stride: 1},\n\t\t{Lo: 0x1f48, Hi: 0x1f4d, Stride: 1},\n\t\t{Lo: 0x1f50, Hi: 0x1f57, Stride: 1},\n\t\t{Lo: 0x1f59, Hi: 0x1f59, Stride: 1},\n\t\t{Lo: 0x1f5b, Hi: 0x1f5b, Stride: 1},\n\t\t{Lo: 0x1f5d, Hi: 0x1f5d, Stride: 1},\n\t\t{Lo: 0x1f5f, Hi: 0x1f7d, Stride: 1},\n\t\t{Lo: 0x1f80, Hi: 0x1fb4, Stride: 1},\n\t\t{Lo: 0x1fb6, Hi: 0x1fbc, Stride: 1},\n\t\t{Lo: 0x1fbe, Hi: 0x1fbe, Stride: 1},\n\t\t{Lo: 0x1fc2, Hi: 0x1fc4, Stride: 1},\n\t\t{Lo: 0x1fc6, Hi: 0x1fcc, Stride: 1},\n\t\t{Lo: 0x1fd0, Hi: 0x1fd3, Stride: 1},\n\t\t{Lo: 0x1fd6, Hi: 0x1fdb, Stride: 1},\n\t\t{Lo: 0x1fe0, Hi: 0x1fec, Stride: 1},\n\t\t{Lo: 0x1ff2, Hi: 0x1ff4, Stride: 1},\n\t\t{Lo: 0x1ff6, Hi: 0x1ffc, Stride: 1},\n\t\t{Lo: 0x200c, Hi: 0x200d, Stride: 1},\n\t\t{Lo: 0x203f, Hi: 0x2040, Stride: 1},\n\t\t{Lo: 0x2054, Hi: 0x2054, Stride: 1},\n\t\t{Lo: 0x2071, Hi: 0x2071, Stride: 1},\n\t\t{Lo: 0x207f, Hi: 0x207f, Stride: 1},\n\t\t{Lo: 0x2090, Hi: 0x209c, Stride: 1},\n\t\t{Lo: 0x20d0, Hi: 0x20dc, Stride: 1},\n\t\t{Lo: 0x20e1, Hi: 0x20e1, Stride: 1},\n\t\t{Lo: 0x20e5, Hi: 0x20f0, Stride: 1},\n\t\t{Lo: 0x2102, Hi: 0x2102, Stride: 1},\n\t\t{Lo: 0x2107, Hi: 0x2107, Stride: 1},\n\t\t{Lo: 0x210a, Hi: 0x2113, Stride: 1},\n\t\t{Lo: 0x2115, Hi: 0x2115, Stride: 1},\n\t\t{Lo: 0x2118, Hi: 0x211d, Stride: 1},\n\t\t{Lo: 0x2124, Hi: 0x2124, Stride: 1},\n\t\t{Lo: 0x2126, Hi: 0x2126, Stride: 1},\n\t\t{Lo: 0x2128, Hi: 0x2128, Stride: 1},\n\t\t{Lo: 0x212a, Hi: 0x2139, Stride: 1},\n\t\t{Lo: 0x213c, Hi: 0x213f, Stride: 1},\n\t\t{Lo: 0x2145, Hi: 0x2149, Stride: 1},\n\t\t{Lo: 0x214e, Hi: 0x214e, Stride: 1},\n\t\t{Lo: 0x2160, Hi: 0x2188, Stride: 1},\n\t\t{Lo: 0x2c00, Hi: 0x2ce4, Stride: 1},\n\t\t{Lo: 0x2ceb, Hi: 0x2cf3, Stride: 1},\n\t\t{Lo: 0x2d00, Hi: 0x2d25, Stride: 1},\n\t\t{Lo: 0x2d27, Hi: 0x2d27, Stride: 1},\n\t\t{Lo: 0x2d2d, Hi: 0x2d2d, Stride: 1},\n\t\t{Lo: 0x2d30, Hi: 0x2d67, Stride: 1},\n\t\t{Lo: 0x2d6f, Hi: 0x2d6f, Stride: 1},\n\t\t{Lo: 0x2d7f, Hi: 0x2d96, Stride: 1},\n\t\t{Lo: 0x2da0, Hi: 0x2da6, Stride: 1},\n\t\t{Lo: 0x2da8, Hi: 0x2dae, Stride: 1},\n\t\t{Lo: 0x2db0, Hi: 0x2db6, Stride: 1},\n\t\t{Lo: 0x2db8, Hi: 0x2dbe, Stride: 1},\n\t\t{Lo: 0x2dc0, Hi: 0x2dc6, Stride: 1},\n\t\t{Lo: 0x2dc8, Hi: 0x2dce, Stride: 1},\n\t\t{Lo: 0x2dd0, Hi: 0x2dd6, Stride: 1},\n\t\t{Lo: 0x2dd8, Hi: 0x2dde, Stride: 1},\n\t\t{Lo: 0x2de0, Hi: 0x2dff, Stride: 1},\n\t\t{Lo: 0x3005, Hi: 0x3007, Stride: 1},\n\t\t{Lo: 0x3021, Hi: 0x302f, Stride: 1},\n\t\t{Lo: 0x3031, Hi: 0x3035, Stride: 1},\n\t\t{Lo: 0x3038, Hi: 0x303c, Stride: 1},\n\t\t{Lo: 0x3041, Hi: 0x3096, Stride: 1},\n\t\t{Lo: 0x3099, Hi: 0x309f, Stride: 1},\n\t\t{Lo: 0x30a1, Hi: 0x30ff, Stride: 1},\n\t\t{Lo: 0x3105, Hi: 0x312f, Stride: 1},\n\t\t{Lo: 0x3131, Hi: 0x318e, Stride: 1},\n\t\t{Lo: 0x31a0, Hi: 0x31bf, Stride: 1},\n\t\t{Lo: 0x31f0, Hi: 0x31ff, Stride: 1},\n\t\t{Lo: 0x3400, Hi: 0x4dbf, Stride: 1},\n\t\t{Lo: 0x4e00, Hi: 0xa48c, Stride: 1},\n\t\t{Lo: 0xa4d0, Hi: 0xa4fd, Stride: 1},\n\t\t{Lo: 0xa500, Hi: 0xa60c, Stride: 1},\n\t\t{Lo: 0xa610, Hi: 0xa62b, Stride: 1},\n\t\t{Lo: 0xa640, Hi: 0xa66f, Stride: 1},\n\t\t{Lo: 0xa674, Hi: 0xa67d, Stride: 1},\n\t\t{Lo: 0xa67f, Hi: 0xa6f1, Stride: 1},\n\t\t{Lo: 0xa717, Hi: 0xa71f, Stride: 1},\n\t\t{Lo: 0xa722, Hi: 0xa788, Stride: 1},\n\t\t{Lo: 0xa78b, Hi: 0xa7ca, Stride: 1},\n\t\t{Lo: 0xa7d0, Hi: 0xa7d1, Stride: 1},\n\t\t{Lo: 0xa7d3, Hi: 0xa7d3, Stride: 1},\n\t\t{Lo: 0xa7d5, Hi: 0xa7d9, Stride: 1},\n\t\t{Lo: 0xa7f2, Hi: 0xa827, Stride: 1},\n\t\t{Lo: 0xa82c, Hi: 0xa82c, Stride: 1},\n\t\t{Lo: 0xa840, Hi: 0xa873, Stride: 1},\n\t\t{Lo: 0xa880, Hi: 0xa8c5, Stride: 1},\n\t\t{Lo: 0xa8d0, Hi: 0xa8d9, Stride: 1},\n\t\t{Lo: 0xa8e0, Hi: 0xa8f7, Stride: 1},\n\t\t{Lo: 0xa8fb, Hi: 0xa8fb, Stride: 1},\n\t\t{Lo: 0xa8fd, Hi: 0xa92d, Stride: 1},\n\t\t{Lo: 0xa930, Hi: 0xa953, Stride: 1},\n\t\t{Lo: 0xa960, Hi: 0xa97c, Stride: 1},\n\t\t{Lo: 0xa980, Hi: 0xa9c0, Stride: 1},\n\t\t{Lo: 0xa9cf, Hi: 0xa9d9, Stride: 1},\n\t\t{Lo: 0xa9e0, Hi: 0xa9fe, Stride: 1},\n\t\t{Lo: 0xaa00, Hi: 0xaa36, Stride: 1},\n\t\t{Lo: 0xaa40, Hi: 0xaa4d, Stride: 1},\n\t\t{Lo: 0xaa50, Hi: 0xaa59, Stride: 1},\n\t\t{Lo: 0xaa60, Hi: 0xaa76, Stride: 1},\n\t\t{Lo: 0xaa7a, Hi: 0xaac2, Stride: 1},\n\t\t{Lo: 0xaadb, Hi: 0xaadd, Stride: 1},\n\t\t{Lo: 0xaae0, Hi: 0xaaef, Stride: 1},\n\t\t{Lo: 0xaaf2, Hi: 0xaaf6, Stride: 1},\n\t\t{Lo: 0xab01, Hi: 0xab06, Stride: 1},\n\t\t{Lo: 0xab09, Hi: 0xab0e, Stride: 1},\n\t\t{Lo: 0xab11, Hi: 0xab16, Stride: 1},\n\t\t{Lo: 0xab20, Hi: 0xab26, Stride: 1},\n\t\t{Lo: 0xab28, Hi: 0xab2e, Stride: 1},\n\t\t{Lo: 0xab30, Hi: 0xab5a, Stride: 1},\n\t\t{Lo: 0xab5c, Hi: 0xab69, Stride: 1},\n\t\t{Lo: 0xab70, Hi: 0xabea, Stride: 1},\n\t\t{Lo: 0xabec, Hi: 0xabed, Stride: 1},\n\t\t{Lo: 0xabf0, Hi: 0xabf9, Stride: 1},\n\t\t{Lo: 0xac00, Hi: 0xd7a3, Stride: 1},\n\t\t{Lo: 0xd7b0, Hi: 0xd7c6, Stride: 1},\n\t\t{Lo: 0xd7cb, Hi: 0xd7fb, Stride: 1},\n\t\t{Lo: 0xf900, Hi: 0xfa6d, Stride: 1},\n\t\t{Lo: 0xfa70, Hi: 0xfad9, Stride: 1},\n\t\t{Lo: 0xfb00, Hi: 0xfb06, Stride: 1},\n\t\t{Lo: 0xfb13, Hi: 0xfb17, Stride: 1},\n\t\t{Lo: 0xfb1d, Hi: 0xfb28, Stride: 1},\n\t\t{Lo: 0xfb2a, Hi: 0xfb36, Stride: 1},\n\t\t{Lo: 0xfb38, Hi: 0xfb3c, Stride: 1},\n\t\t{Lo: 0xfb3e, Hi: 0xfb3e, Stride: 1},\n\t\t{Lo: 0xfb40, Hi: 0xfb41, Stride: 1},\n\t\t{Lo: 0xfb43, Hi: 0xfb44, Stride: 1},\n\t\t{Lo: 0xfb46, Hi: 0xfbb1, Stride: 1},\n\t\t{Lo: 0xfbd3, Hi: 0xfd3d, Stride: 1},\n\t\t{Lo: 0xfd50, Hi: 0xfd8f, Stride: 1},\n\t\t{Lo: 0xfd92, Hi: 0xfdc7, Stride: 1},\n\t\t{Lo: 0xfdf0, Hi: 0xfdfb, Stride: 1},\n\t\t{Lo: 0xfe00, Hi: 0xfe0f, Stride: 1},\n\t\t{Lo: 0xfe20, Hi: 0xfe2f, Stride: 1},\n\t\t{Lo: 0xfe33, Hi: 0xfe34, Stride: 1},\n\t\t{Lo: 0xfe4d, Hi: 0xfe4f, Stride: 1},\n\t\t{Lo: 0xfe70, Hi: 0xfe74, Stride: 1},\n\t\t{Lo: 0xfe76, Hi: 0xfefc, Stride: 1},\n\t\t{Lo: 0xff10, Hi: 0xff19, Stride: 1},\n\t\t{Lo: 0xff21, Hi: 0xff3a, Stride: 1},\n\t\t{Lo: 0xff3f, Hi: 0xff3f, Stride: 1},\n\t\t{Lo: 0xff41, Hi: 0xff5a, Stride: 1},\n\t\t{Lo: 0xff65, Hi: 0xffbe, Stride: 1},\n\t\t{Lo: 0xffc2, Hi: 0xffc7, Stride: 1},\n\t\t{Lo: 0xffca, Hi: 0xffcf, Stride: 1},\n\t\t{Lo: 0xffd2, Hi: 0xffd7, Stride: 1},\n\t\t{Lo: 0xffda, Hi: 0xffdc, Stride: 1},\n\t\t{Lo: 0x10000, Hi: 0x1000b, Stride: 1},\n\t\t{Lo: 0x1000d, Hi: 0x10026, Stride: 1},\n\t\t{Lo: 0x10028, Hi: 0x1003a, Stride: 1},\n\t\t{Lo: 0x1003c, Hi: 0x1003d, Stride: 1},\n\t\t{Lo: 0x1003f, Hi: 0x1004d, Stride: 1},\n\t\t{Lo: 0x10050, Hi: 0x1005d, Stride: 1},\n\t\t{Lo: 0x10080, Hi: 0x100fa, Stride: 1},\n\t\t{Lo: 0x10140, Hi: 0x10174, Stride: 1},\n\t\t{Lo: 0x101fd, Hi: 0x101fd, Stride: 1},\n\t\t{Lo: 0x10280, Hi: 0x1029c, Stride: 1},\n\t\t{Lo: 0x102a0, Hi: 0x102d0, Stride: 1},\n\t\t{Lo: 0x102e0, Hi: 0x102e0, Stride: 1},\n\t\t{Lo: 0x10300, Hi: 0x1031f, Stride: 1},\n\t\t{Lo: 0x1032d, Hi: 0x1034a, Stride: 1},\n\t\t{Lo: 0x10350, Hi: 0x1037a, Stride: 1},\n\t\t{Lo: 0x10380, Hi: 0x1039d, Stride: 1},\n\t\t{Lo: 0x103a0, Hi: 0x103c3, Stride: 1},\n\t\t{Lo: 0x103c8, Hi: 0x103cf, Stride: 1},\n\t\t{Lo: 0x103d1, Hi: 0x103d5, Stride: 1},\n\t\t{Lo: 0x10400, Hi: 0x1049d, Stride: 1},\n\t\t{Lo: 0x104a0, Hi: 0x104a9, Stride: 1},\n\t\t{Lo: 0x104b0, Hi: 0x104d3, Stride: 1},\n\t\t{Lo: 0x104d8, Hi: 0x104fb, Stride: 1},\n\t\t{Lo: 0x10500, Hi: 0x10527, Stride: 1},\n\t\t{Lo: 0x10530, Hi: 0x10563, Stride: 1},\n\t\t{Lo: 0x10570, Hi: 0x1057a, Stride: 1},\n\t\t{Lo: 0x1057c, Hi: 0x1058a, Stride: 1},\n\t\t{Lo: 0x1058c, Hi: 0x10592, Stride: 1},\n\t\t{Lo: 0x10594, Hi: 0x10595, Stride: 1},\n\t\t{Lo: 0x10597, Hi: 0x105a1, Stride: 1},\n\t\t{Lo: 0x105a3, Hi: 0x105b1, Stride: 1},\n\t\t{Lo: 0x105b3, Hi: 0x105b9, Stride: 1},\n\t\t{Lo: 0x105bb, Hi: 0x105bc, Stride: 1},\n\t\t{Lo: 0x10600, Hi: 0x10736, Stride: 1},\n\t\t{Lo: 0x10740, Hi: 0x10755, Stride: 1},\n\t\t{Lo: 0x10760, Hi: 0x10767, Stride: 1},\n\t\t{Lo: 0x10780, Hi: 0x10785, Stride: 1},\n\t\t{Lo: 0x10787, Hi: 0x107b0, Stride: 1},\n\t\t{Lo: 0x107b2, Hi: 0x107ba, Stride: 1},\n\t\t{Lo: 0x10800, Hi: 0x10805, Stride: 1},\n\t\t{Lo: 0x10808, Hi: 0x10808, Stride: 1},\n\t\t{Lo: 0x1080a, Hi: 0x10835, Stride: 1},\n\t\t{Lo: 0x10837, Hi: 0x10838, Stride: 1},\n\t\t{Lo: 0x1083c, Hi: 0x1083c, Stride: 1},\n\t\t{Lo: 0x1083f, Hi: 0x10855, Stride: 1},\n\t\t{Lo: 0x10860, Hi: 0x10876, Stride: 1},\n\t\t{Lo: 0x10880, Hi: 0x1089e, Stride: 1},\n\t\t{Lo: 0x108e0, Hi: 0x108f2, Stride: 1},\n\t\t{Lo: 0x108f4, Hi: 0x108f5, Stride: 1},\n\t\t{Lo: 0x10900, Hi: 0x10915, Stride: 1},\n\t\t{Lo: 0x10920, Hi: 0x10939, Stride: 1},\n\t\t{Lo: 0x10980, Hi: 0x109b7, Stride: 1},\n\t\t{Lo: 0x109be, Hi: 0x109bf, Stride: 1},\n\t\t{Lo: 0x10a00, Hi: 0x10a03, Stride: 1},\n\t\t{Lo: 0x10a05, Hi: 0x10a06, Stride: 1},\n\t\t{Lo: 0x10a0c, Hi: 0x10a13, Stride: 1},\n\t\t{Lo: 0x10a15, Hi: 0x10a17, Stride: 1},\n\t\t{Lo: 0x10a19, Hi: 0x10a35, Stride: 1},\n\t\t{Lo: 0x10a38, Hi: 0x10a3a, Stride: 1},\n\t\t{Lo: 0x10a3f, Hi: 0x10a3f, Stride: 1},\n\t\t{Lo: 0x10a60, Hi: 0x10a7c, Stride: 1},\n\t\t{Lo: 0x10a80, Hi: 0x10a9c, Stride: 1},\n\t\t{Lo: 0x10ac0, Hi: 0x10ac7, Stride: 1},\n\t\t{Lo: 0x10ac9, Hi: 0x10ae6, Stride: 1},\n\t\t{Lo: 0x10b00, Hi: 0x10b35, Stride: 1},\n\t\t{Lo: 0x10b40, Hi: 0x10b55, Stride: 1},\n\t\t{Lo: 0x10b60, Hi: 0x10b72, Stride: 1},\n\t\t{Lo: 0x10b80, Hi: 0x10b91, Stride: 1},\n\t\t{Lo: 0x10c00, Hi: 0x10c48, Stride: 1},\n\t\t{Lo: 0x10c80, Hi: 0x10cb2, Stride: 1},\n\t\t{Lo: 0x10cc0, Hi: 0x10cf2, Stride: 1},\n\t\t{Lo: 0x10d00, Hi: 0x10d27, Stride: 1},\n\t\t{Lo: 0x10d30, Hi: 0x10d39, Stride: 1},\n\t\t{Lo: 0x10e80, Hi: 0x10ea9, Stride: 1},\n\t\t{Lo: 0x10eab, Hi: 0x10eac, Stride: 1},\n\t\t{Lo: 0x10eb0, Hi: 0x10eb1, Stride: 1},\n\t\t{Lo: 0x10efd, Hi: 0x10f1c, Stride: 1},\n\t\t{Lo: 0x10f27, Hi: 0x10f27, Stride: 1},\n\t\t{Lo: 0x10f30, Hi: 0x10f50, Stride: 1},\n\t\t{Lo: 0x10f70, Hi: 0x10f85, Stride: 1},\n\t\t{Lo: 0x10fb0, Hi: 0x10fc4, Stride: 1},\n\t\t{Lo: 0x10fe0, Hi: 0x10ff6, Stride: 1},\n\t\t{Lo: 0x11000, Hi: 0x11046, Stride: 1},\n\t\t{Lo: 0x11066, Hi: 0x11075, Stride: 1},\n\t\t{Lo: 0x1107f, Hi: 0x110ba, Stride: 1},\n\t\t{Lo: 0x110c2, Hi: 0x110c2, Stride: 1},\n\t\t{Lo: 0x110d0, Hi: 0x110e8, Stride: 1},\n\t\t{Lo: 0x110f0, Hi: 0x110f9, Stride: 1},\n\t\t{Lo: 0x11100, Hi: 0x11134, Stride: 1},\n\t\t{Lo: 0x11136, Hi: 0x1113f, Stride: 1},\n\t\t{Lo: 0x11144, Hi: 0x11147, Stride: 1},\n\t\t{Lo: 0x11150, Hi: 0x11173, Stride: 1},\n\t\t{Lo: 0x11176, Hi: 0x11176, Stride: 1},\n\t\t{Lo: 0x11180, Hi: 0x111c4, Stride: 1},\n\t\t{Lo: 0x111c9, Hi: 0x111cc, Stride: 1},\n\t\t{Lo: 0x111ce, Hi: 0x111da, Stride: 1},\n\t\t{Lo: 0x111dc, Hi: 0x111dc, Stride: 1},\n\t\t{Lo: 0x11200, Hi: 0x11211, Stride: 1},\n\t\t{Lo: 0x11213, Hi: 0x11237, Stride: 1},\n\t\t{Lo: 0x1123e, Hi: 0x11241, Stride: 1},\n\t\t{Lo: 0x11280, Hi: 0x11286, Stride: 1},\n\t\t{Lo: 0x11288, Hi: 0x11288, Stride: 1},\n\t\t{Lo: 0x1128a, Hi: 0x1128d, Stride: 1},\n\t\t{Lo: 0x1128f, Hi: 0x1129d, Stride: 1},\n\t\t{Lo: 0x1129f, Hi: 0x112a8, Stride: 1},\n\t\t{Lo: 0x112b0, Hi: 0x112ea, Stride: 1},\n\t\t{Lo: 0x112f0, Hi: 0x112f9, Stride: 1},\n\t\t{Lo: 0x11300, Hi: 0x11303, Stride: 1},\n\t\t{Lo: 0x11305, Hi: 0x1130c, Stride: 1},\n\t\t{Lo: 0x1130f, Hi: 0x11310, Stride: 1},\n\t\t{Lo: 0x11313, Hi: 0x11328, Stride: 1},\n\t\t{Lo: 0x1132a, Hi: 0x11330, Stride: 1},\n\t\t{Lo: 0x11332, Hi: 0x11333, Stride: 1},\n\t\t{Lo: 0x11335, Hi: 0x11339, Stride: 1},\n\t\t{Lo: 0x1133b, Hi: 0x11344, Stride: 1},\n\t\t{Lo: 0x11347, Hi: 0x11348, Stride: 1},\n\t\t{Lo: 0x1134b, Hi: 0x1134d, Stride: 1},\n\t\t{Lo: 0x11350, Hi: 0x11350, Stride: 1},\n\t\t{Lo: 0x11357, Hi: 0x11357, Stride: 1},\n\t\t{Lo: 0x1135d, Hi: 0x11363, Stride: 1},\n\t\t{Lo: 0x11366, Hi: 0x1136c, Stride: 1},\n\t\t{Lo: 0x11370, Hi: 0x11374, Stride: 1},\n\t\t{Lo: 0x11400, Hi: 0x1144a, Stride: 1},\n\t\t{Lo: 0x11450, Hi: 0x11459, Stride: 1},\n\t\t{Lo: 0x1145e, Hi: 0x11461, Stride: 1},\n\t\t{Lo: 0x11480, Hi: 0x114c5, Stride: 1},\n\t\t{Lo: 0x114c7, Hi: 0x114c7, Stride: 1},\n\t\t{Lo: 0x114d0, Hi: 0x114d9, Stride: 1},\n\t\t{Lo: 0x11580, Hi: 0x115b5, Stride: 1},\n\t\t{Lo: 0x115b8, Hi: 0x115c0, Stride: 1},\n\t\t{Lo: 0x115d8, Hi: 0x115dd, Stride: 1},\n\t\t{Lo: 0x11600, Hi: 0x11640, Stride: 1},\n\t\t{Lo: 0x11644, Hi: 0x11644, Stride: 1},\n\t\t{Lo: 0x11650, Hi: 0x11659, Stride: 1},\n\t\t{Lo: 0x11680, Hi: 0x116b8, Stride: 1},\n\t\t{Lo: 0x116c0, Hi: 0x116c9, Stride: 1},\n\t\t{Lo: 0x11700, Hi: 0x1171a, Stride: 1},\n\t\t{Lo: 0x1171d, Hi: 0x1172b, Stride: 1},\n\t\t{Lo: 0x11730, Hi: 0x11739, Stride: 1},\n\t\t{Lo: 0x11740, Hi: 0x11746, Stride: 1},\n\t\t{Lo: 0x11800, Hi: 0x1183a, Stride: 1},\n\t\t{Lo: 0x118a0, Hi: 0x118e9, Stride: 1},\n\t\t{Lo: 0x118ff, Hi: 0x11906, Stride: 1},\n\t\t{Lo: 0x11909, Hi: 0x11909, Stride: 1},\n\t\t{Lo: 0x1190c, Hi: 0x11913, Stride: 1},\n\t\t{Lo: 0x11915, Hi: 0x11916, Stride: 1},\n\t\t{Lo: 0x11918, Hi: 0x11935, Stride: 1},\n\t\t{Lo: 0x11937, Hi: 0x11938, Stride: 1},\n\t\t{Lo: 0x1193b, Hi: 0x11943, Stride: 1},\n\t\t{Lo: 0x11950, Hi: 0x11959, Stride: 1},\n\t\t{Lo: 0x119a0, Hi: 0x119a7, Stride: 1},\n\t\t{Lo: 0x119aa, Hi: 0x119d7, Stride: 1},\n\t\t{Lo: 0x119da, Hi: 0x119e1, Stride: 1},\n\t\t{Lo: 0x119e3, Hi: 0x119e4, Stride: 1},\n\t\t{Lo: 0x11a00, Hi: 0x11a3e, Stride: 1},\n\t\t{Lo: 0x11a47, Hi: 0x11a47, Stride: 1},\n\t\t{Lo: 0x11a50, Hi: 0x11a99, Stride: 1},\n\t\t{Lo: 0x11a9d, Hi: 0x11a9d, Stride: 1},\n\t\t{Lo: 0x11ab0, Hi: 0x11af8, Stride: 1},\n\t\t{Lo: 0x11c00, Hi: 0x11c08, Stride: 1},\n\t\t{Lo: 0x11c0a, Hi: 0x11c36, Stride: 1},\n\t\t{Lo: 0x11c38, Hi: 0x11c40, Stride: 1},\n\t\t{Lo: 0x11c50, Hi: 0x11c59, Stride: 1},\n\t\t{Lo: 0x11c72, Hi: 0x11c8f, Stride: 1},\n\t\t{Lo: 0x11c92, Hi: 0x11ca7, Stride: 1},\n\t\t{Lo: 0x11ca9, Hi: 0x11cb6, Stride: 1},\n\t\t{Lo: 0x11d00, Hi: 0x11d06, Stride: 1},\n\t\t{Lo: 0x11d08, Hi: 0x11d09, Stride: 1},\n\t\t{Lo: 0x11d0b, Hi: 0x11d36, Stride: 1},\n\t\t{Lo: 0x11d3a, Hi: 0x11d3a, Stride: 1},\n\t\t{Lo: 0x11d3c, Hi: 0x11d3d, Stride: 1},\n\t\t{Lo: 0x11d3f, Hi: 0x11d47, Stride: 1},\n\t\t{Lo: 0x11d50, Hi: 0x11d59, Stride: 1},\n\t\t{Lo: 0x11d60, Hi: 0x11d65, Stride: 1},\n\t\t{Lo: 0x11d67, Hi: 0x11d68, Stride: 1},\n\t\t{Lo: 0x11d6a, Hi: 0x11d8e, Stride: 1},\n\t\t{Lo: 0x11d90, Hi: 0x11d91, Stride: 1},\n\t\t{Lo: 0x11d93, Hi: 0x11d98, Stride: 1},\n\t\t{Lo: 0x11da0, Hi: 0x11da9, Stride: 1},\n\t\t{Lo: 0x11ee0, Hi: 0x11ef6, Stride: 1},\n\t\t{Lo: 0x11f00, Hi: 0x11f10, Stride: 1},\n\t\t{Lo: 0x11f12, Hi: 0x11f3a, Stride: 1},\n\t\t{Lo: 0x11f3e, Hi: 0x11f42, Stride: 1},\n\t\t{Lo: 0x11f50, Hi: 0x11f59, Stride: 1},\n\t\t{Lo: 0x11fb0, Hi: 0x11fb0, Stride: 1},\n\t\t{Lo: 0x12000, Hi: 0x12399, Stride: 1},\n\t\t{Lo: 0x12400, Hi: 0x1246e, Stride: 1},\n\t\t{Lo: 0x12480, Hi: 0x12543, Stride: 1},\n\t\t{Lo: 0x12f90, Hi: 0x12ff0, Stride: 1},\n\t\t{Lo: 0x13000, Hi: 0x1342f, Stride: 1},\n\t\t{Lo: 0x13440, Hi: 0x13455, Stride: 1},\n\t\t{Lo: 0x14400, Hi: 0x14646, Stride: 1},\n\t\t{Lo: 0x16800, Hi: 0x16a38, Stride: 1},\n\t\t{Lo: 0x16a40, Hi: 0x16a5e, Stride: 1},\n\t\t{Lo: 0x16a60, Hi: 0x16a69, Stride: 1},\n\t\t{Lo: 0x16a70, Hi: 0x16abe, Stride: 1},\n\t\t{Lo: 0x16ac0, Hi: 0x16ac9, Stride: 1},\n\t\t{Lo: 0x16ad0, Hi: 0x16aed, Stride: 1},\n\t\t{Lo: 0x16af0, Hi: 0x16af4, Stride: 1},\n\t\t{Lo: 0x16b00, Hi: 0x16b36, Stride: 1},\n\t\t{Lo: 0x16b40, Hi: 0x16b43, Stride: 1},\n\t\t{Lo: 0x16b50, Hi: 0x16b59, Stride: 1},\n\t\t{Lo: 0x16b63, Hi: 0x16b77, Stride: 1},\n\t\t{Lo: 0x16b7d, Hi: 0x16b8f, Stride: 1},\n\t\t{Lo: 0x16e40, Hi: 0x16e7f, Stride: 1},\n\t\t{Lo: 0x16f00, Hi: 0x16f4a, Stride: 1},\n\t\t{Lo: 0x16f4f, Hi: 0x16f87, Stride: 1},\n\t\t{Lo: 0x16f8f, Hi: 0x16f9f, Stride: 1},\n\t\t{Lo: 0x16fe0, Hi: 0x16fe1, Stride: 1},\n\t\t{Lo: 0x16fe3, Hi: 0x16fe4, Stride: 1},\n\t\t{Lo: 0x16ff0, Hi: 0x16ff1, Stride: 1},\n\t\t{Lo: 0x17000, Hi: 0x187f7, Stride: 1},\n\t\t{Lo: 0x18800, Hi: 0x18cd5, Stride: 1},\n\t\t{Lo: 0x18d00, Hi: 0x18d08, Stride: 1},\n\t\t{Lo: 0x1aff0, Hi: 0x1aff3, Stride: 1},\n\t\t{Lo: 0x1aff5, Hi: 0x1affb, Stride: 1},\n\t\t{Lo: 0x1affd, Hi: 0x1affe, Stride: 1},\n\t\t{Lo: 0x1b000, Hi: 0x1b122, Stride: 1},\n\t\t{Lo: 0x1b132, Hi: 0x1b132, Stride: 1},\n\t\t{Lo: 0x1b150, Hi: 0x1b152, Stride: 1},\n\t\t{Lo: 0x1b155, Hi: 0x1b155, Stride: 1},\n\t\t{Lo: 0x1b164, Hi: 0x1b167, Stride: 1},\n\t\t{Lo: 0x1b170, Hi: 0x1b2fb, Stride: 1},\n\t\t{Lo: 0x1bc00, Hi: 0x1bc6a, Stride: 1},\n\t\t{Lo: 0x1bc70, Hi: 0x1bc7c, Stride: 1},\n\t\t{Lo: 0x1bc80, Hi: 0x1bc88, Stride: 1},\n\t\t{Lo: 0x1bc90, Hi: 0x1bc99, Stride: 1},\n\t\t{Lo: 0x1bc9d, Hi: 0x1bc9e, Stride: 1},\n\t\t{Lo: 0x1cf00, Hi: 0x1cf2d, Stride: 1},\n\t\t{Lo: 0x1cf30, Hi: 0x1cf46, Stride: 1},\n\t\t{Lo: 0x1d165, Hi: 0x1d169, Stride: 1},\n\t\t{Lo: 0x1d16d, Hi: 0x1d172, Stride: 1},\n\t\t{Lo: 0x1d17b, Hi: 0x1d182, Stride: 1},\n\t\t{Lo: 0x1d185, Hi: 0x1d18b, Stride: 1},\n\t\t{Lo: 0x1d1aa, Hi: 0x1d1ad, Stride: 1},\n\t\t{Lo: 0x1d242, Hi: 0x1d244, Stride: 1},\n\t\t{Lo: 0x1d400, Hi: 0x1d454, Stride: 1},\n\t\t{Lo: 0x1d456, Hi: 0x1d49c, Stride: 1},\n\t\t{Lo: 0x1d49e, Hi: 0x1d49f, Stride: 1},\n\t\t{Lo: 0x1d4a2, Hi: 0x1d4a2, Stride: 1},\n\t\t{Lo: 0x1d4a5, Hi: 0x1d4a6, Stride: 1},\n\t\t{Lo: 0x1d4a9, Hi: 0x1d4ac, Stride: 1},\n\t\t{Lo: 0x1d4ae, Hi: 0x1d4b9, Stride: 1},\n\t\t{Lo: 0x1d4bb, Hi: 0x1d4bb, Stride: 1},\n\t\t{Lo: 0x1d4bd, Hi: 0x1d4c3, Stride: 1},\n\t\t{Lo: 0x1d4c5, Hi: 0x1d505, Stride: 1},\n\t\t{Lo: 0x1d507, Hi: 0x1d50a, Stride: 1},\n\t\t{Lo: 0x1d50d, Hi: 0x1d514, Stride: 1},\n\t\t{Lo: 0x1d516, Hi: 0x1d51c, Stride: 1},\n\t\t{Lo: 0x1d51e, Hi: 0x1d539, Stride: 1},\n\t\t{Lo: 0x1d53b, Hi: 0x1d53e, Stride: 1},\n\t\t{Lo: 0x1d540, Hi: 0x1d544, Stride: 1},\n\t\t{Lo: 0x1d546, Hi: 0x1d546, Stride: 1},\n\t\t{Lo: 0x1d54a, Hi: 0x1d550, Stride: 1},\n\t\t{Lo: 0x1d552, Hi: 0x1d6a5, Stride: 1},\n\t\t{Lo: 0x1d6a8, Hi: 0x1d6c0, Stride: 1},\n\t\t{Lo: 0x1d6c2, Hi: 0x1d6da, Stride: 1},\n\t\t{Lo: 0x1d6dc, Hi: 0x1d6fa, Stride: 1},\n\t\t{Lo: 0x1d6fc, Hi: 0x1d714, Stride: 1},\n\t\t{Lo: 0x1d716, Hi: 0x1d734, Stride: 1},\n\t\t{Lo: 0x1d736, Hi: 0x1d74e, Stride: 1},\n\t\t{Lo: 0x1d750, Hi: 0x1d76e, Stride: 1},\n\t\t{Lo: 0x1d770, Hi: 0x1d788, Stride: 1},\n\t\t{Lo: 0x1d78a, Hi: 0x1d7a8, Stride: 1},\n\t\t{Lo: 0x1d7aa, Hi: 0x1d7c2, Stride: 1},\n\t\t{Lo: 0x1d7c4, Hi: 0x1d7cb, Stride: 1},\n\t\t{Lo: 0x1d7ce, Hi: 0x1d7ff, Stride: 1},\n\t\t{Lo: 0x1da00, Hi: 0x1da36, Stride: 1},\n\t\t{Lo: 0x1da3b, Hi: 0x1da6c, Stride: 1},\n\t\t{Lo: 0x1da75, Hi: 0x1da75, Stride: 1},\n\t\t{Lo: 0x1da84, Hi: 0x1da84, Stride: 1},\n\t\t{Lo: 0x1da9b, Hi: 0x1da9f, Stride: 1},\n\t\t{Lo: 0x1daa1, Hi: 0x1daaf, Stride: 1},\n\t\t{Lo: 0x1df00, Hi: 0x1df1e, Stride: 1},\n\t\t{Lo: 0x1df25, Hi: 0x1df2a, Stride: 1},\n\t\t{Lo: 0x1e000, Hi: 0x1e006, Stride: 1},\n\t\t{Lo: 0x1e008, Hi: 0x1e018, Stride: 1},\n\t\t{Lo: 0x1e01b, Hi: 0x1e021, Stride: 1},\n\t\t{Lo: 0x1e023, Hi: 0x1e024, Stride: 1},\n\t\t{Lo: 0x1e026, Hi: 0x1e02a, Stride: 1},\n\t\t{Lo: 0x1e030, Hi: 0x1e06d, Stride: 1},\n\t\t{Lo: 0x1e08f, Hi: 0x1e08f, Stride: 1},\n\t\t{Lo: 0x1e100, Hi: 0x1e12c, Stride: 1},\n\t\t{Lo: 0x1e130, Hi: 0x1e13d, Stride: 1},\n\t\t{Lo: 0x1e140, Hi: 0x1e149, Stride: 1},\n\t\t{Lo: 0x1e14e, Hi: 0x1e14e, Stride: 1},\n\t\t{Lo: 0x1e290, Hi: 0x1e2ae, Stride: 1},\n\t\t{Lo: 0x1e2c0, Hi: 0x1e2f9, Stride: 1},\n\t\t{Lo: 0x1e4d0, Hi: 0x1e4f9, Stride: 1},\n\t\t{Lo: 0x1e7e0, Hi: 0x1e7e6, Stride: 1},\n\t\t{Lo: 0x1e7e8, Hi: 0x1e7eb, Stride: 1},\n\t\t{Lo: 0x1e7ed, Hi: 0x1e7ee, Stride: 1},\n\t\t{Lo: 0x1e7f0, Hi: 0x1e7fe, Stride: 1},\n\t\t{Lo: 0x1e800, Hi: 0x1e8c4, Stride: 1},\n\t\t{Lo: 0x1e8d0, Hi: 0x1e8d6, Stride: 1},\n\t\t{Lo: 0x1e900, Hi: 0x1e94b, Stride: 1},\n\t\t{Lo: 0x1e950, Hi: 0x1e959, Stride: 1},\n\t\t{Lo: 0x1ee00, Hi: 0x1ee03, Stride: 1},\n\t\t{Lo: 0x1ee05, Hi: 0x1ee1f, Stride: 1},\n\t\t{Lo: 0x1ee21, Hi: 0x1ee22, Stride: 1},\n\t\t{Lo: 0x1ee24, Hi: 0x1ee24, Stride: 1},\n\t\t{Lo: 0x1ee27, Hi: 0x1ee27, Stride: 1},\n\t\t{Lo: 0x1ee29, Hi: 0x1ee32, Stride: 1},\n\t\t{Lo: 0x1ee34, Hi: 0x1ee37, Stride: 1},\n\t\t{Lo: 0x1ee39, Hi: 0x1ee39, Stride: 1},\n\t\t{Lo: 0x1ee3b, Hi: 0x1ee3b, Stride: 1},\n\t\t{Lo: 0x1ee42, Hi: 0x1ee42, Stride: 1},\n\t\t{Lo: 0x1ee47, Hi: 0x1ee47, Stride: 1},\n\t\t{Lo: 0x1ee49, Hi: 0x1ee49, Stride: 1},\n\t\t{Lo: 0x1ee4b, Hi: 0x1ee4b, Stride: 1},\n\t\t{Lo: 0x1ee4d, Hi: 0x1ee4f, Stride: 1},\n\t\t{Lo: 0x1ee51, Hi: 0x1ee52, Stride: 1},\n\t\t{Lo: 0x1ee54, Hi: 0x1ee54, Stride: 1},\n\t\t{Lo: 0x1ee57, Hi: 0x1ee57, Stride: 1},\n\t\t{Lo: 0x1ee59, Hi: 0x1ee59, Stride: 1},\n\t\t{Lo: 0x1ee5b, Hi: 0x1ee5b, Stride: 1},\n\t\t{Lo: 0x1ee5d, Hi: 0x1ee5d, Stride: 1},\n\t\t{Lo: 0x1ee5f, Hi: 0x1ee5f, Stride: 1},\n\t\t{Lo: 0x1ee61, Hi: 0x1ee62, Stride: 1},\n\t\t{Lo: 0x1ee64, Hi: 0x1ee64, Stride: 1},\n\t\t{Lo: 0x1ee67, Hi: 0x1ee6a, Stride: 1},\n\t\t{Lo: 0x1ee6c, Hi: 0x1ee72, Stride: 1},\n\t\t{Lo: 0x1ee74, Hi: 0x1ee77, Stride: 1},\n\t\t{Lo: 0x1ee79, Hi: 0x1ee7c, Stride: 1},\n\t\t{Lo: 0x1ee7e, Hi: 0x1ee7e, Stride: 1},\n\t\t{Lo: 0x1ee80, Hi: 0x1ee89, Stride: 1},\n\t\t{Lo: 0x1ee8b, Hi: 0x1ee9b, Stride: 1},\n\t\t{Lo: 0x1eea1, Hi: 0x1eea3, Stride: 1},\n\t\t{Lo: 0x1eea5, Hi: 0x1eea9, Stride: 1},\n\t\t{Lo: 0x1eeab, Hi: 0x1eebb, Stride: 1},\n\t\t{Lo: 0x1fbf0, Hi: 0x1fbf9, Stride: 1},\n\t\t{Lo: 0x20000, Hi: 0x2a6df, Stride: 1},\n\t\t{Lo: 0x2a700, Hi: 0x2b739, Stride: 1},\n\t\t{Lo: 0x2b740, Hi: 0x2b81d, Stride: 1},\n\t\t{Lo: 0x2b820, Hi: 0x2cea1, Stride: 1},\n\t\t{Lo: 0x2ceb0, Hi: 0x2ebe0, Stride: 1},\n\t\t{Lo: 0x2ebf0, Hi: 0x2ee5d, Stride: 1},\n\t\t{Lo: 0x2f800, Hi: 0x2fa1d, Stride: 1},\n\t\t{Lo: 0x30000, Hi: 0x3134a, Stride: 1},\n\t\t{Lo: 0x31350, Hi: 0x323af, Stride: 1},\n\t\t{Lo: 0xe0100, Hi: 0xe01ef, Stride: 1},\n\t},\n}\n"
  },
  {
    "path": "internal/js_lexer/js_lexer.go",
    "content": "package js_lexer\n\n// The lexer converts a source file to a stream of tokens. Unlike many\n// compilers, esbuild does not run the lexer to completion before the parser is\n// started. Instead, the lexer is called repeatedly by the parser as the parser\n// parses the file. This is because many tokens are context-sensitive and need\n// high-level information from the parser. Examples are regular expression\n// literals and JSX elements.\n//\n// For efficiency, the text associated with textual tokens is stored in two\n// separate ways depending on the token. Identifiers use UTF-8 encoding which\n// allows them to be slices of the input file without allocating extra memory.\n// Strings use UTF-16 encoding so they can represent unicode surrogates\n// accurately.\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\ntype T uint8\n\n// If you add a new token, remember to add it to \"tokenToString\" too\nconst (\n\tTEndOfFile T = iota\n\tTSyntaxError\n\n\t// \"#!/usr/bin/env node\"\n\tTHashbang\n\n\t// Literals\n\tTNoSubstitutionTemplateLiteral // Contents are in lexer.StringLiteral ([]uint16)\n\tTNumericLiteral                // Contents are in lexer.Number (float64)\n\tTStringLiteral                 // Contents are in lexer.StringLiteral ([]uint16)\n\tTBigIntegerLiteral             // Contents are in lexer.Identifier (string)\n\n\t// Pseudo-literals\n\tTTemplateHead   // Contents are in lexer.StringLiteral ([]uint16)\n\tTTemplateMiddle // Contents are in lexer.StringLiteral ([]uint16)\n\tTTemplateTail   // Contents are in lexer.StringLiteral ([]uint16)\n\n\t// Punctuation\n\tTAmpersand\n\tTAmpersandAmpersand\n\tTAsterisk\n\tTAsteriskAsterisk\n\tTAt\n\tTBar\n\tTBarBar\n\tTCaret\n\tTCloseBrace\n\tTCloseBracket\n\tTCloseParen\n\tTColon\n\tTComma\n\tTDot\n\tTDotDotDot\n\tTEqualsEquals\n\tTEqualsEqualsEquals\n\tTEqualsGreaterThan\n\tTExclamation\n\tTExclamationEquals\n\tTExclamationEqualsEquals\n\tTGreaterThan\n\tTGreaterThanEquals\n\tTGreaterThanGreaterThan\n\tTGreaterThanGreaterThanGreaterThan\n\tTLessThan\n\tTLessThanEquals\n\tTLessThanLessThan\n\tTMinus\n\tTMinusMinus\n\tTOpenBrace\n\tTOpenBracket\n\tTOpenParen\n\tTPercent\n\tTPlus\n\tTPlusPlus\n\tTQuestion\n\tTQuestionDot\n\tTQuestionQuestion\n\tTSemicolon\n\tTSlash\n\tTTilde\n\n\t// Assignments (keep in sync with IsAssign() below)\n\tTAmpersandAmpersandEquals\n\tTAmpersandEquals\n\tTAsteriskAsteriskEquals\n\tTAsteriskEquals\n\tTBarBarEquals\n\tTBarEquals\n\tTCaretEquals\n\tTEquals\n\tTGreaterThanGreaterThanEquals\n\tTGreaterThanGreaterThanGreaterThanEquals\n\tTLessThanLessThanEquals\n\tTMinusEquals\n\tTPercentEquals\n\tTPlusEquals\n\tTQuestionQuestionEquals\n\tTSlashEquals\n\n\t// Class-private fields and methods\n\tTPrivateIdentifier\n\n\t// Identifiers\n\tTIdentifier     // Contents are in lexer.Identifier (string)\n\tTEscapedKeyword // A keyword that has been escaped as an identifier\n\n\t// Reserved words\n\tTBreak\n\tTCase\n\tTCatch\n\tTClass\n\tTConst\n\tTContinue\n\tTDebugger\n\tTDefault\n\tTDelete\n\tTDo\n\tTElse\n\tTEnum\n\tTExport\n\tTExtends\n\tTFalse\n\tTFinally\n\tTFor\n\tTFunction\n\tTIf\n\tTImport\n\tTIn\n\tTInstanceof\n\tTNew\n\tTNull\n\tTReturn\n\tTSuper\n\tTSwitch\n\tTThis\n\tTThrow\n\tTTrue\n\tTTry\n\tTTypeof\n\tTVar\n\tTVoid\n\tTWhile\n\tTWith\n)\n\nfunc (t T) IsAssign() bool {\n\treturn t >= TAmpersandAmpersandEquals && t <= TSlashEquals\n}\n\nvar Keywords = map[string]T{\n\t// Reserved words\n\t\"break\":      TBreak,\n\t\"case\":       TCase,\n\t\"catch\":      TCatch,\n\t\"class\":      TClass,\n\t\"const\":      TConst,\n\t\"continue\":   TContinue,\n\t\"debugger\":   TDebugger,\n\t\"default\":    TDefault,\n\t\"delete\":     TDelete,\n\t\"do\":         TDo,\n\t\"else\":       TElse,\n\t\"enum\":       TEnum,\n\t\"export\":     TExport,\n\t\"extends\":    TExtends,\n\t\"false\":      TFalse,\n\t\"finally\":    TFinally,\n\t\"for\":        TFor,\n\t\"function\":   TFunction,\n\t\"if\":         TIf,\n\t\"import\":     TImport,\n\t\"in\":         TIn,\n\t\"instanceof\": TInstanceof,\n\t\"new\":        TNew,\n\t\"null\":       TNull,\n\t\"return\":     TReturn,\n\t\"super\":      TSuper,\n\t\"switch\":     TSwitch,\n\t\"this\":       TThis,\n\t\"throw\":      TThrow,\n\t\"true\":       TTrue,\n\t\"try\":        TTry,\n\t\"typeof\":     TTypeof,\n\t\"var\":        TVar,\n\t\"void\":       TVoid,\n\t\"while\":      TWhile,\n\t\"with\":       TWith,\n}\n\nvar StrictModeReservedWords = map[string]bool{\n\t\"implements\": true,\n\t\"interface\":  true,\n\t\"let\":        true,\n\t\"package\":    true,\n\t\"private\":    true,\n\t\"protected\":  true,\n\t\"public\":     true,\n\t\"static\":     true,\n\t\"yield\":      true,\n}\n\n// This represents a string that is maybe a substring of the current file's\n// \"source.Contents\" string. The point of doing this is that if it is a\n// substring (the common case), then we can represent it more efficiently.\n//\n// For compactness and performance, the JS AST represents identifiers as a\n// symbol reference instead of as a string. However, we need to track the\n// string between the first pass and the second pass because the string is only\n// resolved to a symbol in the second pass. To avoid allocating extra memory\n// to store the string, we instead use an index+length slice of the original JS\n// source code. That index is what \"Start\" represents here. The length is just\n// \"len(String)\".\n//\n// Set \"Start\" to invalid (the zero value) if \"String\" is not a substring of\n// \"source.Contents\". This is the case for escaped identifiers. For example,\n// the identifier \"fo\\u006f\" would be \"MaybeSubstring{String: \"foo\"}\". It's\n// critical that any code changing the \"String\" also set \"Start\" to the zero\n// value, which is best done by just overwriting the whole \"MaybeSubstring\".\n//\n// The substring range used to be recovered automatically from the string but\n// that relied on the Go \"unsafe\" package which can hypothetically break under\n// certain Go compiler optimization passes, so it has been removed and replaced\n// with this more error-prone approach that doesn't use \"unsafe\".\ntype MaybeSubstring struct {\n\tString string\n\tStart  ast.Index32\n}\n\ntype Lexer struct {\n\tLegalCommentsBeforeToken     []logger.Range\n\tCommentsBeforeToken          []logger.Range\n\tAllComments                  []logger.Range\n\tIdentifier                   MaybeSubstring\n\tlog                          logger.Log\n\tsource                       logger.Source\n\tJSXFactoryPragmaComment      logger.Span\n\tJSXFragmentPragmaComment     logger.Span\n\tJSXRuntimePragmaComment      logger.Span\n\tJSXImportSourcePragmaComment logger.Span\n\tSourceMappingURL             logger.Span\n\tBadArrowInTSXSuggestion      string\n\n\t// Escape sequences in string literals are decoded lazily because they are\n\t// not interpreted inside tagged templates, and tagged templates can contain\n\t// invalid escape sequences. If the decoded array is nil, the encoded value\n\t// should be passed to \"tryToDecodeEscapeSequences\" first.\n\tdecodedStringLiteralOrNil []uint16\n\tencodedStringLiteralText  string\n\n\terrorSuffix string\n\ttracker     logger.LineColumnTracker\n\n\tencodedStringLiteralStart int\n\n\tNumber                          float64\n\tcurrent                         int\n\tstart                           int\n\tend                             int\n\tApproximateNewlineCount         int\n\tCouldBeBadArrowInTSX            int\n\tBadArrowInTSXRange              logger.Range\n\tLegacyOctalLoc                  logger.Loc\n\tAwaitKeywordLoc                 logger.Loc\n\tFnOrArrowStartLoc               logger.Loc\n\tPreviousBackslashQuoteInJSX     logger.Range\n\tLegacyHTMLCommentRange          logger.Range\n\tcodePoint                       rune\n\tprevErrorLoc                    logger.Loc\n\tjson                            JSONFlavor\n\tToken                           T\n\tts                              config.TSOptions\n\tHasNewlineBefore                bool\n\tHasCommentBefore                CommentBefore\n\tIsLegacyOctalLiteral            bool\n\tPrevTokenWasAwaitKeyword        bool\n\trescanCloseBraceAsTemplateToken bool\n\tforGlobalName                   bool\n\n\t// The log is disabled during speculative scans that may backtrack\n\tIsLogDisabled bool\n}\n\ntype CommentBefore uint8\n\nconst (\n\tPureCommentBefore CommentBefore = 1 << iota\n\tKeyCommentBefore\n\tNoSideEffectsCommentBefore\n)\n\ntype LexerPanic struct{}\n\nfunc NewLexer(log logger.Log, source logger.Source, ts config.TSOptions) Lexer {\n\tlexer := Lexer{\n\t\tlog:               log,\n\t\tsource:            source,\n\t\ttracker:           logger.MakeLineColumnTracker(&source),\n\t\tprevErrorLoc:      logger.Loc{Start: -1},\n\t\tFnOrArrowStartLoc: logger.Loc{Start: -1},\n\t\tts:                ts,\n\t\tjson:              NotJSON,\n\t}\n\tlexer.step()\n\tlexer.Next()\n\treturn lexer\n}\n\nfunc NewLexerGlobalName(log logger.Log, source logger.Source) Lexer {\n\tlexer := Lexer{\n\t\tlog:               log,\n\t\tsource:            source,\n\t\ttracker:           logger.MakeLineColumnTracker(&source),\n\t\tprevErrorLoc:      logger.Loc{Start: -1},\n\t\tFnOrArrowStartLoc: logger.Loc{Start: -1},\n\t\tforGlobalName:     true,\n\t\tjson:              NotJSON,\n\t}\n\tlexer.step()\n\tlexer.Next()\n\treturn lexer\n}\n\ntype JSONFlavor uint8\n\nconst (\n\t// Specification: https://json.org/\n\tJSON JSONFlavor = iota\n\n\t// TypeScript's JSON superset is not documented but appears to allow:\n\t// - Comments: https://github.com/microsoft/TypeScript/issues/4987\n\t// - Trailing commas\n\t// - Full JS number syntax\n\tTSConfigJSON\n\n\t// This is used by the JavaScript lexer\n\tNotJSON\n)\n\nfunc NewLexerJSON(log logger.Log, source logger.Source, json JSONFlavor, errorSuffix string) Lexer {\n\tlexer := Lexer{\n\t\tlog:               log,\n\t\tsource:            source,\n\t\ttracker:           logger.MakeLineColumnTracker(&source),\n\t\tprevErrorLoc:      logger.Loc{Start: -1},\n\t\tFnOrArrowStartLoc: logger.Loc{Start: -1},\n\t\terrorSuffix:       errorSuffix,\n\t\tjson:              json,\n\t}\n\tlexer.step()\n\tlexer.Next()\n\treturn lexer\n}\n\nfunc (lexer *Lexer) Loc() logger.Loc {\n\treturn logger.Loc{Start: int32(lexer.start)}\n}\n\nfunc (lexer *Lexer) Range() logger.Range {\n\treturn logger.Range{Loc: logger.Loc{Start: int32(lexer.start)}, Len: int32(lexer.end - lexer.start)}\n}\n\nfunc (lexer *Lexer) Raw() string {\n\treturn lexer.source.Contents[lexer.start:lexer.end]\n}\n\nfunc (lexer *Lexer) rawIdentifier() MaybeSubstring {\n\treturn MaybeSubstring{lexer.Raw(), ast.MakeIndex32(uint32(lexer.start))}\n}\n\nfunc (lexer *Lexer) StringLiteral() []uint16 {\n\tif lexer.decodedStringLiteralOrNil == nil {\n\t\t// Lazily decode escape sequences if needed\n\t\tif decoded, ok, end := lexer.tryToDecodeEscapeSequences(lexer.encodedStringLiteralStart, lexer.encodedStringLiteralText, true /* reportErrors */); !ok {\n\t\t\tlexer.end = end\n\t\t\tlexer.SyntaxError()\n\t\t} else {\n\t\t\tlexer.decodedStringLiteralOrNil = decoded\n\t\t}\n\t}\n\treturn lexer.decodedStringLiteralOrNil\n}\n\nfunc (lexer *Lexer) CookedAndRawTemplateContents() ([]uint16, string) {\n\tvar raw string\n\n\tswitch lexer.Token {\n\tcase TNoSubstitutionTemplateLiteral, TTemplateTail:\n\t\t// \"`x`\" or \"}x`\"\n\t\traw = lexer.source.Contents[lexer.start+1 : lexer.end-1]\n\n\tcase TTemplateHead, TTemplateMiddle:\n\t\t// \"`x${\" or \"}x${\"\n\t\traw = lexer.source.Contents[lexer.start+1 : lexer.end-2]\n\t}\n\n\tif strings.IndexByte(raw, '\\r') != -1 {\n\t\t// From the specification:\n\t\t//\n\t\t// 11.8.6.1 Static Semantics: TV and TRV\n\t\t//\n\t\t// TV excludes the code units of LineContinuation while TRV includes\n\t\t// them. <CR><LF> and <CR> LineTerminatorSequences are normalized to\n\t\t// <LF> for both TV and TRV. An explicit EscapeSequence is needed to\n\t\t// include a <CR> or <CR><LF> sequence.\n\n\t\tbytes := []byte(raw)\n\t\tend := 0\n\t\ti := 0\n\n\t\tfor i < len(bytes) {\n\t\t\tc := bytes[i]\n\t\t\ti++\n\n\t\t\tif c == '\\r' {\n\t\t\t\t// Convert '\\r\\n' into '\\n'\n\t\t\t\tif i < len(bytes) && bytes[i] == '\\n' {\n\t\t\t\t\ti++\n\t\t\t\t}\n\n\t\t\t\t// Convert '\\r' into '\\n'\n\t\t\t\tc = '\\n'\n\t\t\t}\n\n\t\t\tbytes[end] = c\n\t\t\tend++\n\t\t}\n\n\t\traw = string(bytes[:end])\n\t}\n\n\t// This will return nil on failure, which will become \"undefined\" for the tag\n\tcooked, _, _ := lexer.tryToDecodeEscapeSequences(lexer.start+1, raw, false /* reportErrors */)\n\treturn cooked, raw\n}\n\nfunc (lexer *Lexer) IsIdentifierOrKeyword() bool {\n\treturn lexer.Token >= TIdentifier\n}\n\nfunc (lexer *Lexer) IsContextualKeyword(text string) bool {\n\treturn lexer.Token == TIdentifier && lexer.Raw() == text\n}\n\nfunc (lexer *Lexer) ExpectContextualKeyword(text string) {\n\tif !lexer.IsContextualKeyword(text) {\n\t\tlexer.ExpectedString(fmt.Sprintf(\"%q\", text))\n\t}\n\tlexer.Next()\n}\n\nfunc (lexer *Lexer) SyntaxError() {\n\tloc := logger.Loc{Start: int32(lexer.end)}\n\tmessage := \"Unexpected end of file\"\n\tif lexer.end < len(lexer.source.Contents) {\n\t\tc, _ := utf8.DecodeRuneInString(lexer.source.Contents[lexer.end:])\n\t\tif c < 0x20 {\n\t\t\tmessage = fmt.Sprintf(\"Syntax error \\\"\\\\x%02X\\\"\", c)\n\t\t} else if c >= 0x80 {\n\t\t\tmessage = fmt.Sprintf(\"Syntax error \\\"\\\\u{%x}\\\"\", c)\n\t\t} else if c != '\"' {\n\t\t\tmessage = fmt.Sprintf(\"Syntax error \\\"%c\\\"\", c)\n\t\t} else {\n\t\t\tmessage = \"Syntax error '\\\"'\"\n\t\t}\n\t}\n\tlexer.addRangeError(logger.Range{Loc: loc}, message)\n\tpanic(LexerPanic{})\n}\n\nfunc (lexer *Lexer) ExpectedString(text string) {\n\t// Provide a friendly error message about \"await\" without \"async\"\n\tif lexer.PrevTokenWasAwaitKeyword {\n\t\tvar notes []logger.MsgData\n\t\tif lexer.FnOrArrowStartLoc.Start != -1 {\n\t\t\tnote := lexer.tracker.MsgData(logger.Range{Loc: lexer.FnOrArrowStartLoc},\n\t\t\t\t\"Consider adding the \\\"async\\\" keyword here:\")\n\t\t\tnote.Location.Suggestion = \"async\"\n\t\t\tnotes = []logger.MsgData{note}\n\t\t}\n\t\tlexer.AddRangeErrorWithNotes(RangeOfIdentifier(lexer.source, lexer.AwaitKeywordLoc),\n\t\t\t\"\\\"await\\\" can only be used inside an \\\"async\\\" function\",\n\t\t\tnotes)\n\t\tpanic(LexerPanic{})\n\t}\n\n\tfound := fmt.Sprintf(\"%q\", lexer.Raw())\n\tif lexer.start == len(lexer.source.Contents) {\n\t\tfound = \"end of file\"\n\t}\n\n\tsuggestion := \"\"\n\tif strings.HasPrefix(text, \"\\\"\") && strings.HasSuffix(text, \"\\\"\") {\n\t\tsuggestion = text[1 : len(text)-1]\n\t}\n\n\tlexer.addRangeErrorWithSuggestion(lexer.Range(), fmt.Sprintf(\"Expected %s%s but found %s\", text, lexer.errorSuffix, found), suggestion)\n\tpanic(LexerPanic{})\n}\n\nfunc (lexer *Lexer) Expected(token T) {\n\tif text, ok := tokenToString[token]; ok {\n\t\tlexer.ExpectedString(text)\n\t} else {\n\t\tlexer.Unexpected()\n\t}\n}\n\nfunc (lexer *Lexer) Unexpected() {\n\tfound := fmt.Sprintf(\"%q\", lexer.Raw())\n\tif lexer.start == len(lexer.source.Contents) {\n\t\tfound = \"end of file\"\n\t}\n\tlexer.addRangeError(lexer.Range(), fmt.Sprintf(\"Unexpected %s%s\", found, lexer.errorSuffix))\n\tpanic(LexerPanic{})\n}\n\nfunc (lexer *Lexer) Expect(token T) {\n\tif lexer.Token != token {\n\t\tlexer.Expected(token)\n\t}\n\tlexer.Next()\n}\n\nfunc (lexer *Lexer) ExpectOrInsertSemicolon() {\n\tif lexer.Token == TSemicolon || (!lexer.HasNewlineBefore &&\n\t\tlexer.Token != TCloseBrace && lexer.Token != TEndOfFile) {\n\t\tlexer.Expect(TSemicolon)\n\t}\n}\n\n// This parses a single \"<\" token. If that is the first part of a longer token,\n// this function splits off the first \"<\" and leaves the remainder of the\n// current token as another, smaller token. For example, \"<<=\" becomes \"<=\".\nfunc (lexer *Lexer) ExpectLessThan(isInsideJSXElement bool) {\n\tswitch lexer.Token {\n\tcase TLessThan:\n\t\tif isInsideJSXElement {\n\t\t\tlexer.NextInsideJSXElement()\n\t\t} else {\n\t\t\tlexer.Next()\n\t\t}\n\n\tcase TLessThanEquals:\n\t\tlexer.Token = TEquals\n\t\tlexer.start++\n\t\tlexer.maybeExpandEquals()\n\n\tcase TLessThanLessThan:\n\t\tlexer.Token = TLessThan\n\t\tlexer.start++\n\n\tcase TLessThanLessThanEquals:\n\t\tlexer.Token = TLessThanEquals\n\t\tlexer.start++\n\n\tdefault:\n\t\tlexer.Expected(TLessThan)\n\t}\n}\n\n// This parses a single \">\" token. If that is the first part of a longer token,\n// this function splits off the first \">\" and leaves the remainder of the\n// current token as another, smaller token. For example, \">>=\" becomes \">=\".\nfunc (lexer *Lexer) ExpectGreaterThan(isInsideJSXElement bool) {\n\tswitch lexer.Token {\n\tcase TGreaterThan:\n\t\tif isInsideJSXElement {\n\t\t\tlexer.NextInsideJSXElement()\n\t\t} else {\n\t\t\tlexer.Next()\n\t\t}\n\n\tcase TGreaterThanEquals:\n\t\tlexer.Token = TEquals\n\t\tlexer.start++\n\t\tlexer.maybeExpandEquals()\n\n\tcase TGreaterThanGreaterThan:\n\t\tlexer.Token = TGreaterThan\n\t\tlexer.start++\n\n\tcase TGreaterThanGreaterThanEquals:\n\t\tlexer.Token = TGreaterThanEquals\n\t\tlexer.start++\n\n\tcase TGreaterThanGreaterThanGreaterThan:\n\t\tlexer.Token = TGreaterThanGreaterThan\n\t\tlexer.start++\n\n\tcase TGreaterThanGreaterThanGreaterThanEquals:\n\t\tlexer.Token = TGreaterThanGreaterThanEquals\n\t\tlexer.start++\n\n\tdefault:\n\t\tlexer.Expected(TGreaterThan)\n\t}\n}\n\nfunc (lexer *Lexer) maybeExpandEquals() {\n\tswitch lexer.codePoint {\n\tcase '>':\n\t\t// \"=\" + \">\" = \"=>\"\n\t\tlexer.Token = TEqualsGreaterThan\n\t\tlexer.step()\n\n\tcase '=':\n\t\t// \"=\" + \"=\" = \"==\"\n\t\tlexer.Token = TEqualsEquals\n\t\tlexer.step()\n\n\t\tif lexer.Token == '=' {\n\t\t\t// \"=\" + \"==\" = \"===\"\n\t\t\tlexer.Token = TEqualsEqualsEquals\n\t\t\tlexer.step()\n\t\t}\n\t}\n}\n\nfunc RangeOfIdentifier(source logger.Source, loc logger.Loc) logger.Range {\n\ttext := source.Contents[loc.Start:]\n\tif len(text) == 0 {\n\t\treturn logger.Range{Loc: loc, Len: 0}\n\t}\n\n\ti := 0\n\tc, _ := utf8.DecodeRuneInString(text[i:])\n\n\t// Handle private names\n\tif c == '#' {\n\t\ti++\n\t\tc, _ = utf8.DecodeRuneInString(text[i:])\n\t}\n\n\tif js_ast.IsIdentifierStart(c) || c == '\\\\' {\n\t\t// Search for the end of the identifier\n\t\tfor i < len(text) {\n\t\t\tc2, width2 := utf8.DecodeRuneInString(text[i:])\n\t\t\tif c2 == '\\\\' {\n\t\t\t\ti += width2\n\n\t\t\t\t// Skip over bracketed unicode escapes such as \"\\u{10000}\"\n\t\t\t\tif i+2 < len(text) && text[i] == 'u' && text[i+1] == '{' {\n\t\t\t\t\ti += 2\n\t\t\t\t\tfor i < len(text) {\n\t\t\t\t\t\tif text[i] == '}' {\n\t\t\t\t\t\t\ti++\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\ti++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if !js_ast.IsIdentifierContinue(c2) {\n\t\t\t\treturn logger.Range{Loc: loc, Len: int32(i)}\n\t\t\t} else {\n\t\t\t\ti += width2\n\t\t\t}\n\t\t}\n\t}\n\n\t// When minifying, this identifier may have originally been a string\n\treturn source.RangeOfString(loc)\n}\n\ntype KeyOrValue uint8\n\nconst (\n\tKeyRange KeyOrValue = iota\n\tValueRange\n\tKeyAndValueRange\n)\n\nfunc RangeOfImportAssertOrWith(source logger.Source, assertOrWith ast.AssertOrWithEntry, which KeyOrValue) logger.Range {\n\tif which == KeyRange {\n\t\treturn RangeOfIdentifier(source, assertOrWith.KeyLoc)\n\t}\n\tif which == ValueRange {\n\t\treturn source.RangeOfString(assertOrWith.ValueLoc)\n\t}\n\tloc := RangeOfIdentifier(source, assertOrWith.KeyLoc).Loc\n\treturn logger.Range{Loc: loc, Len: source.RangeOfString(assertOrWith.ValueLoc).End() - loc.Start}\n}\n\nfunc (lexer *Lexer) ExpectJSXElementChild(token T) {\n\tif lexer.Token != token {\n\t\tlexer.Expected(token)\n\t}\n\tlexer.NextJSXElementChild()\n}\n\nfunc (lexer *Lexer) NextJSXElementChild() {\n\tlexer.HasNewlineBefore = false\n\toriginalStart := lexer.end\n\n\tfor {\n\t\tlexer.start = lexer.end\n\t\tlexer.Token = 0\n\n\t\tswitch lexer.codePoint {\n\t\tcase -1: // This indicates the end of the file\n\t\t\tlexer.Token = TEndOfFile\n\n\t\tcase '{':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TOpenBrace\n\n\t\tcase '<':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TLessThan\n\n\t\tdefault:\n\t\t\tneedsFixing := false\n\n\t\tstringLiteral:\n\t\t\tfor {\n\t\t\t\tswitch lexer.codePoint {\n\t\t\t\tcase -1, '{', '<':\n\t\t\t\t\t// Stop when the string ends\n\t\t\t\t\tbreak stringLiteral\n\n\t\t\t\tcase '&', '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t\t\t// This needs fixing if it has an entity or if it's a multi-line string\n\t\t\t\t\tneedsFixing = true\n\t\t\t\t\tlexer.step()\n\n\t\t\t\tcase '}', '>':\n\t\t\t\t\t// These technically aren't valid JSX: https://facebook.github.io/jsx/\n\t\t\t\t\t//\n\t\t\t\t\t//   JSXTextCharacter :\n\t\t\t\t\t//     * SourceCharacter but not one of {, <, > or }\n\t\t\t\t\t//\n\t\t\t\t\tvar replacement string\n\t\t\t\t\tif lexer.codePoint == '}' {\n\t\t\t\t\t\treplacement = \"{'}'}\"\n\t\t\t\t\t} else {\n\t\t\t\t\t\treplacement = \"{'>'}\"\n\t\t\t\t\t}\n\t\t\t\t\tmsg := logger.Msg{\n\t\t\t\t\t\tKind: logger.Error,\n\t\t\t\t\t\tData: lexer.tracker.MsgData(logger.Range{Loc: logger.Loc{Start: int32(lexer.end)}, Len: 1},\n\t\t\t\t\t\t\tfmt.Sprintf(\"The character \\\"%c\\\" is not valid inside a JSX element\", lexer.codePoint)),\n\t\t\t\t\t}\n\n\t\t\t\t\t// Attempt to provide a better error message if this looks like an arrow function\n\t\t\t\t\tif lexer.CouldBeBadArrowInTSX > 0 && lexer.codePoint == '>' && lexer.source.Contents[lexer.end-1] == '=' {\n\t\t\t\t\t\tmsg.Notes = []logger.MsgData{lexer.tracker.MsgData(lexer.BadArrowInTSXRange,\n\t\t\t\t\t\t\t\"TypeScript's TSX syntax interprets arrow functions with a single generic type parameter as an opening JSX element. \"+\n\t\t\t\t\t\t\t\t\"If you want it to be interpreted as an arrow function instead, you need to add a trailing comma after the type parameter to disambiguate:\")}\n\t\t\t\t\t\tmsg.Notes[0].Location.Suggestion = lexer.BadArrowInTSXSuggestion\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmsg.Notes = []logger.MsgData{{Text: fmt.Sprintf(\"Did you mean to escape it as %q instead?\", replacement)}}\n\t\t\t\t\t\tmsg.Data.Location.Suggestion = replacement\n\t\t\t\t\t\tif !lexer.ts.Parse {\n\t\t\t\t\t\t\t// TypeScript treats this as an error but Babel doesn't treat this\n\t\t\t\t\t\t\t// as an error yet, so allow this in JS for now. Babel version 8\n\t\t\t\t\t\t\t// was supposed to be released in 2021 but was never released. If\n\t\t\t\t\t\t\t// it's released in the future, this can be changed to an error too.\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// More context:\n\t\t\t\t\t\t\t// * TypeScript change: https://github.com/microsoft/TypeScript/issues/36341\n\t\t\t\t\t\t\t// * Babel 8 change: https://github.com/babel/babel/issues/11042\n\t\t\t\t\t\t\t// * Babel 8 release: https://github.com/babel/babel/issues/10746\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\tmsg.Kind = logger.Warning\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tlexer.log.AddMsg(msg)\n\t\t\t\t\tlexer.step()\n\n\t\t\t\tdefault:\n\t\t\t\t\t// Non-ASCII strings need the slow path\n\t\t\t\t\tif lexer.codePoint >= 0x80 {\n\t\t\t\t\t\tneedsFixing = true\n\t\t\t\t\t}\n\t\t\t\t\tlexer.step()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlexer.Token = TStringLiteral\n\t\t\ttext := lexer.source.Contents[originalStart:lexer.end]\n\n\t\t\tif needsFixing {\n\t\t\t\t// Slow path\n\t\t\t\tlexer.decodedStringLiteralOrNil = fixWhitespaceAndDecodeJSXEntities(text)\n\t\t\t} else {\n\t\t\t\t// Fast path\n\t\t\t\tn := len(text)\n\t\t\t\tcopy := make([]uint16, n)\n\t\t\t\tfor i := 0; i < n; i++ {\n\t\t\t\t\tcopy[i] = uint16(text[i])\n\t\t\t\t}\n\t\t\t\tlexer.decodedStringLiteralOrNil = copy\n\t\t\t}\n\t\t}\n\n\t\tbreak\n\t}\n}\n\nfunc (lexer *Lexer) ExpectInsideJSXElement(token T) {\n\tif lexer.Token != token {\n\t\tlexer.Expected(token)\n\t}\n\tlexer.NextInsideJSXElement()\n}\n\nfunc (lexer *Lexer) NextInsideJSXElement() {\n\tlexer.HasNewlineBefore = false\n\n\tfor {\n\t\tlexer.start = lexer.end\n\t\tlexer.Token = 0\n\n\t\tswitch lexer.codePoint {\n\t\tcase -1: // This indicates the end of the file\n\t\t\tlexer.Token = TEndOfFile\n\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\tlexer.step()\n\t\t\tlexer.HasNewlineBefore = true\n\t\t\tcontinue\n\n\t\tcase '\\t', ' ':\n\t\t\tlexer.step()\n\t\t\tcontinue\n\n\t\tcase '.':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TDot\n\n\t\tcase ':':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TColon\n\n\t\tcase '=':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TEquals\n\n\t\tcase '{':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TOpenBrace\n\n\t\tcase '}':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TCloseBrace\n\n\t\tcase '<':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TLessThan\n\n\t\tcase '>':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TGreaterThan\n\n\t\tcase '/':\n\t\t\t// '/' or '//' or '/* ... */'\n\t\t\tlexer.step()\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '/':\n\t\t\tsingleLineComment:\n\t\t\t\tfor {\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tswitch lexer.codePoint {\n\t\t\t\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t\t\t\tbreak singleLineComment\n\n\t\t\t\t\tcase -1: // This indicates the end of the file\n\t\t\t\t\t\tbreak singleLineComment\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue\n\n\t\t\tcase '*':\n\t\t\t\tlexer.step()\n\t\t\t\tstartRange := lexer.Range()\n\t\t\tmultiLineComment:\n\t\t\t\tfor {\n\t\t\t\t\tswitch lexer.codePoint {\n\t\t\t\t\tcase '*':\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t\tif lexer.codePoint == '/' {\n\t\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t\t\tbreak multiLineComment\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t\tlexer.HasNewlineBefore = true\n\n\t\t\t\t\tcase -1: // This indicates the end of the file\n\t\t\t\t\t\tlexer.start = lexer.end\n\t\t\t\t\t\tlexer.AddRangeErrorWithNotes(logger.Range{Loc: lexer.Loc()}, \"Expected \\\"*/\\\" to terminate multi-line comment\",\n\t\t\t\t\t\t\t[]logger.MsgData{lexer.tracker.MsgData(startRange, \"The multi-line comment starts here:\")})\n\t\t\t\t\t\tpanic(LexerPanic{})\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue\n\n\t\t\tdefault:\n\t\t\t\tlexer.Token = TSlash\n\t\t\t}\n\n\t\tcase '\\'', '\"':\n\t\t\tvar backslash logger.Range\n\t\t\tquote := lexer.codePoint\n\t\t\tneedsDecode := false\n\t\t\tlexer.step()\n\n\t\tstringLiteral:\n\t\t\tfor {\n\t\t\t\tswitch lexer.codePoint {\n\t\t\t\tcase -1: // This indicates the end of the file\n\t\t\t\t\tlexer.SyntaxError()\n\n\t\t\t\tcase '&':\n\t\t\t\t\tneedsDecode = true\n\t\t\t\t\tlexer.step()\n\n\t\t\t\tcase '\\\\':\n\t\t\t\t\tbackslash = logger.Range{Loc: logger.Loc{Start: int32(lexer.end)}, Len: 1}\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tcontinue\n\n\t\t\t\tcase quote:\n\t\t\t\t\tif backslash.Len > 0 {\n\t\t\t\t\t\tbackslash.Len++\n\t\t\t\t\t\tlexer.PreviousBackslashQuoteInJSX = backslash\n\t\t\t\t\t}\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tbreak stringLiteral\n\n\t\t\t\tdefault:\n\t\t\t\t\t// Non-ASCII strings need the slow path\n\t\t\t\t\tif lexer.codePoint >= 0x80 {\n\t\t\t\t\t\tneedsDecode = true\n\t\t\t\t\t}\n\t\t\t\t\tlexer.step()\n\t\t\t\t}\n\t\t\t\tbackslash = logger.Range{}\n\t\t\t}\n\n\t\t\tlexer.Token = TStringLiteral\n\t\t\ttext := lexer.source.Contents[lexer.start+1 : lexer.end-1]\n\n\t\t\tif needsDecode {\n\t\t\t\t// Slow path\n\t\t\t\tlexer.decodedStringLiteralOrNil = decodeJSXEntities([]uint16{}, text)\n\t\t\t} else {\n\t\t\t\t// Fast path\n\t\t\t\tn := len(text)\n\t\t\t\tcopy := make([]uint16, n)\n\t\t\t\tfor i := 0; i < n; i++ {\n\t\t\t\t\tcopy[i] = uint16(text[i])\n\t\t\t\t}\n\t\t\t\tlexer.decodedStringLiteralOrNil = copy\n\t\t\t}\n\n\t\tdefault:\n\t\t\t// Check for unusual whitespace characters\n\t\t\tif js_ast.IsWhitespace(lexer.codePoint) {\n\t\t\t\tlexer.step()\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif js_ast.IsIdentifierStart(lexer.codePoint) {\n\t\t\t\tlexer.step()\n\t\t\t\tfor js_ast.IsIdentifierContinue(lexer.codePoint) || lexer.codePoint == '-' {\n\t\t\t\t\tlexer.step()\n\t\t\t\t}\n\n\t\t\t\tlexer.Identifier = lexer.rawIdentifier()\n\t\t\t\tlexer.Token = TIdentifier\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tlexer.end = lexer.current\n\t\t\tlexer.Token = TSyntaxError\n\t\t}\n\n\t\treturn\n\t}\n}\n\nfunc (lexer *Lexer) Next() {\n\tlexer.HasNewlineBefore = lexer.end == 0\n\tlexer.HasCommentBefore = 0\n\tlexer.PrevTokenWasAwaitKeyword = false\n\tlexer.LegalCommentsBeforeToken = lexer.LegalCommentsBeforeToken[:0]\n\tlexer.CommentsBeforeToken = lexer.CommentsBeforeToken[:0]\n\n\tfor {\n\t\tlexer.start = lexer.end\n\t\tlexer.Token = 0\n\n\t\tswitch lexer.codePoint {\n\t\tcase -1: // This indicates the end of the file\n\t\t\tlexer.Token = TEndOfFile\n\n\t\tcase '#':\n\t\t\tif lexer.start == 0 && strings.HasPrefix(lexer.source.Contents, \"#!\") {\n\t\t\t\t// \"#!/usr/bin/env node\"\n\t\t\t\tlexer.Token = THashbang\n\t\t\thashbang:\n\t\t\t\tfor {\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tswitch lexer.codePoint {\n\t\t\t\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t\t\t\tbreak hashbang\n\n\t\t\t\t\tcase -1: // This indicates the end of the file\n\t\t\t\t\t\tbreak hashbang\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlexer.Identifier = lexer.rawIdentifier()\n\t\t\t} else {\n\t\t\t\t// \"#foo\"\n\t\t\t\tlexer.step()\n\t\t\t\tif lexer.codePoint == '\\\\' {\n\t\t\t\t\tlexer.Identifier, _ = lexer.scanIdentifierWithEscapes(privateIdentifier)\n\t\t\t\t} else {\n\t\t\t\t\tif !js_ast.IsIdentifierStart(lexer.codePoint) {\n\t\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t\t}\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tfor js_ast.IsIdentifierContinue(lexer.codePoint) {\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t}\n\t\t\t\t\tif lexer.codePoint == '\\\\' {\n\t\t\t\t\t\tlexer.Identifier, _ = lexer.scanIdentifierWithEscapes(privateIdentifier)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlexer.Identifier = lexer.rawIdentifier()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlexer.Token = TPrivateIdentifier\n\t\t\t}\n\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\tlexer.step()\n\t\t\tlexer.HasNewlineBefore = true\n\t\t\tcontinue\n\n\t\tcase '\\t', ' ':\n\t\t\tlexer.step()\n\t\t\tcontinue\n\n\t\tcase '(':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TOpenParen\n\n\t\tcase ')':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TCloseParen\n\n\t\tcase '[':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TOpenBracket\n\n\t\tcase ']':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TCloseBracket\n\n\t\tcase '{':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TOpenBrace\n\n\t\tcase '}':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TCloseBrace\n\n\t\tcase ',':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TComma\n\n\t\tcase ':':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TColon\n\n\t\tcase ';':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TSemicolon\n\n\t\tcase '@':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TAt\n\n\t\tcase '~':\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TTilde\n\n\t\tcase '?':\n\t\t\t// '?' or '?.' or '??' or '??='\n\t\t\tlexer.step()\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '?':\n\t\t\t\tlexer.step()\n\t\t\t\tswitch lexer.codePoint {\n\t\t\t\tcase '=':\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.Token = TQuestionQuestionEquals\n\t\t\t\tdefault:\n\t\t\t\t\tlexer.Token = TQuestionQuestion\n\t\t\t\t}\n\t\t\tcase '.':\n\t\t\t\tlexer.Token = TQuestion\n\t\t\t\tcurrent := lexer.current\n\t\t\t\tcontents := lexer.source.Contents\n\n\t\t\t\t// Lookahead to disambiguate with 'a?.1:b'\n\t\t\t\tif current < len(contents) {\n\t\t\t\t\tc := contents[current]\n\t\t\t\t\tif c < '0' || c > '9' {\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t\tlexer.Token = TQuestionDot\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tlexer.Token = TQuestion\n\t\t\t}\n\n\t\tcase '%':\n\t\t\t// '%' or '%='\n\t\t\tlexer.step()\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '=':\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token = TPercentEquals\n\t\t\tdefault:\n\t\t\t\tlexer.Token = TPercent\n\t\t\t}\n\n\t\tcase '&':\n\t\t\t// '&' or '&=' or '&&' or '&&='\n\t\t\tlexer.step()\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '=':\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token = TAmpersandEquals\n\t\t\tcase '&':\n\t\t\t\tlexer.step()\n\t\t\t\tswitch lexer.codePoint {\n\t\t\t\tcase '=':\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.Token = TAmpersandAmpersandEquals\n\t\t\t\tdefault:\n\t\t\t\t\tlexer.Token = TAmpersandAmpersand\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tlexer.Token = TAmpersand\n\t\t\t}\n\n\t\tcase '|':\n\t\t\t// '|' or '|=' or '||' or '||='\n\t\t\tlexer.step()\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '=':\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token = TBarEquals\n\t\t\tcase '|':\n\t\t\t\tlexer.step()\n\t\t\t\tswitch lexer.codePoint {\n\t\t\t\tcase '=':\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.Token = TBarBarEquals\n\t\t\t\tdefault:\n\t\t\t\t\tlexer.Token = TBarBar\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tlexer.Token = TBar\n\t\t\t}\n\n\t\tcase '^':\n\t\t\t// '^' or '^='\n\t\t\tlexer.step()\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '=':\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token = TCaretEquals\n\t\t\tdefault:\n\t\t\t\tlexer.Token = TCaret\n\t\t\t}\n\n\t\tcase '+':\n\t\t\t// '+' or '+=' or '++'\n\t\t\tlexer.step()\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '=':\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token = TPlusEquals\n\t\t\tcase '+':\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token = TPlusPlus\n\t\t\tdefault:\n\t\t\t\tlexer.Token = TPlus\n\t\t\t}\n\n\t\tcase '-':\n\t\t\t// '-' or '-=' or '--' or '-->'\n\t\t\tlexer.step()\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '=':\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token = TMinusEquals\n\t\t\tcase '-':\n\t\t\t\tlexer.step()\n\n\t\t\t\t// Handle legacy HTML-style comments\n\t\t\t\tif lexer.codePoint == '>' && lexer.HasNewlineBefore {\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.LegacyHTMLCommentRange = lexer.Range()\n\t\t\t\t\tlexer.log.AddID(logger.MsgID_JS_HTMLCommentInJS, logger.Warning, &lexer.tracker, lexer.Range(),\n\t\t\t\t\t\t\"Treating \\\"-->\\\" as the start of a legacy HTML single-line comment\")\n\t\t\t\tsingleLineHTMLCloseComment:\n\t\t\t\t\tfor {\n\t\t\t\t\t\tswitch lexer.codePoint {\n\t\t\t\t\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t\t\t\t\tbreak singleLineHTMLCloseComment\n\n\t\t\t\t\t\tcase -1: // This indicates the end of the file\n\t\t\t\t\t\t\tbreak singleLineHTMLCloseComment\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tlexer.Token = TMinusMinus\n\t\t\tdefault:\n\t\t\t\tlexer.Token = TMinus\n\t\t\t\tif lexer.json == JSON && lexer.codePoint != '.' && (lexer.codePoint < '0' || lexer.codePoint > '9') {\n\t\t\t\t\tlexer.Unexpected()\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase '*':\n\t\t\t// '*' or '*=' or '**' or '**='\n\t\t\tlexer.step()\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '=':\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token = TAsteriskEquals\n\n\t\t\tcase '*':\n\t\t\t\tlexer.step()\n\t\t\t\tswitch lexer.codePoint {\n\t\t\t\tcase '=':\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.Token = TAsteriskAsteriskEquals\n\n\t\t\t\tdefault:\n\t\t\t\t\tlexer.Token = TAsteriskAsterisk\n\t\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tlexer.Token = TAsterisk\n\t\t\t}\n\n\t\tcase '/':\n\t\t\t// '/' or '/=' or '//' or '/* ... */'\n\t\t\tlexer.step()\n\t\t\tif lexer.forGlobalName {\n\t\t\t\tlexer.Token = TSlash\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '=':\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token = TSlashEquals\n\n\t\t\tcase '/':\n\t\t\tsingleLineComment:\n\t\t\t\tfor {\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tswitch lexer.codePoint {\n\t\t\t\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t\t\t\tbreak singleLineComment\n\n\t\t\t\t\tcase -1: // This indicates the end of the file\n\t\t\t\t\t\tbreak singleLineComment\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif lexer.json == JSON {\n\t\t\t\t\tlexer.addRangeError(lexer.Range(), \"JSON does not support comments\")\n\t\t\t\t}\n\t\t\t\tlexer.scanCommentText()\n\t\t\t\tcontinue\n\n\t\t\tcase '*':\n\t\t\t\tlexer.step()\n\t\t\t\tstartRange := lexer.Range()\n\t\t\tmultiLineComment:\n\t\t\t\tfor {\n\t\t\t\t\tswitch lexer.codePoint {\n\t\t\t\t\tcase '*':\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t\tif lexer.codePoint == '/' {\n\t\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t\t\tbreak multiLineComment\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t\tlexer.HasNewlineBefore = true\n\n\t\t\t\t\tcase -1: // This indicates the end of the file\n\t\t\t\t\t\tlexer.start = lexer.end\n\t\t\t\t\t\tlexer.AddRangeErrorWithNotes(logger.Range{Loc: lexer.Loc()}, \"Expected \\\"*/\\\" to terminate multi-line comment\",\n\t\t\t\t\t\t\t[]logger.MsgData{lexer.tracker.MsgData(startRange, \"The multi-line comment starts here:\")})\n\t\t\t\t\t\tpanic(LexerPanic{})\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif lexer.json == JSON {\n\t\t\t\t\tlexer.addRangeError(lexer.Range(), \"JSON does not support comments\")\n\t\t\t\t}\n\t\t\t\tlexer.scanCommentText()\n\t\t\t\tcontinue\n\n\t\t\tdefault:\n\t\t\t\tlexer.Token = TSlash\n\t\t\t}\n\n\t\tcase '=':\n\t\t\t// '=' or '=>' or '==' or '==='\n\t\t\tlexer.step()\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '>':\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token = TEqualsGreaterThan\n\t\t\tcase '=':\n\t\t\t\tlexer.step()\n\t\t\t\tswitch lexer.codePoint {\n\t\t\t\tcase '=':\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.Token = TEqualsEqualsEquals\n\t\t\t\tdefault:\n\t\t\t\t\tlexer.Token = TEqualsEquals\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tlexer.Token = TEquals\n\t\t\t}\n\n\t\tcase '<':\n\t\t\t// '<' or '<<' or '<=' or '<<=' or '<!--'\n\t\t\tlexer.step()\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '=':\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token = TLessThanEquals\n\t\t\tcase '<':\n\t\t\t\tlexer.step()\n\t\t\t\tswitch lexer.codePoint {\n\t\t\t\tcase '=':\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.Token = TLessThanLessThanEquals\n\t\t\t\tdefault:\n\t\t\t\t\tlexer.Token = TLessThanLessThan\n\t\t\t\t}\n\n\t\t\t\t// Handle legacy HTML-style comments\n\t\t\tcase '!':\n\t\t\t\tif strings.HasPrefix(lexer.source.Contents[lexer.start:], \"<!--\") {\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.LegacyHTMLCommentRange = lexer.Range()\n\t\t\t\t\tlexer.log.AddID(logger.MsgID_JS_HTMLCommentInJS, logger.Warning, &lexer.tracker, lexer.Range(),\n\t\t\t\t\t\t\"Treating \\\"<!--\\\" as the start of a legacy HTML single-line comment\")\n\t\t\t\tsingleLineHTMLOpenComment:\n\t\t\t\t\tfor {\n\t\t\t\t\t\tswitch lexer.codePoint {\n\t\t\t\t\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t\t\t\t\tbreak singleLineHTMLOpenComment\n\n\t\t\t\t\t\tcase -1: // This indicates the end of the file\n\t\t\t\t\t\t\tbreak singleLineHTMLOpenComment\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tlexer.Token = TLessThan\n\n\t\t\tdefault:\n\t\t\t\tlexer.Token = TLessThan\n\t\t\t}\n\n\t\tcase '>':\n\t\t\t// '>' or '>>' or '>>>' or '>=' or '>>=' or '>>>='\n\t\t\tlexer.step()\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '=':\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token = TGreaterThanEquals\n\t\t\tcase '>':\n\t\t\t\tlexer.step()\n\t\t\t\tswitch lexer.codePoint {\n\t\t\t\tcase '=':\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.Token = TGreaterThanGreaterThanEquals\n\t\t\t\tcase '>':\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tswitch lexer.codePoint {\n\t\t\t\t\tcase '=':\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t\tlexer.Token = TGreaterThanGreaterThanGreaterThanEquals\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tlexer.Token = TGreaterThanGreaterThanGreaterThan\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tlexer.Token = TGreaterThanGreaterThan\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tlexer.Token = TGreaterThan\n\t\t\t}\n\n\t\tcase '!':\n\t\t\t// '!' or '!=' or '!=='\n\t\t\tlexer.step()\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '=':\n\t\t\t\tlexer.step()\n\t\t\t\tswitch lexer.codePoint {\n\t\t\t\tcase '=':\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.Token = TExclamationEqualsEquals\n\t\t\t\tdefault:\n\t\t\t\t\tlexer.Token = TExclamationEquals\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tlexer.Token = TExclamation\n\t\t\t}\n\n\t\tcase '\\'', '\"', '`':\n\t\t\tquote := lexer.codePoint\n\t\t\tneedsSlowPath := false\n\t\t\tsuffixLen := 1\n\n\t\t\tif quote != '`' {\n\t\t\t\tlexer.Token = TStringLiteral\n\t\t\t} else if lexer.rescanCloseBraceAsTemplateToken {\n\t\t\t\tlexer.Token = TTemplateTail\n\t\t\t} else {\n\t\t\t\tlexer.Token = TNoSubstitutionTemplateLiteral\n\t\t\t}\n\t\t\tlexer.step()\n\n\t\tstringLiteral:\n\t\t\tfor {\n\t\t\t\tswitch lexer.codePoint {\n\t\t\t\tcase '\\\\':\n\t\t\t\t\tneedsSlowPath = true\n\t\t\t\t\tlexer.step()\n\n\t\t\t\t\t// Handle Windows CRLF\n\t\t\t\t\tif lexer.codePoint == '\\r' && lexer.json != JSON {\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t\tif lexer.codePoint == '\\n' {\n\t\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\tcase -1: // This indicates the end of the file\n\t\t\t\t\tlexer.addRangeError(logger.Range{Loc: logger.Loc{Start: int32(lexer.end)}}, \"Unterminated string literal\")\n\t\t\t\t\tpanic(LexerPanic{})\n\n\t\t\t\tcase '\\r':\n\t\t\t\t\tif quote != '`' {\n\t\t\t\t\t\tlexer.addRangeError(logger.Range{Loc: logger.Loc{Start: int32(lexer.end)}}, \"Unterminated string literal\")\n\t\t\t\t\t\tpanic(LexerPanic{})\n\t\t\t\t\t}\n\n\t\t\t\t\t// Template literals require newline normalization\n\t\t\t\t\tneedsSlowPath = true\n\n\t\t\t\tcase '\\n':\n\t\t\t\t\tif quote != '`' {\n\t\t\t\t\t\tlexer.addRangeError(logger.Range{Loc: logger.Loc{Start: int32(lexer.end)}}, \"Unterminated string literal\")\n\t\t\t\t\t\tpanic(LexerPanic{})\n\t\t\t\t\t}\n\n\t\t\t\tcase '$':\n\t\t\t\t\tif quote == '`' {\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t\tif lexer.codePoint == '{' {\n\t\t\t\t\t\t\tsuffixLen = 2\n\t\t\t\t\t\t\tlexer.step()\n\t\t\t\t\t\t\tif lexer.rescanCloseBraceAsTemplateToken {\n\t\t\t\t\t\t\t\tlexer.Token = TTemplateMiddle\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tlexer.Token = TTemplateHead\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak stringLiteral\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue stringLiteral\n\t\t\t\t\t}\n\n\t\t\t\tcase quote:\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tbreak stringLiteral\n\n\t\t\t\tdefault:\n\t\t\t\t\t// Non-ASCII strings need the slow path\n\t\t\t\t\tif lexer.codePoint >= 0x80 {\n\t\t\t\t\t\tneedsSlowPath = true\n\t\t\t\t\t} else if lexer.json == JSON && lexer.codePoint < 0x20 {\n\t\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlexer.step()\n\t\t\t}\n\n\t\t\ttext := lexer.source.Contents[lexer.start+1 : lexer.end-suffixLen]\n\n\t\t\tif needsSlowPath {\n\t\t\t\t// Slow path\n\t\t\t\tlexer.decodedStringLiteralOrNil = nil\n\t\t\t\tlexer.encodedStringLiteralStart = lexer.start + 1\n\t\t\t\tlexer.encodedStringLiteralText = text\n\t\t\t} else {\n\t\t\t\t// Fast path\n\t\t\t\tn := len(text)\n\t\t\t\tcopy := make([]uint16, n)\n\t\t\t\tfor i := 0; i < n; i++ {\n\t\t\t\t\tcopy[i] = uint16(text[i])\n\t\t\t\t}\n\t\t\t\tlexer.decodedStringLiteralOrNil = copy\n\t\t\t}\n\n\t\t\tif quote == '\\'' && (lexer.json == JSON || lexer.json == TSConfigJSON) {\n\t\t\t\tlexer.addRangeError(lexer.Range(), \"JSON strings must use double quotes\")\n\t\t\t}\n\n\t\t// Note: This case is hot in profiles\n\t\tcase '_', '$',\n\t\t\t'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',\n\t\t\t'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',\n\t\t\t'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',\n\t\t\t'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z':\n\t\t\t// This is a fast path for long ASCII identifiers. Doing this in a loop\n\t\t\t// first instead of doing \"step()\" and \"js_ast.IsIdentifierContinue()\" like we\n\t\t\t// do after this is noticeably faster in the common case of ASCII-only\n\t\t\t// text. For example, doing this sped up end-to-end consuming of a large\n\t\t\t// TypeScript type declaration file from 97ms to 79ms (around 20% faster).\n\t\t\tcontents := lexer.source.Contents\n\t\t\tn := len(contents)\n\t\t\ti := lexer.current\n\t\t\tfor i < n {\n\t\t\t\tc := contents[i]\n\t\t\t\tif (c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '_' && c != '$' {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ti++\n\t\t\t}\n\t\t\tlexer.current = i\n\n\t\t\t// Now do the slow path for any remaining non-ASCII identifier characters\n\t\t\tlexer.step()\n\t\t\tif lexer.codePoint >= 0x80 {\n\t\t\t\tfor js_ast.IsIdentifierContinue(lexer.codePoint) {\n\t\t\t\t\tlexer.step()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If there's a slash, then we're in the extra-slow (and extra-rare) case\n\t\t\t// where the identifier has embedded escapes\n\t\t\tif lexer.codePoint == '\\\\' {\n\t\t\t\tlexer.Identifier, lexer.Token = lexer.scanIdentifierWithEscapes(normalIdentifier)\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Otherwise (if there was no escape) we can slice the code verbatim\n\t\t\tlexer.Identifier = lexer.rawIdentifier()\n\t\t\tlexer.Token = Keywords[lexer.Raw()]\n\t\t\tif lexer.Token == 0 {\n\t\t\t\tlexer.Token = TIdentifier\n\t\t\t}\n\n\t\tcase '\\\\':\n\t\t\tlexer.Identifier, lexer.Token = lexer.scanIdentifierWithEscapes(normalIdentifier)\n\n\t\tcase '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':\n\t\t\tlexer.parseNumericLiteralOrDot()\n\n\t\tdefault:\n\t\t\t// Check for unusual whitespace characters\n\t\t\tif js_ast.IsWhitespace(lexer.codePoint) {\n\t\t\t\tlexer.step()\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif js_ast.IsIdentifierStart(lexer.codePoint) {\n\t\t\t\tlexer.step()\n\t\t\t\tfor js_ast.IsIdentifierContinue(lexer.codePoint) {\n\t\t\t\t\tlexer.step()\n\t\t\t\t}\n\t\t\t\tif lexer.codePoint == '\\\\' {\n\t\t\t\t\tlexer.Identifier, lexer.Token = lexer.scanIdentifierWithEscapes(normalIdentifier)\n\t\t\t\t} else {\n\t\t\t\t\tlexer.Token = TIdentifier\n\t\t\t\t\tlexer.Identifier = lexer.rawIdentifier()\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tlexer.end = lexer.current\n\t\t\tlexer.Token = TSyntaxError\n\t\t}\n\n\t\treturn\n\t}\n}\n\ntype identifierKind uint8\n\nconst (\n\tnormalIdentifier identifierKind = iota\n\tprivateIdentifier\n)\n\n// This is an edge case that doesn't really exist in the wild, so it doesn't\n// need to be as fast as possible.\nfunc (lexer *Lexer) scanIdentifierWithEscapes(kind identifierKind) (MaybeSubstring, T) {\n\t// First pass: scan over the identifier to see how long it is\n\tfor {\n\t\t// Scan a unicode escape sequence. There is at least one because that's\n\t\t// what caused us to get on this slow path in the first place.\n\t\tif lexer.codePoint == '\\\\' {\n\t\t\tlexer.step()\n\t\t\tif lexer.codePoint != 'u' {\n\t\t\t\tlexer.SyntaxError()\n\t\t\t}\n\t\t\tlexer.step()\n\t\t\tif lexer.codePoint == '{' {\n\t\t\t\t// Variable-length\n\t\t\t\tlexer.step()\n\t\t\t\tfor lexer.codePoint != '}' {\n\t\t\t\t\tswitch lexer.codePoint {\n\t\t\t\t\tcase '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n\t\t\t\t\t\t'a', 'b', 'c', 'd', 'e', 'f',\n\t\t\t\t\t\t'A', 'B', 'C', 'D', 'E', 'F':\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlexer.step()\n\t\t\t} else {\n\t\t\t\t// Fixed-length\n\t\t\t\tfor j := 0; j < 4; j++ {\n\t\t\t\t\tswitch lexer.codePoint {\n\t\t\t\t\tcase '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n\t\t\t\t\t\t'a', 'b', 'c', 'd', 'e', 'f',\n\t\t\t\t\t\t'A', 'B', 'C', 'D', 'E', 'F':\n\t\t\t\t\t\tlexer.step()\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Stop when we reach the end of the identifier\n\t\tif !js_ast.IsIdentifierContinue(lexer.codePoint) {\n\t\t\tbreak\n\t\t}\n\t\tlexer.step()\n\t}\n\n\t// Second pass: re-use our existing escape sequence parser\n\tdecoded, ok, end := lexer.tryToDecodeEscapeSequences(lexer.start, lexer.Raw(), true /* reportErrors */)\n\tif !ok {\n\t\tlexer.end = end\n\t\tlexer.SyntaxError()\n\t}\n\ttext := string(helpers.UTF16ToString(decoded))\n\n\t// Even though it was escaped, it must still be a valid identifier\n\tidentifier := text\n\tif kind == privateIdentifier {\n\t\tidentifier = identifier[1:] // Skip over the \"#\"\n\t}\n\tif !js_ast.IsIdentifier(identifier) {\n\t\tlexer.addRangeError(logger.Range{Loc: logger.Loc{Start: int32(lexer.start)}, Len: int32(lexer.end - lexer.start)},\n\t\t\tfmt.Sprintf(\"Invalid identifier: %q\", text))\n\t}\n\n\t// Escaped keywords are not allowed to work as actual keywords, but they are\n\t// allowed wherever we allow identifiers or keywords. For example:\n\t//\n\t//   // This is an error (equivalent to \"var var;\")\n\t//   var \\u0076\\u0061\\u0072;\n\t//\n\t//   // This is an error (equivalent to \"var foo;\" except for this rule)\n\t//   \\u0076\\u0061\\u0072 foo;\n\t//\n\t//   // This is an fine (equivalent to \"foo.var;\")\n\t//   foo.\\u0076\\u0061\\u0072;\n\t//\n\tif Keywords[text] != 0 {\n\t\treturn MaybeSubstring{String: text}, TEscapedKeyword\n\t} else {\n\t\treturn MaybeSubstring{String: text}, TIdentifier\n\t}\n}\n\nfunc (lexer *Lexer) parseNumericLiteralOrDot() {\n\t// Number or dot\n\tfirst := lexer.codePoint\n\tlexer.step()\n\n\t// Dot without a digit after it\n\tif first == '.' && (lexer.codePoint < '0' || lexer.codePoint > '9') {\n\t\t// \"...\"\n\t\tif lexer.codePoint == '.' &&\n\t\t\tlexer.current < len(lexer.source.Contents) &&\n\t\t\tlexer.source.Contents[lexer.current] == '.' {\n\t\t\tlexer.step()\n\t\t\tlexer.step()\n\t\t\tlexer.Token = TDotDotDot\n\t\t\treturn\n\t\t}\n\n\t\t// \".\"\n\t\tlexer.Token = TDot\n\t\treturn\n\t}\n\n\tunderscoreCount := 0\n\tlastUnderscoreEnd := 0\n\thasDotOrExponent := first == '.'\n\tisMissingDigitAfterDot := false\n\tbase := 0.0\n\tlexer.IsLegacyOctalLiteral = false\n\n\t// Assume this is a number, but potentially change to a bigint later\n\tlexer.Token = TNumericLiteral\n\n\t// Check for binary, octal, or hexadecimal literal\n\tif first == '0' {\n\t\tswitch lexer.codePoint {\n\t\tcase 'b', 'B':\n\t\t\tbase = 2\n\n\t\tcase 'o', 'O':\n\t\t\tbase = 8\n\n\t\tcase 'x', 'X':\n\t\t\tbase = 16\n\n\t\tcase '0', '1', '2', '3', '4', '5', '6', '7', '_':\n\t\t\tbase = 8\n\t\t\tlexer.IsLegacyOctalLiteral = true\n\n\t\tcase '8', '9':\n\t\t\tlexer.IsLegacyOctalLiteral = true\n\t\t}\n\t}\n\n\tif base != 0 {\n\t\t// Integer literal\n\t\tisFirst := true\n\t\tisInvalidLegacyOctalLiteral := false\n\t\tlexer.Number = 0\n\t\tif !lexer.IsLegacyOctalLiteral {\n\t\t\tlexer.step()\n\t\t}\n\n\tintegerLiteral:\n\t\tfor {\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '_':\n\t\t\t\t// Cannot have multiple underscores in a row\n\t\t\t\tif lastUnderscoreEnd > 0 && lexer.end == lastUnderscoreEnd+1 {\n\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t}\n\n\t\t\t\t// The first digit must exist\n\t\t\t\tif isFirst || lexer.IsLegacyOctalLiteral {\n\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t}\n\n\t\t\t\tlastUnderscoreEnd = lexer.end\n\t\t\t\tunderscoreCount++\n\n\t\t\tcase '0', '1':\n\t\t\t\tlexer.Number = lexer.Number*base + float64(lexer.codePoint-'0')\n\n\t\t\tcase '2', '3', '4', '5', '6', '7':\n\t\t\t\tif base == 2 {\n\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t}\n\t\t\t\tlexer.Number = lexer.Number*base + float64(lexer.codePoint-'0')\n\n\t\t\tcase '8', '9':\n\t\t\t\tif lexer.IsLegacyOctalLiteral {\n\t\t\t\t\tisInvalidLegacyOctalLiteral = true\n\t\t\t\t} else if base < 10 {\n\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t}\n\t\t\t\tlexer.Number = lexer.Number*base + float64(lexer.codePoint-'0')\n\n\t\t\tcase 'A', 'B', 'C', 'D', 'E', 'F':\n\t\t\t\tif base != 16 {\n\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t}\n\t\t\t\tlexer.Number = lexer.Number*base + float64(lexer.codePoint+10-'A')\n\n\t\t\tcase 'a', 'b', 'c', 'd', 'e', 'f':\n\t\t\t\tif base != 16 {\n\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t}\n\t\t\t\tlexer.Number = lexer.Number*base + float64(lexer.codePoint+10-'a')\n\n\t\t\tdefault:\n\t\t\t\t// The first digit must exist\n\t\t\t\tif isFirst {\n\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t}\n\n\t\t\t\tbreak integerLiteral\n\t\t\t}\n\n\t\t\tlexer.step()\n\t\t\tisFirst = false\n\t\t}\n\n\t\tisBigIntegerLiteral := lexer.codePoint == 'n' && !hasDotOrExponent\n\n\t\t// Slow path: do we need to re-scan the input as text?\n\t\tif isBigIntegerLiteral || isInvalidLegacyOctalLiteral {\n\t\t\ttext := lexer.rawIdentifier()\n\n\t\t\t// Can't use a leading zero for bigint literals\n\t\t\tif isBigIntegerLiteral && lexer.IsLegacyOctalLiteral {\n\t\t\t\tlexer.SyntaxError()\n\t\t\t}\n\n\t\t\t// Filter out underscores\n\t\t\tif underscoreCount > 0 {\n\t\t\t\tbytes := make([]byte, 0, len(text.String)-underscoreCount)\n\t\t\t\tfor i := 0; i < len(text.String); i++ {\n\t\t\t\t\tc := text.String[i]\n\t\t\t\t\tif c != '_' {\n\t\t\t\t\t\tbytes = append(bytes, c)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ttext = MaybeSubstring{String: string(bytes)}\n\t\t\t}\n\n\t\t\t// Store bigints as text to avoid precision loss\n\t\t\tif isBigIntegerLiteral {\n\t\t\t\tlexer.Identifier = text\n\t\t\t} else if isInvalidLegacyOctalLiteral {\n\t\t\t\t// Legacy octal literals may turn out to be a base 10 literal after all\n\t\t\t\tvalue, _ := strconv.ParseFloat(text.String, 64)\n\t\t\t\tlexer.Number = value\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// Floating-point literal\n\t\tisInvalidLegacyOctalLiteral := first == '0' && (lexer.codePoint == '8' || lexer.codePoint == '9')\n\n\t\t// Initial digits\n\t\tfor {\n\t\t\tif lexer.codePoint < '0' || lexer.codePoint > '9' {\n\t\t\t\tif lexer.codePoint != '_' {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// Cannot have multiple underscores in a row\n\t\t\t\tif lastUnderscoreEnd > 0 && lexer.end == lastUnderscoreEnd+1 {\n\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t}\n\n\t\t\t\t// The specification forbids underscores in this case\n\t\t\t\tif isInvalidLegacyOctalLiteral {\n\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t}\n\n\t\t\t\tlastUnderscoreEnd = lexer.end\n\t\t\t\tunderscoreCount++\n\t\t\t}\n\t\t\tlexer.step()\n\t\t}\n\n\t\t// Fractional digits\n\t\tif first != '.' && lexer.codePoint == '.' {\n\t\t\t// An underscore must not come last\n\t\t\tif lastUnderscoreEnd > 0 && lexer.end == lastUnderscoreEnd+1 {\n\t\t\t\tlexer.end--\n\t\t\t\tlexer.SyntaxError()\n\t\t\t}\n\n\t\t\thasDotOrExponent = true\n\t\t\tlexer.step()\n\t\t\tif lexer.codePoint == '_' {\n\t\t\t\tlexer.SyntaxError()\n\t\t\t}\n\t\t\tisMissingDigitAfterDot = true\n\t\t\tfor {\n\t\t\t\tif lexer.codePoint >= '0' && lexer.codePoint <= '9' {\n\t\t\t\t\tisMissingDigitAfterDot = false\n\t\t\t\t} else {\n\t\t\t\t\tif lexer.codePoint != '_' {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\t// Cannot have multiple underscores in a row\n\t\t\t\t\tif lastUnderscoreEnd > 0 && lexer.end == lastUnderscoreEnd+1 {\n\t\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t\t}\n\n\t\t\t\t\tlastUnderscoreEnd = lexer.end\n\t\t\t\t\tunderscoreCount++\n\t\t\t\t}\n\t\t\t\tlexer.step()\n\t\t\t}\n\t\t}\n\n\t\t// Exponent\n\t\tif lexer.codePoint == 'e' || lexer.codePoint == 'E' {\n\t\t\t// An underscore must not come last\n\t\t\tif lastUnderscoreEnd > 0 && lexer.end == lastUnderscoreEnd+1 {\n\t\t\t\tlexer.end--\n\t\t\t\tlexer.SyntaxError()\n\t\t\t}\n\n\t\t\thasDotOrExponent = true\n\t\t\tlexer.step()\n\t\t\tif lexer.codePoint == '+' || lexer.codePoint == '-' {\n\t\t\t\tlexer.step()\n\t\t\t}\n\t\t\tif lexer.codePoint < '0' || lexer.codePoint > '9' {\n\t\t\t\tlexer.SyntaxError()\n\t\t\t}\n\t\t\tfor {\n\t\t\t\tif lexer.codePoint < '0' || lexer.codePoint > '9' {\n\t\t\t\t\tif lexer.codePoint != '_' {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\t// Cannot have multiple underscores in a row\n\t\t\t\t\tif lastUnderscoreEnd > 0 && lexer.end == lastUnderscoreEnd+1 {\n\t\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t\t}\n\n\t\t\t\t\tlastUnderscoreEnd = lexer.end\n\t\t\t\t\tunderscoreCount++\n\t\t\t\t}\n\t\t\t\tlexer.step()\n\t\t\t}\n\t\t}\n\n\t\t// Take a slice of the text to parse\n\t\ttext := lexer.rawIdentifier()\n\n\t\t// Filter out underscores\n\t\tif underscoreCount > 0 {\n\t\t\tbytes := make([]byte, 0, len(text.String)-underscoreCount)\n\t\t\tfor i := 0; i < len(text.String); i++ {\n\t\t\t\tc := text.String[i]\n\t\t\t\tif c != '_' {\n\t\t\t\t\tbytes = append(bytes, c)\n\t\t\t\t}\n\t\t\t}\n\t\t\ttext = MaybeSubstring{String: string(bytes)}\n\t\t}\n\n\t\tif lexer.codePoint == 'n' && !hasDotOrExponent {\n\t\t\t// The only bigint literal that can start with 0 is \"0n\"\n\t\t\tif len(text.String) > 1 && first == '0' {\n\t\t\t\tlexer.SyntaxError()\n\t\t\t}\n\n\t\t\t// Store bigints as text to avoid precision loss\n\t\t\tlexer.Identifier = text\n\t\t} else if !hasDotOrExponent && lexer.end-lexer.start < 10 {\n\t\t\t// Parse a 32-bit integer (very fast path)\n\t\t\tvar number uint32 = 0\n\t\t\tfor _, c := range text.String {\n\t\t\t\tnumber = number*10 + uint32(c-'0')\n\t\t\t}\n\t\t\tlexer.Number = float64(number)\n\t\t} else {\n\t\t\t// Parse a double-precision floating-point number\n\t\t\tvalue, _ := strconv.ParseFloat(text.String, 64)\n\t\t\tlexer.Number = value\n\t\t}\n\t}\n\n\t// An underscore must not come last\n\tif lastUnderscoreEnd > 0 && lexer.end == lastUnderscoreEnd+1 {\n\t\tlexer.end--\n\t\tlexer.SyntaxError()\n\t}\n\n\t// Handle bigint literals after the underscore-at-end check above\n\tif lexer.codePoint == 'n' && !hasDotOrExponent {\n\t\tlexer.Token = TBigIntegerLiteral\n\t\tlexer.step()\n\t}\n\n\t// Identifiers can't occur immediately after numbers\n\tif js_ast.IsIdentifierStart(lexer.codePoint) {\n\t\tlexer.SyntaxError()\n\t}\n\n\t// None of these are allowed in JSON\n\tif lexer.json == JSON && (first == '.' || base != 0 || underscoreCount > 0 || isMissingDigitAfterDot) {\n\t\tlexer.Unexpected()\n\t}\n}\n\nfunc (lexer *Lexer) ScanRegExp() {\n\tvalidateAndStep := func() {\n\t\tif lexer.codePoint == '\\\\' {\n\t\t\tlexer.step()\n\t\t}\n\n\t\tswitch lexer.codePoint {\n\t\tcase -1, // This indicates the end of the file\n\t\t\t'\\r', '\\n', 0x2028, 0x2029: // Newlines aren't allowed in regular expressions\n\t\t\tlexer.addRangeError(logger.Range{Loc: logger.Loc{Start: int32(lexer.end)}}, \"Unterminated regular expression\")\n\t\t\tpanic(LexerPanic{})\n\n\t\tdefault:\n\t\t\tlexer.step()\n\t\t}\n\t}\n\n\tfor {\n\t\tswitch lexer.codePoint {\n\t\tcase '/':\n\t\t\tlexer.step()\n\t\t\tbits := uint32(0)\n\t\t\tfor js_ast.IsIdentifierContinue(lexer.codePoint) {\n\t\t\t\tswitch lexer.codePoint {\n\t\t\t\tcase 'd', 'g', 'i', 'm', 's', 'u', 'v', 'y':\n\t\t\t\t\tbit := uint32(1) << uint32(lexer.codePoint-'a')\n\t\t\t\t\tif (bit & bits) != 0 {\n\t\t\t\t\t\t// Reject duplicate flags\n\t\t\t\t\t\tr1 := logger.Range{Loc: logger.Loc{Start: int32(lexer.start)}, Len: 1}\n\t\t\t\t\t\tr2 := logger.Range{Loc: logger.Loc{Start: int32(lexer.end)}, Len: 1}\n\t\t\t\t\t\tfor r1.Loc.Start < r2.Loc.Start && lexer.source.Contents[r1.Loc.Start] != byte(lexer.codePoint) {\n\t\t\t\t\t\t\tr1.Loc.Start++\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlexer.log.AddErrorWithNotes(&lexer.tracker, r2,\n\t\t\t\t\t\t\tfmt.Sprintf(\"Duplicate flag \\\"%c\\\" in regular expression\", lexer.codePoint),\n\t\t\t\t\t\t\t[]logger.MsgData{lexer.tracker.MsgData(r1,\n\t\t\t\t\t\t\t\tfmt.Sprintf(\"The first \\\"%c\\\" was here:\", lexer.codePoint))})\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbits |= bit\n\t\t\t\t\t}\n\t\t\t\t\tlexer.step()\n\n\t\t\t\tdefault:\n\t\t\t\t\tlexer.SyntaxError()\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn\n\n\t\tcase '[':\n\t\t\tlexer.step()\n\t\t\tfor lexer.codePoint != ']' {\n\t\t\t\tvalidateAndStep()\n\t\t\t}\n\t\t\tlexer.step()\n\n\t\tdefault:\n\t\t\tvalidateAndStep()\n\t\t}\n\t}\n}\n\nfunc decodeJSXEntities(decoded []uint16, text string) []uint16 {\n\ti := 0\n\n\tfor i < len(text) {\n\t\tc, width := utf8.DecodeRuneInString(text[i:])\n\t\ti += width\n\n\t\tif c == '&' {\n\t\t\tlength := strings.IndexByte(text[i:], ';')\n\t\t\tif length > 0 {\n\t\t\t\tentity := text[i : i+length]\n\t\t\t\tif entity[0] == '#' {\n\t\t\t\t\tnumber := entity[1:]\n\t\t\t\t\tbase := 10\n\t\t\t\t\tif len(number) > 1 && number[0] == 'x' {\n\t\t\t\t\t\tnumber = number[1:]\n\t\t\t\t\t\tbase = 16\n\t\t\t\t\t}\n\t\t\t\t\tif value, err := strconv.ParseInt(number, base, 32); err == nil {\n\t\t\t\t\t\tc = rune(value)\n\t\t\t\t\t\ti += length + 1\n\t\t\t\t\t}\n\t\t\t\t} else if value, ok := jsxEntity[entity]; ok {\n\t\t\t\t\tc = value\n\t\t\t\t\ti += length + 1\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif c <= 0xFFFF {\n\t\t\tdecoded = append(decoded, uint16(c))\n\t\t} else {\n\t\t\tc -= 0x10000\n\t\t\tdecoded = append(decoded, uint16(0xD800+((c>>10)&0x3FF)), uint16(0xDC00+(c&0x3FF)))\n\t\t}\n\t}\n\n\treturn decoded\n}\n\nfunc fixWhitespaceAndDecodeJSXEntities(text string) []uint16 {\n\tafterLastNonWhitespace := -1\n\tdecoded := []uint16{}\n\ti := 0\n\n\t// Trim whitespace off the end of the first line\n\tfirstNonWhitespace := 0\n\n\t// Split into lines\n\tfor i < len(text) {\n\t\tc, width := utf8.DecodeRuneInString(text[i:])\n\n\t\tswitch c {\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t// Newline\n\t\t\tif firstNonWhitespace != -1 && afterLastNonWhitespace != -1 {\n\t\t\t\tif len(decoded) > 0 {\n\t\t\t\t\tdecoded = append(decoded, ' ')\n\t\t\t\t}\n\n\t\t\t\t// Trim whitespace off the start and end of lines in the middle\n\t\t\t\tdecoded = decodeJSXEntities(decoded, text[firstNonWhitespace:afterLastNonWhitespace])\n\t\t\t}\n\n\t\t\t// Reset for the next line\n\t\t\tfirstNonWhitespace = -1\n\n\t\tcase '\\t', ' ':\n\t\t\t// Whitespace\n\n\t\tdefault:\n\t\t\t// Check for unusual whitespace characters\n\t\t\tif !js_ast.IsWhitespace(c) {\n\t\t\t\tafterLastNonWhitespace = i + width\n\t\t\t\tif firstNonWhitespace == -1 {\n\t\t\t\t\tfirstNonWhitespace = i\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ti += width\n\t}\n\n\tif firstNonWhitespace != -1 {\n\t\tif len(decoded) > 0 {\n\t\t\tdecoded = append(decoded, ' ')\n\t\t}\n\n\t\t// Trim whitespace off the start of the last line\n\t\tdecoded = decodeJSXEntities(decoded, text[firstNonWhitespace:])\n\t}\n\n\treturn decoded\n}\n\n// If this fails, this returns \"nil, false, end\" where \"end\" is the value to\n// store to \"lexer.end\" before calling \"lexer.SyntaxError()\" if relevant\nfunc (lexer *Lexer) tryToDecodeEscapeSequences(start int, text string, reportErrors bool) ([]uint16, bool, int) {\n\tdecoded := []uint16{}\n\ti := 0\n\n\tfor i < len(text) {\n\t\tc, width := utf8.DecodeRuneInString(text[i:])\n\t\ti += width\n\n\t\tswitch c {\n\t\tcase '\\r':\n\t\t\t// From the specification:\n\t\t\t//\n\t\t\t// 11.8.6.1 Static Semantics: TV and TRV\n\t\t\t//\n\t\t\t// TV excludes the code units of LineContinuation while TRV includes\n\t\t\t// them. <CR><LF> and <CR> LineTerminatorSequences are normalized to\n\t\t\t// <LF> for both TV and TRV. An explicit EscapeSequence is needed to\n\t\t\t// include a <CR> or <CR><LF> sequence.\n\n\t\t\t// Convert '\\r\\n' into '\\n'\n\t\t\tif i < len(text) && text[i] == '\\n' {\n\t\t\t\ti++\n\t\t\t}\n\n\t\t\t// Convert '\\r' into '\\n'\n\t\t\tdecoded = append(decoded, '\\n')\n\t\t\tcontinue\n\n\t\tcase '\\\\':\n\t\t\tc2, width2 := utf8.DecodeRuneInString(text[i:])\n\t\t\ti += width2\n\n\t\t\tswitch c2 {\n\t\t\tcase 'b':\n\t\t\t\tdecoded = append(decoded, '\\b')\n\t\t\t\tcontinue\n\n\t\t\tcase 'f':\n\t\t\t\tdecoded = append(decoded, '\\f')\n\t\t\t\tcontinue\n\n\t\t\tcase 'n':\n\t\t\t\tdecoded = append(decoded, '\\n')\n\t\t\t\tcontinue\n\n\t\t\tcase 'r':\n\t\t\t\tdecoded = append(decoded, '\\r')\n\t\t\t\tcontinue\n\n\t\t\tcase 't':\n\t\t\t\tdecoded = append(decoded, '\\t')\n\t\t\t\tcontinue\n\n\t\t\tcase 'v':\n\t\t\t\tif lexer.json == JSON {\n\t\t\t\t\treturn nil, false, start + i - width2\n\t\t\t\t}\n\n\t\t\t\tdecoded = append(decoded, '\\v')\n\t\t\t\tcontinue\n\n\t\t\tcase '0', '1', '2', '3', '4', '5', '6', '7':\n\t\t\t\toctalStart := i - 2\n\t\t\t\tif lexer.json == JSON {\n\t\t\t\t\treturn nil, false, start + i - width2\n\t\t\t\t}\n\n\t\t\t\t// 1-3 digit octal\n\t\t\t\tisBad := false\n\t\t\t\tvalue := c2 - '0'\n\t\t\t\tc3, width3 := utf8.DecodeRuneInString(text[i:])\n\t\t\t\tswitch c3 {\n\t\t\t\tcase '0', '1', '2', '3', '4', '5', '6', '7':\n\t\t\t\t\tvalue = value*8 + c3 - '0'\n\t\t\t\t\ti += width3\n\t\t\t\t\tc4, width4 := utf8.DecodeRuneInString(text[i:])\n\t\t\t\t\tswitch c4 {\n\t\t\t\t\tcase '0', '1', '2', '3', '4', '5', '6', '7':\n\t\t\t\t\t\ttemp := value*8 + c4 - '0'\n\t\t\t\t\t\tif temp < 256 {\n\t\t\t\t\t\t\tvalue = temp\n\t\t\t\t\t\t\ti += width4\n\t\t\t\t\t\t}\n\t\t\t\t\tcase '8', '9':\n\t\t\t\t\t\tisBad = true\n\t\t\t\t\t}\n\t\t\t\tcase '8', '9':\n\t\t\t\t\tisBad = true\n\t\t\t\t}\n\t\t\t\tc = value\n\n\t\t\t\t// Forbid the use of octal literals other than \"\\0\"\n\t\t\t\tif isBad || text[octalStart:i] != \"\\\\0\" {\n\t\t\t\t\tlexer.LegacyOctalLoc = logger.Loc{Start: int32(start + octalStart)}\n\t\t\t\t}\n\n\t\t\tcase '8', '9':\n\t\t\t\tc = c2\n\n\t\t\t\t// Forbid the invalid octal literals \"\\8\" and \"\\9\"\n\t\t\t\tlexer.LegacyOctalLoc = logger.Loc{Start: int32(start + i - 2)}\n\n\t\t\tcase 'x':\n\t\t\t\tif lexer.json == JSON {\n\t\t\t\t\treturn nil, false, start + i - width2\n\t\t\t\t}\n\n\t\t\t\t// 2-digit hexadecimal\n\t\t\t\tvalue := '\\000'\n\t\t\t\tfor j := 0; j < 2; j++ {\n\t\t\t\t\tc3, width3 := utf8.DecodeRuneInString(text[i:])\n\t\t\t\t\ti += width3\n\t\t\t\t\tswitch c3 {\n\t\t\t\t\tcase '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':\n\t\t\t\t\t\tvalue = value*16 | (c3 - '0')\n\t\t\t\t\tcase 'a', 'b', 'c', 'd', 'e', 'f':\n\t\t\t\t\t\tvalue = value*16 | (c3 + 10 - 'a')\n\t\t\t\t\tcase 'A', 'B', 'C', 'D', 'E', 'F':\n\t\t\t\t\t\tvalue = value*16 | (c3 + 10 - 'A')\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn nil, false, start + i - width3\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tc = value\n\n\t\t\tcase 'u':\n\t\t\t\t// Unicode\n\t\t\t\tvalue := '\\000'\n\n\t\t\t\t// Check the first character\n\t\t\t\tc3, width3 := utf8.DecodeRuneInString(text[i:])\n\t\t\t\ti += width3\n\n\t\t\t\tif c3 == '{' {\n\t\t\t\t\tif lexer.json == JSON {\n\t\t\t\t\t\treturn nil, false, start + i - width2\n\t\t\t\t\t}\n\n\t\t\t\t\t// Variable-length\n\t\t\t\t\thexStart := i - width - width2 - width3\n\t\t\t\t\tisFirst := true\n\t\t\t\t\tisOutOfRange := false\n\t\t\t\tvariableLength:\n\t\t\t\t\tfor {\n\t\t\t\t\t\tc3, width3 = utf8.DecodeRuneInString(text[i:])\n\t\t\t\t\t\ti += width3\n\n\t\t\t\t\t\tswitch c3 {\n\t\t\t\t\t\tcase '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':\n\t\t\t\t\t\t\tvalue = value*16 | (c3 - '0')\n\t\t\t\t\t\tcase 'a', 'b', 'c', 'd', 'e', 'f':\n\t\t\t\t\t\t\tvalue = value*16 | (c3 + 10 - 'a')\n\t\t\t\t\t\tcase 'A', 'B', 'C', 'D', 'E', 'F':\n\t\t\t\t\t\t\tvalue = value*16 | (c3 + 10 - 'A')\n\t\t\t\t\t\tcase '}':\n\t\t\t\t\t\t\tif isFirst {\n\t\t\t\t\t\t\t\treturn nil, false, start + i - width3\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak variableLength\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn nil, false, start + i - width3\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif value > utf8.MaxRune {\n\t\t\t\t\t\t\tisOutOfRange = true\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tisFirst = false\n\t\t\t\t\t}\n\n\t\t\t\t\tif isOutOfRange && reportErrors {\n\t\t\t\t\t\tlexer.addRangeError(logger.Range{Loc: logger.Loc{Start: int32(start + hexStart)}, Len: int32(i - hexStart)},\n\t\t\t\t\t\t\t\"Unicode escape sequence is out of range\")\n\t\t\t\t\t\tpanic(LexerPanic{})\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Fixed-length\n\t\t\t\t\tfor j := 0; j < 4; j++ {\n\t\t\t\t\t\tswitch c3 {\n\t\t\t\t\t\tcase '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':\n\t\t\t\t\t\t\tvalue = value*16 | (c3 - '0')\n\t\t\t\t\t\tcase 'a', 'b', 'c', 'd', 'e', 'f':\n\t\t\t\t\t\t\tvalue = value*16 | (c3 + 10 - 'a')\n\t\t\t\t\t\tcase 'A', 'B', 'C', 'D', 'E', 'F':\n\t\t\t\t\t\t\tvalue = value*16 | (c3 + 10 - 'A')\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn nil, false, start + i - width3\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif j < 3 {\n\t\t\t\t\t\t\tc3, width3 = utf8.DecodeRuneInString(text[i:])\n\t\t\t\t\t\t\ti += width3\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tc = value\n\n\t\t\tcase '\\r':\n\t\t\t\tif lexer.json == JSON {\n\t\t\t\t\treturn nil, false, start + i - width2\n\t\t\t\t}\n\n\t\t\t\t// Ignore line continuations. A line continuation is not an escaped newline.\n\t\t\t\tif i < len(text) && text[i] == '\\n' {\n\t\t\t\t\t// Make sure Windows CRLF counts as a single newline\n\t\t\t\t\ti++\n\t\t\t\t}\n\t\t\t\tcontinue\n\n\t\t\tcase '\\n', '\\u2028', '\\u2029':\n\t\t\t\tif lexer.json == JSON {\n\t\t\t\t\treturn nil, false, start + i - width2\n\t\t\t\t}\n\n\t\t\t\t// Ignore line continuations. A line continuation is not an escaped newline.\n\t\t\t\tcontinue\n\n\t\t\tdefault:\n\t\t\t\tif lexer.json == JSON {\n\t\t\t\t\tswitch c2 {\n\t\t\t\t\tcase '\"', '\\\\', '/':\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn nil, false, start + i - width2\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tc = c2\n\t\t\t}\n\t\t}\n\n\t\tif c <= 0xFFFF {\n\t\t\tdecoded = append(decoded, uint16(c))\n\t\t} else {\n\t\t\tc -= 0x10000\n\t\t\tdecoded = append(decoded, uint16(0xD800+((c>>10)&0x3FF)), uint16(0xDC00+(c&0x3FF)))\n\t\t}\n\t}\n\n\treturn decoded, true, 0\n}\n\nfunc (lexer *Lexer) RescanCloseBraceAsTemplateToken() {\n\tif lexer.Token != TCloseBrace {\n\t\tlexer.Expected(TCloseBrace)\n\t}\n\n\tlexer.rescanCloseBraceAsTemplateToken = true\n\tlexer.codePoint = '`'\n\tlexer.current = lexer.end\n\tlexer.end -= 1\n\tlexer.Next()\n\tlexer.rescanCloseBraceAsTemplateToken = false\n}\n\nfunc (lexer *Lexer) step() {\n\tcodePoint, width := utf8.DecodeRuneInString(lexer.source.Contents[lexer.current:])\n\n\t// Use -1 to indicate the end of the file\n\tif width == 0 {\n\t\tcodePoint = -1\n\t}\n\n\t// Track the approximate number of newlines in the file so we can preallocate\n\t// the line offset table in the printer for source maps. The line offset table\n\t// is the #1 highest allocation in the heap profile, so this is worth doing.\n\t// This count is approximate because it handles \"\\n\" and \"\\r\\n\" (the common\n\t// cases) but not \"\\r\" or \"\\u2028\" or \"\\u2029\". Getting this wrong is harmless\n\t// because it's only a preallocation. The array will just grow if it's too small.\n\tif codePoint == '\\n' {\n\t\tlexer.ApproximateNewlineCount++\n\t}\n\n\tlexer.codePoint = codePoint\n\tlexer.end = lexer.current\n\tlexer.current += width\n}\n\nfunc (lexer *Lexer) addRangeError(r logger.Range, text string) {\n\t// Don't report multiple errors in the same spot\n\tif r.Loc == lexer.prevErrorLoc {\n\t\treturn\n\t}\n\tlexer.prevErrorLoc = r.Loc\n\n\tif !lexer.IsLogDisabled {\n\t\tlexer.log.AddError(&lexer.tracker, r, text)\n\t}\n}\n\nfunc (lexer *Lexer) addRangeErrorWithSuggestion(r logger.Range, text string, suggestion string) {\n\t// Don't report multiple errors in the same spot\n\tif r.Loc == lexer.prevErrorLoc {\n\t\treturn\n\t}\n\tlexer.prevErrorLoc = r.Loc\n\n\tif !lexer.IsLogDisabled {\n\t\tdata := lexer.tracker.MsgData(r, text)\n\t\tdata.Location.Suggestion = suggestion\n\t\tlexer.log.AddMsg(logger.Msg{Kind: logger.Error, Data: data})\n\t}\n}\n\nfunc (lexer *Lexer) AddRangeErrorWithNotes(r logger.Range, text string, notes []logger.MsgData) {\n\t// Don't report multiple errors in the same spot\n\tif r.Loc == lexer.prevErrorLoc {\n\t\treturn\n\t}\n\tlexer.prevErrorLoc = r.Loc\n\n\tif !lexer.IsLogDisabled {\n\t\tlexer.log.AddErrorWithNotes(&lexer.tracker, r, text, notes)\n\t}\n}\n\nfunc hasPrefixWithWordBoundary(text string, prefix string) bool {\n\tt := len(text)\n\tp := len(prefix)\n\tif t >= p && text[0:p] == prefix {\n\t\tif t == p {\n\t\t\treturn true\n\t\t}\n\t\tc, _ := utf8.DecodeRuneInString(text[p:])\n\t\tif !js_ast.IsIdentifierContinue(c) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\ntype pragmaArg uint8\n\nconst (\n\tpragmaNoSpaceFirst pragmaArg = iota\n\tpragmaSkipSpaceFirst\n)\n\nfunc scanForPragmaArg(kind pragmaArg, start int, pragma string, text string) (logger.Span, bool) {\n\ttext = text[len(pragma):]\n\tstart += len(pragma)\n\n\tif text == \"\" {\n\t\treturn logger.Span{}, false\n\t}\n\n\t// One or more whitespace characters\n\tc, width := utf8.DecodeRuneInString(text)\n\tif kind == pragmaSkipSpaceFirst {\n\t\tif !js_ast.IsWhitespace(c) {\n\t\t\treturn logger.Span{}, false\n\t\t}\n\t\tfor js_ast.IsWhitespace(c) {\n\t\t\ttext = text[width:]\n\t\t\tstart += width\n\t\t\tif text == \"\" {\n\t\t\t\treturn logger.Span{}, false\n\t\t\t}\n\t\t\tc, width = utf8.DecodeRuneInString(text)\n\t\t}\n\t}\n\n\t// One or more non-whitespace characters\n\ti := 0\n\tfor !js_ast.IsWhitespace(c) {\n\t\ti += width\n\t\tif i >= len(text) {\n\t\t\tbreak\n\t\t}\n\t\tc, width = utf8.DecodeRuneInString(text[i:])\n\t\tif js_ast.IsWhitespace(c) {\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn logger.Span{\n\t\tText: text[:i],\n\t\tRange: logger.Range{\n\t\t\tLoc: logger.Loc{Start: int32(start)},\n\t\t\tLen: int32(i),\n\t\t},\n\t}, true\n}\n\nfunc isUpperASCII(c byte) bool {\n\treturn c >= 'A' && c <= 'Z'\n}\n\nfunc isLetterASCII(c byte) bool {\n\treturn (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')\n}\n\nfunc (lexer *Lexer) scanCommentText() {\n\ttext := lexer.source.Contents[lexer.start:lexer.end]\n\thasLegalAnnotation := len(text) > 2 && text[2] == '!'\n\tisMultiLineComment := text[1] == '*'\n\tomitFromGeneralCommentPreservation := false\n\n\t// Save the original comment text so we can subtract comments from the\n\t// character frequency analysis used by symbol minification\n\tlexer.AllComments = append(lexer.AllComments, lexer.Range())\n\n\t// Omit the trailing \"*/\" from the checks below\n\tendOfCommentText := len(text)\n\tif isMultiLineComment {\n\t\tendOfCommentText -= 2\n\t}\n\n\tfor i, n := 0, len(text); i < n; i++ {\n\t\tswitch text[i] {\n\t\tcase '#':\n\t\t\trest := text[i+1 : endOfCommentText]\n\t\t\tif hasPrefixWithWordBoundary(rest, \"__PURE__\") {\n\t\t\t\tomitFromGeneralCommentPreservation = true\n\t\t\t\tlexer.HasCommentBefore |= PureCommentBefore\n\t\t\t} else if hasPrefixWithWordBoundary(rest, \"__KEY__\") {\n\t\t\t\tomitFromGeneralCommentPreservation = true\n\t\t\t\tlexer.HasCommentBefore |= KeyCommentBefore\n\t\t\t} else if hasPrefixWithWordBoundary(rest, \"__NO_SIDE_EFFECTS__\") {\n\t\t\t\tomitFromGeneralCommentPreservation = true\n\t\t\t\tlexer.HasCommentBefore |= NoSideEffectsCommentBefore\n\t\t\t} else if i == 2 && strings.HasPrefix(rest, \" sourceMappingURL=\") {\n\t\t\t\tif arg, ok := scanForPragmaArg(pragmaNoSpaceFirst, lexer.start+i+1, \" sourceMappingURL=\", rest); ok {\n\t\t\t\t\tomitFromGeneralCommentPreservation = true\n\t\t\t\t\tlexer.SourceMappingURL = arg\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase '@':\n\t\t\trest := text[i+1 : endOfCommentText]\n\t\t\tif hasPrefixWithWordBoundary(rest, \"__PURE__\") {\n\t\t\t\tomitFromGeneralCommentPreservation = true\n\t\t\t\tlexer.HasCommentBefore |= PureCommentBefore\n\t\t\t} else if hasPrefixWithWordBoundary(rest, \"__KEY__\") {\n\t\t\t\tomitFromGeneralCommentPreservation = true\n\t\t\t\tlexer.HasCommentBefore |= KeyCommentBefore\n\t\t\t} else if hasPrefixWithWordBoundary(rest, \"__NO_SIDE_EFFECTS__\") {\n\t\t\t\tomitFromGeneralCommentPreservation = true\n\t\t\t\tlexer.HasCommentBefore |= NoSideEffectsCommentBefore\n\t\t\t} else if hasPrefixWithWordBoundary(rest, \"preserve\") || hasPrefixWithWordBoundary(rest, \"license\") {\n\t\t\t\thasLegalAnnotation = true\n\t\t\t} else if hasPrefixWithWordBoundary(rest, \"jsx\") {\n\t\t\t\tif arg, ok := scanForPragmaArg(pragmaSkipSpaceFirst, lexer.start+i+1, \"jsx\", rest); ok {\n\t\t\t\t\tlexer.JSXFactoryPragmaComment = arg\n\t\t\t\t}\n\t\t\t} else if hasPrefixWithWordBoundary(rest, \"jsxFrag\") {\n\t\t\t\tif arg, ok := scanForPragmaArg(pragmaSkipSpaceFirst, lexer.start+i+1, \"jsxFrag\", rest); ok {\n\t\t\t\t\tlexer.JSXFragmentPragmaComment = arg\n\t\t\t\t}\n\t\t\t} else if hasPrefixWithWordBoundary(rest, \"jsxRuntime\") {\n\t\t\t\tif arg, ok := scanForPragmaArg(pragmaSkipSpaceFirst, lexer.start+i+1, \"jsxRuntime\", rest); ok {\n\t\t\t\t\tlexer.JSXRuntimePragmaComment = arg\n\t\t\t\t}\n\t\t\t} else if hasPrefixWithWordBoundary(rest, \"jsxImportSource\") {\n\t\t\t\tif arg, ok := scanForPragmaArg(pragmaSkipSpaceFirst, lexer.start+i+1, \"jsxImportSource\", rest); ok {\n\t\t\t\t\tlexer.JSXImportSourcePragmaComment = arg\n\t\t\t\t}\n\t\t\t} else if i == 2 && strings.HasPrefix(rest, \" sourceMappingURL=\") {\n\t\t\t\tif arg, ok := scanForPragmaArg(pragmaNoSpaceFirst, lexer.start+i+1, \" sourceMappingURL=\", rest); ok {\n\t\t\t\t\tomitFromGeneralCommentPreservation = true\n\t\t\t\t\tlexer.SourceMappingURL = arg\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif hasLegalAnnotation {\n\t\tlexer.LegalCommentsBeforeToken = append(lexer.LegalCommentsBeforeToken, lexer.Range())\n\t}\n\n\tif !omitFromGeneralCommentPreservation {\n\t\tlexer.CommentsBeforeToken = append(lexer.CommentsBeforeToken, lexer.Range())\n\t}\n}\n"
  },
  {
    "path": "internal/js_lexer/js_lexer_test.go",
    "content": "package js_lexer\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"strings\"\n\t\"testing\"\n\t\"unicode/utf8\"\n\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/test\"\n)\n\nfunc assertEqualStrings(t *testing.T, a string, b string) {\n\tt.Helper()\n\tpretty := func(text string) string {\n\t\tbuilder := strings.Builder{}\n\t\tbuilder.WriteRune('\"')\n\t\ti := 0\n\t\tfor i < len(text) {\n\t\t\tc, width := utf8.DecodeRuneInString(text[i:])\n\t\t\tbuilder.WriteString(fmt.Sprintf(\"\\\\u{%X}\", c))\n\t\t\ti += width\n\t\t}\n\t\tbuilder.WriteRune('\"')\n\t\treturn builder.String()\n\t}\n\tif a != b {\n\t\tt.Fatalf(\"%s != %s\", pretty(a), pretty(b))\n\t}\n}\n\nfunc lexToken(contents string) T {\n\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\tlexer := NewLexer(log, test.SourceForTest(contents), config.TSOptions{})\n\treturn lexer.Token\n}\n\nfunc expectLexerError(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\tt.Run(contents, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\t\tfunc() {\n\t\t\tdefer func() {\n\t\t\t\tr := recover()\n\t\t\t\tif _, isLexerPanic := r.(LexerPanic); r != nil && !isLexerPanic {\n\t\t\t\t\tpanic(r)\n\t\t\t\t}\n\t\t\t}()\n\t\t\tNewLexer(log, test.SourceForTest(contents), config.TSOptions{})\n\t\t}()\n\t\tmsgs := log.Done()\n\t\tvar text strings.Builder\n\t\tfor _, msg := range msgs {\n\t\t\ttext.WriteString(msg.String(logger.OutputOptions{}, logger.TerminalInfo{}))\n\t\t}\n\t\ttest.AssertEqual(t, text.String(), expected)\n\t})\n}\n\nfunc TestComment(t *testing.T) {\n\texpectLexerError(t, \"/*\", \"<stdin>: ERROR: Expected \\\"*/\\\" to terminate multi-line comment\\n<stdin>: NOTE: The multi-line comment starts here:\\n\")\n\texpectLexerError(t, \"/*/\", \"<stdin>: ERROR: Expected \\\"*/\\\" to terminate multi-line comment\\n<stdin>: NOTE: The multi-line comment starts here:\\n\")\n\texpectLexerError(t, \"/**/\", \"\")\n\texpectLexerError(t, \"//\", \"\")\n}\n\nfunc expectHashbang(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\tt.Run(contents, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\t\tlexer := func() Lexer {\n\t\t\tdefer func() {\n\t\t\t\tr := recover()\n\t\t\t\tif _, isLexerPanic := r.(LexerPanic); r != nil && !isLexerPanic {\n\t\t\t\t\tpanic(r)\n\t\t\t\t}\n\t\t\t}()\n\t\t\treturn NewLexer(log, test.SourceForTest(contents), config.TSOptions{})\n\t\t}()\n\t\tmsgs := log.Done()\n\t\ttest.AssertEqual(t, len(msgs), 0)\n\t\ttest.AssertEqual(t, lexer.Token, THashbang)\n\t\ttest.AssertEqual(t, lexer.Identifier.String, expected)\n\t})\n}\n\nfunc TestHashbang(t *testing.T) {\n\texpectHashbang(t, \"#!/usr/bin/env node\", \"#!/usr/bin/env node\")\n\texpectHashbang(t, \"#!/usr/bin/env node\\n\", \"#!/usr/bin/env node\")\n\texpectHashbang(t, \"#!/usr/bin/env node\\nlet x\", \"#!/usr/bin/env node\")\n\texpectLexerError(t, \" #!/usr/bin/env node\", \"<stdin>: ERROR: Syntax error \\\"!\\\"\\n\")\n}\n\nfunc expectIdentifier(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\tt.Run(contents, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\t\tlexer := func() Lexer {\n\t\t\tdefer func() {\n\t\t\t\tr := recover()\n\t\t\t\tif _, isLexerPanic := r.(LexerPanic); r != nil && !isLexerPanic {\n\t\t\t\t\tpanic(r)\n\t\t\t\t}\n\t\t\t}()\n\t\t\treturn NewLexer(log, test.SourceForTest(contents), config.TSOptions{})\n\t\t}()\n\t\tmsgs := log.Done()\n\t\ttest.AssertEqual(t, len(msgs), 0)\n\t\ttest.AssertEqual(t, lexer.Token, TIdentifier)\n\t\ttest.AssertEqual(t, lexer.Identifier.String, expected)\n\t})\n}\n\nfunc TestIdentifier(t *testing.T) {\n\texpectIdentifier(t, \"_\", \"_\")\n\texpectIdentifier(t, \"$\", \"$\")\n\texpectIdentifier(t, \"test\", \"test\")\n\texpectIdentifier(t, \"t\\\\u0065st\", \"test\")\n\texpectIdentifier(t, \"t\\\\u{65}st\", \"test\")\n\n\texpectLexerError(t, \"t\\\\u.\", \"<stdin>: ERROR: Syntax error \\\".\\\"\\n\")\n\texpectLexerError(t, \"t\\\\u0.\", \"<stdin>: ERROR: Syntax error \\\".\\\"\\n\")\n\texpectLexerError(t, \"t\\\\u00.\", \"<stdin>: ERROR: Syntax error \\\".\\\"\\n\")\n\texpectLexerError(t, \"t\\\\u006.\", \"<stdin>: ERROR: Syntax error \\\".\\\"\\n\")\n\texpectLexerError(t, \"t\\\\u{.\", \"<stdin>: ERROR: Syntax error \\\".\\\"\\n\")\n\texpectLexerError(t, \"t\\\\u{0.\", \"<stdin>: ERROR: Syntax error \\\".\\\"\\n\")\n\n\texpectIdentifier(t, \"a\\u200C\", \"a\\u200C\")\n\texpectIdentifier(t, \"a\\u200D\", \"a\\u200D\")\n\texpectIdentifier(t, \"a\\u200Cb\", \"a\\u200Cb\")\n\texpectIdentifier(t, \"a\\u200Db\", \"a\\u200Db\")\n}\n\nfunc expectNumber(t *testing.T, contents string, expected float64) {\n\tt.Helper()\n\tt.Run(contents, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\t\tlexer := func() Lexer {\n\t\t\tdefer func() {\n\t\t\t\tr := recover()\n\t\t\t\tif _, isLexerPanic := r.(LexerPanic); r != nil && !isLexerPanic {\n\t\t\t\t\tpanic(r)\n\t\t\t\t}\n\t\t\t}()\n\t\t\treturn NewLexer(log, test.SourceForTest(contents), config.TSOptions{})\n\t\t}()\n\t\tmsgs := log.Done()\n\t\ttest.AssertEqual(t, len(msgs), 0)\n\t\ttest.AssertEqual(t, lexer.Token, TNumericLiteral)\n\t\ttest.AssertEqual(t, lexer.Number, expected)\n\t})\n}\n\nfunc TestNumericLiteral(t *testing.T) {\n\texpectNumber(t, \"0\", 0.0)\n\texpectNumber(t, \"000\", 0.0)\n\texpectNumber(t, \"010\", 8.0)\n\texpectNumber(t, \"123\", 123.0)\n\texpectNumber(t, \"987\", 987.0)\n\texpectNumber(t, \"0000\", 0.0)\n\texpectNumber(t, \"0123\", 83.0)\n\texpectNumber(t, \"0123.4567\", 83.0)\n\texpectNumber(t, \"0987\", 987.0)\n\texpectNumber(t, \"0987.6543\", 987.6543)\n\texpectNumber(t, \"01289\", 1289.0)\n\texpectNumber(t, \"01289.345\", 1289.0)\n\texpectNumber(t, \"999999999\", 999999999.0)\n\texpectNumber(t, \"9999999999\", 9999999999.0)\n\texpectNumber(t, \"99999999999\", 99999999999.0)\n\texpectNumber(t, \"123456789123456789\", 123456789123456780.0)\n\texpectNumber(t, \"123456789123456789\"+strings.Repeat(\"0\", 128), 1.2345678912345679e+145)\n\n\texpectNumber(t, \"0b00101\", 5.0)\n\texpectNumber(t, \"0B00101\", 5.0)\n\texpectNumber(t, \"0b1011101011101011101011101011101011101\", 100352251741.0)\n\texpectNumber(t, \"0B1011101011101011101011101011101011101\", 100352251741.0)\n\texpectLexerError(t, \"0b\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \"0B\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \"0b012\", \"<stdin>: ERROR: Syntax error \\\"2\\\"\\n\")\n\texpectLexerError(t, \"0b018\", \"<stdin>: ERROR: Syntax error \\\"8\\\"\\n\")\n\texpectLexerError(t, \"0b01a\", \"<stdin>: ERROR: Syntax error \\\"a\\\"\\n\")\n\texpectLexerError(t, \"0b01A\", \"<stdin>: ERROR: Syntax error \\\"A\\\"\\n\")\n\n\texpectNumber(t, \"0o12345\", 5349.0)\n\texpectNumber(t, \"0O12345\", 5349.0)\n\texpectNumber(t, \"0o1234567654321\", 89755965649.0)\n\texpectNumber(t, \"0O1234567654321\", 89755965649.0)\n\texpectLexerError(t, \"0o\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \"0O\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \"0o018\", \"<stdin>: ERROR: Syntax error \\\"8\\\"\\n\")\n\texpectLexerError(t, \"0o01a\", \"<stdin>: ERROR: Syntax error \\\"a\\\"\\n\")\n\texpectLexerError(t, \"0o01A\", \"<stdin>: ERROR: Syntax error \\\"A\\\"\\n\")\n\n\texpectNumber(t, \"0x12345678\", float64(0x12345678))\n\texpectNumber(t, \"0xFEDCBA987\", float64(0xFEDCBA987))\n\texpectNumber(t, \"0x000012345678\", float64(0x12345678))\n\texpectNumber(t, \"0x123456781234\", float64(0x123456781234))\n\texpectLexerError(t, \"0x\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \"0X\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \"0xGFEDCBA\", \"<stdin>: ERROR: Syntax error \\\"G\\\"\\n\")\n\texpectLexerError(t, \"0xABCDEFG\", \"<stdin>: ERROR: Syntax error \\\"G\\\"\\n\")\n\n\texpectNumber(t, \"123.\", 123.0)\n\texpectNumber(t, \".0123\", 0.0123)\n\texpectNumber(t, \"0.0123\", 0.0123)\n\texpectNumber(t, \"2.2250738585072014e-308\", 2.2250738585072014e-308)\n\texpectNumber(t, \"1.7976931348623157e+308\", 1.7976931348623157e+308)\n\n\t// Underflow\n\texpectNumber(t, \"4.9406564584124654417656879286822e-324\", 5e-324)\n\texpectNumber(t, \"5e-324\", 5e-324)\n\texpectNumber(t, \"1e-325\", 0.0)\n\n\t// Overflow\n\texpectNumber(t, \"1.797693134862315708145274237317e+308\", 1.7976931348623157e+308)\n\texpectNumber(t, \"1.797693134862315808e+308\", math.Inf(1))\n\texpectNumber(t, \"1e+309\", math.Inf(1))\n\n\t// int32\n\texpectNumber(t, \"0x7fff_ffff\", 2147483647.0)\n\texpectNumber(t, \"0x8000_0000\", 2147483648.0)\n\texpectNumber(t, \"0x8000_0001\", 2147483649.0)\n\n\t// uint32\n\texpectNumber(t, \"0xffff_ffff\", 4294967295.0)\n\texpectNumber(t, \"0x1_0000_0000\", 4294967296.0)\n\texpectNumber(t, \"0x1_0000_0001\", 4294967297.0)\n\n\t// int64\n\texpectNumber(t, \"0x7fff_ffff_ffff_fdff\", 9223372036854774784)\n\texpectNumber(t, \"0x8000_0000_0000_0000\", 9.223372036854776e+18)\n\texpectNumber(t, \"0x8000_0000_0000_3000\", 9.223372036854788e+18)\n\n\t// uint64\n\texpectNumber(t, \"0xffff_ffff_ffff_fbff\", 1.844674407370955e+19)\n\texpectNumber(t, \"0x1_0000_0000_0000_0000\", 1.8446744073709552e+19)\n\texpectNumber(t, \"0x1_0000_0000_0000_1000\", 1.8446744073709556e+19)\n\n\texpectNumber(t, \"1.\", 1.0)\n\texpectNumber(t, \".1\", 0.1)\n\texpectNumber(t, \"1.1\", 1.1)\n\texpectNumber(t, \"1e1\", 10.0)\n\texpectNumber(t, \"1e+1\", 10.0)\n\texpectNumber(t, \"1e-1\", 0.1)\n\texpectNumber(t, \".1e1\", 1.0)\n\texpectNumber(t, \".1e+1\", 1.0)\n\texpectNumber(t, \".1e-1\", 0.01)\n\texpectNumber(t, \"1.e1\", 10.0)\n\texpectNumber(t, \"1.e+1\", 10.0)\n\texpectNumber(t, \"1.e-1\", 0.1)\n\texpectNumber(t, \"1.1e1\", 11.0)\n\texpectNumber(t, \"1.1e+1\", 11.0)\n\texpectNumber(t, \"1.1e-1\", 0.11)\n\n\texpectLexerError(t, \"1e\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \".1e\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \"1.e\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \"1.1e\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \"1e+\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \".1e+\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \"1.e+\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \"1.1e+\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \"1e-\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \".1e-\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \"1.e-\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \"1.1e-\", \"<stdin>: ERROR: Unexpected end of file\\n\")\n\texpectLexerError(t, \"1e+-1\", \"<stdin>: ERROR: Syntax error \\\"-\\\"\\n\")\n\texpectLexerError(t, \"1e-+1\", \"<stdin>: ERROR: Syntax error \\\"+\\\"\\n\")\n\n\texpectLexerError(t, \"1z\", \"<stdin>: ERROR: Syntax error \\\"z\\\"\\n\")\n\texpectLexerError(t, \"1.z\", \"<stdin>: ERROR: Syntax error \\\"z\\\"\\n\")\n\texpectLexerError(t, \"1.0f\", \"<stdin>: ERROR: Syntax error \\\"f\\\"\\n\")\n\texpectLexerError(t, \"0b1z\", \"<stdin>: ERROR: Syntax error \\\"z\\\"\\n\")\n\texpectLexerError(t, \"0o1z\", \"<stdin>: ERROR: Syntax error \\\"z\\\"\\n\")\n\texpectLexerError(t, \"0x1z\", \"<stdin>: ERROR: Syntax error \\\"z\\\"\\n\")\n\texpectLexerError(t, \"1e1z\", \"<stdin>: ERROR: Syntax error \\\"z\\\"\\n\")\n\n\texpectNumber(t, \"1_2_3\", 123)\n\texpectNumber(t, \".1_2\", 0.12)\n\texpectNumber(t, \"1_2.3_4\", 12.34)\n\texpectNumber(t, \"1e2_3\", 1e23)\n\texpectNumber(t, \"1_2e3_4\", 12e34)\n\texpectNumber(t, \"1_2.3_4e5_6\", 12.34e56)\n\texpectNumber(t, \"0b1_0\", 2)\n\texpectNumber(t, \"0B1_0\", 2)\n\texpectNumber(t, \"0o1_2\", 10)\n\texpectNumber(t, \"0O1_2\", 10)\n\texpectNumber(t, \"0x1_2\", 0x12)\n\texpectNumber(t, \"0X1_2\", 0x12)\n\texpectNumber(t, \"08.0_1\", 8.01)\n\texpectNumber(t, \"09.0_1\", 9.01)\n\n\texpectLexerError(t, \"0_0\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0_1\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0_7\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0_8\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0_9\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"00_0\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"01_0\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"07_0\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"08_0\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"09_0\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"08_0.1\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"09_0.1\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\n\texpectLexerError(t, \"1__2\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \".1__2\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"1e2__3\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0b1__0\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0B1__0\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0o1__2\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0O1__2\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0x1__2\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0X1__2\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\n\texpectLexerError(t, \"1_\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"1._\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"1_.\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \".1_\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"1e_\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"1e1_\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"1_e1\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \".1_e1\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"1._2\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"1_.2\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0b_1\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0B_1\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0o_1\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0O_1\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0x_1\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0X_1\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0b1_\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0B1_\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0o1_\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0O1_\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0x1_\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n\texpectLexerError(t, \"0X1_\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n}\n\nfunc expectBigInteger(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\tt.Run(contents, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\t\tlexer := func() Lexer {\n\t\t\tdefer func() {\n\t\t\t\tr := recover()\n\t\t\t\tif _, isLexerPanic := r.(LexerPanic); r != nil && !isLexerPanic {\n\t\t\t\t\tpanic(r)\n\t\t\t\t}\n\t\t\t}()\n\t\t\treturn NewLexer(log, test.SourceForTest(contents), config.TSOptions{})\n\t\t}()\n\t\tmsgs := log.Done()\n\t\ttest.AssertEqual(t, len(msgs), 0)\n\t\ttest.AssertEqual(t, lexer.Token, TBigIntegerLiteral)\n\t\ttest.AssertEqual(t, lexer.Identifier.String, expected)\n\t})\n}\n\nfunc TestBigIntegerLiteral(t *testing.T) {\n\texpectBigInteger(t, \"0n\", \"0\")\n\texpectBigInteger(t, \"123n\", \"123\")\n\texpectBigInteger(t, \"9007199254740993n\", \"9007199254740993\") // This can't fit in a float64\n\n\texpectBigInteger(t, \"0b00101n\", \"0b00101\")\n\texpectBigInteger(t, \"0B00101n\", \"0B00101\")\n\texpectBigInteger(t, \"0b1011101011101011101011101011101011101n\", \"0b1011101011101011101011101011101011101\")\n\texpectBigInteger(t, \"0B1011101011101011101011101011101011101n\", \"0B1011101011101011101011101011101011101\")\n\n\texpectBigInteger(t, \"0o12345n\", \"0o12345\")\n\texpectBigInteger(t, \"0O12345n\", \"0O12345\")\n\texpectBigInteger(t, \"0o1234567654321n\", \"0o1234567654321\")\n\texpectBigInteger(t, \"0O1234567654321n\", \"0O1234567654321\")\n\n\texpectBigInteger(t, \"0x12345678n\", \"0x12345678\")\n\texpectBigInteger(t, \"0xFEDCBA987n\", \"0xFEDCBA987\")\n\texpectBigInteger(t, \"0x000012345678n\", \"0x000012345678\")\n\texpectBigInteger(t, \"0x123456781234n\", \"0x123456781234\")\n\n\texpectBigInteger(t, \"1_2_3n\", \"123\")\n\texpectBigInteger(t, \"0b1_0_1n\", \"0b101\")\n\texpectBigInteger(t, \"0o1_2_3n\", \"0o123\")\n\texpectBigInteger(t, \"0x1_2_3n\", \"0x123\")\n\n\texpectLexerError(t, \"1e2n\", \"<stdin>: ERROR: Syntax error \\\"n\\\"\\n\")\n\texpectLexerError(t, \"1.0n\", \"<stdin>: ERROR: Syntax error \\\"n\\\"\\n\")\n\texpectLexerError(t, \".1n\", \"<stdin>: ERROR: Syntax error \\\"n\\\"\\n\")\n\texpectLexerError(t, \"000n\", \"<stdin>: ERROR: Syntax error \\\"n\\\"\\n\")\n\texpectLexerError(t, \"0123n\", \"<stdin>: ERROR: Syntax error \\\"n\\\"\\n\")\n\texpectLexerError(t, \"089n\", \"<stdin>: ERROR: Syntax error \\\"n\\\"\\n\")\n\texpectLexerError(t, \"0_1n\", \"<stdin>: ERROR: Syntax error \\\"_\\\"\\n\")\n}\n\nfunc expectString(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\tt.Run(contents, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\t\tlexer := func() Lexer {\n\t\t\tdefer func() {\n\t\t\t\tr := recover()\n\t\t\t\tif _, isLexerPanic := r.(LexerPanic); r != nil && !isLexerPanic {\n\t\t\t\t\tpanic(r)\n\t\t\t\t}\n\t\t\t}()\n\t\t\treturn NewLexer(log, test.SourceForTest(contents), config.TSOptions{})\n\t\t}()\n\t\ttext := lexer.StringLiteral()\n\t\tmsgs := log.Done()\n\t\ttest.AssertEqual(t, len(msgs), 0)\n\t\ttest.AssertEqual(t, lexer.Token, TStringLiteral)\n\t\tassertEqualStrings(t, helpers.UTF16ToString(text), expected)\n\t})\n}\n\nfunc expectLexerErrorString(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\tt.Run(contents, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\t\tfunc() {\n\t\t\tdefer func() {\n\t\t\t\tr := recover()\n\t\t\t\tif _, isLexerPanic := r.(LexerPanic); r != nil && !isLexerPanic {\n\t\t\t\t\tpanic(r)\n\t\t\t\t}\n\t\t\t}()\n\t\t\tlexer := NewLexer(log, test.SourceForTest(contents), config.TSOptions{})\n\t\t\tlexer.StringLiteral()\n\t\t}()\n\t\tmsgs := log.Done()\n\t\tvar text strings.Builder\n\t\tfor _, msg := range msgs {\n\t\t\ttext.WriteString(msg.String(logger.OutputOptions{}, logger.TerminalInfo{}))\n\t\t}\n\t\ttest.AssertEqual(t, text.String(), expected)\n\t})\n}\n\nfunc TestStringLiteral(t *testing.T) {\n\texpectString(t, \"''\", \"\")\n\texpectString(t, \"'123'\", \"123\")\n\n\texpectString(t, \"'\\\"'\", \"\\\"\")\n\texpectString(t, \"'\\\\''\", \"'\")\n\texpectString(t, \"'\\\\\\\"'\", \"\\\"\")\n\texpectString(t, \"'\\\\\\\\'\", \"\\\\\")\n\texpectString(t, \"'\\\\a'\", \"a\")\n\texpectString(t, \"'\\\\b'\", \"\\b\")\n\texpectString(t, \"'\\\\f'\", \"\\f\")\n\texpectString(t, \"'\\\\n'\", \"\\n\")\n\texpectString(t, \"'\\\\r'\", \"\\r\")\n\texpectString(t, \"'\\\\t'\", \"\\t\")\n\texpectString(t, \"'\\\\v'\", \"\\v\")\n\n\texpectString(t, \"'\\\\0'\", \"\\000\")\n\texpectString(t, \"'\\\\1'\", \"\\001\")\n\texpectString(t, \"'\\\\2'\", \"\\002\")\n\texpectString(t, \"'\\\\3'\", \"\\003\")\n\texpectString(t, \"'\\\\4'\", \"\\004\")\n\texpectString(t, \"'\\\\5'\", \"\\005\")\n\texpectString(t, \"'\\\\6'\", \"\\006\")\n\texpectString(t, \"'\\\\7'\", \"\\007\")\n\n\texpectString(t, \"'\\\\000'\", \"\\000\")\n\texpectString(t, \"'\\\\001'\", \"\\001\")\n\texpectString(t, \"'\\\\002'\", \"\\002\")\n\texpectString(t, \"'\\\\003'\", \"\\003\")\n\texpectString(t, \"'\\\\004'\", \"\\004\")\n\texpectString(t, \"'\\\\005'\", \"\\005\")\n\texpectString(t, \"'\\\\006'\", \"\\006\")\n\texpectString(t, \"'\\\\007'\", \"\\007\")\n\n\texpectString(t, \"'\\\\000'\", \"\\000\")\n\texpectString(t, \"'\\\\100'\", \"\\100\")\n\texpectString(t, \"'\\\\200'\", \"\\u0080\")\n\texpectString(t, \"'\\\\300'\", \"\\u00C0\")\n\texpectString(t, \"'\\\\377'\", \"\\u00FF\")\n\texpectString(t, \"'\\\\378'\", \"\\0378\")\n\texpectString(t, \"'\\\\400'\", \"\\0400\")\n\texpectString(t, \"'\\\\500'\", \"\\0500\")\n\texpectString(t, \"'\\\\600'\", \"\\0600\")\n\texpectString(t, \"'\\\\700'\", \"\\0700\")\n\n\texpectString(t, \"'\\\\x00'\", \"\\x00\")\n\texpectString(t, \"'\\\\X11'\", \"X11\")\n\texpectString(t, \"'\\\\x71'\", \"\\x71\")\n\texpectString(t, \"'\\\\x7f'\", \"\\x7f\")\n\texpectString(t, \"'\\\\x7F'\", \"\\x7F\")\n\n\texpectString(t, \"'\\\\u0000'\", \"\\u0000\")\n\texpectString(t, \"'\\\\ucafe\\\\uCAFE\\\\u7FFF'\", \"\\ucafe\\uCAFE\\u7FFF\")\n\texpectString(t, \"'\\\\uD800'\", \"\\xED\\xA0\\x80\")\n\texpectString(t, \"'\\\\uDC00'\", \"\\xED\\xB0\\x80\")\n\texpectString(t, \"'\\\\U0000'\", \"U0000\")\n\n\texpectString(t, \"'\\\\u{100000}'\", \"\\U00100000\")\n\texpectString(t, \"'\\\\u{10FFFF}'\", \"\\U0010FFFF\")\n\texpectLexerErrorString(t, \"'\\\\u{110000}'\", \"<stdin>: ERROR: Unicode escape sequence is out of range\\n\")\n\texpectLexerErrorString(t, \"'\\\\u{FFFFFFFF}'\", \"<stdin>: ERROR: Unicode escape sequence is out of range\\n\")\n\n\t// Line continuation\n\texpectLexerErrorString(t, \"'\\n'\", \"<stdin>: ERROR: Unterminated string literal\\n\")\n\texpectLexerErrorString(t, \"'\\r'\", \"<stdin>: ERROR: Unterminated string literal\\n\")\n\texpectLexerErrorString(t, \"\\\"\\n\\\"\", \"<stdin>: ERROR: Unterminated string literal\\n\")\n\texpectLexerErrorString(t, \"\\\"\\r\\\"\", \"<stdin>: ERROR: Unterminated string literal\\n\")\n\n\texpectString(t, \"'\\u2028'\", \"\\u2028\")\n\texpectString(t, \"'\\u2029'\", \"\\u2029\")\n\texpectString(t, \"\\\"\\u2028\\\"\", \"\\u2028\")\n\texpectString(t, \"\\\"\\u2029\\\"\", \"\\u2029\")\n\n\texpectString(t, \"'1\\\\\\r2'\", \"12\")\n\texpectString(t, \"'1\\\\\\n2'\", \"12\")\n\texpectString(t, \"'1\\\\\\r\\n2'\", \"12\")\n\texpectString(t, \"'1\\\\\\u20282'\", \"12\")\n\texpectString(t, \"'1\\\\\\u20292'\", \"12\")\n\texpectLexerErrorString(t, \"'1\\\\\\n\\r2'\", \"<stdin>: ERROR: Unterminated string literal\\n\")\n\n\texpectLexerErrorString(t, \"\\\"'\", \"<stdin>: ERROR: Unterminated string literal\\n\")\n\texpectLexerErrorString(t, \"'\\\"\", \"<stdin>: ERROR: Unterminated string literal\\n\")\n\texpectLexerErrorString(t, \"'\\\\\", \"<stdin>: ERROR: Unterminated string literal\\n\")\n\texpectLexerErrorString(t, \"'\\\\'\", \"<stdin>: ERROR: Unterminated string literal\\n\")\n\n\texpectLexerErrorString(t, \"'\\\\x\", \"<stdin>: ERROR: Unterminated string literal\\n\")\n\texpectLexerErrorString(t, \"'\\\\x'\", \"<stdin>: ERROR: Syntax error \\\"'\\\"\\n\")\n\texpectLexerErrorString(t, \"'\\\\xG'\", \"<stdin>: ERROR: Syntax error \\\"G\\\"\\n\")\n\texpectLexerErrorString(t, \"'\\\\xF'\", \"<stdin>: ERROR: Syntax error \\\"'\\\"\\n\")\n\texpectLexerErrorString(t, \"'\\\\xFG'\", \"<stdin>: ERROR: Syntax error \\\"G\\\"\\n\")\n\n\texpectLexerErrorString(t, \"'\\\\u\", \"<stdin>: ERROR: Unterminated string literal\\n\")\n\texpectLexerErrorString(t, \"'\\\\u'\", \"<stdin>: ERROR: Syntax error \\\"'\\\"\\n\")\n\texpectLexerErrorString(t, \"'\\\\u0'\", \"<stdin>: ERROR: Syntax error \\\"'\\\"\\n\")\n\texpectLexerErrorString(t, \"'\\\\u00'\", \"<stdin>: ERROR: Syntax error \\\"'\\\"\\n\")\n\texpectLexerErrorString(t, \"'\\\\u000'\", \"<stdin>: ERROR: Syntax error \\\"'\\\"\\n\")\n}\n\nfunc TestTokens(t *testing.T) {\n\texpected := []struct {\n\t\tcontents string\n\t\ttoken    T\n\t}{\n\t\t{\"\", TEndOfFile},\n\t\t{\"\\x00\", TSyntaxError},\n\n\t\t// \"#!/usr/bin/env node\"\n\t\t{\"#!\", THashbang},\n\n\t\t// Punctuation\n\t\t{\"(\", TOpenParen},\n\t\t{\")\", TCloseParen},\n\t\t{\"[\", TOpenBracket},\n\t\t{\"]\", TCloseBracket},\n\t\t{\"{\", TOpenBrace},\n\t\t{\"}\", TCloseBrace},\n\n\t\t// Reserved words\n\t\t{\"break\", TBreak},\n\t\t{\"case\", TCase},\n\t\t{\"catch\", TCatch},\n\t\t{\"class\", TClass},\n\t\t{\"const\", TConst},\n\t\t{\"continue\", TContinue},\n\t\t{\"debugger\", TDebugger},\n\t\t{\"default\", TDefault},\n\t\t{\"delete\", TDelete},\n\t\t{\"do\", TDo},\n\t\t{\"else\", TElse},\n\t\t{\"enum\", TEnum},\n\t\t{\"export\", TExport},\n\t\t{\"extends\", TExtends},\n\t\t{\"false\", TFalse},\n\t\t{\"finally\", TFinally},\n\t\t{\"for\", TFor},\n\t\t{\"function\", TFunction},\n\t\t{\"if\", TIf},\n\t\t{\"import\", TImport},\n\t\t{\"in\", TIn},\n\t\t{\"instanceof\", TInstanceof},\n\t\t{\"new\", TNew},\n\t\t{\"null\", TNull},\n\t\t{\"return\", TReturn},\n\t\t{\"super\", TSuper},\n\t\t{\"switch\", TSwitch},\n\t\t{\"this\", TThis},\n\t\t{\"throw\", TThrow},\n\t\t{\"true\", TTrue},\n\t\t{\"try\", TTry},\n\t\t{\"typeof\", TTypeof},\n\t\t{\"var\", TVar},\n\t\t{\"void\", TVoid},\n\t\t{\"while\", TWhile},\n\t\t{\"with\", TWith},\n\t}\n\n\tfor _, it := range expected {\n\t\tcontents := it.contents\n\t\ttoken := it.token\n\t\tt.Run(contents, func(t *testing.T) {\n\t\t\ttest.AssertEqual(t, lexToken(contents), token)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/js_lexer/tables.go",
    "content": "package js_lexer\n\nvar tokenToString = map[T]string{\n\tTEndOfFile:   \"end of file\",\n\tTSyntaxError: \"syntax error\",\n\tTHashbang:    \"hashbang comment\",\n\n\t// Literals\n\tTNoSubstitutionTemplateLiteral: \"template literal\",\n\tTNumericLiteral:                \"number\",\n\tTStringLiteral:                 \"string\",\n\tTBigIntegerLiteral:             \"bigint\",\n\n\t// Pseudo-literals\n\tTTemplateHead:   \"template literal\",\n\tTTemplateMiddle: \"template literal\",\n\tTTemplateTail:   \"template literal\",\n\n\t// Punctuation\n\tTAmpersand:                         \"\\\"&\\\"\",\n\tTAmpersandAmpersand:                \"\\\"&&\\\"\",\n\tTAsterisk:                          \"\\\"*\\\"\",\n\tTAsteriskAsterisk:                  \"\\\"**\\\"\",\n\tTAt:                                \"\\\"@\\\"\",\n\tTBar:                               \"\\\"|\\\"\",\n\tTBarBar:                            \"\\\"||\\\"\",\n\tTCaret:                             \"\\\"^\\\"\",\n\tTCloseBrace:                        \"\\\"}\\\"\",\n\tTCloseBracket:                      \"\\\"]\\\"\",\n\tTCloseParen:                        \"\\\")\\\"\",\n\tTColon:                             \"\\\":\\\"\",\n\tTComma:                             \"\\\",\\\"\",\n\tTDot:                               \"\\\".\\\"\",\n\tTDotDotDot:                         \"\\\"...\\\"\",\n\tTEqualsEquals:                      \"\\\"==\\\"\",\n\tTEqualsEqualsEquals:                \"\\\"===\\\"\",\n\tTEqualsGreaterThan:                 \"\\\"=>\\\"\",\n\tTExclamation:                       \"\\\"!\\\"\",\n\tTExclamationEquals:                 \"\\\"!=\\\"\",\n\tTExclamationEqualsEquals:           \"\\\"!==\\\"\",\n\tTGreaterThan:                       \"\\\">\\\"\",\n\tTGreaterThanEquals:                 \"\\\">=\\\"\",\n\tTGreaterThanGreaterThan:            \"\\\">>\\\"\",\n\tTGreaterThanGreaterThanGreaterThan: \"\\\">>>\\\"\",\n\tTLessThan:                          \"\\\"<\\\"\",\n\tTLessThanEquals:                    \"\\\"<=\\\"\",\n\tTLessThanLessThan:                  \"\\\"<<\\\"\",\n\tTMinus:                             \"\\\"-\\\"\",\n\tTMinusMinus:                        \"\\\"--\\\"\",\n\tTOpenBrace:                         \"\\\"{\\\"\",\n\tTOpenBracket:                       \"\\\"[\\\"\",\n\tTOpenParen:                         \"\\\"(\\\"\",\n\tTPercent:                           \"\\\"%\\\"\",\n\tTPlus:                              \"\\\"+\\\"\",\n\tTPlusPlus:                          \"\\\"++\\\"\",\n\tTQuestion:                          \"\\\"?\\\"\",\n\tTQuestionDot:                       \"\\\"?.\\\"\",\n\tTQuestionQuestion:                  \"\\\"??\\\"\",\n\tTSemicolon:                         \"\\\";\\\"\",\n\tTSlash:                             \"\\\"/\\\"\",\n\tTTilde:                             \"\\\"~\\\"\",\n\n\t// Assignments\n\tTAmpersandAmpersandEquals:                \"\\\"&&=\\\"\",\n\tTAmpersandEquals:                         \"\\\"&=\\\"\",\n\tTAsteriskAsteriskEquals:                  \"\\\"**=\\\"\",\n\tTAsteriskEquals:                          \"\\\"*=\\\"\",\n\tTBarBarEquals:                            \"\\\"||=\\\"\",\n\tTBarEquals:                               \"\\\"|=\\\"\",\n\tTCaretEquals:                             \"\\\"^=\\\"\",\n\tTEquals:                                  \"\\\"=\\\"\",\n\tTGreaterThanGreaterThanEquals:            \"\\\">>=\\\"\",\n\tTGreaterThanGreaterThanGreaterThanEquals: \"\\\">>>=\\\"\",\n\tTLessThanLessThanEquals:                  \"\\\"<<=\\\"\",\n\tTMinusEquals:                             \"\\\"-=\\\"\",\n\tTPercentEquals:                           \"\\\"%=\\\"\",\n\tTPlusEquals:                              \"\\\"+=\\\"\",\n\tTQuestionQuestionEquals:                  \"\\\"??=\\\"\",\n\tTSlashEquals:                             \"\\\"/=\\\"\",\n\n\t// Class-private fields and methods\n\tTPrivateIdentifier: \"private identifier\",\n\n\t// Identifiers\n\tTIdentifier:     \"identifier\",\n\tTEscapedKeyword: \"escaped keyword\",\n\n\t// Reserved words\n\tTBreak:      \"\\\"break\\\"\",\n\tTCase:       \"\\\"case\\\"\",\n\tTCatch:      \"\\\"catch\\\"\",\n\tTClass:      \"\\\"class\\\"\",\n\tTConst:      \"\\\"const\\\"\",\n\tTContinue:   \"\\\"continue\\\"\",\n\tTDebugger:   \"\\\"debugger\\\"\",\n\tTDefault:    \"\\\"default\\\"\",\n\tTDelete:     \"\\\"delete\\\"\",\n\tTDo:         \"\\\"do\\\"\",\n\tTElse:       \"\\\"else\\\"\",\n\tTEnum:       \"\\\"enum\\\"\",\n\tTExport:     \"\\\"export\\\"\",\n\tTExtends:    \"\\\"extends\\\"\",\n\tTFalse:      \"\\\"false\\\"\",\n\tTFinally:    \"\\\"finally\\\"\",\n\tTFor:        \"\\\"for\\\"\",\n\tTFunction:   \"\\\"function\\\"\",\n\tTIf:         \"\\\"if\\\"\",\n\tTImport:     \"\\\"import\\\"\",\n\tTIn:         \"\\\"in\\\"\",\n\tTInstanceof: \"\\\"instanceof\\\"\",\n\tTNew:        \"\\\"new\\\"\",\n\tTNull:       \"\\\"null\\\"\",\n\tTReturn:     \"\\\"return\\\"\",\n\tTSuper:      \"\\\"super\\\"\",\n\tTSwitch:     \"\\\"switch\\\"\",\n\tTThis:       \"\\\"this\\\"\",\n\tTThrow:      \"\\\"throw\\\"\",\n\tTTrue:       \"\\\"true\\\"\",\n\tTTry:        \"\\\"try\\\"\",\n\tTTypeof:     \"\\\"typeof\\\"\",\n\tTVar:        \"\\\"var\\\"\",\n\tTVoid:       \"\\\"void\\\"\",\n\tTWhile:      \"\\\"while\\\"\",\n\tTWith:       \"\\\"with\\\"\",\n}\n\n// This is from https://github.com/microsoft/TypeScript/blob/master/src/compiler/transformers/jsx.ts\nvar jsxEntity = map[string]rune{\n\t\"quot\":     0x0022,\n\t\"amp\":      0x0026,\n\t\"apos\":     0x0027,\n\t\"lt\":       0x003C,\n\t\"gt\":       0x003E,\n\t\"nbsp\":     0x00A0,\n\t\"iexcl\":    0x00A1,\n\t\"cent\":     0x00A2,\n\t\"pound\":    0x00A3,\n\t\"curren\":   0x00A4,\n\t\"yen\":      0x00A5,\n\t\"brvbar\":   0x00A6,\n\t\"sect\":     0x00A7,\n\t\"uml\":      0x00A8,\n\t\"copy\":     0x00A9,\n\t\"ordf\":     0x00AA,\n\t\"laquo\":    0x00AB,\n\t\"not\":      0x00AC,\n\t\"shy\":      0x00AD,\n\t\"reg\":      0x00AE,\n\t\"macr\":     0x00AF,\n\t\"deg\":      0x00B0,\n\t\"plusmn\":   0x00B1,\n\t\"sup2\":     0x00B2,\n\t\"sup3\":     0x00B3,\n\t\"acute\":    0x00B4,\n\t\"micro\":    0x00B5,\n\t\"para\":     0x00B6,\n\t\"middot\":   0x00B7,\n\t\"cedil\":    0x00B8,\n\t\"sup1\":     0x00B9,\n\t\"ordm\":     0x00BA,\n\t\"raquo\":    0x00BB,\n\t\"frac14\":   0x00BC,\n\t\"frac12\":   0x00BD,\n\t\"frac34\":   0x00BE,\n\t\"iquest\":   0x00BF,\n\t\"Agrave\":   0x00C0,\n\t\"Aacute\":   0x00C1,\n\t\"Acirc\":    0x00C2,\n\t\"Atilde\":   0x00C3,\n\t\"Auml\":     0x00C4,\n\t\"Aring\":    0x00C5,\n\t\"AElig\":    0x00C6,\n\t\"Ccedil\":   0x00C7,\n\t\"Egrave\":   0x00C8,\n\t\"Eacute\":   0x00C9,\n\t\"Ecirc\":    0x00CA,\n\t\"Euml\":     0x00CB,\n\t\"Igrave\":   0x00CC,\n\t\"Iacute\":   0x00CD,\n\t\"Icirc\":    0x00CE,\n\t\"Iuml\":     0x00CF,\n\t\"ETH\":      0x00D0,\n\t\"Ntilde\":   0x00D1,\n\t\"Ograve\":   0x00D2,\n\t\"Oacute\":   0x00D3,\n\t\"Ocirc\":    0x00D4,\n\t\"Otilde\":   0x00D5,\n\t\"Ouml\":     0x00D6,\n\t\"times\":    0x00D7,\n\t\"Oslash\":   0x00D8,\n\t\"Ugrave\":   0x00D9,\n\t\"Uacute\":   0x00DA,\n\t\"Ucirc\":    0x00DB,\n\t\"Uuml\":     0x00DC,\n\t\"Yacute\":   0x00DD,\n\t\"THORN\":    0x00DE,\n\t\"szlig\":    0x00DF,\n\t\"agrave\":   0x00E0,\n\t\"aacute\":   0x00E1,\n\t\"acirc\":    0x00E2,\n\t\"atilde\":   0x00E3,\n\t\"auml\":     0x00E4,\n\t\"aring\":    0x00E5,\n\t\"aelig\":    0x00E6,\n\t\"ccedil\":   0x00E7,\n\t\"egrave\":   0x00E8,\n\t\"eacute\":   0x00E9,\n\t\"ecirc\":    0x00EA,\n\t\"euml\":     0x00EB,\n\t\"igrave\":   0x00EC,\n\t\"iacute\":   0x00ED,\n\t\"icirc\":    0x00EE,\n\t\"iuml\":     0x00EF,\n\t\"eth\":      0x00F0,\n\t\"ntilde\":   0x00F1,\n\t\"ograve\":   0x00F2,\n\t\"oacute\":   0x00F3,\n\t\"ocirc\":    0x00F4,\n\t\"otilde\":   0x00F5,\n\t\"ouml\":     0x00F6,\n\t\"divide\":   0x00F7,\n\t\"oslash\":   0x00F8,\n\t\"ugrave\":   0x00F9,\n\t\"uacute\":   0x00FA,\n\t\"ucirc\":    0x00FB,\n\t\"uuml\":     0x00FC,\n\t\"yacute\":   0x00FD,\n\t\"thorn\":    0x00FE,\n\t\"yuml\":     0x00FF,\n\t\"OElig\":    0x0152,\n\t\"oelig\":    0x0153,\n\t\"Scaron\":   0x0160,\n\t\"scaron\":   0x0161,\n\t\"Yuml\":     0x0178,\n\t\"fnof\":     0x0192,\n\t\"circ\":     0x02C6,\n\t\"tilde\":    0x02DC,\n\t\"Alpha\":    0x0391,\n\t\"Beta\":     0x0392,\n\t\"Gamma\":    0x0393,\n\t\"Delta\":    0x0394,\n\t\"Epsilon\":  0x0395,\n\t\"Zeta\":     0x0396,\n\t\"Eta\":      0x0397,\n\t\"Theta\":    0x0398,\n\t\"Iota\":     0x0399,\n\t\"Kappa\":    0x039A,\n\t\"Lambda\":   0x039B,\n\t\"Mu\":       0x039C,\n\t\"Nu\":       0x039D,\n\t\"Xi\":       0x039E,\n\t\"Omicron\":  0x039F,\n\t\"Pi\":       0x03A0,\n\t\"Rho\":      0x03A1,\n\t\"Sigma\":    0x03A3,\n\t\"Tau\":      0x03A4,\n\t\"Upsilon\":  0x03A5,\n\t\"Phi\":      0x03A6,\n\t\"Chi\":      0x03A7,\n\t\"Psi\":      0x03A8,\n\t\"Omega\":    0x03A9,\n\t\"alpha\":    0x03B1,\n\t\"beta\":     0x03B2,\n\t\"gamma\":    0x03B3,\n\t\"delta\":    0x03B4,\n\t\"epsilon\":  0x03B5,\n\t\"zeta\":     0x03B6,\n\t\"eta\":      0x03B7,\n\t\"theta\":    0x03B8,\n\t\"iota\":     0x03B9,\n\t\"kappa\":    0x03BA,\n\t\"lambda\":   0x03BB,\n\t\"mu\":       0x03BC,\n\t\"nu\":       0x03BD,\n\t\"xi\":       0x03BE,\n\t\"omicron\":  0x03BF,\n\t\"pi\":       0x03C0,\n\t\"rho\":      0x03C1,\n\t\"sigmaf\":   0x03C2,\n\t\"sigma\":    0x03C3,\n\t\"tau\":      0x03C4,\n\t\"upsilon\":  0x03C5,\n\t\"phi\":      0x03C6,\n\t\"chi\":      0x03C7,\n\t\"psi\":      0x03C8,\n\t\"omega\":    0x03C9,\n\t\"thetasym\": 0x03D1,\n\t\"upsih\":    0x03D2,\n\t\"piv\":      0x03D6,\n\t\"ensp\":     0x2002,\n\t\"emsp\":     0x2003,\n\t\"thinsp\":   0x2009,\n\t\"zwnj\":     0x200C,\n\t\"zwj\":      0x200D,\n\t\"lrm\":      0x200E,\n\t\"rlm\":      0x200F,\n\t\"ndash\":    0x2013,\n\t\"mdash\":    0x2014,\n\t\"lsquo\":    0x2018,\n\t\"rsquo\":    0x2019,\n\t\"sbquo\":    0x201A,\n\t\"ldquo\":    0x201C,\n\t\"rdquo\":    0x201D,\n\t\"bdquo\":    0x201E,\n\t\"dagger\":   0x2020,\n\t\"Dagger\":   0x2021,\n\t\"bull\":     0x2022,\n\t\"hellip\":   0x2026,\n\t\"permil\":   0x2030,\n\t\"prime\":    0x2032,\n\t\"Prime\":    0x2033,\n\t\"lsaquo\":   0x2039,\n\t\"rsaquo\":   0x203A,\n\t\"oline\":    0x203E,\n\t\"frasl\":    0x2044,\n\t\"euro\":     0x20AC,\n\t\"image\":    0x2111,\n\t\"weierp\":   0x2118,\n\t\"real\":     0x211C,\n\t\"trade\":    0x2122,\n\t\"alefsym\":  0x2135,\n\t\"larr\":     0x2190,\n\t\"uarr\":     0x2191,\n\t\"rarr\":     0x2192,\n\t\"darr\":     0x2193,\n\t\"harr\":     0x2194,\n\t\"crarr\":    0x21B5,\n\t\"lArr\":     0x21D0,\n\t\"uArr\":     0x21D1,\n\t\"rArr\":     0x21D2,\n\t\"dArr\":     0x21D3,\n\t\"hArr\":     0x21D4,\n\t\"forall\":   0x2200,\n\t\"part\":     0x2202,\n\t\"exist\":    0x2203,\n\t\"empty\":    0x2205,\n\t\"nabla\":    0x2207,\n\t\"isin\":     0x2208,\n\t\"notin\":    0x2209,\n\t\"ni\":       0x220B,\n\t\"prod\":     0x220F,\n\t\"sum\":      0x2211,\n\t\"minus\":    0x2212,\n\t\"lowast\":   0x2217,\n\t\"radic\":    0x221A,\n\t\"prop\":     0x221D,\n\t\"infin\":    0x221E,\n\t\"ang\":      0x2220,\n\t\"and\":      0x2227,\n\t\"or\":       0x2228,\n\t\"cap\":      0x2229,\n\t\"cup\":      0x222A,\n\t\"int\":      0x222B,\n\t\"there4\":   0x2234,\n\t\"sim\":      0x223C,\n\t\"cong\":     0x2245,\n\t\"asymp\":    0x2248,\n\t\"ne\":       0x2260,\n\t\"equiv\":    0x2261,\n\t\"le\":       0x2264,\n\t\"ge\":       0x2265,\n\t\"sub\":      0x2282,\n\t\"sup\":      0x2283,\n\t\"nsub\":     0x2284,\n\t\"sube\":     0x2286,\n\t\"supe\":     0x2287,\n\t\"oplus\":    0x2295,\n\t\"otimes\":   0x2297,\n\t\"perp\":     0x22A5,\n\t\"sdot\":     0x22C5,\n\t\"lceil\":    0x2308,\n\t\"rceil\":    0x2309,\n\t\"lfloor\":   0x230A,\n\t\"rfloor\":   0x230B,\n\t\"lang\":     0x2329,\n\t\"rang\":     0x232A,\n\t\"loz\":      0x25CA,\n\t\"spades\":   0x2660,\n\t\"clubs\":    0x2663,\n\t\"hearts\":   0x2665,\n\t\"diams\":    0x2666,\n}\n"
  },
  {
    "path": "internal/js_parser/global_name_parser.go",
    "content": "package js_parser\n\nimport (\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_lexer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\nfunc ParseGlobalName(log logger.Log, source logger.Source) (result []string, ok bool) {\n\tok = true\n\tdefer func() {\n\t\tr := recover()\n\t\tif _, isLexerPanic := r.(js_lexer.LexerPanic); isLexerPanic {\n\t\t\tok = false\n\t\t} else if r != nil {\n\t\t\tpanic(r)\n\t\t}\n\t}()\n\n\tlexer := js_lexer.NewLexerGlobalName(log, source)\n\n\t// Start off with an identifier or a keyword that results in an object\n\tresult = append(result, lexer.Identifier.String)\n\tswitch lexer.Token {\n\tcase js_lexer.TThis:\n\t\tlexer.Next()\n\n\tcase js_lexer.TImport:\n\t\t// Handle \"import.meta\"\n\t\tlexer.Next()\n\t\tlexer.Expect(js_lexer.TDot)\n\t\tresult = append(result, lexer.Identifier.String)\n\t\tlexer.ExpectContextualKeyword(\"meta\")\n\n\tdefault:\n\t\tlexer.Expect(js_lexer.TIdentifier)\n\t}\n\n\t// Follow with dot or index expressions\n\tfor lexer.Token != js_lexer.TEndOfFile {\n\t\tswitch lexer.Token {\n\t\tcase js_lexer.TDot:\n\t\t\tlexer.Next()\n\t\t\tif !lexer.IsIdentifierOrKeyword() {\n\t\t\t\tlexer.Expect(js_lexer.TIdentifier)\n\t\t\t}\n\t\t\tresult = append(result, lexer.Identifier.String)\n\t\t\tlexer.Next()\n\n\t\tcase js_lexer.TOpenBracket:\n\t\t\tlexer.Next()\n\t\t\tresult = append(result, helpers.UTF16ToString(lexer.StringLiteral()))\n\t\t\tlexer.Expect(js_lexer.TStringLiteral)\n\t\t\tlexer.Expect(js_lexer.TCloseBracket)\n\n\t\tdefault:\n\t\t\tlexer.Expect(js_lexer.TDot)\n\t\t}\n\t}\n\n\treturn\n}\n"
  },
  {
    "path": "internal/js_parser/js_parser.go",
    "content": "package js_parser\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"math/big\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/js_lexer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/renamer\"\n\t\"github.com/evanw/esbuild/internal/runtime\"\n)\n\n// This parser does two passes:\n//\n// 1. Parse the source into an AST, create the scope tree, and declare symbols.\n//\n//  2. Visit each node in the AST, bind identifiers to declared symbols, do\n//     constant folding, substitute compile-time variable definitions, and\n//     lower certain syntactic constructs as appropriate given the language\n//     target.\n//\n// So many things have been put in so few passes because we want to minimize\n// the number of full-tree passes to improve performance. However, we need\n// to have at least two separate passes to handle variable hoisting. See the\n// comment about scopesInOrder below for more information.\ntype parser struct {\n\toptions                    Options\n\tlog                        logger.Log\n\tsource                     logger.Source\n\ttracker                    logger.LineColumnTracker\n\tfnOrArrowDataParse         fnOrArrowDataParse\n\tfnOnlyDataVisit            fnOnlyDataVisit\n\tallocatedNames             []string\n\tcurrentScope               *js_ast.Scope\n\tscopesForCurrentPart       []*js_ast.Scope\n\tsymbols                    []ast.Symbol\n\tastHelpers                 js_ast.HelperContext\n\ttsUseCounts                []uint32\n\tinjectedDefineSymbols      []ast.Ref\n\tinjectedSymbolSources      map[ast.Ref]injectedSymbolSource\n\tinjectedDotNames           map[string][]injectedDotName\n\tdropLabelsMap              map[string]struct{}\n\texprComments               map[logger.Loc][]string\n\tmangledProps               map[string]ast.Ref\n\treservedProps              map[string]bool\n\tsymbolUses                 map[ast.Ref]js_ast.SymbolUse\n\timportSymbolPropertyUses   map[ast.Ref]map[string]js_ast.SymbolUse\n\tsymbolCallUses             map[ast.Ref]js_ast.SymbolCallUse\n\tdeclaredSymbols            []js_ast.DeclaredSymbol\n\tglobPatternImports         []globPatternImport\n\truntimeImports             map[string]ast.LocRef\n\tduplicateCaseChecker       duplicateCaseChecker\n\tunrepresentableIdentifiers map[string]bool\n\tlegacyOctalLiterals        map[js_ast.E]logger.Range\n\tscopesInOrderForEnum       map[logger.Loc][]scopeOrder\n\tbinaryExprStack            []binaryExprVisitor\n\n\t// For strict mode handling\n\thoistedRefForSloppyModeBlockFn map[ast.Ref]ast.Ref\n\n\t// For lowering private methods\n\tprivateGetters map[ast.Ref]ast.Ref\n\tprivateSetters map[ast.Ref]ast.Ref\n\n\t// These are for TypeScript\n\t//\n\t// We build up enough information about the TypeScript namespace hierarchy to\n\t// be able to resolve scope lookups and property accesses for TypeScript enum\n\t// and namespace features. Each JavaScript scope object inside a namespace\n\t// has a reference to a map of exported namespace members from sibling scopes.\n\t//\n\t// In addition, there is a map from each relevant symbol reference to the data\n\t// associated with that namespace or namespace member: \"refToTSNamespaceMemberData\".\n\t// This gives enough info to be able to resolve queries into the namespace.\n\t//\n\t// When visiting expressions, namespace metadata is associated with the most\n\t// recently visited node. If namespace metadata is present, \"tsNamespaceTarget\"\n\t// will be set to the most recently visited node (as a way to mark that this\n\t// node has metadata) and \"tsNamespaceMemberData\" will be set to the metadata.\n\trefToTSNamespaceMemberData map[ast.Ref]js_ast.TSNamespaceMemberData\n\ttsNamespaceTarget          js_ast.E\n\ttsNamespaceMemberData      js_ast.TSNamespaceMemberData\n\temittedNamespaceVars       map[ast.Ref]bool\n\tisExportedInsideNamespace  map[ast.Ref]ast.Ref\n\tlocalTypeNames             map[string]bool\n\ttsEnums                    map[ast.Ref]map[string]js_ast.TSEnumValue\n\tconstValues                map[ast.Ref]js_ast.ConstValue\n\tpropDerivedCtorValue       js_ast.E\n\tpropMethodDecoratorScope   *js_ast.Scope\n\n\t// This is the reference to the generated function argument for the namespace,\n\t// which is different than the reference to the namespace itself:\n\t//\n\t//   namespace ns {\n\t//   }\n\t//\n\t// The code above is transformed into something like this:\n\t//\n\t//   var ns1;\n\t//   (function(ns2) {\n\t//   })(ns1 || (ns1 = {}));\n\t//\n\t// This variable is \"ns2\" not \"ns1\". It is only used during the second\n\t// \"visit\" pass.\n\tenclosingNamespaceArgRef *ast.Ref\n\n\t// Imports (both ES6 and CommonJS) are tracked at the top level\n\timportRecords               []ast.ImportRecord\n\timportRecordsForCurrentPart []uint32\n\texportStarImportRecords     []uint32\n\n\t// These are for handling ES6 imports and exports\n\timportItemsForNamespace map[ast.Ref]namespaceImportItems\n\tisImportItem            map[ast.Ref]bool\n\tnamedImports            map[ast.Ref]js_ast.NamedImport\n\tnamedExports            map[string]js_ast.NamedExport\n\ttopLevelSymbolToParts   map[ast.Ref][]uint32\n\timportNamespaceCCMap    map[importNamespaceCall]bool\n\n\t// The parser does two passes and we need to pass the scope tree information\n\t// from the first pass to the second pass. That's done by tracking the calls\n\t// to pushScopeForParsePass() and popScope() during the first pass in\n\t// scopesInOrder.\n\t//\n\t// Then, when the second pass calls pushScopeForVisitPass() and popScope(),\n\t// we consume entries from scopesInOrder and make sure they are in the same\n\t// order. This way the second pass can efficiently use the same scope tree\n\t// as the first pass without having to attach the scope tree to the AST.\n\t//\n\t// We need to split this into two passes because the pass that declares the\n\t// symbols must be separate from the pass that binds identifiers to declared\n\t// symbols to handle declaring a hoisted \"var\" symbol in a nested scope and\n\t// binding a name to it in a parent or sibling scope.\n\tscopesInOrder []scopeOrder\n\n\t// These propagate the name from the parent context into an anonymous child\n\t// expression. For example:\n\t//\n\t//   let foo = function() {}\n\t//   assert.strictEqual(foo.name, 'foo')\n\t//\n\tnameToKeep      string\n\tnameToKeepIsFor js_ast.E\n\n\t// These properties are for the visit pass, which runs after the parse pass.\n\t// The visit pass binds identifiers to declared symbols, does constant\n\t// folding, substitutes compile-time variable definitions, and lowers certain\n\t// syntactic constructs as appropriate.\n\tstmtExprValue                        js_ast.E\n\tcallTarget                           js_ast.E\n\tdotOrIndexTarget                     js_ast.E\n\ttemplateTag                          js_ast.E\n\tdeleteTarget                         js_ast.E\n\tloopBody                             js_ast.S\n\tsuspiciousLogicalOperatorInsideArrow js_ast.E\n\tmoduleScope                          *js_ast.Scope\n\n\t// This is internal-only data used for the implementation of Yarn PnP\n\tmanifestForYarnPnP     js_ast.Expr\n\tstringLocalsForYarnPnP map[ast.Ref]stringLocalForYarnPnP\n\n\t// This helps recognize the \"await import()\" pattern. When this is present,\n\t// warnings about non-string import paths will be omitted inside try blocks.\n\tawaitTarget js_ast.E\n\n\t// This helps recognize the \"import().catch()\" pattern. We also try to avoid\n\t// warning about this just like the \"try { await import() }\" pattern.\n\tthenCatchChain thenCatchChain\n\n\t// When bundling, hoisted top-level local variables declared with \"var\" in\n\t// nested scopes are moved up to be declared in the top-level scope instead.\n\t// The old \"var\" statements are turned into regular assignments instead. This\n\t// makes it easier to quickly scan the top-level statements for \"var\" locals\n\t// with the guarantee that all will be found.\n\trelocatedTopLevelVars []ast.LocRef\n\n\t// We need to lower private names such as \"#foo\" if they are used in a brand\n\t// check such as \"#foo in x\" even if the private name syntax would otherwise\n\t// be supported. This is because private names are a newly-added feature.\n\t//\n\t// However, this parser operates in only two passes for speed. The first pass\n\t// parses things and declares variables, and the second pass lowers things and\n\t// resolves references to declared variables. So the existence of a \"#foo in x\"\n\t// expression for a specific \"#foo\" cannot be used to decide to lower \"#foo\"\n\t// because it's too late by that point. There may be another expression such\n\t// as \"x.#foo\" before that point and that must be lowered as well even though\n\t// it has already been visited.\n\t//\n\t// Instead what we do is track just the names of fields used in private brand\n\t// checks during the first pass. This tracks the names themselves, not symbol\n\t// references. Then, during the second pass when we are about to enter into\n\t// a class, we conservatively decide to lower all private names in that class\n\t// which are used in a brand check anywhere in the file.\n\tlowerAllOfThesePrivateNames map[string]bool\n\n\t// Temporary variables used for lowering\n\ttempLetsToDeclare         []ast.Ref\n\ttempRefsToDeclare         []tempRef\n\ttopLevelTempRefsToDeclare []tempRef\n\n\tlexer js_lexer.Lexer\n\n\t// Private field access in a decorator lowers all private fields in that class\n\tparseExperimentalDecoratorNesting int\n\n\t// Temporary variables used for lowering\n\ttempRefCount         int\n\ttopLevelTempRefCount int\n\n\t// We need to scan over the source contents to recover the line and column offsets\n\tjsxSourceLoc    int\n\tjsxSourceLine   int\n\tjsxSourceColumn int\n\n\texportsRef    ast.Ref\n\trequireRef    ast.Ref\n\tmoduleRef     ast.Ref\n\timportMetaRef ast.Ref\n\tpromiseRef    ast.Ref\n\tregExpRef     ast.Ref\n\tbigIntRef     ast.Ref\n\tsuperCtorRef  ast.Ref\n\n\t// Imports from \"react/jsx-runtime\" and \"react\", respectively.\n\t// (Or whatever was specified in the \"importSource\" option)\n\tjsxRuntimeImports map[string]ast.LocRef\n\tjsxLegacyImports  map[string]ast.LocRef\n\n\t// For lowering private methods\n\tweakMapRef ast.Ref\n\tweakSetRef ast.Ref\n\n\tesmImportStatementKeyword logger.Range\n\tesmImportMeta             logger.Range\n\tesmExportKeyword          logger.Range\n\tenclosingClassKeyword     logger.Range\n\ttopLevelAwaitKeyword      logger.Range\n\tliveTopLevelAwaitKeyword  logger.Range\n\n\tlatestArrowArgLoc      logger.Loc\n\tforbidSuffixAfterAsLoc logger.Loc\n\tfirstJSXElementLoc     logger.Loc\n\n\tfnOrArrowDataVisit fnOrArrowDataVisit\n\tsingleStmtDepth    int\n\n\t// ArrowFunction is a special case in the grammar. Although it appears to be\n\t// a PrimaryExpression, it's actually an AssignmentExpression. This means if\n\t// a AssignmentExpression ends up producing an ArrowFunction then nothing can\n\t// come after it other than the comma operator, since the comma operator is\n\t// the only thing above AssignmentExpression under the Expression rule:\n\t//\n\t//   AssignmentExpression:\n\t//     ArrowFunction\n\t//     ConditionalExpression\n\t//     LeftHandSideExpression = AssignmentExpression\n\t//     LeftHandSideExpression AssignmentOperator AssignmentExpression\n\t//\n\t//   Expression:\n\t//     AssignmentExpression\n\t//     Expression , AssignmentExpression\n\t//\n\tafterArrowBodyLoc logger.Loc\n\n\t// Setting this to true disables warnings about code that is very likely to\n\t// be a bug. This is used to ignore issues inside \"node_modules\" directories.\n\t// This has caught real issues in the past. However, it's not esbuild's job\n\t// to find bugs in other libraries, and these warnings are problematic for\n\t// people using these libraries with esbuild. The only fix is to either\n\t// disable all esbuild warnings and not get warnings about your own code, or\n\t// to try to get the warning fixed in the affected library. This is\n\t// especially annoying if the warning is a false positive as was the case in\n\t// https://github.com/firebase/firebase-js-sdk/issues/3814. So these warnings\n\t// are now disabled for code inside \"node_modules\" directories.\n\tsuppressWarningsAboutWeirdCode bool\n\n\t// A file is considered to be an ECMAScript module if it has any of the\n\t// features of one (e.g. the \"export\" keyword), otherwise it's considered\n\t// a CommonJS module.\n\t//\n\t// However, we have a single exception: a file where the only ESM feature\n\t// is the \"import\" keyword is allowed to have CommonJS exports. This feature\n\t// is necessary to be able to synchronously import ESM code into CommonJS,\n\t// which we need to enable in a few important cases. Some examples are:\n\t// our runtime code, injected files (the \"inject\" feature is ESM-only),\n\t// and certain automatically-generated virtual modules from plugins.\n\tisFileConsideredToHaveESMExports bool // Use only for export-related stuff\n\tisFileConsideredESM              bool // Use for all other stuff\n\n\t// Inside a TypeScript namespace, an \"export declare\" statement can be used\n\t// to cause a namespace to be emitted even though it has no other observable\n\t// effect. This flag is used to implement this feature.\n\t//\n\t// Specifically, namespaces should be generated for all of the following\n\t// namespaces below except for \"f\", which should not be generated:\n\t//\n\t//   namespace a { export declare const a }\n\t//   namespace b { export declare let [[b]] }\n\t//   namespace c { export declare function c() }\n\t//   namespace d { export declare class d {} }\n\t//   namespace e { export declare enum e {} }\n\t//   namespace f { export declare namespace f {} }\n\t//\n\t// The TypeScript compiler compiles this into the following code (notice \"f\"\n\t// is missing):\n\t//\n\t//   var a; (function (a_1) {})(a || (a = {}));\n\t//   var b; (function (b_1) {})(b || (b = {}));\n\t//   var c; (function (c_1) {})(c || (c = {}));\n\t//   var d; (function (d_1) {})(d || (d = {}));\n\t//   var e; (function (e_1) {})(e || (e = {}));\n\t//\n\t// Note that this should not be implemented by declaring symbols for \"export\n\t// declare\" statements because the TypeScript compiler doesn't generate any\n\t// code for these statements, so these statements are actually references to\n\t// global variables. There is one exception, which is that local variables\n\t// *should* be declared as symbols because they are replaced with. This seems\n\t// like very arbitrary behavior but it's what the TypeScript compiler does,\n\t// so we try to match it.\n\t//\n\t// Specifically, in the following code below \"a\" and \"b\" should be declared\n\t// and should be substituted with \"ns.a\" and \"ns.b\" but the other symbols\n\t// shouldn't. References to the other symbols actually refer to global\n\t// variables instead of to symbols that are exported from the namespace.\n\t// This is the case as of TypeScript 4.3. I assume this is a TypeScript bug:\n\t//\n\t//   namespace ns {\n\t//     export declare const a\n\t//     export declare let [[b]]\n\t//     export declare function c()\n\t//     export declare class d { }\n\t//     export declare enum e { }\n\t//     console.log(a, b, c, d, e)\n\t//   }\n\t//\n\t// The TypeScript compiler compiles this into the following code:\n\t//\n\t//   var ns;\n\t//   (function (ns) {\n\t//       console.log(ns.a, ns.b, c, d, e);\n\t//   })(ns || (ns = {}));\n\t//\n\t// Relevant issue: https://github.com/evanw/esbuild/issues/1158\n\thasNonLocalExportDeclareInsideNamespace bool\n\n\t// When this flag is enabled, we attempt to fold all expressions that\n\t// TypeScript would consider to be \"constant expressions\". This flag is\n\t// enabled inside each enum body block since TypeScript requires numeric\n\t// constant folding in enum definitions.\n\t//\n\t// We also enable this flag in certain cases in JavaScript files such as when\n\t// parsing \"const\" declarations at the top of a non-ESM file, but we still\n\t// reuse TypeScript's notion of \"constant expressions\" for our own convenience.\n\t//\n\t// As of TypeScript 5.0, a \"constant expression\" is defined as follows:\n\t//\n\t//   An expression is considered a constant expression if it is\n\t//\n\t//   * a number or string literal,\n\t//   * a unary +, -, or ~ applied to a numeric constant expression,\n\t//   * a binary +, -, *, /, %, **, <<, >>, >>>, |, &, ^ applied to two numeric constant expressions,\n\t//   * a binary + applied to two constant expressions whereof at least one is a string,\n\t//   * a template expression where each substitution expression is a constant expression,\n\t//   * a parenthesized constant expression,\n\t//   * a dotted name (e.g. x.y.z) that references a const variable with a constant expression initializer and no type annotation,\n\t//   * a dotted name that references an enum member with an enum literal type, or\n\t//   * a dotted name indexed by a string literal (e.g. x.y[\"z\"]) that references an enum member with an enum literal type.\n\t//\n\t// More detail: https://github.com/microsoft/TypeScript/pull/50528. Note that\n\t// we don't implement certain items in this list. For example, we don't do all\n\t// number-to-string conversions since ours might differ from how JavaScript\n\t// would do it, which would be a correctness issue.\n\tshouldFoldTypeScriptConstantExpressions bool\n\n\tallowIn                     bool\n\thasTopLevelReturn           bool\n\tlatestReturnHadSemicolon    bool\n\tmessageAboutThisIsUndefined bool\n\tisControlFlowDead           bool\n\tshouldAddKeyComment         bool\n\n\t// If this is true, then all top-level statements are wrapped in a try/catch\n\twillWrapModuleInTryCatchForUsing bool\n}\n\ntype globPatternImport struct {\n\tassertOrWith     *ast.ImportAssertOrWith\n\tparts            []helpers.GlobPart\n\tname             string\n\tapproximateRange logger.Range\n\tref              ast.Ref\n\tkind             ast.ImportKind\n\tphase            ast.ImportPhase\n}\n\ntype namespaceImportItems struct {\n\tentries           map[string]ast.LocRef\n\timportRecordIndex uint32\n}\n\ntype stringLocalForYarnPnP struct {\n\tvalue []uint16\n\tloc   logger.Loc\n}\n\ntype injectedSymbolSource struct {\n\tsource logger.Source\n\tloc    logger.Loc\n}\n\ntype injectedDotName struct {\n\tparts               []string\n\tinjectedDefineIndex uint32\n}\n\ntype importNamespaceCallKind uint8\n\nconst (\n\texprKindCall importNamespaceCallKind = iota\n\texprKindNew\n\texprKindJSXTag\n)\n\ntype importNamespaceCall struct {\n\tref  ast.Ref\n\tkind importNamespaceCallKind\n}\n\ntype thenCatchChain struct {\n\tnextTarget      js_ast.E\n\tcatchLoc        logger.Loc\n\thasMultipleArgs bool\n\thasCatch        bool\n}\n\n// This is used as part of an incremental build cache key. Some of these values\n// can potentially change between builds if they are derived from nearby\n// \"package.json\" or \"tsconfig.json\" files that were changed since the last\n// build.\ntype Options struct {\n\tinjectedFiles  []config.InjectedFile\n\tjsx            config.JSXOptions\n\ttsAlwaysStrict *config.TSAlwaysStrict\n\tmangleProps    *regexp.Regexp\n\treserveProps   *regexp.Regexp\n\tdropLabels     []string\n\n\t// This pointer will always be different for each build but the contents\n\t// shouldn't ever behave different semantically. We ignore this field for the\n\t// equality comparison.\n\tdefines *config.ProcessedDefines\n\n\t// This is an embedded struct. Always access these directly instead of off\n\t// the name \"optionsThatSupportStructuralEquality\". This is only grouped like\n\t// this to make the equality comparison easier and safer (and hopefully faster).\n\toptionsThatSupportStructuralEquality\n}\n\ntype optionsThatSupportStructuralEquality struct {\n\toriginalTargetEnv                 string\n\tmoduleTypeData                    js_ast.ModuleTypeData\n\tunsupportedJSFeatures             compat.JSFeature\n\tunsupportedJSFeatureOverrides     compat.JSFeature\n\tunsupportedJSFeatureOverridesMask compat.JSFeature\n\n\t// Byte-sized values go here (gathered together here to keep this object compact)\n\tts                     config.TSOptions\n\tmode                   config.Mode\n\tplatform               config.Platform\n\toutputFormat           config.Format\n\tlogPathStyle           logger.PathStyle\n\tcodePathStyle          logger.PathStyle\n\tasciiOnly              bool\n\tkeepNames              bool\n\tminifySyntax           bool\n\tminifyIdentifiers      bool\n\tminifyWhitespace       bool\n\tomitRuntimeForTests    bool\n\tomitJSXRuntimeForTests bool\n\tignoreDCEAnnotations   bool\n\ttreeShaking            bool\n\tdropDebugger           bool\n\tmangleQuoted           bool\n\n\t// This is an internal-only option used for the implementation of Yarn PnP\n\tdecodeHydrateRuntimeStateYarnPnP bool\n}\n\nfunc OptionsForYarnPnP() Options {\n\treturn Options{\n\t\toptionsThatSupportStructuralEquality: optionsThatSupportStructuralEquality{\n\t\t\tdecodeHydrateRuntimeStateYarnPnP: true,\n\t\t},\n\t}\n}\n\nfunc OptionsFromConfig(options *config.Options) Options {\n\treturn Options{\n\t\tinjectedFiles:  options.InjectedFiles,\n\t\tjsx:            options.JSX,\n\t\tdefines:        options.Defines,\n\t\ttsAlwaysStrict: options.TSAlwaysStrict,\n\t\tmangleProps:    options.MangleProps,\n\t\treserveProps:   options.ReserveProps,\n\t\tdropLabels:     options.DropLabels,\n\n\t\toptionsThatSupportStructuralEquality: optionsThatSupportStructuralEquality{\n\t\t\tunsupportedJSFeatures:             options.UnsupportedJSFeatures,\n\t\t\tunsupportedJSFeatureOverrides:     options.UnsupportedJSFeatureOverrides,\n\t\t\tunsupportedJSFeatureOverridesMask: options.UnsupportedJSFeatureOverridesMask,\n\t\t\toriginalTargetEnv:                 options.OriginalTargetEnv,\n\t\t\tts:                                options.TS,\n\t\t\tmode:                              options.Mode,\n\t\t\tplatform:                          options.Platform,\n\t\t\toutputFormat:                      options.OutputFormat,\n\t\t\tmoduleTypeData:                    options.ModuleTypeData,\n\t\t\tasciiOnly:                         options.ASCIIOnly,\n\t\t\tkeepNames:                         options.KeepNames,\n\t\t\tminifySyntax:                      options.MinifySyntax,\n\t\t\tminifyIdentifiers:                 options.MinifyIdentifiers,\n\t\t\tminifyWhitespace:                  options.MinifyWhitespace,\n\t\t\tomitRuntimeForTests:               options.OmitRuntimeForTests,\n\t\t\tomitJSXRuntimeForTests:            options.OmitJSXRuntimeForTests,\n\t\t\tignoreDCEAnnotations:              options.IgnoreDCEAnnotations,\n\t\t\ttreeShaking:                       options.TreeShaking,\n\t\t\tdropDebugger:                      options.DropDebugger,\n\t\t\tmangleQuoted:                      options.MangleQuoted,\n\t\t\tlogPathStyle:                      options.LogPathStyle,\n\t\t\tcodePathStyle:                     options.CodePathStyle,\n\t\t},\n\t}\n}\n\nfunc (a *Options) Equal(b *Options) bool {\n\t// Compare \"optionsThatSupportStructuralEquality\"\n\tif a.optionsThatSupportStructuralEquality != b.optionsThatSupportStructuralEquality {\n\t\treturn false\n\t}\n\n\t// Compare \"tsAlwaysStrict\"\n\tif (a.tsAlwaysStrict == nil && b.tsAlwaysStrict != nil) || (a.tsAlwaysStrict != nil && b.tsAlwaysStrict == nil) ||\n\t\t(a.tsAlwaysStrict != nil && b.tsAlwaysStrict != nil && *a.tsAlwaysStrict != *b.tsAlwaysStrict) {\n\t\treturn false\n\t}\n\n\t// Compare \"mangleProps\" and \"reserveProps\"\n\tif !isSameRegexp(a.mangleProps, b.mangleProps) || !isSameRegexp(a.reserveProps, b.reserveProps) {\n\t\treturn false\n\t}\n\n\t// Compare \"dropLabels\"\n\tif !helpers.StringArraysEqual(a.dropLabels, b.dropLabels) {\n\t\treturn false\n\t}\n\n\t// Compare \"injectedFiles\"\n\tif len(a.injectedFiles) != len(b.injectedFiles) {\n\t\treturn false\n\t}\n\tfor i, x := range a.injectedFiles {\n\t\ty := b.injectedFiles[i]\n\t\tif x.Source != y.Source || x.DefineName != y.DefineName || len(x.Exports) != len(y.Exports) {\n\t\t\treturn false\n\t\t}\n\t\tfor j := range x.Exports {\n\t\t\tif x.Exports[j] != y.Exports[j] {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compare \"jsx\"\n\tif a.jsx.Parse != b.jsx.Parse || !jsxExprsEqual(a.jsx.Factory, b.jsx.Factory) || !jsxExprsEqual(a.jsx.Fragment, b.jsx.Fragment) {\n\t\treturn false\n\t}\n\n\t// Do a cheap assert that the defines object hasn't changed\n\tif (a.defines != nil || b.defines != nil) && (a.defines == nil || b.defines == nil ||\n\t\tlen(a.defines.IdentifierDefines) != len(b.defines.IdentifierDefines) ||\n\t\tlen(a.defines.DotDefines) != len(b.defines.DotDefines)) {\n\t\tpanic(\"Internal error\")\n\t}\n\n\treturn true\n}\n\nfunc isSameRegexp(a *regexp.Regexp, b *regexp.Regexp) bool {\n\tif a == nil {\n\t\treturn b == nil\n\t} else {\n\t\treturn b != nil && a.String() == b.String()\n\t}\n}\n\nfunc jsxExprsEqual(a config.DefineExpr, b config.DefineExpr) bool {\n\tif !helpers.StringArraysEqual(a.Parts, b.Parts) {\n\t\treturn false\n\t}\n\n\tif a.Constant != nil {\n\t\tif b.Constant == nil || !js_ast.ValuesLookTheSame(a.Constant, b.Constant) {\n\t\t\treturn false\n\t\t}\n\t} else if b.Constant != nil {\n\t\treturn false\n\t}\n\n\treturn true\n}\n\ntype tempRef struct {\n\tvalueOrNil js_ast.Expr\n\tref        ast.Ref\n}\n\nconst (\n\tlocModuleScope = -1\n)\n\ntype scopeOrder struct {\n\tscope *js_ast.Scope\n\tloc   logger.Loc\n}\n\ntype awaitOrYield uint8\n\nconst (\n\t// The keyword is used as an identifier, not a special expression\n\tallowIdent awaitOrYield = iota\n\n\t// Declaring the identifier is forbidden, and the keyword is used as a special expression\n\tallowExpr\n\n\t// Declaring the identifier is forbidden, and using the identifier is also forbidden\n\tforbidAll\n)\n\n// This is function-specific information used during parsing. It is saved and\n// restored on the call stack around code that parses nested functions and\n// arrow expressions.\ntype fnOrArrowDataParse struct {\n\tarrowArgErrors      *deferredArrowArgErrors\n\tdecoratorScope      *js_ast.Scope\n\tasyncRange          logger.Range\n\tneedsAsyncLoc       logger.Loc\n\tawait               awaitOrYield\n\tyield               awaitOrYield\n\tallowSuperCall      bool\n\tallowSuperProperty  bool\n\tisTopLevel          bool\n\tisConstructor       bool\n\tisTypeScriptDeclare bool\n\tisThisDisallowed    bool\n\tisReturnDisallowed  bool\n\n\t// In TypeScript, forward declarations of functions have no bodies\n\tallowMissingBodyForTypeScript bool\n}\n\n// This is function-specific information used during visiting. It is saved and\n// restored on the call stack around code that parses nested functions and\n// arrow expressions.\ntype fnOrArrowDataVisit struct {\n\t// This is used to silence unresolvable imports due to \"require\" calls inside\n\t// a try/catch statement. The assumption is that the try/catch statement is\n\t// there to handle the case where the reference to \"require\" crashes.\n\ttryBodyCount int32\n\ttryCatchLoc  logger.Loc\n\n\tisArrow                        bool\n\tisAsync                        bool\n\tisGenerator                    bool\n\tisInsideLoop                   bool\n\tisInsideSwitch                 bool\n\tisDerivedClassCtor             bool\n\tisOutsideFnOrArrow             bool\n\tshouldLowerSuperPropertyAccess bool\n}\n\n// This is function-specific information used during visiting. It is saved and\n// restored on the call stack around code that parses nested functions (but not\n// nested arrow functions).\ntype fnOnlyDataVisit struct {\n\t// This is a reference to the magic \"arguments\" variable that exists inside\n\t// functions in JavaScript. It will be non-nil inside functions and nil\n\t// otherwise.\n\targumentsRef *ast.Ref\n\n\t// Arrow functions don't capture the value of \"this\" and \"arguments\". Instead,\n\t// the values are inherited from the surrounding context. If arrow functions\n\t// are turned into regular functions due to lowering, we will need to generate\n\t// local variables to capture these values so they are preserved correctly.\n\tthisCaptureRef      *ast.Ref\n\targumentsCaptureRef *ast.Ref\n\n\t// If true, we're inside a static class context where \"this\" expressions\n\t// should be replaced with the class name.\n\tshouldReplaceThisWithInnerClassNameRef bool\n\n\t// This is true if \"this\" is equal to the class name. It's true if we're in a\n\t// static class field initializer, a static class method, or a static class\n\t// block.\n\tisInStaticClassContext bool\n\n\t// This is a reference to the enclosing class name if there is one. It's used\n\t// to implement \"this\" and \"super\" references. A name is automatically generated\n\t// if one is missing so this will always be present inside a class body.\n\tinnerClassNameRef *ast.Ref\n\n\t// If we're inside an async arrow function and async functions are not\n\t// supported, then we will have to convert that arrow function to a generator\n\t// function. That means references to \"arguments\" inside the arrow function\n\t// will have to reference a captured variable instead of the real variable.\n\tisInsideAsyncArrowFn bool\n\n\t// If false, disallow \"new.target\" expressions. We disallow all \"new.target\"\n\t// expressions at the top-level of the file (i.e. not inside a function or\n\t// a class field). Technically since CommonJS files are wrapped in a function\n\t// you can use \"new.target\" in node as an alias for \"undefined\" but we don't\n\t// support that.\n\tisNewTargetAllowed bool\n\n\t// If false, the value for \"this\" is the top-level module scope \"this\" value.\n\t// That means it's \"undefined\" for ECMAScript modules and \"exports\" for\n\t// CommonJS modules. We track this information so that we can substitute the\n\t// correct value for these top-level \"this\" references at compile time instead\n\t// of passing the \"this\" expression through to the output and leaving the\n\t// interpretation up to the run-time behavior of the generated code.\n\t//\n\t// If true, the value for \"this\" is nested inside something (either a function\n\t// or a class declaration). That means the top-level module scope \"this\" value\n\t// has been shadowed and is now inaccessible.\n\tisThisNested bool\n\n\t// If true, \"this\" is used in current function scope.\n\thasThisUsage bool\n\n\t// Do not warn about \"this\" being undefined for code that the TypeScript\n\t// compiler generates that looks like this:\n\t//\n\t//   var __rest = (this && this.__rest) || function (s, e) {\n\t//     ...\n\t//   };\n\t//\n\tsilenceMessageAboutThisBeingUndefined bool\n}\n\ntype livenessStatus int8\n\nconst (\n\talwaysDead      livenessStatus = -1\n\tlivenessUnknown livenessStatus = 0\n\talwaysLive      livenessStatus = 1\n)\n\ntype switchCaseLiveness struct {\n\tstatus         livenessStatus\n\tcanFallThrough bool\n}\n\nfunc analyzeSwitchCasesForLiveness(s *js_ast.SSwitch) []switchCaseLiveness {\n\tcases := make([]switchCaseLiveness, 0, len(s.Cases))\n\tdefaultIndex := -1\n\n\t// Determine the status of the individual cases independently\n\tmaxStatus := alwaysDead\n\tfor i, c := range s.Cases {\n\t\tif c.ValueOrNil.Data == nil {\n\t\t\tdefaultIndex = i\n\t\t}\n\n\t\t// Check the value for strict equality\n\t\tvar status livenessStatus\n\t\tif maxStatus == alwaysLive {\n\t\t\tstatus = alwaysDead // Everything after an always-live case is always dead\n\t\t} else if c.ValueOrNil.Data == nil {\n\t\t\tstatus = alwaysDead // This is the default case, and will be filled in later\n\t\t} else if isEqualToTest, ok := js_ast.CheckEqualityIfNoSideEffects(s.Test.Data, c.ValueOrNil.Data, js_ast.StrictEquality); ok {\n\t\t\tif isEqualToTest {\n\t\t\t\tstatus = alwaysLive // This branch will always be matched, and will be taken unless an earlier branch was taken\n\t\t\t} else {\n\t\t\t\tstatus = alwaysDead // This branch will never be matched, and will not be taken unless there was fall-through\n\t\t\t}\n\t\t} else {\n\t\t\tstatus = livenessUnknown // This branch depends on run-time values and may or may not be matched\n\t\t}\n\t\tif maxStatus < status {\n\t\t\tmaxStatus = status\n\t\t}\n\n\t\tcases = append(cases, switchCaseLiveness{\n\t\t\tstatus:         status,\n\t\t\tcanFallThrough: caseBodyCouldHaveFallThrough(c.Body),\n\t\t})\n\t}\n\n\t// Set the liveness for the default case last based on the other cases\n\tif defaultIndex != -1 {\n\t\t// The negation here transposes \"always live\" with \"always dead\"\n\t\tstatus := -maxStatus\n\t\tif maxStatus < status {\n\t\t\tmaxStatus = status\n\t\t}\n\t\tcases[defaultIndex].status = status\n\t}\n\n\t// Then propagate fall-through information in linear fall-through order\n\tfor i, c := range cases {\n\t\t// Propagate state forward if this isn't dead. Note that the \"can fall\n\t\t// through\" flag does not imply \"must fall through\". The body may have\n\t\t// an embedded \"break\" inside an if statement, for example.\n\t\tif c.status != alwaysDead {\n\t\t\tfor j := i + 1; j < len(cases) && cases[j-1].canFallThrough; j++ {\n\t\t\t\tcases[j].status = livenessUnknown\n\t\t\t}\n\t\t} else if maxStatus > alwaysDead && stmtsCareAboutScope(s.Cases[i].Body) {\n\t\t\t// Since adjacent cases share a scope, dead cases can potentially still\n\t\t\t// affect other cases that are live. Consider the following:\n\t\t\t//\n\t\t\t//   globalThis.foo = true\n\t\t\t//   switch (1) {\n\t\t\t//     case 0:\n\t\t\t//       let foo\n\t\t\t//     case 1:\n\t\t\t//       return foo\n\t\t\t//   }\n\t\t\t//\n\t\t\t// This code is supposed to throw a ReferenceError. But if we treat the\n\t\t\t// first case as dead code, then \"let foo\" will end up being removed and\n\t\t\t// the code will incorrectly return true instead.\n\t\t\tcases[i].status = livenessUnknown\n\t\t}\n\t}\n\treturn cases\n}\n\n// Check for potential fall-through by checking for a jump at the end of the body\nfunc caseBodyCouldHaveFallThrough(stmts []js_ast.Stmt) bool {\n\tfor len(stmts) > 0 {\n\t\tswitch s := stmts[len(stmts)-1].Data.(type) {\n\t\tcase *js_ast.SBlock:\n\t\t\tstmts = s.Stmts // If this ends with a block, check the block's body next\n\t\t\tcontinue\n\t\tcase *js_ast.SBreak, *js_ast.SContinue, *js_ast.SReturn, *js_ast.SThrow:\n\t\t\treturn false\n\t\t}\n\t\tbreak\n\t}\n\treturn true\n}\n\nconst bloomFilterSize = 251\n\ntype duplicateCaseValue struct {\n\tvalue js_ast.Expr\n\thash  uint32\n}\n\ntype duplicateCaseChecker struct {\n\tcases       []duplicateCaseValue\n\tbloomFilter [(bloomFilterSize + 7) / 8]byte\n}\n\nfunc (dc *duplicateCaseChecker) reset() {\n\t// Preserve capacity\n\tdc.cases = dc.cases[:0]\n\n\t// This should be optimized by the compiler. See this for more information:\n\t// https://github.com/golang/go/issues/5373\n\tbytes := dc.bloomFilter\n\tfor i := range bytes {\n\t\tbytes[i] = 0\n\t}\n}\n\nfunc (dc *duplicateCaseChecker) check(p *parser, expr js_ast.Expr) {\n\tif hash, ok := duplicateCaseHash(expr); ok {\n\t\tbucket := hash % bloomFilterSize\n\t\tentry := &dc.bloomFilter[bucket/8]\n\t\tmask := byte(1) << (bucket % 8)\n\n\t\t// Check for collisions\n\t\tif (*entry & mask) != 0 {\n\t\t\tfor _, c := range dc.cases {\n\t\t\t\tif c.hash == hash {\n\t\t\t\t\tif equals, couldBeIncorrect := duplicateCaseEquals(c.value, expr); equals {\n\t\t\t\t\t\tvar laterRange logger.Range\n\t\t\t\t\t\tvar earlierRange logger.Range\n\t\t\t\t\t\tif _, ok := expr.Data.(*js_ast.EString); ok {\n\t\t\t\t\t\t\tlaterRange = p.source.RangeOfString(expr.Loc)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlaterRange = p.source.RangeOfOperatorBefore(expr.Loc, \"case\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif _, ok := c.value.Data.(*js_ast.EString); ok {\n\t\t\t\t\t\t\tearlierRange = p.source.RangeOfString(c.value.Loc)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tearlierRange = p.source.RangeOfOperatorBefore(c.value.Loc, \"case\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttext := \"This case clause will never be evaluated because it duplicates an earlier case clause\"\n\t\t\t\t\t\tif couldBeIncorrect {\n\t\t\t\t\t\t\ttext = \"This case clause may never be evaluated because it likely duplicates an earlier case clause\"\n\t\t\t\t\t\t}\n\t\t\t\t\t\tkind := logger.Warning\n\t\t\t\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\t\t\t\tkind = logger.Debug\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_DuplicateCase, kind, &p.tracker, laterRange, text,\n\t\t\t\t\t\t\t[]logger.MsgData{p.tracker.MsgData(earlierRange, \"The earlier case clause is here:\")})\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t*entry |= mask\n\t\tdc.cases = append(dc.cases, duplicateCaseValue{hash: hash, value: expr})\n\t}\n}\n\nfunc duplicateCaseHash(expr js_ast.Expr) (uint32, bool) {\n\tswitch e := expr.Data.(type) {\n\tcase *js_ast.EInlinedEnum:\n\t\treturn duplicateCaseHash(e.Value)\n\n\tcase *js_ast.ENull:\n\t\treturn 0, true\n\n\tcase *js_ast.EUndefined:\n\t\treturn 1, true\n\n\tcase *js_ast.EBoolean:\n\t\tif e.Value {\n\t\t\treturn helpers.HashCombine(2, 1), true\n\t\t}\n\t\treturn helpers.HashCombine(2, 0), true\n\n\tcase *js_ast.ENumber:\n\t\tbits := math.Float64bits(e.Value)\n\t\treturn helpers.HashCombine(helpers.HashCombine(3, uint32(bits)), uint32(bits>>32)), true\n\n\tcase *js_ast.EString:\n\t\thash := uint32(4)\n\t\tfor _, c := range e.Value {\n\t\t\thash = helpers.HashCombine(hash, uint32(c))\n\t\t}\n\t\treturn hash, true\n\n\tcase *js_ast.EBigInt:\n\t\thash := uint32(5)\n\t\tfor _, c := range e.Value {\n\t\t\thash = helpers.HashCombine(hash, uint32(c))\n\t\t}\n\t\treturn hash, true\n\n\tcase *js_ast.EIdentifier:\n\t\treturn helpers.HashCombine(6, e.Ref.InnerIndex), true\n\n\tcase *js_ast.EDot:\n\t\tif target, ok := duplicateCaseHash(e.Target); ok {\n\t\t\treturn helpers.HashCombineString(helpers.HashCombine(7, target), e.Name), true\n\t\t}\n\n\tcase *js_ast.EIndex:\n\t\tif target, ok := duplicateCaseHash(e.Target); ok {\n\t\t\tif index, ok := duplicateCaseHash(e.Index); ok {\n\t\t\t\treturn helpers.HashCombine(helpers.HashCombine(8, target), index), true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn 0, false\n}\n\nfunc duplicateCaseEquals(left js_ast.Expr, right js_ast.Expr) (equals bool, couldBeIncorrect bool) {\n\tif b, ok := right.Data.(*js_ast.EInlinedEnum); ok {\n\t\treturn duplicateCaseEquals(left, b.Value)\n\t}\n\n\tswitch a := left.Data.(type) {\n\tcase *js_ast.EInlinedEnum:\n\t\treturn duplicateCaseEquals(a.Value, right)\n\n\tcase *js_ast.ENull:\n\t\t_, ok := right.Data.(*js_ast.ENull)\n\t\treturn ok, false\n\n\tcase *js_ast.EUndefined:\n\t\t_, ok := right.Data.(*js_ast.EUndefined)\n\t\treturn ok, false\n\n\tcase *js_ast.EBoolean:\n\t\tb, ok := right.Data.(*js_ast.EBoolean)\n\t\treturn ok && a.Value == b.Value, false\n\n\tcase *js_ast.ENumber:\n\t\tb, ok := right.Data.(*js_ast.ENumber)\n\t\treturn ok && a.Value == b.Value, false\n\n\tcase *js_ast.EString:\n\t\tb, ok := right.Data.(*js_ast.EString)\n\t\treturn ok && helpers.UTF16EqualsUTF16(a.Value, b.Value), false\n\n\tcase *js_ast.EBigInt:\n\t\tif b, ok := right.Data.(*js_ast.EBigInt); ok {\n\t\t\tequal, ok := js_ast.CheckEqualityBigInt(a.Value, b.Value)\n\t\t\treturn ok && equal, false\n\t\t}\n\n\tcase *js_ast.EIdentifier:\n\t\tb, ok := right.Data.(*js_ast.EIdentifier)\n\t\treturn ok && a.Ref == b.Ref, false\n\n\tcase *js_ast.EDot:\n\t\tif b, ok := right.Data.(*js_ast.EDot); ok && a.OptionalChain == b.OptionalChain && a.Name == b.Name {\n\t\t\tequals, _ := duplicateCaseEquals(a.Target, b.Target)\n\t\t\treturn equals, true\n\t\t}\n\n\tcase *js_ast.EIndex:\n\t\tif b, ok := right.Data.(*js_ast.EIndex); ok && a.OptionalChain == b.OptionalChain {\n\t\t\tif equals, _ := duplicateCaseEquals(a.Index, b.Index); equals {\n\t\t\t\tequals, _ := duplicateCaseEquals(a.Target, b.Target)\n\t\t\t\treturn equals, true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false, false\n}\n\ntype duplicatePropertiesIn uint8\n\nconst (\n\tduplicatePropertiesInObject duplicatePropertiesIn = iota\n\tduplicatePropertiesInClass\n)\n\nfunc (p *parser) warnAboutDuplicateProperties(properties []js_ast.Property, in duplicatePropertiesIn) {\n\tif len(properties) < 2 {\n\t\treturn\n\t}\n\n\ttype keyKind uint8\n\ttype existingKey struct {\n\t\tloc  logger.Loc\n\t\tkind keyKind\n\t}\n\tconst (\n\t\tkeyMissing keyKind = iota\n\t\tkeyNormal\n\t\tkeyGet\n\t\tkeySet\n\t\tkeyGetAndSet\n\t)\n\tinstanceKeys := make(map[string]existingKey)\n\tstaticKeys := make(map[string]existingKey)\n\n\tfor _, property := range properties {\n\t\tif property.Kind != js_ast.PropertySpread {\n\t\t\tif str, ok := property.Key.Data.(*js_ast.EString); ok {\n\t\t\t\tvar keys map[string]existingKey\n\t\t\t\tif property.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t\t\tkeys = staticKeys\n\t\t\t\t} else {\n\t\t\t\t\tkeys = instanceKeys\n\t\t\t\t}\n\t\t\t\tkey := helpers.UTF16ToString(str.Value)\n\t\t\t\tprevKey := keys[key]\n\t\t\t\tnextKey := existingKey{kind: keyNormal, loc: property.Key.Loc}\n\n\t\t\t\tif property.Kind == js_ast.PropertyGetter {\n\t\t\t\t\tnextKey.kind = keyGet\n\t\t\t\t} else if property.Kind == js_ast.PropertySetter {\n\t\t\t\t\tnextKey.kind = keySet\n\t\t\t\t}\n\n\t\t\t\tif prevKey.kind != keyMissing && (in != duplicatePropertiesInObject || key != \"__proto__\") && (in != duplicatePropertiesInClass || key != \"constructor\") {\n\t\t\t\t\tif (prevKey.kind == keyGet && nextKey.kind == keySet) || (prevKey.kind == keySet && nextKey.kind == keyGet) {\n\t\t\t\t\t\tnextKey.kind = keyGetAndSet\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar id logger.MsgID\n\t\t\t\t\t\tvar what string\n\t\t\t\t\t\tvar where string\n\t\t\t\t\t\tswitch in {\n\t\t\t\t\t\tcase duplicatePropertiesInObject:\n\t\t\t\t\t\t\tid = logger.MsgID_JS_DuplicateObjectKey\n\t\t\t\t\t\t\twhat = \"key\"\n\t\t\t\t\t\t\twhere = \"object literal\"\n\t\t\t\t\t\tcase duplicatePropertiesInClass:\n\t\t\t\t\t\t\tid = logger.MsgID_JS_DuplicateClassMember\n\t\t\t\t\t\t\twhat = \"member\"\n\t\t\t\t\t\t\twhere = \"class body\"\n\t\t\t\t\t\t}\n\t\t\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, property.Key.Loc)\n\t\t\t\t\t\tp.log.AddIDWithNotes(id, logger.Warning, &p.tracker, r,\n\t\t\t\t\t\t\tfmt.Sprintf(\"Duplicate %s %q in %s\", what, key, where),\n\t\t\t\t\t\t\t[]logger.MsgData{p.tracker.MsgData(js_lexer.RangeOfIdentifier(p.source, prevKey.loc),\n\t\t\t\t\t\t\t\tfmt.Sprintf(\"The original %s %q is here:\", what, key))})\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tkeys[key] = nextKey\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc isJumpStatement(data js_ast.S) bool {\n\tswitch data.(type) {\n\tcase *js_ast.SBreak, *js_ast.SContinue, *js_ast.SReturn, *js_ast.SThrow:\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc jumpStmtsLookTheSame(left js_ast.S, right js_ast.S) bool {\n\tswitch a := left.(type) {\n\tcase *js_ast.SBreak:\n\t\tb, ok := right.(*js_ast.SBreak)\n\t\treturn ok && (a.Label == nil) == (b.Label == nil) && (a.Label == nil || a.Label.Ref == b.Label.Ref)\n\n\tcase *js_ast.SContinue:\n\t\tb, ok := right.(*js_ast.SContinue)\n\t\treturn ok && (a.Label == nil) == (b.Label == nil) && (a.Label == nil || a.Label.Ref == b.Label.Ref)\n\n\tcase *js_ast.SReturn:\n\t\tb, ok := right.(*js_ast.SReturn)\n\t\treturn ok && (a.ValueOrNil.Data == nil) == (b.ValueOrNil.Data == nil) &&\n\t\t\t(a.ValueOrNil.Data == nil || js_ast.ValuesLookTheSame(a.ValueOrNil.Data, b.ValueOrNil.Data))\n\n\tcase *js_ast.SThrow:\n\t\tb, ok := right.(*js_ast.SThrow)\n\t\treturn ok && js_ast.ValuesLookTheSame(a.Value.Data, b.Value.Data)\n\t}\n\n\treturn false\n}\n\nfunc (p *parser) selectLocalKind(kind js_ast.LocalKind) js_ast.LocalKind {\n\t// Use \"var\" instead of \"let\" and \"const\" if the variable declaration may\n\t// need to be separated from the initializer. This allows us to safely move\n\t// this declaration into a nested scope.\n\tif p.currentScope.Parent == nil && (kind == js_ast.LocalLet || kind == js_ast.LocalConst) &&\n\t\t(p.options.mode == config.ModeBundle || p.willWrapModuleInTryCatchForUsing) {\n\t\treturn js_ast.LocalVar\n\t}\n\n\t// Optimization: use \"let\" instead of \"const\" because it's shorter. This is\n\t// only done when bundling because assigning to \"const\" is only an error when\n\t// bundling.\n\tif p.options.mode == config.ModeBundle && kind == js_ast.LocalConst && p.options.minifySyntax {\n\t\treturn js_ast.LocalLet\n\t}\n\n\treturn kind\n}\n\nfunc (p *parser) pushScopeForParsePass(kind js_ast.ScopeKind, loc logger.Loc) int {\n\tparent := p.currentScope\n\tscope := &js_ast.Scope{\n\t\tKind:    kind,\n\t\tParent:  parent,\n\t\tMembers: make(map[string]js_ast.ScopeMember),\n\t\tLabel:   ast.LocRef{Ref: ast.InvalidRef},\n\t}\n\tif parent != nil {\n\t\tparent.Children = append(parent.Children, scope)\n\t\tscope.StrictMode = parent.StrictMode\n\t\tscope.UseStrictLoc = parent.UseStrictLoc\n\t}\n\tp.currentScope = scope\n\n\t// Enforce that scope locations are strictly increasing to help catch bugs\n\t// where the pushed scopes are mismatched between the first and second passes\n\tif len(p.scopesInOrder) > 0 {\n\t\tprevStart := p.scopesInOrder[len(p.scopesInOrder)-1].loc.Start\n\t\tif prevStart >= loc.Start {\n\t\t\tpanic(fmt.Sprintf(\"Scope location %d must be greater than %d\", loc.Start, prevStart))\n\t\t}\n\t}\n\n\t// Copy down function arguments into the function body scope. That way we get\n\t// errors if a statement in the function body tries to re-declare any of the\n\t// arguments.\n\tif kind == js_ast.ScopeFunctionBody {\n\t\tif scope.Parent.Kind != js_ast.ScopeFunctionArgs {\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\t\tfor name, member := range scope.Parent.Members {\n\t\t\t// Don't copy down the optional function expression name. Re-declaring\n\t\t\t// the name of a function expression is allowed.\n\t\t\tkind := p.symbols[member.Ref.InnerIndex].Kind\n\t\t\tif kind != ast.SymbolHoistedFunction {\n\t\t\t\tscope.Members[name] = member\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remember the length in case we call popAndDiscardScope() later\n\tscopeIndex := len(p.scopesInOrder)\n\tp.scopesInOrder = append(p.scopesInOrder, scopeOrder{loc: loc, scope: scope})\n\treturn scopeIndex\n}\n\nfunc (p *parser) popScope() {\n\t// We cannot rename anything inside a scope containing a direct eval() call\n\tif p.currentScope.ContainsDirectEval {\n\t\tfor _, member := range p.currentScope.Members {\n\t\t\t// Using direct eval when bundling is not a good idea in general because\n\t\t\t// esbuild must assume that it can potentially reach anything in any of\n\t\t\t// the containing scopes. We try to make it work but this isn't possible\n\t\t\t// in some cases.\n\t\t\t//\n\t\t\t// For example, symbols imported using an ESM import are a live binding\n\t\t\t// to the underlying symbol in another file. This is emulated during\n\t\t\t// scope hoisting by erasing the ESM import and just referencing the\n\t\t\t// underlying symbol in the flattened bundle directly. However, that\n\t\t\t// symbol may have a different name which could break uses of direct\n\t\t\t// eval:\n\t\t\t//\n\t\t\t//   // Before bundling\n\t\t\t//   import { foo as bar } from './foo.js'\n\t\t\t//   console.log(eval('bar'))\n\t\t\t//\n\t\t\t//   // After bundling\n\t\t\t//   let foo = 123 // The contents of \"foo.js\"\n\t\t\t//   console.log(eval('bar'))\n\t\t\t//\n\t\t\t// There really isn't any way to fix this. You can't just rename \"foo\" to\n\t\t\t// \"bar\" in the example above because there may be a third bundled file\n\t\t\t// that also contains direct eval and imports the same symbol with a\n\t\t\t// different conflicting import alias. And there is no way to store a\n\t\t\t// live binding to the underlying symbol in a variable with the import's\n\t\t\t// name so that direct eval can access it:\n\t\t\t//\n\t\t\t//   // After bundling\n\t\t\t//   let foo = 123 // The contents of \"foo.js\"\n\t\t\t//   const bar = /* cannot express a live binding to \"foo\" here */\n\t\t\t//   console.log(eval('bar'))\n\t\t\t//\n\t\t\t// Technically a \"with\" statement could potentially make this work (with\n\t\t\t// a big hit to performance), but they are deprecated and are unavailable\n\t\t\t// in strict mode. This is a non-starter since all ESM code is strict mode.\n\t\t\t//\n\t\t\t// So while we still try to obey the requirement that all symbol names are\n\t\t\t// pinned when direct eval is present, we make an exception for top-level\n\t\t\t// symbols in an ESM file when bundling is enabled. We make no guarantee\n\t\t\t// that \"eval\" will be able to reach these symbols and we allow them to be\n\t\t\t// renamed or removed by tree shaking.\n\t\t\tif p.options.mode == config.ModeBundle && p.currentScope.Parent == nil && p.isFileConsideredESM {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tp.symbols[member.Ref.InnerIndex].Flags |= ast.MustNotBeRenamed\n\t\t}\n\t}\n\n\tp.currentScope = p.currentScope.Parent\n}\n\nfunc (p *parser) popAndDiscardScope(scopeIndex int) {\n\t// Unwind any newly-added scopes in reverse order\n\tfor i := len(p.scopesInOrder) - 1; i >= scopeIndex; i-- {\n\t\tscope := p.scopesInOrder[i].scope\n\t\tparent := scope.Parent\n\t\tlast := len(parent.Children) - 1\n\t\tif parent.Children[last] != scope {\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\t\tparent.Children = parent.Children[:last]\n\t}\n\n\t// Move up to the parent scope\n\tp.currentScope = p.currentScope.Parent\n\n\t// Truncate the scope order where we started to pretend we never saw this scope\n\tp.scopesInOrder = p.scopesInOrder[:scopeIndex]\n}\n\nfunc (p *parser) popAndFlattenScope(scopeIndex int) {\n\t// Move up to the parent scope\n\ttoFlatten := p.currentScope\n\tparent := toFlatten.Parent\n\tp.currentScope = parent\n\n\t// Erase this scope from the order. This will shift over the indices of all\n\t// the scopes that were created after us. However, we shouldn't have to\n\t// worry about other code with outstanding scope indices for these scopes.\n\t// These scopes were all created in between this scope's push and pop\n\t// operations, so they should all be child scopes and should all be popped\n\t// by the time we get here.\n\tcopy(p.scopesInOrder[scopeIndex:], p.scopesInOrder[scopeIndex+1:])\n\tp.scopesInOrder = p.scopesInOrder[:len(p.scopesInOrder)-1]\n\n\t// Remove the last child from the parent scope\n\tlast := len(parent.Children) - 1\n\tif parent.Children[last] != toFlatten {\n\t\tpanic(\"Internal error\")\n\t}\n\tparent.Children = parent.Children[:last]\n\n\t// Reparent our child scopes into our parent\n\tfor _, scope := range toFlatten.Children {\n\t\tscope.Parent = parent\n\t\tparent.Children = append(parent.Children, scope)\n\t}\n}\n\n// Undo all scopes pushed and popped after this scope index. This assumes that\n// the scope stack is at the same level now as it was at the given scope index.\nfunc (p *parser) discardScopesUpTo(scopeIndex int) {\n\t// Remove any direct children from their parent\n\tchildren := p.currentScope.Children\n\tfor _, child := range p.scopesInOrder[scopeIndex:] {\n\t\tif child.scope.Parent == p.currentScope {\n\t\t\tfor i := len(children) - 1; i >= 0; i-- {\n\t\t\t\tif children[i] == child.scope {\n\t\t\t\t\tchildren = append(children[:i], children[i+1:]...)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tp.currentScope.Children = children\n\n\t// Truncate the scope order where we started to pretend we never saw this scope\n\tp.scopesInOrder = p.scopesInOrder[:scopeIndex]\n}\n\nfunc (p *parser) newSymbol(kind ast.SymbolKind, name string) ast.Ref {\n\tref := ast.Ref{SourceIndex: p.source.Index, InnerIndex: uint32(len(p.symbols))}\n\tp.symbols = append(p.symbols, ast.Symbol{\n\t\tKind:         kind,\n\t\tOriginalName: name,\n\t\tLink:         ast.InvalidRef,\n\t})\n\tif p.options.ts.Parse {\n\t\tp.tsUseCounts = append(p.tsUseCounts, 0)\n\t}\n\treturn ref\n}\n\n// This is similar to \"ast.MergeSymbols\" but it works with this parser's\n// one-level symbol map instead of the linker's two-level symbol map. It also\n// doesn't handle cycles since they shouldn't come up due to the way this\n// function is used.\nfunc (p *parser) mergeSymbols(old ast.Ref, new ast.Ref) ast.Ref {\n\tif old == new {\n\t\treturn new\n\t}\n\n\toldSymbol := &p.symbols[old.InnerIndex]\n\tif oldSymbol.Link != ast.InvalidRef {\n\t\toldSymbol.Link = p.mergeSymbols(oldSymbol.Link, new)\n\t\treturn oldSymbol.Link\n\t}\n\n\tnewSymbol := &p.symbols[new.InnerIndex]\n\tif newSymbol.Link != ast.InvalidRef {\n\t\tnewSymbol.Link = p.mergeSymbols(old, newSymbol.Link)\n\t\treturn newSymbol.Link\n\t}\n\n\toldSymbol.Link = new\n\tnewSymbol.MergeContentsWith(oldSymbol)\n\treturn new\n}\n\ntype mergeResult int\n\nconst (\n\tmergeForbidden = iota\n\tmergeReplaceWithNew\n\tmergeOverwriteWithNew\n\tmergeKeepExisting\n\tmergeBecomePrivateGetSetPair\n\tmergeBecomePrivateStaticGetSetPair\n)\n\nfunc (p *parser) canMergeSymbols(scope *js_ast.Scope, existing ast.SymbolKind, new ast.SymbolKind) mergeResult {\n\tif existing == ast.SymbolUnbound {\n\t\treturn mergeReplaceWithNew\n\t}\n\n\t// In TypeScript, imports are allowed to silently collide with symbols within\n\t// the module. Presumably this is because the imports may be type-only:\n\t//\n\t//   import {Foo} from 'bar'\n\t//   class Foo {}\n\t//\n\tif p.options.ts.Parse && existing == ast.SymbolImport {\n\t\treturn mergeReplaceWithNew\n\t}\n\n\t// \"enum Foo {} enum Foo {}\"\n\tif new == ast.SymbolTSEnum && existing == ast.SymbolTSEnum {\n\t\treturn mergeKeepExisting\n\t}\n\n\t// \"namespace Foo { ... } enum Foo {}\"\n\tif new == ast.SymbolTSEnum && existing == ast.SymbolTSNamespace {\n\t\treturn mergeReplaceWithNew\n\t}\n\n\t// \"namespace Foo { ... } namespace Foo { ... }\"\n\t// \"function Foo() {} namespace Foo { ... }\"\n\t// \"enum Foo {} namespace Foo { ... }\"\n\tif new == ast.SymbolTSNamespace {\n\t\tswitch existing {\n\t\tcase ast.SymbolTSNamespace, ast.SymbolHoistedFunction, ast.SymbolGeneratorOrAsyncFunction, ast.SymbolTSEnum, ast.SymbolClass:\n\t\t\treturn mergeKeepExisting\n\t\t}\n\t}\n\n\t// \"var foo; var foo;\"\n\t// \"var foo; function foo() {}\"\n\t// \"function foo() {} var foo;\"\n\t// \"function *foo() {} function *foo() {}\" but not \"{ function *foo() {} function *foo() {} }\"\n\tif new.IsHoistedOrFunction() && existing.IsHoistedOrFunction() &&\n\t\t(scope.Kind == js_ast.ScopeEntry ||\n\t\t\tscope.Kind == js_ast.ScopeFunctionBody ||\n\t\t\tscope.Kind == js_ast.ScopeFunctionArgs ||\n\t\t\t(new == existing && new.IsHoisted())) {\n\t\treturn mergeReplaceWithNew\n\t}\n\n\t// \"get #foo() {} set #foo() {}\"\n\t// \"set #foo() {} get #foo() {}\"\n\tif (existing == ast.SymbolPrivateGet && new == ast.SymbolPrivateSet) ||\n\t\t(existing == ast.SymbolPrivateSet && new == ast.SymbolPrivateGet) {\n\t\treturn mergeBecomePrivateGetSetPair\n\t}\n\tif (existing == ast.SymbolPrivateStaticGet && new == ast.SymbolPrivateStaticSet) ||\n\t\t(existing == ast.SymbolPrivateStaticSet && new == ast.SymbolPrivateStaticGet) {\n\t\treturn mergeBecomePrivateStaticGetSetPair\n\t}\n\n\t// \"try {} catch (e) { var e }\"\n\tif existing == ast.SymbolCatchIdentifier && new == ast.SymbolHoisted {\n\t\treturn mergeReplaceWithNew\n\t}\n\n\t// \"function() { var arguments }\"\n\tif existing == ast.SymbolArguments && new == ast.SymbolHoisted {\n\t\treturn mergeKeepExisting\n\t}\n\n\t// \"function() { let arguments }\"\n\tif existing == ast.SymbolArguments && new != ast.SymbolHoisted {\n\t\treturn mergeOverwriteWithNew\n\t}\n\n\treturn mergeForbidden\n}\n\nfunc (p *parser) addSymbolAlreadyDeclaredError(name string, newLoc logger.Loc, oldLoc logger.Loc) {\n\tp.log.AddErrorWithNotes(&p.tracker,\n\t\tjs_lexer.RangeOfIdentifier(p.source, newLoc),\n\t\tfmt.Sprintf(\"The symbol %q has already been declared\", name),\n\n\t\t[]logger.MsgData{p.tracker.MsgData(\n\t\t\tjs_lexer.RangeOfIdentifier(p.source, oldLoc),\n\t\t\tfmt.Sprintf(\"The symbol %q was originally declared here:\", name),\n\t\t)},\n\t)\n}\n\nfunc (p *parser) declareSymbol(kind ast.SymbolKind, loc logger.Loc, name string) ast.Ref {\n\tp.checkForUnrepresentableIdentifier(loc, name)\n\n\t// Allocate a new symbol\n\tref := p.newSymbol(kind, name)\n\n\t// Check for a collision in the declaring scope\n\tif existing, ok := p.currentScope.Members[name]; ok {\n\t\tsymbol := &p.symbols[existing.Ref.InnerIndex]\n\n\t\tswitch p.canMergeSymbols(p.currentScope, symbol.Kind, kind) {\n\t\tcase mergeForbidden:\n\t\t\tp.addSymbolAlreadyDeclaredError(name, loc, existing.Loc)\n\t\t\treturn existing.Ref\n\n\t\tcase mergeKeepExisting:\n\t\t\tref = existing.Ref\n\n\t\tcase mergeReplaceWithNew:\n\t\t\tsymbol.Link = ref\n\t\t\tp.currentScope.Replaced = append(p.currentScope.Replaced, existing)\n\n\t\t\t// If these are both functions, remove the overwritten declaration\n\t\t\tif p.options.minifySyntax && kind.IsFunction() && symbol.Kind.IsFunction() {\n\t\t\t\tsymbol.Flags |= ast.RemoveOverwrittenFunctionDeclaration\n\t\t\t}\n\n\t\tcase mergeBecomePrivateGetSetPair:\n\t\t\tref = existing.Ref\n\t\t\tsymbol.Kind = ast.SymbolPrivateGetSetPair\n\n\t\tcase mergeBecomePrivateStaticGetSetPair:\n\t\t\tref = existing.Ref\n\t\t\tsymbol.Kind = ast.SymbolPrivateStaticGetSetPair\n\n\t\tcase mergeOverwriteWithNew:\n\t\t}\n\t}\n\n\t// Overwrite this name in the declaring scope\n\tp.currentScope.Members[name] = js_ast.ScopeMember{Ref: ref, Loc: loc}\n\treturn ref\n\n}\n\n// This type is just so we can use Go's native sort function\ntype scopeMemberArray []js_ast.ScopeMember\n\nfunc (a scopeMemberArray) Len() int          { return len(a) }\nfunc (a scopeMemberArray) Swap(i int, j int) { a[i], a[j] = a[j], a[i] }\n\nfunc (a scopeMemberArray) Less(i int, j int) bool {\n\tai := a[i].Ref\n\tbj := a[j].Ref\n\treturn ai.InnerIndex < bj.InnerIndex || (ai.InnerIndex == bj.InnerIndex && ai.SourceIndex < bj.SourceIndex)\n}\n\nfunc (p *parser) hoistSymbols(scope *js_ast.Scope) {\n\t// Duplicate function declarations are forbidden in nested blocks in strict\n\t// mode. Separately, they are also forbidden at the top-level of modules.\n\t// This check needs to be delayed until now instead of being done when the\n\t// functions are declared because we potentially need to scan the whole file\n\t// to know if the file is considered to be in strict mode (or is considered\n\t// to be a module). We might only encounter an \"export {}\" clause at the end\n\t// of the file.\n\tif (scope.StrictMode != js_ast.SloppyMode && scope.Kind == js_ast.ScopeBlock) || (scope.Parent == nil && p.isFileConsideredESM) {\n\t\tfor _, replaced := range scope.Replaced {\n\t\t\tsymbol := &p.symbols[replaced.Ref.InnerIndex]\n\t\t\tif symbol.Kind.IsFunction() {\n\t\t\t\tif member, ok := scope.Members[symbol.OriginalName]; ok && p.symbols[member.Ref.InnerIndex].Kind.IsFunction() {\n\t\t\t\t\tvar notes []logger.MsgData\n\t\t\t\t\tif scope.Parent == nil && p.isFileConsideredESM {\n\t\t\t\t\t\t_, notes = p.whyESModule()\n\t\t\t\t\t\tnotes[0].Text = fmt.Sprintf(\"Duplicate top-level function declarations are not allowed in an ECMAScript module. %s\", notes[0].Text)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar where string\n\t\t\t\t\t\twhere, notes = p.whyStrictMode(scope)\n\t\t\t\t\t\tnotes[0].Text = fmt.Sprintf(\"Duplicate function declarations are not allowed in nested blocks %s. %s\", where, notes[0].Text)\n\t\t\t\t\t}\n\n\t\t\t\t\tp.log.AddErrorWithNotes(&p.tracker,\n\t\t\t\t\t\tjs_lexer.RangeOfIdentifier(p.source, member.Loc),\n\t\t\t\t\t\tfmt.Sprintf(\"The symbol %q has already been declared\", symbol.OriginalName),\n\n\t\t\t\t\t\tappend([]logger.MsgData{p.tracker.MsgData(\n\t\t\t\t\t\t\tjs_lexer.RangeOfIdentifier(p.source, replaced.Loc),\n\t\t\t\t\t\t\tfmt.Sprintf(\"The symbol %q was originally declared here:\", symbol.OriginalName),\n\t\t\t\t\t\t)}, notes...),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif !scope.Kind.StopsHoisting() {\n\t\t// We create new symbols in the loop below, so the iteration order of the\n\t\t// loop must be deterministic to avoid generating different minified names\n\t\tsortedMembers := make(scopeMemberArray, 0, len(scope.Members))\n\t\tfor _, member := range scope.Members {\n\t\t\tsortedMembers = append(sortedMembers, member)\n\t\t}\n\t\tsort.Sort(sortedMembers)\n\n\tnextMember:\n\t\tfor _, member := range sortedMembers {\n\t\t\tsymbol := &p.symbols[member.Ref.InnerIndex]\n\n\t\t\t// Handle non-hoisted collisions between catch bindings and the catch body.\n\t\t\t// This implements \"B.3.4 VariableStatements in Catch Blocks\" from Annex B\n\t\t\t// of the ECMAScript standard version 6+ (except for the hoisted case, which\n\t\t\t// is handled later on below):\n\t\t\t//\n\t\t\t// * It is a Syntax Error if any element of the BoundNames of CatchParameter\n\t\t\t//   also occurs in the LexicallyDeclaredNames of Block.\n\t\t\t//\n\t\t\t// * It is a Syntax Error if any element of the BoundNames of CatchParameter\n\t\t\t//   also occurs in the VarDeclaredNames of Block unless CatchParameter is\n\t\t\t//   CatchParameter : BindingIdentifier .\n\t\t\t//\n\t\t\tif scope.Parent.Kind == js_ast.ScopeCatchBinding && symbol.Kind != ast.SymbolHoisted {\n\t\t\t\tif existingMember, ok := scope.Parent.Members[symbol.OriginalName]; ok {\n\t\t\t\t\tp.addSymbolAlreadyDeclaredError(symbol.OriginalName, member.Loc, existingMember.Loc)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !symbol.Kind.IsHoisted() {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Implement \"Block-Level Function Declarations Web Legacy Compatibility\n\t\t\t// Semantics\" from Annex B of the ECMAScript standard version 6+\n\t\t\tisSloppyModeBlockLevelFnStmt := false\n\t\t\toriginalMemberRef := member.Ref\n\t\t\tif symbol.Kind == ast.SymbolHoistedFunction {\n\t\t\t\t// Block-level function declarations behave like \"let\" in strict mode\n\t\t\t\tif scope.StrictMode != js_ast.SloppyMode {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// In sloppy mode, block level functions behave like \"let\" except with\n\t\t\t\t// an assignment to \"var\", sort of. This code:\n\t\t\t\t//\n\t\t\t\t//   if (x) {\n\t\t\t\t//     f();\n\t\t\t\t//     function f() {}\n\t\t\t\t//   }\n\t\t\t\t//   f();\n\t\t\t\t//\n\t\t\t\t// behaves like this code:\n\t\t\t\t//\n\t\t\t\t//   if (x) {\n\t\t\t\t//     let f2 = function() {}\n\t\t\t\t//     var f = f2;\n\t\t\t\t//     f2();\n\t\t\t\t//   }\n\t\t\t\t//   f();\n\t\t\t\t//\n\t\t\t\thoistedRef := p.newSymbol(ast.SymbolHoisted, symbol.OriginalName)\n\t\t\t\tscope.Generated = append(scope.Generated, hoistedRef)\n\t\t\t\tif p.hoistedRefForSloppyModeBlockFn == nil {\n\t\t\t\t\tp.hoistedRefForSloppyModeBlockFn = make(map[ast.Ref]ast.Ref)\n\t\t\t\t}\n\t\t\t\tp.hoistedRefForSloppyModeBlockFn[member.Ref] = hoistedRef\n\t\t\t\tsymbol = &p.symbols[hoistedRef.InnerIndex]\n\t\t\t\tmember.Ref = hoistedRef\n\t\t\t\tisSloppyModeBlockLevelFnStmt = true\n\t\t\t}\n\n\t\t\t// Check for collisions that would prevent to hoisting \"var\" symbols up to the enclosing function scope\n\t\t\ts := scope.Parent\n\t\t\tfor {\n\t\t\t\t// Variable declarations hoisted past a \"with\" statement may actually end\n\t\t\t\t// up overwriting a property on the target of the \"with\" statement instead\n\t\t\t\t// of initializing the variable. We must not rename them or we risk\n\t\t\t\t// causing a behavior change.\n\t\t\t\t//\n\t\t\t\t//   var obj = { foo: 1 }\n\t\t\t\t//   with (obj) { var foo = 2 }\n\t\t\t\t//   assert(foo === undefined)\n\t\t\t\t//   assert(obj.foo === 2)\n\t\t\t\t//\n\t\t\t\tif s.Kind == js_ast.ScopeWith {\n\t\t\t\t\tsymbol.Flags |= ast.MustNotBeRenamed\n\t\t\t\t}\n\n\t\t\t\tif existingMember, ok := s.Members[symbol.OriginalName]; ok {\n\t\t\t\t\texistingSymbol := &p.symbols[existingMember.Ref.InnerIndex]\n\n\t\t\t\t\t// We can hoist the symbol from the child scope into the symbol in\n\t\t\t\t\t// this scope if:\n\t\t\t\t\t//\n\t\t\t\t\t//   - The symbol is unbound (i.e. a global variable access)\n\t\t\t\t\t//   - The symbol is also another hoisted variable\n\t\t\t\t\t//   - The symbol is a function of any kind and we're in a function or module scope\n\t\t\t\t\t//\n\t\t\t\t\t// Is this unbound (i.e. a global access) or also hoisted?\n\t\t\t\t\tif existingSymbol.Kind == ast.SymbolUnbound || existingSymbol.Kind == ast.SymbolHoisted ||\n\t\t\t\t\t\t(existingSymbol.Kind.IsFunction() && (s.Kind == js_ast.ScopeEntry || s.Kind == js_ast.ScopeFunctionBody)) {\n\t\t\t\t\t\t// Silently merge this symbol into the existing symbol\n\t\t\t\t\t\tsymbol.Link = existingMember.Ref\n\t\t\t\t\t\ts.Members[symbol.OriginalName] = existingMember\n\t\t\t\t\t\tcontinue nextMember\n\t\t\t\t\t}\n\n\t\t\t\t\t// Otherwise if this isn't a catch identifier or \"arguments\", it's a collision\n\t\t\t\t\tif existingSymbol.Kind != ast.SymbolCatchIdentifier && existingSymbol.Kind != ast.SymbolArguments {\n\t\t\t\t\t\t// An identifier binding from a catch statement and a function\n\t\t\t\t\t\t// declaration can both silently shadow another hoisted symbol\n\t\t\t\t\t\tif symbol.Kind != ast.SymbolCatchIdentifier && symbol.Kind != ast.SymbolHoistedFunction {\n\t\t\t\t\t\t\tif !isSloppyModeBlockLevelFnStmt {\n\t\t\t\t\t\t\t\tp.addSymbolAlreadyDeclaredError(symbol.OriginalName, member.Loc, existingMember.Loc)\n\t\t\t\t\t\t\t} else if s == scope.Parent {\n\t\t\t\t\t\t\t\t// Never mind about this, turns out it's not needed after all\n\t\t\t\t\t\t\t\tdelete(p.hoistedRefForSloppyModeBlockFn, originalMemberRef)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue nextMember\n\t\t\t\t\t}\n\n\t\t\t\t\t// If this is a catch identifier, silently merge the existing symbol\n\t\t\t\t\t// into this symbol but continue hoisting past this catch scope\n\t\t\t\t\texistingSymbol.Link = member.Ref\n\t\t\t\t\ts.Members[symbol.OriginalName] = member\n\t\t\t\t}\n\n\t\t\t\tif s.Kind.StopsHoisting() {\n\t\t\t\t\t// Declare the member in the scope that stopped the hoisting\n\t\t\t\t\ts.Members[symbol.OriginalName] = member\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ts = s.Parent\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, child := range scope.Children {\n\t\tp.hoistSymbols(child)\n\t}\n}\n\nfunc (p *parser) declareBinding(kind ast.SymbolKind, binding js_ast.Binding, opts parseStmtOpts) {\n\tjs_ast.ForEachIdentifierBinding(binding, func(loc logger.Loc, b *js_ast.BIdentifier) {\n\t\tif !opts.isTypeScriptDeclare || (opts.isNamespaceScope && opts.isExport) {\n\t\t\tb.Ref = p.declareSymbol(kind, loc, p.loadNameFromRef(b.Ref))\n\t\t}\n\t})\n}\n\nfunc (p *parser) recordUsage(ref ast.Ref) {\n\t// The use count stored in the symbol is used for generating symbol names\n\t// during minification. These counts shouldn't include references inside dead\n\t// code regions since those will be culled.\n\tif !p.isControlFlowDead {\n\t\tp.symbols[ref.InnerIndex].UseCountEstimate++\n\t\tuse := p.symbolUses[ref]\n\t\tuse.CountEstimate++\n\t\tp.symbolUses[ref] = use\n\t}\n\n\t// The correctness of TypeScript-to-JavaScript conversion relies on accurate\n\t// symbol use counts for the whole file, including dead code regions. This is\n\t// tracked separately in a parser-only data structure.\n\tif p.options.ts.Parse {\n\t\tp.tsUseCounts[ref.InnerIndex]++\n\t}\n}\n\nfunc (p *parser) ignoreUsage(ref ast.Ref) {\n\t// Roll back the use count increment in recordUsage()\n\tif !p.isControlFlowDead {\n\t\tp.symbols[ref.InnerIndex].UseCountEstimate--\n\t\tuse := p.symbolUses[ref]\n\t\tuse.CountEstimate--\n\t\tif use.CountEstimate == 0 {\n\t\t\tdelete(p.symbolUses, ref)\n\t\t} else {\n\t\t\tp.symbolUses[ref] = use\n\t\t}\n\t}\n\n\t// Don't roll back the \"tsUseCounts\" increment. This must be counted even if\n\t// the value is ignored because that's what the TypeScript compiler does.\n}\n\nfunc (p *parser) ignoreUsageOfIdentifierInDotChain(expr js_ast.Expr) {\n\tfor {\n\t\tswitch e := expr.Data.(type) {\n\t\tcase *js_ast.EIdentifier:\n\t\t\tp.ignoreUsage(e.Ref)\n\n\t\tcase *js_ast.EDot:\n\t\t\texpr = e.Target\n\t\t\tcontinue\n\n\t\tcase *js_ast.EIndex:\n\t\t\tif _, ok := e.Index.Data.(*js_ast.EString); ok {\n\t\t\t\texpr = e.Target\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\treturn\n\t}\n}\n\nfunc (p *parser) importFromRuntime(loc logger.Loc, name string) js_ast.Expr {\n\tit, ok := p.runtimeImports[name]\n\tif !ok {\n\t\tit.Loc = loc\n\t\tit.Ref = p.newSymbol(ast.SymbolOther, name)\n\t\tp.moduleScope.Generated = append(p.moduleScope.Generated, it.Ref)\n\t\tp.runtimeImports[name] = it\n\t}\n\tp.recordUsage(it.Ref)\n\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: it.Ref}}\n}\n\nfunc (p *parser) callRuntime(loc logger.Loc, name string, args []js_ast.Expr) js_ast.Expr {\n\treturn js_ast.Expr{Loc: loc, Data: &js_ast.ECall{\n\t\tTarget: p.importFromRuntime(loc, name),\n\t\tArgs:   args,\n\t}}\n}\n\ntype JSXImport uint8\n\nconst (\n\tJSXImportJSX JSXImport = iota\n\tJSXImportJSXS\n\tJSXImportFragment\n\tJSXImportCreateElement\n)\n\nfunc (p *parser) importJSXSymbol(loc logger.Loc, jsx JSXImport) js_ast.Expr {\n\tvar symbols map[string]ast.LocRef\n\tvar name string\n\n\tswitch jsx {\n\tcase JSXImportJSX:\n\t\tsymbols = p.jsxRuntimeImports\n\t\tif p.options.jsx.Development {\n\t\t\tname = \"jsxDEV\"\n\t\t} else {\n\t\t\tname = \"jsx\"\n\t\t}\n\n\tcase JSXImportJSXS:\n\t\tsymbols = p.jsxRuntimeImports\n\t\tif p.options.jsx.Development {\n\t\t\tname = \"jsxDEV\"\n\t\t} else {\n\t\t\tname = \"jsxs\"\n\t\t}\n\n\tcase JSXImportFragment:\n\t\tsymbols = p.jsxRuntimeImports\n\t\tname = \"Fragment\"\n\n\tcase JSXImportCreateElement:\n\t\tsymbols = p.jsxLegacyImports\n\t\tname = \"createElement\"\n\t}\n\n\tit, ok := symbols[name]\n\tif !ok {\n\t\tit.Loc = loc\n\t\tit.Ref = p.newSymbol(ast.SymbolOther, name)\n\t\tp.moduleScope.Generated = append(p.moduleScope.Generated, it.Ref)\n\t\tp.isImportItem[it.Ref] = true\n\t\tsymbols[name] = it\n\t}\n\n\tp.recordUsage(it.Ref)\n\treturn p.handleIdentifier(loc, &js_ast.EIdentifier{Ref: it.Ref}, identifierOpts{\n\t\twasOriginallyIdentifier: true,\n\t})\n}\n\nfunc (p *parser) valueToSubstituteForRequire(loc logger.Loc) js_ast.Expr {\n\tif p.source.Index != runtime.SourceIndex &&\n\t\tconfig.ShouldCallRuntimeRequire(p.options.mode, p.options.outputFormat) {\n\t\treturn p.importFromRuntime(loc, \"__require\")\n\t}\n\n\tp.recordUsage(p.requireRef)\n\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: p.requireRef}}\n}\n\nfunc (p *parser) makePromiseRef() ast.Ref {\n\tif p.promiseRef == ast.InvalidRef {\n\t\tp.promiseRef = p.newSymbol(ast.SymbolUnbound, \"Promise\")\n\t}\n\treturn p.promiseRef\n}\n\nfunc (p *parser) makeRegExpRef() ast.Ref {\n\tif p.regExpRef == ast.InvalidRef {\n\t\tp.regExpRef = p.newSymbol(ast.SymbolUnbound, \"RegExp\")\n\t\tp.moduleScope.Generated = append(p.moduleScope.Generated, p.regExpRef)\n\t}\n\treturn p.regExpRef\n}\n\nfunc (p *parser) makeBigIntRef() ast.Ref {\n\tif p.bigIntRef == ast.InvalidRef {\n\t\tp.bigIntRef = p.newSymbol(ast.SymbolUnbound, \"BigInt\")\n\t\tp.moduleScope.Generated = append(p.moduleScope.Generated, p.bigIntRef)\n\t}\n\treturn p.bigIntRef\n}\n\n// The name is temporarily stored in the ref until the scope traversal pass\n// happens, at which point a symbol will be generated and the ref will point\n// to the symbol instead.\n//\n// The scope traversal pass will reconstruct the name using one of two methods.\n// In the common case, the name is a slice of the file itself. In that case we\n// can just store the slice and not need to allocate any extra memory. In the\n// rare case, the name is an externally-allocated string. In that case we store\n// an index to the string and use that index during the scope traversal pass.\nfunc (p *parser) storeNameInRef(name js_lexer.MaybeSubstring) ast.Ref {\n\t// Is the data in \"name\" a subset of the data in \"p.source.Contents\"?\n\tif name.Start.IsValid() {\n\t\t// The name is a slice of the file contents, so we can just reference it by\n\t\t// length and don't have to allocate anything. This is the common case.\n\t\t//\n\t\t// It's stored as a negative value so we'll crash if we try to use it. That\n\t\t// way we'll catch cases where we've forgotten to call loadNameFromRef().\n\t\t// The length is the negative part because we know it's non-zero.\n\t\treturn ast.Ref{SourceIndex: -uint32(len(name.String)), InnerIndex: uint32(name.Start.GetIndex())}\n\t} else {\n\t\t// The name is some memory allocated elsewhere. This is either an inline\n\t\t// string constant in the parser or an identifier with escape sequences\n\t\t// in the source code, which is very unusual. Stash it away for later.\n\t\t// This uses allocations but it should hopefully be very uncommon.\n\t\tref := ast.Ref{SourceIndex: 0x80000000, InnerIndex: uint32(len(p.allocatedNames))}\n\t\tp.allocatedNames = append(p.allocatedNames, name.String)\n\t\treturn ref\n\t}\n}\n\n// This is the inverse of storeNameInRef() above\nfunc (p *parser) loadNameFromRef(ref ast.Ref) string {\n\tif ref.SourceIndex == 0x80000000 {\n\t\treturn p.allocatedNames[ref.InnerIndex]\n\t} else {\n\t\tif (ref.SourceIndex & 0x80000000) == 0 {\n\t\t\tpanic(\"Internal error: invalid symbol reference\")\n\t\t}\n\t\treturn p.source.Contents[ref.InnerIndex : int32(ref.InnerIndex)-int32(ref.SourceIndex)]\n\t}\n}\n\n// Due to ES6 destructuring patterns, there are many cases where it's\n// impossible to distinguish between an array or object literal and a\n// destructuring assignment until we hit the \"=\" operator later on.\n// This object defers errors about being in one state or the other\n// until we discover which state we're in.\ntype deferredErrors struct {\n\t// These are errors for expressions\n\tinvalidExprDefaultValue  logger.Range\n\tinvalidExprAfterQuestion logger.Range\n\tarraySpreadFeature       logger.Range\n\n\t// These errors are for arrow functions\n\tinvalidParens []logger.Range\n}\n\nfunc (from *deferredErrors) mergeInto(to *deferredErrors) {\n\tif from.invalidExprDefaultValue.Len > 0 {\n\t\tto.invalidExprDefaultValue = from.invalidExprDefaultValue\n\t}\n\tif from.invalidExprAfterQuestion.Len > 0 {\n\t\tto.invalidExprAfterQuestion = from.invalidExprAfterQuestion\n\t}\n\tif from.arraySpreadFeature.Len > 0 {\n\t\tto.arraySpreadFeature = from.arraySpreadFeature\n\t}\n\tif len(from.invalidParens) > 0 {\n\t\tif len(to.invalidParens) > 0 {\n\t\t\tto.invalidParens = append(to.invalidParens, from.invalidParens...)\n\t\t} else {\n\t\t\tto.invalidParens = from.invalidParens\n\t\t}\n\t}\n}\n\nfunc (p *parser) logExprErrors(errors *deferredErrors) {\n\tif errors.invalidExprDefaultValue.Len > 0 {\n\t\tp.log.AddError(&p.tracker, errors.invalidExprDefaultValue, \"Unexpected \\\"=\\\"\")\n\t}\n\n\tif errors.invalidExprAfterQuestion.Len > 0 {\n\t\tr := errors.invalidExprAfterQuestion\n\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\"Unexpected %q\", p.source.Contents[r.Loc.Start:r.Loc.Start+r.Len]))\n\t}\n\n\tif errors.arraySpreadFeature.Len > 0 {\n\t\tp.markSyntaxFeature(compat.ArraySpread, errors.arraySpreadFeature)\n\t}\n}\n\nfunc (p *parser) logDeferredArrowArgErrors(errors *deferredErrors) {\n\tfor _, paren := range errors.invalidParens {\n\t\tp.log.AddError(&p.tracker, paren, \"Invalid binding pattern\")\n\t}\n}\n\nfunc (p *parser) logNullishCoalescingErrorPrecedenceError(op string) {\n\tprevOp := \"??\"\n\tif p.lexer.Token == js_lexer.TQuestionQuestion {\n\t\top, prevOp = prevOp, op\n\t}\n\t// p.log.AddError(&p.tracker, p.lexer.Range(), fmt.Sprintf(\"The %q operator requires parentheses\"))\n\tp.log.AddErrorWithNotes(&p.tracker, p.lexer.Range(), fmt.Sprintf(\"Cannot use %q with %q without parentheses\", op, prevOp),\n\t\t[]logger.MsgData{{Text: fmt.Sprintf(\"Expressions of the form \\\"x %s y %s z\\\" are not allowed in JavaScript. \"+\n\t\t\t\"You must disambiguate between \\\"(x %s y) %s z\\\" and \\\"x %s (y %s z)\\\" by adding parentheses.\", prevOp, op, prevOp, op, prevOp, op)}})\n}\n\nfunc defineValueCanBeUsedInAssignTarget(data js_ast.E) bool {\n\tswitch data.(type) {\n\tcase *js_ast.EIdentifier, *js_ast.EDot:\n\t\treturn true\n\t}\n\n\t// Substituting a constant into an assignment target (e.g. \"x = 1\" becomes\n\t// \"0 = 1\") will cause a syntax error, so we avoid doing this. The caller\n\t// will log a warning instead.\n\treturn false\n}\n\nfunc (p *parser) logAssignToDefine(r logger.Range, name string, expr js_ast.Expr) {\n\t// If this is a compound expression, pretty-print it for the error message.\n\t// We don't use a literal slice of the source text in case it contains\n\t// problematic things (e.g. spans multiple lines, has embedded comments).\n\tif expr.Data != nil {\n\t\tvar parts []string\n\t\tfor {\n\t\t\tif id, ok := expr.Data.(*js_ast.EIdentifier); ok {\n\t\t\t\tparts = append(parts, p.loadNameFromRef(id.Ref))\n\t\t\t\tbreak\n\t\t\t} else if dot, ok := expr.Data.(*js_ast.EDot); ok {\n\t\t\t\tparts = append(parts, dot.Name)\n\t\t\t\tparts = append(parts, \".\")\n\t\t\t\texpr = dot.Target\n\t\t\t} else if index, ok := expr.Data.(*js_ast.EIndex); ok {\n\t\t\t\tif str, ok := index.Index.Data.(*js_ast.EString); ok {\n\t\t\t\t\tparts = append(parts, \"]\")\n\t\t\t\t\tparts = append(parts, string(helpers.QuoteSingle(helpers.UTF16ToString(str.Value), false)))\n\t\t\t\t\tparts = append(parts, \"[\")\n\t\t\t\t\texpr = index.Target\n\t\t\t\t} else {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tfor i, j := 0, len(parts)-1; i < j; i, j = i+1, j-1 {\n\t\t\tparts[i], parts[j] = parts[j], parts[i]\n\t\t}\n\t\tname = strings.Join(parts, \"\")\n\t}\n\n\tkind := logger.Warning\n\tif p.suppressWarningsAboutWeirdCode {\n\t\tkind = logger.Debug\n\t}\n\n\tp.log.AddIDWithNotes(logger.MsgID_JS_AssignToDefine, kind, &p.tracker, r,\n\t\tfmt.Sprintf(\"Suspicious assignment to defined constant %q\", name),\n\t\t[]logger.MsgData{{Text: fmt.Sprintf(\n\t\t\t\"The expression %q has been configured to be replaced with a constant using the \\\"define\\\" feature. \"+\n\t\t\t\t\"If this expression is supposed to be a compile-time constant, then it doesn't make sense to assign to it here. \"+\n\t\t\t\t\"Or if this expression is supposed to change at run-time, this \\\"define\\\" substitution should be removed.\", name)}})\n}\n\n// The \"await\" and \"yield\" expressions are never allowed in argument lists but\n// may or may not be allowed otherwise depending on the details of the enclosing\n// function or module. This needs to be handled when parsing an arrow function\n// argument list because we don't know if these expressions are not allowed until\n// we reach the \"=>\" token (or discover the absence of one).\n//\n// Specifically, for await:\n//\n//\t// This is ok\n//\tasync function foo() { (x = await y) }\n//\n//\t// This is an error\n//\tasync function foo() { (x = await y) => {} }\n//\n// And for yield:\n//\n//\t// This is ok\n//\tfunction* foo() { (x = yield y) }\n//\n//\t// This is an error\n//\tfunction* foo() { (x = yield y) => {} }\ntype deferredArrowArgErrors struct {\n\tinvalidExprAwait logger.Range\n\tinvalidExprYield logger.Range\n}\n\nfunc (p *parser) logArrowArgErrors(errors *deferredArrowArgErrors) {\n\tif errors.invalidExprAwait.Len > 0 {\n\t\tp.log.AddError(&p.tracker, errors.invalidExprAwait, \"Cannot use an \\\"await\\\" expression here:\")\n\t}\n\n\tif errors.invalidExprYield.Len > 0 {\n\t\tp.log.AddError(&p.tracker, errors.invalidExprYield, \"Cannot use a \\\"yield\\\" expression here:\")\n\t}\n}\n\nfunc (p *parser) keyNameForError(key js_ast.Expr) string {\n\tswitch k := key.Data.(type) {\n\tcase *js_ast.EString:\n\t\treturn fmt.Sprintf(\"%q\", helpers.UTF16ToString(k.Value))\n\tcase *js_ast.EPrivateIdentifier:\n\t\treturn fmt.Sprintf(\"%q\", p.loadNameFromRef(k.Ref))\n\t}\n\treturn \"property\"\n}\n\nfunc (p *parser) checkForLegacyOctalLiteral(e js_ast.E) {\n\tif p.lexer.IsLegacyOctalLiteral {\n\t\tif p.legacyOctalLiterals == nil {\n\t\t\tp.legacyOctalLiterals = make(map[js_ast.E]logger.Range)\n\t\t}\n\t\tp.legacyOctalLiterals[e] = p.lexer.Range()\n\t}\n}\n\nfunc (p *parser) notesForAssertTypeJSON(record *ast.ImportRecord, alias string) []logger.MsgData {\n\treturn []logger.MsgData{p.tracker.MsgData(\n\t\tjs_lexer.RangeOfImportAssertOrWith(p.source, *ast.FindAssertOrWithEntry(record.AssertOrWith.Entries, \"type\"), js_lexer.KeyAndValueRange),\n\t\t\"The JSON import assertion is here:\"),\n\t\t{Text: fmt.Sprintf(\"You can either keep the import assertion and only use the \\\"default\\\" import, \"+\n\t\t\t\"or you can remove the import assertion and use the %q import.\", alias)}}\n}\n\n// This assumes the caller has already checked for TStringLiteral or TNoSubstitutionTemplateLiteral\nfunc (p *parser) parseStringLiteral() js_ast.Expr {\n\tvar legacyOctalLoc logger.Loc\n\tloc := p.lexer.Loc()\n\ttext := p.lexer.StringLiteral()\n\n\t// Enable using a \"/* @__KEY__ */\" comment to turn a string into a key\n\thasPropertyKeyComment := (p.lexer.HasCommentBefore & js_lexer.KeyCommentBefore) != 0\n\tif hasPropertyKeyComment {\n\t\tif name := helpers.UTF16ToString(text); p.isMangledProp(name) {\n\t\t\tvalue := js_ast.Expr{Loc: loc, Data: &js_ast.ENameOfSymbol{\n\t\t\t\tRef:                   p.storeNameInRef(js_lexer.MaybeSubstring{String: name}),\n\t\t\t\tHasPropertyKeyComment: true,\n\t\t\t}}\n\t\t\tp.lexer.Next()\n\t\t\treturn value\n\t\t}\n\t}\n\n\tif p.lexer.LegacyOctalLoc.Start > loc.Start {\n\t\tlegacyOctalLoc = p.lexer.LegacyOctalLoc\n\t}\n\tvalue := js_ast.Expr{Loc: loc, Data: &js_ast.EString{\n\t\tValue:                 text,\n\t\tLegacyOctalLoc:        legacyOctalLoc,\n\t\tPreferTemplate:        p.lexer.Token == js_lexer.TNoSubstitutionTemplateLiteral,\n\t\tHasPropertyKeyComment: hasPropertyKeyComment,\n\t}}\n\tp.lexer.Next()\n\treturn value\n}\n\nfunc (p *parser) parseBigIntOrStringIfUnsupported() js_ast.Expr {\n\tif p.options.unsupportedJSFeatures.Has(compat.Bigint) {\n\t\tvar i big.Int\n\t\tfmt.Sscan(p.lexer.Identifier.String, &i)\n\t\treturn js_ast.Expr{Loc: p.lexer.Loc(), Data: &js_ast.EString{Value: helpers.StringToUTF16(i.String())}}\n\t}\n\treturn js_ast.Expr{Loc: p.lexer.Loc(), Data: &js_ast.EBigInt{Value: p.lexer.Identifier.String}}\n}\n\ntype propertyOpts struct {\n\tdecorators       []js_ast.Decorator\n\tdecoratorScope   *js_ast.Scope\n\tdecoratorContext decoratorContextFlags\n\n\tasyncRange     logger.Range\n\tgeneratorRange logger.Range\n\ttsDeclareRange logger.Range\n\tclassKeyword   logger.Range\n\tisAsync        bool\n\tisGenerator    bool\n\n\t// Class-related options\n\tisStatic        bool\n\tisTSAbstract    bool\n\tisClass         bool\n\tclassHasExtends bool\n}\n\nfunc (p *parser) parseProperty(startLoc logger.Loc, kind js_ast.PropertyKind, opts propertyOpts, errors *deferredErrors) (js_ast.Property, bool) {\n\tvar flags js_ast.PropertyFlags\n\tvar key js_ast.Expr\n\tvar closeBracketLoc logger.Loc\n\tkeyRange := p.lexer.Range()\n\n\tswitch p.lexer.Token {\n\tcase js_lexer.TNumericLiteral:\n\t\tkey = js_ast.Expr{Loc: p.lexer.Loc(), Data: &js_ast.ENumber{Value: p.lexer.Number}}\n\t\tp.checkForLegacyOctalLiteral(key.Data)\n\t\tp.lexer.Next()\n\n\tcase js_lexer.TStringLiteral:\n\t\tkey = p.parseStringLiteral()\n\t\tif !p.options.minifySyntax {\n\t\t\tflags |= js_ast.PropertyPreferQuotedKey\n\t\t}\n\n\tcase js_lexer.TBigIntegerLiteral:\n\t\tkey = p.parseBigIntOrStringIfUnsupported()\n\t\tp.lexer.Next()\n\n\tcase js_lexer.TPrivateIdentifier:\n\t\tif p.options.ts.Parse && p.options.ts.Config.ExperimentalDecorators == config.True && len(opts.decorators) > 0 {\n\t\t\tp.log.AddError(&p.tracker, p.lexer.Range(), \"TypeScript experimental decorators cannot be used on private identifiers\")\n\t\t} else if !opts.isClass {\n\t\t\tp.lexer.Expected(js_lexer.TIdentifier)\n\t\t} else if opts.tsDeclareRange.Len != 0 {\n\t\t\tp.log.AddError(&p.tracker, opts.tsDeclareRange, \"\\\"declare\\\" cannot be used with a private identifier\")\n\t\t}\n\t\tname := p.lexer.Identifier\n\t\tkey = js_ast.Expr{Loc: p.lexer.Loc(), Data: &js_ast.EPrivateIdentifier{Ref: p.storeNameInRef(name)}}\n\t\tp.reportPrivateNameUsage(name.String)\n\t\tp.lexer.Next()\n\n\tcase js_lexer.TOpenBracket:\n\t\tflags |= js_ast.PropertyIsComputed\n\t\tp.markSyntaxFeature(compat.ObjectExtensions, p.lexer.Range())\n\t\tp.lexer.Next()\n\t\twasIdentifier := p.lexer.Token == js_lexer.TIdentifier\n\t\texpr := p.parseExpr(js_ast.LComma)\n\n\t\t// Handle index signatures\n\t\tif p.options.ts.Parse && p.lexer.Token == js_lexer.TColon && wasIdentifier && opts.isClass {\n\t\t\tif _, ok := expr.Data.(*js_ast.EIdentifier); ok {\n\t\t\t\tif opts.tsDeclareRange.Len != 0 {\n\t\t\t\t\tp.log.AddError(&p.tracker, opts.tsDeclareRange, \"\\\"declare\\\" cannot be used with an index signature\")\n\t\t\t\t}\n\n\t\t\t\t// \"[key: string]: any;\"\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\t\tp.lexer.Expect(js_lexer.TCloseBracket)\n\t\t\t\tp.lexer.Expect(js_lexer.TColon)\n\t\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\t\tp.lexer.ExpectOrInsertSemicolon()\n\n\t\t\t\t// Skip this property entirely\n\t\t\t\treturn js_ast.Property{}, false\n\t\t\t}\n\t\t}\n\n\t\tcloseBracketLoc = p.saveExprCommentsHere()\n\t\tp.lexer.Expect(js_lexer.TCloseBracket)\n\t\tkey = expr\n\n\tcase js_lexer.TAsterisk:\n\t\tif kind != js_ast.PropertyField && (kind != js_ast.PropertyMethod || opts.isGenerator) {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t\topts.isGenerator = true\n\t\topts.generatorRange = p.lexer.Range()\n\t\tp.lexer.Next()\n\t\treturn p.parseProperty(startLoc, js_ast.PropertyMethod, opts, errors)\n\n\tdefault:\n\t\tname := p.lexer.Identifier\n\t\traw := p.lexer.Raw()\n\t\tnameRange := p.lexer.Range()\n\t\tif !p.lexer.IsIdentifierOrKeyword() {\n\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t}\n\t\tp.lexer.Next()\n\n\t\t// Support contextual keywords\n\t\tif kind == js_ast.PropertyField {\n\t\t\t// Does the following token look like a key?\n\t\t\tcouldBeModifierKeyword := p.lexer.IsIdentifierOrKeyword()\n\t\t\tif !couldBeModifierKeyword {\n\t\t\t\tswitch p.lexer.Token {\n\t\t\t\tcase js_lexer.TOpenBracket, js_lexer.TNumericLiteral, js_lexer.TStringLiteral, js_lexer.TPrivateIdentifier:\n\t\t\t\t\tcouldBeModifierKeyword = true\n\t\t\t\tcase js_lexer.TAsterisk:\n\t\t\t\t\tif opts.isAsync || (raw != \"get\" && raw != \"set\") {\n\t\t\t\t\t\tcouldBeModifierKeyword = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If so, check for a modifier keyword\n\t\t\tif couldBeModifierKeyword {\n\t\t\t\tswitch raw {\n\t\t\t\tcase \"get\":\n\t\t\t\t\tif !opts.isAsync {\n\t\t\t\t\t\tp.markSyntaxFeature(compat.ObjectAccessors, nameRange)\n\t\t\t\t\t\treturn p.parseProperty(startLoc, js_ast.PropertyGetter, opts, nil)\n\t\t\t\t\t}\n\n\t\t\t\tcase \"set\":\n\t\t\t\t\tif !opts.isAsync {\n\t\t\t\t\t\tp.markSyntaxFeature(compat.ObjectAccessors, nameRange)\n\t\t\t\t\t\treturn p.parseProperty(startLoc, js_ast.PropertySetter, opts, nil)\n\t\t\t\t\t}\n\n\t\t\t\tcase \"accessor\":\n\t\t\t\t\tif !p.lexer.HasNewlineBefore && !opts.isAsync && opts.isClass {\n\t\t\t\t\t\treturn p.parseProperty(startLoc, js_ast.PropertyAutoAccessor, opts, nil)\n\t\t\t\t\t}\n\n\t\t\t\tcase \"async\":\n\t\t\t\t\tif !p.lexer.HasNewlineBefore && !opts.isAsync {\n\t\t\t\t\t\topts.isAsync = true\n\t\t\t\t\t\topts.asyncRange = nameRange\n\t\t\t\t\t\treturn p.parseProperty(startLoc, js_ast.PropertyMethod, opts, nil)\n\t\t\t\t\t}\n\n\t\t\t\tcase \"static\":\n\t\t\t\t\tif !opts.isStatic && !opts.isAsync && opts.isClass {\n\t\t\t\t\t\topts.isStatic = true\n\t\t\t\t\t\treturn p.parseProperty(startLoc, kind, opts, nil)\n\t\t\t\t\t}\n\n\t\t\t\tcase \"declare\":\n\t\t\t\t\tif !p.lexer.HasNewlineBefore && opts.isClass && p.options.ts.Parse && opts.tsDeclareRange.Len == 0 {\n\t\t\t\t\t\topts.tsDeclareRange = nameRange\n\t\t\t\t\t\tscopeIndex := len(p.scopesInOrder)\n\n\t\t\t\t\t\tif prop, ok := p.parseProperty(startLoc, kind, opts, nil); ok &&\n\t\t\t\t\t\t\tprop.Kind == js_ast.PropertyField && prop.ValueOrNil.Data == nil &&\n\t\t\t\t\t\t\t(p.options.ts.Config.ExperimentalDecorators == config.True && len(opts.decorators) > 0) {\n\t\t\t\t\t\t\t// If this is a well-formed class field with the \"declare\" keyword,\n\t\t\t\t\t\t\t// only keep the declaration to preserve its side-effects when\n\t\t\t\t\t\t\t// there are TypeScript experimental decorators present:\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t//   class Foo {\n\t\t\t\t\t\t\t//     // Remove this\n\t\t\t\t\t\t\t//     declare [(console.log('side effect 1'), 'foo')]\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t//     // Keep this\n\t\t\t\t\t\t\t//     @decorator(console.log('side effect 2')) declare bar\n\t\t\t\t\t\t\t//   }\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// This behavior is surprisingly somehow valid with TypeScript\n\t\t\t\t\t\t\t// experimental decorators, which was possibly by accident.\n\t\t\t\t\t\t\t// TypeScript does not allow this with JavaScript decorators.\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// References:\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t//   https://github.com/evanw/esbuild/issues/1675\n\t\t\t\t\t\t\t//   https://github.com/microsoft/TypeScript/issues/46345\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\tprop.Kind = js_ast.PropertyDeclareOrAbstract\n\t\t\t\t\t\t\treturn prop, true\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tp.discardScopesUpTo(scopeIndex)\n\t\t\t\t\t\treturn js_ast.Property{}, false\n\t\t\t\t\t}\n\n\t\t\t\tcase \"abstract\":\n\t\t\t\t\tif !p.lexer.HasNewlineBefore && opts.isClass && p.options.ts.Parse && !opts.isTSAbstract {\n\t\t\t\t\t\topts.isTSAbstract = true\n\t\t\t\t\t\tscopeIndex := len(p.scopesInOrder)\n\n\t\t\t\t\t\tif prop, ok := p.parseProperty(startLoc, kind, opts, nil); ok &&\n\t\t\t\t\t\t\tprop.Kind == js_ast.PropertyField && prop.ValueOrNil.Data == nil &&\n\t\t\t\t\t\t\t(p.options.ts.Config.ExperimentalDecorators == config.True && len(opts.decorators) > 0) {\n\t\t\t\t\t\t\t// If this is a well-formed class field with the \"abstract\" keyword,\n\t\t\t\t\t\t\t// only keep the declaration to preserve its side-effects when\n\t\t\t\t\t\t\t// there are TypeScript experimental decorators present:\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t//   abstract class Foo {\n\t\t\t\t\t\t\t//     // Remove this\n\t\t\t\t\t\t\t//     abstract [(console.log('side effect 1'), 'foo')]\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t//     // Keep this\n\t\t\t\t\t\t\t//     @decorator(console.log('side effect 2')) abstract bar\n\t\t\t\t\t\t\t//   }\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// This behavior is valid with TypeScript experimental decorators.\n\t\t\t\t\t\t\t// TypeScript does not allow this with JavaScript decorators.\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// References:\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t//   https://github.com/evanw/esbuild/issues/3684\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\tprop.Kind = js_ast.PropertyDeclareOrAbstract\n\t\t\t\t\t\t\treturn prop, true\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tp.discardScopesUpTo(scopeIndex)\n\t\t\t\t\t\treturn js_ast.Property{}, false\n\t\t\t\t\t}\n\n\t\t\t\tcase \"private\", \"protected\", \"public\", \"readonly\", \"override\":\n\t\t\t\t\t// Skip over TypeScript keywords\n\t\t\t\t\tif opts.isClass && p.options.ts.Parse {\n\t\t\t\t\t\treturn p.parseProperty(startLoc, kind, opts, nil)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if p.lexer.Token == js_lexer.TOpenBrace && name.String == \"static\" && len(opts.decorators) == 0 {\n\t\t\t\tloc := p.lexer.Loc()\n\t\t\t\tp.lexer.Next()\n\n\t\t\t\toldFnOrArrowDataParse := p.fnOrArrowDataParse\n\t\t\t\tp.fnOrArrowDataParse = fnOrArrowDataParse{\n\t\t\t\t\tisReturnDisallowed: true,\n\t\t\t\t\tallowSuperProperty: true,\n\t\t\t\t\tawait:              forbidAll,\n\t\t\t\t}\n\n\t\t\t\tp.pushScopeForParsePass(js_ast.ScopeClassStaticInit, loc)\n\t\t\t\tstmts := p.parseStmtsUpTo(js_lexer.TCloseBrace, parseStmtOpts{})\n\t\t\t\tp.popScope()\n\n\t\t\t\tp.fnOrArrowDataParse = oldFnOrArrowDataParse\n\n\t\t\t\tcloseBraceLoc := p.lexer.Loc()\n\t\t\t\tp.lexer.Expect(js_lexer.TCloseBrace)\n\t\t\t\treturn js_ast.Property{\n\t\t\t\t\tKind: js_ast.PropertyClassStaticBlock,\n\t\t\t\t\tLoc:  startLoc,\n\t\t\t\t\tClassStaticBlock: &js_ast.ClassStaticBlock{\n\t\t\t\t\t\tLoc:   loc,\n\t\t\t\t\t\tBlock: js_ast.SBlock{Stmts: stmts, CloseBraceLoc: closeBraceLoc},\n\t\t\t\t\t},\n\t\t\t\t}, true\n\t\t\t}\n\t\t}\n\n\t\tif p.isMangledProp(name.String) {\n\t\t\tkey = js_ast.Expr{Loc: nameRange.Loc, Data: &js_ast.ENameOfSymbol{\n\t\t\t\tRef:                   p.storeNameInRef(name),\n\t\t\t\tHasPropertyKeyComment: true,\n\t\t\t}}\n\t\t} else {\n\t\t\tkey = js_ast.Expr{Loc: nameRange.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(name.String)}}\n\t\t}\n\n\t\t// Parse a shorthand property\n\t\tif !opts.isClass && kind == js_ast.PropertyField && p.lexer.Token != js_lexer.TColon &&\n\t\t\tp.lexer.Token != js_lexer.TOpenParen && p.lexer.Token != js_lexer.TLessThan &&\n\t\t\tjs_lexer.Keywords[name.String] == js_lexer.T(0) {\n\n\t\t\t// Forbid invalid identifiers\n\t\t\tif (p.fnOrArrowDataParse.await != allowIdent && name.String == \"await\") ||\n\t\t\t\t(p.fnOrArrowDataParse.yield != allowIdent && name.String == \"yield\") {\n\t\t\t\tp.log.AddError(&p.tracker, nameRange, fmt.Sprintf(\"Cannot use %q as an identifier here:\", name.String))\n\t\t\t}\n\n\t\t\tref := p.storeNameInRef(name)\n\t\t\tvalue := js_ast.Expr{Loc: key.Loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\n\t\t\t// Destructuring patterns have an optional default value\n\t\t\tvar initializerOrNil js_ast.Expr\n\t\t\tif errors != nil && p.lexer.Token == js_lexer.TEquals {\n\t\t\t\terrors.invalidExprDefaultValue = p.lexer.Range()\n\t\t\t\tp.lexer.Next()\n\t\t\t\tinitializerOrNil = p.parseExpr(js_ast.LComma)\n\t\t\t}\n\n\t\t\treturn js_ast.Property{\n\t\t\t\tKind:             kind,\n\t\t\t\tLoc:              startLoc,\n\t\t\t\tKey:              key,\n\t\t\t\tValueOrNil:       value,\n\t\t\t\tInitializerOrNil: initializerOrNil,\n\t\t\t\tFlags:            js_ast.PropertyWasShorthand,\n\t\t\t}, true\n\t\t}\n\t}\n\n\thasTypeParameters := false\n\thasDefiniteAssignmentAssertionOperator := false\n\n\tif p.options.ts.Parse {\n\t\tif opts.isClass {\n\t\t\tif p.lexer.Token == js_lexer.TQuestion {\n\t\t\t\t// \"class X { foo?: number }\"\n\t\t\t\t// \"class X { foo?(): number }\"\n\t\t\t\tp.lexer.Next()\n\t\t\t} else if p.lexer.Token == js_lexer.TExclamation && !p.lexer.HasNewlineBefore &&\n\t\t\t\t(kind == js_ast.PropertyField || kind == js_ast.PropertyAutoAccessor) {\n\t\t\t\t// \"class X { foo!: number }\"\n\t\t\t\tp.lexer.Next()\n\t\t\t\thasDefiniteAssignmentAssertionOperator = true\n\t\t\t}\n\t\t}\n\n\t\t// \"class X { foo?<T>(): T }\"\n\t\t// \"const x = { foo<T>(): T {} }\"\n\t\tif !hasDefiniteAssignmentAssertionOperator && kind != js_ast.PropertyAutoAccessor {\n\t\t\thasTypeParameters = p.skipTypeScriptTypeParameters(allowConstModifier) != didNotSkipAnything\n\t\t}\n\t}\n\n\t// Parse a class field with an optional initial value\n\tif kind == js_ast.PropertyAutoAccessor || (opts.isClass && kind == js_ast.PropertyField &&\n\t\t!hasTypeParameters && (p.lexer.Token != js_lexer.TOpenParen || hasDefiniteAssignmentAssertionOperator)) {\n\t\tvar initializerOrNil js_ast.Expr\n\n\t\t// Forbid the names \"constructor\" and \"prototype\" in some cases\n\t\tif !flags.Has(js_ast.PropertyIsComputed) {\n\t\t\tif str, ok := key.Data.(*js_ast.EString); ok && (helpers.UTF16EqualsString(str.Value, \"constructor\") ||\n\t\t\t\t(opts.isStatic && helpers.UTF16EqualsString(str.Value, \"prototype\"))) {\n\t\t\t\tp.log.AddError(&p.tracker, keyRange, fmt.Sprintf(\"Invalid field name %q\", helpers.UTF16ToString(str.Value)))\n\t\t\t}\n\t\t}\n\n\t\t// Skip over types\n\t\tif p.options.ts.Parse && p.lexer.Token == js_lexer.TColon {\n\t\t\tp.lexer.Next()\n\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t}\n\n\t\tif p.lexer.Token == js_lexer.TEquals {\n\t\t\tp.lexer.Next()\n\n\t\t\t// \"this\" and \"super\" property access is allowed in field initializers\n\t\t\toldIsThisDisallowed := p.fnOrArrowDataParse.isThisDisallowed\n\t\t\toldAllowSuperProperty := p.fnOrArrowDataParse.allowSuperProperty\n\t\t\tp.fnOrArrowDataParse.isThisDisallowed = false\n\t\t\tp.fnOrArrowDataParse.allowSuperProperty = true\n\n\t\t\tinitializerOrNil = p.parseExpr(js_ast.LComma)\n\n\t\t\tp.fnOrArrowDataParse.isThisDisallowed = oldIsThisDisallowed\n\t\t\tp.fnOrArrowDataParse.allowSuperProperty = oldAllowSuperProperty\n\t\t}\n\n\t\t// Special-case private identifiers\n\t\tif private, ok := key.Data.(*js_ast.EPrivateIdentifier); ok {\n\t\t\tname := p.loadNameFromRef(private.Ref)\n\t\t\tif name == \"#constructor\" {\n\t\t\t\tp.log.AddError(&p.tracker, keyRange, fmt.Sprintf(\"Invalid field name %q\", name))\n\t\t\t}\n\t\t\tvar declare ast.SymbolKind\n\t\t\tif kind == js_ast.PropertyAutoAccessor {\n\t\t\t\tif opts.isStatic {\n\t\t\t\t\tdeclare = ast.SymbolPrivateStaticGetSetPair\n\t\t\t\t} else {\n\t\t\t\t\tdeclare = ast.SymbolPrivateGetSetPair\n\t\t\t\t}\n\t\t\t\tprivate.Ref = p.declareSymbol(declare, key.Loc, name)\n\t\t\t\tp.privateGetters[private.Ref] = p.newSymbol(ast.SymbolOther, name[1:]+\"_get\")\n\t\t\t\tp.privateSetters[private.Ref] = p.newSymbol(ast.SymbolOther, name[1:]+\"_set\")\n\t\t\t} else {\n\t\t\t\tif opts.isStatic {\n\t\t\t\t\tdeclare = ast.SymbolPrivateStaticField\n\t\t\t\t} else {\n\t\t\t\t\tdeclare = ast.SymbolPrivateField\n\t\t\t\t}\n\t\t\t\tprivate.Ref = p.declareSymbol(declare, key.Loc, name)\n\t\t\t}\n\t\t}\n\n\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\tif opts.isStatic {\n\t\t\tflags |= js_ast.PropertyIsStatic\n\t\t}\n\t\treturn js_ast.Property{\n\t\t\tDecorators:       opts.decorators,\n\t\t\tLoc:              startLoc,\n\t\t\tKind:             kind,\n\t\t\tFlags:            flags,\n\t\t\tKey:              key,\n\t\t\tInitializerOrNil: initializerOrNil,\n\t\t\tCloseBracketLoc:  closeBracketLoc,\n\t\t}, true\n\t}\n\n\t// Parse a method expression\n\tif p.lexer.Token == js_lexer.TOpenParen || kind.IsMethodDefinition() || opts.isClass {\n\t\thasError := false\n\n\t\tif !hasError && opts.tsDeclareRange.Len != 0 {\n\t\t\twhat := \"method\"\n\t\t\tif kind == js_ast.PropertyGetter {\n\t\t\t\twhat = \"getter\"\n\t\t\t} else if kind == js_ast.PropertySetter {\n\t\t\t\twhat = \"setter\"\n\t\t\t}\n\t\t\tp.log.AddError(&p.tracker, opts.tsDeclareRange, \"\\\"declare\\\" cannot be used with a \"+what)\n\t\t\thasError = true\n\t\t}\n\n\t\tif opts.isAsync && p.markAsyncFn(opts.asyncRange, opts.isGenerator) {\n\t\t\thasError = true\n\t\t}\n\n\t\tif !hasError && opts.isGenerator && p.markSyntaxFeature(compat.Generator, opts.generatorRange) {\n\t\t\thasError = true\n\t\t}\n\n\t\tif !hasError && p.lexer.Token == js_lexer.TOpenParen && kind != js_ast.PropertyGetter && kind != js_ast.PropertySetter && p.markSyntaxFeature(compat.ObjectExtensions, p.lexer.Range()) {\n\t\t\thasError = true\n\t\t}\n\n\t\tloc := p.lexer.Loc()\n\t\tscopeIndex := p.pushScopeForParsePass(js_ast.ScopeFunctionArgs, loc)\n\t\tisConstructor := false\n\n\t\t// Forbid the names \"constructor\" and \"prototype\" in some cases\n\t\tif opts.isClass && !flags.Has(js_ast.PropertyIsComputed) {\n\t\t\tif str, ok := key.Data.(*js_ast.EString); ok {\n\t\t\t\tif !opts.isStatic && helpers.UTF16EqualsString(str.Value, \"constructor\") {\n\t\t\t\t\tswitch {\n\t\t\t\t\tcase kind == js_ast.PropertyGetter:\n\t\t\t\t\t\tp.log.AddError(&p.tracker, keyRange, \"Class constructor cannot be a getter\")\n\t\t\t\t\tcase kind == js_ast.PropertySetter:\n\t\t\t\t\t\tp.log.AddError(&p.tracker, keyRange, \"Class constructor cannot be a setter\")\n\t\t\t\t\tcase opts.isAsync:\n\t\t\t\t\t\tp.log.AddError(&p.tracker, keyRange, \"Class constructor cannot be an async function\")\n\t\t\t\t\tcase opts.isGenerator:\n\t\t\t\t\t\tp.log.AddError(&p.tracker, keyRange, \"Class constructor cannot be a generator\")\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tisConstructor = true\n\t\t\t\t\t}\n\t\t\t\t} else if opts.isStatic && helpers.UTF16EqualsString(str.Value, \"prototype\") {\n\t\t\t\t\tp.log.AddError(&p.tracker, keyRange, \"Invalid static method name \\\"prototype\\\"\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tawait := allowIdent\n\t\tyield := allowIdent\n\t\tif opts.isAsync {\n\t\t\tawait = allowExpr\n\t\t}\n\t\tif opts.isGenerator {\n\t\t\tyield = allowExpr\n\t\t}\n\n\t\tfn, hadBody := p.parseFn(nil, opts.classKeyword, opts.decoratorContext, fnOrArrowDataParse{\n\t\t\tneedsAsyncLoc:      key.Loc,\n\t\t\tasyncRange:         opts.asyncRange,\n\t\t\tawait:              await,\n\t\t\tyield:              yield,\n\t\t\tallowSuperCall:     opts.classHasExtends && isConstructor,\n\t\t\tallowSuperProperty: true,\n\t\t\tdecoratorScope:     opts.decoratorScope,\n\t\t\tisConstructor:      isConstructor,\n\n\t\t\t// Only allow omitting the body if we're parsing TypeScript class\n\t\t\tallowMissingBodyForTypeScript: p.options.ts.Parse && opts.isClass,\n\t\t})\n\n\t\t// \"class Foo { foo(): void; foo(): void {} }\"\n\t\tif !hadBody {\n\t\t\t// Skip this property entirely\n\t\t\tp.popAndDiscardScope(scopeIndex)\n\t\t\treturn js_ast.Property{}, false\n\t\t}\n\n\t\tp.popScope()\n\t\tfn.IsUniqueFormalParameters = true\n\t\tvalue := js_ast.Expr{Loc: loc, Data: &js_ast.EFunction{Fn: fn}}\n\n\t\t// Enforce argument rules for accessors\n\t\tswitch kind {\n\t\tcase js_ast.PropertyGetter:\n\t\t\tif len(fn.Args) > 0 {\n\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, fn.Args[0].Binding.Loc)\n\t\t\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\"Getter %s must have zero arguments\", p.keyNameForError(key)))\n\t\t\t}\n\n\t\tcase js_ast.PropertySetter:\n\t\t\tif len(fn.Args) != 1 {\n\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, key.Loc)\n\t\t\t\tif len(fn.Args) > 1 {\n\t\t\t\t\tr = js_lexer.RangeOfIdentifier(p.source, fn.Args[1].Binding.Loc)\n\t\t\t\t}\n\t\t\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\"Setter %s must have exactly one argument\", p.keyNameForError(key)))\n\t\t\t}\n\n\t\tdefault:\n\t\t\tkind = js_ast.PropertyMethod\n\t\t}\n\n\t\t// Special-case private identifiers\n\t\tif private, ok := key.Data.(*js_ast.EPrivateIdentifier); ok {\n\t\t\tvar declare ast.SymbolKind\n\t\t\tvar suffix string\n\t\t\tswitch kind {\n\t\t\tcase js_ast.PropertyGetter:\n\t\t\t\tif opts.isStatic {\n\t\t\t\t\tdeclare = ast.SymbolPrivateStaticGet\n\t\t\t\t} else {\n\t\t\t\t\tdeclare = ast.SymbolPrivateGet\n\t\t\t\t}\n\t\t\t\tsuffix = \"_get\"\n\t\t\tcase js_ast.PropertySetter:\n\t\t\t\tif opts.isStatic {\n\t\t\t\t\tdeclare = ast.SymbolPrivateStaticSet\n\t\t\t\t} else {\n\t\t\t\t\tdeclare = ast.SymbolPrivateSet\n\t\t\t\t}\n\t\t\t\tsuffix = \"_set\"\n\t\t\tdefault:\n\t\t\t\tif opts.isStatic {\n\t\t\t\t\tdeclare = ast.SymbolPrivateStaticMethod\n\t\t\t\t} else {\n\t\t\t\t\tdeclare = ast.SymbolPrivateMethod\n\t\t\t\t}\n\t\t\t\tsuffix = \"_fn\"\n\t\t\t}\n\t\t\tname := p.loadNameFromRef(private.Ref)\n\t\t\tif name == \"#constructor\" {\n\t\t\t\tp.log.AddError(&p.tracker, keyRange, fmt.Sprintf(\"Invalid method name %q\", name))\n\t\t\t}\n\t\t\tprivate.Ref = p.declareSymbol(declare, key.Loc, name)\n\t\t\tmethodRef := p.newSymbol(ast.SymbolOther, name[1:]+suffix)\n\t\t\tif kind == js_ast.PropertySetter {\n\t\t\t\tp.privateSetters[private.Ref] = methodRef\n\t\t\t} else {\n\t\t\t\tp.privateGetters[private.Ref] = methodRef\n\t\t\t}\n\t\t}\n\n\t\tif opts.isStatic {\n\t\t\tflags |= js_ast.PropertyIsStatic\n\t\t}\n\t\treturn js_ast.Property{\n\t\t\tDecorators:      opts.decorators,\n\t\t\tLoc:             startLoc,\n\t\t\tKind:            kind,\n\t\t\tFlags:           flags,\n\t\t\tKey:             key,\n\t\t\tValueOrNil:      value,\n\t\t\tCloseBracketLoc: closeBracketLoc,\n\t\t}, true\n\t}\n\n\t// Parse an object key/value pair\n\tp.lexer.Expect(js_lexer.TColon)\n\tvalue := p.parseExprOrBindings(js_ast.LComma, errors)\n\treturn js_ast.Property{\n\t\tLoc:             startLoc,\n\t\tKind:            kind,\n\t\tFlags:           flags,\n\t\tKey:             key,\n\t\tValueOrNil:      value,\n\t\tCloseBracketLoc: closeBracketLoc,\n\t}, true\n}\n\nfunc (p *parser) parsePropertyBinding() js_ast.PropertyBinding {\n\tvar key js_ast.Expr\n\tvar closeBracketLoc logger.Loc\n\tisComputed := false\n\tpreferQuotedKey := false\n\tloc := p.lexer.Loc()\n\n\tswitch p.lexer.Token {\n\tcase js_lexer.TDotDotDot:\n\t\tp.lexer.Next()\n\t\tvalue := js_ast.Binding{Loc: p.saveExprCommentsHere(), Data: &js_ast.BIdentifier{Ref: p.storeNameInRef(p.lexer.Identifier)}}\n\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\treturn js_ast.PropertyBinding{\n\t\t\tLoc:      loc,\n\t\t\tIsSpread: true,\n\t\t\tValue:    value,\n\t\t}\n\n\tcase js_lexer.TNumericLiteral:\n\t\tkey = js_ast.Expr{Loc: p.lexer.Loc(), Data: &js_ast.ENumber{Value: p.lexer.Number}}\n\t\tp.checkForLegacyOctalLiteral(key.Data)\n\t\tp.lexer.Next()\n\n\tcase js_lexer.TStringLiteral:\n\t\tkey = p.parseStringLiteral()\n\t\tpreferQuotedKey = !p.options.minifySyntax\n\n\tcase js_lexer.TBigIntegerLiteral:\n\t\tkey = p.parseBigIntOrStringIfUnsupported()\n\t\tp.lexer.Next()\n\n\tcase js_lexer.TOpenBracket:\n\t\tisComputed = true\n\t\tp.lexer.Next()\n\t\tkey = p.parseExpr(js_ast.LComma)\n\t\tcloseBracketLoc = p.saveExprCommentsHere()\n\t\tp.lexer.Expect(js_lexer.TCloseBracket)\n\n\tdefault:\n\t\tname := p.lexer.Identifier\n\t\tnameRange := p.lexer.Range()\n\t\tif !p.lexer.IsIdentifierOrKeyword() {\n\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t}\n\t\tp.lexer.Next()\n\t\tif p.isMangledProp(name.String) {\n\t\t\tkey = js_ast.Expr{Loc: nameRange.Loc, Data: &js_ast.ENameOfSymbol{Ref: p.storeNameInRef(name)}}\n\t\t} else {\n\t\t\tkey = js_ast.Expr{Loc: nameRange.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(name.String)}}\n\t\t}\n\n\t\tif p.lexer.Token != js_lexer.TColon && p.lexer.Token != js_lexer.TOpenParen {\n\t\t\t// Forbid invalid identifiers\n\t\t\tif (p.fnOrArrowDataParse.await != allowIdent && name.String == \"await\") ||\n\t\t\t\t(p.fnOrArrowDataParse.yield != allowIdent && name.String == \"yield\") {\n\t\t\t\tp.log.AddError(&p.tracker, nameRange, fmt.Sprintf(\"Cannot use %q as an identifier here:\", name.String))\n\t\t\t}\n\n\t\t\tref := p.storeNameInRef(name)\n\t\t\tvalue := js_ast.Binding{Loc: nameRange.Loc, Data: &js_ast.BIdentifier{Ref: ref}}\n\n\t\t\tvar defaultValueOrNil js_ast.Expr\n\t\t\tif p.lexer.Token == js_lexer.TEquals {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tdefaultValueOrNil = p.parseExpr(js_ast.LComma)\n\t\t\t}\n\n\t\t\treturn js_ast.PropertyBinding{\n\t\t\t\tLoc:               loc,\n\t\t\t\tKey:               key,\n\t\t\t\tValue:             value,\n\t\t\t\tDefaultValueOrNil: defaultValueOrNil,\n\t\t\t}\n\t\t}\n\t}\n\n\tp.lexer.Expect(js_lexer.TColon)\n\tvalue := p.parseBinding(parseBindingOpts{})\n\n\tvar defaultValueOrNil js_ast.Expr\n\tif p.lexer.Token == js_lexer.TEquals {\n\t\tp.lexer.Next()\n\t\tdefaultValueOrNil = p.parseExpr(js_ast.LComma)\n\t}\n\n\treturn js_ast.PropertyBinding{\n\t\tLoc:               loc,\n\t\tIsComputed:        isComputed,\n\t\tPreferQuotedKey:   preferQuotedKey,\n\t\tKey:               key,\n\t\tValue:             value,\n\t\tDefaultValueOrNil: defaultValueOrNil,\n\t\tCloseBracketLoc:   closeBracketLoc,\n\t}\n}\n\n// These properties have special semantics in JavaScript. They must not be\n// mangled or we could potentially fail to parse valid JavaScript syntax or\n// generate invalid JavaScript syntax as output.\n//\n// This list is only intended to contain properties specific to the JavaScript\n// language itself to avoid syntax errors in the generated output. It's not\n// intended to contain properties for JavaScript APIs. Those must be provided\n// by the user.\nvar permanentReservedProps = map[string]bool{\n\t\"__proto__\":   true,\n\t\"constructor\": true,\n\t\"prototype\":   true,\n}\n\nfunc (p *parser) isMangledProp(name string) bool {\n\tif p.options.mangleProps == nil {\n\t\treturn false\n\t}\n\tif p.options.mangleProps.MatchString(name) && !permanentReservedProps[name] && (p.options.reserveProps == nil || !p.options.reserveProps.MatchString(name)) {\n\t\treturn true\n\t}\n\treservedProps := p.reservedProps\n\tif reservedProps == nil {\n\t\treservedProps = make(map[string]bool)\n\t\tp.reservedProps = reservedProps\n\t}\n\treservedProps[name] = true\n\treturn false\n}\n\nfunc (p *parser) symbolForMangledProp(name string) ast.Ref {\n\tmangledProps := p.mangledProps\n\tif mangledProps == nil {\n\t\tmangledProps = make(map[string]ast.Ref)\n\t\tp.mangledProps = mangledProps\n\t}\n\tref, ok := mangledProps[name]\n\tif !ok {\n\t\tref = p.newSymbol(ast.SymbolMangledProp, name)\n\t\tmangledProps[name] = ref\n\t}\n\tif !p.isControlFlowDead {\n\t\tp.symbols[ref.InnerIndex].UseCountEstimate++\n\t}\n\treturn ref\n}\n\ntype wasOriginallyDotOrIndex uint8\n\nconst (\n\twasOriginallyDot wasOriginallyDotOrIndex = iota\n\twasOriginallyIndex\n)\n\nfunc (p *parser) dotOrMangledPropParse(\n\ttarget js_ast.Expr,\n\tname js_lexer.MaybeSubstring,\n\tnameLoc logger.Loc,\n\toptionalChain js_ast.OptionalChain,\n\toriginal wasOriginallyDotOrIndex,\n) js_ast.E {\n\tif (original != wasOriginallyIndex || p.options.mangleQuoted) && p.isMangledProp(name.String) {\n\t\treturn &js_ast.EIndex{\n\t\t\tTarget:        target,\n\t\t\tIndex:         js_ast.Expr{Loc: nameLoc, Data: &js_ast.ENameOfSymbol{Ref: p.storeNameInRef(name)}},\n\t\t\tOptionalChain: optionalChain,\n\t\t}\n\t}\n\n\treturn &js_ast.EDot{\n\t\tTarget:        target,\n\t\tName:          name.String,\n\t\tNameLoc:       nameLoc,\n\t\tOptionalChain: optionalChain,\n\t}\n}\n\nfunc (p *parser) dotOrMangledPropVisit(target js_ast.Expr, name string, nameLoc logger.Loc) js_ast.E {\n\tif p.isMangledProp(name) {\n\t\treturn &js_ast.EIndex{\n\t\t\tTarget: target,\n\t\t\tIndex:  js_ast.Expr{Loc: nameLoc, Data: &js_ast.ENameOfSymbol{Ref: p.symbolForMangledProp(name)}},\n\t\t}\n\t}\n\n\treturn &js_ast.EDot{\n\t\tTarget:  target,\n\t\tName:    name,\n\t\tNameLoc: nameLoc,\n\t}\n}\n\nfunc (p *parser) parseArrowBody(args []js_ast.Arg, data fnOrArrowDataParse) *js_ast.EArrow {\n\tarrowLoc := p.lexer.Loc()\n\n\t// Newlines are not allowed before \"=>\"\n\tif p.lexer.HasNewlineBefore {\n\t\tp.log.AddError(&p.tracker, p.lexer.Range(), \"Unexpected newline before \\\"=>\\\"\")\n\t\tpanic(js_lexer.LexerPanic{})\n\t}\n\n\tp.lexer.Expect(js_lexer.TEqualsGreaterThan)\n\n\tfor _, arg := range args {\n\t\tp.declareBinding(ast.SymbolHoisted, arg.Binding, parseStmtOpts{})\n\t}\n\n\t// The ability to use \"this\" and \"super\" is inherited by arrow functions\n\tdata.isThisDisallowed = p.fnOrArrowDataParse.isThisDisallowed\n\tdata.allowSuperCall = p.fnOrArrowDataParse.allowSuperCall\n\tdata.allowSuperProperty = p.fnOrArrowDataParse.allowSuperProperty\n\n\tif p.lexer.Token == js_lexer.TOpenBrace {\n\t\tbody := p.parseFnBody(data)\n\t\tp.afterArrowBodyLoc = p.lexer.Loc()\n\t\treturn &js_ast.EArrow{Args: args, Body: body}\n\t}\n\n\tp.pushScopeForParsePass(js_ast.ScopeFunctionBody, arrowLoc)\n\tdefer p.popScope()\n\n\toldFnOrArrowData := p.fnOrArrowDataParse\n\tp.fnOrArrowDataParse = data\n\texpr := p.parseExpr(js_ast.LComma)\n\tp.fnOrArrowDataParse = oldFnOrArrowData\n\treturn &js_ast.EArrow{\n\t\tArgs:       args,\n\t\tPreferExpr: true,\n\t\tBody:       js_ast.FnBody{Loc: arrowLoc, Block: js_ast.SBlock{Stmts: []js_ast.Stmt{{Loc: expr.Loc, Data: &js_ast.SReturn{ValueOrNil: expr}}}}},\n\t}\n}\n\nfunc (p *parser) checkForArrowAfterTheCurrentToken() bool {\n\toldLexer := p.lexer\n\tp.lexer.IsLogDisabled = true\n\n\t// Implement backtracking by restoring the lexer's memory to its original state\n\tdefer func() {\n\t\tr := recover()\n\t\tif _, isLexerPanic := r.(js_lexer.LexerPanic); isLexerPanic {\n\t\t\tp.lexer = oldLexer\n\t\t} else if r != nil {\n\t\t\tpanic(r)\n\t\t}\n\t}()\n\n\tp.lexer.Next()\n\tisArrowAfterThisToken := p.lexer.Token == js_lexer.TEqualsGreaterThan\n\n\tp.lexer = oldLexer\n\treturn isArrowAfterThisToken\n}\n\n// This parses an expression. This assumes we've already parsed the \"async\"\n// keyword and are currently looking at the following token.\nfunc (p *parser) parseAsyncPrefixExpr(asyncRange logger.Range, level js_ast.L, flags exprFlag) js_ast.Expr {\n\t// \"async function() {}\"\n\tif !p.lexer.HasNewlineBefore && p.lexer.Token == js_lexer.TFunction {\n\t\treturn p.parseFnExpr(asyncRange.Loc, true /* isAsync */, asyncRange)\n\t}\n\n\t// Check the precedence level to avoid parsing an arrow function in\n\t// \"new async () => {}\". This also avoids parsing \"new async()\" as\n\t// \"new (async())()\" instead.\n\tif !p.lexer.HasNewlineBefore && level < js_ast.LMember {\n\t\tswitch p.lexer.Token {\n\t\t// \"async => {}\"\n\t\tcase js_lexer.TEqualsGreaterThan:\n\t\t\tif level <= js_ast.LAssign {\n\t\t\t\targ := js_ast.Arg{Binding: js_ast.Binding{Loc: asyncRange.Loc, Data: &js_ast.BIdentifier{\n\t\t\t\t\tRef: p.storeNameInRef(js_lexer.MaybeSubstring{String: \"async\"})}}}\n\n\t\t\t\tp.pushScopeForParsePass(js_ast.ScopeFunctionArgs, asyncRange.Loc)\n\t\t\t\tdefer p.popScope()\n\n\t\t\t\treturn js_ast.Expr{Loc: asyncRange.Loc, Data: p.parseArrowBody([]js_ast.Arg{arg}, fnOrArrowDataParse{\n\t\t\t\t\tneedsAsyncLoc: asyncRange.Loc,\n\t\t\t\t})}\n\t\t\t}\n\n\t\t// \"async x => {}\"\n\t\tcase js_lexer.TIdentifier:\n\t\t\tif level <= js_ast.LAssign {\n\t\t\t\tisArrowFn := true\n\t\t\t\tif (flags&exprFlagForLoopInit) != 0 && p.lexer.Identifier.String == \"of\" {\n\t\t\t\t\t// See https://github.com/tc39/ecma262/issues/2034 for details\n\n\t\t\t\t\t// \"for (async of\" is only an arrow function if the next token is \"=>\"\n\t\t\t\t\tisArrowFn = p.checkForArrowAfterTheCurrentToken()\n\n\t\t\t\t\t// Do not allow \"for (async of []) ;\" but do allow \"for await (async of []) ;\"\n\t\t\t\t\tif !isArrowFn && (flags&exprFlagForAwaitLoopInit) == 0 && p.lexer.Raw() == \"of\" {\n\t\t\t\t\t\tr := logger.Range{Loc: asyncRange.Loc, Len: p.lexer.Range().End() - asyncRange.Loc.Start}\n\t\t\t\t\t\tp.log.AddError(&p.tracker, r, \"For loop initializers cannot start with \\\"async of\\\"\")\n\t\t\t\t\t\tpanic(js_lexer.LexerPanic{})\n\t\t\t\t\t}\n\t\t\t\t} else if p.options.ts.Parse && p.lexer.Token == js_lexer.TIdentifier {\n\t\t\t\t\t// Make sure we can parse the following TypeScript code:\n\t\t\t\t\t//\n\t\t\t\t\t//   export function open(async?: boolean): void {\n\t\t\t\t\t//     console.log(async as boolean)\n\t\t\t\t\t//   }\n\t\t\t\t\t//\n\t\t\t\t\t// TypeScript solves this by using a two-token lookahead to check for\n\t\t\t\t\t// \"=>\" after an identifier after the \"async\". This is done in\n\t\t\t\t\t// \"isUnParenthesizedAsyncArrowFunctionWorker\" which was introduced\n\t\t\t\t\t// here: https://github.com/microsoft/TypeScript/pull/8444\n\t\t\t\t\tisArrowFn = p.checkForArrowAfterTheCurrentToken()\n\t\t\t\t}\n\n\t\t\t\tif isArrowFn {\n\t\t\t\t\tp.markAsyncFn(asyncRange, false)\n\t\t\t\t\tref := p.storeNameInRef(p.lexer.Identifier)\n\t\t\t\t\targ := js_ast.Arg{Binding: js_ast.Binding{Loc: p.lexer.Loc(), Data: &js_ast.BIdentifier{Ref: ref}}}\n\t\t\t\t\tp.lexer.Next()\n\n\t\t\t\t\tp.pushScopeForParsePass(js_ast.ScopeFunctionArgs, asyncRange.Loc)\n\t\t\t\t\tdefer p.popScope()\n\n\t\t\t\t\tarrow := p.parseArrowBody([]js_ast.Arg{arg}, fnOrArrowDataParse{\n\t\t\t\t\t\tneedsAsyncLoc: arg.Binding.Loc,\n\t\t\t\t\t\tawait:         allowExpr,\n\t\t\t\t\t})\n\t\t\t\t\tarrow.IsAsync = true\n\t\t\t\t\treturn js_ast.Expr{Loc: asyncRange.Loc, Data: arrow}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// \"async()\"\n\t\t// \"async () => {}\"\n\t\tcase js_lexer.TOpenParen:\n\t\t\tp.lexer.Next()\n\t\t\treturn p.parseParenExpr(asyncRange.Loc, level, parenExprOpts{asyncRange: asyncRange})\n\n\t\t// \"async<T>()\"\n\t\t// \"async <T>() => {}\"\n\t\tcase js_lexer.TLessThan:\n\t\t\tif p.options.ts.Parse && (!p.options.jsx.Parse || p.isTSArrowFnJSX()) {\n\t\t\t\tif result := p.trySkipTypeScriptTypeParametersThenOpenParenWithBacktracking(); result != didNotSkipAnything {\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\treturn p.parseParenExpr(asyncRange.Loc, level, parenExprOpts{\n\t\t\t\t\t\tasyncRange:   asyncRange,\n\t\t\t\t\t\tforceArrowFn: result == definitelyTypeParameters,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// \"async\"\n\t// \"async + 1\"\n\treturn js_ast.Expr{Loc: asyncRange.Loc, Data: &js_ast.EIdentifier{\n\t\tRef: p.storeNameInRef(js_lexer.MaybeSubstring{String: \"async\"})}}\n}\n\nfunc (p *parser) parseFnExpr(loc logger.Loc, isAsync bool, asyncRange logger.Range) js_ast.Expr {\n\tp.lexer.Next()\n\tisGenerator := p.lexer.Token == js_lexer.TAsterisk\n\thasError := false\n\tif isAsync {\n\t\thasError = p.markAsyncFn(asyncRange, isGenerator)\n\t}\n\tif isGenerator {\n\t\tif !hasError {\n\t\t\tp.markSyntaxFeature(compat.Generator, p.lexer.Range())\n\t\t}\n\t\tp.lexer.Next()\n\t}\n\tvar name *ast.LocRef\n\n\tp.pushScopeForParsePass(js_ast.ScopeFunctionArgs, loc)\n\tdefer p.popScope()\n\n\t// The name is optional\n\tif p.lexer.Token == js_lexer.TIdentifier {\n\t\t// Don't declare the name \"arguments\" since it's shadowed and inaccessible\n\t\tname = &ast.LocRef{Loc: p.lexer.Loc()}\n\t\tif text := p.lexer.Identifier.String; text != \"arguments\" {\n\t\t\tname.Ref = p.declareSymbol(ast.SymbolHoistedFunction, name.Loc, text)\n\t\t} else {\n\t\t\tname.Ref = p.newSymbol(ast.SymbolHoistedFunction, text)\n\t\t}\n\t\tp.lexer.Next()\n\t}\n\n\t// Even anonymous functions can have TypeScript type parameters\n\tif p.options.ts.Parse {\n\t\tp.skipTypeScriptTypeParameters(allowConstModifier)\n\t}\n\n\tawait := allowIdent\n\tyield := allowIdent\n\tif isAsync {\n\t\tawait = allowExpr\n\t}\n\tif isGenerator {\n\t\tyield = allowExpr\n\t}\n\n\tfn, _ := p.parseFn(name, logger.Range{}, 0, fnOrArrowDataParse{\n\t\tneedsAsyncLoc: loc,\n\t\tasyncRange:    asyncRange,\n\t\tawait:         await,\n\t\tyield:         yield,\n\t})\n\tp.validateFunctionName(fn, fnExpr)\n\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EFunction{Fn: fn}}\n}\n\ntype parenExprOpts struct {\n\tasyncRange                    logger.Range\n\tforceArrowFn                  bool\n\tisAfterQuestionAndBeforeColon bool\n}\n\n// This assumes that the open parenthesis has already been parsed by the caller\nfunc (p *parser) parseParenExpr(loc logger.Loc, level js_ast.L, opts parenExprOpts) js_ast.Expr {\n\titems := []js_ast.Expr{}\n\terrors := deferredErrors{}\n\tarrowArgErrors := deferredArrowArgErrors{}\n\tspreadRange := logger.Range{}\n\ttypeColonRange := logger.Range{}\n\tcommaAfterSpread := logger.Loc{}\n\tisAsync := opts.asyncRange.Len > 0\n\n\t// Push a scope assuming this is an arrow function. It may not be, in which\n\t// case we'll need to roll this change back. This has to be done ahead of\n\t// parsing the arguments instead of later on when we hit the \"=>\" token and\n\t// we know it's an arrow function because the arguments may have default\n\t// values that introduce new scopes and declare new symbols. If this is an\n\t// arrow function, then those new scopes will need to be parented under the\n\t// scope of the arrow function itself.\n\tscopeIndex := p.pushScopeForParsePass(js_ast.ScopeFunctionArgs, loc)\n\n\t// Allow \"in\" inside parentheses\n\toldAllowIn := p.allowIn\n\tp.allowIn = true\n\n\t// Forbid \"await\" and \"yield\", but only for arrow functions\n\toldFnOrArrowData := p.fnOrArrowDataParse\n\tp.fnOrArrowDataParse.arrowArgErrors = &arrowArgErrors\n\n\t// Scan over the comma-separated arguments or expressions\n\tfor p.lexer.Token != js_lexer.TCloseParen {\n\t\titemLoc := p.lexer.Loc()\n\t\tisSpread := p.lexer.Token == js_lexer.TDotDotDot\n\n\t\tif isSpread {\n\t\t\tspreadRange = p.lexer.Range()\n\t\t\tp.markSyntaxFeature(compat.RestArgument, spreadRange)\n\t\t\tp.lexer.Next()\n\t\t}\n\n\t\t// We don't know yet whether these are arguments or expressions, so parse\n\t\t// a superset of the expression syntax. Errors about things that are valid\n\t\t// in one but not in the other are deferred.\n\t\tp.latestArrowArgLoc = p.lexer.Loc()\n\t\titem := p.parseExprOrBindings(js_ast.LComma, &errors)\n\n\t\tif isSpread {\n\t\t\titem = js_ast.Expr{Loc: itemLoc, Data: &js_ast.ESpread{Value: item}}\n\t\t}\n\n\t\t// Skip over types\n\t\tif p.options.ts.Parse && p.lexer.Token == js_lexer.TColon {\n\t\t\ttypeColonRange = p.lexer.Range()\n\t\t\tp.lexer.Next()\n\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t}\n\n\t\t// There may be a \"=\" after the type (but not after an \"as\" cast)\n\t\tif p.options.ts.Parse && p.lexer.Token == js_lexer.TEquals && p.lexer.Loc() != p.forbidSuffixAfterAsLoc {\n\t\t\tp.lexer.Next()\n\t\t\titem = js_ast.Assign(item, p.parseExpr(js_ast.LComma))\n\t\t}\n\n\t\titems = append(items, item)\n\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\tbreak\n\t\t}\n\n\t\t// Spread arguments must come last. If there's a spread argument followed\n\t\t// by a comma, throw an error if we use these expressions as bindings.\n\t\tif isSpread {\n\t\t\tcommaAfterSpread = p.lexer.Loc()\n\t\t}\n\n\t\t// Eat the comma token\n\t\tp.lexer.Next()\n\t}\n\n\t// The parenthetical construct must end with a close parenthesis\n\tp.lexer.Expect(js_lexer.TCloseParen)\n\n\t// Restore \"in\" operator status before we parse the arrow function body\n\tp.allowIn = oldAllowIn\n\n\t// Also restore \"await\" and \"yield\" expression errors\n\tp.fnOrArrowDataParse = oldFnOrArrowData\n\n\t// Are these arguments to an arrow function?\n\tisArrowFn := p.lexer.Token == js_lexer.TEqualsGreaterThan\n\tif isArrowFn || opts.forceArrowFn || (p.options.ts.Parse && p.lexer.Token == js_lexer.TColon) {\n\t\t// Arrow functions are not allowed inside certain expressions\n\t\tif level > js_ast.LAssign {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\n\t\tvar invalidLog invalidLog\n\t\targs := []js_ast.Arg{}\n\n\t\tif isAsync {\n\t\t\tp.markAsyncFn(opts.asyncRange, false)\n\t\t}\n\n\t\t// First, try converting the expressions to bindings\n\t\tfor _, item := range items {\n\t\t\tisSpread := false\n\t\t\tif spread, ok := item.Data.(*js_ast.ESpread); ok {\n\t\t\t\titem = spread.Value\n\t\t\t\tisSpread = true\n\t\t\t}\n\t\t\tbinding, initializerOrNil, log := p.convertExprToBindingAndInitializer(item, invalidLog, isSpread)\n\t\t\tinvalidLog = log\n\t\t\targs = append(args, js_ast.Arg{Binding: binding, DefaultOrNil: initializerOrNil})\n\t\t}\n\n\t\tawait := allowIdent\n\t\tif isAsync {\n\t\t\tawait = allowExpr\n\t\t}\n\n\t\t// Avoid parsing TypeScript code like \"a ? (1 + 2) : (3 + 4)\" as an arrow\n\t\t// function. The \":\" after the \")\" may be a return type annotation, so we\n\t\t// attempt to convert the expressions to bindings first before deciding\n\t\t// whether this is an arrow function, and only pick an arrow function if\n\t\t// there were no conversion errors.\n\t\tif p.options.ts.Parse && p.lexer.Token == js_lexer.TColon && len(invalidLog.invalidTokens) == 0 {\n\t\t\tif opts.isAfterQuestionAndBeforeColon {\n\t\t\t\t// Only do this very expensive check if we must\n\t\t\t\tisArrowFn = p.isTypeScriptArrowReturnTypeAfterQuestionAndBeforeColon(await)\n\t\t\t\tif isArrowFn {\n\t\t\t\t\t// We know this will succeed because we've already done it once above\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tp.skipTypeScriptReturnType()\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Otherwise, do the less expensive check\n\t\t\t\tisArrowFn = p.trySkipTypeScriptArrowReturnTypeWithBacktracking()\n\t\t\t}\n\t\t}\n\n\t\t// Arrow function parsing may be forced if this parenthesized expression\n\t\t// was prefixed by a TypeScript type parameter list such as \"<T,>()\"\n\t\tif isArrowFn || opts.forceArrowFn {\n\t\t\tif commaAfterSpread.Start != 0 {\n\t\t\t\tp.log.AddError(&p.tracker, logger.Range{Loc: commaAfterSpread, Len: 1}, \"Unexpected \\\",\\\" after rest pattern\")\n\t\t\t}\n\t\t\tp.logArrowArgErrors(&arrowArgErrors)\n\t\t\tp.logDeferredArrowArgErrors(&errors)\n\n\t\t\t// Now that we've decided we're an arrow function, report binding pattern\n\t\t\t// conversion errors\n\t\t\tif len(invalidLog.invalidTokens) > 0 {\n\t\t\t\tfor _, token := range invalidLog.invalidTokens {\n\t\t\t\t\tp.log.AddError(&p.tracker, token, \"Invalid binding pattern\")\n\t\t\t\t}\n\t\t\t\tpanic(js_lexer.LexerPanic{})\n\t\t\t}\n\n\t\t\t// Also report syntax features used in bindings\n\t\t\tfor _, entry := range invalidLog.syntaxFeatures {\n\t\t\t\tp.markSyntaxFeature(entry.feature, entry.token)\n\t\t\t}\n\n\t\t\tarrow := p.parseArrowBody(args, fnOrArrowDataParse{\n\t\t\t\tneedsAsyncLoc: loc,\n\t\t\t\tawait:         await,\n\t\t\t})\n\t\t\tarrow.IsAsync = isAsync\n\t\t\tarrow.HasRestArg = spreadRange.Len > 0\n\t\t\tp.popScope()\n\t\t\treturn js_ast.Expr{Loc: loc, Data: arrow}\n\t\t}\n\t}\n\n\t// If we get here, it's not an arrow function so undo the pushing of the\n\t// scope we did earlier. This needs to flatten any child scopes into the\n\t// parent scope as if the scope was never pushed in the first place.\n\tp.popAndFlattenScope(scopeIndex)\n\n\t// If this isn't an arrow function, then types aren't allowed\n\tif typeColonRange.Len > 0 {\n\t\tp.log.AddError(&p.tracker, typeColonRange, \"Unexpected \\\":\\\"\")\n\t\tpanic(js_lexer.LexerPanic{})\n\t}\n\n\t// Are these arguments for a call to a function named \"async\"?\n\tif isAsync {\n\t\tp.logExprErrors(&errors)\n\t\tasync := js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{\n\t\t\tRef: p.storeNameInRef(js_lexer.MaybeSubstring{String: \"async\"})}}\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.ECall{\n\t\t\tTarget: async,\n\t\t\tArgs:   items,\n\t\t}}\n\t}\n\n\t// Is this a chain of expressions and comma operators?\n\tif len(items) > 0 {\n\t\tp.logExprErrors(&errors)\n\t\tif spreadRange.Len > 0 {\n\t\t\tp.log.AddError(&p.tracker, spreadRange, \"Unexpected \\\"...\\\"\")\n\t\t\tpanic(js_lexer.LexerPanic{})\n\t\t}\n\t\tvalue := js_ast.JoinAllWithComma(items)\n\t\tp.markExprAsParenthesized(value, loc, isAsync)\n\t\treturn value\n\t}\n\n\t// Indicate that we expected an arrow function\n\tp.lexer.Expected(js_lexer.TEqualsGreaterThan)\n\treturn js_ast.Expr{}\n}\n\ntype invalidLog struct {\n\tinvalidTokens  []logger.Range\n\tsyntaxFeatures []syntaxFeature\n}\n\ntype syntaxFeature struct {\n\tfeature compat.JSFeature\n\ttoken   logger.Range\n}\n\nfunc (p *parser) convertExprToBindingAndInitializer(\n\texpr js_ast.Expr, invalidLog invalidLog, isSpread bool,\n) (js_ast.Binding, js_ast.Expr, invalidLog) {\n\tvar initializerOrNil js_ast.Expr\n\tif assign, ok := expr.Data.(*js_ast.EBinary); ok && assign.Op == js_ast.BinOpAssign {\n\t\tinitializerOrNil = assign.Right\n\t\texpr = assign.Left\n\t}\n\tbinding, invalidLog := p.convertExprToBinding(expr, invalidLog)\n\tif initializerOrNil.Data != nil {\n\t\tequalsRange := p.source.RangeOfOperatorBefore(initializerOrNil.Loc, \"=\")\n\t\tif isSpread {\n\t\t\tp.log.AddError(&p.tracker, equalsRange, \"A rest argument cannot have a default initializer\")\n\t\t} else {\n\t\t\tinvalidLog.syntaxFeatures = append(invalidLog.syntaxFeatures, syntaxFeature{\n\t\t\t\tfeature: compat.DefaultArgument,\n\t\t\t\ttoken:   equalsRange,\n\t\t\t})\n\t\t}\n\t}\n\treturn binding, initializerOrNil, invalidLog\n}\n\n// Note: do not write to \"p.log\" in this function. Any errors due to conversion\n// from expression to binding should be written to \"invalidLog\" instead. That\n// way we can potentially keep this as an expression if it turns out it's not\n// needed as a binding after all.\nfunc (p *parser) convertExprToBinding(expr js_ast.Expr, invalidLog invalidLog) (js_ast.Binding, invalidLog) {\n\tswitch e := expr.Data.(type) {\n\tcase *js_ast.EMissing:\n\t\treturn js_ast.Binding{Loc: expr.Loc, Data: js_ast.BMissingShared}, invalidLog\n\n\tcase *js_ast.EIdentifier:\n\t\treturn js_ast.Binding{Loc: expr.Loc, Data: &js_ast.BIdentifier{Ref: e.Ref}}, invalidLog\n\n\tcase *js_ast.EArray:\n\t\tif e.CommaAfterSpread.Start != 0 {\n\t\t\tinvalidLog.invalidTokens = append(invalidLog.invalidTokens, logger.Range{Loc: e.CommaAfterSpread, Len: 1})\n\t\t}\n\t\tinvalidLog.syntaxFeatures = append(invalidLog.syntaxFeatures,\n\t\t\tsyntaxFeature{feature: compat.Destructuring, token: p.source.RangeOfOperatorAfter(expr.Loc, \"[\")})\n\t\titems := []js_ast.ArrayBinding{}\n\t\tisSpread := false\n\t\tfor _, item := range e.Items {\n\t\t\tif i, ok := item.Data.(*js_ast.ESpread); ok {\n\t\t\t\tisSpread = true\n\t\t\t\titem = i.Value\n\t\t\t\tif _, ok := item.Data.(*js_ast.EIdentifier); !ok {\n\t\t\t\t\tp.markSyntaxFeature(compat.NestedRestBinding, p.source.RangeOfOperatorAfter(item.Loc, \"[\"))\n\t\t\t\t}\n\t\t\t}\n\t\t\tbinding, initializerOrNil, log := p.convertExprToBindingAndInitializer(item, invalidLog, isSpread)\n\t\t\tinvalidLog = log\n\t\t\titems = append(items, js_ast.ArrayBinding{\n\t\t\t\tBinding:           binding,\n\t\t\t\tDefaultValueOrNil: initializerOrNil,\n\t\t\t\tLoc:               item.Loc,\n\t\t\t})\n\t\t}\n\t\treturn js_ast.Binding{Loc: expr.Loc, Data: &js_ast.BArray{\n\t\t\tItems:           items,\n\t\t\tHasSpread:       isSpread,\n\t\t\tIsSingleLine:    e.IsSingleLine,\n\t\t\tCloseBracketLoc: e.CloseBracketLoc,\n\t\t}}, invalidLog\n\n\tcase *js_ast.EObject:\n\t\tif e.CommaAfterSpread.Start != 0 {\n\t\t\tinvalidLog.invalidTokens = append(invalidLog.invalidTokens, logger.Range{Loc: e.CommaAfterSpread, Len: 1})\n\t\t}\n\t\tinvalidLog.syntaxFeatures = append(invalidLog.syntaxFeatures,\n\t\t\tsyntaxFeature{feature: compat.Destructuring, token: p.source.RangeOfOperatorAfter(expr.Loc, \"{\")})\n\t\tproperties := []js_ast.PropertyBinding{}\n\t\tfor _, property := range e.Properties {\n\t\t\tif property.Kind.IsMethodDefinition() {\n\t\t\t\tinvalidLog.invalidTokens = append(invalidLog.invalidTokens, js_lexer.RangeOfIdentifier(p.source, property.Key.Loc))\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tbinding, initializerOrNil, log := p.convertExprToBindingAndInitializer(property.ValueOrNil, invalidLog, false)\n\t\t\tinvalidLog = log\n\t\t\tif initializerOrNil.Data == nil {\n\t\t\t\tinitializerOrNil = property.InitializerOrNil\n\t\t\t}\n\t\t\tproperties = append(properties, js_ast.PropertyBinding{\n\t\t\t\tLoc:               property.Loc,\n\t\t\t\tIsSpread:          property.Kind == js_ast.PropertySpread,\n\t\t\t\tIsComputed:        property.Flags.Has(js_ast.PropertyIsComputed),\n\t\t\t\tKey:               property.Key,\n\t\t\t\tValue:             binding,\n\t\t\t\tDefaultValueOrNil: initializerOrNil,\n\t\t\t})\n\t\t}\n\t\treturn js_ast.Binding{Loc: expr.Loc, Data: &js_ast.BObject{\n\t\t\tProperties:    properties,\n\t\t\tIsSingleLine:  e.IsSingleLine,\n\t\t\tCloseBraceLoc: e.CloseBraceLoc,\n\t\t}}, invalidLog\n\n\tdefault:\n\t\tinvalidLog.invalidTokens = append(invalidLog.invalidTokens, logger.Range{Loc: expr.Loc})\n\t\treturn js_ast.Binding{}, invalidLog\n\t}\n}\n\nfunc (p *parser) saveExprCommentsHere() logger.Loc {\n\tloc := p.lexer.Loc()\n\tif p.exprComments != nil && len(p.lexer.CommentsBeforeToken) > 0 {\n\t\tcomments := make([]string, len(p.lexer.CommentsBeforeToken))\n\t\tfor i, comment := range p.lexer.CommentsBeforeToken {\n\t\t\tcomments[i] = p.source.CommentTextWithoutIndent(comment)\n\t\t}\n\t\tp.exprComments[loc] = comments\n\t\tp.lexer.CommentsBeforeToken = p.lexer.CommentsBeforeToken[0:]\n\t}\n\treturn loc\n}\n\ntype exprFlag uint8\n\nconst (\n\texprFlagDecorator exprFlag = 1 << iota\n\texprFlagForLoopInit\n\texprFlagForAwaitLoopInit\n\texprFlagAfterQuestionAndBeforeColon\n)\n\nfunc (p *parser) parsePrefix(level js_ast.L, errors *deferredErrors, flags exprFlag) js_ast.Expr {\n\tloc := p.saveExprCommentsHere()\n\n\tswitch p.lexer.Token {\n\tcase js_lexer.TSuper:\n\t\tsuperRange := p.lexer.Range()\n\t\tp.lexer.Next()\n\n\t\tswitch p.lexer.Token {\n\t\tcase js_lexer.TOpenParen:\n\t\t\tif level < js_ast.LCall && p.fnOrArrowDataParse.allowSuperCall {\n\t\t\t\treturn js_ast.Expr{Loc: loc, Data: js_ast.ESuperShared}\n\t\t\t}\n\n\t\tcase js_lexer.TDot, js_lexer.TOpenBracket:\n\t\t\tif p.fnOrArrowDataParse.allowSuperProperty {\n\t\t\t\treturn js_ast.Expr{Loc: loc, Data: js_ast.ESuperShared}\n\t\t\t}\n\t\t}\n\n\t\tp.log.AddError(&p.tracker, superRange, \"Unexpected \\\"super\\\"\")\n\t\treturn js_ast.Expr{Loc: loc, Data: js_ast.ESuperShared}\n\n\tcase js_lexer.TOpenParen:\n\t\tif errors != nil {\n\t\t\terrors.invalidParens = append(errors.invalidParens, p.lexer.Range())\n\t\t}\n\n\t\tp.lexer.Next()\n\n\t\t// Arrow functions aren't allowed in the middle of expressions\n\t\tif level > js_ast.LAssign {\n\t\t\t// Allow \"in\" inside parentheses\n\t\t\toldAllowIn := p.allowIn\n\t\t\tp.allowIn = true\n\n\t\t\tvalue := p.parseExpr(js_ast.LLowest)\n\n\t\t\t// Don't consider the \"@(...)\" decorator syntax to be important parentheses to preserve\n\t\t\tif (flags & exprFlagDecorator) == 0 {\n\t\t\t\tp.markExprAsParenthesized(value, loc, false)\n\t\t\t}\n\n\t\t\tp.lexer.Expect(js_lexer.TCloseParen)\n\n\t\t\tp.allowIn = oldAllowIn\n\t\t\treturn value\n\t\t}\n\n\t\tvalue := p.parseParenExpr(loc, level, parenExprOpts{\n\t\t\tisAfterQuestionAndBeforeColon: (flags & exprFlagAfterQuestionAndBeforeColon) != 0,\n\t\t})\n\t\treturn value\n\n\tcase js_lexer.TFalse:\n\t\tp.lexer.Next()\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EBoolean{Value: false}}\n\n\tcase js_lexer.TTrue:\n\t\tp.lexer.Next()\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EBoolean{Value: true}}\n\n\tcase js_lexer.TNull:\n\t\tp.lexer.Next()\n\t\treturn js_ast.Expr{Loc: loc, Data: js_ast.ENullShared}\n\n\tcase js_lexer.TThis:\n\t\tif p.fnOrArrowDataParse.isThisDisallowed {\n\t\t\tp.log.AddError(&p.tracker, p.lexer.Range(), \"Cannot use \\\"this\\\" here:\")\n\t\t}\n\t\tp.lexer.Next()\n\t\treturn js_ast.Expr{Loc: loc, Data: js_ast.EThisShared}\n\n\tcase js_lexer.TPrivateIdentifier:\n\t\tif !p.allowIn || level >= js_ast.LCompare {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\n\t\tname := p.lexer.Identifier\n\t\tp.lexer.Next()\n\n\t\t// Check for \"#foo in bar\"\n\t\tif p.lexer.Token != js_lexer.TIn {\n\t\t\tp.lexer.Expected(js_lexer.TIn)\n\t\t}\n\n\t\t// Make sure to lower all matching private names\n\t\tif p.options.unsupportedJSFeatures.Has(compat.ClassPrivateBrandCheck) {\n\t\t\tif p.lowerAllOfThesePrivateNames == nil {\n\t\t\t\tp.lowerAllOfThesePrivateNames = make(map[string]bool)\n\t\t\t}\n\t\t\tp.lowerAllOfThesePrivateNames[name.String] = true\n\t\t}\n\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EPrivateIdentifier{Ref: p.storeNameInRef(name)}}\n\n\tcase js_lexer.TIdentifier:\n\t\tname := p.lexer.Identifier\n\t\tnameRange := p.lexer.Range()\n\t\traw := p.lexer.Raw()\n\t\tp.lexer.Next()\n\n\t\t// Handle async and await expressions\n\t\tswitch name.String {\n\t\tcase \"async\":\n\t\t\tif raw == \"async\" {\n\t\t\t\treturn p.parseAsyncPrefixExpr(nameRange, level, flags)\n\t\t\t}\n\n\t\tcase \"await\":\n\t\t\tswitch p.fnOrArrowDataParse.await {\n\t\t\tcase forbidAll:\n\t\t\t\tp.log.AddError(&p.tracker, nameRange, \"The keyword \\\"await\\\" cannot be used here:\")\n\n\t\t\tcase allowExpr:\n\t\t\t\tif raw != \"await\" {\n\t\t\t\t\tp.log.AddError(&p.tracker, nameRange, \"The keyword \\\"await\\\" cannot be escaped\")\n\t\t\t\t} else {\n\t\t\t\t\tif p.fnOrArrowDataParse.isTopLevel {\n\t\t\t\t\t\tp.topLevelAwaitKeyword = nameRange\n\t\t\t\t\t}\n\t\t\t\t\tif p.fnOrArrowDataParse.arrowArgErrors != nil {\n\t\t\t\t\t\tp.fnOrArrowDataParse.arrowArgErrors.invalidExprAwait = nameRange\n\t\t\t\t\t}\n\t\t\t\t\tvalue := p.parseExpr(js_ast.LPrefix)\n\t\t\t\t\tif p.lexer.Token == js_lexer.TAsteriskAsterisk {\n\t\t\t\t\t\tp.lexer.Unexpected()\n\t\t\t\t\t}\n\t\t\t\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EAwait{Value: value}}\n\t\t\t\t}\n\n\t\t\tcase allowIdent:\n\t\t\t\tp.lexer.PrevTokenWasAwaitKeyword = true\n\t\t\t\tp.lexer.AwaitKeywordLoc = loc\n\t\t\t\tp.lexer.FnOrArrowStartLoc = p.fnOrArrowDataParse.needsAsyncLoc\n\t\t\t}\n\n\t\tcase \"yield\":\n\t\t\tswitch p.fnOrArrowDataParse.yield {\n\t\t\tcase forbidAll:\n\t\t\t\tp.log.AddError(&p.tracker, nameRange, \"The keyword \\\"yield\\\" cannot be used here:\")\n\n\t\t\tcase allowExpr:\n\t\t\t\tif raw != \"yield\" {\n\t\t\t\t\tp.log.AddError(&p.tracker, nameRange, \"The keyword \\\"yield\\\" cannot be escaped\")\n\t\t\t\t} else {\n\t\t\t\t\tif level > js_ast.LAssign {\n\t\t\t\t\t\tp.log.AddError(&p.tracker, nameRange, \"Cannot use a \\\"yield\\\" expression here without parentheses:\")\n\t\t\t\t\t}\n\t\t\t\t\tif p.fnOrArrowDataParse.arrowArgErrors != nil {\n\t\t\t\t\t\tp.fnOrArrowDataParse.arrowArgErrors.invalidExprYield = nameRange\n\t\t\t\t\t}\n\t\t\t\t\treturn p.parseYieldExpr(loc)\n\t\t\t\t}\n\n\t\t\tcase allowIdent:\n\t\t\t\tif !p.lexer.HasNewlineBefore {\n\t\t\t\t\t// Try to gracefully recover if \"yield\" is used in the wrong place\n\t\t\t\t\tswitch p.lexer.Token {\n\t\t\t\t\tcase js_lexer.TNull, js_lexer.TIdentifier, js_lexer.TFalse, js_lexer.TTrue,\n\t\t\t\t\t\tjs_lexer.TNumericLiteral, js_lexer.TBigIntegerLiteral, js_lexer.TStringLiteral:\n\t\t\t\t\t\tp.log.AddError(&p.tracker, nameRange, \"Cannot use \\\"yield\\\" outside a generator function\")\n\t\t\t\t\t\treturn p.parseYieldExpr(loc)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Handle the start of an arrow expression\n\t\tif p.lexer.Token == js_lexer.TEqualsGreaterThan && level <= js_ast.LAssign {\n\t\t\tref := p.storeNameInRef(name)\n\t\t\targ := js_ast.Arg{Binding: js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: ref}}}\n\n\t\t\tp.pushScopeForParsePass(js_ast.ScopeFunctionArgs, loc)\n\t\t\tdefer p.popScope()\n\n\t\t\treturn js_ast.Expr{Loc: loc, Data: p.parseArrowBody([]js_ast.Arg{arg}, fnOrArrowDataParse{\n\t\t\t\tneedsAsyncLoc: loc,\n\t\t\t})}\n\t\t}\n\n\t\tref := p.storeNameInRef(name)\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\n\tcase js_lexer.TStringLiteral, js_lexer.TNoSubstitutionTemplateLiteral:\n\t\treturn p.parseStringLiteral()\n\n\tcase js_lexer.TTemplateHead:\n\t\tvar legacyOctalLoc logger.Loc\n\t\theadLoc := p.lexer.Loc()\n\t\thead := p.lexer.StringLiteral()\n\t\tif p.lexer.LegacyOctalLoc.Start > loc.Start {\n\t\t\tlegacyOctalLoc = p.lexer.LegacyOctalLoc\n\t\t}\n\t\tparts, tailLegacyOctalLoc := p.parseTemplateParts(false /* includeRaw */)\n\t\tif tailLegacyOctalLoc.Start > 0 {\n\t\t\tlegacyOctalLoc = tailLegacyOctalLoc\n\t\t}\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.ETemplate{\n\t\t\tHeadLoc:        headLoc,\n\t\t\tHeadCooked:     head,\n\t\t\tParts:          parts,\n\t\t\tLegacyOctalLoc: legacyOctalLoc,\n\t\t}}\n\n\tcase js_lexer.TNumericLiteral:\n\t\tvalue := js_ast.Expr{Loc: loc, Data: &js_ast.ENumber{Value: p.lexer.Number}}\n\t\tp.checkForLegacyOctalLiteral(value.Data)\n\t\tp.lexer.Next()\n\t\treturn value\n\n\tcase js_lexer.TBigIntegerLiteral:\n\t\tvalue := p.lexer.Identifier\n\t\tp.lexer.Next()\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EBigInt{Value: value.String}}\n\n\tcase js_lexer.TSlash, js_lexer.TSlashEquals:\n\t\tp.lexer.ScanRegExp()\n\t\tvalue := p.lexer.Raw()\n\t\tp.lexer.Next()\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.ERegExp{Value: value}}\n\n\tcase js_lexer.TVoid:\n\t\tp.lexer.Next()\n\t\tvalue := p.parseExpr(js_ast.LPrefix)\n\t\tif p.lexer.Token == js_lexer.TAsteriskAsterisk {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EUnary{Op: js_ast.UnOpVoid, Value: value}}\n\n\tcase js_lexer.TTypeof:\n\t\tp.lexer.Next()\n\t\tvalue := p.parseExpr(js_ast.LPrefix)\n\t\tif p.lexer.Token == js_lexer.TAsteriskAsterisk {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t\t_, valueIsIdentifier := value.Data.(*js_ast.EIdentifier)\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EUnary{\n\t\t\tOp:                            js_ast.UnOpTypeof,\n\t\t\tValue:                         value,\n\t\t\tWasOriginallyTypeofIdentifier: valueIsIdentifier,\n\t\t}}\n\n\tcase js_lexer.TDelete:\n\t\tp.lexer.Next()\n\t\tvalue := p.parseExpr(js_ast.LPrefix)\n\t\tif p.lexer.Token == js_lexer.TAsteriskAsterisk {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t\tif index, ok := value.Data.(*js_ast.EIndex); ok {\n\t\t\tif private, ok := index.Index.Data.(*js_ast.EPrivateIdentifier); ok {\n\t\t\t\tname := p.loadNameFromRef(private.Ref)\n\t\t\t\tr := logger.Range{Loc: index.Index.Loc, Len: int32(len(name))}\n\t\t\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\"Deleting the private name %q is forbidden\", name))\n\t\t\t}\n\t\t}\n\t\t_, valueIsIdentifier := value.Data.(*js_ast.EIdentifier)\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EUnary{\n\t\t\tOp:    js_ast.UnOpDelete,\n\t\t\tValue: value,\n\t\t\tWasOriginallyDeleteOfIdentifierOrPropertyAccess: valueIsIdentifier || js_ast.IsPropertyAccess(value),\n\t\t}}\n\n\tcase js_lexer.TPlus:\n\t\tp.lexer.Next()\n\t\tvalue := p.parseExpr(js_ast.LPrefix)\n\t\tif p.lexer.Token == js_lexer.TAsteriskAsterisk {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EUnary{Op: js_ast.UnOpPos, Value: value}}\n\n\tcase js_lexer.TMinus:\n\t\tp.lexer.Next()\n\t\tvalue := p.parseExpr(js_ast.LPrefix)\n\t\tif p.lexer.Token == js_lexer.TAsteriskAsterisk {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EUnary{Op: js_ast.UnOpNeg, Value: value}}\n\n\tcase js_lexer.TTilde:\n\t\tp.lexer.Next()\n\t\tvalue := p.parseExpr(js_ast.LPrefix)\n\t\tif p.lexer.Token == js_lexer.TAsteriskAsterisk {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EUnary{Op: js_ast.UnOpCpl, Value: value}}\n\n\tcase js_lexer.TExclamation:\n\t\tp.lexer.Next()\n\t\tvalue := p.parseExpr(js_ast.LPrefix)\n\t\tif p.lexer.Token == js_lexer.TAsteriskAsterisk {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EUnary{Op: js_ast.UnOpNot, Value: value}}\n\n\tcase js_lexer.TMinusMinus:\n\t\tp.lexer.Next()\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EUnary{Op: js_ast.UnOpPreDec, Value: p.parseExpr(js_ast.LPrefix)}}\n\n\tcase js_lexer.TPlusPlus:\n\t\tp.lexer.Next()\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EUnary{Op: js_ast.UnOpPreInc, Value: p.parseExpr(js_ast.LPrefix)}}\n\n\tcase js_lexer.TFunction:\n\t\treturn p.parseFnExpr(loc, false /* isAsync */, logger.Range{})\n\n\tcase js_lexer.TClass:\n\t\treturn p.parseClassExpr(nil)\n\n\tcase js_lexer.TAt:\n\t\t// Parse decorators before class expressions\n\t\tdecorators := p.parseDecorators(p.currentScope, logger.Range{}, decoratorBeforeClassExpr)\n\t\treturn p.parseClassExpr(decorators)\n\n\tcase js_lexer.TNew:\n\t\tp.lexer.Next()\n\n\t\t// Special-case the weird \"new.target\" expression here\n\t\tif p.lexer.Token == js_lexer.TDot {\n\t\t\tp.lexer.Next()\n\t\t\tif p.lexer.Token != js_lexer.TIdentifier || p.lexer.Raw() != \"target\" {\n\t\t\t\tp.lexer.Unexpected()\n\t\t\t}\n\t\t\tr := logger.Range{Loc: loc, Len: p.lexer.Range().End() - loc.Start}\n\t\t\tp.markSyntaxFeature(compat.NewTarget, r)\n\t\t\tp.lexer.Next()\n\t\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.ENewTarget{Range: r}}\n\t\t}\n\n\t\ttarget := p.parseExprWithFlags(js_ast.LMember, flags)\n\t\targs := []js_ast.Expr{}\n\t\tvar closeParenLoc logger.Loc\n\t\tvar isMultiLine bool\n\n\t\tif p.lexer.Token == js_lexer.TOpenParen {\n\t\t\targs, closeParenLoc, isMultiLine = p.parseCallArgs()\n\t\t}\n\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.ENew{\n\t\t\tTarget:        target,\n\t\t\tArgs:          args,\n\t\t\tCloseParenLoc: closeParenLoc,\n\t\t\tIsMultiLine:   isMultiLine,\n\t\t}}\n\n\tcase js_lexer.TOpenBracket:\n\t\tp.lexer.Next()\n\t\tisSingleLine := !p.lexer.HasNewlineBefore\n\t\titems := []js_ast.Expr{}\n\t\tselfErrors := deferredErrors{}\n\t\tcommaAfterSpread := logger.Loc{}\n\n\t\t// Allow \"in\" inside arrays\n\t\toldAllowIn := p.allowIn\n\t\tp.allowIn = true\n\n\t\tfor p.lexer.Token != js_lexer.TCloseBracket {\n\t\t\tswitch p.lexer.Token {\n\t\t\tcase js_lexer.TComma:\n\t\t\t\titems = append(items, js_ast.Expr{Loc: p.lexer.Loc(), Data: js_ast.EMissingShared})\n\n\t\t\tcase js_lexer.TDotDotDot:\n\t\t\t\tif errors != nil {\n\t\t\t\t\terrors.arraySpreadFeature = p.lexer.Range()\n\t\t\t\t} else {\n\t\t\t\t\tp.markSyntaxFeature(compat.ArraySpread, p.lexer.Range())\n\t\t\t\t}\n\t\t\t\tdotsLoc := p.saveExprCommentsHere()\n\t\t\t\tp.lexer.Next()\n\t\t\t\titem := p.parseExprOrBindings(js_ast.LComma, &selfErrors)\n\t\t\t\titems = append(items, js_ast.Expr{Loc: dotsLoc, Data: &js_ast.ESpread{Value: item}})\n\n\t\t\t\t// Commas are not allowed here when destructuring\n\t\t\t\tif p.lexer.Token == js_lexer.TComma {\n\t\t\t\t\tcommaAfterSpread = p.lexer.Loc()\n\t\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\titem := p.parseExprOrBindings(js_ast.LComma, &selfErrors)\n\t\t\t\titems = append(items, item)\n\t\t\t}\n\n\t\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\tisSingleLine = false\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\tisSingleLine = false\n\t\t\t}\n\t\t}\n\n\t\tif p.lexer.HasNewlineBefore {\n\t\t\tisSingleLine = false\n\t\t}\n\t\tcloseBracketLoc := p.saveExprCommentsHere()\n\t\tp.lexer.Expect(js_lexer.TCloseBracket)\n\t\tp.allowIn = oldAllowIn\n\n\t\tif p.willNeedBindingPattern() {\n\t\t\t// Is this a binding pattern?\n\t\t} else if errors == nil {\n\t\t\t// Is this an expression?\n\t\t\tp.logExprErrors(&selfErrors)\n\t\t} else {\n\t\t\t// In this case, we can't distinguish between the two yet\n\t\t\tselfErrors.mergeInto(errors)\n\t\t}\n\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EArray{\n\t\t\tItems:            items,\n\t\t\tCommaAfterSpread: commaAfterSpread,\n\t\t\tIsSingleLine:     isSingleLine,\n\t\t\tCloseBracketLoc:  closeBracketLoc,\n\t\t}}\n\n\tcase js_lexer.TOpenBrace:\n\t\tp.lexer.Next()\n\t\tisSingleLine := !p.lexer.HasNewlineBefore\n\t\tproperties := []js_ast.Property{}\n\t\tselfErrors := deferredErrors{}\n\t\tcommaAfterSpread := logger.Loc{}\n\n\t\t// Allow \"in\" inside object literals\n\t\toldAllowIn := p.allowIn\n\t\tp.allowIn = true\n\n\t\tfor p.lexer.Token != js_lexer.TCloseBrace {\n\t\t\tif p.lexer.Token == js_lexer.TDotDotDot {\n\t\t\t\tdotLoc := p.saveExprCommentsHere()\n\t\t\t\tp.lexer.Next()\n\t\t\t\tvalue := p.parseExprOrBindings(js_ast.LComma, &selfErrors)\n\t\t\t\tproperties = append(properties, js_ast.Property{\n\t\t\t\t\tKind:       js_ast.PropertySpread,\n\t\t\t\t\tLoc:        dotLoc,\n\t\t\t\t\tValueOrNil: value,\n\t\t\t\t})\n\n\t\t\t\t// Commas are not allowed here when destructuring\n\t\t\t\tif p.lexer.Token == js_lexer.TComma {\n\t\t\t\t\tcommaAfterSpread = p.lexer.Loc()\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// This property may turn out to be a type in TypeScript, which should be ignored\n\t\t\t\tif property, ok := p.parseProperty(p.saveExprCommentsHere(), js_ast.PropertyField, propertyOpts{}, &selfErrors); ok {\n\t\t\t\t\tproperties = append(properties, property)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\tisSingleLine = false\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\tisSingleLine = false\n\t\t\t}\n\t\t}\n\n\t\tif p.lexer.HasNewlineBefore {\n\t\t\tisSingleLine = false\n\t\t}\n\t\tcloseBraceLoc := p.saveExprCommentsHere()\n\t\tp.lexer.Expect(js_lexer.TCloseBrace)\n\t\tp.allowIn = oldAllowIn\n\n\t\tif p.willNeedBindingPattern() {\n\t\t\t// Is this a binding pattern?\n\t\t} else if errors == nil {\n\t\t\t// Is this an expression?\n\t\t\tp.logExprErrors(&selfErrors)\n\t\t} else {\n\t\t\t// In this case, we can't distinguish between the two yet\n\t\t\tselfErrors.mergeInto(errors)\n\t\t}\n\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EObject{\n\t\t\tProperties:       properties,\n\t\t\tCommaAfterSpread: commaAfterSpread,\n\t\t\tIsSingleLine:     isSingleLine,\n\t\t\tCloseBraceLoc:    closeBraceLoc,\n\t\t}}\n\n\tcase js_lexer.TLessThan:\n\t\t// This is a very complicated and highly ambiguous area of TypeScript\n\t\t// syntax. Many similar-looking things are overloaded.\n\t\t//\n\t\t// TS:\n\t\t//\n\t\t//   A type cast:\n\t\t//     <A>(x)\n\t\t//     <[]>(x)\n\t\t//     <A[]>(x)\n\t\t//     <const>(x)\n\t\t//\n\t\t//   An arrow function with type parameters:\n\t\t//     <A>(x) => {}\n\t\t//     <A, B>(x) => {}\n\t\t//     <A = B>(x) => {}\n\t\t//     <A extends B>(x) => {}\n\t\t//     <const A>(x) => {}\n\t\t//     <const A extends B>(x) => {}\n\t\t//\n\t\t//   A syntax error:\n\t\t//     <>() => {}\n\t\t//\n\t\t// TSX:\n\t\t//\n\t\t//   A JSX element:\n\t\t//     <>() => {}</>\n\t\t//     <A>(x) => {}</A>\n\t\t//     <A extends/>\n\t\t//     <A extends>(x) => {}</A>\n\t\t//     <A extends={false}>(x) => {}</A>\n\t\t//     <const A extends/>\n\t\t//     <const A extends>(x) => {}</const>\n\t\t//\n\t\t//   An arrow function with type parameters:\n\t\t//     <A,>(x) => {}\n\t\t//     <A, B>(x) => {}\n\t\t//     <A = B>(x) => {}\n\t\t//     <A extends B>(x) => {}\n\t\t//     <const>(x)</const>\n\t\t//     <const A extends B>(x) => {}\n\t\t//\n\t\t//   A syntax error:\n\t\t//     <[]>(x)\n\t\t//     <A[]>(x)\n\t\t//     <>() => {}\n\t\t//     <A>(x) => {}\n\n\t\tif p.options.ts.Parse && p.options.jsx.Parse && p.isTSArrowFnJSX() {\n\t\t\tp.skipTypeScriptTypeParameters(allowConstModifier)\n\t\t\tp.lexer.Expect(js_lexer.TOpenParen)\n\t\t\treturn p.parseParenExpr(loc, level, parenExprOpts{forceArrowFn: true})\n\t\t}\n\n\t\t// Print a friendly error message when parsing JSX as JavaScript\n\t\tif !p.options.jsx.Parse && !p.options.ts.Parse {\n\t\t\tvar how string\n\t\t\tswitch logger.API {\n\t\t\tcase logger.CLIAPI:\n\t\t\t\thow = \" You can use \\\"--loader:.js=jsx\\\" to do that.\"\n\t\t\tcase logger.JSAPI:\n\t\t\t\thow = \" You can use \\\"loader: { '.js': 'jsx' }\\\" to do that.\"\n\t\t\tcase logger.GoAPI:\n\t\t\t\thow = \" You can use 'Loader: map[string]api.Loader{\\\".js\\\": api.LoaderJSX}' to do that.\"\n\t\t\t}\n\t\t\tp.log.AddErrorWithNotes(&p.tracker, p.lexer.Range(), \"The JSX syntax extension is not currently enabled\", []logger.MsgData{{\n\t\t\t\tText: \"The esbuild loader for this file is currently set to \\\"js\\\" but it must be set to \\\"jsx\\\" to be able to parse JSX syntax.\" + how}})\n\t\t\tp.options.jsx.Parse = true\n\t\t}\n\n\t\tif p.options.jsx.Parse {\n\t\t\t// Use NextInsideJSXElement() instead of Next() so we parse \"<<\" as \"<\"\n\t\t\tp.lexer.NextInsideJSXElement()\n\t\t\telement := p.parseJSXElement(loc)\n\n\t\t\t// The call to parseJSXElement() above doesn't consume the last\n\t\t\t// TGreaterThan because the caller knows what Next() function to call.\n\t\t\t// Use Next() instead of NextInsideJSXElement() here since the next\n\t\t\t// token is an expression.\n\t\t\tp.lexer.Next()\n\t\t\treturn element\n\t\t}\n\n\t\tif p.options.ts.Parse {\n\t\t\t// This is either an old-style type cast or a generic lambda function\n\n\t\t\t// TypeScript 4.5 introduced the \".mts\" and \".cts\" extensions that forbid\n\t\t\t// the use of an expression starting with \"<\" that would be ambiguous\n\t\t\t// when the file is in JSX mode.\n\t\t\tif p.options.ts.NoAmbiguousLessThan && !p.isTSArrowFnJSX() {\n\t\t\t\tp.log.AddError(&p.tracker, p.lexer.Range(),\n\t\t\t\t\t\"This syntax is not allowed in files with the \\\".mts\\\" or \\\".cts\\\" extension\")\n\t\t\t}\n\n\t\t\t// \"<T>(x)\"\n\t\t\t// \"<T>(x) => {}\"\n\t\t\tif result := p.trySkipTypeScriptTypeParametersThenOpenParenWithBacktracking(); result != didNotSkipAnything {\n\t\t\t\tp.lexer.Expect(js_lexer.TOpenParen)\n\t\t\t\treturn p.parseParenExpr(loc, level, parenExprOpts{\n\t\t\t\t\tforceArrowFn: result == definitelyTypeParameters,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// \"<T>x\"\n\t\t\tp.lexer.Next()\n\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\tp.lexer.ExpectGreaterThan(false /* isInsideJSXElement */)\n\t\t\tvalue := p.parsePrefix(level, errors, flags)\n\t\t\treturn value\n\t\t}\n\n\t\tp.lexer.Unexpected()\n\t\treturn js_ast.Expr{}\n\n\tcase js_lexer.TImport:\n\t\tp.lexer.Next()\n\t\treturn p.parseImportExpr(loc, level)\n\n\tdefault:\n\t\tp.lexer.Unexpected()\n\t\treturn js_ast.Expr{}\n\t}\n}\n\nfunc (p *parser) parseYieldExpr(loc logger.Loc) js_ast.Expr {\n\t// Parse a yield-from expression, which yields from an iterator\n\tisStar := p.lexer.Token == js_lexer.TAsterisk\n\tif isStar && !p.lexer.HasNewlineBefore {\n\t\tp.lexer.Next()\n\t}\n\n\tvar valueOrNil js_ast.Expr\n\n\t// The yield expression only has a value in certain cases\n\tif isStar {\n\t\tvalueOrNil = p.parseExpr(js_ast.LYield)\n\t} else {\n\t\tswitch p.lexer.Token {\n\t\tcase js_lexer.TCloseBrace, js_lexer.TCloseBracket, js_lexer.TCloseParen,\n\t\t\tjs_lexer.TColon, js_lexer.TComma, js_lexer.TSemicolon:\n\n\t\tdefault:\n\t\t\tif !p.lexer.HasNewlineBefore {\n\t\t\t\tvalueOrNil = p.parseExpr(js_ast.LYield)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EYield{ValueOrNil: valueOrNil, IsStar: isStar}}\n}\n\nfunc (p *parser) willNeedBindingPattern() bool {\n\tswitch p.lexer.Token {\n\tcase js_lexer.TEquals:\n\t\t// \"[a] = b;\"\n\t\treturn true\n\n\tcase js_lexer.TIn:\n\t\t// \"for ([a] in b) {}\"\n\t\treturn !p.allowIn\n\n\tcase js_lexer.TIdentifier:\n\t\t// \"for ([a] of b) {}\"\n\t\treturn !p.allowIn && p.lexer.IsContextualKeyword(\"of\")\n\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// Note: The caller has already parsed the \"import\" keyword\nfunc (p *parser) parseImportExpr(loc logger.Loc, level js_ast.L) js_ast.Expr {\n\t// Parse an \"import.meta\" expression\n\tphase := ast.EvaluationPhase\n\tif p.lexer.Token == js_lexer.TDot {\n\t\tp.lexer.Next()\n\t\tif p.lexer.IsContextualKeyword(\"meta\") {\n\t\t\tp.esmImportMeta = logger.Range{Loc: loc, Len: p.lexer.Range().End() - loc.Start}\n\t\t\tp.lexer.Next()\n\t\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EImportMeta{RangeLen: p.esmImportMeta.Len}}\n\t\t} else if p.lexer.IsContextualKeyword(\"defer\") {\n\t\t\tp.markSyntaxFeature(compat.ImportDefer, p.lexer.Range())\n\t\t\tphase = ast.DeferPhase\n\t\t\tp.lexer.Next()\n\t\t} else if p.lexer.IsContextualKeyword(\"source\") {\n\t\t\tp.markSyntaxFeature(compat.ImportSource, p.lexer.Range())\n\t\t\tphase = ast.SourcePhase\n\t\t\tp.lexer.Next()\n\t\t} else {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t}\n\n\tif level > js_ast.LCall {\n\t\tr := js_lexer.RangeOfIdentifier(p.source, loc)\n\t\tp.log.AddError(&p.tracker, r, \"Cannot use an \\\"import\\\" expression here without parentheses:\")\n\t}\n\n\t// Allow \"in\" inside call arguments\n\toldAllowIn := p.allowIn\n\tp.allowIn = true\n\n\tp.lexer.Expect(js_lexer.TOpenParen)\n\n\tvalue := p.parseExpr(js_ast.LComma)\n\tvar optionsOrNil js_ast.Expr\n\n\tif p.lexer.Token == js_lexer.TComma {\n\t\t// \"import('./foo.json', )\"\n\t\tp.lexer.Next()\n\n\t\tif p.lexer.Token != js_lexer.TCloseParen {\n\t\t\t// \"import('./foo.json', { assert: { type: 'json' } })\"\n\t\t\toptionsOrNil = p.parseExpr(js_ast.LComma)\n\n\t\t\tif p.lexer.Token == js_lexer.TComma {\n\t\t\t\t// \"import('./foo.json', { assert: { type: 'json' } }, )\"\n\t\t\t\tp.lexer.Next()\n\t\t\t}\n\t\t}\n\t}\n\n\tcloseParenLoc := p.saveExprCommentsHere()\n\tp.lexer.Expect(js_lexer.TCloseParen)\n\n\tp.allowIn = oldAllowIn\n\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EImportCall{\n\t\tExpr:          value,\n\t\tOptionsOrNil:  optionsOrNil,\n\t\tCloseParenLoc: closeParenLoc,\n\t\tPhase:         phase,\n\t}}\n}\n\nfunc (p *parser) parseExprOrBindings(level js_ast.L, errors *deferredErrors) js_ast.Expr {\n\treturn p.parseExprCommon(level, errors, 0)\n}\n\nfunc (p *parser) parseExpr(level js_ast.L) js_ast.Expr {\n\treturn p.parseExprCommon(level, nil, 0)\n}\n\nfunc (p *parser) parseExprWithFlags(level js_ast.L, flags exprFlag) js_ast.Expr {\n\treturn p.parseExprCommon(level, nil, flags)\n}\n\nfunc (p *parser) parseExprCommon(level js_ast.L, errors *deferredErrors, flags exprFlag) js_ast.Expr {\n\tlexerCommentFlags := p.lexer.HasCommentBefore\n\texpr := p.parsePrefix(level, errors, flags)\n\n\tif (lexerCommentFlags&(js_lexer.PureCommentBefore|js_lexer.NoSideEffectsCommentBefore)) != 0 && !p.options.ignoreDCEAnnotations {\n\t\tif (lexerCommentFlags & js_lexer.NoSideEffectsCommentBefore) != 0 {\n\t\t\tswitch e := expr.Data.(type) {\n\t\t\tcase *js_ast.EArrow:\n\t\t\t\te.HasNoSideEffectsComment = true\n\t\t\tcase *js_ast.EFunction:\n\t\t\t\te.Fn.HasNoSideEffectsComment = true\n\t\t\t}\n\t\t}\n\n\t\t// There is no formal spec for \"__PURE__\" comments but from reverse-\n\t\t// engineering, it looks like they apply to the next CallExpression or\n\t\t// NewExpression. So in \"/* @__PURE__ */ a().b() + c()\" the comment applies\n\t\t// to the expression \"a().b()\".\n\t\tif (lexerCommentFlags&js_lexer.PureCommentBefore) != 0 && level < js_ast.LCall {\n\t\t\texpr = p.parseSuffix(expr, js_ast.LCall-1, errors, flags)\n\t\t\tswitch e := expr.Data.(type) {\n\t\t\tcase *js_ast.ECall:\n\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\tcase *js_ast.ENew:\n\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn p.parseSuffix(expr, level, errors, flags)\n}\n\nfunc (p *parser) parseSuffix(left js_ast.Expr, level js_ast.L, errors *deferredErrors, flags exprFlag) js_ast.Expr {\n\toptionalChain := js_ast.OptionalChainNone\n\n\tfor {\n\t\tif p.lexer.Loc() == p.afterArrowBodyLoc {\n\t\t\tfor {\n\t\t\t\tswitch p.lexer.Token {\n\t\t\t\tcase js_lexer.TComma:\n\t\t\t\t\tif level >= js_ast.LComma {\n\t\t\t\t\t\treturn left\n\t\t\t\t\t}\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpComma, Left: left, Right: p.parseExpr(js_ast.LComma)}}\n\n\t\t\t\tdefault:\n\t\t\t\t\treturn left\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Stop now if this token is forbidden to follow a TypeScript \"as\" cast\n\t\tif p.lexer.Loc() == p.forbidSuffixAfterAsLoc {\n\t\t\treturn left\n\t\t}\n\n\t\t// Reset the optional chain flag by default. That way we won't accidentally\n\t\t// treat \"c.d\" as OptionalChainContinue in \"a?.b + c.d\".\n\t\toldOptionalChain := optionalChain\n\t\toptionalChain = js_ast.OptionalChainNone\n\n\t\tswitch p.lexer.Token {\n\t\tcase js_lexer.TDot:\n\t\t\tp.lexer.Next()\n\n\t\t\tif p.lexer.Token == js_lexer.TPrivateIdentifier {\n\t\t\t\t// \"a.#b\"\n\t\t\t\t// \"a?.b.#c\"\n\t\t\t\tif _, ok := left.Data.(*js_ast.ESuper); ok {\n\t\t\t\t\tp.lexer.Expected(js_lexer.TIdentifier)\n\t\t\t\t}\n\t\t\t\tname := p.lexer.Identifier\n\t\t\t\tnameLoc := p.lexer.Loc()\n\t\t\t\tp.reportPrivateNameUsage(name.String)\n\t\t\t\tp.lexer.Next()\n\t\t\t\tref := p.storeNameInRef(name)\n\t\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EIndex{\n\t\t\t\t\tTarget:        left,\n\t\t\t\t\tIndex:         js_ast.Expr{Loc: nameLoc, Data: &js_ast.EPrivateIdentifier{Ref: ref}},\n\t\t\t\t\tOptionalChain: oldOptionalChain,\n\t\t\t\t}}\n\t\t\t} else {\n\t\t\t\t// \"a.b\"\n\t\t\t\t// \"a?.b.c\"\n\t\t\t\tif !p.lexer.IsIdentifierOrKeyword() {\n\t\t\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t\t\t}\n\t\t\t\tname := p.lexer.Identifier\n\t\t\t\tnameLoc := p.lexer.Loc()\n\t\t\t\tp.lexer.Next()\n\t\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: p.dotOrMangledPropParse(left, name, nameLoc, oldOptionalChain, wasOriginallyDot)}\n\t\t\t}\n\n\t\t\toptionalChain = oldOptionalChain\n\n\t\tcase js_lexer.TQuestionDot:\n\t\t\tp.lexer.Next()\n\t\t\toptionalStart := js_ast.OptionalChainStart\n\n\t\t\t// Remove unnecessary optional chains\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tif isNullOrUndefined, _, ok := js_ast.ToNullOrUndefinedWithSideEffects(left.Data); ok && !isNullOrUndefined {\n\t\t\t\t\toptionalStart = js_ast.OptionalChainNone\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tswitch p.lexer.Token {\n\t\t\tcase js_lexer.TOpenBracket:\n\t\t\t\t// \"a?.[b]\"\n\t\t\t\tp.lexer.Next()\n\n\t\t\t\t// Allow \"in\" inside the brackets\n\t\t\t\toldAllowIn := p.allowIn\n\t\t\t\tp.allowIn = true\n\n\t\t\t\tindex := p.parseExpr(js_ast.LLowest)\n\n\t\t\t\tp.allowIn = oldAllowIn\n\n\t\t\t\tcloseBracketLoc := p.saveExprCommentsHere()\n\t\t\t\tp.lexer.Expect(js_lexer.TCloseBracket)\n\t\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EIndex{\n\t\t\t\t\tTarget:          left,\n\t\t\t\t\tIndex:           index,\n\t\t\t\t\tOptionalChain:   optionalStart,\n\t\t\t\t\tCloseBracketLoc: closeBracketLoc,\n\t\t\t\t}}\n\n\t\t\tcase js_lexer.TOpenParen:\n\t\t\t\t// \"a?.()\"\n\t\t\t\tif level >= js_ast.LCall {\n\t\t\t\t\treturn left\n\t\t\t\t}\n\t\t\t\tkind := js_ast.NormalCall\n\t\t\t\tif js_ast.IsPropertyAccess(left) {\n\t\t\t\t\tkind = js_ast.TargetWasOriginallyPropertyAccess\n\t\t\t\t}\n\t\t\t\targs, closeParenLoc, isMultiLine := p.parseCallArgs()\n\t\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.ECall{\n\t\t\t\t\tTarget:        left,\n\t\t\t\t\tArgs:          args,\n\t\t\t\t\tCloseParenLoc: closeParenLoc,\n\t\t\t\t\tOptionalChain: optionalStart,\n\t\t\t\t\tIsMultiLine:   isMultiLine,\n\t\t\t\t\tKind:          kind,\n\t\t\t\t}}\n\n\t\t\tcase js_lexer.TLessThan, js_lexer.TLessThanLessThan:\n\t\t\t\t// \"a?.<T>()\"\n\t\t\t\t// \"a?.<<T>() => T>()\"\n\t\t\t\tif !p.options.ts.Parse {\n\t\t\t\t\tp.lexer.Expected(js_lexer.TIdentifier)\n\t\t\t\t}\n\t\t\t\tp.skipTypeScriptTypeArguments(skipTypeScriptTypeArgumentsOpts{})\n\t\t\t\tif p.lexer.Token != js_lexer.TOpenParen {\n\t\t\t\t\tp.lexer.Expected(js_lexer.TOpenParen)\n\t\t\t\t}\n\t\t\t\tif level >= js_ast.LCall {\n\t\t\t\t\treturn left\n\t\t\t\t}\n\t\t\t\tkind := js_ast.NormalCall\n\t\t\t\tif js_ast.IsPropertyAccess(left) {\n\t\t\t\t\tkind = js_ast.TargetWasOriginallyPropertyAccess\n\t\t\t\t}\n\t\t\t\targs, closeParenLoc, isMultiLine := p.parseCallArgs()\n\t\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.ECall{\n\t\t\t\t\tTarget:        left,\n\t\t\t\t\tArgs:          args,\n\t\t\t\t\tCloseParenLoc: closeParenLoc,\n\t\t\t\t\tOptionalChain: optionalStart,\n\t\t\t\t\tIsMultiLine:   isMultiLine,\n\t\t\t\t\tKind:          kind,\n\t\t\t\t}}\n\n\t\t\tdefault:\n\t\t\t\tif p.lexer.Token == js_lexer.TPrivateIdentifier {\n\t\t\t\t\t// \"a?.#b\"\n\t\t\t\t\tname := p.lexer.Identifier\n\t\t\t\t\tnameLoc := p.lexer.Loc()\n\t\t\t\t\tp.reportPrivateNameUsage(name.String)\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tref := p.storeNameInRef(name)\n\t\t\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EIndex{\n\t\t\t\t\t\tTarget:        left,\n\t\t\t\t\t\tIndex:         js_ast.Expr{Loc: nameLoc, Data: &js_ast.EPrivateIdentifier{Ref: ref}},\n\t\t\t\t\t\tOptionalChain: optionalStart,\n\t\t\t\t\t}}\n\t\t\t\t} else {\n\t\t\t\t\t// \"a?.b\"\n\t\t\t\t\tif !p.lexer.IsIdentifierOrKeyword() {\n\t\t\t\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t\t\t\t}\n\t\t\t\t\tname := p.lexer.Identifier\n\t\t\t\t\tnameLoc := p.lexer.Loc()\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: p.dotOrMangledPropParse(left, name, nameLoc, optionalStart, wasOriginallyDot)}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Only continue if we have started\n\t\t\tif optionalStart == js_ast.OptionalChainStart {\n\t\t\t\toptionalChain = js_ast.OptionalChainContinue\n\t\t\t}\n\n\t\tcase js_lexer.TNoSubstitutionTemplateLiteral:\n\t\t\tif oldOptionalChain != js_ast.OptionalChainNone {\n\t\t\t\tp.log.AddError(&p.tracker, p.lexer.Range(), \"Template literals cannot have an optional chain as a tag\")\n\t\t\t}\n\t\t\theadLoc := p.lexer.Loc()\n\t\t\theadCooked, headRaw := p.lexer.CookedAndRawTemplateContents()\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.ETemplate{\n\t\t\t\tTagOrNil:                       left,\n\t\t\t\tHeadLoc:                        headLoc,\n\t\t\t\tHeadCooked:                     headCooked,\n\t\t\t\tHeadRaw:                        headRaw,\n\t\t\t\tTagWasOriginallyPropertyAccess: js_ast.IsPropertyAccess(left),\n\t\t\t}}\n\n\t\tcase js_lexer.TTemplateHead:\n\t\t\tif oldOptionalChain != js_ast.OptionalChainNone {\n\t\t\t\tp.log.AddError(&p.tracker, p.lexer.Range(), \"Template literals cannot have an optional chain as a tag\")\n\t\t\t}\n\t\t\theadLoc := p.lexer.Loc()\n\t\t\theadCooked, headRaw := p.lexer.CookedAndRawTemplateContents()\n\t\t\tparts, _ := p.parseTemplateParts(true /* includeRaw */)\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.ETemplate{\n\t\t\t\tTagOrNil:                       left,\n\t\t\t\tHeadLoc:                        headLoc,\n\t\t\t\tHeadCooked:                     headCooked,\n\t\t\t\tHeadRaw:                        headRaw,\n\t\t\t\tParts:                          parts,\n\t\t\t\tTagWasOriginallyPropertyAccess: js_ast.IsPropertyAccess(left),\n\t\t\t}}\n\n\t\tcase js_lexer.TOpenBracket:\n\t\t\t// When parsing a decorator, ignore EIndex expressions since they may be\n\t\t\t// part of a computed property:\n\t\t\t//\n\t\t\t//   class Foo {\n\t\t\t//     @foo ['computed']() {}\n\t\t\t//   }\n\t\t\t//\n\t\t\t// This matches the behavior of the TypeScript compiler.\n\t\t\tif (flags & exprFlagDecorator) != 0 {\n\t\t\t\treturn left\n\t\t\t}\n\n\t\t\tp.lexer.Next()\n\n\t\t\t// Allow \"in\" inside the brackets\n\t\t\toldAllowIn := p.allowIn\n\t\t\tp.allowIn = true\n\n\t\t\tindex := p.parseExpr(js_ast.LLowest)\n\n\t\t\tp.allowIn = oldAllowIn\n\n\t\t\tcloseBracketLoc := p.saveExprCommentsHere()\n\t\t\tp.lexer.Expect(js_lexer.TCloseBracket)\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EIndex{\n\t\t\t\tTarget:          left,\n\t\t\t\tIndex:           index,\n\t\t\t\tOptionalChain:   oldOptionalChain,\n\t\t\t\tCloseBracketLoc: closeBracketLoc,\n\t\t\t}}\n\t\t\toptionalChain = oldOptionalChain\n\n\t\tcase js_lexer.TOpenParen:\n\t\t\tif level >= js_ast.LCall {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tkind := js_ast.NormalCall\n\t\t\tif js_ast.IsPropertyAccess(left) {\n\t\t\t\tkind = js_ast.TargetWasOriginallyPropertyAccess\n\t\t\t}\n\t\t\targs, closeParenLoc, isMultiLine := p.parseCallArgs()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.ECall{\n\t\t\t\tTarget:        left,\n\t\t\t\tArgs:          args,\n\t\t\t\tCloseParenLoc: closeParenLoc,\n\t\t\t\tOptionalChain: oldOptionalChain,\n\t\t\t\tIsMultiLine:   isMultiLine,\n\t\t\t\tKind:          kind,\n\t\t\t}}\n\t\t\toptionalChain = oldOptionalChain\n\n\t\tcase js_lexer.TQuestion:\n\t\t\tif level >= js_ast.LConditional {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\n\t\t\t// Stop now if we're parsing one of these:\n\t\t\t// \"(a?) => {}\"\n\t\t\t// \"(a?: b) => {}\"\n\t\t\t// \"(a?, b?) => {}\"\n\t\t\tif p.options.ts.Parse && left.Loc == p.latestArrowArgLoc && (p.lexer.Token == js_lexer.TColon ||\n\t\t\t\tp.lexer.Token == js_lexer.TCloseParen || p.lexer.Token == js_lexer.TComma) {\n\t\t\t\tif errors == nil {\n\t\t\t\t\tp.lexer.Unexpected()\n\t\t\t\t}\n\t\t\t\terrors.invalidExprAfterQuestion = p.lexer.Range()\n\t\t\t\treturn left\n\t\t\t}\n\n\t\t\t// Allow \"in\" in between \"?\" and \":\"\n\t\t\toldAllowIn := p.allowIn\n\t\t\tp.allowIn = true\n\n\t\t\tyes := p.parseExprWithFlags(js_ast.LComma, exprFlagAfterQuestionAndBeforeColon)\n\n\t\t\tp.allowIn = oldAllowIn\n\n\t\t\tp.lexer.Expect(js_lexer.TColon)\n\t\t\tno := p.parseExprWithFlags(js_ast.LComma, flags&exprFlagAfterQuestionAndBeforeColon)\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EIf{Test: left, Yes: yes, No: no}}\n\n\t\tcase js_lexer.TExclamation:\n\t\t\t// Skip over TypeScript non-null assertions\n\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tif !p.options.ts.Parse {\n\t\t\t\tp.lexer.Unexpected()\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\toptionalChain = oldOptionalChain\n\n\t\tcase js_lexer.TMinusMinus:\n\t\t\tif p.lexer.HasNewlineBefore || level >= js_ast.LPostfix {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EUnary{Op: js_ast.UnOpPostDec, Value: left}}\n\n\t\tcase js_lexer.TPlusPlus:\n\t\t\tif p.lexer.HasNewlineBefore || level >= js_ast.LPostfix {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EUnary{Op: js_ast.UnOpPostInc, Value: left}}\n\n\t\tcase js_lexer.TComma:\n\t\t\tif level >= js_ast.LComma {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpComma, Left: left, Right: p.parseExpr(js_ast.LComma)}}\n\n\t\tcase js_lexer.TPlus:\n\t\t\tif level >= js_ast.LAdd {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpAdd, Left: left, Right: p.parseExpr(js_ast.LAdd)}}\n\n\t\tcase js_lexer.TPlusEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpAddAssign, Left: left, Right: p.parseExpr(js_ast.LAssign - 1)}}\n\n\t\tcase js_lexer.TMinus:\n\t\t\tif level >= js_ast.LAdd {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpSub, Left: left, Right: p.parseExpr(js_ast.LAdd)}}\n\n\t\tcase js_lexer.TMinusEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpSubAssign, Left: left, Right: p.parseExpr(js_ast.LAssign - 1)}}\n\n\t\tcase js_lexer.TAsterisk:\n\t\t\tif level >= js_ast.LMultiply {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpMul, Left: left, Right: p.parseExpr(js_ast.LMultiply)}}\n\n\t\tcase js_lexer.TAsteriskAsterisk:\n\t\t\tif level >= js_ast.LExponentiation {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpPow, Left: left, Right: p.parseExpr(js_ast.LExponentiation - 1)}}\n\n\t\tcase js_lexer.TAsteriskAsteriskEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpPowAssign, Left: left, Right: p.parseExpr(js_ast.LAssign - 1)}}\n\n\t\tcase js_lexer.TAsteriskEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpMulAssign, Left: left, Right: p.parseExpr(js_ast.LAssign - 1)}}\n\n\t\tcase js_lexer.TPercent:\n\t\t\tif level >= js_ast.LMultiply {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpRem, Left: left, Right: p.parseExpr(js_ast.LMultiply)}}\n\n\t\tcase js_lexer.TPercentEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpRemAssign, Left: left, Right: p.parseExpr(js_ast.LAssign - 1)}}\n\n\t\tcase js_lexer.TSlash:\n\t\t\tif level >= js_ast.LMultiply {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpDiv, Left: left, Right: p.parseExpr(js_ast.LMultiply)}}\n\n\t\tcase js_lexer.TSlashEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpDivAssign, Left: left, Right: p.parseExpr(js_ast.LAssign - 1)}}\n\n\t\tcase js_lexer.TEqualsEquals:\n\t\t\tif level >= js_ast.LEquals {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpLooseEq, Left: left, Right: p.parseExpr(js_ast.LEquals)}}\n\n\t\tcase js_lexer.TExclamationEquals:\n\t\t\tif level >= js_ast.LEquals {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpLooseNe, Left: left, Right: p.parseExpr(js_ast.LEquals)}}\n\n\t\tcase js_lexer.TEqualsEqualsEquals:\n\t\t\tif level >= js_ast.LEquals {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpStrictEq, Left: left, Right: p.parseExpr(js_ast.LEquals)}}\n\n\t\tcase js_lexer.TExclamationEqualsEquals:\n\t\t\tif level >= js_ast.LEquals {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpStrictNe, Left: left, Right: p.parseExpr(js_ast.LEquals)}}\n\n\t\tcase js_lexer.TLessThan:\n\t\t\t// TypeScript allows type arguments to be specified with angle brackets\n\t\t\t// inside an expression. Unlike in other languages, this unfortunately\n\t\t\t// appears to require backtracking to parse.\n\t\t\tif p.options.ts.Parse && p.trySkipTypeArgumentsInExpressionWithBacktracking() {\n\t\t\t\toptionalChain = oldOptionalChain\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif level >= js_ast.LCompare {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpLt, Left: left, Right: p.parseExpr(js_ast.LCompare)}}\n\n\t\tcase js_lexer.TLessThanEquals:\n\t\t\tif level >= js_ast.LCompare {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpLe, Left: left, Right: p.parseExpr(js_ast.LCompare)}}\n\n\t\tcase js_lexer.TGreaterThan:\n\t\t\tif level >= js_ast.LCompare {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpGt, Left: left, Right: p.parseExpr(js_ast.LCompare)}}\n\n\t\tcase js_lexer.TGreaterThanEquals:\n\t\t\tif level >= js_ast.LCompare {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpGe, Left: left, Right: p.parseExpr(js_ast.LCompare)}}\n\n\t\tcase js_lexer.TLessThanLessThan:\n\t\t\t// TypeScript allows type arguments to be specified with angle brackets\n\t\t\t// inside an expression. Unlike in other languages, this unfortunately\n\t\t\t// appears to require backtracking to parse.\n\t\t\tif p.options.ts.Parse && p.trySkipTypeArgumentsInExpressionWithBacktracking() {\n\t\t\t\toptionalChain = oldOptionalChain\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif level >= js_ast.LShift {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpShl, Left: left, Right: p.parseExpr(js_ast.LShift)}}\n\n\t\tcase js_lexer.TLessThanLessThanEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpShlAssign, Left: left, Right: p.parseExpr(js_ast.LAssign - 1)}}\n\n\t\tcase js_lexer.TGreaterThanGreaterThan:\n\t\t\tif level >= js_ast.LShift {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpShr, Left: left, Right: p.parseExpr(js_ast.LShift)}}\n\n\t\tcase js_lexer.TGreaterThanGreaterThanEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpShrAssign, Left: left, Right: p.parseExpr(js_ast.LAssign - 1)}}\n\n\t\tcase js_lexer.TGreaterThanGreaterThanGreaterThan:\n\t\t\tif level >= js_ast.LShift {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpUShr, Left: left, Right: p.parseExpr(js_ast.LShift)}}\n\n\t\tcase js_lexer.TGreaterThanGreaterThanGreaterThanEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpUShrAssign, Left: left, Right: p.parseExpr(js_ast.LAssign - 1)}}\n\n\t\tcase js_lexer.TQuestionQuestion:\n\t\t\tif level >= js_ast.LNullishCoalescing {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpNullishCoalescing, Left: left, Right: p.parseExpr(js_ast.LNullishCoalescing)}}\n\n\t\tcase js_lexer.TQuestionQuestionEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpNullishCoalescingAssign, Left: left, Right: p.parseExpr(js_ast.LAssign - 1)}}\n\n\t\tcase js_lexer.TBarBar:\n\t\t\tif level >= js_ast.LLogicalOr {\n\t\t\t\treturn left\n\t\t\t}\n\n\t\t\t// Prevent \"||\" inside \"??\" from the right\n\t\t\tif level == js_ast.LNullishCoalescing {\n\t\t\t\tp.logNullishCoalescingErrorPrecedenceError(\"||\")\n\t\t\t}\n\n\t\t\tp.lexer.Next()\n\t\t\tright := p.parseExpr(js_ast.LLogicalOr)\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpLogicalOr, Left: left, Right: right}}\n\n\t\t\t// Prevent \"||\" inside \"??\" from the left\n\t\t\tif level < js_ast.LNullishCoalescing {\n\t\t\t\tleft = p.parseSuffix(left, js_ast.LNullishCoalescing+1, nil, flags)\n\t\t\t\tif p.lexer.Token == js_lexer.TQuestionQuestion {\n\t\t\t\t\tp.logNullishCoalescingErrorPrecedenceError(\"||\")\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase js_lexer.TBarBarEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpLogicalOrAssign, Left: left, Right: p.parseExpr(js_ast.LAssign - 1)}}\n\n\t\tcase js_lexer.TAmpersandAmpersand:\n\t\t\tif level >= js_ast.LLogicalAnd {\n\t\t\t\treturn left\n\t\t\t}\n\n\t\t\t// Prevent \"&&\" inside \"??\" from the right\n\t\t\tif level == js_ast.LNullishCoalescing {\n\t\t\t\tp.logNullishCoalescingErrorPrecedenceError(\"&&\")\n\t\t\t}\n\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpLogicalAnd, Left: left, Right: p.parseExpr(js_ast.LLogicalAnd)}}\n\n\t\t\t// Prevent \"&&\" inside \"??\" from the left\n\t\t\tif level < js_ast.LNullishCoalescing {\n\t\t\t\tleft = p.parseSuffix(left, js_ast.LNullishCoalescing+1, nil, flags)\n\t\t\t\tif p.lexer.Token == js_lexer.TQuestionQuestion {\n\t\t\t\t\tp.logNullishCoalescingErrorPrecedenceError(\"&&\")\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase js_lexer.TAmpersandAmpersandEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpLogicalAndAssign, Left: left, Right: p.parseExpr(js_ast.LAssign - 1)}}\n\n\t\tcase js_lexer.TBar:\n\t\t\tif level >= js_ast.LBitwiseOr {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpBitwiseOr, Left: left, Right: p.parseExpr(js_ast.LBitwiseOr)}}\n\n\t\tcase js_lexer.TBarEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpBitwiseOrAssign, Left: left, Right: p.parseExpr(js_ast.LAssign - 1)}}\n\n\t\tcase js_lexer.TAmpersand:\n\t\t\tif level >= js_ast.LBitwiseAnd {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpBitwiseAnd, Left: left, Right: p.parseExpr(js_ast.LBitwiseAnd)}}\n\n\t\tcase js_lexer.TAmpersandEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpBitwiseAndAssign, Left: left, Right: p.parseExpr(js_ast.LAssign - 1)}}\n\n\t\tcase js_lexer.TCaret:\n\t\t\tif level >= js_ast.LBitwiseXor {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpBitwiseXor, Left: left, Right: p.parseExpr(js_ast.LBitwiseXor)}}\n\n\t\tcase js_lexer.TCaretEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpBitwiseXorAssign, Left: left, Right: p.parseExpr(js_ast.LAssign - 1)}}\n\n\t\tcase js_lexer.TEquals:\n\t\t\tif level >= js_ast.LAssign {\n\t\t\t\treturn left\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Assign(left, p.parseExpr(js_ast.LAssign-1))\n\n\t\tcase js_lexer.TIn:\n\t\t\tif level >= js_ast.LCompare || !p.allowIn {\n\t\t\t\treturn left\n\t\t\t}\n\n\t\t\t// Warn about \"!a in b\" instead of \"!(a in b)\"\n\t\t\tkind := logger.Warning\n\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\tkind = logger.Debug\n\t\t\t}\n\t\t\tif e, ok := left.Data.(*js_ast.EUnary); ok && e.Op == js_ast.UnOpNot {\n\t\t\t\tr := logger.Range{Loc: left.Loc, Len: p.source.LocBeforeWhitespace(p.lexer.Loc()).Start - left.Loc.Start}\n\t\t\t\tdata := p.tracker.MsgData(r, \"Suspicious use of the \\\"!\\\" operator inside the \\\"in\\\" operator\")\n\t\t\t\tdata.Location.Suggestion = fmt.Sprintf(\"(%s)\", p.source.TextForRange(r))\n\t\t\t\tp.log.AddMsgID(logger.MsgID_JS_SuspiciousBooleanNot, logger.Msg{\n\t\t\t\t\tKind: kind,\n\t\t\t\t\tData: data,\n\t\t\t\t\tNotes: []logger.MsgData{{Text: \"The code \\\"!x in y\\\" is parsed as \\\"(!x) in y\\\". \" +\n\t\t\t\t\t\t\"You need to insert parentheses to get \\\"!(x in y)\\\" instead.\"}},\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpIn, Left: left, Right: p.parseExpr(js_ast.LCompare)}}\n\n\t\tcase js_lexer.TInstanceof:\n\t\t\tif level >= js_ast.LCompare {\n\t\t\t\treturn left\n\t\t\t}\n\n\t\t\t// Warn about \"!a instanceof b\" instead of \"!(a instanceof b)\". Here's an\n\t\t\t// example of code with this problem: https://github.com/mrdoob/three.js/pull/11182.\n\t\t\tkind := logger.Warning\n\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\tkind = logger.Debug\n\t\t\t}\n\t\t\tif e, ok := left.Data.(*js_ast.EUnary); ok && e.Op == js_ast.UnOpNot {\n\t\t\t\tr := logger.Range{Loc: left.Loc, Len: p.source.LocBeforeWhitespace(p.lexer.Loc()).Start - left.Loc.Start}\n\t\t\t\tdata := p.tracker.MsgData(r, \"Suspicious use of the \\\"!\\\" operator inside the \\\"instanceof\\\" operator\")\n\t\t\t\tdata.Location.Suggestion = fmt.Sprintf(\"(%s)\", p.source.TextForRange(r))\n\t\t\t\tp.log.AddMsgID(logger.MsgID_JS_SuspiciousBooleanNot, logger.Msg{\n\t\t\t\t\tKind: kind,\n\t\t\t\t\tData: data,\n\t\t\t\t\tNotes: []logger.MsgData{{Text: \"The code \\\"!x instanceof y\\\" is parsed as \\\"(!x) instanceof y\\\". \" +\n\t\t\t\t\t\t\"You need to insert parentheses to get \\\"!(x instanceof y)\\\" instead.\"}},\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tp.lexer.Next()\n\t\t\tleft = js_ast.Expr{Loc: left.Loc, Data: &js_ast.EBinary{Op: js_ast.BinOpInstanceof, Left: left, Right: p.parseExpr(js_ast.LCompare)}}\n\n\t\tdefault:\n\t\t\t// Handle the TypeScript \"as\"/\"satisfies\" operator\n\t\t\tif p.options.ts.Parse && level < js_ast.LCompare && !p.lexer.HasNewlineBefore && (p.lexer.IsContextualKeyword(\"as\") || p.lexer.IsContextualKeyword(\"satisfies\")) {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\n\t\t\t\t// These tokens are not allowed to follow a cast expression. This isn't\n\t\t\t\t// an outright error because it may be on a new line, in which case it's\n\t\t\t\t// the start of a new expression when it's after a cast:\n\t\t\t\t//\n\t\t\t\t//   x = y as z\n\t\t\t\t//   (something);\n\t\t\t\t//\n\t\t\t\tswitch p.lexer.Token {\n\t\t\t\tcase js_lexer.TPlusPlus, js_lexer.TMinusMinus, js_lexer.TNoSubstitutionTemplateLiteral,\n\t\t\t\t\tjs_lexer.TTemplateHead, js_lexer.TOpenParen, js_lexer.TOpenBracket, js_lexer.TQuestionDot:\n\t\t\t\t\tp.forbidSuffixAfterAsLoc = p.lexer.Loc()\n\t\t\t\t\treturn left\n\t\t\t\t}\n\t\t\t\tif p.lexer.Token.IsAssign() {\n\t\t\t\t\tp.forbidSuffixAfterAsLoc = p.lexer.Loc()\n\t\t\t\t\treturn left\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\treturn left\n\t\t}\n\t}\n}\n\nfunc (p *parser) parseExprOrLetOrUsingStmt(opts parseStmtOpts) (js_ast.Expr, js_ast.Stmt, []js_ast.Decl) {\n\tcouldBeLet := false\n\tcouldBeUsing := false\n\tcouldBeAwaitUsing := false\n\ttokenRange := p.lexer.Range()\n\n\tif p.lexer.Token == js_lexer.TIdentifier {\n\t\traw := p.lexer.Raw()\n\t\tcouldBeLet = raw == \"let\"\n\t\tcouldBeUsing = raw == \"using\"\n\t\tcouldBeAwaitUsing = raw == \"await\" && p.fnOrArrowDataParse.await == allowExpr\n\t}\n\n\tif !couldBeLet && !couldBeUsing && !couldBeAwaitUsing {\n\t\tvar flags exprFlag\n\t\tif opts.isForLoopInit {\n\t\t\tflags |= exprFlagForLoopInit\n\t\t}\n\t\tif opts.isForAwaitLoopInit {\n\t\t\tflags |= exprFlagForAwaitLoopInit\n\t\t}\n\t\treturn p.parseExprCommon(js_ast.LLowest, nil, flags), js_ast.Stmt{}, nil\n\t}\n\n\tname := p.lexer.Identifier\n\tp.lexer.Next()\n\n\tif couldBeLet {\n\t\tisLet := opts.isExport\n\t\tswitch p.lexer.Token {\n\t\tcase js_lexer.TIdentifier, js_lexer.TOpenBracket, js_lexer.TOpenBrace:\n\t\t\tif opts.lexicalDecl == lexicalDeclAllowAll || !p.lexer.HasNewlineBefore || p.lexer.Token == js_lexer.TOpenBracket {\n\t\t\t\tisLet = true\n\t\t\t}\n\t\t}\n\t\tif isLet {\n\t\t\t// Handle a \"let\" declaration\n\t\t\tif opts.lexicalDecl != lexicalDeclAllowAll {\n\t\t\t\tp.forbidLexicalDecl(tokenRange.Loc)\n\t\t\t}\n\t\t\tp.markSyntaxFeature(compat.ConstAndLet, tokenRange)\n\t\t\tdecls := p.parseAndDeclareDecls(ast.SymbolOther, opts)\n\t\t\treturn js_ast.Expr{}, js_ast.Stmt{Loc: tokenRange.Loc, Data: &js_ast.SLocal{\n\t\t\t\tKind:     js_ast.LocalLet,\n\t\t\t\tDecls:    decls,\n\t\t\t\tIsExport: opts.isExport,\n\t\t\t}}, decls\n\t\t}\n\t} else if couldBeUsing && p.lexer.Token == js_lexer.TIdentifier && !p.lexer.HasNewlineBefore && (!opts.isForLoopInit || p.lexer.Raw() != \"of\") {\n\t\t// Handle a \"using\" declaration\n\t\tif opts.isCaseBody {\n\t\t\tp.forbidUsingInSwitch(tokenRange.Loc)\n\t\t} else if opts.lexicalDecl != lexicalDeclAllowAll {\n\t\t\tp.forbidLexicalDecl(tokenRange.Loc)\n\t\t}\n\t\topts.isUsingStmt = true\n\t\tdecls := p.parseAndDeclareDecls(ast.SymbolConst, opts)\n\t\tif !opts.isForLoopInit {\n\t\t\tp.requireInitializers(js_ast.LocalUsing, decls)\n\t\t}\n\t\treturn js_ast.Expr{}, js_ast.Stmt{Loc: tokenRange.Loc, Data: &js_ast.SLocal{\n\t\t\tKind:     js_ast.LocalUsing,\n\t\t\tDecls:    decls,\n\t\t\tIsExport: opts.isExport,\n\t\t}}, decls\n\t} else if couldBeAwaitUsing {\n\t\t// Handle an \"await using\" declaration\n\t\tif p.fnOrArrowDataParse.isTopLevel {\n\t\t\tp.topLevelAwaitKeyword = tokenRange\n\t\t}\n\t\tvar value js_ast.Expr\n\t\tif p.lexer.Token == js_lexer.TIdentifier && p.lexer.Raw() == \"using\" {\n\t\t\tusingLoc := p.saveExprCommentsHere()\n\t\t\tusingRange := p.lexer.Range()\n\t\t\tp.lexer.Next()\n\t\t\tif p.lexer.Token == js_lexer.TIdentifier && !p.lexer.HasNewlineBefore {\n\t\t\t\t// It's an \"await using\" declaration if we get here\n\t\t\t\tif opts.isCaseBody {\n\t\t\t\t\tp.forbidUsingInSwitch(usingRange.Loc)\n\t\t\t\t} else if opts.lexicalDecl != lexicalDeclAllowAll {\n\t\t\t\t\tp.forbidLexicalDecl(usingRange.Loc)\n\t\t\t\t}\n\t\t\t\topts.isUsingStmt = true\n\t\t\t\tdecls := p.parseAndDeclareDecls(ast.SymbolConst, opts)\n\t\t\t\tif !opts.isForLoopInit {\n\t\t\t\t\tp.requireInitializers(js_ast.LocalAwaitUsing, decls)\n\t\t\t\t}\n\t\t\t\treturn js_ast.Expr{}, js_ast.Stmt{Loc: tokenRange.Loc, Data: &js_ast.SLocal{\n\t\t\t\t\tKind:     js_ast.LocalAwaitUsing,\n\t\t\t\t\tDecls:    decls,\n\t\t\t\t\tIsExport: opts.isExport,\n\t\t\t\t}}, decls\n\t\t\t}\n\t\t\tvalue = js_ast.Expr{Loc: usingLoc, Data: &js_ast.EIdentifier{Ref: p.storeNameInRef(js_lexer.MaybeSubstring{String: \"using\"})}}\n\t\t} else {\n\t\t\tvalue = p.parseExpr(js_ast.LPrefix)\n\t\t}\n\t\tif p.lexer.Token == js_lexer.TAsteriskAsterisk {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t\tvalue = p.parseSuffix(value, js_ast.LPrefix, nil, 0)\n\t\texpr := js_ast.Expr{Loc: tokenRange.Loc, Data: &js_ast.EAwait{Value: value}}\n\t\treturn p.parseSuffix(expr, js_ast.LLowest, nil, 0), js_ast.Stmt{}, nil\n\t}\n\n\t// Parse the remainder of this expression that starts with an identifier\n\texpr := js_ast.Expr{Loc: tokenRange.Loc, Data: &js_ast.EIdentifier{Ref: p.storeNameInRef(name)}}\n\treturn p.parseSuffix(expr, js_ast.LLowest, nil, 0), js_ast.Stmt{}, nil\n}\n\nfunc (p *parser) parseCallArgs() (args []js_ast.Expr, closeParenLoc logger.Loc, isMultiLine bool) {\n\t// Allow \"in\" inside call arguments\n\toldAllowIn := p.allowIn\n\tp.allowIn = true\n\n\tp.lexer.Expect(js_lexer.TOpenParen)\n\n\tfor p.lexer.Token != js_lexer.TCloseParen {\n\t\tif p.lexer.HasNewlineBefore {\n\t\t\tisMultiLine = true\n\t\t}\n\t\tloc := p.lexer.Loc()\n\t\tisSpread := p.lexer.Token == js_lexer.TDotDotDot\n\t\tif isSpread {\n\t\t\tp.markSyntaxFeature(compat.RestArgument, p.lexer.Range())\n\t\t\tp.lexer.Next()\n\t\t}\n\t\targ := p.parseExpr(js_ast.LComma)\n\t\tif isSpread {\n\t\t\targ = js_ast.Expr{Loc: loc, Data: &js_ast.ESpread{Value: arg}}\n\t\t}\n\t\targs = append(args, arg)\n\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\tbreak\n\t\t}\n\t\tif p.lexer.HasNewlineBefore {\n\t\t\tisMultiLine = true\n\t\t}\n\t\tp.lexer.Next()\n\t}\n\n\tif p.lexer.HasNewlineBefore {\n\t\tisMultiLine = true\n\t}\n\tcloseParenLoc = p.saveExprCommentsHere()\n\tp.lexer.Expect(js_lexer.TCloseParen)\n\tp.allowIn = oldAllowIn\n\treturn\n}\n\nfunc (p *parser) parseJSXNamespacedName() (logger.Range, js_lexer.MaybeSubstring) {\n\tnameRange := p.lexer.Range()\n\tname := p.lexer.Identifier\n\tp.lexer.ExpectInsideJSXElement(js_lexer.TIdentifier)\n\n\t// Parse JSX namespaces. These are not supported by React or TypeScript\n\t// but someone using JSX syntax in more obscure ways may find a use for\n\t// them. A namespaced name is just always turned into a string so you\n\t// can't use this feature to reference JavaScript identifiers.\n\tif p.lexer.Token == js_lexer.TColon {\n\t\t// Parse the colon\n\t\tnameRange.Len = p.lexer.Range().End() - nameRange.Loc.Start\n\t\tns := name.String + \":\"\n\t\tp.lexer.NextInsideJSXElement()\n\n\t\t// Parse the second identifier\n\t\tif p.lexer.Token == js_lexer.TIdentifier {\n\t\t\tnameRange.Len = p.lexer.Range().End() - nameRange.Loc.Start\n\t\t\tns += p.lexer.Identifier.String\n\t\t\tp.lexer.NextInsideJSXElement()\n\t\t} else {\n\t\t\tp.log.AddError(&p.tracker, logger.Range{Loc: logger.Loc{Start: nameRange.End()}},\n\t\t\t\tfmt.Sprintf(\"Expected identifier after %q in namespaced JSX name\", ns))\n\t\t\tpanic(js_lexer.LexerPanic{})\n\t\t}\n\t\treturn nameRange, js_lexer.MaybeSubstring{String: ns}\n\t}\n\n\treturn nameRange, name\n}\n\nfunc tagOrFragmentHelpText(tag string) string {\n\tif tag == \"\" {\n\t\treturn \"fragment tag\"\n\t}\n\treturn fmt.Sprintf(\"%q tag\", tag)\n}\n\nfunc (p *parser) parseJSXTag() (logger.Range, string, js_ast.Expr) {\n\tloc := p.lexer.Loc()\n\n\t// A missing tag is a fragment\n\tif p.lexer.Token == js_lexer.TGreaterThan {\n\t\treturn logger.Range{Loc: loc, Len: 0}, \"\", js_ast.Expr{}\n\t}\n\n\t// The tag is an identifier\n\ttagRange, tagName := p.parseJSXNamespacedName()\n\n\t// Certain identifiers are strings\n\tif strings.ContainsAny(tagName.String, \"-:\") || (p.lexer.Token != js_lexer.TDot && tagName.String[0] >= 'a' && tagName.String[0] <= 'z') {\n\t\treturn tagRange, tagName.String, js_ast.Expr{Loc: loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(tagName.String)}}\n\t}\n\n\t// Otherwise, this is an identifier\n\ttag := js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: p.storeNameInRef(tagName)}}\n\n\t// Parse a member expression chain\n\tvar chain strings.Builder\n\tchain.WriteString(tagName.String)\n\tfor p.lexer.Token == js_lexer.TDot {\n\t\tp.lexer.NextInsideJSXElement()\n\t\tmemberRange := p.lexer.Range()\n\t\tmember := p.lexer.Identifier\n\t\tp.lexer.ExpectInsideJSXElement(js_lexer.TIdentifier)\n\n\t\t// Dashes are not allowed in member expression chains\n\t\tindex := strings.IndexByte(member.String, '-')\n\t\tif index >= 0 {\n\t\t\tp.log.AddError(&p.tracker, logger.Range{Loc: logger.Loc{Start: memberRange.Loc.Start + int32(index)}},\n\t\t\t\t\"Unexpected \\\"-\\\"\")\n\t\t\tpanic(js_lexer.LexerPanic{})\n\t\t}\n\n\t\tchain.WriteString(\".\" + member.String)\n\t\ttag = js_ast.Expr{Loc: loc, Data: p.dotOrMangledPropParse(tag, member, memberRange.Loc, js_ast.OptionalChainNone, wasOriginallyDot)}\n\t\ttagRange.Len = memberRange.Loc.Start + memberRange.Len - tagRange.Loc.Start\n\t}\n\n\treturn tagRange, chain.String(), tag\n}\n\nfunc (p *parser) parseJSXElement(loc logger.Loc) js_ast.Expr {\n\t// Keep track of the location of the first JSX element for error messages\n\tif p.firstJSXElementLoc.Start == -1 {\n\t\tp.firstJSXElementLoc = loc\n\t}\n\n\t// Parse the tag\n\tstartRange, startText, startTagOrNil := p.parseJSXTag()\n\n\t// The tag may have TypeScript type arguments: \"<Foo<T>/>\"\n\tif p.options.ts.Parse {\n\t\t// Pass a flag to the type argument skipper because we need to call\n\t\t// js_lexer.NextInsideJSXElement() after we hit the closing \">\". The next\n\t\t// token after the \">\" might be an attribute name with a dash in it\n\t\t// like this: \"<Foo<T> data-disabled/>\"\n\t\tp.skipTypeScriptTypeArguments(skipTypeScriptTypeArgumentsOpts{isInsideJSXElement: true})\n\t}\n\n\t// Parse attributes\n\tvar previousStringWithBackslashLoc logger.Loc\n\tproperties := []js_ast.Property{}\n\tisSingleLine := true\n\tif startTagOrNil.Data != nil {\n\tparseAttributes:\n\t\tfor {\n\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\tisSingleLine = false\n\t\t\t}\n\n\t\t\tswitch p.lexer.Token {\n\t\t\tcase js_lexer.TIdentifier:\n\t\t\t\t// Parse the key\n\t\t\t\tkeyRange, keyName := p.parseJSXNamespacedName()\n\t\t\t\tvar key js_ast.Expr\n\t\t\t\tif p.isMangledProp(keyName.String) && !strings.ContainsRune(keyName.String, ':') {\n\t\t\t\t\tkey = js_ast.Expr{Loc: keyRange.Loc, Data: &js_ast.ENameOfSymbol{Ref: p.storeNameInRef(keyName)}}\n\t\t\t\t} else {\n\t\t\t\t\tkey = js_ast.Expr{Loc: keyRange.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(keyName.String)}}\n\t\t\t\t}\n\n\t\t\t\t// Parse the value\n\t\t\t\tvar value js_ast.Expr\n\t\t\t\tvar flags js_ast.PropertyFlags\n\t\t\t\tif p.lexer.Token != js_lexer.TEquals {\n\t\t\t\t\t// Implicitly true value\n\t\t\t\t\tflags |= js_ast.PropertyWasShorthand\n\t\t\t\t\tvalue = js_ast.Expr{Loc: logger.Loc{Start: keyRange.Loc.Start + keyRange.Len}, Data: &js_ast.EBoolean{Value: true}}\n\t\t\t\t} else {\n\t\t\t\t\t// Use NextInsideJSXElement() not Next() so we can parse a JSX-style string literal\n\t\t\t\t\tp.lexer.NextInsideJSXElement()\n\t\t\t\t\tif p.lexer.Token == js_lexer.TStringLiteral {\n\t\t\t\t\t\tstringLoc := p.lexer.Loc()\n\t\t\t\t\t\tif p.lexer.PreviousBackslashQuoteInJSX.Loc.Start > stringLoc.Start {\n\t\t\t\t\t\t\tpreviousStringWithBackslashLoc = stringLoc\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif p.options.jsx.Preserve {\n\t\t\t\t\t\t\tvalue = js_ast.Expr{Loc: stringLoc, Data: &js_ast.EJSXText{Raw: p.lexer.Raw()}}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tvalue = js_ast.Expr{Loc: stringLoc, Data: &js_ast.EString{Value: p.lexer.StringLiteral()}}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.lexer.NextInsideJSXElement()\n\t\t\t\t\t} else if p.lexer.Token == js_lexer.TLessThan {\n\t\t\t\t\t\t// This may be removed in the future: https://github.com/facebook/jsx/issues/53\n\t\t\t\t\t\tloc := p.lexer.Loc()\n\t\t\t\t\t\tp.lexer.NextInsideJSXElement()\n\t\t\t\t\t\tflags |= js_ast.PropertyWasShorthand\n\t\t\t\t\t\tvalue = p.parseJSXElement(loc)\n\n\t\t\t\t\t\t// The call to parseJSXElement() above doesn't consume the last\n\t\t\t\t\t\t// TGreaterThan because the caller knows what Next() function to call.\n\t\t\t\t\t\t// Use NextJSXElementChild() here since the next token is inside a JSX\n\t\t\t\t\t\t// element.\n\t\t\t\t\t\tp.lexer.NextInsideJSXElement()\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Use Expect() not ExpectInsideJSXElement() so we can parse expression tokens\n\t\t\t\t\t\tp.lexer.Expect(js_lexer.TOpenBrace)\n\t\t\t\t\t\tvalue = p.parseExpr(js_ast.LLowest)\n\t\t\t\t\t\tp.lexer.ExpectInsideJSXElement(js_lexer.TCloseBrace)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Add a property\n\t\t\t\tproperties = append(properties, js_ast.Property{\n\t\t\t\t\tLoc:        keyRange.Loc,\n\t\t\t\t\tKey:        key,\n\t\t\t\t\tValueOrNil: value,\n\t\t\t\t\tFlags:      flags,\n\t\t\t\t})\n\n\t\t\tcase js_lexer.TOpenBrace:\n\t\t\t\t// Use Next() not ExpectInsideJSXElement() so we can parse \"...\"\n\t\t\t\tp.lexer.Next()\n\t\t\t\tdotLoc := p.saveExprCommentsHere()\n\t\t\t\tp.lexer.Expect(js_lexer.TDotDotDot)\n\t\t\t\tvalue := p.parseExpr(js_ast.LComma)\n\t\t\t\tproperties = append(properties, js_ast.Property{\n\t\t\t\t\tKind:       js_ast.PropertySpread,\n\t\t\t\t\tLoc:        dotLoc,\n\t\t\t\t\tValueOrNil: value,\n\t\t\t\t})\n\n\t\t\t\t// Use NextInsideJSXElement() not Next() so we can parse \">>\" as \">\"\n\t\t\t\tp.lexer.NextInsideJSXElement()\n\n\t\t\tdefault:\n\t\t\t\tbreak parseAttributes\n\t\t\t}\n\t\t}\n\n\t\t// Check for and warn about duplicate attributes\n\t\tif len(properties) > 1 && !p.suppressWarningsAboutWeirdCode {\n\t\t\tkeys := make(map[string]logger.Loc)\n\t\t\tfor _, property := range properties {\n\t\t\t\tif property.Kind != js_ast.PropertySpread {\n\t\t\t\t\tif str, ok := property.Key.Data.(*js_ast.EString); ok {\n\t\t\t\t\t\tkey := helpers.UTF16ToString(str.Value)\n\t\t\t\t\t\tif prevLoc, ok := keys[key]; ok {\n\t\t\t\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, property.Key.Loc)\n\t\t\t\t\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_DuplicateObjectKey, logger.Warning, &p.tracker, r,\n\t\t\t\t\t\t\t\tfmt.Sprintf(\"Duplicate %q attribute in JSX element\", key),\n\t\t\t\t\t\t\t\t[]logger.MsgData{p.tracker.MsgData(js_lexer.RangeOfIdentifier(p.source, prevLoc),\n\t\t\t\t\t\t\t\t\tfmt.Sprintf(\"The original %q attribute is here:\", key))})\n\t\t\t\t\t\t}\n\t\t\t\t\t\tkeys[key] = property.Key.Loc\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// People sometimes try to use the output of \"JSON.stringify()\" as a JSX\n\t// attribute when automatically-generating JSX code. Doing so is incorrect\n\t// because JSX strings work like XML instead of like JS (since JSX is XML-in-\n\t// JS). Specifically, using a backslash before a quote does not cause it to\n\t// be escaped:\n\t//\n\t//   JSX ends the \"content\" attribute here and sets \"content\" to 'some so-called \\\\'\n\t//                                          v\n\t//         <Button content=\"some so-called \\\"button text\\\"\" />\n\t//                                                      ^\n\t//       There is no \"=\" after the JSX attribute \"text\", so we expect a \">\"\n\t//\n\t// This code special-cases this error to provide a less obscure error message.\n\tif p.lexer.Token == js_lexer.TSyntaxError && p.lexer.Raw() == \"\\\\\" && previousStringWithBackslashLoc.Start > 0 {\n\t\tmsg := logger.Msg{Kind: logger.Error, Data: p.tracker.MsgData(p.lexer.Range(),\n\t\t\t\"Unexpected backslash in JSX element\")}\n\n\t\t// Option 1: Suggest using an XML escape\n\t\tjsEscape := p.source.TextForRange(p.lexer.PreviousBackslashQuoteInJSX)\n\t\txmlEscape := \"\"\n\t\tif jsEscape == \"\\\\\\\"\" {\n\t\t\txmlEscape = \"&quot;\"\n\t\t} else if jsEscape == \"\\\\'\" {\n\t\t\txmlEscape = \"&apos;\"\n\t\t}\n\t\tif xmlEscape != \"\" {\n\t\t\tdata := p.tracker.MsgData(p.lexer.PreviousBackslashQuoteInJSX,\n\t\t\t\t\"Quoted JSX attributes use XML-style escapes instead of JavaScript-style escapes:\")\n\t\t\tdata.Location.Suggestion = xmlEscape\n\t\t\tmsg.Notes = append(msg.Notes, data)\n\t\t}\n\n\t\t// Option 2: Suggest using a JavaScript string\n\t\tif stringRange := p.source.RangeOfString(previousStringWithBackslashLoc); stringRange.Len > 0 {\n\t\t\tdata := p.tracker.MsgData(stringRange,\n\t\t\t\t\"Consider using a JavaScript string inside {...} instead of a quoted JSX attribute:\")\n\t\t\tdata.Location.Suggestion = fmt.Sprintf(\"{%s}\", p.source.TextForRange(stringRange))\n\t\t\tmsg.Notes = append(msg.Notes, data)\n\t\t}\n\n\t\tp.log.AddMsg(msg)\n\t\tpanic(js_lexer.LexerPanic{})\n\t}\n\n\t// A slash here is a self-closing element\n\tif p.lexer.Token == js_lexer.TSlash {\n\t\t// Use NextInsideJSXElement() not Next() so we can parse \">>\" as \">\"\n\t\tcloseLoc := p.lexer.Loc()\n\t\tp.lexer.NextInsideJSXElement()\n\t\tif p.lexer.Token != js_lexer.TGreaterThan {\n\t\t\tp.lexer.Expected(js_lexer.TGreaterThan)\n\t\t}\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EJSXElement{\n\t\t\tTagOrNil:        startTagOrNil,\n\t\t\tProperties:      properties,\n\t\t\tCloseLoc:        closeLoc,\n\t\t\tIsTagSingleLine: isSingleLine,\n\t\t}}\n\t}\n\n\t// Attempt to provide a better error message for people incorrectly trying to\n\t// use arrow functions in TSX (which doesn't work because they are JSX elements)\n\tif p.options.ts.Parse && len(properties) == 0 && startText != \"\" && p.lexer.Token == js_lexer.TGreaterThan &&\n\t\tstrings.HasPrefix(p.source.Contents[p.lexer.Loc().Start:], \">(\") {\n\t\tbadArrowInTSXRange := p.lexer.BadArrowInTSXRange\n\t\tbadArrowInTSXSuggestion := p.lexer.BadArrowInTSXSuggestion\n\n\t\tp.lexer.CouldBeBadArrowInTSX++\n\t\tp.lexer.BadArrowInTSXRange = logger.Range{Loc: loc, Len: p.lexer.Range().End() - loc.Start}\n\t\tp.lexer.BadArrowInTSXSuggestion = fmt.Sprintf(\"<%s,>\", startText)\n\n\t\tdefer func() {\n\t\t\tp.lexer.CouldBeBadArrowInTSX--\n\t\t\tp.lexer.BadArrowInTSXRange = badArrowInTSXRange\n\t\t\tp.lexer.BadArrowInTSXSuggestion = badArrowInTSXSuggestion\n\t\t}()\n\t}\n\n\t// Use ExpectJSXElementChild() so we parse child strings\n\tp.lexer.ExpectJSXElementChild(js_lexer.TGreaterThan)\n\n\t// Parse the children of this element\n\tnullableChildren := []js_ast.Expr{}\n\tfor {\n\t\tswitch p.lexer.Token {\n\t\tcase js_lexer.TStringLiteral:\n\t\t\tif p.options.jsx.Preserve {\n\t\t\t\tnullableChildren = append(nullableChildren, js_ast.Expr{Loc: p.lexer.Loc(), Data: &js_ast.EJSXText{Raw: p.lexer.Raw()}})\n\t\t\t} else if str := p.lexer.StringLiteral(); len(str) > 0 {\n\t\t\t\tnullableChildren = append(nullableChildren, js_ast.Expr{Loc: p.lexer.Loc(), Data: &js_ast.EString{Value: str}})\n\t\t\t} else {\n\t\t\t\t// Skip this token if it turned out to be empty after trimming\n\t\t\t}\n\t\t\tp.lexer.NextJSXElementChild()\n\n\t\tcase js_lexer.TOpenBrace:\n\t\t\t// Use Next() instead of NextJSXElementChild() here since the next token is an expression\n\t\t\tp.lexer.Next()\n\n\t\t\t// The expression is optional, and may be absent\n\t\t\tif p.lexer.Token == js_lexer.TCloseBrace {\n\t\t\t\t// Save comments even for absent expressions\n\t\t\t\tnullableChildren = append(nullableChildren, js_ast.Expr{Loc: p.saveExprCommentsHere(), Data: nil})\n\t\t\t} else {\n\t\t\t\tif p.lexer.Token == js_lexer.TDotDotDot {\n\t\t\t\t\t// TypeScript preserves \"...\" before JSX child expressions here.\n\t\t\t\t\t// Babel gives the error \"Spread children are not supported in React\"\n\t\t\t\t\t// instead, so it should be safe to support this TypeScript-specific\n\t\t\t\t\t// behavior. Note that TypeScript's behavior changed in TypeScript 4.5.\n\t\t\t\t\t// Before that, the \"...\" was omitted instead of being preserved.\n\t\t\t\t\titemLoc := p.lexer.Loc()\n\t\t\t\t\tp.markSyntaxFeature(compat.RestArgument, p.lexer.Range())\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tnullableChildren = append(nullableChildren, js_ast.Expr{Loc: itemLoc, Data: &js_ast.ESpread{Value: p.parseExpr(js_ast.LLowest)}})\n\t\t\t\t} else {\n\t\t\t\t\tnullableChildren = append(nullableChildren, p.parseExpr(js_ast.LLowest))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Use ExpectJSXElementChild() so we parse child strings\n\t\t\tp.lexer.ExpectJSXElementChild(js_lexer.TCloseBrace)\n\n\t\tcase js_lexer.TLessThan:\n\t\t\tlessThanLoc := p.lexer.Loc()\n\t\t\tp.lexer.NextInsideJSXElement()\n\n\t\t\tif p.lexer.Token != js_lexer.TSlash {\n\t\t\t\t// This is a child element\n\t\t\t\tnullableChildren = append(nullableChildren, p.parseJSXElement(lessThanLoc))\n\n\t\t\t\t// The call to parseJSXElement() above doesn't consume the last\n\t\t\t\t// TGreaterThan because the caller knows what Next() function to call.\n\t\t\t\t// Use NextJSXElementChild() here since the next token is an element\n\t\t\t\t// child.\n\t\t\t\tp.lexer.NextJSXElementChild()\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// This is the closing element\n\t\t\tp.lexer.NextInsideJSXElement()\n\t\t\tendRange, endText, _ := p.parseJSXTag()\n\t\t\tif startText != endText {\n\t\t\t\tstartTag := tagOrFragmentHelpText(startText)\n\t\t\t\tendTag := tagOrFragmentHelpText(endText)\n\t\t\t\tmsg := logger.Msg{\n\t\t\t\t\tKind:  logger.Error,\n\t\t\t\t\tData:  p.tracker.MsgData(endRange, fmt.Sprintf(\"Unexpected closing %s does not match opening %s\", endTag, startTag)),\n\t\t\t\t\tNotes: []logger.MsgData{p.tracker.MsgData(startRange, fmt.Sprintf(\"The opening %s is here:\", startTag))},\n\t\t\t\t}\n\t\t\t\tmsg.Data.Location.Suggestion = startText\n\t\t\t\tp.log.AddMsg(msg)\n\t\t\t}\n\t\t\tif p.lexer.Token != js_lexer.TGreaterThan {\n\t\t\t\tp.lexer.Expected(js_lexer.TGreaterThan)\n\t\t\t}\n\n\t\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EJSXElement{\n\t\t\t\tTagOrNil:         startTagOrNil,\n\t\t\t\tProperties:       properties,\n\t\t\t\tNullableChildren: nullableChildren,\n\t\t\t\tCloseLoc:         lessThanLoc,\n\t\t\t\tIsTagSingleLine:  isSingleLine,\n\t\t\t}}\n\n\t\tcase js_lexer.TEndOfFile:\n\t\t\tstartTag := tagOrFragmentHelpText(startText)\n\t\t\tmsg := logger.Msg{\n\t\t\t\tKind:  logger.Error,\n\t\t\t\tData:  p.tracker.MsgData(p.lexer.Range(), fmt.Sprintf(\"Unexpected end of file before a closing %s\", startTag)),\n\t\t\t\tNotes: []logger.MsgData{p.tracker.MsgData(startRange, fmt.Sprintf(\"The opening %s is here:\", startTag))},\n\t\t\t}\n\t\t\tmsg.Data.Location.Suggestion = fmt.Sprintf(\"</%s>\", startText)\n\t\t\tp.log.AddMsg(msg)\n\t\t\tpanic(js_lexer.LexerPanic{})\n\n\t\tdefault:\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t}\n}\n\nfunc (p *parser) parseTemplateParts(includeRaw bool) (parts []js_ast.TemplatePart, legacyOctalLoc logger.Loc) {\n\t// Allow \"in\" inside template literals\n\toldAllowIn := p.allowIn\n\tp.allowIn = true\n\n\tfor {\n\t\tp.lexer.Next()\n\t\tvalue := p.parseExpr(js_ast.LLowest)\n\t\ttailLoc := p.lexer.Loc()\n\t\tp.lexer.RescanCloseBraceAsTemplateToken()\n\t\tif includeRaw {\n\t\t\ttailCooked, tailRaw := p.lexer.CookedAndRawTemplateContents()\n\t\t\tparts = append(parts, js_ast.TemplatePart{\n\t\t\t\tValue:      value,\n\t\t\t\tTailLoc:    tailLoc,\n\t\t\t\tTailCooked: tailCooked,\n\t\t\t\tTailRaw:    tailRaw,\n\t\t\t})\n\t\t} else {\n\t\t\tparts = append(parts, js_ast.TemplatePart{\n\t\t\t\tValue:      value,\n\t\t\t\tTailLoc:    tailLoc,\n\t\t\t\tTailCooked: p.lexer.StringLiteral(),\n\t\t\t})\n\t\t\tif p.lexer.LegacyOctalLoc.Start > tailLoc.Start {\n\t\t\t\tlegacyOctalLoc = p.lexer.LegacyOctalLoc\n\t\t\t}\n\t\t}\n\t\tif p.lexer.Token == js_lexer.TTemplateTail {\n\t\t\tp.lexer.Next()\n\t\t\tbreak\n\t\t}\n\t}\n\n\tp.allowIn = oldAllowIn\n\n\treturn parts, legacyOctalLoc\n}\n\nfunc (p *parser) parseAndDeclareDecls(kind ast.SymbolKind, opts parseStmtOpts) []js_ast.Decl {\n\tdecls := []js_ast.Decl{}\n\n\tfor {\n\t\t// Forbid \"let let\" and \"const let\" but not \"var let\"\n\t\tif (kind == ast.SymbolOther || kind == ast.SymbolConst) && p.lexer.IsContextualKeyword(\"let\") {\n\t\t\tp.log.AddError(&p.tracker, p.lexer.Range(), \"Cannot use \\\"let\\\" as an identifier here:\")\n\t\t}\n\n\t\tvar valueOrNil js_ast.Expr\n\t\tlocal := p.parseBinding(parseBindingOpts{isUsingStmt: opts.isUsingStmt})\n\t\tp.declareBinding(kind, local, opts)\n\n\t\t// Skip over types\n\t\tif p.options.ts.Parse {\n\t\t\t// \"let foo!\"\n\t\t\tisDefiniteAssignmentAssertion := p.lexer.Token == js_lexer.TExclamation && !p.lexer.HasNewlineBefore\n\t\t\tif isDefiniteAssignmentAssertion {\n\t\t\t\tp.lexer.Next()\n\t\t\t}\n\n\t\t\t// \"let foo: number\"\n\t\t\tif isDefiniteAssignmentAssertion || p.lexer.Token == js_lexer.TColon {\n\t\t\t\tp.lexer.Expect(js_lexer.TColon)\n\t\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\t}\n\t\t}\n\n\t\tif p.lexer.Token == js_lexer.TEquals {\n\t\t\tp.lexer.Next()\n\t\t\tvalueOrNil = p.parseExpr(js_ast.LComma)\n\n\t\t\t// Rollup (the tool that invented the \"@__NO_SIDE_EFFECTS__\" comment) only\n\t\t\t// applies this to the first declaration, and only when it's a \"const\".\n\t\t\t// For more info see: https://github.com/rollup/rollup/pull/5024/files\n\t\t\tif !p.options.ignoreDCEAnnotations && kind == ast.SymbolConst {\n\t\t\t\tswitch e := valueOrNil.Data.(type) {\n\t\t\t\tcase *js_ast.EArrow:\n\t\t\t\t\tif opts.hasNoSideEffectsComment {\n\t\t\t\t\t\te.HasNoSideEffectsComment = true\n\t\t\t\t\t}\n\t\t\t\t\tif e.HasNoSideEffectsComment && !opts.isTypeScriptDeclare {\n\t\t\t\t\t\tif b, ok := local.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\t\t\t\tp.symbols[b.Ref.InnerIndex].Flags |= ast.CallCanBeUnwrappedIfUnused\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase *js_ast.EFunction:\n\t\t\t\t\tif opts.hasNoSideEffectsComment {\n\t\t\t\t\t\te.Fn.HasNoSideEffectsComment = true\n\t\t\t\t\t}\n\t\t\t\t\tif e.Fn.HasNoSideEffectsComment && !opts.isTypeScriptDeclare {\n\t\t\t\t\t\tif b, ok := local.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\t\t\t\tp.symbols[b.Ref.InnerIndex].Flags |= ast.CallCanBeUnwrappedIfUnused\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Only apply this to the first declaration\n\t\t\t\topts.hasNoSideEffectsComment = false\n\t\t\t}\n\t\t}\n\n\t\tdecls = append(decls, js_ast.Decl{Binding: local, ValueOrNil: valueOrNil})\n\n\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\tbreak\n\t\t}\n\t\tp.lexer.Next()\n\t}\n\n\treturn decls\n}\n\nfunc (p *parser) requireInitializers(kind js_ast.LocalKind, decls []js_ast.Decl) {\n\tfor _, d := range decls {\n\t\tif d.ValueOrNil.Data == nil {\n\t\t\twhat := \"constant\"\n\t\t\tif kind == js_ast.LocalUsing {\n\t\t\t\twhat = \"declaration\"\n\t\t\t}\n\t\t\tif id, ok := d.Binding.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, d.Binding.Loc)\n\t\t\t\tp.log.AddError(&p.tracker, r,\n\t\t\t\t\tfmt.Sprintf(\"The %s %q must be initialized\", what, p.symbols[id.Ref.InnerIndex].OriginalName))\n\t\t\t} else {\n\t\t\t\tp.log.AddError(&p.tracker, logger.Range{Loc: d.Binding.Loc},\n\t\t\t\t\tfmt.Sprintf(\"This %s must be initialized\", what))\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (p *parser) forbidInitializers(decls []js_ast.Decl, loopType string, isVar bool) {\n\tif len(decls) > 1 {\n\t\tp.log.AddError(&p.tracker, logger.Range{Loc: decls[0].Binding.Loc},\n\t\t\tfmt.Sprintf(\"for-%s loops must have a single declaration\", loopType))\n\t} else if len(decls) == 1 && decls[0].ValueOrNil.Data != nil {\n\t\tif isVar {\n\t\t\tif _, ok := decls[0].Binding.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\t// This is a weird special case. Initializers are allowed in \"var\"\n\t\t\t\t// statements with identifier bindings.\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tp.log.AddError(&p.tracker, logger.Range{Loc: decls[0].ValueOrNil.Loc},\n\t\t\tfmt.Sprintf(\"for-%s loop variables cannot have an initializer\", loopType))\n\t}\n}\n\nfunc (p *parser) parseClauseAlias(kind string) js_lexer.MaybeSubstring {\n\tloc := p.lexer.Loc()\n\n\t// The alias may now be a string (see https://github.com/tc39/ecma262/pull/2154)\n\tif p.lexer.Token == js_lexer.TStringLiteral {\n\t\tr := p.source.RangeOfString(loc)\n\t\talias, problem, ok := helpers.UTF16ToStringWithValidation(p.lexer.StringLiteral())\n\t\tif !ok {\n\t\t\tp.log.AddError(&p.tracker, r,\n\t\t\t\tfmt.Sprintf(\"This %s alias is invalid because it contains the unpaired Unicode surrogate U+%X\", kind, problem))\n\t\t}\n\t\treturn js_lexer.MaybeSubstring{String: alias}\n\t}\n\n\t// The alias may be a keyword\n\tif !p.lexer.IsIdentifierOrKeyword() {\n\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t}\n\n\talias := p.lexer.Identifier\n\tp.checkForUnrepresentableIdentifier(loc, alias.String)\n\treturn alias\n}\n\nfunc (p *parser) parseImportClause() ([]js_ast.ClauseItem, bool) {\n\titems := []js_ast.ClauseItem{}\n\tp.lexer.Expect(js_lexer.TOpenBrace)\n\tisSingleLine := !p.lexer.HasNewlineBefore\n\n\tfor p.lexer.Token != js_lexer.TCloseBrace {\n\t\tisIdentifier := p.lexer.Token == js_lexer.TIdentifier\n\t\taliasLoc := p.lexer.Loc()\n\t\talias := p.parseClauseAlias(\"import\")\n\t\tname := ast.LocRef{Loc: aliasLoc, Ref: p.storeNameInRef(alias)}\n\t\toriginalName := alias\n\t\tp.lexer.Next()\n\n\t\t// \"import { type xx } from 'mod'\"\n\t\t// \"import { type xx as yy } from 'mod'\"\n\t\t// \"import { type 'xx' as yy } from 'mod'\"\n\t\t// \"import { type as } from 'mod'\"\n\t\t// \"import { type as as } from 'mod'\"\n\t\t// \"import { type as as as } from 'mod'\"\n\t\tif p.options.ts.Parse && alias.String == \"type\" && p.lexer.Token != js_lexer.TComma && p.lexer.Token != js_lexer.TCloseBrace {\n\t\t\tif p.lexer.IsContextualKeyword(\"as\") {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tif p.lexer.IsContextualKeyword(\"as\") {\n\t\t\t\t\toriginalName = p.lexer.Identifier\n\t\t\t\t\tname = ast.LocRef{Loc: p.lexer.Loc(), Ref: p.storeNameInRef(originalName)}\n\t\t\t\t\tp.lexer.Next()\n\n\t\t\t\t\tif p.lexer.Token == js_lexer.TIdentifier {\n\t\t\t\t\t\t// \"import { type as as as } from 'mod'\"\n\t\t\t\t\t\t// \"import { type as as foo } from 'mod'\"\n\t\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// \"import { type as as } from 'mod'\"\n\t\t\t\t\t\titems = append(items, js_ast.ClauseItem{\n\t\t\t\t\t\t\tAlias:        alias.String,\n\t\t\t\t\t\t\tAliasLoc:     aliasLoc,\n\t\t\t\t\t\t\tName:         name,\n\t\t\t\t\t\t\tOriginalName: originalName.String,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t} else if p.lexer.Token == js_lexer.TIdentifier {\n\t\t\t\t\t// \"import { type as xxx } from 'mod'\"\n\t\t\t\t\toriginalName = p.lexer.Identifier\n\t\t\t\t\tname = ast.LocRef{Loc: p.lexer.Loc(), Ref: p.storeNameInRef(originalName)}\n\t\t\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\n\t\t\t\t\t// Reject forbidden names\n\t\t\t\t\tif isEvalOrArguments(originalName.String) {\n\t\t\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, name.Loc)\n\t\t\t\t\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\"Cannot use %q as an identifier here:\", originalName.String))\n\t\t\t\t\t}\n\n\t\t\t\t\titems = append(items, js_ast.ClauseItem{\n\t\t\t\t\t\tAlias:        alias.String,\n\t\t\t\t\t\tAliasLoc:     aliasLoc,\n\t\t\t\t\t\tName:         name,\n\t\t\t\t\t\tOriginalName: originalName.String,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tisIdentifier := p.lexer.Token == js_lexer.TIdentifier\n\n\t\t\t\t// \"import { type xx } from 'mod'\"\n\t\t\t\t// \"import { type xx as yy } from 'mod'\"\n\t\t\t\t// \"import { type if as yy } from 'mod'\"\n\t\t\t\t// \"import { type 'xx' as yy } from 'mod'\"\n\t\t\t\tp.parseClauseAlias(\"import\")\n\t\t\t\tp.lexer.Next()\n\n\t\t\t\tif p.lexer.IsContextualKeyword(\"as\") {\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t\t\t} else if !isIdentifier {\n\t\t\t\t\t// An import where the name is a keyword must have an alias\n\t\t\t\t\tp.lexer.ExpectedString(\"\\\"as\\\"\")\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif p.lexer.IsContextualKeyword(\"as\") {\n\t\t\t\tp.lexer.Next()\n\t\t\t\toriginalName = p.lexer.Identifier\n\t\t\t\tname = ast.LocRef{Loc: p.lexer.Loc(), Ref: p.storeNameInRef(originalName)}\n\t\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t\t} else if !isIdentifier {\n\t\t\t\t// An import where the name is a keyword must have an alias\n\t\t\t\tp.lexer.ExpectedString(\"\\\"as\\\"\")\n\t\t\t}\n\n\t\t\t// Reject forbidden names\n\t\t\tif isEvalOrArguments(originalName.String) {\n\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, name.Loc)\n\t\t\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\"Cannot use %q as an identifier here:\", originalName.String))\n\t\t\t}\n\n\t\t\titems = append(items, js_ast.ClauseItem{\n\t\t\t\tAlias:        alias.String,\n\t\t\t\tAliasLoc:     aliasLoc,\n\t\t\t\tName:         name,\n\t\t\t\tOriginalName: originalName.String,\n\t\t\t})\n\t\t}\n\n\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\tbreak\n\t\t}\n\t\tif p.lexer.HasNewlineBefore {\n\t\t\tisSingleLine = false\n\t\t}\n\t\tp.lexer.Next()\n\t\tif p.lexer.HasNewlineBefore {\n\t\t\tisSingleLine = false\n\t\t}\n\t}\n\n\tif p.lexer.HasNewlineBefore {\n\t\tisSingleLine = false\n\t}\n\tp.lexer.Expect(js_lexer.TCloseBrace)\n\treturn items, isSingleLine\n}\n\nfunc (p *parser) parseExportClause() ([]js_ast.ClauseItem, bool) {\n\titems := []js_ast.ClauseItem{}\n\tfirstNonIdentifierLoc := logger.Loc{}\n\tp.lexer.Expect(js_lexer.TOpenBrace)\n\tisSingleLine := !p.lexer.HasNewlineBefore\n\n\tfor p.lexer.Token != js_lexer.TCloseBrace {\n\t\talias := p.parseClauseAlias(\"export\")\n\t\taliasLoc := p.lexer.Loc()\n\t\tname := ast.LocRef{Loc: aliasLoc, Ref: p.storeNameInRef(alias)}\n\t\toriginalName := alias\n\n\t\t// The name can actually be a keyword if we're really an \"export from\"\n\t\t// statement. However, we won't know until later. Allow keywords as\n\t\t// identifiers for now and throw an error later if there's no \"from\".\n\t\t//\n\t\t//   // This is fine\n\t\t//   export { default } from 'path'\n\t\t//\n\t\t//   // This is a syntax error\n\t\t//   export { default }\n\t\t//\n\t\tif p.lexer.Token != js_lexer.TIdentifier && firstNonIdentifierLoc.Start == 0 {\n\t\t\tfirstNonIdentifierLoc = p.lexer.Loc()\n\t\t}\n\t\tp.lexer.Next()\n\n\t\tif p.options.ts.Parse && alias.String == \"type\" && p.lexer.Token != js_lexer.TComma && p.lexer.Token != js_lexer.TCloseBrace {\n\t\t\tif p.lexer.IsContextualKeyword(\"as\") {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tif p.lexer.IsContextualKeyword(\"as\") {\n\t\t\t\t\talias = p.parseClauseAlias(\"export\")\n\t\t\t\t\taliasLoc = p.lexer.Loc()\n\t\t\t\t\tp.lexer.Next()\n\n\t\t\t\t\tif p.lexer.Token != js_lexer.TComma && p.lexer.Token != js_lexer.TCloseBrace {\n\t\t\t\t\t\t// \"export { type as as as }\"\n\t\t\t\t\t\t// \"export { type as as foo }\"\n\t\t\t\t\t\t// \"export { type as as 'foo' }\"\n\t\t\t\t\t\tp.parseClauseAlias(\"export\")\n\t\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// \"export { type as as }\"\n\t\t\t\t\t\titems = append(items, js_ast.ClauseItem{\n\t\t\t\t\t\t\tAlias:        alias.String,\n\t\t\t\t\t\t\tAliasLoc:     aliasLoc,\n\t\t\t\t\t\t\tName:         name,\n\t\t\t\t\t\t\tOriginalName: originalName.String,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t} else if p.lexer.Token != js_lexer.TComma && p.lexer.Token != js_lexer.TCloseBrace {\n\t\t\t\t\t// \"export { type as xxx }\"\n\t\t\t\t\t// \"export { type as 'xxx' }\"\n\t\t\t\t\talias = p.parseClauseAlias(\"export\")\n\t\t\t\t\taliasLoc = p.lexer.Loc()\n\t\t\t\t\tp.lexer.Next()\n\n\t\t\t\t\titems = append(items, js_ast.ClauseItem{\n\t\t\t\t\t\tAlias:        alias.String,\n\t\t\t\t\t\tAliasLoc:     aliasLoc,\n\t\t\t\t\t\tName:         name,\n\t\t\t\t\t\tOriginalName: originalName.String,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// The name can actually be a keyword if we're really an \"export from\"\n\t\t\t\t// statement. However, we won't know until later. Allow keywords as\n\t\t\t\t// identifiers for now and throw an error later if there's no \"from\".\n\t\t\t\t//\n\t\t\t\t//   // This is fine\n\t\t\t\t//   export { type default } from 'path'\n\t\t\t\t//\n\t\t\t\t//   // This is a syntax error\n\t\t\t\t//   export { type default }\n\t\t\t\t//\n\t\t\t\tif p.lexer.Token != js_lexer.TIdentifier && firstNonIdentifierLoc.Start == 0 {\n\t\t\t\t\tfirstNonIdentifierLoc = p.lexer.Loc()\n\t\t\t\t}\n\n\t\t\t\t// \"export { type xx }\"\n\t\t\t\t// \"export { type xx as yy }\"\n\t\t\t\t// \"export { type xx as if }\"\n\t\t\t\t// \"export { type default } from 'path'\"\n\t\t\t\t// \"export { type default as if } from 'path'\"\n\t\t\t\t// \"export { type xx as 'yy' }\"\n\t\t\t\t// \"export { type 'xx' } from 'mod'\"\n\t\t\t\tp.parseClauseAlias(\"export\")\n\t\t\t\tp.lexer.Next()\n\n\t\t\t\tif p.lexer.IsContextualKeyword(\"as\") {\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tp.parseClauseAlias(\"export\")\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif p.lexer.IsContextualKeyword(\"as\") {\n\t\t\t\tp.lexer.Next()\n\t\t\t\talias = p.parseClauseAlias(\"export\")\n\t\t\t\taliasLoc = p.lexer.Loc()\n\t\t\t\tp.lexer.Next()\n\t\t\t}\n\n\t\t\titems = append(items, js_ast.ClauseItem{\n\t\t\t\tAlias:        alias.String,\n\t\t\t\tAliasLoc:     aliasLoc,\n\t\t\t\tName:         name,\n\t\t\t\tOriginalName: originalName.String,\n\t\t\t})\n\t\t}\n\n\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\tbreak\n\t\t}\n\t\tif p.lexer.HasNewlineBefore {\n\t\t\tisSingleLine = false\n\t\t}\n\t\tp.lexer.Next()\n\t\tif p.lexer.HasNewlineBefore {\n\t\t\tisSingleLine = false\n\t\t}\n\t}\n\n\tif p.lexer.HasNewlineBefore {\n\t\tisSingleLine = false\n\t}\n\tp.lexer.Expect(js_lexer.TCloseBrace)\n\n\t// Throw an error here if we found a keyword earlier and this isn't an\n\t// \"export from\" statement after all\n\tif firstNonIdentifierLoc.Start != 0 && !p.lexer.IsContextualKeyword(\"from\") {\n\t\tr := js_lexer.RangeOfIdentifier(p.source, firstNonIdentifierLoc)\n\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\"Expected identifier but found %q\", p.source.TextForRange(r)))\n\t\tpanic(js_lexer.LexerPanic{})\n\t}\n\n\treturn items, isSingleLine\n}\n\ntype parseBindingOpts struct {\n\tisUsingStmt bool\n}\n\nfunc (p *parser) parseBinding(opts parseBindingOpts) js_ast.Binding {\n\tloc := p.lexer.Loc()\n\n\tswitch p.lexer.Token {\n\tcase js_lexer.TIdentifier:\n\t\tname := p.lexer.Identifier\n\n\t\t// Forbid invalid identifiers\n\t\tif (p.fnOrArrowDataParse.await != allowIdent && name.String == \"await\") ||\n\t\t\t(p.fnOrArrowDataParse.yield != allowIdent && name.String == \"yield\") {\n\t\t\tp.log.AddError(&p.tracker, p.lexer.Range(), fmt.Sprintf(\"Cannot use %q as an identifier here:\", name.String))\n\t\t}\n\n\t\tref := p.storeNameInRef(name)\n\t\tp.lexer.Next()\n\t\treturn js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: ref}}\n\n\tcase js_lexer.TOpenBracket:\n\t\tif opts.isUsingStmt {\n\t\t\tbreak\n\t\t}\n\t\tp.markSyntaxFeature(compat.Destructuring, p.lexer.Range())\n\t\tp.lexer.Next()\n\t\tisSingleLine := !p.lexer.HasNewlineBefore\n\t\titems := []js_ast.ArrayBinding{}\n\t\thasSpread := false\n\n\t\t// \"in\" expressions are allowed\n\t\toldAllowIn := p.allowIn\n\t\tp.allowIn = true\n\n\t\tfor p.lexer.Token != js_lexer.TCloseBracket {\n\t\t\titemLoc := p.saveExprCommentsHere()\n\n\t\t\tif p.lexer.Token == js_lexer.TComma {\n\t\t\t\tbinding := js_ast.Binding{Loc: itemLoc, Data: js_ast.BMissingShared}\n\t\t\t\titems = append(items, js_ast.ArrayBinding{\n\t\t\t\t\tBinding: binding,\n\t\t\t\t\tLoc:     itemLoc,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tif p.lexer.Token == js_lexer.TDotDotDot {\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\thasSpread = true\n\n\t\t\t\t\t// This was a bug in the ES2015 spec that was fixed in ES2016\n\t\t\t\t\tif p.lexer.Token != js_lexer.TIdentifier {\n\t\t\t\t\t\tp.markSyntaxFeature(compat.NestedRestBinding, p.lexer.Range())\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tp.saveExprCommentsHere()\n\t\t\t\tbinding := p.parseBinding(parseBindingOpts{})\n\n\t\t\t\tvar defaultValueOrNil js_ast.Expr\n\t\t\t\tif !hasSpread && p.lexer.Token == js_lexer.TEquals {\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tdefaultValueOrNil = p.parseExpr(js_ast.LComma)\n\t\t\t\t}\n\n\t\t\t\titems = append(items, js_ast.ArrayBinding{\n\t\t\t\t\tBinding:           binding,\n\t\t\t\t\tDefaultValueOrNil: defaultValueOrNil,\n\t\t\t\t\tLoc:               itemLoc,\n\t\t\t\t})\n\n\t\t\t\t// Commas after spread elements are not allowed\n\t\t\t\tif hasSpread && p.lexer.Token == js_lexer.TComma {\n\t\t\t\t\tp.log.AddError(&p.tracker, p.lexer.Range(), \"Unexpected \\\",\\\" after rest pattern\")\n\t\t\t\t\tpanic(js_lexer.LexerPanic{})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\tisSingleLine = false\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\tisSingleLine = false\n\t\t\t}\n\t\t}\n\n\t\tp.allowIn = oldAllowIn\n\n\t\tif p.lexer.HasNewlineBefore {\n\t\t\tisSingleLine = false\n\t\t}\n\t\tcloseBracketLoc := p.saveExprCommentsHere()\n\t\tp.lexer.Expect(js_lexer.TCloseBracket)\n\t\treturn js_ast.Binding{Loc: loc, Data: &js_ast.BArray{\n\t\t\tItems:           items,\n\t\t\tHasSpread:       hasSpread,\n\t\t\tIsSingleLine:    isSingleLine,\n\t\t\tCloseBracketLoc: closeBracketLoc,\n\t\t}}\n\n\tcase js_lexer.TOpenBrace:\n\t\tif opts.isUsingStmt {\n\t\t\tbreak\n\t\t}\n\t\tp.markSyntaxFeature(compat.Destructuring, p.lexer.Range())\n\t\tp.lexer.Next()\n\t\tisSingleLine := !p.lexer.HasNewlineBefore\n\t\tproperties := []js_ast.PropertyBinding{}\n\n\t\t// \"in\" expressions are allowed\n\t\toldAllowIn := p.allowIn\n\t\tp.allowIn = true\n\n\t\tfor p.lexer.Token != js_lexer.TCloseBrace {\n\t\t\tp.saveExprCommentsHere()\n\t\t\tproperty := p.parsePropertyBinding()\n\t\t\tproperties = append(properties, property)\n\n\t\t\t// Commas after spread elements are not allowed\n\t\t\tif property.IsSpread && p.lexer.Token == js_lexer.TComma {\n\t\t\t\tp.log.AddError(&p.tracker, p.lexer.Range(), \"Unexpected \\\",\\\" after rest pattern\")\n\t\t\t\tpanic(js_lexer.LexerPanic{})\n\t\t\t}\n\n\t\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\tisSingleLine = false\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\tisSingleLine = false\n\t\t\t}\n\t\t}\n\n\t\tp.allowIn = oldAllowIn\n\n\t\tif p.lexer.HasNewlineBefore {\n\t\t\tisSingleLine = false\n\t\t}\n\t\tcloseBraceLoc := p.saveExprCommentsHere()\n\t\tp.lexer.Expect(js_lexer.TCloseBrace)\n\t\treturn js_ast.Binding{Loc: loc, Data: &js_ast.BObject{\n\t\t\tProperties:    properties,\n\t\t\tIsSingleLine:  isSingleLine,\n\t\t\tCloseBraceLoc: closeBraceLoc,\n\t\t}}\n\t}\n\n\tp.lexer.Expect(js_lexer.TIdentifier)\n\treturn js_ast.Binding{}\n}\n\nfunc (p *parser) parseFn(\n\tname *ast.LocRef,\n\tclassKeyword logger.Range,\n\tdecoratorContext decoratorContextFlags,\n\tdata fnOrArrowDataParse,\n) (fn js_ast.Fn, hadBody bool) {\n\tfn.Name = name\n\tfn.HasRestArg = false\n\tfn.IsAsync = data.await == allowExpr\n\tfn.IsGenerator = data.yield == allowExpr\n\tfn.ArgumentsRef = ast.InvalidRef\n\tfn.OpenParenLoc = p.lexer.Loc()\n\tp.lexer.Expect(js_lexer.TOpenParen)\n\n\t// Await and yield are not allowed in function arguments\n\toldFnOrArrowData := p.fnOrArrowDataParse\n\tif data.await == allowExpr {\n\t\tp.fnOrArrowDataParse.await = forbidAll\n\t} else {\n\t\tp.fnOrArrowDataParse.await = allowIdent\n\t}\n\tif data.yield == allowExpr {\n\t\tp.fnOrArrowDataParse.yield = forbidAll\n\t} else {\n\t\tp.fnOrArrowDataParse.yield = allowIdent\n\t}\n\n\t// Don't suggest inserting \"async\" before anything if \"await\" is found\n\tp.fnOrArrowDataParse.needsAsyncLoc.Start = -1\n\n\t// If \"super\" is allowed in the body, it's allowed in the arguments\n\tp.fnOrArrowDataParse.allowSuperCall = data.allowSuperCall\n\tp.fnOrArrowDataParse.allowSuperProperty = data.allowSuperProperty\n\n\tfor p.lexer.Token != js_lexer.TCloseParen {\n\t\t// Skip over \"this\" type annotations\n\t\tif p.options.ts.Parse && p.lexer.Token == js_lexer.TThis {\n\t\t\tp.lexer.Next()\n\t\t\tif p.lexer.Token == js_lexer.TColon {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\t}\n\t\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tcontinue\n\t\t}\n\n\t\tvar decorators []js_ast.Decorator\n\t\tif data.decoratorScope != nil {\n\t\t\toldAwait := p.fnOrArrowDataParse.await\n\t\t\toldNeedsAsyncLoc := p.fnOrArrowDataParse.needsAsyncLoc\n\n\t\t\t// While TypeScript parameter decorators are expressions, they are not\n\t\t\t// evaluated where they exist in the code. They are moved to after the\n\t\t\t// class declaration and evaluated there instead. Specifically this\n\t\t\t// TypeScript code:\n\t\t\t//\n\t\t\t//   class Foo {\n\t\t\t//     foo(@bar() baz) {}\n\t\t\t//   }\n\t\t\t//\n\t\t\t// becomes this JavaScript code:\n\t\t\t//\n\t\t\t//   class Foo {\n\t\t\t//     foo(baz) {}\n\t\t\t//   }\n\t\t\t//   __decorate([\n\t\t\t//     __param(0, bar())\n\t\t\t//   ], Foo.prototype, \"foo\", null);\n\t\t\t//\n\t\t\t// One consequence of this is that whether \"await\" is allowed or not\n\t\t\t// depends on whether the class declaration itself is inside an \"async\"\n\t\t\t// function or not. The TypeScript compiler allows code that does this:\n\t\t\t//\n\t\t\t//   async function fn(foo) {\n\t\t\t//     class Foo {\n\t\t\t//       foo(@bar(await foo) baz) {}\n\t\t\t//     }\n\t\t\t//     return Foo\n\t\t\t//   }\n\t\t\t//\n\t\t\t// because that becomes the following valid JavaScript:\n\t\t\t//\n\t\t\t//   async function fn(foo) {\n\t\t\t//     class Foo {\n\t\t\t//       foo(baz) {}\n\t\t\t//     }\n\t\t\t//     __decorate([\n\t\t\t//       __param(0, bar(await foo))\n\t\t\t//     ], Foo.prototype, \"foo\", null);\n\t\t\t//     return Foo;\n\t\t\t//   }\n\t\t\t//\n\t\t\tif oldFnOrArrowData.await == allowExpr {\n\t\t\t\tp.fnOrArrowDataParse.await = allowExpr\n\t\t\t} else {\n\t\t\t\tp.fnOrArrowDataParse.needsAsyncLoc = oldFnOrArrowData.needsAsyncLoc\n\t\t\t}\n\n\t\t\tdecorators = p.parseDecorators(data.decoratorScope, classKeyword, decoratorContext|decoratorInFnArgs)\n\n\t\t\tp.fnOrArrowDataParse.await = oldAwait\n\t\t\tp.fnOrArrowDataParse.needsAsyncLoc = oldNeedsAsyncLoc\n\t\t}\n\n\t\tif !fn.HasRestArg && p.lexer.Token == js_lexer.TDotDotDot {\n\t\t\tp.markSyntaxFeature(compat.RestArgument, p.lexer.Range())\n\t\t\tp.lexer.Next()\n\t\t\tfn.HasRestArg = true\n\t\t}\n\n\t\tisTypeScriptCtorField := false\n\t\tisIdentifier := p.lexer.Token == js_lexer.TIdentifier\n\t\ttext := p.lexer.Identifier.String\n\t\targ := p.parseBinding(parseBindingOpts{})\n\n\t\tif p.options.ts.Parse {\n\t\t\t// Skip over TypeScript accessibility modifiers, which turn this argument\n\t\t\t// into a class field when used inside a class constructor. This is known\n\t\t\t// as a \"parameter property\" in TypeScript.\n\t\t\tif isIdentifier && data.isConstructor {\n\t\t\t\tfor p.lexer.Token == js_lexer.TIdentifier || p.lexer.Token == js_lexer.TOpenBrace || p.lexer.Token == js_lexer.TOpenBracket {\n\t\t\t\t\tif text != \"public\" && text != \"private\" && text != \"protected\" && text != \"readonly\" && text != \"override\" {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tisTypeScriptCtorField = true\n\n\t\t\t\t\t// TypeScript requires an identifier binding\n\t\t\t\t\tif p.lexer.Token != js_lexer.TIdentifier {\n\t\t\t\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t\t\t\t}\n\t\t\t\t\ttext = p.lexer.Identifier.String\n\n\t\t\t\t\t// Re-parse the binding (the current binding is the TypeScript keyword)\n\t\t\t\t\targ = p.parseBinding(parseBindingOpts{})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// \"function foo(a?) {}\"\n\t\t\tif p.lexer.Token == js_lexer.TQuestion {\n\t\t\t\tp.lexer.Next()\n\t\t\t}\n\n\t\t\t// \"function foo(a: any) {}\"\n\t\t\tif p.lexer.Token == js_lexer.TColon {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\t}\n\t\t}\n\n\t\tp.declareBinding(ast.SymbolHoisted, arg, parseStmtOpts{})\n\n\t\tvar defaultValueOrNil js_ast.Expr\n\t\tif !fn.HasRestArg && p.lexer.Token == js_lexer.TEquals {\n\t\t\tp.markSyntaxFeature(compat.DefaultArgument, p.lexer.Range())\n\t\t\tp.lexer.Next()\n\t\t\tdefaultValueOrNil = p.parseExpr(js_ast.LComma)\n\t\t}\n\n\t\tfn.Args = append(fn.Args, js_ast.Arg{\n\t\t\tDecorators:   decorators,\n\t\t\tBinding:      arg,\n\t\t\tDefaultOrNil: defaultValueOrNil,\n\n\t\t\t// We need to track this because it affects code generation\n\t\t\tIsTypeScriptCtorField: isTypeScriptCtorField,\n\t\t})\n\n\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\tbreak\n\t\t}\n\t\tif fn.HasRestArg {\n\t\t\t// JavaScript does not allow a comma after a rest argument\n\t\t\tif data.isTypeScriptDeclare {\n\t\t\t\t// TypeScript does allow a comma after a rest argument in a \"declare\" context\n\t\t\t\tp.lexer.Next()\n\t\t\t} else {\n\t\t\t\tp.lexer.Expect(js_lexer.TCloseParen)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tp.lexer.Next()\n\t}\n\n\t// Reserve the special name \"arguments\" in this scope. This ensures that it\n\t// shadows any variable called \"arguments\" in any parent scopes. But only do\n\t// this if it wasn't already declared above because arguments are allowed to\n\t// be called \"arguments\", in which case the real \"arguments\" is inaccessible.\n\tif _, ok := p.currentScope.Members[\"arguments\"]; !ok {\n\t\tfn.ArgumentsRef = p.declareSymbol(ast.SymbolArguments, fn.OpenParenLoc, \"arguments\")\n\t\tp.symbols[fn.ArgumentsRef.InnerIndex].Flags |= ast.MustNotBeRenamed\n\t}\n\n\tp.lexer.Expect(js_lexer.TCloseParen)\n\tp.fnOrArrowDataParse = oldFnOrArrowData\n\n\t// \"function foo(): any {}\"\n\tif p.options.ts.Parse && p.lexer.Token == js_lexer.TColon {\n\t\tp.lexer.Next()\n\t\tp.skipTypeScriptReturnType()\n\t}\n\n\t// \"function foo(): any;\"\n\tif data.allowMissingBodyForTypeScript && p.lexer.Token != js_lexer.TOpenBrace {\n\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\treturn\n\t}\n\n\tfn.Body = p.parseFnBody(data)\n\thadBody = true\n\treturn\n}\n\ntype fnKind uint8\n\nconst (\n\tfnStmt fnKind = iota\n\tfnExpr\n)\n\nfunc (p *parser) validateFunctionName(fn js_ast.Fn, kind fnKind) {\n\t// Prevent the function name from being the same as a function-specific keyword\n\tif fn.Name != nil {\n\t\tif fn.IsAsync && p.symbols[fn.Name.Ref.InnerIndex].OriginalName == \"await\" {\n\t\t\tp.log.AddError(&p.tracker, js_lexer.RangeOfIdentifier(p.source, fn.Name.Loc),\n\t\t\t\t\"An async function cannot be named \\\"await\\\"\")\n\t\t} else if fn.IsGenerator && p.symbols[fn.Name.Ref.InnerIndex].OriginalName == \"yield\" && kind == fnExpr {\n\t\t\tp.log.AddError(&p.tracker, js_lexer.RangeOfIdentifier(p.source, fn.Name.Loc),\n\t\t\t\t\"A generator function expression cannot be named \\\"yield\\\"\")\n\t\t}\n\t}\n}\n\nfunc (p *parser) validateDeclaredSymbolName(loc logger.Loc, name string) {\n\tif js_lexer.StrictModeReservedWords[name] {\n\t\tp.markStrictModeFeature(reservedWord, js_lexer.RangeOfIdentifier(p.source, loc), name)\n\t} else if isEvalOrArguments(name) {\n\t\tp.markStrictModeFeature(evalOrArguments, js_lexer.RangeOfIdentifier(p.source, loc), name)\n\t}\n}\n\nfunc (p *parser) parseClassStmt(loc logger.Loc, opts parseStmtOpts) js_ast.Stmt {\n\tvar name *ast.LocRef\n\tclassKeyword := p.lexer.Range()\n\tif p.lexer.Token == js_lexer.TClass {\n\t\tp.markSyntaxFeature(compat.Class, classKeyword)\n\t\tp.lexer.Next()\n\t} else {\n\t\tp.lexer.Expected(js_lexer.TClass)\n\t}\n\n\tif !opts.isNameOptional || (p.lexer.Token == js_lexer.TIdentifier && (!p.options.ts.Parse || p.lexer.Identifier.String != \"implements\")) {\n\t\tnameLoc := p.lexer.Loc()\n\t\tnameText := p.lexer.Identifier.String\n\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\tif p.fnOrArrowDataParse.await != allowIdent && nameText == \"await\" {\n\t\t\tp.log.AddError(&p.tracker, js_lexer.RangeOfIdentifier(p.source, nameLoc), \"Cannot use \\\"await\\\" as an identifier here:\")\n\t\t}\n\t\tname = &ast.LocRef{Loc: nameLoc, Ref: ast.InvalidRef}\n\t\tif !opts.isTypeScriptDeclare {\n\t\t\tname.Ref = p.declareSymbol(ast.SymbolClass, nameLoc, nameText)\n\t\t}\n\t}\n\n\t// Even anonymous classes can have TypeScript type parameters\n\tif p.options.ts.Parse {\n\t\tp.skipTypeScriptTypeParameters(allowInOutVarianceAnnotations | allowConstModifier)\n\t}\n\n\tclassOpts := parseClassOpts{\n\t\tisTypeScriptDeclare: opts.isTypeScriptDeclare,\n\t}\n\tif opts.deferredDecorators != nil {\n\t\tclassOpts.decorators = opts.deferredDecorators.decorators\n\t}\n\tscopeIndex := p.pushScopeForParsePass(js_ast.ScopeClassName, loc)\n\tclass := p.parseClass(classKeyword, name, classOpts)\n\n\tif opts.isTypeScriptDeclare {\n\t\tp.popAndDiscardScope(scopeIndex)\n\n\t\tif opts.isNamespaceScope && opts.isExport {\n\t\t\tp.hasNonLocalExportDeclareInsideNamespace = true\n\t\t}\n\n\t\t// Remember that this was a \"declare class\" so we can allow decorators on it\n\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptSharedWasDeclareClass}\n\t}\n\n\tp.popScope()\n\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SClass{Class: class, IsExport: opts.isExport}}\n}\n\nfunc (p *parser) parseClassExpr(decorators []js_ast.Decorator) js_ast.Expr {\n\tclassKeyword := p.lexer.Range()\n\tp.markSyntaxFeature(compat.Class, classKeyword)\n\tp.lexer.Expect(js_lexer.TClass)\n\tvar name *ast.LocRef\n\n\topts := parseClassOpts{\n\t\tdecorators:       decorators,\n\t\tdecoratorContext: decoratorInClassExpr,\n\t}\n\tp.pushScopeForParsePass(js_ast.ScopeClassName, classKeyword.Loc)\n\n\t// Parse an optional class name\n\tif p.lexer.Token == js_lexer.TIdentifier {\n\t\tif nameText := p.lexer.Identifier.String; !p.options.ts.Parse || nameText != \"implements\" {\n\t\t\tif p.fnOrArrowDataParse.await != allowIdent && nameText == \"await\" {\n\t\t\t\tp.log.AddError(&p.tracker, p.lexer.Range(), \"Cannot use \\\"await\\\" as an identifier here:\")\n\t\t\t}\n\t\t\tname = &ast.LocRef{Loc: p.lexer.Loc(), Ref: p.newSymbol(ast.SymbolOther, nameText)}\n\t\t\tp.lexer.Next()\n\t\t}\n\t}\n\n\t// Even anonymous classes can have TypeScript type parameters\n\tif p.options.ts.Parse {\n\t\tp.skipTypeScriptTypeParameters(allowInOutVarianceAnnotations | allowConstModifier)\n\t}\n\n\tclass := p.parseClass(classKeyword, name, opts)\n\n\tp.popScope()\n\treturn js_ast.Expr{Loc: classKeyword.Loc, Data: &js_ast.EClass{Class: class}}\n}\n\ntype parseClassOpts struct {\n\tdecorators          []js_ast.Decorator\n\tdecoratorContext    decoratorContextFlags\n\tisTypeScriptDeclare bool\n}\n\n// By the time we call this, the identifier and type parameters have already\n// been parsed. We need to start parsing from the \"extends\" clause.\nfunc (p *parser) parseClass(classKeyword logger.Range, name *ast.LocRef, classOpts parseClassOpts) js_ast.Class {\n\tvar extendsOrNil js_ast.Expr\n\n\tif p.lexer.Token == js_lexer.TExtends {\n\t\tp.lexer.Next()\n\t\textendsOrNil = p.parseExpr(js_ast.LNew)\n\n\t\t// TypeScript's type argument parser inside expressions backtracks if the\n\t\t// first token after the end of the type parameter list is \"{\", so the\n\t\t// parsed expression above will have backtracked if there are any type\n\t\t// arguments. This means we have to re-parse for any type arguments here.\n\t\t// This seems kind of wasteful to me but it's what the official compiler\n\t\t// does and it probably doesn't have that high of a performance overhead\n\t\t// because \"extends\" clauses aren't that frequent, so it should be ok.\n\t\tif p.options.ts.Parse {\n\t\t\tp.skipTypeScriptTypeArguments(skipTypeScriptTypeArgumentsOpts{})\n\t\t}\n\t}\n\n\tif p.options.ts.Parse && p.lexer.IsContextualKeyword(\"implements\") {\n\t\tp.lexer.Next()\n\t\tfor {\n\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t}\n\t}\n\n\tbodyLoc := p.lexer.Loc()\n\tp.lexer.Expect(js_lexer.TOpenBrace)\n\tproperties := []js_ast.Property{}\n\thasPropertyDecorator := false\n\n\t// Allow \"in\" and private fields inside class bodies\n\toldAllowIn := p.allowIn\n\tp.allowIn = true\n\n\t// A scope is needed for private identifiers\n\tscopeIndex := p.pushScopeForParsePass(js_ast.ScopeClassBody, bodyLoc)\n\n\topts := propertyOpts{\n\t\tisClass:          true,\n\t\tdecoratorScope:   p.currentScope,\n\t\tdecoratorContext: classOpts.decoratorContext,\n\t\tclassHasExtends:  extendsOrNil.Data != nil,\n\t\tclassKeyword:     classKeyword,\n\t}\n\thasConstructor := false\n\n\tfor p.lexer.Token != js_lexer.TCloseBrace {\n\t\tif p.lexer.Token == js_lexer.TSemicolon {\n\t\t\tp.lexer.Next()\n\t\t\tcontinue\n\t\t}\n\n\t\t// Parse decorators for this property\n\t\tfirstDecoratorLoc := p.lexer.Loc()\n\t\tscopeIndex := len(p.scopesInOrder)\n\t\topts.decorators = p.parseDecorators(p.currentScope, classKeyword, opts.decoratorContext)\n\t\tif len(opts.decorators) > 0 {\n\t\t\thasPropertyDecorator = true\n\t\t}\n\n\t\t// This property may turn out to be a type in TypeScript, which should be ignored\n\t\tif property, ok := p.parseProperty(p.saveExprCommentsHere(), js_ast.PropertyField, opts, nil); ok {\n\t\t\tproperties = append(properties, property)\n\n\t\t\t// Forbid decorators on class constructors\n\t\t\tif key, ok := property.Key.Data.(*js_ast.EString); ok && helpers.UTF16EqualsString(key.Value, \"constructor\") {\n\t\t\t\tif len(opts.decorators) > 0 {\n\t\t\t\t\tp.log.AddError(&p.tracker, logger.Range{Loc: firstDecoratorLoc},\n\t\t\t\t\t\t\"Decorators are not allowed on class constructors\")\n\t\t\t\t}\n\t\t\t\tif property.Kind.IsMethodDefinition() && !property.Flags.Has(js_ast.PropertyIsStatic) && !property.Flags.Has(js_ast.PropertyIsComputed) {\n\t\t\t\t\tif hasConstructor {\n\t\t\t\t\t\tp.log.AddError(&p.tracker, js_lexer.RangeOfIdentifier(p.source, property.Key.Loc),\n\t\t\t\t\t\t\t\"Classes cannot contain more than one constructor\")\n\t\t\t\t\t}\n\t\t\t\t\thasConstructor = true\n\t\t\t\t}\n\t\t\t}\n\t\t} else if !classOpts.isTypeScriptDeclare && len(opts.decorators) > 0 {\n\t\t\tp.log.AddError(&p.tracker, logger.Range{Loc: firstDecoratorLoc, Len: 1}, \"Decorators are not valid here\")\n\t\t\tp.discardScopesUpTo(scopeIndex)\n\t\t}\n\t}\n\n\t// Discard the private identifier scope inside a TypeScript \"declare class\"\n\tif classOpts.isTypeScriptDeclare {\n\t\tp.popAndDiscardScope(scopeIndex)\n\t} else {\n\t\tp.popScope()\n\t}\n\n\tp.allowIn = oldAllowIn\n\n\tcloseBraceLoc := p.saveExprCommentsHere()\n\tp.lexer.Expect(js_lexer.TCloseBrace)\n\n\t// TypeScript has legacy behavior that uses assignment semantics instead of\n\t// define semantics for class fields when \"useDefineForClassFields\" is enabled\n\t// (in which case TypeScript behaves differently than JavaScript, which is\n\t// arguably \"wrong\").\n\t//\n\t// This legacy behavior exists because TypeScript added class fields to\n\t// TypeScript before they were added to JavaScript. They decided to go with\n\t// assignment semantics for whatever reason. Later on TC39 decided to go with\n\t// define semantics for class fields instead. This behaves differently if the\n\t// base class has a setter with the same name.\n\t//\n\t// The value of \"useDefineForClassFields\" defaults to false when it's not\n\t// specified and the target is earlier than \"ES2022\" since the class field\n\t// language feature was added in ES2022. However, TypeScript's \"target\"\n\t// setting currently defaults to \"ES3\" which unfortunately means that the\n\t// \"useDefineForClassFields\" setting defaults to false (i.e. to \"wrong\").\n\t//\n\t// We default \"useDefineForClassFields\" to true (i.e. to \"correct\") instead.\n\t// This is partially because our target defaults to \"esnext\", and partially\n\t// because this is a legacy behavior that no one should be using anymore.\n\t// Users that want the wrong behavior can either set \"useDefineForClassFields\"\n\t// to false in \"tsconfig.json\" explicitly, or set TypeScript's \"target\" to\n\t// \"ES2021\" or earlier in their in \"tsconfig.json\" file.\n\tuseDefineForClassFields := !p.options.ts.Parse || p.options.ts.Config.UseDefineForClassFields == config.True ||\n\t\t(p.options.ts.Config.UseDefineForClassFields == config.Unspecified && p.options.ts.Config.Target != config.TSTargetBelowES2022)\n\n\treturn js_ast.Class{\n\t\tClassKeyword:  classKeyword,\n\t\tDecorators:    classOpts.decorators,\n\t\tName:          name,\n\t\tExtendsOrNil:  extendsOrNil,\n\t\tBodyLoc:       bodyLoc,\n\t\tProperties:    properties,\n\t\tCloseBraceLoc: closeBraceLoc,\n\n\t\t// Always lower standard decorators if they are present and TypeScript's\n\t\t// \"useDefineForClassFields\" setting is false even if the configured target\n\t\t// environment supports decorators. This setting changes the behavior of\n\t\t// class fields, and so we must lower decorators so they behave correctly.\n\t\tShouldLowerStandardDecorators: (len(classOpts.decorators) > 0 || hasPropertyDecorator) &&\n\t\t\t((!p.options.ts.Parse && p.options.unsupportedJSFeatures.Has(compat.Decorators)) ||\n\t\t\t\t(p.options.ts.Parse && p.options.ts.Config.ExperimentalDecorators != config.True &&\n\t\t\t\t\t(p.options.unsupportedJSFeatures.Has(compat.Decorators) || !useDefineForClassFields))),\n\n\t\tUseDefineForClassFields: useDefineForClassFields,\n\t}\n}\n\nfunc (p *parser) parseLabelName() *ast.LocRef {\n\tif p.lexer.Token != js_lexer.TIdentifier || p.lexer.HasNewlineBefore {\n\t\treturn nil\n\t}\n\n\tname := ast.LocRef{Loc: p.lexer.Loc(), Ref: p.storeNameInRef(p.lexer.Identifier)}\n\tp.lexer.Next()\n\treturn &name\n}\n\nfunc (p *parser) parsePath() (logger.Range, string, *ast.ImportAssertOrWith, ast.ImportRecordFlags) {\n\tvar flags ast.ImportRecordFlags\n\tpathRange := p.lexer.Range()\n\tpathText := helpers.UTF16ToString(p.lexer.StringLiteral())\n\tif p.lexer.Token == js_lexer.TNoSubstitutionTemplateLiteral {\n\t\tp.lexer.Next()\n\t} else {\n\t\tp.lexer.Expect(js_lexer.TStringLiteral)\n\t}\n\n\t// See https://github.com/tc39/proposal-import-attributes for more info\n\tvar assertOrWith *ast.ImportAssertOrWith\n\tif p.lexer.Token == js_lexer.TWith || (!p.lexer.HasNewlineBefore && p.lexer.IsContextualKeyword(\"assert\")) {\n\t\t// \"import './foo.json' assert { type: 'json' }\"\n\t\t// \"import './foo.json' with { type: 'json' }\"\n\t\tvar entries []ast.AssertOrWithEntry\n\t\tduplicates := make(map[string]logger.Range)\n\t\tkeyword := ast.WithKeyword\n\t\tif p.lexer.Token != js_lexer.TWith {\n\t\t\tkeyword = ast.AssertKeyword\n\t\t}\n\t\tkeywordLoc := p.saveExprCommentsHere()\n\t\tp.lexer.Next()\n\t\topenBraceLoc := p.saveExprCommentsHere()\n\t\tp.lexer.Expect(js_lexer.TOpenBrace)\n\n\t\tfor p.lexer.Token != js_lexer.TCloseBrace {\n\t\t\t// Parse the key\n\t\t\tkeyLoc := p.saveExprCommentsHere()\n\t\t\tpreferQuotedKey := false\n\t\t\tvar key []uint16\n\t\t\tvar keyText string\n\t\t\tif p.lexer.IsIdentifierOrKeyword() {\n\t\t\t\tkeyText = p.lexer.Identifier.String\n\t\t\t\tkey = helpers.StringToUTF16(keyText)\n\t\t\t} else if p.lexer.Token == js_lexer.TStringLiteral {\n\t\t\t\tkey = p.lexer.StringLiteral()\n\t\t\t\tkeyText = helpers.UTF16ToString(key)\n\t\t\t\tpreferQuotedKey = !p.options.minifySyntax\n\t\t\t} else {\n\t\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t\t}\n\t\t\tif prevRange, ok := duplicates[keyText]; ok {\n\t\t\t\twhat := \"attribute\"\n\t\t\t\tif keyword == ast.AssertKeyword {\n\t\t\t\t\twhat = \"assertion\"\n\t\t\t\t}\n\t\t\t\tp.log.AddErrorWithNotes(&p.tracker, p.lexer.Range(), fmt.Sprintf(\"Duplicate import %s %q\", what, keyText),\n\t\t\t\t\t[]logger.MsgData{p.tracker.MsgData(prevRange, fmt.Sprintf(\"The first %q was here:\", keyText))})\n\t\t\t}\n\t\t\tduplicates[keyText] = p.lexer.Range()\n\t\t\tp.lexer.Next()\n\t\t\tp.lexer.Expect(js_lexer.TColon)\n\n\t\t\t// Parse the value\n\t\t\tvalueLoc := p.saveExprCommentsHere()\n\t\t\tvalue := p.lexer.StringLiteral()\n\t\t\tp.lexer.Expect(js_lexer.TStringLiteral)\n\n\t\t\tentries = append(entries, ast.AssertOrWithEntry{\n\t\t\t\tKey:             key,\n\t\t\t\tKeyLoc:          keyLoc,\n\t\t\t\tValue:           value,\n\t\t\t\tValueLoc:        valueLoc,\n\t\t\t\tPreferQuotedKey: preferQuotedKey,\n\t\t\t})\n\n\t\t\t// Using \"assert: { type: 'json' }\" triggers special behavior\n\t\t\tif keyword == ast.AssertKeyword && helpers.UTF16EqualsString(key, \"type\") && helpers.UTF16EqualsString(value, \"json\") {\n\t\t\t\tflags |= ast.AssertTypeJSON\n\t\t\t}\n\n\t\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t}\n\n\t\tcloseBraceLoc := p.saveExprCommentsHere()\n\t\tp.lexer.Expect(js_lexer.TCloseBrace)\n\t\tif keyword == ast.AssertKeyword {\n\t\t\tp.maybeWarnAboutAssertKeyword(keywordLoc)\n\t\t}\n\t\tassertOrWith = &ast.ImportAssertOrWith{\n\t\t\tEntries:            entries,\n\t\t\tKeyword:            keyword,\n\t\t\tKeywordLoc:         keywordLoc,\n\t\t\tInnerOpenBraceLoc:  openBraceLoc,\n\t\t\tInnerCloseBraceLoc: closeBraceLoc,\n\t\t}\n\t}\n\n\treturn pathRange, pathText, assertOrWith, flags\n}\n\n// Let people know if they probably should be using \"with\" instead of \"assert\"\nfunc (p *parser) maybeWarnAboutAssertKeyword(loc logger.Loc) {\n\tif p.options.unsupportedJSFeatures.Has(compat.ImportAssertions) && !p.options.unsupportedJSFeatures.Has(compat.ImportAttributes) {\n\t\twhere := config.PrettyPrintTargetEnvironment(p.options.originalTargetEnv, p.options.unsupportedJSFeatureOverridesMask)\n\t\tmsg := logger.Msg{\n\t\t\tKind:  logger.Warning,\n\t\t\tData:  p.tracker.MsgData(js_lexer.RangeOfIdentifier(p.source, loc), \"The \\\"assert\\\" keyword is not supported in \"+where),\n\t\t\tNotes: []logger.MsgData{{Text: \"Did you mean to use \\\"with\\\" instead of \\\"assert\\\"?\"}},\n\t\t}\n\t\tmsg.Data.Location.Suggestion = \"with\"\n\t\tp.log.AddMsgID(logger.MsgID_JS_AssertToWith, msg)\n\t}\n}\n\n// This assumes the \"function\" token has already been parsed\nfunc (p *parser) parseFnStmt(loc logger.Loc, opts parseStmtOpts, isAsync bool, asyncRange logger.Range) js_ast.Stmt {\n\tisGenerator := p.lexer.Token == js_lexer.TAsterisk\n\thasError := false\n\tif isAsync {\n\t\thasError = p.markAsyncFn(asyncRange, isGenerator)\n\t}\n\tif isGenerator {\n\t\tif !hasError {\n\t\t\tp.markSyntaxFeature(compat.Generator, p.lexer.Range())\n\t\t}\n\t\tp.lexer.Next()\n\t}\n\n\tswitch opts.lexicalDecl {\n\tcase lexicalDeclForbid:\n\t\tp.forbidLexicalDecl(loc)\n\n\t// Allow certain function statements in certain single-statement contexts\n\tcase lexicalDeclAllowFnInsideIf, lexicalDeclAllowFnInsideLabel:\n\t\tif opts.isTypeScriptDeclare || isGenerator || isAsync {\n\t\t\tp.forbidLexicalDecl(loc)\n\t\t}\n\t}\n\n\tvar name *ast.LocRef\n\tvar nameText string\n\n\t// The name is optional for \"export default function() {}\" pseudo-statements\n\tif !opts.isNameOptional || p.lexer.Token == js_lexer.TIdentifier {\n\t\tnameLoc := p.lexer.Loc()\n\t\tnameText = p.lexer.Identifier.String\n\t\tif !isAsync && p.fnOrArrowDataParse.await != allowIdent && nameText == \"await\" {\n\t\t\tp.log.AddError(&p.tracker, js_lexer.RangeOfIdentifier(p.source, nameLoc), \"Cannot use \\\"await\\\" as an identifier here:\")\n\t\t}\n\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\tname = &ast.LocRef{Loc: nameLoc, Ref: ast.InvalidRef}\n\t}\n\n\t// Even anonymous functions can have TypeScript type parameters\n\tif p.options.ts.Parse {\n\t\tp.skipTypeScriptTypeParameters(allowConstModifier)\n\t}\n\n\t// Introduce a fake block scope for function declarations inside if statements\n\tvar ifStmtScopeIndex int\n\thasIfScope := opts.lexicalDecl == lexicalDeclAllowFnInsideIf\n\tif hasIfScope {\n\t\tifStmtScopeIndex = p.pushScopeForParsePass(js_ast.ScopeBlock, loc)\n\t}\n\n\tscopeIndex := p.pushScopeForParsePass(js_ast.ScopeFunctionArgs, p.lexer.Loc())\n\n\tawait := allowIdent\n\tyield := allowIdent\n\tif isAsync {\n\t\tawait = allowExpr\n\t}\n\tif isGenerator {\n\t\tyield = allowExpr\n\t}\n\n\tfn, hadBody := p.parseFn(name, logger.Range{}, 0, fnOrArrowDataParse{\n\t\tneedsAsyncLoc:       loc,\n\t\tasyncRange:          asyncRange,\n\t\tawait:               await,\n\t\tyield:               yield,\n\t\tisTypeScriptDeclare: opts.isTypeScriptDeclare,\n\n\t\t// Only allow omitting the body if we're parsing TypeScript\n\t\tallowMissingBodyForTypeScript: p.options.ts.Parse,\n\t})\n\n\t// Don't output anything if it's just a forward declaration of a function\n\tif opts.isTypeScriptDeclare || !hadBody {\n\t\tp.popAndDiscardScope(scopeIndex)\n\n\t\t// Balance the fake block scope introduced above\n\t\tif hasIfScope {\n\t\t\tp.popAndDiscardScope(ifStmtScopeIndex)\n\t\t}\n\n\t\tif opts.isTypeScriptDeclare && opts.isNamespaceScope && opts.isExport {\n\t\t\tp.hasNonLocalExportDeclareInsideNamespace = true\n\t\t}\n\n\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptShared}\n\t}\n\n\tp.popScope()\n\n\t// Only declare the function after we know if it had a body or not. Otherwise\n\t// TypeScript code such as this will double-declare the symbol:\n\t//\n\t//     function foo(): void;\n\t//     function foo(): void {}\n\t//\n\tif name != nil {\n\t\tkind := ast.SymbolHoistedFunction\n\t\tif isGenerator || isAsync {\n\t\t\tkind = ast.SymbolGeneratorOrAsyncFunction\n\t\t}\n\t\tname.Ref = p.declareSymbol(kind, name.Loc, nameText)\n\t}\n\n\t// Balance the fake block scope introduced above\n\tif hasIfScope {\n\t\tp.popScope()\n\t}\n\n\tfn.HasIfScope = hasIfScope\n\tp.validateFunctionName(fn, fnStmt)\n\tif opts.hasNoSideEffectsComment && !p.options.ignoreDCEAnnotations {\n\t\tfn.HasNoSideEffectsComment = true\n\t\tif name != nil && !opts.isTypeScriptDeclare {\n\t\t\tp.symbols[name.Ref.InnerIndex].Flags |= ast.CallCanBeUnwrappedIfUnused\n\t\t}\n\t}\n\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SFunction{Fn: fn, IsExport: opts.isExport}}\n}\n\ntype deferredDecorators struct {\n\tdecorators []js_ast.Decorator\n}\n\ntype decoratorContextFlags uint8\n\nconst (\n\tdecoratorBeforeClassExpr = 1 << iota\n\tdecoratorInClassExpr\n\tdecoratorInFnArgs\n)\n\nfunc (p *parser) parseDecorators(decoratorScope *js_ast.Scope, classKeyword logger.Range, context decoratorContextFlags) (decorators []js_ast.Decorator) {\n\tif p.lexer.Token == js_lexer.TAt {\n\t\tif p.options.ts.Parse {\n\t\t\tif p.options.ts.Config.ExperimentalDecorators == config.True {\n\t\t\t\tif (context & decoratorInClassExpr) != 0 {\n\t\t\t\t\tp.lexer.AddRangeErrorWithNotes(p.lexer.Range(), \"TypeScript experimental decorators can only be used with class declarations\",\n\t\t\t\t\t\t[]logger.MsgData{p.tracker.MsgData(classKeyword, \"This is a class expression, not a class declaration:\")})\n\t\t\t\t} else if (context & decoratorBeforeClassExpr) != 0 {\n\t\t\t\t\tp.log.AddError(&p.tracker, p.lexer.Range(), \"TypeScript experimental decorators cannot be used in expression position\")\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (context&decoratorInFnArgs) != 0 && p.options.ts.Config.ExperimentalDecorators != config.True {\n\t\t\t\t\tp.log.AddErrorWithNotes(&p.tracker, p.lexer.Range(), \"Parameter decorators only work when experimental decorators are enabled\", []logger.MsgData{{\n\t\t\t\t\t\tText: \"You can enable experimental decorators by adding \\\"experimentalDecorators\\\": true to your \\\"tsconfig.json\\\" file.\",\n\t\t\t\t\t}})\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (context & decoratorInFnArgs) != 0 {\n\t\t\t\tp.log.AddError(&p.tracker, p.lexer.Range(), \"Parameter decorators are not allowed in JavaScript\")\n\t\t\t}\n\t\t}\n\t}\n\n\t// TypeScript decorators cause us to temporarily revert to the scope that\n\t// encloses the class declaration, since that's where the generated code\n\t// for TypeScript decorators will be inserted.\n\toldScope := p.currentScope\n\tp.currentScope = decoratorScope\n\n\tfor p.lexer.Token == js_lexer.TAt {\n\t\tatLoc := p.lexer.Loc()\n\t\tp.lexer.Next()\n\n\t\tvar value js_ast.Expr\n\t\tif p.options.ts.Parse && p.options.ts.Config.ExperimentalDecorators == config.True {\n\t\t\t// TypeScript's experimental decorator syntax is more permissive than\n\t\t\t// JavaScript. Parse a new/call expression with \"exprFlagDecorator\" so\n\t\t\t// we ignore EIndex expressions, since they may be part of a computed\n\t\t\t// property:\n\t\t\t//\n\t\t\t//   class Foo {\n\t\t\t//     @foo ['computed']() {}\n\t\t\t//   }\n\t\t\t//\n\t\t\t// This matches the behavior of the TypeScript compiler.\n\t\t\tp.parseExperimentalDecoratorNesting++\n\t\t\tvalue = p.parseExprWithFlags(js_ast.LNew, exprFlagDecorator)\n\t\t\tp.parseExperimentalDecoratorNesting--\n\t\t} else {\n\t\t\t// JavaScript's decorator syntax is more restrictive. Parse it using a\n\t\t\t// special parser that doesn't allow normal expressions (e.g. \"?.\").\n\t\t\tvalue = p.parseDecorator()\n\t\t}\n\t\tdecorators = append(decorators, js_ast.Decorator{\n\t\t\tValue:            value,\n\t\t\tAtLoc:            atLoc,\n\t\t\tOmitNewlineAfter: !p.lexer.HasNewlineBefore,\n\t\t})\n\t}\n\n\t// Avoid \"popScope\" because this decorator scope is not hierarchical\n\tp.currentScope = oldScope\n\treturn decorators\n}\n\nfunc (p *parser) parseDecorator() js_ast.Expr {\n\tif p.lexer.Token == js_lexer.TOpenParen {\n\t\tp.lexer.Next()\n\t\tvalue := p.parseExpr(js_ast.LLowest)\n\t\tp.lexer.Expect(js_lexer.TCloseParen)\n\t\treturn value\n\t}\n\n\tname := p.lexer.Identifier\n\tnameRange := p.lexer.Range()\n\tp.lexer.Expect(js_lexer.TIdentifier)\n\n\t// Forbid invalid identifiers\n\tif (p.fnOrArrowDataParse.await != allowIdent && name.String == \"await\") ||\n\t\t(p.fnOrArrowDataParse.yield != allowIdent && name.String == \"yield\") {\n\t\tp.log.AddError(&p.tracker, nameRange, fmt.Sprintf(\"Cannot use %q as an identifier here:\", name.String))\n\t}\n\n\tmemberExpr := js_ast.Expr{Loc: nameRange.Loc, Data: &js_ast.EIdentifier{Ref: p.storeNameInRef(name)}}\n\n\t// Custom error reporting for error recovery\n\tvar syntaxError logger.MsgData\n\twrapRange := nameRange\n\nloop:\n\tfor {\n\t\tswitch p.lexer.Token {\n\t\tcase js_lexer.TExclamation:\n\t\t\t// Skip over TypeScript non-null assertions\n\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tif !p.options.ts.Parse {\n\t\t\t\tp.lexer.Unexpected()\n\t\t\t}\n\t\t\twrapRange.Len = p.lexer.Range().End() - wrapRange.Loc.Start\n\t\t\tp.lexer.Next()\n\n\t\tcase js_lexer.TDot, js_lexer.TQuestionDot:\n\t\t\t// The grammar for \"DecoratorMemberExpression\" currently forbids \"?.\"\n\t\t\tif p.lexer.Token == js_lexer.TQuestionDot && syntaxError.Location == nil {\n\t\t\t\tsyntaxError = p.tracker.MsgData(p.lexer.Range(), \"JavaScript decorator syntax does not allow \\\"?.\\\" here\")\n\t\t\t}\n\n\t\t\tp.lexer.Next()\n\t\t\twrapRange.Len = p.lexer.Range().End() - wrapRange.Loc.Start\n\n\t\t\tif p.lexer.Token == js_lexer.TPrivateIdentifier {\n\t\t\t\tname := p.lexer.Identifier\n\t\t\t\tmemberExpr.Data = &js_ast.EIndex{\n\t\t\t\t\tTarget: memberExpr,\n\t\t\t\t\tIndex:  js_ast.Expr{Loc: p.lexer.Loc(), Data: &js_ast.EPrivateIdentifier{Ref: p.storeNameInRef(name)}},\n\t\t\t\t}\n\t\t\t\tp.reportPrivateNameUsage(name.String)\n\t\t\t\tp.lexer.Next()\n\t\t\t} else {\n\t\t\t\tmemberExpr.Data = &js_ast.EDot{\n\t\t\t\t\tTarget:  memberExpr,\n\t\t\t\t\tName:    p.lexer.Identifier.String,\n\t\t\t\t\tNameLoc: p.lexer.Loc(),\n\t\t\t\t}\n\t\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t\t}\n\n\t\tcase js_lexer.TOpenParen:\n\t\t\targs, closeParenLoc, isMultiLine := p.parseCallArgs()\n\t\t\tmemberExpr.Data = &js_ast.ECall{\n\t\t\t\tTarget:        memberExpr,\n\t\t\t\tArgs:          args,\n\t\t\t\tCloseParenLoc: closeParenLoc,\n\t\t\t\tIsMultiLine:   isMultiLine,\n\t\t\t\tKind:          js_ast.TargetWasOriginallyPropertyAccess,\n\t\t\t}\n\t\t\twrapRange.Len = closeParenLoc.Start + 1 - wrapRange.Loc.Start\n\n\t\t\t// The grammar for \"DecoratorCallExpression\" currently forbids anything after it\n\t\t\tif p.lexer.Token == js_lexer.TDot {\n\t\t\t\tif syntaxError.Location == nil {\n\t\t\t\t\tsyntaxError = p.tracker.MsgData(p.lexer.Range(), \"JavaScript decorator syntax does not allow \\\".\\\" after a call expression\")\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tbreak loop\n\n\t\tdefault:\n\t\t\t// \"@x<y>\"\n\t\t\t// \"@x.y<z>\"\n\t\t\tif !p.skipTypeScriptTypeArguments(skipTypeScriptTypeArgumentsOpts{}) {\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t}\n\t}\n\n\t// Suggest that non-decorator expressions be wrapped in parentheses\n\tif syntaxError.Location != nil {\n\t\tvar notes []logger.MsgData\n\t\tif text := p.source.TextForRange(wrapRange); !strings.ContainsRune(text, '\\n') {\n\t\t\tnote := p.tracker.MsgData(wrapRange, \"Wrap this decorator in parentheses to allow arbitrary expressions:\")\n\t\t\tnote.Location.Suggestion = fmt.Sprintf(\"(%s)\", text)\n\t\t\tnotes = []logger.MsgData{note}\n\t\t}\n\t\tp.log.AddMsg(logger.Msg{\n\t\t\tKind:  logger.Error,\n\t\t\tData:  syntaxError,\n\t\t\tNotes: notes,\n\t\t})\n\t}\n\n\treturn memberExpr\n}\n\ntype lexicalDecl uint8\n\nconst (\n\tlexicalDeclForbid lexicalDecl = iota\n\tlexicalDeclAllowAll\n\tlexicalDeclAllowFnInsideIf\n\tlexicalDeclAllowFnInsideLabel\n)\n\ntype parseStmtOpts struct {\n\tdeferredDecorators      *deferredDecorators\n\tlexicalDecl             lexicalDecl\n\tisModuleScope           bool\n\tisNamespaceScope        bool\n\tisExport                bool\n\tisExportDefault         bool\n\tisNameOptional          bool // For \"export default\" pseudo-statements\n\tisTypeScriptDeclare     bool\n\tisForLoopInit           bool\n\tisForAwaitLoopInit      bool\n\tallowDirectivePrologue  bool\n\thasNoSideEffectsComment bool\n\tisUsingStmt             bool\n\tisCaseBody              bool\n}\n\nfunc (p *parser) parseStmt(opts parseStmtOpts) js_ast.Stmt {\n\tloc := p.lexer.Loc()\n\n\tif (p.lexer.HasCommentBefore & js_lexer.NoSideEffectsCommentBefore) != 0 {\n\t\topts.hasNoSideEffectsComment = true\n\t}\n\n\t// Do not attach any leading comments to the next expression\n\tp.lexer.CommentsBeforeToken = p.lexer.CommentsBeforeToken[:0]\n\n\tswitch p.lexer.Token {\n\tcase js_lexer.TSemicolon:\n\t\tp.lexer.Next()\n\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.SEmptyShared}\n\n\tcase js_lexer.TExport:\n\t\tpreviousExportKeyword := p.esmExportKeyword\n\t\tif opts.isModuleScope {\n\t\t\tp.esmExportKeyword = p.lexer.Range()\n\t\t} else if !opts.isNamespaceScope {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t\tp.lexer.Next()\n\n\t\tswitch p.lexer.Token {\n\t\tcase js_lexer.TClass, js_lexer.TConst, js_lexer.TFunction, js_lexer.TVar, js_lexer.TAt:\n\t\t\topts.isExport = true\n\t\t\treturn p.parseStmt(opts)\n\n\t\tcase js_lexer.TImport:\n\t\t\t// \"export import foo = bar\"\n\t\t\tif p.options.ts.Parse && (opts.isModuleScope || opts.isNamespaceScope) {\n\t\t\t\topts.isExport = true\n\t\t\t\treturn p.parseStmt(opts)\n\t\t\t}\n\n\t\t\tp.lexer.Unexpected()\n\t\t\treturn js_ast.Stmt{}\n\n\t\tcase js_lexer.TEnum:\n\t\t\tif !p.options.ts.Parse {\n\t\t\t\tp.lexer.Unexpected()\n\t\t\t}\n\t\t\topts.isExport = true\n\t\t\treturn p.parseStmt(opts)\n\n\t\tcase js_lexer.TIdentifier:\n\t\t\tif p.lexer.IsContextualKeyword(\"let\") {\n\t\t\t\topts.isExport = true\n\t\t\t\treturn p.parseStmt(opts)\n\t\t\t}\n\n\t\t\tif p.lexer.IsContextualKeyword(\"as\") {\n\t\t\t\t// \"export as namespace ns;\"\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.lexer.ExpectContextualKeyword(\"namespace\")\n\t\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptShared}\n\t\t\t}\n\n\t\t\tif p.lexer.IsContextualKeyword(\"async\") {\n\t\t\t\t// \"export async function foo() {}\"\n\t\t\t\tasyncRange := p.lexer.Range()\n\t\t\t\tp.lexer.Next()\n\t\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\t\tp.log.AddError(&p.tracker, logger.Range{Loc: logger.Loc{Start: asyncRange.End()}},\n\t\t\t\t\t\t\"Unexpected newline after \\\"async\\\"\")\n\t\t\t\t\tpanic(js_lexer.LexerPanic{})\n\t\t\t\t}\n\t\t\t\tp.lexer.Expect(js_lexer.TFunction)\n\t\t\t\topts.isExport = true\n\t\t\t\treturn p.parseFnStmt(loc, opts, true /* isAsync */, asyncRange)\n\t\t\t}\n\n\t\t\tif p.options.ts.Parse {\n\t\t\t\tswitch p.lexer.Identifier.String {\n\t\t\t\tcase \"type\":\n\t\t\t\t\t// \"export type foo = ...\"\n\t\t\t\t\ttypeRange := p.lexer.Range()\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tif p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace && p.lexer.Token != js_lexer.TAsterisk {\n\t\t\t\t\t\tp.log.AddError(&p.tracker, logger.Range{Loc: logger.Loc{Start: typeRange.End()}},\n\t\t\t\t\t\t\t\"Unexpected newline after \\\"type\\\"\")\n\t\t\t\t\t\tpanic(js_lexer.LexerPanic{})\n\t\t\t\t\t}\n\t\t\t\t\tp.skipTypeScriptTypeStmt(parseStmtOpts{isModuleScope: opts.isModuleScope, isExport: true})\n\t\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptShared}\n\n\t\t\t\tcase \"namespace\", \"abstract\", \"module\", \"interface\":\n\t\t\t\t\t// \"export namespace Foo {}\"\n\t\t\t\t\t// \"export abstract class Foo {}\"\n\t\t\t\t\t// \"export module Foo {}\"\n\t\t\t\t\t// \"export interface Foo {}\"\n\t\t\t\t\topts.isExport = true\n\t\t\t\t\treturn p.parseStmt(opts)\n\n\t\t\t\tcase \"declare\":\n\t\t\t\t\t// \"export declare class Foo {}\"\n\t\t\t\t\topts.isExport = true\n\t\t\t\t\topts.lexicalDecl = lexicalDeclAllowAll\n\t\t\t\t\topts.isTypeScriptDeclare = true\n\t\t\t\t\treturn p.parseStmt(opts)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.lexer.Unexpected()\n\t\t\treturn js_ast.Stmt{}\n\n\t\tcase js_lexer.TDefault:\n\t\t\tif !opts.isModuleScope && (!opts.isNamespaceScope || !opts.isTypeScriptDeclare) {\n\t\t\t\tp.lexer.Unexpected()\n\t\t\t}\n\n\t\t\tdefaultLoc := p.lexer.Loc()\n\t\t\tp.lexer.Next()\n\n\t\t\t// Also pick up comments after the \"default\" keyword\n\t\t\tif (p.lexer.HasCommentBefore & js_lexer.NoSideEffectsCommentBefore) != 0 {\n\t\t\t\topts.hasNoSideEffectsComment = true\n\t\t\t}\n\n\t\t\t// The default name is lazily generated only if no other name is present\n\t\t\tcreateDefaultName := func() ast.LocRef {\n\t\t\t\t// This must be named \"default\" for when \"--keep-names\" is active\n\t\t\t\tdefaultName := ast.LocRef{Loc: defaultLoc, Ref: p.newSymbol(ast.SymbolOther, \"default\")}\n\t\t\t\tp.currentScope.Generated = append(p.currentScope.Generated, defaultName.Ref)\n\t\t\t\treturn defaultName\n\t\t\t}\n\n\t\t\t// \"export default async function() {}\"\n\t\t\t// \"export default async function foo() {}\"\n\t\t\tif p.lexer.IsContextualKeyword(\"async\") {\n\t\t\t\tasyncRange := p.lexer.Range()\n\t\t\t\tp.lexer.Next()\n\n\t\t\t\tif p.lexer.Token == js_lexer.TFunction && !p.lexer.HasNewlineBefore {\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tstmt := p.parseFnStmt(loc, parseStmtOpts{\n\t\t\t\t\t\tisNameOptional:          true,\n\t\t\t\t\t\tlexicalDecl:             lexicalDeclAllowAll,\n\t\t\t\t\t\thasNoSideEffectsComment: opts.hasNoSideEffectsComment,\n\t\t\t\t\t}, true /* isAsync */, asyncRange)\n\t\t\t\t\tif _, ok := stmt.Data.(*js_ast.STypeScript); ok {\n\t\t\t\t\t\treturn stmt // This was just a type annotation\n\t\t\t\t\t}\n\n\t\t\t\t\t// Use the statement name if present, since it's a better name\n\t\t\t\t\tvar defaultName ast.LocRef\n\t\t\t\t\tif s, ok := stmt.Data.(*js_ast.SFunction); ok && s.Fn.Name != nil {\n\t\t\t\t\t\tdefaultName = ast.LocRef{Loc: defaultLoc, Ref: s.Fn.Name.Ref}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdefaultName = createDefaultName()\n\t\t\t\t\t}\n\n\t\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SExportDefault{DefaultName: defaultName, Value: stmt}}\n\t\t\t\t}\n\n\t\t\t\tdefaultName := createDefaultName()\n\t\t\t\texpr := p.parseSuffix(p.parseAsyncPrefixExpr(asyncRange, js_ast.LComma, 0), js_ast.LComma, nil, 0)\n\t\t\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SExportDefault{\n\t\t\t\t\tDefaultName: defaultName, Value: js_ast.Stmt{Loc: loc, Data: &js_ast.SExpr{Value: expr}}}}\n\t\t\t}\n\n\t\t\t// \"export default class {}\"\n\t\t\t// \"export default class Foo {}\"\n\t\t\t// \"export default @x class {}\"\n\t\t\t// \"export default @x class Foo {}\"\n\t\t\t// \"export default function() {}\"\n\t\t\t// \"export default function foo() {}\"\n\t\t\t// \"export default interface Foo {}\"\n\t\t\t// \"export default interface + 1\"\n\t\t\tif p.lexer.Token == js_lexer.TFunction || p.lexer.Token == js_lexer.TClass || p.lexer.Token == js_lexer.TAt ||\n\t\t\t\t(p.options.ts.Parse && p.lexer.IsContextualKeyword(\"interface\")) {\n\t\t\t\tstmt := p.parseStmt(parseStmtOpts{\n\t\t\t\t\tdeferredDecorators:      opts.deferredDecorators,\n\t\t\t\t\tisNameOptional:          true,\n\t\t\t\t\tisExportDefault:         true,\n\t\t\t\t\tlexicalDecl:             lexicalDeclAllowAll,\n\t\t\t\t\thasNoSideEffectsComment: opts.hasNoSideEffectsComment,\n\t\t\t\t})\n\n\t\t\t\t// Use the statement name if present, since it's a better name\n\t\t\t\tvar defaultName ast.LocRef\n\t\t\t\tswitch s := stmt.Data.(type) {\n\t\t\t\tcase *js_ast.STypeScript, *js_ast.SExpr:\n\t\t\t\t\treturn stmt // Handle the \"interface\" case above\n\t\t\t\tcase *js_ast.SFunction:\n\t\t\t\t\tif s.Fn.Name != nil {\n\t\t\t\t\t\tdefaultName = ast.LocRef{Loc: defaultLoc, Ref: s.Fn.Name.Ref}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdefaultName = createDefaultName()\n\t\t\t\t\t}\n\t\t\t\tcase *js_ast.SClass:\n\t\t\t\t\tif s.Class.Name != nil {\n\t\t\t\t\t\tdefaultName = ast.LocRef{Loc: defaultLoc, Ref: s.Class.Name.Ref}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdefaultName = createDefaultName()\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tpanic(\"Internal error\")\n\t\t\t\t}\n\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SExportDefault{DefaultName: defaultName, Value: stmt}}\n\t\t\t}\n\n\t\t\tisIdentifier := p.lexer.Token == js_lexer.TIdentifier\n\t\t\tname := p.lexer.Identifier.String\n\t\t\texpr := p.parseExpr(js_ast.LComma)\n\n\t\t\t// \"export default abstract class {}\"\n\t\t\t// \"export default abstract class Foo {}\"\n\t\t\tif p.options.ts.Parse && isIdentifier && name == \"abstract\" && !p.lexer.HasNewlineBefore {\n\t\t\t\tif _, ok := expr.Data.(*js_ast.EIdentifier); ok && p.lexer.Token == js_lexer.TClass {\n\t\t\t\t\tstmt := p.parseClassStmt(loc, parseStmtOpts{\n\t\t\t\t\t\tdeferredDecorators: opts.deferredDecorators,\n\t\t\t\t\t\tisNameOptional:     true,\n\t\t\t\t\t})\n\n\t\t\t\t\t// Use the statement name if present, since it's a better name\n\t\t\t\t\tvar defaultName ast.LocRef\n\t\t\t\t\tif s, ok := stmt.Data.(*js_ast.SClass); ok && s.Class.Name != nil {\n\t\t\t\t\t\tdefaultName = ast.LocRef{Loc: defaultLoc, Ref: s.Class.Name.Ref}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdefaultName = createDefaultName()\n\t\t\t\t\t}\n\n\t\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SExportDefault{DefaultName: defaultName, Value: stmt}}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\t\tdefaultName := createDefaultName()\n\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SExportDefault{\n\t\t\t\tDefaultName: defaultName, Value: js_ast.Stmt{Loc: loc, Data: &js_ast.SExpr{Value: expr}}}}\n\n\t\tcase js_lexer.TAsterisk:\n\t\t\tif !opts.isModuleScope && (!opts.isNamespaceScope || !opts.isTypeScriptDeclare) {\n\t\t\t\tp.lexer.Unexpected()\n\t\t\t}\n\n\t\t\tp.lexer.Next()\n\t\t\tvar namespaceRef ast.Ref\n\t\t\tvar alias *js_ast.ExportStarAlias\n\t\t\tvar pathRange logger.Range\n\t\t\tvar pathText string\n\t\t\tvar assertOrWith *ast.ImportAssertOrWith\n\t\t\tvar flags ast.ImportRecordFlags\n\n\t\t\tif p.lexer.IsContextualKeyword(\"as\") {\n\t\t\t\t// \"export * as ns from 'path'\"\n\t\t\t\tp.lexer.Next()\n\t\t\t\tname := p.parseClauseAlias(\"export\")\n\t\t\t\tnamespaceRef = p.storeNameInRef(name)\n\t\t\t\talias = &js_ast.ExportStarAlias{Loc: p.lexer.Loc(), OriginalName: name.String}\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.lexer.ExpectContextualKeyword(\"from\")\n\t\t\t\tpathRange, pathText, assertOrWith, flags = p.parsePath()\n\t\t\t} else {\n\t\t\t\t// \"export * from 'path'\"\n\t\t\t\tp.lexer.ExpectContextualKeyword(\"from\")\n\t\t\t\tpathRange, pathText, assertOrWith, flags = p.parsePath()\n\t\t\t\tname := js_ast.GenerateNonUniqueNameFromPath(pathText) + \"_star\"\n\t\t\t\tnamespaceRef = p.storeNameInRef(js_lexer.MaybeSubstring{String: name})\n\t\t\t}\n\t\t\timportRecordIndex := p.addImportRecord(ast.ImportStmt, ast.EvaluationPhase, pathRange, pathText, assertOrWith, flags)\n\n\t\t\t// Export-star statements anywhere in the file disable top-level const\n\t\t\t// local prefix because import cycles can be used to trigger TDZ\n\t\t\tp.currentScope.IsAfterConstLocalPrefix = true\n\n\t\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SExportStar{\n\t\t\t\tNamespaceRef:      namespaceRef,\n\t\t\t\tAlias:             alias,\n\t\t\t\tImportRecordIndex: importRecordIndex,\n\t\t\t}}\n\n\t\tcase js_lexer.TOpenBrace:\n\t\t\tif !opts.isModuleScope && (!opts.isNamespaceScope || !opts.isTypeScriptDeclare) {\n\t\t\t\tp.lexer.Unexpected()\n\t\t\t}\n\n\t\t\titems, isSingleLine := p.parseExportClause()\n\t\t\tif p.lexer.IsContextualKeyword(\"from\") {\n\t\t\t\t// \"export {} from 'path'\"\n\t\t\t\tp.lexer.Next()\n\t\t\t\tpathLoc, pathText, assertOrWith, flags := p.parsePath()\n\t\t\t\timportRecordIndex := p.addImportRecord(ast.ImportStmt, ast.EvaluationPhase, pathLoc, pathText, assertOrWith, flags)\n\t\t\t\tname := \"import_\" + js_ast.GenerateNonUniqueNameFromPath(pathText)\n\t\t\t\tnamespaceRef := p.storeNameInRef(js_lexer.MaybeSubstring{String: name})\n\n\t\t\t\t// Export clause statements anywhere in the file disable top-level const\n\t\t\t\t// local prefix because import cycles can be used to trigger TDZ\n\t\t\t\tp.currentScope.IsAfterConstLocalPrefix = true\n\n\t\t\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SExportFrom{\n\t\t\t\t\tItems:             items,\n\t\t\t\t\tNamespaceRef:      namespaceRef,\n\t\t\t\t\tImportRecordIndex: importRecordIndex,\n\t\t\t\t\tIsSingleLine:      isSingleLine,\n\t\t\t\t}}\n\t\t\t}\n\n\t\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SExportClause{Items: items, IsSingleLine: isSingleLine}}\n\n\t\tcase js_lexer.TEquals:\n\t\t\t// \"export = value;\"\n\t\t\tp.esmExportKeyword = previousExportKeyword // This wasn't an ESM export statement after all\n\t\t\tif p.options.ts.Parse {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tvalue := p.parseExpr(js_ast.LLowest)\n\t\t\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SExportEquals{Value: value}}\n\t\t\t}\n\t\t\tp.lexer.Unexpected()\n\t\t\treturn js_ast.Stmt{}\n\n\t\tdefault:\n\t\t\tp.lexer.Unexpected()\n\t\t\treturn js_ast.Stmt{}\n\t\t}\n\n\tcase js_lexer.TFunction:\n\t\tp.lexer.Next()\n\t\treturn p.parseFnStmt(loc, opts, false /* isAsync */, logger.Range{})\n\n\tcase js_lexer.TEnum:\n\t\tif !p.options.ts.Parse {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t\treturn p.parseTypeScriptEnumStmt(loc, opts)\n\n\tcase js_lexer.TAt:\n\t\t// Parse decorators before class statements, which are potentially exported\n\t\tscopeIndex := len(p.scopesInOrder)\n\t\tdecorators := p.parseDecorators(p.currentScope, logger.Range{}, 0)\n\n\t\t// \"@x export @y class Foo {}\"\n\t\tif opts.deferredDecorators != nil {\n\t\t\tp.log.AddError(&p.tracker, logger.Range{Loc: loc, Len: 1}, \"Decorators are not valid here\")\n\t\t\tp.discardScopesUpTo(scopeIndex)\n\t\t\treturn p.parseStmt(opts)\n\t\t}\n\n\t\t// If this turns out to be a \"declare class\" statement, we need to undo the\n\t\t// scopes that were potentially pushed while parsing the decorator arguments.\n\t\t// That can look like any one of the following:\n\t\t//\n\t\t//   \"@decorator declare class Foo {}\"\n\t\t//   \"@decorator declare abstract class Foo {}\"\n\t\t//   \"@decorator export declare class Foo {}\"\n\t\t//   \"@decorator export declare abstract class Foo {}\"\n\t\t//\n\t\topts.deferredDecorators = &deferredDecorators{\n\t\t\tdecorators: decorators,\n\t\t}\n\n\t\tstmt := p.parseStmt(opts)\n\n\t\t// Check for valid decorator targets\n\t\tswitch s := stmt.Data.(type) {\n\t\tcase *js_ast.SClass:\n\t\t\treturn stmt\n\n\t\tcase *js_ast.SExportDefault:\n\t\t\tswitch s.Value.Data.(type) {\n\t\t\tcase *js_ast.SClass:\n\t\t\t\treturn stmt\n\t\t\t}\n\n\t\tcase *js_ast.STypeScript:\n\t\t\tif s.WasDeclareClass {\n\t\t\t\t// If this is a type declaration, discard any scopes that were pushed\n\t\t\t\t// while parsing decorators. Unlike with the class statements above,\n\t\t\t\t// these scopes won't end up being visited during the upcoming visit\n\t\t\t\t// pass because type declarations aren't visited at all.\n\t\t\t\tp.discardScopesUpTo(scopeIndex)\n\t\t\t\treturn stmt\n\t\t\t}\n\t\t}\n\n\t\t// Forbid decorators on anything other than a class statement\n\t\tp.log.AddError(&p.tracker, logger.Range{Loc: loc, Len: 1}, \"Decorators are not valid here\")\n\t\tstmt.Data = js_ast.STypeScriptShared\n\t\tp.discardScopesUpTo(scopeIndex)\n\t\treturn stmt\n\n\tcase js_lexer.TClass:\n\t\tif opts.lexicalDecl != lexicalDeclAllowAll {\n\t\t\tp.forbidLexicalDecl(loc)\n\t\t}\n\t\treturn p.parseClassStmt(loc, opts)\n\n\tcase js_lexer.TVar:\n\t\tp.lexer.Next()\n\t\tdecls := p.parseAndDeclareDecls(ast.SymbolHoisted, opts)\n\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SLocal{\n\t\t\tKind:     js_ast.LocalVar,\n\t\t\tDecls:    decls,\n\t\t\tIsExport: opts.isExport,\n\t\t}}\n\n\tcase js_lexer.TConst:\n\t\tif opts.lexicalDecl != lexicalDeclAllowAll {\n\t\t\tp.forbidLexicalDecl(loc)\n\t\t}\n\t\tp.markSyntaxFeature(compat.ConstAndLet, p.lexer.Range())\n\t\tp.lexer.Next()\n\n\t\tif p.options.ts.Parse && p.lexer.Token == js_lexer.TEnum {\n\t\t\treturn p.parseTypeScriptEnumStmt(loc, opts)\n\t\t}\n\n\t\tdecls := p.parseAndDeclareDecls(ast.SymbolConst, opts)\n\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\tif !opts.isTypeScriptDeclare {\n\t\t\tp.requireInitializers(js_ast.LocalConst, decls)\n\t\t}\n\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SLocal{\n\t\t\tKind:     js_ast.LocalConst,\n\t\t\tDecls:    decls,\n\t\t\tIsExport: opts.isExport,\n\t\t}}\n\n\tcase js_lexer.TIf:\n\t\tp.lexer.Next()\n\t\tp.lexer.Expect(js_lexer.TOpenParen)\n\t\ttest := p.parseExpr(js_ast.LLowest)\n\t\tp.lexer.Expect(js_lexer.TCloseParen)\n\t\tisSingleLineYes := !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace\n\t\tyes := p.parseStmt(parseStmtOpts{lexicalDecl: lexicalDeclAllowFnInsideIf})\n\t\tvar noOrNil js_ast.Stmt\n\t\tvar isSingleLineNo bool\n\t\tif p.lexer.Token == js_lexer.TElse {\n\t\t\tp.lexer.Next()\n\t\t\tisSingleLineNo = !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace\n\t\t\tnoOrNil = p.parseStmt(parseStmtOpts{lexicalDecl: lexicalDeclAllowFnInsideIf})\n\t\t}\n\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SIf{Test: test, Yes: yes, NoOrNil: noOrNil, IsSingleLineYes: isSingleLineYes, IsSingleLineNo: isSingleLineNo}}\n\n\tcase js_lexer.TDo:\n\t\tp.lexer.Next()\n\t\tbody := p.parseStmt(parseStmtOpts{})\n\t\tp.lexer.Expect(js_lexer.TWhile)\n\t\tp.lexer.Expect(js_lexer.TOpenParen)\n\t\ttest := p.parseExpr(js_ast.LLowest)\n\t\tp.lexer.Expect(js_lexer.TCloseParen)\n\n\t\t// This is a weird corner case where automatic semicolon insertion applies\n\t\t// even without a newline present\n\t\tif p.lexer.Token == js_lexer.TSemicolon {\n\t\t\tp.lexer.Next()\n\t\t}\n\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SDoWhile{Body: body, Test: test}}\n\n\tcase js_lexer.TWhile:\n\t\tp.lexer.Next()\n\t\tp.lexer.Expect(js_lexer.TOpenParen)\n\t\ttest := p.parseExpr(js_ast.LLowest)\n\t\tp.lexer.Expect(js_lexer.TCloseParen)\n\t\tisSingleLineBody := !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace\n\t\tbody := p.parseStmt(parseStmtOpts{})\n\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SWhile{Test: test, Body: body, IsSingleLineBody: isSingleLineBody}}\n\n\tcase js_lexer.TWith:\n\t\tp.lexer.Next()\n\t\tp.lexer.Expect(js_lexer.TOpenParen)\n\t\ttest := p.parseExpr(js_ast.LLowest)\n\t\tbodyLoc := p.lexer.Loc()\n\t\tp.lexer.Expect(js_lexer.TCloseParen)\n\n\t\t// Push a scope so we make sure to prevent any bare identifiers referenced\n\t\t// within the body from being renamed. Renaming them might change the\n\t\t// semantics of the code.\n\t\tp.pushScopeForParsePass(js_ast.ScopeWith, bodyLoc)\n\t\tisSingleLineBody := !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace\n\t\tbody := p.parseStmt(parseStmtOpts{})\n\t\tp.popScope()\n\n\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SWith{Value: test, BodyLoc: bodyLoc, Body: body, IsSingleLineBody: isSingleLineBody}}\n\n\tcase js_lexer.TSwitch:\n\t\tp.lexer.Next()\n\t\tp.lexer.Expect(js_lexer.TOpenParen)\n\t\ttest := p.parseExpr(js_ast.LLowest)\n\t\tp.lexer.Expect(js_lexer.TCloseParen)\n\n\t\tbodyLoc := p.lexer.Loc()\n\t\tp.pushScopeForParsePass(js_ast.ScopeBlock, bodyLoc)\n\t\tdefer p.popScope()\n\n\t\tp.lexer.Expect(js_lexer.TOpenBrace)\n\t\tcases := []js_ast.Case{}\n\t\tfoundDefault := false\n\t\tswitchScopeStart := len(p.scopesInOrder)\n\t\tvar caseScopeMap map[*js_ast.Scope]struct{}\n\n\t\tfor p.lexer.Token != js_lexer.TCloseBrace {\n\t\t\tvar value js_ast.Expr\n\t\t\tbody := []js_ast.Stmt{}\n\t\t\tcaseLoc := p.saveExprCommentsHere()\n\t\t\tcaseScopeStart := len(p.scopesInOrder)\n\n\t\t\tif p.lexer.Token == js_lexer.TDefault {\n\t\t\t\tif foundDefault {\n\t\t\t\t\tp.log.AddError(&p.tracker, p.lexer.Range(), \"Multiple default clauses are not allowed\")\n\t\t\t\t\tpanic(js_lexer.LexerPanic{})\n\t\t\t\t}\n\t\t\t\tfoundDefault = true\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.lexer.Expect(js_lexer.TColon)\n\t\t\t} else {\n\t\t\t\tp.lexer.Expect(js_lexer.TCase)\n\t\t\t\tvalue = p.parseExpr(js_ast.LLowest)\n\t\t\t\tp.lexer.Expect(js_lexer.TColon)\n\t\t\t}\n\n\t\t\t// Keep track of any scopes created by case values. This can happen if\n\t\t\t// code uses anonymous functions inside a case value. For example:\n\t\t\t//\n\t\t\t//   switch (x) {\n\t\t\t//     case y.map(z => -z).join(':'):\n\t\t\t//       return y\n\t\t\t//   }\n\t\t\t//\n\t\t\tif caseScopeStart < len(p.scopesInOrder) {\n\t\t\t\tif caseScopeMap == nil {\n\t\t\t\t\tcaseScopeMap = make(map[*js_ast.Scope]struct{})\n\t\t\t\t}\n\t\t\t\tfor {\n\t\t\t\t\tcaseScopeMap[p.scopesInOrder[caseScopeStart].scope] = struct{}{}\n\t\t\t\t\tcaseScopeStart++\n\t\t\t\t\tif caseScopeStart == len(p.scopesInOrder) {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcaseBody:\n\t\t\tfor {\n\t\t\t\tswitch p.lexer.Token {\n\t\t\t\tcase js_lexer.TCloseBrace, js_lexer.TCase, js_lexer.TDefault:\n\t\t\t\t\tbreak caseBody\n\n\t\t\t\tdefault:\n\t\t\t\t\tbody = append(body, p.parseStmt(parseStmtOpts{\n\t\t\t\t\t\tlexicalDecl: lexicalDeclAllowAll,\n\t\t\t\t\t\tisCaseBody:  true,\n\t\t\t\t\t}))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcases = append(cases, js_ast.Case{ValueOrNil: value, Body: body, Loc: caseLoc})\n\t\t}\n\n\t\t// If any case contains values that create a scope, reorder those scopes to\n\t\t// come first before any scopes created by case bodies. This reflects the\n\t\t// order in which we will visit the AST in our second parsing pass. The\n\t\t// second parsing pass visits things in a different order because it uses\n\t\t// case values to determine liveness, and then uses the liveness information\n\t\t// when visiting the case bodies (e.g. avoid \"require()\" calls in dead code).\n\t\t// For example:\n\t\t//\n\t\t//   switch (1) {\n\t\t//     case y(() => 1):\n\t\t//       z = () => 2;\n\t\t//       break;\n\t\t//\n\t\t//     case y(() => 3):\n\t\t//       z = () => 4;\n\t\t//       break;\n\t\t//   }\n\t\t//\n\t\t// This is parsed in the order 1,2,3,4 but visited in the order 1,3,2,4.\n\t\tif len(caseScopeMap) > 0 {\n\t\t\tcaseScopes := make([]scopeOrder, 0, len(caseScopeMap))\n\t\t\tbodyScopes := make([]scopeOrder, 0, len(p.scopesInOrder)-switchScopeStart-len(caseScopeMap))\n\t\t\tfor i := switchScopeStart; i < len(p.scopesInOrder); i++ {\n\t\t\t\tit := p.scopesInOrder[i]\n\t\t\t\tif _, ok := caseScopeMap[it.scope]; ok {\n\t\t\t\t\tcaseScopes = append(caseScopes, it)\n\t\t\t\t} else {\n\t\t\t\t\tbodyScopes = append(bodyScopes, it)\n\t\t\t\t}\n\t\t\t}\n\t\t\tcopy(p.scopesInOrder[switchScopeStart:switchScopeStart+len(caseScopeMap)], caseScopes)\n\t\t\tcopy(p.scopesInOrder[switchScopeStart+len(caseScopeMap):], bodyScopes)\n\t\t}\n\n\t\tcloseBraceLoc := p.lexer.Loc()\n\t\tp.lexer.Expect(js_lexer.TCloseBrace)\n\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SSwitch{\n\t\t\tTest:          test,\n\t\t\tCases:         cases,\n\t\t\tBodyLoc:       bodyLoc,\n\t\t\tCloseBraceLoc: closeBraceLoc,\n\t\t}}\n\n\tcase js_lexer.TTry:\n\t\tp.lexer.Next()\n\t\tblockLoc := p.lexer.Loc()\n\t\tp.lexer.Expect(js_lexer.TOpenBrace)\n\t\tp.pushScopeForParsePass(js_ast.ScopeBlock, loc)\n\t\tbody := p.parseStmtsUpTo(js_lexer.TCloseBrace, parseStmtOpts{})\n\t\tp.popScope()\n\t\tcloseBraceLoc := p.lexer.Loc()\n\t\tp.lexer.Next()\n\n\t\tvar catch *js_ast.Catch = nil\n\t\tvar finally *js_ast.Finally = nil\n\n\t\tif p.lexer.Token == js_lexer.TCatch {\n\t\t\tcatchLoc := p.lexer.Loc()\n\t\t\tp.pushScopeForParsePass(js_ast.ScopeCatchBinding, catchLoc)\n\t\t\tp.lexer.Next()\n\t\t\tvar bindingOrNil js_ast.Binding\n\n\t\t\t// The catch binding is optional, and can be omitted\n\t\t\tif p.lexer.Token == js_lexer.TOpenBrace {\n\t\t\t\tif p.options.unsupportedJSFeatures.Has(compat.OptionalCatchBinding) {\n\t\t\t\t\t// Generate a new symbol for the catch binding for older browsers\n\t\t\t\t\tref := p.newSymbol(ast.SymbolOther, \"e\")\n\t\t\t\t\tp.currentScope.Generated = append(p.currentScope.Generated, ref)\n\t\t\t\t\tbindingOrNil = js_ast.Binding{Loc: p.lexer.Loc(), Data: &js_ast.BIdentifier{Ref: ref}}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tp.lexer.Expect(js_lexer.TOpenParen)\n\t\t\t\tbindingOrNil = p.parseBinding(parseBindingOpts{})\n\n\t\t\t\t// Skip over types\n\t\t\t\tif p.options.ts.Parse && p.lexer.Token == js_lexer.TColon {\n\t\t\t\t\tp.lexer.Expect(js_lexer.TColon)\n\t\t\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\t\t}\n\n\t\t\t\tp.lexer.Expect(js_lexer.TCloseParen)\n\n\t\t\t\t// Bare identifiers are a special case\n\t\t\t\tkind := ast.SymbolOther\n\t\t\t\tif _, ok := bindingOrNil.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\t\tkind = ast.SymbolCatchIdentifier\n\t\t\t\t}\n\t\t\t\tp.declareBinding(kind, bindingOrNil, parseStmtOpts{})\n\t\t\t}\n\n\t\t\tblockLoc := p.lexer.Loc()\n\t\t\tp.lexer.Expect(js_lexer.TOpenBrace)\n\n\t\t\tp.pushScopeForParsePass(js_ast.ScopeBlock, blockLoc)\n\t\t\tstmts := p.parseStmtsUpTo(js_lexer.TCloseBrace, parseStmtOpts{})\n\t\t\tp.popScope()\n\n\t\t\tcloseBraceLoc := p.lexer.Loc()\n\t\t\tp.lexer.Next()\n\t\t\tcatch = &js_ast.Catch{Loc: catchLoc, BindingOrNil: bindingOrNil, BlockLoc: blockLoc, Block: js_ast.SBlock{Stmts: stmts, CloseBraceLoc: closeBraceLoc}}\n\t\t\tp.popScope()\n\t\t}\n\n\t\tif p.lexer.Token == js_lexer.TFinally || catch == nil {\n\t\t\tfinallyLoc := p.lexer.Loc()\n\t\t\tp.pushScopeForParsePass(js_ast.ScopeBlock, finallyLoc)\n\t\t\tp.lexer.Expect(js_lexer.TFinally)\n\t\t\tp.lexer.Expect(js_lexer.TOpenBrace)\n\t\t\tstmts := p.parseStmtsUpTo(js_lexer.TCloseBrace, parseStmtOpts{})\n\t\t\tcloseBraceLoc := p.lexer.Loc()\n\t\t\tp.lexer.Next()\n\t\t\tfinally = &js_ast.Finally{Loc: finallyLoc, Block: js_ast.SBlock{Stmts: stmts, CloseBraceLoc: closeBraceLoc}}\n\t\t\tp.popScope()\n\t\t}\n\n\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.STry{\n\t\t\tBlockLoc: blockLoc,\n\t\t\tBlock:    js_ast.SBlock{Stmts: body, CloseBraceLoc: closeBraceLoc},\n\t\t\tCatch:    catch,\n\t\t\tFinally:  finally,\n\t\t}}\n\n\tcase js_lexer.TFor:\n\t\tp.pushScopeForParsePass(js_ast.ScopeBlock, loc)\n\t\tdefer p.popScope()\n\n\t\tp.lexer.Next()\n\n\t\t// \"for await (let x of y) {}\"\n\t\tvar awaitRange logger.Range\n\t\tif p.lexer.IsContextualKeyword(\"await\") {\n\t\t\tawaitRange = p.lexer.Range()\n\t\t\tif p.fnOrArrowDataParse.await != allowExpr {\n\t\t\t\tp.log.AddError(&p.tracker, awaitRange, \"Cannot use \\\"await\\\" outside an async function\")\n\t\t\t\tawaitRange = logger.Range{}\n\t\t\t} else {\n\t\t\t\tdidGenerateError := false\n\t\t\t\tif p.fnOrArrowDataParse.isTopLevel {\n\t\t\t\t\tp.topLevelAwaitKeyword = awaitRange\n\t\t\t\t}\n\t\t\t\tif !didGenerateError && p.options.unsupportedJSFeatures.Has(compat.AsyncAwait) && p.options.unsupportedJSFeatures.Has(compat.Generator) {\n\t\t\t\t\t// If for-await loops aren't supported, then we only support lowering\n\t\t\t\t\t// if either async/await or generators is supported. Otherwise we\n\t\t\t\t\t// cannot lower for-await loops.\n\t\t\t\t\tp.markSyntaxFeature(compat.ForAwait, awaitRange)\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t}\n\n\t\tp.lexer.Expect(js_lexer.TOpenParen)\n\n\t\tvar initOrNil js_ast.Stmt\n\t\tvar testOrNil js_ast.Expr\n\t\tvar updateOrNil js_ast.Expr\n\n\t\t// \"in\" expressions aren't allowed here\n\t\tp.allowIn = false\n\n\t\tvar badLetRange logger.Range\n\t\tif p.lexer.IsContextualKeyword(\"let\") {\n\t\t\tbadLetRange = p.lexer.Range()\n\t\t}\n\t\tdecls := []js_ast.Decl{}\n\t\tinitLoc := p.lexer.Loc()\n\t\tisVar := false\n\t\tswitch p.lexer.Token {\n\t\tcase js_lexer.TVar:\n\t\t\tisVar = true\n\t\t\tp.lexer.Next()\n\t\t\tdecls = p.parseAndDeclareDecls(ast.SymbolHoisted, parseStmtOpts{})\n\t\t\tinitOrNil = js_ast.Stmt{Loc: initLoc, Data: &js_ast.SLocal{Kind: js_ast.LocalVar, Decls: decls}}\n\n\t\tcase js_lexer.TConst:\n\t\t\tp.markSyntaxFeature(compat.ConstAndLet, p.lexer.Range())\n\t\t\tp.lexer.Next()\n\t\t\tdecls = p.parseAndDeclareDecls(ast.SymbolConst, parseStmtOpts{})\n\t\t\tinitOrNil = js_ast.Stmt{Loc: initLoc, Data: &js_ast.SLocal{Kind: js_ast.LocalConst, Decls: decls}}\n\n\t\tcase js_lexer.TSemicolon:\n\n\t\tdefault:\n\t\t\tvar expr js_ast.Expr\n\t\t\tvar stmt js_ast.Stmt\n\t\t\texpr, stmt, decls = p.parseExprOrLetOrUsingStmt(parseStmtOpts{\n\t\t\t\tlexicalDecl:        lexicalDeclAllowAll,\n\t\t\t\tisForLoopInit:      true,\n\t\t\t\tisForAwaitLoopInit: awaitRange.Len > 0,\n\t\t\t})\n\t\t\tif stmt.Data != nil {\n\t\t\t\tbadLetRange = logger.Range{}\n\t\t\t\tinitOrNil = stmt\n\t\t\t} else {\n\t\t\t\tinitOrNil = js_ast.Stmt{Loc: expr.Loc, Data: &js_ast.SExpr{Value: expr}}\n\t\t\t}\n\t\t}\n\n\t\t// \"in\" expressions are allowed again\n\t\tp.allowIn = true\n\n\t\t// Detect for-of loops\n\t\tif p.lexer.IsContextualKeyword(\"of\") || awaitRange.Len > 0 {\n\t\t\tif badLetRange.Len > 0 {\n\t\t\t\tp.log.AddError(&p.tracker, badLetRange, \"\\\"let\\\" must be wrapped in parentheses to be used as an expression here:\")\n\t\t\t}\n\t\t\tif awaitRange.Len > 0 && !p.lexer.IsContextualKeyword(\"of\") {\n\t\t\t\tif initOrNil.Data != nil {\n\t\t\t\t\tp.lexer.ExpectedString(\"\\\"of\\\"\")\n\t\t\t\t} else {\n\t\t\t\t\tp.lexer.Unexpected()\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.forbidInitializers(decls, \"of\", false)\n\t\t\tp.markSyntaxFeature(compat.ForOf, p.lexer.Range())\n\t\t\tp.lexer.Next()\n\t\t\tvalue := p.parseExpr(js_ast.LComma)\n\t\t\tp.lexer.Expect(js_lexer.TCloseParen)\n\t\t\tisSingleLineBody := !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace\n\t\t\tbody := p.parseStmt(parseStmtOpts{})\n\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SForOf{Await: awaitRange, Init: initOrNil, Value: value, Body: body, IsSingleLineBody: isSingleLineBody}}\n\t\t}\n\n\t\t// Detect for-in loops\n\t\tif p.lexer.Token == js_lexer.TIn {\n\t\t\tp.forbidInitializers(decls, \"in\", isVar)\n\t\t\tif len(decls) == 1 {\n\t\t\t\tif local, ok := initOrNil.Data.(*js_ast.SLocal); ok {\n\t\t\t\t\tif local.Kind == js_ast.LocalUsing {\n\t\t\t\t\t\tp.log.AddError(&p.tracker, js_lexer.RangeOfIdentifier(p.source, initOrNil.Loc), \"\\\"using\\\" declarations are not allowed here\")\n\t\t\t\t\t} else if local.Kind == js_ast.LocalAwaitUsing {\n\t\t\t\t\t\tp.log.AddError(&p.tracker, js_lexer.RangeOfIdentifier(p.source, initOrNil.Loc), \"\\\"await using\\\" declarations are not allowed here\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tvalue := p.parseExpr(js_ast.LLowest)\n\t\t\tp.lexer.Expect(js_lexer.TCloseParen)\n\t\t\tisSingleLineBody := !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace\n\t\t\tbody := p.parseStmt(parseStmtOpts{})\n\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SForIn{Init: initOrNil, Value: value, Body: body, IsSingleLineBody: isSingleLineBody}}\n\t\t}\n\n\t\tp.lexer.Expect(js_lexer.TSemicolon)\n\n\t\t// \"await using\" declarations are only allowed in for-of loops\n\t\tif local, ok := initOrNil.Data.(*js_ast.SLocal); ok && local.Kind == js_ast.LocalAwaitUsing {\n\t\t\tp.log.AddError(&p.tracker, js_lexer.RangeOfIdentifier(p.source, initOrNil.Loc), \"\\\"await using\\\" declarations are not allowed here\")\n\t\t}\n\n\t\t// Only require \"const\" statement initializers when we know we're a normal for loop\n\t\tif local, ok := initOrNil.Data.(*js_ast.SLocal); ok && (local.Kind == js_ast.LocalConst || local.Kind == js_ast.LocalUsing) {\n\t\t\tp.requireInitializers(local.Kind, decls)\n\t\t}\n\n\t\tif p.lexer.Token != js_lexer.TSemicolon {\n\t\t\ttestOrNil = p.parseExpr(js_ast.LLowest)\n\t\t}\n\n\t\tp.lexer.Expect(js_lexer.TSemicolon)\n\n\t\tif p.lexer.Token != js_lexer.TCloseParen {\n\t\t\tupdateOrNil = p.parseExpr(js_ast.LLowest)\n\t\t}\n\n\t\tp.lexer.Expect(js_lexer.TCloseParen)\n\t\tisSingleLineBody := !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace\n\t\tbody := p.parseStmt(parseStmtOpts{})\n\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SFor{\n\t\t\tInitOrNil:        initOrNil,\n\t\t\tTestOrNil:        testOrNil,\n\t\t\tUpdateOrNil:      updateOrNil,\n\t\t\tBody:             body,\n\t\t\tIsSingleLineBody: isSingleLineBody,\n\t\t}}\n\n\tcase js_lexer.TImport:\n\t\tpreviousImportStatementKeyword := p.esmImportStatementKeyword\n\t\tp.esmImportStatementKeyword = p.lexer.Range()\n\t\tp.lexer.Next()\n\t\tstmt := js_ast.SImport{}\n\t\tphase := ast.EvaluationPhase\n\t\twasOriginallyBareImport := false\n\n\t\t// \"export import foo = bar\"\n\t\t// \"import foo = bar\" in a namespace\n\t\tif (opts.isExport || (opts.isNamespaceScope && !opts.isTypeScriptDeclare)) && p.lexer.Token != js_lexer.TIdentifier {\n\t\t\tp.lexer.Expected(js_lexer.TIdentifier)\n\t\t}\n\n\tsyntaxBeforePath:\n\t\tswitch p.lexer.Token {\n\t\tcase js_lexer.TOpenParen, js_lexer.TDot:\n\t\t\t// \"import('path')\"\n\t\t\t// \"import.meta\"\n\t\t\tp.esmImportStatementKeyword = previousImportStatementKeyword // This wasn't an ESM import statement after all\n\t\t\texpr := p.parseSuffix(p.parseImportExpr(loc, js_ast.LLowest), js_ast.LLowest, nil, 0)\n\t\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SExpr{Value: expr}}\n\n\t\tcase js_lexer.TStringLiteral, js_lexer.TNoSubstitutionTemplateLiteral:\n\t\t\t// \"import 'path'\"\n\t\t\tif !opts.isModuleScope && (!opts.isNamespaceScope || !opts.isTypeScriptDeclare) {\n\t\t\t\tp.lexer.Unexpected()\n\t\t\t\treturn js_ast.Stmt{}\n\t\t\t}\n\n\t\t\twasOriginallyBareImport = true\n\n\t\tcase js_lexer.TAsterisk:\n\t\t\t// \"import * as ns from 'path'\"\n\t\t\tif !opts.isModuleScope && (!opts.isNamespaceScope || !opts.isTypeScriptDeclare) {\n\t\t\t\tp.lexer.Unexpected()\n\t\t\t\treturn js_ast.Stmt{}\n\t\t\t}\n\n\t\t\tp.lexer.Next()\n\t\t\tp.lexer.ExpectContextualKeyword(\"as\")\n\t\t\tstmt.NamespaceRef = p.storeNameInRef(p.lexer.Identifier)\n\t\t\tstarLoc := p.lexer.Loc()\n\t\t\tstmt.StarNameLoc = &starLoc\n\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t\tp.lexer.ExpectContextualKeyword(\"from\")\n\n\t\tcase js_lexer.TOpenBrace:\n\t\t\t// \"import {item1, item2} from 'path'\"\n\t\t\tif !opts.isModuleScope && (!opts.isNamespaceScope || !opts.isTypeScriptDeclare) {\n\t\t\t\tp.lexer.Unexpected()\n\t\t\t\treturn js_ast.Stmt{}\n\t\t\t}\n\n\t\t\titems, isSingleLine := p.parseImportClause()\n\t\t\tstmt.Items = &items\n\t\t\tstmt.IsSingleLine = isSingleLine\n\t\t\tp.lexer.ExpectContextualKeyword(\"from\")\n\n\t\tcase js_lexer.TIdentifier:\n\t\t\t// \"import defaultItem from 'path'\"\n\t\t\t// \"import foo = bar\"\n\t\t\tif !opts.isModuleScope && !opts.isNamespaceScope {\n\t\t\t\tp.lexer.Unexpected()\n\t\t\t\treturn js_ast.Stmt{}\n\t\t\t}\n\n\t\t\tdefaultName := p.lexer.Identifier\n\t\t\tdefaultLoc := p.lexer.Loc()\n\t\t\tisDeferName := p.lexer.Raw() == \"defer\"\n\t\t\tisSourceName := p.lexer.Raw() == \"source\"\n\t\t\tp.lexer.Next()\n\n\t\t\tif isDeferName && p.lexer.Token == js_lexer.TAsterisk {\n\t\t\t\t// \"import defer * as foo from 'bar';\"\n\t\t\t\tp.markSyntaxFeature(compat.ImportDefer, js_lexer.RangeOfIdentifier(p.source, defaultLoc))\n\t\t\t\tphase = ast.DeferPhase\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.lexer.ExpectContextualKeyword(\"as\")\n\t\t\t\tstmt.NamespaceRef = p.storeNameInRef(p.lexer.Identifier)\n\t\t\t\tstarLoc := p.lexer.Loc()\n\t\t\t\tstmt.StarNameLoc = &starLoc\n\t\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t\t\tp.lexer.ExpectContextualKeyword(\"from\")\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif isSourceName && p.lexer.Token == js_lexer.TIdentifier {\n\t\t\t\tif p.lexer.Raw() == \"from\" {\n\t\t\t\t\tnameSubstring := p.lexer.Identifier\n\t\t\t\t\tnameLoc := p.lexer.Loc()\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tif p.lexer.IsContextualKeyword(\"from\") {\n\t\t\t\t\t\t// \"import source from from 'foo';\"\n\t\t\t\t\t\tp.markSyntaxFeature(compat.ImportSource, js_lexer.RangeOfIdentifier(p.source, defaultLoc))\n\t\t\t\t\t\tphase = ast.SourcePhase\n\t\t\t\t\t\tstmt.DefaultName = &ast.LocRef{Loc: nameLoc, Ref: p.storeNameInRef(nameSubstring)}\n\t\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// \"import source from 'foo';\"\n\t\t\t\t\t\tstmt.DefaultName = &ast.LocRef{Loc: defaultLoc, Ref: p.storeNameInRef(defaultName)}\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// \"import source foo from 'bar';\"\n\t\t\t\tp.markSyntaxFeature(compat.ImportSource, js_lexer.RangeOfIdentifier(p.source, defaultLoc))\n\t\t\t\tphase = ast.SourcePhase\n\t\t\t\tstmt.DefaultName = &ast.LocRef{Loc: p.lexer.Loc(), Ref: p.storeNameInRef(p.lexer.Identifier)}\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.lexer.ExpectContextualKeyword(\"from\")\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tstmt.DefaultName = &ast.LocRef{Loc: defaultLoc, Ref: p.storeNameInRef(defaultName)}\n\n\t\t\tif p.options.ts.Parse {\n\t\t\t\t// Skip over type-only imports\n\t\t\t\tif defaultName.String == \"type\" {\n\t\t\t\t\tswitch p.lexer.Token {\n\t\t\t\t\tcase js_lexer.TIdentifier:\n\t\t\t\t\t\tnameSubstring := p.lexer.Identifier\n\t\t\t\t\t\tnameLoc := p.lexer.Loc()\n\t\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\t\tif p.lexer.Token == js_lexer.TEquals {\n\t\t\t\t\t\t\t// \"import type foo = require('bar');\"\n\t\t\t\t\t\t\t// \"import type foo = bar.baz;\"\n\t\t\t\t\t\t\topts.isTypeScriptDeclare = true\n\t\t\t\t\t\t\treturn p.parseTypeScriptImportEqualsStmt(loc, opts, nameLoc, nameSubstring.String)\n\t\t\t\t\t\t} else if p.lexer.Token == js_lexer.TStringLiteral && nameSubstring.String == \"from\" {\n\t\t\t\t\t\t\t// \"import type from 'bar';\"\n\t\t\t\t\t\t\tbreak syntaxBeforePath\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// \"import type foo from 'bar';\"\n\t\t\t\t\t\t\tp.lexer.ExpectContextualKeyword(\"from\")\n\t\t\t\t\t\t\tp.parsePath()\n\t\t\t\t\t\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\t\t\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptShared}\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase js_lexer.TAsterisk:\n\t\t\t\t\t\t// \"import type * as foo from 'bar';\"\n\t\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\t\tp.lexer.ExpectContextualKeyword(\"as\")\n\t\t\t\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t\t\t\t\tp.lexer.ExpectContextualKeyword(\"from\")\n\t\t\t\t\t\tp.parsePath()\n\t\t\t\t\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\t\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptShared}\n\n\t\t\t\t\tcase js_lexer.TOpenBrace:\n\t\t\t\t\t\t// \"import type {foo} from 'bar';\"\n\t\t\t\t\t\tp.parseImportClause()\n\t\t\t\t\t\tp.lexer.ExpectContextualKeyword(\"from\")\n\t\t\t\t\t\tp.parsePath()\n\t\t\t\t\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\t\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptShared}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Parse TypeScript import assignment statements\n\t\t\t\tif p.lexer.Token == js_lexer.TEquals || opts.isExport || (opts.isNamespaceScope && !opts.isTypeScriptDeclare) {\n\t\t\t\t\tp.esmImportStatementKeyword = previousImportStatementKeyword // This wasn't an ESM import statement after all\n\t\t\t\t\treturn p.parseTypeScriptImportEqualsStmt(loc, opts, stmt.DefaultName.Loc, defaultName.String)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif p.lexer.Token == js_lexer.TComma {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tswitch p.lexer.Token {\n\t\t\t\tcase js_lexer.TAsterisk:\n\t\t\t\t\t// \"import defaultItem, * as ns from 'path'\"\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tp.lexer.ExpectContextualKeyword(\"as\")\n\t\t\t\t\tstmt.NamespaceRef = p.storeNameInRef(p.lexer.Identifier)\n\t\t\t\t\tstarLoc := p.lexer.Loc()\n\t\t\t\t\tstmt.StarNameLoc = &starLoc\n\t\t\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\n\t\t\t\tcase js_lexer.TOpenBrace:\n\t\t\t\t\t// \"import defaultItem, {item1, item2} from 'path'\"\n\t\t\t\t\titems, isSingleLine := p.parseImportClause()\n\t\t\t\t\tstmt.Items = &items\n\t\t\t\t\tstmt.IsSingleLine = isSingleLine\n\n\t\t\t\tdefault:\n\t\t\t\t\tp.lexer.Unexpected()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.lexer.ExpectContextualKeyword(\"from\")\n\n\t\tdefault:\n\t\t\tp.lexer.Unexpected()\n\t\t\treturn js_ast.Stmt{}\n\t\t}\n\n\t\tpathLoc, pathText, assertOrWith, flags := p.parsePath()\n\t\tp.lexer.ExpectOrInsertSemicolon()\n\n\t\t// If TypeScript's \"preserveValueImports\": true setting is active, TypeScript's\n\t\t// \"importsNotUsedAsValues\": \"preserve\" setting is NOT active, and the import\n\t\t// clause is present and empty (or is non-empty but filled with type-only\n\t\t// items), then the import statement should still be removed entirely to match\n\t\t// the behavior of the TypeScript compiler:\n\t\t//\n\t\t//   // Keep these\n\t\t//   import 'x'\n\t\t//   import { y } from 'x'\n\t\t//   import { y, type z } from 'x'\n\t\t//\n\t\t//   // Remove these\n\t\t//   import {} from 'x'\n\t\t//   import { type y } from 'x'\n\t\t//\n\t\t//   // Remove the items from these\n\t\t//   import d, {} from 'x'\n\t\t//   import d, { type y } from 'x'\n\t\t//\n\t\tif p.options.ts.Parse && p.options.ts.Config.UnusedImportFlags() == config.TSUnusedImport_KeepValues && stmt.Items != nil && len(*stmt.Items) == 0 {\n\t\t\tif stmt.DefaultName == nil {\n\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptShared}\n\t\t\t}\n\t\t\tstmt.Items = nil\n\t\t}\n\n\t\tif wasOriginallyBareImport {\n\t\t\tflags |= ast.WasOriginallyBareImport\n\t\t}\n\t\tstmt.ImportRecordIndex = p.addImportRecord(ast.ImportStmt, phase, pathLoc, pathText, assertOrWith, flags)\n\n\t\tif stmt.StarNameLoc != nil {\n\t\t\tname := p.loadNameFromRef(stmt.NamespaceRef)\n\t\t\tstmt.NamespaceRef = p.declareSymbol(ast.SymbolImport, *stmt.StarNameLoc, name)\n\t\t} else {\n\t\t\t// Generate a symbol for the namespace\n\t\t\tname := \"import_\" + js_ast.GenerateNonUniqueNameFromPath(pathText)\n\t\t\tstmt.NamespaceRef = p.newSymbol(ast.SymbolOther, name)\n\t\t\tp.currentScope.Generated = append(p.currentScope.Generated, stmt.NamespaceRef)\n\t\t}\n\t\titemRefs := make(map[string]ast.LocRef)\n\n\t\t// Link the default item to the namespace\n\t\tif stmt.DefaultName != nil {\n\t\t\tname := p.loadNameFromRef(stmt.DefaultName.Ref)\n\t\t\tref := p.declareSymbol(ast.SymbolImport, stmt.DefaultName.Loc, name)\n\t\t\tp.isImportItem[ref] = true\n\t\t\tstmt.DefaultName.Ref = ref\n\t\t}\n\n\t\t// Link each import item to the namespace\n\t\tif stmt.Items != nil {\n\t\t\tfor i, item := range *stmt.Items {\n\t\t\t\tname := p.loadNameFromRef(item.Name.Ref)\n\t\t\t\tref := p.declareSymbol(ast.SymbolImport, item.Name.Loc, name)\n\t\t\t\tp.checkForUnrepresentableIdentifier(item.AliasLoc, item.Alias)\n\t\t\t\tp.isImportItem[ref] = true\n\t\t\t\t(*stmt.Items)[i].Name.Ref = ref\n\t\t\t\titemRefs[item.Alias] = ast.LocRef{Loc: item.Name.Loc, Ref: ref}\n\t\t\t}\n\t\t}\n\n\t\t// Track the items for this namespace\n\t\tp.importItemsForNamespace[stmt.NamespaceRef] = namespaceImportItems{\n\t\t\tentries:           itemRefs,\n\t\t\timportRecordIndex: stmt.ImportRecordIndex,\n\t\t}\n\n\t\t// Import statements anywhere in the file disable top-level const\n\t\t// local prefix because import cycles can be used to trigger TDZ\n\t\tp.currentScope.IsAfterConstLocalPrefix = true\n\t\treturn js_ast.Stmt{Loc: loc, Data: &stmt}\n\n\tcase js_lexer.TBreak:\n\t\tp.lexer.Next()\n\t\tname := p.parseLabelName()\n\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SBreak{Label: name}}\n\n\tcase js_lexer.TContinue:\n\t\tp.lexer.Next()\n\t\tname := p.parseLabelName()\n\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SContinue{Label: name}}\n\n\tcase js_lexer.TReturn:\n\t\tif p.fnOrArrowDataParse.isReturnDisallowed {\n\t\t\tp.log.AddError(&p.tracker, p.lexer.Range(), \"A return statement cannot be used here:\")\n\t\t}\n\t\tp.lexer.Next()\n\t\tvar value js_ast.Expr\n\t\tif p.lexer.Token != js_lexer.TSemicolon &&\n\t\t\t!p.lexer.HasNewlineBefore &&\n\t\t\tp.lexer.Token != js_lexer.TCloseBrace &&\n\t\t\tp.lexer.Token != js_lexer.TEndOfFile {\n\t\t\tvalue = p.parseExpr(js_ast.LLowest)\n\t\t}\n\t\tp.latestReturnHadSemicolon = p.lexer.Token == js_lexer.TSemicolon\n\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SReturn{ValueOrNil: value}}\n\n\tcase js_lexer.TThrow:\n\t\tp.lexer.Next()\n\t\tif p.lexer.HasNewlineBefore {\n\t\t\tendLoc := logger.Loc{Start: loc.Start + 5}\n\t\t\tp.log.AddError(&p.tracker, logger.Range{Loc: endLoc},\n\t\t\t\t\"Unexpected newline after \\\"throw\\\"\")\n\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SThrow{Value: js_ast.Expr{Loc: endLoc, Data: js_ast.ENullShared}}}\n\t\t}\n\t\texpr := p.parseExpr(js_ast.LLowest)\n\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SThrow{Value: expr}}\n\n\tcase js_lexer.TDebugger:\n\t\tp.lexer.Next()\n\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.SDebuggerShared}\n\n\tcase js_lexer.TOpenBrace:\n\t\tp.pushScopeForParsePass(js_ast.ScopeBlock, loc)\n\t\tdefer p.popScope()\n\n\t\tp.lexer.Next()\n\t\tstmts := p.parseStmtsUpTo(js_lexer.TCloseBrace, parseStmtOpts{})\n\t\tcloseBraceLoc := p.lexer.Loc()\n\t\tp.lexer.Next()\n\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SBlock{Stmts: stmts, CloseBraceLoc: closeBraceLoc}}\n\n\tdefault:\n\t\tisIdentifier := p.lexer.Token == js_lexer.TIdentifier\n\t\tnameRange := p.lexer.Range()\n\t\tname := p.lexer.Identifier.String\n\n\t\t// Parse either an async function, an async expression, or a normal expression\n\t\tvar expr js_ast.Expr\n\t\tif isIdentifier && p.lexer.Raw() == \"async\" {\n\t\t\tp.lexer.Next()\n\t\t\tif p.lexer.Token == js_lexer.TFunction && !p.lexer.HasNewlineBefore {\n\t\t\t\tp.lexer.Next()\n\t\t\t\treturn p.parseFnStmt(nameRange.Loc, opts, true /* isAsync */, nameRange)\n\t\t\t}\n\t\t\texpr = p.parseSuffix(p.parseAsyncPrefixExpr(nameRange, js_ast.LLowest, 0), js_ast.LLowest, nil, 0)\n\t\t} else {\n\t\t\tvar stmt js_ast.Stmt\n\t\t\texpr, stmt, _ = p.parseExprOrLetOrUsingStmt(opts)\n\t\t\tif stmt.Data != nil {\n\t\t\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\t\t\treturn stmt\n\t\t\t}\n\t\t}\n\n\t\tif isIdentifier {\n\t\t\tif ident, ok := expr.Data.(*js_ast.EIdentifier); ok {\n\t\t\t\tif p.lexer.Token == js_lexer.TColon && opts.deferredDecorators == nil {\n\t\t\t\t\tp.pushScopeForParsePass(js_ast.ScopeLabel, loc)\n\t\t\t\t\tdefer p.popScope()\n\n\t\t\t\t\t// Parse a labeled statement\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tname := ast.LocRef{Loc: expr.Loc, Ref: ident.Ref}\n\t\t\t\t\tnestedOpts := parseStmtOpts{}\n\t\t\t\t\tif opts.lexicalDecl == lexicalDeclAllowAll || opts.lexicalDecl == lexicalDeclAllowFnInsideLabel {\n\t\t\t\t\t\tnestedOpts.lexicalDecl = lexicalDeclAllowFnInsideLabel\n\t\t\t\t\t}\n\t\t\t\t\tisSingleLineStmt := !p.lexer.HasNewlineBefore && p.lexer.Token != js_lexer.TOpenBrace\n\t\t\t\t\tstmt := p.parseStmt(nestedOpts)\n\t\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SLabel{Name: name, Stmt: stmt, IsSingleLineStmt: isSingleLineStmt}}\n\t\t\t\t}\n\n\t\t\t\tif p.options.ts.Parse {\n\t\t\t\t\tswitch name {\n\t\t\t\t\tcase \"type\":\n\t\t\t\t\t\tif !p.lexer.HasNewlineBefore && p.lexer.Token == js_lexer.TIdentifier {\n\t\t\t\t\t\t\t// \"type Foo = any\"\n\t\t\t\t\t\t\tp.skipTypeScriptTypeStmt(parseStmtOpts{isModuleScope: opts.isModuleScope})\n\t\t\t\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptShared}\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase \"namespace\", \"module\":\n\t\t\t\t\t\t// \"namespace Foo {}\"\n\t\t\t\t\t\t// \"module Foo {}\"\n\t\t\t\t\t\t// \"declare module 'fs' {}\"\n\t\t\t\t\t\t// \"declare module 'fs';\"\n\t\t\t\t\t\tif !p.lexer.HasNewlineBefore && (opts.isModuleScope || opts.isNamespaceScope) && (p.lexer.Token == js_lexer.TIdentifier ||\n\t\t\t\t\t\t\t(p.lexer.Token == js_lexer.TStringLiteral && opts.isTypeScriptDeclare)) {\n\t\t\t\t\t\t\treturn p.parseTypeScriptNamespaceStmt(loc, opts)\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase \"interface\":\n\t\t\t\t\t\t// \"interface Foo {}\"\n\t\t\t\t\t\t// \"export default interface Foo {}\"\n\t\t\t\t\t\t// \"export default interface \\n Foo {}\"\n\t\t\t\t\t\tif !p.lexer.HasNewlineBefore || opts.isExportDefault {\n\t\t\t\t\t\t\tp.skipTypeScriptInterfaceStmt(parseStmtOpts{isModuleScope: opts.isModuleScope})\n\t\t\t\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptShared}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// \"interface \\n Foo {}\"\n\t\t\t\t\t\t// \"export interface \\n Foo {}\"\n\t\t\t\t\t\tif opts.isExport {\n\t\t\t\t\t\t\tp.log.AddError(&p.tracker, nameRange, \"Unexpected \\\"interface\\\"\")\n\t\t\t\t\t\t\tpanic(js_lexer.LexerPanic{})\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase \"abstract\":\n\t\t\t\t\t\tif !p.lexer.HasNewlineBefore && p.lexer.Token == js_lexer.TClass {\n\t\t\t\t\t\t\treturn p.parseClassStmt(loc, opts)\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase \"global\":\n\t\t\t\t\t\t// \"declare module 'fs' { global { namespace NodeJS {} } }\"\n\t\t\t\t\t\tif opts.isNamespaceScope && opts.isTypeScriptDeclare && p.lexer.Token == js_lexer.TOpenBrace {\n\t\t\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\t\t\tp.parseStmtsUpTo(js_lexer.TCloseBrace, opts)\n\t\t\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptShared}\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase \"declare\":\n\t\t\t\t\t\tif !p.lexer.HasNewlineBefore {\n\t\t\t\t\t\t\topts.lexicalDecl = lexicalDeclAllowAll\n\t\t\t\t\t\t\topts.isTypeScriptDeclare = true\n\n\t\t\t\t\t\t\t// \"declare global { ... }\"\n\t\t\t\t\t\t\tif p.lexer.IsContextualKeyword(\"global\") {\n\t\t\t\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\t\t\t\tp.lexer.Expect(js_lexer.TOpenBrace)\n\t\t\t\t\t\t\t\tp.parseStmtsUpTo(js_lexer.TCloseBrace, opts)\n\t\t\t\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptShared}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// \"declare const x: any\"\n\t\t\t\t\t\t\tscopeIndex := len(p.scopesInOrder)\n\t\t\t\t\t\t\toldLexer := p.lexer\n\t\t\t\t\t\t\tstmt := p.parseStmt(opts)\n\t\t\t\t\t\t\ttypeDeclarationData := js_ast.STypeScriptShared\n\t\t\t\t\t\t\tswitch s := stmt.Data.(type) {\n\t\t\t\t\t\t\tcase *js_ast.SEmpty:\n\t\t\t\t\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SExpr{Value: expr}}\n\n\t\t\t\t\t\t\tcase *js_ast.STypeScript:\n\t\t\t\t\t\t\t\t// Type declarations are expected. Propagate the \"declare class\"\n\t\t\t\t\t\t\t\t// status in case our caller is a decorator that needs to know\n\t\t\t\t\t\t\t\t// this was a \"declare class\" statement.\n\t\t\t\t\t\t\t\ttypeDeclarationData = s\n\n\t\t\t\t\t\t\tcase *js_ast.SLocal:\n\t\t\t\t\t\t\t\t// This is also a type declaration (but doesn't use \"STypeScript\"\n\t\t\t\t\t\t\t\t// because we need to be able to handle namespace exports below)\n\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t// Anything that we don't expect is a syntax error. For example,\n\t\t\t\t\t\t\t\t// we consider this a syntax error:\n\t\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t\t//   declare let declare: any, foo: any\n\t\t\t\t\t\t\t\t//   declare foo\n\t\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t\t// Strangely TypeScript allows this code starting with version\n\t\t\t\t\t\t\t\t// 4.4, but I assume this is a bug. This bug was reported here:\n\t\t\t\t\t\t\t\t// https://github.com/microsoft/TypeScript/issues/54602\n\t\t\t\t\t\t\t\tp.lexer = oldLexer\n\t\t\t\t\t\t\t\tp.lexer.Unexpected()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tp.discardScopesUpTo(scopeIndex)\n\n\t\t\t\t\t\t\t// Unlike almost all uses of \"declare\", statements that use\n\t\t\t\t\t\t\t// \"export declare\" with \"var/let/const\" inside a namespace affect\n\t\t\t\t\t\t\t// code generation. They cause any declared bindings to be\n\t\t\t\t\t\t\t// considered exports of the namespace. Identifier references to\n\t\t\t\t\t\t\t// those names must be converted into property accesses off the\n\t\t\t\t\t\t\t// namespace object:\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t//   namespace ns {\n\t\t\t\t\t\t\t//     export declare const x\n\t\t\t\t\t\t\t//     export function y() { return x }\n\t\t\t\t\t\t\t//   }\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t//   (ns as any).x = 1\n\t\t\t\t\t\t\t//   console.log(ns.y())\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// In this example, \"return x\" must be replaced with \"return ns.x\".\n\t\t\t\t\t\t\t// This is handled by replacing each \"export declare\" statement\n\t\t\t\t\t\t\t// inside a namespace with an \"export var\" statement containing all\n\t\t\t\t\t\t\t// of the declared bindings. That \"export var\" statement will later\n\t\t\t\t\t\t\t// cause identifiers to be transformed into property accesses.\n\t\t\t\t\t\t\tif opts.isNamespaceScope && opts.isExport {\n\t\t\t\t\t\t\t\tvar decls []js_ast.Decl\n\t\t\t\t\t\t\t\tif s, ok := stmt.Data.(*js_ast.SLocal); ok {\n\t\t\t\t\t\t\t\t\tjs_ast.ForEachIdentifierBindingInDecls(s.Decls, func(loc logger.Loc, b *js_ast.BIdentifier) {\n\t\t\t\t\t\t\t\t\t\tdecls = append(decls, js_ast.Decl{Binding: js_ast.Binding{Loc: loc, Data: b}})\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif len(decls) > 0 {\n\t\t\t\t\t\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SLocal{\n\t\t\t\t\t\t\t\t\t\tKind:     js_ast.LocalVar,\n\t\t\t\t\t\t\t\t\t\tIsExport: true,\n\t\t\t\t\t\t\t\t\t\tDecls:    decls,\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn js_ast.Stmt{Loc: loc, Data: typeDeclarationData}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SExpr{Value: expr}}\n\t}\n}\n\nfunc (p *parser) addImportRecord(\n\tkind ast.ImportKind,\n\tphase ast.ImportPhase,\n\tpathRange logger.Range,\n\ttext string,\n\tassertOrWith *ast.ImportAssertOrWith,\n\tflags ast.ImportRecordFlags,\n) uint32 {\n\tindex := uint32(len(p.importRecords))\n\tp.importRecords = append(p.importRecords, ast.ImportRecord{\n\t\tKind:         kind,\n\t\tRange:        pathRange,\n\t\tPath:         logger.Path{Text: text},\n\t\tAssertOrWith: assertOrWith,\n\t\tPhase:        phase,\n\t\tFlags:        flags,\n\t})\n\treturn index\n}\n\nfunc (p *parser) parseFnBody(data fnOrArrowDataParse) js_ast.FnBody {\n\toldFnOrArrowData := p.fnOrArrowDataParse\n\toldAllowIn := p.allowIn\n\tp.fnOrArrowDataParse = data\n\tp.allowIn = true\n\n\tloc := p.lexer.Loc()\n\tp.pushScopeForParsePass(js_ast.ScopeFunctionBody, loc)\n\tdefer p.popScope()\n\n\tp.lexer.Expect(js_lexer.TOpenBrace)\n\tstmts := p.parseStmtsUpTo(js_lexer.TCloseBrace, parseStmtOpts{\n\t\tallowDirectivePrologue: true,\n\t})\n\tcloseBraceLoc := p.lexer.Loc()\n\tp.lexer.Next()\n\n\tp.allowIn = oldAllowIn\n\tp.fnOrArrowDataParse = oldFnOrArrowData\n\treturn js_ast.FnBody{Loc: loc, Block: js_ast.SBlock{Stmts: stmts, CloseBraceLoc: closeBraceLoc}}\n}\n\nfunc (p *parser) forbidLexicalDecl(loc logger.Loc) {\n\tr := js_lexer.RangeOfIdentifier(p.source, loc)\n\tp.log.AddErrorWithNotes(&p.tracker, r, \"Cannot use a declaration in a single-statement context\",\n\t\t[]logger.MsgData{{Text: \"Wrap this declaration in a block statement to use it here.\"}})\n}\n\nfunc (p *parser) forbidUsingInSwitch(loc logger.Loc) {\n\tr := js_lexer.RangeOfIdentifier(p.source, loc)\n\tp.log.AddErrorWithNotes(&p.tracker, r, \"Cannot use a \\\"using\\\" declaration directly inside a switch case\",\n\t\t[]logger.MsgData{{Text: \"Wrap this declaration in a block statement to use it here.\"}})\n}\n\nfunc (p *parser) parseStmtsUpTo(end js_lexer.T, opts parseStmtOpts) []js_ast.Stmt {\n\tstmts := []js_ast.Stmt{}\n\treturnWithoutSemicolonStart := int32(-1)\n\topts.lexicalDecl = lexicalDeclAllowAll\n\tisDirectivePrologue := opts.allowDirectivePrologue\n\n\tfor {\n\t\t// Preserve some statement-level comments\n\t\tcomments := p.lexer.LegalCommentsBeforeToken\n\t\tif len(comments) > 0 {\n\t\t\tfor _, comment := range comments {\n\t\t\t\tstmts = append(stmts, js_ast.Stmt{\n\t\t\t\t\tLoc: comment.Loc,\n\t\t\t\t\tData: &js_ast.SComment{\n\t\t\t\t\t\tText:           p.source.CommentTextWithoutIndent(comment),\n\t\t\t\t\t\tIsLegalComment: true,\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tif p.lexer.Token == end {\n\t\t\tbreak\n\t\t}\n\n\t\tstmt := p.parseStmt(opts)\n\n\t\t// Skip TypeScript types entirely\n\t\tif p.options.ts.Parse {\n\t\t\tif _, ok := stmt.Data.(*js_ast.STypeScript); ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Parse one or more directives at the beginning\n\t\tif isDirectivePrologue {\n\t\t\tisDirectivePrologue = false\n\t\t\tif expr, ok := stmt.Data.(*js_ast.SExpr); ok {\n\t\t\t\tif str, ok := expr.Value.Data.(*js_ast.EString); ok && !str.PreferTemplate {\n\t\t\t\t\tstmt.Data = &js_ast.SDirective{Value: str.Value, LegacyOctalLoc: str.LegacyOctalLoc}\n\t\t\t\t\tisDirectivePrologue = true\n\n\t\t\t\t\tif helpers.UTF16EqualsString(str.Value, \"use strict\") {\n\t\t\t\t\t\t// Track \"use strict\" directives\n\t\t\t\t\t\tp.currentScope.StrictMode = js_ast.ExplicitStrictMode\n\t\t\t\t\t\tp.currentScope.UseStrictLoc = expr.Value.Loc\n\n\t\t\t\t\t\t// Inside a function, strict mode actually propagates from the child\n\t\t\t\t\t\t// scope to the parent scope:\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//   // This is a syntax error\n\t\t\t\t\t\t//   function fn(arguments) {\n\t\t\t\t\t\t//     \"use strict\";\n\t\t\t\t\t\t//   }\n\t\t\t\t\t\t//\n\t\t\t\t\t\tif p.currentScope.Kind == js_ast.ScopeFunctionBody &&\n\t\t\t\t\t\t\tp.currentScope.Parent.Kind == js_ast.ScopeFunctionArgs &&\n\t\t\t\t\t\t\tp.currentScope.Parent.StrictMode == js_ast.SloppyMode {\n\t\t\t\t\t\t\tp.currentScope.Parent.StrictMode = js_ast.ExplicitStrictMode\n\t\t\t\t\t\t\tp.currentScope.Parent.UseStrictLoc = expr.Value.Loc\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if helpers.UTF16EqualsString(str.Value, \"use asm\") {\n\t\t\t\t\t\t// Deliberately remove \"use asm\" directives. The asm.js subset of\n\t\t\t\t\t\t// JavaScript has complicated validation rules that are triggered\n\t\t\t\t\t\t// by this directive. This parser is not designed with asm.js in\n\t\t\t\t\t\t// mind and round-tripping asm.js code through esbuild will very\n\t\t\t\t\t\t// likely cause it to no longer validate as asm.js. When this\n\t\t\t\t\t\t// happens, V8 prints a warning and people don't like seeing the\n\t\t\t\t\t\t// warning.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// We deliberately do not attempt to preserve the validity of\n\t\t\t\t\t\t// asm.js code because it's a complicated legacy format and it's\n\t\t\t\t\t\t// obsolete now that WebAssembly exists. By removing this directive\n\t\t\t\t\t\t// it will just become normal JavaScript, which will work fine and\n\t\t\t\t\t\t// won't generate a warning (but will run slower). We don't generate\n\t\t\t\t\t\t// a warning ourselves in this case because there isn't necessarily\n\t\t\t\t\t\t// anything easy and actionable that the user can do to fix this.\n\t\t\t\t\t\tstmt.Data = &js_ast.SEmpty{}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstmts = append(stmts, stmt)\n\n\t\t// Warn about ASI and return statements. Here's an example of code with\n\t\t// this problem: https://github.com/rollup/rollup/issues/3729\n\t\tif !p.suppressWarningsAboutWeirdCode {\n\t\t\tif s, ok := stmt.Data.(*js_ast.SReturn); ok && s.ValueOrNil.Data == nil && !p.latestReturnHadSemicolon {\n\t\t\t\treturnWithoutSemicolonStart = stmt.Loc.Start\n\t\t\t} else {\n\t\t\t\tif returnWithoutSemicolonStart != -1 {\n\t\t\t\t\tif _, ok := stmt.Data.(*js_ast.SExpr); ok {\n\t\t\t\t\t\tp.log.AddID(logger.MsgID_JS_SemicolonAfterReturn, logger.Warning, &p.tracker, logger.Range{Loc: logger.Loc{Start: returnWithoutSemicolonStart + 6}},\n\t\t\t\t\t\t\t\"The following expression is not returned because of an automatically-inserted semicolon\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturnWithoutSemicolonStart = -1\n\t\t\t}\n\t\t}\n\t}\n\n\treturn stmts\n}\n\ntype generateTempRefArg uint8\n\nconst (\n\ttempRefNeedsDeclare generateTempRefArg = iota\n\ttempRefNoDeclare\n\n\t// This is used when the generated temporary may a) be used inside of a loop\n\t// body and b) may be used inside of a closure. In that case we can't use\n\t// \"var\" for the temporary and we can't declare the temporary at the top of\n\t// the enclosing function. Instead, we need to use \"let\" and we need to\n\t// declare the temporary in the enclosing block (so it's inside of the loop\n\t// body).\n\ttempRefNeedsDeclareMayBeCapturedInsideLoop\n)\n\nfunc (p *parser) generateTempRef(declare generateTempRefArg, optionalName string) ast.Ref {\n\tscope := p.currentScope\n\n\tif declare != tempRefNeedsDeclareMayBeCapturedInsideLoop {\n\t\tfor !scope.Kind.StopsHoisting() {\n\t\t\tscope = scope.Parent\n\t\t}\n\t}\n\n\tif optionalName == \"\" {\n\t\toptionalName = \"_\" + ast.DefaultNameMinifierJS.NumberToMinifiedName(p.tempRefCount)\n\t\tp.tempRefCount++\n\t}\n\tref := p.newSymbol(ast.SymbolOther, optionalName)\n\n\tif declare == tempRefNeedsDeclareMayBeCapturedInsideLoop && !scope.Kind.StopsHoisting() {\n\t\tp.tempLetsToDeclare = append(p.tempLetsToDeclare, ref)\n\t} else if declare != tempRefNoDeclare {\n\t\tp.tempRefsToDeclare = append(p.tempRefsToDeclare, tempRef{ref: ref})\n\t}\n\n\tscope.Generated = append(scope.Generated, ref)\n\treturn ref\n}\n\nfunc (p *parser) generateTopLevelTempRef() ast.Ref {\n\tref := p.newSymbol(ast.SymbolOther, \"_\"+ast.DefaultNameMinifierJS.NumberToMinifiedName(p.topLevelTempRefCount))\n\tp.topLevelTempRefsToDeclare = append(p.topLevelTempRefsToDeclare, tempRef{ref: ref})\n\tp.moduleScope.Generated = append(p.moduleScope.Generated, ref)\n\tp.topLevelTempRefCount++\n\treturn ref\n}\n\nfunc (p *parser) pushScopeForVisitPass(kind js_ast.ScopeKind, loc logger.Loc) {\n\torder := p.scopesInOrder[0]\n\n\t// Sanity-check that the scopes generated by the first and second passes match\n\tif order.loc != loc || order.scope.Kind != kind {\n\t\tpanic(fmt.Sprintf(\"Expected scope (%d, %d) in %q, found scope (%d, %d)\",\n\t\t\tkind, loc.Start,\n\t\t\tp.source.PrettyPaths.Select(p.options.logPathStyle),\n\t\t\torder.scope.Kind, order.loc.Start))\n\t}\n\n\tp.scopesInOrder = p.scopesInOrder[1:]\n\tp.currentScope = order.scope\n\tp.scopesForCurrentPart = append(p.scopesForCurrentPart, order.scope)\n}\n\ntype findSymbolResult struct {\n\tref               ast.Ref\n\tdeclareLoc        logger.Loc\n\tisInsideWithScope bool\n}\n\nfunc (p *parser) findSymbol(loc logger.Loc, name string) findSymbolResult {\n\tvar ref ast.Ref\n\tvar declareLoc logger.Loc\n\tisInsideWithScope := false\n\tdidForbidArguments := false\n\ts := p.currentScope\n\n\tfor {\n\t\t// Track if we're inside a \"with\" statement body\n\t\tif s.Kind == js_ast.ScopeWith {\n\t\t\tisInsideWithScope = true\n\t\t}\n\n\t\t// Forbid referencing \"arguments\" inside class bodies\n\t\tif s.ForbidArguments && name == \"arguments\" && !didForbidArguments {\n\t\t\tr := js_lexer.RangeOfIdentifier(p.source, loc)\n\t\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\"Cannot access %q here:\", name))\n\t\t\tdidForbidArguments = true\n\t\t}\n\n\t\t// Is the symbol a member of this scope?\n\t\tif member, ok := s.Members[name]; ok {\n\t\t\tref = member.Ref\n\t\t\tdeclareLoc = member.Loc\n\t\t\tbreak\n\t\t}\n\n\t\t// Is the symbol a member of this scope's TypeScript namespace?\n\t\tif tsNamespace := s.TSNamespace; tsNamespace != nil {\n\t\t\tif member, ok := tsNamespace.ExportedMembers[name]; ok && tsNamespace.IsEnumScope == member.IsEnumValue {\n\t\t\t\t// If this is an identifier from a sibling TypeScript namespace, then we're\n\t\t\t\t// going to have to generate a property access instead of a simple reference.\n\t\t\t\t// Lazily-generate an identifier that represents this property access.\n\t\t\t\tcache := tsNamespace.LazilyGeneratedProperyAccesses\n\t\t\t\tif cache == nil {\n\t\t\t\t\tcache = make(map[string]ast.Ref)\n\t\t\t\t\ttsNamespace.LazilyGeneratedProperyAccesses = cache\n\t\t\t\t}\n\t\t\t\tref, ok = cache[name]\n\t\t\t\tif !ok {\n\t\t\t\t\tref = p.newSymbol(ast.SymbolOther, name)\n\t\t\t\t\tp.symbols[ref.InnerIndex].NamespaceAlias = &ast.NamespaceAlias{\n\t\t\t\t\t\tNamespaceRef: tsNamespace.ArgRef,\n\t\t\t\t\t\tAlias:        name,\n\t\t\t\t\t}\n\t\t\t\t\tcache[name] = ref\n\t\t\t\t}\n\t\t\t\tdeclareLoc = member.Loc\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\ts = s.Parent\n\t\tif s == nil {\n\t\t\t// Allocate an \"unbound\" symbol\n\t\t\tp.checkForUnrepresentableIdentifier(loc, name)\n\t\t\tref = p.newSymbol(ast.SymbolUnbound, name)\n\t\t\tdeclareLoc = loc\n\t\t\tp.moduleScope.Members[name] = js_ast.ScopeMember{Ref: ref, Loc: logger.Loc{Start: -1}}\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// If we had to pass through a \"with\" statement body to get to the symbol\n\t// declaration, then this reference could potentially also refer to a\n\t// property on the target object of the \"with\" statement. We must not rename\n\t// it or we risk changing the behavior of the code.\n\tif isInsideWithScope {\n\t\tp.symbols[ref.InnerIndex].Flags |= ast.MustNotBeRenamed\n\t}\n\n\t// Track how many times we've referenced this symbol\n\tp.recordUsage(ref)\n\treturn findSymbolResult{ref, declareLoc, isInsideWithScope}\n}\n\nfunc (p *parser) findLabelSymbol(loc logger.Loc, name string) (ref ast.Ref, isLoop bool, ok bool) {\n\tfor s := p.currentScope; s != nil && !s.Kind.StopsHoisting(); s = s.Parent {\n\t\tif s.Kind == js_ast.ScopeLabel && name == p.symbols[s.Label.Ref.InnerIndex].OriginalName {\n\t\t\t// Track how many times we've referenced this symbol\n\t\t\tp.recordUsage(s.Label.Ref)\n\t\t\tref = s.Label.Ref\n\t\t\tisLoop = s.LabelStmtIsLoop\n\t\t\tok = true\n\t\t\treturn\n\t\t}\n\t}\n\n\tr := js_lexer.RangeOfIdentifier(p.source, loc)\n\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\"There is no containing label named %q\", name))\n\n\t// Allocate an \"unbound\" symbol\n\tref = p.newSymbol(ast.SymbolUnbound, name)\n\n\t// Track how many times we've referenced this symbol\n\tp.recordUsage(ref)\n\treturn\n}\n\nfunc findIdentifiers(binding js_ast.Binding, identifiers []js_ast.Decl) []js_ast.Decl {\n\tswitch b := binding.Data.(type) {\n\tcase *js_ast.BIdentifier:\n\t\tidentifiers = append(identifiers, js_ast.Decl{Binding: binding})\n\n\tcase *js_ast.BArray:\n\t\tfor _, item := range b.Items {\n\t\t\tidentifiers = findIdentifiers(item.Binding, identifiers)\n\t\t}\n\n\tcase *js_ast.BObject:\n\t\tfor _, property := range b.Properties {\n\t\t\tidentifiers = findIdentifiers(property.Value, identifiers)\n\t\t}\n\t}\n\n\treturn identifiers\n}\n\nfunc shouldKeepStmtsInDeadControlFlow(stmts []js_ast.Stmt) bool {\n\tfor _, child := range stmts {\n\t\tif shouldKeepStmtInDeadControlFlow(child) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// If this is in a dead branch, then we want to trim as much dead code as we\n// can. Everything can be trimmed except for hoisted declarations (\"var\" and\n// \"function\"), which affect the parent scope. For example:\n//\n//\tfunction foo() {\n//\t  if (false) { var x; }\n//\t  x = 1;\n//\t}\n//\n// We can't trim the entire branch as dead or calling foo() will incorrectly\n// assign to a global variable instead.\nfunc shouldKeepStmtInDeadControlFlow(stmt js_ast.Stmt) bool {\n\tswitch s := stmt.Data.(type) {\n\tcase *js_ast.SEmpty, *js_ast.SExpr, *js_ast.SThrow, *js_ast.SReturn,\n\t\t*js_ast.SBreak, *js_ast.SContinue, *js_ast.SClass, *js_ast.SDebugger:\n\t\t// Omit these statements entirely\n\t\treturn false\n\n\tcase *js_ast.SLocal:\n\t\tif s.Kind != js_ast.LocalVar {\n\t\t\t// Omit these statements entirely\n\t\t\treturn false\n\t\t}\n\n\t\t// Omit everything except the identifiers\n\t\tidentifiers := []js_ast.Decl{}\n\t\tfor _, decl := range s.Decls {\n\t\t\tidentifiers = findIdentifiers(decl.Binding, identifiers)\n\t\t}\n\t\tif len(identifiers) == 0 {\n\t\t\treturn false\n\t\t}\n\t\ts.Decls = identifiers\n\t\treturn true\n\n\tcase *js_ast.SBlock:\n\t\treturn shouldKeepStmtsInDeadControlFlow(s.Stmts)\n\n\tcase *js_ast.STry:\n\t\treturn shouldKeepStmtsInDeadControlFlow(s.Block.Stmts) ||\n\t\t\t(s.Catch != nil && shouldKeepStmtsInDeadControlFlow(s.Catch.Block.Stmts)) ||\n\t\t\t(s.Finally != nil && shouldKeepStmtsInDeadControlFlow(s.Finally.Block.Stmts))\n\n\tcase *js_ast.SIf:\n\t\treturn shouldKeepStmtInDeadControlFlow(s.Yes) || (s.NoOrNil.Data != nil && shouldKeepStmtInDeadControlFlow(s.NoOrNil))\n\n\tcase *js_ast.SWhile:\n\t\treturn shouldKeepStmtInDeadControlFlow(s.Body)\n\n\tcase *js_ast.SDoWhile:\n\t\treturn shouldKeepStmtInDeadControlFlow(s.Body)\n\n\tcase *js_ast.SFor:\n\t\treturn (s.InitOrNil.Data != nil && shouldKeepStmtInDeadControlFlow(s.InitOrNil)) || shouldKeepStmtInDeadControlFlow(s.Body)\n\n\tcase *js_ast.SForIn:\n\t\treturn shouldKeepStmtInDeadControlFlow(s.Init) || shouldKeepStmtInDeadControlFlow(s.Body)\n\n\tcase *js_ast.SForOf:\n\t\treturn shouldKeepStmtInDeadControlFlow(s.Init) || shouldKeepStmtInDeadControlFlow(s.Body)\n\n\tcase *js_ast.SLabel:\n\t\treturn shouldKeepStmtInDeadControlFlow(s.Stmt)\n\n\tdefault:\n\t\t// Everything else must be kept\n\t\treturn true\n\t}\n}\n\ntype prependTempRefsOpts struct {\n\tfnBodyLoc *logger.Loc\n\tkind      stmtsKind\n}\n\nfunc (p *parser) visitStmtsAndPrependTempRefs(stmts []js_ast.Stmt, opts prependTempRefsOpts) []js_ast.Stmt {\n\toldTempRefs := p.tempRefsToDeclare\n\toldTempRefCount := p.tempRefCount\n\tp.tempRefsToDeclare = nil\n\tp.tempRefCount = 0\n\n\tstmts = p.visitStmts(stmts, opts.kind)\n\n\t// Prepend values for \"this\" and \"arguments\"\n\tif opts.fnBodyLoc != nil {\n\t\t// Capture \"this\"\n\t\tif ref := p.fnOnlyDataVisit.thisCaptureRef; ref != nil {\n\t\t\tp.tempRefsToDeclare = append(p.tempRefsToDeclare, tempRef{\n\t\t\t\tref:        *ref,\n\t\t\t\tvalueOrNil: js_ast.Expr{Loc: *opts.fnBodyLoc, Data: js_ast.EThisShared},\n\t\t\t})\n\t\t\tp.currentScope.Generated = append(p.currentScope.Generated, *ref)\n\t\t}\n\n\t\t// Capture \"arguments\"\n\t\tif ref := p.fnOnlyDataVisit.argumentsCaptureRef; ref != nil {\n\t\t\tp.tempRefsToDeclare = append(p.tempRefsToDeclare, tempRef{\n\t\t\t\tref:        *ref,\n\t\t\t\tvalueOrNil: js_ast.Expr{Loc: *opts.fnBodyLoc, Data: &js_ast.EIdentifier{Ref: *p.fnOnlyDataVisit.argumentsRef}},\n\t\t\t})\n\t\t\tp.currentScope.Generated = append(p.currentScope.Generated, *ref)\n\t\t}\n\t}\n\n\t// There may also be special top-level-only temporaries to declare\n\tif p.currentScope == p.moduleScope && p.topLevelTempRefsToDeclare != nil {\n\t\tp.tempRefsToDeclare = append(p.tempRefsToDeclare, p.topLevelTempRefsToDeclare...)\n\t\tp.topLevelTempRefsToDeclare = nil\n\t}\n\n\t// Prepend the generated temporary variables to the beginning of the statement list\n\tdecls := []js_ast.Decl{}\n\tfor _, temp := range p.tempRefsToDeclare {\n\t\tif p.symbols[temp.ref.InnerIndex].UseCountEstimate > 0 {\n\t\t\tdecls = append(decls, js_ast.Decl{Binding: js_ast.Binding{Data: &js_ast.BIdentifier{Ref: temp.ref}}, ValueOrNil: temp.valueOrNil})\n\t\t\tp.recordDeclaredSymbol(temp.ref)\n\t\t}\n\t}\n\tif len(decls) > 0 {\n\t\t// Skip past leading directives and comments\n\t\tsplit := 0\n\t\tfor split < len(stmts) {\n\t\t\tswitch stmts[split].Data.(type) {\n\t\t\tcase *js_ast.SComment, *js_ast.SDirective:\n\t\t\t\tsplit++\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tstmts = append(\n\t\t\tappend(\n\t\t\t\tappend(\n\t\t\t\t\t[]js_ast.Stmt{},\n\t\t\t\t\tstmts[:split]...),\n\t\t\t\tjs_ast.Stmt{Data: &js_ast.SLocal{Kind: js_ast.LocalVar, Decls: decls}}),\n\t\t\tstmts[split:]...)\n\t}\n\n\tp.tempRefsToDeclare = oldTempRefs\n\tp.tempRefCount = oldTempRefCount\n\treturn stmts\n}\n\ntype stmtsKind uint8\n\nconst (\n\tstmtsNormal stmtsKind = iota\n\tstmtsLoopBody\n\tstmtsFnBody\n)\n\nfunc (p *parser) visitStmts(stmts []js_ast.Stmt, kind stmtsKind) []js_ast.Stmt {\n\t// Save the current control-flow liveness. This represents if we are\n\t// currently inside an \"if (false) { ... }\" block.\n\toldIsControlFlowDead := p.isControlFlowDead\n\n\toldTempLetsToDeclare := p.tempLetsToDeclare\n\tp.tempLetsToDeclare = nil\n\n\t// Visit all statements first\n\tvisited := make([]js_ast.Stmt, 0, len(stmts))\n\tvar before []js_ast.Stmt\n\tvar after []js_ast.Stmt\n\tvar preprocessedEnums map[int][]js_ast.Stmt\n\tif p.scopesInOrderForEnum != nil {\n\t\t// Preprocess TypeScript enums to improve code generation. Otherwise\n\t\t// uses of an enum before that enum has been declared won't be inlined:\n\t\t//\n\t\t//   console.log(Foo.FOO) // We want \"FOO\" to be inlined here\n\t\t//   const enum Foo { FOO = 0 }\n\t\t//\n\t\t// The TypeScript compiler itself contains code with this pattern, so\n\t\t// it's important to implement this optimization.\n\t\tfor i, stmt := range stmts {\n\t\t\tif _, ok := stmt.Data.(*js_ast.SEnum); ok {\n\t\t\t\tif preprocessedEnums == nil {\n\t\t\t\t\tpreprocessedEnums = make(map[int][]js_ast.Stmt)\n\t\t\t\t}\n\t\t\t\toldScopesInOrder := p.scopesInOrder\n\t\t\t\tp.scopesInOrder = p.scopesInOrderForEnum[stmt.Loc]\n\t\t\t\tpreprocessedEnums[i] = p.visitAndAppendStmt(nil, stmt)\n\t\t\t\tp.scopesInOrder = oldScopesInOrder\n\t\t\t}\n\t\t}\n\t}\n\tfor i, stmt := range stmts {\n\t\tswitch s := stmt.Data.(type) {\n\t\tcase *js_ast.SExportEquals:\n\t\t\t// TypeScript \"export = value;\" becomes \"module.exports = value;\". This\n\t\t\t// must happen at the end after everything is parsed because TypeScript\n\t\t\t// moves this statement to the end when it generates code.\n\t\t\tafter = p.visitAndAppendStmt(after, stmt)\n\t\t\tcontinue\n\n\t\tcase *js_ast.SFunction:\n\t\t\t// Manually hoist block-level function declarations to preserve semantics.\n\t\t\t// This is only done for function declarations that are not generators\n\t\t\t// or async functions, since this is a backwards-compatibility hack from\n\t\t\t// Annex B of the JavaScript standard.\n\t\t\tif !p.currentScope.Kind.StopsHoisting() && p.symbols[int(s.Fn.Name.Ref.InnerIndex)].Kind == ast.SymbolHoistedFunction {\n\t\t\t\tbefore = p.visitAndAppendStmt(before, stmt)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tcase *js_ast.SEnum:\n\t\t\tvisited = append(visited, preprocessedEnums[i]...)\n\t\t\tp.scopesInOrder = p.scopesInOrder[len(p.scopesInOrderForEnum[stmt.Loc]):]\n\t\t\tcontinue\n\t\t}\n\t\tvisited = p.visitAndAppendStmt(visited, stmt)\n\t}\n\n\t// This is used for temporary variables that could be captured in a closure,\n\t// and therefore need to be generated inside the nearest enclosing block in\n\t// case they are generated inside a loop.\n\tif len(p.tempLetsToDeclare) > 0 {\n\t\tdecls := make([]js_ast.Decl, 0, len(p.tempLetsToDeclare))\n\t\tfor _, ref := range p.tempLetsToDeclare {\n\t\t\tdecls = append(decls, js_ast.Decl{Binding: js_ast.Binding{Data: &js_ast.BIdentifier{Ref: ref}}})\n\t\t}\n\t\tbefore = append(before, js_ast.Stmt{Data: &js_ast.SLocal{Kind: js_ast.LocalLet, Decls: decls}})\n\t}\n\tp.tempLetsToDeclare = oldTempLetsToDeclare\n\n\t// Transform block-level function declarations into variable declarations\n\tif len(before) > 0 {\n\t\tvar letDecls []js_ast.Decl\n\t\tvar varDecls []js_ast.Decl\n\t\tvar nonFnStmts []js_ast.Stmt\n\t\tfnStmts := make(map[ast.Ref]int)\n\t\tfor _, stmt := range before {\n\t\t\ts, ok := stmt.Data.(*js_ast.SFunction)\n\t\t\tif !ok {\n\t\t\t\t// We may get non-function statements here in certain scenarios such as when \"KeepNames\" is enabled\n\t\t\t\tnonFnStmts = append(nonFnStmts, stmt)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// This transformation of function declarations in nested scopes is\n\t\t\t// intended to preserve the hoisting semantics of the original code. In\n\t\t\t// JavaScript, function hoisting works differently in strict mode vs.\n\t\t\t// sloppy mode code. We want the code we generate to use the semantics of\n\t\t\t// the original environment, not the generated environment. However, if\n\t\t\t// direct \"eval\" is present then it's not possible to preserve the\n\t\t\t// semantics because we need two identifiers to do that and direct \"eval\"\n\t\t\t// means neither identifier can be renamed to something else. So in that\n\t\t\t// case we give up and do not preserve the semantics of the original code.\n\t\t\tif p.currentScope.ContainsDirectEval {\n\t\t\t\tif hoistedRef, ok := p.hoistedRefForSloppyModeBlockFn[s.Fn.Name.Ref]; ok {\n\t\t\t\t\t// Merge the two identifiers back into a single one\n\t\t\t\t\tp.symbols[hoistedRef.InnerIndex].Link = s.Fn.Name.Ref\n\t\t\t\t}\n\t\t\t\tnonFnStmts = append(nonFnStmts, stmt)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tindex, ok := fnStmts[s.Fn.Name.Ref]\n\t\t\tif !ok {\n\t\t\t\tindex = len(letDecls)\n\t\t\t\tfnStmts[s.Fn.Name.Ref] = index\n\t\t\t\tletDecls = append(letDecls, js_ast.Decl{Binding: js_ast.Binding{\n\t\t\t\t\tLoc: s.Fn.Name.Loc, Data: &js_ast.BIdentifier{Ref: s.Fn.Name.Ref}}})\n\n\t\t\t\t// Also write the function to the hoisted sibling symbol if applicable\n\t\t\t\tif hoistedRef, ok := p.hoistedRefForSloppyModeBlockFn[s.Fn.Name.Ref]; ok {\n\t\t\t\t\tp.recordDeclaredSymbol(hoistedRef)\n\t\t\t\t\tp.recordUsage(s.Fn.Name.Ref)\n\t\t\t\t\tvarDecls = append(varDecls, js_ast.Decl{\n\t\t\t\t\t\tBinding:    js_ast.Binding{Loc: s.Fn.Name.Loc, Data: &js_ast.BIdentifier{Ref: hoistedRef}},\n\t\t\t\t\t\tValueOrNil: js_ast.Expr{Loc: s.Fn.Name.Loc, Data: &js_ast.EIdentifier{Ref: s.Fn.Name.Ref}},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// The last function statement for a given symbol wins\n\t\t\ts.Fn.Name = nil\n\t\t\tletDecls[index].ValueOrNil = js_ast.Expr{Loc: stmt.Loc, Data: &js_ast.EFunction{Fn: s.Fn}}\n\t\t}\n\n\t\t// Reuse memory from \"before\"\n\t\tbefore = before[:0]\n\t\tkind := js_ast.LocalLet\n\t\tif p.options.unsupportedJSFeatures.Has(compat.ConstAndLet) {\n\t\t\tkind = js_ast.LocalVar\n\t\t}\n\t\tif len(letDecls) > 0 {\n\t\t\tbefore = append(before, js_ast.Stmt{Loc: letDecls[0].ValueOrNil.Loc, Data: &js_ast.SLocal{Kind: kind, Decls: letDecls}})\n\t\t}\n\t\tif len(varDecls) > 0 {\n\t\t\t// Potentially relocate \"var\" declarations to the top level\n\t\t\tif assign, ok := p.maybeRelocateVarsToTopLevel(varDecls, relocateVarsNormal); ok {\n\t\t\t\tif assign.Data != nil {\n\t\t\t\t\tbefore = append(before, assign)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tbefore = append(before, js_ast.Stmt{Loc: varDecls[0].ValueOrNil.Loc, Data: &js_ast.SLocal{Kind: js_ast.LocalVar, Decls: varDecls}})\n\t\t\t}\n\t\t}\n\t\tbefore = append(before, nonFnStmts...)\n\t\tvisited = append(before, visited...)\n\t}\n\n\t// Move TypeScript \"export =\" statements to the end\n\tvisited = append(visited, after...)\n\n\t// Restore the current control-flow liveness if it was changed inside the\n\t// loop above. This is important because the caller will not restore it.\n\tp.isControlFlowDead = oldIsControlFlowDead\n\n\t// Lower using declarations\n\tif p.shouldLowerUsingDeclarations(visited) {\n\t\tctx := p.lowerUsingDeclarationContext()\n\t\tctx.scanStmts(p, visited)\n\t\tvisited = ctx.finalize(p, visited, p.currentScope.Parent == nil)\n\t}\n\n\t// Stop now if we're not mangling\n\tif !p.options.minifySyntax {\n\t\treturn visited\n\t}\n\n\t// If this is in a dead branch, trim as much dead code as we can\n\tif p.isControlFlowDead {\n\t\tend := 0\n\t\tfor _, stmt := range visited {\n\t\t\tif !shouldKeepStmtInDeadControlFlow(stmt) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Merge adjacent var statements\n\t\t\tif s, ok := stmt.Data.(*js_ast.SLocal); ok && s.Kind == js_ast.LocalVar && end > 0 {\n\t\t\t\tprevStmt := visited[end-1]\n\t\t\t\tif prevS, ok := prevStmt.Data.(*js_ast.SLocal); ok && prevS.Kind == js_ast.LocalVar && s.IsExport == prevS.IsExport {\n\t\t\t\t\tprevS.Decls = append(prevS.Decls, s.Decls...)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvisited[end] = stmt\n\t\t\tend++\n\t\t}\n\t\treturn visited[:end]\n\t}\n\n\treturn p.mangleStmts(visited, kind)\n}\n\nfunc (p *parser) mangleStmts(stmts []js_ast.Stmt, kind stmtsKind) []js_ast.Stmt {\n\t// Remove inlined constants now that we know whether any of these statements\n\t// contained a direct eval() or not. This can't be done earlier when we\n\t// encounter the constant because we haven't encountered the eval() yet.\n\t// Inlined constants are not removed if they are in a top-level scope or\n\t// if they are exported (which could be in a nested TypeScript namespace).\n\tif p.currentScope.Parent != nil && !p.currentScope.ContainsDirectEval {\n\t\tfor i, stmt := range stmts {\n\t\t\tswitch s := stmt.Data.(type) {\n\t\t\tcase *js_ast.SEmpty, *js_ast.SComment, *js_ast.SDirective, *js_ast.SDebugger, *js_ast.STypeScript:\n\t\t\t\tcontinue\n\n\t\t\tcase *js_ast.SLocal:\n\t\t\t\tif !s.IsExport {\n\t\t\t\t\tend := 0\n\t\t\t\t\tfor _, d := range s.Decls {\n\t\t\t\t\t\tif id, ok := d.Binding.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\t\t\t\tif _, ok := p.constValues[id.Ref]; ok && p.symbols[id.Ref.InnerIndex].UseCountEstimate == 0 {\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\ts.Decls[end] = d\n\t\t\t\t\t\tend++\n\t\t\t\t\t}\n\t\t\t\t\tif end == 0 {\n\t\t\t\t\t\tstmts[i].Data = js_ast.SEmptyShared\n\t\t\t\t\t} else {\n\t\t\t\t\t\ts.Decls = s.Decls[:end]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Merge adjacent statements during mangling\n\tresult := make([]js_ast.Stmt, 0, len(stmts))\n\tisControlFlowDead := false\n\tfor i, stmt := range stmts {\n\t\tif isControlFlowDead && !shouldKeepStmtInDeadControlFlow(stmt) {\n\t\t\t// Strip unnecessary statements if the control flow is dead here\n\t\t\tcontinue\n\t\t}\n\n\t\t// Inline single-use variable declarations where possible:\n\t\t//\n\t\t//   // Before\n\t\t//   let x = fn();\n\t\t//   return x.y();\n\t\t//\n\t\t//   // After\n\t\t//   return fn().y();\n\t\t//\n\t\t// The declaration must not be exported. We can't just check for the\n\t\t// \"export\" keyword because something might do \"export {id};\" later on.\n\t\t// Instead we just ignore all top-level declarations for now. That means\n\t\t// this optimization currently only applies in nested scopes.\n\t\t//\n\t\t// Ignore declarations if the scope is shadowed by a direct \"eval\" call.\n\t\t// The eval'd code may indirectly reference this symbol and the actual\n\t\t// use count may be greater than 1.\n\t\tif p.currentScope != p.moduleScope && !p.currentScope.ContainsDirectEval {\n\t\t\t// Keep inlining variables until a failure or until there are none left.\n\t\t\t// That handles cases like this:\n\t\t\t//\n\t\t\t//   // Before\n\t\t\t//   let x = fn();\n\t\t\t//   let y = x.prop;\n\t\t\t//   return y;\n\t\t\t//\n\t\t\t//   // After\n\t\t\t//   return fn().prop;\n\t\t\t//\n\t\t\tfor len(result) > 0 {\n\t\t\t\t// Ignore \"var\" declarations since those have function-level scope and\n\t\t\t\t// we may not have visited all of their uses yet by this point. We\n\t\t\t\t// should have visited all the uses of \"let\" and \"const\" declarations\n\t\t\t\t// by now since they are scoped to this block which we just finished\n\t\t\t\t// visiting.\n\t\t\t\tif prevS, ok := result[len(result)-1].Data.(*js_ast.SLocal); ok && prevS.Kind != js_ast.LocalVar {\n\t\t\t\t\tlast := prevS.Decls[len(prevS.Decls)-1]\n\n\t\t\t\t\t// The binding must be an identifier that is only used once.\n\t\t\t\t\t// Ignore destructuring bindings since that's not the simple case.\n\t\t\t\t\t// Destructuring bindings could potentially execute side-effecting\n\t\t\t\t\t// code which would invalidate reordering.\n\t\t\t\t\tif id, ok := last.Binding.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\t\t\t// Don't do this if \"__name\" was called on this symbol. In that\n\t\t\t\t\t\t// case there is actually more than one use even though it says\n\t\t\t\t\t\t// there is only one. The \"__name\" use isn't counted so that\n\t\t\t\t\t\t// tree shaking still works when names are kept.\n\t\t\t\t\t\tif symbol := p.symbols[id.Ref.InnerIndex]; symbol.UseCountEstimate == 1 && !symbol.Flags.Has(ast.DidKeepName) {\n\t\t\t\t\t\t\treplacement := last.ValueOrNil\n\n\t\t\t\t\t\t\t// The variable must be initialized, since we will be substituting\n\t\t\t\t\t\t\t// the value into the usage.\n\t\t\t\t\t\t\tif replacement.Data == nil {\n\t\t\t\t\t\t\t\treplacement = js_ast.Expr{Loc: last.Binding.Loc, Data: js_ast.EUndefinedShared}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Try to substitute the identifier with the initializer. This will\n\t\t\t\t\t\t\t// fail if something with side effects is in between the declaration\n\t\t\t\t\t\t\t// and the usage.\n\t\t\t\t\t\t\tif p.substituteSingleUseSymbolInStmt(stmt, id.Ref, replacement) {\n\t\t\t\t\t\t\t\t// Remove the previous declaration, since the substitution was\n\t\t\t\t\t\t\t\t// successful.\n\t\t\t\t\t\t\t\tif len(prevS.Decls) == 1 {\n\t\t\t\t\t\t\t\t\tresult = result[:len(result)-1]\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tprevS.Decls = prevS.Decls[:len(prevS.Decls)-1]\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Loop back to try again\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Substitution failed so stop trying\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tswitch s := stmt.Data.(type) {\n\t\tcase *js_ast.SEmpty:\n\t\t\t// Strip empty statements\n\t\t\tcontinue\n\n\t\tcase *js_ast.SLocal:\n\t\t\t// Merge adjacent local statements\n\t\t\tif len(result) > 0 {\n\t\t\t\tprevStmt := result[len(result)-1]\n\t\t\t\tif prevS, ok := prevStmt.Data.(*js_ast.SLocal); ok && s.Kind == prevS.Kind && s.IsExport == prevS.IsExport {\n\t\t\t\t\tprevS.Decls = append(prevS.Decls, s.Decls...)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *js_ast.SExpr:\n\t\t\t// Trim expressions without side effects\n\t\t\ts.Value = p.astHelpers.SimplifyUnusedExpr(s.Value, p.options.unsupportedJSFeatures)\n\t\t\tif s.Value.Data == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Merge adjacent expression statements\n\t\t\tif len(result) > 0 {\n\t\t\t\tprevStmt := result[len(result)-1]\n\t\t\t\tif prevS, ok := prevStmt.Data.(*js_ast.SExpr); ok {\n\t\t\t\t\tif !s.IsFromClassOrFnThatCanBeRemovedIfUnused {\n\t\t\t\t\t\tprevS.IsFromClassOrFnThatCanBeRemovedIfUnused = false\n\t\t\t\t\t}\n\t\t\t\t\tprevS.Value = js_ast.JoinWithComma(prevS.Value, s.Value)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *js_ast.SSwitch:\n\t\t\t// Absorb a previous expression statement\n\t\t\tif len(result) > 0 {\n\t\t\t\tprevStmt := result[len(result)-1]\n\t\t\t\tif prevS, ok := prevStmt.Data.(*js_ast.SExpr); ok {\n\t\t\t\t\ts.Test = js_ast.JoinWithComma(prevS.Value, s.Test)\n\t\t\t\t\tresult = result[:len(result)-1]\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *js_ast.SIf:\n\t\t\t// Absorb a previous expression statement\n\t\t\tif len(result) > 0 {\n\t\t\t\tprevStmt := result[len(result)-1]\n\t\t\t\tif prevS, ok := prevStmt.Data.(*js_ast.SExpr); ok {\n\t\t\t\t\ts.Test = js_ast.JoinWithComma(prevS.Value, s.Test)\n\t\t\t\t\tresult = result[:len(result)-1]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif isJumpStatement(s.Yes.Data) {\n\t\t\t\toptimizeImplicitJump := false\n\n\t\t\t\t// Absorb a previous if statement\n\t\t\t\tif len(result) > 0 {\n\t\t\t\t\tprevStmt := result[len(result)-1]\n\t\t\t\t\tif prevS, ok := prevStmt.Data.(*js_ast.SIf); ok && prevS.NoOrNil.Data == nil && jumpStmtsLookTheSame(prevS.Yes.Data, s.Yes.Data) {\n\t\t\t\t\t\t// \"if (a) break c; if (b) break c;\" => \"if (a || b) break c;\"\n\t\t\t\t\t\t// \"if (a) continue c; if (b) continue c;\" => \"if (a || b) continue c;\"\n\t\t\t\t\t\t// \"if (a) return c; if (b) return c;\" => \"if (a || b) return c;\"\n\t\t\t\t\t\t// \"if (a) throw c; if (b) throw c;\" => \"if (a || b) throw c;\"\n\t\t\t\t\t\ts.Test = js_ast.JoinWithLeftAssociativeOp(js_ast.BinOpLogicalOr, prevS.Test, s.Test)\n\t\t\t\t\t\tresult = result[:len(result)-1]\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// \"while (x) { if (y) continue; z(); }\" => \"while (x) { if (!y) z(); }\"\n\t\t\t\t// \"while (x) { if (y) continue; else z(); w(); }\" => \"while (x) { if (!y) { z(); w(); } }\" => \"for (; x;) !y && (z(), w());\"\n\t\t\t\tif kind == stmtsLoopBody {\n\t\t\t\t\tif continueS, ok := s.Yes.Data.(*js_ast.SContinue); ok && continueS.Label == nil {\n\t\t\t\t\t\toptimizeImplicitJump = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// \"let x = () => { if (y) return; z(); };\" => \"let x = () => { if (!y) z(); };\"\n\t\t\t\t// \"let x = () => { if (y) return; else z(); w(); };\" => \"let x = () => { if (!y) { z(); w(); } };\" => \"let x = () => { !y && (z(), w()); };\"\n\t\t\t\tif kind == stmtsFnBody {\n\t\t\t\t\tif returnS, ok := s.Yes.Data.(*js_ast.SReturn); ok && returnS.ValueOrNil.Data == nil {\n\t\t\t\t\t\toptimizeImplicitJump = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif optimizeImplicitJump {\n\t\t\t\t\tvar body []js_ast.Stmt\n\t\t\t\t\tif s.NoOrNil.Data != nil {\n\t\t\t\t\t\tbody = append(body, s.NoOrNil)\n\t\t\t\t\t}\n\t\t\t\t\tbody = append(body, stmts[i+1:]...)\n\n\t\t\t\t\t// Don't do this transformation if the branch condition could\n\t\t\t\t\t// potentially access symbols declared later on this scope below.\n\t\t\t\t\t// If so, inverting the branch condition and nesting statements after\n\t\t\t\t\t// this in a block would break that access which is a behavior change.\n\t\t\t\t\t//\n\t\t\t\t\t//   // This transformation is incorrect\n\t\t\t\t\t//   if (a()) return; function a() {}\n\t\t\t\t\t//   if (!a()) { function a() {} }\n\t\t\t\t\t//\n\t\t\t\t\t//   // This transformation is incorrect\n\t\t\t\t\t//   if (a(() => b)) return; let b;\n\t\t\t\t\t//   if (a(() => b)) { let b; }\n\t\t\t\t\t//\n\t\t\t\t\tif !stmtsCareAboutScope(body) {\n\t\t\t\t\t\tbody = p.mangleStmts(body, kind)\n\t\t\t\t\t\tbodyLoc := s.Yes.Loc\n\t\t\t\t\t\tif len(body) > 0 {\n\t\t\t\t\t\t\tbodyLoc = body[0].Loc\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn p.mangleIf(result, stmt.Loc, &js_ast.SIf{\n\t\t\t\t\t\t\tTest: p.astHelpers.SimplifyBooleanExpr(js_ast.Not(s.Test)),\n\t\t\t\t\t\t\tYes:  stmtsToSingleStmt(bodyLoc, body, logger.Loc{}),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif s.NoOrNil.Data != nil {\n\t\t\t\t\t// \"if (a) return b; else if (c) return d; else return e;\" => \"if (a) return b; if (c) return d; return e;\"\n\t\t\t\t\tfor {\n\t\t\t\t\t\tresult = append(result, stmt)\n\t\t\t\t\t\tstmt = s.NoOrNil\n\t\t\t\t\t\ts.NoOrNil = js_ast.Stmt{}\n\t\t\t\t\t\tvar ok bool\n\t\t\t\t\t\ts, ok = stmt.Data.(*js_ast.SIf)\n\t\t\t\t\t\tif !ok || !isJumpStatement(s.Yes.Data) || s.NoOrNil.Data == nil {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tresult = appendIfOrLabelBodyPreservingScope(result, stmt)\n\t\t\t\t\tif isJumpStatement(stmt.Data) {\n\t\t\t\t\t\tisControlFlowDead = true\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *js_ast.SReturn:\n\t\t\t// Merge return statements with the previous expression statement\n\t\t\tif len(result) > 0 && s.ValueOrNil.Data != nil {\n\t\t\t\tprevStmt := result[len(result)-1]\n\t\t\t\tif prevS, ok := prevStmt.Data.(*js_ast.SExpr); ok {\n\t\t\t\t\tresult[len(result)-1] = js_ast.Stmt{Loc: prevStmt.Loc,\n\t\t\t\t\t\tData: &js_ast.SReturn{ValueOrNil: js_ast.JoinWithComma(prevS.Value, s.ValueOrNil)}}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tisControlFlowDead = true\n\n\t\tcase *js_ast.SThrow:\n\t\t\t// Merge throw statements with the previous expression statement\n\t\t\tif len(result) > 0 {\n\t\t\t\tprevStmt := result[len(result)-1]\n\t\t\t\tif prevS, ok := prevStmt.Data.(*js_ast.SExpr); ok {\n\t\t\t\t\tresult[len(result)-1] = js_ast.Stmt{Loc: prevStmt.Loc, Data: &js_ast.SThrow{Value: js_ast.JoinWithComma(prevS.Value, s.Value)}}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tisControlFlowDead = true\n\n\t\tcase *js_ast.SBreak, *js_ast.SContinue:\n\t\t\tisControlFlowDead = true\n\n\t\tcase *js_ast.SFor:\n\t\t\tif len(result) > 0 {\n\t\t\t\tprevStmt := result[len(result)-1]\n\t\t\t\tif prevS, ok := prevStmt.Data.(*js_ast.SExpr); ok {\n\t\t\t\t\t// Insert the previous expression into the for loop initializer\n\t\t\t\t\tif s.InitOrNil.Data == nil {\n\t\t\t\t\t\tresult[len(result)-1] = stmt\n\t\t\t\t\t\ts.InitOrNil = js_ast.Stmt{Loc: prevStmt.Loc, Data: &js_ast.SExpr{Value: prevS.Value}}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t} else if s2, ok := s.InitOrNil.Data.(*js_ast.SExpr); ok {\n\t\t\t\t\t\tresult[len(result)-1] = stmt\n\t\t\t\t\t\ts.InitOrNil = js_ast.Stmt{Loc: prevStmt.Loc, Data: &js_ast.SExpr{Value: js_ast.JoinWithComma(prevS.Value, s2.Value)}}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Insert the previous variable declaration into the for loop\n\t\t\t\t\t// initializer if it's a \"var\" declaration, since the scope\n\t\t\t\t\t// doesn't matter due to scope hoisting\n\t\t\t\t\tif s.InitOrNil.Data == nil {\n\t\t\t\t\t\tif s2, ok := prevStmt.Data.(*js_ast.SLocal); ok && s2.Kind == js_ast.LocalVar && !s2.IsExport {\n\t\t\t\t\t\t\tresult[len(result)-1] = stmt\n\t\t\t\t\t\t\ts.InitOrNil = prevStmt\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif s2, ok := prevStmt.Data.(*js_ast.SLocal); ok && s2.Kind == js_ast.LocalVar && !s2.IsExport {\n\t\t\t\t\t\t\tif s3, ok := s.InitOrNil.Data.(*js_ast.SLocal); ok && s3.Kind == js_ast.LocalVar {\n\t\t\t\t\t\t\t\tresult[len(result)-1] = stmt\n\t\t\t\t\t\t\t\ts.InitOrNil.Data = &js_ast.SLocal{Kind: js_ast.LocalVar, Decls: append(s2.Decls, s3.Decls...)}\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *js_ast.STry:\n\t\t\t// Drop an unused identifier binding if the optional catch binding feature is supported\n\t\t\tif !p.options.unsupportedJSFeatures.Has(compat.OptionalCatchBinding) && s.Catch != nil {\n\t\t\t\tif id, ok := s.Catch.BindingOrNil.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\t\tif symbol := p.symbols[id.Ref.InnerIndex]; symbol.UseCountEstimate == 0 {\n\t\t\t\t\t\tif symbol.Link != ast.InvalidRef {\n\t\t\t\t\t\t\t// We cannot transform \"try { x() } catch (y) { var y = 1 }\" into\n\t\t\t\t\t\t\t// \"try { x() } catch { var y = 1 }\" even though \"y\" is never used\n\t\t\t\t\t\t\t// because the hoisted variable \"y\" would have different values\n\t\t\t\t\t\t\t// after the statement ends due to a strange JavaScript quirk:\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t//   try { x() } catch (y) { var y = 1 }\n\t\t\t\t\t\t\t//   console.log(y) // undefined\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t//   try { x() } catch { var y = 1 }\n\t\t\t\t\t\t\t//   console.log(y) // 1\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t} else if p.currentScope.ContainsDirectEval {\n\t\t\t\t\t\t\t// We cannot transform \"try { x() } catch (y) { eval('z = y') }\"\n\t\t\t\t\t\t\t// into \"try { x() } catch { eval('z = y') }\" because the variable\n\t\t\t\t\t\t\t// \"y\" is actually still used.\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// \"try { x() } catch (y) {}\" => \"try { x() } catch {}\"\n\t\t\t\t\t\t\ts.Catch.BindingOrNil.Data = nil\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tresult = append(result, stmt)\n\t}\n\n\t// Drop a trailing unconditional jump statement if applicable\n\tif len(result) > 0 {\n\t\tswitch kind {\n\t\tcase stmtsLoopBody:\n\t\t\t// \"while (x) { y(); continue; }\" => \"while (x) { y(); }\"\n\t\t\tif continueS, ok := result[len(result)-1].Data.(*js_ast.SContinue); ok && continueS.Label == nil {\n\t\t\t\tresult = result[:len(result)-1]\n\t\t\t}\n\n\t\tcase stmtsFnBody:\n\t\t\tif returnS, ok := result[len(result)-1].Data.(*js_ast.SReturn); ok {\n\t\t\t\tif returnS.ValueOrNil.Data == nil {\n\t\t\t\t\t// \"function f() { x(); return; }\" => \"function f() { x(); }\"\n\t\t\t\t\tresult = result[:len(result)-1]\n\t\t\t\t} else if unary, ok := returnS.ValueOrNil.Data.(*js_ast.EUnary); ok && unary.Op == js_ast.UnOpVoid {\n\t\t\t\t\t// \"function f() { return void x(); }\" => \"function f() { x(); }\"\n\t\t\t\t\tresult[len(result)-1].Data = &js_ast.SExpr{Value: unary.Value}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Merge certain statements in reverse order\n\tif len(result) >= 2 {\n\t\tlastStmt := result[len(result)-1]\n\n\t\tif lastReturn, ok := lastStmt.Data.(*js_ast.SReturn); ok {\n\t\t\t// \"if (a) return b; if (c) return d; return e;\" => \"return a ? b : c ? d : e;\"\n\t\treturnLoop:\n\t\t\tfor len(result) >= 2 {\n\t\t\t\tprevIndex := len(result) - 2\n\t\t\t\tprevStmt := result[prevIndex]\n\n\t\t\t\tswitch prevS := prevStmt.Data.(type) {\n\t\t\t\tcase *js_ast.SExpr:\n\t\t\t\t\t// This return statement must have a value\n\t\t\t\t\tif lastReturn.ValueOrNil.Data == nil {\n\t\t\t\t\t\tbreak returnLoop\n\t\t\t\t\t}\n\n\t\t\t\t\t// \"a(); return b;\" => \"return a(), b;\"\n\t\t\t\t\tlastReturn = &js_ast.SReturn{ValueOrNil: js_ast.JoinWithComma(prevS.Value, lastReturn.ValueOrNil)}\n\n\t\t\t\t\t// Merge the last two statements\n\t\t\t\t\tlastStmt = js_ast.Stmt{Loc: prevStmt.Loc, Data: lastReturn}\n\t\t\t\t\tresult[prevIndex] = lastStmt\n\t\t\t\t\tresult = result[:len(result)-1]\n\n\t\t\t\tcase *js_ast.SIf:\n\t\t\t\t\t// The previous statement must be an if statement with no else clause\n\t\t\t\t\tif prevS.NoOrNil.Data != nil {\n\t\t\t\t\t\tbreak returnLoop\n\t\t\t\t\t}\n\n\t\t\t\t\t// The then clause must be a return\n\t\t\t\t\tprevReturn, ok := prevS.Yes.Data.(*js_ast.SReturn)\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\tbreak returnLoop\n\t\t\t\t\t}\n\n\t\t\t\t\t// Handle some or all of the values being undefined\n\t\t\t\t\tleft := prevReturn.ValueOrNil\n\t\t\t\t\tright := lastReturn.ValueOrNil\n\t\t\t\t\tif left.Data == nil {\n\t\t\t\t\t\t// \"if (a) return; return b;\" => \"return a ? void 0 : b;\"\n\t\t\t\t\t\tleft = js_ast.Expr{Loc: prevS.Yes.Loc, Data: js_ast.EUndefinedShared}\n\t\t\t\t\t}\n\t\t\t\t\tif right.Data == nil {\n\t\t\t\t\t\t// \"if (a) return a; return;\" => \"return a ? b : void 0;\"\n\t\t\t\t\t\tright = js_ast.Expr{Loc: lastStmt.Loc, Data: js_ast.EUndefinedShared}\n\t\t\t\t\t}\n\n\t\t\t\t\t// \"if (!a) return b; return c;\" => \"return a ? c : b;\"\n\t\t\t\t\tif not, ok := prevS.Test.Data.(*js_ast.EUnary); ok && not.Op == js_ast.UnOpNot {\n\t\t\t\t\t\tprevS.Test = not.Value\n\t\t\t\t\t\tleft, right = right, left\n\t\t\t\t\t}\n\n\t\t\t\t\tif comma, ok := prevS.Test.Data.(*js_ast.EBinary); ok && comma.Op == js_ast.BinOpComma {\n\t\t\t\t\t\t// \"if (a, b) return c; return d;\" => \"return a, b ? c : d;\"\n\t\t\t\t\t\tlastReturn = &js_ast.SReturn{ValueOrNil: js_ast.JoinWithComma(comma.Left,\n\t\t\t\t\t\t\tp.astHelpers.MangleIfExpr(comma.Right.Loc, &js_ast.EIf{Test: comma.Right, Yes: left, No: right}, p.options.unsupportedJSFeatures))}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// \"if (a) return b; return c;\" => \"return a ? b : c;\"\n\t\t\t\t\t\tlastReturn = &js_ast.SReturn{ValueOrNil: p.astHelpers.MangleIfExpr(\n\t\t\t\t\t\t\tprevS.Test.Loc, &js_ast.EIf{Test: prevS.Test, Yes: left, No: right}, p.options.unsupportedJSFeatures)}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Merge the last two statements\n\t\t\t\t\tlastStmt = js_ast.Stmt{Loc: prevStmt.Loc, Data: lastReturn}\n\t\t\t\t\tresult[prevIndex] = lastStmt\n\t\t\t\t\tresult = result[:len(result)-1]\n\n\t\t\t\tdefault:\n\t\t\t\t\tbreak returnLoop\n\t\t\t\t}\n\t\t\t}\n\t\t} else if lastThrow, ok := lastStmt.Data.(*js_ast.SThrow); ok {\n\t\t\t// \"if (a) throw b; if (c) throw d; throw e;\" => \"throw a ? b : c ? d : e;\"\n\t\tthrowLoop:\n\t\t\tfor len(result) >= 2 {\n\t\t\t\tprevIndex := len(result) - 2\n\t\t\t\tprevStmt := result[prevIndex]\n\n\t\t\t\tswitch prevS := prevStmt.Data.(type) {\n\t\t\t\tcase *js_ast.SExpr:\n\t\t\t\t\t// \"a(); throw b;\" => \"throw a(), b;\"\n\t\t\t\t\tlastThrow = &js_ast.SThrow{Value: js_ast.JoinWithComma(prevS.Value, lastThrow.Value)}\n\n\t\t\t\t\t// Merge the last two statements\n\t\t\t\t\tlastStmt = js_ast.Stmt{Loc: prevStmt.Loc, Data: lastThrow}\n\t\t\t\t\tresult[prevIndex] = lastStmt\n\t\t\t\t\tresult = result[:len(result)-1]\n\n\t\t\t\tcase *js_ast.SIf:\n\t\t\t\t\t// The previous statement must be an if statement with no else clause\n\t\t\t\t\tif prevS.NoOrNil.Data != nil {\n\t\t\t\t\t\tbreak throwLoop\n\t\t\t\t\t}\n\n\t\t\t\t\t// The then clause must be a throw\n\t\t\t\t\tprevThrow, ok := prevS.Yes.Data.(*js_ast.SThrow)\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\tbreak throwLoop\n\t\t\t\t\t}\n\n\t\t\t\t\tleft := prevThrow.Value\n\t\t\t\t\tright := lastThrow.Value\n\n\t\t\t\t\t// \"if (!a) throw b; throw c;\" => \"throw a ? c : b;\"\n\t\t\t\t\tif not, ok := prevS.Test.Data.(*js_ast.EUnary); ok && not.Op == js_ast.UnOpNot {\n\t\t\t\t\t\tprevS.Test = not.Value\n\t\t\t\t\t\tleft, right = right, left\n\t\t\t\t\t}\n\n\t\t\t\t\t// Merge the last two statements\n\t\t\t\t\tif comma, ok := prevS.Test.Data.(*js_ast.EBinary); ok && comma.Op == js_ast.BinOpComma {\n\t\t\t\t\t\t// \"if (a, b) return c; return d;\" => \"return a, b ? c : d;\"\n\t\t\t\t\t\tlastThrow = &js_ast.SThrow{Value: js_ast.JoinWithComma(comma.Left,\n\t\t\t\t\t\t\tp.astHelpers.MangleIfExpr(comma.Right.Loc, &js_ast.EIf{Test: comma.Right, Yes: left, No: right}, p.options.unsupportedJSFeatures))}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// \"if (a) return b; return c;\" => \"return a ? b : c;\"\n\t\t\t\t\t\tlastThrow = &js_ast.SThrow{\n\t\t\t\t\t\t\tValue: p.astHelpers.MangleIfExpr(prevS.Test.Loc, &js_ast.EIf{Test: prevS.Test, Yes: left, No: right}, p.options.unsupportedJSFeatures)}\n\t\t\t\t\t}\n\t\t\t\t\tlastStmt = js_ast.Stmt{Loc: prevStmt.Loc, Data: lastThrow}\n\t\t\t\t\tresult[prevIndex] = lastStmt\n\t\t\t\t\tresult = result[:len(result)-1]\n\n\t\t\t\tdefault:\n\t\t\t\t\tbreak throwLoop\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result\n}\n\nfunc (p *parser) substituteSingleUseSymbolInStmt(stmt js_ast.Stmt, ref ast.Ref, replacement js_ast.Expr) bool {\n\tvar expr *js_ast.Expr\n\n\tswitch s := stmt.Data.(type) {\n\tcase *js_ast.SExpr:\n\t\texpr = &s.Value\n\tcase *js_ast.SThrow:\n\t\texpr = &s.Value\n\tcase *js_ast.SReturn:\n\t\texpr = &s.ValueOrNil\n\tcase *js_ast.SIf:\n\t\texpr = &s.Test\n\tcase *js_ast.SSwitch:\n\t\texpr = &s.Test\n\tcase *js_ast.SLocal:\n\t\t// Only try substituting into the initializer for the first declaration\n\t\tif first := &s.Decls[0]; first.ValueOrNil.Data != nil {\n\t\t\t// Make sure there isn't destructuring, which could evaluate code\n\t\t\tif _, ok := first.Binding.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\texpr = &first.ValueOrNil\n\t\t\t}\n\t\t}\n\t}\n\n\tif expr != nil {\n\t\t// Only continue trying to insert this replacement into sub-expressions\n\t\t// after the first one if the replacement has no side effects:\n\t\t//\n\t\t//   // Substitution is ok\n\t\t//   let replacement = 123;\n\t\t//   return x + replacement;\n\t\t//\n\t\t//   // Substitution is not ok because \"fn()\" may change \"x\"\n\t\t//   let replacement = fn();\n\t\t//   return x + replacement;\n\t\t//\n\t\t//   // Substitution is not ok because \"x == x\" may change \"x\" due to \"valueOf()\" evaluation\n\t\t//   let replacement = [x];\n\t\t//   return (x == x) + replacement;\n\t\t//\n\t\treplacementCanBeRemoved := p.astHelpers.ExprCanBeRemovedIfUnused(replacement)\n\n\t\tif new, status := p.substituteSingleUseSymbolInExpr(*expr, ref, replacement, replacementCanBeRemoved); status == substituteSuccess {\n\t\t\t*expr = new\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\ntype substituteStatus uint8\n\nconst (\n\tsubstituteContinue substituteStatus = iota\n\tsubstituteSuccess\n\tsubstituteFailure\n)\n\nfunc (p *parser) substituteSingleUseSymbolInExpr(\n\texpr js_ast.Expr,\n\tref ast.Ref,\n\treplacement js_ast.Expr,\n\treplacementCanBeRemoved bool,\n) (js_ast.Expr, substituteStatus) {\n\tswitch e := expr.Data.(type) {\n\tcase *js_ast.EIdentifier:\n\t\tif e.Ref == ref {\n\t\t\tp.ignoreUsage(ref)\n\t\t\treturn replacement, substituteSuccess\n\t\t}\n\n\tcase *js_ast.ESpread:\n\t\tif value, status := p.substituteSingleUseSymbolInExpr(e.Value, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\te.Value = value\n\t\t\treturn expr, status\n\t\t}\n\n\tcase *js_ast.EAwait:\n\t\tif value, status := p.substituteSingleUseSymbolInExpr(e.Value, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\te.Value = value\n\t\t\treturn expr, status\n\t\t}\n\n\tcase *js_ast.EYield:\n\t\tif e.ValueOrNil.Data != nil {\n\t\t\tif value, status := p.substituteSingleUseSymbolInExpr(e.ValueOrNil, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\t\te.ValueOrNil = value\n\t\t\t\treturn expr, status\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.EImportCall:\n\t\tif value, status := p.substituteSingleUseSymbolInExpr(e.Expr, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\te.Expr = value\n\t\t\treturn expr, status\n\t\t}\n\n\t\t// The \"import()\" expression has side effects but the side effects are\n\t\t// always asynchronous so there is no way for the side effects to modify\n\t\t// the replacement value. So it's ok to reorder the replacement value\n\t\t// past the \"import()\" expression assuming everything else checks out.\n\t\tif replacementCanBeRemoved && p.astHelpers.ExprCanBeRemovedIfUnused(e.Expr) {\n\t\t\treturn expr, substituteContinue\n\t\t}\n\n\tcase *js_ast.EUnary:\n\t\tswitch e.Op {\n\t\tcase js_ast.UnOpPreInc, js_ast.UnOpPostInc, js_ast.UnOpPreDec, js_ast.UnOpPostDec, js_ast.UnOpDelete:\n\t\t\t// Do not substitute into an assignment position\n\n\t\tdefault:\n\t\t\tif value, status := p.substituteSingleUseSymbolInExpr(e.Value, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\t\te.Value = value\n\t\t\t\treturn expr, status\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.EDot:\n\t\tif value, status := p.substituteSingleUseSymbolInExpr(e.Target, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\te.Target = value\n\t\t\treturn expr, status\n\t\t}\n\n\tcase *js_ast.EBinary:\n\t\t// Do not substitute into an assignment position\n\t\tif e.Op.BinaryAssignTarget() == js_ast.AssignTargetNone {\n\t\t\tif value, status := p.substituteSingleUseSymbolInExpr(e.Left, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\t\te.Left = value\n\t\t\t\treturn expr, status\n\t\t\t}\n\t\t} else if !p.astHelpers.ExprCanBeRemovedIfUnused(e.Left) {\n\t\t\t// Do not reorder past a side effect in an assignment target, as that may\n\t\t\t// change the replacement value. For example, \"fn()\" may change \"a\" here:\n\t\t\t//\n\t\t\t//   let a = 1;\n\t\t\t//   foo[fn()] = a;\n\t\t\t//\n\t\t\treturn expr, substituteFailure\n\t\t} else if e.Op.BinaryAssignTarget() == js_ast.AssignTargetUpdate && !replacementCanBeRemoved {\n\t\t\t// If this is a read-modify-write assignment and the replacement has side\n\t\t\t// effects, don't reorder it past the assignment target. The assignment\n\t\t\t// target is being read so it may be changed by the side effect. For\n\t\t\t// example, \"fn()\" may change \"foo\" here:\n\t\t\t//\n\t\t\t//   let a = fn();\n\t\t\t//   foo += a;\n\t\t\t//\n\t\t\treturn expr, substituteFailure\n\t\t}\n\n\t\t// If we get here then it should be safe to attempt to substitute the\n\t\t// replacement past the left operand into the right operand.\n\t\tif value, status := p.substituteSingleUseSymbolInExpr(e.Right, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\te.Right = value\n\t\t\treturn expr, status\n\t\t}\n\n\tcase *js_ast.EIf:\n\t\tif value, status := p.substituteSingleUseSymbolInExpr(e.Test, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\te.Test = value\n\t\t\treturn expr, status\n\t\t}\n\n\t\t// Do not substitute our unconditionally-executed value into a branch\n\t\t// unless the value itself has no side effects\n\t\tif replacementCanBeRemoved {\n\t\t\t// Unlike other branches in this function such as \"a && b\" or \"a?.[b]\",\n\t\t\t// the \"a ? b : c\" form has potential code evaluation along both control\n\t\t\t// flow paths. Handle this by allowing substitution into either branch.\n\t\t\t// Side effects in one branch should not prevent the substitution into\n\t\t\t// the other branch.\n\n\t\t\tyesValue, yesStatus := p.substituteSingleUseSymbolInExpr(e.Yes, ref, replacement, replacementCanBeRemoved)\n\t\t\tif yesStatus == substituteSuccess {\n\t\t\t\te.Yes = yesValue\n\t\t\t\treturn expr, yesStatus\n\t\t\t}\n\n\t\t\tnoValue, noStatus := p.substituteSingleUseSymbolInExpr(e.No, ref, replacement, replacementCanBeRemoved)\n\t\t\tif noStatus == substituteSuccess {\n\t\t\t\te.No = noValue\n\t\t\t\treturn expr, noStatus\n\t\t\t}\n\n\t\t\t// Side effects in either branch should stop us from continuing to try to\n\t\t\t// substitute the replacement after the control flow branches merge again.\n\t\t\tif yesStatus != substituteContinue || noStatus != substituteContinue {\n\t\t\t\treturn expr, substituteFailure\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.EIndex:\n\t\tif value, status := p.substituteSingleUseSymbolInExpr(e.Target, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\te.Target = value\n\t\t\treturn expr, status\n\t\t}\n\n\t\t// Do not substitute our unconditionally-executed value into a branch\n\t\t// unless the value itself has no side effects\n\t\tif replacementCanBeRemoved || e.OptionalChain == js_ast.OptionalChainNone {\n\t\t\tif value, status := p.substituteSingleUseSymbolInExpr(e.Index, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\t\te.Index = value\n\t\t\t\treturn expr, status\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.ECall:\n\t\t// Don't substitute something into a call target that could change \"this\"\n\t\t_, isDot := replacement.Data.(*js_ast.EDot)\n\t\t_, isIndex := replacement.Data.(*js_ast.EIndex)\n\t\tif isDot || isIndex {\n\t\t\tif id, ok := e.Target.Data.(*js_ast.EIdentifier); ok && id.Ref == ref {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif value, status := p.substituteSingleUseSymbolInExpr(e.Target, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\te.Target = value\n\t\t\tif status == substituteSuccess {\n\t\t\t\t// \"const y = () => x; y()\" => \"(() => x)()\" => \"x\"\n\t\t\t\tif value, ok := p.maybeInlineIIFE(expr.Loc, e); ok {\n\t\t\t\t\treturn value, substituteSuccess\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn expr, status\n\t\t}\n\n\t\t// Do not substitute our unconditionally-executed value into a branch\n\t\t// unless the value itself has no side effects\n\t\tif replacementCanBeRemoved || e.OptionalChain == js_ast.OptionalChainNone {\n\t\t\tfor i, arg := range e.Args {\n\t\t\t\tif value, status := p.substituteSingleUseSymbolInExpr(arg, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\t\t\te.Args[i] = value\n\t\t\t\t\treturn expr, status\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.EArray:\n\t\tfor i, item := range e.Items {\n\t\t\tif value, status := p.substituteSingleUseSymbolInExpr(item, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\t\te.Items[i] = value\n\t\t\t\treturn expr, status\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.EObject:\n\t\tfor i, property := range e.Properties {\n\t\t\t// Check the key\n\t\t\tif property.Flags.Has(js_ast.PropertyIsComputed) {\n\t\t\t\tif value, status := p.substituteSingleUseSymbolInExpr(property.Key, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\t\t\te.Properties[i].Key = value\n\t\t\t\t\treturn expr, status\n\t\t\t\t}\n\n\t\t\t\t// Stop now because both computed keys and property spread have side effects\n\t\t\t\treturn expr, substituteFailure\n\t\t\t}\n\n\t\t\t// Check the value\n\t\t\tif property.ValueOrNil.Data != nil {\n\t\t\t\tif value, status := p.substituteSingleUseSymbolInExpr(property.ValueOrNil, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\t\t\te.Properties[i].ValueOrNil = value\n\t\t\t\t\treturn expr, status\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.ETemplate:\n\t\tif e.TagOrNil.Data != nil {\n\t\t\tif value, status := p.substituteSingleUseSymbolInExpr(e.TagOrNil, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\t\te.TagOrNil = value\n\t\t\t\treturn expr, status\n\t\t\t}\n\t\t}\n\n\t\tfor i, part := range e.Parts {\n\t\t\tif value, status := p.substituteSingleUseSymbolInExpr(part.Value, ref, replacement, replacementCanBeRemoved); status != substituteContinue {\n\t\t\t\te.Parts[i].Value = value\n\n\t\t\t\t// If we substituted a primitive, merge it into the template\n\t\t\t\tif js_ast.IsPrimitiveLiteral(value.Data) {\n\t\t\t\t\texpr = js_ast.InlinePrimitivesIntoTemplate(expr.Loc, e)\n\t\t\t\t}\n\t\t\t\treturn expr, status\n\t\t\t}\n\t\t}\n\t}\n\n\t// If both the replacement and this expression have no observable side\n\t// effects, then we can reorder the replacement past this expression\n\tif replacementCanBeRemoved && p.astHelpers.ExprCanBeRemovedIfUnused(expr) {\n\t\treturn expr, substituteContinue\n\t}\n\n\t// We can always reorder past primitive values\n\tif js_ast.IsPrimitiveLiteral(expr.Data) || js_ast.IsPrimitiveLiteral(replacement.Data) {\n\t\treturn expr, substituteContinue\n\t}\n\n\t// Otherwise we should stop trying to substitute past this point\n\treturn expr, substituteFailure\n}\n\nfunc (p *parser) visitLoopBody(stmt js_ast.Stmt) js_ast.Stmt {\n\toldIsInsideLoop := p.fnOrArrowDataVisit.isInsideLoop\n\tp.fnOrArrowDataVisit.isInsideLoop = true\n\tp.loopBody = stmt.Data\n\tstmt = p.visitSingleStmt(stmt, stmtsLoopBody)\n\tp.fnOrArrowDataVisit.isInsideLoop = oldIsInsideLoop\n\treturn stmt\n}\n\nfunc (p *parser) visitSingleStmt(stmt js_ast.Stmt, kind stmtsKind) js_ast.Stmt {\n\t// To reduce stack depth, special-case blocks and process their children directly\n\tif block, ok := stmt.Data.(*js_ast.SBlock); ok {\n\t\tp.pushScopeForVisitPass(js_ast.ScopeBlock, stmt.Loc)\n\t\tblock.Stmts = p.visitStmts(block.Stmts, kind)\n\t\tp.popScope()\n\t\tif p.options.minifySyntax {\n\t\t\tstmt = stmtsToSingleStmt(stmt.Loc, block.Stmts, block.CloseBraceLoc)\n\t\t}\n\t\treturn stmt\n\t}\n\n\t// Introduce a fake block scope for function declarations inside if statements\n\tfn, ok := stmt.Data.(*js_ast.SFunction)\n\thasIfScope := ok && fn.Fn.HasIfScope\n\tif hasIfScope {\n\t\tp.pushScopeForVisitPass(js_ast.ScopeBlock, stmt.Loc)\n\t\tif p.isStrictMode() {\n\t\t\tp.markStrictModeFeature(ifElseFunctionStmt, js_lexer.RangeOfIdentifier(p.source, stmt.Loc), \"\")\n\t\t}\n\t}\n\n\tp.singleStmtDepth++\n\tstmts := p.visitStmts([]js_ast.Stmt{stmt}, kind)\n\tp.singleStmtDepth--\n\n\t// Balance the fake block scope introduced above\n\tif hasIfScope {\n\t\tp.popScope()\n\t}\n\n\treturn stmtsToSingleStmt(stmt.Loc, stmts, logger.Loc{})\n}\n\n// One statement could potentially expand to several statements\nfunc stmtsToSingleStmt(loc logger.Loc, stmts []js_ast.Stmt, closeBraceLoc logger.Loc) js_ast.Stmt {\n\tif len(stmts) == 0 {\n\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.SEmptyShared}\n\t}\n\tif len(stmts) == 1 && !stmtCaresAboutScope(stmts[0]) {\n\t\treturn stmts[0]\n\t}\n\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SBlock{Stmts: stmts, CloseBraceLoc: closeBraceLoc}}\n}\n\nfunc (p *parser) visitForLoopInit(stmt js_ast.Stmt, isInOrOf bool) js_ast.Stmt {\n\tswitch s := stmt.Data.(type) {\n\tcase *js_ast.SExpr:\n\t\tassignTarget := js_ast.AssignTargetNone\n\t\tif isInOrOf {\n\t\t\tassignTarget = js_ast.AssignTargetReplace\n\t\t}\n\t\tp.stmtExprValue = s.Value.Data\n\t\ts.Value, _ = p.visitExprInOut(s.Value, exprIn{assignTarget: assignTarget})\n\n\tcase *js_ast.SLocal:\n\t\tfor i := range s.Decls {\n\t\t\td := &s.Decls[i]\n\t\t\tp.visitBinding(d.Binding, bindingOpts{})\n\t\t\tif d.ValueOrNil.Data != nil {\n\t\t\t\td.ValueOrNil = p.visitExpr(d.ValueOrNil)\n\t\t\t}\n\t\t}\n\t\ts.Decls = p.lowerObjectRestInDecls(s.Decls)\n\t\ts.Kind = p.selectLocalKind(s.Kind)\n\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n\n\treturn stmt\n}\n\nfunc (p *parser) recordDeclaredSymbol(ref ast.Ref) {\n\tp.declaredSymbols = append(p.declaredSymbols, js_ast.DeclaredSymbol{\n\t\tRef:        ref,\n\t\tIsTopLevel: p.currentScope == p.moduleScope,\n\t})\n}\n\ntype bindingOpts struct {\n\tduplicateArgCheck map[string]logger.Range\n}\n\nfunc (p *parser) visitBinding(binding js_ast.Binding, opts bindingOpts) {\n\tswitch b := binding.Data.(type) {\n\tcase *js_ast.BMissing:\n\n\tcase *js_ast.BIdentifier:\n\t\tp.recordDeclaredSymbol(b.Ref)\n\t\tname := p.symbols[b.Ref.InnerIndex].OriginalName\n\t\tp.validateDeclaredSymbolName(binding.Loc, name)\n\t\tif opts.duplicateArgCheck != nil {\n\t\t\tr := js_lexer.RangeOfIdentifier(p.source, binding.Loc)\n\t\t\tif firstRange := opts.duplicateArgCheck[name]; firstRange.Len > 0 {\n\t\t\t\tp.log.AddErrorWithNotes(&p.tracker, r,\n\t\t\t\t\tfmt.Sprintf(\"%q cannot be bound multiple times in the same parameter list\", name),\n\t\t\t\t\t[]logger.MsgData{p.tracker.MsgData(firstRange, fmt.Sprintf(\"The name %q was originally bound here:\", name))})\n\t\t\t} else {\n\t\t\t\topts.duplicateArgCheck[name] = r\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.BArray:\n\t\tfor i := range b.Items {\n\t\t\titem := &b.Items[i]\n\t\t\tp.visitBinding(item.Binding, opts)\n\t\t\tif item.DefaultValueOrNil.Data != nil {\n\t\t\t\t// Propagate the name to keep from the binding into the initializer\n\t\t\t\tif id, ok := item.Binding.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\t\tp.nameToKeep = p.symbols[id.Ref.InnerIndex].OriginalName\n\t\t\t\t\tp.nameToKeepIsFor = item.DefaultValueOrNil.Data\n\t\t\t\t}\n\n\t\t\t\titem.DefaultValueOrNil = p.visitExpr(item.DefaultValueOrNil)\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.BObject:\n\t\tfor i, property := range b.Properties {\n\t\t\tif !property.IsSpread {\n\t\t\t\tproperty.Key, _ = p.visitExprInOut(property.Key, exprIn{\n\t\t\t\t\tshouldMangleStringsAsProps: true,\n\t\t\t\t})\n\t\t\t}\n\t\t\tp.visitBinding(property.Value, opts)\n\t\t\tif property.DefaultValueOrNil.Data != nil {\n\t\t\t\t// Propagate the name to keep from the binding into the initializer\n\t\t\t\tif id, ok := property.Value.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\t\tp.nameToKeep = p.symbols[id.Ref.InnerIndex].OriginalName\n\t\t\t\t\tp.nameToKeepIsFor = property.DefaultValueOrNil.Data\n\t\t\t\t}\n\n\t\t\t\tproperty.DefaultValueOrNil = p.visitExpr(property.DefaultValueOrNil)\n\t\t\t}\n\t\t\tb.Properties[i] = property\n\t\t}\n\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\nfunc stmtCaresAboutScope(stmt js_ast.Stmt) bool {\n\tswitch s := stmt.Data.(type) {\n\tcase *js_ast.SBlock, *js_ast.SEmpty, *js_ast.SDebugger, *js_ast.SExpr, *js_ast.SIf,\n\t\t*js_ast.SFor, *js_ast.SForIn, *js_ast.SForOf, *js_ast.SDoWhile, *js_ast.SWhile,\n\t\t*js_ast.SWith, *js_ast.STry, *js_ast.SSwitch, *js_ast.SReturn, *js_ast.SThrow,\n\t\t*js_ast.SBreak, *js_ast.SContinue, *js_ast.SDirective, *js_ast.SLabel:\n\t\treturn false\n\n\tcase *js_ast.SLocal:\n\t\treturn s.Kind != js_ast.LocalVar\n\n\tdefault:\n\t\treturn true\n\t}\n}\n\nfunc stmtsCareAboutScope(stmts []js_ast.Stmt) bool {\n\tfor _, stmt := range stmts {\n\t\tif stmtCaresAboutScope(stmt) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc dropFirstStatement(body js_ast.Stmt, replaceOrNil js_ast.Stmt) js_ast.Stmt {\n\tif block, ok := body.Data.(*js_ast.SBlock); ok && len(block.Stmts) > 0 {\n\t\tif replaceOrNil.Data != nil {\n\t\t\tblock.Stmts[0] = replaceOrNil\n\t\t} else if len(block.Stmts) == 2 && !stmtCaresAboutScope(block.Stmts[1]) {\n\t\t\treturn block.Stmts[1]\n\t\t} else {\n\t\t\tblock.Stmts = block.Stmts[1:]\n\t\t}\n\t\treturn body\n\t}\n\tif replaceOrNil.Data != nil {\n\t\treturn replaceOrNil\n\t}\n\treturn js_ast.Stmt{Loc: body.Loc, Data: js_ast.SEmptyShared}\n}\n\nfunc mangleFor(s *js_ast.SFor) {\n\t// Get the first statement in the loop\n\tfirst := s.Body\n\tif block, ok := first.Data.(*js_ast.SBlock); ok && len(block.Stmts) > 0 {\n\t\tfirst = block.Stmts[0]\n\t}\n\n\tif ifS, ok := first.Data.(*js_ast.SIf); ok {\n\t\t// \"for (;;) if (x) break;\" => \"for (; !x;) ;\"\n\t\t// \"for (; a;) if (x) break;\" => \"for (; a && !x;) ;\"\n\t\t// \"for (;;) if (x) break; else y();\" => \"for (; !x;) y();\"\n\t\t// \"for (; a;) if (x) break; else y();\" => \"for (; a && !x;) y();\"\n\t\tif breakS, ok := ifS.Yes.Data.(*js_ast.SBreak); ok && breakS.Label == nil {\n\t\t\tvar not js_ast.Expr\n\t\t\tif unary, ok := ifS.Test.Data.(*js_ast.EUnary); ok && unary.Op == js_ast.UnOpNot {\n\t\t\t\tnot = unary.Value\n\t\t\t} else {\n\t\t\t\tnot = js_ast.Not(ifS.Test)\n\t\t\t}\n\t\t\tif s.TestOrNil.Data != nil {\n\t\t\t\ts.TestOrNil = js_ast.Expr{Loc: s.TestOrNil.Loc, Data: &js_ast.EBinary{\n\t\t\t\t\tOp:    js_ast.BinOpLogicalAnd,\n\t\t\t\t\tLeft:  s.TestOrNil,\n\t\t\t\t\tRight: not,\n\t\t\t\t}}\n\t\t\t} else {\n\t\t\t\ts.TestOrNil = not\n\t\t\t}\n\t\t\ts.Body = dropFirstStatement(s.Body, ifS.NoOrNil)\n\t\t\treturn\n\t\t}\n\n\t\t// \"for (;;) if (x) y(); else break;\" => \"for (; x;) y();\"\n\t\t// \"for (; a;) if (x) y(); else break;\" => \"for (; a && x;) y();\"\n\t\tif ifS.NoOrNil.Data != nil {\n\t\t\tif breakS, ok := ifS.NoOrNil.Data.(*js_ast.SBreak); ok && breakS.Label == nil {\n\t\t\t\tif s.TestOrNil.Data != nil {\n\t\t\t\t\ts.TestOrNil = js_ast.Expr{Loc: s.TestOrNil.Loc, Data: &js_ast.EBinary{\n\t\t\t\t\t\tOp:    js_ast.BinOpLogicalAnd,\n\t\t\t\t\t\tLeft:  s.TestOrNil,\n\t\t\t\t\t\tRight: ifS.Test,\n\t\t\t\t\t}}\n\t\t\t\t} else {\n\t\t\t\t\ts.TestOrNil = ifS.Test\n\t\t\t\t}\n\t\t\t\ts.Body = dropFirstStatement(s.Body, ifS.Yes)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc appendIfOrLabelBodyPreservingScope(stmts []js_ast.Stmt, body js_ast.Stmt) []js_ast.Stmt {\n\tif block, ok := body.Data.(*js_ast.SBlock); ok && !stmtsCareAboutScope(block.Stmts) {\n\t\treturn append(stmts, block.Stmts...)\n\t}\n\tif stmtCaresAboutScope(body) {\n\t\treturn append(stmts, js_ast.Stmt{Loc: body.Loc, Data: &js_ast.SBlock{Stmts: []js_ast.Stmt{body}}})\n\t}\n\treturn append(stmts, body)\n}\n\nfunc (p *parser) mangleIf(stmts []js_ast.Stmt, loc logger.Loc, s *js_ast.SIf) []js_ast.Stmt {\n\t// Constant folding using the test expression\n\tif boolean, sideEffects, ok := js_ast.ToBooleanWithSideEffects(s.Test.Data); ok {\n\t\tif boolean {\n\t\t\t// The test is truthy\n\t\t\tif s.NoOrNil.Data == nil || !shouldKeepStmtInDeadControlFlow(s.NoOrNil) {\n\t\t\t\t// We can drop the \"no\" branch\n\t\t\t\tif sideEffects == js_ast.CouldHaveSideEffects {\n\t\t\t\t\t// Keep the condition if it could have side effects (but is still known to be truthy)\n\t\t\t\t\tif test := p.astHelpers.SimplifyUnusedExpr(s.Test, p.options.unsupportedJSFeatures); test.Data != nil {\n\t\t\t\t\t\tstmts = append(stmts, js_ast.Stmt{Loc: s.Test.Loc, Data: &js_ast.SExpr{Value: test}})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn appendIfOrLabelBodyPreservingScope(stmts, s.Yes)\n\t\t\t} else {\n\t\t\t\t// We have to keep the \"no\" branch\n\t\t\t}\n\t\t} else {\n\t\t\t// The test is falsy\n\t\t\tif !shouldKeepStmtInDeadControlFlow(s.Yes) {\n\t\t\t\t// We can drop the \"yes\" branch\n\t\t\t\tif sideEffects == js_ast.CouldHaveSideEffects {\n\t\t\t\t\t// Keep the condition if it could have side effects (but is still known to be falsy)\n\t\t\t\t\tif test := p.astHelpers.SimplifyUnusedExpr(s.Test, p.options.unsupportedJSFeatures); test.Data != nil {\n\t\t\t\t\t\tstmts = append(stmts, js_ast.Stmt{Loc: s.Test.Loc, Data: &js_ast.SExpr{Value: test}})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif s.NoOrNil.Data == nil {\n\t\t\t\t\treturn stmts\n\t\t\t\t}\n\t\t\t\treturn appendIfOrLabelBodyPreservingScope(stmts, s.NoOrNil)\n\t\t\t} else {\n\t\t\t\t// We have to keep the \"yes\" branch\n\t\t\t}\n\t\t}\n\n\t\t// Use \"1\" and \"0\" instead of \"true\" and \"false\" to be shorter\n\t\tif sideEffects == js_ast.NoSideEffects {\n\t\t\tif boolean {\n\t\t\t\ts.Test.Data = &js_ast.ENumber{Value: 1}\n\t\t\t} else {\n\t\t\t\ts.Test.Data = &js_ast.ENumber{Value: 0}\n\t\t\t}\n\t\t}\n\t}\n\n\tvar expr js_ast.Expr\n\n\tif yes, ok := s.Yes.Data.(*js_ast.SExpr); ok {\n\t\t// \"yes\" is an expression\n\t\tif s.NoOrNil.Data == nil {\n\t\t\tif not, ok := s.Test.Data.(*js_ast.EUnary); ok && not.Op == js_ast.UnOpNot {\n\t\t\t\t// \"if (!a) b();\" => \"a || b();\"\n\t\t\t\texpr = js_ast.JoinWithLeftAssociativeOp(js_ast.BinOpLogicalOr, not.Value, yes.Value)\n\t\t\t} else {\n\t\t\t\t// \"if (a) b();\" => \"a && b();\"\n\t\t\t\texpr = js_ast.JoinWithLeftAssociativeOp(js_ast.BinOpLogicalAnd, s.Test, yes.Value)\n\t\t\t}\n\t\t} else if no, ok := s.NoOrNil.Data.(*js_ast.SExpr); ok {\n\t\t\t// \"if (a) b(); else c();\" => \"a ? b() : c();\"\n\t\t\texpr = p.astHelpers.MangleIfExpr(loc, &js_ast.EIf{\n\t\t\t\tTest: s.Test,\n\t\t\t\tYes:  yes.Value,\n\t\t\t\tNo:   no.Value,\n\t\t\t}, p.options.unsupportedJSFeatures)\n\t\t}\n\t} else if _, ok := s.Yes.Data.(*js_ast.SEmpty); ok {\n\t\t// \"yes\" is missing\n\t\tif s.NoOrNil.Data == nil {\n\t\t\t// \"yes\" and \"no\" are both missing\n\t\t\tif p.astHelpers.ExprCanBeRemovedIfUnused(s.Test) {\n\t\t\t\t// \"if (1) {}\" => \"\"\n\t\t\t\treturn stmts\n\t\t\t} else {\n\t\t\t\t// \"if (a) {}\" => \"a;\"\n\t\t\t\texpr = s.Test\n\t\t\t}\n\t\t} else if no, ok := s.NoOrNil.Data.(*js_ast.SExpr); ok {\n\t\t\tif not, ok := s.Test.Data.(*js_ast.EUnary); ok && not.Op == js_ast.UnOpNot {\n\t\t\t\t// \"if (!a) {} else b();\" => \"a && b();\"\n\t\t\t\texpr = js_ast.JoinWithLeftAssociativeOp(js_ast.BinOpLogicalAnd, not.Value, no.Value)\n\t\t\t} else {\n\t\t\t\t// \"if (a) {} else b();\" => \"a || b();\"\n\t\t\t\texpr = js_ast.JoinWithLeftAssociativeOp(js_ast.BinOpLogicalOr, s.Test, no.Value)\n\t\t\t}\n\t\t} else {\n\t\t\t// \"yes\" is missing and \"no\" is not missing (and is not an expression)\n\t\t\tif not, ok := s.Test.Data.(*js_ast.EUnary); ok && not.Op == js_ast.UnOpNot {\n\t\t\t\t// \"if (!a) {} else throw b;\" => \"if (a) throw b;\"\n\t\t\t\ts.Test = not.Value\n\t\t\t\ts.Yes = s.NoOrNil\n\t\t\t\ts.NoOrNil = js_ast.Stmt{}\n\t\t\t} else {\n\t\t\t\t// \"if (a) {} else throw b;\" => \"if (!a) throw b;\"\n\t\t\t\ts.Test = js_ast.Not(s.Test)\n\t\t\t\ts.Yes = s.NoOrNil\n\t\t\t\ts.NoOrNil = js_ast.Stmt{}\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// \"yes\" is not missing (and is not an expression)\n\t\tif s.NoOrNil.Data != nil {\n\t\t\t// \"yes\" is not missing (and is not an expression) and \"no\" is not missing\n\t\t\tif not, ok := s.Test.Data.(*js_ast.EUnary); ok && not.Op == js_ast.UnOpNot {\n\t\t\t\t// \"if (!a) return b; else return c;\" => \"if (a) return c; else return b;\"\n\t\t\t\ts.Test = not.Value\n\t\t\t\ts.Yes, s.NoOrNil = s.NoOrNil, s.Yes\n\t\t\t}\n\t\t} else {\n\t\t\t// \"no\" is missing\n\t\t\tif s2, ok := s.Yes.Data.(*js_ast.SIf); ok && s2.NoOrNil.Data == nil {\n\t\t\t\t// \"if (a) if (b) return c;\" => \"if (a && b) return c;\"\n\t\t\t\ts.Test = js_ast.JoinWithLeftAssociativeOp(js_ast.BinOpLogicalAnd, s.Test, s2.Test)\n\t\t\t\ts.Yes = s2.Yes\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return an expression if we replaced the if statement with an expression above\n\tif expr.Data != nil {\n\t\texpr = p.astHelpers.SimplifyUnusedExpr(expr, p.options.unsupportedJSFeatures)\n\t\treturn append(stmts, js_ast.Stmt{Loc: loc, Data: &js_ast.SExpr{Value: expr}})\n\t}\n\n\treturn append(stmts, js_ast.Stmt{Loc: loc, Data: s})\n}\n\nfunc (p *parser) keepExprSymbolName(value js_ast.Expr, name string) js_ast.Expr {\n\tvalue = p.callRuntime(value.Loc, \"__name\", []js_ast.Expr{value,\n\t\t{Loc: value.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(name)}},\n\t})\n\n\t// Make sure tree shaking removes this if the function is never used\n\tvalue.Data.(*js_ast.ECall).CanBeUnwrappedIfUnused = true\n\treturn value\n}\n\nfunc (p *parser) keepClassOrFnSymbolName(loc logger.Loc, expr js_ast.Expr, name string) js_ast.Stmt {\n\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SExpr{\n\t\tValue: p.callRuntime(loc, \"__name\", []js_ast.Expr{\n\t\t\texpr,\n\t\t\t{Loc: loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(name)}},\n\t\t}),\n\t\tIsFromClassOrFnThatCanBeRemovedIfUnused: true,\n\t}}\n}\n\nfunc (p *parser) visitAndAppendStmt(stmts []js_ast.Stmt, stmt js_ast.Stmt) []js_ast.Stmt {\n\t// By default any statement ends the const local prefix\n\twasAfterAfterConstLocalPrefix := p.currentScope.IsAfterConstLocalPrefix\n\tp.currentScope.IsAfterConstLocalPrefix = true\n\n\tswitch s := stmt.Data.(type) {\n\tcase *js_ast.SEmpty, *js_ast.SComment:\n\t\t// Comments do not end the const local prefix\n\t\tp.currentScope.IsAfterConstLocalPrefix = wasAfterAfterConstLocalPrefix\n\n\tcase *js_ast.SDebugger:\n\t\t// Debugger statements do not end the const local prefix\n\t\tp.currentScope.IsAfterConstLocalPrefix = wasAfterAfterConstLocalPrefix\n\n\t\tif p.options.dropDebugger {\n\t\t\treturn stmts\n\t\t}\n\n\tcase *js_ast.STypeScript:\n\t\t// Type annotations do not end the const local prefix\n\t\tp.currentScope.IsAfterConstLocalPrefix = wasAfterAfterConstLocalPrefix\n\n\t\t// Erase TypeScript constructs from the output completely\n\t\treturn stmts\n\n\tcase *js_ast.SDirective:\n\t\t// Directives do not end the const local prefix\n\t\tp.currentScope.IsAfterConstLocalPrefix = wasAfterAfterConstLocalPrefix\n\n\t\tif p.isStrictMode() && s.LegacyOctalLoc.Start > 0 {\n\t\t\tp.markStrictModeFeature(legacyOctalEscape, p.source.RangeOfLegacyOctalEscape(s.LegacyOctalLoc), \"\")\n\t\t}\n\n\tcase *js_ast.SImport:\n\t\tp.recordDeclaredSymbol(s.NamespaceRef)\n\n\t\tif s.DefaultName != nil {\n\t\t\tp.recordDeclaredSymbol(s.DefaultName.Ref)\n\t\t}\n\n\t\tif s.Items != nil {\n\t\t\tfor _, item := range *s.Items {\n\t\t\t\tp.recordDeclaredSymbol(item.Name.Ref)\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.SExportClause:\n\t\t// \"export {foo}\"\n\t\tend := 0\n\t\tfor _, item := range s.Items {\n\t\t\tname := p.loadNameFromRef(item.Name.Ref)\n\t\t\tref := p.findSymbol(item.AliasLoc, name).ref\n\n\t\t\tif p.symbols[ref.InnerIndex].Kind == ast.SymbolUnbound {\n\t\t\t\t// Silently strip exports of non-local symbols in TypeScript, since\n\t\t\t\t// those likely correspond to type-only exports. But report exports of\n\t\t\t\t// non-local symbols as errors in JavaScript.\n\t\t\t\tif !p.options.ts.Parse {\n\t\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, item.Name.Loc)\n\t\t\t\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\"%q is not declared in this file\", name))\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\titem.Name.Ref = ref\n\t\t\ts.Items[end] = item\n\t\t\tend++\n\t\t}\n\n\t\t// Note: do not remove empty export statements since TypeScript uses them as module markers\n\t\ts.Items = s.Items[:end]\n\n\tcase *js_ast.SExportFrom:\n\t\t// \"export {foo} from 'path'\"\n\t\tname := p.loadNameFromRef(s.NamespaceRef)\n\t\ts.NamespaceRef = p.newSymbol(ast.SymbolOther, name)\n\t\tp.currentScope.Generated = append(p.currentScope.Generated, s.NamespaceRef)\n\t\tp.recordDeclaredSymbol(s.NamespaceRef)\n\n\t\t// This is a re-export and the symbols created here are used to reference\n\t\t// names in another file. This means the symbols are really aliases.\n\t\tfor i, item := range s.Items {\n\t\t\tname := p.loadNameFromRef(item.Name.Ref)\n\t\t\tref := p.newSymbol(ast.SymbolOther, name)\n\t\t\tp.currentScope.Generated = append(p.currentScope.Generated, ref)\n\t\t\tp.recordDeclaredSymbol(ref)\n\t\t\ts.Items[i].Name.Ref = ref\n\t\t}\n\n\tcase *js_ast.SExportStar:\n\t\t// \"export * from 'path'\"\n\t\t// \"export * as ns from 'path'\"\n\t\tname := p.loadNameFromRef(s.NamespaceRef)\n\t\ts.NamespaceRef = p.newSymbol(ast.SymbolOther, name)\n\t\tp.currentScope.Generated = append(p.currentScope.Generated, s.NamespaceRef)\n\t\tp.recordDeclaredSymbol(s.NamespaceRef)\n\n\t\t// \"export * as ns from 'path'\"\n\t\tif s.Alias != nil {\n\t\t\t// \"import * as ns from 'path'\"\n\t\t\t// \"export {ns}\"\n\t\t\tif p.options.unsupportedJSFeatures.Has(compat.ExportStarAs) {\n\t\t\t\tp.recordUsage(s.NamespaceRef)\n\t\t\t\treturn append(stmts,\n\t\t\t\t\tjs_ast.Stmt{Loc: stmt.Loc, Data: &js_ast.SImport{\n\t\t\t\t\t\tNamespaceRef:      s.NamespaceRef,\n\t\t\t\t\t\tStarNameLoc:       &s.Alias.Loc,\n\t\t\t\t\t\tImportRecordIndex: s.ImportRecordIndex,\n\t\t\t\t\t}},\n\t\t\t\t\tjs_ast.Stmt{Loc: stmt.Loc, Data: &js_ast.SExportClause{\n\t\t\t\t\t\tItems: []js_ast.ClauseItem{{\n\t\t\t\t\t\t\tAlias:        s.Alias.OriginalName,\n\t\t\t\t\t\t\tOriginalName: s.Alias.OriginalName,\n\t\t\t\t\t\t\tAliasLoc:     s.Alias.Loc,\n\t\t\t\t\t\t\tName:         ast.LocRef{Loc: s.Alias.Loc, Ref: s.NamespaceRef},\n\t\t\t\t\t\t}},\n\t\t\t\t\t\tIsSingleLine: true,\n\t\t\t\t\t}},\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.SExportDefault:\n\t\tp.recordDeclaredSymbol(s.DefaultName.Ref)\n\n\t\tswitch s2 := s.Value.Data.(type) {\n\t\tcase *js_ast.SExpr:\n\t\t\t// Propagate the name to keep from the export into the value\n\t\t\tp.nameToKeep = \"default\"\n\t\t\tp.nameToKeepIsFor = s2.Value.Data\n\n\t\t\ts2.Value = p.visitExpr(s2.Value)\n\n\t\t\t// Discard type-only export default statements\n\t\t\tif p.options.ts.Parse {\n\t\t\t\tif id, ok := s2.Value.Data.(*js_ast.EIdentifier); ok {\n\t\t\t\t\tsymbol := p.symbols[id.Ref.InnerIndex]\n\t\t\t\t\tif symbol.Kind == ast.SymbolUnbound && p.localTypeNames[symbol.OriginalName] {\n\t\t\t\t\t\treturn stmts\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If there are lowered \"using\" declarations, change this into a \"var\"\n\t\t\tif p.currentScope.Parent == nil && p.willWrapModuleInTryCatchForUsing {\n\t\t\t\tstmts = append(stmts,\n\t\t\t\t\tjs_ast.Stmt{Loc: stmt.Loc, Data: &js_ast.SLocal{\n\t\t\t\t\t\tDecls: []js_ast.Decl{{\n\t\t\t\t\t\t\tBinding:    js_ast.Binding{Loc: s.DefaultName.Loc, Data: &js_ast.BIdentifier{Ref: s.DefaultName.Ref}},\n\t\t\t\t\t\t\tValueOrNil: s2.Value,\n\t\t\t\t\t\t}},\n\t\t\t\t\t}},\n\t\t\t\t\tjs_ast.Stmt{Loc: stmt.Loc, Data: &js_ast.SExportClause{Items: []js_ast.ClauseItem{{\n\t\t\t\t\t\tAlias:    \"default\",\n\t\t\t\t\t\tAliasLoc: s.DefaultName.Loc,\n\t\t\t\t\t\tName:     s.DefaultName,\n\t\t\t\t\t}}}},\n\t\t\t\t)\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tstmts = append(stmts, stmt)\n\n\t\tcase *js_ast.SFunction:\n\t\t\t// If we need to preserve the name but there is no name, generate a name\n\t\t\tvar name string\n\t\t\tif p.options.keepNames {\n\t\t\t\tif s2.Fn.Name == nil {\n\t\t\t\t\tclone := s.DefaultName\n\t\t\t\t\ts2.Fn.Name = &clone\n\t\t\t\t\tname = \"default\"\n\t\t\t\t} else {\n\t\t\t\t\tname = p.symbols[s2.Fn.Name.Ref.InnerIndex].OriginalName\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.visitFn(&s2.Fn, s2.Fn.OpenParenLoc, visitFnOpts{})\n\t\t\tstmts = append(stmts, stmt)\n\n\t\t\t// Optionally preserve the name\n\t\t\tif p.options.keepNames {\n\t\t\t\tp.symbols[s2.Fn.Name.Ref.InnerIndex].Flags |= ast.DidKeepName\n\t\t\t\tfn := js_ast.Expr{Loc: s2.Fn.Name.Loc, Data: &js_ast.EIdentifier{Ref: s2.Fn.Name.Ref}}\n\t\t\t\tstmts = append(stmts, p.keepClassOrFnSymbolName(s2.Fn.Name.Loc, fn, name))\n\t\t\t}\n\n\t\tcase *js_ast.SClass:\n\t\t\tresult := p.visitClass(s.Value.Loc, &s2.Class, s.DefaultName.Ref, \"default\")\n\n\t\t\t// Lower class field syntax for browsers that don't support it\n\t\t\tclassStmts, _ := p.lowerClass(stmt, js_ast.Expr{}, result, \"\")\n\n\t\t\t// Remember if the class was side-effect free before lowering\n\t\t\tif result.canBeRemovedIfUnused {\n\t\t\t\tfor _, classStmt := range classStmts {\n\t\t\t\t\tif s2, ok := classStmt.Data.(*js_ast.SExpr); ok {\n\t\t\t\t\t\ts2.IsFromClassOrFnThatCanBeRemovedIfUnused = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tstmts = append(stmts, classStmts...)\n\n\t\tdefault:\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\n\t\t// Use a more friendly name than \"default\" now that \"--keep-names\" has\n\t\t// been applied and has made sure to enforce the name \"default\"\n\t\tif p.symbols[s.DefaultName.Ref.InnerIndex].OriginalName == \"default\" {\n\t\t\tp.symbols[s.DefaultName.Ref.InnerIndex].OriginalName = p.source.IdentifierName + \"_default\"\n\t\t}\n\n\t\treturn stmts\n\n\tcase *js_ast.SExportEquals:\n\t\t// \"module.exports = value\"\n\t\tstmts = append(stmts, js_ast.AssignStmt(\n\t\t\tjs_ast.Expr{Loc: stmt.Loc, Data: &js_ast.EDot{\n\t\t\t\tTarget:  js_ast.Expr{Loc: stmt.Loc, Data: &js_ast.EIdentifier{Ref: p.moduleRef}},\n\t\t\t\tName:    \"exports\",\n\t\t\t\tNameLoc: stmt.Loc,\n\t\t\t}},\n\t\t\tp.visitExpr(s.Value),\n\t\t))\n\t\tp.recordUsage(p.moduleRef)\n\t\treturn stmts\n\n\tcase *js_ast.SBreak:\n\t\tif s.Label != nil {\n\t\t\tname := p.loadNameFromRef(s.Label.Ref)\n\t\t\ts.Label.Ref, _, _ = p.findLabelSymbol(s.Label.Loc, name)\n\t\t} else if !p.fnOrArrowDataVisit.isInsideLoop && !p.fnOrArrowDataVisit.isInsideSwitch {\n\t\t\tr := js_lexer.RangeOfIdentifier(p.source, stmt.Loc)\n\t\t\tp.log.AddError(&p.tracker, r, \"Cannot use \\\"break\\\" here:\")\n\t\t}\n\n\tcase *js_ast.SContinue:\n\t\tif s.Label != nil {\n\t\t\tname := p.loadNameFromRef(s.Label.Ref)\n\t\t\tvar isLoop, ok bool\n\t\t\ts.Label.Ref, isLoop, ok = p.findLabelSymbol(s.Label.Loc, name)\n\t\t\tif ok && !isLoop {\n\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, s.Label.Loc)\n\t\t\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\"Cannot continue to label \\\"%s\\\"\", name))\n\t\t\t}\n\t\t} else if !p.fnOrArrowDataVisit.isInsideLoop {\n\t\t\tr := js_lexer.RangeOfIdentifier(p.source, stmt.Loc)\n\t\t\tp.log.AddError(&p.tracker, r, \"Cannot use \\\"continue\\\" here:\")\n\t\t}\n\n\tcase *js_ast.SLabel:\n\t\t// Forbid functions inside labels in strict mode\n\t\tif p.isStrictMode() {\n\t\t\tif _, ok := s.Stmt.Data.(*js_ast.SFunction); ok {\n\t\t\t\tp.markStrictModeFeature(labelFunctionStmt, js_lexer.RangeOfIdentifier(p.source, s.Stmt.Loc), \"\")\n\t\t\t}\n\t\t}\n\n\t\tp.pushScopeForVisitPass(js_ast.ScopeLabel, stmt.Loc)\n\t\tname := p.loadNameFromRef(s.Name.Ref)\n\t\tif js_lexer.StrictModeReservedWords[name] {\n\t\t\tp.markStrictModeFeature(reservedWord, js_lexer.RangeOfIdentifier(p.source, s.Name.Loc), name)\n\t\t}\n\t\tref := p.newSymbol(ast.SymbolLabel, name)\n\t\ts.Name.Ref = ref\n\n\t\t// Duplicate labels are an error\n\t\tfor scope := p.currentScope.Parent; scope != nil; scope = scope.Parent {\n\t\t\tif scope.Label.Ref != ast.InvalidRef && name == p.symbols[scope.Label.Ref.InnerIndex].OriginalName {\n\t\t\t\tp.log.AddErrorWithNotes(&p.tracker, js_lexer.RangeOfIdentifier(p.source, s.Name.Loc),\n\t\t\t\t\tfmt.Sprintf(\"Duplicate label %q\", name),\n\t\t\t\t\t[]logger.MsgData{p.tracker.MsgData(js_lexer.RangeOfIdentifier(p.source, scope.Label.Loc),\n\t\t\t\t\t\tfmt.Sprintf(\"The original label %q is here:\", name))})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif scope.Kind == js_ast.ScopeFunctionBody {\n\t\t\t\t// Labels are only visible within the function they are defined in.\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tp.currentScope.Label = ast.LocRef{Loc: s.Name.Loc, Ref: ref}\n\t\tswitch s.Stmt.Data.(type) {\n\t\tcase *js_ast.SFor, *js_ast.SForIn, *js_ast.SForOf, *js_ast.SWhile, *js_ast.SDoWhile:\n\t\t\tp.currentScope.LabelStmtIsLoop = true\n\t\t}\n\n\t\t// If we're dropping this statement, consider control flow to be dead\n\t\t_, shouldDropLabel := p.dropLabelsMap[name]\n\t\told := p.isControlFlowDead\n\t\tif shouldDropLabel {\n\t\t\tp.isControlFlowDead = true\n\t\t}\n\n\t\ts.Stmt = p.visitSingleStmt(s.Stmt, stmtsNormal)\n\t\tp.popScope()\n\n\t\t// Drop this entire statement if requested\n\t\tif shouldDropLabel {\n\t\t\tp.isControlFlowDead = old\n\t\t\treturn stmts\n\t\t}\n\n\t\tif p.options.minifySyntax {\n\t\t\t// Optimize \"x: break x\" which some people apparently write by hand\n\t\t\tif child, ok := s.Stmt.Data.(*js_ast.SBreak); ok && child.Label != nil && child.Label.Ref == s.Name.Ref {\n\t\t\t\treturn stmts\n\t\t\t}\n\n\t\t\t// Remove the label if it's not necessary\n\t\t\tif p.symbols[ref.InnerIndex].UseCountEstimate == 0 {\n\t\t\t\treturn appendIfOrLabelBodyPreservingScope(stmts, s.Stmt)\n\t\t\t}\n\t\t}\n\n\t\t// Handle \"for await\" that has been lowered by moving this label inside the \"try\"\n\t\tif try, ok := s.Stmt.Data.(*js_ast.STry); ok && len(try.Block.Stmts) == 1 {\n\t\t\tif loop, ok := try.Block.Stmts[0].Data.(*js_ast.SFor); ok && loop.IsLoweredForAwait {\n\t\t\t\ttry.Block.Stmts[0] = js_ast.Stmt{Loc: stmt.Loc, Data: &js_ast.SLabel{\n\t\t\t\t\tStmt:             try.Block.Stmts[0],\n\t\t\t\t\tName:             s.Name,\n\t\t\t\t\tIsSingleLineStmt: s.IsSingleLineStmt,\n\t\t\t\t}}\n\t\t\t\treturn append(stmts, s.Stmt)\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.SLocal:\n\t\t// Silently remove unsupported top-level \"await\" in dead code branches\n\t\tif s.Kind == js_ast.LocalAwaitUsing && p.fnOrArrowDataVisit.isOutsideFnOrArrow {\n\t\t\tif p.isControlFlowDead && (p.options.unsupportedJSFeatures.Has(compat.TopLevelAwait) || !p.options.outputFormat.KeepESMImportExportSyntax()) {\n\t\t\t\ts.Kind = js_ast.LocalUsing\n\t\t\t} else {\n\t\t\t\tp.liveTopLevelAwaitKeyword = logger.Range{Loc: stmt.Loc, Len: 5}\n\t\t\t\tp.markSyntaxFeature(compat.TopLevelAwait, logger.Range{Loc: stmt.Loc, Len: 5})\n\t\t\t}\n\t\t}\n\n\t\t// Local statements do not end the const local prefix\n\t\tp.currentScope.IsAfterConstLocalPrefix = wasAfterAfterConstLocalPrefix\n\n\t\tfor i := range s.Decls {\n\t\t\td := &s.Decls[i]\n\t\t\tp.visitBinding(d.Binding, bindingOpts{})\n\n\t\t\t// Visit the initializer\n\t\t\tif d.ValueOrNil.Data != nil {\n\t\t\t\t// Fold numeric constants in the initializer\n\t\t\t\toldShouldFoldTypeScriptConstantExpressions := p.shouldFoldTypeScriptConstantExpressions\n\t\t\t\tp.shouldFoldTypeScriptConstantExpressions = p.options.minifySyntax && !p.currentScope.IsAfterConstLocalPrefix\n\n\t\t\t\t// Propagate the name to keep from the binding into the initializer\n\t\t\t\tif id, ok := d.Binding.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\t\tp.nameToKeep = p.symbols[id.Ref.InnerIndex].OriginalName\n\t\t\t\t\tp.nameToKeepIsFor = d.ValueOrNil.Data\n\t\t\t\t}\n\n\t\t\t\td.ValueOrNil = p.visitExpr(d.ValueOrNil)\n\n\t\t\t\tp.shouldFoldTypeScriptConstantExpressions = oldShouldFoldTypeScriptConstantExpressions\n\n\t\t\t\t// Initializing to undefined is implicit, but be careful to not\n\t\t\t\t// accidentally cause a syntax error or behavior change by removing\n\t\t\t\t// the value\n\t\t\t\t//\n\t\t\t\t// Good:\n\t\t\t\t//   \"let a = undefined;\" => \"let a;\"\n\t\t\t\t//\n\t\t\t\t// Bad (a syntax error):\n\t\t\t\t//   \"let {} = undefined;\" => \"let {};\"\n\t\t\t\t//\n\t\t\t\t// Bad (a behavior change):\n\t\t\t\t//   \"a = 123; var a = undefined;\" => \"a = 123; var a;\"\n\t\t\t\t//\n\t\t\t\tif p.options.minifySyntax && s.Kind == js_ast.LocalLet {\n\t\t\t\t\tif _, ok := d.Binding.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\t\t\tif _, ok := d.ValueOrNil.Data.(*js_ast.EUndefined); ok {\n\t\t\t\t\t\t\td.ValueOrNil = js_ast.Expr{}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Yarn's PnP data may be stored in a variable: https://github.com/yarnpkg/berry/pull/4320\n\t\t\t\tif p.options.decodeHydrateRuntimeStateYarnPnP {\n\t\t\t\t\tif str, ok := d.ValueOrNil.Data.(*js_ast.EString); ok {\n\t\t\t\t\t\tif id, ok := d.Binding.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\t\t\t\tif p.stringLocalsForYarnPnP == nil {\n\t\t\t\t\t\t\t\tp.stringLocalsForYarnPnP = make(map[ast.Ref]stringLocalForYarnPnP)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tp.stringLocalsForYarnPnP[id.Ref] = stringLocalForYarnPnP{value: str.Value, loc: d.ValueOrNil.Loc}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Attempt to continue the const local prefix\n\t\t\tif p.options.minifySyntax && !p.currentScope.IsAfterConstLocalPrefix {\n\t\t\t\tif id, ok := d.Binding.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\t\tif s.Kind == js_ast.LocalConst && d.ValueOrNil.Data != nil {\n\t\t\t\t\t\tif value := js_ast.ExprToConstValue(d.ValueOrNil); value.Kind != js_ast.ConstValueNone {\n\t\t\t\t\t\t\tif p.constValues == nil {\n\t\t\t\t\t\t\t\tp.constValues = make(map[ast.Ref]js_ast.ConstValue)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tp.constValues[id.Ref] = value\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif d.ValueOrNil.Data != nil && !isSafeForConstLocalPrefix(d.ValueOrNil) {\n\t\t\t\t\t\tp.currentScope.IsAfterConstLocalPrefix = true\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// A non-identifier binding ends the const local prefix\n\t\t\t\t\tp.currentScope.IsAfterConstLocalPrefix = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Handle being exported inside a namespace\n\t\tif s.IsExport && p.enclosingNamespaceArgRef != nil {\n\t\t\twrapIdentifier := func(loc logger.Loc, ref ast.Ref) js_ast.Expr {\n\t\t\t\tp.recordUsage(*p.enclosingNamespaceArgRef)\n\t\t\t\treturn js_ast.Expr{Loc: loc, Data: p.dotOrMangledPropVisit(\n\t\t\t\t\tjs_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: *p.enclosingNamespaceArgRef}},\n\t\t\t\t\tp.symbols[ref.InnerIndex].OriginalName,\n\t\t\t\t\tloc,\n\t\t\t\t)}\n\t\t\t}\n\t\t\tfor _, decl := range s.Decls {\n\t\t\t\tif decl.ValueOrNil.Data != nil {\n\t\t\t\t\ttarget := js_ast.ConvertBindingToExpr(decl.Binding, wrapIdentifier)\n\t\t\t\t\tif result, ok := p.lowerAssign(target, decl.ValueOrNil, objRestReturnValueIsUnused); ok {\n\t\t\t\t\t\ttarget = result\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttarget = js_ast.Assign(target, decl.ValueOrNil)\n\t\t\t\t\t}\n\t\t\t\t\tstmts = append(stmts, js_ast.Stmt{Loc: stmt.Loc, Data: &js_ast.SExpr{Value: target}})\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn stmts\n\t\t}\n\n\t\ts.Decls = p.lowerObjectRestInDecls(s.Decls)\n\n\t\t// Optimization: Avoid unnecessary \"using\" machinery by changing ones\n\t\t// initialized to \"null\" or \"undefined\" into a normal variable. Note that\n\t\t// \"await using\" still needs the \"await\", so we can't do it for those.\n\t\tif p.options.minifySyntax && s.Kind == js_ast.LocalUsing {\n\t\t\ts.Kind = js_ast.LocalConst\n\t\t\tfor _, decl := range s.Decls {\n\t\t\t\tif t := js_ast.KnownPrimitiveType(decl.ValueOrNil.Data); t != js_ast.PrimitiveNull && t != js_ast.PrimitiveUndefined {\n\t\t\t\t\ts.Kind = js_ast.LocalUsing\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ts.Kind = p.selectLocalKind(s.Kind)\n\n\t\t// Potentially relocate \"var\" declarations to the top level\n\t\tif s.Kind == js_ast.LocalVar {\n\t\t\tif assign, ok := p.maybeRelocateVarsToTopLevel(s.Decls, relocateVarsNormal); ok {\n\t\t\t\tif assign.Data != nil {\n\t\t\t\t\tstmts = append(stmts, assign)\n\t\t\t\t}\n\t\t\t\treturn stmts\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.SExpr:\n\t\tshouldTrimUnsightlyPrimitives := !p.options.minifySyntax && !isUnsightlyPrimitive(s.Value.Data)\n\t\tp.stmtExprValue = s.Value.Data\n\t\ts.Value = p.visitExpr(s.Value)\n\n\t\t// Expressions that have been simplified down to a single primitive don't\n\t\t// have any effect, and are automatically removed during minification.\n\t\t// However, some people are really bothered by seeing them. Remove them\n\t\t// so we don't bother these people.\n\t\tif shouldTrimUnsightlyPrimitives && isUnsightlyPrimitive(s.Value.Data) {\n\t\t\treturn stmts\n\t\t}\n\n\tcase *js_ast.SThrow:\n\t\ts.Value = p.visitExpr(s.Value)\n\n\tcase *js_ast.SReturn:\n\t\t// Forbid top-level return inside modules with ECMAScript syntax\n\t\tif p.fnOrArrowDataVisit.isOutsideFnOrArrow {\n\t\t\tif p.isFileConsideredESM {\n\t\t\t\t_, notes := p.whyESModule()\n\t\t\t\tp.log.AddErrorWithNotes(&p.tracker, js_lexer.RangeOfIdentifier(p.source, stmt.Loc),\n\t\t\t\t\t\"Top-level return cannot be used inside an ECMAScript module\", notes)\n\t\t\t} else {\n\t\t\t\tp.hasTopLevelReturn = true\n\t\t\t}\n\t\t}\n\n\t\tif s.ValueOrNil.Data != nil {\n\t\t\ts.ValueOrNil = p.visitExpr(s.ValueOrNil)\n\n\t\t\t// Returning undefined is implicit except when inside an async generator\n\t\t\t// function, where \"return undefined\" behaves like \"return await undefined\"\n\t\t\t// but just \"return\" has no \"await\".\n\t\t\tif p.options.minifySyntax && (!p.fnOrArrowDataVisit.isAsync || !p.fnOrArrowDataVisit.isGenerator) {\n\t\t\t\tif _, ok := s.ValueOrNil.Data.(*js_ast.EUndefined); ok {\n\t\t\t\t\ts.ValueOrNil = js_ast.Expr{}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.SBlock:\n\t\tp.pushScopeForVisitPass(js_ast.ScopeBlock, stmt.Loc)\n\n\t\t// Pass the \"is loop body\" status on to the direct children of a block used\n\t\t// as a loop body. This is used to enable optimizations specific to the\n\t\t// topmost scope in a loop body block.\n\t\tif p.loopBody == s {\n\t\t\ts.Stmts = p.visitStmts(s.Stmts, stmtsLoopBody)\n\t\t} else {\n\t\t\ts.Stmts = p.visitStmts(s.Stmts, stmtsNormal)\n\t\t}\n\n\t\tp.popScope()\n\n\t\tif p.options.minifySyntax {\n\t\t\tif len(s.Stmts) == 1 && !stmtCaresAboutScope(s.Stmts[0]) {\n\t\t\t\t// Unwrap blocks containing a single statement\n\t\t\t\tstmt = s.Stmts[0]\n\t\t\t} else if len(s.Stmts) == 0 {\n\t\t\t\t// Trim empty blocks\n\t\t\t\tstmt = js_ast.Stmt{Loc: stmt.Loc, Data: js_ast.SEmptyShared}\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.SWith:\n\t\tp.markStrictModeFeature(withStatement, js_lexer.RangeOfIdentifier(p.source, stmt.Loc), \"\")\n\t\ts.Value = p.visitExpr(s.Value)\n\t\tp.pushScopeForVisitPass(js_ast.ScopeWith, s.BodyLoc)\n\t\ts.Body = p.visitSingleStmt(s.Body, stmtsNormal)\n\t\tp.popScope()\n\n\tcase *js_ast.SWhile:\n\t\ts.Test = p.visitExpr(s.Test)\n\t\ts.Body = p.visitLoopBody(s.Body)\n\n\t\tif p.options.minifySyntax {\n\t\t\ts.Test = p.astHelpers.SimplifyBooleanExpr(s.Test)\n\n\t\t\t// A true value is implied\n\t\t\ttestOrNil := s.Test\n\t\t\tif boolean, sideEffects, ok := js_ast.ToBooleanWithSideEffects(s.Test.Data); ok && boolean && sideEffects == js_ast.NoSideEffects {\n\t\t\t\ttestOrNil = js_ast.Expr{}\n\t\t\t}\n\n\t\t\t// \"while (a) {}\" => \"for (;a;) {}\"\n\t\t\tforS := &js_ast.SFor{TestOrNil: testOrNil, Body: s.Body, IsSingleLineBody: s.IsSingleLineBody}\n\t\t\tmangleFor(forS)\n\t\t\tstmt = js_ast.Stmt{Loc: stmt.Loc, Data: forS}\n\t\t}\n\n\tcase *js_ast.SDoWhile:\n\t\ts.Body = p.visitLoopBody(s.Body)\n\t\ts.Test = p.visitExpr(s.Test)\n\n\t\tif p.options.minifySyntax {\n\t\t\ts.Test = p.astHelpers.SimplifyBooleanExpr(s.Test)\n\t\t}\n\n\tcase *js_ast.SIf:\n\t\ts.Test = p.visitExpr(s.Test)\n\n\t\tif p.options.minifySyntax {\n\t\t\ts.Test = p.astHelpers.SimplifyBooleanExpr(s.Test)\n\t\t}\n\n\t\t// Fold constants\n\t\tboolean, _, ok := js_ast.ToBooleanWithSideEffects(s.Test.Data)\n\n\t\t// Mark the control flow as dead if the branch is never taken\n\t\tif ok && !boolean {\n\t\t\told := p.isControlFlowDead\n\t\t\tp.isControlFlowDead = true\n\t\t\ts.Yes = p.visitSingleStmt(s.Yes, stmtsNormal)\n\t\t\tp.isControlFlowDead = old\n\t\t} else {\n\t\t\ts.Yes = p.visitSingleStmt(s.Yes, stmtsNormal)\n\t\t}\n\n\t\t// The \"else\" clause is optional\n\t\tif s.NoOrNil.Data != nil {\n\t\t\t// Mark the control flow as dead if the branch is never taken\n\t\t\tif ok && boolean {\n\t\t\t\told := p.isControlFlowDead\n\t\t\t\tp.isControlFlowDead = true\n\t\t\t\ts.NoOrNil = p.visitSingleStmt(s.NoOrNil, stmtsNormal)\n\t\t\t\tp.isControlFlowDead = old\n\t\t\t} else {\n\t\t\t\ts.NoOrNil = p.visitSingleStmt(s.NoOrNil, stmtsNormal)\n\t\t\t}\n\n\t\t\t// Trim unnecessary \"else\" clauses\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tif _, ok := s.NoOrNil.Data.(*js_ast.SEmpty); ok {\n\t\t\t\t\ts.NoOrNil = js_ast.Stmt{}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif p.options.minifySyntax {\n\t\t\treturn p.mangleIf(stmts, stmt.Loc, s)\n\t\t}\n\n\tcase *js_ast.SFor:\n\t\tp.pushScopeForVisitPass(js_ast.ScopeBlock, stmt.Loc)\n\t\tif s.InitOrNil.Data != nil {\n\t\t\tp.visitForLoopInit(s.InitOrNil, false)\n\t\t}\n\n\t\tif s.TestOrNil.Data != nil {\n\t\t\ts.TestOrNil = p.visitExpr(s.TestOrNil)\n\n\t\t\tif p.options.minifySyntax {\n\t\t\t\ts.TestOrNil = p.astHelpers.SimplifyBooleanExpr(s.TestOrNil)\n\n\t\t\t\t// A true value is implied\n\t\t\t\tif boolean, sideEffects, ok := js_ast.ToBooleanWithSideEffects(s.TestOrNil.Data); ok && boolean && sideEffects == js_ast.NoSideEffects {\n\t\t\t\t\ts.TestOrNil = js_ast.Expr{}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif s.UpdateOrNil.Data != nil {\n\t\t\ts.UpdateOrNil = p.visitExpr(s.UpdateOrNil)\n\t\t}\n\t\ts.Body = p.visitLoopBody(s.Body)\n\n\t\t// Potentially relocate \"var\" declarations to the top level. Note that this\n\t\t// must be done inside the scope of the for loop or they won't be relocated.\n\t\tif s.InitOrNil.Data != nil {\n\t\t\tif init, ok := s.InitOrNil.Data.(*js_ast.SLocal); ok && init.Kind == js_ast.LocalVar {\n\t\t\t\tif assign, ok := p.maybeRelocateVarsToTopLevel(init.Decls, relocateVarsNormal); ok {\n\t\t\t\t\tif assign.Data != nil {\n\t\t\t\t\t\ts.InitOrNil = assign\n\t\t\t\t\t} else {\n\t\t\t\t\t\ts.InitOrNil = js_ast.Stmt{}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tp.popScope()\n\n\t\tif p.options.minifySyntax {\n\t\t\tmangleFor(s)\n\t\t}\n\n\tcase *js_ast.SForIn:\n\t\tp.pushScopeForVisitPass(js_ast.ScopeBlock, stmt.Loc)\n\t\tp.visitForLoopInit(s.Init, true)\n\t\ts.Value = p.visitExpr(s.Value)\n\t\ts.Body = p.visitLoopBody(s.Body)\n\n\t\t// Check for a variable initializer\n\t\tif local, ok := s.Init.Data.(*js_ast.SLocal); ok && local.Kind == js_ast.LocalVar && len(local.Decls) == 1 {\n\t\t\tdecl := &local.Decls[0]\n\t\t\tif id, ok := decl.Binding.Data.(*js_ast.BIdentifier); ok && decl.ValueOrNil.Data != nil {\n\t\t\t\tp.markStrictModeFeature(forInVarInit, p.source.RangeOfOperatorBefore(decl.ValueOrNil.Loc, \"=\"), \"\")\n\n\t\t\t\t// Lower for-in variable initializers in case the output is used in strict mode\n\t\t\t\tstmts = append(stmts, js_ast.Stmt{Loc: stmt.Loc, Data: &js_ast.SExpr{Value: js_ast.Assign(\n\t\t\t\t\tjs_ast.Expr{Loc: decl.Binding.Loc, Data: &js_ast.EIdentifier{Ref: id.Ref}},\n\t\t\t\t\tdecl.ValueOrNil,\n\t\t\t\t)}})\n\t\t\t\tdecl.ValueOrNil = js_ast.Expr{}\n\t\t\t}\n\t\t}\n\n\t\t// Potentially relocate \"var\" declarations to the top level. Note that this\n\t\t// must be done inside the scope of the for loop or they won't be relocated.\n\t\tif init, ok := s.Init.Data.(*js_ast.SLocal); ok && init.Kind == js_ast.LocalVar {\n\t\t\tif replacement, ok := p.maybeRelocateVarsToTopLevel(init.Decls, relocateVarsForInOrForOf); ok {\n\t\t\t\ts.Init = replacement\n\t\t\t}\n\t\t}\n\n\t\tp.popScope()\n\n\t\tp.lowerObjectRestInForLoopInit(s.Init, &s.Body)\n\n\tcase *js_ast.SForOf:\n\t\t// Silently remove unsupported top-level \"await\" in dead code branches\n\t\tif s.Await.Len > 0 && p.fnOrArrowDataVisit.isOutsideFnOrArrow {\n\t\t\tif p.isControlFlowDead && (p.options.unsupportedJSFeatures.Has(compat.TopLevelAwait) || !p.options.outputFormat.KeepESMImportExportSyntax()) {\n\t\t\t\ts.Await = logger.Range{}\n\t\t\t} else {\n\t\t\t\tp.liveTopLevelAwaitKeyword = s.Await\n\t\t\t\tp.markSyntaxFeature(compat.TopLevelAwait, s.Await)\n\t\t\t}\n\t\t}\n\n\t\tp.pushScopeForVisitPass(js_ast.ScopeBlock, stmt.Loc)\n\t\tp.visitForLoopInit(s.Init, true)\n\t\ts.Value = p.visitExpr(s.Value)\n\t\ts.Body = p.visitLoopBody(s.Body)\n\n\t\t// Potentially relocate \"var\" declarations to the top level. Note that this\n\t\t// must be done inside the scope of the for loop or they won't be relocated.\n\t\tif init, ok := s.Init.Data.(*js_ast.SLocal); ok && init.Kind == js_ast.LocalVar {\n\t\t\tif replacement, ok := p.maybeRelocateVarsToTopLevel(init.Decls, relocateVarsForInOrForOf); ok {\n\t\t\t\ts.Init = replacement\n\t\t\t}\n\t\t}\n\n\t\t// Handle \"for (using x of y)\" and \"for (await using x of y)\"\n\t\tif local, ok := s.Init.Data.(*js_ast.SLocal); ok {\n\t\t\tif local.Kind == js_ast.LocalUsing && p.options.unsupportedJSFeatures.Has(compat.Using) {\n\t\t\t\tp.lowerUsingDeclarationInForOf(s.Init.Loc, local, &s.Body)\n\t\t\t} else if local.Kind == js_ast.LocalAwaitUsing {\n\t\t\t\tif p.fnOrArrowDataVisit.isOutsideFnOrArrow {\n\t\t\t\t\tif p.isControlFlowDead && (p.options.unsupportedJSFeatures.Has(compat.TopLevelAwait) || !p.options.outputFormat.KeepESMImportExportSyntax()) {\n\t\t\t\t\t\t// Silently remove unsupported top-level \"await\" in dead code branches\n\t\t\t\t\t\tlocal.Kind = js_ast.LocalUsing\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.liveTopLevelAwaitKeyword = logger.Range{Loc: s.Init.Loc, Len: 5}\n\t\t\t\t\t\tp.markSyntaxFeature(compat.TopLevelAwait, p.liveTopLevelAwaitKeyword)\n\t\t\t\t\t}\n\t\t\t\t\tif p.options.unsupportedJSFeatures.Has(compat.Using) {\n\t\t\t\t\t\tp.lowerUsingDeclarationInForOf(s.Init.Loc, local, &s.Body)\n\t\t\t\t\t}\n\t\t\t\t} else if p.options.unsupportedJSFeatures.Has(compat.Using) || p.options.unsupportedJSFeatures.Has(compat.AsyncAwait) ||\n\t\t\t\t\t(p.options.unsupportedJSFeatures.Has(compat.AsyncGenerator) && p.fnOrArrowDataVisit.isGenerator) {\n\t\t\t\t\tp.lowerUsingDeclarationInForOf(s.Init.Loc, local, &s.Body)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tp.popScope()\n\n\t\tp.lowerObjectRestInForLoopInit(s.Init, &s.Body)\n\n\t\t// Lower \"for await\" if it's unsupported if it's in a lowered async generator\n\t\tif s.Await.Len > 0 && (p.options.unsupportedJSFeatures.Has(compat.ForAwait) ||\n\t\t\t(p.options.unsupportedJSFeatures.Has(compat.AsyncGenerator) && p.fnOrArrowDataVisit.isGenerator)) {\n\t\t\treturn p.lowerForAwaitLoop(stmt.Loc, s, stmts)\n\t\t}\n\n\tcase *js_ast.STry:\n\t\tp.pushScopeForVisitPass(js_ast.ScopeBlock, stmt.Loc)\n\t\tif p.fnOrArrowDataVisit.tryBodyCount == 0 {\n\t\t\tif s.Catch != nil {\n\t\t\t\tp.fnOrArrowDataVisit.tryCatchLoc = s.Catch.Loc\n\t\t\t} else {\n\t\t\t\tp.fnOrArrowDataVisit.tryCatchLoc = stmt.Loc\n\t\t\t}\n\t\t}\n\t\tp.fnOrArrowDataVisit.tryBodyCount++\n\t\ts.Block.Stmts = p.visitStmts(s.Block.Stmts, stmtsNormal)\n\t\tp.fnOrArrowDataVisit.tryBodyCount--\n\t\tp.popScope()\n\n\t\tif s.Catch != nil {\n\t\t\told := p.isControlFlowDead\n\n\t\t\t// If the try body is empty, then the catch body is dead\n\t\t\tif len(s.Block.Stmts) == 0 {\n\t\t\t\tp.isControlFlowDead = true\n\t\t\t}\n\n\t\t\tp.pushScopeForVisitPass(js_ast.ScopeCatchBinding, s.Catch.Loc)\n\t\t\tif s.Catch.BindingOrNil.Data != nil {\n\t\t\t\tp.visitBinding(s.Catch.BindingOrNil, bindingOpts{})\n\t\t\t}\n\n\t\t\tp.pushScopeForVisitPass(js_ast.ScopeBlock, s.Catch.BlockLoc)\n\t\t\ts.Catch.Block.Stmts = p.visitStmts(s.Catch.Block.Stmts, stmtsNormal)\n\t\t\tp.popScope()\n\n\t\t\tp.lowerObjectRestInCatchBinding(s.Catch)\n\t\t\tp.popScope()\n\n\t\t\tp.isControlFlowDead = old\n\t\t}\n\n\t\tif s.Finally != nil {\n\t\t\tp.pushScopeForVisitPass(js_ast.ScopeBlock, s.Finally.Loc)\n\t\t\ts.Finally.Block.Stmts = p.visitStmts(s.Finally.Block.Stmts, stmtsNormal)\n\t\t\tp.popScope()\n\t\t}\n\n\t\tif p.options.minifySyntax {\n\t\t\tif len(s.Block.Stmts) == 0 {\n\t\t\t\t// Try to drop the whole thing if the try body is empty\n\t\t\t\tkeepCatch := false\n\n\t\t\t\t// Certain \"catch\" blocks need to be preserved:\n\t\t\t\t//\n\t\t\t\t//   try {} catch { let foo } // Can be removed\n\t\t\t\t//   try {} catch { var foo } // Must be kept\n\t\t\t\t//\n\t\t\t\tif s.Catch != nil {\n\t\t\t\t\tfor _, stmt2 := range s.Catch.Block.Stmts {\n\t\t\t\t\t\tif shouldKeepStmtInDeadControlFlow(stmt2) {\n\t\t\t\t\t\t\tkeepCatch = true\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Make sure to preserve the \"finally\" block if present\n\t\t\t\tif !keepCatch {\n\t\t\t\t\tif s.Finally == nil {\n\t\t\t\t\t\treturn stmts\n\t\t\t\t\t}\n\t\t\t\t\tif !stmtsCareAboutScope(s.Finally.Block.Stmts) {\n\t\t\t\t\t\treturn append(stmts, s.Finally.Block.Stmts...)\n\t\t\t\t\t}\n\t\t\t\t\tblock := s.Finally.Block\n\t\t\t\t\tstmt = js_ast.Stmt{Loc: s.Finally.Loc, Data: &block}\n\t\t\t\t}\n\t\t\t} else if s.Finally != nil && len(s.Finally.Block.Stmts) == 0 {\n\t\t\t\tif s.Catch != nil {\n\t\t\t\t\t// Just remove the \"finally\" block if there's a \"catch\"\n\t\t\t\t\ts.Finally = nil\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, try to unwrap the whole \"try\" statement\n\t\t\t\t\tif !stmtsCareAboutScope(s.Block.Stmts) {\n\t\t\t\t\t\treturn append(stmts, s.Block.Stmts...)\n\t\t\t\t\t}\n\t\t\t\t\tblock := s.Block\n\t\t\t\t\tstmt = js_ast.Stmt{Loc: s.Finally.Loc, Data: &block}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.SSwitch:\n\t\ts.Test = p.visitExpr(s.Test)\n\t\tp.pushScopeForVisitPass(js_ast.ScopeBlock, s.BodyLoc)\n\t\toldIsInsideSwitch := p.fnOrArrowDataVisit.isInsideSwitch\n\t\tp.fnOrArrowDataVisit.isInsideSwitch = true\n\n\t\t// Disable const inlining in switch cases. They all share the same scope\n\t\t// and can be evaluated in an unusual order. For example:\n\t\t//\n\t\t//   // This should not become \"return 0\"\n\t\t//   switch (1) {\n\t\t//     case 0:\n\t\t//       const x = 0\n\t\t//     case 1:\n\t\t//       return x\n\t\t//   }\n\t\t//\n\t\t//   // This should not become \"return 0\"\n\t\t//   switch (0) {\n\t\t//     case 0:\n\t\t//       return x\n\t\t//     case 1:\n\t\t//       const x = 0\n\t\t//   }\n\t\t//\n\t\tp.currentScope.IsAfterConstLocalPrefix = true\n\n\t\t// Visit case values first\n\t\tfor i := range s.Cases {\n\t\t\tc := &s.Cases[i]\n\t\t\tif c.ValueOrNil.Data != nil {\n\t\t\t\tc.ValueOrNil = p.visitExpr(c.ValueOrNil)\n\t\t\t\tp.warnAboutEqualityCheck(\"case\", c.ValueOrNil, c.ValueOrNil.Loc)\n\t\t\t\tp.warnAboutTypeofAndString(s.Test, c.ValueOrNil, onlyCheckOriginalOrder)\n\t\t\t}\n\t\t}\n\n\t\t// Check for duplicate case values\n\t\tp.duplicateCaseChecker.reset()\n\t\tfor _, c := range s.Cases {\n\t\t\tif c.ValueOrNil.Data != nil {\n\t\t\t\tp.duplicateCaseChecker.check(p, c.ValueOrNil)\n\t\t\t}\n\t\t}\n\n\t\t// Then analyze the cases to determine which ones are live and/or dead\n\t\tcases := analyzeSwitchCasesForLiveness(s)\n\n\t\t// Then visit case bodies, and potentially filter out dead cases\n\t\tend := 0\n\t\tfor i, c := range s.Cases {\n\t\t\tisAlwaysDead := cases[i].status == alwaysDead\n\n\t\t\t// Potentially treat the case body as dead code\n\t\t\told := p.isControlFlowDead\n\t\t\tif isAlwaysDead {\n\t\t\t\tp.isControlFlowDead = true\n\t\t\t}\n\t\t\tc.Body = p.visitStmts(c.Body, stmtsNormal)\n\t\t\tp.isControlFlowDead = old\n\n\t\t\t// Filter out this case when minifying if it's known to be dead. Visiting\n\t\t\t// the body above should already have removed any statements that can be\n\t\t\t// removed safely, so if the body isn't empty then that means it contains\n\t\t\t// some statements that can't be removed safely (e.g. a hoisted \"var\").\n\t\t\t// So don't remove this case if the body isn't empty.\n\t\t\tif p.options.minifySyntax && isAlwaysDead && len(c.Body) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Make sure the assignment to the body above is preserved\n\t\t\ts.Cases[end] = c\n\t\t\tend++\n\t\t}\n\t\ts.Cases = s.Cases[:end]\n\n\t\tp.fnOrArrowDataVisit.isInsideSwitch = oldIsInsideSwitch\n\t\tp.popScope()\n\n\t\t// Unwrap switch statements in dead code\n\t\tif p.options.minifySyntax && p.isControlFlowDead {\n\t\t\tfor _, c := range s.Cases {\n\t\t\t\tstmts = append(stmts, c.Body...)\n\t\t\t}\n\t\t\treturn stmts\n\t\t}\n\n\t\tif p.options.minifySyntax {\n\t\t\treturn p.minifySwitchStmt(stmt.Loc, s, stmts)\n\t\t}\n\n\tcase *js_ast.SFunction:\n\t\tp.visitFn(&s.Fn, s.Fn.OpenParenLoc, visitFnOpts{})\n\n\t\t// Strip this function declaration if it was overwritten\n\t\tif p.symbols[s.Fn.Name.Ref.InnerIndex].Flags.Has(ast.RemoveOverwrittenFunctionDeclaration) && !s.IsExport {\n\t\t\treturn stmts\n\t\t}\n\n\t\tif p.options.minifySyntax && !s.Fn.IsGenerator && !s.Fn.IsAsync && !s.Fn.HasRestArg && s.Fn.Name != nil {\n\t\t\tif len(s.Fn.Body.Block.Stmts) == 0 {\n\t\t\t\t// Mark if this function is an empty function\n\t\t\t\thasSideEffectFreeArguments := true\n\t\t\t\tfor _, arg := range s.Fn.Args {\n\t\t\t\t\tif _, ok := arg.Binding.Data.(*js_ast.BIdentifier); !ok {\n\t\t\t\t\t\thasSideEffectFreeArguments = false\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif hasSideEffectFreeArguments {\n\t\t\t\t\tp.symbols[s.Fn.Name.Ref.InnerIndex].Flags |= ast.IsEmptyFunction\n\t\t\t\t}\n\t\t\t} else if len(s.Fn.Args) == 1 && len(s.Fn.Body.Block.Stmts) == 1 {\n\t\t\t\t// Mark if this function is an identity function\n\t\t\t\tif arg := s.Fn.Args[0]; arg.DefaultOrNil.Data == nil {\n\t\t\t\t\tif id, ok := arg.Binding.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\t\t\tif ret, ok := s.Fn.Body.Block.Stmts[0].Data.(*js_ast.SReturn); ok {\n\t\t\t\t\t\t\tif retID, ok := ret.ValueOrNil.Data.(*js_ast.EIdentifier); ok && id.Ref == retID.Ref {\n\t\t\t\t\t\t\t\tp.symbols[s.Fn.Name.Ref.InnerIndex].Flags |= ast.IsIdentityFunction\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Handle exporting this function from a namespace\n\t\tif s.IsExport && p.enclosingNamespaceArgRef != nil {\n\t\t\ts.IsExport = false\n\t\t\tstmts = append(stmts, stmt, js_ast.AssignStmt(\n\t\t\t\tjs_ast.Expr{Loc: stmt.Loc, Data: p.dotOrMangledPropVisit(\n\t\t\t\t\tjs_ast.Expr{Loc: stmt.Loc, Data: &js_ast.EIdentifier{Ref: *p.enclosingNamespaceArgRef}},\n\t\t\t\t\tp.symbols[s.Fn.Name.Ref.InnerIndex].OriginalName,\n\t\t\t\t\ts.Fn.Name.Loc,\n\t\t\t\t)},\n\t\t\t\tjs_ast.Expr{Loc: s.Fn.Name.Loc, Data: &js_ast.EIdentifier{Ref: s.Fn.Name.Ref}},\n\t\t\t))\n\t\t} else {\n\t\t\tstmts = append(stmts, stmt)\n\t\t}\n\n\t\t// Optionally preserve the name\n\t\tif p.options.keepNames {\n\t\t\tsymbol := &p.symbols[s.Fn.Name.Ref.InnerIndex]\n\t\t\tsymbol.Flags |= ast.DidKeepName\n\t\t\tfn := js_ast.Expr{Loc: s.Fn.Name.Loc, Data: &js_ast.EIdentifier{Ref: s.Fn.Name.Ref}}\n\t\t\tstmts = append(stmts, p.keepClassOrFnSymbolName(s.Fn.Name.Loc, fn, symbol.OriginalName))\n\t\t}\n\t\treturn stmts\n\n\tcase *js_ast.SClass:\n\t\tresult := p.visitClass(stmt.Loc, &s.Class, ast.InvalidRef, \"\")\n\n\t\t// Remove the export flag inside a namespace\n\t\tvar nameToExport string\n\t\twasExportInsideNamespace := s.IsExport && p.enclosingNamespaceArgRef != nil\n\t\tif wasExportInsideNamespace {\n\t\t\tnameToExport = p.symbols[s.Class.Name.Ref.InnerIndex].OriginalName\n\t\t\ts.IsExport = false\n\t\t}\n\n\t\t// Lower class field syntax for browsers that don't support it\n\t\tclassStmts, _ := p.lowerClass(stmt, js_ast.Expr{}, result, \"\")\n\n\t\t// Remember if the class was side-effect free before lowering\n\t\tif result.canBeRemovedIfUnused {\n\t\t\tfor _, classStmt := range classStmts {\n\t\t\t\tif s2, ok := classStmt.Data.(*js_ast.SExpr); ok {\n\t\t\t\t\ts2.IsFromClassOrFnThatCanBeRemovedIfUnused = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstmts = append(stmts, classStmts...)\n\n\t\t// Handle exporting this class from a namespace\n\t\tif wasExportInsideNamespace {\n\t\t\tstmts = append(stmts, js_ast.AssignStmt(\n\t\t\t\tjs_ast.Expr{Loc: stmt.Loc, Data: p.dotOrMangledPropVisit(\n\t\t\t\t\tjs_ast.Expr{Loc: stmt.Loc, Data: &js_ast.EIdentifier{Ref: *p.enclosingNamespaceArgRef}},\n\t\t\t\t\tnameToExport,\n\t\t\t\t\ts.Class.Name.Loc,\n\t\t\t\t)},\n\t\t\t\tjs_ast.Expr{Loc: s.Class.Name.Loc, Data: &js_ast.EIdentifier{Ref: s.Class.Name.Ref}},\n\t\t\t))\n\t\t}\n\n\t\treturn stmts\n\n\tcase *js_ast.SEnum:\n\t\t// Do not end the const local prefix after TypeScript enums. We process\n\t\t// them first within their scope so that they are inlined into all code in\n\t\t// that scope. We don't want that to cause the const local prefix to end.\n\t\tp.currentScope.IsAfterConstLocalPrefix = wasAfterAfterConstLocalPrefix\n\n\t\t// Track cross-module enum constants during bundling\n\t\tvar tsTopLevelEnumValues map[string]js_ast.TSEnumValue\n\t\tif p.currentScope == p.moduleScope && p.options.mode == config.ModeBundle {\n\t\t\ttsTopLevelEnumValues = make(map[string]js_ast.TSEnumValue)\n\t\t}\n\n\t\tp.recordDeclaredSymbol(s.Name.Ref)\n\t\tp.pushScopeForVisitPass(js_ast.ScopeEntry, stmt.Loc)\n\t\tp.recordDeclaredSymbol(s.Arg)\n\n\t\t// Scan ahead for any variables inside this namespace. This must be done\n\t\t// ahead of time before visiting any statements inside the namespace\n\t\t// because we may end up visiting the uses before the declarations.\n\t\t// We need to convert the uses into property accesses on the namespace.\n\t\tfor _, value := range s.Values {\n\t\t\tif value.Ref != ast.InvalidRef {\n\t\t\t\tp.isExportedInsideNamespace[value.Ref] = s.Arg\n\t\t\t}\n\t\t}\n\n\t\t// Values without initializers are initialized to one more than the\n\t\t// previous value if the previous value is numeric. Otherwise values\n\t\t// without initializers are initialized to undefined.\n\t\tnextNumericValue := float64(0)\n\t\thasNumericValue := true\n\t\tvalueExprs := []js_ast.Expr{}\n\t\tallValuesArePure := true\n\n\t\t// Update the exported members of this enum as we constant fold each one\n\t\texportedMembers := p.currentScope.TSNamespace.ExportedMembers\n\n\t\t// We normally don't fold numeric constants because they might increase code\n\t\t// size, but it's important to fold numeric constants inside enums since\n\t\t// that's what the TypeScript compiler does.\n\t\toldShouldFoldTypeScriptConstantExpressions := p.shouldFoldTypeScriptConstantExpressions\n\t\tp.shouldFoldTypeScriptConstantExpressions = true\n\n\t\t// Create an assignment for each enum value\n\t\tfor _, value := range s.Values {\n\t\t\tname := helpers.UTF16ToString(value.Name)\n\t\t\tvar assignTarget js_ast.Expr\n\t\t\thasStringValue := false\n\n\t\t\tif value.ValueOrNil.Data != nil {\n\t\t\t\tvalue.ValueOrNil = p.visitExpr(value.ValueOrNil)\n\t\t\t\thasNumericValue = false\n\n\t\t\t\t// \"See through\" any wrapped comments\n\t\t\t\tunderlyingValue := value.ValueOrNil\n\t\t\t\tif inlined, ok := value.ValueOrNil.Data.(*js_ast.EInlinedEnum); ok {\n\t\t\t\t\tunderlyingValue = inlined.Value\n\t\t\t\t}\n\n\t\t\t\tswitch e := underlyingValue.Data.(type) {\n\t\t\t\tcase *js_ast.ENumber:\n\t\t\t\t\tif tsTopLevelEnumValues != nil {\n\t\t\t\t\t\ttsTopLevelEnumValues[name] = js_ast.TSEnumValue{Number: e.Value}\n\t\t\t\t\t}\n\t\t\t\t\tmember := exportedMembers[name]\n\t\t\t\t\tmember.Data = &js_ast.TSNamespaceMemberEnumNumber{Value: e.Value}\n\t\t\t\t\texportedMembers[name] = member\n\t\t\t\t\tp.refToTSNamespaceMemberData[value.Ref] = member.Data\n\t\t\t\t\thasNumericValue = true\n\t\t\t\t\tnextNumericValue = e.Value + 1\n\n\t\t\t\tcase *js_ast.EString:\n\t\t\t\t\tif tsTopLevelEnumValues != nil {\n\t\t\t\t\t\ttsTopLevelEnumValues[name] = js_ast.TSEnumValue{String: e.Value}\n\t\t\t\t\t}\n\t\t\t\t\tmember := exportedMembers[name]\n\t\t\t\t\tmember.Data = &js_ast.TSNamespaceMemberEnumString{Value: e.Value}\n\t\t\t\t\texportedMembers[name] = member\n\t\t\t\t\tp.refToTSNamespaceMemberData[value.Ref] = member.Data\n\t\t\t\t\thasStringValue = true\n\n\t\t\t\tdefault:\n\t\t\t\t\tif js_ast.KnownPrimitiveType(underlyingValue.Data) == js_ast.PrimitiveString {\n\t\t\t\t\t\thasStringValue = true\n\t\t\t\t\t}\n\t\t\t\t\tif !p.astHelpers.ExprCanBeRemovedIfUnused(underlyingValue) {\n\t\t\t\t\t\tallValuesArePure = false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if hasNumericValue {\n\t\t\t\tif tsTopLevelEnumValues != nil {\n\t\t\t\t\ttsTopLevelEnumValues[name] = js_ast.TSEnumValue{Number: nextNumericValue}\n\t\t\t\t}\n\t\t\t\tmember := exportedMembers[name]\n\t\t\t\tmember.Data = &js_ast.TSNamespaceMemberEnumNumber{Value: nextNumericValue}\n\t\t\t\texportedMembers[name] = member\n\t\t\t\tp.refToTSNamespaceMemberData[value.Ref] = member.Data\n\t\t\t\tvalue.ValueOrNil = js_ast.Expr{Loc: value.Loc, Data: &js_ast.ENumber{Value: nextNumericValue}}\n\t\t\t\tnextNumericValue++\n\t\t\t} else {\n\t\t\t\tvalue.ValueOrNil = js_ast.Expr{Loc: value.Loc, Data: js_ast.EUndefinedShared}\n\t\t\t}\n\n\t\t\tif p.options.minifySyntax && js_ast.IsIdentifier(name) {\n\t\t\t\t// \"Enum.Name = value\"\n\t\t\t\tassignTarget = js_ast.Assign(\n\t\t\t\t\tjs_ast.Expr{Loc: value.Loc, Data: &js_ast.EDot{\n\t\t\t\t\t\tTarget:  js_ast.Expr{Loc: value.Loc, Data: &js_ast.EIdentifier{Ref: s.Arg}},\n\t\t\t\t\t\tName:    name,\n\t\t\t\t\t\tNameLoc: value.Loc,\n\t\t\t\t\t}},\n\t\t\t\t\tvalue.ValueOrNil,\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\t// \"Enum['Name'] = value\"\n\t\t\t\tassignTarget = js_ast.Assign(\n\t\t\t\t\tjs_ast.Expr{Loc: value.Loc, Data: &js_ast.EIndex{\n\t\t\t\t\t\tTarget: js_ast.Expr{Loc: value.Loc, Data: &js_ast.EIdentifier{Ref: s.Arg}},\n\t\t\t\t\t\tIndex:  js_ast.Expr{Loc: value.Loc, Data: &js_ast.EString{Value: value.Name}},\n\t\t\t\t\t}},\n\t\t\t\t\tvalue.ValueOrNil,\n\t\t\t\t)\n\t\t\t}\n\t\t\tp.recordUsage(s.Arg)\n\n\t\t\t// String-valued enums do not form a two-way map\n\t\t\tif hasStringValue {\n\t\t\t\tvalueExprs = append(valueExprs, assignTarget)\n\t\t\t} else {\n\t\t\t\t// \"Enum[assignTarget] = 'Name'\"\n\t\t\t\tvalueExprs = append(valueExprs, js_ast.Assign(\n\t\t\t\t\tjs_ast.Expr{Loc: value.Loc, Data: &js_ast.EIndex{\n\t\t\t\t\t\tTarget: js_ast.Expr{Loc: value.Loc, Data: &js_ast.EIdentifier{Ref: s.Arg}},\n\t\t\t\t\t\tIndex:  assignTarget,\n\t\t\t\t\t}},\n\t\t\t\t\tjs_ast.Expr{Loc: value.Loc, Data: &js_ast.EString{Value: value.Name}},\n\t\t\t\t))\n\t\t\t\tp.recordUsage(s.Arg)\n\t\t\t}\n\t\t}\n\n\t\tp.popScope()\n\t\tp.shouldFoldTypeScriptConstantExpressions = oldShouldFoldTypeScriptConstantExpressions\n\n\t\t// Track all exported top-level enums for cross-module inlining\n\t\tif tsTopLevelEnumValues != nil {\n\t\t\tif p.tsEnums == nil {\n\t\t\t\tp.tsEnums = make(map[ast.Ref]map[string]js_ast.TSEnumValue)\n\t\t\t}\n\t\t\tp.tsEnums[s.Name.Ref] = tsTopLevelEnumValues\n\t\t}\n\n\t\t// Wrap this enum definition in a closure\n\t\tstmts = p.generateClosureForTypeScriptEnum(\n\t\t\tstmts, stmt.Loc, s.IsExport, s.Name.Loc, s.Name.Ref, s.Arg, valueExprs, allValuesArePure)\n\t\treturn stmts\n\n\tcase *js_ast.SNamespace:\n\t\tp.recordDeclaredSymbol(s.Name.Ref)\n\n\t\t// Scan ahead for any variables inside this namespace. This must be done\n\t\t// ahead of time before visiting any statements inside the namespace\n\t\t// because we may end up visiting the uses before the declarations.\n\t\t// We need to convert the uses into property accesses on the namespace.\n\t\tfor _, childStmt := range s.Stmts {\n\t\t\tif local, ok := childStmt.Data.(*js_ast.SLocal); ok {\n\t\t\t\tif local.IsExport {\n\t\t\t\t\tjs_ast.ForEachIdentifierBindingInDecls(local.Decls, func(loc logger.Loc, b *js_ast.BIdentifier) {\n\t\t\t\t\t\tp.isExportedInsideNamespace[b.Ref] = s.Arg\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\toldEnclosingNamespaceArgRef := p.enclosingNamespaceArgRef\n\t\tp.enclosingNamespaceArgRef = &s.Arg\n\t\tp.pushScopeForVisitPass(js_ast.ScopeEntry, stmt.Loc)\n\t\tp.recordDeclaredSymbol(s.Arg)\n\t\tstmtsInsideNamespace := p.visitStmtsAndPrependTempRefs(s.Stmts, prependTempRefsOpts{kind: stmtsFnBody})\n\t\tp.popScope()\n\t\tp.enclosingNamespaceArgRef = oldEnclosingNamespaceArgRef\n\n\t\t// Generate a closure for this namespace\n\t\tstmts = p.generateClosureForTypeScriptNamespaceOrEnum(\n\t\t\tstmts, stmt.Loc, s.IsExport, s.Name.Loc, s.Name.Ref, s.Arg, stmtsInsideNamespace)\n\t\treturn stmts\n\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n\n\tstmts = append(stmts, stmt)\n\treturn stmts\n}\n\nfunc (p *parser) minifySwitchStmt(loc logger.Loc, s *js_ast.SSwitch, stmts []js_ast.Stmt) []js_ast.Stmt {\n\t// Trim empty cases before a trailing default clause\n\tif len(s.Cases) > 0 {\n\t\tif i := len(s.Cases) - 1; s.Cases[i].ValueOrNil.Data == nil {\n\t\t\t// \"switch (x) { case 0: default: y() }\" => \"switch (x) { default: y() }\"\n\t\t\tfor i > 0 && len(s.Cases[i-1].Body) == 0 && js_ast.IsPrimitiveLiteral(s.Cases[i-1].ValueOrNil.Data) {\n\t\t\t\ti--\n\t\t\t}\n\t\t\ts.Cases = append(s.Cases[:i], s.Cases[len(s.Cases)-1])\n\t\t}\n\t}\n\n\t// Attempt to partially-evaluate statically-determined switch statements\n\tif js_ast.IsPrimitiveLiteral(s.Test.Data) {\n\t\tallCasesArePrimitives := true\n\t\tdefaultIndex := -1\n\n\t\t// Pass 1: Check for primitives and find the \"default\" case\n\t\tfor i, c := range s.Cases {\n\t\t\tif c.ValueOrNil.Data == nil {\n\t\t\t\tdefaultIndex = i\n\t\t\t} else if !js_ast.IsPrimitiveLiteral(c.ValueOrNil.Data) {\n\t\t\t\tallCasesArePrimitives = false\n\t\t\t}\n\t\t}\n\n\t\t// To simplify analysis, only continue when all cases are primitives\n\t\tif allCasesArePrimitives {\n\t\t\ttakenIndex := -1\n\n\t\t\t// Find the case that compares equal and will be taken\n\t\t\tfor i, c := range s.Cases {\n\t\t\t\tif isEqualToTest, ok := js_ast.CheckEqualityIfNoSideEffects(s.Test.Data, c.ValueOrNil.Data, js_ast.StrictEquality); ok && isEqualToTest {\n\t\t\t\t\ttakenIndex = i\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif takenIndex == -1 {\n\t\t\t\ttakenIndex = defaultIndex\n\t\t\t}\n\n\t\t\t// Partially evaluate the cases\n\t\t\tif takenIndex != -1 {\n\t\t\t\tisFallThrough := false\n\t\t\t\tliveIndex := -1\n\t\t\t\tend := 0\n\t\t\t\tfor i, c := range s.Cases {\n\t\t\t\t\tisTaken := i == takenIndex\n\t\t\t\t\tif isTaken {\n\t\t\t\t\t\tliveIndex = end\n\t\t\t\t\t}\n\t\t\t\t\tif isFallThrough {\n\t\t\t\t\t\tlive := &s.Cases[liveIndex]\n\t\t\t\t\t\tlive.Body = append(live.Body, c.Body...)\n\t\t\t\t\t} else if isTaken || len(c.Body) > 0 {\n\t\t\t\t\t\ts.Cases[end] = c\n\t\t\t\t\t\tend++\n\t\t\t\t\t}\n\t\t\t\t\tif isTaken || isFallThrough {\n\t\t\t\t\t\tisFallThrough = caseBodyCouldHaveFallThrough(c.Body)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ts.Cases = s.Cases[:end]\n\t\t\t}\n\t\t}\n\t}\n\n\t// Handle empty switch statements\n\tif len(s.Cases) == 0 {\n\t\tif p.astHelpers.ExprCanBeRemovedIfUnused(s.Test) {\n\t\t\t// Remove everything\n\t\t\treturn stmts\n\t\t} else {\n\t\t\t// Just keep the test expression\n\t\t\treturn append(stmts, js_ast.Stmt{Loc: s.Test.Loc, Data: &js_ast.SExpr{Value: s.Test}})\n\t\t}\n\t}\n\n\t// Handle a switch statement containing only a \"default\" clause\n\tif len(s.Cases) == 1 {\n\t\tif c := s.Cases[0]; c.ValueOrNil.Data == nil && p.astHelpers.ExprCanBeRemovedIfUnused(s.Test) {\n\t\t\tif body, ok := tryToInlineCaseBody(s.BodyLoc, c.Body, s.CloseBraceLoc); ok {\n\t\t\t\treturn append(stmts, body...)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Try to turn this into an if-else statement\n\tvar yesCase js_ast.Case\n\tvar noCase js_ast.Case\n\tif len(s.Cases) == 1 {\n\t\tif yes := s.Cases[0]; yes.ValueOrNil.Data != nil {\n\t\t\tyesCase = yes\n\t\t}\n\t} else if len(s.Cases) == 2 {\n\t\t// \"switch (x) { case y: a(); break; default: b() }\"\n\t\tif yes := s.Cases[0]; yes.ValueOrNil.Data != nil && !caseBodyCouldHaveFallThrough(yes.Body) {\n\t\t\tif no := s.Cases[1]; no.ValueOrNil.Data == nil {\n\t\t\t\tyesCase = yes\n\t\t\t\tnoCase = no\n\t\t\t}\n\t\t}\n\n\t\t// \"switch (x) { default: a(); break; case y: b() }\"\n\t\tif no := s.Cases[0]; no.ValueOrNil.Data == nil && !caseBodyCouldHaveFallThrough(no.Body) {\n\t\t\tif yes := s.Cases[1]; yes.ValueOrNil.Data != nil {\n\t\t\t\tyesCase = yes\n\t\t\t\tnoCase = no\n\t\t\t}\n\t\t}\n\t}\n\tif yesCase.ValueOrNil.Data != nil {\n\t\tif yesBody, ok := tryToInlineCaseBody(s.BodyLoc, yesCase.Body, s.CloseBraceLoc); ok {\n\t\t\tif noBody, ok := tryToInlineCaseBody(s.BodyLoc, noCase.Body, s.CloseBraceLoc); ok {\n\t\t\t\tifElse := js_ast.SIf{\n\t\t\t\t\tTest: js_ast.Expr{Loc: s.Test.Loc},\n\t\t\t\t\tYes:  stmtsToSingleStmt(yesCase.Loc, yesBody, logger.Loc{}),\n\t\t\t\t}\n\t\t\t\tif isEqualToTest, ok := js_ast.CheckEqualityIfNoSideEffects(s.Test.Data, yesCase.ValueOrNil.Data, js_ast.StrictEquality); ok {\n\t\t\t\t\tifElse.Test.Data = &js_ast.EBoolean{Value: isEqualToTest}\n\t\t\t\t} else {\n\t\t\t\t\tifElse.Test.Data = &js_ast.EBinary{Op: js_ast.BinOpStrictEq, Left: s.Test, Right: yesCase.ValueOrNil}\n\t\t\t\t}\n\t\t\t\tif len(noBody) > 0 {\n\t\t\t\t\tifElse.NoOrNil = stmtsToSingleStmt(noCase.Loc, noBody, logger.Loc{})\n\t\t\t\t}\n\t\t\t\treturn p.mangleIf(stmts, loc, &ifElse)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn append(stmts, js_ast.Stmt{Loc: loc, Data: s})\n}\n\nfunc tryToInlineCaseBody(openBraceLoc logger.Loc, stmts []js_ast.Stmt, closeBraceLoc logger.Loc) ([]js_ast.Stmt, bool) {\n\tif len(stmts) == 1 {\n\t\tif block, ok := stmts[0].Data.(*js_ast.SBlock); ok {\n\t\t\treturn tryToInlineCaseBody(stmts[0].Loc, block.Stmts, block.CloseBraceLoc)\n\t\t}\n\t}\n\n\tcaresAboutScope := false\n\nloop:\n\tfor i, stmt := range stmts {\n\t\tswitch s := stmt.Data.(type) {\n\t\tcase *js_ast.SEmpty, *js_ast.SDirective, *js_ast.SComment, *js_ast.SExpr,\n\t\t\t*js_ast.SDebugger, *js_ast.SContinue, *js_ast.SReturn, *js_ast.SThrow:\n\t\t\t// These can all be inlined outside of the switch without problems\n\t\t\tcontinue\n\n\t\tcase *js_ast.SLocal:\n\t\t\tif s.Kind != js_ast.LocalVar {\n\t\t\t\tcaresAboutScope = true\n\t\t\t}\n\n\t\tcase *js_ast.SBreak:\n\t\t\tif s.Label != nil {\n\t\t\t\t// The break label could target this switch, but we don't know whether that's the case or not here\n\t\t\t\treturn nil, false\n\t\t\t}\n\n\t\t\t// An unlabeled \"break\" inside a switch breaks out of the case\n\t\t\tstmts = stmts[:i]\n\t\t\tbreak loop\n\n\t\tdefault:\n\t\t\t// Assume anything else can't be inlined\n\t\t\treturn nil, false\n\t\t}\n\t}\n\n\t// If we still need a scope, wrap the result in a block\n\tif caresAboutScope {\n\t\treturn []js_ast.Stmt{{Loc: openBraceLoc, Data: &js_ast.SBlock{Stmts: stmts, CloseBraceLoc: closeBraceLoc}}}, true\n\t}\n\treturn stmts, true\n}\n\nfunc isUnsightlyPrimitive(data js_ast.E) bool {\n\tswitch data.(type) {\n\tcase *js_ast.EBoolean, *js_ast.ENull, *js_ast.EUndefined, *js_ast.ENumber, *js_ast.EBigInt, *js_ast.EString:\n\t\treturn true\n\t}\n\treturn false\n}\n\n// If we encounter a variable initializer that could possibly trigger access to\n// a constant declared later on, then we need to end the const local prefix.\n// We want to avoid situations like this:\n//\n//\tconst x = y; // This is supposed to throw due to TDZ\n//\tconst y = 1;\n//\n// or this:\n//\n//\tconst x = 1;\n//\tconst y = foo(); // This is supposed to throw due to TDZ\n//\tconst z = 2;\n//\tconst foo = () => z;\n//\n// But a situation like this is ok:\n//\n//\tconst x = 1;\n//\tconst y = [() => x + z];\n//\tconst z = 2;\nfunc isSafeForConstLocalPrefix(expr js_ast.Expr) bool {\n\tswitch e := expr.Data.(type) {\n\tcase *js_ast.EMissing, *js_ast.EString, *js_ast.ERegExp, *js_ast.EBigInt, *js_ast.EFunction, *js_ast.EArrow:\n\t\treturn true\n\n\tcase *js_ast.EArray:\n\t\tfor _, item := range e.Items {\n\t\t\tif !isSafeForConstLocalPrefix(item) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\n\tcase *js_ast.EObject:\n\t\t// For now just allow \"{}\" and forbid everything else\n\t\treturn len(e.Properties) == 0\n\t}\n\n\treturn false\n}\n\ntype relocateVarsMode uint8\n\nconst (\n\trelocateVarsNormal relocateVarsMode = iota\n\trelocateVarsForInOrForOf\n)\n\n// If we are currently in a hoisted child of the module scope, relocate these\n// declarations to the top level and return an equivalent assignment statement.\n// Make sure to check that the declaration kind is \"var\" before calling this.\n// And make sure to check that the returned statement is not the zero value.\n//\n// This is done to make it easier to traverse top-level declarations in the linker\n// during bundling. Now it is sufficient to just scan the top-level statements\n// instead of having to traverse recursively into the statement tree.\nfunc (p *parser) maybeRelocateVarsToTopLevel(decls []js_ast.Decl, mode relocateVarsMode) (js_ast.Stmt, bool) {\n\t// Only do this when bundling, and not when the scope is already top-level\n\tif p.options.mode != config.ModeBundle || (p.currentScope == p.moduleScope && p.singleStmtDepth == 0) {\n\t\treturn js_ast.Stmt{}, false\n\t}\n\n\t// Only do this if we're not inside a function\n\tscope := p.currentScope\n\tfor !scope.Kind.StopsHoisting() {\n\t\tscope = scope.Parent\n\t}\n\tif scope != p.moduleScope {\n\t\treturn js_ast.Stmt{}, false\n\t}\n\n\t// Convert the declarations to assignments\n\twrapIdentifier := func(loc logger.Loc, ref ast.Ref) js_ast.Expr {\n\t\tp.relocatedTopLevelVars = append(p.relocatedTopLevelVars, ast.LocRef{Loc: loc, Ref: ref})\n\t\tp.recordUsage(ref)\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\t}\n\tvar value js_ast.Expr\n\tfor _, decl := range decls {\n\t\tbinding := js_ast.ConvertBindingToExpr(decl.Binding, wrapIdentifier)\n\t\tif decl.ValueOrNil.Data != nil {\n\t\t\tvalue = js_ast.JoinWithComma(value, js_ast.Assign(binding, decl.ValueOrNil))\n\t\t} else if mode == relocateVarsForInOrForOf {\n\t\t\tvalue = js_ast.JoinWithComma(value, binding)\n\t\t}\n\t}\n\tif value.Data == nil {\n\t\t// If none of the variables had any initializers, just remove the declarations\n\t\treturn js_ast.Stmt{}, true\n\t}\n\treturn js_ast.Stmt{Loc: value.Loc, Data: &js_ast.SExpr{Value: value}}, true\n}\n\nfunc (p *parser) markExprAsParenthesized(value js_ast.Expr, openParenLoc logger.Loc, isAsync bool) {\n\t// Don't lose comments due to parentheses. For example, we don't want to lose\n\t// the comment here:\n\t//\n\t//   ( /* comment */ (foo) );\n\t//\n\tif !isAsync {\n\t\tif comments, ok := p.exprComments[openParenLoc]; ok {\n\t\t\tdelete(p.exprComments, openParenLoc)\n\t\t\tp.exprComments[value.Loc] = append(comments, p.exprComments[value.Loc]...)\n\t\t}\n\t}\n\n\tswitch e := value.Data.(type) {\n\tcase *js_ast.EArray:\n\t\te.IsParenthesized = true\n\tcase *js_ast.EObject:\n\t\te.IsParenthesized = true\n\tcase *js_ast.EFunction:\n\t\te.IsParenthesized = true\n\tcase *js_ast.EArrow:\n\t\te.IsParenthesized = true\n\t}\n}\n\nfunc (p *parser) maybeTransposeIfExprChain(expr js_ast.Expr, visit func(js_ast.Expr) js_ast.Expr) js_ast.Expr {\n\tif e, ok := expr.Data.(*js_ast.EIf); ok {\n\t\te.Yes = p.maybeTransposeIfExprChain(e.Yes, visit)\n\t\te.No = p.maybeTransposeIfExprChain(e.No, visit)\n\t\treturn expr\n\t}\n\treturn visit(expr)\n}\n\nfunc (p *parser) maybeInlineIIFE(loc logger.Loc, e *js_ast.ECall) (js_ast.Expr, bool) {\n\tif len(e.Args) != 0 {\n\t\treturn js_ast.Expr{}, false\n\t}\n\n\t// Note: Do not inline async arrow functions as they are not IIFEs. In\n\t// particular, they are not necessarily invoked immediately, and any\n\t// exceptions involved in their evaluation will be swallowed without\n\t// bubbling up to the surrounding context.\n\tif arrow, ok := e.Target.Data.(*js_ast.EArrow); ok && len(arrow.Args) == 0 && !arrow.IsAsync {\n\t\tstmts := arrow.Body.Block.Stmts\n\n\t\t// \"(() => {})()\" => \"void 0\"\n\t\tif len(stmts) == 0 {\n\t\t\treturn js_ast.Expr{Loc: loc, Data: js_ast.EUndefinedShared}, true\n\t\t}\n\n\t\tif len(stmts) == 1 {\n\t\t\tvar value js_ast.Expr\n\n\t\t\tswitch s := stmts[0].Data.(type) {\n\t\t\t// \"(() => { return })()\" => \"void 0\"\n\t\t\t// \"(() => { return 123 })()\" => \"123\"\n\t\t\tcase *js_ast.SReturn:\n\t\t\t\tvalue = s.ValueOrNil\n\t\t\t\tif value.Data == nil {\n\t\t\t\t\tvalue.Data = js_ast.EUndefinedShared\n\t\t\t\t}\n\n\t\t\t// \"(() => { x })()\" => \"void x\"\n\t\t\tcase *js_ast.SExpr:\n\t\t\t\tvalue = s.Value\n\t\t\t\tvalue.Data = &js_ast.EUnary{Op: js_ast.UnOpVoid, Value: value}\n\t\t\t}\n\n\t\t\tif value.Data != nil {\n\t\t\t\t// Be careful about \"/* @__PURE__ */\" comments:\n\t\t\t\t//\n\t\t\t\t//   OK:  \"(() => x)()\"                 => \"x\"\n\t\t\t\t//   BAD: \"/* @__PURE__ */ (() => x)()\" => \"x\"\n\t\t\t\t//\n\t\t\t\t// The comment indicates that the function body is eligible for\n\t\t\t\t// dead code elimination. Since we don't have a direct AST node\n\t\t\t\t// for that, we can't currently unwrap that and preserve the\n\t\t\t\t// intent. So if it does have a pure comment, only remove it if\n\t\t\t\t// the value itself is already pure.\n\t\t\t\tif !e.CanBeUnwrappedIfUnused || p.astHelpers.ExprCanBeRemovedIfUnused(value) {\n\t\t\t\t\treturn value, true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn js_ast.Expr{}, false\n}\n\nfunc (p *parser) iifeCanBeRemovedIfUnused(args []js_ast.Arg, body js_ast.FnBody) bool {\n\tfor _, arg := range args {\n\t\tif arg.DefaultOrNil.Data != nil && !p.astHelpers.ExprCanBeRemovedIfUnused(arg.DefaultOrNil) {\n\t\t\t// The default value has a side effect\n\t\t\treturn false\n\t\t}\n\n\t\tif _, ok := arg.Binding.Data.(*js_ast.BIdentifier); !ok {\n\t\t\t// Destructuring is a side effect (due to property access)\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// Check whether any statements have side effects or not. Consider return\n\t// statements as not having side effects because if the IIFE can be removed\n\t// then we know the return value is unused, so we know that returning the\n\t// value has no side effects.\n\treturn p.astHelpers.StmtsCanBeRemovedIfUnused(body.Block.Stmts, js_ast.ReturnCanBeRemovedIfUnused)\n}\n\ntype captureValueMode uint8\n\nconst (\n\tvalueDefinitelyNotMutated captureValueMode = iota\n\tvalueCouldBeMutated\n)\n\n// This is a helper function to use when you need to capture a value that may\n// have side effects so you can use it multiple times. It guarantees that the\n// side effects take place exactly once.\n//\n// Example usage:\n//\n//\t// \"value\" => \"value + value\"\n//\t// \"value()\" => \"(_a = value(), _a + _a)\"\n//\tvalueFunc, wrapFunc := p.captureValueWithPossibleSideEffects(loc, 2, value)\n//\treturn wrapFunc(js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n//\t  Op: js_ast.BinOpAdd,\n//\t  Left: valueFunc(),\n//\t  Right: valueFunc(),\n//\t}})\n//\n// This returns a function for generating references instead of a raw reference\n// because AST nodes are supposed to be unique in memory, not aliases of other\n// AST nodes. That way you can mutate one during lowering without having to\n// worry about messing up other nodes.\nfunc (p *parser) captureValueWithPossibleSideEffects(\n\tloc logger.Loc, // The location to use for the generated references\n\tcount int, // The expected number of references to generate\n\tvalue js_ast.Expr, // The value that might have side effects\n\tmode captureValueMode, // Say if \"value\" might be mutated and must be captured\n) (\n\tfunc() js_ast.Expr, // Generates reference expressions \"_a\"\n\tfunc(js_ast.Expr) js_ast.Expr, // Call this on the final expression\n) {\n\twrapFunc := func(expr js_ast.Expr) js_ast.Expr {\n\t\t// Make sure side effects still happen if no expression was generated\n\t\tif expr.Data == nil {\n\t\t\treturn value\n\t\t}\n\t\treturn expr\n\t}\n\n\t// Referencing certain expressions more than once has no side effects, so we\n\t// can just create them inline without capturing them in a temporary variable\n\tvar valueFunc func() js_ast.Expr\n\tswitch e := value.Data.(type) {\n\tcase *js_ast.ENull:\n\t\tvalueFunc = func() js_ast.Expr { return js_ast.Expr{Loc: loc, Data: js_ast.ENullShared} }\n\tcase *js_ast.EUndefined:\n\t\tvalueFunc = func() js_ast.Expr { return js_ast.Expr{Loc: loc, Data: js_ast.EUndefinedShared} }\n\tcase *js_ast.EThis:\n\t\tvalueFunc = func() js_ast.Expr { return js_ast.Expr{Loc: loc, Data: js_ast.EThisShared} }\n\tcase *js_ast.EBoolean:\n\t\tvalueFunc = func() js_ast.Expr { return js_ast.Expr{Loc: loc, Data: &js_ast.EBoolean{Value: e.Value}} }\n\tcase *js_ast.ENumber:\n\t\tvalueFunc = func() js_ast.Expr { return js_ast.Expr{Loc: loc, Data: &js_ast.ENumber{Value: e.Value}} }\n\tcase *js_ast.EBigInt:\n\t\tvalueFunc = func() js_ast.Expr { return js_ast.Expr{Loc: loc, Data: &js_ast.EBigInt{Value: e.Value}} }\n\tcase *js_ast.EString:\n\t\tvalueFunc = func() js_ast.Expr { return js_ast.Expr{Loc: loc, Data: &js_ast.EString{Value: e.Value}} }\n\tcase *js_ast.EPrivateIdentifier:\n\t\tvalueFunc = func() js_ast.Expr { return js_ast.Expr{Loc: loc, Data: &js_ast.EPrivateIdentifier{Ref: e.Ref}} }\n\tcase *js_ast.EIdentifier:\n\t\tif mode == valueDefinitelyNotMutated {\n\t\t\tvalueFunc = func() js_ast.Expr {\n\t\t\t\t// Make sure we record this usage in the usage count so that duplicating\n\t\t\t\t// a single-use reference means it's no longer considered a single-use\n\t\t\t\t// reference. Otherwise the single-use reference inlining code may\n\t\t\t\t// incorrectly inline the initializer into the first reference, leaving\n\t\t\t\t// the second reference without a definition.\n\t\t\t\tp.recordUsage(e.Ref)\n\t\t\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: e.Ref}}\n\t\t\t}\n\t\t}\n\t}\n\tif valueFunc != nil {\n\t\treturn valueFunc, wrapFunc\n\t}\n\n\t// We don't need to worry about side effects if the value won't be used\n\t// multiple times. This special case lets us avoid generating a temporary\n\t// reference.\n\tif count < 2 {\n\t\treturn func() js_ast.Expr {\n\t\t\treturn value\n\t\t}, wrapFunc\n\t}\n\n\t// Otherwise, fall back to generating a temporary reference\n\ttempRef := ast.InvalidRef\n\n\t// If we're in a function argument scope, then we won't be able to generate\n\t// symbols in this scope to store stuff, since there's nowhere to put the\n\t// variable declaration. We don't want to put the variable declaration\n\t// outside the function since some code in the argument list may cause the\n\t// function to be reentrant, and we can't put the variable declaration in\n\t// the function body since that's not accessible by the argument list.\n\t//\n\t// Instead, we use an immediately-invoked arrow function to create a new\n\t// symbol inline by introducing a new scope. Make sure to only use it for\n\t// symbol declaration and still initialize the variable inline to preserve\n\t// side effect order.\n\tif p.currentScope.Kind == js_ast.ScopeFunctionArgs {\n\t\treturn func() js_ast.Expr {\n\t\t\t\tif tempRef == ast.InvalidRef {\n\t\t\t\t\ttempRef = p.generateTempRef(tempRefNoDeclare, \"\")\n\n\t\t\t\t\t// Assign inline so the order of side effects remains the same\n\t\t\t\t\tp.recordUsage(tempRef)\n\t\t\t\t\treturn js_ast.Assign(js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: tempRef}}, value)\n\t\t\t\t}\n\t\t\t\tp.recordUsage(tempRef)\n\t\t\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: tempRef}}\n\t\t\t}, func(expr js_ast.Expr) js_ast.Expr {\n\t\t\t\t// Make sure side effects still happen if no expression was generated\n\t\t\t\tif expr.Data == nil {\n\t\t\t\t\treturn value\n\t\t\t\t}\n\n\t\t\t\t// Generate a new variable using an arrow function to avoid messing with \"this\"\n\t\t\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.ECall{\n\t\t\t\t\tTarget: js_ast.Expr{Loc: loc, Data: &js_ast.EArrow{\n\t\t\t\t\t\tArgs:       []js_ast.Arg{{Binding: js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: tempRef}}}},\n\t\t\t\t\t\tPreferExpr: true,\n\t\t\t\t\t\tBody:       js_ast.FnBody{Loc: loc, Block: js_ast.SBlock{Stmts: []js_ast.Stmt{{Loc: loc, Data: &js_ast.SReturn{ValueOrNil: expr}}}}},\n\t\t\t\t\t}},\n\t\t\t\t}}\n\t\t\t}\n\t}\n\n\treturn func() js_ast.Expr {\n\t\tif tempRef == ast.InvalidRef {\n\t\t\ttempRef = p.generateTempRef(tempRefNeedsDeclare, \"\")\n\t\t\tp.recordUsage(tempRef)\n\t\t\treturn js_ast.Assign(js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: tempRef}}, value)\n\t\t}\n\t\tp.recordUsage(tempRef)\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: tempRef}}\n\t}, wrapFunc\n}\n\nfunc (p *parser) visitDecorators(decorators []js_ast.Decorator, decoratorScope *js_ast.Scope) []js_ast.Decorator {\n\tif decorators != nil {\n\t\t// Decorators cause us to temporarily revert to the scope that encloses the\n\t\t// class declaration, since that's where the generated code for decorators\n\t\t// will be inserted. I believe this currently only matters for parameter\n\t\t// decorators, where the scope should not be within the argument list.\n\t\toldScope := p.currentScope\n\t\tp.currentScope = decoratorScope\n\n\t\tfor i, decorator := range decorators {\n\t\t\tdecorators[i].Value = p.visitExpr(decorator.Value)\n\t\t}\n\n\t\t// Avoid \"popScope\" because this decorator scope is not hierarchical\n\t\tp.currentScope = oldScope\n\t}\n\n\treturn decorators\n}\n\ntype visitClassResult struct {\n\tbodyScope         *js_ast.Scope\n\tinnerClassNameRef ast.Ref\n\tsuperCtorRef      ast.Ref\n\n\t// If true, the class was determined to be safe to remove if the class is\n\t// never used (i.e. the class definition is side-effect free). This is\n\t// determined after visiting but before lowering since lowering may generate\n\t// class mutations that cannot be automatically analyzed as side-effect free.\n\tcanBeRemovedIfUnused bool\n}\n\nfunc (p *parser) visitClass(nameScopeLoc logger.Loc, class *js_ast.Class, defaultNameRef ast.Ref, nameToKeep string) (result visitClassResult) {\n\tclass.Decorators = p.visitDecorators(class.Decorators, p.currentScope)\n\n\tif class.Name != nil {\n\t\tp.recordDeclaredSymbol(class.Name.Ref)\n\t\tif p.options.keepNames {\n\t\t\tnameToKeep = p.symbols[class.Name.Ref.InnerIndex].OriginalName\n\t\t}\n\t}\n\n\t// Replace \"this\" with a reference to the class inside static field\n\t// initializers if static fields are being lowered, since that relocates the\n\t// field initializers outside of the class body and \"this\" will no longer\n\t// reference the same thing.\n\tclassLoweringInfo := p.computeClassLoweringInfo(class)\n\trecomputeClassLoweringInfo := false\n\n\t// Sometimes we need to lower private members even though they are supported.\n\t// This flags them for lowering so that we lower references to them as we\n\t// traverse the class body.\n\t//\n\t// We don't need to worry about possible references to the class shadowing\n\t// symbol inside the class body changing our decision to lower private members\n\t// later on because that shouldn't be possible.\n\tif classLoweringInfo.lowerAllStaticFields {\n\t\tfor _, prop := range class.Properties {\n\t\t\t// We need to lower all private members if fields of that type are lowered,\n\t\t\t// not just private fields (methods and accessors too):\n\t\t\t//\n\t\t\t//   class Foo {\n\t\t\t//     get #foo() {}\n\t\t\t//     static bar = new Foo().#foo\n\t\t\t//   }\n\t\t\t//\n\t\t\t// We can't transform that to this:\n\t\t\t//\n\t\t\t//   class Foo {\n\t\t\t//     get #foo() {}\n\t\t\t//   }\n\t\t\t//   Foo.bar = new Foo().#foo;\n\t\t\t//\n\t\t\t// The private getter must be lowered too.\n\t\t\tif private, ok := prop.Key.Data.(*js_ast.EPrivateIdentifier); ok {\n\t\t\t\tp.symbols[private.Ref.InnerIndex].Flags |= ast.PrivateSymbolMustBeLowered\n\t\t\t\trecomputeClassLoweringInfo = true\n\t\t\t}\n\t\t}\n\t}\n\n\t// Conservatively lower all private names that have been used in a private\n\t// brand check anywhere in the file. See the comment on this map for details.\n\tif p.lowerAllOfThesePrivateNames != nil {\n\t\tfor _, prop := range class.Properties {\n\t\t\tif private, ok := prop.Key.Data.(*js_ast.EPrivateIdentifier); ok {\n\t\t\t\tif symbol := &p.symbols[private.Ref.InnerIndex]; p.lowerAllOfThesePrivateNames[symbol.OriginalName] {\n\t\t\t\t\tsymbol.Flags |= ast.PrivateSymbolMustBeLowered\n\t\t\t\t\trecomputeClassLoweringInfo = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// If we changed private symbol lowering decisions, then recompute class\n\t// lowering info because that may have changed other decisions too\n\tif recomputeClassLoweringInfo {\n\t\tclassLoweringInfo = p.computeClassLoweringInfo(class)\n\t}\n\n\tp.pushScopeForVisitPass(js_ast.ScopeClassName, nameScopeLoc)\n\toldEnclosingClassKeyword := p.enclosingClassKeyword\n\tp.enclosingClassKeyword = class.ClassKeyword\n\tp.currentScope.RecursiveSetStrictMode(js_ast.ImplicitStrictModeClass)\n\tif class.Name != nil {\n\t\tp.validateDeclaredSymbolName(class.Name.Loc, p.symbols[class.Name.Ref.InnerIndex].OriginalName)\n\t}\n\n\t// Create the \"__super\" symbol if necessary. This will cause us to replace\n\t// all \"super()\" call expressions with a call to this symbol, which will\n\t// then be inserted into the \"constructor\" method.\n\tresult.superCtorRef = ast.InvalidRef\n\tif classLoweringInfo.shimSuperCtorCalls {\n\t\tresult.superCtorRef = p.newSymbol(ast.SymbolOther, \"__super\")\n\t\tp.currentScope.Generated = append(p.currentScope.Generated, result.superCtorRef)\n\t\tp.recordDeclaredSymbol(result.superCtorRef)\n\t}\n\toldSuperCtorRef := p.superCtorRef\n\tp.superCtorRef = result.superCtorRef\n\n\t// Insert an immutable inner name that spans the whole class to match\n\t// JavaScript's semantics specifically the \"CreateImmutableBinding\" here:\n\t// https://262.ecma-international.org/6.0/#sec-runtime-semantics-classdefinitionevaluation\n\t// The class body (and extends clause) \"captures\" the original value of the\n\t// class name. This matters for class statements because the symbol can be\n\t// re-assigned to something else later. The captured values must be the\n\t// original value of the name, not the re-assigned value. Use \"const\" for\n\t// this symbol to match JavaScript run-time semantics. You are not allowed\n\t// to assign to this symbol (it throws a TypeError).\n\tif class.Name != nil {\n\t\tname := p.symbols[class.Name.Ref.InnerIndex].OriginalName\n\t\tresult.innerClassNameRef = p.newSymbol(ast.SymbolConst, \"_\"+name)\n\t\tp.currentScope.Members[name] = js_ast.ScopeMember{Loc: class.Name.Loc, Ref: result.innerClassNameRef}\n\t} else {\n\t\tname := \"_this\"\n\t\tif defaultNameRef != ast.InvalidRef {\n\t\t\tname = \"_\" + p.source.IdentifierName + \"_default\"\n\t\t}\n\t\tresult.innerClassNameRef = p.newSymbol(ast.SymbolConst, name)\n\t}\n\tp.recordDeclaredSymbol(result.innerClassNameRef)\n\n\tif class.ExtendsOrNil.Data != nil {\n\t\tclass.ExtendsOrNil = p.visitExpr(class.ExtendsOrNil)\n\t}\n\n\t// A scope is needed for private identifiers\n\tp.pushScopeForVisitPass(js_ast.ScopeClassBody, class.BodyLoc)\n\tresult.bodyScope = p.currentScope\n\n\tfor i := range class.Properties {\n\t\tproperty := &class.Properties[i]\n\n\t\tif property.Kind == js_ast.PropertyClassStaticBlock {\n\t\t\toldFnOrArrowData := p.fnOrArrowDataVisit\n\t\t\toldFnOnlyDataVisit := p.fnOnlyDataVisit\n\n\t\t\tp.fnOrArrowDataVisit = fnOrArrowDataVisit{}\n\t\t\tp.fnOnlyDataVisit = fnOnlyDataVisit{\n\t\t\t\tisThisNested:           true,\n\t\t\t\tisNewTargetAllowed:     true,\n\t\t\t\tisInStaticClassContext: true,\n\t\t\t\tinnerClassNameRef:      &result.innerClassNameRef,\n\t\t\t}\n\n\t\t\tif classLoweringInfo.lowerAllStaticFields {\n\t\t\t\t// Need to lower \"this\" and \"super\" since they won't be valid outside the class body\n\t\t\t\tp.fnOnlyDataVisit.shouldReplaceThisWithInnerClassNameRef = true\n\t\t\t\tp.fnOrArrowDataVisit.shouldLowerSuperPropertyAccess = true\n\t\t\t}\n\n\t\t\tp.pushScopeForVisitPass(js_ast.ScopeClassStaticInit, property.ClassStaticBlock.Loc)\n\n\t\t\t// Make it an error to use \"arguments\" in a static class block\n\t\t\tp.currentScope.ForbidArguments = true\n\n\t\t\tproperty.ClassStaticBlock.Block.Stmts = p.visitStmts(property.ClassStaticBlock.Block.Stmts, stmtsFnBody)\n\t\t\tp.popScope()\n\n\t\t\tp.fnOrArrowDataVisit = oldFnOrArrowData\n\t\t\tp.fnOnlyDataVisit = oldFnOnlyDataVisit\n\t\t\tcontinue\n\t\t}\n\n\t\tproperty.Decorators = p.visitDecorators(property.Decorators, result.bodyScope)\n\n\t\t// Visit the property key\n\t\tif private, ok := property.Key.Data.(*js_ast.EPrivateIdentifier); ok {\n\t\t\t// Special-case private identifiers here\n\t\t\tp.recordDeclaredSymbol(private.Ref)\n\t\t} else {\n\t\t\t// It's forbidden to reference the class name in a computed key\n\t\t\tif property.Flags.Has(js_ast.PropertyIsComputed) && class.Name != nil {\n\t\t\t\tp.symbols[result.innerClassNameRef.InnerIndex].Kind = ast.SymbolClassInComputedPropertyKey\n\t\t\t}\n\n\t\t\tkey, _ := p.visitExprInOut(property.Key, exprIn{\n\t\t\t\tshouldMangleStringsAsProps: true,\n\t\t\t})\n\t\t\tproperty.Key = key\n\n\t\t\t// Re-allow using the class name after visiting a computed key\n\t\t\tif property.Flags.Has(js_ast.PropertyIsComputed) && class.Name != nil {\n\t\t\t\tp.symbols[result.innerClassNameRef.InnerIndex].Kind = ast.SymbolConst\n\t\t\t}\n\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tif inlined, ok := key.Data.(*js_ast.EInlinedEnum); ok {\n\t\t\t\t\tswitch inlined.Value.Data.(type) {\n\t\t\t\t\tcase *js_ast.EString, *js_ast.ENumber:\n\t\t\t\t\t\tkey.Data = inlined.Value.Data\n\t\t\t\t\t\tproperty.Key.Data = key.Data\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tswitch k := key.Data.(type) {\n\t\t\t\tcase *js_ast.ENumber, *js_ast.ENameOfSymbol:\n\t\t\t\t\t// \"class { [123] }\" => \"class { 123 }\"\n\t\t\t\t\tproperty.Flags &= ^js_ast.PropertyIsComputed\n\t\t\t\tcase *js_ast.EString:\n\t\t\t\t\tif numberValue, ok := js_ast.StringToEquivalentNumberValue(k.Value); ok && numberValue >= 0 {\n\t\t\t\t\t\t// \"class { '123' }\" => \"class { 123 }\"\n\t\t\t\t\t\tproperty.Key.Data = &js_ast.ENumber{Value: numberValue}\n\t\t\t\t\t\tproperty.Flags &= ^js_ast.PropertyIsComputed\n\t\t\t\t\t} else if property.Flags.Has(js_ast.PropertyIsComputed) {\n\t\t\t\t\t\t// \"class {['x'] = y}\" => \"class {'x' = y}\"\n\t\t\t\t\t\tisInvalidConstructor := false\n\t\t\t\t\t\tif helpers.UTF16EqualsString(k.Value, \"constructor\") {\n\t\t\t\t\t\t\tif !property.Kind.IsMethodDefinition() {\n\t\t\t\t\t\t\t\t// \"constructor\" is an invalid name for both instance and static fields\n\t\t\t\t\t\t\t\tisInvalidConstructor = true\n\t\t\t\t\t\t\t} else if !property.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t\t\t\t\t\t// Calling an instance method \"constructor\" is problematic so avoid that too\n\t\t\t\t\t\t\t\tisInvalidConstructor = true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// A static property must not be called \"prototype\"\n\t\t\t\t\t\tisInvalidPrototype := property.Flags.Has(js_ast.PropertyIsStatic) && helpers.UTF16EqualsString(k.Value, \"prototype\")\n\n\t\t\t\t\t\tif !isInvalidConstructor && !isInvalidPrototype {\n\t\t\t\t\t\t\tproperty.Flags &= ^js_ast.PropertyIsComputed\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Make it an error to use \"arguments\" in a class body\n\t\tp.currentScope.ForbidArguments = true\n\n\t\t// The value of \"this\" and \"super\" is shadowed inside property values\n\t\toldFnOnlyDataVisit := p.fnOnlyDataVisit\n\t\toldShouldLowerSuperPropertyAccess := p.fnOrArrowDataVisit.shouldLowerSuperPropertyAccess\n\t\tp.fnOrArrowDataVisit.shouldLowerSuperPropertyAccess = false\n\t\tp.fnOnlyDataVisit.shouldReplaceThisWithInnerClassNameRef = false\n\t\tp.fnOnlyDataVisit.isThisNested = true\n\t\tp.fnOnlyDataVisit.isNewTargetAllowed = true\n\t\tp.fnOnlyDataVisit.isInStaticClassContext = property.Flags.Has(js_ast.PropertyIsStatic)\n\t\tp.fnOnlyDataVisit.innerClassNameRef = &result.innerClassNameRef\n\n\t\t// We need to explicitly assign the name to the property initializer if it\n\t\t// will be transformed such that it is no longer an inline initializer.\n\t\tnameToKeep := \"\"\n\t\tisLoweredPrivateMethod := false\n\t\tif private, ok := property.Key.Data.(*js_ast.EPrivateIdentifier); ok {\n\t\t\tif !property.Kind.IsMethodDefinition() || p.privateSymbolNeedsToBeLowered(private) {\n\t\t\t\tnameToKeep = p.symbols[private.Ref.InnerIndex].OriginalName\n\t\t\t}\n\n\t\t\t// Lowered private methods (both instance and static) are initialized\n\t\t\t// outside of the class body, so we must rewrite \"super\" property\n\t\t\t// accesses inside them. Lowered private instance fields are initialized\n\t\t\t// inside the constructor where \"super\" is valid, so those don't need to\n\t\t\t// be rewritten.\n\t\t\tif property.Kind.IsMethodDefinition() && p.privateSymbolNeedsToBeLowered(private) {\n\t\t\t\tisLoweredPrivateMethod = true\n\t\t\t}\n\t\t} else if !property.Kind.IsMethodDefinition() && !property.Flags.Has(js_ast.PropertyIsComputed) {\n\t\t\tif str, ok := property.Key.Data.(*js_ast.EString); ok {\n\t\t\t\tnameToKeep = helpers.UTF16ToString(str.Value)\n\t\t\t}\n\t\t}\n\n\t\t// Handle methods\n\t\tif property.ValueOrNil.Data != nil {\n\t\t\tp.propMethodDecoratorScope = result.bodyScope\n\n\t\t\t// Propagate the name to keep from the method into the initializer\n\t\t\tif nameToKeep != \"\" {\n\t\t\t\tp.nameToKeep = nameToKeep\n\t\t\t\tp.nameToKeepIsFor = property.ValueOrNil.Data\n\t\t\t}\n\n\t\t\t// Propagate whether we're in a derived class constructor\n\t\t\tif class.ExtendsOrNil.Data != nil && !property.Flags.Has(js_ast.PropertyIsComputed) {\n\t\t\t\tif str, ok := property.Key.Data.(*js_ast.EString); ok && helpers.UTF16EqualsString(str.Value, \"constructor\") {\n\t\t\t\t\tp.propDerivedCtorValue = property.ValueOrNil.Data\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tproperty.ValueOrNil, _ = p.visitExprInOut(property.ValueOrNil, exprIn{\n\t\t\t\tisMethod:               true,\n\t\t\t\tisLoweredPrivateMethod: isLoweredPrivateMethod,\n\t\t\t})\n\t\t}\n\n\t\t// Handle initialized fields\n\t\tif property.InitializerOrNil.Data != nil {\n\t\t\tif property.Flags.Has(js_ast.PropertyIsStatic) && classLoweringInfo.lowerAllStaticFields {\n\t\t\t\t// Need to lower \"this\" and \"super\" since they won't be valid outside the class body\n\t\t\t\tp.fnOnlyDataVisit.shouldReplaceThisWithInnerClassNameRef = true\n\t\t\t\tp.fnOrArrowDataVisit.shouldLowerSuperPropertyAccess = true\n\t\t\t}\n\n\t\t\t// Propagate the name to keep from the field into the initializer\n\t\t\tif nameToKeep != \"\" {\n\t\t\t\tp.nameToKeep = nameToKeep\n\t\t\t\tp.nameToKeepIsFor = property.InitializerOrNil.Data\n\t\t\t}\n\n\t\t\tproperty.InitializerOrNil = p.visitExpr(property.InitializerOrNil)\n\t\t}\n\n\t\t// Restore \"this\" so it will take the inherited value in property keys\n\t\tp.fnOnlyDataVisit = oldFnOnlyDataVisit\n\t\tp.fnOrArrowDataVisit.shouldLowerSuperPropertyAccess = oldShouldLowerSuperPropertyAccess\n\n\t\t// Restore the ability to use \"arguments\" in decorators and computed properties\n\t\tp.currentScope.ForbidArguments = false\n\t}\n\n\t// Check for and warn about duplicate keys in class bodies\n\tif !p.suppressWarningsAboutWeirdCode {\n\t\tp.warnAboutDuplicateProperties(class.Properties, duplicatePropertiesInClass)\n\t}\n\n\t// Analyze side effects before adding the name keeping call\n\tresult.canBeRemovedIfUnused = p.astHelpers.ClassCanBeRemovedIfUnused(*class)\n\n\t// Implement name keeping using a static block at the start of the class body\n\tif p.options.keepNames && nameToKeep != \"\" {\n\t\tpropertyPreventsKeepNames := false\n\t\tfor _, prop := range class.Properties {\n\t\t\t// A static property called \"name\" shadows the automatically-generated name\n\t\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t\tif str, ok := prop.Key.Data.(*js_ast.EString); ok && helpers.UTF16EqualsString(str.Value, \"name\") {\n\t\t\t\t\tpropertyPreventsKeepNames = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif !propertyPreventsKeepNames {\n\t\t\tvar this js_ast.Expr\n\t\t\tif classLoweringInfo.lowerAllStaticFields {\n\t\t\t\tp.recordUsage(result.innerClassNameRef)\n\t\t\t\tthis = js_ast.Expr{Loc: class.BodyLoc, Data: &js_ast.EIdentifier{Ref: result.innerClassNameRef}}\n\t\t\t} else {\n\t\t\t\tthis = js_ast.Expr{Loc: class.BodyLoc, Data: js_ast.EThisShared}\n\t\t\t}\n\t\t\tproperties := make([]js_ast.Property, 0, 1+len(class.Properties))\n\t\t\tproperties = append(properties, js_ast.Property{\n\t\t\t\tKind: js_ast.PropertyClassStaticBlock,\n\t\t\t\tClassStaticBlock: &js_ast.ClassStaticBlock{Loc: class.BodyLoc, Block: js_ast.SBlock{Stmts: []js_ast.Stmt{\n\t\t\t\t\tp.keepClassOrFnSymbolName(class.BodyLoc, this, nameToKeep),\n\t\t\t\t}}},\n\t\t\t})\n\t\t\tclass.Properties = append(properties, class.Properties...)\n\t\t}\n\t}\n\n\tp.enclosingClassKeyword = oldEnclosingClassKeyword\n\tp.superCtorRef = oldSuperCtorRef\n\tp.popScope()\n\n\tif p.symbols[result.innerClassNameRef.InnerIndex].UseCountEstimate == 0 {\n\t\t// Don't generate a shadowing name if one isn't needed\n\t\tresult.innerClassNameRef = ast.InvalidRef\n\t} else if class.Name == nil {\n\t\t// If there was originally no class name but something inside needed one\n\t\t// (e.g. there was a static property initializer that referenced \"this\"),\n\t\t// populate the class name. If this is an \"export default class\" statement,\n\t\t// use the existing default name so that things will work as expected if\n\t\t// this is turned into a regular class statement later on.\n\t\tclassNameRef := defaultNameRef\n\t\tif classNameRef == ast.InvalidRef {\n\t\t\tclassNameRef = p.newSymbol(ast.SymbolOther, \"_this\")\n\t\t\tp.currentScope.Generated = append(p.currentScope.Generated, classNameRef)\n\t\t\tp.recordDeclaredSymbol(classNameRef)\n\t\t}\n\t\tclass.Name = &ast.LocRef{Loc: nameScopeLoc, Ref: classNameRef}\n\t}\n\n\tp.popScope()\n\n\t// Sanity check that the class lowering info hasn't changed before and after\n\t// visiting. The class transform relies on this because lowering assumes that\n\t// must be able to expect that visiting has done certain things.\n\tif classLoweringInfo != p.computeClassLoweringInfo(class) {\n\t\tpanic(\"Internal error\")\n\t}\n\n\treturn\n}\n\nfunc isSimpleParameterList(args []js_ast.Arg, hasRestArg bool) bool {\n\tif hasRestArg {\n\t\treturn false\n\t}\n\tfor _, arg := range args {\n\t\tif _, ok := arg.Binding.Data.(*js_ast.BIdentifier); !ok || arg.DefaultOrNil.Data != nil {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc fnBodyContainsUseStrict(body []js_ast.Stmt) (logger.Loc, bool) {\n\tfor _, stmt := range body {\n\t\tswitch s := stmt.Data.(type) {\n\t\tcase *js_ast.SComment:\n\t\t\tcontinue\n\t\tcase *js_ast.SDirective:\n\t\t\tif helpers.UTF16EqualsString(s.Value, \"use strict\") {\n\t\t\t\treturn stmt.Loc, true\n\t\t\t}\n\t\tdefault:\n\t\t\treturn logger.Loc{}, false\n\t\t}\n\t}\n\treturn logger.Loc{}, false\n}\n\ntype visitArgsOpts struct {\n\tbody           []js_ast.Stmt\n\tdecoratorScope *js_ast.Scope\n\thasRestArg     bool\n\n\t// This is true if the function is an arrow function or a method\n\tisUniqueFormalParameters bool\n}\n\nfunc (p *parser) visitArgs(args []js_ast.Arg, opts visitArgsOpts) {\n\tvar duplicateArgCheck map[string]logger.Range\n\tuseStrictLoc, hasUseStrict := fnBodyContainsUseStrict(opts.body)\n\thasSimpleArgs := isSimpleParameterList(args, opts.hasRestArg)\n\n\t// Section 15.2.1 Static Semantics: Early Errors: \"It is a Syntax Error if\n\t// FunctionBodyContainsUseStrict of FunctionBody is true and\n\t// IsSimpleParameterList of FormalParameters is false.\"\n\tif hasUseStrict && !hasSimpleArgs {\n\t\tp.log.AddError(&p.tracker, p.source.RangeOfString(useStrictLoc),\n\t\t\t\"Cannot use a \\\"use strict\\\" directive in a function with a non-simple parameter list\")\n\t}\n\n\t// Section 15.1.1 Static Semantics: Early Errors: \"Multiple occurrences of\n\t// the same BindingIdentifier in a FormalParameterList is only allowed for\n\t// functions which have simple parameter lists and which are not defined in\n\t// strict mode code.\"\n\tif opts.isUniqueFormalParameters || hasUseStrict || !hasSimpleArgs || p.isStrictMode() {\n\t\tduplicateArgCheck = make(map[string]logger.Range)\n\t}\n\n\tfor i := range args {\n\t\targ := &args[i]\n\t\targ.Decorators = p.visitDecorators(arg.Decorators, opts.decoratorScope)\n\t\tp.visitBinding(arg.Binding, bindingOpts{\n\t\t\tduplicateArgCheck: duplicateArgCheck,\n\t\t})\n\t\tif arg.DefaultOrNil.Data != nil {\n\t\t\targ.DefaultOrNil = p.visitExpr(arg.DefaultOrNil)\n\t\t}\n\t}\n}\n\nfunc (p *parser) isDotOrIndexDefineMatch(expr js_ast.Expr, parts []string) bool {\n\tswitch e := expr.Data.(type) {\n\tcase *js_ast.EDot:\n\t\tif len(parts) > 1 {\n\t\t\t// Intermediates must be dot expressions\n\t\t\tlast := len(parts) - 1\n\t\t\treturn parts[last] == e.Name && p.isDotOrIndexDefineMatch(e.Target, parts[:last])\n\t\t}\n\n\tcase *js_ast.EIndex:\n\t\tif len(parts) > 1 {\n\t\t\tif str, ok := e.Index.Data.(*js_ast.EString); ok {\n\t\t\t\t// Intermediates must be dot expressions\n\t\t\t\tlast := len(parts) - 1\n\t\t\t\treturn parts[last] == helpers.UTF16ToString(str.Value) && p.isDotOrIndexDefineMatch(e.Target, parts[:last])\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.EThis:\n\t\t// Allow matching on top-level \"this\"\n\t\tif !p.fnOnlyDataVisit.isThisNested {\n\t\t\treturn len(parts) == 1 && parts[0] == \"this\"\n\t\t}\n\n\tcase *js_ast.EImportMeta:\n\t\t// Allow matching on \"import.meta\"\n\t\treturn len(parts) == 2 && parts[0] == \"import\" && parts[1] == \"meta\"\n\n\tcase *js_ast.EIdentifier:\n\t\t// The last expression must be an identifier\n\t\tif len(parts) == 1 {\n\t\t\t// The name must match\n\t\t\tname := p.loadNameFromRef(e.Ref)\n\t\t\tif name != parts[0] {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tresult := p.findSymbol(expr.Loc, name)\n\n\t\t\t// The \"findSymbol\" function also marks this symbol as used. But that's\n\t\t\t// never what we want here because we're just peeking to see what kind of\n\t\t\t// symbol it is to see if it's a match. If it's not a match, it will be\n\t\t\t// re-resolved again later and marked as used there. So we don't want to\n\t\t\t// mark it as used twice.\n\t\t\tp.ignoreUsage(result.ref)\n\n\t\t\t// We must not be in a \"with\" statement scope\n\t\t\tif result.isInsideWithScope {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\t// The last symbol must be unbound or injected\n\t\t\treturn p.symbols[result.ref.InnerIndex].Kind.IsUnboundOrInjected()\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc (p *parser) instantiateDefineExpr(loc logger.Loc, expr config.DefineExpr, opts identifierOpts) js_ast.Expr {\n\tif expr.Constant != nil {\n\t\treturn js_ast.Expr{Loc: loc, Data: expr.Constant}\n\t}\n\n\tif expr.InjectedDefineIndex.IsValid() {\n\t\tref := p.injectedDefineSymbols[expr.InjectedDefineIndex.GetIndex()]\n\t\tp.recordUsage(ref)\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\t}\n\n\tparts := expr.Parts\n\tif len(parts) == 0 {\n\t\treturn js_ast.Expr{}\n\t}\n\n\t// Check both user-specified defines and known globals\n\tif opts.matchAgainstDefines {\n\t\t// Make sure define resolution is not recursive\n\t\topts.matchAgainstDefines = false\n\n\t\t// Substitute user-specified defines\n\t\tif defines, ok := p.options.defines.DotDefines[parts[len(parts)-1]]; ok {\n\t\t\tfor _, define := range defines {\n\t\t\t\tif define.DefineExpr != nil && helpers.StringArraysEqual(define.KeyParts, parts) {\n\t\t\t\t\treturn p.instantiateDefineExpr(loc, *define.DefineExpr, opts)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check injected dot names\n\tif names, ok := p.injectedDotNames[parts[len(parts)-1]]; ok {\n\t\tfor _, name := range names {\n\t\t\tif helpers.StringArraysEqual(name.parts, parts) {\n\t\t\t\treturn p.instantiateInjectDotName(loc, name, opts.assignTarget)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Generate an identifier for the first part\n\tvar value js_ast.Expr\n\tfirstPart := parts[0]\n\tparts = parts[1:]\n\tswitch firstPart {\n\tcase \"NaN\":\n\t\tvalue = js_ast.Expr{Loc: loc, Data: &js_ast.ENumber{Value: math.NaN()}}\n\n\tcase \"Infinity\":\n\t\tvalue = js_ast.Expr{Loc: loc, Data: &js_ast.ENumber{Value: math.Inf(1)}}\n\n\tcase \"null\":\n\t\tvalue = js_ast.Expr{Loc: loc, Data: js_ast.ENullShared}\n\n\tcase \"undefined\":\n\t\tvalue = js_ast.Expr{Loc: loc, Data: js_ast.EUndefinedShared}\n\n\tcase \"this\":\n\t\tif thisValue, ok := p.valueForThis(loc, false /* shouldLog */, js_ast.AssignTargetNone, false, false); ok {\n\t\t\tvalue = thisValue\n\t\t} else {\n\t\t\tvalue = js_ast.Expr{Loc: loc, Data: js_ast.EThisShared}\n\t\t}\n\n\tdefault:\n\t\tif firstPart == \"import\" && len(parts) > 0 && parts[0] == \"meta\" {\n\t\t\tif importMeta, ok := p.valueForImportMeta(loc); ok {\n\t\t\t\tvalue = importMeta\n\t\t\t} else {\n\t\t\t\tvalue = js_ast.Expr{Loc: loc, Data: &js_ast.EImportMeta{}}\n\t\t\t}\n\t\t\tparts = parts[1:]\n\t\t\tbreak\n\t\t}\n\n\t\tresult := p.findSymbol(loc, firstPart)\n\t\tvalue = p.handleIdentifier(loc, &js_ast.EIdentifier{\n\t\t\tRef:                   result.ref,\n\t\t\tMustKeepDueToWithStmt: result.isInsideWithScope,\n\n\t\t\t// Enable tree shaking\n\t\t\tCanBeRemovedIfUnused: true,\n\t\t}, opts)\n\t}\n\n\t// Build up a chain of property access expressions for subsequent parts\n\tfor _, part := range parts {\n\t\tif expr, ok := p.maybeRewritePropertyAccess(loc, js_ast.AssignTargetNone, false, value, part, loc, false, false, false); ok {\n\t\t\tvalue = expr\n\t\t} else if p.isMangledProp(part) {\n\t\t\tvalue = js_ast.Expr{Loc: loc, Data: &js_ast.EIndex{\n\t\t\t\tTarget: value,\n\t\t\t\tIndex:  js_ast.Expr{Loc: loc, Data: &js_ast.ENameOfSymbol{Ref: p.symbolForMangledProp(part)}},\n\t\t\t}}\n\t\t} else {\n\t\t\tvalue = js_ast.Expr{Loc: loc, Data: &js_ast.EDot{\n\t\t\t\tTarget:  value,\n\t\t\t\tName:    part,\n\t\t\t\tNameLoc: loc,\n\n\t\t\t\t// Enable tree shaking\n\t\t\t\tCanBeRemovedIfUnused: true,\n\t\t\t}}\n\t\t}\n\t}\n\n\treturn value\n}\n\nfunc (p *parser) instantiateInjectDotName(loc logger.Loc, name injectedDotName, assignTarget js_ast.AssignTarget) js_ast.Expr {\n\t// Note: We don't need to \"ignoreRef\" on the underlying identifier\n\t// because we have only parsed it but not visited it yet\n\tref := p.injectedDefineSymbols[name.injectedDefineIndex]\n\tp.recordUsage(ref)\n\n\tif assignTarget != js_ast.AssignTargetNone {\n\t\tif where, ok := p.injectedSymbolSources[ref]; ok {\n\t\t\tr := js_lexer.RangeOfIdentifier(p.source, loc)\n\t\t\ttracker := logger.MakeLineColumnTracker(&where.source)\n\t\t\tjoined := strings.Join(name.parts, \".\")\n\t\t\tp.log.AddErrorWithNotes(&p.tracker, r,\n\t\t\t\tfmt.Sprintf(\"Cannot assign to %q because it's an import from an injected file\", joined),\n\t\t\t\t[]logger.MsgData{tracker.MsgData(js_lexer.RangeOfIdentifier(where.source, where.loc),\n\t\t\t\t\tfmt.Sprintf(\"The symbol %q was exported from %q here:\",\n\t\t\t\t\t\tjoined, where.source.PrettyPaths.Select(p.options.logPathStyle)))})\n\t\t}\n\t}\n\n\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: ref}}\n}\n\nfunc (p *parser) checkForUnrepresentableIdentifier(loc logger.Loc, name string) {\n\tif p.options.asciiOnly && p.options.unsupportedJSFeatures.Has(compat.UnicodeEscapes) &&\n\t\thelpers.ContainsNonBMPCodePoint(name) {\n\t\tif p.unrepresentableIdentifiers == nil {\n\t\t\tp.unrepresentableIdentifiers = make(map[string]bool)\n\t\t}\n\t\tif !p.unrepresentableIdentifiers[name] {\n\t\t\tp.unrepresentableIdentifiers[name] = true\n\t\t\twhere := config.PrettyPrintTargetEnvironment(p.options.originalTargetEnv, p.options.unsupportedJSFeatureOverridesMask)\n\t\t\tr := js_lexer.RangeOfIdentifier(p.source, loc)\n\t\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\"%q cannot be escaped in %s but you \"+\n\t\t\t\t\"can set the charset to \\\"utf8\\\" to allow unescaped Unicode characters\", name, where))\n\t\t}\n\t}\n}\n\ntype typeofStringOrder uint8\n\nconst (\n\tonlyCheckOriginalOrder typeofStringOrder = iota\n\tcheckBothOrders\n)\n\nfunc (p *parser) warnAboutTypeofAndString(a js_ast.Expr, b js_ast.Expr, order typeofStringOrder) {\n\tif order == checkBothOrders {\n\t\tif _, ok := a.Data.(*js_ast.EString); ok {\n\t\t\ta, b = b, a\n\t\t}\n\t}\n\n\tif typeof, ok := a.Data.(*js_ast.EUnary); ok && typeof.Op == js_ast.UnOpTypeof {\n\t\tif str, ok := b.Data.(*js_ast.EString); ok {\n\t\t\tvalue := helpers.UTF16ToString(str.Value)\n\t\t\tswitch value {\n\t\t\tcase \"undefined\", \"object\", \"boolean\", \"number\", \"bigint\", \"string\", \"symbol\", \"function\", \"unknown\":\n\t\t\tdefault:\n\t\t\t\t// Warn about typeof comparisons with values that will never be\n\t\t\t\t// returned. Here's an example of code with this problem:\n\t\t\t\t// https://github.com/olifolkerd/tabulator/issues/2962\n\t\t\t\tr := p.source.RangeOfString(b.Loc)\n\t\t\t\ttext := fmt.Sprintf(\"The \\\"typeof\\\" operator will never evaluate to %q\", value)\n\t\t\t\tkind := logger.Warning\n\t\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\t\tkind = logger.Debug\n\t\t\t\t}\n\t\t\t\tvar notes []logger.MsgData\n\t\t\t\tif value == \"null\" {\n\t\t\t\t\tnotes = append(notes, logger.MsgData{\n\t\t\t\t\t\tText: \"The expression \\\"typeof x\\\" actually evaluates to \\\"object\\\" in JavaScript, not \\\"null\\\". \" +\n\t\t\t\t\t\t\t\"You need to use \\\"x === null\\\" to test for null.\",\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_ImpossibleTypeof, kind, &p.tracker, r, text, notes)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (p *parser) warnAboutEqualityCheck(op string, value js_ast.Expr, afterOpLoc logger.Loc) bool {\n\tswitch e := value.Data.(type) {\n\tcase *js_ast.ENumber:\n\t\t// \"0 === -0\" is true in JavaScript. Here's an example of code with this\n\t\t// problem: https://github.com/mrdoob/three.js/pull/11183\n\t\tif e.Value == 0 && math.Signbit(e.Value) {\n\t\t\tr := logger.Range{Loc: value.Loc, Len: 0}\n\t\t\tif int(r.Loc.Start) < len(p.source.Contents) && p.source.Contents[r.Loc.Start] == '-' {\n\t\t\t\tzeroRange := p.source.RangeOfNumber(logger.Loc{Start: r.Loc.Start + 1})\n\t\t\t\tr.Len = zeroRange.Len + 1\n\t\t\t}\n\t\t\ttext := fmt.Sprintf(\"Comparison with -0 using the %q operator will also match 0\", op)\n\t\t\tif op == \"case\" {\n\t\t\t\ttext = \"Comparison with -0 using a case clause will also match 0\"\n\t\t\t}\n\t\t\tkind := logger.Warning\n\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\tkind = logger.Debug\n\t\t\t}\n\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_EqualsNegativeZero, kind, &p.tracker, r, text,\n\t\t\t\t[]logger.MsgData{{Text: \"Floating-point equality is defined such that 0 and -0 are equal, so \\\"x === -0\\\" returns true for both 0 and -0. \" +\n\t\t\t\t\t\"You need to use \\\"Object.is(x, -0)\\\" instead to test for -0.\"}})\n\t\t\treturn true\n\t\t}\n\n\t\t// \"NaN === NaN\" is false in JavaScript\n\t\tif math.IsNaN(e.Value) {\n\t\t\ttext := fmt.Sprintf(\"Comparison with NaN using the %q operator here is always %v\", op, op[0] == '!')\n\t\t\tif op == \"case\" {\n\t\t\t\ttext = \"This case clause will never be evaluated because equality with NaN is always false\"\n\t\t\t}\n\t\t\tr := p.source.RangeOfOperatorBefore(afterOpLoc, op)\n\t\t\tkind := logger.Warning\n\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\tkind = logger.Debug\n\t\t\t}\n\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_EqualsNaN, kind, &p.tracker, r, text,\n\t\t\t\t[]logger.MsgData{{Text: \"Floating-point equality is defined such that NaN is never equal to anything, so \\\"x === NaN\\\" always returns false. \" +\n\t\t\t\t\t\"You need to use \\\"Number.isNaN(x)\\\" instead to test for NaN.\"}})\n\t\t\treturn true\n\t\t}\n\n\tcase *js_ast.EArray, *js_ast.EArrow, *js_ast.EClass,\n\t\t*js_ast.EFunction, *js_ast.EObject, *js_ast.ERegExp:\n\t\t// This warning only applies to strict equality because loose equality can\n\t\t// cause string conversions. For example, \"x == []\" is true if x is the\n\t\t// empty string. Here's an example of code with this problem:\n\t\t// https://github.com/aws/aws-sdk-js/issues/3325\n\t\tif len(op) > 2 {\n\t\t\ttext := fmt.Sprintf(\"Comparison using the %q operator here is always %v\", op, op[0] == '!')\n\t\t\tif op == \"case\" {\n\t\t\t\ttext = \"This case clause will never be evaluated because the comparison is always false\"\n\t\t\t}\n\t\t\tr := p.source.RangeOfOperatorBefore(afterOpLoc, op)\n\t\t\tkind := logger.Warning\n\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\tkind = logger.Debug\n\t\t\t}\n\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_EqualsNewObject, kind, &p.tracker, r, text,\n\t\t\t\t[]logger.MsgData{{Text: \"Equality with a new object is always false in JavaScript because the equality operator tests object identity. \" +\n\t\t\t\t\t\"You need to write code to compare the contents of the object instead. \" +\n\t\t\t\t\t\"For example, use \\\"Array.isArray(x) && x.length === 0\\\" instead of \\\"x === []\\\" to test for an empty array.\"}})\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\n// EDot nodes represent a property access. This function may return an\n// expression to replace the property access with. It assumes that the\n// target of the EDot expression has already been visited.\nfunc (p *parser) maybeRewritePropertyAccess(\n\tloc logger.Loc,\n\tassignTarget js_ast.AssignTarget,\n\tisDeleteTarget bool,\n\ttarget js_ast.Expr,\n\tname string,\n\tnameLoc logger.Loc,\n\tisCallTarget bool,\n\tisTemplateTag bool,\n\tpreferQuotedKey bool,\n) (js_ast.Expr, bool) {\n\tif id, ok := target.Data.(*js_ast.EIdentifier); ok {\n\t\t// Rewrite property accesses on explicit namespace imports as an identifier.\n\t\t// This lets us replace them easily in the printer to rebind them to\n\t\t// something else without paying the cost of a whole-tree traversal during\n\t\t// module linking just to rewrite these EDot expressions.\n\t\tif p.options.mode == config.ModeBundle {\n\t\t\tif importItems, ok := p.importItemsForNamespace[id.Ref]; ok {\n\t\t\t\t// Cache translation so each property access resolves to the same import\n\t\t\t\titem, ok := importItems.entries[name]\n\t\t\t\tif !ok {\n\t\t\t\t\t// Replace non-default imports with \"undefined\" for JSON import assertions\n\t\t\t\t\tif record := &p.importRecords[importItems.importRecordIndex]; (record.Flags&ast.AssertTypeJSON) != 0 && name != \"default\" {\n\t\t\t\t\t\tkind := logger.Warning\n\t\t\t\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\t\t\t\tkind = logger.Debug\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_AssertTypeJSON, kind, &p.tracker, js_lexer.RangeOfIdentifier(p.source, nameLoc),\n\t\t\t\t\t\t\tfmt.Sprintf(\"Non-default import %q is undefined with a JSON import assertion\", name),\n\t\t\t\t\t\t\tp.notesForAssertTypeJSON(record, name))\n\t\t\t\t\t\tp.ignoreUsage(id.Ref)\n\t\t\t\t\t\treturn js_ast.Expr{Loc: loc, Data: js_ast.EUndefinedShared}, true\n\t\t\t\t\t}\n\n\t\t\t\t\t// Generate a new import item symbol in the module scope\n\t\t\t\t\titem = ast.LocRef{Loc: nameLoc, Ref: p.newSymbol(ast.SymbolImport, name)}\n\t\t\t\t\tp.moduleScope.Generated = append(p.moduleScope.Generated, item.Ref)\n\n\t\t\t\t\t// Link the namespace import and the import item together\n\t\t\t\t\timportItems.entries[name] = item\n\t\t\t\t\tp.isImportItem[item.Ref] = true\n\n\t\t\t\t\tsymbol := &p.symbols[item.Ref.InnerIndex]\n\t\t\t\t\tif p.options.mode == config.ModePassThrough {\n\t\t\t\t\t\t// Make sure the printer prints this as a property access\n\t\t\t\t\t\tsymbol.NamespaceAlias = &ast.NamespaceAlias{\n\t\t\t\t\t\t\tNamespaceRef: id.Ref,\n\t\t\t\t\t\t\tAlias:        name,\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Mark this as generated in case it's missing. We don't want to\n\t\t\t\t\t\t// generate errors for missing import items that are automatically\n\t\t\t\t\t\t// generated.\n\t\t\t\t\t\tsymbol.ImportItemStatus = ast.ImportItemGenerated\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Undo the usage count for the namespace itself. This is used later\n\t\t\t\t// to detect whether the namespace symbol has ever been \"captured\"\n\t\t\t\t// or whether it has just been used to read properties off of.\n\t\t\t\t//\n\t\t\t\t// The benefit of doing this is that if both this module and the\n\t\t\t\t// imported module end up in the same module group and the namespace\n\t\t\t\t// symbol has never been captured, then we don't need to generate\n\t\t\t\t// any code for the namespace at all.\n\t\t\t\tp.ignoreUsage(id.Ref)\n\n\t\t\t\t// Track how many times we've referenced this symbol\n\t\t\t\tp.recordUsage(item.Ref)\n\t\t\t\treturn p.handleIdentifier(nameLoc, &js_ast.EIdentifier{Ref: item.Ref}, identifierOpts{\n\t\t\t\t\tassignTarget:    assignTarget,\n\t\t\t\t\tisCallTarget:    isCallTarget,\n\t\t\t\t\tisDeleteTarget:  isDeleteTarget,\n\t\t\t\t\tpreferQuotedKey: preferQuotedKey,\n\n\t\t\t\t\t// If this expression is used as the target of a call expression, make\n\t\t\t\t\t// sure the value of \"this\" is preserved.\n\t\t\t\t\twasOriginallyIdentifier: false,\n\t\t\t\t}), true\n\t\t\t}\n\n\t\t\t// Rewrite \"module.require()\" to \"require()\" for Webpack compatibility.\n\t\t\t// See https://github.com/webpack/webpack/pull/7750 for more info.\n\t\t\tif isCallTarget && id.Ref == p.moduleRef && name == \"require\" {\n\t\t\t\tp.ignoreUsage(p.moduleRef)\n\n\t\t\t\t// This uses \"require\" instead of a reference to our \"__require\"\n\t\t\t\t// function so that the code coming up that detects calls to\n\t\t\t\t// \"require\" will recognize it.\n\t\t\t\tp.recordUsage(p.requireRef)\n\t\t\t\treturn js_ast.Expr{Loc: nameLoc, Data: &js_ast.EIdentifier{Ref: p.requireRef}}, true\n\t\t\t}\n\t\t}\n\t}\n\n\t// Attempt to simplify statically-determined object literal property accesses\n\tif !isCallTarget && !isTemplateTag && p.options.minifySyntax && assignTarget == js_ast.AssignTargetNone {\n\t\tif object, ok := target.Data.(*js_ast.EObject); ok {\n\t\t\tvar replace js_ast.Expr\n\t\t\thasProtoNull := false\n\t\t\tisUnsafe := false\n\n\t\t\t// Check that doing this is safe\n\t\t\tfor _, prop := range object.Properties {\n\t\t\t\t// \"{ ...a }.a\" must be preserved\n\t\t\t\t// \"new ({ a() {} }.a)\" must throw\n\t\t\t\t// \"{ get a() {} }.a\" must be preserved\n\t\t\t\t// \"{ set a(b) {} }.a = 1\" must be preserved\n\t\t\t\t// \"{ a: 1, [String.fromCharCode(97)]: 2 }.a\" must be 2\n\t\t\t\tif prop.Kind == js_ast.PropertySpread || prop.Flags.Has(js_ast.PropertyIsComputed) || prop.Kind.IsMethodDefinition() {\n\t\t\t\t\tisUnsafe = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// Do not attempt to compare against numeric keys\n\t\t\t\tkey, ok := prop.Key.Data.(*js_ast.EString)\n\t\t\t\tif !ok {\n\t\t\t\t\tisUnsafe = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// The \"__proto__\" key has special behavior\n\t\t\t\tif helpers.UTF16EqualsString(key.Value, \"__proto__\") {\n\t\t\t\t\tif _, ok := prop.ValueOrNil.Data.(*js_ast.ENull); ok {\n\t\t\t\t\t\t// Replacing \"{__proto__: null}.a\" with undefined should be safe\n\t\t\t\t\t\thasProtoNull = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// This entire object literal must have no side effects\n\t\t\t\tif !p.astHelpers.ExprCanBeRemovedIfUnused(prop.ValueOrNil) {\n\t\t\t\t\tisUnsafe = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// Note that we need to take the last value if there are duplicate keys\n\t\t\t\tif helpers.UTF16EqualsString(key.Value, name) {\n\t\t\t\t\treplace = prop.ValueOrNil\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !isUnsafe {\n\t\t\t\t// If the key was found, return the value for that key. Note\n\t\t\t\t// that \"{__proto__: null}.__proto__\" is undefined, not null.\n\t\t\t\tif replace.Data != nil && name != \"__proto__\" {\n\t\t\t\t\treturn replace, true\n\t\t\t\t}\n\n\t\t\t\t// We can only return \"undefined\" when a key is missing if the prototype is null\n\t\t\t\tif hasProtoNull {\n\t\t\t\t\treturn js_ast.Expr{Loc: target.Loc, Data: js_ast.EUndefinedShared}, true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Handle references to namespaces or namespace members\n\tif target.Data == p.tsNamespaceTarget && assignTarget == js_ast.AssignTargetNone && !isDeleteTarget {\n\t\tif ns, ok := p.tsNamespaceMemberData.(*js_ast.TSNamespaceMemberNamespace); ok {\n\t\t\tif member, ok := ns.ExportedMembers[name]; ok {\n\t\t\t\tswitch m := member.Data.(type) {\n\t\t\t\tcase *js_ast.TSNamespaceMemberEnumNumber:\n\t\t\t\t\tp.ignoreUsageOfIdentifierInDotChain(target)\n\t\t\t\t\treturn p.wrapInlinedEnum(js_ast.Expr{Loc: loc, Data: &js_ast.ENumber{Value: m.Value}}, name), true\n\n\t\t\t\tcase *js_ast.TSNamespaceMemberEnumString:\n\t\t\t\t\tp.ignoreUsageOfIdentifierInDotChain(target)\n\t\t\t\t\treturn p.wrapInlinedEnum(js_ast.Expr{Loc: loc, Data: &js_ast.EString{Value: m.Value}}, name), true\n\n\t\t\t\tcase *js_ast.TSNamespaceMemberNamespace:\n\t\t\t\t\t// If this isn't a constant, return a clone of this property access\n\t\t\t\t\t// but with the namespace member data associated with it so that\n\t\t\t\t\t// more property accesses off of this property access are recognized.\n\t\t\t\t\tif preferQuotedKey || !js_ast.IsIdentifier(name) {\n\t\t\t\t\t\tp.tsNamespaceTarget = &js_ast.EIndex{\n\t\t\t\t\t\t\tTarget: target,\n\t\t\t\t\t\t\tIndex:  js_ast.Expr{Loc: nameLoc, Data: &js_ast.EString{Value: helpers.StringToUTF16(name)}},\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.tsNamespaceTarget = p.dotOrMangledPropVisit(target, name, nameLoc)\n\t\t\t\t\t}\n\t\t\t\t\tp.tsNamespaceMemberData = member.Data\n\t\t\t\t\treturn js_ast.Expr{Loc: loc, Data: p.tsNamespaceTarget}, true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Symbol uses due to a property access off of an imported symbol are tracked\n\t// specially. This lets us do tree shaking for cross-file TypeScript enums.\n\tif p.options.mode == config.ModeBundle && !p.isControlFlowDead {\n\t\tif id, ok := target.Data.(*js_ast.EImportIdentifier); ok {\n\t\t\t// Remove the normal symbol use\n\t\t\tuse := p.symbolUses[id.Ref]\n\t\t\tuse.CountEstimate--\n\t\t\tif use.CountEstimate == 0 {\n\t\t\t\tdelete(p.symbolUses, id.Ref)\n\t\t\t} else {\n\t\t\t\tp.symbolUses[id.Ref] = use\n\t\t\t}\n\n\t\t\t// Add a special symbol use instead\n\t\t\tif p.importSymbolPropertyUses == nil {\n\t\t\t\tp.importSymbolPropertyUses = make(map[ast.Ref]map[string]js_ast.SymbolUse)\n\t\t\t}\n\t\t\tproperties := p.importSymbolPropertyUses[id.Ref]\n\t\t\tif properties == nil {\n\t\t\t\tproperties = make(map[string]js_ast.SymbolUse)\n\t\t\t\tp.importSymbolPropertyUses[id.Ref] = properties\n\t\t\t}\n\t\t\tuse = properties[name]\n\t\t\tuse.CountEstimate++\n\t\t\tproperties[name] = use\n\t\t}\n\t}\n\n\t// Minify \"foo\".length\n\tif p.options.minifySyntax && assignTarget == js_ast.AssignTargetNone {\n\t\tswitch t := target.Data.(type) {\n\t\tcase *js_ast.EString:\n\t\t\tif name == \"length\" {\n\t\t\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.ENumber{Value: float64(len(t.Value))}}, true\n\t\t\t}\n\t\tcase *js_ast.EInlinedEnum:\n\t\t\tif s, ok := t.Value.Data.(*js_ast.EString); ok && name == \"length\" {\n\t\t\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.ENumber{Value: float64(len(s.Value))}}, true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn js_ast.Expr{}, false\n}\n\ntype exprIn struct {\n\tisMethod               bool\n\tisLoweredPrivateMethod bool\n\n\t// This tells us if there are optional chain expressions (EDot, EIndex, or\n\t// ECall) that are chained on to this expression. Because of the way the AST\n\t// works, chaining expressions on to this expression means they are our\n\t// parent expressions.\n\t//\n\t// Some examples:\n\t//\n\t//   a?.b.c  // EDot\n\t//   a?.b[c] // EIndex\n\t//   a?.b()  // ECall\n\t//\n\t// Note that this is false if our parent is a node with a OptionalChain\n\t// value of OptionalChainStart. That means it's the start of a new chain, so\n\t// it's not considered part of this one.\n\t//\n\t// Some examples:\n\t//\n\t//   a?.b?.c   // EDot\n\t//   a?.b?.[c] // EIndex\n\t//   a?.b?.()  // ECall\n\t//\n\t// Also note that this is false if our parent is a node with a OptionalChain\n\t// value of OptionalChainNone. That means it's outside parentheses, which\n\t// means it's no longer part of the chain.\n\t//\n\t// Some examples:\n\t//\n\t//   (a?.b).c  // EDot\n\t//   (a?.b)[c] // EIndex\n\t//   (a?.b)()  // ECall\n\t//\n\thasChainParent bool\n\n\t// If our parent is an ECall node with an OptionalChain value of\n\t// OptionalChainStart, then we will need to store the value for the \"this\" of\n\t// that call somewhere if the current expression is an optional chain that\n\t// ends in a property access. That's because the value for \"this\" will be\n\t// used twice: once for the inner optional chain and once for the outer\n\t// optional chain.\n\t//\n\t// Example:\n\t//\n\t//   // Original\n\t//   a?.b?.();\n\t//\n\t//   // Lowered\n\t//   var _a;\n\t//   (_a = a == null ? void 0 : a.b) == null ? void 0 : _a.call(a);\n\t//\n\t// In the example above we need to store \"a\" as the value for \"this\" so we\n\t// can substitute it back in when we call \"_a\" if \"_a\" is indeed present.\n\t// See also \"thisArgFunc\" and \"thisArgWrapFunc\" in \"exprOut\".\n\tstoreThisArgForParentOptionalChain bool\n\n\t// If true, string literals that match the current property mangling pattern\n\t// should be turned into ENameOfSymbol expressions, which will cause us to\n\t// rename them in the linker.\n\tshouldMangleStringsAsProps bool\n\n\t// Certain substitutions of identifiers are disallowed for assignment targets.\n\t// For example, we shouldn't transform \"undefined = 1\" into \"void 0 = 1\". This\n\t// isn't something real-world code would do but it matters for conformance\n\t// tests.\n\tassignTarget js_ast.AssignTarget\n}\n\ntype exprOut struct {\n\t// If our parent is an ECall node with an OptionalChain value of\n\t// OptionalChainContinue, then we may need to return the value for \"this\"\n\t// from this node or one of this node's children so that the parent that is\n\t// the end of the optional chain can use it.\n\t//\n\t// Example:\n\t//\n\t//   // Original\n\t//   a?.b?.().c();\n\t//\n\t//   // Lowered\n\t//   var _a;\n\t//   (_a = a == null ? void 0 : a.b) == null ? void 0 : _a.call(a).c();\n\t//\n\t// The value \"_a\" for \"this\" must be passed all the way up to the call to\n\t// \".c()\" which is where the optional chain is lowered. From there it must\n\t// be substituted as the value for \"this\" in the call to \".b?.()\". See also\n\t// \"storeThisArgForParentOptionalChain\" in \"exprIn\".\n\tthisArgFunc     func() js_ast.Expr\n\tthisArgWrapFunc func(js_ast.Expr) js_ast.Expr\n\n\t// True if the child node is an optional chain node (EDot, EIndex, or ECall\n\t// with an IsOptionalChain value of true)\n\tchildContainsOptionalChain bool\n\n\t// If true and this is used as a call target, the whole call expression\n\t// must be replaced with undefined.\n\tcallMustBeReplacedWithUndefined       bool\n\tmethodCallMustBeReplacedWithUndefined bool\n}\n\nfunc (p *parser) visitExpr(expr js_ast.Expr) js_ast.Expr {\n\texpr, _ = p.visitExprInOut(expr, exprIn{})\n\treturn expr\n}\n\nfunc (p *parser) valueForThis(\n\tloc logger.Loc,\n\tshouldLog bool,\n\tassignTarget js_ast.AssignTarget,\n\tisCallTarget bool,\n\tisDeleteTarget bool,\n) (js_ast.Expr, bool) {\n\t// Substitute \"this\" if we're inside a static class context\n\tif p.fnOnlyDataVisit.shouldReplaceThisWithInnerClassNameRef {\n\t\tp.recordUsage(*p.fnOnlyDataVisit.innerClassNameRef)\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: *p.fnOnlyDataVisit.innerClassNameRef}}, true\n\t}\n\n\t// Is this a top-level use of \"this\"?\n\tif !p.fnOnlyDataVisit.isThisNested {\n\t\t// Substitute user-specified defines\n\t\tif data, ok := p.options.defines.IdentifierDefines[\"this\"]; ok {\n\t\t\tif data.DefineExpr != nil {\n\t\t\t\treturn p.instantiateDefineExpr(loc, *data.DefineExpr, identifierOpts{\n\t\t\t\t\tassignTarget:   assignTarget,\n\t\t\t\t\tisCallTarget:   isCallTarget,\n\t\t\t\t\tisDeleteTarget: isDeleteTarget,\n\t\t\t\t}), true\n\t\t\t}\n\t\t}\n\n\t\t// Otherwise, replace top-level \"this\" with either \"undefined\" or \"exports\"\n\t\tif p.isFileConsideredToHaveESMExports {\n\t\t\t// Warn about \"this\" becoming undefined, but only once per file\n\t\t\tif shouldLog && !p.messageAboutThisIsUndefined && !p.fnOnlyDataVisit.silenceMessageAboutThisBeingUndefined {\n\t\t\t\tp.messageAboutThisIsUndefined = true\n\t\t\t\tkind := logger.Debug\n\t\t\t\tdata := p.tracker.MsgData(js_lexer.RangeOfIdentifier(p.source, loc),\n\t\t\t\t\t\"Top-level \\\"this\\\" will be replaced with undefined since this file is an ECMAScript module\")\n\t\t\t\tdata.Location.Suggestion = \"undefined\"\n\t\t\t\t_, notes := p.whyESModule()\n\t\t\t\tp.log.AddMsgID(logger.MsgID_JS_ThisIsUndefinedInESM, logger.Msg{Kind: kind, Data: data, Notes: notes})\n\t\t\t}\n\n\t\t\t// In an ES6 module, \"this\" is supposed to be undefined. Instead of\n\t\t\t// doing this at runtime using \"fn.call(undefined)\", we do it at\n\t\t\t// compile time using expression substitution here.\n\t\t\treturn js_ast.Expr{Loc: loc, Data: js_ast.EUndefinedShared}, true\n\t\t} else if p.options.mode != config.ModePassThrough {\n\t\t\t// In a CommonJS module, \"this\" is supposed to be the same as \"exports\".\n\t\t\t// Instead of doing this at runtime using \"fn.call(module.exports)\", we\n\t\t\t// do it at compile time using expression substitution here.\n\t\t\tp.recordUsage(p.exportsRef)\n\t\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: p.exportsRef}}, true\n\t\t}\n\t}\n\n\treturn js_ast.Expr{}, false\n}\n\nfunc (p *parser) valueForImportMeta(loc logger.Loc) (js_ast.Expr, bool) {\n\tif p.options.unsupportedJSFeatures.Has(compat.ImportMeta) ||\n\t\t(p.options.mode != config.ModePassThrough && !p.options.outputFormat.KeepESMImportExportSyntax()) {\n\t\t// Generate the variable if it doesn't exist yet\n\t\tif p.importMetaRef == ast.InvalidRef {\n\t\t\tp.importMetaRef = p.newSymbol(ast.SymbolOther, \"import_meta\")\n\t\t\tp.moduleScope.Generated = append(p.moduleScope.Generated, p.importMetaRef)\n\t\t}\n\n\t\t// Replace \"import.meta\" with a reference to the symbol\n\t\tp.recordUsage(p.importMetaRef)\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: p.importMetaRef}}, true\n\t}\n\n\treturn js_ast.Expr{}, false\n}\n\nfunc locAfterOp(e *js_ast.EBinary) logger.Loc {\n\tif e.Left.Loc.Start < e.Right.Loc.Start {\n\t\treturn e.Right.Loc\n\t} else {\n\t\t// Handle the case when we have transposed the operands\n\t\treturn e.Left.Loc\n\t}\n}\n\n// This function exists to tie all of these checks together in one place\nfunc isEvalOrArguments(name string) bool {\n\treturn name == \"eval\" || name == \"arguments\"\n}\n\nfunc (p *parser) reportPrivateNameUsage(name string) {\n\tif p.parseExperimentalDecoratorNesting > 0 {\n\t\tif p.lowerAllOfThesePrivateNames == nil {\n\t\t\tp.lowerAllOfThesePrivateNames = make(map[string]bool)\n\t\t}\n\t\tp.lowerAllOfThesePrivateNames[name] = true\n\t}\n}\n\nfunc (p *parser) isValidAssignmentTarget(expr js_ast.Expr) bool {\n\tswitch e := expr.Data.(type) {\n\tcase *js_ast.EIdentifier:\n\t\tif p.isStrictMode() {\n\t\t\tif name := p.loadNameFromRef(e.Ref); isEvalOrArguments(name) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\tcase *js_ast.EDot:\n\t\treturn e.OptionalChain == js_ast.OptionalChainNone\n\tcase *js_ast.EIndex:\n\t\treturn e.OptionalChain == js_ast.OptionalChainNone\n\n\t// Don't worry about recursive checking for objects and arrays. This will\n\t// already be handled naturally by passing down the assign target flag.\n\tcase *js_ast.EObject:\n\t\treturn !e.IsParenthesized\n\tcase *js_ast.EArray:\n\t\treturn !e.IsParenthesized\n\t}\n\treturn false\n}\n\nfunc containsClosingScriptTag(text string) bool {\n\tfor {\n\t\ti := strings.Index(text, \"</\")\n\t\tif i < 0 {\n\t\t\tbreak\n\t\t}\n\t\ttext = text[i+2:]\n\t\tif len(text) >= 6 && strings.EqualFold(text[:6], \"script\") {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (p *parser) isUnsupportedRegularExpression(loc logger.Loc, value string) (pattern string, flags string, isUnsupported bool) {\n\tvar what string\n\tvar r logger.Range\n\n\tend := strings.LastIndexByte(value, '/')\n\tpattern = value[1:end]\n\tflags = value[end+1:]\n\tisUnicode := strings.IndexByte(flags, 'u') >= 0\n\tparenDepth := 0\n\ti := 0\n\n\t// Do a simple scan for unsupported features assuming the regular expression\n\t// is valid. This doesn't do a full validation of the regular expression\n\t// because regular expression grammar is complicated. If it contains a syntax\n\t// error that we don't catch, then we will just generate output code with a\n\t// syntax error. Garbage in, garbage out.\npattern:\n\tfor i < len(pattern) {\n\t\tc := pattern[i]\n\t\ti++\n\n\t\tswitch c {\n\t\tcase '[':\n\t\tclass:\n\t\t\tfor i < len(pattern) {\n\t\t\t\tc := pattern[i]\n\t\t\t\ti++\n\n\t\t\t\tswitch c {\n\t\t\t\tcase ']':\n\t\t\t\t\tbreak class\n\n\t\t\t\tcase '\\\\':\n\t\t\t\t\ti++ // Skip the escaped character\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase '(':\n\t\t\ttail := pattern[i:]\n\n\t\t\tif strings.HasPrefix(tail, \"?<=\") || strings.HasPrefix(tail, \"?<!\") {\n\t\t\t\tif p.options.unsupportedJSFeatures.Has(compat.RegexpLookbehindAssertions) {\n\t\t\t\t\twhat = \"Lookbehind assertions in regular expressions are not available\"\n\t\t\t\t\tr = logger.Range{Loc: logger.Loc{Start: loc.Start + int32(i) + 1}, Len: 3}\n\t\t\t\t\tisUnsupported = true\n\t\t\t\t\tbreak pattern\n\t\t\t\t}\n\t\t\t} else if strings.HasPrefix(tail, \"?<\") {\n\t\t\t\tif p.options.unsupportedJSFeatures.Has(compat.RegexpNamedCaptureGroups) {\n\t\t\t\t\tif end := strings.IndexByte(tail, '>'); end >= 0 {\n\t\t\t\t\t\twhat = \"Named capture groups in regular expressions are not available\"\n\t\t\t\t\t\tr = logger.Range{Loc: logger.Loc{Start: loc.Start + int32(i) + 1}, Len: int32(end) + 1}\n\t\t\t\t\t\tisUnsupported = true\n\t\t\t\t\t\tbreak pattern\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tparenDepth++\n\n\t\tcase ')':\n\t\t\tif parenDepth == 0 {\n\t\t\t\tr := logger.Range{Loc: logger.Loc{Start: loc.Start + int32(i)}, Len: 1}\n\t\t\t\tp.log.AddError(&p.tracker, r, \"Unexpected \\\")\\\" in regular expression\")\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tparenDepth--\n\n\t\tcase '\\\\':\n\t\t\ttail := pattern[i:]\n\n\t\t\tif isUnicode && (strings.HasPrefix(tail, \"p{\") || strings.HasPrefix(tail, \"P{\")) {\n\t\t\t\tif p.options.unsupportedJSFeatures.Has(compat.RegexpUnicodePropertyEscapes) {\n\t\t\t\t\tif end := strings.IndexByte(tail, '}'); end >= 0 {\n\t\t\t\t\t\twhat = \"Unicode property escapes in regular expressions are not available\"\n\t\t\t\t\t\tr = logger.Range{Loc: logger.Loc{Start: loc.Start + int32(i)}, Len: int32(end) + 2}\n\t\t\t\t\t\tisUnsupported = true\n\t\t\t\t\t\tbreak pattern\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ti++ // Skip the escaped character\n\t\t}\n\t}\n\n\tif !isUnsupported {\n\t\tfor i, c := range flags {\n\t\t\tswitch c {\n\t\t\tcase 'g', 'i', 'm':\n\t\t\t\tcontinue // These are part of ES5 and are always supported\n\n\t\t\tcase 's':\n\t\t\t\tif !p.options.unsupportedJSFeatures.Has(compat.RegexpDotAllFlag) {\n\t\t\t\t\tcontinue // This is part of ES2018\n\t\t\t\t}\n\n\t\t\tcase 'y', 'u':\n\t\t\t\tif !p.options.unsupportedJSFeatures.Has(compat.RegexpStickyAndUnicodeFlags) {\n\t\t\t\t\tcontinue // These are part of ES2018\n\t\t\t\t}\n\n\t\t\tcase 'd':\n\t\t\t\tif !p.options.unsupportedJSFeatures.Has(compat.RegexpMatchIndices) {\n\t\t\t\t\tcontinue // This is part of ES2022\n\t\t\t\t}\n\n\t\t\tcase 'v':\n\t\t\t\tif !p.options.unsupportedJSFeatures.Has(compat.RegexpSetNotation) {\n\t\t\t\t\tcontinue // This is from a proposal: https://github.com/tc39/proposal-regexp-v-flag\n\t\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\t// Unknown flags are never supported\n\t\t\t}\n\n\t\t\tr = logger.Range{Loc: logger.Loc{Start: loc.Start + int32(end+1) + int32(i)}, Len: 1}\n\t\t\twhat = fmt.Sprintf(\"The regular expression flag \\\"%c\\\" is not available\", c)\n\t\t\tisUnsupported = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif isUnsupported {\n\t\twhere := config.PrettyPrintTargetEnvironment(p.options.originalTargetEnv, p.options.unsupportedJSFeatureOverridesMask)\n\t\tp.log.AddIDWithNotes(logger.MsgID_JS_UnsupportedRegExp, logger.Debug, &p.tracker, r, fmt.Sprintf(\"%s in %s\", what, where), []logger.MsgData{{\n\t\t\tText: \"This regular expression literal has been converted to a \\\"new RegExp()\\\" constructor \" +\n\t\t\t\t\"to avoid generating code with a syntax error. However, you will need to include a \" +\n\t\t\t\t\"polyfill for \\\"RegExp\\\" for your code to have the correct behavior at run-time.\"}})\n\t}\n\n\treturn\n}\n\n// This function takes \"exprIn\" as input from the caller and produces \"exprOut\"\n// for the caller to pass along extra data. This is mostly for optional chaining.\nfunc (p *parser) visitExprInOut(expr js_ast.Expr, in exprIn) (js_ast.Expr, exprOut) {\n\tif in.assignTarget != js_ast.AssignTargetNone && !p.isValidAssignmentTarget(expr) {\n\t\tp.log.AddError(&p.tracker, logger.Range{Loc: expr.Loc}, \"Invalid assignment target\")\n\t}\n\n\t// Note: Anything added before or after this switch statement will be bypassed\n\t// when visiting nested \"EBinary\" nodes due to stack overflow mitigations for\n\t// deeply-nested ASTs. If anything like that is added, care must be taken that\n\t// it doesn't affect these mitigations by ensuring that the mitigations are not\n\t// applied in those cases (e.g. by adding an additional conditional check).\n\tswitch e := expr.Data.(type) {\n\tcase *js_ast.ENull, *js_ast.ESuper, *js_ast.EBoolean, *js_ast.EUndefined, *js_ast.EJSXText:\n\n\tcase *js_ast.EBigInt:\n\t\tif p.options.unsupportedJSFeatures.Has(compat.Bigint) {\n\t\t\t// For ease of implementation, the actual reference of the \"BigInt\"\n\t\t\t// symbol is deferred to print time. That means we don't have to\n\t\t\t// special-case the \"BigInt\" constructor in side-effect computations\n\t\t\t// and future big integer constant folding (of which there isn't any\n\t\t\t// at the moment).\n\t\t\tp.markSyntaxFeature(compat.Bigint, p.source.RangeOfNumber(expr.Loc))\n\t\t\tp.recordUsage(p.makeBigIntRef())\n\t\t}\n\n\tcase *js_ast.ENameOfSymbol:\n\t\te.Ref = p.symbolForMangledProp(p.loadNameFromRef(e.Ref))\n\n\tcase *js_ast.ERegExp:\n\t\t// \"/pattern/flags\" => \"new RegExp('pattern', 'flags')\"\n\t\tif pattern, flags, ok := p.isUnsupportedRegularExpression(expr.Loc, e.Value); ok {\n\t\t\targs := []js_ast.Expr{{\n\t\t\t\tLoc:  logger.Loc{Start: expr.Loc.Start + 1},\n\t\t\t\tData: &js_ast.EString{Value: helpers.StringToUTF16(pattern)},\n\t\t\t}}\n\t\t\tif flags != \"\" {\n\t\t\t\targs = append(args, js_ast.Expr{\n\t\t\t\t\tLoc:  logger.Loc{Start: expr.Loc.Start + int32(len(pattern)) + 2},\n\t\t\t\t\tData: &js_ast.EString{Value: helpers.StringToUTF16(flags)},\n\t\t\t\t})\n\t\t\t}\n\t\t\tregExpRef := p.makeRegExpRef()\n\t\t\tp.recordUsage(regExpRef)\n\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENew{\n\t\t\t\tTarget:        js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EIdentifier{Ref: regExpRef}},\n\t\t\t\tArgs:          args,\n\t\t\t\tCloseParenLoc: logger.Loc{Start: expr.Loc.Start + int32(len(e.Value))},\n\t\t\t}}, exprOut{}\n\t\t}\n\n\tcase *js_ast.ENewTarget:\n\t\tif !p.fnOnlyDataVisit.isNewTargetAllowed {\n\t\t\tp.log.AddError(&p.tracker, e.Range, \"Cannot use \\\"new.target\\\" here:\")\n\t\t}\n\n\tcase *js_ast.EString:\n\t\tif e.LegacyOctalLoc.Start > 0 {\n\t\t\tif e.PreferTemplate {\n\t\t\t\tp.log.AddError(&p.tracker, p.source.RangeOfLegacyOctalEscape(e.LegacyOctalLoc),\n\t\t\t\t\t\"Legacy octal escape sequences cannot be used in template literals\")\n\t\t\t} else if p.isStrictMode() {\n\t\t\t\tp.markStrictModeFeature(legacyOctalEscape, p.source.RangeOfLegacyOctalEscape(e.LegacyOctalLoc), \"\")\n\t\t\t}\n\t\t}\n\n\t\tif in.shouldMangleStringsAsProps && p.options.mangleQuoted && !e.PreferTemplate {\n\t\t\tif name := helpers.UTF16ToString(e.Value); p.isMangledProp(name) {\n\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENameOfSymbol{\n\t\t\t\t\tRef:                   p.symbolForMangledProp(name),\n\t\t\t\t\tHasPropertyKeyComment: e.HasPropertyKeyComment,\n\t\t\t\t}}, exprOut{}\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.ENumber:\n\t\tif p.legacyOctalLiterals != nil && p.isStrictMode() {\n\t\t\tif r, ok := p.legacyOctalLiterals[expr.Data]; ok {\n\t\t\t\tp.markStrictModeFeature(legacyOctalLiteral, r, \"\")\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.EThis:\n\t\tisDeleteTarget := e == p.deleteTarget\n\t\tisCallTarget := e == p.callTarget\n\n\t\tp.fnOnlyDataVisit.hasThisUsage = true\n\n\t\tif value, ok := p.valueForThis(expr.Loc, true /* shouldLog */, in.assignTarget, isDeleteTarget, isCallTarget); ok {\n\t\t\treturn value, exprOut{}\n\t\t}\n\n\t\t// Capture \"this\" inside arrow functions that will be lowered into normal\n\t\t// function expressions for older language environments\n\t\tif p.fnOrArrowDataVisit.isArrow && p.options.unsupportedJSFeatures.Has(compat.Arrow) && p.fnOnlyDataVisit.isThisNested {\n\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EIdentifier{Ref: p.captureThis()}}, exprOut{}\n\t\t}\n\n\tcase *js_ast.EImportMeta:\n\t\tisDeleteTarget := e == p.deleteTarget\n\t\tisCallTarget := e == p.callTarget\n\n\t\t// Check both user-specified defines and known globals\n\t\tif defines, ok := p.options.defines.DotDefines[\"meta\"]; ok {\n\t\t\tfor _, define := range defines {\n\t\t\t\tif p.isDotOrIndexDefineMatch(expr, define.KeyParts) {\n\t\t\t\t\t// Substitute user-specified defines\n\t\t\t\t\tif define.DefineExpr != nil {\n\t\t\t\t\t\treturn p.instantiateDefineExpr(expr.Loc, *define.DefineExpr, identifierOpts{\n\t\t\t\t\t\t\tassignTarget:   in.assignTarget,\n\t\t\t\t\t\t\tisCallTarget:   isCallTarget,\n\t\t\t\t\t\t\tisDeleteTarget: isDeleteTarget,\n\t\t\t\t\t\t}), exprOut{}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Check injected dot names\n\t\tif names, ok := p.injectedDotNames[\"meta\"]; ok {\n\t\t\tfor _, name := range names {\n\t\t\t\tif p.isDotOrIndexDefineMatch(expr, name.parts) {\n\t\t\t\t\t// Note: We don't need to \"ignoreRef\" on the underlying identifier\n\t\t\t\t\t// because we have only parsed it but not visited it yet\n\t\t\t\t\treturn p.instantiateInjectDotName(expr.Loc, name, in.assignTarget), exprOut{}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Warn about \"import.meta\" if it's not replaced by a define\n\t\tif p.options.unsupportedJSFeatures.Has(compat.ImportMeta) {\n\t\t\tr := logger.Range{Loc: expr.Loc, Len: e.RangeLen}\n\t\t\tp.markSyntaxFeature(compat.ImportMeta, r)\n\t\t} else if p.options.mode != config.ModePassThrough && !p.options.outputFormat.KeepESMImportExportSyntax() {\n\t\t\tr := logger.Range{Loc: expr.Loc, Len: e.RangeLen}\n\t\t\tkind := logger.Warning\n\t\t\tif p.suppressWarningsAboutWeirdCode || p.fnOrArrowDataVisit.tryBodyCount > 0 {\n\t\t\t\tkind = logger.Debug\n\t\t\t}\n\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_EmptyImportMeta, kind, &p.tracker, r, fmt.Sprintf(\n\t\t\t\t\"\\\"import.meta\\\" is not available with the %q output format and will be empty\", p.options.outputFormat.String()),\n\t\t\t\t[]logger.MsgData{{Text: \"You need to set the output format to \\\"esm\\\" for \\\"import.meta\\\" to work correctly.\"}})\n\t\t}\n\n\t\t// Convert \"import.meta\" to a variable if it's not supported in the output format\n\t\tif importMeta, ok := p.valueForImportMeta(expr.Loc); ok {\n\t\t\treturn importMeta, exprOut{}\n\t\t}\n\n\tcase *js_ast.ESpread:\n\t\te.Value = p.visitExpr(e.Value)\n\n\tcase *js_ast.EIdentifier:\n\t\tisCallTarget := e == p.callTarget\n\t\tisDeleteTarget := e == p.deleteTarget\n\t\tname := p.loadNameFromRef(e.Ref)\n\t\tif p.isStrictMode() && js_lexer.StrictModeReservedWords[name] {\n\t\t\tp.markStrictModeFeature(reservedWord, js_lexer.RangeOfIdentifier(p.source, expr.Loc), name)\n\t\t}\n\t\tresult := p.findSymbol(expr.Loc, name)\n\t\te.MustKeepDueToWithStmt = result.isInsideWithScope\n\t\te.Ref = result.ref\n\n\t\t// Handle referencing a class name within that class's computed property\n\t\t// key. This is not allowed, and must fail at run-time:\n\t\t//\n\t\t//   class Foo {\n\t\t//     static foo = 'bar'\n\t\t//     static [Foo.foo] = 'foo'\n\t\t//   }\n\t\t//\n\t\tif p.symbols[result.ref.InnerIndex].Kind == ast.SymbolClassInComputedPropertyKey {\n\t\t\tp.log.AddID(logger.MsgID_JS_ClassNameWillThrow, logger.Warning, &p.tracker, js_lexer.RangeOfIdentifier(p.source, expr.Loc),\n\t\t\t\tfmt.Sprintf(\"Accessing class %q before initialization will throw\", name))\n\t\t\treturn p.callRuntime(expr.Loc, \"__earlyAccess\", []js_ast.Expr{{Loc: expr.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(name)}}}), exprOut{}\n\t\t}\n\n\t\t// Handle assigning to a constant\n\t\tif in.assignTarget != js_ast.AssignTargetNone {\n\t\t\tswitch p.symbols[result.ref.InnerIndex].Kind {\n\t\t\tcase ast.SymbolConst:\n\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, expr.Loc)\n\t\t\t\tnotes := []logger.MsgData{p.tracker.MsgData(js_lexer.RangeOfIdentifier(p.source, result.declareLoc),\n\t\t\t\t\tfmt.Sprintf(\"The symbol %q was declared a constant here:\", name))}\n\n\t\t\t\t// Make this an error when bundling because we may need to convert this\n\t\t\t\t// \"const\" into a \"var\" during bundling. Also make this an error when\n\t\t\t\t// the constant is inlined because we will otherwise generate code with\n\t\t\t\t// a syntax error.\n\t\t\t\tif _, isInlinedConstant := p.constValues[result.ref]; isInlinedConstant || p.options.mode == config.ModeBundle ||\n\t\t\t\t\t(p.currentScope.Parent == nil && p.willWrapModuleInTryCatchForUsing) {\n\t\t\t\t\tp.log.AddErrorWithNotes(&p.tracker, r,\n\t\t\t\t\t\tfmt.Sprintf(\"Cannot assign to %q because it is a constant\", name), notes)\n\t\t\t\t} else {\n\t\t\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_AssignToConstant, logger.Warning, &p.tracker, r,\n\t\t\t\t\t\tfmt.Sprintf(\"This assignment will throw because %q is a constant\", name), notes)\n\t\t\t\t}\n\n\t\t\tcase ast.SymbolInjected:\n\t\t\t\tif where, ok := p.injectedSymbolSources[result.ref]; ok {\n\t\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, expr.Loc)\n\t\t\t\t\ttracker := logger.MakeLineColumnTracker(&where.source)\n\t\t\t\t\tp.log.AddErrorWithNotes(&p.tracker, r,\n\t\t\t\t\t\tfmt.Sprintf(\"Cannot assign to %q because it's an import from an injected file\", name),\n\t\t\t\t\t\t[]logger.MsgData{tracker.MsgData(js_lexer.RangeOfIdentifier(where.source, where.loc),\n\t\t\t\t\t\t\tfmt.Sprintf(\"The symbol %q was exported from %q here:\",\n\t\t\t\t\t\t\t\tname, where.source.PrettyPaths.Select(p.options.logPathStyle)))})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Substitute user-specified defines for unbound or injected symbols\n\t\tmethodCallMustBeReplacedWithUndefined := false\n\t\tif p.symbols[e.Ref.InnerIndex].Kind.IsUnboundOrInjected() && !result.isInsideWithScope && e != p.deleteTarget {\n\t\t\tif data, ok := p.options.defines.IdentifierDefines[name]; ok {\n\t\t\t\tif data.DefineExpr != nil {\n\t\t\t\t\tnew := p.instantiateDefineExpr(expr.Loc, *data.DefineExpr, identifierOpts{\n\t\t\t\t\t\tassignTarget:   in.assignTarget,\n\t\t\t\t\t\tisCallTarget:   isCallTarget,\n\t\t\t\t\t\tisDeleteTarget: isDeleteTarget,\n\t\t\t\t\t})\n\t\t\t\t\tif in.assignTarget == js_ast.AssignTargetNone || defineValueCanBeUsedInAssignTarget(new.Data) {\n\t\t\t\t\t\tp.ignoreUsage(e.Ref)\n\t\t\t\t\t\treturn new, exprOut{}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.logAssignToDefine(js_lexer.RangeOfIdentifier(p.source, expr.Loc), name, js_ast.Expr{})\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Copy the side effect flags over in case this expression is unused\n\t\t\t\tif data.Flags.Has(config.CanBeRemovedIfUnused) {\n\t\t\t\t\te.CanBeRemovedIfUnused = true\n\t\t\t\t}\n\t\t\t\tif data.Flags.Has(config.CallCanBeUnwrappedIfUnused) && !p.options.ignoreDCEAnnotations {\n\t\t\t\t\te.CallCanBeUnwrappedIfUnused = true\n\t\t\t\t}\n\t\t\t\tif data.Flags.Has(config.MethodCallsMustBeReplacedWithUndefined) {\n\t\t\t\t\tmethodCallMustBeReplacedWithUndefined = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn p.handleIdentifier(expr.Loc, e, identifierOpts{\n\t\t\t\tassignTarget:            in.assignTarget,\n\t\t\t\tisCallTarget:            isCallTarget,\n\t\t\t\tisDeleteTarget:          isDeleteTarget,\n\t\t\t\twasOriginallyIdentifier: true,\n\t\t\t}), exprOut{\n\t\t\t\tmethodCallMustBeReplacedWithUndefined: methodCallMustBeReplacedWithUndefined,\n\t\t\t}\n\n\tcase *js_ast.EJSXElement:\n\t\tpropsLoc := expr.Loc\n\n\t\t// Resolving the location index to a specific line and column in\n\t\t// development mode is not too expensive because we seek from the\n\t\t// previous JSX element. It amounts to at most a single additional\n\t\t// scan over the source code. Note that this has to happen before\n\t\t// we visit anything about this JSX element to make sure that we\n\t\t// only ever need to scan forward, not backward.\n\t\tvar jsxSourceLine int\n\t\tvar jsxSourceColumn int\n\t\tif p.options.jsx.Development && p.options.jsx.AutomaticRuntime {\n\t\t\tfor p.jsxSourceLoc < int(propsLoc.Start) {\n\t\t\t\tr, size := utf8.DecodeRuneInString(p.source.Contents[p.jsxSourceLoc:])\n\t\t\t\tp.jsxSourceLoc += size\n\t\t\t\tif r == '\\n' || r == '\\r' || r == '\\u2028' || r == '\\u2029' {\n\t\t\t\t\tif r == '\\r' && p.jsxSourceLoc < len(p.source.Contents) && p.source.Contents[p.jsxSourceLoc] == '\\n' {\n\t\t\t\t\t\tp.jsxSourceLoc++ // Handle Windows-style CRLF newlines\n\t\t\t\t\t}\n\t\t\t\t\tp.jsxSourceLine++\n\t\t\t\t\tp.jsxSourceColumn = 0\n\t\t\t\t} else {\n\t\t\t\t\t// Babel and TypeScript count columns in UTF-16 code units\n\t\t\t\t\tif r < 0xFFFF {\n\t\t\t\t\t\tp.jsxSourceColumn++\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.jsxSourceColumn += 2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tjsxSourceLine = p.jsxSourceLine\n\t\t\tjsxSourceColumn = p.jsxSourceColumn\n\t\t}\n\n\t\tif e.TagOrNil.Data != nil {\n\t\t\tpropsLoc = e.TagOrNil.Loc\n\t\t\te.TagOrNil = p.visitExpr(e.TagOrNil)\n\t\t\tp.warnAboutImportNamespaceCall(e.TagOrNil, exprKindJSXTag)\n\t\t}\n\n\t\t// Visit properties\n\t\thasSpread := false\n\t\tfor i, property := range e.Properties {\n\t\t\tif property.Kind == js_ast.PropertySpread {\n\t\t\t\thasSpread = true\n\t\t\t} else {\n\t\t\t\tif mangled, ok := property.Key.Data.(*js_ast.ENameOfSymbol); ok {\n\t\t\t\t\tmangled.Ref = p.symbolForMangledProp(p.loadNameFromRef(mangled.Ref))\n\t\t\t\t} else {\n\t\t\t\t\tproperty.Key = p.visitExpr(property.Key)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif property.ValueOrNil.Data != nil {\n\t\t\t\tproperty.ValueOrNil = p.visitExpr(property.ValueOrNil)\n\t\t\t}\n\t\t\tif property.InitializerOrNil.Data != nil {\n\t\t\t\tproperty.InitializerOrNil = p.visitExpr(property.InitializerOrNil)\n\t\t\t}\n\t\t\te.Properties[i] = property\n\t\t}\n\n\t\t// \"{a, ...{b, c}, d}\" => \"{a, b, c, d}\"\n\t\tif p.options.minifySyntax && hasSpread {\n\t\t\te.Properties = js_ast.MangleObjectSpread(e.Properties)\n\t\t}\n\n\t\t// Visit children\n\t\tif len(e.NullableChildren) > 0 {\n\t\t\tfor i, childOrNil := range e.NullableChildren {\n\t\t\t\tif childOrNil.Data != nil {\n\t\t\t\t\te.NullableChildren[i] = p.visitExpr(childOrNil)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif p.options.jsx.Preserve {\n\t\t\t// If the tag is an identifier, mark it as needing to be upper-case\n\t\t\tswitch tag := e.TagOrNil.Data.(type) {\n\t\t\tcase *js_ast.EIdentifier:\n\t\t\t\tp.symbols[tag.Ref.InnerIndex].Flags |= ast.MustStartWithCapitalLetterForJSX\n\n\t\t\tcase *js_ast.EImportIdentifier:\n\t\t\t\tp.symbols[tag.Ref.InnerIndex].Flags |= ast.MustStartWithCapitalLetterForJSX\n\t\t\t}\n\t\t} else {\n\t\t\t// Remove any nil children in the array (in place) before iterating over it\n\t\t\tchildren := e.NullableChildren\n\t\t\t{\n\t\t\t\tend := 0\n\t\t\t\tfor _, childOrNil := range children {\n\t\t\t\t\tif childOrNil.Data != nil {\n\t\t\t\t\t\tchildren[end] = childOrNil\n\t\t\t\t\t\tend++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tchildren = children[:end]\n\t\t\t}\n\n\t\t\t// A missing tag is a fragment\n\t\t\tif e.TagOrNil.Data == nil {\n\t\t\t\tif p.options.jsx.AutomaticRuntime {\n\t\t\t\t\te.TagOrNil = p.importJSXSymbol(expr.Loc, JSXImportFragment)\n\t\t\t\t} else {\n\t\t\t\t\te.TagOrNil = p.instantiateDefineExpr(expr.Loc, p.options.jsx.Fragment, identifierOpts{\n\t\t\t\t\t\twasOriginallyIdentifier: true,\n\t\t\t\t\t\tmatchAgainstDefines:     true, // Allow defines to rewrite the JSX fragment factory\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tshouldUseCreateElement := !p.options.jsx.AutomaticRuntime\n\t\t\tif !shouldUseCreateElement {\n\t\t\t\t// Even for runtime=\"automatic\", <div {...props} key={key} /> is special cased to createElement\n\t\t\t\t// See https://github.com/babel/babel/blob/e482c763466ba3f44cb9e3467583b78b7f030b4a/packages/babel-plugin-transform-react-jsx/src/create-plugin.ts#L352\n\t\t\t\tseenPropsSpread := false\n\t\t\t\tfor _, property := range e.Properties {\n\t\t\t\t\tif seenPropsSpread && property.Kind == js_ast.PropertyField {\n\t\t\t\t\t\tif str, ok := property.Key.Data.(*js_ast.EString); ok && helpers.UTF16EqualsString(str.Value, \"key\") {\n\t\t\t\t\t\t\tshouldUseCreateElement = true\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if property.Kind == js_ast.PropertySpread {\n\t\t\t\t\t\tseenPropsSpread = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif shouldUseCreateElement {\n\t\t\t\t// Arguments to createElement()\n\t\t\t\targs := []js_ast.Expr{e.TagOrNil}\n\t\t\t\tif len(e.Properties) > 0 {\n\t\t\t\t\targs = append(args, p.lowerObjectSpread(propsLoc, &js_ast.EObject{\n\t\t\t\t\t\tProperties:   e.Properties,\n\t\t\t\t\t\tIsSingleLine: e.IsTagSingleLine,\n\t\t\t\t\t}))\n\t\t\t\t} else {\n\t\t\t\t\targs = append(args, js_ast.Expr{Loc: propsLoc, Data: js_ast.ENullShared})\n\t\t\t\t}\n\t\t\t\tif len(children) > 0 {\n\t\t\t\t\targs = append(args, children...)\n\t\t\t\t}\n\n\t\t\t\t// Call createElement()\n\t\t\t\tvar target js_ast.Expr\n\t\t\t\tkind := js_ast.NormalCall\n\t\t\t\tif p.options.jsx.AutomaticRuntime {\n\t\t\t\t\ttarget = p.importJSXSymbol(expr.Loc, JSXImportCreateElement)\n\t\t\t\t} else {\n\t\t\t\t\ttarget = p.instantiateDefineExpr(expr.Loc, p.options.jsx.Factory, identifierOpts{\n\t\t\t\t\t\twasOriginallyIdentifier: true,\n\t\t\t\t\t\tmatchAgainstDefines:     true, // Allow defines to rewrite the JSX factory\n\t\t\t\t\t})\n\t\t\t\t\tif js_ast.IsPropertyAccess(target) {\n\t\t\t\t\t\tkind = js_ast.TargetWasOriginallyPropertyAccess\n\t\t\t\t\t}\n\t\t\t\t\tp.warnAboutImportNamespaceCall(target, exprKindCall)\n\t\t\t\t}\n\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ECall{\n\t\t\t\t\tTarget:        target,\n\t\t\t\t\tArgs:          args,\n\t\t\t\t\tCloseParenLoc: e.CloseLoc,\n\t\t\t\t\tIsMultiLine:   !e.IsTagSingleLine,\n\t\t\t\t\tKind:          kind,\n\n\t\t\t\t\t// Enable tree shaking\n\t\t\t\t\tCanBeUnwrappedIfUnused: !p.options.ignoreDCEAnnotations && !p.options.jsx.SideEffects,\n\t\t\t\t}}, exprOut{}\n\t\t\t} else {\n\t\t\t\t// Arguments to jsx()\n\t\t\t\targs := []js_ast.Expr{e.TagOrNil}\n\n\t\t\t\t// Props argument\n\t\t\t\tproperties := make([]js_ast.Property, 0, len(e.Properties)+1)\n\n\t\t\t\t// For jsx(), \"key\" is passed in as a separate argument, so filter it out\n\t\t\t\t// from the props here. Also, check for __source and __self, which might have\n\t\t\t\t// been added by some upstream plugin. Their presence here would represent a\n\t\t\t\t// configuration error.\n\t\t\t\thasKey := false\n\t\t\t\tkeyProperty := js_ast.Expr{Loc: expr.Loc, Data: js_ast.EUndefinedShared}\n\t\t\t\tfor _, property := range e.Properties {\n\t\t\t\t\tif str, ok := property.Key.Data.(*js_ast.EString); ok {\n\t\t\t\t\t\tpropName := helpers.UTF16ToString(str.Value)\n\t\t\t\t\t\tswitch propName {\n\t\t\t\t\t\tcase \"key\":\n\t\t\t\t\t\t\tif boolean, ok := property.ValueOrNil.Data.(*js_ast.EBoolean); ok && boolean.Value && property.Flags.Has(js_ast.PropertyWasShorthand) {\n\t\t\t\t\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, property.Loc)\n\t\t\t\t\t\t\t\tmsg := logger.Msg{\n\t\t\t\t\t\t\t\t\tKind:  logger.Error,\n\t\t\t\t\t\t\t\t\tData:  p.tracker.MsgData(r, \"Please provide an explicit value for \\\"key\\\":\"),\n\t\t\t\t\t\t\t\t\tNotes: []logger.MsgData{{Text: \"Using \\\"key\\\" as a shorthand for \\\"key={true}\\\" is not allowed when using React's \\\"automatic\\\" JSX transform.\"}},\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tmsg.Data.Location.Suggestion = \"key={true}\"\n\t\t\t\t\t\t\t\tp.log.AddMsg(msg)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tkeyProperty = property.ValueOrNil\n\t\t\t\t\t\t\t\thasKey = true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontinue\n\n\t\t\t\t\t\tcase \"__source\", \"__self\":\n\t\t\t\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, property.Loc)\n\t\t\t\t\t\t\tp.log.AddErrorWithNotes(&p.tracker, r,\n\t\t\t\t\t\t\t\tfmt.Sprintf(\"Duplicate \\\"%s\\\" prop found:\", propName),\n\t\t\t\t\t\t\t\t[]logger.MsgData{{Text: \"Both \\\"__source\\\" and \\\"__self\\\" are set automatically by esbuild when using React's \\\"automatic\\\" JSX transform. \" +\n\t\t\t\t\t\t\t\t\t\"This duplicate prop may have come from a plugin.\"}})\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tproperties = append(properties, property)\n\t\t\t\t}\n\n\t\t\t\tisStaticChildren := len(children) > 1\n\n\t\t\t\t// Children are passed in as an explicit prop\n\t\t\t\tif len(children) > 0 {\n\t\t\t\t\tchildrenValue := children[0]\n\n\t\t\t\t\tif len(children) > 1 {\n\t\t\t\t\t\tchildrenValue.Data = &js_ast.EArray{Items: children}\n\t\t\t\t\t} else if _, ok := childrenValue.Data.(*js_ast.ESpread); ok {\n\t\t\t\t\t\t// TypeScript considers spread children to be static, but Babel considers\n\t\t\t\t\t\t// it to be an error (\"Spread children are not supported in React.\").\n\t\t\t\t\t\t// We'll follow TypeScript's behavior here because spread children may be\n\t\t\t\t\t\t// valid with non-React source runtimes.\n\t\t\t\t\t\tchildrenValue.Data = &js_ast.EArray{Items: []js_ast.Expr{childrenValue}}\n\t\t\t\t\t\tisStaticChildren = true\n\t\t\t\t\t}\n\n\t\t\t\t\tproperties = append(properties, js_ast.Property{\n\t\t\t\t\t\tKey: js_ast.Expr{\n\t\t\t\t\t\t\tData: &js_ast.EString{Value: helpers.StringToUTF16(\"children\")},\n\t\t\t\t\t\t\tLoc:  childrenValue.Loc,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tValueOrNil: childrenValue,\n\t\t\t\t\t\tKind:       js_ast.PropertyField,\n\t\t\t\t\t\tLoc:        childrenValue.Loc,\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\targs = append(args, p.lowerObjectSpread(propsLoc, &js_ast.EObject{\n\t\t\t\t\tProperties:   properties,\n\t\t\t\t\tIsSingleLine: e.IsTagSingleLine,\n\t\t\t\t}))\n\n\t\t\t\t// \"key\"\n\t\t\t\tif hasKey || p.options.jsx.Development {\n\t\t\t\t\targs = append(args, keyProperty)\n\t\t\t\t}\n\n\t\t\t\tif p.options.jsx.Development {\n\t\t\t\t\t// \"isStaticChildren\"\n\t\t\t\t\targs = append(args, js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EBoolean{Value: isStaticChildren}})\n\n\t\t\t\t\t// \"__source\"\n\t\t\t\t\targs = append(args, js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EObject{\n\t\t\t\t\t\tProperties: []js_ast.Property{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tKind:       js_ast.PropertyField,\n\t\t\t\t\t\t\t\tKey:        js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(\"fileName\")}},\n\t\t\t\t\t\t\t\tValueOrNil: js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(p.source.PrettyPaths.Select(p.options.codePathStyle))}},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tKind:       js_ast.PropertyField,\n\t\t\t\t\t\t\t\tKey:        js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(\"lineNumber\")}},\n\t\t\t\t\t\t\t\tValueOrNil: js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENumber{Value: float64(jsxSourceLine + 1)}}, // 1-based lines\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tKind:       js_ast.PropertyField,\n\t\t\t\t\t\t\t\tKey:        js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(\"columnNumber\")}},\n\t\t\t\t\t\t\t\tValueOrNil: js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENumber{Value: float64(jsxSourceColumn + 1)}}, // 1-based columns\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t}})\n\n\t\t\t\t\t// \"__self\"\n\t\t\t\t\t__self := js_ast.Expr{Loc: expr.Loc, Data: js_ast.EThisShared}\n\t\t\t\t\t{\n\t\t\t\t\t\tif p.fnOnlyDataVisit.shouldReplaceThisWithInnerClassNameRef {\n\t\t\t\t\t\t\t// Substitute \"this\" if we're inside a static class context\n\t\t\t\t\t\t\tp.recordUsage(*p.fnOnlyDataVisit.innerClassNameRef)\n\t\t\t\t\t\t\t__self.Data = &js_ast.EIdentifier{Ref: *p.fnOnlyDataVisit.innerClassNameRef}\n\t\t\t\t\t\t} else if !p.fnOnlyDataVisit.isThisNested && p.options.mode != config.ModePassThrough {\n\t\t\t\t\t\t\t// Replace top-level \"this\" with \"undefined\" if there's an output format\n\t\t\t\t\t\t\t__self.Data = js_ast.EUndefinedShared\n\t\t\t\t\t\t} else if p.fnOrArrowDataVisit.isDerivedClassCtor {\n\t\t\t\t\t\t\t// We can't use \"this\" here in case it comes before \"super()\"\n\t\t\t\t\t\t\t__self.Data = js_ast.EUndefinedShared\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif _, ok := __self.Data.(*js_ast.EUndefined); !ok {\n\t\t\t\t\t\t// Omit \"__self\" entirely if it's undefined\n\t\t\t\t\t\targs = append(args, __self)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tjsx := JSXImportJSX\n\t\t\t\tif isStaticChildren {\n\t\t\t\t\tjsx = JSXImportJSXS\n\t\t\t\t}\n\n\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ECall{\n\t\t\t\t\tTarget:        p.importJSXSymbol(expr.Loc, jsx),\n\t\t\t\t\tArgs:          args,\n\t\t\t\t\tCloseParenLoc: e.CloseLoc,\n\t\t\t\t\tIsMultiLine:   !e.IsTagSingleLine,\n\n\t\t\t\t\t// Enable tree shaking\n\t\t\t\t\tCanBeUnwrappedIfUnused: !p.options.ignoreDCEAnnotations && !p.options.jsx.SideEffects,\n\t\t\t\t}}, exprOut{}\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.ETemplate:\n\t\tif e.LegacyOctalLoc.Start > 0 {\n\t\t\tp.log.AddError(&p.tracker, p.source.RangeOfLegacyOctalEscape(e.LegacyOctalLoc),\n\t\t\t\t\"Legacy octal escape sequences cannot be used in template literals\")\n\t\t}\n\n\t\tvar tagThisFunc func() js_ast.Expr\n\t\tvar tagWrapFunc func(js_ast.Expr) js_ast.Expr\n\n\t\tif e.TagOrNil.Data != nil {\n\t\t\t// Capture the value for \"this\" if the tag is a lowered optional chain.\n\t\t\t// We'll need to manually apply this value later to preserve semantics.\n\t\t\ttagIsLoweredOptionalChain := false\n\t\t\tif p.options.unsupportedJSFeatures.Has(compat.OptionalChain) {\n\t\t\t\tswitch target := e.TagOrNil.Data.(type) {\n\t\t\t\tcase *js_ast.EDot:\n\t\t\t\t\ttagIsLoweredOptionalChain = target.OptionalChain != js_ast.OptionalChainNone\n\t\t\t\tcase *js_ast.EIndex:\n\t\t\t\t\ttagIsLoweredOptionalChain = target.OptionalChain != js_ast.OptionalChainNone\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.templateTag = e.TagOrNil.Data\n\t\t\ttag, tagOut := p.visitExprInOut(e.TagOrNil, exprIn{storeThisArgForParentOptionalChain: tagIsLoweredOptionalChain})\n\t\t\te.TagOrNil = tag\n\t\t\ttagThisFunc = tagOut.thisArgFunc\n\t\t\ttagWrapFunc = tagOut.thisArgWrapFunc\n\n\t\t\t// Copy the call side effect flag over if this is a known target\n\t\t\tif id, ok := tag.Data.(*js_ast.EIdentifier); ok && p.symbols[id.Ref.InnerIndex].Flags.Has(ast.CallCanBeUnwrappedIfUnused) {\n\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t}\n\n\t\t\t// The value of \"this\" must be manually preserved for private member\n\t\t\t// accesses inside template tag expressions such as \"this.#foo``\".\n\t\t\t// The private member \"this.#foo\" must see the value of \"this\".\n\t\t\tif target, loc, private := p.extractPrivateIndex(e.TagOrNil); private != nil {\n\t\t\t\t// \"foo.#bar`123`\" => \"__privateGet(_a = foo, #bar).bind(_a)`123`\"\n\t\t\t\ttargetFunc, targetWrapFunc := p.captureValueWithPossibleSideEffects(target.Loc, 2, target, valueCouldBeMutated)\n\t\t\t\te.TagOrNil = targetWrapFunc(js_ast.Expr{Loc: target.Loc, Data: &js_ast.ECall{\n\t\t\t\t\tTarget: js_ast.Expr{Loc: target.Loc, Data: &js_ast.EDot{\n\t\t\t\t\t\tTarget:  p.lowerPrivateGet(targetFunc(), loc, private),\n\t\t\t\t\t\tName:    \"bind\",\n\t\t\t\t\t\tNameLoc: target.Loc,\n\t\t\t\t\t}},\n\t\t\t\t\tArgs: []js_ast.Expr{targetFunc()},\n\t\t\t\t\tKind: js_ast.TargetWasOriginallyPropertyAccess,\n\t\t\t\t}})\n\t\t\t}\n\t\t}\n\n\t\tfor i, part := range e.Parts {\n\t\t\te.Parts[i].Value = p.visitExpr(part.Value)\n\t\t}\n\n\t\t// When mangling, inline string values into the template literal. Note that\n\t\t// it may no longer be a template literal after this point (it may turn into\n\t\t// a plain string literal instead).\n\t\tif p.shouldFoldTypeScriptConstantExpressions || p.options.minifySyntax {\n\t\t\texpr = js_ast.InlinePrimitivesIntoTemplate(expr.Loc, e)\n\t\t}\n\n\t\tshouldLowerTemplateLiteral := p.options.unsupportedJSFeatures.Has(compat.TemplateLiteral)\n\n\t\t// If the tag was originally an optional chaining property access, then\n\t\t// we'll need to lower this template literal as well to preserve the value\n\t\t// for \"this\".\n\t\tif tagThisFunc != nil {\n\t\t\tshouldLowerTemplateLiteral = true\n\t\t}\n\n\t\t// Lower tagged template literals that include \"</script\"\n\t\t// since we won't be able to escape it without lowering it\n\t\tif !shouldLowerTemplateLiteral && !p.options.unsupportedJSFeatures.Has(compat.InlineScript) && e.TagOrNil.Data != nil {\n\t\t\tif containsClosingScriptTag(e.HeadRaw) {\n\t\t\t\tshouldLowerTemplateLiteral = true\n\t\t\t} else {\n\t\t\t\tfor _, part := range e.Parts {\n\t\t\t\t\tif containsClosingScriptTag(part.TailRaw) {\n\t\t\t\t\t\tshouldLowerTemplateLiteral = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Convert template literals to older syntax if this is still a template literal\n\t\tif shouldLowerTemplateLiteral {\n\t\t\tif e, ok := expr.Data.(*js_ast.ETemplate); ok {\n\t\t\t\treturn p.lowerTemplateLiteral(expr.Loc, e, tagThisFunc, tagWrapFunc), exprOut{}\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.EBinary:\n\t\t// The handling of binary expressions is convoluted because we're using\n\t\t// iteration on the heap instead of recursion on the call stack to avoid\n\t\t// stack overflow for deeply-nested ASTs. See the comment before the\n\t\t// definition of \"binaryExprVisitor\" for details.\n\t\tv := binaryExprVisitor{\n\t\t\te:   e,\n\t\t\tloc: expr.Loc,\n\t\t\tin:  in,\n\t\t}\n\n\t\t// Everything uses a single stack to reduce allocation overhead. This stack\n\t\t// should almost always be very small, and almost all visits should reuse\n\t\t// existing memory without allocating anything.\n\t\tstackBottom := len(p.binaryExprStack)\n\n\t\t// Iterate down into the AST along the left node of the binary operation.\n\t\t// Continue iterating until we encounter something that's not a binary node.\n\t\tfor {\n\t\t\t// Check whether this node is a special case. If it is, a result will be\n\t\t\t// provided which ends our iteration. Otherwise, the visitor object will\n\t\t\t// be prepared for visiting.\n\t\t\tif result := v.checkAndPrepare(p); result.Data != nil {\n\t\t\t\texpr = result\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Grab the arguments to our nested \"visitExprInOut\" call for the left\n\t\t\t// node. We only care about deeply-nested left nodes because most binary\n\t\t\t// operators in JavaScript are left-associative and the problematic edge\n\t\t\t// cases we're trying to avoid crashing on have lots of left-associative\n\t\t\t// binary operators chained together without parentheses (e.g. \"1+2+...\").\n\t\t\tleft := v.e.Left\n\t\t\tleftIn := v.leftIn\n\t\t\tleftBinary, ok := left.Data.(*js_ast.EBinary)\n\n\t\t\t// Stop iterating if iteration doesn't apply to the left node. This checks\n\t\t\t// the assignment target because \"visitExprInOut\" has additional behavior\n\t\t\t// in that case that we don't want to miss (before the top-level \"switch\"\n\t\t\t// statement).\n\t\t\tif !ok || leftIn.assignTarget != js_ast.AssignTargetNone {\n\t\t\t\tv.e.Left, _ = p.visitExprInOut(left, leftIn)\n\t\t\t\texpr = v.visitRightAndFinish(p)\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Note that we only append to the stack (and therefore allocate memory\n\t\t\t// on the heap) when there are nested binary expressions. A single binary\n\t\t\t// expression doesn't add anything to the stack.\n\t\t\tp.binaryExprStack = append(p.binaryExprStack, v)\n\t\t\tv = binaryExprVisitor{\n\t\t\t\te:   leftBinary,\n\t\t\t\tloc: left.Loc,\n\t\t\t\tin:  leftIn,\n\t\t\t}\n\t\t}\n\n\t\t// Process all binary operations from the deepest-visited node back toward\n\t\t// our original top-level binary operation.\n\t\tfor {\n\t\t\tn := len(p.binaryExprStack) - 1\n\t\t\tif n < stackBottom {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tv := p.binaryExprStack[n]\n\t\t\tp.binaryExprStack = p.binaryExprStack[:n]\n\t\t\tv.e.Left = expr\n\t\t\texpr = v.visitRightAndFinish(p)\n\t\t}\n\n\t\treturn expr, exprOut{}\n\n\tcase *js_ast.EDot:\n\t\tisDeleteTarget := e == p.deleteTarget\n\t\tisCallTarget := e == p.callTarget\n\t\tisTemplateTag := e == p.templateTag\n\n\t\t// Check both user-specified defines and known globals\n\t\tif defines, ok := p.options.defines.DotDefines[e.Name]; ok {\n\t\t\tfor _, define := range defines {\n\t\t\t\tif p.isDotOrIndexDefineMatch(expr, define.KeyParts) {\n\t\t\t\t\t// Substitute user-specified defines\n\t\t\t\t\tif define.DefineExpr != nil {\n\t\t\t\t\t\tnew := p.instantiateDefineExpr(expr.Loc, *define.DefineExpr, identifierOpts{\n\t\t\t\t\t\t\tassignTarget:   in.assignTarget,\n\t\t\t\t\t\t\tisCallTarget:   isCallTarget,\n\t\t\t\t\t\t\tisDeleteTarget: isDeleteTarget,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tif in.assignTarget == js_ast.AssignTargetNone || defineValueCanBeUsedInAssignTarget(new.Data) {\n\t\t\t\t\t\t\t// Note: We don't need to \"ignoreRef\" on the underlying identifier\n\t\t\t\t\t\t\t// because we have only parsed it but not visited it yet\n\t\t\t\t\t\t\treturn new, exprOut{}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tr := logger.Range{Loc: expr.Loc, Len: js_lexer.RangeOfIdentifier(p.source, e.NameLoc).End() - expr.Loc.Start}\n\t\t\t\t\t\t\tp.logAssignToDefine(r, \"\", expr)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Copy the side effect flags over in case this expression is unused\n\t\t\t\t\tif define.Flags.Has(config.CanBeRemovedIfUnused) {\n\t\t\t\t\t\te.CanBeRemovedIfUnused = true\n\t\t\t\t\t}\n\t\t\t\t\tif define.Flags.Has(config.CallCanBeUnwrappedIfUnused) && !p.options.ignoreDCEAnnotations {\n\t\t\t\t\t\te.CallCanBeUnwrappedIfUnused = true\n\t\t\t\t\t}\n\t\t\t\t\tif define.Flags.Has(config.IsSymbolInstance) {\n\t\t\t\t\t\te.IsSymbolInstance = true\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Check injected dot names\n\t\tif names, ok := p.injectedDotNames[e.Name]; ok {\n\t\t\tfor _, name := range names {\n\t\t\t\tif p.isDotOrIndexDefineMatch(expr, name.parts) {\n\t\t\t\t\t// Note: We don't need to \"ignoreRef\" on the underlying identifier\n\t\t\t\t\t// because we have only parsed it but not visited it yet\n\t\t\t\t\treturn p.instantiateInjectDotName(expr.Loc, name, in.assignTarget), exprOut{}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Track \".then().catch()\" chains\n\t\tif isCallTarget && p.thenCatchChain.nextTarget == e {\n\t\t\tif e.Name == \"catch\" {\n\t\t\t\tp.thenCatchChain = thenCatchChain{\n\t\t\t\t\tnextTarget: e.Target.Data,\n\t\t\t\t\thasCatch:   true,\n\t\t\t\t\tcatchLoc:   e.NameLoc,\n\t\t\t\t}\n\t\t\t} else if e.Name == \"then\" {\n\t\t\t\tp.thenCatchChain = thenCatchChain{\n\t\t\t\t\tnextTarget: e.Target.Data,\n\t\t\t\t\thasCatch:   p.thenCatchChain.hasCatch || p.thenCatchChain.hasMultipleArgs,\n\t\t\t\t\tcatchLoc:   p.thenCatchChain.catchLoc,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tp.dotOrIndexTarget = e.Target.Data\n\t\ttarget, out := p.visitExprInOut(e.Target, exprIn{\n\t\t\thasChainParent: e.OptionalChain == js_ast.OptionalChainContinue,\n\t\t})\n\t\te.Target = target\n\n\t\t// Lower \"super.prop\" if necessary\n\t\tif e.OptionalChain == js_ast.OptionalChainNone && in.assignTarget == js_ast.AssignTargetNone &&\n\t\t\t!isCallTarget && p.shouldLowerSuperPropertyAccess(e.Target) {\n\t\t\t// \"super.foo\" => \"__superGet('foo')\"\n\t\t\tkey := js_ast.Expr{Loc: e.NameLoc, Data: &js_ast.EString{Value: helpers.StringToUTF16(e.Name)}}\n\t\t\tvalue := p.lowerSuperPropertyGet(expr.Loc, key)\n\t\t\tif isTemplateTag {\n\t\t\t\tvalue.Data = &js_ast.ECall{\n\t\t\t\t\tTarget: js_ast.Expr{Loc: value.Loc, Data: &js_ast.EDot{\n\t\t\t\t\t\tTarget:  value,\n\t\t\t\t\t\tName:    \"bind\",\n\t\t\t\t\t\tNameLoc: value.Loc,\n\t\t\t\t\t}},\n\t\t\t\t\tArgs: []js_ast.Expr{{Loc: value.Loc, Data: js_ast.EThisShared}},\n\t\t\t\t\tKind: js_ast.TargetWasOriginallyPropertyAccess,\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn value, exprOut{}\n\t\t}\n\n\t\t// Lower optional chaining if we're the top of the chain\n\t\tcontainsOptionalChain := e.OptionalChain == js_ast.OptionalChainStart ||\n\t\t\t(e.OptionalChain == js_ast.OptionalChainContinue && out.childContainsOptionalChain)\n\t\tif containsOptionalChain && !in.hasChainParent {\n\t\t\treturn p.lowerOptionalChain(expr, in, out)\n\t\t}\n\n\t\t// Also erase \"console.log.call(console, 123)\" and \"console.log.bind(console)\"\n\t\tif out.callMustBeReplacedWithUndefined {\n\t\t\tif e.Name == \"call\" || e.Name == \"apply\" {\n\t\t\t\tout.methodCallMustBeReplacedWithUndefined = true\n\t\t\t} else if p.options.unsupportedJSFeatures.Has(compat.Arrow) {\n\t\t\t\te.Target.Data = &js_ast.EFunction{}\n\t\t\t} else {\n\t\t\t\te.Target.Data = &js_ast.EArrow{}\n\t\t\t}\n\t\t}\n\n\t\t// Potentially rewrite this property access\n\t\tout = exprOut{\n\t\t\tchildContainsOptionalChain:      containsOptionalChain,\n\t\t\tcallMustBeReplacedWithUndefined: out.methodCallMustBeReplacedWithUndefined,\n\t\t\tthisArgFunc:                     out.thisArgFunc,\n\t\t\tthisArgWrapFunc:                 out.thisArgWrapFunc,\n\t\t}\n\t\tif !in.hasChainParent {\n\t\t\tout.thisArgFunc = nil\n\t\t\tout.thisArgWrapFunc = nil\n\t\t}\n\t\tif e.OptionalChain == js_ast.OptionalChainNone {\n\t\t\tif value, ok := p.maybeRewritePropertyAccess(expr.Loc, in.assignTarget,\n\t\t\t\tisDeleteTarget, e.Target, e.Name, e.NameLoc, isCallTarget, isTemplateTag, false); ok {\n\t\t\t\treturn value, out\n\t\t\t}\n\t\t}\n\t\treturn js_ast.Expr{Loc: expr.Loc, Data: e}, out\n\n\tcase *js_ast.EIndex:\n\t\tisCallTarget := e == p.callTarget\n\t\tisTemplateTag := e == p.templateTag\n\t\tisDeleteTarget := e == p.deleteTarget\n\n\t\t// Check both user-specified defines and known globals\n\t\tif str, ok := e.Index.Data.(*js_ast.EString); ok {\n\t\t\tif defines, ok := p.options.defines.DotDefines[helpers.UTF16ToString(str.Value)]; ok {\n\t\t\t\tfor _, define := range defines {\n\t\t\t\t\tif p.isDotOrIndexDefineMatch(expr, define.KeyParts) {\n\t\t\t\t\t\t// Substitute user-specified defines\n\t\t\t\t\t\tif define.DefineExpr != nil {\n\t\t\t\t\t\t\tnew := p.instantiateDefineExpr(expr.Loc, *define.DefineExpr, identifierOpts{\n\t\t\t\t\t\t\t\tassignTarget:   in.assignTarget,\n\t\t\t\t\t\t\t\tisCallTarget:   isCallTarget,\n\t\t\t\t\t\t\t\tisDeleteTarget: isDeleteTarget,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tif in.assignTarget == js_ast.AssignTargetNone || defineValueCanBeUsedInAssignTarget(new.Data) {\n\t\t\t\t\t\t\t\t// Note: We don't need to \"ignoreRef\" on the underlying identifier\n\t\t\t\t\t\t\t\t// because we have only parsed it but not visited it yet\n\t\t\t\t\t\t\t\treturn new, exprOut{}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tr := logger.Range{Loc: expr.Loc}\n\t\t\t\t\t\t\t\tafterIndex := logger.Loc{Start: p.source.RangeOfString(e.Index.Loc).End()}\n\t\t\t\t\t\t\t\tif closeBracket := p.source.RangeOfOperatorAfter(afterIndex, \"]\"); closeBracket.Len > 0 {\n\t\t\t\t\t\t\t\t\tr.Len = closeBracket.End() - r.Loc.Start\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tp.logAssignToDefine(r, \"\", expr)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Copy the side effect flags over in case this expression is unused\n\t\t\t\t\t\tif define.Flags.Has(config.CanBeRemovedIfUnused) {\n\t\t\t\t\t\t\te.CanBeRemovedIfUnused = true\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif define.Flags.Has(config.CallCanBeUnwrappedIfUnused) && !p.options.ignoreDCEAnnotations {\n\t\t\t\t\t\t\te.CallCanBeUnwrappedIfUnused = true\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif define.Flags.Has(config.IsSymbolInstance) {\n\t\t\t\t\t\t\te.IsSymbolInstance = true\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// \"a['b']\" => \"a.b\"\n\t\tif p.options.minifySyntax {\n\t\t\tif str, ok := e.Index.Data.(*js_ast.EString); ok && js_ast.IsIdentifierUTF16(str.Value) {\n\t\t\t\tdot := p.dotOrMangledPropParse(e.Target, js_lexer.MaybeSubstring{String: helpers.UTF16ToString(str.Value)}, e.Index.Loc, e.OptionalChain, wasOriginallyIndex)\n\t\t\t\tif isCallTarget {\n\t\t\t\t\tp.callTarget = dot\n\t\t\t\t}\n\t\t\t\tif isTemplateTag {\n\t\t\t\t\tp.templateTag = dot\n\t\t\t\t}\n\t\t\t\tif isDeleteTarget {\n\t\t\t\t\tp.deleteTarget = dot\n\t\t\t\t}\n\t\t\t\treturn p.visitExprInOut(js_ast.Expr{Loc: expr.Loc, Data: dot}, in)\n\t\t\t}\n\t\t}\n\n\t\tp.dotOrIndexTarget = e.Target.Data\n\t\ttarget, out := p.visitExprInOut(e.Target, exprIn{\n\t\t\thasChainParent: e.OptionalChain == js_ast.OptionalChainContinue,\n\t\t})\n\t\te.Target = target\n\n\t\t// Special-case private identifiers\n\t\tif private, ok := e.Index.Data.(*js_ast.EPrivateIdentifier); ok {\n\t\t\tname := p.loadNameFromRef(private.Ref)\n\t\t\tresult := p.findSymbol(e.Index.Loc, name)\n\t\t\tprivate.Ref = result.ref\n\n\t\t\t// Unlike regular identifiers, there are no unbound private identifiers\n\t\t\tkind := p.symbols[result.ref.InnerIndex].Kind\n\t\t\tif !kind.IsPrivate() {\n\t\t\t\tr := logger.Range{Loc: e.Index.Loc, Len: int32(len(name))}\n\t\t\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\"Private name %q must be declared in an enclosing class\", name))\n\t\t\t} else {\n\t\t\t\tvar r logger.Range\n\t\t\t\tvar text string\n\t\t\t\tif in.assignTarget != js_ast.AssignTargetNone && (kind == ast.SymbolPrivateMethod || kind == ast.SymbolPrivateStaticMethod) {\n\t\t\t\t\tr = logger.Range{Loc: e.Index.Loc, Len: int32(len(name))}\n\t\t\t\t\ttext = fmt.Sprintf(\"Writing to read-only method %q will throw\", name)\n\t\t\t\t} else if in.assignTarget != js_ast.AssignTargetNone && (kind == ast.SymbolPrivateGet || kind == ast.SymbolPrivateStaticGet) {\n\t\t\t\t\tr = logger.Range{Loc: e.Index.Loc, Len: int32(len(name))}\n\t\t\t\t\ttext = fmt.Sprintf(\"Writing to getter-only property %q will throw\", name)\n\t\t\t\t} else if in.assignTarget != js_ast.AssignTargetReplace && (kind == ast.SymbolPrivateSet || kind == ast.SymbolPrivateStaticSet) {\n\t\t\t\t\tr = logger.Range{Loc: e.Index.Loc, Len: int32(len(name))}\n\t\t\t\t\ttext = fmt.Sprintf(\"Reading from setter-only property %q will throw\", name)\n\t\t\t\t}\n\t\t\t\tif text != \"\" {\n\t\t\t\t\tkind := logger.Warning\n\t\t\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\t\t\tkind = logger.Debug\n\t\t\t\t\t}\n\t\t\t\t\tp.log.AddID(logger.MsgID_JS_PrivateNameWillThrow, kind, &p.tracker, r, text)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Lower private member access only if we're sure the target isn't needed\n\t\t\t// for the value of \"this\" for a call expression. All other cases will be\n\t\t\t// taken care of by the enclosing call expression.\n\t\t\tif p.privateSymbolNeedsToBeLowered(private) && e.OptionalChain == js_ast.OptionalChainNone &&\n\t\t\t\tin.assignTarget == js_ast.AssignTargetNone && !isCallTarget && !isTemplateTag {\n\t\t\t\t// \"foo.#bar\" => \"__privateGet(foo, #bar)\"\n\t\t\t\treturn p.lowerPrivateGet(e.Target, e.Index.Loc, private), exprOut{}\n\t\t\t}\n\t\t} else {\n\t\t\te.Index, _ = p.visitExprInOut(e.Index, exprIn{\n\t\t\t\tshouldMangleStringsAsProps: true,\n\t\t\t})\n\t\t}\n\n\t\t// Lower \"super[prop]\" if necessary\n\t\tif e.OptionalChain == js_ast.OptionalChainNone && in.assignTarget == js_ast.AssignTargetNone &&\n\t\t\t!isCallTarget && p.shouldLowerSuperPropertyAccess(e.Target) {\n\t\t\t// \"super[foo]\" => \"__superGet(foo)\"\n\t\t\tvalue := p.lowerSuperPropertyGet(expr.Loc, e.Index)\n\t\t\tif isTemplateTag {\n\t\t\t\tvalue.Data = &js_ast.ECall{\n\t\t\t\t\tTarget: js_ast.Expr{Loc: value.Loc, Data: &js_ast.EDot{\n\t\t\t\t\t\tTarget:  value,\n\t\t\t\t\t\tName:    \"bind\",\n\t\t\t\t\t\tNameLoc: value.Loc,\n\t\t\t\t\t}},\n\t\t\t\t\tArgs: []js_ast.Expr{{Loc: value.Loc, Data: js_ast.EThisShared}},\n\t\t\t\t\tKind: js_ast.TargetWasOriginallyPropertyAccess,\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn value, exprOut{}\n\t\t}\n\n\t\t// Lower optional chaining if we're the top of the chain\n\t\tcontainsOptionalChain := e.OptionalChain == js_ast.OptionalChainStart ||\n\t\t\t(e.OptionalChain == js_ast.OptionalChainContinue && out.childContainsOptionalChain)\n\t\tif containsOptionalChain && !in.hasChainParent {\n\t\t\treturn p.lowerOptionalChain(expr, in, out)\n\t\t}\n\n\t\t// Potentially rewrite this property access\n\t\tout = exprOut{\n\t\t\tchildContainsOptionalChain:      containsOptionalChain,\n\t\t\tcallMustBeReplacedWithUndefined: out.methodCallMustBeReplacedWithUndefined,\n\t\t\tthisArgFunc:                     out.thisArgFunc,\n\t\t\tthisArgWrapFunc:                 out.thisArgWrapFunc,\n\t\t}\n\t\tif !in.hasChainParent {\n\t\t\tout.thisArgFunc = nil\n\t\t\tout.thisArgWrapFunc = nil\n\t\t}\n\t\tif str, ok := e.Index.Data.(*js_ast.EString); ok && e.OptionalChain == js_ast.OptionalChainNone {\n\t\t\tpreferQuotedKey := !p.options.minifySyntax\n\t\t\tif value, ok := p.maybeRewritePropertyAccess(expr.Loc, in.assignTarget, isDeleteTarget,\n\t\t\t\te.Target, helpers.UTF16ToString(str.Value), e.Index.Loc, isCallTarget, isTemplateTag, preferQuotedKey); ok {\n\t\t\t\treturn value, out\n\t\t\t}\n\t\t}\n\n\t\t// Create an error for assigning to an import namespace when bundling. Even\n\t\t// though this is a run-time error, we make it a compile-time error when\n\t\t// bundling because scope hoisting means these will no longer be run-time\n\t\t// errors.\n\t\tif p.options.mode == config.ModeBundle && (in.assignTarget != js_ast.AssignTargetNone || isDeleteTarget) {\n\t\t\tif id, ok := e.Target.Data.(*js_ast.EIdentifier); ok && p.symbols[id.Ref.InnerIndex].Kind == ast.SymbolImport {\n\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, e.Target.Loc)\n\t\t\t\tp.log.AddErrorWithNotes(&p.tracker, r,\n\t\t\t\t\tfmt.Sprintf(\"Cannot assign to property on import %q\", p.symbols[id.Ref.InnerIndex].OriginalName),\n\t\t\t\t\t[]logger.MsgData{{Text: \"Imports are immutable in JavaScript. \" +\n\t\t\t\t\t\t\"To modify the value of this import, you must export a setter function in the \" +\n\t\t\t\t\t\t\"imported file and then import and call that function here instead.\"}})\n\n\t\t\t}\n\t\t}\n\n\t\tif p.options.minifySyntax {\n\t\t\tswitch index := e.Index.Data.(type) {\n\t\t\tcase *js_ast.EString:\n\t\t\t\t// \"a['x' + 'y']\" => \"a.xy\" (this is done late to allow for constant folding)\n\t\t\t\tif js_ast.IsIdentifierUTF16(index.Value) {\n\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EDot{\n\t\t\t\t\t\tTarget:                     e.Target,\n\t\t\t\t\t\tName:                       helpers.UTF16ToString(index.Value),\n\t\t\t\t\t\tNameLoc:                    e.Index.Loc,\n\t\t\t\t\t\tOptionalChain:              e.OptionalChain,\n\t\t\t\t\t\tCanBeRemovedIfUnused:       e.CanBeRemovedIfUnused,\n\t\t\t\t\t\tCallCanBeUnwrappedIfUnused: e.CallCanBeUnwrappedIfUnused,\n\t\t\t\t\t}}, out\n\t\t\t\t}\n\n\t\t\t\t// \"a['123']\" => \"a[123]\" (this is done late to allow \"'123'\" to be mangled)\n\t\t\t\tif numberValue, ok := js_ast.StringToEquivalentNumberValue(index.Value); ok {\n\t\t\t\t\te.Index.Data = &js_ast.ENumber{Value: numberValue}\n\t\t\t\t}\n\n\t\t\tcase *js_ast.ENumber:\n\t\t\t\t// \"'abc'[1]\" => \"'b'\"\n\t\t\t\tif target, ok := e.Target.Data.(*js_ast.EString); ok {\n\t\t\t\t\tif intValue := math.Floor(index.Value); index.Value == intValue && intValue >= 0 && intValue < float64(len(target.Value)) {\n\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: []uint16{target.Value[int(intValue)]}}}, out\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn js_ast.Expr{Loc: expr.Loc, Data: e}, out\n\n\tcase *js_ast.EUnary:\n\t\tswitch e.Op {\n\t\tcase js_ast.UnOpTypeof:\n\t\t\te.Value, _ = p.visitExprInOut(e.Value, exprIn{assignTarget: e.Op.UnaryAssignTarget()})\n\n\t\t\t// Compile-time \"typeof\" evaluation\n\t\t\tif typeof, ok := js_ast.TypeofWithoutSideEffects(e.Value.Data); ok {\n\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(typeof)}}, exprOut{}\n\t\t\t}\n\n\t\tcase js_ast.UnOpDelete:\n\t\t\t// Warn about code that tries to do \"delete super.foo\"\n\t\t\tvar superPropLoc logger.Loc\n\t\t\tswitch e2 := e.Value.Data.(type) {\n\t\t\tcase *js_ast.EDot:\n\t\t\t\tif _, ok := e2.Target.Data.(*js_ast.ESuper); ok {\n\t\t\t\t\tsuperPropLoc = e2.Target.Loc\n\t\t\t\t}\n\t\t\tcase *js_ast.EIndex:\n\t\t\t\tif _, ok := e2.Target.Data.(*js_ast.ESuper); ok {\n\t\t\t\t\tsuperPropLoc = e2.Target.Loc\n\t\t\t\t}\n\t\t\tcase *js_ast.EIdentifier:\n\t\t\t\tp.markStrictModeFeature(deleteBareName, js_lexer.RangeOfIdentifier(p.source, e.Value.Loc), \"\")\n\t\t\t}\n\t\t\tif superPropLoc.Start != 0 {\n\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, superPropLoc)\n\t\t\t\ttext := \"Attempting to delete a property of \\\"super\\\" will throw a ReferenceError\"\n\t\t\t\tkind := logger.Warning\n\t\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\t\tkind = logger.Debug\n\t\t\t\t}\n\t\t\t\tp.log.AddID(logger.MsgID_JS_DeleteSuperProperty, kind, &p.tracker, r, text)\n\t\t\t}\n\n\t\t\tp.deleteTarget = e.Value.Data\n\t\t\tvalue, out := p.visitExprInOut(e.Value, exprIn{hasChainParent: true})\n\t\t\te.Value = value\n\n\t\t\t// Lower optional chaining if present since we're guaranteed to be the\n\t\t\t// end of the chain\n\t\t\tif out.childContainsOptionalChain {\n\t\t\t\treturn p.lowerOptionalChain(expr, in, out)\n\t\t\t}\n\n\t\tdefault:\n\t\t\te.Value, _ = p.visitExprInOut(e.Value, exprIn{assignTarget: e.Op.UnaryAssignTarget()})\n\n\t\t\t// Post-process the unary expression\n\t\t\tswitch e.Op {\n\t\t\tcase js_ast.UnOpNot:\n\t\t\t\tif p.options.minifySyntax {\n\t\t\t\t\te.Value = p.astHelpers.SimplifyBooleanExpr(e.Value)\n\t\t\t\t}\n\n\t\t\t\tif boolean, sideEffects, ok := js_ast.ToBooleanWithSideEffects(e.Value.Data); ok && sideEffects == js_ast.NoSideEffects {\n\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EBoolean{Value: !boolean}}, exprOut{}\n\t\t\t\t}\n\n\t\t\t\tif p.options.minifySyntax {\n\t\t\t\t\tif result, ok := js_ast.MaybeSimplifyNot(e.Value); ok {\n\t\t\t\t\t\treturn result, exprOut{}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tcase js_ast.UnOpVoid:\n\t\t\t\tvar shouldRemove bool\n\t\t\t\tif p.options.minifySyntax {\n\t\t\t\t\tshouldRemove = p.astHelpers.ExprCanBeRemovedIfUnused(e.Value)\n\t\t\t\t} else {\n\t\t\t\t\t// This special case was added for a very obscure reason. There's a\n\t\t\t\t\t// custom dialect of JavaScript called Svelte that uses JavaScript\n\t\t\t\t\t// syntax with different semantics. Specifically variable accesses\n\t\t\t\t\t// have side effects (!). And someone wants to use \"void x\" instead\n\t\t\t\t\t// of just \"x\" to trigger the side effect for some reason.\n\t\t\t\t\t//\n\t\t\t\t\t// Arguably this should not be supported, because you shouldn't be\n\t\t\t\t\t// running esbuild on weird kinda-JavaScript-but-not languages and\n\t\t\t\t\t// expecting it to work correctly. But this one special case seems\n\t\t\t\t\t// harmless enough. This is definitely not fully supported though.\n\t\t\t\t\t//\n\t\t\t\t\t// More info: https://github.com/evanw/esbuild/issues/4041\n\t\t\t\t\tshouldRemove = isUnsightlyPrimitive(e.Value.Data)\n\t\t\t\t}\n\t\t\t\tif shouldRemove {\n\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: js_ast.EUndefinedShared}, exprOut{}\n\t\t\t\t}\n\n\t\t\tcase js_ast.UnOpPos:\n\t\t\t\tif number, ok := js_ast.ToNumberWithoutSideEffects(e.Value.Data); ok {\n\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENumber{Value: number}}, exprOut{}\n\t\t\t\t}\n\n\t\t\tcase js_ast.UnOpNeg:\n\t\t\t\tif number, ok := js_ast.ToNumberWithoutSideEffects(e.Value.Data); ok {\n\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENumber{Value: -number}}, exprOut{}\n\t\t\t\t}\n\n\t\t\tcase js_ast.UnOpCpl:\n\t\t\t\tif p.shouldFoldTypeScriptConstantExpressions || p.options.minifySyntax {\n\t\t\t\t\t// Minification folds complement operations since they are unlikely to result in larger output\n\t\t\t\t\tif number, ok := js_ast.ToNumberWithoutSideEffects(e.Value.Data); ok {\n\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENumber{Value: float64(^js_ast.ToInt32(number))}}, exprOut{}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t////////////////////////////////////////////////////////////////////////////////\n\t\t\t\t// All assignment operators below here\n\n\t\t\tcase js_ast.UnOpPreDec, js_ast.UnOpPreInc, js_ast.UnOpPostDec, js_ast.UnOpPostInc:\n\t\t\t\tif target, loc, private := p.extractPrivateIndex(e.Value); private != nil {\n\t\t\t\t\treturn p.lowerPrivateSetUnOp(target, loc, private, e.Op), exprOut{}\n\t\t\t\t}\n\t\t\t\tif property := p.extractSuperProperty(e.Value); property.Data != nil {\n\t\t\t\t\te.Value = p.callSuperPropertyWrapper(expr.Loc, property)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// \"-(a, b)\" => \"a, -b\"\n\t\tif p.options.minifySyntax && e.Op != js_ast.UnOpDelete && e.Op != js_ast.UnOpTypeof {\n\t\t\tif comma, ok := e.Value.Data.(*js_ast.EBinary); ok && comma.Op == js_ast.BinOpComma {\n\t\t\t\treturn js_ast.JoinWithComma(comma.Left, js_ast.Expr{\n\t\t\t\t\tLoc: comma.Right.Loc,\n\t\t\t\t\tData: &js_ast.EUnary{\n\t\t\t\t\t\tOp:    e.Op,\n\t\t\t\t\t\tValue: comma.Right,\n\t\t\t\t\t},\n\t\t\t\t}), exprOut{}\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.EIf:\n\t\te.Test = p.visitExpr(e.Test)\n\n\t\tif p.options.minifySyntax {\n\t\t\te.Test = p.astHelpers.SimplifyBooleanExpr(e.Test)\n\t\t}\n\n\t\t// Propagate these flags into the branches\n\t\tchildIn := exprIn{\n\t\t\tshouldMangleStringsAsProps: in.shouldMangleStringsAsProps,\n\t\t}\n\n\t\t// Fold constants\n\t\tif boolean, sideEffects, ok := js_ast.ToBooleanWithSideEffects(e.Test.Data); !ok {\n\t\t\te.Yes, _ = p.visitExprInOut(e.Yes, childIn)\n\t\t\te.No, _ = p.visitExprInOut(e.No, childIn)\n\t\t} else {\n\t\t\t// Mark the control flow as dead if the branch is never taken\n\t\t\tif boolean {\n\t\t\t\t// \"true ? live : dead\"\n\t\t\t\te.Yes, _ = p.visitExprInOut(e.Yes, childIn)\n\t\t\t\told := p.isControlFlowDead\n\t\t\t\tp.isControlFlowDead = true\n\t\t\t\te.No, _ = p.visitExprInOut(e.No, childIn)\n\t\t\t\tp.isControlFlowDead = old\n\n\t\t\t\tif p.options.minifySyntax {\n\t\t\t\t\t// \"(a, true) ? b : c\" => \"a, b\"\n\t\t\t\t\tif sideEffects == js_ast.CouldHaveSideEffects {\n\t\t\t\t\t\treturn js_ast.JoinWithComma(p.astHelpers.SimplifyUnusedExpr(e.Test, p.options.unsupportedJSFeatures), e.Yes), exprOut{}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn e.Yes, exprOut{}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// \"false ? dead : live\"\n\t\t\t\told := p.isControlFlowDead\n\t\t\t\tp.isControlFlowDead = true\n\t\t\t\te.Yes, _ = p.visitExprInOut(e.Yes, childIn)\n\t\t\t\tp.isControlFlowDead = old\n\t\t\t\te.No, _ = p.visitExprInOut(e.No, childIn)\n\n\t\t\t\tif p.options.minifySyntax {\n\t\t\t\t\t// \"(a, false) ? b : c\" => \"a, c\"\n\t\t\t\t\tif sideEffects == js_ast.CouldHaveSideEffects {\n\t\t\t\t\t\treturn js_ast.JoinWithComma(p.astHelpers.SimplifyUnusedExpr(e.Test, p.options.unsupportedJSFeatures), e.No), exprOut{}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn e.No, exprOut{}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif p.options.minifySyntax {\n\t\t\treturn p.astHelpers.MangleIfExpr(expr.Loc, e, p.options.unsupportedJSFeatures), exprOut{}\n\t\t}\n\n\tcase *js_ast.EAwait:\n\t\t// Silently remove unsupported top-level \"await\" in dead code branches\n\t\tif p.fnOrArrowDataVisit.isOutsideFnOrArrow {\n\t\t\tif p.isControlFlowDead && (p.options.unsupportedJSFeatures.Has(compat.TopLevelAwait) || !p.options.outputFormat.KeepESMImportExportSyntax()) {\n\t\t\t\treturn p.visitExprInOut(e.Value, in)\n\t\t\t} else {\n\t\t\t\tp.liveTopLevelAwaitKeyword = logger.Range{Loc: expr.Loc, Len: 5}\n\t\t\t\tp.markSyntaxFeature(compat.TopLevelAwait, logger.Range{Loc: expr.Loc, Len: 5})\n\t\t\t}\n\t\t}\n\n\t\tp.awaitTarget = e.Value.Data\n\t\te.Value = p.visitExpr(e.Value)\n\n\t\t// \"await\" expressions turn into \"yield\" expressions when lowering\n\t\treturn p.maybeLowerAwait(expr.Loc, e), exprOut{}\n\n\tcase *js_ast.EYield:\n\t\tif e.ValueOrNil.Data != nil {\n\t\t\te.ValueOrNil = p.visitExpr(e.ValueOrNil)\n\t\t}\n\n\t\t// \"yield* x\" turns into \"yield* __yieldStar(x)\" when lowering async generator functions\n\t\tif e.IsStar && p.options.unsupportedJSFeatures.Has(compat.AsyncGenerator) && p.fnOrArrowDataVisit.isGenerator {\n\t\t\te.ValueOrNil = p.callRuntime(expr.Loc, \"__yieldStar\", []js_ast.Expr{e.ValueOrNil})\n\t\t}\n\n\tcase *js_ast.EArray:\n\t\tif in.assignTarget != js_ast.AssignTargetNone {\n\t\t\tif e.CommaAfterSpread.Start != 0 {\n\t\t\t\tp.log.AddError(&p.tracker, logger.Range{Loc: e.CommaAfterSpread, Len: 1}, \"Unexpected \\\",\\\" after rest pattern\")\n\t\t\t}\n\t\t\tp.markSyntaxFeature(compat.Destructuring, logger.Range{Loc: expr.Loc, Len: 1})\n\t\t}\n\t\thasSpread := false\n\t\tfor i, item := range e.Items {\n\t\t\tswitch e2 := item.Data.(type) {\n\t\t\tcase *js_ast.EMissing:\n\t\t\tcase *js_ast.ESpread:\n\t\t\t\te2.Value, _ = p.visitExprInOut(e2.Value, exprIn{assignTarget: in.assignTarget})\n\t\t\t\thasSpread = true\n\t\t\tcase *js_ast.EBinary:\n\t\t\t\tif in.assignTarget != js_ast.AssignTargetNone && e2.Op == js_ast.BinOpAssign {\n\t\t\t\t\te2.Left, _ = p.visitExprInOut(e2.Left, exprIn{assignTarget: js_ast.AssignTargetReplace})\n\n\t\t\t\t\t// Propagate the name to keep from the binding into the initializer\n\t\t\t\t\tif id, ok := e2.Left.Data.(*js_ast.EIdentifier); ok {\n\t\t\t\t\t\tp.nameToKeep = p.symbols[id.Ref.InnerIndex].OriginalName\n\t\t\t\t\t\tp.nameToKeepIsFor = e2.Right.Data\n\t\t\t\t\t}\n\n\t\t\t\t\te2.Right = p.visitExpr(e2.Right)\n\t\t\t\t} else {\n\t\t\t\t\titem, _ = p.visitExprInOut(item, exprIn{assignTarget: in.assignTarget})\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\titem, _ = p.visitExprInOut(item, exprIn{assignTarget: in.assignTarget})\n\t\t\t}\n\t\t\te.Items[i] = item\n\t\t}\n\n\t\t// \"[1, ...[2, 3], 4]\" => \"[1, 2, 3, 4]\"\n\t\tif p.options.minifySyntax && hasSpread && in.assignTarget == js_ast.AssignTargetNone {\n\t\t\te.Items = js_ast.InlineSpreadsOfArrayLiterals(e.Items)\n\t\t}\n\n\tcase *js_ast.EObject:\n\t\tif in.assignTarget != js_ast.AssignTargetNone {\n\t\t\tif e.CommaAfterSpread.Start != 0 {\n\t\t\t\tp.log.AddError(&p.tracker, logger.Range{Loc: e.CommaAfterSpread, Len: 1}, \"Unexpected \\\",\\\" after rest pattern\")\n\t\t\t}\n\t\t\tp.markSyntaxFeature(compat.Destructuring, logger.Range{Loc: expr.Loc, Len: 1})\n\t\t}\n\n\t\thasSpread := false\n\t\tprotoRange := logger.Range{}\n\t\tinnerClassNameRef := ast.InvalidRef\n\n\t\tfor i := range e.Properties {\n\t\t\tproperty := &e.Properties[i]\n\n\t\t\tif property.Kind != js_ast.PropertySpread {\n\t\t\t\tkey := property.Key\n\t\t\t\tif mangled, ok := key.Data.(*js_ast.ENameOfSymbol); ok {\n\t\t\t\t\tmangled.Ref = p.symbolForMangledProp(p.loadNameFromRef(mangled.Ref))\n\t\t\t\t} else {\n\t\t\t\t\tkey, _ = p.visitExprInOut(property.Key, exprIn{\n\t\t\t\t\t\tshouldMangleStringsAsProps: true,\n\t\t\t\t\t})\n\t\t\t\t\tproperty.Key = key\n\t\t\t\t}\n\n\t\t\t\t// Forbid duplicate \"__proto__\" properties according to the specification\n\t\t\t\tif !property.Flags.Has(js_ast.PropertyIsComputed) && !property.Flags.Has(js_ast.PropertyWasShorthand) &&\n\t\t\t\t\tproperty.Kind == js_ast.PropertyField && in.assignTarget == js_ast.AssignTargetNone {\n\t\t\t\t\tif str, ok := key.Data.(*js_ast.EString); ok && helpers.UTF16EqualsString(str.Value, \"__proto__\") {\n\t\t\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, key.Loc)\n\t\t\t\t\t\tif protoRange.Len > 0 {\n\t\t\t\t\t\t\tp.log.AddErrorWithNotes(&p.tracker, r,\n\t\t\t\t\t\t\t\t\"Cannot specify the \\\"__proto__\\\" property more than once per object\",\n\t\t\t\t\t\t\t\t[]logger.MsgData{p.tracker.MsgData(protoRange, \"The earlier \\\"__proto__\\\" property is here:\")})\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tprotoRange = r\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// \"{['x']: y}\" => \"{x: y}\"\n\t\t\t\tif p.options.minifySyntax && property.Flags.Has(js_ast.PropertyIsComputed) {\n\t\t\t\t\tif inlined, ok := key.Data.(*js_ast.EInlinedEnum); ok {\n\t\t\t\t\t\tswitch inlined.Value.Data.(type) {\n\t\t\t\t\t\tcase *js_ast.EString, *js_ast.ENumber:\n\t\t\t\t\t\t\tkey.Data = inlined.Value.Data\n\t\t\t\t\t\t\tproperty.Key.Data = key.Data\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tswitch k := key.Data.(type) {\n\t\t\t\t\tcase *js_ast.ENumber, *js_ast.ENameOfSymbol:\n\t\t\t\t\t\tproperty.Flags &= ^js_ast.PropertyIsComputed\n\t\t\t\t\tcase *js_ast.EString:\n\t\t\t\t\t\tif !helpers.UTF16EqualsString(k.Value, \"__proto__\") {\n\t\t\t\t\t\t\tproperty.Flags &= ^js_ast.PropertyIsComputed\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\thasSpread = true\n\t\t\t}\n\n\t\t\t// Extract the initializer for expressions like \"({ a: b = c } = d)\"\n\t\t\tif in.assignTarget != js_ast.AssignTargetNone && property.InitializerOrNil.Data == nil && property.ValueOrNil.Data != nil {\n\t\t\t\tif binary, ok := property.ValueOrNil.Data.(*js_ast.EBinary); ok && binary.Op == js_ast.BinOpAssign {\n\t\t\t\t\tproperty.InitializerOrNil = binary.Right\n\t\t\t\t\tproperty.ValueOrNil = binary.Left\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif property.ValueOrNil.Data != nil {\n\t\t\t\toldIsInStaticClassContext := p.fnOnlyDataVisit.isInStaticClassContext\n\t\t\t\toldInnerClassNameRef := p.fnOnlyDataVisit.innerClassNameRef\n\n\t\t\t\t// If this is an async method and async methods are unsupported,\n\t\t\t\t// generate a temporary variable in case this async method contains a\n\t\t\t\t// \"super\" property reference. If that happens, the \"super\" expression\n\t\t\t\t// must be lowered which will need a reference to this object literal.\n\t\t\t\tif property.Kind == js_ast.PropertyMethod && p.options.unsupportedJSFeatures.Has(compat.AsyncAwait) {\n\t\t\t\t\tif fn, ok := property.ValueOrNil.Data.(*js_ast.EFunction); ok && fn.Fn.IsAsync {\n\t\t\t\t\t\tif innerClassNameRef == ast.InvalidRef {\n\t\t\t\t\t\t\tinnerClassNameRef = p.generateTempRef(tempRefNeedsDeclareMayBeCapturedInsideLoop, \"\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.fnOnlyDataVisit.isInStaticClassContext = true\n\t\t\t\t\t\tp.fnOnlyDataVisit.innerClassNameRef = &innerClassNameRef\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Propagate the name to keep from the property into the value\n\t\t\t\tif str, ok := property.Key.Data.(*js_ast.EString); ok {\n\t\t\t\t\tp.nameToKeep = helpers.UTF16ToString(str.Value)\n\t\t\t\t\tp.nameToKeepIsFor = property.ValueOrNil.Data\n\t\t\t\t}\n\n\t\t\t\tproperty.ValueOrNil, _ = p.visitExprInOut(property.ValueOrNil, exprIn{\n\t\t\t\t\tisMethod:     property.Kind.IsMethodDefinition(),\n\t\t\t\t\tassignTarget: in.assignTarget,\n\t\t\t\t})\n\n\t\t\t\tp.fnOnlyDataVisit.innerClassNameRef = oldInnerClassNameRef\n\t\t\t\tp.fnOnlyDataVisit.isInStaticClassContext = oldIsInStaticClassContext\n\t\t\t}\n\n\t\t\tif property.InitializerOrNil.Data != nil {\n\t\t\t\t// Propagate the name to keep from the binding into the initializer\n\t\t\t\tif id, ok := property.ValueOrNil.Data.(*js_ast.EIdentifier); ok {\n\t\t\t\t\tp.nameToKeep = p.symbols[id.Ref.InnerIndex].OriginalName\n\t\t\t\t\tp.nameToKeepIsFor = property.InitializerOrNil.Data\n\t\t\t\t}\n\n\t\t\t\tproperty.InitializerOrNil = p.visitExpr(property.InitializerOrNil)\n\t\t\t}\n\n\t\t\t// \"{ '123': 4 }\" => \"{ 123: 4 }\" (this is done late to allow \"'123'\" to be mangled)\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tif str, ok := property.Key.Data.(*js_ast.EString); ok {\n\t\t\t\t\tif numberValue, ok := js_ast.StringToEquivalentNumberValue(str.Value); ok && numberValue >= 0 {\n\t\t\t\t\t\tproperty.Key.Data = &js_ast.ENumber{Value: numberValue}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Check for and warn about duplicate keys in object literals\n\t\tif !p.suppressWarningsAboutWeirdCode {\n\t\t\tp.warnAboutDuplicateProperties(e.Properties, duplicatePropertiesInObject)\n\t\t}\n\n\t\tif in.assignTarget == js_ast.AssignTargetNone {\n\t\t\t// \"{a, ...{b, c}, d}\" => \"{a, b, c, d}\"\n\t\t\tif p.options.minifySyntax && hasSpread {\n\t\t\t\te.Properties = js_ast.MangleObjectSpread(e.Properties)\n\t\t\t}\n\n\t\t\t// Object expressions represent both object literals and binding patterns.\n\t\t\t// Only lower object spread if we're an object literal, not a binding pattern.\n\t\t\tvalue := p.lowerObjectSpread(expr.Loc, e)\n\n\t\t\t// If we generated and used the temporary variable for a lowered \"super\"\n\t\t\t// property reference inside a lowered \"async\" method, then initialize\n\t\t\t// the temporary with this object literal.\n\t\t\tif innerClassNameRef != ast.InvalidRef && p.symbols[innerClassNameRef.InnerIndex].UseCountEstimate > 0 {\n\t\t\t\tp.recordUsage(innerClassNameRef)\n\t\t\t\tvalue = js_ast.Assign(js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EIdentifier{Ref: innerClassNameRef}}, value)\n\t\t\t}\n\n\t\t\treturn value, exprOut{}\n\t\t}\n\n\tcase *js_ast.EImportCall:\n\t\tisAwaitTarget := e == p.awaitTarget\n\t\tisThenCatchTarget := e == p.thenCatchChain.nextTarget && p.thenCatchChain.hasCatch\n\t\te.Expr = p.visitExpr(e.Expr)\n\n\t\tvar assertOrWith *ast.ImportAssertOrWith\n\t\tvar flags ast.ImportRecordFlags\n\t\tif e.OptionsOrNil.Data != nil {\n\t\t\te.OptionsOrNil = p.visitExpr(e.OptionsOrNil)\n\n\t\t\t// If there's an additional argument, this can't be split because the\n\t\t\t// additional argument requires evaluation and our AST nodes can't be\n\t\t\t// reused in different places in the AST (e.g. function scopes must be\n\t\t\t// unique). Also the additional argument may have side effects and we\n\t\t\t// don't currently account for that.\n\t\t\twhy := \"the second argument was not an object literal\"\n\t\t\twhyLoc := e.OptionsOrNil.Loc\n\n\t\t\t// However, make a special case for an additional argument that contains\n\t\t\t// only an \"assert\" or a \"with\" clause. In that case we can split this\n\t\t\t// AST node.\n\t\t\tif object, ok := e.OptionsOrNil.Data.(*js_ast.EObject); ok {\n\t\t\t\tif len(object.Properties) == 1 {\n\t\t\t\t\tif prop := object.Properties[0]; prop.Kind == js_ast.PropertyField && !prop.Flags.Has(js_ast.PropertyIsComputed) {\n\t\t\t\t\t\tif str, ok := prop.Key.Data.(*js_ast.EString); ok && (helpers.UTF16EqualsString(str.Value, \"assert\") || helpers.UTF16EqualsString(str.Value, \"with\")) {\n\t\t\t\t\t\t\tkeyword := ast.WithKeyword\n\t\t\t\t\t\t\tif helpers.UTF16EqualsString(str.Value, \"assert\") {\n\t\t\t\t\t\t\t\tkeyword = ast.AssertKeyword\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif value, ok := prop.ValueOrNil.Data.(*js_ast.EObject); ok {\n\t\t\t\t\t\t\t\tentries := []ast.AssertOrWithEntry{}\n\t\t\t\t\t\t\t\tfor _, p := range value.Properties {\n\t\t\t\t\t\t\t\t\tif p.Kind == js_ast.PropertyField && !p.Flags.Has(js_ast.PropertyIsComputed) {\n\t\t\t\t\t\t\t\t\t\tif key, ok := p.Key.Data.(*js_ast.EString); ok {\n\t\t\t\t\t\t\t\t\t\t\tif value, ok := p.ValueOrNil.Data.(*js_ast.EString); ok {\n\t\t\t\t\t\t\t\t\t\t\t\tentries = append(entries, ast.AssertOrWithEntry{\n\t\t\t\t\t\t\t\t\t\t\t\t\tKey:             key.Value,\n\t\t\t\t\t\t\t\t\t\t\t\t\tKeyLoc:          p.Key.Loc,\n\t\t\t\t\t\t\t\t\t\t\t\t\tValue:           value.Value,\n\t\t\t\t\t\t\t\t\t\t\t\t\tValueLoc:        p.ValueOrNil.Loc,\n\t\t\t\t\t\t\t\t\t\t\t\t\tPreferQuotedKey: p.Flags.Has(js_ast.PropertyPreferQuotedKey),\n\t\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t\t\tif keyword == ast.AssertKeyword && helpers.UTF16EqualsString(key.Value, \"type\") && helpers.UTF16EqualsString(value.Value, \"json\") {\n\t\t\t\t\t\t\t\t\t\t\t\t\tflags |= ast.AssertTypeJSON\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\twhy = fmt.Sprintf(\"the value for the property %q was not a string literal\",\n\t\t\t\t\t\t\t\t\t\t\t\t\thelpers.UTF16ToString(key.Value))\n\t\t\t\t\t\t\t\t\t\t\t\twhyLoc = p.ValueOrNil.Loc\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\twhy = \"this property was not a string literal\"\n\t\t\t\t\t\t\t\t\t\t\twhyLoc = p.Key.Loc\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\twhy = \"this property was invalid\"\n\t\t\t\t\t\t\t\t\t\twhyLoc = p.Key.Loc\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tentries = nil\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif entries != nil {\n\t\t\t\t\t\t\t\t\tif keyword == ast.AssertKeyword {\n\t\t\t\t\t\t\t\t\t\tp.maybeWarnAboutAssertKeyword(prop.Key.Loc)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tassertOrWith = &ast.ImportAssertOrWith{\n\t\t\t\t\t\t\t\t\t\tEntries:            entries,\n\t\t\t\t\t\t\t\t\t\tKeyword:            keyword,\n\t\t\t\t\t\t\t\t\t\tKeywordLoc:         prop.Key.Loc,\n\t\t\t\t\t\t\t\t\t\tInnerOpenBraceLoc:  prop.ValueOrNil.Loc,\n\t\t\t\t\t\t\t\t\t\tInnerCloseBraceLoc: value.CloseBraceLoc,\n\t\t\t\t\t\t\t\t\t\tOuterOpenBraceLoc:  e.OptionsOrNil.Loc,\n\t\t\t\t\t\t\t\t\t\tOuterCloseBraceLoc: object.CloseBraceLoc,\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\twhy = \"\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\twhy = \"the value for \\\"assert\\\" was not an object literal\"\n\t\t\t\t\t\t\t\twhyLoc = prop.ValueOrNil.Loc\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\twhy = \"this property was not called \\\"assert\\\" or \\\"with\\\"\"\n\t\t\t\t\t\t\twhyLoc = prop.Key.Loc\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\twhy = \"this property was invalid\"\n\t\t\t\t\t\twhyLoc = prop.Key.Loc\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\twhy = \"the second argument was not an object literal with a single property called \\\"assert\\\" or \\\"with\\\"\"\n\t\t\t\t\twhyLoc = e.OptionsOrNil.Loc\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Handle the case that isn't just an import assertion or attribute clause\n\t\t\tif why != \"\" {\n\t\t\t\t// Only warn when bundling\n\t\t\t\tif p.options.mode == config.ModeBundle {\n\t\t\t\t\ttext := \"This \\\"import()\\\" was not recognized because \" + why\n\t\t\t\t\tkind := logger.Warning\n\t\t\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\t\t\tkind = logger.Debug\n\t\t\t\t\t}\n\t\t\t\t\tp.log.AddID(logger.MsgID_JS_UnsupportedDynamicImport, kind, &p.tracker, logger.Range{Loc: whyLoc}, text)\n\t\t\t\t}\n\n\t\t\t\t// If import assertions and/attributes are both not supported in the\n\t\t\t\t// target platform, then \"import()\" cannot accept a second argument\n\t\t\t\t// and keeping them would be a syntax error, so we need to get rid of\n\t\t\t\t// them. We can't just not print them because they may have important\n\t\t\t\t// side effects. Attempt to discard them without changing side effects\n\t\t\t\t// and generate an error if that isn't possible.\n\t\t\t\tif p.options.unsupportedJSFeatures.Has(compat.ImportAssertions) && p.options.unsupportedJSFeatures.Has(compat.ImportAttributes) {\n\t\t\t\t\tif p.astHelpers.ExprCanBeRemovedIfUnused(e.OptionsOrNil) {\n\t\t\t\t\t\te.OptionsOrNil = js_ast.Expr{}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.markSyntaxFeature(compat.ImportAttributes, logger.Range{Loc: e.OptionsOrNil.Loc})\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Stop now so we don't try to split \"?:\" expressions below and\n\t\t\t\t// potentially end up with an AST node reused multiple times\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn p.maybeTransposeIfExprChain(e.Expr, func(arg js_ast.Expr) js_ast.Expr {\n\t\t\t// The argument must be a string\n\t\t\tif str, ok := arg.Data.(*js_ast.EString); ok {\n\t\t\t\t// Ignore calls to import() if the control flow is provably dead here.\n\t\t\t\t// We don't want to spend time scanning the required files if they will\n\t\t\t\t// never be used.\n\t\t\t\tif p.isControlFlowDead {\n\t\t\t\t\treturn js_ast.Expr{Loc: arg.Loc, Data: js_ast.ENullShared}\n\t\t\t\t}\n\n\t\t\t\timportRecordIndex := p.addImportRecord(ast.ImportDynamic, e.Phase, p.source.RangeOfString(arg.Loc), helpers.UTF16ToString(str.Value), assertOrWith, flags)\n\t\t\t\tif isAwaitTarget && p.fnOrArrowDataVisit.tryBodyCount != 0 {\n\t\t\t\t\trecord := &p.importRecords[importRecordIndex]\n\t\t\t\t\trecord.Flags |= ast.HandlesImportErrors\n\t\t\t\t\trecord.ErrorHandlerLoc = p.fnOrArrowDataVisit.tryCatchLoc\n\t\t\t\t} else if isThenCatchTarget {\n\t\t\t\t\trecord := &p.importRecords[importRecordIndex]\n\t\t\t\t\trecord.Flags |= ast.HandlesImportErrors\n\t\t\t\t\trecord.ErrorHandlerLoc = p.thenCatchChain.catchLoc\n\t\t\t\t}\n\t\t\t\tp.importRecordsForCurrentPart = append(p.importRecordsForCurrentPart, importRecordIndex)\n\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EImportString{\n\t\t\t\t\tImportRecordIndex: importRecordIndex,\n\t\t\t\t\tCloseParenLoc:     e.CloseParenLoc,\n\t\t\t\t}}\n\t\t\t}\n\n\t\t\t// Handle glob patterns\n\t\t\tif p.options.mode == config.ModeBundle {\n\t\t\t\tif value := p.handleGlobPattern(arg, ast.ImportDynamic, e.Phase, \"globImport\", assertOrWith); value.Data != nil {\n\t\t\t\t\treturn value\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Use a debug log so people can see this if they want to\n\t\t\tr := js_lexer.RangeOfIdentifier(p.source, expr.Loc)\n\t\t\tp.log.AddID(logger.MsgID_JS_UnsupportedDynamicImport, logger.Debug, &p.tracker, r,\n\t\t\t\t\"This \\\"import\\\" expression will not be bundled because the argument is not a string literal\")\n\n\t\t\t// We need to convert this into a call to \"require()\" if ES6 syntax is\n\t\t\t// not supported in the current output format. The full conversion:\n\t\t\t//\n\t\t\t//   Before:\n\t\t\t//     import(foo)\n\t\t\t//\n\t\t\t//   After:\n\t\t\t//     Promise.resolve().then(() => __toESM(require(foo)))\n\t\t\t//\n\t\t\t// This is normally done by the printer since we don't know during the\n\t\t\t// parsing stage whether this module is external or not. However, it's\n\t\t\t// guaranteed to be external if the argument isn't a string. We handle\n\t\t\t// this case here instead of in the printer because both the printer\n\t\t\t// and the linker currently need an import record to handle this case\n\t\t\t// correctly, and you need a string literal to get an import record.\n\t\t\tif p.options.unsupportedJSFeatures.Has(compat.DynamicImport) {\n\t\t\t\tvar then js_ast.Expr\n\t\t\t\tvalue := p.callRuntime(arg.Loc, \"__toESM\", []js_ast.Expr{{Loc: expr.Loc, Data: &js_ast.ECall{\n\t\t\t\t\tTarget:        p.valueToSubstituteForRequire(expr.Loc),\n\t\t\t\t\tArgs:          []js_ast.Expr{arg},\n\t\t\t\t\tCloseParenLoc: e.CloseParenLoc,\n\t\t\t\t}}})\n\t\t\t\tbody := js_ast.FnBody{Loc: expr.Loc, Block: js_ast.SBlock{Stmts: []js_ast.Stmt{{Loc: expr.Loc, Data: &js_ast.SReturn{ValueOrNil: value}}}}}\n\t\t\t\tif p.options.unsupportedJSFeatures.Has(compat.Arrow) {\n\t\t\t\t\tthen = js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EFunction{Fn: js_ast.Fn{Body: body}}}\n\t\t\t\t} else {\n\t\t\t\t\tthen = js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EArrow{Body: body, PreferExpr: true}}\n\t\t\t\t}\n\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ECall{\n\t\t\t\t\tTarget: js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EDot{\n\t\t\t\t\t\tTarget: js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ECall{\n\t\t\t\t\t\t\tTarget: js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EDot{\n\t\t\t\t\t\t\t\tTarget:  js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EIdentifier{Ref: p.makePromiseRef()}},\n\t\t\t\t\t\t\t\tName:    \"resolve\",\n\t\t\t\t\t\t\t\tNameLoc: expr.Loc,\n\t\t\t\t\t\t\t}},\n\t\t\t\t\t\t\tKind: js_ast.TargetWasOriginallyPropertyAccess,\n\t\t\t\t\t\t}},\n\t\t\t\t\t\tName:    \"then\",\n\t\t\t\t\t\tNameLoc: expr.Loc,\n\t\t\t\t\t}},\n\t\t\t\t\tArgs: []js_ast.Expr{then},\n\t\t\t\t\tKind: js_ast.TargetWasOriginallyPropertyAccess,\n\t\t\t\t}}\n\t\t\t}\n\n\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EImportCall{\n\t\t\t\tExpr:          arg,\n\t\t\t\tOptionsOrNil:  e.OptionsOrNil,\n\t\t\t\tCloseParenLoc: e.CloseParenLoc,\n\t\t\t}}\n\t\t}), exprOut{}\n\n\tcase *js_ast.ECall:\n\t\tp.callTarget = e.Target.Data\n\n\t\t// Track \".then().catch()\" chains\n\t\tp.thenCatchChain = thenCatchChain{\n\t\t\tnextTarget:      e.Target.Data,\n\t\t\thasMultipleArgs: len(e.Args) >= 2,\n\t\t\thasCatch:        p.thenCatchChain.nextTarget == e && p.thenCatchChain.hasCatch,\n\t\t\tcatchLoc:        p.thenCatchChain.catchLoc,\n\t\t}\n\t\tif p.thenCatchChain.hasMultipleArgs {\n\t\t\tp.thenCatchChain.catchLoc = e.Args[1].Loc\n\t\t}\n\n\t\twasIdentifierBeforeVisit := false\n\t\tisParenthesizedOptionalChain := false\n\t\tswitch e2 := e.Target.Data.(type) {\n\t\tcase *js_ast.EIdentifier:\n\t\t\twasIdentifierBeforeVisit = true\n\t\tcase *js_ast.EDot:\n\t\t\tisParenthesizedOptionalChain = e.OptionalChain == js_ast.OptionalChainNone && e2.OptionalChain != js_ast.OptionalChainNone\n\t\tcase *js_ast.EIndex:\n\t\t\tisParenthesizedOptionalChain = e.OptionalChain == js_ast.OptionalChainNone && e2.OptionalChain != js_ast.OptionalChainNone\n\t\t}\n\t\ttarget, out := p.visitExprInOut(e.Target, exprIn{\n\t\t\thasChainParent: e.OptionalChain == js_ast.OptionalChainContinue,\n\n\t\t\t// Signal to our child if this is an ECall at the start of an optional\n\t\t\t// chain. If so, the child will need to stash the \"this\" context for us\n\t\t\t// that we need for the \".call(this, ...args)\".\n\t\t\tstoreThisArgForParentOptionalChain: e.OptionalChain == js_ast.OptionalChainStart || isParenthesizedOptionalChain,\n\t\t})\n\t\te.Target = target\n\t\tp.warnAboutImportNamespaceCall(target, exprKindCall)\n\n\t\t// Automatically mark immediately-invoked function expressions for eager compilation\n\t\tif fn, ok := target.Data.(*js_ast.EFunction); ok {\n\t\t\tfn.IsParenthesized = true\n\t\t}\n\n\t\thasSpread := false\n\t\toldIsControlFlowDead := p.isControlFlowDead\n\n\t\t// If we're removing this call, don't count any arguments as symbol uses\n\t\tif out.callMustBeReplacedWithUndefined {\n\t\t\tif js_ast.IsPropertyAccess(e.Target) {\n\t\t\t\tp.isControlFlowDead = true\n\t\t\t} else {\n\t\t\t\tout.callMustBeReplacedWithUndefined = false\n\t\t\t}\n\t\t}\n\n\t\t// Visit the arguments\n\t\tfor i, arg := range e.Args {\n\t\t\targ = p.visitExpr(arg)\n\t\t\tif _, ok := arg.Data.(*js_ast.ESpread); ok {\n\t\t\t\thasSpread = true\n\t\t\t}\n\t\t\te.Args[i] = arg\n\t\t}\n\n\t\t// Mark side-effect free IIFEs with \"/* @__PURE__ */\"\n\t\tif !e.CanBeUnwrappedIfUnused {\n\t\t\tswitch target := e.Target.Data.(type) {\n\t\t\tcase *js_ast.EArrow:\n\t\t\t\tif !target.IsAsync && p.iifeCanBeRemovedIfUnused(target.Args, target.Body) {\n\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t\t}\n\t\t\tcase *js_ast.EFunction:\n\t\t\t\tif !target.Fn.IsAsync && !target.Fn.IsGenerator && p.iifeCanBeRemovedIfUnused(target.Fn.Args, target.Fn.Body) {\n\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Our hack for reading Yarn PnP files is implemented here:\n\t\tif p.options.decodeHydrateRuntimeStateYarnPnP {\n\t\t\tif id, ok := e.Target.Data.(*js_ast.EIdentifier); ok && p.symbols[id.Ref.InnerIndex].OriginalName == \"hydrateRuntimeState\" && len(e.Args) >= 1 {\n\t\t\t\tswitch arg := e.Args[0].Data.(type) {\n\t\t\t\tcase *js_ast.EObject:\n\t\t\t\t\t// \"hydrateRuntimeState(<object literal>)\"\n\t\t\t\t\tif arg := e.Args[0]; isValidJSON(arg) {\n\t\t\t\t\t\tp.manifestForYarnPnP = arg\n\t\t\t\t\t}\n\n\t\t\t\tcase *js_ast.ECall:\n\t\t\t\t\t// \"hydrateRuntimeState(JSON.parse(<something>))\"\n\t\t\t\t\tif len(arg.Args) == 1 {\n\t\t\t\t\t\tif dot, ok := arg.Target.Data.(*js_ast.EDot); ok && dot.Name == \"parse\" {\n\t\t\t\t\t\t\tif id, ok := dot.Target.Data.(*js_ast.EIdentifier); ok {\n\t\t\t\t\t\t\t\tif symbol := &p.symbols[id.Ref.InnerIndex]; symbol.Kind == ast.SymbolUnbound && symbol.OriginalName == \"JSON\" {\n\t\t\t\t\t\t\t\t\targ := arg.Args[0]\n\t\t\t\t\t\t\t\t\tswitch a := arg.Data.(type) {\n\t\t\t\t\t\t\t\t\tcase *js_ast.EString:\n\t\t\t\t\t\t\t\t\t\t// \"hydrateRuntimeState(JSON.parse(<string literal>))\"\n\t\t\t\t\t\t\t\t\t\tsource := logger.Source{KeyPath: p.source.KeyPath, Contents: helpers.UTF16ToString(a.Value)}\n\t\t\t\t\t\t\t\t\t\tstringInJSTable := logger.GenerateStringInJSTable(p.source.Contents, arg.Loc, source.Contents)\n\t\t\t\t\t\t\t\t\t\tlog := logger.NewStringInJSLog(p.log, &p.tracker, stringInJSTable)\n\t\t\t\t\t\t\t\t\t\tp.manifestForYarnPnP, _ = ParseJSON(log, source, JSONOptions{})\n\t\t\t\t\t\t\t\t\t\tremapExprLocsInJSON(&p.manifestForYarnPnP, stringInJSTable)\n\n\t\t\t\t\t\t\t\t\tcase *js_ast.EIdentifier:\n\t\t\t\t\t\t\t\t\t\t// \"hydrateRuntimeState(JSON.parse(<identifier>))\"\n\t\t\t\t\t\t\t\t\t\tif data, ok := p.stringLocalsForYarnPnP[a.Ref]; ok {\n\t\t\t\t\t\t\t\t\t\t\tsource := logger.Source{KeyPath: p.source.KeyPath, Contents: helpers.UTF16ToString(data.value)}\n\t\t\t\t\t\t\t\t\t\t\tstringInJSTable := logger.GenerateStringInJSTable(p.source.Contents, data.loc, source.Contents)\n\t\t\t\t\t\t\t\t\t\t\tlog := logger.NewStringInJSLog(p.log, &p.tracker, stringInJSTable)\n\t\t\t\t\t\t\t\t\t\t\tp.manifestForYarnPnP, _ = ParseJSON(log, source, JSONOptions{})\n\t\t\t\t\t\t\t\t\t\t\tremapExprLocsInJSON(&p.manifestForYarnPnP, stringInJSTable)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Stop now if this call must be removed\n\t\tif out.callMustBeReplacedWithUndefined {\n\t\t\tp.isControlFlowDead = oldIsControlFlowDead\n\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: js_ast.EUndefinedShared}, exprOut{}\n\t\t}\n\n\t\tif p.options.minifySyntax {\n\t\t\t// \"foo(1, ...[2, 3], 4)\" => \"foo(1, 2, 3, 4)\"\n\t\t\tif hasSpread {\n\t\t\t\te.Args = js_ast.InlineSpreadsOfArrayLiterals(e.Args)\n\t\t\t}\n\n\t\t\t// \"(() => x)()\" => \"x\"\n\t\t\tif value, ok := p.maybeInlineIIFE(expr.Loc, e); ok {\n\t\t\t\treturn value, exprOut{}\n\t\t\t}\n\t\t}\n\n\t\tswitch t := target.Data.(type) {\n\t\tcase *js_ast.EImportIdentifier:\n\t\t\t// If this function is inlined, allow it to be tree-shaken\n\t\t\tif p.options.minifySyntax && !p.isControlFlowDead {\n\t\t\t\tp.convertSymbolUseToCall(t.Ref, len(e.Args) == 1 && !hasSpread)\n\t\t\t}\n\n\t\tcase *js_ast.EIdentifier:\n\t\t\t// Detect if this is a direct eval. Note that \"(1 ? eval : 0)(x)\" will\n\t\t\t// become \"eval(x)\" after we visit the target due to dead code elimination,\n\t\t\t// but that doesn't mean it should become a direct eval.\n\t\t\t//\n\t\t\t// Note that \"eval?.(x)\" is considered an indirect eval. There was debate\n\t\t\t// about this after everyone implemented it as a direct eval, but the\n\t\t\t// language committee said it was indirect and everyone had to change it:\n\t\t\t// https://github.com/tc39/ecma262/issues/2062.\n\t\t\tif e.OptionalChain == js_ast.OptionalChainNone {\n\t\t\t\tsymbol := p.symbols[t.Ref.InnerIndex]\n\t\t\t\tif wasIdentifierBeforeVisit && symbol.OriginalName == \"eval\" {\n\t\t\t\t\te.Kind = js_ast.DirectEval\n\n\t\t\t\t\t// Pessimistically assume that if this looks like a CommonJS module\n\t\t\t\t\t// (e.g. no \"export\" keywords), a direct call to \"eval\" means that\n\t\t\t\t\t// code could potentially access \"module\" or \"exports\".\n\t\t\t\t\tif p.options.mode == config.ModeBundle && !p.isFileConsideredToHaveESMExports {\n\t\t\t\t\t\tp.recordUsage(p.moduleRef)\n\t\t\t\t\t\tp.recordUsage(p.exportsRef)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Mark this scope and all parent scopes as containing a direct eval.\n\t\t\t\t\t// This will prevent us from renaming any symbols.\n\t\t\t\t\tfor s := p.currentScope; s != nil; s = s.Parent {\n\t\t\t\t\t\ts.ContainsDirectEval = true\n\t\t\t\t\t}\n\n\t\t\t\t\t// Warn when direct eval is used in an ESM file. There is no way we\n\t\t\t\t\t// can guarantee that this will work correctly for top-level imported\n\t\t\t\t\t// and exported symbols due to scope hoisting. Except don't warn when\n\t\t\t\t\t// this code is in a 3rd-party library because there's nothing people\n\t\t\t\t\t// will be able to do about the warning.\n\t\t\t\t\ttext := \"Using direct eval with a bundler is not recommended and may cause problems\"\n\t\t\t\t\tkind := logger.Debug\n\t\t\t\t\tif p.options.mode == config.ModeBundle && p.isFileConsideredESM && !p.suppressWarningsAboutWeirdCode {\n\t\t\t\t\t\tkind = logger.Warning\n\t\t\t\t\t}\n\t\t\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_DirectEval, kind, &p.tracker, js_lexer.RangeOfIdentifier(p.source, e.Target.Loc), text,\n\t\t\t\t\t\t[]logger.MsgData{{Text: \"You can read more about direct eval and bundling here: https://esbuild.github.io/link/direct-eval\"}})\n\t\t\t\t} else if symbol.Flags.Has(ast.CallCanBeUnwrappedIfUnused) {\n\t\t\t\t\t// Automatically add a \"/* @__PURE__ */\" comment to file-local calls\n\t\t\t\t\t// of functions declared with a \"/* @__NO_SIDE_EFFECTS__ */\" comment\n\t\t\t\t\tt.CallCanBeUnwrappedIfUnused = true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Handle certain special cases\n\t\t\tif len(e.Args) <= 1 && !hasSpread {\n\t\t\t\tif symbol := &p.symbols[t.Ref.InnerIndex]; symbol.Kind == ast.SymbolUnbound {\n\t\t\t\t\tswitch symbol.OriginalName {\n\t\t\t\t\tcase \"Symbol\":\n\t\t\t\t\t\t// Calling the \"Symbol()\" constructor with a primitive will never throw\n\t\t\t\t\t\tif len(e.Args) == 0 || js_ast.KnownPrimitiveType(e.Args[0].Data) != js_ast.PrimitiveUnknown {\n\t\t\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Optimize references to global constructors\n\t\t\t\t\tif p.options.minifySyntax && t.CanBeRemovedIfUnused {\n\t\t\t\t\t\t// Note: We construct expressions by assigning to \"expr.Data\" so\n\t\t\t\t\t\t// that the source map position for the constructor is preserved\n\t\t\t\t\t\tswitch symbol.OriginalName {\n\t\t\t\t\t\tcase \"Boolean\":\n\t\t\t\t\t\t\tif len(e.Args) == 0 {\n\t\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EBoolean{Value: false}}, exprOut{}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\texpr.Data = &js_ast.EUnary{Value: p.astHelpers.SimplifyBooleanExpr(e.Args[0]), Op: js_ast.UnOpNot}\n\t\t\t\t\t\t\t\treturn js_ast.Not(expr), exprOut{}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcase \"Number\":\n\t\t\t\t\t\t\tif len(e.Args) == 0 {\n\t\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENumber{Value: 0}}, exprOut{}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\targ := e.Args[0]\n\n\t\t\t\t\t\t\t\tswitch js_ast.KnownPrimitiveType(arg.Data) {\n\t\t\t\t\t\t\t\tcase js_ast.PrimitiveNumber:\n\t\t\t\t\t\t\t\t\treturn arg, exprOut{}\n\n\t\t\t\t\t\t\t\tcase\n\t\t\t\t\t\t\t\t\tjs_ast.PrimitiveUndefined, // NaN\n\t\t\t\t\t\t\t\t\tjs_ast.PrimitiveNull,      // 0\n\t\t\t\t\t\t\t\t\tjs_ast.PrimitiveBoolean,   // 0 or 1\n\t\t\t\t\t\t\t\t\tjs_ast.PrimitiveString:    // StringToNumber\n\t\t\t\t\t\t\t\t\tif number, ok := js_ast.ToNumberWithoutSideEffects(arg.Data); ok {\n\t\t\t\t\t\t\t\t\t\texpr.Data = &js_ast.ENumber{Value: number}\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\texpr.Data = &js_ast.EUnary{Value: arg, Op: js_ast.UnOpPos}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn expr, exprOut{}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcase \"String\":\n\t\t\t\t\t\t\tif len(e.Args) == 0 {\n\t\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: nil}}, exprOut{}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\targ := e.Args[0]\n\n\t\t\t\t\t\t\t\tswitch js_ast.KnownPrimitiveType(arg.Data) {\n\t\t\t\t\t\t\t\tcase js_ast.PrimitiveString:\n\t\t\t\t\t\t\t\t\treturn arg, exprOut{}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcase \"BigInt\":\n\t\t\t\t\t\t\tif len(e.Args) == 1 {\n\t\t\t\t\t\t\t\targ := e.Args[0]\n\n\t\t\t\t\t\t\t\tswitch js_ast.KnownPrimitiveType(arg.Data) {\n\t\t\t\t\t\t\t\tcase js_ast.PrimitiveBigInt:\n\t\t\t\t\t\t\t\t\treturn arg, exprOut{}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Copy the call side effect flag over if this is a known target\n\t\t\tif t.CallCanBeUnwrappedIfUnused {\n\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t}\n\n\t\t\t// If this function is inlined, allow it to be tree-shaken\n\t\t\tif p.options.minifySyntax && !p.isControlFlowDead {\n\t\t\t\tp.convertSymbolUseToCall(t.Ref, len(e.Args) == 1 && !hasSpread)\n\t\t\t}\n\n\t\tcase *js_ast.EDot:\n\t\t\tif len(e.Args) == 1 {\n\t\t\t\tswitch t.Name {\n\t\t\t\tcase \"resolve\":\n\t\t\t\t\t// Recognize \"require.resolve()\" calls\n\t\t\t\t\tif t.OptionalChain == js_ast.OptionalChainNone && p.options.mode != config.ModePassThrough {\n\t\t\t\t\t\tif id, ok := t.Target.Data.(*js_ast.EIdentifier); ok && id.Ref == p.requireRef {\n\t\t\t\t\t\t\tp.ignoreUsage(p.requireRef)\n\t\t\t\t\t\t\treturn p.maybeTransposeIfExprChain(e.Args[0], func(arg js_ast.Expr) js_ast.Expr {\n\t\t\t\t\t\t\t\tif str, ok := e.Args[0].Data.(*js_ast.EString); ok {\n\t\t\t\t\t\t\t\t\t// Ignore calls to require.resolve() if the control flow is provably\n\t\t\t\t\t\t\t\t\t// dead here. We don't want to spend time scanning the required files\n\t\t\t\t\t\t\t\t\t// if they will never be used.\n\t\t\t\t\t\t\t\t\tif p.isControlFlowDead {\n\t\t\t\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: js_ast.ENullShared}\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\timportRecordIndex := p.addImportRecord(ast.ImportRequireResolve, ast.EvaluationPhase, p.source.RangeOfString(e.Args[0].Loc), helpers.UTF16ToString(str.Value), nil, 0)\n\t\t\t\t\t\t\t\t\tif p.fnOrArrowDataVisit.tryBodyCount != 0 {\n\t\t\t\t\t\t\t\t\t\trecord := &p.importRecords[importRecordIndex]\n\t\t\t\t\t\t\t\t\t\trecord.Flags |= ast.HandlesImportErrors\n\t\t\t\t\t\t\t\t\t\trecord.ErrorHandlerLoc = p.fnOrArrowDataVisit.tryCatchLoc\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tp.importRecordsForCurrentPart = append(p.importRecordsForCurrentPart, importRecordIndex)\n\n\t\t\t\t\t\t\t\t\t// Create a new expression to represent the operation\n\t\t\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ERequireResolveString{\n\t\t\t\t\t\t\t\t\t\tImportRecordIndex: importRecordIndex,\n\t\t\t\t\t\t\t\t\t\tCloseParenLoc:     e.CloseParenLoc,\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Otherwise just return a clone of the \"require.resolve()\" call\n\t\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ECall{\n\t\t\t\t\t\t\t\t\tTarget: js_ast.Expr{Loc: e.Target.Loc, Data: &js_ast.EDot{\n\t\t\t\t\t\t\t\t\t\tTarget:  p.valueToSubstituteForRequire(t.Target.Loc),\n\t\t\t\t\t\t\t\t\t\tName:    t.Name,\n\t\t\t\t\t\t\t\t\t\tNameLoc: t.NameLoc,\n\t\t\t\t\t\t\t\t\t}},\n\t\t\t\t\t\t\t\t\tArgs:          []js_ast.Expr{arg},\n\t\t\t\t\t\t\t\t\tKind:          e.Kind,\n\t\t\t\t\t\t\t\t\tCloseParenLoc: e.CloseParenLoc,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t}), exprOut{}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"for\":\n\t\t\t\t\t// Calling \"Symbol.for()\" with a primitive will never throw\n\t\t\t\t\tif id, ok := t.Target.Data.(*js_ast.EIdentifier); ok {\n\t\t\t\t\t\tif symbol := &p.symbols[id.Ref.InnerIndex]; symbol.Kind == ast.SymbolUnbound && symbol.OriginalName == \"Symbol\" {\n\t\t\t\t\t\t\tif js_ast.KnownPrimitiveType(e.Args[0].Data) != js_ast.PrimitiveUnknown {\n\t\t\t\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"create\":\n\t\t\t\t\t// Recognize \"Object.create()\" calls\n\t\t\t\t\tif id, ok := t.Target.Data.(*js_ast.EIdentifier); ok {\n\t\t\t\t\t\tif symbol := &p.symbols[id.Ref.InnerIndex]; symbol.Kind == ast.SymbolUnbound && symbol.OriginalName == \"Object\" {\n\t\t\t\t\t\t\tswitch e.Args[0].Data.(type) {\n\t\t\t\t\t\t\tcase *js_ast.ENull, *js_ast.EObject:\n\t\t\t\t\t\t\t\t// Mark \"Object.create(null)\" and \"Object.create({})\" as pure\n\t\t\t\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"escape\":\n\t\t\t\t\t// Recognize \"RegExp.escape()\" calls\n\t\t\t\t\tif id, ok := t.Target.Data.(*js_ast.EIdentifier); ok {\n\t\t\t\t\t\tif symbol := &p.symbols[id.Ref.InnerIndex]; symbol.Kind == ast.SymbolUnbound && symbol.OriginalName == \"RegExp\" {\n\t\t\t\t\t\t\tif js_ast.KnownPrimitiveType(e.Args[0].Data) == js_ast.PrimitiveString {\n\t\t\t\t\t\t\t\t// Mark \"RegExp.escape\" with a string literal as pure\n\t\t\t\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif p.options.minifySyntax {\n\t\t\t\tswitch t.Name {\n\t\t\t\tcase \"charCodeAt\":\n\t\t\t\t\t// Recognize \"'string'.charCodeAt()\" calls\n\t\t\t\t\tif str, ok := t.Target.Data.(*js_ast.EString); ok && len(e.Args) <= 1 {\n\t\t\t\t\t\tindex := 0\n\t\t\t\t\t\thasIndex := false\n\t\t\t\t\t\tif len(e.Args) == 0 {\n\t\t\t\t\t\t\thasIndex = true\n\t\t\t\t\t\t} else if num, ok := e.Args[0].Data.(*js_ast.ENumber); ok && num.Value == math.Trunc(num.Value) && math.Abs(num.Value) <= 0x7FFF_FFFF {\n\t\t\t\t\t\t\tindex = int(num.Value)\n\t\t\t\t\t\t\thasIndex = true\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif hasIndex {\n\t\t\t\t\t\t\tif index >= 0 && index < len(str.Value) {\n\t\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENumber{Value: float64(str.Value[index])}}, exprOut{}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENumber{Value: math.NaN()}}, exprOut{}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"fromCharCode\":\n\t\t\t\t\t// Recognize \"String.fromCharCode()\" calls\n\t\t\t\t\tif id, ok := t.Target.Data.(*js_ast.EIdentifier); ok {\n\t\t\t\t\t\tif symbol := &p.symbols[id.Ref.InnerIndex]; symbol.Kind == ast.SymbolUnbound && symbol.OriginalName == \"String\" {\n\t\t\t\t\t\t\tcharCodes := make([]uint16, 0, len(e.Args))\n\t\t\t\t\t\t\tfor _, arg := range e.Args {\n\t\t\t\t\t\t\t\targ, ok := js_ast.ToNumberWithoutSideEffects(arg.Data)\n\t\t\t\t\t\t\t\tif !ok {\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcharCodes = append(charCodes, uint16(js_ast.ToInt32(arg)))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif len(charCodes) == len(e.Args) {\n\t\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: charCodes}}, exprOut{}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"toString\":\n\t\t\t\t\tswitch target := t.Target.Data.(type) {\n\t\t\t\t\tcase *js_ast.ENumber:\n\t\t\t\t\t\tradix := 0\n\t\t\t\t\t\tif len(e.Args) == 0 {\n\t\t\t\t\t\t\tradix = 10\n\t\t\t\t\t\t} else if len(e.Args) == 1 {\n\t\t\t\t\t\t\tif num, ok := e.Args[0].Data.(*js_ast.ENumber); ok && num.Value == math.Trunc(num.Value) && num.Value >= 2 && num.Value <= 36 {\n\t\t\t\t\t\t\t\tradix = int(num.Value)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif radix != 0 {\n\t\t\t\t\t\t\tif str, ok := js_ast.TryToStringOnNumberSafely(target.Value, radix); ok {\n\t\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(str)}}, exprOut{}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase *js_ast.ERegExp:\n\t\t\t\t\t\tif len(e.Args) == 0 {\n\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(target.Value)}}, exprOut{}\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase *js_ast.EBoolean:\n\t\t\t\t\t\tif len(e.Args) == 0 {\n\t\t\t\t\t\t\tif target.Value {\n\t\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(\"true\")}}, exprOut{}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(\"false\")}}, exprOut{}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase *js_ast.EString:\n\t\t\t\t\t\tif len(e.Args) == 0 {\n\t\t\t\t\t\t\treturn t.Target, exprOut{}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Copy the call side effect flag over if this is a known target\n\t\t\tif t.CallCanBeUnwrappedIfUnused {\n\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t}\n\n\t\tcase *js_ast.EIndex:\n\t\t\t// Copy the call side effect flag over if this is a known target\n\t\t\tif t.CallCanBeUnwrappedIfUnused {\n\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t}\n\n\t\tcase *js_ast.ESuper:\n\t\t\t// If we're shimming \"super()\" calls, replace this call with \"__super()\"\n\t\t\tif p.superCtorRef != ast.InvalidRef {\n\t\t\t\tp.recordUsage(p.superCtorRef)\n\t\t\t\ttarget.Data = &js_ast.EIdentifier{Ref: p.superCtorRef}\n\t\t\t\te.Target.Data = target.Data\n\t\t\t}\n\t\t}\n\n\t\t// Handle parenthesized optional chains\n\t\tif isParenthesizedOptionalChain && out.thisArgFunc != nil && out.thisArgWrapFunc != nil {\n\t\t\treturn p.lowerParenthesizedOptionalChain(expr.Loc, e, out), exprOut{}\n\t\t}\n\n\t\t// Lower optional chaining if we're the top of the chain\n\t\tcontainsOptionalChain := e.OptionalChain == js_ast.OptionalChainStart ||\n\t\t\t(e.OptionalChain == js_ast.OptionalChainContinue && out.childContainsOptionalChain)\n\t\tif containsOptionalChain && !in.hasChainParent {\n\t\t\treturn p.lowerOptionalChain(expr, in, out)\n\t\t}\n\n\t\t// If this is a plain call expression (instead of an optional chain), lower\n\t\t// private member access in the call target now if there is one\n\t\tif !containsOptionalChain {\n\t\t\tif target, loc, private := p.extractPrivateIndex(e.Target); private != nil {\n\t\t\t\t// \"foo.#bar(123)\" => \"__privateGet(_a = foo, #bar).call(_a, 123)\"\n\t\t\t\ttargetFunc, targetWrapFunc := p.captureValueWithPossibleSideEffects(target.Loc, 2, target, valueCouldBeMutated)\n\t\t\t\treturn targetWrapFunc(js_ast.Expr{Loc: target.Loc, Data: &js_ast.ECall{\n\t\t\t\t\tTarget: js_ast.Expr{Loc: target.Loc, Data: &js_ast.EDot{\n\t\t\t\t\t\tTarget:  p.lowerPrivateGet(targetFunc(), loc, private),\n\t\t\t\t\t\tName:    \"call\",\n\t\t\t\t\t\tNameLoc: target.Loc,\n\t\t\t\t\t}},\n\t\t\t\t\tArgs:                   append([]js_ast.Expr{targetFunc()}, e.Args...),\n\t\t\t\t\tCanBeUnwrappedIfUnused: e.CanBeUnwrappedIfUnused,\n\t\t\t\t\tKind:                   js_ast.TargetWasOriginallyPropertyAccess,\n\t\t\t\t}}), exprOut{}\n\t\t\t}\n\t\t\tp.maybeLowerSuperPropertyGetInsideCall(e)\n\t\t}\n\n\t\t// Track calls to require() so we can use them while bundling\n\t\tif p.options.mode != config.ModePassThrough && e.OptionalChain == js_ast.OptionalChainNone {\n\t\t\tif id, ok := e.Target.Data.(*js_ast.EIdentifier); ok && id.Ref == p.requireRef {\n\t\t\t\t// Heuristic: omit warnings inside try/catch blocks because presumably\n\t\t\t\t// the try/catch statement is there to handle the potential run-time\n\t\t\t\t// error from the unbundled require() call failing.\n\t\t\t\tomitWarnings := p.fnOrArrowDataVisit.tryBodyCount != 0\n\n\t\t\t\tif p.options.mode != config.ModePassThrough {\n\t\t\t\t\t// There must be one argument\n\t\t\t\t\tif len(e.Args) == 1 {\n\t\t\t\t\t\tp.ignoreUsage(p.requireRef)\n\t\t\t\t\t\treturn p.maybeTransposeIfExprChain(e.Args[0], func(arg js_ast.Expr) js_ast.Expr {\n\t\t\t\t\t\t\t// The argument must be a string\n\t\t\t\t\t\t\tif str, ok := arg.Data.(*js_ast.EString); ok {\n\t\t\t\t\t\t\t\t// Ignore calls to require() if the control flow is provably dead here.\n\t\t\t\t\t\t\t\t// We don't want to spend time scanning the required files if they will\n\t\t\t\t\t\t\t\t// never be used.\n\t\t\t\t\t\t\t\tif p.isControlFlowDead {\n\t\t\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: js_ast.ENullShared}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\timportRecordIndex := p.addImportRecord(ast.ImportRequire, ast.EvaluationPhase, p.source.RangeOfString(arg.Loc), helpers.UTF16ToString(str.Value), nil, 0)\n\t\t\t\t\t\t\t\tif p.fnOrArrowDataVisit.tryBodyCount != 0 {\n\t\t\t\t\t\t\t\t\trecord := &p.importRecords[importRecordIndex]\n\t\t\t\t\t\t\t\t\trecord.Flags |= ast.HandlesImportErrors\n\t\t\t\t\t\t\t\t\trecord.ErrorHandlerLoc = p.fnOrArrowDataVisit.tryCatchLoc\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tp.importRecordsForCurrentPart = append(p.importRecordsForCurrentPart, importRecordIndex)\n\n\t\t\t\t\t\t\t\t// Currently \"require\" is not converted into \"import\" for ESM\n\t\t\t\t\t\t\t\tif p.options.mode != config.ModeBundle && p.options.outputFormat == config.FormatESModule && !omitWarnings {\n\t\t\t\t\t\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, e.Target.Loc)\n\t\t\t\t\t\t\t\t\tp.log.AddID(logger.MsgID_JS_UnsupportedRequireCall, logger.Warning, &p.tracker, r, \"Converting \\\"require\\\" to \\\"esm\\\" is currently not supported\")\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Create a new expression to represent the operation\n\t\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ERequireString{\n\t\t\t\t\t\t\t\t\tImportRecordIndex: importRecordIndex,\n\t\t\t\t\t\t\t\t\tCloseParenLoc:     e.CloseParenLoc,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Handle glob patterns\n\t\t\t\t\t\t\tif p.options.mode == config.ModeBundle {\n\t\t\t\t\t\t\t\tif value := p.handleGlobPattern(arg, ast.ImportRequire, ast.EvaluationPhase, \"globRequire\", nil); value.Data != nil {\n\t\t\t\t\t\t\t\t\treturn value\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Use a debug log so people can see this if they want to\n\t\t\t\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, e.Target.Loc)\n\t\t\t\t\t\t\tp.log.AddID(logger.MsgID_JS_UnsupportedRequireCall, logger.Debug, &p.tracker, r,\n\t\t\t\t\t\t\t\t\"This call to \\\"require\\\" will not be bundled because the argument is not a string literal\")\n\n\t\t\t\t\t\t\t// Otherwise just return a clone of the \"require()\" call\n\t\t\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ECall{\n\t\t\t\t\t\t\t\tTarget:        p.valueToSubstituteForRequire(e.Target.Loc),\n\t\t\t\t\t\t\t\tArgs:          []js_ast.Expr{arg},\n\t\t\t\t\t\t\t\tCloseParenLoc: e.CloseParenLoc,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t}), exprOut{}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Use a debug log so people can see this if they want to\n\t\t\t\t\t\tr := js_lexer.RangeOfIdentifier(p.source, e.Target.Loc)\n\t\t\t\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_UnsupportedRequireCall, logger.Debug, &p.tracker, r,\n\t\t\t\t\t\t\tfmt.Sprintf(\"This call to \\\"require\\\" will not be bundled because it has %d arguments\", len(e.Args)),\n\t\t\t\t\t\t\t[]logger.MsgData{{Text: \"To be bundled by esbuild, a \\\"require\\\" call must have exactly 1 argument.\"}})\n\t\t\t\t\t}\n\n\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ECall{\n\t\t\t\t\t\tTarget:        p.valueToSubstituteForRequire(e.Target.Loc),\n\t\t\t\t\t\tArgs:          e.Args,\n\t\t\t\t\t\tCloseParenLoc: e.CloseParenLoc,\n\t\t\t\t\t}}, exprOut{}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tout = exprOut{\n\t\t\tchildContainsOptionalChain: containsOptionalChain,\n\t\t\tthisArgFunc:                out.thisArgFunc,\n\t\t\tthisArgWrapFunc:            out.thisArgWrapFunc,\n\t\t}\n\t\tif !in.hasChainParent {\n\t\t\tout.thisArgFunc = nil\n\t\t\tout.thisArgWrapFunc = nil\n\t\t}\n\t\treturn expr, out\n\n\tcase *js_ast.ENew:\n\t\thasSpread := false\n\n\t\te.Target = p.visitExpr(e.Target)\n\t\tp.warnAboutImportNamespaceCall(e.Target, exprKindNew)\n\n\t\tfor i, arg := range e.Args {\n\t\t\targ = p.visitExpr(arg)\n\t\t\tif _, ok := arg.Data.(*js_ast.ESpread); ok {\n\t\t\t\thasSpread = true\n\t\t\t}\n\t\t\te.Args[i] = arg\n\t\t}\n\n\t\t// \"new foo(1, ...[2, 3], 4)\" => \"new foo(1, 2, 3, 4)\"\n\t\tif p.options.minifySyntax && hasSpread {\n\t\t\te.Args = js_ast.InlineSpreadsOfArrayLiterals(e.Args)\n\t\t}\n\n\t\tp.maybeMarkKnownGlobalConstructorAsPure(e)\n\n\tcase *js_ast.EArrow:\n\t\t// Check for a propagated name to keep from the parent context\n\t\tvar nameToKeep string\n\t\tif p.nameToKeepIsFor == e {\n\t\t\tnameToKeep = p.nameToKeep\n\t\t}\n\n\t\t// Prepare for suspicious logical operator checking\n\t\tif e.PreferExpr && len(e.Args) == 1 && e.Args[0].DefaultOrNil.Data == nil && len(e.Body.Block.Stmts) == 1 {\n\t\t\tif _, ok := e.Args[0].Binding.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\tif stmt, ok := e.Body.Block.Stmts[0].Data.(*js_ast.SReturn); ok {\n\t\t\t\t\tif binary, ok := stmt.ValueOrNil.Data.(*js_ast.EBinary); ok && (binary.Op == js_ast.BinOpLogicalAnd || binary.Op == js_ast.BinOpLogicalOr) {\n\t\t\t\t\t\tp.suspiciousLogicalOperatorInsideArrow = binary\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tasyncArrowNeedsToBeLowered := e.IsAsync && p.options.unsupportedJSFeatures.Has(compat.AsyncAwait)\n\t\toldFnOrArrowData := p.fnOrArrowDataVisit\n\t\tp.fnOrArrowDataVisit = fnOrArrowDataVisit{\n\t\t\tisArrow:                        true,\n\t\t\tisAsync:                        e.IsAsync,\n\t\t\tshouldLowerSuperPropertyAccess: oldFnOrArrowData.shouldLowerSuperPropertyAccess || asyncArrowNeedsToBeLowered,\n\t\t}\n\n\t\t// Mark if we're inside an async arrow function. This value should be true\n\t\t// even if we're inside multiple arrow functions and the closest inclosing\n\t\t// arrow function isn't async, as long as at least one enclosing arrow\n\t\t// function within the current enclosing function is async.\n\t\toldInsideAsyncArrowFn := p.fnOnlyDataVisit.isInsideAsyncArrowFn\n\t\tif e.IsAsync {\n\t\t\tp.fnOnlyDataVisit.isInsideAsyncArrowFn = true\n\t\t}\n\n\t\tp.pushScopeForVisitPass(js_ast.ScopeFunctionArgs, expr.Loc)\n\t\tp.visitArgs(e.Args, visitArgsOpts{\n\t\t\thasRestArg:               e.HasRestArg,\n\t\t\tbody:                     e.Body.Block.Stmts,\n\t\t\tisUniqueFormalParameters: true,\n\t\t})\n\t\tp.pushScopeForVisitPass(js_ast.ScopeFunctionBody, e.Body.Loc)\n\t\te.Body.Block.Stmts = p.visitStmtsAndPrependTempRefs(e.Body.Block.Stmts, prependTempRefsOpts{kind: stmtsFnBody})\n\t\tp.popScope()\n\t\tp.lowerFunction(&e.IsAsync, nil, &e.Args, e.Body.Loc, &e.Body.Block, &e.PreferExpr, &e.HasRestArg, true /* isArrow */)\n\t\tp.popScope()\n\n\t\tif p.options.minifySyntax && len(e.Body.Block.Stmts) == 1 {\n\t\t\tif s, ok := e.Body.Block.Stmts[0].Data.(*js_ast.SReturn); ok && s.ValueOrNil.Data != nil {\n\t\t\t\t// \"() => { return x }\" => \"() => x\"\n\t\t\t\te.PreferExpr = true\n\t\t\t}\n\t\t}\n\n\t\tp.fnOnlyDataVisit.isInsideAsyncArrowFn = oldInsideAsyncArrowFn\n\t\tp.fnOrArrowDataVisit = oldFnOrArrowData\n\n\t\t// Convert arrow functions to function expressions when lowering\n\t\tif p.options.unsupportedJSFeatures.Has(compat.Arrow) {\n\t\t\texpr.Data = &js_ast.EFunction{Fn: js_ast.Fn{\n\t\t\t\tArgs:         e.Args,\n\t\t\t\tBody:         e.Body,\n\t\t\t\tArgumentsRef: ast.InvalidRef,\n\t\t\t\tIsAsync:      e.IsAsync,\n\t\t\t\tHasRestArg:   e.HasRestArg,\n\t\t\t}}\n\t\t}\n\n\t\t// Optionally preserve the name\n\t\tif p.options.keepNames && nameToKeep != \"\" {\n\t\t\texpr = p.keepExprSymbolName(expr, nameToKeep)\n\t\t}\n\n\tcase *js_ast.EFunction:\n\t\t// Check for a propagated name to keep from the parent context\n\t\tvar nameToKeep string\n\t\tif p.nameToKeepIsFor == e {\n\t\t\tnameToKeep = p.nameToKeep\n\t\t}\n\n\t\tp.visitFn(&e.Fn, expr.Loc, visitFnOpts{\n\t\t\tisMethod:               in.isMethod,\n\t\t\tisDerivedClassCtor:     e == p.propDerivedCtorValue,\n\t\t\tisLoweredPrivateMethod: in.isLoweredPrivateMethod,\n\t\t})\n\t\tname := e.Fn.Name\n\n\t\t// Remove unused function names when minifying\n\t\tif p.options.minifySyntax && !p.currentScope.ContainsDirectEval &&\n\t\t\tname != nil && p.symbols[name.Ref.InnerIndex].UseCountEstimate == 0 {\n\t\t\te.Fn.Name = nil\n\t\t}\n\n\t\t// Optionally preserve the name for functions, but not for methods\n\t\tif p.options.keepNames && (!in.isMethod || in.isLoweredPrivateMethod) {\n\t\t\tif name != nil {\n\t\t\t\texpr = p.keepExprSymbolName(expr, p.symbols[name.Ref.InnerIndex].OriginalName)\n\t\t\t} else if nameToKeep != \"\" {\n\t\t\t\texpr = p.keepExprSymbolName(expr, nameToKeep)\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.EClass:\n\t\t// Check for a propagated name to keep from the parent context\n\t\tvar nameToKeep string\n\t\tif p.nameToKeepIsFor == e {\n\t\t\tnameToKeep = p.nameToKeep\n\t\t}\n\n\t\tresult := p.visitClass(expr.Loc, &e.Class, ast.InvalidRef, nameToKeep)\n\n\t\t// Lower class field syntax for browsers that don't support it\n\t\t_, expr = p.lowerClass(js_ast.Stmt{}, expr, result, nameToKeep)\n\n\t\t// We may be able to determine that a class is side-effect before lowering\n\t\t// but not after lowering (e.g. due to \"--keep-names\" mutating the object).\n\t\t// If that's the case, add a special annotation so this doesn't prevent\n\t\t// tree-shaking from happening.\n\t\tif result.canBeRemovedIfUnused {\n\t\t\texpr.Data = &js_ast.EAnnotation{\n\t\t\t\tValue: expr,\n\t\t\t\tFlags: js_ast.CanBeRemovedIfUnusedFlag,\n\t\t\t}\n\t\t}\n\n\tdefault:\n\t\t// Note: EPrivateIdentifier should have already been handled\n\t\tpanic(fmt.Sprintf(\"Unexpected expression of type %T\", expr.Data))\n\t}\n\n\treturn expr, exprOut{}\n}\n\n// This exists to handle very deeply-nested ASTs. For example, the \"grapheme-splitter\"\n// package contains this monstrosity:\n//\n//\tif (\n//\t  (0x0300 <= code && code <= 0x036F) ||\n//\t  (0x0483 <= code && code <= 0x0487) ||\n//\t  (0x0488 <= code && code <= 0x0489) ||\n//\t  (0x0591 <= code && code <= 0x05BD) ||\n//\t  ... many hundreds of lines later ...\n//\t) {\n//\t  return;\n//\t}\n//\n// If \"checkAndPrepare\" returns non-nil, then the return value is the final\n// expression. Otherwise, the final expression can be obtained by manually\n// visiting the left child and then calling \"visitRightAndFinish\":\n//\n//\tif result := v.checkAndPrepare(p); result.Data != nil {\n//\t  return result\n//\t}\n//\tv.e.Left, _ = p.visitExprInOut(v.e.Left, v.leftIn)\n//\treturn v.visitRightAndFinish(p)\n//\n// This code is convoluted this way so that we can use our own stack on the\n// heap instead of the call stack when there are additional levels of nesting.\n// Before this transformation, the code previously looked something like this:\n//\n//\t... The code in \"checkAndPrepare\" ...\n//\te.Left, _ = p.visitExprInOut(e.Left, in)\n//\t... The code in \"visitRightAndFinish\" ...\n//\n// If this code is still confusing, it may be helpful to look back in git\n// history at the commit that introduced this transformation.\n//\n// Go normally has growable call stacks so this code transformation normally\n// doesn't do anything, but WebAssembly doesn't allow stack pointer manipulation\n// so Go's WebAssembly implementation doesn't support growable call stacks and\n// is therefore vulnerable to stack overflow. So this code transformation is\n// only really relevant for esbuild's WebAssembly-based API.\ntype binaryExprVisitor struct {\n\t// Inputs\n\te   *js_ast.EBinary\n\tloc logger.Loc\n\tin  exprIn\n\n\t// Input for visiting the left child\n\tleftIn exprIn\n\n\t// \"Local variables\" passed from \"checkAndPrepare\" to \"visitRightAndFinish\"\n\tisStmtExpr                               bool\n\toldSilenceWarningAboutThisBeingUndefined bool\n}\n\nfunc (v *binaryExprVisitor) checkAndPrepare(p *parser) js_ast.Expr {\n\te := v.e\n\n\t// Special-case EPrivateIdentifier to allow it here\n\tif private, ok := e.Left.Data.(*js_ast.EPrivateIdentifier); ok && e.Op == js_ast.BinOpIn {\n\t\tname := p.loadNameFromRef(private.Ref)\n\t\tresult := p.findSymbol(e.Left.Loc, name)\n\t\tprivate.Ref = result.ref\n\n\t\t// Unlike regular identifiers, there are no unbound private identifiers\n\t\tsymbol := &p.symbols[result.ref.InnerIndex]\n\t\tif !symbol.Kind.IsPrivate() {\n\t\t\tr := logger.Range{Loc: e.Left.Loc, Len: int32(len(name))}\n\t\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\"Private name %q must be declared in an enclosing class\", name))\n\t\t}\n\n\t\te.Right = p.visitExpr(e.Right)\n\n\t\tif p.privateSymbolNeedsToBeLowered(private) {\n\t\t\treturn p.lowerPrivateBrandCheck(e.Right, v.loc, private)\n\t\t}\n\t\treturn js_ast.Expr{Loc: v.loc, Data: e}\n\t}\n\n\tv.isStmtExpr = e == p.stmtExprValue\n\tv.oldSilenceWarningAboutThisBeingUndefined = p.fnOnlyDataVisit.silenceMessageAboutThisBeingUndefined\n\n\tif _, ok := e.Left.Data.(*js_ast.EThis); ok && e.Op == js_ast.BinOpLogicalAnd {\n\t\tp.fnOnlyDataVisit.silenceMessageAboutThisBeingUndefined = true\n\t}\n\tv.leftIn = exprIn{\n\t\tassignTarget:               e.Op.BinaryAssignTarget(),\n\t\tshouldMangleStringsAsProps: e.Op == js_ast.BinOpIn,\n\t}\n\treturn js_ast.Expr{}\n}\n\nfunc (v *binaryExprVisitor) visitRightAndFinish(p *parser) js_ast.Expr {\n\te := v.e\n\n\t// Mark the control flow as dead if the branch is never taken\n\tswitch e.Op {\n\tcase js_ast.BinOpLogicalOr:\n\t\tif boolean, _, ok := js_ast.ToBooleanWithSideEffects(e.Left.Data); ok && boolean {\n\t\t\t// \"true || dead\"\n\t\t\told := p.isControlFlowDead\n\t\t\tp.isControlFlowDead = true\n\t\t\te.Right = p.visitExpr(e.Right)\n\t\t\tp.isControlFlowDead = old\n\t\t} else {\n\t\t\te.Right = p.visitExpr(e.Right)\n\t\t}\n\n\tcase js_ast.BinOpLogicalAnd:\n\t\tif boolean, _, ok := js_ast.ToBooleanWithSideEffects(e.Left.Data); ok && !boolean {\n\t\t\t// \"false && dead\"\n\t\t\told := p.isControlFlowDead\n\t\t\tp.isControlFlowDead = true\n\t\t\te.Right = p.visitExpr(e.Right)\n\t\t\tp.isControlFlowDead = old\n\t\t} else {\n\t\t\te.Right = p.visitExpr(e.Right)\n\t\t}\n\n\tcase js_ast.BinOpNullishCoalescing:\n\t\tif isNullOrUndefined, _, ok := js_ast.ToNullOrUndefinedWithSideEffects(e.Left.Data); ok && !isNullOrUndefined {\n\t\t\t// \"notNullOrUndefined ?? dead\"\n\t\t\told := p.isControlFlowDead\n\t\t\tp.isControlFlowDead = true\n\t\t\te.Right = p.visitExpr(e.Right)\n\t\t\tp.isControlFlowDead = old\n\t\t} else {\n\t\t\te.Right = p.visitExpr(e.Right)\n\t\t}\n\n\tcase js_ast.BinOpComma:\n\t\te.Right, _ = p.visitExprInOut(e.Right, exprIn{\n\t\t\tshouldMangleStringsAsProps: v.in.shouldMangleStringsAsProps,\n\t\t})\n\n\tcase js_ast.BinOpAssign, js_ast.BinOpLogicalOrAssign, js_ast.BinOpLogicalAndAssign, js_ast.BinOpNullishCoalescingAssign:\n\t\t// Check for a propagated name to keep from the parent context\n\t\tif id, ok := e.Left.Data.(*js_ast.EIdentifier); ok {\n\t\t\tp.nameToKeep = p.symbols[id.Ref.InnerIndex].OriginalName\n\t\t\tp.nameToKeepIsFor = e.Right.Data\n\t\t}\n\n\t\te.Right = p.visitExpr(e.Right)\n\n\tdefault:\n\t\te.Right = p.visitExpr(e.Right)\n\t}\n\tp.fnOnlyDataVisit.silenceMessageAboutThisBeingUndefined = v.oldSilenceWarningAboutThisBeingUndefined\n\n\t// Always put constants consistently on the same side for equality\n\t// comparisons to help improve compression. In theory, dictionary-based\n\t// compression methods may already have a dictionary entry for code that\n\t// is similar to previous code. Note that we can only reorder expressions\n\t// that do not have any side effects.\n\t//\n\t// Constants are currently ordered on the right instead of the left because\n\t// it results in slightly smalller gzip size on our primary benchmark\n\t// (although slightly larger uncompressed size). The size difference is\n\t// less than 0.1% so it really isn't that important an optimization.\n\tif p.options.minifySyntax {\n\t\tswitch e.Op {\n\t\tcase js_ast.BinOpLooseEq, js_ast.BinOpLooseNe, js_ast.BinOpStrictEq, js_ast.BinOpStrictNe:\n\t\t\t// \"1 === x\" => \"x === 1\"\n\t\t\tif js_ast.IsPrimitiveLiteral(e.Left.Data) && !js_ast.IsPrimitiveLiteral(e.Right.Data) {\n\t\t\t\te.Left, e.Right = e.Right, e.Left\n\t\t\t}\n\t\t}\n\t}\n\n\tif p.shouldFoldTypeScriptConstantExpressions || (p.options.minifySyntax && js_ast.ShouldFoldBinaryOperatorWhenMinifying(e)) {\n\t\tif result := js_ast.FoldBinaryOperator(v.loc, e); result.Data != nil {\n\t\t\treturn result\n\t\t}\n\t}\n\n\t// Post-process the binary expression\n\tswitch e.Op {\n\tcase js_ast.BinOpComma:\n\t\t// \"(1, 2)\" => \"2\"\n\t\t// \"(sideEffects(), 2)\" => \"(sideEffects(), 2)\"\n\t\tif p.options.minifySyntax {\n\t\t\te.Left = p.astHelpers.SimplifyUnusedExpr(e.Left, p.options.unsupportedJSFeatures)\n\t\t\tif e.Left.Data == nil {\n\t\t\t\treturn e.Right\n\t\t\t}\n\t\t}\n\n\tcase js_ast.BinOpLooseEq:\n\t\tif result, ok := js_ast.CheckEqualityIfNoSideEffects(e.Left.Data, e.Right.Data, js_ast.LooseEquality); ok {\n\t\t\treturn js_ast.Expr{Loc: v.loc, Data: &js_ast.EBoolean{Value: result}}\n\t\t}\n\t\tafterOpLoc := locAfterOp(e)\n\t\tif !p.warnAboutEqualityCheck(\"==\", e.Left, afterOpLoc) {\n\t\t\tp.warnAboutEqualityCheck(\"==\", e.Right, afterOpLoc)\n\t\t}\n\t\tp.warnAboutTypeofAndString(e.Left, e.Right, checkBothOrders)\n\n\t\tif p.options.minifySyntax {\n\t\t\t// \"x == void 0\" => \"x == null\"\n\t\t\tif _, ok := e.Left.Data.(*js_ast.EUndefined); ok {\n\t\t\t\te.Left.Data = js_ast.ENullShared\n\t\t\t} else if _, ok := e.Right.Data.(*js_ast.EUndefined); ok {\n\t\t\t\te.Right.Data = js_ast.ENullShared\n\t\t\t}\n\n\t\t\tif result, ok := js_ast.MaybeSimplifyEqualityComparison(v.loc, e, p.options.unsupportedJSFeatures); ok {\n\t\t\t\treturn result\n\t\t\t}\n\t\t}\n\n\tcase js_ast.BinOpStrictEq:\n\t\tif result, ok := js_ast.CheckEqualityIfNoSideEffects(e.Left.Data, e.Right.Data, js_ast.StrictEquality); ok {\n\t\t\treturn js_ast.Expr{Loc: v.loc, Data: &js_ast.EBoolean{Value: result}}\n\t\t}\n\t\tafterOpLoc := locAfterOp(e)\n\t\tif !p.warnAboutEqualityCheck(\"===\", e.Left, afterOpLoc) {\n\t\t\tp.warnAboutEqualityCheck(\"===\", e.Right, afterOpLoc)\n\t\t}\n\t\tp.warnAboutTypeofAndString(e.Left, e.Right, checkBothOrders)\n\n\t\tif p.options.minifySyntax {\n\t\t\t// \"typeof x === 'undefined'\" => \"typeof x == 'undefined'\"\n\t\t\tif js_ast.CanChangeStrictToLoose(e.Left, e.Right) {\n\t\t\t\te.Op = js_ast.BinOpLooseEq\n\t\t\t}\n\n\t\t\tif result, ok := js_ast.MaybeSimplifyEqualityComparison(v.loc, e, p.options.unsupportedJSFeatures); ok {\n\t\t\t\treturn result\n\t\t\t}\n\t\t}\n\n\tcase js_ast.BinOpLooseNe:\n\t\tif result, ok := js_ast.CheckEqualityIfNoSideEffects(e.Left.Data, e.Right.Data, js_ast.LooseEquality); ok {\n\t\t\treturn js_ast.Expr{Loc: v.loc, Data: &js_ast.EBoolean{Value: !result}}\n\t\t}\n\t\tafterOpLoc := locAfterOp(e)\n\t\tif !p.warnAboutEqualityCheck(\"!=\", e.Left, afterOpLoc) {\n\t\t\tp.warnAboutEqualityCheck(\"!=\", e.Right, afterOpLoc)\n\t\t}\n\t\tp.warnAboutTypeofAndString(e.Left, e.Right, checkBothOrders)\n\n\t\tif p.options.minifySyntax {\n\t\t\t// \"x != void 0\" => \"x != null\"\n\t\t\tif _, ok := e.Left.Data.(*js_ast.EUndefined); ok {\n\t\t\t\te.Left.Data = js_ast.ENullShared\n\t\t\t} else if _, ok := e.Right.Data.(*js_ast.EUndefined); ok {\n\t\t\t\te.Right.Data = js_ast.ENullShared\n\t\t\t}\n\n\t\t\tif result, ok := js_ast.MaybeSimplifyEqualityComparison(v.loc, e, p.options.unsupportedJSFeatures); ok {\n\t\t\t\treturn result\n\t\t\t}\n\t\t}\n\n\tcase js_ast.BinOpStrictNe:\n\t\tif result, ok := js_ast.CheckEqualityIfNoSideEffects(e.Left.Data, e.Right.Data, js_ast.StrictEquality); ok {\n\t\t\treturn js_ast.Expr{Loc: v.loc, Data: &js_ast.EBoolean{Value: !result}}\n\t\t}\n\t\tafterOpLoc := locAfterOp(e)\n\t\tif !p.warnAboutEqualityCheck(\"!==\", e.Left, afterOpLoc) {\n\t\t\tp.warnAboutEqualityCheck(\"!==\", e.Right, afterOpLoc)\n\t\t}\n\t\tp.warnAboutTypeofAndString(e.Left, e.Right, checkBothOrders)\n\n\t\tif p.options.minifySyntax {\n\t\t\t// \"typeof x !== 'undefined'\" => \"typeof x != 'undefined'\"\n\t\t\tif js_ast.CanChangeStrictToLoose(e.Left, e.Right) {\n\t\t\t\te.Op = js_ast.BinOpLooseNe\n\t\t\t}\n\n\t\t\tif result, ok := js_ast.MaybeSimplifyEqualityComparison(v.loc, e, p.options.unsupportedJSFeatures); ok {\n\t\t\t\treturn result\n\t\t\t}\n\t\t}\n\n\tcase js_ast.BinOpNullishCoalescing:\n\t\tif isNullOrUndefined, sideEffects, ok := js_ast.ToNullOrUndefinedWithSideEffects(e.Left.Data); ok {\n\t\t\t// Warn about potential bugs\n\t\t\tif !js_ast.IsPrimitiveLiteral(e.Left.Data) {\n\t\t\t\t// \"return props.flag === flag ?? true\" is \"return (props.flag === flag) ?? true\" not \"return props.flag === (flag ?? true)\"\n\t\t\t\tvar which string\n\t\t\t\tvar leftIsNullOrUndefined string\n\t\t\t\tvar leftIsReturned string\n\t\t\t\tif !isNullOrUndefined {\n\t\t\t\t\twhich = \"left\"\n\t\t\t\t\tleftIsNullOrUndefined = \"never\"\n\t\t\t\t\tleftIsReturned = \"always\"\n\t\t\t\t} else {\n\t\t\t\t\twhich = \"right\"\n\t\t\t\t\tleftIsNullOrUndefined = \"always\"\n\t\t\t\t\tleftIsReturned = \"never\"\n\t\t\t\t}\n\t\t\t\tkind := logger.Warning\n\t\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\t\tkind = logger.Debug\n\t\t\t\t}\n\t\t\t\trOp := p.source.RangeOfOperatorBefore(e.Right.Loc, \"??\")\n\t\t\t\trLeft := logger.Range{Loc: e.Left.Loc, Len: p.source.LocBeforeWhitespace(rOp.Loc).Start - e.Left.Loc.Start}\n\t\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_SuspiciousNullishCoalescing, kind, &p.tracker, rOp,\n\t\t\t\t\tfmt.Sprintf(\"The \\\"??\\\" operator here will always return the %s operand\", which), []logger.MsgData{\n\t\t\t\t\t\tp.tracker.MsgData(rLeft, fmt.Sprintf(\n\t\t\t\t\t\t\t\"The left operand of the \\\"??\\\" operator here will %s be null or undefined, so it will %s be returned. This usually indicates a bug in your code:\",\n\t\t\t\t\t\t\tleftIsNullOrUndefined, leftIsReturned))})\n\t\t\t}\n\n\t\t\tif !isNullOrUndefined {\n\t\t\t\treturn e.Left\n\t\t\t} else if sideEffects == js_ast.NoSideEffects {\n\t\t\t\treturn e.Right\n\t\t\t}\n\t\t}\n\n\t\tif p.options.minifySyntax {\n\t\t\t// \"a ?? (b ?? c)\" => \"a ?? b ?? c\"\n\t\t\tif right, ok := e.Right.Data.(*js_ast.EBinary); ok && right.Op == js_ast.BinOpNullishCoalescing {\n\t\t\t\te.Left = js_ast.JoinWithLeftAssociativeOp(js_ast.BinOpNullishCoalescing, e.Left, right.Left)\n\t\t\t\te.Right = right.Right\n\t\t\t}\n\t\t}\n\n\t\tif p.options.unsupportedJSFeatures.Has(compat.NullishCoalescing) {\n\t\t\treturn p.lowerNullishCoalescing(v.loc, e.Left, e.Right)\n\t\t}\n\n\tcase js_ast.BinOpLogicalOr:\n\t\tif boolean, sideEffects, ok := js_ast.ToBooleanWithSideEffects(e.Left.Data); ok {\n\t\t\t// Warn about potential bugs\n\t\t\tif e == p.suspiciousLogicalOperatorInsideArrow {\n\t\t\t\tif arrowLoc := p.source.RangeOfOperatorBefore(v.loc, \"=>\"); arrowLoc.Loc.Start+2 == p.source.LocBeforeWhitespace(v.loc).Start {\n\t\t\t\t\t// \"return foo => 1 || foo <= 0\"\n\t\t\t\t\tvar which string\n\t\t\t\t\tif boolean {\n\t\t\t\t\t\twhich = \"left\"\n\t\t\t\t\t} else {\n\t\t\t\t\t\twhich = \"right\"\n\t\t\t\t\t}\n\t\t\t\t\tkind := logger.Warning\n\t\t\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\t\t\tkind = logger.Debug\n\t\t\t\t\t}\n\t\t\t\t\tnote := p.tracker.MsgData(arrowLoc,\n\t\t\t\t\t\t\"The \\\"=>\\\" symbol creates an arrow function expression in JavaScript. Did you mean to use the greater-than-or-equal-to operator \\\">=\\\" here instead?\")\n\t\t\t\t\tnote.Location.Suggestion = \">=\"\n\t\t\t\t\trOp := p.source.RangeOfOperatorBefore(e.Right.Loc, \"||\")\n\t\t\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_SuspiciousLogicalOperator, kind, &p.tracker, rOp,\n\t\t\t\t\t\tfmt.Sprintf(\"The \\\"||\\\" operator here will always return the %s operand\", which), []logger.MsgData{note})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif boolean {\n\t\t\t\treturn e.Left\n\t\t\t} else if sideEffects == js_ast.NoSideEffects {\n\t\t\t\treturn e.Right\n\t\t\t}\n\t\t}\n\n\t\tif p.options.minifySyntax {\n\t\t\t// \"a || (b || c)\" => \"a || b || c\"\n\t\t\tif right, ok := e.Right.Data.(*js_ast.EBinary); ok && right.Op == js_ast.BinOpLogicalOr {\n\t\t\t\te.Left = js_ast.JoinWithLeftAssociativeOp(js_ast.BinOpLogicalOr, e.Left, right.Left)\n\t\t\t\te.Right = right.Right\n\t\t\t}\n\n\t\t\t// \"a === null || a === undefined\" => \"a == null\"\n\t\t\tif left, right, ok := js_ast.IsBinaryNullAndUndefined(e.Left, e.Right, js_ast.BinOpStrictEq); ok {\n\t\t\t\te.Op = js_ast.BinOpLooseEq\n\t\t\t\te.Left = left\n\t\t\t\te.Right = right\n\t\t\t}\n\t\t}\n\n\tcase js_ast.BinOpLogicalAnd:\n\t\tif boolean, sideEffects, ok := js_ast.ToBooleanWithSideEffects(e.Left.Data); ok {\n\t\t\t// Warn about potential bugs\n\t\t\tif e == p.suspiciousLogicalOperatorInsideArrow {\n\t\t\t\tif arrowLoc := p.source.RangeOfOperatorBefore(v.loc, \"=>\"); arrowLoc.Loc.Start+2 == p.source.LocBeforeWhitespace(v.loc).Start {\n\t\t\t\t\t// \"return foo => 0 && foo <= 1\"\n\t\t\t\t\tvar which string\n\t\t\t\t\tif !boolean {\n\t\t\t\t\t\twhich = \"left\"\n\t\t\t\t\t} else {\n\t\t\t\t\t\twhich = \"right\"\n\t\t\t\t\t}\n\t\t\t\t\tkind := logger.Warning\n\t\t\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\t\t\tkind = logger.Debug\n\t\t\t\t\t}\n\t\t\t\t\tnote := p.tracker.MsgData(arrowLoc,\n\t\t\t\t\t\t\"The \\\"=>\\\" symbol creates an arrow function expression in JavaScript. Did you mean to use the greater-than-or-equal-to operator \\\">=\\\" here instead?\")\n\t\t\t\t\tnote.Location.Suggestion = \">=\"\n\t\t\t\t\trOp := p.source.RangeOfOperatorBefore(e.Right.Loc, \"&&\")\n\t\t\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_SuspiciousLogicalOperator, kind, &p.tracker, rOp,\n\t\t\t\t\t\tfmt.Sprintf(\"The \\\"&&\\\" operator here will always return the %s operand\", which), []logger.MsgData{note})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !boolean {\n\t\t\t\treturn e.Left\n\t\t\t} else if sideEffects == js_ast.NoSideEffects {\n\t\t\t\treturn e.Right\n\t\t\t}\n\t\t}\n\n\t\tif p.options.minifySyntax {\n\t\t\t// \"a && (b && c)\" => \"a && b && c\"\n\t\t\tif right, ok := e.Right.Data.(*js_ast.EBinary); ok && right.Op == js_ast.BinOpLogicalAnd {\n\t\t\t\te.Left = js_ast.JoinWithLeftAssociativeOp(js_ast.BinOpLogicalAnd, e.Left, right.Left)\n\t\t\t\te.Right = right.Right\n\t\t\t}\n\n\t\t\t// \"a !== null && a !== undefined\" => \"a != null\"\n\t\t\tif left, right, ok := js_ast.IsBinaryNullAndUndefined(e.Left, e.Right, js_ast.BinOpStrictNe); ok {\n\t\t\t\te.Op = js_ast.BinOpLooseNe\n\t\t\t\te.Left = left\n\t\t\t\te.Right = right\n\t\t\t}\n\t\t}\n\n\tcase js_ast.BinOpAdd:\n\t\t// \"'abc' + 'xyz'\" => \"'abcxyz'\"\n\t\tif result := js_ast.FoldStringAddition(e.Left, e.Right, js_ast.StringAdditionNormal); result.Data != nil {\n\t\t\treturn result\n\t\t}\n\n\t\tif left, ok := e.Left.Data.(*js_ast.EBinary); ok && left.Op == js_ast.BinOpAdd {\n\t\t\t// \"x + 'abc' + 'xyz'\" => \"x + 'abcxyz'\"\n\t\t\tif result := js_ast.FoldStringAddition(left.Right, e.Right, js_ast.StringAdditionWithNestedLeft); result.Data != nil {\n\t\t\t\treturn js_ast.Expr{Loc: v.loc, Data: &js_ast.EBinary{Op: left.Op, Left: left.Left, Right: result}}\n\t\t\t}\n\t\t}\n\n\tcase js_ast.BinOpPow:\n\t\t// Lower the exponentiation operator for browsers that don't support it\n\t\tif p.options.unsupportedJSFeatures.Has(compat.ExponentOperator) {\n\t\t\treturn p.callRuntime(v.loc, \"__pow\", []js_ast.Expr{e.Left, e.Right})\n\t\t}\n\n\t\t////////////////////////////////////////////////////////////////////////////////\n\t\t// All assignment operators below here\n\n\tcase js_ast.BinOpAssign:\n\t\tif target, loc, private := p.extractPrivateIndex(e.Left); private != nil {\n\t\t\treturn p.lowerPrivateSet(target, loc, private, e.Right)\n\t\t}\n\n\t\tif property := p.extractSuperProperty(e.Left); property.Data != nil {\n\t\t\treturn p.lowerSuperPropertySet(e.Left.Loc, property, e.Right)\n\t\t}\n\n\t\t// Lower assignment destructuring patterns for browsers that don't\n\t\t// support them. Note that assignment expressions are used to represent\n\t\t// initializers in binding patterns, so only do this if we're not\n\t\t// ourselves the target of an assignment. Example: \"[a = b] = c\"\n\t\tif v.in.assignTarget == js_ast.AssignTargetNone {\n\t\t\tmode := objRestMustReturnInitExpr\n\t\t\tif v.isStmtExpr {\n\t\t\t\tmode = objRestReturnValueIsUnused\n\t\t\t}\n\t\t\tif result, ok := p.lowerAssign(e.Left, e.Right, mode); ok {\n\t\t\t\treturn result\n\t\t\t}\n\n\t\t\t// If CommonJS-style exports are disabled, then references to them are\n\t\t\t// treated as global variable references. This is consistent with how\n\t\t\t// they work in node and the browser, so it's the correct interpretation.\n\t\t\t//\n\t\t\t// However, people sometimes try to use both types of exports within the\n\t\t\t// same module and expect it to work. We warn about this when module\n\t\t\t// format conversion is enabled.\n\t\t\t//\n\t\t\t// Only warn about this for uses in assignment position since there are\n\t\t\t// some legitimate other uses. For example, some people do \"typeof module\"\n\t\t\t// to check for a CommonJS environment, and we shouldn't warn on that.\n\t\t\tif p.options.mode != config.ModePassThrough && p.isFileConsideredToHaveESMExports && !p.isControlFlowDead {\n\t\t\t\tif dot, ok := e.Left.Data.(*js_ast.EDot); ok {\n\t\t\t\t\tvar name string\n\t\t\t\t\tvar loc logger.Loc\n\n\t\t\t\t\tswitch target := dot.Target.Data.(type) {\n\t\t\t\t\tcase *js_ast.EIdentifier:\n\t\t\t\t\t\tif symbol := &p.symbols[target.Ref.InnerIndex]; symbol.Kind == ast.SymbolUnbound &&\n\t\t\t\t\t\t\t((symbol.OriginalName == \"module\" && dot.Name == \"exports\") || symbol.OriginalName == \"exports\") &&\n\t\t\t\t\t\t\t!symbol.Flags.Has(ast.DidWarnAboutCommonJSInESM) {\n\t\t\t\t\t\t\t// \"module.exports = ...\"\n\t\t\t\t\t\t\t// \"exports.something = ...\"\n\t\t\t\t\t\t\tname = symbol.OriginalName\n\t\t\t\t\t\t\tloc = dot.Target.Loc\n\t\t\t\t\t\t\tsymbol.Flags |= ast.DidWarnAboutCommonJSInESM\n\t\t\t\t\t\t}\n\n\t\t\t\t\tcase *js_ast.EDot:\n\t\t\t\t\t\tif target.Name == \"exports\" {\n\t\t\t\t\t\t\tif id, ok := target.Target.Data.(*js_ast.EIdentifier); ok {\n\t\t\t\t\t\t\t\tif symbol := &p.symbols[id.Ref.InnerIndex]; symbol.Kind == ast.SymbolUnbound &&\n\t\t\t\t\t\t\t\t\tsymbol.OriginalName == \"module\" && !symbol.Flags.Has(ast.DidWarnAboutCommonJSInESM) {\n\t\t\t\t\t\t\t\t\t// \"module.exports.foo = ...\"\n\t\t\t\t\t\t\t\t\tname = symbol.OriginalName\n\t\t\t\t\t\t\t\t\tloc = target.Target.Loc\n\t\t\t\t\t\t\t\t\tsymbol.Flags |= ast.DidWarnAboutCommonJSInESM\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif name != \"\" {\n\t\t\t\t\t\tkind := logger.Warning\n\t\t\t\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\t\t\t\tkind = logger.Debug\n\t\t\t\t\t\t}\n\t\t\t\t\t\twhy, notes := p.whyESModule()\n\t\t\t\t\t\tif why == whyESMTypeModulePackageJSON {\n\t\t\t\t\t\t\ttext := \"Node's package format requires that CommonJS files in a \\\"type\\\": \\\"module\\\" package use the \\\".cjs\\\" file extension.\"\n\t\t\t\t\t\t\tif p.options.ts.Parse {\n\t\t\t\t\t\t\t\ttext += \" If you are using TypeScript, you can use the \\\".cts\\\" file extension with esbuild instead.\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnotes = append(notes, logger.MsgData{Text: text})\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_CommonJSVariableInESM, kind, &p.tracker, js_lexer.RangeOfIdentifier(p.source, loc),\n\t\t\t\t\t\t\tfmt.Sprintf(\"The CommonJS %q variable is treated as a global variable in an ECMAScript module and may not work as expected\", name),\n\t\t\t\t\t\t\tnotes)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\tcase js_ast.BinOpAddAssign:\n\t\tif result := p.maybeLowerSetBinOp(e.Left, js_ast.BinOpAdd, e.Right); result.Data != nil {\n\t\t\treturn result\n\t\t}\n\n\tcase js_ast.BinOpSubAssign:\n\t\tif result := p.maybeLowerSetBinOp(e.Left, js_ast.BinOpSub, e.Right); result.Data != nil {\n\t\t\treturn result\n\t\t}\n\n\tcase js_ast.BinOpMulAssign:\n\t\tif result := p.maybeLowerSetBinOp(e.Left, js_ast.BinOpMul, e.Right); result.Data != nil {\n\t\t\treturn result\n\t\t}\n\n\tcase js_ast.BinOpDivAssign:\n\t\tif result := p.maybeLowerSetBinOp(e.Left, js_ast.BinOpDiv, e.Right); result.Data != nil {\n\t\t\treturn result\n\t\t}\n\n\tcase js_ast.BinOpRemAssign:\n\t\tif result := p.maybeLowerSetBinOp(e.Left, js_ast.BinOpRem, e.Right); result.Data != nil {\n\t\t\treturn result\n\t\t}\n\n\tcase js_ast.BinOpPowAssign:\n\t\t// Lower the exponentiation operator for browsers that don't support it\n\t\tif p.options.unsupportedJSFeatures.Has(compat.ExponentOperator) {\n\t\t\treturn p.lowerExponentiationAssignmentOperator(v.loc, e)\n\t\t}\n\n\t\tif result := p.maybeLowerSetBinOp(e.Left, js_ast.BinOpPow, e.Right); result.Data != nil {\n\t\t\treturn result\n\t\t}\n\n\tcase js_ast.BinOpShlAssign:\n\t\tif result := p.maybeLowerSetBinOp(e.Left, js_ast.BinOpShl, e.Right); result.Data != nil {\n\t\t\treturn result\n\t\t}\n\n\tcase js_ast.BinOpShrAssign:\n\t\tif result := p.maybeLowerSetBinOp(e.Left, js_ast.BinOpShr, e.Right); result.Data != nil {\n\t\t\treturn result\n\t\t}\n\n\tcase js_ast.BinOpUShrAssign:\n\t\tif result := p.maybeLowerSetBinOp(e.Left, js_ast.BinOpUShr, e.Right); result.Data != nil {\n\t\t\treturn result\n\t\t}\n\n\tcase js_ast.BinOpBitwiseOrAssign:\n\t\tif result := p.maybeLowerSetBinOp(e.Left, js_ast.BinOpBitwiseOr, e.Right); result.Data != nil {\n\t\t\treturn result\n\t\t}\n\n\tcase js_ast.BinOpBitwiseAndAssign:\n\t\tif result := p.maybeLowerSetBinOp(e.Left, js_ast.BinOpBitwiseAnd, e.Right); result.Data != nil {\n\t\t\treturn result\n\t\t}\n\n\tcase js_ast.BinOpBitwiseXorAssign:\n\t\tif result := p.maybeLowerSetBinOp(e.Left, js_ast.BinOpBitwiseXor, e.Right); result.Data != nil {\n\t\t\treturn result\n\t\t}\n\n\tcase js_ast.BinOpNullishCoalescingAssign:\n\t\tif value, ok := p.lowerNullishCoalescingAssignmentOperator(v.loc, e); ok {\n\t\t\treturn value\n\t\t}\n\n\tcase js_ast.BinOpLogicalAndAssign:\n\t\tif value, ok := p.lowerLogicalAssignmentOperator(v.loc, e, js_ast.BinOpLogicalAnd); ok {\n\t\t\treturn value\n\t\t}\n\n\tcase js_ast.BinOpLogicalOrAssign:\n\t\tif value, ok := p.lowerLogicalAssignmentOperator(v.loc, e, js_ast.BinOpLogicalOr); ok {\n\t\t\treturn value\n\t\t}\n\t}\n\n\t// \"(a, b) + c\" => \"a, b + c\"\n\tif p.options.minifySyntax && e.Op != js_ast.BinOpComma {\n\t\tif comma, ok := e.Left.Data.(*js_ast.EBinary); ok && comma.Op == js_ast.BinOpComma {\n\t\t\treturn js_ast.JoinWithComma(comma.Left, js_ast.Expr{\n\t\t\t\tLoc: comma.Right.Loc,\n\t\t\t\tData: &js_ast.EBinary{\n\t\t\t\t\tOp:    e.Op,\n\t\t\t\t\tLeft:  comma.Right,\n\t\t\t\t\tRight: e.Right,\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t}\n\n\treturn js_ast.Expr{Loc: v.loc, Data: e}\n}\n\nfunc remapExprLocsInJSON(expr *js_ast.Expr, table []logger.StringInJSTableEntry) {\n\texpr.Loc = logger.RemapStringInJSLoc(table, expr.Loc)\n\n\tswitch e := expr.Data.(type) {\n\tcase *js_ast.EArray:\n\t\te.CloseBracketLoc = logger.RemapStringInJSLoc(table, e.CloseBracketLoc)\n\t\tfor i := range e.Items {\n\t\t\tremapExprLocsInJSON(&e.Items[i], table)\n\t\t}\n\n\tcase *js_ast.EObject:\n\t\te.CloseBraceLoc = logger.RemapStringInJSLoc(table, e.CloseBraceLoc)\n\t\tfor i := range e.Properties {\n\t\t\tremapExprLocsInJSON(&e.Properties[i].Key, table)\n\t\t\tremapExprLocsInJSON(&e.Properties[i].ValueOrNil, table)\n\t\t}\n\t}\n}\n\nfunc (p *parser) handleGlobPattern(expr js_ast.Expr, kind ast.ImportKind, phase ast.ImportPhase, prefix string, assertOrWith *ast.ImportAssertOrWith) js_ast.Expr {\n\tpattern, approximateRange := p.globPatternFromExpr(expr)\n\tif pattern == nil {\n\t\treturn js_ast.Expr{}\n\t}\n\n\tvar last helpers.GlobPart\n\tvar parts []helpers.GlobPart\n\n\tfor _, part := range pattern {\n\t\tif part.isWildcard {\n\t\t\tif last.Wildcard == helpers.GlobNone {\n\t\t\t\tif !strings.HasSuffix(last.Prefix, \"/\") {\n\t\t\t\t\t// \"`a${b}c`\" => \"a*c\"\n\t\t\t\t\tlast.Wildcard = helpers.GlobAllExceptSlash\n\t\t\t\t} else {\n\t\t\t\t\t// \"`a/${b}c`\" => \"a/**/*c\"\n\t\t\t\t\tlast.Wildcard = helpers.GlobAllIncludingSlash\n\t\t\t\t\tparts = append(parts, last)\n\t\t\t\t\tlast = helpers.GlobPart{Prefix: \"/\", Wildcard: helpers.GlobAllExceptSlash}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if part.text != \"\" {\n\t\t\tif last.Wildcard != helpers.GlobNone {\n\t\t\t\tparts = append(parts, last)\n\t\t\t\tlast = helpers.GlobPart{}\n\t\t\t}\n\t\t\tlast.Prefix += part.text\n\t\t}\n\t}\n\n\tparts = append(parts, last)\n\n\t// Don't handle this if it's a string constant\n\tif len(parts) == 1 && parts[0].Wildcard == helpers.GlobNone {\n\t\treturn js_ast.Expr{}\n\t}\n\n\t// We currently only support relative globs\n\tif prefix := parts[0].Prefix; !strings.HasPrefix(prefix, \"./\") && !strings.HasPrefix(prefix, \"../\") {\n\t\treturn js_ast.Expr{}\n\t}\n\n\tref := ast.InvalidRef\n\n\t// Don't generate duplicate glob imports\nouter:\n\tfor _, globPattern := range p.globPatternImports {\n\t\t// Check the kind and phase\n\t\tif globPattern.kind != kind || globPattern.phase != phase {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Check the parts\n\t\tif len(globPattern.parts) != len(parts) {\n\t\t\tcontinue\n\t\t}\n\t\tfor i := range parts {\n\t\t\tif globPattern.parts[i] != parts[i] {\n\t\t\t\tcontinue outer\n\t\t\t}\n\t\t}\n\n\t\t// Check the import assertions/attributes\n\t\tif assertOrWith == nil {\n\t\t\tif globPattern.assertOrWith != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t} else {\n\t\t\tif globPattern.assertOrWith == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif assertOrWith.Keyword != globPattern.assertOrWith.Keyword {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ta := assertOrWith.Entries\n\t\t\tb := globPattern.assertOrWith.Entries\n\t\t\tif len(a) != len(b) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfor i := range a {\n\t\t\t\tai := a[i]\n\t\t\t\tbi := b[i]\n\t\t\t\tif !helpers.UTF16EqualsUTF16(ai.Key, bi.Key) || !helpers.UTF16EqualsUTF16(ai.Value, bi.Value) {\n\t\t\t\t\tcontinue outer\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we get here, then these are the same glob pattern\n\t\tref = globPattern.ref\n\t\tbreak\n\t}\n\n\t// If there's no duplicate glob import, then generate a new glob import\n\tif ref == ast.InvalidRef && prefix != \"\" {\n\t\tsb := strings.Builder{}\n\t\tsb.WriteString(prefix)\n\n\t\tfor _, part := range parts {\n\t\t\tgap := true\n\t\t\tfor _, c := range part.Prefix {\n\t\t\t\tif !js_ast.IsIdentifierContinue(c) {\n\t\t\t\t\tgap = true\n\t\t\t\t} else {\n\t\t\t\t\tif gap {\n\t\t\t\t\t\tsb.WriteByte('_')\n\t\t\t\t\t\tgap = false\n\t\t\t\t\t}\n\t\t\t\t\tsb.WriteRune(c)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tname := sb.String()\n\t\tref = p.newSymbol(ast.SymbolOther, name)\n\t\tp.moduleScope.Generated = append(p.moduleScope.Generated, ref)\n\n\t\tp.globPatternImports = append(p.globPatternImports, globPatternImport{\n\t\t\tassertOrWith:     assertOrWith,\n\t\t\tparts:            parts,\n\t\t\tname:             name,\n\t\t\tapproximateRange: approximateRange,\n\t\t\tref:              ref,\n\t\t\tkind:             kind,\n\t\t\tphase:            phase,\n\t\t})\n\t}\n\n\tp.recordUsage(ref)\n\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ECall{\n\t\tTarget: js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EIdentifier{Ref: ref}},\n\t\tArgs:   []js_ast.Expr{expr},\n\t}}\n}\n\ntype globPart struct {\n\ttext       string\n\tisWildcard bool\n}\n\nfunc (p *parser) globPatternFromExpr(expr js_ast.Expr) ([]globPart, logger.Range) {\n\tswitch e := expr.Data.(type) {\n\tcase *js_ast.EString:\n\t\treturn []globPart{{text: helpers.UTF16ToString(e.Value)}}, p.source.RangeOfString(expr.Loc)\n\n\tcase *js_ast.ETemplate:\n\t\tif e.TagOrNil.Data != nil {\n\t\t\tbreak\n\t\t}\n\n\t\tpattern := make([]globPart, 0, 1+2*len(e.Parts))\n\t\tpattern = append(pattern, globPart{text: helpers.UTF16ToString(e.HeadCooked)})\n\n\t\tfor _, part := range e.Parts {\n\t\t\tif partPattern, _ := p.globPatternFromExpr(part.Value); partPattern != nil {\n\t\t\t\tpattern = append(pattern, partPattern...)\n\t\t\t} else {\n\t\t\t\tpattern = append(pattern, globPart{isWildcard: true})\n\t\t\t}\n\t\t\tpattern = append(pattern, globPart{text: helpers.UTF16ToString(part.TailCooked)})\n\t\t}\n\n\t\tif len(e.Parts) == 0 {\n\t\t\treturn pattern, p.source.RangeOfString(expr.Loc)\n\t\t}\n\n\t\ttext := p.source.Contents\n\t\ttemplateRange := logger.Range{Loc: e.HeadLoc}\n\n\t\tfor i := e.Parts[len(e.Parts)-1].TailLoc.Start; i < int32(len(text)); i++ {\n\t\t\tc := text[i]\n\t\t\tif c == '`' {\n\t\t\t\ttemplateRange.Len = i + 1 - templateRange.Loc.Start\n\t\t\t\tbreak\n\t\t\t} else if c == '\\\\' {\n\t\t\t\ti += 1\n\t\t\t}\n\t\t}\n\n\t\treturn pattern, templateRange\n\n\tcase *js_ast.EBinary:\n\t\tif e.Op != js_ast.BinOpAdd {\n\t\t\tbreak\n\t\t}\n\n\t\tpattern, leftRange := p.globPatternFromExpr(e.Left)\n\t\tif pattern == nil {\n\t\t\tbreak\n\t\t}\n\n\t\tif rightPattern, rightRange := p.globPatternFromExpr(e.Right); rightPattern != nil {\n\t\t\tpattern = append(pattern, rightPattern...)\n\t\t\tleftRange.Len = rightRange.End() - leftRange.Loc.Start\n\t\t\treturn pattern, leftRange\n\t\t}\n\n\t\tpattern = append(pattern, globPart{isWildcard: true})\n\n\t\t// Try to extend the left range by the right operand in some common cases\n\t\tswitch right := e.Right.Data.(type) {\n\t\tcase *js_ast.EIdentifier:\n\t\t\tleftRange.Len = js_lexer.RangeOfIdentifier(p.source, e.Right.Loc).End() - leftRange.Loc.Start\n\n\t\tcase *js_ast.ECall:\n\t\t\tif right.CloseParenLoc.Start > 0 {\n\t\t\t\tleftRange.Len = right.CloseParenLoc.Start + 1 - leftRange.Loc.Start\n\t\t\t}\n\t\t}\n\n\t\treturn pattern, leftRange\n\t}\n\n\treturn nil, logger.Range{}\n}\n\nfunc (p *parser) convertSymbolUseToCall(ref ast.Ref, isSingleNonSpreadArgCall bool) {\n\t// Remove the normal symbol use\n\tuse := p.symbolUses[ref]\n\tuse.CountEstimate--\n\tif use.CountEstimate == 0 {\n\t\tdelete(p.symbolUses, ref)\n\t} else {\n\t\tp.symbolUses[ref] = use\n\t}\n\n\t// Add a special symbol use instead\n\tif p.symbolCallUses == nil {\n\t\tp.symbolCallUses = make(map[ast.Ref]js_ast.SymbolCallUse)\n\t}\n\tcallUse := p.symbolCallUses[ref]\n\tcallUse.CallCountEstimate++\n\tif isSingleNonSpreadArgCall {\n\t\tcallUse.SingleArgNonSpreadCallCountEstimate++\n\t}\n\tp.symbolCallUses[ref] = callUse\n}\n\nfunc (p *parser) warnAboutImportNamespaceCall(target js_ast.Expr, kind importNamespaceCallKind) {\n\tif p.options.outputFormat != config.FormatPreserve {\n\t\tif id, ok := target.Data.(*js_ast.EIdentifier); ok && p.importItemsForNamespace[id.Ref].entries != nil {\n\t\t\tkey := importNamespaceCall{\n\t\t\t\tref:  id.Ref,\n\t\t\t\tkind: kind,\n\t\t\t}\n\t\t\tif p.importNamespaceCCMap == nil {\n\t\t\t\tp.importNamespaceCCMap = make(map[importNamespaceCall]bool)\n\t\t\t}\n\n\t\t\t// Don't log a warning for the same identifier more than once\n\t\t\tif _, ok := p.importNamespaceCCMap[key]; ok {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tp.importNamespaceCCMap[key] = true\n\t\t\tr := js_lexer.RangeOfIdentifier(p.source, target.Loc)\n\n\t\t\tvar notes []logger.MsgData\n\t\t\tname := p.symbols[id.Ref.InnerIndex].OriginalName\n\t\t\tif member, ok := p.moduleScope.Members[name]; ok && member.Ref == id.Ref {\n\t\t\t\tif star := p.source.RangeOfOperatorBefore(member.Loc, \"*\"); star.Len > 0 {\n\t\t\t\t\tif as := p.source.RangeOfOperatorBefore(member.Loc, \"as\"); as.Len > 0 && as.Loc.Start > star.Loc.Start {\n\t\t\t\t\t\tnote := p.tracker.MsgData(\n\t\t\t\t\t\t\tlogger.Range{Loc: star.Loc, Len: js_lexer.RangeOfIdentifier(p.source, member.Loc).End() - star.Loc.Start},\n\t\t\t\t\t\t\tfmt.Sprintf(\"Consider changing %q to a default import instead:\", name))\n\t\t\t\t\t\tnote.Location.Suggestion = name\n\t\t\t\t\t\tnotes = append(notes, note)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif p.options.ts.Parse {\n\t\t\t\tnotes = append(notes, logger.MsgData{\n\t\t\t\t\tText: \"Make sure to enable TypeScript's \\\"esModuleInterop\\\" setting so that TypeScript's type checker generates an error when you try to do this. \" +\n\t\t\t\t\t\t\"You can read more about this setting here: https://www.typescriptlang.org/tsconfig#esModuleInterop\",\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tvar verb string\n\t\t\tvar where string\n\t\t\tvar noun string\n\n\t\t\tswitch kind {\n\t\t\tcase exprKindCall:\n\t\t\t\tverb = \"Calling\"\n\t\t\t\tnoun = \"function\"\n\n\t\t\tcase exprKindNew:\n\t\t\t\tverb = \"Constructing\"\n\t\t\t\tnoun = \"constructor\"\n\n\t\t\tcase exprKindJSXTag:\n\t\t\t\tverb = \"Using\"\n\t\t\t\twhere = \" in a JSX expression\"\n\t\t\t\tnoun = \"component\"\n\t\t\t}\n\n\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_CallImportNamespace, logger.Warning, &p.tracker, r, fmt.Sprintf(\n\t\t\t\t\"%s %q%s will crash at run-time because it's an import namespace object, not a %s\",\n\t\t\t\tverb,\n\t\t\t\tp.symbols[id.Ref.InnerIndex].OriginalName,\n\t\t\t\twhere,\n\t\t\t\tnoun,\n\t\t\t), notes)\n\t\t}\n\t}\n}\n\nfunc (p *parser) maybeMarkKnownGlobalConstructorAsPure(e *js_ast.ENew) {\n\tif id, ok := e.Target.Data.(*js_ast.EIdentifier); ok {\n\t\tif symbol := p.symbols[id.Ref.InnerIndex]; symbol.Kind == ast.SymbolUnbound {\n\t\t\tswitch symbol.OriginalName {\n\t\t\tcase \"WeakSet\", \"WeakMap\":\n\t\t\t\tn := len(e.Args)\n\n\t\t\t\tif n == 0 {\n\t\t\t\t\t// \"new WeakSet()\" is pure\n\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tif n == 1 {\n\t\t\t\t\tswitch arg := e.Args[0].Data.(type) {\n\t\t\t\t\tcase *js_ast.ENull, *js_ast.EUndefined:\n\t\t\t\t\t\t// \"new WeakSet(null)\" is pure\n\t\t\t\t\t\t// \"new WeakSet(void 0)\" is pure\n\t\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\n\t\t\t\t\tcase *js_ast.EArray:\n\t\t\t\t\t\tif len(arg.Items) == 0 {\n\t\t\t\t\t\t\t// \"new WeakSet([])\" is pure\n\t\t\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// \"new WeakSet([x])\" is impure because an exception is thrown if \"x\" is not an object\n\t\t\t\t\t\t}\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// \"new WeakSet(x)\" is impure because the iterator for \"x\" could have side effects\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tcase \"Date\":\n\t\t\t\tn := len(e.Args)\n\n\t\t\t\tif n == 0 {\n\t\t\t\t\t// \"new Date()\" is pure\n\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tif n == 1 {\n\t\t\t\t\tswitch js_ast.KnownPrimitiveType(e.Args[0].Data) {\n\t\t\t\t\tcase js_ast.PrimitiveNull, js_ast.PrimitiveUndefined, js_ast.PrimitiveBoolean, js_ast.PrimitiveNumber, js_ast.PrimitiveString:\n\t\t\t\t\t\t// \"new Date('')\" is pure\n\t\t\t\t\t\t// \"new Date(0)\" is pure\n\t\t\t\t\t\t// \"new Date(null)\" is pure\n\t\t\t\t\t\t// \"new Date(true)\" is pure\n\t\t\t\t\t\t// \"new Date(false)\" is pure\n\t\t\t\t\t\t// \"new Date(undefined)\" is pure\n\t\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// \"new Date(x)\" is impure because converting \"x\" to a string could have side effects\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tcase \"Set\":\n\t\t\t\tn := len(e.Args)\n\n\t\t\t\tif n == 0 {\n\t\t\t\t\t// \"new Set()\" is pure\n\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tif n == 1 {\n\t\t\t\t\tswitch e.Args[0].Data.(type) {\n\t\t\t\t\tcase *js_ast.EArray, *js_ast.ENull, *js_ast.EUndefined:\n\t\t\t\t\t\t// \"new Set([a, b, c])\" is pure\n\t\t\t\t\t\t// \"new Set(null)\" is pure\n\t\t\t\t\t\t// \"new Set(void 0)\" is pure\n\t\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// \"new Set(x)\" is impure because the iterator for \"x\" could have side effects\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tcase \"Map\":\n\t\t\t\tn := len(e.Args)\n\n\t\t\t\tif n == 0 {\n\t\t\t\t\t// \"new Map()\" is pure\n\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tif n == 1 {\n\t\t\t\t\tswitch arg := e.Args[0].Data.(type) {\n\t\t\t\t\tcase *js_ast.ENull, *js_ast.EUndefined:\n\t\t\t\t\t\t// \"new Map(null)\" is pure\n\t\t\t\t\t\t// \"new Map(void 0)\" is pure\n\t\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\n\t\t\t\t\tcase *js_ast.EArray:\n\t\t\t\t\t\tallEntriesAreArrays := true\n\t\t\t\t\t\tfor _, item := range arg.Items {\n\t\t\t\t\t\t\tif _, ok := item.Data.(*js_ast.EArray); !ok {\n\t\t\t\t\t\t\t\t// \"new Map([x])\" is impure because \"x[0]\" could have side effects\n\t\t\t\t\t\t\t\tallEntriesAreArrays = false\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// \"new Map([[a, b], [c, d]])\" is pure\n\t\t\t\t\t\tif allEntriesAreArrays {\n\t\t\t\t\t\t\te.CanBeUnwrappedIfUnused = true\n\t\t\t\t\t\t}\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// \"new Map(x)\" is impure because the iterator for \"x\" could have side effects\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\ntype identifierOpts struct {\n\tassignTarget            js_ast.AssignTarget\n\tisCallTarget            bool\n\tisDeleteTarget          bool\n\tpreferQuotedKey         bool\n\twasOriginallyIdentifier bool\n\tmatchAgainstDefines     bool\n}\n\nfunc (p *parser) handleIdentifier(loc logger.Loc, e *js_ast.EIdentifier, opts identifierOpts) js_ast.Expr {\n\tref := e.Ref\n\n\t// Substitute inlined constants\n\tif p.options.minifySyntax && !p.currentScope.ContainsDirectEval {\n\t\tif value, ok := p.constValues[ref]; ok {\n\t\t\tp.ignoreUsage(ref)\n\t\t\treturn js_ast.ConstValueToExpr(loc, value)\n\t\t}\n\t}\n\n\t// Capture the \"arguments\" variable if necessary\n\tif p.fnOnlyDataVisit.argumentsRef != nil && ref == *p.fnOnlyDataVisit.argumentsRef {\n\t\tisInsideUnsupportedArrow := p.fnOrArrowDataVisit.isArrow && p.options.unsupportedJSFeatures.Has(compat.Arrow)\n\t\tisInsideUnsupportedAsyncArrow := p.fnOnlyDataVisit.isInsideAsyncArrowFn && p.options.unsupportedJSFeatures.Has(compat.AsyncAwait)\n\t\tif isInsideUnsupportedArrow || isInsideUnsupportedAsyncArrow {\n\t\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: p.captureArguments()}}\n\t\t}\n\t}\n\n\t// Create an error for assigning to an import namespace\n\tif (opts.assignTarget != js_ast.AssignTargetNone ||\n\t\t(opts.isDeleteTarget && p.symbols[ref.InnerIndex].ImportItemStatus == ast.ImportItemGenerated)) &&\n\t\tp.symbols[ref.InnerIndex].Kind == ast.SymbolImport {\n\t\tr := js_lexer.RangeOfIdentifier(p.source, loc)\n\n\t\t// Try to come up with a setter name to try to make this message more understandable\n\t\tvar setterHint string\n\t\toriginalName := p.symbols[ref.InnerIndex].OriginalName\n\t\tif js_ast.IsIdentifier(originalName) && originalName != \"_\" {\n\t\t\tif len(originalName) == 1 || (len(originalName) > 1 && originalName[0] < utf8.RuneSelf) {\n\t\t\t\tsetterHint = fmt.Sprintf(\" (e.g. \\\"set%s%s\\\")\", strings.ToUpper(originalName[:1]), originalName[1:])\n\t\t\t} else {\n\t\t\t\tsetterHint = fmt.Sprintf(\" (e.g. \\\"set_%s\\\")\", originalName)\n\t\t\t}\n\t\t}\n\n\t\tnotes := []logger.MsgData{{Text: \"Imports are immutable in JavaScript. \" +\n\t\t\tfmt.Sprintf(\"To modify the value of this import, you must export a setter function in the \"+\n\t\t\t\t\"imported file%s and then import and call that function here instead.\", setterHint)}}\n\n\t\tif p.options.mode == config.ModeBundle {\n\t\t\tp.log.AddErrorWithNotes(&p.tracker, r, fmt.Sprintf(\"Cannot assign to import %q\", originalName), notes)\n\t\t} else {\n\t\t\tkind := logger.Warning\n\t\t\tif p.suppressWarningsAboutWeirdCode {\n\t\t\t\tkind = logger.Debug\n\t\t\t}\n\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_AssignToImport, kind, &p.tracker, r,\n\t\t\t\tfmt.Sprintf(\"This assignment will throw because %q is an import\", originalName), notes)\n\t\t}\n\t}\n\n\t// Substitute an EImportIdentifier now if this has a namespace alias\n\tif opts.assignTarget == js_ast.AssignTargetNone && !opts.isDeleteTarget {\n\t\tsymbol := &p.symbols[ref.InnerIndex]\n\t\tif nsAlias := symbol.NamespaceAlias; nsAlias != nil {\n\t\t\tdata := p.dotOrMangledPropVisit(\n\t\t\t\tjs_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: nsAlias.NamespaceRef}},\n\t\t\t\tsymbol.OriginalName, loc)\n\n\t\t\t// Handle references to namespaces or namespace members\n\t\t\tif tsMemberData, ok := p.refToTSNamespaceMemberData[nsAlias.NamespaceRef]; ok {\n\t\t\t\tif ns, ok := tsMemberData.(*js_ast.TSNamespaceMemberNamespace); ok {\n\t\t\t\t\tif member, ok := ns.ExportedMembers[nsAlias.Alias]; ok {\n\t\t\t\t\t\tswitch m := member.Data.(type) {\n\t\t\t\t\t\tcase *js_ast.TSNamespaceMemberEnumNumber:\n\t\t\t\t\t\t\treturn p.wrapInlinedEnum(js_ast.Expr{Loc: loc, Data: &js_ast.ENumber{Value: m.Value}}, nsAlias.Alias)\n\n\t\t\t\t\t\tcase *js_ast.TSNamespaceMemberEnumString:\n\t\t\t\t\t\t\treturn p.wrapInlinedEnum(js_ast.Expr{Loc: loc, Data: &js_ast.EString{Value: m.Value}}, nsAlias.Alias)\n\n\t\t\t\t\t\tcase *js_ast.TSNamespaceMemberNamespace:\n\t\t\t\t\t\t\tp.tsNamespaceTarget = data\n\t\t\t\t\t\t\tp.tsNamespaceMemberData = member.Data\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn js_ast.Expr{Loc: loc, Data: data}\n\t\t}\n\t}\n\n\t// Substitute an EImportIdentifier now if this is an import item\n\tif p.isImportItem[ref] {\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EImportIdentifier{\n\t\t\tRef:                     ref,\n\t\t\tPreferQuotedKey:         opts.preferQuotedKey,\n\t\t\tWasOriginallyIdentifier: opts.wasOriginallyIdentifier,\n\t\t}}\n\t}\n\n\t// Handle references to namespaces or namespace members\n\tif tsMemberData, ok := p.refToTSNamespaceMemberData[ref]; ok {\n\t\tswitch m := tsMemberData.(type) {\n\t\tcase *js_ast.TSNamespaceMemberEnumNumber:\n\t\t\treturn p.wrapInlinedEnum(js_ast.Expr{Loc: loc, Data: &js_ast.ENumber{Value: m.Value}}, p.symbols[ref.InnerIndex].OriginalName)\n\n\t\tcase *js_ast.TSNamespaceMemberEnumString:\n\t\t\treturn p.wrapInlinedEnum(js_ast.Expr{Loc: loc, Data: &js_ast.EString{Value: m.Value}}, p.symbols[ref.InnerIndex].OriginalName)\n\n\t\tcase *js_ast.TSNamespaceMemberNamespace:\n\t\t\tp.tsNamespaceTarget = e\n\t\t\tp.tsNamespaceMemberData = tsMemberData\n\t\t}\n\t}\n\n\t// Substitute a namespace export reference now if appropriate\n\tif p.options.ts.Parse {\n\t\tif nsRef, ok := p.isExportedInsideNamespace[ref]; ok {\n\t\t\tname := p.symbols[ref.InnerIndex].OriginalName\n\n\t\t\t// Otherwise, create a property access on the namespace\n\t\t\tp.recordUsage(nsRef)\n\t\t\tpropertyAccess := p.dotOrMangledPropVisit(js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: nsRef}}, name, loc)\n\t\t\tif p.tsNamespaceTarget == e {\n\t\t\t\tp.tsNamespaceTarget = propertyAccess\n\t\t\t}\n\t\t\treturn js_ast.Expr{Loc: loc, Data: propertyAccess}\n\t\t}\n\t}\n\n\t// Swap references to the global \"require\" function with our \"__require\" stub\n\tif ref == p.requireRef && !opts.isCallTarget {\n\t\tif p.options.mode == config.ModeBundle && p.source.Index != runtime.SourceIndex && e != p.dotOrIndexTarget {\n\t\t\tp.log.AddID(logger.MsgID_JS_IndirectRequire, logger.Debug, &p.tracker, js_lexer.RangeOfIdentifier(p.source, loc),\n\t\t\t\t\"Indirect calls to \\\"require\\\" will not be bundled\")\n\t\t}\n\n\t\treturn p.valueToSubstituteForRequire(loc)\n\t}\n\n\t// Mark any mutated symbols as mutable\n\tif opts.assignTarget != js_ast.AssignTargetNone {\n\t\tp.symbols[e.Ref.InnerIndex].Flags |= ast.CouldPotentiallyBeMutated\n\t}\n\n\treturn js_ast.Expr{Loc: loc, Data: e}\n}\n\ntype visitFnOpts struct {\n\tisMethod               bool\n\tisDerivedClassCtor     bool\n\tisLoweredPrivateMethod bool\n}\n\nfunc (p *parser) visitFn(fn *js_ast.Fn, scopeLoc logger.Loc, opts visitFnOpts) {\n\tvar decoratorScope *js_ast.Scope\n\toldFnOrArrowData := p.fnOrArrowDataVisit\n\toldFnOnlyData := p.fnOnlyDataVisit\n\tp.fnOrArrowDataVisit = fnOrArrowDataVisit{\n\t\tisAsync:                        fn.IsAsync,\n\t\tisGenerator:                    fn.IsGenerator,\n\t\tisDerivedClassCtor:             opts.isDerivedClassCtor,\n\t\tshouldLowerSuperPropertyAccess: (fn.IsAsync && p.options.unsupportedJSFeatures.Has(compat.AsyncAwait)) || opts.isLoweredPrivateMethod,\n\t}\n\tp.fnOnlyDataVisit = fnOnlyDataVisit{\n\t\tisThisNested:       true,\n\t\tisNewTargetAllowed: true,\n\t\targumentsRef:       &fn.ArgumentsRef,\n\t}\n\n\tif opts.isMethod {\n\t\tdecoratorScope = p.propMethodDecoratorScope\n\t\tp.fnOnlyDataVisit.innerClassNameRef = oldFnOnlyData.innerClassNameRef\n\t\tp.fnOnlyDataVisit.isInStaticClassContext = oldFnOnlyData.isInStaticClassContext\n\t}\n\n\tif fn.Name != nil {\n\t\tp.recordDeclaredSymbol(fn.Name.Ref)\n\t}\n\n\tp.pushScopeForVisitPass(js_ast.ScopeFunctionArgs, scopeLoc)\n\tp.visitArgs(fn.Args, visitArgsOpts{\n\t\thasRestArg:               fn.HasRestArg,\n\t\tbody:                     fn.Body.Block.Stmts,\n\t\tisUniqueFormalParameters: fn.IsUniqueFormalParameters,\n\t\tdecoratorScope:           decoratorScope,\n\t})\n\tp.pushScopeForVisitPass(js_ast.ScopeFunctionBody, fn.Body.Loc)\n\tif fn.Name != nil {\n\t\tp.validateDeclaredSymbolName(fn.Name.Loc, p.symbols[fn.Name.Ref.InnerIndex].OriginalName)\n\t}\n\tfn.Body.Block.Stmts = p.visitStmtsAndPrependTempRefs(fn.Body.Block.Stmts, prependTempRefsOpts{fnBodyLoc: &fn.Body.Loc, kind: stmtsFnBody})\n\tp.popScope()\n\tp.lowerFunction(&fn.IsAsync, &fn.IsGenerator, &fn.Args, fn.Body.Loc, &fn.Body.Block, nil, &fn.HasRestArg, false /* isArrow */)\n\tp.popScope()\n\n\tp.fnOrArrowDataVisit = oldFnOrArrowData\n\tp.fnOnlyDataVisit = oldFnOnlyData\n}\n\nfunc (p *parser) recordExport(loc logger.Loc, alias string, ref ast.Ref) {\n\tif name, ok := p.namedExports[alias]; ok {\n\t\t// Duplicate exports are an error\n\t\tp.log.AddErrorWithNotes(&p.tracker, js_lexer.RangeOfIdentifier(p.source, loc),\n\t\t\tfmt.Sprintf(\"Multiple exports with the same name %q\", alias),\n\t\t\t[]logger.MsgData{p.tracker.MsgData(js_lexer.RangeOfIdentifier(p.source, name.AliasLoc),\n\t\t\t\tfmt.Sprintf(\"The name %q was originally exported here:\", alias))})\n\t} else {\n\t\tp.namedExports[alias] = js_ast.NamedExport{AliasLoc: loc, Ref: ref}\n\t}\n}\n\ntype importsExportsScanResult struct {\n\tstmts               []js_ast.Stmt\n\tkeptImportEquals    bool\n\tremovedImportEquals bool\n}\n\n// Returns true if this is an unused TypeScript import-equals statement\nfunc (p *parser) checkForUnusedTSImportEquals(s *js_ast.SLocal, result *importsExportsScanResult) bool {\n\tif s.WasTSImportEquals && !s.IsExport {\n\t\tdecl := s.Decls[0]\n\n\t\t// Skip to the underlying reference\n\t\tvalue := s.Decls[0].ValueOrNil\n\t\tfor {\n\t\t\tif dot, ok := value.Data.(*js_ast.EDot); ok {\n\t\t\t\tvalue = dot.Target\n\t\t\t} else {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Is this an identifier reference and not a require() call?\n\t\tvalueRef := ast.InvalidRef\n\t\tswitch v := value.Data.(type) {\n\t\tcase *js_ast.EIdentifier:\n\t\t\tvalueRef = v.Ref\n\t\tcase *js_ast.EImportIdentifier:\n\t\t\tvalueRef = v.Ref\n\t\t}\n\t\tif valueRef != ast.InvalidRef {\n\t\t\t// Is this import statement unused?\n\t\t\tif ref := decl.Binding.Data.(*js_ast.BIdentifier).Ref; p.symbols[ref.InnerIndex].UseCountEstimate == 0 {\n\t\t\t\t// Also don't count the referenced identifier\n\t\t\t\tp.ignoreUsage(valueRef)\n\n\t\t\t\t// Import-equals statements can come in any order. Removing one\n\t\t\t\t// could potentially cause another one to be removable too.\n\t\t\t\t// Continue iterating until a fixed point has been reached to make\n\t\t\t\t// sure we get them all.\n\t\t\t\tresult.removedImportEquals = true\n\t\t\t\treturn true\n\t\t\t} else {\n\t\t\t\tresult.keptImportEquals = true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc (p *parser) scanForUnusedTSImportEquals(stmts []js_ast.Stmt) (result importsExportsScanResult) {\n\tstmtsEnd := 0\n\n\tfor _, stmt := range stmts {\n\t\tif s, ok := stmt.Data.(*js_ast.SLocal); ok && p.checkForUnusedTSImportEquals(s, &result) {\n\t\t\t// Remove unused import-equals statements, since those likely\n\t\t\t// correspond to types instead of values\n\t\t\tcontinue\n\t\t}\n\n\t\t// Filter out statements we skipped over\n\t\tstmts[stmtsEnd] = stmt\n\t\tstmtsEnd++\n\t}\n\n\tresult.stmts = stmts[:stmtsEnd]\n\treturn\n}\n\nfunc (p *parser) scanForImportsAndExports(stmts []js_ast.Stmt) (result importsExportsScanResult) {\n\tunusedImportFlags := p.options.ts.Config.UnusedImportFlags()\n\tstmtsEnd := 0\n\n\tfor _, stmt := range stmts {\n\t\tswitch s := stmt.Data.(type) {\n\t\tcase *js_ast.SImport:\n\t\t\trecord := &p.importRecords[s.ImportRecordIndex]\n\n\t\t\t// We implement TypeScript's \"preserveValueImports\" tsconfig.json setting\n\t\t\t// to support the use case of compiling partial modules for compile-to-\n\t\t\t// JavaScript languages such as Svelte. These languages try to reference\n\t\t\t// imports in ways that are impossible for TypeScript and esbuild to know\n\t\t\t// about when they are only given a partial module to compile. Here is an\n\t\t\t// example of some Svelte code that contains a TypeScript snippet:\n\t\t\t//\n\t\t\t//   <script lang=\"ts\">\n\t\t\t//     import Counter from './Counter.svelte';\n\t\t\t//     export let name: string = 'world';\n\t\t\t//   </script>\n\t\t\t//   <main>\n\t\t\t//     <h1>Hello {name}!</h1>\n\t\t\t//     <Counter />\n\t\t\t//   </main>\n\t\t\t//\n\t\t\t// Tools that use esbuild to compile TypeScript code inside a Svelte\n\t\t\t// file like this only give esbuild the contents of the <script> tag.\n\t\t\t// The \"preserveValueImports\" setting avoids removing unused import\n\t\t\t// names, which means additional code appended after the TypeScript-\n\t\t\t// to-JavaScript conversion can still access those unused imports.\n\t\t\t//\n\t\t\t// There are two scenarios where we don't do this:\n\t\t\t//\n\t\t\t//   * If we're bundling, then we know we aren't being used to compile\n\t\t\t//     a partial module. The parser is seeing the entire code for the\n\t\t\t//     module so it's safe to remove unused imports. And also we don't\n\t\t\t//     want the linker to generate errors about missing imports if the\n\t\t\t//     imported file is also in the bundle.\n\t\t\t//\n\t\t\t//   * If identifier minification is enabled, then using esbuild as a\n\t\t\t//     partial-module transform library wouldn't work anyway because\n\t\t\t//     the names wouldn't match. And that means we're minifying so the\n\t\t\t//     user is expecting the output to be as small as possible. So we\n\t\t\t//     should omit unused imports.\n\t\t\t//\n\t\t\tkeepUnusedImports := p.options.ts.Parse && (unusedImportFlags&config.TSUnusedImport_KeepValues) != 0 &&\n\t\t\t\tp.options.mode != config.ModeBundle && !p.options.minifyIdentifiers\n\n\t\t\t// Forbid non-default imports for JSON import assertions\n\t\t\tif (record.Flags&ast.AssertTypeJSON) != 0 && p.options.mode == config.ModeBundle && s.Items != nil {\n\t\t\t\tfor _, item := range *s.Items {\n\t\t\t\t\tif p.options.ts.Parse && p.tsUseCounts[item.Name.Ref.InnerIndex] == 0 && (unusedImportFlags&config.TSUnusedImport_KeepValues) == 0 {\n\t\t\t\t\t\t// Do not count imports that TypeScript interprets as type annotations\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif item.Alias != \"default\" {\n\t\t\t\t\t\tp.log.AddErrorWithNotes(&p.tracker, js_lexer.RangeOfIdentifier(p.source, item.AliasLoc),\n\t\t\t\t\t\t\tfmt.Sprintf(\"Cannot use non-default import %q with a JSON import assertion\", item.Alias),\n\t\t\t\t\t\t\tp.notesForAssertTypeJSON(record, item.Alias))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// TypeScript always trims unused imports. This is important for\n\t\t\t// correctness since some imports might be fake (only in the type\n\t\t\t// system and used for type-only imports).\n\t\t\tif (p.options.minifySyntax || p.options.ts.Parse) && !keepUnusedImports {\n\t\t\t\tfoundImports := false\n\t\t\t\tisUnusedInTypeScript := true\n\n\t\t\t\t// Remove the default name if it's unused\n\t\t\t\tif s.DefaultName != nil {\n\t\t\t\t\tfoundImports = true\n\t\t\t\t\tsymbol := p.symbols[s.DefaultName.Ref.InnerIndex]\n\n\t\t\t\t\t// TypeScript has a separate definition of unused\n\t\t\t\t\tif p.options.ts.Parse && (p.tsUseCounts[s.DefaultName.Ref.InnerIndex] != 0 || (p.options.ts.Config.UnusedImportFlags()&config.TSUnusedImport_KeepValues) != 0) {\n\t\t\t\t\t\tisUnusedInTypeScript = false\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove the symbol if it's never used outside a dead code region\n\t\t\t\t\tif symbol.UseCountEstimate == 0 && (p.options.ts.Parse || !p.moduleScope.ContainsDirectEval) {\n\t\t\t\t\t\ts.DefaultName = nil\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Remove the star import if it's unused\n\t\t\t\tif s.StarNameLoc != nil {\n\t\t\t\t\tfoundImports = true\n\t\t\t\t\tsymbol := p.symbols[s.NamespaceRef.InnerIndex]\n\n\t\t\t\t\t// TypeScript has a separate definition of unused\n\t\t\t\t\tif p.options.ts.Parse && (p.tsUseCounts[s.NamespaceRef.InnerIndex] != 0 || (p.options.ts.Config.UnusedImportFlags()&config.TSUnusedImport_KeepValues) != 0) {\n\t\t\t\t\t\tisUnusedInTypeScript = false\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove the symbol if it's never used outside a dead code region\n\t\t\t\t\tif symbol.UseCountEstimate == 0 && (p.options.ts.Parse || !p.moduleScope.ContainsDirectEval) {\n\t\t\t\t\t\t// Make sure we don't remove this if it was used for a property\n\t\t\t\t\t\t// access while bundling\n\t\t\t\t\t\tif importItems, ok := p.importItemsForNamespace[s.NamespaceRef]; ok && len(importItems.entries) == 0 {\n\t\t\t\t\t\t\ts.StarNameLoc = nil\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Remove items if they are unused\n\t\t\t\tif s.Items != nil {\n\t\t\t\t\tfoundImports = true\n\t\t\t\t\titemsEnd := 0\n\n\t\t\t\t\tfor _, item := range *s.Items {\n\t\t\t\t\t\tsymbol := p.symbols[item.Name.Ref.InnerIndex]\n\n\t\t\t\t\t\t// TypeScript has a separate definition of unused\n\t\t\t\t\t\tif p.options.ts.Parse && (p.tsUseCounts[item.Name.Ref.InnerIndex] != 0 || (p.options.ts.Config.UnusedImportFlags()&config.TSUnusedImport_KeepValues) != 0) {\n\t\t\t\t\t\t\tisUnusedInTypeScript = false\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Remove the symbol if it's never used outside a dead code region\n\t\t\t\t\t\tif symbol.UseCountEstimate != 0 || (!p.options.ts.Parse && p.moduleScope.ContainsDirectEval) {\n\t\t\t\t\t\t\t(*s.Items)[itemsEnd] = item\n\t\t\t\t\t\t\titemsEnd++\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Filter the array by taking a slice\n\t\t\t\t\tif itemsEnd == 0 {\n\t\t\t\t\t\ts.Items = nil\n\t\t\t\t\t} else {\n\t\t\t\t\t\t*s.Items = (*s.Items)[:itemsEnd]\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Omit this statement if we're parsing TypeScript and all imports are\n\t\t\t\t// unused. Note that this is distinct from the case where there were\n\t\t\t\t// no imports at all (e.g. \"import 'foo'\"). In that case we want to keep\n\t\t\t\t// the statement because the user is clearly trying to import the module\n\t\t\t\t// for side effects.\n\t\t\t\t//\n\t\t\t\t// This culling is important for correctness when parsing TypeScript\n\t\t\t\t// because a) the TypeScript compiler does ths and we want to match it\n\t\t\t\t// and b) this may be a fake module that only exists in the type system\n\t\t\t\t// and doesn't actually exist in reality.\n\t\t\t\t//\n\t\t\t\t// We do not want to do this culling in JavaScript though because the\n\t\t\t\t// module may have side effects even if all imports are unused.\n\t\t\t\tif p.options.ts.Parse && foundImports && isUnusedInTypeScript && (unusedImportFlags&config.TSUnusedImport_KeepStmt) == 0 {\n\t\t\t\t\t// Ignore import records with a pre-filled source index. These are\n\t\t\t\t\t// for injected files and we definitely do not want to trim these.\n\t\t\t\t\tif !record.SourceIndex.IsValid() && !record.CopySourceIndex.IsValid() {\n\t\t\t\t\t\trecord.Flags |= ast.IsUnused\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif p.options.mode != config.ModePassThrough {\n\t\t\t\tif s.StarNameLoc != nil {\n\t\t\t\t\t// \"importItemsForNamespace\" has property accesses off the namespace\n\t\t\t\t\tif importItems, ok := p.importItemsForNamespace[s.NamespaceRef]; ok && len(importItems.entries) > 0 {\n\t\t\t\t\t\t// Sort keys for determinism\n\t\t\t\t\t\tsorted := make([]string, 0, len(importItems.entries))\n\t\t\t\t\t\tfor alias := range importItems.entries {\n\t\t\t\t\t\t\tsorted = append(sorted, alias)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsort.Strings(sorted)\n\n\t\t\t\t\t\t// Create named imports for these property accesses. This will\n\t\t\t\t\t\t// cause missing imports to generate useful warnings.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// It will also improve bundling efficiency for internal imports\n\t\t\t\t\t\t// by still converting property accesses off the namespace into\n\t\t\t\t\t\t// bare identifiers even if the namespace is still needed.\n\t\t\t\t\t\tfor _, alias := range sorted {\n\t\t\t\t\t\t\tname := importItems.entries[alias]\n\t\t\t\t\t\t\tp.namedImports[name.Ref] = js_ast.NamedImport{\n\t\t\t\t\t\t\t\tAlias:             alias,\n\t\t\t\t\t\t\t\tAliasLoc:          name.Loc,\n\t\t\t\t\t\t\t\tNamespaceRef:      s.NamespaceRef,\n\t\t\t\t\t\t\t\tImportRecordIndex: s.ImportRecordIndex,\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Make sure the printer prints this as a property access\n\t\t\t\t\t\t\tp.symbols[name.Ref.InnerIndex].NamespaceAlias = &ast.NamespaceAlias{\n\t\t\t\t\t\t\t\tNamespaceRef: s.NamespaceRef,\n\t\t\t\t\t\t\t\tAlias:        alias,\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Also record these automatically-generated top-level namespace alias symbols\n\t\t\t\t\t\t\tp.declaredSymbols = append(p.declaredSymbols, js_ast.DeclaredSymbol{\n\t\t\t\t\t\t\t\tRef:        name.Ref,\n\t\t\t\t\t\t\t\tIsTopLevel: true,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif s.DefaultName != nil {\n\t\t\t\t\tp.namedImports[s.DefaultName.Ref] = js_ast.NamedImport{\n\t\t\t\t\t\tAlias:             \"default\",\n\t\t\t\t\t\tAliasLoc:          s.DefaultName.Loc,\n\t\t\t\t\t\tNamespaceRef:      s.NamespaceRef,\n\t\t\t\t\t\tImportRecordIndex: s.ImportRecordIndex,\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif s.StarNameLoc != nil {\n\t\t\t\t\tp.namedImports[s.NamespaceRef] = js_ast.NamedImport{\n\t\t\t\t\t\tAliasIsStar:       true,\n\t\t\t\t\t\tAliasLoc:          *s.StarNameLoc,\n\t\t\t\t\t\tNamespaceRef:      ast.InvalidRef,\n\t\t\t\t\t\tImportRecordIndex: s.ImportRecordIndex,\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif s.Items != nil {\n\t\t\t\t\tfor _, item := range *s.Items {\n\t\t\t\t\t\tp.namedImports[item.Name.Ref] = js_ast.NamedImport{\n\t\t\t\t\t\t\tAlias:             item.Alias,\n\t\t\t\t\t\t\tAliasLoc:          item.AliasLoc,\n\t\t\t\t\t\t\tNamespaceRef:      s.NamespaceRef,\n\t\t\t\t\t\t\tImportRecordIndex: s.ImportRecordIndex,\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.importRecordsForCurrentPart = append(p.importRecordsForCurrentPart, s.ImportRecordIndex)\n\n\t\t\tif s.StarNameLoc != nil {\n\t\t\t\trecord.Flags |= ast.ContainsImportStar\n\t\t\t}\n\n\t\t\tif s.DefaultName != nil {\n\t\t\t\trecord.Flags |= ast.ContainsDefaultAlias\n\t\t\t} else if s.Items != nil {\n\t\t\t\tfor _, item := range *s.Items {\n\t\t\t\t\tif item.Alias == \"default\" {\n\t\t\t\t\t\trecord.Flags |= ast.ContainsDefaultAlias\n\t\t\t\t\t} else if item.Alias == \"__esModule\" {\n\t\t\t\t\t\trecord.Flags |= ast.ContainsESModuleAlias\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *js_ast.SFunction:\n\t\t\tif s.IsExport {\n\t\t\t\tp.recordExport(s.Fn.Name.Loc, p.symbols[s.Fn.Name.Ref.InnerIndex].OriginalName, s.Fn.Name.Ref)\n\t\t\t}\n\n\t\tcase *js_ast.SClass:\n\t\t\tif s.IsExport {\n\t\t\t\tp.recordExport(s.Class.Name.Loc, p.symbols[s.Class.Name.Ref.InnerIndex].OriginalName, s.Class.Name.Ref)\n\t\t\t}\n\n\t\tcase *js_ast.SLocal:\n\t\t\tif s.IsExport {\n\t\t\t\tjs_ast.ForEachIdentifierBindingInDecls(s.Decls, func(loc logger.Loc, b *js_ast.BIdentifier) {\n\t\t\t\t\tp.recordExport(loc, p.symbols[b.Ref.InnerIndex].OriginalName, b.Ref)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Remove unused import-equals statements, since those likely\n\t\t\t// correspond to types instead of values\n\t\t\tif p.checkForUnusedTSImportEquals(s, &result) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tcase *js_ast.SExportDefault:\n\t\t\tp.recordExport(s.DefaultName.Loc, \"default\", s.DefaultName.Ref)\n\n\t\tcase *js_ast.SExportClause:\n\t\t\tfor _, item := range s.Items {\n\t\t\t\tp.recordExport(item.AliasLoc, item.Alias, item.Name.Ref)\n\t\t\t}\n\n\t\tcase *js_ast.SExportStar:\n\t\t\trecord := &p.importRecords[s.ImportRecordIndex]\n\t\t\tp.importRecordsForCurrentPart = append(p.importRecordsForCurrentPart, s.ImportRecordIndex)\n\n\t\t\tif s.Alias != nil {\n\t\t\t\t// \"export * as ns from 'path'\"\n\t\t\t\tp.namedImports[s.NamespaceRef] = js_ast.NamedImport{\n\t\t\t\t\tAliasIsStar:       true,\n\t\t\t\t\tAliasLoc:          s.Alias.Loc,\n\t\t\t\t\tNamespaceRef:      ast.InvalidRef,\n\t\t\t\t\tImportRecordIndex: s.ImportRecordIndex,\n\t\t\t\t\tIsExported:        true,\n\t\t\t\t}\n\t\t\t\tp.recordExport(s.Alias.Loc, s.Alias.OriginalName, s.NamespaceRef)\n\n\t\t\t\trecord.Flags |= ast.ContainsImportStar\n\t\t\t} else {\n\t\t\t\t// \"export * from 'path'\"\n\t\t\t\tp.exportStarImportRecords = append(p.exportStarImportRecords, s.ImportRecordIndex)\n\t\t\t}\n\n\t\tcase *js_ast.SExportFrom:\n\t\t\trecord := &p.importRecords[s.ImportRecordIndex]\n\t\t\tp.importRecordsForCurrentPart = append(p.importRecordsForCurrentPart, s.ImportRecordIndex)\n\n\t\t\tfor _, item := range s.Items {\n\t\t\t\t// Note that the imported alias is not item.Alias, which is the\n\t\t\t\t// exported alias. This is somewhat confusing because each\n\t\t\t\t// SExportFrom statement is basically SImport + SExportClause in one.\n\t\t\t\tp.namedImports[item.Name.Ref] = js_ast.NamedImport{\n\t\t\t\t\tAlias:             item.OriginalName,\n\t\t\t\t\tAliasLoc:          item.Name.Loc,\n\t\t\t\t\tNamespaceRef:      s.NamespaceRef,\n\t\t\t\t\tImportRecordIndex: s.ImportRecordIndex,\n\t\t\t\t\tIsExported:        true,\n\t\t\t\t}\n\t\t\t\tp.recordExport(item.Name.Loc, item.Alias, item.Name.Ref)\n\n\t\t\t\tif item.OriginalName == \"default\" {\n\t\t\t\t\trecord.Flags |= ast.ContainsDefaultAlias\n\t\t\t\t} else if item.OriginalName == \"__esModule\" {\n\t\t\t\t\trecord.Flags |= ast.ContainsESModuleAlias\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forbid non-default imports for JSON import assertions\n\t\t\tif (record.Flags&ast.AssertTypeJSON) != 0 && p.options.mode == config.ModeBundle {\n\t\t\t\tfor _, item := range s.Items {\n\t\t\t\t\tif item.OriginalName != \"default\" {\n\t\t\t\t\t\tp.log.AddErrorWithNotes(&p.tracker, js_lexer.RangeOfIdentifier(p.source, item.Name.Loc),\n\t\t\t\t\t\t\tfmt.Sprintf(\"Cannot use non-default import %q with a JSON import assertion\", item.OriginalName),\n\t\t\t\t\t\t\tp.notesForAssertTypeJSON(record, item.OriginalName))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// TypeScript always trims unused re-exports. This is important for\n\t\t\t// correctness since some re-exports might be fake (only in the type\n\t\t\t// system and used for type-only stuff).\n\t\t\tif p.options.ts.Parse && len(s.Items) == 0 && (unusedImportFlags&config.TSUnusedImport_KeepStmt) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Filter out statements we skipped over\n\t\tstmts[stmtsEnd] = stmt\n\t\tstmtsEnd++\n\t}\n\n\tresult.stmts = stmts[:stmtsEnd]\n\treturn\n}\n\nfunc (p *parser) appendPart(parts []js_ast.Part, stmts []js_ast.Stmt) []js_ast.Part {\n\tp.symbolUses = make(map[ast.Ref]js_ast.SymbolUse)\n\tp.importSymbolPropertyUses = nil\n\tp.symbolCallUses = nil\n\tp.declaredSymbols = nil\n\tp.importRecordsForCurrentPart = nil\n\tp.scopesForCurrentPart = nil\n\n\tpart := js_ast.Part{\n\t\tStmts:      p.visitStmtsAndPrependTempRefs(stmts, prependTempRefsOpts{}),\n\t\tSymbolUses: p.symbolUses,\n\t}\n\n\t// Sanity check\n\tif p.currentScope != p.moduleScope {\n\t\tpanic(\"Internal error: Scope stack imbalance\")\n\t}\n\n\t// Insert any relocated variable statements now\n\tif len(p.relocatedTopLevelVars) > 0 {\n\t\talreadyDeclared := make(map[ast.Ref]bool)\n\t\tfor _, local := range p.relocatedTopLevelVars {\n\t\t\t// Follow links because \"var\" declarations may be merged due to hoisting\n\t\t\tfor {\n\t\t\t\tlink := p.symbols[local.Ref.InnerIndex].Link\n\t\t\t\tif link == ast.InvalidRef {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tlocal.Ref = link\n\t\t\t}\n\n\t\t\t// Only declare a given relocated variable once\n\t\t\tif !alreadyDeclared[local.Ref] {\n\t\t\t\talreadyDeclared[local.Ref] = true\n\t\t\t\tpart.Stmts = append(part.Stmts, js_ast.Stmt{Loc: local.Loc, Data: &js_ast.SLocal{\n\t\t\t\t\tDecls: []js_ast.Decl{{\n\t\t\t\t\t\tBinding: js_ast.Binding{Loc: local.Loc, Data: &js_ast.BIdentifier{Ref: local.Ref}},\n\t\t\t\t\t}},\n\t\t\t\t}})\n\t\t\t}\n\t\t}\n\t\tp.relocatedTopLevelVars = nil\n\t}\n\n\tif len(part.Stmts) > 0 {\n\t\tvar flags js_ast.StmtsCanBeRemovedIfUnusedFlags\n\t\tif p.options.mode == config.ModePassThrough {\n\t\t\t// Exports are tracked separately, so export clauses can normally always\n\t\t\t// be removed. Except we should keep them if we're not doing any format\n\t\t\t// conversion because exports are not re-emitted in that case.\n\t\t\tflags |= js_ast.KeepExportClauses\n\t\t}\n\t\tpart.CanBeRemovedIfUnused = p.astHelpers.StmtsCanBeRemovedIfUnused(part.Stmts, flags)\n\t\tpart.DeclaredSymbols = p.declaredSymbols\n\t\tpart.ImportRecordIndices = p.importRecordsForCurrentPart\n\t\tpart.ImportSymbolPropertyUses = p.importSymbolPropertyUses\n\t\tpart.SymbolCallUses = p.symbolCallUses\n\t\tpart.Scopes = p.scopesForCurrentPart\n\t\tparts = append(parts, part)\n\t}\n\treturn parts\n}\n\nfunc newParser(log logger.Log, source logger.Source, lexer js_lexer.Lexer, options *Options) *parser {\n\tif options.defines == nil {\n\t\tdefaultDefines := config.ProcessDefines(nil)\n\t\toptions.defines = &defaultDefines\n\t}\n\n\tp := &parser{\n\t\tlog:                log,\n\t\tsource:             source,\n\t\ttracker:            logger.MakeLineColumnTracker(&source),\n\t\tlexer:              lexer,\n\t\tallowIn:            true,\n\t\toptions:            *options,\n\t\truntimeImports:     make(map[string]ast.LocRef),\n\t\tpromiseRef:         ast.InvalidRef,\n\t\tregExpRef:          ast.InvalidRef,\n\t\tbigIntRef:          ast.InvalidRef,\n\t\tafterArrowBodyLoc:  logger.Loc{Start: -1},\n\t\tfirstJSXElementLoc: logger.Loc{Start: -1},\n\t\timportMetaRef:      ast.InvalidRef,\n\t\tsuperCtorRef:       ast.InvalidRef,\n\n\t\t// For lowering private methods\n\t\tweakMapRef:     ast.InvalidRef,\n\t\tweakSetRef:     ast.InvalidRef,\n\t\tprivateGetters: make(map[ast.Ref]ast.Ref),\n\t\tprivateSetters: make(map[ast.Ref]ast.Ref),\n\n\t\t// These are for TypeScript\n\t\trefToTSNamespaceMemberData: make(map[ast.Ref]js_ast.TSNamespaceMemberData),\n\t\temittedNamespaceVars:       make(map[ast.Ref]bool),\n\t\tisExportedInsideNamespace:  make(map[ast.Ref]ast.Ref),\n\t\tlocalTypeNames:             make(map[string]bool),\n\n\t\t// These are for handling ES6 imports and exports\n\t\timportItemsForNamespace: make(map[ast.Ref]namespaceImportItems),\n\t\tisImportItem:            make(map[ast.Ref]bool),\n\t\tnamedImports:            make(map[ast.Ref]js_ast.NamedImport),\n\t\tnamedExports:            make(map[string]js_ast.NamedExport),\n\n\t\t// For JSX runtime imports\n\t\tjsxRuntimeImports: make(map[string]ast.LocRef),\n\t\tjsxLegacyImports:  make(map[string]ast.LocRef),\n\n\t\t// Add \"/* @__KEY__ */\" comments when mangling properties to support\n\t\t// running esbuild (or other tools like Terser) again on the output.\n\t\t// This checks both \"--mangle-props\" and \"--reserve-props\" so that\n\t\t// you can turn this on with just \"--reserve-props=.\" if you want to.\n\t\tshouldAddKeyComment: options.mangleProps != nil || options.reserveProps != nil,\n\n\t\tsuppressWarningsAboutWeirdCode: helpers.IsInsideNodeModules(source.KeyPath.Text),\n\t}\n\n\tif len(options.dropLabels) > 0 {\n\t\tp.dropLabelsMap = make(map[string]struct{})\n\t\tfor _, name := range options.dropLabels {\n\t\t\tp.dropLabelsMap[name] = struct{}{}\n\t\t}\n\t}\n\n\tif !options.minifyWhitespace {\n\t\tp.exprComments = make(map[logger.Loc][]string)\n\t}\n\n\tp.astHelpers = js_ast.MakeHelperContext(func(ref ast.Ref) bool {\n\t\treturn p.symbols[ref.InnerIndex].Kind == ast.SymbolUnbound\n\t})\n\n\tp.pushScopeForParsePass(js_ast.ScopeEntry, logger.Loc{Start: locModuleScope})\n\n\treturn p\n}\n\nvar defaultJSXFactory = []string{\"React\", \"createElement\"}\nvar defaultJSXFragment = []string{\"React\", \"Fragment\"}\n\nconst defaultJSXImportSource = \"react\"\n\nfunc Parse(log logger.Log, source logger.Source, options Options) (result js_ast.AST, ok bool) {\n\tok = true\n\tdefer func() {\n\t\tr := recover()\n\t\tif _, isLexerPanic := r.(js_lexer.LexerPanic); isLexerPanic {\n\t\t\tok = false\n\t\t} else if r != nil {\n\t\t\tpanic(r)\n\t\t}\n\t}()\n\n\t// Default options for JSX elements\n\tif len(options.jsx.Factory.Parts) == 0 {\n\t\toptions.jsx.Factory = config.DefineExpr{Parts: defaultJSXFactory}\n\t}\n\tif len(options.jsx.Fragment.Parts) == 0 && options.jsx.Fragment.Constant == nil {\n\t\toptions.jsx.Fragment = config.DefineExpr{Parts: defaultJSXFragment}\n\t}\n\tif len(options.jsx.ImportSource) == 0 {\n\t\toptions.jsx.ImportSource = defaultJSXImportSource\n\t}\n\n\tp := newParser(log, source, js_lexer.NewLexer(log, source, options.ts), &options)\n\n\t// Consume a leading hashbang comment\n\thashbang := \"\"\n\tif p.lexer.Token == js_lexer.THashbang {\n\t\thashbang = p.lexer.Identifier.String\n\t\tp.lexer.Next()\n\t}\n\n\t// Allow top-level await\n\tp.fnOrArrowDataParse.await = allowExpr\n\tp.fnOrArrowDataParse.isTopLevel = true\n\n\t// Parse the file in the first pass, but do not bind symbols\n\tstmts := p.parseStmtsUpTo(js_lexer.TEndOfFile, parseStmtOpts{\n\t\tisModuleScope:          true,\n\t\tallowDirectivePrologue: true,\n\t})\n\tp.prepareForVisitPass()\n\n\t// Insert a \"use strict\" directive if \"alwaysStrict\" is active\n\tvar directives []string\n\tif tsAlwaysStrict := p.options.tsAlwaysStrict; tsAlwaysStrict != nil && tsAlwaysStrict.Value {\n\t\tdirectives = append(directives, \"use strict\")\n\t}\n\n\t// Strip off all leading directives\n\t{\n\t\ttotalCount := 0\n\t\tkeptCount := 0\n\n\t\tfor _, stmt := range stmts {\n\t\t\tswitch s := stmt.Data.(type) {\n\t\t\tcase *js_ast.SComment:\n\t\t\t\tstmts[keptCount] = stmt\n\t\t\t\tkeptCount++\n\t\t\t\ttotalCount++\n\t\t\t\tcontinue\n\n\t\t\tcase *js_ast.SDirective:\n\t\t\t\tif p.isStrictMode() && s.LegacyOctalLoc.Start > 0 {\n\t\t\t\t\tp.markStrictModeFeature(legacyOctalEscape, p.source.RangeOfLegacyOctalEscape(s.LegacyOctalLoc), \"\")\n\t\t\t\t}\n\t\t\t\tdirective := helpers.UTF16ToString(s.Value)\n\n\t\t\t\t// Remove duplicate directives\n\t\t\t\tfound := false\n\t\t\t\tfor _, existing := range directives {\n\t\t\t\t\tif existing == directive {\n\t\t\t\t\t\tfound = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif !found {\n\t\t\t\t\tdirectives = append(directives, directive)\n\t\t\t\t}\n\n\t\t\t\t// Remove this directive from the statement list\n\t\t\t\ttotalCount++\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Stop when the directive prologue ends\n\t\t\tbreak\n\t\t}\n\n\t\tif keptCount < totalCount {\n\t\t\tstmts = append(stmts[:keptCount], stmts[totalCount:]...)\n\t\t}\n\t}\n\n\t// Add an empty part for the namespace export that we can fill in later\n\tnsExportPart := js_ast.Part{\n\t\tSymbolUses:           make(map[ast.Ref]js_ast.SymbolUse),\n\t\tCanBeRemovedIfUnused: true,\n\t}\n\n\tvar before = []js_ast.Part{nsExportPart}\n\tvar parts []js_ast.Part\n\tvar after []js_ast.Part\n\n\t// Insert any injected import statements now that symbols have been declared\n\tfor _, file := range p.options.injectedFiles {\n\t\texportsNoConflict := make([]string, 0, len(file.Exports))\n\t\tsymbols := make(map[string]ast.LocRef)\n\n\t\tif file.DefineName != \"\" {\n\t\t\tref := p.newSymbol(ast.SymbolOther, file.DefineName)\n\t\t\tp.moduleScope.Generated = append(p.moduleScope.Generated, ref)\n\t\t\tsymbols[\"default\"] = ast.LocRef{Ref: ref}\n\t\t\texportsNoConflict = append(exportsNoConflict, \"default\")\n\t\t\tp.injectedDefineSymbols = append(p.injectedDefineSymbols, ref)\n\t\t} else {\n\t\tnextExport:\n\t\t\tfor _, export := range file.Exports {\n\t\t\t\t// Skip injecting this symbol if it's already declared locally (i.e. it's not a reference to a global)\n\t\t\t\tif _, ok := p.moduleScope.Members[export.Alias]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tparts := strings.Split(export.Alias, \".\")\n\n\t\t\t\t// The key must be a dot-separated identifier list\n\t\t\t\tfor _, part := range parts {\n\t\t\t\t\tif !js_ast.IsIdentifier(part) {\n\t\t\t\t\t\tcontinue nextExport\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tref := p.newSymbol(ast.SymbolInjected, export.Alias)\n\t\t\t\tsymbols[export.Alias] = ast.LocRef{Ref: ref}\n\t\t\t\tif len(parts) == 1 {\n\t\t\t\t\t// Handle the identifier case by generating an injected symbol directly\n\t\t\t\t\tp.moduleScope.Members[export.Alias] = js_ast.ScopeMember{Ref: ref}\n\t\t\t\t} else {\n\t\t\t\t\t// Handle the dot case using a map. This map is similar to the map\n\t\t\t\t\t// \"options.defines.DotDefines\" but is kept separate instead of being\n\t\t\t\t\t// implemented using the same mechanism because we allow you to use\n\t\t\t\t\t// \"define\" to rewrite something to an injected symbol (i.e. we allow\n\t\t\t\t\t// two levels of mappings). This was historically necessary to be able\n\t\t\t\t\t// to map a dot name to an injected symbol because we previously didn't\n\t\t\t\t\t// support dot names as injected symbols. But now dot names as injected\n\t\t\t\t\t// symbols has been implemented, so supporting two levels of mappings\n\t\t\t\t\t// is only for backward-compatibility.\n\t\t\t\t\tif p.injectedDotNames == nil {\n\t\t\t\t\t\tp.injectedDotNames = make(map[string][]injectedDotName)\n\t\t\t\t\t}\n\t\t\t\t\ttail := parts[len(parts)-1]\n\t\t\t\t\tp.injectedDotNames[tail] = append(p.injectedDotNames[tail], injectedDotName{parts: parts, injectedDefineIndex: uint32(len(p.injectedDefineSymbols))})\n\t\t\t\t\tp.injectedDefineSymbols = append(p.injectedDefineSymbols, ref)\n\t\t\t\t}\n\t\t\t\texportsNoConflict = append(exportsNoConflict, export.Alias)\n\t\t\t\tif p.injectedSymbolSources == nil {\n\t\t\t\t\tp.injectedSymbolSources = make(map[ast.Ref]injectedSymbolSource)\n\t\t\t\t}\n\t\t\t\tp.injectedSymbolSources[ref] = injectedSymbolSource{\n\t\t\t\t\tsource: file.Source,\n\t\t\t\t\tloc:    export.Loc,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif file.IsCopyLoader {\n\t\t\tbefore, _ = p.generateImportStmt(file.Source.KeyPath.Text, logger.Range{}, exportsNoConflict, before, symbols, nil, &file.Source.Index)\n\t\t} else {\n\t\t\tbefore, _ = p.generateImportStmt(file.Source.KeyPath.Text, logger.Range{}, exportsNoConflict, before, symbols, &file.Source.Index, nil)\n\t\t}\n\t}\n\n\t// When \"using\" declarations appear at the top level, we change all TDZ\n\t// variables in the top-level scope into \"var\" so that they aren't harmed\n\t// when they are moved into the try/catch statement that lowering will\n\t// generate.\n\t//\n\t// This is necessary because exported function declarations must be hoisted\n\t// outside of the try/catch statement because they can be evaluated before\n\t// this module is evaluated due to ESM cross-file function hoisting. And\n\t// these function bodies might reference anything else in this scope, which\n\t// must still work when those things are moved inside a try/catch statement.\n\t//\n\t// Before:\n\t//\n\t//   using foo = get()\n\t//   export function fn() {\n\t//     return [foo, new Bar]\n\t//   }\n\t//   class Bar {}\n\t//\n\t// After (\"fn\" is hoisted, \"Bar\" is converted to \"var\"):\n\t//\n\t//   export function fn() {\n\t//     return [foo, new Bar]\n\t//   }\n\t//   try {\n\t//     var foo = get();\n\t//     var Bar = class {};\n\t//   } catch (_) {\n\t//     ...\n\t//   } finally {\n\t//     ...\n\t//   }\n\t//\n\t// This is also necessary because other code might be appended to the code\n\t// that we're processing and expect to be able to access top-level variables.\n\tp.willWrapModuleInTryCatchForUsing = p.shouldLowerUsingDeclarations(stmts)\n\n\t// Bind symbols in a second pass over the AST. I started off doing this in a\n\t// single pass, but it turns out it's pretty much impossible to do this\n\t// correctly while handling arrow functions because of the grammar\n\t// ambiguities.\n\t//\n\t// Note that top-level lowered \"using\" declarations disable tree-shaking\n\t// because we only do tree-shaking on top-level statements and lowering\n\t// a top-level \"using\" declaration moves all top-level statements into a\n\t// nested scope.\n\tif !p.options.treeShaking || p.willWrapModuleInTryCatchForUsing {\n\t\t// When tree shaking is disabled, everything comes in a single part\n\t\tparts = p.appendPart(parts, stmts)\n\t} else {\n\t\tvar preprocessedEnums map[int][]js_ast.Part\n\t\tif p.scopesInOrderForEnum != nil {\n\t\t\t// Preprocess TypeScript enums to improve code generation. Otherwise\n\t\t\t// uses of an enum before that enum has been declared won't be inlined:\n\t\t\t//\n\t\t\t//   console.log(Foo.FOO) // We want \"FOO\" to be inlined here\n\t\t\t//   const enum Foo { FOO = 0 }\n\t\t\t//\n\t\t\t// The TypeScript compiler itself contains code with this pattern, so\n\t\t\t// it's important to implement this optimization.\n\t\t\tfor i, stmt := range stmts {\n\t\t\t\tif _, ok := stmt.Data.(*js_ast.SEnum); ok {\n\t\t\t\t\tif preprocessedEnums == nil {\n\t\t\t\t\t\tpreprocessedEnums = make(map[int][]js_ast.Part)\n\t\t\t\t\t}\n\t\t\t\t\toldScopesInOrder := p.scopesInOrder\n\t\t\t\t\tp.scopesInOrder = p.scopesInOrderForEnum[stmt.Loc]\n\t\t\t\t\tpreprocessedEnums[i] = p.appendPart(nil, []js_ast.Stmt{stmt})\n\t\t\t\t\tp.scopesInOrder = oldScopesInOrder\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// When tree shaking is enabled, each top-level statement is potentially a separate part\n\t\tfor i, stmt := range stmts {\n\t\t\tswitch s := stmt.Data.(type) {\n\t\t\tcase *js_ast.SLocal:\n\t\t\t\t// Split up top-level multi-declaration variable statements\n\t\t\t\tfor _, decl := range s.Decls {\n\t\t\t\t\tclone := *s\n\t\t\t\t\tclone.Decls = []js_ast.Decl{decl}\n\t\t\t\t\tparts = p.appendPart(parts, []js_ast.Stmt{{Loc: stmt.Loc, Data: &clone}})\n\t\t\t\t}\n\n\t\t\tcase *js_ast.SImport, *js_ast.SExportFrom, *js_ast.SExportStar:\n\t\t\t\tif p.options.mode != config.ModePassThrough {\n\t\t\t\t\t// Move imports (and import-like exports) to the top of the file to\n\t\t\t\t\t// ensure that if they are converted to a require() call, the effects\n\t\t\t\t\t// will take place before any other statements are evaluated.\n\t\t\t\t\tbefore = p.appendPart(before, []js_ast.Stmt{stmt})\n\t\t\t\t} else {\n\t\t\t\t\t// If we aren't doing any format conversion, just keep these statements\n\t\t\t\t\t// inline where they were. Exports are sorted so order doesn't matter:\n\t\t\t\t\t// https://262.ecma-international.org/6.0/#sec-module-namespace-exotic-objects.\n\t\t\t\t\t// However, this is likely an aesthetic issue that some people will\n\t\t\t\t\t// complain about. In addition, there are code transformation tools\n\t\t\t\t\t// such as TypeScript and Babel with bugs where the order of exports\n\t\t\t\t\t// in the file is incorrectly preserved instead of sorted, so preserving\n\t\t\t\t\t// the order of exports ourselves here may be preferable.\n\t\t\t\t\tparts = p.appendPart(parts, []js_ast.Stmt{stmt})\n\t\t\t\t}\n\n\t\t\tcase *js_ast.SExportEquals:\n\t\t\t\t// TypeScript \"export = value;\" becomes \"module.exports = value;\". This\n\t\t\t\t// must happen at the end after everything is parsed because TypeScript\n\t\t\t\t// moves this statement to the end when it generates code.\n\t\t\t\tafter = p.appendPart(after, []js_ast.Stmt{stmt})\n\n\t\t\tcase *js_ast.SEnum:\n\t\t\t\tparts = append(parts, preprocessedEnums[i]...)\n\t\t\t\tp.scopesInOrder = p.scopesInOrder[len(p.scopesInOrderForEnum[stmt.Loc]):]\n\n\t\t\tdefault:\n\t\t\t\tparts = p.appendPart(parts, []js_ast.Stmt{stmt})\n\t\t\t}\n\t\t}\n\t}\n\n\t// Insert a variable for \"import.meta\" at the top of the file if it was used.\n\t// We don't need to worry about \"use strict\" directives because this only\n\t// happens when bundling, in which case we are flatting the module scopes of\n\t// all modules together anyway so such directives are meaningless.\n\tif p.importMetaRef != ast.InvalidRef {\n\t\timportMetaStmt := js_ast.Stmt{Data: &js_ast.SLocal{\n\t\t\tKind: p.selectLocalKind(js_ast.LocalConst),\n\t\t\tDecls: []js_ast.Decl{{\n\t\t\t\tBinding:    js_ast.Binding{Data: &js_ast.BIdentifier{Ref: p.importMetaRef}},\n\t\t\t\tValueOrNil: js_ast.Expr{Data: &js_ast.EObject{}},\n\t\t\t}},\n\t\t}}\n\t\tbefore = append(before, js_ast.Part{\n\t\t\tStmts:                []js_ast.Stmt{importMetaStmt},\n\t\t\tSymbolUses:           make(map[ast.Ref]js_ast.SymbolUse),\n\t\t\tDeclaredSymbols:      []js_ast.DeclaredSymbol{{Ref: p.importMetaRef, IsTopLevel: true}},\n\t\t\tCanBeRemovedIfUnused: true,\n\t\t})\n\t}\n\n\t// Pop the module scope to apply the \"ContainsDirectEval\" rules\n\tp.popScope()\n\n\tresult = p.toAST(before, parts, after, hashbang, directives)\n\tresult.SourceMapComment = p.lexer.SourceMappingURL\n\treturn\n}\n\ntype HelperCall struct {\n\tGlobal  []string\n\tRuntime string\n}\n\nfunc LazyExportAST(log logger.Log, source logger.Source, options Options, expr js_ast.Expr, helperCall *HelperCall) js_ast.AST {\n\t// Don't create a new lexer using js_lexer.NewLexer() here since that will\n\t// actually attempt to parse the first token, which might cause a syntax\n\t// error.\n\tp := newParser(log, source, js_lexer.Lexer{}, &options)\n\tp.prepareForVisitPass()\n\n\t// Optionally call a runtime API function to transform the expression\n\tif helperCall != nil {\n\t\tp.symbolUses = make(map[ast.Ref]js_ast.SymbolUse)\n\t\tif len(helperCall.Global) > 0 {\n\t\t\tref := p.newSymbol(ast.SymbolUnbound, helperCall.Global[0])\n\t\t\tp.recordUsage(ref)\n\t\t\ttarget := js_ast.Expr{Data: &js_ast.EIdentifier{Ref: ref}}\n\t\t\tkind := js_ast.NormalCall\n\t\t\tfor _, name := range helperCall.Global[1:] {\n\t\t\t\ttarget.Data = &js_ast.EDot{Target: target, Name: name}\n\t\t\t\tkind = js_ast.TargetWasOriginallyPropertyAccess\n\t\t\t}\n\t\t\texpr.Data = &js_ast.ECall{Target: target, Args: []js_ast.Expr{expr}, Kind: kind}\n\t\t} else {\n\t\t\texpr = p.callRuntime(expr.Loc, helperCall.Runtime, []js_ast.Expr{expr})\n\t\t}\n\t}\n\n\t// Add an empty part for the namespace export that we can fill in later\n\tnsExportPart := js_ast.Part{\n\t\tSymbolUses:           make(map[ast.Ref]js_ast.SymbolUse),\n\t\tCanBeRemovedIfUnused: true,\n\t}\n\n\t// Defer the actual code generation until linking\n\tpart := js_ast.Part{\n\t\tStmts:      []js_ast.Stmt{{Loc: expr.Loc, Data: &js_ast.SLazyExport{Value: expr}}},\n\t\tSymbolUses: p.symbolUses,\n\t}\n\tp.symbolUses = nil\n\n\tast := p.toAST([]js_ast.Part{nsExportPart}, []js_ast.Part{part}, nil, \"\", nil)\n\tast.HasLazyExport = true\n\treturn ast\n}\n\nfunc GlobResolveAST(log logger.Log, source logger.Source, importRecords []ast.ImportRecord, object *js_ast.EObject, name string) js_ast.AST {\n\t// Don't create a new lexer using js_lexer.NewLexer() here since that will\n\t// actually attempt to parse the first token, which might cause a syntax\n\t// error.\n\tp := newParser(log, source, js_lexer.Lexer{}, &Options{})\n\tp.prepareForVisitPass()\n\n\t// Add an empty part for the namespace export that we can fill in later\n\tnsExportPart := js_ast.Part{\n\t\tSymbolUses:           make(map[ast.Ref]js_ast.SymbolUse),\n\t\tCanBeRemovedIfUnused: true,\n\t}\n\n\tif len(p.importRecords) != 0 {\n\t\tpanic(\"Internal error\")\n\t}\n\tp.importRecords = importRecords\n\n\timportRecordIndices := make([]uint32, 0, len(importRecords))\n\tfor importRecordIndex := range importRecords {\n\t\timportRecordIndices = append(importRecordIndices, uint32(importRecordIndex))\n\t}\n\n\tp.symbolUses = make(map[ast.Ref]js_ast.SymbolUse)\n\tref := p.newSymbol(ast.SymbolOther, name)\n\tp.moduleScope.Generated = append(p.moduleScope.Generated, ref)\n\n\tpart := js_ast.Part{\n\t\tStmts: []js_ast.Stmt{{Data: &js_ast.SLocal{\n\t\t\tIsExport: true,\n\t\t\tDecls: []js_ast.Decl{{\n\t\t\t\tBinding:    js_ast.Binding{Data: &js_ast.BIdentifier{Ref: ref}},\n\t\t\t\tValueOrNil: p.callRuntime(logger.Loc{}, \"__glob\", []js_ast.Expr{{Data: object}}),\n\t\t\t}},\n\t\t}}},\n\t\tImportRecordIndices: importRecordIndices,\n\t\tSymbolUses:          p.symbolUses,\n\t}\n\tp.symbolUses = nil\n\n\tp.esmExportKeyword.Len = 1\n\treturn p.toAST([]js_ast.Part{nsExportPart}, []js_ast.Part{part}, nil, \"\", nil)\n}\n\nfunc ParseDefineExpr(text string) (config.DefineExpr, js_ast.E) {\n\tif text == \"\" {\n\t\treturn config.DefineExpr{}, nil\n\t}\n\n\t// Try a property chain\n\tparts := strings.Split(text, \".\")\n\tfor i, part := range parts {\n\t\tif !js_ast.IsIdentifier(part) {\n\t\t\tparts = nil\n\t\t\tbreak\n\t\t}\n\n\t\t// Don't allow most keywords as the identifier\n\t\tif i == 0 {\n\t\t\tif token, ok := js_lexer.Keywords[part]; ok && token != js_lexer.TNull && token != js_lexer.TThis &&\n\t\t\t\t(token != js_lexer.TImport || len(parts) < 2 || parts[1] != \"meta\") {\n\t\t\t\tparts = nil\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tif parts != nil {\n\t\treturn config.DefineExpr{Parts: parts}, nil\n\t}\n\n\t// Try parsing a value\n\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\texpr, ok := ParseJSON(log, logger.Source{Contents: text}, JSONOptions{\n\t\tIsForDefine: true,\n\t})\n\tif !ok {\n\t\treturn config.DefineExpr{}, nil\n\t}\n\n\t// Only primitive literals are inlined directly\n\tswitch expr.Data.(type) {\n\tcase *js_ast.ENull, *js_ast.EBoolean, *js_ast.EString, *js_ast.ENumber, *js_ast.EBigInt:\n\t\treturn config.DefineExpr{Constant: expr.Data}, nil\n\t}\n\n\t// If it's not a primitive, return the whole compound JSON value to be injected out-of-line\n\treturn config.DefineExpr{}, expr.Data\n}\n\ntype whyESM uint8\n\nconst (\n\twhyESMUnknown whyESM = iota\n\twhyESMExportKeyword\n\twhyESMImportMeta\n\twhyESMTopLevelAwait\n\twhyESMFileMJS\n\twhyESMFileMTS\n\twhyESMTypeModulePackageJSON\n\twhyESMImportStatement\n)\n\n// Say why this the current file is being considered an ES module\nfunc (p *parser) whyESModule() (whyESM, []logger.MsgData) {\n\tbecause := \"This file is considered to be an ECMAScript module because\"\n\tswitch {\n\tcase p.esmExportKeyword.Len > 0:\n\t\treturn whyESMExportKeyword, []logger.MsgData{p.tracker.MsgData(p.esmExportKeyword,\n\t\t\tbecause+\" of the \\\"export\\\" keyword here:\")}\n\n\tcase p.esmImportMeta.Len > 0:\n\t\treturn whyESMImportMeta, []logger.MsgData{p.tracker.MsgData(p.esmImportMeta,\n\t\t\tbecause+\" of the use of \\\"import.meta\\\" here:\")}\n\n\tcase p.topLevelAwaitKeyword.Len > 0:\n\t\treturn whyESMTopLevelAwait, []logger.MsgData{p.tracker.MsgData(p.topLevelAwaitKeyword,\n\t\t\tbecause+\" of the top-level \\\"await\\\" keyword here:\")}\n\n\tcase p.options.moduleTypeData.Type == js_ast.ModuleESM_MJS:\n\t\treturn whyESMFileMJS, []logger.MsgData{{Text: because + \" the file name ends in \\\".mjs\\\".\"}}\n\n\tcase p.options.moduleTypeData.Type == js_ast.ModuleESM_MTS:\n\t\treturn whyESMFileMTS, []logger.MsgData{{Text: because + \" the file name ends in \\\".mts\\\".\"}}\n\n\tcase p.options.moduleTypeData.Type == js_ast.ModuleESM_PackageJSON:\n\t\ttracker := logger.MakeLineColumnTracker(p.options.moduleTypeData.Source)\n\t\treturn whyESMTypeModulePackageJSON, []logger.MsgData{tracker.MsgData(p.options.moduleTypeData.Range,\n\t\t\tbecause+\" the enclosing \\\"package.json\\\" file sets the type of this file to \\\"module\\\":\")}\n\n\t// This case must come last because some code cares about the \"import\"\n\t// statement keyword and some doesn't, and we don't want to give code\n\t// that doesn't care about the \"import\" statement the wrong error message.\n\tcase p.esmImportStatementKeyword.Len > 0:\n\t\treturn whyESMImportStatement, []logger.MsgData{p.tracker.MsgData(p.esmImportStatementKeyword,\n\t\t\tbecause+\" of the \\\"import\\\" keyword here:\")}\n\t}\n\treturn whyESMUnknown, nil\n}\n\nfunc (p *parser) prepareForVisitPass() {\n\tp.pushScopeForVisitPass(js_ast.ScopeEntry, logger.Loc{Start: locModuleScope})\n\tp.fnOrArrowDataVisit.isOutsideFnOrArrow = true\n\tp.moduleScope = p.currentScope\n\n\t// Force-enable strict mode if that's the way TypeScript is configured\n\tif tsAlwaysStrict := p.options.tsAlwaysStrict; tsAlwaysStrict != nil && tsAlwaysStrict.Value {\n\t\tp.currentScope.StrictMode = js_ast.ImplicitStrictModeTSAlwaysStrict\n\t}\n\n\t// Determine whether or not this file is ESM\n\tp.isFileConsideredToHaveESMExports =\n\t\tp.esmExportKeyword.Len > 0 ||\n\t\t\tp.esmImportMeta.Len > 0 ||\n\t\t\tp.topLevelAwaitKeyword.Len > 0 ||\n\t\t\tp.options.moduleTypeData.Type.IsESM()\n\tp.isFileConsideredESM =\n\t\tp.isFileConsideredToHaveESMExports ||\n\t\t\tp.esmImportStatementKeyword.Len > 0\n\n\t// Legacy HTML comments are not allowed in ESM files\n\tif p.isFileConsideredESM && p.lexer.LegacyHTMLCommentRange.Len > 0 {\n\t\t_, notes := p.whyESModule()\n\t\tp.log.AddErrorWithNotes(&p.tracker, p.lexer.LegacyHTMLCommentRange,\n\t\t\t\"Legacy HTML single-line comments are not allowed in ECMAScript modules\", notes)\n\t}\n\n\t// ECMAScript modules are always interpreted as strict mode. This has to be\n\t// done before \"hoistSymbols\" because strict mode can alter hoisting (!).\n\tif p.isFileConsideredESM {\n\t\tp.moduleScope.RecursiveSetStrictMode(js_ast.ImplicitStrictModeESM)\n\t}\n\n\tp.hoistSymbols(p.moduleScope)\n\n\tif p.options.mode != config.ModePassThrough {\n\t\tp.requireRef = p.declareCommonJSSymbol(ast.SymbolUnbound, \"require\")\n\t} else {\n\t\tp.requireRef = p.newSymbol(ast.SymbolUnbound, \"require\")\n\t}\n\n\t// CommonJS-style exports are only enabled if this isn't using ECMAScript-\n\t// style exports. You can still use \"require\" in ESM, just not \"module\" or\n\t// \"exports\". You can also still use \"import\" in CommonJS.\n\tif p.options.mode != config.ModePassThrough && !p.isFileConsideredToHaveESMExports {\n\t\t// CommonJS-style exports\n\t\tp.exportsRef = p.declareCommonJSSymbol(ast.SymbolHoisted, \"exports\")\n\t\tp.moduleRef = p.declareCommonJSSymbol(ast.SymbolHoisted, \"module\")\n\t} else {\n\t\t// ESM-style exports\n\t\tp.exportsRef = p.newSymbol(ast.SymbolHoisted, \"exports\")\n\t\tp.moduleRef = p.newSymbol(ast.SymbolHoisted, \"module\")\n\t}\n\n\t// Handle \"@jsx\" and \"@jsxFrag\" pragmas now that lexing is done\n\tif p.options.jsx.Parse {\n\t\tif jsxRuntime := p.lexer.JSXRuntimePragmaComment; jsxRuntime.Text != \"\" {\n\t\t\tif jsxRuntime.Text == \"automatic\" {\n\t\t\t\tp.options.jsx.AutomaticRuntime = true\n\t\t\t} else if jsxRuntime.Text == \"classic\" {\n\t\t\t\tp.options.jsx.AutomaticRuntime = false\n\t\t\t} else {\n\t\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_UnsupportedJSXComment, logger.Warning, &p.tracker, jsxRuntime.Range,\n\t\t\t\t\tfmt.Sprintf(\"Invalid JSX runtime: %q\", jsxRuntime.Text),\n\t\t\t\t\t[]logger.MsgData{{Text: \"The JSX runtime can only be set to either \\\"classic\\\" or \\\"automatic\\\".\"}})\n\t\t\t}\n\t\t}\n\n\t\tif jsxFactory := p.lexer.JSXFactoryPragmaComment; jsxFactory.Text != \"\" {\n\t\t\tif p.options.jsx.AutomaticRuntime {\n\t\t\t\tp.log.AddID(logger.MsgID_JS_UnsupportedJSXComment, logger.Warning, &p.tracker, jsxFactory.Range,\n\t\t\t\t\t\"The JSX factory cannot be set when using React's \\\"automatic\\\" JSX transform\")\n\t\t\t} else if expr, _ := ParseDefineExpr(jsxFactory.Text); len(expr.Parts) > 0 {\n\t\t\t\tp.options.jsx.Factory = expr\n\t\t\t} else {\n\t\t\t\tp.log.AddID(logger.MsgID_JS_UnsupportedJSXComment, logger.Warning, &p.tracker, jsxFactory.Range,\n\t\t\t\t\tfmt.Sprintf(\"Invalid JSX factory: %s\", jsxFactory.Text))\n\t\t\t}\n\t\t}\n\n\t\tif jsxFragment := p.lexer.JSXFragmentPragmaComment; jsxFragment.Text != \"\" {\n\t\t\tif p.options.jsx.AutomaticRuntime {\n\t\t\t\tp.log.AddID(logger.MsgID_JS_UnsupportedJSXComment, logger.Warning, &p.tracker, jsxFragment.Range,\n\t\t\t\t\t\"The JSX fragment cannot be set when using React's \\\"automatic\\\" JSX transform\")\n\t\t\t} else if expr, _ := ParseDefineExpr(jsxFragment.Text); len(expr.Parts) > 0 || expr.Constant != nil {\n\t\t\t\tp.options.jsx.Fragment = expr\n\t\t\t} else {\n\t\t\t\tp.log.AddID(logger.MsgID_JS_UnsupportedJSXComment, logger.Warning, &p.tracker, jsxFragment.Range,\n\t\t\t\t\tfmt.Sprintf(\"Invalid JSX fragment: %s\", jsxFragment.Text))\n\t\t\t}\n\t\t}\n\n\t\tif jsxImportSource := p.lexer.JSXImportSourcePragmaComment; jsxImportSource.Text != \"\" {\n\t\t\tif !p.options.jsx.AutomaticRuntime {\n\t\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_UnsupportedJSXComment, logger.Warning, &p.tracker, jsxImportSource.Range,\n\t\t\t\t\t\"The JSX import source cannot be set without also enabling React's \\\"automatic\\\" JSX transform\",\n\t\t\t\t\t[]logger.MsgData{{Text: \"You can enable React's \\\"automatic\\\" JSX transform for this file by using a \\\"@jsxRuntime automatic\\\" comment.\"}})\n\t\t\t} else {\n\t\t\t\tp.options.jsx.ImportSource = jsxImportSource.Text\n\t\t\t}\n\t\t}\n\t}\n\n\t// Force-enable strict mode if the JSX \"automatic\" runtime is enabled and\n\t// there is at least one JSX element. This is because the automatically-\n\t// generated import statement turns the file into an ES module. This behavior\n\t// matches TypeScript which also does this. See this PR for more information:\n\t// https://github.com/microsoft/TypeScript/pull/39199\n\tif p.currentScope.StrictMode == js_ast.SloppyMode && p.options.jsx.AutomaticRuntime && p.firstJSXElementLoc.Start != -1 {\n\t\tp.currentScope.StrictMode = js_ast.ImplicitStrictModeJSXAutomaticRuntime\n\t}\n}\n\nfunc (p *parser) declareCommonJSSymbol(kind ast.SymbolKind, name string) ast.Ref {\n\tmember, ok := p.moduleScope.Members[name]\n\n\t// If the code declared this symbol using \"var name\", then this is actually\n\t// not a collision. For example, node will let you do this:\n\t//\n\t//   var exports;\n\t//   module.exports.foo = 123;\n\t//   console.log(exports.foo);\n\t//\n\t// This works because node's implementation of CommonJS wraps the entire\n\t// source file like this:\n\t//\n\t//   (function(require, exports, module, __filename, __dirname) {\n\t//     var exports;\n\t//     module.exports.foo = 123;\n\t//     console.log(exports.foo);\n\t//   })\n\t//\n\t// Both the \"exports\" argument and \"var exports\" are hoisted variables, so\n\t// they don't collide.\n\tif ok && p.symbols[member.Ref.InnerIndex].Kind == ast.SymbolHoisted &&\n\t\tkind == ast.SymbolHoisted && !p.isFileConsideredToHaveESMExports {\n\t\treturn member.Ref\n\t}\n\n\t// Create a new symbol if we didn't merge with an existing one above\n\tref := p.newSymbol(kind, name)\n\n\t// If the variable wasn't declared, declare it now. This means any references\n\t// to this name will become bound to this symbol after this (since we haven't\n\t// run the visit pass yet).\n\tif !ok {\n\t\tp.moduleScope.Members[name] = js_ast.ScopeMember{Ref: ref, Loc: logger.Loc{Start: -1}}\n\t\treturn ref\n\t}\n\n\t// If the variable was declared, then it shadows this symbol. The code in\n\t// this module will be unable to reference this symbol. However, we must\n\t// still add the symbol to the scope so it gets minified (automatically-\n\t// generated code may still reference the symbol).\n\tp.moduleScope.Generated = append(p.moduleScope.Generated, ref)\n\treturn ref\n}\n\n// Compute a character frequency histogram for everything that's not a bound\n// symbol. This is used to modify how minified names are generated for slightly\n// better gzip compression. Even though it's a very small win, we still do it\n// because it's simple to do and very cheap to compute.\nfunc (p *parser) computeCharacterFrequency() *ast.CharFreq {\n\tif !p.options.minifyIdentifiers || p.source.Index == runtime.SourceIndex {\n\t\treturn nil\n\t}\n\n\t// Add everything in the file to the histogram\n\tcharFreq := &ast.CharFreq{}\n\tcharFreq.Scan(p.source.Contents, 1)\n\n\t// Subtract out all comments\n\tfor _, commentRange := range p.lexer.AllComments {\n\t\tcharFreq.Scan(p.source.TextForRange(commentRange), -1)\n\t}\n\n\t// Subtract out all import paths\n\tfor _, record := range p.importRecords {\n\t\tif !record.SourceIndex.IsValid() {\n\t\t\tcharFreq.Scan(record.Path.Text, -1)\n\t\t}\n\t}\n\n\t// Subtract out all symbols that will be minified\n\tvar visit func(*js_ast.Scope)\n\tvisit = func(scope *js_ast.Scope) {\n\t\tfor _, member := range scope.Members {\n\t\t\tsymbol := &p.symbols[member.Ref.InnerIndex]\n\t\t\tif symbol.SlotNamespace() != ast.SlotMustNotBeRenamed {\n\t\t\t\tcharFreq.Scan(symbol.OriginalName, -int32(symbol.UseCountEstimate))\n\t\t\t}\n\t\t}\n\t\tif scope.Label.Ref != ast.InvalidRef {\n\t\t\tsymbol := &p.symbols[scope.Label.Ref.InnerIndex]\n\t\t\tif symbol.SlotNamespace() != ast.SlotMustNotBeRenamed {\n\t\t\t\tcharFreq.Scan(symbol.OriginalName, -int32(symbol.UseCountEstimate)-1)\n\t\t\t}\n\t\t}\n\t\tfor _, child := range scope.Children {\n\t\t\tvisit(child)\n\t\t}\n\t}\n\tvisit(p.moduleScope)\n\n\t// Subtract out all properties that will be mangled\n\tfor _, ref := range p.mangledProps {\n\t\tsymbol := &p.symbols[ref.InnerIndex]\n\t\tcharFreq.Scan(symbol.OriginalName, -int32(symbol.UseCountEstimate))\n\t}\n\n\treturn charFreq\n}\n\nfunc (p *parser) generateImportStmt(\n\tpath string,\n\tpathRange logger.Range,\n\timports []string,\n\tparts []js_ast.Part,\n\tsymbols map[string]ast.LocRef,\n\tsourceIndex *uint32,\n\tcopySourceIndex *uint32,\n) ([]js_ast.Part, uint32) {\n\tif pathRange.Len == 0 {\n\t\tisFirst := true\n\t\tfor _, it := range symbols {\n\t\t\tif isFirst || it.Loc.Start < pathRange.Loc.Start {\n\t\t\t\tpathRange.Loc = it.Loc\n\t\t\t}\n\t\t\tisFirst = false\n\t\t}\n\t}\n\n\tnamespaceRef := p.newSymbol(ast.SymbolOther, \"import_\"+js_ast.GenerateNonUniqueNameFromPath(path))\n\tp.moduleScope.Generated = append(p.moduleScope.Generated, namespaceRef)\n\tdeclaredSymbols := make([]js_ast.DeclaredSymbol, 1+len(imports))\n\tclauseItems := make([]js_ast.ClauseItem, len(imports))\n\timportRecordIndex := p.addImportRecord(ast.ImportStmt, ast.EvaluationPhase, pathRange, path, nil, 0)\n\tif sourceIndex != nil {\n\t\tp.importRecords[importRecordIndex].SourceIndex = ast.MakeIndex32(*sourceIndex)\n\t}\n\tif copySourceIndex != nil {\n\t\tp.importRecords[importRecordIndex].CopySourceIndex = ast.MakeIndex32(*copySourceIndex)\n\t}\n\tdeclaredSymbols[0] = js_ast.DeclaredSymbol{Ref: namespaceRef, IsTopLevel: true}\n\n\t// Create per-import information\n\tfor i, alias := range imports {\n\t\tit := symbols[alias]\n\t\tdeclaredSymbols[i+1] = js_ast.DeclaredSymbol{Ref: it.Ref, IsTopLevel: true}\n\t\tclauseItems[i] = js_ast.ClauseItem{\n\t\t\tAlias:    alias,\n\t\t\tAliasLoc: it.Loc,\n\t\t\tName:     ast.LocRef{Loc: it.Loc, Ref: it.Ref},\n\t\t}\n\t\tp.isImportItem[it.Ref] = true\n\t\tp.namedImports[it.Ref] = js_ast.NamedImport{\n\t\t\tAlias:             alias,\n\t\t\tAliasLoc:          it.Loc,\n\t\t\tNamespaceRef:      namespaceRef,\n\t\t\tImportRecordIndex: importRecordIndex,\n\t\t}\n\t}\n\n\t// Append a single import to the end of the file (ES6 imports are hoisted\n\t// so we don't need to worry about where the import statement goes)\n\treturn append(parts, js_ast.Part{\n\t\tDeclaredSymbols:     declaredSymbols,\n\t\tImportRecordIndices: []uint32{importRecordIndex},\n\t\tStmts: []js_ast.Stmt{{Loc: pathRange.Loc, Data: &js_ast.SImport{\n\t\t\tNamespaceRef:      namespaceRef,\n\t\t\tItems:             &clauseItems,\n\t\t\tImportRecordIndex: importRecordIndex,\n\t\t\tIsSingleLine:      true,\n\t\t}}},\n\t}), importRecordIndex\n}\n\n// Sort the keys for determinism\nfunc sortedKeysOfMapStringLocRef(in map[string]ast.LocRef) []string {\n\tkeys := make([]string, 0, len(in))\n\tfor key := range in {\n\t\tkeys = append(keys, key)\n\t}\n\tsort.Strings(keys)\n\treturn keys\n}\n\nfunc (p *parser) toAST(before, parts, after []js_ast.Part, hashbang string, directives []string) js_ast.AST {\n\t// Insert an import statement for any runtime imports we generated\n\tif len(p.runtimeImports) > 0 && !p.options.omitRuntimeForTests {\n\t\tkeys := sortedKeysOfMapStringLocRef(p.runtimeImports)\n\t\tsourceIndex := runtime.SourceIndex\n\t\tbefore, _ = p.generateImportStmt(\"<runtime>\", logger.Range{}, keys, before, p.runtimeImports, &sourceIndex, nil)\n\t}\n\n\t// Insert an import statement for any jsx runtime imports we generated\n\tif len(p.jsxRuntimeImports) > 0 && !p.options.omitJSXRuntimeForTests {\n\t\tkeys := sortedKeysOfMapStringLocRef(p.jsxRuntimeImports)\n\n\t\t// Determine the runtime source and whether it's prod or dev\n\t\tpath := p.options.jsx.ImportSource\n\t\tif p.options.jsx.Development {\n\t\t\tpath = path + \"/jsx-dev-runtime\"\n\t\t} else {\n\t\t\tpath = path + \"/jsx-runtime\"\n\t\t}\n\n\t\tbefore, _ = p.generateImportStmt(path, logger.Range{}, keys, before, p.jsxRuntimeImports, nil, nil)\n\t}\n\n\t// Insert an import statement for any legacy jsx imports we generated (i.e., createElement)\n\tif len(p.jsxLegacyImports) > 0 && !p.options.omitJSXRuntimeForTests {\n\t\tkeys := sortedKeysOfMapStringLocRef(p.jsxLegacyImports)\n\t\tpath := p.options.jsx.ImportSource\n\t\tbefore, _ = p.generateImportStmt(path, logger.Range{}, keys, before, p.jsxLegacyImports, nil, nil)\n\t}\n\n\t// Insert imports for each glob pattern\n\tfor _, glob := range p.globPatternImports {\n\t\tsymbols := map[string]ast.LocRef{glob.name: {Loc: glob.approximateRange.Loc, Ref: glob.ref}}\n\t\tvar importRecordIndex uint32\n\t\tbefore, importRecordIndex = p.generateImportStmt(helpers.GlobPatternToString(glob.parts), glob.approximateRange, []string{glob.name}, before, symbols, nil, nil)\n\t\trecord := &p.importRecords[importRecordIndex]\n\t\trecord.AssertOrWith = glob.assertOrWith\n\t\trecord.Phase = glob.phase\n\t\trecord.GlobPattern = &ast.GlobPattern{\n\t\t\tParts:       glob.parts,\n\t\t\tExportAlias: glob.name,\n\t\t\tKind:        glob.kind,\n\t\t}\n\t}\n\n\t// Generated imports are inserted before other code instead of appending them\n\t// to the end of the file. Appending them should work fine because JavaScript\n\t// import statements are \"hoisted\" to run before the importing file. However,\n\t// some buggy JavaScript toolchains such as the TypeScript compiler convert\n\t// ESM into CommonJS by replacing \"import\" statements inline without doing\n\t// any hoisting, which is incorrect. See the following issue for more info:\n\t// https://github.com/microsoft/TypeScript/issues/16166. Since JSX-related\n\t// imports are present in the generated code when bundling is disabled, and\n\t// could therefore be processed by these buggy tools, it's more robust to put\n\t// them at the top even though it means potentially reallocating almost the\n\t// entire array of parts.\n\tif len(before) > 0 {\n\t\tparts = append(before, parts...)\n\t}\n\tparts = append(parts, after...)\n\n\t// Handle import paths after the whole file has been visited because we need\n\t// symbol usage counts to be able to remove unused type-only imports in\n\t// TypeScript code.\n\tkeptImportEquals := false\n\tremovedImportEquals := false\n\tpartsEnd := 0\n\tfor partIndex, part := range parts {\n\t\tp.importRecordsForCurrentPart = nil\n\t\tp.declaredSymbols = nil\n\n\t\tresult := p.scanForImportsAndExports(part.Stmts)\n\t\tpart.Stmts = result.stmts\n\t\tkeptImportEquals = keptImportEquals || result.keptImportEquals\n\t\tremovedImportEquals = removedImportEquals || result.removedImportEquals\n\n\t\tpart.ImportRecordIndices = append(part.ImportRecordIndices, p.importRecordsForCurrentPart...)\n\t\tpart.DeclaredSymbols = append(part.DeclaredSymbols, p.declaredSymbols...)\n\n\t\tif len(part.Stmts) > 0 || uint32(partIndex) == js_ast.NSExportPartIndex {\n\t\t\tif p.moduleScope.ContainsDirectEval && len(part.DeclaredSymbols) > 0 {\n\t\t\t\t// If this file contains a direct call to \"eval()\", all parts that\n\t\t\t\t// declare top-level symbols must be kept since the eval'd code may\n\t\t\t\t// reference those symbols.\n\t\t\t\tpart.CanBeRemovedIfUnused = false\n\t\t\t}\n\t\t\tparts[partsEnd] = part\n\t\t\tpartsEnd++\n\t\t}\n\t}\n\tparts = parts[:partsEnd]\n\n\t// We need to iterate multiple times if an import-equals statement was\n\t// removed and there are more import-equals statements that may be removed.\n\t// In the example below, a/b/c should be kept but x/y/z should be removed\n\t// (and removal requires multiple passes):\n\t//\n\t//   import a = foo.a\n\t//   import b = a.b\n\t//   import c = b.c\n\t//\n\t//   import x = foo.x\n\t//   import y = x.y\n\t//   import z = y.z\n\t//\n\t//   export let bar = c\n\t//\n\t// This is a smaller version of the general import/export scanning loop above.\n\t// We only want to repeat the code that eliminates TypeScript import-equals\n\t// statements, not the other code in the loop above.\n\tfor keptImportEquals && removedImportEquals {\n\t\tkeptImportEquals = false\n\t\tremovedImportEquals = false\n\t\tpartsEnd := 0\n\t\tfor partIndex, part := range parts {\n\t\t\tresult := p.scanForUnusedTSImportEquals(part.Stmts)\n\t\t\tpart.Stmts = result.stmts\n\t\t\tkeptImportEquals = keptImportEquals || result.keptImportEquals\n\t\t\tremovedImportEquals = removedImportEquals || result.removedImportEquals\n\t\t\tif len(part.Stmts) > 0 || uint32(partIndex) == js_ast.NSExportPartIndex {\n\t\t\t\tparts[partsEnd] = part\n\t\t\t\tpartsEnd++\n\t\t\t}\n\t\t}\n\t\tparts = parts[:partsEnd]\n\t}\n\n\t// Do a second pass for exported items now that imported items are filled out\n\tfor _, part := range parts {\n\t\tfor _, stmt := range part.Stmts {\n\t\t\tif s, ok := stmt.Data.(*js_ast.SExportClause); ok {\n\t\t\t\tfor _, item := range s.Items {\n\t\t\t\t\t// Mark re-exported imports as such\n\t\t\t\t\tif namedImport, ok := p.namedImports[item.Name.Ref]; ok {\n\t\t\t\t\t\tnamedImport.IsExported = true\n\t\t\t\t\t\tp.namedImports[item.Name.Ref] = namedImport\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Analyze cross-part dependencies for tree shaking and code splitting\n\t{\n\t\t// Map locals to parts\n\t\tp.topLevelSymbolToParts = make(map[ast.Ref][]uint32)\n\t\tfor partIndex, part := range parts {\n\t\t\tfor _, declared := range part.DeclaredSymbols {\n\t\t\t\tif declared.IsTopLevel {\n\t\t\t\t\t// If this symbol was merged, use the symbol at the end of the\n\t\t\t\t\t// linked list in the map. This is the case for multiple \"var\"\n\t\t\t\t\t// declarations with the same name, for example.\n\t\t\t\t\tref := declared.Ref\n\t\t\t\t\tfor p.symbols[ref.InnerIndex].Link != ast.InvalidRef {\n\t\t\t\t\t\tref = p.symbols[ref.InnerIndex].Link\n\t\t\t\t\t}\n\t\t\t\t\tp.topLevelSymbolToParts[ref] = append(\n\t\t\t\t\t\tp.topLevelSymbolToParts[ref], uint32(partIndex))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Pulling in the exports of this module always pulls in the export part\n\t\tp.topLevelSymbolToParts[p.exportsRef] = append(p.topLevelSymbolToParts[p.exportsRef], js_ast.NSExportPartIndex)\n\t}\n\n\t// Make a wrapper symbol in case we need to be wrapped in a closure\n\twrapperRef := p.newSymbol(ast.SymbolOther, \"require_\"+p.source.IdentifierName)\n\n\t// Assign slots to symbols in nested scopes. This is some precomputation for\n\t// the symbol renaming pass that will happen later in the linker. It's done\n\t// now in the parser because we want it to be done in parallel per file and\n\t// we're already executing code in a dedicated goroutine for this file.\n\tvar nestedScopeSlotCounts ast.SlotCounts\n\tif p.options.minifyIdentifiers {\n\t\tnestedScopeSlotCounts = renamer.AssignNestedScopeSlots(p.moduleScope, p.symbols)\n\t}\n\n\texportsKind := js_ast.ExportsNone\n\tusesExportsRef := p.symbols[p.exportsRef.InnerIndex].UseCountEstimate > 0\n\tusesModuleRef := p.symbols[p.moduleRef.InnerIndex].UseCountEstimate > 0\n\n\tif p.esmExportKeyword.Len > 0 || p.esmImportMeta.Len > 0 || p.topLevelAwaitKeyword.Len > 0 {\n\t\texportsKind = js_ast.ExportsESM\n\t} else if usesExportsRef || usesModuleRef || p.hasTopLevelReturn {\n\t\texportsKind = js_ast.ExportsCommonJS\n\t} else {\n\t\t// If this module has no exports, try to determine what kind of module it\n\t\t// is by looking at node's \"type\" field in \"package.json\" and/or whether\n\t\t// the file extension is \".mjs\"/\".mts\" or \".cjs\"/\".cts\".\n\t\tswitch {\n\t\tcase p.options.moduleTypeData.Type.IsCommonJS():\n\t\t\t// \".cjs\" or \".cts\" or (\"type: commonjs\" and (\".js\" or \".jsx\" or \".ts\" or \".tsx\"))\n\t\t\texportsKind = js_ast.ExportsCommonJS\n\n\t\tcase p.options.moduleTypeData.Type.IsESM():\n\t\t\t// \".mjs\" or \".mts\" or (\"type: module\" and (\".js\" or \".jsx\" or \".ts\" or \".tsx\"))\n\t\t\texportsKind = js_ast.ExportsESM\n\n\t\tdefault:\n\t\t\t// Treat unknown modules containing an import statement as ESM. Otherwise\n\t\t\t// the bundler will treat this file as CommonJS if it's imported and ESM\n\t\t\t// if it's not imported.\n\t\t\tif p.esmImportStatementKeyword.Len > 0 {\n\t\t\t\texportsKind = js_ast.ExportsESM\n\t\t\t}\n\t\t}\n\t}\n\n\treturn js_ast.AST{\n\t\tParts:                           parts,\n\t\tModuleTypeData:                  p.options.moduleTypeData,\n\t\tModuleScope:                     p.moduleScope,\n\t\tCharFreq:                        p.computeCharacterFrequency(),\n\t\tSymbols:                         p.symbols,\n\t\tExportsRef:                      p.exportsRef,\n\t\tModuleRef:                       p.moduleRef,\n\t\tWrapperRef:                      wrapperRef,\n\t\tHashbang:                        hashbang,\n\t\tDirectives:                      directives,\n\t\tNamedImports:                    p.namedImports,\n\t\tNamedExports:                    p.namedExports,\n\t\tTSEnums:                         p.tsEnums,\n\t\tConstValues:                     p.constValues,\n\t\tExprComments:                    p.exprComments,\n\t\tNestedScopeSlotCounts:           nestedScopeSlotCounts,\n\t\tTopLevelSymbolToPartsFromParser: p.topLevelSymbolToParts,\n\t\tExportStarImportRecords:         p.exportStarImportRecords,\n\t\tImportRecords:                   p.importRecords,\n\t\tApproximateLineCount:            int32(p.lexer.ApproximateNewlineCount) + 1,\n\t\tMangledProps:                    p.mangledProps,\n\t\tReservedProps:                   p.reservedProps,\n\t\tManifestForYarnPnP:              p.manifestForYarnPnP,\n\n\t\t// CommonJS features\n\t\tUsesExportsRef: usesExportsRef,\n\t\tUsesModuleRef:  usesModuleRef,\n\t\tExportsKind:    exportsKind,\n\n\t\t// ES6 features\n\t\tExportKeyword:            p.esmExportKeyword,\n\t\tTopLevelAwaitKeyword:     p.topLevelAwaitKeyword,\n\t\tLiveTopLevelAwaitKeyword: p.liveTopLevelAwaitKeyword,\n\t}\n}\n"
  },
  {
    "path": "internal/js_parser/js_parser_lower.go",
    "content": "// This file contains code for \"lowering\" syntax, which means converting it to\n// older JavaScript. For example, \"a ** b\" becomes a call to \"Math.pow(a, b)\"\n// when lowered. Which syntax is lowered is determined by the language target.\n\npackage js_parser\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\nfunc (p *parser) markSyntaxFeature(feature compat.JSFeature, r logger.Range) (didGenerateError bool) {\n\tdidGenerateError = true\n\n\tif !p.options.unsupportedJSFeatures.Has(feature) {\n\t\tif feature == compat.TopLevelAwait && !p.options.outputFormat.KeepESMImportExportSyntax() {\n\t\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\n\t\t\t\t\"Top-level await is currently not supported with the %q output format\", p.options.outputFormat.String()))\n\t\t\treturn\n\t\t}\n\n\t\tdidGenerateError = false\n\t\treturn\n\t}\n\n\tvar name string\n\twhere := config.PrettyPrintTargetEnvironment(p.options.originalTargetEnv, p.options.unsupportedJSFeatureOverridesMask)\n\n\tswitch feature {\n\tcase compat.DefaultArgument:\n\t\tname = \"default arguments\"\n\n\tcase compat.RestArgument:\n\t\tname = \"rest arguments\"\n\n\tcase compat.ArraySpread:\n\t\tname = \"array spread\"\n\n\tcase compat.ForOf:\n\t\tname = \"for-of loops\"\n\n\tcase compat.ObjectAccessors:\n\t\tname = \"object accessors\"\n\n\tcase compat.ObjectExtensions:\n\t\tname = \"object literal extensions\"\n\n\tcase compat.Destructuring:\n\t\tname = \"destructuring\"\n\n\tcase compat.NewTarget:\n\t\tname = \"new.target\"\n\n\tcase compat.ConstAndLet:\n\t\tname = p.source.TextForRange(r)\n\n\tcase compat.Class:\n\t\tname = \"class syntax\"\n\n\tcase compat.Generator:\n\t\tname = \"generator functions\"\n\n\tcase compat.AsyncAwait:\n\t\tname = \"async functions\"\n\n\tcase compat.AsyncGenerator:\n\t\tname = \"async generator functions\"\n\n\tcase compat.ForAwait:\n\t\tname = \"for-await loops\"\n\n\tcase compat.NestedRestBinding:\n\t\tname = \"non-identifier array rest patterns\"\n\n\tcase compat.ImportAttributes:\n\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\n\t\t\t\"Using an arbitrary value as the second argument to \\\"import()\\\" is not possible in %s\", where))\n\t\treturn\n\n\tcase compat.TopLevelAwait:\n\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\n\t\t\t\"Top-level await is not available in %s\", where))\n\t\treturn\n\n\tcase compat.ImportDefer:\n\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\n\t\t\t\"Deferred imports are not available in %s\", where))\n\t\treturn\n\n\tcase compat.ImportSource:\n\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\n\t\t\t\"Source phase imports are not available in %s\", where))\n\t\treturn\n\n\tcase compat.Bigint:\n\t\t// This can't be polyfilled\n\t\tkind := logger.Warning\n\t\tif p.suppressWarningsAboutWeirdCode || p.fnOrArrowDataVisit.tryBodyCount > 0 {\n\t\t\tkind = logger.Debug\n\t\t}\n\t\tp.log.AddID(logger.MsgID_JS_BigInt, kind, &p.tracker, r, fmt.Sprintf(\n\t\t\t\"Big integer literals are not available in %s and may crash at run-time\", where))\n\t\treturn\n\n\tcase compat.ImportMeta:\n\t\t// This can't be polyfilled\n\t\tkind := logger.Warning\n\t\tif p.suppressWarningsAboutWeirdCode || p.fnOrArrowDataVisit.tryBodyCount > 0 {\n\t\t\tkind = logger.Debug\n\t\t}\n\t\tp.log.AddID(logger.MsgID_JS_EmptyImportMeta, kind, &p.tracker, r, fmt.Sprintf(\n\t\t\t\"\\\"import.meta\\\" is not available in %s and will be empty\", where))\n\t\treturn\n\n\tdefault:\n\t\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\n\t\t\t\"This feature is not available in %s\", where))\n\t\treturn\n\t}\n\n\tp.log.AddError(&p.tracker, r, fmt.Sprintf(\n\t\t\"Transforming %s to %s is not supported yet\", name, where))\n\treturn\n}\n\nfunc (p *parser) isStrictMode() bool {\n\treturn p.currentScope.StrictMode != js_ast.SloppyMode\n}\n\nfunc (p *parser) isStrictModeOutputFormat() bool {\n\treturn p.options.outputFormat == config.FormatESModule\n}\n\ntype strictModeFeature uint8\n\nconst (\n\twithStatement strictModeFeature = iota\n\tdeleteBareName\n\tforInVarInit\n\tevalOrArguments\n\treservedWord\n\tlegacyOctalLiteral\n\tlegacyOctalEscape\n\tifElseFunctionStmt\n\tlabelFunctionStmt\n\tduplicateLexicallyDeclaredNames\n)\n\nfunc (p *parser) markStrictModeFeature(feature strictModeFeature, r logger.Range, detail string) {\n\tvar text string\n\tcanBeTransformed := false\n\n\tswitch feature {\n\tcase withStatement:\n\t\ttext = \"With statements\"\n\n\tcase deleteBareName:\n\t\ttext = \"Delete of a bare identifier\"\n\n\tcase forInVarInit:\n\t\ttext = \"Variable initializers inside for-in loops\"\n\t\tcanBeTransformed = true\n\n\tcase evalOrArguments:\n\t\ttext = fmt.Sprintf(\"Declarations with the name %q\", detail)\n\n\tcase reservedWord:\n\t\ttext = fmt.Sprintf(\"%q is a reserved word and\", detail)\n\n\tcase legacyOctalLiteral:\n\t\ttext = \"Legacy octal literals\"\n\n\tcase legacyOctalEscape:\n\t\ttext = \"Legacy octal escape sequences\"\n\n\tcase ifElseFunctionStmt:\n\t\ttext = \"Function declarations inside if statements\"\n\n\tcase labelFunctionStmt:\n\t\ttext = \"Function declarations inside labels\"\n\n\tcase duplicateLexicallyDeclaredNames:\n\t\ttext = \"Duplicate lexically-declared names\"\n\n\tdefault:\n\t\ttext = \"This feature\"\n\t}\n\n\tif p.isStrictMode() {\n\t\twhere, notes := p.whyStrictMode(p.currentScope)\n\t\tp.log.AddErrorWithNotes(&p.tracker, r,\n\t\t\tfmt.Sprintf(\"%s cannot be used %s\", text, where), notes)\n\t} else if !canBeTransformed && p.isStrictModeOutputFormat() {\n\t\tp.log.AddError(&p.tracker, r,\n\t\t\tfmt.Sprintf(\"%s cannot be used with the \\\"esm\\\" output format due to strict mode\", text))\n\t}\n}\n\nfunc (p *parser) whyStrictMode(scope *js_ast.Scope) (where string, notes []logger.MsgData) {\n\twhere = \"in strict mode\"\n\n\tswitch scope.StrictMode {\n\tcase js_ast.ImplicitStrictModeClass:\n\t\tnotes = []logger.MsgData{p.tracker.MsgData(p.enclosingClassKeyword,\n\t\t\t\"All code inside a class is implicitly in strict mode\")}\n\n\tcase js_ast.ImplicitStrictModeTSAlwaysStrict:\n\t\ttsAlwaysStrict := p.options.tsAlwaysStrict\n\t\tt := logger.MakeLineColumnTracker(&tsAlwaysStrict.Source)\n\t\tnotes = []logger.MsgData{t.MsgData(tsAlwaysStrict.Range, fmt.Sprintf(\n\t\t\t\"TypeScript's %q setting was enabled here:\", tsAlwaysStrict.Name))}\n\n\tcase js_ast.ImplicitStrictModeJSXAutomaticRuntime:\n\t\tnotes = []logger.MsgData{p.tracker.MsgData(logger.Range{Loc: p.firstJSXElementLoc, Len: 1},\n\t\t\t\"This file is implicitly in strict mode due to the JSX element here:\"),\n\t\t\t{Text: \"When React's \\\"automatic\\\" JSX transform is enabled, using a JSX element automatically inserts \" +\n\t\t\t\t\"an \\\"import\\\" statement at the top of the file for the corresponding the JSX helper function. \" +\n\t\t\t\t\"This means the file is considered an ECMAScript module, and all ECMAScript modules use strict mode.\"}}\n\n\tcase js_ast.ExplicitStrictMode:\n\t\tnotes = []logger.MsgData{p.tracker.MsgData(p.source.RangeOfString(scope.UseStrictLoc),\n\t\t\t\"Strict mode is triggered by the \\\"use strict\\\" directive here:\")}\n\n\tcase js_ast.ImplicitStrictModeESM:\n\t\t_, notes = p.whyESModule()\n\t\twhere = \"in an ECMAScript module\"\n\t}\n\n\treturn\n}\n\nfunc (p *parser) markAsyncFn(asyncRange logger.Range, isGenerator bool) (didGenerateError bool) {\n\t// Lowered async functions are implemented in terms of generators. So if\n\t// generators aren't supported, async functions aren't supported either.\n\t// But if generators are supported, then async functions are unconditionally\n\t// supported because we can use generators to implement them.\n\tif !p.options.unsupportedJSFeatures.Has(compat.Generator) {\n\t\treturn false\n\t}\n\n\tfeature := compat.AsyncAwait\n\tif isGenerator {\n\t\tfeature = compat.AsyncGenerator\n\t}\n\treturn p.markSyntaxFeature(feature, asyncRange)\n}\n\nfunc (p *parser) captureThis() ast.Ref {\n\tif p.fnOnlyDataVisit.thisCaptureRef == nil {\n\t\tref := p.newSymbol(ast.SymbolHoisted, \"_this\")\n\t\tp.fnOnlyDataVisit.thisCaptureRef = &ref\n\t}\n\n\tref := *p.fnOnlyDataVisit.thisCaptureRef\n\tp.recordUsage(ref)\n\treturn ref\n}\n\nfunc (p *parser) captureArguments() ast.Ref {\n\tif p.fnOnlyDataVisit.argumentsCaptureRef == nil {\n\t\tref := p.newSymbol(ast.SymbolHoisted, \"_arguments\")\n\t\tp.fnOnlyDataVisit.argumentsCaptureRef = &ref\n\t}\n\n\tref := *p.fnOnlyDataVisit.argumentsCaptureRef\n\tp.recordUsage(ref)\n\treturn ref\n}\n\nfunc (p *parser) lowerFunction(\n\tisAsync *bool,\n\tisGenerator *bool,\n\targs *[]js_ast.Arg,\n\tbodyLoc logger.Loc,\n\tbodyBlock *js_ast.SBlock,\n\tpreferExpr *bool,\n\thasRestArg *bool,\n\tisArrow bool,\n) {\n\t// Lower object rest binding patterns in function arguments\n\tif p.options.unsupportedJSFeatures.Has(compat.ObjectRestSpread) {\n\t\tvar prefixStmts []js_ast.Stmt\n\n\t\t// Lower each argument individually instead of lowering all arguments\n\t\t// together. There is a correctness tradeoff here around default values\n\t\t// for function arguments, with no right answer.\n\t\t//\n\t\t// Lowering all arguments together will preserve the order of side effects\n\t\t// for default values, but will mess up their scope:\n\t\t//\n\t\t//   // Side effect order: a(), b(), c()\n\t\t//   function foo([{[a()]: w, ...x}, y = b()], z = c()) {}\n\t\t//\n\t\t//   // Side effect order is correct but scope is wrong\n\t\t//   function foo(_a, _b) {\n\t\t//     var [[{[a()]: w, ...x}, y = b()], z = c()] = [_a, _b]\n\t\t//   }\n\t\t//\n\t\t// Lowering each argument individually will preserve the scope for default\n\t\t// values that don't contain object rest binding patterns, but will mess up\n\t\t// the side effect order:\n\t\t//\n\t\t//   // Side effect order: a(), b(), c()\n\t\t//   function foo([{[a()]: w, ...x}, y = b()], z = c()) {}\n\t\t//\n\t\t//   // Side effect order is wrong but scope for c() is correct\n\t\t//   function foo(_a, z = c()) {\n\t\t//     var [{[a()]: w, ...x}, y = b()] = _a\n\t\t//   }\n\t\t//\n\t\t// This transform chooses to lower each argument individually with the\n\t\t// thinking that perhaps scope matters more in real-world code than side\n\t\t// effect order.\n\t\tfor i, arg := range *args {\n\t\t\tif bindingHasObjectRest(arg.Binding) {\n\t\t\t\tref := p.generateTempRef(tempRefNoDeclare, \"\")\n\t\t\t\ttarget := js_ast.ConvertBindingToExpr(arg.Binding, nil)\n\t\t\t\tinit := js_ast.Expr{Loc: arg.Binding.Loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\t\t\t\tp.recordUsage(ref)\n\n\t\t\t\tif decls, ok := p.lowerObjectRestToDecls(target, init, nil); ok {\n\t\t\t\t\t// Replace the binding but leave the default value intact\n\t\t\t\t\t(*args)[i].Binding.Data = &js_ast.BIdentifier{Ref: ref}\n\n\t\t\t\t\t// Append a variable declaration to the function body\n\t\t\t\t\tprefixStmts = append(prefixStmts, js_ast.Stmt{Loc: arg.Binding.Loc,\n\t\t\t\t\t\tData: &js_ast.SLocal{Kind: js_ast.LocalVar, Decls: decls}})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif len(prefixStmts) > 0 {\n\t\t\tbodyBlock.Stmts = append(prefixStmts, bodyBlock.Stmts...)\n\t\t}\n\t}\n\n\t// Lower async functions and async generator functions\n\tif *isAsync && (p.options.unsupportedJSFeatures.Has(compat.AsyncAwait) || (isGenerator != nil && *isGenerator && p.options.unsupportedJSFeatures.Has(compat.AsyncGenerator))) {\n\t\t// Use the shortened form if we're an arrow function\n\t\tif preferExpr != nil {\n\t\t\t*preferExpr = true\n\t\t}\n\n\t\t// Determine the value for \"this\"\n\t\tthisValue, hasThisValue := p.valueForThis(\n\t\t\tbodyLoc,\n\t\t\tfalse, /* shouldWarn */\n\t\t\tjs_ast.AssignTargetNone,\n\t\t\tfalse, /* isCallTarget */\n\t\t\tfalse, /* isDeleteTarget */\n\t\t)\n\n\t\tif isArrow && !p.fnOnlyDataVisit.hasThisUsage {\n\t\t\tthisValue = js_ast.Expr{Loc: bodyLoc, Data: js_ast.ENullShared}\n\t\t} else if !hasThisValue {\n\t\t\tthisValue = js_ast.Expr{Loc: bodyLoc, Data: js_ast.EThisShared}\n\t\t}\n\n\t\t// Move the code into a nested generator function\n\t\tfn := js_ast.Fn{\n\t\t\tIsGenerator: true,\n\t\t\tBody:        js_ast.FnBody{Loc: bodyLoc, Block: *bodyBlock},\n\t\t}\n\t\tbodyBlock.Stmts = nil\n\n\t\t// Errors thrown during argument evaluation must reject the\n\t\t// resulting promise, which needs more complex code to handle\n\t\tcouldThrowErrors := false\n\t\tfor _, arg := range *args {\n\t\t\tif _, ok := arg.Binding.Data.(*js_ast.BIdentifier); !ok ||\n\t\t\t\t(arg.DefaultOrNil.Data != nil && couldPotentiallyThrow(arg.DefaultOrNil.Data)) {\n\t\t\t\tcouldThrowErrors = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Forward the arguments to the wrapper function\n\t\tusesArgumentsRef := !isArrow && p.fnOnlyDataVisit.argumentsRef != nil &&\n\t\t\tp.symbolUses[*p.fnOnlyDataVisit.argumentsRef].CountEstimate > 0\n\t\tvar forwardedArgs js_ast.Expr\n\t\tif !couldThrowErrors && !usesArgumentsRef {\n\t\t\t// Simple case: the arguments can stay on the outer function. It's\n\t\t\t// worth separating out the simple case because it's the common case\n\t\t\t// and it generates smaller code.\n\t\t\tforwardedArgs = js_ast.Expr{Loc: bodyLoc, Data: js_ast.ENullShared}\n\t\t} else {\n\t\t\t// If code uses \"arguments\" then we must move the arguments to the inner\n\t\t\t// function. This is because you can modify arguments by assigning to\n\t\t\t// elements in the \"arguments\" object:\n\t\t\t//\n\t\t\t//   async function foo(x) {\n\t\t\t//     arguments[0] = 1;\n\t\t\t//     // \"x\" must be 1 here\n\t\t\t//   }\n\t\t\t//\n\n\t\t\t// Complex case: the arguments must be moved to the inner function\n\t\t\tfn.Args = *args\n\t\t\tfn.HasRestArg = *hasRestArg\n\t\t\t*args = nil\n\t\t\t*hasRestArg = false\n\n\t\t\t// Make sure to not change the value of the \"length\" property. This is\n\t\t\t// done by generating dummy arguments for the outer function equal to\n\t\t\t// the expected length of the function:\n\t\t\t//\n\t\t\t//   async function foo(a, b, c = d, ...e) {\n\t\t\t//   }\n\t\t\t//\n\t\t\t// This turns into:\n\t\t\t//\n\t\t\t//   function foo(_0, _1) {\n\t\t\t//     return __async(this, arguments, function* (a, b, c = d, ...e) {\n\t\t\t//     });\n\t\t\t//   }\n\t\t\t//\n\t\t\t// The \"_0\" and \"_1\" are dummy variables to ensure \"foo.length\" is 2.\n\t\t\tfor i, arg := range fn.Args {\n\t\t\t\tif arg.DefaultOrNil.Data != nil || fn.HasRestArg && i+1 == len(fn.Args) {\n\t\t\t\t\t// Arguments from here on don't add to the \"length\"\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// Generate a dummy variable\n\t\t\t\targRef := p.newSymbol(ast.SymbolOther, fmt.Sprintf(\"_%d\", i))\n\t\t\t\tp.currentScope.Generated = append(p.currentScope.Generated, argRef)\n\t\t\t\t*args = append(*args, js_ast.Arg{Binding: js_ast.Binding{Loc: arg.Binding.Loc, Data: &js_ast.BIdentifier{Ref: argRef}}})\n\t\t\t}\n\n\t\t\t// Forward all arguments from the outer function to the inner function\n\t\t\tif !isArrow {\n\t\t\t\t// Normal functions can just use \"arguments\" to forward everything\n\t\t\t\tforwardedArgs = js_ast.Expr{Loc: bodyLoc, Data: &js_ast.EIdentifier{Ref: *p.fnOnlyDataVisit.argumentsRef}}\n\t\t\t} else {\n\t\t\t\t// Arrow functions can't use \"arguments\", so we need to forward\n\t\t\t\t// the arguments manually.\n\t\t\t\t//\n\t\t\t\t// Note that if the arrow function references \"arguments\" in its body\n\t\t\t\t// (even if it's inside another nested arrow function), that reference\n\t\t\t\t// to \"arguments\" will have to be substituted with a captured variable.\n\t\t\t\t// This is because we're changing the arrow function into a generator\n\t\t\t\t// function, which introduces a variable named \"arguments\". This is\n\t\t\t\t// handled separately during symbol resolution instead of being handled\n\t\t\t\t// here so we don't need to re-traverse the arrow function body.\n\n\t\t\t\t// If we need to forward more than the current number of arguments,\n\t\t\t\t// add a rest argument to the set of forwarding variables. This is the\n\t\t\t\t// case if the arrow function has rest or default arguments.\n\t\t\t\tif len(*args) < len(fn.Args) {\n\t\t\t\t\targRef := p.newSymbol(ast.SymbolOther, fmt.Sprintf(\"_%d\", len(*args)))\n\t\t\t\t\tp.currentScope.Generated = append(p.currentScope.Generated, argRef)\n\t\t\t\t\t*args = append(*args, js_ast.Arg{Binding: js_ast.Binding{Loc: bodyLoc, Data: &js_ast.BIdentifier{Ref: argRef}}})\n\t\t\t\t\t*hasRestArg = true\n\t\t\t\t}\n\n\t\t\t\t// Forward all of the arguments\n\t\t\t\titems := make([]js_ast.Expr, 0, len(*args))\n\t\t\t\tfor i, arg := range *args {\n\t\t\t\t\tid := arg.Binding.Data.(*js_ast.BIdentifier)\n\t\t\t\t\titem := js_ast.Expr{Loc: arg.Binding.Loc, Data: &js_ast.EIdentifier{Ref: id.Ref}}\n\t\t\t\t\tif *hasRestArg && i+1 == len(*args) {\n\t\t\t\t\t\titem.Data = &js_ast.ESpread{Value: item}\n\t\t\t\t\t}\n\t\t\t\t\titems = append(items, item)\n\t\t\t\t}\n\t\t\t\tforwardedArgs = js_ast.Expr{Loc: bodyLoc, Data: &js_ast.EArray{Items: items, IsSingleLine: true}}\n\t\t\t}\n\t\t}\n\n\t\tvar name string\n\t\tif isGenerator != nil && *isGenerator {\n\t\t\t// \"async function* foo(a, b) { stmts }\" => \"function foo(a, b) { return __asyncGenerator(this, null, function* () { stmts }) }\"\n\t\t\tname = \"__asyncGenerator\"\n\t\t\t*isGenerator = false\n\t\t} else {\n\t\t\t// \"async function foo(a, b) { stmts }\" => \"function foo(a, b) { return __async(this, null, function* () { stmts }) }\"\n\t\t\tname = \"__async\"\n\t\t}\n\t\t*isAsync = false\n\t\tcallAsync := p.callRuntime(bodyLoc, name, []js_ast.Expr{\n\t\t\tthisValue,\n\t\t\tforwardedArgs,\n\t\t\t{Loc: bodyLoc, Data: &js_ast.EFunction{Fn: fn}},\n\t\t})\n\t\tbodyBlock.Stmts = []js_ast.Stmt{{Loc: bodyLoc, Data: &js_ast.SReturn{ValueOrNil: callAsync}}}\n\t}\n}\n\nfunc (p *parser) lowerOptionalChain(expr js_ast.Expr, in exprIn, childOut exprOut) (js_ast.Expr, exprOut) {\n\tvalueWhenUndefined := js_ast.Expr{Loc: expr.Loc, Data: js_ast.EUndefinedShared}\n\tendsWithPropertyAccess := false\n\tcontainsPrivateName := false\n\tstartsWithCall := false\n\toriginalExpr := expr\n\tchain := []js_ast.Expr{}\n\tloc := expr.Loc\n\n\t// Step 1: Get an array of all expressions in the chain. We're traversing the\n\t// chain from the outside in, so the array will be filled in \"backwards\".\nflatten:\n\tfor {\n\t\tchain = append(chain, expr)\n\n\t\tswitch e := expr.Data.(type) {\n\t\tcase *js_ast.EDot:\n\t\t\texpr = e.Target\n\t\t\tif len(chain) == 1 {\n\t\t\t\tendsWithPropertyAccess = true\n\t\t\t}\n\t\t\tif e.OptionalChain == js_ast.OptionalChainStart {\n\t\t\t\tbreak flatten\n\t\t\t}\n\n\t\tcase *js_ast.EIndex:\n\t\t\texpr = e.Target\n\t\t\tif len(chain) == 1 {\n\t\t\t\tendsWithPropertyAccess = true\n\t\t\t}\n\n\t\t\t// If this is a private name that needs to be lowered, the entire chain\n\t\t\t// itself will have to be lowered even if the language target supports\n\t\t\t// optional chaining. This is because there's no way to use our shim\n\t\t\t// function for private names with optional chaining syntax.\n\t\t\tif private, ok := e.Index.Data.(*js_ast.EPrivateIdentifier); ok && p.privateSymbolNeedsToBeLowered(private) {\n\t\t\t\tcontainsPrivateName = true\n\t\t\t}\n\n\t\t\tif e.OptionalChain == js_ast.OptionalChainStart {\n\t\t\t\tbreak flatten\n\t\t\t}\n\n\t\tcase *js_ast.ECall:\n\t\t\texpr = e.Target\n\t\t\tif e.OptionalChain == js_ast.OptionalChainStart {\n\t\t\t\tstartsWithCall = true\n\t\t\t\tbreak flatten\n\t\t\t}\n\n\t\tcase *js_ast.EUnary: // UnOpDelete\n\t\t\tvalueWhenUndefined = js_ast.Expr{Loc: loc, Data: &js_ast.EBoolean{Value: true}}\n\t\t\texpr = e.Value\n\n\t\tdefault:\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\t}\n\n\t// Stop now if we can strip the whole chain as dead code. Since the chain is\n\t// lazily evaluated, it's safe to just drop the code entirely.\n\tif p.options.minifySyntax {\n\t\tif isNullOrUndefined, sideEffects, ok := js_ast.ToNullOrUndefinedWithSideEffects(expr.Data); ok && isNullOrUndefined {\n\t\t\tif sideEffects == js_ast.CouldHaveSideEffects {\n\t\t\t\treturn js_ast.JoinWithComma(p.astHelpers.SimplifyUnusedExpr(expr, p.options.unsupportedJSFeatures), valueWhenUndefined), exprOut{}\n\t\t\t}\n\t\t\treturn valueWhenUndefined, exprOut{}\n\t\t}\n\t} else {\n\t\tswitch expr.Data.(type) {\n\t\tcase *js_ast.ENull, *js_ast.EUndefined:\n\t\t\treturn valueWhenUndefined, exprOut{}\n\t\t}\n\t}\n\n\t// We need to lower this if this is an optional call off of a private name\n\t// such as \"foo.#bar?.()\" because the value of \"this\" must be captured.\n\tif _, _, private := p.extractPrivateIndex(expr); private != nil {\n\t\tcontainsPrivateName = true\n\t}\n\n\t// Don't lower this if we don't need to. This check must be done here instead\n\t// of earlier so we can do the dead code elimination above when the target is\n\t// null or undefined.\n\tif !p.options.unsupportedJSFeatures.Has(compat.OptionalChain) && !containsPrivateName {\n\t\treturn originalExpr, exprOut{}\n\t}\n\n\t// Step 2: Figure out if we need to capture the value for \"this\" for the\n\t// initial ECall. This will be passed to \".call(this, ...args)\" later.\n\tvar thisArg js_ast.Expr\n\tvar targetWrapFunc func(js_ast.Expr) js_ast.Expr\n\tif startsWithCall {\n\t\tif childOut.thisArgFunc != nil {\n\t\t\t// The initial value is a nested optional chain that ended in a property\n\t\t\t// access. The nested chain was processed first and has saved the\n\t\t\t// appropriate value for \"this\". The callback here will return a\n\t\t\t// reference to that saved location.\n\t\t\tthisArg = childOut.thisArgFunc()\n\t\t} else {\n\t\t\t// The initial value is a normal expression. If it's a property access,\n\t\t\t// strip the property off and save the target of the property access to\n\t\t\t// be used as the value for \"this\".\n\t\t\tswitch e := expr.Data.(type) {\n\t\t\tcase *js_ast.EDot:\n\t\t\t\tif _, ok := e.Target.Data.(*js_ast.ESuper); ok {\n\t\t\t\t\t// Lower \"super.prop\" if necessary\n\t\t\t\t\tif p.shouldLowerSuperPropertyAccess(e.Target) {\n\t\t\t\t\t\tkey := js_ast.Expr{Loc: e.NameLoc, Data: &js_ast.EString{Value: helpers.StringToUTF16(e.Name)}}\n\t\t\t\t\t\texpr = p.lowerSuperPropertyGet(expr.Loc, key)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Special-case \"super.foo?.()\" to avoid a syntax error. Without this,\n\t\t\t\t\t// we would generate:\n\t\t\t\t\t//\n\t\t\t\t\t//   (_b = (_a = super).foo) == null ? void 0 : _b.call(_a)\n\t\t\t\t\t//\n\t\t\t\t\t// which is a syntax error. Now we generate this instead:\n\t\t\t\t\t//\n\t\t\t\t\t//   (_a = super.foo) == null ? void 0 : _a.call(this)\n\t\t\t\t\t//\n\t\t\t\t\tthisArg = js_ast.Expr{Loc: loc, Data: js_ast.EThisShared}\n\t\t\t\t} else {\n\t\t\t\t\ttargetFunc, wrapFunc := p.captureValueWithPossibleSideEffects(loc, 2, e.Target, valueDefinitelyNotMutated)\n\t\t\t\t\texpr = js_ast.Expr{Loc: loc, Data: &js_ast.EDot{\n\t\t\t\t\t\tTarget:  targetFunc(),\n\t\t\t\t\t\tName:    e.Name,\n\t\t\t\t\t\tNameLoc: e.NameLoc,\n\t\t\t\t\t}}\n\t\t\t\t\tthisArg = targetFunc()\n\t\t\t\t\ttargetWrapFunc = wrapFunc\n\t\t\t\t}\n\n\t\t\tcase *js_ast.EIndex:\n\t\t\t\tif _, ok := e.Target.Data.(*js_ast.ESuper); ok {\n\t\t\t\t\t// Lower \"super[prop]\" if necessary\n\t\t\t\t\tif p.shouldLowerSuperPropertyAccess(e.Target) {\n\t\t\t\t\t\texpr = p.lowerSuperPropertyGet(expr.Loc, e.Index)\n\t\t\t\t\t}\n\n\t\t\t\t\t// See the comment above about a similar special case for EDot\n\t\t\t\t\tthisArg = js_ast.Expr{Loc: loc, Data: js_ast.EThisShared}\n\t\t\t\t} else {\n\t\t\t\t\ttargetFunc, wrapFunc := p.captureValueWithPossibleSideEffects(loc, 2, e.Target, valueDefinitelyNotMutated)\n\t\t\t\t\ttargetWrapFunc = wrapFunc\n\n\t\t\t\t\t// Capture the value of \"this\" if the target of the starting call\n\t\t\t\t\t// expression is a private property access\n\t\t\t\t\tif private, ok := e.Index.Data.(*js_ast.EPrivateIdentifier); ok && p.privateSymbolNeedsToBeLowered(private) {\n\t\t\t\t\t\t// \"foo().#bar?.()\" must capture \"foo()\" for \"this\"\n\t\t\t\t\t\texpr = p.lowerPrivateGet(targetFunc(), e.Index.Loc, private)\n\t\t\t\t\t\tthisArg = targetFunc()\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\texpr = js_ast.Expr{Loc: loc, Data: &js_ast.EIndex{\n\t\t\t\t\t\tTarget: targetFunc(),\n\t\t\t\t\t\tIndex:  e.Index,\n\t\t\t\t\t}}\n\t\t\t\t\tthisArg = targetFunc()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Step 3: Figure out if we need to capture the starting value. We don't need\n\t// to capture it if it doesn't have any side effects (e.g. it's just a bare\n\t// identifier). Skipping the capture reduces code size and matches the output\n\t// of the TypeScript compiler.\n\texprFunc, exprWrapFunc := p.captureValueWithPossibleSideEffects(loc, 2, expr, valueDefinitelyNotMutated)\n\texpr = exprFunc()\n\tresult := exprFunc()\n\n\t// Step 4: Wrap the starting value by each expression in the chain. We\n\t// traverse the chain in reverse because we want to go from the inside out\n\t// and the chain was built from the outside in.\n\tvar parentThisArgFunc func() js_ast.Expr\n\tvar parentThisArgWrapFunc func(js_ast.Expr) js_ast.Expr\n\tvar privateThisFunc func() js_ast.Expr\n\tvar privateThisWrapFunc func(js_ast.Expr) js_ast.Expr\n\tfor i := len(chain) - 1; i >= 0; i-- {\n\t\t// Save a reference to the value of \"this\" for our parent ECall\n\t\tif i == 0 && in.storeThisArgForParentOptionalChain && endsWithPropertyAccess {\n\t\t\tparentThisArgFunc, parentThisArgWrapFunc = p.captureValueWithPossibleSideEffects(result.Loc, 2, result, valueDefinitelyNotMutated)\n\t\t\tresult = parentThisArgFunc()\n\t\t}\n\n\t\tswitch e := chain[i].Data.(type) {\n\t\tcase *js_ast.EDot:\n\t\t\tresult = js_ast.Expr{Loc: loc, Data: &js_ast.EDot{\n\t\t\t\tTarget:  result,\n\t\t\t\tName:    e.Name,\n\t\t\t\tNameLoc: e.NameLoc,\n\t\t\t}}\n\n\t\tcase *js_ast.EIndex:\n\t\t\tif private, ok := e.Index.Data.(*js_ast.EPrivateIdentifier); ok && p.privateSymbolNeedsToBeLowered(private) {\n\t\t\t\t// If this is private name property access inside a call expression and\n\t\t\t\t// the call expression is part of this chain, then the call expression\n\t\t\t\t// is going to need a copy of the property access target as the value\n\t\t\t\t// for \"this\" for the call. Example for this case: \"foo.#bar?.()\"\n\t\t\t\tif i > 0 {\n\t\t\t\t\tif _, ok := chain[i-1].Data.(*js_ast.ECall); ok {\n\t\t\t\t\t\tprivateThisFunc, privateThisWrapFunc = p.captureValueWithPossibleSideEffects(loc, 2, result, valueDefinitelyNotMutated)\n\t\t\t\t\t\tresult = privateThisFunc()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tresult = p.lowerPrivateGet(result, e.Index.Loc, private)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tresult = js_ast.Expr{Loc: loc, Data: &js_ast.EIndex{\n\t\t\t\tTarget: result,\n\t\t\t\tIndex:  e.Index,\n\t\t\t}}\n\n\t\tcase *js_ast.ECall:\n\t\t\t// If this is the initial ECall in the chain and it's being called off of\n\t\t\t// a property access, invoke the function using \".call(this, ...args)\" to\n\t\t\t// explicitly provide the value for \"this\".\n\t\t\tif i == len(chain)-1 && thisArg.Data != nil {\n\t\t\t\tresult = js_ast.Expr{Loc: loc, Data: &js_ast.ECall{\n\t\t\t\t\tTarget: js_ast.Expr{Loc: loc, Data: &js_ast.EDot{\n\t\t\t\t\t\tTarget:  result,\n\t\t\t\t\t\tName:    \"call\",\n\t\t\t\t\t\tNameLoc: loc,\n\t\t\t\t\t}},\n\t\t\t\t\tArgs:                   append([]js_ast.Expr{thisArg}, e.Args...),\n\t\t\t\t\tCanBeUnwrappedIfUnused: e.CanBeUnwrappedIfUnused,\n\t\t\t\t\tIsMultiLine:            e.IsMultiLine,\n\t\t\t\t\tKind:                   js_ast.TargetWasOriginallyPropertyAccess,\n\t\t\t\t}}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// If the target of this call expression is a private name property\n\t\t\t// access that's also part of this chain, then we must use the copy of\n\t\t\t// the property access target that was stashed away earlier as the value\n\t\t\t// for \"this\" for the call. Example for this case: \"foo.#bar?.()\"\n\t\t\tif privateThisFunc != nil {\n\t\t\t\tresult = privateThisWrapFunc(js_ast.Expr{Loc: loc, Data: &js_ast.ECall{\n\t\t\t\t\tTarget: js_ast.Expr{Loc: loc, Data: &js_ast.EDot{\n\t\t\t\t\t\tTarget:  result,\n\t\t\t\t\t\tName:    \"call\",\n\t\t\t\t\t\tNameLoc: loc,\n\t\t\t\t\t}},\n\t\t\t\t\tArgs:                   append([]js_ast.Expr{privateThisFunc()}, e.Args...),\n\t\t\t\t\tCanBeUnwrappedIfUnused: e.CanBeUnwrappedIfUnused,\n\t\t\t\t\tIsMultiLine:            e.IsMultiLine,\n\t\t\t\t\tKind:                   js_ast.TargetWasOriginallyPropertyAccess,\n\t\t\t\t}})\n\t\t\t\tprivateThisFunc = nil\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tresult = js_ast.Expr{Loc: loc, Data: &js_ast.ECall{\n\t\t\t\tTarget:                 result,\n\t\t\t\tArgs:                   e.Args,\n\t\t\t\tCanBeUnwrappedIfUnused: e.CanBeUnwrappedIfUnused,\n\t\t\t\tIsMultiLine:            e.IsMultiLine,\n\t\t\t\tKind:                   e.Kind,\n\t\t\t}}\n\n\t\tcase *js_ast.EUnary:\n\t\t\tresult = js_ast.Expr{Loc: loc, Data: &js_ast.EUnary{\n\t\t\t\tOp:    js_ast.UnOpDelete,\n\t\t\t\tValue: result,\n\n\t\t\t\t// If a delete of an optional chain takes place, it behaves as if the\n\t\t\t\t// optional chain isn't there with regard to the \"delete\" semantics.\n\t\t\t\tWasOriginallyDeleteOfIdentifierOrPropertyAccess: e.WasOriginallyDeleteOfIdentifierOrPropertyAccess,\n\t\t\t}}\n\n\t\tdefault:\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\t}\n\n\t// Step 5: Wrap it all in a conditional that returns the chain or the default\n\t// value if the initial value is null/undefined. The default value is usually\n\t// \"undefined\" but is \"true\" if the chain ends in a \"delete\" operator.\n\t// \"x?.y\" => \"x == null ? void 0 : x.y\"\n\t// \"x()?.y()\" => \"(_a = x()) == null ? void 0 : _a.y()\"\n\tresult = js_ast.Expr{Loc: loc, Data: &js_ast.EIf{\n\t\tTest: js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\tOp:    js_ast.BinOpLooseEq,\n\t\t\tLeft:  expr,\n\t\t\tRight: js_ast.Expr{Loc: loc, Data: js_ast.ENullShared},\n\t\t}},\n\t\tYes: valueWhenUndefined,\n\t\tNo:  result,\n\t}}\n\tif exprWrapFunc != nil {\n\t\tresult = exprWrapFunc(result)\n\t}\n\tif targetWrapFunc != nil {\n\t\tresult = targetWrapFunc(result)\n\t}\n\tif childOut.thisArgWrapFunc != nil {\n\t\tresult = childOut.thisArgWrapFunc(result)\n\t}\n\treturn result, exprOut{\n\t\tthisArgFunc:     parentThisArgFunc,\n\t\tthisArgWrapFunc: parentThisArgWrapFunc,\n\t}\n}\n\nfunc (p *parser) lowerParenthesizedOptionalChain(loc logger.Loc, e *js_ast.ECall, childOut exprOut) js_ast.Expr {\n\treturn childOut.thisArgWrapFunc(js_ast.Expr{Loc: loc, Data: &js_ast.ECall{\n\t\tTarget: js_ast.Expr{Loc: loc, Data: &js_ast.EDot{\n\t\t\tTarget:  e.Target,\n\t\t\tName:    \"call\",\n\t\t\tNameLoc: loc,\n\t\t}},\n\t\tArgs:        append(append(make([]js_ast.Expr, 0, len(e.Args)+1), childOut.thisArgFunc()), e.Args...),\n\t\tIsMultiLine: e.IsMultiLine,\n\t\tKind:        js_ast.TargetWasOriginallyPropertyAccess,\n\t}})\n}\n\nfunc (p *parser) lowerAssignmentOperator(value js_ast.Expr, callback func(js_ast.Expr, js_ast.Expr) js_ast.Expr) js_ast.Expr {\n\tswitch left := value.Data.(type) {\n\tcase *js_ast.EDot:\n\t\tif left.OptionalChain == js_ast.OptionalChainNone {\n\t\t\treferenceFunc, wrapFunc := p.captureValueWithPossibleSideEffects(value.Loc, 2, left.Target, valueDefinitelyNotMutated)\n\t\t\treturn wrapFunc(callback(\n\t\t\t\tjs_ast.Expr{Loc: value.Loc, Data: &js_ast.EDot{\n\t\t\t\t\tTarget:  referenceFunc(),\n\t\t\t\t\tName:    left.Name,\n\t\t\t\t\tNameLoc: left.NameLoc,\n\t\t\t\t}},\n\t\t\t\tjs_ast.Expr{Loc: value.Loc, Data: &js_ast.EDot{\n\t\t\t\t\tTarget:  referenceFunc(),\n\t\t\t\t\tName:    left.Name,\n\t\t\t\t\tNameLoc: left.NameLoc,\n\t\t\t\t}},\n\t\t\t))\n\t\t}\n\n\tcase *js_ast.EIndex:\n\t\tif left.OptionalChain == js_ast.OptionalChainNone {\n\t\t\ttargetFunc, targetWrapFunc := p.captureValueWithPossibleSideEffects(value.Loc, 2, left.Target, valueDefinitelyNotMutated)\n\t\t\tindexFunc, indexWrapFunc := p.captureValueWithPossibleSideEffects(value.Loc, 2, left.Index, valueDefinitelyNotMutated)\n\t\t\treturn targetWrapFunc(indexWrapFunc(callback(\n\t\t\t\tjs_ast.Expr{Loc: value.Loc, Data: &js_ast.EIndex{\n\t\t\t\t\tTarget: targetFunc(),\n\t\t\t\t\tIndex:  indexFunc(),\n\t\t\t\t}},\n\t\t\t\tjs_ast.Expr{Loc: value.Loc, Data: &js_ast.EIndex{\n\t\t\t\t\tTarget: targetFunc(),\n\t\t\t\t\tIndex:  indexFunc(),\n\t\t\t\t}},\n\t\t\t)))\n\t\t}\n\n\tcase *js_ast.EIdentifier:\n\t\treturn callback(\n\t\t\tjs_ast.Expr{Loc: value.Loc, Data: &js_ast.EIdentifier{Ref: left.Ref}},\n\t\t\tvalue,\n\t\t)\n\t}\n\n\t// We shouldn't get here with valid syntax? Just let this through for now\n\t// since there's currently no assignment target validation. Garbage in,\n\t// garbage out.\n\treturn value\n}\n\nfunc (p *parser) lowerExponentiationAssignmentOperator(loc logger.Loc, e *js_ast.EBinary) js_ast.Expr {\n\tif target, privateLoc, private := p.extractPrivateIndex(e.Left); private != nil {\n\t\t// \"a.#b **= c\" => \"__privateSet(a, #b, __pow(__privateGet(a, #b), c))\"\n\t\ttargetFunc, targetWrapFunc := p.captureValueWithPossibleSideEffects(loc, 2, target, valueDefinitelyNotMutated)\n\t\treturn targetWrapFunc(p.lowerPrivateSet(targetFunc(), privateLoc, private,\n\t\t\tp.callRuntime(loc, \"__pow\", []js_ast.Expr{\n\t\t\t\tp.lowerPrivateGet(targetFunc(), privateLoc, private),\n\t\t\t\te.Right,\n\t\t\t})))\n\t}\n\n\treturn p.lowerAssignmentOperator(e.Left, func(a js_ast.Expr, b js_ast.Expr) js_ast.Expr {\n\t\t// \"a **= b\" => \"a = __pow(a, b)\"\n\t\treturn js_ast.Assign(a, p.callRuntime(loc, \"__pow\", []js_ast.Expr{b, e.Right}))\n\t})\n}\n\nfunc (p *parser) lowerNullishCoalescingAssignmentOperator(loc logger.Loc, e *js_ast.EBinary) (js_ast.Expr, bool) {\n\tif target, privateLoc, private := p.extractPrivateIndex(e.Left); private != nil {\n\t\tif p.options.unsupportedJSFeatures.Has(compat.NullishCoalescing) {\n\t\t\t// \"a.#b ??= c\" => \"(_a = __privateGet(a, #b)) != null ? _a : __privateSet(a, #b, c)\"\n\t\t\ttargetFunc, targetWrapFunc := p.captureValueWithPossibleSideEffects(loc, 2, target, valueDefinitelyNotMutated)\n\t\t\tleft := p.lowerPrivateGet(targetFunc(), privateLoc, private)\n\t\t\tright := p.lowerPrivateSet(targetFunc(), privateLoc, private, e.Right)\n\t\t\treturn targetWrapFunc(p.lowerNullishCoalescing(loc, left, right)), true\n\t\t}\n\n\t\t// \"a.#b ??= c\" => \"__privateGet(a, #b) ?? __privateSet(a, #b, c)\"\n\t\ttargetFunc, targetWrapFunc := p.captureValueWithPossibleSideEffects(loc, 2, target, valueDefinitelyNotMutated)\n\t\treturn targetWrapFunc(js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\tOp:    js_ast.BinOpNullishCoalescing,\n\t\t\tLeft:  p.lowerPrivateGet(targetFunc(), privateLoc, private),\n\t\t\tRight: p.lowerPrivateSet(targetFunc(), privateLoc, private, e.Right),\n\t\t}}), true\n\t}\n\n\tif p.options.unsupportedJSFeatures.Has(compat.LogicalAssignment) {\n\t\treturn p.lowerAssignmentOperator(e.Left, func(a js_ast.Expr, b js_ast.Expr) js_ast.Expr {\n\t\t\tif p.options.unsupportedJSFeatures.Has(compat.NullishCoalescing) {\n\t\t\t\t// \"a ??= b\" => \"(_a = a) != null ? _a : a = b\"\n\t\t\t\treturn p.lowerNullishCoalescing(loc, a, js_ast.Assign(b, e.Right))\n\t\t\t}\n\n\t\t\t// \"a ??= b\" => \"a ?? (a = b)\"\n\t\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\t\tOp:    js_ast.BinOpNullishCoalescing,\n\t\t\t\tLeft:  a,\n\t\t\t\tRight: js_ast.Assign(b, e.Right),\n\t\t\t}}\n\t\t}), true\n\t}\n\n\treturn js_ast.Expr{}, false\n}\n\nfunc (p *parser) lowerLogicalAssignmentOperator(loc logger.Loc, e *js_ast.EBinary, op js_ast.OpCode) (js_ast.Expr, bool) {\n\tif target, privateLoc, private := p.extractPrivateIndex(e.Left); private != nil {\n\t\t// \"a.#b &&= c\" => \"__privateGet(a, #b) && __privateSet(a, #b, c)\"\n\t\t// \"a.#b ||= c\" => \"__privateGet(a, #b) || __privateSet(a, #b, c)\"\n\t\ttargetFunc, targetWrapFunc := p.captureValueWithPossibleSideEffects(loc, 2, target, valueDefinitelyNotMutated)\n\t\treturn targetWrapFunc(js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\tOp:    op,\n\t\t\tLeft:  p.lowerPrivateGet(targetFunc(), privateLoc, private),\n\t\t\tRight: p.lowerPrivateSet(targetFunc(), privateLoc, private, e.Right),\n\t\t}}), true\n\t}\n\n\tif p.options.unsupportedJSFeatures.Has(compat.LogicalAssignment) {\n\t\treturn p.lowerAssignmentOperator(e.Left, func(a js_ast.Expr, b js_ast.Expr) js_ast.Expr {\n\t\t\t// \"a &&= b\" => \"a && (a = b)\"\n\t\t\t// \"a ||= b\" => \"a || (a = b)\"\n\t\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\t\tOp:    op,\n\t\t\t\tLeft:  a,\n\t\t\t\tRight: js_ast.Assign(b, e.Right),\n\t\t\t}}\n\t\t}), true\n\t}\n\n\treturn js_ast.Expr{}, false\n}\n\nfunc (p *parser) lowerNullishCoalescing(loc logger.Loc, left js_ast.Expr, right js_ast.Expr) js_ast.Expr {\n\t// \"x ?? y\" => \"x != null ? x : y\"\n\t// \"x() ?? y()\" => \"_a = x(), _a != null ? _a : y\"\n\tleftFunc, wrapFunc := p.captureValueWithPossibleSideEffects(loc, 2, left, valueDefinitelyNotMutated)\n\treturn wrapFunc(js_ast.Expr{Loc: loc, Data: &js_ast.EIf{\n\t\tTest: js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\tOp:    js_ast.BinOpLooseNe,\n\t\t\tLeft:  leftFunc(),\n\t\t\tRight: js_ast.Expr{Loc: loc, Data: js_ast.ENullShared},\n\t\t}},\n\t\tYes: leftFunc(),\n\t\tNo:  right,\n\t}})\n}\n\n// Lower object spread for environments that don't support them. Non-spread\n// properties are grouped into object literals and then passed to the\n// \"__spreadValues\" and \"__spreadProps\" functions like this:\n//\n//\t\"{a, b, ...c, d, e}\" => \"__spreadProps(__spreadValues(__spreadProps({a, b}, c), {d, e})\"\n//\n// If the object literal starts with a spread, then we pass an empty object\n// literal to \"__spreadValues\" to make sure we clone the object:\n//\n//\t\"{...a, b}\" => \"__spreadProps(__spreadValues({}, a), {b})\"\n//\n// It's not immediately obvious why we don't compile everything to a single\n// call to a function that takes any number of arguments, since that would be\n// shorter. The reason is to preserve the order of side effects. Consider\n// this code:\n//\n//\tlet a = {\n//\t  get x() {\n//\t    b = {y: 2}\n//\t    return 1\n//\t  }\n//\t}\n//\tlet b = {}\n//\tlet c = {...a, ...b}\n//\n// Converting the above code to \"let c = __spreadFn({}, a, null, b)\" means \"c\"\n// becomes \"{x: 1}\" which is incorrect. Converting the above code instead to\n// \"let c = __spreadProps(__spreadProps({}, a), b)\" means \"c\" becomes\n// \"{x: 1, y: 2}\" which is correct.\nfunc (p *parser) lowerObjectSpread(loc logger.Loc, e *js_ast.EObject) js_ast.Expr {\n\tneedsLowering := false\n\n\tif p.options.unsupportedJSFeatures.Has(compat.ObjectRestSpread) {\n\t\tfor _, property := range e.Properties {\n\t\t\tif property.Kind == js_ast.PropertySpread {\n\t\t\t\tneedsLowering = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tif !needsLowering {\n\t\treturn js_ast.Expr{Loc: loc, Data: e}\n\t}\n\n\tvar result js_ast.Expr\n\tproperties := []js_ast.Property{}\n\n\tfor _, property := range e.Properties {\n\t\tif property.Kind != js_ast.PropertySpread {\n\t\t\tproperties = append(properties, property)\n\t\t\tcontinue\n\t\t}\n\n\t\tif len(properties) > 0 || result.Data == nil {\n\t\t\tif result.Data == nil {\n\t\t\t\t// \"{a, ...b}\" => \"__spreadValues({a}, b)\"\n\t\t\t\tresult = js_ast.Expr{Loc: loc, Data: &js_ast.EObject{\n\t\t\t\t\tProperties:   properties,\n\t\t\t\t\tIsSingleLine: e.IsSingleLine,\n\t\t\t\t}}\n\t\t\t} else {\n\t\t\t\t// \"{...a, b, ...c}\" => \"__spreadValues(__spreadProps(__spreadValues({}, a), {b}), c)\"\n\t\t\t\tresult = p.callRuntime(loc, \"__spreadProps\",\n\t\t\t\t\t[]js_ast.Expr{result, {Loc: loc, Data: &js_ast.EObject{\n\t\t\t\t\t\tProperties:   properties,\n\t\t\t\t\t\tIsSingleLine: e.IsSingleLine,\n\t\t\t\t\t}}})\n\t\t\t}\n\t\t\tproperties = []js_ast.Property{}\n\t\t}\n\n\t\t// \"{a, ...b}\" => \"__spreadValues({a}, b)\"\n\t\tresult = p.callRuntime(loc, \"__spreadValues\", []js_ast.Expr{result, property.ValueOrNil})\n\t}\n\n\tif len(properties) > 0 {\n\t\t// \"{...a, b}\" => \"__spreadProps(__spreadValues({}, a), {b})\"\n\t\tresult = p.callRuntime(loc, \"__spreadProps\", []js_ast.Expr{result, {Loc: loc, Data: &js_ast.EObject{\n\t\t\tProperties:    properties,\n\t\t\tIsSingleLine:  e.IsSingleLine,\n\t\t\tCloseBraceLoc: e.CloseBraceLoc,\n\t\t}}})\n\t}\n\n\treturn result\n}\n\nfunc (p *parser) maybeLowerAwait(loc logger.Loc, e *js_ast.EAwait) js_ast.Expr {\n\t// \"await x\" turns into \"yield __await(x)\" when lowering async generator functions\n\tif p.fnOrArrowDataVisit.isGenerator && (p.options.unsupportedJSFeatures.Has(compat.AsyncAwait) || p.options.unsupportedJSFeatures.Has(compat.AsyncGenerator)) {\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EYield{\n\t\t\tValueOrNil: js_ast.Expr{Loc: loc, Data: &js_ast.ENew{\n\t\t\t\tTarget: p.importFromRuntime(loc, \"__await\"),\n\t\t\t\tArgs:   []js_ast.Expr{e.Value},\n\t\t\t}},\n\t\t}}\n\t}\n\n\t// \"await x\" turns into \"yield x\" when lowering async functions\n\tif p.options.unsupportedJSFeatures.Has(compat.AsyncAwait) {\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EYield{\n\t\t\tValueOrNil: e.Value,\n\t\t}}\n\t}\n\n\treturn js_ast.Expr{Loc: loc, Data: e}\n}\n\nfunc (p *parser) lowerForAwaitLoop(loc logger.Loc, loop *js_ast.SForOf, stmts []js_ast.Stmt) []js_ast.Stmt {\n\t// This code:\n\t//\n\t//   for await (let x of y) z()\n\t//\n\t// is transformed into the following code:\n\t//\n\t//   try {\n\t//     for (var iter = __forAwait(y), more, temp, error; more = !(temp = await iter.next()).done; more = false) {\n\t//       let x = temp.value;\n\t//       z();\n\t//     }\n\t//   } catch (temp) {\n\t//     error = [temp]\n\t//   } finally {\n\t//     try {\n\t//       more && (temp = iter.return) && (await temp.call(iter))\n\t//     } finally {\n\t//       if (error) throw error[0]\n\t//     }\n\t//   }\n\t//\n\t// except that \"yield\" is used instead of \"await\" if await is unsupported.\n\t// This mostly follows TypeScript's implementation of the syntax transform.\n\n\titerRef := p.generateTempRef(tempRefNoDeclare, \"iter\")\n\tmoreRef := p.generateTempRef(tempRefNoDeclare, \"more\")\n\ttempRef := p.generateTempRef(tempRefNoDeclare, \"temp\")\n\terrorRef := p.generateTempRef(tempRefNoDeclare, \"error\")\n\n\tp.recordUsage(iterRef)\n\tp.recordUsage(moreRef)\n\tp.recordUsage(tempRef)\n\tp.recordUsage(errorRef)\n\n\tswitch init := loop.Init.Data.(type) {\n\tcase *js_ast.SLocal:\n\t\tif len(init.Decls) == 1 {\n\t\t\tinit.Decls[0].ValueOrNil = js_ast.Expr{Loc: loc, Data: &js_ast.EDot{\n\t\t\t\tTarget:  js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: tempRef}},\n\t\t\t\tNameLoc: loc,\n\t\t\t\tName:    \"value\",\n\t\t\t}}\n\t\t}\n\tcase *js_ast.SExpr:\n\t\tinit.Value.Data = &js_ast.EBinary{\n\t\t\tOp:   js_ast.BinOpAssign,\n\t\t\tLeft: init.Value,\n\t\t\tRight: js_ast.Expr{Loc: loc, Data: &js_ast.EDot{\n\t\t\t\tTarget:  js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: tempRef}},\n\t\t\t\tNameLoc: loc,\n\t\t\t\tName:    \"value\",\n\t\t\t}},\n\t\t}\n\t}\n\n\tvar body []js_ast.Stmt\n\tvar closeBraceLoc logger.Loc\n\tbody = append(body, loop.Init)\n\n\tif block, ok := loop.Body.Data.(*js_ast.SBlock); ok {\n\t\tbody = append(body, block.Stmts...)\n\t\tcloseBraceLoc = block.CloseBraceLoc\n\t} else {\n\t\tbody = append(body, loop.Body)\n\t}\n\n\tawaitIterNext := js_ast.Expr{Loc: loc, Data: &js_ast.ECall{\n\t\tTarget: js_ast.Expr{Loc: loc, Data: &js_ast.EDot{\n\t\t\tTarget:  js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: iterRef}},\n\t\t\tNameLoc: loc,\n\t\t\tName:    \"next\",\n\t\t}},\n\t\tKind: js_ast.TargetWasOriginallyPropertyAccess,\n\t}}\n\tawaitTempCallIter := js_ast.Expr{Loc: loc, Data: &js_ast.ECall{\n\t\tTarget: js_ast.Expr{Loc: loc, Data: &js_ast.EDot{\n\t\t\tTarget:  js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: tempRef}},\n\t\t\tNameLoc: loc,\n\t\t\tName:    \"call\",\n\t\t}},\n\t\tArgs: []js_ast.Expr{{Loc: loc, Data: &js_ast.EIdentifier{Ref: iterRef}}},\n\t\tKind: js_ast.TargetWasOriginallyPropertyAccess,\n\t}}\n\n\t// \"await\" expressions turn into \"yield\" expressions when lowering\n\tawaitIterNext = p.maybeLowerAwait(awaitIterNext.Loc, &js_ast.EAwait{Value: awaitIterNext})\n\tawaitTempCallIter = p.maybeLowerAwait(awaitTempCallIter.Loc, &js_ast.EAwait{Value: awaitTempCallIter})\n\n\treturn append(stmts, js_ast.Stmt{Loc: loc, Data: &js_ast.STry{\n\t\tBlockLoc: loc,\n\t\tBlock: js_ast.SBlock{\n\t\t\tStmts: []js_ast.Stmt{{Loc: loc, Data: &js_ast.SFor{\n\t\t\t\tIsLoweredForAwait: true,\n\t\t\t\tInitOrNil: js_ast.Stmt{Loc: loc, Data: &js_ast.SLocal{Kind: js_ast.LocalVar, Decls: []js_ast.Decl{\n\t\t\t\t\t{Binding: js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: iterRef}},\n\t\t\t\t\t\tValueOrNil: p.callRuntime(loc, \"__forAwait\", []js_ast.Expr{loop.Value})},\n\t\t\t\t\t{Binding: js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: moreRef}}},\n\t\t\t\t\t{Binding: js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: tempRef}}},\n\t\t\t\t\t{Binding: js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: errorRef}}},\n\t\t\t\t}}},\n\t\t\t\tTestOrNil: js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\t\t\tOp:   js_ast.BinOpAssign,\n\t\t\t\t\tLeft: js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: moreRef}},\n\t\t\t\t\tRight: js_ast.Expr{Loc: loc, Data: &js_ast.EUnary{\n\t\t\t\t\t\tOp: js_ast.UnOpNot,\n\t\t\t\t\t\tValue: js_ast.Expr{Loc: loc, Data: &js_ast.EDot{\n\t\t\t\t\t\t\tTarget: js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\t\t\t\t\t\tOp:    js_ast.BinOpAssign,\n\t\t\t\t\t\t\t\tLeft:  js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: tempRef}},\n\t\t\t\t\t\t\t\tRight: awaitIterNext,\n\t\t\t\t\t\t\t}},\n\t\t\t\t\t\t\tNameLoc: loc,\n\t\t\t\t\t\t\tName:    \"done\",\n\t\t\t\t\t\t}},\n\t\t\t\t\t}},\n\t\t\t\t}},\n\t\t\t\tUpdateOrNil: js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\t\t\tOp:    js_ast.BinOpAssign,\n\t\t\t\t\tLeft:  js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: moreRef}},\n\t\t\t\t\tRight: js_ast.Expr{Loc: loc, Data: &js_ast.EBoolean{Value: false}},\n\t\t\t\t}},\n\t\t\t\tBody: js_ast.Stmt{Loc: loop.Body.Loc, Data: &js_ast.SBlock{\n\t\t\t\t\tStmts:         body,\n\t\t\t\t\tCloseBraceLoc: closeBraceLoc,\n\t\t\t\t}},\n\t\t\t}}},\n\t\t},\n\n\t\tCatch: &js_ast.Catch{\n\t\t\tLoc: loc,\n\t\t\tBindingOrNil: js_ast.Binding{\n\t\t\t\tLoc:  loc,\n\t\t\t\tData: &js_ast.BIdentifier{Ref: tempRef},\n\t\t\t},\n\t\t\tBlock: js_ast.SBlock{\n\t\t\t\tStmts: []js_ast.Stmt{{Loc: loc, Data: &js_ast.SExpr{Value: js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\t\t\tOp:   js_ast.BinOpAssign,\n\t\t\t\t\tLeft: js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: errorRef}},\n\t\t\t\t\tRight: js_ast.Expr{Loc: loc, Data: &js_ast.EArray{\n\t\t\t\t\t\tItems:        []js_ast.Expr{{Loc: loc, Data: &js_ast.EIdentifier{Ref: tempRef}}},\n\t\t\t\t\t\tIsSingleLine: true,\n\t\t\t\t\t}},\n\t\t\t\t}}}}},\n\t\t\t},\n\t\t},\n\n\t\tFinally: &js_ast.Finally{\n\t\t\tLoc: loc,\n\t\t\tBlock: js_ast.SBlock{\n\t\t\t\tStmts: []js_ast.Stmt{{Loc: loc, Data: &js_ast.STry{\n\t\t\t\t\tBlockLoc: loc,\n\t\t\t\t\tBlock: js_ast.SBlock{Stmts: []js_ast.Stmt{{Loc: loc, Data: &js_ast.SExpr{\n\t\t\t\t\t\tValue: js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\t\t\t\t\tOp: js_ast.BinOpLogicalAnd,\n\t\t\t\t\t\t\tLeft: js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\t\t\t\t\t\tOp:   js_ast.BinOpLogicalAnd,\n\t\t\t\t\t\t\t\tLeft: js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: moreRef}},\n\t\t\t\t\t\t\t\tRight: js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\t\t\t\t\t\t\tOp:   js_ast.BinOpAssign,\n\t\t\t\t\t\t\t\t\tLeft: js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: tempRef}},\n\t\t\t\t\t\t\t\t\tRight: js_ast.Expr{Loc: loc, Data: &js_ast.EDot{\n\t\t\t\t\t\t\t\t\t\tTarget:  js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: iterRef}},\n\t\t\t\t\t\t\t\t\t\tNameLoc: loc,\n\t\t\t\t\t\t\t\t\t\tName:    \"return\",\n\t\t\t\t\t\t\t\t\t}},\n\t\t\t\t\t\t\t\t}},\n\t\t\t\t\t\t\t}},\n\t\t\t\t\t\t\tRight: awaitTempCallIter,\n\t\t\t\t\t\t}},\n\t\t\t\t\t}}}},\n\t\t\t\t\tFinally: &js_ast.Finally{\n\t\t\t\t\t\tLoc: loc,\n\t\t\t\t\t\tBlock: js_ast.SBlock{Stmts: []js_ast.Stmt{{Loc: loc, Data: &js_ast.SIf{\n\t\t\t\t\t\t\tTest: js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: errorRef}},\n\t\t\t\t\t\t\tYes: js_ast.Stmt{Loc: loc, Data: &js_ast.SThrow{Value: js_ast.Expr{Loc: loc, Data: &js_ast.EIndex{\n\t\t\t\t\t\t\t\tTarget: js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: errorRef}},\n\t\t\t\t\t\t\t\tIndex:  js_ast.Expr{Loc: loc, Data: &js_ast.ENumber{Value: 0}},\n\t\t\t\t\t\t\t}}}},\n\t\t\t\t\t\t}}}},\n\t\t\t\t\t},\n\t\t\t\t}}},\n\t\t\t},\n\t\t},\n\t}})\n}\n\nfunc bindingHasObjectRest(binding js_ast.Binding) bool {\n\tswitch b := binding.Data.(type) {\n\tcase *js_ast.BArray:\n\t\tfor _, item := range b.Items {\n\t\t\tif bindingHasObjectRest(item.Binding) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\tcase *js_ast.BObject:\n\t\tfor _, property := range b.Properties {\n\t\t\tif property.IsSpread || bindingHasObjectRest(property.Value) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc exprHasObjectRest(expr js_ast.Expr) bool {\n\tswitch e := expr.Data.(type) {\n\tcase *js_ast.EBinary:\n\t\tif e.Op == js_ast.BinOpAssign && exprHasObjectRest(e.Left) {\n\t\t\treturn true\n\t\t}\n\tcase *js_ast.EArray:\n\t\tfor _, item := range e.Items {\n\t\t\tif exprHasObjectRest(item) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\tcase *js_ast.EObject:\n\t\tfor _, property := range e.Properties {\n\t\t\tif property.Kind == js_ast.PropertySpread || exprHasObjectRest(property.ValueOrNil) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (p *parser) lowerObjectRestInDecls(decls []js_ast.Decl) []js_ast.Decl {\n\tif !p.options.unsupportedJSFeatures.Has(compat.ObjectRestSpread) {\n\t\treturn decls\n\t}\n\n\t// Don't do any allocations if there are no object rest patterns. We want as\n\t// little overhead as possible in the common case.\n\tfor i, decl := range decls {\n\t\tif decl.ValueOrNil.Data != nil && bindingHasObjectRest(decl.Binding) {\n\t\t\tclone := append([]js_ast.Decl{}, decls[:i]...)\n\t\t\tfor _, decl := range decls[i:] {\n\t\t\t\tif decl.ValueOrNil.Data != nil {\n\t\t\t\t\ttarget := js_ast.ConvertBindingToExpr(decl.Binding, nil)\n\t\t\t\t\tif result, ok := p.lowerObjectRestToDecls(target, decl.ValueOrNil, clone); ok {\n\t\t\t\t\t\tclone = result\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tclone = append(clone, decl)\n\t\t\t}\n\n\t\t\treturn clone\n\t\t}\n\t}\n\n\treturn decls\n}\n\nfunc (p *parser) lowerObjectRestInForLoopInit(init js_ast.Stmt, body *js_ast.Stmt) {\n\tif !p.options.unsupportedJSFeatures.Has(compat.ObjectRestSpread) {\n\t\treturn\n\t}\n\n\tvar bodyPrefixStmt js_ast.Stmt\n\n\tswitch s := init.Data.(type) {\n\tcase *js_ast.SExpr:\n\t\t// \"for ({...x} in y) {}\"\n\t\t// \"for ({...x} of y) {}\"\n\t\tif exprHasObjectRest(s.Value) {\n\t\t\tref := p.generateTempRef(tempRefNeedsDeclare, \"\")\n\t\t\tif expr, ok := p.lowerAssign(s.Value, js_ast.Expr{Loc: init.Loc, Data: &js_ast.EIdentifier{Ref: ref}}, objRestReturnValueIsUnused); ok {\n\t\t\t\tp.recordUsage(ref)\n\t\t\t\ts.Value.Data = &js_ast.EIdentifier{Ref: ref}\n\t\t\t\tbodyPrefixStmt = js_ast.Stmt{Loc: expr.Loc, Data: &js_ast.SExpr{Value: expr}}\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.SLocal:\n\t\t// \"for (let {...x} in y) {}\"\n\t\t// \"for (let {...x} of y) {}\"\n\t\tif len(s.Decls) == 1 && bindingHasObjectRest(s.Decls[0].Binding) {\n\t\t\tref := p.generateTempRef(tempRefNoDeclare, \"\")\n\t\t\tdecl := js_ast.Decl{Binding: s.Decls[0].Binding, ValueOrNil: js_ast.Expr{Loc: init.Loc, Data: &js_ast.EIdentifier{Ref: ref}}}\n\t\t\tp.recordUsage(ref)\n\t\t\tdecls := p.lowerObjectRestInDecls([]js_ast.Decl{decl})\n\t\t\ts.Decls[0].Binding.Data = &js_ast.BIdentifier{Ref: ref}\n\t\t\tbodyPrefixStmt = js_ast.Stmt{Loc: init.Loc, Data: &js_ast.SLocal{Kind: s.Kind, Decls: decls}}\n\t\t}\n\t}\n\n\tif bodyPrefixStmt.Data != nil {\n\t\tif block, ok := body.Data.(*js_ast.SBlock); ok {\n\t\t\t// If there's already a block, insert at the front\n\t\t\tstmts := make([]js_ast.Stmt, 0, 1+len(block.Stmts))\n\t\t\tblock.Stmts = append(append(stmts, bodyPrefixStmt), block.Stmts...)\n\t\t} else {\n\t\t\t// Otherwise, make a block and insert at the front\n\t\t\tbody.Data = &js_ast.SBlock{Stmts: []js_ast.Stmt{bodyPrefixStmt, *body}}\n\t\t}\n\t}\n}\n\nfunc (p *parser) lowerObjectRestInCatchBinding(catch *js_ast.Catch) {\n\tif !p.options.unsupportedJSFeatures.Has(compat.ObjectRestSpread) {\n\t\treturn\n\t}\n\n\tif catch.BindingOrNil.Data != nil && bindingHasObjectRest(catch.BindingOrNil) {\n\t\tref := p.generateTempRef(tempRefNoDeclare, \"\")\n\t\tdecl := js_ast.Decl{Binding: catch.BindingOrNil, ValueOrNil: js_ast.Expr{Loc: catch.BindingOrNil.Loc, Data: &js_ast.EIdentifier{Ref: ref}}}\n\t\tp.recordUsage(ref)\n\t\tdecls := p.lowerObjectRestInDecls([]js_ast.Decl{decl})\n\t\tcatch.BindingOrNil.Data = &js_ast.BIdentifier{Ref: ref}\n\t\tstmts := make([]js_ast.Stmt, 0, 1+len(catch.Block.Stmts))\n\t\tstmts = append(stmts, js_ast.Stmt{Loc: catch.BindingOrNil.Loc, Data: &js_ast.SLocal{Kind: js_ast.LocalLet, Decls: decls}})\n\t\tcatch.Block.Stmts = append(stmts, catch.Block.Stmts...)\n\t}\n}\n\ntype objRestMode uint8\n\nconst (\n\tobjRestReturnValueIsUnused objRestMode = iota\n\tobjRestMustReturnInitExpr\n)\n\nfunc (p *parser) lowerAssign(rootExpr js_ast.Expr, rootInit js_ast.Expr, mode objRestMode) (js_ast.Expr, bool) {\n\trootExpr, didLower := p.lowerSuperPropertyOrPrivateInAssign(rootExpr)\n\n\tvar expr js_ast.Expr\n\tassign := func(left js_ast.Expr, right js_ast.Expr) {\n\t\texpr = js_ast.JoinWithComma(expr, js_ast.Assign(left, right))\n\t}\n\n\tif initWrapFunc, ok := p.lowerObjectRestHelper(rootExpr, rootInit, assign, tempRefNeedsDeclare, mode); ok {\n\t\tif initWrapFunc != nil {\n\t\t\texpr = initWrapFunc(expr)\n\t\t}\n\t\treturn expr, true\n\t}\n\n\tif didLower {\n\t\treturn js_ast.Assign(rootExpr, rootInit), true\n\t}\n\n\treturn js_ast.Expr{}, false\n}\n\nfunc (p *parser) lowerObjectRestToDecls(rootExpr js_ast.Expr, rootInit js_ast.Expr, decls []js_ast.Decl) ([]js_ast.Decl, bool) {\n\tassign := func(left js_ast.Expr, right js_ast.Expr) {\n\t\tbinding, invalidLog := p.convertExprToBinding(left, invalidLog{})\n\t\tif len(invalidLog.invalidTokens) > 0 {\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\t\tdecls = append(decls, js_ast.Decl{Binding: binding, ValueOrNil: right})\n\t}\n\n\tif _, ok := p.lowerObjectRestHelper(rootExpr, rootInit, assign, tempRefNoDeclare, objRestReturnValueIsUnused); ok {\n\t\treturn decls, true\n\t}\n\n\treturn nil, false\n}\n\nfunc (p *parser) lowerObjectRestHelper(\n\trootExpr js_ast.Expr,\n\trootInit js_ast.Expr,\n\tassign func(js_ast.Expr, js_ast.Expr),\n\tdeclare generateTempRefArg,\n\tmode objRestMode,\n) (wrapFunc func(js_ast.Expr) js_ast.Expr, ok bool) {\n\tif !p.options.unsupportedJSFeatures.Has(compat.ObjectRestSpread) {\n\t\treturn nil, false\n\t}\n\n\t// Check if this could possibly contain an object rest binding\n\tswitch rootExpr.Data.(type) {\n\tcase *js_ast.EArray, *js_ast.EObject:\n\tdefault:\n\t\treturn nil, false\n\t}\n\n\t// Scan for object rest bindings and initialize rest binding containment\n\tcontainsRestBinding := make(map[js_ast.E]bool)\n\tvar findRestBindings func(js_ast.Expr) bool\n\tfindRestBindings = func(expr js_ast.Expr) bool {\n\t\tfound := false\n\t\tswitch e := expr.Data.(type) {\n\t\tcase *js_ast.EBinary:\n\t\t\tif e.Op == js_ast.BinOpAssign && findRestBindings(e.Left) {\n\t\t\t\tfound = true\n\t\t\t}\n\t\tcase *js_ast.EArray:\n\t\t\tfor _, item := range e.Items {\n\t\t\t\tif findRestBindings(item) {\n\t\t\t\t\tfound = true\n\t\t\t\t}\n\t\t\t}\n\t\tcase *js_ast.EObject:\n\t\t\tfor _, property := range e.Properties {\n\t\t\t\tif property.Kind == js_ast.PropertySpread || findRestBindings(property.ValueOrNil) {\n\t\t\t\t\tfound = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif found {\n\t\t\tcontainsRestBinding[expr.Data] = true\n\t\t}\n\t\treturn found\n\t}\n\tfindRestBindings(rootExpr)\n\tif len(containsRestBinding) == 0 {\n\t\treturn nil, false\n\t}\n\n\t// If there is at least one rest binding, lower the whole expression\n\tvar visit func(js_ast.Expr, js_ast.Expr, []func() js_ast.Expr)\n\n\tcaptureIntoRef := func(expr js_ast.Expr) ast.Ref {\n\t\tref := p.generateTempRef(declare, \"\")\n\t\tassign(js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EIdentifier{Ref: ref}}, expr)\n\t\tp.recordUsage(ref)\n\t\treturn ref\n\t}\n\n\tlowerObjectRestPattern := func(\n\t\tbefore []js_ast.Property,\n\t\tbinding js_ast.Expr,\n\t\tinit js_ast.Expr,\n\t\tcapturedKeys []func() js_ast.Expr,\n\t\tisSingleLine bool,\n\t) {\n\t\t// If there are properties before this one, store the initializer in a\n\t\t// temporary so we can reference it multiple times, then create a new\n\t\t// destructuring assignment for these properties\n\t\tif len(before) > 0 {\n\t\t\t// \"let {a, ...b} = c\"\n\t\t\tref := captureIntoRef(init)\n\t\t\tassign(js_ast.Expr{Loc: before[0].Key.Loc, Data: &js_ast.EObject{Properties: before, IsSingleLine: isSingleLine}},\n\t\t\t\tjs_ast.Expr{Loc: init.Loc, Data: &js_ast.EIdentifier{Ref: ref}})\n\t\t\tinit = js_ast.Expr{Loc: init.Loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\t\t\tp.recordUsage(ref)\n\t\t\tp.recordUsage(ref)\n\t\t}\n\n\t\t// Call \"__objRest\" to clone the initializer without the keys for previous\n\t\t// properties, then assign the result to the binding for the rest pattern\n\t\tkeysToExclude := make([]js_ast.Expr, len(capturedKeys))\n\t\tfor i, capturedKey := range capturedKeys {\n\t\t\tkeysToExclude[i] = capturedKey()\n\t\t}\n\t\tassign(binding, p.callRuntime(binding.Loc, \"__objRest\", []js_ast.Expr{init,\n\t\t\t{Loc: binding.Loc, Data: &js_ast.EArray{Items: keysToExclude, IsSingleLine: isSingleLine}}}))\n\t}\n\n\tsplitArrayPattern := func(\n\t\tbefore []js_ast.Expr,\n\t\tsplit js_ast.Expr,\n\t\tafter []js_ast.Expr,\n\t\tinit js_ast.Expr,\n\t\tisSingleLine bool,\n\t) {\n\t\t// If this has a default value, skip the value to target the binding\n\t\tbinding := &split\n\t\tif binary, ok := binding.Data.(*js_ast.EBinary); ok && binary.Op == js_ast.BinOpAssign {\n\t\t\tbinding = &binary.Left\n\t\t}\n\n\t\t// Swap the binding with a temporary\n\t\tsplitRef := p.generateTempRef(declare, \"\")\n\t\tdeferredBinding := *binding\n\t\tbinding.Data = &js_ast.EIdentifier{Ref: splitRef}\n\t\titems := append(before, split)\n\n\t\t// If there are any items left over, defer them until later too\n\t\tvar tailExpr js_ast.Expr\n\t\tvar tailInit js_ast.Expr\n\t\tif len(after) > 0 {\n\t\t\ttailRef := p.generateTempRef(declare, \"\")\n\t\t\tloc := after[0].Loc\n\t\t\ttailExpr = js_ast.Expr{Loc: loc, Data: &js_ast.EArray{Items: after, IsSingleLine: isSingleLine}}\n\t\t\ttailInit = js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: tailRef}}\n\t\t\titems = append(items, js_ast.Expr{Loc: loc, Data: &js_ast.ESpread{Value: js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: tailRef}}}})\n\t\t\tp.recordUsage(tailRef)\n\t\t\tp.recordUsage(tailRef)\n\t\t}\n\n\t\t// The original destructuring assignment must come first\n\t\tassign(js_ast.Expr{Loc: split.Loc, Data: &js_ast.EArray{Items: items, IsSingleLine: isSingleLine}}, init)\n\n\t\t// Then the deferred split is evaluated\n\t\tvisit(deferredBinding, js_ast.Expr{Loc: split.Loc, Data: &js_ast.EIdentifier{Ref: splitRef}}, nil)\n\t\tp.recordUsage(splitRef)\n\n\t\t// Then anything after the split\n\t\tif len(after) > 0 {\n\t\t\tvisit(tailExpr, tailInit, nil)\n\t\t}\n\t}\n\n\tsplitObjectPattern := func(\n\t\tupToSplit []js_ast.Property,\n\t\tafterSplit []js_ast.Property,\n\t\tinit js_ast.Expr,\n\t\tcapturedKeys []func() js_ast.Expr,\n\t\tisSingleLine bool,\n\t) {\n\t\t// If there are properties after the split, store the initializer in a\n\t\t// temporary so we can reference it multiple times\n\t\tvar afterSplitInit js_ast.Expr\n\t\tif len(afterSplit) > 0 {\n\t\t\tref := captureIntoRef(init)\n\t\t\tinit = js_ast.Expr{Loc: init.Loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\t\t\tafterSplitInit = js_ast.Expr{Loc: init.Loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\t\t}\n\n\t\tsplit := &upToSplit[len(upToSplit)-1]\n\t\tbinding := &split.ValueOrNil\n\n\t\t// Swap the binding with a temporary\n\t\tsplitRef := p.generateTempRef(declare, \"\")\n\t\tdeferredBinding := *binding\n\t\tbinding.Data = &js_ast.EIdentifier{Ref: splitRef}\n\t\tp.recordUsage(splitRef)\n\n\t\t// Use a destructuring assignment to unpack everything up to and including\n\t\t// the split point\n\t\tassign(js_ast.Expr{Loc: binding.Loc, Data: &js_ast.EObject{Properties: upToSplit, IsSingleLine: isSingleLine}}, init)\n\n\t\t// Handle any nested rest binding patterns inside the split point\n\t\tvisit(deferredBinding, js_ast.Expr{Loc: binding.Loc, Data: &js_ast.EIdentifier{Ref: splitRef}}, nil)\n\t\tp.recordUsage(splitRef)\n\n\t\t// Then continue on to any properties after the split\n\t\tif len(afterSplit) > 0 {\n\t\t\tvisit(js_ast.Expr{Loc: binding.Loc, Data: &js_ast.EObject{\n\t\t\t\tProperties:   afterSplit,\n\t\t\t\tIsSingleLine: isSingleLine,\n\t\t\t}}, afterSplitInit, capturedKeys)\n\t\t}\n\t}\n\n\t// This takes an expression representing a binding pattern as input and\n\t// returns that binding pattern with any object rest patterns stripped out.\n\t// The object rest patterns are lowered and appended to \"exprChain\" along\n\t// with any child binding patterns that came after the binding pattern\n\t// containing the object rest pattern.\n\t//\n\t// This transform must be very careful to preserve the exact evaluation\n\t// order of all assignments, default values, and computed property keys.\n\t//\n\t// Unlike the Babel and TypeScript compilers, this transform does not\n\t// lower binding patterns other than object rest patterns. For example,\n\t// array spread patterns are preserved.\n\t//\n\t// Certain patterns such as \"{a: {...a}, b: {...b}, ...c}\" may need to be\n\t// split multiple times. In this case the \"capturedKeys\" argument allows\n\t// the visitor to pass on captured keys to the tail-recursive call that\n\t// handles the properties after the split.\n\tvisit = func(expr js_ast.Expr, init js_ast.Expr, capturedKeys []func() js_ast.Expr) {\n\t\tswitch e := expr.Data.(type) {\n\t\tcase *js_ast.EArray:\n\t\t\t// Split on the first binding with a nested rest binding pattern\n\t\t\tfor i, item := range e.Items {\n\t\t\t\t// \"let [a, {...b}, c] = d\"\n\t\t\t\tif containsRestBinding[item.Data] {\n\t\t\t\t\tsplitArrayPattern(e.Items[:i], item, append([]js_ast.Expr{}, e.Items[i+1:]...), init, e.IsSingleLine)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *js_ast.EObject:\n\t\t\tlast := len(e.Properties) - 1\n\t\t\tendsWithRestBinding := last >= 0 && e.Properties[last].Kind == js_ast.PropertySpread\n\n\t\t\t// Split on the first binding with a nested rest binding pattern\n\t\t\tfor i := range e.Properties {\n\t\t\t\tproperty := &e.Properties[i]\n\n\t\t\t\t// \"let {a, ...b} = c\"\n\t\t\t\tif property.Kind == js_ast.PropertySpread {\n\t\t\t\t\tlowerObjectRestPattern(e.Properties[:i], property.ValueOrNil, init, capturedKeys, e.IsSingleLine)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Save a copy of this key so the rest binding can exclude it\n\t\t\t\tif endsWithRestBinding {\n\t\t\t\t\tkey, capturedKey := p.captureKeyForObjectRest(property.Key)\n\t\t\t\t\tproperty.Key = key\n\t\t\t\t\tcapturedKeys = append(capturedKeys, capturedKey)\n\t\t\t\t}\n\n\t\t\t\t// \"let {a: {...b}, c} = d\"\n\t\t\t\tif containsRestBinding[property.ValueOrNil.Data] {\n\t\t\t\t\tsplitObjectPattern(e.Properties[:i+1], e.Properties[i+1:], init, capturedKeys, e.IsSingleLine)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tassign(expr, init)\n\t}\n\n\t// Capture and return the value of the initializer if this is an assignment\n\t// expression and the return value is used:\n\t//\n\t//   // Input:\n\t//   console.log({...x} = x);\n\t//\n\t//   // Output:\n\t//   var _a;\n\t//   console.log((x = __objRest(_a = x, []), _a));\n\t//\n\t// This isn't necessary if the return value is unused:\n\t//\n\t//   // Input:\n\t//   ({...x} = x);\n\t//\n\t//   // Output:\n\t//   x = __objRest(x, []);\n\t//\n\tif mode == objRestMustReturnInitExpr {\n\t\tinitFunc, initWrapFunc := p.captureValueWithPossibleSideEffects(rootInit.Loc, 2, rootInit, valueCouldBeMutated)\n\t\trootInit = initFunc()\n\t\twrapFunc = func(expr js_ast.Expr) js_ast.Expr {\n\t\t\treturn initWrapFunc(js_ast.JoinWithComma(expr, initFunc()))\n\t\t}\n\t}\n\n\tvisit(rootExpr, rootInit, nil)\n\treturn wrapFunc, true\n}\n\n// Save a copy of the key for the call to \"__objRest\" later on. Certain\n// expressions can be converted to keys more efficiently than others.\nfunc (p *parser) captureKeyForObjectRest(originalKey js_ast.Expr) (finalKey js_ast.Expr, capturedKey func() js_ast.Expr) {\n\tloc := originalKey.Loc\n\tfinalKey = originalKey\n\n\tswitch k := originalKey.Data.(type) {\n\tcase *js_ast.EString:\n\t\tcapturedKey = func() js_ast.Expr { return js_ast.Expr{Loc: loc, Data: &js_ast.EString{Value: k.Value}} }\n\n\tcase *js_ast.ENumber:\n\t\t// Emit it as the number plus a string (i.e. call toString() on it).\n\t\t// It's important to do it this way instead of trying to print the\n\t\t// float as a string because Go's floating-point printer doesn't\n\t\t// behave exactly the same as JavaScript and if they are different,\n\t\t// the generated code will be wrong.\n\t\tcapturedKey = func() js_ast.Expr {\n\t\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\t\tOp:    js_ast.BinOpAdd,\n\t\t\t\tLeft:  js_ast.Expr{Loc: loc, Data: &js_ast.ENumber{Value: k.Value}},\n\t\t\t\tRight: js_ast.Expr{Loc: loc, Data: &js_ast.EString{}},\n\t\t\t}}\n\t\t}\n\n\tcase *js_ast.EIdentifier:\n\t\tcapturedKey = func() js_ast.Expr {\n\t\t\tp.recordUsage(k.Ref)\n\t\t\treturn p.callRuntime(loc, \"__restKey\", []js_ast.Expr{{Loc: loc, Data: &js_ast.EIdentifier{Ref: k.Ref}}})\n\t\t}\n\n\tdefault:\n\t\t// If it's an arbitrary expression, it probably has a side effect.\n\t\t// Stash it in a temporary reference so we don't evaluate it twice.\n\t\ttempRef := p.generateTempRef(tempRefNeedsDeclare, \"\")\n\t\tfinalKey = js_ast.Assign(js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: tempRef}}, originalKey)\n\t\tcapturedKey = func() js_ast.Expr {\n\t\t\tp.recordUsage(tempRef)\n\t\t\treturn p.callRuntime(loc, \"__restKey\", []js_ast.Expr{{Loc: loc, Data: &js_ast.EIdentifier{Ref: tempRef}}})\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc (p *parser) lowerTemplateLiteral(loc logger.Loc, e *js_ast.ETemplate, tagThisFunc func() js_ast.Expr, tagWrapFunc func(js_ast.Expr) js_ast.Expr) js_ast.Expr {\n\t// If there is no tag, turn this into normal string concatenation\n\tif e.TagOrNil.Data == nil {\n\t\tvar value js_ast.Expr\n\n\t\t// Handle the head\n\t\tvalue = js_ast.Expr{Loc: loc, Data: &js_ast.EString{\n\t\t\tValue:          e.HeadCooked,\n\t\t\tLegacyOctalLoc: e.LegacyOctalLoc,\n\t\t}}\n\n\t\t// Handle the tail. Each one is handled with a separate call to \".concat()\"\n\t\t// to handle various corner cases in the specification including:\n\t\t//\n\t\t//   * For objects, \"toString\" must be called instead of \"valueOf\"\n\t\t//   * Side effects must happen inline instead of at the end\n\t\t//   * Passing a \"Symbol\" instance should throw\n\t\t//\n\t\tfor _, part := range e.Parts {\n\t\t\tvar args []js_ast.Expr\n\t\t\tif len(part.TailCooked) > 0 {\n\t\t\t\targs = []js_ast.Expr{part.Value, {Loc: part.TailLoc, Data: &js_ast.EString{Value: part.TailCooked}}}\n\t\t\t} else {\n\t\t\t\targs = []js_ast.Expr{part.Value}\n\t\t\t}\n\t\t\tvalue = js_ast.Expr{Loc: loc, Data: &js_ast.ECall{\n\t\t\t\tTarget: js_ast.Expr{Loc: loc, Data: &js_ast.EDot{\n\t\t\t\t\tTarget:  value,\n\t\t\t\t\tName:    \"concat\",\n\t\t\t\t\tNameLoc: part.Value.Loc,\n\t\t\t\t}},\n\t\t\t\tArgs: args,\n\t\t\t\tKind: js_ast.TargetWasOriginallyPropertyAccess,\n\t\t\t}}\n\t\t}\n\n\t\treturn value\n\t}\n\n\t// Otherwise, call the tag with the template object\n\tneedsRaw := false\n\tcooked := []js_ast.Expr{}\n\traw := []js_ast.Expr{}\n\targs := make([]js_ast.Expr, 0, 1+len(e.Parts))\n\targs = append(args, js_ast.Expr{})\n\n\t// Handle the head\n\tif e.HeadCooked == nil {\n\t\tcooked = append(cooked, js_ast.Expr{Loc: e.HeadLoc, Data: js_ast.EUndefinedShared})\n\t\tneedsRaw = true\n\t} else {\n\t\tcooked = append(cooked, js_ast.Expr{Loc: e.HeadLoc, Data: &js_ast.EString{Value: e.HeadCooked}})\n\t\tif !helpers.UTF16EqualsString(e.HeadCooked, e.HeadRaw) {\n\t\t\tneedsRaw = true\n\t\t}\n\t}\n\traw = append(raw, js_ast.Expr{Loc: e.HeadLoc, Data: &js_ast.EString{Value: helpers.StringToUTF16(e.HeadRaw)}})\n\n\t// Handle the tail\n\tfor _, part := range e.Parts {\n\t\targs = append(args, part.Value)\n\t\tif part.TailCooked == nil {\n\t\t\tcooked = append(cooked, js_ast.Expr{Loc: part.TailLoc, Data: js_ast.EUndefinedShared})\n\t\t\tneedsRaw = true\n\t\t} else {\n\t\t\tcooked = append(cooked, js_ast.Expr{Loc: part.TailLoc, Data: &js_ast.EString{Value: part.TailCooked}})\n\t\t\tif !helpers.UTF16EqualsString(part.TailCooked, part.TailRaw) {\n\t\t\t\tneedsRaw = true\n\t\t\t}\n\t\t}\n\t\traw = append(raw, js_ast.Expr{Loc: part.TailLoc, Data: &js_ast.EString{Value: helpers.StringToUTF16(part.TailRaw)}})\n\t}\n\n\t// Construct the template object\n\tcookedArray := js_ast.Expr{Loc: e.HeadLoc, Data: &js_ast.EArray{Items: cooked, IsSingleLine: true}}\n\tvar arrays []js_ast.Expr\n\tif needsRaw {\n\t\tarrays = []js_ast.Expr{cookedArray, {Loc: e.HeadLoc, Data: &js_ast.EArray{Items: raw, IsSingleLine: true}}}\n\t} else {\n\t\tarrays = []js_ast.Expr{cookedArray}\n\t}\n\ttemplateObj := p.callRuntime(e.HeadLoc, \"__template\", arrays)\n\n\t// Cache it in a temporary object (required by the specification)\n\ttempRef := p.generateTopLevelTempRef()\n\tp.recordUsage(tempRef)\n\tp.recordUsage(tempRef)\n\targs[0] = js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\tOp:   js_ast.BinOpLogicalOr,\n\t\tLeft: js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: tempRef}},\n\t\tRight: js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\tOp:    js_ast.BinOpAssign,\n\t\t\tLeft:  js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: tempRef}},\n\t\t\tRight: templateObj,\n\t\t}},\n\t}}\n\n\t// If this optional chain was used as a template tag, then also forward the value for \"this\"\n\tif tagThisFunc != nil {\n\t\treturn tagWrapFunc(js_ast.Expr{Loc: loc, Data: &js_ast.ECall{\n\t\t\tTarget: js_ast.Expr{Loc: loc, Data: &js_ast.EDot{\n\t\t\t\tTarget:  e.TagOrNil,\n\t\t\t\tName:    \"call\",\n\t\t\t\tNameLoc: e.HeadLoc,\n\t\t\t}},\n\t\t\tArgs: append([]js_ast.Expr{tagThisFunc()}, args...),\n\t\t\tKind: js_ast.TargetWasOriginallyPropertyAccess,\n\t\t}})\n\t}\n\n\t// Call the tag function\n\tkind := js_ast.NormalCall\n\tif e.TagWasOriginallyPropertyAccess {\n\t\tkind = js_ast.TargetWasOriginallyPropertyAccess\n\t}\n\treturn js_ast.Expr{Loc: loc, Data: &js_ast.ECall{\n\t\tTarget: e.TagOrNil,\n\t\tArgs:   args,\n\t\tKind:   kind,\n\t}}\n}\n\nfunc couldPotentiallyThrow(data js_ast.E) bool {\n\tswitch data.(type) {\n\tcase *js_ast.ENull, *js_ast.EUndefined, *js_ast.EBoolean, *js_ast.ENumber,\n\t\t*js_ast.EBigInt, *js_ast.EString, *js_ast.EFunction, *js_ast.EArrow:\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (p *parser) maybeLowerSetBinOp(left js_ast.Expr, op js_ast.OpCode, right js_ast.Expr) js_ast.Expr {\n\tif target, loc, private := p.extractPrivateIndex(left); private != nil {\n\t\treturn p.lowerPrivateSetBinOp(target, loc, private, op, right)\n\t}\n\tif property := p.extractSuperProperty(left); property.Data != nil {\n\t\treturn p.lowerSuperPropertySetBinOp(left.Loc, property, op, right)\n\t}\n\treturn js_ast.Expr{}\n}\n\nfunc (p *parser) shouldLowerUsingDeclarations(stmts []js_ast.Stmt) bool {\n\tfor _, stmt := range stmts {\n\t\tif local, ok := stmt.Data.(*js_ast.SLocal); ok &&\n\t\t\t((local.Kind == js_ast.LocalUsing && p.options.unsupportedJSFeatures.Has(compat.Using)) ||\n\t\t\t\t(local.Kind == js_ast.LocalAwaitUsing && (p.options.unsupportedJSFeatures.Has(compat.Using) ||\n\t\t\t\t\tp.options.unsupportedJSFeatures.Has(compat.AsyncAwait) ||\n\t\t\t\t\t(p.options.unsupportedJSFeatures.Has(compat.AsyncGenerator) && p.fnOrArrowDataVisit.isGenerator)))) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\ntype lowerUsingDeclarationContext struct {\n\tfirstUsingLoc logger.Loc\n\tstackRef      ast.Ref\n\thasAwaitUsing bool\n}\n\nfunc (p *parser) lowerUsingDeclarationContext() lowerUsingDeclarationContext {\n\treturn lowerUsingDeclarationContext{\n\t\tstackRef: p.newSymbol(ast.SymbolOther, \"_stack\"),\n\t}\n}\n\nfunc (ctx *lowerUsingDeclarationContext) scanStmts(p *parser, stmts []js_ast.Stmt) {\n\tfor _, stmt := range stmts {\n\t\tif local, ok := stmt.Data.(*js_ast.SLocal); ok && local.Kind.IsUsing() {\n\t\t\t// Wrap each \"using\" initializer in a call to the \"__using\" helper function\n\t\t\tif ctx.firstUsingLoc.Start == 0 {\n\t\t\t\tctx.firstUsingLoc = stmt.Loc\n\t\t\t}\n\t\t\tif local.Kind == js_ast.LocalAwaitUsing {\n\t\t\t\tctx.hasAwaitUsing = true\n\t\t\t}\n\t\t\tfor i, decl := range local.Decls {\n\t\t\t\tif decl.ValueOrNil.Data != nil {\n\t\t\t\t\tvalueLoc := decl.ValueOrNil.Loc\n\t\t\t\t\tp.recordUsage(ctx.stackRef)\n\t\t\t\t\targs := []js_ast.Expr{\n\t\t\t\t\t\t{Loc: valueLoc, Data: &js_ast.EIdentifier{Ref: ctx.stackRef}},\n\t\t\t\t\t\tdecl.ValueOrNil,\n\t\t\t\t\t}\n\t\t\t\t\tif local.Kind == js_ast.LocalAwaitUsing {\n\t\t\t\t\t\targs = append(args, js_ast.Expr{Loc: valueLoc, Data: &js_ast.EBoolean{Value: true}})\n\t\t\t\t\t}\n\t\t\t\t\tlocal.Decls[i].ValueOrNil = p.callRuntime(valueLoc, \"__using\", args)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif p.willWrapModuleInTryCatchForUsing && p.currentScope.Parent == nil {\n\t\t\t\tlocal.Kind = js_ast.LocalVar\n\t\t\t} else {\n\t\t\t\tlocal.Kind = p.selectLocalKind(js_ast.LocalConst)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (ctx *lowerUsingDeclarationContext) finalize(p *parser, stmts []js_ast.Stmt, shouldHoistFunctions bool) []js_ast.Stmt {\n\tvar result []js_ast.Stmt\n\tvar exports []js_ast.ClauseItem\n\tend := 0\n\n\t// Filter out statements that can't go in a try/catch block\n\tfor _, stmt := range stmts {\n\t\tswitch s := stmt.Data.(type) {\n\t\t// Note: We don't need to handle class declarations here because they\n\t\t// should have been already converted into local \"var\" declarations\n\t\t// before this point. It's done in \"lowerClass\" instead of here because\n\t\t// \"lowerClass\" already does this sometimes for other reasons, and it's\n\t\t// more straightforward to do it in one place because it's complicated.\n\n\t\tcase *js_ast.SDirective, *js_ast.SImport, *js_ast.SExportFrom, *js_ast.SExportStar:\n\t\t\t// These can't go in a try/catch block\n\t\t\tresult = append(result, stmt)\n\t\t\tcontinue\n\n\t\tcase *js_ast.SExportClause:\n\t\t\t// Merge export clauses together\n\t\t\texports = append(exports, s.Items...)\n\t\t\tcontinue\n\n\t\tcase *js_ast.SFunction:\n\t\t\tif shouldHoistFunctions {\n\t\t\t\t// Hoist function declarations for cross-file ESM references\n\t\t\t\tresult = append(result, stmt)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tcase *js_ast.SExportDefault:\n\t\t\tif _, ok := s.Value.Data.(*js_ast.SFunction); ok && shouldHoistFunctions {\n\t\t\t\t// Hoist function declarations for cross-file ESM references\n\t\t\t\tresult = append(result, stmt)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tcase *js_ast.SLocal:\n\t\t\t// If any of these are exported, turn it into a \"var\" and add export clauses\n\t\t\tif s.IsExport {\n\t\t\t\tjs_ast.ForEachIdentifierBindingInDecls(s.Decls, func(loc logger.Loc, b *js_ast.BIdentifier) {\n\t\t\t\t\texports = append(exports, js_ast.ClauseItem{\n\t\t\t\t\t\tAlias:    p.symbols[b.Ref.InnerIndex].OriginalName,\n\t\t\t\t\t\tAliasLoc: loc,\n\t\t\t\t\t\tName:     ast.LocRef{Loc: loc, Ref: b.Ref},\n\t\t\t\t\t})\n\t\t\t\t\ts.Kind = js_ast.LocalVar\n\t\t\t\t})\n\t\t\t\ts.IsExport = false\n\t\t\t}\n\t\t}\n\n\t\tstmts[end] = stmt\n\t\tend++\n\t}\n\tstmts = stmts[:end]\n\n\t// Generate the variables we'll need\n\tcaughtRef := p.newSymbol(ast.SymbolOther, \"_\")\n\terrorRef := p.newSymbol(ast.SymbolOther, \"_error\")\n\thasErrorRef := p.newSymbol(ast.SymbolOther, \"_hasError\")\n\n\t// Generated variables are declared with \"var\", so hoist them up\n\tscope := p.currentScope\n\tfor !scope.Kind.StopsHoisting() {\n\t\tscope = scope.Parent\n\t}\n\tisTopLevel := scope == p.moduleScope\n\tscope.Generated = append(scope.Generated, ctx.stackRef, caughtRef, errorRef, hasErrorRef)\n\tp.declaredSymbols = append(p.declaredSymbols,\n\t\tjs_ast.DeclaredSymbol{IsTopLevel: isTopLevel, Ref: ctx.stackRef},\n\t\tjs_ast.DeclaredSymbol{IsTopLevel: isTopLevel, Ref: caughtRef},\n\t\tjs_ast.DeclaredSymbol{IsTopLevel: isTopLevel, Ref: errorRef},\n\t\tjs_ast.DeclaredSymbol{IsTopLevel: isTopLevel, Ref: hasErrorRef},\n\t)\n\n\t// Call the \"__callDispose\" helper function at the end of the scope\n\tloc := ctx.firstUsingLoc\n\tp.recordUsage(ctx.stackRef)\n\tp.recordUsage(errorRef)\n\tp.recordUsage(hasErrorRef)\n\tcallDispose := p.callRuntime(loc, \"__callDispose\", []js_ast.Expr{\n\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: ctx.stackRef}},\n\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: errorRef}},\n\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: hasErrorRef}},\n\t})\n\n\t// If there was an \"await using\", optionally await the returned promise\n\tvar finallyStmts []js_ast.Stmt\n\tif ctx.hasAwaitUsing {\n\t\tpromiseRef := p.generateTempRef(tempRefNoDeclare, \"_promise\")\n\t\tscope.Generated = append(scope.Generated, promiseRef)\n\t\tp.declaredSymbols = append(p.declaredSymbols, js_ast.DeclaredSymbol{IsTopLevel: isTopLevel, Ref: promiseRef})\n\n\t\t// \"await\" expressions turn into \"yield\" expressions when lowering\n\t\tp.recordUsage(promiseRef)\n\t\tawaitExpr := p.maybeLowerAwait(loc, &js_ast.EAwait{Value: js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: promiseRef}}})\n\n\t\tp.recordUsage(promiseRef)\n\t\tfinallyStmts = []js_ast.Stmt{\n\t\t\t{Loc: loc, Data: &js_ast.SLocal{Decls: []js_ast.Decl{{\n\t\t\t\tBinding:    js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: promiseRef}},\n\t\t\t\tValueOrNil: callDispose,\n\t\t\t}}}},\n\n\t\t\t// The \"await\" must not happen if an error was thrown before the\n\t\t\t// \"await using\", so we conditionally await here:\n\t\t\t//\n\t\t\t//   var promise = __callDispose(stack, error, hasError);\n\t\t\t//   promise && await promise;\n\t\t\t//\n\t\t\t{Loc: loc, Data: &js_ast.SExpr{Value: js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{\n\t\t\t\tOp:    js_ast.BinOpLogicalAnd,\n\t\t\t\tLeft:  js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: promiseRef}},\n\t\t\t\tRight: awaitExpr,\n\t\t\t}}}},\n\t\t}\n\t} else {\n\t\tfinallyStmts = []js_ast.Stmt{{Loc: loc, Data: &js_ast.SExpr{Value: callDispose}}}\n\t}\n\n\t// Wrap everything in a try/catch/finally block\n\tp.recordUsage(caughtRef)\n\tresult = append(result,\n\t\tjs_ast.Stmt{Loc: loc, Data: &js_ast.SLocal{\n\t\t\tDecls: []js_ast.Decl{{\n\t\t\t\tBinding:    js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: ctx.stackRef}},\n\t\t\t\tValueOrNil: js_ast.Expr{Loc: loc, Data: &js_ast.EArray{}},\n\t\t\t}},\n\t\t}},\n\t\tjs_ast.Stmt{Loc: loc, Data: &js_ast.STry{\n\t\t\tBlock: js_ast.SBlock{\n\t\t\t\tStmts: stmts,\n\t\t\t},\n\t\t\tBlockLoc: loc,\n\t\t\tCatch: &js_ast.Catch{\n\t\t\t\tLoc:          loc,\n\t\t\t\tBindingOrNil: js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: caughtRef}},\n\t\t\t\tBlock: js_ast.SBlock{Stmts: []js_ast.Stmt{{Loc: loc, Data: &js_ast.SLocal{\n\t\t\t\t\tDecls: []js_ast.Decl{{\n\t\t\t\t\t\tBinding:    js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: errorRef}},\n\t\t\t\t\t\tValueOrNil: js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: caughtRef}},\n\t\t\t\t\t}, {\n\t\t\t\t\t\tBinding:    js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: hasErrorRef}},\n\t\t\t\t\t\tValueOrNil: js_ast.Expr{Loc: loc, Data: &js_ast.EBoolean{Value: true}},\n\t\t\t\t\t}},\n\t\t\t\t}}}},\n\t\t\t\tBlockLoc: loc,\n\t\t\t},\n\t\t\tFinally: &js_ast.Finally{\n\t\t\t\tLoc:   loc,\n\t\t\t\tBlock: js_ast.SBlock{Stmts: finallyStmts},\n\t\t\t},\n\t\t}},\n\t)\n\tif len(exports) > 0 {\n\t\tresult = append(result, js_ast.Stmt{Loc: loc, Data: &js_ast.SExportClause{Items: exports}})\n\t}\n\treturn result\n}\n\nfunc (p *parser) lowerUsingDeclarationInForOf(loc logger.Loc, init *js_ast.SLocal, body *js_ast.Stmt) {\n\tbinding := init.Decls[0].Binding\n\tid := binding.Data.(*js_ast.BIdentifier)\n\ttempRef := p.generateTempRef(tempRefNoDeclare, \"_\"+p.symbols[id.Ref.InnerIndex].OriginalName)\n\tblock, ok := body.Data.(*js_ast.SBlock)\n\tif !ok {\n\t\tblock = &js_ast.SBlock{}\n\t\tif _, ok := body.Data.(*js_ast.SEmpty); !ok {\n\t\t\tblock.Stmts = append(block.Stmts, *body)\n\t\t}\n\t\tbody.Data = block\n\t}\n\tblockStmts := make([]js_ast.Stmt, 0, 1+len(block.Stmts))\n\tblockStmts = append(blockStmts, js_ast.Stmt{Loc: loc, Data: &js_ast.SLocal{\n\t\tKind: init.Kind,\n\t\tDecls: []js_ast.Decl{{\n\t\t\tBinding:    js_ast.Binding{Loc: binding.Loc, Data: &js_ast.BIdentifier{Ref: id.Ref}},\n\t\t\tValueOrNil: js_ast.Expr{Loc: binding.Loc, Data: &js_ast.EIdentifier{Ref: tempRef}},\n\t\t}},\n\t}})\n\tblockStmts = append(blockStmts, block.Stmts...)\n\tctx := p.lowerUsingDeclarationContext()\n\tctx.scanStmts(p, blockStmts)\n\tblock.Stmts = ctx.finalize(p, blockStmts, p.willWrapModuleInTryCatchForUsing && p.currentScope.Parent == nil)\n\tinit.Kind = js_ast.LocalVar\n\tid.Ref = tempRef\n}\n"
  },
  {
    "path": "internal/js_parser/js_parser_lower_class.go",
    "content": "package js_parser\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\nfunc (p *parser) privateSymbolNeedsToBeLowered(private *js_ast.EPrivateIdentifier) bool {\n\tsymbol := &p.symbols[private.Ref.InnerIndex]\n\treturn p.options.unsupportedJSFeatures.Has(compat.SymbolFeature(symbol.Kind)) || symbol.Flags.Has(ast.PrivateSymbolMustBeLowered)\n}\n\nfunc (p *parser) lowerPrivateBrandCheck(target js_ast.Expr, loc logger.Loc, private *js_ast.EPrivateIdentifier) js_ast.Expr {\n\t// \"#field in this\" => \"__privateIn(#field, this)\"\n\treturn p.callRuntime(loc, \"__privateIn\", []js_ast.Expr{\n\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: private.Ref}},\n\t\ttarget,\n\t})\n}\n\nfunc (p *parser) lowerPrivateGet(target js_ast.Expr, loc logger.Loc, private *js_ast.EPrivateIdentifier) js_ast.Expr {\n\tswitch p.symbols[private.Ref.InnerIndex].Kind {\n\tcase ast.SymbolPrivateMethod, ast.SymbolPrivateStaticMethod:\n\t\t// \"this.#method\" => \"__privateMethod(this, #method, method_fn)\"\n\t\tfnRef := p.privateGetters[private.Ref]\n\t\tp.recordUsage(fnRef)\n\t\treturn p.callRuntime(target.Loc, \"__privateMethod\", []js_ast.Expr{\n\t\t\ttarget,\n\t\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: private.Ref}},\n\t\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: fnRef}},\n\t\t})\n\n\tcase ast.SymbolPrivateGet, ast.SymbolPrivateStaticGet,\n\t\tast.SymbolPrivateGetSetPair, ast.SymbolPrivateStaticGetSetPair:\n\t\t// \"this.#getter\" => \"__privateGet(this, #getter, getter_get)\"\n\t\tfnRef := p.privateGetters[private.Ref]\n\t\tp.recordUsage(fnRef)\n\t\treturn p.callRuntime(target.Loc, \"__privateGet\", []js_ast.Expr{\n\t\t\ttarget,\n\t\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: private.Ref}},\n\t\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: fnRef}},\n\t\t})\n\n\tdefault:\n\t\t// \"this.#field\" => \"__privateGet(this, #field)\"\n\t\treturn p.callRuntime(target.Loc, \"__privateGet\", []js_ast.Expr{\n\t\t\ttarget,\n\t\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: private.Ref}},\n\t\t})\n\t}\n}\n\nfunc (p *parser) lowerPrivateSet(\n\ttarget js_ast.Expr,\n\tloc logger.Loc,\n\tprivate *js_ast.EPrivateIdentifier,\n\tvalue js_ast.Expr,\n) js_ast.Expr {\n\tswitch p.symbols[private.Ref.InnerIndex].Kind {\n\tcase ast.SymbolPrivateSet, ast.SymbolPrivateStaticSet,\n\t\tast.SymbolPrivateGetSetPair, ast.SymbolPrivateStaticGetSetPair:\n\t\t// \"this.#setter = 123\" => \"__privateSet(this, #setter, 123, setter_set)\"\n\t\tfnRef := p.privateSetters[private.Ref]\n\t\tp.recordUsage(fnRef)\n\t\treturn p.callRuntime(target.Loc, \"__privateSet\", []js_ast.Expr{\n\t\t\ttarget,\n\t\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: private.Ref}},\n\t\t\tvalue,\n\t\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: fnRef}},\n\t\t})\n\n\tdefault:\n\t\t// \"this.#field = 123\" => \"__privateSet(this, #field, 123)\"\n\t\treturn p.callRuntime(target.Loc, \"__privateSet\", []js_ast.Expr{\n\t\t\ttarget,\n\t\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: private.Ref}},\n\t\t\tvalue,\n\t\t})\n\t}\n}\n\nfunc (p *parser) lowerPrivateSetUnOp(target js_ast.Expr, loc logger.Loc, private *js_ast.EPrivateIdentifier, op js_ast.OpCode) js_ast.Expr {\n\tkind := p.symbols[private.Ref.InnerIndex].Kind\n\n\t// Determine the setter, if any\n\tvar setter js_ast.Expr\n\tswitch kind {\n\tcase ast.SymbolPrivateSet, ast.SymbolPrivateStaticSet,\n\t\tast.SymbolPrivateGetSetPair, ast.SymbolPrivateStaticGetSetPair:\n\t\tref := p.privateSetters[private.Ref]\n\t\tp.recordUsage(ref)\n\t\tsetter = js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\t}\n\n\t// Determine the getter, if any\n\tvar getter js_ast.Expr\n\tswitch kind {\n\tcase ast.SymbolPrivateGet, ast.SymbolPrivateStaticGet,\n\t\tast.SymbolPrivateGetSetPair, ast.SymbolPrivateStaticGetSetPair:\n\t\tref := p.privateGetters[private.Ref]\n\t\tp.recordUsage(ref)\n\t\tgetter = js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\t}\n\n\t// Only include necessary arguments\n\targs := []js_ast.Expr{\n\t\ttarget,\n\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: private.Ref}},\n\t}\n\tif setter.Data != nil {\n\t\targs = append(args, setter)\n\t}\n\tif getter.Data != nil {\n\t\tif setter.Data == nil {\n\t\t\targs = append(args, js_ast.Expr{Loc: loc, Data: js_ast.ENullShared})\n\t\t}\n\t\targs = append(args, getter)\n\t}\n\n\t// \"target.#private++\" => \"__privateWrapper(target, #private, private_set, private_get)._++\"\n\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EUnary{\n\t\tOp: op,\n\t\tValue: js_ast.Expr{Loc: target.Loc, Data: &js_ast.EDot{\n\t\t\tTarget:  p.callRuntime(target.Loc, \"__privateWrapper\", args),\n\t\t\tNameLoc: target.Loc,\n\t\t\tName:    \"_\",\n\t\t}},\n\t}}\n}\n\nfunc (p *parser) lowerPrivateSetBinOp(target js_ast.Expr, loc logger.Loc, private *js_ast.EPrivateIdentifier, op js_ast.OpCode, value js_ast.Expr) js_ast.Expr {\n\t// \"target.#private += 123\" => \"__privateSet(target, #private, __privateGet(target, #private) + 123)\"\n\ttargetFunc, targetWrapFunc := p.captureValueWithPossibleSideEffects(target.Loc, 2, target, valueDefinitelyNotMutated)\n\treturn targetWrapFunc(p.lowerPrivateSet(targetFunc(), loc, private, js_ast.Expr{Loc: value.Loc, Data: &js_ast.EBinary{\n\t\tOp:    op,\n\t\tLeft:  p.lowerPrivateGet(targetFunc(), loc, private),\n\t\tRight: value,\n\t}}))\n}\n\n// Returns valid data if target is an expression of the form \"foo.#bar\" and if\n// the language target is such that private members must be lowered\nfunc (p *parser) extractPrivateIndex(target js_ast.Expr) (js_ast.Expr, logger.Loc, *js_ast.EPrivateIdentifier) {\n\tif index, ok := target.Data.(*js_ast.EIndex); ok {\n\t\tif private, ok := index.Index.Data.(*js_ast.EPrivateIdentifier); ok && p.privateSymbolNeedsToBeLowered(private) {\n\t\t\treturn index.Target, index.Index.Loc, private\n\t\t}\n\t}\n\treturn js_ast.Expr{}, logger.Loc{}, nil\n}\n\n// Returns a valid property if target is an expression of the form \"super.bar\"\n// or \"super[bar]\" and if the situation is such that it must be lowered\nfunc (p *parser) extractSuperProperty(target js_ast.Expr) js_ast.Expr {\n\tswitch e := target.Data.(type) {\n\tcase *js_ast.EDot:\n\t\tif p.shouldLowerSuperPropertyAccess(e.Target) {\n\t\t\treturn js_ast.Expr{Loc: e.NameLoc, Data: &js_ast.EString{Value: helpers.StringToUTF16(e.Name)}}\n\t\t}\n\tcase *js_ast.EIndex:\n\t\tif p.shouldLowerSuperPropertyAccess(e.Target) {\n\t\t\treturn e.Index\n\t\t}\n\t}\n\treturn js_ast.Expr{}\n}\n\nfunc (p *parser) lowerSuperPropertyOrPrivateInAssign(expr js_ast.Expr) (js_ast.Expr, bool) {\n\tdidLower := false\n\n\tswitch e := expr.Data.(type) {\n\tcase *js_ast.ESpread:\n\t\tif value, ok := p.lowerSuperPropertyOrPrivateInAssign(e.Value); ok {\n\t\t\te.Value = value\n\t\t\tdidLower = true\n\t\t}\n\n\tcase *js_ast.EDot:\n\t\t// \"[super.foo] = [bar]\" => \"[__superWrapper(this, 'foo')._] = [bar]\"\n\t\tif p.shouldLowerSuperPropertyAccess(e.Target) {\n\t\t\tkey := js_ast.Expr{Loc: e.NameLoc, Data: &js_ast.EString{Value: helpers.StringToUTF16(e.Name)}}\n\t\t\texpr = p.callSuperPropertyWrapper(expr.Loc, key)\n\t\t\tdidLower = true\n\t\t}\n\n\tcase *js_ast.EIndex:\n\t\t// \"[super[foo]] = [bar]\" => \"[__superWrapper(this, foo)._] = [bar]\"\n\t\tif p.shouldLowerSuperPropertyAccess(e.Target) {\n\t\t\texpr = p.callSuperPropertyWrapper(expr.Loc, e.Index)\n\t\t\tdidLower = true\n\t\t\tbreak\n\t\t}\n\n\t\t// \"[a.#b] = [c]\" => \"[__privateWrapper(a, #b)._] = [c]\"\n\t\tif private, ok := e.Index.Data.(*js_ast.EPrivateIdentifier); ok && p.privateSymbolNeedsToBeLowered(private) {\n\t\t\tvar target js_ast.Expr\n\n\t\t\tswitch p.symbols[private.Ref.InnerIndex].Kind {\n\t\t\tcase ast.SymbolPrivateSet, ast.SymbolPrivateStaticSet,\n\t\t\t\tast.SymbolPrivateGetSetPair, ast.SymbolPrivateStaticGetSetPair:\n\t\t\t\t// \"this.#setter\" => \"__privateWrapper(this, #setter, setter_set)\"\n\t\t\t\tfnRef := p.privateSetters[private.Ref]\n\t\t\t\tp.recordUsage(fnRef)\n\t\t\t\ttarget = p.callRuntime(expr.Loc, \"__privateWrapper\", []js_ast.Expr{\n\t\t\t\t\te.Target,\n\t\t\t\t\t{Loc: expr.Loc, Data: &js_ast.EIdentifier{Ref: private.Ref}},\n\t\t\t\t\t{Loc: expr.Loc, Data: &js_ast.EIdentifier{Ref: fnRef}},\n\t\t\t\t})\n\n\t\t\tdefault:\n\t\t\t\t// \"this.#field\" => \"__privateWrapper(this, #field)\"\n\t\t\t\ttarget = p.callRuntime(expr.Loc, \"__privateWrapper\", []js_ast.Expr{\n\t\t\t\t\te.Target,\n\t\t\t\t\t{Loc: expr.Loc, Data: &js_ast.EIdentifier{Ref: private.Ref}},\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// \"__privateWrapper(this, #field)\" => \"__privateWrapper(this, #field)._\"\n\t\t\texpr.Data = &js_ast.EDot{Target: target, Name: \"_\", NameLoc: expr.Loc}\n\t\t\tdidLower = true\n\t\t}\n\n\tcase *js_ast.EArray:\n\t\tfor i, item := range e.Items {\n\t\t\tif item, ok := p.lowerSuperPropertyOrPrivateInAssign(item); ok {\n\t\t\t\te.Items[i] = item\n\t\t\t\tdidLower = true\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.EObject:\n\t\tfor i, property := range e.Properties {\n\t\t\tif property.ValueOrNil.Data != nil {\n\t\t\t\tif value, ok := p.lowerSuperPropertyOrPrivateInAssign(property.ValueOrNil); ok {\n\t\t\t\t\te.Properties[i].ValueOrNil = value\n\t\t\t\t\tdidLower = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn expr, didLower\n}\n\nfunc (p *parser) shouldLowerSuperPropertyAccess(expr js_ast.Expr) bool {\n\tif p.fnOrArrowDataVisit.shouldLowerSuperPropertyAccess {\n\t\t_, isSuper := expr.Data.(*js_ast.ESuper)\n\t\treturn isSuper\n\t}\n\treturn false\n}\n\nfunc (p *parser) callSuperPropertyWrapper(loc logger.Loc, key js_ast.Expr) js_ast.Expr {\n\tref := *p.fnOnlyDataVisit.innerClassNameRef\n\tp.recordUsage(ref)\n\tclass := js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\tthis := js_ast.Expr{Loc: loc, Data: js_ast.EThisShared}\n\n\t// Handle \"this\" in lowered static class field initializers\n\tif p.fnOnlyDataVisit.shouldReplaceThisWithInnerClassNameRef {\n\t\tp.recordUsage(ref)\n\t\tthis.Data = &js_ast.EIdentifier{Ref: ref}\n\t}\n\n\tif !p.fnOnlyDataVisit.isInStaticClassContext {\n\t\t// \"super.foo\" => \"__superWrapper(Class.prototype, this, 'foo')._\"\n\t\t// \"super[foo]\" => \"__superWrapper(Class.prototype, this, foo)._\"\n\t\tclass.Data = &js_ast.EDot{Target: class, NameLoc: loc, Name: \"prototype\"}\n\t}\n\n\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EDot{Target: p.callRuntime(loc, \"__superWrapper\", []js_ast.Expr{\n\t\tclass,\n\t\tthis,\n\t\tkey,\n\t}), Name: \"_\", NameLoc: loc}}\n}\n\nfunc (p *parser) lowerSuperPropertyGet(loc logger.Loc, key js_ast.Expr) js_ast.Expr {\n\tref := *p.fnOnlyDataVisit.innerClassNameRef\n\tp.recordUsage(ref)\n\tclass := js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\tthis := js_ast.Expr{Loc: loc, Data: js_ast.EThisShared}\n\n\t// Handle \"this\" in lowered static class field initializers\n\tif p.fnOnlyDataVisit.shouldReplaceThisWithInnerClassNameRef {\n\t\tp.recordUsage(ref)\n\t\tthis.Data = &js_ast.EIdentifier{Ref: ref}\n\t}\n\n\tif !p.fnOnlyDataVisit.isInStaticClassContext {\n\t\t// \"super.foo\" => \"__superGet(Class.prototype, this, 'foo')\"\n\t\t// \"super[foo]\" => \"__superGet(Class.prototype, this, foo)\"\n\t\tclass.Data = &js_ast.EDot{Target: class, NameLoc: loc, Name: \"prototype\"}\n\t}\n\n\treturn p.callRuntime(loc, \"__superGet\", []js_ast.Expr{\n\t\tclass,\n\t\tthis,\n\t\tkey,\n\t})\n}\n\nfunc (p *parser) lowerSuperPropertySet(loc logger.Loc, key js_ast.Expr, value js_ast.Expr) js_ast.Expr {\n\t// \"super.foo = bar\" => \"__superSet(Class, this, 'foo', bar)\"\n\t// \"super[foo] = bar\" => \"__superSet(Class, this, foo, bar)\"\n\tref := *p.fnOnlyDataVisit.innerClassNameRef\n\tp.recordUsage(ref)\n\tclass := js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\tthis := js_ast.Expr{Loc: loc, Data: js_ast.EThisShared}\n\n\t// Handle \"this\" in lowered static class field initializers\n\tif p.fnOnlyDataVisit.shouldReplaceThisWithInnerClassNameRef {\n\t\tp.recordUsage(ref)\n\t\tthis.Data = &js_ast.EIdentifier{Ref: ref}\n\t}\n\n\tif !p.fnOnlyDataVisit.isInStaticClassContext {\n\t\t// \"super.foo = bar\" => \"__superSet(Class.prototype, this, 'foo', bar)\"\n\t\t// \"super[foo] = bar\" => \"__superSet(Class.prototype, this, foo, bar)\"\n\t\tclass.Data = &js_ast.EDot{Target: class, NameLoc: loc, Name: \"prototype\"}\n\t}\n\n\treturn p.callRuntime(loc, \"__superSet\", []js_ast.Expr{\n\t\tclass,\n\t\tthis,\n\t\tkey,\n\t\tvalue,\n\t})\n}\n\nfunc (p *parser) lowerSuperPropertySetBinOp(loc logger.Loc, property js_ast.Expr, op js_ast.OpCode, value js_ast.Expr) js_ast.Expr {\n\t// \"super.foo += bar\" => \"__superSet(Class, this, 'foo', __superGet(Class, this, 'foo') + bar)\"\n\t// \"super[foo] += bar\" => \"__superSet(Class, this, foo, __superGet(Class, this, foo) + bar)\"\n\t// \"super[foo()] += bar\" => \"__superSet(Class, this, _a = foo(), __superGet(Class, this, _a) + bar)\"\n\ttargetFunc, targetWrapFunc := p.captureValueWithPossibleSideEffects(property.Loc, 2, property, valueDefinitelyNotMutated)\n\treturn targetWrapFunc(p.lowerSuperPropertySet(loc, targetFunc(), js_ast.Expr{Loc: value.Loc, Data: &js_ast.EBinary{\n\t\tOp:    op,\n\t\tLeft:  p.lowerSuperPropertyGet(loc, targetFunc()),\n\t\tRight: value,\n\t}}))\n}\n\nfunc (p *parser) maybeLowerSuperPropertyGetInsideCall(call *js_ast.ECall) {\n\tvar key js_ast.Expr\n\n\tswitch e := call.Target.Data.(type) {\n\tcase *js_ast.EDot:\n\t\t// Lower \"super.prop\" if necessary\n\t\tif !p.shouldLowerSuperPropertyAccess(e.Target) {\n\t\t\treturn\n\t\t}\n\t\tkey = js_ast.Expr{Loc: e.NameLoc, Data: &js_ast.EString{Value: helpers.StringToUTF16(e.Name)}}\n\n\tcase *js_ast.EIndex:\n\t\t// Lower \"super[prop]\" if necessary\n\t\tif !p.shouldLowerSuperPropertyAccess(e.Target) {\n\t\t\treturn\n\t\t}\n\t\tkey = e.Index\n\n\tdefault:\n\t\treturn\n\t}\n\n\t// \"super.foo(a, b)\" => \"__superGet(Class, this, 'foo').call(this, a, b)\"\n\tcall.Target.Data = &js_ast.EDot{\n\t\tTarget:  p.lowerSuperPropertyGet(call.Target.Loc, key),\n\t\tNameLoc: key.Loc,\n\t\tName:    \"call\",\n\t}\n\tthisExpr := js_ast.Expr{Loc: call.Target.Loc, Data: js_ast.EThisShared}\n\tcall.Args = append([]js_ast.Expr{thisExpr}, call.Args...)\n}\n\ntype classLoweringInfo struct {\n\tlowerAllInstanceFields bool\n\tlowerAllStaticFields   bool\n\tshimSuperCtorCalls     bool\n}\n\nfunc (p *parser) computeClassLoweringInfo(class *js_ast.Class) (result classLoweringInfo) {\n\t// Name keeping for classes is implemented with a static block. So we need to\n\t// lower all static fields if static blocks are unsupported so that the name\n\t// keeping comes first before other static initializers.\n\tif p.options.keepNames && p.options.unsupportedJSFeatures.Has(compat.ClassStaticBlocks) {\n\t\tresult.lowerAllStaticFields = true\n\t}\n\n\t// TypeScript's \"experimentalDecorators\" feature replaces all references of\n\t// the class name with the decorated class after class decorators have run.\n\t// This cannot be done by only reassigning to the class symbol in JavaScript\n\t// because it's shadowed by the class name within the class body. Instead,\n\t// we need to hoist all code in static contexts out of the class body so\n\t// that it's no longer shadowed:\n\t//\n\t//   const decorate = x => ({ x })\n\t//   @decorate\n\t//   class Foo {\n\t//     static oldFoo = Foo\n\t//     static newFoo = () => Foo\n\t//   }\n\t//   console.log('This must be false:', Foo.x.oldFoo === Foo.x.newFoo())\n\t//\n\tif p.options.ts.Parse && p.options.ts.Config.ExperimentalDecorators == config.True && len(class.Decorators) > 0 {\n\t\tresult.lowerAllStaticFields = true\n\t}\n\n\t// If something has decorators, just lower everything for now. It's possible\n\t// that we could avoid lowering in certain cases, but doing so is very tricky\n\t// due to the complexity of the decorator specification. The specification is\n\t// also still evolving so trying to optimize it now is also potentially\n\t// premature.\n\tif class.ShouldLowerStandardDecorators {\n\t\tfor _, prop := range class.Properties {\n\t\t\tif len(prop.Decorators) > 0 {\n\t\t\t\tfor _, prop := range class.Properties {\n\t\t\t\t\tif private, ok := prop.Key.Data.(*js_ast.EPrivateIdentifier); ok {\n\t\t\t\t\t\tp.symbols[private.Ref.InnerIndex].Flags |= ast.PrivateSymbolMustBeLowered\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresult.lowerAllStaticFields = true\n\t\t\t\tresult.lowerAllInstanceFields = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\t// Conservatively lower fields of a given type (instance or static) when any\n\t// member of that type needs to be lowered. This must be done to preserve\n\t// evaluation order. For example:\n\t//\n\t//   class Foo {\n\t//     #foo = 123\n\t//     bar = this.#foo\n\t//   }\n\t//\n\t// It would be bad if we transformed that into something like this:\n\t//\n\t//   var _foo;\n\t//   class Foo {\n\t//     constructor() {\n\t//       _foo.set(this, 123);\n\t//     }\n\t//     bar = __privateGet(this, _foo);\n\t//   }\n\t//   _foo = new WeakMap();\n\t//\n\t// That evaluates \"bar\" then \"foo\" instead of \"foo\" then \"bar\" like the\n\t// original code. We need to do this instead:\n\t//\n\t//   var _foo;\n\t//   class Foo {\n\t//     constructor() {\n\t//       _foo.set(this, 123);\n\t//       __publicField(this, \"bar\", __privateGet(this, _foo));\n\t//     }\n\t//   }\n\t//   _foo = new WeakMap();\n\t//\n\tfor _, prop := range class.Properties {\n\t\tif prop.Kind == js_ast.PropertyClassStaticBlock {\n\t\t\tif p.options.unsupportedJSFeatures.Has(compat.ClassStaticBlocks) {\n\t\t\t\tresult.lowerAllStaticFields = true\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif private, ok := prop.Key.Data.(*js_ast.EPrivateIdentifier); ok {\n\t\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t\tif p.privateSymbolNeedsToBeLowered(private) {\n\t\t\t\t\tresult.lowerAllStaticFields = true\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif p.privateSymbolNeedsToBeLowered(private) {\n\t\t\t\t\tresult.lowerAllInstanceFields = true\n\n\t\t\t\t\t// We can't transform this:\n\t\t\t\t\t//\n\t\t\t\t\t//   class Foo {\n\t\t\t\t\t//     #foo = 123\n\t\t\t\t\t//     static bar = new Foo().#foo\n\t\t\t\t\t//   }\n\t\t\t\t\t//\n\t\t\t\t\t// into this:\n\t\t\t\t\t//\n\t\t\t\t\t//   var _foo;\n\t\t\t\t\t//   const _Foo = class {\n\t\t\t\t\t//     constructor() {\n\t\t\t\t\t//       _foo.set(this, 123);\n\t\t\t\t\t//     }\n\t\t\t\t\t//     static bar = __privateGet(new _Foo(), _foo);\n\t\t\t\t\t//   };\n\t\t\t\t\t//   let Foo = _Foo;\n\t\t\t\t\t//   _foo = new WeakMap();\n\t\t\t\t\t//\n\t\t\t\t\t// because \"_Foo\" won't be initialized in the initializer for \"bar\".\n\t\t\t\t\t// So we currently lower all static fields in this case too. This\n\t\t\t\t\t// isn't great and it would be good to find a way to avoid this.\n\t\t\t\t\t// The inner class name symbol substitution mechanism should probably\n\t\t\t\t\t// be rethought.\n\t\t\t\t\tresult.lowerAllStaticFields = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif prop.Kind == js_ast.PropertyAutoAccessor {\n\t\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t\tif p.options.unsupportedJSFeatures.Has(compat.ClassPrivateStaticField) {\n\t\t\t\t\tresult.lowerAllStaticFields = true\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif p.options.unsupportedJSFeatures.Has(compat.ClassPrivateField) {\n\t\t\t\t\tresult.lowerAllInstanceFields = true\n\t\t\t\t\tresult.lowerAllStaticFields = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// This doesn't come before the private member check above because\n\t\t// unsupported private methods must also trigger field lowering:\n\t\t//\n\t\t//   class Foo {\n\t\t//     bar = this.#foo()\n\t\t//     #foo() {}\n\t\t//   }\n\t\t//\n\t\t// It would be bad if we transformed that to something like this:\n\t\t//\n\t\t//   var _foo, foo_fn;\n\t\t//   class Foo {\n\t\t//     constructor() {\n\t\t//       _foo.add(this);\n\t\t//     }\n\t\t//     bar = __privateMethod(this, _foo, foo_fn).call(this);\n\t\t//   }\n\t\t//   _foo = new WeakSet();\n\t\t//   foo_fn = function() {\n\t\t//   };\n\t\t//\n\t\t// In that case the initializer of \"bar\" would fail to call \"#foo\" because\n\t\t// it's only added to the instance in the body of the constructor.\n\t\tif prop.Kind.IsMethodDefinition() {\n\t\t\t// We need to shim \"super()\" inside the constructor if this is a derived\n\t\t\t// class and the constructor has any parameter properties, since those\n\t\t\t// use \"this\" and we can only access \"this\" after \"super()\" is called\n\t\t\tif class.ExtendsOrNil.Data != nil {\n\t\t\t\tif key, ok := prop.Key.Data.(*js_ast.EString); ok && helpers.UTF16EqualsString(key.Value, \"constructor\") {\n\t\t\t\t\tif fn, ok := prop.ValueOrNil.Data.(*js_ast.EFunction); ok {\n\t\t\t\t\t\tfor _, arg := range fn.Fn.Args {\n\t\t\t\t\t\t\tif arg.IsTypeScriptCtorField {\n\t\t\t\t\t\t\t\tresult.shimSuperCtorCalls = true\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t// Static fields must be lowered if the target doesn't support them\n\t\t\tif p.options.unsupportedJSFeatures.Has(compat.ClassStaticField) {\n\t\t\t\tresult.lowerAllStaticFields = true\n\t\t\t}\n\n\t\t\t// Convert static fields to assignment statements if the TypeScript\n\t\t\t// setting for this is enabled. I don't think this matters for private\n\t\t\t// fields because there's no way for this to call a setter in the base\n\t\t\t// class, so this isn't done for private fields.\n\t\t\t//\n\t\t\t// If class static blocks are supported, then we can do this inline\n\t\t\t// without needing to move the initializers outside of the class body.\n\t\t\t// Otherwise, we need to lower all static class fields.\n\t\t\tif p.options.ts.Parse && !class.UseDefineForClassFields && p.options.unsupportedJSFeatures.Has(compat.ClassStaticBlocks) {\n\t\t\t\tresult.lowerAllStaticFields = true\n\t\t\t}\n\t\t} else {\n\t\t\tif p.options.ts.Parse && !class.UseDefineForClassFields {\n\t\t\t\t// Convert instance fields to assignment statements if the TypeScript\n\t\t\t\t// setting for this is enabled. I don't think this matters for private\n\t\t\t\t// fields because there's no way for this to call a setter in the base\n\t\t\t\t// class, so this isn't done for private fields.\n\t\t\t\tif prop.InitializerOrNil.Data != nil {\n\t\t\t\t\t// We can skip lowering all instance fields if all instance fields\n\t\t\t\t\t// disappear completely when lowered. This happens when\n\t\t\t\t\t// \"useDefineForClassFields\" is false and there is no initializer.\n\t\t\t\t\tresult.lowerAllInstanceFields = true\n\t\t\t\t}\n\t\t\t} else if p.options.unsupportedJSFeatures.Has(compat.ClassField) {\n\t\t\t\t// Instance fields must be lowered if the target doesn't support them\n\t\t\t\tresult.lowerAllInstanceFields = true\n\t\t\t}\n\t\t}\n\t}\n\n\t// We need to shim \"super()\" inside the constructor if this is a derived\n\t// class and there are any instance fields that need to be lowered, since\n\t// those use \"this\" and we can only access \"this\" after \"super()\" is called\n\tif result.lowerAllInstanceFields && class.ExtendsOrNil.Data != nil {\n\t\tresult.shimSuperCtorCalls = true\n\t}\n\n\treturn\n}\n\ntype classKind uint8\n\nconst (\n\tclassKindExpr classKind = iota\n\tclassKindStmt\n\tclassKindExportStmt\n\tclassKindExportDefaultStmt\n)\n\ntype lowerClassContext struct {\n\tnameToKeep  string\n\tkind        classKind\n\tclass       *js_ast.Class\n\tclassLoc    logger.Loc\n\tclassExpr   js_ast.Expr // Only for \"kind == classKindExpr\", may be replaced by \"nameFunc()\"\n\tdefaultName ast.LocRef\n\n\tctor                   *js_ast.EFunction\n\textendsRef             ast.Ref\n\tparameterFields        []js_ast.Stmt\n\tinstanceMembers        []js_ast.Stmt\n\tinstancePrivateMethods []js_ast.Stmt\n\tautoAccessorCount      int\n\n\t// These expressions are generated after the class body, in this order\n\tcomputedPropertyChain js_ast.Expr\n\tprivateMembers        []js_ast.Expr\n\tstaticMembers         []js_ast.Expr\n\tstaticPrivateMethods  []js_ast.Expr\n\n\t// These contain calls to \"__decorateClass\" for TypeScript experimental decorators\n\tinstanceExperimentalDecorators []js_ast.Expr\n\tstaticExperimentalDecorators   []js_ast.Expr\n\n\t// These are used for implementing JavaScript decorators\n\tdecoratorContextRef                          ast.Ref\n\tdecoratorClassDecorators                     js_ast.Expr\n\tdecoratorPropertyToInitializerMap            map[int]int\n\tdecoratorCallInstanceMethodExtraInitializers bool\n\tdecoratorCallStaticMethodExtraInitializers   bool\n\tdecoratorStaticNonFieldElements              []js_ast.Expr\n\tdecoratorInstanceNonFieldElements            []js_ast.Expr\n\tdecoratorStaticFieldElements                 []js_ast.Expr\n\tdecoratorInstanceFieldElements               []js_ast.Expr\n\n\t// These are used by \"lowerMethod\"\n\tprivateInstanceMethodRef ast.Ref\n\tprivateStaticMethodRef   ast.Ref\n\n\t// These are only for class expressions that need to be captured\n\tnameFunc            func() js_ast.Expr\n\twrapFunc            func(js_ast.Expr) js_ast.Expr\n\tdidCaptureClassExpr bool\n}\n\n// Apply all relevant transforms to a class object (either a statement or an\n// expression) including:\n//\n//   - Transforming class fields for older environments\n//   - Transforming static blocks for older environments\n//   - Transforming TypeScript experimental decorators into JavaScript\n//   - Transforming TypeScript class fields into assignments for \"useDefineForClassFields\"\n//\n// Note that this doesn't transform any nested AST subtrees inside the class\n// body (e.g. the contents of initializers, methods, and static blocks). Those\n// have already been transformed by \"visitClass\" by this point. It's done that\n// way for performance so that we don't need to do another AST pass.\nfunc (p *parser) lowerClass(stmt js_ast.Stmt, expr js_ast.Expr, result visitClassResult, nameToKeep string) ([]js_ast.Stmt, js_ast.Expr) {\n\tctx := lowerClassContext{\n\t\tnameToKeep:               nameToKeep,\n\t\textendsRef:               ast.InvalidRef,\n\t\tdecoratorContextRef:      ast.InvalidRef,\n\t\tprivateInstanceMethodRef: ast.InvalidRef,\n\t\tprivateStaticMethodRef:   ast.InvalidRef,\n\t}\n\n\t// Unpack the class from the statement or expression\n\tif stmt.Data == nil {\n\t\te, _ := expr.Data.(*js_ast.EClass)\n\t\tctx.class = &e.Class\n\t\tctx.classExpr = expr\n\t\tctx.kind = classKindExpr\n\t\tif ctx.class.Name != nil {\n\t\t\tsymbol := &p.symbols[ctx.class.Name.Ref.InnerIndex]\n\t\t\tctx.nameToKeep = symbol.OriginalName\n\n\t\t\t// The inner class name inside the class expression should be the same as\n\t\t\t// the class expression name itself\n\t\t\tif result.innerClassNameRef != ast.InvalidRef {\n\t\t\t\tp.mergeSymbols(result.innerClassNameRef, ctx.class.Name.Ref)\n\t\t\t}\n\n\t\t\t// Remove unused class names when minifying. Check this after we merge in\n\t\t\t// the inner class name above since that will adjust the use count.\n\t\t\tif p.options.minifySyntax && symbol.UseCountEstimate == 0 {\n\t\t\t\tctx.class.Name = nil\n\t\t\t}\n\t\t}\n\t} else if s, ok := stmt.Data.(*js_ast.SClass); ok {\n\t\tctx.class = &s.Class\n\t\tif ctx.class.Name != nil {\n\t\t\tctx.nameToKeep = p.symbols[ctx.class.Name.Ref.InnerIndex].OriginalName\n\t\t}\n\t\tif s.IsExport {\n\t\t\tctx.kind = classKindExportStmt\n\t\t} else {\n\t\t\tctx.kind = classKindStmt\n\t\t}\n\t} else {\n\t\ts, _ := stmt.Data.(*js_ast.SExportDefault)\n\t\ts2, _ := s.Value.Data.(*js_ast.SClass)\n\t\tctx.class = &s2.Class\n\t\tif ctx.class.Name != nil {\n\t\t\tctx.nameToKeep = p.symbols[ctx.class.Name.Ref.InnerIndex].OriginalName\n\t\t}\n\t\tctx.defaultName = s.DefaultName\n\t\tctx.kind = classKindExportDefaultStmt\n\t}\n\tif stmt.Data == nil {\n\t\tctx.classLoc = expr.Loc\n\t} else {\n\t\tctx.classLoc = stmt.Loc\n\t}\n\n\tclassLoweringInfo := p.computeClassLoweringInfo(ctx.class)\n\tctx.enableNameCapture(p, result)\n\tctx.processProperties(p, classLoweringInfo, result)\n\tctx.insertInitializersIntoConstructor(p, classLoweringInfo, result)\n\treturn ctx.finishAndGenerateCode(p, result)\n}\n\nfunc (ctx *lowerClassContext) enableNameCapture(p *parser, result visitClassResult) {\n\t// Class statements can be missing a name if they are in an\n\t// \"export default\" statement:\n\t//\n\t//   export default class {\n\t//     static foo = 123\n\t//   }\n\t//\n\tctx.nameFunc = func() js_ast.Expr {\n\t\tif ctx.kind == classKindExpr {\n\t\t\t// If this is a class expression, capture and store it. We have to\n\t\t\t// do this even if it has a name since the name isn't exposed\n\t\t\t// outside the class body.\n\t\t\tclassExpr := &js_ast.EClass{Class: *ctx.class}\n\t\t\tctx.class = &classExpr.Class\n\t\t\tctx.nameFunc, ctx.wrapFunc = p.captureValueWithPossibleSideEffects(ctx.classLoc, 2, js_ast.Expr{Loc: ctx.classLoc, Data: classExpr}, valueDefinitelyNotMutated)\n\t\t\tctx.classExpr = ctx.nameFunc()\n\t\t\tctx.didCaptureClassExpr = true\n\t\t\tname := ctx.nameFunc()\n\n\t\t\t// If we're storing the class expression in a variable, remove the class\n\t\t\t// name and rewrite all references to the class name with references to\n\t\t\t// the temporary variable holding the class expression. This ensures that\n\t\t\t// references to the class expression by name in any expressions that end\n\t\t\t// up being pulled outside of the class body still work. For example:\n\t\t\t//\n\t\t\t//   let Bar = class Foo {\n\t\t\t//     static foo = 123\n\t\t\t//     static bar = Foo.foo\n\t\t\t//   }\n\t\t\t//\n\t\t\t// This might be converted into the following:\n\t\t\t//\n\t\t\t//   var _a;\n\t\t\t//   let Bar = (_a = class {\n\t\t\t//   }, _a.foo = 123, _a.bar = _a.foo, _a);\n\t\t\t//\n\t\t\tif ctx.class.Name != nil {\n\t\t\t\tp.mergeSymbols(ctx.class.Name.Ref, name.Data.(*js_ast.EIdentifier).Ref)\n\t\t\t\tctx.class.Name = nil\n\t\t\t}\n\n\t\t\treturn name\n\t\t} else {\n\t\t\t// If anything referenced the inner class name, then we should use that\n\t\t\t// name for any automatically-generated initialization code, since it\n\t\t\t// will come before the outer class name is initialized.\n\t\t\tif result.innerClassNameRef != ast.InvalidRef {\n\t\t\t\tp.recordUsage(result.innerClassNameRef)\n\t\t\t\treturn js_ast.Expr{Loc: ctx.class.Name.Loc, Data: &js_ast.EIdentifier{Ref: result.innerClassNameRef}}\n\t\t\t}\n\n\t\t\t// Otherwise we should just use the outer class name\n\t\t\tif ctx.class.Name == nil {\n\t\t\t\tif ctx.kind == classKindExportDefaultStmt {\n\t\t\t\t\tctx.class.Name = &ctx.defaultName\n\t\t\t\t} else {\n\t\t\t\t\tctx.class.Name = &ast.LocRef{Loc: ctx.classLoc, Ref: p.generateTempRef(tempRefNoDeclare, \"\")}\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.recordUsage(ctx.class.Name.Ref)\n\t\t\treturn js_ast.Expr{Loc: ctx.class.Name.Loc, Data: &js_ast.EIdentifier{Ref: ctx.class.Name.Ref}}\n\t\t}\n\t}\n}\n\n// Handle lowering of instance and static fields. Move their initializers\n// from the class body to either the constructor (instance fields) or after\n// the class (static fields).\n//\n// If this returns true, the return property should be added to the class\n// body. Otherwise the property should be omitted from the class body.\nfunc (ctx *lowerClassContext) lowerField(\n\tp *parser,\n\tprop js_ast.Property,\n\tprivate *js_ast.EPrivateIdentifier,\n\tshouldOmitFieldInitializer bool,\n\tstaticFieldToBlockAssign bool,\n\tinitializerIndex int,\n) (js_ast.Property, ast.Ref, bool) {\n\tmustLowerPrivate := private != nil && p.privateSymbolNeedsToBeLowered(private)\n\tref := ast.InvalidRef\n\n\t// The TypeScript compiler doesn't follow the JavaScript spec for\n\t// uninitialized fields. They are supposed to be set to undefined but the\n\t// TypeScript compiler just omits them entirely.\n\tif !shouldOmitFieldInitializer {\n\t\tloc := prop.Loc\n\n\t\t// Determine where to store the field\n\t\tvar target js_ast.Expr\n\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) && !staticFieldToBlockAssign {\n\t\t\ttarget = ctx.nameFunc()\n\t\t} else {\n\t\t\ttarget = js_ast.Expr{Loc: loc, Data: js_ast.EThisShared}\n\t\t}\n\n\t\t// Generate the assignment initializer\n\t\tvar init js_ast.Expr\n\t\tif prop.InitializerOrNil.Data != nil {\n\t\t\tinit = prop.InitializerOrNil\n\t\t} else {\n\t\t\tinit = js_ast.Expr{Loc: loc, Data: js_ast.EUndefinedShared}\n\t\t}\n\n\t\t// Optionally call registered decorator initializers\n\t\tif initializerIndex != -1 {\n\t\t\tvar value js_ast.Expr\n\t\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t\tvalue = ctx.nameFunc()\n\t\t\t} else {\n\t\t\t\tvalue = js_ast.Expr{Loc: loc, Data: js_ast.EThisShared}\n\t\t\t}\n\t\t\targs := []js_ast.Expr{\n\t\t\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: ctx.decoratorContextRef}},\n\t\t\t\t{Loc: loc, Data: &js_ast.ENumber{Value: float64((4 + 2*initializerIndex) << 1)}},\n\t\t\t\tvalue,\n\t\t\t}\n\t\t\tif _, ok := init.Data.(*js_ast.EUndefined); !ok {\n\t\t\t\targs = append(args, init)\n\t\t\t}\n\t\t\tinit = p.callRuntime(init.Loc, \"__runInitializers\", args)\n\t\t\tp.recordUsage(ctx.decoratorContextRef)\n\t\t}\n\n\t\t// Generate the assignment target\n\t\tvar memberExpr js_ast.Expr\n\t\tif mustLowerPrivate {\n\t\t\t// Generate a new symbol for this private field\n\t\t\tref = p.generateTempRef(tempRefNeedsDeclare, \"_\"+p.symbols[private.Ref.InnerIndex].OriginalName[1:])\n\t\t\tp.symbols[private.Ref.InnerIndex].Link = ref\n\n\t\t\t// Initialize the private field to a new WeakMap\n\t\t\tif p.weakMapRef == ast.InvalidRef {\n\t\t\t\tp.weakMapRef = p.newSymbol(ast.SymbolUnbound, \"WeakMap\")\n\t\t\t\tp.moduleScope.Generated = append(p.moduleScope.Generated, p.weakMapRef)\n\t\t\t}\n\t\t\tctx.privateMembers = append(ctx.privateMembers, js_ast.Assign(\n\t\t\t\tjs_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: ref}},\n\t\t\t\tjs_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.ENew{Target: js_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: p.weakMapRef}}}},\n\t\t\t))\n\t\t\tp.recordUsage(ref)\n\n\t\t\t// Add every newly-constructed instance into this map\n\t\t\tkey := js_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\t\t\targs := []js_ast.Expr{target, key}\n\t\t\tif _, ok := init.Data.(*js_ast.EUndefined); !ok {\n\t\t\t\targs = append(args, init)\n\t\t\t}\n\t\t\tmemberExpr = p.callRuntime(loc, \"__privateAdd\", args)\n\t\t\tp.recordUsage(ref)\n\t\t} else if private == nil && ctx.class.UseDefineForClassFields {\n\t\t\tif p.shouldAddKeyComment {\n\t\t\t\tif str, ok := prop.Key.Data.(*js_ast.EString); ok {\n\t\t\t\t\tstr.HasPropertyKeyComment = true\n\t\t\t\t}\n\t\t\t}\n\t\t\targs := []js_ast.Expr{target, prop.Key}\n\t\t\tif _, ok := init.Data.(*js_ast.EUndefined); !ok {\n\t\t\t\targs = append(args, init)\n\t\t\t}\n\t\t\tmemberExpr = js_ast.Expr{Loc: loc, Data: &js_ast.ECall{\n\t\t\t\tTarget: p.importFromRuntime(loc, \"__publicField\"),\n\t\t\t\tArgs:   args,\n\t\t\t}}\n\t\t} else {\n\t\t\tif key, ok := prop.Key.Data.(*js_ast.EString); ok && !prop.Flags.Has(js_ast.PropertyIsComputed) && !prop.Flags.Has(js_ast.PropertyPreferQuotedKey) {\n\t\t\t\ttarget = js_ast.Expr{Loc: loc, Data: &js_ast.EDot{\n\t\t\t\t\tTarget:  target,\n\t\t\t\t\tName:    helpers.UTF16ToString(key.Value),\n\t\t\t\t\tNameLoc: prop.Key.Loc,\n\t\t\t\t}}\n\t\t\t} else {\n\t\t\t\ttarget = js_ast.Expr{Loc: loc, Data: &js_ast.EIndex{\n\t\t\t\t\tTarget: target,\n\t\t\t\t\tIndex:  prop.Key,\n\t\t\t\t}}\n\t\t\t}\n\n\t\t\tmemberExpr = js_ast.Assign(target, init)\n\t\t}\n\n\t\t// Run extra initializers\n\t\tif initializerIndex != -1 {\n\t\t\tvar value js_ast.Expr\n\t\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t\tvalue = ctx.nameFunc()\n\t\t\t} else {\n\t\t\t\tvalue = js_ast.Expr{Loc: loc, Data: js_ast.EThisShared}\n\t\t\t}\n\t\t\tmemberExpr = js_ast.JoinWithComma(memberExpr, p.callRuntime(loc, \"__runInitializers\", []js_ast.Expr{\n\t\t\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: ctx.decoratorContextRef}},\n\t\t\t\t{Loc: loc, Data: &js_ast.ENumber{Value: float64(((5 + 2*initializerIndex) << 1) | 1)}},\n\t\t\t\tvalue,\n\t\t\t}))\n\t\t\tp.recordUsage(ctx.decoratorContextRef)\n\t\t}\n\n\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t// Move this property to an assignment after the class ends\n\t\t\tif staticFieldToBlockAssign {\n\t\t\t\t// Use inline assignment in a static block instead of lowering\n\t\t\t\treturn js_ast.Property{\n\t\t\t\t\tLoc:  loc,\n\t\t\t\t\tKind: js_ast.PropertyClassStaticBlock,\n\t\t\t\t\tClassStaticBlock: &js_ast.ClassStaticBlock{\n\t\t\t\t\t\tLoc: loc,\n\t\t\t\t\t\tBlock: js_ast.SBlock{Stmts: []js_ast.Stmt{\n\t\t\t\t\t\t\t{Loc: loc, Data: &js_ast.SExpr{Value: memberExpr}}},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t}, ref, true\n\t\t\t} else {\n\t\t\t\t// Move this property to an assignment after the class ends\n\t\t\t\tctx.staticMembers = append(ctx.staticMembers, memberExpr)\n\t\t\t}\n\t\t} else {\n\t\t\t// Move this property to an assignment inside the class constructor\n\t\t\tctx.instanceMembers = append(ctx.instanceMembers, js_ast.Stmt{Loc: loc, Data: &js_ast.SExpr{Value: memberExpr}})\n\t\t}\n\t}\n\n\tif private == nil || mustLowerPrivate {\n\t\t// Remove the field from the class body\n\t\treturn js_ast.Property{}, ref, false\n\t}\n\n\t// Keep the private field but remove the initializer\n\tprop.InitializerOrNil = js_ast.Expr{}\n\treturn prop, ref, true\n}\n\nfunc (ctx *lowerClassContext) lowerPrivateMethod(p *parser, prop js_ast.Property, private *js_ast.EPrivateIdentifier) {\n\t// All private methods can share the same WeakSet\n\tvar ref *ast.Ref\n\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\tref = &ctx.privateStaticMethodRef\n\t} else {\n\t\tref = &ctx.privateInstanceMethodRef\n\t}\n\tif *ref == ast.InvalidRef {\n\t\t// Generate a new symbol to store the WeakSet\n\t\tvar name string\n\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\tname = \"_static\"\n\t\t} else {\n\t\t\tname = \"_instances\"\n\t\t}\n\t\tif ctx.nameToKeep != \"\" {\n\t\t\tname = fmt.Sprintf(\"_%s%s\", ctx.nameToKeep, name)\n\t\t}\n\t\t*ref = p.generateTempRef(tempRefNeedsDeclare, name)\n\n\t\t// Generate the initializer\n\t\tif p.weakSetRef == ast.InvalidRef {\n\t\t\tp.weakSetRef = p.newSymbol(ast.SymbolUnbound, \"WeakSet\")\n\t\t\tp.moduleScope.Generated = append(p.moduleScope.Generated, p.weakSetRef)\n\t\t}\n\t\tctx.privateMembers = append(ctx.privateMembers, js_ast.Assign(\n\t\t\tjs_ast.Expr{Loc: ctx.classLoc, Data: &js_ast.EIdentifier{Ref: *ref}},\n\t\t\tjs_ast.Expr{Loc: ctx.classLoc, Data: &js_ast.ENew{Target: js_ast.Expr{Loc: ctx.classLoc, Data: &js_ast.EIdentifier{Ref: p.weakSetRef}}}},\n\t\t))\n\t\tp.recordUsage(*ref)\n\t\tp.recordUsage(p.weakSetRef)\n\n\t\t// Determine what to store in the WeakSet\n\t\tvar target js_ast.Expr\n\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\ttarget = ctx.nameFunc()\n\t\t} else {\n\t\t\ttarget = js_ast.Expr{Loc: ctx.classLoc, Data: js_ast.EThisShared}\n\t\t}\n\n\t\t// Add every newly-constructed instance into this set\n\t\tmethodExpr := p.callRuntime(ctx.classLoc, \"__privateAdd\", []js_ast.Expr{\n\t\t\ttarget,\n\t\t\t{Loc: ctx.classLoc, Data: &js_ast.EIdentifier{Ref: *ref}},\n\t\t})\n\t\tp.recordUsage(*ref)\n\n\t\t// Make sure that adding to the map happens before any field\n\t\t// initializers to handle cases like this:\n\t\t//\n\t\t//   class A {\n\t\t//     pub = this.#priv;\n\t\t//     #priv() {}\n\t\t//   }\n\t\t//\n\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t// Move this property to an assignment after the class ends\n\t\t\tctx.staticPrivateMethods = append(ctx.staticPrivateMethods, methodExpr)\n\t\t} else {\n\t\t\t// Move this property to an assignment inside the class constructor\n\t\t\tctx.instancePrivateMethods = append(ctx.instancePrivateMethods, js_ast.Stmt{Loc: ctx.classLoc, Data: &js_ast.SExpr{Value: methodExpr}})\n\t\t}\n\t}\n\tp.symbols[private.Ref.InnerIndex].Link = *ref\n}\n\n// If this returns true, the method property should be dropped as it has\n// already been accounted for elsewhere (e.g. a lowered private method).\nfunc (ctx *lowerClassContext) lowerMethod(p *parser, prop js_ast.Property, private *js_ast.EPrivateIdentifier) bool {\n\tif private != nil && p.privateSymbolNeedsToBeLowered(private) {\n\t\tctx.lowerPrivateMethod(p, prop, private)\n\n\t\t// Move the method definition outside the class body\n\t\tmethodRef := p.generateTempRef(tempRefNeedsDeclare, \"_\")\n\t\tif prop.Kind == js_ast.PropertySetter {\n\t\t\tp.symbols[methodRef.InnerIndex].Link = p.privateSetters[private.Ref]\n\t\t} else {\n\t\t\tp.symbols[methodRef.InnerIndex].Link = p.privateGetters[private.Ref]\n\t\t}\n\t\tp.recordUsage(methodRef)\n\t\tctx.privateMembers = append(ctx.privateMembers, js_ast.Assign(\n\t\t\tjs_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: methodRef}},\n\t\t\tprop.ValueOrNil,\n\t\t))\n\t\treturn true\n\t}\n\n\tif key, ok := prop.Key.Data.(*js_ast.EString); ok && helpers.UTF16EqualsString(key.Value, \"constructor\") {\n\t\tif fn, ok := prop.ValueOrNil.Data.(*js_ast.EFunction); ok {\n\t\t\t// Remember where the constructor is for later\n\t\t\tctx.ctor = fn\n\n\t\t\t// Initialize TypeScript constructor parameter fields\n\t\t\tif p.options.ts.Parse {\n\t\t\t\tfor _, arg := range ctx.ctor.Fn.Args {\n\t\t\t\t\tif arg.IsTypeScriptCtorField {\n\t\t\t\t\t\tif id, ok := arg.Binding.Data.(*js_ast.BIdentifier); ok {\n\t\t\t\t\t\t\tctx.parameterFields = append(ctx.parameterFields, js_ast.AssignStmt(\n\t\t\t\t\t\t\t\tjs_ast.Expr{Loc: arg.Binding.Loc, Data: p.dotOrMangledPropVisit(\n\t\t\t\t\t\t\t\t\tjs_ast.Expr{Loc: arg.Binding.Loc, Data: js_ast.EThisShared},\n\t\t\t\t\t\t\t\t\tp.symbols[id.Ref.InnerIndex].OriginalName,\n\t\t\t\t\t\t\t\t\targ.Binding.Loc,\n\t\t\t\t\t\t\t\t)},\n\t\t\t\t\t\t\t\tjs_ast.Expr{Loc: arg.Binding.Loc, Data: &js_ast.EIdentifier{Ref: id.Ref}},\n\t\t\t\t\t\t\t))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false\n}\n\ntype propertyAnalysis struct {\n\tprivate                         *js_ast.EPrivateIdentifier\n\tpropExperimentalDecorators      []js_ast.Decorator\n\tpropDecorators                  []js_ast.Decorator\n\tmustLowerField                  bool\n\tneedsValueOfKey                 bool\n\trewriteAutoAccessorToGetSet     bool\n\tshouldOmitFieldInitializer      bool\n\tstaticFieldToBlockAssign        bool\n\tisComputedPropertyCopiedOrMoved bool\n}\n\nfunc (ctx *lowerClassContext) analyzeProperty(p *parser, prop js_ast.Property, classLoweringInfo classLoweringInfo) (analysis propertyAnalysis) {\n\t// The TypeScript class field transform requires removing fields without\n\t// initializers. If the field is removed, then we only need the key for\n\t// its side effects and we don't need a temporary reference for the key.\n\t// However, the TypeScript compiler doesn't remove the field when doing\n\t// strict class field initialization, so we shouldn't either.\n\tanalysis.private, _ = prop.Key.Data.(*js_ast.EPrivateIdentifier)\n\tmustLowerPrivate := analysis.private != nil && p.privateSymbolNeedsToBeLowered(analysis.private)\n\tanalysis.shouldOmitFieldInitializer = p.options.ts.Parse && !prop.Kind.IsMethodDefinition() && prop.InitializerOrNil.Data == nil &&\n\t\t!ctx.class.UseDefineForClassFields && !mustLowerPrivate && !ctx.class.ShouldLowerStandardDecorators\n\n\t// Class fields must be lowered if the environment doesn't support them\n\tif !prop.Kind.IsMethodDefinition() {\n\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\tanalysis.mustLowerField = classLoweringInfo.lowerAllStaticFields\n\t\t} else if prop.Kind == js_ast.PropertyField && p.options.ts.Parse && !ctx.class.UseDefineForClassFields && analysis.private == nil {\n\t\t\t// Lower non-private instance fields (not accessors) if TypeScript's\n\t\t\t// \"useDefineForClassFields\" setting is disabled. When all such fields\n\t\t\t// have no initializers, we avoid setting the \"lowerAllInstanceFields\"\n\t\t\t// flag as an optimization because we can just remove all class field\n\t\t\t// declarations in that case without messing with the constructor. But\n\t\t\t// we must set the \"mustLowerField\" flag here to cause this class field\n\t\t\t// declaration to still be removed.\n\t\t\tanalysis.mustLowerField = true\n\t\t} else {\n\t\t\tanalysis.mustLowerField = classLoweringInfo.lowerAllInstanceFields\n\t\t}\n\t}\n\n\t// If the field uses the TypeScript \"declare\" or \"abstract\" keyword, just\n\t// omit it entirely. However, we must still keep any side-effects in the\n\t// computed value and/or in the decorators.\n\tif prop.Kind == js_ast.PropertyDeclareOrAbstract && prop.ValueOrNil.Data == nil {\n\t\tanalysis.mustLowerField = true\n\t\tanalysis.shouldOmitFieldInitializer = true\n\t}\n\n\t// For convenience, split decorators off into separate fields based on how\n\t// they will end up being lowered (if they are even being lowered at all)\n\tif p.options.ts.Parse && p.options.ts.Config.ExperimentalDecorators == config.True {\n\t\tanalysis.propExperimentalDecorators = prop.Decorators\n\t} else if ctx.class.ShouldLowerStandardDecorators {\n\t\tanalysis.propDecorators = prop.Decorators\n\t}\n\n\t// Note: Auto-accessors use a different transform when they are decorated.\n\t// This transform trades off worse run-time performance for better code size.\n\tanalysis.rewriteAutoAccessorToGetSet = len(analysis.propDecorators) == 0 && prop.Kind == js_ast.PropertyAutoAccessor &&\n\t\t(p.options.unsupportedJSFeatures.Has(compat.Decorators) || analysis.mustLowerField)\n\n\t// Transform non-lowered static fields that use assign semantics into an\n\t// assignment in an inline static block instead of lowering them. This lets\n\t// us avoid having to unnecessarily lower static private fields when\n\t// \"useDefineForClassFields\" is disabled.\n\tanalysis.staticFieldToBlockAssign = prop.Kind == js_ast.PropertyField && !analysis.mustLowerField && !ctx.class.UseDefineForClassFields &&\n\t\tprop.Flags.Has(js_ast.PropertyIsStatic) && analysis.private == nil\n\n\t// Computed properties can't be copied or moved because they have side effects\n\t// and we don't want to evaluate their side effects twice or change their\n\t// evaluation order. We'll need to store them in temporary variables to keep\n\t// their side effects in place when we reference them elsewhere.\n\tanalysis.needsValueOfKey = true\n\tif prop.Flags.Has(js_ast.PropertyIsComputed) &&\n\t\t(len(analysis.propExperimentalDecorators) > 0 ||\n\t\t\tlen(analysis.propDecorators) > 0 ||\n\t\t\tanalysis.mustLowerField ||\n\t\t\tanalysis.staticFieldToBlockAssign ||\n\t\t\tanalysis.rewriteAutoAccessorToGetSet) {\n\t\tanalysis.isComputedPropertyCopiedOrMoved = true\n\n\t\t// Determine if we don't actually need the value of the key (only the side\n\t\t// effects). In that case we don't need a temporary variable.\n\t\tif len(analysis.propExperimentalDecorators) == 0 &&\n\t\t\tlen(analysis.propDecorators) == 0 &&\n\t\t\t!analysis.rewriteAutoAccessorToGetSet &&\n\t\t\tanalysis.shouldOmitFieldInitializer {\n\t\t\tanalysis.needsValueOfKey = false\n\t\t}\n\t}\n\treturn\n}\n\nfunc (p *parser) propertyNameHint(key js_ast.Expr) string {\n\tswitch k := key.Data.(type) {\n\tcase *js_ast.EString:\n\t\treturn helpers.UTF16ToString(k.Value)\n\tcase *js_ast.EIdentifier:\n\t\treturn p.symbols[k.Ref.InnerIndex].OriginalName\n\tcase *js_ast.EPrivateIdentifier:\n\t\treturn p.symbols[k.Ref.InnerIndex].OriginalName[1:]\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\nfunc (ctx *lowerClassContext) hoistComputedProperties(p *parser, classLoweringInfo classLoweringInfo) (\n\tpropertyKeyTempRefs map[int]ast.Ref, decoratorTempRefs map[int]ast.Ref) {\n\tvar nextComputedPropertyKey *js_ast.Expr\n\n\t// Computed property keys must be evaluated in a specific order for their\n\t// side effects. This order must be preserved even when we have to move a\n\t// class element around. For example, this can happen when using class fields\n\t// with computed property keys and targeting environments without class field\n\t// support. For example:\n\t//\n\t//   class Foo {\n\t//     [a()]() {}\n\t//     static [b()] = null;\n\t//     [c()]() {}\n\t//   }\n\t//\n\t// If we need to lower the static field because static fields aren't supported,\n\t// we still need to ensure that \"b()\" is called before \"a()\" and after \"c()\".\n\t// That looks something like this:\n\t//\n\t//   var _a;\n\t//   class Foo {\n\t//     [a()]() {}\n\t//     [(_a = b(), c())]() {}\n\t//   }\n\t//   __publicField(Foo, _a, null);\n\t//\n\t// Iterate in reverse so that any initializers are \"pushed up\" before the\n\t// class body if there's nowhere else to put them. They can't be \"pushed\n\t// down\" into a static block in the class body (the logical place to put\n\t// them that's next in the evaluation order) because these expressions\n\t// may contain \"await\" and static blocks do not allow \"await\".\n\tfor propIndex := len(ctx.class.Properties) - 1; propIndex >= 0; propIndex-- {\n\t\tprop := &ctx.class.Properties[propIndex]\n\t\tanalysis := ctx.analyzeProperty(p, *prop, classLoweringInfo)\n\n\t\t// Evaluate the decorator expressions inline before computed property keys\n\t\tvar decorators js_ast.Expr\n\t\tif len(analysis.propDecorators) > 0 {\n\t\t\tname := p.propertyNameHint(prop.Key)\n\t\t\tif name != \"\" {\n\t\t\t\tname = \"_\" + name\n\t\t\t}\n\t\t\tname += \"_dec\"\n\t\t\tref := p.generateTempRef(tempRefNeedsDeclare, name)\n\t\t\tvalues := make([]js_ast.Expr, len(analysis.propDecorators))\n\t\t\tfor i, decorator := range analysis.propDecorators {\n\t\t\t\tvalues[i] = decorator.Value\n\t\t\t}\n\t\t\tatLoc := analysis.propDecorators[0].AtLoc\n\t\t\tdecorators = js_ast.Assign(\n\t\t\t\tjs_ast.Expr{Loc: atLoc, Data: &js_ast.EIdentifier{Ref: ref}},\n\t\t\t\tjs_ast.Expr{Loc: atLoc, Data: &js_ast.EArray{Items: values, IsSingleLine: true}})\n\t\t\tp.recordUsage(ref)\n\t\t\tif decoratorTempRefs == nil {\n\t\t\t\tdecoratorTempRefs = make(map[int]ast.Ref)\n\t\t\t}\n\t\t\tdecoratorTempRefs[propIndex] = ref\n\t\t}\n\n\t\t// Skip property keys that we know are side-effect free\n\t\tswitch prop.Key.Data.(type) {\n\t\tcase *js_ast.EString, *js_ast.ENameOfSymbol, *js_ast.ENumber, *js_ast.EPrivateIdentifier:\n\t\t\t// Figure out where to stick the decorator side effects to preserve their order\n\t\t\tif nextComputedPropertyKey != nil {\n\t\t\t\t// Insert it before everything that comes after it\n\t\t\t\t*nextComputedPropertyKey = js_ast.JoinWithComma(decorators, *nextComputedPropertyKey)\n\t\t\t} else {\n\t\t\t\t// Insert it after the first thing that comes before it\n\t\t\t\tctx.computedPropertyChain = js_ast.JoinWithComma(decorators, ctx.computedPropertyChain)\n\t\t\t}\n\t\t\tcontinue\n\n\t\tdefault:\n\t\t\t// Otherwise, evaluate the decorators right before the property key\n\t\t\tif decorators.Data != nil {\n\t\t\t\tprop.Key = js_ast.JoinWithComma(decorators, prop.Key)\n\t\t\t\tprop.Flags |= js_ast.PropertyIsComputed\n\t\t\t}\n\t\t}\n\n\t\t// If this key is referenced elsewhere, make sure to still preserve\n\t\t// its side effects in the property's original location\n\t\tif analysis.isComputedPropertyCopiedOrMoved {\n\t\t\t// If this property is being duplicated instead of moved or removed, then\n\t\t\t// we still need the assignment to the temporary so that we can reference\n\t\t\t// it in multiple places, but we don't have to hoist the assignment to an\n\t\t\t// earlier property (since this property is still there). In that case\n\t\t\t// we can reduce generated code size by avoiding the hoist. One example\n\t\t\t// of this case is a decorator on a class element with a computed\n\t\t\t// property key:\n\t\t\t//\n\t\t\t//   class Foo {\n\t\t\t//     @dec [a()]() {}\n\t\t\t//   }\n\t\t\t//\n\t\t\t// We want to do this:\n\t\t\t//\n\t\t\t//   var _a;\n\t\t\t//   class Foo {\n\t\t\t//     [_a = a()]() {}\n\t\t\t//   }\n\t\t\t//   __decorateClass([dec], Foo.prototype, _a, 1);\n\t\t\t//\n\t\t\t// instead of this:\n\t\t\t//\n\t\t\t//   var _a;\n\t\t\t//   _a = a();\n\t\t\t//   class Foo {\n\t\t\t//     [_a]() {}\n\t\t\t//   }\n\t\t\t//   __decorateClass([dec], Foo.prototype, _a, 1);\n\t\t\t//\n\t\t\t// So only do the hoist if this property is being moved or removed.\n\t\t\tif !analysis.rewriteAutoAccessorToGetSet && (analysis.mustLowerField || analysis.staticFieldToBlockAssign) {\n\t\t\t\tinlineKey := prop.Key\n\n\t\t\t\tif !analysis.needsValueOfKey {\n\t\t\t\t\t// In certain cases, we only need to evaluate a property key for its\n\t\t\t\t\t// side effects but we don't actually need the value of the key itself.\n\t\t\t\t\t// For example, a TypeScript class field without an initializer is\n\t\t\t\t\t// omitted when TypeScript's \"useDefineForClassFields\" setting is false.\n\t\t\t\t} else {\n\t\t\t\t\t// Store the key in a temporary so we can refer to it later\n\t\t\t\t\tref := p.generateTempRef(tempRefNeedsDeclare, \"\")\n\t\t\t\t\tinlineKey = js_ast.Assign(js_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: ref}}, prop.Key)\n\t\t\t\t\tp.recordUsage(ref)\n\n\t\t\t\t\t// Replace this property key with a reference to the temporary. We\n\t\t\t\t\t// don't need to store the temporary in the \"propertyKeyTempRefs\"\n\t\t\t\t\t// map because all references will refer to the temporary, not just\n\t\t\t\t\t// some of them.\n\t\t\t\t\tprop.Key = js_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\t\t\t\t\tp.recordUsage(ref)\n\t\t\t\t}\n\n\t\t\t\t// Figure out where to stick this property's side effect to preserve its order\n\t\t\t\tif nextComputedPropertyKey != nil {\n\t\t\t\t\t// Insert it before everything that comes after it\n\t\t\t\t\t*nextComputedPropertyKey = js_ast.JoinWithComma(inlineKey, *nextComputedPropertyKey)\n\t\t\t\t} else {\n\t\t\t\t\t// Insert it after the first thing that comes before it\n\t\t\t\t\tctx.computedPropertyChain = js_ast.JoinWithComma(inlineKey, ctx.computedPropertyChain)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Otherwise, we keep the side effects in place (as described above) but\n\t\t\t// just store the key in a temporary so we can refer to it later.\n\t\t\tref := p.generateTempRef(tempRefNeedsDeclare, \"\")\n\t\t\tprop.Key = js_ast.Assign(js_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: ref}}, prop.Key)\n\t\t\tp.recordUsage(ref)\n\n\t\t\t// Use this temporary when creating duplicate references to this key\n\t\t\tif propertyKeyTempRefs == nil {\n\t\t\t\tpropertyKeyTempRefs = make(map[int]ast.Ref)\n\t\t\t}\n\t\t\tpropertyKeyTempRefs[propIndex] = ref\n\n\t\t\t// Deliberately continue to fall through to the \"computed\" case below:\n\t\t}\n\n\t\t// Otherwise, this computed property could be a good location to evaluate\n\t\t// something that comes before it. Remember this location for later.\n\t\tif prop.Flags.Has(js_ast.PropertyIsComputed) {\n\t\t\t// If any side effects after this were hoisted here, then inline them now.\n\t\t\t// We don't want to reorder any side effects.\n\t\t\tif ctx.computedPropertyChain.Data != nil {\n\t\t\t\tref, ok := propertyKeyTempRefs[propIndex]\n\t\t\t\tif !ok {\n\t\t\t\t\tref = p.generateTempRef(tempRefNeedsDeclare, \"\")\n\t\t\t\t\tprop.Key = js_ast.Assign(js_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: ref}}, prop.Key)\n\t\t\t\t\tp.recordUsage(ref)\n\t\t\t\t}\n\t\t\t\tprop.Key = js_ast.JoinWithComma(\n\t\t\t\t\tjs_ast.JoinWithComma(prop.Key, ctx.computedPropertyChain),\n\t\t\t\t\tjs_ast.Expr{Loc: prop.Key.Loc, Data: &js_ast.EIdentifier{Ref: ref}})\n\t\t\t\tp.recordUsage(ref)\n\t\t\t\tctx.computedPropertyChain = js_ast.Expr{}\n\t\t\t}\n\n\t\t\t// Remember this location for later\n\t\t\tnextComputedPropertyKey = &prop.Key\n\t\t}\n\t}\n\n\t// If any side effects in the class body were hoisted up to the \"extends\"\n\t// clause, then inline them before the \"extends\" clause is evaluated. We\n\t// don't want to reorder any side effects. For example:\n\t//\n\t//   class Foo extends a() {\n\t//     static [b()]\n\t//   }\n\t//\n\t// We want to do this:\n\t//\n\t//   var _a, _b;\n\t//   class Foo extends (_b = a(), _a = b(), _b) {\n\t//   }\n\t//   __publicField(Foo, _a);\n\t//\n\t// instead of this:\n\t//\n\t//   var _a;\n\t//   _a = b();\n\t//   class Foo extends a() {\n\t//   }\n\t//   __publicField(Foo, _a);\n\t//\n\tif ctx.computedPropertyChain.Data != nil && ctx.class.ExtendsOrNil.Data != nil {\n\t\tctx.extendsRef = p.generateTempRef(tempRefNeedsDeclare, \"\")\n\t\tctx.class.ExtendsOrNil = js_ast.JoinWithComma(js_ast.JoinWithComma(\n\t\t\tjs_ast.Assign(js_ast.Expr{Loc: ctx.class.ExtendsOrNil.Loc, Data: &js_ast.EIdentifier{Ref: ctx.extendsRef}}, ctx.class.ExtendsOrNil),\n\t\t\tctx.computedPropertyChain),\n\t\t\tjs_ast.Expr{Loc: ctx.class.ExtendsOrNil.Loc, Data: &js_ast.EIdentifier{Ref: ctx.extendsRef}})\n\t\tp.recordUsage(ctx.extendsRef)\n\t\tp.recordUsage(ctx.extendsRef)\n\t\tctx.computedPropertyChain = js_ast.Expr{}\n\t}\n\treturn\n}\n\n// This corresponds to the initialization order in the specification:\n//\n//  27. For each element e of staticElements, do\n//     a. If e is a ClassElementDefinition Record and e.[[Kind]] is not field, then\n//\n//  28. For each element e of instanceElements, do\n//     a. If e.[[Kind]] is not field, then\n//\n//  29. For each element e of staticElements, do\n//     a. If e.[[Kind]] is field, then\n//\n//  30. For each element e of instanceElements, do\n//     a. If e.[[Kind]] is field, then\nfunc fieldOrAccessorOrder(kind js_ast.PropertyKind, flags js_ast.PropertyFlags) (int, bool) {\n\tif kind == js_ast.PropertyAutoAccessor {\n\t\tif flags.Has(js_ast.PropertyIsStatic) {\n\t\t\treturn 0, true\n\t\t} else {\n\t\t\treturn 1, true\n\t\t}\n\t} else if kind == js_ast.PropertyField {\n\t\tif flags.Has(js_ast.PropertyIsStatic) {\n\t\t\treturn 2, true\n\t\t} else {\n\t\t\treturn 3, true\n\t\t}\n\t}\n\treturn 0, false\n}\n\nfunc (ctx *lowerClassContext) processProperties(p *parser, classLoweringInfo classLoweringInfo, result visitClassResult) {\n\tproperties := make([]js_ast.Property, 0, len(ctx.class.Properties))\n\tpropertyKeyTempRefs, decoratorTempRefs := ctx.hoistComputedProperties(p, classLoweringInfo)\n\n\t// Save the initializer index for each field and accessor element\n\tif ctx.class.ShouldLowerStandardDecorators {\n\t\tvar counts [4]int\n\n\t\t// Count how many initializers there are in each section\n\t\tfor _, prop := range ctx.class.Properties {\n\t\t\tif len(prop.Decorators) > 0 {\n\t\t\t\tif i, ok := fieldOrAccessorOrder(prop.Kind, prop.Flags); ok {\n\t\t\t\t\tcounts[i]++\n\t\t\t\t} else if prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t\t\tctx.decoratorCallStaticMethodExtraInitializers = true\n\t\t\t\t} else {\n\t\t\t\t\tctx.decoratorCallInstanceMethodExtraInitializers = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Give each on an index for the order it will be initialized in\n\t\tif counts[0] > 0 || counts[1] > 0 || counts[2] > 0 || counts[3] > 0 {\n\t\t\tindices := [4]int{0, counts[0], counts[0] + counts[1], counts[0] + counts[1] + counts[2]}\n\t\t\tctx.decoratorPropertyToInitializerMap = make(map[int]int)\n\n\t\t\tfor propIndex, prop := range ctx.class.Properties {\n\t\t\t\tif len(prop.Decorators) > 0 {\n\t\t\t\t\tif i, ok := fieldOrAccessorOrder(prop.Kind, prop.Flags); ok {\n\t\t\t\t\t\tctx.decoratorPropertyToInitializerMap[propIndex] = indices[i]\n\t\t\t\t\t\tindices[i]++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Evaluate the decorator expressions inline\n\tif ctx.class.ShouldLowerStandardDecorators && len(ctx.class.Decorators) > 0 {\n\t\tname := ctx.nameToKeep\n\t\tif name == \"\" {\n\t\t\tname = \"class\"\n\t\t}\n\t\tdecoratorsRef := p.generateTempRef(tempRefNeedsDeclare, fmt.Sprintf(\"_%s_decorators\", name))\n\t\tvalues := make([]js_ast.Expr, len(ctx.class.Decorators))\n\t\tfor i, decorator := range ctx.class.Decorators {\n\t\t\tvalues[i] = decorator.Value\n\t\t}\n\t\tatLoc := ctx.class.Decorators[0].AtLoc\n\t\tctx.computedPropertyChain = js_ast.JoinWithComma(js_ast.Assign(\n\t\t\tjs_ast.Expr{Loc: atLoc, Data: &js_ast.EIdentifier{Ref: decoratorsRef}},\n\t\t\tjs_ast.Expr{Loc: atLoc, Data: &js_ast.EArray{Items: values, IsSingleLine: true}},\n\t\t), ctx.computedPropertyChain)\n\t\tp.recordUsage(decoratorsRef)\n\t\tctx.decoratorClassDecorators = js_ast.Expr{Loc: atLoc, Data: &js_ast.EIdentifier{Ref: decoratorsRef}}\n\t\tp.recordUsage(decoratorsRef)\n\t\tctx.class.Decorators = nil\n\t}\n\n\tfor propIndex, prop := range ctx.class.Properties {\n\t\tif prop.Kind == js_ast.PropertyClassStaticBlock {\n\t\t\t// Drop empty class blocks when minifying\n\t\t\tif p.options.minifySyntax && len(prop.ClassStaticBlock.Block.Stmts) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Lower this block if needed\n\t\t\tif classLoweringInfo.lowerAllStaticFields {\n\t\t\t\tctx.lowerStaticBlock(p, prop.Loc, *prop.ClassStaticBlock)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Otherwise, keep this property\n\t\t\tproperties = append(properties, prop)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Merge parameter decorators with method decorators\n\t\tif p.options.ts.Parse && prop.Kind.IsMethodDefinition() {\n\t\t\tif fn, ok := prop.ValueOrNil.Data.(*js_ast.EFunction); ok {\n\t\t\t\tisConstructor := false\n\t\t\t\tif key, ok := prop.Key.Data.(*js_ast.EString); ok {\n\t\t\t\t\tisConstructor = helpers.UTF16EqualsString(key.Value, \"constructor\")\n\t\t\t\t}\n\t\t\t\targs := fn.Fn.Args\n\t\t\t\tfor i, arg := range args {\n\t\t\t\t\tfor _, decorator := range arg.Decorators {\n\t\t\t\t\t\t// Generate a call to \"__decorateParam()\" for this parameter decorator\n\t\t\t\t\t\tvar decorators *[]js_ast.Decorator = &prop.Decorators\n\t\t\t\t\t\tif isConstructor {\n\t\t\t\t\t\t\tdecorators = &ctx.class.Decorators\n\t\t\t\t\t\t}\n\t\t\t\t\t\t*decorators = append(*decorators, js_ast.Decorator{\n\t\t\t\t\t\t\tValue: p.callRuntime(decorator.Value.Loc, \"__decorateParam\", []js_ast.Expr{\n\t\t\t\t\t\t\t\t{Loc: decorator.Value.Loc, Data: &js_ast.ENumber{Value: float64(i)}},\n\t\t\t\t\t\t\t\tdecorator.Value,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tAtLoc: decorator.AtLoc,\n\t\t\t\t\t\t})\n\t\t\t\t\t\targs[i].Decorators = nil\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tanalysis := ctx.analyzeProperty(p, prop, classLoweringInfo)\n\n\t\t// When the property key needs to be referenced multiple times, subsequent\n\t\t// references may need to reference a temporary variable instead of copying\n\t\t// the whole property key expression (since we only want to evaluate side\n\t\t// effects once).\n\t\tkeyExprNoSideEffects := prop.Key\n\t\tif ref, ok := propertyKeyTempRefs[propIndex]; ok {\n\t\t\tkeyExprNoSideEffects.Data = &js_ast.EIdentifier{Ref: ref}\n\t\t}\n\n\t\t// Handle TypeScript experimental decorators\n\t\tif len(analysis.propExperimentalDecorators) > 0 {\n\t\t\tprop.Decorators = nil\n\n\t\t\t// Generate a single call to \"__decorateClass()\" for this property\n\t\t\tloc := prop.Key.Loc\n\n\t\t\t// This code tells \"__decorateClass()\" if the descriptor should be undefined\n\t\t\tdescriptorKind := float64(1)\n\t\t\tif prop.Kind == js_ast.PropertyField || prop.Kind == js_ast.PropertyDeclareOrAbstract {\n\t\t\t\tdescriptorKind = 2\n\t\t\t}\n\n\t\t\t// Instance properties use the prototype, static properties use the class\n\t\t\tvar target js_ast.Expr\n\t\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t\ttarget = ctx.nameFunc()\n\t\t\t} else {\n\t\t\t\ttarget = js_ast.Expr{Loc: loc, Data: &js_ast.EDot{Target: ctx.nameFunc(), Name: \"prototype\", NameLoc: loc}}\n\t\t\t}\n\n\t\t\tvalues := make([]js_ast.Expr, len(analysis.propExperimentalDecorators))\n\t\t\tfor i, decorator := range analysis.propExperimentalDecorators {\n\t\t\t\tvalues[i] = decorator.Value\n\t\t\t}\n\t\t\tdecorator := p.callRuntime(loc, \"__decorateClass\", []js_ast.Expr{\n\t\t\t\t{Loc: loc, Data: &js_ast.EArray{Items: values}},\n\t\t\t\ttarget,\n\t\t\t\tcloneKeyForLowerClass(keyExprNoSideEffects),\n\t\t\t\t{Loc: loc, Data: &js_ast.ENumber{Value: descriptorKind}},\n\t\t\t})\n\n\t\t\t// Static decorators are grouped after instance decorators\n\t\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t\tctx.staticExperimentalDecorators = append(ctx.staticExperimentalDecorators, decorator)\n\t\t\t} else {\n\t\t\t\tctx.instanceExperimentalDecorators = append(ctx.instanceExperimentalDecorators, decorator)\n\t\t\t}\n\t\t}\n\n\t\t// Handle JavaScript decorators\n\t\tinitializerIndex := -1\n\t\tif len(analysis.propDecorators) > 0 {\n\t\t\tprop.Decorators = nil\n\t\t\tloc := prop.Loc\n\t\t\tkeyLoc := prop.Key.Loc\n\t\t\tatLoc := analysis.propDecorators[0].AtLoc\n\n\t\t\t// Encode information about this property using bit flags\n\t\t\tvar flags int\n\t\t\tswitch prop.Kind {\n\t\t\tcase js_ast.PropertyMethod:\n\t\t\t\tflags = 1\n\t\t\tcase js_ast.PropertyGetter:\n\t\t\t\tflags = 2\n\t\t\tcase js_ast.PropertySetter:\n\t\t\t\tflags = 3\n\t\t\tcase js_ast.PropertyAutoAccessor:\n\t\t\t\tflags = 4\n\t\t\tcase js_ast.PropertyField:\n\t\t\t\tflags = 5\n\t\t\t}\n\t\t\tif flags >= 4 {\n\t\t\t\tinitializerIndex = ctx.decoratorPropertyToInitializerMap[propIndex]\n\t\t\t}\n\t\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t\tflags |= 8\n\t\t\t}\n\t\t\tif analysis.private != nil {\n\t\t\t\tflags |= 16\n\t\t\t}\n\n\t\t\t// Start the arguments for the call to \"__decorateElement\"\n\t\t\tvar key js_ast.Expr\n\t\t\tdecoratorsRef := decoratorTempRefs[propIndex]\n\t\t\tif ctx.decoratorContextRef == ast.InvalidRef {\n\t\t\t\tctx.decoratorContextRef = p.generateTempRef(tempRefNeedsDeclare, \"_init\")\n\t\t\t}\n\t\t\tif analysis.private != nil {\n\t\t\t\tkey = js_ast.Expr{Loc: loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(p.symbols[analysis.private.Ref.InnerIndex].OriginalName)}}\n\t\t\t} else {\n\t\t\t\tkey = cloneKeyForLowerClass(keyExprNoSideEffects)\n\t\t\t}\n\t\t\targs := []js_ast.Expr{\n\t\t\t\t{Loc: loc, Data: &js_ast.EIdentifier{Ref: ctx.decoratorContextRef}},\n\t\t\t\t{Loc: loc, Data: &js_ast.ENumber{Value: float64(flags)}},\n\t\t\t\tkey,\n\t\t\t\t{Loc: atLoc, Data: &js_ast.EIdentifier{Ref: decoratorsRef}},\n\t\t\t}\n\t\t\tp.recordUsage(ctx.decoratorContextRef)\n\t\t\tp.recordUsage(decoratorsRef)\n\n\t\t\t// Append any optional additional arguments\n\t\t\tprivateFnRef := ast.InvalidRef\n\t\t\tif analysis.private != nil {\n\t\t\t\t// Add the \"target\" argument (the weak set)\n\t\t\t\targs = append(args, js_ast.Expr{Loc: keyLoc, Data: &js_ast.EIdentifier{Ref: analysis.private.Ref}})\n\t\t\t\tp.recordUsage(analysis.private.Ref)\n\n\t\t\t\t// Add the \"extra\" argument (the function)\n\t\t\t\tswitch prop.Kind {\n\t\t\t\tcase js_ast.PropertyMethod:\n\t\t\t\t\tprivateFnRef = p.privateGetters[analysis.private.Ref]\n\t\t\t\tcase js_ast.PropertyGetter:\n\t\t\t\t\tprivateFnRef = p.privateGetters[analysis.private.Ref]\n\t\t\t\tcase js_ast.PropertySetter:\n\t\t\t\t\tprivateFnRef = p.privateSetters[analysis.private.Ref]\n\t\t\t\t}\n\t\t\t\tif privateFnRef != ast.InvalidRef {\n\t\t\t\t\targs = append(args, js_ast.Expr{Loc: keyLoc, Data: &js_ast.EIdentifier{Ref: privateFnRef}})\n\t\t\t\t\tp.recordUsage(privateFnRef)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Add the \"target\" argument (the class object)\n\t\t\t\targs = append(args, ctx.nameFunc())\n\t\t\t}\n\n\t\t\t// Auto-accessors will generate a private field for storage. Lower this\n\t\t\t// field, which will generate a WeakMap instance, and then pass the\n\t\t\t// WeakMap instance into the decorator helper so the lowered getter and\n\t\t\t// setter can use it.\n\t\t\tif prop.Kind == js_ast.PropertyAutoAccessor {\n\t\t\t\tvar kind ast.SymbolKind\n\t\t\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t\t\tkind = ast.SymbolPrivateStaticField\n\t\t\t\t} else {\n\t\t\t\t\tkind = ast.SymbolPrivateField\n\t\t\t\t}\n\t\t\t\tref := p.newSymbol(kind, \"#\"+p.propertyNameHint(prop.Key))\n\t\t\t\tp.symbols[ref.InnerIndex].Flags |= ast.PrivateSymbolMustBeLowered\n\t\t\t\t_, autoAccessorWeakMapRef, _ := ctx.lowerField(p, prop, &js_ast.EPrivateIdentifier{Ref: ref}, false, false, initializerIndex)\n\t\t\t\targs = append(args, js_ast.Expr{Loc: keyLoc, Data: &js_ast.EIdentifier{Ref: autoAccessorWeakMapRef}})\n\t\t\t\tp.recordUsage(autoAccessorWeakMapRef)\n\t\t\t}\n\n\t\t\t// Assign the result\n\t\t\telement := p.callRuntime(loc, \"__decorateElement\", args)\n\t\t\tif privateFnRef != ast.InvalidRef {\n\t\t\t\telement = js_ast.Assign(js_ast.Expr{Loc: keyLoc, Data: &js_ast.EIdentifier{Ref: privateFnRef}}, element)\n\t\t\t\tp.recordUsage(privateFnRef)\n\t\t\t} else if prop.Kind == js_ast.PropertyAutoAccessor && analysis.private != nil {\n\t\t\t\tref := p.generateTempRef(tempRefNeedsDeclare, \"\")\n\t\t\t\tprivateGetFnRef := p.generateTempRef(tempRefNeedsDeclare, \"_\")\n\t\t\t\tprivateSetFnRef := p.generateTempRef(tempRefNeedsDeclare, \"_\")\n\t\t\t\tp.symbols[privateGetFnRef.InnerIndex].Link = p.privateGetters[analysis.private.Ref]\n\t\t\t\tp.symbols[privateSetFnRef.InnerIndex].Link = p.privateSetters[analysis.private.Ref]\n\n\t\t\t\t// Unpack the \"get\" and \"set\" properties from the returned property descriptor\n\t\t\t\telement = js_ast.JoinWithComma(js_ast.JoinWithComma(\n\t\t\t\t\tjs_ast.Assign(\n\t\t\t\t\t\tjs_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: ref}},\n\t\t\t\t\t\telement),\n\t\t\t\t\tjs_ast.Assign(\n\t\t\t\t\t\tjs_ast.Expr{Loc: keyLoc, Data: &js_ast.EIdentifier{Ref: privateGetFnRef}},\n\t\t\t\t\t\tjs_ast.Expr{Loc: loc, Data: &js_ast.EDot{Target: js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: ref}}, Name: \"get\", NameLoc: loc}})),\n\t\t\t\t\tjs_ast.Assign(\n\t\t\t\t\t\tjs_ast.Expr{Loc: keyLoc, Data: &js_ast.EIdentifier{Ref: privateSetFnRef}},\n\t\t\t\t\t\tjs_ast.Expr{Loc: loc, Data: &js_ast.EDot{Target: js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: ref}}, Name: \"set\", NameLoc: loc}}))\n\t\t\t\tp.recordUsage(ref)\n\t\t\t\tp.recordUsage(privateGetFnRef)\n\t\t\t\tp.recordUsage(ref)\n\t\t\t\tp.recordUsage(privateSetFnRef)\n\t\t\t\tp.recordUsage(ref)\n\t\t\t}\n\n\t\t\t// Put the call to the decorators in the right place\n\t\t\tif prop.Kind == js_ast.PropertyField {\n\t\t\t\t// Field\n\t\t\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t\t\tctx.decoratorStaticFieldElements = append(ctx.decoratorStaticFieldElements, element)\n\t\t\t\t} else {\n\t\t\t\t\tctx.decoratorInstanceFieldElements = append(ctx.decoratorInstanceFieldElements, element)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Non-field\n\t\t\t\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\t\t\t\tctx.decoratorStaticNonFieldElements = append(ctx.decoratorStaticNonFieldElements, element)\n\t\t\t\t} else {\n\t\t\t\t\tctx.decoratorInstanceNonFieldElements = append(ctx.decoratorInstanceNonFieldElements, element)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Omit decorated auto-accessors as they will be now generated at run-time instead\n\t\t\tif prop.Kind == js_ast.PropertyAutoAccessor {\n\t\t\t\tif analysis.private != nil {\n\t\t\t\t\tctx.lowerPrivateMethod(p, prop, analysis.private)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Generate get/set methods for auto-accessors\n\t\tif analysis.rewriteAutoAccessorToGetSet {\n\t\t\tproperties = ctx.rewriteAutoAccessorToGetSet(p, prop, properties, keyExprNoSideEffects, analysis.mustLowerField, analysis.private, result)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Lower fields\n\t\tif (!prop.Kind.IsMethodDefinition() && analysis.mustLowerField) || analysis.staticFieldToBlockAssign {\n\t\t\tvar keep bool\n\t\t\tprop, _, keep = ctx.lowerField(p, prop, analysis.private, analysis.shouldOmitFieldInitializer, analysis.staticFieldToBlockAssign, initializerIndex)\n\t\t\tif !keep {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Lower methods\n\t\tif prop.Kind.IsMethodDefinition() && ctx.lowerMethod(p, prop, analysis.private) {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Keep this property\n\t\tproperties = append(properties, prop)\n\t}\n\n\t// Finish the filtering operation\n\tctx.class.Properties = properties\n}\n\nfunc (ctx *lowerClassContext) lowerStaticBlock(p *parser, loc logger.Loc, block js_ast.ClassStaticBlock) {\n\tisAllExprs := []js_ast.Expr{}\n\n\t// Are all statements in the block expression statements?\nloop:\n\tfor _, stmt := range block.Block.Stmts {\n\t\tswitch s := stmt.Data.(type) {\n\t\tcase *js_ast.SEmpty:\n\t\t\t// Omit stray semicolons completely\n\t\tcase *js_ast.SExpr:\n\t\t\tisAllExprs = append(isAllExprs, s.Value)\n\t\tdefault:\n\t\t\tisAllExprs = nil\n\t\t\tbreak loop\n\t\t}\n\t}\n\n\tif isAllExprs != nil {\n\t\t// I think it should be safe to inline the static block IIFE here\n\t\t// since all uses of \"this\" should have already been replaced by now.\n\t\tctx.staticMembers = append(ctx.staticMembers, isAllExprs...)\n\t} else {\n\t\t// But if there is a non-expression statement, fall back to using an\n\t\t// IIFE since we may be in an expression context and can't use a block.\n\t\tctx.staticMembers = append(ctx.staticMembers, js_ast.Expr{Loc: loc, Data: &js_ast.ECall{\n\t\t\tTarget: js_ast.Expr{Loc: loc, Data: &js_ast.EArrow{Body: js_ast.FnBody{\n\t\t\t\tLoc:   block.Loc,\n\t\t\t\tBlock: block.Block,\n\t\t\t}}},\n\t\t\tCanBeUnwrappedIfUnused: p.astHelpers.StmtsCanBeRemovedIfUnused(block.Block.Stmts, 0),\n\t\t}})\n\t}\n}\n\nfunc (ctx *lowerClassContext) rewriteAutoAccessorToGetSet(\n\tp *parser,\n\tprop js_ast.Property,\n\tproperties []js_ast.Property,\n\tkeyExprNoSideEffects js_ast.Expr,\n\tmustLowerField bool,\n\tprivate *js_ast.EPrivateIdentifier,\n\tresult visitClassResult,\n) []js_ast.Property {\n\tvar storageKind ast.SymbolKind\n\tif prop.Flags.Has(js_ast.PropertyIsStatic) {\n\t\tstorageKind = ast.SymbolPrivateStaticField\n\t} else {\n\t\tstorageKind = ast.SymbolPrivateField\n\t}\n\n\t// Generate the name of the private field to use for storage\n\tvar storageName string\n\tswitch k := keyExprNoSideEffects.Data.(type) {\n\tcase *js_ast.EString:\n\t\tstorageName = \"#\" + helpers.UTF16ToString(k.Value)\n\tcase *js_ast.EPrivateIdentifier:\n\t\tstorageName = \"#_\" + p.symbols[k.Ref.InnerIndex].OriginalName[1:]\n\tdefault:\n\t\tstorageName = \"#\" + ast.DefaultNameMinifierJS.NumberToMinifiedName(ctx.autoAccessorCount)\n\t\tctx.autoAccessorCount++\n\t}\n\n\t// Generate the symbols we need\n\tstorageRef := p.newSymbol(storageKind, storageName)\n\targRef := p.newSymbol(ast.SymbolOther, \"_\")\n\tresult.bodyScope.Generated = append(result.bodyScope.Generated, storageRef)\n\tresult.bodyScope.Children = append(result.bodyScope.Children, &js_ast.Scope{Kind: js_ast.ScopeFunctionBody, Generated: []ast.Ref{argRef}})\n\n\t// Replace this accessor with other properties\n\tloc := keyExprNoSideEffects.Loc\n\tstoragePrivate := &js_ast.EPrivateIdentifier{Ref: storageRef}\n\tif mustLowerField {\n\t\t// Forward the accessor's lowering status on to the storage field. If we\n\t\t// don't do this, then we risk having the underlying private symbol\n\t\t// behaving differently than if it were authored manually (e.g. being\n\t\t// placed outside of the class body, which is a syntax error).\n\t\tp.symbols[storageRef.InnerIndex].Flags |= ast.PrivateSymbolMustBeLowered\n\t}\n\tstorageNeedsToBeLowered := p.privateSymbolNeedsToBeLowered(storagePrivate)\n\tstorageProp := js_ast.Property{\n\t\tLoc:              prop.Loc,\n\t\tKind:             js_ast.PropertyField,\n\t\tFlags:            prop.Flags & js_ast.PropertyIsStatic,\n\t\tKey:              js_ast.Expr{Loc: loc, Data: storagePrivate},\n\t\tInitializerOrNil: prop.InitializerOrNil,\n\t}\n\tif !mustLowerField {\n\t\tproperties = append(properties, storageProp)\n\t} else if prop, _, ok := ctx.lowerField(p, storageProp, storagePrivate, false, false, -1); ok {\n\t\tproperties = append(properties, prop)\n\t}\n\n\t// Getter\n\tvar getExpr js_ast.Expr\n\tif storageNeedsToBeLowered {\n\t\tgetExpr = p.lowerPrivateGet(js_ast.Expr{Loc: loc, Data: js_ast.EThisShared}, loc, storagePrivate)\n\t} else {\n\t\tp.recordUsage(storageRef)\n\t\tgetExpr = js_ast.Expr{Loc: loc, Data: &js_ast.EIndex{\n\t\t\tTarget: js_ast.Expr{Loc: loc, Data: js_ast.EThisShared},\n\t\t\tIndex:  js_ast.Expr{Loc: loc, Data: &js_ast.EPrivateIdentifier{Ref: storageRef}},\n\t\t}}\n\t}\n\tgetterProp := js_ast.Property{\n\t\tLoc:   prop.Loc,\n\t\tKind:  js_ast.PropertyGetter,\n\t\tFlags: prop.Flags,\n\t\tKey:   prop.Key,\n\t\tValueOrNil: js_ast.Expr{Loc: loc, Data: &js_ast.EFunction{\n\t\t\tFn: js_ast.Fn{\n\t\t\t\tBody: js_ast.FnBody{\n\t\t\t\t\tLoc: loc,\n\t\t\t\t\tBlock: js_ast.SBlock{\n\t\t\t\t\t\tStmts: []js_ast.Stmt{\n\t\t\t\t\t\t\t{Loc: loc, Data: &js_ast.SReturn{ValueOrNil: getExpr}},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}},\n\t}\n\tif !ctx.lowerMethod(p, getterProp, private) {\n\t\tproperties = append(properties, getterProp)\n\t}\n\n\t// Setter\n\tvar setExpr js_ast.Expr\n\tif storageNeedsToBeLowered {\n\t\tsetExpr = p.lowerPrivateSet(js_ast.Expr{Loc: loc, Data: js_ast.EThisShared}, loc, storagePrivate,\n\t\t\tjs_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: argRef}})\n\t} else {\n\t\tp.recordUsage(storageRef)\n\t\tp.recordUsage(argRef)\n\t\tsetExpr = js_ast.Assign(\n\t\t\tjs_ast.Expr{Loc: loc, Data: &js_ast.EIndex{\n\t\t\t\tTarget: js_ast.Expr{Loc: loc, Data: js_ast.EThisShared},\n\t\t\t\tIndex:  js_ast.Expr{Loc: loc, Data: &js_ast.EPrivateIdentifier{Ref: storageRef}},\n\t\t\t}},\n\t\t\tjs_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: argRef}},\n\t\t)\n\t}\n\tsetterProp := js_ast.Property{\n\t\tLoc:   prop.Loc,\n\t\tKind:  js_ast.PropertySetter,\n\t\tFlags: prop.Flags,\n\t\tKey:   cloneKeyForLowerClass(keyExprNoSideEffects),\n\t\tValueOrNil: js_ast.Expr{Loc: loc, Data: &js_ast.EFunction{\n\t\t\tFn: js_ast.Fn{\n\t\t\t\tArgs: []js_ast.Arg{\n\t\t\t\t\t{Binding: js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: argRef}}},\n\t\t\t\t},\n\t\t\t\tBody: js_ast.FnBody{\n\t\t\t\t\tLoc: loc,\n\t\t\t\t\tBlock: js_ast.SBlock{\n\t\t\t\t\t\tStmts: []js_ast.Stmt{\n\t\t\t\t\t\t\t{Loc: loc, Data: &js_ast.SExpr{Value: setExpr}},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}},\n\t}\n\tif !ctx.lowerMethod(p, setterProp, private) {\n\t\tproperties = append(properties, setterProp)\n\t}\n\treturn properties\n}\n\nfunc (ctx *lowerClassContext) insertInitializersIntoConstructor(p *parser, classLoweringInfo classLoweringInfo, result visitClassResult) {\n\tif len(ctx.parameterFields) == 0 &&\n\t\t!ctx.decoratorCallInstanceMethodExtraInitializers &&\n\t\tlen(ctx.instancePrivateMethods) == 0 &&\n\t\tlen(ctx.instanceMembers) == 0 &&\n\t\t(ctx.ctor == nil || result.superCtorRef == ast.InvalidRef) {\n\t\t// No need to generate a constructor\n\t\treturn\n\t}\n\n\t// Create a constructor if one doesn't already exist\n\tif ctx.ctor == nil {\n\t\tctx.ctor = &js_ast.EFunction{Fn: js_ast.Fn{Body: js_ast.FnBody{Loc: ctx.classLoc}}}\n\n\t\t// Append it to the list to reuse existing allocation space\n\t\tctx.class.Properties = append(ctx.class.Properties, js_ast.Property{\n\t\t\tKind:       js_ast.PropertyMethod,\n\t\t\tLoc:        ctx.classLoc,\n\t\t\tKey:        js_ast.Expr{Loc: ctx.classLoc, Data: &js_ast.EString{Value: helpers.StringToUTF16(\"constructor\")}},\n\t\t\tValueOrNil: js_ast.Expr{Loc: ctx.classLoc, Data: ctx.ctor},\n\t\t})\n\n\t\t// Make sure the constructor has a super() call if needed\n\t\tif ctx.class.ExtendsOrNil.Data != nil {\n\t\t\ttarget := js_ast.Expr{Loc: ctx.classLoc, Data: js_ast.ESuperShared}\n\t\t\tif classLoweringInfo.shimSuperCtorCalls {\n\t\t\t\tp.recordUsage(result.superCtorRef)\n\t\t\t\ttarget.Data = &js_ast.EIdentifier{Ref: result.superCtorRef}\n\t\t\t}\n\t\t\targumentsRef := p.newSymbol(ast.SymbolUnbound, \"arguments\")\n\t\t\tp.currentScope.Generated = append(p.currentScope.Generated, argumentsRef)\n\t\t\tctx.ctor.Fn.Body.Block.Stmts = append(ctx.ctor.Fn.Body.Block.Stmts, js_ast.Stmt{Loc: ctx.classLoc, Data: &js_ast.SExpr{Value: js_ast.Expr{Loc: ctx.classLoc, Data: &js_ast.ECall{\n\t\t\t\tTarget: target,\n\t\t\t\tArgs:   []js_ast.Expr{{Loc: ctx.classLoc, Data: &js_ast.ESpread{Value: js_ast.Expr{Loc: ctx.classLoc, Data: &js_ast.EIdentifier{Ref: argumentsRef}}}}},\n\t\t\t}}}})\n\t\t}\n\t}\n\n\t// Run instanceMethodExtraInitializers if needed\n\tvar decoratorInstanceMethodExtraInitializers js_ast.Expr\n\tif ctx.decoratorCallInstanceMethodExtraInitializers {\n\t\tdecoratorInstanceMethodExtraInitializers = p.callRuntime(ctx.classLoc, \"__runInitializers\", []js_ast.Expr{\n\t\t\t{Loc: ctx.classLoc, Data: &js_ast.EIdentifier{Ref: ctx.decoratorContextRef}},\n\t\t\t{Loc: ctx.classLoc, Data: &js_ast.ENumber{Value: (2 << 1) | 1}},\n\t\t\t{Loc: ctx.classLoc, Data: js_ast.EThisShared},\n\t\t})\n\t\tp.recordUsage(ctx.decoratorContextRef)\n\t}\n\n\t// Make sure the instance field initializers come after \"super()\" since\n\t// they need \"this\" to ba available\n\tgeneratedStmts := make([]js_ast.Stmt, 0,\n\t\tlen(ctx.parameterFields)+\n\t\t\tlen(ctx.instancePrivateMethods)+\n\t\t\tlen(ctx.instanceMembers))\n\tgeneratedStmts = append(generatedStmts, ctx.parameterFields...)\n\tif decoratorInstanceMethodExtraInitializers.Data != nil {\n\t\tgeneratedStmts = append(generatedStmts, js_ast.Stmt{Loc: decoratorInstanceMethodExtraInitializers.Loc, Data: &js_ast.SExpr{Value: decoratorInstanceMethodExtraInitializers}})\n\t}\n\tgeneratedStmts = append(generatedStmts, ctx.instancePrivateMethods...)\n\tgeneratedStmts = append(generatedStmts, ctx.instanceMembers...)\n\tp.insertStmtsAfterSuperCall(&ctx.ctor.Fn.Body, generatedStmts, result.superCtorRef)\n\n\t// Sort the constructor first to match the TypeScript compiler's output\n\tfor i := 0; i < len(ctx.class.Properties); i++ {\n\t\tif ctx.class.Properties[i].ValueOrNil.Data == ctx.ctor {\n\t\t\tctorProp := ctx.class.Properties[i]\n\t\t\tfor j := i; j > 0; j-- {\n\t\t\t\tctx.class.Properties[j] = ctx.class.Properties[j-1]\n\t\t\t}\n\t\t\tctx.class.Properties[0] = ctorProp\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc (ctx *lowerClassContext) finishAndGenerateCode(p *parser, result visitClassResult) ([]js_ast.Stmt, js_ast.Expr) {\n\t// When bundling is enabled, we convert top-level class statements to\n\t// expressions:\n\t//\n\t//   // Before\n\t//   class Foo {\n\t//     static foo = () => Foo\n\t//   }\n\t//   Foo = wrap(Foo)\n\t//\n\t//   // After\n\t//   var _Foo = class _Foo {\n\t//     static foo = () => _Foo;\n\t//   };\n\t//   var Foo = _Foo;\n\t//   Foo = wrap(Foo);\n\t//\n\t// One reason to do this is that esbuild's bundler sometimes needs to lazily-\n\t// evaluate a module. For example, a module may end up being both the target\n\t// of a dynamic \"import()\" call and a static \"import\" statement. Lazy module\n\t// evaluation is done by wrapping the top-level module code in a closure. To\n\t// avoid a performance hit for static \"import\" statements, esbuild stores\n\t// top-level exported symbols outside of the closure and references them\n\t// directly instead of indirectly.\n\t//\n\t// Another reason to do this is that multiple JavaScript VMs have had and\n\t// continue to have performance issues with TDZ (i.e. \"temporal dead zone\")\n\t// checks. These checks validate that a let, or const, or class symbol isn't\n\t// used before it's initialized. Here are two issues with well-known VMs:\n\t//\n\t//   * V8: https://bugs.chromium.org/p/v8/issues/detail?id=13723 (10% slowdown)\n\t//   * JavaScriptCore: https://bugs.webkit.org/show_bug.cgi?id=199866 (1,000% slowdown!)\n\t//\n\t// JavaScriptCore had a severe performance issue as their TDZ implementation\n\t// had time complexity that was quadratic in the number of variables needing\n\t// TDZ checks in the same scope (with the top-level scope typically being the\n\t// worst offender). V8 has ongoing issues with TDZ checks being present\n\t// throughout the code their JIT generates even when they have already been\n\t// checked earlier in the same function or when the function in question has\n\t// already been run (so the checks have already happened).\n\t//\n\t// Due to esbuild's parallel architecture, we both a) need to transform class\n\t// statements to variables during parsing and b) don't yet know whether this\n\t// module will need to be lazily-evaluated or not in the parser. So we always\n\t// do this just in case it's needed.\n\tmustConvertStmtToExpr := ctx.kind != classKindExpr && p.currentScope.Parent == nil && (p.options.mode == config.ModeBundle || p.willWrapModuleInTryCatchForUsing)\n\n\t// Check to see if we have lowered decorators on the class itself\n\tvar classDecorators js_ast.Expr\n\tvar classExperimentalDecorators []js_ast.Decorator\n\tif p.options.ts.Parse && p.options.ts.Config.ExperimentalDecorators == config.True {\n\t\tclassExperimentalDecorators = ctx.class.Decorators\n\t\tctx.class.Decorators = nil\n\t} else if ctx.class.ShouldLowerStandardDecorators {\n\t\tclassDecorators = ctx.decoratorClassDecorators\n\t}\n\n\tvar decorateClassExpr js_ast.Expr\n\tif classDecorators.Data != nil {\n\t\t// Handle JavaScript decorators on the class itself\n\t\tif ctx.decoratorContextRef == ast.InvalidRef {\n\t\t\tctx.decoratorContextRef = p.generateTempRef(tempRefNeedsDeclare, \"_init\")\n\t\t}\n\t\tdecorateClassExpr = p.callRuntime(ctx.classLoc, \"__decorateElement\", []js_ast.Expr{\n\t\t\t{Loc: ctx.classLoc, Data: &js_ast.EIdentifier{Ref: ctx.decoratorContextRef}},\n\t\t\t{Loc: ctx.classLoc, Data: &js_ast.ENumber{Value: 0}},\n\t\t\t{Loc: ctx.classLoc, Data: &js_ast.EString{Value: helpers.StringToUTF16(ctx.nameToKeep)}},\n\t\t\tclassDecorators,\n\t\t\tctx.nameFunc(),\n\t\t})\n\t\tp.recordUsage(ctx.decoratorContextRef)\n\t\tdecorateClassExpr = js_ast.Assign(ctx.nameFunc(), decorateClassExpr)\n\t} else if ctx.decoratorContextRef != ast.InvalidRef {\n\t\t// Decorator metadata is present if there are any decorators on the class at all\n\t\tdecorateClassExpr = p.callRuntime(ctx.classLoc, \"__decoratorMetadata\", []js_ast.Expr{\n\t\t\t{Loc: ctx.classLoc, Data: &js_ast.EIdentifier{Ref: ctx.decoratorContextRef}},\n\t\t\tctx.nameFunc(),\n\t\t})\n\t}\n\n\t// If this is true, we have removed some code from the class body that could\n\t// potentially contain an expression that captures the inner class name.\n\t// In this case we must explicitly store the class to a separate inner class\n\t// name binding to avoid incorrect behavior if the class is later re-assigned,\n\t// since the removed code will no longer be in the class body scope.\n\thasPotentialInnerClassNameEscape := result.innerClassNameRef != ast.InvalidRef &&\n\t\t(ctx.computedPropertyChain.Data != nil ||\n\t\t\tlen(ctx.privateMembers) > 0 ||\n\t\t\tlen(ctx.staticPrivateMethods) > 0 ||\n\t\t\tlen(ctx.staticMembers) > 0 ||\n\n\t\t\t// TypeScript experimental decorators\n\t\t\tlen(ctx.instanceExperimentalDecorators) > 0 ||\n\t\t\tlen(ctx.staticExperimentalDecorators) > 0 ||\n\t\t\tlen(classExperimentalDecorators) > 0 ||\n\n\t\t\t// JavaScript decorators\n\t\t\tctx.decoratorContextRef != ast.InvalidRef)\n\n\t// If we need to represent the class as an expression (even if it's a\n\t// statement), then generate another symbol to use as the class name\n\tnameForClassDecorators := ast.LocRef{Ref: ast.InvalidRef}\n\tif len(classExperimentalDecorators) > 0 || hasPotentialInnerClassNameEscape || mustConvertStmtToExpr {\n\t\tif ctx.kind == classKindExpr {\n\t\t\t// For expressions, the inner and outer class names are the same\n\t\t\tname := ctx.nameFunc()\n\t\t\tnameForClassDecorators = ast.LocRef{Loc: name.Loc, Ref: name.Data.(*js_ast.EIdentifier).Ref}\n\t\t} else {\n\t\t\t// For statements we need to use the outer class name, not the inner one\n\t\t\tif ctx.class.Name != nil {\n\t\t\t\tnameForClassDecorators = *ctx.class.Name\n\t\t\t} else if ctx.kind == classKindExportDefaultStmt {\n\t\t\t\tnameForClassDecorators = ctx.defaultName\n\t\t\t} else {\n\t\t\t\tnameForClassDecorators = ast.LocRef{Loc: ctx.classLoc, Ref: p.generateTempRef(tempRefNoDeclare, \"\")}\n\t\t\t}\n\t\t\tp.recordUsage(nameForClassDecorators.Ref)\n\t\t}\n\t}\n\n\tvar prefixExprs []js_ast.Expr\n\tvar suffixExprs []js_ast.Expr\n\n\t// If there are JavaScript decorators, start by allocating a context object\n\tif ctx.decoratorContextRef != ast.InvalidRef {\n\t\tbase := js_ast.Expr{Loc: ctx.classLoc, Data: js_ast.ENullShared}\n\t\tif ctx.class.ExtendsOrNil.Data != nil {\n\t\t\tif ctx.extendsRef == ast.InvalidRef {\n\t\t\t\tctx.extendsRef = p.generateTempRef(tempRefNeedsDeclare, \"\")\n\t\t\t\tctx.class.ExtendsOrNil = js_ast.Assign(js_ast.Expr{Loc: ctx.class.ExtendsOrNil.Loc, Data: &js_ast.EIdentifier{Ref: ctx.extendsRef}}, ctx.class.ExtendsOrNil)\n\t\t\t\tp.recordUsage(ctx.extendsRef)\n\t\t\t}\n\t\t\tbase.Data = &js_ast.EIdentifier{Ref: ctx.extendsRef}\n\t\t}\n\t\tsuffixExprs = append(suffixExprs, js_ast.Assign(\n\t\t\tjs_ast.Expr{Loc: ctx.classLoc, Data: &js_ast.EIdentifier{Ref: ctx.decoratorContextRef}},\n\t\t\tp.callRuntime(ctx.classLoc, \"__decoratorStart\", []js_ast.Expr{base}),\n\t\t))\n\t\tp.recordUsage(ctx.decoratorContextRef)\n\t}\n\n\t// Any of the computed property chain that we hoisted out of the class\n\t// body needs to come before the class expression.\n\tif ctx.computedPropertyChain.Data != nil {\n\t\tprefixExprs = append(prefixExprs, ctx.computedPropertyChain)\n\t}\n\n\t// WeakSets and WeakMaps\n\tsuffixExprs = append(suffixExprs, ctx.privateMembers...)\n\n\t// Evaluate JavaScript decorators here\n\tsuffixExprs = append(suffixExprs, ctx.decoratorStaticNonFieldElements...)\n\tsuffixExprs = append(suffixExprs, ctx.decoratorInstanceNonFieldElements...)\n\tsuffixExprs = append(suffixExprs, ctx.decoratorStaticFieldElements...)\n\tsuffixExprs = append(suffixExprs, ctx.decoratorInstanceFieldElements...)\n\n\t// Lowered initializers for static methods (including getters and setters)\n\tsuffixExprs = append(suffixExprs, ctx.staticPrivateMethods...)\n\n\t// Run JavaScript class decorators at the end of class initialization\n\tif decorateClassExpr.Data != nil {\n\t\tsuffixExprs = append(suffixExprs, decorateClassExpr)\n\t}\n\n\t// For each element initializer of staticMethodExtraInitializers\n\tif ctx.decoratorCallStaticMethodExtraInitializers {\n\t\tsuffixExprs = append(suffixExprs, p.callRuntime(ctx.classLoc, \"__runInitializers\", []js_ast.Expr{\n\t\t\t{Loc: ctx.classLoc, Data: &js_ast.EIdentifier{Ref: ctx.decoratorContextRef}},\n\t\t\t{Loc: ctx.classLoc, Data: &js_ast.ENumber{Value: (1 << 1) | 1}},\n\t\t\tctx.nameFunc(),\n\t\t}))\n\t\tp.recordUsage(ctx.decoratorContextRef)\n\t}\n\n\t// Lowered initializers for static fields, static accessors, and static blocks\n\tsuffixExprs = append(suffixExprs, ctx.staticMembers...)\n\n\t// The official TypeScript compiler adds generated code after the class body\n\t// in this exact order. Matching this order is important for correctness.\n\tsuffixExprs = append(suffixExprs, ctx.instanceExperimentalDecorators...)\n\tsuffixExprs = append(suffixExprs, ctx.staticExperimentalDecorators...)\n\n\t// For each element initializer of classExtraInitializers\n\tif classDecorators.Data != nil {\n\t\tsuffixExprs = append(suffixExprs, p.callRuntime(ctx.classLoc, \"__runInitializers\", []js_ast.Expr{\n\t\t\t{Loc: ctx.classLoc, Data: &js_ast.EIdentifier{Ref: ctx.decoratorContextRef}},\n\t\t\t{Loc: ctx.classLoc, Data: &js_ast.ENumber{Value: (0 << 1) | 1}},\n\t\t\tctx.nameFunc(),\n\t\t}))\n\t\tp.recordUsage(ctx.decoratorContextRef)\n\t}\n\n\t// Run TypeScript experimental class decorators at the end of class initialization\n\tif len(classExperimentalDecorators) > 0 {\n\t\tvalues := make([]js_ast.Expr, len(classExperimentalDecorators))\n\t\tfor i, decorator := range classExperimentalDecorators {\n\t\t\tvalues[i] = decorator.Value\n\t\t}\n\t\tsuffixExprs = append(suffixExprs, js_ast.Assign(\n\t\t\tjs_ast.Expr{Loc: nameForClassDecorators.Loc, Data: &js_ast.EIdentifier{Ref: nameForClassDecorators.Ref}},\n\t\t\tp.callRuntime(ctx.classLoc, \"__decorateClass\", []js_ast.Expr{\n\t\t\t\t{Loc: ctx.classLoc, Data: &js_ast.EArray{Items: values}},\n\t\t\t\t{Loc: nameForClassDecorators.Loc, Data: &js_ast.EIdentifier{Ref: nameForClassDecorators.Ref}},\n\t\t\t}),\n\t\t))\n\t\tp.recordUsage(nameForClassDecorators.Ref)\n\t\tp.recordUsage(nameForClassDecorators.Ref)\n\t}\n\n\t// Our caller expects us to return the same form that was originally given to\n\t// us. If the class was originally an expression, then return an expression.\n\tif ctx.kind == classKindExpr {\n\t\t// Calling \"nameFunc\" will replace \"classExpr\", so make sure to do that first\n\t\t// before joining \"classExpr\" with any other expressions\n\t\tvar nameToJoin js_ast.Expr\n\t\tif ctx.didCaptureClassExpr || len(suffixExprs) > 0 {\n\t\t\tnameToJoin = ctx.nameFunc()\n\t\t}\n\n\t\t// Insert expressions on either side of the class as appropriate\n\t\tctx.classExpr = js_ast.JoinWithComma(js_ast.JoinAllWithComma(prefixExprs), ctx.classExpr)\n\t\tctx.classExpr = js_ast.JoinWithComma(ctx.classExpr, js_ast.JoinAllWithComma(suffixExprs))\n\n\t\t// Finally join \"classExpr\" with the variable that holds the class object\n\t\tctx.classExpr = js_ast.JoinWithComma(ctx.classExpr, nameToJoin)\n\t\tif ctx.wrapFunc != nil {\n\t\t\tctx.classExpr = ctx.wrapFunc(ctx.classExpr)\n\t\t}\n\t\treturn nil, ctx.classExpr\n\t}\n\n\t// Otherwise, the class was originally a statement. Return an array of\n\t// statements instead.\n\tvar stmts []js_ast.Stmt\n\tvar outerClassNameDecl js_ast.Stmt\n\n\t// Insert expressions before the class as appropriate\n\tfor _, expr := range prefixExprs {\n\t\tstmts = append(stmts, js_ast.Stmt{Loc: expr.Loc, Data: &js_ast.SExpr{Value: expr}})\n\t}\n\n\t// Handle converting a class statement to a class expression\n\tif nameForClassDecorators.Ref != ast.InvalidRef {\n\t\tclassExpr := js_ast.EClass{Class: *ctx.class}\n\t\tctx.class = &classExpr.Class\n\t\tinit := js_ast.Expr{Loc: ctx.classLoc, Data: &classExpr}\n\n\t\t// If the inner class name was referenced, then set the name of the class\n\t\t// that we will end up printing to the inner class name. Otherwise if the\n\t\t// inner class name was unused, we can just leave it blank.\n\t\tif result.innerClassNameRef != ast.InvalidRef {\n\t\t\t// \"class Foo { x = Foo }\" => \"const Foo = class _Foo { x = _Foo }\"\n\t\t\tctx.class.Name.Ref = result.innerClassNameRef\n\t\t} else {\n\t\t\t// \"class Foo {}\" => \"const Foo = class {}\"\n\t\t\tctx.class.Name = nil\n\t\t}\n\n\t\t// Generate the class initialization statement\n\t\tif len(classExperimentalDecorators) > 0 {\n\t\t\t// If there are class decorators, then we actually need to mutate the\n\t\t\t// immutable \"const\" binding that shadows everything in the class body.\n\t\t\t// The official TypeScript compiler does this by rewriting all class name\n\t\t\t// references in the class body to another temporary variable. This is\n\t\t\t// basically what we're doing here.\n\t\t\tp.recordUsage(nameForClassDecorators.Ref)\n\t\t\tstmts = append(stmts, js_ast.Stmt{Loc: ctx.classLoc, Data: &js_ast.SLocal{\n\t\t\t\tKind:     p.selectLocalKind(js_ast.LocalLet),\n\t\t\t\tIsExport: ctx.kind == classKindExportStmt,\n\t\t\t\tDecls: []js_ast.Decl{{\n\t\t\t\t\tBinding:    js_ast.Binding{Loc: nameForClassDecorators.Loc, Data: &js_ast.BIdentifier{Ref: nameForClassDecorators.Ref}},\n\t\t\t\t\tValueOrNil: init,\n\t\t\t\t}},\n\t\t\t}})\n\t\t\tif ctx.class.Name != nil {\n\t\t\t\tp.mergeSymbols(ctx.class.Name.Ref, nameForClassDecorators.Ref)\n\t\t\t\tctx.class.Name = nil\n\t\t\t}\n\t\t} else if hasPotentialInnerClassNameEscape {\n\t\t\t// If the inner class name was used, then we explicitly generate a binding\n\t\t\t// for it. That means the mutable outer class name is separate, and is\n\t\t\t// initialized after all static member initializers have finished.\n\t\t\tcaptureRef := p.newSymbol(ast.SymbolOther, p.symbols[result.innerClassNameRef.InnerIndex].OriginalName)\n\t\t\tp.currentScope.Generated = append(p.currentScope.Generated, captureRef)\n\t\t\tp.recordDeclaredSymbol(captureRef)\n\t\t\tp.mergeSymbols(result.innerClassNameRef, captureRef)\n\t\t\tkind := js_ast.LocalConst\n\t\t\tif classDecorators.Data != nil {\n\t\t\t\t// Class decorators need to be able to potentially mutate this binding\n\t\t\t\tkind = js_ast.LocalLet\n\t\t\t}\n\t\t\tstmts = append(stmts, js_ast.Stmt{Loc: ctx.classLoc, Data: &js_ast.SLocal{\n\t\t\t\tKind: p.selectLocalKind(kind),\n\t\t\t\tDecls: []js_ast.Decl{{\n\t\t\t\t\tBinding:    js_ast.Binding{Loc: nameForClassDecorators.Loc, Data: &js_ast.BIdentifier{Ref: captureRef}},\n\t\t\t\t\tValueOrNil: init,\n\t\t\t\t}},\n\t\t\t}})\n\t\t\tp.recordUsage(nameForClassDecorators.Ref)\n\t\t\tp.recordUsage(captureRef)\n\t\t\touterClassNameDecl = js_ast.Stmt{Loc: ctx.classLoc, Data: &js_ast.SLocal{\n\t\t\t\tKind:     p.selectLocalKind(js_ast.LocalLet),\n\t\t\t\tIsExport: ctx.kind == classKindExportStmt,\n\t\t\t\tDecls: []js_ast.Decl{{\n\t\t\t\t\tBinding:    js_ast.Binding{Loc: nameForClassDecorators.Loc, Data: &js_ast.BIdentifier{Ref: nameForClassDecorators.Ref}},\n\t\t\t\t\tValueOrNil: js_ast.Expr{Loc: ctx.classLoc, Data: &js_ast.EIdentifier{Ref: captureRef}},\n\t\t\t\t}},\n\t\t\t}}\n\t\t} else {\n\t\t\t// Otherwise, the inner class name isn't needed and we can just\n\t\t\t// use a single variable declaration for the outer class name.\n\t\t\tp.recordUsage(nameForClassDecorators.Ref)\n\t\t\tstmts = append(stmts, js_ast.Stmt{Loc: ctx.classLoc, Data: &js_ast.SLocal{\n\t\t\t\tKind:     p.selectLocalKind(js_ast.LocalLet),\n\t\t\t\tIsExport: ctx.kind == classKindExportStmt,\n\t\t\t\tDecls: []js_ast.Decl{{\n\t\t\t\t\tBinding:    js_ast.Binding{Loc: nameForClassDecorators.Loc, Data: &js_ast.BIdentifier{Ref: nameForClassDecorators.Ref}},\n\t\t\t\t\tValueOrNil: init,\n\t\t\t\t}},\n\t\t\t}})\n\t\t}\n\t} else {\n\t\t// Generate the specific kind of class statement that was passed in to us\n\t\tswitch ctx.kind {\n\t\tcase classKindStmt:\n\t\t\tstmts = append(stmts, js_ast.Stmt{Loc: ctx.classLoc, Data: &js_ast.SClass{Class: *ctx.class}})\n\t\tcase classKindExportStmt:\n\t\t\tstmts = append(stmts, js_ast.Stmt{Loc: ctx.classLoc, Data: &js_ast.SClass{Class: *ctx.class, IsExport: true}})\n\t\tcase classKindExportDefaultStmt:\n\t\t\tstmts = append(stmts, js_ast.Stmt{Loc: ctx.classLoc, Data: &js_ast.SExportDefault{\n\t\t\t\tDefaultName: ctx.defaultName,\n\t\t\t\tValue:       js_ast.Stmt{Loc: ctx.classLoc, Data: &js_ast.SClass{Class: *ctx.class}},\n\t\t\t}})\n\t\t}\n\n\t\t// The inner class name inside the class statement should be the same as\n\t\t// the class statement name itself\n\t\tif ctx.class.Name != nil && result.innerClassNameRef != ast.InvalidRef {\n\t\t\t// If the class body contains a direct eval call, then the inner class\n\t\t\t// name will be marked as \"MustNotBeRenamed\" (because we have already\n\t\t\t// popped the class body scope) but the outer class name won't be marked\n\t\t\t// as \"MustNotBeRenamed\" yet (because we haven't yet popped the containing\n\t\t\t// scope). Propagate this flag now before we merge these symbols so we\n\t\t\t// don't end up accidentally renaming the outer class name to the inner\n\t\t\t// class name.\n\t\t\tif p.currentScope.ContainsDirectEval {\n\t\t\t\tp.symbols[ctx.class.Name.Ref.InnerIndex].Flags |= (p.symbols[result.innerClassNameRef.InnerIndex].Flags & ast.MustNotBeRenamed)\n\t\t\t}\n\t\t\tp.mergeSymbols(result.innerClassNameRef, ctx.class.Name.Ref)\n\t\t}\n\t}\n\n\t// Insert expressions after the class as appropriate\n\tfor _, expr := range suffixExprs {\n\t\tstmts = append(stmts, js_ast.Stmt{Loc: expr.Loc, Data: &js_ast.SExpr{Value: expr}})\n\t}\n\n\t// This must come after the class body initializers have finished\n\tif outerClassNameDecl.Data != nil {\n\t\tstmts = append(stmts, outerClassNameDecl)\n\t}\n\n\tif nameForClassDecorators.Ref != ast.InvalidRef && ctx.kind == classKindExportDefaultStmt {\n\t\t// \"export default class x {}\" => \"class x {} export {x as default}\"\n\t\tstmts = append(stmts, js_ast.Stmt{Loc: ctx.classLoc, Data: &js_ast.SExportClause{\n\t\t\tItems: []js_ast.ClauseItem{{Alias: \"default\", Name: ctx.defaultName}},\n\t\t}})\n\t}\n\treturn stmts, js_ast.Expr{}\n}\n\nfunc cloneKeyForLowerClass(key js_ast.Expr) js_ast.Expr {\n\tswitch k := key.Data.(type) {\n\tcase *js_ast.ENumber:\n\t\tclone := *k\n\t\tkey.Data = &clone\n\tcase *js_ast.EString:\n\t\tclone := *k\n\t\tkey.Data = &clone\n\tcase *js_ast.EIdentifier:\n\t\tclone := *k\n\t\tkey.Data = &clone\n\tcase *js_ast.ENameOfSymbol:\n\t\tclone := *k\n\t\tkey.Data = &clone\n\tcase *js_ast.EPrivateIdentifier:\n\t\tclone := *k\n\t\tkey.Data = &clone\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n\treturn key\n}\n\n// Replace \"super()\" calls with our shim so that we can guarantee\n// that instance field initialization doesn't happen before \"super()\"\n// is called, since at that point \"this\" isn't available.\nfunc (p *parser) insertStmtsAfterSuperCall(body *js_ast.FnBody, stmtsToInsert []js_ast.Stmt, superCtorRef ast.Ref) {\n\t// If this class has no base class, then there's no \"super()\" call to handle\n\tif superCtorRef == ast.InvalidRef || p.symbols[superCtorRef.InnerIndex].UseCountEstimate == 0 {\n\t\tbody.Block.Stmts = append(stmtsToInsert, body.Block.Stmts...)\n\t\treturn\n\t}\n\n\t// It's likely that there's only one \"super()\" call, and that it's a\n\t// top-level expression in the constructor function body. If so, we\n\t// can generate tighter code for this common case.\n\tif p.symbols[superCtorRef.InnerIndex].UseCountEstimate == 1 {\n\t\tfor i, stmt := range body.Block.Stmts {\n\t\t\tvar before js_ast.Expr\n\t\t\tvar callLoc logger.Loc\n\t\t\tvar callData *js_ast.ECall\n\t\t\tvar after js_ast.Stmt\n\n\t\t\tswitch s := stmt.Data.(type) {\n\t\t\tcase *js_ast.SExpr:\n\t\t\t\tif b, loc, c, a := findFirstTopLevelSuperCall(s.Value, superCtorRef); c != nil {\n\t\t\t\t\tbefore, callLoc, callData = b, loc, c\n\t\t\t\t\tif a.Data != nil {\n\t\t\t\t\t\ts.Value = a\n\t\t\t\t\t\tafter = js_ast.Stmt{Loc: a.Loc, Data: s}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tcase *js_ast.SReturn:\n\t\t\t\tif s.ValueOrNil.Data != nil {\n\t\t\t\t\tif b, loc, c, a := findFirstTopLevelSuperCall(s.ValueOrNil, superCtorRef); c != nil && a.Data != nil {\n\t\t\t\t\t\tbefore, callLoc, callData = b, loc, c\n\t\t\t\t\t\ts.ValueOrNil = a\n\t\t\t\t\t\tafter = js_ast.Stmt{Loc: a.Loc, Data: s}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tcase *js_ast.SThrow:\n\t\t\t\tif b, loc, c, a := findFirstTopLevelSuperCall(s.Value, superCtorRef); c != nil && a.Data != nil {\n\t\t\t\t\tbefore, callLoc, callData = b, loc, c\n\t\t\t\t\ts.Value = a\n\t\t\t\t\tafter = js_ast.Stmt{Loc: a.Loc, Data: s}\n\t\t\t\t}\n\n\t\t\tcase *js_ast.SIf:\n\t\t\t\tif b, loc, c, a := findFirstTopLevelSuperCall(s.Test, superCtorRef); c != nil && a.Data != nil {\n\t\t\t\t\tbefore, callLoc, callData = b, loc, c\n\t\t\t\t\ts.Test = a\n\t\t\t\t\tafter = js_ast.Stmt{Loc: a.Loc, Data: s}\n\t\t\t\t}\n\n\t\t\tcase *js_ast.SSwitch:\n\t\t\t\tif b, loc, c, a := findFirstTopLevelSuperCall(s.Test, superCtorRef); c != nil && a.Data != nil {\n\t\t\t\t\tbefore, callLoc, callData = b, loc, c\n\t\t\t\t\ts.Test = a\n\t\t\t\t\tafter = js_ast.Stmt{Loc: a.Loc, Data: s}\n\t\t\t\t}\n\n\t\t\tcase *js_ast.SFor:\n\t\t\t\tif expr, ok := s.InitOrNil.Data.(*js_ast.SExpr); ok {\n\t\t\t\t\tif b, loc, c, a := findFirstTopLevelSuperCall(expr.Value, superCtorRef); c != nil {\n\t\t\t\t\t\tbefore, callLoc, callData = b, loc, c\n\t\t\t\t\t\tif a.Data != nil {\n\t\t\t\t\t\t\texpr.Value = a\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ts.InitOrNil.Data = nil\n\t\t\t\t\t\t}\n\t\t\t\t\t\tafter = js_ast.Stmt{Loc: a.Loc, Data: s}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif callData != nil {\n\t\t\t\t// Revert \"__super()\" back to \"super()\"\n\t\t\t\tcallData.Target.Data = js_ast.ESuperShared\n\t\t\t\tp.ignoreUsage(superCtorRef)\n\n\t\t\t\t// Inject \"stmtsToInsert\" after \"super()\"\n\t\t\t\tstmtsBefore := body.Block.Stmts[:i]\n\t\t\t\tstmtsAfter := body.Block.Stmts[i+1:]\n\t\t\t\tstmts := append([]js_ast.Stmt{}, stmtsBefore...)\n\t\t\t\tif before.Data != nil {\n\t\t\t\t\tstmts = append(stmts, js_ast.Stmt{Loc: before.Loc, Data: &js_ast.SExpr{Value: before}})\n\t\t\t\t}\n\t\t\t\tstmts = append(stmts, js_ast.Stmt{Loc: callLoc, Data: &js_ast.SExpr{Value: js_ast.Expr{Loc: callLoc, Data: callData}}})\n\t\t\t\tstmts = append(stmts, stmtsToInsert...)\n\t\t\t\tif after.Data != nil {\n\t\t\t\t\tstmts = append(stmts, after)\n\t\t\t\t}\n\t\t\t\tstmts = append(stmts, stmtsAfter...)\n\t\t\t\tbody.Block.Stmts = stmts\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Otherwise, inject a generated \"__super\" helper function at the top of the\n\t// constructor that looks like this:\n\t//\n\t//   var __super = (...args) => {\n\t//     super(...args);\n\t//     ...stmtsToInsert...\n\t//     return this;\n\t//   };\n\t//\n\targsRef := p.newSymbol(ast.SymbolOther, \"args\")\n\tp.currentScope.Generated = append(p.currentScope.Generated, argsRef)\n\tp.recordUsage(argsRef)\n\tsuperCall := js_ast.Expr{Loc: body.Loc, Data: &js_ast.ECall{\n\t\tTarget: js_ast.Expr{Loc: body.Loc, Data: js_ast.ESuperShared},\n\t\tArgs:   []js_ast.Expr{{Loc: body.Loc, Data: &js_ast.ESpread{Value: js_ast.Expr{Loc: body.Loc, Data: &js_ast.EIdentifier{Ref: argsRef}}}}},\n\t}}\n\tstmtsToInsert = append(append(\n\t\t[]js_ast.Stmt{{Loc: body.Loc, Data: &js_ast.SExpr{Value: superCall}}},\n\t\tstmtsToInsert...),\n\t\tjs_ast.Stmt{Loc: body.Loc, Data: &js_ast.SReturn{ValueOrNil: js_ast.Expr{Loc: body.Loc, Data: js_ast.EThisShared}}},\n\t)\n\tif p.options.minifySyntax {\n\t\tstmtsToInsert = p.mangleStmts(stmtsToInsert, stmtsFnBody)\n\t}\n\tbody.Block.Stmts = append([]js_ast.Stmt{{Loc: body.Loc, Data: &js_ast.SLocal{Decls: []js_ast.Decl{{\n\t\tBinding: js_ast.Binding{Loc: body.Loc, Data: &js_ast.BIdentifier{Ref: superCtorRef}}, ValueOrNil: js_ast.Expr{Loc: body.Loc, Data: &js_ast.EArrow{\n\t\t\tHasRestArg: true,\n\t\t\tPreferExpr: true,\n\t\t\tArgs:       []js_ast.Arg{{Binding: js_ast.Binding{Loc: body.Loc, Data: &js_ast.BIdentifier{Ref: argsRef}}}},\n\t\t\tBody:       js_ast.FnBody{Loc: body.Loc, Block: js_ast.SBlock{Stmts: stmtsToInsert}},\n\t\t}},\n\t}}}}}, body.Block.Stmts...)\n}\n\nfunc findFirstTopLevelSuperCall(expr js_ast.Expr, superCtorRef ast.Ref) (js_ast.Expr, logger.Loc, *js_ast.ECall, js_ast.Expr) {\n\tif call, ok := expr.Data.(*js_ast.ECall); ok {\n\t\tif target, ok := call.Target.Data.(*js_ast.EIdentifier); ok && target.Ref == superCtorRef {\n\t\t\tcall.Target.Data = js_ast.ESuperShared\n\t\t\treturn js_ast.Expr{}, expr.Loc, call, js_ast.Expr{}\n\t\t}\n\t}\n\n\t// Also search down comma operator chains for a super call\n\tif comma, ok := expr.Data.(*js_ast.EBinary); ok && comma.Op == js_ast.BinOpComma {\n\t\tif before, loc, call, after := findFirstTopLevelSuperCall(comma.Left, superCtorRef); call != nil {\n\t\t\treturn before, loc, call, js_ast.JoinWithComma(after, comma.Right)\n\t\t}\n\n\t\tif before, loc, call, after := findFirstTopLevelSuperCall(comma.Right, superCtorRef); call != nil {\n\t\t\treturn js_ast.JoinWithComma(comma.Left, before), loc, call, after\n\t\t}\n\t}\n\n\treturn js_ast.Expr{}, logger.Loc{}, nil, js_ast.Expr{}\n}\n"
  },
  {
    "path": "internal/js_parser/js_parser_lower_test.go",
    "content": "package js_parser\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/compat\"\n)\n\nfunc TestLowerFunctionArgumentScope(t *testing.T) {\n\ttemplates := []string{\n\t\t\"(x = %s) => {\\n};\\n\",\n\t\t\"(function(x = %s) {\\n});\\n\",\n\t\t\"function foo(x = %s) {\\n}\\n\",\n\n\t\t\"({ [%s]: x }) => {\\n};\\n\",\n\t\t\"(function({ [%s]: x }) {\\n});\\n\",\n\t\t\"function foo({ [%s]: x }) {\\n}\\n\",\n\n\t\t\"({ x = %s }) => {\\n};\\n\",\n\t\t\"(function({ x = %s }) {\\n});\\n\",\n\t\t\"function foo({ x = %s }) {\\n}\\n\",\n\t}\n\n\tfor _, template := range templates {\n\t\ttest := func(before string, after string) {\n\t\t\texpectPrintedTarget(t, 2015, fmt.Sprintf(template, before), fmt.Sprintf(template, after))\n\t\t}\n\n\t\ttest(\"a() ?? b\", \"((_a) => (_a = a()) != null ? _a : b)()\")\n\t\ttest(\"a()?.b\", \"((_a) => (_a = a()) == null ? void 0 : _a.b)()\")\n\t\ttest(\"a?.b?.()\", \"((_a) => (_a = a == null ? void 0 : a.b) == null ? void 0 : _a.call(a))()\")\n\t\ttest(\"a.b.c?.()\", \"((_a) => ((_b) => (_b = (_a = a.b).c) == null ? void 0 : _b.call(_a))())()\")\n\t\ttest(\"class { static a }\", \"((_a) => (_a = class {\\n}, __publicField(_a, \\\"a\\\"), _a))()\")\n\t}\n}\n\nfunc TestLowerArrowFunction(t *testing.T) {\n\texpectPrintedTarget(t, 5, \"function foo(a) { arr.forEach(e => this.foo(e)) }\",\n\t\t\"function foo(a) {\\n  var _this = this;\\n  arr.forEach(function(e) {\\n    return _this.foo(e);\\n  });\\n}\\n\")\n\texpectPrintedTarget(t, 5, \"function foo(a) { return () => arguments[0] }\",\n\t\t\"function foo(a) {\\n  var _arguments = arguments;\\n  return function() {\\n    return _arguments[0];\\n  };\\n}\\n\")\n\n\texpectPrintedTarget(t, 5, \"function foo(a) { arr.forEach(function(e) { return this.foo(e) }) }\",\n\t\t\"function foo(a) {\\n  arr.forEach(function(e) {\\n    return this.foo(e);\\n  });\\n}\\n\")\n\texpectPrintedTarget(t, 5, \"function foo(a) { return function() { return arguments[0] } }\",\n\t\t\"function foo(a) {\\n  return function() {\\n    return arguments[0];\\n  };\\n}\\n\")\n\n\t// Handling this case isn't implemented yet\n\texpectPrintedTarget(t, 5, \"var foo = () => this\",\n\t\t\"var foo = function() {\\n  return this;\\n};\\n\")\n}\n\nfunc TestLowerNullishCoalescing(t *testing.T) {\n\texpectParseError(t, \"a ?? b && c\",\n\t\t\"<stdin>: ERROR: Cannot use \\\"&&\\\" with \\\"??\\\" without parentheses\\n\"+\n\t\t\t\"NOTE: Expressions of the form \\\"x ?? y && z\\\" are not allowed in JavaScript. \"+\n\t\t\t\"You must disambiguate between \\\"(x ?? y) && z\\\" and \\\"x ?? (y && z)\\\" by adding parentheses.\\n\")\n\texpectParseError(t, \"a ?? b || c\",\n\t\t\"<stdin>: ERROR: Cannot use \\\"||\\\" with \\\"??\\\" without parentheses\\n\"+\n\t\t\t\"NOTE: Expressions of the form \\\"x ?? y || z\\\" are not allowed in JavaScript. \"+\n\t\t\t\"You must disambiguate between \\\"(x ?? y) || z\\\" and \\\"x ?? (y || z)\\\" by adding parentheses.\\n\")\n\texpectParseError(t, \"a ?? b && c || d\",\n\t\t\"<stdin>: ERROR: Cannot use \\\"&&\\\" with \\\"??\\\" without parentheses\\n\"+\n\t\t\t\"NOTE: Expressions of the form \\\"x ?? y && z\\\" are not allowed in JavaScript. \"+\n\t\t\t\"You must disambiguate between \\\"(x ?? y) && z\\\" and \\\"x ?? (y && z)\\\" by adding parentheses.\\n\"+\n\t\t\t\"<stdin>: ERROR: Cannot use \\\"||\\\" with \\\"??\\\" without parentheses\\n\"+\n\t\t\t\"NOTE: Expressions of the form \\\"x ?? y || z\\\" are not allowed in JavaScript. \"+\n\t\t\t\"You must disambiguate between \\\"(x ?? y) || z\\\" and \\\"x ?? (y || z)\\\" by adding parentheses.\\n\")\n\texpectParseError(t, \"a ?? b || c && d\",\n\t\t\"<stdin>: ERROR: Cannot use \\\"||\\\" with \\\"??\\\" without parentheses\\n\"+\n\t\t\t\"NOTE: Expressions of the form \\\"x ?? y || z\\\" are not allowed in JavaScript. \"+\n\t\t\t\"You must disambiguate between \\\"(x ?? y) || z\\\" and \\\"x ?? (y || z)\\\" by adding parentheses.\\n\")\n\texpectParseError(t, \"a && b ?? c\",\n\t\t\"<stdin>: ERROR: Cannot use \\\"??\\\" with \\\"&&\\\" without parentheses\\n\"+\n\t\t\t\"NOTE: Expressions of the form \\\"x && y ?? z\\\" are not allowed in JavaScript. \"+\n\t\t\t\"You must disambiguate between \\\"(x && y) ?? z\\\" and \\\"x && (y ?? z)\\\" by adding parentheses.\\n\")\n\texpectParseError(t, \"a || b ?? c\",\n\t\t\"<stdin>: ERROR: Cannot use \\\"??\\\" with \\\"||\\\" without parentheses\\n\"+\n\t\t\t\"NOTE: Expressions of the form \\\"x || y ?? z\\\" are not allowed in JavaScript. \"+\n\t\t\t\"You must disambiguate between \\\"(x || y) ?? z\\\" and \\\"x || (y ?? z)\\\" by adding parentheses.\\n\")\n\texpectParseError(t, \"a && b || c ?? c\",\n\t\t\"<stdin>: ERROR: Cannot use \\\"??\\\" with \\\"||\\\" without parentheses\\n\"+\n\t\t\t\"NOTE: Expressions of the form \\\"x || y ?? z\\\" are not allowed in JavaScript. \"+\n\t\t\t\"You must disambiguate between \\\"(x || y) ?? z\\\" and \\\"x || (y ?? z)\\\" by adding parentheses.\\n\")\n\texpectParseError(t, \"a || b && c ?? d\",\n\t\t\"<stdin>: ERROR: Cannot use \\\"??\\\" with \\\"||\\\" without parentheses\\n\"+\n\t\t\t\"NOTE: Expressions of the form \\\"x || y ?? z\\\" are not allowed in JavaScript. \"+\n\t\t\t\"You must disambiguate between \\\"(x || y) ?? z\\\" and \\\"x || (y ?? z)\\\" by adding parentheses.\\n\")\n\texpectPrinted(t, \"a ?? b, b && c\", \"a ?? b, b && c;\\n\")\n\texpectPrinted(t, \"a ?? b, b || c\", \"a ?? b, b || c;\\n\")\n\texpectPrinted(t, \"a && b, b ?? c\", \"a && b, b ?? c;\\n\")\n\texpectPrinted(t, \"a || b, b ?? c\", \"a || b, b ?? c;\\n\")\n\n\texpectPrintedTarget(t, 2020, \"a ?? b\", \"a ?? b;\\n\")\n\texpectPrintedTarget(t, 2019, \"a ?? b\", \"a != null ? a : b;\\n\")\n\texpectPrintedTarget(t, 2019, \"a() ?? b()\", \"var _a;\\n(_a = a()) != null ? _a : b();\\n\")\n\texpectPrintedTarget(t, 2019, \"function foo() { if (x) { a() ?? b() ?? c() } }\",\n\t\t\"function foo() {\\n  var _a, _b;\\n  if (x) {\\n    (_b = (_a = a()) != null ? _a : b()) != null ? _b : c();\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2019, \"() => a ?? b\", \"() => a != null ? a : b;\\n\")\n\texpectPrintedTarget(t, 2019, \"() => a() ?? b()\", \"() => {\\n  var _a;\\n  return (_a = a()) != null ? _a : b();\\n};\\n\")\n\n\t// Temporary variables should not come before \"use strict\"\n\texpectPrintedTarget(t, 2019, \"function f() { /*! @license */ 'use strict'; a = b.c ?? d }\",\n\t\t\"function f() {\\n  /*! @license */\\n  \\\"use strict\\\";\\n  var _a;\\n  a = (_a = b.c) != null ? _a : d;\\n}\\n\")\n}\n\nfunc TestLowerNullishCoalescingAssign(t *testing.T) {\n\texpectPrinted(t, \"a ??= b\", \"a ??= b;\\n\")\n\n\texpectPrintedTarget(t, 2019, \"a ??= b\", \"a != null ? a : a = b;\\n\")\n\texpectPrintedTarget(t, 2019, \"a.b ??= c\", \"var _a;\\n(_a = a.b) != null ? _a : a.b = c;\\n\")\n\texpectPrintedTarget(t, 2019, \"a().b ??= c\", \"var _a, _b;\\n(_b = (_a = a()).b) != null ? _b : _a.b = c;\\n\")\n\texpectPrintedTarget(t, 2019, \"a[b] ??= c\", \"var _a;\\n(_a = a[b]) != null ? _a : a[b] = c;\\n\")\n\texpectPrintedTarget(t, 2019, \"a()[b()] ??= c\", \"var _a, _b, _c;\\n(_c = (_a = a())[_b = b()]) != null ? _c : _a[_b] = c;\\n\")\n\n\texpectPrintedTarget(t, 2019, \"class Foo { #x; constructor() { this.#x ??= 2 } }\", `var _x;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x);\n    var _a;\n    (_a = __privateGet(this, _x)) != null ? _a : __privateSet(this, _x, 2);\n  }\n}\n_x = new WeakMap();\n`)\n\n\texpectPrintedTarget(t, 2020, \"a ??= b\", \"a ?? (a = b);\\n\")\n\texpectPrintedTarget(t, 2020, \"a.b ??= c\", \"a.b ?? (a.b = c);\\n\")\n\texpectPrintedTarget(t, 2020, \"a().b ??= c\", \"var _a;\\n(_a = a()).b ?? (_a.b = c);\\n\")\n\texpectPrintedTarget(t, 2020, \"a[b] ??= c\", \"a[b] ?? (a[b] = c);\\n\")\n\texpectPrintedTarget(t, 2020, \"a()[b()] ??= c\", \"var _a, _b;\\n(_a = a())[_b = b()] ?? (_a[_b] = c);\\n\")\n\n\texpectPrintedTarget(t, 2020, \"class Foo { #x; constructor() { this.#x ??= 2 } }\", `var _x;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x);\n    __privateGet(this, _x) ?? __privateSet(this, _x, 2);\n  }\n}\n_x = new WeakMap();\n`)\n\n\texpectPrintedTarget(t, 2021, \"a ??= b\", \"a ??= b;\\n\")\n\texpectPrintedTarget(t, 2021, \"a.b ??= c\", \"a.b ??= c;\\n\")\n\texpectPrintedTarget(t, 2021, \"a().b ??= c\", \"a().b ??= c;\\n\")\n\texpectPrintedTarget(t, 2021, \"a[b] ??= c\", \"a[b] ??= c;\\n\")\n\texpectPrintedTarget(t, 2021, \"a()[b()] ??= c\", \"a()[b()] ??= c;\\n\")\n\n\texpectPrintedTarget(t, 2021, \"class Foo { #x; constructor() { this.#x ??= 2 } }\", `var _x;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x);\n    __privateGet(this, _x) ?? __privateSet(this, _x, 2);\n  }\n}\n_x = new WeakMap();\n`)\n\n\t// Temporary variables should not come before \"use strict\"\n\texpectPrintedTarget(t, 2019, \"function f() { /*! @license */ 'use strict'; a.b ??= c.d }\",\n\t\t\"function f() {\\n  /*! @license */\\n  \\\"use strict\\\";\\n  var _a;\\n  (_a = a.b) != null ? _a : a.b = c.d;\\n}\\n\")\n}\n\nfunc TestLowerLogicalAssign(t *testing.T) {\n\texpectPrinted(t, \"a &&= b\", \"a &&= b;\\n\")\n\texpectPrinted(t, \"a ||= b\", \"a ||= b;\\n\")\n\n\texpectPrintedTarget(t, 2020, \"a &&= b\", \"a && (a = b);\\n\")\n\texpectPrintedTarget(t, 2020, \"a.b &&= c\", \"a.b && (a.b = c);\\n\")\n\texpectPrintedTarget(t, 2020, \"a().b &&= c\", \"var _a;\\n(_a = a()).b && (_a.b = c);\\n\")\n\texpectPrintedTarget(t, 2020, \"a[b] &&= c\", \"a[b] && (a[b] = c);\\n\")\n\texpectPrintedTarget(t, 2020, \"a()[b()] &&= c\", \"var _a, _b;\\n(_a = a())[_b = b()] && (_a[_b] = c);\\n\")\n\n\texpectPrintedTarget(t, 2020, \"class Foo { #x; constructor() { this.#x &&= 2 } }\", `var _x;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x);\n    __privateGet(this, _x) && __privateSet(this, _x, 2);\n  }\n}\n_x = new WeakMap();\n`)\n\n\texpectPrintedTarget(t, 2021, \"a &&= b\", \"a &&= b;\\n\")\n\texpectPrintedTarget(t, 2021, \"a.b &&= c\", \"a.b &&= c;\\n\")\n\texpectPrintedTarget(t, 2021, \"a().b &&= c\", \"a().b &&= c;\\n\")\n\texpectPrintedTarget(t, 2021, \"a[b] &&= c\", \"a[b] &&= c;\\n\")\n\texpectPrintedTarget(t, 2021, \"a()[b()] &&= c\", \"a()[b()] &&= c;\\n\")\n\n\texpectPrintedTarget(t, 2021, \"class Foo { #x; constructor() { this.#x &&= 2 } }\", `var _x;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x);\n    __privateGet(this, _x) && __privateSet(this, _x, 2);\n  }\n}\n_x = new WeakMap();\n`)\n\n\texpectPrintedTarget(t, 2020, \"a ||= b\", \"a || (a = b);\\n\")\n\texpectPrintedTarget(t, 2020, \"a.b ||= c\", \"a.b || (a.b = c);\\n\")\n\texpectPrintedTarget(t, 2020, \"a().b ||= c\", \"var _a;\\n(_a = a()).b || (_a.b = c);\\n\")\n\texpectPrintedTarget(t, 2020, \"a[b] ||= c\", \"a[b] || (a[b] = c);\\n\")\n\texpectPrintedTarget(t, 2020, \"a()[b()] ||= c\", \"var _a, _b;\\n(_a = a())[_b = b()] || (_a[_b] = c);\\n\")\n\n\texpectPrintedTarget(t, 2020, \"class Foo { #x; constructor() { this.#x ||= 2 } }\", `var _x;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x);\n    __privateGet(this, _x) || __privateSet(this, _x, 2);\n  }\n}\n_x = new WeakMap();\n`)\n\n\texpectPrintedTarget(t, 2021, \"a ||= b\", \"a ||= b;\\n\")\n\texpectPrintedTarget(t, 2021, \"a.b ||= c\", \"a.b ||= c;\\n\")\n\texpectPrintedTarget(t, 2021, \"a().b ||= c\", \"a().b ||= c;\\n\")\n\texpectPrintedTarget(t, 2021, \"a[b] ||= c\", \"a[b] ||= c;\\n\")\n\texpectPrintedTarget(t, 2021, \"a()[b()] ||= c\", \"a()[b()] ||= c;\\n\")\n\n\texpectPrintedTarget(t, 2021, \"class Foo { #x; constructor() { this.#x ||= 2 } }\", `var _x;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x);\n    __privateGet(this, _x) || __privateSet(this, _x, 2);\n  }\n}\n_x = new WeakMap();\n`)\n}\n\nfunc TestLowerAsyncFunctions(t *testing.T) {\n\t// Lowered non-arrow functions with argument evaluations should merely use\n\t// \"arguments\" rather than allocating a new array when forwarding arguments\n\texpectPrintedTarget(t, 2015, \"async function foo(a, b = couldThrowErrors()) {console.log(a, b);}\", `function foo(_0) {\n  return __async(this, arguments, function* (a, b = couldThrowErrors()) {\n    console.log(a, b);\n  });\n}\n`)\n\t// Skip forwarding altogether when parameter evaluation obviously cannot throw\n\texpectPrintedTarget(t, 2015, \"async (a, b = 123) => {console.log(a, b);}\", `(a, b = 123) => __async(null, null, function* () {\n  console.log(a, b);\n});\n`)\n}\n\nfunc TestLowerClassSideEffectOrder(t *testing.T) {\n\t// The order of computed property side effects must not change\n\texpectPrintedTarget(t, 2015, `class Foo {\n\t[a()]() {}\n\t[b()];\n\t[c()] = 1;\n\t[d()]() {}\n\tstatic [e()];\n\tstatic [f()] = 1;\n\tstatic [g()]() {}\n\t[h()];\n}\n`, `var _a, _b, _c, _d, _e, _f;\nclass Foo {\n  constructor() {\n    __publicField(this, _f);\n    __publicField(this, _e, 1);\n    __publicField(this, _a);\n  }\n  [a()]() {\n  }\n  [(_f = b(), _e = c(), d())]() {\n  }\n  static [(_d = e(), _c = f(), _b = g(), _a = h(), _b)]() {\n  }\n}\n__publicField(Foo, _d);\n__publicField(Foo, _c, 1);\n`)\n}\n\nfunc TestLowerClassInstance(t *testing.T) {\n\texpectPrintedTarget(t, 2015, \"class Foo {}\", \"class Foo {\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { foo }\", \"class Foo {\\n  constructor() {\\n    __publicField(this, \\\"foo\\\");\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { foo = null }\", \"class Foo {\\n  constructor() {\\n    __publicField(this, \\\"foo\\\", null);\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { 123 }\", \"class Foo {\\n  constructor() {\\n    __publicField(this, 123);\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { 123 = null }\", \"class Foo {\\n  constructor() {\\n    __publicField(this, 123, null);\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { [foo] }\", \"var _a;\\n_a = foo;\\nclass Foo {\\n  constructor() {\\n    __publicField(this, _a);\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { [foo] = null }\", \"var _a;\\n_a = foo;\\nclass Foo {\\n  constructor() {\\n    __publicField(this, _a, null);\\n  }\\n}\\n\")\n\n\texpectPrintedTarget(t, 2015, \"(class {})\", \"(class {\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { foo })\", \"(class {\\n  constructor() {\\n    __publicField(this, \\\"foo\\\");\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { foo = null })\", \"(class {\\n  constructor() {\\n    __publicField(this, \\\"foo\\\", null);\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { 123 })\", \"(class {\\n  constructor() {\\n    __publicField(this, 123);\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { 123 = null })\", \"(class {\\n  constructor() {\\n    __publicField(this, 123, null);\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { [foo] })\", \"var _a;\\n_a = foo, class {\\n  constructor() {\\n    __publicField(this, _a);\\n  }\\n};\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { [foo] = null })\", \"var _a;\\n_a = foo, class {\\n  constructor() {\\n    __publicField(this, _a, null);\\n  }\\n};\\n\")\n\n\texpectPrintedTarget(t, 2015, \"class Foo extends Bar {}\", `class Foo extends Bar {\n}\n`)\n\texpectPrintedTarget(t, 2015, \"class Foo extends Bar { bar() {} constructor() { super() } }\", `class Foo extends Bar {\n  bar() {\n  }\n  constructor() {\n    super();\n  }\n}\n`)\n\texpectPrintedTarget(t, 2015, \"class Foo extends Bar { bar() {} foo }\", `class Foo extends Bar {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"foo\");\n  }\n  bar() {\n  }\n}\n`)\n\texpectPrintedTarget(t, 2015, \"class Foo extends Bar { bar() {} foo; constructor() { super() } }\", `class Foo extends Bar {\n  constructor() {\n    super();\n    __publicField(this, \"foo\");\n  }\n  bar() {\n  }\n}\n`)\n\texpectPrintedTarget(t, 2015, \"class Foo extends Bar { bar() {} foo; constructor({ ...args }) { super() } }\", `class Foo extends Bar {\n  constructor(_a) {\n    var args = __objRest(_a, []);\n    super();\n    __publicField(this, \"foo\");\n  }\n  bar() {\n  }\n}\n`)\n}\n\nfunc TestLowerClassStatic(t *testing.T) {\n\texpectPrintedTarget(t, 2015, \"class Foo { static foo }\", \"class Foo {\\n}\\n__publicField(Foo, \\\"foo\\\");\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static foo = null }\", \"class Foo {\\n}\\n__publicField(Foo, \\\"foo\\\", null);\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static foo(a, b) {} }\", \"class Foo {\\n  static foo(a, b) {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static get foo() {} }\", \"class Foo {\\n  static get foo() {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static set foo(a) {} }\", \"class Foo {\\n  static set foo(a) {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static 123 }\", \"class Foo {\\n}\\n__publicField(Foo, 123);\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static 123 = null }\", \"class Foo {\\n}\\n__publicField(Foo, 123, null);\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static 123(a, b) {} }\", \"class Foo {\\n  static 123(a, b) {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static get 123() {} }\", \"class Foo {\\n  static get 123() {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static set 123(a) {} }\", \"class Foo {\\n  static set 123(a) {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static [foo] }\", \"var _a;\\n_a = foo;\\nclass Foo {\\n}\\n__publicField(Foo, _a);\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static [foo] = null }\", \"var _a;\\n_a = foo;\\nclass Foo {\\n}\\n__publicField(Foo, _a, null);\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static [foo](a, b) {} }\", \"class Foo {\\n  static [foo](a, b) {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static get [foo]() {} }\", \"class Foo {\\n  static get [foo]() {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static set [foo](a) {} }\", \"class Foo {\\n  static set [foo](a) {\\n  }\\n}\\n\")\n\n\texpectPrintedTarget(t, 2015, \"export default class Foo { static foo }\", \"export default class Foo {\\n}\\n__publicField(Foo, \\\"foo\\\");\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class Foo { static foo = null }\", \"export default class Foo {\\n}\\n__publicField(Foo, \\\"foo\\\", null);\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class Foo { static foo(a, b) {} }\", \"export default class Foo {\\n  static foo(a, b) {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class Foo { static get foo() {} }\", \"export default class Foo {\\n  static get foo() {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class Foo { static set foo(a) {} }\", \"export default class Foo {\\n  static set foo(a) {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class Foo { static 123 }\", \"export default class Foo {\\n}\\n__publicField(Foo, 123);\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class Foo { static 123 = null }\", \"export default class Foo {\\n}\\n__publicField(Foo, 123, null);\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class Foo { static 123(a, b) {} }\", \"export default class Foo {\\n  static 123(a, b) {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class Foo { static get 123() {} }\", \"export default class Foo {\\n  static get 123() {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class Foo { static set 123(a) {} }\", \"export default class Foo {\\n  static set 123(a) {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class Foo { static [foo] }\", \"var _a;\\n_a = foo;\\nexport default class Foo {\\n}\\n__publicField(Foo, _a);\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class Foo { static [foo] = null }\", \"var _a;\\n_a = foo;\\nexport default class Foo {\\n}\\n__publicField(Foo, _a, null);\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class Foo { static [foo](a, b) {} }\", \"export default class Foo {\\n  static [foo](a, b) {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class Foo { static get [foo]() {} }\", \"export default class Foo {\\n  static get [foo]() {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class Foo { static set [foo](a) {} }\", \"export default class Foo {\\n  static set [foo](a) {\\n  }\\n}\\n\")\n\n\texpectPrintedTarget(t, 2015, \"export default class { static foo }\",\n\t\t\"export default class stdin_default {\\n}\\n__publicField(stdin_default, \\\"foo\\\");\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class { static foo = null }\",\n\t\t\"export default class stdin_default {\\n}\\n__publicField(stdin_default, \\\"foo\\\", null);\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class { static foo(a, b) {} }\", \"export default class {\\n  static foo(a, b) {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class { static get foo() {} }\", \"export default class {\\n  static get foo() {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class { static set foo(a) {} }\", \"export default class {\\n  static set foo(a) {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class { static 123 }\",\n\t\t\"export default class stdin_default {\\n}\\n__publicField(stdin_default, 123);\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class { static 123 = null }\",\n\t\t\"export default class stdin_default {\\n}\\n__publicField(stdin_default, 123, null);\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class { static 123(a, b) {} }\", \"export default class {\\n  static 123(a, b) {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class { static get 123() {} }\", \"export default class {\\n  static get 123() {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class { static set 123(a) {} }\", \"export default class {\\n  static set 123(a) {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class { static [foo] }\",\n\t\t\"var _a;\\n_a = foo;\\nexport default class stdin_default {\\n}\\n__publicField(stdin_default, _a);\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class { static [foo] = null }\",\n\t\t\"var _a;\\n_a = foo;\\nexport default class stdin_default {\\n}\\n__publicField(stdin_default, _a, null);\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class { static [foo](a, b) {} }\", \"export default class {\\n  static [foo](a, b) {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class { static get [foo]() {} }\", \"export default class {\\n  static get [foo]() {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"export default class { static set [foo](a) {} }\", \"export default class {\\n  static set [foo](a) {\\n  }\\n}\\n\")\n\n\texpectPrintedTarget(t, 2015, \"(class Foo { static foo })\", \"var _a;\\n_a = class {\\n}, __publicField(_a, \\\"foo\\\"), _a;\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static foo = null })\", \"var _a;\\n_a = class {\\n}, __publicField(_a, \\\"foo\\\", null), _a;\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static foo(a, b) {} })\", \"(class Foo {\\n  static foo(a, b) {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static get foo() {} })\", \"(class Foo {\\n  static get foo() {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static set foo(a) {} })\", \"(class Foo {\\n  static set foo(a) {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static 123 })\", \"var _a;\\n_a = class {\\n}, __publicField(_a, 123), _a;\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static 123 = null })\", \"var _a;\\n_a = class {\\n}, __publicField(_a, 123, null), _a;\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static 123(a, b) {} })\", \"(class Foo {\\n  static 123(a, b) {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static get 123() {} })\", \"(class Foo {\\n  static get 123() {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static set 123(a) {} })\", \"(class Foo {\\n  static set 123(a) {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static [foo] })\", \"var _a, _b;\\n_a = foo, _b = class {\\n}, __publicField(_b, _a), _b;\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static [foo] = null })\", \"var _a, _b;\\n_a = foo, _b = class {\\n}, __publicField(_b, _a, null), _b;\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static [foo](a, b) {} })\", \"(class Foo {\\n  static [foo](a, b) {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static get [foo]() {} })\", \"(class Foo {\\n  static get [foo]() {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static set [foo](a) {} })\", \"(class Foo {\\n  static set [foo](a) {\\n  }\\n});\\n\")\n\n\texpectPrintedTarget(t, 2015, \"(class { static foo })\", \"var _a;\\n_a = class {\\n}, __publicField(_a, \\\"foo\\\"), _a;\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { static foo = null })\", \"var _a;\\n_a = class {\\n}, __publicField(_a, \\\"foo\\\", null), _a;\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { static foo(a, b) {} })\", \"(class {\\n  static foo(a, b) {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { static get foo() {} })\", \"(class {\\n  static get foo() {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { static set foo(a) {} })\", \"(class {\\n  static set foo(a) {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { static 123 })\", \"var _a;\\n_a = class {\\n}, __publicField(_a, 123), _a;\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { static 123 = null })\", \"var _a;\\n_a = class {\\n}, __publicField(_a, 123, null), _a;\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { static 123(a, b) {} })\", \"(class {\\n  static 123(a, b) {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { static get 123() {} })\", \"(class {\\n  static get 123() {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { static set 123(a) {} })\", \"(class {\\n  static set 123(a) {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { static [foo] })\", \"var _a, _b;\\n_a = foo, _b = class {\\n}, __publicField(_b, _a), _b;\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { static [foo] = null })\", \"var _a, _b;\\n_a = foo, _b = class {\\n}, __publicField(_b, _a, null), _b;\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { static [foo](a, b) {} })\", \"(class {\\n  static [foo](a, b) {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { static get [foo]() {} })\", \"(class {\\n  static get [foo]() {\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"(class { static set [foo](a) {} })\", \"(class {\\n  static set [foo](a) {\\n  }\\n});\\n\")\n\n\texpectPrintedTarget(t, 2015, \"(class {})\", \"(class {\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo {}\", \"class Foo {\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo {})\", \"(class Foo {\\n});\\n\")\n\n\t// Static field with initializers that access the class expression name must\n\t// still work when they are pulled outside of the class body\n\texpectPrintedTarget(t, 2015, `\n\t\tlet Bar = class Foo {\n\t\t\tstatic foo = 123\n\t\t\tstatic bar = Foo.foo\n\t\t}\n\t`, `var _a;\nlet Bar = (_a = class {\n}, __publicField(_a, \"foo\", 123), __publicField(_a, \"bar\", _a.foo), _a);\n`)\n\n\t// Generated IIFEs for static class blocks should be appropriately annotated\n\texpectPrintedTarget(t, 2015, \"class Foo { static { try {} finally { impureCall() } } }\",\n\t\t\"class Foo {\\n}\\n(() => {\\n  try {\\n  } finally {\\n    impureCall();\\n  }\\n})();\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static { try {} finally { impureCall() } } })\",\n\t\t\"var _a;\\n_a = class {\\n}, (() => {\\n  try {\\n  } finally {\\n    impureCall();\\n  }\\n})(), _a;\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static { try {} finally { /* @__PURE__ */ pureCall() } } }\",\n\t\t\"class Foo {\\n}\\n/* @__PURE__ */ (() => {\\n  try {\\n  } finally {\\n    /* @__PURE__ */ pureCall();\\n  }\\n})();\\n\")\n\texpectPrintedTarget(t, 2015, \"(class Foo { static { try {} finally { /* @__PURE__ */ pureCall() } } })\",\n\t\t\"var _a;\\n_a = class {\\n}, /* @__PURE__ */ (() => {\\n  try {\\n  } finally {\\n    /* @__PURE__ */ pureCall();\\n  }\\n})(), _a;\\n\")\n}\n\nfunc TestLowerClassStaticThis(t *testing.T) {\n\texpectPrinted(t, \"class Foo { x = this }\", \"class Foo {\\n  x = this;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static x = this }\", \"class Foo {\\n  static x = this;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static x = () => this }\", \"class Foo {\\n  static x = () => this;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static x = function() { return this } }\", \"class Foo {\\n  static x = function() {\\n    return this;\\n  };\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static [this.x] }\", \"class Foo {\\n  static [this.x];\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static x = class { y = this } }\", \"class Foo {\\n  static x = class {\\n    y = this;\\n  };\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static x = class { [this.y] } }\", \"class Foo {\\n  static x = class {\\n    [this.y];\\n  };\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static x = class extends this {} }\", \"class Foo {\\n  static x = class extends this {\\n  };\\n}\\n\")\n\n\texpectPrinted(t, \"x = class Foo { x = this }\", \"x = class Foo {\\n  x = this;\\n};\\n\")\n\texpectPrinted(t, \"x = class Foo { static x = this }\", \"x = class Foo {\\n  static x = this;\\n};\\n\")\n\texpectPrinted(t, \"x = class Foo { static x = () => this }\", \"x = class Foo {\\n  static x = () => this;\\n};\\n\")\n\texpectPrinted(t, \"x = class Foo { static x = function() { return this } }\", \"x = class Foo {\\n  static x = function() {\\n    return this;\\n  };\\n};\\n\")\n\texpectPrinted(t, \"x = class Foo { static [this.x] }\", \"x = class Foo {\\n  static [this.x];\\n};\\n\")\n\texpectPrinted(t, \"x = class Foo { static x = class { y = this } }\", \"x = class Foo {\\n  static x = class {\\n    y = this;\\n  };\\n};\\n\")\n\texpectPrinted(t, \"x = class Foo { static x = class { [this.y] } }\", \"x = class Foo {\\n  static x = class {\\n    [this.y];\\n  };\\n};\\n\")\n\texpectPrinted(t, \"x = class Foo { static x = class extends this {} }\", \"x = class Foo {\\n  static x = class extends this {\\n  };\\n};\\n\")\n\n\texpectPrinted(t, \"x = class { x = this }\", \"x = class {\\n  x = this;\\n};\\n\")\n\texpectPrinted(t, \"x = class { static x = this }\", \"x = class {\\n  static x = this;\\n};\\n\")\n\texpectPrinted(t, \"x = class { static x = () => this }\", \"x = class {\\n  static x = () => this;\\n};\\n\")\n\texpectPrinted(t, \"x = class { static x = function() { return this } }\", \"x = class {\\n  static x = function() {\\n    return this;\\n  };\\n};\\n\")\n\texpectPrinted(t, \"x = class { static [this.x] }\", \"x = class {\\n  static [this.x];\\n};\\n\")\n\texpectPrinted(t, \"x = class { static x = class { y = this } }\", \"x = class {\\n  static x = class {\\n    y = this;\\n  };\\n};\\n\")\n\texpectPrinted(t, \"x = class { static x = class { [this.y] } }\", \"x = class {\\n  static x = class {\\n    [this.y];\\n  };\\n};\\n\")\n\texpectPrinted(t, \"x = class { static x = class extends this {} }\", \"x = class {\\n  static x = class extends this {\\n  };\\n};\\n\")\n\n\texpectPrintedTarget(t, 2015, \"class Foo { x = this }\",\n\t\t\"class Foo {\\n  constructor() {\\n    __publicField(this, \\\"x\\\", this);\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { [this.x] }\",\n\t\t\"var _a;\\n_a = this.x;\\nclass Foo {\\n  constructor() {\\n    __publicField(this, _a);\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static x = this }\",\n\t\t\"const _Foo = class _Foo {\\n};\\n__publicField(_Foo, \\\"x\\\", _Foo);\\nlet Foo = _Foo;\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static x = () => this }\",\n\t\t\"const _Foo = class _Foo {\\n};\\n__publicField(_Foo, \\\"x\\\", () => _Foo);\\nlet Foo = _Foo;\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static x = function() { return this } }\",\n\t\t\"class Foo {\\n}\\n__publicField(Foo, \\\"x\\\", function() {\\n  return this;\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static [this.x] }\",\n\t\t\"var _a;\\n_a = this.x;\\nclass Foo {\\n}\\n__publicField(Foo, _a);\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static x = class { y = this } }\",\n\t\t\"class Foo {\\n}\\n__publicField(Foo, \\\"x\\\", class {\\n  constructor() {\\n    __publicField(this, \\\"y\\\", this);\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static x = class { [this.y] } }\",\n\t\t\"var _a;\\nconst _Foo = class _Foo {\\n};\\n__publicField(_Foo, \\\"x\\\", (_a = _Foo.y, class {\\n  constructor() {\\n    __publicField(this, _a);\\n  }\\n}));\\nlet Foo = _Foo;\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static x = class extends this {} }\",\n\t\t\"const _Foo = class _Foo {\\n};\\n__publicField(_Foo, \\\"x\\\", class extends _Foo {\\n});\\nlet Foo = _Foo;\\n\")\n\n\texpectPrintedTarget(t, 2015, \"x = class Foo { x = this }\",\n\t\t\"x = class Foo {\\n  constructor() {\\n    __publicField(this, \\\"x\\\", this);\\n  }\\n};\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class Foo { [this.x] }\",\n\t\t\"var _a;\\nx = (_a = this.x, class Foo {\\n  constructor() {\\n    __publicField(this, _a);\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class Foo { static x = this }\",\n\t\t\"var _a;\\nx = (_a = class {\\n}, __publicField(_a, \\\"x\\\", _a), _a);\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class Foo { static x = () => this }\",\n\t\t\"var _a;\\nx = (_a = class {\\n}, __publicField(_a, \\\"x\\\", () => _a), _a);\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class Foo { static x = function() { return this } }\",\n\t\t\"var _a;\\nx = (_a = class {\\n}, __publicField(_a, \\\"x\\\", function() {\\n  return this;\\n}), _a);\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class Foo { static [this.x] }\",\n\t\t\"var _a, _b;\\nx = (_a = this.x, _b = class {\\n}, __publicField(_b, _a), _b);\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class Foo { static x = class { y = this } }\",\n\t\t\"var _a;\\nx = (_a = class {\\n}, __publicField(_a, \\\"x\\\", class {\\n  constructor() {\\n    __publicField(this, \\\"y\\\", this);\\n  }\\n}), _a);\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class Foo { static x = class { [this.y] } }\",\n\t\t\"var _a, _b;\\nx = (_b = class {\\n}, __publicField(_b, \\\"x\\\", (_a = _b.y, class {\\n  constructor() {\\n    __publicField(this, _a);\\n  }\\n})), _b);\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class Foo { static x = class extends this {} }\",\n\t\t\"var _a;\\nx = (_a = class {\\n}, __publicField(_a, \\\"x\\\", class extends _a {\\n}), _a);\\n\")\n\n\texpectPrintedTarget(t, 2015, \"x = class { x = this }\",\n\t\t\"x = class {\\n  constructor() {\\n    __publicField(this, \\\"x\\\", this);\\n  }\\n};\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class { [this.x] }\",\n\t\t\"var _a;\\nx = (_a = this.x, class {\\n  constructor() {\\n    __publicField(this, _a);\\n  }\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class { static x = this }\",\n\t\t\"var _a;\\nx = (_a = class {\\n}, __publicField(_a, \\\"x\\\", _a), _a);\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class { static x = () => this }\",\n\t\t\"var _a;\\nx = (_a = class {\\n}, __publicField(_a, \\\"x\\\", () => _a), _a);\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class { static x = function() { return this } }\",\n\t\t\"var _a;\\nx = (_a = class {\\n}, __publicField(_a, \\\"x\\\", function() {\\n  return this;\\n}), _a);\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class { static [this.x] }\",\n\t\t\"var _a, _b;\\nx = (_a = this.x, _b = class {\\n}, __publicField(_b, _a), _b);\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class { static x = class { y = this } }\",\n\t\t\"var _a;\\nx = (_a = class {\\n}, __publicField(_a, \\\"x\\\", class {\\n  constructor() {\\n    __publicField(this, \\\"y\\\", this);\\n  }\\n}), _a);\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class { static x = class { [this.y] } }\",\n\t\t\"var _a, _b;\\nx = (_b = class {\\n}, __publicField(_b, \\\"x\\\", (_a = _b.y, class {\\n  constructor() {\\n    __publicField(this, _a);\\n  }\\n})), _b);\\n\")\n\texpectPrintedTarget(t, 2015, \"x = class Foo { static x = class extends this {} }\",\n\t\t\"var _a;\\nx = (_a = class {\\n}, __publicField(_a, \\\"x\\\", class extends _a {\\n}), _a);\\n\")\n}\n\nfunc TestLowerClassStaticBlocks(t *testing.T) {\n\texpectPrintedTarget(t, 2015, \"class Foo { static {} }\", \"class Foo {\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static {} x() {} }\", \"class Foo {\\n  x() {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { x() {} static {} }\", \"class Foo {\\n  x() {\\n  }\\n}\\n\")\n\texpectPrintedTarget(t, 2015, \"class Foo { static { x } static {} static { y } }\", \"class Foo {\\n}\\nx;\\ny;\\n\")\n\n\texpectPrintedMangleTarget(t, 2015, \"class Foo { static {} }\", \"class Foo {\\n}\\n\")\n\texpectPrintedMangleTarget(t, 2015, \"class Foo { static {} x() {} }\", \"class Foo {\\n  x() {\\n  }\\n}\\n\")\n\texpectPrintedMangleTarget(t, 2015, \"class Foo { x() {} static {} }\", \"class Foo {\\n  x() {\\n  }\\n}\\n\")\n\texpectPrintedMangleTarget(t, 2015, \"class Foo { static { x } static {} static { y } }\", \"class Foo {\\n}\\nx, y;\\n\")\n}\n\nfunc TestLowerOptionalChain(t *testing.T) {\n\texpectPrintedTarget(t, 2019, \"a?.b.c\", \"a == null ? void 0 : a.b.c;\\n\")\n\texpectPrintedTarget(t, 2019, \"(a?.b).c\", \"(a == null ? void 0 : a.b).c;\\n\")\n\texpectPrintedTarget(t, 2019, \"a.b?.c\", \"var _a;\\n(_a = a.b) == null ? void 0 : _a.c;\\n\")\n\texpectPrintedTarget(t, 2019, \"this?.x\", \"this == null ? void 0 : this.x;\\n\")\n\n\texpectPrintedTarget(t, 2019, \"a?.[b][c]\", \"a == null ? void 0 : a[b][c];\\n\")\n\texpectPrintedTarget(t, 2019, \"(a?.[b])[c]\", \"(a == null ? void 0 : a[b])[c];\\n\")\n\texpectPrintedTarget(t, 2019, \"a[b]?.[c]\", \"var _a;\\n(_a = a[b]) == null ? void 0 : _a[c];\\n\")\n\texpectPrintedTarget(t, 2019, \"this?.[x]\", \"this == null ? void 0 : this[x];\\n\")\n\n\texpectPrintedTarget(t, 2019, \"a?.(b)(c)\", \"a == null ? void 0 : a(b)(c);\\n\")\n\texpectPrintedTarget(t, 2019, \"(a?.(b))(c)\", \"(a == null ? void 0 : a(b))(c);\\n\")\n\texpectPrintedTarget(t, 2019, \"a(b)?.(c)\", \"var _a;\\n(_a = a(b)) == null ? void 0 : _a(c);\\n\")\n\texpectPrintedTarget(t, 2019, \"this?.(x)\", \"this == null ? void 0 : this(x);\\n\")\n\n\texpectPrintedTarget(t, 2019, \"delete a?.b.c\", \"a == null ? true : delete a.b.c;\\n\")\n\texpectPrintedTarget(t, 2019, \"delete a?.[b][c]\", \"a == null ? true : delete a[b][c];\\n\")\n\texpectPrintedTarget(t, 2019, \"delete a?.(b)(c)\", \"a == null ? true : delete a(b)(c);\\n\")\n\n\texpectPrintedTarget(t, 2019, \"delete (a?.b).c\", \"delete (a == null ? void 0 : a.b).c;\\n\")\n\texpectPrintedTarget(t, 2019, \"delete (a?.[b])[c]\", \"delete (a == null ? void 0 : a[b])[c];\\n\")\n\texpectPrintedTarget(t, 2019, \"delete (a?.(b))(c)\", \"delete (a == null ? void 0 : a(b))(c);\\n\")\n\n\texpectPrintedTarget(t, 2019, \"(delete a?.b).c\", \"(a == null ? true : delete a.b).c;\\n\")\n\texpectPrintedTarget(t, 2019, \"(delete a?.[b])[c]\", \"(a == null ? true : delete a[b])[c];\\n\")\n\texpectPrintedTarget(t, 2019, \"(delete a?.(b))(c)\", \"(a == null ? true : delete a(b))(c);\\n\")\n\n\texpectPrintedTarget(t, 2019, \"null?.x\", \"\")\n\texpectPrintedTarget(t, 2019, \"null?.[x]\", \"\")\n\texpectPrintedTarget(t, 2019, \"null?.(x)\", \"\")\n\n\texpectPrintedTarget(t, 2019, \"delete null?.x\", \"\")\n\texpectPrintedTarget(t, 2019, \"delete null?.[x]\", \"\")\n\texpectPrintedTarget(t, 2019, \"delete null?.(x)\", \"\")\n\n\texpectPrintedTarget(t, 2019, \"undefined?.x\", \"\")\n\texpectPrintedTarget(t, 2019, \"undefined?.[x]\", \"\")\n\texpectPrintedTarget(t, 2019, \"undefined?.(x)\", \"\")\n\n\texpectPrintedTarget(t, 2019, \"delete undefined?.x\", \"\")\n\texpectPrintedTarget(t, 2019, \"delete undefined?.[x]\", \"\")\n\texpectPrintedTarget(t, 2019, \"delete undefined?.(x)\", \"\")\n\n\texpectPrintedMangleTarget(t, 2019, \"(foo(), null)?.x; y = (bar(), null)?.x\", \"foo(), y = (bar(), void 0);\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"(foo(), null)?.[x]; y = (bar(), null)?.[x]\", \"foo(), y = (bar(), void 0);\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"(foo(), null)?.(x); y = (bar(), null)?.(x)\", \"foo(), y = (bar(), void 0);\\n\")\n\n\texpectPrintedMangleTarget(t, 2019, \"(foo(), void 0)?.x; y = (bar(), void 0)?.x\", \"foo(), y = (bar(), void 0);\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"(foo(), void 0)?.[x]; y = (bar(), void 0)?.[x]\", \"foo(), y = (bar(), void 0);\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"(foo(), void 0)?.(x); y = (bar(), void 0)?.(x)\", \"foo(), y = (bar(), void 0);\\n\")\n\n\texpectPrintedTarget(t, 2020, \"x?.y\", \"x?.y;\\n\")\n\texpectPrintedTarget(t, 2020, \"x?.[y]\", \"x?.[y];\\n\")\n\texpectPrintedTarget(t, 2020, \"x?.(y)\", \"x?.(y);\\n\")\n\n\texpectPrintedTarget(t, 2020, \"null?.x\", \"\")\n\texpectPrintedTarget(t, 2020, \"null?.[x]\", \"\")\n\texpectPrintedTarget(t, 2020, \"null?.(x)\", \"\")\n\n\texpectPrintedTarget(t, 2020, \"undefined?.x\", \"\")\n\texpectPrintedTarget(t, 2020, \"undefined?.[x]\", \"\")\n\texpectPrintedTarget(t, 2020, \"undefined?.(x)\", \"\")\n\n\texpectPrintedTarget(t, 2020, \"(foo(), null)?.x\", \"(foo(), null)?.x;\\n\")\n\texpectPrintedTarget(t, 2020, \"(foo(), null)?.[x]\", \"(foo(), null)?.[x];\\n\")\n\texpectPrintedTarget(t, 2020, \"(foo(), null)?.(x)\", \"(foo(), null)?.(x);\\n\")\n\n\texpectPrintedTarget(t, 2020, \"(foo(), void 0)?.x\", \"(foo(), void 0)?.x;\\n\")\n\texpectPrintedTarget(t, 2020, \"(foo(), void 0)?.[x]\", \"(foo(), void 0)?.[x];\\n\")\n\texpectPrintedTarget(t, 2020, \"(foo(), void 0)?.(x)\", \"(foo(), void 0)?.(x);\\n\")\n\n\texpectPrintedMangleTarget(t, 2020, \"(foo(), null)?.x; y = (bar(), null)?.x\", \"foo(), y = (bar(), void 0);\\n\")\n\texpectPrintedMangleTarget(t, 2020, \"(foo(), null)?.[x]; y = (bar(), null)?.[x]\", \"foo(), y = (bar(), void 0);\\n\")\n\texpectPrintedMangleTarget(t, 2020, \"(foo(), null)?.(x); y = (bar(), null)?.(x)\", \"foo(), y = (bar(), void 0);\\n\")\n\n\texpectPrintedMangleTarget(t, 2020, \"(foo(), void 0)?.x; y = (bar(), void 0)?.x\", \"foo(), y = (bar(), void 0);\\n\")\n\texpectPrintedMangleTarget(t, 2020, \"(foo(), void 0)?.[x]; y = (bar(), void 0)?.[x]\", \"foo(), y = (bar(), void 0);\\n\")\n\texpectPrintedMangleTarget(t, 2020, \"(foo(), void 0)?.(x); y = (bar(), void 0)?.(x)\", \"foo(), y = (bar(), void 0);\\n\")\n\n\texpectPrintedTarget(t, 2019, \"a?.b()\", \"a == null ? void 0 : a.b();\\n\")\n\texpectPrintedTarget(t, 2019, \"a?.[b]()\", \"a == null ? void 0 : a[b]();\\n\")\n\texpectPrintedTarget(t, 2019, \"a?.b.c()\", \"a == null ? void 0 : a.b.c();\\n\")\n\texpectPrintedTarget(t, 2019, \"a?.b[c]()\", \"a == null ? void 0 : a.b[c]();\\n\")\n\texpectPrintedTarget(t, 2019, \"a()?.b()\", \"var _a;\\n(_a = a()) == null ? void 0 : _a.b();\\n\")\n\texpectPrintedTarget(t, 2019, \"a()?.[b]()\", \"var _a;\\n(_a = a()) == null ? void 0 : _a[b]();\\n\")\n\n\texpectPrintedTarget(t, 2019, \"(a?.b)()\", \"(a == null ? void 0 : a.b).call(a);\\n\")\n\texpectPrintedTarget(t, 2019, \"(a?.[b])()\", \"(a == null ? void 0 : a[b]).call(a);\\n\")\n\texpectPrintedTarget(t, 2019, \"(a?.b.c)()\", \"var _a;\\n(a == null ? void 0 : (_a = a.b).c).call(_a);\\n\")\n\texpectPrintedTarget(t, 2019, \"(a?.b[c])()\", \"var _a;\\n(a == null ? void 0 : (_a = a.b)[c]).call(_a);\\n\")\n\texpectPrintedTarget(t, 2019, \"(a()?.b)()\", \"var _a;\\n((_a = a()) == null ? void 0 : _a.b).call(_a);\\n\")\n\texpectPrintedTarget(t, 2019, \"(a()?.[b])()\", \"var _a;\\n((_a = a()) == null ? void 0 : _a[b]).call(_a);\\n\")\n\n\t// Check multiple levels of nesting\n\texpectPrintedTarget(t, 2019, \"a?.b?.c?.d\", `var _a, _b;\n(_b = (_a = a == null ? void 0 : a.b) == null ? void 0 : _a.c) == null ? void 0 : _b.d;\n`)\n\texpectPrintedTarget(t, 2019, \"a?.[b]?.[c]?.[d]\", `var _a, _b;\n(_b = (_a = a == null ? void 0 : a[b]) == null ? void 0 : _a[c]) == null ? void 0 : _b[d];\n`)\n\texpectPrintedTarget(t, 2019, \"a?.(b)?.(c)?.(d)\", `var _a, _b;\n(_b = (_a = a == null ? void 0 : a(b)) == null ? void 0 : _a(c)) == null ? void 0 : _b(d);\n`)\n\n\t// Check the need to use \".call()\"\n\texpectPrintedTarget(t, 2019, \"a.b?.(c)\", `var _a;\n(_a = a.b) == null ? void 0 : _a.call(a, c);\n`)\n\texpectPrintedTarget(t, 2019, \"a[b]?.(c)\", `var _a;\n(_a = a[b]) == null ? void 0 : _a.call(a, c);\n`)\n\texpectPrintedTarget(t, 2019, \"a?.[b]?.(c)\", `var _a;\n(_a = a == null ? void 0 : a[b]) == null ? void 0 : _a.call(a, c);\n`)\n\texpectPrintedTarget(t, 2019, \"a?.[b]?.(c).d\", `var _a;\n(_a = a == null ? void 0 : a[b]) == null ? void 0 : _a.call(a, c).d;\n`)\n\texpectPrintedTarget(t, 2019, \"a?.[b]?.(c).d()\", `var _a;\n(_a = a == null ? void 0 : a[b]) == null ? void 0 : _a.call(a, c).d();\n`)\n\texpectPrintedTarget(t, 2019, \"a?.[b]?.(c)['d']\", `var _a;\n(_a = a == null ? void 0 : a[b]) == null ? void 0 : _a.call(a, c)[\"d\"];\n`)\n\texpectPrintedTarget(t, 2019, \"a?.[b]?.(c)['d']()\", `var _a;\n(_a = a == null ? void 0 : a[b]) == null ? void 0 : _a.call(a, c)[\"d\"]();\n`)\n\texpectPrintedTarget(t, 2019, \"a?.[b]?.(c).d['e'](f)['g'].h(i)\", `var _a;\n(_a = a == null ? void 0 : a[b]) == null ? void 0 : _a.call(a, c).d[\"e\"](f)[\"g\"].h(i);\n`)\n\texpectPrintedTarget(t, 2019, \"123?.[b]?.(c)\", `var _a;\n(_a = 123 == null ? void 0 : 123[b]) == null ? void 0 : _a.call(123, c);\n`)\n\texpectPrintedTarget(t, 2019, \"a?.[b][c]?.(d)\", `var _a, _b;\n(_b = a == null ? void 0 : (_a = a[b])[c]) == null ? void 0 : _b.call(_a, d);\n`)\n\texpectPrintedTarget(t, 2019, \"a[b][c]?.(d)\", `var _a, _b;\n(_b = (_a = a[b])[c]) == null ? void 0 : _b.call(_a, d);\n`)\n\n\t// Check that direct eval status is not propagated through optional chaining\n\texpectPrintedTarget(t, 2019, \"eval?.(x)\", \"eval == null ? void 0 : (0, eval)(x);\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"(1 ? eval : 0)?.(x)\", \"eval == null || (0, eval)(x);\\n\")\n\n\t// Check super property access\n\texpectPrintedTarget(t, 2019, \"class Foo extends Bar { foo() { super.bar?.() } }\", `class Foo extends Bar {\n  foo() {\n    var _a;\n    (_a = super.bar) == null ? void 0 : _a.call(this);\n  }\n}\n`)\n\texpectPrintedTarget(t, 2019, \"class Foo extends Bar { foo() { super['bar']?.() } }\", `class Foo extends Bar {\n  foo() {\n    var _a;\n    (_a = super[\"bar\"]) == null ? void 0 : _a.call(this);\n  }\n}\n`)\n\n\texpectPrintedTarget(t, 2020, \"(x?.y)``\", \"(x?.y)``;\\n\")\n\texpectPrintedTarget(t, 2019, \"(x?.y)``\", \"var _a;\\n(x == null ? void 0 : x.y).call(x, _a || (_a = __template([\\\"\\\"])));\\n\")\n\texpectPrintedTarget(t, 5, \"(x?.y)``\", \"var _a;\\n(x == null ? void 0 : x.y).call(x, _a || (_a = __template([\\\"\\\"])));\\n\")\n\n\t// Temporary variables should not come before \"use strict\"\n\texpectPrintedTarget(t, 2019, \"function f() { /*! @license */ 'use strict'; a.b?.c() }\",\n\t\t\"function f() {\\n  /*! @license */\\n  \\\"use strict\\\";\\n  var _a;\\n  (_a = a.b) == null ? void 0 : _a.c();\\n}\\n\")\n}\n\nfunc TestLowerOptionalCatchBinding(t *testing.T) {\n\texpectPrintedTarget(t, 2019, \"try {} catch {}\", \"try {\\n} catch {\\n}\\n\")\n\texpectPrintedTarget(t, 2018, \"try {} catch {}\", \"try {\\n} catch (e) {\\n}\\n\")\n}\n\nfunc TestLowerBigInt(t *testing.T) {\n\texpectPrintedTarget(t, 2019, \"x = 0n\", \"x = /* @__PURE__ */ BigInt(\\\"0\\\");\\n\")\n\texpectPrintedTarget(t, 2020, \"x = 0n\", \"x = 0n;\\n\")\n\n\texpectPrintedTarget(t, 2019, \"x = 0b100101n\", \"x = /* @__PURE__ */ BigInt(\\\"0b100101\\\");\\n\")\n\texpectPrintedTarget(t, 2019, \"x = 0B100101n\", \"x = /* @__PURE__ */ BigInt(\\\"0B100101\\\");\\n\")\n\texpectPrintedTarget(t, 2019, \"x = 0o76543210n\", \"x = /* @__PURE__ */ BigInt(\\\"0o76543210\\\");\\n\")\n\texpectPrintedTarget(t, 2019, \"x = 0O76543210n\", \"x = /* @__PURE__ */ BigInt(\\\"0O76543210\\\");\\n\")\n\texpectPrintedTarget(t, 2019, \"x = 0xFEDCBA9876543210n\", \"x = /* @__PURE__ */ BigInt(\\\"0xFEDCBA9876543210\\\");\\n\")\n\texpectPrintedTarget(t, 2019, \"x = 0XFEDCBA9876543210n\", \"x = /* @__PURE__ */ BigInt(\\\"0XFEDCBA9876543210\\\");\\n\")\n\texpectPrintedTarget(t, 2019, \"x = 0xb0ba_cafe_f00dn\", \"x = /* @__PURE__ */ BigInt(\\\"0xb0bacafef00d\\\");\\n\")\n\texpectPrintedTarget(t, 2019, \"x = 0xB0BA_CAFE_F00Dn\", \"x = /* @__PURE__ */ BigInt(\\\"0xB0BACAFEF00D\\\");\\n\")\n\texpectPrintedTarget(t, 2019, \"x = 102030405060708090807060504030201n\", \"x = /* @__PURE__ */ BigInt(\\\"102030405060708090807060504030201\\\");\\n\")\n\n\texpectPrintedTarget(t, 2019, \"x = {0b100101n: 0}\", \"x = { \\\"37\\\": 0 };\\n\")\n\texpectPrintedTarget(t, 2019, \"x = {0B100101n: 0}\", \"x = { \\\"37\\\": 0 };\\n\")\n\texpectPrintedTarget(t, 2019, \"x = {0o76543210n: 0}\", \"x = { \\\"16434824\\\": 0 };\\n\")\n\texpectPrintedTarget(t, 2019, \"x = {0O76543210n: 0}\", \"x = { \\\"16434824\\\": 0 };\\n\")\n\texpectPrintedTarget(t, 2019, \"x = {0xFEDCBA9876543210n: 0}\", \"x = { \\\"18364758544493064720\\\": 0 };\\n\")\n\texpectPrintedTarget(t, 2019, \"x = {0XFEDCBA9876543210n: 0}\", \"x = { \\\"18364758544493064720\\\": 0 };\\n\")\n\texpectPrintedTarget(t, 2019, \"x = {0xb0ba_cafe_f00dn: 0}\", \"x = { \\\"194316316110861\\\": 0 };\\n\")\n\texpectPrintedTarget(t, 2019, \"x = {0xB0BA_CAFE_F00Dn: 0}\", \"x = { \\\"194316316110861\\\": 0 };\\n\")\n\texpectPrintedTarget(t, 2019, \"x = {102030405060708090807060504030201n: 0}\", \"x = { \\\"102030405060708090807060504030201\\\": 0 };\\n\")\n\n\texpectPrintedTarget(t, 2019, \"({0b100101n: x} = y)\", \"({ \\\"37\\\": x } = y);\\n\")\n\texpectPrintedTarget(t, 2019, \"({0B100101n: x} = y)\", \"({ \\\"37\\\": x } = y);\\n\")\n\texpectPrintedTarget(t, 2019, \"({0o76543210n: x} = y)\", \"({ \\\"16434824\\\": x } = y);\\n\")\n\texpectPrintedTarget(t, 2019, \"({0O76543210n: x} = y)\", \"({ \\\"16434824\\\": x } = y);\\n\")\n\texpectPrintedTarget(t, 2019, \"({0xFEDCBA9876543210n: x} = y)\", \"({ \\\"18364758544493064720\\\": x } = y);\\n\")\n\texpectPrintedTarget(t, 2019, \"({0XFEDCBA9876543210n: x} = y)\", \"({ \\\"18364758544493064720\\\": x } = y);\\n\")\n\texpectPrintedTarget(t, 2019, \"({0xb0ba_cafe_f00dn: x} = y)\", \"({ \\\"194316316110861\\\": x } = y);\\n\")\n\texpectPrintedTarget(t, 2019, \"({0xB0BA_CAFE_F00Dn: x} = y)\", \"({ \\\"194316316110861\\\": x } = y);\\n\")\n\texpectPrintedTarget(t, 2019, \"({102030405060708090807060504030201n: x} = y)\", \"({ \\\"102030405060708090807060504030201\\\": x } = y);\\n\")\n\n\texpectPrintedMangleTarget(t, 2019, \"x = {0b100101n: 0}\", \"x = { 37: 0 };\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"x = {0B100101n: 0}\", \"x = { 37: 0 };\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"x = {0o76543210n: 0}\", \"x = { 16434824: 0 };\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"x = {0O76543210n: 0}\", \"x = { 16434824: 0 };\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"x = {0xFEDCBA9876543210n: 0}\", \"x = { \\\"18364758544493064720\\\": 0 };\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"x = {0XFEDCBA9876543210n: 0}\", \"x = { \\\"18364758544493064720\\\": 0 };\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"x = {0xb0ba_cafe_f00dn: 0}\", \"x = { \\\"194316316110861\\\": 0 };\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"x = {0xB0BA_CAFE_F00Dn: 0}\", \"x = { \\\"194316316110861\\\": 0 };\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"x = {102030405060708090807060504030201n: 0}\", \"x = { \\\"102030405060708090807060504030201\\\": 0 };\\n\")\n\n\texpectPrintedMangleTarget(t, 2019, \"({0b100101n: x} = y)\", \"({ 37: x } = y);\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"({0B100101n: x} = y)\", \"({ 37: x } = y);\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"({0o76543210n: x} = y)\", \"({ 16434824: x } = y);\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"({0O76543210n: x} = y)\", \"({ 16434824: x } = y);\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"({0xFEDCBA9876543210n: x} = y)\", \"({ \\\"18364758544493064720\\\": x } = y);\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"({0XFEDCBA9876543210n: x} = y)\", \"({ \\\"18364758544493064720\\\": x } = y);\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"({0xb0ba_cafe_f00dn: x} = y)\", \"({ \\\"194316316110861\\\": x } = y);\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"({0xB0BA_CAFE_F00Dn: x} = y)\", \"({ \\\"194316316110861\\\": x } = y);\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"({102030405060708090807060504030201n: x} = y)\", \"({ \\\"102030405060708090807060504030201\\\": x } = y);\\n\")\n}\n\nfunc TestLowerExportStarAs(t *testing.T) {\n\texpectPrintedTarget(t, 2020, \"export * as ns from 'path'\", \"export * as ns from \\\"path\\\";\\n\")\n\texpectPrintedTarget(t, 2019, \"export * as ns from 'path'\", \"import * as ns from \\\"path\\\";\\nexport { ns };\\n\")\n}\n\nfunc TestAsyncGeneratorFns(t *testing.T) {\n\terr := \"\"\n\texpectParseErrorWithUnsupportedFeatures(t, compat.AsyncAwait, \"async function gen() {}\", err)\n\texpectParseErrorWithUnsupportedFeatures(t, compat.AsyncAwait, \"(async function () {});\", err)\n\texpectParseErrorWithUnsupportedFeatures(t, compat.AsyncAwait, \"({ async foo() {} });\", err)\n\n\terr = \"<stdin>: ERROR: Transforming generator functions to the configured target environment is not supported yet\\n\"\n\texpectParseErrorWithUnsupportedFeatures(t, compat.Generator, \"function* gen() {}\", err)\n\texpectParseErrorWithUnsupportedFeatures(t, compat.Generator, \"(function* () {});\", err)\n\texpectParseErrorWithUnsupportedFeatures(t, compat.Generator, \"({ *foo() {} });\", err)\n\n\terr = \"<stdin>: ERROR: Transforming async functions to the configured target environment is not supported yet\\n\"\n\texpectParseErrorWithUnsupportedFeatures(t, compat.AsyncAwait|compat.Generator, \"async function gen() {}\", err)\n\texpectParseErrorWithUnsupportedFeatures(t, compat.AsyncAwait|compat.Generator, \"(async function () {});\", err)\n\texpectParseErrorWithUnsupportedFeatures(t, compat.AsyncAwait|compat.Generator, \"({ async foo() {} });\", err)\n\n\terr = \"\"\n\texpectParseErrorWithUnsupportedFeatures(t, compat.AsyncGenerator, \"async function* gen() {}\", err)\n\texpectParseErrorWithUnsupportedFeatures(t, compat.AsyncGenerator, \"(async function* () {});\", err)\n\texpectParseErrorWithUnsupportedFeatures(t, compat.AsyncGenerator, \"({ async *foo() {} });\", err)\n}\n\nfunc TestForAwait(t *testing.T) {\n\terr := \"\"\n\texpectParseErrorWithUnsupportedFeatures(t, compat.AsyncAwait, \"async function gen() { for await (x of y) ; }\", err)\n\texpectParseErrorWithUnsupportedFeatures(t, compat.Generator, \"async function gen() { for await (x of y) ; }\", err)\n\n\t// This is ok because for-await can be lowered to await\n\texpectParseErrorWithUnsupportedFeatures(t, compat.ForAwait|compat.Generator, \"async function gen() { for await (x of y) ; }\", err)\n\n\t// This is ok because for-await can be lowered to yield\n\texpectParseErrorWithUnsupportedFeatures(t, compat.ForAwait|compat.AsyncAwait, \"async function gen() { for await (x of y) ; }\", err)\n\n\t// This is not ok because for-await can't be lowered\n\terr =\n\t\t\"<stdin>: ERROR: Transforming async functions to the configured target environment is not supported yet\\n\" +\n\t\t\t\"<stdin>: ERROR: Transforming for-await loops to the configured target environment is not supported yet\\n\"\n\texpectParseErrorWithUnsupportedFeatures(t, compat.ForAwait|compat.AsyncAwait|compat.Generator, \"async function gen() { for await (x of y) ; }\", err)\n\n\t// Can't use for-await at the top-level without top-level await\n\terr = \"<stdin>: ERROR: Top-level await is not available in the configured target environment\\n\"\n\texpectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, \"for await (x of y) ;\", err)\n\texpectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, \"if (true) for await (x of y) ;\", err)\n\texpectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, \"if (false) for await (x of y) ;\", \"if (false) for (x of y) ;\\n\")\n\texpectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, \"with (x) y; if (false) for await (x of y) ;\",\n\t\t\"<stdin>: ERROR: With statements cannot be used in an ECMAScript module\\n\"+\n\t\t\t\"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the top-level \\\"await\\\" keyword here:\\n\")\n}\n\nfunc TestLowerAutoAccessors(t *testing.T) {\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators, \"class Foo { accessor x }\",\n\t\t\"class Foo {\\n  #x;\\n  get x() {\\n    return this.#x;\\n  }\\n  set x(_) {\\n    this.#x = _;\\n  }\\n}\\n\")\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators, \"class Foo { accessor [x] }\",\n\t\t\"var _a;\\nclass Foo {\\n  #a;\\n  get [_a = x]() {\\n    return this.#a;\\n  }\\n  set [_a](_) {\\n    this.#a = _;\\n  }\\n}\\n\")\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators, \"class Foo { accessor x = null }\",\n\t\t\"class Foo {\\n  #x = null;\\n  get x() {\\n    return this.#x;\\n  }\\n  set x(_) {\\n    this.#x = _;\\n  }\\n}\\n\")\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators, \"class Foo { accessor [x] = null }\",\n\t\t\"var _a;\\nclass Foo {\\n  #a = null;\\n  get [_a = x]() {\\n    return this.#a;\\n  }\\n  set [_a](_) {\\n    this.#a = _;\\n  }\\n}\\n\")\n\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators, \"class Foo { static accessor x }\",\n\t\t\"class Foo {\\n  static #x;\\n  static get x() {\\n    return this.#x;\\n  }\\n  static set x(_) {\\n    this.#x = _;\\n  }\\n}\\n\")\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators, \"class Foo { static accessor [x] }\",\n\t\t\"var _a;\\nclass Foo {\\n  static #a;\\n  static get [_a = x]() {\\n    return this.#a;\\n  }\\n  static set [_a](_) {\\n    this.#a = _;\\n  }\\n}\\n\")\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators, \"class Foo { static accessor x = null }\",\n\t\t\"class Foo {\\n  static #x = null;\\n  static get x() {\\n    return this.#x;\\n  }\\n  static set x(_) {\\n    this.#x = _;\\n  }\\n}\\n\")\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators, \"class Foo { static accessor [x] = null }\",\n\t\t\"var _a;\\nclass Foo {\\n  static #a = null;\\n  static get [_a = x]() {\\n    return this.#a;\\n  }\\n  static set [_a](_) {\\n    this.#a = _;\\n  }\\n}\\n\")\n\n\t// Test various combinations of flags\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators|compat.ClassPrivateField, \"class Foo { accessor x = null }\",\n\t\t`var _x;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x, null);\n  }\n  get x() {\n    return __privateGet(this, _x);\n  }\n  set x(_) {\n    __privateSet(this, _x, _);\n  }\n}\n_x = new WeakMap();\n`)\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators|compat.ClassPrivateStaticField, \"class Foo { static accessor x = null }\",\n\t\t`var _x;\nclass Foo {\n  static get x() {\n    return __privateGet(this, _x);\n  }\n  static set x(_) {\n    __privateSet(this, _x, _);\n  }\n}\n_x = new WeakMap();\n__privateAdd(Foo, _x, null);\n`)\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators|compat.ClassField|compat.ClassPrivateField, \"class Foo { accessor x = null }\",\n\t\t`var _x;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x, null);\n  }\n  get x() {\n    return __privateGet(this, _x);\n  }\n  set x(_) {\n    __privateSet(this, _x, _);\n  }\n}\n_x = new WeakMap();\n`)\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators|compat.ClassStaticField|compat.ClassPrivateStaticField, \"class Foo { static accessor x = null }\",\n\t\t`var _x;\nclass Foo {\n  static get x() {\n    return __privateGet(this, _x);\n  }\n  static set x(_) {\n    __privateSet(this, _x, _);\n  }\n}\n_x = new WeakMap();\n__privateAdd(Foo, _x, null);\n`)\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators|compat.ClassField|compat.ClassPrivateField, \"class Foo { accessor x = 1; static accessor y = 2 }\",\n\t\t`var _x, _y;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x, 1);\n  }\n  get x() {\n    return __privateGet(this, _x);\n  }\n  set x(_) {\n    __privateSet(this, _x, _);\n  }\n  static get y() {\n    return __privateGet(this, _y);\n  }\n  static set y(_) {\n    __privateSet(this, _y, _);\n  }\n}\n_x = new WeakMap();\n_y = new WeakMap();\n__privateAdd(Foo, _y, 2);\n`)\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators|compat.ClassStaticField|compat.ClassPrivateStaticField, \"class Foo { accessor x = 1; static accessor y = 2 }\",\n\t\t`var _y;\nclass Foo {\n  #x = 1;\n  get x() {\n    return this.#x;\n  }\n  set x(_) {\n    this.#x = _;\n  }\n  static get y() {\n    return __privateGet(this, _y);\n  }\n  static set y(_) {\n    __privateSet(this, _y, _);\n  }\n}\n_y = new WeakMap();\n__privateAdd(Foo, _y, 2);\n`)\n}\n"
  },
  {
    "path": "internal/js_parser/js_parser_test.go",
    "content": "package js_parser\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/js_printer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/renamer\"\n\t\"github.com/evanw/esbuild/internal/test\"\n)\n\nfunc expectParseErrorCommon(t *testing.T, contents string, expected string, options config.Options) {\n\tt.Helper()\n\tt.Run(contents, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\t\tParse(log, test.SourceForTest(contents), OptionsFromConfig(&options))\n\t\tmsgs := log.Done()\n\t\tvar text strings.Builder\n\t\tfor _, msg := range msgs {\n\t\t\ttext.WriteString(msg.String(logger.OutputOptions{}, logger.TerminalInfo{}))\n\t\t}\n\t\ttest.AssertEqualWithDiff(t, text.String(), expected)\n\t})\n}\n\nfunc expectParseError(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectParseErrorCommon(t, contents, expected, config.Options{})\n}\n\nfunc expectParseErrorTarget(t *testing.T, esVersion int, contents string, expected string) {\n\tt.Helper()\n\texpectParseErrorCommon(t, contents, expected, config.Options{\n\t\tUnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{\n\t\t\tcompat.ES: {Parts: []int{esVersion}},\n\t\t}),\n\t})\n}\n\nfunc expectPrintedWithUnsupportedFeatures(t *testing.T, unsupportedJSFeatures compat.JSFeature, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tUnsupportedJSFeatures: unsupportedJSFeatures,\n\t})\n}\n\nfunc expectParseErrorWithUnsupportedFeatures(t *testing.T, unsupportedJSFeatures compat.JSFeature, contents string, expected string) {\n\tt.Helper()\n\texpectParseErrorCommon(t, contents, expected, config.Options{\n\t\tUnsupportedJSFeatures: unsupportedJSFeatures,\n\t})\n}\n\nfunc expectPrintedCommon(t *testing.T, contents string, expected string, options config.Options) {\n\tt.Helper()\n\tt.Run(contents, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\t\toptions.OmitRuntimeForTests = true\n\t\ttree, ok := Parse(log, test.SourceForTest(contents), OptionsFromConfig(&options))\n\t\tmsgs := log.Done()\n\t\tvar text strings.Builder\n\t\tfor _, msg := range msgs {\n\t\t\tif msg.Kind != logger.Warning {\n\t\t\t\ttext.WriteString(msg.String(logger.OutputOptions{}, logger.TerminalInfo{}))\n\t\t\t}\n\t\t}\n\t\ttest.AssertEqualWithDiff(t, text.String(), \"\")\n\t\tif !ok {\n\t\t\tt.Fatal(\"Parse error\")\n\t\t}\n\t\tsymbols := ast.NewSymbolMap(1)\n\t\tsymbols.SymbolsForSource[0] = tree.Symbols\n\t\tr := renamer.NewNoOpRenamer(symbols)\n\t\tjs := js_printer.Print(tree, symbols, r, js_printer.Options{\n\t\t\tUnsupportedFeatures: options.UnsupportedJSFeatures,\n\t\t\tASCIIOnly:           options.ASCIIOnly,\n\t\t}).JS\n\t\ttest.AssertEqualWithDiff(t, string(js), expected)\n\t})\n}\n\nfunc expectPrinted(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{})\n}\n\nfunc expectPrintedMangle(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tMinifySyntax: true,\n\t})\n}\n\nfunc expectPrintedNormalAndMangle(t *testing.T, contents string, normal string, mangle string) {\n\texpectPrinted(t, contents, normal)\n\texpectPrintedMangle(t, contents, mangle)\n}\n\nfunc expectPrintedTarget(t *testing.T, esVersion int, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tUnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{\n\t\t\tcompat.ES: {Parts: []int{esVersion}},\n\t\t}),\n\t})\n}\n\nfunc expectPrintedMangleTarget(t *testing.T, esVersion int, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tUnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{\n\t\t\tcompat.ES: {Parts: []int{esVersion}},\n\t\t}),\n\t\tMinifySyntax: true,\n\t})\n}\n\nfunc expectPrintedASCII(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tASCIIOnly: true,\n\t})\n}\n\nfunc expectPrintedTargetASCII(t *testing.T, esVersion int, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tUnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{\n\t\t\tcompat.ES: {Parts: []int{esVersion}},\n\t\t}),\n\t\tASCIIOnly: true,\n\t})\n}\n\nfunc expectParseErrorTargetASCII(t *testing.T, esVersion int, contents string, expected string) {\n\tt.Helper()\n\texpectParseErrorCommon(t, contents, expected, config.Options{\n\t\tUnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{\n\t\t\tcompat.ES: {Parts: []int{esVersion}},\n\t\t}),\n\t\tASCIIOnly: true,\n\t})\n}\n\nfunc expectParseErrorJSX(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectParseErrorCommon(t, contents, expected, config.Options{\n\t\tJSX: config.JSXOptions{\n\t\t\tParse: true,\n\t\t},\n\t})\n}\n\nfunc expectPrintedJSX(t *testing.T, contents string, expectedPreserve string, expectedTransform string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expectedPreserve, config.Options{\n\t\tJSX: config.JSXOptions{\n\t\t\tParse:    true,\n\t\t\tPreserve: true,\n\t\t},\n\t})\n\texpectPrintedCommon(t, contents, expectedTransform, config.Options{\n\t\tJSX: config.JSXOptions{\n\t\t\tParse: true,\n\t\t},\n\t})\n}\n\nfunc expectPrintedJSXSideEffects(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tJSX: config.JSXOptions{\n\t\t\tParse:       true,\n\t\t\tSideEffects: true,\n\t\t},\n\t})\n}\n\nfunc expectPrintedMangleJSX(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tMinifySyntax: true,\n\t\tJSX: config.JSXOptions{\n\t\t\tParse: true,\n\t\t},\n\t})\n}\n\ntype JSXAutomaticTestOptions struct {\n\tDevelopment            bool\n\tImportSource           string\n\tOmitJSXRuntimeForTests bool\n\tSideEffects            bool\n}\n\nfunc expectParseErrorJSXAutomatic(t *testing.T, options JSXAutomaticTestOptions, contents string, expected string) {\n\tt.Helper()\n\texpectParseErrorCommon(t, contents, expected, config.Options{\n\t\tOmitJSXRuntimeForTests: options.OmitJSXRuntimeForTests,\n\t\tJSX: config.JSXOptions{\n\t\t\tAutomaticRuntime: true,\n\t\t\tParse:            true,\n\t\t\tDevelopment:      options.Development,\n\t\t\tImportSource:     options.ImportSource,\n\t\t\tSideEffects:      options.SideEffects,\n\t\t},\n\t})\n}\n\nfunc expectPrintedJSXAutomatic(t *testing.T, options JSXAutomaticTestOptions, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tOmitJSXRuntimeForTests: options.OmitJSXRuntimeForTests,\n\t\tJSX: config.JSXOptions{\n\t\t\tAutomaticRuntime: true,\n\t\t\tParse:            true,\n\t\t\tDevelopment:      options.Development,\n\t\t\tImportSource:     options.ImportSource,\n\t\t\tSideEffects:      options.SideEffects,\n\t\t},\n\t})\n}\n\nfunc TestUnOp(t *testing.T) {\n\t// This was important to someone for a very obscure reason. See\n\t// https://github.com/evanw/esbuild/issues/4041 for more info.\n\texpectPrinted(t, \"let x; void 0; x\", \"let x;\\nx;\\n\")\n\texpectPrinted(t, \"let x; void x; x\", \"let x;\\nvoid x;\\nx;\\n\")\n}\n\nfunc TestBinOp(t *testing.T) {\n\tfor code, entry := range js_ast.OpTable {\n\t\topCode := js_ast.OpCode(code)\n\n\t\tif opCode.IsLeftAssociative() {\n\t\t\top := entry.Text\n\t\t\texpectPrinted(t, \"a \"+op+\" b \"+op+\" c\", \"a \"+op+\" b \"+op+\" c;\\n\")\n\t\t\texpectPrinted(t, \"(a \"+op+\" b) \"+op+\" c\", \"a \"+op+\" b \"+op+\" c;\\n\")\n\t\t\texpectPrinted(t, \"a \"+op+\" (b \"+op+\" c)\", \"a \"+op+\" (b \"+op+\" c);\\n\")\n\t\t}\n\n\t\tif opCode.IsRightAssociative() {\n\t\t\top := entry.Text\n\t\t\texpectPrinted(t, \"a \"+op+\" b \"+op+\" c\", \"a \"+op+\" b \"+op+\" c;\\n\")\n\n\t\t\t// Avoid errors about invalid assignment targets\n\t\t\tif opCode.BinaryAssignTarget() == js_ast.AssignTargetNone {\n\t\t\t\texpectPrinted(t, \"(a \"+op+\" b) \"+op+\" c\", \"(a \"+op+\" b) \"+op+\" c;\\n\")\n\t\t\t}\n\n\t\t\texpectPrinted(t, \"a \"+op+\" (b \"+op+\" c)\", \"a \"+op+\" b \"+op+\" c;\\n\")\n\t\t}\n\t}\n}\n\nfunc TestComments(t *testing.T) {\n\texpectParseError(t, \"throw //\\n x\", \"<stdin>: ERROR: Unexpected newline after \\\"throw\\\"\\n\")\n\texpectParseError(t, \"throw /**/\\n x\", \"<stdin>: ERROR: Unexpected newline after \\\"throw\\\"\\n\")\n\texpectParseError(t, \"throw <!--\\n x\",\n\t\t`<stdin>: ERROR: Unexpected newline after \"throw\"\n<stdin>: WARNING: Treating \"<!--\" as the start of a legacy HTML single-line comment\n`)\n\texpectParseError(t, \"throw -->\\n x\", \"<stdin>: ERROR: Unexpected \\\">\\\"\\n\")\n\n\texpectParseError(t, \"export {}\\n<!--\", `<stdin>: ERROR: Legacy HTML single-line comments are not allowed in ECMAScript modules\n<stdin>: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n<stdin>: WARNING: Treating \"<!--\" as the start of a legacy HTML single-line comment\n`)\n\n\texpectParseError(t, \"export {}\\n-->\", `<stdin>: ERROR: Legacy HTML single-line comments are not allowed in ECMAScript modules\n<stdin>: NOTE: This file is considered to be an ECMAScript module because of the \"export\" keyword here:\n<stdin>: WARNING: Treating \"-->\" as the start of a legacy HTML single-line comment\n`)\n\n\texpectPrinted(t, \"return //\\n x\", \"return;\\nx;\\n\")\n\texpectPrinted(t, \"return /**/\\n x\", \"return;\\nx;\\n\")\n\texpectPrinted(t, \"return <!--\\n x\", \"return;\\nx;\\n\")\n\texpectPrinted(t, \"-->\\nx\", \"x;\\n\")\n\texpectPrinted(t, \"x\\n-->\\ny\", \"x;\\ny;\\n\")\n\texpectPrinted(t, \"x\\n -->\\ny\", \"x;\\ny;\\n\")\n\texpectPrinted(t, \"x\\n/**/-->\\ny\", \"x;\\ny;\\n\")\n\texpectPrinted(t, \"x/*\\n*/-->\\ny\", \"x;\\ny;\\n\")\n\texpectPrinted(t, \"x\\n/**/ /**/-->\\ny\", \"x;\\ny;\\n\")\n\texpectPrinted(t, \"if(x-->y)z\", \"if (x-- > y) z;\\n\")\n}\n\nfunc TestStrictMode(t *testing.T) {\n\tuseStrict := \"<stdin>: NOTE: Strict mode is triggered by the \\\"use strict\\\" directive here:\\n\"\n\n\texpectPrinted(t, \"'use strict'\", \"\\\"use strict\\\";\\n\")\n\texpectPrinted(t, \"`use strict`\", \"`use strict`;\\n\")\n\texpectPrinted(t, \"//! @legal comment\\n 'use strict'\", \"\\\"use strict\\\";\\n//! @legal comment\\n\")\n\texpectPrinted(t, \"/*! @legal comment */ 'use strict'\", \"\\\"use strict\\\";\\n/*! @legal comment */\\n\")\n\texpectPrinted(t, \"function f() { //! @legal comment\\n 'use strict' }\", \"function f() {\\n  //! @legal comment\\n  \\\"use strict\\\";\\n}\\n\")\n\texpectPrinted(t, \"function f() { /*! @legal comment */ 'use strict' }\", \"function f() {\\n  /*! @legal comment */\\n  \\\"use strict\\\";\\n}\\n\")\n\texpectParseError(t, \"//! @legal comment\\n 'use strict'\", \"\")\n\texpectParseError(t, \"/*! @legal comment */ 'use strict'\", \"\")\n\texpectParseError(t, \"function f() { //! @legal comment\\n 'use strict' }\", \"\")\n\texpectParseError(t, \"function f() { /*! @legal comment */ 'use strict' }\", \"\")\n\n\tnonSimple := \"<stdin>: ERROR: Cannot use a \\\"use strict\\\" directive in a function with a non-simple parameter list\\n\"\n\texpectParseError(t, \"function f() { 'use strict' }\", \"\")\n\texpectParseError(t, \"function f(x) { 'use strict' }\", \"\")\n\texpectParseError(t, \"function f([x]) { 'use strict' }\", nonSimple)\n\texpectParseError(t, \"function f({x}) { 'use strict' }\", nonSimple)\n\texpectParseError(t, \"function f(x = 1) { 'use strict' }\", nonSimple)\n\texpectParseError(t, \"function f(x, ...y) { 'use strict' }\", nonSimple)\n\texpectParseError(t, \"(function() { 'use strict' })\", \"\")\n\texpectParseError(t, \"(function(x) { 'use strict' })\", \"\")\n\texpectParseError(t, \"(function([x]) { 'use strict' })\", nonSimple)\n\texpectParseError(t, \"(function({x}) { 'use strict' })\", nonSimple)\n\texpectParseError(t, \"(function(x = 1) { 'use strict' })\", nonSimple)\n\texpectParseError(t, \"(function(x, ...y) { 'use strict' })\", nonSimple)\n\texpectParseError(t, \"() => { 'use strict' }\", \"\")\n\texpectParseError(t, \"(x) => { 'use strict' }\", \"\")\n\texpectParseError(t, \"([x]) => { 'use strict' }\", nonSimple)\n\texpectParseError(t, \"({x}) => { 'use strict' }\", nonSimple)\n\texpectParseError(t, \"(x = 1) => { 'use strict' }\", nonSimple)\n\texpectParseError(t, \"(x, ...y) => { 'use strict' }\", nonSimple)\n\texpectParseError(t, \"(x, ...y) => { //! @license comment\\n 'use strict' }\", nonSimple)\n\n\twhy := \"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the \\\"export\\\" keyword here:\\n\"\n\n\texpectPrinted(t, \"let x = '\\\\0'\", \"let x = \\\"\\\\0\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\00'\", \"let x = \\\"\\\\0\\\";\\n\")\n\texpectPrinted(t, \"'use strict'; let x = '\\\\0'\", \"\\\"use strict\\\";\\nlet x = \\\"\\\\0\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\0'; export {}\", \"let x = \\\"\\\\0\\\";\\nexport {};\\n\")\n\texpectParseError(t, \"'use strict'; let x = '\\\\00'\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; let x = '\\\\08'\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; let x = '\\\\008'\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"let x = '\\\\00'; export {}\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in an ECMAScript module\\n\"+why)\n\texpectParseError(t, \"let x = '\\\\09'; export {}\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in an ECMAScript module\\n\"+why)\n\texpectParseError(t, \"let x = '\\\\009'; export {}\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in an ECMAScript module\\n\"+why)\n\n\texpectPrinted(t, \"'\\\\0'\", \"\\\"\\\\0\\\";\\n\")\n\texpectPrinted(t, \"'\\\\00'\", \"\\\"\\\\0\\\";\\n\")\n\texpectPrinted(t, \"'use strict'; '\\\\0'\", \"\\\"use strict\\\";\\n\\\"\\\\0\\\";\\n\")\n\texpectParseError(t, \"'use strict'; '\\\\00'\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; '\\\\08'\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; '\\\\008'\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'\\\\00'; 'use strict';\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'\\\\08'; 'use strict';\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'\\\\008'; 'use strict';\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'\\\\00'; export {}\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in an ECMAScript module\\n\"+why)\n\texpectParseError(t, \"'\\\\09'; export {}\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in an ECMAScript module\\n\"+why)\n\texpectParseError(t, \"'\\\\009'; export {}\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in an ECMAScript module\\n\"+why)\n\n\texpectPrinted(t, \"with (x) y\", \"with (x) y;\\n\")\n\texpectParseError(t, \"'use strict'; with (x) y\", \"<stdin>: ERROR: With statements cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"with (x) y; export {}\", \"<stdin>: ERROR: With statements cannot be used in an ECMAScript module\\n\"+why)\n\n\texpectPrinted(t, \"delete x\", \"delete x;\\n\")\n\texpectParseError(t, \"'use strict'; delete x\", \"<stdin>: ERROR: Delete of a bare identifier cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"delete x; export {}\", \"<stdin>: ERROR: Delete of a bare identifier cannot be used in an ECMAScript module\\n\"+why)\n\n\texpectPrinted(t, \"for (var x = y in z) ;\", \"x = y;\\nfor (var x in z) ;\\n\")\n\texpectParseError(t, \"'use strict'; for (var x = y in z) ;\",\n\t\t\"<stdin>: ERROR: Variable initializers inside for-in loops cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"for (var x = y in z) ; export {}\",\n\t\t\"<stdin>: ERROR: Variable initializers inside for-in loops cannot be used in an ECMAScript module\\n\"+why)\n\n\texpectPrinted(t, \"function f(a, a) {}\", \"function f(a, a) {\\n}\\n\")\n\texpectPrinted(t, \"(function(a, a) {})\", \"(function(a, a) {\\n});\\n\")\n\texpectPrinted(t, \"({ f: function(a, a) {} })\", \"({ f: function(a, a) {\\n} });\\n\")\n\texpectPrinted(t, \"({ f: function*(a, a) {} })\", \"({ f: function* (a, a) {\\n} });\\n\")\n\texpectPrinted(t, \"({ f: async function(a, a) {} })\", \"({ f: async function(a, a) {\\n} });\\n\")\n\n\tbindingError := \"<stdin>: ERROR: \\\"a\\\" cannot be bound multiple times in the same parameter list\\n\" +\n\t\t\"<stdin>: NOTE: The name \\\"a\\\" was originally bound here:\\n\"\n\n\texpectParseError(t, \"function f(a, a) { 'use strict' }\", bindingError)\n\texpectParseError(t, \"function *f(a, a) { 'use strict' }\", bindingError)\n\texpectParseError(t, \"async function f(a, a) { 'use strict' }\", bindingError)\n\texpectParseError(t, \"(function(a, a) { 'use strict' })\", bindingError)\n\texpectParseError(t, \"(function*(a, a) { 'use strict' })\", bindingError)\n\texpectParseError(t, \"(async function(a, a) { 'use strict' })\", bindingError)\n\texpectParseError(t, \"function f(a, [a]) {}\", bindingError)\n\texpectParseError(t, \"function f([a], a) {}\", bindingError)\n\texpectParseError(t, \"'use strict'; function f(a, a) {}\", bindingError)\n\texpectParseError(t, \"'use strict'; (function(a, a) {})\", bindingError)\n\texpectParseError(t, \"'use strict'; ((a, a) => {})\", bindingError)\n\texpectParseError(t, \"function f(a, a) {}; export {}\", bindingError)\n\texpectParseError(t, \"(function(a, a) {}); export {}\", bindingError)\n\texpectParseError(t, \"(function(a, [a]) {})\", bindingError)\n\texpectParseError(t, \"({ f(a, a) {} })\", bindingError)\n\texpectParseError(t, \"({ *f(a, a) {} })\", bindingError)\n\texpectParseError(t, \"({ async f(a, a) {} })\", bindingError)\n\texpectParseError(t, \"(a, a) => {}\", bindingError)\n\n\texpectParseError(t, \"'use strict'; if (0) function f() {}\",\n\t\t\"<stdin>: ERROR: Function declarations inside if statements cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; if (0) ; else function f() {}\",\n\t\t\"<stdin>: ERROR: Function declarations inside if statements cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; x: function f() {}\",\n\t\t\"<stdin>: ERROR: Function declarations inside labels cannot be used in strict mode\\n\"+useStrict)\n\n\texpectParseError(t, \"if (0) function f() {} export {}\",\n\t\t\"<stdin>: ERROR: Function declarations inside if statements cannot be used in an ECMAScript module\\n\"+why)\n\texpectParseError(t, \"if (0) ; else function f() {} export {}\",\n\t\t\"<stdin>: ERROR: Function declarations inside if statements cannot be used in an ECMAScript module\\n\"+why)\n\texpectParseError(t, \"x: function f() {} export {}\",\n\t\t\"<stdin>: ERROR: Function declarations inside labels cannot be used in an ECMAScript module\\n\"+why)\n\n\texpectPrinted(t, \"eval++\", \"eval++;\\n\")\n\texpectPrinted(t, \"eval = 0\", \"eval = 0;\\n\")\n\texpectPrinted(t, \"eval += 0\", \"eval += 0;\\n\")\n\texpectPrinted(t, \"[eval] = 0\", \"[eval] = 0;\\n\")\n\texpectPrinted(t, \"arguments++\", \"arguments++;\\n\")\n\texpectPrinted(t, \"arguments = 0\", \"arguments = 0;\\n\")\n\texpectPrinted(t, \"arguments += 0\", \"arguments += 0;\\n\")\n\texpectPrinted(t, \"[arguments] = 0\", \"[arguments] = 0;\\n\")\n\texpectParseError(t, \"'use strict'; eval++\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"'use strict'; eval = 0\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"'use strict'; eval += 0\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"'use strict'; [eval] = 0\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"'use strict'; arguments++\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"'use strict'; arguments = 0\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"'use strict'; arguments += 0\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"'use strict'; [arguments] = 0\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\n\tevalDecl := \"<stdin>: ERROR: Declarations with the name \\\"eval\\\" cannot be used in strict mode\\n\" + useStrict\n\targsDecl := \"<stdin>: ERROR: Declarations with the name \\\"arguments\\\" cannot be used in strict mode\\n\" + useStrict\n\texpectPrinted(t, \"function eval() {}\", \"function eval() {\\n}\\n\")\n\texpectPrinted(t, \"function arguments() {}\", \"function arguments() {\\n}\\n\")\n\texpectPrinted(t, \"function f(eval) {}\", \"function f(eval) {\\n}\\n\")\n\texpectPrinted(t, \"function f(arguments) {}\", \"function f(arguments) {\\n}\\n\")\n\texpectPrinted(t, \"({ f(eval) {} })\", \"({ f(eval) {\\n} });\\n\")\n\texpectPrinted(t, \"({ f(arguments) {} })\", \"({ f(arguments) {\\n} });\\n\")\n\texpectParseError(t, \"'use strict'; function eval() {}\", evalDecl)\n\texpectParseError(t, \"'use strict'; function arguments() {}\", argsDecl)\n\texpectParseError(t, \"'use strict'; function f(eval) {}\", evalDecl)\n\texpectParseError(t, \"'use strict'; function f(arguments) {}\", argsDecl)\n\texpectParseError(t, \"function eval() { 'use strict' }\", evalDecl)\n\texpectParseError(t, \"function arguments() { 'use strict' }\", argsDecl)\n\texpectParseError(t, \"function f(eval) { 'use strict' }\", evalDecl)\n\texpectParseError(t, \"function f(arguments) { 'use strict' }\", argsDecl)\n\texpectParseError(t, \"({ f(eval) { 'use strict' } })\", evalDecl)\n\texpectParseError(t, \"({ f(arguments) { 'use strict' } })\", argsDecl)\n\texpectParseError(t, \"'use strict'; class eval {}\", evalDecl)\n\texpectParseError(t, \"'use strict'; class arguments {}\", argsDecl)\n\n\texpectPrinted(t, \"let protected\", \"let protected;\\n\")\n\texpectPrinted(t, \"let protecte\\\\u0064\", \"let protected;\\n\")\n\texpectPrinted(t, \"let x = protected\", \"let x = protected;\\n\")\n\texpectPrinted(t, \"let x = protecte\\\\u0064\", \"let x = protected;\\n\")\n\texpectParseError(t, \"'use strict'; let protected\",\n\t\t\"<stdin>: ERROR: \\\"protected\\\" is a reserved word and cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; let protecte\\\\u0064\",\n\t\t\"<stdin>: ERROR: \\\"protected\\\" is a reserved word and cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; let x = protected\",\n\t\t\"<stdin>: ERROR: \\\"protected\\\" is a reserved word and cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; let x = protecte\\\\u0064\",\n\t\t\"<stdin>: ERROR: \\\"protected\\\" is a reserved word and cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; protected: 0\",\n\t\t\"<stdin>: ERROR: \\\"protected\\\" is a reserved word and cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; protecte\\\\u0064: 0\",\n\t\t\"<stdin>: ERROR: \\\"protected\\\" is a reserved word and cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; function protected() {}\",\n\t\t\"<stdin>: ERROR: \\\"protected\\\" is a reserved word and cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; function protecte\\\\u0064() {}\",\n\t\t\"<stdin>: ERROR: \\\"protected\\\" is a reserved word and cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; (function protected() {})\",\n\t\t\"<stdin>: ERROR: \\\"protected\\\" is a reserved word and cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; (function protecte\\\\u0064() {})\",\n\t\t\"<stdin>: ERROR: \\\"protected\\\" is a reserved word and cannot be used in strict mode\\n\"+useStrict)\n\n\texpectPrinted(t, \"0123\", \"83;\\n\")\n\texpectPrinted(t, \"({0123: 4})\", \"({ 83: 4 });\\n\")\n\texpectPrinted(t, \"let {0123: x} = y\", \"let { 83: x } = y;\\n\")\n\texpectParseError(t, \"'use strict'; 0123\",\n\t\t\"<stdin>: ERROR: Legacy octal literals cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; ({0123: 4})\",\n\t\t\"<stdin>: ERROR: Legacy octal literals cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; let {0123: x} = y\",\n\t\t\"<stdin>: ERROR: Legacy octal literals cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; 08\",\n\t\t\"<stdin>: ERROR: Legacy octal literals cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; ({08: 4})\",\n\t\t\"<stdin>: ERROR: Legacy octal literals cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"'use strict'; let {08: x} = y\",\n\t\t\"<stdin>: ERROR: Legacy octal literals cannot be used in strict mode\\n\"+useStrict)\n\n\tclassNote := \"<stdin>: NOTE: All code inside a class is implicitly in strict mode\\n\"\n\n\texpectPrinted(t, \"function f() { 'use strict' } with (x) y\", \"function f() {\\n  \\\"use strict\\\";\\n}\\nwith (x) y;\\n\")\n\texpectPrinted(t, \"with (x) y; function f() { 'use strict' }\", \"with (x) y;\\nfunction f() {\\n  \\\"use strict\\\";\\n}\\n\")\n\texpectPrinted(t, \"class f {} with (x) y\", \"class f {\\n}\\nwith (x) y;\\n\")\n\texpectPrinted(t, \"with (x) y; class f {}\", \"with (x) y;\\nclass f {\\n}\\n\")\n\texpectPrinted(t, \"`use strict`; with (x) y\", \"`use strict`;\\nwith (x) y;\\n\")\n\texpectPrinted(t, \"{ 'use strict'; with (x) y }\", \"{\\n  \\\"use strict\\\";\\n  with (x) y;\\n}\\n\")\n\texpectPrinted(t, \"if (0) { 'use strict'; with (x) y }\", \"if (0) {\\n  \\\"use strict\\\";\\n  with (x) y;\\n}\\n\")\n\texpectPrinted(t, \"while (0) { 'use strict'; with (x) y }\", \"while (0) {\\n  \\\"use strict\\\";\\n  with (x) y;\\n}\\n\")\n\texpectPrinted(t, \"try { 'use strict'; with (x) y } catch {}\", \"try {\\n  \\\"use strict\\\";\\n  with (x) y;\\n} catch {\\n}\\n\")\n\texpectPrinted(t, \"try {} catch { 'use strict'; with (x) y }\", \"try {\\n} catch {\\n  \\\"use strict\\\";\\n  with (x) y;\\n}\\n\")\n\texpectPrinted(t, \"try {} finally { 'use strict'; with (x) y }\", \"try {\\n} finally {\\n  \\\"use strict\\\";\\n  with (x) y;\\n}\\n\")\n\texpectParseError(t, \"\\\"use strict\\\"; with (x) y\", \"<stdin>: ERROR: With statements cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"function f() { 'use strict'; with (x) y }\", \"<stdin>: ERROR: With statements cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"function f() { 'use strict'; function y() { with (x) y } }\", \"<stdin>: ERROR: With statements cannot be used in strict mode\\n\"+useStrict)\n\texpectParseError(t, \"class f { x() { with (x) y } }\", \"<stdin>: ERROR: With statements cannot be used in strict mode\\n\"+classNote)\n\texpectParseError(t, \"class f { x() { function y() { with (x) y } } }\", \"<stdin>: ERROR: With statements cannot be used in strict mode\\n\"+classNote)\n\texpectParseError(t, \"class f { x() { function protected() {} } }\", \"<stdin>: ERROR: \\\"protected\\\" is a reserved word and cannot be used in strict mode\\n\"+classNote)\n\n\treservedWordExport := \"<stdin>: ERROR: \\\"protected\\\" is a reserved word and cannot be used in an ECMAScript module\\n\" +\n\t\twhy\n\n\texpectParseError(t, \"var protected; export {}\", reservedWordExport)\n\texpectParseError(t, \"class protected {} export {}\", reservedWordExport)\n\texpectParseError(t, \"(class protected {}); export {}\", reservedWordExport)\n\texpectParseError(t, \"function protected() {} export {}\", reservedWordExport)\n\texpectParseError(t, \"(function protected() {}); export {}\", reservedWordExport)\n\n\timportMeta := \"<stdin>: ERROR: With statements cannot be used in an ECMAScript module\\n\" +\n\t\t\"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the use of \\\"import.meta\\\" here:\\n\"\n\timportStatement := \"<stdin>: ERROR: With statements cannot be used in an ECMAScript module\\n\" +\n\t\t\"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the \\\"import\\\" keyword here:\\n\"\n\texportKeyword := \"<stdin>: ERROR: With statements cannot be used in an ECMAScript module\\n\" +\n\t\t\"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the \\\"export\\\" keyword here:\\n\"\n\ttlaKeyword := \"<stdin>: ERROR: With statements cannot be used in an ECMAScript module\\n\" +\n\t\t\"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the top-level \\\"await\\\" keyword here:\\n\"\n\n\texpectPrinted(t, \"import(x); with (y) z\", \"import(x);\\nwith (y) z;\\n\")\n\texpectPrinted(t, \"import('x'); with (y) z\", \"import(\\\"x\\\");\\nwith (y) z;\\n\")\n\texpectPrinted(t, \"with (y) z; import(x)\", \"with (y) z;\\nimport(x);\\n\")\n\texpectPrinted(t, \"with (y) z; import('x')\", \"with (y) z;\\nimport(\\\"x\\\");\\n\")\n\texpectPrinted(t, \"(import(x)); with (y) z\", \"import(x);\\nwith (y) z;\\n\")\n\texpectPrinted(t, \"(import('x')); with (y) z\", \"import(\\\"x\\\");\\nwith (y) z;\\n\")\n\texpectPrinted(t, \"with (y) z; (import(x))\", \"with (y) z;\\nimport(x);\\n\")\n\texpectPrinted(t, \"with (y) z; (import('x'))\", \"with (y) z;\\nimport(\\\"x\\\");\\n\")\n\n\texpectParseError(t, \"import.meta; with (y) z\", importMeta)\n\texpectParseError(t, \"with (y) z; import.meta\", importMeta)\n\texpectParseError(t, \"(import.meta); with (y) z\", importMeta)\n\texpectParseError(t, \"with (y) z; (import.meta)\", importMeta)\n\texpectParseError(t, \"import 'x'; with (y) z\", importStatement)\n\texpectParseError(t, \"import * as x from 'x'; with (y) z\", importStatement)\n\texpectParseError(t, \"import x from 'x'; with (y) z\", importStatement)\n\texpectParseError(t, \"import {x} from 'x'; with (y) z\", importStatement)\n\n\texpectParseError(t, \"export {}; with (y) z\", exportKeyword)\n\texpectParseError(t, \"export let x; with (y) z\", exportKeyword)\n\texpectParseError(t, \"export function x() {} with (y) z\", exportKeyword)\n\texpectParseError(t, \"export class x {} with (y) z\", exportKeyword)\n\n\texpectParseError(t, \"await 0; with (y) z\", tlaKeyword)\n\texpectParseError(t, \"with (y) z; await 0\", tlaKeyword)\n\texpectParseError(t, \"for await (x of y); with (y) z\", tlaKeyword)\n\texpectParseError(t, \"with (y) z; for await (x of y);\", tlaKeyword)\n\texpectParseError(t, \"await using x = _; with (y) z\", tlaKeyword)\n\texpectParseError(t, \"with (y) z; await using x = _\", tlaKeyword)\n\texpectParseError(t, \"for (await using x of _) ; with (y) z\", tlaKeyword)\n\texpectParseError(t, \"with (y) z; for (await using x of _) ;\", tlaKeyword)\n\n\tfAlreadyDeclaredError := \"<stdin>: ERROR: The symbol \\\"f\\\" has already been declared\\n\" +\n\t\t\"<stdin>: NOTE: The symbol \\\"f\\\" was originally declared here:\\n\"\n\tnestedNote := \"<stdin>: NOTE: Duplicate function declarations are not allowed in nested blocks\"\n\tmoduleNote := \"<stdin>: NOTE: Duplicate top-level function declarations are not allowed in an ECMAScript module. \" +\n\t\t\"This file is considered to be an ECMAScript module because of the \\\"export\\\" keyword here:\\n\"\n\n\tcases := []string{\n\t\t\"function f() {} function f() {}\",\n\t\t\"function f() {} function *f() {}\",\n\t\t\"function *f() {} function f() {}\",\n\t\t\"function f() {} async function f() {}\",\n\t\t\"async function f() {} function f() {}\",\n\t\t\"function f() {} async function *f() {}\",\n\t\t\"async function *f() {} function f() {}\",\n\t}\n\n\tfor _, c := range cases {\n\t\texpectParseError(t, c, \"\")\n\t\texpectParseError(t, \"'use strict'; \"+c, \"\")\n\t\texpectParseError(t, \"function foo() { 'use strict'; \"+c+\" }\", \"\")\n\t}\n\n\texpectParseError(t, \"function f() {} function f() {} export {}\", fAlreadyDeclaredError+moduleNote)\n\texpectParseError(t, \"function f() {} function *f() {} export {}\", fAlreadyDeclaredError+moduleNote)\n\texpectParseError(t, \"function f() {} async function f() {} export {}\", fAlreadyDeclaredError+moduleNote)\n\texpectParseError(t, \"function *f() {} function f() {} export {}\", fAlreadyDeclaredError+moduleNote)\n\texpectParseError(t, \"async function f() {} function f() {} export {}\", fAlreadyDeclaredError+moduleNote)\n\n\texpectParseError(t, \"'use strict'; { function f() {} function f() {} }\",\n\t\tfAlreadyDeclaredError+nestedNote+\" in strict mode. Strict mode is triggered by the \\\"use strict\\\" directive here:\\n\")\n\texpectParseError(t, \"'use strict'; switch (0) { case 1: function f() {} default: function f() {} }\",\n\t\tfAlreadyDeclaredError+nestedNote+\" in strict mode. Strict mode is triggered by the \\\"use strict\\\" directive here:\\n\")\n\n\texpectParseError(t, \"function foo() { 'use strict'; { function f() {} function f() {} } }\",\n\t\tfAlreadyDeclaredError+nestedNote+\" in strict mode. Strict mode is triggered by the \\\"use strict\\\" directive here:\\n\")\n\texpectParseError(t, \"function foo() { 'use strict'; switch (0) { case 1: function f() {} default: function f() {} } }\",\n\t\tfAlreadyDeclaredError+nestedNote+\" in strict mode. Strict mode is triggered by the \\\"use strict\\\" directive here:\\n\")\n\n\texpectParseError(t, \"{ function f() {} function f() {} } export {}\",\n\t\tfAlreadyDeclaredError+nestedNote+\" in an ECMAScript module. This file is considered to be an ECMAScript module because of the \\\"export\\\" keyword here:\\n\")\n\texpectParseError(t, \"switch (0) { case 1: function f() {} default: function f() {} } export {}\",\n\t\tfAlreadyDeclaredError+nestedNote+\" in an ECMAScript module. This file is considered to be an ECMAScript module because of the \\\"export\\\" keyword here:\\n\")\n\n\texpectParseError(t, \"var x; var x\", \"\")\n\texpectParseError(t, \"'use strict'; var x; var x\", \"\")\n\texpectParseError(t, \"var x; var x; export {}\", \"\")\n}\n\nfunc TestExponentiation(t *testing.T) {\n\texpectPrinted(t, \"--x ** 2\", \"--x ** 2;\\n\")\n\texpectPrinted(t, \"++x ** 2\", \"++x ** 2;\\n\")\n\texpectPrinted(t, \"x-- ** 2\", \"x-- ** 2;\\n\")\n\texpectPrinted(t, \"x++ ** 2\", \"x++ ** 2;\\n\")\n\n\texpectPrinted(t, \"(-x) ** 2\", \"(-x) ** 2;\\n\")\n\texpectPrinted(t, \"(+x) ** 2\", \"(+x) ** 2;\\n\")\n\texpectPrinted(t, \"(~x) ** 2\", \"(~x) ** 2;\\n\")\n\texpectPrinted(t, \"(!x) ** 2\", \"(!x) ** 2;\\n\")\n\texpectPrinted(t, \"(-1) ** 2\", \"(-1) ** 2;\\n\")\n\texpectPrinted(t, \"(+1) ** 2\", \"1 ** 2;\\n\")\n\texpectPrinted(t, \"(~1) ** 2\", \"(~1) ** 2;\\n\")\n\texpectPrinted(t, \"(!1) ** 2\", \"false ** 2;\\n\")\n\texpectPrinted(t, \"(void x) ** 2\", \"(void x) ** 2;\\n\")\n\texpectPrinted(t, \"(delete x) ** 2\", \"(delete x) ** 2;\\n\")\n\texpectPrinted(t, \"(typeof x) ** 2\", \"(typeof x) ** 2;\\n\")\n\texpectPrinted(t, \"undefined ** 2\", \"(void 0) ** 2;\\n\")\n\n\texpectParseError(t, \"-x ** 2\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"+x ** 2\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"~x ** 2\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"!x ** 2\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"void x ** 2\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"delete x ** 2\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"typeof x ** 2\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\n\texpectParseError(t, \"-x.y() ** 2\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"+x.y() ** 2\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"~x.y() ** 2\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"!x.y() ** 2\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"void x.y() ** 2\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"delete x.y() ** 2\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"typeof x.y() ** 2\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\n\t// https://github.com/tc39/ecma262/issues/2197\n\texpectParseError(t, \"delete x ** 0\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"delete x.prop ** 0\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"delete x[0] ** 0\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"delete x?.prop ** 0\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"void x ** 0\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"typeof x ** 0\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"+x ** 0\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"-x ** 0\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"~x ** 0\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"!x ** 0\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"await x ** 0\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectParseError(t, \"await -x ** 0\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectPrinted(t, \"(delete x) ** 0\", \"(delete x) ** 0;\\n\")\n\texpectPrinted(t, \"(delete x.prop) ** 0\", \"(delete x.prop) ** 0;\\n\")\n\texpectPrinted(t, \"(delete x[0]) ** 0\", \"(delete x[0]) ** 0;\\n\")\n\texpectPrinted(t, \"(delete x?.prop) ** 0\", \"(delete x?.prop) ** 0;\\n\")\n\texpectPrinted(t, \"(void x) ** 0\", \"(void x) ** 0;\\n\")\n\texpectPrinted(t, \"(typeof x) ** 0\", \"(typeof x) ** 0;\\n\")\n\texpectPrinted(t, \"(+x) ** 0\", \"(+x) ** 0;\\n\")\n\texpectPrinted(t, \"(-x) ** 0\", \"(-x) ** 0;\\n\")\n\texpectPrinted(t, \"(~x) ** 0\", \"(~x) ** 0;\\n\")\n\texpectPrinted(t, \"(!x) ** 0\", \"(!x) ** 0;\\n\")\n\texpectPrinted(t, \"(await x) ** 0\", \"(await x) ** 0;\\n\")\n\texpectPrinted(t, \"(await -x) ** 0\", \"(await -x) ** 0;\\n\")\n}\n\nfunc TestAwait(t *testing.T) {\n\texpectPrinted(t, \"await x\", \"await x;\\n\")\n\texpectPrinted(t, \"await +x\", \"await +x;\\n\")\n\texpectPrinted(t, \"await -x\", \"await -x;\\n\")\n\texpectPrinted(t, \"await ~x\", \"await ~x;\\n\")\n\texpectPrinted(t, \"await !x\", \"await !x;\\n\")\n\texpectPrinted(t, \"await --x\", \"await --x;\\n\")\n\texpectPrinted(t, \"await ++x\", \"await ++x;\\n\")\n\texpectPrinted(t, \"await x--\", \"await x--;\\n\")\n\texpectPrinted(t, \"await x++\", \"await x++;\\n\")\n\texpectPrinted(t, \"await void x\", \"await void x;\\n\")\n\texpectPrinted(t, \"await typeof x\", \"await typeof x;\\n\")\n\texpectPrinted(t, \"await (x * y)\", \"await (x * y);\\n\")\n\texpectPrinted(t, \"await (x ** y)\", \"await (x ** y);\\n\")\n\n\texpectParseError(t, \"var { await } = {}\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"async function f() { var { await } = {} }\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"async function* f() { var { await } = {} }\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"class C { async f() { var { await } = {} } }\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"class C { async* f() { var { await } = {} } }\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"class C { static { var { await } = {} } }\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\n\texpectParseError(t, \"var {} = { await }\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"async function f() { var {} = { await } }\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"async function* f() { var {} = { await } }\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"class C { async f() { var {} = { await } } }\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"class C { async* f() { var {} = { await } } }\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"class C { static { var {} = { await } } }\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\n\texpectParseError(t, \"await delete x\",\n\t\t`<stdin>: ERROR: Delete of a bare identifier cannot be used in an ECMAScript module\n<stdin>: NOTE: This file is considered to be an ECMAScript module because of the top-level \"await\" keyword here:\n`)\n\texpectPrinted(t, \"async function f() { await delete x }\", \"async function f() {\\n  await delete x;\\n}\\n\")\n\n\t// Can't use await at the top-level without top-level await\n\terr := \"<stdin>: ERROR: Top-level await is not available in the configured target environment\\n\"\n\texpectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, \"await x;\", err)\n\texpectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, \"if (true) await x;\", err)\n\texpectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, \"if (false) await x;\", \"if (false) x;\\n\")\n\texpectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, \"with (x) y; if (false) await x;\",\n\t\t\"<stdin>: ERROR: With statements cannot be used in an ECMAScript module\\n\"+\n\t\t\t\"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the top-level \\\"await\\\" keyword here:\\n\")\n}\n\nfunc TestRegExp(t *testing.T) {\n\texpectPrinted(t, \"/x/d\", \"/x/d;\\n\")\n\texpectPrinted(t, \"/x/g\", \"/x/g;\\n\")\n\texpectPrinted(t, \"/x/i\", \"/x/i;\\n\")\n\texpectPrinted(t, \"/x/m\", \"/x/m;\\n\")\n\texpectPrinted(t, \"/x/s\", \"/x/s;\\n\")\n\texpectPrinted(t, \"/x/u\", \"/x/u;\\n\")\n\texpectPrinted(t, \"/x/y\", \"/x/y;\\n\")\n\n\texpectParseError(t, \"/)/\", \"<stdin>: ERROR: Unexpected \\\")\\\" in regular expression\\n\")\n\texpectPrinted(t, \"/[\\\\])]/\", \"/[\\\\])]/;\\n\")\n\n\texpectParseError(t, \"/x/msuygig\",\n\t\t`<stdin>: ERROR: Duplicate flag \"g\" in regular expression\n<stdin>: NOTE: The first \"g\" was here:\n`)\n}\n\nfunc TestUnicodeIdentifierNames(t *testing.T) {\n\t// There are two code points that are valid in identifiers in ES5 but not in ES6+:\n\t//\n\t//   U+30FB KATAKANA MIDDLE DOT\n\t//   U+FF65 HALFWIDTH KATAKANA MIDDLE DOT\n\t//\n\texpectPrinted(t, \"x = {x・: 0}\", \"x = { \\\"x・\\\": 0 };\\n\")\n\texpectPrinted(t, \"x = {x･: 0}\", \"x = { \\\"x･\\\": 0 };\\n\")\n\texpectPrinted(t, \"x = {xπ: 0}\", \"x = { xπ: 0 };\\n\")\n\texpectPrinted(t, \"x = y.x・\", \"x = y[\\\"x・\\\"];\\n\")\n\texpectPrinted(t, \"x = y.x･\", \"x = y[\\\"x･\\\"];\\n\")\n\texpectPrinted(t, \"x = y.xπ\", \"x = y.xπ;\\n\")\n}\n\nfunc TestIdentifierEscapes(t *testing.T) {\n\texpectPrinted(t, \"var _\\\\u0076\\\\u0061\\\\u0072\", \"var _var;\\n\")\n\texpectParseError(t, \"var \\\\u0076\\\\u0061\\\\u0072\", \"<stdin>: ERROR: Expected identifier but found \\\"\\\\\\\\u0076\\\\\\\\u0061\\\\\\\\u0072\\\"\\n\")\n\texpectParseError(t, \"\\\\u0076\\\\u0061\\\\u0072 foo\", \"<stdin>: ERROR: Unexpected \\\"\\\\\\\\u0076\\\\\\\\u0061\\\\\\\\u0072\\\"\\n\")\n\n\texpectPrinted(t, \"foo._\\\\u0076\\\\u0061\\\\u0072\", \"foo._var;\\n\")\n\texpectPrinted(t, \"foo.\\\\u0076\\\\u0061\\\\u0072\", \"foo.var;\\n\")\n\n\texpectParseError(t, \"\\u200Ca\", \"<stdin>: ERROR: Unexpected \\\"\\\\u200c\\\"\\n\")\n\texpectParseError(t, \"\\u200Da\", \"<stdin>: ERROR: Unexpected \\\"\\\\u200d\\\"\\n\")\n}\n\nfunc TestSpecialIdentifiers(t *testing.T) {\n\texpectPrinted(t, \"exports\", \"exports;\\n\")\n\texpectPrinted(t, \"require\", \"require;\\n\")\n\texpectPrinted(t, \"module\", \"module;\\n\")\n}\n\nfunc TestDecls(t *testing.T) {\n\texpectParseError(t, \"var x = 0\", \"\")\n\texpectParseError(t, \"let x = 0\", \"\")\n\texpectParseError(t, \"const x = 0\", \"\")\n\texpectParseError(t, \"for (var x = 0;;) ;\", \"\")\n\texpectParseError(t, \"for (let x = 0;;) ;\", \"\")\n\texpectParseError(t, \"for (const x = 0;;) ;\", \"\")\n\n\texpectParseError(t, \"for (var x in y) ;\", \"\")\n\texpectParseError(t, \"for (let x in y) ;\", \"\")\n\texpectParseError(t, \"for (const x in y) ;\", \"\")\n\texpectParseError(t, \"for (var x of y) ;\", \"\")\n\texpectParseError(t, \"for (let x of y) ;\", \"\")\n\texpectParseError(t, \"for (const x of y) ;\", \"\")\n\n\texpectParseError(t, \"var x\", \"\")\n\texpectParseError(t, \"let x\", \"\")\n\texpectParseError(t, \"const x\", \"<stdin>: ERROR: The constant \\\"x\\\" must be initialized\\n\")\n\texpectParseError(t, \"const {}\", \"<stdin>: ERROR: This constant must be initialized\\n\")\n\texpectParseError(t, \"const []\", \"<stdin>: ERROR: This constant must be initialized\\n\")\n\texpectParseError(t, \"for (var x;;) ;\", \"\")\n\texpectParseError(t, \"for (let x;;) ;\", \"\")\n\texpectParseError(t, \"for (const x;;) ;\", \"<stdin>: ERROR: The constant \\\"x\\\" must be initialized\\n\")\n\texpectParseError(t, \"for (const {};;) ;\", \"<stdin>: ERROR: This constant must be initialized\\n\")\n\texpectParseError(t, \"for (const [];;) ;\", \"<stdin>: ERROR: This constant must be initialized\\n\")\n\n\t// Make sure bindings are visited during parsing\n\texpectPrinted(t, \"var {[x]: y} = {}\", \"var { [x]: y } = {};\\n\")\n\texpectPrinted(t, \"var {...x} = {}\", \"var { ...x } = {};\\n\")\n\n\t// Test destructuring patterns\n\texpectPrinted(t, \"var [...x] = []\", \"var [...x] = [];\\n\")\n\texpectPrinted(t, \"var {...x} = {}\", \"var { ...x } = {};\\n\")\n\texpectPrinted(t, \"([...x] = []) => {}\", \"([...x] = []) => {\\n};\\n\")\n\texpectPrinted(t, \"({...x} = {}) => {}\", \"({ ...x } = {}) => {\\n};\\n\")\n\n\texpectParseError(t, \"var [...x,] = []\", \"<stdin>: ERROR: Unexpected \\\",\\\" after rest pattern\\n\")\n\texpectParseError(t, \"var {...x,} = {}\", \"<stdin>: ERROR: Unexpected \\\",\\\" after rest pattern\\n\")\n\texpectParseError(t, \"([...x,] = []) => {}\", \"<stdin>: ERROR: Invalid binding pattern\\n\")\n\texpectParseError(t, \"({...x,} = {}) => {}\", \"<stdin>: ERROR: Invalid binding pattern\\n\")\n\n\texpectPrinted(t, \"[b, ...c] = d\", \"[b, ...c] = d;\\n\")\n\texpectPrinted(t, \"([b, ...c] = d)\", \"[b, ...c] = d;\\n\")\n\texpectPrinted(t, \"({b, ...c} = d)\", \"({ b, ...c } = d);\\n\")\n\texpectPrinted(t, \"({a = b} = c)\", \"({ a = b } = c);\\n\")\n\texpectPrinted(t, \"({a: b = c} = d)\", \"({ a: b = c } = d);\\n\")\n\texpectPrinted(t, \"({a: b.c} = d)\", \"({ a: b.c } = d);\\n\")\n\texpectPrinted(t, \"[a = {}] = b\", \"[a = {}] = b;\\n\")\n\texpectPrinted(t, \"[[...a, b].x] = c\", \"[[...a, b].x] = c;\\n\")\n\texpectPrinted(t, \"[{...a, b}.x] = c\", \"[{ ...a, b }.x] = c;\\n\")\n\texpectPrinted(t, \"({x: [...a, b].x} = c)\", \"({ x: [...a, b].x } = c);\\n\")\n\texpectPrinted(t, \"({x: {...a, b}.x} = c)\", \"({ x: { ...a, b }.x } = c);\\n\")\n\texpectPrinted(t, \"[x = [...a, b]] = c\", \"[x = [...a, b]] = c;\\n\")\n\texpectPrinted(t, \"[x = {...a, b}] = c\", \"[x = { ...a, b }] = c;\\n\")\n\texpectPrinted(t, \"({x = [...a, b]} = c)\", \"({ x = [...a, b] } = c);\\n\")\n\texpectPrinted(t, \"({x = {...a, b}} = c)\", \"({ x = { ...a, b } } = c);\\n\")\n\n\texpectPrinted(t, \"(x = y)\", \"x = y;\\n\")\n\texpectPrinted(t, \"([] = [])\", \"[] = [];\\n\")\n\texpectPrinted(t, \"({} = {})\", \"({} = {});\\n\")\n\texpectPrinted(t, \"([[]] = [[]])\", \"[[]] = [[]];\\n\")\n\texpectPrinted(t, \"({x: {}} = {x: {}})\", \"({ x: {} } = { x: {} });\\n\")\n\texpectPrinted(t, \"(x) = y\", \"x = y;\\n\")\n\texpectParseError(t, \"([]) = []\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"({}) = {}\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"[([])] = [[]]\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"({x: ({})} = {x: {}})\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"(([]) = []) => {}\", \"<stdin>: ERROR: Invalid binding pattern\\n\")\n\texpectParseError(t, \"(({}) = {}) => {}\", \"<stdin>: ERROR: Invalid binding pattern\\n\")\n\texpectParseError(t, \"function f(([]) = []) {}\", \"<stdin>: ERROR: Expected identifier but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"function f(({}) = {}) {}\", \"<stdin>: ERROR: Expected identifier but found \\\"(\\\"\\n\")\n\n\texpectPrinted(t, \"for (x in y) ;\", \"for (x in y) ;\\n\")\n\texpectPrinted(t, \"for ([] in y) ;\", \"for ([] in y) ;\\n\")\n\texpectPrinted(t, \"for ({} in y) ;\", \"for ({} in y) ;\\n\")\n\texpectPrinted(t, \"for ((x) in y) ;\", \"for (x in y) ;\\n\")\n\texpectParseError(t, \"for (([]) in y) ;\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"for (({}) in y) ;\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\n\texpectPrinted(t, \"for (x of y) ;\", \"for (x of y) ;\\n\")\n\texpectPrinted(t, \"for ([] of y) ;\", \"for ([] of y) ;\\n\")\n\texpectPrinted(t, \"for ({} of y) ;\", \"for ({} of y) ;\\n\")\n\texpectPrinted(t, \"for ((x) of y) ;\", \"for (x of y) ;\\n\")\n\texpectParseError(t, \"for (([]) of y) ;\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"for (({}) of y) ;\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\n\texpectParseError(t, \"[[...a, b]] = c\", \"<stdin>: ERROR: Unexpected \\\",\\\" after rest pattern\\n\")\n\texpectParseError(t, \"[{...a, b}] = c\", \"<stdin>: ERROR: Unexpected \\\",\\\" after rest pattern\\n\")\n\texpectParseError(t, \"({x: [...a, b]} = c)\", \"<stdin>: ERROR: Unexpected \\\",\\\" after rest pattern\\n\")\n\texpectParseError(t, \"({x: {...a, b}} = c)\", \"<stdin>: ERROR: Unexpected \\\",\\\" after rest pattern\\n\")\n\texpectParseError(t, \"[b, ...c,] = d\", \"<stdin>: ERROR: Unexpected \\\",\\\" after rest pattern\\n\")\n\texpectParseError(t, \"([b, ...c,] = d)\", \"<stdin>: ERROR: Unexpected \\\",\\\" after rest pattern\\n\")\n\texpectParseError(t, \"({b, ...c,} = d)\", \"<stdin>: ERROR: Unexpected \\\",\\\" after rest pattern\\n\")\n\texpectParseError(t, \"({a = b})\", \"<stdin>: ERROR: Unexpected \\\"=\\\"\\n\")\n\texpectParseError(t, \"({x = {a = b}} = c)\", \"<stdin>: ERROR: Unexpected \\\"=\\\"\\n\")\n\texpectParseError(t, \"[a = {b = c}] = d\", \"<stdin>: ERROR: Unexpected \\\"=\\\"\\n\")\n\n\texpectPrinted(t, \"for ([{a = {}}] in b) {}\", \"for ([{ a = {} }] in b) {\\n}\\n\")\n\texpectPrinted(t, \"for ([{a = {}}] of b) {}\", \"for ([{ a = {} }] of b) {\\n}\\n\")\n\texpectPrinted(t, \"for ({a = {}} in b) {}\", \"for ({ a = {} } in b) {\\n}\\n\")\n\texpectPrinted(t, \"for ({a = {}} of b) {}\", \"for ({ a = {} } of b) {\\n}\\n\")\n\n\texpectParseError(t, \"({a = {}} in b)\", \"<stdin>: ERROR: Unexpected \\\"=\\\"\\n\")\n\texpectParseError(t, \"[{a = {}}]\\nof()\", \"<stdin>: ERROR: Unexpected \\\"=\\\"\\n\")\n\texpectParseError(t, \"for ([...a, b] in c) {}\", \"<stdin>: ERROR: Unexpected \\\",\\\" after rest pattern\\n\")\n\texpectParseError(t, \"for ([...a, b] of c) {}\", \"<stdin>: ERROR: Unexpected \\\",\\\" after rest pattern\\n\")\n}\n\nfunc TestBreakAndContinue(t *testing.T) {\n\texpectParseError(t, \"break\", \"<stdin>: ERROR: Cannot use \\\"break\\\" here:\\n\")\n\texpectParseError(t, \"continue\", \"<stdin>: ERROR: Cannot use \\\"continue\\\" here:\\n\")\n\n\texpectParseError(t, \"x: { break }\", \"<stdin>: ERROR: Cannot use \\\"break\\\" here:\\n\")\n\texpectParseError(t, \"x: { break x }\", \"\")\n\texpectParseError(t, \"x: { continue }\", \"<stdin>: ERROR: Cannot use \\\"continue\\\" here:\\n\")\n\texpectParseError(t, \"x: { continue x }\", \"<stdin>: ERROR: Cannot continue to label \\\"x\\\"\\n\")\n\n\texpectParseError(t, \"while (1) break\", \"\")\n\texpectParseError(t, \"while (1) continue\", \"\")\n\texpectParseError(t, \"while (1) { function foo() { break } }\", \"<stdin>: ERROR: Cannot use \\\"break\\\" here:\\n\")\n\texpectParseError(t, \"while (1) { function foo() { continue } }\", \"<stdin>: ERROR: Cannot use \\\"continue\\\" here:\\n\")\n\texpectParseError(t, \"x: while (1) break x\", \"\")\n\texpectParseError(t, \"x: while (1) continue x\", \"\")\n\texpectParseError(t, \"x: while (1) y: { break x }\", \"\")\n\texpectParseError(t, \"x: while (1) y: { continue x }\", \"\")\n\texpectParseError(t, \"x: while (1) y: { break y }\", \"\")\n\texpectParseError(t, \"x: while (1) y: { continue y }\", \"<stdin>: ERROR: Cannot continue to label \\\"y\\\"\\n\")\n\texpectParseError(t, \"x: while (1) { function foo() { break x } }\", \"<stdin>: ERROR: There is no containing label named \\\"x\\\"\\n\")\n\texpectParseError(t, \"x: while (1) { function foo() { continue x } }\", \"<stdin>: ERROR: There is no containing label named \\\"x\\\"\\n\")\n\n\texpectParseError(t, \"switch (1) { case 1: break }\", \"\")\n\texpectParseError(t, \"switch (1) { case 1: continue }\", \"<stdin>: ERROR: Cannot use \\\"continue\\\" here:\\n\")\n\texpectParseError(t, \"x: switch (1) { case 1: break x }\", \"\")\n\texpectParseError(t, \"x: switch (1) { case 1: continue x }\", \"<stdin>: ERROR: Cannot continue to label \\\"x\\\"\\n\")\n}\n\nfunc TestFor(t *testing.T) {\n\texpectParseError(t, \"for (; in x) ;\", \"<stdin>: ERROR: Unexpected \\\"in\\\"\\n\")\n\texpectParseError(t, \"for (; of x) ;\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"for (; in; ) ;\", \"<stdin>: ERROR: Unexpected \\\"in\\\"\\n\")\n\texpectPrinted(t, \"for (; of; ) ;\", \"for (; of; ) ;\\n\")\n\n\texpectPrinted(t, \"for (a in b) ;\", \"for (a in b) ;\\n\")\n\texpectPrinted(t, \"for (var a in b) ;\", \"for (var a in b) ;\\n\")\n\texpectPrinted(t, \"for (let a in b) ;\", \"for (let a in b) ;\\n\")\n\texpectPrinted(t, \"for (const a in b) ;\", \"for (const a in b) ;\\n\")\n\texpectPrinted(t, \"for (a in b, c) ;\", \"for (a in b, c) ;\\n\")\n\texpectPrinted(t, \"for (a in b = c) ;\", \"for (a in b = c) ;\\n\")\n\texpectPrinted(t, \"for (var a in b, c) ;\", \"for (var a in b, c) ;\\n\")\n\texpectPrinted(t, \"for (var a in b = c) ;\", \"for (var a in b = c) ;\\n\")\n\texpectParseError(t, \"for (var a, b in b) ;\", \"<stdin>: ERROR: for-in loops must have a single declaration\\n\")\n\texpectParseError(t, \"for (let a, b in b) ;\", \"<stdin>: ERROR: for-in loops must have a single declaration\\n\")\n\texpectParseError(t, \"for (const a, b in b) ;\", \"<stdin>: ERROR: for-in loops must have a single declaration\\n\")\n\n\texpectPrinted(t, \"for (a of b) ;\", \"for (a of b) ;\\n\")\n\texpectPrinted(t, \"for (var a of b) ;\", \"for (var a of b) ;\\n\")\n\texpectPrinted(t, \"for (let a of b) ;\", \"for (let a of b) ;\\n\")\n\texpectPrinted(t, \"for (const a of b) ;\", \"for (const a of b) ;\\n\")\n\texpectPrinted(t, \"for (a of b = c) ;\", \"for (a of b = c) ;\\n\")\n\texpectPrinted(t, \"for (var a of b = c) ;\", \"for (var a of b = c) ;\\n\")\n\texpectParseError(t, \"for (a of b, c) ;\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\",\\\"\\n\")\n\texpectParseError(t, \"for (var a of b, c) ;\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\",\\\"\\n\")\n\texpectParseError(t, \"for (var a, b of b) ;\", \"<stdin>: ERROR: for-of loops must have a single declaration\\n\")\n\texpectParseError(t, \"for (let a, b of b) ;\", \"<stdin>: ERROR: for-of loops must have a single declaration\\n\")\n\texpectParseError(t, \"for (const a, b of b) ;\", \"<stdin>: ERROR: for-of loops must have a single declaration\\n\")\n\n\t// Avoid the initializer starting with \"let\" token\n\texpectPrinted(t, \"for ((let) of bar);\", \"for ((let) of bar) ;\\n\")\n\texpectPrinted(t, \"for ((let).foo of bar);\", \"for ((let).foo of bar) ;\\n\")\n\texpectPrinted(t, \"for ((let.foo) of bar);\", \"for ((let).foo of bar) ;\\n\")\n\texpectPrinted(t, \"for ((let``.foo) of bar);\", \"for ((let)``.foo of bar) ;\\n\")\n\texpectParseError(t, \"for (let.foo of bar);\", \"<stdin>: ERROR: \\\"let\\\" must be wrapped in parentheses to be used as an expression here:\\n\")\n\texpectParseError(t, \"for (let().foo of bar);\", \"<stdin>: ERROR: \\\"let\\\" must be wrapped in parentheses to be used as an expression here:\\n\")\n\texpectParseError(t, \"for (let``.foo of bar);\", \"<stdin>: ERROR: \\\"let\\\" must be wrapped in parentheses to be used as an expression here:\\n\")\n\n\texpectPrinted(t, \"for (var x = 0 in y) ;\", \"x = 0;\\nfor (var x in y) ;\\n\") // This is a weird special-case\n\texpectParseError(t, \"for (let x = 0 in y) ;\", \"<stdin>: ERROR: for-in loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (const x = 0 in y) ;\", \"<stdin>: ERROR: for-in loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (var x = 0 of y) ;\", \"<stdin>: ERROR: for-of loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (let x = 0 of y) ;\", \"<stdin>: ERROR: for-of loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (const x = 0 of y) ;\", \"<stdin>: ERROR: for-of loop variables cannot have an initializer\\n\")\n\n\texpectParseError(t, \"for (var [x] = y in z) ;\", \"<stdin>: ERROR: for-in loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (let [x] = y in z) ;\", \"<stdin>: ERROR: for-in loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (const [x] = y in z) ;\", \"<stdin>: ERROR: for-in loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (var [x] = y of z) ;\", \"<stdin>: ERROR: for-of loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (let [x] = y of z) ;\", \"<stdin>: ERROR: for-of loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (const [x] = y of z) ;\", \"<stdin>: ERROR: for-of loop variables cannot have an initializer\\n\")\n\n\texpectParseError(t, \"for (var {x} = y in z) ;\", \"<stdin>: ERROR: for-in loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (let {x} = y in z) ;\", \"<stdin>: ERROR: for-in loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (const {x} = y in z) ;\", \"<stdin>: ERROR: for-in loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (var {x} = y of z) ;\", \"<stdin>: ERROR: for-of loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (let {x} = y of z) ;\", \"<stdin>: ERROR: for-of loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (const {x} = y of z) ;\", \"<stdin>: ERROR: for-of loop variables cannot have an initializer\\n\")\n\n\t// Make sure \"in\" rules are enabled\n\texpectPrinted(t, \"for (var x = () => a in b);\", \"x = () => a;\\nfor (var x in b) ;\\n\")\n\texpectPrinted(t, \"for (var x = a + b in c);\", \"x = a + b;\\nfor (var x in c) ;\\n\")\n\n\t// Make sure \"in\" rules are disabled\n\texpectPrinted(t, \"for (var x = `${y in z}`;;);\", \"for (var x = `${y in z}`; ; ) ;\\n\")\n\texpectPrinted(t, \"for (var {[x in y]: z} = {};;);\", \"for (var { [x in y]: z } = {}; ; ) ;\\n\")\n\texpectPrinted(t, \"for (var {x = y in z} = {};;);\", \"for (var { x = y in z } = {}; ; ) ;\\n\")\n\texpectPrinted(t, \"for (var [x = y in z] = {};;);\", \"for (var [x = y in z] = {}; ; ) ;\\n\")\n\texpectPrinted(t, \"for (var {x: y = z in w} = {};;);\", \"for (var { x: y = z in w } = {}; ; ) ;\\n\")\n\texpectPrinted(t, \"for (var x = (a in b);;);\", \"for (var x = (a in b); ; ) ;\\n\")\n\texpectPrinted(t, \"for (var x = [a in b];;);\", \"for (var x = [a in b]; ; ) ;\\n\")\n\texpectPrinted(t, \"for (var x = y(a in b);;);\", \"for (var x = y(a in b); ; ) ;\\n\")\n\texpectPrinted(t, \"for (var x = {y: a in b};;);\", \"for (var x = { y: a in b }; ; ) ;\\n\")\n\texpectPrinted(t, \"for (a ? b in c : d;;);\", \"for (a ? b in c : d; ; ) ;\\n\")\n\texpectPrinted(t, \"for (var x = () => { a in b };;);\", \"for (var x = () => {\\n  a in b;\\n}; ; ) ;\\n\")\n\texpectPrinted(t, \"for (var x = async () => { a in b };;);\", \"for (var x = async () => {\\n  a in b;\\n}; ; ) ;\\n\")\n\texpectPrinted(t, \"for (var x = function() { a in b };;);\", \"for (var x = function() {\\n  a in b;\\n}; ; ) ;\\n\")\n\texpectPrinted(t, \"for (var x = async function() { a in b };;);\", \"for (var x = async function() {\\n  a in b;\\n}; ; ) ;\\n\")\n\texpectPrinted(t, \"for (var x = class { [a in b]() {} };;);\", \"for (var x = class {\\n  [a in b]() {\\n  }\\n}; ; ) ;\\n\")\n\texpectParseError(t, \"for (var x = class extends a in b {};;);\", \"<stdin>: ERROR: Expected \\\"{\\\" but found \\\"in\\\"\\n\")\n\n\terrorText := `<stdin>: WARNING: This assignment will throw because \"x\" is a constant\n<stdin>: NOTE: The symbol \"x\" was declared a constant here:\n`\n\texpectParseError(t, \"for (var x = 0; ; x = 1) ;\", \"\")\n\texpectParseError(t, \"for (let x = 0; ; x = 1) ;\", \"\")\n\texpectParseError(t, \"for (const x = 0; ; x = 1) ;\", errorText)\n\texpectParseError(t, \"for (var x = 0; ; x++) ;\", \"\")\n\texpectParseError(t, \"for (let x = 0; ; x++) ;\", \"\")\n\texpectParseError(t, \"for (const x = 0; ; x++) ;\", errorText)\n\n\texpectParseError(t, \"for (var x in y) x = 1\", \"\")\n\texpectParseError(t, \"for (let x in y) x = 1\", \"\")\n\texpectParseError(t, \"for (const x in y) x = 1\", errorText)\n\texpectParseError(t, \"for (var x in y) x++\", \"\")\n\texpectParseError(t, \"for (let x in y) x++\", \"\")\n\texpectParseError(t, \"for (const x in y) x++\", errorText)\n\n\texpectParseError(t, \"for (var x of y) x = 1\", \"\")\n\texpectParseError(t, \"for (let x of y) x = 1\", \"\")\n\texpectParseError(t, \"for (const x of y) x = 1\", errorText)\n\texpectParseError(t, \"for (var x of y) x++\", \"\")\n\texpectParseError(t, \"for (let x of y) x++\", \"\")\n\texpectParseError(t, \"for (const x of y) x++\", errorText)\n\n\texpectPrinted(t, \"async of => {}\", \"async (of) => {\\n};\\n\")\n\texpectPrinted(t, \"for ((async) of []) ;\", \"for ((async) of []) ;\\n\")\n\texpectPrinted(t, \"for (async.x of []) ;\", \"for (async.x of []) ;\\n\")\n\texpectPrinted(t, \"for (async of => {};;) ;\", \"for (async (of) => {\\n}; ; ) ;\\n\")\n\texpectPrinted(t, \"for (\\\\u0061sync of []) ;\", \"for ((async) of []) ;\\n\")\n\texpectPrinted(t, \"for await (async of []) ;\", \"for await (async of []) ;\\n\")\n\texpectParseError(t, \"for (async of []) ;\", \"<stdin>: ERROR: For loop initializers cannot start with \\\"async of\\\"\\n\")\n\texpectParseError(t, \"for (async o\\\\u0066 []) ;\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"o\\\\\\\\u0066\\\"\\n\")\n\texpectParseError(t, \"for await (async of => {}) ;\", \"<stdin>: ERROR: Expected \\\"of\\\" but found \\\")\\\"\\n\")\n\texpectParseError(t, \"for await (async of => {} of []) ;\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"for await (async o\\\\u0066 []) ;\", \"<stdin>: ERROR: Expected \\\"of\\\" but found \\\"o\\\\\\\\u0066\\\"\\n\")\n\n\t// Can't use await at the top-level without top-level await\n\terr := \"<stdin>: ERROR: Top-level await is not available in the configured target environment\\n\"\n\texpectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, \"for await (x of y);\", err)\n\texpectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, \"if (true) for await (x of y);\", err)\n\texpectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, \"if (false) for await (x of y);\", \"if (false) for (x of y) ;\\n\")\n\texpectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, \"with (x) y; if (false) for await (x of y);\",\n\t\t\"<stdin>: ERROR: With statements cannot be used in an ECMAScript module\\n\"+\n\t\t\t\"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the top-level \\\"await\\\" keyword here:\\n\")\n}\n\nfunc TestScope(t *testing.T) {\n\terrorText := `<stdin>: ERROR: The symbol \"x\" has already been declared\n<stdin>: NOTE: The symbol \"x\" was originally declared here:\n`\n\n\texpectParseError(t, \"var x; var y\", \"\")\n\texpectParseError(t, \"var x; let y\", \"\")\n\texpectParseError(t, \"let x; var y\", \"\")\n\texpectParseError(t, \"let x; let y\", \"\")\n\n\texpectParseError(t, \"var x; var x\", \"\")\n\texpectParseError(t, \"var x; let x\", errorText)\n\texpectParseError(t, \"let x; var x\", errorText)\n\texpectParseError(t, \"let x; let x\", errorText)\n\texpectParseError(t, \"function x() {} let x\", errorText)\n\texpectParseError(t, \"let x; function x() {}\", errorText)\n\n\texpectParseError(t, \"var x; {var x}\", \"\")\n\texpectParseError(t, \"var x; {let x}\", \"\")\n\texpectParseError(t, \"let x; {var x}\", errorText)\n\texpectParseError(t, \"let x; {let x}\", \"\")\n\texpectParseError(t, \"let x; {function x() {}}\", \"\")\n\n\texpectParseError(t, \"{var x} var x\", \"\")\n\texpectParseError(t, \"{var x} let x\", errorText)\n\texpectParseError(t, \"{let x} var x\", \"\")\n\texpectParseError(t, \"{let x} let x\", \"\")\n\texpectParseError(t, \"{function x() {}} let x\", \"\")\n\n\texpectParseError(t, \"{var x; {var x}}\", \"\")\n\texpectParseError(t, \"{var x; {let x}}\", \"\")\n\texpectParseError(t, \"{let x; {var x}}\", errorText)\n\texpectParseError(t, \"{let x; {let x}}\", \"\")\n\texpectParseError(t, \"{let x; {function x() {}}}\", \"\")\n\n\texpectParseError(t, \"{{var x} var x}\", \"\")\n\texpectParseError(t, \"{{var x} let x}\", errorText)\n\texpectParseError(t, \"{{let x} var x}\", \"\")\n\texpectParseError(t, \"{{let x} let x}\", \"\")\n\texpectParseError(t, \"{{function x() {}} let x}\", \"\")\n\n\texpectParseError(t, \"{var x} {var x}\", \"\")\n\texpectParseError(t, \"{var x} {let x}\", \"\")\n\texpectParseError(t, \"{let x} {var x}\", \"\")\n\texpectParseError(t, \"{let x} {let x}\", \"\")\n\texpectParseError(t, \"{let x} {function x() {}}\", \"\")\n\texpectParseError(t, \"{function x() {}} {let x}\", \"\")\n\n\texpectParseError(t, \"function x() {} {var x}\", \"\")\n\texpectParseError(t, \"function *x() {} {var x}\", \"\")\n\texpectParseError(t, \"async function x() {} {var x}\", \"\")\n\texpectParseError(t, \"async function *x() {} {var x}\", \"\")\n\n\texpectParseError(t, \"{var x} function x() {}\", \"\")\n\texpectParseError(t, \"{var x} function *x() {}\", \"\")\n\texpectParseError(t, \"{var x} async function x() {}\", \"\")\n\texpectParseError(t, \"{var x} async function *x() {}\", \"\")\n\n\texpectParseError(t, \"{ function x() {} {var x} }\", errorText)\n\texpectParseError(t, \"{ function *x() {} {var x} }\", errorText)\n\texpectParseError(t, \"{ async function x() {} {var x} }\", errorText)\n\texpectParseError(t, \"{ async function *x() {} {var x} }\", errorText)\n\n\texpectParseError(t, \"{ {var x} function x() {} }\", errorText)\n\texpectParseError(t, \"{ {var x} function *x() {} }\", errorText)\n\texpectParseError(t, \"{ {var x} async function x() {} }\", errorText)\n\texpectParseError(t, \"{ {var x} async function *x() {} }\", errorText)\n\n\texpectParseError(t, \"function f() { function x() {} {var x} }\", \"\")\n\texpectParseError(t, \"function f() { function *x() {} {var x} }\", \"\")\n\texpectParseError(t, \"function f() { async function x() {} {var x} }\", \"\")\n\texpectParseError(t, \"function f() { async function *x() {} {var x} }\", \"\")\n\n\texpectParseError(t, \"function f() { {var x} function x() {} }\", \"\")\n\texpectParseError(t, \"function f() { {var x} function *x() {} }\", \"\")\n\texpectParseError(t, \"function f() { {var x} async function x() {} }\", \"\")\n\texpectParseError(t, \"function f() { {var x} async function *x() {} }\", \"\")\n\n\texpectParseError(t, \"function f() { { function x() {} {var x} } }\", errorText)\n\texpectParseError(t, \"function f() { { function *x() {} {var x} } }\", errorText)\n\texpectParseError(t, \"function f() { { async function x() {} {var x} } }\", errorText)\n\texpectParseError(t, \"function f() { { async function *x() {} {var x} } }\", errorText)\n\n\texpectParseError(t, \"function f() { { {var x} function x() {} } }\", errorText)\n\texpectParseError(t, \"function f() { { {var x} function *x() {} } }\", errorText)\n\texpectParseError(t, \"function f() { { {var x} async function x() {} } }\", errorText)\n\texpectParseError(t, \"function f() { { {var x} async function *x() {} } }\", errorText)\n\n\texpectParseError(t, \"var x=1, x=2\", \"\")\n\texpectParseError(t, \"let x=1, x=2\", errorText)\n\texpectParseError(t, \"const x=1, x=2\", errorText)\n\n\texpectParseError(t, \"function foo(x) { var x }\", \"\")\n\texpectParseError(t, \"function foo(x) { let x }\", errorText)\n\texpectParseError(t, \"function foo(x) { const x = 0 }\", errorText)\n\texpectParseError(t, \"function foo() { var foo }\", \"\")\n\texpectParseError(t, \"function foo() { let foo }\", \"\")\n\texpectParseError(t, \"function foo() { const foo = 0 }\", \"\")\n\n\texpectParseError(t, \"(function foo(x) { var x })\", \"\")\n\texpectParseError(t, \"(function foo(x) { let x })\", errorText)\n\texpectParseError(t, \"(function foo(x) { const x = 0 })\", errorText)\n\texpectParseError(t, \"(function foo() { var foo })\", \"\")\n\texpectParseError(t, \"(function foo() { let foo })\", \"\")\n\texpectParseError(t, \"(function foo() { const foo = 0 })\", \"\")\n\n\texpectParseError(t, \"var x; function x() {}\", \"\")\n\texpectParseError(t, \"var x; function *x() {}\", \"\")\n\texpectParseError(t, \"var x; async function x() {}\", \"\")\n\texpectParseError(t, \"let x; function x() {}\", errorText)\n\texpectParseError(t, \"function x() {} var x\", \"\")\n\texpectParseError(t, \"function* x() {} var x\", \"\")\n\texpectParseError(t, \"async function x() {} var x\", \"\")\n\texpectParseError(t, \"function x() {} let x\", errorText)\n\texpectParseError(t, \"function x() {} function x() {}\", \"\")\n\n\texpectParseError(t, \"var x; class x {}\", errorText)\n\texpectParseError(t, \"let x; class x {}\", errorText)\n\texpectParseError(t, \"class x {} var x\", errorText)\n\texpectParseError(t, \"class x {} let x\", errorText)\n\texpectParseError(t, \"class x {} class x {}\", errorText)\n\n\texpectParseError(t, \"function x() {} function x() {}\", \"\")\n\texpectParseError(t, \"function x() {} function *x() {}\", \"\")\n\texpectParseError(t, \"function x() {} async function x() {}\", \"\")\n\texpectParseError(t, \"function *x() {} function x() {}\", \"\")\n\texpectParseError(t, \"function *x() {} function *x() {}\", \"\")\n\texpectParseError(t, \"async function x() {} function x() {}\", \"\")\n\texpectParseError(t, \"async function x() {} async function x() {}\", \"\")\n\n\texpectParseError(t, \"function f() { function x() {} function x() {} }\", \"\")\n\texpectParseError(t, \"function f() { function x() {} function *x() {} }\", \"\")\n\texpectParseError(t, \"function f() { function x() {} async function x() {} }\", \"\")\n\texpectParseError(t, \"function f() { function *x() {} function x() {} }\", \"\")\n\texpectParseError(t, \"function f() { function *x() {} function *x() {} }\", \"\")\n\texpectParseError(t, \"function f() { async function x() {} function x() {} }\", \"\")\n\texpectParseError(t, \"function f() { async function x() {} async function x() {} }\", \"\")\n\n\ttext := \"<stdin>: ERROR: The symbol \\\"x\\\" has already been declared\\n<stdin>: NOTE: The symbol \\\"x\\\" was originally declared here:\\n\"\n\tfor _, scope := range []string{\"\", \"with (x)\", \"while (x)\", \"if (x)\"} {\n\t\texpectParseError(t, scope+\"{ function x() {} function x() {} }\", \"\")\n\t\texpectParseError(t, scope+\"{ function x() {} function *x() {} }\", text)\n\t\texpectParseError(t, scope+\"{ function x() {} async function x() {} }\", text)\n\t\texpectParseError(t, scope+\"{ function *x() {} function x() {} }\", text)\n\t\texpectParseError(t, scope+\"{ function *x() {} function *x() {} }\", text)\n\t\texpectParseError(t, scope+\"{ async function x() {} function x() {} }\", text)\n\t\texpectParseError(t, scope+\"{ async function x() {} async function x() {} }\", text)\n\t}\n}\n\nfunc TestASI(t *testing.T) {\n\texpectParseError(t, \"throw\\n0\", \"<stdin>: ERROR: Unexpected newline after \\\"throw\\\"\\n\")\n\texpectParseError(t, \"return\\n0\", \"<stdin>: WARNING: The following expression is not returned because of an automatically-inserted semicolon\\n\")\n\texpectPrinted(t, \"return\\n0\", \"return;\\n0;\\n\")\n\texpectPrinted(t, \"0\\n[1]\", \"0[1];\\n\")\n\texpectPrinted(t, \"0\\n(1)\", \"0(1);\\n\")\n\texpectPrinted(t, \"new x\\n(1)\", \"new x(1);\\n\")\n\texpectPrinted(t, \"while (true) break\\nx\", \"while (true) break;\\nx;\\n\")\n\texpectPrinted(t, \"x\\n!y\", \"x;\\n!y;\\n\")\n\texpectPrinted(t, \"x\\n++y\", \"x;\\n++y;\\n\")\n\texpectPrinted(t, \"x\\n--y\", \"x;\\n--y;\\n\")\n\n\texpectPrinted(t, \"function* foo(){yield\\na}\", \"function* foo() {\\n  yield;\\n  a;\\n}\\n\")\n\texpectParseError(t, \"function* foo(){yield\\n*a}\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\texpectPrinted(t, \"function* foo(){yield*\\na}\", \"function* foo() {\\n  yield* a;\\n}\\n\")\n\n\texpectPrinted(t, \"async\\nx => {}\", \"async;\\n(x) => {\\n};\\n\")\n\texpectPrinted(t, \"async\\nfunction foo() {}\", \"async;\\nfunction foo() {\\n}\\n\")\n\texpectPrinted(t, \"export default async\\nx => {}\", \"export default async;\\n(x) => {\\n};\\n\")\n\texpectPrinted(t, \"export default async\\nfunction foo() {}\", \"export default async;\\nfunction foo() {\\n}\\n\")\n\texpectParseError(t, \"async\\n() => {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"=>\\\"\\n\")\n\texpectParseError(t, \"export async\\nfunction foo() {}\", \"<stdin>: ERROR: Unexpected newline after \\\"async\\\"\\n\")\n\texpectParseError(t, \"export default async\\n() => {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"=>\\\"\\n\")\n\texpectParseError(t, \"(async\\nx => {})\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"(async\\n() => {})\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"=>\\\"\\n\")\n\texpectParseError(t, \"(async\\nfunction foo() {})\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"function\\\"\\n\")\n\n\texpectPrinted(t, \"if (0) let\\nx = 0\", \"if (0) let;\\nx = 0;\\n\")\n\texpectPrinted(t, \"if (0) let\\n{x}\", \"if (0) let;\\n{\\n  x;\\n}\\n\")\n\texpectParseError(t, \"if (0) let\\n{x} = 0\", \"<stdin>: ERROR: Unexpected \\\"=\\\"\\n\")\n\texpectParseError(t, \"if (0) let\\n[x] = 0\", \"<stdin>: ERROR: Cannot use a declaration in a single-statement context\\n\"+\n\t\t\"NOTE: Wrap this declaration in a block statement to use it here.\\n\")\n\texpectPrinted(t, \"function *foo() { if (0) let\\nyield 0 }\", \"function* foo() {\\n  if (0) let;\\n  yield 0;\\n}\\n\")\n\texpectPrinted(t, \"async function foo() { if (0) let\\nawait 0 }\", \"async function foo() {\\n  if (0) let;\\n  await 0;\\n}\\n\")\n\n\texpectPrinted(t, \"let\\nx = 0\", \"let x = 0;\\n\")\n\texpectPrinted(t, \"let\\n{x} = 0\", \"let { x } = 0;\\n\")\n\texpectPrinted(t, \"let\\n[x] = 0\", \"let [x] = 0;\\n\")\n\texpectParseError(t, \"function *foo() { let\\nyield 0 }\",\n\t\t\"<stdin>: ERROR: Cannot use \\\"yield\\\" as an identifier here:\\n<stdin>: ERROR: Expected \\\";\\\" but found \\\"0\\\"\\n\")\n\texpectParseError(t, \"async function foo() { let\\nawait 0 }\",\n\t\t\"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n<stdin>: ERROR: Expected \\\";\\\" but found \\\"0\\\"\\n\")\n\n\t// This is a weird corner case where ASI applies without a newline\n\texpectPrinted(t, \"do x;while(y)z\", \"do\\n  x;\\nwhile (y);\\nz;\\n\")\n\texpectPrinted(t, \"do x;while(y);z\", \"do\\n  x;\\nwhile (y);\\nz;\\n\")\n\texpectPrinted(t, \"{do x;while(y)}\", \"{\\n  do\\n    x;\\n  while (y);\\n}\\n\")\n}\n\nfunc TestLocal(t *testing.T) {\n\texpectPrinted(t, \"var let = 0\", \"var let = 0;\\n\")\n\texpectParseError(t, \"let let = 0\", \"<stdin>: ERROR: Cannot use \\\"let\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"const let = 0\", \"<stdin>: ERROR: Cannot use \\\"let\\\" as an identifier here:\\n\")\n\n\texpectPrinted(t, \"var\\nlet = 0\", \"var let = 0;\\n\")\n\texpectParseError(t, \"let\\nlet = 0\", \"<stdin>: ERROR: Cannot use \\\"let\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"const\\nlet = 0\", \"<stdin>: ERROR: Cannot use \\\"let\\\" as an identifier here:\\n\")\n\n\texpectPrinted(t, \"for (var let in x) ;\", \"for (var let in x) ;\\n\")\n\texpectParseError(t, \"for (let let in x) ;\", \"<stdin>: ERROR: Cannot use \\\"let\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"for (const let in x) ;\", \"<stdin>: ERROR: Cannot use \\\"let\\\" as an identifier here:\\n\")\n\n\texpectPrinted(t, \"for (var let of x) ;\", \"for (var let of x) ;\\n\")\n\texpectParseError(t, \"for (let let of x) ;\", \"<stdin>: ERROR: Cannot use \\\"let\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"for (const let of x) ;\", \"<stdin>: ERROR: Cannot use \\\"let\\\" as an identifier here:\\n\")\n\n\terrorText := `<stdin>: WARNING: This assignment will throw because \"x\" is a constant\n<stdin>: NOTE: The symbol \"x\" was declared a constant here:\n`\n\texpectParseError(t, \"var x = 0; x = 1\", \"\")\n\texpectParseError(t, \"let x = 0; x = 1\", \"\")\n\texpectParseError(t, \"const x = 0; x = 1\", errorText)\n\texpectParseError(t, \"var x = 0; x++\", \"\")\n\texpectParseError(t, \"let x = 0; x++\", \"\")\n\texpectParseError(t, \"const x = 0; x++\", errorText)\n}\n\nfunc TestArrays(t *testing.T) {\n\texpectPrinted(t, \"[]\", \"[];\\n\")\n\texpectPrinted(t, \"[,]\", \"[,];\\n\")\n\texpectPrinted(t, \"[1]\", \"[1];\\n\")\n\texpectPrinted(t, \"[1,]\", \"[1];\\n\")\n\texpectPrinted(t, \"[,1]\", \"[, 1];\\n\")\n\texpectPrinted(t, \"[1,2]\", \"[1, 2];\\n\")\n\texpectPrinted(t, \"[,1,2]\", \"[, 1, 2];\\n\")\n\texpectPrinted(t, \"[1,,2]\", \"[1, , 2];\\n\")\n\texpectPrinted(t, \"[1,2,]\", \"[1, 2];\\n\")\n\texpectPrinted(t, \"[1,2,,]\", \"[1, 2, ,];\\n\")\n}\n\nfunc TestPattern(t *testing.T) {\n\texpectPrinted(t, \"let {if: x} = y\", \"let { if: x } = y;\\n\")\n\texpectParseError(t, \"let {x: if} = y\", \"<stdin>: ERROR: Expected identifier but found \\\"if\\\"\\n\")\n\n\texpectPrinted(t, \"let {1_2_3n: x} = y\", \"let { 123n: x } = y;\\n\")\n\texpectPrinted(t, \"let {0x1_2_3n: x} = y\", \"let { 0x123n: x } = y;\\n\")\n\n\texpectParseError(t, \"var [ (x) ] = 0\", \"<stdin>: ERROR: Expected identifier but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"var [ ...(x) ] = 0\", \"<stdin>: ERROR: Expected identifier but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"var { (x) } = 0\", \"<stdin>: ERROR: Expected identifier but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"var { x: (y) } = 0\", \"<stdin>: ERROR: Expected identifier but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"var { ...(x) } = 0\", \"<stdin>: ERROR: Expected identifier but found \\\"(\\\"\\n\")\n}\n\nfunc TestAssignTarget(t *testing.T) {\n\texpectParseError(t, \"x = 0\", \"\")\n\texpectParseError(t, \"x.y = 0\", \"\")\n\texpectParseError(t, \"x[y] = 0\", \"\")\n\texpectParseError(t, \"[,] = 0\", \"\")\n\texpectParseError(t, \"[x] = 0\", \"\")\n\texpectParseError(t, \"[x = y] = 0\", \"\")\n\texpectParseError(t, \"[...x] = 0\", \"\")\n\texpectParseError(t, \"({...x} = 0)\", \"\")\n\texpectParseError(t, \"({x = 0} = 0)\", \"\")\n\texpectParseError(t, \"({x: y = 0} = 0)\", \"\")\n\n\texpectParseError(t, \"[ (y) ] = 0\", \"\")\n\texpectParseError(t, \"[ ...(y) ] = 0\", \"\")\n\texpectParseError(t, \"({ (y) } = 0)\", \"<stdin>: ERROR: Expected identifier but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"({ y: (z) } = 0)\", \"\")\n\texpectParseError(t, \"({ ...(y) } = 0)\", \"\")\n\n\texpectParseError(t, \"[...x = y] = 0\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"x() = 0\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"x?.y = 0\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"x?.[y] = 0\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"({x: 0} = 0)\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"({x() {}} = 0)\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"({x: 0 = y} = 0)\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n}\n\nfunc TestObject(t *testing.T) {\n\texpectPrinted(t, \"({foo})\", \"({ foo });\\n\")\n\texpectPrinted(t, \"({foo:0})\", \"({ foo: 0 });\\n\")\n\texpectPrinted(t, \"({1e9:0})\", \"({ 1e9: 0 });\\n\")\n\texpectPrinted(t, \"({1_2_3n:0})\", \"({ 123n: 0 });\\n\")\n\texpectPrinted(t, \"({0x1_2_3n:0})\", \"({ 0x123n: 0 });\\n\")\n\texpectPrinted(t, \"({foo() {}})\", \"({ foo() {\\n} });\\n\")\n\texpectPrinted(t, \"({*foo() {}})\", \"({ *foo() {\\n} });\\n\")\n\texpectPrinted(t, \"({get foo() {}})\", \"({ get foo() {\\n} });\\n\")\n\texpectPrinted(t, \"({set foo(x) {}})\", \"({ set foo(x) {\\n} });\\n\")\n\n\texpectPrinted(t, \"({if:0})\", \"({ if: 0 });\\n\")\n\texpectPrinted(t, \"({if() {}})\", \"({ if() {\\n} });\\n\")\n\texpectPrinted(t, \"({*if() {}})\", \"({ *if() {\\n} });\\n\")\n\texpectPrinted(t, \"({get if() {}})\", \"({ get if() {\\n} });\\n\")\n\texpectPrinted(t, \"({set if(x) {}})\", \"({ set if(x) {\\n} });\\n\")\n\n\texpectParseError(t, \"({static foo() {}})\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"foo\\\"\\n\")\n\texpectParseError(t, \"({`a`})\", \"<stdin>: ERROR: Expected identifier but found \\\"`a`\\\"\\n\")\n\texpectParseError(t, \"({if})\", \"<stdin>: ERROR: Expected \\\":\\\" but found \\\"}\\\"\\n\")\n\n\tprotoError := \"<stdin>: ERROR: Cannot specify the \\\"__proto__\\\" property more than once per object\\n\" +\n\t\t\"<stdin>: NOTE: The earlier \\\"__proto__\\\" property is here:\\n\"\n\n\texpectParseError(t, \"({__proto__: 1, __proto__: 2})\", protoError)\n\texpectParseError(t, \"({__proto__: 1, '__proto__': 2})\", protoError)\n\texpectParseError(t, \"({__proto__: 1, __proto__() {}})\", \"\")\n\texpectParseError(t, \"({__proto__: 1, get __proto__() {}})\", \"\")\n\texpectParseError(t, \"({__proto__: 1, set __proto__(x) {}})\", \"\")\n\texpectParseError(t, \"({__proto__: 1, ['__proto__']: 2})\", \"\")\n\texpectParseError(t, \"({__proto__, __proto__: 2})\", \"\")\n\texpectParseError(t, \"({__proto__: x, __proto__: y} = z)\", \"\")\n\n\texpectPrintedMangle(t, \"x = {['_proto_']: x}\", \"x = { _proto_: x };\\n\")\n\texpectPrintedMangle(t, \"x = {['__proto__']: x}\", \"x = { [\\\"__proto__\\\"]: x };\\n\")\n\n\texpectParseError(t, \"({set foo() {}})\", \"<stdin>: ERROR: Setter \\\"foo\\\" must have exactly one argument\\n\")\n\texpectParseError(t, \"({get foo(x) {}})\", \"<stdin>: ERROR: Getter \\\"foo\\\" must have zero arguments\\n\")\n\texpectParseError(t, \"({set foo(x, y) {}})\", \"<stdin>: ERROR: Setter \\\"foo\\\" must have exactly one argument\\n\")\n\n\texpectParseError(t, \"(class {set #foo() {}})\", \"<stdin>: ERROR: Setter \\\"#foo\\\" must have exactly one argument\\n\")\n\texpectParseError(t, \"(class {get #foo(x) {}})\", \"<stdin>: ERROR: Getter \\\"#foo\\\" must have zero arguments\\n\")\n\texpectParseError(t, \"(class {set #foo(x, y) {}})\", \"<stdin>: ERROR: Setter \\\"#foo\\\" must have exactly one argument\\n\")\n\n\texpectParseError(t, \"({set [foo]() {}})\", \"<stdin>: ERROR: Setter property must have exactly one argument\\n\")\n\texpectParseError(t, \"({get [foo](x) {}})\", \"<stdin>: ERROR: Getter property must have zero arguments\\n\")\n\texpectParseError(t, \"({set [foo](x, y) {}})\", \"<stdin>: ERROR: Setter property must have exactly one argument\\n\")\n\n\tduplicateWarning := \"<stdin>: WARNING: Duplicate key \\\"x\\\" in object literal\\n\" +\n\t\t\"<stdin>: NOTE: The original key \\\"x\\\" is here:\\n\"\n\texpectParseError(t, \"({x, x})\", duplicateWarning)\n\texpectParseError(t, \"({x() {}, x() {}})\", duplicateWarning)\n\texpectParseError(t, \"({get x() {}, get x() {}})\", duplicateWarning)\n\texpectParseError(t, \"({get x() {}, set x(y) {}, get x() {}})\", duplicateWarning)\n\texpectParseError(t, \"({get x() {}, set x(y) {}, set x(y) {}})\", duplicateWarning)\n\texpectParseError(t, \"({get x() {}, set x(y) {}})\", \"\")\n\texpectParseError(t, \"({set x(y) {}, get x() {}})\", \"\")\n\n\t// Check the string-to-int optimization\n\texpectPrintedMangle(t, \"x = { '0': y }\", \"x = { 0: y };\\n\")\n\texpectPrintedMangle(t, \"x = { '123': y }\", \"x = { 123: y };\\n\")\n\texpectPrintedMangle(t, \"x = { '-123': y }\", \"x = { \\\"-123\\\": y };\\n\")\n\texpectPrintedMangle(t, \"x = { '-0': y }\", \"x = { \\\"-0\\\": y };\\n\")\n\texpectPrintedMangle(t, \"x = { '01': y }\", \"x = { \\\"01\\\": y };\\n\")\n\texpectPrintedMangle(t, \"x = { '-01': y }\", \"x = { \\\"-01\\\": y };\\n\")\n\texpectPrintedMangle(t, \"x = { '0x1': y }\", \"x = { \\\"0x1\\\": y };\\n\")\n\texpectPrintedMangle(t, \"x = { '-0x1': y }\", \"x = { \\\"-0x1\\\": y };\\n\")\n\texpectPrintedMangle(t, \"x = { '2147483647': y }\", \"x = { 2147483647: y };\\n\")\n\texpectPrintedMangle(t, \"x = { '2147483648': y }\", \"x = { \\\"2147483648\\\": y };\\n\")\n\texpectPrintedMangle(t, \"x = { '-2147483648': y }\", \"x = { \\\"-2147483648\\\": y };\\n\")\n\texpectPrintedMangle(t, \"x = { '-2147483649': y }\", \"x = { \\\"-2147483649\\\": y };\\n\")\n\n\t// See: https://github.com/microsoft/TypeScript/pull/60225\n\texpectPrinted(t, \"x = { get \\n x() {} }\", \"x = { get x() {\\n} };\\n\")\n\texpectPrinted(t, \"x = { set \\n x(_) {} }\", \"x = { set x(_) {\\n} };\\n\")\n\texpectParseError(t, \"x = { get \\n *x() {} }\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"*\\\"\\n\")\n\texpectParseError(t, \"x = { set \\n *x(_) {} }\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"*\\\"\\n\")\n\texpectParseError(t, \"x = { get \\n async x() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"x = { set \\n async x(_) {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"x\\\"\\n\")\n}\n\nfunc TestComputedProperty(t *testing.T) {\n\texpectPrinted(t, \"({[a]: foo})\", \"({ [a]: foo });\\n\")\n\texpectPrinted(t, \"({[(a, b)]: foo})\", \"({ [(a, b)]: foo });\\n\")\n\texpectParseError(t, \"({[a, b]: foo})\", \"<stdin>: ERROR: Expected \\\"]\\\" but found \\\",\\\"\\n\")\n\n\texpectPrinted(t, \"({[a]: foo}) => {}\", \"({ [a]: foo }) => {\\n};\\n\")\n\texpectPrinted(t, \"({[(a, b)]: foo}) => {}\", \"({ [(a, b)]: foo }) => {\\n};\\n\")\n\texpectParseError(t, \"({[a, b]: foo}) => {}\", \"<stdin>: ERROR: Expected \\\"]\\\" but found \\\",\\\"\\n\")\n\n\texpectPrinted(t, \"var {[a]: foo} = bar\", \"var { [a]: foo } = bar;\\n\")\n\texpectPrinted(t, \"var {[(a, b)]: foo} = bar\", \"var { [(a, b)]: foo } = bar;\\n\")\n\texpectParseError(t, \"var {[a, b]: foo} = bar\", \"<stdin>: ERROR: Expected \\\"]\\\" but found \\\",\\\"\\n\")\n\n\texpectPrinted(t, \"class Foo {[a] = foo}\", \"class Foo {\\n  [a] = foo;\\n}\\n\")\n\texpectPrinted(t, \"class Foo {[(a, b)] = foo}\", \"class Foo {\\n  [(a, b)] = foo;\\n}\\n\")\n\texpectParseError(t, \"class Foo {[a, b] = foo}\", \"<stdin>: ERROR: Expected \\\"]\\\" but found \\\",\\\"\\n\")\n}\n\nfunc TestQuotedProperty(t *testing.T) {\n\texpectPrinted(t, \"x.x; y['y']\", \"x.x;\\ny[\\\"y\\\"];\\n\")\n\texpectPrinted(t, \"({y: y, 'z': z} = x)\", \"({ y, \\\"z\\\": z } = x);\\n\")\n\texpectPrinted(t, \"var {y: y, 'z': z} = x\", \"var { y, \\\"z\\\": z } = x;\\n\")\n\texpectPrinted(t, \"x = {y: 1, 'z': 2}\", \"x = { y: 1, \\\"z\\\": 2 };\\n\")\n\texpectPrinted(t, \"x = {y() {}, 'z'() {}}\", \"x = { y() {\\n}, \\\"z\\\"() {\\n} };\\n\")\n\texpectPrinted(t, \"x = {get y() {}, set 'z'(z) {}}\", \"x = { get y() {\\n}, set \\\"z\\\"(z) {\\n} };\\n\")\n\texpectPrinted(t, \"x = class {y = 1; 'z' = 2}\", \"x = class {\\n  y = 1;\\n  \\\"z\\\" = 2;\\n};\\n\")\n\texpectPrinted(t, \"x = class {y() {}; 'z'() {}}\", \"x = class {\\n  y() {\\n  }\\n  \\\"z\\\"() {\\n  }\\n};\\n\")\n\texpectPrinted(t, \"x = class {get y() {}; set 'z'(z) {}}\", \"x = class {\\n  get y() {\\n  }\\n  set \\\"z\\\"(z) {\\n  }\\n};\\n\")\n\n\texpectPrintedMangle(t, \"x.x; y['y']\", \"x.x, y.y;\\n\")\n\texpectPrintedMangle(t, \"({y: y, 'z': z} = x)\", \"({ y, z } = x);\\n\")\n\texpectPrintedMangle(t, \"var {y: y, 'z': z} = x\", \"var { y, z } = x;\\n\")\n\texpectPrintedMangle(t, \"x = {y: 1, 'z': 2}\", \"x = { y: 1, z: 2 };\\n\")\n\texpectPrintedMangle(t, \"x = {y() {}, 'z'() {}}\", \"x = { y() {\\n}, z() {\\n} };\\n\")\n\texpectPrintedMangle(t, \"x = {get y() {}, set 'z'(z) {}}\", \"x = { get y() {\\n}, set z(z) {\\n} };\\n\")\n\texpectPrintedMangle(t, \"x = class {y = 1; 'z' = 2}\", \"x = class {\\n  y = 1;\\n  z = 2;\\n};\\n\")\n\texpectPrintedMangle(t, \"x = class {y() {}; 'z'() {}}\", \"x = class {\\n  y() {\\n  }\\n  z() {\\n  }\\n};\\n\")\n\texpectPrintedMangle(t, \"x = class {get y() {}; set 'z'(z) {}}\", \"x = class {\\n  get y() {\\n  }\\n  set z(z) {\\n  }\\n};\\n\")\n}\n\nfunc TestLexicalDecl(t *testing.T) {\n\texpectPrinted(t, \"if (1) var x\", \"if (1) var x;\\n\")\n\texpectPrinted(t, \"if (1) function x() {}\", \"if (1) {\\n  let x = function() {\\n  };\\n  var x = x;\\n}\\n\")\n\texpectPrinted(t, \"if (1) {} else function x() {}\", \"if (1) {\\n} else {\\n  let x = function() {\\n  };\\n  var x = x;\\n}\\n\")\n\texpectPrinted(t, \"switch (1) { case 1: const x = 1 }\", \"switch (1) {\\n  case 1:\\n    const x = 1;\\n}\\n\")\n\texpectPrinted(t, \"switch (1) { default: const x = 1 }\", \"switch (1) {\\n  default:\\n    const x = 1;\\n}\\n\")\n\n\tsingleStmtContext := []string{\n\t\t\"label: %s\",\n\t\t\"for (;;) %s\",\n\t\t\"if (1) %s\",\n\t\t\"while (1) %s\",\n\t\t\"with ({}) %s\",\n\t\t\"if (1) {} else %s\",\n\t\t\"do %s \\n while(0)\",\n\n\t\t\"for (;;) label: %s\",\n\t\t\"if (1) label: %s\",\n\t\t\"while (1) label: %s\",\n\t\t\"with ({}) label: %s\",\n\t\t\"if (1) {} else label: %s\",\n\t\t\"do label: %s \\n while(0)\",\n\n\t\t\"for (;;) label: label2: %s\",\n\t\t\"if (1) label: label2: %s\",\n\t\t\"while (1) label: label2: %s\",\n\t\t\"with ({}) label: label2: %s\",\n\t\t\"if (1) {} else label: label2: %s\",\n\t\t\"do label: label2: %s \\n while(0)\",\n\t}\n\n\tsingleStmtError := \"<stdin>: ERROR: Cannot use a declaration in a single-statement context\\n\" +\n\t\t\"NOTE: Wrap this declaration in a block statement to use it here.\\n\"\n\n\tfor _, context := range singleStmtContext {\n\t\texpectParseError(t, fmt.Sprintf(context, \"const x = 0\"), singleStmtError)\n\t\texpectParseError(t, fmt.Sprintf(context, \"let x\"), singleStmtError)\n\t\texpectParseError(t, fmt.Sprintf(context, \"class X {}\"), singleStmtError)\n\t\texpectParseError(t, fmt.Sprintf(context, \"function* x() {}\"), singleStmtError)\n\t\texpectParseError(t, fmt.Sprintf(context, \"async function x() {}\"), singleStmtError)\n\t\texpectParseError(t, fmt.Sprintf(context, \"async function* x() {}\"), singleStmtError)\n\t}\n\n\texpectPrinted(t, \"function f() {}\", \"function f() {\\n}\\n\")\n\texpectPrinted(t, \"{function f() {}} let f\", \"{\\n  let f = function() {\\n  };\\n}\\nlet f;\\n\")\n\texpectPrinted(t, \"if (1) function f() {} let f\", \"if (1) {\\n  let f = function() {\\n  };\\n}\\nlet f;\\n\")\n\texpectPrinted(t, \"if (0) ; else function f() {} let f\", \"if (0) ;\\nelse {\\n  let f = function() {\\n  };\\n}\\nlet f;\\n\")\n\texpectPrinted(t, \"x: function f() {}\", \"x: {\\n  let f = function() {\\n  };\\n  var f = f;\\n}\\n\")\n\texpectPrinted(t, \"{function* f() {}} let f\", \"{\\n  function* f() {\\n  }\\n}\\nlet f;\\n\")\n\texpectPrinted(t, \"{async function f() {}} let f\", \"{\\n  async function f() {\\n  }\\n}\\nlet f;\\n\")\n\n\texpectParseError(t, \"if (1) label: function f() {} let f\", singleStmtError)\n\texpectParseError(t, \"if (1) label: label2: function f() {} let f\", singleStmtError)\n\texpectParseError(t, \"if (0) ; else label: function f() {} let f\", singleStmtError)\n\texpectParseError(t, \"if (0) ; else label: label2: function f() {} let f\", singleStmtError)\n\n\texpectParseError(t, \"for (;;) function f() {}\", singleStmtError)\n\texpectParseError(t, \"for (x in y) function f() {}\", singleStmtError)\n\texpectParseError(t, \"for (x of y) function f() {}\", singleStmtError)\n\texpectParseError(t, \"for await (x of y) function f() {}\", singleStmtError)\n\texpectParseError(t, \"with (1) function f() {}\", singleStmtError)\n\texpectParseError(t, \"while (1) function f() {}\", singleStmtError)\n\texpectParseError(t, \"do function f() {} while (0)\", singleStmtError)\n\n\tfnLabelAwait := \"<stdin>: ERROR: Function declarations inside labels cannot be used in an ECMAScript module\\n\" +\n\t\t\"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the top-level \\\"await\\\" keyword here:\\n\"\n\n\texpectParseError(t, \"for (;;) label: function f() {}\", singleStmtError)\n\texpectParseError(t, \"for (x in y) label: function f() {}\", singleStmtError)\n\texpectParseError(t, \"for (x of y) label: function f() {}\", singleStmtError)\n\texpectParseError(t, \"for await (x of y) label: function f() {}\", singleStmtError+fnLabelAwait)\n\texpectParseError(t, \"with (1) label: function f() {}\", singleStmtError)\n\texpectParseError(t, \"while (1) label: function f() {}\", singleStmtError)\n\texpectParseError(t, \"do label: function f() {} while (0)\", singleStmtError)\n\n\texpectParseError(t, \"for (;;) label: label2: function f() {}\", singleStmtError)\n\texpectParseError(t, \"for (x in y) label: label2: function f() {}\", singleStmtError)\n\texpectParseError(t, \"for (x of y) label: label2: function f() {}\", singleStmtError)\n\texpectParseError(t, \"for await (x of y) label: label2: function f() {}\", singleStmtError+fnLabelAwait)\n\texpectParseError(t, \"with (1) label: label2: function f() {}\", singleStmtError)\n\texpectParseError(t, \"while (1) label: label2: function f() {}\", singleStmtError)\n\texpectParseError(t, \"do label: label2: function f() {} while (0)\", singleStmtError)\n\n\t// Test direct \"eval\"\n\texpectPrinted(t, \"if (foo) { function x() {} }\", \"if (foo) {\\n  let x = function() {\\n  };\\n  var x = x;\\n}\\n\")\n\texpectPrinted(t, \"if (foo) { function x() {} eval('') }\", \"if (foo) {\\n  function x() {\\n  }\\n  eval(\\\"\\\");\\n}\\n\")\n\texpectPrinted(t, \"if (foo) { function x() {} if (bar) { eval('') } }\", \"if (foo) {\\n  function x() {\\n  }\\n  if (bar) {\\n    eval(\\\"\\\");\\n  }\\n}\\n\")\n\texpectPrinted(t, \"if (foo) { eval(''); function x() {} }\", \"if (foo) {\\n  function x() {\\n  }\\n  eval(\\\"\\\");\\n}\\n\")\n\texpectPrinted(t, \"'use strict'; if (foo) { function x() {} }\", \"\\\"use strict\\\";\\nif (foo) {\\n  let x = function() {\\n  };\\n}\\n\")\n\texpectPrinted(t, \"'use strict'; if (foo) { function x() {} eval('') }\", \"\\\"use strict\\\";\\nif (foo) {\\n  function x() {\\n  }\\n  eval(\\\"\\\");\\n}\\n\")\n\texpectPrinted(t, \"'use strict'; if (foo) { function x() {} if (bar) { eval('') } }\", \"\\\"use strict\\\";\\nif (foo) {\\n  function x() {\\n  }\\n  if (bar) {\\n    eval(\\\"\\\");\\n  }\\n}\\n\")\n\texpectPrinted(t, \"'use strict'; if (foo) { eval(''); function x() {} }\", \"\\\"use strict\\\";\\nif (foo) {\\n  function x() {\\n  }\\n  eval(\\\"\\\");\\n}\\n\")\n}\n\nfunc TestFunction(t *testing.T) {\n\texpectPrinted(t, \"function f() {} function f() {}\", \"function f() {\\n}\\nfunction f() {\\n}\\n\")\n\texpectPrinted(t, \"function f() {} function* f() {}\", \"function f() {\\n}\\nfunction* f() {\\n}\\n\")\n\texpectPrinted(t, \"function* f() {} function* f() {}\", \"function* f() {\\n}\\nfunction* f() {\\n}\\n\")\n\texpectPrinted(t, \"function f() {} async function f() {}\", \"function f() {\\n}\\nasync function f() {\\n}\\n\")\n\texpectPrinted(t, \"async function f() {} async function f() {}\", \"async function f() {\\n}\\nasync function f() {\\n}\\n\")\n\n\texpectPrinted(t, \"function arguments() {}\", \"function arguments() {\\n}\\n\")\n\texpectPrinted(t, \"(function arguments() {})\", \"(function arguments() {\\n});\\n\")\n\texpectPrinted(t, \"function foo(arguments) {}\", \"function foo(arguments) {\\n}\\n\")\n\texpectPrinted(t, \"(function foo(arguments) {})\", \"(function foo(arguments) {\\n});\\n\")\n\n\texpectPrinted(t, \"(function foo() { var arguments })\", \"(function foo() {\\n  var arguments;\\n});\\n\")\n\texpectPrinted(t, \"(function foo() { { var arguments } })\", \"(function foo() {\\n  {\\n    var arguments;\\n  }\\n});\\n\")\n\n\texpectPrintedMangle(t, \"function foo() { return undefined }\", \"function foo() {\\n}\\n\")\n\texpectPrintedMangle(t, \"function* foo() { return undefined }\", \"function* foo() {\\n}\\n\")\n\texpectPrintedMangle(t, \"async function foo() { return undefined }\", \"async function foo() {\\n}\\n\")\n\texpectPrintedMangle(t, \"async function* foo() { return undefined }\", \"async function* foo() {\\n  return void 0;\\n}\\n\")\n\n\t// Strip overwritten function declarations\n\texpectPrintedMangle(t, \"function f() { x() } function f() { y() }\", \"function f() {\\n  y();\\n}\\n\")\n\texpectPrintedMangle(t, \"function f() { x() } function *f() { y() }\", \"function* f() {\\n  y();\\n}\\n\")\n\texpectPrintedMangle(t, \"function *f() { x() } function f() { y() }\", \"function f() {\\n  y();\\n}\\n\")\n\texpectPrintedMangle(t, \"function *f() { x() } function *f() { y() }\", \"function* f() {\\n  y();\\n}\\n\")\n\texpectPrintedMangle(t, \"function f() { x() } async function f() { y() }\", \"async function f() {\\n  y();\\n}\\n\")\n\texpectPrintedMangle(t, \"async function f() { x() } function f() { y() }\", \"function f() {\\n  y();\\n}\\n\")\n\texpectPrintedMangle(t, \"async function f() { x() } async function f() { y() }\", \"async function f() {\\n  y();\\n}\\n\")\n\texpectPrintedMangle(t, \"var f; function f() {}\", \"var f;\\nfunction f() {\\n}\\n\")\n\texpectPrintedMangle(t, \"function f() {} var f\", \"function f() {\\n}\\nvar f;\\n\")\n\texpectPrintedMangle(t, \"var f; function f() { x() } function f() { y() }\", \"var f;\\nfunction f() {\\n  y();\\n}\\n\")\n\texpectPrintedMangle(t, \"function f() { x() } function f() { y() } var f\", \"function f() {\\n  y();\\n}\\nvar f;\\n\")\n\texpectPrintedMangle(t, \"function f() { x() } var f; function f() { y() }\", \"function f() {\\n  x();\\n}\\nvar f;\\nfunction f() {\\n  y();\\n}\\n\")\n\n\tredeclaredError := \"<stdin>: ERROR: The symbol \\\"f\\\" has already been declared\\n\" +\n\t\t\"<stdin>: NOTE: The symbol \\\"f\\\" was originally declared here:\\n\"\n\n\texpectParseError(t, \"function *f() {} function *f() {}\", \"\")\n\texpectParseError(t, \"function f() {} let f\", redeclaredError)\n\texpectParseError(t, \"function f() {} var f\", \"\")\n\texpectParseError(t, \"function *f() {} var f\", \"\")\n\texpectParseError(t, \"let f; function f() {}\", redeclaredError)\n\texpectParseError(t, \"var f; function f() {}\", \"\")\n\texpectParseError(t, \"var f; function *f() {}\", \"\")\n\n\texpectParseError(t, \"{ function *f() {} function *f() {} }\", redeclaredError)\n\texpectParseError(t, \"{ function f() {} let f }\", redeclaredError)\n\texpectParseError(t, \"{ function f() {} var f }\", redeclaredError)\n\texpectParseError(t, \"{ function *f() {} var f }\", redeclaredError)\n\texpectParseError(t, \"{ let f; function f() {} }\", redeclaredError)\n\texpectParseError(t, \"{ var f; function f() {} }\", redeclaredError)\n\texpectParseError(t, \"{ var f; function *f() {} }\", redeclaredError)\n\n\texpectParseError(t, \"switch (0) { case 1: function *f() {} default: function *f() {} }\", redeclaredError)\n\texpectParseError(t, \"switch (0) { case 1: function f() {} default: let f }\", redeclaredError)\n\texpectParseError(t, \"switch (0) { case 1: function f() {} default: var f }\", redeclaredError)\n\texpectParseError(t, \"switch (0) { case 1: function *f() {} default: var f }\", redeclaredError)\n\texpectParseError(t, \"switch (0) { case 1: let f; default: function f() {} }\", redeclaredError)\n\texpectParseError(t, \"switch (0) { case 1: var f; default: function f() {} }\", redeclaredError)\n\texpectParseError(t, \"switch (0) { case 1: var f; default: function *f() {} }\", redeclaredError)\n\n\t// Inject parentheses around IIFEs as they are an optimization hint for VMs\n\texpectPrinted(t, \"var x = function() { y() }()\", \"var x = (function() {\\n  y();\\n})();\\n\")\n\texpectPrinted(t, \"var x = (true && function() { y() })()\", \"var x = (function() {\\n  y();\\n})();\\n\")\n}\n\nfunc TestClass(t *testing.T) {\n\texpectPrinted(t, \"class Foo { foo() {} }\", \"class Foo {\\n  foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { *foo() {} }\", \"class Foo {\\n  *foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { get foo() {} }\", \"class Foo {\\n  get foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { set foo(x) {} }\", \"class Foo {\\n  set foo(x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { async foo() {} }\", \"class Foo {\\n  async foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { async *foo() {} }\", \"class Foo {\\n  async *foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static foo() {} }\", \"class Foo {\\n  static foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static *foo() {} }\", \"class Foo {\\n  static *foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static get foo() {} }\", \"class Foo {\\n  static get foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static set foo(x) {} }\", \"class Foo {\\n  static set foo(x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static async foo() {} }\", \"class Foo {\\n  static async foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static async *foo() {} }\", \"class Foo {\\n  static async *foo() {\\n  }\\n}\\n\")\n\texpectParseError(t, \"class Foo { async static foo() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"foo\\\"\\n\")\n\texpectParseError(t, \"class Foo { * static foo() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"foo\\\"\\n\")\n\texpectParseError(t, \"class Foo { * *foo() {} }\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\texpectParseError(t, \"class Foo { async * *foo() {} }\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\texpectParseError(t, \"class Foo { * async foo() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"foo\\\"\\n\")\n\texpectParseError(t, \"class Foo { * async * foo() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"*\\\"\\n\")\n\texpectParseError(t, \"class Foo { static * *foo() {} }\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\texpectParseError(t, \"class Foo { static async * *foo() {} }\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\texpectParseError(t, \"class Foo { static * async foo() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"foo\\\"\\n\")\n\texpectParseError(t, \"class Foo { static * async * foo() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"*\\\"\\n\")\n\n\texpectPrinted(t, \"class Foo { if() {} }\", \"class Foo {\\n  if() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { *if() {} }\", \"class Foo {\\n  *if() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { get if() {} }\", \"class Foo {\\n  get if() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { set if(x) {} }\", \"class Foo {\\n  set if(x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { async if() {} }\", \"class Foo {\\n  async if() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { async *if() {} }\", \"class Foo {\\n  async *if() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static if() {} }\", \"class Foo {\\n  static if() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static *if() {} }\", \"class Foo {\\n  static *if() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static get if() {} }\", \"class Foo {\\n  static get if() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static set if(x) {} }\", \"class Foo {\\n  static set if(x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static async if() {} }\", \"class Foo {\\n  static async if() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static async *if() {} }\", \"class Foo {\\n  static async *if() {\\n  }\\n}\\n\")\n\texpectParseError(t, \"class Foo { async static if() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"if\\\"\\n\")\n\texpectParseError(t, \"class Foo { * static if() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"if\\\"\\n\")\n\texpectParseError(t, \"class Foo { * *if() {} }\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\texpectParseError(t, \"class Foo { async * *if() {} }\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\texpectParseError(t, \"class Foo { * async if() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"if\\\"\\n\")\n\texpectParseError(t, \"class Foo { * async * if() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"*\\\"\\n\")\n\texpectParseError(t, \"class Foo { static * *if() {} }\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\texpectParseError(t, \"class Foo { static async * *if() {} }\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\texpectParseError(t, \"class Foo { static * async if() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"if\\\"\\n\")\n\texpectParseError(t, \"class Foo { static * async * if() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"*\\\"\\n\")\n\n\texpectPrinted(t, \"class Foo { a() {} b() {} }\", \"class Foo {\\n  a() {\\n  }\\n  b() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { a() {} get b() {} }\", \"class Foo {\\n  a() {\\n  }\\n  get b() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { a() {} set b(x) {} }\", \"class Foo {\\n  a() {\\n  }\\n  set b(x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { a() {} async b() {} }\", \"class Foo {\\n  a() {\\n  }\\n  async b() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { a() {} async *b() {} }\", \"class Foo {\\n  a() {\\n  }\\n  async *b() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { a() {} static b() {} }\", \"class Foo {\\n  a() {\\n  }\\n  static b() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { a() {} static *b() {} }\", \"class Foo {\\n  a() {\\n  }\\n  static *b() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { a() {} static get b() {} }\", \"class Foo {\\n  a() {\\n  }\\n  static get b() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { a() {} static set b(x) {} }\", \"class Foo {\\n  a() {\\n  }\\n  static set b(x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { a() {} static async b() {} }\", \"class Foo {\\n  a() {\\n  }\\n  static async b() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { a() {} static async *b() {} }\", \"class Foo {\\n  a() {\\n  }\\n  static async *b() {\\n  }\\n}\\n\")\n\texpectParseError(t, \"class Foo { a() {} async static b() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"b\\\"\\n\")\n\texpectParseError(t, \"class Foo { a() {} * static b() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"b\\\"\\n\")\n\texpectParseError(t, \"class Foo { a() {} * *b() {} }\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\texpectParseError(t, \"class Foo { a() {} async * *b() {} }\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\texpectParseError(t, \"class Foo { a() {} * async b() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"b\\\"\\n\")\n\texpectParseError(t, \"class Foo { a() {} * async * b() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"*\\\"\\n\")\n\texpectParseError(t, \"class Foo { a() {} static * *b() {} }\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\texpectParseError(t, \"class Foo { a() {} static async * *b() {} }\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\texpectParseError(t, \"class Foo { a() {} static * async b() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"b\\\"\\n\")\n\texpectParseError(t, \"class Foo { a() {} static * async * b() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"*\\\"\\n\")\n\n\texpectParseError(t, \"class Foo { `a`() {} }\", \"<stdin>: ERROR: Expected identifier but found \\\"`a`\\\"\\n\")\n\n\t// Strict mode reserved words cannot be used as class names\n\texpectParseError(t, \"class static {}\",\n\t\t\"<stdin>: ERROR: \\\"static\\\" is a reserved word and cannot be used in strict mode\\n\"+\n\t\t\t\"<stdin>: NOTE: All code inside a class is implicitly in strict mode\\n\")\n\texpectParseError(t, \"(class static {})\",\n\t\t\"<stdin>: ERROR: \\\"static\\\" is a reserved word and cannot be used in strict mode\\n\"+\n\t\t\t\"<stdin>: NOTE: All code inside a class is implicitly in strict mode\\n\")\n\texpectParseError(t, \"class implements {}\",\n\t\t\"<stdin>: ERROR: \\\"implements\\\" is a reserved word and cannot be used in strict mode\\n\"+\n\t\t\t\"<stdin>: NOTE: All code inside a class is implicitly in strict mode\\n\")\n\texpectParseError(t, \"(class implements {})\",\n\t\t\"<stdin>: ERROR: \\\"implements\\\" is a reserved word and cannot be used in strict mode\\n\"+\n\t\t\t\"<stdin>: NOTE: All code inside a class is implicitly in strict mode\\n\")\n\n\t// The name \"arguments\" is forbidden in class bodies outside of computed properties\n\texpectPrinted(t, \"class Foo { [arguments] }\", \"class Foo {\\n  [arguments];\\n}\\n\")\n\texpectPrinted(t, \"class Foo { [arguments] = 1 }\", \"class Foo {\\n  [arguments] = 1;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { arguments = 1 }\", \"class Foo {\\n  arguments = 1;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { x = class { arguments = 1 } }\", \"class Foo {\\n  x = class {\\n    arguments = 1;\\n  };\\n}\\n\")\n\texpectPrinted(t, \"class Foo { x = function() { arguments } }\", \"class Foo {\\n  x = function() {\\n    arguments;\\n  };\\n}\\n\")\n\texpectParseError(t, \"class Foo { x = arguments }\", \"<stdin>: ERROR: Cannot access \\\"arguments\\\" here:\\n\")\n\texpectParseError(t, \"class Foo { x = () => arguments }\", \"<stdin>: ERROR: Cannot access \\\"arguments\\\" here:\\n\")\n\texpectParseError(t, \"class Foo { x = typeof arguments }\", \"<stdin>: ERROR: Cannot access \\\"arguments\\\" here:\\n\")\n\texpectParseError(t, \"class Foo { x = 1 ? 2 : arguments }\", \"<stdin>: ERROR: Cannot access \\\"arguments\\\" here:\\n\")\n\texpectParseError(t, \"class Foo { x = class { [arguments] } }\", \"<stdin>: ERROR: Cannot access \\\"arguments\\\" here:\\n\")\n\texpectParseError(t, \"class Foo { x = class { [arguments] = 1 } }\", \"<stdin>: ERROR: Cannot access \\\"arguments\\\" here:\\n\")\n\texpectParseError(t, \"class Foo { static { arguments } }\", \"<stdin>: ERROR: Cannot access \\\"arguments\\\" here:\\n\")\n\texpectParseError(t, \"class Foo { static { class Bar { [arguments] } } }\", \"<stdin>: ERROR: Cannot access \\\"arguments\\\" here:\\n\")\n\n\t// The name \"constructor\" is sometimes forbidden\n\texpectPrinted(t, \"class Foo { get ['constructor']() {} }\", \"class Foo {\\n  get [\\\"constructor\\\"]() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { set ['constructor'](x) {} }\", \"class Foo {\\n  set [\\\"constructor\\\"](x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { *['constructor']() {} }\", \"class Foo {\\n  *[\\\"constructor\\\"]() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { async ['constructor']() {} }\", \"class Foo {\\n  async [\\\"constructor\\\"]() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { async *['constructor']() {} }\", \"class Foo {\\n  async *[\\\"constructor\\\"]() {\\n  }\\n}\\n\")\n\texpectParseError(t, \"class Foo { get constructor() {} }\", \"<stdin>: ERROR: Class constructor cannot be a getter\\n\")\n\texpectParseError(t, \"class Foo { get 'constructor'() {} }\", \"<stdin>: ERROR: Class constructor cannot be a getter\\n\")\n\texpectParseError(t, \"class Foo { set constructor(x) {} }\", \"<stdin>: ERROR: Class constructor cannot be a setter\\n\")\n\texpectParseError(t, \"class Foo { set 'constructor'(x) {} }\", \"<stdin>: ERROR: Class constructor cannot be a setter\\n\")\n\texpectParseError(t, \"class Foo { *constructor() {} }\", \"<stdin>: ERROR: Class constructor cannot be a generator\\n\")\n\texpectParseError(t, \"class Foo { *'constructor'() {} }\", \"<stdin>: ERROR: Class constructor cannot be a generator\\n\")\n\texpectParseError(t, \"class Foo { async constructor() {} }\", \"<stdin>: ERROR: Class constructor cannot be an async function\\n\")\n\texpectParseError(t, \"class Foo { async 'constructor'() {} }\", \"<stdin>: ERROR: Class constructor cannot be an async function\\n\")\n\texpectParseError(t, \"class Foo { async *constructor() {} }\", \"<stdin>: ERROR: Class constructor cannot be an async function\\n\")\n\texpectParseError(t, \"class Foo { async *'constructor'() {} }\", \"<stdin>: ERROR: Class constructor cannot be an async function\\n\")\n\texpectPrinted(t, \"class Foo { static get constructor() {} }\", \"class Foo {\\n  static get constructor() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static get 'constructor'() {} }\", \"class Foo {\\n  static get \\\"constructor\\\"() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static set constructor(x) {} }\", \"class Foo {\\n  static set constructor(x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static set 'constructor'(x) {} }\", \"class Foo {\\n  static set \\\"constructor\\\"(x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static *constructor() {} }\", \"class Foo {\\n  static *constructor() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static *'constructor'() {} }\", \"class Foo {\\n  static *\\\"constructor\\\"() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static async constructor() {} }\", \"class Foo {\\n  static async constructor() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static async 'constructor'() {} }\", \"class Foo {\\n  static async \\\"constructor\\\"() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static async *constructor() {} }\", \"class Foo {\\n  static async *constructor() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static async *'constructor'() {} }\", \"class Foo {\\n  static async *\\\"constructor\\\"() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"({ constructor: 1 })\", \"({ constructor: 1 });\\n\")\n\texpectPrinted(t, \"({ get constructor() {} })\", \"({ get constructor() {\\n} });\\n\")\n\texpectPrinted(t, \"({ set constructor(x) {} })\", \"({ set constructor(x) {\\n} });\\n\")\n\texpectPrinted(t, \"({ *constructor() {} })\", \"({ *constructor() {\\n} });\\n\")\n\texpectPrinted(t, \"({ async constructor() {} })\", \"({ async constructor() {\\n} });\\n\")\n\texpectPrinted(t, \"({ async* constructor() {} })\", \"({ async *constructor() {\\n} });\\n\")\n\n\t// The name \"prototype\" is sometimes forbidden\n\texpectPrinted(t, \"class Foo { get prototype() {} }\", \"class Foo {\\n  get prototype() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { get 'prototype'() {} }\", \"class Foo {\\n  get \\\"prototype\\\"() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { set prototype(x) {} }\", \"class Foo {\\n  set prototype(x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { set 'prototype'(x) {} }\", \"class Foo {\\n  set \\\"prototype\\\"(x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { *prototype() {} }\", \"class Foo {\\n  *prototype() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { *'prototype'() {} }\", \"class Foo {\\n  *\\\"prototype\\\"() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { async prototype() {} }\", \"class Foo {\\n  async prototype() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { async 'prototype'() {} }\", \"class Foo {\\n  async \\\"prototype\\\"() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { async *prototype() {} }\", \"class Foo {\\n  async *prototype() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { async *'prototype'() {} }\", \"class Foo {\\n  async *\\\"prototype\\\"() {\\n  }\\n}\\n\")\n\texpectParseError(t, \"class Foo { static get prototype() {} }\", \"<stdin>: ERROR: Invalid static method name \\\"prototype\\\"\\n\")\n\texpectParseError(t, \"class Foo { static get 'prototype'() {} }\", \"<stdin>: ERROR: Invalid static method name \\\"prototype\\\"\\n\")\n\texpectParseError(t, \"class Foo { static set prototype(x) {} }\", \"<stdin>: ERROR: Invalid static method name \\\"prototype\\\"\\n\")\n\texpectParseError(t, \"class Foo { static set 'prototype'(x) {} }\", \"<stdin>: ERROR: Invalid static method name \\\"prototype\\\"\\n\")\n\texpectParseError(t, \"class Foo { static *prototype() {} }\", \"<stdin>: ERROR: Invalid static method name \\\"prototype\\\"\\n\")\n\texpectParseError(t, \"class Foo { static *'prototype'() {} }\", \"<stdin>: ERROR: Invalid static method name \\\"prototype\\\"\\n\")\n\texpectParseError(t, \"class Foo { static async prototype() {} }\", \"<stdin>: ERROR: Invalid static method name \\\"prototype\\\"\\n\")\n\texpectParseError(t, \"class Foo { static async 'prototype'() {} }\", \"<stdin>: ERROR: Invalid static method name \\\"prototype\\\"\\n\")\n\texpectParseError(t, \"class Foo { static async *prototype() {} }\", \"<stdin>: ERROR: Invalid static method name \\\"prototype\\\"\\n\")\n\texpectParseError(t, \"class Foo { static async *'prototype'() {} }\", \"<stdin>: ERROR: Invalid static method name \\\"prototype\\\"\\n\")\n\texpectPrinted(t, \"class Foo { static get ['prototype']() {} }\", \"class Foo {\\n  static get [\\\"prototype\\\"]() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static set ['prototype'](x) {} }\", \"class Foo {\\n  static set [\\\"prototype\\\"](x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static *['prototype']() {} }\", \"class Foo {\\n  static *[\\\"prototype\\\"]() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static async ['prototype']() {} }\", \"class Foo {\\n  static async [\\\"prototype\\\"]() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static async *['prototype']() {} }\", \"class Foo {\\n  static async *[\\\"prototype\\\"]() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"({ prototype: 1 })\", \"({ prototype: 1 });\\n\")\n\texpectPrinted(t, \"({ get prototype() {} })\", \"({ get prototype() {\\n} });\\n\")\n\texpectPrinted(t, \"({ set prototype(x) {} })\", \"({ set prototype(x) {\\n} });\\n\")\n\texpectPrinted(t, \"({ *prototype() {} })\", \"({ *prototype() {\\n} });\\n\")\n\texpectPrinted(t, \"({ async prototype() {} })\", \"({ async prototype() {\\n} });\\n\")\n\texpectPrinted(t, \"({ async* prototype() {} })\", \"({ async *prototype() {\\n} });\\n\")\n\n\texpectPrintedMangle(t, \"class Foo { ['constructor'] = 0 }\", \"class Foo {\\n  [\\\"constructor\\\"] = 0;\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { ['constructor']() {} }\", \"class Foo {\\n  [\\\"constructor\\\"]() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { *['constructor']() {} }\", \"class Foo {\\n  *[\\\"constructor\\\"]() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { get ['constructor']() {} }\", \"class Foo {\\n  get [\\\"constructor\\\"]() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { set ['constructor'](x) {} }\", \"class Foo {\\n  set [\\\"constructor\\\"](x) {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { async ['constructor']() {} }\", \"class Foo {\\n  async [\\\"constructor\\\"]() {\\n  }\\n}\\n\")\n\n\texpectPrintedMangle(t, \"class Foo { static ['constructor'] = 0 }\", \"class Foo {\\n  static [\\\"constructor\\\"] = 0;\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { static ['constructor']() {} }\", \"class Foo {\\n  static constructor() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { static *['constructor']() {} }\", \"class Foo {\\n  static *constructor() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { static get ['constructor']() {} }\", \"class Foo {\\n  static get constructor() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { static set ['constructor'](x) {} }\", \"class Foo {\\n  static set constructor(x) {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { static async ['constructor']() {} }\", \"class Foo {\\n  static async constructor() {\\n  }\\n}\\n\")\n\n\texpectPrintedMangle(t, \"class Foo { ['prototype'] = 0 }\", \"class Foo {\\n  prototype = 0;\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { ['prototype']() {} }\", \"class Foo {\\n  prototype() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { *['prototype']() {} }\", \"class Foo {\\n  *prototype() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { get ['prototype']() {} }\", \"class Foo {\\n  get prototype() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { set ['prototype'](x) {} }\", \"class Foo {\\n  set prototype(x) {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { async ['prototype']() {} }\", \"class Foo {\\n  async prototype() {\\n  }\\n}\\n\")\n\n\texpectPrintedMangle(t, \"class Foo { static ['prototype'] = 0 }\", \"class Foo {\\n  static [\\\"prototype\\\"] = 0;\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { static ['prototype']() {} }\", \"class Foo {\\n  static [\\\"prototype\\\"]() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { static *['prototype']() {} }\", \"class Foo {\\n  static *[\\\"prototype\\\"]() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { static get ['prototype']() {} }\", \"class Foo {\\n  static get [\\\"prototype\\\"]() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { static set ['prototype'](x) {} }\", \"class Foo {\\n  static set [\\\"prototype\\\"](x) {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { static async ['prototype']() {} }\", \"class Foo {\\n  static async [\\\"prototype\\\"]() {\\n  }\\n}\\n\")\n\n\tdupCtor := \"<stdin>: ERROR: Classes cannot contain more than one constructor\\n\"\n\n\texpectParseError(t, \"class Foo { constructor() {} constructor() {} }\", dupCtor)\n\texpectParseError(t, \"class Foo { constructor() {} 'constructor'() {} }\", dupCtor)\n\texpectParseError(t, \"class Foo { constructor() {} ['constructor']() {} }\", \"\")\n\texpectParseError(t, \"class Foo { 'constructor'() {} constructor() {} }\", dupCtor)\n\texpectParseError(t, \"class Foo { ['constructor']() {} constructor() {} }\", \"\")\n\texpectParseError(t, \"class Foo { constructor() {} static constructor() {} }\", \"\")\n\texpectParseError(t, \"class Foo { static constructor() {} constructor() {} }\", \"\")\n\texpectParseError(t, \"class Foo { static constructor() {} static constructor() {} }\", \"\")\n\texpectParseError(t, \"class Foo { constructor = () => {}; constructor = () => {} }\",\n\t\t\"<stdin>: ERROR: Invalid field name \\\"constructor\\\"\\n<stdin>: ERROR: Invalid field name \\\"constructor\\\"\\n\")\n\texpectParseError(t, \"({ constructor() {}, constructor() {} })\",\n\t\t\"<stdin>: WARNING: Duplicate key \\\"constructor\\\" in object literal\\n<stdin>: NOTE: The original key \\\"constructor\\\" is here:\\n\")\n\texpectParseError(t, \"(class { constructor() {} constructor() {} })\", dupCtor)\n\texpectPrintedMangle(t, \"class Foo { constructor() {} ['constructor']() {} }\",\n\t\t\"class Foo {\\n  constructor() {\\n  }\\n  [\\\"constructor\\\"]() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { static constructor() {} static ['constructor']() {} }\",\n\t\t\"class Foo {\\n  static constructor() {\\n  }\\n  static constructor() {\\n  }\\n}\\n\")\n\n\t// Check the string-to-int optimization\n\texpectPrintedMangle(t, \"class x { '0' = y }\", \"class x {\\n  0 = y;\\n}\\n\")\n\texpectPrintedMangle(t, \"class x { '123' = y }\", \"class x {\\n  123 = y;\\n}\\n\")\n\texpectPrintedMangle(t, \"class x { ['-123'] = y }\", \"class x {\\n  \\\"-123\\\" = y;\\n}\\n\")\n\texpectPrintedMangle(t, \"class x { '-0' = y }\", \"class x {\\n  \\\"-0\\\" = y;\\n}\\n\")\n\texpectPrintedMangle(t, \"class x { '01' = y }\", \"class x {\\n  \\\"01\\\" = y;\\n}\\n\")\n\texpectPrintedMangle(t, \"class x { '-01' = y }\", \"class x {\\n  \\\"-01\\\" = y;\\n}\\n\")\n\texpectPrintedMangle(t, \"class x { '0x1' = y }\", \"class x {\\n  \\\"0x1\\\" = y;\\n}\\n\")\n\texpectPrintedMangle(t, \"class x { '-0x1' = y }\", \"class x {\\n  \\\"-0x1\\\" = y;\\n}\\n\")\n\texpectPrintedMangle(t, \"class x { '2147483647' = y }\", \"class x {\\n  2147483647 = y;\\n}\\n\")\n\texpectPrintedMangle(t, \"class x { '2147483648' = y }\", \"class x {\\n  \\\"2147483648\\\" = y;\\n}\\n\")\n\texpectPrintedMangle(t, \"class x { ['-2147483648'] = y }\", \"class x {\\n  \\\"-2147483648\\\" = y;\\n}\\n\")\n\texpectPrintedMangle(t, \"class x { ['-2147483649'] = y }\", \"class x {\\n  \\\"-2147483649\\\" = y;\\n}\\n\")\n\n\t// Make sure direct \"eval\" doesn't cause the class name to change\n\texpectPrinted(t, \"class Foo { foo = [Foo, eval(bar)] }\", \"class Foo {\\n  foo = [Foo, eval(bar)];\\n}\\n\")\n\n\t// See: https://github.com/microsoft/TypeScript/pull/60225\n\texpectPrinted(t, \"class A { get \\n x() {} }\", \"class A {\\n  get x() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class A { set \\n x(_) {} }\", \"class A {\\n  set x(_) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class A { get \\n *x() {} }\", \"class A {\\n  get;\\n  *x() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class A { set \\n *x(_) {} }\", \"class A {\\n  set;\\n  *x(_) {\\n  }\\n}\\n\")\n\texpectParseError(t, \"class A { get \\n async x() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"class A { set \\n async x(_) {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"class A { async get \\n *x() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"*\\\"\\n\")\n\texpectParseError(t, \"class A { async set \\n *x(_) {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"*\\\"\\n\")\n}\n\nfunc TestSuperCall(t *testing.T) {\n\texpectParseError(t, \"super\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"super()\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"class Foo { foo = super() }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"class Foo { foo() { super() } }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"class Foo extends Bar { foo = super() }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"class Foo extends Bar { foo() { super() } }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"class Foo extends Bar { static constructor() { super() } }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"class Foo extends Bar { constructor(x = function() { super() }) {} }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"class Foo extends Bar { constructor() { function foo() { super() } } }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"class Foo extends Bar { constructor() { super } }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectPrinted(t, \"class Foo extends Bar { constructor() { super() } }\",\n\t\t\"class Foo extends Bar {\\n  constructor() {\\n    super();\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo extends Bar { constructor() { () => super() } }\",\n\t\t\"class Foo extends Bar {\\n  constructor() {\\n    () => super();\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo extends Bar { constructor() { () => { super() } } }\",\n\t\t\"class Foo extends Bar {\\n  constructor() {\\n    () => {\\n      super();\\n    };\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo extends Bar { constructor(x = super()) {} }\",\n\t\t\"class Foo extends Bar {\\n  constructor(x = super()) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo extends Bar { constructor(x = () => super()) {} }\",\n\t\t\"class Foo extends Bar {\\n  constructor(x = () => super()) {\\n  }\\n}\\n\")\n\n\texpectPrintedMangleTarget(t, 2015, \"class A extends B { x; constructor() { super() } }\",\n\t\t\"class A extends B {\\n  constructor() {\\n    super();\\n    __publicField(this, \\\"x\\\");\\n  }\\n}\\n\")\n\texpectPrintedMangleTarget(t, 2015, \"class A extends B { x = 1; constructor() { super() } }\",\n\t\t\"class A extends B {\\n  constructor() {\\n    super();\\n    __publicField(this, \\\"x\\\", 1);\\n  }\\n}\\n\")\n\texpectPrintedMangleTarget(t, 2015, \"class A extends B { x = 1; constructor() { super(); c() } }\",\n\t\t\"class A extends B {\\n  constructor() {\\n    super();\\n    __publicField(this, \\\"x\\\", 1);\\n    c();\\n  }\\n}\\n\")\n\texpectPrintedMangleTarget(t, 2015, \"class A extends B { x = 1; constructor() { c(); super() } }\",\n\t\t\"class A extends B {\\n  constructor() {\\n    c();\\n    super();\\n    __publicField(this, \\\"x\\\", 1);\\n  }\\n}\\n\")\n\texpectPrintedMangleTarget(t, 2015, \"class A extends B { x = 1; constructor() { super(); if (c) throw c } }\",\n\t\t\"class A extends B {\\n  constructor() {\\n    super();\\n    __publicField(this, \\\"x\\\", 1);\\n    if (c) throw c;\\n  }\\n}\\n\")\n\texpectPrintedMangleTarget(t, 2015, \"class A extends B { x = 1; constructor() { super(); switch (c) { case 0: throw c } } }\",\n\t\t\"class A extends B {\\n  constructor() {\\n    super();\\n    __publicField(this, \\\"x\\\", 1);\\n    if (c === 0)\\n      throw c;\\n  }\\n}\\n\")\n\texpectPrintedMangleTarget(t, 2015, \"class A extends B { x = 1; constructor() { super(); while (!c) throw c } }\",\n\t\t\"class A extends B {\\n  constructor() {\\n    super();\\n    __publicField(this, \\\"x\\\", 1);\\n    for (; !c; ) throw c;\\n  }\\n}\\n\")\n\texpectPrintedMangleTarget(t, 2015, \"class A extends B { x = 1; constructor() { super(); return c } }\",\n\t\t\"class A extends B {\\n  constructor() {\\n    super();\\n    __publicField(this, \\\"x\\\", 1);\\n    return c;\\n  }\\n}\\n\")\n\texpectPrintedMangleTarget(t, 2015, \"class A extends B { x = 1; constructor() { super(); throw c } }\",\n\t\t\"class A extends B {\\n  constructor() {\\n    super();\\n    __publicField(this, \\\"x\\\", 1);\\n    throw c;\\n  }\\n}\\n\")\n\texpectPrintedMangleTarget(t, 2015, \"class A extends B { x = 1; constructor() { if (true) super(1); else super(2); } }\",\n\t\t\"class A extends B {\\n  constructor() {\\n    super(1);\\n    __publicField(this, \\\"x\\\", 1);\\n  }\\n}\\n\")\n\texpectPrintedMangleTarget(t, 2015, \"class A extends B { x = 1; constructor() { if (foo) super(1); else super(2); } }\",\n\t\t\"class A extends B {\\n  constructor() {\\n    var __super = (...args) => (super(...args), __publicField(this, \\\"x\\\", 1), this);\\n    foo ? __super(1) : __super(2);\\n  }\\n}\\n\")\n}\n\nfunc TestSuperProp(t *testing.T) {\n\texpectParseError(t, \"super.x\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"super[x]\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\n\texpectPrinted(t, \"class Foo { foo() { super.x } }\", \"class Foo {\\n  foo() {\\n    super.x;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { foo() { super[x] } }\", \"class Foo {\\n  foo() {\\n    super[x];\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { foo(x = super.x) {} }\", \"class Foo {\\n  foo(x = super.x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { foo(x = super[x]) {} }\", \"class Foo {\\n  foo(x = super[x]) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static foo() { super.x } }\", \"class Foo {\\n  static foo() {\\n    super.x;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static foo() { super[x] } }\", \"class Foo {\\n  static foo() {\\n    super[x];\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static foo(x = super.x) {} }\", \"class Foo {\\n  static foo(x = super.x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static foo(x = super[x]) {} }\", \"class Foo {\\n  static foo(x = super[x]) {\\n  }\\n}\\n\")\n\n\texpectPrinted(t, \"(class { foo() { super.x } })\", \"(class {\\n  foo() {\\n    super.x;\\n  }\\n});\\n\")\n\texpectPrinted(t, \"(class { foo() { super[x] } })\", \"(class {\\n  foo() {\\n    super[x];\\n  }\\n});\\n\")\n\texpectPrinted(t, \"(class { foo(x = super.x) {} })\", \"(class {\\n  foo(x = super.x) {\\n  }\\n});\\n\")\n\texpectPrinted(t, \"(class { foo(x = super[x]) {} })\", \"(class {\\n  foo(x = super[x]) {\\n  }\\n});\\n\")\n\texpectPrinted(t, \"(class { static foo() { super.x } })\", \"(class {\\n  static foo() {\\n    super.x;\\n  }\\n});\\n\")\n\texpectPrinted(t, \"(class { static foo() { super[x] } })\", \"(class {\\n  static foo() {\\n    super[x];\\n  }\\n});\\n\")\n\texpectPrinted(t, \"(class { static foo(x = super.x) {} })\", \"(class {\\n  static foo(x = super.x) {\\n  }\\n});\\n\")\n\texpectPrinted(t, \"(class { static foo(x = super[x]) {} })\", \"(class {\\n  static foo(x = super[x]) {\\n  }\\n});\\n\")\n\n\texpectPrinted(t, \"class Foo { foo = super.x }\", \"class Foo {\\n  foo = super.x;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { foo = super[x] }\", \"class Foo {\\n  foo = super[x];\\n}\\n\")\n\texpectPrinted(t, \"class Foo { foo = () => super.x }\", \"class Foo {\\n  foo = () => super.x;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { foo = () => super[x] }\", \"class Foo {\\n  foo = () => super[x];\\n}\\n\")\n\texpectParseError(t, \"class Foo { foo = function () { super.x } }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"class Foo { foo = function () { super[x] } }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\n\texpectPrinted(t, \"class Foo { static foo = super.x }\", \"class Foo {\\n  static foo = super.x;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static foo = super[x] }\", \"class Foo {\\n  static foo = super[x];\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static foo = () => super.x }\", \"class Foo {\\n  static foo = () => super.x;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static foo = () => super[x] }\", \"class Foo {\\n  static foo = () => super[x];\\n}\\n\")\n\texpectParseError(t, \"class Foo { static foo = function () { super.x } }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"class Foo { static foo = function () { super[x] } }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\n\texpectPrinted(t, \"(class { foo = super.x })\", \"(class {\\n  foo = super.x;\\n});\\n\")\n\texpectPrinted(t, \"(class { foo = super[x] })\", \"(class {\\n  foo = super[x];\\n});\\n\")\n\texpectPrinted(t, \"(class { foo = () => super.x })\", \"(class {\\n  foo = () => super.x;\\n});\\n\")\n\texpectPrinted(t, \"(class { foo = () => super[x] })\", \"(class {\\n  foo = () => super[x];\\n});\\n\")\n\texpectParseError(t, \"(class { foo = function () { super.x } })\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"(class { foo = function () { super[x] } })\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\n\texpectPrinted(t, \"(class { static foo = super.x })\", \"(class {\\n  static foo = super.x;\\n});\\n\")\n\texpectPrinted(t, \"(class { static foo = super[x] })\", \"(class {\\n  static foo = super[x];\\n});\\n\")\n\texpectPrinted(t, \"(class { static foo = () => super.x })\", \"(class {\\n  static foo = () => super.x;\\n});\\n\")\n\texpectPrinted(t, \"(class { static foo = () => super[x] })\", \"(class {\\n  static foo = () => super[x];\\n});\\n\")\n\texpectParseError(t, \"(class { static foo = function () { super.x } })\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"(class { static foo = function () { super[x] } })\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\n\texpectParseError(t, \"({ foo: super.x })\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"({ foo: super[x] })\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"({ foo: () => super.x })\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"({ foo: () => super[x] })\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"({ foo: function () { super.x } })\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"({ foo: function () { super[x] } })\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectPrinted(t, \"({ foo() { super.x } })\", \"({ foo() {\\n  super.x;\\n} });\\n\")\n\texpectPrinted(t, \"({ foo() { super[x] } })\", \"({ foo() {\\n  super[x];\\n} });\\n\")\n\texpectPrinted(t, \"({ foo(x = super.x) {} })\", \"({ foo(x = super.x) {\\n} });\\n\")\n\n\texpectParseError(t, \"class Foo { [super.x] }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"class Foo { [super[x]] }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"class Foo { static [super.x] }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"class Foo { static [super[x]] }\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"(class { [super.x] })\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"(class { [super[x]] })\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"(class { static [super.x] })\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseError(t, \"(class { static [super[x]] })\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n}\n\nfunc TestClassFields(t *testing.T) {\n\texpectPrinted(t, \"class Foo { a }\", \"class Foo {\\n  a;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { a = 1 }\", \"class Foo {\\n  a = 1;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { a = 1; b }\", \"class Foo {\\n  a = 1;\\n  b;\\n}\\n\")\n\texpectParseError(t, \"class Foo { a = 1 b }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"b\\\"\\n\")\n\n\texpectPrinted(t, \"class Foo { [a] }\", \"class Foo {\\n  [a];\\n}\\n\")\n\texpectPrinted(t, \"class Foo { [a] = 1 }\", \"class Foo {\\n  [a] = 1;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { [a] = 1; [b] }\", \"class Foo {\\n  [a] = 1;\\n  [b];\\n}\\n\")\n\texpectParseError(t, \"class Foo { [a] = 1 b }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"b\\\"\\n\")\n\n\texpectPrinted(t, \"class Foo { static a }\", \"class Foo {\\n  static a;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static a = 1 }\", \"class Foo {\\n  static a = 1;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static a = 1; b }\", \"class Foo {\\n  static a = 1;\\n  b;\\n}\\n\")\n\texpectParseError(t, \"class Foo { static a = 1 b }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"b\\\"\\n\")\n\n\texpectPrinted(t, \"class Foo { static [a] }\", \"class Foo {\\n  static [a];\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static [a] = 1 }\", \"class Foo {\\n  static [a] = 1;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static [a] = 1; [b] }\", \"class Foo {\\n  static [a] = 1;\\n  [b];\\n}\\n\")\n\texpectParseError(t, \"class Foo { static [a] = 1 b }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"b\\\"\\n\")\n\n\texpectParseError(t, \"class Foo { get a }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"}\\\"\\n\")\n\texpectParseError(t, \"class Foo { set a }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"}\\\"\\n\")\n\texpectParseError(t, \"class Foo { async a }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"}\\\"\\n\")\n\n\texpectParseError(t, \"class Foo { get a = 1 }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"=\\\"\\n\")\n\texpectParseError(t, \"class Foo { set a = 1 }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"=\\\"\\n\")\n\texpectParseError(t, \"class Foo { async a = 1 }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"=\\\"\\n\")\n\n\texpectParseError(t, \"class Foo { `a` = 0 }\", \"<stdin>: ERROR: Expected identifier but found \\\"`a`\\\"\\n\")\n\n\t// The name \"constructor\" is forbidden\n\texpectParseError(t, \"class Foo { constructor }\", \"<stdin>: ERROR: Invalid field name \\\"constructor\\\"\\n\")\n\texpectParseError(t, \"class Foo { 'constructor' }\", \"<stdin>: ERROR: Invalid field name \\\"constructor\\\"\\n\")\n\texpectParseError(t, \"class Foo { constructor = 1 }\", \"<stdin>: ERROR: Invalid field name \\\"constructor\\\"\\n\")\n\texpectParseError(t, \"class Foo { 'constructor' = 1 }\", \"<stdin>: ERROR: Invalid field name \\\"constructor\\\"\\n\")\n\texpectParseError(t, \"class Foo { static constructor }\", \"<stdin>: ERROR: Invalid field name \\\"constructor\\\"\\n\")\n\texpectParseError(t, \"class Foo { static 'constructor' }\", \"<stdin>: ERROR: Invalid field name \\\"constructor\\\"\\n\")\n\texpectParseError(t, \"class Foo { static constructor = 1 }\", \"<stdin>: ERROR: Invalid field name \\\"constructor\\\"\\n\")\n\texpectParseError(t, \"class Foo { static 'constructor' = 1 }\", \"<stdin>: ERROR: Invalid field name \\\"constructor\\\"\\n\")\n\n\texpectPrinted(t, \"class Foo { ['constructor'] }\", \"class Foo {\\n  [\\\"constructor\\\"];\\n}\\n\")\n\texpectPrinted(t, \"class Foo { ['constructor'] = 1 }\", \"class Foo {\\n  [\\\"constructor\\\"] = 1;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static ['constructor'] }\", \"class Foo {\\n  static [\\\"constructor\\\"];\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static ['constructor'] = 1 }\", \"class Foo {\\n  static [\\\"constructor\\\"] = 1;\\n}\\n\")\n\n\t// The name \"prototype\" is sometimes forbidden\n\texpectPrinted(t, \"class Foo { prototype }\", \"class Foo {\\n  prototype;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { 'prototype' }\", \"class Foo {\\n  \\\"prototype\\\";\\n}\\n\")\n\texpectPrinted(t, \"class Foo { prototype = 1 }\", \"class Foo {\\n  prototype = 1;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { 'prototype' = 1 }\", \"class Foo {\\n  \\\"prototype\\\" = 1;\\n}\\n\")\n\texpectParseError(t, \"class Foo { static prototype }\", \"<stdin>: ERROR: Invalid field name \\\"prototype\\\"\\n\")\n\texpectParseError(t, \"class Foo { static 'prototype' }\", \"<stdin>: ERROR: Invalid field name \\\"prototype\\\"\\n\")\n\texpectParseError(t, \"class Foo { static prototype = 1 }\", \"<stdin>: ERROR: Invalid field name \\\"prototype\\\"\\n\")\n\texpectParseError(t, \"class Foo { static 'prototype' = 1 }\", \"<stdin>: ERROR: Invalid field name \\\"prototype\\\"\\n\")\n\texpectPrinted(t, \"class Foo { static ['prototype'] }\", \"class Foo {\\n  static [\\\"prototype\\\"];\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static ['prototype'] = 1 }\", \"class Foo {\\n  static [\\\"prototype\\\"] = 1;\\n}\\n\")\n}\n\nfunc TestClassStaticBlocks(t *testing.T) {\n\texpectPrinted(t, \"class Foo { static {} }\", \"class Foo {\\n  static {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static {} x = 1 }\", \"class Foo {\\n  static {\\n  }\\n  x = 1;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static { this.foo() } }\", \"class Foo {\\n  static {\\n    this.foo();\\n  }\\n}\\n\")\n\n\texpectParseError(t, \"class Foo { static { yield } }\",\n\t\t\"<stdin>: ERROR: \\\"yield\\\" is a reserved word and cannot be used in strict mode\\n\"+\n\t\t\t\"<stdin>: NOTE: All code inside a class is implicitly in strict mode\\n\")\n\texpectParseError(t, \"class Foo { static { await } }\", \"<stdin>: ERROR: The keyword \\\"await\\\" cannot be used here:\\n\")\n\texpectParseError(t, \"class Foo { static { return } }\", \"<stdin>: ERROR: A return statement cannot be used here:\\n\")\n\texpectParseError(t, \"class Foo { static { break } }\", \"<stdin>: ERROR: Cannot use \\\"break\\\" here:\\n\")\n\texpectParseError(t, \"class Foo { static { continue } }\", \"<stdin>: ERROR: Cannot use \\\"continue\\\" here:\\n\")\n\texpectParseError(t, \"x: { class Foo { static { break x } } }\", \"<stdin>: ERROR: There is no containing label named \\\"x\\\"\\n\")\n\texpectParseError(t, \"x: { class Foo { static { continue x } } }\", \"<stdin>: ERROR: There is no containing label named \\\"x\\\"\\n\")\n\n\texpectPrintedMangle(t, \"class Foo { static {} }\", \"class Foo {\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { static { 123 } }\", \"class Foo {\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { static { /* @__PURE__ */ foo() } }\", \"class Foo {\\n}\\n\")\n\texpectPrintedMangle(t, \"class Foo { static { foo() } }\", \"class Foo {\\n  static {\\n    foo();\\n  }\\n}\\n\")\n}\n\nfunc TestAutoAccessors(t *testing.T) {\n\texpectPrinted(t, \"class Foo { accessor }\", \"class Foo {\\n  accessor;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { accessor \\n x }\", \"class Foo {\\n  accessor;\\n  x;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static accessor }\", \"class Foo {\\n  static accessor;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static accessor \\n x }\", \"class Foo {\\n  static accessor;\\n  x;\\n}\\n\")\n\n\texpectPrinted(t, \"class Foo { accessor x }\", \"class Foo {\\n  accessor x;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { accessor x = y }\", \"class Foo {\\n  accessor x = y;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { accessor [x] }\", \"class Foo {\\n  accessor [x];\\n}\\n\")\n\texpectPrinted(t, \"class Foo { accessor [x] = y }\", \"class Foo {\\n  accessor [x] = y;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static accessor x }\", \"class Foo {\\n  static accessor x;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static accessor [x] }\", \"class Foo {\\n  static accessor [x];\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static accessor x = y }\", \"class Foo {\\n  static accessor x = y;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static accessor [x] = y }\", \"class Foo {\\n  static accessor [x] = y;\\n}\\n\")\n\n\texpectPrinted(t, \"Foo = class { accessor x }\", \"Foo = class {\\n  accessor x;\\n};\\n\")\n\texpectPrinted(t, \"Foo = class { accessor [x] }\", \"Foo = class {\\n  accessor [x];\\n};\\n\")\n\texpectPrinted(t, \"Foo = class { accessor x = y }\", \"Foo = class {\\n  accessor x = y;\\n};\\n\")\n\texpectPrinted(t, \"Foo = class { accessor [x] = y }\", \"Foo = class {\\n  accessor [x] = y;\\n};\\n\")\n\texpectPrinted(t, \"Foo = class { static accessor x }\", \"Foo = class {\\n  static accessor x;\\n};\\n\")\n\texpectPrinted(t, \"Foo = class { static accessor [x] }\", \"Foo = class {\\n  static accessor [x];\\n};\\n\")\n\texpectPrinted(t, \"Foo = class { static accessor x = y }\", \"Foo = class {\\n  static accessor x = y;\\n};\\n\")\n\n\texpectPrinted(t, \"class Foo { accessor get }\", \"class Foo {\\n  accessor get;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { get accessor() {} }\", \"class Foo {\\n  get accessor() {\\n  }\\n}\\n\")\n\texpectParseError(t, \"class Foo { accessor x() {} }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"class Foo { accessor get x() {} }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"class Foo { get accessor x() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"x\\\"\\n\")\n\n\texpectPrinted(t, \"Foo = { get accessor() {} }\", \"Foo = { get accessor() {\\n} };\\n\")\n\texpectParseError(t, \"Foo = { accessor x }\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"Foo = { accessor x() {} }\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"Foo = { get accessor x() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"x\\\"\\n\")\n\n\texpectParseError(t, \"class Foo { accessor x, y }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\",\\\"\\n\")\n\texpectParseError(t, \"class Foo { static accessor x, y }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\",\\\"\\n\")\n\texpectParseError(t, \"Foo = class { accessor x, y }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\",\\\"\\n\")\n\texpectParseError(t, \"Foo = class { static accessor x, y }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\",\\\"\\n\")\n}\n\nfunc TestDecorators(t *testing.T) {\n\texpectPrinted(t, \"@x @y class Foo {}\", \"@x @y class Foo {\\n}\\n\")\n\texpectPrinted(t, \"@x @y export class Foo {}\", \"@x @y export class Foo {\\n}\\n\")\n\texpectPrinted(t, \"@x @y export default class Foo {}\", \"@x @y export default class Foo {\\n}\\n\")\n\texpectPrinted(t, \"_ = @x @y class {}\", \"_ = @x @y class {\\n};\\n\")\n\n\texpectPrinted(t, \"class Foo { @x y }\", \"class Foo {\\n  @x y;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { @x y() {} }\", \"class Foo {\\n  @x y() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { @x static y }\", \"class Foo {\\n  @x static y;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { @x static y() {} }\", \"class Foo {\\n  @x static y() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { @x accessor y }\", \"class Foo {\\n  @x accessor y;\\n}\\n\")\n\n\texpectPrinted(t, \"class Foo { @x #y }\", \"class Foo {\\n  @x #y;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { @x #y() {} }\", \"class Foo {\\n  @x #y() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { @x static #y }\", \"class Foo {\\n  @x static #y;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { @x static #y() {} }\", \"class Foo {\\n  @x static #y() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { @x accessor #y }\", \"class Foo {\\n  @x accessor #y;\\n}\\n\")\n\n\texpectParseError(t, \"class Foo { x(@y z) {} }\", \"<stdin>: ERROR: Parameter decorators are not allowed in JavaScript\\n\")\n\texpectParseError(t, \"class Foo { @x static {} }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"{\\\"\\n\")\n\n\texpectPrinted(t, \"@\\na\\n(\\n)\\n@\\n(\\nb\\n)\\nclass\\nFoo\\n{\\n}\\n\", \"@a()\\n@b\\nclass Foo {\\n}\\n\")\n\texpectPrinted(t, \"@(a, b) class Foo {}\", \"@(a, b) class Foo {\\n}\\n\")\n\texpectPrinted(t, \"@x() class Foo {}\", \"@x() class Foo {\\n}\\n\")\n\texpectPrinted(t, \"@x.y() class Foo {}\", \"@x.y() class Foo {\\n}\\n\")\n\texpectPrinted(t, \"@(() => {}) class Foo {}\", \"@(() => {\\n}) class Foo {\\n}\\n\")\n\texpectPrinted(t, \"class Foo { #x = @y.#x.y.#x class {} }\", \"class Foo {\\n  #x = @y.#x.y.#x class {\\n  };\\n}\\n\")\n\texpectParseError(t, \"@123 class Foo {}\", \"<stdin>: ERROR: Expected identifier but found \\\"123\\\"\\n\")\n\texpectParseError(t, \"@x[y] class Foo {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"class\\\"\\n\")\n\texpectParseError(t, \"@x?.() class Foo {}\", \"<stdin>: ERROR: Expected identifier but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"@x?.y() class Foo {}\",\n\t\t\"<stdin>: ERROR: JavaScript decorator syntax does not allow \\\"?.\\\" here\\n\"+\n\t\t\t\"<stdin>: NOTE: Wrap this decorator in parentheses to allow arbitrary expressions:\\n\")\n\texpectParseError(t, \"@x?.[y]() class Foo {}\", \"<stdin>: ERROR: Expected identifier but found \\\"[\\\"\\n\")\n\texpectParseError(t, \"@new Function() class Foo {}\", \"<stdin>: ERROR: Expected identifier but found \\\"new\\\"\\n\")\n\texpectParseError(t, \"@() => {} class Foo {}\", \"<stdin>: ERROR: Unexpected \\\")\\\"\\n\")\n\texpectParseError(t, \"x = @y function() {}\", \"<stdin>: ERROR: Expected \\\"class\\\" but found \\\"function\\\"\\n\")\n\n\t// See: https://github.com/microsoft/TypeScript/issues/55336\n\texpectParseError(t, \"@x().y() class Foo {}\",\n\t\t\"<stdin>: ERROR: JavaScript decorator syntax does not allow \\\".\\\" after a call expression\\n\"+\n\t\t\t\"<stdin>: NOTE: Wrap this decorator in parentheses to allow arbitrary expressions:\\n\")\n\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators, \"@dec class Foo {}\",\n\t\t`var _Foo_decorators, _init;\n_Foo_decorators = [dec];\nclass Foo {\n}\n_init = __decoratorStart(null);\nFoo = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, Foo);\n__runInitializers(_init, 1, Foo);\n`)\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators, \"class Foo { @dec x }\",\n\t\t`var _x_dec, _init;\n_x_dec = [dec];\nclass Foo {\n  constructor() {\n    __publicField(this, \"x\", __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);\n  }\n}\n_init = __decoratorStart(null);\n__decorateElement(_init, 5, \"x\", _x_dec, Foo);\n__decoratorMetadata(_init, Foo);\n`)\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators, \"class Foo { @dec x() {} }\",\n\t\t`var _x_dec, _init;\n_x_dec = [dec];\nclass Foo {\n  constructor() {\n    __runInitializers(_init, 5, this);\n  }\n  x() {\n  }\n}\n_init = __decoratorStart(null);\n__decorateElement(_init, 1, \"x\", _x_dec, Foo);\n__decoratorMetadata(_init, Foo);\n`)\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators, \"class Foo { @dec accessor x }\",\n\t\t`var _x_dec, _init, _x;\n_x_dec = [dec];\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x, __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);\n  }\n}\n_init = __decoratorStart(null);\n_x = new WeakMap();\n__decorateElement(_init, 4, \"x\", _x_dec, Foo, _x);\n__decoratorMetadata(_init, Foo);\n`)\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators, \"class Foo { @dec static x }\",\n\t\t`var _x_dec, _init;\n_x_dec = [dec];\nclass Foo {\n}\n_init = __decoratorStart(null);\n__decorateElement(_init, 13, \"x\", _x_dec, Foo);\n__decoratorMetadata(_init, Foo);\n__publicField(Foo, \"x\", __runInitializers(_init, 8, Foo)), __runInitializers(_init, 11, Foo);\n`)\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators, \"class Foo { @dec static x() {} }\",\n\t\t`var _x_dec, _init;\n_x_dec = [dec];\nclass Foo {\n  static x() {\n  }\n}\n_init = __decoratorStart(null);\n__decorateElement(_init, 9, \"x\", _x_dec, Foo);\n__decoratorMetadata(_init, Foo);\n__runInitializers(_init, 3, Foo);\n`)\n\texpectPrintedWithUnsupportedFeatures(t, compat.Decorators, \"class Foo { @dec static accessor x }\",\n\t\t`var _x_dec, _init, _x;\n_x_dec = [dec];\nclass Foo {\n}\n_init = __decoratorStart(null);\n_x = new WeakMap();\n__decorateElement(_init, 12, \"x\", _x_dec, Foo, _x);\n__decoratorMetadata(_init, Foo);\n__privateAdd(Foo, _x, __runInitializers(_init, 8, Foo)), __runInitializers(_init, 11, Foo);\n`)\n\n\t// Check ASI for \"abstract\"\n\texpectParseError(t, \"@x abstract class Foo {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"class\\\"\\n\")\n\texpectParseError(t, \"@x abstract\\nclass Foo {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\n\t// Check decorator locations in relation to the \"export\" keyword\n\texpectPrinted(t, \"@x export class Foo {}\", \"@x export class Foo {\\n}\\n\")\n\texpectPrinted(t, \"export @x class Foo {}\", \"@x export class Foo {\\n}\\n\")\n\texpectPrinted(t, \"@x export default class {}\", \"@x export default class {\\n}\\n\")\n\texpectPrinted(t, \"export default @x class {}\", \"@x export default class {\\n}\\n\")\n\texpectPrinted(t, \"@x export default class Foo {}\", \"@x export default class Foo {\\n}\\n\")\n\texpectPrinted(t, \"export default @x class Foo {}\", \"@x export default class Foo {\\n}\\n\")\n\texpectPrinted(t, \"export default (@x class {})\", \"export default (@x class {\\n});\\n\")\n\texpectPrinted(t, \"export default (@x class Foo {})\", \"export default (@x class Foo {\\n});\\n\")\n\texpectParseError(t, \"export @x default class {}\", \"<stdin>: ERROR: Unexpected \\\"default\\\"\\n\")\n\texpectParseError(t, \"@x export @y class Foo {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseError(t, \"@x export default abstract\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseError(t, \"@x export @y default class {}\", \"<stdin>: ERROR: Decorators are not valid here\\n<stdin>: ERROR: Unexpected \\\"default\\\"\\n\")\n\n\t// Disallow TypeScript syntax in JavaScript\n\texpectParseError(t, \"@x!.y!.z class Foo {}\", \"<stdin>: ERROR: Unexpected \\\"!\\\"\\n\")\n}\n\nfunc TestGenerator(t *testing.T) {\n\texpectParseError(t, \"(class { * foo })\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"}\\\"\\n\")\n\texpectParseError(t, \"(class { * *foo() {} })\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\texpectParseError(t, \"(class { get*foo() {} })\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"*\\\"\\n\")\n\texpectParseError(t, \"(class { set*foo() {} })\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"*\\\"\\n\")\n\texpectParseError(t, \"(class { *get foo() {} })\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"foo\\\"\\n\")\n\texpectParseError(t, \"(class { *set foo() {} })\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"foo\\\"\\n\")\n\texpectParseError(t, \"(class { *static foo() {} })\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"foo\\\"\\n\")\n\texpectParseError(t, \"(class { *async foo() {} })\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"foo\\\"\\n\")\n\texpectParseError(t, \"(class { async * *foo() {} })\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\n\texpectParseError(t, \"function* foo() { -yield 100 }\", \"<stdin>: ERROR: Cannot use a \\\"yield\\\" expression here without parentheses:\\n\")\n\texpectPrinted(t, \"function* foo() { -(yield 100) }\", \"function* foo() {\\n  -(yield 100);\\n}\\n\")\n}\n\nfunc TestYield(t *testing.T) {\n\texpectParseError(t, \"yield 100\", \"<stdin>: ERROR: Cannot use \\\"yield\\\" outside a generator function\\n\")\n\texpectParseError(t, \"-yield 100\", \"<stdin>: ERROR: Cannot use \\\"yield\\\" outside a generator function\\n\")\n\texpectPrinted(t, \"yield\\n100\", \"yield;\\n100;\\n\")\n\n\tnoYield := \"<stdin>: ERROR: The keyword \\\"yield\\\" cannot be used here:\\n\"\n\texpectParseError(t, \"function* bar(x = yield y) {}\", noYield+\"<stdin>: ERROR: Expected \\\")\\\" but found \\\"y\\\"\\n\")\n\texpectParseError(t, \"(function*(x = yield y) {})\", noYield+\"<stdin>: ERROR: Expected \\\")\\\" but found \\\"y\\\"\\n\")\n\texpectParseError(t, \"({ *foo(x = yield y) {} })\", noYield+\"<stdin>: ERROR: Expected \\\")\\\" but found \\\"y\\\"\\n\")\n\texpectParseError(t, \"class Foo { *foo(x = yield y) {} }\", noYield+\"<stdin>: ERROR: Expected \\\")\\\" but found \\\"y\\\"\\n\")\n\texpectParseError(t, \"(class { *foo(x = yield y) {} })\", noYield+\"<stdin>: ERROR: Expected \\\")\\\" but found \\\"y\\\"\\n\")\n\n\texpectParseError(t, \"function *foo() { function bar(x = yield y) {} }\", \"<stdin>: ERROR: Cannot use \\\"yield\\\" outside a generator function\\n\")\n\texpectParseError(t, \"function *foo() { (function(x = yield y) {}) }\", \"<stdin>: ERROR: Cannot use \\\"yield\\\" outside a generator function\\n\")\n\texpectParseError(t, \"function *foo() { ({ foo(x = yield y) {} }) }\", \"<stdin>: ERROR: Cannot use \\\"yield\\\" outside a generator function\\n\")\n\texpectParseError(t, \"function *foo() { class Foo { foo(x = yield y) {} } }\", \"<stdin>: ERROR: Cannot use \\\"yield\\\" outside a generator function\\n\")\n\texpectParseError(t, \"function *foo() { (class { foo(x = yield y) {} }) }\", \"<stdin>: ERROR: Cannot use \\\"yield\\\" outside a generator function\\n\")\n\texpectParseError(t, \"function *foo() { (x = yield y) => {} }\", \"<stdin>: ERROR: Cannot use a \\\"yield\\\" expression here:\\n\")\n\texpectPrinted(t, \"function *foo() { x = yield }\", \"function* foo() {\\n  x = yield;\\n}\\n\")\n\texpectPrinted(t, \"function *foo() { x = yield; }\", \"function* foo() {\\n  x = yield;\\n}\\n\")\n\texpectPrinted(t, \"function *foo() { (x = yield) }\", \"function* foo() {\\n  x = yield;\\n}\\n\")\n\texpectPrinted(t, \"function *foo() { [x = yield] }\", \"function* foo() {\\n  [x = yield];\\n}\\n\")\n\texpectPrinted(t, \"function *foo() { x = (yield, yield) }\", \"function* foo() {\\n  x = (yield, yield);\\n}\\n\")\n\texpectPrinted(t, \"function *foo() { x = y ? yield : yield }\", \"function* foo() {\\n  x = y ? yield : yield;\\n}\\n\")\n\texpectParseError(t, \"function *foo() { x = yield ? y : z }\", \"<stdin>: ERROR: Unexpected \\\"?\\\"\\n\")\n\texpectParseError(t, \"function *foo() { x = yield * }\", \"<stdin>: ERROR: Unexpected \\\"}\\\"\\n\")\n\texpectParseError(t, \"function *foo() { (x = yield *) }\", \"<stdin>: ERROR: Unexpected \\\")\\\"\\n\")\n\texpectParseError(t, \"function *foo() { [x = yield *] }\", \"<stdin>: ERROR: Unexpected \\\"]\\\"\\n\")\n\texpectPrinted(t, \"function *foo() { x = yield y }\", \"function* foo() {\\n  x = yield y;\\n}\\n\")\n\texpectPrinted(t, \"function *foo() { (x = yield y) }\", \"function* foo() {\\n  x = yield y;\\n}\\n\")\n\texpectPrinted(t, \"function *foo() { x = yield \\n y }\", \"function* foo() {\\n  x = yield;\\n  y;\\n}\\n\")\n\texpectPrinted(t, \"function *foo() { x = yield * y }\", \"function* foo() {\\n  x = yield* y;\\n}\\n\")\n\texpectPrinted(t, \"function *foo() { (x = yield * y) }\", \"function* foo() {\\n  x = yield* y;\\n}\\n\")\n\texpectPrinted(t, \"function *foo() { x = yield * \\n y }\", \"function* foo() {\\n  x = yield* y;\\n}\\n\")\n\texpectParseError(t, \"function *foo() { x = yield \\n * y }\", \"<stdin>: ERROR: Unexpected \\\"*\\\"\\n\")\n\texpectParseError(t, \"function foo() { (x = yield y) }\", \"<stdin>: ERROR: Cannot use \\\"yield\\\" outside a generator function\\n\")\n\texpectPrinted(t, \"function foo() { x = yield * y }\", \"function foo() {\\n  x = yield * y;\\n}\\n\")\n\texpectPrinted(t, \"function foo() { (x = yield * y) }\", \"function foo() {\\n  x = yield * y;\\n}\\n\")\n\texpectParseError(t, \"function *foo() { (x = \\\\u0079ield) }\", \"<stdin>: ERROR: The keyword \\\"yield\\\" cannot be escaped\\n\")\n\texpectParseError(t, \"function *foo() { (x = \\\\u0079ield* y) }\", \"<stdin>: ERROR: The keyword \\\"yield\\\" cannot be escaped\\n\")\n\n\t// Yield as an identifier\n\texpectPrinted(t, \"({yield} = x)\", \"({ yield } = x);\\n\")\n\texpectPrinted(t, \"let x = {yield}\", \"let x = { yield };\\n\")\n\texpectPrinted(t, \"function* yield() {}\", \"function* yield() {\\n}\\n\")\n\texpectPrinted(t, \"function foo() { ({yield} = x) }\", \"function foo() {\\n  ({ yield } = x);\\n}\\n\")\n\texpectPrinted(t, \"function foo() { let x = {yield} }\", \"function foo() {\\n  let x = { yield };\\n}\\n\")\n\texpectParseError(t, \"function *foo() { ({yield} = x) }\", \"<stdin>: ERROR: Cannot use \\\"yield\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"function *foo() { let x = {yield} }\", \"<stdin>: ERROR: Cannot use \\\"yield\\\" as an identifier here:\\n\")\n\n\t// Yield as a declaration\n\texpectPrinted(t, \"({ *yield() {} })\", \"({ *yield() {\\n} });\\n\")\n\texpectPrinted(t, \"(class { *yield() {} })\", \"(class {\\n  *yield() {\\n  }\\n});\\n\")\n\texpectPrinted(t, \"class Foo { *yield() {} }\", \"class Foo {\\n  *yield() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"function* yield() {}\", \"function* yield() {\\n}\\n\")\n\texpectParseError(t, \"(function* yield() {})\", \"<stdin>: ERROR: A generator function expression cannot be named \\\"yield\\\"\\n\")\n\n\t// Yield as an async declaration\n\texpectPrinted(t, \"({ async *yield() {} })\", \"({ async *yield() {\\n} });\\n\")\n\texpectPrinted(t, \"(class { async *yield() {} })\", \"(class {\\n  async *yield() {\\n  }\\n});\\n\")\n\texpectPrinted(t, \"class Foo { async *yield() {} }\", \"class Foo {\\n  async *yield() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"async function* yield() {}\", \"async function* yield() {\\n}\\n\")\n\texpectParseError(t, \"(async function* yield() {})\", \"<stdin>: ERROR: A generator function expression cannot be named \\\"yield\\\"\\n\")\n}\n\nfunc TestAsync(t *testing.T) {\n\texpectPrinted(t, \"function foo() { await }\", \"function foo() {\\n  await;\\n}\\n\")\n\texpectPrinted(t, \"async function foo() { await 0 }\", \"async function foo() {\\n  await 0;\\n}\\n\")\n\texpectParseError(t, \"async function() {}\", \"<stdin>: ERROR: Expected identifier but found \\\"(\\\"\\n\")\n\n\texpectPrinted(t, \"-async function foo() { await 0 }\", \"-async function foo() {\\n  await 0;\\n};\\n\")\n\texpectPrinted(t, \"-async function() { await 0 }\", \"-async function() {\\n  await 0;\\n};\\n\")\n\texpectPrinted(t, \"1 - async function foo() { await 0 }\", \"1 - async function foo() {\\n  await 0;\\n};\\n\")\n\texpectPrinted(t, \"1 - async function() { await 0 }\", \"1 - async function() {\\n  await 0;\\n};\\n\")\n\texpectPrinted(t, \"(async function foo() { await 0 })\", \"(async function foo() {\\n  await 0;\\n});\\n\")\n\texpectPrinted(t, \"(async function() { await 0 })\", \"(async function() {\\n  await 0;\\n});\\n\")\n\texpectPrinted(t, \"(x, async function foo() { await 0 })\", \"x, async function foo() {\\n  await 0;\\n};\\n\")\n\texpectPrinted(t, \"(x, async function() { await 0 })\", \"x, async function() {\\n  await 0;\\n};\\n\")\n\texpectPrinted(t, \"new async function() { await 0 }\", \"new async function() {\\n  await 0;\\n}();\\n\")\n\texpectPrinted(t, \"new async function() { await 0 }.x\", \"new async function() {\\n  await 0;\\n}.x();\\n\")\n\n\tfriendlyAwaitError := \"<stdin>: ERROR: \\\"await\\\" can only be used inside an \\\"async\\\" function\\n\"\n\tfriendlyAwaitErrorWithNote := friendlyAwaitError + \"<stdin>: NOTE: Consider adding the \\\"async\\\" keyword here:\\n\"\n\n\texpectPrinted(t, \"async\", \"async;\\n\")\n\texpectPrinted(t, \"async + 1\", \"async + 1;\\n\")\n\texpectPrinted(t, \"async => {}\", \"(async) => {\\n};\\n\")\n\texpectPrinted(t, \"(async, 1)\", \"async, 1;\\n\")\n\texpectPrinted(t, \"(async, x) => {}\", \"(async, x) => {\\n};\\n\")\n\texpectPrinted(t, \"async ()\", \"async();\\n\")\n\texpectPrinted(t, \"async (x)\", \"async(x);\\n\")\n\texpectPrinted(t, \"async (...x)\", \"async(...x);\\n\")\n\texpectPrinted(t, \"async (...x, ...y)\", \"async(...x, ...y);\\n\")\n\texpectPrinted(t, \"async () => {}\", \"async () => {\\n};\\n\")\n\texpectPrinted(t, \"async x => {}\", \"async (x) => {\\n};\\n\")\n\texpectPrinted(t, \"async (x) => {}\", \"async (x) => {\\n};\\n\")\n\texpectPrinted(t, \"async (...x) => {}\", \"async (...x) => {\\n};\\n\")\n\texpectPrinted(t, \"async x => await 0\", \"async (x) => await 0;\\n\")\n\texpectPrinted(t, \"async () => await 0\", \"async () => await 0;\\n\")\n\texpectPrinted(t, \"new async()\", \"new async();\\n\")\n\texpectPrinted(t, \"new async().x\", \"new async().x;\\n\")\n\texpectPrinted(t, \"new (async())\", \"new (async())();\\n\")\n\texpectPrinted(t, \"new (async().x)\", \"new (async()).x();\\n\")\n\texpectParseError(t, \"async x;\", \"<stdin>: ERROR: Expected \\\"=>\\\" but found \\\";\\\"\\n\")\n\texpectParseError(t, \"async (...x,) => {}\", \"<stdin>: ERROR: Unexpected \\\",\\\" after rest pattern\\n\")\n\texpectParseError(t, \"async => await 0\", friendlyAwaitErrorWithNote)\n\texpectParseError(t, \"new async => {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"=>\\\"\\n\")\n\texpectParseError(t, \"new async () => {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"=>\\\"\\n\")\n\n\texpectPrinted(t, \"(async x => y), z\", \"(async (x) => y), z;\\n\")\n\texpectPrinted(t, \"(async x => y, z)\", \"async (x) => y, z;\\n\")\n\texpectPrinted(t, \"(async x => (y, z))\", \"(async (x) => (y, z));\\n\")\n\texpectPrinted(t, \"(async (x) => y), z\", \"(async (x) => y), z;\\n\")\n\texpectPrinted(t, \"(async (x) => y, z)\", \"async (x) => y, z;\\n\")\n\texpectPrinted(t, \"(async (x) => (y, z))\", \"(async (x) => (y, z));\\n\")\n\texpectPrinted(t, \"async x => y, z\", \"async (x) => y, z;\\n\")\n\texpectPrinted(t, \"async x => (y, z)\", \"async (x) => (y, z);\\n\")\n\texpectPrinted(t, \"async (x) => y, z\", \"async (x) => y, z;\\n\")\n\texpectPrinted(t, \"async (x) => (y, z)\", \"async (x) => (y, z);\\n\")\n\texpectPrinted(t, \"export default async x => (y, z)\", \"export default async (x) => (y, z);\\n\")\n\texpectPrinted(t, \"export default async (x) => (y, z)\", \"export default async (x) => (y, z);\\n\")\n\texpectParseError(t, \"export default async x => y, z\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\",\\\"\\n\")\n\texpectParseError(t, \"export default async (x) => y, z\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\",\\\"\\n\")\n\n\texpectPrinted(t, \"class Foo { async async() {} }\", \"class Foo {\\n  async async() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"(class { async async() {} })\", \"(class {\\n  async async() {\\n  }\\n});\\n\")\n\texpectPrinted(t, \"({ async async() {} })\", \"({ async async() {\\n} });\\n\")\n\texpectParseError(t, \"class Foo { async async }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"}\\\"\\n\")\n\texpectParseError(t, \"(class { async async })\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"}\\\"\\n\")\n\texpectParseError(t, \"({ async async })\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"}\\\"\\n\")\n\n\tnoAwait := \"<stdin>: ERROR: The keyword \\\"await\\\" cannot be used here:\\n\"\n\texpectParseError(t, \"async function bar(x = await y) {}\", noAwait+\"<stdin>: ERROR: Expected \\\")\\\" but found \\\"y\\\"\\n\")\n\texpectParseError(t, \"async (function(x = await y) {})\", friendlyAwaitError)\n\texpectParseError(t, \"async ({ foo(x = await y) {} })\", friendlyAwaitError)\n\texpectParseError(t, \"class Foo { async foo(x = await y) {} }\", noAwait+\"<stdin>: ERROR: Expected \\\")\\\" but found \\\"y\\\"\\n\")\n\texpectParseError(t, \"(class { async foo(x = await y) {} })\", noAwait+\"<stdin>: ERROR: Expected \\\")\\\" but found \\\"y\\\"\\n\")\n\n\texpectParseError(t, \"async function foo() { function bar(x = await y) {} }\", friendlyAwaitError)\n\texpectParseError(t, \"async function foo() { (function(x = await y) {}) }\", friendlyAwaitError)\n\texpectParseError(t, \"async function foo() { ({ foo(x = await y) {} }) }\", friendlyAwaitError)\n\texpectParseError(t, \"async function foo() { class Foo { foo(x = await y) {} } }\", friendlyAwaitError)\n\texpectParseError(t, \"async function foo() { (class { foo(x = await y) {} }) }\", friendlyAwaitError)\n\texpectParseError(t, \"async function foo() { (x = await y) => {} }\", \"<stdin>: ERROR: Cannot use an \\\"await\\\" expression here:\\n\")\n\texpectParseError(t, \"async function foo(x = await y) {}\", \"<stdin>: ERROR: The keyword \\\"await\\\" cannot be used here:\\n<stdin>: ERROR: Expected \\\")\\\" but found \\\"y\\\"\\n\")\n\texpectParseError(t, \"async function foo({ [await y]: x }) {}\", \"<stdin>: ERROR: The keyword \\\"await\\\" cannot be used here:\\n<stdin>: ERROR: Expected \\\"]\\\" but found \\\"y\\\"\\n\")\n\texpectPrinted(t, \"async function foo() { (x = await y) }\", \"async function foo() {\\n  x = await y;\\n}\\n\")\n\texpectParseError(t, \"function foo() { (x = await y) }\", friendlyAwaitErrorWithNote)\n\n\t// Newlines\n\texpectPrinted(t, \"(class { async \\n foo() {} })\", \"(class {\\n  async;\\n  foo() {\\n  }\\n});\\n\")\n\texpectPrinted(t, \"(class { async \\n *foo() {} })\", \"(class {\\n  async;\\n  *foo() {\\n  }\\n});\\n\")\n\texpectParseError(t, \"({ async \\n foo() {} })\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"foo\\\"\\n\")\n\texpectParseError(t, \"({ async \\n *foo() {} })\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"*\\\"\\n\")\n\n\t// Top-level await\n\texpectPrinted(t, \"await foo;\", \"await foo;\\n\")\n\texpectPrinted(t, \"for await(foo of bar);\", \"for await (foo of bar) ;\\n\")\n\texpectParseError(t, \"function foo() { await foo }\", friendlyAwaitErrorWithNote)\n\texpectParseError(t, \"function foo() { for await(foo of bar); }\", \"<stdin>: ERROR: Cannot use \\\"await\\\" outside an async function\\n\")\n\texpectPrinted(t, \"function foo(x = await) {}\", \"function foo(x = await) {\\n}\\n\")\n\texpectParseError(t, \"function foo(x = await y) {}\", friendlyAwaitError)\n\texpectPrinted(t, \"(function(x = await) {})\", \"(function(x = await) {\\n});\\n\")\n\texpectParseError(t, \"(function(x = await y) {})\", friendlyAwaitError)\n\texpectPrinted(t, \"({ foo(x = await) {} })\", \"({ foo(x = await) {\\n} });\\n\")\n\texpectParseError(t, \"({ foo(x = await y) {} })\", friendlyAwaitError)\n\texpectPrinted(t, \"class Foo { foo(x = await) {} }\", \"class Foo {\\n  foo(x = await) {\\n  }\\n}\\n\")\n\texpectParseError(t, \"class Foo { foo(x = await y) {} }\", friendlyAwaitError)\n\texpectPrinted(t, \"(class { foo(x = await) {} })\", \"(class {\\n  foo(x = await) {\\n  }\\n});\\n\")\n\texpectParseError(t, \"(class { foo(x = await y) {} })\", friendlyAwaitError)\n\texpectParseError(t, \"(x = await) => {}\", \"<stdin>: ERROR: Unexpected \\\")\\\"\\n\")\n\texpectParseError(t, \"(x = await y) => {}\", \"<stdin>: ERROR: Cannot use an \\\"await\\\" expression here:\\n\")\n\texpectParseError(t, \"(x = await)\", \"<stdin>: ERROR: Unexpected \\\")\\\"\\n\")\n\texpectPrinted(t, \"(x = await y)\", \"x = await y;\\n\")\n\texpectParseError(t, \"async (x = await) => {}\", \"<stdin>: ERROR: Unexpected \\\")\\\"\\n\")\n\texpectParseError(t, \"async (x = await y) => {}\", \"<stdin>: ERROR: Cannot use an \\\"await\\\" expression here:\\n\")\n\texpectPrinted(t, \"async(x = await y)\", \"async(x = await y);\\n\")\n\n\t// Keywords with escapes\n\texpectPrinted(t, \"\\\\u0061sync\", \"async;\\n\")\n\texpectPrinted(t, \"(\\\\u0061sync)\", \"async;\\n\")\n\texpectPrinted(t, \"function foo() { \\\\u0061wait }\", \"function foo() {\\n  await;\\n}\\n\")\n\texpectPrinted(t, \"function foo() { var \\\\u0061wait }\", \"function foo() {\\n  var await;\\n}\\n\")\n\texpectParseError(t, \"\\\\u0061wait\", \"<stdin>: ERROR: The keyword \\\"await\\\" cannot be escaped\\n\")\n\texpectParseError(t, \"var \\\\u0061wait\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"async function foo() { \\\\u0061wait }\", \"<stdin>: ERROR: The keyword \\\"await\\\" cannot be escaped\\n\")\n\texpectParseError(t, \"async function foo() { var \\\\u0061wait }\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"\\\\u0061sync x => {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"\\\\u0061sync () => {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"=>\\\"\\n\")\n\texpectParseError(t, \"\\\\u0061sync function foo() {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"function\\\"\\n\")\n\texpectParseError(t, \"({ \\\\u0061sync foo() {} })\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"foo\\\"\\n\")\n\texpectParseError(t, \"({ \\\\u0061sync *foo() {} })\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"*\\\"\\n\")\n\n\t// For-await\n\texpectParseError(t, \"for await(;;);\", \"<stdin>: ERROR: Unexpected \\\";\\\"\\n\")\n\texpectParseError(t, \"for await(x in y);\", \"<stdin>: ERROR: Expected \\\"of\\\" but found \\\"in\\\"\\n\")\n\texpectParseError(t, \"async function foo(){for await(;;);}\", \"<stdin>: ERROR: Unexpected \\\";\\\"\\n\")\n\texpectParseError(t, \"async function foo(){for await(let x;;);}\", \"<stdin>: ERROR: Expected \\\"of\\\" but found \\\";\\\"\\n\")\n\texpectPrinted(t, \"async function foo(){for await(x of y);}\", \"async function foo() {\\n  for await (x of y) ;\\n}\\n\")\n\texpectPrinted(t, \"async function foo(){for await(let x of y);}\", \"async function foo() {\\n  for await (let x of y) ;\\n}\\n\")\n\n\t// Await as an identifier\n\texpectPrinted(t, \"(function await() {})\", \"(function await() {\\n});\\n\")\n\texpectPrinted(t, \"function foo() { ({await} = x) }\", \"function foo() {\\n  ({ await } = x);\\n}\\n\")\n\texpectPrinted(t, \"function foo() { let x = {await} }\", \"function foo() {\\n  let x = { await };\\n}\\n\")\n\texpectParseError(t, \"({await} = x)\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"let x = {await}\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"class await {}\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"(class await {})\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"function await() {}\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"async function foo() { ({await} = x) }\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"async function foo() { let x = {await} }\", \"<stdin>: ERROR: Cannot use \\\"await\\\" as an identifier here:\\n\")\n\n\t// Await as a declaration\n\texpectPrinted(t, \"({ async await() {} })\", \"({ async await() {\\n} });\\n\")\n\texpectPrinted(t, \"(class { async await() {} })\", \"(class {\\n  async await() {\\n  }\\n});\\n\")\n\texpectPrinted(t, \"class Foo { async await() {} }\", \"class Foo {\\n  async await() {\\n  }\\n}\\n\")\n\texpectParseError(t, \"async function await() {}\", \"<stdin>: ERROR: An async function cannot be named \\\"await\\\"\\n\")\n\texpectParseError(t, \"(async function await() {})\", \"<stdin>: ERROR: An async function cannot be named \\\"await\\\"\\n\")\n\n\t// Await as a generator declaration\n\texpectPrinted(t, \"({ async *await() {} })\", \"({ async *await() {\\n} });\\n\")\n\texpectPrinted(t, \"(class { async *await() {} })\", \"(class {\\n  async *await() {\\n  }\\n});\\n\")\n\texpectPrinted(t, \"class Foo { async *await() {} }\", \"class Foo {\\n  async *await() {\\n  }\\n}\\n\")\n\texpectParseError(t, \"async function* await() {}\", \"<stdin>: ERROR: An async function cannot be named \\\"await\\\"\\n\")\n\texpectParseError(t, \"(async function* await() {})\", \"<stdin>: ERROR: An async function cannot be named \\\"await\\\"\\n\")\n}\n\nfunc TestLabels(t *testing.T) {\n\texpectPrinted(t, \"{a:b}\", \"{\\n  a: b;\\n}\\n\")\n\texpectPrinted(t, \"({a:b})\", \"({ a: b });\\n\")\n\n\texpectParseError(t, \"while (1) break x\", \"<stdin>: ERROR: There is no containing label named \\\"x\\\"\\n\")\n\texpectParseError(t, \"while (1) continue x\", \"<stdin>: ERROR: There is no containing label named \\\"x\\\"\\n\")\n\n\texpectPrinted(t, \"x: y: z: 1\", \"x: y: z: 1;\\n\")\n\texpectPrinted(t, \"x: 1; y: 2; x: 3\", \"x: 1;\\ny: 2;\\nx: 3;\\n\")\n\texpectPrinted(t, \"x: (() => { x: 1; })()\", \"x: (() => {\\n  x: 1;\\n})();\\n\")\n\texpectPrinted(t, \"x: ({ f() { x: 1; } }).f()\", \"x: ({ f() {\\n  x: 1;\\n} }).f();\\n\")\n\texpectPrinted(t, \"x: (function() { x: 1; })()\", \"x: (function() {\\n  x: 1;\\n})();\\n\")\n\texpectParseError(t, \"x: y: x: 1\", \"<stdin>: ERROR: Duplicate label \\\"x\\\"\\n<stdin>: NOTE: The original label \\\"x\\\" is here:\\n\")\n\n\texpectPrinted(t, \"x: break x\", \"x: break x;\\n\")\n\texpectPrinted(t, \"x: { break x; foo() }\", \"x: {\\n  break x;\\n  foo();\\n}\\n\")\n\texpectPrinted(t, \"x: { y: { z: { foo(); break x; } } }\", \"x: {\\n  y: {\\n    z: {\\n      foo();\\n      break x;\\n    }\\n  }\\n}\\n\")\n\texpectPrinted(t, \"x: { class X { static { new X } } }\", \"x: {\\n  class X {\\n    static {\\n      new X();\\n    }\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"x: break x\", \"\")\n\texpectPrintedMangle(t, \"x: { break x; foo() }\", \"\")\n\texpectPrintedMangle(t, \"y: while (foo()) x: { break x; foo() }\", \"for (; foo(); ) ;\\n\")\n\texpectPrintedMangle(t, \"y: while (foo()) x: { break y; foo() }\", \"y: for (; foo(); ) break y;\\n\")\n\texpectPrintedMangle(t, \"x: { y: { z: { foo(); break x; } } }\", \"x: {\\n  foo();\\n  break x;\\n}\\n\")\n\texpectPrintedMangle(t, \"x: { class X { static { new X } } }\", \"{\\n  class X {\\n    static {\\n      new X();\\n    }\\n  }\\n}\\n\")\n}\n\nfunc TestArrow(t *testing.T) {\n\texpectParseError(t, \"({a: b, c() {}}) => {}\", \"<stdin>: ERROR: Invalid binding pattern\\n\")\n\texpectParseError(t, \"({a: b, get c() {}}) => {}\", \"<stdin>: ERROR: Invalid binding pattern\\n\")\n\texpectParseError(t, \"({a: b, set c(x) {}}) => {}\", \"<stdin>: ERROR: Invalid binding pattern\\n\")\n\n\texpectParseError(t, \"x = ([ (y) ]) => 0\", \"<stdin>: ERROR: Invalid binding pattern\\n\")\n\texpectParseError(t, \"x = ([ ...(y) ]) => 0\", \"<stdin>: ERROR: Invalid binding pattern\\n\")\n\texpectParseError(t, \"x = ({ (y) }) => 0\", \"<stdin>: ERROR: Expected identifier but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"x = ({ y: (z) }) => 0\", \"<stdin>: ERROR: Invalid binding pattern\\n\")\n\texpectParseError(t, \"x = ({ ...(y) }) => 0\", \"<stdin>: ERROR: Invalid binding pattern\\n\")\n\n\texpectPrinted(t, \"x = ([ y = [ (z) ] ]) => 0\", \"x = ([y = [z]]) => 0;\\n\")\n\texpectPrinted(t, \"x = ([ y = [ ...(z) ] ]) => 0\", \"x = ([y = [...z]]) => 0;\\n\")\n\texpectPrinted(t, \"x = ({ y = { y: (z) } }) => 0\", \"x = ({ y = { y: z } }) => 0;\\n\")\n\texpectPrinted(t, \"x = ({ y = { ...(y) } }) => 0\", \"x = ({ y = { ...y } }) => 0;\\n\")\n\n\texpectPrinted(t, \"x => function() {}\", \"(x) => function() {\\n};\\n\")\n\texpectPrinted(t, \"(x) => function() {}\", \"(x) => function() {\\n};\\n\")\n\texpectPrinted(t, \"(x => function() {})\", \"((x) => function() {\\n});\\n\")\n\n\texpectPrinted(t, \"(x = () => {}) => {}\", \"(x = () => {\\n}) => {\\n};\\n\")\n\texpectPrinted(t, \"async (x = () => {}) => {}\", \"async (x = () => {\\n}) => {\\n};\\n\")\n\n\texpectParseError(t, \"()\\n=> {}\", \"<stdin>: ERROR: Unexpected newline before \\\"=>\\\"\\n\")\n\texpectParseError(t, \"x\\n=> {}\", \"<stdin>: ERROR: Unexpected newline before \\\"=>\\\"\\n\")\n\texpectParseError(t, \"async x\\n=> {}\", \"<stdin>: ERROR: Unexpected newline before \\\"=>\\\"\\n\")\n\texpectParseError(t, \"async ()\\n=> {}\", \"<stdin>: ERROR: Unexpected newline before \\\"=>\\\"\\n\")\n\texpectParseError(t, \"(()\\n=> {})\", \"<stdin>: ERROR: Unexpected newline before \\\"=>\\\"\\n\")\n\texpectParseError(t, \"(x\\n=> {})\", \"<stdin>: ERROR: Unexpected newline before \\\"=>\\\"\\n\")\n\texpectParseError(t, \"(async x\\n=> {})\", \"<stdin>: ERROR: Unexpected newline before \\\"=>\\\"\\n\")\n\texpectParseError(t, \"(async ()\\n=> {})\", \"<stdin>: ERROR: Unexpected newline before \\\"=>\\\"\\n\")\n\n\texpectPrinted(t, \"(() => {}) ? a : b\", \"(() => {\\n}) ? a : b;\\n\")\n\texpectPrintedMangle(t, \"(() => {}) ? a : b\", \"a;\\n\")\n\texpectParseError(t, \"() => {} ? a : b\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"?\\\"\\n\")\n\texpectPrinted(t, \"1 < (() => {})\", \"1 < (() => {\\n});\\n\")\n\texpectParseError(t, \"1 < () => {}\", \"<stdin>: ERROR: Unexpected \\\")\\\"\\n\")\n\texpectParseError(t, \"(...x = y) => {}\", \"<stdin>: ERROR: A rest argument cannot have a default initializer\\n\")\n\texpectParseError(t, \"([...x = y]) => {}\", \"<stdin>: ERROR: A rest argument cannot have a default initializer\\n\")\n\n\t// Can assign an arrow function\n\texpectPrinted(t, \"y = x => {}\", \"y = (x) => {\\n};\\n\")\n\texpectPrinted(t, \"y = () => {}\", \"y = () => {\\n};\\n\")\n\texpectPrinted(t, \"y = (x) => {}\", \"y = (x) => {\\n};\\n\")\n\texpectPrinted(t, \"y = async x => {}\", \"y = async (x) => {\\n};\\n\")\n\texpectPrinted(t, \"y = async () => {}\", \"y = async () => {\\n};\\n\")\n\texpectPrinted(t, \"y = async (x) => {}\", \"y = async (x) => {\\n};\\n\")\n\n\t// Cannot add an arrow function\n\texpectPrinted(t, \"1 + function () {}\", \"1 + function() {\\n};\\n\")\n\texpectPrinted(t, \"1 + async function () {}\", \"1 + async function() {\\n};\\n\")\n\texpectParseError(t, \"1 + x => {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"=>\\\"\\n\")\n\texpectParseError(t, \"1 + () => {}\", \"<stdin>: ERROR: Unexpected \\\")\\\"\\n\")\n\texpectParseError(t, \"1 + (x) => {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"=>\\\"\\n\")\n\texpectParseError(t, \"1 + async x => {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"1 + async () => {}\", \"<stdin>: ERROR: Unexpected \\\"=>\\\"\\n\")\n\texpectParseError(t, \"1 + async (x) => {}\", \"<stdin>: ERROR: Unexpected \\\"=>\\\"\\n\")\n\n\t// Cannot extend an arrow function\n\texpectPrinted(t, \"class Foo extends function () {} {}\", \"class Foo extends function() {\\n} {\\n}\\n\")\n\texpectPrinted(t, \"class Foo extends async function () {} {}\", \"class Foo extends async function() {\\n} {\\n}\\n\")\n\texpectParseError(t, \"class Foo extends x => {} {}\", \"<stdin>: ERROR: Expected \\\"{\\\" but found \\\"=>\\\"\\n\")\n\texpectParseError(t, \"class Foo extends () => {} {}\", \"<stdin>: ERROR: Unexpected \\\")\\\"\\n\")\n\texpectParseError(t, \"class Foo extends (x) => {} {}\", \"<stdin>: ERROR: Expected \\\"{\\\" but found \\\"=>\\\"\\n\")\n\texpectParseError(t, \"class Foo extends async x => {} {}\", \"<stdin>: ERROR: Expected \\\"{\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"class Foo extends async () => {} {}\", \"<stdin>: ERROR: Unexpected \\\"=>\\\"\\n\")\n\texpectParseError(t, \"class Foo extends async (x) => {} {}\", \"<stdin>: ERROR: Unexpected \\\"=>\\\"\\n\")\n\texpectParseError(t, \"(class extends x => {} {})\", \"<stdin>: ERROR: Expected \\\"{\\\" but found \\\"=>\\\"\\n\")\n\texpectParseError(t, \"(class extends () => {} {})\", \"<stdin>: ERROR: Unexpected \\\")\\\"\\n\")\n\texpectParseError(t, \"(class extends (x) => {} {})\", \"<stdin>: ERROR: Expected \\\"{\\\" but found \\\"=>\\\"\\n\")\n\texpectParseError(t, \"(class extends async x => {} {})\", \"<stdin>: ERROR: Expected \\\"{\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"(class extends async () => {} {})\", \"<stdin>: ERROR: Unexpected \\\"=>\\\"\\n\")\n\texpectParseError(t, \"(class extends async (x) => {} {})\", \"<stdin>: ERROR: Unexpected \\\"=>\\\"\\n\")\n\n\texpectParseError(t, \"() => {}(0)\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"x => {}(0)\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"async () => {}(0)\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"async x => {}(0)\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"async (x) => {}(0)\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"0, async () => {}(0)\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"0, async x => {}(0)\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"0, async (x) => {}(0)\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\n\texpectPrinted(t, \"() => {}\\n(0)\", \"() => {\\n};\\n0;\\n\")\n\texpectPrinted(t, \"x => {}\\n(0)\", \"(x) => {\\n};\\n0;\\n\")\n\texpectPrinted(t, \"async () => {}\\n(0)\", \"async () => {\\n};\\n0;\\n\")\n\texpectPrinted(t, \"async x => {}\\n(0)\", \"async (x) => {\\n};\\n0;\\n\")\n\texpectPrinted(t, \"async (x) => {}\\n(0)\", \"async (x) => {\\n};\\n0;\\n\")\n\n\texpectPrinted(t, \"() => {}\\n,0\", \"() => {\\n}, 0;\\n\")\n\texpectPrinted(t, \"x => {}\\n,0\", \"(x) => {\\n}, 0;\\n\")\n\texpectPrinted(t, \"async () => {}\\n,0\", \"async () => {\\n}, 0;\\n\")\n\texpectPrinted(t, \"async x => {}\\n,0\", \"async (x) => {\\n}, 0;\\n\")\n\texpectPrinted(t, \"async (x) => {}\\n,0\", \"async (x) => {\\n}, 0;\\n\")\n\n\texpectPrinted(t, \"(() => {})\\n(0)\", \"/* @__PURE__ */ (() => {\\n})(0);\\n\")\n\texpectPrinted(t, \"(x => {})\\n(0)\", \"/* @__PURE__ */ ((x) => {\\n})(0);\\n\")\n\texpectPrinted(t, \"(async () => {})\\n(0)\", \"(async () => {\\n})(0);\\n\")\n\texpectPrinted(t, \"(async x => {})\\n(0)\", \"(async (x) => {\\n})(0);\\n\")\n\texpectPrinted(t, \"(async (x) => {})\\n(0)\", \"(async (x) => {\\n})(0);\\n\")\n\n\texpectParseError(t, \"y = () => {}(0)\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"y = x => {}(0)\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"y = async () => {}(0)\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"y = async x => {}(0)\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"y = async (x) => {}(0)\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\n\texpectPrinted(t, \"y = () => {}\\n(0)\", \"y = () => {\\n};\\n0;\\n\")\n\texpectPrinted(t, \"y = x => {}\\n(0)\", \"y = (x) => {\\n};\\n0;\\n\")\n\texpectPrinted(t, \"y = async () => {}\\n(0)\", \"y = async () => {\\n};\\n0;\\n\")\n\texpectPrinted(t, \"y = async x => {}\\n(0)\", \"y = async (x) => {\\n};\\n0;\\n\")\n\texpectPrinted(t, \"y = async (x) => {}\\n(0)\", \"y = async (x) => {\\n};\\n0;\\n\")\n\n\texpectPrinted(t, \"y = () => {}\\n,0\", \"y = () => {\\n}, 0;\\n\")\n\texpectPrinted(t, \"y = x => {}\\n,0\", \"y = (x) => {\\n}, 0;\\n\")\n\texpectPrinted(t, \"y = async () => {}\\n,0\", \"y = async () => {\\n}, 0;\\n\")\n\texpectPrinted(t, \"y = async x => {}\\n,0\", \"y = async (x) => {\\n}, 0;\\n\")\n\texpectPrinted(t, \"y = async (x) => {}\\n,0\", \"y = async (x) => {\\n}, 0;\\n\")\n\n\texpectPrinted(t, \"y = (() => {})\\n(0)\", \"y = /* @__PURE__ */ (() => {\\n})(0);\\n\")\n\texpectPrinted(t, \"y = (x => {})\\n(0)\", \"y = /* @__PURE__ */ ((x) => {\\n})(0);\\n\")\n\texpectPrinted(t, \"y = (async () => {})\\n(0)\", \"y = (async () => {\\n})(0);\\n\")\n\texpectPrinted(t, \"y = (async x => {})\\n(0)\", \"y = (async (x) => {\\n})(0);\\n\")\n\texpectPrinted(t, \"y = (async (x) => {})\\n(0)\", \"y = (async (x) => {\\n})(0);\\n\")\n\n\texpectParseError(t, \"(() => {}(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"(x => {}(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"(async () => {}(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"(async x => {}(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"(async (x) => {}(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\n\texpectParseError(t, \"(() => {}\\n(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"(x => {}\\n(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"(async () => {}\\n(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"(async x => {}\\n(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"(async (x) => {}\\n(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\n\texpectPrinted(t, \"(() => {}\\n,0)\", \"() => {\\n}, 0;\\n\")\n\texpectPrinted(t, \"(x => {}\\n,0)\", \"(x) => {\\n}, 0;\\n\")\n\texpectPrinted(t, \"(async () => {}\\n,0)\", \"async () => {\\n}, 0;\\n\")\n\texpectPrinted(t, \"(async x => {}\\n,0)\", \"async (x) => {\\n}, 0;\\n\")\n\texpectPrinted(t, \"(async (x) => {}\\n,0)\", \"async (x) => {\\n}, 0;\\n\")\n\n\texpectPrinted(t, \"((() => {})\\n(0))\", \"/* @__PURE__ */ (() => {\\n})(0);\\n\")\n\texpectPrinted(t, \"((x => {})\\n(0))\", \"/* @__PURE__ */ ((x) => {\\n})(0);\\n\")\n\texpectPrinted(t, \"((async () => {})\\n(0))\", \"(async () => {\\n})(0);\\n\")\n\texpectPrinted(t, \"((async x => {})\\n(0))\", \"(async (x) => {\\n})(0);\\n\")\n\texpectPrinted(t, \"((async (x) => {})\\n(0))\", \"(async (x) => {\\n})(0);\\n\")\n\n\texpectParseError(t, \"y = (() => {}(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"y = (x => {}(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"y = (async () => {}(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"y = (async x => {}(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"y = (async (x) => {}(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\n\texpectParseError(t, \"y = (() => {}\\n(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"y = (x => {}\\n(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"y = (async () => {}\\n(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"y = (async x => {}\\n(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"y = (async (x) => {}\\n(0))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n\n\texpectPrinted(t, \"y = (() => {}\\n,0)\", \"y = (() => {\\n}, 0);\\n\")\n\texpectPrinted(t, \"y = (x => {}\\n,0)\", \"y = ((x) => {\\n}, 0);\\n\")\n\texpectPrinted(t, \"y = (async () => {}\\n,0)\", \"y = (async () => {\\n}, 0);\\n\")\n\texpectPrinted(t, \"y = (async x => {}\\n,0)\", \"y = (async (x) => {\\n}, 0);\\n\")\n\texpectPrinted(t, \"y = (async (x) => {}\\n,0)\", \"y = (async (x) => {\\n}, 0);\\n\")\n\n\texpectPrinted(t, \"y = ((() => {})\\n(0))\", \"y = /* @__PURE__ */ (() => {\\n})(0);\\n\")\n\texpectPrinted(t, \"y = ((x => {})\\n(0))\", \"y = /* @__PURE__ */ ((x) => {\\n})(0);\\n\")\n\texpectPrinted(t, \"y = ((async () => {})\\n(0))\", \"y = (async () => {\\n})(0);\\n\")\n\texpectPrinted(t, \"y = ((async x => {})\\n(0))\", \"y = (async (x) => {\\n})(0);\\n\")\n\texpectPrinted(t, \"y = ((async (x) => {})\\n(0))\", \"y = (async (x) => {\\n})(0);\\n\")\n}\n\nfunc TestTemplate(t *testing.T) {\n\texpectPrinted(t, \"`\\\\0`\", \"`\\\\0`;\\n\")\n\texpectPrinted(t, \"`${'\\\\00'}`\", \"`${\\\"\\\\0\\\"}`;\\n\")\n\n\texpectParseError(t, \"`\\\\7`\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in template literals\\n\")\n\texpectParseError(t, \"`\\\\8`\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in template literals\\n\")\n\texpectParseError(t, \"`\\\\9`\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in template literals\\n\")\n\texpectParseError(t, \"`\\\\00`\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in template literals\\n\")\n\texpectParseError(t, \"`\\\\00${x}`\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in template literals\\n\")\n\texpectParseError(t, \"`${x}\\\\00`\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in template literals\\n\")\n\texpectParseError(t, \"`${x}\\\\00${y}`\", \"<stdin>: ERROR: Legacy octal escape sequences cannot be used in template literals\\n\")\n\texpectParseError(t, \"`\\\\unicode`\", \"<stdin>: ERROR: Syntax error \\\"n\\\"\\n\")\n\texpectParseError(t, \"`\\\\unicode${x}`\", \"<stdin>: ERROR: Syntax error \\\"n\\\"\\n\")\n\texpectParseError(t, \"`${x}\\\\unicode`\", \"<stdin>: ERROR: Syntax error \\\"n\\\"\\n\")\n\texpectParseError(t, \"`\\\\u{10FFFFF}`\", \"<stdin>: ERROR: Unicode escape sequence is out of range\\n\")\n\n\texpectPrinted(t, \"tag`\\\\7`\", \"tag`\\\\7`;\\n\")\n\texpectPrinted(t, \"tag`\\\\8`\", \"tag`\\\\8`;\\n\")\n\texpectPrinted(t, \"tag`\\\\9`\", \"tag`\\\\9`;\\n\")\n\texpectPrinted(t, \"tag`\\\\00`\", \"tag`\\\\00`;\\n\")\n\texpectPrinted(t, \"tag`\\\\00${x}`\", \"tag`\\\\00${x}`;\\n\")\n\texpectPrinted(t, \"tag`${x}\\\\00`\", \"tag`${x}\\\\00`;\\n\")\n\texpectPrinted(t, \"tag`${x}\\\\00${y}`\", \"tag`${x}\\\\00${y}`;\\n\")\n\texpectPrinted(t, \"tag`\\\\unicode`\", \"tag`\\\\unicode`;\\n\")\n\texpectPrinted(t, \"tag`\\\\unicode${x}`\", \"tag`\\\\unicode${x}`;\\n\")\n\texpectPrinted(t, \"tag`${x}\\\\unicode`\", \"tag`${x}\\\\unicode`;\\n\")\n\texpectPrinted(t, \"tag`\\\\u{10FFFFF}`\", \"tag`\\\\u{10FFFFF}`;\\n\")\n\n\texpectPrinted(t, \"tag``\", \"tag``;\\n\")\n\texpectPrinted(t, \"(a?.b)``\", \"(a?.b)``;\\n\")\n\texpectPrinted(t, \"(a?.(b))``\", \"(a?.(b))``;\\n\")\n\texpectPrinted(t, \"(a?.[b])``\", \"(a?.[b])``;\\n\")\n\texpectPrinted(t, \"(a?.b.c)``\", \"(a?.b.c)``;\\n\")\n\texpectPrinted(t, \"(a?.(b).c)``\", \"(a?.(b).c)``;\\n\")\n\texpectPrinted(t, \"(a?.[b].c)``\", \"(a?.[b].c)``;\\n\")\n\n\texpectParseError(t, \"a?.b``\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.(b)``\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.[b]``\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.b.c``\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.(b).c``\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.[b].c``\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\n\texpectParseError(t, \"a?.b`${d}`\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.(b)`${d}`\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.[b]`${d}`\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.b.c`${d}`\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.(b).c`${d}`\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.[b].c`${d}`\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\n\texpectParseError(t, \"a?.b\\n``\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.(b)\\n``\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.[b]\\n``\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.b.c\\n``\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.(b).c\\n``\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.[b].c\\n``\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\n\texpectParseError(t, \"a?.b\\n`${d}`\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.(b)\\n`${d}`\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.[b]\\n`${d}`\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.b.c\\n`${d}`\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.(b).c\\n`${d}`\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\texpectParseError(t, \"a?.[b].c\\n`${d}`\", \"<stdin>: ERROR: Template literals cannot have an optional chain as a tag\\n\")\n\n\texpectPrinted(t, \"`a${1 + `b${2}c` + 3}d`\", \"`a${`1b${2}c3`}d`;\\n\")\n\texpectPrintedMangle(t, \"x = `a${1 + `b${2}c` + 3}d`\", \"x = `a1b2c3d`;\\n\")\n\n\texpectPrinted(t, \"`a\\nb`\", \"`a\\nb`;\\n\")\n\texpectPrinted(t, \"`a\\rb`\", \"`a\\nb`;\\n\")\n\texpectPrinted(t, \"`a\\r\\nb`\", \"`a\\nb`;\\n\")\n\texpectPrinted(t, \"`a\\\\nb`\", \"`a\\nb`;\\n\")\n\texpectPrinted(t, \"`a\\\\rb`\", \"`a\\\\rb`;\\n\")\n\texpectPrinted(t, \"`a\\\\r\\\\nb`\", \"`a\\\\r\\nb`;\\n\")\n\texpectPrinted(t, \"`a\\u2028b`\", \"`a\\\\u2028b`;\\n\")\n\texpectPrinted(t, \"`a\\u2029b`\", \"`a\\\\u2029b`;\\n\")\n\n\texpectPrinted(t, \"`a\\n${b}`\", \"`a\\n${b}`;\\n\")\n\texpectPrinted(t, \"`a\\r${b}`\", \"`a\\n${b}`;\\n\")\n\texpectPrinted(t, \"`a\\r\\n${b}`\", \"`a\\n${b}`;\\n\")\n\texpectPrinted(t, \"`a\\\\n${b}`\", \"`a\\n${b}`;\\n\")\n\texpectPrinted(t, \"`a\\\\r${b}`\", \"`a\\\\r${b}`;\\n\")\n\texpectPrinted(t, \"`a\\\\r\\\\n${b}`\", \"`a\\\\r\\n${b}`;\\n\")\n\texpectPrinted(t, \"`a\\u2028${b}`\", \"`a\\\\u2028${b}`;\\n\")\n\texpectPrinted(t, \"`a\\u2029${b}`\", \"`a\\\\u2029${b}`;\\n\")\n\n\texpectPrinted(t, \"`${a}\\nb`\", \"`${a}\\nb`;\\n\")\n\texpectPrinted(t, \"`${a}\\rb`\", \"`${a}\\nb`;\\n\")\n\texpectPrinted(t, \"`${a}\\r\\nb`\", \"`${a}\\nb`;\\n\")\n\texpectPrinted(t, \"`${a}\\\\nb`\", \"`${a}\\nb`;\\n\")\n\texpectPrinted(t, \"`${a}\\\\rb`\", \"`${a}\\\\rb`;\\n\")\n\texpectPrinted(t, \"`${a}\\\\r\\\\nb`\", \"`${a}\\\\r\\nb`;\\n\")\n\texpectPrinted(t, \"`${a}\\u2028b`\", \"`${a}\\\\u2028b`;\\n\")\n\texpectPrinted(t, \"`${a}\\u2029b`\", \"`${a}\\\\u2029b`;\\n\")\n\n\texpectPrinted(t, \"tag`a\\nb`\", \"tag`a\\nb`;\\n\")\n\texpectPrinted(t, \"tag`a\\rb`\", \"tag`a\\nb`;\\n\")\n\texpectPrinted(t, \"tag`a\\r\\nb`\", \"tag`a\\nb`;\\n\")\n\texpectPrinted(t, \"tag`a\\\\nb`\", \"tag`a\\\\nb`;\\n\")\n\texpectPrinted(t, \"tag`a\\\\rb`\", \"tag`a\\\\rb`;\\n\")\n\texpectPrinted(t, \"tag`a\\\\r\\\\nb`\", \"tag`a\\\\r\\\\nb`;\\n\")\n\texpectPrinted(t, \"tag`a\\u2028b`\", \"tag`a\\u2028b`;\\n\")\n\texpectPrinted(t, \"tag`a\\u2029b`\", \"tag`a\\u2029b`;\\n\")\n\n\texpectPrinted(t, \"tag`a\\n${b}`\", \"tag`a\\n${b}`;\\n\")\n\texpectPrinted(t, \"tag`a\\r${b}`\", \"tag`a\\n${b}`;\\n\")\n\texpectPrinted(t, \"tag`a\\r\\n${b}`\", \"tag`a\\n${b}`;\\n\")\n\texpectPrinted(t, \"tag`a\\\\n${b}`\", \"tag`a\\\\n${b}`;\\n\")\n\texpectPrinted(t, \"tag`a\\\\r${b}`\", \"tag`a\\\\r${b}`;\\n\")\n\texpectPrinted(t, \"tag`a\\\\r\\\\n${b}`\", \"tag`a\\\\r\\\\n${b}`;\\n\")\n\texpectPrinted(t, \"tag`a\\u2028${b}`\", \"tag`a\\u2028${b}`;\\n\")\n\texpectPrinted(t, \"tag`a\\u2029${b}`\", \"tag`a\\u2029${b}`;\\n\")\n\n\texpectPrinted(t, \"tag`${a}\\nb`\", \"tag`${a}\\nb`;\\n\")\n\texpectPrinted(t, \"tag`${a}\\rb`\", \"tag`${a}\\nb`;\\n\")\n\texpectPrinted(t, \"tag`${a}\\r\\nb`\", \"tag`${a}\\nb`;\\n\")\n\texpectPrinted(t, \"tag`${a}\\\\nb`\", \"tag`${a}\\\\nb`;\\n\")\n\texpectPrinted(t, \"tag`${a}\\\\rb`\", \"tag`${a}\\\\rb`;\\n\")\n\texpectPrinted(t, \"tag`${a}\\\\r\\\\nb`\", \"tag`${a}\\\\r\\\\nb`;\\n\")\n\texpectPrinted(t, \"tag`${a}\\u2028b`\", \"tag`${a}\\u2028b`;\\n\")\n\texpectPrinted(t, \"tag`${a}\\u2029b`\", \"tag`${a}\\u2029b`;\\n\")\n}\n\nfunc TestSwitch(t *testing.T) {\n\texpectPrinted(t, \"switch (x) { default: }\", \"switch (x) {\\n  default:\\n}\\n\")\n\texpectPrinted(t, \"switch ((x => x + 1)(0)) { case 1: var y } y = 2\", \"switch (((x) => x + 1)(0)) {\\n  case 1:\\n    var y;\\n}\\ny = 2;\\n\")\n\texpectParseError(t, \"switch (x) { default: default: }\", \"<stdin>: ERROR: Multiple default clauses are not allowed\\n\")\n\n\texpectPrintedMangle(t, \"switch (x) {}\", \"x;\\n\")\n\texpectPrintedMangle(t, \"switch (x) { case x: a(); break; case y: b(); break }\", \"switch (x) {\\n  case x:\\n    a();\\n    break;\\n  case y:\\n    b();\\n    break;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"switch (0) { default: a() }\", \"a();\\n\")\n\texpectPrintedMangle(t, \"switch (x) { default: a() }\", \"switch (x) {\\n  default:\\n    a();\\n}\\n\")\n\n\texpectPrintedMangle(t, \"switch (0) { case 0: a(); break; case 1: b(); break }\", \"a();\\n\")\n\texpectPrintedMangle(t, \"switch (1) { case 0: a(); break; case 1: b(); break }\", \"b();\\n\")\n\texpectPrintedMangle(t, \"switch (2) { case 0: a(); break; case 1: b(); break }\", \"\")\n\n\texpectPrintedMangle(t, \"switch (0) { case 0: a(); case 1: b(); break }\", \"a(), b();\\n\")\n\texpectPrintedMangle(t, \"switch (1) { case 0: a(); case 1: b(); break }\", \"b();\\n\")\n\texpectPrintedMangle(t, \"switch (2) { case 0: a(); case 1: b(); break }\", \"\")\n\n\texpectPrintedMangle(t, \"switch (0) { case 0: a(); break; default: b(); break }\", \"a();\\n\")\n\texpectPrintedMangle(t, \"switch (1) { case 0: a(); break; default: b(); break }\", \"b();\\n\")\n\n\texpectPrintedMangle(t, \"switch (0) { case 0: { a(); break; } case 1: b(); break }\", \"a();\\n\")\n\texpectPrintedMangle(t, \"switch (0) { case 0: { var x = a(); break; } case 1: b(); break }\", \"var x = a();\\n\")\n\texpectPrintedMangle(t, \"switch (0) { case 0: { let x = a(); break; } case 1: b(); break }\", \"{\\n  let x = a();\\n}\\n\")\n\texpectPrintedMangle(t, \"switch (0) { case 0: { const x = a(); break; } case 1: b(); break }\", \"{\\n  const x = a();\\n}\\n\")\n\n\texpectPrintedMangle(t, \"for (x of y) switch (0) { case 0: a(); continue; default: b(); continue }\", \"for (x of y) a();\\n\")\n\texpectPrintedMangle(t, \"for (x of y) switch (1) { case 0: a(); continue; default: b(); continue }\", \"for (x of y) b();\\n\")\n\n\texpectPrintedMangle(t, \"for (x of y) switch (0) { case 0: throw a(); default: throw b() }\", \"for (x of y) throw a();\\n\")\n\texpectPrintedMangle(t, \"for (x of y) switch (1) { case 0: throw a(); default: throw b() }\", \"for (x of y) throw b();\\n\")\n\n\texpectPrintedMangle(t, \"for (x of y) switch (0) { case 0: return a(); default: return b() }\", \"for (x of y) return a();\\n\")\n\texpectPrintedMangle(t, \"for (x of y) switch (1) { case 0: return a(); default: return b() }\", \"for (x of y) return b();\\n\")\n\n\texpectPrintedMangle(t, \"z: for (x of y) switch (0) { case 0: a(); break z; default: b(); break z }\", \"z: for (x of y) switch (0) {\\n  case 0:\\n    a();\\n    break z;\\n}\\n\")\n\texpectPrintedMangle(t, \"z: for (x of y) switch (1) { case 0: a(); break z; default: b(); break z }\", \"z: for (x of y) switch (1) {\\n  default:\\n    b();\\n    break z;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"for (x of y) z: switch (0) { case 0: a(); break z; default: b(); break z }\", \"for (x of y) z: switch (0) {\\n  case 0:\\n    a();\\n    break z;\\n}\\n\")\n\texpectPrintedMangle(t, \"for (x of y) z: switch (1) { case 0: a(); break z; default: b(); break z }\", \"for (x of y) z: switch (1) {\\n  default:\\n    b();\\n    break z;\\n}\\n\")\n\n\t// Some people put functions inside case expressions, so make sure that works\n\t// For more info, see: https://github.com/evanw/esbuild/issues/4088\n\texpectPrinted(t, \"switch (0) { case x(() => 1): y = () => 2; case x(() => 3): y = () => 4 }\",\n\t\t\"switch (0) {\\n  case x(() => 1):\\n    y = () => 2;\\n  case x(() => 3):\\n    y = () => 4;\\n}\\n\")\n\n\t// The specification was changed after implementations shipped the feature.\n\t// Specifically \"using\" inside \"case\" and \"default\" inside \"switch\" is no\n\t// longer allowed: https://github.com/rbuckton/ecma262/pull/14\n\tusingError := \"<stdin>: ERROR: Cannot use a \\\"using\\\" declaration directly inside a switch case\\n\" +\n\t\t\"NOTE: Wrap this declaration in a block statement to use it here.\\n\"\n\texpectParseError(t, \"switch (x) { case 0: using y = z }\\n\", usingError)\n\texpectParseError(t, \"switch (x) { case 0: await using y = z }\\n\", usingError)\n\texpectPrinted(t, \"switch (x) { case 0: { using y = z } }\\n\", \"switch (x) {\\n  case 0: {\\n    using y = z;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"switch (x) { case 0: { await using y = z } }\\n\", \"switch (x) {\\n  case 0: {\\n    await using y = z;\\n  }\\n}\\n\")\n}\n\nfunc TestConstantFolding(t *testing.T) {\n\texpectPrinted(t, \"x = !false\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = !true\", \"x = false;\\n\")\n\n\texpectPrinted(t, \"x = !!0\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = !!-0\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = !!1\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = !!NaN\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = !!Infinity\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = !!-Infinity\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = !!\\\"\\\"\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = !!\\\"x\\\"\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = !!function() {}\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = !!(() => {})\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = !!0n\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = !!1n\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = !!0b0n\", \"x = !!0b0n;\\n\")\n\texpectPrinted(t, \"x = !!0b1n\", \"x = !!0b1n;\\n\")\n\texpectPrinted(t, \"x = !!0o0n\", \"x = !!0o0n;\\n\")\n\texpectPrinted(t, \"x = !!0o1n\", \"x = !!0o1n;\\n\")\n\texpectPrinted(t, \"x = !!0x0n\", \"x = !!0x0n;\\n\")\n\texpectPrinted(t, \"x = !!0x1n\", \"x = !!0x1n;\\n\")\n\n\texpectPrinted(t, \"x = 1 ? a : b\", \"x = 1 ? a : b;\\n\")\n\texpectPrinted(t, \"x = 0 ? a : b\", \"x = 0 ? a : b;\\n\")\n\texpectPrintedMangle(t, \"x = 1 ? a : b\", \"x = a;\\n\")\n\texpectPrintedMangle(t, \"x = 0 ? a : b\", \"x = b;\\n\")\n\n\texpectPrinted(t, \"x = 1 && 2\", \"x = 2;\\n\")\n\texpectPrinted(t, \"x = 1 || 2\", \"x = 1;\\n\")\n\texpectPrinted(t, \"x = 0 && 1\", \"x = 0;\\n\")\n\texpectPrinted(t, \"x = 0 || 1\", \"x = 1;\\n\")\n\n\texpectPrinted(t, \"x = null ?? 1\", \"x = 1;\\n\")\n\texpectPrinted(t, \"x = undefined ?? 1\", \"x = 1;\\n\")\n\texpectPrinted(t, \"x = 0 ?? 1\", \"x = 0;\\n\")\n\texpectPrinted(t, \"x = false ?? 1\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = \\\"\\\" ?? 1\", \"x = \\\"\\\";\\n\")\n\n\texpectPrinted(t, \"x = typeof undefined\", \"x = \\\"undefined\\\";\\n\")\n\texpectPrinted(t, \"x = typeof null\", \"x = \\\"object\\\";\\n\")\n\texpectPrinted(t, \"x = typeof false\", \"x = \\\"boolean\\\";\\n\")\n\texpectPrinted(t, \"x = typeof true\", \"x = \\\"boolean\\\";\\n\")\n\texpectPrinted(t, \"x = typeof 123\", \"x = \\\"number\\\";\\n\")\n\texpectPrinted(t, \"x = typeof 123n\", \"x = \\\"bigint\\\";\\n\")\n\texpectPrinted(t, \"x = typeof 'abc'\", \"x = \\\"string\\\";\\n\")\n\texpectPrinted(t, \"x = typeof function() {}\", \"x = \\\"function\\\";\\n\")\n\texpectPrinted(t, \"x = typeof (() => {})\", \"x = \\\"function\\\";\\n\")\n\texpectPrinted(t, \"x = typeof {}\", \"x = typeof {};\\n\")\n\texpectPrinted(t, \"x = typeof []\", \"x = typeof [];\\n\")\n\n\texpectPrinted(t, \"x = undefined === undefined\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = undefined !== undefined\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = undefined == undefined\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = undefined != undefined\", \"x = false;\\n\")\n\n\texpectPrinted(t, \"x = null === null\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = null !== null\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = null == null\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = null != null\", \"x = false;\\n\")\n\n\texpectPrinted(t, \"x = null === undefined\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = null !== undefined\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = null == undefined\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = null != undefined\", \"x = false;\\n\")\n\n\texpectPrinted(t, \"x = undefined === null\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = undefined !== null\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = undefined == null\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = undefined != null\", \"x = false;\\n\")\n\n\texpectPrinted(t, \"x = true === true\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = true === false\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = true !== true\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = true !== false\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = true == true\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = true == false\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = true != true\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = true != false\", \"x = true;\\n\")\n\n\texpectPrinted(t, \"x = 1 === 1\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 1 === 2\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 1 === '1'\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 1 == 1\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 1 == 2\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 1 == '1'\", \"x = 1 == \\\"1\\\";\\n\")\n\n\texpectPrinted(t, \"x = 1 !== 1\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 1 !== 2\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 1 !== '1'\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 1 != 1\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 1 != 2\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 1 != '1'\", \"x = 1 != \\\"1\\\";\\n\")\n\n\texpectPrinted(t, \"x = 'a' === '\\\\x61'\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 'a' === '\\\\x62'\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 'a' === 'abc'\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 'a' !== '\\\\x61'\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 'a' !== '\\\\x62'\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 'a' !== 'abc'\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 'a' == '\\\\x61'\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 'a' == '\\\\x62'\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 'a' == 'abc'\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 'a' != '\\\\x61'\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 'a' != '\\\\x62'\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 'a' != 'abc'\", \"x = true;\\n\")\n\n\texpectPrinted(t, \"x = 'a' + 'b'\", \"x = \\\"ab\\\";\\n\")\n\texpectPrinted(t, \"x = 'a' + 'bc'\", \"x = \\\"abc\\\";\\n\")\n\texpectPrinted(t, \"x = 'ab' + 'c'\", \"x = \\\"abc\\\";\\n\")\n\texpectPrinted(t, \"x = x + 'a' + 'b'\", \"x = x + \\\"ab\\\";\\n\")\n\texpectPrinted(t, \"x = x + 'a' + 'bc'\", \"x = x + \\\"abc\\\";\\n\")\n\texpectPrinted(t, \"x = x + 'ab' + 'c'\", \"x = x + \\\"abc\\\";\\n\")\n\texpectPrinted(t, \"x = 'a' + 1\", \"x = \\\"a1\\\";\\n\")\n\texpectPrinted(t, \"x = x * 'a' + 'b'\", \"x = x * \\\"a\\\" + \\\"b\\\";\\n\")\n\n\texpectPrinted(t, \"x = 'string' + `template`\", \"x = `stringtemplate`;\\n\")\n\texpectPrinted(t, \"x = 'string' + `a${foo}b`\", \"x = `stringa${foo}b`;\\n\")\n\texpectPrinted(t, \"x = 'string' + tag`template`\", \"x = \\\"string\\\" + tag`template`;\\n\")\n\texpectPrinted(t, \"x = `template` + 'string'\", \"x = `templatestring`;\\n\")\n\texpectPrinted(t, \"x = `a${foo}b` + 'string'\", \"x = `a${foo}bstring`;\\n\")\n\texpectPrinted(t, \"x = tag`template` + 'string'\", \"x = tag`template` + \\\"string\\\";\\n\")\n\texpectPrinted(t, \"x = `template` + `a${foo}b`\", \"x = `templatea${foo}b`;\\n\")\n\texpectPrinted(t, \"x = `a${foo}b` + `template`\", \"x = `a${foo}btemplate`;\\n\")\n\texpectPrinted(t, \"x = `a${foo}b` + `x${bar}y`\", \"x = `a${foo}bx${bar}y`;\\n\")\n\texpectPrinted(t, \"x = `a${i}${j}bb` + `xxx${bar}yyyy`\", \"x = `a${i}${j}bbxxx${bar}yyyy`;\\n\")\n\texpectPrinted(t, \"x = `a${foo}bb` + `xxx${i}${j}yyyy`\", \"x = `a${foo}bbxxx${i}${j}yyyy`;\\n\")\n\texpectPrinted(t, \"x = `template` + tag`template2`\", \"x = `template` + tag`template2`;\\n\")\n\texpectPrinted(t, \"x = tag`template` + `template2`\", \"x = tag`template` + `template2`;\\n\")\n\n\texpectPrinted(t, \"x = 123\", \"x = 123;\\n\")\n\texpectPrinted(t, \"x = 123 .toString()\", \"x = 123 .toString();\\n\")\n\texpectPrinted(t, \"x = -123\", \"x = -123;\\n\")\n\texpectPrinted(t, \"x = (-123).toString()\", \"x = (-123).toString();\\n\")\n\texpectPrinted(t, \"x = -0\", \"x = -0;\\n\")\n\texpectPrinted(t, \"x = (-0).toString()\", \"x = (-0).toString();\\n\")\n\texpectPrinted(t, \"x = -0 === 0\", \"x = true;\\n\")\n\n\texpectPrinted(t, \"x = NaN\", \"x = NaN;\\n\")\n\texpectPrinted(t, \"x = NaN.toString()\", \"x = NaN.toString();\\n\")\n\texpectPrinted(t, \"x = NaN === NaN\", \"x = false;\\n\")\n\n\texpectPrinted(t, \"x = Infinity\", \"x = Infinity;\\n\")\n\texpectPrinted(t, \"x = Infinity.toString()\", \"x = Infinity.toString();\\n\")\n\texpectPrinted(t, \"x = (-Infinity).toString()\", \"x = (-Infinity).toString();\\n\")\n\texpectPrinted(t, \"x = Infinity === Infinity\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = Infinity === -Infinity\", \"x = false;\\n\")\n\n\texpectPrinted(t, \"x = 0n === 0n\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 1n === 1n\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 0n === 1n\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 0n !== 1n\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 0n !== 0n\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 123n === 1_2_3n\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 0n === '1n'\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 0n !== '1n'\", \"x = true;\\n\")\n\n\texpectPrinted(t, \"x = 0n === 0b0n\", \"x = 0n === 0b0n;\\n\")\n\texpectPrinted(t, \"x = 0n === 0o0n\", \"x = 0n === 0o0n;\\n\")\n\texpectPrinted(t, \"x = 0n === 0x0n\", \"x = 0n === 0x0n;\\n\")\n\texpectPrinted(t, \"x = 0b0n === 0b0n\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 0o0n === 0o0n\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 0x0n === 0x0n\", \"x = true;\\n\")\n\n\t// We support folding strings from sibling AST nodes since that ends up being\n\t// equivalent with string addition. For example, \"(x + 'a') + 'b'\" is the\n\t// same as \"x + 'ab'\". However, this is not true for numbers. We can't turn\n\t// \"(x + 1) + '2'\" into \"x + '12'\". These tests check for this edge case.\n\texpectPrinted(t, \"x = 'a' + 'b' + y\", \"x = \\\"ab\\\" + y;\\n\")\n\texpectPrinted(t, \"x = y + 'a' + 'b'\", \"x = y + \\\"ab\\\";\\n\")\n\texpectPrinted(t, \"x = '3' + 4 + y\", \"x = \\\"34\\\" + y;\\n\")\n\texpectPrinted(t, \"x = y + 4 + '5'\", \"x = y + 4 + \\\"5\\\";\\n\")\n\texpectPrinted(t, \"x = '3' + 4 + 5\", \"x = \\\"345\\\";\\n\")\n\texpectPrinted(t, \"x = 3 + 4 + '5'\", \"x = 3 + 4 + \\\"5\\\";\\n\")\n\n\texpectPrinted(t, \"x = null == 0\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 0 == null\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = undefined == 0\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 0 == undefined\", \"x = false;\\n\")\n\n\texpectPrinted(t, \"x = null == NaN\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = NaN == null\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = undefined == NaN\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = NaN == undefined\", \"x = false;\\n\")\n\n\texpectPrinted(t, \"x = null == ''\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = '' == null\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = undefined == ''\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = '' == undefined\", \"x = false;\\n\")\n\n\texpectPrinted(t, \"x = null == 'null'\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 'null' == null\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = undefined == 'undefined'\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 'undefined' == undefined\", \"x = false;\\n\")\n\n\texpectPrinted(t, \"x = false === 0\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = true === 1\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = false == 0\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = false == -0\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = true == 1\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = true == 2\", \"x = false;\\n\")\n\n\texpectPrinted(t, \"x = 0 === false\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 1 === true\", \"x = false;\\n\")\n\texpectPrinted(t, \"x = 0 == false\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = -0 == false\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 1 == true\", \"x = true;\\n\")\n\texpectPrinted(t, \"x = 2 == true\", \"x = false;\\n\")\n}\n\nfunc TestConstantFoldingScopes(t *testing.T) {\n\t// Parsing will crash if somehow the scope traversal is misaligned between\n\t// the parsing and binding passes. This checks for those cases.\n\texpectPrintedMangle(t, \"x; 1 ? 0 : ()=>{}; (()=>{})()\", \"x;\\n\")\n\texpectPrintedMangle(t, \"x; 0 ? ()=>{} : 1; (()=>{})()\", \"x;\\n\")\n\texpectPrinted(t, \"x; 0 && (()=>{}); (()=>{})()\", \"x;\\n/* @__PURE__ */ (() => {\\n})();\\n\")\n\texpectPrinted(t, \"x; 1 || (()=>{}); (()=>{})()\", \"x;\\n/* @__PURE__ */ (() => {\\n})();\\n\")\n\texpectPrintedMangle(t, \"if (1) 0; else ()=>{}; (()=>{})()\", \"\")\n\texpectPrintedMangle(t, \"if (0) ()=>{}; else 1; (()=>{})()\", \"\")\n}\n\nfunc TestImport(t *testing.T) {\n\texpectPrinted(t, \"import \\\"foo\\\"\", \"import \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"import {} from \\\"foo\\\"\", \"import {} from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"import {x} from \\\"foo\\\";x\", \"import { x } from \\\"foo\\\";\\nx;\\n\")\n\texpectPrinted(t, \"import {x as y} from \\\"foo\\\";y\", \"import { x as y } from \\\"foo\\\";\\ny;\\n\")\n\texpectPrinted(t, \"import {x as y, z} from \\\"foo\\\";y;z\", \"import { x as y, z } from \\\"foo\\\";\\ny;\\nz;\\n\")\n\texpectPrinted(t, \"import {x as y, z,} from \\\"foo\\\";y;z\", \"import { x as y, z } from \\\"foo\\\";\\ny;\\nz;\\n\")\n\texpectPrinted(t, \"import z, {x as y} from \\\"foo\\\";y;z\", \"import z, { x as y } from \\\"foo\\\";\\ny;\\nz;\\n\")\n\texpectPrinted(t, \"import z from \\\"foo\\\";z\", \"import z from \\\"foo\\\";\\nz;\\n\")\n\texpectPrinted(t, \"import * as ns from \\\"foo\\\";ns;ns.x\", \"import * as ns from \\\"foo\\\";\\nns;\\nns.x;\\n\")\n\texpectPrinted(t, \"import z, * as ns from \\\"foo\\\";z;ns;ns.x\", \"import z, * as ns from \\\"foo\\\";\\nz;\\nns;\\nns.x;\\n\")\n\n\texpectParseError(t, \"import * from \\\"foo\\\"\", \"<stdin>: ERROR: Expected \\\"as\\\" but found \\\"from\\\"\\n\")\n\n\texpectPrinted(t, \"import('foo')\", \"import(\\\"foo\\\");\\n\")\n\texpectPrinted(t, \"(import('foo'))\", \"import(\\\"foo\\\");\\n\")\n\texpectPrinted(t, \"{import('foo')}\", \"{\\n  import(\\\"foo\\\");\\n}\\n\")\n\texpectPrinted(t, \"import('foo').then(() => {})\", \"import(\\\"foo\\\").then(() => {\\n});\\n\")\n\texpectPrinted(t, \"new import.meta\", \"new import.meta();\\n\")\n\texpectPrinted(t, \"new (import('foo'))\", \"new (import(\\\"foo\\\"))();\\n\")\n\texpectParseError(t, \"import()\", \"<stdin>: ERROR: Unexpected \\\")\\\"\\n\")\n\texpectParseError(t, \"import(...a)\", \"<stdin>: ERROR: Unexpected \\\"...\\\"\\n\")\n\texpectParseError(t, \"new import('foo')\", \"<stdin>: ERROR: Cannot use an \\\"import\\\" expression here without parentheses:\\n\")\n\n\texpectPrinted(t, \"import.meta\", \"import.meta;\\n\")\n\texpectPrinted(t, \"(import.meta)\", \"import.meta;\\n\")\n\texpectPrinted(t, \"{import.meta}\", \"{\\n  import.meta;\\n}\\n\")\n\n\texpectPrinted(t, \"import x from \\\"foo\\\"; x = 1\", \"import x from \\\"foo\\\";\\nx = 1;\\n\")\n\texpectPrinted(t, \"import x from \\\"foo\\\"; x++\", \"import x from \\\"foo\\\";\\nx++;\\n\")\n\texpectPrinted(t, \"import x from \\\"foo\\\"; ([x] = 1)\", \"import x from \\\"foo\\\";\\n[x] = 1;\\n\")\n\texpectPrinted(t, \"import x from \\\"foo\\\"; ({x} = 1)\", \"import x from \\\"foo\\\";\\n({ x } = 1);\\n\")\n\texpectPrinted(t, \"import x from \\\"foo\\\"; ({y: x} = 1)\", \"import x from \\\"foo\\\";\\n({ y: x } = 1);\\n\")\n\texpectPrinted(t, \"import {x} from \\\"foo\\\"; x++\", \"import { x } from \\\"foo\\\";\\nx++;\\n\")\n\texpectPrinted(t, \"import * as x from \\\"foo\\\"; x++\", \"import * as x from \\\"foo\\\";\\nx++;\\n\")\n\texpectPrinted(t, \"import * as x from \\\"foo\\\"; x.y = 1\", \"import * as x from \\\"foo\\\";\\nx.y = 1;\\n\")\n\texpectPrinted(t, \"import * as x from \\\"foo\\\"; x[y] = 1\", \"import * as x from \\\"foo\\\";\\nx[y] = 1;\\n\")\n\texpectPrinted(t, \"import * as x from \\\"foo\\\"; x['y'] = 1\", \"import * as x from \\\"foo\\\";\\nx[\\\"y\\\"] = 1;\\n\")\n\texpectPrinted(t, \"import * as x from \\\"foo\\\"; x['y z'] = 1\", \"import * as x from \\\"foo\\\";\\nx[\\\"y z\\\"] = 1;\\n\")\n\texpectPrinted(t, \"import x from \\\"foo\\\"; ({y = x} = 1)\", \"import x from \\\"foo\\\";\\n({ y = x } = 1);\\n\")\n\texpectPrinted(t, \"import x from \\\"foo\\\"; ({[x]: y} = 1)\", \"import x from \\\"foo\\\";\\n({ [x]: y } = 1);\\n\")\n\texpectPrinted(t, \"import x from \\\"foo\\\"; x.y = 1\", \"import x from \\\"foo\\\";\\nx.y = 1;\\n\")\n\texpectPrinted(t, \"import x from \\\"foo\\\"; x[y] = 1\", \"import x from \\\"foo\\\";\\nx[y] = 1;\\n\")\n\texpectPrinted(t, \"import x from \\\"foo\\\"; x['y'] = 1\", \"import x from \\\"foo\\\";\\nx[\\\"y\\\"] = 1;\\n\")\n\n\t// \"eval\" and \"arguments\" are forbidden import names\n\texpectParseError(t, \"import {eval} from 'foo'\", \"<stdin>: ERROR: Cannot use \\\"eval\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"import {ev\\\\u0061l} from 'foo'\", \"<stdin>: ERROR: Cannot use \\\"eval\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"import {x as eval} from 'foo'\", \"<stdin>: ERROR: Cannot use \\\"eval\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"import {x as ev\\\\u0061l} from 'foo'\", \"<stdin>: ERROR: Cannot use \\\"eval\\\" as an identifier here:\\n\")\n\texpectPrinted(t, \"import {eval as x} from 'foo'\", \"import { eval as x } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"import {ev\\\\u0061l as x} from 'foo'\", \"import { eval as x } from \\\"foo\\\";\\n\")\n\texpectParseError(t, \"import {arguments} from 'foo'\", \"<stdin>: ERROR: Cannot use \\\"arguments\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"import {\\\\u0061rguments} from 'foo'\", \"<stdin>: ERROR: Cannot use \\\"arguments\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"import {x as arguments} from 'foo'\", \"<stdin>: ERROR: Cannot use \\\"arguments\\\" as an identifier here:\\n\")\n\texpectParseError(t, \"import {x as \\\\u0061rguments} from 'foo'\", \"<stdin>: ERROR: Cannot use \\\"arguments\\\" as an identifier here:\\n\")\n\texpectPrinted(t, \"import {arguments as x} from 'foo'\", \"import { arguments as x } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"import {\\\\u0061rguments as x} from 'foo'\", \"import { arguments as x } from \\\"foo\\\";\\n\")\n\n\t// String import alias with \"import {} from\"\n\texpectPrinted(t, \"import {'' as x} from 'foo'\", \"import { \\\"\\\" as x } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"import {'🍕' as x} from 'foo'\", \"import { \\\"🍕\\\" as x } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"import {'a b' as x} from 'foo'\", \"import { \\\"a b\\\" as x } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"import {'\\\\uD800\\\\uDC00' as x} from 'foo'\", \"import { 𐀀 as x } from \\\"foo\\\";\\n\")\n\texpectParseError(t, \"import {'x'} from 'foo'\", \"<stdin>: ERROR: Expected \\\"as\\\" but found \\\"}\\\"\\n\")\n\texpectParseError(t, \"import {'\\\\uD800' as x} from 'foo'\",\n\t\t\"<stdin>: ERROR: This import alias is invalid because it contains the unpaired Unicode surrogate U+D800\\n\")\n\texpectParseError(t, \"import {'\\\\uDC00' as x} from 'foo'\",\n\t\t\"<stdin>: ERROR: This import alias is invalid because it contains the unpaired Unicode surrogate U+DC00\\n\")\n\n\t// String import alias with \"import * as\"\n\texpectParseError(t, \"import * as '' from 'foo'\", \"<stdin>: ERROR: Expected identifier but found \\\"''\\\"\\n\")\n\n\t// See: https://github.com/tc39/proposal-defer-import-eval\n\texpectPrinted(t, \"import defer from 'bar'\", \"import defer from \\\"bar\\\";\\n\")\n\texpectPrinted(t, \"import defer, { foo } from 'bar'\", \"import defer, { foo } from \\\"bar\\\";\\n\")\n\texpectPrinted(t, \"import defer * as foo from 'bar'\", \"import defer * as foo from \\\"bar\\\";\\n\")\n\texpectPrinted(t, \"import.defer('foo')\", \"import.defer(\\\"foo\\\");\\n\")\n\texpectParseError(t, \"import defer 'bar'\", \"<stdin>: ERROR: Expected \\\"from\\\" but found \\\"'bar'\\\"\\n\")\n\texpectParseError(t, \"import defer foo from 'bar'\", \"<stdin>: ERROR: Expected \\\"from\\\" but found \\\"foo\\\"\\n\")\n\texpectParseError(t, \"import defer { foo } from 'bar'\", \"<stdin>: ERROR: Expected \\\"from\\\" but found \\\"{\\\"\\n\")\n\texpectParseErrorTarget(t, 6, \"import defer * as foo from 'bar'\", \"<stdin>: ERROR: Deferred imports are not available in the configured target environment\\n\")\n\texpectParseErrorTarget(t, 6, \"import.defer('foo')\", \"<stdin>: ERROR: Deferred imports are not available in the configured target environment\\n\")\n\n\t// See: https://github.com/tc39/proposal-source-phase-imports\n\texpectPrinted(t, \"import source from 'bar'\", \"import source from \\\"bar\\\";\\n\")\n\texpectPrinted(t, \"import source, { foo } from 'bar'\", \"import source, { foo } from \\\"bar\\\";\\n\")\n\texpectPrinted(t, \"import source foo from 'bar'\", \"import source foo from \\\"bar\\\";\\n\")\n\texpectPrinted(t, \"import source from from 'bar'\", \"import source from from \\\"bar\\\";\\n\")\n\texpectPrinted(t, \"import source source from 'bar'\", \"import source source from \\\"bar\\\";\\n\")\n\texpectPrinted(t, \"import.source('foo')\", \"import.source(\\\"foo\\\");\\n\")\n\texpectParseError(t, \"import source 'bar'\", \"<stdin>: ERROR: Expected \\\"from\\\" but found \\\"'bar'\\\"\\n\")\n\texpectParseError(t, \"import source * as foo from 'bar'\", \"<stdin>: ERROR: Expected \\\"from\\\" but found \\\"*\\\"\\n\")\n\texpectParseError(t, \"import source { foo } from 'bar'\", \"<stdin>: ERROR: Expected \\\"from\\\" but found \\\"{\\\"\\n\")\n\texpectParseErrorTarget(t, 6, \"import source foo from 'bar'\", \"<stdin>: ERROR: Source phase imports are not available in the configured target environment\\n\")\n\texpectParseErrorTarget(t, 6, \"import.source('foo')\", \"<stdin>: ERROR: Source phase imports are not available in the configured target environment\\n\")\n}\n\nfunc TestExport(t *testing.T) {\n\texpectPrinted(t, \"export default x\", \"export default x;\\n\")\n\texpectPrinted(t, \"export class x {}\", \"export class x {\\n}\\n\")\n\texpectPrinted(t, \"export function x() {}\", \"export function x() {\\n}\\n\")\n\texpectPrinted(t, \"export async function x() {}\", \"export async function x() {\\n}\\n\")\n\texpectPrinted(t, \"export var x, y\", \"export var x, y;\\n\")\n\texpectPrinted(t, \"export let x, y\", \"export let x, y;\\n\")\n\texpectPrinted(t, \"export const x = 0, y = 1\", \"export const x = 0, y = 1;\\n\")\n\texpectPrinted(t, \"export * from \\\"foo\\\"\", \"export * from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"export * as ns from \\\"foo\\\"\", \"export * as ns from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"export * as if from \\\"foo\\\"\", \"export * as if from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"let x; export {x}\", \"let x;\\nexport { x };\\n\")\n\texpectPrinted(t, \"let x; export {x as y}\", \"let x;\\nexport { x as y };\\n\")\n\texpectPrinted(t, \"let x, z; export {x as y, z}\", \"let x, z;\\nexport { x as y, z };\\n\")\n\texpectPrinted(t, \"let x, z; export {x as y, z,}\", \"let x, z;\\nexport { x as y, z };\\n\")\n\texpectPrinted(t, \"let x; export {x} from \\\"foo\\\"\", \"let x;\\nexport { x } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"let x; export {x as y} from \\\"foo\\\"\", \"let x;\\nexport { x as y } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"let x, z; export {x as y, z} from \\\"foo\\\"\", \"let x, z;\\nexport { x as y, z } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"let x, z; export {x as y, z,} from \\\"foo\\\"\", \"let x, z;\\nexport { x as y, z } from \\\"foo\\\";\\n\")\n\n\texpectParseError(t, \"export x from \\\"foo\\\"\", \"<stdin>: ERROR: Unexpected \\\"x\\\"\\n\")\n\texpectParseError(t, \"export async\", \"<stdin>: ERROR: Expected \\\"function\\\" but found end of file\\n\")\n\texpectParseError(t, \"export async function\", \"<stdin>: ERROR: Expected identifier but found end of file\\n\")\n\texpectParseError(t, \"export async () => {}\", \"<stdin>: ERROR: Expected \\\"function\\\" but found \\\"(\\\"\\n\")\n\texpectParseError(t, \"export var\", \"<stdin>: ERROR: Expected identifier but found end of file\\n\")\n\texpectParseError(t, \"export let\", \"<stdin>: ERROR: Expected identifier but found end of file\\n\")\n\texpectParseError(t, \"export const\", \"<stdin>: ERROR: Expected identifier but found end of file\\n\")\n\n\t// Do not parse TypeScript export syntax in JavaScript\n\texpectParseError(t, \"export enum Foo {}\", \"<stdin>: ERROR: Unexpected \\\"enum\\\"\\n\")\n\texpectParseError(t, \"export interface Foo {}\", \"<stdin>: ERROR: Unexpected \\\"interface\\\"\\n\")\n\texpectParseError(t, \"export namespace Foo {}\", \"<stdin>: ERROR: Unexpected \\\"namespace\\\"\\n\")\n\texpectParseError(t, \"export abstract class Foo {}\", \"<stdin>: ERROR: Unexpected \\\"abstract\\\"\\n\")\n\texpectParseError(t, \"export declare class Foo {}\", \"<stdin>: ERROR: Unexpected \\\"declare\\\"\\n\")\n\texpectParseError(t, \"export declare function foo() {}\", \"<stdin>: ERROR: Unexpected \\\"declare\\\"\\n\")\n\n\t// String export alias with \"export {}\"\n\texpectPrinted(t, \"let x; export {x as ''}\", \"let x;\\nexport { x as \\\"\\\" };\\n\")\n\texpectPrinted(t, \"let x; export {x as '🍕'}\", \"let x;\\nexport { x as \\\"🍕\\\" };\\n\")\n\texpectPrinted(t, \"let x; export {x as 'a b'}\", \"let x;\\nexport { x as \\\"a b\\\" };\\n\")\n\texpectPrinted(t, \"let x; export {x as '\\\\uD800\\\\uDC00'}\", \"let x;\\nexport { x as 𐀀 };\\n\")\n\texpectParseError(t, \"let x; export {'x'}\", \"<stdin>: ERROR: Expected identifier but found \\\"'x'\\\"\\n\")\n\texpectParseError(t, \"let x; export {'x' as 'y'}\", \"<stdin>: ERROR: Expected identifier but found \\\"'x'\\\"\\n\")\n\texpectParseError(t, \"let x; export {x as '\\\\uD800'}\",\n\t\t\"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+D800\\n\")\n\texpectParseError(t, \"let x; export {x as '\\\\uDC00'}\",\n\t\t\"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+DC00\\n\")\n\n\t// String import alias with \"export {} from\"\n\texpectPrinted(t, \"export {'' as x} from 'foo'\", \"export { \\\"\\\" as x } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"export {'🍕' as x} from 'foo'\", \"export { \\\"🍕\\\" as x } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"export {'a b' as x} from 'foo'\", \"export { \\\"a b\\\" as x } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"export {'\\\\uD800\\\\uDC00' as x} from 'foo'\", \"export { 𐀀 as x } from \\\"foo\\\";\\n\")\n\texpectParseError(t, \"export {'\\\\uD800' as x} from 'foo'\",\n\t\t\"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+D800\\n\")\n\texpectParseError(t, \"export {'\\\\uDC00' as x} from 'foo'\",\n\t\t\"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+DC00\\n\")\n\n\t// String export alias with \"export {} from\"\n\texpectPrinted(t, \"export {x as ''} from 'foo'\", \"export { x as \\\"\\\" } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"export {x as '🍕'} from 'foo'\", \"export { x as \\\"🍕\\\" } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"export {x as 'a b'} from 'foo'\", \"export { x as \\\"a b\\\" } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"export {x as '\\\\uD800\\\\uDC00'} from 'foo'\", \"export { x as 𐀀 } from \\\"foo\\\";\\n\")\n\texpectParseError(t, \"export {x as '\\\\uD800'} from 'foo'\",\n\t\t\"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+D800\\n\")\n\texpectParseError(t, \"export {x as '\\\\uDC00'} from 'foo'\",\n\t\t\"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+DC00\\n\")\n\n\t// String import and export alias with \"export {} from\"\n\texpectPrinted(t, \"export {'x'} from 'foo'\", \"export { x } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"export {'a b'} from 'foo'\", \"export { \\\"a b\\\" } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"export {'x' as 'y'} from 'foo'\", \"export { x as y } from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"export {'a b' as 'c d'} from 'foo'\", \"export { \\\"a b\\\" as \\\"c d\\\" } from \\\"foo\\\";\\n\")\n\n\t// String export alias with \"export * as\"\n\texpectPrinted(t, \"export * as '' from 'foo'\", \"export * as \\\"\\\" from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"export * as '🍕' from 'foo'\", \"export * as \\\"🍕\\\" from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"export * as 'a b' from 'foo'\", \"export * as \\\"a b\\\" from \\\"foo\\\";\\n\")\n\texpectPrinted(t, \"export * as '\\\\uD800\\\\uDC00' from 'foo'\", \"export * as 𐀀 from \\\"foo\\\";\\n\")\n\texpectParseError(t, \"export * as '\\\\uD800' from 'foo'\",\n\t\t\"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+D800\\n\")\n\texpectParseError(t, \"export * as '\\\\uDC00' from 'foo'\",\n\t\t\"<stdin>: ERROR: This export alias is invalid because it contains the unpaired Unicode surrogate U+DC00\\n\")\n}\n\nfunc TestExportDuplicates(t *testing.T) {\n\texpectPrinted(t, \"export {x};let x\", \"export { x };\\nlet x;\\n\")\n\texpectPrinted(t, \"export {x, x as y};let x\", \"export { x, x as y };\\nlet x;\\n\")\n\texpectPrinted(t, \"export {x};export {x as y} from 'foo';let x\", \"export { x };\\nexport { x as y } from \\\"foo\\\";\\nlet x;\\n\")\n\texpectPrinted(t, \"export {x};export default function x() {}\", \"export { x };\\nexport default function x() {\\n}\\n\")\n\texpectPrinted(t, \"export {x};export default class x {}\", \"export { x };\\nexport default class x {\\n}\\n\")\n\n\terrorTextX := `<stdin>: ERROR: Multiple exports with the same name \"x\"\n<stdin>: NOTE: The name \"x\" was originally exported here:\n`\n\n\texpectParseError(t, \"export {x, x};let x\", errorTextX)\n\texpectParseError(t, \"export {x, y as x};let x, y\", errorTextX)\n\texpectParseError(t, \"export {x};export function x() {}\", errorTextX)\n\texpectParseError(t, \"export {x};export class x {}\", errorTextX)\n\texpectParseError(t, \"export {x};export const x = 0\", errorTextX)\n\texpectParseError(t, \"export {x};export let x\", errorTextX)\n\texpectParseError(t, \"export {x};export var x\", errorTextX)\n\texpectParseError(t, \"export {x};let x;export {x} from 'foo'\", errorTextX)\n\texpectParseError(t, \"export {x};let x;export {y as x} from 'foo'\", errorTextX)\n\texpectParseError(t, \"export {x};let x;export * as x from 'foo'\", errorTextX)\n\n\terrorTextDefault := `<stdin>: ERROR: Multiple exports with the same name \"default\"\n<stdin>: NOTE: The name \"default\" was originally exported here:\n`\n\n\texpectParseError(t, \"export {x as default};let x;export default 0\", errorTextDefault)\n\texpectParseError(t, \"export {x as default};let x;export default function() {}\", errorTextDefault)\n\texpectParseError(t, \"export {x as default};let x;export default class {}\", errorTextDefault)\n\texpectParseError(t, \"export {x as default};export default function x() {}\", errorTextDefault)\n\texpectParseError(t, \"export {x as default};export default class x {}\", errorTextDefault)\n}\n\nfunc TestExportDefault(t *testing.T) {\n\texpectParseError(t, \"export default 1, 2\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\",\\\"\\n\")\n\texpectPrinted(t, \"export default (1, 2)\", \"export default (1, 2);\\n\")\n\n\texpectParseError(t, \"export default async, 0\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\",\\\"\\n\")\n\texpectPrinted(t, \"export default async\", \"export default async;\\n\")\n\texpectPrinted(t, \"export default async()\", \"export default async();\\n\")\n\texpectPrinted(t, \"export default async + 1\", \"export default async + 1;\\n\")\n\texpectPrinted(t, \"export default async => {}\", \"export default (async) => {\\n};\\n\")\n\texpectPrinted(t, \"export default async x => {}\", \"export default async (x) => {\\n};\\n\")\n\texpectPrinted(t, \"export default async () => {}\", \"export default async () => {\\n};\\n\")\n\n\t// This is a corner case in the ES6 grammar. The \"export default\" statement\n\t// normally takes an expression except for the function and class keywords\n\t// which behave sort of like their respective declarations instead.\n\texpectPrinted(t, \"export default function() {} - after\", \"export default function() {\\n}\\n-after;\\n\")\n\texpectPrinted(t, \"export default function*() {} - after\", \"export default function* () {\\n}\\n-after;\\n\")\n\texpectPrinted(t, \"export default function foo() {} - after\", \"export default function foo() {\\n}\\n-after;\\n\")\n\texpectPrinted(t, \"export default function* foo() {} - after\", \"export default function* foo() {\\n}\\n-after;\\n\")\n\texpectPrinted(t, \"export default async function() {} - after\", \"export default async function() {\\n}\\n-after;\\n\")\n\texpectPrinted(t, \"export default async function*() {} - after\", \"export default async function* () {\\n}\\n-after;\\n\")\n\texpectPrinted(t, \"export default async function foo() {} - after\", \"export default async function foo() {\\n}\\n-after;\\n\")\n\texpectPrinted(t, \"export default async function* foo() {} - after\", \"export default async function* foo() {\\n}\\n-after;\\n\")\n\texpectPrinted(t, \"export default class {} - after\", \"export default class {\\n}\\n-after;\\n\")\n\texpectPrinted(t, \"export default class Foo {} - after\", \"export default class Foo {\\n}\\n-after;\\n\")\n\n\t// Check ASI for \"abstract\"\n\texpectPrinted(t, \"export default abstract\\nclass Foo {}\", \"export default abstract;\\nclass Foo {\\n}\\n\")\n\texpectParseError(t, \"export default abstract class {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"class\\\"\\n\")\n}\n\nfunc TestExportClause(t *testing.T) {\n\texpectPrinted(t, \"export {x, y};let x, y\", \"export { x, y };\\nlet x, y;\\n\")\n\texpectPrinted(t, \"export {x, y as z,};let x, y\", \"export { x, y as z };\\nlet x, y;\\n\")\n\texpectPrinted(t, \"export {x, y} from 'path'\", \"export { x, y } from \\\"path\\\";\\n\")\n\texpectPrinted(t, \"export {default, if} from 'path'\", \"export { default, if } from \\\"path\\\";\\n\")\n\texpectPrinted(t, \"export {default as foo, if as bar} from 'path'\", \"export { default as foo, if as bar } from \\\"path\\\";\\n\")\n\texpectParseError(t, \"export {default}\", \"<stdin>: ERROR: Expected identifier but found \\\"default\\\"\\n\")\n\texpectParseError(t, \"export {default as foo}\", \"<stdin>: ERROR: Expected identifier but found \\\"default\\\"\\n\")\n\texpectParseError(t, \"export {if}\", \"<stdin>: ERROR: Expected identifier but found \\\"if\\\"\\n\")\n\texpectParseError(t, \"export {if as foo}\", \"<stdin>: ERROR: Expected identifier but found \\\"if\\\"\\n\")\n}\n\nfunc TestCatch(t *testing.T) {\n\texpectPrinted(t, \"try {} catch (e) {}\", \"try {\\n} catch (e) {\\n}\\n\")\n\texpectPrinted(t, \"try {} catch (e) { var e }\", \"try {\\n} catch (e) {\\n  var e;\\n}\\n\")\n\texpectPrinted(t, \"var e; try {} catch (e) {}\", \"var e;\\ntry {\\n} catch (e) {\\n}\\n\")\n\texpectPrinted(t, \"let e; try {} catch (e) {}\", \"let e;\\ntry {\\n} catch (e) {\\n}\\n\")\n\texpectPrinted(t, \"try { var e } catch (e) {}\", \"try {\\n  var e;\\n} catch (e) {\\n}\\n\")\n\texpectPrinted(t, \"try { function e() {} } catch (e) {}\", \"try {\\n  let e = function() {\\n  };\\n  var e = e;\\n} catch (e) {\\n}\\n\")\n\texpectPrinted(t, \"try {} catch (e) { { function e() {} } }\", \"try {\\n} catch (e) {\\n  {\\n    let e = function() {\\n    };\\n    var e = e;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"try {} catch (e) { if (1) function e() {} }\", \"try {\\n} catch (e) {\\n  if (1) {\\n    let e = function() {\\n    };\\n    var e = e;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"try {} catch (e) { if (0) ; else function e() {} }\", \"try {\\n} catch (e) {\\n  if (0) ;\\n  else {\\n    let e = function() {\\n    };\\n    var e = e;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"try {} catch ({ e }) { { function e() {} } }\", \"try {\\n} catch ({ e }) {\\n  {\\n    let e = function() {\\n    };\\n    var e = e;\\n  }\\n}\\n\")\n\n\terrorText := `<stdin>: ERROR: The symbol \"e\" has already been declared\n<stdin>: NOTE: The symbol \"e\" was originally declared here:\n`\n\n\texpectParseError(t, \"try {} catch (e) { function e() {} }\", errorText)\n\texpectParseError(t, \"try {} catch ({ e }) { var e }\", errorText)\n\texpectParseError(t, \"try {} catch ({ e }) { { var e } }\", errorText)\n\texpectParseError(t, \"try {} catch ({ e }) { function e() {} }\", errorText)\n\texpectParseError(t, \"try {} catch (e) { let e }\", errorText)\n\texpectParseError(t, \"try {} catch (e) { const e = 0 }\", errorText)\n}\n\nfunc TestWarningEqualsNegativeZero(t *testing.T) {\n\tnote := \"NOTE: Floating-point equality is defined such that 0 and -0 are equal, so \\\"x === -0\\\" returns true for both 0 and -0. \" +\n\t\t\"You need to use \\\"Object.is(x, -0)\\\" instead to test for -0.\\n\"\n\n\texpectParseError(t, \"x === -0\", \"<stdin>: WARNING: Comparison with -0 using the \\\"===\\\" operator will also match 0\\n\"+note)\n\texpectParseError(t, \"x == -0\", \"<stdin>: WARNING: Comparison with -0 using the \\\"==\\\" operator will also match 0\\n\"+note)\n\texpectParseError(t, \"x !== -0\", \"<stdin>: WARNING: Comparison with -0 using the \\\"!==\\\" operator will also match 0\\n\"+note)\n\texpectParseError(t, \"x != -0\", \"<stdin>: WARNING: Comparison with -0 using the \\\"!=\\\" operator will also match 0\\n\"+note)\n\texpectParseError(t, \"switch (x) { case -0: }\", \"<stdin>: WARNING: Comparison with -0 using a case clause will also match 0\\n\"+note)\n\n\texpectParseError(t, \"-0 === x\", \"<stdin>: WARNING: Comparison with -0 using the \\\"===\\\" operator will also match 0\\n\"+note)\n\texpectParseError(t, \"-0 == x\", \"<stdin>: WARNING: Comparison with -0 using the \\\"==\\\" operator will also match 0\\n\"+note)\n\texpectParseError(t, \"-0 !== x\", \"<stdin>: WARNING: Comparison with -0 using the \\\"!==\\\" operator will also match 0\\n\"+note)\n\texpectParseError(t, \"-0 != x\", \"<stdin>: WARNING: Comparison with -0 using the \\\"!=\\\" operator will also match 0\\n\"+note)\n\texpectParseError(t, \"switch (-0) { case x: }\", \"\") // Don't bother to handle this case\n}\n\nfunc TestWarningEqualsNewObject(t *testing.T) {\n\tnote := \"NOTE: Equality with a new object is always false in JavaScript because the equality operator tests object identity. \" +\n\t\t\"You need to write code to compare the contents of the object instead. \" +\n\t\t\"For example, use \\\"Array.isArray(x) && x.length === 0\\\" instead of \\\"x === []\\\" to test for an empty array.\\n\"\n\n\texpectParseError(t, \"x === []\", \"<stdin>: WARNING: Comparison using the \\\"===\\\" operator here is always false\\n\"+note)\n\texpectParseError(t, \"x !== []\", \"<stdin>: WARNING: Comparison using the \\\"!==\\\" operator here is always true\\n\"+note)\n\texpectParseError(t, \"x == []\", \"\")\n\texpectParseError(t, \"x != []\", \"\")\n\texpectParseError(t, \"switch (x) { case []: }\", \"<stdin>: WARNING: This case clause will never be evaluated because the comparison is always false\\n\"+note)\n\n\texpectParseError(t, \"[] === x\", \"<stdin>: WARNING: Comparison using the \\\"===\\\" operator here is always false\\n\"+note)\n\texpectParseError(t, \"[] !== x\", \"<stdin>: WARNING: Comparison using the \\\"!==\\\" operator here is always true\\n\"+note)\n\texpectParseError(t, \"[] == x\", \"\")\n\texpectParseError(t, \"[] != x\", \"\")\n\texpectParseError(t, \"switch ([]) { case x: }\", \"\") // Don't bother to handle this case\n}\n\nfunc TestWarningEqualsNaN(t *testing.T) {\n\tnote := \"NOTE: Floating-point equality is defined such that NaN is never equal to anything, so \\\"x === NaN\\\" always returns false. \" +\n\t\t\"You need to use \\\"Number.isNaN(x)\\\" instead to test for NaN.\\n\"\n\n\texpectParseError(t, \"x === NaN\", \"<stdin>: WARNING: Comparison with NaN using the \\\"===\\\" operator here is always false\\n\"+note)\n\texpectParseError(t, \"x !== NaN\", \"<stdin>: WARNING: Comparison with NaN using the \\\"!==\\\" operator here is always true\\n\"+note)\n\texpectParseError(t, \"x == NaN\", \"<stdin>: WARNING: Comparison with NaN using the \\\"==\\\" operator here is always false\\n\"+note)\n\texpectParseError(t, \"x != NaN\", \"<stdin>: WARNING: Comparison with NaN using the \\\"!=\\\" operator here is always true\\n\"+note)\n\texpectParseError(t, \"switch (x) { case NaN: }\", \"<stdin>: WARNING: This case clause will never be evaluated because equality with NaN is always false\\n\"+note)\n\n\texpectParseError(t, \"NaN === x\", \"<stdin>: WARNING: Comparison with NaN using the \\\"===\\\" operator here is always false\\n\"+note)\n\texpectParseError(t, \"NaN !== x\", \"<stdin>: WARNING: Comparison with NaN using the \\\"!==\\\" operator here is always true\\n\"+note)\n\texpectParseError(t, \"NaN == x\", \"<stdin>: WARNING: Comparison with NaN using the \\\"==\\\" operator here is always false\\n\"+note)\n\texpectParseError(t, \"NaN != x\", \"<stdin>: WARNING: Comparison with NaN using the \\\"!=\\\" operator here is always true\\n\"+note)\n\texpectParseError(t, \"switch (NaN) { case x: }\", \"\") // Don't bother to handle this case\n}\n\nfunc TestWarningTypeofEquals(t *testing.T) {\n\tnote := \"NOTE: The expression \\\"typeof x\\\" actually evaluates to \\\"object\\\" in JavaScript, not \\\"null\\\". \" +\n\t\t\"You need to use \\\"x === null\\\" to test for null.\\n\"\n\n\texpectParseError(t, \"typeof x === 'null'\", \"<stdin>: WARNING: The \\\"typeof\\\" operator will never evaluate to \\\"null\\\"\\n\"+note)\n\texpectParseError(t, \"typeof x !== 'null'\", \"<stdin>: WARNING: The \\\"typeof\\\" operator will never evaluate to \\\"null\\\"\\n\"+note)\n\texpectParseError(t, \"typeof x == 'null'\", \"<stdin>: WARNING: The \\\"typeof\\\" operator will never evaluate to \\\"null\\\"\\n\"+note)\n\texpectParseError(t, \"typeof x != 'null'\", \"<stdin>: WARNING: The \\\"typeof\\\" operator will never evaluate to \\\"null\\\"\\n\"+note)\n\texpectParseError(t, \"switch (typeof x) { case 'null': }\", \"<stdin>: WARNING: The \\\"typeof\\\" operator will never evaluate to \\\"null\\\"\\n\"+note)\n\n\texpectParseError(t, \"'null' === typeof x\", \"<stdin>: WARNING: The \\\"typeof\\\" operator will never evaluate to \\\"null\\\"\\n\"+note)\n\texpectParseError(t, \"'null' !== typeof x\", \"<stdin>: WARNING: The \\\"typeof\\\" operator will never evaluate to \\\"null\\\"\\n\"+note)\n\texpectParseError(t, \"'null' == typeof x\", \"<stdin>: WARNING: The \\\"typeof\\\" operator will never evaluate to \\\"null\\\"\\n\"+note)\n\texpectParseError(t, \"'null' != typeof x\", \"<stdin>: WARNING: The \\\"typeof\\\" operator will never evaluate to \\\"null\\\"\\n\"+note)\n\texpectParseError(t, \"switch ('null') { case typeof x: }\", \"\") // Don't bother to handle this case\n}\n\nfunc TestWarningDeleteSuperProperty(t *testing.T) {\n\ttext := \"<stdin>: WARNING: Attempting to delete a property of \\\"super\\\" will throw a ReferenceError\\n\"\n\texpectParseError(t, \"class Foo extends Bar { constructor() { delete super.foo } }\", text)\n\texpectParseError(t, \"class Foo extends Bar { constructor() { delete super['foo'] } }\", text)\n\texpectParseError(t, \"class Foo extends Bar { constructor() { delete (super.foo) } }\", text)\n\texpectParseError(t, \"class Foo extends Bar { constructor() { delete (super['foo']) } }\", text)\n\n\texpectParseError(t, \"class Foo extends Bar { constructor() { delete super.foo.bar } }\", \"\")\n\texpectParseError(t, \"class Foo extends Bar { constructor() { delete super['foo']['bar'] } }\", \"\")\n}\n\nfunc TestWarningDuplicateCase(t *testing.T) {\n\texpectParseError(t, \"switch (x) { case null: case undefined: }\", \"\")\n\texpectParseError(t, \"switch (x) { case false: case true: }\", \"\")\n\texpectParseError(t, \"switch (x) { case 0: case 1: }\", \"\")\n\texpectParseError(t, \"switch (x) { case 1: case 1n: }\", \"\")\n\texpectParseError(t, \"switch (x) { case 'a': case 'b': }\", \"\")\n\texpectParseError(t, \"switch (x) { case y: case z: }\", \"\")\n\texpectParseError(t, \"switch (x) { case y.a: case y.b: }\", \"\")\n\texpectParseError(t, \"switch (x) { case y.a: case z.a: }\", \"\")\n\texpectParseError(t, \"switch (x) { case y.a: case y?.a: }\", \"\")\n\texpectParseError(t, \"switch (x) { case y[a]: case y[b]: }\", \"\")\n\texpectParseError(t, \"switch (x) { case y[a]: case z[a]: }\", \"\")\n\texpectParseError(t, \"switch (x) { case y[a]: case y?.[a]: }\", \"\")\n\n\talwaysWarning := \"<stdin>: WARNING: This case clause will never be evaluated because it duplicates an earlier case clause\\n\" +\n\t\t\"<stdin>: NOTE: The earlier case clause is here:\\n\"\n\tlikelyWarning := \"<stdin>: WARNING: This case clause may never be evaluated because it likely duplicates an earlier case clause\\n\" +\n\t\t\"<stdin>: NOTE: The earlier case clause is here:\\n\"\n\n\texpectParseError(t, \"switch (x) { case null: case null: }\", alwaysWarning)\n\texpectParseError(t, \"switch (x) { case undefined: case undefined: }\", alwaysWarning)\n\texpectParseError(t, \"switch (x) { case true: case true: }\", alwaysWarning)\n\texpectParseError(t, \"switch (x) { case false: case false: }\", alwaysWarning)\n\texpectParseError(t, \"switch (x) { case 0xF: case 15: }\", alwaysWarning)\n\texpectParseError(t, \"switch (x) { case 'a': case `a`: }\", alwaysWarning)\n\texpectParseError(t, \"switch (x) { case 123n: case 1_2_3n: }\", alwaysWarning)\n\texpectParseError(t, \"switch (x) { case y: case y: }\", alwaysWarning)\n\texpectParseError(t, \"switch (x) { case y.a: case y.a: }\", likelyWarning)\n\texpectParseError(t, \"switch (x) { case y?.a: case y?.a: }\", likelyWarning)\n\texpectParseError(t, \"switch (x) { case y[a]: case y[a]: }\", likelyWarning)\n\texpectParseError(t, \"switch (x) { case y?.[a]: case y?.[a]: }\", likelyWarning)\n}\n\nfunc TestWarningDuplicateClassMember(t *testing.T) {\n\tduplicateWarning := \"<stdin>: WARNING: Duplicate member \\\"x\\\" in class body\\n\" +\n\t\t\"<stdin>: NOTE: The original member \\\"x\\\" is here:\\n\"\n\n\texpectParseError(t, \"class Foo { x; x }\", duplicateWarning)\n\texpectParseError(t, \"class Foo { x() {}; x() {} }\", duplicateWarning)\n\texpectParseError(t, \"class Foo { get x() {}; get x() {} }\", duplicateWarning)\n\texpectParseError(t, \"class Foo { get x() {}; set x(y) {}; get x() {} }\", duplicateWarning)\n\texpectParseError(t, \"class Foo { get x() {}; set x(y) {}; set x(y) {} }\", duplicateWarning)\n\texpectParseError(t, \"class Foo { get x() {}; set x(y) {} }\", \"\")\n\texpectParseError(t, \"class Foo { set x(y) {}; get x() {} }\", \"\")\n\n\texpectParseError(t, \"class Foo { static x; static x }\", duplicateWarning)\n\texpectParseError(t, \"class Foo { static x() {}; static x() {} }\", duplicateWarning)\n\texpectParseError(t, \"class Foo { static get x() {}; static get x() {} }\", duplicateWarning)\n\texpectParseError(t, \"class Foo { static get x() {}; static set x(y) {}; static get x() {} }\", duplicateWarning)\n\texpectParseError(t, \"class Foo { static get x() {}; static set x(y) {}; static set x(y) {} }\", duplicateWarning)\n\texpectParseError(t, \"class Foo { static get x() {}; static set x(y) {} }\", \"\")\n\texpectParseError(t, \"class Foo { static set x(y) {}; static get x() {} }\", \"\")\n\n\texpectParseError(t, \"class Foo { x; static x }\", \"\")\n\texpectParseError(t, \"class Foo { x; static x() {} }\", \"\")\n\texpectParseError(t, \"class Foo { x() {}; static x }\", \"\")\n\texpectParseError(t, \"class Foo { x() {}; static x() {} }\", \"\")\n\texpectParseError(t, \"class Foo { static x; x }\", \"\")\n\texpectParseError(t, \"class Foo { static x; x() {} }\", \"\")\n\texpectParseError(t, \"class Foo { static x() {}; x }\", \"\")\n\texpectParseError(t, \"class Foo { static x() {}; x() {} }\", \"\")\n\texpectParseError(t, \"class Foo { get x() {}; static get x() {} }\", \"\")\n\texpectParseError(t, \"class Foo { set x(y) {}; static set x(y) {} }\", \"\")\n}\n\nfunc TestWarningNullishCoalescing(t *testing.T) {\n\texpectParseError(t, \"x = null ?? y\", \"\")\n\texpectParseError(t, \"x = undefined ?? y\", \"\")\n\texpectParseError(t, \"x = false ?? y\", \"\")\n\texpectParseError(t, \"x = true ?? y\", \"\")\n\texpectParseError(t, \"x = 0 ?? y\", \"\")\n\texpectParseError(t, \"x = 1 ?? y\", \"\")\n\n\talwaysLeft := \"<stdin>: WARNING: The \\\"??\\\" operator here will always return the left operand\\n\" +\n\t\t\"<stdin>: NOTE: The left operand of the \\\"??\\\" operator here will never be null or undefined, so it will always be returned. This usually indicates a bug in your code:\\n\"\n\talwaysRight := \"<stdin>: WARNING: The \\\"??\\\" operator here will always return the right operand\\n\" +\n\t\t\"<stdin>: NOTE: The left operand of the \\\"??\\\" operator here will always be null or undefined, so it will never be returned. This usually indicates a bug in your code:\\n\"\n\n\texpectParseError(t, \"x = a === b ?? y\", alwaysLeft)\n\texpectParseError(t, \"x = { ...a } ?? y\", alwaysLeft)\n\texpectParseError(t, \"x = (a => b) ?? y\", alwaysLeft)\n\texpectParseError(t, \"x = void a ?? y\", alwaysRight)\n}\n\nfunc TestWarningLogicalOperator(t *testing.T) {\n\texpectParseError(t, \"x(a => b && a <= c)\", \"\")\n\texpectParseError(t, \"x(a => b || a <= c)\", \"\")\n\texpectParseError(t, \"x(a => (0 && a <= 1))\", \"\")\n\texpectParseError(t, \"x(a => (-1 && a <= 0))\", \"\")\n\texpectParseError(t, \"x(a => (0 || a <= -1))\", \"\")\n\texpectParseError(t, \"x(a => (1 || a <= 0))\", \"\")\n\n\texpectParseError(t, \"x(a => 0 && a <= 1)\", \"<stdin>: WARNING: The \\\"&&\\\" operator here will always return the left operand\\n\"+\n\t\t\"<stdin>: NOTE: The \\\"=>\\\" symbol creates an arrow function expression in JavaScript. Did you mean to use the greater-than-or-equal-to operator \\\">=\\\" here instead?\\n\")\n\texpectParseError(t, \"x(a => -1 && a <= 0)\", \"<stdin>: WARNING: The \\\"&&\\\" operator here will always return the right operand\\n\"+\n\t\t\"<stdin>: NOTE: The \\\"=>\\\" symbol creates an arrow function expression in JavaScript. Did you mean to use the greater-than-or-equal-to operator \\\">=\\\" here instead?\\n\")\n\texpectParseError(t, \"x(a => 0 || a <= -1)\", \"<stdin>: WARNING: The \\\"||\\\" operator here will always return the right operand\\n\"+\n\t\t\"<stdin>: NOTE: The \\\"=>\\\" symbol creates an arrow function expression in JavaScript. Did you mean to use the greater-than-or-equal-to operator \\\">=\\\" here instead?\\n\")\n\texpectParseError(t, \"x(a => 1 || a <= 0)\", \"<stdin>: WARNING: The \\\"||\\\" operator here will always return the left operand\\n\"+\n\t\t\"<stdin>: NOTE: The \\\"=>\\\" symbol creates an arrow function expression in JavaScript. Did you mean to use the greater-than-or-equal-to operator \\\">=\\\" here instead?\\n\")\n}\n\nfunc TestMangleFor(t *testing.T) {\n\texpectPrintedMangle(t, \"var a; while (1) ;\", \"for (var a; ; ) ;\\n\")\n\texpectPrintedMangle(t, \"let a; while (1) ;\", \"let a;\\nfor (; ; ) ;\\n\")\n\texpectPrintedMangle(t, \"const a=0; while (1) ;\", \"const a = 0;\\nfor (; ; ) ;\\n\")\n\n\texpectPrintedMangle(t, \"var a; for (var b;;) ;\", \"for (var a, b; ; ) ;\\n\")\n\texpectPrintedMangle(t, \"let a; for (let b;;) ;\", \"let a;\\nfor (let b; ; ) ;\\n\")\n\texpectPrintedMangle(t, \"const a=0; for (const b = 1;;) ;\", \"const a = 0;\\nfor (const b = 1; ; ) ;\\n\")\n\n\texpectPrintedMangle(t, \"export var a; while (1) ;\", \"export var a;\\nfor (; ; ) ;\\n\")\n\texpectPrintedMangle(t, \"export let a; while (1) ;\", \"export let a;\\nfor (; ; ) ;\\n\")\n\texpectPrintedMangle(t, \"export const a=0; while (1) ;\", \"export const a = 0;\\nfor (; ; ) ;\\n\")\n\n\texpectPrintedMangle(t, \"export var a; for (var b;;) ;\", \"export var a;\\nfor (var b; ; ) ;\\n\")\n\texpectPrintedMangle(t, \"export let a; for (let b;;) ;\", \"export let a;\\nfor (let b; ; ) ;\\n\")\n\texpectPrintedMangle(t, \"export const a=0; for (const b = 1;;) ;\", \"export const a = 0;\\nfor (const b = 1; ; ) ;\\n\")\n\n\texpectPrintedMangle(t, \"var a; for (let b;;) ;\", \"var a;\\nfor (let b; ; ) ;\\n\")\n\texpectPrintedMangle(t, \"let a; for (const b=0;;) ;\", \"let a;\\nfor (const b = 0; ; ) ;\\n\")\n\texpectPrintedMangle(t, \"const a=0; for (var b;;) ;\", \"const a = 0;\\nfor (var b; ; ) ;\\n\")\n\n\texpectPrintedMangle(t, \"a(); while (1) ;\", \"for (a(); ; ) ;\\n\")\n\texpectPrintedMangle(t, \"a(); for (b();;) ;\", \"for (a(), b(); ; ) ;\\n\")\n\n\texpectPrintedMangle(t, \"for (; ;) if (x) break;\", \"for (; !x; ) ;\\n\")\n\texpectPrintedMangle(t, \"for (; ;) if (!x) break;\", \"for (; x; ) ;\\n\")\n\texpectPrintedMangle(t, \"for (; a;) if (x) break;\", \"for (; a && !x; ) ;\\n\")\n\texpectPrintedMangle(t, \"for (; a;) if (!x) break;\", \"for (; a && x; ) ;\\n\")\n\texpectPrintedMangle(t, \"for (; ;) { if (x) break; y(); }\", \"for (; !x; )\\n  y();\\n\")\n\texpectPrintedMangle(t, \"for (; a;) { if (x) break; y(); }\", \"for (; a && !x; )\\n  y();\\n\")\n\texpectPrintedMangle(t, \"for (; ;) if (x) break; else y();\", \"for (; !x; ) y();\\n\")\n\texpectPrintedMangle(t, \"for (; a;) if (x) break; else y();\", \"for (; a && !x; ) y();\\n\")\n\texpectPrintedMangle(t, \"for (; ;) { if (x) break; else y(); z(); }\", \"for (; !x; )\\n  y(), z();\\n\")\n\texpectPrintedMangle(t, \"for (; a;) { if (x) break; else y(); z(); }\", \"for (; a && !x; )\\n  y(), z();\\n\")\n\texpectPrintedMangle(t, \"for (; ;) if (x) y(); else break;\", \"for (; x; ) y();\\n\")\n\texpectPrintedMangle(t, \"for (; ;) if (!x) y(); else break;\", \"for (; !x; ) y();\\n\")\n\texpectPrintedMangle(t, \"for (; a;) if (x) y(); else break;\", \"for (; a && x; ) y();\\n\")\n\texpectPrintedMangle(t, \"for (; a;) if (!x) y(); else break;\", \"for (; a && !x; ) y();\\n\")\n\texpectPrintedMangle(t, \"for (; ;) { if (x) y(); else break; z(); }\", \"for (; x; ) {\\n  y();\\n  z();\\n}\\n\")\n\texpectPrintedMangle(t, \"for (; a;) { if (x) y(); else break; z(); }\", \"for (; a && x; ) {\\n  y();\\n  z();\\n}\\n\")\n}\n\nfunc TestMangleLoopJump(t *testing.T) {\n\t// Trim after jump\n\texpectPrintedMangle(t, \"while (x) { if (1) break; z(); }\", \"for (; x; )\\n  break;\\n\")\n\texpectPrintedMangle(t, \"while (x) { if (1) continue; z(); }\", \"for (; x; )\\n  ;\\n\")\n\texpectPrintedMangle(t, \"foo: while (a) while (x) { if (1) continue foo; z(); }\", \"foo: for (; a; ) for (; x; )\\n  continue foo;\\n\")\n\texpectPrintedMangle(t, \"while (x) { y(); if (1) break; z(); }\", \"for (; x; ) {\\n  y();\\n  break;\\n}\\n\")\n\texpectPrintedMangle(t, \"while (x) { y(); if (1) continue; z(); }\", \"for (; x; )\\n  y();\\n\")\n\texpectPrintedMangle(t, \"while (x) { y(); debugger; if (1) continue; z(); }\", \"for (; x; ) {\\n  y();\\n  debugger;\\n}\\n\")\n\texpectPrintedMangle(t, \"while (x) { let y = z(); if (1) continue; z(); }\", \"for (; x; ) {\\n  let y = z();\\n}\\n\")\n\texpectPrintedMangle(t, \"while (x) { debugger; if (y) { if (1) break; z() } }\", \"for (; x; ) {\\n  debugger;\\n  if (y)\\n    break;\\n}\\n\")\n\texpectPrintedMangle(t, \"while (x) { debugger; if (y) { if (1) continue; z() } }\", \"for (; x; ) {\\n  debugger;\\n  y;\\n}\\n\")\n\texpectPrintedMangle(t, \"while (x) { debugger; if (1) { if (1) break; z() } }\", \"for (; x; ) {\\n  debugger;\\n  break;\\n}\\n\")\n\texpectPrintedMangle(t, \"while (x) { debugger; if (1) { if (1) continue; z() } }\", \"for (; x; )\\n  debugger;\\n\")\n\n\t// Trim trailing continue\n\texpectPrintedMangle(t, \"while (x()) continue\", \"for (; x(); ) ;\\n\")\n\texpectPrintedMangle(t, \"while (x) { y(); continue }\", \"for (; x; )\\n  y();\\n\")\n\texpectPrintedMangle(t, \"while (x) { if (y) { z(); continue } }\",\n\t\t\"for (; x; )\\n  if (y) {\\n    z();\\n    continue;\\n  }\\n\")\n\texpectPrintedMangle(t, \"label: while (x) while (y) { z(); continue label }\",\n\t\t\"label: for (; x; ) for (; y; ) {\\n  z();\\n  continue label;\\n}\\n\")\n\n\t// Optimize implicit continue\n\texpectPrintedMangle(t, \"while (x) { if (y) continue; z(); }\", \"for (; x; )\\n  y || z();\\n\")\n\texpectPrintedMangle(t, \"while (x) { if (y) continue; else z(); w(); }\", \"for (; x; )\\n  y || (z(), w());\\n\")\n\texpectPrintedMangle(t, \"while (x) { t(); if (y) continue; z(); }\", \"for (; x; )\\n  t(), !y && z();\\n\")\n\texpectPrintedMangle(t, \"while (x) { t(); if (y) continue; else z(); w(); }\", \"for (; x; )\\n  t(), !y && (z(), w());\\n\")\n\texpectPrintedMangle(t, \"while (x) { debugger; if (y) continue; z(); }\", \"for (; x; ) {\\n  debugger;\\n  y || z();\\n}\\n\")\n\texpectPrintedMangle(t, \"while (x) { debugger; if (y) continue; else z(); w(); }\", \"for (; x; ) {\\n  debugger;\\n  y || (z(), w());\\n}\\n\")\n\n\t// Do not optimize implicit continue for statements that care about scope\n\texpectPrintedMangle(t, \"while (x) { if (y) continue; function y() {} }\", \"for (; x; ) {\\n  let y = function() {\\n  };\\n  var y = y;\\n}\\n\")\n\texpectPrintedMangle(t, \"while (x) { if (y) continue; let y }\", \"for (; x; ) {\\n  if (y) continue;\\n  let y;\\n}\\n\")\n\texpectPrintedMangle(t, \"while (x) { if (y) continue; var y }\", \"for (; x; )\\n  if (!y)\\n    var y;\\n\")\n}\n\nfunc TestMangleUndefined(t *testing.T) {\n\t// These should be transformed\n\texpectPrintedNormalAndMangle(t, \"console.log(undefined)\", \"console.log(void 0);\\n\", \"console.log(void 0);\\n\")\n\texpectPrintedNormalAndMangle(t, \"console.log(+undefined)\", \"console.log(NaN);\\n\", \"console.log(NaN);\\n\")\n\texpectPrintedNormalAndMangle(t, \"console.log(undefined + undefined)\", \"console.log(void 0 + void 0);\\n\", \"console.log(void 0 + void 0);\\n\")\n\texpectPrintedNormalAndMangle(t, \"const x = undefined\", \"const x = void 0;\\n\", \"const x = void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = undefined\", \"let x = void 0;\\n\", \"let x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"var x = undefined\", \"var x = void 0;\\n\", \"var x = void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"function foo(a) { if (!a) return undefined; a() }\", \"function foo(a) {\\n  if (!a) return void 0;\\n  a();\\n}\\n\", \"function foo(a) {\\n  a && a();\\n}\\n\")\n\n\t// These should not be transformed\n\texpectPrintedNormalAndMangle(t, \"delete undefined\", \"delete undefined;\\n\", \"delete undefined;\\n\")\n\texpectPrintedNormalAndMangle(t, \"undefined--\", \"undefined--;\\n\", \"undefined--;\\n\")\n\texpectPrintedNormalAndMangle(t, \"undefined++\", \"undefined++;\\n\", \"undefined++;\\n\")\n\texpectPrintedNormalAndMangle(t, \"--undefined\", \"--undefined;\\n\", \"--undefined;\\n\")\n\texpectPrintedNormalAndMangle(t, \"++undefined\", \"++undefined;\\n\", \"++undefined;\\n\")\n\texpectPrintedNormalAndMangle(t, \"undefined = 1\", \"undefined = 1;\\n\", \"undefined = 1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"[undefined] = 1\", \"[undefined] = 1;\\n\", \"[undefined] = 1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"({x: undefined} = 1)\", \"({ x: undefined } = 1);\\n\", \"({ x: undefined } = 1);\\n\")\n\texpectPrintedNormalAndMangle(t, \"with (x) y(undefined); z(undefined)\", \"with (x) y(undefined);\\nz(void 0);\\n\", \"with (x) y(undefined);\\nz(void 0);\\n\")\n\texpectPrintedNormalAndMangle(t, \"with (x) while (i) y(undefined); z(undefined)\", \"with (x) while (i) y(undefined);\\nz(void 0);\\n\", \"with (x) for (; i; ) y(undefined);\\nz(void 0);\\n\")\n}\n\nfunc TestMangleIndex(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"x['y']\", \"x[\\\"y\\\"];\\n\", \"x.y;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x['y z']\", \"x[\\\"y z\\\"];\\n\", \"x[\\\"y z\\\"];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x?.['y']\", \"x?.[\\\"y\\\"];\\n\", \"x?.y;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x?.['y z']\", \"x?.[\\\"y z\\\"];\\n\", \"x?.[\\\"y z\\\"];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x?.['y']()\", \"x?.[\\\"y\\\"]();\\n\", \"x?.y();\\n\")\n\texpectPrintedNormalAndMangle(t, \"x?.['y z']()\", \"x?.[\\\"y z\\\"]();\\n\", \"x?.[\\\"y z\\\"]();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x['y' + 'z']\", \"x[\\\"yz\\\"];\\n\", \"x.yz;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x?.['y' + 'z']\", \"x?.[\\\"yz\\\"];\\n\", \"x?.[\\\"yz\\\"];\\n\")\n\n\t// Check the string-to-int optimization\n\texpectPrintedNormalAndMangle(t, \"x['0']\", \"x[\\\"0\\\"];\\n\", \"x[0];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x['123']\", \"x[\\\"123\\\"];\\n\", \"x[123];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x['-123']\", \"x[\\\"-123\\\"];\\n\", \"x[-123];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x['-0']\", \"x[\\\"-0\\\"];\\n\", \"x[\\\"-0\\\"];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x['01']\", \"x[\\\"01\\\"];\\n\", \"x[\\\"01\\\"];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x['-01']\", \"x[\\\"-01\\\"];\\n\", \"x[\\\"-01\\\"];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x['0x1']\", \"x[\\\"0x1\\\"];\\n\", \"x[\\\"0x1\\\"];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x['-0x1']\", \"x[\\\"-0x1\\\"];\\n\", \"x[\\\"-0x1\\\"];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x['2147483647']\", \"x[\\\"2147483647\\\"];\\n\", \"x[2147483647];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x['2147483648']\", \"x[\\\"2147483648\\\"];\\n\", \"x[\\\"2147483648\\\"];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x['-2147483648']\", \"x[\\\"-2147483648\\\"];\\n\", \"x[-2147483648];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x['-2147483649']\", \"x[\\\"-2147483649\\\"];\\n\", \"x[\\\"-2147483649\\\"];\\n\")\n}\n\nfunc TestMangleBlock(t *testing.T) {\n\texpectPrintedMangle(t, \"while(1) { while (1) {} }\", \"for (; ; )\\n  for (; ; )\\n    ;\\n\")\n\texpectPrintedMangle(t, \"while(1) { const x = y; }\", \"for (; ; ) {\\n  const x = y;\\n}\\n\")\n\texpectPrintedMangle(t, \"while(1) { let x; }\", \"for (; ; ) {\\n  let x;\\n}\\n\")\n\texpectPrintedMangle(t, \"while(1) { var x; }\", \"for (; ; )\\n  var x;\\n\")\n\texpectPrintedMangle(t, \"while(1) { class X {} }\", \"for (; ; ) {\\n  class X {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"while(1) { function x() {} }\", \"for (; ; )\\n  var x = function() {\\n  };\\n\")\n\texpectPrintedMangle(t, \"while(1) { function* x() {} }\", \"for (; ; ) {\\n  function* x() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"while(1) { async function x() {} }\", \"for (; ; ) {\\n  async function x() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"while(1) { async function* x() {} }\", \"for (; ; ) {\\n  async function* x() {\\n  }\\n}\\n\")\n}\n\nfunc TestMangleSwitch(t *testing.T) {\n\texpectPrintedMangle(t, \"x(); switch (y) { case z: return w; }\", \"if (x(), y === z)\\n  return w;\\n\")\n\texpectPrintedMangle(t, \"if (t) { x(); switch (y) { case z: return w; } }\", \"if (t && (x(), y === z))\\n  return w;\\n\")\n\n\t// We potentially need to keep let/const declarations in dead cases\n\texpectPrintedMangle(t, \"switch (1) { case 0: x; case 1: return x }\", \"return x;\\n\")\n\texpectPrintedMangle(t, \"switch (1) { case 0: var x; case 1: return x }\", \"switch (1) {\\n  case 0:\\n    var x;\\n  case 1:\\n    return x;\\n}\\n\")\n\texpectPrintedMangle(t, \"switch (1) { case 0: let x; case 1: return x }\", \"switch (1) {\\n  case 0:\\n    let x;\\n  case 1:\\n    return x;\\n}\\n\")\n\texpectPrintedMangle(t, \"switch (1) { case 0: const x = 0; case 1: return x }\", \"switch (1) {\\n  case 0:\\n    const x = 0;\\n  case 1:\\n    return x;\\n}\\n\")\n\texpectPrintedMangle(t, \"switch (2) { case 0: var x; case 1: return x }\", \"if (0)\\n  var x;\\n\")\n\texpectPrintedMangle(t, \"switch (2) { case 0: let x; case 1: return x }\", \"\")\n\texpectPrintedMangle(t, \"switch (2) { case 0: const x = 0; case 1: return x }\", \"\")\n\n\t// https://github.com/evanw/esbuild/issues/4359\n\texpectPrintedMangle(t, \"switch (x) { case 0: a(); break; default: b() }\", \"x === 0 ? a() : b();\\n\")\n\texpectPrintedMangle(t, \"switch (x) { default: a(); break; case 0: b() }\", \"x === 0 ? b() : a();\\n\")\n\texpectPrintedMangle(t, \"switch (x) { case p: a(); break; case q: default: b() }\", \"switch (x) {\\n  case p:\\n    a();\\n    break;\\n  case q:\\n  default:\\n    b();\\n}\\n\")\n\texpectPrintedMangle(t, \"switch (x) { case 0: a(); break; case 1: case 2: default: b() }\", \"x === 0 ? a() : b();\\n\")\n\texpectPrintedMangle(t, \"switch (x) { case 0: default: a(); break; case 0: b() }\", \"switch (x) {\\n  case 0:\\n  default:\\n    a();\\n    break;\\n  case 0:\\n    b();\\n}\\n\")\n\texpectPrintedMangle(t, \"switch (x) { case 0: if (y) break; a(); break; default: b() }\",\n\t\t\"switch (x) {\\n  case 0:\\n    if (y) break;\\n    a();\\n    break;\\n  default:\\n    b();\\n}\\n\")\n\texpectPrintedMangle(t, \"switch (x) { case 0: a(); break; default: if (y) break; b() }\",\n\t\t\"switch (x) {\\n  case 0:\\n    a();\\n    break;\\n  default:\\n    if (y) break;\\n    b();\\n}\\n\")\n\n\t// https://github.com/evanw/esbuild/issues/4176\n\texpectPrintedMangle(t, \"switch (1) { case 0: case 1: case 2: x() }\", \"x();\\n\")\n\texpectPrintedMangle(t, \"switch (1) { case 0: x(); case 1: case 2: y() }\", \"y();\\n\")\n\texpectPrintedMangle(t, \"switch (1) { case 0: x(); case 1: y(); case 2: z() }\", \"y(), z();\\n\")\n\texpectPrintedMangle(t, \"switch (1) { case 0: x(); default: y(); case 2: z() }\", \"y(), z();\\n\")\n\texpectPrintedMangle(t, \"switch (1) { case 0: x(); case 1: y(); break; case 2: z() }\", \"y();\\n\")\n\texpectPrintedMangle(t, \"switch (1) { case 0: x(); default: y(); break; case 2: z() }\", \"y();\\n\")\n\texpectPrintedMangle(t, \"switch (0) { case 0: case y: x() }\", \"switch (0) {\\n  case 0:\\n  case y:\\n    x();\\n}\\n\")\n}\n\nfunc TestMangleAddEmptyString(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"a = '' + 0\", \"a = \\\"0\\\";\\n\", \"a = \\\"0\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = 0 + ''\", \"a = \\\"0\\\";\\n\", \"a = \\\"0\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = '' + b\", \"a = \\\"\\\" + b;\\n\", \"a = \\\"\\\" + b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = b + ''\", \"a = b + \\\"\\\";\\n\", \"a = b + \\\"\\\";\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = [] + 0\", \"a = \\\"0\\\";\\n\", \"a = \\\"0\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = 0 + []\", \"a = \\\"0\\\";\\n\", \"a = \\\"0\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = [] + b\", \"a = [] + b;\\n\", \"a = [] + b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = b + []\", \"a = b + [];\\n\", \"a = b + [];\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = [b] + 0\", \"a = [b] + 0;\\n\", \"a = [b] + 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = 0 + [b]\", \"a = 0 + [b];\\n\", \"a = 0 + [b];\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = [1, 2] + ''\", \"a = \\\"1,2\\\";\\n\", \"a = \\\"1,2\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = [1, 0, 2] + ''\", \"a = \\\"1,0,2\\\";\\n\", \"a = \\\"1,0,2\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = [1, null, 2] + ''\", \"a = \\\"1,,2\\\";\\n\", \"a = \\\"1,,2\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = [1, undefined, 2] + ''\", \"a = \\\"1,,2\\\";\\n\", \"a = \\\"1,,2\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = [1, true, 2] + ''\", \"a = \\\"1,true,2\\\";\\n\", \"a = \\\"1,true,2\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = [1, false, 2] + ''\", \"a = \\\"1,false,2\\\";\\n\", \"a = \\\"1,false,2\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = [1, , 2] + ''\", \"a = [1, , 2] + \\\"\\\";\\n\", \"a = [1, , 2] + \\\"\\\";\\n\") // Note: Prototype hazards\n\texpectPrintedNormalAndMangle(t, \"a = [1, , ,] + ''\", \"a = [1, , ,] + \\\"\\\";\\n\", \"a = [1, , ,] + \\\"\\\";\\n\") // Note: Prototype hazards\n\n\texpectPrintedNormalAndMangle(t, \"a = {} + 0\", \"a = \\\"[object Object]0\\\";\\n\", \"a = \\\"[object Object]0\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = 0 + {}\", \"a = \\\"0[object Object]\\\";\\n\", \"a = \\\"0[object Object]\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = {} + b\", \"a = {} + b;\\n\", \"a = {} + b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = b + {}\", \"a = b + {};\\n\", \"a = b + {};\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = {toString:()=>1} + 0\", \"a = { toString: () => 1 } + 0;\\n\", \"a = { toString: () => 1 } + 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = 0 + {toString:()=>1}\", \"a = 0 + { toString: () => 1 };\\n\", \"a = 0 + { toString: () => 1 };\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = '' + `${b}`\", \"a = `${b}`;\\n\", \"a = `${b}`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = `${b}` + ''\", \"a = `${b}`;\\n\", \"a = `${b}`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = '' + typeof b\", \"a = typeof b;\\n\", \"a = typeof b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = typeof b + ''\", \"a = typeof b;\\n\", \"a = typeof b;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = [] + `${b}`\", \"a = `${b}`;\\n\", \"a = `${b}`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = `${b}` + []\", \"a = `${b}`;\\n\", \"a = `${b}`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = [] + typeof b\", \"a = typeof b;\\n\", \"a = typeof b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = typeof b + []\", \"a = typeof b;\\n\", \"a = typeof b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = [b] + `${b}`\", \"a = [b] + `${b}`;\\n\", \"a = [b] + `${b}`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = `${b}` + [b]\", \"a = `${b}` + [b];\\n\", \"a = `${b}` + [b];\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = {} + `${b}`\", \"a = `[object Object]${b}`;\\n\", \"a = `[object Object]${b}`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = `${b}` + {}\", \"a = `${b}[object Object]`;\\n\", \"a = `${b}[object Object]`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = {} + typeof b\", \"a = {} + typeof b;\\n\", \"a = {} + typeof b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = typeof b + {}\", \"a = typeof b + {};\\n\", \"a = typeof b + {};\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = {toString:()=>1} + `${b}`\", \"a = { toString: () => 1 } + `${b}`;\\n\", \"a = { toString: () => 1 } + `${b}`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = `${b}` + {toString:()=>1}\", \"a = `${b}` + { toString: () => 1 };\\n\", \"a = `${b}` + { toString: () => 1 };\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = '' + false\", \"a = \\\"false\\\";\\n\", \"a = \\\"false\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = '' + true\", \"a = \\\"true\\\";\\n\", \"a = \\\"true\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = false + ''\", \"a = \\\"false\\\";\\n\", \"a = \\\"false\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = true + ''\", \"a = \\\"true\\\";\\n\", \"a = \\\"true\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = 1 + false + ''\", \"a = 1 + false + \\\"\\\";\\n\", \"a = 1 + false + \\\"\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = 0 + true + ''\", \"a = 0 + true + \\\"\\\";\\n\", \"a = 0 + true + \\\"\\\";\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = '' + null\", \"a = \\\"null\\\";\\n\", \"a = \\\"null\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = null + ''\", \"a = \\\"null\\\";\\n\", \"a = \\\"null\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = '' + undefined\", \"a = \\\"undefined\\\";\\n\", \"a = \\\"undefined\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = undefined + ''\", \"a = \\\"undefined\\\";\\n\", \"a = \\\"undefined\\\";\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = '' + 0n\", \"a = \\\"0\\\";\\n\", \"a = \\\"0\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = '' + 1n\", \"a = \\\"1\\\";\\n\", \"a = \\\"1\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = '' + 123n\", \"a = \\\"123\\\";\\n\", \"a = \\\"123\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = '' + 1_2_3n\", \"a = \\\"123\\\";\\n\", \"a = \\\"123\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = '' + 0b0n\", \"a = \\\"\\\" + 0b0n;\\n\", \"a = \\\"\\\" + 0b0n;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = '' + 0o0n\", \"a = \\\"\\\" + 0o0n;\\n\", \"a = \\\"\\\" + 0o0n;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = '' + 0x0n\", \"a = \\\"\\\" + 0x0n;\\n\", \"a = \\\"\\\" + 0x0n;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = '' + /a\\\\\\\\b/ig\", \"a = \\\"/a\\\\\\\\\\\\\\\\b/ig\\\";\\n\", \"a = \\\"/a\\\\\\\\\\\\\\\\b/ig\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = /a\\\\\\\\b/ig + ''\", \"a = \\\"/a\\\\\\\\\\\\\\\\b/ig\\\";\\n\", \"a = \\\"/a\\\\\\\\\\\\\\\\b/ig\\\";\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = '' + ''.constructor\", \"a = \\\"function String() { [native code] }\\\";\\n\", \"a = \\\"function String() { [native code] }\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = ''.constructor + ''\", \"a = \\\"function String() { [native code] }\\\";\\n\", \"a = \\\"function String() { [native code] }\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = '' + /./.constructor\", \"a = \\\"function RegExp() { [native code] }\\\";\\n\", \"a = \\\"function RegExp() { [native code] }\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = /./.constructor + ''\", \"a = \\\"function RegExp() { [native code] }\\\";\\n\", \"a = \\\"function RegExp() { [native code] }\\\";\\n\")\n}\n\nfunc TestMangleStringLength(t *testing.T) {\n\texpectPrinted(t, \"a = ''.length\", \"a = \\\"\\\".length;\\n\")\n\texpectPrintedMangle(t, \"''.length++\", \"\\\"\\\".length++;\\n\")\n\texpectPrintedMangle(t, \"''.length = a\", \"\\\"\\\".length = a;\\n\")\n\n\texpectPrintedMangle(t, \"a = ''.len\", \"a = \\\"\\\".len;\\n\")\n\texpectPrintedMangle(t, \"a = [].length\", \"a = [].length;\\n\")\n\texpectPrintedMangle(t, \"a = ''.length\", \"a = 0;\\n\")\n\texpectPrintedMangle(t, \"a = ``.length\", \"a = 0;\\n\")\n\texpectPrintedMangle(t, \"a = b``.length\", \"a = b``.length;\\n\")\n\texpectPrintedMangle(t, \"a = 'abc'.length\", \"a = 3;\\n\")\n\texpectPrintedMangle(t, \"a = 'ȧḃċ'.length\", \"a = 3;\\n\")\n\texpectPrintedMangle(t, \"a = '👯‍♂️'.length\", \"a = 5;\\n\")\n}\n\nfunc TestMangleStringIndex(t *testing.T) {\n\texpectPrinted(t, \"a = 'abc'[0]\", \"a = \\\"abc\\\"[0];\\n\")\n\texpectPrintedMangle(t, \"a = 'abc'[-1]\", \"a = \\\"abc\\\"[-1];\\n\")\n\texpectPrintedMangle(t, \"a = 'abc'[-0]\", \"a = \\\"a\\\";\\n\")\n\texpectPrintedMangle(t, \"a = 'abc'[0]\", \"a = \\\"a\\\";\\n\")\n\texpectPrintedMangle(t, \"a = 'abc'[2]\", \"a = \\\"c\\\";\\n\")\n\texpectPrintedMangle(t, \"a = 'abc'[3]\", \"a = \\\"abc\\\"[3];\\n\")\n\texpectPrintedMangle(t, \"a = 'abc'[NaN]\", \"a = \\\"abc\\\"[NaN];\\n\")\n\texpectPrintedMangle(t, \"a = 'abc'[-1e100]\", \"a = \\\"abc\\\"[-1e100];\\n\")\n\texpectPrintedMangle(t, \"a = 'abc'[1e100]\", \"a = \\\"abc\\\"[1e100];\\n\")\n\texpectPrintedMangle(t, \"a = 'abc'[-Infinity]\", \"a = \\\"abc\\\"[-Infinity];\\n\")\n\texpectPrintedMangle(t, \"a = 'abc'[Infinity]\", \"a = \\\"abc\\\"[Infinity];\\n\")\n}\n\nfunc TestMangleNot(t *testing.T) {\n\t// These can be mangled\n\texpectPrintedNormalAndMangle(t, \"a = !(b == c)\", \"a = !(b == c);\\n\", \"a = b != c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !(b != c)\", \"a = !(b != c);\\n\", \"a = b == c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !(b === c)\", \"a = !(b === c);\\n\", \"a = b !== c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !(b !== c)\", \"a = !(b !== c);\\n\", \"a = b === c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!(a, b)) return c\", \"if (!(a, b)) return c;\\n\", \"if (a, !b) return c;\\n\")\n\n\t// These can't be mangled due to NaN and other special cases\n\texpectPrintedNormalAndMangle(t, \"a = !(b < c)\", \"a = !(b < c);\\n\", \"a = !(b < c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !(b > c)\", \"a = !(b > c);\\n\", \"a = !(b > c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !(b <= c)\", \"a = !(b <= c);\\n\", \"a = !(b <= c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !(b >= c)\", \"a = !(b >= c);\\n\", \"a = !(b >= c);\\n\")\n}\n\nfunc TestMangleDoubleNot(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"a = !!b\", \"a = !!b;\\n\", \"a = !!b;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = !!!b\", \"a = !!!b;\\n\", \"a = !b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!-b\", \"a = !!-b;\\n\", \"a = !!-b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!void b\", \"a = !!void b;\\n\", \"a = !!void b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!delete b\", \"a = !!delete b;\\n\", \"a = delete b;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = !!(b + c)\", \"a = !!(b + c);\\n\", \"a = !!(b + c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(b == c)\", \"a = !!(b == c);\\n\", \"a = b == c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(b != c)\", \"a = !!(b != c);\\n\", \"a = b != c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(b === c)\", \"a = !!(b === c);\\n\", \"a = b === c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(b !== c)\", \"a = !!(b !== c);\\n\", \"a = b !== c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(b < c)\", \"a = !!(b < c);\\n\", \"a = b < c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(b > c)\", \"a = !!(b > c);\\n\", \"a = b > c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(b <= c)\", \"a = !!(b <= c);\\n\", \"a = b <= c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(b >= c)\", \"a = !!(b >= c);\\n\", \"a = b >= c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(b in c)\", \"a = !!(b in c);\\n\", \"a = b in c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(b instanceof c)\", \"a = !!(b instanceof c);\\n\", \"a = b instanceof c;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = !!(b && c)\", \"a = !!(b && c);\\n\", \"a = !!(b && c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(b || c)\", \"a = !!(b || c);\\n\", \"a = !!(b || c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(b ?? c)\", \"a = !!(b ?? c);\\n\", \"a = !!(b ?? c);\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = !!(!b && c)\", \"a = !!(!b && c);\\n\", \"a = !!(!b && c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(!b || c)\", \"a = !!(!b || c);\\n\", \"a = !!(!b || c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(!b ?? c)\", \"a = !!!b;\\n\", \"a = !b;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = !!(b && !c)\", \"a = !!(b && !c);\\n\", \"a = !!(b && !c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(b || !c)\", \"a = !!(b || !c);\\n\", \"a = !!(b || !c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(b ?? !c)\", \"a = !!(b ?? !c);\\n\", \"a = !!(b ?? !c);\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = !!(!b && !c)\", \"a = !!(!b && !c);\\n\", \"a = !b && !c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(!b || !c)\", \"a = !!(!b || !c);\\n\", \"a = !b || !c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !!(!b ?? !c)\", \"a = !!!b;\\n\", \"a = !b;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = !!(b, c)\", \"a = !!(b, c);\\n\", \"a = (b, !!c);\\n\")\n}\n\nfunc TestMangleBooleanConstructor(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"a = Boolean(b); var Boolean\", \"a = Boolean(b);\\nvar Boolean;\\n\", \"a = Boolean(b);\\nvar Boolean;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = Boolean()\", \"a = Boolean();\\n\", \"a = false;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Boolean(b)\", \"a = Boolean(b);\\n\", \"a = !!b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Boolean(!b)\", \"a = Boolean(!b);\\n\", \"a = !b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Boolean(!!b)\", \"a = Boolean(!!b);\\n\", \"a = !!b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Boolean(b ? true : false)\", \"a = Boolean(b ? true : false);\\n\", \"a = !!b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Boolean(b ? false : true)\", \"a = Boolean(b ? false : true);\\n\", \"a = !b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Boolean(b ? c > 0 : c < 0)\", \"a = Boolean(b ? c > 0 : c < 0);\\n\", \"a = b ? c > 0 : c < 0;\\n\")\n\n\t// Check for calling \"SimplifyBooleanExpr\" on the argument\n\texpectPrintedNormalAndMangle(t, \"a = Boolean((b | c) !== 0)\", \"a = Boolean((b | c) !== 0);\\n\", \"a = (b | c) !== 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Boolean((b >>> c) !== 0)\", \"a = Boolean(b >>> c !== 0);\\n\", \"a = !!(b >>> c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Boolean(b ? (c | d) !== 0 : (d | e) !== 0)\",\n\t\t\"a = Boolean(b ? (c | d) !== 0 : (d | e) !== 0);\\n\", \"a = b ? (c | d) !== 0 : (d | e) !== 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Boolean(b ? (c >>> d) !== 0 : (d >>> e) !== 0)\",\n\t\t\"a = Boolean(b ? c >>> d !== 0 : d >>> e !== 0);\\n\", \"a = !!(b ? c >>> d : d >>> e);\\n\")\n}\n\nfunc TestMangleNumberConstructor(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"a = Number(x)\", \"a = Number(x);\\n\", \"a = Number(x);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Number(0n)\", \"a = Number(0n);\\n\", \"a = Number(0n);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Number(false); var Number\", \"a = Number(false);\\nvar Number;\\n\", \"a = Number(false);\\nvar Number;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Number(0xFFFF_FFFF_FFFF_FFFFn)\", \"a = Number(0xFFFFFFFFFFFFFFFFn);\\n\", \"a = Number(0xFFFFFFFFFFFFFFFFn);\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = Number()\", \"a = Number();\\n\", \"a = 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Number(-123)\", \"a = Number(-123);\\n\", \"a = -123;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Number(false)\", \"a = Number(false);\\n\", \"a = 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Number(true)\", \"a = Number(true);\\n\", \"a = 1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Number(undefined)\", \"a = Number(void 0);\\n\", \"a = NaN;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Number(null)\", \"a = Number(null);\\n\", \"a = 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = Number(b ? !c : !d)\", \"a = Number(b ? !c : !d);\\n\", \"a = +(b ? !c : !d);\\n\")\n}\n\nfunc TestMangleStringConstructor(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"a = String(x)\", \"a = String(x);\\n\", \"a = String(x);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = String('x'); var String\", \"a = String(\\\"x\\\");\\nvar String;\\n\", \"a = String(\\\"x\\\");\\nvar String;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = String()\", \"a = String();\\n\", \"a = \\\"\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = String('x')\", \"a = String(\\\"x\\\");\\n\", \"a = \\\"x\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = String(b ? 'x' : 'y')\", \"a = String(b ? \\\"x\\\" : \\\"y\\\");\\n\", \"a = b ? \\\"x\\\" : \\\"y\\\";\\n\")\n}\n\nfunc TestMangleBigIntConstructor(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"a = BigInt(x)\", \"a = BigInt(x);\\n\", \"a = BigInt(x);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = BigInt(0n); var BigInt\", \"a = BigInt(0n);\\nvar BigInt;\\n\", \"a = BigInt(0n);\\nvar BigInt;\\n\")\n\n\t// Note: This throws instead of returning \"0n\"\n\texpectPrintedNormalAndMangle(t, \"a = BigInt()\", \"a = BigInt();\\n\", \"a = BigInt();\\n\")\n\n\t// Note: Transforming this into \"0n\" is unsafe because that syntax may not be supported\n\texpectPrintedNormalAndMangle(t, \"a = BigInt('0')\", \"a = BigInt(\\\"0\\\");\\n\", \"a = BigInt(\\\"0\\\");\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = BigInt(0n)\", \"a = BigInt(0n);\\n\", \"a = 0n;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = BigInt(b ? 0n : 1n)\", \"a = BigInt(b ? 0n : 1n);\\n\", \"a = b ? 0n : 1n;\\n\")\n}\n\nfunc TestMangleCharCodeAt(t *testing.T) {\n\texpectPrinted(t, \"a = 'xy'.charCodeAt(0)\", \"a = \\\"xy\\\".charCodeAt(0);\\n\")\n\n\texpectPrintedMangle(t, \"a = 'xy'.charCodeAt()\", \"a = 120;\\n\")\n\texpectPrintedMangle(t, \"a = 'xy'.charCodeAt(0)\", \"a = 120;\\n\")\n\texpectPrintedMangle(t, \"a = 'xy'.charCodeAt(1)\", \"a = 121;\\n\")\n\texpectPrintedMangle(t, \"a = 'xy'.charCodeAt(-1)\", \"a = NaN;\\n\")\n\texpectPrintedMangle(t, \"a = 'xy'.charCodeAt(2)\", \"a = NaN;\\n\")\n\n\texpectPrintedMangle(t, \"a = '🧀'.charCodeAt()\", \"a = 55358;\\n\")\n\texpectPrintedMangle(t, \"a = '🧀'.charCodeAt(0)\", \"a = 55358;\\n\")\n\texpectPrintedMangle(t, \"a = '🧀'.charCodeAt(1)\", \"a = 56768;\\n\")\n\texpectPrintedMangle(t, \"a = '🧀'.charCodeAt(-1)\", \"a = NaN;\\n\")\n\texpectPrintedMangle(t, \"a = '🧀'.charCodeAt(2)\", \"a = NaN;\\n\")\n\n\texpectPrintedMangle(t, \"a = 'xy'.charCodeAt(NaN)\", \"a = \\\"xy\\\".charCodeAt(NaN);\\n\")\n\texpectPrintedMangle(t, \"a = 'xy'.charCodeAt(-Infinity)\", \"a = \\\"xy\\\".charCodeAt(-Infinity);\\n\")\n\texpectPrintedMangle(t, \"a = 'xy'.charCodeAt(Infinity)\", \"a = \\\"xy\\\".charCodeAt(Infinity);\\n\")\n\texpectPrintedMangle(t, \"a = 'xy'.charCodeAt(0.5)\", \"a = \\\"xy\\\".charCodeAt(0.5);\\n\")\n\texpectPrintedMangle(t, \"a = 'xy'.charCodeAt(1e99)\", \"a = \\\"xy\\\".charCodeAt(1e99);\\n\")\n\texpectPrintedMangle(t, \"a = 'xy'.charCodeAt('1')\", \"a = \\\"xy\\\".charCodeAt(\\\"1\\\");\\n\")\n\texpectPrintedMangle(t, \"a = 'xy'.charCodeAt(1, 2)\", \"a = \\\"xy\\\".charCodeAt(1, 2);\\n\")\n}\n\nfunc TestMangleFromCharCode(t *testing.T) {\n\texpectPrinted(t, \"a = String.fromCharCode(120, 121)\", \"a = String.fromCharCode(120, 121);\\n\")\n\n\texpectPrintedMangle(t, \"a = String.fromCharCode()\", \"a = \\\"\\\";\\n\")\n\texpectPrintedMangle(t, \"a = String.fromCharCode(0)\", \"a = \\\"\\\\0\\\";\\n\")\n\texpectPrintedMangle(t, \"a = String.fromCharCode(120)\", \"a = \\\"x\\\";\\n\")\n\texpectPrintedMangle(t, \"a = String.fromCharCode(120, 121)\", \"a = \\\"xy\\\";\\n\")\n\texpectPrintedMangle(t, \"a = String.fromCharCode(55358, 56768)\", \"a = \\\"🧀\\\";\\n\")\n\texpectPrintedMangle(t, \"a = String.fromCharCode(0x10000)\", \"a = \\\"\\\\0\\\";\\n\")\n\texpectPrintedMangle(t, \"a = String.fromCharCode(0x10078, 0x10079)\", \"a = \\\"xy\\\";\\n\")\n\texpectPrintedMangle(t, \"a = String.fromCharCode(0x1_0000_FFFF)\", \"a = \\\"\\uFFFF\\\";\\n\")\n\texpectPrintedMangle(t, \"a = String.fromCharCode(NaN)\", \"a = \\\"\\\\0\\\";\\n\")\n\texpectPrintedMangle(t, \"a = String.fromCharCode(-Infinity)\", \"a = \\\"\\\\0\\\";\\n\")\n\texpectPrintedMangle(t, \"a = String.fromCharCode(Infinity)\", \"a = \\\"\\\\0\\\";\\n\")\n\texpectPrintedMangle(t, \"a = String.fromCharCode(null)\", \"a = \\\"\\\\0\\\";\\n\")\n\texpectPrintedMangle(t, \"a = String.fromCharCode(undefined)\", \"a = \\\"\\\\0\\\";\\n\")\n\texpectPrintedMangle(t, \"a = String.fromCharCode('123')\", \"a = \\\"{\\\";\\n\")\n\n\texpectPrintedMangle(t, \"a = String.fromCharCode(x)\", \"a = String.fromCharCode(x);\\n\")\n\texpectPrintedMangle(t, \"a = String.fromCharCode('x')\", \"a = String.fromCharCode(\\\"x\\\");\\n\")\n\texpectPrintedMangle(t, \"a = String.fromCharCode('0.5')\", \"a = String.fromCharCode(\\\"0.5\\\");\\n\")\n}\n\nfunc TestMangleToString(t *testing.T) {\n\texpectPrinted(t, \"a = \\\"xy\\\".toString()\", \"a = \\\"xy\\\".toString();\\n\")\n\n\texpectPrintedMangle(t, \"a = false.toString()\", \"a = \\\"false\\\";\\n\")\n\texpectPrintedMangle(t, \"a = true.toString()\", \"a = \\\"true\\\";\\n\")\n\texpectPrintedMangle(t, \"a = \\\"xy\\\".toString()\", \"a = \\\"xy\\\";\\n\")\n\texpectPrintedMangle(t, \"a = 0 .toString()\", \"a = \\\"0\\\";\\n\")\n\texpectPrintedMangle(t, \"a = (-0).toString()\", \"a = \\\"0\\\";\\n\")\n\texpectPrintedMangle(t, \"a = 123 .toString()\", \"a = \\\"123\\\";\\n\")\n\texpectPrintedMangle(t, \"a = (-123).toString()\", \"a = \\\"-123\\\";\\n\")\n\texpectPrintedMangle(t, \"a = NaN.toString()\", \"a = \\\"NaN\\\";\\n\")\n\texpectPrintedMangle(t, \"a = Infinity.toString()\", \"a = \\\"Infinity\\\";\\n\")\n\texpectPrintedMangle(t, \"a = (-Infinity).toString()\", \"a = \\\"-Infinity\\\";\\n\")\n\texpectPrintedMangle(t, \"a = /a\\\\\\\\b/ig.toString()\", \"a = \\\"/a\\\\\\\\\\\\\\\\b/ig\\\";\\n\")\n\n\t// Handle a radix other than 10\n\texpectPrintedMangle(t, \"a = 100 .toString(0)\", \"a = 100 .toString(0);\\n\")\n\texpectPrintedMangle(t, \"a = 100 .toString(1)\", \"a = 100 .toString(1);\\n\")\n\texpectPrintedMangle(t, \"a = 100 .toString(2)\", \"a = \\\"1100100\\\";\\n\")\n\texpectPrintedMangle(t, \"a = 100 .toString(5)\", \"a = \\\"400\\\";\\n\")\n\texpectPrintedMangle(t, \"a = 100 .toString(8)\", \"a = \\\"144\\\";\\n\")\n\texpectPrintedMangle(t, \"a = 100 .toString(13)\", \"a = \\\"79\\\";\\n\")\n\texpectPrintedMangle(t, \"a = 100 .toString(16)\", \"a = \\\"64\\\";\\n\")\n\texpectPrintedMangle(t, \"a = 10000 .toString(19)\", \"a = \\\"18d6\\\";\\n\")\n\texpectPrintedMangle(t, \"a = 10000 .toString(23)\", \"a = \\\"iki\\\";\\n\")\n\texpectPrintedMangle(t, \"a = 1000000 .toString(29)\", \"a = \\\"1c01m\\\";\\n\")\n\texpectPrintedMangle(t, \"a = 1000000 .toString(31)\", \"a = \\\"12hi2\\\";\\n\")\n\texpectPrintedMangle(t, \"a = 1000000 .toString(36)\", \"a = \\\"lfls\\\";\\n\")\n\texpectPrintedMangle(t, \"a = (-1000000).toString(36)\", \"a = \\\"-lfls\\\";\\n\")\n\texpectPrintedMangle(t, \"a = 0 .toString(36)\", \"a = \\\"0\\\";\\n\")\n\texpectPrintedMangle(t, \"a = (-0).toString(36)\", \"a = \\\"0\\\";\\n\")\n\n\texpectPrintedMangle(t, \"a = false.toString(b)\", \"a = false.toString(b);\\n\")\n\texpectPrintedMangle(t, \"a = true.toString(b)\", \"a = true.toString(b);\\n\")\n\texpectPrintedMangle(t, \"a = \\\"xy\\\".toString(b)\", \"a = \\\"xy\\\".toString(b);\\n\")\n\texpectPrintedMangle(t, \"a = 123 .toString(b)\", \"a = 123 .toString(b);\\n\")\n\texpectPrintedMangle(t, \"a = 0.5.toString()\", \"a = 0.5.toString();\\n\")\n\texpectPrintedMangle(t, \"a = 1e99.toString(b)\", \"a = 1e99.toString(b);\\n\")\n\texpectPrintedMangle(t, \"a = /./.toString(b)\", \"a = /./.toString(b);\\n\")\n}\n\nfunc TestMangleIf(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"1 ? a() : b()\", \"1 ? a() : b();\\n\", \"a();\\n\")\n\texpectPrintedNormalAndMangle(t, \"0 ? a() : b()\", \"0 ? a() : b();\\n\", \"b();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a ? a : b\", \"a ? a : b;\\n\", \"a || b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b : a\", \"a ? b : a;\\n\", \"a && b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a.x ? a.x : b\", \"a.x ? a.x : b;\\n\", \"a.x ? a.x : b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a.x ? b : a.x\", \"a.x ? b : a.x;\\n\", \"a.x ? b : a.x;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a ? b() : c()\", \"a ? b() : c();\\n\", \"a ? b() : c();\\n\")\n\texpectPrintedNormalAndMangle(t, \"!a ? b() : c()\", \"!a ? b() : c();\\n\", \"a ? c() : b();\\n\")\n\texpectPrintedNormalAndMangle(t, \"!!a ? b() : c()\", \"!!a ? b() : c();\\n\", \"a ? b() : c();\\n\")\n\texpectPrintedNormalAndMangle(t, \"!!!a ? b() : c()\", \"!!!a ? b() : c();\\n\", \"a ? c() : b();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"if (1) a(); else b()\", \"if (1) a();\\nelse b();\\n\", \"a();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0) a(); else b()\", \"if (0) a();\\nelse b();\\n\", \"b();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (a) b(); else c()\", \"if (a) b();\\nelse c();\\n\", \"a ? b() : c();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!a) b(); else c()\", \"if (!a) b();\\nelse c();\\n\", \"a ? c() : b();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!!a) b(); else c()\", \"if (!!a) b();\\nelse c();\\n\", \"a ? b() : c();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!!!a) b(); else c()\", \"if (!!!a) b();\\nelse c();\\n\", \"a ? c() : b();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"if (1) a()\", \"if (1) a();\\n\", \"a();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0) a()\", \"if (0) a();\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"if (a) b()\", \"if (a) b();\\n\", \"a && b();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!a) b()\", \"if (!a) b();\\n\", \"a || b();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!!a) b()\", \"if (!!a) b();\\n\", \"a && b();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!!!a) b()\", \"if (!!!a) b();\\n\", \"a || b();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"if (1) {} else a()\", \"if (1) {\\n} else a();\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"if (0) {} else a()\", \"if (0) {\\n} else a();\\n\", \"a();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (a) {} else b()\", \"if (a) {\\n} else b();\\n\", \"a || b();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!a) {} else b()\", \"if (!a) {\\n} else b();\\n\", \"a && b();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!!a) {} else b()\", \"if (!!a) {\\n} else b();\\n\", \"a || b();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!!!a) {} else b()\", \"if (!!!a) {\\n} else b();\\n\", \"a && b();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"if (a) {} else throw b\", \"if (a) {\\n} else throw b;\\n\", \"if (!a)\\n  throw b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!a) {} else throw b\", \"if (!a) {\\n} else throw b;\\n\", \"if (a)\\n  throw b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a(); if (b) throw c\", \"a();\\nif (b) throw c;\\n\", \"if (a(), b) throw c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (a) if (b) throw c\", \"if (a) {\\n  if (b) throw c;\\n}\\n\", \"if (a && b) throw c;\\n\")\n\n\texpectPrintedMangle(t, \"if (true) { let a = b; if (c) throw d }\",\n\t\t\"{\\n  let a = b;\\n  if (c) throw d;\\n}\\n\")\n\texpectPrintedMangle(t, \"if (true) { if (a) throw b; if (c) throw d }\",\n\t\t\"if (a) throw b;\\nif (c) throw d;\\n\")\n\n\texpectPrintedMangle(t, \"if (false) throw a; else { let b = c; if (d) throw e }\",\n\t\t\"{\\n  let b = c;\\n  if (d) throw e;\\n}\\n\")\n\texpectPrintedMangle(t, \"if (false) throw a; else { if (b) throw c; if (d) throw e }\",\n\t\t\"if (b) throw c;\\nif (d) throw e;\\n\")\n\n\texpectPrintedMangle(t, \"if (a) { if (b) throw c; else { let d = e; if (f) throw g } }\",\n\t\t\"if (a) {\\n  if (b) throw c;\\n  {\\n    let d = e;\\n    if (f) throw g;\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"if (a) { if (b) throw c; else if (d) throw e; else if (f) throw g }\",\n\t\t\"if (a) {\\n  if (b) throw c;\\n  if (d) throw e;\\n  if (f) throw g;\\n}\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = b ? true : false\", \"a = b ? true : false;\\n\", \"a = !!b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = b ? false : true\", \"a = b ? false : true;\\n\", \"a = !b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !b ? true : false\", \"a = !b ? true : false;\\n\", \"a = !b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = !b ? false : true\", \"a = !b ? false : true;\\n\", \"a = !!b;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = b == c ? true : false\", \"a = b == c ? true : false;\\n\", \"a = b == c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = b != c ? true : false\", \"a = b != c ? true : false;\\n\", \"a = b != c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = b === c ? true : false\", \"a = b === c ? true : false;\\n\", \"a = b === c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = b !== c ? true : false\", \"a = b !== c ? true : false;\\n\", \"a = b !== c;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a ? b(c) : b(d)\", \"a ? b(c) : b(d);\\n\", \"a ? b(c) : b(d);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a; a ? b(c) : b(d)\", \"let a;\\na ? b(c) : b(d);\\n\", \"let a;\\na ? b(c) : b(d);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b; a ? b(c) : b(d)\", \"let a, b;\\na ? b(c) : b(d);\\n\", \"let a, b;\\nb(a ? c : d);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b; a ? b(c, 0) : b(d)\", \"let a, b;\\na ? b(c, 0) : b(d);\\n\", \"let a, b;\\na ? b(c, 0) : b(d);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b; a ? b(c) : b(d, 0)\", \"let a, b;\\na ? b(c) : b(d, 0);\\n\", \"let a, b;\\na ? b(c) : b(d, 0);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b; a ? b(c, 0) : b(d, 1)\", \"let a, b;\\na ? b(c, 0) : b(d, 1);\\n\", \"let a, b;\\na ? b(c, 0) : b(d, 1);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b; a ? b(c, 0) : b(d, 0)\", \"let a, b;\\na ? b(c, 0) : b(d, 0);\\n\", \"let a, b;\\nb(a ? c : d, 0);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b; a ? b(...c) : b(d)\", \"let a, b;\\na ? b(...c) : b(d);\\n\", \"let a, b;\\na ? b(...c) : b(d);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b; a ? b(c) : b(...d)\", \"let a, b;\\na ? b(c) : b(...d);\\n\", \"let a, b;\\na ? b(c) : b(...d);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b; a ? b(...c) : b(...d)\", \"let a, b;\\na ? b(...c) : b(...d);\\n\", \"let a, b;\\nb(...a ? c : d);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b; a ? b(a) : b(c)\", \"let a, b;\\na ? b(a) : b(c);\\n\", \"let a, b;\\nb(a || c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b; a ? b(c) : b(a)\", \"let a, b;\\na ? b(c) : b(a);\\n\", \"let a, b;\\nb(a && c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b; a ? b(...a) : b(...c)\", \"let a, b;\\na ? b(...a) : b(...c);\\n\", \"let a, b;\\nb(...a || c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b; a ? b(...c) : b(...a)\", \"let a, b;\\na ? b(...c) : b(...a);\\n\", \"let a, b;\\nb(...a && c);\\n\")\n\n\t// Note: \"a.x\" may change \"b\" and \"b.y\" may change \"a\" in the examples\n\t// below, so the presence of these expressions must prevent reordering\n\texpectPrintedNormalAndMangle(t, \"let a; a.x ? b(c) : b(d)\", \"let a;\\na.x ? b(c) : b(d);\\n\", \"let a;\\na.x ? b(c) : b(d);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b; a.x ? b(c) : b(d)\", \"let a, b;\\na.x ? b(c) : b(d);\\n\", \"let a, b;\\na.x ? b(c) : b(d);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b; a ? b.y(c) : b.y(d)\", \"let a, b;\\na ? b.y(c) : b.y(d);\\n\", \"let a, b;\\na ? b.y(c) : b.y(d);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b; a.x ? b.y(c) : b.y(d)\", \"let a, b;\\na.x ? b.y(c) : b.y(d);\\n\", \"let a, b;\\na.x ? b.y(c) : b.y(d);\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a ? b : c ? b : d\", \"a ? b : c ? b : d;\\n\", \"a || c ? b : d;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b ? c : d : d\", \"a ? b ? c : d : d;\\n\", \"a && b ? c : d;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a ? c : (b, c)\", \"a ? c : (b, c);\\n\", \"a || b, c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? (b, c) : c\", \"a ? (b, c) : c;\\n\", \"a && b, c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? c : (b, d)\", \"a ? c : (b, d);\\n\", \"a ? c : (b, d);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? (b, c) : d\", \"a ? (b, c) : d;\\n\", \"a ? (b, c) : d;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a ? b || c : c\", \"a ? b || c : c;\\n\", \"a && b || c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b || c : d\", \"a ? b || c : d;\\n\", \"a ? b || c : d;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b && c : c\", \"a ? b && c : c;\\n\", \"a ? b && c : c;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a ? c : b && c\", \"a ? c : b && c;\\n\", \"(a || b) && c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? c : b && d\", \"a ? c : b && d;\\n\", \"a ? c : b && d;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? c : b || c\", \"a ? c : b || c;\\n\", \"a ? c : b || c;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a = b == null ? c : b\", \"a = b == null ? c : b;\\n\", \"a = b == null ? c : b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a = b != null ? b : c\", \"a = b != null ? b : c;\\n\", \"a = b != null ? b : c;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"let b; a = b == null ? c : b\", \"let b;\\na = b == null ? c : b;\\n\", \"let b;\\na = b ?? c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let b; a = b != null ? b : c\", \"let b;\\na = b != null ? b : c;\\n\", \"let b;\\na = b ?? c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let b; a = b == null ? b : c\", \"let b;\\na = b == null ? b : c;\\n\", \"let b;\\na = b == null ? b : c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let b; a = b != null ? c : b\", \"let b;\\na = b != null ? c : b;\\n\", \"let b;\\na = b != null ? c : b;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"let b; a = null == b ? c : b\", \"let b;\\na = null == b ? c : b;\\n\", \"let b;\\na = b ?? c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let b; a = null != b ? b : c\", \"let b;\\na = null != b ? b : c;\\n\", \"let b;\\na = b ?? c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let b; a = null == b ? b : c\", \"let b;\\na = null == b ? b : c;\\n\", \"let b;\\na = b == null ? b : c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let b; a = null != b ? c : b\", \"let b;\\na = null != b ? c : b;\\n\", \"let b;\\na = b != null ? c : b;\\n\")\n\n\t// Don't do this if the condition has side effects\n\texpectPrintedNormalAndMangle(t, \"let b; a = b.x == null ? c : b.x\", \"let b;\\na = b.x == null ? c : b.x;\\n\", \"let b;\\na = b.x == null ? c : b.x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let b; a = b.x != null ? b.x : c\", \"let b;\\na = b.x != null ? b.x : c;\\n\", \"let b;\\na = b.x != null ? b.x : c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let b; a = null == b.x ? c : b.x\", \"let b;\\na = null == b.x ? c : b.x;\\n\", \"let b;\\na = b.x == null ? c : b.x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let b; a = null != b.x ? b.x : c\", \"let b;\\na = null != b.x ? b.x : c;\\n\", \"let b;\\na = b.x != null ? b.x : c;\\n\")\n\n\t// Don't do this for strict equality comparisons\n\texpectPrintedNormalAndMangle(t, \"let b; a = b === null ? c : b\", \"let b;\\na = b === null ? c : b;\\n\", \"let b;\\na = b === null ? c : b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let b; a = b !== null ? b : c\", \"let b;\\na = b !== null ? b : c;\\n\", \"let b;\\na = b !== null ? b : c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let b; a = null === b ? c : b\", \"let b;\\na = null === b ? c : b;\\n\", \"let b;\\na = b === null ? c : b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let b; a = null !== b ? b : c\", \"let b;\\na = null !== b ? b : c;\\n\", \"let b;\\na = b !== null ? b : c;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"let b; a = null === b || b === undefined ? c : b\", \"let b;\\na = null === b || b === void 0 ? c : b;\\n\", \"let b;\\na = b ?? c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let b; a = b !== undefined && b !== null ? b : c\", \"let b;\\na = b !== void 0 && b !== null ? b : c;\\n\", \"let b;\\na = b ?? c;\\n\")\n\n\t// Distinguish between negative an non-negative zero (i.e. Object.is)\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness\n\texpectPrintedNormalAndMangle(t, \"a(b ? 0 : 0)\", \"a(b ? 0 : 0);\\n\", \"a((b, 0));\\n\")\n\texpectPrintedNormalAndMangle(t, \"a(b ? +0 : -0)\", \"a(b ? 0 : -0);\\n\", \"a(b ? 0 : -0);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a(b ? +0 : 0)\", \"a(b ? 0 : 0);\\n\", \"a((b, 0));\\n\")\n\texpectPrintedNormalAndMangle(t, \"a(b ? -0 : 0)\", \"a(b ? -0 : 0);\\n\", \"a(b ? -0 : 0);\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a ? b : b\", \"a ? b : b;\\n\", \"a, b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a; a ? b : b\", \"let a;\\na ? b : b;\\n\", \"let a;\\nb;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a ? -b : -b\", \"a ? -b : -b;\\n\", \"a, -b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b.c : b.c\", \"a ? b.c : b.c;\\n\", \"a, b.c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b?.c : b?.c\", \"a ? b?.c : b?.c;\\n\", \"a, b?.c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b[c] : b[c]\", \"a ? b[c] : b[c];\\n\", \"a, b[c];\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b() : b()\", \"a ? b() : b();\\n\", \"a, b();\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b?.() : b?.()\", \"a ? b?.() : b?.();\\n\", \"a, b?.();\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b?.[c] : b?.[c]\", \"a ? b?.[c] : b?.[c];\\n\", \"a, b?.[c];\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b == c : b == c\", \"a ? b == c : b == c;\\n\", \"a, b == c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b.c(d + e[f]) : b.c(d + e[f])\", \"a ? b.c(d + e[f]) : b.c(d + e[f]);\\n\", \"a, b.c(d + e[f]);\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a ? -b : !b\", \"a ? -b : !b;\\n\", \"a ? -b : b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b() : b(c)\", \"a ? b() : b(c);\\n\", \"a ? b() : b(c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b(c) : b(d)\", \"a ? b(c) : b(d);\\n\", \"a ? b(c) : b(d);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b?.c : b.c\", \"a ? b?.c : b.c;\\n\", \"a ? b?.c : b.c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b?.() : b()\", \"a ? b?.() : b();\\n\", \"a ? b?.() : b();\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b?.[c] : b[c]\", \"a ? b?.[c] : b[c];\\n\", \"a ? b?.[c] : b[c];\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b == c : b != c\", \"a ? b == c : b != c;\\n\", \"a ? b == c : b != c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ? b.c(d + e[f]) : b.c(d + e[g])\", \"a ? b.c(d + e[f]) : b.c(d + e[g]);\\n\", \"a ? b.c(d + e[f]) : b.c(d + e[g]);\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"(a, b) ? c : d\", \"(a, b) ? c : d;\\n\", \"a, b ? c : d;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"return a && ((b && c) && (d && e))\", \"return a && (b && c && (d && e));\\n\", \"return a && b && c && d && e;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a || ((b || c) || (d || e))\", \"return a || (b || c || (d || e));\\n\", \"return a || b || c || d || e;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a ?? ((b ?? c) ?? (d ?? e))\", \"return a ?? (b ?? c ?? (d ?? e));\\n\", \"return a ?? b ?? c ?? d ?? e;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (a) if (b) if (c) d\", \"if (a) {\\n  if (b) {\\n    if (c) d;\\n  }\\n}\\n\", \"a && b && c && d;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!a) if (!b) if (!c) d\", \"if (!a) {\\n  if (!b) {\\n    if (!c) d;\\n  }\\n}\\n\", \"a || b || c || d;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a, b, c; return a != null ? a : b != null ? b : c\", \"let a, b, c;\\nreturn a != null ? a : b != null ? b : c;\\n\", \"let a, b, c;\\nreturn a ?? b ?? c;\\n\")\n\n\texpectPrintedMangle(t, \"if (a) return c; if (b) return d;\", \"if (a) return c;\\nif (b) return d;\\n\")\n\texpectPrintedMangle(t, \"if (a) return c; if (b) return c;\", \"if (a || b) return c;\\n\")\n\texpectPrintedMangle(t, \"if (a) return c; if (b) return;\", \"if (a) return c;\\nif (b) return;\\n\")\n\texpectPrintedMangle(t, \"if (a) return; if (b) return c;\", \"if (a) return;\\nif (b) return c;\\n\")\n\texpectPrintedMangle(t, \"if (a) return; if (b) return;\", \"if (a || b) return;\\n\")\n\texpectPrintedMangle(t, \"if (a) throw c; if (b) throw d;\", \"if (a) throw c;\\nif (b) throw d;\\n\")\n\texpectPrintedMangle(t, \"if (a) throw c; if (b) throw c;\", \"if (a || b) throw c;\\n\")\n\texpectPrintedMangle(t, \"while (x) { if (a) break; if (b) break; }\", \"for (; x && !(a || b); )\\n  ;\\n\")\n\texpectPrintedMangle(t, \"while (x) { if (a) continue; if (b) continue; }\", \"for (; x; )\\n  a || b;\\n\")\n\texpectPrintedMangle(t, \"while (x) { debugger; if (a) break; if (b) break; }\", \"for (; x; ) {\\n  debugger;\\n  if (a || b) break;\\n}\\n\")\n\texpectPrintedMangle(t, \"while (x) { debugger; if (a) continue; if (b) continue; }\", \"for (; x; ) {\\n  debugger;\\n  a || b;\\n}\\n\")\n\texpectPrintedMangle(t, \"x: while (x) y: while (y) { if (a) break x; if (b) break y; }\",\n\t\t\"x: for (; x; ) y: for (; y; ) {\\n  if (a) break x;\\n  if (b) break y;\\n}\\n\")\n\texpectPrintedMangle(t, \"x: while (x) y: while (y) { if (a) continue x; if (b) continue y; }\",\n\t\t\"x: for (; x; ) y: for (; y; ) {\\n  if (a) continue x;\\n  if (b) continue y;\\n}\\n\")\n\texpectPrintedMangle(t, \"x: while (x) y: while (y) { if (a) break x; if (b) break x; }\",\n\t\t\"x: for (; x; ) for (; y; )\\n  if (a || b) break x;\\n\")\n\texpectPrintedMangle(t, \"x: while (x) y: while (y) { if (a) continue x; if (b) continue x; }\",\n\t\t\"x: for (; x; ) for (; y; )\\n  if (a || b) continue x;\\n\")\n\texpectPrintedMangle(t, \"x: while (x) y: while (y) { if (a) break y; if (b) break y; }\",\n\t\t\"for (; x; ) y: for (; y; )\\n  if (a || b) break y;\\n\")\n\texpectPrintedMangle(t, \"x: while (x) y: while (y) { if (a) continue y; if (b) continue y; }\",\n\t\t\"for (; x; ) y: for (; y; )\\n  if (a || b) continue y;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"if (x ? y : 0) foo()\", \"if (x ? y : 0) foo();\\n\", \"x && y && foo();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (x ? y : 1) foo()\", \"if (x ? y : 1) foo();\\n\", \"(!x || y) && foo();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (x ? 0 : y) foo()\", \"if (x ? 0 : y) foo();\\n\", \"!x && y && foo();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (x ? 1 : y) foo()\", \"if (x ? 1 : y) foo();\\n\", \"(x || y) && foo();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"if (x ? y : 0) ; else foo()\", \"if (x ? y : 0) ;\\nelse foo();\\n\", \"x && y || foo();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (x ? y : 1) ; else foo()\", \"if (x ? y : 1) ;\\nelse foo();\\n\", \"!x || y || foo();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (x ? 0 : y) ; else foo()\", \"if (x ? 0 : y) ;\\nelse foo();\\n\", \"!x && y || foo();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (x ? 1 : y) ; else foo()\", \"if (x ? 1 : y) ;\\nelse foo();\\n\", \"x || y || foo();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"(x ? y : 0) && foo();\", \"(x ? y : 0) && foo();\\n\", \"x && y && foo();\\n\")\n\texpectPrintedNormalAndMangle(t, \"(x ? y : 1) && foo();\", \"(x ? y : 1) && foo();\\n\", \"(!x || y) && foo();\\n\")\n\texpectPrintedNormalAndMangle(t, \"(x ? 0 : y) && foo();\", \"(x ? 0 : y) && foo();\\n\", \"!x && y && foo();\\n\")\n\texpectPrintedNormalAndMangle(t, \"(x ? 1 : y) && foo();\", \"(x ? 1 : y) && foo();\\n\", \"(x || y) && foo();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"(x ? y : 0) || foo();\", \"(x ? y : 0) || foo();\\n\", \"x && y || foo();\\n\")\n\texpectPrintedNormalAndMangle(t, \"(x ? y : 1) || foo();\", \"(x ? y : 1) || foo();\\n\", \"!x || y || foo();\\n\")\n\texpectPrintedNormalAndMangle(t, \"(x ? 0 : y) || foo();\", \"(x ? 0 : y) || foo();\\n\", \"!x && y || foo();\\n\")\n\texpectPrintedNormalAndMangle(t, \"(x ? 1 : y) || foo();\", \"(x ? 1 : y) || foo();\\n\", \"x || y || foo();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"if (!!a || !!b) throw 0\", \"if (!!a || !!b) throw 0;\\n\", \"if (a || b) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!!a && !!b) throw 0\", \"if (!!a && !!b) throw 0;\\n\", \"if (a && b) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!!a ? !!b : !!c) throw 0\", \"if (!!a ? !!b : !!c) throw 0;\\n\", \"if (a ? b : c) throw 0;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"if ((a + b) !== 0) throw 0\", \"if (a + b !== 0) throw 0;\\n\", \"if (a + b !== 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if ((a | b) !== 0) throw 0\", \"if ((a | b) !== 0) throw 0;\\n\", \"if ((a | b) !== 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if ((a & b) !== 0) throw 0\", \"if ((a & b) !== 0) throw 0;\\n\", \"if ((a & b) !== 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if ((a ^ b) !== 0) throw 0\", \"if ((a ^ b) !== 0) throw 0;\\n\", \"if ((a ^ b) !== 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if ((a << b) !== 0) throw 0\", \"if (a << b !== 0) throw 0;\\n\", \"if (a << b !== 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if ((a >> b) !== 0) throw 0\", \"if (a >> b !== 0) throw 0;\\n\", \"if (a >> b !== 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if ((a >>> b) !== 0) throw 0\", \"if (a >>> b !== 0) throw 0;\\n\", \"if (a >>> b) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (+a !== 0) throw 0\", \"if (+a !== 0) throw 0;\\n\", \"if (+a != 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (~a !== 0) throw 0\", \"if (~a !== 0) throw 0;\\n\", \"if (~a !== 0) throw 0;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"if (0 != (a + b)) throw 0\", \"if (0 != a + b) throw 0;\\n\", \"if (a + b != 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 != (a | b)) throw 0\", \"if (0 != (a | b)) throw 0;\\n\", \"if ((a | b) != 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 != (a & b)) throw 0\", \"if (0 != (a & b)) throw 0;\\n\", \"if ((a & b) != 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 != (a ^ b)) throw 0\", \"if (0 != (a ^ b)) throw 0;\\n\", \"if ((a ^ b) != 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 != (a << b)) throw 0\", \"if (0 != a << b) throw 0;\\n\", \"if (a << b != 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 != (a >> b)) throw 0\", \"if (0 != a >> b) throw 0;\\n\", \"if (a >> b != 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 != (a >>> b)) throw 0\", \"if (0 != a >>> b) throw 0;\\n\", \"if (a >>> b) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 != +a) throw 0\", \"if (0 != +a) throw 0;\\n\", \"if (+a != 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 != ~a) throw 0\", \"if (0 != ~a) throw 0;\\n\", \"if (~a != 0) throw 0;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"if ((a + b) === 0) throw 0\", \"if (a + b === 0) throw 0;\\n\", \"if (a + b === 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if ((a | b) === 0) throw 0\", \"if ((a | b) === 0) throw 0;\\n\", \"if ((a | b) === 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if ((a & b) === 0) throw 0\", \"if ((a & b) === 0) throw 0;\\n\", \"if ((a & b) === 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if ((a ^ b) === 0) throw 0\", \"if ((a ^ b) === 0) throw 0;\\n\", \"if ((a ^ b) === 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if ((a << b) === 0) throw 0\", \"if (a << b === 0) throw 0;\\n\", \"if (a << b === 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if ((a >> b) === 0) throw 0\", \"if (a >> b === 0) throw 0;\\n\", \"if (a >> b === 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if ((a >>> b) === 0) throw 0\", \"if (a >>> b === 0) throw 0;\\n\", \"if (!(a >>> b)) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (+a === 0) throw 0\", \"if (+a === 0) throw 0;\\n\", \"if (+a == 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (~a === 0) throw 0\", \"if (~a === 0) throw 0;\\n\", \"if (~a === 0) throw 0;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"if (0 == (a + b)) throw 0\", \"if (0 == a + b) throw 0;\\n\", \"if (a + b == 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 == (a | b)) throw 0\", \"if (0 == (a | b)) throw 0;\\n\", \"if ((a | b) == 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 == (a & b)) throw 0\", \"if (0 == (a & b)) throw 0;\\n\", \"if ((a & b) == 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 == (a ^ b)) throw 0\", \"if (0 == (a ^ b)) throw 0;\\n\", \"if ((a ^ b) == 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 == (a << b)) throw 0\", \"if (0 == a << b) throw 0;\\n\", \"if (a << b == 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 == (a >> b)) throw 0\", \"if (0 == a >> b) throw 0;\\n\", \"if (a >> b == 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 == (a >>> b)) throw 0\", \"if (0 == a >>> b) throw 0;\\n\", \"if (!(a >>> b)) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 == +a) throw 0\", \"if (0 == +a) throw 0;\\n\", \"if (+a == 0) throw 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0 == ~a) throw 0\", \"if (0 == ~a) throw 0;\\n\", \"if (~a == 0) throw 0;\\n\")\n}\n\nfunc TestMangleWrapToAvoidAmbiguousElse(t *testing.T) {\n\texpectPrintedMangle(t, \"if (a) { if (b) return c } else return d\", \"if (a) {\\n  if (b) return c;\\n} else return d;\\n\")\n\texpectPrintedMangle(t, \"if (a) while (1) { if (b) return c } else return d\", \"if (a) {\\n  for (; ; )\\n    if (b) return c;\\n} else return d;\\n\")\n\texpectPrintedMangle(t, \"if (a) for (;;) { if (b) return c } else return d\", \"if (a) {\\n  for (; ; )\\n    if (b) return c;\\n} else return d;\\n\")\n\texpectPrintedMangle(t, \"if (a) for (x in y) { if (b) return c } else return d\", \"if (a) {\\n  for (x in y)\\n    if (b) return c;\\n} else return d;\\n\")\n\texpectPrintedMangle(t, \"if (a) for (x of y) { if (b) return c } else return d\", \"if (a) {\\n  for (x of y)\\n    if (b) return c;\\n} else return d;\\n\")\n\texpectPrintedMangle(t, \"if (a) with (x) { if (b) return c } else return d\", \"if (a) {\\n  with (x)\\n    if (b) return c;\\n} else return d;\\n\")\n\texpectPrintedMangle(t, \"if (a) x: { if (b) break x } else return c\", \"if (a) {\\n  x:\\n    if (b) break x;\\n} else return c;\\n\")\n}\n\nfunc TestMangleOptionalChain(t *testing.T) {\n\texpectPrintedMangle(t, \"let a; return a != null ? a.b : undefined\", \"let a;\\nreturn a?.b;\\n\")\n\texpectPrintedMangle(t, \"let a; return a != null ? a[b] : undefined\", \"let a;\\nreturn a?.[b];\\n\")\n\texpectPrintedMangle(t, \"let a; return a != null ? a(b) : undefined\", \"let a;\\nreturn a?.(b);\\n\")\n\n\texpectPrintedMangle(t, \"let a; return a == null ? undefined : a.b\", \"let a;\\nreturn a?.b;\\n\")\n\texpectPrintedMangle(t, \"let a; return a == null ? undefined : a[b]\", \"let a;\\nreturn a?.[b];\\n\")\n\texpectPrintedMangle(t, \"let a; return a == null ? undefined : a(b)\", \"let a;\\nreturn a?.(b);\\n\")\n\n\texpectPrintedMangle(t, \"let a; return null != a ? a.b : undefined\", \"let a;\\nreturn a?.b;\\n\")\n\texpectPrintedMangle(t, \"let a; return null != a ? a[b] : undefined\", \"let a;\\nreturn a?.[b];\\n\")\n\texpectPrintedMangle(t, \"let a; return null != a ? a(b) : undefined\", \"let a;\\nreturn a?.(b);\\n\")\n\n\texpectPrintedMangle(t, \"let a; return null == a ? undefined : a.b\", \"let a;\\nreturn a?.b;\\n\")\n\texpectPrintedMangle(t, \"let a; return null == a ? undefined : a[b]\", \"let a;\\nreturn a?.[b];\\n\")\n\texpectPrintedMangle(t, \"let a; return null == a ? undefined : a(b)\", \"let a;\\nreturn a?.(b);\\n\")\n\n\texpectPrintedMangle(t, \"return a != null ? a.b : undefined\", \"return a != null ? a.b : void 0;\\n\")\n\texpectPrintedMangle(t, \"let a; return a != null ? a.b : null\", \"let a;\\nreturn a != null ? a.b : null;\\n\")\n\texpectPrintedMangle(t, \"let a; return a != null ? b.a : undefined\", \"let a;\\nreturn a != null ? b.a : void 0;\\n\")\n\texpectPrintedMangle(t, \"let a; return a != 0 ? a.b : undefined\", \"let a;\\nreturn a != 0 ? a.b : void 0;\\n\")\n\texpectPrintedMangle(t, \"let a; return a !== null ? a.b : undefined\", \"let a;\\nreturn a !== null ? a.b : void 0;\\n\")\n\texpectPrintedMangle(t, \"let a; return a != undefined ? a.b : undefined\", \"let a;\\nreturn a?.b;\\n\")\n\texpectPrintedMangle(t, \"let a; return a != null ? a?.b : undefined\", \"let a;\\nreturn a?.b;\\n\")\n\texpectPrintedMangle(t, \"let a; return a != null ? a.b.c[d](e) : undefined\", \"let a;\\nreturn a?.b.c[d](e);\\n\")\n\texpectPrintedMangle(t, \"let a; return a != null ? a?.b.c[d](e) : undefined\", \"let a;\\nreturn a?.b.c[d](e);\\n\")\n\texpectPrintedMangle(t, \"let a; return a != null ? a.b.c?.[d](e) : undefined\", \"let a;\\nreturn a?.b.c?.[d](e);\\n\")\n\texpectPrintedMangle(t, \"let a; return a != null ? a?.b.c?.[d](e) : undefined\", \"let a;\\nreturn a?.b.c?.[d](e);\\n\")\n\texpectPrintedMangleTarget(t, 2019, \"let a; return a != null ? a.b : undefined\", \"let a;\\nreturn a != null ? a.b : void 0;\\n\")\n\texpectPrintedMangleTarget(t, 2020, \"let a; return a != null ? a.b : undefined\", \"let a;\\nreturn a?.b;\\n\")\n\n\texpectPrintedMangle(t, \"a != null && a.b()\", \"a?.b();\\n\")\n\texpectPrintedMangle(t, \"a == null || a.b()\", \"a?.b();\\n\")\n\texpectPrintedMangle(t, \"null != a && a.b()\", \"a?.b();\\n\")\n\texpectPrintedMangle(t, \"null == a || a.b()\", \"a?.b();\\n\")\n\n\texpectPrintedMangle(t, \"a == null && a.b()\", \"a == null && a.b();\\n\")\n\texpectPrintedMangle(t, \"a != null || a.b()\", \"a != null || a.b();\\n\")\n\texpectPrintedMangle(t, \"null == a && a.b()\", \"a == null && a.b();\\n\")\n\texpectPrintedMangle(t, \"null != a || a.b()\", \"a != null || a.b();\\n\")\n\n\texpectPrintedMangle(t, \"x = a != null && a.b()\", \"x = a != null && a.b();\\n\")\n\texpectPrintedMangle(t, \"x = a == null || a.b()\", \"x = a == null || a.b();\\n\")\n\n\texpectPrintedMangle(t, \"if (a != null) a.b()\", \"a?.b();\\n\")\n\texpectPrintedMangle(t, \"if (a == null) ; else a.b()\", \"a?.b();\\n\")\n\n\texpectPrintedMangle(t, \"if (a == null) a.b()\", \"a == null && a.b();\\n\")\n\texpectPrintedMangle(t, \"if (a != null) ; else a.b()\", \"a != null || a.b();\\n\")\n}\n\nfunc TestMangleNullOrUndefinedWithSideEffects(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"x(y ?? 1)\", \"x(y ?? 1);\\n\", \"x(y ?? 1);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(y.z ?? 1)\", \"x(y.z ?? 1);\\n\", \"x(y.z ?? 1);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(y[z] ?? 1)\", \"x(y[z] ?? 1);\\n\", \"x(y[z] ?? 1);\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x(0 ?? 1)\", \"x(0);\\n\", \"x(0);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(0n ?? 1)\", \"x(0n);\\n\", \"x(0n);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x('' ?? 1)\", \"x(\\\"\\\");\\n\", \"x(\\\"\\\");\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(/./ ?? 1)\", \"x(/./);\\n\", \"x(/./);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x({} ?? 1)\", \"x({});\\n\", \"x({});\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((() => {}) ?? 1)\", \"x((() => {\\n}));\\n\", \"x((() => {\\n}));\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(class {} ?? 1)\", \"x(class {\\n});\\n\", \"x(class {\\n});\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(function() {} ?? 1)\", \"x(function() {\\n});\\n\", \"x(function() {\\n});\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x(null ?? 1)\", \"x(1);\\n\", \"x(1);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(undefined ?? 1)\", \"x(1);\\n\", \"x(1);\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x(void y ?? 1)\", \"x(void y ?? 1);\\n\", \"x(void y ?? 1);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(-y ?? 1)\", \"x(-y);\\n\", \"x(-y);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(+y ?? 1)\", \"x(+y);\\n\", \"x(+y);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(!y ?? 1)\", \"x(!y);\\n\", \"x(!y);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(~y ?? 1)\", \"x(~y);\\n\", \"x(~y);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(--y ?? 1)\", \"x(--y);\\n\", \"x(--y);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(++y ?? 1)\", \"x(++y);\\n\", \"x(++y);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(y-- ?? 1)\", \"x(y--);\\n\", \"x(y--);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(y++ ?? 1)\", \"x(y++);\\n\", \"x(y++);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(delete y ?? 1)\", \"x(delete y);\\n\", \"x(delete y);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x(typeof y ?? 1)\", \"x(typeof y);\\n\", \"x(typeof y);\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x((y, 0) ?? 1)\", \"x((y, 0));\\n\", \"x((y, 0));\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y, !z) ?? 1)\", \"x((y, !z));\\n\", \"x((y, !z));\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y, null) ?? 1)\", \"x((y, null) ?? 1);\\n\", \"x((y, null ?? 1));\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y, void z) ?? 1)\", \"x((y, void z) ?? 1);\\n\", \"x((y, void z ?? 1));\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x((y + z) ?? 1)\", \"x(y + z);\\n\", \"x(y + z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y - z) ?? 1)\", \"x(y - z);\\n\", \"x(y - z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y * z) ?? 1)\", \"x(y * z);\\n\", \"x(y * z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y / z) ?? 1)\", \"x(y / z);\\n\", \"x(y / z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y % z) ?? 1)\", \"x(y % z);\\n\", \"x(y % z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y ** z) ?? 1)\", \"x(y ** z);\\n\", \"x(y ** z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y << z) ?? 1)\", \"x(y << z);\\n\", \"x(y << z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y >> z) ?? 1)\", \"x(y >> z);\\n\", \"x(y >> z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y >>> z) ?? 1)\", \"x(y >>> z);\\n\", \"x(y >>> z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y | z) ?? 1)\", \"x(y | z);\\n\", \"x(y | z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y & z) ?? 1)\", \"x(y & z);\\n\", \"x(y & z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y ^ z) ?? 1)\", \"x(y ^ z);\\n\", \"x(y ^ z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y < z) ?? 1)\", \"x(y < z);\\n\", \"x(y < z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y > z) ?? 1)\", \"x(y > z);\\n\", \"x(y > z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y <= z) ?? 1)\", \"x(y <= z);\\n\", \"x(y <= z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y >= z) ?? 1)\", \"x(y >= z);\\n\", \"x(y >= z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y == z) ?? 1)\", \"x(y == z);\\n\", \"x(y == z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y != z) ?? 1)\", \"x(y != z);\\n\", \"x(y != z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y === z) ?? 1)\", \"x(y === z);\\n\", \"x(y === z);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y !== z) ?? 1)\", \"x(y !== z);\\n\", \"x(y !== z);\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x((y || z) ?? 1)\", \"x((y || z) ?? 1);\\n\", \"x((y || z) ?? 1);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y && z) ?? 1)\", \"x((y && z) ?? 1);\\n\", \"x((y && z) ?? 1);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x((y ?? z) ?? 1)\", \"x(y ?? z ?? 1);\\n\", \"x(y ?? z ?? 1);\\n\")\n}\n\nfunc TestMangleBooleanWithSideEffects(t *testing.T) {\n\tfalsyNoSideEffects := []string{\"false\", \"\\\"\\\"\", \"0\", \"0n\", \"null\", \"void 0\"}\n\ttruthyNoSideEffects := []string{\"true\", \"\\\" \\\"\", \"1\", \"1n\", \"/./\", \"(() => {\\n})\", \"function() {\\n}\", \"[1, 2]\", \"{ a: 0 }\"}\n\n\tfor _, value := range falsyNoSideEffects {\n\t\texpectPrintedMangle(t, \"y(x && \"+value+\")\", \"y(x && \"+value+\");\\n\")\n\t\texpectPrintedMangle(t, \"y(x || \"+value+\")\", \"y(x || \"+value+\");\\n\")\n\n\t\texpectPrintedMangle(t, \"y(!(x && \"+value+\"))\", \"y(!(x && false));\\n\")\n\t\texpectPrintedMangle(t, \"y(!(x || \"+value+\"))\", \"y(!x);\\n\")\n\n\t\texpectPrintedMangle(t, \"if (x && \"+value+\") y\", \"x;\\n\")\n\t\texpectPrintedMangle(t, \"if (x || \"+value+\") y\", \"x && y;\\n\")\n\n\t\texpectPrintedMangle(t, \"if (x && \"+value+\") y; else z\", \"x, z;\\n\")\n\t\texpectPrintedMangle(t, \"if (x || \"+value+\") y; else z\", \"x ? y : z;\\n\")\n\n\t\texpectPrintedMangle(t, \"y(x && \"+value+\" ? y : z)\", \"y((x, z));\\n\")\n\t\texpectPrintedMangle(t, \"y(x || \"+value+\" ? y : z)\", \"y(x ? y : z);\\n\")\n\n\t\texpectPrintedMangle(t, \"while (\"+value+\") x()\", \"for (; false; ) x();\\n\")\n\t\texpectPrintedMangle(t, \"for (; \"+value+\"; ) x()\", \"for (; false; ) x();\\n\")\n\t}\n\n\tfor _, value := range truthyNoSideEffects {\n\t\texpectPrintedMangle(t, \"y(x && \"+value+\")\", \"y(x && \"+value+\");\\n\")\n\t\texpectPrintedMangle(t, \"y(x || \"+value+\")\", \"y(x || \"+value+\");\\n\")\n\n\t\texpectPrintedMangle(t, \"y(!(x && \"+value+\"))\", \"y(!x);\\n\")\n\t\texpectPrintedMangle(t, \"y(!(x || \"+value+\"))\", \"y(!(x || true));\\n\")\n\n\t\texpectPrintedMangle(t, \"if (x && \"+value+\") y\", \"x && y;\\n\")\n\t\texpectPrintedMangle(t, \"if (x || \"+value+\") y\", \"x, y;\\n\")\n\n\t\texpectPrintedMangle(t, \"if (x && \"+value+\") y; else z\", \"x ? y : z;\\n\")\n\t\texpectPrintedMangle(t, \"if (x || \"+value+\") y; else z\", \"x, y;\\n\")\n\n\t\texpectPrintedMangle(t, \"y(x && \"+value+\" ? y : z)\", \"y(x ? y : z);\\n\")\n\t\texpectPrintedMangle(t, \"y(x || \"+value+\" ? y : z)\", \"y((x, y));\\n\")\n\n\t\texpectPrintedMangle(t, \"while (\"+value+\") x()\", \"for (; ; ) x();\\n\")\n\t\texpectPrintedMangle(t, \"for (; \"+value+\"; ) x()\", \"for (; ; ) x();\\n\")\n\t}\n\n\tfalsyHasSideEffects := []string{\"void foo()\"}\n\ttruthyHasSideEffects := []string{\"typeof foo()\", \"[foo()]\", \"{ [foo()]: 0 }\"}\n\n\tfor _, value := range falsyHasSideEffects {\n\t\texpectPrintedMangle(t, \"y(x && \"+value+\")\", \"y(x && \"+value+\");\\n\")\n\t\texpectPrintedMangle(t, \"y(x || \"+value+\")\", \"y(x || \"+value+\");\\n\")\n\n\t\texpectPrintedMangle(t, \"y(!(x && \"+value+\"))\", \"y(!(x && \"+value+\"));\\n\")\n\t\texpectPrintedMangle(t, \"y(!(x || \"+value+\"))\", \"y(!(x || \"+value+\"));\\n\")\n\n\t\texpectPrintedMangle(t, \"if (x || \"+value+\") y\", \"(x || \"+value+\") && y;\\n\")\n\t\texpectPrintedMangle(t, \"if (x || \"+value+\") y; else z\", \"x || \"+value+\" ? y : z;\\n\")\n\t\texpectPrintedMangle(t, \"y(x || \"+value+\" ? y : z)\", \"y(x || \"+value+\" ? y : z);\\n\")\n\n\t\texpectPrintedMangle(t, \"while (\"+value+\") x()\", \"for (; \"+value+\"; ) x();\\n\")\n\t\texpectPrintedMangle(t, \"for (; \"+value+\"; ) x()\", \"for (; \"+value+\"; ) x();\\n\")\n\t}\n\n\tfor _, value := range truthyHasSideEffects {\n\t\texpectPrintedMangle(t, \"y(x && \"+value+\")\", \"y(x && \"+value+\");\\n\")\n\t\texpectPrintedMangle(t, \"y(x || \"+value+\")\", \"y(x || \"+value+\");\\n\")\n\n\t\texpectPrintedMangle(t, \"y(!(x || \"+value+\"))\", \"y(!(x || \"+value+\"));\\n\")\n\t\texpectPrintedMangle(t, \"y(!(x && \"+value+\"))\", \"y(!(x && \"+value+\"));\\n\")\n\n\t\texpectPrintedMangle(t, \"if (x && \"+value+\") y\", \"x && \"+value+\" && y;\\n\")\n\t\texpectPrintedMangle(t, \"if (x && \"+value+\") y; else z\", \"x && \"+value+\" ? y : z;\\n\")\n\t\texpectPrintedMangle(t, \"y(x && \"+value+\" ? y : z)\", \"y(x && \"+value+\" ? y : z);\\n\")\n\n\t\texpectPrintedMangle(t, \"while (\"+value+\") x()\", \"for (; \"+value+\"; ) x();\\n\")\n\t\texpectPrintedMangle(t, \"for (; \"+value+\"; ) x()\", \"for (; \"+value+\"; ) x();\\n\")\n\t}\n}\n\nfunc TestMangleReturn(t *testing.T) {\n\texpectPrintedMangle(t, \"function foo() { x(); return; }\", \"function foo() {\\n  x();\\n}\\n\")\n\texpectPrintedMangle(t, \"let foo = function() { x(); return; }\", \"let foo = function() {\\n  x();\\n};\\n\")\n\texpectPrintedMangle(t, \"let foo = () => { x(); return; }\", \"let foo = () => {\\n  x();\\n};\\n\")\n\texpectPrintedMangle(t, \"function foo() { x(); return y; }\", \"function foo() {\\n  return x(), y;\\n}\\n\")\n\texpectPrintedMangle(t, \"let foo = function() { x(); return y; }\", \"let foo = function() {\\n  return x(), y;\\n};\\n\")\n\texpectPrintedMangle(t, \"let foo = () => { x(); return y; }\", \"let foo = () => (x(), y);\\n\")\n\n\t// Don't trim a trailing top-level return because we may be compiling a partial module\n\texpectPrintedMangle(t, \"x(); return;\", \"x();\\nreturn;\\n\")\n\n\texpectPrintedMangle(t, \"function foo() { a = b; if (a) return a; if (b) c = b; return c; }\",\n\t\t\"function foo() {\\n  return a = b, a || (b && (c = b), c);\\n}\\n\")\n\texpectPrintedMangle(t, \"function foo() { a = b; if (a) return; if (b) c = b; return c; }\",\n\t\t\"function foo() {\\n  if (a = b, !a)\\n    return b && (c = b), c;\\n}\\n\")\n\texpectPrintedMangle(t, \"function foo() { if (!a) return b; return c; }\", \"function foo() {\\n  return a ? c : b;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"if (1) return a(); else return b()\", \"return a();\\n\")\n\texpectPrintedMangle(t, \"if (0) return a(); else return b()\", \"return b();\\n\")\n\texpectPrintedMangle(t, \"if (a) return b(); else return c()\", \"return a ? b() : c();\\n\")\n\texpectPrintedMangle(t, \"if (!a) return b(); else return c()\", \"return a ? c() : b();\\n\")\n\texpectPrintedMangle(t, \"if (!!a) return b(); else return c()\", \"return a ? b() : c();\\n\")\n\texpectPrintedMangle(t, \"if (!!!a) return b(); else return c()\", \"return a ? c() : b();\\n\")\n\n\texpectPrintedMangle(t, \"if (1) return a(); return b()\", \"return a();\\n\")\n\texpectPrintedMangle(t, \"if (0) return a(); return b()\", \"return b();\\n\")\n\texpectPrintedMangle(t, \"if (a) return b(); return c()\", \"return a ? b() : c();\\n\")\n\texpectPrintedMangle(t, \"if (!a) return b(); return c()\", \"return a ? c() : b();\\n\")\n\texpectPrintedMangle(t, \"if (!!a) return b(); return c()\", \"return a ? b() : c();\\n\")\n\texpectPrintedMangle(t, \"if (!!!a) return b(); return c()\", \"return a ? c() : b();\\n\")\n\n\texpectPrintedMangle(t, \"if (a) return b; else return c; return d;\\n\", \"return a ? b : c;\\n\")\n\n\t// Optimize implicit return\n\texpectPrintedMangle(t, \"function x() { if (y) return; z(); }\", \"function x() {\\n  y || z();\\n}\\n\")\n\texpectPrintedMangle(t, \"function x() { if (y) return; else z(); w(); }\", \"function x() {\\n  y || (z(), w());\\n}\\n\")\n\texpectPrintedMangle(t, \"function x() { t(); if (y) return; z(); }\", \"function x() {\\n  t(), !y && z();\\n}\\n\")\n\texpectPrintedMangle(t, \"function x() { t(); if (y) return; else z(); w(); }\", \"function x() {\\n  t(), !y && (z(), w());\\n}\\n\")\n\texpectPrintedMangle(t, \"function x() { debugger; if (y) return; z(); }\", \"function x() {\\n  debugger;\\n  y || z();\\n}\\n\")\n\texpectPrintedMangle(t, \"function x() { debugger; if (y) return; else z(); w(); }\", \"function x() {\\n  debugger;\\n  y || (z(), w());\\n}\\n\")\n\texpectPrintedMangle(t, \"function x() { if (y) { if (z) return; } }\",\n\t\t\"function x() {\\n  y && z;\\n}\\n\")\n\texpectPrintedMangle(t, \"function x() { if (y) { if (z) return; w(); } }\",\n\t\t\"function x() {\\n  if (y) {\\n    if (z) return;\\n    w();\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"function foo(x) { if (!x.y) {} else return x }\", \"function foo(x) {\\n  if (x.y)\\n    return x;\\n}\\n\")\n\texpectPrintedMangle(t, \"function foo(x) { if (!x.y) return undefined; return x }\", \"function foo(x) {\\n  if (x.y)\\n    return x;\\n}\\n\")\n\n\t// Do not optimize implicit return for statements that care about scope\n\texpectPrintedMangle(t, \"function x() { if (y) return; function y() {} }\", \"function x() {\\n  if (y) return;\\n  function y() {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"function x() { if (y) return; let y }\", \"function x() {\\n  if (y) return;\\n  let y;\\n}\\n\")\n\texpectPrintedMangle(t, \"function x() { if (y) return; var y }\", \"function x() {\\n  if (!y)\\n    var y;\\n}\\n\")\n}\n\nfunc TestMangleThrow(t *testing.T) {\n\texpectPrintedNormalAndMangle(t,\n\t\t\"function foo() { a = b; if (a) throw a; if (b) c = b; throw c; }\",\n\t\t\"function foo() {\\n  a = b;\\n  if (a) throw a;\\n  if (b) c = b;\\n  throw c;\\n}\\n\",\n\t\t\"function foo() {\\n  throw a = b, a || (b && (c = b), c);\\n}\\n\")\n\texpectPrintedNormalAndMangle(t,\n\t\t\"function foo() { if (!a) throw b; throw c; }\",\n\t\t\"function foo() {\\n  if (!a) throw b;\\n  throw c;\\n}\\n\",\n\t\t\"function foo() {\\n  throw a ? c : b;\\n}\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"if (1) throw a(); else throw b()\", \"if (1) throw a();\\nelse throw b();\\n\", \"throw a();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0) throw a(); else throw b()\", \"if (0) throw a();\\nelse throw b();\\n\", \"throw b();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (a) throw b(); else throw c()\", \"if (a) throw b();\\nelse throw c();\\n\", \"throw a ? b() : c();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!a) throw b(); else throw c()\", \"if (!a) throw b();\\nelse throw c();\\n\", \"throw a ? c() : b();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!!a) throw b(); else throw c()\", \"if (!!a) throw b();\\nelse throw c();\\n\", \"throw a ? b() : c();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!!!a) throw b(); else throw c()\", \"if (!!!a) throw b();\\nelse throw c();\\n\", \"throw a ? c() : b();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"if (1) throw a(); throw b()\", \"if (1) throw a();\\nthrow b();\\n\", \"throw a();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (0) throw a(); throw b()\", \"if (0) throw a();\\nthrow b();\\n\", \"throw b();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (a) throw b(); throw c()\", \"if (a) throw b();\\nthrow c();\\n\", \"throw a ? b() : c();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!a) throw b(); throw c()\", \"if (!a) throw b();\\nthrow c();\\n\", \"throw a ? c() : b();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!!a) throw b(); throw c()\", \"if (!!a) throw b();\\nthrow c();\\n\", \"throw a ? b() : c();\\n\")\n\texpectPrintedNormalAndMangle(t, \"if (!!!a) throw b(); throw c()\", \"if (!!!a) throw b();\\nthrow c();\\n\", \"throw a ? c() : b();\\n\")\n}\n\nfunc TestMangleInitializer(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"const a = undefined\", \"const a = void 0;\\n\", \"const a = void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let a = undefined\", \"let a = void 0;\\n\", \"let a;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let {} = undefined\", \"let {} = void 0;\\n\", \"let {} = void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let [] = undefined\", \"let [] = void 0;\\n\", \"let [] = void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"var a = undefined\", \"var a = void 0;\\n\", \"var a = void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"var {} = undefined\", \"var {} = void 0;\\n\", \"var {} = void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"var [] = undefined\", \"var [] = void 0;\\n\", \"var [] = void 0;\\n\")\n}\n\nfunc TestMangleCall(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"x = foo(1, ...[], 2)\", \"x = foo(1, ...[], 2);\\n\", \"x = foo(1, 2);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = foo(1, ...2, 3)\", \"x = foo(1, ...2, 3);\\n\", \"x = foo(1, ...2, 3);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = foo(1, ...[2], 3)\", \"x = foo(1, ...[2], 3);\\n\", \"x = foo(1, 2, 3);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = foo(1, ...[2, 3], 4)\", \"x = foo(1, ...[2, 3], 4);\\n\", \"x = foo(1, 2, 3, 4);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = foo(1, ...[2, ...y, 3], 4)\", \"x = foo(1, ...[2, ...y, 3], 4);\\n\", \"x = foo(1, 2, ...y, 3, 4);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = foo(1, ...{a, b}, 4)\", \"x = foo(1, ...{ a, b }, 4);\\n\", \"x = foo(1, ...{ a, b }, 4);\\n\")\n\n\t// Holes must become undefined\n\texpectPrintedNormalAndMangle(t, \"x = foo(1, ...[,2,,], 3)\", \"x = foo(1, ...[, 2, ,], 3);\\n\", \"x = foo(1, void 0, 2, void 0, 3);\\n\")\n}\n\nfunc TestMangleNew(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"x = new foo(1, ...[], 2)\", \"x = new foo(1, ...[], 2);\\n\", \"x = new foo(1, 2);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = new foo(1, ...2, 3)\", \"x = new foo(1, ...2, 3);\\n\", \"x = new foo(1, ...2, 3);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = new foo(1, ...[2], 3)\", \"x = new foo(1, ...[2], 3);\\n\", \"x = new foo(1, 2, 3);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = new foo(1, ...[2, 3], 4)\", \"x = new foo(1, ...[2, 3], 4);\\n\", \"x = new foo(1, 2, 3, 4);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = new foo(1, ...[2, ...y, 3], 4)\", \"x = new foo(1, ...[2, ...y, 3], 4);\\n\", \"x = new foo(1, 2, ...y, 3, 4);\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = new foo(1, ...{a, b}, 4)\", \"x = new foo(1, ...{ a, b }, 4);\\n\", \"x = new foo(1, ...{ a, b }, 4);\\n\")\n\n\t// Holes must become undefined\n\texpectPrintedNormalAndMangle(t, \"x = new foo(1, ...[,2,,], 3)\", \"x = new foo(1, ...[, 2, ,], 3);\\n\", \"x = new foo(1, void 0, 2, void 0, 3);\\n\")\n}\n\nfunc TestMangleArray(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"x = [1, ...[], 2]\", \"x = [1, ...[], 2];\\n\", \"x = [1, 2];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = [1, ...2, 3]\", \"x = [1, ...2, 3];\\n\", \"x = [1, ...2, 3];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = [1, ...[2], 3]\", \"x = [1, ...[2], 3];\\n\", \"x = [1, 2, 3];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = [1, ...[2, 3], 4]\", \"x = [1, ...[2, 3], 4];\\n\", \"x = [1, 2, 3, 4];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = [1, ...[2, ...y, 3], 4]\", \"x = [1, ...[2, ...y, 3], 4];\\n\", \"x = [1, 2, ...y, 3, 4];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = [1, ...{a, b}, 4]\", \"x = [1, ...{ a, b }, 4];\\n\", \"x = [1, ...{ a, b }, 4];\\n\")\n\n\t// Holes must become undefined, which is different than a hole\n\texpectPrintedNormalAndMangle(t, \"x = [1, ...[,2,,], 3]\", \"x = [1, ...[, 2, ,], 3];\\n\", \"x = [1, void 0, 2, void 0, 3];\\n\")\n}\n\nfunc TestMangleObject(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"x = {['y']: z}\", \"x = { [\\\"y\\\"]: z };\\n\", \"x = { y: z };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {['y']() {}}\", \"x = { [\\\"y\\\"]() {\\n} };\\n\", \"x = { y() {\\n} };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {get ['y']() {}}\", \"x = { get [\\\"y\\\"]() {\\n} };\\n\", \"x = { get y() {\\n} };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {set ['y'](z) {}}\", \"x = { set [\\\"y\\\"](z) {\\n} };\\n\", \"x = { set y(z) {\\n} };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {async ['y']() {}}\", \"x = { async [\\\"y\\\"]() {\\n} };\\n\", \"x = { async y() {\\n} };\\n\")\n\texpectPrintedNormalAndMangle(t, \"({['y']: z} = x)\", \"({ [\\\"y\\\"]: z } = x);\\n\", \"({ y: z } = x);\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...{}, b}\", \"x = { a, ...{}, b };\\n\", \"x = { a, b };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...b, c}\", \"x = { a, ...b, c };\\n\", \"x = { a, ...b, c };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...{b}, c}\", \"x = { a, ...{ b }, c };\\n\", \"x = { a, b, c };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...{b() {}}, c}\", \"x = { a, ...{ b() {\\n} }, c };\\n\", \"x = { a, b() {\\n}, c };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...{b, c}, d}\", \"x = { a, ...{ b, c }, d };\\n\", \"x = { a, b, c, d };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...{b, ...y, c}, d}\", \"x = { a, ...{ b, ...y, c }, d };\\n\", \"x = { a, b, ...y, c, d };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...[b, c], d}\", \"x = { a, ...[b, c], d };\\n\", \"x = { a, ...[b, c], d };\\n\")\n\n\t// Computed properties should be ok\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...{[b]: c}, d}\", \"x = { a, ...{ [b]: c }, d };\\n\", \"x = { a, [b]: c, d };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...{[b]() {}}, c}\", \"x = { a, ...{ [b]() {\\n} }, c };\\n\", \"x = { a, [b]() {\\n}, c };\\n\")\n\n\t// Getters and setters are not supported\n\texpectPrintedNormalAndMangle(t,\n\t\t\"x = {a, ...{b, get c() { return y++ }, d}, e}\",\n\t\t\"x = { a, ...{ b, get c() {\\n  return y++;\\n}, d }, e };\\n\",\n\t\t\"x = { a, b, ...{ get c() {\\n  return y++;\\n}, d }, e };\\n\")\n\texpectPrintedNormalAndMangle(t,\n\t\t\"x = {a, ...{b, set c(_) { throw _ }, d}, e}\",\n\t\t\"x = { a, ...{ b, set c(_) {\\n  throw _;\\n}, d }, e };\\n\",\n\t\t\"x = { a, b, ...{ set c(_) {\\n  throw _;\\n}, d }, e };\\n\")\n\n\t// \"__proto__\" is not supported\n\texpectPrintedNormalAndMangle(t,\n\t\t\"x = {a, ...{b, __proto__: c, d}, e}\",\n\t\t\"x = { a, ...{ b, __proto__: c, d }, e };\\n\",\n\t\t\"x = { a, b, ...{ __proto__: c, d }, e };\\n\")\n\texpectPrintedNormalAndMangle(t,\n\t\t\"x = {a, ...{b, ['__proto__']: c, d}, e}\",\n\t\t\"x = { a, ...{ b, [\\\"__proto__\\\"]: c, d }, e };\\n\",\n\t\t\"x = { a, b, [\\\"__proto__\\\"]: c, d, e };\\n\")\n\texpectPrintedNormalAndMangle(t,\n\t\t\"x = {a, ...{b, __proto__() {}, c}, d}\",\n\t\t\"x = { a, ...{ b, __proto__() {\\n}, c }, d };\\n\",\n\t\t\"x = { a, b, __proto__() {\\n}, c, d };\\n\")\n\n\t// Spread is ignored for certain values\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...true, b}\", \"x = { a, ...true, b };\\n\", \"x = { a, b };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...null, b}\", \"x = { a, ...null, b };\\n\", \"x = { a, b };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...void 0, b}\", \"x = { a, ...void 0, b };\\n\", \"x = { a, b };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...123, b}\", \"x = { a, ...123, b };\\n\", \"x = { a, b };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...123n, b}\", \"x = { a, ...123n, b };\\n\", \"x = { a, b };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, .../x/, b}\", \"x = { a, .../x/, b };\\n\", \"x = { a, b };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...function(){}, b}\", \"x = { a, ...function() {\\n}, b };\\n\", \"x = { a, b };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...()=>{}, b}\", \"x = { a, ...() => {\\n}, b };\\n\", \"x = { a, b };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...'123', b}\", \"x = { a, ...\\\"123\\\", b };\\n\", \"x = { a, ...\\\"123\\\", b };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...[1, 2, 3], b}\", \"x = { a, ...[1, 2, 3], b };\\n\", \"x = { a, ...[1, 2, 3], b };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {a, ...(()=>{})(), b}\", \"x = { a, .../* @__PURE__ */ (() => {\\n})(), b };\\n\", \"x = { a, b };\\n\")\n\n\t// Check simple cases of object simplification (advanced cases are checked in end-to-end tests)\n\texpectPrintedNormalAndMangle(t, \"x = {['y']: z}.y\", \"x = { [\\\"y\\\"]: z }.y;\\n\", \"x = { y: z }.y;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {['y']: z}.y; var z\", \"x = { [\\\"y\\\"]: z }.y;\\nvar z;\\n\", \"x = z;\\nvar z;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {foo: foo(), y: 1}.y\", \"x = { foo: foo(), y: 1 }.y;\\n\", \"x = { foo: foo(), y: 1 }.y;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {foo: /* @__PURE__ */ foo(), y: 1}.y\", \"x = { foo: /* @__PURE__ */ foo(), y: 1 }.y;\\n\", \"x = 1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {__proto__: null}.y\", \"x = { __proto__: null }.y;\\n\", \"x = void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {__proto__: null, y: 1}.y\", \"x = { __proto__: null, y: 1 }.y;\\n\", \"x = 1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {__proto__: null}.__proto__\", \"x = { __proto__: null }.__proto__;\\n\", \"x = void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {['__proto__']: null}.y\", \"x = { [\\\"__proto__\\\"]: null }.y;\\n\", \"x = { [\\\"__proto__\\\"]: null }.y;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {['__proto__']: null, y: 1}.y\", \"x = { [\\\"__proto__\\\"]: null, y: 1 }.y;\\n\", \"x = { [\\\"__proto__\\\"]: null, y: 1 }.y;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {['__proto__']: null}.__proto__\", \"x = { [\\\"__proto__\\\"]: null }.__proto__;\\n\", \"x = { [\\\"__proto__\\\"]: null }.__proto__;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x = {y: 1}?.y\", \"x = { y: 1 }?.y;\\n\", \"x = 1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {y: 1}?.['y']\", \"x = { y: 1 }?.[\\\"y\\\"];\\n\", \"x = 1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {y: {z: 1}}?.y.z\", \"x = { y: { z: 1 } }?.y.z;\\n\", \"x = 1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {y: {z: 1}}?.y?.z\", \"x = { y: { z: 1 } }?.y?.z;\\n\", \"x = { z: 1 }?.z;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = {y() {}}?.y()\", \"x = { y() {\\n} }?.y();\\n\", \"x = { y() {\\n} }.y();\\n\")\n\n\t// Don't change the value of \"this\" for tagged template literals if the original syntax had a value for \"this\"\n\texpectPrintedNormalAndMangle(t, \"function f(x) { return {x}.x`` }\", \"function f(x) {\\n  return { x }.x``;\\n}\\n\", \"function f(x) {\\n  return { x }.x``;\\n}\\n\")\n\texpectPrintedNormalAndMangle(t, \"function f(x) { return (0, {x}.x)`` }\", \"function f(x) {\\n  return (0, { x }.x)``;\\n}\\n\", \"function f(x) {\\n  return x``;\\n}\\n\")\n}\n\nfunc TestMangleObjectJSX(t *testing.T) {\n\texpectPrintedJSX(t, \"x = <foo bar {...{}} />\", \"x = <foo bar {...{}} />;\\n\", \"x = /* @__PURE__ */ React.createElement(\\\"foo\\\", { bar: true, ...{} });\\n\")\n\texpectPrintedJSX(t, \"x = <foo bar {...null} />\", \"x = <foo bar {...null} />;\\n\", \"x = /* @__PURE__ */ React.createElement(\\\"foo\\\", { bar: true, ...null });\\n\")\n\texpectPrintedJSX(t, \"x = <foo bar {...{bar}} />\", \"x = <foo bar {...{ bar }} />;\\n\", \"x = /* @__PURE__ */ React.createElement(\\\"foo\\\", { bar: true, ...{ bar } });\\n\")\n\texpectPrintedJSX(t, \"x = <foo bar {...bar} />\", \"x = <foo bar {...bar} />;\\n\", \"x = /* @__PURE__ */ React.createElement(\\\"foo\\\", { bar: true, ...bar });\\n\")\n\n\texpectPrintedMangleJSX(t, \"x = <foo bar {...{}} />\", \"x = /* @__PURE__ */ React.createElement(\\\"foo\\\", { bar: true });\\n\")\n\texpectPrintedMangleJSX(t, \"x = <foo bar {...null} />\", \"x = /* @__PURE__ */ React.createElement(\\\"foo\\\", { bar: true });\\n\")\n\texpectPrintedMangleJSX(t, \"x = <foo bar {...{bar}} />\", \"x = /* @__PURE__ */ React.createElement(\\\"foo\\\", { bar: true, bar });\\n\")\n\texpectPrintedMangleJSX(t, \"x = <foo bar {...bar} />\", \"x = /* @__PURE__ */ React.createElement(\\\"foo\\\", { bar: true, ...bar });\\n\")\n}\n\nfunc TestMangleArrow(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"var a = () => {}\", \"var a = () => {\\n};\\n\", \"var a = () => {\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"var a = () => 123\", \"var a = () => 123;\\n\", \"var a = () => 123;\\n\")\n\texpectPrintedNormalAndMangle(t, \"var a = () => void 0\", \"var a = () => void 0;\\n\", \"var a = () => {\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"var a = () => undefined\", \"var a = () => void 0;\\n\", \"var a = () => {\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"var a = () => {return}\", \"var a = () => {\\n  return;\\n};\\n\", \"var a = () => {\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"var a = () => {return 123}\", \"var a = () => {\\n  return 123;\\n};\\n\", \"var a = () => 123;\\n\")\n\texpectPrintedNormalAndMangle(t, \"var a = () => {throw 123}\", \"var a = () => {\\n  throw 123;\\n};\\n\", \"var a = () => {\\n  throw 123;\\n};\\n\")\n}\n\nfunc TestMangleIIFE(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"var a = (() => {})()\", \"var a = /* @__PURE__ */ (() => {\\n})();\\n\", \"var a = void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(() => a)()\", \"(() => a)();\\n\", \"a;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(() => a)(...[])\", \"(() => a)(...[]);\\n\", \"a;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(() => a())()\", \"(() => a())();\\n\", \"a();\\n\")\n\texpectPrintedNormalAndMangle(t, \"(() => { a() })()\", \"(() => {\\n  a();\\n})();\\n\", \"a();\\n\")\n\texpectPrintedNormalAndMangle(t, \"(() => { return a() })()\", \"(() => {\\n  return a();\\n})();\\n\", \"a();\\n\")\n\texpectPrintedNormalAndMangle(t, \"(() => {})()\", \"/* @__PURE__ */ (() => {\\n})();\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"(() => { let b = a; b() })()\", \"(() => {\\n  let b = a;\\n  b();\\n})();\\n\", \"a();\\n\")\n\texpectPrintedNormalAndMangle(t, \"(() => { let b = a; return b() })()\", \"(() => {\\n  let b = a;\\n  return b();\\n})();\\n\", \"a();\\n\")\n\texpectPrintedNormalAndMangle(t, \"(async () => {})()\", \"(async () => {\\n})();\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"(async () => { a() })()\", \"(async () => {\\n  a();\\n})();\\n\", \"(async () => a())();\\n\")\n\texpectPrintedNormalAndMangle(t, \"(async () => { let b = a; b() })()\", \"(async () => {\\n  let b = a;\\n  b();\\n})();\\n\", \"(async () => a())();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"var a = (function() {})()\", \"var a = /* @__PURE__ */ (function() {\\n})();\\n\", \"var a = /* @__PURE__ */ (function() {\\n})();\\n\")\n\texpectPrintedNormalAndMangle(t, \"(function() {})()\", \"/* @__PURE__ */ (function() {\\n})();\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"(function*() {})()\", \"(function* () {\\n})();\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"(async function() {})()\", \"(async function() {\\n})();\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"(function() { a() })()\", \"(function() {\\n  a();\\n})();\\n\", \"(function() {\\n  a();\\n})();\\n\")\n\texpectPrintedNormalAndMangle(t, \"(function*() { a() })()\", \"(function* () {\\n  a();\\n})();\\n\", \"(function* () {\\n  a();\\n})();\\n\")\n\texpectPrintedNormalAndMangle(t, \"(async function() { a() })()\", \"(async function() {\\n  a();\\n})();\\n\", \"(async function() {\\n  a();\\n})();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"(() => x)()\", \"(() => x)();\\n\", \"x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(() => { return x })()\", \"(() => {\\n  return x;\\n})();\\n\", \"x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(() => { x })()\", \"(() => {\\n  x;\\n})();\\n\", \"x;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"return (() => x)()\", \"return (() => x)();\\n\", \"return x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return (() => { return x })()\", \"return (() => {\\n  return x;\\n})();\\n\", \"return x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return (() => { x })()\", \"return (() => {\\n  x;\\n})();\\n\", \"return void x;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"/* @__PURE__ */ (() => x)()\", \"/* @__PURE__ */ (() => x)();\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"/* @__PURE__ */ (() => x)(y, z)\", \"/* @__PURE__ */ (() => x)(y, z);\\n\", \"y, z;\\n\")\n\n\t// https://github.com/evanw/esbuild/issues/4354\n\texpectPrintedNormalAndMangle(t, \"let x = () => { let y = () => z(); y() }\",\n\t\t\"let x = () => {\\n  let y = () => z();\\n  y();\\n};\\n\",\n\t\t\"let x = () => {\\n  z();\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = () => { let y = () => z(); return y() }\",\n\t\t\"let x = () => {\\n  let y = () => z();\\n  return y();\\n};\\n\",\n\t\t\"let x = () => z();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = () => { let y = () => { z() }; y() }\",\n\t\t\"let x = () => {\\n  let y = () => {\\n    z();\\n  };\\n  y();\\n};\\n\",\n\t\t\"let x = () => {\\n  z();\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = () => { let y = () => { z() }; return y() }\",\n\t\t\"let x = () => {\\n  let y = () => {\\n    z();\\n  };\\n  return y();\\n};\\n\",\n\t\t\"let x = () => {\\n  z();\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = () => { let y = () => { z() }; let x = y(); foo(x) }\",\n\t\t\"let x = () => {\\n  let y = () => {\\n    z();\\n  };\\n  let x = y();\\n  foo(x);\\n};\\n\",\n\t\t\"let x = () => {\\n  let x = void z();\\n  foo(x);\\n};\\n\")\n}\n\nfunc TestMangleTemplate(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"_ = `a${x}b${y}c`\", \"_ = `a${x}b${y}c`;\\n\", \"_ = `a${x}b${y}c`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"_ = `a${x}b${'y'}c`\", \"_ = `a${x}b${\\\"y\\\"}c`;\\n\", \"_ = `a${x}byc`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"_ = `a${'x'}b${y}c`\", \"_ = `a${\\\"x\\\"}b${y}c`;\\n\", \"_ = `axb${y}c`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"_ = `a${'x'}b${'y'}c`\", \"_ = `a${\\\"x\\\"}b${\\\"y\\\"}c`;\\n\", \"_ = `axbyc`;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"tag`a${x}b${y}c`\", \"tag`a${x}b${y}c`;\\n\", \"tag`a${x}b${y}c`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"tag`a${x}b${'y'}c`\", \"tag`a${x}b${\\\"y\\\"}c`;\\n\", \"tag`a${x}b${\\\"y\\\"}c`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"tag`a${'x'}b${y}c`\", \"tag`a${\\\"x\\\"}b${y}c`;\\n\", \"tag`a${\\\"x\\\"}b${y}c`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"tag`a${'x'}b${'y'}c`\", \"tag`a${\\\"x\\\"}b${\\\"y\\\"}c`;\\n\", \"tag`a${\\\"x\\\"}b${\\\"y\\\"}c`;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"(1, x)``\", \"(1, x)``;\\n\", \"x``;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(1, x.y)``\", \"(1, x.y)``;\\n\", \"(0, x.y)``;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(1, x[y])``\", \"(1, x[y])``;\\n\", \"(0, x[y])``;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(true && x)``\", \"x``;\\n\", \"x``;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(true && x.y)``\", \"(0, x.y)``;\\n\", \"(0, x.y)``;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(true && x[y])``\", \"(0, x[y])``;\\n\", \"(0, x[y])``;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(false || x)``\", \"x``;\\n\", \"x``;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(false || x.y)``\", \"(0, x.y)``;\\n\", \"(0, x.y)``;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(false || x[y])``\", \"(0, x[y])``;\\n\", \"(0, x[y])``;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(null ?? x)``\", \"x``;\\n\", \"x``;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(null ?? x.y)``\", \"(0, x.y)``;\\n\", \"(0, x.y)``;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(null ?? x[y])``\", \"(0, x[y])``;\\n\", \"(0, x[y])``;\\n\")\n\n\texpectPrintedMangleTarget(t, 2015, \"class Foo { #foo() { return this.#foo`` } }\", `var _Foo_instances, foo_fn;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _Foo_instances);\n  }\n}\n_Foo_instances = new WeakSet(), foo_fn = function() {\n  return __privateMethod(this, _Foo_instances, foo_fn).bind(this)`+\"``\"+`;\n};\n`)\n\n\texpectPrintedMangleTarget(t, 2015, \"class Foo { #foo() { return (0, this.#foo)`` } }\", `var _Foo_instances, foo_fn;\nclass Foo {\n  constructor() {\n    __privateAdd(this, _Foo_instances);\n  }\n}\n_Foo_instances = new WeakSet(), foo_fn = function() {\n  return __privateMethod(this, _Foo_instances, foo_fn)`+\"``\"+`;\n};\n`)\n\n\texpectPrintedNormalAndMangle(t,\n\t\t\"function f(a) { let c = a.b; return c`` }\",\n\t\t\"function f(a) {\\n  let c = a.b;\\n  return c``;\\n}\\n\",\n\t\t\"function f(a) {\\n  return (0, a.b)``;\\n}\\n\")\n\texpectPrintedNormalAndMangle(t,\n\t\t\"function f(a) { let c = a.b; return c`${x}` }\",\n\t\t\"function f(a) {\\n  let c = a.b;\\n  return c`${x}`;\\n}\\n\",\n\t\t\"function f(a) {\\n  return (0, a.b)`${x}`;\\n}\\n\")\n}\n\nfunc TestMangleTypeofIdentifier(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"return typeof (123, x)\", \"return typeof (123, x);\\n\", \"return typeof (0, x);\\n\")\n\texpectPrintedNormalAndMangle(t, \"return typeof (123, x.y)\", \"return typeof (123, x.y);\\n\", \"return typeof x.y;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return typeof (123, x); var x\", \"return typeof (123, x);\\nvar x;\\n\", \"return typeof x;\\nvar x;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"return typeof (true && x)\", \"return typeof (0, x);\\n\", \"return typeof (0, x);\\n\")\n\texpectPrintedNormalAndMangle(t, \"return typeof (true && x.y)\", \"return typeof x.y;\\n\", \"return typeof x.y;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return typeof (true && x); var x\", \"return typeof x;\\nvar x;\\n\", \"return typeof x;\\nvar x;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"return typeof (false || x)\", \"return typeof (0, x);\\n\", \"return typeof (0, x);\\n\")\n\texpectPrintedNormalAndMangle(t, \"return typeof (false || x.y)\", \"return typeof x.y;\\n\", \"return typeof x.y;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return typeof (false || x); var x\", \"return typeof x;\\nvar x;\\n\", \"return typeof x;\\nvar x;\\n\")\n}\n\nfunc TestMangleTypeofEqualsUndefined(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"return typeof x !== 'undefined'\", \"return typeof x !== \\\"undefined\\\";\\n\", \"return typeof x < \\\"u\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"return typeof x != 'undefined'\", \"return typeof x != \\\"undefined\\\";\\n\", \"return typeof x < \\\"u\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"return 'undefined' !== typeof x\", \"return \\\"undefined\\\" !== typeof x;\\n\", \"return typeof x < \\\"u\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"return 'undefined' != typeof x\", \"return \\\"undefined\\\" != typeof x;\\n\", \"return typeof x < \\\"u\\\";\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"return typeof x === 'undefined'\", \"return typeof x === \\\"undefined\\\";\\n\", \"return typeof x > \\\"u\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"return typeof x == 'undefined'\", \"return typeof x == \\\"undefined\\\";\\n\", \"return typeof x > \\\"u\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"return 'undefined' === typeof x\", \"return \\\"undefined\\\" === typeof x;\\n\", \"return typeof x > \\\"u\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"return 'undefined' == typeof x\", \"return \\\"undefined\\\" == typeof x;\\n\", \"return typeof x > \\\"u\\\";\\n\")\n}\n\nfunc TestMangleEquals(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"return typeof x === y\", \"return typeof x === y;\\n\", \"return typeof x === y;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return typeof x !== y\", \"return typeof x !== y;\\n\", \"return typeof x !== y;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return y === typeof x\", \"return y === typeof x;\\n\", \"return y === typeof x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return y !== typeof x\", \"return y !== typeof x;\\n\", \"return y !== typeof x;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"return typeof x === 'string'\", \"return typeof x === \\\"string\\\";\\n\", \"return typeof x == \\\"string\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"return typeof x !== 'string'\", \"return typeof x !== \\\"string\\\";\\n\", \"return typeof x != \\\"string\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"return 'string' === typeof x\", \"return \\\"string\\\" === typeof x;\\n\", \"return typeof x == \\\"string\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"return 'string' !== typeof x\", \"return \\\"string\\\" !== typeof x;\\n\", \"return typeof x != \\\"string\\\";\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"return a === 0\", \"return a === 0;\\n\", \"return a === 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a !== 0\", \"return a !== 0;\\n\", \"return a !== 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return +a === 0\", \"return +a === 0;\\n\", \"return +a == 0;\\n\") // No BigInt hazard\n\texpectPrintedNormalAndMangle(t, \"return +a !== 0\", \"return +a !== 0;\\n\", \"return +a != 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return -a === 0\", \"return -a === 0;\\n\", \"return -a === 0;\\n\") // BigInt hazard\n\texpectPrintedNormalAndMangle(t, \"return -a !== 0\", \"return -a !== 0;\\n\", \"return -a !== 0;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"return a === ''\", \"return a === \\\"\\\";\\n\", \"return a === \\\"\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a !== ''\", \"return a !== \\\"\\\";\\n\", \"return a !== \\\"\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"return (a + '!') === 'a!'\", \"return a + \\\"!\\\" === \\\"a!\\\";\\n\", \"return a + \\\"!\\\" == \\\"a!\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"return (a + '!') !== 'a!'\", \"return a + \\\"!\\\" !== \\\"a!\\\";\\n\", \"return a + \\\"!\\\" != \\\"a!\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"return (a += '!') === 'a!'\", \"return (a += \\\"!\\\") === \\\"a!\\\";\\n\", \"return (a += \\\"!\\\") == \\\"a!\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"return (a += '!') !== 'a!'\", \"return (a += \\\"!\\\") !== \\\"a!\\\";\\n\", \"return (a += \\\"!\\\") != \\\"a!\\\";\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"return a === false\", \"return a === false;\\n\", \"return a === false;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a === true\", \"return a === true;\\n\", \"return a === true;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a !== false\", \"return a !== false;\\n\", \"return a !== false;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a !== true\", \"return a !== true;\\n\", \"return a !== true;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return !a === false\", \"return !a === false;\\n\", \"return !!a;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return !a === true\", \"return !a === true;\\n\", \"return !a;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return !a !== false\", \"return !a !== false;\\n\", \"return !a;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return !a !== true\", \"return !a !== true;\\n\", \"return !!a;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return false === !a\", \"return false === !a;\\n\", \"return !!a;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return true === !a\", \"return true === !a;\\n\", \"return !a;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return false !== !a\", \"return false !== !a;\\n\", \"return !a;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return true !== !a\", \"return true !== !a;\\n\", \"return !!a;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"return a === !b\", \"return a === !b;\\n\", \"return a === !b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a === !b\", \"return a === !b;\\n\", \"return a === !b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a !== !b\", \"return a !== !b;\\n\", \"return a !== !b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a !== !b\", \"return a !== !b;\\n\", \"return a !== !b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return !a === !b\", \"return !a === !b;\\n\", \"return !a == !b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return !a === !b\", \"return !a === !b;\\n\", \"return !a == !b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return !a !== !b\", \"return !a !== !b;\\n\", \"return !a != !b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return !a !== !b\", \"return !a !== !b;\\n\", \"return !a != !b;\\n\")\n\n\t// These have BigInt hazards and should not be changed\n\texpectPrintedNormalAndMangle(t, \"return (a, -1n) !== -1\", \"return (a, -1n) !== -1;\\n\", \"return a, -1n !== -1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return (a, ~1n) !== -1\", \"return (a, ~1n) !== -1;\\n\", \"return a, ~1n !== -1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return (a -= 1n) !== -1\", \"return (a -= 1n) !== -1;\\n\", \"return (a -= 1n) !== -1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return (a *= 1n) !== -1\", \"return (a *= 1n) !== -1;\\n\", \"return (a *= 1n) !== -1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return (a **= 1n) !== -1\", \"return (a **= 1n) !== -1;\\n\", \"return (a **= 1n) !== -1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return (a /= 1n) !== -1\", \"return (a /= 1n) !== -1;\\n\", \"return (a /= 1n) !== -1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return (a %= 1n) !== -1\", \"return (a %= 1n) !== -1;\\n\", \"return (a %= 1n) !== -1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return (a &= 1n) !== -1\", \"return (a &= 1n) !== -1;\\n\", \"return (a &= 1n) !== -1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return (a |= 1n) !== -1\", \"return (a |= 1n) !== -1;\\n\", \"return (a |= 1n) !== -1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return (a ^= 1n) !== -1\", \"return (a ^= 1n) !== -1;\\n\", \"return (a ^= 1n) !== -1;\\n\")\n}\n\nfunc TestMangleUnaryInsideComma(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"return -(a, b)\", \"return -(a, b);\\n\", \"return a, -b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return +(a, b)\", \"return +(a, b);\\n\", \"return a, +b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return ~(a, b)\", \"return ~(a, b);\\n\", \"return a, ~b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return !(a, b)\", \"return !(a, b);\\n\", \"return a, !b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return void (a, b)\", \"return void (a, b);\\n\", \"return a, void b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return typeof (a, b)\", \"return typeof (a, b);\\n\", \"return typeof (a, b);\\n\")\n\texpectPrintedNormalAndMangle(t, \"return delete (a, b)\", \"return delete (a, b);\\n\", \"return delete (a, b);\\n\")\n}\n\nfunc TestMangleBinaryInsideComma(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"(a, b) && c\", \"(a, b) && c;\\n\", \"a, b && c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(a, b) == c\", \"(a, b) == c;\\n\", \"a, b == c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(a, b) + c\", \"(a, b) + c;\\n\", \"a, b + c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a && (b, c)\", \"a && (b, c);\\n\", \"a && (b, c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a == (b, c)\", \"a == (b, c);\\n\", \"a == (b, c);\\n\")\n\texpectPrintedNormalAndMangle(t, \"a + (b, c)\", \"a + (b, c);\\n\", \"a + (b, c);\\n\")\n}\n\nfunc TestMangleUnaryConstantFolding(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"x = +5\", \"x = 5;\\n\", \"x = 5;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = -5\", \"x = -5;\\n\", \"x = -5;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = ~5\", \"x = ~5;\\n\", \"x = -6;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = !5\", \"x = false;\\n\", \"x = false;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = typeof 5\", \"x = \\\"number\\\";\\n\", \"x = \\\"number\\\";\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x = +''\", \"x = 0;\\n\", \"x = 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = +[]\", \"x = 0;\\n\", \"x = 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = +{}\", \"x = NaN;\\n\", \"x = NaN;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = +/1/\", \"x = NaN;\\n\", \"x = NaN;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = +[1]\", \"x = +[1];\\n\", \"x = +[1];\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = +'123'\", \"x = 123;\\n\", \"x = 123;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = +'-123'\", \"x = -123;\\n\", \"x = -123;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = +'0x10'\", \"x = +\\\"0x10\\\";\\n\", \"x = +\\\"0x10\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = +{toString:()=>1}\", \"x = +{ toString: () => 1 };\\n\", \"x = +{ toString: () => 1 };\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = +{valueOf:()=>1}\", \"x = +{ valueOf: () => 1 };\\n\", \"x = +{ valueOf: () => 1 };\\n\")\n}\n\nfunc TestMangleBinaryConstantFolding(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"x = 3 + 6\", \"x = 3 + 6;\\n\", \"x = 9;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 - 6\", \"x = 3 - 6;\\n\", \"x = -3;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 * 6\", \"x = 3 * 6;\\n\", \"x = 18;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 / 6\", \"x = 3 / 6;\\n\", \"x = 3 / 6;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 % 6\", \"x = 3 % 6;\\n\", \"x = 3 % 6;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 ** 6\", \"x = 3 ** 6;\\n\", \"x = 3 ** 6;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x = 0 / 0\", \"x = 0 / 0;\\n\", \"x = NaN;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 123 / 0\", \"x = 123 / 0;\\n\", \"x = Infinity;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 123 / -0\", \"x = 123 / -0;\\n\", \"x = -Infinity;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = -123 / 0\", \"x = -123 / 0;\\n\", \"x = -Infinity;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = -123 / -0\", \"x = -123 / -0;\\n\", \"x = Infinity;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x = 3 < 6\", \"x = 3 < 6;\\n\", \"x = true;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 > 6\", \"x = 3 > 6;\\n\", \"x = false;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 <= 6\", \"x = 3 <= 6;\\n\", \"x = true;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 >= 6\", \"x = 3 >= 6;\\n\", \"x = false;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 == 6\", \"x = false;\\n\", \"x = false;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 != 6\", \"x = true;\\n\", \"x = true;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 === 6\", \"x = false;\\n\", \"x = false;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 !== 6\", \"x = true;\\n\", \"x = true;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x = 'a' < 'b'\", \"x = \\\"a\\\" < \\\"b\\\";\\n\", \"x = true;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 'a' > 'b'\", \"x = \\\"a\\\" > \\\"b\\\";\\n\", \"x = false;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 'a' <= 'b'\", \"x = \\\"a\\\" <= \\\"b\\\";\\n\", \"x = true;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 'a' >= 'b'\", \"x = \\\"a\\\" >= \\\"b\\\";\\n\", \"x = false;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x = 'ab' < 'abc'\", \"x = \\\"ab\\\" < \\\"abc\\\";\\n\", \"x = true;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 'ab' > 'abc'\", \"x = \\\"ab\\\" > \\\"abc\\\";\\n\", \"x = false;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 'ab' <= 'abc'\", \"x = \\\"ab\\\" <= \\\"abc\\\";\\n\", \"x = true;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 'ab' >= 'abc'\", \"x = \\\"ab\\\" >= \\\"abc\\\";\\n\", \"x = false;\\n\")\n\n\t// This checks for comparing by code point vs. by code unit\n\texpectPrintedNormalAndMangle(t, \"x = '𐙩' < 'ﬡ'\", \"x = \\\"𐙩\\\" < \\\"ﬡ\\\";\\n\", \"x = true;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = '𐙩' > 'ﬡ'\", \"x = \\\"𐙩\\\" > \\\"ﬡ\\\";\\n\", \"x = false;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = '𐙩' <= 'ﬡ'\", \"x = \\\"𐙩\\\" <= \\\"ﬡ\\\";\\n\", \"x = true;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = '𐙩' >= 'ﬡ'\", \"x = \\\"𐙩\\\" >= \\\"ﬡ\\\";\\n\", \"x = false;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x = 3 in 6\", \"x = 3 in 6;\\n\", \"x = 3 in 6;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 instanceof 6\", \"x = 3 instanceof 6;\\n\", \"x = 3 instanceof 6;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = (3, 6)\", \"x = (3, 6);\\n\", \"x = 6;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x = 10 << 0\", \"x = 10 << 0;\\n\", \"x = 10;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 10 << 1\", \"x = 10 << 1;\\n\", \"x = 20;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 10 << 16\", \"x = 10 << 16;\\n\", \"x = 655360;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 10 << 17\", \"x = 10 << 17;\\n\", \"x = 10 << 17;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 10 >> 0\", \"x = 10 >> 0;\\n\", \"x = 10;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 10 >> 1\", \"x = 10 >> 1;\\n\", \"x = 5;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 10 >>> 0\", \"x = 10 >>> 0;\\n\", \"x = 10;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 10 >>> 1\", \"x = 10 >>> 1;\\n\", \"x = 5;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = -10 >>> 1\", \"x = -10 >>> 1;\\n\", \"x = -10 >>> 1;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = -1 >>> 0\", \"x = -1 >>> 0;\\n\", \"x = -1 >>> 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = -123 >>> 5\", \"x = -123 >>> 5;\\n\", \"x = -123 >>> 5;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = -123 >>> 6\", \"x = -123 >>> 6;\\n\", \"x = 67108862;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 & 6\", \"x = 3 & 6;\\n\", \"x = 2;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 | 6\", \"x = 3 | 6;\\n\", \"x = 7;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 ^ 6\", \"x = 3 ^ 6;\\n\", \"x = 5;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x = 3 && 6\", \"x = 6;\\n\", \"x = 6;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 || 6\", \"x = 3;\\n\", \"x = 3;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = 3 ?? 6\", \"x = 3;\\n\", \"x = 3;\\n\")\n}\n\nfunc TestMangleNestedLogical(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"(a && b) && c\", \"a && b && c;\\n\", \"a && b && c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a && (b && c)\", \"a && (b && c);\\n\", \"a && b && c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(a || b) && c\", \"(a || b) && c;\\n\", \"(a || b) && c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a && (b || c)\", \"a && (b || c);\\n\", \"a && (b || c);\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"(a || b) || c\", \"a || b || c;\\n\", \"a || b || c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a || (b || c)\", \"a || (b || c);\\n\", \"a || b || c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(a && b) || c\", \"a && b || c;\\n\", \"a && b || c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a || (b && c)\", \"a || b && c;\\n\", \"a || b && c;\\n\")\n}\n\nfunc TestMangleEqualsUndefined(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"return a === void 0\", \"return a === void 0;\\n\", \"return a === void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a !== void 0\", \"return a !== void 0;\\n\", \"return a !== void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return void 0 === a\", \"return void 0 === a;\\n\", \"return a === void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return void 0 !== a\", \"return void 0 !== a;\\n\", \"return a !== void 0;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"return a == void 0\", \"return a == void 0;\\n\", \"return a == null;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a != void 0\", \"return a != void 0;\\n\", \"return a != null;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return void 0 == a\", \"return void 0 == a;\\n\", \"return a == null;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return void 0 != a\", \"return void 0 != a;\\n\", \"return a != null;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"return a === null || a === undefined\", \"return a === null || a === void 0;\\n\", \"return a == null;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a === null || a !== undefined\", \"return a === null || a !== void 0;\\n\", \"return a === null || a !== void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a !== null || a === undefined\", \"return a !== null || a === void 0;\\n\", \"return a !== null || a === void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a === null && a === undefined\", \"return a === null && a === void 0;\\n\", \"return a === null && a === void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a.x === null || a.x === undefined\", \"return a.x === null || a.x === void 0;\\n\", \"return a.x === null || a.x === void 0;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"return a === undefined || a === null\", \"return a === void 0 || a === null;\\n\", \"return a == null;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a === undefined || a !== null\", \"return a === void 0 || a !== null;\\n\", \"return a === void 0 || a !== null;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a !== undefined || a === null\", \"return a !== void 0 || a === null;\\n\", \"return a !== void 0 || a === null;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a === undefined && a === null\", \"return a === void 0 && a === null;\\n\", \"return a === void 0 && a === null;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a.x === undefined || a.x === null\", \"return a.x === void 0 || a.x === null;\\n\", \"return a.x === void 0 || a.x === null;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"return a !== null && a !== undefined\", \"return a !== null && a !== void 0;\\n\", \"return a != null;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a !== null && a === undefined\", \"return a !== null && a === void 0;\\n\", \"return a !== null && a === void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a === null && a !== undefined\", \"return a === null && a !== void 0;\\n\", \"return a === null && a !== void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a !== null || a !== undefined\", \"return a !== null || a !== void 0;\\n\", \"return a !== null || a !== void 0;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a.x !== null && a.x !== undefined\", \"return a.x !== null && a.x !== void 0;\\n\", \"return a.x !== null && a.x !== void 0;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"return a !== undefined && a !== null\", \"return a !== void 0 && a !== null;\\n\", \"return a != null;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a !== undefined && a === null\", \"return a !== void 0 && a === null;\\n\", \"return a !== void 0 && a === null;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a === undefined && a !== null\", \"return a === void 0 && a !== null;\\n\", \"return a === void 0 && a !== null;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a !== undefined || a !== null\", \"return a !== void 0 || a !== null;\\n\", \"return a !== void 0 || a !== null;\\n\")\n\texpectPrintedNormalAndMangle(t, \"return a.x !== undefined && a.x !== null\", \"return a.x !== void 0 && a.x !== null;\\n\", \"return a.x !== void 0 && a.x !== null;\\n\")\n}\n\nfunc TestMangleUnusedFunctionExpressionNames(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"x = function y() {}\", \"x = function y() {\\n};\\n\", \"x = function() {\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = function y() { return y }\", \"x = function y() {\\n  return y;\\n};\\n\", \"x = function y() {\\n  return y;\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = function y() { return eval('y') }\", \"x = function y() {\\n  return eval(\\\"y\\\");\\n};\\n\", \"x = function y() {\\n  return eval(\\\"y\\\");\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = function y() { if (0) return y }\", \"x = function y() {\\n  if (0) return y;\\n};\\n\", \"x = function() {\\n};\\n\")\n}\n\nfunc TestMangleClass(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"class x {['y'] = z}\", \"class x {\\n  [\\\"y\\\"] = z;\\n}\\n\", \"class x {\\n  y = z;\\n}\\n\")\n\texpectPrintedNormalAndMangle(t, \"class x {['y']() {}}\", \"class x {\\n  [\\\"y\\\"]() {\\n  }\\n}\\n\", \"class x {\\n  y() {\\n  }\\n}\\n\")\n\texpectPrintedNormalAndMangle(t, \"class x {get ['y']() {}}\", \"class x {\\n  get [\\\"y\\\"]() {\\n  }\\n}\\n\", \"class x {\\n  get y() {\\n  }\\n}\\n\")\n\texpectPrintedNormalAndMangle(t, \"class x {set ['y'](z) {}}\", \"class x {\\n  set [\\\"y\\\"](z) {\\n  }\\n}\\n\", \"class x {\\n  set y(z) {\\n  }\\n}\\n\")\n\texpectPrintedNormalAndMangle(t, \"class x {async ['y']() {}}\", \"class x {\\n  async [\\\"y\\\"]() {\\n  }\\n}\\n\", \"class x {\\n  async y() {\\n  }\\n}\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"x = class {['y'] = z}\", \"x = class {\\n  [\\\"y\\\"] = z;\\n};\\n\", \"x = class {\\n  y = z;\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = class {['y']() {}}\", \"x = class {\\n  [\\\"y\\\"]() {\\n  }\\n};\\n\", \"x = class {\\n  y() {\\n  }\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = class {get ['y']() {}}\", \"x = class {\\n  get [\\\"y\\\"]() {\\n  }\\n};\\n\", \"x = class {\\n  get y() {\\n  }\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = class {set ['y'](z) {}}\", \"x = class {\\n  set [\\\"y\\\"](z) {\\n  }\\n};\\n\", \"x = class {\\n  set y(z) {\\n  }\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = class {async ['y']() {}}\", \"x = class {\\n  async [\\\"y\\\"]() {\\n  }\\n};\\n\", \"x = class {\\n  async y() {\\n  }\\n};\\n\")\n}\n\nfunc TestMangleUnusedClassExpressionNames(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"x = class y {}\", \"x = class y {\\n};\\n\", \"x = class {\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = class y { foo() { return y } }\", \"x = class y {\\n  foo() {\\n    return y;\\n  }\\n};\\n\", \"x = class y {\\n  foo() {\\n    return y;\\n  }\\n};\\n\")\n\texpectPrintedNormalAndMangle(t, \"x = class y { foo() { if (0) return y } }\", \"x = class y {\\n  foo() {\\n    if (0) return _y;\\n  }\\n};\\n\", \"x = class {\\n  foo() {\\n  }\\n};\\n\")\n}\n\nfunc TestMangleUnused(t *testing.T) {\n\texpectPrintedNormalAndMangle(t, \"null\", \"null;\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"void 0\", \"\", \"\")\n\texpectPrintedNormalAndMangle(t, \"void 0\", \"\", \"\")\n\texpectPrintedNormalAndMangle(t, \"false\", \"false;\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"true\", \"true;\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"123\", \"123;\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"123n\", \"123n;\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"'abc'\", \"\\\"abc\\\";\\n\", \"\\\"abc\\\";\\n\") // Technically a directive, not a string expression\n\texpectPrintedNormalAndMangle(t, \"0; 'abc'\", \"0;\\n\\\"abc\\\";\\n\", \"\")    // Actually a string expression\n\texpectPrintedNormalAndMangle(t, \"'abc'; 'use strict'\", \"\\\"abc\\\";\\n\\\"use strict\\\";\\n\", \"\\\"abc\\\";\\n\\\"use strict\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"function f() { 'abc'; 'use strict' }\", \"function f() {\\n  \\\"abc\\\";\\n  \\\"use strict\\\";\\n}\\n\", \"function f() {\\n  \\\"abc\\\";\\n  \\\"use strict\\\";\\n}\\n\")\n\texpectPrintedNormalAndMangle(t, \"this\", \"this;\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"/regex/\", \"/regex/;\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"(function() {})\", \"(function() {\\n});\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"(() => {})\", \"(() => {\\n});\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"import.meta\", \"import.meta;\\n\", \"\")\n\n\t// Unary operators\n\texpectPrintedNormalAndMangle(t, \"+x\", \"+x;\\n\", \"+x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"-x\", \"-x;\\n\", \"-x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"!x\", \"!x;\\n\", \"x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"~x\", \"~x;\\n\", \"~x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"++x\", \"++x;\\n\", \"++x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"--x\", \"--x;\\n\", \"--x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x++\", \"x++;\\n\", \"x++;\\n\")\n\texpectPrintedNormalAndMangle(t, \"x--\", \"x--;\\n\", \"x--;\\n\")\n\texpectPrintedNormalAndMangle(t, \"void x\", \"void x;\\n\", \"x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete x\", \"delete x;\\n\", \"delete x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"typeof x\", \"typeof x;\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"typeof x()\", \"typeof x();\\n\", \"x();\\n\")\n\texpectPrintedNormalAndMangle(t, \"typeof (0, x)\", \"typeof (0, x);\\n\", \"x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"typeof (0 || x)\", \"typeof (0, x);\\n\", \"x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"typeof (1 && x)\", \"typeof (0, x);\\n\", \"x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"typeof (1 ? x : 0)\", \"typeof (1 ? x : 0);\\n\", \"x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"typeof (0 ? 1 : x)\", \"typeof (0 ? 1 : x);\\n\", \"x;\\n\")\n\n\t// Binary operators\n\texpectPrintedNormalAndMangle(t, \"a + b\", \"a + b;\\n\", \"a + b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a - b\", \"a - b;\\n\", \"a - b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a * b\", \"a * b;\\n\", \"a * b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a / b\", \"a / b;\\n\", \"a / b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a % b\", \"a % b;\\n\", \"a % b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ** b\", \"a ** b;\\n\", \"a ** b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a & b\", \"a & b;\\n\", \"a & b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a | b\", \"a | b;\\n\", \"a | b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a ^ b\", \"a ^ b;\\n\", \"a ^ b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a << b\", \"a << b;\\n\", \"a << b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a >> b\", \"a >> b;\\n\", \"a >> b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a >>> b\", \"a >>> b;\\n\", \"a >>> b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a === b\", \"a === b;\\n\", \"a, b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a !== b\", \"a !== b;\\n\", \"a, b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a == b\", \"a == b;\\n\", \"a == b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a != b\", \"a != b;\\n\", \"a != b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a, b\", \"a, b;\\n\", \"a, b;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"a + '' == b\", \"a + \\\"\\\" == b;\\n\", \"a + \\\"\\\" == b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a + '' != b\", \"a + \\\"\\\" != b;\\n\", \"a + \\\"\\\" != b;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a + '' == b + ''\", \"a + \\\"\\\" == b + \\\"\\\";\\n\", \"a + \\\"\\\", b + \\\"\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a + '' != b + ''\", \"a + \\\"\\\" != b + \\\"\\\";\\n\", \"a + \\\"\\\", b + \\\"\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"a + '' == (b | c)\", \"a + \\\"\\\" == (b | c);\\n\", \"a + \\\"\\\", b | c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a + '' != (b | c)\", \"a + \\\"\\\" != (b | c);\\n\", \"a + \\\"\\\", b | c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"typeof a == b + ''\", \"typeof a == b + \\\"\\\";\\n\", \"b + \\\"\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"typeof a != b + ''\", \"typeof a != b + \\\"\\\";\\n\", \"b + \\\"\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"typeof a == 'b'\", \"typeof a == \\\"b\\\";\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"typeof a != 'b'\", \"typeof a != \\\"b\\\";\\n\", \"\")\n\n\t// Known globals can be removed\n\texpectPrintedNormalAndMangle(t, \"Object\", \"Object;\\n\", \"\")\n\texpectPrintedNormalAndMangle(t, \"Object()\", \"Object();\\n\", \"Object();\\n\")\n\texpectPrintedNormalAndMangle(t, \"NonObject\", \"NonObject;\\n\", \"NonObject;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"var bound; unbound\", \"var bound;\\nunbound;\\n\", \"var bound;\\nunbound;\\n\")\n\texpectPrintedNormalAndMangle(t, \"var bound; bound\", \"var bound;\\nbound;\\n\", \"var bound;\\n\")\n\texpectPrintedNormalAndMangle(t, \"foo, 123, bar\", \"foo, 123, bar;\\n\", \"foo, bar;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"[[foo,, 123,, bar]]\", \"[[foo, , 123, , bar]];\\n\", \"foo, bar;\\n\")\n\texpectPrintedNormalAndMangle(t, \"var bound; [123, unbound, ...unbound, 234]\", \"var bound;\\n[123, unbound, ...unbound, 234];\\n\", \"var bound;\\n[unbound, ...unbound];\\n\")\n\texpectPrintedNormalAndMangle(t, \"var bound; [123, bound, ...bound, 234]\", \"var bound;\\n[123, bound, ...bound, 234];\\n\", \"var bound;\\n[...bound];\\n\")\n\n\texpectPrintedNormalAndMangle(t,\n\t\t\"({foo, x: 123, [y]: 123, z: z, bar})\",\n\t\t\"({ foo, x: 123, [y]: 123, z, bar });\\n\",\n\t\t\"foo, y + \\\"\\\", z, bar;\\n\")\n\texpectPrintedNormalAndMangle(t,\n\t\t\"var bound; ({x: 123, unbound, ...unbound, [unbound]: null, y: 234})\",\n\t\t\"var bound;\\n({ x: 123, unbound, ...unbound, [unbound]: null, y: 234 });\\n\",\n\t\t\"var bound;\\n({ unbound, ...unbound, [unbound]: 0 });\\n\")\n\texpectPrintedNormalAndMangle(t,\n\t\t\"var bound; ({x: 123, bound, ...bound, [bound]: null, y: 234})\",\n\t\t\"var bound;\\n({ x: 123, bound, ...bound, [bound]: null, y: 234 });\\n\",\n\t\t\"var bound;\\n({ ...bound, [bound]: 0 });\\n\")\n\texpectPrintedNormalAndMangle(t,\n\t\t\"var bound; ({x: 123, bound, ...bound, [bound]: foo(), y: 234})\",\n\t\t\"var bound;\\n({ x: 123, bound, ...bound, [bound]: foo(), y: 234 });\\n\",\n\t\t\"var bound;\\n({ ...bound, [bound]: foo() });\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"console.log(1, foo(), bar())\", \"console.log(1, foo(), bar());\\n\", \"console.log(1, foo(), bar());\\n\")\n\texpectPrintedNormalAndMangle(t, \"/* @__PURE__ */ console.log(1, foo(), bar())\", \"/* @__PURE__ */ console.log(1, foo(), bar());\\n\", \"foo(), bar();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"new TestCase(1, foo(), bar())\", \"new TestCase(1, foo(), bar());\\n\", \"new TestCase(1, foo(), bar());\\n\")\n\texpectPrintedNormalAndMangle(t, \"/* @__PURE__ */ new TestCase(1, foo(), bar())\", \"/* @__PURE__ */ new TestCase(1, foo(), bar());\\n\", \"foo(), bar();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"let x = (1, 2)\", \"let x = (1, 2);\\n\", \"let x = 2;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (y, 2)\", \"let x = (y, 2);\\n\", \"let x = (y, 2);\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (/* @__PURE__ */ foo(bar), 2)\", \"let x = (/* @__PURE__ */ foo(bar), 2);\\n\", \"let x = (bar, 2);\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"let x = (2, y)\", \"let x = (2, y);\\n\", \"let x = y;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (2, y)()\", \"let x = (2, y)();\\n\", \"let x = y();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (true && y)()\", \"let x = y();\\n\", \"let x = y();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (false || y)()\", \"let x = y();\\n\", \"let x = y();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (null ?? y)()\", \"let x = y();\\n\", \"let x = y();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (1 ? y : 2)()\", \"let x = (1 ? y : 2)();\\n\", \"let x = y();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (0 ? 1 : y)()\", \"let x = (0 ? 1 : y)();\\n\", \"let x = y();\\n\")\n\n\t// Make sure call targets with \"this\" values are preserved\n\texpectPrintedNormalAndMangle(t, \"let x = (2, y.z)\", \"let x = (2, y.z);\\n\", \"let x = y.z;\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (2, y.z)()\", \"let x = (2, y.z)();\\n\", \"let x = (0, y.z)();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (true && y.z)()\", \"let x = (0, y.z)();\\n\", \"let x = (0, y.z)();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (false || y.z)()\", \"let x = (0, y.z)();\\n\", \"let x = (0, y.z)();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (null ?? y.z)()\", \"let x = (0, y.z)();\\n\", \"let x = (0, y.z)();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (1 ? y.z : 2)()\", \"let x = (1 ? y.z : 2)();\\n\", \"let x = (0, y.z)();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (0 ? 1 : y.z)()\", \"let x = (0 ? 1 : y.z)();\\n\", \"let x = (0, y.z)();\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"let x = (2, y[z])\", \"let x = (2, y[z]);\\n\", \"let x = y[z];\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (2, y[z])()\", \"let x = (2, y[z])();\\n\", \"let x = (0, y[z])();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (true && y[z])()\", \"let x = (0, y[z])();\\n\", \"let x = (0, y[z])();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (false || y[z])()\", \"let x = (0, y[z])();\\n\", \"let x = (0, y[z])();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (null ?? y[z])()\", \"let x = (0, y[z])();\\n\", \"let x = (0, y[z])();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (1 ? y[z] : 2)()\", \"let x = (1 ? y[z] : 2)();\\n\", \"let x = (0, y[z])();\\n\")\n\texpectPrintedNormalAndMangle(t, \"let x = (0 ? 1 : y[z])()\", \"let x = (0 ? 1 : y[z])();\\n\", \"let x = (0, y[z])();\\n\")\n\n\t// Make sure the return value of \"delete\" is preserved\n\texpectPrintedNormalAndMangle(t, \"delete (x)\", \"delete x;\\n\", \"delete x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (x); var x\", \"delete x;\\nvar x;\\n\", \"delete x;\\nvar x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (x.y)\", \"delete x.y;\\n\", \"delete x.y;\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (x[y])\", \"delete x[y];\\n\", \"delete x[y];\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (x?.y)\", \"delete x?.y;\\n\", \"delete x?.y;\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (x?.[y])\", \"delete x?.[y];\\n\", \"delete x?.[y];\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (2, x)\", \"delete (2, x);\\n\", \"delete (0, x);\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (2, x); var x\", \"delete (2, x);\\nvar x;\\n\", \"delete (0, x);\\nvar x;\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (2, x.y)\", \"delete (2, x.y);\\n\", \"delete (0, x.y);\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (2, x[y])\", \"delete (2, x[y]);\\n\", \"delete (0, x[y]);\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (2, x?.y)\", \"delete (2, x?.y);\\n\", \"delete (0, x?.y);\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (2, x?.[y])\", \"delete (2, x?.[y]);\\n\", \"delete (0, x?.[y]);\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (true && x)\", \"delete (0, x);\\n\", \"delete (0, x);\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (false || x)\", \"delete (0, x);\\n\", \"delete (0, x);\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (null ?? x)\", \"delete (0, x);\\n\", \"delete (0, x);\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (1 ? x : 2)\", \"delete (1 ? x : 2);\\n\", \"delete (0, x);\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (0 ? 1 : x)\", \"delete (0 ? 1 : x);\\n\", \"delete (0, x);\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (NaN)\", \"delete NaN;\\n\", \"delete NaN;\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (Infinity)\", \"delete Infinity;\\n\", \"delete Infinity;\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (-Infinity)\", \"delete -Infinity;\\n\", \"delete -Infinity;\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (1, NaN)\", \"delete (1, NaN);\\n\", \"delete (0, NaN);\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (1, Infinity)\", \"delete (1, Infinity);\\n\", \"delete (0, Infinity);\\n\")\n\texpectPrintedNormalAndMangle(t, \"delete (1, -Infinity)\", \"delete (1, -Infinity);\\n\", \"delete -Infinity;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"foo ? 1 : 2\", \"foo ? 1 : 2;\\n\", \"foo;\\n\")\n\texpectPrintedNormalAndMangle(t, \"foo ? 1 : bar\", \"foo ? 1 : bar;\\n\", \"foo || bar;\\n\")\n\texpectPrintedNormalAndMangle(t, \"foo ? bar : 2\", \"foo ? bar : 2;\\n\", \"foo && bar;\\n\")\n\texpectPrintedNormalAndMangle(t, \"foo ? bar : baz\", \"foo ? bar : baz;\\n\", \"foo ? bar : baz;\\n\")\n\n\tfor _, op := range []string{\"&&\", \"||\", \"??\"} {\n\t\texpectPrintedNormalAndMangle(t, \"foo \"+op+\" bar\", \"foo \"+op+\" bar;\\n\", \"foo \"+op+\" bar;\\n\")\n\t\texpectPrintedNormalAndMangle(t, \"var foo; foo \"+op+\" bar\", \"var foo;\\nfoo \"+op+\" bar;\\n\", \"var foo;\\nfoo \"+op+\" bar;\\n\")\n\t\texpectPrintedNormalAndMangle(t, \"var bar; foo \"+op+\" bar\", \"var bar;\\nfoo \"+op+\" bar;\\n\", \"var bar;\\nfoo;\\n\")\n\t\texpectPrintedNormalAndMangle(t, \"var foo, bar; foo \"+op+\" bar\", \"var foo, bar;\\nfoo \"+op+\" bar;\\n\", \"var foo, bar;\\n\")\n\t}\n\n\texpectPrintedNormalAndMangle(t, \"tag`a${b}c${d}e`\", \"tag`a${b}c${d}e`;\\n\", \"tag`a${b}c${d}e`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"`a${b}c${d}e`\", \"`a${b}c${d}e`;\\n\", \"`${b}${d}`;\\n\")\n\n\t// These can't be reduced to string addition due to \"valueOf\". See:\n\t// https://github.com/terser/terser/issues/1128#issuecomment-994209801\n\texpectPrintedNormalAndMangle(t, \"`stuff ${x} ${1}`\", \"`stuff ${x} ${1}`;\\n\", \"`${x}`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"`stuff ${1} ${y}`\", \"`stuff ${1} ${y}`;\\n\", \"`${y}`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"`stuff ${x} ${y}`\", \"`stuff ${x} ${y}`;\\n\", \"`${x}${y}`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"`stuff ${x ? 1 : 2} ${y}`\", \"`stuff ${x ? 1 : 2} ${y}`;\\n\", \"x, `${y}`;\\n\")\n\texpectPrintedNormalAndMangle(t, \"`stuff ${x} ${y ? 1 : 2}`\", \"`stuff ${x} ${y ? 1 : 2}`;\\n\", \"`${x}`, y;\\n\")\n\texpectPrintedNormalAndMangle(t, \"`stuff ${x} ${y ? 1 : 2} ${z}`\", \"`stuff ${x} ${y ? 1 : 2} ${z}`;\\n\", \"`${x}`, y, `${z}`;\\n\")\n\n\texpectPrintedNormalAndMangle(t, \"'a' + b + 'c' + d\", \"\\\"a\\\" + b + \\\"c\\\" + d;\\n\", \"\\\"\\\" + b + d;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a + 'b' + c + 'd'\", \"a + \\\"b\\\" + c + \\\"d\\\";\\n\", \"a + \\\"\\\" + c;\\n\")\n\texpectPrintedNormalAndMangle(t, \"a + b + 'c' + 'd'\", \"a + b + \\\"cd\\\";\\n\", \"a + b + \\\"\\\";\\n\")\n\texpectPrintedNormalAndMangle(t, \"'a' + 'b' + c + d\", \"\\\"ab\\\" + c + d;\\n\", \"\\\"\\\" + c + d;\\n\")\n\texpectPrintedNormalAndMangle(t, \"(a + '') + (b + '')\", \"a + (b + \\\"\\\");\\n\", \"a + (b + \\\"\\\");\\n\")\n\n\t// Make sure identifiers inside \"with\" statements are kept\n\texpectPrintedNormalAndMangle(t, \"with (a) []\", \"with (a) [];\\n\", \"with (a) ;\\n\")\n\texpectPrintedNormalAndMangle(t, \"var a; with (b) a\", \"var a;\\nwith (b) a;\\n\", \"var a;\\nwith (b) a;\\n\")\n}\n\nfunc TestMangleInlineLocals(t *testing.T) {\n\tcheck := func(a string, b string) {\n\t\tt.Helper()\n\t\texpectPrintedMangle(t, \"function wrapper(arg0, arg1) {\"+a+\"}\",\n\t\t\t\"function wrapper(arg0, arg1) {\"+strings.ReplaceAll(\"\\n\"+b, \"\\n\", \"\\n  \")+\"\\n}\\n\")\n\t}\n\n\tcheck(\"var x = 1; return x\", \"var x = 1;\\nreturn x;\")\n\tcheck(\"let x = 1; return x\", \"return 1;\")\n\tcheck(\"const x = 1; return x\", \"return 1;\")\n\n\tcheck(\"let x = 1; if (false) x++; return x\", \"return 1;\")\n\tcheck(\"let x = 1; if (true) x++; return x\", \"let x = 1;\\nreturn x++, x;\")\n\tcheck(\"let x = 1; return x + x\", \"let x = 1;\\nreturn x + x;\")\n\n\t// Can substitute into normal unary operators\n\tcheck(\"let x = 1; return +x\", \"return +1;\")\n\tcheck(\"let x = 1; return -x\", \"return -1;\")\n\tcheck(\"let x = 1; return !x\", \"return !1;\")\n\tcheck(\"let x = 1; return ~x\", \"return ~1;\")\n\tcheck(\"let x = 1; return void x\", \"let x = 1;\")\n\tcheck(\"let x = 1; return typeof x\", \"return typeof 1;\")\n\n\t// Can substitute into template literals\n\tcheck(\"let x = 1; return `<${x}>`\", \"return `<1>`;\")\n\tcheck(\"let x = 1n; return `<${x}>`\", \"return `<1>`;\")\n\tcheck(\"let x = null; return `<${x}>`\", \"return `<null>`;\")\n\tcheck(\"let x = undefined; return `<${x}>`\", \"return `<undefined>`;\")\n\tcheck(\"let x = false; return `<${x}>`\", \"return `<false>`;\")\n\tcheck(\"let x = true; return `<${x}>`\", \"return `<true>`;\")\n\n\t// Check substituting a side-effect free value into normal binary operators\n\tcheck(\"let x = 1; return x + 2\", \"return 1 + 2;\")\n\tcheck(\"let x = 1; return 2 + x\", \"return 2 + 1;\")\n\tcheck(\"let x = 1; return x + arg0\", \"return 1 + arg0;\")\n\tcheck(\"let x = 1; return arg0 + x\", \"return arg0 + 1;\")\n\tcheck(\"let x = 1; return x + fn()\", \"return 1 + fn();\")\n\tcheck(\"let x = 1; return fn() + x\", \"return fn() + 1;\")\n\tcheck(\"let x = 1; return x + undef\", \"return 1 + undef;\")\n\tcheck(\"let x = 1; return undef + x\", \"return undef + 1;\")\n\n\t// Check substituting a value with side-effects into normal binary operators\n\tcheck(\"let x = fn(); return x + 2\", \"return fn() + 2;\")\n\tcheck(\"let x = fn(); return 2 + x\", \"return 2 + fn();\")\n\tcheck(\"let x = fn(); return x + arg0\", \"return fn() + arg0;\")\n\tcheck(\"let x = fn(); return arg0 + x\", \"let x = fn();\\nreturn arg0 + x;\")\n\tcheck(\"let x = fn(); return x + fn2()\", \"return fn() + fn2();\")\n\tcheck(\"let x = fn(); return fn2() + x\", \"let x = fn();\\nreturn fn2() + x;\")\n\tcheck(\"let x = fn(); return x + undef\", \"return fn() + undef;\")\n\tcheck(\"let x = fn(); return undef + x\", \"let x = fn();\\nreturn undef + x;\")\n\n\t// Cannot substitute into mutating unary operators\n\tcheck(\"let x = 1; ++x\", \"let x = 1;\\n++x;\")\n\tcheck(\"let x = 1; --x\", \"let x = 1;\\n--x;\")\n\tcheck(\"let x = 1; x++\", \"let x = 1;\\nx++;\")\n\tcheck(\"let x = 1; x--\", \"let x = 1;\\nx--;\")\n\tcheck(\"let x = 1; delete x\", \"let x = 1;\\ndelete x;\")\n\n\t// Cannot substitute into mutating binary operators\n\tcheck(\"let x = 1; x = 2\", \"let x = 1;\\nx = 2;\")\n\tcheck(\"let x = 1; x += 2\", \"let x = 1;\\nx += 2;\")\n\tcheck(\"let x = 1; x ||= 2\", \"let x = 1;\\nx ||= 2;\")\n\n\t// Can substitute past mutating binary operators when the left operand has no side effects\n\tcheck(\"let x = 1; arg0 = x\", \"arg0 = 1;\")\n\tcheck(\"let x = 1; arg0 += x\", \"arg0 += 1;\")\n\tcheck(\"let x = 1; arg0 ||= x\", \"arg0 ||= 1;\")\n\tcheck(\"let x = fn(); arg0 = x\", \"arg0 = fn();\")\n\tcheck(\"let x = fn(); arg0 += x\", \"let x = fn();\\narg0 += x;\")\n\tcheck(\"let x = fn(); arg0 ||= x\", \"let x = fn();\\narg0 ||= x;\")\n\n\t// Cannot substitute past mutating binary operators when the left operand has side effects\n\tcheck(\"let x = 1; y.z = x\", \"let x = 1;\\ny.z = x;\")\n\tcheck(\"let x = 1; y.z += x\", \"let x = 1;\\ny.z += x;\")\n\tcheck(\"let x = 1; y.z ||= x\", \"let x = 1;\\ny.z ||= x;\")\n\tcheck(\"let x = fn(); y.z = x\", \"let x = fn();\\ny.z = x;\")\n\tcheck(\"let x = fn(); y.z += x\", \"let x = fn();\\ny.z += x;\")\n\tcheck(\"let x = fn(); y.z ||= x\", \"let x = fn();\\ny.z ||= x;\")\n\n\t// Can substitute code without side effects into branches\n\tcheck(\"let x = arg0; return x ? y : z;\", \"return arg0 ? y : z;\")\n\tcheck(\"let x = arg0; return arg1 ? x : y;\", \"return arg1 ? arg0 : y;\")\n\tcheck(\"let x = arg0; return arg1 ? y : x;\", \"return arg1 ? y : arg0;\")\n\tcheck(\"let x = arg0; return x || y;\", \"return arg0 || y;\")\n\tcheck(\"let x = arg0; return x && y;\", \"return arg0 && y;\")\n\tcheck(\"let x = arg0; return x ?? y;\", \"return arg0 ?? y;\")\n\tcheck(\"let x = arg0; return arg1 || x;\", \"return arg1 || arg0;\")\n\tcheck(\"let x = arg0; return arg1 && x;\", \"return arg1 && arg0;\")\n\tcheck(\"let x = arg0; return arg1 ?? x;\", \"return arg1 ?? arg0;\")\n\n\t// Can substitute code without side effects into branches past an expression with side effects\n\tcheck(\"let x = arg0; return y ? x : z;\", \"let x = arg0;\\nreturn y ? x : z;\")\n\tcheck(\"let x = arg0; return y ? z : x;\", \"let x = arg0;\\nreturn y ? z : x;\")\n\tcheck(\"let x = arg0; return (arg1 ? 1 : 2) ? x : 3;\", \"return arg0;\")\n\tcheck(\"let x = arg0; return (arg1 ? 1 : 2) ? 3 : x;\", \"let x = arg0;\\nreturn 3;\")\n\tcheck(\"let x = arg0; return (arg1 ? y : 1) ? x : 2;\", \"let x = arg0;\\nreturn !arg1 || y ? x : 2;\")\n\tcheck(\"let x = arg0; return (arg1 ? 1 : y) ? x : 2;\", \"let x = arg0;\\nreturn arg1 || y ? x : 2;\")\n\tcheck(\"let x = arg0; return (arg1 ? y : 1) ? 2 : x;\", \"let x = arg0;\\nreturn !arg1 || y ? 2 : x;\")\n\tcheck(\"let x = arg0; return (arg1 ? 1 : y) ? 2 : x;\", \"let x = arg0;\\nreturn arg1 || y ? 2 : x;\")\n\tcheck(\"let x = arg0; return y || x;\", \"let x = arg0;\\nreturn y || x;\")\n\tcheck(\"let x = arg0; return y && x;\", \"let x = arg0;\\nreturn y && x;\")\n\tcheck(\"let x = arg0; return y ?? x;\", \"let x = arg0;\\nreturn y ?? x;\")\n\n\t// Cannot substitute code with side effects into branches\n\tcheck(\"let x = fn(); return x ? arg0 : y;\", \"return fn() ? arg0 : y;\")\n\tcheck(\"let x = fn(); return arg0 ? x : y;\", \"let x = fn();\\nreturn arg0 ? x : y;\")\n\tcheck(\"let x = fn(); return arg0 ? y : x;\", \"let x = fn();\\nreturn arg0 ? y : x;\")\n\tcheck(\"let x = fn(); return x || arg0;\", \"return fn() || arg0;\")\n\tcheck(\"let x = fn(); return x && arg0;\", \"return fn() && arg0;\")\n\tcheck(\"let x = fn(); return x ?? arg0;\", \"return fn() ?? arg0;\")\n\tcheck(\"let x = fn(); return arg0 || x;\", \"let x = fn();\\nreturn arg0 || x;\")\n\tcheck(\"let x = fn(); return arg0 && x;\", \"let x = fn();\\nreturn arg0 && x;\")\n\tcheck(\"let x = fn(); return arg0 ?? x;\", \"let x = fn();\\nreturn arg0 ?? x;\")\n\n\t// Test chaining\n\tcheck(\"let x = fn(); let y = x[prop]; let z = y.val; throw z\", \"throw fn()[prop].val;\")\n\tcheck(\"let x = fn(), y = x[prop], z = y.val; throw z\", \"throw fn()[prop].val;\")\n\n\t// Can substitute an initializer with side effects\n\tcheck(\"let x = 0; let y = ++x; return y\",\n\t\t\"let x = 0;\\nreturn ++x;\")\n\n\t// Can substitute an initializer without side effects past an expression without side effects\n\tcheck(\"let x = 0; let y = x; return [x, y]\",\n\t\t\"let x = 0;\\nreturn [x, x];\")\n\n\t// Cannot substitute an initializer with side effects past an expression without side effects\n\tcheck(\"let x = 0; let y = ++x; return [x, y]\",\n\t\t\"let x = 0, y = ++x;\\nreturn [x, y];\")\n\n\t// Cannot substitute an initializer without side effects past an expression with side effects\n\tcheck(\"let x = 0; let y = {valueOf() { x = 1 }}; let z = x; return [y == 1, z]\",\n\t\t\"let x = 0, y = { valueOf() {\\n  x = 1;\\n} }, z = x;\\nreturn [y == 1, z];\")\n\n\t// Cannot inline past a spread operator, since that evaluates code\n\tcheck(\"let x = arg0; return [...x];\", \"return [...arg0];\")\n\tcheck(\"let x = arg0; return [x, ...arg1];\", \"return [arg0, ...arg1];\")\n\tcheck(\"let x = arg0; return [...arg1, x];\", \"let x = arg0;\\nreturn [...arg1, x];\")\n\tcheck(\"let x = arg0; return arg1(...x);\", \"return arg1(...arg0);\")\n\tcheck(\"let x = arg0; return arg1(x, ...arg1);\", \"return arg1(arg0, ...arg1);\")\n\tcheck(\"let x = arg0; return arg1(...arg1, x);\", \"let x = arg0;\\nreturn arg1(...arg1, x);\")\n\n\t// Test various statement kinds\n\tcheck(\"let x = arg0; arg1(x);\", \"arg1(arg0);\")\n\tcheck(\"let x = arg0; throw x;\", \"throw arg0;\")\n\tcheck(\"let x = arg0; return x;\", \"return arg0;\")\n\tcheck(\"let x = arg0; if (x) return 1;\", \"if (arg0) return 1;\")\n\tcheck(\"let x = arg0; switch (x) { case 0: return 1; }\", \"if (arg0 === 0)\\n  return 1;\")\n\tcheck(\"let x = arg0; let y = x; return y + y;\", \"let y = arg0;\\nreturn y + y;\")\n\n\t// Loops must not be substituted into because they evaluate multiple times\n\tcheck(\"let x = arg0; do {} while (x);\", \"let x = arg0;\\ndo\\n  ;\\nwhile (x);\")\n\tcheck(\"let x = arg0; while (x) return 1;\", \"let x = arg0;\\nfor (; x; ) return 1;\")\n\tcheck(\"let x = arg0; for (; x; ) return 1;\", \"let x = arg0;\\nfor (; x; ) return 1;\")\n\n\t// Can substitute an expression without side effects into a branch due to optional chaining\n\tcheck(\"let x = arg0; return arg1?.[x];\", \"return arg1?.[arg0];\")\n\tcheck(\"let x = arg0; return arg1?.(x);\", \"return arg1?.(arg0);\")\n\n\t// Cannot substitute an expression with side effects into a branch due to optional chaining,\n\t// since that would change the expression with side effects from being unconditionally\n\t// evaluated to being conditionally evaluated, which is a behavior change\n\tcheck(\"let x = fn(); return arg1?.[x];\", \"let x = fn();\\nreturn arg1?.[x];\")\n\tcheck(\"let x = fn(); return arg1?.(x);\", \"let x = fn();\\nreturn arg1?.(x);\")\n\n\t// Can substitute an expression past an optional chaining operation, since it has side effects\n\tcheck(\"let x = arg0; return arg1?.a === x;\", \"let x = arg0;\\nreturn arg1?.a === x;\")\n\tcheck(\"let x = arg0; return arg1?.[0] === x;\", \"let x = arg0;\\nreturn arg1?.[0] === x;\")\n\tcheck(\"let x = arg0; return arg1?.(0) === x;\", \"let x = arg0;\\nreturn arg1?.(0) === x;\")\n\tcheck(\"let x = arg0; return arg1?.a[x];\", \"let x = arg0;\\nreturn arg1?.a[x];\")\n\tcheck(\"let x = arg0; return arg1?.a(x);\", \"let x = arg0;\\nreturn arg1?.a(x);\")\n\tcheck(\"let x = arg0; return arg1?.[a][x];\", \"let x = arg0;\\nreturn arg1?.[a][x];\")\n\tcheck(\"let x = arg0; return arg1?.[a](x);\", \"let x = arg0;\\nreturn arg1?.[a](x);\")\n\tcheck(\"let x = arg0; return arg1?.(a)[x];\", \"let x = arg0;\\nreturn arg1?.(a)[x];\")\n\tcheck(\"let x = arg0; return arg1?.(a)(x);\", \"let x = arg0;\\nreturn arg1?.(a)(x);\")\n\n\t// Can substitute into an object as long as there are no side effects\n\t// beforehand. Note that computed properties must call \"toString()\" which\n\t// can have side effects.\n\tcheck(\"let x = arg0; return {x};\", \"return { x: arg0 };\")\n\tcheck(\"let x = arg0; return {x: y, y: x};\", \"let x = arg0;\\nreturn { x: y, y: x };\")\n\tcheck(\"let x = arg0; return {x: arg1, y: x};\", \"return { x: arg1, y: arg0 };\")\n\tcheck(\"let x = arg0; return {[x]: 0};\", \"return { [arg0]: 0 };\")\n\tcheck(\"let x = arg0; return {[y]: x};\", \"let x = arg0;\\nreturn { [y]: x };\")\n\tcheck(\"let x = arg0; return {[arg1]: x};\", \"let x = arg0;\\nreturn { [arg1]: x };\")\n\tcheck(\"let x = arg0; return {y() {}, x};\", \"return { y() {\\n}, x: arg0 };\")\n\tcheck(\"let x = arg0; return {[y]() {}, x};\", \"let x = arg0;\\nreturn { [y]() {\\n}, x };\")\n\tcheck(\"let x = arg0; return {...x};\", \"return { ...arg0 };\")\n\tcheck(\"let x = arg0; return {...x, y};\", \"return { ...arg0, y };\")\n\tcheck(\"let x = arg0; return {x, ...y};\", \"return { x: arg0, ...y };\")\n\tcheck(\"let x = arg0; return {...y, x};\", \"let x = arg0;\\nreturn { ...y, x };\")\n\n\t// Check substitutions into template literals\n\tcheck(\"let x = arg0; return `a${x}b${y}c`;\", \"return `a${arg0}b${y}c`;\")\n\tcheck(\"let x = arg0; return `a${y}b${x}c`;\", \"let x = arg0;\\nreturn `a${y}b${x}c`;\")\n\tcheck(\"let x = arg0; return `a${arg1}b${x}c`;\", \"return `a${arg1}b${arg0}c`;\")\n\tcheck(\"let x = arg0; return x`y`;\", \"return arg0`y`;\")\n\tcheck(\"let x = arg0; return y`a${x}b`;\", \"let x = arg0;\\nreturn y`a${x}b`;\")\n\tcheck(\"let x = arg0; return arg1`a${x}b`;\", \"return arg1`a${arg0}b`;\")\n\tcheck(\"let x = 'x'; return `a${x}b`;\", \"return `axb`;\")\n\n\t// Check substitutions into import expressions\n\tcheck(\"let x = arg0; return import(x);\", \"return import(arg0);\")\n\tcheck(\"let x = arg0; return [import(y), x];\", \"let x = arg0;\\nreturn [import(y), x];\")\n\tcheck(\"let x = arg0; return [import(arg1), x];\", \"return [import(arg1), arg0];\")\n\n\t// Check substitutions into await expressions\n\tcheck(\"return async () => { let x = arg0; await x; };\", \"return async () => {\\n  await arg0;\\n};\")\n\tcheck(\"return async () => { let x = arg0; await y; return x; };\", \"return async () => {\\n  let x = arg0;\\n  return await y, x;\\n};\")\n\tcheck(\"return async () => { let x = arg0; await arg1; return x; };\", \"return async () => {\\n  let x = arg0;\\n  return await arg1, x;\\n};\")\n\n\t// Check substitutions into yield expressions\n\tcheck(\"return function* () { let x = arg0; yield x; };\", \"return function* () {\\n  yield arg0;\\n};\")\n\tcheck(\"return function* () { let x = arg0; yield; return x; };\", \"return function* () {\\n  let x = arg0;\\n  return yield, x;\\n};\")\n\tcheck(\"return function* () { let x = arg0; yield y; return x; };\", \"return function* () {\\n  let x = arg0;\\n  return yield y, x;\\n};\")\n\tcheck(\"return function* () { let x = arg0; yield arg1; return x; };\", \"return function* () {\\n  let x = arg0;\\n  return yield arg1, x;\\n};\")\n\n\t// Make sure that transforms which duplicate identifiers cause\n\t// them to no longer be considered single-use identifiers\n\texpectPrintedMangleTarget(t, 2015, \"(x => { let y = x; throw y ?? z })()\", \"((x) => {\\n  let y = x;\\n  throw y != null ? y : z;\\n})();\\n\")\n\texpectPrintedMangleTarget(t, 2015, \"(x => { let y = x; y.z ??= z })()\", \"((x) => {\\n  var _a;\\n  let y = x;\\n  (_a = y.z) != null || (y.z = z);\\n})();\\n\")\n\texpectPrintedMangleTarget(t, 2015, \"(x => { let y = x; y?.z })()\", \"((x) => {\\n  let y = x;\\n  y == null || y.z;\\n})();\\n\")\n\n\t// Cannot substitute into call targets when it would change \"this\"\n\tcheck(\"let x = arg0; x()\", \"arg0();\")\n\tcheck(\"let x = arg0; (0, x)()\", \"arg0();\")\n\tcheck(\"let x = arg0.foo; x.bar()\", \"arg0.foo.bar();\")\n\tcheck(\"let x = arg0.foo; x[bar]()\", \"arg0.foo[bar]();\")\n\tcheck(\"let x = arg0.foo; x()\", \"let x = arg0.foo;\\nx();\")\n\tcheck(\"let x = arg0[foo]; x()\", \"let x = arg0[foo];\\nx();\")\n\tcheck(\"let x = arg0?.foo; x()\", \"let x = arg0?.foo;\\nx();\")\n\tcheck(\"let x = arg0?.[foo]; x()\", \"let x = arg0?.[foo];\\nx();\")\n\tcheck(\"let x = arg0.foo; (0, x)()\", \"let x = arg0.foo;\\nx();\")\n\tcheck(\"let x = arg0[foo]; (0, x)()\", \"let x = arg0[foo];\\nx();\")\n\tcheck(\"let x = arg0?.foo; (0, x)()\", \"let x = arg0?.foo;\\nx();\")\n\tcheck(\"let x = arg0?.[foo]; (0, x)()\", \"let x = arg0?.[foo];\\nx();\")\n\n\t// Explicitly allow reordering calls that are both marked as \"/* @__PURE__ */\".\n\t// This happens because only two expressions that are free from side-effects\n\t// can be freely reordered, and marking something as \"/* @__PURE__ */\" tells\n\t// us that it has no side effects.\n\tcheck(\"let x = arg0(); arg1() + x\", \"let x = arg0();\\narg1() + x;\")\n\tcheck(\"let x = arg0(); /* @__PURE__ */ arg1() + x\", \"let x = arg0();\\n/* @__PURE__ */ arg1() + x;\")\n\tcheck(\"let x = /* @__PURE__ */ arg0(); arg1() + x\", \"let x = /* @__PURE__ */ arg0();\\narg1() + x;\")\n\tcheck(\"let x = /* @__PURE__ */ arg0(); /* @__PURE__ */ arg1() + x\", \"/* @__PURE__ */ arg1() + /* @__PURE__ */ arg0();\")\n}\n\nfunc TestTrimCodeInDeadControlFlow(t *testing.T) {\n\texpectPrintedMangle(t, \"if (1) a(); else { ; }\", \"a();\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else { b() }\", \"a();\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else { const b = c }\", \"a();\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else { let b }\", \"a();\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else { throw b }\", \"a();\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else { return b }\", \"a();\\n\")\n\texpectPrintedMangle(t, \"b: { if (x) a(); else { break b } }\", \"b:\\n  if (x) a();\\n  else\\n    break b;\\n\")\n\texpectPrintedMangle(t, \"b: { if (1) a(); else { break b } }\", \"a();\\n\")\n\texpectPrintedMangle(t, \"b: { if (0) a(); else { break b } }\", \"\")\n\texpectPrintedMangle(t, \"b: while (1) if (x) a(); else { continue b }\", \"b: for (; ; ) if (x) a();\\nelse\\n  continue b;\\n\")\n\texpectPrintedMangle(t, \"b: while (1) if (1) a(); else { continue b }\", \"for (; ; ) a();\\n\")\n\texpectPrintedMangle(t, \"b: while (1) if (0) a(); else { continue b }\", \"b: for (; ; ) continue b;\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else { class b {} }\", \"a();\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else { debugger }\", \"a();\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else { switch (1) { case 1: b() } }\", \"a();\\n\")\n\n\texpectPrintedMangle(t, \"if (0) {let a = 1} else a()\", \"a();\\n\")\n\texpectPrintedMangle(t, \"if (1) {let a = 1} else a()\", \"{\\n  let a = 1;\\n}\\n\")\n\texpectPrintedMangle(t, \"if (0) a(); else {let a = 1}\", \"{\\n  let a = 1;\\n}\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else {let a = 1}\", \"a();\\n\")\n\n\texpectPrintedMangle(t, \"if (1) a(); else { var a = b }\", \"if (1) a();\\nelse\\n  var a;\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else { var [a] = b }\", \"if (1) a();\\nelse\\n  var a;\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else { var {x: a} = b }\", \"if (1) a();\\nelse\\n  var a;\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else { var [] = b }\", \"a();\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else { var {} = b }\", \"a();\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else { function a() {} }\", \"if (1) a();\\nelse\\n  var a;\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else { for(;;){var a} }\", \"if (1) a();\\nelse\\n  for (; ; )\\n    var a;\\n\")\n\texpectPrintedMangle(t, \"if (1) { a(); b() } else { var a; var b; }\", \"if (1)\\n  a(), b();\\nelse\\n  var a, b;\\n\")\n\texpectPrintedMangle(t, \"if (1) a(); else { switch (1) { case 1: case 2: var a } }\", \"if (1) a();\\nelse\\n  var a;\\n\")\n\n\t// See: https://github.com/evanw/esbuild/issues/4224\n\texpectPrintedMangle(t, \"return 'foo'; try { return 'bar' } catch {}\", \"return \\\"foo\\\";\\n\")\n\texpectPrintedMangle(t, \"return foo = true; try { var foo } catch {}\", \"return foo = true;\\ntry {\\n  var foo;\\n} catch {\\n}\\n\")\n\texpectPrintedMangle(t, \"return foo = true; try {} catch { var foo }\", \"return foo = true;\\ntry {\\n} catch {\\n  var foo;\\n}\\n\")\n\texpectPrintedMangle(t, `\n\t\tasync function test() {\n\t\t\tif (true) return { status: \"disabled_for_development\" };\n\t\t\ttry {\n\t\t\t\tconst response = await httpClients.releasesApi.get();\n\t\t\t\tif (!response.ok) return { status: \"no_release_found\" };\n\t\t\t\tif (response.statusCode === 204) return { status: \"up_to_date\" };\n\t\t\t} catch (error) {\n\t\t\t\treturn { status: \"no_release_found\" };\n\t\t\t}\n\t\t\treturn { status: \"downloading\" };\n\t\t}\n\t`, \"async function test() {\\n  return { status: \\\"disabled_for_development\\\" };\\n}\\n\")\n}\n\nfunc TestPreservedComments(t *testing.T) {\n\texpectPrinted(t, \"//\", \"\")\n\texpectPrinted(t, \"//preserve\", \"\")\n\texpectPrinted(t, \"//@__PURE__\", \"\")\n\texpectPrinted(t, \"//!\", \"//!\\n\")\n\texpectPrinted(t, \"//@license\", \"//@license\\n\")\n\texpectPrinted(t, \"//@preserve\", \"//@preserve\\n\")\n\texpectPrinted(t, \"// @license\", \"// @license\\n\")\n\texpectPrinted(t, \"// @preserve\", \"// @preserve\\n\")\n\n\texpectPrinted(t, \"/**/\", \"\")\n\texpectPrinted(t, \"/*preserve*/\", \"\")\n\texpectPrinted(t, \"/*@__PURE__*/\", \"\")\n\texpectPrinted(t, \"/*!*/\", \"/*!*/\\n\")\n\texpectPrinted(t, \"/*@license*/\", \"/*@license*/\\n\")\n\texpectPrinted(t, \"/*@preserve*/\", \"/*@preserve*/\\n\")\n\texpectPrinted(t, \"/*\\n * @license\\n */\", \"/*\\n * @license\\n */\\n\")\n\texpectPrinted(t, \"/*\\n * @preserve\\n */\", \"/*\\n * @preserve\\n */\\n\")\n\n\texpectPrinted(t, \"foo() //! test\", \"foo();\\n//! test\\n\")\n\texpectPrinted(t, \"//! test\\nfoo()\", \"//! test\\nfoo();\\n\")\n\texpectPrinted(t, \"if (1) //! test\\nfoo()\", \"if (1)\\n  foo();\\n\")\n\texpectPrinted(t, \"if (1) {//! test\\nfoo()}\", \"if (1) {\\n  //! test\\n  foo();\\n}\\n\")\n\texpectPrinted(t, \"if (1) {foo() //! test\\n}\", \"if (1) {\\n  foo();\\n  //! test\\n}\\n\")\n\n\texpectPrinted(t, \"    /*!\\r     * Re-indent test\\r     */\", \"/*!\\n * Re-indent test\\n */\\n\")\n\texpectPrinted(t, \"    /*!\\n     * Re-indent test\\n     */\", \"/*!\\n * Re-indent test\\n */\\n\")\n\texpectPrinted(t, \"    /*!\\r\\n     * Re-indent test\\r\\n     */\", \"/*!\\n * Re-indent test\\n */\\n\")\n\texpectPrinted(t, \"    /*!\\u2028     * Re-indent test\\u2028     */\", \"/*!\\n * Re-indent test\\n */\\n\")\n\texpectPrinted(t, \"    /*!\\u2029     * Re-indent test\\u2029     */\", \"/*!\\n * Re-indent test\\n */\\n\")\n\n\texpectPrinted(t, \"\\t\\t/*!\\r\\t\\t * Re-indent test\\r\\t\\t */\", \"/*!\\n * Re-indent test\\n */\\n\")\n\texpectPrinted(t, \"\\t\\t/*!\\n\\t\\t * Re-indent test\\n\\t\\t */\", \"/*!\\n * Re-indent test\\n */\\n\")\n\texpectPrinted(t, \"\\t\\t/*!\\r\\n\\t\\t * Re-indent test\\r\\n\\t\\t */\", \"/*!\\n * Re-indent test\\n */\\n\")\n\texpectPrinted(t, \"\\t\\t/*!\\u2028\\t\\t * Re-indent test\\u2028\\t\\t */\", \"/*!\\n * Re-indent test\\n */\\n\")\n\texpectPrinted(t, \"\\t\\t/*!\\u2029\\t\\t * Re-indent test\\u2029\\t\\t */\", \"/*!\\n * Re-indent test\\n */\\n\")\n\n\texpectPrinted(t, \"x\\r    /*!\\r     * Re-indent test\\r     */\", \"x;\\n/*!\\n * Re-indent test\\n */\\n\")\n\texpectPrinted(t, \"x\\n    /*!\\n     * Re-indent test\\n     */\", \"x;\\n/*!\\n * Re-indent test\\n */\\n\")\n\texpectPrinted(t, \"x\\r\\n    /*!\\r\\n     * Re-indent test\\r\\n     */\", \"x;\\n/*!\\n * Re-indent test\\n */\\n\")\n\texpectPrinted(t, \"x\\u2028    /*!\\u2028     * Re-indent test\\u2028     */\", \"x;\\n/*!\\n * Re-indent test\\n */\\n\")\n\texpectPrinted(t, \"x\\u2029    /*!\\u2029     * Re-indent test\\u2029     */\", \"x;\\n/*!\\n * Re-indent test\\n */\\n\")\n}\n\nfunc TestUnicodeWhitespace(t *testing.T) {\n\twhitespace := []string{\n\t\t\"\\u0009\", // character tabulation\n\t\t\"\\u000B\", // line tabulation\n\t\t\"\\u000C\", // form feed\n\t\t\"\\u0020\", // space\n\t\t\"\\u00A0\", // no-break space\n\t\t\"\\u1680\", // ogham space mark\n\t\t\"\\u2000\", // en quad\n\t\t\"\\u2001\", // em quad\n\t\t\"\\u2002\", // en space\n\t\t\"\\u2003\", // em space\n\t\t\"\\u2004\", // three-per-em space\n\t\t\"\\u2005\", // four-per-em space\n\t\t\"\\u2006\", // six-per-em space\n\t\t\"\\u2007\", // figure space\n\t\t\"\\u2008\", // punctuation space\n\t\t\"\\u2009\", // thin space\n\t\t\"\\u200A\", // hair space\n\t\t\"\\u202F\", // narrow no-break space\n\t\t\"\\u205F\", // medium mathematical space\n\t\t\"\\u3000\", // ideographic space\n\t\t\"\\uFEFF\", // zero width non-breaking space\n\t}\n\n\t// Test \"js_lexer.Next()\"\n\texpectParseError(t, \"var\\u0008x\", \"<stdin>: ERROR: Expected identifier but found \\\"\\\\b\\\"\\n\")\n\tfor _, s := range whitespace {\n\t\texpectPrinted(t, \"var\"+s+\"x\", \"var x;\\n\")\n\t}\n\n\t// Test \"js_lexer.NextInsideJSXElement()\"\n\texpectParseErrorJSX(t, \"<x\\u0008y/>\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\"\\\\b\\\"\\n\")\n\tfor _, s := range whitespace {\n\t\texpectPrintedJSX(t, \"<x\"+s+\"y/>\", \"<x y />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", { y: true });\\n\")\n\t}\n\n\t// Test \"js_lexer.NextJSXElementChild()\"\n\texpectPrintedJSX(t, \"<x>\\n\\u0008\\n</x>\", \"<x>\\n\\u0008\\n</x>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", null, \\\"\\\\b\\\");\\n\")\n\tfor _, s := range whitespace {\n\t\texpectPrintedJSX(t, \"<x>\\n\"+s+\"\\n</x>\", \"<x>\\n\"+s+\"\\n</x>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", null);\\n\")\n\t}\n\n\t// Test \"fixWhitespaceAndDecodeJSXEntities()\"\n\texpectPrintedJSX(t, \"<x>\\n\\u0008&quot;\\n</x>\", \"<x>\\n\\u0008&quot;\\n</x>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", null, '\\\\b\\\"');\\n\")\n\tfor _, s := range whitespace {\n\t\texpectPrintedJSX(t, \"<x>\\n\"+s+\"&quot;\\n</x>\", \"<x>\\n\"+s+\"&quot;\\n</x>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", null, '\\\"');\\n\")\n\t}\n\n\tinvalidWhitespaceInJS := []string{\n\t\t\"\\u0085\", // next line (nel)\n\t}\n\n\t// Test \"js_lexer.Next()\"\n\tfor _, s := range invalidWhitespaceInJS {\n\t\tr, _ := helpers.DecodeWTF8Rune(s)\n\t\texpectParseError(t, \"var\"+s+\"x\", fmt.Sprintf(\"<stdin>: ERROR: Expected identifier but found \\\"\\\\u%04x\\\"\\n\", r))\n\t}\n\n\t// Test \"js_lexer.NextInsideJSXElement()\"\n\tfor _, s := range invalidWhitespaceInJS {\n\t\tr, _ := helpers.DecodeWTF8Rune(s)\n\t\texpectParseErrorJSX(t, \"<x\"+s+\"y/>\", fmt.Sprintf(\"<stdin>: ERROR: Expected \\\">\\\" but found \\\"\\\\u%04x\\\"\\n\", r))\n\t}\n\n\t// Test \"js_lexer.NextJSXElementChild()\"\n\tfor _, s := range invalidWhitespaceInJS {\n\t\texpectPrintedJSX(t, \"<x>\\n\"+s+\"\\n</x>\", \"<x>\\n\"+s+\"\\n</x>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", null, \\\"\"+s+\"\\\");\\n\")\n\t}\n\n\t// Test \"fixWhitespaceAndDecodeJSXEntities()\"\n\tfor _, s := range invalidWhitespaceInJS {\n\t\texpectPrintedJSX(t, \"<x>\\n\"+s+\"&quot;\\n</x>\", \"<x>\\n\"+s+\"&quot;\\n</x>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", null, '\"+s+\"\\\"');\\n\")\n\t}\n}\n\n// Make sure we can handle the unicode replacement character \"�\" in various places\nfunc TestReplacementCharacter(t *testing.T) {\n\texpectPrinted(t, \"//\\uFFFD\\n123\", \"123;\\n\")\n\texpectPrinted(t, \"/*\\uFFFD*/123\", \"123;\\n\")\n\n\texpectPrinted(t, \"'\\uFFFD'\", \"\\\"\\uFFFD\\\";\\n\")\n\texpectPrinted(t, \"\\\"\\uFFFD\\\"\", \"\\\"\\uFFFD\\\";\\n\")\n\texpectPrinted(t, \"`\\uFFFD`\", \"`\\uFFFD`;\\n\")\n\texpectPrinted(t, \"/\\uFFFD/\", \"/\\uFFFD/;\\n\")\n\n\texpectPrintedJSX(t, \"<a>\\uFFFD</a>\", \"<a>\\uFFFD</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"\\uFFFD\\\");\\n\")\n}\n\nfunc TestNewTarget(t *testing.T) {\n\texpectPrinted(t, \"function f() { new.target }\", \"function f() {\\n  new.target;\\n}\\n\")\n\texpectPrinted(t, \"function f() { (new.target) }\", \"function f() {\\n  new.target;\\n}\\n\")\n\texpectPrinted(t, \"function f() { () => new.target }\", \"function f() {\\n  () => new.target;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { x = new.target }\", \"class Foo {\\n  x = new.target;\\n}\\n\")\n\n\texpectParseError(t, \"new.t\\\\u0061rget\", \"<stdin>: ERROR: Unexpected \\\"t\\\\\\\\u0061rget\\\"\\n\")\n\texpectParseError(t, \"new.target\", \"<stdin>: ERROR: Cannot use \\\"new.target\\\" here:\\n\")\n\texpectParseError(t, \"() => new.target\", \"<stdin>: ERROR: Cannot use \\\"new.target\\\" here:\\n\")\n\texpectParseError(t, \"class Foo { [new.target] }\", \"<stdin>: ERROR: Cannot use \\\"new.target\\\" here:\\n\")\n}\n\nfunc TestJSX(t *testing.T) {\n\texpectParseErrorJSX(t, \"<div>></div>\",\n\t\t\"<stdin>: WARNING: The character \\\">\\\" is not valid inside a JSX element\\n\"+\n\t\t\t\"NOTE: Did you mean to escape it as \\\"{'>'}\\\" instead?\\n\")\n\texpectParseErrorJSX(t, \"<div>{1}}</div>\",\n\t\t\"<stdin>: WARNING: The character \\\"}\\\" is not valid inside a JSX element\\n\"+\n\t\t\t\"NOTE: Did you mean to escape it as \\\"{'}'}\\\" instead?\\n\")\n\texpectPrintedJSX(t, \"<div>></div>\", \"<div>></div>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"div\\\", null, \\\">\\\");\\n\")\n\texpectPrintedJSX(t, \"<div>{1}}</div>\", \"<div>{1}}</div>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"div\\\", null, 1, \\\"}\\\");\\n\")\n\n\texpectParseError(t, \"<a/>\", \"<stdin>: ERROR: The JSX syntax extension is not currently enabled\\n\"+\n\t\t\"NOTE: The esbuild loader for this file is currently set to \\\"js\\\" but it must be set to \\\"jsx\\\" to be able to parse JSX syntax. \"+\n\t\t\"You can use 'Loader: map[string]api.Loader{\\\".js\\\": api.LoaderJSX}' to do that.\\n\")\n\n\texpectPrintedJSX(t, \"<a/>\", \"<a />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<a></a>\", \"<a />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<A/>\", \"<A />;\\n\", \"/* @__PURE__ */ React.createElement(A, null);\\n\")\n\texpectPrintedJSX(t, \"<a.b/>\", \"<a.b />;\\n\", \"/* @__PURE__ */ React.createElement(a.b, null);\\n\")\n\texpectPrintedJSX(t, \"<_a/>\", \"<_a />;\\n\", \"/* @__PURE__ */ React.createElement(_a, null);\\n\")\n\texpectPrintedJSX(t, \"<a-b/>\", \"<a-b />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a-b\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<a0/>\", \"<a0 />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a0\\\", null);\\n\")\n\texpectParseErrorJSX(t, \"<0a/>\", \"<stdin>: ERROR: Expected identifier but found \\\"0\\\"\\n\")\n\n\texpectPrintedJSX(t, \"<a b/>\", \"<a b />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: true });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"\\\\\\\"/>\", \"<a b=\\\"\\\\\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"\\\\\\\\\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"<>\\\"/>\", \"<a b=\\\"<>\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"<>\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"&lt;&gt;\\\"/>\", \"<a b=\\\"&lt;&gt;\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"<>\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"&wrong;\\\"/>\", \"<a b=\\\"&wrong;\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"&wrong;\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b={1, 2}/>\", \"<a b={(1, 2)} />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: (1, 2) });\\n\")\n\texpectPrintedJSX(t, \"<a b={<c/>}/>\", \"<a b={<c />} />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: /* @__PURE__ */ React.createElement(\\\"c\\\", null) });\\n\")\n\texpectPrintedJSX(t, \"<a {...props}/>\", \"<a {...props} />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { ...props });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"🙂\\\"/>\", \"<a b=\\\"🙂\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"🙂\\\" });\\n\")\n\n\texpectPrintedJSX(t, \"<a>\\n</a>\", \"<a>\\n</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<a>123</a>\", \"<a>123</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"123\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>}</a>\", \"<a>}</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"}\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>=</a>\", \"<a>=</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"=\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>></a>\", \"<a>></a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\">\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>>=</a>\", \"<a>>=</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\">=\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>>></a>\", \"<a>>></a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\">>\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>{}</a>\", \"<a>{}</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<a>{/* comment */}</a>\", \"<a>{\\n  /* comment */\\n}</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<a>b{}</a>\", \"<a>b{}</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>b{/* comment */}</a>\", \"<a>b{\\n  /* comment */\\n}</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>{}c</a>\", \"<a>{}c</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"c\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>{/* comment */}c</a>\", \"<a>{\\n  /* comment */\\n}c</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"c\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>b{}c</a>\", \"<a>b{}c</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\", \\\"c\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>b{/* comment */}c</a>\", \"<a>b{\\n  /* comment */\\n}c</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\", \\\"c\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>{1, 2}</a>\", \"<a>{(1, 2)}</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, (1, 2));\\n\")\n\texpectPrintedJSX(t, \"<a>&lt;&gt;</a>\", \"<a>&lt;&gt;</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"<>\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>&wrong;</a>\", \"<a>&wrong;</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"&wrong;\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>🙂</a>\", \"<a>🙂</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"🙂\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>{...children}</a>\", \"<a>{...children}</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, ...children);\\n\")\n\n\t// Note: The TypeScript compiler and Babel disagree. This matches TypeScript.\n\texpectPrintedJSX(t, \"<a b=\\\"   c\\\"/>\", \"<a b=\\\"   c\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"   c\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"   \\nc\\\"/>\", \"<a b=\\\"   \\nc\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"   \\\\nc\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"\\n   c\\\"/>\", \"<a b=\\\"\\n   c\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"\\\\n   c\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"c   \\\"/>\", \"<a b=\\\"c   \\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"c   \\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"c   \\n\\\"/>\", \"<a b=\\\"c   \\n\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"c   \\\\n\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"c\\n   \\\"/>\", \"<a b=\\\"c\\n   \\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"c\\\\n   \\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"c   d\\\"/>\", \"<a b=\\\"c   d\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"c   d\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"c   \\nd\\\"/>\", \"<a b=\\\"c   \\nd\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"c   \\\\nd\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"c\\n   d\\\"/>\", \"<a b=\\\"c\\n   d\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"c\\\\n   d\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"   c\\\"/>\", \"<a b=\\\"   c\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"   c\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"   \\nc\\\"/>\", \"<a b=\\\"   \\nc\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"   \\\\nc\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"\\n   c\\\"/>\", \"<a b=\\\"\\n   c\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"\\\\n   c\\\" });\\n\")\n\n\t// Same test as above except with multi-byte Unicode characters\n\texpectPrintedJSX(t, \"<a b=\\\"   🙂\\\"/>\", \"<a b=\\\"   🙂\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"   🙂\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"   \\n🙂\\\"/>\", \"<a b=\\\"   \\n🙂\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"   \\\\n🙂\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"\\n   🙂\\\"/>\", \"<a b=\\\"\\n   🙂\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"\\\\n   🙂\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"🙂   \\\"/>\", \"<a b=\\\"🙂   \\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"🙂   \\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"🙂   \\n\\\"/>\", \"<a b=\\\"🙂   \\n\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"🙂   \\\\n\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"🙂\\n   \\\"/>\", \"<a b=\\\"🙂\\n   \\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"🙂\\\\n   \\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"🙂   🍕\\\"/>\", \"<a b=\\\"🙂   🍕\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"🙂   🍕\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"🙂   \\n🍕\\\"/>\", \"<a b=\\\"🙂   \\n🍕\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"🙂   \\\\n🍕\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"🙂\\n   🍕\\\"/>\", \"<a b=\\\"🙂\\n   🍕\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"🙂\\\\n   🍕\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"   🙂\\\"/>\", \"<a b=\\\"   🙂\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"   🙂\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"   \\n🙂\\\"/>\", \"<a b=\\\"   \\n🙂\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"   \\\\n🙂\\\" });\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"\\n   🙂\\\"/>\", \"<a b=\\\"\\n   🙂\\\" />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: \\\"\\\\n   🙂\\\" });\\n\")\n\n\texpectPrintedJSX(t, \"<a>   b</a>\", \"<a>   b</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"   b\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>   \\nb</a>\", \"<a>   \\nb</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>\\n   b</a>\", \"<a>\\n   b</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>b   </a>\", \"<a>b   </a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b   \\\");\\n\")\n\texpectPrintedJSX(t, \"<a>b   \\n</a>\", \"<a>b   \\n</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>b\\n   </a>\", \"<a>b\\n   </a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>b   c</a>\", \"<a>b   c</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b   c\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>b   \\nc</a>\", \"<a>b   \\nc</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b c\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>b\\n   c</a>\", \"<a>b\\n   c</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b c\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>   b</a>\", \"<a>   b</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"   b\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>   \\nb</a>\", \"<a>   \\nb</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>\\n   b</a>\", \"<a>\\n   b</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\");\\n\")\n\n\t// Same test as above except with multi-byte Unicode characters\n\texpectPrintedJSX(t, \"<a>   🙂</a>\", \"<a>   🙂</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"   🙂\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>   \\n🙂</a>\", \"<a>   \\n🙂</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"🙂\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>\\n   🙂</a>\", \"<a>\\n   🙂</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"🙂\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>🙂   </a>\", \"<a>🙂   </a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"🙂   \\\");\\n\")\n\texpectPrintedJSX(t, \"<a>🙂   \\n</a>\", \"<a>🙂   \\n</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"🙂\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>🙂\\n   </a>\", \"<a>🙂\\n   </a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"🙂\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>🙂   🍕</a>\", \"<a>🙂   🍕</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"🙂   🍕\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>🙂   \\n🍕</a>\", \"<a>🙂   \\n🍕</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"🙂 🍕\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>🙂\\n   🍕</a>\", \"<a>🙂\\n   🍕</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"🙂 🍕\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>   🙂</a>\", \"<a>   🙂</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"   🙂\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>   \\n🙂</a>\", \"<a>   \\n🙂</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"🙂\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>\\n   🙂</a>\", \"<a>\\n   🙂</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"🙂\\\");\\n\")\n\n\t// \"<a>{x}</b></a>\" with all combinations of \"\", \" \", and \"\\n\" inserted in between\n\texpectPrintedJSX(t, \"<a>{x}<b/></a>;\", \"<a>{x}<b /></a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a>\\n{x}<b/></a>;\", \"<a>\\n{x}<b /></a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a>{x}\\n<b/></a>;\", \"<a>{x}\\n<b /></a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a>\\n{x}\\n<b/></a>;\", \"<a>\\n{x}\\n<b /></a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a>{x}<b/>\\n</a>;\", \"<a>{x}<b />\\n</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a>\\n{x}<b/>\\n</a>;\", \"<a>\\n{x}<b />\\n</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a>{x}\\n<b/>\\n</a>;\", \"<a>{x}\\n<b />\\n</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a>\\n{x}\\n<b/>\\n</a>;\", \"<a>\\n{x}\\n<b />\\n</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a> {x}<b/></a>;\", \"<a> {x}<b /></a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\" \\\", x, /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a> {x}\\n<b/></a>;\", \"<a> {x}\\n<b /></a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\" \\\", x, /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a> {x}<b/>\\n</a>;\", \"<a> {x}<b />\\n</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\" \\\", x, /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a> {x}\\n<b/>\\n</a>;\", \"<a> {x}\\n<b />\\n</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\" \\\", x, /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a>{x} <b/></a>;\", \"<a>{x} <b /></a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, \\\" \\\", /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a>\\n{x} <b/></a>;\", \"<a>\\n{x} <b /></a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, \\\" \\\", /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a>{x} <b/>\\n</a>;\", \"<a>{x} <b />\\n</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, \\\" \\\", /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a>\\n{x} <b/>\\n</a>;\", \"<a>\\n{x} <b />\\n</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, \\\" \\\", /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a> {x} <b/></a>;\", \"<a> {x} <b /></a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\" \\\", x, \\\" \\\", /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a> {x} <b/>\\n</a>;\", \"<a> {x} <b />\\n</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\" \\\", x, \\\" \\\", /* @__PURE__ */ React.createElement(\\\"b\\\", null));\\n\")\n\texpectPrintedJSX(t, \"<a>{x}<b/> </a>;\", \"<a>{x}<b /> </a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, /* @__PURE__ */ React.createElement(\\\"b\\\", null), \\\" \\\");\\n\")\n\texpectPrintedJSX(t, \"<a>\\n{x}<b/> </a>;\", \"<a>\\n{x}<b /> </a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, /* @__PURE__ */ React.createElement(\\\"b\\\", null), \\\" \\\");\\n\")\n\texpectPrintedJSX(t, \"<a>{x}\\n<b/> </a>;\", \"<a>{x}\\n<b /> </a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, /* @__PURE__ */ React.createElement(\\\"b\\\", null), \\\" \\\");\\n\")\n\texpectPrintedJSX(t, \"<a>\\n{x}\\n<b/> </a>;\", \"<a>\\n{x}\\n<b /> </a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, /* @__PURE__ */ React.createElement(\\\"b\\\", null), \\\" \\\");\\n\")\n\texpectPrintedJSX(t, \"<a> {x}<b/> </a>;\", \"<a> {x}<b /> </a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\" \\\", x, /* @__PURE__ */ React.createElement(\\\"b\\\", null), \\\" \\\");\\n\")\n\texpectPrintedJSX(t, \"<a> {x}\\n<b/> </a>;\", \"<a> {x}\\n<b /> </a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\" \\\", x, /* @__PURE__ */ React.createElement(\\\"b\\\", null), \\\" \\\");\\n\")\n\texpectPrintedJSX(t, \"<a>{x} <b/> </a>;\", \"<a>{x} <b /> </a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, \\\" \\\", /* @__PURE__ */ React.createElement(\\\"b\\\", null), \\\" \\\");\\n\")\n\texpectPrintedJSX(t, \"<a>\\n{x} <b/> </a>;\", \"<a>\\n{x} <b /> </a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, x, \\\" \\\", /* @__PURE__ */ React.createElement(\\\"b\\\", null), \\\" \\\");\\n\")\n\texpectPrintedJSX(t, \"<a> {x} <b/> </a>;\", \"<a> {x} <b /> </a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\" \\\", x, \\\" \\\", /* @__PURE__ */ React.createElement(\\\"b\\\", null), \\\" \\\");\\n\")\n\n\texpectParseErrorJSX(t, \"<a b=true/>\", \"<stdin>: ERROR: Expected \\\"{\\\" but found \\\"true\\\"\\n\")\n\texpectParseErrorJSX(t, \"</a>\", \"<stdin>: ERROR: Expected identifier but found \\\"/\\\"\\n\")\n\texpectParseErrorJSX(t, \"<></b>\",\n\t\t\"<stdin>: ERROR: Unexpected closing \\\"b\\\" tag does not match opening fragment tag\\n<stdin>: NOTE: The opening fragment tag is here:\\n\")\n\texpectParseErrorJSX(t, \"<a></>\",\n\t\t\"<stdin>: ERROR: Unexpected closing fragment tag does not match opening \\\"a\\\" tag\\n<stdin>: NOTE: The opening \\\"a\\\" tag is here:\\n\")\n\texpectParseErrorJSX(t, \"<a></b>\",\n\t\t\"<stdin>: ERROR: Unexpected closing \\\"b\\\" tag does not match opening \\\"a\\\" tag\\n<stdin>: NOTE: The opening \\\"a\\\" tag is here:\\n\")\n\texpectParseErrorJSX(t, \"<\\na\\n.\\nb\\n>\\n<\\n/\\nc\\n.\\nd\\n>\",\n\t\t\"<stdin>: ERROR: Unexpected closing \\\"c.d\\\" tag does not match opening \\\"a.b\\\" tag\\n<stdin>: NOTE: The opening \\\"a.b\\\" tag is here:\\n\")\n\texpectParseErrorJSX(t, \"<a-b.c>\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\".\\\"\\n\")\n\texpectParseErrorJSX(t, \"<a.b-c>\", \"<stdin>: ERROR: Unexpected \\\"-\\\"\\n\")\n\n\texpectPrintedJSX(t, \"< /**/ a/>\", \"<a />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"< //\\n a/>\", \"<a />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<a /**/ />\", \"<a />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<a //\\n />\", \"<a />;\\n\", \"/* @__PURE__ */ React.createElement(\\n  \\\"a\\\",\\n  null\\n);\\n\")\n\texpectPrintedJSX(t, \"<a/ /**/ >\", \"<a />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<a/ //\\n >\", \"<a />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\n\texpectPrintedJSX(t, \"<a>b< /**/ /a>\", \"<a>b</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>b< //\\n /a>\", \"<a>b</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>b</ /**/ a>\", \"<a>b</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>b</ //\\n a>\", \"<a>b</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>b</a /**/ >\", \"<a>b</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\");\\n\")\n\texpectPrintedJSX(t, \"<a>b</a //\\n >\", \"<a>b</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"b\\\");\\n\")\n\n\texpectPrintedJSX(t, \"<a> /**/ </a>\", \"<a> /**/ </a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\" /**/ \\\");\\n\")\n\texpectPrintedJSX(t, \"<a> //\\n </a>\", \"<a> //\\n </a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\" //\\\");\\n\")\n\n\t// Unicode tests\n\texpectPrintedJSX(t, \"<\\U00020000/>\", \"<\\U00020000 />;\\n\", \"/* @__PURE__ */ React.createElement(\\U00020000, null);\\n\")\n\texpectPrintedJSX(t, \"<a>\\U00020000</a>\", \"<a>\\U00020000</a>;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null, \\\"\\U00020000\\\");\\n\")\n\texpectPrintedJSX(t, \"<a \\U00020000={0}/>\", \"<a \\U00020000={0} />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { \\\"\\U00020000\\\": 0 });\\n\")\n\n\t// Comment tests\n\texpectParseErrorJSX(t, \"<a /* />\", \"<stdin>: ERROR: Expected \\\"*/\\\" to terminate multi-line comment\\n<stdin>: NOTE: The multi-line comment starts here:\\n\")\n\texpectParseErrorJSX(t, \"<a /*/ />\", \"<stdin>: ERROR: Expected \\\"*/\\\" to terminate multi-line comment\\n<stdin>: NOTE: The multi-line comment starts here:\\n\")\n\texpectParseErrorJSX(t, \"<a // />\", \"<stdin>: ERROR: Expected \\\">\\\" but found end of file\\n\")\n\texpectParseErrorJSX(t, \"<a /**/>\", \"<stdin>: ERROR: Unexpected end of file before a closing \\\"a\\\" tag\\n<stdin>: NOTE: The opening \\\"a\\\" tag is here:\\n\")\n\texpectParseErrorJSX(t, \"<a /**/ />\", \"\")\n\texpectParseErrorJSX(t, \"<a // \\n />\", \"\")\n\texpectParseErrorJSX(t, \"<a b/* />\", \"<stdin>: ERROR: Expected \\\"*/\\\" to terminate multi-line comment\\n<stdin>: NOTE: The multi-line comment starts here:\\n\")\n\texpectParseErrorJSX(t, \"<a b/*/ />\", \"<stdin>: ERROR: Expected \\\"*/\\\" to terminate multi-line comment\\n<stdin>: NOTE: The multi-line comment starts here:\\n\")\n\texpectParseErrorJSX(t, \"<a b// />\", \"<stdin>: ERROR: Expected \\\">\\\" but found end of file\\n\")\n\texpectParseErrorJSX(t, \"<a b/**/>\", \"<stdin>: ERROR: Unexpected end of file before a closing \\\"a\\\" tag\\n<stdin>: NOTE: The opening \\\"a\\\" tag is here:\\n\")\n\texpectParseErrorJSX(t, \"<a b/**/ />\", \"\")\n\texpectParseErrorJSX(t, \"<a b// \\n />\", \"\")\n\n\t// JSX namespaced names\n\tfor _, colon := range []string{\":\", \" :\", \": \", \" : \"} {\n\t\texpectPrintedJSX(t, \"<a\"+colon+\"b/>\", \"<a:b />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a:b\\\", null);\\n\")\n\t\texpectPrintedJSX(t, \"<a-b\"+colon+\"c-d/>\", \"<a-b:c-d />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a-b:c-d\\\", null);\\n\")\n\t\texpectPrintedJSX(t, \"<a-\"+colon+\"b-/>\", \"<a-:b- />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a-:b-\\\", null);\\n\")\n\t\texpectPrintedJSX(t, \"<Te\"+colon+\"st/>\", \"<Te:st />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"Te:st\\\", null);\\n\")\n\t\texpectPrintedJSX(t, \"<x a\"+colon+\"b/>\", \"<x a:b />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", { \\\"a:b\\\": true });\\n\")\n\t\texpectPrintedJSX(t, \"<x a-b\"+colon+\"c-d/>\", \"<x a-b:c-d />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", { \\\"a-b:c-d\\\": true });\\n\")\n\t\texpectPrintedJSX(t, \"<x a-\"+colon+\"b-/>\", \"<x a-:b- />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", { \\\"a-:b-\\\": true });\\n\")\n\t\texpectPrintedJSX(t, \"<x Te\"+colon+\"st/>\", \"<x Te:st />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", { \\\"Te:st\\\": true });\\n\")\n\t\texpectPrintedJSX(t, \"<x a\"+colon+\"b={0}/>\", \"<x a:b={0} />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", { \\\"a:b\\\": 0 });\\n\")\n\t\texpectPrintedJSX(t, \"<x a-b\"+colon+\"c-d={0}/>\", \"<x a-b:c-d={0} />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", { \\\"a-b:c-d\\\": 0 });\\n\")\n\t\texpectPrintedJSX(t, \"<x a-\"+colon+\"b-={0}/>\", \"<x a-:b-={0} />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", { \\\"a-:b-\\\": 0 });\\n\")\n\t\texpectPrintedJSX(t, \"<x Te\"+colon+\"st={0}/>\", \"<x Te:st={0} />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", { \\\"Te:st\\\": 0 });\\n\")\n\t\texpectPrintedJSX(t, \"<a-b a-b={a-b}/>\", \"<a-b a-b={a - b} />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a-b\\\", { \\\"a-b\\\": a - b });\\n\")\n\t\texpectParseErrorJSX(t, \"<x\"+colon+\"/>\", \"<stdin>: ERROR: Expected identifier after \\\"x:\\\" in namespaced JSX name\\n\")\n\t\texpectParseErrorJSX(t, \"<x\"+colon+\"y\"+colon+\"/>\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\":\\\"\\n\")\n\t\texpectParseErrorJSX(t, \"<x\"+colon+\"0y/>\", \"<stdin>: ERROR: Expected identifier after \\\"x:\\\" in namespaced JSX name\\n\")\n\t}\n\n\t// JSX elements as JSX attribute values\n\texpectPrintedJSX(t, \"<a b=<c/>/>\", \"<a b=<c /> />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: /* @__PURE__ */ React.createElement(\\\"c\\\", null) });\\n\")\n\texpectPrintedJSX(t, \"<a b=<></>/>\", \"<a b=<></> />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", { b: /* @__PURE__ */ React.createElement(React.Fragment, null) });\\n\")\n\texpectParseErrorJSX(t, \"<a b=</a>/>\", \"<stdin>: ERROR: Expected identifier but found \\\"/\\\"\\n\")\n\texpectParseErrorJSX(t, \"<a b=<>/>\",\n\t\t\"<stdin>: WARNING: The character \\\">\\\" is not valid inside a JSX element\\nNOTE: Did you mean to escape it as \\\"{'>'}\\\" instead?\\n\"+\n\t\t\t\"<stdin>: ERROR: Unexpected end of file before a closing fragment tag\\n<stdin>: NOTE: The opening fragment tag is here:\\n\")\n\texpectParseErrorJSX(t, \"<a b=<c>></a>\",\n\t\t\"<stdin>: WARNING: The character \\\">\\\" is not valid inside a JSX element\\nNOTE: Did you mean to escape it as \\\"{'>'}\\\" instead?\\n\"+\n\t\t\t\"<stdin>: ERROR: Unexpected closing \\\"a\\\" tag does not match opening \\\"c\\\" tag\\n<stdin>: NOTE: The opening \\\"c\\\" tag is here:\\n\"+\n\t\t\t\"<stdin>: ERROR: Expected \\\">\\\" but found end of file\\n\")\n\texpectParseErrorJSX(t, \"<a b=<c>/>\",\n\t\t\"<stdin>: WARNING: The character \\\">\\\" is not valid inside a JSX element\\nNOTE: Did you mean to escape it as \\\"{'>'}\\\" instead?\\n\"+\n\t\t\t\"<stdin>: ERROR: Unexpected end of file before a closing \\\"c\\\" tag\\n<stdin>: NOTE: The opening \\\"c\\\" tag is here:\\n\")\n}\n\nfunc TestJSXSingleLine(t *testing.T) {\n\texpectPrintedJSX(t, \"<x/>\", \"<x />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<x y/>\", \"<x y />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", { y: true });\\n\")\n\texpectPrintedJSX(t, \"<x\\n/>\", \"<x />;\\n\", \"/* @__PURE__ */ React.createElement(\\n  \\\"x\\\",\\n  null\\n);\\n\")\n\texpectPrintedJSX(t, \"<x\\ny/>\", \"<x\\n  y\\n/>;\\n\", \"/* @__PURE__ */ React.createElement(\\n  \\\"x\\\",\\n  {\\n    y: true\\n  }\\n);\\n\")\n\texpectPrintedJSX(t, \"<x y\\n/>\", \"<x\\n  y\\n/>;\\n\", \"/* @__PURE__ */ React.createElement(\\n  \\\"x\\\",\\n  {\\n    y: true\\n  }\\n);\\n\")\n\texpectPrintedJSX(t, \"<x\\n{...y}/>\", \"<x\\n  {...y}\\n/>;\\n\", \"/* @__PURE__ */ React.createElement(\\n  \\\"x\\\",\\n  {\\n    ...y\\n  }\\n);\\n\")\n}\n\nfunc TestJSXPragmas(t *testing.T) {\n\texpectPrintedJSX(t, \"// @jsx h\\n<a/>\", \"<a />;\\n\", \"/* @__PURE__ */ h(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"/*@jsx h*/\\n<a/>\", \"<a />;\\n\", \"/* @__PURE__ */ h(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"/* @jsx h */\\n<a/>\", \"<a />;\\n\", \"/* @__PURE__ */ h(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<a/>\\n// @jsx h\", \"<a />;\\n\", \"/* @__PURE__ */ h(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<a/>\\n/*@jsx h*/\", \"<a />;\\n\", \"/* @__PURE__ */ h(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<a/>\\n/* @jsx h */\", \"<a />;\\n\", \"/* @__PURE__ */ h(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"// @jsx a.b.c\\n<a/>\", \"<a />;\\n\", \"/* @__PURE__ */ a.b.c(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"/*@jsx a.b.c*/\\n<a/>\", \"<a />;\\n\", \"/* @__PURE__ */ a.b.c(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"/* @jsx a.b.c */\\n<a/>\", \"<a />;\\n\", \"/* @__PURE__ */ a.b.c(\\\"a\\\", null);\\n\")\n\n\texpectPrintedJSX(t, \"// @jsxFrag f\\n<></>\", \"<></>;\\n\", \"/* @__PURE__ */ React.createElement(f, null);\\n\")\n\texpectPrintedJSX(t, \"/*@jsxFrag f*/\\n<></>\", \"<></>;\\n\", \"/* @__PURE__ */ React.createElement(f, null);\\n\")\n\texpectPrintedJSX(t, \"/* @jsxFrag f */\\n<></>\", \"<></>;\\n\", \"/* @__PURE__ */ React.createElement(f, null);\\n\")\n\texpectPrintedJSX(t, \"<></>\\n// @jsxFrag f\", \"<></>;\\n\", \"/* @__PURE__ */ React.createElement(f, null);\\n\")\n\texpectPrintedJSX(t, \"<></>\\n/*@jsxFrag f*/\", \"<></>;\\n\", \"/* @__PURE__ */ React.createElement(f, null);\\n\")\n\texpectPrintedJSX(t, \"<></>\\n/* @jsxFrag f */\", \"<></>;\\n\", \"/* @__PURE__ */ React.createElement(f, null);\\n\")\n\texpectPrintedJSX(t, \"// @jsxFrag a.b.c\\n<></>\", \"<></>;\\n\", \"/* @__PURE__ */ React.createElement(a.b.c, null);\\n\")\n\texpectPrintedJSX(t, \"/*@jsxFrag a.b.c*/\\n<></>\", \"<></>;\\n\", \"/* @__PURE__ */ React.createElement(a.b.c, null);\\n\")\n\texpectPrintedJSX(t, \"/* @jsxFrag a.b.c */\\n<></>\", \"<></>;\\n\", \"/* @__PURE__ */ React.createElement(a.b.c, null);\\n\")\n}\n\nfunc TestJSXAutomatic(t *testing.T) {\n\t// Prod, without runtime imports\n\tp := JSXAutomaticTestOptions{Development: false, OmitJSXRuntimeForTests: true}\n\texpectPrintedJSXAutomatic(t, p, \"<div>></div>\", \"/* @__PURE__ */ jsx(\\\"div\\\", { children: \\\">\\\" });\\n\")\n\texpectPrintedJSXAutomatic(t, p, \"<div>{1}}</div>\", \"/* @__PURE__ */ jsxs(\\\"div\\\", { children: [\\n  1,\\n  \\\"}\\\"\\n] });\\n\")\n\texpectPrintedJSXAutomatic(t, p, \"<div key={true} />\", \"/* @__PURE__ */ jsx(\\\"div\\\", {}, true);\\n\")\n\texpectPrintedJSXAutomatic(t, p, \"<div key=\\\"key\\\" />\", \"/* @__PURE__ */ jsx(\\\"div\\\", {}, \\\"key\\\");\\n\")\n\texpectPrintedJSXAutomatic(t, p, \"<div key=\\\"key\\\" {...props} />\", \"/* @__PURE__ */ jsx(\\\"div\\\", { ...props }, \\\"key\\\");\\n\")\n\texpectPrintedJSXAutomatic(t, p, \"<div {...props} key=\\\"key\\\" />\", \"/* @__PURE__ */ createElement(\\\"div\\\", { ...props, key: \\\"key\\\" });\\n\") // Falls back to createElement\n\texpectPrintedJSXAutomatic(t, p, \"<div>{...children}</div>\", \"/* @__PURE__ */ jsxs(\\\"div\\\", { children: [\\n  ...children\\n] });\\n\")\n\texpectPrintedJSXAutomatic(t, p, \"<div>{...children}<a/></div>\", \"/* @__PURE__ */ jsxs(\\\"div\\\", { children: [\\n  ...children,\\n  /* @__PURE__ */ jsx(\\\"a\\\", {})\\n] });\\n\")\n\texpectPrintedJSXAutomatic(t, p, \"<>></>\", \"/* @__PURE__ */ jsx(Fragment, { children: \\\">\\\" });\\n\")\n\n\texpectParseErrorJSXAutomatic(t, p, \"<a key/>\",\n\t\t`<stdin>: ERROR: Please provide an explicit value for \"key\":\nNOTE: Using \"key\" as a shorthand for \"key={true}\" is not allowed when using React's \"automatic\" JSX transform.\n`)\n\texpectParseErrorJSXAutomatic(t, p, \"<div __self={self} />\",\n\t\t`<stdin>: ERROR: Duplicate \"__self\" prop found:\nNOTE: Both \"__source\" and \"__self\" are set automatically by esbuild when using React's \"automatic\" JSX transform. This duplicate prop may have come from a plugin.\n`)\n\texpectParseErrorJSXAutomatic(t, p, \"<div __source=\\\"/path/to/source.jsx\\\" />\",\n\t\t`<stdin>: ERROR: Duplicate \"__source\" prop found:\nNOTE: Both \"__source\" and \"__self\" are set automatically by esbuild when using React's \"automatic\" JSX transform. This duplicate prop may have come from a plugin.\n`)\n\n\t// Prod, with runtime imports\n\tpr := JSXAutomaticTestOptions{Development: false}\n\texpectPrintedJSXAutomatic(t, pr, \"<div/>\", \"import { jsx } from \\\"react/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(\\\"div\\\", {});\\n\")\n\texpectPrintedJSXAutomatic(t, pr, \"<><a/><b/></>\", \"import { Fragment, jsx, jsxs } from \\\"react/jsx-runtime\\\";\\n/* @__PURE__ */ jsxs(Fragment, { children: [\\n  /* @__PURE__ */ jsx(\\\"a\\\", {}),\\n  /* @__PURE__ */ jsx(\\\"b\\\", {})\\n] });\\n\")\n\texpectPrintedJSXAutomatic(t, pr, \"<div {...props} key=\\\"key\\\" />\", \"import { createElement } from \\\"react\\\";\\n/* @__PURE__ */ createElement(\\\"div\\\", { ...props, key: \\\"key\\\" });\\n\")\n\texpectPrintedJSXAutomatic(t, pr, \"<><div {...props} key=\\\"key\\\" /></>\", \"import { Fragment, jsx } from \\\"react/jsx-runtime\\\";\\nimport { createElement } from \\\"react\\\";\\n/* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ createElement(\\\"div\\\", { ...props, key: \\\"key\\\" }) });\\n\")\n\n\tpri := JSXAutomaticTestOptions{Development: false, ImportSource: \"my-jsx-lib\"}\n\texpectPrintedJSXAutomatic(t, pri, \"<div/>\", \"import { jsx } from \\\"my-jsx-lib/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(\\\"div\\\", {});\\n\")\n\texpectPrintedJSXAutomatic(t, pri, \"<div {...props} key=\\\"key\\\" />\", \"import { createElement } from \\\"my-jsx-lib\\\";\\n/* @__PURE__ */ createElement(\\\"div\\\", { ...props, key: \\\"key\\\" });\\n\")\n\n\t// Impure JSX call expressions\n\tpi := JSXAutomaticTestOptions{SideEffects: true, ImportSource: \"my-jsx-lib\"}\n\texpectPrintedJSXAutomatic(t, pi, \"<a/>\", \"import { jsx } from \\\"my-jsx-lib/jsx-runtime\\\";\\njsx(\\\"a\\\", {});\\n\")\n\texpectPrintedJSXAutomatic(t, pi, \"<></>\", \"import { Fragment, jsx } from \\\"my-jsx-lib/jsx-runtime\\\";\\njsx(Fragment, {});\\n\")\n\n\t// Dev, without runtime imports\n\td := JSXAutomaticTestOptions{Development: true, OmitJSXRuntimeForTests: true}\n\texpectPrintedJSXAutomatic(t, d, \"<div>></div>\", \"/* @__PURE__ */ jsxDEV(\\\"div\\\", { children: \\\">\\\" }, void 0, false, {\\n  fileName: \\\"<stdin>\\\",\\n  lineNumber: 1,\\n  columnNumber: 1\\n}, this);\\n\")\n\texpectPrintedJSXAutomatic(t, d, \"<div>{1}}</div>\", \"/* @__PURE__ */ jsxDEV(\\\"div\\\", { children: [\\n  1,\\n  \\\"}\\\"\\n] }, void 0, true, {\\n  fileName: \\\"<stdin>\\\",\\n  lineNumber: 1,\\n  columnNumber: 1\\n}, this);\\n\")\n\texpectPrintedJSXAutomatic(t, d, \"<div key={true} />\", \"/* @__PURE__ */ jsxDEV(\\\"div\\\", {}, true, false, {\\n  fileName: \\\"<stdin>\\\",\\n  lineNumber: 1,\\n  columnNumber: 1\\n}, this);\\n\")\n\texpectPrintedJSXAutomatic(t, d, \"<div key=\\\"key\\\" />\", \"/* @__PURE__ */ jsxDEV(\\\"div\\\", {}, \\\"key\\\", false, {\\n  fileName: \\\"<stdin>\\\",\\n  lineNumber: 1,\\n  columnNumber: 1\\n}, this);\\n\")\n\texpectPrintedJSXAutomatic(t, d, \"<div key=\\\"key\\\" {...props} />\", \"/* @__PURE__ */ jsxDEV(\\\"div\\\", { ...props }, \\\"key\\\", false, {\\n  fileName: \\\"<stdin>\\\",\\n  lineNumber: 1,\\n  columnNumber: 1\\n}, this);\\n\")\n\texpectPrintedJSXAutomatic(t, d, \"<div {...props} key=\\\"key\\\" />\", \"/* @__PURE__ */ createElement(\\\"div\\\", { ...props, key: \\\"key\\\" });\\n\") // Falls back to createElement\n\texpectPrintedJSXAutomatic(t, d, \"<div>{...children}</div>\", \"/* @__PURE__ */ jsxDEV(\\\"div\\\", { children: [\\n  ...children\\n] }, void 0, true, {\\n  fileName: \\\"<stdin>\\\",\\n  lineNumber: 1,\\n  columnNumber: 1\\n}, this);\\n\")\n\texpectPrintedJSXAutomatic(t, d, \"<div>\\n  {...children}\\n  <a/></div>\", \"/* @__PURE__ */ jsxDEV(\\\"div\\\", { children: [\\n  ...children,\\n  /* @__PURE__ */ jsxDEV(\\\"a\\\", {}, void 0, false, {\\n    fileName: \\\"<stdin>\\\",\\n    lineNumber: 3,\\n    columnNumber: 3\\n  }, this)\\n] }, void 0, true, {\\n  fileName: \\\"<stdin>\\\",\\n  lineNumber: 1,\\n  columnNumber: 1\\n}, this);\\n\")\n\texpectPrintedJSXAutomatic(t, d, \"<>></>\", \"/* @__PURE__ */ jsxDEV(Fragment, { children: \\\">\\\" }, void 0, false, {\\n  fileName: \\\"<stdin>\\\",\\n  lineNumber: 1,\\n  columnNumber: 1\\n}, this);\\n\")\n\n\texpectParseErrorJSXAutomatic(t, d, \"<a key/>\",\n\t\t`<stdin>: ERROR: Please provide an explicit value for \"key\":\nNOTE: Using \"key\" as a shorthand for \"key={true}\" is not allowed when using React's \"automatic\" JSX transform.\n`)\n\texpectParseErrorJSXAutomatic(t, d, \"<div __self={self} />\",\n\t\t`<stdin>: ERROR: Duplicate \"__self\" prop found:\nNOTE: Both \"__source\" and \"__self\" are set automatically by esbuild when using React's \"automatic\" JSX transform. This duplicate prop may have come from a plugin.\n`)\n\texpectParseErrorJSXAutomatic(t, d, \"<div __source=\\\"/path/to/source.jsx\\\" />\",\n\t\t`<stdin>: ERROR: Duplicate \"__source\" prop found:\nNOTE: Both \"__source\" and \"__self\" are set automatically by esbuild when using React's \"automatic\" JSX transform. This duplicate prop may have come from a plugin.\n`)\n\n\t// Line/column offset tests. Unlike Babel, TypeScript sometimes points to a\n\t// location other than the start of the element. I'm not sure if that's a bug\n\t// or not, but it seems weird. So I decided to match Babel instead.\n\texpectPrintedJSXAutomatic(t, d, \"\\r\\n<x/>\", \"/* @__PURE__ */ jsxDEV(\\\"x\\\", {}, void 0, false, {\\n  fileName: \\\"<stdin>\\\",\\n  lineNumber: 2,\\n  columnNumber: 1\\n}, this);\\n\")\n\texpectPrintedJSXAutomatic(t, d, \"\\n\\r<x/>\", \"/* @__PURE__ */ jsxDEV(\\\"x\\\", {}, void 0, false, {\\n  fileName: \\\"<stdin>\\\",\\n  lineNumber: 3,\\n  columnNumber: 1\\n}, this);\\n\")\n\texpectPrintedJSXAutomatic(t, d, \"let 𐀀 = <x>🍕🍕🍕<y/></x>\", \"let 𐀀 = /* @__PURE__ */ jsxDEV(\\\"x\\\", { children: [\\n  \\\"🍕🍕🍕\\\",\\n  /* @__PURE__ */ jsxDEV(\\\"y\\\", {}, void 0, false, {\\n    fileName: \\\"<stdin>\\\",\\n    lineNumber: 1,\\n    columnNumber: 19\\n  }, this)\\n] }, void 0, true, {\\n  fileName: \\\"<stdin>\\\",\\n  lineNumber: 1,\\n  columnNumber: 10\\n}, this);\\n\")\n\n\t// Dev, with runtime imports\n\tdr := JSXAutomaticTestOptions{Development: true}\n\texpectPrintedJSXAutomatic(t, dr, \"<div/>\", \"import { jsxDEV } from \\\"react/jsx-dev-runtime\\\";\\n/* @__PURE__ */ jsxDEV(\\\"div\\\", {}, void 0, false, {\\n  fileName: \\\"<stdin>\\\",\\n  lineNumber: 1,\\n  columnNumber: 1\\n}, this);\\n\")\n\texpectPrintedJSXAutomatic(t, dr, \"<>\\n  <a/>\\n  <b/>\\n</>\", \"import { Fragment, jsxDEV } from \\\"react/jsx-dev-runtime\\\";\\n/* @__PURE__ */ jsxDEV(Fragment, { children: [\\n  /* @__PURE__ */ jsxDEV(\\\"a\\\", {}, void 0, false, {\\n    fileName: \\\"<stdin>\\\",\\n    lineNumber: 2,\\n    columnNumber: 3\\n  }, this),\\n  /* @__PURE__ */ jsxDEV(\\\"b\\\", {}, void 0, false, {\\n    fileName: \\\"<stdin>\\\",\\n    lineNumber: 3,\\n    columnNumber: 3\\n  }, this)\\n] }, void 0, true, {\\n  fileName: \\\"<stdin>\\\",\\n  lineNumber: 1,\\n  columnNumber: 1\\n}, this);\\n\")\n\n\tdri := JSXAutomaticTestOptions{Development: true, ImportSource: \"preact\"}\n\texpectPrintedJSXAutomatic(t, dri, \"<div/>\", \"import { jsxDEV } from \\\"preact/jsx-dev-runtime\\\";\\n/* @__PURE__ */ jsxDEV(\\\"div\\\", {}, void 0, false, {\\n  fileName: \\\"<stdin>\\\",\\n  lineNumber: 1,\\n  columnNumber: 1\\n}, this);\\n\")\n\texpectPrintedJSXAutomatic(t, dri, \"<>\\n  <a/>\\n  <b/>\\n</>\", \"import { Fragment, jsxDEV } from \\\"preact/jsx-dev-runtime\\\";\\n/* @__PURE__ */ jsxDEV(Fragment, { children: [\\n  /* @__PURE__ */ jsxDEV(\\\"a\\\", {}, void 0, false, {\\n    fileName: \\\"<stdin>\\\",\\n    lineNumber: 2,\\n    columnNumber: 3\\n  }, this),\\n  /* @__PURE__ */ jsxDEV(\\\"b\\\", {}, void 0, false, {\\n    fileName: \\\"<stdin>\\\",\\n    lineNumber: 3,\\n    columnNumber: 3\\n  }, this)\\n] }, void 0, true, {\\n  fileName: \\\"<stdin>\\\",\\n  lineNumber: 1,\\n  columnNumber: 1\\n}, this);\\n\")\n\n\t// JSX namespaced names\n\tfor _, colon := range []string{\":\", \" :\", \": \", \" : \"} {\n\t\texpectPrintedJSXAutomatic(t, p, \"<a\"+colon+\"b/>\", \"/* @__PURE__ */ jsx(\\\"a:b\\\", {});\\n\")\n\t\texpectPrintedJSXAutomatic(t, p, \"<a-b\"+colon+\"c-d/>\", \"/* @__PURE__ */ jsx(\\\"a-b:c-d\\\", {});\\n\")\n\t\texpectPrintedJSXAutomatic(t, p, \"<a-\"+colon+\"b-/>\", \"/* @__PURE__ */ jsx(\\\"a-:b-\\\", {});\\n\")\n\t\texpectPrintedJSXAutomatic(t, p, \"<Te\"+colon+\"st/>\", \"/* @__PURE__ */ jsx(\\\"Te:st\\\", {});\\n\")\n\t\texpectPrintedJSXAutomatic(t, p, \"<x a\"+colon+\"b/>\", \"/* @__PURE__ */ jsx(\\\"x\\\", { \\\"a:b\\\": true });\\n\")\n\t\texpectPrintedJSXAutomatic(t, p, \"<x a-b\"+colon+\"c-d/>\", \"/* @__PURE__ */ jsx(\\\"x\\\", { \\\"a-b:c-d\\\": true });\\n\")\n\t\texpectPrintedJSXAutomatic(t, p, \"<x a-\"+colon+\"b-/>\", \"/* @__PURE__ */ jsx(\\\"x\\\", { \\\"a-:b-\\\": true });\\n\")\n\t\texpectPrintedJSXAutomatic(t, p, \"<x Te\"+colon+\"st/>\", \"/* @__PURE__ */ jsx(\\\"x\\\", { \\\"Te:st\\\": true });\\n\")\n\t\texpectPrintedJSXAutomatic(t, p, \"<x a\"+colon+\"b={0}/>\", \"/* @__PURE__ */ jsx(\\\"x\\\", { \\\"a:b\\\": 0 });\\n\")\n\t\texpectPrintedJSXAutomatic(t, p, \"<x a-b\"+colon+\"c-d={0}/>\", \"/* @__PURE__ */ jsx(\\\"x\\\", { \\\"a-b:c-d\\\": 0 });\\n\")\n\t\texpectPrintedJSXAutomatic(t, p, \"<x a-\"+colon+\"b-={0}/>\", \"/* @__PURE__ */ jsx(\\\"x\\\", { \\\"a-:b-\\\": 0 });\\n\")\n\t\texpectPrintedJSXAutomatic(t, p, \"<x Te\"+colon+\"st={0}/>\", \"/* @__PURE__ */ jsx(\\\"x\\\", { \\\"Te:st\\\": 0 });\\n\")\n\t\texpectPrintedJSXAutomatic(t, p, \"<a-b a-b={a-b}/>\", \"/* @__PURE__ */ jsx(\\\"a-b\\\", { \\\"a-b\\\": a - b });\\n\")\n\t\texpectParseErrorJSXAutomatic(t, p, \"<x\"+colon+\"/>\", \"<stdin>: ERROR: Expected identifier after \\\"x:\\\" in namespaced JSX name\\n\")\n\t\texpectParseErrorJSXAutomatic(t, p, \"<x\"+colon+\"y\"+colon+\"/>\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\":\\\"\\n\")\n\t\texpectParseErrorJSXAutomatic(t, p, \"<x\"+colon+\"0y/>\", \"<stdin>: ERROR: Expected identifier after \\\"x:\\\" in namespaced JSX name\\n\")\n\t}\n\n\t// Enabling the \"automatic\" runtime means that any JSX element will cause the\n\t// file to be implicitly in strict mode due to the automatically-generated\n\t// import statement. This is the same behavior as the TypeScript compiler.\n\tstrictModeError := \"<stdin>: ERROR: With statements cannot be used in strict mode\\n\" +\n\t\t\"<stdin>: NOTE: This file is implicitly in strict mode due to the JSX element here:\\n\" +\n\t\t\"NOTE: When React's \\\"automatic\\\" JSX transform is enabled, using a JSX element automatically inserts an \\\"import\\\" statement at the top of the file \" +\n\t\t\"for the corresponding the JSX helper function. This means the file is considered an ECMAScript module, and all ECMAScript modules use strict mode.\\n\"\n\texpectPrintedJSX(t, \"with (x) y(<z/>)\", \"with (x) y(<z />);\\n\", \"with (x) y(/* @__PURE__ */ React.createElement(\\\"z\\\", null));\\n\")\n\texpectPrintedJSXAutomatic(t, p, \"with (x) y\", \"with (x) y;\\n\")\n\texpectParseErrorJSX(t, \"with (x) y(<z/>) // @jsxRuntime automatic\", strictModeError)\n\texpectParseErrorJSXAutomatic(t, p, \"with (x) y(<z/>)\", strictModeError)\n}\n\nfunc TestJSXAutomaticPragmas(t *testing.T) {\n\texpectPrintedJSX(t, \"// @jsxRuntime automatic\\n<a/>\", \"<a />;\\n\", \"import { jsx } from \\\"react/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(\\\"a\\\", {});\\n\")\n\texpectPrintedJSX(t, \"/*@jsxRuntime automatic*/\\n<a/>\", \"<a />;\\n\", \"import { jsx } from \\\"react/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(\\\"a\\\", {});\\n\")\n\texpectPrintedJSX(t, \"/* @jsxRuntime automatic */\\n<a/>\", \"<a />;\\n\", \"import { jsx } from \\\"react/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(\\\"a\\\", {});\\n\")\n\texpectPrintedJSX(t, \"<a/>\\n/*@jsxRuntime automatic*/\", \"<a />;\\n\", \"import { jsx } from \\\"react/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(\\\"a\\\", {});\\n\")\n\texpectPrintedJSX(t, \"<a/>\\n/* @jsxRuntime automatic */\", \"<a />;\\n\", \"import { jsx } from \\\"react/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(\\\"a\\\", {});\\n\")\n\n\texpectPrintedJSX(t, \"// @jsxRuntime classic\\n<a/>\", \"<a />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"/*@jsxRuntime classic*/\\n<a/>\", \"<a />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"/* @jsxRuntime classic */\\n<a/>\", \"<a />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<a/>\\n/*@jsxRuntime classic*/\\n\", \"<a />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<a/>\\n/* @jsxRuntime classic */\\n\", \"<a />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\n\texpectParseErrorJSX(t, \"// @jsxRuntime foo\\n<a/>\",\n\t\t`<stdin>: WARNING: Invalid JSX runtime: \"foo\"\nNOTE: The JSX runtime can only be set to either \"classic\" or \"automatic\".\n`)\n\n\texpectPrintedJSX(t, \"// @jsxRuntime automatic @jsxImportSource src\\n<a/>\", \"<a />;\\n\", \"import { jsx } from \\\"src/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(\\\"a\\\", {});\\n\")\n\texpectPrintedJSX(t, \"/*@jsxRuntime automatic @jsxImportSource src*/\\n<a/>\", \"<a />;\\n\", \"import { jsx } from \\\"src/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(\\\"a\\\", {});\\n\")\n\texpectPrintedJSX(t, \"/*@jsxRuntime automatic*//*@jsxImportSource src*/\\n<a/>\", \"<a />;\\n\", \"import { jsx } from \\\"src/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(\\\"a\\\", {});\\n\")\n\texpectPrintedJSX(t, \"/* @jsxRuntime automatic */\\n/* @jsxImportSource src */\\n<a/>\", \"<a />;\\n\", \"import { jsx } from \\\"src/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(\\\"a\\\", {});\\n\")\n\texpectPrintedJSX(t, \"<a/>\\n/*@jsxRuntime automatic @jsxImportSource src*/\", \"<a />;\\n\", \"import { jsx } from \\\"src/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(\\\"a\\\", {});\\n\")\n\texpectPrintedJSX(t, \"<a/>\\n/*@jsxRuntime automatic*/\\n/*@jsxImportSource src*/\", \"<a />;\\n\", \"import { jsx } from \\\"src/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(\\\"a\\\", {});\\n\")\n\texpectPrintedJSX(t, \"<a/>\\n/* @jsxRuntime automatic */\\n/* @jsxImportSource src */\", \"<a />;\\n\", \"import { jsx } from \\\"src/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(\\\"a\\\", {});\\n\")\n\n\texpectPrintedJSX(t, \"// @jsxRuntime classic @jsxImportSource src\\n<a/>\", \"<a />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\texpectParseErrorJSX(t, \"// @jsxRuntime classic @jsxImportSource src\\n<a/>\",\n\t\t`<stdin>: WARNING: The JSX import source cannot be set without also enabling React's \"automatic\" JSX transform\nNOTE: You can enable React's \"automatic\" JSX transform for this file by using a \"@jsxRuntime automatic\" comment.\n`)\n\texpectParseErrorJSX(t, \"// @jsxImportSource src\\n<a/>\",\n\t\t`<stdin>: WARNING: The JSX import source cannot be set without also enabling React's \"automatic\" JSX transform\nNOTE: You can enable React's \"automatic\" JSX transform for this file by using a \"@jsxRuntime automatic\" comment.\n`)\n\n\texpectPrintedJSX(t, \"// @jsxRuntime automatic @jsx h\\n<a/>\", \"<a />;\\n\", \"import { jsx } from \\\"react/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(\\\"a\\\", {});\\n\")\n\texpectParseErrorJSX(t, \"// @jsxRuntime automatic @jsx h\\n<a/>\", \"<stdin>: WARNING: The JSX factory cannot be set when using React's \\\"automatic\\\" JSX transform\\n\")\n\n\texpectPrintedJSX(t, \"// @jsxRuntime automatic @jsxFrag f\\n<></>\", \"<></>;\\n\", \"import { Fragment, jsx } from \\\"react/jsx-runtime\\\";\\n/* @__PURE__ */ jsx(Fragment, {});\\n\")\n\texpectParseErrorJSX(t, \"// @jsxRuntime automatic @jsxFrag f\\n<></>\", \"<stdin>: WARNING: The JSX fragment cannot be set when using React's \\\"automatic\\\" JSX transform\\n\")\n}\n\nfunc TestJSXSideEffects(t *testing.T) {\n\texpectPrintedJSX(t, \"<a/>\", \"<a />;\\n\", \"/* @__PURE__ */ React.createElement(\\\"a\\\", null);\\n\")\n\texpectPrintedJSX(t, \"<></>\", \"<></>;\\n\", \"/* @__PURE__ */ React.createElement(React.Fragment, null);\\n\")\n\n\texpectPrintedJSXSideEffects(t, \"<a/>\", \"React.createElement(\\\"a\\\", null);\\n\")\n\texpectPrintedJSXSideEffects(t, \"<></>\", \"React.createElement(React.Fragment, null);\\n\")\n}\n\nfunc TestPreserveOptionalChainParentheses(t *testing.T) {\n\texpectPrinted(t, \"a?.b.c\", \"a?.b.c;\\n\")\n\texpectPrinted(t, \"(a?.b).c\", \"(a?.b).c;\\n\")\n\texpectPrinted(t, \"a?.b.c.d\", \"a?.b.c.d;\\n\")\n\texpectPrinted(t, \"(a?.b.c).d\", \"(a?.b.c).d;\\n\")\n\texpectPrinted(t, \"a?.b[c]\", \"a?.b[c];\\n\")\n\texpectPrinted(t, \"(a?.b)[c]\", \"(a?.b)[c];\\n\")\n\texpectPrinted(t, \"a?.b(c)\", \"a?.b(c);\\n\")\n\texpectPrinted(t, \"(a?.b)(c)\", \"(a?.b)(c);\\n\")\n\n\texpectPrinted(t, \"a?.[b][c]\", \"a?.[b][c];\\n\")\n\texpectPrinted(t, \"(a?.[b])[c]\", \"(a?.[b])[c];\\n\")\n\texpectPrinted(t, \"a?.[b][c][d]\", \"a?.[b][c][d];\\n\")\n\texpectPrinted(t, \"(a?.[b][c])[d]\", \"(a?.[b][c])[d];\\n\")\n\texpectPrinted(t, \"a?.[b].c\", \"a?.[b].c;\\n\")\n\texpectPrinted(t, \"(a?.[b]).c\", \"(a?.[b]).c;\\n\")\n\texpectPrinted(t, \"a?.[b](c)\", \"a?.[b](c);\\n\")\n\texpectPrinted(t, \"(a?.[b])(c)\", \"(a?.[b])(c);\\n\")\n\n\texpectPrinted(t, \"a?.(b)(c)\", \"a?.(b)(c);\\n\")\n\texpectPrinted(t, \"(a?.(b))(c)\", \"(a?.(b))(c);\\n\")\n\texpectPrinted(t, \"a?.(b)(c)(d)\", \"a?.(b)(c)(d);\\n\")\n\texpectPrinted(t, \"(a?.(b)(c))(d)\", \"(a?.(b)(c))(d);\\n\")\n\texpectPrinted(t, \"a?.(b).c\", \"a?.(b).c;\\n\")\n\texpectPrinted(t, \"(a?.(b)).c\", \"(a?.(b)).c;\\n\")\n\texpectPrinted(t, \"a?.(b)[c]\", \"a?.(b)[c];\\n\")\n\texpectPrinted(t, \"(a?.(b))[c]\", \"(a?.(b))[c];\\n\")\n}\n\nfunc TestPrivateIdentifiers(t *testing.T) {\n\texpectParseError(t, \"#foo\", \"<stdin>: ERROR: Expected \\\"in\\\" but found end of file\\n\")\n\texpectParseError(t, \"#foo in this\", \"<stdin>: ERROR: Private name \\\"#foo\\\" must be declared in an enclosing class\\n\")\n\texpectParseError(t, \"this.#foo\", \"<stdin>: ERROR: Private name \\\"#foo\\\" must be declared in an enclosing class\\n\")\n\texpectParseError(t, \"this?.#foo\", \"<stdin>: ERROR: Private name \\\"#foo\\\" must be declared in an enclosing class\\n\")\n\texpectParseError(t, \"({ #foo: 1 })\", \"<stdin>: ERROR: Expected identifier but found \\\"#foo\\\"\\n\")\n\texpectParseError(t, \"class Foo { x = { #foo: 1 } }\", \"<stdin>: ERROR: Expected identifier but found \\\"#foo\\\"\\n\")\n\texpectParseError(t, \"class Foo { x = #foo }\", \"<stdin>: ERROR: Expected \\\"in\\\" but found \\\"}\\\"\\n\")\n\texpectParseError(t, \"class Foo { #foo; foo() { delete this.#foo } }\",\n\t\t\"<stdin>: ERROR: Deleting the private name \\\"#foo\\\" is forbidden\\n\")\n\texpectParseError(t, \"class Foo { #foo; foo() { delete this?.#foo } }\",\n\t\t\"<stdin>: ERROR: Deleting the private name \\\"#foo\\\" is forbidden\\n\")\n\texpectParseError(t, \"class Foo extends Bar { #foo; foo() { super.#foo } }\",\n\t\t\"<stdin>: ERROR: Expected identifier but found \\\"#foo\\\"\\n\")\n\texpectParseError(t, \"class Foo { #foo = () => { for (#foo in this) ; } }\",\n\t\t\"<stdin>: ERROR: Unexpected \\\"#foo\\\"\\n\")\n\texpectParseError(t, \"class Foo { #foo = () => { for (x = #foo in this) ; } }\",\n\t\t\"<stdin>: ERROR: Unexpected \\\"#foo\\\"\\n\")\n\n\texpectPrinted(t, \"class Foo { #foo }\", \"class Foo {\\n  #foo;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { #foo = 1 }\", \"class Foo {\\n  #foo = 1;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { #foo = #foo in this }\", \"class Foo {\\n  #foo = #foo in this;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { #foo = #foo in (#bar in this); #bar }\", \"class Foo {\\n  #foo = #foo in (#bar in this);\\n  #bar;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { #foo() {} }\", \"class Foo {\\n  #foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { get #foo() {} }\", \"class Foo {\\n  get #foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { set #foo(x) {} }\", \"class Foo {\\n  set #foo(x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static #foo }\", \"class Foo {\\n  static #foo;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static #foo = 1 }\", \"class Foo {\\n  static #foo = 1;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static #foo() {} }\", \"class Foo {\\n  static #foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static get #foo() {} }\", \"class Foo {\\n  static get #foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static set #foo(x) {} }\", \"class Foo {\\n  static set #foo(x) {\\n  }\\n}\\n\")\n\texpectParseError(t, \"class Foo { #foo = #foo in #bar in this; #bar }\", \"<stdin>: ERROR: Unexpected \\\"#bar\\\"\\n\")\n\n\t// The name \"#constructor\" is forbidden\n\texpectParseError(t, \"class Foo { #constructor }\", \"<stdin>: ERROR: Invalid field name \\\"#constructor\\\"\\n\")\n\texpectParseError(t, \"class Foo { #constructor() {} }\", \"<stdin>: ERROR: Invalid method name \\\"#constructor\\\"\\n\")\n\texpectParseError(t, \"class Foo { static #constructor }\", \"<stdin>: ERROR: Invalid field name \\\"#constructor\\\"\\n\")\n\texpectParseError(t, \"class Foo { static #constructor() {} }\", \"<stdin>: ERROR: Invalid method name \\\"#constructor\\\"\\n\")\n\texpectParseError(t, \"class Foo { #\\\\u0063onstructor }\", \"<stdin>: ERROR: Invalid field name \\\"#constructor\\\"\\n\")\n\texpectParseError(t, \"class Foo { #\\\\u0063onstructor() {} }\", \"<stdin>: ERROR: Invalid method name \\\"#constructor\\\"\\n\")\n\texpectParseError(t, \"class Foo { static #\\\\u0063onstructor }\", \"<stdin>: ERROR: Invalid field name \\\"#constructor\\\"\\n\")\n\texpectParseError(t, \"class Foo { static #\\\\u0063onstructor() {} }\", \"<stdin>: ERROR: Invalid method name \\\"#constructor\\\"\\n\")\n\n\t// Test escape sequences\n\texpectPrinted(t, \"class Foo { #\\\\u0066oo; foo = this.#foo }\", \"class Foo {\\n  #foo;\\n  foo = this.#foo;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { #fo\\\\u006f; foo = this.#foo }\", \"class Foo {\\n  #foo;\\n  foo = this.#foo;\\n}\\n\")\n\texpectParseError(t, \"class Foo { #\\\\u0020oo }\", \"<stdin>: ERROR: Invalid identifier: \\\"# oo\\\"\\n\")\n\texpectParseError(t, \"class Foo { #fo\\\\u0020 }\", \"<stdin>: ERROR: Invalid identifier: \\\"#fo \\\"\\n\")\n\n\terrorText := `<stdin>: ERROR: The symbol \"#foo\" has already been declared\n<stdin>: NOTE: The symbol \"#foo\" was originally declared here:\n`\n\n\t// Scope tests\n\texpectParseError(t, \"class Foo { #foo; #foo }\", errorText)\n\texpectParseError(t, \"class Foo { #foo; static #foo }\", errorText)\n\texpectParseError(t, \"class Foo { static #foo; #foo }\", errorText)\n\texpectParseError(t, \"class Foo { #foo; #foo() {} }\", errorText)\n\texpectParseError(t, \"class Foo { #foo; get #foo() {} }\", errorText)\n\texpectParseError(t, \"class Foo { #foo; set #foo(x) {} }\", errorText)\n\texpectParseError(t, \"class Foo { #foo() {} #foo }\", errorText)\n\texpectParseError(t, \"class Foo { get #foo() {} #foo }\", errorText)\n\texpectParseError(t, \"class Foo { set #foo(x) {} #foo }\", errorText)\n\texpectParseError(t, \"class Foo { get #foo() {} get #foo() {} }\", errorText)\n\texpectParseError(t, \"class Foo { set #foo(x) {} set #foo(x) {} }\", errorText)\n\texpectParseError(t, \"class Foo { get #foo() {} set #foo(x) {} #foo }\", errorText)\n\texpectParseError(t, \"class Foo { set #foo(x) {} get #foo() {} #foo }\", errorText)\n\texpectPrinted(t, \"class Foo { get #foo() {} set #foo(x) { this.#foo } }\",\n\t\t\"class Foo {\\n  get #foo() {\\n  }\\n  set #foo(x) {\\n    this.#foo;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { set #foo(x) { this.#foo } get #foo() {} }\",\n\t\t\"class Foo {\\n  set #foo(x) {\\n    this.#foo;\\n  }\\n  get #foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { #foo } class Bar { #foo }\", \"class Foo {\\n  #foo;\\n}\\nclass Bar {\\n  #foo;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { foo = this.#foo; #foo }\", \"class Foo {\\n  foo = this.#foo;\\n  #foo;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { foo = this?.#foo; #foo }\", \"class Foo {\\n  foo = this?.#foo;\\n  #foo;\\n}\\n\")\n\texpectParseError(t, \"class Foo { #foo } class Bar { foo = this.#foo }\",\n\t\t\"<stdin>: ERROR: Private name \\\"#foo\\\" must be declared in an enclosing class\\n\")\n\texpectParseError(t, \"class Foo { #foo } class Bar { foo = this?.#foo }\",\n\t\t\"<stdin>: ERROR: Private name \\\"#foo\\\" must be declared in an enclosing class\\n\")\n\texpectParseError(t, \"class Foo { #foo } class Bar { foo = #foo in this }\",\n\t\t\"<stdin>: ERROR: Private name \\\"#foo\\\" must be declared in an enclosing class\\n\")\n\n\t// Getter and setter warnings\n\texpectParseError(t, \"class Foo { get #x() { this.#x = 1 } }\",\n\t\t\"<stdin>: WARNING: Writing to getter-only property \\\"#x\\\" will throw\\n\")\n\texpectParseError(t, \"class Foo { get #x() { this.#x += 1 } }\",\n\t\t\"<stdin>: WARNING: Writing to getter-only property \\\"#x\\\" will throw\\n\")\n\texpectParseError(t, \"class Foo { set #x(x) { this.#x } }\",\n\t\t\"<stdin>: WARNING: Reading from setter-only property \\\"#x\\\" will throw\\n\")\n\texpectParseError(t, \"class Foo { set #x(x) { this.#x += 1 } }\",\n\t\t\"<stdin>: WARNING: Reading from setter-only property \\\"#x\\\" will throw\\n\")\n\n\t// Writing to method warnings\n\texpectParseError(t, \"class Foo { #x() { this.#x = 1 } }\",\n\t\t\"<stdin>: WARNING: Writing to read-only method \\\"#x\\\" will throw\\n\")\n\texpectParseError(t, \"class Foo { #x() { this.#x += 1 } }\",\n\t\t\"<stdin>: WARNING: Writing to read-only method \\\"#x\\\" will throw\\n\")\n\n\texpectPrinted(t, `class Foo {\n\t#if\n\t#im() { return this.#im(this.#if) }\n\tstatic #sf\n\tstatic #sm() { return this.#sm(this.#sf) }\n\tfoo() {\n\t\treturn class {\n\t\t\t#inner() {\n\t\t\t\treturn [this.#im, this?.#inner, this?.x.#if]\n\t\t\t}\n\t\t}\n\t}\n}\n`, `class Foo {\n  #if;\n  #im() {\n    return this.#im(this.#if);\n  }\n  static #sf;\n  static #sm() {\n    return this.#sm(this.#sf);\n  }\n  foo() {\n    return class {\n      #inner() {\n        return [this.#im, this?.#inner, this?.x.#if];\n      }\n    };\n  }\n}\n`)\n}\n\nfunc TestImportAssertions(t *testing.T) {\n\texpectPrinted(t, \"import 'x' assert {}\", \"import \\\"x\\\" assert {};\\n\")\n\texpectPrinted(t, \"import 'x' assert {\\n}\", \"import \\\"x\\\" assert {};\\n\")\n\texpectPrinted(t, \"import 'x' assert\\n{}\", \"import \\\"x\\\" assert {};\\n\")\n\texpectPrinted(t, \"import 'x'\\nassert\\n{}\", \"import \\\"x\\\";\\nassert;\\n{\\n}\\n\")\n\texpectPrinted(t, \"import 'x' assert {type: 'json'}\", \"import \\\"x\\\" assert { type: \\\"json\\\" };\\n\")\n\texpectPrinted(t, \"import 'x' assert {type: 'json',}\", \"import \\\"x\\\" assert { type: \\\"json\\\" };\\n\")\n\texpectPrinted(t, \"import 'x' assert {'type': 'json'}\", \"import \\\"x\\\" assert { \\\"type\\\": \\\"json\\\" };\\n\")\n\texpectPrinted(t, \"import 'x' assert {a: 'b', c: 'd'}\", \"import \\\"x\\\" assert { a: \\\"b\\\", c: \\\"d\\\" };\\n\")\n\texpectPrinted(t, \"import 'x' assert {a: 'b', c: 'd',}\", \"import \\\"x\\\" assert { a: \\\"b\\\", c: \\\"d\\\" };\\n\")\n\texpectPrinted(t, \"import 'x' assert {if: 'keyword'}\", \"import \\\"x\\\" assert { if: \\\"keyword\\\" };\\n\")\n\texpectPrintedMangle(t, \"import 'x' assert {'type': 'json'}\", \"import \\\"x\\\" assert { type: \\\"json\\\" };\\n\")\n\texpectPrintedMangle(t, \"import 'x' assert {'ty pe': 'json'}\", \"import \\\"x\\\" assert { \\\"ty pe\\\": \\\"json\\\" };\\n\")\n\n\texpectParseError(t, \"import 'x' assert {,}\", \"<stdin>: ERROR: Expected identifier but found \\\",\\\"\\n\")\n\texpectParseError(t, \"import 'x' assert {x}\", \"<stdin>: ERROR: Expected \\\":\\\" but found \\\"}\\\"\\n\")\n\texpectParseError(t, \"import 'x' assert {x 'y'}\", \"<stdin>: ERROR: Expected \\\":\\\" but found \\\"'y'\\\"\\n\")\n\texpectParseError(t, \"import 'x' assert {x: y}\", \"<stdin>: ERROR: Expected string but found \\\"y\\\"\\n\")\n\texpectParseError(t, \"import 'x' assert {x: 'y',,}\", \"<stdin>: ERROR: Expected identifier but found \\\",\\\"\\n\")\n\texpectParseError(t, \"import 'x' assert {`x`: 'y'}\", \"<stdin>: ERROR: Expected identifier but found \\\"`x`\\\"\\n\")\n\texpectParseError(t, \"import 'x' assert {x: `y`}\", \"<stdin>: ERROR: Expected string but found \\\"`y`\\\"\\n\")\n\texpectParseError(t, \"import 'x' assert: {x: 'y'}\", \"<stdin>: ERROR: Expected \\\"{\\\" but found \\\":\\\"\\n\")\n\n\texpectParseError(t, \"import 'x' assert {x: 'y', x: 'y'}\",\n\t\t\"<stdin>: ERROR: Duplicate import assertion \\\"x\\\"\\n<stdin>: NOTE: The first \\\"x\\\" was here:\\n\")\n\texpectParseError(t, \"import 'x' assert {x: 'y', \\\\u0078: 'y'}\",\n\t\t\"<stdin>: ERROR: Duplicate import assertion \\\"x\\\"\\n<stdin>: NOTE: The first \\\"x\\\" was here:\\n\")\n\n\texpectPrinted(t, \"import x from 'x' assert {x: 'y'}\", \"import x from \\\"x\\\" assert { x: \\\"y\\\" };\\n\")\n\texpectPrinted(t, \"import * as x from 'x' assert {x: 'y'}\", \"import * as x from \\\"x\\\" assert { x: \\\"y\\\" };\\n\")\n\texpectPrinted(t, \"import {} from 'x' assert {x: 'y'}\", \"import {} from \\\"x\\\" assert { x: \\\"y\\\" };\\n\")\n\texpectPrinted(t, \"export {} from 'x' assert {x: 'y'}\", \"export {} from \\\"x\\\" assert { x: \\\"y\\\" };\\n\")\n\texpectPrinted(t, \"export * from 'x' assert {x: 'y'}\", \"export * from \\\"x\\\" assert { x: \\\"y\\\" };\\n\")\n\n\texpectPrinted(t, \"import(x ? 'y' : 'z')\", \"x ? import(\\\"y\\\") : import(\\\"z\\\");\\n\")\n\texpectPrinted(t, \"import(x ? 'y' : 'z', {assert: {}})\",\n\t\t\"x ? import(\\\"y\\\", { assert: {} }) : import(\\\"z\\\", { assert: {} });\\n\")\n\texpectPrinted(t, \"import(x ? 'y' : 'z', {assert: {a: 'b'}})\",\n\t\t\"x ? import(\\\"y\\\", { assert: { a: \\\"b\\\" } }) : import(\\\"z\\\", { assert: { a: \\\"b\\\" } });\\n\")\n\texpectPrinted(t, \"import(x ? 'y' : 'z', {assert: {'a': 'b'}})\",\n\t\t\"x ? import(\\\"y\\\", { assert: { \\\"a\\\": \\\"b\\\" } }) : import(\\\"z\\\", { assert: { \\\"a\\\": \\\"b\\\" } });\\n\")\n\texpectPrintedMangle(t, \"import(x ? 'y' : 'z', {assert: {'a': 'b'}})\",\n\t\t\"x ? import(\\\"y\\\", { assert: { a: \\\"b\\\" } }) : import(\\\"z\\\", { assert: { a: \\\"b\\\" } });\\n\")\n\texpectPrintedMangle(t, \"import(x ? 'y' : 'z', {assert: {'a a': 'b'}})\",\n\t\t\"x ? import(\\\"y\\\", { assert: { \\\"a a\\\": \\\"b\\\" } }) : import(\\\"z\\\", { assert: { \\\"a a\\\": \\\"b\\\" } });\\n\")\n\n\texpectPrinted(t, \"import(x ? 'y' : 'z', {})\", \"import(x ? \\\"y\\\" : \\\"z\\\", {});\\n\")\n\texpectPrinted(t, \"import(x ? 'y' : 'z', {assert: []})\", \"import(x ? \\\"y\\\" : \\\"z\\\", { assert: [] });\\n\")\n\texpectPrinted(t, \"import(x ? 'y' : 'z', {asserts: {}})\", \"import(x ? \\\"y\\\" : \\\"z\\\", { asserts: {} });\\n\")\n\texpectPrinted(t, \"import(x ? 'y' : 'z', {assert: {x: 1}})\", \"import(x ? \\\"y\\\" : \\\"z\\\", { assert: { x: 1 } });\\n\")\n\n\texpectPrintedTarget(t, 2015, \"import 'x' assert {x: 'y'}\", \"import \\\"x\\\";\\n\")\n\texpectPrintedTarget(t, 2015, \"import(x, {assert: {x: 'y'}})\", \"import(x);\\n\")\n\texpectPrintedTarget(t, 2015, \"import(x, {assert: {x: 1}})\", \"import(x);\\n\")\n\texpectPrintedTarget(t, 2015, \"import(x ? 'y' : 'z', {assert: {x: 'y'}})\", \"x ? import(\\\"y\\\") : import(\\\"z\\\");\\n\")\n\texpectPrintedTarget(t, 2015, \"import(x ? 'y' : 'z', {assert: {x: 1}})\", \"import(x ? \\\"y\\\" : \\\"z\\\");\\n\")\n\texpectParseErrorTarget(t, 2015, \"import(x ? 'y' : 'z', {assert: {x: foo()}})\",\n\t\t\"<stdin>: ERROR: Using an arbitrary value as the second argument to \\\"import()\\\" is not possible in the configured target environment\\n\")\n\n\t// Make sure there are no errors when bundling is disabled\n\texpectParseError(t, \"import { foo } from 'x' assert {type: 'json'}\", \"\")\n\texpectParseError(t, \"export { foo } from 'x' assert {type: 'json'}\", \"\")\n\n\t// Only omit the second argument to \"import()\" if both assertions and attributes aren't supported\n\texpectPrintedWithUnsupportedFeatures(t, compat.ImportAssertions,\n\t\t\"import 'x' assert {y: 'z'}; import('x', {assert: {y: 'z'}})\",\n\t\t\"import \\\"x\\\";\\nimport(\\\"x\\\", { assert: { y: \\\"z\\\" } });\\n\")\n\texpectPrintedWithUnsupportedFeatures(t, compat.ImportAttributes,\n\t\t\"import 'x' assert {y: 'z'}; import('x', {assert: {y: 'z'}})\",\n\t\t\"import \\\"x\\\" assert { y: \\\"z\\\" };\\nimport(\\\"x\\\", { assert: { y: \\\"z\\\" } });\\n\")\n\texpectPrintedWithUnsupportedFeatures(t, compat.ImportAssertions|compat.ImportAttributes,\n\t\t\"import 'x' assert {y: 'z'}; import('x', {assert: {y: 'z'}})\",\n\t\t\"import \\\"x\\\";\\nimport(\\\"x\\\");\\n\")\n}\n\nfunc TestImportAttributes(t *testing.T) {\n\texpectPrinted(t, \"import 'x' with {}\", \"import \\\"x\\\" with {};\\n\")\n\texpectPrinted(t, \"import 'x' with {\\n}\", \"import \\\"x\\\" with {};\\n\")\n\texpectPrinted(t, \"import 'x' with\\n{}\", \"import \\\"x\\\" with {};\\n\")\n\texpectPrinted(t, \"import 'x'\\nwith\\n{}\", \"import \\\"x\\\" with {};\\n\")\n\texpectPrinted(t, \"import 'x' with {type: 'json'}\", \"import \\\"x\\\" with { type: \\\"json\\\" };\\n\")\n\texpectPrinted(t, \"import 'x' with {type: 'json',}\", \"import \\\"x\\\" with { type: \\\"json\\\" };\\n\")\n\texpectPrinted(t, \"import 'x' with {'type': 'json'}\", \"import \\\"x\\\" with { \\\"type\\\": \\\"json\\\" };\\n\")\n\texpectPrinted(t, \"import 'x' with {a: 'b', c: 'd'}\", \"import \\\"x\\\" with { a: \\\"b\\\", c: \\\"d\\\" };\\n\")\n\texpectPrinted(t, \"import 'x' with {a: 'b', c: 'd',}\", \"import \\\"x\\\" with { a: \\\"b\\\", c: \\\"d\\\" };\\n\")\n\texpectPrinted(t, \"import 'x' with {if: 'keyword'}\", \"import \\\"x\\\" with { if: \\\"keyword\\\" };\\n\")\n\texpectPrintedMangle(t, \"import 'x' with {'type': 'json'}\", \"import \\\"x\\\" with { type: \\\"json\\\" };\\n\")\n\texpectPrintedMangle(t, \"import 'x' with {'ty pe': 'json'}\", \"import \\\"x\\\" with { \\\"ty pe\\\": \\\"json\\\" };\\n\")\n\n\texpectParseError(t, \"import 'x' with {,}\", \"<stdin>: ERROR: Expected identifier but found \\\",\\\"\\n\")\n\texpectParseError(t, \"import 'x' with {x}\", \"<stdin>: ERROR: Expected \\\":\\\" but found \\\"}\\\"\\n\")\n\texpectParseError(t, \"import 'x' with {x 'y'}\", \"<stdin>: ERROR: Expected \\\":\\\" but found \\\"'y'\\\"\\n\")\n\texpectParseError(t, \"import 'x' with {x: y}\", \"<stdin>: ERROR: Expected string but found \\\"y\\\"\\n\")\n\texpectParseError(t, \"import 'x' with {x: 'y',,}\", \"<stdin>: ERROR: Expected identifier but found \\\",\\\"\\n\")\n\texpectParseError(t, \"import 'x' with {`x`: 'y'}\", \"<stdin>: ERROR: Expected identifier but found \\\"`x`\\\"\\n\")\n\texpectParseError(t, \"import 'x' with {x: `y`}\", \"<stdin>: ERROR: Expected string but found \\\"`y`\\\"\\n\")\n\texpectParseError(t, \"import 'x' with: {x: 'y'}\", \"<stdin>: ERROR: Expected \\\"{\\\" but found \\\":\\\"\\n\")\n\n\texpectParseError(t, \"import 'x' with {x: 'y', x: 'y'}\",\n\t\t\"<stdin>: ERROR: Duplicate import attribute \\\"x\\\"\\n<stdin>: NOTE: The first \\\"x\\\" was here:\\n\")\n\texpectParseError(t, \"import 'x' with {x: 'y', \\\\u0078: 'y'}\",\n\t\t\"<stdin>: ERROR: Duplicate import attribute \\\"x\\\"\\n<stdin>: NOTE: The first \\\"x\\\" was here:\\n\")\n\n\texpectPrinted(t, \"import x from 'x' with {x: 'y'}\", \"import x from \\\"x\\\" with { x: \\\"y\\\" };\\n\")\n\texpectPrinted(t, \"import * as x from 'x' with {x: 'y'}\", \"import * as x from \\\"x\\\" with { x: \\\"y\\\" };\\n\")\n\texpectPrinted(t, \"import {} from 'x' with {x: 'y'}\", \"import {} from \\\"x\\\" with { x: \\\"y\\\" };\\n\")\n\texpectPrinted(t, \"export {} from 'x' with {x: 'y'}\", \"export {} from \\\"x\\\" with { x: \\\"y\\\" };\\n\")\n\texpectPrinted(t, \"export * from 'x' with {x: 'y'}\", \"export * from \\\"x\\\" with { x: \\\"y\\\" };\\n\")\n\n\texpectPrinted(t, \"import(x ? 'y' : 'z')\", \"x ? import(\\\"y\\\") : import(\\\"z\\\");\\n\")\n\texpectPrinted(t, \"import(x ? 'y' : 'z', {with: {}})\",\n\t\t\"x ? import(\\\"y\\\", { with: {} }) : import(\\\"z\\\", { with: {} });\\n\")\n\texpectPrinted(t, \"import(x ? 'y' : 'z', {with: {a: 'b'}})\",\n\t\t\"x ? import(\\\"y\\\", { with: { a: \\\"b\\\" } }) : import(\\\"z\\\", { with: { a: \\\"b\\\" } });\\n\")\n\texpectPrinted(t, \"import(x ? 'y' : 'z', {with: {'a': 'b'}})\",\n\t\t\"x ? import(\\\"y\\\", { with: { \\\"a\\\": \\\"b\\\" } }) : import(\\\"z\\\", { with: { \\\"a\\\": \\\"b\\\" } });\\n\")\n\texpectPrintedMangle(t, \"import(x ? 'y' : 'z', {with: {'a': 'b'}})\",\n\t\t\"x ? import(\\\"y\\\", { with: { a: \\\"b\\\" } }) : import(\\\"z\\\", { with: { a: \\\"b\\\" } });\\n\")\n\texpectPrintedMangle(t, \"import(x ? 'y' : 'z', {with: {'a a': 'b'}})\",\n\t\t\"x ? import(\\\"y\\\", { with: { \\\"a a\\\": \\\"b\\\" } }) : import(\\\"z\\\", { with: { \\\"a a\\\": \\\"b\\\" } });\\n\")\n\n\texpectPrinted(t, \"import(x ? 'y' : 'z', {})\", \"import(x ? \\\"y\\\" : \\\"z\\\", {});\\n\")\n\texpectPrinted(t, \"import(x ? 'y' : 'z', {with: []})\", \"import(x ? \\\"y\\\" : \\\"z\\\", { with: [] });\\n\")\n\texpectPrinted(t, \"import(x ? 'y' : 'z', {whithe: {}})\", \"import(x ? \\\"y\\\" : \\\"z\\\", { whithe: {} });\\n\")\n\texpectPrinted(t, \"import(x ? 'y' : 'z', {with: {x: 1}})\", \"import(x ? \\\"y\\\" : \\\"z\\\", { with: { x: 1 } });\\n\")\n\n\texpectPrintedTarget(t, 2015, \"import 'x' with {x: 'y'}\", \"import \\\"x\\\";\\n\")\n\texpectPrintedTarget(t, 2015, \"import(x, {with: {x: 'y'}})\", \"import(x);\\n\")\n\texpectPrintedTarget(t, 2015, \"import(x, {with: {x: 1}})\", \"import(x);\\n\")\n\texpectPrintedTarget(t, 2015, \"import(x ? 'y' : 'z', {with: {x: 'y'}})\", \"x ? import(\\\"y\\\") : import(\\\"z\\\");\\n\")\n\texpectPrintedTarget(t, 2015, \"import(x ? 'y' : 'z', {with: {x: 1}})\", \"import(x ? \\\"y\\\" : \\\"z\\\");\\n\")\n\texpectParseErrorTarget(t, 2015, \"import(x ? 'y' : 'z', {with: {x: foo()}})\",\n\t\t\"<stdin>: ERROR: Using an arbitrary value as the second argument to \\\"import()\\\" is not possible in the configured target environment\\n\")\n\n\t// Make sure there are no errors when bundling is disabled\n\texpectParseError(t, \"import { foo } from 'x' with {type: 'json'}\", \"\")\n\texpectParseError(t, \"export { foo } from 'x' with {type: 'json'}\", \"\")\n\n\t// Only omit the second argument to \"import()\" if both assertions and attributes aren't supported\n\texpectPrintedWithUnsupportedFeatures(t, compat.ImportAssertions,\n\t\t\"import 'x' with {y: 'z'}; import('x', {with: {y: 'z'}})\",\n\t\t\"import \\\"x\\\" with { y: \\\"z\\\" };\\nimport(\\\"x\\\", { with: { y: \\\"z\\\" } });\\n\")\n\texpectPrintedWithUnsupportedFeatures(t, compat.ImportAttributes,\n\t\t\"import 'x' with {y: 'z'}; import('x', {with: {y: 'z'}})\",\n\t\t\"import \\\"x\\\";\\nimport(\\\"x\\\", { with: { y: \\\"z\\\" } });\\n\")\n\texpectPrintedWithUnsupportedFeatures(t, compat.ImportAssertions|compat.ImportAttributes,\n\t\t\"import 'x' with {y: 'z'}; import('x', {with: {y: 'z'}})\",\n\t\t\"import \\\"x\\\";\\nimport(\\\"x\\\");\\n\")\n\n\t// Test the migration warning\n\texpectParseErrorWithUnsupportedFeatures(t, compat.ImportAssertions,\n\t\t\"import x from 'y' assert {type: 'json'}\",\n\t\t\"<stdin>: WARNING: The \\\"assert\\\" keyword is not supported in the configured target environment\\nNOTE: Did you mean to use \\\"with\\\" instead of \\\"assert\\\"?\\n\")\n\texpectParseErrorWithUnsupportedFeatures(t, compat.ImportAssertions,\n\t\t\"export {default} from 'y' assert {type: 'json'}\",\n\t\t\"<stdin>: WARNING: The \\\"assert\\\" keyword is not supported in the configured target environment\\nNOTE: Did you mean to use \\\"with\\\" instead of \\\"assert\\\"?\\n\")\n\texpectParseErrorWithUnsupportedFeatures(t, compat.ImportAssertions,\n\t\t\"import('y', {assert: {type: 'json'}})\",\n\t\t\"<stdin>: WARNING: The \\\"assert\\\" keyword is not supported in the configured target environment\\nNOTE: Did you mean to use \\\"with\\\" instead of \\\"assert\\\"?\\n\")\n}\n\nfunc TestES5(t *testing.T) {\n\t// Do not generate \"let\" when emulating block-level function declarations and targeting ES5\n\texpectPrintedTarget(t, 2015, \"if (1) function f() {}\", \"if (1) {\\n  let f = function() {\\n  };\\n  var f = f;\\n}\\n\")\n\texpectPrintedTarget(t, 5, \"if (1) function f() {}\", \"if (1) {\\n  var f = function() {\\n  };\\n  var f = f;\\n}\\n\")\n\n\texpectParseErrorTarget(t, 5, \"function foo(x = 0) {}\",\n\t\t\"<stdin>: ERROR: Transforming default arguments to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"(function(x = 0) {})\",\n\t\t\"<stdin>: ERROR: Transforming default arguments to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"(x = 0) => {}\",\n\t\t\"<stdin>: ERROR: Transforming default arguments to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"function foo(...x) {}\",\n\t\t\"<stdin>: ERROR: Transforming rest arguments to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"(function(...x) {})\",\n\t\t\"<stdin>: ERROR: Transforming rest arguments to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"(...x) => {}\",\n\t\t\"<stdin>: ERROR: Transforming rest arguments to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"foo(...x)\",\n\t\t\"<stdin>: ERROR: Transforming rest arguments to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"[...x]\",\n\t\t\"<stdin>: ERROR: Transforming array spread to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"for (var x of y) ;\",\n\t\t\"<stdin>: ERROR: Transforming for-of loops to the configured target environment is not supported yet\\n\")\n\texpectPrintedTarget(t, 5, \"({ x })\", \"({ x: x });\\n\")\n\texpectParseErrorTarget(t, 5, \"({ [x]: y })\",\n\t\t\"<stdin>: ERROR: Transforming object literal extensions to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"({ x() {} });\",\n\t\t\"<stdin>: ERROR: Transforming object literal extensions to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"({ get x() {} });\", \"\")\n\texpectParseErrorTarget(t, 5, \"({ set x(x) {} });\", \"\")\n\texpectParseErrorTarget(t, 5, \"({ get [x]() {} });\",\n\t\t\"<stdin>: ERROR: Transforming object literal extensions to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"({ set [x](x) {} });\",\n\t\t\"<stdin>: ERROR: Transforming object literal extensions to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"function foo([]) {}\",\n\t\t\"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"function foo({}) {}\",\n\t\t\"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"(function([]) {})\",\n\t\t\"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"(function({}) {})\",\n\t\t\"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"([]) => {}\",\n\t\t\"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"({}) => {}\",\n\t\t\"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"var [] = [];\",\n\t\t\"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"var {} = {};\",\n\t\t\"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"([] = []);\",\n\t\t\"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"({} = {});\",\n\t\t\"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"for ([] in []);\",\n\t\t\"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"for ({} in []);\",\n\t\t\"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"function foo([...x]) {}\",\n\t\t\"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"(function([...x]) {})\",\n\t\t\"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"([...x]) => {}\",\n\t\t\"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"function foo([...[x]]) {}\",\n\t\t`<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n<stdin>: ERROR: Transforming non-identifier array rest patterns to the configured target environment is not supported yet\n`)\n\texpectParseErrorTarget(t, 5, \"(function([...[x]]) {})\",\n\t\t`<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n<stdin>: ERROR: Transforming non-identifier array rest patterns to the configured target environment is not supported yet\n`)\n\texpectParseErrorTarget(t, 5, \"([...[x]]) => {}\",\n\t\t`<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\n<stdin>: ERROR: Transforming non-identifier array rest patterns to the configured target environment is not supported yet\n`)\n\texpectParseErrorTarget(t, 5, \"([...[x]])\",\n\t\t\"<stdin>: ERROR: Transforming array spread to the configured target environment is not supported yet\\n\")\n\texpectPrintedTarget(t, 5, \"`abc`;\", \"\\\"abc\\\";\\n\")\n\texpectPrintedTarget(t, 5, \"`a${b}`;\", \"\\\"a\\\".concat(b);\\n\")\n\texpectPrintedTarget(t, 5, \"`${a}b`;\", \"\\\"\\\".concat(a, \\\"b\\\");\\n\")\n\texpectPrintedTarget(t, 5, \"`${a}${b}`;\", \"\\\"\\\".concat(a).concat(b);\\n\")\n\texpectPrintedTarget(t, 5, \"`a${b}c`;\", \"\\\"a\\\".concat(b, \\\"c\\\");\\n\")\n\texpectPrintedTarget(t, 5, \"`a${b}${c}`;\", \"\\\"a\\\".concat(b).concat(c);\\n\")\n\texpectPrintedTarget(t, 5, \"`a${b}${c}d`;\", \"\\\"a\\\".concat(b).concat(c, \\\"d\\\");\\n\")\n\texpectPrintedTarget(t, 5, \"`a${b}c${d}`;\", \"\\\"a\\\".concat(b, \\\"c\\\").concat(d);\\n\")\n\texpectPrintedTarget(t, 5, \"`a${b}c${d}e`;\", \"\\\"a\\\".concat(b, \\\"c\\\").concat(d, \\\"e\\\");\\n\")\n\texpectPrintedTarget(t, 5, \"tag``;\", \"var _a;\\ntag(_a || (_a = __template([\\\"\\\"])));\\n\")\n\texpectPrintedTarget(t, 5, \"tag`abc`;\", \"var _a;\\ntag(_a || (_a = __template([\\\"abc\\\"])));\\n\")\n\texpectPrintedTarget(t, 5, \"tag`\\\\utf`;\", \"var _a;\\ntag(_a || (_a = __template([void 0], [\\\"\\\\\\\\utf\\\"])));\\n\")\n\texpectPrintedTarget(t, 5, \"tag`${a}b`;\", \"var _a;\\ntag(_a || (_a = __template([\\\"\\\", \\\"b\\\"])), a);\\n\")\n\texpectPrintedTarget(t, 5, \"tag`a${b}`;\", \"var _a;\\ntag(_a || (_a = __template([\\\"a\\\", \\\"\\\"])), b);\\n\")\n\texpectPrintedTarget(t, 5, \"tag`a${b}c`;\", \"var _a;\\ntag(_a || (_a = __template([\\\"a\\\", \\\"c\\\"])), b);\\n\")\n\texpectPrintedTarget(t, 5, \"tag`a${b}\\\\u`;\", \"var _a;\\ntag(_a || (_a = __template([\\\"a\\\", void 0], [\\\"a\\\", \\\"\\\\\\\\u\\\"])), b);\\n\")\n\texpectPrintedTarget(t, 5, \"tag`\\\\u${b}c`;\", \"var _a;\\ntag(_a || (_a = __template([void 0, \\\"c\\\"], [\\\"\\\\\\\\u\\\", \\\"c\\\"])), b);\\n\")\n\texpectParseErrorTarget(t, 5, \"class Foo { constructor() { new.target } }\",\n\t\t\"<stdin>: ERROR: Transforming class syntax to the configured target environment is not supported yet\\n\"+\n\t\t\t\"<stdin>: ERROR: Transforming object literal extensions to the configured target environment is not supported yet\\n\"+\n\t\t\t\"<stdin>: ERROR: Transforming new.target to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"const x = 1;\",\n\t\t\"<stdin>: ERROR: Transforming const to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"let x = 2;\",\n\t\t\"<stdin>: ERROR: Transforming let to the configured target environment is not supported yet\\n\")\n\texpectPrintedTarget(t, 5, \"async => foo;\", \"(function(async) {\\n  return foo;\\n});\\n\")\n\texpectPrintedTarget(t, 5, \"x => x;\", \"(function(x) {\\n  return x;\\n});\\n\")\n\texpectParseErrorTarget(t, 5, \"async () => foo;\",\n\t\t\"<stdin>: ERROR: Transforming async functions to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"class Foo {}\",\n\t\t\"<stdin>: ERROR: Transforming class syntax to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"(class {});\",\n\t\t\"<stdin>: ERROR: Transforming class syntax to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"function* gen() {}\",\n\t\t\"<stdin>: ERROR: Transforming generator functions to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"(function* () {});\",\n\t\t\"<stdin>: ERROR: Transforming generator functions to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTarget(t, 5, \"({ *foo() {} });\",\n\t\t\"<stdin>: ERROR: Transforming generator functions to the configured target environment is not supported yet\\n\")\n}\n\nfunc TestASCIIOnly(t *testing.T) {\n\tes5 := \"<stdin>: ERROR: \\\"𐀀\\\" cannot be escaped in the configured target environment \" +\n\t\t\"but you can set the charset to \\\"utf8\\\" to allow unescaped Unicode characters\\n\"\n\n\t// Some context: \"π\" is in the BMP (i.e. has a code point ≤0xFFFF) and \"𐀀\" is\n\t// not in the BMP (i.e. has a code point >0xFFFF). This distinction matters\n\t// because it's impossible to escape non-BMP characters before ES6.\n\n\texpectPrinted(t, \"π\", \"π;\\n\")\n\texpectPrinted(t, \"𐀀\", \"𐀀;\\n\")\n\texpectPrintedASCII(t, \"π\", \"\\\\u03C0;\\n\")\n\texpectPrintedASCII(t, \"𐀀\", \"\\\\u{10000};\\n\")\n\texpectPrintedTargetASCII(t, 5, \"π\", \"\\\\u03C0;\\n\")\n\texpectParseErrorTargetASCII(t, 5, \"𐀀\", es5)\n\n\texpectPrinted(t, \"var π\", \"var π;\\n\")\n\texpectPrinted(t, \"var 𐀀\", \"var 𐀀;\\n\")\n\texpectPrintedASCII(t, \"var π\", \"var \\\\u03C0;\\n\")\n\texpectPrintedASCII(t, \"var 𐀀\", \"var \\\\u{10000};\\n\")\n\texpectPrintedTargetASCII(t, 5, \"var π\", \"var \\\\u03C0;\\n\")\n\texpectParseErrorTargetASCII(t, 5, \"var 𐀀\", es5)\n\n\texpectPrinted(t, \"'π'\", \"\\\"π\\\";\\n\")\n\texpectPrinted(t, \"'𐀀'\", \"\\\"𐀀\\\";\\n\")\n\texpectPrintedASCII(t, \"'π'\", \"\\\"\\\\u03C0\\\";\\n\")\n\texpectPrintedASCII(t, \"'𐀀'\", \"\\\"\\\\u{10000}\\\";\\n\")\n\texpectPrintedTargetASCII(t, 5, \"'π'\", \"\\\"\\\\u03C0\\\";\\n\")\n\texpectPrintedTargetASCII(t, 5, \"'𐀀'\", \"\\\"\\\\uD800\\\\uDC00\\\";\\n\")\n\n\texpectPrinted(t, \"x.π\", \"x.π;\\n\")\n\texpectPrinted(t, \"x.𐀀\", \"x[\\\"𐀀\\\"];\\n\")\n\texpectPrintedASCII(t, \"x.π\", \"x.\\\\u03C0;\\n\")\n\texpectPrintedASCII(t, \"x.𐀀\", \"x[\\\"\\\\u{10000}\\\"];\\n\")\n\texpectPrintedTargetASCII(t, 5, \"x.π\", \"x.\\\\u03C0;\\n\")\n\texpectPrintedTargetASCII(t, 5, \"x.𐀀\", \"x[\\\"\\\\uD800\\\\uDC00\\\"];\\n\")\n\n\texpectPrinted(t, \"x?.π\", \"x?.π;\\n\")\n\texpectPrinted(t, \"x?.𐀀\", \"x?.[\\\"𐀀\\\"];\\n\")\n\texpectPrintedASCII(t, \"x?.π\", \"x?.\\\\u03C0;\\n\")\n\texpectPrintedASCII(t, \"x?.𐀀\", \"x?.[\\\"\\\\u{10000}\\\"];\\n\")\n\texpectPrintedTargetASCII(t, 5, \"x?.π\", \"x == null ? void 0 : x.\\\\u03C0;\\n\")\n\texpectPrintedTargetASCII(t, 5, \"x?.𐀀\", \"x == null ? void 0 : x[\\\"\\\\uD800\\\\uDC00\\\"];\\n\")\n\n\texpectPrinted(t, \"0 .π\", \"0 .π;\\n\")\n\texpectPrinted(t, \"0 .𐀀\", \"0[\\\"𐀀\\\"];\\n\")\n\texpectPrintedASCII(t, \"0 .π\", \"0 .\\\\u03C0;\\n\")\n\texpectPrintedASCII(t, \"0 .𐀀\", \"0[\\\"\\\\u{10000}\\\"];\\n\")\n\texpectPrintedTargetASCII(t, 5, \"0 .π\", \"0 .\\\\u03C0;\\n\")\n\texpectPrintedTargetASCII(t, 5, \"0 .𐀀\", \"0[\\\"\\\\uD800\\\\uDC00\\\"];\\n\")\n\n\texpectPrinted(t, \"0?.π\", \"0?.π;\\n\")\n\texpectPrinted(t, \"0?.𐀀\", \"0?.[\\\"𐀀\\\"];\\n\")\n\texpectPrintedASCII(t, \"0?.π\", \"0?.\\\\u03C0;\\n\")\n\texpectPrintedASCII(t, \"0?.𐀀\", \"0?.[\\\"\\\\u{10000}\\\"];\\n\")\n\texpectPrintedTargetASCII(t, 5, \"0?.π\", \"0 == null ? void 0 : 0 .\\\\u03C0;\\n\")\n\texpectPrintedTargetASCII(t, 5, \"0?.𐀀\", \"0 == null ? void 0 : 0[\\\"\\\\uD800\\\\uDC00\\\"];\\n\")\n\n\texpectPrinted(t, \"import 'π'\", \"import \\\"π\\\";\\n\")\n\texpectPrinted(t, \"import '𐀀'\", \"import \\\"𐀀\\\";\\n\")\n\texpectPrintedASCII(t, \"import 'π'\", \"import \\\"\\\\u03C0\\\";\\n\")\n\texpectPrintedASCII(t, \"import '𐀀'\", \"import \\\"\\\\u{10000}\\\";\\n\")\n\texpectPrintedTargetASCII(t, 5, \"import 'π'\", \"import \\\"\\\\u03C0\\\";\\n\")\n\texpectPrintedTargetASCII(t, 5, \"import '𐀀'\", \"import \\\"\\\\uD800\\\\uDC00\\\";\\n\")\n\n\texpectPrinted(t, \"({π: 0})\", \"({ π: 0 });\\n\")\n\texpectPrinted(t, \"({𐀀: 0})\", \"({ \\\"𐀀\\\": 0 });\\n\")\n\texpectPrintedASCII(t, \"({π: 0})\", \"({ \\\\u03C0: 0 });\\n\")\n\texpectPrintedASCII(t, \"({𐀀: 0})\", \"({ \\\"\\\\u{10000}\\\": 0 });\\n\")\n\texpectPrintedTargetASCII(t, 5, \"({π: 0})\", \"({ \\\\u03C0: 0 });\\n\")\n\texpectPrintedTargetASCII(t, 5, \"({𐀀: 0})\", \"({ \\\"\\\\uD800\\\\uDC00\\\": 0 });\\n\")\n\n\texpectPrinted(t, \"({π})\", \"({ π });\\n\")\n\texpectPrinted(t, \"({𐀀})\", \"({ \\\"𐀀\\\": 𐀀 });\\n\")\n\texpectPrintedASCII(t, \"({π})\", \"({ \\\\u03C0 });\\n\")\n\texpectPrintedASCII(t, \"({𐀀})\", \"({ \\\"\\\\u{10000}\\\": \\\\u{10000} });\\n\")\n\texpectPrintedTargetASCII(t, 5, \"({π})\", \"({ \\\\u03C0: \\\\u03C0 });\\n\")\n\texpectParseErrorTargetASCII(t, 5, \"({𐀀})\", es5)\n\n\texpectPrinted(t, \"import * as π from 'path'; π\", \"import * as π from \\\"path\\\";\\nπ;\\n\")\n\texpectPrinted(t, \"import * as 𐀀 from 'path'; 𐀀\", \"import * as 𐀀 from \\\"path\\\";\\n𐀀;\\n\")\n\texpectPrintedASCII(t, \"import * as π from 'path'; π\", \"import * as \\\\u03C0 from \\\"path\\\";\\n\\\\u03C0;\\n\")\n\texpectPrintedASCII(t, \"import * as 𐀀 from 'path'; 𐀀\", \"import * as \\\\u{10000} from \\\"path\\\";\\n\\\\u{10000};\\n\")\n\texpectPrintedTargetASCII(t, 5, \"import * as π from 'path'; π\", \"import * as \\\\u03C0 from \\\"path\\\";\\n\\\\u03C0;\\n\")\n\texpectParseErrorTargetASCII(t, 5, \"import * as 𐀀 from 'path'\", es5)\n\n\texpectPrinted(t, \"import {π} from 'path'; π\", \"import { π } from \\\"path\\\";\\nπ;\\n\")\n\texpectPrinted(t, \"import {𐀀} from 'path'; 𐀀\", \"import { 𐀀 } from \\\"path\\\";\\n𐀀;\\n\")\n\texpectPrintedASCII(t, \"import {π} from 'path'; π\", \"import { \\\\u03C0 } from \\\"path\\\";\\n\\\\u03C0;\\n\")\n\texpectPrintedASCII(t, \"import {𐀀} from 'path'; 𐀀\", \"import { \\\\u{10000} } from \\\"path\\\";\\n\\\\u{10000};\\n\")\n\texpectPrintedTargetASCII(t, 5, \"import {π} from 'path'; π\", \"import { \\\\u03C0 } from \\\"path\\\";\\n\\\\u03C0;\\n\")\n\texpectParseErrorTargetASCII(t, 5, \"import {𐀀} from 'path'\", es5)\n\n\texpectPrinted(t, \"import {π as x} from 'path'\", \"import { π as x } from \\\"path\\\";\\n\")\n\texpectPrinted(t, \"import {𐀀 as x} from 'path'\", \"import { 𐀀 as x } from \\\"path\\\";\\n\")\n\texpectPrintedASCII(t, \"import {π as x} from 'path'\", \"import { \\\\u03C0 as x } from \\\"path\\\";\\n\")\n\texpectPrintedASCII(t, \"import {𐀀 as x} from 'path'\", \"import { \\\\u{10000} as x } from \\\"path\\\";\\n\")\n\texpectPrintedTargetASCII(t, 5, \"import {π as x} from 'path'\", \"import { \\\\u03C0 as x } from \\\"path\\\";\\n\")\n\texpectParseErrorTargetASCII(t, 5, \"import {𐀀 as x} from 'path'\", es5)\n\n\texpectPrinted(t, \"import {x as π} from 'path'\", \"import { x as π } from \\\"path\\\";\\n\")\n\texpectPrinted(t, \"import {x as 𐀀} from 'path'\", \"import { x as 𐀀 } from \\\"path\\\";\\n\")\n\texpectPrintedASCII(t, \"import {x as π} from 'path'\", \"import { x as \\\\u03C0 } from \\\"path\\\";\\n\")\n\texpectPrintedASCII(t, \"import {x as 𐀀} from 'path'\", \"import { x as \\\\u{10000} } from \\\"path\\\";\\n\")\n\texpectPrintedTargetASCII(t, 5, \"import {x as π} from 'path'\", \"import { x as \\\\u03C0 } from \\\"path\\\";\\n\")\n\texpectParseErrorTargetASCII(t, 5, \"import {x as 𐀀} from 'path'\", es5)\n\n\texpectPrinted(t, \"export * as π from 'path'; π\", \"export * as π from \\\"path\\\";\\nπ;\\n\")\n\texpectPrinted(t, \"export * as 𐀀 from 'path'; 𐀀\", \"export * as 𐀀 from \\\"path\\\";\\n𐀀;\\n\")\n\texpectPrintedASCII(t, \"export * as π from 'path'; π\", \"export * as \\\\u03C0 from \\\"path\\\";\\n\\\\u03C0;\\n\")\n\texpectPrintedASCII(t, \"export * as 𐀀 from 'path'; 𐀀\", \"export * as \\\\u{10000} from \\\"path\\\";\\n\\\\u{10000};\\n\")\n\texpectPrintedTargetASCII(t, 5, \"export * as π from 'path'\", \"import * as \\\\u03C0 from \\\"path\\\";\\nexport { \\\\u03C0 };\\n\")\n\texpectParseErrorTargetASCII(t, 5, \"export * as 𐀀 from 'path'\", es5)\n\n\texpectPrinted(t, \"export {π} from 'path'; π\", \"export { π } from \\\"path\\\";\\nπ;\\n\")\n\texpectPrinted(t, \"export {𐀀} from 'path'; 𐀀\", \"export { 𐀀 } from \\\"path\\\";\\n𐀀;\\n\")\n\texpectPrintedASCII(t, \"export {π} from 'path'; π\", \"export { \\\\u03C0 } from \\\"path\\\";\\n\\\\u03C0;\\n\")\n\texpectPrintedASCII(t, \"export {𐀀} from 'path'; 𐀀\", \"export { \\\\u{10000} } from \\\"path\\\";\\n\\\\u{10000};\\n\")\n\texpectPrintedTargetASCII(t, 5, \"export {π} from 'path'; π\", \"export { \\\\u03C0 } from \\\"path\\\";\\n\\\\u03C0;\\n\")\n\texpectParseErrorTargetASCII(t, 5, \"export {𐀀} from 'path'\", es5)\n\n\texpectPrinted(t, \"export {π as x} from 'path'\", \"export { π as x } from \\\"path\\\";\\n\")\n\texpectPrinted(t, \"export {𐀀 as x} from 'path'\", \"export { 𐀀 as x } from \\\"path\\\";\\n\")\n\texpectPrintedASCII(t, \"export {π as x} from 'path'\", \"export { \\\\u03C0 as x } from \\\"path\\\";\\n\")\n\texpectPrintedASCII(t, \"export {𐀀 as x} from 'path'\", \"export { \\\\u{10000} as x } from \\\"path\\\";\\n\")\n\texpectPrintedTargetASCII(t, 5, \"export {π as x} from 'path'\", \"export { \\\\u03C0 as x } from \\\"path\\\";\\n\")\n\texpectParseErrorTargetASCII(t, 5, \"export {𐀀 as x} from 'path'\", es5)\n\n\texpectPrinted(t, \"export {x as π} from 'path'\", \"export { x as π } from \\\"path\\\";\\n\")\n\texpectPrinted(t, \"export {x as 𐀀} from 'path'\", \"export { x as 𐀀 } from \\\"path\\\";\\n\")\n\texpectPrintedASCII(t, \"export {x as π} from 'path'\", \"export { x as \\\\u03C0 } from \\\"path\\\";\\n\")\n\texpectPrintedASCII(t, \"export {x as 𐀀} from 'path'\", \"export { x as \\\\u{10000} } from \\\"path\\\";\\n\")\n\texpectPrintedTargetASCII(t, 5, \"export {x as π} from 'path'\", \"export { x as \\\\u03C0 } from \\\"path\\\";\\n\")\n\texpectParseErrorTargetASCII(t, 5, \"export {x as 𐀀} from 'path'\", es5)\n\n\texpectPrinted(t, \"export {π}; var π\", \"export { π };\\nvar π;\\n\")\n\texpectPrinted(t, \"export {𐀀}; var 𐀀\", \"export { 𐀀 };\\nvar 𐀀;\\n\")\n\texpectPrintedASCII(t, \"export {π}; var π\", \"export { \\\\u03C0 };\\nvar \\\\u03C0;\\n\")\n\texpectPrintedASCII(t, \"export {𐀀}; var 𐀀\", \"export { \\\\u{10000} };\\nvar \\\\u{10000};\\n\")\n\texpectPrintedTargetASCII(t, 5, \"export {π}; var π\", \"export { \\\\u03C0 };\\nvar \\\\u03C0;\\n\")\n\texpectParseErrorTargetASCII(t, 5, \"export {𐀀}; var 𐀀\", es5)\n\n\texpectPrinted(t, \"export var π\", \"export var π;\\n\")\n\texpectPrinted(t, \"export var 𐀀\", \"export var 𐀀;\\n\")\n\texpectPrintedASCII(t, \"export var π\", \"export var \\\\u03C0;\\n\")\n\texpectPrintedASCII(t, \"export var 𐀀\", \"export var \\\\u{10000};\\n\")\n\texpectPrintedTargetASCII(t, 5, \"export var π\", \"export var \\\\u03C0;\\n\")\n\texpectParseErrorTargetASCII(t, 5, \"export var 𐀀\", es5)\n}\n\nfunc TestMangleCatch(t *testing.T) {\n\texpectPrintedMangle(t, \"try { throw 0 } catch (e) { console.log(0) }\", \"try {\\n  throw 0;\\n} catch {\\n  console.log(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"try { throw 0 } catch (e) { console.log(0, e) }\", \"try {\\n  throw 0;\\n} catch (e) {\\n  console.log(0, e);\\n}\\n\")\n\texpectPrintedMangle(t, \"try { throw 0 } catch (e) { 0 && console.log(0, e) }\", \"try {\\n  throw 0;\\n} catch {\\n}\\n\")\n\texpectPrintedMangle(t, \"try { thrower() } catch ([a]) { console.log(0) }\", \"try {\\n  thrower();\\n} catch ([a]) {\\n  console.log(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"try { thrower() } catch ({ a }) { console.log(0) }\", \"try {\\n  thrower();\\n} catch ({ a }) {\\n  console.log(0);\\n}\\n\")\n\texpectPrintedMangleTarget(t, 2018, \"try { throw 0 } catch (e) { console.log(0) }\", \"try {\\n  throw 0;\\n} catch (e) {\\n  console.log(0);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"try { throw 1 } catch (x) { y(x); var x = 2; y(x) }\", \"try {\\n  throw 1;\\n} catch (x) {\\n  y(x);\\n  var x = 2;\\n  y(x);\\n}\\n\")\n\texpectPrintedMangle(t, \"try { throw 1 } catch (x) { var x = 2; y(x) }\", \"try {\\n  throw 1;\\n} catch (x) {\\n  var x = 2;\\n  y(x);\\n}\\n\")\n\texpectPrintedMangle(t, \"try { throw 1 } catch (x) { var x = 2 }\", \"try {\\n  throw 1;\\n} catch (x) {\\n  var x = 2;\\n}\\n\")\n\texpectPrintedMangle(t, \"try { throw 1 } catch (x) { eval('x') }\", \"try {\\n  throw 1;\\n} catch (x) {\\n  eval(\\\"x\\\");\\n}\\n\")\n\texpectPrintedMangle(t, \"if (y) try { throw 1 } catch (x) {} else eval('x')\", \"if (y) try {\\n  throw 1;\\n} catch {\\n}\\nelse eval(\\\"x\\\");\\n\")\n}\n\nfunc TestMangleTry(t *testing.T) {\n\texpectPrintedMangle(t, \"try { throw 0 } catch (e) { foo() }\", \"try {\\n  throw 0;\\n} catch {\\n  foo();\\n}\\n\")\n\texpectPrintedMangle(t, \"try {} catch (e) { var foo }\", \"try {\\n} catch {\\n  var foo;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"try {} catch (e) { foo() }\", \"\")\n\texpectPrintedMangle(t, \"try {} catch (e) { foo() } finally {}\", \"\")\n\n\texpectPrintedMangle(t, \"try {} finally { foo() }\", \"foo();\\n\")\n\texpectPrintedMangle(t, \"try {} catch (e) { foo() } finally { bar() }\", \"bar();\\n\")\n\n\texpectPrintedMangle(t, \"try {} finally { var x = foo() }\", \"var x = foo();\\n\")\n\texpectPrintedMangle(t, \"try {} catch (e) { foo() } finally { var x = bar() }\", \"var x = bar();\\n\")\n\n\texpectPrintedMangle(t, \"try {} finally { let x = foo() }\", \"{\\n  let x = foo();\\n}\\n\")\n\texpectPrintedMangle(t, \"try {} catch (e) { foo() } finally { let x = bar() }\", \"{\\n  let x = bar();\\n}\\n\")\n\n\texpectPrintedMangle(t, \"try { foo() } catch {}\", \"try {\\n  foo();\\n} catch {\\n}\\n\")\n\texpectPrintedMangle(t, \"try { foo() } catch {} finally {}\", \"try {\\n  foo();\\n} catch {\\n}\\n\")\n\texpectPrintedMangle(t, \"try { foo() } finally {}\", \"foo();\\n\")\n\n\texpectPrintedMangle(t, \"try { var x = foo() } catch {}\", \"try {\\n  var x = foo();\\n} catch {\\n}\\n\")\n\texpectPrintedMangle(t, \"try { var x = foo() } catch {} finally {}\", \"try {\\n  var x = foo();\\n} catch {\\n}\\n\")\n\texpectPrintedMangle(t, \"try { var x = foo() } finally {}\", \"var x = foo();\\n\")\n\n\texpectPrintedMangle(t, \"try { let x = foo() } catch {}\", \"try {\\n  let x = foo();\\n} catch {\\n}\\n\")\n\texpectPrintedMangle(t, \"try { let x = foo() } catch {} finally {}\", \"try {\\n  let x = foo();\\n} catch {\\n}\\n\")\n\texpectPrintedMangle(t, \"try { let x = foo() } finally {}\", \"{\\n  let x = foo();\\n}\\n\")\n\n\t// The Kotlin compiler apparently generates code like this.\n\t// See https://github.com/evanw/esbuild/issues/4064 for info.\n\texpectPrintedMangle(t, \"x: try { while (true) ; break x } catch {}\", \"x: try {\\n  for (; ; ) ;\\n  break x;\\n} catch {\\n}\\n\")\n\n\t// The TeaVM compiler apparently generates code like this.\n\t// See https://github.com/evanw/esbuild/issues/4351 for info.\n\texpectPrintedMangle(t, \"d: { e: { try { while (1) { break d } } catch { break e } } }\",\n\t\t\"d:\\n  e:\\n    try {\\n      for (; ; )\\n        break d;\\n    } catch {\\n      break e;\\n    }\\n\")\n}\n\nfunc TestAutoPureForObjectCreate(t *testing.T) {\n\texpectPrinted(t, \"Object.create(null)\", \"/* @__PURE__ */ Object.create(null);\\n\")\n\texpectPrinted(t, \"Object.create({})\", \"/* @__PURE__ */ Object.create({});\\n\")\n\n\texpectPrinted(t, \"Object.create()\", \"Object.create();\\n\")\n\texpectPrinted(t, \"Object.create(x)\", \"Object.create(x);\\n\")\n\texpectPrinted(t, \"Object.create(undefined)\", \"Object.create(void 0);\\n\")\n}\n\nfunc TestAutoPureForSet(t *testing.T) {\n\texpectPrinted(t, \"new Set\", \"/* @__PURE__ */ new Set();\\n\")\n\texpectPrinted(t, \"new Set(null)\", \"/* @__PURE__ */ new Set(null);\\n\")\n\texpectPrinted(t, \"new Set(undefined)\", \"/* @__PURE__ */ new Set(void 0);\\n\")\n\texpectPrinted(t, \"new Set([])\", \"/* @__PURE__ */ new Set([]);\\n\")\n\texpectPrinted(t, \"new Set([x])\", \"/* @__PURE__ */ new Set([x]);\\n\")\n\n\texpectPrinted(t, \"new Set(x)\", \"new Set(x);\\n\")\n\texpectPrinted(t, \"new Set(false)\", \"new Set(false);\\n\")\n\texpectPrinted(t, \"new Set({})\", \"new Set({});\\n\")\n\texpectPrinted(t, \"new Set({ x })\", \"new Set({ x });\\n\")\n}\n\nfunc TestAutoPureForMap(t *testing.T) {\n\texpectPrinted(t, \"new Map\", \"/* @__PURE__ */ new Map();\\n\")\n\texpectPrinted(t, \"new Map(null)\", \"/* @__PURE__ */ new Map(null);\\n\")\n\texpectPrinted(t, \"new Map(undefined)\", \"/* @__PURE__ */ new Map(void 0);\\n\")\n\texpectPrinted(t, \"new Map([])\", \"/* @__PURE__ */ new Map([]);\\n\")\n\texpectPrinted(t, \"new Map([[]])\", \"/* @__PURE__ */ new Map([[]]);\\n\")\n\texpectPrinted(t, \"new Map([[], []])\", \"/* @__PURE__ */ new Map([[], []]);\\n\")\n\n\texpectPrinted(t, \"new Map(x)\", \"new Map(x);\\n\")\n\texpectPrinted(t, \"new Map(false)\", \"new Map(false);\\n\")\n\texpectPrinted(t, \"new Map([x])\", \"new Map([x]);\\n\")\n\texpectPrinted(t, \"new Map([x, []])\", \"new Map([x, []]);\\n\")\n\texpectPrinted(t, \"new Map([[], x])\", \"new Map([[], x]);\\n\")\n}\n\nfunc TestAutoPureForWeakSet(t *testing.T) {\n\texpectPrinted(t, \"new WeakSet\", \"/* @__PURE__ */ new WeakSet();\\n\")\n\texpectPrinted(t, \"new WeakSet(null)\", \"/* @__PURE__ */ new WeakSet(null);\\n\")\n\texpectPrinted(t, \"new WeakSet(undefined)\", \"/* @__PURE__ */ new WeakSet(void 0);\\n\")\n\texpectPrinted(t, \"new WeakSet([])\", \"/* @__PURE__ */ new WeakSet([]);\\n\")\n\n\texpectPrinted(t, \"new WeakSet([x])\", \"new WeakSet([x]);\\n\")\n\texpectPrinted(t, \"new WeakSet(x)\", \"new WeakSet(x);\\n\")\n\texpectPrinted(t, \"new WeakSet(false)\", \"new WeakSet(false);\\n\")\n\texpectPrinted(t, \"new WeakSet({})\", \"new WeakSet({});\\n\")\n\texpectPrinted(t, \"new WeakSet({ x })\", \"new WeakSet({ x });\\n\")\n}\n\nfunc TestAutoPureForWeakMap(t *testing.T) {\n\texpectPrinted(t, \"new WeakMap\", \"/* @__PURE__ */ new WeakMap();\\n\")\n\texpectPrinted(t, \"new WeakMap(null)\", \"/* @__PURE__ */ new WeakMap(null);\\n\")\n\texpectPrinted(t, \"new WeakMap(undefined)\", \"/* @__PURE__ */ new WeakMap(void 0);\\n\")\n\texpectPrinted(t, \"new WeakMap([])\", \"/* @__PURE__ */ new WeakMap([]);\\n\")\n\n\texpectPrinted(t, \"new WeakMap([[]])\", \"new WeakMap([[]]);\\n\")\n\texpectPrinted(t, \"new WeakMap([[], []])\", \"new WeakMap([[], []]);\\n\")\n\texpectPrinted(t, \"new WeakMap(x)\", \"new WeakMap(x);\\n\")\n\texpectPrinted(t, \"new WeakMap(false)\", \"new WeakMap(false);\\n\")\n\texpectPrinted(t, \"new WeakMap([x])\", \"new WeakMap([x]);\\n\")\n\texpectPrinted(t, \"new WeakMap([x, []])\", \"new WeakMap([x, []]);\\n\")\n\texpectPrinted(t, \"new WeakMap([[], x])\", \"new WeakMap([[], x]);\\n\")\n}\n\nfunc TestAutoPureForDate(t *testing.T) {\n\texpectPrinted(t, \"new Date\", \"/* @__PURE__ */ new Date();\\n\")\n\texpectPrinted(t, \"new Date(0)\", \"/* @__PURE__ */ new Date(0);\\n\")\n\texpectPrinted(t, \"new Date('')\", \"/* @__PURE__ */ new Date(\\\"\\\");\\n\")\n\texpectPrinted(t, \"new Date(null)\", \"/* @__PURE__ */ new Date(null);\\n\")\n\texpectPrinted(t, \"new Date(true)\", \"/* @__PURE__ */ new Date(true);\\n\")\n\texpectPrinted(t, \"new Date(false)\", \"/* @__PURE__ */ new Date(false);\\n\")\n\texpectPrinted(t, \"new Date(undefined)\", \"/* @__PURE__ */ new Date(void 0);\\n\")\n\texpectPrinted(t, \"new Date(`${foo}`)\", \"/* @__PURE__ */ new Date(`${foo}`);\\n\")\n\texpectPrinted(t, \"new Date(foo ? 'x' : 'y')\", \"/* @__PURE__ */ new Date(foo ? \\\"x\\\" : \\\"y\\\");\\n\")\n\n\texpectPrinted(t, \"new Date(foo)\", \"new Date(foo);\\n\")\n\texpectPrinted(t, \"new Date(foo``)\", \"new Date(foo``);\\n\")\n\texpectPrinted(t, \"new Date(foo ? x : y)\", \"new Date(foo ? x : y);\\n\")\n}\n\nfunc TestAutoPureForRegExpEscape(t *testing.T) {\n\texpectPrinted(t, \"RegExp.escape('x')\", \"/* @__PURE__ */ RegExp.escape(\\\"x\\\");\\n\")\n\texpectPrinted(t, \"RegExp.escape(`${x}`)\", \"/* @__PURE__ */ RegExp.escape(`${x}`);\\n\")\n\texpectPrinted(t, \"RegExp.escape(x ? 'y' : 'z')\", \"/* @__PURE__ */ RegExp.escape(x ? \\\"y\\\" : \\\"z\\\");\\n\")\n\n\texpectPrinted(t, \"RegExp.escape()\", \"RegExp.escape();\\n\")\n\texpectPrinted(t, \"RegExp.escape(x`y`)\", \"RegExp.escape(x`y`);\\n\")\n\texpectPrinted(t, \"RegExp.escape('x', 'y')\", \"RegExp.escape(\\\"x\\\", \\\"y\\\");\\n\")\n\texpectPrinted(t, \"RegExp.escape(x ? 'y' : z)\", \"RegExp.escape(x ? \\\"y\\\" : z);\\n\")\n\texpectPrinted(t, \"RegExp.escape(x ? y : 'z')\", \"RegExp.escape(x ? y : \\\"z\\\");\\n\")\n}\n\n// See: https://github.com/tc39/proposal-explicit-resource-management\nfunc TestUsing(t *testing.T) {\n\texpectPrinted(t, \"using x = y\", \"using x = y;\\n\")\n\texpectPrinted(t, \"using x = y; z\", \"using x = y;\\nz;\\n\")\n\texpectPrinted(t, \"using x = y, z = _\", \"using x = y, z = _;\\n\")\n\texpectPrinted(t, \"using x = y, \\n z = _\", \"using x = y, z = _;\\n\")\n\texpectPrinted(t, \"using \\n x = y\", \"using;\\nx = y;\\n\")\n\texpectPrinted(t, \"using [x]\", \"using[x];\\n\")\n\texpectPrinted(t, \"using [x] = y\", \"using[x] = y;\\n\")\n\texpectPrinted(t, \"using \\n [x] = y\", \"using[x] = y;\\n\")\n\texpectParseError(t, \"using x\", \"<stdin>: ERROR: The declaration \\\"x\\\" must be initialized\\n\")\n\texpectParseError(t, \"using {x}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"{\\\"\\n\")\n\texpectParseError(t, \"using x = y, z\", \"<stdin>: ERROR: The declaration \\\"z\\\" must be initialized\\n\")\n\texpectParseError(t, \"using x = y, [z] = _\", \"<stdin>: ERROR: Expected identifier but found \\\"[\\\"\\n\")\n\texpectParseError(t, \"using x = y, {z} = _\", \"<stdin>: ERROR: Expected identifier but found \\\"{\\\"\\n\")\n\texpectParseError(t, \"export using x = y\", \"<stdin>: ERROR: Unexpected \\\"using\\\"\\n\")\n\n\texpectPrinted(t, \"for (using x = y;;) ;\", \"for (using x = y; ; ) ;\\n\")\n\texpectPrinted(t, \"for (using x of y) ;\", \"for (using x of y) ;\\n\")\n\texpectPrinted(t, \"for (using of x) ;\", \"for (using of x) ;\\n\")\n\texpectPrinted(t, \"for (using of of) ;\", \"for (using of of) ;\\n\")\n\texpectPrinted(t, \"for (await using of of x) ;\", \"for (await using of of x) ;\\n\")\n\texpectPrinted(t, \"for (await using of of of) ;\", \"for (await using of of of) ;\\n\")\n\texpectPrinted(t, \"for await (using x of y) ;\", \"for await (using x of y) ;\\n\")\n\texpectPrinted(t, \"for await (using of x) ;\", \"for await (using of x) ;\\n\")\n\texpectParseError(t, \"for (using of of x) ;\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"for (using of of of) ;\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"of\\\"\\n\")\n\texpectParseError(t, \"for (using x in y) ;\", \"<stdin>: ERROR: \\\"using\\\" declarations are not allowed here\\n\")\n\texpectParseError(t, \"for (using x;;) ;\", \"<stdin>: ERROR: The declaration \\\"x\\\" must be initialized\\n\")\n\texpectParseError(t, \"for (using x = y of z) ;\", \"<stdin>: ERROR: for-of loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (using \\n x of y) ;\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"for await (using x = y of z) ;\", \"<stdin>: ERROR: for-of loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for await (using \\n x of y) ;\", \"<stdin>: ERROR: Expected \\\"of\\\" but found \\\"x\\\"\\n\")\n\n\texpectPrinted(t, \"await using \\n x = y\", \"await using;\\nx = y;\\n\")\n\texpectPrinted(t, \"await \\n using \\n x \\n = \\n y\", \"await using;\\nx = y;\\n\")\n\texpectPrinted(t, \"await using [x]\", \"await using[x];\\n\")\n\texpectPrinted(t, \"await using ([x] = y)\", \"await using([x] = y);\\n\")\n\texpectPrinted(t, \"await (using [x] = y)\", \"await (using[x] = y);\\n\")\n\texpectParseError(t, \"await using [x] = y\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseError(t, \"for (await using x in y) ;\", \"<stdin>: ERROR: \\\"await using\\\" declarations are not allowed here\\n\")\n\texpectParseError(t, \"for (await using x = y;;) ;\", \"<stdin>: ERROR: \\\"await using\\\" declarations are not allowed here\\n\")\n\texpectParseError(t, \"for (await using of x) ;\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"for (await using x = y of z) ;\", \"<stdin>: ERROR: for-of loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for (await using \\n x of y) ;\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"for await (await using of x) ;\", \"<stdin>: ERROR: Expected \\\"of\\\" but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"for await (await using x = y of z) ;\", \"<stdin>: ERROR: for-of loop variables cannot have an initializer\\n\")\n\texpectParseError(t, \"for await (await using \\n x of y) ;\", \"<stdin>: ERROR: Expected \\\"of\\\" but found \\\"x\\\"\\n\")\n\n\texpectPrinted(t, \"await using x = y\", \"await using x = y;\\n\")\n\texpectPrinted(t, \"await using x = y, z = _\", \"await using x = y, z = _;\\n\")\n\texpectPrinted(t, \"for (await using x of y) ;\", \"for (await using x of y) ;\\n\")\n\texpectPrinted(t, \"for await (await using x of y) ;\", \"for await (await using x of y) ;\\n\")\n\n\texpectPrinted(t, \"function foo() { using x = y }\", \"function foo() {\\n  using x = y;\\n}\\n\")\n\texpectPrinted(t, \"foo = function() { using x = y }\", \"foo = function() {\\n  using x = y;\\n};\\n\")\n\texpectPrinted(t, \"foo = () => { using x = y }\", \"foo = () => {\\n  using x = y;\\n};\\n\")\n\texpectPrinted(t, \"async function foo() { using x = y }\", \"async function foo() {\\n  using x = y;\\n}\\n\")\n\texpectPrinted(t, \"foo = async function() { using x = y }\", \"foo = async function() {\\n  using x = y;\\n};\\n\")\n\texpectPrinted(t, \"foo = async () => { using x = y }\", \"foo = async () => {\\n  using x = y;\\n};\\n\")\n\texpectPrinted(t, \"async function foo() { await using x = y }\", \"async function foo() {\\n  await using x = y;\\n}\\n\")\n\texpectPrinted(t, \"foo = async function() { await using x = y }\", \"foo = async function() {\\n  await using x = y;\\n};\\n\")\n\texpectPrinted(t, \"foo = async () => { await using x = y }\", \"foo = async () => {\\n  await using x = y;\\n};\\n\")\n\n\texpectParseError(t, \"export using x = y\", \"<stdin>: ERROR: Unexpected \\\"using\\\"\\n\")\n\texpectParseError(t, \"export await using x = y\", \"<stdin>: ERROR: Unexpected \\\"await\\\"\\n\")\n\n\tneedAsync := \"<stdin>: ERROR: \\\"await\\\" can only be used inside an \\\"async\\\" function\\n<stdin>: NOTE: Consider adding the \\\"async\\\" keyword here:\\n\"\n\texpectParseError(t, \"function foo() { await using x = y }\", needAsync)\n\texpectParseError(t, \"foo = function() { await using x = y }\", needAsync)\n\texpectParseError(t, \"foo = () => { await using x = y }\", needAsync)\n\n\t// Can't use await at the top-level without top-level await\n\terr := \"<stdin>: ERROR: Top-level await is not available in the configured target environment\\n\"\n\texpectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, \"await using x = y;\", err)\n\texpectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, \"for (await using x of y) ;\", err)\n\texpectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, \"if (true) { await using x = y }\", err)\n\texpectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, \"if (true) for (await using x of y) ;\", err)\n\texpectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, \"if (false) { await using x = y }\", \"if (false) {\\n  using x = y;\\n}\\n\")\n\texpectPrintedWithUnsupportedFeatures(t, compat.TopLevelAwait, \"if (false) for (await using x of y) ;\", \"if (false) for (using x of y) ;\\n\")\n\texpectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, \"with (x) y; if (false) { await using x = y }\",\n\t\t\"<stdin>: ERROR: With statements cannot be used in an ECMAScript module\\n\"+\n\t\t\t\"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the top-level \\\"await\\\" keyword here:\\n\")\n\texpectParseErrorWithUnsupportedFeatures(t, compat.TopLevelAwait, \"with (x) y; if (false) for (await using x of y) ;\",\n\t\t\"<stdin>: ERROR: With statements cannot be used in an ECMAScript module\\n\"+\n\t\t\t\"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the top-level \\\"await\\\" keyword here:\\n\")\n\n\t// Optimization: \"using\" declarations initialized to null or undefined can avoid the \"using\" machinery\n\texpectPrinted(t, \"using x = {}\", \"using x = {};\\n\")\n\texpectPrinted(t, \"using x = null\", \"using x = null;\\n\")\n\texpectPrinted(t, \"using x = undefined\", \"using x = void 0;\\n\")\n\texpectPrinted(t, \"using x = (foo, y)\", \"using x = (foo, y);\\n\")\n\texpectPrinted(t, \"using x = (foo, null)\", \"using x = (foo, null);\\n\")\n\texpectPrinted(t, \"using x = (foo, undefined)\", \"using x = (foo, void 0);\\n\")\n\texpectPrintedMangle(t, \"using x = {}\", \"using x = {};\\n\")\n\texpectPrintedMangle(t, \"using x = null\", \"const x = null;\\n\")\n\texpectPrintedMangle(t, \"using x = undefined\", \"const x = void 0;\\n\")\n\texpectPrintedMangle(t, \"using x = (foo, y)\", \"using x = (foo, y);\\n\")\n\texpectPrintedMangle(t, \"using x = (foo, null)\", \"const x = (foo, null);\\n\")\n\texpectPrintedMangle(t, \"using x = (foo, undefined)\", \"const x = (foo, void 0);\\n\")\n\texpectPrintedMangle(t, \"using x = null, y = undefined\", \"const x = null, y = void 0;\\n\")\n\texpectPrintedMangle(t, \"using x = null, y = z\", \"using x = null, y = z;\\n\")\n\texpectPrintedMangle(t, \"using x = z, y = undefined\", \"using x = z, y = void 0;\\n\")\n}\n"
  },
  {
    "path": "internal/js_parser/json_parser.go",
    "content": "package js_parser\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/js_lexer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\ntype jsonParser struct {\n\tlog                            logger.Log\n\tsource                         logger.Source\n\ttracker                        logger.LineColumnTracker\n\tlexer                          js_lexer.Lexer\n\toptions                        JSONOptions\n\tsuppressWarningsAboutWeirdCode bool\n}\n\nfunc (p *jsonParser) parseMaybeTrailingComma(closeToken js_lexer.T) bool {\n\tcommaRange := p.lexer.Range()\n\tp.lexer.Expect(js_lexer.TComma)\n\n\tif p.lexer.Token == closeToken {\n\t\tif p.options.Flavor == js_lexer.JSON {\n\t\t\tp.log.AddError(&p.tracker, commaRange, \"JSON does not support trailing commas\")\n\t\t}\n\t\treturn false\n\t}\n\n\treturn true\n}\n\nfunc (p *jsonParser) parseExpr() js_ast.Expr {\n\tloc := p.lexer.Loc()\n\n\tswitch p.lexer.Token {\n\tcase js_lexer.TFalse:\n\t\tp.lexer.Next()\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EBoolean{Value: false}}\n\n\tcase js_lexer.TTrue:\n\t\tp.lexer.Next()\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EBoolean{Value: true}}\n\n\tcase js_lexer.TNull:\n\t\tp.lexer.Next()\n\t\treturn js_ast.Expr{Loc: loc, Data: js_ast.ENullShared}\n\n\tcase js_lexer.TStringLiteral:\n\t\tvalue := p.lexer.StringLiteral()\n\t\tp.lexer.Next()\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EString{Value: value}}\n\n\tcase js_lexer.TNumericLiteral:\n\t\tvalue := p.lexer.Number\n\t\tp.lexer.Next()\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.ENumber{Value: value}}\n\n\tcase js_lexer.TMinus:\n\t\tp.lexer.Next()\n\t\tvalue := p.lexer.Number\n\t\tp.lexer.Expect(js_lexer.TNumericLiteral)\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.ENumber{Value: -value}}\n\n\tcase js_lexer.TOpenBracket:\n\t\tp.lexer.Next()\n\t\tisSingleLine := !p.lexer.HasNewlineBefore\n\t\titems := []js_ast.Expr{}\n\n\t\tfor p.lexer.Token != js_lexer.TCloseBracket {\n\t\t\tif len(items) > 0 {\n\t\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\t\tisSingleLine = false\n\t\t\t\t}\n\t\t\t\tif !p.parseMaybeTrailingComma(js_lexer.TCloseBracket) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\t\tisSingleLine = false\n\t\t\t\t}\n\t\t\t}\n\n\t\t\titem := p.parseExpr()\n\t\t\titems = append(items, item)\n\t\t}\n\n\t\tif p.lexer.HasNewlineBefore {\n\t\t\tisSingleLine = false\n\t\t}\n\t\tcloseBracketLoc := p.lexer.Loc()\n\t\tp.lexer.Expect(js_lexer.TCloseBracket)\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EArray{\n\t\t\tItems:           items,\n\t\t\tIsSingleLine:    isSingleLine,\n\t\t\tCloseBracketLoc: closeBracketLoc,\n\t\t}}\n\n\tcase js_lexer.TOpenBrace:\n\t\tp.lexer.Next()\n\t\tisSingleLine := !p.lexer.HasNewlineBefore\n\t\tproperties := []js_ast.Property{}\n\t\tduplicates := make(map[string]logger.Range)\n\n\t\tfor p.lexer.Token != js_lexer.TCloseBrace {\n\t\t\tif len(properties) > 0 {\n\t\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\t\tisSingleLine = false\n\t\t\t\t}\n\t\t\t\tif !p.parseMaybeTrailingComma(js_lexer.TCloseBrace) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\t\tisSingleLine = false\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tkeyString := p.lexer.StringLiteral()\n\t\t\tkeyRange := p.lexer.Range()\n\t\t\tkey := js_ast.Expr{Loc: keyRange.Loc, Data: &js_ast.EString{Value: keyString}}\n\t\t\tp.lexer.Expect(js_lexer.TStringLiteral)\n\n\t\t\t// Warn about duplicate keys\n\t\t\tif !p.suppressWarningsAboutWeirdCode {\n\t\t\t\tkeyText := helpers.UTF16ToString(keyString)\n\t\t\t\tif prevRange, ok := duplicates[keyText]; ok {\n\t\t\t\t\tp.log.AddIDWithNotes(logger.MsgID_JS_DuplicateObjectKey, logger.Warning, &p.tracker, keyRange,\n\t\t\t\t\t\tfmt.Sprintf(\"Duplicate key %q in object literal\", keyText),\n\t\t\t\t\t\t[]logger.MsgData{p.tracker.MsgData(prevRange, fmt.Sprintf(\"The original key %q is here:\", keyText))})\n\t\t\t\t} else {\n\t\t\t\t\tduplicates[keyText] = keyRange\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.lexer.Expect(js_lexer.TColon)\n\t\t\tvalue := p.parseExpr()\n\n\t\t\tproperty := js_ast.Property{\n\t\t\t\tKind:       js_ast.PropertyField,\n\t\t\t\tLoc:        keyRange.Loc,\n\t\t\t\tKey:        key,\n\t\t\t\tValueOrNil: value,\n\t\t\t}\n\n\t\t\t// The key \"__proto__\" must not be a string literal in JavaScript because\n\t\t\t// that actually modifies the prototype of the object. This can be\n\t\t\t// avoided by using a computed property key instead of a string literal.\n\t\t\tif helpers.UTF16EqualsString(keyString, \"__proto__\") && !p.options.UnsupportedJSFeatures.Has(compat.ObjectExtensions) {\n\t\t\t\tproperty.Flags |= js_ast.PropertyIsComputed\n\t\t\t}\n\n\t\t\tproperties = append(properties, property)\n\t\t}\n\n\t\tif p.lexer.HasNewlineBefore {\n\t\t\tisSingleLine = false\n\t\t}\n\t\tcloseBraceLoc := p.lexer.Loc()\n\t\tp.lexer.Expect(js_lexer.TCloseBrace)\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EObject{\n\t\t\tProperties:    properties,\n\t\t\tIsSingleLine:  isSingleLine,\n\t\t\tCloseBraceLoc: closeBraceLoc,\n\t\t}}\n\n\tcase js_lexer.TBigIntegerLiteral:\n\t\tif !p.options.IsForDefine {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t\tvalue := p.lexer.Identifier\n\t\tp.lexer.Next()\n\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EBigInt{Value: value.String}}\n\n\tdefault:\n\t\tp.lexer.Unexpected()\n\t\treturn js_ast.Expr{}\n\t}\n}\n\ntype JSONOptions struct {\n\tUnsupportedJSFeatures compat.JSFeature\n\tFlavor                js_lexer.JSONFlavor\n\tErrorSuffix           string\n\tIsForDefine           bool\n}\n\nfunc ParseJSON(log logger.Log, source logger.Source, options JSONOptions) (result js_ast.Expr, ok bool) {\n\tok = true\n\tdefer func() {\n\t\tr := recover()\n\t\tif _, isLexerPanic := r.(js_lexer.LexerPanic); isLexerPanic {\n\t\t\tok = false\n\t\t} else if r != nil {\n\t\t\tpanic(r)\n\t\t}\n\t}()\n\n\tif options.ErrorSuffix == \"\" {\n\t\toptions.ErrorSuffix = \" in JSON\"\n\t}\n\n\tp := &jsonParser{\n\t\tlog:                            log,\n\t\tsource:                         source,\n\t\ttracker:                        logger.MakeLineColumnTracker(&source),\n\t\toptions:                        options,\n\t\tlexer:                          js_lexer.NewLexerJSON(log, source, options.Flavor, options.ErrorSuffix),\n\t\tsuppressWarningsAboutWeirdCode: helpers.IsInsideNodeModules(source.KeyPath.Text),\n\t}\n\n\tresult = p.parseExpr()\n\tp.lexer.Expect(js_lexer.TEndOfFile)\n\treturn\n}\n\nfunc isValidJSON(value js_ast.Expr) bool {\n\tswitch e := value.Data.(type) {\n\tcase *js_ast.ENull, *js_ast.EBoolean, *js_ast.EString, *js_ast.ENumber:\n\t\treturn true\n\n\tcase *js_ast.EArray:\n\t\tfor _, item := range e.Items {\n\t\t\tif !isValidJSON(item) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\n\tcase *js_ast.EObject:\n\t\tfor _, property := range e.Properties {\n\t\t\tif property.Kind != js_ast.PropertyField || property.Flags.Has(js_ast.PropertyIsComputed) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif _, ok := property.Key.Data.(*js_ast.EString); !ok {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif !isValidJSON(property.ValueOrNil) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "internal/js_parser/json_parser_test.go",
    "content": "package js_parser\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/js_printer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/test\"\n)\n\nfunc expectParseErrorJSON(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\tt.Run(contents, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\t\tParseJSON(log, test.SourceForTest(contents), JSONOptions{})\n\t\tmsgs := log.Done()\n\t\tvar text strings.Builder\n\t\tfor _, msg := range msgs {\n\t\t\ttext.WriteString(msg.String(logger.OutputOptions{}, logger.TerminalInfo{}))\n\t\t}\n\t\ttest.AssertEqualWithDiff(t, text.String(), expected)\n\t})\n}\n\n// Note: The input is parsed as JSON but printed as JS. This means the printed\n// code may not be valid JSON. That's ok because esbuild always outputs JS\n// bundles, not JSON bundles.\nfunc expectPrintedJSON(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedJSONWithWarning(t, contents, \"\", expected)\n}\n\nfunc expectPrintedJSONWithWarning(t *testing.T, contents string, warning string, expected string) {\n\tt.Helper()\n\tt.Run(contents, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\t\texpr, ok := ParseJSON(log, test.SourceForTest(contents), JSONOptions{})\n\t\tmsgs := log.Done()\n\t\tvar text strings.Builder\n\t\tfor _, msg := range msgs {\n\t\t\ttext.WriteString(msg.String(logger.OutputOptions{}, logger.TerminalInfo{}))\n\t\t}\n\t\ttest.AssertEqualWithDiff(t, text.String(), warning)\n\t\tif !ok {\n\t\t\tt.Fatal(\"Parse error\")\n\t\t}\n\n\t\t// Insert this expression into a statement\n\t\ttree := js_ast.AST{\n\t\t\tParts: []js_ast.Part{{Stmts: []js_ast.Stmt{{Data: &js_ast.SExpr{Value: expr}}}}},\n\t\t}\n\n\t\tjs := js_printer.Print(tree, ast.SymbolMap{}, nil, js_printer.Options{\n\t\t\tMinifyWhitespace: true,\n\t\t}).JS\n\n\t\t// Remove the trailing semicolon\n\t\tif n := len(js); n > 1 && js[n-1] == ';' {\n\t\t\tjs = js[:n-1]\n\t\t}\n\n\t\ttest.AssertEqualWithDiff(t, string(js), expected)\n\t})\n}\n\nfunc TestJSONAtom(t *testing.T) {\n\texpectPrintedJSON(t, \"false\", \"false\")\n\texpectPrintedJSON(t, \"true\", \"true\")\n\texpectPrintedJSON(t, \"null\", \"null\")\n\texpectParseErrorJSON(t, \"undefined\", \"<stdin>: ERROR: Unexpected \\\"undefined\\\" in JSON\\n\")\n}\n\nfunc TestJSONString(t *testing.T) {\n\texpectPrintedJSON(t, \"\\\"x\\\"\", \"\\\"x\\\"\")\n\texpectParseErrorJSON(t, \"'x'\", \"<stdin>: ERROR: JSON strings must use double quotes\\n\")\n\texpectParseErrorJSON(t, \"`x`\", \"<stdin>: ERROR: Unexpected \\\"`x`\\\" in JSON\\n\")\n\n\t// Newlines\n\texpectPrintedJSON(t, \"\\\"\\u2028\\\"\", \"\\\"\\\\u2028\\\"\")\n\texpectPrintedJSON(t, \"\\\"\\u2029\\\"\", \"\\\"\\\\u2029\\\"\")\n\texpectParseErrorJSON(t, \"\\\"\\r\\\"\", \"<stdin>: ERROR: Unterminated string literal\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\n\\\"\", \"<stdin>: ERROR: Unterminated string literal\\n\")\n\n\t// Control characters\n\tfor c := 0; c < 0x20; c++ {\n\t\tif c != '\\r' && c != '\\n' {\n\t\t\texpectParseErrorJSON(t, fmt.Sprintf(\"\\\"%c\\\"\", c),\n\t\t\t\tfmt.Sprintf(\"<stdin>: ERROR: Syntax error \\\"\\\\x%02X\\\"\\n\", c))\n\t\t}\n\t}\n\n\t// Valid escapes\n\texpectPrintedJSON(t, \"\\\"\\\\\\\"\\\"\", \"'\\\"'\")\n\texpectPrintedJSON(t, \"\\\"\\\\\\\\\\\"\", \"\\\"\\\\\\\\\\\"\")\n\texpectPrintedJSON(t, \"\\\"\\\\/\\\"\", \"\\\"/\\\"\")\n\texpectPrintedJSON(t, \"\\\"\\\\b\\\"\", \"\\\"\\\\b\\\"\")\n\texpectPrintedJSON(t, \"\\\"\\\\f\\\"\", \"\\\"\\\\f\\\"\")\n\texpectPrintedJSON(t, \"\\\"\\\\n\\\"\", \"\\\"\\\\n\\\"\")\n\texpectPrintedJSON(t, \"\\\"\\\\r\\\"\", \"\\\"\\\\r\\\"\")\n\texpectPrintedJSON(t, \"\\\"\\\\t\\\"\", \"\\\"\\t\\\"\")\n\texpectPrintedJSON(t, \"\\\"\\\\u0000\\\"\", \"\\\"\\\\0\\\"\")\n\texpectPrintedJSON(t, \"\\\"\\\\u0078\\\"\", \"\\\"x\\\"\")\n\texpectPrintedJSON(t, \"\\\"\\\\u1234\\\"\", \"\\\"\\u1234\\\"\")\n\texpectPrintedJSON(t, \"\\\"\\\\uD800\\\"\", \"\\\"\\\\uD800\\\"\")\n\texpectPrintedJSON(t, \"\\\"\\\\uDC00\\\"\", \"\\\"\\\\uDC00\\\"\")\n\n\t// Invalid escapes\n\texpectParseErrorJSON(t, \"\\\"\\\\\", \"<stdin>: ERROR: Unterminated string literal\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\0\\\"\", \"<stdin>: ERROR: Syntax error \\\"0\\\"\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\1\\\"\", \"<stdin>: ERROR: Syntax error \\\"1\\\"\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\'\\\"\", \"<stdin>: ERROR: Syntax error \\\"'\\\"\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\a\\\"\", \"<stdin>: ERROR: Syntax error \\\"a\\\"\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\v\\\"\", \"<stdin>: ERROR: Syntax error \\\"v\\\"\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\\\n\\\"\", \"<stdin>: ERROR: Syntax error \\\"\\\\x0A\\\"\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\x78\\\"\", \"<stdin>: ERROR: Syntax error \\\"x\\\"\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\u{1234}\\\"\", \"<stdin>: ERROR: Syntax error \\\"{\\\"\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\uG\\\"\", \"<stdin>: ERROR: Syntax error \\\"G\\\"\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\uDG\\\"\", \"<stdin>: ERROR: Syntax error \\\"G\\\"\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\uDEG\\\"\", \"<stdin>: ERROR: Syntax error \\\"G\\\"\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\uDEFG\\\"\", \"<stdin>: ERROR: Syntax error \\\"G\\\"\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\u\\\"\", \"<stdin>: ERROR: Syntax error '\\\"'\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\uD\\\"\", \"<stdin>: ERROR: Syntax error '\\\"'\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\uDE\\\"\", \"<stdin>: ERROR: Syntax error '\\\"'\\n\")\n\texpectParseErrorJSON(t, \"\\\"\\\\uDEF\\\"\", \"<stdin>: ERROR: Syntax error '\\\"'\\n\")\n}\n\nfunc TestJSONNumber(t *testing.T) {\n\texpectPrintedJSON(t, \"0\", \"0\")\n\texpectPrintedJSON(t, \"-0\", \"-0\")\n\texpectPrintedJSON(t, \"123\", \"123\")\n\texpectPrintedJSON(t, \"123.456\", \"123.456\")\n\texpectPrintedJSON(t, \"123e20\", \"123e20\")\n\texpectPrintedJSON(t, \"123e-20\", \"123e-20\")\n\texpectParseErrorJSON(t, \"123.\", \"<stdin>: ERROR: Unexpected \\\"123.\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"-123.\", \"<stdin>: ERROR: Unexpected \\\"123.\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \".123\", \"<stdin>: ERROR: Unexpected \\\".123\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"-.123\", \"<stdin>: ERROR: Unexpected \\\".123\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"NaN\", \"<stdin>: ERROR: Unexpected \\\"NaN\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"Infinity\", \"<stdin>: ERROR: Unexpected \\\"Infinity\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"-Infinity\", \"<stdin>: ERROR: Unexpected \\\"-\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"+1\", \"<stdin>: ERROR: Unexpected \\\"+\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"- 1\", \"<stdin>: ERROR: Unexpected \\\"-\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"01\", \"<stdin>: ERROR: Unexpected \\\"01\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"0b1\", \"<stdin>: ERROR: Unexpected \\\"0b1\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"0o1\", \"<stdin>: ERROR: Unexpected \\\"0o1\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"0x1\", \"<stdin>: ERROR: Unexpected \\\"0x1\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"0n\", \"<stdin>: ERROR: Unexpected \\\"0n\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"-01\", \"<stdin>: ERROR: Unexpected \\\"01\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"-0b1\", \"<stdin>: ERROR: Unexpected \\\"0b1\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"-0o1\", \"<stdin>: ERROR: Unexpected \\\"0o1\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"-0x1\", \"<stdin>: ERROR: Unexpected \\\"0x1\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"-0n\", \"<stdin>: ERROR: Expected number in JSON but found \\\"0n\\\"\\n\")\n\texpectParseErrorJSON(t, \"1_2\", \"<stdin>: ERROR: Unexpected \\\"1_2\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"1.e2\", \"<stdin>: ERROR: Unexpected \\\"1.e2\\\" in JSON\\n\")\n}\n\nfunc TestJSONObject(t *testing.T) {\n\texpectPrintedJSON(t, \"{\\\"x\\\":0}\", \"({x:0})\")\n\texpectPrintedJSON(t, \"{\\\"x\\\":0,\\\"y\\\":1}\", \"({x:0,y:1})\")\n\texpectPrintedJSONWithWarning(t,\n\t\t\"{\\\"x\\\":0,\\\"x\\\":1}\",\n\t\t\"<stdin>: WARNING: Duplicate key \\\"x\\\" in object literal\\n<stdin>: NOTE: The original key \\\"x\\\" is here:\\n\",\n\t\t\"({x:0,x:1})\")\n\texpectParseErrorJSON(t, \"{\\\"x\\\":0,}\", \"<stdin>: ERROR: JSON does not support trailing commas\\n\")\n\texpectParseErrorJSON(t, \"{x:0}\", \"<stdin>: ERROR: Expected string in JSON but found \\\"x\\\"\\n\")\n\texpectParseErrorJSON(t, \"{1:0}\", \"<stdin>: ERROR: Expected string in JSON but found \\\"1\\\"\\n\")\n\texpectParseErrorJSON(t, \"{[\\\"x\\\"]:0}\", \"<stdin>: ERROR: Expected string in JSON but found \\\"[\\\"\\n\")\n}\n\nfunc TestJSONArray(t *testing.T) {\n\texpectPrintedJSON(t, \"[]\", \"[]\")\n\texpectPrintedJSON(t, \"[1]\", \"[1]\")\n\texpectPrintedJSON(t, \"[1,2]\", \"[1,2]\")\n\texpectParseErrorJSON(t, \"[,]\", \"<stdin>: ERROR: Unexpected \\\",\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"[,1]\", \"<stdin>: ERROR: Unexpected \\\",\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"[1,]\", \"<stdin>: ERROR: JSON does not support trailing commas\\n\")\n\texpectParseErrorJSON(t, \"[1,,2]\", \"<stdin>: ERROR: Unexpected \\\",\\\" in JSON\\n\")\n}\n\nfunc TestJSONInvalid(t *testing.T) {\n\texpectParseErrorJSON(t, \"({\\\"x\\\":0})\", \"<stdin>: ERROR: Unexpected \\\"(\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"{\\\"x\\\":(0)}\", \"<stdin>: ERROR: Unexpected \\\"(\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"#!/usr/bin/env node\\n{}\", \"<stdin>: ERROR: Unexpected \\\"#!/usr/bin/env node\\\" in JSON\\n\")\n\texpectParseErrorJSON(t, \"{\\\"x\\\":0}{\\\"y\\\":1}\", \"<stdin>: ERROR: Expected end of file in JSON but found \\\"{\\\"\\n\")\n}\n\nfunc TestJSONComments(t *testing.T) {\n\texpectParseErrorJSON(t, \"/*comment*/{}\", \"<stdin>: ERROR: JSON does not support comments\\n\")\n\texpectParseErrorJSON(t, \"//comment\\n{}\", \"<stdin>: ERROR: JSON does not support comments\\n\")\n\texpectParseErrorJSON(t, \"{/*comment*/}\", \"<stdin>: ERROR: JSON does not support comments\\n\")\n\texpectParseErrorJSON(t, \"{//comment\\n}\", \"<stdin>: ERROR: JSON does not support comments\\n\")\n\texpectParseErrorJSON(t, \"{}/*comment*/\", \"<stdin>: ERROR: JSON does not support comments\\n\")\n\texpectParseErrorJSON(t, \"{}//comment\\n\", \"<stdin>: ERROR: JSON does not support comments\\n\")\n}\n"
  },
  {
    "path": "internal/js_parser/sourcemap_parser.go",
    "content": "package js_parser\n\nimport (\n\t\"fmt\"\n\t\"net/url\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/sourcemap\"\n)\n\n// New specification: https://tc39.es/ecma426/\n// Old specification: https://sourcemaps.info/spec.html\nfunc ParseSourceMap(log logger.Log, source logger.Source) *sourcemap.SourceMap {\n\texpr, ok := ParseJSON(log, source, JSONOptions{ErrorSuffix: \" in source map\"})\n\tif !ok {\n\t\treturn nil\n\t}\n\n\tobj, ok := expr.Data.(*js_ast.EObject)\n\ttracker := logger.MakeLineColumnTracker(&source)\n\tif !ok {\n\t\tlog.AddError(&tracker, logger.Range{Loc: expr.Loc}, \"Invalid source map\")\n\t\treturn nil\n\t}\n\n\ttype sourceMapSection struct {\n\t\tlineOffset   int32\n\t\tcolumnOffset int32\n\t\tsourceMap    *js_ast.EObject\n\t}\n\n\tvar sections []sourceMapSection\n\thasSections := false\n\n\tfor _, prop := range obj.Properties {\n\t\tif !helpers.UTF16EqualsString(prop.Key.Data.(*js_ast.EString).Value, \"sections\") {\n\t\t\tcontinue\n\t\t}\n\n\t\tif value, ok := prop.ValueOrNil.Data.(*js_ast.EArray); ok {\n\t\t\tfor _, item := range value.Items {\n\t\t\t\tif element, ok := item.Data.(*js_ast.EObject); ok {\n\t\t\t\t\tvar sectionLineOffset int32\n\t\t\t\t\tvar sectionColumnOffset int32\n\t\t\t\t\tvar sectionSourceMap *js_ast.EObject\n\n\t\t\t\t\tfor _, sectionProp := range element.Properties {\n\t\t\t\t\t\tswitch helpers.UTF16ToString(sectionProp.Key.Data.(*js_ast.EString).Value) {\n\t\t\t\t\t\tcase \"offset\":\n\t\t\t\t\t\t\tif offsetValue, ok := sectionProp.ValueOrNil.Data.(*js_ast.EObject); ok {\n\t\t\t\t\t\t\t\tfor _, offsetProp := range offsetValue.Properties {\n\t\t\t\t\t\t\t\t\tswitch helpers.UTF16ToString(offsetProp.Key.Data.(*js_ast.EString).Value) {\n\t\t\t\t\t\t\t\t\tcase \"line\":\n\t\t\t\t\t\t\t\t\t\tif lineValue, ok := offsetProp.ValueOrNil.Data.(*js_ast.ENumber); ok {\n\t\t\t\t\t\t\t\t\t\t\tsectionLineOffset = int32(lineValue.Value)\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tcase \"column\":\n\t\t\t\t\t\t\t\t\t\tif columnValue, ok := offsetProp.ValueOrNil.Data.(*js_ast.ENumber); ok {\n\t\t\t\t\t\t\t\t\t\t\tsectionColumnOffset = int32(columnValue.Value)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tlog.AddError(&tracker, logger.Range{Loc: sectionProp.ValueOrNil.Loc}, \"Expected \\\"offset\\\" to be an object\")\n\t\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcase \"map\":\n\t\t\t\t\t\t\tif mapValue, ok := sectionProp.ValueOrNil.Data.(*js_ast.EObject); ok {\n\t\t\t\t\t\t\t\tsectionSourceMap = mapValue\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tlog.AddError(&tracker, logger.Range{Loc: sectionProp.ValueOrNil.Loc}, \"Expected \\\"map\\\" to be an object\")\n\t\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif sectionSourceMap != nil {\n\t\t\t\t\t\tsections = append(sections, sourceMapSection{\n\t\t\t\t\t\t\tlineOffset:   sectionLineOffset,\n\t\t\t\t\t\t\tcolumnOffset: sectionColumnOffset,\n\t\t\t\t\t\t\tsourceMap:    sectionSourceMap,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tlog.AddError(&tracker, logger.Range{Loc: prop.ValueOrNil.Loc}, \"Expected \\\"sections\\\" to be an array\")\n\t\t\treturn nil\n\t\t}\n\n\t\thasSections = true\n\t\tbreak\n\t}\n\n\tif !hasSections {\n\t\tsections = append(sections, sourceMapSection{\n\t\t\tsourceMap: obj,\n\t\t})\n\t}\n\n\tvar sources []string\n\tvar sourcesContent []sourcemap.SourceContent\n\tvar names []string\n\tvar mappings mappingArray\n\tvar generatedLine int32\n\tvar generatedColumn int32\n\tneedSort := false\n\n\tfor _, section := range sections {\n\t\tvar sourcesArray []js_ast.Expr\n\t\tvar sourcesContentArray []js_ast.Expr\n\t\tvar namesArray []js_ast.Expr\n\t\tvar mappingsRaw []uint16\n\t\tvar mappingsStart int32\n\t\tvar sourceRoot string\n\t\thasVersion := false\n\n\t\tfor _, prop := range section.sourceMap.Properties {\n\t\t\tswitch helpers.UTF16ToString(prop.Key.Data.(*js_ast.EString).Value) {\n\t\t\tcase \"version\":\n\t\t\t\tif value, ok := prop.ValueOrNil.Data.(*js_ast.ENumber); ok && value.Value == 3 {\n\t\t\t\t\thasVersion = true\n\t\t\t\t}\n\n\t\t\tcase \"mappings\":\n\t\t\t\tif value, ok := prop.ValueOrNil.Data.(*js_ast.EString); ok {\n\t\t\t\t\tmappingsRaw = value.Value\n\t\t\t\t\tmappingsStart = prop.ValueOrNil.Loc.Start + 1\n\t\t\t\t}\n\n\t\t\tcase \"sourceRoot\":\n\t\t\t\tif value, ok := prop.ValueOrNil.Data.(*js_ast.EString); ok {\n\t\t\t\t\tsourceRoot = helpers.UTF16ToString(value.Value)\n\t\t\t\t}\n\n\t\t\tcase \"sources\":\n\t\t\t\tif value, ok := prop.ValueOrNil.Data.(*js_ast.EArray); ok {\n\t\t\t\t\tsourcesArray = value.Items\n\t\t\t\t}\n\n\t\t\tcase \"sourcesContent\":\n\t\t\t\tif value, ok := prop.ValueOrNil.Data.(*js_ast.EArray); ok {\n\t\t\t\t\tsourcesContentArray = value.Items\n\t\t\t\t}\n\n\t\t\tcase \"names\":\n\t\t\t\tif value, ok := prop.ValueOrNil.Data.(*js_ast.EArray); ok {\n\t\t\t\t\tnamesArray = value.Items\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Silently ignore the section if the version was missing or incorrect\n\t\tif !hasVersion {\n\t\t\tcontinue\n\t\t}\n\n\t\tmappingsLen := len(mappingsRaw)\n\t\tsourcesLen := len(sourcesArray)\n\t\tnamesLen := len(namesArray)\n\n\t\t// Silently ignore the section if the source map is pointless (i.e. empty)\n\t\tif mappingsLen == 0 || sourcesLen == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tif section.lineOffset < generatedLine || (section.lineOffset == generatedLine && section.columnOffset < generatedColumn) {\n\t\t\tneedSort = true\n\t\t}\n\n\t\tlineOffset := section.lineOffset\n\t\tcolumnOffset := section.columnOffset\n\t\tsourceOffset := int32(len(sources))\n\t\tnameOffset := int32(len(names))\n\n\t\tgeneratedLine = lineOffset\n\t\tgeneratedColumn = columnOffset\n\t\tsourceIndex := sourceOffset\n\t\tvar originalLine int32\n\t\tvar originalColumn int32\n\t\toriginalName := nameOffset\n\n\t\tcurrent := 0\n\t\terrorText := \"\"\n\t\terrorLen := 0\n\n\t\t// Parse the mappings\n\t\tfor current < mappingsLen {\n\t\t\t// Handle a line break\n\t\t\tif mappingsRaw[current] == ';' {\n\t\t\t\tgeneratedLine++\n\t\t\t\tgeneratedColumn = 0\n\t\t\t\tcurrent++\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Read the generated column\n\t\t\tgeneratedColumnDelta, i, ok := sourcemap.DecodeVLQUTF16(mappingsRaw[current:])\n\t\t\tif !ok {\n\t\t\t\terrorText = \"Missing generated column\"\n\t\t\t\terrorLen = i\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif generatedColumnDelta < 0 {\n\t\t\t\t// This would mess up binary search\n\t\t\t\tneedSort = true\n\t\t\t}\n\t\t\tgeneratedColumn += generatedColumnDelta\n\t\t\tif (generatedLine == lineOffset && generatedColumn < columnOffset) || generatedColumn < 0 {\n\t\t\t\terrorText = fmt.Sprintf(\"Invalid generated column value: %d\", generatedColumn)\n\t\t\t\terrorLen = i\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcurrent += i\n\n\t\t\t// According to the specification, it's valid for a mapping to have 1,\n\t\t\t// 4, or 5 variable-length fields. Having one field means there's no\n\t\t\t// original location information, which is pretty useless. Just ignore\n\t\t\t// those entries.\n\t\t\tif current == mappingsLen {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tswitch mappingsRaw[current] {\n\t\t\tcase ',':\n\t\t\t\tcurrent++\n\t\t\t\tcontinue\n\t\t\tcase ';':\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Read the original source\n\t\t\tsourceIndexDelta, i, ok := sourcemap.DecodeVLQUTF16(mappingsRaw[current:])\n\t\t\tif !ok {\n\t\t\t\terrorText = \"Missing source index\"\n\t\t\t\terrorLen = i\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tsourceIndex += sourceIndexDelta\n\t\t\tif sourceIndex < sourceOffset || sourceIndex >= sourceOffset+int32(sourcesLen) {\n\t\t\t\terrorText = fmt.Sprintf(\"Invalid source index value: %d\", sourceIndex)\n\t\t\t\terrorLen = i\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcurrent += i\n\n\t\t\t// Read the original line\n\t\t\toriginalLineDelta, i, ok := sourcemap.DecodeVLQUTF16(mappingsRaw[current:])\n\t\t\tif !ok {\n\t\t\t\terrorText = \"Missing original line\"\n\t\t\t\terrorLen = i\n\t\t\t\tbreak\n\t\t\t}\n\t\t\toriginalLine += originalLineDelta\n\t\t\tif originalLine < 0 {\n\t\t\t\terrorText = fmt.Sprintf(\"Invalid original line value: %d\", originalLine)\n\t\t\t\terrorLen = i\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcurrent += i\n\n\t\t\t// Read the original column\n\t\t\toriginalColumnDelta, i, ok := sourcemap.DecodeVLQUTF16(mappingsRaw[current:])\n\t\t\tif !ok {\n\t\t\t\terrorText = \"Missing original column\"\n\t\t\t\terrorLen = i\n\t\t\t\tbreak\n\t\t\t}\n\t\t\toriginalColumn += originalColumnDelta\n\t\t\tif originalColumn < 0 {\n\t\t\t\terrorText = fmt.Sprintf(\"Invalid original column value: %d\", originalColumn)\n\t\t\t\terrorLen = i\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcurrent += i\n\n\t\t\t// Read the original name\n\t\t\tvar optionalName ast.Index32\n\t\t\tif originalNameDelta, i, ok := sourcemap.DecodeVLQUTF16(mappingsRaw[current:]); ok {\n\t\t\t\toriginalName += originalNameDelta\n\t\t\t\tif originalName < nameOffset || originalName >= nameOffset+int32(namesLen) {\n\t\t\t\t\terrorText = fmt.Sprintf(\"Invalid name index value: %d\", originalName)\n\t\t\t\t\terrorLen = i\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\toptionalName = ast.MakeIndex32(uint32(originalName))\n\t\t\t\tcurrent += i\n\t\t\t}\n\n\t\t\t// Handle the next character\n\t\t\tif current < mappingsLen {\n\t\t\t\tif c := mappingsRaw[current]; c == ',' {\n\t\t\t\t\tcurrent++\n\t\t\t\t} else if c != ';' {\n\t\t\t\t\terrorText = fmt.Sprintf(\"Invalid character after mapping: %q\",\n\t\t\t\t\t\thelpers.UTF16ToString(mappingsRaw[current:current+1]))\n\t\t\t\t\terrorLen = 1\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmappings = append(mappings, sourcemap.Mapping{\n\t\t\t\tGeneratedLine:   generatedLine,\n\t\t\t\tGeneratedColumn: generatedColumn,\n\t\t\t\tSourceIndex:     sourceIndex,\n\t\t\t\tOriginalLine:    originalLine,\n\t\t\t\tOriginalColumn:  originalColumn,\n\t\t\t\tOriginalName:    optionalName,\n\t\t\t})\n\t\t}\n\n\t\tif errorText != \"\" {\n\t\t\tr := logger.Range{Loc: logger.Loc{Start: mappingsStart + int32(current)}, Len: int32(errorLen)}\n\t\t\tlog.AddID(logger.MsgID_SourceMap_InvalidSourceMappings, logger.Warning, &tracker, r,\n\t\t\t\tfmt.Sprintf(\"Bad \\\"mappings\\\" data in source map at character %d: %s\", current, errorText))\n\t\t\treturn nil\n\t\t}\n\n\t\t// Try resolving relative source URLs into absolute source URLs.\n\t\t// See https://tc39.es/ecma426/#resolving-sources for details.\n\t\tvar sourceURLPrefix string\n\t\tvar baseURL *url.URL\n\t\tif sourceRoot != \"\" {\n\t\t\tif index := strings.LastIndexByte(sourceRoot, '/'); index != -1 {\n\t\t\t\tsourceURLPrefix = sourceRoot[:index+1]\n\t\t\t} else {\n\t\t\t\tsourceURLPrefix = sourceRoot + \"/\"\n\t\t\t}\n\t\t}\n\t\tif source.KeyPath.Namespace == \"file\" {\n\t\t\tbaseURL = helpers.FileURLFromFilePath(source.KeyPath.Text)\n\t\t}\n\n\t\tfor _, item := range sourcesArray {\n\t\t\tif element, ok := item.Data.(*js_ast.EString); ok {\n\t\t\t\tsourcePath := sourceURLPrefix + helpers.UTF16ToString(element.Value)\n\t\t\t\tsourceURL, err := url.Parse(sourcePath)\n\n\t\t\t\t// Ignore URL parse errors (such as \"%XY\" being an invalid escape)\n\t\t\t\tif err != nil {\n\t\t\t\t\tsources = append(sources, sourcePath)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Resolve this URL relative to the enclosing directory\n\t\t\t\tif baseURL != nil {\n\t\t\t\t\tsourceURL = baseURL.ResolveReference(sourceURL)\n\t\t\t\t}\n\t\t\t\tsources = append(sources, sourceURL.String())\n\t\t\t} else {\n\t\t\t\tsources = append(sources, \"\")\n\t\t\t}\n\t\t}\n\n\t\tif len(sourcesContentArray) > 0 {\n\t\t\t// It's possible that one of the source maps inside \"sections\" has\n\t\t\t// different lengths for the \"sources\" and \"sourcesContent\" arrays.\n\t\t\t// This is bad because we need to us a single index to get the name\n\t\t\t// of the source from \"sources[i]\" and the content of the source\n\t\t\t// from \"sourcesContent[i]\".\n\t\t\t//\n\t\t\t// So if a previous source map had a shorter \"sourcesContent\" array\n\t\t\t// than its \"sources\" array (or if the previous source map just had\n\t\t\t// no \"sourcesContent\" array), expand our aggregated array to the\n\t\t\t// right length by padding it out with empty entries.\n\t\t\tsourcesContent = append(sourcesContent, make([]sourcemap.SourceContent, int(sourceOffset)-len(sourcesContent))...)\n\n\t\t\tfor i, item := range sourcesContentArray {\n\t\t\t\t// Make sure we don't ever record more \"sourcesContent\" entries\n\t\t\t\t// than there are \"sources\" entries, which is possible because\n\t\t\t\t// these are two separate arrays in the source map JSON. We need\n\t\t\t\t// to avoid this because that would mess up our shared indexing\n\t\t\t\t// of the \"sources\" and \"sourcesContent\" arrays. See the above\n\t\t\t\t// comment for more details.\n\t\t\t\tif i == sourcesLen {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tif element, ok := item.Data.(*js_ast.EString); ok {\n\t\t\t\t\tsourcesContent = append(sourcesContent, sourcemap.SourceContent{\n\t\t\t\t\t\tValue:  element.Value,\n\t\t\t\t\t\tQuoted: source.TextForRange(source.RangeOfString(item.Loc)),\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tsourcesContent = append(sourcesContent, sourcemap.SourceContent{})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor _, item := range namesArray {\n\t\t\tif element, ok := item.Data.(*js_ast.EString); ok {\n\t\t\t\tnames = append(names, helpers.UTF16ToString(element.Value))\n\t\t\t} else {\n\t\t\t\tnames = append(names, \"\")\n\t\t\t}\n\t\t}\n\t}\n\n\t// Silently fail if the source map is pointless (i.e. empty)\n\tif len(sources) == 0 || len(mappings) == 0 {\n\t\treturn nil\n\t}\n\n\tif needSort {\n\t\t// If we get here, some mappings are out of order. Lines can't be out of\n\t\t// order by construction but columns can. This is a pretty rare situation\n\t\t// because almost all source map generators always write out mappings in\n\t\t// order as they write the output instead of scrambling the order.\n\t\tsort.Stable(mappings)\n\t}\n\n\treturn &sourcemap.SourceMap{\n\t\tSources:        sources,\n\t\tSourcesContent: sourcesContent,\n\t\tMappings:       mappings,\n\t\tNames:          names,\n\t}\n}\n\n// This type is just so we can use Go's native sort function\ntype mappingArray []sourcemap.Mapping\n\nfunc (a mappingArray) Len() int          { return len(a) }\nfunc (a mappingArray) Swap(i int, j int) { a[i], a[j] = a[j], a[i] }\n\nfunc (a mappingArray) Less(i int, j int) bool {\n\tai := a[i]\n\taj := a[j]\n\treturn ai.GeneratedLine < aj.GeneratedLine || (ai.GeneratedLine == aj.GeneratedLine && ai.GeneratedColumn <= aj.GeneratedColumn)\n}\n"
  },
  {
    "path": "internal/js_parser/ts_parser.go",
    "content": "// This file contains code for parsing TypeScript syntax. The parser just skips\n// over type expressions as if they are whitespace and doesn't bother generating\n// an AST because nothing uses type information.\n\npackage js_parser\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/js_lexer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\nfunc (p *parser) skipTypeScriptBinding() {\n\tswitch p.lexer.Token {\n\tcase js_lexer.TIdentifier, js_lexer.TThis:\n\t\tp.lexer.Next()\n\n\tcase js_lexer.TOpenBracket:\n\t\tp.lexer.Next()\n\n\t\t// \"[, , a]\"\n\t\tfor p.lexer.Token == js_lexer.TComma {\n\t\t\tp.lexer.Next()\n\t\t}\n\n\t\t// \"[a, b]\"\n\t\tfor p.lexer.Token != js_lexer.TCloseBracket {\n\t\t\t// \"[...a]\"\n\t\t\tif p.lexer.Token == js_lexer.TDotDotDot {\n\t\t\t\tp.lexer.Next()\n\t\t\t}\n\n\t\t\tp.skipTypeScriptBinding()\n\t\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t}\n\n\t\tp.lexer.Expect(js_lexer.TCloseBracket)\n\n\tcase js_lexer.TOpenBrace:\n\t\tp.lexer.Next()\n\n\t\tfor p.lexer.Token != js_lexer.TCloseBrace {\n\t\t\tfoundIdentifier := false\n\n\t\t\tswitch p.lexer.Token {\n\t\t\tcase js_lexer.TDotDotDot:\n\t\t\t\tp.lexer.Next()\n\n\t\t\t\tif p.lexer.Token != js_lexer.TIdentifier {\n\t\t\t\t\tp.lexer.Unexpected()\n\t\t\t\t}\n\n\t\t\t\t// \"{...x}\"\n\t\t\t\tfoundIdentifier = true\n\t\t\t\tp.lexer.Next()\n\n\t\t\tcase js_lexer.TIdentifier:\n\t\t\t\t// \"{x}\"\n\t\t\t\t// \"{x: y}\"\n\t\t\t\tfoundIdentifier = true\n\t\t\t\tp.lexer.Next()\n\n\t\t\t\t// \"{1: y}\"\n\t\t\t\t// \"{'x': y}\"\n\t\t\tcase js_lexer.TStringLiteral, js_lexer.TNumericLiteral:\n\t\t\t\tp.lexer.Next()\n\n\t\t\tdefault:\n\t\t\t\tif p.lexer.IsIdentifierOrKeyword() {\n\t\t\t\t\t// \"{if: x}\"\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t} else {\n\t\t\t\t\tp.lexer.Unexpected()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif p.lexer.Token == js_lexer.TColon || !foundIdentifier {\n\t\t\t\tp.lexer.Expect(js_lexer.TColon)\n\t\t\t\tp.skipTypeScriptBinding()\n\t\t\t}\n\n\t\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t}\n\n\t\tp.lexer.Expect(js_lexer.TCloseBrace)\n\n\tdefault:\n\t\tp.lexer.Unexpected()\n\t}\n}\n\nfunc (p *parser) skipTypeScriptFnArgs() {\n\tp.lexer.Expect(js_lexer.TOpenParen)\n\n\tfor p.lexer.Token != js_lexer.TCloseParen {\n\t\t// \"(...a)\"\n\t\tif p.lexer.Token == js_lexer.TDotDotDot {\n\t\t\tp.lexer.Next()\n\t\t}\n\n\t\tp.skipTypeScriptBinding()\n\n\t\t// \"(a?)\"\n\t\tif p.lexer.Token == js_lexer.TQuestion {\n\t\t\tp.lexer.Next()\n\t\t}\n\n\t\t// \"(a: any)\"\n\t\tif p.lexer.Token == js_lexer.TColon {\n\t\t\tp.lexer.Next()\n\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t}\n\n\t\t// \"(a, b)\"\n\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\tbreak\n\t\t}\n\t\tp.lexer.Next()\n\t}\n\n\tp.lexer.Expect(js_lexer.TCloseParen)\n}\n\n// This is a spot where the TypeScript grammar is highly ambiguous. Here are\n// some cases that are valid:\n//\n//\tlet x = (y: any): (() => {}) => { };\n//\tlet x = (y: any): () => {} => { };\n//\tlet x = (y: any): (y) => {} => { };\n//\tlet x = (y: any): (y[]) => {};\n//\tlet x = (y: any): (a | b) => {};\n//\n// Here are some cases that aren't valid:\n//\n//\tlet x = (y: any): (y) => {};\n//\tlet x = (y: any): (y) => {return 0};\n//\tlet x = (y: any): asserts y is (y) => {};\nfunc (p *parser) skipTypeScriptParenOrFnType() {\n\tif p.trySkipTypeScriptArrowArgsWithBacktracking() {\n\t\tp.skipTypeScriptReturnType()\n\t} else {\n\t\tp.lexer.Expect(js_lexer.TOpenParen)\n\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\tp.lexer.Expect(js_lexer.TCloseParen)\n\t}\n}\n\nfunc (p *parser) skipTypeScriptReturnType() {\n\tp.skipTypeScriptTypeWithFlags(js_ast.LLowest, isReturnTypeFlag)\n}\n\nfunc (p *parser) skipTypeScriptType(level js_ast.L) {\n\tp.skipTypeScriptTypeWithFlags(level, 0)\n}\n\ntype skipTypeFlags uint8\n\nconst (\n\tisReturnTypeFlag skipTypeFlags = 1 << iota\n\tisIndexSignatureFlag\n\tallowTupleLabelsFlag\n\tdisallowConditionalTypesFlag\n)\n\nfunc (flags skipTypeFlags) has(flag skipTypeFlags) bool {\n\treturn (flags & flag) != 0\n}\n\ntype tsTypeIdentifierKind uint8\n\nconst (\n\ttsTypeIdentifierNormal tsTypeIdentifierKind = iota\n\ttsTypeIdentifierUnique\n\ttsTypeIdentifierAbstract\n\ttsTypeIdentifierAsserts\n\ttsTypeIdentifierPrefix\n\ttsTypeIdentifierPrimitive\n\ttsTypeIdentifierInfer\n)\n\n// Use a map to improve lookup speed\nvar tsTypeIdentifierMap = map[string]tsTypeIdentifierKind{\n\t\"unique\":   tsTypeIdentifierUnique,\n\t\"abstract\": tsTypeIdentifierAbstract,\n\t\"asserts\":  tsTypeIdentifierAsserts,\n\n\t\"keyof\":    tsTypeIdentifierPrefix,\n\t\"readonly\": tsTypeIdentifierPrefix,\n\n\t\"any\":       tsTypeIdentifierPrimitive,\n\t\"never\":     tsTypeIdentifierPrimitive,\n\t\"unknown\":   tsTypeIdentifierPrimitive,\n\t\"undefined\": tsTypeIdentifierPrimitive,\n\t\"object\":    tsTypeIdentifierPrimitive,\n\t\"number\":    tsTypeIdentifierPrimitive,\n\t\"string\":    tsTypeIdentifierPrimitive,\n\t\"boolean\":   tsTypeIdentifierPrimitive,\n\t\"bigint\":    tsTypeIdentifierPrimitive,\n\t\"symbol\":    tsTypeIdentifierPrimitive,\n\n\t\"infer\": tsTypeIdentifierInfer,\n}\n\nfunc (p *parser) skipTypeScriptTypeWithFlags(level js_ast.L, flags skipTypeFlags) {\nloop:\n\tfor {\n\t\tswitch p.lexer.Token {\n\t\tcase js_lexer.TNumericLiteral, js_lexer.TBigIntegerLiteral, js_lexer.TStringLiteral,\n\t\t\tjs_lexer.TNoSubstitutionTemplateLiteral, js_lexer.TTrue, js_lexer.TFalse,\n\t\t\tjs_lexer.TNull, js_lexer.TVoid:\n\t\t\tp.lexer.Next()\n\n\t\tcase js_lexer.TConst:\n\t\t\tr := p.lexer.Range()\n\t\t\tp.lexer.Next()\n\n\t\t\t// \"[const: number]\"\n\t\t\tif flags.has(allowTupleLabelsFlag) && p.lexer.Token == js_lexer.TColon {\n\t\t\t\tp.log.AddError(&p.tracker, r, \"Unexpected \\\"const\\\"\")\n\t\t\t}\n\n\t\tcase js_lexer.TThis:\n\t\t\tp.lexer.Next()\n\n\t\t\t// \"function check(): this is boolean\"\n\t\t\tif p.lexer.IsContextualKeyword(\"is\") && !p.lexer.HasNewlineBefore {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\t\treturn\n\t\t\t}\n\n\t\tcase js_lexer.TMinus:\n\t\t\t// \"-123\"\n\t\t\t// \"-123n\"\n\t\t\tp.lexer.Next()\n\t\t\tif p.lexer.Token == js_lexer.TBigIntegerLiteral {\n\t\t\t\tp.lexer.Next()\n\t\t\t} else {\n\t\t\t\tp.lexer.Expect(js_lexer.TNumericLiteral)\n\t\t\t}\n\n\t\tcase js_lexer.TAmpersand:\n\t\tcase js_lexer.TBar:\n\t\t\t// Support things like \"type Foo = | A | B\" and \"type Foo = & A & B\"\n\t\t\tp.lexer.Next()\n\t\t\tcontinue\n\n\t\tcase js_lexer.TImport:\n\t\t\t// \"import('fs')\"\n\t\t\tp.lexer.Next()\n\n\t\t\t// \"[import: number]\"\n\t\t\t// \"[import?: number]\"\n\t\t\tif flags.has(allowTupleLabelsFlag) && (p.lexer.Token == js_lexer.TColon || p.lexer.Token == js_lexer.TQuestion) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tp.lexer.Expect(js_lexer.TOpenParen)\n\t\t\tp.lexer.Expect(js_lexer.TStringLiteral)\n\n\t\t\t// \"import('./foo.json', { assert: { type: 'json' } })\"\n\t\t\tif p.lexer.Token == js_lexer.TComma {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.skipTypeScriptObjectType()\n\n\t\t\t\t// \"import('./foo.json', { assert: { type: 'json' } }, )\"\n\t\t\t\tif p.lexer.Token == js_lexer.TComma {\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.lexer.Expect(js_lexer.TCloseParen)\n\n\t\tcase js_lexer.TNew:\n\t\t\t// \"new () => Foo\"\n\t\t\t// \"new <T>() => Foo<T>\"\n\t\t\tp.lexer.Next()\n\n\t\t\t// \"[new: number]\"\n\t\t\t// \"[new?: number]\"\n\t\t\tif flags.has(allowTupleLabelsFlag) && (p.lexer.Token == js_lexer.TColon || p.lexer.Token == js_lexer.TQuestion) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tp.skipTypeScriptTypeParameters(allowConstModifier)\n\t\t\tp.skipTypeScriptParenOrFnType()\n\n\t\tcase js_lexer.TLessThan:\n\t\t\t// \"<T>() => Foo<T>\"\n\t\t\tp.skipTypeScriptTypeParameters(allowConstModifier)\n\t\t\tp.skipTypeScriptParenOrFnType()\n\n\t\tcase js_lexer.TOpenParen:\n\t\t\t// \"(number | string)\"\n\t\t\tp.skipTypeScriptParenOrFnType()\n\n\t\tcase js_lexer.TIdentifier:\n\t\t\tkind := tsTypeIdentifierMap[p.lexer.Identifier.String]\n\t\t\tcheckTypeParameters := true\n\n\t\t\tswitch kind {\n\t\t\tcase tsTypeIdentifierPrefix:\n\t\t\t\tp.lexer.Next()\n\n\t\t\t\t// Valid:\n\t\t\t\t//   \"[keyof: string]\"\n\t\t\t\t//   \"[keyof?: string]\"\n\t\t\t\t//   \"{[keyof: string]: number}\"\n\t\t\t\t//   \"{[keyof in string]: number}\"\n\t\t\t\t//\n\t\t\t\t// Invalid:\n\t\t\t\t//   \"A extends B ? keyof : string\"\n\t\t\t\t//\n\t\t\t\tif (p.lexer.Token != js_lexer.TColon && p.lexer.Token != js_lexer.TQuestion && p.lexer.Token != js_lexer.TIn) ||\n\t\t\t\t\t(!flags.has(isIndexSignatureFlag) && !flags.has(allowTupleLabelsFlag)) {\n\t\t\t\t\tp.skipTypeScriptType(js_ast.LPrefix)\n\t\t\t\t}\n\t\t\t\tbreak loop\n\n\t\t\tcase tsTypeIdentifierInfer:\n\t\t\t\tp.lexer.Next()\n\n\t\t\t\t// \"type Foo = Bar extends [infer T] ? T : null\"\n\t\t\t\t// \"type Foo = Bar extends [infer T extends string] ? T : null\"\n\t\t\t\t// \"type Foo = Bar extends [infer T extends string ? infer T : never] ? T : null\"\n\t\t\t\t// \"type Foo = { [infer in Bar]: number }\"\n\t\t\t\t// \"type Foo = [infer: number]\"\n\t\t\t\t// \"type Foo = [infer?: number]\"\n\t\t\t\tif (p.lexer.Token != js_lexer.TColon && p.lexer.Token != js_lexer.TQuestion && p.lexer.Token != js_lexer.TIn) ||\n\t\t\t\t\t(!flags.has(isIndexSignatureFlag) && !flags.has(allowTupleLabelsFlag)) {\n\t\t\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t\t\t\tif p.lexer.Token == js_lexer.TExtends {\n\t\t\t\t\t\tp.trySkipTypeScriptConstraintOfInferTypeWithBacktracking(flags)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak loop\n\n\t\t\tcase tsTypeIdentifierUnique:\n\t\t\t\tp.lexer.Next()\n\n\t\t\t\t// \"let foo: unique symbol\"\n\t\t\t\tif p.lexer.IsContextualKeyword(\"symbol\") {\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tbreak loop\n\t\t\t\t}\n\n\t\t\tcase tsTypeIdentifierAbstract:\n\t\t\t\tp.lexer.Next()\n\n\t\t\t\t// \"let foo: abstract new () => {}\" added in TypeScript 4.2\n\t\t\t\tif p.lexer.Token == js_lexer.TNew {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\tcase tsTypeIdentifierAsserts:\n\t\t\t\tp.lexer.Next()\n\n\t\t\t\t// \"function assert(x: boolean): asserts x\"\n\t\t\t\t// \"function assert(x: boolean): asserts x is boolean\"\n\t\t\t\tif flags.has(isReturnTypeFlag) && !p.lexer.HasNewlineBefore && (p.lexer.Token == js_lexer.TIdentifier || p.lexer.Token == js_lexer.TThis) {\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t}\n\n\t\t\tcase tsTypeIdentifierPrimitive:\n\t\t\t\tp.lexer.Next()\n\t\t\t\tcheckTypeParameters = false\n\n\t\t\tdefault:\n\t\t\t\tp.lexer.Next()\n\t\t\t}\n\n\t\t\t// \"function assert(x: any): x is boolean\"\n\t\t\tif p.lexer.IsContextualKeyword(\"is\") && !p.lexer.HasNewlineBefore {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// \"let foo: any \\n <number>foo\" must not become a single type\n\t\t\tif checkTypeParameters && !p.lexer.HasNewlineBefore {\n\t\t\t\tp.skipTypeScriptTypeArguments(skipTypeScriptTypeArgumentsOpts{})\n\t\t\t}\n\n\t\tcase js_lexer.TTypeof:\n\t\t\tp.lexer.Next()\n\n\t\t\t// \"[typeof: number]\"\n\t\t\t// \"[typeof?: number]\"\n\t\t\tif flags.has(allowTupleLabelsFlag) && (p.lexer.Token == js_lexer.TColon || p.lexer.Token == js_lexer.TQuestion) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif p.lexer.Token == js_lexer.TImport {\n\t\t\t\t// \"typeof import('fs')\"\n\t\t\t\tcontinue\n\t\t\t} else {\n\t\t\t\t// \"typeof x\"\n\t\t\t\tif !p.lexer.IsIdentifierOrKeyword() {\n\t\t\t\t\tp.lexer.Expected(js_lexer.TIdentifier)\n\t\t\t\t}\n\t\t\t\tp.lexer.Next()\n\n\t\t\t\t// \"typeof x.y\"\n\t\t\t\t// \"typeof x.#y\"\n\t\t\t\tfor p.lexer.Token == js_lexer.TDot {\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tif !p.lexer.IsIdentifierOrKeyword() && p.lexer.Token != js_lexer.TPrivateIdentifier {\n\t\t\t\t\t\tp.lexer.Expected(js_lexer.TIdentifier)\n\t\t\t\t\t}\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t}\n\n\t\t\t\tif !p.lexer.HasNewlineBefore {\n\t\t\t\t\tp.skipTypeScriptTypeArguments(skipTypeScriptTypeArgumentsOpts{})\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase js_lexer.TOpenBracket:\n\t\t\t// \"[number, string]\"\n\t\t\t// \"[first: number, second: string]\"\n\t\t\tp.lexer.Next()\n\t\t\tfor p.lexer.Token != js_lexer.TCloseBracket {\n\t\t\t\tif p.lexer.Token == js_lexer.TDotDotDot {\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t}\n\t\t\t\tp.skipTypeScriptTypeWithFlags(js_ast.LLowest, allowTupleLabelsFlag)\n\t\t\t\tif p.lexer.Token == js_lexer.TQuestion {\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t}\n\t\t\t\tif p.lexer.Token == js_lexer.TColon {\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\t\t}\n\t\t\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tp.lexer.Next()\n\t\t\t}\n\t\t\tp.lexer.Expect(js_lexer.TCloseBracket)\n\n\t\tcase js_lexer.TOpenBrace:\n\t\t\tp.skipTypeScriptObjectType()\n\n\t\tcase js_lexer.TTemplateHead:\n\t\t\t// \"`${'a' | 'b'}-${'c' | 'd'}`\"\n\t\t\tfor {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\t\tp.lexer.RescanCloseBraceAsTemplateToken()\n\t\t\t\tif p.lexer.Token == js_lexer.TTemplateTail {\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\tdefault:\n\t\t\t// \"[function: number]\"\n\t\t\t// \"[function?: number]\"\n\t\t\tif flags.has(allowTupleLabelsFlag) && p.lexer.IsIdentifierOrKeyword() {\n\t\t\t\tif p.lexer.Token != js_lexer.TFunction {\n\t\t\t\t\tp.log.AddError(&p.tracker, p.lexer.Range(), fmt.Sprintf(\"Unexpected %q\", p.lexer.Raw()))\n\t\t\t\t}\n\t\t\t\tp.lexer.Next()\n\t\t\t\tif p.lexer.Token != js_lexer.TColon && p.lexer.Token != js_lexer.TQuestion {\n\t\t\t\t\tp.lexer.Expect(js_lexer.TColon)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t\tbreak\n\t}\n\n\tfor {\n\t\tswitch p.lexer.Token {\n\t\tcase js_lexer.TBar:\n\t\t\tif level >= js_ast.LBitwiseOr {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tp.skipTypeScriptTypeWithFlags(js_ast.LBitwiseOr, flags)\n\n\t\tcase js_lexer.TAmpersand:\n\t\t\tif level >= js_ast.LBitwiseAnd {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tp.skipTypeScriptTypeWithFlags(js_ast.LBitwiseAnd, flags)\n\n\t\tcase js_lexer.TExclamation:\n\t\t\t// A postfix \"!\" is allowed in JSDoc types in TypeScript, which are only\n\t\t\t// present in comments. While it's not valid in a non-comment position,\n\t\t\t// it's still parsed and turned into a soft error by the TypeScript\n\t\t\t// compiler. It turns out parsing this is important for correctness for\n\t\t\t// \"as\" casts because the \"!\" token must still be consumed.\n\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tp.lexer.Next()\n\n\t\tcase js_lexer.TDot:\n\t\t\tp.lexer.Next()\n\t\t\tif !p.lexer.IsIdentifierOrKeyword() {\n\t\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t\t}\n\t\t\tp.lexer.Next()\n\n\t\t\t// \"{ <A extends B>(): c.d \\n <E extends F>(): g.h }\" must not become a single type\n\t\t\tif !p.lexer.HasNewlineBefore {\n\t\t\t\tp.skipTypeScriptTypeArguments(skipTypeScriptTypeArgumentsOpts{})\n\t\t\t}\n\n\t\tcase js_lexer.TOpenBracket:\n\t\t\t// \"{ ['x']: string \\n ['y']: string }\" must not become a single type\n\t\t\tif p.lexer.HasNewlineBefore {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tif p.lexer.Token != js_lexer.TCloseBracket {\n\t\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\t}\n\t\t\tp.lexer.Expect(js_lexer.TCloseBracket)\n\n\t\tcase js_lexer.TExtends:\n\t\t\t// \"{ x: number \\n extends: boolean }\" must not become a single type\n\t\t\tif p.lexer.HasNewlineBefore || flags.has(disallowConditionalTypesFlag) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tp.lexer.Next()\n\n\t\t\t// The type following \"extends\" is not permitted to be another conditional type\n\t\t\tp.skipTypeScriptTypeWithFlags(js_ast.LLowest, disallowConditionalTypesFlag)\n\t\t\tp.lexer.Expect(js_lexer.TQuestion)\n\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\tp.lexer.Expect(js_lexer.TColon)\n\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\n\t\tdefault:\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (p *parser) skipTypeScriptObjectType() {\n\tp.lexer.Expect(js_lexer.TOpenBrace)\n\n\tfor p.lexer.Token != js_lexer.TCloseBrace {\n\t\t// \"{ -readonly [K in keyof T]: T[K] }\"\n\t\t// \"{ +readonly [K in keyof T]: T[K] }\"\n\t\tif p.lexer.Token == js_lexer.TPlus || p.lexer.Token == js_lexer.TMinus {\n\t\t\tp.lexer.Next()\n\t\t}\n\n\t\t// Skip over modifiers and the property identifier\n\t\tfoundKey := false\n\t\tfor p.lexer.IsIdentifierOrKeyword() ||\n\t\t\tp.lexer.Token == js_lexer.TStringLiteral ||\n\t\t\tp.lexer.Token == js_lexer.TNumericLiteral {\n\t\t\tp.lexer.Next()\n\t\t\tfoundKey = true\n\t\t}\n\n\t\tif p.lexer.Token == js_lexer.TOpenBracket {\n\t\t\t// Index signature or computed property\n\t\t\tp.lexer.Next()\n\t\t\tp.skipTypeScriptTypeWithFlags(js_ast.LLowest, isIndexSignatureFlag)\n\n\t\t\t// \"{ [key: string]: number }\"\n\t\t\t// \"{ readonly [K in keyof T]: T[K] }\"\n\t\t\tif p.lexer.Token == js_lexer.TColon {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\t} else if p.lexer.Token == js_lexer.TIn {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\t\tif p.lexer.IsContextualKeyword(\"as\") {\n\t\t\t\t\t// \"{ [K in keyof T as `get-${K}`]: T[K] }\"\n\t\t\t\t\tp.lexer.Next()\n\t\t\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.lexer.Expect(js_lexer.TCloseBracket)\n\n\t\t\t// \"{ [K in keyof T]+?: T[K] }\"\n\t\t\t// \"{ [K in keyof T]-?: T[K] }\"\n\t\t\tif p.lexer.Token == js_lexer.TPlus || p.lexer.Token == js_lexer.TMinus {\n\t\t\t\tp.lexer.Next()\n\t\t\t}\n\n\t\t\tfoundKey = true\n\t\t}\n\n\t\t// \"?\" indicates an optional property\n\t\t// \"!\" indicates an initialization assertion\n\t\tif foundKey && (p.lexer.Token == js_lexer.TQuestion || p.lexer.Token == js_lexer.TExclamation) {\n\t\t\tp.lexer.Next()\n\t\t}\n\n\t\t// Type parameters come right after the optional mark\n\t\tp.skipTypeScriptTypeParameters(allowConstModifier)\n\n\t\tswitch p.lexer.Token {\n\t\tcase js_lexer.TColon:\n\t\t\t// Regular property\n\t\t\tif !foundKey {\n\t\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\n\t\tcase js_lexer.TOpenParen:\n\t\t\t// Method signature\n\t\t\tp.skipTypeScriptFnArgs()\n\t\t\tif p.lexer.Token == js_lexer.TColon {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.skipTypeScriptReturnType()\n\t\t\t}\n\n\t\tdefault:\n\t\t\tif !foundKey {\n\t\t\t\tp.lexer.Unexpected()\n\t\t\t}\n\t\t}\n\n\t\tswitch p.lexer.Token {\n\t\tcase js_lexer.TCloseBrace:\n\n\t\tcase js_lexer.TComma, js_lexer.TSemicolon:\n\t\t\tp.lexer.Next()\n\n\t\tdefault:\n\t\t\tif !p.lexer.HasNewlineBefore {\n\t\t\t\tp.lexer.Unexpected()\n\t\t\t}\n\t\t}\n\t}\n\n\tp.lexer.Expect(js_lexer.TCloseBrace)\n}\n\ntype typeParameterFlags uint8\n\nconst (\n\t// TypeScript 4.7\n\tallowInOutVarianceAnnotations typeParameterFlags = 1 << iota\n\n\t// TypeScript 5.0\n\tallowConstModifier\n\n\t// Allow \"<>\" without any type parameters\n\tallowEmptyTypeParameters\n)\n\ntype skipTypeScriptTypeParametersResult uint8\n\nconst (\n\tdidNotSkipAnything skipTypeScriptTypeParametersResult = iota\n\tcouldBeTypeCast\n\tdefinitelyTypeParameters\n)\n\n// This is the type parameter declarations that go with other symbol\n// declarations (class, function, type, etc.)\nfunc (p *parser) skipTypeScriptTypeParameters(flags typeParameterFlags) skipTypeScriptTypeParametersResult {\n\tif p.lexer.Token != js_lexer.TLessThan {\n\t\treturn didNotSkipAnything\n\t}\n\n\tp.lexer.Next()\n\tresult := couldBeTypeCast\n\n\tif (flags&allowEmptyTypeParameters) != 0 && p.lexer.Token == js_lexer.TGreaterThan {\n\t\tp.lexer.Next()\n\t\treturn definitelyTypeParameters\n\t}\n\n\tfor {\n\t\thasIn := false\n\t\thasOut := false\n\t\texpectIdentifier := true\n\t\tinvalidModifierRange := logger.Range{}\n\n\t\t// Scan over a sequence of \"in\" and \"out\" modifiers (a.k.a. optional\n\t\t// variance annotations) as well as \"const\" modifiers\n\t\tfor {\n\t\t\tif p.lexer.Token == js_lexer.TConst {\n\t\t\t\tif invalidModifierRange.Len == 0 && (flags&allowConstModifier) == 0 {\n\t\t\t\t\t// Valid:\n\t\t\t\t\t//   \"class Foo<const T> {}\"\n\t\t\t\t\t// Invalid:\n\t\t\t\t\t//   \"interface Foo<const T> {}\"\n\t\t\t\t\tinvalidModifierRange = p.lexer.Range()\n\t\t\t\t}\n\t\t\t\tresult = definitelyTypeParameters\n\t\t\t\tp.lexer.Next()\n\t\t\t\texpectIdentifier = true\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif p.lexer.Token == js_lexer.TIn {\n\t\t\t\tif invalidModifierRange.Len == 0 && ((flags&allowInOutVarianceAnnotations) == 0 || hasIn || hasOut) {\n\t\t\t\t\t// Valid:\n\t\t\t\t\t//   \"type Foo<in T> = T\"\n\t\t\t\t\t// Invalid:\n\t\t\t\t\t//   \"type Foo<in in T> = T\"\n\t\t\t\t\t//   \"type Foo<out in T> = T\"\n\t\t\t\t\tinvalidModifierRange = p.lexer.Range()\n\t\t\t\t}\n\t\t\t\tp.lexer.Next()\n\t\t\t\thasIn = true\n\t\t\t\texpectIdentifier = true\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif p.lexer.IsContextualKeyword(\"out\") {\n\t\t\t\tr := p.lexer.Range()\n\t\t\t\tif invalidModifierRange.Len == 0 && (flags&allowInOutVarianceAnnotations) == 0 {\n\t\t\t\t\tinvalidModifierRange = r\n\t\t\t\t}\n\t\t\t\tp.lexer.Next()\n\t\t\t\tif invalidModifierRange.Len == 0 && hasOut && (p.lexer.Token == js_lexer.TIn || p.lexer.Token == js_lexer.TIdentifier) {\n\t\t\t\t\t// Valid:\n\t\t\t\t\t//   \"type Foo<out T> = T\"\n\t\t\t\t\t//   \"type Foo<out out> = T\"\n\t\t\t\t\t//   \"type Foo<out out, T> = T\"\n\t\t\t\t\t//   \"type Foo<out out = T> = T\"\n\t\t\t\t\t//   \"type Foo<out out extends T> = T\"\n\t\t\t\t\t// Invalid:\n\t\t\t\t\t//   \"type Foo<out out in T> = T\"\n\t\t\t\t\t//   \"type Foo<out out T> = T\"\n\t\t\t\t\tinvalidModifierRange = r\n\t\t\t\t}\n\t\t\t\thasOut = true\n\t\t\t\texpectIdentifier = false\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tbreak\n\t\t}\n\n\t\t// Only report an error for the first invalid modifier\n\t\tif invalidModifierRange.Len > 0 {\n\t\t\tp.log.AddError(&p.tracker, invalidModifierRange, fmt.Sprintf(\n\t\t\t\t\"The modifier %q is not valid here:\", p.source.TextForRange(invalidModifierRange)))\n\t\t}\n\n\t\t// expectIdentifier => Mandatory identifier (e.g. after \"type Foo <in ___\")\n\t\t// !expectIdentifier => Optional identifier (e.g. after \"type Foo <out ___\" since \"out\" may be the identifier)\n\t\tif expectIdentifier || p.lexer.Token == js_lexer.TIdentifier {\n\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t}\n\n\t\t// \"class Foo<T extends number> {}\"\n\t\tif p.lexer.Token == js_lexer.TExtends {\n\t\t\tresult = definitelyTypeParameters\n\t\t\tp.lexer.Next()\n\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t}\n\n\t\t// \"class Foo<T = void> {}\"\n\t\tif p.lexer.Token == js_lexer.TEquals {\n\t\t\tresult = definitelyTypeParameters\n\t\t\tp.lexer.Next()\n\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t}\n\n\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\tbreak\n\t\t}\n\t\tp.lexer.Next()\n\t\tif p.lexer.Token == js_lexer.TGreaterThan {\n\t\t\tresult = definitelyTypeParameters\n\t\t\tbreak\n\t\t}\n\t}\n\n\tp.lexer.ExpectGreaterThan(false /* isInsideJSXElement */)\n\treturn result\n}\n\ntype skipTypeScriptTypeArgumentsOpts struct {\n\tisInsideJSXElement               bool\n\tisParseTypeArgumentsInExpression bool\n}\n\nfunc (p *parser) skipTypeScriptTypeArguments(opts skipTypeScriptTypeArgumentsOpts) bool {\n\tswitch p.lexer.Token {\n\tcase js_lexer.TLessThan, js_lexer.TLessThanEquals,\n\t\tjs_lexer.TLessThanLessThan, js_lexer.TLessThanLessThanEquals:\n\tdefault:\n\t\treturn false\n\t}\n\n\tp.lexer.ExpectLessThan(false /* isInsideJSXElement */)\n\n\tfor {\n\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\tbreak\n\t\t}\n\t\tp.lexer.Next()\n\t}\n\n\t// This type argument list must end with a \">\"\n\tif !opts.isParseTypeArgumentsInExpression {\n\t\t// Normally TypeScript allows any token starting with \">\". For example,\n\t\t// \"Array<Array<number>>()\" is a type argument list even though there's a\n\t\t// \">>\" token, because \">>\" starts with \">\".\n\t\tp.lexer.ExpectGreaterThan(opts.isInsideJSXElement)\n\t} else {\n\t\t// However, if we're emulating the TypeScript compiler's function called\n\t\t// \"parseTypeArgumentsInExpression\" function, then we must only allow the\n\t\t// \">\" token itself. For example, \"x < y >= z\" is not a type argument list.\n\t\t//\n\t\t// This doesn't detect \">>\" in \"Array<Array<number>>()\" because the inner\n\t\t// type argument list isn't a call to \"parseTypeArgumentsInExpression\"\n\t\t// because it's within a type context, not an expression context. So the\n\t\t// token that we see here is \">\" in that case because the first \">\" has\n\t\t// already been stripped off of the \">>\" by the inner call.\n\t\tif opts.isInsideJSXElement {\n\t\t\tp.lexer.ExpectInsideJSXElement(js_lexer.TGreaterThan)\n\t\t} else {\n\t\t\tp.lexer.Expect(js_lexer.TGreaterThan)\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (p *parser) trySkipTypeArgumentsInExpressionWithBacktracking() bool {\n\toldLexer := p.lexer\n\tp.lexer.IsLogDisabled = true\n\n\t// Implement backtracking by restoring the lexer's memory to its original state\n\tdefer func() {\n\t\tr := recover()\n\t\tif _, isLexerPanic := r.(js_lexer.LexerPanic); isLexerPanic {\n\t\t\tp.lexer = oldLexer\n\t\t} else if r != nil {\n\t\t\tpanic(r)\n\t\t}\n\t}()\n\n\tif p.skipTypeScriptTypeArguments(skipTypeScriptTypeArgumentsOpts{isParseTypeArgumentsInExpression: true}) {\n\t\t// Check the token after the type argument list and backtrack if it's invalid\n\t\tif !p.tsCanFollowTypeArgumentsInExpression() {\n\t\t\tp.lexer.Unexpected()\n\t\t}\n\t}\n\n\t// Restore the log disabled flag. Note that we can't just set it back to false\n\t// because it may have been true to start with.\n\tp.lexer.IsLogDisabled = oldLexer.IsLogDisabled\n\treturn true\n}\n\nfunc (p *parser) trySkipTypeScriptTypeParametersThenOpenParenWithBacktracking() skipTypeScriptTypeParametersResult {\n\toldLexer := p.lexer\n\tp.lexer.IsLogDisabled = true\n\n\t// Implement backtracking by restoring the lexer's memory to its original state\n\tdefer func() {\n\t\tr := recover()\n\t\tif _, isLexerPanic := r.(js_lexer.LexerPanic); isLexerPanic {\n\t\t\tp.lexer = oldLexer\n\t\t} else if r != nil {\n\t\t\tpanic(r)\n\t\t}\n\t}()\n\n\tresult := p.skipTypeScriptTypeParameters(allowConstModifier)\n\tif p.lexer.Token != js_lexer.TOpenParen {\n\t\tp.lexer.Unexpected()\n\t}\n\n\t// Restore the log disabled flag. Note that we can't just set it back to false\n\t// because it may have been true to start with.\n\tp.lexer.IsLogDisabled = oldLexer.IsLogDisabled\n\treturn result\n}\n\nfunc (p *parser) trySkipTypeScriptArrowReturnTypeWithBacktracking() bool {\n\toldLexer := p.lexer\n\tp.lexer.IsLogDisabled = true\n\n\t// Implement backtracking by restoring the lexer's memory to its original state\n\tdefer func() {\n\t\tr := recover()\n\t\tif _, isLexerPanic := r.(js_lexer.LexerPanic); isLexerPanic {\n\t\t\tp.lexer = oldLexer\n\t\t} else if r != nil {\n\t\t\tpanic(r)\n\t\t}\n\t}()\n\n\tp.lexer.Expect(js_lexer.TColon)\n\tp.skipTypeScriptReturnType()\n\n\t// Check the token after this and backtrack if it's the wrong one\n\tif p.lexer.Token != js_lexer.TEqualsGreaterThan {\n\t\tp.lexer.Unexpected()\n\t}\n\n\t// Restore the log disabled flag. Note that we can't just set it back to false\n\t// because it may have been true to start with.\n\tp.lexer.IsLogDisabled = oldLexer.IsLogDisabled\n\treturn true\n}\n\n// This is a very specific function that determines whether a colon token is a\n// TypeScript arrow function return type in the case where the arrow function\n// is the middle expression of a JavaScript ternary operator (i.e. is between\n// the \"?\" and \":\" tokens). It's separate from the other function above called\n// \"trySkipTypeScriptArrowReturnTypeWithBacktracking\" because it's much more\n// expensive, and likely not as robust.\nfunc (originalParser *parser) isTypeScriptArrowReturnTypeAfterQuestionAndBeforeColon(await awaitOrYield) bool {\n\t// Implement \"backtracking\" by swallowing lexer errors on a temporary parser\n\tdefer func() {\n\t\tr := recover()\n\t\tif _, isLexerPanic := r.(js_lexer.LexerPanic); isLexerPanic {\n\t\t\treturn // Swallow this error\n\t\t} else if r != nil {\n\t\t\tpanic(r)\n\t\t}\n\t}()\n\n\t// THIS IS A GROSS HACK. Some context:\n\t//\n\t// JavaScript is designed to not require a backtracking parser. Generally a\n\t// backtracking parser is not regarded as a good thing and you try to avoid\n\t// having one if it's not necessary.\n\t//\n\t// However, TypeScript's parser does do backtracking in an (admittedly noble)\n\t// effort to retrofit nice type syntax onto JavaScript. Up until this edge\n\t// case was discovered, this backtracking was limited to type syntax so\n\t// esbuild could deal with it by using a backtracking lexer without needing a\n\t// backtracking parser.\n\t//\n\t// This edge case requires a backtracking parser. The TypeScript compiler's\n\t// algorithm for parsing this is to try to parse the entire arrow function\n\t// body and then reset all the way back to the colon for the arrow function\n\t// return type if the token following the arrow function body is not another\n\t// colon. For example:\n\t//\n\t//   x = a ? (b) : c => d;\n\t//   y = a ? (b) : c => d : e;\n\t//\n\t// The first colon of \"x\" pairs with the \"?\" because the arrow function\n\t// \"(b) : c => d\" is not followed by a colon. However, the first colon of \"y\"\n\t// starts a return type because the arrow function \"(b) : c => d\" is followed\n\t// by a colon. In other words, the first \":\" before the arrow function body\n\t// must pair with the \"?\" unless there is another \":\" to pair with it after\n\t// the function body.\n\t//\n\t// I'm not going to rewrite esbuild's parser to support backtracking for this\n\t// one edge case. So instead, esbuild tries to parse the arrow function body\n\t// using a rough copy of the parser and then always throws the result away.\n\t// So arrow function bodies will always be parsed twice for this edge case.\n\t//\n\t// This is a hack instead of a good solution because the parser isn't designed\n\t// for this, and doing this is not going to have good test coverage given that\n\t// it's an edge case. We can't prevent parser code (either currently or in the\n\t// future) from accidentally depending on some parser state that isn't cloned\n\t// here. That could result in a parser panic when parsing a more complex\n\t// version of this edge case.\n\tp := newParser(logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil), originalParser.source, originalParser.lexer, &originalParser.options)\n\n\t// Clone all state that the parser needs to parse this arrow function body\n\tp.allowIn = originalParser.allowIn\n\tp.lexer.IsLogDisabled = true\n\tp.pushScopeForParsePass(js_ast.ScopeEntry, logger.Loc{Start: 0})\n\tp.pushScopeForParsePass(js_ast.ScopeFunctionArgs, logger.Loc{Start: 1})\n\n\t// Parse the return type\n\tp.lexer.Expect(js_lexer.TColon)\n\tp.skipTypeScriptReturnType()\n\n\t// Parse the body and throw it out (with the side effect of maybe throwing an error)\n\t_ = p.parseArrowBody([]js_ast.Arg{}, fnOrArrowDataParse{await: await})\n\n\t// There must be a colon following the arrow function body to pair with the leading \"?\"\n\tp.lexer.Expect(js_lexer.TColon)\n\n\t// Parsing was successful if we get here\n\treturn true\n}\n\nfunc (p *parser) trySkipTypeScriptArrowArgsWithBacktracking() bool {\n\toldLexer := p.lexer\n\tp.lexer.IsLogDisabled = true\n\n\t// Implement backtracking by restoring the lexer's memory to its original state\n\tdefer func() {\n\t\tr := recover()\n\t\tif _, isLexerPanic := r.(js_lexer.LexerPanic); isLexerPanic {\n\t\t\tp.lexer = oldLexer\n\t\t} else if r != nil {\n\t\t\tpanic(r)\n\t\t}\n\t}()\n\n\tp.skipTypeScriptFnArgs()\n\tp.lexer.Expect(js_lexer.TEqualsGreaterThan)\n\n\t// Restore the log disabled flag. Note that we can't just set it back to false\n\t// because it may have been true to start with.\n\tp.lexer.IsLogDisabled = oldLexer.IsLogDisabled\n\treturn true\n}\n\nfunc (p *parser) trySkipTypeScriptConstraintOfInferTypeWithBacktracking(flags skipTypeFlags) bool {\n\toldLexer := p.lexer\n\tp.lexer.IsLogDisabled = true\n\n\t// Implement backtracking by restoring the lexer's memory to its original state\n\tdefer func() {\n\t\tr := recover()\n\t\tif _, isLexerPanic := r.(js_lexer.LexerPanic); isLexerPanic {\n\t\t\tp.lexer = oldLexer\n\t\t} else if r != nil {\n\t\t\tpanic(r)\n\t\t}\n\t}()\n\n\tp.lexer.Expect(js_lexer.TExtends)\n\tp.skipTypeScriptTypeWithFlags(js_ast.LPrefix, disallowConditionalTypesFlag)\n\tif !flags.has(disallowConditionalTypesFlag) && p.lexer.Token == js_lexer.TQuestion {\n\t\tp.lexer.Unexpected()\n\t}\n\n\t// Restore the log disabled flag. Note that we can't just set it back to false\n\t// because it may have been true to start with.\n\tp.lexer.IsLogDisabled = oldLexer.IsLogDisabled\n\treturn true\n}\n\n// Returns true if the current less-than token is considered to be an arrow\n// function under TypeScript's rules for files containing JSX syntax\nfunc (p *parser) isTSArrowFnJSX() (isTSArrowFn bool) {\n\toldLexer := p.lexer\n\tp.lexer.Next()\n\n\t// Look ahead to see if this should be an arrow function instead\n\tif p.lexer.Token == js_lexer.TConst {\n\t\tp.lexer.Next()\n\t}\n\tif p.lexer.Token == js_lexer.TIdentifier {\n\t\tp.lexer.Next()\n\t\tif p.lexer.Token == js_lexer.TComma || p.lexer.Token == js_lexer.TEquals {\n\t\t\tisTSArrowFn = true\n\t\t} else if p.lexer.Token == js_lexer.TExtends {\n\t\t\tp.lexer.Next()\n\t\t\tisTSArrowFn = p.lexer.Token != js_lexer.TEquals && p.lexer.Token != js_lexer.TGreaterThan && p.lexer.Token != js_lexer.TSlash\n\t\t}\n\t}\n\n\t// Restore the lexer\n\tp.lexer = oldLexer\n\treturn\n}\n\n// This function is taken from the official TypeScript compiler source code:\n// https://github.com/microsoft/TypeScript/blob/master/src/compiler/parser.ts\n//\n// This function is pretty inefficient as written, and could be collapsed into\n// a single switch statement. But that would make it harder to keep this in\n// sync with the TypeScript compiler's source code, so we keep doing it the\n// slow way.\nfunc (p *parser) tsCanFollowTypeArgumentsInExpression() bool {\n\tswitch p.lexer.Token {\n\tcase\n\t\t// These tokens can follow a type argument list in a call expression.\n\t\tjs_lexer.TOpenParen,                     // foo<x>(\n\t\tjs_lexer.TNoSubstitutionTemplateLiteral, // foo<T> `...`\n\t\tjs_lexer.TTemplateHead:                  // foo<T> `...${100}...`\n\t\treturn true\n\n\t// A type argument list followed by `<` never makes sense, and a type argument list followed\n\t// by `>` is ambiguous with a (re-scanned) `>>` operator, so we disqualify both. Also, in\n\t// this context, `+` and `-` are unary operators, not binary operators.\n\tcase js_lexer.TLessThan,\n\t\tjs_lexer.TGreaterThan,\n\t\tjs_lexer.TPlus,\n\t\tjs_lexer.TMinus,\n\t\t// TypeScript always sees \"TGreaterThan\" instead of these tokens since\n\t\t// their scanner works a little differently than our lexer. So since\n\t\t// \"TGreaterThan\" is forbidden above, we also forbid these too.\n\t\tjs_lexer.TGreaterThanEquals,\n\t\tjs_lexer.TGreaterThanGreaterThan,\n\t\tjs_lexer.TGreaterThanGreaterThanEquals,\n\t\tjs_lexer.TGreaterThanGreaterThanGreaterThan,\n\t\tjs_lexer.TGreaterThanGreaterThanGreaterThanEquals:\n\t\treturn false\n\t}\n\n\t// We favor the type argument list interpretation when it is immediately followed by\n\t// a line break, a binary operator, or something that can't start an expression.\n\treturn p.lexer.HasNewlineBefore || p.tsIsBinaryOperator() || !p.tsIsStartOfExpression()\n}\n\n// This function is taken from the official TypeScript compiler source code:\n// https://github.com/microsoft/TypeScript/blob/master/src/compiler/parser.ts\nfunc (p *parser) tsIsBinaryOperator() bool {\n\tswitch p.lexer.Token {\n\tcase js_lexer.TIn:\n\t\treturn p.allowIn\n\n\tcase\n\t\tjs_lexer.TQuestionQuestion,\n\t\tjs_lexer.TBarBar,\n\t\tjs_lexer.TAmpersandAmpersand,\n\t\tjs_lexer.TBar,\n\t\tjs_lexer.TCaret,\n\t\tjs_lexer.TAmpersand,\n\t\tjs_lexer.TEqualsEquals,\n\t\tjs_lexer.TExclamationEquals,\n\t\tjs_lexer.TEqualsEqualsEquals,\n\t\tjs_lexer.TExclamationEqualsEquals,\n\t\tjs_lexer.TLessThan,\n\t\tjs_lexer.TGreaterThan,\n\t\tjs_lexer.TLessThanEquals,\n\t\tjs_lexer.TGreaterThanEquals,\n\t\tjs_lexer.TInstanceof,\n\t\tjs_lexer.TLessThanLessThan,\n\t\tjs_lexer.TGreaterThanGreaterThan,\n\t\tjs_lexer.TGreaterThanGreaterThanGreaterThan,\n\t\tjs_lexer.TPlus,\n\t\tjs_lexer.TMinus,\n\t\tjs_lexer.TAsterisk,\n\t\tjs_lexer.TSlash,\n\t\tjs_lexer.TPercent,\n\t\tjs_lexer.TAsteriskAsterisk:\n\t\treturn true\n\n\tcase js_lexer.TIdentifier:\n\t\tif p.lexer.IsContextualKeyword(\"as\") || p.lexer.IsContextualKeyword(\"satisfies\") {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\n// This function is taken from the official TypeScript compiler source code:\n// https://github.com/microsoft/TypeScript/blob/master/src/compiler/parser.ts\nfunc (p *parser) tsIsStartOfExpression() bool {\n\tif p.tsIsStartOfLeftHandSideExpression() {\n\t\treturn true\n\t}\n\n\tswitch p.lexer.Token {\n\tcase\n\t\tjs_lexer.TPlus,\n\t\tjs_lexer.TMinus,\n\t\tjs_lexer.TTilde,\n\t\tjs_lexer.TExclamation,\n\t\tjs_lexer.TDelete,\n\t\tjs_lexer.TTypeof,\n\t\tjs_lexer.TVoid,\n\t\tjs_lexer.TPlusPlus,\n\t\tjs_lexer.TMinusMinus,\n\t\tjs_lexer.TLessThan,\n\t\tjs_lexer.TPrivateIdentifier,\n\t\tjs_lexer.TAt:\n\t\treturn true\n\n\tdefault:\n\t\tif p.lexer.Token == js_lexer.TIdentifier && (p.lexer.Identifier.String == \"await\" || p.lexer.Identifier.String == \"yield\") {\n\t\t\t// Yield/await always starts an expression.  Either it is an identifier (in which case\n\t\t\t// it is definitely an expression).  Or it's a keyword (either because we're in\n\t\t\t// a generator or async function, or in strict mode (or both)) and it started a yield or await expression.\n\t\t\treturn true\n\t\t}\n\n\t\t// Error tolerance.  If we see the start of some binary operator, we consider\n\t\t// that the start of an expression.  That way we'll parse out a missing identifier,\n\t\t// give a good message about an identifier being missing, and then consume the\n\t\t// rest of the binary expression.\n\t\tif p.tsIsBinaryOperator() {\n\t\t\treturn true\n\t\t}\n\n\t\treturn p.tsIsIdentifier()\n\t}\n}\n\n// This function is taken from the official TypeScript compiler source code:\n// https://github.com/microsoft/TypeScript/blob/master/src/compiler/parser.ts\nfunc (p *parser) tsIsStartOfLeftHandSideExpression() bool {\n\tswitch p.lexer.Token {\n\tcase\n\t\tjs_lexer.TThis,\n\t\tjs_lexer.TSuper,\n\t\tjs_lexer.TNull,\n\t\tjs_lexer.TTrue,\n\t\tjs_lexer.TFalse,\n\t\tjs_lexer.TNumericLiteral,\n\t\tjs_lexer.TBigIntegerLiteral,\n\t\tjs_lexer.TStringLiteral,\n\t\tjs_lexer.TNoSubstitutionTemplateLiteral,\n\t\tjs_lexer.TTemplateHead,\n\t\tjs_lexer.TOpenParen,\n\t\tjs_lexer.TOpenBracket,\n\t\tjs_lexer.TOpenBrace,\n\t\tjs_lexer.TFunction,\n\t\tjs_lexer.TClass,\n\t\tjs_lexer.TNew,\n\t\tjs_lexer.TSlash,\n\t\tjs_lexer.TSlashEquals,\n\t\tjs_lexer.TIdentifier:\n\t\treturn true\n\n\tcase js_lexer.TImport:\n\t\treturn p.tsLookAheadNextTokenIsOpenParenOrLessThanOrDot()\n\n\tdefault:\n\t\treturn p.tsIsIdentifier()\n\t}\n}\n\n// This function is taken from the official TypeScript compiler source code:\n// https://github.com/microsoft/TypeScript/blob/master/src/compiler/parser.ts\nfunc (p *parser) tsLookAheadNextTokenIsOpenParenOrLessThanOrDot() (result bool) {\n\toldLexer := p.lexer\n\tp.lexer.Next()\n\n\tresult = p.lexer.Token == js_lexer.TOpenParen ||\n\t\tp.lexer.Token == js_lexer.TLessThan ||\n\t\tp.lexer.Token == js_lexer.TDot\n\n\t// Restore the lexer\n\tp.lexer = oldLexer\n\treturn\n}\n\n// This function is taken from the official TypeScript compiler source code:\n// https://github.com/microsoft/TypeScript/blob/master/src/compiler/parser.ts\nfunc (p *parser) tsIsIdentifier() bool {\n\tif p.lexer.Token == js_lexer.TIdentifier {\n\t\t// If we have a 'yield' keyword, and we're in the [yield] context, then 'yield' is\n\t\t// considered a keyword and is not an identifier.\n\t\tif p.fnOrArrowDataParse.yield != allowIdent && p.lexer.Identifier.String == \"yield\" {\n\t\t\treturn false\n\t\t}\n\n\t\t// If we have a 'await' keyword, and we're in the [Await] context, then 'await' is\n\t\t// considered a keyword and is not an identifier.\n\t\tif p.fnOrArrowDataParse.await != allowIdent && p.lexer.Identifier.String == \"await\" {\n\t\t\treturn false\n\t\t}\n\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc (p *parser) skipTypeScriptInterfaceStmt(opts parseStmtOpts) {\n\tname := p.lexer.Identifier.String\n\tp.lexer.Expect(js_lexer.TIdentifier)\n\n\tif opts.isModuleScope {\n\t\tp.localTypeNames[name] = true\n\t}\n\n\tp.skipTypeScriptTypeParameters(allowInOutVarianceAnnotations | allowEmptyTypeParameters)\n\n\tif p.lexer.Token == js_lexer.TExtends {\n\t\tp.lexer.Next()\n\t\tfor {\n\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t}\n\t}\n\n\tif p.lexer.IsContextualKeyword(\"implements\") {\n\t\tp.lexer.Next()\n\t\tfor {\n\t\t\tp.skipTypeScriptType(js_ast.LLowest)\n\t\t\tif p.lexer.Token != js_lexer.TComma {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.lexer.Next()\n\t\t}\n\t}\n\n\tp.skipTypeScriptObjectType()\n}\n\nfunc (p *parser) skipTypeScriptTypeStmt(opts parseStmtOpts) {\n\tif opts.isExport {\n\t\tswitch p.lexer.Token {\n\t\tcase js_lexer.TOpenBrace:\n\t\t\t// \"export type {foo}\"\n\t\t\t// \"export type {foo} from 'bar'\"\n\t\t\tp.parseExportClause()\n\t\t\tif p.lexer.IsContextualKeyword(\"from\") {\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.parsePath()\n\t\t\t}\n\t\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\t\treturn\n\n\t\t// This is invalid TypeScript, and is rejected by the TypeScript compiler:\n\t\t//\n\t\t//   example.ts:1:1 - error TS1383: Only named exports may use 'export type'.\n\t\t//\n\t\t//   1 export type * from './types'\n\t\t//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\t\t//\n\t\t// However, people may not know this and then blame esbuild for it not\n\t\t// working. So we parse it anyway and then discard it (since we always\n\t\t// discard all types). People who do this should be running the TypeScript\n\t\t// type checker when using TypeScript, which will then report this error.\n\t\tcase js_lexer.TAsterisk:\n\t\t\t// \"export type * from 'path'\"\n\t\t\tp.lexer.Next()\n\t\t\tif p.lexer.IsContextualKeyword(\"as\") {\n\t\t\t\t// \"export type * as ns from 'path'\"\n\t\t\t\tp.lexer.Next()\n\t\t\t\tp.parseClauseAlias(\"export\")\n\t\t\t\tp.lexer.Next()\n\t\t\t}\n\t\t\tp.lexer.ExpectContextualKeyword(\"from\")\n\t\t\tp.parsePath()\n\t\t\tp.lexer.ExpectOrInsertSemicolon()\n\t\t\treturn\n\t\t}\n\t}\n\n\tname := p.lexer.Identifier.String\n\tp.lexer.Expect(js_lexer.TIdentifier)\n\n\tif opts.isModuleScope {\n\t\tp.localTypeNames[name] = true\n\t}\n\n\tp.skipTypeScriptTypeParameters(allowInOutVarianceAnnotations | allowEmptyTypeParameters)\n\tp.lexer.Expect(js_lexer.TEquals)\n\tp.skipTypeScriptType(js_ast.LLowest)\n\tp.lexer.ExpectOrInsertSemicolon()\n}\n\nfunc (p *parser) parseTypeScriptEnumStmt(loc logger.Loc, opts parseStmtOpts) js_ast.Stmt {\n\tp.lexer.Expect(js_lexer.TEnum)\n\tnameLoc := p.lexer.Loc()\n\tnameText := p.lexer.Identifier.String\n\tp.lexer.Expect(js_lexer.TIdentifier)\n\tname := ast.LocRef{Loc: nameLoc, Ref: ast.InvalidRef}\n\n\t// Generate the namespace object\n\texportedMembers := p.getOrCreateExportedNamespaceMembers(nameText, opts.isExport)\n\ttsNamespace := &js_ast.TSNamespaceScope{\n\t\tExportedMembers: exportedMembers,\n\t\tArgRef:          ast.InvalidRef,\n\t\tIsEnumScope:     true,\n\t}\n\tenumMemberData := &js_ast.TSNamespaceMemberNamespace{\n\t\tExportedMembers: exportedMembers,\n\t}\n\n\t// Declare the enum and create the scope\n\tscopeIndex := len(p.scopesInOrder)\n\tif !opts.isTypeScriptDeclare {\n\t\tname.Ref = p.declareSymbol(ast.SymbolTSEnum, nameLoc, nameText)\n\t\tp.pushScopeForParsePass(js_ast.ScopeEntry, loc)\n\t\tp.currentScope.TSNamespace = tsNamespace\n\t\tp.refToTSNamespaceMemberData[name.Ref] = enumMemberData\n\t}\n\n\tp.lexer.Expect(js_lexer.TOpenBrace)\n\tvalues := []js_ast.EnumValue{}\n\n\toldFnOrArrowData := p.fnOrArrowDataParse\n\tp.fnOrArrowDataParse = fnOrArrowDataParse{\n\t\tisThisDisallowed: true,\n\t\tneedsAsyncLoc:    logger.Loc{Start: -1},\n\t}\n\n\t// Parse the body\n\tfor p.lexer.Token != js_lexer.TCloseBrace {\n\t\tnameRange := p.lexer.Range()\n\t\tvalue := js_ast.EnumValue{\n\t\t\tLoc: nameRange.Loc,\n\t\t\tRef: ast.InvalidRef,\n\t\t}\n\n\t\t// Parse the name\n\t\tvar nameText string\n\t\tif p.lexer.Token == js_lexer.TStringLiteral {\n\t\t\tvalue.Name = p.lexer.StringLiteral()\n\t\t\tnameText = helpers.UTF16ToString(value.Name)\n\t\t} else if p.lexer.IsIdentifierOrKeyword() {\n\t\t\tnameText = p.lexer.Identifier.String\n\t\t\tvalue.Name = helpers.StringToUTF16(nameText)\n\t\t} else {\n\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t}\n\t\tp.lexer.Next()\n\n\t\t// Identifiers can be referenced by other values\n\t\tif !opts.isTypeScriptDeclare && js_ast.IsIdentifierUTF16(value.Name) {\n\t\t\tvalue.Ref = p.declareSymbol(ast.SymbolOther, value.Loc, helpers.UTF16ToString(value.Name))\n\t\t}\n\n\t\t// Parse the initializer\n\t\tif p.lexer.Token == js_lexer.TEquals {\n\t\t\tp.lexer.Next()\n\t\t\tvalue.ValueOrNil = p.parseExpr(js_ast.LComma)\n\t\t}\n\n\t\tvalues = append(values, value)\n\n\t\t// Add this enum value as a member of the enum's namespace\n\t\texportedMembers[nameText] = js_ast.TSNamespaceMember{\n\t\t\tLoc:         value.Loc,\n\t\t\tData:        &js_ast.TSNamespaceMemberProperty{},\n\t\t\tIsEnumValue: true,\n\t\t}\n\n\t\tif p.lexer.Token != js_lexer.TComma && p.lexer.Token != js_lexer.TSemicolon {\n\t\t\tif p.lexer.IsIdentifierOrKeyword() || p.lexer.Token == js_lexer.TStringLiteral {\n\t\t\t\tvar errorLoc logger.Loc\n\t\t\t\tvar errorText string\n\n\t\t\t\tif value.ValueOrNil.Data == nil {\n\t\t\t\t\terrorLoc = logger.Loc{Start: nameRange.End()}\n\t\t\t\t\terrorText = fmt.Sprintf(\"Expected \\\",\\\" after %q in enum\", nameText)\n\t\t\t\t} else {\n\t\t\t\t\tvar nextName string\n\t\t\t\t\tif p.lexer.Token == js_lexer.TStringLiteral {\n\t\t\t\t\t\tnextName = helpers.UTF16ToString(p.lexer.StringLiteral())\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnextName = p.lexer.Identifier.String\n\t\t\t\t\t}\n\t\t\t\t\terrorLoc = p.lexer.Loc()\n\t\t\t\t\terrorText = fmt.Sprintf(\"Expected \\\",\\\" before %q in enum\", nextName)\n\t\t\t\t}\n\n\t\t\t\tdata := p.tracker.MsgData(logger.Range{Loc: errorLoc}, errorText)\n\t\t\t\tdata.Location.Suggestion = \",\"\n\t\t\t\tp.log.AddMsg(logger.Msg{Kind: logger.Error, Data: data})\n\t\t\t\tpanic(js_lexer.LexerPanic{})\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tp.lexer.Next()\n\t}\n\n\tp.fnOrArrowDataParse = oldFnOrArrowData\n\n\tif !opts.isTypeScriptDeclare {\n\t\t// Avoid a collision with the enum closure argument variable if the\n\t\t// enum exports a symbol with the same name as the enum itself:\n\t\t//\n\t\t//   enum foo {\n\t\t//     foo = 123,\n\t\t//     bar = foo,\n\t\t//   }\n\t\t//\n\t\t// TypeScript generates the following code in this case:\n\t\t//\n\t\t//   var foo;\n\t\t//   (function (foo) {\n\t\t//     foo[foo[\"foo\"] = 123] = \"foo\";\n\t\t//     foo[foo[\"bar\"] = 123] = \"bar\";\n\t\t//   })(foo || (foo = {}));\n\t\t//\n\t\t// Whereas in this case:\n\t\t//\n\t\t//   enum foo {\n\t\t//     bar = foo as any,\n\t\t//   }\n\t\t//\n\t\t// TypeScript generates the following code:\n\t\t//\n\t\t//   var foo;\n\t\t//   (function (foo) {\n\t\t//     foo[foo[\"bar\"] = foo] = \"bar\";\n\t\t//   })(foo || (foo = {}));\n\t\t//\n\t\tif _, ok := p.currentScope.Members[nameText]; ok {\n\t\t\t// Add a \"_\" to make tests easier to read, since non-bundler tests don't\n\t\t\t// run the renamer. For external-facing things the renamer will avoid\n\t\t\t// collisions automatically so this isn't important for correctness.\n\t\t\ttsNamespace.ArgRef = p.newSymbol(ast.SymbolHoisted, \"_\"+nameText)\n\t\t\tp.currentScope.Generated = append(p.currentScope.Generated, tsNamespace.ArgRef)\n\t\t} else {\n\t\t\ttsNamespace.ArgRef = p.declareSymbol(ast.SymbolHoisted, nameLoc, nameText)\n\t\t}\n\t\tp.refToTSNamespaceMemberData[tsNamespace.ArgRef] = enumMemberData\n\n\t\tp.popScope()\n\t}\n\n\tp.lexer.Expect(js_lexer.TCloseBrace)\n\n\tif opts.isTypeScriptDeclare {\n\t\tif opts.isNamespaceScope && opts.isExport {\n\t\t\tp.hasNonLocalExportDeclareInsideNamespace = true\n\t\t}\n\n\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptShared}\n\t}\n\n\t// Save these for when we do out-of-order enum visiting\n\tif p.scopesInOrderForEnum == nil {\n\t\tp.scopesInOrderForEnum = make(map[logger.Loc][]scopeOrder)\n\t}\n\n\t// Make a copy of \"scopesInOrder\" instead of a slice since the original\n\t// array may be flattened in the future by \"popAndFlattenScope\"\n\tp.scopesInOrderForEnum[loc] = append([]scopeOrder{}, p.scopesInOrder[scopeIndex:]...)\n\n\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SEnum{\n\t\tName:     name,\n\t\tArg:      tsNamespace.ArgRef,\n\t\tValues:   values,\n\t\tIsExport: opts.isExport,\n\t}}\n}\n\n// This assumes the caller has already parsed the \"import\" token\nfunc (p *parser) parseTypeScriptImportEqualsStmt(loc logger.Loc, opts parseStmtOpts, defaultNameLoc logger.Loc, defaultName string) js_ast.Stmt {\n\tp.lexer.Expect(js_lexer.TEquals)\n\n\tkind := p.selectLocalKind(js_ast.LocalConst)\n\tname := p.lexer.Identifier\n\tvalue := js_ast.Expr{Loc: p.lexer.Loc(), Data: &js_ast.EIdentifier{Ref: p.storeNameInRef(name)}}\n\tp.lexer.Expect(js_lexer.TIdentifier)\n\n\tif name.String == \"require\" && p.lexer.Token == js_lexer.TOpenParen {\n\t\t// \"import ns = require('x')\"\n\t\tp.lexer.Next()\n\t\tpath := js_ast.Expr{Loc: p.lexer.Loc(), Data: &js_ast.EString{Value: p.lexer.StringLiteral()}}\n\t\tp.lexer.Expect(js_lexer.TStringLiteral)\n\t\tp.lexer.Expect(js_lexer.TCloseParen)\n\t\tvalue.Data = &js_ast.ECall{\n\t\t\tTarget: value,\n\t\t\tArgs:   []js_ast.Expr{path},\n\t\t}\n\t} else {\n\t\t// \"import Foo = Bar\"\n\t\t// \"import Foo = Bar.Baz\"\n\t\tfor p.lexer.Token == js_lexer.TDot {\n\t\t\tp.lexer.Next()\n\t\t\tvalue.Data = &js_ast.EDot{\n\t\t\t\tTarget:               value,\n\t\t\t\tName:                 p.lexer.Identifier.String,\n\t\t\t\tNameLoc:              p.lexer.Loc(),\n\t\t\t\tCanBeRemovedIfUnused: true,\n\t\t\t}\n\t\t\tp.lexer.Expect(js_lexer.TIdentifier)\n\t\t}\n\t}\n\n\tp.lexer.ExpectOrInsertSemicolon()\n\n\tif opts.isTypeScriptDeclare {\n\t\t// \"import type foo = require('bar');\"\n\t\t// \"import type foo = bar.baz;\"\n\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptShared}\n\t}\n\n\tref := p.declareSymbol(ast.SymbolConst, defaultNameLoc, defaultName)\n\tdecls := []js_ast.Decl{{\n\t\tBinding:    js_ast.Binding{Loc: defaultNameLoc, Data: &js_ast.BIdentifier{Ref: ref}},\n\t\tValueOrNil: value,\n\t}}\n\n\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SLocal{\n\t\tKind:              kind,\n\t\tDecls:             decls,\n\t\tIsExport:          opts.isExport,\n\t\tWasTSImportEquals: true,\n\t}}\n}\n\n// Generate a TypeScript namespace object for this namespace's scope. If this\n// namespace is another block that is to be merged with an existing namespace,\n// use that earlier namespace's object instead.\nfunc (p *parser) getOrCreateExportedNamespaceMembers(name string, isExport bool) js_ast.TSNamespaceMembers {\n\t// Merge with a sibling namespace from the same scope\n\tif existingMember, ok := p.currentScope.Members[name]; ok {\n\t\tif memberData, ok := p.refToTSNamespaceMemberData[existingMember.Ref]; ok {\n\t\t\tif nsMemberData, ok := memberData.(*js_ast.TSNamespaceMemberNamespace); ok {\n\t\t\t\treturn nsMemberData.ExportedMembers\n\t\t\t}\n\t\t}\n\t}\n\n\t// Merge with a sibling namespace from a different scope\n\tif isExport {\n\t\tif parentNamespace := p.currentScope.TSNamespace; parentNamespace != nil {\n\t\t\tif existing, ok := parentNamespace.ExportedMembers[name]; ok {\n\t\t\t\tif existing, ok := existing.Data.(*js_ast.TSNamespaceMemberNamespace); ok {\n\t\t\t\t\treturn existing.ExportedMembers\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Otherwise, generate a new namespace object\n\treturn make(js_ast.TSNamespaceMembers)\n}\n\nfunc (p *parser) parseTypeScriptNamespaceStmt(loc logger.Loc, opts parseStmtOpts) js_ast.Stmt {\n\t// \"namespace Foo {}\"\n\tnameLoc := p.lexer.Loc()\n\tnameText := p.lexer.Identifier.String\n\tp.lexer.Next()\n\n\t// Generate the namespace object\n\texportedMembers := p.getOrCreateExportedNamespaceMembers(nameText, opts.isExport)\n\ttsNamespace := &js_ast.TSNamespaceScope{\n\t\tExportedMembers: exportedMembers,\n\t\tArgRef:          ast.InvalidRef,\n\t}\n\tnsMemberData := &js_ast.TSNamespaceMemberNamespace{\n\t\tExportedMembers: exportedMembers,\n\t}\n\n\t// Declare the namespace and create the scope\n\tname := ast.LocRef{Loc: nameLoc, Ref: ast.InvalidRef}\n\tscopeIndex := p.pushScopeForParsePass(js_ast.ScopeEntry, loc)\n\tp.currentScope.TSNamespace = tsNamespace\n\n\toldHasNonLocalExportDeclareInsideNamespace := p.hasNonLocalExportDeclareInsideNamespace\n\toldFnOrArrowData := p.fnOrArrowDataParse\n\tp.hasNonLocalExportDeclareInsideNamespace = false\n\tp.fnOrArrowDataParse = fnOrArrowDataParse{\n\t\tisThisDisallowed:   true,\n\t\tisReturnDisallowed: true,\n\t\tneedsAsyncLoc:      logger.Loc{Start: -1},\n\t}\n\n\t// Parse the statements inside the namespace\n\tvar stmts []js_ast.Stmt\n\tif p.lexer.Token == js_lexer.TDot {\n\t\tdotLoc := p.lexer.Loc()\n\t\tp.lexer.Next()\n\t\tstmts = []js_ast.Stmt{p.parseTypeScriptNamespaceStmt(dotLoc, parseStmtOpts{\n\t\t\tisExport:            true,\n\t\t\tisNamespaceScope:    true,\n\t\t\tisTypeScriptDeclare: opts.isTypeScriptDeclare,\n\t\t})}\n\t} else if opts.isTypeScriptDeclare && p.lexer.Token != js_lexer.TOpenBrace {\n\t\tp.lexer.ExpectOrInsertSemicolon()\n\t} else {\n\t\tp.lexer.Expect(js_lexer.TOpenBrace)\n\t\tstmts = p.parseStmtsUpTo(js_lexer.TCloseBrace, parseStmtOpts{\n\t\t\tisNamespaceScope:    true,\n\t\t\tisTypeScriptDeclare: opts.isTypeScriptDeclare,\n\t\t})\n\t\tp.lexer.Next()\n\t}\n\n\thasNonLocalExportDeclareInsideNamespace := p.hasNonLocalExportDeclareInsideNamespace\n\tp.hasNonLocalExportDeclareInsideNamespace = oldHasNonLocalExportDeclareInsideNamespace\n\tp.fnOrArrowDataParse = oldFnOrArrowData\n\n\t// Add any exported members from this namespace's body as members of the\n\t// associated namespace object.\n\tfor _, stmt := range stmts {\n\t\tswitch s := stmt.Data.(type) {\n\t\tcase *js_ast.SFunction:\n\t\t\tif s.IsExport {\n\t\t\t\tname := p.symbols[s.Fn.Name.Ref.InnerIndex].OriginalName\n\t\t\t\tmember := js_ast.TSNamespaceMember{\n\t\t\t\t\tLoc:  s.Fn.Name.Loc,\n\t\t\t\t\tData: &js_ast.TSNamespaceMemberProperty{},\n\t\t\t\t}\n\t\t\t\texportedMembers[name] = member\n\t\t\t\tp.refToTSNamespaceMemberData[s.Fn.Name.Ref] = member.Data\n\t\t\t}\n\n\t\tcase *js_ast.SClass:\n\t\t\tif s.IsExport {\n\t\t\t\tname := p.symbols[s.Class.Name.Ref.InnerIndex].OriginalName\n\t\t\t\tmember := js_ast.TSNamespaceMember{\n\t\t\t\t\tLoc:  s.Class.Name.Loc,\n\t\t\t\t\tData: &js_ast.TSNamespaceMemberProperty{},\n\t\t\t\t}\n\t\t\t\texportedMembers[name] = member\n\t\t\t\tp.refToTSNamespaceMemberData[s.Class.Name.Ref] = member.Data\n\t\t\t}\n\n\t\tcase *js_ast.SNamespace:\n\t\t\tif s.IsExport {\n\t\t\t\tif memberData, ok := p.refToTSNamespaceMemberData[s.Name.Ref]; ok {\n\t\t\t\t\tif nsMemberData, ok := memberData.(*js_ast.TSNamespaceMemberNamespace); ok {\n\t\t\t\t\t\tmember := js_ast.TSNamespaceMember{\n\t\t\t\t\t\t\tLoc: s.Name.Loc,\n\t\t\t\t\t\t\tData: &js_ast.TSNamespaceMemberNamespace{\n\t\t\t\t\t\t\t\tExportedMembers: nsMemberData.ExportedMembers,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t\texportedMembers[p.symbols[s.Name.Ref.InnerIndex].OriginalName] = member\n\t\t\t\t\t\tp.refToTSNamespaceMemberData[s.Name.Ref] = member.Data\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *js_ast.SEnum:\n\t\t\tif s.IsExport {\n\t\t\t\tif memberData, ok := p.refToTSNamespaceMemberData[s.Name.Ref]; ok {\n\t\t\t\t\tif nsMemberData, ok := memberData.(*js_ast.TSNamespaceMemberNamespace); ok {\n\t\t\t\t\t\tmember := js_ast.TSNamespaceMember{\n\t\t\t\t\t\t\tLoc: s.Name.Loc,\n\t\t\t\t\t\t\tData: &js_ast.TSNamespaceMemberNamespace{\n\t\t\t\t\t\t\t\tExportedMembers: nsMemberData.ExportedMembers,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t\texportedMembers[p.symbols[s.Name.Ref.InnerIndex].OriginalName] = member\n\t\t\t\t\t\tp.refToTSNamespaceMemberData[s.Name.Ref] = member.Data\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *js_ast.SLocal:\n\t\t\tif s.IsExport {\n\t\t\t\tjs_ast.ForEachIdentifierBindingInDecls(s.Decls, func(loc logger.Loc, b *js_ast.BIdentifier) {\n\t\t\t\t\tname := p.symbols[b.Ref.InnerIndex].OriginalName\n\t\t\t\t\tmember := js_ast.TSNamespaceMember{\n\t\t\t\t\t\tLoc:  loc,\n\t\t\t\t\t\tData: &js_ast.TSNamespaceMemberProperty{},\n\t\t\t\t\t}\n\t\t\t\t\texportedMembers[name] = member\n\t\t\t\t\tp.refToTSNamespaceMemberData[b.Ref] = member.Data\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\t// Import assignments may be only used in type expressions, not value\n\t// expressions. If this is the case, the TypeScript compiler removes\n\t// them entirely from the output. That can cause the namespace itself\n\t// to be considered empty and thus be removed.\n\timportEqualsCount := 0\n\tfor _, stmt := range stmts {\n\t\tif local, ok := stmt.Data.(*js_ast.SLocal); ok && local.WasTSImportEquals && !local.IsExport {\n\t\t\timportEqualsCount++\n\t\t}\n\t}\n\n\t// TypeScript omits namespaces without values. These namespaces\n\t// are only allowed to be used in type expressions. They are\n\t// allowed to be exported, but can also only be used in type\n\t// expressions when imported. So we shouldn't count them as a\n\t// real export either.\n\t//\n\t// TypeScript also strangely counts namespaces containing only\n\t// \"export declare\" statements as non-empty even though \"declare\"\n\t// statements are only type annotations. We cannot omit the namespace\n\t// in that case. See https://github.com/evanw/esbuild/issues/1158.\n\tif (len(stmts) == importEqualsCount && !hasNonLocalExportDeclareInsideNamespace) || opts.isTypeScriptDeclare {\n\t\tp.popAndDiscardScope(scopeIndex)\n\t\tif opts.isModuleScope {\n\t\t\tp.localTypeNames[nameText] = true\n\t\t}\n\t\treturn js_ast.Stmt{Loc: loc, Data: js_ast.STypeScriptShared}\n\t}\n\n\tif !opts.isTypeScriptDeclare {\n\t\t// Avoid a collision with the namespace closure argument variable if the\n\t\t// namespace exports a symbol with the same name as the namespace itself:\n\t\t//\n\t\t//   namespace foo {\n\t\t//     export let foo = 123\n\t\t//     console.log(foo)\n\t\t//   }\n\t\t//\n\t\t// TypeScript generates the following code in this case:\n\t\t//\n\t\t//   var foo;\n\t\t//   (function (foo_1) {\n\t\t//     foo_1.foo = 123;\n\t\t//     console.log(foo_1.foo);\n\t\t//   })(foo || (foo = {}));\n\t\t//\n\t\tif _, ok := p.currentScope.Members[nameText]; ok {\n\t\t\t// Add a \"_\" to make tests easier to read, since non-bundler tests don't\n\t\t\t// run the renamer. For external-facing things the renamer will avoid\n\t\t\t// collisions automatically so this isn't important for correctness.\n\t\t\ttsNamespace.ArgRef = p.newSymbol(ast.SymbolHoisted, \"_\"+nameText)\n\t\t\tp.currentScope.Generated = append(p.currentScope.Generated, tsNamespace.ArgRef)\n\t\t} else {\n\t\t\ttsNamespace.ArgRef = p.declareSymbol(ast.SymbolHoisted, nameLoc, nameText)\n\t\t}\n\t\tp.refToTSNamespaceMemberData[tsNamespace.ArgRef] = nsMemberData\n\t}\n\n\tp.popScope()\n\tif !opts.isTypeScriptDeclare {\n\t\tname.Ref = p.declareSymbol(ast.SymbolTSNamespace, nameLoc, nameText)\n\t\tp.refToTSNamespaceMemberData[name.Ref] = nsMemberData\n\t}\n\treturn js_ast.Stmt{Loc: loc, Data: &js_ast.SNamespace{\n\t\tName:     name,\n\t\tArg:      tsNamespace.ArgRef,\n\t\tStmts:    stmts,\n\t\tIsExport: opts.isExport,\n\t}}\n}\n\nfunc (p *parser) generateClosureForTypeScriptNamespaceOrEnum(\n\tstmts []js_ast.Stmt, stmtLoc logger.Loc, isExport bool, nameLoc logger.Loc,\n\tnameRef ast.Ref, argRef ast.Ref, stmtsInsideClosure []js_ast.Stmt,\n) []js_ast.Stmt {\n\t// Follow the link chain in case symbols were merged\n\tsymbol := p.symbols[nameRef.InnerIndex]\n\tfor symbol.Link != ast.InvalidRef {\n\t\tnameRef = symbol.Link\n\t\tsymbol = p.symbols[nameRef.InnerIndex]\n\t}\n\n\t// Make sure to only emit a variable once for a given namespace, since there\n\t// can be multiple namespace blocks for the same namespace\n\tif (symbol.Kind == ast.SymbolTSNamespace || symbol.Kind == ast.SymbolTSEnum) && !p.emittedNamespaceVars[nameRef] {\n\t\tdecls := []js_ast.Decl{{Binding: js_ast.Binding{Loc: nameLoc, Data: &js_ast.BIdentifier{Ref: nameRef}}}}\n\t\tp.emittedNamespaceVars[nameRef] = true\n\t\tif p.currentScope == p.moduleScope {\n\t\t\t// Top-level namespace: \"var\"\n\t\t\tstmts = append(stmts, js_ast.Stmt{Loc: stmtLoc, Data: &js_ast.SLocal{\n\t\t\t\tKind:     js_ast.LocalVar,\n\t\t\t\tDecls:    decls,\n\t\t\t\tIsExport: isExport,\n\t\t\t}})\n\t\t} else {\n\t\t\t// Nested namespace: \"let\"\n\t\t\tstmts = append(stmts, js_ast.Stmt{Loc: stmtLoc, Data: &js_ast.SLocal{\n\t\t\t\tKind:  js_ast.LocalLet,\n\t\t\t\tDecls: decls,\n\t\t\t}})\n\t\t}\n\t}\n\n\tvar argExpr js_ast.Expr\n\tif p.options.minifySyntax && !p.options.unsupportedJSFeatures.Has(compat.LogicalAssignment) {\n\t\t// If the \"||=\" operator is supported, our minified output can be slightly smaller\n\t\tif isExport && p.enclosingNamespaceArgRef != nil {\n\t\t\t// \"name = (enclosing.name ||= {})\"\n\t\t\targExpr = js_ast.Assign(\n\t\t\t\tjs_ast.Expr{Loc: nameLoc, Data: &js_ast.EIdentifier{Ref: nameRef}},\n\t\t\t\tjs_ast.Expr{Loc: nameLoc, Data: &js_ast.EBinary{\n\t\t\t\t\tOp: js_ast.BinOpLogicalOrAssign,\n\t\t\t\t\tLeft: js_ast.Expr{Loc: nameLoc, Data: p.dotOrMangledPropVisit(\n\t\t\t\t\t\tjs_ast.Expr{Loc: nameLoc, Data: &js_ast.EIdentifier{Ref: *p.enclosingNamespaceArgRef}},\n\t\t\t\t\t\tp.symbols[nameRef.InnerIndex].OriginalName,\n\t\t\t\t\t\tnameLoc,\n\t\t\t\t\t)},\n\t\t\t\t\tRight: js_ast.Expr{Loc: nameLoc, Data: &js_ast.EObject{}},\n\t\t\t\t}},\n\t\t\t)\n\t\t\tp.recordUsage(*p.enclosingNamespaceArgRef)\n\t\t\tp.recordUsage(nameRef)\n\t\t} else {\n\t\t\t// \"name ||= {}\"\n\t\t\targExpr = js_ast.Expr{Loc: nameLoc, Data: &js_ast.EBinary{\n\t\t\t\tOp:    js_ast.BinOpLogicalOrAssign,\n\t\t\t\tLeft:  js_ast.Expr{Loc: nameLoc, Data: &js_ast.EIdentifier{Ref: nameRef}},\n\t\t\t\tRight: js_ast.Expr{Loc: nameLoc, Data: &js_ast.EObject{}},\n\t\t\t}}\n\t\t\tp.recordUsage(nameRef)\n\t\t}\n\t} else {\n\t\tif isExport && p.enclosingNamespaceArgRef != nil {\n\t\t\t// \"name = enclosing.name || (enclosing.name = {})\"\n\t\t\tname := p.symbols[nameRef.InnerIndex].OriginalName\n\t\t\targExpr = js_ast.Assign(\n\t\t\t\tjs_ast.Expr{Loc: nameLoc, Data: &js_ast.EIdentifier{Ref: nameRef}},\n\t\t\t\tjs_ast.Expr{Loc: nameLoc, Data: &js_ast.EBinary{\n\t\t\t\t\tOp: js_ast.BinOpLogicalOr,\n\t\t\t\t\tLeft: js_ast.Expr{Loc: nameLoc, Data: p.dotOrMangledPropVisit(\n\t\t\t\t\t\tjs_ast.Expr{Loc: nameLoc, Data: &js_ast.EIdentifier{Ref: *p.enclosingNamespaceArgRef}},\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tnameLoc,\n\t\t\t\t\t)},\n\t\t\t\t\tRight: js_ast.Assign(\n\t\t\t\t\t\tjs_ast.Expr{Loc: nameLoc, Data: p.dotOrMangledPropVisit(\n\t\t\t\t\t\t\tjs_ast.Expr{Loc: nameLoc, Data: &js_ast.EIdentifier{Ref: *p.enclosingNamespaceArgRef}},\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\tnameLoc,\n\t\t\t\t\t\t)},\n\t\t\t\t\t\tjs_ast.Expr{Loc: nameLoc, Data: &js_ast.EObject{}},\n\t\t\t\t\t),\n\t\t\t\t}},\n\t\t\t)\n\t\t\tp.recordUsage(*p.enclosingNamespaceArgRef)\n\t\t\tp.recordUsage(*p.enclosingNamespaceArgRef)\n\t\t\tp.recordUsage(nameRef)\n\t\t} else {\n\t\t\t// \"name || (name = {})\"\n\t\t\targExpr = js_ast.Expr{Loc: nameLoc, Data: &js_ast.EBinary{\n\t\t\t\tOp:   js_ast.BinOpLogicalOr,\n\t\t\t\tLeft: js_ast.Expr{Loc: nameLoc, Data: &js_ast.EIdentifier{Ref: nameRef}},\n\t\t\t\tRight: js_ast.Assign(\n\t\t\t\t\tjs_ast.Expr{Loc: nameLoc, Data: &js_ast.EIdentifier{Ref: nameRef}},\n\t\t\t\t\tjs_ast.Expr{Loc: nameLoc, Data: &js_ast.EObject{}},\n\t\t\t\t),\n\t\t\t}}\n\t\t\tp.recordUsage(nameRef)\n\t\t\tp.recordUsage(nameRef)\n\t\t}\n\t}\n\n\t// Try to use an arrow function if possible for compactness\n\tvar targetExpr js_ast.Expr\n\targs := []js_ast.Arg{{Binding: js_ast.Binding{Loc: nameLoc, Data: &js_ast.BIdentifier{Ref: argRef}}}}\n\tif p.options.unsupportedJSFeatures.Has(compat.Arrow) {\n\t\ttargetExpr = js_ast.Expr{Loc: stmtLoc, Data: &js_ast.EFunction{Fn: js_ast.Fn{\n\t\t\tArgs: args,\n\t\t\tBody: js_ast.FnBody{Loc: stmtLoc, Block: js_ast.SBlock{Stmts: stmtsInsideClosure}},\n\t\t}}}\n\t} else {\n\t\t// \"(() => { foo() })()\" => \"(() => foo())()\"\n\t\tif p.options.minifySyntax && len(stmtsInsideClosure) == 1 {\n\t\t\tif expr, ok := stmtsInsideClosure[0].Data.(*js_ast.SExpr); ok {\n\t\t\t\tstmtsInsideClosure[0].Data = &js_ast.SReturn{ValueOrNil: expr.Value}\n\t\t\t}\n\t\t}\n\t\ttargetExpr = js_ast.Expr{Loc: stmtLoc, Data: &js_ast.EArrow{\n\t\t\tArgs:       args,\n\t\t\tBody:       js_ast.FnBody{Loc: stmtLoc, Block: js_ast.SBlock{Stmts: stmtsInsideClosure}},\n\t\t\tPreferExpr: true,\n\t\t}}\n\t}\n\n\t// Call the closure with the name object\n\tstmts = append(stmts, js_ast.Stmt{Loc: stmtLoc, Data: &js_ast.SExpr{Value: js_ast.Expr{Loc: stmtLoc, Data: &js_ast.ECall{\n\t\tTarget: targetExpr,\n\t\tArgs:   []js_ast.Expr{argExpr},\n\t}}}})\n\n\treturn stmts\n}\n\nfunc (p *parser) generateClosureForTypeScriptEnum(\n\tstmts []js_ast.Stmt, stmtLoc logger.Loc, isExport bool, nameLoc logger.Loc,\n\tnameRef ast.Ref, argRef ast.Ref, exprsInsideClosure []js_ast.Expr,\n\tallValuesArePure bool,\n) []js_ast.Stmt {\n\t// Bail back to the namespace code for enums that aren't at the top level.\n\t// Doing this for nested enums is problematic for two reasons. First of all\n\t// enums inside of namespaces must be property accesses off the namespace\n\t// object instead of variable declarations. Also we'd need to use \"let\"\n\t// instead of \"var\" which doesn't allow sibling declarations to be merged.\n\tif p.currentScope != p.moduleScope {\n\t\tstmtsInsideClosure := []js_ast.Stmt{}\n\t\tif len(exprsInsideClosure) > 0 {\n\t\t\tif p.options.minifySyntax {\n\t\t\t\t// \"a; b; c;\" => \"a, b, c;\"\n\t\t\t\tjoined := js_ast.JoinAllWithComma(exprsInsideClosure)\n\t\t\t\tstmtsInsideClosure = append(stmtsInsideClosure, js_ast.Stmt{Loc: joined.Loc, Data: &js_ast.SExpr{Value: joined}})\n\t\t\t} else {\n\t\t\t\tfor _, expr := range exprsInsideClosure {\n\t\t\t\t\tstmtsInsideClosure = append(stmtsInsideClosure, js_ast.Stmt{Loc: expr.Loc, Data: &js_ast.SExpr{Value: expr}})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn p.generateClosureForTypeScriptNamespaceOrEnum(\n\t\t\tstmts, stmtLoc, isExport, nameLoc, nameRef, argRef, stmtsInsideClosure)\n\t}\n\n\t// This uses an output format for enums that's different but equivalent to\n\t// what TypeScript uses. Here is TypeScript's output:\n\t//\n\t//   var x;\n\t//   (function (x) {\n\t//     x[x[\"y\"] = 1] = \"y\";\n\t//   })(x || (x = {}));\n\t//\n\t// And here's our output:\n\t//\n\t//   var x = /* @__PURE__ */ ((x) => {\n\t//     x[x[\"y\"] = 1] = \"y\";\n\t//     return x;\n\t//   })(x || {});\n\t//\n\t// One benefit is that the minified output is smaller:\n\t//\n\t//   // Old output minified\n\t//   var x;(function(n){n[n.y=1]=\"y\"})(x||(x={}));\n\t//\n\t//   // New output minified\n\t//   var x=(r=>(r[r.y=1]=\"y\",r))(x||{});\n\t//\n\t// Another benefit is that the @__PURE__ annotation means it automatically\n\t// works with tree-shaking, even with more advanced features such as sibling\n\t// enum declarations and enum/namespace merges. Ideally all uses of the enum\n\t// are just direct references to enum members (and are therefore inlined as\n\t// long as the enum value is a constant) and the enum definition itself is\n\t// unused and can be removed as dead code.\n\n\t// Follow the link chain in case symbols were merged\n\tsymbol := p.symbols[nameRef.InnerIndex]\n\tfor symbol.Link != ast.InvalidRef {\n\t\tnameRef = symbol.Link\n\t\tsymbol = p.symbols[nameRef.InnerIndex]\n\t}\n\n\t// Generate the body of the closure, including a return statement at the end\n\tstmtsInsideClosure := []js_ast.Stmt{}\n\targExpr := js_ast.Expr{Loc: nameLoc, Data: &js_ast.EIdentifier{Ref: argRef}}\n\tif p.options.minifySyntax {\n\t\t// \"a; b; return c;\" => \"return a, b, c;\"\n\t\tjoined := js_ast.JoinAllWithComma(exprsInsideClosure)\n\t\tjoined = js_ast.JoinWithComma(joined, argExpr)\n\t\tstmtsInsideClosure = append(stmtsInsideClosure, js_ast.Stmt{Loc: joined.Loc, Data: &js_ast.SReturn{ValueOrNil: joined}})\n\t} else {\n\t\tfor _, expr := range exprsInsideClosure {\n\t\t\tstmtsInsideClosure = append(stmtsInsideClosure, js_ast.Stmt{Loc: expr.Loc, Data: &js_ast.SExpr{Value: expr}})\n\t\t}\n\t\tstmtsInsideClosure = append(stmtsInsideClosure, js_ast.Stmt{Loc: argExpr.Loc, Data: &js_ast.SReturn{ValueOrNil: argExpr}})\n\t}\n\n\t// Try to use an arrow function if possible for compactness\n\tvar targetExpr js_ast.Expr\n\targs := []js_ast.Arg{{Binding: js_ast.Binding{Loc: nameLoc, Data: &js_ast.BIdentifier{Ref: argRef}}}}\n\tif p.options.unsupportedJSFeatures.Has(compat.Arrow) {\n\t\ttargetExpr = js_ast.Expr{Loc: stmtLoc, Data: &js_ast.EFunction{Fn: js_ast.Fn{\n\t\t\tArgs: args,\n\t\t\tBody: js_ast.FnBody{Loc: stmtLoc, Block: js_ast.SBlock{Stmts: stmtsInsideClosure}},\n\t\t}}}\n\t} else {\n\t\ttargetExpr = js_ast.Expr{Loc: stmtLoc, Data: &js_ast.EArrow{\n\t\t\tArgs:       args,\n\t\t\tBody:       js_ast.FnBody{Loc: stmtLoc, Block: js_ast.SBlock{Stmts: stmtsInsideClosure}},\n\t\t\tPreferExpr: p.options.minifySyntax,\n\t\t}}\n\t}\n\n\t// Call the closure with the name object and store it to the variable\n\tdecls := []js_ast.Decl{{\n\t\tBinding: js_ast.Binding{Loc: nameLoc, Data: &js_ast.BIdentifier{Ref: nameRef}},\n\t\tValueOrNil: js_ast.Expr{Loc: stmtLoc, Data: &js_ast.ECall{\n\t\t\tTarget: targetExpr,\n\t\t\tArgs: []js_ast.Expr{{Loc: nameLoc, Data: &js_ast.EBinary{\n\t\t\t\tOp:    js_ast.BinOpLogicalOr,\n\t\t\t\tLeft:  js_ast.Expr{Loc: nameLoc, Data: &js_ast.EIdentifier{Ref: nameRef}},\n\t\t\t\tRight: js_ast.Expr{Loc: nameLoc, Data: &js_ast.EObject{}},\n\t\t\t}}},\n\t\t\tCanBeUnwrappedIfUnused: allValuesArePure,\n\t\t}},\n\t}}\n\tp.recordUsage(nameRef)\n\n\t// Use a \"var\" statement since this is a top-level enum, but only use \"export\" once\n\tstmts = append(stmts, js_ast.Stmt{Loc: stmtLoc, Data: &js_ast.SLocal{\n\t\tKind:     js_ast.LocalVar,\n\t\tDecls:    decls,\n\t\tIsExport: isExport && !p.emittedNamespaceVars[nameRef],\n\t}})\n\tp.emittedNamespaceVars[nameRef] = true\n\n\treturn stmts\n}\n\nfunc (p *parser) wrapInlinedEnum(value js_ast.Expr, comment string) js_ast.Expr {\n\tif strings.Contains(comment, \"*/\") {\n\t\t// Don't wrap with a comment\n\t\treturn value\n\t}\n\n\t// Wrap with a comment\n\treturn js_ast.Expr{Loc: value.Loc, Data: &js_ast.EInlinedEnum{\n\t\tValue:   value,\n\t\tComment: comment,\n\t}}\n}\n"
  },
  {
    "path": "internal/js_parser/ts_parser_test.go",
    "content": "package js_parser\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n)\n\nfunc expectParseErrorTS(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectParseErrorCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse: true,\n\t\t},\n\t})\n}\n\nfunc expectParseErrorExperimentalDecoratorTS(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectParseErrorCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse: true,\n\t\t\tConfig: config.TSConfig{\n\t\t\t\tExperimentalDecorators: config.True,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc expectPrintedWithUnsupportedFeaturesTS(t *testing.T, unsupportedJSFeatures compat.JSFeature, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse: true,\n\t\t},\n\t\tUnsupportedJSFeatures: unsupportedJSFeatures,\n\t})\n}\n\nfunc expectParseErrorTargetTS(t *testing.T, esVersion int, contents string, expected string) {\n\tt.Helper()\n\texpectParseErrorCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse: true,\n\t\t},\n\t\tUnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{\n\t\t\tcompat.ES: {Parts: []int{esVersion}},\n\t\t}),\n\t})\n}\n\nfunc expectPrintedTS(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse: true,\n\t\t},\n\t})\n}\n\nfunc expectPrintedAssignSemanticsTS(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse: true,\n\t\t\tConfig: config.TSConfig{\n\t\t\t\tUseDefineForClassFields: config.False,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc expectPrintedAssignSemanticsTargetTS(t *testing.T, esVersion int, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse: true,\n\t\t\tConfig: config.TSConfig{\n\t\t\t\tUseDefineForClassFields: config.False,\n\t\t\t},\n\t\t},\n\t\tUnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{\n\t\t\tcompat.ES: {Parts: []int{esVersion}},\n\t\t}),\n\t})\n}\n\nfunc expectPrintedExperimentalDecoratorTS(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse: true,\n\t\t\tConfig: config.TSConfig{\n\t\t\t\tExperimentalDecorators: config.True,\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunc expectPrintedMangleTS(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse: true,\n\t\t},\n\t\tMinifySyntax: true,\n\t})\n}\n\nfunc expectPrintedMangleAssignSemanticsTS(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse: true,\n\t\t\tConfig: config.TSConfig{\n\t\t\t\tUseDefineForClassFields: config.False,\n\t\t\t},\n\t\t},\n\t\tMinifySyntax: true,\n\t})\n}\n\nfunc expectPrintedTargetTS(t *testing.T, esVersion int, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse: true,\n\t\t},\n\t\tUnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{\n\t\t\tcompat.ES: {Parts: []int{esVersion}},\n\t\t}),\n\t})\n}\n\nfunc expectPrintedTargetExperimentalDecoratorTS(t *testing.T, esVersion int, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse: true,\n\t\t\tConfig: config.TSConfig{\n\t\t\t\tExperimentalDecorators: config.True,\n\t\t\t},\n\t\t},\n\t\tUnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{\n\t\t\tcompat.ES: {Parts: []int{esVersion}},\n\t\t}),\n\t})\n}\n\nfunc expectParseErrorTSNoAmbiguousLessThan(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectParseErrorCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse:               true,\n\t\t\tNoAmbiguousLessThan: true,\n\t\t},\n\t})\n}\n\nfunc expectPrintedTSNoAmbiguousLessThan(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse:               true,\n\t\t\tNoAmbiguousLessThan: true,\n\t\t},\n\t})\n}\n\nfunc expectParseErrorTSX(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectParseErrorCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse: true,\n\t\t},\n\t\tJSX: config.JSXOptions{\n\t\t\tParse: true,\n\t\t},\n\t})\n}\n\nfunc expectPrintedTSX(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, expected, config.Options{\n\t\tTS: config.TSOptions{\n\t\t\tParse: true,\n\t\t},\n\t\tJSX: config.JSXOptions{\n\t\t\tParse: true,\n\t\t},\n\t})\n}\n\nfunc TestTSTypes(t *testing.T) {\n\texpectPrintedTS(t, \"let x: T extends number\\n ? T\\n : number\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: {y: T extends number ? T : number}\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: {y: T \\n extends: number}\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: {y: T \\n extends?: number}\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: (number | string)[]\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: [string[]?]\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: [number?, string?]\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: [a: number, b?: string, ...c: number[]]\", \"let x;\\n\")\n\texpectPrintedTS(t, \"type x =\\n A\\n | B\\n C\", \"C;\\n\")\n\texpectPrintedTS(t, \"type x =\\n | A\\n | B\\n C\", \"C;\\n\")\n\texpectPrintedTS(t, \"type x =\\n A\\n & B\\n C\", \"C;\\n\")\n\texpectPrintedTS(t, \"type x =\\n & A\\n & B\\n C\", \"C;\\n\")\n\texpectPrintedTS(t, \"type x = [-1, 0, 1]\\n[]\", \"[];\\n\")\n\texpectPrintedTS(t, \"type x = [-1n, 0n, 1n]\\n[]\", \"[];\\n\")\n\texpectPrintedTS(t, \"type x = {0: number, readonly 1: boolean}\\n[]\", \"[];\\n\")\n\texpectPrintedTS(t, \"type x = {'a': number, readonly 'b': boolean}\\n[]\", \"[];\\n\")\n\texpectPrintedTS(t, \"type\\nFoo = {}\", \"type;\\nFoo = {};\\n\")\n\texpectPrintedTS(t, \"export type\\n{ Foo } \\n x\", \"x;\\n\")\n\texpectPrintedTS(t, \"export type\\n* from 'foo' \\n x\", \"x;\\n\")\n\texpectPrintedTS(t, \"export type\\n* as ns from 'foo' \\n x\", \"x;\\n\")\n\texpectParseErrorTS(t, \"export type\\nFoo = {}\", \"<stdin>: ERROR: Unexpected newline after \\\"type\\\"\\n\")\n\texpectPrintedTS(t, \"let x: {x: 'a', y: false, z: null}\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: {foo(): void}\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: {['x']: number}\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: {['x'](): void}\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: {[key: string]: number}\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: {[keyof: string]: number}\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: {[readonly: string]: number}\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: {[infer: string]: number}\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: [keyof: string]\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: [readonly: string]\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: [infer: string]\", \"let x;\\n\")\n\texpectParseErrorTS(t, \"let x: A extends B ? keyof : string\", \"<stdin>: ERROR: Unexpected \\\":\\\"\\n\")\n\texpectParseErrorTS(t, \"let x: A extends B ? readonly : string\", \"<stdin>: ERROR: Unexpected \\\":\\\"\\n\")\n\texpectParseErrorTS(t, \"let x: A extends B ? infer : string\", \"<stdin>: ERROR: Expected identifier but found \\\":\\\"\\n\")\n\texpectParseErrorTS(t, \"let x: {[new: string]: number}\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\":\\\"\\n\")\n\texpectParseErrorTS(t, \"let x: {[import: string]: number}\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\":\\\"\\n\")\n\texpectParseErrorTS(t, \"let x: {[typeof: string]: number}\", \"<stdin>: ERROR: Expected identifier but found \\\":\\\"\\n\")\n\texpectPrintedTS(t, \"let x: () => void = Foo\", \"let x = Foo;\\n\")\n\texpectPrintedTS(t, \"let x: new () => void = Foo\", \"let x = Foo;\\n\")\n\texpectPrintedTS(t, \"let x = 'x' as keyof T\", \"let x = \\\"x\\\";\\n\")\n\texpectPrintedTS(t, \"let x = [1] as readonly [number]\", \"let x = [1];\\n\")\n\texpectPrintedTS(t, \"let x = 'x' as keyof typeof Foo\", \"let x = \\\"x\\\";\\n\")\n\texpectPrintedTS(t, \"let fs: typeof import('fs') = require('fs')\", \"let fs = require(\\\"fs\\\");\\n\")\n\texpectPrintedTS(t, \"let fs: typeof import('fs').exists = require('fs').exists\", \"let fs = require(\\\"fs\\\").exists;\\n\")\n\texpectPrintedTS(t, \"let fs: typeof import('fs', { assert: { type: 'json' } }) = require('fs')\", \"let fs = require(\\\"fs\\\");\\n\")\n\texpectPrintedTS(t, \"let fs: typeof import('fs', { assert: { 'resolution-mode': 'import' } }) = require('fs')\", \"let fs = require(\\\"fs\\\");\\n\")\n\texpectPrintedTS(t, \"let x: <T>() => Foo<T>\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: new <T>() => Foo<T>\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: <T extends object>() => Foo<T>\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: new <T extends object>() => Foo<T>\", \"let x;\\n\")\n\texpectPrintedTS(t, \"type Foo<T> = {[P in keyof T]?: T[P]}\", \"\")\n\texpectPrintedTS(t, \"type Foo<T> = {[P in keyof T]+?: T[P]}\", \"\")\n\texpectPrintedTS(t, \"type Foo<T> = {[P in keyof T]-?: T[P]}\", \"\")\n\texpectPrintedTS(t, \"type Foo<T> = {readonly [P in keyof T]: T[P]}\", \"\")\n\texpectPrintedTS(t, \"type Foo<T> = {-readonly [P in keyof T]: T[P]}\", \"\")\n\texpectPrintedTS(t, \"type Foo<T> = {+readonly [P in keyof T]: T[P]}\", \"\")\n\texpectPrintedTS(t, \"type Foo<T> = {[infer in T]?: Foo}\", \"\")\n\texpectPrintedTS(t, \"type Foo<T> = {[keyof in T]?: Foo}\", \"\")\n\texpectPrintedTS(t, \"type Foo<T> = {[asserts in T]?: Foo}\", \"\")\n\texpectPrintedTS(t, \"type Foo<T> = {[abstract in T]?: Foo}\", \"\")\n\texpectPrintedTS(t, \"type Foo<T> = {[readonly in T]?: Foo}\", \"\")\n\texpectPrintedTS(t, \"type Foo<T> = {[satisfies in T]?: Foo}\", \"\")\n\texpectPrintedTS(t, \"let x: number! = y\", \"let x = y;\\n\")\n\texpectPrintedTS(t, \"let x: number \\n !y\", \"let x;\\n!y;\\n\")\n\texpectPrintedTS(t, \"const x: unique = y\", \"const x = y;\\n\")\n\texpectPrintedTS(t, \"const x: unique<T> = y\", \"const x = y;\\n\")\n\texpectPrintedTS(t, \"const x: unique\\nsymbol = y\", \"const x = y;\\n\")\n\texpectPrintedTS(t, \"let x: typeof a = y\", \"let x = y;\\n\")\n\texpectPrintedTS(t, \"let x: typeof a.b = y\", \"let x = y;\\n\")\n\texpectPrintedTS(t, \"let x: typeof a.if = y\", \"let x = y;\\n\")\n\texpectPrintedTS(t, \"let x: typeof if.a = y\", \"let x = y;\\n\")\n\texpectPrintedTS(t, \"let x: typeof readonly = y\", \"let x = y;\\n\")\n\texpectParseErrorTS(t, \"let x: typeof readonly Array\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"Array\\\"\\n\")\n\texpectPrintedTS(t, \"let x: `y`\", \"let x;\\n\")\n\texpectParseErrorTS(t, \"let x: tag`y`\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"`y`\\\"\\n\")\n\texpectPrintedTS(t, \"let x: { <A extends B>(): c.d \\n <E extends F>(): g.h }\", \"let x;\\n\")\n\texpectPrintedTSX(t, \"type x = a.b \\n <c></c>\", \"/* @__PURE__ */ React.createElement(\\\"c\\\", null);\\n\")\n\texpectPrintedTS(t, \"type Foo = a.b \\n | c.d\", \"\")\n\texpectPrintedTS(t, \"type Foo = a.b \\n & c.d\", \"\")\n\texpectPrintedTS(t, \"type Foo = \\n | a.b \\n | c.d\", \"\")\n\texpectPrintedTS(t, \"type Foo = \\n & a.b \\n & c.d\", \"\")\n\texpectPrintedTS(t, \"type Foo = Bar extends [infer T] ? T : null\", \"\")\n\texpectPrintedTS(t, \"type Foo = Bar extends [infer T extends string] ? T : null\", \"\")\n\texpectPrintedTS(t, \"type Foo = {} extends infer T extends {} ? A<T> : never\", \"\")\n\texpectPrintedTS(t, \"type Foo = {} extends (infer T extends {}) ? A<T> : never\", \"\")\n\texpectPrintedTS(t, \"type Foo<T> = T extends { a: infer U extends number } | { b: infer U extends number } ? U : never\", \"\")\n\texpectPrintedTS(t, \"type Foo<T> = T extends { a: infer U extends number } & { b: infer U extends number } ? U : never\", \"\")\n\texpectPrintedTS(t, \"type Foo<T> = T extends { a: infer U extends number } | infer U extends number ? U : never\", \"\")\n\texpectPrintedTS(t, \"type Foo<T> = T extends { a: infer U extends number } & infer U extends number ? U : never\", \"\")\n\texpectPrintedTS(t, \"let x: A extends B<infer C extends D> ? D : never\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: A extends B<infer C extends D ? infer C : never> ? D : never\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: ([e1, e2, ...es]: any) => any\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: (...[e1, e2, es]: any) => any\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: (...[e1, e2, ...es]: any) => any\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: (y, [e1, e2, ...es]: any) => any\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: (y, ...[e1, e2, es]: any) => any\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: (y, ...[e1, e2, ...es]: any) => any\", \"let x;\\n\")\n\n\texpectPrintedTS(t, \"let x: A.B<X.Y>\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: A.B<X.Y>=2\", \"let x = 2;\\n\")\n\texpectPrintedTS(t, \"let x: A.B<X.Y<Z>>\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: A.B<X.Y<Z>>=2\", \"let x = 2;\\n\")\n\texpectPrintedTS(t, \"let x: A.B<X.Y<Z<T>>>\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: A.B<X.Y<Z<T>>>=2\", \"let x = 2;\\n\")\n\n\texpectPrintedTS(t, \"(): A<T>=> 0\", \"() => 0;\\n\")\n\texpectPrintedTS(t, \"(): A<B<T>>=> 0\", \"() => 0;\\n\")\n\texpectPrintedTS(t, \"(): A<B<C<T>>>=> 0\", \"() => 0;\\n\")\n\n\texpectPrintedTS(t, \"let foo: any\\n<x>y\", \"let foo;\\ny;\\n\")\n\texpectPrintedTSX(t, \"let foo: any\\n<x>y</x>\", \"let foo;\\n/* @__PURE__ */ React.createElement(\\\"x\\\", null, \\\"y\\\");\\n\")\n\texpectParseErrorTS(t, \"let foo: (any\\n<x>y)\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"<\\\"\\n\")\n\n\texpectPrintedTS(t, \"let foo = bar as (null)\", \"let foo = bar;\\n\")\n\texpectPrintedTS(t, \"let foo = bar\\nas (null)\", \"let foo = bar;\\nas(null);\\n\")\n\texpectParseErrorTS(t, \"let foo = (bar\\nas (null))\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"as\\\"\\n\")\n\n\texpectPrintedTS(t, \"a as any ? b : c;\", \"a ? b : c;\\n\")\n\texpectPrintedTS(t, \"a as any ? async () => b : c;\", \"a ? async () => b : c;\\n\")\n\texpectPrintedTS(t, \"foo as number extends Object ? any : any;\", \"foo;\\n\")\n\texpectPrintedTS(t, \"foo as number extends Object ? () => void : any;\", \"foo;\\n\")\n\texpectPrintedTS(t, \"let a = b ? c : d as T extends T ? T extends T ? T : never : never ? e : f;\", \"let a = b ? c : d ? e : f;\\n\")\n\texpectParseErrorTS(t, \"type a = b extends c\", \"<stdin>: ERROR: Expected \\\"?\\\" but found end of file\\n\")\n\texpectParseErrorTS(t, \"type a = b extends c extends d\", \"<stdin>: ERROR: Expected \\\"?\\\" but found \\\"extends\\\"\\n\")\n\texpectParseErrorTS(t, \"type a = b ? c : d\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"?\\\"\\n\")\n\n\texpectPrintedTS(t, \"let foo: keyof Object = 'toString'\", \"let foo = \\\"toString\\\";\\n\")\n\texpectPrintedTS(t, \"let foo: keyof\\nObject = 'toString'\", \"let foo = \\\"toString\\\";\\n\")\n\texpectPrintedTS(t, \"let foo: (keyof\\nObject) = 'toString'\", \"let foo = \\\"toString\\\";\\n\")\n\n\texpectPrintedTS(t, \"type Foo = Array<<T>(x: T) => T>\\n x\", \"x;\\n\")\n\texpectPrintedTSX(t, \"<Foo<<T>(x: T) => T>/>\", \"/* @__PURE__ */ React.createElement(Foo, null);\\n\")\n\n\texpectPrintedTS(t, \"interface Foo<> {}\", \"\")\n\texpectPrintedTSX(t, \"interface Foo<> {}\", \"\")\n\texpectPrintedTS(t, \"type Foo<> = {}\", \"\")\n\texpectPrintedTSX(t, \"type Foo<> = {}\", \"\")\n\texpectParseErrorTS(t, \"class Foo<> {}\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTSX(t, \"class Foo<> {}\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { foo<>() {} }\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTSX(t, \"class Foo { foo<>() {} }\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"type Foo = { foo<>(): void }\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTSX(t, \"type Foo = { foo<>(): void }\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"type Foo = <>() => {}\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTSX(t, \"type Foo = <>() => {}\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"let Foo = <>() => {}\", \"<stdin>: ERROR: Unexpected \\\">\\\"\\n\")\n\texpectParseErrorTSX(t, \"let Foo = <>() => {}\",\n\t\t\"<stdin>: ERROR: The character \\\">\\\" is not valid inside a JSX element\\nNOTE: Did you mean to escape it as \\\"{'>'}\\\" instead?\\n\"+\n\t\t\t\"<stdin>: ERROR: Unexpected end of file before a closing fragment tag\\n<stdin>: NOTE: The opening fragment tag is here:\\n\")\n\n\t// Certain built-in types do not accept type parameters\n\texpectPrintedTS(t, \"x as 1 < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as 1n < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as -1 < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as -1n < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as '' < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as `` < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as any < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as bigint < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as false < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as never < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as null < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as number < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as object < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as string < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as symbol < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as this < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as true < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as undefined < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as unique symbol < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as unknown < 1\", \"x < 1;\\n\")\n\texpectPrintedTS(t, \"x as void < 1\", \"x < 1;\\n\")\n\texpectParseErrorTS(t, \"x as Foo < 1\", \"<stdin>: ERROR: Expected \\\">\\\" but found end of file\\n\")\n\n\t// These keywords are valid tuple labels\n\texpectPrintedTS(t, \"type _any = [any: string]\", \"\")\n\texpectPrintedTS(t, \"type _asserts = [asserts: string]\", \"\")\n\texpectPrintedTS(t, \"type _bigint = [bigint: string]\", \"\")\n\texpectPrintedTS(t, \"type _boolean = [boolean: string]\", \"\")\n\texpectPrintedTS(t, \"type _false = [false: string]\", \"\")\n\texpectPrintedTS(t, \"type _function = [function: string]\", \"\")\n\texpectPrintedTS(t, \"type _import = [import: string]\", \"\")\n\texpectPrintedTS(t, \"type _infer = [infer: string]\", \"\")\n\texpectPrintedTS(t, \"type _never = [never: string]\", \"\")\n\texpectPrintedTS(t, \"type _new = [new: string]\", \"\")\n\texpectPrintedTS(t, \"type _null = [null: string]\", \"\")\n\texpectPrintedTS(t, \"type _number = [number: string]\", \"\")\n\texpectPrintedTS(t, \"type _object = [object: string]\", \"\")\n\texpectPrintedTS(t, \"type _readonly = [readonly: string]\", \"\")\n\texpectPrintedTS(t, \"type _string = [string: string]\", \"\")\n\texpectPrintedTS(t, \"type _symbol = [symbol: string]\", \"\")\n\texpectPrintedTS(t, \"type _this = [this: string]\", \"\")\n\texpectPrintedTS(t, \"type _true = [true: string]\", \"\")\n\texpectPrintedTS(t, \"type _typeof = [typeof: string]\", \"\")\n\texpectPrintedTS(t, \"type _undefined = [undefined: string]\", \"\")\n\texpectPrintedTS(t, \"type _unique = [unique: string]\", \"\")\n\texpectPrintedTS(t, \"type _unknown = [unknown: string]\", \"\")\n\texpectPrintedTS(t, \"type _void = [void: string]\", \"\")\n\n\t// Also check tuple labels with a question mark\n\texpectPrintedTS(t, \"type _any = [any?: string]\", \"\")\n\texpectPrintedTS(t, \"type _asserts = [asserts?: string]\", \"\")\n\texpectPrintedTS(t, \"type _bigint = [bigint?: string]\", \"\")\n\texpectPrintedTS(t, \"type _boolean = [boolean?: string]\", \"\")\n\texpectPrintedTS(t, \"type _false = [false?: string]\", \"\")\n\texpectPrintedTS(t, \"type _function = [function?: string]\", \"\")\n\texpectPrintedTS(t, \"type _import = [import?: string]\", \"\")\n\texpectPrintedTS(t, \"type _infer = [infer?: string]\", \"\")\n\texpectPrintedTS(t, \"type _never = [never?: string]\", \"\")\n\texpectPrintedTS(t, \"type _new = [new?: string]\", \"\")\n\texpectPrintedTS(t, \"type _null = [null?: string]\", \"\")\n\texpectPrintedTS(t, \"type _number = [number?: string]\", \"\")\n\texpectPrintedTS(t, \"type _object = [object?: string]\", \"\")\n\texpectPrintedTS(t, \"type _readonly = [readonly?: string]\", \"\")\n\texpectPrintedTS(t, \"type _string = [string?: string]\", \"\")\n\texpectPrintedTS(t, \"type _symbol = [symbol?: string]\", \"\")\n\texpectPrintedTS(t, \"type _this = [this?: string]\", \"\")\n\texpectPrintedTS(t, \"type _true = [true?: string]\", \"\")\n\texpectPrintedTS(t, \"type _typeof = [typeof?: string]\", \"\")\n\texpectPrintedTS(t, \"type _undefined = [undefined?: string]\", \"\")\n\texpectPrintedTS(t, \"type _unique = [unique?: string]\", \"\")\n\texpectPrintedTS(t, \"type _unknown = [unknown?: string]\", \"\")\n\texpectPrintedTS(t, \"type _void = [void?: string]\", \"\")\n\n\t// These keywords are invalid tuple labels\n\texpectParseErrorTS(t, \"type _break = [break: string]\", \"<stdin>: ERROR: Unexpected \\\"break\\\"\\n\")\n\texpectParseErrorTS(t, \"type _case = [case: string]\", \"<stdin>: ERROR: Unexpected \\\"case\\\"\\n\")\n\texpectParseErrorTS(t, \"type _catch = [catch: string]\", \"<stdin>: ERROR: Unexpected \\\"catch\\\"\\n\")\n\texpectParseErrorTS(t, \"type _class = [class: string]\", \"<stdin>: ERROR: Unexpected \\\"class\\\"\\n\")\n\texpectParseErrorTS(t, \"type _const = [const: string]\", \"<stdin>: ERROR: Unexpected \\\"const\\\"\\n\")\n\texpectParseErrorTS(t, \"type _continue = [continue: string]\", \"<stdin>: ERROR: Unexpected \\\"continue\\\"\\n\")\n\texpectParseErrorTS(t, \"type _debugger = [debugger: string]\", \"<stdin>: ERROR: Unexpected \\\"debugger\\\"\\n\")\n\texpectParseErrorTS(t, \"type _default = [default: string]\", \"<stdin>: ERROR: Unexpected \\\"default\\\"\\n\")\n\texpectParseErrorTS(t, \"type _delete = [delete: string]\", \"<stdin>: ERROR: Unexpected \\\"delete\\\"\\n\")\n\texpectParseErrorTS(t, \"type _do = [do: string]\", \"<stdin>: ERROR: Unexpected \\\"do\\\"\\n\")\n\texpectParseErrorTS(t, \"type _else = [else: string]\", \"<stdin>: ERROR: Unexpected \\\"else\\\"\\n\")\n\texpectParseErrorTS(t, \"type _enum = [enum: string]\", \"<stdin>: ERROR: Unexpected \\\"enum\\\"\\n\")\n\texpectParseErrorTS(t, \"type _export = [export: string]\", \"<stdin>: ERROR: Unexpected \\\"export\\\"\\n\")\n\texpectParseErrorTS(t, \"type _extends = [extends: string]\", \"<stdin>: ERROR: Unexpected \\\"extends\\\"\\n\")\n\texpectParseErrorTS(t, \"type _finally = [finally: string]\", \"<stdin>: ERROR: Unexpected \\\"finally\\\"\\n\")\n\texpectParseErrorTS(t, \"type _for = [for: string]\", \"<stdin>: ERROR: Unexpected \\\"for\\\"\\n\")\n\texpectParseErrorTS(t, \"type _if = [if: string]\", \"<stdin>: ERROR: Unexpected \\\"if\\\"\\n\")\n\texpectParseErrorTS(t, \"type _in = [in: string]\", \"<stdin>: ERROR: Unexpected \\\"in\\\"\\n\")\n\texpectParseErrorTS(t, \"type _instanceof = [instanceof: string]\", \"<stdin>: ERROR: Unexpected \\\"instanceof\\\"\\n\")\n\texpectParseErrorTS(t, \"type _return = [return: string]\", \"<stdin>: ERROR: Unexpected \\\"return\\\"\\n\")\n\texpectParseErrorTS(t, \"type _super = [super: string]\", \"<stdin>: ERROR: Unexpected \\\"super\\\"\\n\")\n\texpectParseErrorTS(t, \"type _switch = [switch: string]\", \"<stdin>: ERROR: Unexpected \\\"switch\\\"\\n\")\n\texpectParseErrorTS(t, \"type _throw = [throw: string]\", \"<stdin>: ERROR: Unexpected \\\"throw\\\"\\n\")\n\texpectParseErrorTS(t, \"type _try = [try: string]\", \"<stdin>: ERROR: Unexpected \\\"try\\\"\\n\")\n\texpectParseErrorTS(t, \"type _var = [var: string]\", \"<stdin>: ERROR: Unexpected \\\"var\\\"\\n\")\n\texpectParseErrorTS(t, \"type _while = [while: string]\", \"<stdin>: ERROR: Unexpected \\\"while\\\"\\n\")\n\texpectParseErrorTS(t, \"type _with = [with: string]\", \"<stdin>: ERROR: Unexpected \\\"with\\\"\\n\")\n\n\t// TypeScript 4.1\n\texpectPrintedTS(t, \"let foo: `${'a' | 'b'}-${'c' | 'd'}` = 'a-c'\", \"let foo = \\\"a-c\\\";\\n\")\n\n\t// TypeScript 4.2\n\texpectPrintedTS(t, \"let x: abstract new () => void = Foo\", \"let x = Foo;\\n\")\n\texpectPrintedTS(t, \"let x: abstract new <T>() => Foo<T>\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: abstract new <T extends object>() => Foo<T>\", \"let x;\\n\")\n\texpectParseErrorTS(t, \"let x: abstract () => void = Foo\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseErrorTS(t, \"let x: abstract <T>() => Foo<T>\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseErrorTS(t, \"let x: abstract <T extends object>() => Foo<T>\", \"<stdin>: ERROR: Expected \\\"?\\\" but found \\\">\\\"\\n\")\n\n\t// TypeScript 4.7\n\tjsxErrorArrow := \"<stdin>: ERROR: The character \\\">\\\" is not valid inside a JSX element\\n\" +\n\t\t\"NOTE: Did you mean to escape it as \\\"{'>'}\\\" instead?\\n\"\n\texpectPrintedTS(t, \"type Foo<in T> = T\", \"\")\n\texpectPrintedTS(t, \"type Foo<out T> = T\", \"\")\n\texpectPrintedTS(t, \"type Foo<in out> = T\", \"\")\n\texpectPrintedTS(t, \"type Foo<out out> = T\", \"\")\n\texpectPrintedTS(t, \"type Foo<in out out> = T\", \"\")\n\texpectPrintedTS(t, \"type Foo<in X, out Y> = [X, Y]\", \"\")\n\texpectPrintedTS(t, \"type Foo<out X, in Y> = [X, Y]\", \"\")\n\texpectPrintedTS(t, \"type Foo<out X, out Y extends keyof X> = [X, Y]\", \"\")\n\texpectParseErrorTS(t, \"type Foo<i\\\\u006E T> = T\", \"<stdin>: ERROR: Expected identifier but found \\\"i\\\\\\\\u006E\\\"\\n\")\n\texpectParseErrorTS(t, \"type Foo<ou\\\\u0074 T> = T\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\"T\\\"\\n\")\n\texpectParseErrorTS(t, \"type Foo<in in> = T\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"type Foo<out in> = T\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"type Foo<out in T> = T\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"type Foo<public T> = T\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\"T\\\"\\n\")\n\texpectParseErrorTS(t, \"type Foo<in out in T> = T\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"type Foo<in out out T> = T\", \"<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectPrintedTS(t, \"class Foo<in T> {}\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo<out T> {}\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class Foo<in T> {}\", \"export default class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class Foo<out T> {}\", \"export default class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class <in T> {}\", \"export default class {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class <out T> {}\", \"export default class {\\n}\\n\")\n\texpectPrintedTS(t, \"interface Foo<in T> {}\", \"\")\n\texpectPrintedTS(t, \"interface Foo<out T> {}\", \"\")\n\texpectPrintedTS(t, \"declare class Foo<in T> {}\", \"\")\n\texpectPrintedTS(t, \"declare class Foo<out T> {}\", \"\")\n\texpectPrintedTS(t, \"declare interface Foo<in T> {}\", \"\")\n\texpectPrintedTS(t, \"declare interface Foo<out T> {}\", \"\")\n\texpectParseErrorTS(t, \"function foo<in T>() {}\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"function foo<out T>() {}\", \"<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"export default function foo<in T>() {}\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"export default function foo<out T>() {}\", \"<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"export default function <in T>() {}\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"export default function <out T>() {}\", \"<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"let foo: Foo<in T>\", \"<stdin>: ERROR: Unexpected \\\"in\\\"\\n\")\n\texpectParseErrorTS(t, \"let foo: Foo<out T>\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\"T\\\"\\n\")\n\texpectParseErrorTS(t, \"declare function foo<in T>()\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"declare function foo<out T>()\", \"<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"declare let foo: Foo<in T>\", \"<stdin>: ERROR: Unexpected \\\"in\\\"\\n\")\n\texpectParseErrorTS(t, \"declare let foo: Foo<out T>\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\"T\\\"\\n\")\n\texpectPrintedTS(t, \"Foo = class <in T> {}\", \"Foo = class {\\n};\\n\")\n\texpectPrintedTS(t, \"Foo = class <out T> {}\", \"Foo = class {\\n};\\n\")\n\texpectPrintedTS(t, \"Foo = class Bar<in T> {}\", \"Foo = class Bar {\\n};\\n\")\n\texpectPrintedTS(t, \"Foo = class Bar<out T> {}\", \"Foo = class Bar {\\n};\\n\")\n\texpectParseErrorTS(t, \"foo = function <in T>() {}\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"foo = function <out T>() {}\", \"<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"class Foo { foo<in T>(): T {} }\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"class Foo { foo<out T>(): T {} }\", \"<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"foo = { foo<in T>(): T {} }\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"foo = { foo<out T>(): T {} }\", \"<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"<in T>() => {}\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"<out T>() => {}\", \"<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"<in T, out T>() => {}\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"let x: <in T>() => {}\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"let x: <out T>() => {}\", \"<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"let x: <in T, out T>() => {}\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"let x: new <in T>() => {}\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"let x: new <out T>() => {}\", \"<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"let x: new <in T, out T>() => {}\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"let x: { y<in T>(): any }\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"let x: { y<out T>(): any }\", \"<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"let x: { y<in T, out T>(): any }\", \"<stdin>: ERROR: The modifier \\\"in\\\" is not valid here:\\n<stdin>: ERROR: The modifier \\\"out\\\" is not valid here:\\n\")\n\texpectPrintedTSX(t, \"<in T></in>\", \"/* @__PURE__ */ React.createElement(\\\"in\\\", { T: true });\\n\")\n\texpectPrintedTSX(t, \"<out T></out>\", \"/* @__PURE__ */ React.createElement(\\\"out\\\", { T: true });\\n\")\n\texpectPrintedTSX(t, \"<in out T></in>\", \"/* @__PURE__ */ React.createElement(\\\"in\\\", { out: true, T: true });\\n\")\n\texpectPrintedTSX(t, \"<out in T></out>\", \"/* @__PURE__ */ React.createElement(\\\"out\\\", { in: true, T: true });\\n\")\n\texpectPrintedTSX(t, \"<in T extends={true}></in>\", \"/* @__PURE__ */ React.createElement(\\\"in\\\", { T: true, extends: true });\\n\")\n\texpectPrintedTSX(t, \"<out T extends={true}></out>\", \"/* @__PURE__ */ React.createElement(\\\"out\\\", { T: true, extends: true });\\n\")\n\texpectPrintedTSX(t, \"<in out T extends={true}></in>\", \"/* @__PURE__ */ React.createElement(\\\"in\\\", { out: true, T: true, extends: true });\\n\")\n\texpectParseErrorTSX(t, \"<in T,>() => {}\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\",\\\"\\n\")\n\texpectParseErrorTSX(t, \"<out T,>() => {}\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\",\\\"\\n\")\n\texpectParseErrorTSX(t, \"<in out T,>() => {}\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\",\\\"\\n\")\n\texpectParseErrorTSX(t, \"<in T extends any>() => {}\", jsxErrorArrow+\"<stdin>: ERROR: Unexpected end of file before a closing \\\"in\\\" tag\\n<stdin>: NOTE: The opening \\\"in\\\" tag is here:\\n\")\n\texpectParseErrorTSX(t, \"<out T extends any>() => {}\", jsxErrorArrow+\"<stdin>: ERROR: Unexpected end of file before a closing \\\"out\\\" tag\\n<stdin>: NOTE: The opening \\\"out\\\" tag is here:\\n\")\n\texpectParseErrorTSX(t, \"<in out T extends any>() => {}\", jsxErrorArrow+\"<stdin>: ERROR: Unexpected end of file before a closing \\\"in\\\" tag\\n<stdin>: NOTE: The opening \\\"in\\\" tag is here:\\n\")\n\texpectPrintedTS(t, \"class Container { get data(): typeof this.#data {} }\", \"class Container {\\n  get data() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"const a: typeof this.#a = 1;\", \"const a = 1;\\n\")\n\texpectParseErrorTS(t, \"const a: typeof #a = 1;\", \"<stdin>: ERROR: Expected identifier but found \\\"#a\\\"\\n\")\n\n\t// TypeScript 5.0\n\texpectPrintedTS(t, \"class Foo<const T> {}\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo<const T extends X> {}\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"Foo = class <const T> {}\", \"Foo = class {\\n};\\n\")\n\texpectPrintedTS(t, \"Foo = class Bar<const T> {}\", \"Foo = class Bar {\\n};\\n\")\n\texpectPrintedTS(t, \"function foo<const T>() {}\", \"function foo() {\\n}\\n\")\n\texpectPrintedTS(t, \"foo = function <const T>() {}\", \"foo = function() {\\n};\\n\")\n\texpectPrintedTS(t, \"foo = function bar<const T>() {}\", \"foo = function bar() {\\n};\\n\")\n\texpectPrintedTS(t, \"class Foo { bar<const T>() {} }\", \"class Foo {\\n  bar() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"interface Foo { bar<const T>(): T }\", \"\")\n\texpectPrintedTS(t, \"interface Foo { new bar<const T>(): T }\", \"\")\n\texpectPrintedTS(t, \"let x: { bar<const T>(): T }\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: { new bar<const T>(): T }\", \"let x;\\n\")\n\texpectPrintedTS(t, \"foo = { bar<const T>() {} }\", \"foo = { bar() {\\n} };\\n\")\n\texpectPrintedTS(t, \"x = <const>(y)\", \"x = y;\\n\")\n\texpectPrintedTS(t, \"<const T>() => {}\", \"() => {\\n};\\n\")\n\texpectPrintedTS(t, \"<const const T>() => {}\", \"() => {\\n};\\n\")\n\texpectPrintedTS(t, \"async <const T>() => {}\", \"async () => {\\n};\\n\")\n\texpectPrintedTS(t, \"async <const const T>() => {}\", \"async () => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x: <const T>() => T = y\", \"let x = y;\\n\")\n\texpectPrintedTS(t, \"let x: <const const T>() => T = y\", \"let x = y;\\n\")\n\texpectPrintedTS(t, \"let x: new <const T>() => T = y\", \"let x = y;\\n\")\n\texpectPrintedTS(t, \"let x: new <const const T>() => T = y\", \"let x = y;\\n\")\n\texpectParseErrorTS(t, \"type Foo<const T> = T\", \"<stdin>: ERROR: The modifier \\\"const\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"interface Foo<const T> {}\", \"<stdin>: ERROR: The modifier \\\"const\\\" is not valid here:\\n\")\n\texpectParseErrorTS(t, \"let x: <const>() => {}\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"let x: new <const>() => {}\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"let x: Foo<const T>\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\"T\\\"\\n\")\n\texpectParseErrorTS(t, \"x = <T,>(y)\", \"<stdin>: ERROR: Expected \\\"=>\\\" but found end of file\\n\")\n\texpectParseErrorTS(t, \"x = <const T>(y)\", \"<stdin>: ERROR: Expected \\\"=>\\\" but found end of file\\n\")\n\texpectParseErrorTS(t, \"x = <T extends X>(y)\", \"<stdin>: ERROR: Expected \\\"=>\\\" but found end of file\\n\")\n\texpectParseErrorTS(t, \"x = async <T,>(y)\", \"<stdin>: ERROR: Expected \\\"=>\\\" but found end of file\\n\")\n\texpectParseErrorTS(t, \"x = async <const T>(y)\", \"<stdin>: ERROR: Expected \\\"=>\\\" but found end of file\\n\")\n\texpectParseErrorTS(t, \"x = async <T extends X>(y)\", \"<stdin>: ERROR: Expected \\\"=>\\\" but found end of file\\n\")\n\texpectParseErrorTS(t, \"x = <const const>() => {}\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\"const\\\"\\n\")\n\texpectPrintedTS(t, \"class Foo<const const const T> {}\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo<const in out T> {}\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo<in const out T> {}\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo<in out const T> {}\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo<const in const out const T> {}\", \"class Foo {\\n}\\n\")\n\texpectParseErrorTS(t, \"class Foo<in const> {}\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo<out const> {}\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo<in out const> {}\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectPrintedTSX(t, \"<const>(x)</const>\", \"/* @__PURE__ */ React.createElement(\\\"const\\\", null, \\\"(x)\\\");\\n\")\n\texpectPrintedTSX(t, \"<const const/>\", \"/* @__PURE__ */ React.createElement(\\\"const\\\", { const: true });\\n\")\n\texpectPrintedTSX(t, \"<const const></const>\", \"/* @__PURE__ */ React.createElement(\\\"const\\\", { const: true });\\n\")\n\texpectPrintedTSX(t, \"<const T/>\", \"/* @__PURE__ */ React.createElement(\\\"const\\\", { T: true });\\n\")\n\texpectPrintedTSX(t, \"<const T></const>\", \"/* @__PURE__ */ React.createElement(\\\"const\\\", { T: true });\\n\")\n\texpectPrintedTSX(t, \"<const T>(y) = {}</const>\", \"/* @__PURE__ */ React.createElement(\\\"const\\\", { T: true }, \\\"(y) = \\\");\\n\")\n\texpectPrintedTSX(t, \"<const T extends/>\", \"/* @__PURE__ */ React.createElement(\\\"const\\\", { T: true, extends: true });\\n\")\n\texpectPrintedTSX(t, \"<const T extends></const>\", \"/* @__PURE__ */ React.createElement(\\\"const\\\", { T: true, extends: true });\\n\")\n\texpectPrintedTSX(t, \"<const T extends>(y) = {}</const>\", \"/* @__PURE__ */ React.createElement(\\\"const\\\", { T: true, extends: true }, \\\"(y) = \\\");\\n\")\n\texpectPrintedTSX(t, \"<const T,>() => {}\", \"() => {\\n};\\n\")\n\texpectPrintedTSX(t, \"<const T, X>() => {}\", \"() => {\\n};\\n\")\n\texpectPrintedTSX(t, \"<const T, const X>() => {}\", \"() => {\\n};\\n\")\n\texpectPrintedTSX(t, \"<const T, const const X>() => {}\", \"() => {\\n};\\n\")\n\texpectPrintedTSX(t, \"<const T extends X>() => {}\", \"() => {\\n};\\n\")\n\texpectPrintedTSX(t, \"async <const T,>() => {}\", \"async () => {\\n};\\n\")\n\texpectPrintedTSX(t, \"async <const T, X>() => {}\", \"async () => {\\n};\\n\")\n\texpectPrintedTSX(t, \"async <const T, const X>() => {}\", \"async () => {\\n};\\n\")\n\texpectPrintedTSX(t, \"async <const T, const const X>() => {}\", \"async () => {\\n};\\n\")\n\texpectPrintedTSX(t, \"async <const T extends X>() => {}\", \"async () => {\\n};\\n\")\n\texpectParseErrorTSX(t, \"<const T>() => {}\", jsxErrorArrow+\"<stdin>: ERROR: Unexpected end of file before a closing \\\"const\\\" tag\\n<stdin>: NOTE: The opening \\\"const\\\" tag is here:\\n\")\n\texpectParseErrorTSX(t, \"<const const>() => {}\", jsxErrorArrow+\"<stdin>: ERROR: Unexpected end of file before a closing \\\"const\\\" tag\\n<stdin>: NOTE: The opening \\\"const\\\" tag is here:\\n\")\n\texpectParseErrorTSX(t, \"<const const T,>() => {}\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\",\\\"\\n\")\n\texpectParseErrorTSX(t, \"<const const T extends X>() => {}\", jsxErrorArrow+\"<stdin>: ERROR: Unexpected end of file before a closing \\\"const\\\" tag\\n<stdin>: NOTE: The opening \\\"const\\\" tag is here:\\n\")\n\texpectParseErrorTSX(t, \"async <const T>() => {}\", \"<stdin>: ERROR: Unexpected \\\"const\\\"\\n\")\n\texpectParseErrorTSX(t, \"async <const const>() => {}\", \"<stdin>: ERROR: Unexpected \\\"const\\\"\\n\")\n\texpectParseErrorTSX(t, \"async <const const T,>() => {}\", \"<stdin>: ERROR: Unexpected \\\"const\\\"\\n\")\n\texpectParseErrorTSX(t, \"async <const const T extends X>() => {}\", \"<stdin>: ERROR: Unexpected \\\"const\\\"\\n\")\n}\n\nfunc TestTSAsCast(t *testing.T) {\n\texpectPrintedTS(t, \"x as any\\n(y);\", \"x;\\ny;\\n\")\n\texpectPrintedTS(t, \"x as any\\n`y`;\", \"x;\\n`y`;\\n\")\n\texpectPrintedTS(t, \"x as any\\n`${y}`;\", \"x;\\n`${y}`;\\n\")\n\texpectPrintedTS(t, \"x as any\\n--y;\", \"x;\\n--y;\\n\")\n\texpectPrintedTS(t, \"x as any\\n++y;\", \"x;\\n++y;\\n\")\n\texpectPrintedTS(t, \"x + y as any\\n(z as any) + 1;\", \"x + y;\\nz + 1;\\n\")\n\texpectPrintedTS(t, \"x + y as any\\n(z as any) = 1;\", \"x + y;\\nz = 1;\\n\")\n\texpectPrintedTS(t, \"x = y as any\\n(z as any) + 1;\", \"x = y;\\nz + 1;\\n\")\n\texpectPrintedTS(t, \"x = y as any\\n(z as any) = 1;\", \"x = y;\\nz = 1;\\n\")\n\texpectPrintedTS(t, \"x * y as any\\n['z'];\", \"x * y;\\n[\\\"z\\\"];\\n\")\n\texpectPrintedTS(t, \"x * y as any\\n.z;\", \"x * y;\\n\")\n\texpectPrintedTS(t, \"x as y['x'];\", \"x;\\n\")\n\texpectPrintedTS(t, \"x as y!['x'];\", \"x;\\n\")\n\texpectPrintedTS(t, \"x as y\\n['x'];\", \"x;\\n[\\\"x\\\"];\\n\")\n\texpectPrintedTS(t, \"x as y\\n!['x'];\", \"x;\\n![\\\"x\\\"];\\n\")\n\texpectParseErrorTS(t, \"x = y as any `z`;\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"`z`\\\"\\n\")\n\texpectParseErrorTS(t, \"x = y as any `${z}`;\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"`${\\\"\\n\")\n\texpectParseErrorTS(t, \"x = y as any?.z;\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"?.\\\"\\n\")\n\texpectParseErrorTS(t, \"x = y as any--;\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"--\\\"\\n\")\n\texpectParseErrorTS(t, \"x = y as any++;\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"++\\\"\\n\")\n\texpectParseErrorTS(t, \"x = y as any(z);\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseErrorTS(t, \"x = y as any\\n= z;\", \"<stdin>: ERROR: Unexpected \\\"=\\\"\\n\")\n\texpectParseErrorTS(t, \"a, x as y `z`;\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"`z`\\\"\\n\")\n\texpectParseErrorTS(t, \"a ? b : x as y `z`;\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"`z`\\\"\\n\")\n\texpectParseErrorTS(t, \"x as any = y;\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"=\\\"\\n\")\n\texpectParseErrorTS(t, \"(x as any = y);\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"=\\\"\\n\")\n\texpectParseErrorTS(t, \"(x = y as any(z));\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"(\\\"\\n\")\n}\n\nfunc TestTSSatisfies(t *testing.T) {\n\texpectPrintedTS(t, \"const t1 = { a: 1 } satisfies I1;\", \"const t1 = { a: 1 };\\n\")\n\texpectPrintedTS(t, \"const t2 = { a: 1, b: 1 } satisfies I1;\", \"const t2 = { a: 1, b: 1 };\\n\")\n\texpectPrintedTS(t, \"const t3 = { } satisfies I1;\", \"const t3 = {};\\n\")\n\texpectPrintedTS(t, \"const t4: T1 = { a: 'a' } satisfies T1;\", \"const t4 = { a: \\\"a\\\" };\\n\")\n\texpectPrintedTS(t, \"const t5 = (m => m.substring(0)) satisfies T2;\", \"const t5 = ((m) => m.substring(0));\\n\")\n\texpectPrintedTS(t, \"const t6 = [1, 2] satisfies [number, number];\", \"const t6 = [1, 2];\\n\")\n\texpectPrintedTS(t, \"let t7 = { a: 'test' } satisfies A;\", \"let t7 = { a: \\\"test\\\" };\\n\")\n\texpectPrintedTS(t, \"let t8 = { a: 'test', b: 'test' } satisfies A;\", \"let t8 = { a: \\\"test\\\", b: \\\"test\\\" };\\n\")\n\texpectPrintedTS(t, \"export default {} satisfies Foo;\", \"export default {};\\n\")\n\texpectPrintedTS(t, \"export default { a: 1 } satisfies Foo;\", \"export default { a: 1 };\\n\")\n\texpectPrintedTS(t,\n\t\t\"const p = { isEven: n => n % 2 === 0, isOdd: n => n % 2 === 1 } satisfies Predicates;\",\n\t\t\"const p = { isEven: (n) => n % 2 === 0, isOdd: (n) => n % 2 === 1 };\\n\")\n\texpectPrintedTS(t,\n\t\t\"let obj: { f(s: string): void } & Record<string, unknown> = { f(s) { }, g(s) { } } satisfies { g(s: string): void } & Record<string, unknown>;\",\n\t\t\"let obj = { f(s) {\\n}, g(s) {\\n} };\\n\")\n\texpectPrintedTS(t,\n\t\t\"const car = { start() { }, move(d) { }, stop() { } } satisfies Movable & Record<string, unknown>;\",\n\t\t\"const car = { start() {\\n}, move(d) {\\n}, stop() {\\n} };\\n\",\n\t)\n\texpectPrintedTS(t, \"var v = undefined satisfies 1;\", \"var v = void 0;\\n\")\n\texpectPrintedTS(t, \"const a = { x: 10 } satisfies Partial<Point2d>;\", \"const a = { x: 10 };\\n\")\n\texpectPrintedTS(t,\n\t\t\"const p = { a: 0, b: \\\"hello\\\", x: 8 } satisfies Partial<Record<Keys, unknown>>;\",\n\t\t\"const p = { a: 0, b: \\\"hello\\\", x: 8 };\\n\",\n\t)\n\texpectPrintedTS(t,\n\t\t\"const p = { a: 0, b: \\\"hello\\\", x: 8 } satisfies Record<Keys, unknown>;\",\n\t\t\"const p = { a: 0, b: \\\"hello\\\", x: 8 };\\n\",\n\t)\n\texpectPrintedTS(t,\n\t\t\"const x2 = { m: true, s: \\\"false\\\" } satisfies Facts;\",\n\t\t\"const x2 = { m: true, s: \\\"false\\\" };\\n\",\n\t)\n\texpectPrintedTS(t,\n\t\t\"export const Palette = { white: { r: 255, g: 255, b: 255 }, black: { r: 0, g: 0, d: 0 }, blue: { r: 0, g: 0, b: 255 }, } satisfies Record<string, Color>;\",\n\t\t\"export const Palette = { white: { r: 255, g: 255, b: 255 }, black: { r: 0, g: 0, d: 0 }, blue: { r: 0, g: 0, b: 255 } };\\n\",\n\t)\n\texpectPrintedTS(t,\n\t\t\"const a: \\\"baz\\\" = \\\"foo\\\" satisfies \\\"foo\\\" | \\\"bar\\\";\",\n\t\t\"const a = \\\"foo\\\";\\n\",\n\t)\n\texpectPrintedTS(t,\n\t\t\"const b: { xyz: \\\"baz\\\" } = { xyz: \\\"foo\\\" } satisfies { xyz: \\\"foo\\\" | \\\"bar\\\" };\",\n\t\t\"const b = { xyz: \\\"foo\\\" };\\n\",\n\t)\n}\n\nfunc TestTSClass(t *testing.T) {\n\texpectPrintedTS(t, \"export default class Foo {}\", \"export default class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class Foo extends Bar<T> {}\", \"export default class Foo extends Bar {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class Foo extends Bar<T>() {}\", \"export default class Foo extends Bar() {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class Foo implements Bar<T> {}\", \"export default class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class Foo<T> {}\", \"export default class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class Foo<T> extends Bar<T> {}\", \"export default class Foo extends Bar {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class Foo<T> extends Bar<T>() {}\", \"export default class Foo extends Bar() {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class Foo<T> implements Bar<T> {}\", \"export default class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"(class Foo<T> {})\", \"(class Foo {\\n});\\n\")\n\texpectPrintedTS(t, \"(class Foo<T> extends Bar<T> {})\", \"(class Foo extends Bar {\\n});\\n\")\n\texpectPrintedTS(t, \"(class Foo<T> extends Bar<T>() {})\", \"(class Foo extends Bar() {\\n});\\n\")\n\texpectPrintedTS(t, \"(class Foo<T> implements Bar<T> {})\", \"(class Foo {\\n});\\n\")\n\n\texpectPrintedTS(t, \"export default class {}\", \"export default class {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class extends Foo<T> {}\", \"export default class extends Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class implements Foo<T> {}\", \"export default class {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class <T> {}\", \"export default class {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class <T> extends Foo<T> {}\", \"export default class extends Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"export default class <T> implements Foo<T> {}\", \"export default class {\\n}\\n\")\n\texpectPrintedTS(t, \"(class <T> {})\", \"(class {\\n});\\n\")\n\texpectPrintedTS(t, \"(class extends Foo<T> {})\", \"(class extends Foo {\\n});\\n\")\n\texpectPrintedTS(t, \"(class extends Foo<T>() {})\", \"(class extends Foo() {\\n});\\n\")\n\texpectPrintedTS(t, \"(class implements Foo<T> {})\", \"(class {\\n});\\n\")\n\texpectPrintedTS(t, \"(class <T> extends Foo<T> {})\", \"(class extends Foo {\\n});\\n\")\n\texpectPrintedTS(t, \"(class <T> extends Foo<T>() {})\", \"(class extends Foo() {\\n});\\n\")\n\texpectPrintedTS(t, \"(class <T> implements Foo<T> {})\", \"(class {\\n});\\n\")\n\n\t// Check ASI for \"abstract\"\n\texpectPrintedTS(t, \"abstract \\n class A {}\", \"abstract;\\nclass A {\\n}\\n\")\n\texpectPrintedTS(t, \"export default abstract \\n class A {}\", \"export default abstract;\\nclass A {\\n}\\n\")\n\texpectPrintedTS(t, \"abstract class A { abstract \\n foo(): void {} }\", \"class A {\\n  abstract;\\n  foo() {\\n  }\\n}\\n\")\n\n\texpectPrintedTS(t, \"abstract class A { abstract foo(): void; bar(): void {} }\", \"class A {\\n  bar() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"export abstract class A { abstract foo(): void; bar(): void {} }\", \"export class A {\\n  bar() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"export default abstract\", \"export default abstract;\\n\")\n\texpectPrintedTS(t, \"export default abstract - after\", \"export default abstract - after;\\n\")\n\texpectPrintedTS(t, \"export default abstract class { abstract foo(): void; bar(): void {} } - after\", \"export default class {\\n  bar() {\\n  }\\n}\\n-after;\\n\")\n\texpectPrintedTS(t, \"export default abstract class A { abstract foo(): void; bar(): void {} } - after\", \"export default class A {\\n  bar() {\\n  }\\n}\\n-after;\\n\")\n\n\texpectPrintedTS(t, \"class A<T extends number> extends B.C<D, E> {}\", \"class A extends B.C {\\n}\\n\")\n\texpectPrintedTS(t, \"class A<T extends number> implements B.C<D, E>, F.G<H, I> {}\", \"class A {\\n}\\n\")\n\texpectPrintedTS(t, \"class A<T extends number> extends X implements B.C<D, E>, F.G<H, I> {}\", \"class A extends X {\\n}\\n\")\n\n\treservedWordError :=\n\t\t\" is a reserved word and cannot be used in strict mode\\n\" +\n\t\t\t\"<stdin>: NOTE: All code inside a class is implicitly in strict mode\\n\"\n\n\texpectParseErrorTS(t, \"class Foo { constructor(public) {} }\", \"<stdin>: ERROR: \\\"public\\\"\"+reservedWordError)\n\texpectParseErrorTS(t, \"class Foo { constructor(protected) {} }\", \"<stdin>: ERROR: \\\"protected\\\"\"+reservedWordError)\n\texpectParseErrorTS(t, \"class Foo { constructor(private) {} }\", \"<stdin>: ERROR: \\\"private\\\"\"+reservedWordError)\n\texpectPrintedTS(t, \"class Foo { constructor(readonly) {} }\", \"class Foo {\\n  constructor(readonly) {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { constructor(override) {} }\", \"class Foo {\\n  constructor(override) {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { constructor(public x) {} }\", \"class Foo {\\n  constructor(x) {\\n    this.x = x;\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { constructor(protected x) {} }\", \"class Foo {\\n  constructor(x) {\\n    this.x = x;\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { constructor(private x) {} }\", \"class Foo {\\n  constructor(x) {\\n    this.x = x;\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { constructor(readonly x) {} }\", \"class Foo {\\n  constructor(x) {\\n    this.x = x;\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { constructor(override x) {} }\", \"class Foo {\\n  constructor(x) {\\n    this.x = x;\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { constructor(public readonly x) {} }\", \"class Foo {\\n  constructor(x) {\\n    this.x = x;\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { constructor(protected readonly x) {} }\", \"class Foo {\\n  constructor(x) {\\n    this.x = x;\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { constructor(private readonly x) {} }\", \"class Foo {\\n  constructor(x) {\\n    this.x = x;\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { constructor(override readonly x) {} }\", \"class Foo {\\n  constructor(x) {\\n    this.x = x;\\n  }\\n}\\n\")\n\n\texpectParseErrorTS(t, \"class Foo { constructor(public {x}) {} }\", \"<stdin>: ERROR: Expected identifier but found \\\"{\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { constructor(protected {x}) {} }\", \"<stdin>: ERROR: Expected identifier but found \\\"{\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { constructor(private {x}) {} }\", \"<stdin>: ERROR: Expected identifier but found \\\"{\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { constructor(readonly {x}) {} }\", \"<stdin>: ERROR: Expected identifier but found \\\"{\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { constructor(override {x}) {} }\", \"<stdin>: ERROR: Expected identifier but found \\\"{\\\"\\n\")\n\n\texpectParseErrorTS(t, \"class Foo { constructor(public [x]) {} }\", \"<stdin>: ERROR: Expected identifier but found \\\"[\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { constructor(protected [x]) {} }\", \"<stdin>: ERROR: Expected identifier but found \\\"[\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { constructor(private [x]) {} }\", \"<stdin>: ERROR: Expected identifier but found \\\"[\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { constructor(readonly [x]) {} }\", \"<stdin>: ERROR: Expected identifier but found \\\"[\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { constructor(override [x]) {} }\", \"<stdin>: ERROR: Expected identifier but found \\\"[\\\"\\n\")\n\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { foo: number = 0 }\", \"class Foo {\\n  constructor() {\\n    this.foo = 0;\\n  }\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { ['foo']: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { ['foo']: number = 0 }\", \"class Foo {\\n  constructor() {\\n    this[\\\"foo\\\"] = 0;\\n  }\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { foo(): void {} }\", \"class Foo {\\n  foo() {\\n  }\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { foo(): void; foo(): void {} }\", \"class Foo {\\n  foo() {\\n  }\\n}\\n\")\n\texpectParseErrorTS(t, \"class Foo { foo(): void foo(): void {} }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"foo\\\"\\n\")\n\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { foo?: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { foo?: number = 0 }\", \"class Foo {\\n  constructor() {\\n    this.foo = 0;\\n  }\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { foo?(): void {} }\", \"class Foo {\\n  foo() {\\n  }\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { foo?(): void; foo(): void {} }\", \"class Foo {\\n  foo() {\\n  }\\n}\\n\")\n\texpectParseErrorTS(t, \"class Foo { foo?(): void foo(): void {} }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"foo\\\"\\n\")\n\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { foo!: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { foo!: number = 0 }\", \"class Foo {\\n  constructor() {\\n    this.foo = 0;\\n  }\\n}\\n\")\n\texpectParseErrorTS(t, \"class Foo { foo!() {} }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { *foo!() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"!\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { get foo!() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"!\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { set foo!(x) {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"!\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { async foo!() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"!\\\"\\n\")\n\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { 'foo' = 0 }\", \"class Foo {\\n  constructor() {\\n    this[\\\"foo\\\"] = 0;\\n  }\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { ['foo'] = 0 }\", \"class Foo {\\n  constructor() {\\n    this[\\\"foo\\\"] = 0;\\n  }\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { [foo] = 0 }\", \"var _a;\\n_a = foo;\\nclass Foo {\\n  constructor() {\\n    this[_a] = 0;\\n  }\\n}\\n\")\n\texpectPrintedMangleAssignSemanticsTS(t, \"class Foo { 'foo' = 0 }\", \"class Foo {\\n  constructor() {\\n    this.foo = 0;\\n  }\\n}\\n\")\n\texpectPrintedMangleAssignSemanticsTS(t, \"class Foo { ['foo'] = 0 }\", \"class Foo {\\n  constructor() {\\n    this.foo = 0;\\n  }\\n}\\n\")\n\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { foo \\n ?: number }\", \"class Foo {\\n}\\n\")\n\texpectParseErrorTS(t, \"class Foo { foo \\n !: number }\", \"<stdin>: ERROR: Expected identifier but found \\\"!\\\"\\n\")\n\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { public foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { private foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { protected foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { declare foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { declare public foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { public declare foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { override foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { override public foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { public override foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { declare override public foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { declare foo = 123 }\", \"class Foo {\\n}\\n\")\n\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { public static foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { private static foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { protected static foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { declare static foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { declare public static foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { public declare static foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { public static declare foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { override static foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { override public static foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { public override static foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { public static override foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { declare override public static foo: number }\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { declare static foo = 123 }\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { static declare foo = 123 }\", \"class Foo {\\n}\\n\")\n\n\texpectParseErrorTS(t, \"class Foo { declare #foo }\", \"<stdin>: ERROR: \\\"declare\\\" cannot be used with a private identifier\\n\")\n\texpectParseErrorTS(t, \"class Foo { declare [foo: string]: number }\", \"<stdin>: ERROR: \\\"declare\\\" cannot be used with an index signature\\n\")\n\texpectParseErrorTS(t, \"class Foo { declare foo() }\", \"<stdin>: ERROR: \\\"declare\\\" cannot be used with a method\\n\")\n\texpectParseErrorTS(t, \"class Foo { declare get foo() }\", \"<stdin>: ERROR: \\\"declare\\\" cannot be used with a getter\\n\")\n\texpectParseErrorTS(t, \"class Foo { declare set foo(x) }\", \"<stdin>: ERROR: \\\"declare\\\" cannot be used with a setter\\n\")\n\n\texpectParseErrorTS(t, \"class Foo { declare static #foo }\", \"<stdin>: ERROR: \\\"declare\\\" cannot be used with a private identifier\\n\")\n\texpectParseErrorTS(t, \"class Foo { declare static [foo: string]: number }\", \"<stdin>: ERROR: \\\"declare\\\" cannot be used with an index signature\\n\")\n\texpectParseErrorTS(t, \"class Foo { declare static foo() }\", \"<stdin>: ERROR: \\\"declare\\\" cannot be used with a method\\n\")\n\texpectParseErrorTS(t, \"class Foo { declare static get foo() }\", \"<stdin>: ERROR: \\\"declare\\\" cannot be used with a getter\\n\")\n\texpectParseErrorTS(t, \"class Foo { declare static set foo(x) }\", \"<stdin>: ERROR: \\\"declare\\\" cannot be used with a setter\\n\")\n\n\texpectParseErrorTS(t, \"class Foo { static declare #foo }\", \"<stdin>: ERROR: \\\"declare\\\" cannot be used with a private identifier\\n\")\n\texpectParseErrorTS(t, \"class Foo { static declare [foo: string]: number }\", \"<stdin>: ERROR: \\\"declare\\\" cannot be used with an index signature\\n\")\n\texpectParseErrorTS(t, \"class Foo { static declare foo() }\", \"<stdin>: ERROR: \\\"declare\\\" cannot be used with a method\\n\")\n\texpectParseErrorTS(t, \"class Foo { static declare get foo() }\", \"<stdin>: ERROR: \\\"declare\\\" cannot be used with a getter\\n\")\n\texpectParseErrorTS(t, \"class Foo { static declare set foo(x) }\", \"<stdin>: ERROR: \\\"declare\\\" cannot be used with a setter\\n\")\n\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { [key: string]: any\\nfoo = 0 }\", \"class Foo {\\n  constructor() {\\n    this.foo = 0;\\n  }\\n}\\n\")\n\texpectPrintedAssignSemanticsTS(t, \"class Foo { [key: string]: any; foo = 0 }\", \"class Foo {\\n  constructor() {\\n    this.foo = 0;\\n  }\\n}\\n\")\n\n\texpectParseErrorTS(t, \"class Foo<> {}\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo<,> {}\", \"<stdin>: ERROR: Expected identifier but found \\\",\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo<T><T> {}\", \"<stdin>: ERROR: Expected \\\"{\\\" but found \\\"<\\\"\\n\")\n\n\texpectPrintedTS(t, \"class Foo { foo<T>() {} }\", \"class Foo {\\n  foo() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { foo?<T>() {} }\", \"class Foo {\\n  foo() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { [foo]<T>() {} }\", \"class Foo {\\n  [foo]() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { [foo]?<T>() {} }\", \"class Foo {\\n  [foo]() {\\n  }\\n}\\n\")\n\texpectParseErrorTS(t, \"class Foo { foo<T> }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"}\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { foo?<T> }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"}\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { foo!<T>() {} }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"<\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { [foo]<T> }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"}\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { [foo]?<T> }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"}\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { [foo]!<T>() {} }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"<\\\"\\n\")\n\n\t// See: https://github.com/microsoft/TypeScript/pull/60225\n\texpectPrintedTS(t, \"class A { get \\n x() {} }\", \"class A {\\n  get x() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class A { set \\n x(_) {} }\", \"class A {\\n  set x(_) {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class A { get \\n *x() {} }\", \"class A {\\n  get;\\n  *x() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class A { set \\n *x(_) {} }\", \"class A {\\n  set;\\n  *x(_) {\\n  }\\n}\\n\")\n\texpectParseErrorTS(t, \"class A { get \\n async x() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"x\\\"\\n\")\n\texpectParseErrorTS(t, \"class A { set \\n async x(_) {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"x\\\"\\n\")\n\texpectParseErrorTS(t, \"class A { async get \\n *x() {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"*\\\"\\n\")\n\texpectParseErrorTS(t, \"class A { async set \\n *x(_) {} }\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"*\\\"\\n\")\n}\n\nfunc TestTSAutoAccessors(t *testing.T) {\n\texpectPrintedTS(t, \"class Foo { accessor }\", \"class Foo {\\n  accessor;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor x }\", \"class Foo {\\n  accessor x;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor x? }\", \"class Foo {\\n  accessor x;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor x! }\", \"class Foo {\\n  accessor x;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor x = y }\", \"class Foo {\\n  accessor x = y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor x? = y }\", \"class Foo {\\n  accessor x = y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor x! = y }\", \"class Foo {\\n  accessor x = y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor x: any }\", \"class Foo {\\n  accessor x;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor x?: any }\", \"class Foo {\\n  accessor x;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor x!: any }\", \"class Foo {\\n  accessor x;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor x: any = y }\", \"class Foo {\\n  accessor x = y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor x?: any = y }\", \"class Foo {\\n  accessor x = y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor x!: any = y }\", \"class Foo {\\n  accessor x = y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor [x] }\", \"class Foo {\\n  accessor [x];\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor [x]? }\", \"class Foo {\\n  accessor [x];\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor [x]! }\", \"class Foo {\\n  accessor [x];\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor [x] = y }\", \"class Foo {\\n  accessor [x] = y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor [x]? = y }\", \"class Foo {\\n  accessor [x] = y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor [x]! = y }\", \"class Foo {\\n  accessor [x] = y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor [x]: any }\", \"class Foo {\\n  accessor [x];\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor [x]?: any }\", \"class Foo {\\n  accessor [x];\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor [x]!: any }\", \"class Foo {\\n  accessor [x];\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor [x]: any = y }\", \"class Foo {\\n  accessor [x] = y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor [x]?: any = y }\", \"class Foo {\\n  accessor [x] = y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { accessor [x]!: any = y }\", \"class Foo {\\n  accessor [x] = y;\\n}\\n\")\n\n\texpectParseErrorTS(t, \"class Foo { accessor x<T> }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"<\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { accessor x<T>() {} }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"<\\\"\\n\")\n\n\texpectPrintedTS(t, \"declare class Foo { accessor x }\", \"\")\n\texpectPrintedTS(t, \"declare class Foo { accessor #x }\", \"\")\n\texpectPrintedTS(t, \"declare class Foo { static accessor x }\", \"\")\n\texpectPrintedTS(t, \"declare class Foo { static accessor #x }\", \"\")\n\n\t// TypeScript doesn't allow these combinations, but we shouldn't crash\n\texpectPrintedTS(t, \"class Foo { declare accessor x }\", \"class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { readonly accessor x }\", \"class Foo {\\n  accessor x;\\n}\\n\")\n\texpectPrintedTS(t, \"interface Foo { accessor x }\", \"\")\n\texpectPrintedTS(t, \"interface Foo { static accessor x }\", \"\")\n\texpectPrintedTS(t, \"let x: { accessor x }\", \"let x;\\n\")\n\texpectPrintedTS(t, \"let x: { static accessor x }\", \"let x;\\n\")\n\texpectParseErrorTS(t, \"class Foo { accessor declare x }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"x\\\"\\n\")\n\texpectParseErrorTS(t, \"class Foo { accessor readonly x }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"x\\\"\\n\")\n}\n\nfunc TestTSPrivateIdentifiers(t *testing.T) {\n\t// The TypeScript compiler still moves private field initializers into the\n\t// constructor, but it has to leave the private field declaration in place so\n\t// the private field is still declared.\n\texpectPrintedTS(t, \"class Foo { #foo }\", \"class Foo {\\n  #foo;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { #foo = 1 }\", \"class Foo {\\n  #foo = 1;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { #foo() {} }\", \"class Foo {\\n  #foo() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { get #foo() {} }\", \"class Foo {\\n  get #foo() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { set #foo(x) {} }\", \"class Foo {\\n  set #foo(x) {\\n  }\\n}\\n\")\n\n\t// The TypeScript compiler doesn't currently support static private fields\n\t// because it moves static field initializers to after the class body and\n\t// private fields can't be used outside the class body. It remains to be seen\n\t// how the TypeScript compiler will transform private static fields once it\n\t// finally does support them. For now just leave the initializer in place.\n\texpectPrintedTS(t, \"class Foo { static #foo }\", \"class Foo {\\n  static #foo;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { static #foo = 1 }\", \"class Foo {\\n  static #foo = 1;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { static #foo() {} }\", \"class Foo {\\n  static #foo() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { static get #foo() {} }\", \"class Foo {\\n  static get #foo() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { static set #foo(x) {} }\", \"class Foo {\\n  static set #foo(x) {\\n  }\\n}\\n\")\n\n\t// Decorators are not valid on private members\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec #foo }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec #foo = 1 }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec #foo() {} }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec get #foo() {} }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec set #foo(x) {x} }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec accessor #foo }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec static #foo }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec static #foo = 1 }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec static #foo() {} }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec static get #foo() {} }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec static set #foo(x) {x} }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec static accessor #foo }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\n\t// Decorators are now able to access private names, since the TypeScript\n\t// compiler was changed to move them into a \"static {}\" block within the\n\t// class body: https://github.com/microsoft/TypeScript/pull/50074\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { static #foo; @dec(Foo.#foo) bar }\", \"\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { static #foo; @dec(Foo.#foo) bar() {} }\", \"\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { static #foo; bar(@dec(Foo.#foo) x) {} }\", \"\")\n}\n\nfunc TestTSInterface(t *testing.T) {\n\texpectPrintedTS(t, \"interface\\nA\\n{ a }\", \"interface;\\nA;\\n{\\n  a;\\n}\\n\")\n\n\texpectPrintedTS(t, \"interface A { a } x\", \"x;\\n\")\n\texpectPrintedTS(t, \"interface A { a; b } x\", \"x;\\n\")\n\texpectPrintedTS(t, \"interface A { a() } x\", \"x;\\n\")\n\texpectPrintedTS(t, \"interface A { a(); b } x\", \"x;\\n\")\n\texpectPrintedTS(t, \"interface Foo { foo(): Foo \\n is: Bar } x\", \"x;\\n\")\n\texpectPrintedTS(t, \"interface A<T extends number> extends B.C<D, E>, F.G<H, I> {} x\", \"x;\\n\")\n\texpectPrintedTS(t, \"export interface A<T extends number> extends B.C<D, E>, F.G<H, I> {} x\", \"x;\\n\")\n\texpectPrintedTS(t, \"export default interface Foo {} x\", \"x;\\n\")\n\texpectParseErrorTS(t, \"export default interface + x\",\n\t\t\"<stdin>: ERROR: \\\"interface\\\" is a reserved word and cannot be used in an ECMAScript module\\n\"+\n\t\t\t\"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the \\\"export\\\" keyword here:\\n\")\n\n\t// Check ASI for \"interface\"\n\texpectPrintedTS(t, \"interface\\nFoo\\n{}\", \"interface;\\nFoo;\\n{\\n}\\n\")\n\texpectPrintedTS(t, \"export default interface\\nFoo {} x\", \"x;\\n\")\n\texpectPrintedTS(t, \"export default interface\\nFoo\\n{} x\", \"x;\\n\")\n\texpectParseErrorTS(t, \"interface\\nFoo {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"{\\\"\\n\")\n\texpectParseErrorTS(t, \"export interface\\nFoo {}\", \"<stdin>: ERROR: Unexpected \\\"interface\\\"\\n\")\n\texpectParseErrorTS(t, \"export interface\\nFoo\\n{}\", \"<stdin>: ERROR: Unexpected \\\"interface\\\"\\n\")\n\texpectParseErrorTS(t, \"export default interface\\nFoo\", \"<stdin>: ERROR: Expected \\\"{\\\" but found end of file\\n\")\n}\n\nfunc TestTSNamespace(t *testing.T) {\n\texpectPrintedTS(t, \"namespace\\nx\\n{ var y }\", \"namespace;\\nx;\\n{\\n  var y;\\n}\\n\")\n\n\t// Check ES5 emit\n\texpectPrintedTargetTS(t, 5, \"namespace x { export var y = 1 }\", \"var x;\\n(function(x) {\\n  x.y = 1;\\n})(x || (x = {}));\\n\")\n\texpectPrintedTargetTS(t, 2015, \"namespace x { export var y = 1 }\", \"var x;\\n((x) => {\\n  x.y = 1;\\n})(x || (x = {}));\\n\")\n\n\t// Certain syntax isn't allowed inside a namespace block\n\texpectParseErrorTS(t, \"namespace x { return }\", \"<stdin>: ERROR: A return statement cannot be used here:\\n\")\n\texpectParseErrorTS(t, \"namespace x { await 1 }\", \"<stdin>: ERROR: \\\"await\\\" can only be used inside an \\\"async\\\" function\\n\")\n\texpectParseErrorTS(t, \"namespace x { if (y) return }\", \"<stdin>: ERROR: A return statement cannot be used here:\\n\")\n\texpectParseErrorTS(t, \"namespace x { if (y) await 1 }\", \"<stdin>: ERROR: \\\"await\\\" can only be used inside an \\\"async\\\" function\\n\")\n\texpectParseErrorTS(t, \"namespace x { this }\", \"<stdin>: ERROR: Cannot use \\\"this\\\" here:\\n\")\n\texpectParseErrorTS(t, \"namespace x { () => this }\", \"<stdin>: ERROR: Cannot use \\\"this\\\" here:\\n\")\n\texpectParseErrorTS(t, \"namespace x { class y { [this] } }\", \"<stdin>: ERROR: Cannot use \\\"this\\\" here:\\n\")\n\texpectParseErrorTS(t, \"namespace x { (function() { this }) }\", \"\")\n\texpectParseErrorTS(t, \"namespace x { function y() { this } }\", \"\")\n\texpectParseErrorTS(t, \"namespace x { class y { x = this } }\", \"\")\n\texpectParseErrorTS(t, \"export namespace x { export let yield = 1 }\",\n\t\t\"<stdin>: ERROR: \\\"yield\\\" is a reserved word and cannot be used in an ECMAScript module\\n\"+\n\t\t\t\"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the \\\"export\\\" keyword here:\\n\")\n\texpectPrintedTS(t, \"namespace x { export let await = 1, y = await }\", `var x;\n((x) => {\n  x.await = 1;\n  x.y = x.await;\n})(x || (x = {}));\n`)\n\texpectPrintedTS(t, \"namespace x { export let yield = 1, y = yield }\", `var x;\n((x) => {\n  x.yield = 1;\n  x.y = x.yield;\n})(x || (x = {}));\n`)\n\n\texpectPrintedTS(t, \"namespace Foo { 0 }\", `var Foo;\n((Foo) => {\n  0;\n})(Foo || (Foo = {}));\n`)\n\texpectPrintedTS(t, \"export namespace Foo { 0 }\", `export var Foo;\n((Foo) => {\n  0;\n})(Foo || (Foo = {}));\n`)\n\n\t// Namespaces should introduce a scope that prevents name collisions\n\texpectPrintedTS(t, \"namespace Foo { let x } let x\", `var Foo;\n((Foo) => {\n  let x;\n})(Foo || (Foo = {}));\nlet x;\n`)\n\n\t// Exports in namespaces shouldn't collide with module exports\n\texpectPrintedTS(t, \"namespace Foo { export let x } export let x\", `var Foo;\n((Foo) => {\n})(Foo || (Foo = {}));\nexport let x;\n`)\n\texpectPrintedTS(t, \"declare namespace Foo { export let x } namespace x { 0 }\", `var x;\n((x) => {\n  0;\n})(x || (x = {}));\n`)\n\n\terrorText := `<stdin>: ERROR: The symbol \"foo\" has already been declared\n<stdin>: NOTE: The symbol \"foo\" was originally declared here:\n`\n\n\t// Namespaces with values are not allowed to merge\n\texpectParseErrorTS(t, \"var foo; namespace foo { 0 }\", errorText)\n\texpectParseErrorTS(t, \"let foo; namespace foo { 0 }\", errorText)\n\texpectParseErrorTS(t, \"const foo = 0; namespace foo { 0 }\", errorText)\n\texpectParseErrorTS(t, \"namespace foo { 0 } var foo\", errorText)\n\texpectParseErrorTS(t, \"namespace foo { 0 } let foo\", errorText)\n\texpectParseErrorTS(t, \"namespace foo { 0 } const foo = 0\", errorText)\n\n\t// Namespaces without values are allowed to merge\n\texpectPrintedTS(t, \"var foo; namespace foo {}\", \"var foo;\\n\")\n\texpectPrintedTS(t, \"let foo; namespace foo {}\", \"let foo;\\n\")\n\texpectPrintedTS(t, \"const foo = 0; namespace foo {}\", \"const foo = 0;\\n\")\n\texpectPrintedTS(t, \"namespace foo {} var foo\", \"var foo;\\n\")\n\texpectPrintedTS(t, \"namespace foo {} let foo\", \"let foo;\\n\")\n\texpectPrintedTS(t, \"namespace foo {} const foo = 0\", \"const foo = 0;\\n\")\n\n\t// Namespaces with types but no values are allowed to merge\n\texpectPrintedTS(t, \"var foo; namespace foo { export type bar = number }\", \"var foo;\\n\")\n\texpectPrintedTS(t, \"let foo; namespace foo { export type bar = number }\", \"let foo;\\n\")\n\texpectPrintedTS(t, \"const foo = 0; namespace foo { export type bar = number }\", \"const foo = 0;\\n\")\n\texpectPrintedTS(t, \"namespace foo { export type bar = number } var foo\", \"var foo;\\n\")\n\texpectPrintedTS(t, \"namespace foo { export type bar = number } let foo\", \"let foo;\\n\")\n\texpectPrintedTS(t, \"namespace foo { export type bar = number } const foo = 0\", \"const foo = 0;\\n\")\n\n\t// Namespaces are allowed to merge with certain symbols\n\texpectPrintedTS(t, \"function foo() {} namespace foo { 0 }\", `function foo() {\n}\n((foo) => {\n  0;\n})(foo || (foo = {}));\n`)\n\texpectPrintedTS(t, \"function* foo() {} namespace foo { 0 }\", `function* foo() {\n}\n((foo) => {\n  0;\n})(foo || (foo = {}));\n`)\n\texpectPrintedTS(t, \"async function foo() {} namespace foo { 0 }\", `async function foo() {\n}\n((foo) => {\n  0;\n})(foo || (foo = {}));\n`)\n\texpectPrintedTS(t, \"class foo {} namespace foo { 0 }\", `class foo {\n}\n((foo) => {\n  0;\n})(foo || (foo = {}));\n`)\n\texpectPrintedTS(t, \"enum foo { a } namespace foo { 0 }\", `var foo = /* @__PURE__ */ ((foo) => {\n  foo[foo[\"a\"] = 0] = \"a\";\n  return foo;\n})(foo || {});\n((foo) => {\n  0;\n})(foo || (foo = {}));\n`)\n\texpectPrintedTS(t, \"namespace foo {} namespace foo { 0 }\", `var foo;\n((foo) => {\n  0;\n})(foo || (foo = {}));\n`)\n\texpectParseErrorTS(t, \"namespace foo { 0 } function foo() {}\", errorText)\n\texpectParseErrorTS(t, \"namespace foo { 0 } function* foo() {}\", errorText)\n\texpectParseErrorTS(t, \"namespace foo { 0 } async function foo() {}\", errorText)\n\texpectParseErrorTS(t, \"namespace foo { 0 } class foo {}\", errorText)\n\texpectPrintedTS(t, \"namespace foo { 0 } enum foo { a }\", `((foo) => {\n  0;\n})(foo || (foo = {}));\nvar foo = /* @__PURE__ */ ((foo) => {\n  foo[foo[\"a\"] = 0] = \"a\";\n  return foo;\n})(foo || {});\n`)\n\texpectPrintedTS(t, \"namespace foo { 0 } namespace foo {}\", `var foo;\n((foo) => {\n  0;\n})(foo || (foo = {}));\n`)\n\texpectPrintedTS(t, \"namespace foo { 0 } namespace foo { 0 }\", `var foo;\n((foo) => {\n  0;\n})(foo || (foo = {}));\n((foo) => {\n  0;\n})(foo || (foo = {}));\n`)\n\texpectPrintedTS(t, \"function foo() {} namespace foo { 0 } function foo() {}\", `function foo() {\n}\n((foo) => {\n  0;\n})(foo || (foo = {}));\nfunction foo() {\n}\n`)\n\texpectPrintedTS(t, \"function* foo() {} namespace foo { 0 } function* foo() {}\", `function* foo() {\n}\n((foo) => {\n  0;\n})(foo || (foo = {}));\nfunction* foo() {\n}\n`)\n\texpectPrintedTS(t, \"async function foo() {} namespace foo { 0 } async function foo() {}\", `async function foo() {\n}\n((foo) => {\n  0;\n})(foo || (foo = {}));\nasync function foo() {\n}\n`)\n\n\t// Namespace merging shouldn't allow for other merging\n\texpectParseErrorTS(t, \"class foo {} namespace foo { 0 } class foo {}\", errorText)\n\texpectParseErrorTS(t, \"class foo {} namespace foo { 0 } enum foo {}\", errorText)\n\texpectParseErrorTS(t, \"enum foo {} namespace foo { 0 } class foo {}\", errorText)\n\texpectParseErrorTS(t, \"namespace foo { 0 } namespace foo { 0 } let foo\", errorText)\n\texpectParseErrorTS(t, \"namespace foo { 0 } enum foo {} class foo {}\", errorText)\n\n\t// Test dot nested namespace syntax\n\texpectPrintedTS(t, \"namespace foo.bar { foo(bar) }\", `var foo;\n((foo) => {\n  let bar;\n  ((bar) => {\n    foo(bar);\n  })(bar = foo.bar || (foo.bar = {}));\n})(foo || (foo = {}));\n`)\n\n\t// \"module\" is a deprecated alias for \"namespace\"\n\texpectPrintedTS(t, \"module foo { export namespace bar { foo(bar) } }\", `var foo;\n((foo) => {\n  let bar;\n  ((bar) => {\n    foo(bar);\n  })(bar = foo.bar || (foo.bar = {}));\n})(foo || (foo = {}));\n`)\n\texpectPrintedTS(t, \"namespace foo { export module bar { foo(bar) } }\", `var foo;\n((foo) => {\n  let bar;\n  ((bar) => {\n    foo(bar);\n  })(bar = foo.bar || (foo.bar = {}));\n})(foo || (foo = {}));\n`)\n\texpectPrintedTS(t, \"module foo.bar { foo(bar) }\", `var foo;\n((foo) => {\n  let bar;\n  ((bar) => {\n    foo(bar);\n  })(bar = foo.bar || (foo.bar = {}));\n})(foo || (foo = {}));\n`)\n}\n\nfunc TestTSNamespaceExports(t *testing.T) {\n\texpectPrintedTS(t, `\n\t\tnamespace A {\n\t\t\texport namespace B {\n\t\t\t\texport function fn() {}\n\t\t\t}\n\t\t\tnamespace C {\n\t\t\t\texport function fn() {}\n\t\t\t}\n\t\t\tnamespace D {\n\t\t\t\tfunction fn() {}\n\t\t\t}\n\t\t}\n\t`, `var A;\n((A) => {\n  let B;\n  ((B) => {\n    function fn() {\n    }\n    B.fn = fn;\n  })(B = A.B || (A.B = {}));\n  let C;\n  ((C) => {\n    function fn() {\n    }\n    C.fn = fn;\n  })(C || (C = {}));\n  let D;\n  ((D) => {\n    function fn() {\n    }\n  })(D || (D = {}));\n})(A || (A = {}));\n`)\n\n\texpectPrintedTS(t, `\n\t\tnamespace A {\n\t\t\texport namespace B {\n\t\t\t\texport class Class {}\n\t\t\t}\n\t\t\tnamespace C {\n\t\t\t\texport class Class {}\n\t\t\t}\n\t\t\tnamespace D {\n\t\t\t\tclass Class {}\n\t\t\t}\n\t\t}\n\t`, `var A;\n((A) => {\n  let B;\n  ((B) => {\n    class Class {\n    }\n    B.Class = Class;\n  })(B = A.B || (A.B = {}));\n  let C;\n  ((C) => {\n    class Class {\n    }\n    C.Class = Class;\n  })(C || (C = {}));\n  let D;\n  ((D) => {\n    class Class {\n    }\n  })(D || (D = {}));\n})(A || (A = {}));\n`)\n\n\texpectPrintedTS(t, `\n\t\tnamespace A {\n\t\t\texport namespace B {\n\t\t\t\texport enum Enum {}\n\t\t\t}\n\t\t\tnamespace C {\n\t\t\t\texport enum Enum {}\n\t\t\t}\n\t\t\tnamespace D {\n\t\t\t\tenum Enum {}\n\t\t\t}\n\t\t}\n\t`, `var A;\n((A) => {\n  let B;\n  ((B) => {\n    let Enum;\n    ((Enum) => {\n    })(Enum = B.Enum || (B.Enum = {}));\n  })(B = A.B || (A.B = {}));\n  let C;\n  ((C) => {\n    let Enum;\n    ((Enum) => {\n    })(Enum = C.Enum || (C.Enum = {}));\n  })(C || (C = {}));\n  let D;\n  ((D) => {\n    let Enum;\n    ((Enum) => {\n    })(Enum || (Enum = {}));\n  })(D || (D = {}));\n})(A || (A = {}));\n`)\n\n\texpectPrintedTS(t, `\n\t\tnamespace A {\n\t\t\texport namespace B {\n\t\t\t\texport let foo = 1\n\t\t\t\tfoo += foo\n\t\t\t}\n\t\t\tnamespace C {\n\t\t\t\texport let foo = 1\n\t\t\t\tfoo += foo\n\t\t\t}\n\t\t\tnamespace D {\n\t\t\t\tlet foo = 1\n\t\t\t\tfoo += foo\n\t\t\t}\n\t\t}\n\t`, `var A;\n((A) => {\n  let B;\n  ((B) => {\n    B.foo = 1;\n    B.foo += B.foo;\n  })(B = A.B || (A.B = {}));\n  let C;\n  ((C) => {\n    C.foo = 1;\n    C.foo += C.foo;\n  })(C || (C = {}));\n  let D;\n  ((D) => {\n    let foo = 1;\n    foo += foo;\n  })(D || (D = {}));\n})(A || (A = {}));\n`)\n\n\texpectPrintedTS(t, `\n\t\tnamespace A {\n\t\t\texport namespace B {\n\t\t\t\texport const foo = 1\n\t\t\t}\n\t\t\tnamespace C {\n\t\t\t\texport const foo = 1\n\t\t\t}\n\t\t\tnamespace D {\n\t\t\t\tconst foo = 1\n\t\t\t}\n\t\t}\n\t`, `var A;\n((A) => {\n  let B;\n  ((B) => {\n    B.foo = 1;\n  })(B = A.B || (A.B = {}));\n  let C;\n  ((C) => {\n    C.foo = 1;\n  })(C || (C = {}));\n  let D;\n  ((D) => {\n    const foo = 1;\n  })(D || (D = {}));\n})(A || (A = {}));\n`)\n\n\texpectPrintedTS(t, `\n\t\tnamespace A {\n\t\t\texport namespace B {\n\t\t\t\texport var foo = 1\n\t\t\t\tfoo += foo\n\t\t\t}\n\t\t\tnamespace C {\n\t\t\t\texport var foo = 1\n\t\t\t\tfoo += foo\n\t\t\t}\n\t\t\tnamespace D {\n\t\t\t\tvar foo = 1\n\t\t\t\tfoo += foo\n\t\t\t}\n\t\t}\n\t`, `var A;\n((A) => {\n  let B;\n  ((B) => {\n    B.foo = 1;\n    B.foo += B.foo;\n  })(B = A.B || (A.B = {}));\n  let C;\n  ((C) => {\n    C.foo = 1;\n    C.foo += C.foo;\n  })(C || (C = {}));\n  let D;\n  ((D) => {\n    var foo = 1;\n    foo += foo;\n  })(D || (D = {}));\n})(A || (A = {}));\n`)\n\n\texpectPrintedTS(t, `\n\t\tnamespace ns {\n\t\t\texport declare const L1\n\t\t\tconsole.log(L1)\n\n\t\t\texport declare let [[L2 = x, { [y]: L3 }]]\n\t\t\tconsole.log(L2, L3)\n\n\t\t\texport declare function F()\n\t\t\tconsole.log(F)\n\n\t\t\texport declare function F2() { }\n\t\t\tconsole.log(F2)\n\n\t\t\texport declare class C { }\n\t\t\tconsole.log(C)\n\n\t\t\texport declare enum E { }\n\t\t\tconsole.log(E)\n\n\t\t\texport declare namespace N { }\n\t\t\tconsole.log(N)\n\t\t}\n\t`, `var ns;\n((ns) => {\n  console.log(ns.L1);\n  console.log(ns.L2, ns.L3);\n  console.log(F);\n  console.log(F2);\n  console.log(C);\n  console.log(E);\n  console.log(N);\n})(ns || (ns = {}));\n`)\n\n\texpectPrintedTS(t, `\n\t\tnamespace a { export var a = 123; log(a) }\n\t\tnamespace b { export let b = 123; log(b) }\n\t\tnamespace c { export enum c {} log(c) }\n\t\tnamespace d { export class d {} log(d) }\n\t\tnamespace e { export namespace e {} log(e) }\n\t\tnamespace f { export function f() {} log(f) }\n\t`, `var a;\n((_a) => {\n  _a.a = 123;\n  log(_a.a);\n})(a || (a = {}));\nvar b;\n((_b) => {\n  _b.b = 123;\n  log(_b.b);\n})(b || (b = {}));\nvar c;\n((_c) => {\n  let c;\n  ((c) => {\n  })(c = _c.c || (_c.c = {}));\n  log(c);\n})(c || (c = {}));\nvar d;\n((_d) => {\n  class d {\n  }\n  _d.d = d;\n  log(d);\n})(d || (d = {}));\nvar e;\n((e) => {\n  log(e);\n})(e || (e = {}));\nvar f;\n((_f) => {\n  function f() {\n  }\n  _f.f = f;\n  log(f);\n})(f || (f = {}));\n`)\n\n\texpectPrintedTS(t, `\n\t\tnamespace a { export declare var a }\n\t\tnamespace b { export declare let b }\n\t\tnamespace c { export declare enum c {} }\n\t\tnamespace d { export declare class d {} }\n\t\tnamespace e { export declare namespace e {} }\n\t\tnamespace f { export declare function f() {} }\n\t`, `var a;\n((_a) => {\n})(a || (a = {}));\nvar b;\n((_b) => {\n})(b || (b = {}));\nvar c;\n((c) => {\n})(c || (c = {}));\nvar d;\n((d) => {\n})(d || (d = {}));\nvar f;\n((f) => {\n})(f || (f = {}));\n`)\n}\n\nfunc TestTSNamespaceDestructuring(t *testing.T) {\n\texpectPrintedTS(t, `\n\t\tnamespace A {\n\t\t\texport var [\n\t\t\t\ta,\n\t\t\t\t[, b = c, ...d],\n\t\t\t\t{[x]: [[y]] = z, ...o},\n\t\t\t] = ref\n\t\t}\n\t`, `var A;\n((A) => {\n  [\n    A.a,\n    [, A.b = c, ...A.d],\n    { [x]: [[A.y]] = z, ...A.o }\n  ] = ref;\n})(A || (A = {}));\n`)\n}\n\nfunc TestTSEnum(t *testing.T) {\n\texpectParseErrorTS(t, \"enum x { y z }\", \"<stdin>: ERROR: Expected \\\",\\\" after \\\"y\\\" in enum\\n\")\n\texpectParseErrorTS(t, \"enum x { 'y' 'z' }\", \"<stdin>: ERROR: Expected \\\",\\\" after \\\"y\\\" in enum\\n\")\n\texpectParseErrorTS(t, \"enum x { y = 0 z }\", \"<stdin>: ERROR: Expected \\\",\\\" before \\\"z\\\" in enum\\n\")\n\texpectParseErrorTS(t, \"enum x { 'y' = 0 'z' }\", \"<stdin>: ERROR: Expected \\\",\\\" before \\\"z\\\" in enum\\n\")\n\n\t// Check ES5 emit\n\texpectPrintedTargetTS(t, 5, \"enum x { y = 1 }\", \"var x = /* @__PURE__ */ function(x) {\\n  x[x[\\\"y\\\"] = 1] = \\\"y\\\";\\n  return x;\\n}(x || {});\\n\")\n\texpectPrintedTargetTS(t, 2015, \"enum x { y = 1 }\", \"var x = /* @__PURE__ */ ((x) => {\\n  x[x[\\\"y\\\"] = 1] = \\\"y\\\";\\n  return x;\\n})(x || {});\\n\")\n\n\t// Certain syntax isn't allowed inside an enum block\n\texpectParseErrorTS(t, \"enum x { y = this }\", \"<stdin>: ERROR: Cannot use \\\"this\\\" here:\\n\")\n\texpectParseErrorTS(t, \"enum x { y = () => this }\", \"<stdin>: ERROR: Cannot use \\\"this\\\" here:\\n\")\n\texpectParseErrorTS(t, \"enum x { y = function() { this } }\", \"\")\n\n\texpectPrintedTS(t, \"enum Foo { A, B }\", `var Foo = /* @__PURE__ */ ((Foo) => {\n  Foo[Foo[\"A\"] = 0] = \"A\";\n  Foo[Foo[\"B\"] = 1] = \"B\";\n  return Foo;\n})(Foo || {});\n`)\n\texpectPrintedTS(t, \"export enum Foo { A; B }\", `export var Foo = /* @__PURE__ */ ((Foo) => {\n  Foo[Foo[\"A\"] = 0] = \"A\";\n  Foo[Foo[\"B\"] = 1] = \"B\";\n  return Foo;\n})(Foo || {});\n`)\n\texpectPrintedTS(t, \"enum Foo { A, B, C = 3.3, D, E }\", `var Foo = /* @__PURE__ */ ((Foo) => {\n  Foo[Foo[\"A\"] = 0] = \"A\";\n  Foo[Foo[\"B\"] = 1] = \"B\";\n  Foo[Foo[\"C\"] = 3.3] = \"C\";\n  Foo[Foo[\"D\"] = 4.3] = \"D\";\n  Foo[Foo[\"E\"] = 5.3] = \"E\";\n  return Foo;\n})(Foo || {});\n`)\n\texpectPrintedTS(t, \"enum Foo { A, B, C = 'x', D, E, F = `y`, G = `${z}`, H = tag`` }\", `var Foo = ((Foo) => {\n  Foo[Foo[\"A\"] = 0] = \"A\";\n  Foo[Foo[\"B\"] = 1] = \"B\";\n  Foo[\"C\"] = \"x\";\n  Foo[Foo[\"D\"] = void 0] = \"D\";\n  Foo[Foo[\"E\"] = void 0] = \"E\";\n  Foo[\"F\"] = `+\"`y`\"+`;\n  Foo[\"G\"] = `+\"`${z}`\"+`;\n  Foo[Foo[\"H\"] = tag`+\"``\"+`] = \"H\";\n  return Foo;\n})(Foo || {});\n`)\n\n\t// TypeScript allows splitting an enum into multiple blocks\n\texpectPrintedTS(t, \"enum Foo { A = 1 } enum Foo { B = 2 }\", `var Foo = /* @__PURE__ */ ((Foo) => {\n  Foo[Foo[\"A\"] = 1] = \"A\";\n  return Foo;\n})(Foo || {});\nvar Foo = /* @__PURE__ */ ((Foo) => {\n  Foo[Foo[\"B\"] = 2] = \"B\";\n  return Foo;\n})(Foo || {});\n`)\n\n\texpectPrintedTS(t, `\n\t\tenum Foo {\n\t\t\t'a' = 10.01,\n\t\t\t'a b' = 100,\n\t\t\tc = a + Foo.a + Foo['a b'],\n\t\t\td,\n\t\t\te = a + Foo.a + Foo['a b'] + Math.random(),\n\t\t\tf,\n\t\t}\n\t\tenum Bar {\n\t\t\ta = Foo.a\n\t\t}\n\t`, `var Foo = ((Foo) => {\n  Foo[Foo[\"a\"] = 10.01] = \"a\";\n  Foo[Foo[\"a b\"] = 100] = \"a b\";\n  Foo[Foo[\"c\"] = 120.02] = \"c\";\n  Foo[Foo[\"d\"] = 121.02] = \"d\";\n  Foo[Foo[\"e\"] = 120.02 + Math.random()] = \"e\";\n  Foo[Foo[\"f\"] = void 0] = \"f\";\n  return Foo;\n})(Foo || {});\nvar Bar = /* @__PURE__ */ ((Bar) => {\n  Bar[Bar[\"a\"] = 10.01 /* a */] = \"a\";\n  return Bar;\n})(Bar || {});\n`)\n\n\texpectPrintedTS(t, `\n\t\tenum Foo { A }\n\t\tx = [Foo.A, Foo?.A, Foo?.A()]\n\t\ty = [Foo['A'], Foo?.['A'], Foo?.['A']()]\n\t`, `var Foo = /* @__PURE__ */ ((Foo) => {\n  Foo[Foo[\"A\"] = 0] = \"A\";\n  return Foo;\n})(Foo || {});\nx = [0 /* A */, Foo?.A, Foo?.A()];\ny = [0 /* A */, Foo?.[\"A\"], Foo?.[\"A\"]()];\n`)\n\n\t// Check shadowing\n\texpectPrintedTS(t, \"enum Foo { Foo }\", `var Foo = /* @__PURE__ */ ((_Foo) => {\n  _Foo[_Foo[\"Foo\"] = 0] = \"Foo\";\n  return _Foo;\n})(Foo || {});\n`)\n\texpectPrintedTS(t, \"enum Foo { Bar = Foo }\", `var Foo = /* @__PURE__ */ ((Foo) => {\n  Foo[Foo[\"Bar\"] = Foo] = \"Bar\";\n  return Foo;\n})(Foo || {});\n`)\n\texpectPrintedTS(t, \"enum Foo { Foo = 1, Bar = Foo }\", `var Foo = /* @__PURE__ */ ((_Foo) => {\n  _Foo[_Foo[\"Foo\"] = 1] = \"Foo\";\n  _Foo[_Foo[\"Bar\"] = 1 /* Foo */] = \"Bar\";\n  return _Foo;\n})(Foo || {});\n`)\n\n\t// Check top-level \"var\" and nested \"let\"\n\texpectPrintedTS(t, \"enum a { b = 1 }\", \"var a = /* @__PURE__ */ ((a) => {\\n  a[a[\\\"b\\\"] = 1] = \\\"b\\\";\\n  return a;\\n})(a || {});\\n\")\n\texpectPrintedTS(t, \"{ enum a { b = 1 } }\", \"{\\n  let a;\\n  ((a) => {\\n    a[a[\\\"b\\\"] = 1] = \\\"b\\\";\\n  })(a || (a = {}));\\n}\\n\")\n\n\t// Check \"await\" and \"yield\"\n\texpectPrintedTS(t, \"enum x { await = 1, y = await }\", `var x = /* @__PURE__ */ ((x) => {\n  x[x[\"await\"] = 1] = \"await\";\n  x[x[\"y\"] = 1 /* await */] = \"y\";\n  return x;\n})(x || {});\n`)\n\texpectPrintedTS(t, \"enum x { yield = 1, y = yield }\", `var x = /* @__PURE__ */ ((x) => {\n  x[x[\"yield\"] = 1] = \"yield\";\n  x[x[\"y\"] = 1 /* yield */] = \"y\";\n  return x;\n})(x || {});\n`)\n\texpectParseErrorTS(t, \"enum x { y = await 1 }\", \"<stdin>: ERROR: \\\"await\\\" can only be used inside an \\\"async\\\" function\\n\")\n\texpectParseErrorTS(t, \"function *f() { enum x { y = yield 1 } }\", \"<stdin>: ERROR: Cannot use \\\"yield\\\" outside a generator function\\n\")\n\texpectParseErrorTS(t, \"async function f() { enum x { y = await 1 } }\", \"<stdin>: ERROR: \\\"await\\\" can only be used inside an \\\"async\\\" function\\n\")\n\texpectParseErrorTS(t, \"export enum x { yield = 1, y = yield }\",\n\t\t\"<stdin>: ERROR: \\\"yield\\\" is a reserved word and cannot be used in an ECMAScript module\\n\"+\n\t\t\t\"<stdin>: NOTE: This file is considered to be an ECMAScript module because of the \\\"export\\\" keyword here:\\n\")\n\n\t// Check enum use before declaration\n\texpectPrintedTS(t, \"foo = Foo.FOO; enum Foo { FOO } bar = Foo.FOO\", `foo = 0 /* FOO */;\nvar Foo = /* @__PURE__ */ ((Foo) => {\n  Foo[Foo[\"FOO\"] = 0] = \"FOO\";\n  return Foo;\n})(Foo || {});\nbar = 0 /* FOO */;\n`)\n\n\t// https://github.com/evanw/esbuild/issues/3205\n\texpectPrintedTS(t, \"() => { const enum Foo { A } () => Foo.A }\", `() => {\n  let Foo;\n  ((Foo) => {\n    Foo[Foo[\"A\"] = 0] = \"A\";\n  })(Foo || (Foo = {}));\n  () => 0 /* A */;\n};\n`)\n}\n\nfunc TestTSEnumConstantFolding(t *testing.T) {\n\texpectPrintedTS(t, `\n\t\tenum Foo {\n\t\t\tadd = 1 + 2,\n\t\t\tsub = -1 - 2,\n\t\t\tmul = 10 * 20,\n\n\t\t\tdiv_pos_inf = 1 / 0,\n\t\t\tdiv_neg_inf = 1 / -0,\n\t\t\tdiv_nan = 0 / 0,\n\t\t\tdiv_neg_zero = 1 / (1 / -0),\n\n\t\t\tdiv0 = 10 / 20,\n\t\t\tdiv1 = 10 / -20,\n\t\t\tdiv2 = -10 / 20,\n\t\t\tdiv3 = -10 / -20,\n\n\t\t\tmod0 = 123 % 100,\n\t\t\tmod1 = 123 % -100,\n\t\t\tmod2 = -123 % 100,\n\t\t\tmod3 = -123 % -100,\n\n\t\t\tfmod0 = 1.375 % 0.75,\n\t\t\tfmod1 = 1.375 % -0.75,\n\t\t\tfmod2 = -1.375 % 0.75,\n\t\t\tfmod3 = -1.375 % -0.75,\n\n\t\t\tpow0 = 2.25 ** 3,\n\t\t\tpow1 = 2.25 ** -3,\n\t\t\tpow2 = (-2.25) ** 3,\n\t\t\tpow3 = (-2.25) ** -3,\n\t\t}\n\t`, `var Foo = /* @__PURE__ */ ((Foo) => {\n  Foo[Foo[\"add\"] = 3] = \"add\";\n  Foo[Foo[\"sub\"] = -3] = \"sub\";\n  Foo[Foo[\"mul\"] = 200] = \"mul\";\n  Foo[Foo[\"div_pos_inf\"] = Infinity] = \"div_pos_inf\";\n  Foo[Foo[\"div_neg_inf\"] = -Infinity] = \"div_neg_inf\";\n  Foo[Foo[\"div_nan\"] = NaN] = \"div_nan\";\n  Foo[Foo[\"div_neg_zero\"] = -0] = \"div_neg_zero\";\n  Foo[Foo[\"div0\"] = 0.5] = \"div0\";\n  Foo[Foo[\"div1\"] = -0.5] = \"div1\";\n  Foo[Foo[\"div2\"] = -0.5] = \"div2\";\n  Foo[Foo[\"div3\"] = 0.5] = \"div3\";\n  Foo[Foo[\"mod0\"] = 23] = \"mod0\";\n  Foo[Foo[\"mod1\"] = 23] = \"mod1\";\n  Foo[Foo[\"mod2\"] = -23] = \"mod2\";\n  Foo[Foo[\"mod3\"] = -23] = \"mod3\";\n  Foo[Foo[\"fmod0\"] = 0.625] = \"fmod0\";\n  Foo[Foo[\"fmod1\"] = 0.625] = \"fmod1\";\n  Foo[Foo[\"fmod2\"] = -0.625] = \"fmod2\";\n  Foo[Foo[\"fmod3\"] = -0.625] = \"fmod3\";\n  Foo[Foo[\"pow0\"] = 11.390625] = \"pow0\";\n  Foo[Foo[\"pow1\"] = 0.0877914951989026] = \"pow1\";\n  Foo[Foo[\"pow2\"] = -11.390625] = \"pow2\";\n  Foo[Foo[\"pow3\"] = -0.0877914951989026] = \"pow3\";\n  return Foo;\n})(Foo || {});\n`)\n\n\texpectPrintedTS(t, `\n\t\tenum Foo {\n\t\t\tpos = +54321012345,\n\t\t\tneg = -54321012345,\n\t\t\tcpl = ~54321012345,\n\n\t\t\tshl0 = 987654321 << 2,\n\t\t\tshl1 = 987654321 << 31,\n\t\t\tshl2 = 987654321 << 34,\n\n\t\t\tshr0 = -987654321 >> 2,\n\t\t\tshr1 = -987654321 >> 31,\n\t\t\tshr2 = -987654321 >> 34,\n\n\t\t\tushr0 = -987654321 >>> 2,\n\t\t\tushr1 = -987654321 >>> 31,\n\t\t\tushr2 = -987654321 >>> 34,\n\n\t\t\tbitand = 0xDEADF00D & 0xBADCAFE,\n\t\t\tbitor = 0xDEADF00D | 0xBADCAFE,\n\t\t\tbitxor = 0xDEADF00D ^ 0xBADCAFE,\n\t\t}\n\t`, `var Foo = /* @__PURE__ */ ((Foo) => {\n  Foo[Foo[\"pos\"] = 54321012345] = \"pos\";\n  Foo[Foo[\"neg\"] = -54321012345] = \"neg\";\n  Foo[Foo[\"cpl\"] = 1513562502] = \"cpl\";\n  Foo[Foo[\"shl0\"] = -344350012] = \"shl0\";\n  Foo[Foo[\"shl1\"] = -2147483648] = \"shl1\";\n  Foo[Foo[\"shl2\"] = -344350012] = \"shl2\";\n  Foo[Foo[\"shr0\"] = -246913581] = \"shr0\";\n  Foo[Foo[\"shr1\"] = -1] = \"shr1\";\n  Foo[Foo[\"shr2\"] = -246913581] = \"shr2\";\n  Foo[Foo[\"ushr0\"] = 826828243] = \"ushr0\";\n  Foo[Foo[\"ushr1\"] = 1] = \"ushr1\";\n  Foo[Foo[\"ushr2\"] = 826828243] = \"ushr2\";\n  Foo[Foo[\"bitand\"] = 179159052] = \"bitand\";\n  Foo[Foo[\"bitor\"] = -542246145] = \"bitor\";\n  Foo[Foo[\"bitxor\"] = -721405197] = \"bitxor\";\n  return Foo;\n})(Foo || {});\n`)\n}\n\nfunc TestTSFunction(t *testing.T) {\n\texpectPrintedTS(t, \"function foo(): void; function foo(): void {}\", \"function foo() {\\n}\\n\")\n\n\texpectPrintedTS(t, \"function foo<A>() {}\", \"function foo() {\\n}\\n\")\n\texpectPrintedTS(t, \"function foo<A extends B<A>>() {}\", \"function foo() {\\n}\\n\")\n\texpectPrintedTS(t, \"function foo<A extends B<C<A>>>() {}\", \"function foo() {\\n}\\n\")\n\texpectPrintedTS(t, \"function foo<A,B,C,>() {}\", \"function foo() {\\n}\\n\")\n\texpectPrintedTS(t, \"function foo<A extends B<C>= B<C>>() {}\", \"function foo() {\\n}\\n\")\n\texpectPrintedTS(t, \"function foo<A extends B<C<D>>= B<C<D>>>() {}\", \"function foo() {\\n}\\n\")\n\texpectPrintedTS(t, \"function foo<A extends B<C<D<E>>>= B<C<D<E>>>>() {}\", \"function foo() {\\n}\\n\")\n\n\texpectParseErrorTS(t, \"function foo<>() {}\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"function foo<,>() {}\", \"<stdin>: ERROR: Expected identifier but found \\\",\\\"\\n\")\n\texpectParseErrorTS(t, \"function foo<T><T>() {}\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"<\\\"\\n\")\n\n\texpectPrintedTS(t, \"export default function <T>() {}\", \"export default function() {\\n}\\n\")\n\texpectParseErrorTS(t, \"export default function <>() {}\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"export default function <,>() {}\", \"<stdin>: ERROR: Expected identifier but found \\\",\\\"\\n\")\n\texpectParseErrorTS(t, \"export default function <T><T>() {}\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"<\\\"\\n\")\n\n\texpectPrintedTS(t, `\n\t\texport default function foo();\n\t\texport default function foo(x);\n\t\texport default function foo(x?, y?) {}\n\t`, \"export default function foo(x, y) {\\n}\\n\")\n}\n\nfunc TestTSDecl(t *testing.T) {\n\texpectPrintedTS(t, \"var a!: string, b!: boolean\", \"var a, b;\\n\")\n\texpectPrintedTS(t, \"let a!: string, b!: boolean\", \"let a, b;\\n\")\n\texpectPrintedTS(t, \"const a!: string = '', b!: boolean = false\", \"const a = \\\"\\\", b = false;\\n\")\n\texpectPrintedTS(t, \"var a\\n!b\", \"var a;\\n!b;\\n\")\n\texpectPrintedTS(t, \"let a\\n!b\", \"let a;\\n!b;\\n\")\n\texpectParseErrorTS(t, \"var a!\", \"<stdin>: ERROR: Expected \\\":\\\" but found end of file\\n\")\n\texpectParseErrorTS(t, \"var a! = \", \"<stdin>: ERROR: Expected \\\":\\\" but found \\\"=\\\"\\n\")\n\texpectParseErrorTS(t, \"var a!, b\", \"<stdin>: ERROR: Expected \\\":\\\" but found \\\",\\\"\\n\")\n\n\texpectPrinted(t, \"a ? ({b}) => {} : c\", \"a ? ({ b }) => {\\n} : c;\\n\")\n\texpectPrinted(t, \"a ? (({b}) => {}) : c\", \"a ? (({ b }) => {\\n}) : c;\\n\")\n\texpectPrinted(t, \"a ? (({b})) : c\", \"a ? { b } : c;\\n\")\n\texpectParseError(t, \"a ? (({b})) => {} : c\", \"<stdin>: ERROR: Invalid binding pattern\\n\")\n\texpectPrintedTS(t, \"a ? ({b}) => {} : c\", \"a ? ({ b }) => {\\n} : c;\\n\")\n\texpectPrintedTS(t, \"a ? (({b}) => {}) : c\", \"a ? (({ b }) => {\\n}) : c;\\n\")\n\texpectPrintedTS(t, \"a ? (({b})) : c\", \"a ? { b } : c;\\n\")\n\texpectParseErrorTS(t, \"a ? (({b})) => {} : c\", \"<stdin>: ERROR: Invalid binding pattern\\n\")\n}\n\nfunc TestTSDeclare(t *testing.T) {\n\texpectPrintedTS(t, \"declare\\nfoo\", \"declare;\\nfoo;\\n\")\n\texpectPrintedTS(t, \"declare\\nvar foo\", \"declare;\\nvar foo;\\n\")\n\texpectPrintedTS(t, \"declare\\nlet foo\", \"declare;\\nlet foo;\\n\")\n\texpectPrintedTS(t, \"declare\\nconst foo = 0\", \"declare;\\nconst foo = 0;\\n\")\n\texpectPrintedTS(t, \"declare\\nfunction foo() {}\", \"declare;\\nfunction foo() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare\\nclass Foo {}\", \"declare;\\nclass Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"declare\\nenum Foo {}\", \"declare;\\nvar Foo = /* @__PURE__ */ ((Foo) => {\\n  return Foo;\\n})(Foo || {});\\n\")\n\texpectPrintedTS(t, \"class Foo { declare \\n foo }\", \"class Foo {\\n  declare;\\n  foo;\\n}\\n\")\n\n\texpectPrintedTS(t, \"declare;\", \"declare;\\n\")\n\texpectPrintedTS(t, \"declare();\", \"declare();\\n\")\n\texpectPrintedTS(t, \"declare[x];\", \"declare[x];\\n\")\n\n\texpectPrintedTS(t, \"declare var x: number\", \"\")\n\texpectPrintedTS(t, \"declare let x: number\", \"\")\n\texpectPrintedTS(t, \"declare const x: number\", \"\")\n\texpectPrintedTS(t, \"declare var x = function() {}; function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare let x = function() {}; function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare const x = function() {}; function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare function fn(); function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare function fn()\\n function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare function fn() {} function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare enum X {} function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare enum X { x = function() {} } function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare class X {} function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare class X { x = function() {} } function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare interface X {} function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare namespace X {} function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare namespace X { export var x = function() {} } function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare namespace X { export let x = function() {} } function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare namespace X { export const x = function() {} } function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare namespace X { export function fn() {} } function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare module X {} function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare module 'X' {} function scope() {}\", \"function scope() {\\n}\\n\")\n\texpectPrintedTS(t, \"declare module 'X'; let foo\", \"let foo;\\n\")\n\texpectPrintedTS(t, \"declare module 'X'\\nlet foo\", \"let foo;\\n\")\n\texpectPrintedTS(t, \"declare module 'X' { let foo }\", \"\")\n\texpectPrintedTS(t, \"declare module 'X'\\n{ let foo }\", \"\")\n\texpectPrintedTS(t, \"declare global { interface Foo {} let foo: any } let bar\", \"let bar;\\n\")\n\texpectPrintedTS(t, \"declare module M { const x }\", \"\")\n\texpectPrintedTS(t, \"declare module M { global { const x } }\", \"\")\n\texpectPrintedTS(t, \"declare module M { global { const x } function foo() {} }\", \"\")\n\texpectPrintedTS(t, \"declare module M { global \\n { const x } }\", \"\")\n\texpectPrintedTS(t, \"declare module M { import 'path' }\", \"\")\n\texpectPrintedTS(t, \"declare module M { import x from 'path' }\", \"\")\n\texpectPrintedTS(t, \"declare module M { import {x} from 'path' }\", \"\")\n\texpectPrintedTS(t, \"declare module M { import * as ns from 'path' }\", \"\")\n\texpectPrintedTS(t, \"declare module M { import foo = bar }\", \"\")\n\texpectPrintedTS(t, \"declare module M { export import foo = bar }\", \"\")\n\texpectPrintedTS(t, \"declare module M { export {x} from 'path' }\", \"\")\n\texpectPrintedTS(t, \"declare module M { export default 123 }\", \"\")\n\texpectPrintedTS(t, \"declare module M { export default function x() {} }\", \"\")\n\texpectPrintedTS(t, \"declare module M { export default class X {} }\", \"\")\n\texpectPrintedTS(t, \"declare module M { export * as ns from 'path' }\", \"\")\n\texpectPrintedTS(t, \"declare module M { export * from 'path' }\", \"\")\n\texpectPrintedTS(t, \"declare module M { export = foo }\", \"\")\n\texpectPrintedTS(t, \"declare module M { export as namespace ns }\", \"\")\n\texpectPrintedTS(t, \"declare module M { export as namespace ns; }\", \"\")\n\texpectParseErrorTS(t, \"declare module M { export as namespace ns.foo }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\".\\\"\\n\")\n\texpectParseErrorTS(t, \"declare module M { export as namespace ns function foo() {} }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"function\\\"\\n\")\n\texpectParseErrorTS(t, \"module M { const x }\", \"<stdin>: ERROR: The constant \\\"x\\\" must be initialized\\n\")\n\texpectParseErrorTS(t, \"module M { const [] }\", \"<stdin>: ERROR: This constant must be initialized\\n\")\n\texpectParseErrorTS(t, \"module M { const {} }\", \"<stdin>: ERROR: This constant must be initialized\\n\")\n\n\t// This is a weird case where \",\" after a rest parameter is allowed\n\texpectPrintedTS(t, \"declare function fn(x: any, ...y, )\", \"\")\n\texpectPrintedTS(t, \"declare function fn(x: any, ...y: any, )\", \"\")\n\texpectParseErrorTS(t, \"function fn(x: any, ...y, )\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\",\\\"\\n\")\n\texpectParseErrorTS(t, \"function fn(x: any, ...y, ) {}\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\",\\\"\\n\")\n\texpectParseErrorTS(t, \"function fn(x: any, ...y: any, )\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\",\\\"\\n\")\n\texpectParseErrorTS(t, \"function fn(x: any, ...y: any, ) {}\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\",\\\"\\n\")\n\n\t// This declares a global module\n\texpectPrintedTS(t, \"export as namespace ns\", \"\")\n\texpectParseErrorTS(t, \"export as namespace ns.foo\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\".\\\"\\n\")\n\n\t// TypeScript 4.4+ technically treats these as valid syntax, but I assume\n\t// this is a bug: https://github.com/microsoft/TypeScript/issues/54602\n\texpectParseErrorTS(t, \"declare foo\", \"<stdin>: ERROR: Unexpected \\\"foo\\\"\\n\")\n\texpectParseErrorTS(t, \"declare foo()\", \"<stdin>: ERROR: Unexpected \\\"foo\\\"\\n\")\n\texpectParseErrorTS(t, \"declare {foo}\", \"<stdin>: ERROR: Unexpected \\\"{\\\"\\n\")\n}\n\nfunc TestTSExperimentalDecorator(t *testing.T) {\n\t// Tests of \"declare class\"\n\texpectPrintedExperimentalDecoratorTS(t, \"@dec(() => 0) declare class Foo {} {let foo}\", \"{\\n  let foo;\\n}\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"@dec(() => 0) declare abstract class Foo {} {let foo}\", \"{\\n  let foo;\\n}\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"@dec(() => 0) export declare class Foo {} {let foo}\", \"{\\n  let foo;\\n}\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"@dec(() => 0) export declare abstract class Foo {} {let foo}\", \"{\\n  let foo;\\n}\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"declare class Foo { @dec(() => 0) foo } {let foo}\", \"{\\n  let foo;\\n}\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"declare class Foo { @dec(() => 0) foo() } {let foo}\", \"{\\n  let foo;\\n}\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"declare class Foo { foo(@dec(() => 0) x) } {let foo}\", \"{\\n  let foo;\\n}\\n\")\n\n\t// Decorators must only work on class statements\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec enum foo {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec namespace foo {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec function foo() {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec abstract\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec declare: x\", \"<stdin>: ERROR: Unexpected \\\":\\\"\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec declare enum foo {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec declare namespace foo {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec declare function foo()\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec export {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec export enum foo {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec export namespace foo {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec export function foo() {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec export default abstract\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec export declare enum foo {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec export declare namespace foo {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@dec export declare function foo()\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\n\t// Decorators must be forbidden outside class statements\n\tnote := \"<stdin>: NOTE: This is a class expression, not a class declaration:\\n\"\n\texpectParseErrorExperimentalDecoratorTS(t, \"(class { @dec foo })\", \"<stdin>: ERROR: TypeScript experimental decorators can only be used with class declarations\\n\"+note)\n\texpectParseErrorExperimentalDecoratorTS(t, \"(class { @dec foo() {} })\", \"<stdin>: ERROR: TypeScript experimental decorators can only be used with class declarations\\n\"+note)\n\texpectParseErrorExperimentalDecoratorTS(t, \"(class { foo(@dec x) {} })\", \"<stdin>: ERROR: TypeScript experimental decorators can only be used with class declarations\\n\"+note)\n\texpectParseErrorExperimentalDecoratorTS(t, \"({ @dec foo })\", \"<stdin>: ERROR: Expected identifier but found \\\"@\\\"\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"({ @dec foo() {} })\", \"<stdin>: ERROR: Expected identifier but found \\\"@\\\"\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"({ foo(@dec x) {} })\", \"<stdin>: ERROR: Expected identifier but found \\\"@\\\"\\n\")\n\n\t// Decorators aren't allowed with private names\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec #foo }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec #foo = 1 }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec #foo() {} }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec *#foo() {} }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec async #foo() {} }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec async* #foo() {} }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec accessor #foo }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec static #foo }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec static #foo = 1 }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec static #foo() {} }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec static *#foo() {} }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec static async #foo() {} }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec static async* #foo() {} }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec static accessor #foo }\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used on private identifiers\\n\")\n\n\t// Decorators aren't allowed on class constructors\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec constructor() {} }\", \"<stdin>: ERROR: Decorators are not allowed on class constructors\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec public constructor() {} }\", \"<stdin>: ERROR: Decorators are not allowed on class constructors\\n\")\n\n\t// Check use of \"await\"\n\tfriendlyAwaitErrorWithNote := \"<stdin>: ERROR: \\\"await\\\" can only be used inside an \\\"async\\\" function\\n\" +\n\t\t\"<stdin>: NOTE: Consider adding the \\\"async\\\" keyword here:\\n\"\n\texpectPrintedExperimentalDecoratorTS(t, \"async function foo() { @dec(await x) class Foo {} }\",\n\t\t\"async function foo() {\\n  let Foo = class {\\n  };\\n  Foo = __decorateClass([\\n    dec(await x)\\n  ], Foo);\\n}\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"async function foo() { class Foo { @dec(await x) foo() {} } }\",\n\t\t\"async function foo() {\\n  class Foo {\\n    foo() {\\n    }\\n  }\\n  __decorateClass([\\n    dec(await x)\\n  ], Foo.prototype, \\\"foo\\\", 1);\\n}\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"async function foo() { class Foo { foo(@dec(await x) y) {} } }\",\n\t\t\"async function foo() {\\n  class Foo {\\n    foo(y) {\\n    }\\n  }\\n  __decorateClass([\\n    __decorateParam(0, dec(await x))\\n  ], Foo.prototype, \\\"foo\\\", 1);\\n}\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"function foo() { @dec(await x) class Foo {} }\", friendlyAwaitErrorWithNote)\n\texpectParseErrorExperimentalDecoratorTS(t, \"function foo() { class Foo { @dec(await x) foo() {} } }\", friendlyAwaitErrorWithNote)\n\texpectParseErrorExperimentalDecoratorTS(t, \"function foo() { class Foo { foo(@dec(await x) y) {} } }\", friendlyAwaitErrorWithNote)\n\texpectParseErrorExperimentalDecoratorTS(t, \"function foo() { class Foo { @dec(await x) async foo() {} } }\", friendlyAwaitErrorWithNote)\n\texpectParseErrorExperimentalDecoratorTS(t, \"function foo() { class Foo { async foo(@dec(await x) y) {} } }\",\n\t\t\"<stdin>: ERROR: The keyword \\\"await\\\" cannot be used here:\\n<stdin>: ERROR: Expected \\\")\\\" but found \\\"x\\\"\\n\")\n\n\t// Check lowered use of \"await\"\n\texpectPrintedTargetExperimentalDecoratorTS(t, 2015, \"async function foo() { @dec(await x) class Foo {} }\",\n\t\t`function foo() {\n  return __async(this, null, function* () {\n    let Foo = class {\n    };\n    Foo = __decorateClass([\n      dec(yield x)\n    ], Foo);\n  });\n}\n`)\n\texpectPrintedTargetExperimentalDecoratorTS(t, 2015, \"async function foo() { class Foo { @dec(await x) foo() {} } }\",\n\t\t`function foo() {\n  return __async(this, null, function* () {\n    class Foo {\n      foo() {\n      }\n    }\n    __decorateClass([\n      dec(yield x)\n    ], Foo.prototype, \"foo\", 1);\n  });\n}\n`)\n\texpectPrintedTargetExperimentalDecoratorTS(t, 2015, \"async function foo() { class Foo { foo(@dec(await x) y) {} } }\",\n\t\t`function foo() {\n  return __async(this, null, function* () {\n    class Foo {\n      foo(y) {\n      }\n    }\n    __decorateClass([\n      __decorateParam(0, dec(yield x))\n    ], Foo.prototype, \"foo\", 1);\n  });\n}\n`)\n\n\t// Check use of \"yield\"\n\texpectPrintedExperimentalDecoratorTS(t, \"function *foo() { @dec(yield x) class Foo {} }\", // We currently allow this but TypeScript doesn't\n\t\t\"function* foo() {\\n  let Foo = class {\\n  };\\n  Foo = __decorateClass([\\n    dec(yield x)\\n  ], Foo);\\n}\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"function *foo() { class Foo { @dec(yield x) foo() {} } }\", // We currently allow this but TypeScript doesn't\n\t\t\"function* foo() {\\n  class Foo {\\n    foo() {\\n    }\\n  }\\n  __decorateClass([\\n    dec(yield x)\\n  ], Foo.prototype, \\\"foo\\\", 1);\\n}\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"function *foo() { class Foo { foo(@dec(yield x) y) {} } }\", // TypeScript doesn't allow this (although it could because it would work fine)\n\t\t\"<stdin>: ERROR: Cannot use \\\"yield\\\" outside a generator function\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"function foo() { @dec(yield x) class Foo {} }\", \"<stdin>: ERROR: Cannot use \\\"yield\\\" outside a generator function\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"function foo() { class Foo { @dec(yield x) foo() {} } }\", \"<stdin>: ERROR: Cannot use \\\"yield\\\" outside a generator function\\n\")\n\n\t// Check inline function expressions\n\texpectPrintedExperimentalDecoratorTS(t, \"@((x, y) => x + y) class Foo {}\",\n\t\t\"let Foo = class {\\n};\\nFoo = __decorateClass([\\n  (x, y) => x + y\\n], Foo);\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"@((x, y) => x + y) export class Foo {}\",\n\t\t\"export let Foo = class {\\n};\\nFoo = __decorateClass([\\n  (x, y) => x + y\\n], Foo);\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"@(function(x, y) { return x + y }) class Foo {}\",\n\t\t\"let Foo = class {\\n};\\nFoo = __decorateClass([\\n  function(x, y) {\\n    return x + y;\\n  }\\n], Foo);\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"@(function(x, y) { return x + y }) export class Foo {}\",\n\t\t\"export let Foo = class {\\n};\\nFoo = __decorateClass([\\n  function(x, y) {\\n    return x + y;\\n  }\\n], Foo);\\n\")\n\n\t// Don't allow decorators on static blocks\n\texpectPrintedTS(t, \"class Foo { static }\", \"class Foo {\\n  static;\\n}\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"class Foo { @dec static }\", \"class Foo {\\n  static;\\n}\\n__decorateClass([\\n  dec\\n], Foo.prototype, \\\"static\\\", 2);\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"class Foo { @dec static {} }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"{\\\"\\n\")\n\n\t// TypeScript experimental decorators allow more expressions than JavaScript decorators\n\texpectPrintedExperimentalDecoratorTS(t, \"@x() class Foo {}\", \"let Foo = class {\\n};\\nFoo = __decorateClass([\\n  x()\\n], Foo);\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"@x.y() class Foo {}\", \"let Foo = class {\\n};\\nFoo = __decorateClass([\\n  x.y()\\n], Foo);\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"@(() => {}) class Foo {}\", \"let Foo = class {\\n};\\nFoo = __decorateClass([\\n  () => {\\n  }\\n], Foo);\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"@123 class Foo {}\", \"let Foo = class {\\n};\\nFoo = __decorateClass([\\n  123\\n], Foo);\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"@x?.() class Foo {}\", \"let Foo = class {\\n};\\nFoo = __decorateClass([\\n  x?.()\\n], Foo);\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"@x?.y() class Foo {}\", \"let Foo = class {\\n};\\nFoo = __decorateClass([\\n  x?.y()\\n], Foo);\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"@x?.[y]() class Foo {}\", \"let Foo = class {\\n};\\nFoo = __decorateClass([\\n  x?.[y]()\\n], Foo);\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"@new Function() class Foo {}\", \"let Foo = class {\\n};\\nFoo = __decorateClass([\\n  new Function()\\n], Foo);\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@x[y] class Foo {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"class\\\"\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@() => {} class Foo {}\", \"<stdin>: ERROR: Unexpected \\\")\\\"\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"x = @y function() {}\",\n\t\t\"<stdin>: ERROR: TypeScript experimental decorators cannot be used in expression position\\n\"+\n\t\t\t\"<stdin>: ERROR: Expected \\\"class\\\" but found \\\"function\\\"\\n\")\n\n\t// Check ASI for \"abstract\"\n\texpectPrintedExperimentalDecoratorTS(t, \"@x abstract class Foo {}\", \"let Foo = class {\\n};\\nFoo = __decorateClass([\\n  x\\n], Foo);\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@x abstract\\nclass Foo {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\n\t// Check decorator locations in relation to the \"export\" keyword\n\texpectPrintedExperimentalDecoratorTS(t, \"@x export class Foo {}\", \"export let Foo = class {\\n};\\nFoo = __decorateClass([\\n  x\\n], Foo);\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"export @x class Foo {}\", \"export let Foo = class {\\n};\\nFoo = __decorateClass([\\n  x\\n], Foo);\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"@x export default class {}\",\n\t\t\"let stdin_default = class {\\n};\\nstdin_default = __decorateClass([\\n  x\\n], stdin_default);\\nexport {\\n  stdin_default as default\\n};\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"export default @x class {}\",\n\t\t\"let stdin_default = class {\\n};\\nstdin_default = __decorateClass([\\n  x\\n], stdin_default);\\nexport {\\n  stdin_default as default\\n};\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"@x export default class Foo {}\", \"let Foo = class {\\n};\\nFoo = __decorateClass([\\n  x\\n], Foo);\\nexport {\\n  Foo as default\\n};\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"export default @x class Foo {}\", \"let Foo = class {\\n};\\nFoo = __decorateClass([\\n  x\\n], Foo);\\nexport {\\n  Foo as default\\n};\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"export default (@x class {})\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used in expression position\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"export default (@x class Foo {})\", \"<stdin>: ERROR: TypeScript experimental decorators cannot be used in expression position\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"export @x default class {}\", \"<stdin>: ERROR: Unexpected \\\"default\\\"\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@x export @y class Foo {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@x export default abstract\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorExperimentalDecoratorTS(t, \"@x export @y default class {}\", \"<stdin>: ERROR: Decorators are not valid here\\n<stdin>: ERROR: Unexpected \\\"default\\\"\\n\")\n\n\t// From the TypeScript team: \"We do allow postfix ! because it's TypeScript only.\"\n\t// https://github.com/microsoft/TypeScript/issues/57756\n\texpectPrintedExperimentalDecoratorTS(t, \"@x!.y!.z class Foo {}\", \"let Foo = class {\\n};\\nFoo = __decorateClass([\\n  x.y.z\\n], Foo);\\n\")\n\n\t// TypeScript experimental decorators are actually allowed on declared and abstract fields\n\texpectPrintedExperimentalDecoratorTS(t, \"class Foo { @(() => {}) declare foo: any; @(() => {}) bar: any }\",\n\t\t\"class Foo {\\n  bar;\\n}\\n__decorateClass([\\n  () => {\\n  }\\n], Foo.prototype, \\\"foo\\\", 2);\\n__decorateClass([\\n  () => {\\n  }\\n], Foo.prototype, \\\"bar\\\", 2);\\n\")\n\texpectPrintedExperimentalDecoratorTS(t, \"abstract class Foo { @(() => {}) abstract foo: any; @(() => {}) bar: any }\",\n\t\t\"class Foo {\\n  bar;\\n}\\n__decorateClass([\\n  () => {\\n  }\\n], Foo.prototype, \\\"foo\\\", 2);\\n__decorateClass([\\n  () => {\\n  }\\n], Foo.prototype, \\\"bar\\\", 2);\\n\")\n}\n\nfunc TestTSDecorators(t *testing.T) {\n\texpectPrintedTS(t, \"@x @y class Foo {}\", \"@x @y class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"@x @y export class Foo {}\", \"@x @y export class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"@x @y export default class Foo {}\", \"@x @y export default class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"_ = @x @y class {}\", \"_ = @x @y class {\\n};\\n\")\n\n\texpectPrintedTS(t, \"class Foo { @x y: any }\", \"class Foo {\\n  @x y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { @x y(): any {} }\", \"class Foo {\\n  @x y() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { @x static y: any }\", \"class Foo {\\n  @x static y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { @x static y(): any {} }\", \"class Foo {\\n  @x static y() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { @x accessor y: any }\", \"class Foo {\\n  @x accessor y;\\n}\\n\")\n\n\texpectPrintedTS(t, \"class Foo { @x #y: any }\", \"class Foo {\\n  @x #y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { @x #y(): any {} }\", \"class Foo {\\n  @x #y() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { @x static #y: any }\", \"class Foo {\\n  @x static #y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { @x static #y(): any {} }\", \"class Foo {\\n  @x static #y() {\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { @x accessor #y: any }\", \"class Foo {\\n  @x accessor #y;\\n}\\n\")\n\n\texpectParseErrorTS(t, \"class Foo { x(@y z) {} }\", \"<stdin>: ERROR: Parameter decorators only work when experimental decorators are enabled\\n\"+\n\t\t\"NOTE: You can enable experimental decorators by adding \\\"experimentalDecorators\\\": true to your \\\"tsconfig.json\\\" file.\\n\")\n\texpectParseErrorTS(t, \"class Foo { @x static {} }\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"{\\\"\\n\")\n\n\texpectPrintedTS(t, \"@\\na\\n(\\n)\\n@\\n(\\nb\\n)\\nclass\\nFoo\\n{\\n}\\n\", \"@a()\\n@b\\nclass Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"@(a, b) class Foo {}\", \"@(a, b) class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"@x() class Foo {}\", \"@x() class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"@x.y() class Foo {}\", \"@x.y() class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"@(() => {}) class Foo {}\", \"@(() => {\\n}) class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { #x = @y.#x.y.#x class {} }\", \"class Foo {\\n  #x = @y.#x.y.#x class {\\n  };\\n}\\n\")\n\texpectParseErrorTS(t, \"@123 class Foo {}\", \"<stdin>: ERROR: Expected identifier but found \\\"123\\\"\\n\")\n\texpectParseErrorTS(t, \"@x[y] class Foo {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"class\\\"\\n\")\n\texpectParseErrorTS(t, \"@x?.() class Foo {}\", \"<stdin>: ERROR: Expected identifier but found \\\"(\\\"\\n\")\n\texpectParseErrorTS(t, \"@x?.y() class Foo {}\",\n\t\t\"<stdin>: ERROR: JavaScript decorator syntax does not allow \\\"?.\\\" here\\n\"+\n\t\t\t\"<stdin>: NOTE: Wrap this decorator in parentheses to allow arbitrary expressions:\\n\")\n\texpectParseErrorTS(t, \"@x?.[y]() class Foo {}\", \"<stdin>: ERROR: Expected identifier but found \\\"[\\\"\\n\")\n\texpectParseErrorTS(t, \"@new Function() class Foo {}\", \"<stdin>: ERROR: Expected identifier but found \\\"new\\\"\\n\")\n\texpectParseErrorTS(t, \"@() => {} class Foo {}\", \"<stdin>: ERROR: Unexpected \\\")\\\"\\n\")\n\texpectParseErrorTS(t, \"x = @y function() {}\", \"<stdin>: ERROR: Expected \\\"class\\\" but found \\\"function\\\"\\n\")\n\n\texpectPrintedTS(t, \"class Foo { @x<{}> y: any }\", \"class Foo {\\n  @x y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { @x<{}>() y: any }\", \"class Foo {\\n  @x() y;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { @x<{}> @y<[], () => {}> z: any }\", \"class Foo {\\n  @x @y z;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { @x<{}>() @y<[], () => {}>() z: any }\", \"class Foo {\\n  @x() @y() z;\\n}\\n\")\n\texpectPrintedTS(t, \"class Foo { @x<{}>.y<[], () => {}> z: any }\", \"class Foo {\\n  @x.y z;\\n}\\n\")\n\n\t// TypeScript 5.0+ allows this but Babel doesn't. I believe this is a bug\n\t// with TypeScript: https://github.com/microsoft/TypeScript/issues/55336\n\texpectParseErrorTS(t, \"class Foo { @x<{}>().y<[], () => {}>() z: any }\",\n\t\t\"<stdin>: ERROR: JavaScript decorator syntax does not allow \\\".\\\" after a call expression\\n\"+\n\t\t\t\"<stdin>: NOTE: Wrap this decorator in parentheses to allow arbitrary expressions:\\n\")\n\n\texpectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, \"@dec class Foo {}\",\n\t\t`var _Foo_decorators, _init;\n_Foo_decorators = [dec];\nclass Foo {\n}\n_init = __decoratorStart(null);\nFoo = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, Foo);\n__runInitializers(_init, 1, Foo);\n`)\n\texpectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, \"class Foo { @dec x }\",\n\t\t`var _x_dec, _init;\n_x_dec = [dec];\nclass Foo {\n  constructor() {\n    __publicField(this, \"x\", __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);\n  }\n}\n_init = __decoratorStart(null);\n__decorateElement(_init, 5, \"x\", _x_dec, Foo);\n__decoratorMetadata(_init, Foo);\n`)\n\texpectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, \"class Foo { @dec x() {} }\",\n\t\t`var _x_dec, _init;\n_x_dec = [dec];\nclass Foo {\n  constructor() {\n    __runInitializers(_init, 5, this);\n  }\n  x() {\n  }\n}\n_init = __decoratorStart(null);\n__decorateElement(_init, 1, \"x\", _x_dec, Foo);\n__decoratorMetadata(_init, Foo);\n`)\n\texpectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, \"class Foo { @dec accessor x }\",\n\t\t`var _x_dec, _init, _x;\n_x_dec = [dec];\nclass Foo {\n  constructor() {\n    __privateAdd(this, _x, __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);\n  }\n}\n_init = __decoratorStart(null);\n_x = new WeakMap();\n__decorateElement(_init, 4, \"x\", _x_dec, Foo, _x);\n__decoratorMetadata(_init, Foo);\n`)\n\texpectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, \"class Foo { @dec static x }\",\n\t\t`var _x_dec, _init;\n_x_dec = [dec];\nclass Foo {\n}\n_init = __decoratorStart(null);\n__decorateElement(_init, 13, \"x\", _x_dec, Foo);\n__decoratorMetadata(_init, Foo);\n__publicField(Foo, \"x\", __runInitializers(_init, 8, Foo)), __runInitializers(_init, 11, Foo);\n`)\n\texpectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, \"class Foo { @dec static x() {} }\",\n\t\t`var _x_dec, _init;\n_x_dec = [dec];\nclass Foo {\n  static x() {\n  }\n}\n_init = __decoratorStart(null);\n__decorateElement(_init, 9, \"x\", _x_dec, Foo);\n__decoratorMetadata(_init, Foo);\n__runInitializers(_init, 3, Foo);\n`)\n\texpectPrintedWithUnsupportedFeaturesTS(t, compat.Decorators, \"class Foo { @dec static accessor x }\",\n\t\t`var _x_dec, _init, _x;\n_x_dec = [dec];\nclass Foo {\n}\n_init = __decoratorStart(null);\n_x = new WeakMap();\n__decorateElement(_init, 12, \"x\", _x_dec, Foo, _x);\n__decoratorMetadata(_init, Foo);\n__privateAdd(Foo, _x, __runInitializers(_init, 8, Foo)), __runInitializers(_init, 11, Foo);\n`)\n\n\t// Check ASI for \"abstract\"\n\texpectPrintedTS(t, \"@x abstract class Foo {}\", \"@x class Foo {\\n}\\n\")\n\texpectParseErrorTS(t, \"@x abstract\\nclass Foo {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\n\t// Check decorator locations in relation to the \"export\" keyword\n\texpectPrintedTS(t, \"@x export class Foo {}\", \"@x export class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"export @x class Foo {}\", \"@x export class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"@x export default class {}\", \"@x export default class {\\n}\\n\")\n\texpectPrintedTS(t, \"export default @x class {}\", \"@x export default class {\\n}\\n\")\n\texpectPrintedTS(t, \"@x export default class Foo {}\", \"@x export default class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"export default @x class Foo {}\", \"@x export default class Foo {\\n}\\n\")\n\texpectPrintedTS(t, \"export default (@x class {})\", \"export default (@x class {\\n});\\n\")\n\texpectPrintedTS(t, \"export default (@x class Foo {})\", \"export default (@x class Foo {\\n});\\n\")\n\texpectParseErrorTS(t, \"export @x default class {}\", \"<stdin>: ERROR: Unexpected \\\"default\\\"\\n\")\n\texpectParseErrorTS(t, \"@x export @y class Foo {}\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorTS(t, \"@x export default abstract\", \"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorTS(t, \"@x export @y default class {}\", \"<stdin>: ERROR: Decorators are not valid here\\n<stdin>: ERROR: Unexpected \\\"default\\\"\\n\")\n\n\t// From the TypeScript team: \"We do allow postfix ! because it's TypeScript only.\"\n\t// https://github.com/microsoft/TypeScript/issues/57756\n\texpectPrintedTS(t, \"@x!.y!.z class Foo {}\", \"@x.y.z class Foo {\\n}\\n\")\n\n\t// JavaScript decorators are not allowed on declared or abstract fields\n\texpectParseErrorTS(t, \"class Foo { @(() => {}) declare foo: any; @(() => {}) bar: any }\",\n\t\t\"<stdin>: ERROR: Decorators are not valid here\\n\")\n\texpectParseErrorTS(t, \"abstract class Foo { @(() => {}) abstract foo: any; @(() => {}) bar: any }\",\n\t\t\"<stdin>: ERROR: Decorators are not valid here\\n\")\n}\n\nfunc TestTSTry(t *testing.T) {\n\texpectPrintedTS(t, \"try {} catch (x: any) {}\", \"try {\\n} catch (x) {\\n}\\n\")\n\texpectPrintedTS(t, \"try {} catch (x: unknown) {}\", \"try {\\n} catch (x) {\\n}\\n\")\n\texpectPrintedTS(t, \"try {} catch (x: number) {}\", \"try {\\n} catch (x) {\\n}\\n\")\n\n\texpectPrintedTS(t, \"try {} catch ({x}: any) {}\", \"try {\\n} catch ({ x }) {\\n}\\n\")\n\texpectPrintedTS(t, \"try {} catch ({x}: unknown) {}\", \"try {\\n} catch ({ x }) {\\n}\\n\")\n\texpectPrintedTS(t, \"try {} catch ({x}: number) {}\", \"try {\\n} catch ({ x }) {\\n}\\n\")\n\n\texpectPrintedTS(t, \"try {} catch ([x]: any) {}\", \"try {\\n} catch ([x]) {\\n}\\n\")\n\texpectPrintedTS(t, \"try {} catch ([x]: unknown) {}\", \"try {\\n} catch ([x]) {\\n}\\n\")\n\texpectPrintedTS(t, \"try {} catch ([x]: number) {}\", \"try {\\n} catch ([x]) {\\n}\\n\")\n\n\texpectParseErrorTS(t, \"try {} catch (x!) {}\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"!\\\"\\n\")\n\texpectParseErrorTS(t, \"try {} catch (x!: any) {}\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"!\\\"\\n\")\n\texpectParseErrorTS(t, \"try {} catch (x!: unknown) {}\", \"<stdin>: ERROR: Expected \\\")\\\" but found \\\"!\\\"\\n\")\n}\n\nfunc TestTSArrow(t *testing.T) {\n\texpectPrintedTS(t, \"(a?) => {}\", \"(a) => {\\n};\\n\")\n\texpectPrintedTS(t, \"(a?: number) => {}\", \"(a) => {\\n};\\n\")\n\texpectPrintedTS(t, \"(a?: number = 0) => {}\", \"(a = 0) => {\\n};\\n\")\n\texpectParseErrorTS(t, \"(a? = 0) => {}\", \"<stdin>: ERROR: Unexpected \\\"=\\\"\\n\")\n\n\texpectPrintedTS(t, \"(a?, b) => {}\", \"(a, b) => {\\n};\\n\")\n\texpectPrintedTS(t, \"(a?: number, b) => {}\", \"(a, b) => {\\n};\\n\")\n\texpectPrintedTS(t, \"(a?: number = 0, b) => {}\", \"(a = 0, b) => {\\n};\\n\")\n\texpectParseErrorTS(t, \"(a? = 0, b) => {}\", \"<stdin>: ERROR: Unexpected \\\"=\\\"\\n\")\n\n\texpectPrintedTS(t, \"(a: number) => {}\", \"(a) => {\\n};\\n\")\n\texpectPrintedTS(t, \"(a: number = 0) => {}\", \"(a = 0) => {\\n};\\n\")\n\texpectPrintedTS(t, \"(a: number, b) => {}\", \"(a, b) => {\\n};\\n\")\n\n\texpectPrintedTS(t, \"(): void => {}\", \"() => {\\n};\\n\")\n\texpectPrintedTS(t, \"(a): void => {}\", \"(a) => {\\n};\\n\")\n\texpectParseErrorTS(t, \"x: void => {}\", \"<stdin>: ERROR: Unexpected \\\"=>\\\"\\n\")\n\texpectPrintedTS(t, \"a ? (1 + 2) : (3 + 4)\", \"a ? 1 + 2 : 3 + 4;\\n\")\n\texpectPrintedTS(t, \"(foo) ? (foo as Bar) : null;\", \"foo ? foo : null;\\n\")\n\texpectPrintedTS(t, \"((foo) ? (foo as Bar) : null)\", \"foo ? foo : null;\\n\")\n\texpectPrintedTS(t, \"let x = a ? (b, c) : (d, e)\", \"let x = a ? (b, c) : (d, e);\\n\")\n\n\texpectPrintedTS(t, \"let x: () => void = () => {}\", \"let x = () => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x: (y) => void = () => {}\", \"let x = () => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x: (this) => void = () => {}\", \"let x = () => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x: (this: any) => void = () => {}\", \"let x = () => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): (() => {}) => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): () => {} => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): (y) => {} => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): ([,[b]]) => {} => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): ([a,[b]]) => {} => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): ([a,[b],]) => {} => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): ({a}) => {} => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): ({a,}) => {} => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): ({a:{b}}) => {} => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): ({0:{b}}) => {} => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): ({'a':{b}}) => {} => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): ({if:{b}}) => {} => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): ({...a}) => {} => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): ({a,...b}) => {} => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): (y[]) => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"let x = (y: any): (a | b) => {};\", \"let x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"type x = ({...fi}) => {};\", \"\")\n\texpectParseErrorTS(t, \"let x = (y: any): (y) => {};\", \"<stdin>: ERROR: Unexpected \\\":\\\"\\n\")\n\texpectParseErrorTS(t, \"let x = (y: any): (y) => {return 0};\", \"<stdin>: ERROR: Unexpected \\\":\\\"\\n\")\n\texpectParseErrorTS(t, \"let x = (y: any): asserts y is (y) => {};\", \"<stdin>: ERROR: Unexpected \\\":\\\"\\n\")\n\texpectParseErrorTS(t, \"type x = ({...if}) => {};\", \"<stdin>: ERROR: Unexpected \\\"...\\\"\\n\")\n\n\texpectPrintedTS(t, \"async (): void => {}\", \"async () => {\\n};\\n\")\n\texpectPrintedTS(t, \"async (a): void => {}\", \"async (a) => {\\n};\\n\")\n\texpectParseErrorTS(t, \"async x: void => {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"x\\\"\\n\")\n\n\texpectPrintedTS(t, \"function foo(x: boolean): asserts x\", \"\")\n\texpectPrintedTS(t, \"function foo(x: boolean): asserts<T>\", \"\")\n\texpectPrintedTS(t, \"function foo(x: boolean): asserts\\nx\", \"x;\\n\")\n\texpectPrintedTS(t, \"function foo(x: boolean): asserts<T>\\nx\", \"x;\\n\")\n\texpectParseErrorTS(t, \"function foo(x: boolean): asserts<T> x\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"x\\\"\\n\")\n\texpectPrintedTS(t, \"(x: boolean): asserts x => {}\", \"(x) => {\\n};\\n\")\n\texpectPrintedTS(t, \"(x: boolean): asserts this is object => {}\", \"(x) => {\\n};\\n\")\n\texpectPrintedTS(t, \"(x: T): asserts x is NonNullable<T> => {}\", \"(x) => {\\n};\\n\")\n\texpectPrintedTS(t, \"(x: any): x is number => {}\", \"(x) => {\\n};\\n\")\n\texpectPrintedTS(t, \"(x: any): this is object => {}\", \"(x) => {\\n};\\n\")\n\texpectPrintedTS(t, \"(x: any): (() => void) => {}\", \"(x) => {\\n};\\n\")\n\texpectPrintedTS(t, \"(x: any): ((y: any) => void) => {}\", \"(x) => {\\n};\\n\")\n\texpectPrintedTS(t, \"function foo(this: any): this is number {}\", \"function foo() {\\n}\\n\")\n\texpectPrintedTS(t, \"function foo(this: any): asserts this is number {}\", \"function foo() {\\n}\\n\")\n\texpectPrintedTS(t, \"(symbol: any): symbol is number => {}\", \"(symbol) => {\\n};\\n\")\n\n\texpectPrintedTS(t, \"let x: () => {} | ({y: z});\", \"let x;\\n\")\n\texpectPrintedTS(t, \"function x(): ({y: z}) {}\", \"function x() {\\n}\\n\")\n\n\texpectParseErrorTargetTS(t, 5, \"return check ? (hover = 2, bar) : baz()\", \"\")\n\texpectParseErrorTargetTS(t, 5, \"return check ? (hover = 2, bar) => 0 : baz()\",\n\t\t\"<stdin>: ERROR: Transforming default arguments to the configured target environment is not supported yet\\n\")\n\n\t// https://github.com/evanw/esbuild/issues/4027\n\texpectPrintedTS(t, \"function f(async?) { g(async in x) }\", \"function f(async) {\\n  g(async in x);\\n}\\n\")\n\texpectPrintedTS(t, \"function f(async?) { g(async as boolean) }\", \"function f(async) {\\n  g(async);\\n}\\n\")\n\texpectPrintedTS(t, \"function f() { g(async as => boolean) }\", \"function f() {\\n  g(async (as) => boolean);\\n}\\n\")\n\n\t// https://github.com/evanw/esbuild/issues/4241\n\texpectPrintedTS(t, \"x = a ? (b = c) : d\", \"x = a ? b = c : d;\\n\")\n\texpectPrintedTS(t, \"x = a ? (b = c) : d => e\", \"x = a ? b = c : (d) => e;\\n\")\n\texpectPrintedTS(t, \"x = a ? (b = c) : T => d : (e = f)\", \"x = a ? (b = c) => d : e = f;\\n\")\n\texpectPrintedTS(t, \"x = a ? (b = c) : T => d : (e = f) : T => g\", \"x = a ? (b = c) => d : (e = f) => g;\\n\")\n\texpectPrintedTS(t, \"x = a ? b ? c : (d = e) : f => g\", \"x = a ? b ? c : d = e : (f) => g;\\n\")\n\texpectPrintedTS(t, \"x = a ? b ? (c = d) => e : (f = g) : h => i\", \"x = a ? b ? (c = d) => e : f = g : (h) => i;\\n\")\n\texpectPrintedTS(t, \"x = a ? b ? (c = d) : T => e : (f = g) : h => i\", \"x = a ? b ? (c = d) => e : f = g : (h) => i;\\n\")\n\texpectPrintedTS(t, \"x = a ? b ? (c = d) : T => e : (f = g) : (h = i) : T => j\", \"x = a ? b ? (c = d) => e : f = g : (h = i) => j;\\n\")\n\texpectPrintedTS(t, \"x = a ? (b) : T => c : d\", \"x = a ? (b) => c : d;\\n\")\n\texpectPrintedTS(t, \"x = a ? b - (c) : d => e\", \"x = a ? b - c : (d) => e;\\n\")\n\texpectPrintedTS(t, \"x = a ? b = (c) : T => d : e\", \"x = a ? b = (c) => d : e;\\n\")\n\texpectParseErrorTS(t, \"x = a ? (b = c) : T => d : (e = f) : g\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\":\\\"\\n\")\n\texpectParseErrorTS(t, \"x = a ? b ? (c = d) : T => e : (f = g)\", \"<stdin>: ERROR: Expected \\\":\\\" but found end of file\\n\")\n\texpectParseErrorTS(t, \"x = a ? - (b) : c => d : e\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\":\\\"\\n\")\n\texpectParseErrorTS(t, \"x = a ? b - (c) : d => e : f\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\":\\\"\\n\")\n\n\t// Note: Newlines are important (they trigger backtracking)\n\texpectPrintedTS(t, \"x = (\\n  a ? (b = c) : { d: e }\\n)\", \"x = a ? b = c : { d: e };\\n\")\n\n\t// Need to clone \"#private\" identifier state in the parser\n\texpectPrintedTS(t, \"x = class { #y; y = a ? (b : T) : T => this.#y : c }\", \"x = class {\\n  #y;\\n  y = a ? (b) => this.#y : c;\\n};\\n\")\n\n\t// Need to clone \"in\" operator state in the parser\n\texpectPrintedTS(t, \"for (x = a ? () : T => b in c : d; ; ) ;\", \"for (x = a ? () => b in c : d; ; ) ;\\n\")\n}\n\nfunc TestTSSuperCall(t *testing.T) {\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { x = 1 }\",\n\t\t`class A extends B {\n  constructor() {\n    super(...arguments);\n    this.x = 1;\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { x }\",\n\t\t`class A extends B {\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { x = 1; constructor() { foo() } }\",\n\t\t`class A extends B {\n  constructor() {\n    this.x = 1;\n    foo();\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { x; constructor() { foo() } }\",\n\t\t`class A extends B {\n  constructor() {\n    foo();\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { x = 1; constructor() { foo(); super(1); } }\",\n\t\t`class A extends B {\n  constructor() {\n    foo();\n    super(1);\n    this.x = 1;\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { x = 1; constructor() { foo(); y ||= super(1); } }\",\n\t\t`class A extends B {\n  constructor() {\n    var __super = (...args) => {\n      super(...args);\n      this.x = 1;\n      return this;\n    };\n    foo();\n    y ||= __super(1);\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { x; constructor() { foo(); super(1); } }\",\n\t\t`class A extends B {\n  constructor() {\n    foo();\n    super(1);\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { x; constructor() { foo(); y ||= super(1); } }\",\n\t\t`class A extends B {\n  constructor() {\n    foo();\n    y ||= super(1);\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { [x] = 1; constructor() { foo(); super(1); } }\",\n\t\t`var _a, _b;\nclass A extends (_b = B, _a = x, _b) {\n  constructor() {\n    foo();\n    super(1);\n    this[_a] = 1;\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { [x] = 1; constructor() { foo(); y ||= super(1); } }\",\n\t\t`var _a, _b;\nclass A extends (_b = B, _a = x, _b) {\n  constructor() {\n    var __super = (...args) => {\n      super(...args);\n      this[_a] = 1;\n      return this;\n    };\n    foo();\n    y ||= __super(1);\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { [x]; constructor() { foo(); super(1); } }\",\n\t\t`var _a;\nclass A extends (_a = B, x, _a) {\n  constructor() {\n    foo();\n    super(1);\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { [x]; constructor() { foo(); y ||= super(1); } }\",\n\t\t`var _a;\nclass A extends (_a = B, x, _a) {\n  constructor() {\n    foo();\n    y ||= super(1);\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { constructor(public x = 1) { foo(); super(1); } }\",\n\t\t`class A extends B {\n  constructor(x = 1) {\n    foo();\n    super(1);\n    this.x = x;\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { constructor(public x = 1) { foo(); super(1); super(2); } }\",\n\t\t`class A extends B {\n  constructor(x = 1) {\n    var __super = (...args) => {\n      super(...args);\n      this.x = x;\n      return this;\n    };\n    foo();\n    __super(1);\n    __super(2);\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { constructor(public x = 1) { if (false) super(1); super(2); } }\", `class A extends B {\n  constructor(x = 1) {\n    if (false) __super(1);\n    super(2);\n    this.x = x;\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { constructor(public x = 1) { if (foo) super(1); super(2); } }\", `class A extends B {\n  constructor(x = 1) {\n    var __super = (...args) => {\n      super(...args);\n      this.x = x;\n      return this;\n    };\n    if (foo) __super(1);\n    __super(2);\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { constructor(public x = 1) { if (foo) super(1); else super(2); } }\", `class A extends B {\n  constructor(x = 1) {\n    var __super = (...args) => {\n      super(...args);\n      this.x = x;\n      return this;\n    };\n    if (foo) __super(1);\n    else __super(2);\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { #x; y; constructor() { super() } }\",\n\t\t`class A extends B {\n  #x;\n  constructor() {\n    super();\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { #x = 1; y; constructor() { super() } }\",\n\t\t`class A extends B {\n  #x = 1;\n  constructor() {\n    super();\n  }\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { #x; y = 1; constructor() { super() } }\",\n\t\t`class A extends B {\n  constructor() {\n    super();\n    this.y = 1;\n  }\n  #x;\n}\n`)\n\n\texpectPrintedAssignSemanticsTS(t, \"class A extends B { #x = 1; y = 2; constructor() { super() } }\",\n\t\t`class A extends B {\n  constructor() {\n    super();\n    this.#x = 1;\n    this.y = 2;\n  }\n  #x;\n}\n`)\n}\n\nfunc TestTSCall(t *testing.T) {\n\texpectPrintedTS(t, \"foo()\", \"foo();\\n\")\n\texpectPrintedTS(t, \"foo<number>()\", \"foo();\\n\")\n\texpectPrintedTS(t, \"foo<number, boolean>()\", \"foo();\\n\")\n}\n\nfunc TestTSNew(t *testing.T) {\n\texpectPrintedTS(t, \"new Foo()\", \"new Foo();\\n\")\n\texpectPrintedTS(t, \"new Foo<number>()\", \"new Foo();\\n\")\n\texpectPrintedTS(t, \"new Foo<number, boolean>()\", \"new Foo();\\n\")\n\texpectPrintedTS(t, \"new Foo<number>\", \"new Foo();\\n\")\n\texpectPrintedTS(t, \"new Foo<number, boolean>\", \"new Foo();\\n\")\n\n\texpectPrintedTS(t, \"new Foo!()\", \"new Foo();\\n\")\n\texpectPrintedTS(t, \"new Foo!<number>()\", \"new Foo();\\n\")\n\texpectPrintedTS(t, \"new Foo!.Bar()\", \"new Foo.Bar();\\n\")\n\texpectPrintedTS(t, \"new Foo!.Bar<number>()\", \"new Foo.Bar();\\n\")\n\texpectPrintedTS(t, \"new Foo!['Bar']()\", \"new Foo[\\\"Bar\\\"]();\\n\")\n\texpectPrintedTS(t, \"new Foo\\n!(x)\", \"new Foo();\\n!x;\\n\")\n\texpectPrintedTS(t, \"new Foo<number>!(x)\", \"new Foo() < number > !x;\\n\")\n\texpectParseErrorTS(t, \"new Foo<number>!()\", \"<stdin>: ERROR: Unexpected \\\")\\\"\\n\")\n\texpectParseErrorTS(t, \"new Foo\\n!.Bar()\", \"<stdin>: ERROR: Unexpected \\\".\\\"\\n\")\n\texpectParseError(t, \"new Foo!()\", \"<stdin>: ERROR: Unexpected \\\"!\\\"\\n\")\n}\n\nfunc TestTSInstantiationExpression(t *testing.T) {\n\texpectPrintedTS(t, \"f<number>\", \"f;\\n\")\n\texpectPrintedTS(t, \"f<number, boolean>\", \"f;\\n\")\n\texpectPrintedTS(t, \"f.g<number>\", \"f.g;\\n\")\n\texpectPrintedTS(t, \"f<number>.g\", \"f.g;\\n\")\n\texpectPrintedTS(t, \"f<number>.g<number>\", \"f.g;\\n\")\n\texpectPrintedTS(t, \"f['g']<number>\", \"f[\\\"g\\\"];\\n\")\n\texpectPrintedTS(t, \"(f<number>)<number>\", \"f;\\n\")\n\n\t// Function call\n\texpectPrintedTS(t, \"const x1 = f<true>\\n(true);\", \"const x1 = f(true);\\n\")\n\t// Relational expression\n\texpectPrintedTS(t, \"const x1 = f<true>\\ntrue;\", \"const x1 = f;\\ntrue;\\n\")\n\t// Instantiation expression\n\texpectPrintedTS(t, \"const x1 = f<true>;\\n(true);\", \"const x1 = f;\\ntrue;\\n\")\n\n\t// Trailing commas are not allowed\n\texpectPrintedTS(t, \"const x = Array<number>\\n(0);\", \"const x = Array(0);\\n\")\n\texpectPrintedTS(t, \"const x = Array<number>;\\n(0);\", \"const x = Array;\\n0;\\n\")\n\texpectParseErrorTS(t, \"const x = Array<number,>\\n(0);\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"const x = Array<number,>;\\n(0);\", \"<stdin>: ERROR: Expected identifier but found \\\">\\\"\\n\")\n\n\texpectPrintedTS(t, \"f<number>?.();\", \"f?.();\\n\")\n\texpectPrintedTS(t, \"f?.<number>();\", \"f?.();\\n\")\n\texpectPrintedTS(t, \"f<<T>() => T>?.();\", \"f?.();\\n\")\n\texpectPrintedTS(t, \"f?.<<T>() => T>();\", \"f?.();\\n\")\n\n\texpectPrintedTS(t, \"f<number>['g'];\", \"f < number > [\\\"g\\\"];\\n\")\n\n\texpectPrintedTS(t, \"type T21 = typeof Array<string>; f();\", \"f();\\n\")\n\texpectPrintedTS(t, \"type T22 = typeof Array<string, number>; f();\", \"f();\\n\")\n\n\texpectPrintedTS(t, \"f<x>, g<y>;\", \"f, g;\\n\")\n\texpectPrintedTS(t, \"f<<T>() => T>;\", \"f;\\n\")\n\texpectPrintedTS(t, \"f.x<<T>() => T>;\", \"f.x;\\n\")\n\texpectPrintedTS(t, \"f['x']<<T>() => T>;\", \"f[\\\"x\\\"];\\n\")\n\texpectPrintedTS(t, \"f<x>g<y>;\", \"f < x > g;\\n\")\n\texpectPrintedTS(t, \"f<x>=g<y>;\", \"f < x >= g;\\n\")\n\texpectPrintedTS(t, \"f<x>>g<y>;\", \"f < x >> g;\\n\")\n\texpectPrintedTS(t, \"f<x>>>g<y>;\", \"f < x >>> g;\\n\")\n\texpectParseErrorTS(t, \"f<x>>=g<y>;\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectParseErrorTS(t, \"f<x>>>=g<y>;\", \"<stdin>: ERROR: Invalid assignment target\\n\")\n\texpectPrintedTS(t, \"f<x,y>g<y>;\", \"f < x, y > g;\\n\")\n\texpectPrintedTS(t, \"f<x,y>=g<y>;\", \"f < x, y >= g;\\n\")\n\texpectPrintedTS(t, \"f<x,y>>g<y>;\", \"f < x, y >> g;\\n\")\n\texpectPrintedTS(t, \"f<x,y>>>g<y>;\", \"f < x, y >>> g;\\n\")\n\texpectPrintedTS(t, \"f<x,y>>=g<y>;\", \"f < x, y >>= g;\\n\")\n\texpectPrintedTS(t, \"f<x,y>>>=g<y>;\", \"f < x, y >>>= g;\\n\")\n\texpectPrintedTS(t, \"f<x> = g<y>;\", \"f = g;\\n\")\n\texpectParseErrorTS(t, \"f<x> > g<y>;\", \"<stdin>: ERROR: Unexpected \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"f<x> >> g<y>;\", \"<stdin>: ERROR: Unexpected \\\">>\\\"\\n\")\n\texpectParseErrorTS(t, \"f<x> >>> g<y>;\", \"<stdin>: ERROR: Unexpected \\\">>>\\\"\\n\")\n\texpectParseErrorTS(t, \"f<x> >= g<y>;\", \"<stdin>: ERROR: Unexpected \\\">=\\\"\\n\")\n\texpectParseErrorTS(t, \"f<x> >>= g<y>;\", \"<stdin>: ERROR: Unexpected \\\">>=\\\"\\n\")\n\texpectParseErrorTS(t, \"f<x> >>>= g<y>;\", \"<stdin>: ERROR: Unexpected \\\">>>=\\\"\\n\")\n\texpectPrintedTS(t, \"f<x,y> = g<y>;\", \"f = g;\\n\")\n\texpectParseErrorTS(t, \"f<x,y> > g<y>;\", \"<stdin>: ERROR: Unexpected \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"f<x,y> >> g<y>;\", \"<stdin>: ERROR: Unexpected \\\">>\\\"\\n\")\n\texpectParseErrorTS(t, \"f<x,y> >>> g<y>;\", \"<stdin>: ERROR: Unexpected \\\">>>\\\"\\n\")\n\texpectParseErrorTS(t, \"f<x,y> >= g<y>;\", \"<stdin>: ERROR: Unexpected \\\">=\\\"\\n\")\n\texpectParseErrorTS(t, \"f<x,y> >>= g<y>;\", \"<stdin>: ERROR: Unexpected \\\">>=\\\"\\n\")\n\texpectParseErrorTS(t, \"f<x,y> >>>= g<y>;\", \"<stdin>: ERROR: Unexpected \\\">>>=\\\"\\n\")\n\texpectPrintedTS(t, \"[f<x>];\", \"[f];\\n\")\n\texpectPrintedTS(t, \"f<x> ? g<y> : h<z>;\", \"f ? g : h;\\n\")\n\texpectPrintedTS(t, \"{ f<x> }\", \"{\\n  f;\\n}\\n\")\n\texpectPrintedTS(t, \"f<x> + g<y>;\", \"f < x > +g;\\n\")\n\texpectPrintedTS(t, \"f<x> - g<y>;\", \"f < x > -g;\\n\")\n\texpectPrintedTS(t, \"f<x> * g<y>;\", \"f * g;\\n\")\n\texpectPrintedTS(t, \"f<x> *= g<y>;\", \"f *= g;\\n\")\n\texpectPrintedTS(t, \"f<x> == g<y>;\", \"f == g;\\n\")\n\texpectPrintedTS(t, \"f<x> ?? g<y>;\", \"f ?? g;\\n\")\n\texpectPrintedTS(t, \"f<x> in g<y>;\", \"f in g;\\n\")\n\texpectPrintedTS(t, \"f<x> instanceof g<y>;\", \"f instanceof g;\\n\")\n\texpectPrintedTS(t, \"f<x> as g<y>;\", \"f;\\n\")\n\texpectPrintedTS(t, \"f<x> satisfies g<y>;\", \"f;\\n\")\n\texpectPrintedTS(t, \"class A extends B { f() { super.f<x>=y } }\", \"class A extends B {\\n  f() {\\n    super.f < x >= y;\\n  }\\n}\\n\")\n\texpectPrintedTS(t, \"class A extends B { f() { super.f<x,y>=z } }\", \"class A extends B {\\n  f() {\\n    super.f < x, y >= z;\\n  }\\n}\\n\")\n\n\texpectParseErrorTS(t, \"const a8 = f<number><number>;\", \"<stdin>: ERROR: Unexpected \\\";\\\"\\n\")\n\texpectParseErrorTS(t, \"const b1 = f?.<number>;\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\";\\\"\\n\")\n\n\t// See: https://github.com/microsoft/TypeScript/issues/48711\n\texpectPrintedTS(t, \"type x = y\\n<number>\\nz\", \"z;\\n\")\n\texpectPrintedTSX(t, \"type x = y\\n<number>\\nz\\n</number>\", \"/* @__PURE__ */ React.createElement(\\\"number\\\", null, \\\"z\\\");\\n\")\n\texpectPrintedTS(t, \"type x = typeof y\\n<number>\\nz\", \"z;\\n\")\n\texpectPrintedTSX(t, \"type x = typeof y\\n<number>\\nz\\n</number>\", \"/* @__PURE__ */ React.createElement(\\\"number\\\", null, \\\"z\\\");\\n\")\n\texpectPrintedTS(t, \"interface Foo { \\n (a: number): a \\n <T>(): void \\n }\", \"\")\n\texpectPrintedTSX(t, \"interface Foo { \\n (a: number): a \\n <T>(): void \\n }\", \"\")\n\texpectPrintedTS(t, \"interface Foo { \\n (a: number): typeof a \\n <T>(): void \\n }\", \"\")\n\texpectPrintedTSX(t, \"interface Foo { \\n (a: number): typeof a \\n <T>(): void \\n }\", \"\")\n\texpectParseErrorTS(t, \"type x = y\\n<number>\\nz\\n</number>\", \"<stdin>: ERROR: Unterminated regular expression\\n\")\n\texpectParseErrorTSX(t, \"type x = y\\n<number>\\nz\", \"<stdin>: ERROR: Unexpected end of file before a closing \\\"number\\\" tag\\n<stdin>: NOTE: The opening \\\"number\\\" tag is here:\\n\")\n\texpectParseErrorTS(t, \"type x = typeof y\\n<number>\\nz\\n</number>\", \"<stdin>: ERROR: Unterminated regular expression\\n\")\n\texpectParseErrorTSX(t, \"type x = typeof y\\n<number>\\nz\", \"<stdin>: ERROR: Unexpected end of file before a closing \\\"number\\\" tag\\n<stdin>: NOTE: The opening \\\"number\\\" tag is here:\\n\")\n\n\t// See: https://github.com/microsoft/TypeScript/issues/48654\n\texpectPrintedTS(t, \"x<true> y\", \"x < true > y;\\n\")\n\texpectPrintedTS(t, \"x<true>\\ny\", \"x;\\ny;\\n\")\n\texpectPrintedTS(t, \"x<true>\\nif (y) {}\", \"x;\\nif (y) {\\n}\\n\")\n\texpectPrintedTS(t, \"x<true>\\nimport 'y'\", \"x;\\nimport \\\"y\\\";\\n\")\n\texpectPrintedTS(t, \"x<true>\\nimport('y')\", \"x;\\nimport(\\\"y\\\");\\n\")\n\texpectPrintedTS(t, \"x<true>\\nimport.meta\", \"x;\\nimport.meta;\\n\")\n\texpectPrintedTS(t, \"x<true> import('y')\", \"x < true > import(\\\"y\\\");\\n\")\n\texpectPrintedTS(t, \"x<true> import.meta\", \"x < true > import.meta;\\n\")\n\texpectPrintedTS(t, \"new x<number> y\", \"new x() < number > y;\\n\")\n\texpectPrintedTS(t, \"new x<number>\\ny\", \"new x();\\ny;\\n\")\n\texpectPrintedTS(t, \"new x<number>\\nif (y) {}\", \"new x();\\nif (y) {\\n}\\n\")\n\texpectPrintedTS(t, \"new x<true>\\nimport 'y'\", \"new x();\\nimport \\\"y\\\";\\n\")\n\texpectPrintedTS(t, \"new x<true>\\nimport('y')\", \"new x();\\nimport(\\\"y\\\");\\n\")\n\texpectPrintedTS(t, \"new x<true>\\nimport.meta\", \"new x();\\nimport.meta;\\n\")\n\texpectPrintedTS(t, \"new x<true> import('y')\", \"new x() < true > import(\\\"y\\\");\\n\")\n\texpectPrintedTS(t, \"new x<true> import.meta\", \"new x() < true > import.meta;\\n\")\n\n\t// See: https://github.com/microsoft/TypeScript/issues/48759\n\texpectParseErrorTS(t, \"x<true>\\nimport<T>('y')\", \"<stdin>: ERROR: Unexpected \\\"<\\\"\\n\")\n\texpectParseErrorTS(t, \"new x<true>\\nimport<T>('y')\", \"<stdin>: ERROR: Unexpected \\\"<\\\"\\n\")\n\n\t// See: https://github.com/evanw/esbuild/issues/2201\n\texpectParseErrorTS(t, \"return Array < ;\", \"<stdin>: ERROR: Unexpected \\\";\\\"\\n\")\n\texpectParseErrorTS(t, \"return Array < > ;\", \"<stdin>: ERROR: Unexpected \\\">\\\"\\n\")\n\texpectParseErrorTS(t, \"return Array < , > ;\", \"<stdin>: ERROR: Unexpected \\\",\\\"\\n\")\n\texpectPrintedTS(t, \"return Array < number > ;\", \"return Array;\\n\")\n\texpectPrintedTS(t, \"return Array < number > 1;\", \"return Array < number > 1;\\n\")\n\texpectPrintedTS(t, \"return Array < number > +1;\", \"return Array < number > 1;\\n\")\n\texpectPrintedTS(t, \"return Array < number > (1);\", \"return Array(1);\\n\")\n\texpectPrintedTS(t, \"return Array < number >> 1;\", \"return Array < number >> 1;\\n\")\n\texpectPrintedTS(t, \"return Array < number >>> 1;\", \"return Array < number >>> 1;\\n\")\n\texpectPrintedTS(t, \"return Array < Array < number >> ;\", \"return Array;\\n\")\n\texpectPrintedTS(t, \"return Array < Array < number > > ;\", \"return Array;\\n\")\n\texpectParseErrorTS(t, \"return Array < Array < number > > 1;\", \"<stdin>: ERROR: Unexpected \\\">\\\"\\n\")\n\texpectPrintedTS(t, \"return Array < Array < number >> 1;\", \"return Array < Array < number >> 1;\\n\")\n\texpectParseErrorTS(t, \"return Array < Array < number > > +1;\", \"<stdin>: ERROR: Unexpected \\\">\\\"\\n\")\n\texpectPrintedTS(t, \"return Array < Array < number >> +1;\", \"return Array < Array < number >> 1;\\n\")\n\texpectPrintedTS(t, \"return Array < Array < number >> (1);\", \"return Array(1);\\n\")\n\texpectPrintedTS(t, \"return Array < Array < number > > (1);\", \"return Array(1);\\n\")\n\texpectPrintedTS(t, \"return Array < number > in x;\", \"return Array in x;\\n\")\n\texpectPrintedTS(t, \"return Array < Array < number >> in x;\", \"return Array in x;\\n\")\n\texpectPrintedTS(t, \"return Array < Array < number > > in x;\", \"return Array in x;\\n\")\n\texpectPrintedTS(t, \"for (var x = Array < number > in y) ;\", \"x = Array;\\nfor (var x in y) ;\\n\")\n\texpectPrintedTS(t, \"for (var x = Array < Array < number >> in y) ;\", \"x = Array;\\nfor (var x in y) ;\\n\")\n\texpectPrintedTS(t, \"for (var x = Array < Array < number > > in y) ;\", \"x = Array;\\nfor (var x in y) ;\\n\")\n\n\t// See: https://github.com/microsoft/TypeScript/pull/49353\n\texpectPrintedTS(t, \"F<{}> 0\", \"F < {} > 0;\\n\")\n\texpectPrintedTS(t, \"F<{}> class F<T> {}\", \"F < {} > class F {\\n};\\n\")\n\texpectPrintedTS(t, \"f<{}> function f<T>() {}\", \"f < {} > function f() {\\n};\\n\")\n\texpectPrintedTS(t, \"F<{}>\\n0\", \"F;\\n0;\\n\")\n\texpectPrintedTS(t, \"F<{}>\\nclass F<T> {}\", \"F;\\nclass F {\\n}\\n\")\n\texpectPrintedTS(t, \"f<{}>\\nfunction f<T>() {}\", \"f;\\nfunction f() {\\n}\\n\")\n}\n\nfunc TestTSExponentiation(t *testing.T) {\n\t// More info: https://github.com/microsoft/TypeScript/issues/41755\n\texpectParseErrorTS(t, \"await x! ** 2\", \"<stdin>: ERROR: Unexpected \\\"**\\\"\\n\")\n\texpectPrintedTS(t, \"await x as any ** 2\", \"(await x) ** 2;\\n\")\n}\n\nfunc TestTSImport(t *testing.T) {\n\texpectPrintedTS(t, \"import {x} from 'foo'\", \"\")\n\texpectPrintedTS(t, \"import {x} from 'foo'; log(x)\", \"import { x } from \\\"foo\\\";\\nlog(x);\\n\")\n\texpectPrintedTS(t, \"import {x, y as z} from 'foo'; log(z)\", \"import { y as z } from \\\"foo\\\";\\nlog(z);\\n\")\n\n\texpectPrintedTS(t, \"import x from 'foo'\", \"\")\n\texpectPrintedTS(t, \"import x from 'foo'; log(x)\", \"import x from \\\"foo\\\";\\nlog(x);\\n\")\n\n\texpectPrintedTS(t, \"import * as ns from 'foo'\", \"\")\n\texpectPrintedTS(t, \"import * as ns from 'foo'; log(ns)\", \"import * as ns from \\\"foo\\\";\\nlog(ns);\\n\")\n\n\t// Dead control flow must not affect usage tracking\n\texpectPrintedTS(t, \"import {x} from 'foo'; if (false) log(x)\", \"import \\\"foo\\\";\\nif (false) log(x);\\n\")\n\texpectPrintedTS(t, \"import x from 'foo'; if (false) log(x)\", \"import \\\"foo\\\";\\nif (false) log(x);\\n\")\n\texpectPrintedTS(t, \"import * as ns from 'foo'; if (false) log(ns)\", \"import \\\"foo\\\";\\nif (false) log(ns);\\n\")\n}\n\n// This is TypeScript-specific export syntax\nfunc TestTSExportEquals(t *testing.T) {\n\t// This use of the \"export\" keyword should not trigger strict mode because\n\t// this syntax works in CommonJS modules, not in ECMAScript modules\n\texpectPrintedTS(t, \"export = []\", \"module.exports = [];\\n\")\n\texpectPrintedTS(t, \"export = []; with ({}) ;\", \"with ({}) ;\\nmodule.exports = [];\\n\")\n}\n\n// This is TypeScript-specific import syntax\nfunc TestTSImportEquals(t *testing.T) {\n\t// This use of the \"export\" keyword should not trigger strict mode because\n\t// this syntax works in CommonJS modules, not in ECMAScript modules\n\texpectPrintedTS(t, \"import x = require('y')\", \"const x = require(\\\"y\\\");\\n\")\n\texpectPrintedTS(t, \"import x = require('y'); with ({}) ;\", \"const x = require(\\\"y\\\");\\nwith ({}) ;\\n\")\n\n\texpectPrintedTS(t, \"import x = require('foo'); x()\", \"const x = require(\\\"foo\\\");\\nx();\\n\")\n\texpectPrintedTS(t, \"import x = require('foo')\\nx()\", \"const x = require(\\\"foo\\\");\\nx();\\n\")\n\texpectPrintedTS(t, \"import x = require\\nx()\", \"const x = require;\\nx();\\n\")\n\texpectPrintedTS(t, \"import x = foo.bar; x()\", \"const x = foo.bar;\\nx();\\n\")\n\texpectPrintedTS(t, \"import x = foo.bar\\nx()\", \"const x = foo.bar;\\nx();\\n\")\n\texpectParseErrorTS(t, \"import x = foo()\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"(\\\"\\n\")\n\texpectParseErrorTS(t, \"import x = foo<T>.bar\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"<\\\"\\n\")\n\texpectParseErrorTS(t, \"{ import x = foo.bar }\", \"<stdin>: ERROR: Unexpected \\\"x\\\"\\n\")\n\n\texpectPrintedTS(t, \"export import x = require('foo'); x()\", \"export const x = require(\\\"foo\\\");\\nx();\\n\")\n\texpectPrintedTS(t, \"export import x = require('foo')\\nx()\", \"export const x = require(\\\"foo\\\");\\nx();\\n\")\n\texpectPrintedTS(t, \"export import x = foo.bar; x()\", \"export const x = foo.bar;\\nx();\\n\")\n\texpectPrintedTS(t, \"export import x = foo.bar\\nx()\", \"export const x = foo.bar;\\nx();\\n\")\n\n\texpectParseError(t, \"export import foo = bar\", \"<stdin>: ERROR: Unexpected \\\"import\\\"\\n\")\n\texpectParseErrorTS(t, \"export import {foo} from 'bar'\", \"<stdin>: ERROR: Expected identifier but found \\\"{\\\"\\n\")\n\texpectParseErrorTS(t, \"export import foo from 'bar'\", \"<stdin>: ERROR: Expected \\\"=\\\" but found \\\"from\\\"\\n\")\n\texpectParseErrorTS(t, \"export import foo = bar; var x; export {x as foo}\",\n\t\t`<stdin>: ERROR: Multiple exports with the same name \"foo\"\n<stdin>: NOTE: The name \"foo\" was originally exported here:\n`)\n\texpectParseErrorTS(t, \"{ export import foo = bar }\", \"<stdin>: ERROR: Unexpected \\\"export\\\"\\n\")\n\n\terrorText := `<stdin>: WARNING: This assignment will throw because \"x\" is a constant\n<stdin>: NOTE: The symbol \"x\" was declared a constant here:\n`\n\texpectParseErrorTS(t, \"import x = require('y'); x = require('z')\", errorText)\n\texpectParseErrorTS(t, \"import x = y.z; x = z.y\", errorText)\n}\n\nfunc TestTSImportEqualsInNamespace(t *testing.T) {\n\texpectPrintedTS(t, \"namespace ns { import foo = bar }\", \"\")\n\texpectPrintedTS(t, \"namespace ns { import foo = bar; type x = foo.x }\", \"\")\n\texpectPrintedTS(t, \"namespace ns { import foo = bar.x; foo }\", `var ns;\n((ns) => {\n  const foo = bar.x;\n  foo;\n})(ns || (ns = {}));\n`)\n\texpectPrintedTS(t, \"namespace ns { export import foo = bar }\", `var ns;\n((ns) => {\n  ns.foo = bar;\n})(ns || (ns = {}));\n`)\n\texpectPrintedTS(t, \"namespace ns { export import foo = bar.x; foo }\", `var ns;\n((ns) => {\n  ns.foo = bar.x;\n  ns.foo;\n})(ns || (ns = {}));\n`)\n\texpectParseErrorTS(t, \"namespace ns { import {foo} from 'bar' }\", \"<stdin>: ERROR: Expected identifier but found \\\"{\\\"\\n\")\n\texpectParseErrorTS(t, \"namespace ns { import foo from 'bar' }\", \"<stdin>: ERROR: Expected \\\"=\\\" but found \\\"from\\\"\\n\")\n\texpectParseErrorTS(t, \"namespace ns { export import {foo} from 'bar' }\", \"<stdin>: ERROR: Expected identifier but found \\\"{\\\"\\n\")\n\texpectParseErrorTS(t, \"namespace ns { export import foo from 'bar' }\", \"<stdin>: ERROR: Expected \\\"=\\\" but found \\\"from\\\"\\n\")\n\texpectParseErrorTS(t, \"namespace ns { { import foo = bar } }\", \"<stdin>: ERROR: Unexpected \\\"foo\\\"\\n\")\n\texpectParseErrorTS(t, \"namespace ns { { export import foo = bar } }\", \"<stdin>: ERROR: Unexpected \\\"export\\\"\\n\")\n}\n\nfunc TestTSTypeOnlyImport(t *testing.T) {\n\texpectPrintedTS(t, \"import type foo from 'bar'; x\", \"x;\\n\")\n\texpectPrintedTS(t, \"import type foo from 'bar'\\nx\", \"x;\\n\")\n\texpectPrintedTS(t, \"import type from from 'bar'; x\", \"x;\\n\")\n\texpectPrintedTS(t, \"import type * as foo from 'bar'; x\", \"x;\\n\")\n\texpectPrintedTS(t, \"import type * as foo from 'bar'\\nx\", \"x;\\n\")\n\texpectPrintedTS(t, \"import type {foo, bar as baz} from 'bar'; x\", \"x;\\n\")\n\texpectPrintedTS(t, \"import type {'foo' as bar} from 'bar'\\nx\", \"x;\\n\")\n\texpectPrintedTS(t, \"import type foo = require('bar'); x\", \"x;\\n\")\n\texpectPrintedTS(t, \"import type foo = bar.baz; x\", \"x;\\n\")\n\texpectPrintedTS(t, \"import type from = require('bar'); x\", \"x;\\n\")\n\n\texpectPrintedTS(t, \"import type = bar; type\", \"const type = bar;\\ntype;\\n\")\n\texpectPrintedTS(t, \"import type = foo.bar; type\", \"const type = foo.bar;\\ntype;\\n\")\n\texpectPrintedTS(t, \"import type = require('type'); type\", \"const type = require(\\\"type\\\");\\ntype;\\n\")\n\texpectPrintedTS(t, \"import type from 'bar'; type\", \"import type from \\\"bar\\\";\\ntype;\\n\")\n\n\texpectPrintedTS(t, \"import { type } from 'mod'; type\", \"import { type } from \\\"mod\\\";\\ntype;\\n\")\n\texpectPrintedTS(t, \"import { x, type foo } from 'mod'; x\", \"import { x } from \\\"mod\\\";\\nx;\\n\")\n\texpectPrintedTS(t, \"import { x, type as } from 'mod'; x\", \"import { x } from \\\"mod\\\";\\nx;\\n\")\n\texpectPrintedTS(t, \"import { x, type foo as bar } from 'mod'; x\", \"import { x } from \\\"mod\\\";\\nx;\\n\")\n\texpectPrintedTS(t, \"import { x, type foo as as } from 'mod'; x\", \"import { x } from \\\"mod\\\";\\nx;\\n\")\n\texpectPrintedTS(t, \"import { type as as } from 'mod'; as\", \"import { type as as } from \\\"mod\\\";\\nas;\\n\")\n\texpectPrintedTS(t, \"import { type as foo } from 'mod'; foo\", \"import { type as foo } from \\\"mod\\\";\\nfoo;\\n\")\n\texpectPrintedTS(t, \"import { type as type } from 'mod'; type\", \"import { type } from \\\"mod\\\";\\ntype;\\n\")\n\texpectPrintedTS(t, \"import { x, type as as foo } from 'mod'; x\", \"import { x } from \\\"mod\\\";\\nx;\\n\")\n\texpectPrintedTS(t, \"import { x, type as as as } from 'mod'; x\", \"import { x } from \\\"mod\\\";\\nx;\\n\")\n\texpectPrintedTS(t, \"import { x, type type as as } from 'mod'; x\", \"import { x } from \\\"mod\\\";\\nx;\\n\")\n\texpectPrintedTS(t, \"import { x, \\\\u0074ype y } from 'mod'; x, y\", \"import { x } from \\\"mod\\\";\\nx, y;\\n\")\n\texpectPrintedTS(t, \"import { x, type if as y } from 'mod'; x, y\", \"import { x } from \\\"mod\\\";\\nx, y;\\n\")\n\n\texpectPrintedTS(t, \"import a = b; import c = a.c\", \"\")\n\texpectPrintedTS(t, \"import c = a.c; import a = b\", \"\")\n\texpectPrintedTS(t, \"import a = b; import c = a.c; c()\", \"const a = b;\\nconst c = a.c;\\nc();\\n\")\n\texpectPrintedTS(t, \"import c = a.c; import a = b; c()\", \"const c = a.c;\\nconst a = b;\\nc();\\n\")\n\n\texpectParseErrorTS(t, \"import type\", \"<stdin>: ERROR: Expected \\\"from\\\" but found end of file\\n\")\n\texpectParseErrorTS(t, \"import type * foo\", \"<stdin>: ERROR: Expected \\\"as\\\" but found \\\"foo\\\"\\n\")\n\texpectParseErrorTS(t, \"import type * as 'bar'\", \"<stdin>: ERROR: Expected identifier but found \\\"'bar'\\\"\\n\")\n\texpectParseErrorTS(t, \"import type { 'bar' }\", \"<stdin>: ERROR: Expected \\\"as\\\" but found \\\"}\\\"\\n\")\n\n\texpectParseErrorTS(t, \"import type foo, * as foo from 'bar'\", \"<stdin>: ERROR: Expected \\\"from\\\" but found \\\",\\\"\\n\")\n\texpectParseErrorTS(t, \"import type foo, {foo} from 'bar'\", \"<stdin>: ERROR: Expected \\\"from\\\" but found \\\",\\\"\\n\")\n\texpectParseErrorTS(t, \"import type from, * as foo from 'bar'\", \"<stdin>: ERROR: Expected \\\"from\\\" but found \\\",\\\"\\n\")\n\texpectParseErrorTS(t, \"import type from, {foo} from 'bar'\", \"<stdin>: ERROR: Expected \\\"from\\\" but found \\\",\\\"\\n\")\n\texpectParseErrorTS(t, \"import type * as foo = require('bar')\", \"<stdin>: ERROR: Expected \\\"from\\\" but found \\\"=\\\"\\n\")\n\texpectParseErrorTS(t, \"import type {foo} = require('bar')\", \"<stdin>: ERROR: Expected \\\"from\\\" but found \\\"=\\\"\\n\")\n\n\texpectParseErrorTS(t, \"import { type as export } from 'mod'\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"export\\\"\\n\")\n\texpectParseErrorTS(t, \"import { type as as export } from 'mod'\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"export\\\"\\n\")\n\texpectParseErrorTS(t, \"import { type import } from 'mod'\", \"<stdin>: ERROR: Expected \\\"as\\\" but found \\\"}\\\"\\n\")\n\texpectParseErrorTS(t, \"import { type foo bar } from 'mod'\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"bar\\\"\\n\")\n\texpectParseErrorTS(t, \"import { type foo as } from 'mod'\", \"<stdin>: ERROR: Expected identifier but found \\\"}\\\"\\n\")\n\texpectParseErrorTS(t, \"import { type foo as bar baz } from 'mod'\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"baz\\\"\\n\")\n\texpectParseErrorTS(t, \"import { type as as as as } from 'mod'\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"as\\\"\\n\")\n\texpectParseErrorTS(t, \"import { type \\\\u0061s x } from 'mod'\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"x\\\"\\n\")\n\texpectParseErrorTS(t, \"import { type x \\\\u0061s y } from 'mod'\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"\\\\\\\\u0061s\\\"\\n\")\n\texpectParseErrorTS(t, \"import { type x as if } from 'mod'\", \"<stdin>: ERROR: Expected identifier but found \\\"if\\\"\\n\")\n\texpectParseErrorTS(t, \"import { type as if } from 'mod'\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"if\\\"\\n\")\n\n\t// Forbidden names\n\texpectParseErrorTS(t, \"import { type as eval } from 'mod'\", \"<stdin>: ERROR: Cannot use \\\"eval\\\" as an identifier here:\\n\")\n\texpectParseErrorTS(t, \"import { type as arguments } from 'mod'\", \"<stdin>: ERROR: Cannot use \\\"arguments\\\" as an identifier here:\\n\")\n\n\t// Arbitrary module namespace identifier names\n\texpectPrintedTS(t, \"import { x, type 'y' as z } from 'mod'; x, z\", \"import { x } from \\\"mod\\\";\\nx, z;\\n\")\n\texpectParseErrorTS(t, \"import { x, type 'y' } from 'mod'\", \"<stdin>: ERROR: Expected \\\"as\\\" but found \\\"}\\\"\\n\")\n\texpectParseErrorTS(t, \"import { x, type 'y' as } from 'mod'\", \"<stdin>: ERROR: Expected identifier but found \\\"}\\\"\\n\")\n\texpectParseErrorTS(t, \"import { x, type 'y' as 'z' } from 'mod'\", \"<stdin>: ERROR: Expected identifier but found \\\"'z'\\\"\\n\")\n\texpectParseErrorTS(t, \"import { x, type as 'y' } from 'mod'\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"'y'\\\"\\n\")\n\texpectParseErrorTS(t, \"import { x, type y as 'z' } from 'mod'\", \"<stdin>: ERROR: Expected identifier but found \\\"'z'\\\"\\n\")\n\n\t// See: https://github.com/tc39/proposal-defer-import-eval\n\texpectPrintedTS(t, \"import defer * as foo from 'bar'\", \"\")\n\texpectPrintedTS(t, \"import defer * as foo from 'bar'; let x: foo.Type\", \"let x;\\n\")\n\texpectPrintedTS(t, \"import defer * as foo from 'bar'; let x = foo.value\", \"import defer * as foo from \\\"bar\\\";\\nlet x = foo.value;\\n\")\n\texpectPrintedTS(t, \"import type defer from 'bar'\", \"\")\n\texpectParseErrorTS(t, \"import type defer * as foo from 'bar'\", \"<stdin>: ERROR: Expected \\\"from\\\" but found \\\"*\\\"\\n\")\n\n\t// See: https://github.com/tc39/proposal-source-phase-imports\n\texpectPrintedTS(t, \"import type source from 'bar'\", \"\")\n\texpectPrintedTS(t, \"import source foo from 'bar'\", \"\")\n\texpectPrintedTS(t, \"import source foo from 'bar'; let x: foo\", \"let x;\\n\")\n\texpectPrintedTS(t, \"import source foo from 'bar'; let x = foo\", \"import source foo from \\\"bar\\\";\\nlet x = foo;\\n\")\n\texpectPrintedTS(t, \"import source type from 'bar'\", \"\")\n\texpectParseErrorTS(t, \"import source type foo from 'bar'\", \"<stdin>: ERROR: Expected \\\"from\\\" but found \\\"foo\\\"\\n\")\n\texpectParseErrorTS(t, \"import type source foo from 'bar'\", \"<stdin>: ERROR: Expected \\\"from\\\" but found \\\"foo\\\"\\n\")\n}\n\nfunc TestTSTypeOnlyExport(t *testing.T) {\n\texpectPrintedTS(t, \"export type {foo, bar as baz} from 'bar'\", \"\")\n\texpectPrintedTS(t, \"export type {foo, bar as baz}\", \"\")\n\texpectPrintedTS(t, \"export type {foo} from 'bar'; x\", \"x;\\n\")\n\texpectPrintedTS(t, \"export type {foo} from 'bar'\\nx\", \"x;\\n\")\n\texpectPrintedTS(t, \"export type {default} from 'bar'\", \"\")\n\texpectParseErrorTS(t, \"export type {default}\", \"<stdin>: ERROR: Expected identifier but found \\\"default\\\"\\n\")\n\n\texpectPrintedTS(t, \"export { type } from 'mod'; type\", \"export { type } from \\\"mod\\\";\\ntype;\\n\")\n\texpectPrintedTS(t, \"export { type, as } from 'mod'\", \"export { type, as } from \\\"mod\\\";\\n\")\n\texpectPrintedTS(t, \"export { x, type foo } from 'mod'; x\", \"export { x } from \\\"mod\\\";\\nx;\\n\")\n\texpectPrintedTS(t, \"export { x, type as } from 'mod'; x\", \"export { x } from \\\"mod\\\";\\nx;\\n\")\n\texpectPrintedTS(t, \"export { x, type foo as bar } from 'mod'; x\", \"export { x } from \\\"mod\\\";\\nx;\\n\")\n\texpectPrintedTS(t, \"export { x, type foo as as } from 'mod'; x\", \"export { x } from \\\"mod\\\";\\nx;\\n\")\n\texpectPrintedTS(t, \"export { type as as } from 'mod'; as\", \"export { type as as } from \\\"mod\\\";\\nas;\\n\")\n\texpectPrintedTS(t, \"export { type as foo } from 'mod'; foo\", \"export { type as foo } from \\\"mod\\\";\\nfoo;\\n\")\n\texpectPrintedTS(t, \"export { type as type } from 'mod'; type\", \"export { type } from \\\"mod\\\";\\ntype;\\n\")\n\texpectPrintedTS(t, \"export { x, type as as foo } from 'mod'; x\", \"export { x } from \\\"mod\\\";\\nx;\\n\")\n\texpectPrintedTS(t, \"export { x, type as as as } from 'mod'; x\", \"export { x } from \\\"mod\\\";\\nx;\\n\")\n\texpectPrintedTS(t, \"export { x, type type as as } from 'mod'; x\", \"export { x } from \\\"mod\\\";\\nx;\\n\")\n\texpectPrintedTS(t, \"export { x, \\\\u0074ype y }; let x, y\", \"export { x };\\nlet x, y;\\n\")\n\texpectPrintedTS(t, \"export { x, \\\\u0074ype y } from 'mod'\", \"export { x } from \\\"mod\\\";\\n\")\n\texpectPrintedTS(t, \"export { x, type if } from 'mod'\", \"export { x } from \\\"mod\\\";\\n\")\n\texpectPrintedTS(t, \"export { x, type y as if }; let x\", \"export { x };\\nlet x;\\n\")\n\n\texpectParseErrorTS(t, \"export { type foo bar } from 'mod'\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"bar\\\"\\n\")\n\texpectParseErrorTS(t, \"export { type foo as } from 'mod'\", \"<stdin>: ERROR: Expected identifier but found \\\"}\\\"\\n\")\n\texpectParseErrorTS(t, \"export { type foo as bar baz } from 'mod'\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"baz\\\"\\n\")\n\texpectParseErrorTS(t, \"export { type as as as as } from 'mod'\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"as\\\"\\n\")\n\texpectParseErrorTS(t, \"export { type \\\\u0061s x } from 'mod'\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"x\\\"\\n\")\n\texpectParseErrorTS(t, \"export { type x \\\\u0061s y } from 'mod'\", \"<stdin>: ERROR: Expected \\\"}\\\" but found \\\"\\\\\\\\u0061s\\\"\\n\")\n\texpectParseErrorTS(t, \"export { x, type if }\", \"<stdin>: ERROR: Expected identifier but found \\\"if\\\"\\n\")\n\n\t// Arbitrary module namespace identifier names\n\texpectPrintedTS(t, \"export { type as \\\"\\\" } from 'mod'\", \"export { type as \\\"\\\" } from \\\"mod\\\";\\n\")\n\texpectPrintedTS(t, \"export { x, type as as \\\"\\\" } from 'mod'\", \"export { x } from \\\"mod\\\";\\n\")\n\texpectPrintedTS(t, \"export { x, type x as \\\"\\\" } from 'mod'\", \"export { x } from \\\"mod\\\";\\n\")\n\texpectPrintedTS(t, \"export { x, type \\\"\\\" as x } from 'mod'\", \"export { x } from \\\"mod\\\";\\n\")\n\texpectPrintedTS(t, \"export { x, type \\\"\\\" as \\\" \\\" } from 'mod'\", \"export { x } from \\\"mod\\\";\\n\")\n\texpectPrintedTS(t, \"export { x, type \\\"\\\" } from 'mod'\", \"export { x } from \\\"mod\\\";\\n\")\n\texpectParseErrorTS(t, \"export { type \\\"\\\" }\", \"<stdin>: ERROR: Expected identifier but found \\\"\\\\\\\"\\\\\\\"\\\"\\n\")\n\texpectParseErrorTS(t, \"export { type \\\"\\\" as x }\", \"<stdin>: ERROR: Expected identifier but found \\\"\\\\\\\"\\\\\\\"\\\"\\n\")\n\texpectParseErrorTS(t, \"export { type \\\"\\\" as \\\" \\\" }\", \"<stdin>: ERROR: Expected identifier but found \\\"\\\\\\\"\\\\\\\"\\\"\\n\")\n\n\t// Named exports should be removed if they don't refer to a local symbol\n\texpectPrintedTS(t, \"const Foo = {}; export {Foo}\", \"const Foo = {};\\nexport { Foo };\\n\")\n\texpectPrintedTS(t, \"type Foo = {}; export {Foo}\", \"export {};\\n\")\n\texpectPrintedTS(t, \"const Foo = {}; export {Foo as Bar}\", \"const Foo = {};\\nexport { Foo as Bar };\\n\")\n\texpectPrintedTS(t, \"type Foo = {}; export {Foo as Bar}\", \"export {};\\n\")\n\texpectPrintedTS(t, \"import Foo from 'foo'; export {Foo}\", \"import Foo from \\\"foo\\\";\\nexport { Foo };\\n\")\n\texpectPrintedTS(t, \"import {Foo} from 'foo'; export {Foo}\", \"import { Foo } from \\\"foo\\\";\\nexport { Foo };\\n\")\n\texpectPrintedTS(t, \"import * as Foo from 'foo'; export {Foo}\", \"import * as Foo from \\\"foo\\\";\\nexport { Foo };\\n\")\n\texpectPrintedTS(t, \"{ var Foo; } export {Foo}\", \"{\\n  var Foo;\\n}\\nexport { Foo };\\n\")\n\texpectPrintedTS(t, \"{ let Foo; } export {Foo}\", \"{\\n  let Foo;\\n}\\nexport {};\\n\")\n\texpectPrintedTS(t, \"export {Foo}\", \"export {};\\n\")\n\texpectParseError(t, \"export {Foo}\", \"<stdin>: ERROR: \\\"Foo\\\" is not declared in this file\\n\")\n\n\t// This is a syntax error in TypeScript, but we parse it anyway because\n\t// people blame esbuild when it doesn't parse. It's silently discarded\n\t// because we always discard all type annotations (even invalid ones).\n\texpectPrintedTS(t, \"export type * from 'foo'\\nbar\", \"bar;\\n\")\n\texpectPrintedTS(t, \"export type * as foo from 'bar'; foo\", \"foo;\\n\")\n\texpectPrintedTS(t, \"export type * as 'f o' from 'bar'; foo\", \"foo;\\n\")\n}\n\nfunc TestTSOptionalChain(t *testing.T) {\n\texpectParseError(t, \"a?.<T>()\", \"<stdin>: ERROR: Expected identifier but found \\\"<\\\"\\n\")\n\texpectParseError(t, \"a?.<<T>() => T>()\", \"<stdin>: ERROR: Expected identifier but found \\\"<<\\\"\\n\")\n\texpectPrintedTS(t, \"a?.<T>()\", \"a?.();\\n\")\n\texpectPrintedTS(t, \"a?.<<T>() => T>()\", \"a?.();\\n\")\n\texpectParseErrorTS(t, \"a?.<T>b\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"b\\\"\\n\")\n\texpectParseErrorTS(t, \"a?.<T>[b]\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"[\\\"\\n\")\n\texpectParseErrorTS(t, \"a?.<<T>() => T>b\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"b\\\"\\n\")\n\texpectParseErrorTS(t, \"a?.<<T>() => T>[b]\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"[\\\"\\n\")\n\n\texpectPrintedTS(t, \"a?.b.c\", \"a?.b.c;\\n\")\n\texpectPrintedTS(t, \"(a?.b).c\", \"(a?.b).c;\\n\")\n\texpectPrintedTS(t, \"a?.b!.c\", \"a?.b.c;\\n\")\n\n\texpectPrintedTS(t, \"a?.b[c]\", \"a?.b[c];\\n\")\n\texpectPrintedTS(t, \"(a?.b)[c]\", \"(a?.b)[c];\\n\")\n\texpectPrintedTS(t, \"a?.b![c]\", \"a?.b[c];\\n\")\n\n\texpectPrintedTS(t, \"a?.b(c)\", \"a?.b(c);\\n\")\n\texpectPrintedTS(t, \"(a?.b)(c)\", \"(a?.b)(c);\\n\")\n\texpectPrintedTS(t, \"a?.b!(c)\", \"a?.b(c);\\n\")\n\n\texpectPrintedTS(t, \"a?.b<T>(c)\", \"a?.b(c);\\n\")\n\texpectPrintedTS(t, \"a?.b<+T>(c)\", \"a?.b < +T > c;\\n\")\n\texpectPrintedTS(t, \"a?.b<<T>() => T>(c)\", \"a?.b(c);\\n\")\n}\n\nfunc TestTSJSX(t *testing.T) {\n\texpectParseErrorTSX(t, \"<div>></div>\",\n\t\t\"<stdin>: ERROR: The character \\\">\\\" is not valid inside a JSX element\\n\"+\n\t\t\t\"NOTE: Did you mean to escape it as \\\"{'>'}\\\" instead?\\n\")\n\texpectParseErrorTSX(t, \"<div>{1}}</div>\",\n\t\t\"<stdin>: ERROR: The character \\\"}\\\" is not valid inside a JSX element\\n\"+\n\t\t\t\"NOTE: Did you mean to escape it as \\\"{'}'}\\\" instead?\\n\")\n\n\texpectPrintedTS(t, \"const x = <number>1\", \"const x = 1;\\n\")\n\texpectPrintedTSX(t, \"const x = <number>1</number>\", \"const x = /* @__PURE__ */ React.createElement(\\\"number\\\", null, \\\"1\\\");\\n\")\n\texpectParseErrorTSX(t, \"const x = <number>1\", \"<stdin>: ERROR: Unexpected end of file before a closing \\\"number\\\" tag\\n<stdin>: NOTE: The opening \\\"number\\\" tag is here:\\n\")\n\n\texpectPrintedTSX(t, \"<x>a{}c</x>\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", null, \\\"a\\\", \\\"c\\\");\\n\")\n\texpectPrintedTSX(t, \"<x>a{/* comment */}c</x>\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", null, \\\"a\\\", \\\"c\\\");\\n\")\n\texpectPrintedTSX(t, \"<x>a{b}c</x>\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", null, \\\"a\\\", b, \\\"c\\\");\\n\")\n\texpectPrintedTSX(t, \"<x>a{...b}c</x>\", \"/* @__PURE__ */ React.createElement(\\\"x\\\", null, \\\"a\\\", ...b, \\\"c\\\");\\n\")\n\n\texpectPrintedTSX(t, \"const x = <Foo<T>></Foo>\", \"const x = /* @__PURE__ */ React.createElement(Foo, null);\\n\")\n\texpectPrintedTSX(t, \"const x = <Foo<T> data-foo></Foo>\", \"const x = /* @__PURE__ */ React.createElement(Foo, { \\\"data-foo\\\": true });\\n\")\n\texpectParseErrorTSX(t, \"const x = <Foo<T>=>\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\"=>\\\"\\n\")\n\n\texpectPrintedTS(t, \"const x = <T>() => {}\", \"const x = () => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = <T>(y)\", \"const x = y;\\n\")\n\texpectPrintedTS(t, \"const x = <T>(y, z)\", \"const x = (y, z);\\n\")\n\texpectPrintedTS(t, \"const x = <T>(y: T) => {}\", \"const x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = <T>(y, z) => {}\", \"const x = (y, z) => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = <T = X>(y: T) => {}\", \"const x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = <T = X>(y, z) => {}\", \"const x = (y, z) => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = <T extends X>(y: T) => {}\", \"const x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = <T extends X>(y, z) => {}\", \"const x = (y, z) => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = <T extends X = Y>(y: T) => {}\", \"const x = (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = <T extends X = Y>(y, z) => {}\", \"const x = (y, z) => {\\n};\\n\")\n\n\texpectPrintedTS(t, \"const x = async <T>() => {}\", \"const x = async () => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = async <T>(y)\", \"const x = async(y);\\n\")\n\texpectPrintedTS(t, \"const x = async\\n<T>(y)\", \"const x = async(y);\\n\")\n\texpectPrintedTS(t, \"const x = async <T>(y, z)\", \"const x = async(y, z);\\n\")\n\texpectPrintedTS(t, \"const x = async <T>(y: T) => {}\", \"const x = async (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = async <T>(y, z) => {}\", \"const x = async (y, z) => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = async <T = X>(y: T) => {}\", \"const x = async (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = async <T = X>(y, z) => {}\", \"const x = async (y, z) => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = async <T extends X>(y: T) => {}\", \"const x = async (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = async <T extends X>(y, z) => {}\", \"const x = async (y, z) => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = async <T extends X = Y>(y: T) => {}\", \"const x = async (y) => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = async <T extends X = Y>(y, z) => {}\", \"const x = async (y, z) => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = (async <T, X> y)\", \"const x = (async < T, X > y);\\n\")\n\texpectPrintedTS(t, \"const x = (async <T, X>(y))\", \"const x = async(y);\\n\")\n\texpectParseErrorTS(t, \"const x = async <T,>(y)\", \"<stdin>: ERROR: Expected \\\"=>\\\" but found end of file\\n\")\n\texpectParseErrorTS(t, \"const x = async <T>(y: T)\", \"<stdin>: ERROR: Unexpected \\\":\\\"\\n\")\n\texpectParseErrorTS(t, \"const x = async\\n<T>() => {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"=>\\\"\\n\")\n\texpectParseErrorTS(t, \"const x = async\\n<T>(x) => {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"=>\\\"\\n\")\n\n\texpectPrintedTS(t, \"const x = <{}>() => {}\", \"const x = () => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = <{}>(y)\", \"const x = y;\\n\")\n\texpectPrintedTS(t, \"const x = <{}>(y, z)\", \"const x = (y, z);\\n\")\n\texpectPrintedTS(t, \"const x = <{}>(y, z) => {}\", \"const x = (y, z) => {\\n};\\n\")\n\n\texpectPrintedTS(t, \"const x = <[]>() => {}\", \"const x = () => {\\n};\\n\")\n\texpectPrintedTS(t, \"const x = <[]>(y)\", \"const x = y;\\n\")\n\texpectPrintedTS(t, \"const x = <[]>(y, z)\", \"const x = (y, z);\\n\")\n\texpectPrintedTS(t, \"const x = <[]>(y, z) => {}\", \"const x = (y, z) => {\\n};\\n\")\n\n\tinvalid := \"<stdin>: ERROR: The character \\\">\\\" is not valid inside a JSX element\\nNOTE: Did you mean to escape it as \\\"{'>'}\\\" instead?\\n\"\n\tinvalidWithHint := \"<stdin>: ERROR: The character \\\">\\\" is not valid inside a JSX element\\n<stdin>: NOTE: TypeScript's TSX syntax interprets \" +\n\t\t\"arrow functions with a single generic type parameter as an opening JSX element. If you want it to be interpreted as an arrow function instead, \" +\n\t\t\"you need to add a trailing comma after the type parameter to disambiguate:\\n\"\n\texpectPrintedTSX(t, \"<T extends/>\", \"/* @__PURE__ */ React.createElement(T, { extends: true });\\n\")\n\texpectPrintedTSX(t, \"<T extends>(y) = {}</T>\", \"/* @__PURE__ */ React.createElement(T, { extends: true }, \\\"(y) = \\\");\\n\")\n\texpectParseErrorTSX(t, \"<T extends X/>\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\"/\\\"\\n\")\n\texpectParseErrorTSX(t, \"<T extends X>(y) = {}</T>\", \"<stdin>: ERROR: Expected \\\"=>\\\" but found \\\"=\\\"\\n\")\n\texpectParseErrorTSX(t, \"(<T>(y) => {}</T>)\", invalidWithHint)\n\texpectParseErrorTSX(t, \"(<T>(x: X<Y>) => {}</Y></T>)\", invalidWithHint)\n\texpectParseErrorTSX(t, \"(<T extends>(y) => {}</T>)\", invalid)\n\texpectParseErrorTSX(t, \"(<T extends={false}>(y) => {}</T>)\", invalid)\n\texpectPrintedTSX(t, \"(<T = X>(y) => {})\", \"((y) => {\\n});\\n\")\n\texpectPrintedTSX(t, \"(<T extends X>(y) => {})\", \"((y) => {\\n});\\n\")\n\texpectPrintedTSX(t, \"(<T extends X = Y>(y) => {})\", \"((y) => {\\n});\\n\")\n\texpectPrintedTSX(t, \"(<T,>() => {})\", \"(() => {\\n});\\n\")\n\texpectPrintedTSX(t, \"(<T, X>(y) => {})\", \"((y) => {\\n});\\n\")\n\texpectPrintedTSX(t, \"(<T, X>(y): (() => {}) => {})\", \"((y) => {\\n});\\n\")\n\texpectParseErrorTSX(t, \"(<T>() => {})\", invalidWithHint+\"<stdin>: ERROR: Unexpected end of file before a closing \\\"T\\\" tag\\n<stdin>: NOTE: The opening \\\"T\\\" tag is here:\\n\")\n\texpectParseErrorTSX(t, \"(<T>(x: X<Y>) => {})\", invalidWithHint+\"<stdin>: ERROR: Unexpected end of file before a closing \\\"Y\\\" tag\\n<stdin>: NOTE: The opening \\\"Y\\\" tag is here:\\n\")\n\texpectParseErrorTSX(t, \"(<T>(x: X<Y>) => {})</Y>\", invalidWithHint+\"<stdin>: ERROR: Unexpected end of file before a closing \\\"T\\\" tag\\n<stdin>: NOTE: The opening \\\"T\\\" tag is here:\\n\")\n\texpectParseErrorTSX(t, \"(<[]>(y))\", \"<stdin>: ERROR: Expected identifier but found \\\"[\\\"\\n\")\n\texpectParseErrorTSX(t, \"(<T[]>(y))\", \"<stdin>: ERROR: Expected \\\">\\\" but found \\\"[\\\"\\n\")\n\texpectParseErrorTSX(t, \"(<T = X>(y))\", \"<stdin>: ERROR: Expected \\\"=>\\\" but found \\\")\\\"\\n\")\n\texpectParseErrorTSX(t, \"(<T, X>(y))\", \"<stdin>: ERROR: Expected \\\"=>\\\" but found \\\")\\\"\\n\")\n\texpectParseErrorTSX(t, \"(<T, X>y => {})\", \"<stdin>: ERROR: Expected \\\"(\\\" but found \\\"y\\\"\\n\")\n\n\t// TypeScript doesn't currently parse these even though it seems unambiguous\n\texpectPrintedTSX(t, \"async <T,>() => {}\", \"async () => {\\n};\\n\")\n\texpectPrintedTSX(t, \"async <T extends X>() => {}\", \"async () => {\\n};\\n\")\n\texpectPrintedTSX(t, \"async <T>()\", \"async();\\n\")\n\texpectParseErrorTSX(t, \"async <T>() => {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"=>\\\"\\n\")\n\texpectParseErrorTSX(t, \"async <T extends>() => {}\", \"<stdin>: ERROR: Expected \\\";\\\" but found \\\"extends\\\"\\n\")\n}\n\nfunc TestTSNoAmbiguousLessThan(t *testing.T) {\n\texpectPrintedTSNoAmbiguousLessThan(t, \"(<T,>() => {})\", \"(() => {\\n});\\n\")\n\texpectPrintedTSNoAmbiguousLessThan(t, \"(<T, X>() => {})\", \"(() => {\\n});\\n\")\n\texpectPrintedTSNoAmbiguousLessThan(t, \"(<T extends X>() => {})\", \"(() => {\\n});\\n\")\n\texpectParseErrorTSNoAmbiguousLessThan(t, \"(<T>x)\",\n\t\t\"<stdin>: ERROR: This syntax is not allowed in files with the \\\".mts\\\" or \\\".cts\\\" extension\\n\")\n\texpectParseErrorTSNoAmbiguousLessThan(t, \"(<T>() => {})\",\n\t\t\"<stdin>: ERROR: This syntax is not allowed in files with the \\\".mts\\\" or \\\".cts\\\" extension\\n\")\n\texpectParseErrorTSNoAmbiguousLessThan(t, \"(<T>(x) => {})\",\n\t\t\"<stdin>: ERROR: This syntax is not allowed in files with the \\\".mts\\\" or \\\".cts\\\" extension\\n\")\n\texpectParseErrorTSNoAmbiguousLessThan(t, \"<x>y</x>\",\n\t\t\"<stdin>: ERROR: This syntax is not allowed in files with the \\\".mts\\\" or \\\".cts\\\" extension\\n\"+\n\t\t\t\"<stdin>: ERROR: Unterminated regular expression\\n\")\n\texpectParseErrorTSNoAmbiguousLessThan(t, \"<x extends></x>\",\n\t\t\"<stdin>: ERROR: This syntax is not allowed in files with the \\\".mts\\\" or \\\".cts\\\" extension\\n\"+\n\t\t\t\"<stdin>: ERROR: Unexpected \\\">\\\"\\n\")\n\texpectParseErrorTSNoAmbiguousLessThan(t, \"<x extends={y}></x>\",\n\t\t\"<stdin>: ERROR: This syntax is not allowed in files with the \\\".mts\\\" or \\\".cts\\\" extension\\n\"+\n\t\t\t\"<stdin>: ERROR: Unexpected \\\"=\\\"\\n\")\n}\n\nfunc TestTSClassSideEffectOrder(t *testing.T) {\n\t// The order of computed property side effects must not change\n\texpectPrintedAssignSemanticsTS(t, `class Foo {\n\t[a()]() {}\n\t[b()];\n\t[c()] = 1;\n\t[d()]() {}\n\tstatic [e()];\n\tstatic [f()] = 1;\n\tstatic [g()]() {}\n\t[h()];\n}\n`, `var _a, _b, _c;\nclass Foo {\n  constructor() {\n    this[_c] = 1;\n  }\n  [a()]() {\n  }\n  [(b(), _c = c(), d())]() {\n  }\n  static {\n    this[_b] = 1;\n  }\n  static [(e(), _b = f(), _a = g(), h(), _a)]() {\n  }\n}\n`)\n\texpectPrintedAssignSemanticsTS(t, `class Foo {\n\tstatic [x()] = 1;\n}\n`, `var _a;\n_a = x();\nclass Foo {\n  static {\n    this[_a] = 1;\n  }\n}\n`)\n\texpectPrintedAssignSemanticsTargetTS(t, 2021, `class Foo {\n\t[a()]() {}\n\t[b()];\n\t[c()] = 1;\n\t[d()]() {}\n\tstatic [e()];\n\tstatic [f()] = 1;\n\tstatic [g()]() {}\n\t[h()];\n}\n`, `var _a, _b, _c;\nclass Foo {\n  constructor() {\n    this[_c] = 1;\n  }\n  [a()]() {\n  }\n  [(b(), _c = c(), d())]() {\n  }\n  static [(e(), _b = f(), _a = g(), h(), _a)]() {\n  }\n}\nFoo[_b] = 1;\n`)\n}\n\nfunc TestTSMangleStringEnumLength(t *testing.T) {\n\texpectPrintedTS(t, \"enum x { y = '' } z = x.y.length\",\n\t\t\"var x = /* @__PURE__ */ ((x) => {\\n  x[\\\"y\\\"] = \\\"\\\";\\n  return x;\\n})(x || {});\\nz = \\\"\\\" /* y */.length;\\n\")\n\n\texpectPrintedMangleTS(t, \"enum x { y = '' } x.y.length++\",\n\t\t\"var x = /* @__PURE__ */ ((x) => (x.y = \\\"\\\", x))(x || {});\\n\\\"\\\" /* y */.length++;\\n\")\n\n\texpectPrintedMangleTS(t, \"enum x { y = '' } x.y.length = z\",\n\t\t\"var x = /* @__PURE__ */ ((x) => (x.y = \\\"\\\", x))(x || {});\\n\\\"\\\" /* y */.length = z;\\n\")\n\n\texpectPrintedMangleTS(t, \"enum x { y = '' } z = x.y.length\",\n\t\t\"var x = /* @__PURE__ */ ((x) => (x.y = \\\"\\\", x))(x || {});\\nz = 0;\\n\")\n\n\texpectPrintedMangleTS(t, \"enum x { y = 'abc' } z = x.y.length\",\n\t\t\"var x = /* @__PURE__ */ ((x) => (x.y = \\\"abc\\\", x))(x || {});\\nz = 3;\\n\")\n\n\texpectPrintedMangleTS(t, \"enum x { y = 'ȧḃċ' } z = x.y.length\",\n\t\t\"var x = /* @__PURE__ */ ((x) => (x.y = \\\"ȧḃċ\\\", x))(x || {});\\nz = 3;\\n\")\n\n\texpectPrintedMangleTS(t, \"enum x { y = '👯‍♂️' } z = x.y.length\",\n\t\t\"var x = /* @__PURE__ */ ((x) => (x.y = \\\"👯‍♂️\\\", x))(x || {});\\nz = 5;\\n\")\n}\n\nfunc TestTSES5(t *testing.T) {\n\t// Errors from lowering hypothetical arrow function arguments to ES5 should\n\t// not leak out when backtracking. This comes up when parentheses are followed\n\t// by a colon in TypeScript because the colon could deliminate an arrow\n\t// function return type. See: https://github.com/evanw/esbuild/issues/2375.\n\texpectPrintedTargetTS(t, 2015, \"0 ? ([]) : 0\", \"0 ? [] : 0;\\n\")\n\texpectPrintedTargetTS(t, 2015, \"0 ? ({}) : 0\", \"0 ? {} : 0;\\n\")\n\texpectPrintedTargetTS(t, 5, \"0 ? ([]) : 0\", \"0 ? [] : 0;\\n\")\n\texpectPrintedTargetTS(t, 5, \"0 ? ({}) : 0\", \"0 ? {} : 0;\\n\")\n\texpectPrintedTargetTS(t, 2015, \"0 ? ([]): 0 => 0 : 0\", \"0 ? ([]) => 0 : 0;\\n\")\n\texpectPrintedTargetTS(t, 2015, \"0 ? ({}): 0 => 0 : 0\", \"0 ? ({}) => 0 : 0;\\n\")\n\texpectParseErrorTargetTS(t, 5, \"0 ? ([]): 0 => 0 : 0\", \"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n\texpectParseErrorTargetTS(t, 5, \"0 ? ({}): 0 => 0 : 0\", \"<stdin>: ERROR: Transforming destructuring to the configured target environment is not supported yet\\n\")\n}\n\nfunc TestTSUsing(t *testing.T) {\n\texpectPrintedTS(t, \"using x = y\", \"using x = y;\\n\")\n\texpectPrintedTS(t, \"using x: any = y\", \"using x = y;\\n\")\n\texpectPrintedTS(t, \"using x: any = y, z: any = _\", \"using x = y, z = _;\\n\")\n\texpectParseErrorTS(t, \"export using x: any = y\", \"<stdin>: ERROR: Unexpected \\\"using\\\"\\n\")\n\texpectParseErrorTS(t, \"namespace ns { export using x: any = y }\", \"<stdin>: ERROR: Unexpected \\\"using\\\"\\n\")\n}\n"
  },
  {
    "path": "internal/js_printer/js_printer.go",
    "content": "package js_printer\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"math\"\n\t\"math/big\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/renamer\"\n\t\"github.com/evanw/esbuild/internal/sourcemap\"\n)\n\nvar positiveInfinity = math.Inf(1)\nvar negativeInfinity = math.Inf(-1)\n\nconst hexChars = \"0123456789ABCDEF\"\nconst firstASCII = 0x20\nconst lastASCII = 0x7E\nconst firstHighSurrogate = 0xD800\nconst lastHighSurrogate = 0xDBFF\nconst firstLowSurrogate = 0xDC00\nconst lastLowSurrogate = 0xDFFF\n\nfunc QuoteIdentifier(js []byte, name string, unsupportedFeatures compat.JSFeature) []byte {\n\tisASCII := false\n\tasciiStart := 0\n\tfor i, c := range name {\n\t\tif c >= firstASCII && c <= lastASCII {\n\t\t\t// Fast path: a run of ASCII characters\n\t\t\tif !isASCII {\n\t\t\t\tisASCII = true\n\t\t\t\tasciiStart = i\n\t\t\t}\n\t\t} else {\n\t\t\t// Slow path: escape non-ACSII characters\n\t\t\tif isASCII {\n\t\t\t\tjs = append(js, name[asciiStart:i]...)\n\t\t\t\tisASCII = false\n\t\t\t}\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tjs = append(js, '\\\\', 'u', hexChars[c>>12], hexChars[(c>>8)&15], hexChars[(c>>4)&15], hexChars[c&15])\n\t\t\t} else if !unsupportedFeatures.Has(compat.UnicodeEscapes) {\n\t\t\t\tjs = append(js, fmt.Sprintf(\"\\\\u{%X}\", c)...)\n\t\t\t} else {\n\t\t\t\tpanic(\"Internal error: Cannot encode identifier: Unicode escapes are unsupported\")\n\t\t\t}\n\t\t}\n\t}\n\tif isASCII {\n\t\t// Print one final run of ASCII characters\n\t\tjs = append(js, name[asciiStart:]...)\n\t}\n\treturn js\n}\n\nfunc (p *printer) printUnquotedUTF16(text []uint16, quote rune, flags printQuotedFlags) {\n\ttemp := make([]byte, utf8.UTFMax)\n\tjs := p.js\n\ti := 0\n\tn := len(text)\n\n\t// Only compute the line length if necessary\n\tvar startLineLength int\n\twrapLongLines := false\n\tif p.options.LineLimit > 0 && (flags&printQuotedNoWrap) == 0 {\n\t\tstartLineLength = p.currentLineLength()\n\t\tif startLineLength > p.options.LineLimit {\n\t\t\tstartLineLength = p.options.LineLimit\n\t\t}\n\t\twrapLongLines = true\n\t}\n\n\tfor i < n {\n\t\t// Wrap long lines that are over the limit using escaped newlines\n\t\tif wrapLongLines && startLineLength+i >= p.options.LineLimit {\n\t\t\tjs = append(js, \"\\\\\\n\"...)\n\t\t\tstartLineLength -= p.options.LineLimit\n\t\t}\n\n\t\tc := text[i]\n\t\ti++\n\n\t\tswitch c {\n\t\t// Special-case the null character since it may mess with code written in C\n\t\t// that treats null characters as the end of the string.\n\t\tcase '\\x00':\n\t\t\t// We don't want \"\\x001\" to be written as \"\\01\"\n\t\t\tif i < n && text[i] >= '0' && text[i] <= '9' {\n\t\t\t\tjs = append(js, \"\\\\x00\"...)\n\t\t\t} else {\n\t\t\t\tjs = append(js, \"\\\\0\"...)\n\t\t\t}\n\n\t\t// Special-case the bell character since it may cause dumping this file to\n\t\t// the terminal to make a sound, which is undesirable. Note that we can't\n\t\t// use an octal literal to print this shorter since octal literals are not\n\t\t// allowed in strict mode (or in template strings).\n\t\tcase '\\x07':\n\t\t\tjs = append(js, \"\\\\x07\"...)\n\n\t\tcase '\\b':\n\t\t\tjs = append(js, \"\\\\b\"...)\n\n\t\tcase '\\f':\n\t\t\tjs = append(js, \"\\\\f\"...)\n\n\t\tcase '\\n':\n\t\t\tif quote == '`' {\n\t\t\t\tstartLineLength = -i // Printing a real newline resets the line length\n\t\t\t\tjs = append(js, '\\n')\n\t\t\t} else {\n\t\t\t\tjs = append(js, \"\\\\n\"...)\n\t\t\t}\n\n\t\tcase '\\r':\n\t\t\tjs = append(js, \"\\\\r\"...)\n\n\t\tcase '\\v':\n\t\t\tjs = append(js, \"\\\\v\"...)\n\n\t\tcase '\\x1B':\n\t\t\tjs = append(js, \"\\\\x1B\"...)\n\n\t\tcase '\\\\':\n\t\t\tjs = append(js, \"\\\\\\\\\"...)\n\n\t\tcase '/':\n\t\t\t// Avoid generating the sequence \"</script\" in JS code\n\t\t\tif !p.options.UnsupportedFeatures.Has(compat.InlineScript) && i >= 2 && text[i-2] == '<' && i+6 <= len(text) {\n\t\t\t\tscript := \"script\"\n\t\t\t\tmatches := true\n\t\t\t\tfor j := 0; j < 6; j++ {\n\t\t\t\t\ta := text[i+j]\n\t\t\t\t\tb := uint16(script[j])\n\t\t\t\t\tif a >= 'A' && a <= 'Z' {\n\t\t\t\t\t\ta += 'a' - 'A'\n\t\t\t\t\t}\n\t\t\t\t\tif a != b {\n\t\t\t\t\t\tmatches = false\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif matches {\n\t\t\t\t\tjs = append(js, '\\\\')\n\t\t\t\t}\n\t\t\t}\n\t\t\tjs = append(js, '/')\n\n\t\tcase '\\'':\n\t\t\tif quote == '\\'' {\n\t\t\t\tjs = append(js, '\\\\')\n\t\t\t}\n\t\t\tjs = append(js, '\\'')\n\n\t\tcase '\"':\n\t\t\tif quote == '\"' {\n\t\t\t\tjs = append(js, '\\\\')\n\t\t\t}\n\t\t\tjs = append(js, '\"')\n\n\t\tcase '`':\n\t\t\tif quote == '`' {\n\t\t\t\tjs = append(js, '\\\\')\n\t\t\t}\n\t\t\tjs = append(js, '`')\n\n\t\tcase '$':\n\t\t\tif quote == '`' && i < n && text[i] == '{' {\n\t\t\t\tjs = append(js, '\\\\')\n\t\t\t}\n\t\t\tjs = append(js, '$')\n\n\t\tcase '\\u2028':\n\t\t\tjs = append(js, \"\\\\u2028\"...)\n\n\t\tcase '\\u2029':\n\t\t\tjs = append(js, \"\\\\u2029\"...)\n\n\t\tcase '\\uFEFF':\n\t\t\tjs = append(js, \"\\\\uFEFF\"...)\n\n\t\tdefault:\n\t\t\tswitch {\n\t\t\t// Common case: just append a single byte\n\t\t\tcase c <= lastASCII:\n\t\t\t\tjs = append(js, byte(c))\n\n\t\t\t// Is this a high surrogate?\n\t\t\tcase c >= firstHighSurrogate && c <= lastHighSurrogate:\n\t\t\t\t// Is there a next character?\n\t\t\t\tif i < n {\n\t\t\t\t\tc2 := text[i]\n\n\t\t\t\t\t// Is it a low surrogate?\n\t\t\t\t\tif c2 >= firstLowSurrogate && c2 <= lastLowSurrogate {\n\t\t\t\t\t\tr := (rune(c) << 10) + rune(c2) + (0x10000 - (firstHighSurrogate << 10) - firstLowSurrogate)\n\t\t\t\t\t\ti++\n\n\t\t\t\t\t\t// Escape this character if UTF-8 isn't allowed\n\t\t\t\t\t\tif p.options.ASCIIOnly {\n\t\t\t\t\t\t\tif !p.options.UnsupportedFeatures.Has(compat.UnicodeEscapes) {\n\t\t\t\t\t\t\t\tjs = append(js, fmt.Sprintf(\"\\\\u{%X}\", r)...)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjs = append(js,\n\t\t\t\t\t\t\t\t\t'\\\\', 'u', hexChars[c>>12], hexChars[(c>>8)&15], hexChars[(c>>4)&15], hexChars[c&15],\n\t\t\t\t\t\t\t\t\t'\\\\', 'u', hexChars[c2>>12], hexChars[(c2>>8)&15], hexChars[(c2>>4)&15], hexChars[c2&15],\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, encode to UTF-8\n\t\t\t\t\t\twidth := utf8.EncodeRune(temp, r)\n\t\t\t\t\t\tjs = append(js, temp[:width]...)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Write an unpaired high surrogate\n\t\t\t\tjs = append(js, '\\\\', 'u', hexChars[c>>12], hexChars[(c>>8)&15], hexChars[(c>>4)&15], hexChars[c&15])\n\n\t\t\t// Is this an unpaired low surrogate or four-digit hex escape?\n\t\t\tcase (c >= firstLowSurrogate && c <= lastLowSurrogate) || (p.options.ASCIIOnly && c > 0xFF):\n\t\t\t\tjs = append(js, '\\\\', 'u', hexChars[c>>12], hexChars[(c>>8)&15], hexChars[(c>>4)&15], hexChars[c&15])\n\n\t\t\t// Can this be a two-digit hex escape?\n\t\t\tcase p.options.ASCIIOnly:\n\t\t\t\tjs = append(js, '\\\\', 'x', hexChars[c>>4], hexChars[c&15])\n\n\t\t\t// Otherwise, just encode to UTF-8\n\t\t\tdefault:\n\t\t\t\twidth := utf8.EncodeRune(temp, rune(c))\n\t\t\t\tjs = append(js, temp[:width]...)\n\t\t\t}\n\t\t}\n\t}\n\n\tp.js = js\n}\n\n// JSX tag syntax doesn't support character escapes so non-ASCII identifiers\n// must be printed as UTF-8 even when the charset is set to ASCII.\nfunc (p *printer) printJSXTag(tagOrNil js_ast.Expr) {\n\tswitch e := tagOrNil.Data.(type) {\n\tcase *js_ast.EString:\n\t\tp.addSourceMapping(tagOrNil.Loc)\n\t\tp.print(helpers.UTF16ToString(e.Value))\n\n\tcase *js_ast.EIdentifier:\n\t\tname := p.renamer.NameForSymbol(e.Ref)\n\t\tp.addSourceMappingForName(tagOrNil.Loc, name, e.Ref)\n\t\tp.print(name)\n\n\tcase *js_ast.EDot:\n\t\tp.printJSXTag(e.Target)\n\t\tp.print(\".\")\n\t\tp.addSourceMapping(e.NameLoc)\n\t\tp.print(e.Name)\n\n\tdefault:\n\t\tif tagOrNil.Data != nil {\n\t\t\tp.printExpr(tagOrNil, js_ast.LLowest, 0)\n\t\t}\n\t}\n}\n\ntype printer struct {\n\tsymbols                ast.SymbolMap\n\tastHelpers             js_ast.HelperContext\n\trenamer                renamer.Renamer\n\timportRecords          []ast.ImportRecord\n\tcallTarget             js_ast.E\n\texprComments           map[logger.Loc][]string\n\tprintedExprComments    map[logger.Loc]bool\n\thasLegalComment        map[string]struct{}\n\textractedLegalComments []string\n\tjs                     []byte\n\tjsonMetadataImports    []string\n\tbinaryExprStack        []binaryExprVisitor\n\toptions                Options\n\tbuilder                sourcemap.ChunkBuilder\n\tprintNextIndentAsSpace bool\n\n\tstmtStart          int\n\texportDefaultStart int\n\tarrowExprStart     int\n\tforOfInitStart     int\n\n\twithNesting          int\n\tprevOpEnd            int\n\tneedSpaceBeforeDot   int\n\tprevRegExpEnd        int\n\tnoLeadingNewlineHere int\n\toldLineStart         int\n\toldLineEnd           int\n\tintToBytesBuffer     [64]byte\n\tneedsSemicolon       bool\n\twasLazyExport        bool\n\tprevOp               js_ast.OpCode\n\tmoduleType           js_ast.ModuleType\n}\n\nfunc (p *printer) print(text string) {\n\tp.js = append(p.js, text...)\n}\n\n// This is the same as \"print(string(bytes))\" without any unnecessary temporary\n// allocations\nfunc (p *printer) printBytes(bytes []byte) {\n\tp.js = append(p.js, bytes...)\n}\n\ntype printQuotedFlags uint8\n\nconst (\n\tprintQuotedAllowBacktick printQuotedFlags = 1 << iota\n\tprintQuotedNoWrap\n)\n\nfunc (p *printer) printQuotedUTF8(text string, flags printQuotedFlags) {\n\tp.printQuotedUTF16(helpers.StringToUTF16(text), flags)\n}\n\nfunc (p *printer) addSourceMapping(loc logger.Loc) {\n\tif p.options.AddSourceMappings {\n\t\tp.builder.AddSourceMapping(loc, \"\", p.js)\n\t}\n}\n\nfunc (p *printer) addSourceMappingForName(loc logger.Loc, name string, ref ast.Ref) {\n\tif p.options.AddSourceMappings {\n\t\tif originalName := p.symbols.Get(ast.FollowSymbols(p.symbols, ref)).OriginalName; originalName != name {\n\t\t\tp.builder.AddSourceMapping(loc, originalName, p.js)\n\t\t} else {\n\t\t\tp.builder.AddSourceMapping(loc, \"\", p.js)\n\t\t}\n\t}\n}\n\nfunc (p *printer) printIndent() {\n\tif p.options.MinifyWhitespace {\n\t\treturn\n\t}\n\n\tif p.printNextIndentAsSpace {\n\t\tp.print(\" \")\n\t\tp.printNextIndentAsSpace = false\n\t\treturn\n\t}\n\n\tindent := p.options.Indent\n\tif p.options.LineLimit > 0 && indent*2 >= p.options.LineLimit {\n\t\tindent = p.options.LineLimit / 2\n\t}\n\tfor i := 0; i < indent; i++ {\n\t\tp.print(\"  \")\n\t}\n}\n\nfunc (p *printer) mangledPropName(ref ast.Ref) string {\n\tref = ast.FollowSymbols(p.symbols, ref)\n\tif name, ok := p.options.MangledProps[ref]; ok {\n\t\treturn name\n\t}\n\treturn p.renamer.NameForSymbol(ref)\n}\n\nfunc (p *printer) tryToGetImportedEnumValue(target js_ast.Expr, name string) (js_ast.TSEnumValue, bool) {\n\tif id, ok := target.Data.(*js_ast.EImportIdentifier); ok {\n\t\tref := ast.FollowSymbols(p.symbols, id.Ref)\n\t\tif symbol := p.symbols.Get(ref); symbol.Kind == ast.SymbolTSEnum {\n\t\t\tif enum, ok := p.options.TSEnums[ref]; ok {\n\t\t\t\tvalue, ok := enum[name]\n\t\t\t\treturn value, ok\n\t\t\t}\n\t\t}\n\t}\n\treturn js_ast.TSEnumValue{}, false\n}\n\nfunc (p *printer) tryToGetImportedEnumValueUTF16(target js_ast.Expr, name []uint16) (js_ast.TSEnumValue, string, bool) {\n\tif id, ok := target.Data.(*js_ast.EImportIdentifier); ok {\n\t\tref := ast.FollowSymbols(p.symbols, id.Ref)\n\t\tif symbol := p.symbols.Get(ref); symbol.Kind == ast.SymbolTSEnum {\n\t\t\tif enum, ok := p.options.TSEnums[ref]; ok {\n\t\t\t\tname := helpers.UTF16ToString(name)\n\t\t\t\tvalue, ok := enum[name]\n\t\t\t\treturn value, name, ok\n\t\t\t}\n\t\t}\n\t}\n\treturn js_ast.TSEnumValue{}, \"\", false\n}\n\nfunc (p *printer) printClauseAlias(loc logger.Loc, alias string) {\n\tif js_ast.IsIdentifier(alias) {\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(loc)\n\t\tp.printIdentifier(alias)\n\t} else {\n\t\tp.addSourceMapping(loc)\n\t\tp.printQuotedUTF8(alias, 0)\n\t}\n}\n\n// Note: The functions below check whether something can be printed as an\n// identifier or if it needs to be quoted (e.g. \"x.y\" vs. \"x['y']\") using the\n// ES5 identifier validity test to maximize cross-platform portability. Even\n// though newer JavaScript environments can handle more Unicode characters,\n// there isn't a published document that says which Unicode versions are\n// supported by which browsers. Even if a character is considered valid in the\n// latest version of Unicode, we don't know if the browser we're targeting\n// contains an older version of Unicode or not. So for safety, we quote\n// anything that isn't guaranteed to be compatible with ES5, the oldest\n// JavaScript language target that we support.\n\nfunc CanEscapeIdentifier(name string, UnsupportedFeatures compat.JSFeature, asciiOnly bool) bool {\n\treturn js_ast.IsIdentifierES5AndESNext(name) && (!asciiOnly ||\n\t\t!UnsupportedFeatures.Has(compat.UnicodeEscapes) ||\n\t\t!helpers.ContainsNonBMPCodePoint(name))\n}\n\nfunc (p *printer) canPrintIdentifier(name string) bool {\n\treturn js_ast.IsIdentifierES5AndESNext(name) && (!p.options.ASCIIOnly ||\n\t\t!p.options.UnsupportedFeatures.Has(compat.UnicodeEscapes) ||\n\t\t!helpers.ContainsNonBMPCodePoint(name))\n}\n\nfunc (p *printer) canPrintIdentifierUTF16(name []uint16) bool {\n\treturn js_ast.IsIdentifierES5AndESNextUTF16(name) && (!p.options.ASCIIOnly ||\n\t\t!p.options.UnsupportedFeatures.Has(compat.UnicodeEscapes) ||\n\t\t!helpers.ContainsNonBMPCodePointUTF16(name))\n}\n\nfunc (p *printer) printIdentifier(name string) {\n\tif p.options.ASCIIOnly {\n\t\tp.js = QuoteIdentifier(p.js, name, p.options.UnsupportedFeatures)\n\t} else {\n\t\tp.print(name)\n\t}\n}\n\n// This is the same as \"printIdentifier(StringToUTF16(bytes))\" without any\n// unnecessary temporary allocations\nfunc (p *printer) printIdentifierUTF16(name []uint16) {\n\tvar temp [utf8.UTFMax]byte\n\tn := len(name)\n\n\tfor i := 0; i < n; i++ {\n\t\tc := rune(name[i])\n\n\t\tif c >= firstHighSurrogate && c <= lastHighSurrogate && i+1 < n {\n\t\t\tif c2 := rune(name[i+1]); c2 >= firstLowSurrogate && c2 <= lastLowSurrogate {\n\t\t\t\tc = (c << 10) + c2 + (0x10000 - (firstHighSurrogate << 10) - firstLowSurrogate)\n\t\t\t\ti++\n\t\t\t}\n\t\t}\n\n\t\tif p.options.ASCIIOnly && c > lastASCII {\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tp.js = append(p.js, '\\\\', 'u', hexChars[c>>12], hexChars[(c>>8)&15], hexChars[(c>>4)&15], hexChars[c&15])\n\t\t\t} else if !p.options.UnsupportedFeatures.Has(compat.UnicodeEscapes) {\n\t\t\t\tp.js = append(p.js, fmt.Sprintf(\"\\\\u{%X}\", c)...)\n\t\t\t} else {\n\t\t\t\tpanic(\"Internal error: Cannot encode identifier: Unicode escapes are unsupported\")\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\twidth := utf8.EncodeRune(temp[:], c)\n\t\tp.js = append(p.js, temp[:width]...)\n\t}\n}\n\nfunc (p *printer) printNumber(value float64, level js_ast.L) {\n\tabsValue := math.Abs(value)\n\n\tif value != value {\n\t\tp.printSpaceBeforeIdentifier()\n\t\tif p.withNesting != 0 {\n\t\t\t// \"with (x) NaN\" really means \"x.NaN\" so avoid identifiers when \"with\" is present\n\t\t\twrap := level >= js_ast.LMultiply\n\t\t\tif wrap {\n\t\t\t\tp.print(\"(\")\n\t\t\t}\n\t\t\tif p.options.MinifyWhitespace {\n\t\t\t\tp.print(\"0/0\")\n\t\t\t} else {\n\t\t\t\tp.print(\"0 / 0\")\n\t\t\t}\n\t\t\tif wrap {\n\t\t\t\tp.print(\")\")\n\t\t\t}\n\t\t} else {\n\t\t\tp.print(\"NaN\")\n\t\t}\n\t} else if value == positiveInfinity || value == negativeInfinity {\n\t\t// \"with (x) Infinity\" really means \"x.Infinity\" so avoid identifiers when \"with\" is present\n\t\twrap := ((p.options.MinifySyntax || p.withNesting != 0) && level >= js_ast.LMultiply) ||\n\t\t\t(value == negativeInfinity && level >= js_ast.LPrefix)\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t}\n\t\tif value == negativeInfinity {\n\t\t\tp.printSpaceBeforeOperator(js_ast.UnOpNeg)\n\t\t\tp.print(\"-\")\n\t\t} else {\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t}\n\t\tif !p.options.MinifySyntax && p.withNesting == 0 {\n\t\t\tp.print(\"Infinity\")\n\t\t} else if p.options.MinifyWhitespace {\n\t\t\tp.print(\"1/0\")\n\t\t} else {\n\t\t\tp.print(\"1 / 0\")\n\t\t}\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\t} else {\n\t\tif !math.Signbit(value) {\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tp.printNonNegativeFloat(absValue)\n\t\t} else if level >= js_ast.LPrefix {\n\t\t\t// Expressions such as \"(-1).toString\" need to wrap negative numbers.\n\t\t\t// Instead of testing for \"value < 0\" we test for \"signbit(value)\" and\n\t\t\t// \"!isNaN(value)\" because we need this to be true for \"-0\" and \"-0 < 0\"\n\t\t\t// is false.\n\t\t\tp.print(\"(-\")\n\t\t\tp.printNonNegativeFloat(absValue)\n\t\t\tp.print(\")\")\n\t\t} else {\n\t\t\tp.printSpaceBeforeOperator(js_ast.UnOpNeg)\n\t\t\tp.print(\"-\")\n\t\t\tp.printNonNegativeFloat(absValue)\n\t\t}\n\t}\n}\n\nfunc (p *printer) willPrintExprCommentsAtLoc(loc logger.Loc) bool {\n\treturn !p.options.MinifyWhitespace && p.exprComments[loc] != nil && !p.printedExprComments[loc]\n}\n\nfunc (p *printer) willPrintExprCommentsForAnyOf(exprs []js_ast.Expr) bool {\n\tfor _, expr := range exprs {\n\t\tif p.willPrintExprCommentsAtLoc(expr.Loc) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (p *printer) printBinding(binding js_ast.Binding) {\n\tswitch b := binding.Data.(type) {\n\tcase *js_ast.BMissing:\n\t\tp.addSourceMapping(binding.Loc)\n\n\tcase *js_ast.BIdentifier:\n\t\tname := p.renamer.NameForSymbol(b.Ref)\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMappingForName(binding.Loc, name, b.Ref)\n\t\tp.printIdentifier(name)\n\n\tcase *js_ast.BArray:\n\t\tisMultiLine := (len(b.Items) > 0 && !b.IsSingleLine) || p.willPrintExprCommentsAtLoc(b.CloseBracketLoc)\n\t\tif !p.options.MinifyWhitespace && !isMultiLine {\n\t\t\tfor _, item := range b.Items {\n\t\t\t\tif p.willPrintExprCommentsAtLoc(item.Loc) {\n\t\t\t\t\tisMultiLine = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tp.addSourceMapping(binding.Loc)\n\t\tp.print(\"[\")\n\t\tif len(b.Items) > 0 || isMultiLine {\n\t\t\tif isMultiLine {\n\t\t\t\tp.options.Indent++\n\t\t\t}\n\n\t\t\tfor i, item := range b.Items {\n\t\t\t\tif i != 0 {\n\t\t\t\t\tp.print(\",\")\n\t\t\t\t}\n\t\t\t\tif p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit() {\n\t\t\t\t\tif isMultiLine {\n\t\t\t\t\t\tp.printNewline()\n\t\t\t\t\t\tp.printIndent()\n\t\t\t\t\t} else if i != 0 {\n\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tp.printExprCommentsAtLoc(item.Loc)\n\t\t\t\tif b.HasSpread && i+1 == len(b.Items) {\n\t\t\t\t\tp.addSourceMapping(item.Loc)\n\t\t\t\t\tp.print(\"...\")\n\t\t\t\t\tp.printExprCommentsAtLoc(item.Binding.Loc)\n\t\t\t\t}\n\t\t\t\tp.printBinding(item.Binding)\n\n\t\t\t\tif item.DefaultValueOrNil.Data != nil {\n\t\t\t\t\tp.printSpace()\n\t\t\t\t\tp.print(\"=\")\n\t\t\t\t\tp.printSpace()\n\t\t\t\t\tp.printExprWithoutLeadingNewline(item.DefaultValueOrNil, js_ast.LComma, 0)\n\t\t\t\t}\n\n\t\t\t\t// Make sure there's a comma after trailing missing items\n\t\t\t\tif _, ok := item.Binding.Data.(*js_ast.BMissing); ok && i == len(b.Items)-1 {\n\t\t\t\t\tp.print(\",\")\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif isMultiLine {\n\t\t\t\tp.printNewline()\n\t\t\t\tp.printExprCommentsAfterCloseTokenAtLoc(b.CloseBracketLoc)\n\t\t\t\tp.options.Indent--\n\t\t\t\tp.printIndent()\n\t\t\t}\n\t\t}\n\t\tp.addSourceMapping(b.CloseBracketLoc)\n\t\tp.print(\"]\")\n\n\tcase *js_ast.BObject:\n\t\tisMultiLine := (len(b.Properties) > 0 && !b.IsSingleLine) || p.willPrintExprCommentsAtLoc(b.CloseBraceLoc)\n\t\tif !p.options.MinifyWhitespace && !isMultiLine {\n\t\t\tfor _, property := range b.Properties {\n\t\t\t\tif p.willPrintExprCommentsAtLoc(property.Loc) {\n\t\t\t\t\tisMultiLine = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tp.addSourceMapping(binding.Loc)\n\t\tp.print(\"{\")\n\t\tif len(b.Properties) > 0 || isMultiLine {\n\t\t\tif isMultiLine {\n\t\t\t\tp.options.Indent++\n\t\t\t}\n\n\t\t\tfor i, property := range b.Properties {\n\t\t\t\tif i != 0 {\n\t\t\t\t\tp.print(\",\")\n\t\t\t\t}\n\t\t\t\tif p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit() {\n\t\t\t\t\tif isMultiLine {\n\t\t\t\t\t\tp.printNewline()\n\t\t\t\t\t\tp.printIndent()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tp.printExprCommentsAtLoc(property.Loc)\n\n\t\t\t\tif property.IsSpread {\n\t\t\t\t\tp.addSourceMapping(property.Loc)\n\t\t\t\t\tp.print(\"...\")\n\t\t\t\t\tp.printExprCommentsAtLoc(property.Value.Loc)\n\t\t\t\t} else {\n\t\t\t\t\tif property.IsComputed {\n\t\t\t\t\t\tp.addSourceMapping(property.Loc)\n\t\t\t\t\t\tisMultiLine := p.willPrintExprCommentsAtLoc(property.Key.Loc) || p.willPrintExprCommentsAtLoc(property.CloseBracketLoc)\n\t\t\t\t\t\tp.print(\"[\")\n\t\t\t\t\t\tif isMultiLine {\n\t\t\t\t\t\t\tp.printNewline()\n\t\t\t\t\t\t\tp.options.Indent++\n\t\t\t\t\t\t\tp.printIndent()\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.printExpr(property.Key, js_ast.LComma, 0)\n\t\t\t\t\t\tif isMultiLine {\n\t\t\t\t\t\t\tp.printNewline()\n\t\t\t\t\t\t\tp.printExprCommentsAfterCloseTokenAtLoc(property.CloseBracketLoc)\n\t\t\t\t\t\t\tp.options.Indent--\n\t\t\t\t\t\t\tp.printIndent()\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif property.CloseBracketLoc.Start > property.Loc.Start {\n\t\t\t\t\t\t\tp.addSourceMapping(property.CloseBracketLoc)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.print(\"]:\")\n\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\tp.printBinding(property.Value)\n\n\t\t\t\t\t\tif property.DefaultValueOrNil.Data != nil {\n\t\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\t\tp.print(\"=\")\n\t\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\t\tp.printExprWithoutLeadingNewline(property.DefaultValueOrNil, js_ast.LComma, 0)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\tif str, ok := property.Key.Data.(*js_ast.EString); ok && !property.PreferQuotedKey && p.canPrintIdentifierUTF16(str.Value) {\n\t\t\t\t\t\t// Use a shorthand property if the names are the same\n\t\t\t\t\t\tif id, ok := property.Value.Data.(*js_ast.BIdentifier); ok &&\n\t\t\t\t\t\t\t!p.willPrintExprCommentsAtLoc(property.Value.Loc) &&\n\t\t\t\t\t\t\thelpers.UTF16EqualsString(str.Value, p.renamer.NameForSymbol(id.Ref)) {\n\t\t\t\t\t\t\tif p.options.AddSourceMappings {\n\t\t\t\t\t\t\t\tp.addSourceMappingForName(property.Key.Loc, helpers.UTF16ToString(str.Value), id.Ref)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tp.printIdentifierUTF16(str.Value)\n\t\t\t\t\t\t\tif property.DefaultValueOrNil.Data != nil {\n\t\t\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\t\t\tp.print(\"=\")\n\t\t\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\t\t\tp.printExprWithoutLeadingNewline(property.DefaultValueOrNil, js_ast.LComma, 0)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tp.addSourceMapping(property.Key.Loc)\n\t\t\t\t\t\tp.printIdentifierUTF16(str.Value)\n\t\t\t\t\t} else if mangled, ok := property.Key.Data.(*js_ast.ENameOfSymbol); ok {\n\t\t\t\t\t\tname := p.mangledPropName(mangled.Ref)\n\t\t\t\t\t\tif p.canPrintIdentifier(name) {\n\t\t\t\t\t\t\tp.addSourceMappingForName(property.Key.Loc, name, mangled.Ref)\n\t\t\t\t\t\t\tp.printIdentifier(name)\n\n\t\t\t\t\t\t\t// Use a shorthand property if the names are the same\n\t\t\t\t\t\t\tif id, ok := property.Value.Data.(*js_ast.BIdentifier); ok &&\n\t\t\t\t\t\t\t\t!p.willPrintExprCommentsAtLoc(property.Value.Loc) &&\n\t\t\t\t\t\t\t\tname == p.renamer.NameForSymbol(id.Ref) {\n\t\t\t\t\t\t\t\tif property.DefaultValueOrNil.Data != nil {\n\t\t\t\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\t\t\t\tp.print(\"=\")\n\t\t\t\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\t\t\t\tp.printExprWithoutLeadingNewline(property.DefaultValueOrNil, js_ast.LComma, 0)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tp.addSourceMapping(property.Key.Loc)\n\t\t\t\t\t\t\tp.printQuotedUTF8(name, 0)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.printExpr(property.Key, js_ast.LLowest, 0)\n\t\t\t\t\t}\n\n\t\t\t\t\tp.print(\":\")\n\t\t\t\t\tp.printSpace()\n\t\t\t\t}\n\t\t\t\tp.printBinding(property.Value)\n\n\t\t\t\tif property.DefaultValueOrNil.Data != nil {\n\t\t\t\t\tp.printSpace()\n\t\t\t\t\tp.print(\"=\")\n\t\t\t\t\tp.printSpace()\n\t\t\t\t\tp.printExprWithoutLeadingNewline(property.DefaultValueOrNil, js_ast.LComma, 0)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif isMultiLine {\n\t\t\t\tp.printNewline()\n\t\t\t\tp.printExprCommentsAfterCloseTokenAtLoc(b.CloseBraceLoc)\n\t\t\t\tp.options.Indent--\n\t\t\t\tp.printIndent()\n\t\t\t} else {\n\t\t\t\t// This block is only reached if len(b.Properties) > 0\n\t\t\t\tp.printSpace()\n\t\t\t}\n\t\t}\n\t\tp.addSourceMapping(b.CloseBraceLoc)\n\t\tp.print(\"}\")\n\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"Unexpected binding of type %T\", binding.Data))\n\t}\n}\n\nfunc (p *printer) printSpace() {\n\tif !p.options.MinifyWhitespace {\n\t\tp.print(\" \")\n\t}\n}\n\nfunc (p *printer) printNewline() {\n\tif !p.options.MinifyWhitespace {\n\t\tp.print(\"\\n\")\n\t}\n}\n\nfunc (p *printer) currentLineLength() int {\n\tjs := p.js\n\tn := len(js)\n\tstop := p.oldLineEnd\n\n\t// Update \"oldLineStart\" to the start of the current line\n\tfor i := n; i > stop; i-- {\n\t\tif c := js[i-1]; c == '\\r' || c == '\\n' {\n\t\t\tp.oldLineStart = i\n\t\t\tbreak\n\t\t}\n\t}\n\n\tp.oldLineEnd = n\n\treturn n - p.oldLineStart\n}\n\nfunc (p *printer) printNewlinePastLineLimit() bool {\n\tif p.currentLineLength() < p.options.LineLimit {\n\t\treturn false\n\t}\n\tp.print(\"\\n\")\n\tp.printIndent()\n\treturn true\n}\n\nfunc (p *printer) printSpaceBeforeOperator(next js_ast.OpCode) {\n\tif p.prevOpEnd == len(p.js) {\n\t\tprev := p.prevOp\n\n\t\t// \"+ + y\" => \"+ +y\"\n\t\t// \"+ ++ y\" => \"+ ++y\"\n\t\t// \"x + + y\" => \"x+ +y\"\n\t\t// \"x ++ + y\" => \"x+++y\"\n\t\t// \"x + ++ y\" => \"x+ ++y\"\n\t\t// \"-- >\" => \"-- >\"\n\t\t// \"< ! --\" => \"<! --\"\n\t\tif ((prev == js_ast.BinOpAdd || prev == js_ast.UnOpPos) && (next == js_ast.BinOpAdd || next == js_ast.UnOpPos || next == js_ast.UnOpPreInc)) ||\n\t\t\t((prev == js_ast.BinOpSub || prev == js_ast.UnOpNeg) && (next == js_ast.BinOpSub || next == js_ast.UnOpNeg || next == js_ast.UnOpPreDec)) ||\n\t\t\t(prev == js_ast.UnOpPostDec && next == js_ast.BinOpGt) ||\n\t\t\t(prev == js_ast.UnOpNot && next == js_ast.UnOpPreDec && len(p.js) > 1 && p.js[len(p.js)-2] == '<') {\n\t\t\tp.print(\" \")\n\t\t}\n\t}\n}\n\nfunc (p *printer) printSemicolonAfterStatement() {\n\tif !p.options.MinifyWhitespace {\n\t\tp.print(\";\\n\")\n\t} else {\n\t\tp.needsSemicolon = true\n\t}\n}\n\nfunc (p *printer) printSemicolonIfNeeded() {\n\tif p.needsSemicolon {\n\t\tp.print(\";\")\n\t\tp.needsSemicolon = false\n\t}\n}\n\nfunc (p *printer) printSpaceBeforeIdentifier() {\n\tif c, _ := utf8.DecodeLastRune(p.js); js_ast.IsIdentifierContinue(c) || p.prevRegExpEnd == len(p.js) {\n\t\tp.print(\" \")\n\t}\n}\n\ntype fnArgsOpts struct {\n\topenParenLoc              logger.Loc\n\taddMappingForOpenParenLoc bool\n\thasRestArg                bool\n\tisArrow                   bool\n}\n\nfunc (p *printer) printFnArgs(args []js_ast.Arg, opts fnArgsOpts) {\n\twrap := true\n\n\t// Minify \"(a) => {}\" as \"a=>{}\"\n\tif p.options.MinifyWhitespace && !opts.hasRestArg && opts.isArrow && len(args) == 1 {\n\t\tif _, ok := args[0].Binding.Data.(*js_ast.BIdentifier); ok && args[0].DefaultOrNil.Data == nil {\n\t\t\twrap = false\n\t\t}\n\t}\n\n\tif wrap {\n\t\tif opts.addMappingForOpenParenLoc {\n\t\t\tp.addSourceMapping(opts.openParenLoc)\n\t\t}\n\t\tp.print(\"(\")\n\t}\n\n\tfor i, arg := range args {\n\t\tif i != 0 {\n\t\t\tp.print(\",\")\n\t\t\tp.printSpace()\n\t\t}\n\t\tp.printDecorators(arg.Decorators, printSpaceAfterDecorator)\n\t\tif opts.hasRestArg && i+1 == len(args) {\n\t\t\tp.print(\"...\")\n\t\t}\n\t\tp.printBinding(arg.Binding)\n\n\t\tif arg.DefaultOrNil.Data != nil {\n\t\t\tp.printSpace()\n\t\t\tp.print(\"=\")\n\t\t\tp.printSpace()\n\t\t\tp.printExprWithoutLeadingNewline(arg.DefaultOrNil, js_ast.LComma, 0)\n\t\t}\n\t}\n\n\tif wrap {\n\t\tp.print(\")\")\n\t}\n}\n\nfunc (p *printer) printFn(fn js_ast.Fn) {\n\tp.printFnArgs(fn.Args, fnArgsOpts{hasRestArg: fn.HasRestArg})\n\tp.printSpace()\n\tp.printBlock(fn.Body.Loc, fn.Body.Block)\n}\n\ntype printAfterDecorator uint8\n\nconst (\n\tprintNewlineAfterDecorator printAfterDecorator = iota\n\tprintSpaceAfterDecorator\n)\n\nfunc (p *printer) printDecorators(decorators []js_ast.Decorator, defaultMode printAfterDecorator) (omitIndentAfter bool) {\n\toldMode := defaultMode\n\n\tfor _, decorator := range decorators {\n\t\twrap := false\n\t\twasCallTarget := false\n\t\texpr := decorator.Value\n\t\tmode := defaultMode\n\t\tif decorator.OmitNewlineAfter {\n\t\t\tmode = printSpaceAfterDecorator\n\t\t}\n\n\touter:\n\t\tfor {\n\t\t\tisCallTarget := wasCallTarget\n\t\t\twasCallTarget = false\n\n\t\t\tswitch e := expr.Data.(type) {\n\t\t\tcase *js_ast.EIdentifier:\n\t\t\t\t// \"@foo\"\n\t\t\t\tbreak outer\n\n\t\t\tcase *js_ast.ECall:\n\t\t\t\t// \"@foo()\"\n\t\t\t\texpr = e.Target\n\t\t\t\twasCallTarget = true\n\t\t\t\tcontinue\n\n\t\t\tcase *js_ast.EDot:\n\t\t\t\t// \"@foo.bar\"\n\t\t\t\tif p.canPrintIdentifier(e.Name) {\n\t\t\t\t\texpr = e.Target\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// \"@foo.\\u30FF\" => \"@(foo['\\u30FF'])\"\n\t\t\t\tbreak\n\n\t\t\tcase *js_ast.EIndex:\n\t\t\t\tif _, ok := e.Index.Data.(*js_ast.EPrivateIdentifier); ok {\n\t\t\t\t\t// \"@foo.#bar\"\n\t\t\t\t\texpr = e.Target\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// \"@(foo[bar])\"\n\t\t\t\tbreak\n\n\t\t\tcase *js_ast.EImportIdentifier:\n\t\t\t\tref := ast.FollowSymbols(p.symbols, e.Ref)\n\t\t\t\tsymbol := p.symbols.Get(ref)\n\n\t\t\t\tif symbol.ImportItemStatus == ast.ImportItemMissing {\n\t\t\t\t\t// \"@(void 0)\"\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tif symbol.NamespaceAlias != nil && isCallTarget && e.WasOriginallyIdentifier {\n\t\t\t\t\t// \"@((0, import_ns.fn)())\"\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tif value := p.options.ConstValues[ref]; value.Kind != js_ast.ConstValueNone {\n\t\t\t\t\t// \"@(<inlined constant>)\"\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// \"@foo\"\n\t\t\t\t// \"@import_ns.fn\"\n\t\t\t\tbreak outer\n\n\t\t\tdefault:\n\t\t\t\t// \"@(foo + bar)\"\n\t\t\t\t// \"@(() => {})\"\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\twrap = true\n\t\t\tbreak outer\n\t\t}\n\n\t\tp.addSourceMapping(decorator.AtLoc)\n\t\tif oldMode == printNewlineAfterDecorator {\n\t\t\tp.printIndent()\n\t\t}\n\n\t\tp.print(\"@\")\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t}\n\t\tp.printExpr(decorator.Value, js_ast.LLowest, 0)\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\t\tswitch mode {\n\t\tcase printNewlineAfterDecorator:\n\t\t\tp.printNewline()\n\n\t\tcase printSpaceAfterDecorator:\n\t\t\tp.printSpace()\n\t\t}\n\t\toldMode = mode\n\t}\n\n\tomitIndentAfter = oldMode == printSpaceAfterDecorator\n\treturn\n}\n\nfunc (p *printer) printClass(class js_ast.Class) {\n\tif class.ExtendsOrNil.Data != nil {\n\t\tp.print(\" extends\")\n\t\tp.printSpace()\n\t\tp.printExpr(class.ExtendsOrNil, js_ast.LNew-1, 0)\n\t}\n\tp.printSpace()\n\n\tp.addSourceMapping(class.BodyLoc)\n\tp.print(\"{\")\n\tp.printNewline()\n\tp.options.Indent++\n\n\tfor _, item := range class.Properties {\n\t\tp.printSemicolonIfNeeded()\n\t\tomitIndent := p.printDecorators(item.Decorators, printNewlineAfterDecorator)\n\t\tif !omitIndent {\n\t\t\tp.printIndent()\n\t\t}\n\n\t\tif item.Kind == js_ast.PropertyClassStaticBlock {\n\t\t\tp.addSourceMapping(item.Loc)\n\t\t\tp.print(\"static\")\n\t\t\tp.printSpace()\n\t\t\tp.printBlock(item.ClassStaticBlock.Loc, item.ClassStaticBlock.Block)\n\t\t\tp.printNewline()\n\t\t\tcontinue\n\t\t}\n\n\t\tp.printProperty(item)\n\n\t\t// Need semicolons after class fields\n\t\tif item.ValueOrNil.Data == nil {\n\t\t\tp.printSemicolonAfterStatement()\n\t\t} else {\n\t\t\tp.printNewline()\n\t\t}\n\t}\n\n\tp.needsSemicolon = false\n\tp.printExprCommentsAfterCloseTokenAtLoc(class.CloseBraceLoc)\n\tp.options.Indent--\n\tp.printIndent()\n\tif class.CloseBraceLoc.Start > class.BodyLoc.Start {\n\t\tp.addSourceMapping(class.CloseBraceLoc)\n\t}\n\tp.print(\"}\")\n}\n\nfunc (p *printer) printProperty(property js_ast.Property) {\n\tp.printExprCommentsAtLoc(property.Loc)\n\n\tif property.Kind == js_ast.PropertySpread {\n\t\tp.addSourceMapping(property.Loc)\n\t\tp.print(\"...\")\n\t\tp.printExpr(property.ValueOrNil, js_ast.LComma, 0)\n\t\treturn\n\t}\n\n\t// Handle key syntax compression for cross-module constant inlining of enums\n\tvar keyFlags printExprFlags\n\tif p.options.MinifySyntax && property.Flags.Has(js_ast.PropertyIsComputed) {\n\t\tproperty.Key = p.lateConstantFoldUnaryOrBinaryOrIfExpr(property.Key)\n\t\tkeyFlags |= parentWasUnaryOrBinaryOrIfTest\n\n\t\tif key, ok := property.Key.Data.(*js_ast.EInlinedEnum); ok {\n\t\t\tproperty.Key = key.Value\n\t\t}\n\n\t\t// Remove the computed flag if it's no longer needed\n\t\tswitch key := property.Key.Data.(type) {\n\t\tcase *js_ast.ENumber:\n\t\t\tproperty.Flags &= ^js_ast.PropertyIsComputed\n\n\t\tcase *js_ast.EString:\n\t\t\tif !helpers.UTF16EqualsString(key.Value, \"__proto__\") &&\n\t\t\t\t!helpers.UTF16EqualsString(key.Value, \"constructor\") &&\n\t\t\t\t!helpers.UTF16EqualsString(key.Value, \"prototype\") {\n\t\t\t\tproperty.Flags &= ^js_ast.PropertyIsComputed\n\t\t\t}\n\t\t}\n\t}\n\n\tif property.Flags.Has(js_ast.PropertyIsStatic) {\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(property.Loc)\n\t\tp.print(\"static\")\n\t\tp.printSpace()\n\t}\n\n\tswitch property.Kind {\n\tcase js_ast.PropertyGetter:\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(property.Loc)\n\t\tp.print(\"get\")\n\t\tp.printSpace()\n\n\tcase js_ast.PropertySetter:\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(property.Loc)\n\t\tp.print(\"set\")\n\t\tp.printSpace()\n\n\tcase js_ast.PropertyAutoAccessor:\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(property.Loc)\n\t\tp.print(\"accessor\")\n\t\tp.printSpace()\n\t}\n\n\tif fn, ok := property.ValueOrNil.Data.(*js_ast.EFunction); property.Kind.IsMethodDefinition() && ok {\n\t\tif fn.Fn.IsAsync {\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tp.addSourceMapping(property.Loc)\n\t\t\tp.print(\"async\")\n\t\t\tp.printSpace()\n\t\t}\n\t\tif fn.Fn.IsGenerator {\n\t\t\tp.addSourceMapping(property.Loc)\n\t\t\tp.print(\"*\")\n\t\t}\n\t}\n\n\tisComputed := property.Flags.Has(js_ast.PropertyIsComputed)\n\n\t// Automatically print numbers that would cause a syntax error as computed properties\n\tif !isComputed {\n\t\tif key, ok := property.Key.Data.(*js_ast.ENumber); ok {\n\t\t\tif math.Signbit(key.Value) || (key.Value == positiveInfinity && p.options.MinifySyntax) {\n\t\t\t\t// \"{ -1: 0 }\" must be printed as \"{ [-1]: 0 }\"\n\t\t\t\t// \"{ 1/0: 0 }\" must be printed as \"{ [1/0]: 0 }\"\n\t\t\t\tisComputed = true\n\t\t\t}\n\t\t}\n\t}\n\n\tif isComputed {\n\t\tp.addSourceMapping(property.Loc)\n\t\tisMultiLine := p.willPrintExprCommentsAtLoc(property.Key.Loc) || p.willPrintExprCommentsAtLoc(property.CloseBracketLoc)\n\t\tp.print(\"[\")\n\t\tif isMultiLine {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent++\n\t\t\tp.printIndent()\n\t\t}\n\t\tp.printExpr(property.Key, js_ast.LComma, keyFlags)\n\t\tif isMultiLine {\n\t\t\tp.printNewline()\n\t\t\tp.printExprCommentsAfterCloseTokenAtLoc(property.CloseBracketLoc)\n\t\t\tp.options.Indent--\n\t\t\tp.printIndent()\n\t\t}\n\t\tif property.CloseBracketLoc.Start > property.Loc.Start {\n\t\t\tp.addSourceMapping(property.CloseBracketLoc)\n\t\t}\n\t\tp.print(\"]\")\n\n\t\tif property.ValueOrNil.Data != nil {\n\t\t\tif fn, ok := property.ValueOrNil.Data.(*js_ast.EFunction); property.Kind.IsMethodDefinition() && ok {\n\t\t\t\tp.printFn(fn.Fn)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tp.print(\":\")\n\t\t\tp.printSpace()\n\t\t\tp.printExprWithoutLeadingNewline(property.ValueOrNil, js_ast.LComma, 0)\n\t\t}\n\n\t\tif property.InitializerOrNil.Data != nil {\n\t\t\tp.printSpace()\n\t\t\tp.print(\"=\")\n\t\t\tp.printSpace()\n\t\t\tp.printExprWithoutLeadingNewline(property.InitializerOrNil, js_ast.LComma, 0)\n\t\t}\n\t\treturn\n\t}\n\n\tswitch key := property.Key.Data.(type) {\n\tcase *js_ast.EPrivateIdentifier:\n\t\tname := p.renamer.NameForSymbol(key.Ref)\n\t\tp.addSourceMappingForName(property.Key.Loc, name, key.Ref)\n\t\tp.printIdentifier(name)\n\n\tcase *js_ast.ENameOfSymbol:\n\t\tname := p.mangledPropName(key.Ref)\n\t\tif p.canPrintIdentifier(name) {\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tp.addSourceMappingForName(property.Key.Loc, name, key.Ref)\n\t\t\tp.printIdentifier(name)\n\n\t\t\t// Use a shorthand property if the names are the same\n\t\t\tif !p.options.UnsupportedFeatures.Has(compat.ObjectExtensions) && property.ValueOrNil.Data != nil && !p.willPrintExprCommentsAtLoc(property.ValueOrNil.Loc) {\n\t\t\t\tswitch e := property.ValueOrNil.Data.(type) {\n\t\t\t\tcase *js_ast.EIdentifier:\n\t\t\t\t\tif name == p.renamer.NameForSymbol(e.Ref) {\n\t\t\t\t\t\tif property.InitializerOrNil.Data != nil {\n\t\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\t\tp.print(\"=\")\n\t\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\t\tp.printExprWithoutLeadingNewline(property.InitializerOrNil, js_ast.LComma, 0)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\tcase *js_ast.EImportIdentifier:\n\t\t\t\t\t// Make sure we're not using a property access instead of an identifier\n\t\t\t\t\tref := ast.FollowSymbols(p.symbols, e.Ref)\n\t\t\t\t\tif symbol := p.symbols.Get(ref); symbol.NamespaceAlias == nil && name == p.renamer.NameForSymbol(ref) &&\n\t\t\t\t\t\tp.options.ConstValues[ref].Kind == js_ast.ConstValueNone {\n\t\t\t\t\t\tif property.InitializerOrNil.Data != nil {\n\t\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\t\tp.print(\"=\")\n\t\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\t\tp.printExprWithoutLeadingNewline(property.InitializerOrNil, js_ast.LComma, 0)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tp.addSourceMapping(property.Key.Loc)\n\t\t\tp.printQuotedUTF8(name, 0)\n\t\t}\n\n\tcase *js_ast.EString:\n\t\tif !property.Flags.Has(js_ast.PropertyPreferQuotedKey) && p.canPrintIdentifierUTF16(key.Value) {\n\t\t\tp.printSpaceBeforeIdentifier()\n\n\t\t\t// Use a shorthand property if the names are the same\n\t\t\tif !p.options.UnsupportedFeatures.Has(compat.ObjectExtensions) && property.ValueOrNil.Data != nil && !p.willPrintExprCommentsAtLoc(property.ValueOrNil.Loc) {\n\t\t\t\tswitch e := property.ValueOrNil.Data.(type) {\n\t\t\t\tcase *js_ast.EIdentifier:\n\t\t\t\t\tif canUseShorthandProperty(key.Value, p.renamer.NameForSymbol(e.Ref), property.Flags) {\n\t\t\t\t\t\tif p.options.AddSourceMappings {\n\t\t\t\t\t\t\tp.addSourceMappingForName(property.Key.Loc, helpers.UTF16ToString(key.Value), e.Ref)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.printIdentifierUTF16(key.Value)\n\t\t\t\t\t\tif property.InitializerOrNil.Data != nil {\n\t\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\t\tp.print(\"=\")\n\t\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\t\tp.printExprWithoutLeadingNewline(property.InitializerOrNil, js_ast.LComma, 0)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\tcase *js_ast.EImportIdentifier:\n\t\t\t\t\t// Make sure we're not using a property access instead of an identifier\n\t\t\t\t\tref := ast.FollowSymbols(p.symbols, e.Ref)\n\t\t\t\t\tif symbol := p.symbols.Get(ref); symbol.NamespaceAlias == nil && canUseShorthandProperty(key.Value, p.renamer.NameForSymbol(ref), property.Flags) &&\n\t\t\t\t\t\tp.options.ConstValues[ref].Kind == js_ast.ConstValueNone {\n\t\t\t\t\t\tif p.options.AddSourceMappings {\n\t\t\t\t\t\t\tp.addSourceMappingForName(property.Key.Loc, helpers.UTF16ToString(key.Value), ref)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.printIdentifierUTF16(key.Value)\n\t\t\t\t\t\tif property.InitializerOrNil.Data != nil {\n\t\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\t\tp.print(\"=\")\n\t\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\t\tp.printExprWithoutLeadingNewline(property.InitializerOrNil, js_ast.LComma, 0)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// The JavaScript specification special-cases the property identifier\n\t\t\t// \"__proto__\" with a colon after it to set the prototype of the object.\n\t\t\t// If we keep the identifier but add a colon then we'll cause a behavior\n\t\t\t// change because the prototype will now be set. Avoid using an identifier\n\t\t\t// by using a computed property with a string instead. For more info see:\n\t\t\t// https://tc39.es/ecma262/#sec-runtime-semantics-propertydefinitionevaluation\n\t\t\tif property.Flags.Has(js_ast.PropertyWasShorthand) && !p.options.UnsupportedFeatures.Has(compat.ObjectExtensions) &&\n\t\t\t\thelpers.UTF16EqualsString(key.Value, \"__proto__\") {\n\t\t\t\tp.print(\"[\")\n\t\t\t\tp.addSourceMapping(property.Key.Loc)\n\t\t\t\tp.printQuotedUTF16(key.Value, 0)\n\t\t\t\tp.print(\"]\")\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tp.addSourceMapping(property.Key.Loc)\n\t\t\tp.printIdentifierUTF16(key.Value)\n\t\t} else {\n\t\t\tp.addSourceMapping(property.Key.Loc)\n\t\t\tp.printQuotedUTF16(key.Value, 0)\n\t\t}\n\n\tdefault:\n\t\tp.printExpr(property.Key, js_ast.LLowest, keyFlags)\n\t}\n\n\tif fn, ok := property.ValueOrNil.Data.(*js_ast.EFunction); property.Kind.IsMethodDefinition() && ok {\n\t\tp.printFn(fn.Fn)\n\t\treturn\n\t}\n\n\tif property.ValueOrNil.Data != nil {\n\t\tp.print(\":\")\n\t\tp.printSpace()\n\t\tp.printExprWithoutLeadingNewline(property.ValueOrNil, js_ast.LComma, 0)\n\t}\n\n\tif property.InitializerOrNil.Data != nil {\n\t\tp.printSpace()\n\t\tp.print(\"=\")\n\t\tp.printSpace()\n\t\tp.printExprWithoutLeadingNewline(property.InitializerOrNil, js_ast.LComma, 0)\n\t}\n}\n\nfunc canUseShorthandProperty(key []uint16, name string, flags js_ast.PropertyFlags) bool {\n\t// The JavaScript specification special-cases the property identifier\n\t// \"__proto__\" with a colon after it to set the prototype of the object. If\n\t// we remove the colon then we'll cause a behavior change because the\n\t// prototype will no longer be set, but we also don't want to add a colon\n\t// if it was omitted. Always use a shorthand property if the property is not\n\t// \"__proto__\", otherwise try to preserve the original shorthand status. See:\n\t// https://tc39.es/ecma262/#sec-runtime-semantics-propertydefinitionevaluation\n\tif !helpers.UTF16EqualsString(key, name) {\n\t\treturn false\n\t}\n\treturn helpers.UTF16EqualsString(key, name) && (name != \"__proto__\" || flags.Has(js_ast.PropertyWasShorthand))\n}\n\nfunc (p *printer) printQuotedUTF16(data []uint16, flags printQuotedFlags) {\n\tif p.options.UnsupportedFeatures.Has(compat.TemplateLiteral) {\n\t\tflags &= ^printQuotedAllowBacktick\n\t}\n\n\tsingleCost := 0\n\tdoubleCost := 0\n\tbacktickCost := 0\n\n\tfor i, c := range data {\n\t\tswitch c {\n\t\tcase '\\n':\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\t// The backslash for the newline costs an extra character for old-style\n\t\t\t\t// string literals when compared to a template literal\n\t\t\t\tbacktickCost--\n\t\t\t}\n\t\tcase '\\'':\n\t\t\tsingleCost++\n\t\tcase '\"':\n\t\t\tdoubleCost++\n\t\tcase '`':\n\t\t\tbacktickCost++\n\t\tcase '$':\n\t\t\t// \"${\" sequences need to be escaped in template literals\n\t\t\tif i+1 < len(data) && data[i+1] == '{' {\n\t\t\t\tbacktickCost++\n\t\t\t}\n\t\t}\n\t}\n\n\tc := \"\\\"\"\n\tif doubleCost > singleCost {\n\t\tc = \"'\"\n\t\tif singleCost > backtickCost && (flags&printQuotedAllowBacktick) != 0 {\n\t\t\tc = \"`\"\n\t\t}\n\t} else if doubleCost > backtickCost && (flags&printQuotedAllowBacktick) != 0 {\n\t\tc = \"`\"\n\t}\n\n\tp.print(c)\n\tp.printUnquotedUTF16(data, rune(c[0]), flags)\n\tp.print(c)\n}\n\nfunc (p *printer) printRequireOrImportExpr(importRecordIndex uint32, level js_ast.L, flags printExprFlags, closeParenLoc logger.Loc, phase ast.ImportPhase) {\n\trecord := &p.importRecords[importRecordIndex]\n\n\tif level >= js_ast.LNew || (flags&forbidCall) != 0 {\n\t\tp.print(\"(\")\n\t\tdefer p.print(\")\")\n\t\tlevel = js_ast.LLowest\n\t}\n\n\tif !record.SourceIndex.IsValid() {\n\t\t// External \"require()\"\n\t\tif record.Kind != ast.ImportDynamic {\n\t\t\t// Wrap this with a call to \"__toESM()\" if this is a CommonJS file\n\t\t\twrapWithToESM := record.Flags.Has(ast.WrapWithToESM)\n\t\t\tif wrapWithToESM {\n\t\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\t\tp.printIdentifier(p.renamer.NameForSymbol(p.options.ToESMRef))\n\t\t\t\tp.print(\"(\")\n\t\t\t}\n\n\t\t\t// Potentially substitute our own \"__require\" stub for \"require\"\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tif record.Flags.Has(ast.CallRuntimeRequire) {\n\t\t\t\tp.printIdentifier(p.renamer.NameForSymbol(p.options.RuntimeRequireRef))\n\t\t\t} else {\n\t\t\t\tp.print(\"require\")\n\t\t\t}\n\n\t\t\tisMultiLine := p.willPrintExprCommentsAtLoc(record.Range.Loc) || p.willPrintExprCommentsAtLoc(closeParenLoc)\n\t\t\tp.print(\"(\")\n\t\t\tif isMultiLine {\n\t\t\t\tp.printNewline()\n\t\t\t\tp.options.Indent++\n\t\t\t\tp.printIndent()\n\t\t\t}\n\t\t\tp.printExprCommentsAtLoc(record.Range.Loc)\n\t\t\tp.printPath(importRecordIndex, ast.ImportRequire)\n\t\t\tif isMultiLine {\n\t\t\t\tp.printNewline()\n\t\t\t\tp.printExprCommentsAfterCloseTokenAtLoc(closeParenLoc)\n\t\t\t\tp.options.Indent--\n\t\t\t\tp.printIndent()\n\t\t\t}\n\t\t\tif closeParenLoc.Start > record.Range.Loc.Start {\n\t\t\t\tp.addSourceMapping(closeParenLoc)\n\t\t\t}\n\t\t\tp.print(\")\")\n\n\t\t\t// Finish the call to \"__toESM()\"\n\t\t\tif wrapWithToESM {\n\t\t\t\tif p.moduleType.IsESM() {\n\t\t\t\t\tp.print(\",\")\n\t\t\t\t\tp.printSpace()\n\t\t\t\t\tp.print(\"1\")\n\t\t\t\t}\n\t\t\t\tp.print(\")\")\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\t// External \"import()\"\n\t\tkind := ast.ImportDynamic\n\t\tif !p.options.UnsupportedFeatures.Has(compat.DynamicImport) {\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tswitch phase {\n\t\t\tcase ast.DeferPhase:\n\t\t\t\tp.print(\"import.defer(\")\n\t\t\tcase ast.SourcePhase:\n\t\t\t\tp.print(\"import.source(\")\n\t\t\tdefault:\n\t\t\t\tp.print(\"import(\")\n\t\t\t}\n\t\t} else {\n\t\t\tkind = ast.ImportRequire\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tp.print(\"Promise.resolve()\")\n\t\t\tp.printDotThenPrefix()\n\t\t\tdefer p.printDotThenSuffix()\n\n\t\t\t// Wrap this with a call to \"__toESM()\" if this is a CommonJS file\n\t\t\tif record.Flags.Has(ast.WrapWithToESM) {\n\t\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\t\tp.printIdentifier(p.renamer.NameForSymbol(p.options.ToESMRef))\n\t\t\t\tp.print(\"(\")\n\t\t\t\tdefer func() {\n\t\t\t\t\tif p.moduleType.IsESM() {\n\t\t\t\t\t\tp.print(\",\")\n\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t\tp.print(\"1\")\n\t\t\t\t\t}\n\t\t\t\t\tp.print(\")\")\n\t\t\t\t}()\n\t\t\t}\n\n\t\t\t// Potentially substitute our own \"__require\" stub for \"require\"\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tif record.Flags.Has(ast.CallRuntimeRequire) {\n\t\t\t\tp.printIdentifier(p.renamer.NameForSymbol(p.options.RuntimeRequireRef))\n\t\t\t} else {\n\t\t\t\tp.print(\"require\")\n\t\t\t}\n\n\t\t\tp.print(\"(\")\n\t\t}\n\t\tisMultiLine := p.willPrintExprCommentsAtLoc(record.Range.Loc) ||\n\t\t\tp.willPrintExprCommentsAtLoc(closeParenLoc) ||\n\t\t\t(record.AssertOrWith != nil &&\n\t\t\t\t!p.options.UnsupportedFeatures.Has(compat.DynamicImport) &&\n\t\t\t\t(!p.options.UnsupportedFeatures.Has(compat.ImportAssertions) ||\n\t\t\t\t\t!p.options.UnsupportedFeatures.Has(compat.ImportAttributes)) &&\n\t\t\t\tp.willPrintExprCommentsAtLoc(record.AssertOrWith.OuterOpenBraceLoc))\n\t\tif isMultiLine {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent++\n\t\t\tp.printIndent()\n\t\t}\n\t\tp.printExprCommentsAtLoc(record.Range.Loc)\n\t\tp.printPath(importRecordIndex, kind)\n\t\tif !p.options.UnsupportedFeatures.Has(compat.DynamicImport) {\n\t\t\tp.printImportCallAssertOrWith(record.AssertOrWith, isMultiLine)\n\t\t}\n\t\tif isMultiLine {\n\t\t\tp.printNewline()\n\t\t\tp.printExprCommentsAfterCloseTokenAtLoc(closeParenLoc)\n\t\t\tp.options.Indent--\n\t\t\tp.printIndent()\n\t\t}\n\t\tif closeParenLoc.Start > record.Range.Loc.Start {\n\t\t\tp.addSourceMapping(closeParenLoc)\n\t\t}\n\t\tp.print(\")\")\n\t\treturn\n\t}\n\n\tmeta := p.options.RequireOrImportMetaForSource(record.SourceIndex.GetIndex())\n\n\t// Don't need the namespace object if the result is unused anyway\n\tif (flags & exprResultIsUnused) != 0 {\n\t\tmeta.ExportsRef = ast.InvalidRef\n\t}\n\n\t// Internal \"import()\" of async ESM\n\tif record.Kind == ast.ImportDynamic && meta.IsWrapperAsync {\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.printIdentifier(p.renamer.NameForSymbol(meta.WrapperRef))\n\t\tp.print(\"()\")\n\t\tif meta.ExportsRef != ast.InvalidRef {\n\t\t\tp.printDotThenPrefix()\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tp.printIdentifier(p.renamer.NameForSymbol(meta.ExportsRef))\n\t\t\tp.printDotThenSuffix()\n\t\t}\n\t\treturn\n\t}\n\n\t// Internal \"require()\" or \"import()\"\n\tif record.Kind == ast.ImportDynamic {\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"Promise.resolve()\")\n\t\tlevel = p.printDotThenPrefix()\n\t\tdefer p.printDotThenSuffix()\n\t}\n\n\t// Make sure the comma operator is properly wrapped\n\tif meta.ExportsRef != ast.InvalidRef && level >= js_ast.LComma {\n\t\tp.print(\"(\")\n\t\tdefer p.print(\")\")\n\t}\n\n\t// Wrap this with a call to \"__toESM()\" if this is a CommonJS file\n\twrapWithToESM := record.Flags.Has(ast.WrapWithToESM)\n\tif wrapWithToESM {\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.printIdentifier(p.renamer.NameForSymbol(p.options.ToESMRef))\n\t\tp.print(\"(\")\n\t}\n\n\t// Call the wrapper\n\tp.printSpaceBeforeIdentifier()\n\tp.printIdentifier(p.renamer.NameForSymbol(meta.WrapperRef))\n\tp.print(\"()\")\n\n\t// Return the namespace object if this is an ESM file\n\tif meta.ExportsRef != ast.InvalidRef {\n\t\tp.print(\",\")\n\t\tp.printSpace()\n\n\t\t// Wrap this with a call to \"__toCommonJS()\" if this is an ESM file\n\t\twrapWithTpCJS := record.Flags.Has(ast.WrapWithToCJS)\n\t\tif wrapWithTpCJS {\n\t\t\tp.printIdentifier(p.renamer.NameForSymbol(p.options.ToCommonJSRef))\n\t\t\tp.print(\"(\")\n\t\t}\n\t\tp.printIdentifier(p.renamer.NameForSymbol(meta.ExportsRef))\n\t\tif wrapWithTpCJS {\n\t\t\tp.print(\")\")\n\t\t}\n\t}\n\n\t// Finish the call to \"__toESM()\"\n\tif wrapWithToESM {\n\t\tif p.moduleType.IsESM() {\n\t\t\tp.print(\",\")\n\t\t\tp.printSpace()\n\t\t\tp.print(\"1\")\n\t\t}\n\t\tp.print(\")\")\n\t}\n}\n\nfunc (p *printer) printDotThenPrefix() js_ast.L {\n\tif p.options.UnsupportedFeatures.Has(compat.Arrow) {\n\t\tp.print(\".then(function()\")\n\t\tp.printSpace()\n\t\tp.print(\"{\")\n\t\tp.printNewline()\n\t\tp.options.Indent++\n\t\tp.printIndent()\n\t\tp.print(\"return\")\n\t\tp.printSpace()\n\t\treturn js_ast.LLowest\n\t} else {\n\t\tp.print(\".then(()\")\n\t\tp.printSpace()\n\t\tp.print(\"=>\")\n\t\tp.printSpace()\n\t\treturn js_ast.LComma\n\t}\n}\n\nfunc (p *printer) printDotThenSuffix() {\n\tif p.options.UnsupportedFeatures.Has(compat.Arrow) {\n\t\tif !p.options.MinifyWhitespace {\n\t\t\tp.print(\";\")\n\t\t}\n\t\tp.printNewline()\n\t\tp.options.Indent--\n\t\tp.printIndent()\n\t\tp.print(\"})\")\n\t} else {\n\t\tp.print(\")\")\n\t}\n}\n\nfunc (p *printer) printUndefined(loc logger.Loc, level js_ast.L) {\n\tif level >= js_ast.LPrefix {\n\t\tp.addSourceMapping(loc)\n\t\tp.print(\"(void 0)\")\n\t} else {\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(loc)\n\t\tp.print(\"void 0\")\n\t}\n}\n\n// Call this before printing an expression to see if it turned out to be empty.\n// We use this to do inlining of empty functions at print time. It can't happen\n// during parse time because a) parse time only has two passes and we only know\n// if a function can be inlined at the end of the second pass (due to is-mutated\n// analysis) and b) we want to enable cross-module inlining of empty functions\n// which has to happen after linking.\n//\n// This function returns \"nil\" to indicate that the expression should be removed\n// completely.\n//\n// This function doesn't need to search everywhere inside the entire expression\n// for calls to inline. Calls are automatically inlined when printed. However,\n// the printer replaces the call with \"undefined\" since the result may still\n// be needed by the caller. If the caller knows that it doesn't need the result,\n// it should call this function first instead so we don't print \"undefined\".\n//\n// This is a separate function instead of trying to work this logic into the\n// printer because it's too late to eliminate the expression entirely when we're\n// in the printer. We may have already printed the leading indent, for example.\nfunc (p *printer) simplifyUnusedExpr(expr js_ast.Expr) js_ast.Expr {\n\tswitch e := expr.Data.(type) {\n\tcase *js_ast.EBinary:\n\t\t// Calls to be inlined may be hidden inside a comma operator chain\n\t\tif e.Op == js_ast.BinOpComma {\n\t\t\tleft := p.simplifyUnusedExpr(e.Left)\n\t\t\tright := p.simplifyUnusedExpr(e.Right)\n\t\t\tif left.Data != e.Left.Data || right.Data != e.Right.Data {\n\t\t\t\treturn js_ast.JoinWithComma(left, right)\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.ECall:\n\t\tvar symbolFlags ast.SymbolFlags\n\t\tswitch target := e.Target.Data.(type) {\n\t\tcase *js_ast.EIdentifier:\n\t\t\tsymbolFlags = p.symbols.Get(target.Ref).Flags\n\t\tcase *js_ast.EImportIdentifier:\n\t\t\tref := ast.FollowSymbols(p.symbols, target.Ref)\n\t\t\tsymbolFlags = p.symbols.Get(ref).Flags\n\t\t}\n\n\t\t// Replace non-mutated empty functions with their arguments at print time\n\t\tif (symbolFlags & (ast.IsEmptyFunction | ast.CouldPotentiallyBeMutated)) == ast.IsEmptyFunction {\n\t\t\tvar replacement js_ast.Expr\n\t\t\tfor _, arg := range e.Args {\n\t\t\t\tif _, ok := arg.Data.(*js_ast.ESpread); ok {\n\t\t\t\t\targ.Data = &js_ast.EArray{Items: []js_ast.Expr{arg}, IsSingleLine: true}\n\t\t\t\t}\n\t\t\t\treplacement = js_ast.JoinWithComma(replacement, p.astHelpers.SimplifyUnusedExpr(p.simplifyUnusedExpr(arg), p.options.UnsupportedFeatures))\n\t\t\t}\n\t\t\treturn replacement // Don't add \"undefined\" here because the result isn't used\n\t\t}\n\n\t\t// Inline non-mutated identity functions at print time\n\t\tif (symbolFlags&(ast.IsIdentityFunction|ast.CouldPotentiallyBeMutated)) == ast.IsIdentityFunction && len(e.Args) == 1 {\n\t\t\targ := e.Args[0]\n\t\t\tif _, ok := arg.Data.(*js_ast.ESpread); !ok {\n\t\t\t\treturn p.astHelpers.SimplifyUnusedExpr(p.simplifyUnusedExpr(arg), p.options.UnsupportedFeatures)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn expr\n}\n\n// This assumes the original expression was some form of indirect value, such\n// as a value returned from a function call or the result of a comma operator.\n// In this case, there is no special behavior with the \"delete\" operator or\n// with function calls. If we substitute this indirect value for another value\n// due to inlining, we have to make sure we don't accidentally introduce special\n// behavior.\nfunc (p *printer) guardAgainstBehaviorChangeDueToSubstitution(expr js_ast.Expr, flags printExprFlags) js_ast.Expr {\n\twrap := false\n\n\tif (flags & isDeleteTarget) != 0 {\n\t\t// \"delete id(x)\" must not become \"delete x\"\n\t\t// \"delete (empty(), x)\" must not become \"delete x\"\n\t\tif binary, ok := expr.Data.(*js_ast.EBinary); !ok || binary.Op != js_ast.BinOpComma {\n\t\t\twrap = true\n\t\t}\n\t} else if (flags & isCallTargetOrTemplateTag) != 0 {\n\t\t// \"id(x.y)()\" must not become \"x.y()\"\n\t\t// \"id(x.y)``\" must not become \"x.y``\"\n\t\t// \"(empty(), x.y)()\" must not become \"x.y()\"\n\t\t// \"(empty(), eval)()\" must not become \"eval()\"\n\t\tswitch expr.Data.(type) {\n\t\tcase *js_ast.EDot, *js_ast.EIndex:\n\t\t\twrap = true\n\t\tcase *js_ast.EIdentifier:\n\t\t\tif p.isUnboundEvalIdentifier(expr) {\n\t\t\t\twrap = true\n\t\t\t}\n\t\t}\n\t}\n\n\tif wrap {\n\t\texpr.Data = &js_ast.EBinary{\n\t\t\tOp:    js_ast.BinOpComma,\n\t\t\tLeft:  js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENumber{Value: 0}},\n\t\t\tRight: expr,\n\t\t}\n\t}\n\n\treturn expr\n}\n\n// Constant folding is already implemented once in the parser. A smaller form\n// of constant folding (just for numbers) is implemented here to clean up cross-\n// module numeric constants and bitwise operations. This is not an general-\n// purpose/optimal approach and never will be. For example, we can't affect\n// tree shaking at this stage because it has already happened.\nfunc (p *printer) lateConstantFoldUnaryOrBinaryOrIfExpr(expr js_ast.Expr) js_ast.Expr {\n\tswitch e := expr.Data.(type) {\n\tcase *js_ast.EImportIdentifier:\n\t\tref := ast.FollowSymbols(p.symbols, e.Ref)\n\t\tif value := p.options.ConstValues[ref]; value.Kind != js_ast.ConstValueNone {\n\t\t\treturn js_ast.ConstValueToExpr(expr.Loc, value)\n\t\t}\n\n\tcase *js_ast.EDot:\n\t\tif value, ok := p.tryToGetImportedEnumValue(e.Target, e.Name); ok {\n\t\t\tvar inlinedValue js_ast.Expr\n\t\t\tif value.String != nil {\n\t\t\t\tinlinedValue = js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: value.String}}\n\t\t\t} else {\n\t\t\t\tinlinedValue = js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENumber{Value: value.Number}}\n\t\t\t}\n\n\t\t\tif strings.Contains(e.Name, \"*/\") {\n\t\t\t\t// Don't wrap with a comment\n\t\t\t\treturn inlinedValue\n\t\t\t}\n\n\t\t\t// Wrap with a comment\n\t\t\treturn js_ast.Expr{Loc: inlinedValue.Loc, Data: &js_ast.EInlinedEnum{\n\t\t\t\tValue:   inlinedValue,\n\t\t\t\tComment: e.Name,\n\t\t\t}}\n\t\t}\n\n\tcase *js_ast.EUnary:\n\t\tvalue := p.lateConstantFoldUnaryOrBinaryOrIfExpr(e.Value)\n\n\t\t// Only fold again if something chained\n\t\tif value.Data != e.Value.Data {\n\t\t\t// Only fold certain operations (just like the parser)\n\t\t\tif v, ok := js_ast.ToNumberWithoutSideEffects(value.Data); ok {\n\t\t\t\tswitch e.Op {\n\t\t\t\tcase js_ast.UnOpPos:\n\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENumber{Value: v}}\n\n\t\t\t\tcase js_ast.UnOpNeg:\n\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENumber{Value: -v}}\n\n\t\t\t\tcase js_ast.UnOpCpl:\n\t\t\t\t\treturn js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENumber{Value: float64(^js_ast.ToInt32(v))}}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Don't mutate the original AST\n\t\t\texpr.Data = &js_ast.EUnary{Op: e.Op, Value: value}\n\t\t}\n\n\tcase *js_ast.EBinary:\n\t\tleft := p.lateConstantFoldUnaryOrBinaryOrIfExpr(e.Left)\n\t\tright := p.lateConstantFoldUnaryOrBinaryOrIfExpr(e.Right)\n\n\t\t// Only fold again if something changed\n\t\tif left.Data != e.Left.Data || right.Data != e.Right.Data {\n\t\t\tbinary := &js_ast.EBinary{Op: e.Op, Left: left, Right: right}\n\n\t\t\t// Only fold certain operations (just like the parser)\n\t\t\tif js_ast.ShouldFoldBinaryOperatorWhenMinifying(binary) {\n\t\t\t\tif result := js_ast.FoldBinaryOperator(expr.Loc, binary); result.Data != nil {\n\t\t\t\t\treturn result\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Don't mutate the original AST\n\t\t\texpr.Data = binary\n\t\t}\n\n\tcase *js_ast.EIf:\n\t\ttest := p.lateConstantFoldUnaryOrBinaryOrIfExpr(e.Test)\n\n\t\t// Only fold again if something changed\n\t\tif test.Data != e.Test.Data {\n\t\t\tif boolean, sideEffects, ok := js_ast.ToBooleanWithSideEffects(test.Data); ok && sideEffects == js_ast.NoSideEffects {\n\t\t\t\tif boolean {\n\t\t\t\t\treturn p.lateConstantFoldUnaryOrBinaryOrIfExpr(e.Yes)\n\t\t\t\t} else {\n\t\t\t\t\treturn p.lateConstantFoldUnaryOrBinaryOrIfExpr(e.No)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Don't mutate the original AST\n\t\t\texpr.Data = &js_ast.EIf{Test: test, Yes: e.Yes, No: e.No}\n\t\t}\n\t}\n\n\treturn expr\n}\n\nfunc (p *printer) isUnboundIdentifier(expr js_ast.Expr) bool {\n\tid, ok := expr.Data.(*js_ast.EIdentifier)\n\treturn ok && p.symbols.Get(ast.FollowSymbols(p.symbols, id.Ref)).Kind == ast.SymbolUnbound\n}\n\nfunc (p *printer) isIdentifierOrNumericConstantOrPropertyAccess(expr js_ast.Expr) bool {\n\tswitch e := expr.Data.(type) {\n\tcase *js_ast.EIdentifier, *js_ast.EDot, *js_ast.EIndex:\n\t\treturn true\n\tcase *js_ast.ENumber:\n\t\treturn math.IsInf(e.Value, 1) || math.IsNaN(e.Value)\n\t}\n\treturn false\n}\n\ntype exprStartFlags uint8\n\nconst (\n\tstmtStartFlag exprStartFlags = 1 << iota\n\texportDefaultStartFlag\n\tarrowExprStartFlag\n\tforOfInitStartFlag\n)\n\nfunc (p *printer) saveExprStartFlags() (flags exprStartFlags) {\n\tn := len(p.js)\n\tif p.stmtStart == n {\n\t\tflags |= stmtStartFlag\n\t}\n\tif p.exportDefaultStart == n {\n\t\tflags |= exportDefaultStartFlag\n\t}\n\tif p.arrowExprStart == n {\n\t\tflags |= arrowExprStartFlag\n\t}\n\tif p.forOfInitStart == n {\n\t\tflags |= forOfInitStartFlag\n\t}\n\treturn\n}\n\nfunc (p *printer) restoreExprStartFlags(flags exprStartFlags) {\n\tif flags != 0 {\n\t\tn := len(p.js)\n\t\tif (flags & stmtStartFlag) != 0 {\n\t\t\tp.stmtStart = n\n\t\t}\n\t\tif (flags & exportDefaultStartFlag) != 0 {\n\t\t\tp.exportDefaultStart = n\n\t\t}\n\t\tif (flags & arrowExprStartFlag) != 0 {\n\t\t\tp.arrowExprStart = n\n\t\t}\n\t\tif (flags & forOfInitStartFlag) != 0 {\n\t\t\tp.forOfInitStart = n\n\t\t}\n\t}\n}\n\n// Print any stored comments that are associated with this location\nfunc (p *printer) printExprCommentsAtLoc(loc logger.Loc) {\n\tif p.options.MinifyWhitespace {\n\t\treturn\n\t}\n\tif comments := p.exprComments[loc]; comments != nil && !p.printedExprComments[loc] {\n\t\tflags := p.saveExprStartFlags()\n\n\t\t// We must never generate a newline before certain expressions. For example,\n\t\t// generating a newline before the expression in a \"return\" statement will\n\t\t// cause a semicolon to be inserted, which would change the code's behavior.\n\t\tif p.noLeadingNewlineHere == len(p.js) {\n\t\t\tfor _, comment := range comments {\n\t\t\t\tif strings.HasPrefix(comment, \"//\") {\n\t\t\t\t\tp.print(\"/*\")\n\t\t\t\t\tp.print(comment[2:])\n\t\t\t\t\tif strings.HasPrefix(comment, \"// \") {\n\t\t\t\t\t\tp.print(\" \")\n\t\t\t\t\t}\n\t\t\t\t\tp.print(\"*/\")\n\t\t\t\t} else {\n\t\t\t\t\tp.print(strings.Join(strings.Split(comment, \"\\n\"), \"\"))\n\t\t\t\t}\n\t\t\t\tp.printSpace()\n\t\t\t}\n\t\t} else {\n\t\t\tfor _, comment := range comments {\n\t\t\t\tp.printIndentedComment(comment)\n\t\t\t\tp.printIndent()\n\t\t\t}\n\t\t}\n\n\t\t// Mark these comments as printed so we don't print them again\n\t\tp.printedExprComments[loc] = true\n\n\t\tp.restoreExprStartFlags(flags)\n\t}\n}\n\nfunc (p *printer) printExprCommentsAfterCloseTokenAtLoc(loc logger.Loc) {\n\tif comments := p.exprComments[loc]; comments != nil && !p.printedExprComments[loc] {\n\t\tflags := p.saveExprStartFlags()\n\n\t\tfor _, comment := range comments {\n\t\t\tp.printIndent()\n\t\t\tp.printIndentedComment(comment)\n\t\t}\n\n\t\t// Mark these comments as printed so we don't print them again\n\t\tp.printedExprComments[loc] = true\n\n\t\tp.restoreExprStartFlags(flags)\n\t}\n}\n\nfunc (p *printer) printExprWithoutLeadingNewline(expr js_ast.Expr, level js_ast.L, flags printExprFlags) {\n\tif !p.options.MinifyWhitespace && p.willPrintExprCommentsAtLoc(expr.Loc) {\n\t\tp.print(\"(\")\n\t\tp.printNewline()\n\t\tp.options.Indent++\n\t\tp.printIndent()\n\t\tp.printExpr(expr, level, flags)\n\t\tp.printNewline()\n\t\tp.options.Indent--\n\t\tp.printIndent()\n\t\tp.print(\")\")\n\t\treturn\n\t}\n\n\tp.noLeadingNewlineHere = len(p.js)\n\tp.printExpr(expr, level, flags)\n}\n\ntype printExprFlags uint16\n\nconst (\n\tforbidCall printExprFlags = 1 << iota\n\tforbidIn\n\thasNonOptionalChainParent\n\texprResultIsUnused\n\tdidAlreadySimplifyUnusedExprs\n\tisFollowedByOf\n\tisInsideForAwait\n\tisDeleteTarget\n\tisCallTargetOrTemplateTag\n\tisPropertyAccessTarget\n\tparentWasUnaryOrBinaryOrIfTest\n)\n\nfunc (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFlags) {\n\t// If syntax compression is enabled, do a pre-pass over unary and binary\n\t// operators to inline bitwise operations of cross-module inlined constants.\n\t// This makes the output a little tighter if people construct bit masks in\n\t// other files. This is not a general-purpose constant folding pass. In\n\t// particular, it has no effect on tree shaking because that pass has already\n\t// been run.\n\t//\n\t// This sets a flag to avoid doing this when the parent is a unary or binary\n\t// operator so that we don't trigger O(n^2) behavior when traversing over a\n\t// large expression tree.\n\tif p.options.MinifySyntax && (flags&parentWasUnaryOrBinaryOrIfTest) == 0 {\n\t\tswitch expr.Data.(type) {\n\t\tcase *js_ast.EUnary, *js_ast.EBinary, *js_ast.EIf:\n\t\t\texpr = p.lateConstantFoldUnaryOrBinaryOrIfExpr(expr)\n\t\t}\n\t}\n\n\tp.printExprCommentsAtLoc(expr.Loc)\n\n\tswitch e := expr.Data.(type) {\n\tcase *js_ast.EMissing:\n\t\tp.addSourceMapping(expr.Loc)\n\n\tcase *js_ast.EAnnotation:\n\t\tp.printExpr(e.Value, level, flags)\n\n\tcase *js_ast.EUndefined:\n\t\tp.printUndefined(expr.Loc, level)\n\n\tcase *js_ast.ESuper:\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.print(\"super\")\n\n\tcase *js_ast.ENull:\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.print(\"null\")\n\n\tcase *js_ast.EThis:\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.print(\"this\")\n\n\tcase *js_ast.ESpread:\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.print(\"...\")\n\t\tp.printExpr(e.Value, js_ast.LComma, 0)\n\n\tcase *js_ast.ENewTarget:\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.print(\"new.target\")\n\n\tcase *js_ast.EImportMeta:\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.print(\"import.meta\")\n\n\tcase *js_ast.ENameOfSymbol:\n\t\tname := p.mangledPropName(e.Ref)\n\t\tp.addSourceMappingForName(expr.Loc, name, e.Ref)\n\n\t\tif !p.options.MinifyWhitespace && e.HasPropertyKeyComment {\n\t\t\tp.print(\"/* @__KEY__ */ \")\n\t\t}\n\n\t\tp.printQuotedUTF8(name, printQuotedAllowBacktick)\n\n\tcase *js_ast.EJSXElement:\n\t\t// Start the opening tag\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.print(\"<\")\n\t\tp.printJSXTag(e.TagOrNil)\n\t\tif !e.IsTagSingleLine {\n\t\t\tp.options.Indent++\n\t\t}\n\n\t\t// Print the attributes\n\t\tfor _, property := range e.Properties {\n\t\t\tif e.IsTagSingleLine {\n\t\t\t\tp.printSpace()\n\t\t\t} else {\n\t\t\t\tp.printNewline()\n\t\t\t\tp.printIndent()\n\t\t\t}\n\n\t\t\tif property.Kind == js_ast.PropertySpread {\n\t\t\t\tif p.willPrintExprCommentsAtLoc(property.Loc) {\n\t\t\t\t\tp.print(\"{\")\n\t\t\t\t\tp.printNewline()\n\t\t\t\t\tp.options.Indent++\n\t\t\t\t\tp.printIndent()\n\t\t\t\t\tp.printExprCommentsAtLoc(property.Loc)\n\t\t\t\t\tp.print(\"...\")\n\t\t\t\t\tp.printExpr(property.ValueOrNil, js_ast.LComma, 0)\n\t\t\t\t\tp.printNewline()\n\t\t\t\t\tp.options.Indent--\n\t\t\t\t\tp.printIndent()\n\t\t\t\t\tp.print(\"}\")\n\t\t\t\t} else {\n\t\t\t\t\tp.print(\"{...\")\n\t\t\t\t\tp.printExpr(property.ValueOrNil, js_ast.LComma, 0)\n\t\t\t\t\tp.print(\"}\")\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tif mangled, ok := property.Key.Data.(*js_ast.ENameOfSymbol); ok {\n\t\t\t\tname := p.mangledPropName(mangled.Ref)\n\t\t\t\tp.addSourceMappingForName(property.Key.Loc, name, mangled.Ref)\n\t\t\t\tp.printIdentifier(name)\n\t\t\t} else if str, ok := property.Key.Data.(*js_ast.EString); ok {\n\t\t\t\tp.addSourceMapping(property.Key.Loc)\n\t\t\t\tp.print(helpers.UTF16ToString(str.Value))\n\t\t\t} else {\n\t\t\t\tp.print(\"{...{\")\n\t\t\t\tp.printSpace()\n\t\t\t\tp.print(\"[\")\n\t\t\t\tp.printExpr(property.Key, js_ast.LComma, 0)\n\t\t\t\tp.print(\"]:\")\n\t\t\t\tp.printSpace()\n\t\t\t\tp.printExpr(property.ValueOrNil, js_ast.LComma, 0)\n\t\t\t\tp.printSpace()\n\t\t\t\tp.print(\"}}\")\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tisMultiLine := p.willPrintExprCommentsAtLoc(property.ValueOrNil.Loc)\n\n\t\t\tif property.Flags.Has(js_ast.PropertyWasShorthand) {\n\t\t\t\t// Implicit \"true\" value\n\t\t\t\tif boolean, ok := property.ValueOrNil.Data.(*js_ast.EBoolean); ok && boolean.Value {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// JSX element as JSX attribute value\n\t\t\t\tif _, ok := property.ValueOrNil.Data.(*js_ast.EJSXElement); ok {\n\t\t\t\t\tp.print(\"=\")\n\t\t\t\t\tp.printExpr(property.ValueOrNil, js_ast.LLowest, 0)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Special-case raw text\n\t\t\tif text, ok := property.ValueOrNil.Data.(*js_ast.EJSXText); ok {\n\t\t\t\tp.print(\"=\")\n\t\t\t\tp.addSourceMapping(property.ValueOrNil.Loc)\n\t\t\t\tp.print(text.Raw)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Generic JS value\n\t\t\tp.print(\"={\")\n\t\t\tif isMultiLine {\n\t\t\t\tp.printNewline()\n\t\t\t\tp.options.Indent++\n\t\t\t\tp.printIndent()\n\t\t\t}\n\t\t\tp.printExpr(property.ValueOrNil, js_ast.LComma, 0)\n\t\t\tif isMultiLine {\n\t\t\t\tp.printNewline()\n\t\t\t\tp.options.Indent--\n\t\t\t\tp.printIndent()\n\t\t\t}\n\t\t\tp.print(\"}\")\n\t\t}\n\n\t\t// End the opening tag\n\t\tif !e.IsTagSingleLine {\n\t\t\tp.options.Indent--\n\t\t\tif len(e.Properties) > 0 {\n\t\t\t\tp.printNewline()\n\t\t\t\tp.printIndent()\n\t\t\t}\n\t\t}\n\t\tif e.TagOrNil.Data != nil && len(e.NullableChildren) == 0 {\n\t\t\tif e.IsTagSingleLine || len(e.Properties) == 0 {\n\t\t\t\tp.printSpace()\n\t\t\t}\n\t\t\tp.addSourceMapping(e.CloseLoc)\n\t\t\tp.print(\"/>\")\n\t\t\tbreak\n\t\t}\n\t\tp.print(\">\")\n\n\t\t// Print the children\n\t\tfor _, childOrNil := range e.NullableChildren {\n\t\t\tif _, ok := childOrNil.Data.(*js_ast.EJSXElement); ok {\n\t\t\t\tp.printExpr(childOrNil, js_ast.LLowest, 0)\n\t\t\t} else if text, ok := childOrNil.Data.(*js_ast.EJSXText); ok {\n\t\t\t\tp.addSourceMapping(childOrNil.Loc)\n\t\t\t\tp.print(text.Raw)\n\t\t\t} else if childOrNil.Data != nil {\n\t\t\t\tisMultiLine := p.willPrintExprCommentsAtLoc(childOrNil.Loc)\n\t\t\t\tp.print(\"{\")\n\t\t\t\tif isMultiLine {\n\t\t\t\t\tp.printNewline()\n\t\t\t\t\tp.options.Indent++\n\t\t\t\t\tp.printIndent()\n\t\t\t\t}\n\t\t\t\tp.printExpr(childOrNil, js_ast.LComma, 0)\n\t\t\t\tif isMultiLine {\n\t\t\t\t\tp.printNewline()\n\t\t\t\t\tp.options.Indent--\n\t\t\t\t\tp.printIndent()\n\t\t\t\t}\n\t\t\t\tp.print(\"}\")\n\t\t\t} else {\n\t\t\t\tp.print(\"{\")\n\t\t\t\tif p.willPrintExprCommentsAtLoc(childOrNil.Loc) {\n\t\t\t\t\t// Note: Some people use these comments for AST transformations\n\t\t\t\t\tp.printNewline()\n\t\t\t\t\tp.options.Indent++\n\t\t\t\t\tp.printExprCommentsAfterCloseTokenAtLoc(childOrNil.Loc)\n\t\t\t\t\tp.options.Indent--\n\t\t\t\t\tp.printIndent()\n\t\t\t\t}\n\t\t\t\tp.print(\"}\")\n\t\t\t}\n\t\t}\n\n\t\t// Print the closing tag\n\t\tp.addSourceMapping(e.CloseLoc)\n\t\tp.print(\"</\")\n\t\tp.printJSXTag(e.TagOrNil)\n\t\tp.print(\">\")\n\n\tcase *js_ast.ENew:\n\t\twrap := level >= js_ast.LCall\n\n\t\thasPureComment := !p.options.MinifyWhitespace && e.CanBeUnwrappedIfUnused\n\t\tif hasPureComment && level >= js_ast.LPostfix {\n\t\t\twrap = true\n\t\t}\n\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t}\n\n\t\tif hasPureComment {\n\t\t\tp.addSourceMapping(expr.Loc)\n\t\t\tp.print(\"/* @__PURE__ */ \")\n\t\t}\n\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.print(\"new\")\n\t\tp.printSpace()\n\t\tp.printExpr(e.Target, js_ast.LNew, forbidCall)\n\n\t\t// Omit the \"()\" when minifying, but only when safe to do so\n\t\tisMultiLine := !p.options.MinifyWhitespace && ((e.IsMultiLine && len(e.Args) > 0) ||\n\t\t\tp.willPrintExprCommentsForAnyOf(e.Args) ||\n\t\t\tp.willPrintExprCommentsAtLoc(e.CloseParenLoc))\n\t\tif !p.options.MinifyWhitespace || len(e.Args) > 0 || level >= js_ast.LPostfix || isMultiLine {\n\t\t\tneedsNewline := true\n\t\t\tp.print(\"(\")\n\t\t\tif isMultiLine {\n\t\t\t\tp.options.Indent++\n\t\t\t}\n\t\t\tfor i, arg := range e.Args {\n\t\t\t\tif i != 0 {\n\t\t\t\t\tp.print(\",\")\n\t\t\t\t}\n\t\t\t\tif p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit() {\n\t\t\t\t\tif isMultiLine {\n\t\t\t\t\t\tif needsNewline {\n\t\t\t\t\t\t\tp.printNewline()\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.printIndent()\n\t\t\t\t\t} else if i != 0 {\n\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tp.printExpr(arg, js_ast.LComma, 0)\n\t\t\t\tneedsNewline = true\n\t\t\t}\n\t\t\tif isMultiLine {\n\t\t\t\tif needsNewline || p.willPrintExprCommentsAtLoc(e.CloseParenLoc) {\n\t\t\t\t\tp.printNewline()\n\t\t\t\t}\n\t\t\t\tp.printExprCommentsAfterCloseTokenAtLoc(e.CloseParenLoc)\n\t\t\t\tp.options.Indent--\n\t\t\t\tp.printIndent()\n\t\t\t}\n\t\t\tif e.CloseParenLoc.Start > expr.Loc.Start {\n\t\t\t\tp.addSourceMapping(e.CloseParenLoc)\n\t\t\t}\n\t\t\tp.print(\")\")\n\t\t}\n\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *js_ast.ECall:\n\t\tif p.options.MinifySyntax {\n\t\t\tvar symbolFlags ast.SymbolFlags\n\t\t\tswitch target := e.Target.Data.(type) {\n\t\t\tcase *js_ast.EIdentifier:\n\t\t\t\tsymbolFlags = p.symbols.Get(target.Ref).Flags\n\t\t\tcase *js_ast.EImportIdentifier:\n\t\t\t\tref := ast.FollowSymbols(p.symbols, target.Ref)\n\t\t\t\tsymbolFlags = p.symbols.Get(ref).Flags\n\t\t\t}\n\n\t\t\t// Replace non-mutated empty functions with their arguments at print time\n\t\t\tif (symbolFlags & (ast.IsEmptyFunction | ast.CouldPotentiallyBeMutated)) == ast.IsEmptyFunction {\n\t\t\t\tvar replacement js_ast.Expr\n\t\t\t\tfor _, arg := range e.Args {\n\t\t\t\t\tif _, ok := arg.Data.(*js_ast.ESpread); ok {\n\t\t\t\t\t\targ.Data = &js_ast.EArray{Items: []js_ast.Expr{arg}, IsSingleLine: true}\n\t\t\t\t\t}\n\t\t\t\t\treplacement = js_ast.JoinWithComma(replacement, p.astHelpers.SimplifyUnusedExpr(arg, p.options.UnsupportedFeatures))\n\t\t\t\t}\n\t\t\t\tif replacement.Data == nil || (flags&exprResultIsUnused) == 0 {\n\t\t\t\t\treplacement = js_ast.JoinWithComma(replacement, js_ast.Expr{Loc: expr.Loc, Data: js_ast.EUndefinedShared})\n\t\t\t\t}\n\t\t\t\tp.printExpr(p.guardAgainstBehaviorChangeDueToSubstitution(replacement, flags), level, flags)\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Inline non-mutated identity functions at print time\n\t\t\tif (symbolFlags&(ast.IsIdentityFunction|ast.CouldPotentiallyBeMutated)) == ast.IsIdentityFunction && len(e.Args) == 1 {\n\t\t\t\targ := e.Args[0]\n\t\t\t\tif _, ok := arg.Data.(*js_ast.ESpread); !ok {\n\t\t\t\t\tif (flags & exprResultIsUnused) != 0 {\n\t\t\t\t\t\targ = p.astHelpers.SimplifyUnusedExpr(arg, p.options.UnsupportedFeatures)\n\t\t\t\t\t\tif arg.Data == nil {\n\t\t\t\t\t\t\targ.Data = js_ast.EUndefinedShared\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tp.printExpr(p.guardAgainstBehaviorChangeDueToSubstitution(arg, flags), level, flags)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Inline IIFEs that return expressions at print time\n\t\t\tif len(e.Args) == 0 {\n\t\t\t\t// Note: Do not inline async arrow functions as they are not IIFEs. In\n\t\t\t\t// particular, they are not necessarily invoked immediately, and any\n\t\t\t\t// exceptions involved in their evaluation will be swallowed without\n\t\t\t\t// bubbling up to the surrounding context.\n\t\t\t\tif arrow, ok := e.Target.Data.(*js_ast.EArrow); ok && len(arrow.Args) == 0 && !arrow.IsAsync {\n\t\t\t\t\tstmts := arrow.Body.Block.Stmts\n\n\t\t\t\t\t// \"(() => {})()\" => \"void 0\"\n\t\t\t\t\tif len(stmts) == 0 {\n\t\t\t\t\t\tvalue := js_ast.Expr{Loc: expr.Loc, Data: js_ast.EUndefinedShared}\n\t\t\t\t\t\tp.printExpr(p.guardAgainstBehaviorChangeDueToSubstitution(value, flags), level, flags)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\t// \"(() => 123)()\" => \"123\"\n\t\t\t\t\tif len(stmts) == 1 {\n\t\t\t\t\t\tif stmt, ok := stmts[0].Data.(*js_ast.SReturn); ok {\n\t\t\t\t\t\t\tvalue := stmt.ValueOrNil\n\t\t\t\t\t\t\tif value.Data == nil {\n\t\t\t\t\t\t\t\tvalue.Data = js_ast.EUndefinedShared\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tp.printExpr(p.guardAgainstBehaviorChangeDueToSubstitution(value, flags), level, flags)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\twrap := level >= js_ast.LNew || (flags&forbidCall) != 0\n\t\tvar targetFlags printExprFlags\n\t\tif e.OptionalChain == js_ast.OptionalChainNone {\n\t\t\ttargetFlags = hasNonOptionalChainParent\n\t\t} else if (flags & hasNonOptionalChainParent) != 0 {\n\t\t\twrap = true\n\t\t}\n\n\t\thasPureComment := !p.options.MinifyWhitespace && e.CanBeUnwrappedIfUnused\n\t\tif hasPureComment && level >= js_ast.LPostfix {\n\t\t\twrap = true\n\t\t}\n\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t}\n\n\t\tif hasPureComment {\n\t\t\tflags := p.saveExprStartFlags()\n\t\t\tp.addSourceMapping(expr.Loc)\n\t\t\tp.print(\"/* @__PURE__ */ \")\n\t\t\tp.restoreExprStartFlags(flags)\n\t\t}\n\n\t\t// We don't ever want to accidentally generate a direct eval expression here\n\t\tp.callTarget = e.Target.Data\n\t\tif (e.Kind != js_ast.DirectEval && p.isUnboundEvalIdentifier(e.Target) && e.OptionalChain == js_ast.OptionalChainNone) ||\n\t\t\t(e.Kind != js_ast.TargetWasOriginallyPropertyAccess && js_ast.IsPropertyAccess(e.Target)) {\n\t\t\tp.print(\"(0,\")\n\t\t\tp.printSpace()\n\t\t\tp.printExpr(e.Target, js_ast.LPostfix, isCallTargetOrTemplateTag)\n\t\t\tp.print(\")\")\n\t\t} else {\n\t\t\tp.printExpr(e.Target, js_ast.LPostfix, isCallTargetOrTemplateTag|targetFlags)\n\t\t}\n\n\t\tif e.OptionalChain == js_ast.OptionalChainStart {\n\t\t\tp.print(\"?.\")\n\t\t}\n\n\t\tisMultiLine := !p.options.MinifyWhitespace && ((e.IsMultiLine && len(e.Args) > 0) ||\n\t\t\tp.willPrintExprCommentsForAnyOf(e.Args) ||\n\t\t\tp.willPrintExprCommentsAtLoc(e.CloseParenLoc))\n\t\tp.print(\"(\")\n\t\tif isMultiLine {\n\t\t\tp.options.Indent++\n\t\t}\n\t\tfor i, arg := range e.Args {\n\t\t\tif i != 0 {\n\t\t\t\tp.print(\",\")\n\t\t\t}\n\t\t\tif p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit() {\n\t\t\t\tif isMultiLine {\n\t\t\t\t\tp.printNewline()\n\t\t\t\t\tp.printIndent()\n\t\t\t\t} else if i != 0 {\n\t\t\t\t\tp.printSpace()\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.printExpr(arg, js_ast.LComma, 0)\n\t\t}\n\t\tif isMultiLine {\n\t\t\tp.printNewline()\n\t\t\tp.printExprCommentsAfterCloseTokenAtLoc(e.CloseParenLoc)\n\t\t\tp.options.Indent--\n\t\t\tp.printIndent()\n\t\t}\n\t\tif e.CloseParenLoc.Start > expr.Loc.Start {\n\t\t\tp.addSourceMapping(e.CloseParenLoc)\n\t\t}\n\t\tp.print(\")\")\n\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *js_ast.ERequireString:\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.printRequireOrImportExpr(e.ImportRecordIndex, level, flags, e.CloseParenLoc, ast.EvaluationPhase)\n\n\tcase *js_ast.ERequireResolveString:\n\t\trecordLoc := p.importRecords[e.ImportRecordIndex].Range.Loc\n\t\tisMultiLine := p.willPrintExprCommentsAtLoc(recordLoc) || p.willPrintExprCommentsAtLoc(e.CloseParenLoc)\n\t\twrap := level >= js_ast.LNew || (flags&forbidCall) != 0\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t}\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.print(\"require.resolve(\")\n\t\tif isMultiLine {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent++\n\t\t\tp.printIndent()\n\t\t\tp.printExprCommentsAtLoc(recordLoc)\n\t\t}\n\t\tp.printPath(e.ImportRecordIndex, ast.ImportRequireResolve)\n\t\tif isMultiLine {\n\t\t\tp.printNewline()\n\t\t\tp.printExprCommentsAfterCloseTokenAtLoc(e.CloseParenLoc)\n\t\t\tp.options.Indent--\n\t\t\tp.printIndent()\n\t\t}\n\t\tif e.CloseParenLoc.Start > expr.Loc.Start {\n\t\t\tp.addSourceMapping(e.CloseParenLoc)\n\t\t}\n\t\tp.print(\")\")\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *js_ast.EImportString:\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.printRequireOrImportExpr(e.ImportRecordIndex, level, flags, e.CloseParenLoc, p.importRecords[e.ImportRecordIndex].Phase)\n\n\tcase *js_ast.EImportCall:\n\t\t// Only print the second argument if either import assertions or import attributes are supported\n\t\tprintImportAssertOrWith := e.OptionsOrNil.Data != nil && (!p.options.UnsupportedFeatures.Has(compat.ImportAssertions) || !p.options.UnsupportedFeatures.Has(compat.ImportAttributes))\n\t\tisMultiLine := !p.options.MinifyWhitespace &&\n\t\t\t(p.willPrintExprCommentsAtLoc(e.Expr.Loc) ||\n\t\t\t\t(printImportAssertOrWith && p.willPrintExprCommentsAtLoc(e.OptionsOrNil.Loc)) ||\n\t\t\t\tp.willPrintExprCommentsAtLoc(e.CloseParenLoc))\n\t\twrap := level >= js_ast.LNew || (flags&forbidCall) != 0\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t}\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(expr.Loc)\n\t\tswitch e.Phase {\n\t\tcase ast.DeferPhase:\n\t\t\tp.print(\"import.defer(\")\n\t\tcase ast.SourcePhase:\n\t\t\tp.print(\"import.source(\")\n\t\tdefault:\n\t\t\tp.print(\"import(\")\n\t\t}\n\t\tif isMultiLine {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent++\n\t\t\tp.printIndent()\n\t\t}\n\t\tp.printExpr(e.Expr, js_ast.LComma, 0)\n\n\t\tif printImportAssertOrWith {\n\t\t\tp.print(\",\")\n\t\t\tif isMultiLine {\n\t\t\t\tp.printNewline()\n\t\t\t\tp.printIndent()\n\t\t\t} else {\n\t\t\t\tp.printSpace()\n\t\t\t}\n\t\t\tp.printExpr(e.OptionsOrNil, js_ast.LComma, 0)\n\t\t}\n\n\t\tif isMultiLine {\n\t\t\tp.printNewline()\n\t\t\tp.printExprCommentsAfterCloseTokenAtLoc(e.CloseParenLoc)\n\t\t\tp.options.Indent--\n\t\t\tp.printIndent()\n\t\t}\n\t\tp.print(\")\")\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *js_ast.EDot:\n\t\twrap := false\n\t\tif e.OptionalChain == js_ast.OptionalChainNone {\n\t\t\tflags |= hasNonOptionalChainParent\n\n\t\t\t// Inline cross-module TypeScript enum references here\n\t\t\tif value, ok := p.tryToGetImportedEnumValue(e.Target, e.Name); ok {\n\t\t\t\tif value.String != nil {\n\t\t\t\t\tp.printQuotedUTF16(value.String, printQuotedAllowBacktick)\n\t\t\t\t} else {\n\t\t\t\t\tp.printNumber(value.Number, level)\n\t\t\t\t}\n\t\t\t\tif !p.options.MinifyWhitespace && !p.options.MinifyIdentifiers && !strings.Contains(e.Name, \"*/\") {\n\t\t\t\t\tp.print(\" /* \")\n\t\t\t\t\tp.print(e.Name)\n\t\t\t\t\tp.print(\" */\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t} else {\n\t\t\tif (flags & hasNonOptionalChainParent) != 0 {\n\t\t\t\twrap = true\n\t\t\t\tp.print(\"(\")\n\t\t\t}\n\t\t\tflags &= ^hasNonOptionalChainParent\n\t\t}\n\t\tp.printExpr(e.Target, js_ast.LPostfix, (flags&(forbidCall|hasNonOptionalChainParent))|isPropertyAccessTarget)\n\t\tif p.canPrintIdentifier(e.Name) {\n\t\t\tif e.OptionalChain != js_ast.OptionalChainStart && p.needSpaceBeforeDot == len(p.js) {\n\t\t\t\t// \"1.toString\" is a syntax error, so print \"1 .toString\" instead\n\t\t\t\tp.print(\" \")\n\t\t\t}\n\t\t\tif e.OptionalChain == js_ast.OptionalChainStart {\n\t\t\t\tp.print(\"?.\")\n\t\t\t} else {\n\t\t\t\tp.print(\".\")\n\t\t\t}\n\t\t\tif p.options.LineLimit > 0 {\n\t\t\t\tp.printNewlinePastLineLimit()\n\t\t\t}\n\t\t\tp.addSourceMapping(e.NameLoc)\n\t\t\tp.printIdentifier(e.Name)\n\t\t} else {\n\t\t\tif e.OptionalChain == js_ast.OptionalChainStart {\n\t\t\t\tp.print(\"?.\")\n\t\t\t}\n\t\t\tp.print(\"[\")\n\t\t\tp.addSourceMapping(e.NameLoc)\n\t\t\tp.printQuotedUTF8(e.Name, printQuotedAllowBacktick)\n\t\t\tp.print(\"]\")\n\t\t}\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *js_ast.EIndex:\n\t\tif e.OptionalChain == js_ast.OptionalChainNone {\n\t\t\tflags |= hasNonOptionalChainParent\n\n\t\t\t// Inline cross-module TypeScript enum references here\n\t\t\tif index, ok := e.Index.Data.(*js_ast.EString); ok {\n\t\t\t\tif value, name, ok := p.tryToGetImportedEnumValueUTF16(e.Target, index.Value); ok {\n\t\t\t\t\tif value.String != nil {\n\t\t\t\t\t\tp.printQuotedUTF16(value.String, printQuotedAllowBacktick)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.printNumber(value.Number, level)\n\t\t\t\t\t}\n\t\t\t\t\tif !p.options.MinifyWhitespace && !p.options.MinifyIdentifiers && !strings.Contains(name, \"*/\") {\n\t\t\t\t\t\tp.print(\" /* \")\n\t\t\t\t\t\tp.print(name)\n\t\t\t\t\t\tp.print(\" */\")\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (flags & hasNonOptionalChainParent) != 0 {\n\t\t\t\tp.print(\"(\")\n\t\t\t\tdefer p.print(\")\")\n\t\t\t}\n\t\t\tflags &= ^hasNonOptionalChainParent\n\t\t}\n\t\tp.printExpr(e.Target, js_ast.LPostfix, (flags&(forbidCall|hasNonOptionalChainParent))|isPropertyAccessTarget)\n\t\tif e.OptionalChain == js_ast.OptionalChainStart {\n\t\t\tp.print(\"?.\")\n\t\t}\n\n\t\tswitch index := e.Index.Data.(type) {\n\t\tcase *js_ast.EPrivateIdentifier:\n\t\t\tif e.OptionalChain != js_ast.OptionalChainStart {\n\t\t\t\tp.print(\".\")\n\t\t\t}\n\t\t\tname := p.renamer.NameForSymbol(index.Ref)\n\t\t\tp.addSourceMappingForName(e.Index.Loc, name, index.Ref)\n\t\t\tp.printIdentifier(name)\n\t\t\treturn\n\n\t\tcase *js_ast.ENameOfSymbol:\n\t\t\tif name := p.mangledPropName(index.Ref); p.canPrintIdentifier(name) {\n\t\t\t\tif e.OptionalChain != js_ast.OptionalChainStart {\n\t\t\t\t\tp.print(\".\")\n\t\t\t\t}\n\t\t\t\tp.addSourceMappingForName(e.Index.Loc, name, index.Ref)\n\t\t\t\tp.printIdentifier(name)\n\t\t\t\treturn\n\t\t\t}\n\n\t\tcase *js_ast.EInlinedEnum:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tif str, ok := index.Value.Data.(*js_ast.EString); ok && p.canPrintIdentifierUTF16(str.Value) {\n\t\t\t\t\tif e.OptionalChain != js_ast.OptionalChainStart {\n\t\t\t\t\t\tp.print(\".\")\n\t\t\t\t\t}\n\t\t\t\t\tp.addSourceMapping(index.Value.Loc)\n\t\t\t\t\tp.printIdentifierUTF16(str.Value)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *js_ast.EDot:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tif value, ok := p.tryToGetImportedEnumValue(index.Target, index.Name); ok && value.String != nil && p.canPrintIdentifierUTF16(value.String) {\n\t\t\t\t\tif e.OptionalChain != js_ast.OptionalChainStart {\n\t\t\t\t\t\tp.print(\".\")\n\t\t\t\t\t}\n\t\t\t\t\tp.addSourceMapping(e.Index.Loc)\n\t\t\t\t\tp.printIdentifierUTF16(value.String)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tisMultiLine := p.willPrintExprCommentsAtLoc(e.Index.Loc) || p.willPrintExprCommentsAtLoc(e.CloseBracketLoc)\n\t\tp.print(\"[\")\n\t\tif isMultiLine {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent++\n\t\t\tp.printIndent()\n\t\t}\n\t\tp.printExpr(e.Index, js_ast.LLowest, 0)\n\t\tif isMultiLine {\n\t\t\tp.printNewline()\n\t\t\tp.printExprCommentsAfterCloseTokenAtLoc(e.CloseBracketLoc)\n\t\t\tp.options.Indent--\n\t\t\tp.printIndent()\n\t\t}\n\t\tif e.CloseBracketLoc.Start > expr.Loc.Start {\n\t\t\tp.addSourceMapping(e.CloseBracketLoc)\n\t\t}\n\t\tp.print(\"]\")\n\n\tcase *js_ast.EIf:\n\t\twrap := level >= js_ast.LConditional\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t\tflags &= ^forbidIn\n\t\t}\n\t\tp.printExpr(e.Test, js_ast.LConditional, (flags&forbidIn)|parentWasUnaryOrBinaryOrIfTest)\n\t\tp.printSpace()\n\t\tp.print(\"?\")\n\t\tif p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit() {\n\t\t\tp.printSpace()\n\t\t}\n\t\tp.printExprWithoutLeadingNewline(e.Yes, js_ast.LYield, 0)\n\t\tp.printSpace()\n\t\tp.print(\":\")\n\t\tif p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit() {\n\t\t\tp.printSpace()\n\t\t}\n\t\tp.printExprWithoutLeadingNewline(e.No, js_ast.LYield, flags&forbidIn)\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *js_ast.EArrow:\n\t\twrap := e.IsParenthesized || level >= js_ast.LAssign\n\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t}\n\t\tif !p.options.MinifyWhitespace && e.HasNoSideEffectsComment {\n\t\t\tp.print(\"/* @__NO_SIDE_EFFECTS__ */ \")\n\t\t}\n\t\tif e.IsAsync {\n\t\t\tp.addSourceMapping(expr.Loc)\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tp.print(\"async\")\n\t\t\tp.printSpace()\n\t\t}\n\n\t\tp.printFnArgs(e.Args, fnArgsOpts{\n\t\t\topenParenLoc:              expr.Loc,\n\t\t\taddMappingForOpenParenLoc: !e.IsAsync,\n\t\t\thasRestArg:                e.HasRestArg,\n\t\t\tisArrow:                   true,\n\t\t})\n\t\tp.printSpace()\n\t\tp.print(\"=>\")\n\t\tp.printSpace()\n\n\t\twasPrinted := false\n\t\tif len(e.Body.Block.Stmts) == 1 && e.PreferExpr {\n\t\t\tif s, ok := e.Body.Block.Stmts[0].Data.(*js_ast.SReturn); ok && s.ValueOrNil.Data != nil {\n\t\t\t\tvar nestedFlags printExprFlags\n\t\t\t\tif (flags&forbidIn) != 0 && !wrap {\n\t\t\t\t\tnestedFlags |= forbidIn\n\t\t\t\t}\n\t\t\t\tp.arrowExprStart = len(p.js)\n\t\t\t\tp.printExprWithoutLeadingNewline(s.ValueOrNil, js_ast.LComma, nestedFlags)\n\t\t\t\twasPrinted = true\n\t\t\t}\n\t\t}\n\t\tif !wasPrinted {\n\t\t\tp.printBlock(e.Body.Loc, e.Body.Block)\n\t\t}\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *js_ast.EFunction:\n\t\tn := len(p.js)\n\t\twrap := e.IsParenthesized || p.stmtStart == n || p.exportDefaultStart == n ||\n\t\t\t((flags&isPropertyAccessTarget) != 0 && p.options.UnsupportedFeatures.Has(compat.FunctionOrClassPropertyAccess))\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t}\n\t\tif !p.options.MinifyWhitespace && e.Fn.HasNoSideEffectsComment {\n\t\t\tp.print(\"/* @__NO_SIDE_EFFECTS__ */ \")\n\t\t}\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(expr.Loc)\n\t\tif e.Fn.IsAsync {\n\t\t\tp.print(\"async \")\n\t\t}\n\t\tp.print(\"function\")\n\t\tif e.Fn.IsGenerator {\n\t\t\tp.print(\"*\")\n\t\t\tp.printSpace()\n\t\t}\n\t\tif e.Fn.Name != nil {\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tname := p.renamer.NameForSymbol(e.Fn.Name.Ref)\n\t\t\tp.addSourceMappingForName(e.Fn.Name.Loc, name, e.Fn.Name.Ref)\n\t\t\tp.printIdentifier(name)\n\t\t}\n\t\tp.printFn(e.Fn)\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *js_ast.EClass:\n\t\tn := len(p.js)\n\t\twrap := p.stmtStart == n || p.exportDefaultStart == n ||\n\t\t\t((flags&isPropertyAccessTarget) != 0 && p.options.UnsupportedFeatures.Has(compat.FunctionOrClassPropertyAccess))\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t}\n\t\tp.printDecorators(e.Class.Decorators, printSpaceAfterDecorator)\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.print(\"class\")\n\t\tif e.Class.Name != nil {\n\t\t\tp.print(\" \")\n\t\t\tname := p.renamer.NameForSymbol(e.Class.Name.Ref)\n\t\t\tp.addSourceMappingForName(e.Class.Name.Loc, name, e.Class.Name.Ref)\n\t\t\tp.printIdentifier(name)\n\t\t}\n\t\tp.printClass(e.Class)\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *js_ast.EArray:\n\t\tisMultiLine := (len(e.Items) > 0 && !e.IsSingleLine) || p.willPrintExprCommentsForAnyOf(e.Items) || p.willPrintExprCommentsAtLoc(e.CloseBracketLoc)\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.print(\"[\")\n\t\tif len(e.Items) > 0 || isMultiLine {\n\t\t\tif isMultiLine {\n\t\t\t\tp.options.Indent++\n\t\t\t}\n\n\t\t\tfor i, item := range e.Items {\n\t\t\t\tif i != 0 {\n\t\t\t\t\tp.print(\",\")\n\t\t\t\t}\n\t\t\t\tif p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit() {\n\t\t\t\t\tif isMultiLine {\n\t\t\t\t\t\tp.printNewline()\n\t\t\t\t\t\tp.printIndent()\n\t\t\t\t\t} else if i != 0 {\n\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tp.printExpr(item, js_ast.LComma, 0)\n\n\t\t\t\t// Make sure there's a comma after trailing missing items\n\t\t\t\t_, ok := item.Data.(*js_ast.EMissing)\n\t\t\t\tif ok && i == len(e.Items)-1 {\n\t\t\t\t\tp.print(\",\")\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif isMultiLine {\n\t\t\t\tp.printNewline()\n\t\t\t\tp.printExprCommentsAfterCloseTokenAtLoc(e.CloseBracketLoc)\n\t\t\t\tp.options.Indent--\n\t\t\t\tp.printIndent()\n\t\t\t}\n\t\t}\n\t\tif e.CloseBracketLoc.Start > expr.Loc.Start {\n\t\t\tp.addSourceMapping(e.CloseBracketLoc)\n\t\t}\n\t\tp.print(\"]\")\n\n\tcase *js_ast.EObject:\n\t\tisMultiLine := (len(e.Properties) > 0 && !e.IsSingleLine) || p.willPrintExprCommentsAtLoc(e.CloseBraceLoc)\n\t\tif !p.options.MinifyWhitespace && !isMultiLine {\n\t\t\tfor _, property := range e.Properties {\n\t\t\t\tif p.willPrintExprCommentsAtLoc(property.Loc) {\n\t\t\t\t\tisMultiLine = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tn := len(p.js)\n\t\twrap := p.stmtStart == n || p.arrowExprStart == n\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t}\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.print(\"{\")\n\t\tif len(e.Properties) > 0 || isMultiLine {\n\t\t\tif isMultiLine {\n\t\t\t\tp.options.Indent++\n\t\t\t}\n\n\t\t\tfor i, item := range e.Properties {\n\t\t\t\tif i != 0 {\n\t\t\t\t\tp.print(\",\")\n\t\t\t\t}\n\t\t\t\tif p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit() {\n\t\t\t\t\tif isMultiLine {\n\t\t\t\t\t\tp.printNewline()\n\t\t\t\t\t\tp.printIndent()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tp.printProperty(item)\n\t\t\t}\n\n\t\t\tif isMultiLine {\n\t\t\t\tp.printNewline()\n\t\t\t\tp.printExprCommentsAfterCloseTokenAtLoc(e.CloseBraceLoc)\n\t\t\t\tp.options.Indent--\n\t\t\t\tp.printIndent()\n\t\t\t} else if len(e.Properties) > 0 {\n\t\t\t\tp.printSpace()\n\t\t\t}\n\t\t}\n\t\tif e.CloseBraceLoc.Start > expr.Loc.Start {\n\t\t\tp.addSourceMapping(e.CloseBraceLoc)\n\t\t}\n\t\tp.print(\"}\")\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *js_ast.EBoolean:\n\t\tp.addSourceMapping(expr.Loc)\n\t\tif p.options.MinifySyntax {\n\t\t\tif level >= js_ast.LPrefix {\n\t\t\t\tif e.Value {\n\t\t\t\t\tp.print(\"(!0)\")\n\t\t\t\t} else {\n\t\t\t\t\tp.print(\"(!1)\")\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif e.Value {\n\t\t\t\t\tp.print(\"!0\")\n\t\t\t\t} else {\n\t\t\t\t\tp.print(\"!1\")\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tif e.Value {\n\t\t\t\tp.print(\"true\")\n\t\t\t} else {\n\t\t\t\tp.print(\"false\")\n\t\t\t}\n\t\t}\n\n\tcase *js_ast.EString:\n\t\tvar flags printQuotedFlags\n\t\tif e.ContainsUniqueKey {\n\t\t\tflags = printQuotedNoWrap\n\t\t}\n\t\tp.addSourceMapping(expr.Loc)\n\n\t\tif !p.options.MinifyWhitespace && e.HasPropertyKeyComment {\n\t\t\tp.print(\"/* @__KEY__ */ \")\n\t\t}\n\n\t\t// If this was originally a template literal, print it as one as long as we're not minifying\n\t\tif e.PreferTemplate && !p.options.MinifySyntax && !p.options.UnsupportedFeatures.Has(compat.TemplateLiteral) {\n\t\t\tp.print(\"`\")\n\t\t\tp.printUnquotedUTF16(e.Value, '`', flags)\n\t\t\tp.print(\"`\")\n\t\t\treturn\n\t\t}\n\n\t\tp.printQuotedUTF16(e.Value, flags|printQuotedAllowBacktick)\n\n\tcase *js_ast.ETemplate:\n\t\tif e.TagOrNil.Data == nil && (p.options.MinifySyntax || p.wasLazyExport) {\n\t\t\t// Inline enums and mangled properties when minifying\n\t\t\tvar replaced []js_ast.TemplatePart\n\t\t\tfor i, part := range e.Parts {\n\t\t\t\tvar inlinedValue js_ast.E\n\t\t\t\tswitch e2 := part.Value.Data.(type) {\n\t\t\t\tcase *js_ast.ENameOfSymbol:\n\t\t\t\t\tinlinedValue = &js_ast.EString{\n\t\t\t\t\t\tValue:                 helpers.StringToUTF16(p.mangledPropName(e2.Ref)),\n\t\t\t\t\t\tHasPropertyKeyComment: e2.HasPropertyKeyComment,\n\t\t\t\t\t}\n\t\t\t\tcase *js_ast.EDot:\n\t\t\t\t\tif value, ok := p.tryToGetImportedEnumValue(e2.Target, e2.Name); ok {\n\t\t\t\t\t\tif value.String != nil {\n\t\t\t\t\t\t\tinlinedValue = &js_ast.EString{Value: value.String}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tinlinedValue = &js_ast.ENumber{Value: value.Number}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif inlinedValue != nil {\n\t\t\t\t\tif replaced == nil {\n\t\t\t\t\t\treplaced = make([]js_ast.TemplatePart, 0, len(e.Parts))\n\t\t\t\t\t\treplaced = append(replaced, e.Parts[:i]...)\n\t\t\t\t\t}\n\t\t\t\t\tpart.Value.Data = inlinedValue\n\t\t\t\t\treplaced = append(replaced, part)\n\t\t\t\t} else if replaced != nil {\n\t\t\t\t\treplaced = append(replaced, part)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif replaced != nil {\n\t\t\t\tcopy := *e\n\t\t\t\tcopy.Parts = replaced\n\t\t\t\tswitch e2 := js_ast.InlinePrimitivesIntoTemplate(logger.Loc{}, &copy).Data.(type) {\n\t\t\t\tcase *js_ast.EString:\n\t\t\t\t\tp.printQuotedUTF16(e2.Value, printQuotedAllowBacktick)\n\t\t\t\t\treturn\n\t\t\t\tcase *js_ast.ETemplate:\n\t\t\t\t\te = e2\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Convert no-substitution template literals into strings if it's smaller\n\t\t\tif len(e.Parts) == 0 {\n\t\t\t\tp.addSourceMapping(expr.Loc)\n\t\t\t\tp.printQuotedUTF16(e.HeadCooked, printQuotedAllowBacktick)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif e.TagOrNil.Data != nil {\n\t\t\ttagIsPropertyAccess := false\n\t\t\tswitch e.TagOrNil.Data.(type) {\n\t\t\tcase *js_ast.EDot, *js_ast.EIndex:\n\t\t\t\ttagIsPropertyAccess = true\n\t\t\t}\n\t\t\tif !e.TagWasOriginallyPropertyAccess && tagIsPropertyAccess {\n\t\t\t\t// Prevent \"x``\" from becoming \"y.z``\"\n\t\t\t\tp.print(\"(0,\")\n\t\t\t\tp.printSpace()\n\t\t\t\tp.printExpr(e.TagOrNil, js_ast.LLowest, isCallTargetOrTemplateTag)\n\t\t\t\tp.print(\")\")\n\t\t\t} else if js_ast.IsOptionalChain(e.TagOrNil) {\n\t\t\t\t// Optional chains are forbidden in template tags\n\t\t\t\tp.print(\"(\")\n\t\t\t\tp.printExpr(e.TagOrNil, js_ast.LLowest, isCallTargetOrTemplateTag)\n\t\t\t\tp.print(\")\")\n\t\t\t} else {\n\t\t\t\tp.printExpr(e.TagOrNil, js_ast.LPostfix, isCallTargetOrTemplateTag)\n\t\t\t}\n\t\t} else {\n\t\t\tp.addSourceMapping(expr.Loc)\n\t\t}\n\t\tp.print(\"`\")\n\t\tif e.TagOrNil.Data != nil {\n\t\t\tp.print(e.HeadRaw)\n\t\t} else {\n\t\t\tp.printUnquotedUTF16(e.HeadCooked, '`', 0)\n\t\t}\n\t\tfor _, part := range e.Parts {\n\t\t\tp.print(\"${\")\n\t\t\tp.printExpr(part.Value, js_ast.LLowest, 0)\n\t\t\tp.addSourceMapping(part.TailLoc)\n\t\t\tp.print(\"}\")\n\t\t\tif e.TagOrNil.Data != nil {\n\t\t\t\tp.print(part.TailRaw)\n\t\t\t} else {\n\t\t\t\tp.printUnquotedUTF16(part.TailCooked, '`', 0)\n\t\t\t}\n\t\t}\n\t\tp.print(\"`\")\n\n\tcase *js_ast.ERegExp:\n\t\tbuffer := p.js\n\t\tn := len(buffer)\n\n\t\t// Avoid forming a single-line comment or \"</script\" sequence\n\t\tif !p.options.UnsupportedFeatures.Has(compat.InlineScript) && n > 0 {\n\t\t\tif last := buffer[n-1]; last == '/' || (last == '<' && len(e.Value) >= 7 && strings.EqualFold(e.Value[:7], \"/script\")) {\n\t\t\t\tp.print(\" \")\n\t\t\t}\n\t\t}\n\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.print(e.Value)\n\n\t\t// Need a space before the next identifier to avoid it turning into flags\n\t\tp.prevRegExpEnd = len(p.js)\n\n\tcase *js_ast.EInlinedEnum:\n\t\tp.printExpr(e.Value, level, flags)\n\n\t\tif !p.options.MinifyWhitespace && !p.options.MinifyIdentifiers {\n\t\t\tp.print(\" /* \")\n\t\t\tp.print(e.Comment)\n\t\t\tp.print(\" */\")\n\t\t}\n\n\tcase *js_ast.EBigInt:\n\t\tif !p.options.UnsupportedFeatures.Has(compat.Bigint) {\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tp.addSourceMapping(expr.Loc)\n\t\t\tp.print(e.Value)\n\t\t\tp.print(\"n\")\n\t\t\tbreak\n\t\t}\n\n\t\twrap := level >= js_ast.LNew || (flags&forbidCall) != 0\n\t\thasPureComment := !p.options.MinifyWhitespace\n\n\t\tif hasPureComment && level >= js_ast.LPostfix {\n\t\t\twrap = true\n\t\t}\n\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t}\n\n\t\tif hasPureComment {\n\t\t\tflags := p.saveExprStartFlags()\n\t\t\tp.addSourceMapping(expr.Loc)\n\t\t\tp.print(\"/* @__PURE__ */ \")\n\t\t\tp.restoreExprStartFlags(flags)\n\t\t}\n\n\t\tvalue := e.Value\n\t\tuseQuotes := true\n\n\t\t// When minifying, try to convert to a shorter form\n\t\tif p.options.MinifySyntax {\n\t\t\tvar i big.Int\n\t\t\tfmt.Sscan(value, &i)\n\t\t\tstr := i.String()\n\n\t\t\t// Print without quotes if it can be converted exactly\n\t\t\tif num, err := strconv.ParseFloat(str, 64); err == nil && str == fmt.Sprintf(\"%.0f\", num) {\n\t\t\t\tuseQuotes = false\n\t\t\t}\n\n\t\t\t// Print the converted form if it's shorter (long hex strings may not be shorter)\n\t\t\tif len(str) < len(value) {\n\t\t\t\tvalue = str\n\t\t\t}\n\t\t}\n\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(expr.Loc)\n\n\t\tif useQuotes {\n\t\t\tp.print(\"BigInt(\\\"\")\n\t\t} else {\n\t\t\tp.print(\"BigInt(\")\n\t\t}\n\n\t\tp.print(value)\n\n\t\tif useQuotes {\n\t\t\tp.print(\"\\\")\")\n\t\t} else {\n\t\t\tp.print(\")\")\n\t\t}\n\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *js_ast.ENumber:\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.printNumber(e.Value, level)\n\n\tcase *js_ast.EIdentifier:\n\t\tname := p.renamer.NameForSymbol(e.Ref)\n\t\twrap := len(p.js) == p.forOfInitStart && (name == \"let\" ||\n\t\t\t((flags&isFollowedByOf) != 0 && (flags&isInsideForAwait) == 0 && name == \"async\"))\n\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t}\n\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMappingForName(expr.Loc, name, e.Ref)\n\t\tp.printIdentifier(name)\n\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *js_ast.EImportIdentifier:\n\t\t// Potentially use a property access instead of an identifier\n\t\tref := ast.FollowSymbols(p.symbols, e.Ref)\n\t\tsymbol := p.symbols.Get(ref)\n\n\t\tif symbol.ImportItemStatus == ast.ImportItemMissing {\n\t\t\tp.printUndefined(expr.Loc, level)\n\t\t} else if symbol.NamespaceAlias != nil {\n\t\t\twrap := p.callTarget == e && e.WasOriginallyIdentifier\n\t\t\tif wrap {\n\t\t\t\tp.print(\"(0,\")\n\t\t\t\tp.printSpace()\n\t\t\t}\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tp.addSourceMapping(expr.Loc)\n\t\t\tp.printIdentifier(p.renamer.NameForSymbol(symbol.NamespaceAlias.NamespaceRef))\n\t\t\talias := symbol.NamespaceAlias.Alias\n\t\t\tif !e.PreferQuotedKey && p.canPrintIdentifier(alias) {\n\t\t\t\tp.print(\".\")\n\t\t\t\tp.addSourceMappingForName(expr.Loc, alias, ref)\n\t\t\t\tp.printIdentifier(alias)\n\t\t\t} else {\n\t\t\t\tp.print(\"[\")\n\t\t\t\tp.addSourceMappingForName(expr.Loc, alias, ref)\n\t\t\t\tp.printQuotedUTF8(alias, printQuotedAllowBacktick)\n\t\t\t\tp.print(\"]\")\n\t\t\t}\n\t\t\tif wrap {\n\t\t\t\tp.print(\")\")\n\t\t\t}\n\t\t} else if value := p.options.ConstValues[ref]; value.Kind != js_ast.ConstValueNone {\n\t\t\t// Handle inlined constants\n\t\t\tp.printExpr(js_ast.ConstValueToExpr(expr.Loc, value), level, flags)\n\t\t} else {\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tname := p.renamer.NameForSymbol(ref)\n\t\t\tp.addSourceMappingForName(expr.Loc, name, ref)\n\t\t\tp.printIdentifier(name)\n\t\t}\n\n\tcase *js_ast.EAwait:\n\t\twrap := level >= js_ast.LPrefix\n\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t}\n\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.print(\"await\")\n\t\tp.printSpace()\n\t\tp.printExpr(e.Value, js_ast.LPrefix-1, 0)\n\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *js_ast.EYield:\n\t\twrap := level >= js_ast.LAssign\n\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t}\n\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(expr.Loc)\n\t\tp.print(\"yield\")\n\n\t\tif e.ValueOrNil.Data != nil {\n\t\t\tif e.IsStar {\n\t\t\t\tp.print(\"*\")\n\t\t\t}\n\t\t\tp.printSpace()\n\t\t\tp.printExprWithoutLeadingNewline(e.ValueOrNil, js_ast.LYield, 0)\n\t\t}\n\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *js_ast.EUnary:\n\t\tentry := js_ast.OpTable[e.Op]\n\t\twrap := level >= entry.Level\n\n\t\tif wrap {\n\t\t\tp.print(\"(\")\n\t\t}\n\n\t\tif !e.Op.IsPrefix() {\n\t\t\tp.printExpr(e.Value, js_ast.LPostfix-1, parentWasUnaryOrBinaryOrIfTest)\n\t\t}\n\n\t\tif entry.IsKeyword {\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tif e.Op.IsPrefix() {\n\t\t\t\tp.addSourceMapping(expr.Loc)\n\t\t\t}\n\t\t\tp.print(entry.Text)\n\t\t\tp.printSpace()\n\t\t} else {\n\t\t\tp.printSpaceBeforeOperator(e.Op)\n\t\t\tif e.Op.IsPrefix() {\n\t\t\t\tp.addSourceMapping(expr.Loc)\n\t\t\t}\n\t\t\tp.print(entry.Text)\n\t\t\tp.prevOp = e.Op\n\t\t\tp.prevOpEnd = len(p.js)\n\t\t}\n\n\t\tif e.Op.IsPrefix() {\n\t\t\tvalueFlags := parentWasUnaryOrBinaryOrIfTest\n\t\t\tif e.Op == js_ast.UnOpDelete {\n\t\t\t\tvalueFlags |= isDeleteTarget\n\t\t\t}\n\n\t\t\t// Never turn \"typeof (0, x)\" into \"typeof x\" or \"delete (0, x)\" into \"delete x\"\n\t\t\tif (e.Op == js_ast.UnOpTypeof && !e.WasOriginallyTypeofIdentifier && p.isUnboundIdentifier(e.Value)) ||\n\t\t\t\t(e.Op == js_ast.UnOpDelete && !e.WasOriginallyDeleteOfIdentifierOrPropertyAccess && p.isIdentifierOrNumericConstantOrPropertyAccess(e.Value)) {\n\t\t\t\tp.print(\"(0,\")\n\t\t\t\tp.printSpace()\n\t\t\t\tp.printExpr(e.Value, js_ast.LPrefix-1, valueFlags)\n\t\t\t\tp.print(\")\")\n\t\t\t} else {\n\t\t\t\tp.printExpr(e.Value, js_ast.LPrefix-1, valueFlags)\n\t\t\t}\n\t\t}\n\n\t\tif wrap {\n\t\t\tp.print(\")\")\n\t\t}\n\n\tcase *js_ast.EBinary:\n\t\t// The handling of binary expressions is convoluted because we're using\n\t\t// iteration on the heap instead of recursion on the call stack to avoid\n\t\t// stack overflow for deeply-nested ASTs. See the comments for the similar\n\t\t// code in the JavaScript parser for details.\n\t\tv := binaryExprVisitor{\n\t\t\te:     e,\n\t\t\tlevel: level,\n\t\t\tflags: flags,\n\t\t}\n\n\t\t// Use a single stack to reduce allocation overhead\n\t\tstackBottom := len(p.binaryExprStack)\n\n\t\tfor {\n\t\t\t// Check whether this node is a special case, and stop if it is\n\t\t\tif !v.checkAndPrepare(p) {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tleft := v.e.Left\n\t\t\tleftBinary, ok := left.Data.(*js_ast.EBinary)\n\n\t\t\t// Stop iterating if iteration doesn't apply to the left node\n\t\t\tif !ok {\n\t\t\t\tp.printExpr(left, v.leftLevel, v.leftFlags)\n\t\t\t\tv.visitRightAndFinish(p)\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Manually run the code at the start of \"printExpr\"\n\t\t\tp.printExprCommentsAtLoc(left.Loc)\n\n\t\t\t// Only allocate heap memory on the stack for nested binary expressions\n\t\t\tp.binaryExprStack = append(p.binaryExprStack, v)\n\t\t\tv = binaryExprVisitor{\n\t\t\t\te:     leftBinary,\n\t\t\t\tlevel: v.leftLevel,\n\t\t\t\tflags: v.leftFlags,\n\t\t\t}\n\t\t}\n\n\t\t// Process all binary operations from the deepest-visited node back toward\n\t\t// our original top-level binary operation\n\t\tfor {\n\t\t\tn := len(p.binaryExprStack) - 1\n\t\t\tif n < stackBottom {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tv := p.binaryExprStack[n]\n\t\t\tp.binaryExprStack = p.binaryExprStack[:n]\n\t\t\tv.visitRightAndFinish(p)\n\t\t}\n\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"Unexpected expression of type %T\", expr.Data))\n\t}\n}\n\n// The handling of binary expressions is convoluted because we're using\n// iteration on the heap instead of recursion on the call stack to avoid\n// stack overflow for deeply-nested ASTs. See the comments for the similar\n// code in the JavaScript parser for details.\ntype binaryExprVisitor struct {\n\t// Inputs\n\te     *js_ast.EBinary\n\tlevel js_ast.L\n\tflags printExprFlags\n\n\t// Input for visiting the left child\n\tleftLevel js_ast.L\n\tleftFlags printExprFlags\n\n\t// \"Local variables\" passed from \"checkAndPrepare\" to \"visitRightAndFinish\"\n\tentry      js_ast.OpTableEntry\n\twrap       bool\n\trightLevel js_ast.L\n}\n\nfunc (v *binaryExprVisitor) checkAndPrepare(p *printer) bool {\n\te := v.e\n\n\t// If this is a comma operator then either the result is unused (and we\n\t// should have already simplified unused expressions), or the result is used\n\t// (and we can still simplify unused expressions inside the left operand)\n\tif e.Op == js_ast.BinOpComma {\n\t\tif (v.flags & didAlreadySimplifyUnusedExprs) == 0 {\n\t\t\tleft := p.simplifyUnusedExpr(e.Left)\n\t\t\tright := e.Right\n\t\t\tif (v.flags & exprResultIsUnused) != 0 {\n\t\t\t\tright = p.simplifyUnusedExpr(right)\n\t\t\t}\n\t\t\tif left.Data != e.Left.Data || right.Data != e.Right.Data {\n\t\t\t\t// Pass a flag so we don't needlessly re-simplify the same expression\n\t\t\t\tp.printExpr(p.guardAgainstBehaviorChangeDueToSubstitution(js_ast.JoinWithComma(left, right), v.flags), v.level, v.flags|didAlreadySimplifyUnusedExprs)\n\t\t\t\treturn false\n\t\t\t}\n\t\t} else {\n\t\t\t// Pass a flag so we don't needlessly re-simplify the same expression\n\t\t\tv.flags |= didAlreadySimplifyUnusedExprs\n\t\t}\n\t}\n\n\tv.entry = js_ast.OpTable[e.Op]\n\tv.wrap = v.level >= v.entry.Level || (e.Op == js_ast.BinOpIn && (v.flags&forbidIn) != 0)\n\n\t// Destructuring assignments must be parenthesized\n\tif n := len(p.js); p.stmtStart == n || p.arrowExprStart == n {\n\t\tif _, ok := e.Left.Data.(*js_ast.EObject); ok {\n\t\t\tv.wrap = true\n\t\t}\n\t}\n\n\tif v.wrap {\n\t\tp.print(\"(\")\n\t\tv.flags &= ^forbidIn\n\t}\n\n\tv.leftLevel = v.entry.Level - 1\n\tv.rightLevel = v.entry.Level - 1\n\n\tif e.Op.IsRightAssociative() {\n\t\tv.leftLevel = v.entry.Level\n\t}\n\tif e.Op.IsLeftAssociative() {\n\t\tv.rightLevel = v.entry.Level\n\t}\n\n\tswitch e.Op {\n\tcase js_ast.BinOpNullishCoalescing:\n\t\t// \"??\" can't directly contain \"||\" or \"&&\" without being wrapped in parentheses\n\t\tif left, ok := e.Left.Data.(*js_ast.EBinary); ok && (left.Op == js_ast.BinOpLogicalOr || left.Op == js_ast.BinOpLogicalAnd) {\n\t\t\tv.leftLevel = js_ast.LPrefix\n\t\t}\n\t\tif right, ok := e.Right.Data.(*js_ast.EBinary); ok && (right.Op == js_ast.BinOpLogicalOr || right.Op == js_ast.BinOpLogicalAnd) {\n\t\t\tv.rightLevel = js_ast.LPrefix\n\t\t}\n\n\tcase js_ast.BinOpPow:\n\t\t// \"**\" can't contain certain unary expressions\n\t\tif left, ok := e.Left.Data.(*js_ast.EUnary); ok && left.Op.UnaryAssignTarget() == js_ast.AssignTargetNone {\n\t\t\tv.leftLevel = js_ast.LCall\n\t\t} else if _, ok := e.Left.Data.(*js_ast.EAwait); ok {\n\t\t\tv.leftLevel = js_ast.LCall\n\t\t} else if _, ok := e.Left.Data.(*js_ast.EUndefined); ok {\n\t\t\t// Undefined is printed as \"void 0\"\n\t\t\tv.leftLevel = js_ast.LCall\n\t\t} else if _, ok := e.Left.Data.(*js_ast.ENumber); ok {\n\t\t\t// Negative numbers are printed using a unary operator\n\t\t\tv.leftLevel = js_ast.LCall\n\t\t} else if p.options.MinifySyntax {\n\t\t\t// When minifying, booleans are printed as \"!0 and \"!1\"\n\t\t\tif _, ok := e.Left.Data.(*js_ast.EBoolean); ok {\n\t\t\t\tv.leftLevel = js_ast.LCall\n\t\t\t}\n\t\t}\n\t}\n\n\t// Special-case \"#foo in bar\"\n\tif private, ok := e.Left.Data.(*js_ast.EPrivateIdentifier); ok && e.Op == js_ast.BinOpIn {\n\t\tname := p.renamer.NameForSymbol(private.Ref)\n\t\tp.addSourceMappingForName(e.Left.Loc, name, private.Ref)\n\t\tp.printIdentifier(name)\n\t\tv.visitRightAndFinish(p)\n\t\treturn false\n\t}\n\n\tif e.Op == js_ast.BinOpComma {\n\t\t// The result of the left operand of the comma operator is unused\n\t\tv.leftFlags = (v.flags & forbidIn) | exprResultIsUnused | parentWasUnaryOrBinaryOrIfTest\n\t} else {\n\t\tv.leftFlags = (v.flags & forbidIn) | parentWasUnaryOrBinaryOrIfTest\n\t}\n\treturn true\n}\n\nfunc (v *binaryExprVisitor) visitRightAndFinish(p *printer) {\n\te := v.e\n\n\tif e.Op != js_ast.BinOpComma {\n\t\tp.printSpace()\n\t}\n\n\tif v.entry.IsKeyword {\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(v.entry.Text)\n\t} else {\n\t\tp.printSpaceBeforeOperator(e.Op)\n\t\tp.print(v.entry.Text)\n\t\tp.prevOp = e.Op\n\t\tp.prevOpEnd = len(p.js)\n\t}\n\n\tif p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit() {\n\t\tp.printSpace()\n\t}\n\n\tif e.Op == js_ast.BinOpComma {\n\t\t// The result of the right operand of the comma operator is unused if the caller doesn't use it\n\t\tp.printExpr(e.Right, v.rightLevel, (v.flags&(forbidIn|exprResultIsUnused))|parentWasUnaryOrBinaryOrIfTest)\n\t} else {\n\t\tp.printExpr(e.Right, v.rightLevel, (v.flags&forbidIn)|parentWasUnaryOrBinaryOrIfTest)\n\t}\n\n\tif v.wrap {\n\t\tp.print(\")\")\n\t}\n}\n\nfunc (p *printer) isUnboundEvalIdentifier(value js_ast.Expr) bool {\n\tif id, ok := value.Data.(*js_ast.EIdentifier); ok {\n\t\t// Using the original name here is ok since unbound symbols are not renamed\n\t\tsymbol := p.symbols.Get(ast.FollowSymbols(p.symbols, id.Ref))\n\t\treturn symbol.Kind == ast.SymbolUnbound && symbol.OriginalName == \"eval\"\n\t}\n\treturn false\n}\n\n// Convert an integer to a byte slice without any allocations\nfunc (p *printer) smallIntToBytes(n int) []byte {\n\twasNegative := n < 0\n\tif wasNegative {\n\t\t// This assumes that -math.MinInt isn't a problem. This is fine because\n\t\t// these integers are floating-point exponents which never go up that high.\n\t\tn = -n\n\t}\n\n\tbytes := p.intToBytesBuffer[:]\n\tstart := len(bytes)\n\n\t// Write out the number from the end to the front\n\tfor {\n\t\tstart--\n\t\tbytes[start] = '0' + byte(n%10)\n\t\tn /= 10\n\t\tif n == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Stick a negative sign on the front if needed\n\tif wasNegative {\n\t\tstart--\n\t\tbytes[start] = '-'\n\t}\n\n\treturn bytes[start:]\n}\n\nfunc parseSmallInt(bytes []byte) int {\n\twasNegative := bytes[0] == '-'\n\tif wasNegative {\n\t\tbytes = bytes[1:]\n\t}\n\n\t// Parse the integer without any error checking. This doesn't need to handle\n\t// integer overflow because these integers are floating-point exponents which\n\t// never go up that high.\n\tn := 0\n\tfor _, c := range bytes {\n\t\tn = n*10 + int(c-'0')\n\t}\n\n\tif wasNegative {\n\t\treturn -n\n\t}\n\treturn n\n}\n\nfunc (p *printer) printNonNegativeFloat(absValue float64) {\n\t// We can avoid the slow call to strconv.FormatFloat() for integers less than\n\t// 1000 because we know that exponential notation will always be longer than\n\t// the integer representation. This is not the case for 1000 which is \"1e3\".\n\tif absValue < 1000 {\n\t\tif asInt := int64(absValue); absValue == float64(asInt) {\n\t\t\tp.printBytes(p.smallIntToBytes(int(asInt)))\n\n\t\t\t// Integers always need a space before \".\" to avoid making a decimal point\n\t\t\tp.needSpaceBeforeDot = len(p.js)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Format this number into a byte slice so we can mutate it in place without\n\t// further reallocation\n\tresult := []byte(strconv.FormatFloat(absValue, 'g', -1, 64))\n\n\t// Simplify the exponent\n\t// \"e+05\" => \"e5\"\n\t// \"e-05\" => \"e-5\"\n\tif e := bytes.LastIndexByte(result, 'e'); e != -1 {\n\t\tfrom := e + 1\n\t\tto := from\n\n\t\tswitch result[from] {\n\t\tcase '+':\n\t\t\t// Strip off the leading \"+\"\n\t\t\tfrom++\n\n\t\tcase '-':\n\t\t\t// Skip past the leading \"-\"\n\t\t\tto++\n\t\t\tfrom++\n\t\t}\n\n\t\t// Strip off leading zeros\n\t\tfor from < len(result) && result[from] == '0' {\n\t\t\tfrom++\n\t\t}\n\n\t\tresult = append(result[:to], result[from:]...)\n\t}\n\n\tdot := bytes.IndexByte(result, '.')\n\n\tif dot == 1 && result[0] == '0' {\n\t\t// Simplify numbers starting with \"0.\"\n\t\tafterDot := 2\n\n\t\t// Strip off the leading zero when minifying\n\t\t// \"0.5\" => \".5\"\n\t\tif p.options.MinifyWhitespace {\n\t\t\tresult = result[1:]\n\t\t\tafterDot--\n\t\t}\n\n\t\t// Try using an exponent\n\t\t// \"0.001\" => \"1e-3\"\n\t\tif result[afterDot] == '0' {\n\t\t\ti := afterDot + 1\n\t\t\tfor result[i] == '0' {\n\t\t\t\ti++\n\t\t\t}\n\t\t\tremaining := result[i:]\n\t\t\texponent := p.smallIntToBytes(afterDot - i - len(remaining))\n\n\t\t\t// Only switch if it's actually shorter\n\t\t\tif len(result) > len(remaining)+1+len(exponent) {\n\t\t\t\tresult = append(append(remaining, 'e'), exponent...)\n\t\t\t}\n\t\t}\n\t} else if dot != -1 {\n\t\t// Try to get rid of a \".\" and maybe also an \"e\"\n\t\tif e := bytes.LastIndexByte(result, 'e'); e != -1 {\n\t\t\tinteger := result[:dot]\n\t\t\tfraction := result[dot+1 : e]\n\t\t\texponent := parseSmallInt(result[e+1:]) - len(fraction)\n\n\t\t\t// Handle small exponents by appending zeros instead\n\t\t\tif exponent >= 0 && exponent <= 2 {\n\t\t\t\t// \"1.2e1\" => \"12\"\n\t\t\t\t// \"1.2e2\" => \"120\"\n\t\t\t\t// \"1.2e3\" => \"1200\"\n\t\t\t\tif len(result) >= len(integer)+len(fraction)+exponent {\n\t\t\t\t\tresult = append(integer, fraction...)\n\t\t\t\t\tfor i := 0; i < exponent; i++ {\n\t\t\t\t\t\tresult = append(result, '0')\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// \"1.2e4\" => \"12e3\"\n\t\t\t\texponent := p.smallIntToBytes(exponent)\n\t\t\t\tif len(result) >= len(integer)+len(fraction)+1+len(exponent) {\n\t\t\t\t\tresult = append(append(append(integer, fraction...), 'e'), exponent...)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if result[len(result)-1] == '0' {\n\t\t// Simplify numbers ending with \"0\" by trying to use an exponent\n\t\t// \"1000\" => \"1e3\"\n\t\ti := len(result) - 1\n\t\tfor i > 0 && result[i-1] == '0' {\n\t\t\ti--\n\t\t}\n\t\tremaining := result[:i]\n\t\texponent := p.smallIntToBytes(len(result) - i)\n\n\t\t// Only switch if it's actually shorter\n\t\tif len(result) > len(remaining)+1+len(exponent) {\n\t\t\tresult = append(append(remaining, 'e'), exponent...)\n\t\t}\n\t}\n\n\t// Numbers in this range can potentially be printed with one fewer byte as\n\t// hex. This compares against 0xFFFF_FFFF_FFFF_F800 instead of comparing\n\t// against 0xFFFF_FFFF_FFFF_FFFF because 0xFFFF_FFFF_FFFF_FFFF when converted\n\t// to float64 rounds up to 0x1_0000_0000_0000_0180, which can no longer fit\n\t// into uint64. In Go, the result of converting float64 to uint64 outside of\n\t// the uint64 range is implementation-dependent and is different on amd64 vs.\n\t// arm64. The float64 value 0xFFFF_FFFF_FFFF_F800 is the biggest value that\n\t// is below the float64 value 0x1_0000_0000_0000_0180, so we use that instead.\n\tif p.options.MinifyWhitespace && absValue >= 1_000_000_000_000 && absValue <= 0xFFFF_FFFF_FFFF_F800 {\n\t\tif asInt := uint64(absValue); absValue == float64(asInt) {\n\t\t\tif hex := strconv.FormatUint(asInt, 16); 2+len(hex) < len(result) {\n\t\t\t\tresult = append(append(result[:0], '0', 'x'), hex...)\n\t\t\t}\n\t\t}\n\t}\n\n\tp.printBytes(result)\n\n\t// We'll need a space before \".\" if it could be parsed as a decimal point\n\tif !bytes.ContainsAny(result, \".ex\") {\n\t\tp.needSpaceBeforeDot = len(p.js)\n\t}\n}\n\nfunc (p *printer) printDeclStmt(isExport bool, keyword string, decls []js_ast.Decl) {\n\tp.printIndent()\n\tp.printSpaceBeforeIdentifier()\n\tif isExport {\n\t\tp.print(\"export \")\n\t}\n\tp.printDecls(keyword, decls, 0)\n\tp.printSemicolonAfterStatement()\n}\n\nfunc (p *printer) printForLoopInit(init js_ast.Stmt, flags printExprFlags) {\n\tswitch s := init.Data.(type) {\n\tcase *js_ast.SExpr:\n\t\tp.printExpr(s.Value, js_ast.LLowest, flags|exprResultIsUnused)\n\tcase *js_ast.SLocal:\n\t\tswitch s.Kind {\n\t\tcase js_ast.LocalAwaitUsing:\n\t\t\tp.printDecls(\"await using\", s.Decls, flags)\n\t\tcase js_ast.LocalConst:\n\t\t\tp.printDecls(\"const\", s.Decls, flags)\n\t\tcase js_ast.LocalLet:\n\t\t\tp.printDecls(\"let\", s.Decls, flags)\n\t\tcase js_ast.LocalUsing:\n\t\t\tp.printDecls(\"using\", s.Decls, flags)\n\t\tcase js_ast.LocalVar:\n\t\t\tp.printDecls(\"var\", s.Decls, flags)\n\t\t}\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\nfunc (p *printer) printDecls(keyword string, decls []js_ast.Decl, flags printExprFlags) {\n\tp.print(keyword)\n\tp.printSpace()\n\n\tfor i, decl := range decls {\n\t\tif i != 0 {\n\t\t\tp.print(\",\")\n\t\t\tif p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit() {\n\t\t\t\tp.printSpace()\n\t\t\t}\n\t\t}\n\t\tp.printBinding(decl.Binding)\n\n\t\tif decl.ValueOrNil.Data != nil {\n\t\t\tp.printSpace()\n\t\t\tp.print(\"=\")\n\t\t\tp.printSpace()\n\t\t\tp.printExprWithoutLeadingNewline(decl.ValueOrNil, js_ast.LComma, flags)\n\t\t}\n\t}\n}\n\nfunc (p *printer) printBody(body js_ast.Stmt, isSingleLine bool) {\n\tif block, ok := body.Data.(*js_ast.SBlock); ok {\n\t\tp.printSpace()\n\t\tp.printBlock(body.Loc, *block)\n\t\tp.printNewline()\n\t} else if isSingleLine {\n\t\tp.printNextIndentAsSpace = true\n\t\tp.printStmt(body, 0)\n\t} else {\n\t\tp.printNewline()\n\t\tp.options.Indent++\n\t\tp.printStmt(body, 0)\n\t\tp.options.Indent--\n\t}\n}\n\nfunc (p *printer) printBlock(loc logger.Loc, block js_ast.SBlock) {\n\tp.addSourceMapping(loc)\n\tp.print(\"{\")\n\tp.printNewline()\n\n\tp.options.Indent++\n\tfor _, stmt := range block.Stmts {\n\t\tp.printSemicolonIfNeeded()\n\t\tp.printStmt(stmt, canOmitStatement)\n\t}\n\tp.options.Indent--\n\tp.needsSemicolon = false\n\n\tp.printIndent()\n\tif block.CloseBraceLoc.Start > loc.Start {\n\t\tp.addSourceMapping(block.CloseBraceLoc)\n\t}\n\tp.print(\"}\")\n}\n\nfunc wrapToAvoidAmbiguousElse(s js_ast.S) bool {\n\tfor {\n\t\tswitch current := s.(type) {\n\t\tcase *js_ast.SIf:\n\t\t\tif current.NoOrNil.Data == nil {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\ts = current.NoOrNil.Data\n\n\t\tcase *js_ast.SFor:\n\t\t\ts = current.Body.Data\n\n\t\tcase *js_ast.SForIn:\n\t\t\ts = current.Body.Data\n\n\t\tcase *js_ast.SForOf:\n\t\t\ts = current.Body.Data\n\n\t\tcase *js_ast.SWhile:\n\t\t\ts = current.Body.Data\n\n\t\tcase *js_ast.SWith:\n\t\t\ts = current.Body.Data\n\n\t\tcase *js_ast.SLabel:\n\t\t\ts = current.Stmt.Data\n\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\t}\n}\n\nfunc (p *printer) printIf(s *js_ast.SIf) {\n\tp.printSpaceBeforeIdentifier()\n\tp.print(\"if\")\n\tp.printSpace()\n\tp.print(\"(\")\n\tif p.willPrintExprCommentsAtLoc(s.Test.Loc) {\n\t\tp.printNewline()\n\t\tp.options.Indent++\n\t\tp.printIndent()\n\t\tp.printExpr(s.Test, js_ast.LLowest, 0)\n\t\tp.printNewline()\n\t\tp.options.Indent--\n\t\tp.printIndent()\n\t} else {\n\t\tp.printExpr(s.Test, js_ast.LLowest, 0)\n\t}\n\tp.print(\")\")\n\n\t// Simplify the else branch, which may disappear entirely\n\tno := s.NoOrNil\n\tif expr, ok := no.Data.(*js_ast.SExpr); ok {\n\t\tif value := p.simplifyUnusedExpr(expr.Value); value.Data == nil {\n\t\t\tno.Data = nil\n\t\t} else if value.Data != expr.Value.Data {\n\t\t\tno.Data = &js_ast.SExpr{Value: value}\n\t\t}\n\t}\n\n\tif yes, ok := s.Yes.Data.(*js_ast.SBlock); ok {\n\t\tp.printSpace()\n\t\tp.printBlock(s.Yes.Loc, *yes)\n\n\t\tif no.Data != nil {\n\t\t\tp.printSpace()\n\t\t} else {\n\t\t\tp.printNewline()\n\t\t}\n\t} else if wrapToAvoidAmbiguousElse(s.Yes.Data) {\n\t\tp.printSpace()\n\t\tp.print(\"{\")\n\t\tp.printNewline()\n\n\t\tp.options.Indent++\n\t\tp.printStmt(s.Yes, canOmitStatement)\n\t\tp.options.Indent--\n\t\tp.needsSemicolon = false\n\n\t\tp.printIndent()\n\t\tp.print(\"}\")\n\n\t\tif no.Data != nil {\n\t\t\tp.printSpace()\n\t\t} else {\n\t\t\tp.printNewline()\n\t\t}\n\t} else {\n\t\tp.printBody(s.Yes, s.IsSingleLineYes)\n\n\t\tif no.Data != nil {\n\t\t\tp.printIndent()\n\t\t}\n\t}\n\n\tif no.Data != nil {\n\t\tp.printSemicolonIfNeeded()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"else\")\n\n\t\tif block, ok := no.Data.(*js_ast.SBlock); ok {\n\t\t\tp.printSpace()\n\t\t\tp.printBlock(no.Loc, *block)\n\t\t\tp.printNewline()\n\t\t} else if ifStmt, ok := no.Data.(*js_ast.SIf); ok {\n\t\t\tp.printIf(ifStmt)\n\t\t} else {\n\t\t\tp.printBody(no, s.IsSingleLineNo)\n\t\t}\n\t}\n}\n\nfunc (p *printer) printIndentedComment(text string) {\n\t// Avoid generating a comment containing the character sequence \"</script\"\n\tif !p.options.UnsupportedFeatures.Has(compat.InlineScript) {\n\t\ttext = helpers.EscapeClosingTag(text, \"/script\")\n\t}\n\n\tif strings.HasPrefix(text, \"/*\") {\n\t\t// Re-indent multi-line comments\n\t\tfor {\n\t\t\tnewline := strings.IndexByte(text, '\\n')\n\t\t\tif newline == -1 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.print(text[:newline+1])\n\t\t\tp.printIndent()\n\t\t\ttext = text[newline+1:]\n\t\t}\n\t\tp.print(text)\n\t\tp.printNewline()\n\t} else {\n\t\t// Print a mandatory newline after single-line comments\n\t\tp.print(text)\n\t\tp.print(\"\\n\")\n\t}\n}\n\nfunc (p *printer) printPath(importRecordIndex uint32, importKind ast.ImportKind) {\n\trecord := p.importRecords[importRecordIndex]\n\tp.addSourceMapping(record.Range.Loc)\n\tp.printQuotedUTF8(record.Path.Text, printQuotedNoWrap)\n\n\tif p.options.NeedsMetafile {\n\t\texternal := \"\"\n\t\tif (record.Flags & ast.ShouldNotBeExternalInMetafile) == 0 {\n\t\t\texternal = p.options.MetafileFormat.MaybeRemoveWhitespace(\",\\n          \\\"external\\\": true\")\n\t\t}\n\t\tp.jsonMetadataImports = append(p.jsonMetadataImports, fmt.Sprintf(\n\t\t\tp.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n        {\\n          \\\"path\\\": %s,\\n          \\\"kind\\\": %s%s\\n        }\"),\n\t\t\thelpers.QuoteForJSON(record.Path.Text, p.options.ASCIIOnly),\n\t\t\thelpers.QuoteForJSON(importKind.StringForMetafile(), p.options.ASCIIOnly),\n\t\t\texternal))\n\t}\n\n\tif record.AssertOrWith != nil && importKind == ast.ImportStmt {\n\t\tfeature := compat.ImportAttributes\n\t\tif record.AssertOrWith.Keyword == ast.AssertKeyword {\n\t\t\tfeature = compat.ImportAssertions\n\t\t}\n\n\t\t// Omit import assertions/attributes on this import statement if they would cause a syntax error\n\t\tif p.options.UnsupportedFeatures.Has(feature) {\n\t\t\treturn\n\t\t}\n\n\t\tp.printSpace()\n\t\tp.addSourceMapping(record.AssertOrWith.KeywordLoc)\n\t\tp.print(record.AssertOrWith.Keyword.String())\n\t\tp.printSpace()\n\t\tp.printImportAssertOrWithClause(*record.AssertOrWith)\n\t}\n}\n\nfunc (p *printer) printImportCallAssertOrWith(assertOrWith *ast.ImportAssertOrWith, outerIsMultiLine bool) {\n\t// Omit import assertions/attributes if we know the \"import()\" syntax doesn't\n\t// support a second argument (i.e. both import assertions and import\n\t// attributes aren't supported) and doing so would cause a syntax error\n\tif assertOrWith == nil || (p.options.UnsupportedFeatures.Has(compat.ImportAssertions) && p.options.UnsupportedFeatures.Has(compat.ImportAttributes)) {\n\t\treturn\n\t}\n\n\tisMultiLine := p.willPrintExprCommentsAtLoc(assertOrWith.KeywordLoc) ||\n\t\tp.willPrintExprCommentsAtLoc(assertOrWith.InnerOpenBraceLoc) ||\n\t\tp.willPrintExprCommentsAtLoc(assertOrWith.OuterCloseBraceLoc)\n\n\tp.print(\",\")\n\tif outerIsMultiLine {\n\t\tp.printNewline()\n\t\tp.printIndent()\n\t} else {\n\t\tp.printSpace()\n\t}\n\tp.printExprCommentsAtLoc(assertOrWith.OuterOpenBraceLoc)\n\tp.addSourceMapping(assertOrWith.OuterOpenBraceLoc)\n\tp.print(\"{\")\n\n\tif isMultiLine {\n\t\tp.printNewline()\n\t\tp.options.Indent++\n\t\tp.printIndent()\n\t} else {\n\t\tp.printSpace()\n\t}\n\n\tp.printExprCommentsAtLoc(assertOrWith.KeywordLoc)\n\tp.addSourceMapping(assertOrWith.KeywordLoc)\n\tp.print(assertOrWith.Keyword.String())\n\tp.print(\":\")\n\n\tif p.willPrintExprCommentsAtLoc(assertOrWith.InnerOpenBraceLoc) {\n\t\tp.printNewline()\n\t\tp.options.Indent++\n\t\tp.printIndent()\n\t\tp.printExprCommentsAtLoc(assertOrWith.InnerOpenBraceLoc)\n\t\tp.printImportAssertOrWithClause(*assertOrWith)\n\t\tp.options.Indent--\n\t} else {\n\t\tp.printSpace()\n\t\tp.printImportAssertOrWithClause(*assertOrWith)\n\t}\n\n\tif isMultiLine {\n\t\tp.printNewline()\n\t\tp.printExprCommentsAfterCloseTokenAtLoc(assertOrWith.OuterCloseBraceLoc)\n\t\tp.options.Indent--\n\t\tp.printIndent()\n\t} else {\n\t\tp.printSpace()\n\t}\n\n\tp.addSourceMapping(assertOrWith.OuterCloseBraceLoc)\n\tp.print(\"}\")\n}\n\nfunc (p *printer) printImportAssertOrWithClause(assertOrWith ast.ImportAssertOrWith) {\n\tisMultiLine := p.willPrintExprCommentsAtLoc(assertOrWith.InnerCloseBraceLoc)\n\tif !isMultiLine {\n\t\tfor _, entry := range assertOrWith.Entries {\n\t\t\tif p.willPrintExprCommentsAtLoc(entry.KeyLoc) || p.willPrintExprCommentsAtLoc(entry.ValueLoc) {\n\t\t\t\tisMultiLine = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tp.addSourceMapping(assertOrWith.InnerOpenBraceLoc)\n\tp.print(\"{\")\n\tif isMultiLine {\n\t\tp.options.Indent++\n\t}\n\n\tfor i, entry := range assertOrWith.Entries {\n\t\tif i > 0 {\n\t\t\tp.print(\",\")\n\t\t}\n\t\tif isMultiLine {\n\t\t\tp.printNewline()\n\t\t\tp.printIndent()\n\t\t} else {\n\t\t\tp.printSpace()\n\t\t}\n\n\t\tp.printExprCommentsAtLoc(entry.KeyLoc)\n\t\tp.addSourceMapping(entry.KeyLoc)\n\t\tif !entry.PreferQuotedKey && p.canPrintIdentifierUTF16(entry.Key) {\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tp.printIdentifierUTF16(entry.Key)\n\t\t} else {\n\t\t\tp.printQuotedUTF16(entry.Key, 0)\n\t\t}\n\n\t\tp.print(\":\")\n\n\t\tif p.willPrintExprCommentsAtLoc(entry.ValueLoc) {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent++\n\t\t\tp.printIndent()\n\t\t\tp.printExprCommentsAtLoc(entry.ValueLoc)\n\t\t\tp.addSourceMapping(entry.ValueLoc)\n\t\t\tp.printQuotedUTF16(entry.Value, 0)\n\t\t\tp.options.Indent--\n\t\t} else {\n\t\t\tp.printSpace()\n\t\t\tp.addSourceMapping(entry.ValueLoc)\n\t\t\tp.printQuotedUTF16(entry.Value, 0)\n\t\t}\n\t}\n\n\tif isMultiLine {\n\t\tp.printNewline()\n\t\tp.printExprCommentsAfterCloseTokenAtLoc(assertOrWith.InnerCloseBraceLoc)\n\t\tp.options.Indent--\n\t\tp.printIndent()\n\t} else if len(assertOrWith.Entries) > 0 {\n\t\tp.printSpace()\n\t}\n\n\tp.addSourceMapping(assertOrWith.InnerCloseBraceLoc)\n\tp.print(\"}\")\n}\n\ntype printStmtFlags uint8\n\nconst (\n\tcanOmitStatement printStmtFlags = 1 << iota\n)\n\nfunc (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) {\n\tif p.options.LineLimit > 0 {\n\t\tp.printNewlinePastLineLimit()\n\t}\n\n\tswitch s := stmt.Data.(type) {\n\tcase *js_ast.SComment:\n\t\ttext := s.Text\n\n\t\tif s.IsLegalComment {\n\t\t\tswitch p.options.LegalComments {\n\t\t\tcase config.LegalCommentsNone:\n\t\t\t\treturn\n\n\t\t\tcase config.LegalCommentsEndOfFile,\n\t\t\t\tconfig.LegalCommentsLinkedWithComment,\n\t\t\t\tconfig.LegalCommentsExternalWithoutComment:\n\n\t\t\t\t// Don't record the same legal comment more than once per file\n\t\t\t\tif p.hasLegalComment == nil {\n\t\t\t\t\tp.hasLegalComment = make(map[string]struct{})\n\t\t\t\t} else if _, ok := p.hasLegalComment[text]; ok {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tp.hasLegalComment[text] = struct{}{}\n\t\t\t\tp.extractedLegalComments = append(p.extractedLegalComments, text)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tp.printIndent()\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndentedComment(text)\n\n\tcase *js_ast.SFunction:\n\t\tif !p.options.MinifyWhitespace && s.Fn.HasNoSideEffectsComment {\n\t\t\tp.printIndent()\n\t\t\tp.print(\"// @__NO_SIDE_EFFECTS__\\n\")\n\t\t}\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tif s.IsExport {\n\t\t\tp.print(\"export \")\n\t\t}\n\t\tif s.Fn.IsAsync {\n\t\t\tp.print(\"async \")\n\t\t}\n\t\tp.print(\"function\")\n\t\tif s.Fn.IsGenerator {\n\t\t\tp.print(\"*\")\n\t\t\tp.printSpace()\n\t\t}\n\t\tp.printSpaceBeforeIdentifier()\n\t\tname := p.renamer.NameForSymbol(s.Fn.Name.Ref)\n\t\tp.addSourceMappingForName(s.Fn.Name.Loc, name, s.Fn.Name.Ref)\n\t\tp.printIdentifier(name)\n\t\tp.printFn(s.Fn)\n\t\tp.printNewline()\n\n\tcase *js_ast.SClass:\n\t\tomitIndent := p.printDecorators(s.Class.Decorators, printNewlineAfterDecorator)\n\t\tif !omitIndent {\n\t\t\tp.printIndent()\n\t\t}\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tif s.IsExport {\n\t\t\tp.print(\"export \")\n\t\t}\n\t\tp.print(\"class \")\n\t\tname := p.renamer.NameForSymbol(s.Class.Name.Ref)\n\t\tp.addSourceMappingForName(s.Class.Name.Loc, name, s.Class.Name.Ref)\n\t\tp.printIdentifier(name)\n\t\tp.printClass(s.Class)\n\t\tp.printNewline()\n\n\tcase *js_ast.SEmpty:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.print(\";\")\n\t\tp.printNewline()\n\n\tcase *js_ast.SExportDefault:\n\t\tif !p.options.MinifyWhitespace {\n\t\t\tif s2, ok := s.Value.Data.(*js_ast.SFunction); ok && s2.Fn.HasNoSideEffectsComment {\n\t\t\t\tp.printIndent()\n\t\t\t\tp.print(\"// @__NO_SIDE_EFFECTS__\\n\")\n\t\t\t}\n\t\t}\n\t\tomitIndent := false\n\t\tif s2, ok := s.Value.Data.(*js_ast.SClass); ok {\n\t\t\tomitIndent = p.printDecorators(s2.Class.Decorators, printNewlineAfterDecorator)\n\t\t}\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tif !omitIndent {\n\t\t\tp.printIndent()\n\t\t}\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"export default\")\n\t\tp.printSpace()\n\n\t\tswitch s2 := s.Value.Data.(type) {\n\t\tcase *js_ast.SExpr:\n\t\t\t// Functions and classes must be wrapped to avoid confusion with their statement forms\n\t\t\tp.exportDefaultStart = len(p.js)\n\n\t\t\tp.printExprWithoutLeadingNewline(s2.Value, js_ast.LComma, 0)\n\t\t\tp.printSemicolonAfterStatement()\n\t\t\treturn\n\n\t\tcase *js_ast.SFunction:\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tif s2.Fn.IsAsync {\n\t\t\t\tp.print(\"async \")\n\t\t\t}\n\t\t\tp.print(\"function\")\n\t\t\tif s2.Fn.IsGenerator {\n\t\t\t\tp.print(\"*\")\n\t\t\t\tp.printSpace()\n\t\t\t}\n\t\t\tif s2.Fn.Name != nil {\n\t\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\t\tname := p.renamer.NameForSymbol(s2.Fn.Name.Ref)\n\t\t\t\tp.addSourceMappingForName(s2.Fn.Name.Loc, name, s2.Fn.Name.Ref)\n\t\t\t\tp.printIdentifier(name)\n\t\t\t}\n\t\t\tp.printFn(s2.Fn)\n\t\t\tp.printNewline()\n\n\t\tcase *js_ast.SClass:\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tp.print(\"class\")\n\t\t\tif s2.Class.Name != nil {\n\t\t\t\tp.print(\" \")\n\t\t\t\tname := p.renamer.NameForSymbol(s2.Class.Name.Ref)\n\t\t\t\tp.addSourceMappingForName(s2.Class.Name.Loc, name, s2.Class.Name.Ref)\n\t\t\t\tp.printIdentifier(name)\n\t\t\t}\n\t\t\tp.printClass(s2.Class)\n\t\t\tp.printNewline()\n\n\t\tdefault:\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\n\tcase *js_ast.SExportStar:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"export\")\n\t\tp.printSpace()\n\t\tp.print(\"*\")\n\t\tp.printSpace()\n\t\tif s.Alias != nil {\n\t\t\tp.print(\"as\")\n\t\t\tp.printSpace()\n\t\t\tp.printClauseAlias(s.Alias.Loc, s.Alias.OriginalName)\n\t\t\tp.printSpace()\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t}\n\t\tp.print(\"from\")\n\t\tp.printSpace()\n\t\tp.printPath(s.ImportRecordIndex, ast.ImportStmt)\n\t\tp.printSemicolonAfterStatement()\n\n\tcase *js_ast.SExportClause:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"export\")\n\t\tp.printSpace()\n\t\tp.print(\"{\")\n\n\t\tif !s.IsSingleLine {\n\t\t\tp.options.Indent++\n\t\t}\n\n\t\tfor i, item := range s.Items {\n\t\t\tif i != 0 {\n\t\t\t\tp.print(\",\")\n\t\t\t}\n\n\t\t\tif p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit() {\n\t\t\t\tif s.IsSingleLine {\n\t\t\t\t\tp.printSpace()\n\t\t\t\t} else {\n\t\t\t\t\tp.printNewline()\n\t\t\t\t\tp.printIndent()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tname := p.renamer.NameForSymbol(item.Name.Ref)\n\t\t\tp.addSourceMappingForName(item.Name.Loc, name, item.Name.Ref)\n\t\t\tp.printIdentifier(name)\n\t\t\tif name != item.Alias {\n\t\t\t\tp.print(\" as\")\n\t\t\t\tp.printSpace()\n\t\t\t\tp.printClauseAlias(item.AliasLoc, item.Alias)\n\t\t\t}\n\t\t}\n\n\t\tif !s.IsSingleLine {\n\t\t\tp.options.Indent--\n\t\t\tp.printNewline()\n\t\t\tp.printIndent()\n\t\t} else if len(s.Items) > 0 {\n\t\t\tp.printSpace()\n\t\t}\n\n\t\tp.print(\"}\")\n\t\tp.printSemicolonAfterStatement()\n\n\tcase *js_ast.SExportFrom:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"export\")\n\t\tp.printSpace()\n\t\tp.print(\"{\")\n\n\t\tif !s.IsSingleLine {\n\t\t\tp.options.Indent++\n\t\t}\n\n\t\tfor i, item := range s.Items {\n\t\t\tif i != 0 {\n\t\t\t\tp.print(\",\")\n\t\t\t}\n\n\t\t\tif p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit() {\n\t\t\t\tif s.IsSingleLine {\n\t\t\t\t\tp.printSpace()\n\t\t\t\t} else {\n\t\t\t\t\tp.printNewline()\n\t\t\t\t\tp.printIndent()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.printClauseAlias(item.Name.Loc, item.OriginalName)\n\t\t\tif item.OriginalName != item.Alias {\n\t\t\t\tp.printSpace()\n\t\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\t\tp.print(\"as\")\n\t\t\t\tp.printSpace()\n\t\t\t\tp.printClauseAlias(item.AliasLoc, item.Alias)\n\t\t\t}\n\t\t}\n\n\t\tif !s.IsSingleLine {\n\t\t\tp.options.Indent--\n\t\t\tp.printNewline()\n\t\t\tp.printIndent()\n\t\t} else if len(s.Items) > 0 {\n\t\t\tp.printSpace()\n\t\t}\n\n\t\tp.print(\"}\")\n\t\tp.printSpace()\n\t\tp.print(\"from\")\n\t\tp.printSpace()\n\t\tp.printPath(s.ImportRecordIndex, ast.ImportStmt)\n\t\tp.printSemicolonAfterStatement()\n\n\tcase *js_ast.SLocal:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tswitch s.Kind {\n\t\tcase js_ast.LocalAwaitUsing:\n\t\t\tp.printDeclStmt(s.IsExport, \"await using\", s.Decls)\n\t\tcase js_ast.LocalConst:\n\t\t\tp.printDeclStmt(s.IsExport, \"const\", s.Decls)\n\t\tcase js_ast.LocalLet:\n\t\t\tp.printDeclStmt(s.IsExport, \"let\", s.Decls)\n\t\tcase js_ast.LocalUsing:\n\t\t\tp.printDeclStmt(s.IsExport, \"using\", s.Decls)\n\t\tcase js_ast.LocalVar:\n\t\t\tp.printDeclStmt(s.IsExport, \"var\", s.Decls)\n\t\t}\n\n\tcase *js_ast.SIf:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printIf(s)\n\n\tcase *js_ast.SDoWhile:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"do\")\n\t\tif block, ok := s.Body.Data.(*js_ast.SBlock); ok {\n\t\t\tp.printSpace()\n\t\t\tp.printBlock(s.Body.Loc, *block)\n\t\t\tp.printSpace()\n\t\t} else {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent++\n\t\t\tp.printStmt(s.Body, 0)\n\t\t\tp.printSemicolonIfNeeded()\n\t\t\tp.options.Indent--\n\t\t\tp.printIndent()\n\t\t}\n\t\tp.print(\"while\")\n\t\tp.printSpace()\n\t\tp.print(\"(\")\n\t\tif p.willPrintExprCommentsAtLoc(s.Test.Loc) {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent++\n\t\t\tp.printIndent()\n\t\t\tp.printExpr(s.Test, js_ast.LLowest, 0)\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent--\n\t\t\tp.printIndent()\n\t\t} else {\n\t\t\tp.printExpr(s.Test, js_ast.LLowest, 0)\n\t\t}\n\t\tp.print(\")\")\n\t\tp.printSemicolonAfterStatement()\n\n\tcase *js_ast.SForIn:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"for\")\n\t\tp.printSpace()\n\t\tp.print(\"(\")\n\t\thasInitComment := p.willPrintExprCommentsAtLoc(s.Init.Loc)\n\t\thasValueComment := p.willPrintExprCommentsAtLoc(s.Value.Loc)\n\t\tif hasInitComment || hasValueComment {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent++\n\t\t\tp.printIndent()\n\t\t}\n\t\tp.printForLoopInit(s.Init, forbidIn)\n\t\tp.printSpace()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"in\")\n\t\tif hasValueComment {\n\t\t\tp.printNewline()\n\t\t\tp.printIndent()\n\t\t} else {\n\t\t\tp.printSpace()\n\t\t}\n\t\tp.printExpr(s.Value, js_ast.LLowest, 0)\n\t\tif hasInitComment || hasValueComment {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent--\n\t\t\tp.printIndent()\n\t\t}\n\t\tp.print(\")\")\n\t\tp.printBody(s.Body, s.IsSingleLineBody)\n\n\tcase *js_ast.SForOf:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"for\")\n\t\tif s.Await.Len > 0 {\n\t\t\tp.print(\" await\")\n\t\t}\n\t\tp.printSpace()\n\t\tp.print(\"(\")\n\t\thasInitComment := p.willPrintExprCommentsAtLoc(s.Init.Loc)\n\t\thasValueComment := p.willPrintExprCommentsAtLoc(s.Value.Loc)\n\t\tflags := forbidIn | isFollowedByOf\n\t\tif s.Await.Len > 0 {\n\t\t\tflags |= isInsideForAwait\n\t\t}\n\t\tif hasInitComment || hasValueComment {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent++\n\t\t\tp.printIndent()\n\t\t}\n\t\tp.forOfInitStart = len(p.js)\n\t\tp.printForLoopInit(s.Init, flags)\n\t\tp.printSpace()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"of\")\n\t\tif hasValueComment {\n\t\t\tp.printNewline()\n\t\t\tp.printIndent()\n\t\t} else {\n\t\t\tp.printSpace()\n\t\t}\n\t\tp.printExpr(s.Value, js_ast.LComma, 0)\n\t\tif hasInitComment || hasValueComment {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent--\n\t\t\tp.printIndent()\n\t\t}\n\t\tp.print(\")\")\n\t\tp.printBody(s.Body, s.IsSingleLineBody)\n\n\tcase *js_ast.SWhile:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"while\")\n\t\tp.printSpace()\n\t\tp.print(\"(\")\n\t\tif p.willPrintExprCommentsAtLoc(s.Test.Loc) {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent++\n\t\t\tp.printIndent()\n\t\t\tp.printExpr(s.Test, js_ast.LLowest, 0)\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent--\n\t\t\tp.printIndent()\n\t\t} else {\n\t\t\tp.printExpr(s.Test, js_ast.LLowest, 0)\n\t\t}\n\t\tp.print(\")\")\n\t\tp.printBody(s.Body, s.IsSingleLineBody)\n\n\tcase *js_ast.SWith:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"with\")\n\t\tp.printSpace()\n\t\tp.print(\"(\")\n\t\tif p.willPrintExprCommentsAtLoc(s.Value.Loc) {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent++\n\t\t\tp.printIndent()\n\t\t\tp.printExpr(s.Value, js_ast.LLowest, 0)\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent--\n\t\t\tp.printIndent()\n\t\t} else {\n\t\t\tp.printExpr(s.Value, js_ast.LLowest, 0)\n\t\t}\n\t\tp.print(\")\")\n\t\tp.withNesting++\n\t\tp.printBody(s.Body, s.IsSingleLineBody)\n\t\tp.withNesting--\n\n\tcase *js_ast.SLabel:\n\t\t// Avoid printing a source mapping that masks the one from the label\n\t\tif !p.options.MinifyWhitespace && (p.options.Indent > 0 || p.printNextIndentAsSpace) {\n\t\t\tp.addSourceMapping(stmt.Loc)\n\t\t\tp.printIndent()\n\t\t}\n\n\t\tp.printSpaceBeforeIdentifier()\n\t\tname := p.renamer.NameForSymbol(s.Name.Ref)\n\t\tp.addSourceMappingForName(s.Name.Loc, name, s.Name.Ref)\n\t\tp.printIdentifier(name)\n\t\tp.print(\":\")\n\t\tp.printBody(s.Stmt, s.IsSingleLineStmt)\n\n\tcase *js_ast.STry:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"try\")\n\t\tp.printSpace()\n\t\tp.printBlock(s.BlockLoc, s.Block)\n\n\t\tif s.Catch != nil {\n\t\t\tp.printSpace()\n\t\t\tp.print(\"catch\")\n\t\t\tif s.Catch.BindingOrNil.Data != nil {\n\t\t\t\tp.printSpace()\n\t\t\t\tp.print(\"(\")\n\t\t\t\tp.printBinding(s.Catch.BindingOrNil)\n\t\t\t\tp.print(\")\")\n\t\t\t}\n\t\t\tp.printSpace()\n\t\t\tp.printBlock(s.Catch.BlockLoc, s.Catch.Block)\n\t\t}\n\n\t\tif s.Finally != nil {\n\t\t\tp.printSpace()\n\t\t\tp.print(\"finally\")\n\t\t\tp.printSpace()\n\t\t\tp.printBlock(s.Finally.Loc, s.Finally.Block)\n\t\t}\n\n\t\tp.printNewline()\n\n\tcase *js_ast.SFor:\n\t\tinit := s.InitOrNil\n\t\tupdate := s.UpdateOrNil\n\n\t\t// Omit calls to empty functions from the output completely\n\t\tif p.options.MinifySyntax {\n\t\t\tif expr, ok := init.Data.(*js_ast.SExpr); ok {\n\t\t\t\tif value := p.simplifyUnusedExpr(expr.Value); value.Data == nil {\n\t\t\t\t\tinit.Data = nil\n\t\t\t\t} else if value.Data != expr.Value.Data {\n\t\t\t\t\tinit.Data = &js_ast.SExpr{Value: value}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif update.Data != nil {\n\t\t\t\tupdate = p.simplifyUnusedExpr(update)\n\t\t\t}\n\t\t}\n\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"for\")\n\t\tp.printSpace()\n\t\tp.print(\"(\")\n\t\tisMultiLine :=\n\t\t\t(init.Data != nil && p.willPrintExprCommentsAtLoc(init.Loc)) ||\n\t\t\t\t(s.TestOrNil.Data != nil && p.willPrintExprCommentsAtLoc(s.TestOrNil.Loc)) ||\n\t\t\t\t(update.Data != nil && p.willPrintExprCommentsAtLoc(update.Loc))\n\t\tif isMultiLine {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent++\n\t\t\tp.printIndent()\n\t\t}\n\t\tif init.Data != nil {\n\t\t\tp.printForLoopInit(init, forbidIn)\n\t\t}\n\t\tp.print(\";\")\n\t\tif isMultiLine {\n\t\t\tp.printNewline()\n\t\t\tp.printIndent()\n\t\t} else {\n\t\t\tp.printSpace()\n\t\t}\n\t\tif s.TestOrNil.Data != nil {\n\t\t\tp.printExpr(s.TestOrNil, js_ast.LLowest, 0)\n\t\t}\n\t\tp.print(\";\")\n\t\tif !isMultiLine {\n\t\t\tp.printSpace()\n\t\t} else if update.Data != nil {\n\t\t\tp.printNewline()\n\t\t\tp.printIndent()\n\t\t}\n\t\tif update.Data != nil {\n\t\t\tp.printExpr(update, js_ast.LLowest, exprResultIsUnused)\n\t\t}\n\t\tif isMultiLine {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent--\n\t\t\tp.printIndent()\n\t\t}\n\t\tp.print(\")\")\n\t\tp.printBody(s.Body, s.IsSingleLineBody)\n\n\tcase *js_ast.SSwitch:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"switch\")\n\t\tp.printSpace()\n\t\tp.print(\"(\")\n\t\tif p.willPrintExprCommentsAtLoc(s.Test.Loc) {\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent++\n\t\t\tp.printIndent()\n\t\t\tp.printExpr(s.Test, js_ast.LLowest, 0)\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent--\n\t\t\tp.printIndent()\n\t\t} else {\n\t\t\tp.printExpr(s.Test, js_ast.LLowest, 0)\n\t\t}\n\t\tp.print(\")\")\n\t\tp.printSpace()\n\t\tp.addSourceMapping(s.BodyLoc)\n\t\tp.print(\"{\")\n\t\tp.printNewline()\n\t\tp.options.Indent++\n\n\t\tfor _, c := range s.Cases {\n\t\t\tp.printSemicolonIfNeeded()\n\t\t\tp.printIndent()\n\t\t\tp.printExprCommentsAtLoc(c.Loc)\n\t\t\tp.addSourceMapping(c.Loc)\n\n\t\t\tif c.ValueOrNil.Data != nil {\n\t\t\t\tp.print(\"case\")\n\t\t\t\tp.printSpace()\n\t\t\t\tp.printExpr(c.ValueOrNil, js_ast.LLogicalAnd, 0)\n\t\t\t} else {\n\t\t\t\tp.print(\"default\")\n\t\t\t}\n\t\t\tp.print(\":\")\n\n\t\t\tif len(c.Body) == 1 {\n\t\t\t\tif block, ok := c.Body[0].Data.(*js_ast.SBlock); ok {\n\t\t\t\t\tp.printSpace()\n\t\t\t\t\tp.printBlock(c.Body[0].Loc, *block)\n\t\t\t\t\tp.printNewline()\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.printNewline()\n\t\t\tp.options.Indent++\n\t\t\tfor _, stmt := range c.Body {\n\t\t\t\tp.printSemicolonIfNeeded()\n\t\t\t\tp.printStmt(stmt, canOmitStatement)\n\t\t\t}\n\t\t\tp.options.Indent--\n\t\t}\n\n\t\tp.options.Indent--\n\t\tp.printIndent()\n\t\tp.addSourceMapping(s.CloseBraceLoc)\n\t\tp.print(\"}\")\n\t\tp.printNewline()\n\t\tp.needsSemicolon = false\n\n\tcase *js_ast.SImport:\n\t\titemCount := 0\n\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tswitch p.importRecords[s.ImportRecordIndex].Phase {\n\t\tcase ast.DeferPhase:\n\t\t\tp.print(\"import defer\")\n\t\tcase ast.SourcePhase:\n\t\t\tp.print(\"import source\")\n\t\tdefault:\n\t\t\tp.print(\"import\")\n\t\t}\n\t\tp.printSpace()\n\n\t\tif s.DefaultName != nil {\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tname := p.renamer.NameForSymbol(s.DefaultName.Ref)\n\t\t\tp.addSourceMappingForName(s.DefaultName.Loc, name, s.DefaultName.Ref)\n\t\t\tp.printIdentifier(name)\n\t\t\titemCount++\n\t\t}\n\n\t\tif s.Items != nil {\n\t\t\tif itemCount > 0 {\n\t\t\t\tp.print(\",\")\n\t\t\t\tp.printSpace()\n\t\t\t}\n\n\t\t\tp.print(\"{\")\n\t\t\tif !s.IsSingleLine {\n\t\t\t\tp.options.Indent++\n\t\t\t}\n\n\t\t\tfor i, item := range *s.Items {\n\t\t\t\tif i != 0 {\n\t\t\t\t\tp.print(\",\")\n\t\t\t\t}\n\n\t\t\t\tif p.options.LineLimit <= 0 || !p.printNewlinePastLineLimit() {\n\t\t\t\t\tif s.IsSingleLine {\n\t\t\t\t\t\tp.printSpace()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.printNewline()\n\t\t\t\t\t\tp.printIndent()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tp.printClauseAlias(item.AliasLoc, item.Alias)\n\n\t\t\t\tname := p.renamer.NameForSymbol(item.Name.Ref)\n\t\t\t\tif name != item.Alias {\n\t\t\t\t\tp.printSpace()\n\t\t\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\t\t\tp.print(\"as \")\n\t\t\t\t\tp.addSourceMappingForName(item.Name.Loc, name, item.Name.Ref)\n\t\t\t\t\tp.printIdentifier(name)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !s.IsSingleLine {\n\t\t\t\tp.options.Indent--\n\t\t\t\tp.printNewline()\n\t\t\t\tp.printIndent()\n\t\t\t} else if len(*s.Items) > 0 {\n\t\t\t\tp.printSpace()\n\t\t\t}\n\n\t\t\tp.print(\"}\")\n\t\t\titemCount++\n\t\t}\n\n\t\tif s.StarNameLoc != nil {\n\t\t\tif itemCount > 0 {\n\t\t\t\tp.print(\",\")\n\t\t\t\tp.printSpace()\n\t\t\t}\n\n\t\t\tp.print(\"*\")\n\t\t\tp.printSpace()\n\t\t\tp.print(\"as \")\n\t\t\tname := p.renamer.NameForSymbol(s.NamespaceRef)\n\t\t\tp.addSourceMappingForName(*s.StarNameLoc, name, s.NamespaceRef)\n\t\t\tp.printIdentifier(name)\n\t\t\titemCount++\n\t\t}\n\n\t\tif itemCount > 0 {\n\t\t\tp.printSpace()\n\t\t\tp.printSpaceBeforeIdentifier()\n\t\t\tp.print(\"from\")\n\t\t\tp.printSpace()\n\t\t}\n\n\t\tp.printPath(s.ImportRecordIndex, ast.ImportStmt)\n\t\tp.printSemicolonAfterStatement()\n\n\tcase *js_ast.SBlock:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printBlock(stmt.Loc, *s)\n\t\tp.printNewline()\n\n\tcase *js_ast.SDebugger:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"debugger\")\n\t\tp.printSemicolonAfterStatement()\n\n\tcase *js_ast.SDirective:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.printQuotedUTF16(s.Value, 0)\n\t\tp.printSemicolonAfterStatement()\n\n\tcase *js_ast.SBreak:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"break\")\n\t\tif s.Label != nil {\n\t\t\tp.print(\" \")\n\t\t\tname := p.renamer.NameForSymbol(s.Label.Ref)\n\t\t\tp.addSourceMappingForName(s.Label.Loc, name, s.Label.Ref)\n\t\t\tp.printIdentifier(name)\n\t\t}\n\t\tp.printSemicolonAfterStatement()\n\n\tcase *js_ast.SContinue:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"continue\")\n\t\tif s.Label != nil {\n\t\t\tp.print(\" \")\n\t\t\tname := p.renamer.NameForSymbol(s.Label.Ref)\n\t\t\tp.addSourceMappingForName(s.Label.Loc, name, s.Label.Ref)\n\t\t\tp.printIdentifier(name)\n\t\t}\n\t\tp.printSemicolonAfterStatement()\n\n\tcase *js_ast.SReturn:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"return\")\n\t\tif s.ValueOrNil.Data != nil {\n\t\t\tp.printSpace()\n\t\t\tp.printExprWithoutLeadingNewline(s.ValueOrNil, js_ast.LLowest, 0)\n\t\t}\n\t\tp.printSemicolonAfterStatement()\n\n\tcase *js_ast.SThrow:\n\t\tp.addSourceMapping(stmt.Loc)\n\t\tp.printIndent()\n\t\tp.printSpaceBeforeIdentifier()\n\t\tp.print(\"throw\")\n\t\tp.printSpace()\n\t\tp.printExprWithoutLeadingNewline(s.Value, js_ast.LLowest, 0)\n\t\tp.printSemicolonAfterStatement()\n\n\tcase *js_ast.SExpr:\n\t\tvalue := s.Value\n\n\t\t// Omit calls to empty functions from the output completely\n\t\tif p.options.MinifySyntax {\n\t\t\tvalue = p.simplifyUnusedExpr(value)\n\t\t\tif value.Data == nil {\n\t\t\t\t// If this statement is not in a block, then we still need to emit something\n\t\t\t\tif (flags & canOmitStatement) == 0 {\n\t\t\t\t\t// \"if (x) empty();\" => \"if (x) ;\"\n\t\t\t\t\tp.addSourceMapping(stmt.Loc)\n\t\t\t\t\tp.printIndent()\n\t\t\t\t\tp.print(\";\")\n\t\t\t\t\tp.printNewline()\n\t\t\t\t} else {\n\t\t\t\t\t// \"if (x) { empty(); }\" => \"if (x) {}\"\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Avoid printing a source mapping when the expression would print one in\n\t\t// the same spot. We don't want to accidentally mask the mapping it emits.\n\t\tif !p.options.MinifyWhitespace && (p.options.Indent > 0 || p.printNextIndentAsSpace) {\n\t\t\tp.addSourceMapping(stmt.Loc)\n\t\t\tp.printIndent()\n\t\t}\n\n\t\tp.stmtStart = len(p.js)\n\t\tp.printExpr(value, js_ast.LLowest, exprResultIsUnused)\n\t\tp.printSemicolonAfterStatement()\n\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"Unexpected statement of type %T\", stmt.Data))\n\t}\n}\n\ntype Options struct {\n\tRequireOrImportMetaForSource func(uint32) RequireOrImportMeta\n\n\t// Cross-module inlining of TypeScript enums is actually done during printing\n\tTSEnums map[ast.Ref]map[string]js_ast.TSEnumValue\n\n\t// Cross-module inlining of detected inlinable constants is also done during printing\n\tConstValues map[ast.Ref]js_ast.ConstValue\n\n\t// Property mangling results go here\n\tMangledProps map[ast.Ref]string\n\n\t// This will be present if the input file had a source map. In that case we\n\t// want to map all the way back to the original input file(s).\n\tInputSourceMap *sourcemap.SourceMap\n\n\t// If we're writing out a source map, this table of line start indices lets\n\t// us do binary search on to figure out what line a given AST node came from\n\tLineOffsetTables []sourcemap.LineOffsetTable\n\n\tToCommonJSRef       ast.Ref\n\tToESMRef            ast.Ref\n\tRuntimeRequireRef   ast.Ref\n\tUnsupportedFeatures compat.JSFeature\n\tIndent              int\n\tLineLimit           int\n\tOutputFormat        config.Format\n\tMinifyWhitespace    bool\n\tMinifyIdentifiers   bool\n\tMinifySyntax        bool\n\tASCIIOnly           bool\n\tLegalComments       config.LegalComments\n\tSourceMap           config.SourceMap\n\tAddSourceMappings   bool\n\tNeedsMetafile       bool\n\tMetafileFormat      config.MetafileFormat\n}\n\ntype RequireOrImportMeta struct {\n\t// CommonJS files will return the \"require_*\" wrapper function and an invalid\n\t// exports object reference. Lazily-initialized ESM files will return the\n\t// \"init_*\" wrapper function and the exports object for that file.\n\tWrapperRef     ast.Ref\n\tExportsRef     ast.Ref\n\tIsWrapperAsync bool\n}\n\ntype PrintResult struct {\n\tJS                     []byte\n\tExtractedLegalComments []string\n\tJSONMetadataImports    []string\n\n\t// This source map chunk just contains the VLQ-encoded offsets for the \"JS\"\n\t// field above. It's not a full source map. The bundler will be joining many\n\t// source map chunks together to form the final source map.\n\tSourceMapChunk sourcemap.Chunk\n}\n\nfunc Print(tree js_ast.AST, symbols ast.SymbolMap, r renamer.Renamer, options Options) PrintResult {\n\tp := &printer{\n\t\tsymbols:       symbols,\n\t\trenamer:       r,\n\t\timportRecords: tree.ImportRecords,\n\t\toptions:       options,\n\t\tmoduleType:    tree.ModuleTypeData.Type,\n\t\texprComments:  tree.ExprComments,\n\t\twasLazyExport: tree.HasLazyExport,\n\n\t\tstmtStart:          -1,\n\t\texportDefaultStart: -1,\n\t\tarrowExprStart:     -1,\n\t\tforOfInitStart:     -1,\n\n\t\tprevOpEnd:            -1,\n\t\tneedSpaceBeforeDot:   -1,\n\t\tprevRegExpEnd:        -1,\n\t\tnoLeadingNewlineHere: -1,\n\t\tbuilder:              sourcemap.MakeChunkBuilder(options.InputSourceMap, options.LineOffsetTables, options.ASCIIOnly),\n\t}\n\n\tif p.exprComments != nil {\n\t\tp.printedExprComments = make(map[logger.Loc]bool)\n\t}\n\n\tp.astHelpers = js_ast.MakeHelperContext(func(ref ast.Ref) bool {\n\t\tref = ast.FollowSymbols(symbols, ref)\n\t\treturn symbols.Get(ref).Kind == ast.SymbolUnbound\n\t})\n\n\t// Add the top-level directive if present\n\tfor _, directive := range tree.Directives {\n\t\tp.printIndent()\n\t\tp.printQuotedUTF8(directive, 0)\n\t\tp.print(\";\")\n\t\tp.printNewline()\n\t}\n\n\tfor _, part := range tree.Parts {\n\t\tfor _, stmt := range part.Stmts {\n\t\t\tp.printStmt(stmt, canOmitStatement)\n\t\t\tp.printSemicolonIfNeeded()\n\t\t}\n\t}\n\n\tresult := PrintResult{\n\t\tJS:                     p.js,\n\t\tJSONMetadataImports:    p.jsonMetadataImports,\n\t\tExtractedLegalComments: p.extractedLegalComments,\n\t}\n\tif options.SourceMap != config.SourceMapNone {\n\t\t// This is expensive. Only do this if it's necessary.\n\t\tresult.SourceMapChunk = p.builder.GenerateChunk(p.js)\n\t}\n\treturn result\n}\n"
  },
  {
    "path": "internal/js_printer/js_printer_test.go",
    "content": "package js_printer\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/js_parser\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/renamer\"\n\t\"github.com/evanw/esbuild/internal/test\"\n)\n\nfunc expectPrintedCommon(t *testing.T, name string, contents string, expected string, options config.Options) {\n\tt.Helper()\n\tt.Run(name, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\t\ttree, ok := js_parser.Parse(log, test.SourceForTest(contents), js_parser.OptionsFromConfig(&options))\n\t\tmsgs := log.Done()\n\t\tvar text strings.Builder\n\t\tfor _, msg := range msgs {\n\t\t\tif msg.Kind != logger.Error {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttext.WriteString(msg.String(logger.OutputOptions{}, logger.TerminalInfo{}))\n\t\t}\n\t\ttest.AssertEqualWithDiff(t, text.String(), \"\")\n\t\tif !ok {\n\t\t\tt.Fatal(\"Parse error\")\n\t\t}\n\t\tsymbols := ast.NewSymbolMap(1)\n\t\tsymbols.SymbolsForSource[0] = tree.Symbols\n\t\tr := renamer.NewNoOpRenamer(symbols)\n\t\tjs := Print(tree, symbols, r, Options{\n\t\t\tASCIIOnly:           options.ASCIIOnly,\n\t\t\tMinifySyntax:        options.MinifySyntax,\n\t\t\tMinifyWhitespace:    options.MinifyWhitespace,\n\t\t\tUnsupportedFeatures: options.UnsupportedJSFeatures,\n\t\t}).JS\n\t\ttest.AssertEqualWithDiff(t, string(js), expected)\n\t})\n}\n\nfunc expectPrinted(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, contents, expected, config.Options{})\n}\n\nfunc expectPrintedMinify(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [minified]\", contents, expected, config.Options{\n\t\tMinifyWhitespace: true,\n\t})\n}\n\nfunc expectPrintedMangle(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [mangled]\", contents, expected, config.Options{\n\t\tMinifySyntax: true,\n\t})\n}\n\nfunc expectPrintedMangleMinify(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [mangled, minified]\", contents, expected, config.Options{\n\t\tMinifySyntax:     true,\n\t\tMinifyWhitespace: true,\n\t})\n}\n\nfunc expectPrintedASCII(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [ascii]\", contents, expected, config.Options{\n\t\tASCIIOnly: true,\n\t})\n}\n\nfunc expectPrintedMinifyASCII(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [ascii]\", contents, expected, config.Options{\n\t\tMinifyWhitespace: true,\n\t\tASCIIOnly:        true,\n\t})\n}\n\nfunc expectPrintedTarget(t *testing.T, esVersion int, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, contents, expected, config.Options{\n\t\tUnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{\n\t\t\tcompat.ES: {Parts: []int{esVersion}},\n\t\t}),\n\t})\n}\n\nfunc expectPrintedTargetMinify(t *testing.T, esVersion int, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [minified]\", contents, expected, config.Options{\n\t\tUnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{\n\t\t\tcompat.ES: {Parts: []int{esVersion}},\n\t\t}),\n\t\tMinifyWhitespace: true,\n\t})\n}\n\nfunc expectPrintedTargetMangle(t *testing.T, esVersion int, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [mangled]\", contents, expected, config.Options{\n\t\tUnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{\n\t\t\tcompat.ES: {Parts: []int{esVersion}},\n\t\t}),\n\t\tMinifySyntax: true,\n\t})\n}\n\nfunc expectPrintedTargetASCII(t *testing.T, esVersion int, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [ascii]\", contents, expected, config.Options{\n\t\tUnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{\n\t\t\tcompat.ES: {Parts: []int{esVersion}},\n\t\t}),\n\t\tASCIIOnly: true,\n\t})\n}\n\nfunc expectPrintedJSX(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, contents, expected, config.Options{\n\t\tJSX: config.JSXOptions{\n\t\t\tParse:    true,\n\t\t\tPreserve: true,\n\t\t},\n\t})\n}\n\nfunc expectPrintedJSXASCII(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, contents, expected, config.Options{\n\t\tJSX: config.JSXOptions{\n\t\t\tParse:    true,\n\t\t\tPreserve: true,\n\t\t},\n\t\tASCIIOnly: true,\n\t})\n}\n\nfunc expectPrintedJSXMinify(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [minified]\", contents, expected, config.Options{\n\t\tJSX: config.JSXOptions{\n\t\t\tParse:    true,\n\t\t\tPreserve: true,\n\t\t},\n\t\tMinifyWhitespace: true,\n\t})\n}\n\nfunc TestNumber(t *testing.T) {\n\t// Check \"1eN\"\n\texpectPrinted(t, \"x = 1e-100\", \"x = 1e-100;\\n\")\n\texpectPrinted(t, \"x = 1e-4\", \"x = 1e-4;\\n\")\n\texpectPrinted(t, \"x = 1e-3\", \"x = 1e-3;\\n\")\n\texpectPrinted(t, \"x = 1e-2\", \"x = 0.01;\\n\")\n\texpectPrinted(t, \"x = 1e-1\", \"x = 0.1;\\n\")\n\texpectPrinted(t, \"x = 1e0\", \"x = 1;\\n\")\n\texpectPrinted(t, \"x = 1e1\", \"x = 10;\\n\")\n\texpectPrinted(t, \"x = 1e2\", \"x = 100;\\n\")\n\texpectPrinted(t, \"x = 1e3\", \"x = 1e3;\\n\")\n\texpectPrinted(t, \"x = 1e4\", \"x = 1e4;\\n\")\n\texpectPrinted(t, \"x = 1e100\", \"x = 1e100;\\n\")\n\texpectPrintedMinify(t, \"x = 1e-100\", \"x=1e-100;\")\n\texpectPrintedMinify(t, \"x = 1e-5\", \"x=1e-5;\")\n\texpectPrintedMinify(t, \"x = 1e-4\", \"x=1e-4;\")\n\texpectPrintedMinify(t, \"x = 1e-3\", \"x=.001;\")\n\texpectPrintedMinify(t, \"x = 1e-2\", \"x=.01;\")\n\texpectPrintedMinify(t, \"x = 1e-1\", \"x=.1;\")\n\texpectPrintedMinify(t, \"x = 1e0\", \"x=1;\")\n\texpectPrintedMinify(t, \"x = 1e1\", \"x=10;\")\n\texpectPrintedMinify(t, \"x = 1e2\", \"x=100;\")\n\texpectPrintedMinify(t, \"x = 1e3\", \"x=1e3;\")\n\texpectPrintedMinify(t, \"x = 1e4\", \"x=1e4;\")\n\texpectPrintedMinify(t, \"x = 1e100\", \"x=1e100;\")\n\n\t// Check \"12eN\"\n\texpectPrinted(t, \"x = 12e-100\", \"x = 12e-100;\\n\")\n\texpectPrinted(t, \"x = 12e-5\", \"x = 12e-5;\\n\")\n\texpectPrinted(t, \"x = 12e-4\", \"x = 12e-4;\\n\")\n\texpectPrinted(t, \"x = 12e-3\", \"x = 0.012;\\n\")\n\texpectPrinted(t, \"x = 12e-2\", \"x = 0.12;\\n\")\n\texpectPrinted(t, \"x = 12e-1\", \"x = 1.2;\\n\")\n\texpectPrinted(t, \"x = 12e0\", \"x = 12;\\n\")\n\texpectPrinted(t, \"x = 12e1\", \"x = 120;\\n\")\n\texpectPrinted(t, \"x = 12e2\", \"x = 1200;\\n\")\n\texpectPrinted(t, \"x = 12e3\", \"x = 12e3;\\n\")\n\texpectPrinted(t, \"x = 12e4\", \"x = 12e4;\\n\")\n\texpectPrinted(t, \"x = 12e100\", \"x = 12e100;\\n\")\n\texpectPrintedMinify(t, \"x = 12e-100\", \"x=12e-100;\")\n\texpectPrintedMinify(t, \"x = 12e-6\", \"x=12e-6;\")\n\texpectPrintedMinify(t, \"x = 12e-5\", \"x=12e-5;\")\n\texpectPrintedMinify(t, \"x = 12e-4\", \"x=.0012;\")\n\texpectPrintedMinify(t, \"x = 12e-3\", \"x=.012;\")\n\texpectPrintedMinify(t, \"x = 12e-2\", \"x=.12;\")\n\texpectPrintedMinify(t, \"x = 12e-1\", \"x=1.2;\")\n\texpectPrintedMinify(t, \"x = 12e0\", \"x=12;\")\n\texpectPrintedMinify(t, \"x = 12e1\", \"x=120;\")\n\texpectPrintedMinify(t, \"x = 12e2\", \"x=1200;\")\n\texpectPrintedMinify(t, \"x = 12e3\", \"x=12e3;\")\n\texpectPrintedMinify(t, \"x = 12e4\", \"x=12e4;\")\n\texpectPrintedMinify(t, \"x = 12e100\", \"x=12e100;\")\n\n\t// Check cases for \"A.BeX\" => \"ABeY\" simplification\n\texpectPrinted(t, \"x = 123456789\", \"x = 123456789;\\n\")\n\texpectPrinted(t, \"x = 1123456789\", \"x = 1123456789;\\n\")\n\texpectPrinted(t, \"x = 10123456789\", \"x = 10123456789;\\n\")\n\texpectPrinted(t, \"x = 100123456789\", \"x = 100123456789;\\n\")\n\texpectPrinted(t, \"x = 1000123456789\", \"x = 1000123456789;\\n\")\n\texpectPrinted(t, \"x = 10000123456789\", \"x = 10000123456789;\\n\")\n\texpectPrinted(t, \"x = 100000123456789\", \"x = 100000123456789;\\n\")\n\texpectPrinted(t, \"x = 1000000123456789\", \"x = 1000000123456789;\\n\")\n\texpectPrinted(t, \"x = 10000000123456789\", \"x = 10000000123456788;\\n\")\n\texpectPrinted(t, \"x = 100000000123456789\", \"x = 100000000123456780;\\n\")\n\texpectPrinted(t, \"x = 1000000000123456789\", \"x = 1000000000123456800;\\n\")\n\texpectPrinted(t, \"x = 10000000000123456789\", \"x = 10000000000123458e3;\\n\")\n\texpectPrinted(t, \"x = 100000000000123456789\", \"x = 10000000000012345e4;\\n\")\n\n\t// Check numbers around the ends of various integer ranges. These were\n\t// crashing in the WebAssembly build due to a bug in the Go runtime.\n\n\t// int32\n\texpectPrinted(t, \"x = 0x7fff_ffff\", \"x = 2147483647;\\n\")\n\texpectPrinted(t, \"x = 0x8000_0000\", \"x = 2147483648;\\n\")\n\texpectPrinted(t, \"x = 0x8000_0001\", \"x = 2147483649;\\n\")\n\texpectPrinted(t, \"x = -0x7fff_ffff\", \"x = -2147483647;\\n\")\n\texpectPrinted(t, \"x = -0x8000_0000\", \"x = -2147483648;\\n\")\n\texpectPrinted(t, \"x = -0x8000_0001\", \"x = -2147483649;\\n\")\n\n\t// uint32\n\texpectPrinted(t, \"x = 0xffff_ffff\", \"x = 4294967295;\\n\")\n\texpectPrinted(t, \"x = 0x1_0000_0000\", \"x = 4294967296;\\n\")\n\texpectPrinted(t, \"x = 0x1_0000_0001\", \"x = 4294967297;\\n\")\n\texpectPrinted(t, \"x = -0xffff_ffff\", \"x = -4294967295;\\n\")\n\texpectPrinted(t, \"x = -0x1_0000_0000\", \"x = -4294967296;\\n\")\n\texpectPrinted(t, \"x = -0x1_0000_0001\", \"x = -4294967297;\\n\")\n\n\t// int64\n\texpectPrinted(t, \"x = 0x7fff_ffff_ffff_fdff\", \"x = 9223372036854775e3;\\n\")\n\texpectPrinted(t, \"x = 0x8000_0000_0000_0000\", \"x = 9223372036854776e3;\\n\")\n\texpectPrinted(t, \"x = 0x8000_0000_0000_3000\", \"x = 9223372036854788e3;\\n\")\n\texpectPrinted(t, \"x = -0x7fff_ffff_ffff_fdff\", \"x = -9223372036854775e3;\\n\")\n\texpectPrinted(t, \"x = -0x8000_0000_0000_0000\", \"x = -9223372036854776e3;\\n\")\n\texpectPrinted(t, \"x = -0x8000_0000_0000_3000\", \"x = -9223372036854788e3;\\n\")\n\n\t// uint64\n\texpectPrinted(t, \"x = 0xffff_ffff_ffff_fbff\", \"x = 1844674407370955e4;\\n\")\n\texpectPrinted(t, \"x = 0x1_0000_0000_0000_0000\", \"x = 18446744073709552e3;\\n\")\n\texpectPrinted(t, \"x = 0x1_0000_0000_0000_1000\", \"x = 18446744073709556e3;\\n\")\n\texpectPrinted(t, \"x = -0xffff_ffff_ffff_fbff\", \"x = -1844674407370955e4;\\n\")\n\texpectPrinted(t, \"x = -0x1_0000_0000_0000_0000\", \"x = -18446744073709552e3;\\n\")\n\texpectPrinted(t, \"x = -0x1_0000_0000_0000_1000\", \"x = -18446744073709556e3;\\n\")\n\n\t// Check the hex vs. decimal decision boundary when minifying\n\texpectPrinted(t, \"x = 999999999999\", \"x = 999999999999;\\n\")\n\texpectPrinted(t, \"x = 1000000000001\", \"x = 1000000000001;\\n\")\n\texpectPrinted(t, \"x = 0x0FFF_FFFF_FFFF_FF80\", \"x = 1152921504606846800;\\n\")\n\texpectPrinted(t, \"x = 0x1000_0000_0000_0000\", \"x = 1152921504606847e3;\\n\")\n\texpectPrinted(t, \"x = 0xFFFF_FFFF_FFFF_F000\", \"x = 18446744073709548e3;\\n\")\n\texpectPrinted(t, \"x = 0xFFFF_FFFF_FFFF_F800\", \"x = 1844674407370955e4;\\n\")\n\texpectPrinted(t, \"x = 0xFFFF_FFFF_FFFF_FFFF\", \"x = 18446744073709552e3;\\n\")\n\texpectPrintedMinify(t, \"x = 999999999999\", \"x=999999999999;\")\n\texpectPrintedMinify(t, \"x = 1000000000001\", \"x=0xe8d4a51001;\")\n\texpectPrintedMinify(t, \"x = 0x0FFF_FFFF_FFFF_FF80\", \"x=0xfffffffffffff80;\")\n\texpectPrintedMinify(t, \"x = 0x1000_0000_0000_0000\", \"x=1152921504606847e3;\")\n\texpectPrintedMinify(t, \"x = 0xFFFF_FFFF_FFFF_F000\", \"x=0xfffffffffffff000;\")\n\texpectPrintedMinify(t, \"x = 0xFFFF_FFFF_FFFF_F800\", \"x=1844674407370955e4;\")\n\texpectPrintedMinify(t, \"x = 0xFFFF_FFFF_FFFF_FFFF\", \"x=18446744073709552e3;\")\n\n\t// Check printing a space in between a number and a subsequent \".\"\n\texpectPrintedMinify(t, \"x = 0.0001 .y\", \"x=1e-4.y;\")\n\texpectPrintedMinify(t, \"x = 0.001 .y\", \"x=.001.y;\")\n\texpectPrintedMinify(t, \"x = 0.01 .y\", \"x=.01.y;\")\n\texpectPrintedMinify(t, \"x = 0.1 .y\", \"x=.1.y;\")\n\texpectPrintedMinify(t, \"x = 0 .y\", \"x=0 .y;\")\n\texpectPrintedMinify(t, \"x = 10 .y\", \"x=10 .y;\")\n\texpectPrintedMinify(t, \"x = 100 .y\", \"x=100 .y;\")\n\texpectPrintedMinify(t, \"x = 1000 .y\", \"x=1e3.y;\")\n\texpectPrintedMinify(t, \"x = 12345 .y\", \"x=12345 .y;\")\n\texpectPrintedMinify(t, \"x = 0xFFFF_0000_FFFF_0000 .y\", \"x=0xffff0000ffff0000.y;\")\n}\n\nfunc TestArray(t *testing.T) {\n\texpectPrinted(t, \"[]\", \"[];\\n\")\n\texpectPrinted(t, \"[,]\", \"[,];\\n\")\n\texpectPrinted(t, \"[,,]\", \"[, ,];\\n\")\n}\n\nfunc TestSplat(t *testing.T) {\n\texpectPrinted(t, \"[...(a, b)]\", \"[...(a, b)];\\n\")\n\texpectPrinted(t, \"x(...(a, b))\", \"x(...(a, b));\\n\")\n\texpectPrinted(t, \"({...(a, b)})\", \"({ ...(a, b) });\\n\")\n}\n\nfunc TestNew(t *testing.T) {\n\texpectPrinted(t, \"new x\", \"new x();\\n\")\n\texpectPrinted(t, \"new x()\", \"new x();\\n\")\n\texpectPrinted(t, \"new (x)\", \"new x();\\n\")\n\texpectPrinted(t, \"new (x())\", \"new (x())();\\n\")\n\texpectPrinted(t, \"new (new x())\", \"new new x()();\\n\")\n\texpectPrinted(t, \"new (x + x)\", \"new (x + x)();\\n\")\n\texpectPrinted(t, \"(new x)()\", \"new x()();\\n\")\n\n\texpectPrinted(t, \"new foo().bar\", \"new foo().bar;\\n\")\n\texpectPrinted(t, \"new (foo().bar)\", \"new (foo()).bar();\\n\")\n\texpectPrinted(t, \"new (foo()).bar\", \"new (foo()).bar();\\n\")\n\texpectPrinted(t, \"new foo()[bar]\", \"new foo()[bar];\\n\")\n\texpectPrinted(t, \"new (foo()[bar])\", \"new (foo())[bar]();\\n\")\n\texpectPrinted(t, \"new (foo())[bar]\", \"new (foo())[bar]();\\n\")\n\n\texpectPrinted(t, \"new (import('foo').bar)\", \"new (import(\\\"foo\\\")).bar();\\n\")\n\texpectPrinted(t, \"new (import('foo')).bar\", \"new (import(\\\"foo\\\")).bar();\\n\")\n\texpectPrinted(t, \"new (import('foo')[bar])\", \"new (import(\\\"foo\\\"))[bar]();\\n\")\n\texpectPrinted(t, \"new (import('foo'))[bar]\", \"new (import(\\\"foo\\\"))[bar]();\\n\")\n\n\texpectPrintedMinify(t, \"new x\", \"new x;\")\n\texpectPrintedMinify(t, \"new x.y\", \"new x.y;\")\n\texpectPrintedMinify(t, \"(new x).y\", \"new x().y;\")\n\texpectPrintedMinify(t, \"new x().y\", \"new x().y;\")\n\texpectPrintedMinify(t, \"new x() + y\", \"new x+y;\")\n\texpectPrintedMinify(t, \"new x() ** 2\", \"new x**2;\")\n\n\t// Test preservation of Webpack-specific comments\n\texpectPrinted(t, \"new Worker(// webpackFoo: 1\\n // webpackBar: 2\\n 'path');\", \"new Worker(\\n  // webpackFoo: 1\\n  // webpackBar: 2\\n  \\\"path\\\"\\n);\\n\")\n\texpectPrinted(t, \"new Worker(/* webpackFoo: 1 */ /* webpackBar: 2 */ 'path');\", \"new Worker(\\n  /* webpackFoo: 1 */\\n  /* webpackBar: 2 */\\n  \\\"path\\\"\\n);\\n\")\n\texpectPrinted(t, \"new Worker(\\n    /* multi\\n     * line\\n     * webpackBar: */ 'path');\", \"new Worker(\\n  /* multi\\n   * line\\n   * webpackBar: */\\n  \\\"path\\\"\\n);\\n\")\n\texpectPrinted(t, \"new Worker(/* webpackFoo: 1 */ 'path' /* webpackBar:2 */);\", \"new Worker(\\n  /* webpackFoo: 1 */\\n  \\\"path\\\"\\n  /* webpackBar:2 */\\n);\\n\")\n\texpectPrinted(t, \"new Worker(/* webpackFoo: 1 */ 'path' /* webpackBar:2 */ ,);\", \"new Worker(\\n  /* webpackFoo: 1 */\\n  \\\"path\\\"\\n);\\n\") // Not currently handled\n\texpectPrinted(t, \"new Worker(/* webpackFoo: 1 */ 'path', /* webpackBar:2 */ );\", \"new Worker(\\n  /* webpackFoo: 1 */\\n  \\\"path\\\"\\n  /* webpackBar:2 */\\n);\\n\")\n\texpectPrinted(t, \"new Worker(new URL('path', /* webpackFoo: these can go anywhere */ import.meta.url))\",\n\t\t\"new Worker(new URL(\\n  \\\"path\\\",\\n  /* webpackFoo: these can go anywhere */\\n  import.meta.url\\n));\\n\")\n}\n\nfunc TestCall(t *testing.T) {\n\texpectPrinted(t, \"x()()()\", \"x()()();\\n\")\n\texpectPrinted(t, \"x().y()[z]()\", \"x().y()[z]();\\n\")\n\texpectPrinted(t, \"(--x)();\", \"(--x)();\\n\")\n\texpectPrinted(t, \"(x--)();\", \"(x--)();\\n\")\n\n\texpectPrinted(t, \"eval(x)\", \"eval(x);\\n\")\n\texpectPrinted(t, \"eval?.(x)\", \"eval?.(x);\\n\")\n\texpectPrinted(t, \"(eval)(x)\", \"eval(x);\\n\")\n\texpectPrinted(t, \"(eval)?.(x)\", \"eval?.(x);\\n\")\n\n\texpectPrinted(t, \"eval(x, y)\", \"eval(x, y);\\n\")\n\texpectPrinted(t, \"eval?.(x, y)\", \"eval?.(x, y);\\n\")\n\texpectPrinted(t, \"(1, eval)(x)\", \"(1, eval)(x);\\n\")\n\texpectPrinted(t, \"(1, eval)?.(x)\", \"(1, eval)?.(x);\\n\")\n\texpectPrintedMangle(t, \"(1 ? eval : 2)(x)\", \"(0, eval)(x);\\n\")\n\texpectPrintedMangle(t, \"(1 ? eval : 2)?.(x)\", \"eval?.(x);\\n\")\n\n\texpectPrintedMinify(t, \"eval?.(x)\", \"eval?.(x);\")\n\texpectPrintedMinify(t, \"eval(x,y)\", \"eval(x,y);\")\n\texpectPrintedMinify(t, \"eval?.(x,y)\", \"eval?.(x,y);\")\n\texpectPrintedMinify(t, \"(1, eval)(x)\", \"(1,eval)(x);\")\n\texpectPrintedMinify(t, \"(1, eval)?.(x)\", \"(1,eval)?.(x);\")\n\texpectPrintedMangleMinify(t, \"(1 ? eval : 2)(x)\", \"(0,eval)(x);\")\n\texpectPrintedMangleMinify(t, \"(1 ? eval : 2)?.(x)\", \"eval?.(x);\")\n}\n\nfunc TestMember(t *testing.T) {\n\texpectPrinted(t, \"x.y[z]\", \"x.y[z];\\n\")\n\texpectPrinted(t, \"((x+1).y+1)[z]\", \"((x + 1).y + 1)[z];\\n\")\n}\n\nfunc TestComma(t *testing.T) {\n\texpectPrinted(t, \"1, 2, 3\", \"1, 2, 3;\\n\")\n\texpectPrinted(t, \"(1, 2), 3\", \"1, 2, 3;\\n\")\n\texpectPrinted(t, \"1, (2, 3)\", \"1, 2, 3;\\n\")\n\texpectPrinted(t, \"a ? (b, c) : (d, e)\", \"a ? (b, c) : (d, e);\\n\")\n\texpectPrinted(t, \"let x = (a, b)\", \"let x = (a, b);\\n\")\n\texpectPrinted(t, \"(x = a), b\", \"x = a, b;\\n\")\n\texpectPrinted(t, \"x = (a, b)\", \"x = (a, b);\\n\")\n\texpectPrinted(t, \"x((1, 2))\", \"x((1, 2));\\n\")\n}\n\nfunc TestUnary(t *testing.T) {\n\texpectPrinted(t, \"+(x--)\", \"+x--;\\n\")\n\texpectPrinted(t, \"-(x++)\", \"-x++;\\n\")\n}\n\nfunc TestNullish(t *testing.T) {\n\t// \"??\" can't directly contain \"||\" or \"&&\"\n\texpectPrinted(t, \"(a && b) ?? c\", \"(a && b) ?? c;\\n\")\n\texpectPrinted(t, \"(a || b) ?? c\", \"(a || b) ?? c;\\n\")\n\texpectPrinted(t, \"a ?? (b && c)\", \"a ?? (b && c);\\n\")\n\texpectPrinted(t, \"a ?? (b || c)\", \"a ?? (b || c);\\n\")\n\n\t// \"||\" and \"&&\" can't directly contain \"??\"\n\texpectPrinted(t, \"a && (b ?? c)\", \"a && (b ?? c);\\n\")\n\texpectPrinted(t, \"a || (b ?? c)\", \"a || (b ?? c);\\n\")\n\texpectPrinted(t, \"(a ?? b) && c\", \"(a ?? b) && c;\\n\")\n\texpectPrinted(t, \"(a ?? b) || c\", \"(a ?? b) || c;\\n\")\n}\n\nfunc TestString(t *testing.T) {\n\texpectPrinted(t, \"let x = ''\", \"let x = \\\"\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\b'\", \"let x = \\\"\\\\b\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\f'\", \"let x = \\\"\\\\f\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\t'\", \"let x = \\\"\\t\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\v'\", \"let x = \\\"\\\\v\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\n'\", \"let x = \\\"\\\\n\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\''\", \"let x = \\\"'\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\\\\"'\", \"let x = '\\\"';\\n\")\n\texpectPrinted(t, \"let x = '\\\\'\\\"'\", \"let x = `'\\\"`;\\n\")\n\texpectPrinted(t, \"let x = '\\\\\\\\'\", \"let x = \\\"\\\\\\\\\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\x00'\", \"let x = \\\"\\\\0\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\x00!'\", \"let x = \\\"\\\\0!\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\x001'\", \"let x = \\\"\\\\x001\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\0'\", \"let x = \\\"\\\\0\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\0!'\", \"let x = \\\"\\\\0!\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\x07'\", \"let x = \\\"\\\\x07\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\x07!'\", \"let x = \\\"\\\\x07!\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\x071'\", \"let x = \\\"\\\\x071\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\7'\", \"let x = \\\"\\\\x07\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\7!'\", \"let x = \\\"\\\\x07!\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\01'\", \"let x = \\\"\\x01\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\x10'\", \"let x = \\\"\\x10\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\x10'\", \"let x = \\\"\\x10\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\x1B'\", \"let x = \\\"\\\\x1B\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\x1B'\", \"let x = \\\"\\\\x1B\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\uABCD'\", \"let x = \\\"\\uABCD\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\uABCD'\", \"let x = \\\"\\uABCD\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\U000123AB'\", \"let x = \\\"\\U000123AB\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\u{123AB}'\", \"let x = \\\"\\U000123AB\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\uD808\\\\uDFAB'\", \"let x = \\\"\\U000123AB\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\uD808'\", \"let x = \\\"\\\\uD808\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\uD808X'\", \"let x = \\\"\\\\uD808X\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\uDFAB'\", \"let x = \\\"\\\\uDFAB\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\uDFABX'\", \"let x = \\\"\\\\uDFABX\\\";\\n\")\n\n\texpectPrinted(t, \"let x = '\\\\x80'\", \"let x = \\\"\\U00000080\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\xFF'\", \"let x = \\\"\\U000000FF\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\xF0\\\\x9F\\\\x8D\\\\x95'\", \"let x = \\\"\\U000000F0\\U0000009F\\U0000008D\\U00000095\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\\\uD801\\\\uDC02\\\\uDC03\\\\uD804'\", \"let x = \\\"\\U00010402\\\\uDC03\\\\uD804\\\";\\n\")\n}\n\nfunc TestTemplate(t *testing.T) {\n\texpectPrinted(t, \"let x = `\\\\0`\", \"let x = `\\\\0`;\\n\")\n\texpectPrinted(t, \"let x = `\\\\x01`\", \"let x = `\\x01`;\\n\")\n\texpectPrinted(t, \"let x = `\\\\0${0}`\", \"let x = `\\\\0${0}`;\\n\")\n\texpectPrinted(t, \"let x = `\\\\x01${0}`\", \"let x = `\\x01${0}`;\\n\")\n\texpectPrinted(t, \"let x = `${0}\\\\0`\", \"let x = `${0}\\\\0`;\\n\")\n\texpectPrinted(t, \"let x = `${0}\\\\x01`\", \"let x = `${0}\\x01`;\\n\")\n\texpectPrinted(t, \"let x = `${0}\\\\0${1}`\", \"let x = `${0}\\\\0${1}`;\\n\")\n\texpectPrinted(t, \"let x = `${0}\\\\x01${1}`\", \"let x = `${0}\\x01${1}`;\\n\")\n\n\texpectPrinted(t, \"let x = String.raw`\\\\1`\", \"let x = String.raw`\\\\1`;\\n\")\n\texpectPrinted(t, \"let x = String.raw`\\\\x01`\", \"let x = String.raw`\\\\x01`;\\n\")\n\texpectPrinted(t, \"let x = String.raw`\\\\1${0}`\", \"let x = String.raw`\\\\1${0}`;\\n\")\n\texpectPrinted(t, \"let x = String.raw`\\\\x01${0}`\", \"let x = String.raw`\\\\x01${0}`;\\n\")\n\texpectPrinted(t, \"let x = String.raw`${0}\\\\1`\", \"let x = String.raw`${0}\\\\1`;\\n\")\n\texpectPrinted(t, \"let x = String.raw`${0}\\\\x01`\", \"let x = String.raw`${0}\\\\x01`;\\n\")\n\texpectPrinted(t, \"let x = String.raw`${0}\\\\1${1}`\", \"let x = String.raw`${0}\\\\1${1}`;\\n\")\n\texpectPrinted(t, \"let x = String.raw`${0}\\\\x01${1}`\", \"let x = String.raw`${0}\\\\x01${1}`;\\n\")\n\n\texpectPrinted(t, \"let x = `${y}`\", \"let x = `${y}`;\\n\")\n\texpectPrinted(t, \"let x = `$(y)`\", \"let x = `$(y)`;\\n\")\n\texpectPrinted(t, \"let x = `{y}$`\", \"let x = `{y}$`;\\n\")\n\texpectPrinted(t, \"let x = `$}y{`\", \"let x = `$}y{`;\\n\")\n\texpectPrinted(t, \"let x = `\\\\${y}`\", \"let x = `\\\\${y}`;\\n\")\n\texpectPrinted(t, \"let x = `$\\\\{y}`\", \"let x = `\\\\${y}`;\\n\")\n\n\texpectPrinted(t, \"await tag`x`\", \"await tag`x`;\\n\")\n\texpectPrinted(t, \"await (tag`x`)\", \"await tag`x`;\\n\")\n\texpectPrinted(t, \"(await tag)`x`\", \"(await tag)`x`;\\n\")\n\n\texpectPrinted(t, \"await tag`${x}`\", \"await tag`${x}`;\\n\")\n\texpectPrinted(t, \"await (tag`${x}`)\", \"await tag`${x}`;\\n\")\n\texpectPrinted(t, \"(await tag)`${x}`\", \"(await tag)`${x}`;\\n\")\n\n\texpectPrinted(t, \"new tag`x`\", \"new tag`x`();\\n\")\n\texpectPrinted(t, \"new (tag`x`)\", \"new tag`x`();\\n\")\n\texpectPrinted(t, \"new tag()`x`\", \"new tag()`x`;\\n\")\n\texpectPrinted(t, \"(new tag)`x`\", \"new tag()`x`;\\n\")\n\texpectPrintedMinify(t, \"new tag`x`\", \"new tag`x`;\")\n\texpectPrintedMinify(t, \"new (tag`x`)\", \"new tag`x`;\")\n\texpectPrintedMinify(t, \"new tag()`x`\", \"new tag()`x`;\")\n\texpectPrintedMinify(t, \"(new tag)`x`\", \"new tag()`x`;\")\n\n\texpectPrinted(t, \"new tag`${x}`\", \"new tag`${x}`();\\n\")\n\texpectPrinted(t, \"new (tag`${x}`)\", \"new tag`${x}`();\\n\")\n\texpectPrinted(t, \"new tag()`${x}`\", \"new tag()`${x}`;\\n\")\n\texpectPrinted(t, \"(new tag)`${x}`\", \"new tag()`${x}`;\\n\")\n\texpectPrintedMinify(t, \"new tag`${x}`\", \"new tag`${x}`;\")\n\texpectPrintedMinify(t, \"new (tag`${x}`)\", \"new tag`${x}`;\")\n\texpectPrintedMinify(t, \"new tag()`${x}`\", \"new tag()`${x}`;\")\n\texpectPrintedMinify(t, \"(new tag)`${x}`\", \"new tag()`${x}`;\")\n}\n\nfunc TestObject(t *testing.T) {\n\texpectPrinted(t, \"let x = {'(':')'}\", \"let x = { \\\"(\\\": \\\")\\\" };\\n\")\n\texpectPrinted(t, \"({})\", \"({});\\n\")\n\texpectPrinted(t, \"({}.x)\", \"({}).x;\\n\")\n\texpectPrinted(t, \"({} = {})\", \"({} = {});\\n\")\n\texpectPrinted(t, \"(x, {} = {})\", \"x, {} = {};\\n\")\n\texpectPrinted(t, \"let x = () => ({})\", \"let x = () => ({});\\n\")\n\texpectPrinted(t, \"let x = () => ({}.x)\", \"let x = () => ({}).x;\\n\")\n\texpectPrinted(t, \"let x = () => ({} = {})\", \"let x = () => ({} = {});\\n\")\n\texpectPrinted(t, \"let x = () => (x, {} = {})\", \"let x = () => (x, {} = {});\\n\")\n\n\t// \"{ __proto__: __proto__ }\" must not become \"{ __proto__ }\"\n\texpectPrinted(t, \"function foo(__proto__) { return { __proto__: __proto__ } }\", \"function foo(__proto__) {\\n  return { __proto__: __proto__ };\\n}\\n\")\n\texpectPrinted(t, \"function foo(__proto__) { return { '__proto__': __proto__ } }\", \"function foo(__proto__) {\\n  return { \\\"__proto__\\\": __proto__ };\\n}\\n\")\n\texpectPrinted(t, \"function foo(__proto__) { return { ['__proto__']: __proto__ } }\", \"function foo(__proto__) {\\n  return { [\\\"__proto__\\\"]: __proto__ };\\n}\\n\")\n\texpectPrinted(t, \"import { __proto__ } from 'foo'; let foo = () => ({ __proto__: __proto__ })\", \"import { __proto__ } from \\\"foo\\\";\\nlet foo = () => ({ __proto__: __proto__ });\\n\")\n\texpectPrinted(t, \"import { __proto__ } from 'foo'; let foo = () => ({ '__proto__': __proto__ })\", \"import { __proto__ } from \\\"foo\\\";\\nlet foo = () => ({ \\\"__proto__\\\": __proto__ });\\n\")\n\texpectPrinted(t, \"import { __proto__ } from 'foo'; let foo = () => ({ ['__proto__']: __proto__ })\", \"import { __proto__ } from \\\"foo\\\";\\nlet foo = () => ({ [\\\"__proto__\\\"]: __proto__ });\\n\")\n\n\t// Don't use ES6+ features (such as a shorthand or computed property name) in ES5\n\texpectPrintedTarget(t, 5, \"function foo(__proto__) { return { __proto__ } }\", \"function foo(__proto__) {\\n  return { __proto__: __proto__ };\\n}\\n\")\n}\n\nfunc TestSwitch(t *testing.T) {\n\t// Ideally comments on case clauses would be preserved\n\texpectPrinted(t, \"switch (x) { /* 1 */ case 1: /* 2 */ case 2: /* default */ default: break }\",\n\t\t\"switch (x) {\\n  /* 1 */\\n  case 1:\\n  /* 2 */\\n  case 2:\\n  /* default */\\n  default:\\n    break;\\n}\\n\")\n}\n\nfunc TestFor(t *testing.T) {\n\t// Make sure \"in\" expressions are forbidden in the right places\n\texpectPrinted(t, \"for ((a in b);;);\", \"for ((a in b); ; ) ;\\n\")\n\texpectPrinted(t, \"for (a ? b : (c in d);;);\", \"for (a ? b : (c in d); ; ) ;\\n\")\n\texpectPrinted(t, \"for ((a ? b : c in d).foo;;);\", \"for ((a ? b : c in d).foo; ; ) ;\\n\")\n\texpectPrinted(t, \"for (var x = (a in b);;);\", \"for (var x = (a in b); ; ) ;\\n\")\n\texpectPrinted(t, \"for (x = (a in b);;);\", \"for (x = (a in b); ; ) ;\\n\")\n\texpectPrinted(t, \"for (x == (a in b);;);\", \"for (x == (a in b); ; ) ;\\n\")\n\texpectPrinted(t, \"for (1 * (x == a in b);;);\", \"for (1 * (x == a in b); ; ) ;\\n\")\n\texpectPrinted(t, \"for (a ? b : x = (c in d);;);\", \"for (a ? b : x = (c in d); ; ) ;\\n\")\n\texpectPrinted(t, \"for (var x = y = (a in b);;);\", \"for (var x = y = (a in b); ; ) ;\\n\")\n\texpectPrinted(t, \"for ([a in b];;);\", \"for ([a in b]; ; ) ;\\n\")\n\texpectPrinted(t, \"for (x(a in b);;);\", \"for (x(a in b); ; ) ;\\n\")\n\texpectPrinted(t, \"for (x[a in b];;);\", \"for (x[a in b]; ; ) ;\\n\")\n\texpectPrinted(t, \"for (x?.[a in b];;);\", \"for (x?.[a in b]; ; ) ;\\n\")\n\texpectPrinted(t, \"for ((x => a in b);;);\", \"for (((x) => a in b); ; ) ;\\n\")\n\n\t// Make sure for-of loops with commas are wrapped in parentheses\n\texpectPrinted(t, \"for (let a in b, c);\", \"for (let a in b, c) ;\\n\")\n\texpectPrinted(t, \"for (let a of (b, c));\", \"for (let a of (b, c)) ;\\n\")\n}\n\nfunc TestFunction(t *testing.T) {\n\texpectPrinted(t,\n\t\t\"function foo(a = (b, c), ...d) {}\",\n\t\t\"function foo(a = (b, c), ...d) {\\n}\\n\")\n\texpectPrinted(t,\n\t\t\"function foo({[1 + 2]: a = 3} = {[1 + 2]: 3}) {}\",\n\t\t\"function foo({ [1 + 2]: a = 3 } = { [1 + 2]: 3 }) {\\n}\\n\")\n\texpectPrinted(t,\n\t\t\"function foo([a = (1, 2), ...[b, ...c]] = [1, [2, 3]]) {}\",\n\t\t\"function foo([a = (1, 2), ...[b, ...c]] = [1, [2, 3]]) {\\n}\\n\")\n\texpectPrinted(t,\n\t\t\"function foo([] = []) {}\",\n\t\t\"function foo([] = []) {\\n}\\n\")\n\texpectPrinted(t,\n\t\t\"function foo([,] = [,]) {}\",\n\t\t\"function foo([,] = [,]) {\\n}\\n\")\n\texpectPrinted(t,\n\t\t\"function foo([,,] = [,,]) {}\",\n\t\t\"function foo([, ,] = [, ,]) {\\n}\\n\")\n}\n\nfunc TestCommentsAndParentheses(t *testing.T) {\n\texpectPrinted(t, \"(/* foo */ { x() { foo() } }.x());\", \"/* foo */\\n({ x() {\\n  foo();\\n} }).x();\\n\")\n\texpectPrinted(t, \"(/* foo */ function f() { foo(f) }());\", \"/* foo */\\n(function f() {\\n  foo(f);\\n})();\\n\")\n\texpectPrinted(t, \"(/* foo */ class x { static y() { foo(x) } }.y());\", \"/* foo */\\n(class x {\\n  static y() {\\n    foo(x);\\n  }\\n}).y();\\n\")\n\texpectPrinted(t, \"(/* @__PURE__ */ (() => foo())());\", \"/* @__PURE__ */ (() => foo())();\\n\")\n\texpectPrinted(t, \"export default (/* foo */ function f() {});\", \"export default (\\n  /* foo */\\n  (function f() {\\n  })\\n);\\n\")\n\texpectPrinted(t, \"export default (/* foo */ class x {});\", \"export default (\\n  /* foo */\\n  class x {\\n  }\\n);\\n\")\n\texpectPrinted(t, \"x = () => (/* foo */ {});\", \"x = () => (\\n  /* foo */\\n  {}\\n);\\n\")\n\texpectPrinted(t, \"for ((/* foo */ let).x of y) ;\", \"for (\\n  /* foo */\\n  (let).x of y\\n) ;\\n\")\n\texpectPrinted(t, \"for (/* foo */ (let).x of y) ;\", \"for (\\n  /* foo */\\n  (let).x of y\\n) ;\\n\")\n\texpectPrinted(t, \"function *x() { yield (/* foo */ y) }\", \"function* x() {\\n  yield (\\n    /* foo */\\n    y\\n  );\\n}\\n\")\n}\n\nfunc TestPureComment(t *testing.T) {\n\texpectPrinted(t,\n\t\t\"(function() { foo() })\",\n\t\t\"(function() {\\n  foo();\\n});\\n\")\n\texpectPrinted(t,\n\t\t\"(function() { foo() })()\",\n\t\t\"(function() {\\n  foo();\\n})();\\n\")\n\texpectPrinted(t,\n\t\t\"/*@__PURE__*/(function() { foo() })()\",\n\t\t\"/* @__PURE__ */ (function() {\\n  foo();\\n})();\\n\")\n\n\texpectPrinted(t,\n\t\t\"new (function() {})\",\n\t\t\"new (function() {\\n})();\\n\")\n\texpectPrinted(t,\n\t\t\"new (function() {})()\",\n\t\t\"new (function() {\\n})();\\n\")\n\texpectPrinted(t,\n\t\t\"/*@__PURE__*/new (function() {})()\",\n\t\t\"/* @__PURE__ */ new (function() {\\n})();\\n\")\n\n\texpectPrinted(t,\n\t\t\"export default (function() { foo() })\",\n\t\t\"export default (function() {\\n  foo();\\n});\\n\")\n\texpectPrinted(t,\n\t\t\"export default (function() { foo() })()\",\n\t\t\"export default (function() {\\n  foo();\\n})();\\n\")\n\texpectPrinted(t,\n\t\t\"export default /*@__PURE__*/(function() { foo() })()\",\n\t\t\"export default /* @__PURE__ */ (function() {\\n  foo();\\n})();\\n\")\n}\n\nfunc TestGenerator(t *testing.T) {\n\texpectPrinted(t,\n\t\t\"function* foo() {}\",\n\t\t\"function* foo() {\\n}\\n\")\n\texpectPrinted(t,\n\t\t\"(function* () {})\",\n\t\t\"(function* () {\\n});\\n\")\n\texpectPrinted(t,\n\t\t\"(function* foo() {})\",\n\t\t\"(function* foo() {\\n});\\n\")\n\n\texpectPrinted(t,\n\t\t\"class Foo { *foo() {} }\",\n\t\t\"class Foo {\\n  *foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t,\n\t\t\"class Foo { static *foo() {} }\",\n\t\t\"class Foo {\\n  static *foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t,\n\t\t\"class Foo { *[foo]() {} }\",\n\t\t\"class Foo {\\n  *[foo]() {\\n  }\\n}\\n\")\n\texpectPrinted(t,\n\t\t\"class Foo { static *[foo]() {} }\",\n\t\t\"class Foo {\\n  static *[foo]() {\\n  }\\n}\\n\")\n\n\texpectPrinted(t,\n\t\t\"(class { *foo() {} })\",\n\t\t\"(class {\\n  *foo() {\\n  }\\n});\\n\")\n\texpectPrinted(t,\n\t\t\"(class { static *foo() {} })\",\n\t\t\"(class {\\n  static *foo() {\\n  }\\n});\\n\")\n\texpectPrinted(t,\n\t\t\"(class { *[foo]() {} })\",\n\t\t\"(class {\\n  *[foo]() {\\n  }\\n});\\n\")\n\texpectPrinted(t,\n\t\t\"(class { static *[foo]() {} })\",\n\t\t\"(class {\\n  static *[foo]() {\\n  }\\n});\\n\")\n}\n\nfunc TestArrow(t *testing.T) {\n\texpectPrinted(t, \"() => {}\", \"() => {\\n};\\n\")\n\texpectPrinted(t, \"x => (x, 0)\", \"(x) => (x, 0);\\n\")\n\texpectPrinted(t, \"x => {y}\", \"(x) => {\\n  y;\\n};\\n\")\n\texpectPrinted(t,\n\t\t\"(a = (b, c), ...d) => {}\",\n\t\t\"(a = (b, c), ...d) => {\\n};\\n\")\n\texpectPrinted(t,\n\t\t\"({[1 + 2]: a = 3} = {[1 + 2]: 3}) => {}\",\n\t\t\"({ [1 + 2]: a = 3 } = { [1 + 2]: 3 }) => {\\n};\\n\")\n\texpectPrinted(t,\n\t\t\"([a = (1, 2), ...[b, ...c]] = [1, [2, 3]]) => {}\",\n\t\t\"([a = (1, 2), ...[b, ...c]] = [1, [2, 3]]) => {\\n};\\n\")\n\texpectPrinted(t,\n\t\t\"([] = []) => {}\",\n\t\t\"([] = []) => {\\n};\\n\")\n\texpectPrinted(t,\n\t\t\"([,] = [,]) => {}\",\n\t\t\"([,] = [,]) => {\\n};\\n\")\n\texpectPrinted(t,\n\t\t\"([,,] = [,,]) => {}\",\n\t\t\"([, ,] = [, ,]) => {\\n};\\n\")\n\texpectPrinted(t,\n\t\t\"a = () => {}\",\n\t\t\"a = () => {\\n};\\n\")\n\texpectPrinted(t,\n\t\t\"a || (() => {})\",\n\t\t\"a || (() => {\\n});\\n\")\n\texpectPrinted(t,\n\t\t\"({a = b, c = d}) => {}\",\n\t\t\"({ a = b, c = d }) => {\\n};\\n\")\n\texpectPrinted(t,\n\t\t\"([{a = b, c = d} = {}] = []) => {}\",\n\t\t\"([{ a = b, c = d } = {}] = []) => {\\n};\\n\")\n\texpectPrinted(t,\n\t\t\"({a: [b = c] = []} = {}) => {}\",\n\t\t\"({ a: [b = c] = [] } = {}) => {\\n};\\n\")\n\n\t// These are not arrow functions but initially look like one\n\texpectPrinted(t, \"(a = b, c)\", \"a = b, c;\\n\")\n\texpectPrinted(t, \"([...a = b])\", \"[...a = b];\\n\")\n\texpectPrinted(t, \"([...a, ...b])\", \"[...a, ...b];\\n\")\n\texpectPrinted(t, \"({a: b, c() {}})\", \"({ a: b, c() {\\n} });\\n\")\n\texpectPrinted(t, \"({a: b, get c() {}})\", \"({ a: b, get c() {\\n} });\\n\")\n\texpectPrinted(t, \"({a: b, set c(x) {}})\", \"({ a: b, set c(x) {\\n} });\\n\")\n}\n\nfunc TestClass(t *testing.T) {\n\texpectPrinted(t, \"class Foo extends (a, b) {}\", \"class Foo extends (a, b) {\\n}\\n\")\n\texpectPrinted(t, \"class Foo { get foo() {} }\", \"class Foo {\\n  get foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { set foo(x) {} }\", \"class Foo {\\n  set foo(x) {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static foo() {} }\", \"class Foo {\\n  static foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static get foo() {} }\", \"class Foo {\\n  static get foo() {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"class Foo { static set foo(x) {} }\", \"class Foo {\\n  static set foo(x) {\\n  }\\n}\\n\")\n}\n\nfunc TestAutoAccessors(t *testing.T) {\n\texpectPrinted(t, \"class Foo { accessor x; static accessor y }\", \"class Foo {\\n  accessor x;\\n  static accessor y;\\n}\\n\")\n\texpectPrinted(t, \"class Foo { accessor [x]; static accessor [y] }\", \"class Foo {\\n  accessor [x];\\n  static accessor [y];\\n}\\n\")\n\texpectPrintedMinify(t, \"class Foo { accessor x; static accessor y }\", \"class Foo{accessor x;static accessor y}\")\n\texpectPrintedMinify(t, \"class Foo { accessor [x]; static accessor [y] }\", \"class Foo{accessor[x];static accessor[y]}\")\n}\n\nfunc TestPrivateIdentifiers(t *testing.T) {\n\texpectPrinted(t, \"class Foo { #foo; foo() { return #foo in this } }\", \"class Foo {\\n  #foo;\\n  foo() {\\n    return #foo in this;\\n  }\\n}\\n\")\n\texpectPrintedMinify(t, \"class Foo { #foo; foo() { return #foo in this } }\", \"class Foo{#foo;foo(){return#foo in this}}\")\n}\n\nfunc TestDecorators(t *testing.T) {\n\texample := \"class Foo {\\n@w\\nw; @x x; @a1\\n@b1@b2\\n@c1@c2@c3\\ny = @y1 @y2 class {}; @a1\\n@b1@b2\\n@c1@c2@c3 z =\\n@z1\\n@z2\\nclass {}}\"\n\texpectPrinted(t, example, \"class Foo {\\n  @w\\n  w;\\n  @x x;\\n  @a1\\n  @b1 @b2\\n  @c1 @c2 @c3\\n  \"+\n\t\t\"y = @y1 @y2 class {\\n  };\\n  @a1\\n  @b1 @b2\\n  @c1 @c2 @c3 z = @z1 @z2 class {\\n  };\\n}\\n\")\n\texpectPrintedMinify(t, example, \"class Foo{@w w;@x x;@a1@b1@b2@c1@c2@c3 y=@y1@y2 class{};@a1@b1@b2@c1@c2@c3 z=@z1@z2 class{}}\")\n}\n\nfunc TestImport(t *testing.T) {\n\texpectPrinted(t, \"import('path');\", \"import(\\\"path\\\");\\n\") // The semicolon must not be a separate statement\n\n\t// Test preservation of Webpack-specific comments\n\texpectPrinted(t, \"import(// webpackFoo: 1\\n // webpackBar: 2\\n 'path');\", \"import(\\n  // webpackFoo: 1\\n  // webpackBar: 2\\n  \\\"path\\\"\\n);\\n\")\n\texpectPrinted(t, \"import(// webpackFoo: 1\\n // webpackBar: 2\\n 'path', {type: 'module'});\", \"import(\\n  // webpackFoo: 1\\n  // webpackBar: 2\\n  \\\"path\\\",\\n  { type: \\\"module\\\" }\\n);\\n\")\n\texpectPrinted(t, \"import(/* webpackFoo: 1 */ /* webpackBar: 2 */ 'path');\", \"import(\\n  /* webpackFoo: 1 */\\n  /* webpackBar: 2 */\\n  \\\"path\\\"\\n);\\n\")\n\texpectPrinted(t, \"import(/* webpackFoo: 1 */ /* webpackBar: 2 */ 'path', {type: 'module'});\", \"import(\\n  /* webpackFoo: 1 */\\n  /* webpackBar: 2 */\\n  \\\"path\\\",\\n  { type: \\\"module\\\" }\\n);\\n\")\n\texpectPrinted(t, \"import(\\n    /* multi\\n     * line\\n     * webpackBar: */ 'path');\", \"import(\\n  /* multi\\n   * line\\n   * webpackBar: */\\n  \\\"path\\\"\\n);\\n\")\n\texpectPrinted(t, \"import(/* webpackFoo: 1 */ 'path' /* webpackBar:2 */);\", \"import(\\n  /* webpackFoo: 1 */\\n  \\\"path\\\"\\n  /* webpackBar:2 */\\n);\\n\")\n\texpectPrinted(t, \"import(/* webpackFoo: 1 */ 'path' /* webpackBar:2 */ ,);\", \"import(\\n  /* webpackFoo: 1 */\\n  \\\"path\\\"\\n);\\n\") // Not currently handled\n\texpectPrinted(t, \"import(/* webpackFoo: 1 */ 'path', /* webpackBar:2 */ );\", \"import(\\n  /* webpackFoo: 1 */\\n  \\\"path\\\"\\n  /* webpackBar:2 */\\n);\\n\")\n\texpectPrinted(t, \"import(/* webpackFoo: 1 */ 'path', { type: 'module' } /* webpackBar:2 */ );\", \"import(\\n  /* webpackFoo: 1 */\\n  \\\"path\\\",\\n  { type: \\\"module\\\" }\\n  /* webpackBar:2 */\\n);\\n\")\n\texpectPrinted(t, \"import(new URL('path', /* webpackFoo: these can go anywhere */ import.meta.url))\",\n\t\t\"import(new URL(\\n  \\\"path\\\",\\n  /* webpackFoo: these can go anywhere */\\n  import.meta.url\\n));\\n\")\n\n\t// See: https://github.com/tc39/proposal-defer-import-eval\n\texpectPrintedMinify(t, \"import defer * as foo from 'bar'\", \"import defer*as foo from\\\"bar\\\";\")\n\n\t// See: https://github.com/tc39/proposal-source-phase-imports\n\texpectPrintedMinify(t, \"import source foo from 'bar'\", \"import source foo from\\\"bar\\\";\")\n}\n\nfunc TestExportDefault(t *testing.T) {\n\texpectPrinted(t, \"export default function() {}\", \"export default function() {\\n}\\n\")\n\texpectPrinted(t, \"export default function foo() {}\", \"export default function foo() {\\n}\\n\")\n\texpectPrinted(t, \"export default async function() {}\", \"export default async function() {\\n}\\n\")\n\texpectPrinted(t, \"export default async function foo() {}\", \"export default async function foo() {\\n}\\n\")\n\texpectPrinted(t, \"export default class {}\", \"export default class {\\n}\\n\")\n\texpectPrinted(t, \"export default class foo {}\", \"export default class foo {\\n}\\n\")\n\n\texpectPrinted(t, \"export default (function() {})\", \"export default (function() {\\n});\\n\")\n\texpectPrinted(t, \"export default (function foo() {})\", \"export default (function foo() {\\n});\\n\")\n\texpectPrinted(t, \"export default (async function() {})\", \"export default (async function() {\\n});\\n\")\n\texpectPrinted(t, \"export default (async function foo() {})\", \"export default (async function foo() {\\n});\\n\")\n\texpectPrinted(t, \"export default (class {})\", \"export default (class {\\n});\\n\")\n\texpectPrinted(t, \"export default (class foo {})\", \"export default (class foo {\\n});\\n\")\n\n\texpectPrinted(t, \"export default (function() {}.toString())\", \"export default (function() {\\n}).toString();\\n\")\n\texpectPrinted(t, \"export default (function foo() {}.toString())\", \"export default (function foo() {\\n}).toString();\\n\")\n\texpectPrinted(t, \"export default (async function() {}.toString())\", \"export default (async function() {\\n}).toString();\\n\")\n\texpectPrinted(t, \"export default (async function foo() {}.toString())\", \"export default (async function foo() {\\n}).toString();\\n\")\n\texpectPrinted(t, \"export default (class {}.toString())\", \"export default (class {\\n}).toString();\\n\")\n\texpectPrinted(t, \"export default (class foo {}.toString())\", \"export default (class foo {\\n}).toString();\\n\")\n\n\texpectPrintedMinify(t, \"export default function() {}\", \"export default function(){}\")\n\texpectPrintedMinify(t, \"export default function foo() {}\", \"export default function foo(){}\")\n\texpectPrintedMinify(t, \"export default async function() {}\", \"export default async function(){}\")\n\texpectPrintedMinify(t, \"export default async function foo() {}\", \"export default async function foo(){}\")\n\texpectPrintedMinify(t, \"export default class {}\", \"export default class{}\")\n\texpectPrintedMinify(t, \"export default class foo {}\", \"export default class foo{}\")\n}\n\nfunc TestWhitespace(t *testing.T) {\n\texpectPrinted(t, \"- -x\", \"- -x;\\n\")\n\texpectPrinted(t, \"+ -x\", \"+-x;\\n\")\n\texpectPrinted(t, \"- +x\", \"-+x;\\n\")\n\texpectPrinted(t, \"+ +x\", \"+ +x;\\n\")\n\texpectPrinted(t, \"- --x\", \"- --x;\\n\")\n\texpectPrinted(t, \"+ --x\", \"+--x;\\n\")\n\texpectPrinted(t, \"- ++x\", \"-++x;\\n\")\n\texpectPrinted(t, \"+ ++x\", \"+ ++x;\\n\")\n\n\texpectPrintedMinify(t, \"- -x\", \"- -x;\")\n\texpectPrintedMinify(t, \"+ -x\", \"+-x;\")\n\texpectPrintedMinify(t, \"- +x\", \"-+x;\")\n\texpectPrintedMinify(t, \"+ +x\", \"+ +x;\")\n\texpectPrintedMinify(t, \"- --x\", \"- --x;\")\n\texpectPrintedMinify(t, \"+ --x\", \"+--x;\")\n\texpectPrintedMinify(t, \"- ++x\", \"-++x;\")\n\texpectPrintedMinify(t, \"+ ++x\", \"+ ++x;\")\n\n\texpectPrintedMinify(t, \"x - --y\", \"x- --y;\")\n\texpectPrintedMinify(t, \"x + --y\", \"x+--y;\")\n\texpectPrintedMinify(t, \"x - ++y\", \"x-++y;\")\n\texpectPrintedMinify(t, \"x + ++y\", \"x+ ++y;\")\n\n\texpectPrintedMinify(t, \"x-- > y\", \"x-- >y;\")\n\texpectPrintedMinify(t, \"x < !--y\", \"x<! --y;\")\n\texpectPrintedMinify(t, \"x > !--y\", \"x>!--y;\")\n\texpectPrintedMinify(t, \"!--y\", \"!--y;\")\n\n\texpectPrintedMinify(t, \"1 + -0\", \"1+-0;\")\n\texpectPrintedMinify(t, \"1 - -0\", \"1- -0;\")\n\texpectPrintedMinify(t, \"1 + -Infinity\", \"1+-Infinity;\")\n\texpectPrintedMinify(t, \"1 - -Infinity\", \"1- -Infinity;\")\n\n\texpectPrintedMinify(t, \"/x/ / /y/\", \"/x// /y/;\")\n\texpectPrintedMinify(t, \"/x/ + Foo\", \"/x/+Foo;\")\n\texpectPrintedMinify(t, \"/x/ instanceof Foo\", \"/x/ instanceof Foo;\")\n\texpectPrintedMinify(t, \"[x] instanceof Foo\", \"[x]instanceof Foo;\")\n\n\texpectPrintedMinify(t, \"throw x\", \"throw x;\")\n\texpectPrintedMinify(t, \"throw typeof x\", \"throw typeof x;\")\n\texpectPrintedMinify(t, \"throw delete x\", \"throw delete x;\")\n\texpectPrintedMinify(t, \"throw function(){}\", \"throw function(){};\")\n\n\texpectPrintedMinify(t, \"x in function(){}\", \"x in function(){};\")\n\texpectPrintedMinify(t, \"x instanceof function(){}\", \"x instanceof function(){};\")\n\texpectPrintedMinify(t, \"π in function(){}\", \"π in function(){};\")\n\texpectPrintedMinify(t, \"π instanceof function(){}\", \"π instanceof function(){};\")\n\n\texpectPrintedMinify(t, \"()=>({})\", \"()=>({});\")\n\texpectPrintedMinify(t, \"()=>({}[1])\", \"()=>({})[1];\")\n\texpectPrintedMinify(t, \"()=>({}+0)\", \"()=>\\\"[object Object]0\\\";\")\n\texpectPrintedMinify(t, \"()=>function(){}\", \"()=>function(){};\")\n\n\texpectPrintedMinify(t, \"(function(){})\", \"(function(){});\")\n\texpectPrintedMinify(t, \"(class{})\", \"(class{});\")\n\texpectPrintedMinify(t, \"({})\", \"({});\")\n}\n\nfunc TestMangle(t *testing.T) {\n\texpectPrintedMangle(t, \"let x = '\\\\n'\", \"let x = `\\n`;\\n\")\n\texpectPrintedMangle(t, \"let x = `\\n`\", \"let x = `\\n`;\\n\")\n\texpectPrintedMangle(t, \"let x = '\\\\n${}'\", \"let x = \\\"\\\\n${}\\\";\\n\")\n\texpectPrintedMangle(t, \"let x = `\\n\\\\${}`\", \"let x = \\\"\\\\n${}\\\";\\n\")\n\texpectPrintedMangle(t, \"let x = `\\n\\\\${}${y}\\\\${}`\", \"let x = `\\n\\\\${}${y}\\\\${}`;\\n\")\n}\n\nfunc TestMinify(t *testing.T) {\n\texpectPrintedMinify(t, \"0.1\", \".1;\")\n\texpectPrintedMinify(t, \"1.2\", \"1.2;\")\n\n\texpectPrintedMinify(t, \"() => {}\", \"()=>{};\")\n\texpectPrintedMinify(t, \"(a) => {}\", \"a=>{};\")\n\texpectPrintedMinify(t, \"(...a) => {}\", \"(...a)=>{};\")\n\texpectPrintedMinify(t, \"(a = 0) => {}\", \"(a=0)=>{};\")\n\texpectPrintedMinify(t, \"(a, b) => {}\", \"(a,b)=>{};\")\n\n\texpectPrinted(t, \"true ** 2\", \"true ** 2;\\n\")\n\texpectPrinted(t, \"false ** 2\", \"false ** 2;\\n\")\n\texpectPrintedMinify(t, \"true ** 2\", \"true**2;\")\n\texpectPrintedMinify(t, \"false ** 2\", \"false**2;\")\n\texpectPrintedMangle(t, \"true ** 2\", \"(!0) ** 2;\\n\")\n\texpectPrintedMangle(t, \"false ** 2\", \"(!1) ** 2;\\n\")\n\n\texpectPrintedMinify(t, \"import a from 'path'\", \"import a from\\\"path\\\";\")\n\texpectPrintedMinify(t, \"import * as ns from 'path'\", \"import*as ns from\\\"path\\\";\")\n\texpectPrintedMinify(t, \"import {a, b as c} from 'path'\", \"import{a,b as c}from\\\"path\\\";\")\n\texpectPrintedMinify(t, \"import {a, ' ' as c} from 'path'\", \"import{a,\\\" \\\"as c}from\\\"path\\\";\")\n\n\texpectPrintedMinify(t, \"export * as ns from 'path'\", \"export*as ns from\\\"path\\\";\")\n\texpectPrintedMinify(t, \"export * as ' ' from 'path'\", \"export*as\\\" \\\"from\\\"path\\\";\")\n\texpectPrintedMinify(t, \"export {a, b as c} from 'path'\", \"export{a,b as c}from\\\"path\\\";\")\n\texpectPrintedMinify(t, \"export {' ', '-' as ';'} from 'path'\", \"export{\\\" \\\",\\\"-\\\"as\\\";\\\"}from\\\"path\\\";\")\n\texpectPrintedMinify(t, \"let a, b; export {a, b as c}\", \"let a,b;export{a,b as c};\")\n\texpectPrintedMinify(t, \"let a, b; export {a, b as ' '}\", \"let a,b;export{a,b as\\\" \\\"};\")\n\n\t// Print some strings using template literals when minifying\n\texpectPrinted(t, \"x = '\\\\n'\", \"x = \\\"\\\\n\\\";\\n\")\n\texpectPrintedMangle(t, \"x = '\\\\n'\", \"x = `\\n`;\\n\")\n\texpectPrintedMangle(t, \"x = {'\\\\n': 0}\", \"x = { \\\"\\\\n\\\": 0 };\\n\")\n\texpectPrintedMangle(t, \"x = class{'\\\\n' = 0}\", \"x = class {\\n  \\\"\\\\n\\\" = 0;\\n};\\n\")\n\texpectPrintedMangle(t, \"class Foo{'\\\\n' = 0}\", \"class Foo {\\n  \\\"\\\\n\\\" = 0;\\n}\\n\")\n\n\t// Special identifiers must not be minified\n\texpectPrintedMinify(t, \"exports\", \"exports;\")\n\texpectPrintedMinify(t, \"require\", \"require;\")\n\texpectPrintedMinify(t, \"module\", \"module;\")\n\n\t// Comment statements must not affect their surroundings when minified\n\texpectPrintedMinify(t, \"//!single\\nthrow 1 + 2\", \"//!single\\nthrow 1+2;\")\n\texpectPrintedMinify(t, \"/*!multi-\\nline*/\\nthrow 1 + 2\", \"/*!multi-\\nline*/throw 1+2;\")\n}\n\nfunc TestES5(t *testing.T) {\n\texpectPrintedTargetMangle(t, 5, \"foo('a\\\\n\\\\n\\\\nb')\", \"foo(\\\"a\\\\n\\\\n\\\\nb\\\");\\n\")\n\texpectPrintedTargetMangle(t, 2015, \"foo('a\\\\n\\\\n\\\\nb')\", \"foo(`a\\n\\n\\nb`);\\n\")\n\n\texpectPrintedTarget(t, 5, \"foo({a, b})\", \"foo({ a: a, b: b });\\n\")\n\texpectPrintedTarget(t, 2015, \"foo({a, b})\", \"foo({ a, b });\\n\")\n\n\texpectPrintedTarget(t, 5, \"x => x\", \"(function(x) {\\n  return x;\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"x => x\", \"(x) => x;\\n\")\n\n\texpectPrintedTarget(t, 5, \"() => {}\", \"(function() {\\n});\\n\")\n\texpectPrintedTarget(t, 2015, \"() => {}\", \"() => {\\n};\\n\")\n\n\texpectPrintedTargetMinify(t, 5, \"x => x\", \"(function(x){return x});\")\n\texpectPrintedTargetMinify(t, 2015, \"x => x\", \"x=>x;\")\n\n\texpectPrintedTargetMinify(t, 5, \"() => {}\", \"(function(){});\")\n\texpectPrintedTargetMinify(t, 2015, \"() => {}\", \"()=>{};\")\n}\n\nfunc TestASCIIOnly(t *testing.T) {\n\texpectPrinted(t, \"let π = 'π'\", \"let π = \\\"π\\\";\\n\")\n\texpectPrinted(t, \"let π_ = 'π'\", \"let π_ = \\\"π\\\";\\n\")\n\texpectPrinted(t, \"let _π = 'π'\", \"let _π = \\\"π\\\";\\n\")\n\texpectPrintedASCII(t, \"let π = 'π'\", \"let \\\\u03C0 = \\\"\\\\u03C0\\\";\\n\")\n\texpectPrintedASCII(t, \"let π_ = 'π'\", \"let \\\\u03C0_ = \\\"\\\\u03C0\\\";\\n\")\n\texpectPrintedASCII(t, \"let _π = 'π'\", \"let _\\\\u03C0 = \\\"\\\\u03C0\\\";\\n\")\n\n\texpectPrinted(t, \"let 貓 = '🐈'\", \"let 貓 = \\\"🐈\\\";\\n\")\n\texpectPrinted(t, \"let 貓abc = '🐈'\", \"let 貓abc = \\\"🐈\\\";\\n\")\n\texpectPrinted(t, \"let abc貓 = '🐈'\", \"let abc貓 = \\\"🐈\\\";\\n\")\n\texpectPrintedASCII(t, \"let 貓 = '🐈'\", \"let \\\\u8C93 = \\\"\\\\u{1F408}\\\";\\n\")\n\texpectPrintedASCII(t, \"let 貓abc = '🐈'\", \"let \\\\u8C93abc = \\\"\\\\u{1F408}\\\";\\n\")\n\texpectPrintedASCII(t, \"let abc貓 = '🐈'\", \"let abc\\\\u8C93 = \\\"\\\\u{1F408}\\\";\\n\")\n\n\t// Test a character outside the BMP\n\texpectPrinted(t, \"var 𐀀\", \"var 𐀀;\\n\")\n\texpectPrinted(t, \"var \\\\u{10000}\", \"var 𐀀;\\n\")\n\texpectPrintedASCII(t, \"var 𐀀\", \"var \\\\u{10000};\\n\")\n\texpectPrintedASCII(t, \"var \\\\u{10000}\", \"var \\\\u{10000};\\n\")\n\texpectPrintedTargetASCII(t, 2015, \"'𐀀'\", \"\\\"\\\\u{10000}\\\";\\n\")\n\texpectPrintedTargetASCII(t, 5, \"'𐀀'\", \"\\\"\\\\uD800\\\\uDC00\\\";\\n\")\n\texpectPrintedTargetASCII(t, 2015, \"x.𐀀\", \"x[\\\"\\\\u{10000}\\\"];\\n\")\n\texpectPrintedTargetASCII(t, 5, \"x.𐀀\", \"x[\\\"\\\\uD800\\\\uDC00\\\"];\\n\")\n\n\t// Escapes should use consistent case\n\texpectPrintedASCII(t, \"var \\\\u{100a} = {\\\\u100A: '\\\\u100A'}\", \"var \\\\u100A = { \\\\u100A: \\\"\\\\u100A\\\" };\\n\")\n\texpectPrintedASCII(t, \"var \\\\u{1000a} = {\\\\u{1000A}: '\\\\u{1000A}'}\", \"var \\\\u{1000A} = { \\\"\\\\u{1000A}\\\": \\\"\\\\u{1000A}\\\" };\\n\")\n\n\t// These characters should always be escaped\n\texpectPrinted(t, \"let x = '\\u2028'\", \"let x = \\\"\\\\u2028\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\u2029'\", \"let x = \\\"\\\\u2029\\\";\\n\")\n\texpectPrinted(t, \"let x = '\\uFEFF'\", \"let x = \\\"\\\\uFEFF\\\";\\n\")\n\n\t// There should still be a space before \"extends\"\n\texpectPrintedASCII(t, \"class 𐀀 extends π {}\", \"class \\\\u{10000} extends \\\\u03C0 {\\n}\\n\")\n\texpectPrintedASCII(t, \"(class 𐀀 extends π {})\", \"(class \\\\u{10000} extends \\\\u03C0 {\\n});\\n\")\n\texpectPrintedMinifyASCII(t, \"class 𐀀 extends π {}\", \"class \\\\u{10000} extends \\\\u03C0{}\")\n\texpectPrintedMinifyASCII(t, \"(class 𐀀 extends π {})\", \"(class \\\\u{10000} extends \\\\u03C0{});\")\n}\n\nfunc TestJSX(t *testing.T) {\n\texpectPrintedJSX(t, \"<a/>\", \"<a />;\\n\")\n\texpectPrintedJSX(t, \"<A/>\", \"<A />;\\n\")\n\texpectPrintedJSX(t, \"<a.b/>\", \"<a.b />;\\n\")\n\texpectPrintedJSX(t, \"<A.B/>\", \"<A.B />;\\n\")\n\texpectPrintedJSX(t, \"<a-b/>\", \"<a-b />;\\n\")\n\texpectPrintedJSX(t, \"<a:b/>\", \"<a:b />;\\n\")\n\texpectPrintedJSX(t, \"<a></a>\", \"<a />;\\n\")\n\texpectPrintedJSX(t, \"<a b></a>\", \"<a b />;\\n\")\n\n\texpectPrintedJSX(t, \"<a b={true}></a>\", \"<a b={true} />;\\n\")\n\texpectPrintedJSX(t, \"<a b='x'></a>\", \"<a b='x' />;\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"x\\\"></a>\", \"<a b=\\\"x\\\" />;\\n\")\n\texpectPrintedJSX(t, \"<a b={'x'}></a>\", \"<a b={\\\"x\\\"} />;\\n\")\n\texpectPrintedJSX(t, \"<a b={`'`}></a>\", \"<a b={`'`} />;\\n\")\n\texpectPrintedJSX(t, \"<a b={`\\\"`}></a>\", \"<a b={`\\\"`} />;\\n\")\n\texpectPrintedJSX(t, \"<a b={`'\\\"`}></a>\", \"<a b={`'\\\"`} />;\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"&quot;\\\"></a>\", \"<a b=\\\"&quot;\\\" />;\\n\")\n\texpectPrintedJSX(t, \"<a b=\\\"&amp;\\\"></a>\", \"<a b=\\\"&amp;\\\" />;\\n\")\n\n\texpectPrintedJSX(t, \"<a>x</a>\", \"<a>x</a>;\\n\")\n\texpectPrintedJSX(t, \"<a>x\\ny</a>\", \"<a>x\\ny</a>;\\n\")\n\texpectPrintedJSX(t, \"<a>{'x'}{'y'}</a>\", \"<a>{\\\"x\\\"}{\\\"y\\\"}</a>;\\n\")\n\texpectPrintedJSX(t, \"<a> x</a>\", \"<a> x</a>;\\n\")\n\texpectPrintedJSX(t, \"<a>x </a>\", \"<a>x </a>;\\n\")\n\texpectPrintedJSX(t, \"<a>&#10;</a>\", \"<a>&#10;</a>;\\n\")\n\texpectPrintedJSX(t, \"<a>&amp;</a>\", \"<a>&amp;</a>;\\n\")\n\texpectPrintedJSX(t, \"<a>&lt;</a>\", \"<a>&lt;</a>;\\n\")\n\texpectPrintedJSX(t, \"<a>&gt;</a>\", \"<a>&gt;</a>;\\n\")\n\texpectPrintedJSX(t, \"<a>&#123;</a>\", \"<a>&#123;</a>;\\n\")\n\texpectPrintedJSX(t, \"<a>&#125;</a>\", \"<a>&#125;</a>;\\n\")\n\n\texpectPrintedJSX(t, \"<a><x/></a>\", \"<a><x /></a>;\\n\")\n\texpectPrintedJSX(t, \"<a><x/><y/></a>\", \"<a><x /><y /></a>;\\n\")\n\texpectPrintedJSX(t, \"<a>b<c/>d</a>\", \"<a>b<c />d</a>;\\n\")\n\n\texpectPrintedJSX(t, \"<></>\", \"<></>;\\n\")\n\texpectPrintedJSX(t, \"<>x<y/>z</>\", \"<>x<y />z</>;\\n\")\n\n\t// JSX elements as JSX attribute values\n\texpectPrintedJSX(t, \"<a b=<c/>/>\", \"<a b=<c /> />;\\n\")\n\texpectPrintedJSX(t, \"<a b=<>c</>/>\", \"<a b=<>c</> />;\\n\")\n\texpectPrintedJSX(t, \"<a b=<>{c}</>/>\", \"<a b=<>{c}</> />;\\n\")\n\texpectPrintedJSX(t, \"<a b={<c/>}/>\", \"<a b={<c />} />;\\n\")\n\texpectPrintedJSX(t, \"<a b={<>c</>}/>\", \"<a b={<>c</>} />;\\n\")\n\texpectPrintedJSX(t, \"<a b={<>{c}</>}/>\", \"<a b={<>{c}</>} />;\\n\")\n\n\t// These can't be escaped because JSX lacks a syntax for escapes\n\texpectPrintedJSXASCII(t, \"<π/>\", \"<π />;\\n\")\n\texpectPrintedJSXASCII(t, \"<π.𐀀/>\", \"<π.𐀀 />;\\n\")\n\texpectPrintedJSXASCII(t, \"<𐀀.π/>\", \"<𐀀.π />;\\n\")\n\texpectPrintedJSXASCII(t, \"<π>x</π>\", \"<π>x</π>;\\n\")\n\texpectPrintedJSXASCII(t, \"<𐀀>x</𐀀>\", \"<𐀀>x</𐀀>;\\n\")\n\texpectPrintedJSXASCII(t, \"<a π/>\", \"<a π />;\\n\")\n\texpectPrintedJSXASCII(t, \"<a 𐀀/>\", \"<a 𐀀 />;\\n\")\n\n\t// JSX text is deliberately not printed as ASCII when JSX preservation is\n\t// enabled. This is because:\n\t//\n\t// a) The JSX specification doesn't say how JSX text is supposed to be interpreted\n\t// b) Enabling JSX preservation means that JSX will be transformed again anyway\n\t// c) People do very weird/custom things with JSX that \"preserve\" shouldn't break\n\t//\n\t// See also: https://github.com/evanw/esbuild/issues/3605\n\texpectPrintedJSXASCII(t, \"<a b='π'/>\", \"<a b='π' />;\\n\")\n\texpectPrintedJSXASCII(t, \"<a b='𐀀'/>\", \"<a b='𐀀' />;\\n\")\n\texpectPrintedJSXASCII(t, \"<a>π</a>\", \"<a>π</a>;\\n\")\n\texpectPrintedJSXASCII(t, \"<a>𐀀</a>\", \"<a>𐀀</a>;\\n\")\n\n\texpectPrintedJSXMinify(t, \"<a b c={x,y} d='true'/>\", \"<a b c={(x,y)}d='true'/>;\")\n\texpectPrintedJSXMinify(t, \"<a><b/><c/></a>\", \"<a><b/><c/></a>;\")\n\texpectPrintedJSXMinify(t, \"<a> x <b/> y </a>\", \"<a> x <b/> y </a>;\")\n\texpectPrintedJSXMinify(t, \"<a>{' x '}{'<b/>'}{' y '}</a>\", \"<a>{\\\" x \\\"}{\\\"<b/>\\\"}{\\\" y \\\"}</a>;\")\n}\n\nfunc TestJSXSingleLine(t *testing.T) {\n\texpectPrintedJSX(t, \"<x/>\", \"<x />;\\n\")\n\texpectPrintedJSX(t, \"<x y/>\", \"<x y />;\\n\")\n\texpectPrintedJSX(t, \"<x\\n/>\", \"<x />;\\n\")\n\texpectPrintedJSX(t, \"<x\\ny/>\", \"<x\\n  y\\n/>;\\n\")\n\texpectPrintedJSX(t, \"<x y\\n/>\", \"<x\\n  y\\n/>;\\n\")\n\texpectPrintedJSX(t, \"<x\\n{...y}/>\", \"<x\\n  {...y}\\n/>;\\n\")\n\n\texpectPrintedJSXMinify(t, \"<x/>\", \"<x/>;\")\n\texpectPrintedJSXMinify(t, \"<x y/>\", \"<x y/>;\")\n\texpectPrintedJSXMinify(t, \"<x\\n/>\", \"<x/>;\")\n\texpectPrintedJSXMinify(t, \"<x\\ny/>\", \"<x y/>;\")\n\texpectPrintedJSXMinify(t, \"<x y\\n/>\", \"<x y/>;\")\n\texpectPrintedJSXMinify(t, \"<x\\n{...y}/>\", \"<x{...y}/>;\")\n}\n\nfunc TestAvoidSlashScript(t *testing.T) {\n\t// Positive cases\n\texpectPrinted(t, \"x = '</script'\", \"x = \\\"<\\\\/script\\\";\\n\")\n\texpectPrinted(t, \"x = `</script`\", \"x = `<\\\\/script`;\\n\")\n\texpectPrinted(t, \"x = `</SCRIPT`\", \"x = `<\\\\/SCRIPT`;\\n\")\n\texpectPrinted(t, \"x = `</ScRiPt`\", \"x = `<\\\\/ScRiPt`;\\n\")\n\texpectPrinted(t, \"x = `</script${y}`\", \"x = `<\\\\/script${y}`;\\n\")\n\texpectPrinted(t, \"x = `${y}</script`\", \"x = `${y}<\\\\/script`;\\n\")\n\texpectPrintedMinify(t, \"x = 1 < /script/.exec(y).length\", \"x=1< /script/.exec(y).length;\")\n\texpectPrintedMinify(t, \"x = 1 < /SCRIPT/.exec(y).length\", \"x=1< /SCRIPT/.exec(y).length;\")\n\texpectPrintedMinify(t, \"x = 1 < /ScRiPt/.exec(y).length\", \"x=1< /ScRiPt/.exec(y).length;\")\n\texpectPrintedMinify(t, \"x = 1 << /script/.exec(y).length\", \"x=1<< /script/.exec(y).length;\")\n\texpectPrinted(t, \"//! </script\\n//! >/script\\n//! /script\", \"//! <\\\\/script\\n//! >/script\\n//! /script\\n\")\n\texpectPrinted(t, \"//! </SCRIPT\\n//! >/SCRIPT\\n//! /SCRIPT\", \"//! <\\\\/SCRIPT\\n//! >/SCRIPT\\n//! /SCRIPT\\n\")\n\texpectPrinted(t, \"//! </ScRiPt\\n//! >/ScRiPt\\n//! /ScRiPt\", \"//! <\\\\/ScRiPt\\n//! >/ScRiPt\\n//! /ScRiPt\\n\")\n\texpectPrinted(t, \"/*! </script \\n </script */\", \"/*! <\\\\/script \\n <\\\\/script */\\n\")\n\texpectPrinted(t, \"/*! </SCRIPT \\n </SCRIPT */\", \"/*! <\\\\/SCRIPT \\n <\\\\/SCRIPT */\\n\")\n\texpectPrinted(t, \"/*! </ScRiPt \\n </ScRiPt */\", \"/*! <\\\\/ScRiPt \\n <\\\\/ScRiPt */\\n\")\n\texpectPrinted(t, \"String.raw`</script`\",\n\t\t\"import { __template } from \\\"<runtime>\\\";\\nvar _a;\\nString.raw(_a || (_a = __template([\\\"<\\\\/script\\\"])));\\n\")\n\texpectPrinted(t, \"String.raw`</script${a}`\",\n\t\t\"import { __template } from \\\"<runtime>\\\";\\nvar _a;\\nString.raw(_a || (_a = __template([\\\"<\\\\/script\\\", \\\"\\\"])), a);\\n\")\n\texpectPrinted(t, \"String.raw`${a}</script`\",\n\t\t\"import { __template } from \\\"<runtime>\\\";\\nvar _a;\\nString.raw(_a || (_a = __template([\\\"\\\", \\\"<\\\\/script\\\"])), a);\\n\")\n\texpectPrinted(t, \"String.raw`</SCRIPT`\",\n\t\t\"import { __template } from \\\"<runtime>\\\";\\nvar _a;\\nString.raw(_a || (_a = __template([\\\"<\\\\/SCRIPT\\\"])));\\n\")\n\texpectPrinted(t, \"String.raw`</ScRiPt`\",\n\t\t\"import { __template } from \\\"<runtime>\\\";\\nvar _a;\\nString.raw(_a || (_a = __template([\\\"<\\\\/ScRiPt\\\"])));\\n\")\n\n\t// Negative cases\n\texpectPrinted(t, \"x = '</'\", \"x = \\\"</\\\";\\n\")\n\texpectPrinted(t, \"x = '</ script'\", \"x = \\\"</ script\\\";\\n\")\n\texpectPrinted(t, \"x = '< /script'\", \"x = \\\"< /script\\\";\\n\")\n\texpectPrinted(t, \"x = '/script>'\", \"x = \\\"/script>\\\";\\n\")\n\texpectPrinted(t, \"x = '<script>'\", \"x = \\\"<script>\\\";\\n\")\n\texpectPrintedMinify(t, \"x = 1 < / script/.exec(y).length\", \"x=1</ script/.exec(y).length;\")\n\texpectPrintedMinify(t, \"x = 1 << / script/.exec(y).length\", \"x=1<</ script/.exec(y).length;\")\n}\n\nfunc TestInfinity(t *testing.T) {\n\texpectPrinted(t, \"x = Infinity\", \"x = Infinity;\\n\")\n\texpectPrinted(t, \"x = -Infinity\", \"x = -Infinity;\\n\")\n\texpectPrinted(t, \"x = (Infinity).toString\", \"x = Infinity.toString;\\n\")\n\texpectPrinted(t, \"x = (-Infinity).toString\", \"x = (-Infinity).toString;\\n\")\n\texpectPrinted(t, \"x = (Infinity) ** 2\", \"x = Infinity ** 2;\\n\")\n\texpectPrinted(t, \"x = (-Infinity) ** 2\", \"x = (-Infinity) ** 2;\\n\")\n\texpectPrinted(t, \"x = ~Infinity\", \"x = ~Infinity;\\n\")\n\texpectPrinted(t, \"x = ~-Infinity\", \"x = ~-Infinity;\\n\")\n\texpectPrinted(t, \"x = Infinity * y\", \"x = Infinity * y;\\n\")\n\texpectPrinted(t, \"x = Infinity / y\", \"x = Infinity / y;\\n\")\n\texpectPrinted(t, \"x = y * Infinity\", \"x = y * Infinity;\\n\")\n\texpectPrinted(t, \"x = y / Infinity\", \"x = y / Infinity;\\n\")\n\texpectPrinted(t, \"throw Infinity\", \"throw Infinity;\\n\")\n\n\texpectPrintedMinify(t, \"x = Infinity\", \"x=Infinity;\")\n\texpectPrintedMinify(t, \"x = -Infinity\", \"x=-Infinity;\")\n\texpectPrintedMinify(t, \"x = (Infinity).toString\", \"x=Infinity.toString;\")\n\texpectPrintedMinify(t, \"x = (-Infinity).toString\", \"x=(-Infinity).toString;\")\n\texpectPrintedMinify(t, \"x = (Infinity) ** 2\", \"x=Infinity**2;\")\n\texpectPrintedMinify(t, \"x = (-Infinity) ** 2\", \"x=(-Infinity)**2;\")\n\texpectPrintedMinify(t, \"x = ~Infinity\", \"x=~Infinity;\")\n\texpectPrintedMinify(t, \"x = ~-Infinity\", \"x=~-Infinity;\")\n\texpectPrintedMinify(t, \"x = Infinity * y\", \"x=Infinity*y;\")\n\texpectPrintedMinify(t, \"x = Infinity / y\", \"x=Infinity/y;\")\n\texpectPrintedMinify(t, \"x = y * Infinity\", \"x=y*Infinity;\")\n\texpectPrintedMinify(t, \"x = y / Infinity\", \"x=y/Infinity;\")\n\texpectPrintedMinify(t, \"throw Infinity\", \"throw Infinity;\")\n\n\texpectPrintedMangle(t, \"x = Infinity\", \"x = 1 / 0;\\n\")\n\texpectPrintedMangle(t, \"x = -Infinity\", \"x = -1 / 0;\\n\")\n\texpectPrintedMangle(t, \"x = (Infinity).toString\", \"x = (1 / 0).toString;\\n\")\n\texpectPrintedMangle(t, \"x = (-Infinity).toString\", \"x = (-1 / 0).toString;\\n\")\n\texpectPrintedMangle(t, \"x = Infinity ** 2\", \"x = (1 / 0) ** 2;\\n\")\n\texpectPrintedMangle(t, \"x = (-Infinity) ** 2\", \"x = (-1 / 0) ** 2;\\n\")\n\texpectPrintedMangle(t, \"x = Infinity * y\", \"x = 1 / 0 * y;\\n\")\n\texpectPrintedMangle(t, \"x = Infinity / y\", \"x = 1 / 0 / y;\\n\")\n\texpectPrintedMangle(t, \"x = y * Infinity\", \"x = y * (1 / 0);\\n\")\n\texpectPrintedMangle(t, \"x = y / Infinity\", \"x = y / (1 / 0);\\n\")\n\texpectPrintedMangle(t, \"throw Infinity\", \"throw 1 / 0;\\n\")\n\n\texpectPrintedMangleMinify(t, \"x = Infinity\", \"x=1/0;\")\n\texpectPrintedMangleMinify(t, \"x = -Infinity\", \"x=-1/0;\")\n\texpectPrintedMangleMinify(t, \"x = (Infinity).toString\", \"x=(1/0).toString;\")\n\texpectPrintedMangleMinify(t, \"x = (-Infinity).toString\", \"x=(-1/0).toString;\")\n\texpectPrintedMangleMinify(t, \"x = Infinity ** 2\", \"x=(1/0)**2;\")\n\texpectPrintedMangleMinify(t, \"x = (-Infinity) ** 2\", \"x=(-1/0)**2;\")\n\texpectPrintedMangleMinify(t, \"x = Infinity * y\", \"x=1/0*y;\")\n\texpectPrintedMangleMinify(t, \"x = Infinity / y\", \"x=1/0/y;\")\n\texpectPrintedMangleMinify(t, \"x = y * Infinity\", \"x=y*(1/0);\")\n\texpectPrintedMangleMinify(t, \"x = y / Infinity\", \"x=y/(1/0);\")\n\texpectPrintedMangleMinify(t, \"throw Infinity\", \"throw 1/0;\")\n}\n\nfunc TestBinaryOperatorVisitor(t *testing.T) {\n\t// Make sure the inner \"/*b*/\" comment doesn't disappear due to weird binary visitor stuff\n\texpectPrintedMangle(t, \"x = (0, /*a*/ (0, /*b*/ (0, /*c*/ 1 == 2) + 3) * 4)\", \"x = /*a*/\\n/*b*/\\n(/*c*/\\n!1 + 3) * 4;\\n\")\n\n\t// Make sure deeply-nested ASTs don't cause a stack overflow\n\tx := \"x = f()\" + strings.Repeat(\" || f()\", 10_000) + \";\\n\"\n\texpectPrinted(t, x, x)\n}\n\n// See: https://github.com/tc39/proposal-explicit-resource-management\nfunc TestUsing(t *testing.T) {\n\texpectPrinted(t, \"using x = y\", \"using x = y;\\n\")\n\texpectPrinted(t, \"using x = y, z = _\", \"using x = y, z = _;\\n\")\n\texpectPrintedMinify(t, \"using x = y\", \"using x=y;\")\n\texpectPrintedMinify(t, \"using x = y, z = _\", \"using x=y,z=_;\")\n\n\texpectPrinted(t, \"await using x = y\", \"await using x = y;\\n\")\n\texpectPrinted(t, \"await using x = y, z = _\", \"await using x = y, z = _;\\n\")\n\texpectPrintedMinify(t, \"await using x = y\", \"await using x=y;\")\n\texpectPrintedMinify(t, \"await using x = y, z = _\", \"await using x=y,z=_;\")\n}\n\nfunc TestMinifyBigInt(t *testing.T) {\n\texpectPrintedTargetMangle(t, 2019, \"x = 0b100101n\", \"x = /* @__PURE__ */ BigInt(37);\\n\")\n\texpectPrintedTargetMangle(t, 2019, \"x = 0B100101n\", \"x = /* @__PURE__ */ BigInt(37);\\n\")\n\texpectPrintedTargetMangle(t, 2019, \"x = 0o76543210n\", \"x = /* @__PURE__ */ BigInt(16434824);\\n\")\n\texpectPrintedTargetMangle(t, 2019, \"x = 0O76543210n\", \"x = /* @__PURE__ */ BigInt(16434824);\\n\")\n\texpectPrintedTargetMangle(t, 2019, \"x = 0xFEDCBA9876543210n\", \"x = /* @__PURE__ */ BigInt(\\\"0xFEDCBA9876543210\\\");\\n\")\n\texpectPrintedTargetMangle(t, 2019, \"x = 0XFEDCBA9876543210n\", \"x = /* @__PURE__ */ BigInt(\\\"0XFEDCBA9876543210\\\");\\n\")\n\texpectPrintedTargetMangle(t, 2019, \"x = 0xb0ba_cafe_f00dn\", \"x = /* @__PURE__ */ BigInt(0xb0bacafef00d);\\n\")\n\texpectPrintedTargetMangle(t, 2019, \"x = 0xB0BA_CAFE_F00Dn\", \"x = /* @__PURE__ */ BigInt(0xB0BACAFEF00D);\\n\")\n\texpectPrintedTargetMangle(t, 2019, \"x = 102030405060708090807060504030201n\", \"x = /* @__PURE__ */ BigInt(\\\"102030405060708090807060504030201\\\");\\n\")\n}\n"
  },
  {
    "path": "internal/linker/debug.go",
    "content": "package linker\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/graph\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n)\n\n// Set this to true and then load the resulting metafile in \"graph-debugger.html\"\n// to debug graph information.\n//\n// This is deliberately not exposed in the final binary. It is *very* internal\n// and only exists to help debug esbuild itself. Make sure this is always set\n// back to false before committing.\nconst debugVerboseMetafile = false\n\nfunc (c *linkerContext) generateExtraDataForFileJS(sourceIndex uint32) string {\n\tif !debugVerboseMetafile {\n\t\treturn \"\"\n\t}\n\n\tfile := &c.graph.Files[sourceIndex]\n\trepr := file.InputFile.Repr.(*graph.JSRepr)\n\tsb := strings.Builder{}\n\tisFirstPartWithStmts := true\n\n\tquoteSym := func(ref ast.Ref) string {\n\t\tname := fmt.Sprintf(\"%d:%d [%s]\", ref.SourceIndex, ref.InnerIndex, c.graph.Symbols.Get(ref).OriginalName)\n\t\treturn string(helpers.QuoteForJSON(name, c.options.ASCIIOnly))\n\t}\n\n\tsb.WriteString(`,\"parts\":[`)\n\tfor partIndex, part := range repr.AST.Parts {\n\t\tif partIndex > 0 {\n\t\t\tsb.WriteByte(',')\n\t\t}\n\t\tvar isFirst bool\n\t\tcode := \"\"\n\n\t\tsb.WriteString(fmt.Sprintf(`{\"isLive\":%v`, part.IsLive))\n\t\tsb.WriteString(fmt.Sprintf(`,\"canBeRemovedIfUnused\":%v`, part.CanBeRemovedIfUnused))\n\n\t\tif partIndex == int(js_ast.NSExportPartIndex) {\n\t\t\tsb.WriteString(`,\"nsExportPartIndex\":true`)\n\t\t} else if ast.MakeIndex32(uint32(partIndex)) == repr.Meta.WrapperPartIndex {\n\t\t\tsb.WriteString(`,\"wrapperPartIndex\":true`)\n\t\t} else if len(part.Stmts) > 0 {\n\t\t\tcontents := file.InputFile.Source.Contents\n\t\t\tstart := int(part.Stmts[0].Loc.Start)\n\t\t\tif isFirstPartWithStmts {\n\t\t\t\tstart = 0\n\t\t\t\tisFirstPartWithStmts = false\n\t\t\t}\n\t\t\tend := len(contents)\n\t\t\tif partIndex+1 < len(repr.AST.Parts) {\n\t\t\t\tif nextStmts := repr.AST.Parts[partIndex+1].Stmts; len(nextStmts) > 0 {\n\t\t\t\t\tif nextStart := int(nextStmts[0].Loc.Start); nextStart >= start {\n\t\t\t\t\t\tend = int(nextStart)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tstart = moveBeforeExport(contents, start)\n\t\t\tend = moveBeforeExport(contents, end)\n\t\t\tcode = contents[start:end]\n\t\t}\n\n\t\t// importRecords\n\t\tsb.WriteString(`,\"importRecords\":[`)\n\t\tisFirst = true\n\t\tfor _, importRecordIndex := range part.ImportRecordIndices {\n\t\t\trecord := repr.AST.ImportRecords[importRecordIndex]\n\t\t\tif !record.SourceIndex.IsValid() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif isFirst {\n\t\t\t\tisFirst = false\n\t\t\t} else {\n\t\t\t\tsb.WriteByte(',')\n\t\t\t}\n\t\t\tpath := c.graph.Files[record.SourceIndex.GetIndex()].InputFile.Source.PrettyPaths.Rel\n\t\t\tsb.WriteString(fmt.Sprintf(`{\"source\":%s}`, helpers.QuoteForJSON(path, c.options.ASCIIOnly)))\n\t\t}\n\t\tsb.WriteByte(']')\n\n\t\t// declaredSymbols\n\t\tsb.WriteString(`,\"declaredSymbols\":[`)\n\t\tisFirst = true\n\t\tfor _, declSym := range part.DeclaredSymbols {\n\t\t\tif !declSym.IsTopLevel {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif isFirst {\n\t\t\t\tisFirst = false\n\t\t\t} else {\n\t\t\t\tsb.WriteByte(',')\n\t\t\t}\n\t\t\tsb.WriteString(fmt.Sprintf(`{\"name\":%s}`, quoteSym(declSym.Ref)))\n\t\t}\n\t\tsb.WriteByte(']')\n\n\t\t// symbolUses\n\t\tsb.WriteString(`,\"symbolUses\":[`)\n\t\tisFirst = true\n\t\tfor ref, uses := range part.SymbolUses {\n\t\t\tif isFirst {\n\t\t\t\tisFirst = false\n\t\t\t} else {\n\t\t\t\tsb.WriteByte(',')\n\t\t\t}\n\t\t\tsb.WriteString(fmt.Sprintf(`{\"name\":%s,\"countEstimate\":%d}`, quoteSym(ref), uses.CountEstimate))\n\t\t}\n\t\tsb.WriteByte(']')\n\n\t\t// dependencies\n\t\tsb.WriteString(`,\"dependencies\":[`)\n\t\tfor i, dep := range part.Dependencies {\n\t\t\tif i > 0 {\n\t\t\t\tsb.WriteByte(',')\n\t\t\t}\n\t\t\tsb.WriteString(fmt.Sprintf(`{\"source\":%s,\"partIndex\":%d}`,\n\t\t\t\thelpers.QuoteForJSON(c.graph.Files[dep.SourceIndex].InputFile.Source.PrettyPaths.Rel, c.options.ASCIIOnly),\n\t\t\t\tdep.PartIndex,\n\t\t\t))\n\t\t}\n\t\tsb.WriteByte(']')\n\n\t\t// code\n\t\tsb.WriteString(`,\"code\":`)\n\t\tsb.Write(helpers.QuoteForJSON(code, c.options.ASCIIOnly))\n\n\t\tsb.WriteByte('}')\n\t}\n\tsb.WriteString(`]`)\n\n\treturn sb.String()\n}\n\nfunc moveBeforeExport(contents string, i int) int {\n\tcontents = strings.TrimRight(contents[:i], \" \\t\\r\\n\")\n\tif strings.HasSuffix(contents, \"export\") {\n\t\treturn len(contents) - 6\n\t}\n\treturn i\n}\n"
  },
  {
    "path": "internal/linker/linker.go",
    "content": "package linker\n\n// This package implements the second phase of the bundling operation that\n// generates the output files when given a module graph. It has been split off\n// into separate package to allow two linkers to cleanly exist in the same code\n// base. This will be useful when rewriting the linker because the new one can\n// be off by default to minimize disruption, but can still be enabled by anyone\n// to assist in giving feedback on the rewrite.\n\nimport (\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"hash\"\n\t\"net/url\"\n\t\"path\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/bundler\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/css_lexer\"\n\t\"github.com/evanw/esbuild/internal/css_parser\"\n\t\"github.com/evanw/esbuild/internal/css_printer\"\n\t\"github.com/evanw/esbuild/internal/fs\"\n\t\"github.com/evanw/esbuild/internal/graph\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/js_lexer\"\n\t\"github.com/evanw/esbuild/internal/js_printer\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/renamer\"\n\t\"github.com/evanw/esbuild/internal/resolver\"\n\t\"github.com/evanw/esbuild/internal/runtime\"\n\t\"github.com/evanw/esbuild/internal/sourcemap\"\n\t\"github.com/evanw/esbuild/internal/xxhash\"\n)\n\ntype linkerContext struct {\n\toptions *config.Options\n\ttimer   *helpers.Timer\n\tlog     logger.Log\n\tfs      fs.FS\n\tres     *resolver.Resolver\n\tgraph   graph.LinkerGraph\n\tchunks  []chunkInfo\n\n\t// This helps avoid an infinite loop when matching imports to exports\n\tcycleDetector []importTracker\n\n\t// This represents the parallel computation of source map related data.\n\t// Calling this will block until the computation is done. The resulting value\n\t// is shared between threads and must be treated as immutable.\n\tdataForSourceMaps func() []bundler.DataForSourceMap\n\n\t// This is passed to us from the bundling phase\n\tuniqueKeyPrefix      string\n\tuniqueKeyPrefixBytes []byte // This is just \"uniqueKeyPrefix\" in byte form\n\n\t// Property mangling results go here\n\tmangledProps map[ast.Ref]string\n\n\t// We may need to refer to the CommonJS \"module\" symbol for exports\n\tunboundModuleRef ast.Ref\n\n\t// We may need to refer to the \"__esm\" and/or \"__commonJS\" runtime symbols\n\tcjsRuntimeRef ast.Ref\n\tesmRuntimeRef ast.Ref\n}\n\ntype partRange struct {\n\tsourceIndex    uint32\n\tpartIndexBegin uint32\n\tpartIndexEnd   uint32\n}\n\ntype chunkInfo struct {\n\t// This is a random string and is used to represent the output path of this\n\t// chunk before the final output path has been computed.\n\tuniqueKey string\n\n\tfilesWithPartsInChunk map[uint32]bool\n\tentryBits             helpers.BitSet\n\n\t// For code splitting\n\tcrossChunkImports []chunkImport\n\n\t// This is the representation-specific information\n\tchunkRepr chunkRepr\n\n\t// This is the final path of this chunk relative to the output directory, but\n\t// without the substitution of the final hash (since it hasn't been computed).\n\tfinalTemplate []config.PathTemplate\n\n\t// This is the final path of this chunk relative to the output directory. It\n\t// is the substitution of the final hash into \"finalTemplate\".\n\tfinalRelPath string\n\n\t// If non-empty, this chunk needs to generate an external legal comments file.\n\texternalLegalComments []byte\n\n\t// This contains the hash for just this chunk without including information\n\t// from the hashes of other chunks. Later on in the linking process, the\n\t// final hash for this chunk will be constructed by merging the isolated\n\t// hashes of all transitive dependencies of this chunk. This is separated\n\t// into two phases like this to handle cycles in the chunk import graph.\n\twaitForIsolatedHash func() []byte\n\n\t// Other fields relating to the output file for this chunk\n\tjsonMetadataChunkCallback func(finalOutputSize int) helpers.Joiner\n\toutputSourceMap           sourcemap.SourceMapPieces\n\n\t// When this chunk is initially generated in isolation, the output pieces\n\t// will contain slices of the output with the unique keys of other chunks\n\t// omitted.\n\tintermediateOutput intermediateOutput\n\n\t// This information is only useful if \"isEntryPoint\" is true\n\tentryPointBit uint   // An index into \"c.graph.EntryPoints\"\n\tsourceIndex   uint32 // An index into \"c.sources\"\n\tisEntryPoint  bool\n\n\tisExecutable bool\n}\n\ntype chunkImport struct {\n\tchunkIndex uint32\n\timportKind ast.ImportKind\n}\n\ntype outputPieceIndexKind uint8\n\nconst (\n\toutputPieceNone outputPieceIndexKind = iota\n\toutputPieceAssetIndex\n\toutputPieceChunkIndex\n)\n\n// This is a chunk of source code followed by a reference to another chunk. For\n// example, the file \"@import 'CHUNK0001'; body { color: black; }\" would be\n// represented by two pieces, one with the data \"@import '\" and another with the\n// data \"'; body { color: black; }\". The first would have the chunk index 1 and\n// the second would have an invalid chunk index.\ntype outputPiece struct {\n\tdata []byte\n\n\t// Note: The \"kind\" may be \"outputPieceNone\" in which case there is one piece\n\t// with data and no chunk index. For example, the chunk may not contain any\n\t// imports.\n\tindex uint32\n\tkind  outputPieceIndexKind\n}\n\ntype intermediateOutput struct {\n\t// If the chunk has references to other chunks, then \"pieces\" contains the\n\t// contents of the chunk and \"joiner\" should not be used. Another joiner\n\t// will have to be constructed later when merging the pieces together.\n\tpieces []outputPiece\n\n\t// If the chunk doesn't have any references to other chunks, then \"pieces\" is\n\t// nil and \"joiner\" contains the contents of the chunk. This is more efficient\n\t// because it avoids doing a join operation twice.\n\tjoiner helpers.Joiner\n}\n\ntype chunkRepr interface{ isChunk() }\n\nfunc (*chunkReprJS) isChunk()  {}\nfunc (*chunkReprCSS) isChunk() {}\n\ntype chunkReprJS struct {\n\tfilesInChunkInOrder []uint32\n\tpartsInChunkInOrder []partRange\n\n\t// For code splitting\n\texportsToOtherChunks   map[ast.Ref]string\n\timportsFromOtherChunks map[uint32]crossChunkImportItemArray\n\tcrossChunkPrefixStmts  []js_ast.Stmt\n\tcrossChunkSuffixStmts  []js_ast.Stmt\n\n\tcssChunkIndex uint32\n\thasCSSChunk   bool\n}\n\ntype chunkReprCSS struct {\n\timportsInChunkInOrder []cssImportOrder\n}\n\ntype externalImportCSS struct {\n\tpath                   logger.Path\n\tconditions             []css_ast.ImportConditions\n\tconditionImportRecords []ast.ImportRecord\n}\n\n// Returns a log where \"log.HasErrors()\" only returns true if any errors have\n// been logged since this call. This is useful when there have already been\n// errors logged by other linkers that share the same log.\nfunc wrappedLog(log logger.Log) logger.Log {\n\tvar mutex sync.Mutex\n\tvar hasErrors bool\n\taddMsg := log.AddMsg\n\n\tlog.AddMsg = func(msg logger.Msg) {\n\t\tif msg.Kind == logger.Error {\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\t\t\thasErrors = true\n\t\t}\n\t\taddMsg(msg)\n\t}\n\n\tlog.HasErrors = func() bool {\n\t\tmutex.Lock()\n\t\tdefer mutex.Unlock()\n\t\treturn hasErrors\n\t}\n\n\treturn log\n}\n\nfunc Link(\n\toptions *config.Options,\n\ttimer *helpers.Timer,\n\tlog logger.Log,\n\tfs fs.FS,\n\tres *resolver.Resolver,\n\tinputFiles []graph.InputFile,\n\tentryPoints []graph.EntryPoint,\n\tuniqueKeyPrefix string,\n\treachableFiles []uint32,\n\tdataForSourceMaps func() []bundler.DataForSourceMap,\n) []graph.OutputFile {\n\ttimer.Begin(\"Link\")\n\tdefer timer.End(\"Link\")\n\n\tlog = wrappedLog(log)\n\n\ttimer.Begin(\"Clone linker graph\")\n\tc := linkerContext{\n\t\toptions:              options,\n\t\ttimer:                timer,\n\t\tlog:                  log,\n\t\tfs:                   fs,\n\t\tres:                  res,\n\t\tdataForSourceMaps:    dataForSourceMaps,\n\t\tuniqueKeyPrefix:      uniqueKeyPrefix,\n\t\tuniqueKeyPrefixBytes: []byte(uniqueKeyPrefix),\n\t\tgraph: graph.CloneLinkerGraph(\n\t\t\tinputFiles,\n\t\t\treachableFiles,\n\t\t\tentryPoints,\n\t\t\toptions.CodeSplitting,\n\t\t),\n\t}\n\ttimer.End(\"Clone linker graph\")\n\n\t// Use a smaller version of these functions if we don't need profiler names\n\truntimeRepr := c.graph.Files[runtime.SourceIndex].InputFile.Repr.(*graph.JSRepr)\n\tif c.options.ProfilerNames {\n\t\tc.cjsRuntimeRef = runtimeRepr.AST.NamedExports[\"__commonJS\"].Ref\n\t\tc.esmRuntimeRef = runtimeRepr.AST.NamedExports[\"__esm\"].Ref\n\t} else {\n\t\tc.cjsRuntimeRef = runtimeRepr.AST.NamedExports[\"__commonJSMin\"].Ref\n\t\tc.esmRuntimeRef = runtimeRepr.AST.NamedExports[\"__esmMin\"].Ref\n\t}\n\n\tvar additionalFiles []graph.OutputFile\n\tfor _, entryPoint := range entryPoints {\n\t\tfile := &c.graph.Files[entryPoint.SourceIndex].InputFile\n\t\tswitch repr := file.Repr.(type) {\n\t\tcase *graph.JSRepr:\n\t\t\t// Loaders default to CommonJS when they are the entry point and the output\n\t\t\t// format is not ESM-compatible since that avoids generating the ESM-to-CJS\n\t\t\t// machinery.\n\t\t\tif repr.AST.HasLazyExport && (c.options.Mode == config.ModePassThrough ||\n\t\t\t\t(c.options.Mode == config.ModeConvertFormat && !c.options.OutputFormat.KeepESMImportExportSyntax())) {\n\t\t\t\trepr.AST.ExportsKind = js_ast.ExportsCommonJS\n\t\t\t}\n\n\t\t\t// Entry points with ES6 exports must generate an exports object when\n\t\t\t// targeting non-ES6 formats. Note that the IIFE format only needs this\n\t\t\t// when the global name is present, since that's the only way the exports\n\t\t\t// can actually be observed externally.\n\t\t\tif repr.AST.ExportKeyword.Len > 0 && (options.OutputFormat == config.FormatCommonJS ||\n\t\t\t\t(options.OutputFormat == config.FormatIIFE && len(options.GlobalName) > 0)) {\n\t\t\t\trepr.AST.UsesExportsRef = true\n\t\t\t\trepr.Meta.ForceIncludeExportsForEntryPoint = true\n\t\t\t}\n\n\t\tcase *graph.CopyRepr:\n\t\t\t// If an entry point uses the copy loader, then copy the file manually\n\t\t\t// here. Other uses of the copy loader will automatically be included\n\t\t\t// along with the corresponding bundled chunk but that doesn't happen\n\t\t\t// for entry points.\n\t\t\tadditionalFiles = append(additionalFiles, file.AdditionalFiles...)\n\t\t}\n\t}\n\n\t// Allocate a new unbound symbol called \"module\" in case we need it later\n\tif c.options.OutputFormat == config.FormatCommonJS {\n\t\tc.unboundModuleRef = c.graph.GenerateNewSymbol(runtime.SourceIndex, ast.SymbolUnbound, \"module\")\n\t} else {\n\t\tc.unboundModuleRef = ast.InvalidRef\n\t}\n\n\tc.scanImportsAndExports()\n\n\t// Stop now if there were errors\n\tif c.log.HasErrors() {\n\t\tc.options.ExclusiveMangleCacheUpdate(func(map[string]interface{}, map[string]bool) {\n\t\t\t// Always do this so that we don't cause other entry points when there are errors\n\t\t})\n\t\treturn []graph.OutputFile{}\n\t}\n\n\tc.treeShakingAndCodeSplitting()\n\n\tif c.options.Mode == config.ModePassThrough {\n\t\tfor _, entryPoint := range c.graph.EntryPoints() {\n\t\t\tc.preventExportsFromBeingRenamed(entryPoint.SourceIndex)\n\t\t}\n\t}\n\n\tc.computeChunks()\n\tc.computeCrossChunkDependencies()\n\n\t// Merge mangled properties before chunks are generated since the names must\n\t// be consistent across all chunks, or the generated code will break\n\tc.timer.Begin(\"Waiting for mangle cache\")\n\tc.options.ExclusiveMangleCacheUpdate(func(\n\t\tmangleCache map[string]interface{},\n\t\tcssUsedLocalNames map[string]bool,\n\t) {\n\t\tc.timer.End(\"Waiting for mangle cache\")\n\t\tc.mangleProps(mangleCache)\n\t\tc.mangleLocalCSS(cssUsedLocalNames)\n\t})\n\n\t// Make sure calls to \"ast.FollowSymbols()\" in parallel goroutines after this\n\t// won't hit concurrent map mutation hazards\n\tast.FollowAllSymbols(c.graph.Symbols)\n\n\treturn c.generateChunksInParallel(additionalFiles)\n}\n\nfunc (c *linkerContext) mangleProps(mangleCache map[string]interface{}) {\n\tc.timer.Begin(\"Mangle props\")\n\tdefer c.timer.End(\"Mangle props\")\n\n\tmangledProps := make(map[ast.Ref]string)\n\tc.mangledProps = mangledProps\n\n\t// Reserve all JS keywords\n\treservedProps := make(map[string]bool)\n\tfor keyword := range js_lexer.Keywords {\n\t\treservedProps[keyword] = true\n\t}\n\n\t// Reserve all target properties in the cache\n\tfor original, remapped := range mangleCache {\n\t\tif remapped == false {\n\t\t\treservedProps[original] = true\n\t\t} else {\n\t\t\treservedProps[remapped.(string)] = true\n\t\t}\n\t}\n\n\t// Merge all mangled property symbols together\n\tfreq := ast.CharFreq{}\n\tmergedProps := make(map[string]ast.Ref)\n\tfor _, sourceIndex := range c.graph.ReachableFiles {\n\t\t// Don't mangle anything in the runtime code\n\t\tif sourceIndex == runtime.SourceIndex {\n\t\t\tcontinue\n\t\t}\n\n\t\t// For each file\n\t\tif repr, ok := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.JSRepr); ok {\n\t\t\t// Reserve all non-mangled properties\n\t\t\tfor prop := range repr.AST.ReservedProps {\n\t\t\t\treservedProps[prop] = true\n\t\t\t}\n\n\t\t\t// Merge each mangled property with other ones of the same name\n\t\t\tfor name, ref := range repr.AST.MangledProps {\n\t\t\t\tif existing, ok := mergedProps[name]; ok {\n\t\t\t\t\tast.MergeSymbols(c.graph.Symbols, ref, existing)\n\t\t\t\t} else {\n\t\t\t\t\tmergedProps[name] = ref\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Include this file's frequency histogram, which affects the mangled names\n\t\t\tif repr.AST.CharFreq != nil {\n\t\t\t\tfreq.Include(repr.AST.CharFreq)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Sort by use count (note: does not currently account for live vs. dead code)\n\tsorted := make(renamer.StableSymbolCountArray, 0, len(mergedProps))\n\tstableSourceIndices := c.graph.StableSourceIndices\n\tfor _, ref := range mergedProps {\n\t\tsorted = append(sorted, renamer.StableSymbolCount{\n\t\t\tStableSourceIndex: stableSourceIndices[ref.SourceIndex],\n\t\t\tRef:               ref,\n\t\t\tCount:             c.graph.Symbols.Get(ref).UseCountEstimate,\n\t\t})\n\t}\n\tsort.Sort(sorted)\n\n\t// Assign names in order of use count\n\tminifier := ast.DefaultNameMinifierJS.ShuffleByCharFreq(freq)\n\tnextName := 0\n\tfor _, symbolCount := range sorted {\n\t\tsymbol := c.graph.Symbols.Get(symbolCount.Ref)\n\n\t\t// Don't change existing mappings\n\t\tif existing, ok := mangleCache[symbol.OriginalName]; ok {\n\t\t\tif existing != false {\n\t\t\t\tmangledProps[symbolCount.Ref] = existing.(string)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Generate a new name\n\t\tname := minifier.NumberToMinifiedName(nextName)\n\t\tnextName++\n\n\t\t// Avoid reserved properties\n\t\tfor reservedProps[name] {\n\t\t\tname = minifier.NumberToMinifiedName(nextName)\n\t\t\tnextName++\n\t\t}\n\n\t\t// Track the new mapping\n\t\tif mangleCache != nil {\n\t\t\tmangleCache[symbol.OriginalName] = name\n\t\t}\n\t\tmangledProps[symbolCount.Ref] = name\n\t}\n}\n\nfunc (c *linkerContext) mangleLocalCSS(usedLocalNames map[string]bool) {\n\tc.timer.Begin(\"Mangle local CSS\")\n\tdefer c.timer.End(\"Mangle local CSS\")\n\n\tmangledProps := c.mangledProps\n\tglobalNames := make(map[string]bool)\n\tlocalNames := make(map[ast.Ref]struct{})\n\n\t// Collect all local and global CSS names\n\tfreq := ast.CharFreq{}\n\tfor _, sourceIndex := range c.graph.ReachableFiles {\n\t\tif repr, ok := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.CSSRepr); ok {\n\t\t\tfor innerIndex, symbol := range c.graph.Symbols.SymbolsForSource[sourceIndex] {\n\t\t\t\tif symbol.Kind == ast.SymbolGlobalCSS {\n\t\t\t\t\tglobalNames[symbol.OriginalName] = true\n\t\t\t\t} else {\n\t\t\t\t\tref := ast.Ref{SourceIndex: sourceIndex, InnerIndex: uint32(innerIndex)}\n\t\t\t\t\tref = ast.FollowSymbols(c.graph.Symbols, ref)\n\t\t\t\t\tlocalNames[ref] = struct{}{}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Include this file's frequency histogram, which affects the mangled names\n\t\t\tif repr.AST.CharFreq != nil {\n\t\t\t\tfreq.Include(repr.AST.CharFreq)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Sort by use count (note: does not currently account for live vs. dead code)\n\tsorted := make(renamer.StableSymbolCountArray, 0, len(localNames))\n\tstableSourceIndices := c.graph.StableSourceIndices\n\tfor ref := range localNames {\n\t\tsorted = append(sorted, renamer.StableSymbolCount{\n\t\t\tStableSourceIndex: stableSourceIndices[ref.SourceIndex],\n\t\t\tRef:               ref,\n\t\t\tCount:             c.graph.Symbols.Get(ref).UseCountEstimate,\n\t\t})\n\t}\n\tsort.Sort(sorted)\n\n\t// Rename all local names to avoid collisions\n\tif c.options.MinifyIdentifiers {\n\t\tminifier := ast.DefaultNameMinifierCSS.ShuffleByCharFreq(freq)\n\t\tnextName := 0\n\n\t\tfor _, symbolCount := range sorted {\n\t\t\tname := minifier.NumberToMinifiedName(nextName)\n\t\t\tfor globalNames[name] || usedLocalNames[name] {\n\t\t\t\tnextName++\n\t\t\t\tname = minifier.NumberToMinifiedName(nextName)\n\t\t\t}\n\n\t\t\t// Turn this local name into a global one\n\t\t\tmangledProps[symbolCount.Ref] = name\n\t\t\tusedLocalNames[name] = true\n\t\t}\n\t} else {\n\t\tnameCounts := make(map[string]uint32)\n\n\t\tfor _, symbolCount := range sorted {\n\t\t\tsymbol := c.graph.Symbols.Get(symbolCount.Ref)\n\t\t\tname := fmt.Sprintf(\"%s_%s\", c.graph.Files[symbolCount.Ref.SourceIndex].InputFile.Source.IdentifierName, symbol.OriginalName)\n\n\t\t\t// If the name is already in use, generate a new name by appending a number\n\t\t\tif globalNames[name] || usedLocalNames[name] {\n\t\t\t\t// To avoid O(n^2) behavior, the number must start off being the number\n\t\t\t\t// that we used last time there was a collision with this name. Otherwise\n\t\t\t\t// if there are many collisions with the same name, each name collision\n\t\t\t\t// would have to increment the counter past all previous name collisions\n\t\t\t\t// which is a O(n^2) time algorithm.\n\t\t\t\ttries, ok := nameCounts[name]\n\t\t\t\tif !ok {\n\t\t\t\t\ttries = 1\n\t\t\t\t}\n\t\t\t\tprefix := name\n\n\t\t\t\t// Keep incrementing the number until the name is unused\n\t\t\t\tfor {\n\t\t\t\t\ttries++\n\t\t\t\t\tname = prefix + strconv.Itoa(int(tries))\n\n\t\t\t\t\t// Make sure this new name is unused\n\t\t\t\t\tif !globalNames[name] && !usedLocalNames[name] {\n\t\t\t\t\t\t// Store the count so we can start here next time instead of starting\n\t\t\t\t\t\t// from 1. This means we avoid O(n^2) behavior.\n\t\t\t\t\t\tnameCounts[prefix] = tries\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn this local name into a global one\n\t\t\tmangledProps[symbolCount.Ref] = name\n\t\t\tusedLocalNames[name] = true\n\t\t}\n\t}\n}\n\n// Currently the automatic chunk generation algorithm should by construction\n// never generate chunks that import each other since files are allocated to\n// chunks based on which entry points they are reachable from.\n//\n// This will change in the future when we allow manual chunk labels. But before\n// we allow manual chunk labels, we'll need to rework module initialization to\n// allow code splitting chunks to be lazily-initialized.\n//\n// Since that work hasn't been finished yet, cycles in the chunk import graph\n// can cause initialization bugs. So let's forbid these cycles for now to guard\n// against code splitting bugs that could cause us to generate buggy chunks.\nfunc (c *linkerContext) enforceNoCyclicChunkImports() {\n\tvar validate func(int, map[int]int) bool\n\n\t// DFS memoization with 3-colors, more space efficient\n\t// 0: white (unvisited), 1: gray (visiting), 2: black (visited)\n\tcolors := make(map[int]int)\n\tvalidate = func(chunkIndex int, colors map[int]int) bool {\n\t\tif colors[chunkIndex] == 1 {\n\t\t\tc.log.AddError(nil, logger.Range{}, \"Internal error: generated chunks contain a circular import\")\n\t\t\treturn true\n\t\t}\n\n\t\tif colors[chunkIndex] == 2 {\n\t\t\treturn false\n\t\t}\n\n\t\tcolors[chunkIndex] = 1\n\n\t\tfor _, chunkImport := range c.chunks[chunkIndex].crossChunkImports {\n\t\t\t// Ignore cycles caused by dynamic \"import()\" expressions. These are fine\n\t\t\t// because they don't necessarily cause initialization order issues and\n\t\t\t// they don't indicate a bug in our chunk generation algorithm. They arise\n\t\t\t// normally in real code (e.g. two files that import each other).\n\t\t\tif chunkImport.importKind != ast.ImportDynamic {\n\n\t\t\t\t// Recursively validate otherChunkIndex\n\t\t\t\tif validate(int(chunkImport.chunkIndex), colors) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tcolors[chunkIndex] = 2\n\t\treturn false\n\t}\n\n\tfor i := range c.chunks {\n\t\tif validate(i, colors) {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc (c *linkerContext) generateChunksInParallel(additionalFiles []graph.OutputFile) []graph.OutputFile {\n\tc.timer.Begin(\"Generate chunks\")\n\tdefer c.timer.End(\"Generate chunks\")\n\n\t// Generate each chunk on a separate goroutine. When a chunk needs to\n\t// reference the path of another chunk, it will use a temporary path called\n\t// the \"uniqueKey\" since the final path hasn't been computed yet (and is\n\t// in general uncomputable at this point because paths have hashes that\n\t// include information about chunk dependencies, and chunk dependencies\n\t// can be cyclic due to dynamic imports).\n\tgenerateWaitGroup := sync.WaitGroup{}\n\tgenerateWaitGroup.Add(len(c.chunks))\n\tfor chunkIndex := range c.chunks {\n\t\tswitch c.chunks[chunkIndex].chunkRepr.(type) {\n\t\tcase *chunkReprJS:\n\t\t\tgo c.generateChunkJS(chunkIndex, &generateWaitGroup)\n\t\tcase *chunkReprCSS:\n\t\t\tgo c.generateChunkCSS(chunkIndex, &generateWaitGroup)\n\t\t}\n\t}\n\tc.enforceNoCyclicChunkImports()\n\tgenerateWaitGroup.Wait()\n\n\t// Compute the final hashes of each chunk, then use those to create the final\n\t// paths of each chunk. This can technically be done in parallel but it\n\t// probably doesn't matter so much because we're not hashing that much data.\n\tvisited := make([]uint32, len(c.chunks))\n\tvar finalBytes []byte\n\tfor chunkIndex := range c.chunks {\n\t\tchunk := &c.chunks[chunkIndex]\n\t\tvar hashSubstitution *string\n\n\t\t// Only wait for the hash if necessary\n\t\tif config.HasPlaceholder(chunk.finalTemplate, config.HashPlaceholder) {\n\t\t\t// Compute the final hash using the isolated hashes of the dependencies\n\t\t\thash := xxhash.New()\n\t\t\tc.appendIsolatedHashesForImportedChunks(hash, uint32(chunkIndex), visited, ^uint32(chunkIndex))\n\t\t\tfinalBytes = hash.Sum(finalBytes[:0])\n\t\t\tfinalString := bundler.HashForFileName(finalBytes)\n\t\t\thashSubstitution = &finalString\n\t\t}\n\n\t\t// Render the last remaining placeholder in the template\n\t\tchunk.finalRelPath = config.TemplateToString(config.SubstituteTemplate(chunk.finalTemplate, config.PathPlaceholders{\n\t\t\tHash: hashSubstitution,\n\t\t}))\n\t}\n\n\t// Generate the final output files by joining file pieces together and\n\t// substituting the temporary paths for the final paths. This substitution\n\t// can be done in parallel for each chunk.\n\tc.timer.Begin(\"Generate final output files\")\n\tvar resultsWaitGroup sync.WaitGroup\n\tresults := make([][]graph.OutputFile, len(c.chunks))\n\tresultsWaitGroup.Add(len(c.chunks))\n\tfor chunkIndex, chunk := range c.chunks {\n\t\tgo func(chunkIndex int, chunk chunkInfo) {\n\t\t\tvar outputFiles []graph.OutputFile\n\n\t\t\t// Each file may optionally contain additional files to be copied to the\n\t\t\t// output directory. This is used by the \"file\" and \"copy\" loaders.\n\t\t\tvar commentPrefix string\n\t\t\tvar commentSuffix string\n\t\t\tswitch chunkRepr := chunk.chunkRepr.(type) {\n\t\t\tcase *chunkReprJS:\n\t\t\t\tfor _, sourceIndex := range chunkRepr.filesInChunkInOrder {\n\t\t\t\t\toutputFiles = append(outputFiles, c.graph.Files[sourceIndex].InputFile.AdditionalFiles...)\n\t\t\t\t}\n\t\t\t\tcommentPrefix = \"//\"\n\n\t\t\tcase *chunkReprCSS:\n\t\t\t\tfor _, entry := range chunkRepr.importsInChunkInOrder {\n\t\t\t\t\tif entry.kind == cssImportSourceIndex {\n\t\t\t\t\t\toutputFiles = append(outputFiles, c.graph.Files[entry.sourceIndex].InputFile.AdditionalFiles...)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcommentPrefix = \"/*\"\n\t\t\t\tcommentSuffix = \" */\"\n\t\t\t}\n\n\t\t\t// Path substitution for the chunk itself\n\t\t\tfinalRelDir := c.fs.Dir(chunk.finalRelPath)\n\t\t\toutputContentsJoiner, outputSourceMapShifts := c.substituteFinalPaths(chunk.intermediateOutput,\n\t\t\t\tfunc(finalRelPathForImport string) string {\n\t\t\t\t\treturn c.pathBetweenChunks(finalRelDir, finalRelPathForImport)\n\t\t\t\t})\n\n\t\t\t// Generate the optional legal comments file for this chunk\n\t\t\tif len(chunk.externalLegalComments) > 0 {\n\t\t\t\tfinalRelPathForLegalComments := chunk.finalRelPath + \".LEGAL.txt\"\n\n\t\t\t\t// Link the file to the legal comments\n\t\t\t\tif c.options.LegalComments == config.LegalCommentsLinkedWithComment {\n\t\t\t\t\timportPath := c.pathBetweenChunks(finalRelDir, finalRelPathForLegalComments)\n\t\t\t\t\timportPath = strings.TrimPrefix(importPath, \"./\")\n\t\t\t\t\toutputContentsJoiner.EnsureNewlineAtEnd()\n\t\t\t\t\toutputContentsJoiner.AddString(\"/*! For license information please see \")\n\t\t\t\t\toutputContentsJoiner.AddString(importPath)\n\t\t\t\t\toutputContentsJoiner.AddString(\" */\\n\")\n\t\t\t\t}\n\n\t\t\t\t// Write the external legal comments file\n\t\t\t\toutputFiles = append(outputFiles, graph.OutputFile{\n\t\t\t\t\tAbsPath:  c.fs.Join(c.options.AbsOutputDir, finalRelPathForLegalComments),\n\t\t\t\t\tContents: chunk.externalLegalComments,\n\t\t\t\t\tJSONMetadataChunk: fmt.Sprintf(\n\t\t\t\t\t\tc.options.MetafileFormat.MaybeRemoveWhitespace(\"{\\n      \\\"imports\\\": [],\\n      \\\"exports\\\": [],\\n      \\\"inputs\\\": {},\\n      \\\"bytes\\\": %d\\n    }\"),\n\t\t\t\t\t\tlen(chunk.externalLegalComments)),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Generate the optional source map for this chunk\n\t\t\tif c.options.SourceMap != config.SourceMapNone && chunk.outputSourceMap.HasContent() {\n\t\t\t\toutputSourceMap := chunk.outputSourceMap.Finalize(outputSourceMapShifts)\n\t\t\t\tfinalRelPathForSourceMap := chunk.finalRelPath + \".map\"\n\n\t\t\t\t// Potentially write a trailing source map comment\n\t\t\t\tswitch c.options.SourceMap {\n\t\t\t\tcase config.SourceMapLinkedWithComment:\n\t\t\t\t\timportPath := c.pathBetweenChunks(finalRelDir, finalRelPathForSourceMap)\n\t\t\t\t\timportPath = strings.TrimPrefix(importPath, \"./\")\n\t\t\t\t\timportURL := url.URL{Path: importPath}\n\t\t\t\t\toutputContentsJoiner.EnsureNewlineAtEnd()\n\t\t\t\t\toutputContentsJoiner.AddString(commentPrefix)\n\t\t\t\t\toutputContentsJoiner.AddString(\"# sourceMappingURL=\")\n\t\t\t\t\toutputContentsJoiner.AddString(importURL.EscapedPath())\n\t\t\t\t\toutputContentsJoiner.AddString(commentSuffix)\n\t\t\t\t\toutputContentsJoiner.AddString(\"\\n\")\n\n\t\t\t\tcase config.SourceMapInline, config.SourceMapInlineAndExternal:\n\t\t\t\t\toutputContentsJoiner.EnsureNewlineAtEnd()\n\t\t\t\t\toutputContentsJoiner.AddString(commentPrefix)\n\t\t\t\t\toutputContentsJoiner.AddString(\"# sourceMappingURL=data:application/json;base64,\")\n\t\t\t\t\toutputContentsJoiner.AddString(base64.StdEncoding.EncodeToString(outputSourceMap))\n\t\t\t\t\toutputContentsJoiner.AddString(commentSuffix)\n\t\t\t\t\toutputContentsJoiner.AddString(\"\\n\")\n\t\t\t\t}\n\n\t\t\t\t// Potentially write the external source map file\n\t\t\t\tswitch c.options.SourceMap {\n\t\t\t\tcase config.SourceMapLinkedWithComment, config.SourceMapInlineAndExternal, config.SourceMapExternalWithoutComment:\n\t\t\t\t\toutputFiles = append(outputFiles, graph.OutputFile{\n\t\t\t\t\t\tAbsPath:  c.fs.Join(c.options.AbsOutputDir, finalRelPathForSourceMap),\n\t\t\t\t\t\tContents: outputSourceMap,\n\t\t\t\t\t\tJSONMetadataChunk: fmt.Sprintf(\n\t\t\t\t\t\t\tc.options.MetafileFormat.MaybeRemoveWhitespace(\"{\\n      \\\"imports\\\": [],\\n      \\\"exports\\\": [],\\n      \\\"inputs\\\": {},\\n      \\\"bytes\\\": %d\\n    }\"),\n\t\t\t\t\t\t\tlen(outputSourceMap)),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Finalize the output contents\n\t\t\toutputContents := outputContentsJoiner.Done()\n\n\t\t\t// Path substitution for the JSON metadata\n\t\t\tvar jsonMetadataChunk string\n\t\t\tif c.options.NeedsMetafile {\n\t\t\t\tjsonMetadataChunkPieces := c.breakJoinerIntoPieces(chunk.jsonMetadataChunkCallback(len(outputContents)))\n\t\t\t\tjsonMetadataChunkBytes, _ := c.substituteFinalPaths(jsonMetadataChunkPieces, func(finalRelPathForImport string) string {\n\t\t\t\t\tprettyPaths := resolver.MakePrettyPaths(c.fs, logger.Path{Text: c.fs.Join(c.options.AbsOutputDir, finalRelPathForImport), Namespace: \"file\"})\n\t\t\t\t\treturn prettyPaths.Select(c.options.MetafilePathStyle)\n\t\t\t\t})\n\t\t\t\tjsonMetadataChunk = string(jsonMetadataChunkBytes.Done())\n\t\t\t}\n\n\t\t\t// Generate the output file for this chunk\n\t\t\toutputFiles = append(outputFiles, graph.OutputFile{\n\t\t\t\tAbsPath:           c.fs.Join(c.options.AbsOutputDir, chunk.finalRelPath),\n\t\t\t\tContents:          outputContents,\n\t\t\t\tJSONMetadataChunk: jsonMetadataChunk,\n\t\t\t\tIsExecutable:      chunk.isExecutable,\n\t\t\t})\n\n\t\t\tresults[chunkIndex] = outputFiles\n\t\t\tresultsWaitGroup.Done()\n\t\t}(chunkIndex, chunk)\n\t}\n\tresultsWaitGroup.Wait()\n\tc.timer.End(\"Generate final output files\")\n\n\t// Merge the output files from the different goroutines together in order\n\toutputFilesLen := len(additionalFiles)\n\tfor _, result := range results {\n\t\toutputFilesLen += len(result)\n\t}\n\toutputFiles := make([]graph.OutputFile, 0, outputFilesLen)\n\toutputFiles = append(outputFiles, additionalFiles...)\n\tfor _, result := range results {\n\t\toutputFiles = append(outputFiles, result...)\n\t}\n\treturn outputFiles\n}\n\n// Given a set of output pieces (i.e. a buffer already divided into the spans\n// between import paths), substitute the final import paths in and then join\n// everything into a single byte buffer.\nfunc (c *linkerContext) substituteFinalPaths(\n\tintermediateOutput intermediateOutput,\n\tmodifyPath func(string) string,\n) (j helpers.Joiner, shifts []sourcemap.SourceMapShift) {\n\t// Optimization: If there can be no substitutions, just reuse the initial\n\t// joiner that was used when generating the intermediate chunk output\n\t// instead of creating another one and copying the whole file into it.\n\tif intermediateOutput.pieces == nil {\n\t\treturn intermediateOutput.joiner, []sourcemap.SourceMapShift{{}}\n\t}\n\n\tvar shift sourcemap.SourceMapShift\n\tshifts = make([]sourcemap.SourceMapShift, 0, len(intermediateOutput.pieces))\n\tshifts = append(shifts, shift)\n\n\tfor _, piece := range intermediateOutput.pieces {\n\t\tvar dataOffset sourcemap.LineColumnOffset\n\t\tj.AddBytes(piece.data)\n\t\tdataOffset.AdvanceBytes(piece.data)\n\t\tshift.Before.Add(dataOffset)\n\t\tshift.After.Add(dataOffset)\n\n\t\tswitch piece.kind {\n\t\tcase outputPieceAssetIndex:\n\t\t\tfile := c.graph.Files[piece.index]\n\t\t\tif len(file.InputFile.AdditionalFiles) != 1 {\n\t\t\t\tpanic(\"Internal error\")\n\t\t\t}\n\t\t\trelPath, _ := c.fs.Rel(c.options.AbsOutputDir, file.InputFile.AdditionalFiles[0].AbsPath)\n\n\t\t\t// Make sure to always use forward slashes, even on Windows\n\t\t\trelPath = strings.ReplaceAll(relPath, \"\\\\\", \"/\")\n\n\t\t\timportPath := modifyPath(relPath)\n\t\t\tj.AddString(importPath)\n\t\t\tshift.Before.AdvanceString(file.InputFile.UniqueKeyForAdditionalFile)\n\t\t\tshift.After.AdvanceString(importPath)\n\t\t\tshifts = append(shifts, shift)\n\n\t\tcase outputPieceChunkIndex:\n\t\t\tchunk := c.chunks[piece.index]\n\t\t\timportPath := modifyPath(chunk.finalRelPath)\n\t\t\tj.AddString(importPath)\n\t\t\tshift.Before.AdvanceString(chunk.uniqueKey)\n\t\t\tshift.After.AdvanceString(importPath)\n\t\t\tshifts = append(shifts, shift)\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc (c *linkerContext) accurateFinalByteCount(output intermediateOutput, chunkFinalRelDir string) int {\n\tcount := 0\n\n\t// Note: The paths generated here must match \"substituteFinalPaths\" above\n\tfor _, piece := range output.pieces {\n\t\tcount += len(piece.data)\n\n\t\tswitch piece.kind {\n\t\tcase outputPieceAssetIndex:\n\t\t\tfile := c.graph.Files[piece.index]\n\t\t\tif len(file.InputFile.AdditionalFiles) != 1 {\n\t\t\t\tpanic(\"Internal error\")\n\t\t\t}\n\t\t\trelPath, _ := c.fs.Rel(c.options.AbsOutputDir, file.InputFile.AdditionalFiles[0].AbsPath)\n\n\t\t\t// Make sure to always use forward slashes, even on Windows\n\t\t\trelPath = strings.ReplaceAll(relPath, \"\\\\\", \"/\")\n\n\t\t\timportPath := c.pathBetweenChunks(chunkFinalRelDir, relPath)\n\t\t\tcount += len(importPath)\n\n\t\tcase outputPieceChunkIndex:\n\t\t\tchunk := c.chunks[piece.index]\n\t\t\timportPath := c.pathBetweenChunks(chunkFinalRelDir, chunk.finalRelPath)\n\t\t\tcount += len(importPath)\n\t\t}\n\t}\n\n\treturn count\n}\n\nfunc (c *linkerContext) pathBetweenChunks(fromRelDir string, toRelPath string) string {\n\t// Join with the public path if it has been configured\n\tif c.options.PublicPath != \"\" {\n\t\treturn joinWithPublicPath(c.options.PublicPath, toRelPath)\n\t}\n\n\t// Otherwise, return a relative path\n\trelPath, ok := c.fs.Rel(fromRelDir, toRelPath)\n\tif !ok {\n\t\tc.log.AddError(nil, logger.Range{},\n\t\t\tfmt.Sprintf(\"Cannot traverse from directory %q to chunk %q\", fromRelDir, toRelPath))\n\t\treturn \"\"\n\t}\n\n\t// Make sure to always use forward slashes, even on Windows\n\trelPath = strings.ReplaceAll(relPath, \"\\\\\", \"/\")\n\n\t// Make sure the relative path doesn't start with a name, since that could\n\t// be interpreted as a package path instead of a relative path\n\tif !strings.HasPrefix(relPath, \"./\") && !strings.HasPrefix(relPath, \"../\") {\n\t\trelPath = \"./\" + relPath\n\t}\n\n\treturn relPath\n}\n\nfunc (c *linkerContext) computeCrossChunkDependencies() {\n\tc.timer.Begin(\"Compute cross-chunk dependencies\")\n\tdefer c.timer.End(\"Compute cross-chunk dependencies\")\n\n\tif !c.options.CodeSplitting {\n\t\t// No need to compute cross-chunk dependencies if there can't be any\n\t\treturn\n\t}\n\n\ttype chunkMeta struct {\n\t\timports        map[ast.Ref]bool\n\t\texports        map[ast.Ref]bool\n\t\tdynamicImports map[int]bool\n\t}\n\n\tchunkMetas := make([]chunkMeta, len(c.chunks))\n\n\t// For each chunk, see what symbols it uses from other chunks. Do this in\n\t// parallel because it's the most expensive part of this function.\n\twaitGroup := sync.WaitGroup{}\n\twaitGroup.Add(len(c.chunks))\n\tfor chunkIndex, chunk := range c.chunks {\n\t\tgo func(chunkIndex int, chunk chunkInfo) {\n\t\t\tchunkMeta := &chunkMetas[chunkIndex]\n\t\t\timports := make(map[ast.Ref]bool)\n\t\t\tchunkMeta.imports = imports\n\t\t\tchunkMeta.exports = make(map[ast.Ref]bool)\n\n\t\t\t// Go over each file in this chunk\n\t\t\tfor sourceIndex := range chunk.filesWithPartsInChunk {\n\t\t\t\t// Go over each part in this file that's marked for inclusion in this chunk\n\t\t\t\tswitch repr := c.graph.Files[sourceIndex].InputFile.Repr.(type) {\n\t\t\t\tcase *graph.JSRepr:\n\t\t\t\t\tfor partIndex, partMeta := range repr.AST.Parts {\n\t\t\t\t\t\tif !partMeta.IsLive {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpart := &repr.AST.Parts[partIndex]\n\n\t\t\t\t\t\t// Rewrite external dynamic imports to point to the chunk for that entry point\n\t\t\t\t\t\tfor _, importRecordIndex := range part.ImportRecordIndices {\n\t\t\t\t\t\t\trecord := &repr.AST.ImportRecords[importRecordIndex]\n\t\t\t\t\t\t\tif record.SourceIndex.IsValid() && c.isExternalDynamicImport(record, sourceIndex) {\n\t\t\t\t\t\t\t\totherChunkIndex := c.graph.Files[record.SourceIndex.GetIndex()].EntryPointChunkIndex\n\t\t\t\t\t\t\t\trecord.Path.Text = c.chunks[otherChunkIndex].uniqueKey\n\t\t\t\t\t\t\t\trecord.SourceIndex = ast.Index32{}\n\t\t\t\t\t\t\t\trecord.Flags |= ast.ShouldNotBeExternalInMetafile | ast.ContainsUniqueKey\n\n\t\t\t\t\t\t\t\t// Track this cross-chunk dynamic import so we make sure to\n\t\t\t\t\t\t\t\t// include its hash when we're calculating the hashes of all\n\t\t\t\t\t\t\t\t// dependencies of this chunk.\n\t\t\t\t\t\t\t\tif int(otherChunkIndex) != chunkIndex {\n\t\t\t\t\t\t\t\t\tif chunkMeta.dynamicImports == nil {\n\t\t\t\t\t\t\t\t\t\tchunkMeta.dynamicImports = make(map[int]bool)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tchunkMeta.dynamicImports[int(otherChunkIndex)] = true\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Remember what chunk each top-level symbol is declared in. Symbols\n\t\t\t\t\t\t// with multiple declarations such as repeated \"var\" statements with\n\t\t\t\t\t\t// the same name should already be marked as all being in a single\n\t\t\t\t\t\t// chunk. In that case this will overwrite the same value below which\n\t\t\t\t\t\t// is fine.\n\t\t\t\t\t\tfor _, declared := range part.DeclaredSymbols {\n\t\t\t\t\t\t\tif declared.IsTopLevel {\n\t\t\t\t\t\t\t\tc.graph.Symbols.Get(declared.Ref).ChunkIndex = ast.MakeIndex32(uint32(chunkIndex))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Record each symbol used in this part. This will later be matched up\n\t\t\t\t\t\t// with our map of which chunk a given symbol is declared in to\n\t\t\t\t\t\t// determine if the symbol needs to be imported from another chunk.\n\t\t\t\t\t\tfor ref := range part.SymbolUses {\n\t\t\t\t\t\t\tsymbol := c.graph.Symbols.Get(ref)\n\n\t\t\t\t\t\t\t// Ignore unbound symbols, which don't have declarations\n\t\t\t\t\t\t\tif symbol.Kind == ast.SymbolUnbound {\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Ignore symbols that are going to be replaced by undefined\n\t\t\t\t\t\t\tif symbol.ImportItemStatus == ast.ImportItemMissing {\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// If this is imported from another file, follow the import\n\t\t\t\t\t\t\t// reference and reference the symbol in that file instead\n\t\t\t\t\t\t\tif importData, ok := repr.Meta.ImportsToBind[ref]; ok {\n\t\t\t\t\t\t\t\tref = importData.Ref\n\t\t\t\t\t\t\t\tsymbol = c.graph.Symbols.Get(ref)\n\t\t\t\t\t\t\t} else if repr.Meta.Wrap == graph.WrapCJS && ref != repr.AST.WrapperRef {\n\t\t\t\t\t\t\t\t// The only internal symbol that wrapped CommonJS files export\n\t\t\t\t\t\t\t\t// is the wrapper itself.\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// If this is an ES6 import from a CommonJS file, it will become a\n\t\t\t\t\t\t\t// property access off the namespace symbol instead of a bare\n\t\t\t\t\t\t\t// identifier. In that case we want to pull in the namespace symbol\n\t\t\t\t\t\t\t// instead. The namespace symbol stores the result of \"require()\".\n\t\t\t\t\t\t\tif symbol.NamespaceAlias != nil {\n\t\t\t\t\t\t\t\tref = symbol.NamespaceAlias.NamespaceRef\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// We must record this relationship even for symbols that are not\n\t\t\t\t\t\t\t// imports. Due to code splitting, the definition of a symbol may\n\t\t\t\t\t\t\t// be moved to a separate chunk than the use of a symbol even if\n\t\t\t\t\t\t\t// the definition and use of that symbol are originally from the\n\t\t\t\t\t\t\t// same source file.\n\t\t\t\t\t\t\timports[ref] = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Include the exports if this is an entry point chunk\n\t\t\tif chunk.isEntryPoint {\n\t\t\t\tif repr, ok := c.graph.Files[chunk.sourceIndex].InputFile.Repr.(*graph.JSRepr); ok {\n\t\t\t\t\tif repr.Meta.Wrap != graph.WrapCJS {\n\t\t\t\t\t\tfor _, alias := range repr.Meta.SortedAndFilteredExportAliases {\n\t\t\t\t\t\t\texport := repr.Meta.ResolvedExports[alias]\n\t\t\t\t\t\t\ttargetRef := export.Ref\n\n\t\t\t\t\t\t\t// If this is an import, then target what the import points to\n\t\t\t\t\t\t\tif importData, ok := c.graph.Files[export.SourceIndex].InputFile.Repr.(*graph.JSRepr).Meta.ImportsToBind[targetRef]; ok {\n\t\t\t\t\t\t\t\ttargetRef = importData.Ref\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// If this is an ES6 import from a CommonJS file, it will become a\n\t\t\t\t\t\t\t// property access off the namespace symbol instead of a bare\n\t\t\t\t\t\t\t// identifier. In that case we want to pull in the namespace symbol\n\t\t\t\t\t\t\t// instead. The namespace symbol stores the result of \"require()\".\n\t\t\t\t\t\t\tif symbol := c.graph.Symbols.Get(targetRef); symbol.NamespaceAlias != nil {\n\t\t\t\t\t\t\t\ttargetRef = symbol.NamespaceAlias.NamespaceRef\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\timports[targetRef] = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Ensure \"exports\" is included if the current output format needs it\n\t\t\t\t\tif repr.Meta.ForceIncludeExportsForEntryPoint {\n\t\t\t\t\t\timports[repr.AST.ExportsRef] = true\n\t\t\t\t\t}\n\n\t\t\t\t\t// Include the wrapper if present\n\t\t\t\t\tif repr.Meta.Wrap != graph.WrapNone {\n\t\t\t\t\t\timports[repr.AST.WrapperRef] = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\twaitGroup.Done()\n\t\t}(chunkIndex, chunk)\n\t}\n\twaitGroup.Wait()\n\n\t// Mark imported symbols as exported in the chunk from which they are declared\n\tfor chunkIndex := range c.chunks {\n\t\tchunk := &c.chunks[chunkIndex]\n\t\tchunkRepr, ok := chunk.chunkRepr.(*chunkReprJS)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tchunkMeta := chunkMetas[chunkIndex]\n\n\t\t// Find all uses in this chunk of symbols from other chunks\n\t\tchunkRepr.importsFromOtherChunks = make(map[uint32]crossChunkImportItemArray)\n\t\tfor importRef := range chunkMeta.imports {\n\t\t\t// Ignore uses that aren't top-level symbols\n\t\t\tif otherChunkIndex := c.graph.Symbols.Get(importRef).ChunkIndex; otherChunkIndex.IsValid() {\n\t\t\t\tif otherChunkIndex := otherChunkIndex.GetIndex(); otherChunkIndex != uint32(chunkIndex) {\n\t\t\t\t\tchunkRepr.importsFromOtherChunks[otherChunkIndex] =\n\t\t\t\t\t\tappend(chunkRepr.importsFromOtherChunks[otherChunkIndex], crossChunkImportItem{ref: importRef})\n\t\t\t\t\tchunkMetas[otherChunkIndex].exports[importRef] = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If this is an entry point, make sure we import all chunks belonging to\n\t\t// this entry point, even if there are no imports. We need to make sure\n\t\t// these chunks are evaluated for their side effects too.\n\t\tif chunk.isEntryPoint {\n\t\t\tfor otherChunkIndex, otherChunk := range c.chunks {\n\t\t\t\tif _, ok := otherChunk.chunkRepr.(*chunkReprJS); ok && chunkIndex != otherChunkIndex && otherChunk.entryBits.HasBit(chunk.entryPointBit) {\n\t\t\t\t\timports := chunkRepr.importsFromOtherChunks[uint32(otherChunkIndex)]\n\t\t\t\t\tchunkRepr.importsFromOtherChunks[uint32(otherChunkIndex)] = imports\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Make sure we also track dynamic cross-chunk imports. These need to be\n\t\t// tracked so we count them as dependencies of this chunk for the purpose\n\t\t// of hash calculation.\n\t\tif chunkMeta.dynamicImports != nil {\n\t\t\tsortedDynamicImports := make([]int, 0, len(chunkMeta.dynamicImports))\n\t\t\tfor chunkIndex := range chunkMeta.dynamicImports {\n\t\t\t\tsortedDynamicImports = append(sortedDynamicImports, chunkIndex)\n\t\t\t}\n\t\t\tsort.Ints(sortedDynamicImports)\n\t\t\tfor _, chunkIndex := range sortedDynamicImports {\n\t\t\t\tchunk.crossChunkImports = append(chunk.crossChunkImports, chunkImport{\n\t\t\t\t\timportKind: ast.ImportDynamic,\n\t\t\t\t\tchunkIndex: uint32(chunkIndex),\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\t// Generate cross-chunk exports. These must be computed before cross-chunk\n\t// imports because of export alias renaming, which must consider all export\n\t// aliases simultaneously to avoid collisions.\n\tfor chunkIndex := range c.chunks {\n\t\tchunk := &c.chunks[chunkIndex]\n\t\tchunkRepr, ok := chunk.chunkRepr.(*chunkReprJS)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\tchunkRepr.exportsToOtherChunks = make(map[ast.Ref]string)\n\t\tswitch c.options.OutputFormat {\n\t\tcase config.FormatESModule:\n\t\t\tr := renamer.ExportRenamer{}\n\t\t\tvar items []js_ast.ClauseItem\n\t\t\tfor _, export := range c.sortedCrossChunkExportItems(chunkMetas[chunkIndex].exports) {\n\t\t\t\tvar alias string\n\t\t\t\tif c.options.MinifyIdentifiers {\n\t\t\t\t\talias = r.NextMinifiedName()\n\t\t\t\t} else {\n\t\t\t\t\talias = r.NextRenamedName(c.graph.Symbols.Get(export.Ref).OriginalName)\n\t\t\t\t}\n\t\t\t\titems = append(items, js_ast.ClauseItem{Name: ast.LocRef{Ref: export.Ref}, Alias: alias})\n\t\t\t\tchunkRepr.exportsToOtherChunks[export.Ref] = alias\n\t\t\t}\n\t\t\tif len(items) > 0 {\n\t\t\t\tchunkRepr.crossChunkSuffixStmts = []js_ast.Stmt{{Data: &js_ast.SExportClause{\n\t\t\t\t\tItems: items,\n\t\t\t\t}}}\n\t\t\t}\n\n\t\tdefault:\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\t}\n\n\t// Generate cross-chunk imports. These must be computed after cross-chunk\n\t// exports because the export aliases must already be finalized so they can\n\t// be embedded in the generated import statements.\n\tfor chunkIndex := range c.chunks {\n\t\tchunk := &c.chunks[chunkIndex]\n\t\tchunkRepr, ok := chunk.chunkRepr.(*chunkReprJS)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\tvar crossChunkPrefixStmts []js_ast.Stmt\n\n\t\tfor _, crossChunkImport := range c.sortedCrossChunkImports(chunkRepr.importsFromOtherChunks) {\n\t\t\tswitch c.options.OutputFormat {\n\t\t\tcase config.FormatESModule:\n\t\t\t\tvar items []js_ast.ClauseItem\n\t\t\t\tfor _, item := range crossChunkImport.sortedImportItems {\n\t\t\t\t\titems = append(items, js_ast.ClauseItem{Name: ast.LocRef{Ref: item.ref}, Alias: item.exportAlias})\n\t\t\t\t}\n\t\t\t\timportRecordIndex := uint32(len(chunk.crossChunkImports))\n\t\t\t\tchunk.crossChunkImports = append(chunk.crossChunkImports, chunkImport{\n\t\t\t\t\timportKind: ast.ImportStmt,\n\t\t\t\t\tchunkIndex: crossChunkImport.chunkIndex,\n\t\t\t\t})\n\t\t\t\tif len(items) > 0 {\n\t\t\t\t\t// \"import {a, b} from './chunk.js'\"\n\t\t\t\t\tcrossChunkPrefixStmts = append(crossChunkPrefixStmts, js_ast.Stmt{Data: &js_ast.SImport{\n\t\t\t\t\t\tItems:             &items,\n\t\t\t\t\t\tImportRecordIndex: importRecordIndex,\n\t\t\t\t\t}})\n\t\t\t\t} else {\n\t\t\t\t\t// \"import './chunk.js'\"\n\t\t\t\t\tcrossChunkPrefixStmts = append(crossChunkPrefixStmts, js_ast.Stmt{Data: &js_ast.SImport{\n\t\t\t\t\t\tImportRecordIndex: importRecordIndex,\n\t\t\t\t\t}})\n\t\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tpanic(\"Internal error\")\n\t\t\t}\n\t\t}\n\n\t\tchunkRepr.crossChunkPrefixStmts = crossChunkPrefixStmts\n\t}\n}\n\ntype crossChunkImport struct {\n\tsortedImportItems crossChunkImportItemArray\n\tchunkIndex        uint32\n}\n\n// This type is just so we can use Go's native sort function\ntype crossChunkImportArray []crossChunkImport\n\nfunc (a crossChunkImportArray) Len() int          { return len(a) }\nfunc (a crossChunkImportArray) Swap(i int, j int) { a[i], a[j] = a[j], a[i] }\n\nfunc (a crossChunkImportArray) Less(i int, j int) bool {\n\treturn a[i].chunkIndex < a[j].chunkIndex\n}\n\n// Sort cross-chunk imports by chunk name for determinism\nfunc (c *linkerContext) sortedCrossChunkImports(importsFromOtherChunks map[uint32]crossChunkImportItemArray) crossChunkImportArray {\n\tresult := make(crossChunkImportArray, 0, len(importsFromOtherChunks))\n\n\tfor otherChunkIndex, importItems := range importsFromOtherChunks {\n\t\t// Sort imports from a single chunk by alias for determinism\n\t\totherChunk := &c.chunks[otherChunkIndex]\n\t\texportsToOtherChunks := otherChunk.chunkRepr.(*chunkReprJS).exportsToOtherChunks\n\t\tfor i, item := range importItems {\n\t\t\timportItems[i].exportAlias = exportsToOtherChunks[item.ref]\n\t\t}\n\t\tsort.Sort(importItems)\n\t\tresult = append(result, crossChunkImport{\n\t\t\tchunkIndex:        otherChunkIndex,\n\t\t\tsortedImportItems: importItems,\n\t\t})\n\t}\n\n\tsort.Sort(result)\n\treturn result\n}\n\ntype crossChunkImportItem struct {\n\texportAlias string\n\tref         ast.Ref\n}\n\n// This type is just so we can use Go's native sort function\ntype crossChunkImportItemArray []crossChunkImportItem\n\nfunc (a crossChunkImportItemArray) Len() int          { return len(a) }\nfunc (a crossChunkImportItemArray) Swap(i int, j int) { a[i], a[j] = a[j], a[i] }\n\nfunc (a crossChunkImportItemArray) Less(i int, j int) bool {\n\treturn a[i].exportAlias < a[j].exportAlias\n}\n\n// The sort order here is arbitrary but needs to be consistent between builds.\n// The InnerIndex should be stable because the parser for a single file is\n// single-threaded and deterministically assigns out InnerIndex values\n// sequentially. But the SourceIndex should be unstable because the main thread\n// assigns out source index values sequentially to newly-discovered dependencies\n// in a multi-threaded producer/consumer relationship. So instead we use the\n// index of the source in the DFS order over all entry points for stability.\ntype stableRef struct {\n\tStableSourceIndex uint32\n\tRef               ast.Ref\n}\n\n// This type is just so we can use Go's native sort function\ntype stableRefArray []stableRef\n\nfunc (a stableRefArray) Len() int          { return len(a) }\nfunc (a stableRefArray) Swap(i int, j int) { a[i], a[j] = a[j], a[i] }\nfunc (a stableRefArray) Less(i int, j int) bool {\n\tai, aj := a[i], a[j]\n\treturn ai.StableSourceIndex < aj.StableSourceIndex ||\n\t\t(ai.StableSourceIndex == aj.StableSourceIndex && ai.Ref.InnerIndex < aj.Ref.InnerIndex)\n}\n\n// Sort cross-chunk exports by chunk name for determinism\nfunc (c *linkerContext) sortedCrossChunkExportItems(exportRefs map[ast.Ref]bool) stableRefArray {\n\tresult := make(stableRefArray, 0, len(exportRefs))\n\tfor ref := range exportRefs {\n\t\tresult = append(result, stableRef{\n\t\t\tStableSourceIndex: c.graph.StableSourceIndices[ref.SourceIndex],\n\t\t\tRef:               ref,\n\t\t})\n\t}\n\tsort.Sort(result)\n\treturn result\n}\n\nfunc (c *linkerContext) scanImportsAndExports() {\n\tc.timer.Begin(\"Scan imports and exports\")\n\tdefer c.timer.End(\"Scan imports and exports\")\n\n\t// Step 1: Figure out what modules must be CommonJS\n\tc.timer.Begin(\"Step 1\")\n\tfor _, sourceIndex := range c.graph.ReachableFiles {\n\t\tfile := &c.graph.Files[sourceIndex]\n\t\tadditionalFiles := file.InputFile.AdditionalFiles\n\n\t\tswitch repr := file.InputFile.Repr.(type) {\n\t\tcase *graph.CSSRepr:\n\t\t\t// Inline URLs for non-CSS files into the CSS file\n\t\t\tfor importRecordIndex := range repr.AST.ImportRecords {\n\t\t\t\tif record := &repr.AST.ImportRecords[importRecordIndex]; record.SourceIndex.IsValid() {\n\t\t\t\t\totherFile := &c.graph.Files[record.SourceIndex.GetIndex()]\n\t\t\t\t\tif otherRepr, ok := otherFile.InputFile.Repr.(*graph.JSRepr); ok {\n\t\t\t\t\t\trecord.Path.Text = otherRepr.AST.URLForCSS\n\t\t\t\t\t\trecord.Path.Namespace = \"\"\n\t\t\t\t\t\trecord.SourceIndex = ast.Index32{}\n\t\t\t\t\t\tif otherFile.InputFile.Loader == config.LoaderEmpty {\n\t\t\t\t\t\t\trecord.Flags |= ast.WasLoadedWithEmptyLoader\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\trecord.Flags |= ast.ShouldNotBeExternalInMetafile\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif strings.Contains(otherRepr.AST.URLForCSS, c.uniqueKeyPrefix) {\n\t\t\t\t\t\t\trecord.Flags |= ast.ContainsUniqueKey\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Copy the additional files to the output directory\n\t\t\t\t\t\tadditionalFiles = append(additionalFiles, otherFile.InputFile.AdditionalFiles...)\n\t\t\t\t\t}\n\t\t\t\t} else if record.CopySourceIndex.IsValid() {\n\t\t\t\t\totherFile := &c.graph.Files[record.CopySourceIndex.GetIndex()]\n\t\t\t\t\tif otherRepr, ok := otherFile.InputFile.Repr.(*graph.CopyRepr); ok {\n\t\t\t\t\t\trecord.Path.Text = otherRepr.URLForCode\n\t\t\t\t\t\trecord.Path.Namespace = \"\"\n\t\t\t\t\t\trecord.CopySourceIndex = ast.Index32{}\n\t\t\t\t\t\trecord.Flags |= ast.ShouldNotBeExternalInMetafile | ast.ContainsUniqueKey\n\n\t\t\t\t\t\t// Copy the additional files to the output directory\n\t\t\t\t\t\tadditionalFiles = append(additionalFiles, otherFile.InputFile.AdditionalFiles...)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Validate cross-file \"composes: ... from\" named imports\n\t\t\tfor _, composes := range repr.AST.Composes {\n\t\t\t\tfor _, name := range composes.ImportedNames {\n\t\t\t\t\tif record := repr.AST.ImportRecords[name.ImportRecordIndex]; record.SourceIndex.IsValid() {\n\t\t\t\t\t\totherFile := &c.graph.Files[record.SourceIndex.GetIndex()]\n\t\t\t\t\t\tif otherRepr, ok := otherFile.InputFile.Repr.(*graph.CSSRepr); ok {\n\t\t\t\t\t\t\tif _, ok := otherRepr.AST.LocalScope[name.Alias]; !ok {\n\t\t\t\t\t\t\t\tif global, ok := otherRepr.AST.GlobalScope[name.Alias]; ok {\n\t\t\t\t\t\t\t\t\tvar hint string\n\t\t\t\t\t\t\t\t\tif otherFile.InputFile.Loader == config.LoaderCSS {\n\t\t\t\t\t\t\t\t\t\thint = fmt.Sprintf(\"Use the \\\"local-css\\\" loader for %q to enable local names.\",\n\t\t\t\t\t\t\t\t\t\t\totherFile.InputFile.Source.PrettyPaths.Select(c.options.LogPathStyle))\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\thint = fmt.Sprintf(\"Use the \\\":local\\\" selector to change %q into a local name.\", name.Alias)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tc.log.AddErrorWithNotes(file.LineColumnTracker(),\n\t\t\t\t\t\t\t\t\t\tcss_lexer.RangeOfIdentifier(file.InputFile.Source, name.AliasLoc),\n\t\t\t\t\t\t\t\t\t\tfmt.Sprintf(\"Cannot use global name %q with \\\"composes\\\"\", name.Alias),\n\t\t\t\t\t\t\t\t\t\t[]logger.MsgData{\n\t\t\t\t\t\t\t\t\t\t\totherFile.LineColumnTracker().MsgData(\n\t\t\t\t\t\t\t\t\t\t\t\tcss_lexer.RangeOfIdentifier(otherFile.InputFile.Source, global.Loc),\n\t\t\t\t\t\t\t\t\t\t\t\tfmt.Sprintf(\"The global name %q is defined here:\", name.Alias),\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t{Text: hint},\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tc.log.AddError(file.LineColumnTracker(),\n\t\t\t\t\t\t\t\t\t\tcss_lexer.RangeOfIdentifier(file.InputFile.Source, name.AliasLoc),\n\t\t\t\t\t\t\t\t\t\tfmt.Sprintf(\"The name %q never appears in %q\", name.Alias,\n\t\t\t\t\t\t\t\t\t\t\totherFile.InputFile.Source.PrettyPaths.Select(c.options.LogPathStyle)))\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tc.validateComposesFromProperties(file, repr)\n\n\t\tcase *graph.JSRepr:\n\t\t\tfor importRecordIndex := range repr.AST.ImportRecords {\n\t\t\t\trecord := &repr.AST.ImportRecords[importRecordIndex]\n\t\t\t\tif !record.SourceIndex.IsValid() {\n\t\t\t\t\tif record.CopySourceIndex.IsValid() {\n\t\t\t\t\t\totherFile := &c.graph.Files[record.CopySourceIndex.GetIndex()]\n\t\t\t\t\t\tif otherRepr, ok := otherFile.InputFile.Repr.(*graph.CopyRepr); ok {\n\t\t\t\t\t\t\trecord.Path.Text = otherRepr.URLForCode\n\t\t\t\t\t\t\trecord.Path.Namespace = \"\"\n\t\t\t\t\t\t\trecord.CopySourceIndex = ast.Index32{}\n\t\t\t\t\t\t\trecord.Flags |= ast.ShouldNotBeExternalInMetafile | ast.ContainsUniqueKey\n\n\t\t\t\t\t\t\t// Copy the additional files to the output directory\n\t\t\t\t\t\t\tadditionalFiles = append(additionalFiles, otherFile.InputFile.AdditionalFiles...)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\totherFile := &c.graph.Files[record.SourceIndex.GetIndex()]\n\t\t\t\totherRepr := otherFile.InputFile.Repr.(*graph.JSRepr)\n\n\t\t\t\tswitch record.Kind {\n\t\t\t\tcase ast.ImportStmt:\n\t\t\t\t\t// Importing using ES6 syntax from a file without any ES6 syntax\n\t\t\t\t\t// causes that module to be considered CommonJS-style, even if it\n\t\t\t\t\t// doesn't have any CommonJS exports.\n\t\t\t\t\t//\n\t\t\t\t\t// That means the ES6 imports will become undefined instead of\n\t\t\t\t\t// causing errors. This is for compatibility with older CommonJS-\n\t\t\t\t\t// style bundlers.\n\t\t\t\t\t//\n\t\t\t\t\t// We emit a warning in this case but try to avoid turning the module\n\t\t\t\t\t// into a CommonJS module if possible. This is possible with named\n\t\t\t\t\t// imports (the module stays an ECMAScript module but the imports are\n\t\t\t\t\t// rewritten with undefined) but is not possible with star or default\n\t\t\t\t\t// imports:\n\t\t\t\t\t//\n\t\t\t\t\t//   import * as ns from './empty-file'\n\t\t\t\t\t//   import defVal from './empty-file'\n\t\t\t\t\t//   console.log(ns, defVal)\n\t\t\t\t\t//\n\t\t\t\t\t// In that case the module *is* considered a CommonJS module because\n\t\t\t\t\t// the namespace object must be created.\n\t\t\t\t\tif (record.Flags.Has(ast.ContainsImportStar) || record.Flags.Has(ast.ContainsDefaultAlias)) &&\n\t\t\t\t\t\totherRepr.AST.ExportsKind == js_ast.ExportsNone && !otherRepr.AST.HasLazyExport {\n\t\t\t\t\t\totherRepr.Meta.Wrap = graph.WrapCJS\n\t\t\t\t\t\totherRepr.AST.ExportsKind = js_ast.ExportsCommonJS\n\t\t\t\t\t}\n\n\t\t\t\tcase ast.ImportRequire:\n\t\t\t\t\t// Files that are imported with require() must be wrapped so that\n\t\t\t\t\t// they can be lazily-evaluated\n\t\t\t\t\tif otherRepr.AST.ExportsKind == js_ast.ExportsESM {\n\t\t\t\t\t\totherRepr.Meta.Wrap = graph.WrapESM\n\t\t\t\t\t} else {\n\t\t\t\t\t\totherRepr.Meta.Wrap = graph.WrapCJS\n\t\t\t\t\t\totherRepr.AST.ExportsKind = js_ast.ExportsCommonJS\n\t\t\t\t\t}\n\n\t\t\t\tcase ast.ImportDynamic:\n\t\t\t\t\tif !c.options.CodeSplitting {\n\t\t\t\t\t\t// If we're not splitting, then import() is just a require() that\n\t\t\t\t\t\t// returns a promise, so the imported file must also be wrapped\n\t\t\t\t\t\tif otherRepr.AST.ExportsKind == js_ast.ExportsESM {\n\t\t\t\t\t\t\totherRepr.Meta.Wrap = graph.WrapESM\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\totherRepr.Meta.Wrap = graph.WrapCJS\n\t\t\t\t\t\t\totherRepr.AST.ExportsKind = js_ast.ExportsCommonJS\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the output format doesn't have an implicit CommonJS wrapper, any file\n\t\t\t// that uses CommonJS features will need to be wrapped, even though the\n\t\t\t// resulting wrapper won't be invoked by other files. An exception is made\n\t\t\t// for entry point files in CommonJS format (or when in pass-through mode).\n\t\t\tif repr.AST.ExportsKind == js_ast.ExportsCommonJS && (!file.IsEntryPoint() ||\n\t\t\t\tc.options.OutputFormat == config.FormatIIFE || c.options.OutputFormat == config.FormatESModule) {\n\t\t\t\trepr.Meta.Wrap = graph.WrapCJS\n\t\t\t}\n\t\t}\n\n\t\tfile.InputFile.AdditionalFiles = additionalFiles\n\t}\n\tc.timer.End(\"Step 1\")\n\n\t// Step 2: Propagate dynamic export status for export star statements that\n\t// are re-exports from a module whose exports are not statically analyzable.\n\t// In this case the export star must be evaluated at run time instead of at\n\t// bundle time.\n\tc.timer.Begin(\"Step 2\")\n\tfor _, sourceIndex := range c.graph.ReachableFiles {\n\t\trepr, ok := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\tif repr.Meta.Wrap != graph.WrapNone {\n\t\t\tc.recursivelyWrapDependencies(sourceIndex)\n\t\t}\n\n\t\tif len(repr.AST.ExportStarImportRecords) > 0 {\n\t\t\tvisited := make(map[uint32]bool)\n\t\t\tc.hasDynamicExportsDueToExportStar(sourceIndex, visited)\n\t\t}\n\n\t\t// Even if the output file is CommonJS-like, we may still need to wrap\n\t\t// CommonJS-style files. Any file that imports a CommonJS-style file will\n\t\t// cause that file to need to be wrapped. This is because the import\n\t\t// method, whatever it is, will need to invoke the wrapper. Note that\n\t\t// this can include entry points (e.g. an entry point that imports a file\n\t\t// that imports that entry point).\n\t\tfor _, record := range repr.AST.ImportRecords {\n\t\t\tif record.SourceIndex.IsValid() {\n\t\t\t\totherRepr := c.graph.Files[record.SourceIndex.GetIndex()].InputFile.Repr.(*graph.JSRepr)\n\t\t\t\tif otherRepr.AST.ExportsKind == js_ast.ExportsCommonJS {\n\t\t\t\t\tc.recursivelyWrapDependencies(record.SourceIndex.GetIndex())\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tc.timer.End(\"Step 2\")\n\n\t// Step 3: Resolve \"export * from\" statements. This must be done after we\n\t// discover all modules that can have dynamic exports because export stars\n\t// are ignored for those modules.\n\tc.timer.Begin(\"Step 3\")\n\texportStarStack := make([]uint32, 0, 32)\n\tfor _, sourceIndex := range c.graph.ReachableFiles {\n\t\trepr, ok := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Expression-style loaders defer code generation until linking. Code\n\t\t// generation is done here because at this point we know that the\n\t\t// \"ExportsKind\" field has its final value and will not be changed.\n\t\tif repr.AST.HasLazyExport {\n\t\t\tc.generateCodeForLazyExport(sourceIndex)\n\t\t}\n\n\t\t// Propagate exports for export star statements\n\t\tif len(repr.AST.ExportStarImportRecords) > 0 {\n\t\t\tc.addExportsForExportStar(repr.Meta.ResolvedExports, sourceIndex, exportStarStack)\n\t\t}\n\n\t\t// Also add a special export so import stars can bind to it. This must be\n\t\t// done in this step because it must come after CommonJS module discovery\n\t\t// but before matching imports with exports.\n\t\trepr.Meta.ResolvedExportStar = &graph.ExportData{\n\t\t\tRef:         repr.AST.ExportsRef,\n\t\t\tSourceIndex: sourceIndex,\n\t\t}\n\t}\n\tc.timer.End(\"Step 3\")\n\n\t// Step 4: Match imports with exports. This must be done after we process all\n\t// export stars because imports can bind to export star re-exports.\n\tc.timer.Begin(\"Step 4\")\n\tfor _, sourceIndex := range c.graph.ReachableFiles {\n\t\tfile := &c.graph.Files[sourceIndex]\n\t\trepr, ok := file.InputFile.Repr.(*graph.JSRepr)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\tif len(repr.AST.NamedImports) > 0 {\n\t\t\tc.matchImportsWithExportsForFile(uint32(sourceIndex))\n\t\t}\n\n\t\t// If we're exporting as CommonJS and this file was originally CommonJS,\n\t\t// then we'll be using the actual CommonJS \"exports\" and/or \"module\"\n\t\t// symbols. In that case make sure to mark them as such so they don't\n\t\t// get minified.\n\t\tif file.IsEntryPoint() && repr.AST.ExportsKind == js_ast.ExportsCommonJS && repr.Meta.Wrap == graph.WrapNone &&\n\t\t\t(c.options.OutputFormat == config.FormatPreserve || c.options.OutputFormat == config.FormatCommonJS) {\n\t\t\texportsRef := ast.FollowSymbols(c.graph.Symbols, repr.AST.ExportsRef)\n\t\t\tmoduleRef := ast.FollowSymbols(c.graph.Symbols, repr.AST.ModuleRef)\n\t\t\tc.graph.Symbols.Get(exportsRef).Kind = ast.SymbolUnbound\n\t\t\tc.graph.Symbols.Get(moduleRef).Kind = ast.SymbolUnbound\n\t\t} else if repr.Meta.ForceIncludeExportsForEntryPoint || repr.AST.ExportsKind != js_ast.ExportsCommonJS {\n\t\t\trepr.Meta.NeedsExportsVariable = true\n\t\t}\n\n\t\t// Create the wrapper part for wrapped files. This is needed by a later step.\n\t\tc.createWrapperForFile(uint32(sourceIndex))\n\t}\n\tc.timer.End(\"Step 4\")\n\n\t// Step 5: Create namespace exports for every file. This is always necessary\n\t// for CommonJS files, and is also necessary for other files if they are\n\t// imported using an import star statement.\n\tc.timer.Begin(\"Step 5\")\n\twaitGroup := sync.WaitGroup{}\n\tfor _, sourceIndex := range c.graph.ReachableFiles {\n\t\trepr, ok := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\t// This is the slowest step and is also parallelizable, so do this in parallel.\n\t\twaitGroup.Add(1)\n\t\tgo func(sourceIndex uint32, repr *graph.JSRepr) {\n\t\t\t// Now that all exports have been resolved, sort and filter them to create\n\t\t\t// something we can iterate over later.\n\t\t\taliases := make([]string, 0, len(repr.Meta.ResolvedExports))\n\t\tnextAlias:\n\t\t\tfor alias, export := range repr.Meta.ResolvedExports {\n\t\t\t\totherFile := &c.graph.Files[export.SourceIndex].InputFile\n\t\t\t\totherRepr := otherFile.Repr.(*graph.JSRepr)\n\n\t\t\t\t// Re-exporting multiple symbols with the same name causes an ambiguous\n\t\t\t\t// export. These names cannot be used and should not end up in generated code.\n\t\t\t\tif len(export.PotentiallyAmbiguousExportStarRefs) > 0 {\n\t\t\t\t\tmainRef := export.Ref\n\t\t\t\t\tmainLoc := export.NameLoc\n\t\t\t\t\tif imported, ok := otherRepr.Meta.ImportsToBind[export.Ref]; ok {\n\t\t\t\t\t\tmainRef = imported.Ref\n\t\t\t\t\t\tmainLoc = imported.NameLoc\n\t\t\t\t\t}\n\n\t\t\t\t\tfor _, ambiguousExport := range export.PotentiallyAmbiguousExportStarRefs {\n\t\t\t\t\t\tambiguousFile := &c.graph.Files[ambiguousExport.SourceIndex].InputFile\n\t\t\t\t\t\tambiguousRepr := ambiguousFile.Repr.(*graph.JSRepr)\n\t\t\t\t\t\tambiguousRef := ambiguousExport.Ref\n\t\t\t\t\t\tambiguousLoc := ambiguousExport.NameLoc\n\t\t\t\t\t\tif imported, ok := ambiguousRepr.Meta.ImportsToBind[ambiguousExport.Ref]; ok {\n\t\t\t\t\t\t\tambiguousRef = imported.Ref\n\t\t\t\t\t\t\tambiguousLoc = imported.NameLoc\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif mainRef != ambiguousRef {\n\t\t\t\t\t\t\tfile := &c.graph.Files[sourceIndex].InputFile\n\t\t\t\t\t\t\totherTracker := logger.MakeLineColumnTracker(&otherFile.Source)\n\t\t\t\t\t\t\tambiguousTracker := logger.MakeLineColumnTracker(&ambiguousFile.Source)\n\t\t\t\t\t\t\tc.log.AddIDWithNotes(logger.MsgID_Bundler_AmbiguousReexport, logger.Debug, nil, logger.Range{},\n\t\t\t\t\t\t\t\tfmt.Sprintf(\"Re-export of %q in %q is ambiguous and has been removed\", alias,\n\t\t\t\t\t\t\t\t\tfile.Source.PrettyPaths.Select(c.options.LogPathStyle)),\n\t\t\t\t\t\t\t\t[]logger.MsgData{\n\t\t\t\t\t\t\t\t\totherTracker.MsgData(js_lexer.RangeOfIdentifier(otherFile.Source, mainLoc),\n\t\t\t\t\t\t\t\t\t\tfmt.Sprintf(\"One definition of %q comes from %q here:\", alias,\n\t\t\t\t\t\t\t\t\t\t\totherFile.Source.PrettyPaths.Select(c.options.LogPathStyle))),\n\t\t\t\t\t\t\t\t\tambiguousTracker.MsgData(js_lexer.RangeOfIdentifier(ambiguousFile.Source, ambiguousLoc),\n\t\t\t\t\t\t\t\t\t\tfmt.Sprintf(\"Another definition of %q comes from %q here:\", alias,\n\t\t\t\t\t\t\t\t\t\t\tambiguousFile.Source.PrettyPaths.Select(c.options.LogPathStyle))),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tcontinue nextAlias\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Ignore re-exported imports in TypeScript files that failed to be\n\t\t\t\t// resolved. These are probably just type-only imports so the best thing to\n\t\t\t\t// do is to silently omit them from the export list.\n\t\t\t\tif otherRepr.Meta.IsProbablyTypeScriptType[export.Ref] {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif c.options.OutputFormat == config.FormatESModule && c.options.UnsupportedJSFeatures.Has(compat.ArbitraryModuleNamespaceNames) && c.graph.Files[sourceIndex].IsEntryPoint() {\n\t\t\t\t\tc.maybeForbidArbitraryModuleNamespaceIdentifier(\"export\", export.SourceIndex, export.NameLoc, alias)\n\t\t\t\t}\n\n\t\t\t\taliases = append(aliases, alias)\n\t\t\t}\n\t\t\tsort.Strings(aliases)\n\t\t\trepr.Meta.SortedAndFilteredExportAliases = aliases\n\n\t\t\t// Export creation uses \"sortedAndFilteredExportAliases\" so this must\n\t\t\t// come second after we fill in that array\n\t\t\tc.createExportsForFile(uint32(sourceIndex))\n\n\t\t\t// Each part tracks the other parts it depends on within this file\n\t\t\tlocalDependencies := make(map[uint32]uint32)\n\t\t\tparts := repr.AST.Parts\n\t\t\tnamedImports := repr.AST.NamedImports\n\t\t\tgraph := c.graph\n\t\t\tfor partIndex := range parts {\n\t\t\t\tpart := &parts[partIndex]\n\n\t\t\t\t// Now that all files have been parsed, determine which property\n\t\t\t\t// accesses off of imported symbols are inlined enum values and\n\t\t\t\t// which ones aren't\n\t\t\t\tfor ref, properties := range part.ImportSymbolPropertyUses {\n\t\t\t\t\tuse := part.SymbolUses[ref]\n\n\t\t\t\t\t// Rare path: this import is a TypeScript enum\n\t\t\t\t\tif importData, ok := repr.Meta.ImportsToBind[ref]; ok {\n\t\t\t\t\t\tif symbol := graph.Symbols.Get(importData.Ref); symbol.Kind == ast.SymbolTSEnum {\n\t\t\t\t\t\t\tif enum, ok := graph.TSEnums[importData.Ref]; ok {\n\t\t\t\t\t\t\t\tfoundNonInlinedEnum := false\n\t\t\t\t\t\t\t\tfor name, propertyUse := range properties {\n\t\t\t\t\t\t\t\t\tif _, ok := enum[name]; !ok {\n\t\t\t\t\t\t\t\t\t\tfoundNonInlinedEnum = true\n\t\t\t\t\t\t\t\t\t\tuse.CountEstimate += propertyUse.CountEstimate\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif foundNonInlinedEnum {\n\t\t\t\t\t\t\t\t\tpart.SymbolUses[ref] = use\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Common path: this import isn't a TypeScript enum\n\t\t\t\t\tfor _, propertyUse := range properties {\n\t\t\t\t\t\tuse.CountEstimate += propertyUse.CountEstimate\n\t\t\t\t\t}\n\t\t\t\t\tpart.SymbolUses[ref] = use\n\t\t\t\t}\n\n\t\t\t\t// Also determine which function calls will be inlined (and so should\n\t\t\t\t// not count as uses), and which ones will not be (and so should count\n\t\t\t\t// as uses)\n\t\t\t\tfor ref, callUse := range part.SymbolCallUses {\n\t\t\t\t\tuse := part.SymbolUses[ref]\n\n\t\t\t\t\t// Find the symbol that was called\n\t\t\t\t\tsymbol := graph.Symbols.Get(ref)\n\t\t\t\t\tif symbol.Kind == ast.SymbolImport {\n\t\t\t\t\t\tif importData, ok := repr.Meta.ImportsToBind[ref]; ok {\n\t\t\t\t\t\t\tsymbol = graph.Symbols.Get(importData.Ref)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tflags := symbol.Flags\n\n\t\t\t\t\t// Rare path: this is a function that will be inlined\n\t\t\t\t\tif (flags & (ast.IsEmptyFunction | ast.CouldPotentiallyBeMutated)) == ast.IsEmptyFunction {\n\t\t\t\t\t\t// Every call will be inlined\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t} else if (flags & (ast.IsIdentityFunction | ast.CouldPotentiallyBeMutated)) == ast.IsIdentityFunction {\n\t\t\t\t\t\t// Every single-argument call will be inlined as long as it's not a spread\n\t\t\t\t\t\tcallUse.CallCountEstimate -= callUse.SingleArgNonSpreadCallCountEstimate\n\t\t\t\t\t\tif callUse.CallCountEstimate == 0 {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Common path: this isn't a function that will be inlined\n\t\t\t\t\tuse.CountEstimate += callUse.CallCountEstimate\n\t\t\t\t\tpart.SymbolUses[ref] = use\n\t\t\t\t}\n\n\t\t\t\t// Now that we know this, we can determine cross-part dependencies\n\t\t\t\tfor ref := range part.SymbolUses {\n\n\t\t\t\t\t// Rare path: this import is an inlined const value\n\t\t\t\t\tif graph.ConstValues != nil {\n\t\t\t\t\t\tif importData, ok := repr.Meta.ImportsToBind[ref]; ok {\n\t\t\t\t\t\t\tif _, isConstValue := graph.ConstValues[importData.Ref]; isConstValue {\n\t\t\t\t\t\t\t\tdelete(part.SymbolUses, importData.Ref)\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tfor _, otherPartIndex := range repr.TopLevelSymbolToParts(ref) {\n\t\t\t\t\t\tif oldPartIndex, ok := localDependencies[otherPartIndex]; !ok || oldPartIndex != uint32(partIndex) {\n\t\t\t\t\t\t\tlocalDependencies[otherPartIndex] = uint32(partIndex)\n\t\t\t\t\t\t\tpart.Dependencies = append(part.Dependencies, js_ast.Dependency{\n\t\t\t\t\t\t\t\tSourceIndex: sourceIndex,\n\t\t\t\t\t\t\t\tPartIndex:   otherPartIndex,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Also map from imports to parts that use them\n\t\t\t\t\tif namedImport, ok := namedImports[ref]; ok {\n\t\t\t\t\t\tnamedImport.LocalPartsWithUses = append(namedImport.LocalPartsWithUses, uint32(partIndex))\n\t\t\t\t\t\tnamedImports[ref] = namedImport\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\twaitGroup.Done()\n\t\t}(sourceIndex, repr)\n\t}\n\twaitGroup.Wait()\n\tc.timer.End(\"Step 5\")\n\n\t// Step 6: Bind imports to exports. This adds non-local dependencies on the\n\t// parts that declare the export to all parts that use the import. Also\n\t// generate wrapper parts for wrapped files.\n\tc.timer.Begin(\"Step 6\")\n\tfor _, sourceIndex := range c.graph.ReachableFiles {\n\t\tfile := &c.graph.Files[sourceIndex]\n\t\trepr, ok := file.InputFile.Repr.(*graph.JSRepr)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Pre-generate symbols for re-exports CommonJS symbols in case they\n\t\t// are necessary later. This is done now because the symbols map cannot be\n\t\t// mutated later due to parallelism.\n\t\tif file.IsEntryPoint() && c.options.OutputFormat == config.FormatESModule {\n\t\t\tcopies := make([]ast.Ref, len(repr.Meta.SortedAndFilteredExportAliases))\n\t\t\tfor i, alias := range repr.Meta.SortedAndFilteredExportAliases {\n\t\t\t\tcopies[i] = c.graph.GenerateNewSymbol(sourceIndex, ast.SymbolOther, \"export_\"+alias)\n\t\t\t}\n\t\t\trepr.Meta.CJSExportCopies = copies\n\t\t}\n\n\t\t// Use \"init_*\" for ESM wrappers instead of \"require_*\"\n\t\tif repr.Meta.Wrap == graph.WrapESM {\n\t\t\tc.graph.Symbols.Get(repr.AST.WrapperRef).OriginalName = \"init_\" + file.InputFile.Source.IdentifierName\n\t\t}\n\n\t\t// If this isn't CommonJS, then rename the unused \"exports\" and \"module\"\n\t\t// variables to avoid them causing the identically-named variables in\n\t\t// actual CommonJS files from being renamed. This is purely about\n\t\t// aesthetics and is not about correctness. This is done here because by\n\t\t// this point, we know the CommonJS status will not change further.\n\t\tif repr.Meta.Wrap != graph.WrapCJS && repr.AST.ExportsKind != js_ast.ExportsCommonJS {\n\t\t\tname := file.InputFile.Source.IdentifierName\n\t\t\tc.graph.Symbols.Get(repr.AST.ExportsRef).OriginalName = name + \"_exports\"\n\t\t\tc.graph.Symbols.Get(repr.AST.ModuleRef).OriginalName = name + \"_module\"\n\t\t}\n\n\t\t// Include the \"__export\" symbol from the runtime if it was used in the\n\t\t// previous step. The previous step can't do this because it's running in\n\t\t// parallel and can't safely mutate the \"importsToBind\" map of another file.\n\t\tif repr.Meta.NeedsExportSymbolFromRuntime {\n\t\t\truntimeRepr := c.graph.Files[runtime.SourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\t\texportRef := runtimeRepr.AST.ModuleScope.Members[\"__export\"].Ref\n\t\t\tc.graph.GenerateSymbolImportAndUse(sourceIndex, js_ast.NSExportPartIndex, exportRef, 1, runtime.SourceIndex)\n\t\t}\n\n\t\tfor importRef, importData := range repr.Meta.ImportsToBind {\n\t\t\tresolvedRepr := c.graph.Files[importData.SourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\t\tpartsDeclaringSymbol := resolvedRepr.TopLevelSymbolToParts(importData.Ref)\n\n\t\t\tfor _, partIndex := range repr.AST.NamedImports[importRef].LocalPartsWithUses {\n\t\t\t\tpart := &repr.AST.Parts[partIndex]\n\n\t\t\t\t// Depend on the file containing the imported symbol\n\t\t\t\tfor _, resolvedPartIndex := range partsDeclaringSymbol {\n\t\t\t\t\tpart.Dependencies = append(part.Dependencies, js_ast.Dependency{\n\t\t\t\t\t\tSourceIndex: importData.SourceIndex,\n\t\t\t\t\t\tPartIndex:   resolvedPartIndex,\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\t// Also depend on any files that re-exported this symbol in between the\n\t\t\t\t// file containing the import and the file containing the imported symbol\n\t\t\t\tpart.Dependencies = append(part.Dependencies, importData.ReExports...)\n\t\t\t}\n\n\t\t\t// Merge these symbols so they will share the same name\n\t\t\tast.MergeSymbols(c.graph.Symbols, importRef, importData.Ref)\n\t\t}\n\n\t\t// If this is an entry point, depend on all exports so they are included\n\t\tif file.IsEntryPoint() {\n\t\t\tvar dependencies []js_ast.Dependency\n\n\t\t\tfor _, alias := range repr.Meta.SortedAndFilteredExportAliases {\n\t\t\t\texport := repr.Meta.ResolvedExports[alias]\n\t\t\t\ttargetSourceIndex := export.SourceIndex\n\t\t\t\ttargetRef := export.Ref\n\n\t\t\t\t// If this is an import, then target what the import points to\n\t\t\t\ttargetRepr := c.graph.Files[targetSourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\t\t\tif importData, ok := targetRepr.Meta.ImportsToBind[targetRef]; ok {\n\t\t\t\t\ttargetSourceIndex = importData.SourceIndex\n\t\t\t\t\ttargetRef = importData.Ref\n\t\t\t\t\ttargetRepr = c.graph.Files[targetSourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\t\t\t\tdependencies = append(dependencies, importData.ReExports...)\n\t\t\t\t}\n\n\t\t\t\t// Pull in all declarations of this symbol\n\t\t\t\tfor _, partIndex := range targetRepr.TopLevelSymbolToParts(targetRef) {\n\t\t\t\t\tdependencies = append(dependencies, js_ast.Dependency{\n\t\t\t\t\t\tSourceIndex: targetSourceIndex,\n\t\t\t\t\t\tPartIndex:   partIndex,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Ensure \"exports\" is included if the current output format needs it\n\t\t\tif repr.Meta.ForceIncludeExportsForEntryPoint {\n\t\t\t\tdependencies = append(dependencies, js_ast.Dependency{\n\t\t\t\t\tSourceIndex: sourceIndex,\n\t\t\t\t\tPartIndex:   js_ast.NSExportPartIndex,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Include the wrapper if present\n\t\t\tif repr.Meta.Wrap != graph.WrapNone {\n\t\t\t\tdependencies = append(dependencies, js_ast.Dependency{\n\t\t\t\t\tSourceIndex: sourceIndex,\n\t\t\t\t\tPartIndex:   repr.Meta.WrapperPartIndex.GetIndex(),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Represent these constraints with a dummy part\n\t\t\tentryPointPartIndex := c.graph.AddPartToFile(sourceIndex, js_ast.Part{\n\t\t\t\tDependencies:         dependencies,\n\t\t\t\tCanBeRemovedIfUnused: false,\n\t\t\t})\n\t\t\trepr.Meta.EntryPointPartIndex = ast.MakeIndex32(entryPointPartIndex)\n\n\t\t\t// Pull in the \"__toCommonJS\" symbol if we need it due to being an entry point\n\t\t\tif repr.Meta.ForceIncludeExportsForEntryPoint {\n\t\t\t\tc.graph.GenerateRuntimeSymbolImportAndUse(sourceIndex, entryPointPartIndex, \"__toCommonJS\", 1)\n\t\t\t}\n\t\t}\n\n\t\t// Encode import-specific constraints in the dependency graph\n\t\tfor partIndex, part := range repr.AST.Parts {\n\t\t\ttoESMUses := uint32(0)\n\t\t\ttoCommonJSUses := uint32(0)\n\t\t\truntimeRequireUses := uint32(0)\n\n\t\t\t// Imports of wrapped files must depend on the wrapper\n\t\t\tfor _, importRecordIndex := range part.ImportRecordIndices {\n\t\t\t\trecord := &repr.AST.ImportRecords[importRecordIndex]\n\n\t\t\t\t// Don't follow external imports (this includes import() expressions)\n\t\t\t\tif !record.SourceIndex.IsValid() || c.isExternalDynamicImport(record, sourceIndex) {\n\t\t\t\t\t// This is an external import. Check if it will be a \"require()\" call.\n\t\t\t\t\tif record.Kind == ast.ImportRequire || !c.options.OutputFormat.KeepESMImportExportSyntax() ||\n\t\t\t\t\t\t(record.Kind == ast.ImportDynamic && c.options.UnsupportedJSFeatures.Has(compat.DynamicImport)) {\n\t\t\t\t\t\t// We should use \"__require\" instead of \"require\" if we're not\n\t\t\t\t\t\t// generating a CommonJS output file, since it won't exist otherwise\n\t\t\t\t\t\tif config.ShouldCallRuntimeRequire(c.options.Mode, c.options.OutputFormat) {\n\t\t\t\t\t\t\trecord.Flags |= ast.CallRuntimeRequire\n\t\t\t\t\t\t\truntimeRequireUses++\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If this wasn't originally a \"require()\" call, then we may need\n\t\t\t\t\t\t// to wrap this in a call to the \"__toESM\" wrapper to convert from\n\t\t\t\t\t\t// CommonJS semantics to ESM semantics.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// Unfortunately this adds some additional code since the conversion\n\t\t\t\t\t\t// is somewhat complex. As an optimization, we can avoid this if the\n\t\t\t\t\t\t// following things are true:\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// - The import is an ES module statement (e.g. not an \"import()\" expression)\n\t\t\t\t\t\t// - The ES module namespace object must not be captured\n\t\t\t\t\t\t// - The \"default\" and \"__esModule\" exports must not be accessed\n\t\t\t\t\t\t//\n\t\t\t\t\t\tif record.Kind != ast.ImportRequire &&\n\t\t\t\t\t\t\t(record.Kind != ast.ImportStmt ||\n\t\t\t\t\t\t\t\trecord.Flags.Has(ast.ContainsImportStar) ||\n\t\t\t\t\t\t\t\trecord.Flags.Has(ast.ContainsDefaultAlias) ||\n\t\t\t\t\t\t\t\trecord.Flags.Has(ast.ContainsESModuleAlias)) {\n\t\t\t\t\t\t\trecord.Flags |= ast.WrapWithToESM\n\t\t\t\t\t\t\ttoESMUses++\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\totherSourceIndex := record.SourceIndex.GetIndex()\n\t\t\t\totherRepr := c.graph.Files[otherSourceIndex].InputFile.Repr.(*graph.JSRepr)\n\n\t\t\t\tif otherRepr.Meta.Wrap != graph.WrapNone {\n\t\t\t\t\t// Depend on the automatically-generated require wrapper symbol\n\t\t\t\t\twrapperRef := otherRepr.AST.WrapperRef\n\t\t\t\t\tc.graph.GenerateSymbolImportAndUse(sourceIndex, uint32(partIndex), wrapperRef, 1, otherSourceIndex)\n\n\t\t\t\t\t// This is an ES6 import of a CommonJS module, so it needs the\n\t\t\t\t\t// \"__toESM\" wrapper as long as it's not a bare \"require()\"\n\t\t\t\t\tif record.Kind != ast.ImportRequire && otherRepr.AST.ExportsKind == js_ast.ExportsCommonJS {\n\t\t\t\t\t\trecord.Flags |= ast.WrapWithToESM\n\t\t\t\t\t\ttoESMUses++\n\t\t\t\t\t}\n\n\t\t\t\t\t// If this is an ESM wrapper, also depend on the exports object\n\t\t\t\t\t// since the final code will contain an inline reference to it.\n\t\t\t\t\t// This must be done for \"require()\" and \"import()\" expressions\n\t\t\t\t\t// but does not need to be done for \"import\" statements since\n\t\t\t\t\t// those just cause us to reference the exports directly.\n\t\t\t\t\tif otherRepr.Meta.Wrap == graph.WrapESM && record.Kind != ast.ImportStmt {\n\t\t\t\t\t\tc.graph.GenerateSymbolImportAndUse(sourceIndex, uint32(partIndex), otherRepr.AST.ExportsRef, 1, otherSourceIndex)\n\n\t\t\t\t\t\t// If this is a \"require()\" call, then we should add the\n\t\t\t\t\t\t// \"__esModule\" marker to behave as if the module was converted\n\t\t\t\t\t\t// from ESM to CommonJS. This is done via a wrapper instead of\n\t\t\t\t\t\t// by modifying the exports object itself because the same ES\n\t\t\t\t\t\t// module may be simultaneously imported and required, and the\n\t\t\t\t\t\t// importing code should not see \"__esModule\" while the requiring\n\t\t\t\t\t\t// code should see \"__esModule\". This is an extremely complex\n\t\t\t\t\t\t// and subtle set of bundler interop issues. See for example\n\t\t\t\t\t\t// https://github.com/evanw/esbuild/issues/1591.\n\t\t\t\t\t\tif record.Kind == ast.ImportRequire {\n\t\t\t\t\t\t\trecord.Flags |= ast.WrapWithToCJS\n\t\t\t\t\t\t\ttoCommonJSUses++\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if record.Kind == ast.ImportStmt && otherRepr.AST.ExportsKind == js_ast.ExportsESMWithDynamicFallback {\n\t\t\t\t\t// This is an import of a module that has a dynamic export fallback\n\t\t\t\t\t// object. In that case we need to depend on that object in case\n\t\t\t\t\t// something ends up needing to use it later. This could potentially\n\t\t\t\t\t// be omitted in some cases with more advanced analysis if this\n\t\t\t\t\t// dynamic export fallback object doesn't end up being needed.\n\t\t\t\t\tc.graph.GenerateSymbolImportAndUse(sourceIndex, uint32(partIndex), otherRepr.AST.ExportsRef, 1, otherSourceIndex)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If there's an ES6 import of a non-ES6 module, then we're going to need the\n\t\t\t// \"__toESM\" symbol from the runtime to wrap the result of \"require()\"\n\t\t\tc.graph.GenerateRuntimeSymbolImportAndUse(sourceIndex, uint32(partIndex), \"__toESM\", toESMUses)\n\n\t\t\t// If there's a CommonJS require of an ES6 module, then we're going to need the\n\t\t\t// \"__toCommonJS\" symbol from the runtime to wrap the exports object\n\t\t\tc.graph.GenerateRuntimeSymbolImportAndUse(sourceIndex, uint32(partIndex), \"__toCommonJS\", toCommonJSUses)\n\n\t\t\t// If there are unbundled calls to \"require()\" and we're not generating\n\t\t\t// code for node, then substitute a \"__require\" wrapper for \"require\".\n\t\t\tc.graph.GenerateRuntimeSymbolImportAndUse(sourceIndex, uint32(partIndex), \"__require\", runtimeRequireUses)\n\n\t\t\t// If there's an ES6 export star statement of a non-ES6 module, then we're\n\t\t\t// going to need the \"__reExport\" symbol from the runtime\n\t\t\treExportUses := uint32(0)\n\t\t\tfor _, importRecordIndex := range repr.AST.ExportStarImportRecords {\n\t\t\t\trecord := &repr.AST.ImportRecords[importRecordIndex]\n\n\t\t\t\t// Is this export star evaluated at run time?\n\t\t\t\thappensAtRunTime := !record.SourceIndex.IsValid() && (!file.IsEntryPoint() || !c.options.OutputFormat.KeepESMImportExportSyntax())\n\t\t\t\tif record.SourceIndex.IsValid() {\n\t\t\t\t\totherSourceIndex := record.SourceIndex.GetIndex()\n\t\t\t\t\totherRepr := c.graph.Files[otherSourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\t\t\t\tif otherSourceIndex != sourceIndex && otherRepr.AST.ExportsKind.IsDynamic() {\n\t\t\t\t\t\thappensAtRunTime = true\n\t\t\t\t\t}\n\t\t\t\t\tif otherRepr.AST.ExportsKind == js_ast.ExportsESMWithDynamicFallback {\n\t\t\t\t\t\t// This looks like \"__reExport(exports_a, exports_b)\". Make sure to\n\t\t\t\t\t\t// pull in the \"exports_b\" symbol into this export star. This matters\n\t\t\t\t\t\t// in code splitting situations where the \"export_b\" symbol might live\n\t\t\t\t\t\t// in a different chunk than this export star.\n\t\t\t\t\t\tc.graph.GenerateSymbolImportAndUse(sourceIndex, uint32(partIndex), otherRepr.AST.ExportsRef, 1, otherSourceIndex)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif happensAtRunTime {\n\t\t\t\t\t// Depend on this file's \"exports\" object for the first argument to \"__reExport\"\n\t\t\t\t\tc.graph.GenerateSymbolImportAndUse(sourceIndex, uint32(partIndex), repr.AST.ExportsRef, 1, sourceIndex)\n\t\t\t\t\trecord.Flags |= ast.CallsRunTimeReExportFn\n\t\t\t\t\trepr.AST.UsesExportsRef = true\n\t\t\t\t\treExportUses++\n\t\t\t\t}\n\t\t\t}\n\t\t\tc.graph.GenerateRuntimeSymbolImportAndUse(sourceIndex, uint32(partIndex), \"__reExport\", reExportUses)\n\t\t}\n\t}\n\tc.timer.End(\"Step 6\")\n}\n\nfunc (c *linkerContext) validateComposesFromProperties(rootFile *graph.LinkerFile, rootRepr *graph.CSSRepr) {\n\tfor _, local := range rootRepr.AST.LocalSymbols {\n\t\ttype propertyInFile struct {\n\t\t\tfile *graph.LinkerFile\n\t\t\tloc  logger.Loc\n\t\t}\n\n\t\tvisited := make(map[ast.Ref]bool)\n\t\tproperties := make(map[string]propertyInFile)\n\t\tvar visit func(*graph.LinkerFile, *graph.CSSRepr, ast.Ref)\n\n\t\tvisit = func(file *graph.LinkerFile, repr *graph.CSSRepr, ref ast.Ref) {\n\t\t\tif visited[ref] {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tvisited[ref] = true\n\n\t\t\tcomposes, ok := repr.AST.Composes[ref]\n\t\t\tif !ok {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tfor _, name := range composes.ImportedNames {\n\t\t\t\tif record := repr.AST.ImportRecords[name.ImportRecordIndex]; record.SourceIndex.IsValid() {\n\t\t\t\t\totherFile := &c.graph.Files[record.SourceIndex.GetIndex()]\n\t\t\t\t\tif otherRepr, ok := otherFile.InputFile.Repr.(*graph.CSSRepr); ok {\n\t\t\t\t\t\tif otherName, ok := otherRepr.AST.LocalScope[name.Alias]; ok {\n\t\t\t\t\t\t\tvisit(otherFile, otherRepr, otherName.Ref)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor _, name := range composes.Names {\n\t\t\t\tvisit(file, repr, name.Ref)\n\t\t\t}\n\n\t\t\t// Warn about cross-file composition with the same CSS properties\n\t\t\tfor keyText, keyLoc := range composes.Properties {\n\t\t\t\tproperty, ok := properties[keyText]\n\t\t\t\tif !ok {\n\t\t\t\t\tproperties[keyText] = propertyInFile{file, keyLoc}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif property.file == file || property.file == nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tlocalOriginalName := c.graph.Symbols.Get(local.Ref).OriginalName\n\t\t\t\tc.log.AddMsgID(logger.MsgID_CSS_UndefinedComposesFrom, logger.Msg{\n\t\t\t\t\tKind: logger.Warning,\n\t\t\t\t\tData: rootFile.LineColumnTracker().MsgData(\n\t\t\t\t\t\tcss_lexer.RangeOfIdentifier(rootFile.InputFile.Source, local.Loc),\n\t\t\t\t\t\tfmt.Sprintf(\"The value of %q in the %q class is undefined\", keyText, localOriginalName),\n\t\t\t\t\t),\n\t\t\t\t\tNotes: []logger.MsgData{\n\t\t\t\t\t\tproperty.file.LineColumnTracker().MsgData(\n\t\t\t\t\t\t\tcss_lexer.RangeOfIdentifier(property.file.InputFile.Source, property.loc),\n\t\t\t\t\t\t\tfmt.Sprintf(\"The first definition of %q is here:\", keyText),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tfile.LineColumnTracker().MsgData(\n\t\t\t\t\t\t\tcss_lexer.RangeOfIdentifier(file.InputFile.Source, keyLoc),\n\t\t\t\t\t\t\tfmt.Sprintf(\"The second definition of %q is here:\", keyText),\n\t\t\t\t\t\t),\n\t\t\t\t\t\t{Text: fmt.Sprintf(\"The specification of \\\"composes\\\" does not define an order when class declarations from separate files are composed together. \"+\n\t\t\t\t\t\t\t\"The value of the %q property for %q may change unpredictably as the code is edited. \"+\n\t\t\t\t\t\t\t\"Make sure that all definitions of %q for %q are in a single file.\", keyText, localOriginalName, keyText, localOriginalName)},\n\t\t\t\t\t},\n\t\t\t\t})\n\n\t\t\t\t// Don't warn more than once\n\t\t\t\tproperty.file = nil\n\t\t\t\tproperties[keyText] = property\n\t\t\t}\n\t\t}\n\n\t\tvisit(rootFile, rootRepr, local.Ref)\n\t}\n}\n\nfunc (c *linkerContext) generateCodeForLazyExport(sourceIndex uint32) {\n\tfile := &c.graph.Files[sourceIndex]\n\trepr := file.InputFile.Repr.(*graph.JSRepr)\n\n\t// Grab the lazy expression\n\tif len(repr.AST.Parts) < 1 {\n\t\tpanic(\"Internal error\")\n\t}\n\tpart := &repr.AST.Parts[len(repr.AST.Parts)-1]\n\tif len(part.Stmts) != 1 {\n\t\tpanic(\"Internal error\")\n\t}\n\tlazyValue := part.Stmts[0].Data.(*js_ast.SLazyExport).Value\n\n\t// If this JavaScript file is a stub from a CSS file, populate the exports of\n\t// this JavaScript stub with the local names from that CSS file. This is done\n\t// now instead of earlier because we need the whole bundle to be present.\n\tif repr.CSSSourceIndex.IsValid() {\n\t\tcssSourceIndex := repr.CSSSourceIndex.GetIndex()\n\t\tif css, ok := c.graph.Files[cssSourceIndex].InputFile.Repr.(*graph.CSSRepr); ok {\n\t\t\texports := js_ast.EObject{}\n\n\t\t\tfor _, local := range css.AST.LocalSymbols {\n\t\t\t\tvalue := js_ast.Expr{Loc: local.Loc, Data: &js_ast.ENameOfSymbol{Ref: local.Ref}}\n\t\t\t\tvisited := map[ast.Ref]bool{local.Ref: true}\n\t\t\t\tvar parts []js_ast.TemplatePart\n\t\t\t\tvar visitName func(*graph.CSSRepr, ast.Ref)\n\t\t\t\tvar visitComposes func(*graph.CSSRepr, ast.Ref)\n\n\t\t\t\tvisitName = func(repr *graph.CSSRepr, ref ast.Ref) {\n\t\t\t\t\tif !visited[ref] {\n\t\t\t\t\t\tvisited[ref] = true\n\t\t\t\t\t\tvisitComposes(repr, ref)\n\t\t\t\t\t\tparts = append(parts, js_ast.TemplatePart{\n\t\t\t\t\t\t\tValue:      js_ast.Expr{Data: &js_ast.ENameOfSymbol{Ref: ref}},\n\t\t\t\t\t\t\tTailCooked: []uint16{' '},\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvisitComposes = func(repr *graph.CSSRepr, ref ast.Ref) {\n\t\t\t\t\tif composes, ok := repr.AST.Composes[ref]; ok {\n\t\t\t\t\t\tfor _, name := range composes.ImportedNames {\n\t\t\t\t\t\t\tif record := repr.AST.ImportRecords[name.ImportRecordIndex]; record.SourceIndex.IsValid() {\n\t\t\t\t\t\t\t\totherFile := &c.graph.Files[record.SourceIndex.GetIndex()]\n\t\t\t\t\t\t\t\tif otherRepr, ok := otherFile.InputFile.Repr.(*graph.CSSRepr); ok {\n\t\t\t\t\t\t\t\t\tif otherName, ok := otherRepr.AST.LocalScope[name.Alias]; ok {\n\t\t\t\t\t\t\t\t\t\tvisitName(otherRepr, otherName.Ref)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor _, name := range composes.Names {\n\t\t\t\t\t\t\tvisitName(repr, name.Ref)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvisitComposes(css, local.Ref)\n\n\t\t\t\tif len(parts) > 0 {\n\t\t\t\t\tvalue.Data = &js_ast.ETemplate{Parts: append(parts, js_ast.TemplatePart{Value: value})}\n\t\t\t\t}\n\n\t\t\t\texports.Properties = append(exports.Properties, js_ast.Property{\n\t\t\t\t\tKey:        js_ast.Expr{Loc: local.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(c.graph.Symbols.Get(local.Ref).OriginalName)}},\n\t\t\t\t\tValueOrNil: value,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tlazyValue.Data = &exports\n\t\t}\n\t}\n\n\t// Use \"module.exports = value\" for CommonJS-style modules\n\tif repr.AST.ExportsKind == js_ast.ExportsCommonJS {\n\t\tpart.Stmts = []js_ast.Stmt{js_ast.AssignStmt(\n\t\t\tjs_ast.Expr{Loc: lazyValue.Loc, Data: &js_ast.EDot{\n\t\t\t\tTarget:  js_ast.Expr{Loc: lazyValue.Loc, Data: &js_ast.EIdentifier{Ref: repr.AST.ModuleRef}},\n\t\t\t\tName:    \"exports\",\n\t\t\t\tNameLoc: lazyValue.Loc,\n\t\t\t}},\n\t\t\tlazyValue,\n\t\t)}\n\t\tc.graph.GenerateSymbolImportAndUse(sourceIndex, 0, repr.AST.ModuleRef, 1, sourceIndex)\n\t\treturn\n\t}\n\n\t// Otherwise, generate ES6 export statements. These are added as additional\n\t// parts so they can be tree shaken individually.\n\tpart.Stmts = nil\n\n\t// Generate a new symbol and link the export into the graph for tree shaking\n\tgenerateExport := func(loc logger.Loc, name string, alias string) (ast.Ref, uint32) {\n\t\tref := c.graph.GenerateNewSymbol(sourceIndex, ast.SymbolOther, name)\n\t\tpartIndex := c.graph.AddPartToFile(sourceIndex, js_ast.Part{\n\t\t\tDeclaredSymbols:      []js_ast.DeclaredSymbol{{Ref: ref, IsTopLevel: true}},\n\t\t\tCanBeRemovedIfUnused: true,\n\t\t})\n\t\tc.graph.GenerateSymbolImportAndUse(sourceIndex, partIndex, repr.AST.ModuleRef, 1, sourceIndex)\n\t\trepr.Meta.TopLevelSymbolToPartsOverlay[ref] = []uint32{partIndex}\n\t\trepr.Meta.ResolvedExports[alias] = graph.ExportData{\n\t\t\tRef:         ref,\n\t\t\tNameLoc:     loc,\n\t\t\tSourceIndex: sourceIndex,\n\t\t}\n\t\treturn ref, partIndex\n\t}\n\n\t// Unwrap JSON objects into separate top-level variables. This improves tree-\n\t// shaking by letting you only import part of a JSON file.\n\t//\n\t// But don't do this for files loaded via \"with { type: 'json' }\" as that\n\t// behavior is specified to not export anything except for the \"default\"\n\t// export: https://github.com/tc39/proposal-json-modules\n\tif object, ok := lazyValue.Data.(*js_ast.EObject); ok && file.InputFile.Loader != config.LoaderWithTypeJSON {\n\t\tfor _, property := range object.Properties {\n\t\t\tif str, ok := property.Key.Data.(*js_ast.EString); ok &&\n\t\t\t\t(!file.IsEntryPoint() || js_ast.IsIdentifierUTF16(str.Value) ||\n\t\t\t\t\t!c.options.UnsupportedJSFeatures.Has(compat.ArbitraryModuleNamespaceNames)) {\n\t\t\t\tif name := helpers.UTF16ToString(str.Value); name != \"default\" {\n\t\t\t\t\tref, partIndex := generateExport(property.Key.Loc, name, name)\n\n\t\t\t\t\t// This initializes the generated variable with a copy of the property\n\t\t\t\t\t// value, which is INCORRECT for values that are objects/arrays because\n\t\t\t\t\t// they will have separate object identity. This is fixed up later in\n\t\t\t\t\t// \"generateCodeForFileInChunkJS\" by changing the object literal to\n\t\t\t\t\t// reference this generated variable instead.\n\t\t\t\t\t//\n\t\t\t\t\t// Changing the object literal is deferred until that point instead of\n\t\t\t\t\t// doing it now because we only want to do this for top-level variables\n\t\t\t\t\t// that actually end up being used, and we don't know which ones will\n\t\t\t\t\t// end up actually being used at this point (since import binding hasn't\n\t\t\t\t\t// happened yet). So we need to wait until after tree shaking happens.\n\t\t\t\t\trepr.AST.Parts[partIndex].Stmts = []js_ast.Stmt{{Loc: property.Key.Loc, Data: &js_ast.SLocal{\n\t\t\t\t\t\tIsExport: true,\n\t\t\t\t\t\tDecls: []js_ast.Decl{{\n\t\t\t\t\t\t\tBinding:    js_ast.Binding{Loc: property.Key.Loc, Data: &js_ast.BIdentifier{Ref: ref}},\n\t\t\t\t\t\t\tValueOrNil: property.ValueOrNil,\n\t\t\t\t\t\t}},\n\t\t\t\t\t}}}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Generate the default export\n\tref, partIndex := generateExport(lazyValue.Loc, file.InputFile.Source.IdentifierName+\"_default\", \"default\")\n\trepr.AST.Parts[partIndex].Stmts = []js_ast.Stmt{{Loc: lazyValue.Loc, Data: &js_ast.SExportDefault{\n\t\tDefaultName: ast.LocRef{Loc: lazyValue.Loc, Ref: ref},\n\t\tValue:       js_ast.Stmt{Loc: lazyValue.Loc, Data: &js_ast.SExpr{Value: lazyValue}},\n\t}}}\n}\n\nfunc (c *linkerContext) createExportsForFile(sourceIndex uint32) {\n\t////////////////////////////////////////////////////////////////////////////////\n\t// WARNING: This method is run in parallel over all files. Do not mutate data\n\t// for other files within this method or you will create a data race.\n\t////////////////////////////////////////////////////////////////////////////////\n\n\tfile := &c.graph.Files[sourceIndex]\n\trepr := file.InputFile.Repr.(*graph.JSRepr)\n\n\t// Generate a getter per export\n\tproperties := []js_ast.Property{}\n\tnsExportDependencies := []js_ast.Dependency{}\n\tnsExportSymbolUses := make(map[ast.Ref]js_ast.SymbolUse)\n\tfor _, alias := range repr.Meta.SortedAndFilteredExportAliases {\n\t\texport := repr.Meta.ResolvedExports[alias]\n\n\t\t// If this is an export of an import, reference the symbol that the import\n\t\t// was eventually resolved to. We need to do this because imports have\n\t\t// already been resolved by this point, so we can't generate a new import\n\t\t// and have that be resolved later.\n\t\tif importData, ok := c.graph.Files[export.SourceIndex].InputFile.Repr.(*graph.JSRepr).Meta.ImportsToBind[export.Ref]; ok {\n\t\t\texport.Ref = importData.Ref\n\t\t\texport.SourceIndex = importData.SourceIndex\n\t\t\tnsExportDependencies = append(nsExportDependencies, importData.ReExports...)\n\t\t}\n\n\t\t// Exports of imports need EImportIdentifier in case they need to be re-\n\t\t// written to a property access later on\n\t\tvar value js_ast.Expr\n\t\tif c.graph.Symbols.Get(export.Ref).NamespaceAlias != nil {\n\t\t\tvalue = js_ast.Expr{Data: &js_ast.EImportIdentifier{Ref: export.Ref}}\n\t\t} else {\n\t\t\tvalue = js_ast.Expr{Data: &js_ast.EIdentifier{Ref: export.Ref}}\n\t\t}\n\n\t\t// Add a getter property\n\t\tvar getter js_ast.Expr\n\t\tbody := js_ast.FnBody{Block: js_ast.SBlock{Stmts: []js_ast.Stmt{{Loc: value.Loc, Data: &js_ast.SReturn{ValueOrNil: value}}}}}\n\t\tif c.options.UnsupportedJSFeatures.Has(compat.Arrow) {\n\t\t\tgetter = js_ast.Expr{Data: &js_ast.EFunction{Fn: js_ast.Fn{Body: body}}}\n\t\t} else {\n\t\t\tgetter = js_ast.Expr{Data: &js_ast.EArrow{PreferExpr: true, Body: body}}\n\t\t}\n\n\t\t// Special case for __proto__ property: use a computed property\n\t\t// name to avoid it being treated as the object's prototype\n\t\tvar flags js_ast.PropertyFlags\n\t\tif alias == \"__proto__\" && !c.options.UnsupportedJSFeatures.Has(compat.ObjectExtensions) {\n\t\t\tflags |= js_ast.PropertyIsComputed\n\t\t}\n\n\t\tproperties = append(properties, js_ast.Property{\n\t\t\tFlags:      flags,\n\t\t\tKey:        js_ast.Expr{Data: &js_ast.EString{Value: helpers.StringToUTF16(alias)}},\n\t\t\tValueOrNil: getter,\n\t\t})\n\t\tnsExportSymbolUses[export.Ref] = js_ast.SymbolUse{CountEstimate: 1}\n\n\t\t// Make sure the part that declares the export is included\n\t\tfor _, partIndex := range c.graph.Files[export.SourceIndex].InputFile.Repr.(*graph.JSRepr).TopLevelSymbolToParts(export.Ref) {\n\t\t\t// Use a non-local dependency since this is likely from a different\n\t\t\t// file if it came in through an export star\n\t\t\tnsExportDependencies = append(nsExportDependencies, js_ast.Dependency{\n\t\t\t\tSourceIndex: export.SourceIndex,\n\t\t\t\tPartIndex:   partIndex,\n\t\t\t})\n\t\t}\n\t}\n\n\tdeclaredSymbols := []js_ast.DeclaredSymbol{}\n\tvar nsExportStmts []js_ast.Stmt\n\n\t// Prefix this part with \"var exports = {}\" if this isn't a CommonJS entry point\n\tif repr.Meta.NeedsExportsVariable {\n\t\tnsExportStmts = append(nsExportStmts, js_ast.Stmt{Data: &js_ast.SLocal{Decls: []js_ast.Decl{{\n\t\t\tBinding:    js_ast.Binding{Data: &js_ast.BIdentifier{Ref: repr.AST.ExportsRef}},\n\t\t\tValueOrNil: js_ast.Expr{Data: &js_ast.EObject{}},\n\t\t}}}})\n\t\tdeclaredSymbols = append(declaredSymbols, js_ast.DeclaredSymbol{\n\t\t\tRef:        repr.AST.ExportsRef,\n\t\t\tIsTopLevel: true,\n\t\t})\n\t}\n\n\t// \"__export(exports, { foo: () => foo })\"\n\texportRef := ast.InvalidRef\n\tif len(properties) > 0 {\n\t\truntimeRepr := c.graph.Files[runtime.SourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\texportRef = runtimeRepr.AST.ModuleScope.Members[\"__export\"].Ref\n\t\tnsExportStmts = append(nsExportStmts, js_ast.Stmt{Data: &js_ast.SExpr{Value: js_ast.Expr{Data: &js_ast.ECall{\n\t\t\tTarget: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: exportRef}},\n\t\t\tArgs: []js_ast.Expr{\n\t\t\t\t{Data: &js_ast.EIdentifier{Ref: repr.AST.ExportsRef}},\n\t\t\t\t{Data: &js_ast.EObject{\n\t\t\t\t\tProperties: properties,\n\t\t\t\t}},\n\t\t\t},\n\t\t}}}})\n\n\t\t// Make sure this file depends on the \"__export\" symbol\n\t\tfor _, partIndex := range runtimeRepr.TopLevelSymbolToParts(exportRef) {\n\t\t\tnsExportDependencies = append(nsExportDependencies, js_ast.Dependency{\n\t\t\t\tSourceIndex: runtime.SourceIndex,\n\t\t\t\tPartIndex:   partIndex,\n\t\t\t})\n\t\t}\n\n\t\t// Make sure the CommonJS closure, if there is one, includes \"exports\"\n\t\trepr.AST.UsesExportsRef = true\n\t}\n\n\t// Decorate \"module.exports\" with the \"__esModule\" flag to indicate that\n\t// we used to be an ES module. This is done by wrapping the exports object\n\t// instead of by mutating the exports object because other modules in the\n\t// bundle (including the entry point module) may do \"import * as\" to get\n\t// access to the exports object and should NOT see the \"__esModule\" flag.\n\tif repr.Meta.ForceIncludeExportsForEntryPoint &&\n\t\tc.options.OutputFormat == config.FormatCommonJS {\n\n\t\truntimeRepr := c.graph.Files[runtime.SourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\ttoCommonJSRef := runtimeRepr.AST.NamedExports[\"__toCommonJS\"].Ref\n\n\t\t// \"module.exports = __toCommonJS(exports);\"\n\t\tnsExportStmts = append(nsExportStmts, js_ast.AssignStmt(\n\t\t\tjs_ast.Expr{Data: &js_ast.EDot{\n\t\t\t\tTarget: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: c.unboundModuleRef}},\n\t\t\t\tName:   \"exports\",\n\t\t\t}},\n\n\t\t\tjs_ast.Expr{Data: &js_ast.ECall{\n\t\t\t\tTarget: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: toCommonJSRef}},\n\t\t\t\tArgs:   []js_ast.Expr{{Data: &js_ast.EIdentifier{Ref: repr.AST.ExportsRef}}},\n\t\t\t}},\n\t\t))\n\t}\n\n\t// No need to generate a part if it'll be empty\n\tif len(nsExportStmts) > 0 {\n\t\t// Initialize the part that was allocated for us earlier. The information\n\t\t// here will be used after this during tree shaking.\n\t\trepr.AST.Parts[js_ast.NSExportPartIndex] = js_ast.Part{\n\t\t\tStmts:           nsExportStmts,\n\t\t\tSymbolUses:      nsExportSymbolUses,\n\t\t\tDependencies:    nsExportDependencies,\n\t\t\tDeclaredSymbols: declaredSymbols,\n\n\t\t\t// This can be removed if nothing uses it\n\t\t\tCanBeRemovedIfUnused: true,\n\n\t\t\t// Make sure this is trimmed if unused even if tree shaking is disabled\n\t\t\tForceTreeShaking: true,\n\t\t}\n\n\t\t// Pull in the \"__export\" symbol if it was used\n\t\tif exportRef != ast.InvalidRef {\n\t\t\trepr.Meta.NeedsExportSymbolFromRuntime = true\n\t\t}\n\t}\n}\n\nfunc (c *linkerContext) createWrapperForFile(sourceIndex uint32) {\n\trepr := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.JSRepr)\n\n\tswitch repr.Meta.Wrap {\n\t// If this is a CommonJS file, we're going to need to generate a wrapper\n\t// for the CommonJS closure. That will end up looking something like this:\n\t//\n\t//   var require_foo = __commonJS((exports, module) => {\n\t//     ...\n\t//   });\n\t//\n\t// However, that generation is special-cased for various reasons and is\n\t// done later on. Still, we're going to need to ensure that this file\n\t// both depends on the \"__commonJS\" symbol and declares the \"require_foo\"\n\t// symbol. Instead of special-casing this during the reachablity analysis\n\t// below, we just append a dummy part to the end of the file with these\n\t// dependencies and let the general-purpose reachablity analysis take care\n\t// of it.\n\tcase graph.WrapCJS:\n\t\truntimeRepr := c.graph.Files[runtime.SourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\tcommonJSParts := runtimeRepr.TopLevelSymbolToParts(c.cjsRuntimeRef)\n\n\t\t// Generate the dummy part\n\t\tdependencies := make([]js_ast.Dependency, len(commonJSParts))\n\t\tfor i, partIndex := range commonJSParts {\n\t\t\tdependencies[i] = js_ast.Dependency{\n\t\t\t\tSourceIndex: runtime.SourceIndex,\n\t\t\t\tPartIndex:   partIndex,\n\t\t\t}\n\t\t}\n\t\tpartIndex := c.graph.AddPartToFile(sourceIndex, js_ast.Part{\n\t\t\tSymbolUses: map[ast.Ref]js_ast.SymbolUse{\n\t\t\t\trepr.AST.WrapperRef: {CountEstimate: 1},\n\t\t\t},\n\t\t\tDeclaredSymbols: []js_ast.DeclaredSymbol{\n\t\t\t\t{Ref: repr.AST.ExportsRef, IsTopLevel: true},\n\t\t\t\t{Ref: repr.AST.ModuleRef, IsTopLevel: true},\n\t\t\t\t{Ref: repr.AST.WrapperRef, IsTopLevel: true},\n\t\t\t},\n\t\t\tDependencies: dependencies,\n\t\t})\n\t\trepr.Meta.WrapperPartIndex = ast.MakeIndex32(partIndex)\n\t\tc.graph.GenerateSymbolImportAndUse(sourceIndex, partIndex, c.cjsRuntimeRef, 1, runtime.SourceIndex)\n\n\t// If this is a lazily-initialized ESM file, we're going to need to\n\t// generate a wrapper for the ESM closure. That will end up looking\n\t// something like this:\n\t//\n\t//   var init_foo = __esm(() => {\n\t//     ...\n\t//   });\n\t//\n\t// This depends on the \"__esm\" symbol and declares the \"init_foo\" symbol\n\t// for similar reasons to the CommonJS closure above.\n\tcase graph.WrapESM:\n\t\truntimeRepr := c.graph.Files[runtime.SourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\tesmParts := runtimeRepr.TopLevelSymbolToParts(c.esmRuntimeRef)\n\n\t\t// Generate the dummy part\n\t\tdependencies := make([]js_ast.Dependency, len(esmParts))\n\t\tfor i, partIndex := range esmParts {\n\t\t\tdependencies[i] = js_ast.Dependency{\n\t\t\t\tSourceIndex: runtime.SourceIndex,\n\t\t\t\tPartIndex:   partIndex,\n\t\t\t}\n\t\t}\n\t\tpartIndex := c.graph.AddPartToFile(sourceIndex, js_ast.Part{\n\t\t\tSymbolUses: map[ast.Ref]js_ast.SymbolUse{\n\t\t\t\trepr.AST.WrapperRef: {CountEstimate: 1},\n\t\t\t},\n\t\t\tDeclaredSymbols: []js_ast.DeclaredSymbol{\n\t\t\t\t{Ref: repr.AST.WrapperRef, IsTopLevel: true},\n\t\t\t},\n\t\t\tDependencies: dependencies,\n\t\t})\n\t\trepr.Meta.WrapperPartIndex = ast.MakeIndex32(partIndex)\n\t\tc.graph.GenerateSymbolImportAndUse(sourceIndex, partIndex, c.esmRuntimeRef, 1, runtime.SourceIndex)\n\t}\n}\n\nfunc (c *linkerContext) matchImportsWithExportsForFile(sourceIndex uint32) {\n\tfile := &c.graph.Files[sourceIndex]\n\trepr := file.InputFile.Repr.(*graph.JSRepr)\n\n\t// Sort imports for determinism. Otherwise our unit tests will randomly\n\t// fail sometimes when error messages are reordered.\n\tsortedImportRefs := make([]int, 0, len(repr.AST.NamedImports))\n\tfor ref := range repr.AST.NamedImports {\n\t\tsortedImportRefs = append(sortedImportRefs, int(ref.InnerIndex))\n\t}\n\tsort.Ints(sortedImportRefs)\n\n\t// Pair imports with their matching exports\n\tfor _, innerIndex := range sortedImportRefs {\n\t\t// Re-use memory for the cycle detector\n\t\tc.cycleDetector = c.cycleDetector[:0]\n\n\t\timportRef := ast.Ref{SourceIndex: sourceIndex, InnerIndex: uint32(innerIndex)}\n\t\tresult, reExports := c.matchImportWithExport(importTracker{sourceIndex: sourceIndex, importRef: importRef}, nil)\n\t\tswitch result.kind {\n\t\tcase matchImportIgnore:\n\n\t\tcase matchImportNormal:\n\t\t\trepr.Meta.ImportsToBind[importRef] = graph.ImportData{\n\t\t\t\tReExports:   reExports,\n\t\t\t\tSourceIndex: result.sourceIndex,\n\t\t\t\tRef:         result.ref,\n\t\t\t}\n\n\t\tcase matchImportNamespace:\n\t\t\tc.graph.Symbols.Get(importRef).NamespaceAlias = &ast.NamespaceAlias{\n\t\t\t\tNamespaceRef: result.namespaceRef,\n\t\t\t\tAlias:        result.alias,\n\t\t\t}\n\n\t\tcase matchImportNormalAndNamespace:\n\t\t\trepr.Meta.ImportsToBind[importRef] = graph.ImportData{\n\t\t\t\tReExports:   reExports,\n\t\t\t\tSourceIndex: result.sourceIndex,\n\t\t\t\tRef:         result.ref,\n\t\t\t}\n\n\t\t\tc.graph.Symbols.Get(importRef).NamespaceAlias = &ast.NamespaceAlias{\n\t\t\t\tNamespaceRef: result.namespaceRef,\n\t\t\t\tAlias:        result.alias,\n\t\t\t}\n\n\t\tcase matchImportCycle:\n\t\t\tnamedImport := repr.AST.NamedImports[importRef]\n\t\t\tc.log.AddError(file.LineColumnTracker(), js_lexer.RangeOfIdentifier(file.InputFile.Source, namedImport.AliasLoc),\n\t\t\t\tfmt.Sprintf(\"Detected cycle while resolving import %q\", namedImport.Alias))\n\n\t\tcase matchImportProbablyTypeScriptType:\n\t\t\trepr.Meta.IsProbablyTypeScriptType[importRef] = true\n\n\t\tcase matchImportAmbiguous:\n\t\t\tnamedImport := repr.AST.NamedImports[importRef]\n\t\t\tr := js_lexer.RangeOfIdentifier(file.InputFile.Source, namedImport.AliasLoc)\n\t\t\tvar notes []logger.MsgData\n\n\t\t\t// Provide the locations of both ambiguous exports if possible\n\t\t\tif result.nameLoc.Start != 0 && result.otherNameLoc.Start != 0 {\n\t\t\t\ta := c.graph.Files[result.sourceIndex]\n\t\t\t\tb := c.graph.Files[result.otherSourceIndex]\n\t\t\t\tra := js_lexer.RangeOfIdentifier(a.InputFile.Source, result.nameLoc)\n\t\t\t\trb := js_lexer.RangeOfIdentifier(b.InputFile.Source, result.otherNameLoc)\n\t\t\t\tnotes = []logger.MsgData{\n\t\t\t\t\ta.LineColumnTracker().MsgData(ra, \"One matching export is here:\"),\n\t\t\t\t\tb.LineColumnTracker().MsgData(rb, \"Another matching export is here:\"),\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsymbol := c.graph.Symbols.Get(importRef)\n\t\t\tif symbol.ImportItemStatus == ast.ImportItemGenerated {\n\t\t\t\t// This is a warning instead of an error because although it appears\n\t\t\t\t// to be a named import, it's actually an automatically-generated\n\t\t\t\t// named import that was originally a property access on an import\n\t\t\t\t// star namespace object. Normally this property access would just\n\t\t\t\t// resolve to undefined at run-time instead of failing at binding-\n\t\t\t\t// time, so we emit a warning and rewrite the value to the literal\n\t\t\t\t// \"undefined\" instead of emitting an error.\n\t\t\t\tsymbol.ImportItemStatus = ast.ImportItemMissing\n\t\t\t\tmsg := fmt.Sprintf(\"Import %q will always be undefined because there are multiple matching exports\", namedImport.Alias)\n\t\t\t\tc.log.AddIDWithNotes(logger.MsgID_Bundler_ImportIsUndefined, logger.Warning, file.LineColumnTracker(), r, msg, notes)\n\t\t\t} else {\n\t\t\t\tmsg := fmt.Sprintf(\"Ambiguous import %q has multiple matching exports\", namedImport.Alias)\n\t\t\t\tc.log.AddErrorWithNotes(file.LineColumnTracker(), r, msg, notes)\n\t\t\t}\n\t\t}\n\t}\n}\n\ntype matchImportKind uint8\n\nconst (\n\t// The import is either external or undefined\n\tmatchImportIgnore matchImportKind = iota\n\n\t// \"sourceIndex\" and \"ref\" are in use\n\tmatchImportNormal\n\n\t// \"namespaceRef\" and \"alias\" are in use\n\tmatchImportNamespace\n\n\t// Both \"matchImportNormal\" and \"matchImportNamespace\"\n\tmatchImportNormalAndNamespace\n\n\t// The import could not be evaluated due to a cycle\n\tmatchImportCycle\n\n\t// The import is missing but came from a TypeScript file\n\tmatchImportProbablyTypeScriptType\n\n\t// The import resolved to multiple symbols via \"export * from\"\n\tmatchImportAmbiguous\n)\n\ntype matchImportResult struct {\n\talias            string\n\tkind             matchImportKind\n\tnamespaceRef     ast.Ref\n\tsourceIndex      uint32\n\tnameLoc          logger.Loc // Optional, goes with sourceIndex, ignore if zero\n\totherSourceIndex uint32\n\totherNameLoc     logger.Loc // Optional, goes with otherSourceIndex, ignore if zero\n\tref              ast.Ref\n}\n\nfunc (c *linkerContext) matchImportWithExport(\n\ttracker importTracker, reExportsIn []js_ast.Dependency,\n) (result matchImportResult, reExports []js_ast.Dependency) {\n\tvar ambiguousResults []matchImportResult\n\treExports = reExportsIn\n\nloop:\n\tfor {\n\t\t// Make sure we avoid infinite loops trying to resolve cycles:\n\t\t//\n\t\t//   // foo.js\n\t\t//   export {a as b} from './foo.js'\n\t\t//   export {b as c} from './foo.js'\n\t\t//   export {c as a} from './foo.js'\n\t\t//\n\t\t// This uses a O(n^2) array scan instead of a O(n) map because the vast\n\t\t// majority of cases have one or two elements and Go arrays are cheap to\n\t\t// reuse without allocating.\n\t\tfor _, previousTracker := range c.cycleDetector {\n\t\t\tif tracker == previousTracker {\n\t\t\t\tresult = matchImportResult{kind: matchImportCycle}\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t}\n\t\tc.cycleDetector = append(c.cycleDetector, tracker)\n\n\t\t// Resolve the import by one step\n\t\tnextTracker, status, potentiallyAmbiguousExportStarRefs := c.advanceImportTracker(tracker)\n\t\tswitch status {\n\t\tcase importCommonJS, importCommonJSWithoutExports, importExternal, importDisabled:\n\t\t\tif status == importExternal && c.options.OutputFormat.KeepESMImportExportSyntax() {\n\t\t\t\t// Imports from external modules should not be converted to CommonJS\n\t\t\t\t// if the output format preserves the original ES6 import statements\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// If it's a CommonJS or external file, rewrite the import to a\n\t\t\t// property access. Don't do this if the namespace reference is invalid\n\t\t\t// though. This is the case for star imports, where the import is the\n\t\t\t// namespace.\n\t\t\ttrackerFile := &c.graph.Files[tracker.sourceIndex]\n\t\t\tnamedImport := trackerFile.InputFile.Repr.(*graph.JSRepr).AST.NamedImports[tracker.importRef]\n\t\t\tif namedImport.NamespaceRef != ast.InvalidRef {\n\t\t\t\tif result.kind == matchImportNormal {\n\t\t\t\t\tresult.kind = matchImportNormalAndNamespace\n\t\t\t\t\tresult.namespaceRef = namedImport.NamespaceRef\n\t\t\t\t\tresult.alias = namedImport.Alias\n\t\t\t\t} else {\n\t\t\t\t\tresult = matchImportResult{\n\t\t\t\t\t\tkind:         matchImportNamespace,\n\t\t\t\t\t\tnamespaceRef: namedImport.NamespaceRef,\n\t\t\t\t\t\talias:        namedImport.Alias,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Warn about importing from a file that is known to not have any exports\n\t\t\tif status == importCommonJSWithoutExports {\n\t\t\t\tsymbol := c.graph.Symbols.Get(tracker.importRef)\n\t\t\t\tsymbol.ImportItemStatus = ast.ImportItemMissing\n\t\t\t\tkind := logger.Warning\n\t\t\t\tif helpers.IsInsideNodeModules(trackerFile.InputFile.Source.KeyPath.Text) {\n\t\t\t\t\tkind = logger.Debug\n\t\t\t\t}\n\t\t\t\tc.log.AddID(logger.MsgID_Bundler_ImportIsUndefined, kind,\n\t\t\t\t\ttrackerFile.LineColumnTracker(),\n\t\t\t\t\tjs_lexer.RangeOfIdentifier(trackerFile.InputFile.Source, namedImport.AliasLoc),\n\t\t\t\t\tfmt.Sprintf(\"Import %q will always be undefined because the file %q has no exports\", namedImport.Alias,\n\t\t\t\t\t\tc.graph.Files[nextTracker.sourceIndex].InputFile.Source.PrettyPaths.Select(c.options.LogPathStyle)))\n\t\t\t}\n\n\t\tcase importDynamicFallback:\n\t\t\t// If it's a file with dynamic export fallback, rewrite the import to a property access\n\t\t\ttrackerFile := &c.graph.Files[tracker.sourceIndex]\n\t\t\tnamedImport := trackerFile.InputFile.Repr.(*graph.JSRepr).AST.NamedImports[tracker.importRef]\n\t\t\tif result.kind == matchImportNormal {\n\t\t\t\tresult.kind = matchImportNormalAndNamespace\n\t\t\t\tresult.namespaceRef = nextTracker.importRef\n\t\t\t\tresult.alias = namedImport.Alias\n\t\t\t} else {\n\t\t\t\tresult = matchImportResult{\n\t\t\t\t\tkind:         matchImportNamespace,\n\t\t\t\t\tnamespaceRef: nextTracker.importRef,\n\t\t\t\t\talias:        namedImport.Alias,\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase importNoMatch:\n\t\t\tsymbol := c.graph.Symbols.Get(tracker.importRef)\n\t\t\ttrackerFile := &c.graph.Files[tracker.sourceIndex]\n\t\t\tnamedImport := trackerFile.InputFile.Repr.(*graph.JSRepr).AST.NamedImports[tracker.importRef]\n\t\t\tr := js_lexer.RangeOfIdentifier(trackerFile.InputFile.Source, namedImport.AliasLoc)\n\n\t\t\t// Report mismatched imports and exports\n\t\t\tif symbol.ImportItemStatus == ast.ImportItemGenerated {\n\t\t\t\t// This is not an error because although it appears to be a named\n\t\t\t\t// import, it's actually an automatically-generated named import\n\t\t\t\t// that was originally a property access on an import star\n\t\t\t\t// namespace object:\n\t\t\t\t//\n\t\t\t\t//   import * as ns from 'foo'\n\t\t\t\t//   const undefinedValue = ns.notAnExport\n\t\t\t\t//\n\t\t\t\t// If this code wasn't bundled, this property access would just resolve\n\t\t\t\t// to undefined at run-time instead of failing at binding-time, so we\n\t\t\t\t// emit rewrite the value to the literal \"undefined\" instead of\n\t\t\t\t// emitting an error.\n\t\t\t\tsymbol.ImportItemStatus = ast.ImportItemMissing\n\n\t\t\t\t// Don't emit a log message if this symbol isn't used, since then the\n\t\t\t\t// log message isn't helpful. This can happen with \"import\" assignment\n\t\t\t\t// statements in TypeScript code since they are ambiguously either a\n\t\t\t\t// type or a value. We consider them to be a type if they aren't used.\n\t\t\t\t//\n\t\t\t\t//   import * as ns from 'foo'\n\t\t\t\t//\n\t\t\t\t//   // There's no warning here because this is dead code\n\t\t\t\t//   if (false) ns.notAnExport\n\t\t\t\t//\n\t\t\t\t//   // There's no warning here because this is never used\n\t\t\t\t//   import unused = ns.notAnExport\n\t\t\t\t//\n\t\t\t\tif symbol.UseCountEstimate > 0 {\n\t\t\t\t\tnextFile := &c.graph.Files[nextTracker.sourceIndex].InputFile\n\t\t\t\t\tmsg := logger.Msg{\n\t\t\t\t\t\tKind: logger.Warning,\n\t\t\t\t\t\tData: trackerFile.LineColumnTracker().MsgData(r, fmt.Sprintf(\n\t\t\t\t\t\t\t\"Import %q will always be undefined because there is no matching export in %q\",\n\t\t\t\t\t\t\tnamedImport.Alias, nextFile.Source.PrettyPaths.Select(c.options.LogPathStyle))),\n\t\t\t\t\t}\n\t\t\t\t\tif helpers.IsInsideNodeModules(trackerFile.InputFile.Source.KeyPath.Text) {\n\t\t\t\t\t\tmsg.Kind = logger.Debug\n\t\t\t\t\t}\n\t\t\t\t\tc.maybeCorrectObviousTypo(nextFile.Repr.(*graph.JSRepr), namedImport.Alias, &msg)\n\t\t\t\t\tc.log.AddMsgID(logger.MsgID_Bundler_ImportIsUndefined, msg)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnextFile := &c.graph.Files[nextTracker.sourceIndex].InputFile\n\t\t\t\tmsg := logger.Msg{\n\t\t\t\t\tKind: logger.Error,\n\t\t\t\t\tData: trackerFile.LineColumnTracker().MsgData(r, fmt.Sprintf(\n\t\t\t\t\t\t\"No matching export in %q for import %q\",\n\t\t\t\t\t\tnextFile.Source.PrettyPaths.Select(c.options.LogPathStyle), namedImport.Alias)),\n\t\t\t\t}\n\t\t\t\tc.maybeCorrectObviousTypo(nextFile.Repr.(*graph.JSRepr), namedImport.Alias, &msg)\n\t\t\t\tc.log.AddMsg(msg)\n\t\t\t}\n\n\t\tcase importProbablyTypeScriptType:\n\t\t\t// Omit this import from any namespace export code we generate for\n\t\t\t// import star statements (i.e. \"import * as ns from 'path'\")\n\t\t\tresult = matchImportResult{kind: matchImportProbablyTypeScriptType}\n\n\t\tcase importFound:\n\t\t\t// If there are multiple ambiguous results due to use of \"export * from\"\n\t\t\t// statements, trace them all to see if they point to different things.\n\t\t\tfor _, ambiguousTracker := range potentiallyAmbiguousExportStarRefs {\n\t\t\t\t// If this is a re-export of another import, follow the import\n\t\t\t\tif _, ok := c.graph.Files[ambiguousTracker.SourceIndex].InputFile.Repr.(*graph.JSRepr).AST.NamedImports[ambiguousTracker.Ref]; ok {\n\t\t\t\t\t// Save and restore the cycle detector to avoid mixing information\n\t\t\t\t\toldCycleDetector := c.cycleDetector\n\t\t\t\t\tambiguousResult, newReExportFiles := c.matchImportWithExport(importTracker{\n\t\t\t\t\t\tsourceIndex: ambiguousTracker.SourceIndex,\n\t\t\t\t\t\timportRef:   ambiguousTracker.Ref,\n\t\t\t\t\t}, reExports)\n\t\t\t\t\tc.cycleDetector = oldCycleDetector\n\t\t\t\t\tambiguousResults = append(ambiguousResults, ambiguousResult)\n\t\t\t\t\treExports = newReExportFiles\n\t\t\t\t} else {\n\t\t\t\t\tambiguousResults = append(ambiguousResults, matchImportResult{\n\t\t\t\t\t\tkind:        matchImportNormal,\n\t\t\t\t\t\tsourceIndex: ambiguousTracker.SourceIndex,\n\t\t\t\t\t\tref:         ambiguousTracker.Ref,\n\t\t\t\t\t\tnameLoc:     ambiguousTracker.NameLoc,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Defer the actual binding of this import until after we generate\n\t\t\t// namespace export code for all files. This has to be done for all\n\t\t\t// import-to-export matches, not just the initial import to the final\n\t\t\t// export, since all imports and re-exports must be merged together\n\t\t\t// for correctness.\n\t\t\tresult = matchImportResult{\n\t\t\t\tkind:        matchImportNormal,\n\t\t\t\tsourceIndex: nextTracker.sourceIndex,\n\t\t\t\tref:         nextTracker.importRef,\n\t\t\t\tnameLoc:     nextTracker.nameLoc,\n\t\t\t}\n\n\t\t\t// Depend on the statement(s) that declared this import symbol in the\n\t\t\t// original file\n\t\t\tfor _, resolvedPartIndex := range c.graph.Files[tracker.sourceIndex].InputFile.Repr.(*graph.JSRepr).TopLevelSymbolToParts(tracker.importRef) {\n\t\t\t\treExports = append(reExports, js_ast.Dependency{\n\t\t\t\t\tSourceIndex: tracker.sourceIndex,\n\t\t\t\t\tPartIndex:   resolvedPartIndex,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// If this is a re-export of another import, continue for another\n\t\t\t// iteration of the loop to resolve that import as well\n\t\t\tif _, ok := c.graph.Files[nextTracker.sourceIndex].InputFile.Repr.(*graph.JSRepr).AST.NamedImports[nextTracker.importRef]; ok {\n\t\t\t\ttracker = nextTracker\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tdefault:\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\n\t\t// Stop now if we didn't explicitly \"continue\" above\n\t\tbreak\n\t}\n\n\t// If there is a potential ambiguity, all results must be the same\n\tfor _, ambiguousResult := range ambiguousResults {\n\t\tif ambiguousResult != result {\n\t\t\tif result.kind == matchImportNormal && ambiguousResult.kind == matchImportNormal &&\n\t\t\t\tresult.nameLoc.Start != 0 && ambiguousResult.nameLoc.Start != 0 {\n\t\t\t\treturn matchImportResult{\n\t\t\t\t\tkind:             matchImportAmbiguous,\n\t\t\t\t\tsourceIndex:      result.sourceIndex,\n\t\t\t\t\tnameLoc:          result.nameLoc,\n\t\t\t\t\totherSourceIndex: ambiguousResult.sourceIndex,\n\t\t\t\t\totherNameLoc:     ambiguousResult.nameLoc,\n\t\t\t\t}, nil\n\t\t\t}\n\t\t\treturn matchImportResult{kind: matchImportAmbiguous}, nil\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc (c *linkerContext) maybeForbidArbitraryModuleNamespaceIdentifier(kind string, sourceIndex uint32, loc logger.Loc, alias string) {\n\tif !js_ast.IsIdentifier(alias) {\n\t\tfile := &c.graph.Files[sourceIndex]\n\t\twhere := config.PrettyPrintTargetEnvironment(c.options.OriginalTargetEnv, c.options.UnsupportedJSFeatureOverridesMask)\n\t\tc.log.AddError(file.LineColumnTracker(), file.InputFile.Source.RangeOfString(loc), fmt.Sprintf(\n\t\t\t\"Using the string %q as an %s name is not supported in %s\", alias, kind, where))\n\t}\n}\n\n// Attempt to correct an import name with a typo\nfunc (c *linkerContext) maybeCorrectObviousTypo(repr *graph.JSRepr, name string, msg *logger.Msg) {\n\tif repr.Meta.ResolvedExportTypos == nil {\n\t\tvalid := make([]string, 0, len(repr.Meta.ResolvedExports))\n\t\tfor alias := range repr.Meta.ResolvedExports {\n\t\t\tvalid = append(valid, alias)\n\t\t}\n\t\tsort.Strings(valid)\n\t\ttypos := helpers.MakeTypoDetector(valid)\n\t\trepr.Meta.ResolvedExportTypos = &typos\n\t}\n\n\tif corrected, ok := repr.Meta.ResolvedExportTypos.MaybeCorrectTypo(name); ok {\n\t\tmsg.Data.Location.Suggestion = corrected\n\t\texport := repr.Meta.ResolvedExports[corrected]\n\t\timportedFile := &c.graph.Files[export.SourceIndex]\n\t\ttext := fmt.Sprintf(\"Did you mean to import %q instead?\", corrected)\n\t\tvar note logger.MsgData\n\t\tif export.NameLoc.Start == 0 {\n\t\t\t// Don't report a source location for definitions without one. This can\n\t\t\t// happen with automatically-generated exports from non-JavaScript files.\n\t\t\tnote.Text = text\n\t\t} else {\n\t\t\tvar r logger.Range\n\t\t\tif importedFile.InputFile.Loader.IsCSS() {\n\t\t\t\tr = css_lexer.RangeOfIdentifier(importedFile.InputFile.Source, export.NameLoc)\n\t\t\t} else {\n\t\t\t\tr = js_lexer.RangeOfIdentifier(importedFile.InputFile.Source, export.NameLoc)\n\t\t\t}\n\t\t\tnote = importedFile.LineColumnTracker().MsgData(r, text)\n\t\t}\n\t\tmsg.Notes = append(msg.Notes, note)\n\t}\n}\n\nfunc (c *linkerContext) recursivelyWrapDependencies(sourceIndex uint32) {\n\trepr := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.JSRepr)\n\tif repr.Meta.DidWrapDependencies {\n\t\treturn\n\t}\n\trepr.Meta.DidWrapDependencies = true\n\n\t// Never wrap the runtime file since it always comes first\n\tif sourceIndex == runtime.SourceIndex {\n\t\treturn\n\t}\n\n\t// This module must be wrapped\n\tif repr.Meta.Wrap == graph.WrapNone {\n\t\tif repr.AST.ExportsKind == js_ast.ExportsCommonJS {\n\t\t\trepr.Meta.Wrap = graph.WrapCJS\n\t\t} else {\n\t\t\trepr.Meta.Wrap = graph.WrapESM\n\t\t}\n\t}\n\n\t// All dependencies must also be wrapped\n\tfor _, record := range repr.AST.ImportRecords {\n\t\tif record.SourceIndex.IsValid() {\n\t\t\tc.recursivelyWrapDependencies(record.SourceIndex.GetIndex())\n\t\t}\n\t}\n}\n\nfunc (c *linkerContext) hasDynamicExportsDueToExportStar(sourceIndex uint32, visited map[uint32]bool) bool {\n\t// Terminate the traversal now if this file already has dynamic exports\n\trepr := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.JSRepr)\n\tif repr.AST.ExportsKind == js_ast.ExportsCommonJS || repr.AST.ExportsKind == js_ast.ExportsESMWithDynamicFallback {\n\t\treturn true\n\t}\n\n\t// Avoid infinite loops due to cycles in the export star graph\n\tif visited[sourceIndex] {\n\t\treturn false\n\t}\n\tvisited[sourceIndex] = true\n\n\t// Scan over the export star graph\n\tfor _, importRecordIndex := range repr.AST.ExportStarImportRecords {\n\t\trecord := &repr.AST.ImportRecords[importRecordIndex]\n\n\t\t// This file has dynamic exports if the exported imports are from a file\n\t\t// that either has dynamic exports directly or transitively by itself\n\t\t// having an export star from a file with dynamic exports.\n\t\tif (!record.SourceIndex.IsValid() && (!c.graph.Files[sourceIndex].IsEntryPoint() || !c.options.OutputFormat.KeepESMImportExportSyntax())) ||\n\t\t\t(record.SourceIndex.IsValid() && record.SourceIndex.GetIndex() != sourceIndex && c.hasDynamicExportsDueToExportStar(record.SourceIndex.GetIndex(), visited)) {\n\t\t\trepr.AST.ExportsKind = js_ast.ExportsESMWithDynamicFallback\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc (c *linkerContext) addExportsForExportStar(\n\tresolvedExports map[string]graph.ExportData,\n\tsourceIndex uint32,\n\tsourceIndexStack []uint32,\n) {\n\t// Avoid infinite loops due to cycles in the export star graph\n\tfor _, prevSourceIndex := range sourceIndexStack {\n\t\tif prevSourceIndex == sourceIndex {\n\t\t\treturn\n\t\t}\n\t}\n\tsourceIndexStack = append(sourceIndexStack, sourceIndex)\n\trepr := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.JSRepr)\n\n\tfor _, importRecordIndex := range repr.AST.ExportStarImportRecords {\n\t\trecord := &repr.AST.ImportRecords[importRecordIndex]\n\t\tif !record.SourceIndex.IsValid() {\n\t\t\t// This will be resolved at run time instead\n\t\t\tcontinue\n\t\t}\n\t\totherSourceIndex := record.SourceIndex.GetIndex()\n\n\t\t// Export stars from a CommonJS module don't work because they can't be\n\t\t// statically discovered. Just silently ignore them in this case.\n\t\t//\n\t\t// We could attempt to check whether the imported file still has ES6\n\t\t// exports even though it still uses CommonJS features. However, when\n\t\t// doing this we'd also have to rewrite any imports of these export star\n\t\t// re-exports as property accesses off of a generated require() call.\n\t\totherRepr := c.graph.Files[otherSourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\tif otherRepr.AST.ExportsKind == js_ast.ExportsCommonJS {\n\t\t\t// All exports will be resolved at run time instead\n\t\t\tcontinue\n\t\t}\n\n\t\t// Accumulate this file's exports\n\tnextExport:\n\t\tfor alias, name := range otherRepr.AST.NamedExports {\n\t\t\t// ES6 export star statements ignore exports named \"default\"\n\t\t\tif alias == \"default\" {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// This export star is shadowed if any file in the stack has a matching real named export\n\t\t\tfor _, prevSourceIndex := range sourceIndexStack {\n\t\t\t\tprevRepr := c.graph.Files[prevSourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\t\t\tif _, ok := prevRepr.AST.NamedExports[alias]; ok {\n\t\t\t\t\tcontinue nextExport\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif existing, ok := resolvedExports[alias]; !ok {\n\t\t\t\t// Initialize the re-export\n\t\t\t\tresolvedExports[alias] = graph.ExportData{\n\t\t\t\t\tRef:         name.Ref,\n\t\t\t\t\tSourceIndex: otherSourceIndex,\n\t\t\t\t\tNameLoc:     name.AliasLoc,\n\t\t\t\t}\n\n\t\t\t\t// Make sure the symbol is marked as imported so that code splitting\n\t\t\t\t// imports it correctly if it ends up being shared with another chunk\n\t\t\t\trepr.Meta.ImportsToBind[name.Ref] = graph.ImportData{\n\t\t\t\t\tRef:         name.Ref,\n\t\t\t\t\tSourceIndex: otherSourceIndex,\n\t\t\t\t}\n\t\t\t} else if existing.SourceIndex != otherSourceIndex {\n\t\t\t\t// Two different re-exports colliding makes it potentially ambiguous\n\t\t\t\texisting.PotentiallyAmbiguousExportStarRefs =\n\t\t\t\t\tappend(existing.PotentiallyAmbiguousExportStarRefs, graph.ImportData{\n\t\t\t\t\t\tSourceIndex: otherSourceIndex,\n\t\t\t\t\t\tRef:         name.Ref,\n\t\t\t\t\t\tNameLoc:     name.AliasLoc,\n\t\t\t\t\t})\n\t\t\t\tresolvedExports[alias] = existing\n\t\t\t}\n\t\t}\n\n\t\t// Search further through this file's export stars\n\t\tc.addExportsForExportStar(resolvedExports, otherSourceIndex, sourceIndexStack)\n\t}\n}\n\ntype importTracker struct {\n\tsourceIndex uint32\n\tnameLoc     logger.Loc // Optional, goes with sourceIndex, ignore if zero\n\timportRef   ast.Ref\n}\n\ntype importStatus uint8\n\nconst (\n\t// The imported file has no matching export\n\timportNoMatch importStatus = iota\n\n\t// The imported file has a matching export\n\timportFound\n\n\t// The imported file is CommonJS and has unknown exports\n\timportCommonJS\n\n\t// The import is missing but there is a dynamic fallback object\n\timportDynamicFallback\n\n\t// The import was treated as a CommonJS import but the file is known to have no exports\n\timportCommonJSWithoutExports\n\n\t// The imported file was disabled by mapping it to false in the \"browser\"\n\t// field of package.json\n\timportDisabled\n\n\t// The imported file is external and has unknown exports\n\timportExternal\n\n\t// This is a missing re-export in a TypeScript file, so it's probably a type\n\timportProbablyTypeScriptType\n)\n\nfunc (c *linkerContext) advanceImportTracker(tracker importTracker) (importTracker, importStatus, []graph.ImportData) {\n\tfile := &c.graph.Files[tracker.sourceIndex]\n\trepr := file.InputFile.Repr.(*graph.JSRepr)\n\tnamedImport := repr.AST.NamedImports[tracker.importRef]\n\n\t// Is this an external file?\n\trecord := &repr.AST.ImportRecords[namedImport.ImportRecordIndex]\n\tif !record.SourceIndex.IsValid() {\n\t\treturn importTracker{}, importExternal, nil\n\t}\n\n\t// Is this a named import of a file without any exports?\n\totherSourceIndex := record.SourceIndex.GetIndex()\n\totherRepr := c.graph.Files[otherSourceIndex].InputFile.Repr.(*graph.JSRepr)\n\tif !namedImport.AliasIsStar && !otherRepr.AST.HasLazyExport &&\n\t\t// CommonJS exports\n\t\totherRepr.AST.ExportKeyword.Len == 0 && namedImport.Alias != \"default\" &&\n\t\t// ESM exports\n\t\t!otherRepr.AST.UsesExportsRef && !otherRepr.AST.UsesModuleRef {\n\t\t// Just warn about it and replace the import with \"undefined\"\n\t\treturn importTracker{sourceIndex: otherSourceIndex, importRef: ast.InvalidRef}, importCommonJSWithoutExports, nil\n\t}\n\n\t// Is this a CommonJS file?\n\tif otherRepr.AST.ExportsKind == js_ast.ExportsCommonJS {\n\t\treturn importTracker{sourceIndex: otherSourceIndex, importRef: ast.InvalidRef}, importCommonJS, nil\n\t}\n\n\t// Match this import star with an export star from the imported file\n\tif matchingExport := otherRepr.Meta.ResolvedExportStar; namedImport.AliasIsStar && matchingExport != nil {\n\t\t// Check to see if this is a re-export of another import\n\t\treturn importTracker{\n\t\t\tsourceIndex: matchingExport.SourceIndex,\n\t\t\timportRef:   matchingExport.Ref,\n\t\t\tnameLoc:     matchingExport.NameLoc,\n\t\t}, importFound, matchingExport.PotentiallyAmbiguousExportStarRefs\n\t}\n\n\t// Match this import up with an export from the imported file\n\tif matchingExport, ok := otherRepr.Meta.ResolvedExports[namedImport.Alias]; ok {\n\t\t// Check to see if this is a re-export of another import\n\t\treturn importTracker{\n\t\t\tsourceIndex: matchingExport.SourceIndex,\n\t\t\timportRef:   matchingExport.Ref,\n\t\t\tnameLoc:     matchingExport.NameLoc,\n\t\t}, importFound, matchingExport.PotentiallyAmbiguousExportStarRefs\n\t}\n\n\t// Is this a file with dynamic exports?\n\tif otherRepr.AST.ExportsKind == js_ast.ExportsESMWithDynamicFallback {\n\t\treturn importTracker{sourceIndex: otherSourceIndex, importRef: otherRepr.AST.ExportsRef}, importDynamicFallback, nil\n\t}\n\n\t// Missing re-exports in TypeScript files are indistinguishable from types\n\tif file.InputFile.Loader.IsTypeScript() && namedImport.IsExported {\n\t\treturn importTracker{}, importProbablyTypeScriptType, nil\n\t}\n\n\treturn importTracker{sourceIndex: otherSourceIndex}, importNoMatch, nil\n}\n\nfunc (c *linkerContext) treeShakingAndCodeSplitting() {\n\t// Tree shaking: Each entry point marks all files reachable from itself\n\tc.timer.Begin(\"Tree shaking\")\n\tfor _, entryPoint := range c.graph.EntryPoints() {\n\t\tc.markFileLiveForTreeShaking(entryPoint.SourceIndex)\n\t}\n\tc.timer.End(\"Tree shaking\")\n\n\t// Code splitting: Determine which entry points can reach which files. This\n\t// has to happen after tree shaking because there is an implicit dependency\n\t// between live parts within the same file. All liveness has to be computed\n\t// first before determining which entry points can reach which files.\n\tc.timer.Begin(\"Code splitting\")\n\tfor i, entryPoint := range c.graph.EntryPoints() {\n\t\tc.markFileReachableForCodeSplitting(entryPoint.SourceIndex, uint(i), 0)\n\t}\n\tc.timer.End(\"Code splitting\")\n}\n\nfunc (c *linkerContext) markFileReachableForCodeSplitting(sourceIndex uint32, entryPointBit uint, distanceFromEntryPoint uint32) {\n\tfile := &c.graph.Files[sourceIndex]\n\tif !file.IsLive {\n\t\treturn\n\t}\n\ttraverseAgain := false\n\n\t// Track the minimum distance to an entry point\n\tif distanceFromEntryPoint < file.DistanceFromEntryPoint {\n\t\tfile.DistanceFromEntryPoint = distanceFromEntryPoint\n\t\ttraverseAgain = true\n\t}\n\tdistanceFromEntryPoint++\n\n\t// Don't mark this file more than once\n\tif file.EntryBits.HasBit(entryPointBit) && !traverseAgain {\n\t\treturn\n\t}\n\tfile.EntryBits.SetBit(entryPointBit)\n\n\tswitch repr := file.InputFile.Repr.(type) {\n\tcase *graph.JSRepr:\n\t\t// If the JavaScript stub for a CSS file is included, also include the CSS file\n\t\tif repr.CSSSourceIndex.IsValid() {\n\t\t\tc.markFileReachableForCodeSplitting(repr.CSSSourceIndex.GetIndex(), entryPointBit, distanceFromEntryPoint)\n\t\t}\n\n\t\t// Traverse into all imported files\n\t\tfor _, record := range repr.AST.ImportRecords {\n\t\t\tif record.SourceIndex.IsValid() && !c.isExternalDynamicImport(&record, sourceIndex) {\n\t\t\t\tc.markFileReachableForCodeSplitting(record.SourceIndex.GetIndex(), entryPointBit, distanceFromEntryPoint)\n\t\t\t}\n\t\t}\n\n\t\t// Traverse into all dependencies of all parts in this file\n\t\tfor _, part := range repr.AST.Parts {\n\t\t\tfor _, dependency := range part.Dependencies {\n\t\t\t\tif dependency.SourceIndex != sourceIndex {\n\t\t\t\t\tc.markFileReachableForCodeSplitting(dependency.SourceIndex, entryPointBit, distanceFromEntryPoint)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\tcase *graph.CSSRepr:\n\t\t// Traverse into all dependencies\n\t\tfor _, record := range repr.AST.ImportRecords {\n\t\t\tif record.SourceIndex.IsValid() {\n\t\t\t\tc.markFileReachableForCodeSplitting(record.SourceIndex.GetIndex(), entryPointBit, distanceFromEntryPoint)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (c *linkerContext) markFileLiveForTreeShaking(sourceIndex uint32) {\n\tfile := &c.graph.Files[sourceIndex]\n\n\t// Don't mark this file more than once\n\tif file.IsLive {\n\t\treturn\n\t}\n\tfile.IsLive = true\n\n\tswitch repr := file.InputFile.Repr.(type) {\n\tcase *graph.JSRepr:\n\t\t// If the JavaScript stub for a CSS file is included, also include the CSS file\n\t\tif repr.CSSSourceIndex.IsValid() {\n\t\t\tc.markFileLiveForTreeShaking(repr.CSSSourceIndex.GetIndex())\n\t\t}\n\n\t\tfor partIndex, part := range repr.AST.Parts {\n\t\t\tcanBeRemovedIfUnused := part.CanBeRemovedIfUnused\n\n\t\t\t// Also include any statement-level imports\n\t\t\tfor _, importRecordIndex := range part.ImportRecordIndices {\n\t\t\t\trecord := &repr.AST.ImportRecords[importRecordIndex]\n\t\t\t\tif record.Kind != ast.ImportStmt {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif record.SourceIndex.IsValid() {\n\t\t\t\t\totherSourceIndex := record.SourceIndex.GetIndex()\n\n\t\t\t\t\t// Don't include this module for its side effects if it can be\n\t\t\t\t\t// considered to have no side effects\n\t\t\t\t\tif otherFile := &c.graph.Files[otherSourceIndex]; otherFile.InputFile.SideEffects.Kind != graph.HasSideEffects && !c.options.IgnoreDCEAnnotations {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// Otherwise, include this module for its side effects\n\t\t\t\t\tc.markFileLiveForTreeShaking(otherSourceIndex)\n\t\t\t\t} else if record.Flags.Has(ast.IsExternalWithoutSideEffects) {\n\t\t\t\t\t// This can be removed if it's unused\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// If we get here then the import was included for its side effects, so\n\t\t\t\t// we must also keep this part\n\t\t\t\tcanBeRemovedIfUnused = false\n\t\t\t}\n\n\t\t\t// Include all parts in this file with side effects, or just include\n\t\t\t// everything if tree-shaking is disabled. Note that we still want to\n\t\t\t// perform tree-shaking on the runtime even if tree-shaking is disabled.\n\t\t\tif !canBeRemovedIfUnused || (!part.ForceTreeShaking && !c.options.TreeShaking && file.IsEntryPoint()) {\n\t\t\t\tc.markPartLiveForTreeShaking(sourceIndex, uint32(partIndex))\n\t\t\t}\n\t\t}\n\n\tcase *graph.CSSRepr:\n\t\t// Include all \"@import\" rules\n\t\tfor _, record := range repr.AST.ImportRecords {\n\t\t\tif record.SourceIndex.IsValid() {\n\t\t\t\tc.markFileLiveForTreeShaking(record.SourceIndex.GetIndex())\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (c *linkerContext) isExternalDynamicImport(record *ast.ImportRecord, sourceIndex uint32) bool {\n\treturn c.options.CodeSplitting &&\n\t\trecord.Kind == ast.ImportDynamic &&\n\t\tc.graph.Files[record.SourceIndex.GetIndex()].IsEntryPoint() &&\n\t\trecord.SourceIndex.GetIndex() != sourceIndex\n}\n\nfunc (c *linkerContext) markPartLiveForTreeShaking(sourceIndex uint32, partIndex uint32) {\n\tfile := &c.graph.Files[sourceIndex]\n\trepr := file.InputFile.Repr.(*graph.JSRepr)\n\tpart := &repr.AST.Parts[partIndex]\n\n\t// Don't mark this part more than once\n\tif part.IsLive {\n\t\treturn\n\t}\n\tpart.IsLive = true\n\n\t// Include the file containing this part\n\tc.markFileLiveForTreeShaking(sourceIndex)\n\n\t// Also include any dependencies\n\tfor _, dep := range part.Dependencies {\n\t\tc.markPartLiveForTreeShaking(dep.SourceIndex, dep.PartIndex)\n\t}\n}\n\n// JavaScript modules are traversed in depth-first postorder. This is the\n// order that JavaScript modules were evaluated in before the top-level await\n// feature was introduced.\n//\n//\t  A\n//\t / \\\n//\tB   C\n//\t \\ /\n//\t  D\n//\n// If A imports B and then C, B imports D, and C imports D, then the JavaScript\n// traversal order is D B C A.\n//\n// This function may deviate from ESM import order for dynamic imports (both\n// \"require()\" and \"import()\"). This is because the import order is impossible\n// to determine since the imports happen at run-time instead of compile-time.\n// In this case we just pick an arbitrary but consistent order.\nfunc (c *linkerContext) findImportedCSSFilesInJSOrder(entryPoint uint32) (order []uint32) {\n\tvisited := make(map[uint32]bool)\n\tvar visit func(uint32)\n\n\t// Include this file and all files it imports\n\tvisit = func(sourceIndex uint32) {\n\t\tif visited[sourceIndex] {\n\t\t\treturn\n\t\t}\n\t\tvisited[sourceIndex] = true\n\t\tfile := &c.graph.Files[sourceIndex]\n\t\trepr := file.InputFile.Repr.(*graph.JSRepr)\n\n\t\t// Iterate over each part in the file in order\n\t\tfor _, part := range repr.AST.Parts {\n\t\t\t// Traverse any files imported by this part. Note that CommonJS calls\n\t\t\t// to \"require()\" count as imports too, sort of as if the part has an\n\t\t\t// ESM \"import\" statement in it. This may seem weird because ESM imports\n\t\t\t// are a compile-time concept while CommonJS imports are a run-time\n\t\t\t// concept. But we don't want to manipulate <style> tags at run-time so\n\t\t\t// this is the only way to do it.\n\t\t\tfor _, importRecordIndex := range part.ImportRecordIndices {\n\t\t\t\tif record := &repr.AST.ImportRecords[importRecordIndex]; record.SourceIndex.IsValid() {\n\t\t\t\t\tvisit(record.SourceIndex.GetIndex())\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Iterate over the associated CSS imports in postorder\n\t\tif repr.CSSSourceIndex.IsValid() {\n\t\t\torder = append(order, repr.CSSSourceIndex.GetIndex())\n\t\t}\n\t}\n\n\t// Include all files reachable from the entry point\n\tvisit(entryPoint)\n\n\treturn\n}\n\ntype cssImportKind uint8\n\nconst (\n\tcssImportNone cssImportKind = iota\n\tcssImportSourceIndex\n\tcssImportExternalPath\n\tcssImportLayers\n)\n\ntype cssImportOrder struct {\n\tconditions             []css_ast.ImportConditions\n\tconditionImportRecords []ast.ImportRecord\n\n\tlayers       [][]string  // kind == cssImportAtLayer\n\texternalPath logger.Path // kind == cssImportExternal\n\tsourceIndex  uint32      // kind == cssImportSourceIndex\n\n\tkind cssImportKind\n}\n\n// CSS files are traversed in depth-first postorder just like JavaScript. But\n// unlike JavaScript import statements, CSS \"@import\" rules are evaluated every\n// time instead of just the first time.\n//\n//\t  A\n//\t / \\\n//\tB   C\n//\t \\ /\n//\t  D\n//\n// If A imports B and then C, B imports D, and C imports D, then the CSS\n// traversal order is D B D C A.\n//\n// However, evaluating a CSS file multiple times is sort of equivalent to\n// evaluating it once at the last location. So we basically drop all but the\n// last evaluation in the order.\n//\n// The only exception to this is \"@layer\". Evaluating a CSS file multiple\n// times is sort of equivalent to evaluating it once at the first location\n// as far as \"@layer\" is concerned. So we may in some cases keep both the\n// first and last locations and only write out the \"@layer\" information\n// for the first location.\nfunc (c *linkerContext) findImportedFilesInCSSOrder(entryPoints []uint32) (order []cssImportOrder) {\n\tvar visit func(uint32, []uint32, []css_ast.ImportConditions, []ast.ImportRecord)\n\thasExternalImport := false\n\n\t// Include this file and all files it imports\n\tvisit = func(\n\t\tsourceIndex uint32,\n\t\tvisited []uint32,\n\t\twrappingConditions []css_ast.ImportConditions,\n\t\twrappingImportRecords []ast.ImportRecord,\n\t) {\n\t\t// The CSS specification strangely does not describe what to do when there\n\t\t// is a cycle. So we are left with reverse-engineering the behavior from a\n\t\t// real browser. Here's what the WebKit code base has to say about this:\n\t\t//\n\t\t//   \"Check for a cycle in our import chain. If we encounter a stylesheet\n\t\t//   in our parent chain with the same URL, then just bail.\"\n\t\t//\n\t\t// So that's what we do here. See \"StyleRuleImport::requestStyleSheet()\" in\n\t\t// WebKit for more information.\n\t\tfor _, visitedSourceIndex := range visited {\n\t\t\tif visitedSourceIndex == sourceIndex {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tvisited = append(visited, sourceIndex)\n\n\t\trepr := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.CSSRepr)\n\t\ttopLevelRules := repr.AST.Rules\n\n\t\t// Any pre-import layers come first\n\t\tif len(repr.AST.LayersPreImport) > 0 {\n\t\t\torder = append(order, cssImportOrder{\n\t\t\t\tkind:                   cssImportLayers,\n\t\t\t\tlayers:                 repr.AST.LayersPreImport,\n\t\t\t\tconditions:             wrappingConditions,\n\t\t\t\tconditionImportRecords: wrappingImportRecords,\n\t\t\t})\n\t\t}\n\n\t\t// Iterate over the top-level \"@import\" rules\n\t\tfor _, rule := range topLevelRules {\n\t\t\tif atImport, ok := rule.Data.(*css_ast.RAtImport); ok {\n\t\t\t\trecord := &repr.AST.ImportRecords[atImport.ImportRecordIndex]\n\n\t\t\t\t// Follow internal dependencies\n\t\t\t\tif record.SourceIndex.IsValid() {\n\t\t\t\t\tnestedConditions := wrappingConditions\n\t\t\t\t\tnestedImportRecords := wrappingImportRecords\n\n\t\t\t\t\t// If this import has conditions, fork our state so that the entire\n\t\t\t\t\t// imported stylesheet subtree is wrapped in all of the conditions\n\t\t\t\t\tif atImport.ImportConditions != nil {\n\t\t\t\t\t\t// Fork our state\n\t\t\t\t\t\tnestedConditions = append([]css_ast.ImportConditions{}, nestedConditions...)\n\t\t\t\t\t\tnestedImportRecords = append([]ast.ImportRecord{}, nestedImportRecords...)\n\n\t\t\t\t\t\t// Clone these import conditions and append them to the state\n\t\t\t\t\t\tvar conditions css_ast.ImportConditions\n\t\t\t\t\t\tconditions, nestedImportRecords = atImport.ImportConditions.CloneWithImportRecords(repr.AST.ImportRecords, nestedImportRecords)\n\t\t\t\t\t\tnestedConditions = append(nestedConditions, conditions)\n\t\t\t\t\t}\n\n\t\t\t\t\tvisit(record.SourceIndex.GetIndex(), visited, nestedConditions, nestedImportRecords)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Record external dependencies\n\t\t\t\tif (record.Flags & ast.WasLoadedWithEmptyLoader) == 0 {\n\t\t\t\t\tallConditions := wrappingConditions\n\t\t\t\t\tallImportRecords := wrappingImportRecords\n\n\t\t\t\t\t// If this import has conditions, append it to the list of overall\n\t\t\t\t\t// conditions for this external import. Note that an external import\n\t\t\t\t\t// may actually have multiple sets of conditions that can't be\n\t\t\t\t\t// merged. When this happens we need to generate a nested imported\n\t\t\t\t\t// CSS file using a data URL.\n\t\t\t\t\tif atImport.ImportConditions != nil {\n\t\t\t\t\t\tvar conditions css_ast.ImportConditions\n\t\t\t\t\t\tallConditions = append([]css_ast.ImportConditions{}, allConditions...)\n\t\t\t\t\t\tallImportRecords = append([]ast.ImportRecord{}, allImportRecords...)\n\t\t\t\t\t\tconditions, allImportRecords = atImport.ImportConditions.CloneWithImportRecords(repr.AST.ImportRecords, allImportRecords)\n\t\t\t\t\t\tallConditions = append(allConditions, conditions)\n\t\t\t\t\t}\n\n\t\t\t\t\torder = append(order, cssImportOrder{\n\t\t\t\t\t\tkind:                   cssImportExternalPath,\n\t\t\t\t\t\texternalPath:           record.Path,\n\t\t\t\t\t\tconditions:             allConditions,\n\t\t\t\t\t\tconditionImportRecords: allImportRecords,\n\t\t\t\t\t})\n\t\t\t\t\thasExternalImport = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Iterate over the \"composes\" directives. Note that the order doesn't\n\t\t// matter for these because the output order is explicitly undefined\n\t\t// in the specification.\n\t\tfor _, record := range repr.AST.ImportRecords {\n\t\t\tif record.Kind == ast.ImportComposesFrom && record.SourceIndex.IsValid() {\n\t\t\t\tvisit(record.SourceIndex.GetIndex(), visited, wrappingConditions, wrappingImportRecords)\n\t\t\t}\n\t\t}\n\n\t\t// Accumulate imports in depth-first postorder\n\t\torder = append(order, cssImportOrder{\n\t\t\tkind:                   cssImportSourceIndex,\n\t\t\tsourceIndex:            sourceIndex,\n\t\t\tconditions:             wrappingConditions,\n\t\t\tconditionImportRecords: wrappingImportRecords,\n\t\t})\n\t}\n\n\t// Include all files reachable from any entry point\n\tvar visited [16]uint32 // Preallocate some space for the visited set\n\tfor _, sourceIndex := range entryPoints {\n\t\tvisit(sourceIndex, visited[:], nil, nil)\n\t}\n\n\t// Create a temporary array that we can use for filtering\n\twipOrder := make([]cssImportOrder, 0, len(order))\n\n\t// CSS syntax unfortunately only allows \"@import\" rules at the top of the\n\t// file. This means we must hoist all external \"@import\" rules to the top of\n\t// the file when bundling, even though doing so will change the order of CSS\n\t// evaluation.\n\tif hasExternalImport {\n\t\t// Pass 1: Pull out leading \"@layer\" and external \"@import\" rules\n\t\tisAtLayerPrefix := true\n\t\tfor _, entry := range order {\n\t\t\tif (entry.kind == cssImportLayers && isAtLayerPrefix) || entry.kind == cssImportExternalPath {\n\t\t\t\twipOrder = append(wipOrder, entry)\n\t\t\t}\n\t\t\tif entry.kind != cssImportLayers {\n\t\t\t\tisAtLayerPrefix = false\n\t\t\t}\n\t\t}\n\n\t\t// Pass 2: Append everything that we didn't pull out in pass 1\n\t\tisAtLayerPrefix = true\n\t\tfor _, entry := range order {\n\t\t\tif (entry.kind != cssImportLayers || !isAtLayerPrefix) && entry.kind != cssImportExternalPath {\n\t\t\t\twipOrder = append(wipOrder, entry)\n\t\t\t}\n\t\t\tif entry.kind != cssImportLayers {\n\t\t\t\tisAtLayerPrefix = false\n\t\t\t}\n\t\t}\n\n\t\torder, wipOrder = wipOrder, order[:0]\n\t}\n\n\t// Next, optimize import order. If there are duplicate copies of an imported\n\t// file, replace all but the last copy with just the layers that are in that\n\t// file. This works because in CSS, the last instance of a declaration\n\t// overrides all previous instances of that declaration.\n\t{\n\t\tsourceIndexDuplicates := make(map[uint32][]int)\n\t\texternalPathDuplicates := make(map[logger.Path][]int)\n\n\tnextBackward:\n\t\tfor i := len(order) - 1; i >= 0; i-- {\n\t\t\tentry := order[i]\n\t\t\tswitch entry.kind {\n\t\t\tcase cssImportSourceIndex:\n\t\t\t\tduplicates := sourceIndexDuplicates[entry.sourceIndex]\n\t\t\t\tfor _, j := range duplicates {\n\t\t\t\t\tif isConditionalImportRedundant(entry.conditions, order[j].conditions) {\n\t\t\t\t\t\torder[i].kind = cssImportLayers\n\t\t\t\t\t\torder[i].layers = c.graph.Files[entry.sourceIndex].InputFile.Repr.(*graph.CSSRepr).AST.LayersPostImport\n\t\t\t\t\t\tcontinue nextBackward\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsourceIndexDuplicates[entry.sourceIndex] = append(duplicates, i)\n\n\t\t\tcase cssImportExternalPath:\n\t\t\t\tduplicates := externalPathDuplicates[entry.externalPath]\n\t\t\t\tfor _, j := range duplicates {\n\t\t\t\t\tif isConditionalImportRedundant(entry.conditions, order[j].conditions) {\n\t\t\t\t\t\t// Don't remove duplicates entirely. The import conditions may\n\t\t\t\t\t\t// still introduce layers to the layer order. Represent this as a\n\t\t\t\t\t\t// file with an empty layer list.\n\t\t\t\t\t\torder[i].kind = cssImportLayers\n\t\t\t\t\t\tcontinue nextBackward\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\texternalPathDuplicates[entry.externalPath] = append(duplicates, i)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Then optimize \"@layer\" rules by removing redundant ones. This loop goes\n\t// forward instead of backward because \"@layer\" takes effect at the first\n\t// copy instead of the last copy like other things in CSS.\n\t{\n\t\ttype duplicateEntry struct {\n\t\t\tlayers  [][]string\n\t\t\tindices []int\n\t\t}\n\t\tvar layerDuplicates []duplicateEntry\n\n\tnextForward:\n\t\tfor i := range order {\n\t\t\tentry := order[i]\n\n\t\t\t// Simplify the conditions since we know they only wrap \"@layer\"\n\t\t\tif entry.kind == cssImportLayers {\n\t\t\t\t// Truncate the conditions at the first anonymous layer\n\t\t\t\tfor i, conditions := range entry.conditions {\n\t\t\t\t\t// The layer is anonymous if it's a \"layer\" token without any\n\t\t\t\t\t// children instead of a \"layer(...)\" token with children:\n\t\t\t\t\t//\n\t\t\t\t\t//   /* entry.css */\n\t\t\t\t\t//   @import \"foo.css\" layer;\n\t\t\t\t\t//\n\t\t\t\t\t//   /* foo.css */\n\t\t\t\t\t//   @layer foo;\n\t\t\t\t\t//\n\t\t\t\t\t// We don't need to generate this (as far as I can tell):\n\t\t\t\t\t//\n\t\t\t\t\t//   @layer {\n\t\t\t\t\t//     @layer foo;\n\t\t\t\t\t//   }\n\t\t\t\t\t//\n\t\t\t\t\tif conditions.Layers != nil && len(conditions.Layers) == 1 && conditions.Layers[0].Children == nil {\n\t\t\t\t\t\tentry.conditions = entry.conditions[:i]\n\t\t\t\t\t\tentry.layers = nil\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If there are no layer names for this file, trim all conditions\n\t\t\t\t// without layers because we know they have no effect.\n\t\t\t\t//\n\t\t\t\t//   /* entry.css */\n\t\t\t\t//   @import \"foo.css\" layer(foo) supports(display: flex);\n\t\t\t\t//\n\t\t\t\t//   /* foo.css */\n\t\t\t\t//   @import \"empty.css\" supports(display: grid);\n\t\t\t\t//\n\t\t\t\t// That would result in this:\n\t\t\t\t//\n\t\t\t\t//   @supports (display: flex) {\n\t\t\t\t//     @layer foo {\n\t\t\t\t//       @supports (display: grid) {}\n\t\t\t\t//     }\n\t\t\t\t//   }\n\t\t\t\t//\n\t\t\t\t// Here we can trim \"supports(display: grid)\" to generate this:\n\t\t\t\t//\n\t\t\t\t//   @supports (display: flex) {\n\t\t\t\t//     @layer foo;\n\t\t\t\t//   }\n\t\t\t\t//\n\t\t\t\tif len(entry.layers) == 0 {\n\t\t\t\t\tfor i := len(entry.conditions) - 1; i >= 0; i-- {\n\t\t\t\t\t\tif len(entry.conditions[i].Layers) > 0 {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tentry.conditions = entry.conditions[:i]\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Remove unnecessary entries entirely\n\t\t\t\tif len(entry.conditions) == 0 && len(entry.layers) == 0 {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Omit redundant \"@layer\" rules with the same set of layer names. Note\n\t\t\t// that this tests all import order entries (not just layer ones) because\n\t\t\t// sometimes non-layer ones can make following layer ones redundant.\n\t\t\tlayersKey := entry.layers\n\t\t\tif entry.kind == cssImportSourceIndex {\n\t\t\t\tlayersKey = c.graph.Files[entry.sourceIndex].InputFile.Repr.(*graph.CSSRepr).AST.LayersPostImport\n\t\t\t}\n\t\t\tindex := 0\n\t\t\tfor index < len(layerDuplicates) {\n\t\t\t\tif helpers.StringArrayArraysEqual(layersKey, layerDuplicates[index].layers) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tindex++\n\t\t\t}\n\t\t\tif index == len(layerDuplicates) {\n\t\t\t\t// This is the first time we've seen this combination of layer names.\n\t\t\t\t// Allocate a new set of duplicate indices to track this combination.\n\t\t\t\tlayerDuplicates = append(layerDuplicates, duplicateEntry{layers: layersKey})\n\t\t\t}\n\t\t\tduplicates := layerDuplicates[index].indices\n\t\t\tfor j := len(duplicates) - 1; j >= 0; j-- {\n\t\t\t\tif index := duplicates[j]; isConditionalImportRedundant(entry.conditions, wipOrder[index].conditions) {\n\t\t\t\t\tif entry.kind != cssImportLayers {\n\t\t\t\t\t\t// If an empty layer is followed immediately by a full layer and\n\t\t\t\t\t\t// everything else is identical, then we don't need to emit the\n\t\t\t\t\t\t// empty layer. For example:\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//   @media screen {\n\t\t\t\t\t\t//     @supports (display: grid) {\n\t\t\t\t\t\t//       @layer foo;\n\t\t\t\t\t\t//     }\n\t\t\t\t\t\t//   }\n\t\t\t\t\t\t//   @media screen {\n\t\t\t\t\t\t//     @supports (display: grid) {\n\t\t\t\t\t\t//       @layer foo {\n\t\t\t\t\t\t//         div {\n\t\t\t\t\t\t//           color: red;\n\t\t\t\t\t\t//         }\n\t\t\t\t\t\t//       }\n\t\t\t\t\t\t//     }\n\t\t\t\t\t\t//   }\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// This can be improved by dropping the empty layer. But we can\n\t\t\t\t\t\t// only do this if there's nothing in between these two rules.\n\t\t\t\t\t\tif j == len(duplicates)-1 && index == len(wipOrder)-1 {\n\t\t\t\t\t\t\tif other := wipOrder[index]; other.kind == cssImportLayers && importConditionsAreEqual(entry.conditions, other.conditions) {\n\t\t\t\t\t\t\t\t// Remove the previous entry and then overwrite it below\n\t\t\t\t\t\t\t\tduplicates = duplicates[:j]\n\t\t\t\t\t\t\t\twipOrder = wipOrder[:index]\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Non-layer entries still need to be present because they have\n\t\t\t\t\t\t// other side effects beside inserting things in the layer order\n\t\t\t\t\t\twipOrder = append(wipOrder, entry)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Don't add this to the duplicate list below because it's redundant\n\t\t\t\t\tcontinue nextForward\n\t\t\t\t}\n\t\t\t}\n\t\t\tlayerDuplicates[index].indices = append(duplicates, len(wipOrder))\n\t\t\twipOrder = append(wipOrder, entry)\n\t\t}\n\n\t\torder, wipOrder = wipOrder, order[:0]\n\t}\n\n\t// Finally, merge adjacent \"@layer\" rules with identical conditions together.\n\t{\n\t\tdidClone := -1\n\t\tfor _, entry := range order {\n\t\t\tif entry.kind == cssImportLayers && len(wipOrder) > 0 {\n\t\t\t\tprevIndex := len(wipOrder) - 1\n\t\t\t\tprev := wipOrder[prevIndex]\n\t\t\t\tif prev.kind == cssImportLayers && importConditionsAreEqual(prev.conditions, entry.conditions) {\n\t\t\t\t\tif didClone != prevIndex {\n\t\t\t\t\t\tdidClone = prevIndex\n\t\t\t\t\t\tprev.layers = append([][]string{}, prev.layers...)\n\t\t\t\t\t}\n\t\t\t\t\twipOrder[prevIndex].layers = append(prev.layers, entry.layers...)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\twipOrder = append(wipOrder, entry)\n\t\t}\n\t\torder = wipOrder\n\t}\n\n\treturn\n}\n\nfunc importConditionsAreEqual(a []css_ast.ImportConditions, b []css_ast.ImportConditions) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor i := 0; i < len(a); i++ {\n\t\tai := a[i]\n\t\tbi := b[i]\n\t\tif !css_ast.TokensEqualIgnoringWhitespace(ai.Layers, bi.Layers) ||\n\t\t\t!css_ast.TokensEqualIgnoringWhitespace(ai.Supports, bi.Supports) ||\n\t\t\t!css_ast.MediaQueriesEqualIgnoringWhitespace(ai.Queries, bi.Queries) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Given two \"@import\" rules for the same source index (an earlier one and a\n// later one), the earlier one is masked by the later one if the later one's\n// condition list is a prefix of the earlier one's condition list.\n//\n// For example:\n//\n//\t// entry.css\n//\t@import \"foo.css\" supports(display: flex);\n//\t@import \"bar.css\" supports(display: flex);\n//\n//\t// foo.css\n//\t@import \"lib.css\" screen;\n//\n//\t// bar.css\n//\t@import \"lib.css\";\n//\n// When we bundle this code we'll get an import order as follows:\n//\n//  1. lib.css [supports(display: flex), screen]\n//  2. foo.css [supports(display: flex)]\n//  3. lib.css [supports(display: flex)]\n//  4. bar.css [supports(display: flex)]\n//  5. entry.css []\n//\n// For \"lib.css\", the entry with the conditions [supports(display: flex)] should\n// make the entry with the conditions [supports(display: flex), screen] redundant.\n//\n// Note that all of this deliberately ignores the existence of \"@layer\" because\n// that is handled separately. All of this is only for handling unlayered styles.\nfunc isConditionalImportRedundant(earlier []css_ast.ImportConditions, later []css_ast.ImportConditions) bool {\n\tif len(later) > len(earlier) {\n\t\treturn false\n\t}\n\n\tfor i := 0; i < len(later); i++ {\n\t\ta := earlier[i]\n\t\tb := later[i]\n\n\t\t// Only compare \"@supports\" and \"@media\" if \"@layers\" is equal\n\t\tif css_ast.TokensEqualIgnoringWhitespace(a.Layers, b.Layers) {\n\t\t\tsameSupports := css_ast.TokensEqualIgnoringWhitespace(a.Supports, b.Supports)\n\t\t\tsameMedia := css_ast.MediaQueriesEqualIgnoringWhitespace(a.Queries, b.Queries)\n\n\t\t\t// If the import conditions are exactly equal, then only keep\n\t\t\t// the later one. The earlier one is redundant. Example:\n\t\t\t//\n\t\t\t//   @import \"foo.css\" layer(abc) supports(display: flex) screen;\n\t\t\t//   @import \"foo.css\" layer(abc) supports(display: flex) screen;\n\t\t\t//\n\t\t\t// The later one makes the earlier one redundant.\n\t\t\tif sameSupports && sameMedia {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// If the media conditions are exactly equal and the later one\n\t\t\t// doesn't have any supports conditions, then the later one will\n\t\t\t// apply in all cases where the earlier one applies. Example:\n\t\t\t//\n\t\t\t//   @import \"foo.css\" layer(abc) supports(display: flex) screen;\n\t\t\t//   @import \"foo.css\" layer(abc) screen;\n\t\t\t//\n\t\t\t// The later one makes the earlier one redundant.\n\t\t\tif sameMedia && len(b.Supports) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// If the supports conditions are exactly equal and the later one\n\t\t\t// doesn't have any media conditions, then the later one will\n\t\t\t// apply in all cases where the earlier one applies. Example:\n\t\t\t//\n\t\t\t//   @import \"foo.css\" layer(abc) supports(display: flex) screen;\n\t\t\t//   @import \"foo.css\" layer(abc) supports(display: flex);\n\t\t\t//\n\t\t\t// The later one makes the earlier one redundant.\n\t\t\tif sameSupports && len(b.Queries) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\treturn false\n\t}\n\n\treturn true\n}\n\nfunc (c *linkerContext) computeChunks() {\n\tc.timer.Begin(\"Compute chunks\")\n\tdefer c.timer.End(\"Compute chunks\")\n\n\tjsChunks := make(map[string]chunkInfo)\n\tcssChunks := make(map[string]chunkInfo)\n\n\t// Create chunks for entry points\n\tfor i, entryPoint := range c.graph.EntryPoints() {\n\t\tfile := &c.graph.Files[entryPoint.SourceIndex]\n\n\t\t// Create a chunk for the entry point here to ensure that the chunk is\n\t\t// always generated even if the resulting file is empty\n\t\tentryBits := helpers.NewBitSet(uint(len(c.graph.EntryPoints())))\n\t\tentryBits.SetBit(uint(i))\n\t\tkey := entryBits.String()\n\t\tchunk := chunkInfo{\n\t\t\tentryBits:             entryBits,\n\t\t\tisEntryPoint:          true,\n\t\t\tsourceIndex:           entryPoint.SourceIndex,\n\t\t\tentryPointBit:         uint(i),\n\t\t\tfilesWithPartsInChunk: make(map[uint32]bool),\n\t\t}\n\n\t\tswitch file.InputFile.Repr.(type) {\n\t\tcase *graph.JSRepr:\n\t\t\tchunkRepr := &chunkReprJS{}\n\t\t\tchunk.chunkRepr = chunkRepr\n\t\t\tjsChunks[key] = chunk\n\n\t\t\t// If this JS entry point has an associated CSS entry point, generate it\n\t\t\t// now. This is essentially done by generating a virtual CSS file that\n\t\t\t// only contains \"@import\" statements in the order that the files were\n\t\t\t// discovered in JS source order, where JS source order is arbitrary but\n\t\t\t// consistent for dynamic imports. Then we run the CSS import order\n\t\t\t// algorithm to determine the final CSS file order for the chunk.\n\n\t\t\tif cssSourceIndices := c.findImportedCSSFilesInJSOrder(entryPoint.SourceIndex); len(cssSourceIndices) > 0 {\n\t\t\t\torder := c.findImportedFilesInCSSOrder(cssSourceIndices)\n\t\t\t\tcssFilesWithPartsInChunk := make(map[uint32]bool)\n\t\t\t\tfor _, entry := range order {\n\t\t\t\t\tif entry.kind == cssImportSourceIndex {\n\t\t\t\t\t\tcssFilesWithPartsInChunk[uint32(entry.sourceIndex)] = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcssChunks[key] = chunkInfo{\n\t\t\t\t\tentryBits:             entryBits,\n\t\t\t\t\tisEntryPoint:          true,\n\t\t\t\t\tsourceIndex:           entryPoint.SourceIndex,\n\t\t\t\t\tentryPointBit:         uint(i),\n\t\t\t\t\tfilesWithPartsInChunk: cssFilesWithPartsInChunk,\n\t\t\t\t\tchunkRepr: &chunkReprCSS{\n\t\t\t\t\t\timportsInChunkInOrder: order,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\tchunkRepr.hasCSSChunk = true\n\t\t\t}\n\n\t\tcase *graph.CSSRepr:\n\t\t\torder := c.findImportedFilesInCSSOrder([]uint32{entryPoint.SourceIndex})\n\t\t\tfor _, entry := range order {\n\t\t\t\tif entry.kind == cssImportSourceIndex {\n\t\t\t\t\tchunk.filesWithPartsInChunk[uint32(entry.sourceIndex)] = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tchunk.chunkRepr = &chunkReprCSS{\n\t\t\t\timportsInChunkInOrder: order,\n\t\t\t}\n\t\t\tcssChunks[key] = chunk\n\t\t}\n\t}\n\n\t// Figure out which JS files are in which chunk\n\tfor _, sourceIndex := range c.graph.ReachableFiles {\n\t\tif file := &c.graph.Files[sourceIndex]; file.IsLive {\n\t\t\tif _, ok := file.InputFile.Repr.(*graph.JSRepr); ok {\n\t\t\t\tkey := file.EntryBits.String()\n\t\t\t\tchunk, ok := jsChunks[key]\n\t\t\t\tif !ok {\n\t\t\t\t\tchunk.entryBits = file.EntryBits\n\t\t\t\t\tchunk.filesWithPartsInChunk = make(map[uint32]bool)\n\t\t\t\t\tchunk.chunkRepr = &chunkReprJS{}\n\t\t\t\t\tjsChunks[key] = chunk\n\t\t\t\t}\n\t\t\t\tchunk.filesWithPartsInChunk[uint32(sourceIndex)] = true\n\t\t\t}\n\t\t}\n\t}\n\n\t// Sort the chunks for determinism. This matters because we use chunk indices\n\t// as sorting keys in a few places.\n\tsortedChunks := make([]chunkInfo, 0, len(jsChunks)+len(cssChunks))\n\tsortedKeys := make([]string, 0, len(jsChunks)+len(cssChunks))\n\tfor key := range jsChunks {\n\t\tsortedKeys = append(sortedKeys, key)\n\t}\n\tsort.Strings(sortedKeys)\n\tjsChunkIndicesForCSS := make(map[string]uint32)\n\tfor _, key := range sortedKeys {\n\t\tchunk := jsChunks[key]\n\t\tif chunk.chunkRepr.(*chunkReprJS).hasCSSChunk {\n\t\t\tjsChunkIndicesForCSS[key] = uint32(len(sortedChunks))\n\t\t}\n\t\tsortedChunks = append(sortedChunks, chunk)\n\t}\n\tsortedKeys = sortedKeys[:0]\n\tfor key := range cssChunks {\n\t\tsortedKeys = append(sortedKeys, key)\n\t}\n\tsort.Strings(sortedKeys)\n\tfor _, key := range sortedKeys {\n\t\tchunk := cssChunks[key]\n\t\tif jsChunkIndex, ok := jsChunkIndicesForCSS[key]; ok {\n\t\t\tsortedChunks[jsChunkIndex].chunkRepr.(*chunkReprJS).cssChunkIndex = uint32(len(sortedChunks))\n\t\t}\n\t\tsortedChunks = append(sortedChunks, chunk)\n\t}\n\n\t// Map from the entry point file to its chunk. We will need this later if\n\t// a file contains a dynamic import to this entry point, since we'll need\n\t// to look up the path for this chunk to use with the import.\n\tfor chunkIndex, chunk := range sortedChunks {\n\t\tif chunk.isEntryPoint {\n\t\t\tfile := &c.graph.Files[chunk.sourceIndex]\n\n\t\t\t// JS entry points that import CSS files generate two chunks, a JS chunk\n\t\t\t// and a CSS chunk. Don't link the CSS chunk to the JS file since the CSS\n\t\t\t// chunk is secondary (the JS chunk is primary).\n\t\t\tif _, ok := chunk.chunkRepr.(*chunkReprCSS); ok {\n\t\t\t\tif _, ok := file.InputFile.Repr.(*graph.JSRepr); ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfile.EntryPointChunkIndex = uint32(chunkIndex)\n\t\t}\n\t}\n\n\t// Determine the order of JS files (and parts) within the chunk ahead of time\n\tfor _, chunk := range sortedChunks {\n\t\tif chunkRepr, ok := chunk.chunkRepr.(*chunkReprJS); ok {\n\t\t\tchunkRepr.filesInChunkInOrder, chunkRepr.partsInChunkInOrder = c.findImportedPartsInJSOrder(&chunk)\n\t\t}\n\t}\n\n\t// Assign general information to each chunk\n\tfor chunkIndex := range sortedChunks {\n\t\tchunk := &sortedChunks[chunkIndex]\n\n\t\t// Assign a unique key to each chunk. This key encodes the index directly so\n\t\t// we can easily recover it later without needing to look it up in a map. The\n\t\t// last 8 numbers of the key are the chunk index.\n\t\tchunk.uniqueKey = fmt.Sprintf(\"%sC%08d\", c.uniqueKeyPrefix, chunkIndex)\n\n\t\t// Determine the standard file extension\n\t\tvar stdExt string\n\t\tswitch chunk.chunkRepr.(type) {\n\t\tcase *chunkReprJS:\n\t\t\tstdExt = c.options.OutputExtensionJS\n\t\tcase *chunkReprCSS:\n\t\t\tstdExt = c.options.OutputExtensionCSS\n\t\t}\n\n\t\t// Compute the template substitutions\n\t\tvar dir, base, ext string\n\t\tvar template []config.PathTemplate\n\t\tif chunk.isEntryPoint {\n\t\t\t// Only use the entry path template for user-specified entry points\n\t\t\tfile := &c.graph.Files[chunk.sourceIndex]\n\t\t\tif file.IsUserSpecifiedEntryPoint() {\n\t\t\t\ttemplate = c.options.EntryPathTemplate\n\t\t\t} else {\n\t\t\t\ttemplate = c.options.ChunkPathTemplate\n\t\t\t}\n\n\t\t\tif c.options.AbsOutputFile != \"\" {\n\t\t\t\t// If the output path was configured explicitly, use it verbatim\n\t\t\t\tdir = \"/\"\n\t\t\t\tbase = c.fs.Base(c.options.AbsOutputFile)\n\t\t\t\toriginalExt := c.fs.Ext(base)\n\t\t\t\tbase = base[:len(base)-len(originalExt)]\n\n\t\t\t\t// Use the extension from the explicit output file path. However, don't do\n\t\t\t\t// that if this is a CSS chunk but the entry point file is not CSS. In that\n\t\t\t\t// case use the standard extension. This happens when importing CSS into JS.\n\t\t\t\tif _, ok := file.InputFile.Repr.(*graph.CSSRepr); ok || stdExt != c.options.OutputExtensionCSS {\n\t\t\t\t\text = originalExt\n\t\t\t\t} else {\n\t\t\t\t\text = stdExt\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Otherwise, derive the output path from the input path\n\t\t\t\tdir, base = bundler.PathRelativeToOutbase(\n\t\t\t\t\t&c.graph.Files[chunk.sourceIndex].InputFile,\n\t\t\t\t\tc.options,\n\t\t\t\t\tc.fs,\n\t\t\t\t\t!file.IsUserSpecifiedEntryPoint(),\n\t\t\t\t\tc.graph.EntryPoints()[chunk.entryPointBit].OutputPath,\n\t\t\t\t)\n\t\t\t\text = stdExt\n\t\t\t}\n\t\t} else {\n\t\t\tdir = \"/\"\n\t\t\tbase = \"chunk\"\n\t\t\text = stdExt\n\t\t\ttemplate = c.options.ChunkPathTemplate\n\t\t}\n\n\t\t// Determine the output path template\n\t\ttemplateExt := strings.TrimPrefix(ext, \".\")\n\t\ttemplate = append(append(make([]config.PathTemplate, 0, len(template)+1), template...), config.PathTemplate{Data: ext})\n\t\tchunk.finalTemplate = config.SubstituteTemplate(template, config.PathPlaceholders{\n\t\t\tDir:  &dir,\n\t\t\tName: &base,\n\t\t\tExt:  &templateExt,\n\t\t})\n\t}\n\n\tc.chunks = sortedChunks\n}\n\ntype chunkOrder struct {\n\tsourceIndex uint32\n\tdistance    uint32\n\ttieBreaker  uint32\n}\n\n// This type is just so we can use Go's native sort function\ntype chunkOrderArray []chunkOrder\n\nfunc (a chunkOrderArray) Len() int          { return len(a) }\nfunc (a chunkOrderArray) Swap(i int, j int) { a[i], a[j] = a[j], a[i] }\n\nfunc (a chunkOrderArray) Less(i int, j int) bool {\n\tai := a[i]\n\taj := a[j]\n\treturn ai.distance < aj.distance || (ai.distance == aj.distance && ai.tieBreaker < aj.tieBreaker)\n}\n\nfunc appendOrExtendPartRange(ranges []partRange, sourceIndex uint32, partIndex uint32) []partRange {\n\tif i := len(ranges) - 1; i >= 0 {\n\t\tif r := &ranges[i]; r.sourceIndex == sourceIndex && r.partIndexEnd == partIndex {\n\t\t\tr.partIndexEnd = partIndex + 1\n\t\t\treturn ranges\n\t\t}\n\t}\n\n\treturn append(ranges, partRange{\n\t\tsourceIndex:    sourceIndex,\n\t\tpartIndexBegin: partIndex,\n\t\tpartIndexEnd:   partIndex + 1,\n\t})\n}\n\nfunc (c *linkerContext) shouldIncludePart(repr *graph.JSRepr, part js_ast.Part) bool {\n\t// As an optimization, ignore parts containing a single import statement to\n\t// an internal non-wrapped file. These will be ignored anyway and it's a\n\t// performance hit to spin up a goroutine only to discover this later.\n\tif len(part.Stmts) == 1 {\n\t\tif s, ok := part.Stmts[0].Data.(*js_ast.SImport); ok {\n\t\t\trecord := &repr.AST.ImportRecords[s.ImportRecordIndex]\n\t\t\tif record.SourceIndex.IsValid() && c.graph.Files[record.SourceIndex.GetIndex()].InputFile.Repr.(*graph.JSRepr).Meta.Wrap == graph.WrapNone {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (c *linkerContext) findImportedPartsInJSOrder(chunk *chunkInfo) (js []uint32, jsParts []partRange) {\n\tsorted := make(chunkOrderArray, 0, len(chunk.filesWithPartsInChunk))\n\n\t// Attach information to the files for use with sorting\n\tfor sourceIndex := range chunk.filesWithPartsInChunk {\n\t\tfile := &c.graph.Files[sourceIndex]\n\t\tsorted = append(sorted, chunkOrder{\n\t\t\tsourceIndex: sourceIndex,\n\t\t\tdistance:    file.DistanceFromEntryPoint,\n\t\t\ttieBreaker:  c.graph.StableSourceIndices[sourceIndex],\n\t\t})\n\t}\n\n\t// Sort so files closest to an entry point come first. If two files are\n\t// equidistant to an entry point, then break the tie by sorting on the\n\t// stable source index derived from the DFS over all entry points.\n\tsort.Sort(sorted)\n\n\tvisited := make(map[uint32]bool)\n\tjsPartsPrefix := []partRange{}\n\n\t// Traverse the graph using this stable order and linearize the files with\n\t// dependencies before dependents\n\tvar visit func(uint32)\n\tvisit = func(sourceIndex uint32) {\n\t\tif visited[sourceIndex] {\n\t\t\treturn\n\t\t}\n\n\t\tvisited[sourceIndex] = true\n\t\tfile := &c.graph.Files[sourceIndex]\n\n\t\tif repr, ok := file.InputFile.Repr.(*graph.JSRepr); ok {\n\t\t\tisFileInThisChunk := chunk.entryBits.Equals(file.EntryBits)\n\n\t\t\t// Wrapped files can't be split because they are all inside the wrapper\n\t\t\tcanFileBeSplit := repr.Meta.Wrap == graph.WrapNone\n\n\t\t\t// Make sure the generated call to \"__export(exports, ...)\" comes first\n\t\t\t// before anything else in this file\n\t\t\tif canFileBeSplit && isFileInThisChunk && repr.AST.Parts[js_ast.NSExportPartIndex].IsLive {\n\t\t\t\tjsParts = appendOrExtendPartRange(jsParts, sourceIndex, js_ast.NSExportPartIndex)\n\t\t\t}\n\n\t\t\tfor partIndex, part := range repr.AST.Parts {\n\t\t\t\tisPartInThisChunk := isFileInThisChunk && repr.AST.Parts[partIndex].IsLive\n\n\t\t\t\t// Also traverse any files imported by this part\n\t\t\t\tfor _, importRecordIndex := range part.ImportRecordIndices {\n\t\t\t\t\trecord := &repr.AST.ImportRecords[importRecordIndex]\n\t\t\t\t\tif record.SourceIndex.IsValid() && (record.Kind == ast.ImportStmt || isPartInThisChunk) {\n\t\t\t\t\t\tif c.isExternalDynamicImport(record, sourceIndex) {\n\t\t\t\t\t\t\t// Don't follow import() dependencies\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvisit(record.SourceIndex.GetIndex())\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Then include this part after the files it imports\n\t\t\t\tif isPartInThisChunk {\n\t\t\t\t\tisFileInThisChunk = true\n\t\t\t\t\tif canFileBeSplit && uint32(partIndex) != js_ast.NSExportPartIndex && c.shouldIncludePart(repr, part) {\n\t\t\t\t\t\tif sourceIndex == runtime.SourceIndex {\n\t\t\t\t\t\t\tjsPartsPrefix = appendOrExtendPartRange(jsPartsPrefix, sourceIndex, uint32(partIndex))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tjsParts = appendOrExtendPartRange(jsParts, sourceIndex, uint32(partIndex))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif isFileInThisChunk {\n\t\t\t\tjs = append(js, sourceIndex)\n\n\t\t\t\t// CommonJS files are all-or-nothing so all parts must be contiguous\n\t\t\t\tif !canFileBeSplit {\n\t\t\t\t\tjsPartsPrefix = append(jsPartsPrefix, partRange{\n\t\t\t\t\t\tsourceIndex:    sourceIndex,\n\t\t\t\t\t\tpartIndexBegin: 0,\n\t\t\t\t\t\tpartIndexEnd:   uint32(len(repr.AST.Parts)),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Always put the runtime code first before anything else\n\tvisit(runtime.SourceIndex)\n\tfor _, data := range sorted {\n\t\tvisit(data.sourceIndex)\n\t}\n\tjsParts = append(jsPartsPrefix, jsParts...)\n\treturn\n}\n\nfunc (c *linkerContext) shouldRemoveImportExportStmt(\n\tsourceIndex uint32,\n\tstmtList *stmtList,\n\tloc logger.Loc,\n\tnamespaceRef ast.Ref,\n\timportRecordIndex uint32,\n) bool {\n\trepr := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.JSRepr)\n\trecord := &repr.AST.ImportRecords[importRecordIndex]\n\n\t// Is this an external import?\n\tif !record.SourceIndex.IsValid() {\n\t\t// Keep the \"import\" statement if \"import\" statements are supported\n\t\tif c.options.OutputFormat.KeepESMImportExportSyntax() {\n\t\t\treturn false\n\t\t}\n\n\t\t// Otherwise, replace this statement with a call to \"require()\"\n\t\tstmtList.insideWrapperPrefix = append(stmtList.insideWrapperPrefix, js_ast.Stmt{\n\t\t\tLoc: loc,\n\t\t\tData: &js_ast.SLocal{Decls: []js_ast.Decl{{\n\t\t\t\tBinding: js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: namespaceRef}},\n\t\t\t\tValueOrNil: js_ast.Expr{Loc: record.Range.Loc, Data: &js_ast.ERequireString{\n\t\t\t\t\tImportRecordIndex: importRecordIndex,\n\t\t\t\t}},\n\t\t\t}}},\n\t\t})\n\t\treturn true\n\t}\n\n\t// We don't need a call to \"require()\" if this is a self-import inside a\n\t// CommonJS-style module, since we can just reference the exports directly.\n\tif repr.AST.ExportsKind == js_ast.ExportsCommonJS && ast.FollowSymbols(c.graph.Symbols, namespaceRef) == repr.AST.ExportsRef {\n\t\treturn true\n\t}\n\n\totherFile := &c.graph.Files[record.SourceIndex.GetIndex()]\n\totherRepr := otherFile.InputFile.Repr.(*graph.JSRepr)\n\tswitch otherRepr.Meta.Wrap {\n\tcase graph.WrapNone:\n\t\t// Remove the statement entirely if this module is not wrapped\n\n\tcase graph.WrapCJS:\n\t\t// Replace the statement with a call to \"require()\"\n\t\tstmtList.insideWrapperPrefix = append(stmtList.insideWrapperPrefix, js_ast.Stmt{\n\t\t\tLoc: loc,\n\t\t\tData: &js_ast.SLocal{Decls: []js_ast.Decl{{\n\t\t\t\tBinding: js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: namespaceRef}},\n\t\t\t\tValueOrNil: js_ast.Expr{Loc: record.Range.Loc, Data: &js_ast.ERequireString{\n\t\t\t\t\tImportRecordIndex: importRecordIndex,\n\t\t\t\t}},\n\t\t\t}}},\n\t\t})\n\n\tcase graph.WrapESM:\n\t\t// Ignore this file if it's not included in the bundle. This can happen for\n\t\t// wrapped ESM files but not for wrapped CommonJS files because we allow\n\t\t// tree shaking inside wrapped ESM files.\n\t\tif !otherFile.IsLive {\n\t\t\tbreak\n\t\t}\n\n\t\t// Replace the statement with a call to \"init()\"\n\t\tvalue := js_ast.Expr{Loc: loc, Data: &js_ast.ECall{Target: js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: otherRepr.AST.WrapperRef}}}}\n\t\tif otherRepr.Meta.IsAsyncOrHasAsyncDependency {\n\t\t\t// This currently evaluates sibling dependencies in serial instead of in\n\t\t\t// parallel, which is incorrect. This should be changed to store a promise\n\t\t\t// and await all stored promises after all imports but before any code.\n\t\t\tvalue.Data = &js_ast.EAwait{Value: value}\n\t\t}\n\t\tstmtList.insideWrapperPrefix = append(stmtList.insideWrapperPrefix, js_ast.Stmt{Loc: loc, Data: &js_ast.SExpr{Value: value}})\n\t}\n\n\treturn true\n}\n\nfunc (c *linkerContext) convertStmtsForChunk(sourceIndex uint32, stmtList *stmtList, partStmts []js_ast.Stmt) {\n\tfile := &c.graph.Files[sourceIndex]\n\tshouldStripExports := c.options.Mode != config.ModePassThrough || !file.IsEntryPoint()\n\trepr := file.InputFile.Repr.(*graph.JSRepr)\n\tshouldExtractESMStmtsForWrap := repr.Meta.Wrap != graph.WrapNone\n\n\t// If this file is a CommonJS entry point, double-write re-exports to the\n\t// external CommonJS \"module.exports\" object in addition to our internal ESM\n\t// export namespace object. The difference between these two objects is that\n\t// our internal one must not have the \"__esModule\" marker while the external\n\t// one must have the \"__esModule\" marker. This is done because an ES module\n\t// importing itself should not see the \"__esModule\" marker but a CommonJS module\n\t// importing us should see the \"__esModule\" marker.\n\tvar moduleExportsForReExportOrNil js_ast.Expr\n\tif c.options.OutputFormat == config.FormatCommonJS && file.IsEntryPoint() {\n\t\tmoduleExportsForReExportOrNil = js_ast.Expr{Data: &js_ast.EDot{\n\t\t\tTarget: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: c.unboundModuleRef}},\n\t\t\tName:   \"exports\",\n\t\t}}\n\t}\n\n\tfor _, stmt := range partStmts {\n\t\tswitch s := stmt.Data.(type) {\n\t\tcase *js_ast.SImport:\n\t\t\t// \"import * as ns from 'path'\"\n\t\t\t// \"import {foo} from 'path'\"\n\t\t\tif c.shouldRemoveImportExportStmt(sourceIndex, stmtList, stmt.Loc, s.NamespaceRef, s.ImportRecordIndex) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif c.options.UnsupportedJSFeatures.Has(compat.ArbitraryModuleNamespaceNames) && s.Items != nil {\n\t\t\t\tfor _, item := range *s.Items {\n\t\t\t\t\tc.maybeForbidArbitraryModuleNamespaceIdentifier(\"import\", sourceIndex, item.AliasLoc, item.Alias)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Make sure these don't end up in the wrapper closure\n\t\t\tif shouldExtractESMStmtsForWrap {\n\t\t\t\tstmtList.outsideWrapperPrefix = append(stmtList.outsideWrapperPrefix, stmt)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tcase *js_ast.SExportStar:\n\t\t\t// \"export * as ns from 'path'\"\n\t\t\tif s.Alias != nil {\n\t\t\t\tif c.shouldRemoveImportExportStmt(sourceIndex, stmtList, stmt.Loc, s.NamespaceRef, s.ImportRecordIndex) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif c.options.UnsupportedJSFeatures.Has(compat.ArbitraryModuleNamespaceNames) {\n\t\t\t\t\tc.maybeForbidArbitraryModuleNamespaceIdentifier(\"export\", sourceIndex, s.Alias.Loc, s.Alias.OriginalName)\n\t\t\t\t}\n\n\t\t\t\tif shouldStripExports {\n\t\t\t\t\t// Turn this statement into \"import * as ns from 'path'\"\n\t\t\t\t\tstmt.Data = &js_ast.SImport{\n\t\t\t\t\t\tNamespaceRef:      s.NamespaceRef,\n\t\t\t\t\t\tStarNameLoc:       &s.Alias.Loc,\n\t\t\t\t\t\tImportRecordIndex: s.ImportRecordIndex,\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Make sure these don't end up in the wrapper closure\n\t\t\t\tif shouldExtractESMStmtsForWrap {\n\t\t\t\t\tstmtList.outsideWrapperPrefix = append(stmtList.outsideWrapperPrefix, stmt)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// \"export * from 'path'\"\n\t\t\tif !shouldStripExports {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\trecord := &repr.AST.ImportRecords[s.ImportRecordIndex]\n\n\t\t\t// Is this export star evaluated at run time?\n\t\t\tif !record.SourceIndex.IsValid() && c.options.OutputFormat.KeepESMImportExportSyntax() {\n\t\t\t\tif record.Flags.Has(ast.CallsRunTimeReExportFn) {\n\t\t\t\t\t// Turn this statement into \"import * as ns from 'path'\"\n\t\t\t\t\tstmt.Data = &js_ast.SImport{\n\t\t\t\t\t\tNamespaceRef:      s.NamespaceRef,\n\t\t\t\t\t\tStarNameLoc:       &logger.Loc{Start: stmt.Loc.Start},\n\t\t\t\t\t\tImportRecordIndex: s.ImportRecordIndex,\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix this module with \"__reExport(exports, ns, module.exports)\"\n\t\t\t\t\texportStarRef := c.graph.Files[runtime.SourceIndex].InputFile.Repr.(*graph.JSRepr).AST.ModuleScope.Members[\"__reExport\"].Ref\n\t\t\t\t\targs := []js_ast.Expr{\n\t\t\t\t\t\t{Loc: stmt.Loc, Data: &js_ast.EIdentifier{Ref: repr.AST.ExportsRef}},\n\t\t\t\t\t\t{Loc: stmt.Loc, Data: &js_ast.EIdentifier{Ref: s.NamespaceRef}},\n\t\t\t\t\t}\n\t\t\t\t\tif moduleExportsForReExportOrNil.Data != nil {\n\t\t\t\t\t\targs = append(args, moduleExportsForReExportOrNil)\n\t\t\t\t\t}\n\t\t\t\t\tstmtList.insideWrapperPrefix = append(stmtList.insideWrapperPrefix, js_ast.Stmt{\n\t\t\t\t\t\tLoc: stmt.Loc,\n\t\t\t\t\t\tData: &js_ast.SExpr{Value: js_ast.Expr{Loc: stmt.Loc, Data: &js_ast.ECall{\n\t\t\t\t\t\t\tTarget: js_ast.Expr{Loc: stmt.Loc, Data: &js_ast.EIdentifier{Ref: exportStarRef}},\n\t\t\t\t\t\t\tArgs:   args,\n\t\t\t\t\t\t}}},\n\t\t\t\t\t})\n\n\t\t\t\t\t// Make sure these don't end up in the wrapper closure\n\t\t\t\t\tif shouldExtractESMStmtsForWrap {\n\t\t\t\t\t\tstmtList.outsideWrapperPrefix = append(stmtList.outsideWrapperPrefix, stmt)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif record.SourceIndex.IsValid() {\n\t\t\t\t\tif otherRepr := c.graph.Files[record.SourceIndex.GetIndex()].InputFile.Repr.(*graph.JSRepr); otherRepr.Meta.Wrap == graph.WrapESM {\n\t\t\t\t\t\tstmtList.insideWrapperPrefix = append(stmtList.insideWrapperPrefix, js_ast.Stmt{Loc: stmt.Loc,\n\t\t\t\t\t\t\tData: &js_ast.SExpr{Value: js_ast.Expr{Loc: stmt.Loc, Data: &js_ast.ECall{\n\t\t\t\t\t\t\t\tTarget: js_ast.Expr{Loc: stmt.Loc, Data: &js_ast.EIdentifier{Ref: otherRepr.AST.WrapperRef}}}}}})\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif record.Flags.Has(ast.CallsRunTimeReExportFn) {\n\t\t\t\t\tvar target js_ast.E\n\t\t\t\t\tif record.SourceIndex.IsValid() {\n\t\t\t\t\t\tif otherRepr := c.graph.Files[record.SourceIndex.GetIndex()].InputFile.Repr.(*graph.JSRepr); otherRepr.AST.ExportsKind == js_ast.ExportsESMWithDynamicFallback {\n\t\t\t\t\t\t\t// Prefix this module with \"__reExport(exports, otherExports, module.exports)\"\n\t\t\t\t\t\t\ttarget = &js_ast.EIdentifier{Ref: otherRepr.AST.ExportsRef}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif target == nil {\n\t\t\t\t\t\t// Prefix this module with \"__reExport(exports, require(path), module.exports)\"\n\t\t\t\t\t\ttarget = &js_ast.ERequireString{\n\t\t\t\t\t\t\tImportRecordIndex: s.ImportRecordIndex,\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\texportStarRef := c.graph.Files[runtime.SourceIndex].InputFile.Repr.(*graph.JSRepr).AST.ModuleScope.Members[\"__reExport\"].Ref\n\t\t\t\t\targs := []js_ast.Expr{\n\t\t\t\t\t\t{Loc: stmt.Loc, Data: &js_ast.EIdentifier{Ref: repr.AST.ExportsRef}},\n\t\t\t\t\t\t{Loc: record.Range.Loc, Data: target},\n\t\t\t\t\t}\n\t\t\t\t\tif moduleExportsForReExportOrNil.Data != nil {\n\t\t\t\t\t\targs = append(args, moduleExportsForReExportOrNil)\n\t\t\t\t\t}\n\t\t\t\t\tstmtList.insideWrapperPrefix = append(stmtList.insideWrapperPrefix, js_ast.Stmt{\n\t\t\t\t\t\tLoc: stmt.Loc,\n\t\t\t\t\t\tData: &js_ast.SExpr{Value: js_ast.Expr{Loc: stmt.Loc, Data: &js_ast.ECall{\n\t\t\t\t\t\t\tTarget: js_ast.Expr{Loc: stmt.Loc, Data: &js_ast.EIdentifier{Ref: exportStarRef}},\n\t\t\t\t\t\t\tArgs:   args,\n\t\t\t\t\t\t}}},\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\t// Remove the export star statement\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tcase *js_ast.SExportFrom:\n\t\t\t// \"export {foo} from 'path'\"\n\t\t\tif c.shouldRemoveImportExportStmt(sourceIndex, stmtList, stmt.Loc, s.NamespaceRef, s.ImportRecordIndex) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif c.options.UnsupportedJSFeatures.Has(compat.ArbitraryModuleNamespaceNames) {\n\t\t\t\tfor _, item := range s.Items {\n\t\t\t\t\tc.maybeForbidArbitraryModuleNamespaceIdentifier(\"import\", sourceIndex, item.Name.Loc, item.OriginalName)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif shouldStripExports {\n\t\t\t\t// Turn this statement into \"import {foo} from 'path'\"\n\t\t\t\tfor i, item := range s.Items {\n\t\t\t\t\ts.Items[i].Alias = item.OriginalName\n\t\t\t\t}\n\t\t\t\tstmt.Data = &js_ast.SImport{\n\t\t\t\t\tNamespaceRef:      s.NamespaceRef,\n\t\t\t\t\tItems:             &s.Items,\n\t\t\t\t\tImportRecordIndex: s.ImportRecordIndex,\n\t\t\t\t\tIsSingleLine:      s.IsSingleLine,\n\t\t\t\t}\n\t\t\t} else if c.options.UnsupportedJSFeatures.Has(compat.ArbitraryModuleNamespaceNames) {\n\t\t\t\tfor _, item := range s.Items {\n\t\t\t\t\tif item.AliasLoc != item.Name.Loc {\n\t\t\t\t\t\tc.maybeForbidArbitraryModuleNamespaceIdentifier(\"export\", sourceIndex, item.AliasLoc, item.Alias)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Make sure these don't end up in the wrapper closure\n\t\t\tif shouldExtractESMStmtsForWrap {\n\t\t\t\tstmtList.outsideWrapperPrefix = append(stmtList.outsideWrapperPrefix, stmt)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tcase *js_ast.SExportClause:\n\t\t\tif shouldStripExports {\n\t\t\t\t// Remove export statements entirely\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif c.options.UnsupportedJSFeatures.Has(compat.ArbitraryModuleNamespaceNames) {\n\t\t\t\tfor _, item := range s.Items {\n\t\t\t\t\tc.maybeForbidArbitraryModuleNamespaceIdentifier(\"export\", sourceIndex, item.AliasLoc, item.Alias)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Make sure these don't end up in the wrapper closure\n\t\t\tif shouldExtractESMStmtsForWrap {\n\t\t\t\tstmtList.outsideWrapperPrefix = append(stmtList.outsideWrapperPrefix, stmt)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tcase *js_ast.SFunction:\n\t\t\t// Strip the \"export\" keyword while bundling\n\t\t\tif shouldStripExports && s.IsExport {\n\t\t\t\t// Be careful to not modify the original statement\n\t\t\t\tclone := *s\n\t\t\t\tclone.IsExport = false\n\t\t\t\tstmt.Data = &clone\n\t\t\t}\n\n\t\tcase *js_ast.SClass:\n\t\t\tif shouldStripExports && s.IsExport {\n\t\t\t\t// Be careful to not modify the original statement\n\t\t\t\tclone := *s\n\t\t\t\tclone.IsExport = false\n\t\t\t\tstmt.Data = &clone\n\t\t\t}\n\n\t\tcase *js_ast.SLocal:\n\t\t\tif shouldStripExports && s.IsExport {\n\t\t\t\t// Be careful to not modify the original statement\n\t\t\t\tclone := *s\n\t\t\t\tclone.IsExport = false\n\t\t\t\tstmt.Data = &clone\n\t\t\t}\n\n\t\tcase *js_ast.SExportDefault:\n\t\t\t// If we're bundling, convert \"export default\" into a normal declaration\n\t\t\tif shouldStripExports {\n\t\t\t\tswitch s2 := s.Value.Data.(type) {\n\t\t\t\tcase *js_ast.SExpr:\n\t\t\t\t\t// \"export default foo;\" => \"var default = foo;\"\n\t\t\t\t\tstmt = js_ast.Stmt{Loc: stmt.Loc, Data: &js_ast.SLocal{Decls: []js_ast.Decl{\n\t\t\t\t\t\t{Binding: js_ast.Binding{Loc: s.DefaultName.Loc, Data: &js_ast.BIdentifier{Ref: s.DefaultName.Ref}}, ValueOrNil: s2.Value},\n\t\t\t\t\t}}}\n\n\t\t\t\tcase *js_ast.SFunction:\n\t\t\t\t\t// \"export default function() {}\" => \"function default() {}\"\n\t\t\t\t\t// \"export default function foo() {}\" => \"function foo() {}\"\n\n\t\t\t\t\t// Be careful to not modify the original statement\n\t\t\t\t\ts2 = &js_ast.SFunction{Fn: s2.Fn}\n\t\t\t\t\ts2.Fn.Name = &s.DefaultName\n\n\t\t\t\t\tstmt = js_ast.Stmt{Loc: s.Value.Loc, Data: s2}\n\n\t\t\t\tcase *js_ast.SClass:\n\t\t\t\t\t// \"export default class {}\" => \"class default {}\"\n\t\t\t\t\t// \"export default class Foo {}\" => \"class Foo {}\"\n\n\t\t\t\t\t// Be careful to not modify the original statement\n\t\t\t\t\ts2 = &js_ast.SClass{Class: s2.Class}\n\t\t\t\t\ts2.Class.Name = &s.DefaultName\n\n\t\t\t\t\tstmt = js_ast.Stmt{Loc: s.Value.Loc, Data: s2}\n\n\t\t\t\tdefault:\n\t\t\t\t\tpanic(\"Internal error\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstmtList.insideWrapperSuffix = append(stmtList.insideWrapperSuffix, stmt)\n\t}\n}\n\n// \"var a = 1; var b = 2;\" => \"var a = 1, b = 2;\"\nfunc mergeAdjacentLocalStmts(stmts []js_ast.Stmt) []js_ast.Stmt {\n\tif len(stmts) == 0 {\n\t\treturn stmts\n\t}\n\n\tdidMergeWithPreviousLocal := false\n\tend := 1\n\n\tfor _, stmt := range stmts[1:] {\n\t\t// Try to merge with the previous variable statement\n\t\tif after, ok := stmt.Data.(*js_ast.SLocal); ok {\n\t\t\tif before, ok := stmts[end-1].Data.(*js_ast.SLocal); ok {\n\t\t\t\t// It must be the same kind of variable statement (i.e. let/var/const)\n\t\t\t\tif before.Kind == after.Kind && before.IsExport == after.IsExport {\n\t\t\t\t\tif didMergeWithPreviousLocal {\n\t\t\t\t\t\t// Avoid O(n^2) behavior for repeated variable declarations\n\t\t\t\t\t\tbefore.Decls = append(before.Decls, after.Decls...)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Be careful to not modify the original statement\n\t\t\t\t\t\tdidMergeWithPreviousLocal = true\n\t\t\t\t\t\tclone := *before\n\t\t\t\t\t\tclone.Decls = make([]js_ast.Decl, 0, len(before.Decls)+len(after.Decls))\n\t\t\t\t\t\tclone.Decls = append(clone.Decls, before.Decls...)\n\t\t\t\t\t\tclone.Decls = append(clone.Decls, after.Decls...)\n\t\t\t\t\t\tstmts[end-1].Data = &clone\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Otherwise, append a normal statement\n\t\tdidMergeWithPreviousLocal = false\n\t\tstmts[end] = stmt\n\t\tend++\n\t}\n\n\treturn stmts[:end]\n}\n\ntype stmtList struct {\n\t// These statements come first, and can be inside the wrapper\n\tinsideWrapperPrefix []js_ast.Stmt\n\n\t// These statements come last, and can be inside the wrapper\n\tinsideWrapperSuffix []js_ast.Stmt\n\n\toutsideWrapperPrefix []js_ast.Stmt\n}\n\ntype compileResultJS struct {\n\tjs_printer.PrintResult\n\n\tsourceIndex uint32\n\n\t// This is the line and column offset since the previous JavaScript string\n\t// or the start of the file if this is the first JavaScript string.\n\tgeneratedOffset sourcemap.LineColumnOffset\n}\n\nfunc (c *linkerContext) requireOrImportMetaForSource(sourceIndex uint32) (meta js_printer.RequireOrImportMeta) {\n\trepr := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.JSRepr)\n\tmeta.WrapperRef = repr.AST.WrapperRef\n\tmeta.IsWrapperAsync = repr.Meta.IsAsyncOrHasAsyncDependency\n\tif repr.Meta.Wrap == graph.WrapESM {\n\t\tmeta.ExportsRef = repr.AST.ExportsRef\n\t} else {\n\t\tmeta.ExportsRef = ast.InvalidRef\n\t}\n\treturn\n}\n\nfunc (c *linkerContext) generateCodeForFileInChunkJS(\n\tr renamer.Renamer,\n\twaitGroup *sync.WaitGroup,\n\tpartRange partRange,\n\ttoCommonJSRef ast.Ref,\n\ttoESMRef ast.Ref,\n\truntimeRequireRef ast.Ref,\n\tresult *compileResultJS,\n\tdataForSourceMaps []bundler.DataForSourceMap,\n) {\n\tdefer c.recoverInternalError(waitGroup, partRange.sourceIndex)\n\n\tfile := &c.graph.Files[partRange.sourceIndex]\n\trepr := file.InputFile.Repr.(*graph.JSRepr)\n\tnsExportPartIndex := js_ast.NSExportPartIndex\n\tneedsWrapper := false\n\tstmtList := stmtList{}\n\n\t// The top-level directive must come first (the non-wrapped case is handled\n\t// by the chunk generation code, although only for the entry point)\n\tif repr.Meta.Wrap != graph.WrapNone && !file.IsEntryPoint() {\n\t\tfor _, directive := range repr.AST.Directives {\n\t\t\tstmtList.insideWrapperPrefix = append(stmtList.insideWrapperPrefix, js_ast.Stmt{\n\t\t\t\tData: &js_ast.SDirective{Value: helpers.StringToUTF16(directive)},\n\t\t\t})\n\t\t}\n\t}\n\n\t// Make sure the generated call to \"__export(exports, ...)\" comes first\n\t// before anything else.\n\tif nsExportPartIndex >= partRange.partIndexBegin && nsExportPartIndex < partRange.partIndexEnd &&\n\t\trepr.AST.Parts[nsExportPartIndex].IsLive {\n\t\tc.convertStmtsForChunk(partRange.sourceIndex, &stmtList, repr.AST.Parts[nsExportPartIndex].Stmts)\n\n\t\t// Move everything to the prefix list\n\t\tif repr.Meta.Wrap == graph.WrapESM {\n\t\t\tstmtList.outsideWrapperPrefix = append(stmtList.outsideWrapperPrefix, stmtList.insideWrapperSuffix...)\n\t\t} else {\n\t\t\tstmtList.insideWrapperPrefix = append(stmtList.insideWrapperPrefix, stmtList.insideWrapperSuffix...)\n\t\t}\n\t\tstmtList.insideWrapperSuffix = nil\n\t}\n\n\tvar partIndexForLazyDefaultExport ast.Index32\n\tif repr.AST.HasLazyExport {\n\t\tif defaultExport, ok := repr.Meta.ResolvedExports[\"default\"]; ok {\n\t\t\tpartIndexForLazyDefaultExport = ast.MakeIndex32(repr.TopLevelSymbolToParts(defaultExport.Ref)[0])\n\t\t}\n\t}\n\n\t// Add all other parts in this chunk\n\tfor partIndex := partRange.partIndexBegin; partIndex < partRange.partIndexEnd; partIndex++ {\n\t\tpart := repr.AST.Parts[partIndex]\n\t\tif !repr.AST.Parts[partIndex].IsLive {\n\t\t\t// Skip the part if it's not in this chunk\n\t\t\tcontinue\n\t\t}\n\n\t\tif uint32(partIndex) == nsExportPartIndex {\n\t\t\t// Skip the generated call to \"__export()\" that was extracted above\n\t\t\tcontinue\n\t\t}\n\n\t\t// Mark if we hit the dummy part representing the wrapper\n\t\tif uint32(partIndex) == repr.Meta.WrapperPartIndex.GetIndex() {\n\t\t\tneedsWrapper = true\n\t\t\tcontinue\n\t\t}\n\n\t\tstmts := part.Stmts\n\n\t\t// If this could be a JSON file that exports a top-level object literal, go\n\t\t// over the non-default top-level properties that ended up being imported\n\t\t// and substitute references to them into the main top-level object literal.\n\t\t// So this JSON file:\n\t\t//\n\t\t//   {\n\t\t//     \"foo\": [1, 2, 3],\n\t\t//     \"bar\": [4, 5, 6],\n\t\t//   }\n\t\t//\n\t\t// is initially compiled into this:\n\t\t//\n\t\t//   export var foo = [1, 2, 3];\n\t\t//   export var bar = [4, 5, 6];\n\t\t//   export default {\n\t\t//     foo: [1, 2, 3],\n\t\t//     bar: [4, 5, 6],\n\t\t//   };\n\t\t//\n\t\t// But we turn it into this if both \"foo\" and \"default\" are imported:\n\t\t//\n\t\t//   export var foo = [1, 2, 3];\n\t\t//   export default {\n\t\t//     foo,\n\t\t//     bar: [4, 5, 6],\n\t\t//   };\n\t\t//\n\t\tif partIndexForLazyDefaultExport.IsValid() && partIndex == partIndexForLazyDefaultExport.GetIndex() {\n\t\t\tstmt := stmts[0]\n\t\t\tdefaultExport := stmt.Data.(*js_ast.SExportDefault)\n\t\t\tdefaultExpr := defaultExport.Value.Data.(*js_ast.SExpr)\n\n\t\t\t// Be careful: the top-level value in a JSON file is not necessarily an object\n\t\t\tif object, ok := defaultExpr.Value.Data.(*js_ast.EObject); ok {\n\t\t\t\tobjectClone := *object\n\t\t\t\tobjectClone.Properties = append([]js_ast.Property{}, objectClone.Properties...)\n\n\t\t\t\t// If any top-level properties ended up being imported directly, change\n\t\t\t\t// the property to just reference the corresponding variable instead\n\t\t\t\tfor i, property := range object.Properties {\n\t\t\t\t\tif str, ok := property.Key.Data.(*js_ast.EString); ok {\n\t\t\t\t\t\tif name := helpers.UTF16ToString(str.Value); name != \"default\" {\n\t\t\t\t\t\t\tif export, ok := repr.Meta.ResolvedExports[name]; ok {\n\t\t\t\t\t\t\t\tif part := repr.AST.Parts[repr.TopLevelSymbolToParts(export.Ref)[0]]; part.IsLive {\n\t\t\t\t\t\t\t\t\tref := part.Stmts[0].Data.(*js_ast.SLocal).Decls[0].Binding.Data.(*js_ast.BIdentifier).Ref\n\t\t\t\t\t\t\t\t\tobjectClone.Properties[i].ValueOrNil = js_ast.Expr{Loc: property.Key.Loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Avoid mutating the original AST\n\t\t\t\tdefaultExprClone := *defaultExpr\n\t\t\t\tdefaultExprClone.Value.Data = &objectClone\n\t\t\t\tdefaultExportClone := *defaultExport\n\t\t\t\tdefaultExportClone.Value.Data = &defaultExprClone\n\t\t\t\tstmt.Data = &defaultExportClone\n\t\t\t\tstmts = []js_ast.Stmt{stmt}\n\t\t\t}\n\t\t}\n\n\t\tc.convertStmtsForChunk(partRange.sourceIndex, &stmtList, stmts)\n\t}\n\n\t// Hoist all import statements before any normal statements. ES6 imports\n\t// are different than CommonJS imports. All modules imported via ES6 import\n\t// statements are evaluated before the module doing the importing is\n\t// evaluated (well, except for cyclic import scenarios). We need to preserve\n\t// these semantics even when modules imported via ES6 import statements end\n\t// up being CommonJS modules.\n\tstmts := stmtList.insideWrapperSuffix\n\tif len(stmtList.insideWrapperPrefix) > 0 {\n\t\tstmts = append(stmtList.insideWrapperPrefix, stmts...)\n\t}\n\tif c.options.MinifySyntax {\n\t\tstmts = mergeAdjacentLocalStmts(stmts)\n\t}\n\n\t// Optionally wrap all statements in a closure\n\tif needsWrapper {\n\t\tswitch repr.Meta.Wrap {\n\t\tcase graph.WrapCJS:\n\t\t\t// Only include the arguments that are actually used\n\t\t\targs := []js_ast.Arg{}\n\t\t\tif repr.AST.UsesExportsRef || repr.AST.UsesModuleRef {\n\t\t\t\targs = append(args, js_ast.Arg{Binding: js_ast.Binding{Data: &js_ast.BIdentifier{Ref: repr.AST.ExportsRef}}})\n\t\t\t\tif repr.AST.UsesModuleRef {\n\t\t\t\t\targs = append(args, js_ast.Arg{Binding: js_ast.Binding{Data: &js_ast.BIdentifier{Ref: repr.AST.ModuleRef}}})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar cjsArgs []js_ast.Expr\n\t\t\tif c.options.ProfilerNames {\n\t\t\t\t// \"__commonJS({ 'file.js'(exports, module) { ... } })\"\n\t\t\t\tkind := js_ast.PropertyField\n\t\t\t\tif !c.options.UnsupportedJSFeatures.Has(compat.ObjectExtensions) {\n\t\t\t\t\tkind = js_ast.PropertyMethod\n\t\t\t\t}\n\t\t\t\tcjsArgs = []js_ast.Expr{{Data: &js_ast.EObject{Properties: []js_ast.Property{{\n\t\t\t\t\tKind:       kind,\n\t\t\t\t\tKey:        js_ast.Expr{Data: &js_ast.EString{Value: helpers.StringToUTF16(file.InputFile.Source.PrettyPaths.Select(c.options.CodePathStyle))}},\n\t\t\t\t\tValueOrNil: js_ast.Expr{Data: &js_ast.EFunction{Fn: js_ast.Fn{Args: args, Body: js_ast.FnBody{Block: js_ast.SBlock{Stmts: stmts}}}}},\n\t\t\t\t}}}}}\n\t\t\t} else if c.options.UnsupportedJSFeatures.Has(compat.Arrow) {\n\t\t\t\t// \"__commonJS(function (exports, module) { ... })\"\n\t\t\t\tcjsArgs = []js_ast.Expr{{Data: &js_ast.EFunction{Fn: js_ast.Fn{Args: args, Body: js_ast.FnBody{Block: js_ast.SBlock{Stmts: stmts}}}}}}\n\t\t\t} else {\n\t\t\t\t// \"__commonJS((exports, module) => { ... })\"\n\t\t\t\tcjsArgs = []js_ast.Expr{{Data: &js_ast.EArrow{Args: args, Body: js_ast.FnBody{Block: js_ast.SBlock{Stmts: stmts}}}}}\n\t\t\t}\n\t\t\tvalue := js_ast.Expr{Data: &js_ast.ECall{\n\t\t\t\tTarget: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: c.cjsRuntimeRef}},\n\t\t\t\tArgs:   cjsArgs,\n\t\t\t}}\n\n\t\t\t// \"var require_foo = __commonJS(...);\"\n\t\t\tstmts = append(stmtList.outsideWrapperPrefix, js_ast.Stmt{Data: &js_ast.SLocal{\n\t\t\t\tDecls: []js_ast.Decl{{\n\t\t\t\t\tBinding:    js_ast.Binding{Data: &js_ast.BIdentifier{Ref: repr.AST.WrapperRef}},\n\t\t\t\t\tValueOrNil: value,\n\t\t\t\t}},\n\t\t\t}})\n\n\t\tcase graph.WrapESM:\n\t\t\t// The wrapper only needs to be \"async\" if there is a transitive async\n\t\t\t// dependency. For correctness, we must not use \"async\" if the module\n\t\t\t// isn't async because then calling \"require()\" on that module would\n\t\t\t// swallow any exceptions thrown during module initialization.\n\t\t\tisAsync := repr.Meta.IsAsyncOrHasAsyncDependency\n\n\t\t\t// Hoist all top-level \"var\" and \"function\" declarations out of the closure\n\t\t\tvar decls []js_ast.Decl\n\t\t\tend := 0\n\t\t\tfor _, stmt := range stmts {\n\t\t\t\tswitch s := stmt.Data.(type) {\n\t\t\t\tcase *js_ast.SLocal:\n\t\t\t\t\t// Convert the declarations to assignments\n\t\t\t\t\twrapIdentifier := func(loc logger.Loc, ref ast.Ref) js_ast.Expr {\n\t\t\t\t\t\tdecls = append(decls, js_ast.Decl{Binding: js_ast.Binding{Loc: loc, Data: &js_ast.BIdentifier{Ref: ref}}})\n\t\t\t\t\t\treturn js_ast.Expr{Loc: loc, Data: &js_ast.EIdentifier{Ref: ref}}\n\t\t\t\t\t}\n\t\t\t\t\tvar value js_ast.Expr\n\t\t\t\t\tfor _, decl := range s.Decls {\n\t\t\t\t\t\tbinding := js_ast.ConvertBindingToExpr(decl.Binding, wrapIdentifier)\n\t\t\t\t\t\tif decl.ValueOrNil.Data != nil {\n\t\t\t\t\t\t\tvalue = js_ast.JoinWithComma(value, js_ast.Assign(binding, decl.ValueOrNil))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif value.Data == nil {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tstmt = js_ast.Stmt{Loc: stmt.Loc, Data: &js_ast.SExpr{Value: value}}\n\n\t\t\t\tcase *js_ast.SFunction:\n\t\t\t\t\tstmtList.outsideWrapperPrefix = append(stmtList.outsideWrapperPrefix, stmt)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tstmts[end] = stmt\n\t\t\t\tend++\n\t\t\t}\n\t\t\tstmts = stmts[:end]\n\n\t\t\tvar esmArgs []js_ast.Expr\n\t\t\tif c.options.ProfilerNames {\n\t\t\t\t// \"__esm({ 'file.js'() { ... } })\"\n\t\t\t\tkind := js_ast.PropertyField\n\t\t\t\tif !c.options.UnsupportedJSFeatures.Has(compat.ObjectExtensions) {\n\t\t\t\t\tkind = js_ast.PropertyMethod\n\t\t\t\t}\n\t\t\t\tesmArgs = []js_ast.Expr{{Data: &js_ast.EObject{Properties: []js_ast.Property{{\n\t\t\t\t\tKind:       kind,\n\t\t\t\t\tKey:        js_ast.Expr{Data: &js_ast.EString{Value: helpers.StringToUTF16(file.InputFile.Source.PrettyPaths.Select(c.options.CodePathStyle))}},\n\t\t\t\t\tValueOrNil: js_ast.Expr{Data: &js_ast.EFunction{Fn: js_ast.Fn{Body: js_ast.FnBody{Block: js_ast.SBlock{Stmts: stmts}}, IsAsync: isAsync}}},\n\t\t\t\t}}}}}\n\t\t\t} else if c.options.UnsupportedJSFeatures.Has(compat.Arrow) {\n\t\t\t\t// \"__esm(function () { ... })\"\n\t\t\t\tesmArgs = []js_ast.Expr{{Data: &js_ast.EFunction{Fn: js_ast.Fn{Body: js_ast.FnBody{Block: js_ast.SBlock{Stmts: stmts}}, IsAsync: isAsync}}}}\n\t\t\t} else {\n\t\t\t\t// \"__esm(() => { ... })\"\n\t\t\t\tesmArgs = []js_ast.Expr{{Data: &js_ast.EArrow{Body: js_ast.FnBody{Block: js_ast.SBlock{Stmts: stmts}}, IsAsync: isAsync}}}\n\t\t\t}\n\t\t\tvalue := js_ast.Expr{Data: &js_ast.ECall{\n\t\t\t\tTarget: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: c.esmRuntimeRef}},\n\t\t\t\tArgs:   esmArgs,\n\t\t\t}}\n\n\t\t\t// \"var foo, bar;\"\n\t\t\tif !c.options.MinifySyntax && len(decls) > 0 {\n\t\t\t\tstmtList.outsideWrapperPrefix = append(stmtList.outsideWrapperPrefix, js_ast.Stmt{Data: &js_ast.SLocal{\n\t\t\t\t\tDecls: decls,\n\t\t\t\t}})\n\t\t\t\tdecls = nil\n\t\t\t}\n\n\t\t\t// \"var init_foo = __esm(...);\"\n\t\t\tstmts = append(stmtList.outsideWrapperPrefix, js_ast.Stmt{Data: &js_ast.SLocal{\n\t\t\t\tDecls: append(decls, js_ast.Decl{\n\t\t\t\t\tBinding:    js_ast.Binding{Data: &js_ast.BIdentifier{Ref: repr.AST.WrapperRef}},\n\t\t\t\t\tValueOrNil: value,\n\t\t\t\t}),\n\t\t\t}})\n\t\t}\n\t}\n\n\t// Only generate a source map if needed\n\tvar addSourceMappings bool\n\tvar inputSourceMap *sourcemap.SourceMap\n\tvar lineOffsetTables []sourcemap.LineOffsetTable\n\tif file.InputFile.Loader.CanHaveSourceMap() && c.options.SourceMap != config.SourceMapNone {\n\t\taddSourceMappings = true\n\t\tinputSourceMap = file.InputFile.InputSourceMap\n\t\tlineOffsetTables = dataForSourceMaps[partRange.sourceIndex].LineOffsetTables\n\t}\n\n\t// Indent the file if everything is wrapped in an IIFE\n\tindent := 0\n\tif c.options.OutputFormat == config.FormatIIFE {\n\t\tindent++\n\t}\n\n\t// Convert the AST to JavaScript code\n\tprintOptions := js_printer.Options{\n\t\tIndent:                       indent,\n\t\tOutputFormat:                 c.options.OutputFormat,\n\t\tMinifyIdentifiers:            c.options.MinifyIdentifiers,\n\t\tMinifyWhitespace:             c.options.MinifyWhitespace,\n\t\tMinifySyntax:                 c.options.MinifySyntax,\n\t\tLineLimit:                    c.options.LineLimit,\n\t\tASCIIOnly:                    c.options.ASCIIOnly,\n\t\tToCommonJSRef:                toCommonJSRef,\n\t\tToESMRef:                     toESMRef,\n\t\tRuntimeRequireRef:            runtimeRequireRef,\n\t\tTSEnums:                      c.graph.TSEnums,\n\t\tConstValues:                  c.graph.ConstValues,\n\t\tLegalComments:                c.options.LegalComments,\n\t\tUnsupportedFeatures:          c.options.UnsupportedJSFeatures,\n\t\tSourceMap:                    c.options.SourceMap,\n\t\tAddSourceMappings:            addSourceMappings,\n\t\tInputSourceMap:               inputSourceMap,\n\t\tLineOffsetTables:             lineOffsetTables,\n\t\tRequireOrImportMetaForSource: c.requireOrImportMetaForSource,\n\t\tMangledProps:                 c.mangledProps,\n\t\tNeedsMetafile:                c.options.NeedsMetafile,\n\t\tMetafileFormat:               c.options.MetafileFormat,\n\t}\n\ttree := repr.AST\n\ttree.Directives = nil // This is handled elsewhere\n\ttree.Parts = []js_ast.Part{{Stmts: stmts}}\n\t*result = compileResultJS{\n\t\tPrintResult: js_printer.Print(tree, c.graph.Symbols, r, printOptions),\n\t\tsourceIndex: partRange.sourceIndex,\n\t}\n\n\tif file.InputFile.Loader == config.LoaderFile {\n\t\tresult.JSONMetadataImports = append(result.JSONMetadataImports, fmt.Sprintf(\n\t\t\tc.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n        {\\n          \\\"path\\\": %s,\\n          \\\"kind\\\": \\\"file-loader\\\"\\n        }\"),\n\t\t\thelpers.QuoteForJSON(file.InputFile.UniqueKeyForAdditionalFile, c.options.ASCIIOnly)))\n\t}\n\n\twaitGroup.Done()\n}\n\nfunc (c *linkerContext) generateEntryPointTailJS(\n\tr renamer.Renamer,\n\ttoCommonJSRef ast.Ref,\n\ttoESMRef ast.Ref,\n\tsourceIndex uint32,\n) (result compileResultJS) {\n\tfile := &c.graph.Files[sourceIndex]\n\trepr := file.InputFile.Repr.(*graph.JSRepr)\n\tvar stmts []js_ast.Stmt\n\n\tswitch c.options.OutputFormat {\n\tcase config.FormatPreserve:\n\t\tif repr.Meta.Wrap != graph.WrapNone {\n\t\t\t// \"require_foo();\"\n\t\t\t// \"init_foo();\"\n\t\t\tstmts = append(stmts, js_ast.Stmt{Data: &js_ast.SExpr{Value: js_ast.Expr{Data: &js_ast.ECall{\n\t\t\t\tTarget: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: repr.AST.WrapperRef}},\n\t\t\t}}}})\n\t\t}\n\n\tcase config.FormatIIFE:\n\t\tif repr.Meta.Wrap == graph.WrapCJS {\n\t\t\tif len(c.options.GlobalName) > 0 {\n\t\t\t\t// \"return require_foo();\"\n\t\t\t\tstmts = append(stmts, js_ast.Stmt{Data: &js_ast.SReturn{ValueOrNil: js_ast.Expr{Data: &js_ast.ECall{\n\t\t\t\t\tTarget: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: repr.AST.WrapperRef}},\n\t\t\t\t}}}})\n\t\t\t} else {\n\t\t\t\t// \"require_foo();\"\n\t\t\t\tstmts = append(stmts, js_ast.Stmt{Data: &js_ast.SExpr{Value: js_ast.Expr{Data: &js_ast.ECall{\n\t\t\t\t\tTarget: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: repr.AST.WrapperRef}},\n\t\t\t\t}}}})\n\t\t\t}\n\t\t} else {\n\t\t\tif repr.Meta.Wrap == graph.WrapESM {\n\t\t\t\t// \"init_foo();\"\n\t\t\t\tstmts = append(stmts, js_ast.Stmt{Data: &js_ast.SExpr{Value: js_ast.Expr{Data: &js_ast.ECall{\n\t\t\t\t\tTarget: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: repr.AST.WrapperRef}},\n\t\t\t\t}}}})\n\t\t\t}\n\n\t\t\tif repr.Meta.ForceIncludeExportsForEntryPoint {\n\t\t\t\t// \"return __toCommonJS(exports);\"\n\t\t\t\tstmts = append(stmts, js_ast.Stmt{Data: &js_ast.SReturn{\n\t\t\t\t\tValueOrNil: js_ast.Expr{Data: &js_ast.ECall{\n\t\t\t\t\t\tTarget: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: toCommonJSRef}},\n\t\t\t\t\t\tArgs:   []js_ast.Expr{{Data: &js_ast.EIdentifier{Ref: repr.AST.ExportsRef}}},\n\t\t\t\t\t}},\n\t\t\t\t}})\n\t\t\t}\n\t\t}\n\n\tcase config.FormatCommonJS:\n\t\tif repr.Meta.Wrap == graph.WrapCJS {\n\t\t\t// \"module.exports = require_foo();\"\n\t\t\tstmts = append(stmts, js_ast.AssignStmt(\n\t\t\t\tjs_ast.Expr{Data: &js_ast.EDot{\n\t\t\t\t\tTarget: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: c.unboundModuleRef}},\n\t\t\t\t\tName:   \"exports\",\n\t\t\t\t}},\n\t\t\t\tjs_ast.Expr{Data: &js_ast.ECall{\n\t\t\t\t\tTarget: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: repr.AST.WrapperRef}},\n\t\t\t\t}},\n\t\t\t))\n\t\t} else {\n\t\t\tif repr.Meta.Wrap == graph.WrapESM {\n\t\t\t\t// \"init_foo();\"\n\t\t\t\tstmts = append(stmts, js_ast.Stmt{Data: &js_ast.SExpr{Value: js_ast.Expr{Data: &js_ast.ECall{\n\t\t\t\t\tTarget: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: repr.AST.WrapperRef}},\n\t\t\t\t}}}})\n\t\t\t}\n\t\t}\n\n\t\t// If we are generating CommonJS for node, encode the known export names in\n\t\t// a form that node can understand them. This relies on the specific behavior\n\t\t// of this parser, which the node project uses to detect named exports in\n\t\t// CommonJS files: https://github.com/guybedford/cjs-module-lexer. Think of\n\t\t// this code as an annotation for that parser.\n\t\tif c.options.Platform == config.PlatformNode {\n\t\t\t// Add a comment since otherwise people will surely wonder what this is.\n\t\t\t// This annotation means you can do this and have it work:\n\t\t\t//\n\t\t\t//   import { name } from './file-from-esbuild.cjs'\n\t\t\t//\n\t\t\t// when \"file-from-esbuild.cjs\" looks like this:\n\t\t\t//\n\t\t\t//   __export(exports, { name: () => name });\n\t\t\t//   0 && (module.exports = {name});\n\t\t\t//\n\t\t\t// The maintainer of \"cjs-module-lexer\" is receptive to adding esbuild-\n\t\t\t// friendly patterns to this library. However, this library has already\n\t\t\t// shipped in node and using existing patterns instead of defining new\n\t\t\t// patterns is maximally compatible.\n\t\t\t//\n\t\t\t// An alternative to doing this could be to use \"Object.defineProperties\"\n\t\t\t// instead of \"__export\" but support for that would need to be added to\n\t\t\t// \"cjs-module-lexer\" and then we would need to be ok with not supporting\n\t\t\t// older versions of node that don't have that newly-added support.\n\n\t\t\t// \"{a, b, if: null}\"\n\t\t\tvar moduleExports []js_ast.Property\n\t\t\tfor _, export := range repr.Meta.SortedAndFilteredExportAliases {\n\t\t\t\tif export == \"default\" {\n\t\t\t\t\t// In node the default export is always \"module.exports\" regardless of\n\t\t\t\t\t// what the annotation says. So don't bother generating \"default\".\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// \"{if: null}\"\n\t\t\t\tvar valueOrNil js_ast.Expr\n\t\t\t\tif _, ok := js_lexer.Keywords[export]; ok || !js_ast.IsIdentifier(export) {\n\t\t\t\t\t// Make sure keywords don't cause a syntax error. This has to map to\n\t\t\t\t\t// \"null\" instead of something shorter like \"0\" because the library\n\t\t\t\t\t// \"cjs-module-lexer\" only supports identifiers in this position, and\n\t\t\t\t\t// it thinks \"null\" is an identifier.\n\t\t\t\t\tvalueOrNil = js_ast.Expr{Data: js_ast.ENullShared}\n\t\t\t\t}\n\n\t\t\t\tmoduleExports = append(moduleExports, js_ast.Property{\n\t\t\t\t\tKey:        js_ast.Expr{Data: &js_ast.EString{Value: helpers.StringToUTF16(export)}},\n\t\t\t\t\tValueOrNil: valueOrNil,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Add annotations for re-exports: \"{...require('./foo')}\"\n\t\t\tfor _, importRecordIndex := range repr.AST.ExportStarImportRecords {\n\t\t\t\tif record := &repr.AST.ImportRecords[importRecordIndex]; !record.SourceIndex.IsValid() {\n\t\t\t\t\tmoduleExports = append(moduleExports, js_ast.Property{\n\t\t\t\t\t\tKind:       js_ast.PropertySpread,\n\t\t\t\t\t\tValueOrNil: js_ast.Expr{Data: &js_ast.ERequireString{ImportRecordIndex: importRecordIndex}},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif len(moduleExports) > 0 {\n\t\t\t\t// \"0 && (module.exports = {a, b, if: null});\"\n\t\t\t\texpr := js_ast.Expr{Data: &js_ast.EBinary{\n\t\t\t\t\tOp:   js_ast.BinOpLogicalAnd,\n\t\t\t\t\tLeft: js_ast.Expr{Data: &js_ast.ENumber{Value: 0}},\n\t\t\t\t\tRight: js_ast.Assign(\n\t\t\t\t\t\tjs_ast.Expr{Data: &js_ast.EDot{\n\t\t\t\t\t\t\tTarget: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: c.unboundModuleRef}},\n\t\t\t\t\t\t\tName:   \"exports\",\n\t\t\t\t\t\t}},\n\t\t\t\t\t\tjs_ast.Expr{Data: &js_ast.EObject{Properties: moduleExports}},\n\t\t\t\t\t),\n\t\t\t\t}}\n\n\t\t\t\tif !c.options.MinifyWhitespace {\n\t\t\t\t\tstmts = append(stmts,\n\t\t\t\t\t\tjs_ast.Stmt{Data: &js_ast.SComment{Text: `// Annotate the CommonJS export names for ESM import in node:`}},\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tstmts = append(stmts, js_ast.Stmt{Data: &js_ast.SExpr{Value: expr}})\n\t\t\t}\n\t\t}\n\n\tcase config.FormatESModule:\n\t\tif repr.Meta.Wrap == graph.WrapCJS {\n\t\t\t// \"export default require_foo();\"\n\t\t\tstmts = append(stmts, js_ast.Stmt{\n\t\t\t\tData: &js_ast.SExportDefault{Value: js_ast.Stmt{\n\t\t\t\t\tData: &js_ast.SExpr{Value: js_ast.Expr{\n\t\t\t\t\t\tData: &js_ast.ECall{Target: js_ast.Expr{\n\t\t\t\t\t\t\tData: &js_ast.EIdentifier{Ref: repr.AST.WrapperRef}}}}}}}})\n\t\t} else {\n\t\t\tif repr.Meta.Wrap == graph.WrapESM {\n\t\t\t\tif repr.Meta.IsAsyncOrHasAsyncDependency {\n\t\t\t\t\t// \"await init_foo();\"\n\t\t\t\t\tstmts = append(stmts, js_ast.Stmt{\n\t\t\t\t\t\tData: &js_ast.SExpr{Value: js_ast.Expr{\n\t\t\t\t\t\t\tData: &js_ast.EAwait{Value: js_ast.Expr{\n\t\t\t\t\t\t\t\tData: &js_ast.ECall{Target: js_ast.Expr{\n\t\t\t\t\t\t\t\t\tData: &js_ast.EIdentifier{Ref: repr.AST.WrapperRef}}}}}}}})\n\t\t\t\t} else {\n\t\t\t\t\t// \"init_foo();\"\n\t\t\t\t\tstmts = append(stmts, js_ast.Stmt{\n\t\t\t\t\t\tData: &js_ast.SExpr{\n\t\t\t\t\t\t\tValue: js_ast.Expr{Data: &js_ast.ECall{Target: js_ast.Expr{\n\t\t\t\t\t\t\t\tData: &js_ast.EIdentifier{Ref: repr.AST.WrapperRef}}}}}})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif len(repr.Meta.SortedAndFilteredExportAliases) > 0 {\n\t\t\t\t// If the output format is ES6 modules and we're an entry point, generate an\n\t\t\t\t// ES6 export statement containing all exports. Except don't do that if this\n\t\t\t\t// entry point is a CommonJS-style module, since that would generate an ES6\n\t\t\t\t// export statement that's not top-level. Instead, we will export the CommonJS\n\t\t\t\t// exports as a default export later on.\n\t\t\t\tvar items []js_ast.ClauseItem\n\n\t\t\t\tfor i, alias := range repr.Meta.SortedAndFilteredExportAliases {\n\t\t\t\t\texport := repr.Meta.ResolvedExports[alias]\n\n\t\t\t\t\t// If this is an export of an import, reference the symbol that the import\n\t\t\t\t\t// was eventually resolved to. We need to do this because imports have\n\t\t\t\t\t// already been resolved by this point, so we can't generate a new import\n\t\t\t\t\t// and have that be resolved later.\n\t\t\t\t\tif importData, ok := c.graph.Files[export.SourceIndex].InputFile.Repr.(*graph.JSRepr).Meta.ImportsToBind[export.Ref]; ok {\n\t\t\t\t\t\texport.Ref = importData.Ref\n\t\t\t\t\t\texport.SourceIndex = importData.SourceIndex\n\t\t\t\t\t}\n\n\t\t\t\t\t// Exports of imports need EImportIdentifier in case they need to be re-\n\t\t\t\t\t// written to a property access later on\n\t\t\t\t\tif c.graph.Symbols.Get(export.Ref).NamespaceAlias != nil {\n\t\t\t\t\t\t// Create both a local variable and an export clause for that variable.\n\t\t\t\t\t\t// The local variable is initialized with the initial value of the\n\t\t\t\t\t\t// export. This isn't fully correct because it's a \"dead\" binding and\n\t\t\t\t\t\t// doesn't update with the \"live\" value as it changes. But ES6 modules\n\t\t\t\t\t\t// don't have any syntax for bare named getter functions so this is the\n\t\t\t\t\t\t// best we can do.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// These input files:\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//   // entry_point.js\n\t\t\t\t\t\t//   export {foo} from './cjs-format.js'\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//   // cjs-format.js\n\t\t\t\t\t\t//   Object.defineProperty(exports, 'foo', {\n\t\t\t\t\t\t//     enumerable: true,\n\t\t\t\t\t\t//     get: () => Math.random(),\n\t\t\t\t\t\t//   })\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// Become this output file:\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//   // cjs-format.js\n\t\t\t\t\t\t//   var require_cjs_format = __commonJS((exports) => {\n\t\t\t\t\t\t//     Object.defineProperty(exports, \"foo\", {\n\t\t\t\t\t\t//       enumerable: true,\n\t\t\t\t\t\t//       get: () => Math.random()\n\t\t\t\t\t\t//     });\n\t\t\t\t\t\t//   });\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//   // entry_point.js\n\t\t\t\t\t\t//   var cjs_format = __toESM(require_cjs_format());\n\t\t\t\t\t\t//   var export_foo = cjs_format.foo;\n\t\t\t\t\t\t//   export {\n\t\t\t\t\t\t//     export_foo as foo\n\t\t\t\t\t\t//   };\n\t\t\t\t\t\t//\n\t\t\t\t\t\ttempRef := repr.Meta.CJSExportCopies[i]\n\t\t\t\t\t\tstmts = append(stmts, js_ast.Stmt{Data: &js_ast.SLocal{\n\t\t\t\t\t\t\tDecls: []js_ast.Decl{{\n\t\t\t\t\t\t\t\tBinding:    js_ast.Binding{Data: &js_ast.BIdentifier{Ref: tempRef}},\n\t\t\t\t\t\t\t\tValueOrNil: js_ast.Expr{Data: &js_ast.EImportIdentifier{Ref: export.Ref}},\n\t\t\t\t\t\t\t}},\n\t\t\t\t\t\t}})\n\t\t\t\t\t\titems = append(items, js_ast.ClauseItem{\n\t\t\t\t\t\t\tName:  ast.LocRef{Ref: tempRef},\n\t\t\t\t\t\t\tAlias: alias,\n\t\t\t\t\t\t})\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Local identifiers can be exported using an export clause. This is done\n\t\t\t\t\t\t// this way instead of leaving the \"export\" keyword on the local declaration\n\t\t\t\t\t\t// itself both because it lets the local identifier be minified and because\n\t\t\t\t\t\t// it works transparently for re-exports across files.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// These input files:\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//   // entry_point.js\n\t\t\t\t\t\t//   export * from './esm-format.js'\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//   // esm-format.js\n\t\t\t\t\t\t//   export let foo = 123\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// Become this output file:\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//   // esm-format.js\n\t\t\t\t\t\t//   let foo = 123;\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//   // entry_point.js\n\t\t\t\t\t\t//   export {\n\t\t\t\t\t\t//     foo\n\t\t\t\t\t\t//   };\n\t\t\t\t\t\t//\n\t\t\t\t\t\titems = append(items, js_ast.ClauseItem{\n\t\t\t\t\t\t\tName:  ast.LocRef{Ref: export.Ref},\n\t\t\t\t\t\t\tAlias: alias,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tstmts = append(stmts, js_ast.Stmt{Data: &js_ast.SExportClause{Items: items}})\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(stmts) == 0 {\n\t\treturn\n\t}\n\n\ttree := repr.AST\n\ttree.Directives = nil\n\ttree.Parts = []js_ast.Part{{Stmts: stmts}}\n\n\t// Indent the file if everything is wrapped in an IIFE\n\tindent := 0\n\tif c.options.OutputFormat == config.FormatIIFE {\n\t\tindent++\n\t}\n\n\t// Convert the AST to JavaScript code\n\tprintOptions := js_printer.Options{\n\t\tIndent:                       indent,\n\t\tOutputFormat:                 c.options.OutputFormat,\n\t\tMinifyIdentifiers:            c.options.MinifyIdentifiers,\n\t\tMinifyWhitespace:             c.options.MinifyWhitespace,\n\t\tMinifySyntax:                 c.options.MinifySyntax,\n\t\tLineLimit:                    c.options.LineLimit,\n\t\tASCIIOnly:                    c.options.ASCIIOnly,\n\t\tToCommonJSRef:                toCommonJSRef,\n\t\tToESMRef:                     toESMRef,\n\t\tLegalComments:                c.options.LegalComments,\n\t\tUnsupportedFeatures:          c.options.UnsupportedJSFeatures,\n\t\tRequireOrImportMetaForSource: c.requireOrImportMetaForSource,\n\t\tMangledProps:                 c.mangledProps,\n\t}\n\tresult.PrintResult = js_printer.Print(tree, c.graph.Symbols, r, printOptions)\n\treturn\n}\n\nfunc (c *linkerContext) renameSymbolsInChunk(chunk *chunkInfo, filesInOrder []uint32, timer *helpers.Timer) renamer.Renamer {\n\tif c.options.MinifyIdentifiers {\n\t\ttimer.Begin(\"Minify symbols\")\n\t\tdefer timer.End(\"Minify symbols\")\n\t} else {\n\t\ttimer.Begin(\"Rename symbols\")\n\t\tdefer timer.End(\"Rename symbols\")\n\t}\n\n\t// Determine the reserved names (e.g. can't generate the name \"if\")\n\ttimer.Begin(\"Compute reserved names\")\n\tmoduleScopes := make([]*js_ast.Scope, len(filesInOrder))\n\tfor i, sourceIndex := range filesInOrder {\n\t\tmoduleScopes[i] = c.graph.Files[sourceIndex].InputFile.Repr.(*graph.JSRepr).AST.ModuleScope\n\t}\n\treservedNames := renamer.ComputeReservedNames(moduleScopes, c.graph.Symbols)\n\n\t// Node contains code that scans CommonJS modules in an attempt to statically\n\t// detect the  set of export names that a module will use. However, it doesn't\n\t// do any scope analysis so it can be fooled by local variables with the same\n\t// name as the CommonJS module-scope variables \"exports\" and \"module\". Avoid\n\t// using these names in this case even if there is not a risk of a name\n\t// collision because there is still a risk of node incorrectly detecting\n\t// something in a nested scope as an top-level export. Here's a case where\n\t// this happened: https://github.com/evanw/esbuild/issues/3544\n\tif c.options.OutputFormat == config.FormatCommonJS && c.options.Platform == config.PlatformNode {\n\t\treservedNames[\"exports\"] = 1\n\t\treservedNames[\"module\"] = 1\n\t}\n\n\t// These are used to implement bundling, and need to be free for use\n\tif c.options.Mode != config.ModePassThrough {\n\t\treservedNames[\"require\"] = 1\n\t\treservedNames[\"Promise\"] = 1\n\t}\n\ttimer.End(\"Compute reserved names\")\n\n\t// Make sure imports get a chance to be renamed too\n\tvar sortedImportsFromOtherChunks stableRefArray\n\tfor _, imports := range chunk.chunkRepr.(*chunkReprJS).importsFromOtherChunks {\n\t\tfor _, item := range imports {\n\t\t\tsortedImportsFromOtherChunks = append(sortedImportsFromOtherChunks, stableRef{\n\t\t\t\tStableSourceIndex: c.graph.StableSourceIndices[item.ref.SourceIndex],\n\t\t\t\tRef:               item.ref,\n\t\t\t})\n\t\t}\n\t}\n\tsort.Sort(sortedImportsFromOtherChunks)\n\n\t// Minification uses frequency analysis to give shorter names to more frequent symbols\n\tif c.options.MinifyIdentifiers {\n\t\t// Determine the first top-level slot (i.e. not in a nested scope)\n\t\tvar firstTopLevelSlots ast.SlotCounts\n\t\tfor _, sourceIndex := range filesInOrder {\n\t\t\tfirstTopLevelSlots.UnionMax(c.graph.Files[sourceIndex].InputFile.Repr.(*graph.JSRepr).AST.NestedScopeSlotCounts)\n\t\t}\n\t\tr := renamer.NewMinifyRenamer(c.graph.Symbols, firstTopLevelSlots, reservedNames)\n\n\t\t// Accumulate nested symbol usage counts\n\t\ttimer.Begin(\"Accumulate symbol counts\")\n\t\ttimer.Begin(\"Parallel phase\")\n\t\tallTopLevelSymbols := make([]renamer.StableSymbolCountArray, len(filesInOrder))\n\t\tstableSourceIndices := c.graph.StableSourceIndices\n\t\tfreq := ast.CharFreq{}\n\t\twaitGroup := sync.WaitGroup{}\n\t\twaitGroup.Add(len(filesInOrder))\n\t\tfor i, sourceIndex := range filesInOrder {\n\t\t\trepr := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.JSRepr)\n\n\t\t\t// Do this outside of the goroutine because it's not atomic\n\t\t\tif repr.AST.CharFreq != nil {\n\t\t\t\tfreq.Include(repr.AST.CharFreq)\n\t\t\t}\n\n\t\t\tgo func(topLevelSymbols *renamer.StableSymbolCountArray, repr *graph.JSRepr) {\n\t\t\t\tif repr.AST.UsesExportsRef {\n\t\t\t\t\tr.AccumulateSymbolCount(topLevelSymbols, repr.AST.ExportsRef, 1, stableSourceIndices)\n\t\t\t\t}\n\t\t\t\tif repr.AST.UsesModuleRef {\n\t\t\t\t\tr.AccumulateSymbolCount(topLevelSymbols, repr.AST.ModuleRef, 1, stableSourceIndices)\n\t\t\t\t}\n\n\t\t\t\tfor partIndex, part := range repr.AST.Parts {\n\t\t\t\t\tif !repr.AST.Parts[partIndex].IsLive {\n\t\t\t\t\t\t// Skip the part if it's not in this chunk\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// Accumulate symbol use counts\n\t\t\t\t\tr.AccumulateSymbolUseCounts(topLevelSymbols, part.SymbolUses, stableSourceIndices)\n\n\t\t\t\t\t// Make sure to also count the declaration in addition to the uses\n\t\t\t\t\tfor _, declared := range part.DeclaredSymbols {\n\t\t\t\t\t\tr.AccumulateSymbolCount(topLevelSymbols, declared.Ref, 1, stableSourceIndices)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsort.Sort(topLevelSymbols)\n\t\t\t\twaitGroup.Done()\n\t\t\t}(&allTopLevelSymbols[i], repr)\n\t\t}\n\t\twaitGroup.Wait()\n\t\ttimer.End(\"Parallel phase\")\n\n\t\t// Accumulate top-level symbol usage counts\n\t\ttimer.Begin(\"Serial phase\")\n\t\tcapacity := len(sortedImportsFromOtherChunks)\n\t\tfor _, array := range allTopLevelSymbols {\n\t\t\tcapacity += len(array)\n\t\t}\n\t\ttopLevelSymbols := make(renamer.StableSymbolCountArray, 0, capacity)\n\t\tfor _, stable := range sortedImportsFromOtherChunks {\n\t\t\tr.AccumulateSymbolCount(&topLevelSymbols, stable.Ref, 1, stableSourceIndices)\n\t\t}\n\t\tfor _, array := range allTopLevelSymbols {\n\t\t\ttopLevelSymbols = append(topLevelSymbols, array...)\n\t\t}\n\t\tr.AllocateTopLevelSymbolSlots(topLevelSymbols)\n\t\ttimer.End(\"Serial phase\")\n\t\ttimer.End(\"Accumulate symbol counts\")\n\n\t\t// Add all of the character frequency histograms for all files in this\n\t\t// chunk together, then use it to compute the character sequence used to\n\t\t// generate minified names. This results in slightly better gzip compression\n\t\t// over assigning minified names in order (i.e. \"a b c ...\"). Even though\n\t\t// it's a very small win, we still do it because it's simple to do and very\n\t\t// cheap to compute.\n\t\tminifier := ast.DefaultNameMinifierJS.ShuffleByCharFreq(freq)\n\t\ttimer.Begin(\"Assign names by frequency\")\n\t\tr.AssignNamesByFrequency(&minifier)\n\t\ttimer.End(\"Assign names by frequency\")\n\t\treturn r\n\t}\n\n\t// When we're not minifying, just append numbers to symbol names to avoid collisions\n\tr := renamer.NewNumberRenamer(c.graph.Symbols, reservedNames)\n\tnestedScopes := make(map[uint32][]*js_ast.Scope)\n\n\ttimer.Begin(\"Add top-level symbols\")\n\tfor _, stable := range sortedImportsFromOtherChunks {\n\t\tr.AddTopLevelSymbol(stable.Ref)\n\t}\n\tfor _, sourceIndex := range filesInOrder {\n\t\trepr := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\tvar scopes []*js_ast.Scope\n\n\t\t// Modules wrapped in a CommonJS closure look like this:\n\t\t//\n\t\t//   // foo.js\n\t\t//   var require_foo = __commonJS((exports, module) => {\n\t\t//     exports.foo = 123;\n\t\t//   });\n\t\t//\n\t\t// The symbol \"require_foo\" is stored in \"file.ast.WrapperRef\". We want\n\t\t// to be able to minify everything inside the closure without worrying\n\t\t// about collisions with other CommonJS modules. Set up the scopes such\n\t\t// that it appears as if the file was structured this way all along. It's\n\t\t// not completely accurate (e.g. we don't set the parent of the module\n\t\t// scope to this new top-level scope) but it's good enough for the\n\t\t// renaming code.\n\t\tif repr.Meta.Wrap == graph.WrapCJS {\n\t\t\tr.AddTopLevelSymbol(repr.AST.WrapperRef)\n\n\t\t\t// External import statements will be hoisted outside of the CommonJS\n\t\t\t// wrapper if the output format supports import statements. We need to\n\t\t\t// add those symbols to the top-level scope to avoid causing name\n\t\t\t// collisions. This code special-cases only those symbols.\n\t\t\tif c.options.OutputFormat.KeepESMImportExportSyntax() {\n\t\t\t\tfor _, part := range repr.AST.Parts {\n\t\t\t\t\tfor _, stmt := range part.Stmts {\n\t\t\t\t\t\tswitch s := stmt.Data.(type) {\n\t\t\t\t\t\tcase *js_ast.SImport:\n\t\t\t\t\t\t\tif !repr.AST.ImportRecords[s.ImportRecordIndex].SourceIndex.IsValid() {\n\t\t\t\t\t\t\t\tr.AddTopLevelSymbol(s.NamespaceRef)\n\t\t\t\t\t\t\t\tif s.DefaultName != nil {\n\t\t\t\t\t\t\t\t\tr.AddTopLevelSymbol(s.DefaultName.Ref)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif s.Items != nil {\n\t\t\t\t\t\t\t\t\tfor _, item := range *s.Items {\n\t\t\t\t\t\t\t\t\t\tr.AddTopLevelSymbol(item.Name.Ref)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcase *js_ast.SExportStar:\n\t\t\t\t\t\t\tif !repr.AST.ImportRecords[s.ImportRecordIndex].SourceIndex.IsValid() {\n\t\t\t\t\t\t\t\tr.AddTopLevelSymbol(s.NamespaceRef)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcase *js_ast.SExportFrom:\n\t\t\t\t\t\t\tif !repr.AST.ImportRecords[s.ImportRecordIndex].SourceIndex.IsValid() {\n\t\t\t\t\t\t\t\tr.AddTopLevelSymbol(s.NamespaceRef)\n\t\t\t\t\t\t\t\tfor _, item := range s.Items {\n\t\t\t\t\t\t\t\t\tr.AddTopLevelSymbol(item.Name.Ref)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tnestedScopes[sourceIndex] = []*js_ast.Scope{repr.AST.ModuleScope}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Modules wrapped in an ESM closure look like this:\n\t\t//\n\t\t//   // foo.js\n\t\t//   var foo, foo_exports = {};\n\t\t//   __export(foo_exports, {\n\t\t//     foo: () => foo\n\t\t//   });\n\t\t//   let init_foo = __esm(() => {\n\t\t//     foo = 123;\n\t\t//   });\n\t\t//\n\t\t// The symbol \"init_foo\" is stored in \"file.ast.WrapperRef\". We need to\n\t\t// minify everything inside the closure without introducing a new scope\n\t\t// since all top-level variables will be hoisted outside of the closure.\n\t\tif repr.Meta.Wrap == graph.WrapESM {\n\t\t\tr.AddTopLevelSymbol(repr.AST.WrapperRef)\n\t\t}\n\n\t\t// Rename each top-level symbol declaration in this chunk\n\t\tfor partIndex, part := range repr.AST.Parts {\n\t\t\tif repr.AST.Parts[partIndex].IsLive {\n\t\t\t\tfor _, declared := range part.DeclaredSymbols {\n\t\t\t\t\tif declared.IsTopLevel {\n\t\t\t\t\t\tr.AddTopLevelSymbol(declared.Ref)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tscopes = append(scopes, part.Scopes...)\n\t\t\t}\n\t\t}\n\n\t\tnestedScopes[sourceIndex] = scopes\n\t}\n\ttimer.End(\"Add top-level symbols\")\n\n\t// Recursively rename symbols in child scopes now that all top-level\n\t// symbols have been renamed. This is done in parallel because the symbols\n\t// inside nested scopes are independent and can't conflict.\n\ttimer.Begin(\"Assign names by scope\")\n\tr.AssignNamesByScope(nestedScopes)\n\ttimer.End(\"Assign names by scope\")\n\treturn r\n}\n\nfunc (c *linkerContext) generateChunkJS(chunkIndex int, chunkWaitGroup *sync.WaitGroup) {\n\tdefer c.recoverInternalError(chunkWaitGroup, runtime.SourceIndex)\n\n\tchunk := &c.chunks[chunkIndex]\n\n\ttimer := c.timer.Fork()\n\tif timer != nil {\n\t\ttimeName := fmt.Sprintf(\"Generate chunk %q\", path.Clean(config.TemplateToString(chunk.finalTemplate)))\n\t\ttimer.Begin(timeName)\n\t\tdefer c.timer.Join(timer)\n\t\tdefer timer.End(timeName)\n\t}\n\n\tchunkRepr := chunk.chunkRepr.(*chunkReprJS)\n\tcompileResults := make([]compileResultJS, 0, len(chunkRepr.partsInChunkInOrder))\n\truntimeMembers := c.graph.Files[runtime.SourceIndex].InputFile.Repr.(*graph.JSRepr).AST.ModuleScope.Members\n\ttoCommonJSRef := ast.FollowSymbols(c.graph.Symbols, runtimeMembers[\"__toCommonJS\"].Ref)\n\ttoESMRef := ast.FollowSymbols(c.graph.Symbols, runtimeMembers[\"__toESM\"].Ref)\n\truntimeRequireRef := ast.FollowSymbols(c.graph.Symbols, runtimeMembers[\"__require\"].Ref)\n\tr := c.renameSymbolsInChunk(chunk, chunkRepr.filesInChunkInOrder, timer)\n\tdataForSourceMaps := c.dataForSourceMaps()\n\n\t// Note: This contains placeholders instead of what the placeholders are\n\t// substituted with. That should be fine though because this should only\n\t// ever be used for figuring out how many \"../\" to add to a relative path\n\t// from a chunk whose final path hasn't been calculated yet to a chunk\n\t// whose final path has already been calculated. That and placeholders are\n\t// never substituted with something containing a \"/\" so substitution should\n\t// never change the \"../\" count.\n\tchunkAbsDir := c.fs.Dir(c.fs.Join(c.options.AbsOutputDir, config.TemplateToString(chunk.finalTemplate)))\n\n\t// Generate JavaScript for each file in parallel\n\ttimer.Begin(\"Print JavaScript files\")\n\twaitGroup := sync.WaitGroup{}\n\tfor _, partRange := range chunkRepr.partsInChunkInOrder {\n\t\t// Skip the runtime in test output\n\t\tif partRange.sourceIndex == runtime.SourceIndex && c.options.OmitRuntimeForTests {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Create a goroutine for this file\n\t\tcompileResults = append(compileResults, compileResultJS{})\n\t\tcompileResult := &compileResults[len(compileResults)-1]\n\t\twaitGroup.Add(1)\n\t\tgo c.generateCodeForFileInChunkJS(\n\t\t\tr,\n\t\t\t&waitGroup,\n\t\t\tpartRange,\n\t\t\ttoCommonJSRef,\n\t\t\ttoESMRef,\n\t\t\truntimeRequireRef,\n\t\t\tcompileResult,\n\t\t\tdataForSourceMaps,\n\t\t)\n\t}\n\n\t// Also generate the cross-chunk binding code\n\tvar crossChunkPrefix []byte\n\tvar crossChunkSuffix []byte\n\tvar jsonMetadataImports []string\n\t{\n\t\t// Indent the file if everything is wrapped in an IIFE\n\t\tindent := 0\n\t\tif c.options.OutputFormat == config.FormatIIFE {\n\t\t\tindent++\n\t\t}\n\t\tprintOptions := js_printer.Options{\n\t\t\tIndent:            indent,\n\t\t\tOutputFormat:      c.options.OutputFormat,\n\t\t\tMinifyIdentifiers: c.options.MinifyIdentifiers,\n\t\t\tMinifyWhitespace:  c.options.MinifyWhitespace,\n\t\t\tMinifySyntax:      c.options.MinifySyntax,\n\t\t\tLineLimit:         c.options.LineLimit,\n\t\t\tNeedsMetafile:     c.options.NeedsMetafile,\n\t\t\tMetafileFormat:    c.options.MetafileFormat,\n\t\t}\n\t\tcrossChunkImportRecords := make([]ast.ImportRecord, len(chunk.crossChunkImports))\n\t\tfor i, chunkImport := range chunk.crossChunkImports {\n\t\t\tcrossChunkImportRecords[i] = ast.ImportRecord{\n\t\t\t\tKind:  chunkImport.importKind,\n\t\t\t\tPath:  logger.Path{Text: c.chunks[chunkImport.chunkIndex].uniqueKey},\n\t\t\t\tFlags: ast.ShouldNotBeExternalInMetafile | ast.ContainsUniqueKey,\n\t\t\t}\n\t\t}\n\t\tcrossChunkResult := js_printer.Print(js_ast.AST{\n\t\t\tImportRecords: crossChunkImportRecords,\n\t\t\tParts:         []js_ast.Part{{Stmts: chunkRepr.crossChunkPrefixStmts}},\n\t\t}, c.graph.Symbols, r, printOptions)\n\t\tcrossChunkPrefix = crossChunkResult.JS\n\t\tjsonMetadataImports = crossChunkResult.JSONMetadataImports\n\t\tcrossChunkSuffix = js_printer.Print(js_ast.AST{\n\t\t\tParts: []js_ast.Part{{Stmts: chunkRepr.crossChunkSuffixStmts}},\n\t\t}, c.graph.Symbols, r, printOptions).JS\n\t}\n\n\t// Generate the exports for the entry point, if there are any\n\tvar entryPointTail compileResultJS\n\tif chunk.isEntryPoint {\n\t\tentryPointTail = c.generateEntryPointTailJS(\n\t\t\tr,\n\t\t\ttoCommonJSRef,\n\t\t\ttoESMRef,\n\t\t\tchunk.sourceIndex,\n\t\t)\n\t}\n\n\twaitGroup.Wait()\n\ttimer.End(\"Print JavaScript files\")\n\ttimer.Begin(\"Join JavaScript files\")\n\n\tj := helpers.Joiner{}\n\tprevOffset := sourcemap.LineColumnOffset{}\n\n\t// Optionally strip whitespace\n\tindent := \"\"\n\tspace := \" \"\n\tnewline := \"\\n\"\n\tif c.options.MinifyWhitespace {\n\t\tspace = \"\"\n\t\tnewline = \"\"\n\t}\n\tnewlineBeforeComment := false\n\tisExecutable := false\n\n\t// Start with the hashbang if there is one. This must be done before the\n\t// banner because it only works if it's literally the first character.\n\tif chunk.isEntryPoint {\n\t\tif repr := c.graph.Files[chunk.sourceIndex].InputFile.Repr.(*graph.JSRepr); repr.AST.Hashbang != \"\" {\n\t\t\thashbang := repr.AST.Hashbang + \"\\n\"\n\t\t\tprevOffset.AdvanceString(hashbang)\n\t\t\tj.AddString(hashbang)\n\t\t\tnewlineBeforeComment = true\n\t\t\tisExecutable = true\n\t\t}\n\t}\n\n\t// Then emit the banner after the hashbang. This must come before the\n\t// \"use strict\" directive below because some people use the banner to\n\t// emit a hashbang, which must be the first thing in the file.\n\tif len(c.options.JSBanner) > 0 {\n\t\tprevOffset.AdvanceString(c.options.JSBanner)\n\t\tprevOffset.AdvanceString(\"\\n\")\n\t\tj.AddString(c.options.JSBanner)\n\t\tj.AddString(\"\\n\")\n\t\tnewlineBeforeComment = true\n\t}\n\n\t// Add the top-level directive if present (but omit \"use strict\" in ES\n\t// modules because all ES modules are automatically in strict mode)\n\tif chunk.isEntryPoint {\n\t\trepr := c.graph.Files[chunk.sourceIndex].InputFile.Repr.(*graph.JSRepr)\n\t\tfor _, directive := range repr.AST.Directives {\n\t\t\tif directive != \"use strict\" || c.options.OutputFormat != config.FormatESModule {\n\t\t\t\tquoted := string(helpers.QuoteForJSON(directive, c.options.ASCIIOnly)) + \";\" + newline\n\t\t\t\tprevOffset.AdvanceString(quoted)\n\t\t\t\tj.AddString(quoted)\n\t\t\t\tnewlineBeforeComment = true\n\t\t\t}\n\t\t}\n\t}\n\n\t// Optionally wrap with an IIFE\n\tif c.options.OutputFormat == config.FormatIIFE {\n\t\tvar text string\n\t\tindent = \"  \"\n\t\tif len(c.options.GlobalName) > 0 {\n\t\t\ttext = c.generateGlobalNamePrefix()\n\t\t}\n\t\tif c.options.UnsupportedJSFeatures.Has(compat.Arrow) {\n\t\t\ttext += \"(function()\" + space + \"{\" + newline\n\t\t} else {\n\t\t\ttext += \"(()\" + space + \"=>\" + space + \"{\" + newline\n\t\t}\n\t\tprevOffset.AdvanceString(text)\n\t\tj.AddString(text)\n\t\tnewlineBeforeComment = false\n\t}\n\n\t// Put the cross-chunk prefix inside the IIFE\n\tif len(crossChunkPrefix) > 0 {\n\t\tnewlineBeforeComment = true\n\t\tprevOffset.AdvanceBytes(crossChunkPrefix)\n\t\tj.AddBytes(crossChunkPrefix)\n\t}\n\n\t// Start the metadata\n\tjMeta := helpers.Joiner{}\n\tif c.options.NeedsMetafile {\n\t\t// Print imports\n\t\tisFirstMeta := true\n\t\tjMeta.AddString(c.options.MetafileFormat.MaybeRemoveWhitespace(\"{\\n      \\\"imports\\\": [\"))\n\t\tfor _, json := range jsonMetadataImports {\n\t\t\tif isFirstMeta {\n\t\t\t\tisFirstMeta = false\n\t\t\t} else {\n\t\t\t\tjMeta.AddString(\",\")\n\t\t\t}\n\t\t\tjMeta.AddString(json)\n\t\t}\n\t\tfor _, compileResult := range compileResults {\n\t\t\tfor _, json := range compileResult.JSONMetadataImports {\n\t\t\t\tif isFirstMeta {\n\t\t\t\t\tisFirstMeta = false\n\t\t\t\t} else {\n\t\t\t\t\tjMeta.AddString(\",\")\n\t\t\t\t}\n\t\t\t\tjMeta.AddString(json)\n\t\t\t}\n\t\t}\n\t\tif !isFirstMeta {\n\t\t\tjMeta.AddString(c.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n      \"))\n\t\t}\n\n\t\t// Print exports\n\t\tjMeta.AddString(c.options.MetafileFormat.MaybeRemoveWhitespace(\"],\\n      \\\"exports\\\": [\"))\n\t\tvar aliases []string\n\t\tif c.options.OutputFormat.KeepESMImportExportSyntax() {\n\t\t\tif chunk.isEntryPoint {\n\t\t\t\tif fileRepr := c.graph.Files[chunk.sourceIndex].InputFile.Repr.(*graph.JSRepr); fileRepr.Meta.Wrap == graph.WrapCJS {\n\t\t\t\t\taliases = []string{\"default\"}\n\t\t\t\t} else {\n\t\t\t\t\tresolvedExports := fileRepr.Meta.ResolvedExports\n\t\t\t\t\taliases = make([]string, 0, len(resolvedExports))\n\t\t\t\t\tfor alias := range resolvedExports {\n\t\t\t\t\t\taliases = append(aliases, alias)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\taliases = make([]string, 0, len(chunkRepr.exportsToOtherChunks))\n\t\t\t\tfor _, alias := range chunkRepr.exportsToOtherChunks {\n\t\t\t\t\taliases = append(aliases, alias)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tisFirstMeta = true\n\t\tsort.Strings(aliases) // Sort for determinism\n\t\tfor _, alias := range aliases {\n\t\t\tif isFirstMeta {\n\t\t\t\tisFirstMeta = false\n\t\t\t} else {\n\t\t\t\tjMeta.AddString(\",\")\n\t\t\t}\n\t\t\tjMeta.AddString(fmt.Sprintf(\n\t\t\t\tc.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n        %s\"),\n\t\t\t\thelpers.QuoteForJSON(alias, c.options.ASCIIOnly)))\n\t\t}\n\t\tif !isFirstMeta {\n\t\t\tjMeta.AddString(c.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n      \"))\n\t\t}\n\t\tjMeta.AddString(c.options.MetafileFormat.MaybeRemoveWhitespace(\"],\\n\"))\n\t\tif chunk.isEntryPoint {\n\t\t\tentryPoint := c.graph.Files[chunk.sourceIndex].InputFile.Source.PrettyPaths.Select(c.options.MetafilePathStyle)\n\t\t\tjMeta.AddString(fmt.Sprintf(c.options.MetafileFormat.MaybeRemoveWhitespace(\"      \\\"entryPoint\\\": %s,\\n\"), helpers.QuoteForJSON(entryPoint, c.options.ASCIIOnly)))\n\t\t}\n\t\tif chunkRepr.hasCSSChunk {\n\t\t\tjMeta.AddString(fmt.Sprintf(c.options.MetafileFormat.MaybeRemoveWhitespace(\"      \\\"cssBundle\\\": %s,\\n\"), helpers.QuoteForJSON(c.chunks[chunkRepr.cssChunkIndex].uniqueKey, c.options.ASCIIOnly)))\n\t\t}\n\t\tjMeta.AddString(c.options.MetafileFormat.MaybeRemoveWhitespace(\"      \\\"inputs\\\": {\"))\n\t}\n\n\t// Concatenate the generated JavaScript chunks together\n\tvar compileResultsForSourceMap []compileResultForSourceMap\n\tvar legalCommentList []legalCommentEntry\n\tvar metaOrder []uint32\n\tvar metaBytes map[uint32][][]byte\n\tprevFileNameComment := uint32(0)\n\tif c.options.NeedsMetafile {\n\t\tmetaOrder = make([]uint32, 0, len(compileResults))\n\t\tmetaBytes = make(map[uint32][][]byte, len(compileResults))\n\t}\n\tfor _, compileResult := range compileResults {\n\t\tif len(compileResult.ExtractedLegalComments) > 0 {\n\t\t\tlegalCommentList = append(legalCommentList, legalCommentEntry{\n\t\t\t\tsourceIndex: compileResult.sourceIndex,\n\t\t\t\tcomments:    compileResult.ExtractedLegalComments,\n\t\t\t})\n\t\t}\n\n\t\t// Add a comment with the file path before the file contents\n\t\tif c.options.Mode == config.ModeBundle && !c.options.MinifyWhitespace &&\n\t\t\tprevFileNameComment != compileResult.sourceIndex && len(compileResult.JS) > 0 {\n\t\t\tif newlineBeforeComment {\n\t\t\t\tprevOffset.AdvanceString(\"\\n\")\n\t\t\t\tj.AddString(\"\\n\")\n\t\t\t}\n\n\t\t\tpath := c.graph.Files[compileResult.sourceIndex].InputFile.Source.PrettyPaths.Select(c.options.CodePathStyle)\n\n\t\t\t// Make sure newlines in the path can't cause a syntax error. This does\n\t\t\t// not minimize allocations because it's expected that this case never\n\t\t\t// comes up in practice.\n\t\t\tpath = strings.ReplaceAll(path, \"\\r\", \"\\\\r\")\n\t\t\tpath = strings.ReplaceAll(path, \"\\n\", \"\\\\n\")\n\t\t\tpath = strings.ReplaceAll(path, \"\\u2028\", \"\\\\u2028\")\n\t\t\tpath = strings.ReplaceAll(path, \"\\u2029\", \"\\\\u2029\")\n\n\t\t\ttext := fmt.Sprintf(\"%s// %s\\n\", indent, path)\n\t\t\tprevOffset.AdvanceString(text)\n\t\t\tj.AddString(text)\n\t\t\tprevFileNameComment = compileResult.sourceIndex\n\t\t}\n\n\t\t// Don't include the runtime in source maps\n\t\tif c.graph.Files[compileResult.sourceIndex].InputFile.OmitFromSourceMapsAndMetafile {\n\t\t\tprevOffset.AdvanceString(string(compileResult.JS))\n\t\t\tj.AddBytes(compileResult.JS)\n\t\t} else {\n\t\t\t// Save the offset to the start of the stored JavaScript\n\t\t\tcompileResult.generatedOffset = prevOffset\n\t\t\tj.AddBytes(compileResult.JS)\n\n\t\t\t// Ignore empty source map chunks\n\t\t\tif compileResult.SourceMapChunk.ShouldIgnore {\n\t\t\t\tprevOffset.AdvanceBytes(compileResult.JS)\n\n\t\t\t\t// Include a null entry in the source map\n\t\t\t\tif len(compileResult.JS) > 0 && c.options.SourceMap != config.SourceMapNone {\n\t\t\t\t\tif n := len(compileResultsForSourceMap); n > 0 && !compileResultsForSourceMap[n-1].isNullEntry {\n\t\t\t\t\t\tcompileResultsForSourceMap = append(compileResultsForSourceMap, compileResultForSourceMap{\n\t\t\t\t\t\t\tsourceIndex: compileResult.sourceIndex,\n\t\t\t\t\t\t\tisNullEntry: true,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tprevOffset = sourcemap.LineColumnOffset{}\n\n\t\t\t\t// Include this file in the source map\n\t\t\t\tif c.options.SourceMap != config.SourceMapNone {\n\t\t\t\t\tcompileResultsForSourceMap = append(compileResultsForSourceMap, compileResultForSourceMap{\n\t\t\t\t\t\tsourceMapChunk:  compileResult.SourceMapChunk,\n\t\t\t\t\t\tgeneratedOffset: compileResult.generatedOffset,\n\t\t\t\t\t\tsourceIndex:     compileResult.sourceIndex,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Include this file in the metadata\n\t\t\tif c.options.NeedsMetafile {\n\t\t\t\t// Accumulate file sizes since a given file may be split into multiple parts\n\t\t\t\tbytes, ok := metaBytes[compileResult.sourceIndex]\n\t\t\t\tif !ok {\n\t\t\t\t\tmetaOrder = append(metaOrder, compileResult.sourceIndex)\n\t\t\t\t}\n\t\t\t\tmetaBytes[compileResult.sourceIndex] = append(bytes, compileResult.JS)\n\t\t\t}\n\t\t}\n\n\t\t// Put a newline before the next file path comment\n\t\tif len(compileResult.JS) > 0 {\n\t\t\tnewlineBeforeComment = true\n\t\t}\n\t}\n\n\t// Stick the entry point tail at the end of the file. Deliberately don't\n\t// include any source mapping information for this because it's automatically\n\t// generated and doesn't correspond to a location in the input file.\n\tj.AddBytes(entryPointTail.JS)\n\n\t// Put the cross-chunk suffix inside the IIFE\n\tif len(crossChunkSuffix) > 0 {\n\t\tif newlineBeforeComment {\n\t\t\tj.AddString(newline)\n\t\t}\n\t\tj.AddBytes(crossChunkSuffix)\n\t}\n\n\t// Optionally wrap with an IIFE\n\tif c.options.OutputFormat == config.FormatIIFE {\n\t\tj.AddString(\"})();\" + newline)\n\t}\n\n\t// Make sure the file ends with a newline\n\tj.EnsureNewlineAtEnd()\n\tslashTag := \"/script\"\n\tif c.options.UnsupportedJSFeatures.Has(compat.InlineScript) {\n\t\tslashTag = \"\"\n\t}\n\tc.maybeAppendLegalComments(c.options.LegalComments, legalCommentList, chunk, &j, slashTag)\n\n\tif len(c.options.JSFooter) > 0 {\n\t\tj.AddString(c.options.JSFooter)\n\t\tj.AddString(\"\\n\")\n\t}\n\n\t// The JavaScript contents are done now that the source map comment is in\n\tchunk.intermediateOutput = c.breakJoinerIntoPieces(j)\n\ttimer.End(\"Join JavaScript files\")\n\n\tif c.options.SourceMap != config.SourceMapNone {\n\t\ttimer.Begin(\"Generate source map\")\n\t\tcanHaveShifts := chunk.intermediateOutput.pieces != nil\n\t\tchunk.outputSourceMap = c.generateSourceMapForChunk(compileResultsForSourceMap, chunkAbsDir, dataForSourceMaps, canHaveShifts)\n\t\ttimer.End(\"Generate source map\")\n\t}\n\n\t// End the metadata lazily. The final output size is not known until the\n\t// final import paths are substituted into the output pieces generated below.\n\tif c.options.NeedsMetafile {\n\t\tpieces := make([][]intermediateOutput, len(metaOrder))\n\t\tfor i, sourceIndex := range metaOrder {\n\t\t\tslices := metaBytes[sourceIndex]\n\t\t\toutputs := make([]intermediateOutput, len(slices))\n\t\t\tfor j, slice := range slices {\n\t\t\t\toutputs[j] = c.breakOutputIntoPieces(slice)\n\t\t\t}\n\t\t\tpieces[i] = outputs\n\t\t}\n\t\tchunk.jsonMetadataChunkCallback = func(finalOutputSize int) helpers.Joiner {\n\t\t\tfinalRelDir := c.fs.Dir(chunk.finalRelPath)\n\t\t\tfor i, sourceIndex := range metaOrder {\n\t\t\t\tif i > 0 {\n\t\t\t\t\tjMeta.AddString(\",\")\n\t\t\t\t}\n\t\t\t\tcount := 0\n\t\t\t\tfor _, output := range pieces[i] {\n\t\t\t\t\tcount += c.accurateFinalByteCount(output, finalRelDir)\n\t\t\t\t}\n\t\t\t\tjMeta.AddString(fmt.Sprintf(\n\t\t\t\t\tc.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n        %s: {\\n          \\\"bytesInOutput\\\": %d\\n        %s}\"),\n\t\t\t\t\thelpers.QuoteForJSON(c.graph.Files[sourceIndex].InputFile.Source.PrettyPaths.Select(c.options.MetafilePathStyle), c.options.ASCIIOnly),\n\t\t\t\t\tcount, c.generateExtraDataForFileJS(sourceIndex)))\n\t\t\t}\n\t\t\tif len(metaOrder) > 0 {\n\t\t\t\tjMeta.AddString(c.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n      \"))\n\t\t\t}\n\t\t\tjMeta.AddString(fmt.Sprintf(c.options.MetafileFormat.MaybeRemoveWhitespace(\"},\\n      \\\"bytes\\\": %d\\n    }\"), finalOutputSize))\n\t\t\treturn jMeta\n\t\t}\n\t}\n\n\tc.generateIsolatedHashInParallel(chunk)\n\tchunk.isExecutable = isExecutable\n\tchunkWaitGroup.Done()\n}\n\nfunc (c *linkerContext) generateGlobalNamePrefix() string {\n\tvar text string\n\tglobalName := c.options.GlobalName\n\tprefix, globalName := globalName[0], globalName[1:]\n\tspace := \" \"\n\tjoin := \";\\n\"\n\n\tif c.options.MinifyWhitespace {\n\t\tspace = \"\"\n\t\tjoin = \";\"\n\t}\n\n\t// Assume the \"this\" and \"import.meta\" objects always exist\n\tisExistingObject := prefix == \"this\"\n\tif prefix == \"import\" && len(globalName) > 0 && globalName[0] == \"meta\" {\n\t\tprefix, globalName = \"import.meta\", globalName[1:]\n\t\tisExistingObject = true\n\t}\n\n\t// Use \"||=\" to make the code more compact when it's supported\n\tif len(globalName) > 0 && !c.options.UnsupportedJSFeatures.Has(compat.LogicalAssignment) {\n\t\tif isExistingObject {\n\t\t\t// Keep the prefix as it is\n\t\t} else if js_printer.CanEscapeIdentifier(prefix, c.options.UnsupportedJSFeatures, c.options.ASCIIOnly) {\n\t\t\tif c.options.ASCIIOnly {\n\t\t\t\tprefix = string(js_printer.QuoteIdentifier(nil, prefix, c.options.UnsupportedJSFeatures))\n\t\t\t}\n\t\t\ttext = fmt.Sprintf(\"var %s%s\", prefix, join)\n\t\t} else {\n\t\t\tprefix = fmt.Sprintf(\"this[%s]\", helpers.QuoteForJSON(prefix, c.options.ASCIIOnly))\n\t\t}\n\t\tfor _, name := range globalName {\n\t\t\tvar dotOrIndex string\n\t\t\tif js_printer.CanEscapeIdentifier(name, c.options.UnsupportedJSFeatures, c.options.ASCIIOnly) {\n\t\t\t\tif c.options.ASCIIOnly {\n\t\t\t\t\tname = string(js_printer.QuoteIdentifier(nil, name, c.options.UnsupportedJSFeatures))\n\t\t\t\t}\n\t\t\t\tdotOrIndex = fmt.Sprintf(\".%s\", name)\n\t\t\t} else {\n\t\t\t\tdotOrIndex = fmt.Sprintf(\"[%s]\", helpers.QuoteForJSON(name, c.options.ASCIIOnly))\n\t\t\t}\n\t\t\tif isExistingObject {\n\t\t\t\tprefix = fmt.Sprintf(\"%s%s\", prefix, dotOrIndex)\n\t\t\t\tisExistingObject = false\n\t\t\t} else {\n\t\t\t\tprefix = fmt.Sprintf(\"(%s%s||=%s{})%s\", prefix, space, space, dotOrIndex)\n\t\t\t}\n\t\t}\n\t\treturn fmt.Sprintf(\"%s%s%s=%s\", text, prefix, space, space)\n\t}\n\n\tif isExistingObject {\n\t\ttext = fmt.Sprintf(\"%s%s=%s\", prefix, space, space)\n\t} else if js_printer.CanEscapeIdentifier(prefix, c.options.UnsupportedJSFeatures, c.options.ASCIIOnly) {\n\t\tif c.options.ASCIIOnly {\n\t\t\tprefix = string(js_printer.QuoteIdentifier(nil, prefix, c.options.UnsupportedJSFeatures))\n\t\t}\n\t\ttext = fmt.Sprintf(\"var %s%s=%s\", prefix, space, space)\n\t} else {\n\t\tprefix = fmt.Sprintf(\"this[%s]\", helpers.QuoteForJSON(prefix, c.options.ASCIIOnly))\n\t\ttext = fmt.Sprintf(\"%s%s=%s\", prefix, space, space)\n\t}\n\n\tfor _, name := range globalName {\n\t\toldPrefix := prefix\n\t\tif js_printer.CanEscapeIdentifier(name, c.options.UnsupportedJSFeatures, c.options.ASCIIOnly) {\n\t\t\tif c.options.ASCIIOnly {\n\t\t\t\tname = string(js_printer.QuoteIdentifier(nil, name, c.options.UnsupportedJSFeatures))\n\t\t\t}\n\t\t\tprefix = fmt.Sprintf(\"%s.%s\", prefix, name)\n\t\t} else {\n\t\t\tprefix = fmt.Sprintf(\"%s[%s]\", prefix, helpers.QuoteForJSON(name, c.options.ASCIIOnly))\n\t\t}\n\t\ttext += fmt.Sprintf(\"%s%s||%s{}%s%s%s=%s\", oldPrefix, space, space, join, prefix, space, space)\n\t}\n\n\treturn text\n}\n\ntype compileResultCSS struct {\n\tcss_printer.PrintResult\n\n\t// This is the line and column offset since the previous CSS string\n\t// or the start of the file if this is the first CSS string.\n\tgeneratedOffset sourcemap.LineColumnOffset\n\n\t// The source index can be invalid for short snippets that aren't necessarily\n\t// tied to any one file and/or that don't really need source mappings. The\n\t// source index is really only valid for the compile result that contains the\n\t// main contents of a file, which we try to only ever write out once.\n\tsourceIndex ast.Index32\n\thasCharset  bool\n}\n\nfunc (c *linkerContext) generateChunkCSS(chunkIndex int, chunkWaitGroup *sync.WaitGroup) {\n\tdefer c.recoverInternalError(chunkWaitGroup, runtime.SourceIndex)\n\n\tchunk := &c.chunks[chunkIndex]\n\n\ttimer := c.timer.Fork()\n\tif timer != nil {\n\t\ttimeName := fmt.Sprintf(\"Generate chunk %q\", path.Clean(config.TemplateToString(chunk.finalTemplate)))\n\t\ttimer.Begin(timeName)\n\t\tdefer c.timer.Join(timer)\n\t\tdefer timer.End(timeName)\n\t}\n\n\tchunkRepr := chunk.chunkRepr.(*chunkReprCSS)\n\tcompileResults := make([]compileResultCSS, len(chunkRepr.importsInChunkInOrder))\n\tdataForSourceMaps := c.dataForSourceMaps()\n\n\t// Note: This contains placeholders instead of what the placeholders are\n\t// substituted with. That should be fine though because this should only\n\t// ever be used for figuring out how many \"../\" to add to a relative path\n\t// from a chunk whose final path hasn't been calculated yet to a chunk\n\t// whose final path has already been calculated. That and placeholders are\n\t// never substituted with something containing a \"/\" so substitution should\n\t// never change the \"../\" count.\n\tchunkAbsDir := c.fs.Dir(c.fs.Join(c.options.AbsOutputDir, config.TemplateToString(chunk.finalTemplate)))\n\n\t// Remove duplicate rules across files. This must be done in serial, not\n\t// in parallel, and must be done from the last rule to the first rule.\n\ttimer.Begin(\"Prepare CSS ASTs\")\n\tasts := make([]css_ast.AST, len(chunkRepr.importsInChunkInOrder))\n\tvar remover css_parser.DeadRuleRemover\n\tif c.options.MinifySyntax {\n\t\tremover = css_parser.MakeDeadRuleMangler(c.graph.Symbols)\n\t}\n\tfor i := len(chunkRepr.importsInChunkInOrder) - 1; i >= 0; i-- {\n\t\tentry := chunkRepr.importsInChunkInOrder[i]\n\t\tswitch entry.kind {\n\t\tcase cssImportLayers:\n\t\t\tvar rules []css_ast.Rule\n\t\t\tif len(entry.layers) > 0 {\n\t\t\t\trules = append(rules, css_ast.Rule{Data: &css_ast.RAtLayer{Names: entry.layers}})\n\t\t\t}\n\t\t\trules, importRecords := wrapRulesWithConditions(rules, nil, entry.conditions, entry.conditionImportRecords)\n\t\t\tasts[i] = css_ast.AST{Rules: rules, ImportRecords: importRecords}\n\n\t\tcase cssImportExternalPath:\n\t\t\tvar conditions *css_ast.ImportConditions\n\t\t\tif len(entry.conditions) > 0 {\n\t\t\t\tconditions = &entry.conditions[0]\n\n\t\t\t\t// Handling a chain of nested conditions is complicated. We can't\n\t\t\t\t// necessarily join them together because a) there may be multiple\n\t\t\t\t// layer names and b) layer names are only supposed to be inserted\n\t\t\t\t// into the layer order if the parent conditions are applied.\n\t\t\t\t//\n\t\t\t\t// Instead we handle them by preserving the \"@import\" nesting using\n\t\t\t\t// imports of data URL stylesheets. This may seem strange but I think\n\t\t\t\t// this is the only way to do this in CSS.\n\t\t\t\tfor i := len(entry.conditions) - 1; i > 0; i-- {\n\t\t\t\t\tastImport := css_ast.AST{\n\t\t\t\t\t\tRules: []css_ast.Rule{{Data: &css_ast.RAtImport{\n\t\t\t\t\t\t\tImportRecordIndex: uint32(len(entry.conditionImportRecords)),\n\t\t\t\t\t\t\tImportConditions:  &entry.conditions[i],\n\t\t\t\t\t\t}}},\n\t\t\t\t\t\tImportRecords: append(entry.conditionImportRecords, ast.ImportRecord{\n\t\t\t\t\t\t\tKind: ast.ImportAt,\n\t\t\t\t\t\t\tPath: entry.externalPath,\n\t\t\t\t\t\t}),\n\t\t\t\t\t}\n\t\t\t\t\tastResult := css_printer.Print(astImport, c.graph.Symbols, css_printer.Options{\n\t\t\t\t\t\tMinifyWhitespace: c.options.MinifyWhitespace,\n\t\t\t\t\t\tASCIIOnly:        c.options.ASCIIOnly,\n\t\t\t\t\t})\n\t\t\t\t\tentry.externalPath = logger.Path{Text: helpers.EncodeStringAsShortestDataURL(\"text/css\", string(bytes.TrimSpace(astResult.CSS)))}\n\t\t\t\t}\n\t\t\t}\n\t\t\tasts[i] = css_ast.AST{\n\t\t\t\tImportRecords: append(append([]ast.ImportRecord{}, entry.conditionImportRecords...), ast.ImportRecord{\n\t\t\t\t\tKind: ast.ImportAt,\n\t\t\t\t\tPath: entry.externalPath,\n\t\t\t\t}),\n\t\t\t\tRules: []css_ast.Rule{{Data: &css_ast.RAtImport{\n\t\t\t\t\tImportRecordIndex: uint32(len(entry.conditionImportRecords)),\n\t\t\t\t\tImportConditions:  conditions,\n\t\t\t\t}}},\n\t\t\t}\n\n\t\tcase cssImportSourceIndex:\n\t\t\tfile := &c.graph.Files[entry.sourceIndex]\n\t\t\tast := file.InputFile.Repr.(*graph.CSSRepr).AST\n\n\t\t\t// Filter out \"@charset\", \"@import\", and leading \"@layer\" rules\n\t\t\trules := make([]css_ast.Rule, 0, len(ast.Rules))\n\t\t\tdidFindAtImport := false\n\t\t\tdidFindAtLayer := false\n\t\t\tfor _, rule := range ast.Rules {\n\t\t\t\tswitch rule.Data.(type) {\n\t\t\t\tcase *css_ast.RAtCharset:\n\t\t\t\t\tcompileResults[i].hasCharset = true\n\t\t\t\t\tcontinue\n\t\t\t\tcase *css_ast.RAtLayer:\n\t\t\t\t\tdidFindAtLayer = true\n\t\t\t\tcase *css_ast.RAtImport:\n\t\t\t\t\tif !didFindAtImport {\n\t\t\t\t\t\tdidFindAtImport = true\n\t\t\t\t\t\tif didFindAtLayer {\n\t\t\t\t\t\t\t// Filter out the pre-import layers once we see the first\n\t\t\t\t\t\t\t// \"@import\". These layers are special-cased by the linker\n\t\t\t\t\t\t\t// and already appear as a separate entry in import order.\n\t\t\t\t\t\t\tend := 0\n\t\t\t\t\t\t\tfor _, rule := range rules {\n\t\t\t\t\t\t\t\tif _, ok := rule.Data.(*css_ast.RAtLayer); !ok {\n\t\t\t\t\t\t\t\t\trules[end] = rule\n\t\t\t\t\t\t\t\t\tend++\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\trules = rules[:end]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\trules = append(rules, rule)\n\t\t\t}\n\n\t\t\trules, ast.ImportRecords = wrapRulesWithConditions(rules, ast.ImportRecords, entry.conditions, entry.conditionImportRecords)\n\n\t\t\t// Remove top-level duplicate rules across files\n\t\t\tif c.options.MinifySyntax {\n\t\t\t\trules = remover.RemoveDeadRulesInPlace(entry.sourceIndex, rules, ast.ImportRecords)\n\t\t\t}\n\n\t\t\tast.Rules = rules\n\t\t\tasts[i] = ast\n\t\t}\n\t}\n\ttimer.End(\"Prepare CSS ASTs\")\n\n\t// Generate CSS for each file in parallel\n\ttimer.Begin(\"Print CSS files\")\n\twaitGroup := sync.WaitGroup{}\n\tfor i, entry := range chunkRepr.importsInChunkInOrder {\n\t\t// Create a goroutine for this file\n\t\twaitGroup.Add(1)\n\t\tgo func(i int, entry cssImportOrder, compileResult *compileResultCSS) {\n\t\t\tcssOptions := css_printer.Options{\n\t\t\t\tMinifyWhitespace:    c.options.MinifyWhitespace,\n\t\t\t\tLineLimit:           c.options.LineLimit,\n\t\t\t\tASCIIOnly:           c.options.ASCIIOnly,\n\t\t\t\tLegalComments:       c.options.LegalComments,\n\t\t\t\tSourceMap:           c.options.SourceMap,\n\t\t\t\tUnsupportedFeatures: c.options.UnsupportedCSSFeatures,\n\t\t\t\tNeedsMetafile:       c.options.NeedsMetafile,\n\t\t\t\tMetafileFormat:      c.options.MetafileFormat,\n\t\t\t\tLocalNames:          c.mangledProps,\n\t\t\t}\n\n\t\t\tif entry.kind == cssImportSourceIndex {\n\t\t\t\tdefer c.recoverInternalError(&waitGroup, entry.sourceIndex)\n\t\t\t\tfile := &c.graph.Files[entry.sourceIndex]\n\n\t\t\t\t// Only generate a source map if needed\n\t\t\t\tif file.InputFile.Loader.CanHaveSourceMap() && c.options.SourceMap != config.SourceMapNone {\n\t\t\t\t\tcssOptions.AddSourceMappings = true\n\t\t\t\t\tcssOptions.InputSourceMap = file.InputFile.InputSourceMap\n\t\t\t\t\tcssOptions.LineOffsetTables = dataForSourceMaps[entry.sourceIndex].LineOffsetTables\n\t\t\t\t}\n\n\t\t\t\tcssOptions.InputSourceIndex = entry.sourceIndex\n\t\t\t\tcompileResult.sourceIndex = ast.MakeIndex32(entry.sourceIndex)\n\t\t\t}\n\n\t\t\tcompileResult.PrintResult = css_printer.Print(asts[i], c.graph.Symbols, cssOptions)\n\t\t\twaitGroup.Done()\n\t\t}(i, entry, &compileResults[i])\n\t}\n\n\twaitGroup.Wait()\n\ttimer.End(\"Print CSS files\")\n\ttimer.Begin(\"Join CSS files\")\n\tj := helpers.Joiner{}\n\tprevOffset := sourcemap.LineColumnOffset{}\n\tnewlineBeforeComment := false\n\n\tif len(c.options.CSSBanner) > 0 {\n\t\tprevOffset.AdvanceString(c.options.CSSBanner)\n\t\tj.AddString(c.options.CSSBanner)\n\t\tprevOffset.AdvanceString(\"\\n\")\n\t\tj.AddString(\"\\n\")\n\t}\n\n\t// Generate any prefix rules now\n\tvar jsonMetadataImports []string\n\t{\n\t\ttree := css_ast.AST{}\n\n\t\t// \"@charset\" is the only thing that comes before \"@import\"\n\t\tfor _, compileResult := range compileResults {\n\t\t\tif compileResult.hasCharset {\n\t\t\t\ttree.Rules = append(tree.Rules, css_ast.Rule{Data: &css_ast.RAtCharset{Encoding: \"UTF-8\"}})\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif len(tree.Rules) > 0 {\n\t\t\tresult := css_printer.Print(tree, c.graph.Symbols, css_printer.Options{\n\t\t\t\tMinifyWhitespace: c.options.MinifyWhitespace,\n\t\t\t\tLineLimit:        c.options.LineLimit,\n\t\t\t\tASCIIOnly:        c.options.ASCIIOnly,\n\t\t\t\tNeedsMetafile:    c.options.NeedsMetafile,\n\t\t\t\tMetafileFormat:   c.options.MetafileFormat,\n\t\t\t})\n\t\t\tjsonMetadataImports = result.JSONMetadataImports\n\t\t\tif len(result.CSS) > 0 {\n\t\t\t\tprevOffset.AdvanceBytes(result.CSS)\n\t\t\t\tj.AddBytes(result.CSS)\n\t\t\t\tnewlineBeforeComment = true\n\t\t\t}\n\t\t}\n\t}\n\n\t// Start the metadata\n\tjMeta := helpers.Joiner{}\n\tif c.options.NeedsMetafile {\n\t\tisFirstMeta := true\n\t\tjMeta.AddString(c.options.MetafileFormat.MaybeRemoveWhitespace(\"{\\n      \\\"imports\\\": [\"))\n\t\tfor _, json := range jsonMetadataImports {\n\t\t\tif isFirstMeta {\n\t\t\t\tisFirstMeta = false\n\t\t\t} else {\n\t\t\t\tjMeta.AddString(\",\")\n\t\t\t}\n\t\t\tjMeta.AddString(json)\n\t\t}\n\t\tfor _, compileResult := range compileResults {\n\t\t\tfor _, json := range compileResult.JSONMetadataImports {\n\t\t\t\tif isFirstMeta {\n\t\t\t\t\tisFirstMeta = false\n\t\t\t\t} else {\n\t\t\t\t\tjMeta.AddString(\",\")\n\t\t\t\t}\n\t\t\t\tjMeta.AddString(json)\n\t\t\t}\n\t\t}\n\t\tif !isFirstMeta {\n\t\t\tjMeta.AddString(c.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n      \"))\n\t\t}\n\t\tif chunk.isEntryPoint {\n\t\t\tfile := &c.graph.Files[chunk.sourceIndex]\n\n\t\t\t// Do not generate \"entryPoint\" for CSS files that are the result of\n\t\t\t// importing CSS into JavaScript. We want this to be a 1:1 relationship\n\t\t\t// and there is already an output file for the JavaScript entry point.\n\t\t\tif _, ok := file.InputFile.Repr.(*graph.CSSRepr); ok {\n\t\t\t\tjMeta.AddString(fmt.Sprintf(\n\t\t\t\t\tc.options.MetafileFormat.MaybeRemoveWhitespace(\"],\\n      \\\"entryPoint\\\": %s,\\n      \\\"inputs\\\": {\"),\n\t\t\t\t\thelpers.QuoteForJSON(file.InputFile.Source.PrettyPaths.Select(c.options.MetafilePathStyle), c.options.ASCIIOnly)))\n\t\t\t} else {\n\t\t\t\tjMeta.AddString(c.options.MetafileFormat.MaybeRemoveWhitespace(\"],\\n      \\\"inputs\\\": {\"))\n\t\t\t}\n\t\t} else {\n\t\t\tjMeta.AddString(c.options.MetafileFormat.MaybeRemoveWhitespace(\"],\\n      \\\"inputs\\\": {\"))\n\t\t}\n\t}\n\n\t// Concatenate the generated CSS chunks together\n\tvar compileResultsForSourceMap []compileResultForSourceMap\n\tvar legalCommentList []legalCommentEntry\n\tfor _, compileResult := range compileResults {\n\t\tif len(compileResult.ExtractedLegalComments) > 0 && compileResult.sourceIndex.IsValid() {\n\t\t\tlegalCommentList = append(legalCommentList, legalCommentEntry{\n\t\t\t\tsourceIndex: compileResult.sourceIndex.GetIndex(),\n\t\t\t\tcomments:    compileResult.ExtractedLegalComments,\n\t\t\t})\n\t\t}\n\n\t\tif c.options.Mode == config.ModeBundle && !c.options.MinifyWhitespace && compileResult.sourceIndex.IsValid() {\n\t\t\tvar newline string\n\t\t\tif newlineBeforeComment {\n\t\t\t\tnewline = \"\\n\"\n\t\t\t}\n\t\t\tcomment := fmt.Sprintf(\"%s/* %s */\\n\", newline,\n\t\t\t\tc.graph.Files[compileResult.sourceIndex.GetIndex()].InputFile.Source.PrettyPaths.Select(c.options.CodePathStyle))\n\t\t\tprevOffset.AdvanceString(comment)\n\t\t\tj.AddString(comment)\n\t\t}\n\t\tif len(compileResult.CSS) > 0 {\n\t\t\tnewlineBeforeComment = true\n\t\t}\n\n\t\t// Save the offset to the start of the stored JavaScript\n\t\tcompileResult.generatedOffset = prevOffset\n\t\tj.AddBytes(compileResult.CSS)\n\n\t\t// Ignore empty source map chunks\n\t\tif compileResult.SourceMapChunk.ShouldIgnore {\n\t\t\tprevOffset.AdvanceBytes(compileResult.CSS)\n\n\t\t\t// Include a null entry in the source map\n\t\t\tif len(compileResult.CSS) > 0 && c.options.SourceMap != config.SourceMapNone && compileResult.sourceIndex.IsValid() {\n\t\t\t\tif n := len(compileResultsForSourceMap); n > 0 && !compileResultsForSourceMap[n-1].isNullEntry {\n\t\t\t\t\tcompileResultsForSourceMap = append(compileResultsForSourceMap, compileResultForSourceMap{\n\t\t\t\t\t\tsourceIndex: compileResult.sourceIndex.GetIndex(),\n\t\t\t\t\t\tisNullEntry: true,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tprevOffset = sourcemap.LineColumnOffset{}\n\n\t\t\t// Include this file in the source map\n\t\t\tif c.options.SourceMap != config.SourceMapNone && compileResult.sourceIndex.IsValid() {\n\t\t\t\tcompileResultsForSourceMap = append(compileResultsForSourceMap, compileResultForSourceMap{\n\t\t\t\t\tsourceMapChunk:  compileResult.SourceMapChunk,\n\t\t\t\t\tgeneratedOffset: compileResult.generatedOffset,\n\t\t\t\t\tsourceIndex:     compileResult.sourceIndex.GetIndex(),\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\t// Make sure the file ends with a newline\n\tj.EnsureNewlineAtEnd()\n\tslashTag := \"/style\"\n\tif c.options.UnsupportedCSSFeatures.Has(compat.InlineStyle) {\n\t\tslashTag = \"\"\n\t}\n\tc.maybeAppendLegalComments(c.options.LegalComments, legalCommentList, chunk, &j, slashTag)\n\n\tif len(c.options.CSSFooter) > 0 {\n\t\tj.AddString(c.options.CSSFooter)\n\t\tj.AddString(\"\\n\")\n\t}\n\n\t// The CSS contents are done now that the source map comment is in\n\tchunk.intermediateOutput = c.breakJoinerIntoPieces(j)\n\ttimer.End(\"Join CSS files\")\n\n\tif c.options.SourceMap != config.SourceMapNone {\n\t\ttimer.Begin(\"Generate source map\")\n\t\tcanHaveShifts := chunk.intermediateOutput.pieces != nil\n\t\tchunk.outputSourceMap = c.generateSourceMapForChunk(compileResultsForSourceMap, chunkAbsDir, dataForSourceMaps, canHaveShifts)\n\t\ttimer.End(\"Generate source map\")\n\t}\n\n\t// End the metadata lazily. The final output size is not known until the\n\t// final import paths are substituted into the output pieces generated below.\n\tif c.options.NeedsMetafile {\n\t\tpieces := make([]intermediateOutput, len(compileResults))\n\t\tfor i, compileResult := range compileResults {\n\t\t\tpieces[i] = c.breakOutputIntoPieces(compileResult.CSS)\n\t\t}\n\t\tchunk.jsonMetadataChunkCallback = func(finalOutputSize int) helpers.Joiner {\n\t\t\tfinalRelDir := c.fs.Dir(chunk.finalRelPath)\n\t\t\tisFirst := true\n\t\t\tfor i, compileResult := range compileResults {\n\t\t\t\tif !compileResult.sourceIndex.IsValid() {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif isFirst {\n\t\t\t\t\tisFirst = false\n\t\t\t\t} else {\n\t\t\t\t\tjMeta.AddString(\",\")\n\t\t\t\t}\n\t\t\t\tjMeta.AddString(fmt.Sprintf(\n\t\t\t\t\tc.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n        %s: {\\n          \\\"bytesInOutput\\\": %d\\n        }\"),\n\t\t\t\t\thelpers.QuoteForJSON(c.graph.Files[compileResult.sourceIndex.GetIndex()].InputFile.Source.PrettyPaths.Select(c.options.MetafilePathStyle), c.options.ASCIIOnly),\n\t\t\t\t\tc.accurateFinalByteCount(pieces[i], finalRelDir)))\n\t\t\t}\n\t\t\tif len(compileResults) > 0 {\n\t\t\t\tjMeta.AddString(c.options.MetafileFormat.MaybeRemoveWhitespace(\"\\n      \"))\n\t\t\t}\n\t\t\tjMeta.AddString(fmt.Sprintf(c.options.MetafileFormat.MaybeRemoveWhitespace(\"},\\n      \\\"bytes\\\": %d\\n    }\"), finalOutputSize))\n\t\t\treturn jMeta\n\t\t}\n\t}\n\n\tc.generateIsolatedHashInParallel(chunk)\n\tchunkWaitGroup.Done()\n}\n\nfunc wrapRulesWithConditions(\n\trules []css_ast.Rule, importRecords []ast.ImportRecord,\n\tconditions []css_ast.ImportConditions, conditionImportRecords []ast.ImportRecord,\n) ([]css_ast.Rule, []ast.ImportRecord) {\n\tfor i := len(conditions) - 1; i >= 0; i-- {\n\t\titem := conditions[i]\n\n\t\t// Generate \"@layer\" wrappers. Note that empty \"@layer\" rules still have\n\t\t// a side effect (they set the layer order) so they cannot be removed.\n\t\tfor _, t := range item.Layers {\n\t\t\tif len(rules) == 0 {\n\t\t\t\tif t.Children == nil {\n\t\t\t\t\t// Omit an empty \"@layer {}\" entirely\n\t\t\t\t\tcontinue\n\t\t\t\t} else {\n\t\t\t\t\t// Generate \"@layer foo;\" instead of \"@layer foo {}\"\n\t\t\t\t\trules = nil\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar prelude []css_ast.Token\n\t\t\tif t.Children != nil {\n\t\t\t\tprelude = *t.Children\n\t\t\t}\n\t\t\tprelude, importRecords = css_ast.CloneTokensWithImportRecords(prelude, conditionImportRecords, nil, importRecords)\n\t\t\trules = []css_ast.Rule{{Data: &css_ast.RKnownAt{\n\t\t\t\tAtToken: \"layer\",\n\t\t\t\tPrelude: prelude,\n\t\t\t\tRules:   rules,\n\t\t\t}}}\n\t\t}\n\n\t\t// Generate \"@supports\" wrappers. This is not done if the rule block is\n\t\t// empty because empty \"@supports\" rules have no effect.\n\t\tif len(rules) > 0 {\n\t\t\tfor _, t := range item.Supports {\n\t\t\t\tt.Kind = css_lexer.TOpenParen\n\t\t\t\tt.Text = \"(\"\n\t\t\t\tvar prelude []css_ast.Token\n\t\t\t\tprelude, importRecords = css_ast.CloneTokensWithImportRecords([]css_ast.Token{t}, conditionImportRecords, nil, importRecords)\n\t\t\t\trules = []css_ast.Rule{{Data: &css_ast.RKnownAt{\n\t\t\t\t\tAtToken: \"supports\",\n\t\t\t\t\tPrelude: prelude,\n\t\t\t\t\tRules:   rules,\n\t\t\t\t}}}\n\t\t\t}\n\t\t}\n\n\t\t// Generate \"@media\" wrappers. This is not done if the rule block is\n\t\t// empty because empty \"@media\" rules have no effect.\n\t\tif len(rules) > 0 && len(item.Queries) > 0 {\n\t\t\tvar queries []css_ast.MediaQuery\n\t\t\tqueries, importRecords = css_ast.CloneMediaQueriesWithImportRecords(item.Queries, conditionImportRecords, nil, importRecords)\n\t\t\trules = []css_ast.Rule{{Data: &css_ast.RAtMedia{\n\t\t\t\tQueries: queries,\n\t\t\t\tRules:   rules,\n\t\t\t}}}\n\t\t}\n\t}\n\n\treturn rules, importRecords\n}\n\ntype legalCommentEntry struct {\n\tsourceIndex uint32\n\tcomments    []string\n}\n\n// Add all unique legal comments to the end of the file. These are\n// deduplicated because some projects have thousands of files with the same\n// comment. The comment must be preserved in the output for legal reasons but\n// at the same time we want to generate a small bundle when minifying.\nfunc (c *linkerContext) maybeAppendLegalComments(\n\tlegalComments config.LegalComments,\n\tlegalCommentList []legalCommentEntry,\n\tchunk *chunkInfo,\n\tj *helpers.Joiner,\n\tslashTag string,\n) {\n\tswitch legalComments {\n\tcase config.LegalCommentsNone, config.LegalCommentsInline:\n\t\treturn\n\t}\n\n\ttype thirdPartyEntry struct {\n\t\tpackagePaths []string\n\t\tcomments     []string\n\t}\n\n\tvar uniqueFirstPartyComments []string\n\tvar thirdPartyComments []thirdPartyEntry\n\thasFirstPartyComment := make(map[string]struct{})\n\n\tfor _, entry := range legalCommentList {\n\t\tsource := c.graph.Files[entry.sourceIndex].InputFile.Source\n\t\tpackagePath := \"\"\n\n\t\t// Try to extract a package name from the source path. If we can find a\n\t\t// \"node_modules\" path component in the path, then assume this is a legal\n\t\t// comment in third-party code and that everything after \"node_modules\" is\n\t\t// the package name and subpath. If we can't, then assume this is a legal\n\t\t// comment in first-party code.\n\t\t//\n\t\t// The rationale for this behavior: If we just include third-party comments\n\t\t// as-is and the third-party comments don't say what package they're from\n\t\t// (which isn't uncommon), then it'll look like that comment applies to\n\t\t// all code in the file which is very wrong. So we need to somehow say\n\t\t// where the comment comes from. But we don't want to say where every\n\t\t// comment comes from because people probably won't appreciate this for\n\t\t// first-party comments. And we don't want to include the whole path to\n\t\t// each third-part module because a) that could contain information about\n\t\t// the local machine that people don't want in their bundle and b) that\n\t\t// could differ depending on unimportant details like the package manager\n\t\t// used to install the packages (npm vs. pnpm vs. yarn).\n\t\tif source.KeyPath.Namespace != \"dataurl\" {\n\t\t\tpath := source.KeyPath.Text\n\t\t\tprevious := len(path)\n\t\t\tfor previous > 0 {\n\t\t\t\tslash := strings.LastIndexAny(path[:previous], \"\\\\/\")\n\t\t\t\tcomponent := path[slash+1 : previous]\n\t\t\t\tif component == \"node_modules\" {\n\t\t\t\t\tif previous < len(path) {\n\t\t\t\t\t\tpackagePath = strings.ReplaceAll(path[previous+1:], \"\\\\\", \"/\")\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tprevious = slash\n\t\t\t}\n\t\t}\n\n\t\tif packagePath != \"\" {\n\t\t\tthirdPartyComments = append(thirdPartyComments, thirdPartyEntry{\n\t\t\t\tpackagePaths: []string{packagePath},\n\t\t\t\tcomments:     entry.comments,\n\t\t\t})\n\t\t} else {\n\t\t\tfor _, comment := range entry.comments {\n\t\t\t\tif _, ok := hasFirstPartyComment[comment]; !ok {\n\t\t\t\t\thasFirstPartyComment[comment] = struct{}{}\n\t\t\t\t\tuniqueFirstPartyComments = append(uniqueFirstPartyComments, comment)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Merge package paths with identical comments\n\tidentical := make(map[string]int)\n\tend := 0\n\tfor _, entry := range thirdPartyComments {\n\t\tkey := strings.Join(entry.comments, \"\\x00\")\n\t\tif index, ok := identical[key]; ok {\n\t\t\texisting := &thirdPartyComments[index]\n\t\t\texisting.packagePaths = append(existing.packagePaths, entry.packagePaths...)\n\t\t} else {\n\t\t\tidentical[key] = end\n\t\t\tthirdPartyComments[end] = entry\n\t\t\tend++\n\t\t}\n\t}\n\tthirdPartyComments = thirdPartyComments[:end]\n\n\tswitch legalComments {\n\tcase config.LegalCommentsEndOfFile:\n\t\tfor _, comment := range uniqueFirstPartyComments {\n\t\t\tj.AddString(helpers.EscapeClosingTag(comment, slashTag))\n\t\t\tj.AddString(\"\\n\")\n\t\t}\n\n\t\tif len(thirdPartyComments) > 0 {\n\t\t\tj.AddString(\"/*! Bundled license information:\\n\")\n\t\t\tfor _, entry := range thirdPartyComments {\n\t\t\t\tj.AddString(\"\\n\")\n\t\t\t\tfor _, packagePath := range entry.packagePaths {\n\t\t\t\t\tj.AddString(fmt.Sprintf(\"%s:\\n\", helpers.EscapeClosingTag(packagePath, slashTag)))\n\t\t\t\t}\n\t\t\t\tfor _, comment := range entry.comments {\n\t\t\t\t\tcomment = helpers.EscapeClosingTag(comment, slashTag)\n\t\t\t\t\tif strings.HasPrefix(comment, \"//\") {\n\t\t\t\t\t\tj.AddString(fmt.Sprintf(\"  (*%s *)\\n\", comment[2:]))\n\t\t\t\t\t} else if strings.HasPrefix(comment, \"/*\") && strings.HasSuffix(comment, \"*/\") {\n\t\t\t\t\t\tj.AddString(fmt.Sprintf(\"  (%s)\\n\", strings.ReplaceAll(comment[1:len(comment)-1], \"\\n\", \"\\n  \")))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tj.AddString(\"*/\\n\")\n\t\t}\n\n\tcase config.LegalCommentsLinkedWithComment, config.LegalCommentsExternalWithoutComment:\n\t\tvar jComments helpers.Joiner\n\n\t\tfor _, comment := range uniqueFirstPartyComments {\n\t\t\tjComments.AddString(comment)\n\t\t\tjComments.AddString(\"\\n\")\n\t\t}\n\n\t\tif len(thirdPartyComments) > 0 {\n\t\t\tif len(uniqueFirstPartyComments) > 0 {\n\t\t\t\tjComments.AddString(\"\\n\")\n\t\t\t}\n\t\t\tjComments.AddString(\"Bundled license information:\\n\")\n\t\t\tfor _, entry := range thirdPartyComments {\n\t\t\t\tjComments.AddString(\"\\n\")\n\t\t\t\tfor _, packagePath := range entry.packagePaths {\n\t\t\t\t\tjComments.AddString(fmt.Sprintf(\"%s:\\n\", packagePath))\n\t\t\t\t}\n\t\t\t\tfor _, comment := range entry.comments {\n\t\t\t\t\tjComments.AddString(fmt.Sprintf(\"  %s\\n\", strings.ReplaceAll(comment, \"\\n\", \"\\n  \")))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tchunk.externalLegalComments = jComments.Done()\n\t}\n}\n\nfunc (c *linkerContext) appendIsolatedHashesForImportedChunks(\n\thash hash.Hash,\n\tchunkIndex uint32,\n\tvisited []uint32,\n\tvisitedKey uint32,\n) {\n\t// Only visit each chunk at most once. This is important because there may be\n\t// cycles in the chunk import graph. If there's a cycle, we want to include\n\t// the hash of every chunk involved in the cycle (along with all of their\n\t// dependencies). This depth-first traversal will naturally do that.\n\tif visited[chunkIndex] == visitedKey {\n\t\treturn\n\t}\n\tvisited[chunkIndex] = visitedKey\n\tchunk := &c.chunks[chunkIndex]\n\n\t// Visit the other chunks that this chunk imports before visiting this chunk\n\tfor _, chunkImport := range chunk.crossChunkImports {\n\t\tc.appendIsolatedHashesForImportedChunks(hash, chunkImport.chunkIndex, visited, visitedKey)\n\t}\n\n\t// Mix in hashes for referenced asset paths (i.e. the \"file\" loader)\n\tfor _, piece := range chunk.intermediateOutput.pieces {\n\t\tif piece.kind == outputPieceAssetIndex {\n\t\t\tfile := c.graph.Files[piece.index]\n\t\t\tif len(file.InputFile.AdditionalFiles) != 1 {\n\t\t\t\tpanic(\"Internal error\")\n\t\t\t}\n\t\t\trelPath, _ := c.fs.Rel(c.options.AbsOutputDir, file.InputFile.AdditionalFiles[0].AbsPath)\n\n\t\t\t// Make sure to always use forward slashes, even on Windows\n\t\t\trelPath = strings.ReplaceAll(relPath, \"\\\\\", \"/\")\n\n\t\t\t// Mix in the hash for the relative path, which ends up as a JS string\n\t\t\thashWriteLengthPrefixed(hash, []byte(relPath))\n\t\t}\n\t}\n\n\t// Mix in the hash for this chunk\n\thash.Write(chunk.waitForIsolatedHash())\n}\n\nfunc (c *linkerContext) breakJoinerIntoPieces(j helpers.Joiner) intermediateOutput {\n\t// Optimization: If there can be no substitutions, just reuse the initial\n\t// joiner that was used when generating the intermediate chunk output\n\t// instead of creating another one and copying the whole file into it.\n\tif !j.Contains(c.uniqueKeyPrefix, c.uniqueKeyPrefixBytes) {\n\t\treturn intermediateOutput{joiner: j}\n\t}\n\treturn c.breakOutputIntoPieces(j.Done())\n}\n\nfunc (c *linkerContext) breakOutputIntoPieces(output []byte) intermediateOutput {\n\tvar pieces []outputPiece\n\tprefix := c.uniqueKeyPrefixBytes\n\tfor {\n\t\t// Scan for the next piece boundary\n\t\tboundary := bytes.Index(output, prefix)\n\n\t\t// Try to parse the piece boundary\n\t\tvar kind outputPieceIndexKind\n\t\tvar index uint32\n\t\tif boundary != -1 {\n\t\t\tif start := boundary + len(prefix); start+9 > len(output) {\n\t\t\t\tboundary = -1\n\t\t\t} else {\n\t\t\t\tswitch output[start] {\n\t\t\t\tcase 'A':\n\t\t\t\t\tkind = outputPieceAssetIndex\n\t\t\t\tcase 'C':\n\t\t\t\t\tkind = outputPieceChunkIndex\n\t\t\t\t}\n\t\t\t\tfor j := 1; j < 9; j++ {\n\t\t\t\t\tc := output[start+j]\n\t\t\t\t\tif c < '0' || c > '9' {\n\t\t\t\t\t\tboundary = -1\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tindex = index*10 + uint32(c) - '0'\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Validate the boundary\n\t\tswitch kind {\n\t\tcase outputPieceAssetIndex:\n\t\t\tif index >= uint32(len(c.graph.Files)) {\n\t\t\t\tboundary = -1\n\t\t\t}\n\n\t\tcase outputPieceChunkIndex:\n\t\t\tif index >= uint32(len(c.chunks)) {\n\t\t\t\tboundary = -1\n\t\t\t}\n\n\t\tdefault:\n\t\t\tboundary = -1\n\t\t}\n\n\t\t// If we're at the end, generate one final piece\n\t\tif boundary == -1 {\n\t\t\tpieces = append(pieces, outputPiece{\n\t\t\t\tdata: output,\n\t\t\t})\n\t\t\tbreak\n\t\t}\n\n\t\t// Otherwise, generate an interior piece and continue\n\t\tpieces = append(pieces, outputPiece{\n\t\t\tdata:  output[:boundary],\n\t\t\tindex: index,\n\t\t\tkind:  kind,\n\t\t})\n\t\toutput = output[boundary+len(prefix)+9:]\n\t}\n\treturn intermediateOutput{pieces: pieces}\n}\n\nfunc (c *linkerContext) generateIsolatedHashInParallel(chunk *chunkInfo) {\n\t// Compute the hash in parallel. This is a speedup when it turns out the hash\n\t// isn't needed (well, as long as there are threads to spare).\n\tchannel := make(chan []byte, 1)\n\tchunk.waitForIsolatedHash = func() []byte {\n\t\tdata := <-channel\n\t\tchannel <- data\n\t\treturn data\n\t}\n\tgo c.generateIsolatedHash(chunk, channel)\n}\n\nfunc (c *linkerContext) generateIsolatedHash(chunk *chunkInfo, channel chan []byte) {\n\thash := xxhash.New()\n\n\t// Mix the file names and part ranges of all of the files in this chunk into\n\t// the hash. Objects that appear identical but that live in separate files or\n\t// that live in separate parts in the same file must not be merged. This only\n\t// needs to be done for JavaScript files, not CSS files.\n\tif chunkRepr, ok := chunk.chunkRepr.(*chunkReprJS); ok {\n\t\tfor _, partRange := range chunkRepr.partsInChunkInOrder {\n\t\t\tvar filePath string\n\t\t\tfile := &c.graph.Files[partRange.sourceIndex]\n\t\t\tif file.InputFile.Source.KeyPath.Namespace == \"file\" {\n\t\t\t\t// Use the pretty path as the file name since it should be platform-\n\t\t\t\t// independent (relative paths and the \"/\" path separator)\n\t\t\t\tfilePath = file.InputFile.Source.PrettyPaths.Rel\n\t\t\t} else {\n\t\t\t\t// If this isn't in the \"file\" namespace, just use the full path text\n\t\t\t\t// verbatim. This could be a source of cross-platform differences if\n\t\t\t\t// plugins are storing platform-specific information in here, but then\n\t\t\t\t// that problem isn't caused by esbuild itself.\n\t\t\t\tfilePath = file.InputFile.Source.KeyPath.Text\n\t\t\t}\n\n\t\t\t// Include the path namespace in the hash\n\t\t\thashWriteLengthPrefixed(hash, []byte(file.InputFile.Source.KeyPath.Namespace))\n\n\t\t\t// Then include the file path\n\t\t\thashWriteLengthPrefixed(hash, []byte(filePath))\n\n\t\t\t// Also write the part range. These numbers are deterministic and allocated\n\t\t\t// per-file so this should be a well-behaved base for a hash.\n\t\t\thashWriteUint32(hash, partRange.partIndexBegin)\n\t\t\thashWriteUint32(hash, partRange.partIndexEnd)\n\t\t}\n\t}\n\n\t// Hash the output path template as part of the content hash because we want\n\t// any import to be considered different if the import's output path has changed.\n\tfor _, part := range chunk.finalTemplate {\n\t\thashWriteLengthPrefixed(hash, []byte(part.Data))\n\t}\n\n\t// Also hash the public path. If provided, this is used whenever files\n\t// reference each other such as cross-chunk imports, asset file references,\n\t// and source map comments. We always include the hash in all chunks instead\n\t// of trying to figure out which chunks will include the public path for\n\t// simplicity and for robustness to code changes in the future.\n\tif c.options.PublicPath != \"\" {\n\t\thashWriteLengthPrefixed(hash, []byte(c.options.PublicPath))\n\t}\n\n\t// Include the generated output content in the hash. This excludes the\n\t// randomly-generated import paths (the unique keys) and only includes the\n\t// data in the spans between them.\n\tif chunk.intermediateOutput.pieces != nil {\n\t\tfor _, piece := range chunk.intermediateOutput.pieces {\n\t\t\thashWriteLengthPrefixed(hash, piece.data)\n\t\t}\n\t} else {\n\t\tbytes := chunk.intermediateOutput.joiner.Done()\n\t\thashWriteLengthPrefixed(hash, bytes)\n\t}\n\n\t// Also include the source map data in the hash. The source map is named the\n\t// same name as the chunk name for ease of discovery. So we want the hash to\n\t// change if the source map data changes even if the chunk data doesn't change.\n\t// Otherwise the output path for the source map wouldn't change and the source\n\t// map wouldn't end up being updated.\n\t//\n\t// Note that this means the contents of all input files are included in the\n\t// hash because of \"sourcesContent\", so changing a comment in an input file\n\t// can now change the hash of the output file. This only happens when you\n\t// have source maps enabled (and \"sourcesContent\", which is on by default).\n\t//\n\t// The generated positions in the mappings here are in the output content\n\t// *before* the final paths have been substituted. This may seem weird.\n\t// However, I think this shouldn't cause issues because a) the unique key\n\t// values are all always the same length so the offsets are deterministic\n\t// and b) the final paths will be folded into the final hash later.\n\thashWriteLengthPrefixed(hash, chunk.outputSourceMap.Prefix)\n\thashWriteLengthPrefixed(hash, chunk.outputSourceMap.Mappings)\n\thashWriteLengthPrefixed(hash, chunk.outputSourceMap.Suffix)\n\n\t// Store the hash so far. All other chunks that import this chunk will mix\n\t// this hash into their final hash to ensure that the import path changes\n\t// if this chunk (or any dependencies of this chunk) is changed.\n\tchannel <- hash.Sum(nil)\n}\n\nfunc hashWriteUint32(hash hash.Hash, value uint32) {\n\tvar lengthBytes [4]byte\n\tbinary.LittleEndian.PutUint32(lengthBytes[:], value)\n\thash.Write(lengthBytes[:])\n}\n\n// Hash the data in length-prefixed form because boundary locations are\n// important. We don't want \"a\" + \"bc\" to hash the same as \"ab\" + \"c\".\nfunc hashWriteLengthPrefixed(hash hash.Hash, bytes []byte) {\n\thashWriteUint32(hash, uint32(len(bytes)))\n\thash.Write(bytes)\n}\n\n// Marking a symbol as unbound prevents it from being renamed or minified.\n// This is only used when a module is compiled independently. We use a very\n// different way of handling exports and renaming/minifying when bundling.\nfunc (c *linkerContext) preventExportsFromBeingRenamed(sourceIndex uint32) {\n\trepr, ok := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.JSRepr)\n\tif !ok {\n\t\treturn\n\t}\n\thasImportOrExport := false\n\n\tfor _, part := range repr.AST.Parts {\n\t\tfor _, stmt := range part.Stmts {\n\t\t\tswitch s := stmt.Data.(type) {\n\t\t\tcase *js_ast.SImport:\n\t\t\t\t// Ignore imports from internal (i.e. non-external) code. Since this\n\t\t\t\t// function is only called when we're not bundling, these imports are\n\t\t\t\t// all for files that were generated automatically and aren't part of\n\t\t\t\t// the original source code (e.g. the runtime or an injected file).\n\t\t\t\t// We shouldn't consider the file a module if the only ESM imports or\n\t\t\t\t// exports are automatically generated ones.\n\t\t\t\tif repr.AST.ImportRecords[s.ImportRecordIndex].SourceIndex.IsValid() {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\thasImportOrExport = true\n\n\t\t\tcase *js_ast.SLocal:\n\t\t\t\tif s.IsExport {\n\t\t\t\t\tjs_ast.ForEachIdentifierBindingInDecls(s.Decls, func(loc logger.Loc, b *js_ast.BIdentifier) {\n\t\t\t\t\t\tc.graph.Symbols.Get(b.Ref).Flags |= ast.MustNotBeRenamed\n\t\t\t\t\t})\n\t\t\t\t\thasImportOrExport = true\n\t\t\t\t}\n\n\t\t\tcase *js_ast.SFunction:\n\t\t\t\tif s.IsExport {\n\t\t\t\t\tc.graph.Symbols.Get(s.Fn.Name.Ref).Kind = ast.SymbolUnbound\n\t\t\t\t\thasImportOrExport = true\n\t\t\t\t}\n\n\t\t\tcase *js_ast.SClass:\n\t\t\t\tif s.IsExport {\n\t\t\t\t\tc.graph.Symbols.Get(s.Class.Name.Ref).Kind = ast.SymbolUnbound\n\t\t\t\t\thasImportOrExport = true\n\t\t\t\t}\n\n\t\t\tcase *js_ast.SExportClause, *js_ast.SExportDefault, *js_ast.SExportStar:\n\t\t\t\thasImportOrExport = true\n\n\t\t\tcase *js_ast.SExportFrom:\n\t\t\t\thasImportOrExport = true\n\t\t\t}\n\t\t}\n\t}\n\n\t// Heuristic: If this module has top-level import or export statements, we\n\t// consider this an ES6 module and only preserve the names of the exported\n\t// symbols. Everything else is minified since the names are private.\n\t//\n\t// Otherwise, we consider this potentially a script-type file instead of an\n\t// ES6 module. In that case, preserve the names of all top-level symbols\n\t// since they are all potentially exported (e.g. if this is used in a\n\t// <script> tag). All symbols in nested scopes are still minified.\n\tif !hasImportOrExport {\n\t\tfor _, member := range repr.AST.ModuleScope.Members {\n\t\t\tc.graph.Symbols.Get(member.Ref).Flags |= ast.MustNotBeRenamed\n\t\t}\n\t}\n}\n\ntype compileResultForSourceMap struct {\n\tsourceMapChunk  sourcemap.Chunk\n\tgeneratedOffset sourcemap.LineColumnOffset\n\tsourceIndex     uint32\n\tisNullEntry     bool\n}\n\nfunc (c *linkerContext) generateSourceMapForChunk(\n\tresults []compileResultForSourceMap,\n\tchunkAbsDir string,\n\tdataForSourceMaps []bundler.DataForSourceMap,\n\tcanHaveShifts bool,\n) (pieces sourcemap.SourceMapPieces) {\n\tj := helpers.Joiner{}\n\tj.AddString(\"{\\n  \\\"version\\\": 3\")\n\n\t// Only write out the sources for a given source index once\n\tsourceIndexToSourcesIndex := make(map[uint32]int)\n\n\t// Generate the \"sources\" and \"sourcesContent\" arrays\n\ttype item struct {\n\t\tsource         string\n\t\tquotedContents []byte\n\t}\n\titems := make([]item, 0, len(results))\n\tnextSourcesIndex := 0\n\tfor _, result := range results {\n\t\tif result.isNullEntry {\n\t\t\tcontinue\n\t\t}\n\t\tif _, ok := sourceIndexToSourcesIndex[result.sourceIndex]; ok {\n\t\t\tcontinue\n\t\t}\n\t\tsourceIndexToSourcesIndex[result.sourceIndex] = nextSourcesIndex\n\t\tfile := &c.graph.Files[result.sourceIndex]\n\n\t\t// Simple case: no nested source map\n\t\tif file.InputFile.InputSourceMap == nil {\n\t\t\tvar quotedContents []byte\n\t\t\tif !c.options.ExcludeSourcesContent {\n\t\t\t\tquotedContents = dataForSourceMaps[result.sourceIndex].QuotedContents[0]\n\t\t\t}\n\t\t\tsource := file.InputFile.Source.KeyPath.Text\n\t\t\tif file.InputFile.Source.KeyPath.Namespace == \"file\" {\n\t\t\t\t// Serialize the file path as a \"file://\" URL, since source maps encode\n\t\t\t\t// sources as URLs. While we could output absolute \"file://\" URLs, it\n\t\t\t\t// will be turned into a relative path when it's written out below for\n\t\t\t\t// better readability and to be independent of build directory.\n\t\t\t\tsource = helpers.FileURLFromFilePath(source).String()\n\t\t\t} else {\n\t\t\t\t// If the path for this file isn't in the \"file\" namespace, then write\n\t\t\t\t// out something arbitrary instead. Source maps encode sources as URLs\n\t\t\t\t// but plugins are allowed to put almost anything in the \"namespace\"\n\t\t\t\t// and \"path\" fields, so we don't attempt to control whether this forms\n\t\t\t\t// a valid URL or not.\n\t\t\t\t//\n\t\t\t\t// The approach used here is to join the namespace with the path text\n\t\t\t\t// using a \":\" character. It's important to include the namespace\n\t\t\t\t// because esbuild considers paths with different namespaces to have\n\t\t\t\t// separate identities. And using a \":\" means that the path is more\n\t\t\t\t// likely to form a valid URL in the source map.\n\t\t\t\t//\n\t\t\t\t// For example, you could imagine a plugin that uses the \"https\"\n\t\t\t\t// namespace and path text like \"//example.com/foo.js\", which would\n\t\t\t\t// then be joined into the URL \"https://example.com/foo.js\" here.\n\t\t\t\t//\n\t\t\t\t// Note that this logic is currently mostly the same as the pretty-\n\t\t\t\t// printed paths that esbuild shows to humans in error messages.\n\t\t\t\t// However, this code has been forked below as these source map URLs\n\t\t\t\t// are intended for code instead of humans, and we don't want the\n\t\t\t\t// changes for humans to unintentionally break code that uses them.\n\t\t\t\t//\n\t\t\t\t// See https://github.com/evanw/esbuild/issues/4078 for more info.\n\t\t\t\tif ns := file.InputFile.Source.KeyPath.Namespace; ns != \"\" {\n\t\t\t\t\tsource = fmt.Sprintf(\"%s:%s\", ns, source)\n\t\t\t\t}\n\t\t\t\tsource += file.InputFile.Source.KeyPath.IgnoredSuffix\n\t\t\t}\n\t\t\titems = append(items, item{\n\t\t\t\tsource:         source,\n\t\t\t\tquotedContents: quotedContents,\n\t\t\t})\n\t\t\tnextSourcesIndex++\n\t\t\tcontinue\n\t\t}\n\n\t\t// Complex case: nested source map\n\t\tsm := file.InputFile.InputSourceMap\n\t\tfor i, source := range sm.Sources {\n\t\t\tvar quotedContents []byte\n\t\t\tif !c.options.ExcludeSourcesContent {\n\t\t\t\tquotedContents = dataForSourceMaps[result.sourceIndex].QuotedContents[i]\n\t\t\t}\n\t\t\titems = append(items, item{\n\t\t\t\tsource:         source,\n\t\t\t\tquotedContents: quotedContents,\n\t\t\t})\n\t\t}\n\t\tnextSourcesIndex += len(sm.Sources)\n\t}\n\n\t// Write the sources\n\tj.AddString(\",\\n  \\\"sources\\\": [\")\n\tfor i, item := range items {\n\t\tif i != 0 {\n\t\t\tj.AddString(\", \")\n\t\t}\n\n\t\t// Modify the absolute path to the original file to be relative to the\n\t\t// directory that will contain the output file for this chunk\n\t\tif sourceURL, err := url.Parse(item.source); err == nil && helpers.IsFileURL(sourceURL) {\n\t\t\tsourcePath := helpers.FilePathFromFileURL(c.fs, sourceURL)\n\t\t\tif relPath, ok := c.fs.Rel(chunkAbsDir, sourcePath); ok {\n\t\t\t\t// Make sure to always use forward slashes, even on Windows\n\t\t\t\trelativeURL := url.URL{Path: strings.ReplaceAll(relPath, \"\\\\\", \"/\")}\n\t\t\t\titem.source = relativeURL.String()\n\n\t\t\t\t// Replace certain percent encodings for better readability\n\t\t\t\titem.source = strings.ReplaceAll(item.source, \"%20\", \" \")\n\t\t\t}\n\t\t}\n\n\t\tj.AddBytes(helpers.QuoteForJSON(item.source, c.options.ASCIIOnly))\n\t}\n\tj.AddString(\"]\")\n\n\tif c.options.SourceRoot != \"\" {\n\t\tj.AddString(\",\\n  \\\"sourceRoot\\\": \")\n\t\tj.AddBytes(helpers.QuoteForJSON(c.options.SourceRoot, c.options.ASCIIOnly))\n\t}\n\n\t// Write the sourcesContent\n\tif !c.options.ExcludeSourcesContent {\n\t\tj.AddString(\",\\n  \\\"sourcesContent\\\": [\")\n\t\tfor i, item := range items {\n\t\t\tif i != 0 {\n\t\t\t\tj.AddString(\", \")\n\t\t\t}\n\t\t\tj.AddBytes(item.quotedContents)\n\t\t}\n\t\tj.AddString(\"]\")\n\t}\n\n\tj.AddString(\",\\n  \\\"mappings\\\": \\\"\")\n\n\t// Write the mappings\n\tmappingsStart := j.Length()\n\tprevEndState := sourcemap.SourceMapState{}\n\tprevColumnOffset := 0\n\ttotalQuotedNameLen := 0\n\tfor _, result := range results {\n\t\tchunk := result.sourceMapChunk\n\t\toffset := result.generatedOffset\n\t\tsourcesIndex, ok := sourceIndexToSourcesIndex[result.sourceIndex]\n\t\tif !ok {\n\t\t\t// If there's no sourcesIndex, then every mapping for this result's\n\t\t\t// sourceIndex were null mappings. We still need to emit the null\n\t\t\t// mapping, but its source index won't matter.\n\t\t\tsourcesIndex = 0\n\t\t\tif !result.isNullEntry {\n\t\t\t\tpanic(\"Internal error\")\n\t\t\t}\n\t\t}\n\n\t\t// This should have already been checked earlier\n\t\tif chunk.ShouldIgnore {\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\n\t\t// Because each file for the bundle is converted to a source map once,\n\t\t// the source maps are shared between all entry points in the bundle.\n\t\t// The easiest way of getting this to work is to have all source maps\n\t\t// generate as if their source index is 0. We then adjust the source\n\t\t// index per entry point by modifying the first source mapping. This\n\t\t// is done by AppendSourceMapChunk() using the source index passed\n\t\t// here.\n\t\tstartState := sourcemap.SourceMapState{\n\t\t\tSourceIndex:     sourcesIndex,\n\t\t\tGeneratedLine:   offset.Lines,\n\t\t\tGeneratedColumn: offset.Columns,\n\t\t\tOriginalName:    totalQuotedNameLen,\n\t\t}\n\t\tif offset.Lines == 0 {\n\t\t\tstartState.GeneratedColumn += prevColumnOffset\n\t\t}\n\n\t\tif result.isNullEntry {\n\t\t\t// Emit a \"null\" mapping\n\t\t\tchunk.Buffer.Data = []byte(\"A\")\n\t\t\tsourcemap.AppendSourceMapChunk(&j, prevEndState, startState, chunk.Buffer)\n\n\t\t\t// Only the generated position was advanced\n\t\t\tprevEndState.GeneratedLine = startState.GeneratedLine\n\t\t\tprevEndState.GeneratedColumn = startState.GeneratedColumn\n\t\t} else {\n\t\t\t// Append the precomputed source map chunk\n\t\t\tsourcemap.AppendSourceMapChunk(&j, prevEndState, startState, chunk.Buffer)\n\n\t\t\t// Generate the relative offset to start from next time\n\t\t\tprevOriginalName := prevEndState.OriginalName\n\t\t\tprevEndState = chunk.EndState\n\t\t\tprevEndState.SourceIndex += sourcesIndex\n\t\t\tif chunk.Buffer.FirstNameOffset.IsValid() {\n\t\t\t\tprevEndState.OriginalName += totalQuotedNameLen\n\t\t\t} else {\n\t\t\t\t// It's possible for a chunk to have mappings but for none of those\n\t\t\t\t// mappings to have an associated name. The name is optional and is\n\t\t\t\t// omitted when the mapping is for a non-name token or if the final\n\t\t\t\t// and original names are the same. In that case we need to restore\n\t\t\t\t// the previous original name end state since it wasn't modified after\n\t\t\t\t// all. If we don't do this, then files after this will adjust their\n\t\t\t\t// name offsets assuming that the previous generated mapping has this\n\t\t\t\t// file's offset, which is wrong.\n\t\t\t\tprevEndState.OriginalName = prevOriginalName\n\t\t\t}\n\t\t\tprevColumnOffset = chunk.FinalGeneratedColumn\n\t\t\ttotalQuotedNameLen += len(chunk.QuotedNames)\n\t\t}\n\n\t\t// If this was all one line, include the column offset from the start\n\t\tif prevEndState.GeneratedLine == 0 {\n\t\t\tprevEndState.GeneratedColumn += startState.GeneratedColumn\n\t\t\tprevColumnOffset += startState.GeneratedColumn\n\t\t}\n\t}\n\tmappingsEnd := j.Length()\n\n\t// Write the names\n\tisFirstName := true\n\tj.AddString(\"\\\",\\n  \\\"names\\\": [\")\n\tfor _, result := range results {\n\t\tfor _, quotedName := range result.sourceMapChunk.QuotedNames {\n\t\t\tif isFirstName {\n\t\t\t\tisFirstName = false\n\t\t\t} else {\n\t\t\t\tj.AddString(\", \")\n\t\t\t}\n\t\t\tj.AddBytes(quotedName)\n\t\t}\n\t}\n\tj.AddString(\"]\")\n\n\t// Finish the source map\n\tj.AddString(\"\\n}\\n\")\n\tbytes := j.Done()\n\n\tif !canHaveShifts {\n\t\t// If there cannot be any shifts, then we can avoid doing extra work later\n\t\t// on by preserving the source map as a single memory allocation throughout\n\t\t// the pipeline. That way we won't need to reallocate it.\n\t\tpieces.Prefix = bytes\n\t} else {\n\t\t// Otherwise if there can be shifts, then we need to split this into several\n\t\t// slices so that the shifts in the mappings array can be processed. This is\n\t\t// more expensive because everything will need to be recombined into a new\n\t\t// memory allocation at the end.\n\t\tpieces.Prefix = bytes[:mappingsStart]\n\t\tpieces.Mappings = bytes[mappingsStart:mappingsEnd]\n\t\tpieces.Suffix = bytes[mappingsEnd:]\n\t}\n\treturn\n}\n\n// Recover from a panic by logging it as an internal error instead of crashing\nfunc (c *linkerContext) recoverInternalError(waitGroup *sync.WaitGroup, sourceIndex uint32) {\n\tif r := recover(); r != nil {\n\t\ttext := fmt.Sprintf(\"panic: %v\", r)\n\t\tif sourceIndex != runtime.SourceIndex {\n\t\t\ttext = fmt.Sprintf(\"%s (while printing %q)\", text,\n\t\t\t\tc.graph.Files[sourceIndex].InputFile.Source.PrettyPaths.Select(c.options.LogPathStyle))\n\t\t}\n\t\tc.log.AddErrorWithNotes(nil, logger.Range{}, text,\n\t\t\t[]logger.MsgData{{Text: helpers.PrettyPrintedStack()}})\n\t\twaitGroup.Done()\n\t}\n}\n\nfunc joinWithPublicPath(publicPath string, relPath string) string {\n\tif strings.HasPrefix(relPath, \"./\") {\n\t\trelPath = relPath[2:]\n\n\t\t// Strip any amount of further no-op slashes (i.e. \".///././/x/y\" => \"x/y\")\n\t\tfor {\n\t\t\tif strings.HasPrefix(relPath, \"/\") {\n\t\t\t\trelPath = relPath[1:]\n\t\t\t} else if strings.HasPrefix(relPath, \"./\") {\n\t\t\t\trelPath = relPath[2:]\n\t\t\t} else {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\t// Use a relative path if there is no public path\n\tif publicPath == \"\" {\n\t\tpublicPath = \".\"\n\t}\n\n\t// Join with a slash\n\tslash := \"/\"\n\tif strings.HasSuffix(publicPath, \"/\") {\n\t\tslash = \"\"\n\t}\n\treturn fmt.Sprintf(\"%s%s%s\", publicPath, slash, relPath)\n}\n"
  },
  {
    "path": "internal/logger/logger.go",
    "content": "package logger\n\n// Logging is either done to stderr (via \"NewStderrLog\") or to an in-memory\n// array (via \"NewDeferLog\"). In-memory arrays are used to capture messages\n// from parsing individual files because during incremental builds, log\n// messages for a given file can be replayed from memory if the file ends up\n// not being reparsed.\n//\n// Errors are streamed asynchronously as they happen, each error contains the\n// contents of the line with the error, and the error count is limited by\n// default.\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\t\"unicode/utf8\"\n)\n\nconst defaultTerminalWidth = 80\n\ntype Log struct {\n\tAddMsg    func(Msg)\n\tHasErrors func() bool\n\tPeek      func() []Msg\n\n\tDone func() []Msg\n\n\tLevel     LogLevel\n\tOverrides map[MsgID]LogLevel\n}\n\ntype LogLevel int8\n\nconst (\n\tLevelNone LogLevel = iota\n\tLevelVerbose\n\tLevelDebug\n\tLevelInfo\n\tLevelWarning\n\tLevelError\n\tLevelSilent\n)\n\ntype MsgKind uint8\n\nconst (\n\tError MsgKind = iota\n\tWarning\n\tInfo\n\tNote\n\tDebug\n\tVerbose\n)\n\nfunc (kind MsgKind) String() string {\n\tswitch kind {\n\tcase Error:\n\t\treturn \"ERROR\"\n\tcase Warning:\n\t\treturn \"WARNING\"\n\tcase Info:\n\t\treturn \"INFO\"\n\tcase Note:\n\t\treturn \"NOTE\"\n\tcase Debug:\n\t\treturn \"DEBUG\"\n\tcase Verbose:\n\t\treturn \"VERBOSE\"\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\nfunc (kind MsgKind) Icon() string {\n\t// Special-case Windows command prompt, which only supports a few characters\n\tif isProbablyWindowsCommandPrompt() {\n\t\tswitch kind {\n\t\tcase Error:\n\t\t\treturn \"X\"\n\t\tcase Warning:\n\t\t\treturn \"▲\"\n\t\tcase Info:\n\t\t\treturn \"►\"\n\t\tcase Note:\n\t\t\treturn \"→\"\n\t\tcase Debug:\n\t\t\treturn \"●\"\n\t\tcase Verbose:\n\t\t\treturn \"♦\"\n\t\tdefault:\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\t}\n\n\tswitch kind {\n\tcase Error:\n\t\treturn \"✘\"\n\tcase Warning:\n\t\treturn \"▲\"\n\tcase Info:\n\t\treturn \"▶\"\n\tcase Note:\n\t\treturn \"→\"\n\tcase Debug:\n\t\treturn \"●\"\n\tcase Verbose:\n\t\treturn \"⬥\"\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\nvar windowsCommandPrompt struct {\n\tmutex         sync.Mutex\n\tonce          bool\n\tisProbablyCMD bool\n}\n\nfunc isProbablyWindowsCommandPrompt() bool {\n\twindowsCommandPrompt.mutex.Lock()\n\tdefer windowsCommandPrompt.mutex.Unlock()\n\n\tif !windowsCommandPrompt.once {\n\t\twindowsCommandPrompt.once = true\n\n\t\t// Assume we are running in Windows Command Prompt if we're on Windows. If\n\t\t// so, we can't use emoji because it won't be supported. Except we can\n\t\t// still use emoji if the WT_SESSION environment variable is present\n\t\t// because that means we're running in the new Windows Terminal instead.\n\t\tif runtime.GOOS == \"windows\" {\n\t\t\twindowsCommandPrompt.isProbablyCMD = true\n\t\t\tif _, ok := os.LookupEnv(\"WT_SESSION\"); ok {\n\t\t\t\twindowsCommandPrompt.isProbablyCMD = false\n\t\t\t}\n\t\t}\n\t}\n\n\treturn windowsCommandPrompt.isProbablyCMD\n}\n\ntype Msg struct {\n\tNotes      []MsgData\n\tPluginName string\n\tData       MsgData\n\tKind       MsgKind\n\tID         MsgID\n}\n\ntype MsgData struct {\n\t// Optional user-specified data that is passed through unmodified\n\tUserDetail interface{}\n\n\tLocation *MsgLocation\n\tText     string\n\n\tDisableMaximumWidth bool\n}\n\ntype MsgLocation struct {\n\tFile       PrettyPaths\n\tNamespace  string\n\tLineText   string\n\tSuggestion string\n\tLine       int // 1-based\n\tColumn     int // 0-based, in bytes\n\tLength     int // in bytes\n}\n\ntype Loc struct {\n\t// This is the 0-based index of this location from the start of the file, in bytes\n\tStart int32\n}\n\ntype Range struct {\n\tLoc Loc\n\tLen int32\n}\n\nfunc (r Range) End() int32 {\n\treturn r.Loc.Start + r.Len\n}\n\nfunc (a *Range) ExpandBy(b Range) {\n\tif a.Len == 0 {\n\t\t*a = b\n\t} else {\n\t\tend := a.End()\n\t\tif n := b.End(); n > end {\n\t\t\tend = n\n\t\t}\n\t\tif b.Loc.Start < a.Loc.Start {\n\t\t\ta.Loc.Start = b.Loc.Start\n\t\t}\n\t\ta.Len = end - a.Loc.Start\n\t}\n}\n\ntype Span struct {\n\tText  string\n\tRange Range\n}\n\n// This type is just so we can use Go's native sort function\ntype SortableMsgs []Msg\n\nfunc (a SortableMsgs) Len() int          { return len(a) }\nfunc (a SortableMsgs) Swap(i int, j int) { a[i], a[j] = a[j], a[i] }\n\nfunc (a SortableMsgs) Less(i int, j int) bool {\n\tai := a[i]\n\taj := a[j]\n\taiLoc := ai.Data.Location\n\tajLoc := aj.Data.Location\n\tif aiLoc == nil || ajLoc == nil {\n\t\treturn aiLoc == nil && ajLoc != nil\n\t}\n\tif aiLoc.File != ajLoc.File {\n\t\treturn aiLoc.File.Abs < ajLoc.File.Abs || (aiLoc.File.Abs == ajLoc.File.Abs && aiLoc.File.Rel < ajLoc.File.Rel)\n\t}\n\tif aiLoc.Line != ajLoc.Line {\n\t\treturn aiLoc.Line < ajLoc.Line\n\t}\n\tif aiLoc.Column != ajLoc.Column {\n\t\treturn aiLoc.Column < ajLoc.Column\n\t}\n\tif ai.Kind != aj.Kind {\n\t\treturn ai.Kind < aj.Kind\n\t}\n\treturn ai.Data.Text < aj.Data.Text\n}\n\n// This is used to represent both file system paths (Namespace == \"file\") and\n// abstract module paths (Namespace != \"file\"). Abstract module paths represent\n// \"virtual modules\" when used for an input file and \"package paths\" when used\n// to represent an external module.\ntype Path struct {\n\tText      string\n\tNamespace string\n\n\t// This feature was added to support ancient CSS libraries that append things\n\t// like \"?#iefix\" and \"#icons\" to some of their import paths as a hack for IE6.\n\t// The intent is for these suffix parts to be ignored but passed through to\n\t// the output. This is supported by other bundlers, so we also support this.\n\tIgnoredSuffix string\n\n\t// Import attributes (the \"with\" keyword after an import) can affect path\n\t// resolution. In other words, two paths in the same file that are otherwise\n\t// equal but that have different import attributes may resolve to different\n\t// paths.\n\tImportAttributes ImportAttributes\n\n\tFlags PathFlags\n}\n\n// We rely on paths as map keys. Go doesn't support custom hash codes and\n// only implements hash codes for certain types. In particular, hash codes\n// are implemented for strings but not for arrays of strings. So we have to\n// pack these import attributes into a string.\ntype ImportAttributes struct {\n\tpackedData string\n}\n\ntype ImportAttribute struct {\n\tKey   string\n\tValue string\n}\n\n// This returns a sorted array instead of a map to make determinism easier\nfunc (attrs ImportAttributes) DecodeIntoArray() (result []ImportAttribute) {\n\tif attrs.packedData == \"\" {\n\t\treturn nil\n\t}\n\tbytes := []byte(attrs.packedData)\n\tfor len(bytes) > 0 {\n\t\tkn := 4 + binary.LittleEndian.Uint32(bytes[:4])\n\t\tk := string(bytes[4:kn])\n\t\tbytes = bytes[kn:]\n\t\tvn := 4 + binary.LittleEndian.Uint32(bytes[:4])\n\t\tv := string(bytes[4:vn])\n\t\tbytes = bytes[vn:]\n\t\tresult = append(result, ImportAttribute{Key: k, Value: v})\n\t}\n\treturn result\n}\n\nfunc (attrs ImportAttributes) DecodeIntoMap() (result map[string]string) {\n\tif array := attrs.DecodeIntoArray(); len(array) > 0 {\n\t\tresult = make(map[string]string, len(array))\n\t\tfor _, attr := range array {\n\t\t\tresult[attr.Key] = attr.Value\n\t\t}\n\t}\n\treturn\n}\n\nfunc EncodeImportAttributes(value map[string]string) ImportAttributes {\n\tif len(value) == 0 {\n\t\treturn ImportAttributes{}\n\t}\n\tkeys := make([]string, 0, len(value))\n\tfor k := range value {\n\t\tkeys = append(keys, k)\n\t}\n\tsort.Strings(keys)\n\tvar sb strings.Builder\n\tvar n [4]byte\n\tfor _, k := range keys {\n\t\tv := value[k]\n\t\tbinary.LittleEndian.PutUint32(n[:], uint32(len(k)))\n\t\tsb.Write(n[:])\n\t\tsb.WriteString(k)\n\t\tbinary.LittleEndian.PutUint32(n[:], uint32(len(v)))\n\t\tsb.Write(n[:])\n\t\tsb.WriteString(v)\n\t}\n\treturn ImportAttributes{packedData: sb.String()}\n}\n\ntype PathFlags uint8\n\nconst (\n\t// This corresponds to a value of \"false' in the \"browser\" package.json field\n\tPathDisabled PathFlags = 1 << iota\n)\n\nfunc (p Path) IsDisabled() bool {\n\treturn (p.Flags & PathDisabled) != 0\n}\n\nvar noColorResult bool\nvar noColorOnce sync.Once\n\nfunc hasNoColorEnvironmentVariable() bool {\n\tnoColorOnce.Do(func() {\n\t\t// Read \"NO_COLOR\" from the environment. This is a convention that some\n\t\t// software follows. See https://no-color.org/ for more information.\n\t\tif _, ok := os.LookupEnv(\"NO_COLOR\"); ok {\n\t\t\tnoColorResult = true\n\t\t}\n\t})\n\treturn noColorResult\n}\n\n// This has a custom implementation instead of using \"filepath.Dir/Base/Ext\"\n// because it should work the same on Unix and Windows. These names end up in\n// the generated output and the generated output should not depend on the OS.\nfunc PlatformIndependentPathDirBaseExt(path string) (dir string, base string, ext string) {\n\tabsRootSlash := -1\n\n\t// Make sure we don't strip off the slash for the root of the file system\n\tif len(path) > 0 && (path[0] == '/' || path[0] == '\\\\') {\n\t\tabsRootSlash = 0 // Unix\n\t} else if len(path) > 2 && path[1] == ':' && (path[2] == '/' || path[2] == '\\\\') {\n\t\tif c := path[0]; (c >= 'a' && c < 'z') || (c >= 'A' && c <= 'Z') {\n\t\t\tabsRootSlash = 2 // Windows\n\t\t}\n\t}\n\n\tfor {\n\t\ti := strings.LastIndexAny(path, \"/\\\\\")\n\n\t\t// Stop if there are no more slashes\n\t\tif i < 0 {\n\t\t\tbase = path\n\t\t\tbreak\n\t\t}\n\n\t\t// Stop if we found a non-trailing slash\n\t\tif i == absRootSlash {\n\t\t\tdir, base = path[:i+1], path[i+1:]\n\t\t\tbreak\n\t\t}\n\t\tif i+1 != len(path) {\n\t\t\tdir, base = path[:i], path[i+1:]\n\t\t\tbreak\n\t\t}\n\n\t\t// Ignore trailing slashes\n\t\tpath = path[:i]\n\t}\n\n\t// Strip off the extension\n\tif dot := strings.LastIndexByte(base, '.'); dot >= 0 {\n\t\text = base[dot:]\n\n\t\t// We default to the \"local-css\" loader for \".module.css\" files. Make sure\n\t\t// the string names generated by this don't all have \"_module_\" in them.\n\t\tif ext == \".css\" {\n\t\t\tif dot2 := strings.LastIndexByte(base[:dot], '.'); dot2 >= 0 && base[dot2:] == \".module.css\" {\n\t\t\t\tdot = dot2\n\t\t\t\text = base[dot:]\n\t\t\t}\n\t\t}\n\n\t\tbase = base[:dot]\n\t}\n\treturn\n}\n\ntype PrettyPaths struct {\n\t// This option exists to help people that run esbuild in many different\n\t// directories and want a unified way of reporting file paths. It avoids\n\t// needing to code to convert from relative paths back to absolute paths\n\t// to find the original file. It means builds are not reproducible across\n\t// machines, however.\n\tAbs string\n\n\t// This is a mostly platform-independent path. It's relative to the current\n\t// working directory and always uses standard path separators. This is the\n\t// default behavior since it leads to reproducible builds across machines.\n\t//\n\t// Note that these paths still use the original case of the path, so they may\n\t// still work differently on file systems that are case-insensitive vs.\n\t// case-sensitive.\n\tRel string\n}\n\ntype PathStyle uint8\n\nconst (\n\tRelPath PathStyle = iota\n\tAbsPath\n)\n\nfunc (paths *PrettyPaths) Select(style PathStyle) string {\n\tif style == AbsPath {\n\t\treturn paths.Abs\n\t}\n\treturn paths.Rel\n}\n\ntype Source struct {\n\t// This is used for error messages and the metadata JSON file.\n\tPrettyPaths PrettyPaths\n\n\t// An identifier that is mixed in to automatically-generated symbol names to\n\t// improve readability. For example, if the identifier is \"util\" then the\n\t// symbol for an \"export default\" statement will be called \"util_default\".\n\tIdentifierName string\n\n\tContents string\n\n\t// This is used as a unique key to identify this source file. It should never\n\t// be shown to the user (e.g. never print this to the terminal).\n\t//\n\t// If it's marked as an absolute path, it's a platform-dependent path that\n\t// includes environment-specific things such as Windows backslash path\n\t// separators and potentially the user's home directory. Only use this for\n\t// passing to syscalls for reading and writing to the file system. Do not\n\t// include this in any output data.\n\t//\n\t// If it's marked as not an absolute path, it's an opaque string that is used\n\t// to refer to an automatically-generated module.\n\tKeyPath Path\n\n\tIndex uint32\n}\n\nfunc (s *Source) TextForRange(r Range) string {\n\treturn s.Contents[r.Loc.Start : r.Loc.Start+r.Len]\n}\n\nfunc (s *Source) LocBeforeWhitespace(loc Loc) Loc {\n\tfor loc.Start > 0 {\n\t\tc, width := utf8.DecodeLastRuneInString(s.Contents[:loc.Start])\n\t\tif c != ' ' && c != '\\t' && c != '\\r' && c != '\\n' {\n\t\t\tbreak\n\t\t}\n\t\tloc.Start -= int32(width)\n\t}\n\treturn loc\n}\n\nfunc (s *Source) RangeOfOperatorBefore(loc Loc, op string) Range {\n\ttext := s.Contents[:loc.Start]\n\tindex := strings.LastIndex(text, op)\n\tif index >= 0 {\n\t\treturn Range{Loc: Loc{Start: int32(index)}, Len: int32(len(op))}\n\t}\n\treturn Range{Loc: loc}\n}\n\nfunc (s *Source) RangeOfOperatorAfter(loc Loc, op string) Range {\n\ttext := s.Contents[loc.Start:]\n\tindex := strings.Index(text, op)\n\tif index >= 0 {\n\t\treturn Range{Loc: Loc{Start: loc.Start + int32(index)}, Len: int32(len(op))}\n\t}\n\treturn Range{Loc: loc}\n}\n\nfunc (s *Source) RangeOfString(loc Loc) Range {\n\ttext := s.Contents[loc.Start:]\n\tif len(text) == 0 {\n\t\treturn Range{Loc: loc, Len: 0}\n\t}\n\n\tquote := text[0]\n\tif quote == '\"' || quote == '\\'' {\n\t\t// Search for the matching quote character\n\t\tfor i := 1; i < len(text); i++ {\n\t\t\tc := text[i]\n\t\t\tif c == quote {\n\t\t\t\treturn Range{Loc: loc, Len: int32(i + 1)}\n\t\t\t} else if c == '\\\\' {\n\t\t\t\ti += 1\n\t\t\t}\n\t\t}\n\t}\n\n\tif quote == '`' {\n\t\t// Search for the matching quote character\n\t\tfor i := 1; i < len(text); i++ {\n\t\t\tc := text[i]\n\t\t\tif c == quote {\n\t\t\t\treturn Range{Loc: loc, Len: int32(i + 1)}\n\t\t\t} else if c == '\\\\' {\n\t\t\t\ti += 1\n\t\t\t} else if c == '$' && i+1 < len(text) && text[i+1] == '{' {\n\t\t\t\tbreak // Only return the range for no-substitution template literals\n\t\t\t}\n\t\t}\n\t}\n\n\treturn Range{Loc: loc, Len: 0}\n}\n\nfunc (s *Source) RangeOfNumber(loc Loc) (r Range) {\n\ttext := s.Contents[loc.Start:]\n\tr = Range{Loc: loc, Len: 0}\n\n\tif len(text) > 0 {\n\t\tif c := text[0]; c >= '0' && c <= '9' {\n\t\t\tr.Len = 1\n\t\t\tfor int(r.Len) < len(text) {\n\t\t\t\tc := text[r.Len]\n\t\t\t\tif (c < '0' || c > '9') && (c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && c != '.' && c != '_' {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tr.Len++\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\nfunc (s *Source) RangeOfLegacyOctalEscape(loc Loc) (r Range) {\n\ttext := s.Contents[loc.Start:]\n\tr = Range{Loc: loc, Len: 0}\n\n\tif len(text) >= 2 && text[0] == '\\\\' {\n\t\tr.Len = 2\n\t\tfor r.Len < 4 && int(r.Len) < len(text) {\n\t\t\tc := text[r.Len]\n\t\t\tif c < '0' || c > '9' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tr.Len++\n\t\t}\n\t}\n\treturn\n}\n\nfunc (s *Source) CommentTextWithoutIndent(r Range) string {\n\ttext := s.Contents[r.Loc.Start:r.End()]\n\tif len(text) < 2 || !strings.HasPrefix(text, \"/*\") {\n\t\treturn text\n\t}\n\tprefix := s.Contents[:r.Loc.Start]\n\n\t// Figure out the initial indent\n\tindent := 0\nseekBackwardToNewline:\n\tfor len(prefix) > 0 {\n\t\tc, size := utf8.DecodeLastRuneInString(prefix)\n\t\tswitch c {\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\tbreak seekBackwardToNewline\n\t\t}\n\t\tprefix = prefix[:len(prefix)-size]\n\t\tindent++\n\t}\n\n\t// Split the comment into lines\n\tvar lines []string\n\tstart := 0\n\tfor i, c := range text {\n\t\tswitch c {\n\t\tcase '\\r', '\\n':\n\t\t\t// Don't double-append for Windows style \"\\r\\n\" newlines\n\t\t\tif start <= i {\n\t\t\t\tlines = append(lines, text[start:i])\n\t\t\t}\n\n\t\t\tstart = i + 1\n\n\t\t\t// Ignore the second part of Windows style \"\\r\\n\" newlines\n\t\t\tif c == '\\r' && start < len(text) && text[start] == '\\n' {\n\t\t\t\tstart++\n\t\t\t}\n\n\t\tcase '\\u2028', '\\u2029':\n\t\t\tlines = append(lines, text[start:i])\n\t\t\tstart = i + 3\n\t\t}\n\t}\n\tlines = append(lines, text[start:])\n\n\t// Find the minimum indent over all lines after the first line\n\tfor _, line := range lines[1:] {\n\t\tlineIndent := 0\n\t\tfor _, c := range line {\n\t\t\tif c != ' ' && c != '\\t' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tlineIndent++\n\t\t}\n\t\tif indent > lineIndent {\n\t\t\tindent = lineIndent\n\t\t}\n\t}\n\n\t// Trim the indent off of all lines after the first line\n\tfor i, line := range lines {\n\t\tif i > 0 {\n\t\t\tlines[i] = line[indent:]\n\t\t}\n\t}\n\treturn strings.Join(lines, \"\\n\")\n}\n\nfunc plural(prefix string, count int, shown int, someAreMissing bool) string {\n\tvar text string\n\tif count == 1 {\n\t\ttext = fmt.Sprintf(\"%d %s\", count, prefix)\n\t} else {\n\t\ttext = fmt.Sprintf(\"%d %ss\", count, prefix)\n\t}\n\tif shown < count {\n\t\ttext = fmt.Sprintf(\"%d of %s\", shown, text)\n\t} else if someAreMissing && count > 1 {\n\t\ttext = \"all \" + text\n\t}\n\treturn text\n}\n\nfunc errorAndWarningSummary(errors int, warnings int, shownErrors int, shownWarnings int) string {\n\tsomeAreMissing := shownWarnings < warnings || shownErrors < errors\n\tswitch {\n\tcase errors == 0:\n\t\treturn plural(\"warning\", warnings, shownWarnings, someAreMissing)\n\tcase warnings == 0:\n\t\treturn plural(\"error\", errors, shownErrors, someAreMissing)\n\tdefault:\n\t\treturn fmt.Sprintf(\"%s and %s\",\n\t\t\tplural(\"warning\", warnings, shownWarnings, someAreMissing),\n\t\t\tplural(\"error\", errors, shownErrors, someAreMissing))\n\t}\n}\n\ntype APIKind uint8\n\nconst (\n\tGoAPI APIKind = iota\n\tCLIAPI\n\tJSAPI\n)\n\n// This can be used to customize error messages for the current API kind\nvar API APIKind\n\ntype TerminalInfo struct {\n\tIsTTY           bool\n\tUseColorEscapes bool\n\tWidth           int\n\tHeight          int\n}\n\nfunc NewStderrLog(options OutputOptions) Log {\n\tvar mutex sync.Mutex\n\tvar msgs SortableMsgs\n\tterminalInfo := GetTerminalInfo(os.Stderr)\n\terrors := 0\n\twarnings := 0\n\tshownErrors := 0\n\tshownWarnings := 0\n\thasErrors := false\n\tremainingMessagesBeforeLimit := options.MessageLimit\n\tif remainingMessagesBeforeLimit == 0 {\n\t\tremainingMessagesBeforeLimit = 0x7FFFFFFF\n\t}\n\tvar deferredWarnings []Msg\n\n\tfinalizeLog := func() {\n\t\t// Print the deferred warning now if there was no error after all\n\t\tfor remainingMessagesBeforeLimit > 0 && len(deferredWarnings) > 0 {\n\t\t\tshownWarnings++\n\t\t\twriteStringWithColor(os.Stderr, deferredWarnings[0].String(options, terminalInfo))\n\t\t\tdeferredWarnings = deferredWarnings[1:]\n\t\t\tremainingMessagesBeforeLimit--\n\t\t}\n\n\t\t// Print out a summary\n\t\tif options.MessageLimit > 0 && errors+warnings > options.MessageLimit {\n\t\t\twriteStringWithColor(os.Stderr, fmt.Sprintf(\"%s shown (disable the message limit with --log-limit=0)\\n\",\n\t\t\t\terrorAndWarningSummary(errors, warnings, shownErrors, shownWarnings)))\n\t\t} else if options.LogLevel <= LevelInfo && (warnings != 0 || errors != 0) {\n\t\t\twriteStringWithColor(os.Stderr, fmt.Sprintf(\"%s\\n\",\n\t\t\t\terrorAndWarningSummary(errors, warnings, shownErrors, shownWarnings)))\n\t\t}\n\t}\n\n\tswitch options.Color {\n\tcase ColorNever:\n\t\tterminalInfo.UseColorEscapes = false\n\tcase ColorAlways:\n\t\tterminalInfo.UseColorEscapes = SupportsColorEscapes\n\t}\n\n\treturn Log{\n\t\tLevel:     options.LogLevel,\n\t\tOverrides: options.Overrides,\n\n\t\tAddMsg: func(msg Msg) {\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\t\t\tmsgs = append(msgs, msg)\n\n\t\t\tswitch msg.Kind {\n\t\t\tcase Verbose:\n\t\t\t\tif options.LogLevel <= LevelVerbose {\n\t\t\t\t\twriteStringWithColor(os.Stderr, msg.String(options, terminalInfo))\n\t\t\t\t}\n\n\t\t\tcase Debug:\n\t\t\t\tif options.LogLevel <= LevelDebug {\n\t\t\t\t\twriteStringWithColor(os.Stderr, msg.String(options, terminalInfo))\n\t\t\t\t}\n\n\t\t\tcase Info:\n\t\t\t\tif options.LogLevel <= LevelInfo {\n\t\t\t\t\twriteStringWithColor(os.Stderr, msg.String(options, terminalInfo))\n\t\t\t\t}\n\n\t\t\tcase Error:\n\t\t\t\thasErrors = true\n\t\t\t\tif options.LogLevel <= LevelError {\n\t\t\t\t\terrors++\n\t\t\t\t}\n\n\t\t\tcase Warning:\n\t\t\t\tif options.LogLevel <= LevelWarning {\n\t\t\t\t\twarnings++\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Be silent if we're past the limit so we don't flood the terminal\n\t\t\tif remainingMessagesBeforeLimit == 0 {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tswitch msg.Kind {\n\t\t\tcase Error:\n\t\t\t\tif options.LogLevel <= LevelError {\n\t\t\t\t\tshownErrors++\n\t\t\t\t\twriteStringWithColor(os.Stderr, msg.String(options, terminalInfo))\n\t\t\t\t\tremainingMessagesBeforeLimit--\n\t\t\t\t}\n\n\t\t\tcase Warning:\n\t\t\t\tif options.LogLevel <= LevelWarning {\n\t\t\t\t\tif remainingMessagesBeforeLimit > (options.MessageLimit+1)/2 {\n\t\t\t\t\t\tshownWarnings++\n\t\t\t\t\t\twriteStringWithColor(os.Stderr, msg.String(options, terminalInfo))\n\t\t\t\t\t\tremainingMessagesBeforeLimit--\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If we have less than half of the slots left, wait for potential\n\t\t\t\t\t\t// future errors instead of using up all of the slots with warnings.\n\t\t\t\t\t\t// We want the log for a failed build to always have at least one\n\t\t\t\t\t\t// error in it.\n\t\t\t\t\t\tdeferredWarnings = append(deferredWarnings, msg)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tHasErrors: func() bool {\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\t\t\treturn hasErrors\n\t\t},\n\n\t\tPeek: func() []Msg {\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\t\t\tsort.Stable(msgs)\n\t\t\treturn append([]Msg{}, msgs...)\n\t\t},\n\n\t\tDone: func() []Msg {\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\t\t\tfinalizeLog()\n\t\t\tsort.Stable(msgs)\n\t\t\treturn msgs\n\t\t},\n\t}\n}\n\nfunc PrintErrorToStderr(osArgs []string, text string) {\n\tPrintMessageToStderr(osArgs, Msg{Kind: Error, Data: MsgData{Text: text}})\n}\n\nfunc PrintErrorWithNoteToStderr(osArgs []string, text string, note string) {\n\tmsg := Msg{\n\t\tKind: Error,\n\t\tData: MsgData{Text: text},\n\t}\n\tif note != \"\" {\n\t\tmsg.Notes = []MsgData{{Text: note}}\n\t}\n\tPrintMessageToStderr(osArgs, msg)\n}\n\nfunc OutputOptionsForArgs(osArgs []string) OutputOptions {\n\toptions := OutputOptions{IncludeSource: true}\n\n\t// Implement a mini argument parser so these options always work even if we\n\t// haven't yet gotten to the general-purpose argument parsing code\n\tfor _, arg := range osArgs {\n\t\tswitch arg {\n\t\tcase \"--color=false\":\n\t\t\toptions.Color = ColorNever\n\t\tcase \"--color=true\", \"--color\":\n\t\t\toptions.Color = ColorAlways\n\t\tcase \"--log-level=info\":\n\t\t\toptions.LogLevel = LevelInfo\n\t\tcase \"--log-level=warning\":\n\t\t\toptions.LogLevel = LevelWarning\n\t\tcase \"--log-level=error\":\n\t\t\toptions.LogLevel = LevelError\n\t\tcase \"--log-level=silent\":\n\t\t\toptions.LogLevel = LevelSilent\n\t\t}\n\t}\n\n\treturn options\n}\n\nfunc PrintMessageToStderr(osArgs []string, msg Msg) {\n\tlog := NewStderrLog(OutputOptionsForArgs(osArgs))\n\tlog.AddMsg(msg)\n\tlog.Done()\n}\n\ntype Colors struct {\n\tReset     string\n\tBold      string\n\tDim       string\n\tUnderline string\n\n\tRed   string\n\tGreen string\n\tBlue  string\n\n\tCyan    string\n\tMagenta string\n\tYellow  string\n\n\tRedBgRed     string\n\tRedBgWhite   string\n\tGreenBgGreen string\n\tGreenBgWhite string\n\tBlueBgBlue   string\n\tBlueBgWhite  string\n\n\tCyanBgCyan       string\n\tCyanBgBlack      string\n\tMagentaBgMagenta string\n\tMagentaBgBlack   string\n\tYellowBgYellow   string\n\tYellowBgBlack    string\n}\n\nvar TerminalColors = Colors{\n\tReset:     \"\\033[0m\",\n\tBold:      \"\\033[1m\",\n\tDim:       \"\\033[37m\",\n\tUnderline: \"\\033[4m\",\n\n\tRed:   \"\\033[31m\",\n\tGreen: \"\\033[32m\",\n\tBlue:  \"\\033[34m\",\n\n\tCyan:    \"\\033[36m\",\n\tMagenta: \"\\033[35m\",\n\tYellow:  \"\\033[33m\",\n\n\tRedBgRed:     \"\\033[41;31m\",\n\tRedBgWhite:   \"\\033[41;97m\",\n\tGreenBgGreen: \"\\033[42;32m\",\n\tGreenBgWhite: \"\\033[42;97m\",\n\tBlueBgBlue:   \"\\033[44;34m\",\n\tBlueBgWhite:  \"\\033[44;97m\",\n\n\tCyanBgCyan:       \"\\033[46;36m\",\n\tCyanBgBlack:      \"\\033[46;30m\",\n\tMagentaBgMagenta: \"\\033[45;35m\",\n\tMagentaBgBlack:   \"\\033[45;30m\",\n\tYellowBgYellow:   \"\\033[43;33m\",\n\tYellowBgBlack:    \"\\033[43;30m\",\n}\n\nfunc PrintText(file *os.File, level LogLevel, osArgs []string, callback func(Colors) string) {\n\toptions := OutputOptionsForArgs(osArgs)\n\n\t// Skip logging these if these logs are disabled\n\tif options.LogLevel > level {\n\t\treturn\n\t}\n\n\tPrintTextWithColor(file, options.Color, callback)\n}\n\nfunc PrintTextWithColor(file *os.File, useColor UseColor, callback func(Colors) string) {\n\tvar useColorEscapes bool\n\tswitch useColor {\n\tcase ColorNever:\n\t\tuseColorEscapes = false\n\tcase ColorAlways:\n\t\tuseColorEscapes = SupportsColorEscapes\n\tcase ColorIfTerminal:\n\t\tuseColorEscapes = GetTerminalInfo(file).UseColorEscapes\n\t}\n\n\tvar colors Colors\n\tif useColorEscapes {\n\t\tcolors = TerminalColors\n\t}\n\twriteStringWithColor(file, callback(colors))\n}\n\ntype SummaryTableEntry struct {\n\tDir         string\n\tBase        string\n\tSize        string\n\tBytes       int\n\tIsSourceMap bool\n}\n\n// This type is just so we can use Go's native sort function\ntype SummaryTable []SummaryTableEntry\n\nfunc (t SummaryTable) Len() int          { return len(t) }\nfunc (t SummaryTable) Swap(i int, j int) { t[i], t[j] = t[j], t[i] }\n\nfunc (t SummaryTable) Less(i int, j int) bool {\n\tti := t[i]\n\ttj := t[j]\n\n\t// Sort source maps last\n\tif !ti.IsSourceMap && tj.IsSourceMap {\n\t\treturn true\n\t}\n\tif ti.IsSourceMap && !tj.IsSourceMap {\n\t\treturn false\n\t}\n\n\t// Sort by size first\n\tif ti.Bytes > tj.Bytes {\n\t\treturn true\n\t}\n\tif ti.Bytes < tj.Bytes {\n\t\treturn false\n\t}\n\n\t// Sort alphabetically by directory first\n\tif ti.Dir < tj.Dir {\n\t\treturn true\n\t}\n\tif ti.Dir > tj.Dir {\n\t\treturn false\n\t}\n\n\t// Then sort alphabetically by file name\n\treturn ti.Base < tj.Base\n}\n\n// Show a warning icon next to output files that are 1mb or larger\nconst sizeWarningThreshold = 1024 * 1024\n\nfunc PrintSummary(useColor UseColor, table SummaryTable, start *time.Time) {\n\tPrintTextWithColor(os.Stderr, useColor, func(colors Colors) string {\n\t\tisProbablyWindowsCommandPrompt := isProbablyWindowsCommandPrompt()\n\t\tsb := strings.Builder{}\n\n\t\tif len(table) > 0 {\n\t\t\tinfo := GetTerminalInfo(os.Stderr)\n\n\t\t\t// Truncate the table in case it's really long\n\t\t\tmaxLength := info.Height / 2\n\t\t\tif info.Height == 0 {\n\t\t\t\tmaxLength = 20\n\t\t\t} else if maxLength < 5 {\n\t\t\t\tmaxLength = 5\n\t\t\t}\n\t\t\tlength := len(table)\n\t\t\tsort.Sort(table)\n\t\t\tif length > maxLength {\n\t\t\t\ttable = table[:maxLength]\n\t\t\t}\n\n\t\t\t// Compute the maximum width of the size column\n\t\t\tspacingBetweenColumns := 2\n\t\t\thasSizeWarning := false\n\t\t\tmaxPath := 0\n\t\t\tmaxSize := 0\n\t\t\tfor _, entry := range table {\n\t\t\t\tpath := len(entry.Dir) + len(entry.Base)\n\t\t\t\tsize := len(entry.Size) + spacingBetweenColumns\n\t\t\t\tif path > maxPath {\n\t\t\t\t\tmaxPath = path\n\t\t\t\t}\n\t\t\t\tif size > maxSize {\n\t\t\t\t\tmaxSize = size\n\t\t\t\t}\n\t\t\t\tif !entry.IsSourceMap && entry.Bytes >= sizeWarningThreshold {\n\t\t\t\t\thasSizeWarning = true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmargin := \"  \"\n\t\t\tlayoutWidth := info.Width\n\t\t\tif layoutWidth < 1 {\n\t\t\t\tlayoutWidth = defaultTerminalWidth\n\t\t\t}\n\t\t\tlayoutWidth -= 2 * len(margin)\n\t\t\tif hasSizeWarning {\n\t\t\t\t// Add space for the warning icon\n\t\t\t\tlayoutWidth -= 2\n\t\t\t}\n\t\t\tif layoutWidth > maxPath+maxSize {\n\t\t\t\tlayoutWidth = maxPath + maxSize\n\t\t\t}\n\t\t\tsb.WriteByte('\\n')\n\n\t\t\tfor _, entry := range table {\n\t\t\t\tdir, base := entry.Dir, entry.Base\n\t\t\t\tpathWidth := layoutWidth - maxSize\n\n\t\t\t\t// Truncate the path with \"...\" to fit on one line\n\t\t\t\tif len(dir)+len(base) > pathWidth {\n\t\t\t\t\t// Trim the directory from the front, leaving the trailing slash\n\t\t\t\t\tif len(dir) > 0 {\n\t\t\t\t\t\tn := pathWidth - len(base) - 3\n\t\t\t\t\t\tif n < 1 {\n\t\t\t\t\t\t\tn = 1\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdir = \"...\" + dir[len(dir)-n:]\n\t\t\t\t\t}\n\n\t\t\t\t\t// Trim the file name from the back\n\t\t\t\t\tif len(dir)+len(base) > pathWidth {\n\t\t\t\t\t\tn := pathWidth - len(dir) - 3\n\t\t\t\t\t\tif n < 0 {\n\t\t\t\t\t\t\tn = 0\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbase = base[:n] + \"...\"\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tspacer := layoutWidth - len(entry.Size) - len(dir) - len(base)\n\t\t\t\tif spacer < 0 {\n\t\t\t\t\tspacer = 0\n\t\t\t\t}\n\n\t\t\t\t// Put a warning next to the size if it's above a certain threshold\n\t\t\t\tsizeColor := colors.Cyan\n\t\t\t\tsizeWarning := \"\"\n\t\t\t\tif !entry.IsSourceMap && entry.Bytes >= sizeWarningThreshold {\n\t\t\t\t\tsizeColor = colors.Yellow\n\n\t\t\t\t\t// Emoji don't work in Windows Command Prompt\n\t\t\t\t\tif !isProbablyWindowsCommandPrompt {\n\t\t\t\t\t\tsizeWarning = \" ⚠️\"\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsb.WriteString(fmt.Sprintf(\"%s%s%s%s%s%s%s%s%s%s%s%s\\n\",\n\t\t\t\t\tmargin,\n\t\t\t\t\tcolors.Dim,\n\t\t\t\t\tdir,\n\t\t\t\t\tcolors.Reset,\n\t\t\t\t\tcolors.Bold,\n\t\t\t\t\tbase,\n\t\t\t\t\tcolors.Reset,\n\t\t\t\t\tstrings.Repeat(\" \", spacer),\n\t\t\t\t\tsizeColor,\n\t\t\t\t\tentry.Size,\n\t\t\t\t\tsizeWarning,\n\t\t\t\t\tcolors.Reset,\n\t\t\t\t))\n\t\t\t}\n\n\t\t\t// Say how many remaining files are not shown\n\t\t\tif length > maxLength {\n\t\t\t\tplural := \"s\"\n\t\t\t\tif length == maxLength+1 {\n\t\t\t\t\tplural = \"\"\n\t\t\t\t}\n\t\t\t\tsb.WriteString(fmt.Sprintf(\"%s%s...and %d more output file%s...%s\\n\", margin, colors.Dim, length-maxLength, plural, colors.Reset))\n\t\t\t}\n\t\t}\n\t\tsb.WriteByte('\\n')\n\n\t\tlightningSymbol := \"⚡ \"\n\n\t\t// Emoji don't work in Windows Command Prompt\n\t\tif isProbablyWindowsCommandPrompt {\n\t\t\tlightningSymbol = \"\"\n\t\t}\n\n\t\t// Printing the time taken is optional\n\t\tif start != nil {\n\t\t\tsb.WriteString(fmt.Sprintf(\"%s%sDone in %dms%s\\n\",\n\t\t\t\tlightningSymbol,\n\t\t\t\tcolors.Green,\n\t\t\t\ttime.Since(*start).Milliseconds(),\n\t\t\t\tcolors.Reset,\n\t\t\t))\n\t\t}\n\n\t\treturn sb.String()\n\t})\n}\n\ntype DeferLogKind uint8\n\nconst (\n\tDeferLogAll DeferLogKind = iota\n\tDeferLogNoVerboseOrDebug\n)\n\nfunc NewDeferLog(kind DeferLogKind, overrides map[MsgID]LogLevel) Log {\n\tvar msgs SortableMsgs\n\tvar mutex sync.Mutex\n\tvar hasErrors bool\n\n\treturn Log{\n\t\tLevel:     LevelInfo,\n\t\tOverrides: overrides,\n\n\t\tAddMsg: func(msg Msg) {\n\t\t\tif kind == DeferLogNoVerboseOrDebug && (msg.Kind == Verbose || msg.Kind == Debug) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\t\t\tif msg.Kind == Error {\n\t\t\t\thasErrors = true\n\t\t\t}\n\t\t\tmsgs = append(msgs, msg)\n\t\t},\n\n\t\tHasErrors: func() bool {\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\t\t\treturn hasErrors\n\t\t},\n\n\t\tPeek: func() []Msg {\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\t\t\treturn append([]Msg{}, msgs...)\n\t\t},\n\n\t\tDone: func() []Msg {\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\t\t\tsort.Stable(msgs)\n\t\t\treturn msgs\n\t\t},\n\t}\n}\n\ntype UseColor uint8\n\nconst (\n\tColorIfTerminal UseColor = iota\n\tColorNever\n\tColorAlways\n)\n\ntype OutputOptions struct {\n\tMessageLimit  int\n\tIncludeSource bool\n\tColor         UseColor\n\tLogLevel      LogLevel\n\tPathStyle     PathStyle\n\tOverrides     map[MsgID]LogLevel\n}\n\nfunc (msg Msg) String(options OutputOptions, terminalInfo TerminalInfo) string {\n\t// Format the message\n\tvar text strings.Builder\n\ttext.WriteString(msgString(options.IncludeSource, options.PathStyle, terminalInfo, msg.ID, msg.Kind, msg.Data, msg.PluginName))\n\n\t// Format the notes\n\tvar oldData MsgData\n\tfor i, note := range msg.Notes {\n\t\tif options.IncludeSource && (i == 0 || strings.IndexByte(oldData.Text, '\\n') >= 0 || oldData.Location != nil) {\n\t\t\ttext.WriteString(\"\\n\")\n\t\t}\n\t\ttext.WriteString(msgString(options.IncludeSource, options.PathStyle, terminalInfo, MsgID_None, Note, note, \"\"))\n\t\toldData = note\n\t}\n\n\t// Add extra spacing between messages if source code is present\n\tif options.IncludeSource {\n\t\ttext.WriteString(\"\\n\")\n\t}\n\treturn text.String()\n}\n\n// The number of margin characters in addition to the line number\nconst extraMarginChars = 9\n\nfunc marginWithLineText(maxMargin int, line int) string {\n\tnumber := fmt.Sprintf(\"%d\", line)\n\treturn fmt.Sprintf(\"      %s%s │ \", strings.Repeat(\" \", maxMargin-len(number)), number)\n}\n\nfunc emptyMarginText(maxMargin int, isLast bool) string {\n\tspace := strings.Repeat(\" \", maxMargin)\n\tif isLast {\n\t\treturn fmt.Sprintf(\"      %s ╵ \", space)\n\t}\n\treturn fmt.Sprintf(\"      %s │ \", space)\n}\n\nfunc msgString(includeSource bool, pathStyle PathStyle, terminalInfo TerminalInfo, id MsgID, kind MsgKind, data MsgData, pluginName string) string {\n\tif !includeSource {\n\t\tif loc := data.Location; loc != nil {\n\t\t\treturn fmt.Sprintf(\"%s: %s: %s\\n\", loc.File.Select(pathStyle), kind.String(), data.Text)\n\t\t}\n\t\treturn fmt.Sprintf(\"%s: %s\\n\", kind.String(), data.Text)\n\t}\n\n\tvar colors Colors\n\tif terminalInfo.UseColorEscapes {\n\t\tcolors = TerminalColors\n\t}\n\n\tvar iconColor string\n\tvar kindColorBrackets string\n\tvar kindColorText string\n\n\tlocation := \"\"\n\n\tif data.Location != nil {\n\t\tmaxMargin := len(fmt.Sprintf(\"%d\", data.Location.Line))\n\t\td := detailStruct(data, pathStyle, terminalInfo, maxMargin)\n\n\t\tif d.Suggestion != \"\" {\n\t\t\tlocation = fmt.Sprintf(\"\\n    %s:%d:%d:\\n%s%s%s%s%s%s\\n%s%s%s%s%s\\n%s%s%s%s%s\\n%s\",\n\t\t\t\td.Path, d.Line, d.Column,\n\t\t\t\tcolors.Dim, d.SourceBefore, colors.Green, d.SourceMarked, colors.Dim, d.SourceAfter,\n\t\t\t\temptyMarginText(maxMargin, false), d.Indent, colors.Green, d.Marker, colors.Dim,\n\t\t\t\temptyMarginText(maxMargin, true), d.Indent, colors.Green, d.Suggestion, colors.Reset,\n\t\t\t\td.ContentAfter,\n\t\t\t)\n\t\t} else {\n\t\t\tlocation = fmt.Sprintf(\"\\n    %s:%d:%d:\\n%s%s%s%s%s%s\\n%s%s%s%s%s\\n%s\",\n\t\t\t\td.Path, d.Line, d.Column,\n\t\t\t\tcolors.Dim, d.SourceBefore, colors.Green, d.SourceMarked, colors.Dim, d.SourceAfter,\n\t\t\t\temptyMarginText(maxMargin, true), d.Indent, colors.Green, d.Marker, colors.Reset,\n\t\t\t\td.ContentAfter,\n\t\t\t)\n\t\t}\n\t}\n\n\tswitch kind {\n\tcase Verbose:\n\t\ticonColor = colors.Cyan\n\t\tkindColorBrackets = colors.CyanBgCyan\n\t\tkindColorText = colors.CyanBgBlack\n\n\tcase Debug:\n\t\ticonColor = colors.Green\n\t\tkindColorBrackets = colors.GreenBgGreen\n\t\tkindColorText = colors.GreenBgWhite\n\n\tcase Info:\n\t\ticonColor = colors.Blue\n\t\tkindColorBrackets = colors.BlueBgBlue\n\t\tkindColorText = colors.BlueBgWhite\n\n\tcase Error:\n\t\ticonColor = colors.Red\n\t\tkindColorBrackets = colors.RedBgRed\n\t\tkindColorText = colors.RedBgWhite\n\n\tcase Warning:\n\t\ticonColor = colors.Yellow\n\t\tkindColorBrackets = colors.YellowBgYellow\n\t\tkindColorText = colors.YellowBgBlack\n\n\tcase Note:\n\t\tsb := strings.Builder{}\n\n\t\tfor _, line := range strings.Split(data.Text, \"\\n\") {\n\t\t\t// Special-case word wrapping\n\t\t\tif wrapWidth := terminalInfo.Width; wrapWidth > 2 {\n\t\t\t\tif !data.DisableMaximumWidth && wrapWidth > 100 {\n\t\t\t\t\twrapWidth = 100 // Enforce a maximum paragraph width for readability\n\t\t\t\t}\n\t\t\t\tfor _, run := range wrapWordsInString(line, wrapWidth-2) {\n\t\t\t\t\tsb.WriteString(\"  \")\n\t\t\t\t\tsb.WriteString(linkifyText(run, colors.Underline, colors.Reset))\n\t\t\t\t\tsb.WriteByte('\\n')\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Otherwise, just write an indented line\n\t\t\tsb.WriteString(\"  \")\n\t\t\tsb.WriteString(linkifyText(line, colors.Underline, colors.Reset))\n\t\t\tsb.WriteByte('\\n')\n\t\t}\n\n\t\tsb.WriteString(location)\n\t\treturn sb.String()\n\t}\n\n\tif pluginName != \"\" {\n\t\tpluginName = fmt.Sprintf(\" %s%s[plugin %s]%s\", colors.Bold, colors.Magenta, pluginName, colors.Reset)\n\t}\n\n\tmsgID := MsgIDToString(id)\n\tif msgID != \"\" {\n\t\tmsgID = fmt.Sprintf(\" [%s]\", msgID)\n\t}\n\n\treturn fmt.Sprintf(\"%s%s %s[%s%s%s]%s %s%s%s%s%s\\n%s\",\n\t\ticonColor, kind.Icon(),\n\t\tkindColorBrackets, kindColorText, kind.String(), kindColorBrackets, colors.Reset,\n\t\tcolors.Bold, data.Text, colors.Reset, pluginName, msgID,\n\t\tlocation,\n\t)\n}\n\nfunc linkifyText(text string, underline string, reset string) string {\n\tif underline == \"\" {\n\t\treturn text\n\t}\n\n\thttps := strings.Index(text, \"https://\")\n\tif https == -1 {\n\t\treturn text\n\t}\n\n\tsb := strings.Builder{}\n\tfor {\n\t\thttps := strings.Index(text, \"https://\")\n\t\tif https == -1 {\n\t\t\tbreak\n\t\t}\n\n\t\tend := strings.IndexByte(text[https:], ' ')\n\t\tif end == -1 {\n\t\t\tend = len(text)\n\t\t} else {\n\t\t\tend += https\n\t\t}\n\n\t\t// Remove trailing punctuation\n\t\tif end > https {\n\t\t\tswitch text[end-1] {\n\t\t\tcase '.', ',', '?', '!', ')', ']', '}':\n\t\t\t\tend--\n\t\t\t}\n\t\t}\n\n\t\tsb.WriteString(text[:https])\n\t\tsb.WriteString(underline)\n\t\tsb.WriteString(text[https:end])\n\t\tsb.WriteString(reset)\n\t\ttext = text[end:]\n\t}\n\n\tsb.WriteString(text)\n\treturn sb.String()\n}\n\nfunc wrapWordsInString(text string, width int) []string {\n\truns := []string{}\n\nouter:\n\tfor text != \"\" {\n\t\ti := 0\n\t\tx := 0\n\t\twordEndI := 0\n\n\t\t// Skip over any leading spaces\n\t\tfor i < len(text) && text[i] == ' ' {\n\t\t\ti++\n\t\t\tx++\n\t\t}\n\n\t\t// Find out how many words will fit in this run\n\t\tfor i < len(text) {\n\t\t\toldWordEndI := wordEndI\n\t\t\twordStartI := i\n\n\t\t\t// Find the end of the word\n\t\t\tfor i < len(text) {\n\t\t\t\tc, width := utf8.DecodeRuneInString(text[i:])\n\t\t\t\tif c == ' ' {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ti += width\n\t\t\t\tx += 1 // Naively assume that each unicode code point is a single column\n\t\t\t}\n\t\t\twordEndI = i\n\n\t\t\t// Split into a new run if this isn't the first word in the run and the end is past the width\n\t\t\tif wordStartI > 0 && x > width {\n\t\t\t\truns = append(runs, text[:oldWordEndI])\n\t\t\t\ttext = text[wordStartI:]\n\t\t\t\tcontinue outer\n\t\t\t}\n\n\t\t\t// Skip over any spaces after the word\n\t\t\tfor i < len(text) && text[i] == ' ' {\n\t\t\t\ti++\n\t\t\t\tx++\n\t\t\t}\n\t\t}\n\n\t\t// If we get here, this is the last run (i.e. everything fits)\n\t\tbreak\n\t}\n\n\t// Remove any trailing spaces on the last run\n\tfor len(text) > 0 && text[len(text)-1] == ' ' {\n\t\ttext = text[:len(text)-1]\n\t}\n\truns = append(runs, text)\n\treturn runs\n}\n\ntype MsgDetail struct {\n\tSourceBefore string\n\tSourceMarked string\n\tSourceAfter  string\n\n\tIndent     string\n\tMarker     string\n\tSuggestion string\n\n\tContentAfter string\n\n\tPath   string\n\tLine   int\n\tColumn int\n}\n\n// It's not common for large files to have many warnings. But when it happens,\n// we want to make sure that it's not too slow. Source code locations are\n// represented as byte offsets for compactness but transforming these to\n// line/column locations for warning messages requires scanning through the\n// file. A naive approach for this would cause O(n^2) scanning time for n\n// warnings distributed throughout the file.\n//\n// Warnings are typically generated sequentially as the file is scanned. So\n// one way of optimizing this is to just start scanning from where we left\n// off last time instead of always starting from the beginning of the file.\n// That's what this object does.\n//\n// Another option could be to eagerly populate an array of line/column offsets\n// and then use binary search for each query. This might slow down the common\n// case of a file with only at most a few warnings though, so think before\n// optimizing too much. Performance in the zero or one warning case is by far\n// the most important.\ntype LineColumnTracker struct {\n\tcontents     string\n\tprettyPaths  PrettyPaths\n\toffset       int32\n\tline         int32\n\tlineStart    int32\n\tlineEnd      int32\n\thasLineStart bool\n\thasLineEnd   bool\n\thasSource    bool\n}\n\nfunc MakeLineColumnTracker(source *Source) LineColumnTracker {\n\tif source == nil {\n\t\treturn LineColumnTracker{\n\t\t\thasSource: false,\n\t\t}\n\t}\n\n\treturn LineColumnTracker{\n\t\tcontents:     source.Contents,\n\t\tprettyPaths:  source.PrettyPaths,\n\t\thasLineStart: true,\n\t\thasSource:    true,\n\t}\n}\n\nfunc (tracker *LineColumnTracker) MsgData(r Range, text string) MsgData {\n\treturn MsgData{\n\t\tText:     text,\n\t\tLocation: tracker.MsgLocationOrNil(r),\n\t}\n}\n\nfunc (t *LineColumnTracker) scanTo(offset int32) {\n\tcontents := t.contents\n\ti := t.offset\n\n\t// Scan forward\n\tif i < offset {\n\t\tfor {\n\t\t\tr, size := utf8.DecodeRuneInString(contents[i:])\n\t\t\ti += int32(size)\n\n\t\t\tswitch r {\n\t\t\tcase '\\n':\n\t\t\t\tt.hasLineStart = true\n\t\t\t\tt.hasLineEnd = false\n\t\t\t\tt.lineStart = i\n\t\t\t\tif i == int32(size) || contents[i-int32(size)-1] != '\\r' {\n\t\t\t\t\tt.line++\n\t\t\t\t}\n\n\t\t\tcase '\\r', '\\u2028', '\\u2029':\n\t\t\t\tt.hasLineStart = true\n\t\t\t\tt.hasLineEnd = false\n\t\t\t\tt.lineStart = i\n\t\t\t\tt.line++\n\t\t\t}\n\n\t\t\tif i >= offset {\n\t\t\t\tt.offset = i\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Scan backward\n\tif i > offset {\n\t\tfor {\n\t\t\tr, size := utf8.DecodeLastRuneInString(contents[:i])\n\t\t\ti -= int32(size)\n\n\t\t\tswitch r {\n\t\t\tcase '\\n':\n\t\t\t\tt.hasLineStart = false\n\t\t\t\tt.hasLineEnd = true\n\t\t\t\tt.lineEnd = i\n\t\t\t\tif i == 0 || contents[i-1] != '\\r' {\n\t\t\t\t\tt.line--\n\t\t\t\t}\n\n\t\t\tcase '\\r', '\\u2028', '\\u2029':\n\t\t\t\tt.hasLineStart = false\n\t\t\t\tt.hasLineEnd = true\n\t\t\t\tt.lineEnd = i\n\t\t\t\tt.line--\n\t\t\t}\n\n\t\t\tif i <= offset {\n\t\t\t\tt.offset = i\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (t *LineColumnTracker) computeLineAndColumn(offset int) (lineCount int, columnCount int, lineStart int, lineEnd int) {\n\tt.scanTo(int32(offset))\n\n\t// Scan for the start of the line\n\tif !t.hasLineStart {\n\t\tcontents := t.contents\n\t\ti := t.offset\n\t\tfor i > 0 {\n\t\t\tr, size := utf8.DecodeLastRuneInString(contents[:i])\n\t\t\tif r == '\\n' || r == '\\r' || r == '\\u2028' || r == '\\u2029' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ti -= int32(size)\n\t\t}\n\t\tt.hasLineStart = true\n\t\tt.lineStart = i\n\t}\n\n\t// Scan for the end of the line\n\tif !t.hasLineEnd {\n\t\tcontents := t.contents\n\t\ti := t.offset\n\t\tn := int32(len(contents))\n\t\tfor i < n {\n\t\t\tr, size := utf8.DecodeRuneInString(contents[i:])\n\t\t\tif r == '\\n' || r == '\\r' || r == '\\u2028' || r == '\\u2029' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ti += int32(size)\n\t\t}\n\t\tt.hasLineEnd = true\n\t\tt.lineEnd = i\n\t}\n\n\treturn int(t.line), offset - int(t.lineStart), int(t.lineStart), int(t.lineEnd)\n}\n\nfunc (tracker *LineColumnTracker) MsgLocationOrNil(r Range) *MsgLocation {\n\tif tracker == nil || !tracker.hasSource {\n\t\treturn nil\n\t}\n\n\t// Convert the index into a line and column number\n\tlineCount, columnCount, lineStart, lineEnd := tracker.computeLineAndColumn(int(r.Loc.Start))\n\n\treturn &MsgLocation{\n\t\tFile:     tracker.prettyPaths,\n\t\tLine:     lineCount + 1, // 0-based to 1-based\n\t\tColumn:   columnCount,\n\t\tLength:   int(r.Len),\n\t\tLineText: tracker.contents[lineStart:lineEnd],\n\t}\n}\n\nfunc detailStruct(data MsgData, pathStyle PathStyle, terminalInfo TerminalInfo, maxMargin int) MsgDetail {\n\t// Only highlight the first line of the line text\n\tloc := *data.Location\n\tendOfFirstLine := len(loc.LineText)\n\n\t// Note: This uses \"IndexByte\" because Go implements this with SIMD, which\n\t// can matter a lot for really long lines. Some people pass huge >100mb\n\t// minified files as line text for the log message.\n\tif i := strings.IndexByte(loc.LineText, '\\n'); i >= 0 {\n\t\tendOfFirstLine = i\n\t}\n\n\tfirstLine := loc.LineText[:endOfFirstLine]\n\tafterFirstLine := loc.LineText[endOfFirstLine:]\n\tif afterFirstLine != \"\" && !strings.HasSuffix(afterFirstLine, \"\\n\") {\n\t\tafterFirstLine += \"\\n\"\n\t}\n\n\t// Clamp values in range\n\tif loc.Line < 0 {\n\t\tloc.Line = 0\n\t}\n\tif loc.Column < 0 {\n\t\tloc.Column = 0\n\t}\n\tif loc.Length < 0 {\n\t\tloc.Length = 0\n\t}\n\tif loc.Column > endOfFirstLine {\n\t\tloc.Column = endOfFirstLine\n\t}\n\tif loc.Length > endOfFirstLine-loc.Column {\n\t\tloc.Length = endOfFirstLine - loc.Column\n\t}\n\n\tspacesPerTab := 2\n\tlineText := renderTabStops(firstLine, spacesPerTab)\n\ttextUpToLoc := renderTabStops(firstLine[:loc.Column], spacesPerTab)\n\tmarkerStart := len(textUpToLoc)\n\tmarkerEnd := markerStart\n\tindent := strings.Repeat(\" \", estimateWidthInTerminal(textUpToLoc))\n\tmarker := \"^\"\n\n\t// Extend markers to cover the full range of the error\n\tif loc.Length > 0 {\n\t\tmarkerEnd = len(renderTabStops(firstLine[:loc.Column+loc.Length], spacesPerTab))\n\t}\n\n\t// Clip the marker to the bounds of the line\n\tif markerStart > len(lineText) {\n\t\tmarkerStart = len(lineText)\n\t}\n\tif markerEnd > len(lineText) {\n\t\tmarkerEnd = len(lineText)\n\t}\n\tif markerEnd < markerStart {\n\t\tmarkerEnd = markerStart\n\t}\n\n\t// Trim the line to fit the terminal width\n\twidth := terminalInfo.Width\n\tif width < 1 {\n\t\twidth = defaultTerminalWidth\n\t}\n\twidth -= maxMargin + extraMarginChars\n\tif width < 1 {\n\t\twidth = 1\n\t}\n\tif loc.Column == endOfFirstLine {\n\t\t// If the marker is at the very end of the line, the marker will be a \"^\"\n\t\t// character that extends one column past the end of the line. In this case\n\t\t// we should reserve a column at the end so the marker doesn't wrap.\n\t\twidth -= 1\n\t}\n\tif len(lineText) > width {\n\t\t// Try to center the error\n\t\tsliceStart := (markerStart + markerEnd - width) / 2\n\t\tif sliceStart > markerStart-width/5 {\n\t\t\tsliceStart = markerStart - width/5\n\t\t}\n\t\tif sliceStart < 0 {\n\t\t\tsliceStart = 0\n\t\t}\n\t\tif sliceStart > len(lineText)-width {\n\t\t\tsliceStart = len(lineText) - width\n\t\t}\n\t\tsliceEnd := sliceStart + width\n\n\t\t// Slice the line\n\t\tslicedLine := lineText[sliceStart:sliceEnd]\n\t\tmarkerStart -= sliceStart\n\t\tmarkerEnd -= sliceStart\n\t\tif markerStart < 0 {\n\t\t\tmarkerStart = 0\n\t\t}\n\t\tif markerEnd > len(slicedLine) {\n\t\t\tmarkerEnd = len(slicedLine)\n\t\t}\n\n\t\t// Truncate the ends with \"...\"\n\t\tif len(slicedLine) > 3 && sliceStart > 0 {\n\t\t\tslicedLine = \"...\" + slicedLine[3:]\n\t\t\tif markerStart < 3 {\n\t\t\t\tmarkerStart = 3\n\t\t\t}\n\t\t}\n\t\tif len(slicedLine) > 3 && sliceEnd < len(lineText) {\n\t\t\tslicedLine = slicedLine[:len(slicedLine)-3] + \"...\"\n\t\t\tif markerEnd > len(slicedLine)-3 {\n\t\t\t\tmarkerEnd = len(slicedLine) - 3\n\t\t\t}\n\t\t\tif markerEnd < markerStart {\n\t\t\t\tmarkerEnd = markerStart\n\t\t\t}\n\t\t}\n\n\t\t// Now we can compute the indent\n\t\tlineText = slicedLine\n\t\tindent = strings.Repeat(\" \", estimateWidthInTerminal(lineText[:markerStart]))\n\t}\n\n\t// If marker is still multi-character after clipping, make the marker wider\n\tif markerEnd-markerStart > 1 {\n\t\tmarker = strings.Repeat(\"~\", estimateWidthInTerminal(lineText[markerStart:markerEnd]))\n\t}\n\n\t// Put a margin before the marker indent\n\tmargin := marginWithLineText(maxMargin, loc.Line)\n\n\treturn MsgDetail{\n\t\tPath:   loc.File.Select(pathStyle),\n\t\tLine:   loc.Line,\n\t\tColumn: loc.Column,\n\n\t\tSourceBefore: margin + lineText[:markerStart],\n\t\tSourceMarked: lineText[markerStart:markerEnd],\n\t\tSourceAfter:  lineText[markerEnd:],\n\n\t\tIndent:     indent,\n\t\tMarker:     marker,\n\t\tSuggestion: loc.Suggestion,\n\n\t\tContentAfter: afterFirstLine,\n\t}\n}\n\n// Estimate the number of columns this string will take when printed\nfunc estimateWidthInTerminal(text string) int {\n\t// For now just assume each code point is one column. This is wrong but is\n\t// less wrong than assuming each code unit is one column.\n\twidth := 0\n\tfor text != \"\" {\n\t\tc, size := utf8.DecodeRuneInString(text)\n\t\ttext = text[size:]\n\n\t\t// Ignore the Zero Width No-Break Space character (UTF-8 BOM)\n\t\tif c != 0xFEFF {\n\t\t\twidth++\n\t\t}\n\t}\n\treturn width\n}\n\nfunc renderTabStops(withTabs string, spacesPerTab int) string {\n\tif !strings.ContainsRune(withTabs, '\\t') {\n\t\treturn withTabs\n\t}\n\n\twithoutTabs := strings.Builder{}\n\tcount := 0\n\n\tfor _, c := range withTabs {\n\t\tif c == '\\t' {\n\t\t\tspaces := spacesPerTab - count%spacesPerTab\n\t\t\tfor i := 0; i < spaces; i++ {\n\t\t\t\twithoutTabs.WriteRune(' ')\n\t\t\t\tcount++\n\t\t\t}\n\t\t} else {\n\t\t\twithoutTabs.WriteRune(c)\n\t\t\tcount++\n\t\t}\n\t}\n\n\treturn withoutTabs.String()\n}\n\nfunc (log Log) AddError(tracker *LineColumnTracker, r Range, text string) {\n\tlog.AddMsg(Msg{\n\t\tKind: Error,\n\t\tData: tracker.MsgData(r, text),\n\t})\n}\n\nfunc (log Log) AddID(id MsgID, kind MsgKind, tracker *LineColumnTracker, r Range, text string) {\n\tif override, ok := allowOverride(log.Overrides, id, kind); ok {\n\t\tlog.AddMsg(Msg{\n\t\t\tID:   id,\n\t\t\tKind: override,\n\t\t\tData: tracker.MsgData(r, text),\n\t\t})\n\t}\n}\n\nfunc (log Log) AddErrorWithNotes(tracker *LineColumnTracker, r Range, text string, notes []MsgData) {\n\tlog.AddMsg(Msg{\n\t\tKind:  Error,\n\t\tData:  tracker.MsgData(r, text),\n\t\tNotes: notes,\n\t})\n}\n\nfunc (log Log) AddIDWithNotes(id MsgID, kind MsgKind, tracker *LineColumnTracker, r Range, text string, notes []MsgData) {\n\tif override, ok := allowOverride(log.Overrides, id, kind); ok {\n\t\tlog.AddMsg(Msg{\n\t\t\tID:    id,\n\t\t\tKind:  override,\n\t\t\tData:  tracker.MsgData(r, text),\n\t\t\tNotes: notes,\n\t\t})\n\t}\n}\n\nfunc (log Log) AddMsgID(id MsgID, msg Msg) {\n\tif override, ok := allowOverride(log.Overrides, id, msg.Kind); ok {\n\t\tmsg.ID = id\n\t\tmsg.Kind = override\n\t\tlog.AddMsg(msg)\n\t}\n}\n\nfunc allowOverride(overrides map[MsgID]LogLevel, id MsgID, kind MsgKind) (MsgKind, bool) {\n\tif logLevel, ok := overrides[id]; ok {\n\t\tswitch logLevel {\n\t\tcase LevelVerbose:\n\t\t\treturn Verbose, true\n\t\tcase LevelDebug:\n\t\t\treturn Debug, true\n\t\tcase LevelInfo:\n\t\t\treturn Info, true\n\t\tcase LevelWarning:\n\t\t\treturn Warning, true\n\t\tcase LevelError:\n\t\t\treturn Error, true\n\t\tdefault:\n\t\t\t// Setting the log level to \"silent\" silences this log message\n\t\t\treturn MsgKind(0), false\n\t\t}\n\t}\n\treturn kind, true\n}\n\ntype StringInJSTableEntry struct {\n\tinnerLine   int32\n\tinnerColumn int32\n\tinnerLoc    Loc\n\touterLoc    Loc\n}\n\n// For Yarn PnP we sometimes parse JSON embedded in a JS string. This generates\n// a table that remaps locations inside the embedded JSON string literal into\n// locations in the actual JS file, which makes them easier to understand.\nfunc GenerateStringInJSTable(outerContents string, outerStringLiteralLoc Loc, innerContents string) (table []StringInJSTableEntry) {\n\ti := int32(0)\n\tn := int32(len(innerContents))\n\tline := int32(1)\n\tcolumn := int32(0)\n\tloc := Loc{Start: outerStringLiteralLoc.Start + 1}\n\n\tfor i < n {\n\t\t// Ignore line continuations. A line continuation is not an escaped newline.\n\t\tfor {\n\t\t\tif c, _ := utf8.DecodeRuneInString(outerContents[loc.Start:]); c != '\\\\' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tc, width := utf8.DecodeRuneInString(outerContents[loc.Start+1:])\n\t\t\tswitch c {\n\t\t\tcase '\\n', '\\r', '\\u2028', '\\u2029':\n\t\t\t\tloc.Start += 1 + int32(width)\n\t\t\t\tif c == '\\r' && outerContents[loc.Start] == '\\n' {\n\t\t\t\t\t// Make sure Windows CRLF counts as a single newline\n\t\t\t\t\tloc.Start++\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\tc, width := utf8.DecodeRuneInString(innerContents[i:])\n\n\t\t// Compress the table using run-length encoding\n\t\ttable = append(table, StringInJSTableEntry{innerLine: line, innerColumn: column, innerLoc: Loc{Start: i}, outerLoc: loc})\n\t\tif len(table) > 1 {\n\t\t\tif last := table[len(table)-2]; line == last.innerLine && loc.Start-column == last.outerLoc.Start-last.innerColumn {\n\t\t\t\ttable = table[:len(table)-1]\n\t\t\t}\n\t\t}\n\n\t\t// Advance the inner line/column\n\t\tswitch c {\n\t\tcase '\\n', '\\r', '\\u2028', '\\u2029':\n\t\t\tline++\n\t\t\tcolumn = 0\n\n\t\t\t// Handle newlines on Windows\n\t\t\tif c == '\\r' && i+1 < n && innerContents[i+1] == '\\n' {\n\t\t\t\ti++\n\t\t\t}\n\n\t\tdefault:\n\t\t\tcolumn += int32(width)\n\t\t}\n\t\ti += int32(width)\n\n\t\t// Advance the outer loc, assuming the string syntax is already valid\n\t\tc, width = utf8.DecodeRuneInString(outerContents[loc.Start:])\n\t\tif c == '\\r' && outerContents[loc.Start+1] == '\\n' {\n\t\t\t// Handle newlines on Windows in template literal strings\n\t\t\tloc.Start += 2\n\t\t} else if c != '\\\\' {\n\t\t\tloc.Start += int32(width)\n\t\t} else {\n\t\t\t// Handle an escape sequence\n\t\t\tc, width = utf8.DecodeRuneInString(outerContents[loc.Start+1:])\n\t\t\tswitch c {\n\t\t\tcase 'x':\n\t\t\t\t// 2-digit hexadecimal\n\t\t\t\tloc.Start += 1 + 2\n\n\t\t\tcase 'u':\n\t\t\t\tloc.Start++\n\t\t\t\tif outerContents[loc.Start] == '{' {\n\t\t\t\t\t// Variable-length\n\t\t\t\t\tfor outerContents[loc.Start] != '}' {\n\t\t\t\t\t\tloc.Start++\n\t\t\t\t\t}\n\t\t\t\t\tloc.Start++\n\t\t\t\t} else {\n\t\t\t\t\t// Fixed-length\n\t\t\t\t\tloc.Start += 4\n\t\t\t\t}\n\n\t\t\tcase '\\n', '\\r', '\\u2028', '\\u2029':\n\t\t\t\t// This will be handled by the next iteration\n\t\t\t\tbreak\n\n\t\t\tdefault:\n\t\t\t\tloc.Start += 1 + int32(width)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc RemapStringInJSLoc(table []StringInJSTableEntry, innerLoc Loc) Loc {\n\tcount := len(table)\n\tindex := 0\n\n\t// Binary search to find the previous entry\n\tfor count > 0 {\n\t\tstep := count / 2\n\t\ti := index + step\n\t\tif i+1 < len(table) {\n\t\t\tif entry := table[i+1]; entry.innerLoc.Start < innerLoc.Start {\n\t\t\t\tindex = i + 1\n\t\t\t\tcount -= step + 1\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tcount = step\n\t}\n\n\tentry := table[index]\n\tentry.outerLoc.Start += innerLoc.Start - entry.innerLoc.Start // Undo run-length compression\n\treturn entry.outerLoc\n}\n\nfunc NewStringInJSLog(log Log, outerTracker *LineColumnTracker, table []StringInJSTableEntry) Log {\n\toldAddMsg := log.AddMsg\n\n\tremapLineAndColumnToLoc := func(line int32, column int32) Loc {\n\t\tcount := len(table)\n\t\tindex := 0\n\n\t\t// Binary search to find the previous entry\n\t\tfor count > 0 {\n\t\t\tstep := count / 2\n\t\t\ti := index + step\n\t\t\tif i+1 < len(table) {\n\t\t\t\tif entry := table[i+1]; entry.innerLine < line || (entry.innerLine == line && entry.innerColumn < column) {\n\t\t\t\t\tindex = i + 1\n\t\t\t\t\tcount -= step + 1\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tcount = step\n\t\t}\n\n\t\tentry := table[index]\n\t\tentry.outerLoc.Start += column - entry.innerColumn // Undo run-length compression\n\t\treturn entry.outerLoc\n\t}\n\n\tremapData := func(data MsgData) MsgData {\n\t\tif data.Location == nil {\n\t\t\treturn data\n\t\t}\n\n\t\t// Generate a range in the outer source using the line/column/length in the inner source\n\t\tr := Range{Loc: remapLineAndColumnToLoc(int32(data.Location.Line), int32(data.Location.Column))}\n\t\tif data.Location.Length != 0 {\n\t\t\tr.Len = remapLineAndColumnToLoc(int32(data.Location.Line), int32(data.Location.Column+data.Location.Length)).Start - r.Loc.Start\n\t\t}\n\n\t\t// Use that range to look up the line in the outer source\n\t\tlocation := outerTracker.MsgData(r, data.Text).Location\n\t\tlocation.Suggestion = data.Location.Suggestion\n\t\tdata.Location = location\n\t\treturn data\n\t}\n\n\tlog.AddMsg = func(msg Msg) {\n\t\tmsg.Data = remapData(msg.Data)\n\t\tfor i, note := range msg.Notes {\n\t\t\tmsg.Notes[i] = remapData(note)\n\t\t}\n\t\toldAddMsg(msg)\n\t}\n\n\treturn log\n}\n"
  },
  {
    "path": "internal/logger/logger_darwin.go",
    "content": "//go:build darwin\n// +build darwin\n\npackage logger\n\nimport (\n\t\"os\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst SupportsColorEscapes = true\n\nfunc GetTerminalInfo(file *os.File) (info TerminalInfo) {\n\tfd := file.Fd()\n\n\t// Is this file descriptor a terminal?\n\tif _, err := unix.IoctlGetTermios(int(fd), unix.TIOCGETA); err == nil {\n\t\tinfo.IsTTY = true\n\t\tinfo.UseColorEscapes = !hasNoColorEnvironmentVariable()\n\n\t\t// Get the width of the window\n\t\tif w, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ); err == nil {\n\t\t\tinfo.Width = int(w.Col)\n\t\t\tinfo.Height = int(w.Row)\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc writeStringWithColor(file *os.File, text string) {\n\tfile.WriteString(text)\n}\n"
  },
  {
    "path": "internal/logger/logger_linux.go",
    "content": "//go:build linux\n// +build linux\n\npackage logger\n\nimport (\n\t\"os\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst SupportsColorEscapes = true\n\nfunc GetTerminalInfo(file *os.File) (info TerminalInfo) {\n\tfd := file.Fd()\n\n\t// Is this file descriptor a terminal?\n\tif _, err := unix.IoctlGetTermios(int(fd), unix.TCGETS); err == nil {\n\t\tinfo.IsTTY = true\n\t\tinfo.UseColorEscapes = !hasNoColorEnvironmentVariable()\n\n\t\t// Get the width of the window\n\t\tif w, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ); err == nil {\n\t\t\tinfo.Width = int(w.Col)\n\t\t\tinfo.Height = int(w.Row)\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc writeStringWithColor(file *os.File, text string) {\n\tfile.WriteString(text)\n}\n"
  },
  {
    "path": "internal/logger/logger_other.go",
    "content": "//go:build !darwin && !linux && !windows\n// +build !darwin,!linux,!windows\n\npackage logger\n\nimport \"os\"\n\nconst SupportsColorEscapes = false\n\nfunc GetTerminalInfo(*os.File) TerminalInfo {\n\treturn TerminalInfo{}\n}\n\nfunc writeStringWithColor(file *os.File, text string) {\n\tfile.WriteString(text)\n}\n"
  },
  {
    "path": "internal/logger/logger_test.go",
    "content": "package logger_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/test\"\n)\n\nfunc TestMsgIDs(t *testing.T) {\n\tfor id := logger.MsgID_None; id <= logger.MsgID_END; id++ {\n\t\tstr := logger.MsgIDToString(id)\n\t\tif str == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\toverrides := make(map[logger.MsgID]logger.LogLevel)\n\t\tlogger.StringToMsgIDs(str, logger.LevelError, overrides)\n\t\tif len(overrides) == 0 {\n\t\t\tt.Fatalf(\"Failed to find message id(s) for the string %q\", str)\n\t\t}\n\n\t\tfor k, v := range overrides {\n\t\t\ttest.AssertEqual(t, logger.MsgIDToString(k), str)\n\t\t\ttest.AssertEqual(t, v, logger.LevelError)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "internal/logger/logger_windows.go",
    "content": "//go:build windows\n// +build windows\n\npackage logger\n\nimport (\n\t\"os\"\n\t\"strings\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nconst SupportsColorEscapes = true\n\nvar kernel32 = syscall.NewLazyDLL(\"kernel32.dll\")\nvar getConsoleMode = kernel32.NewProc(\"GetConsoleMode\")\nvar setConsoleTextAttribute = kernel32.NewProc(\"SetConsoleTextAttribute\")\nvar getConsoleScreenBufferInfo = kernel32.NewProc(\"GetConsoleScreenBufferInfo\")\n\ntype consoleScreenBufferInfo struct {\n\tdwSizeX              int16\n\tdwSizeY              int16\n\tdwCursorPositionX    int16\n\tdwCursorPositionY    int16\n\twAttributes          uint16\n\tsrWindowLeft         int16\n\tsrWindowTop          int16\n\tsrWindowRight        int16\n\tsrWindowBottom       int16\n\tdwMaximumWindowSizeX int16\n\tdwMaximumWindowSizeY int16\n}\n\nfunc GetTerminalInfo(file *os.File) TerminalInfo {\n\tfd := file.Fd()\n\n\t// Is this file descriptor a terminal?\n\tvar unused uint32\n\tisTTY, _, _ := syscall.Syscall(getConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&unused)), 0)\n\n\t// Get the width of the window\n\tvar info consoleScreenBufferInfo\n\tsyscall.Syscall(getConsoleScreenBufferInfo.Addr(), 2, fd, uintptr(unsafe.Pointer(&info)), 0)\n\n\treturn TerminalInfo{\n\t\tIsTTY:           isTTY != 0,\n\t\tWidth:           int(info.dwSizeX) - 1,\n\t\tHeight:          int(info.dwSizeY) - 1,\n\t\tUseColorEscapes: !hasNoColorEnvironmentVariable(),\n\t}\n}\n\nconst (\n\tFOREGROUND_BLUE uint8 = 1 << iota\n\tFOREGROUND_GREEN\n\tFOREGROUND_RED\n\tFOREGROUND_INTENSITY\n\tBACKGROUND_BLUE\n\tBACKGROUND_GREEN\n\tBACKGROUND_RED\n\tBACKGROUND_INTENSITY\n)\n\nvar windowsEscapeSequenceMap = map[string]uint8{\n\tTerminalColors.Reset: FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,\n\tTerminalColors.Dim:   FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,\n\tTerminalColors.Bold:  FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,\n\n\t// Apparently underlines only work with the CJK locale on Windows :(\n\tTerminalColors.Underline: FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,\n\n\tTerminalColors.Red:   FOREGROUND_RED,\n\tTerminalColors.Green: FOREGROUND_GREEN,\n\tTerminalColors.Blue:  FOREGROUND_BLUE,\n\n\tTerminalColors.Cyan:    FOREGROUND_GREEN | FOREGROUND_BLUE,\n\tTerminalColors.Magenta: FOREGROUND_RED | FOREGROUND_BLUE,\n\tTerminalColors.Yellow:  FOREGROUND_RED | FOREGROUND_GREEN,\n\n\tTerminalColors.RedBgRed:     FOREGROUND_RED | BACKGROUND_RED,\n\tTerminalColors.RedBgWhite:   FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | BACKGROUND_RED,\n\tTerminalColors.GreenBgGreen: FOREGROUND_GREEN | BACKGROUND_GREEN,\n\tTerminalColors.GreenBgWhite: FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | BACKGROUND_GREEN,\n\tTerminalColors.BlueBgBlue:   FOREGROUND_BLUE | BACKGROUND_BLUE,\n\tTerminalColors.BlueBgWhite:  FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | BACKGROUND_BLUE,\n\n\tTerminalColors.CyanBgCyan:       FOREGROUND_GREEN | FOREGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_BLUE,\n\tTerminalColors.CyanBgBlack:      BACKGROUND_GREEN | BACKGROUND_BLUE,\n\tTerminalColors.MagentaBgMagenta: FOREGROUND_RED | FOREGROUND_BLUE | BACKGROUND_RED | BACKGROUND_BLUE,\n\tTerminalColors.MagentaBgBlack:   BACKGROUND_RED | BACKGROUND_BLUE,\n\tTerminalColors.YellowBgYellow:   FOREGROUND_RED | FOREGROUND_GREEN | BACKGROUND_RED | BACKGROUND_GREEN,\n\tTerminalColors.YellowBgBlack:    BACKGROUND_RED | BACKGROUND_GREEN,\n}\n\nfunc writeStringWithColor(file *os.File, text string) {\n\tfd := file.Fd()\n\ti := 0\n\n\tfor i < len(text) {\n\t\t// Find the escape\n\t\tif text[i] != 033 {\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\n\t\t// Find the 'm'\n\t\twindow := text[i:]\n\t\tif len(window) > 8 {\n\t\t\twindow = window[:8]\n\t\t}\n\t\tm := strings.IndexByte(window, 'm')\n\t\tif m == -1 {\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\t\tm += i + 1\n\n\t\t// Find the escape sequence\n\t\tattributes, ok := windowsEscapeSequenceMap[text[i:m]]\n\t\tif !ok {\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\n\t\t// Write out the text before the escape sequence\n\t\tfile.WriteString(text[:i])\n\n\t\t// Apply the escape sequence\n\t\ttext = text[m:]\n\t\ti = 0\n\t\tsetConsoleTextAttribute.Call(fd, uintptr(attributes))\n\t}\n\n\t// Write out the remaining text\n\tfile.WriteString(text)\n}\n"
  },
  {
    "path": "internal/logger/msg_ids.go",
    "content": "package logger\n\n// Most non-error log messages are given a message ID that can be used to set\n// the log level for that message. Errors do not get a message ID because you\n// cannot turn errors into non-errors (otherwise the build would incorrectly\n// succeed). Some internal log messages do not get a message ID because they\n// are part of verbose and/or internal debugging output. These messages use\n// \"MsgID_None\" instead.\ntype MsgID = uint8\n\nconst (\n\tMsgID_None MsgID = iota\n\n\t// JavaScript\n\tMsgID_JS_AssertToWith\n\tMsgID_JS_AssertTypeJSON\n\tMsgID_JS_AssignToConstant\n\tMsgID_JS_AssignToDefine\n\tMsgID_JS_AssignToImport\n\tMsgID_JS_BigInt\n\tMsgID_JS_CallImportNamespace\n\tMsgID_JS_ClassNameWillThrow\n\tMsgID_JS_CommonJSVariableInESM\n\tMsgID_JS_DeleteSuperProperty\n\tMsgID_JS_DirectEval\n\tMsgID_JS_DuplicateCase\n\tMsgID_JS_DuplicateClassMember\n\tMsgID_JS_DuplicateObjectKey\n\tMsgID_JS_EmptyImportMeta\n\tMsgID_JS_EqualsNaN\n\tMsgID_JS_EqualsNegativeZero\n\tMsgID_JS_EqualsNewObject\n\tMsgID_JS_HTMLCommentInJS\n\tMsgID_JS_ImpossibleTypeof\n\tMsgID_JS_IndirectRequire\n\tMsgID_JS_PrivateNameWillThrow\n\tMsgID_JS_SemicolonAfterReturn\n\tMsgID_JS_SuspiciousBooleanNot\n\tMsgID_JS_SuspiciousDefine\n\tMsgID_JS_SuspiciousLogicalOperator\n\tMsgID_JS_SuspiciousNullishCoalescing\n\tMsgID_JS_ThisIsUndefinedInESM\n\tMsgID_JS_UnsupportedDynamicImport\n\tMsgID_JS_UnsupportedJSXComment\n\tMsgID_JS_UnsupportedRegExp\n\tMsgID_JS_UnsupportedRequireCall\n\n\t// CSS\n\tMsgID_CSS_CSSSyntaxError\n\tMsgID_CSS_InvalidAtCharset\n\tMsgID_CSS_InvalidAtImport\n\tMsgID_CSS_InvalidAtLayer\n\tMsgID_CSS_InvalidCalc\n\tMsgID_CSS_JSCommentInCSS\n\tMsgID_CSS_UndefinedComposesFrom\n\tMsgID_CSS_UnsupportedAtCharset\n\tMsgID_CSS_UnsupportedAtNamespace\n\tMsgID_CSS_UnsupportedCSSProperty\n\tMsgID_CSS_UnsupportedCSSNesting\n\n\t// Bundler\n\tMsgID_Bundler_AmbiguousReexport\n\tMsgID_Bundler_DifferentPathCase\n\tMsgID_Bundler_EmptyGlob\n\tMsgID_Bundler_IgnoredBareImport\n\tMsgID_Bundler_IgnoredDynamicImport\n\tMsgID_Bundler_ImportIsUndefined\n\tMsgID_Bundler_RequireResolveNotExternal\n\n\t// Source maps\n\tMsgID_SourceMap_InvalidSourceMappings\n\tMsgID_SourceMap_MissingSourceMap\n\tMsgID_SourceMap_UnsupportedSourceMapComment\n\n\t// package.json\n\tMsgID_PackageJSON_FIRST // Keep this first\n\tMsgID_PackageJSON_DeadCondition\n\tMsgID_PackageJSON_InvalidBrowser\n\tMsgID_PackageJSON_InvalidImportsOrExports\n\tMsgID_PackageJSON_InvalidSideEffects\n\tMsgID_PackageJSON_InvalidType\n\tMsgID_PackageJSON_LAST // Keep this last\n\n\t// tsconfig.json\n\tMsgID_TSConfigJSON_FIRST // Keep this first\n\tMsgID_TSConfigJSON_Cycle\n\tMsgID_TSConfigJSON_InvalidImportsNotUsedAsValues\n\tMsgID_TSConfigJSON_InvalidJSX\n\tMsgID_TSConfigJSON_InvalidPaths\n\tMsgID_TSConfigJSON_InvalidTarget\n\tMsgID_TSConfigJSON_InvalidTopLevelOption\n\tMsgID_TSConfigJSON_Missing\n\tMsgID_TSConfigJSON_LAST // Keep this last\n\n\tMsgID_END // Keep this at the end (used only for tests)\n)\n\nfunc StringToMsgIDs(str string, logLevel LogLevel, overrides map[MsgID]LogLevel) {\n\tswitch str {\n\t// JS\n\tcase \"assert-to-with\":\n\t\toverrides[MsgID_JS_AssertToWith] = logLevel\n\tcase \"assert-type-json\":\n\t\toverrides[MsgID_JS_AssertTypeJSON] = logLevel\n\tcase \"assign-to-constant\":\n\t\toverrides[MsgID_JS_AssignToConstant] = logLevel\n\tcase \"assign-to-define\":\n\t\toverrides[MsgID_JS_AssignToDefine] = logLevel\n\tcase \"assign-to-import\":\n\t\toverrides[MsgID_JS_AssignToImport] = logLevel\n\tcase \"bigint\":\n\t\toverrides[MsgID_JS_BigInt] = logLevel\n\tcase \"call-import-namespace\":\n\t\toverrides[MsgID_JS_CallImportNamespace] = logLevel\n\tcase \"class-name-will-throw\":\n\t\toverrides[MsgID_JS_ClassNameWillThrow] = logLevel\n\tcase \"commonjs-variable-in-esm\":\n\t\toverrides[MsgID_JS_CommonJSVariableInESM] = logLevel\n\tcase \"delete-super-property\":\n\t\toverrides[MsgID_JS_DeleteSuperProperty] = logLevel\n\tcase \"direct-eval\":\n\t\toverrides[MsgID_JS_DirectEval] = logLevel\n\tcase \"duplicate-case\":\n\t\toverrides[MsgID_JS_DuplicateCase] = logLevel\n\tcase \"duplicate-class-member\":\n\t\toverrides[MsgID_JS_DuplicateClassMember] = logLevel\n\tcase \"duplicate-object-key\":\n\t\toverrides[MsgID_JS_DuplicateObjectKey] = logLevel\n\tcase \"empty-import-meta\":\n\t\toverrides[MsgID_JS_EmptyImportMeta] = logLevel\n\tcase \"equals-nan\":\n\t\toverrides[MsgID_JS_EqualsNaN] = logLevel\n\tcase \"equals-negative-zero\":\n\t\toverrides[MsgID_JS_EqualsNegativeZero] = logLevel\n\tcase \"equals-new-object\":\n\t\toverrides[MsgID_JS_EqualsNewObject] = logLevel\n\tcase \"html-comment-in-js\":\n\t\toverrides[MsgID_JS_HTMLCommentInJS] = logLevel\n\tcase \"impossible-typeof\":\n\t\toverrides[MsgID_JS_ImpossibleTypeof] = logLevel\n\tcase \"indirect-require\":\n\t\toverrides[MsgID_JS_IndirectRequire] = logLevel\n\tcase \"private-name-will-throw\":\n\t\toverrides[MsgID_JS_PrivateNameWillThrow] = logLevel\n\tcase \"semicolon-after-return\":\n\t\toverrides[MsgID_JS_SemicolonAfterReturn] = logLevel\n\tcase \"suspicious-boolean-not\":\n\t\toverrides[MsgID_JS_SuspiciousBooleanNot] = logLevel\n\tcase \"suspicious-define\":\n\t\toverrides[MsgID_JS_SuspiciousDefine] = logLevel\n\tcase \"suspicious-logical-operator\":\n\t\toverrides[MsgID_JS_SuspiciousLogicalOperator] = logLevel\n\tcase \"suspicious-nullish-coalescing\":\n\t\toverrides[MsgID_JS_SuspiciousNullishCoalescing] = logLevel\n\tcase \"this-is-undefined-in-esm\":\n\t\toverrides[MsgID_JS_ThisIsUndefinedInESM] = logLevel\n\tcase \"unsupported-dynamic-import\":\n\t\toverrides[MsgID_JS_UnsupportedDynamicImport] = logLevel\n\tcase \"unsupported-jsx-comment\":\n\t\toverrides[MsgID_JS_UnsupportedJSXComment] = logLevel\n\tcase \"unsupported-regexp\":\n\t\toverrides[MsgID_JS_UnsupportedRegExp] = logLevel\n\tcase \"unsupported-require-call\":\n\t\toverrides[MsgID_JS_UnsupportedRequireCall] = logLevel\n\n\t// CSS\n\tcase \"css-syntax-error\":\n\t\toverrides[MsgID_CSS_CSSSyntaxError] = logLevel\n\tcase \"invalid-@charset\":\n\t\toverrides[MsgID_CSS_InvalidAtCharset] = logLevel\n\tcase \"invalid-@import\":\n\t\toverrides[MsgID_CSS_InvalidAtImport] = logLevel\n\tcase \"invalid-@layer\":\n\t\toverrides[MsgID_CSS_InvalidAtLayer] = logLevel\n\tcase \"invalid-calc\":\n\t\toverrides[MsgID_CSS_InvalidCalc] = logLevel\n\tcase \"js-comment-in-css\":\n\t\toverrides[MsgID_CSS_JSCommentInCSS] = logLevel\n\tcase \"undefined-composes-from\":\n\t\toverrides[MsgID_CSS_UndefinedComposesFrom] = logLevel\n\tcase \"unsupported-@charset\":\n\t\toverrides[MsgID_CSS_UnsupportedAtCharset] = logLevel\n\tcase \"unsupported-@namespace\":\n\t\toverrides[MsgID_CSS_UnsupportedAtNamespace] = logLevel\n\tcase \"unsupported-css-property\":\n\t\toverrides[MsgID_CSS_UnsupportedCSSProperty] = logLevel\n\tcase \"unsupported-css-nesting\":\n\t\toverrides[MsgID_CSS_UnsupportedCSSNesting] = logLevel\n\n\t// Bundler\n\tcase \"ambiguous-reexport\":\n\t\toverrides[MsgID_Bundler_AmbiguousReexport] = logLevel\n\tcase \"different-path-case\":\n\t\toverrides[MsgID_Bundler_DifferentPathCase] = logLevel\n\tcase \"empty-glob\":\n\t\toverrides[MsgID_Bundler_EmptyGlob] = logLevel\n\tcase \"ignored-bare-import\":\n\t\toverrides[MsgID_Bundler_IgnoredBareImport] = logLevel\n\tcase \"ignored-dynamic-import\":\n\t\toverrides[MsgID_Bundler_IgnoredDynamicImport] = logLevel\n\tcase \"import-is-undefined\":\n\t\toverrides[MsgID_Bundler_ImportIsUndefined] = logLevel\n\tcase \"require-resolve-not-external\":\n\t\toverrides[MsgID_Bundler_RequireResolveNotExternal] = logLevel\n\n\t// Source maps\n\tcase \"invalid-source-mappings\":\n\t\toverrides[MsgID_SourceMap_InvalidSourceMappings] = logLevel\n\tcase \"missing-source-map\":\n\t\toverrides[MsgID_SourceMap_MissingSourceMap] = logLevel\n\tcase \"unsupported-source-map-comment\":\n\t\toverrides[MsgID_SourceMap_UnsupportedSourceMapComment] = logLevel\n\n\tcase \"package.json\":\n\t\tfor i := MsgID_PackageJSON_FIRST; i <= MsgID_PackageJSON_LAST; i++ {\n\t\t\toverrides[i] = logLevel\n\t\t}\n\n\tcase \"tsconfig.json\":\n\t\tfor i := MsgID_TSConfigJSON_FIRST; i <= MsgID_TSConfigJSON_LAST; i++ {\n\t\t\toverrides[i] = logLevel\n\t\t}\n\n\tdefault:\n\t\t// Ignore invalid entries since this message id may have\n\t\t// been renamed/removed since when this code was written\n\t}\n}\n\nfunc MsgIDToString(id MsgID) string {\n\tswitch id {\n\t// JS\n\tcase MsgID_JS_AssertToWith:\n\t\treturn \"assert-to-with\"\n\tcase MsgID_JS_AssertTypeJSON:\n\t\treturn \"assert-type-json\"\n\tcase MsgID_JS_AssignToConstant:\n\t\treturn \"assign-to-constant\"\n\tcase MsgID_JS_AssignToDefine:\n\t\treturn \"assign-to-define\"\n\tcase MsgID_JS_AssignToImport:\n\t\treturn \"assign-to-import\"\n\tcase MsgID_JS_BigInt:\n\t\treturn \"bigint\"\n\tcase MsgID_JS_CallImportNamespace:\n\t\treturn \"call-import-namespace\"\n\tcase MsgID_JS_ClassNameWillThrow:\n\t\treturn \"class-name-will-throw\"\n\tcase MsgID_JS_CommonJSVariableInESM:\n\t\treturn \"commonjs-variable-in-esm\"\n\tcase MsgID_JS_DeleteSuperProperty:\n\t\treturn \"delete-super-property\"\n\tcase MsgID_JS_DirectEval:\n\t\treturn \"direct-eval\"\n\tcase MsgID_JS_DuplicateCase:\n\t\treturn \"duplicate-case\"\n\tcase MsgID_JS_DuplicateClassMember:\n\t\treturn \"duplicate-class-member\"\n\tcase MsgID_JS_DuplicateObjectKey:\n\t\treturn \"duplicate-object-key\"\n\tcase MsgID_JS_EmptyImportMeta:\n\t\treturn \"empty-import-meta\"\n\tcase MsgID_JS_EqualsNaN:\n\t\treturn \"equals-nan\"\n\tcase MsgID_JS_EqualsNegativeZero:\n\t\treturn \"equals-negative-zero\"\n\tcase MsgID_JS_EqualsNewObject:\n\t\treturn \"equals-new-object\"\n\tcase MsgID_JS_HTMLCommentInJS:\n\t\treturn \"html-comment-in-js\"\n\tcase MsgID_JS_ImpossibleTypeof:\n\t\treturn \"impossible-typeof\"\n\tcase MsgID_JS_IndirectRequire:\n\t\treturn \"indirect-require\"\n\tcase MsgID_JS_PrivateNameWillThrow:\n\t\treturn \"private-name-will-throw\"\n\tcase MsgID_JS_SemicolonAfterReturn:\n\t\treturn \"semicolon-after-return\"\n\tcase MsgID_JS_SuspiciousBooleanNot:\n\t\treturn \"suspicious-boolean-not\"\n\tcase MsgID_JS_SuspiciousDefine:\n\t\treturn \"suspicious-define\"\n\tcase MsgID_JS_SuspiciousLogicalOperator:\n\t\treturn \"suspicious-logical-operator\"\n\tcase MsgID_JS_SuspiciousNullishCoalescing:\n\t\treturn \"suspicious-nullish-coalescing\"\n\tcase MsgID_JS_ThisIsUndefinedInESM:\n\t\treturn \"this-is-undefined-in-esm\"\n\tcase MsgID_JS_UnsupportedDynamicImport:\n\t\treturn \"unsupported-dynamic-import\"\n\tcase MsgID_JS_UnsupportedJSXComment:\n\t\treturn \"unsupported-jsx-comment\"\n\tcase MsgID_JS_UnsupportedRegExp:\n\t\treturn \"unsupported-regexp\"\n\tcase MsgID_JS_UnsupportedRequireCall:\n\t\treturn \"unsupported-require-call\"\n\n\t// CSS\n\tcase MsgID_CSS_CSSSyntaxError:\n\t\treturn \"css-syntax-error\"\n\tcase MsgID_CSS_InvalidAtCharset:\n\t\treturn \"invalid-@charset\"\n\tcase MsgID_CSS_InvalidAtImport:\n\t\treturn \"invalid-@import\"\n\tcase MsgID_CSS_InvalidAtLayer:\n\t\treturn \"invalid-@layer\"\n\tcase MsgID_CSS_InvalidCalc:\n\t\treturn \"invalid-calc\"\n\tcase MsgID_CSS_JSCommentInCSS:\n\t\treturn \"js-comment-in-css\"\n\tcase MsgID_CSS_UndefinedComposesFrom:\n\t\treturn \"undefined-composes-from\"\n\tcase MsgID_CSS_UnsupportedAtCharset:\n\t\treturn \"unsupported-@charset\"\n\tcase MsgID_CSS_UnsupportedAtNamespace:\n\t\treturn \"unsupported-@namespace\"\n\tcase MsgID_CSS_UnsupportedCSSProperty:\n\t\treturn \"unsupported-css-property\"\n\tcase MsgID_CSS_UnsupportedCSSNesting:\n\t\treturn \"unsupported-css-nesting\"\n\n\t// Bundler\n\tcase MsgID_Bundler_AmbiguousReexport:\n\t\treturn \"ambiguous-reexport\"\n\tcase MsgID_Bundler_DifferentPathCase:\n\t\treturn \"different-path-case\"\n\tcase MsgID_Bundler_EmptyGlob:\n\t\treturn \"empty-glob\"\n\tcase MsgID_Bundler_IgnoredBareImport:\n\t\treturn \"ignored-bare-import\"\n\tcase MsgID_Bundler_IgnoredDynamicImport:\n\t\treturn \"ignored-dynamic-import\"\n\tcase MsgID_Bundler_ImportIsUndefined:\n\t\treturn \"import-is-undefined\"\n\tcase MsgID_Bundler_RequireResolveNotExternal:\n\t\treturn \"require-resolve-not-external\"\n\n\t// Source maps\n\tcase MsgID_SourceMap_InvalidSourceMappings:\n\t\treturn \"invalid-source-mappings\"\n\tcase MsgID_SourceMap_MissingSourceMap:\n\t\treturn \"missing-source-map\"\n\tcase MsgID_SourceMap_UnsupportedSourceMapComment:\n\t\treturn \"unsupported-source-map-comment\"\n\n\tdefault:\n\t\tif id >= MsgID_PackageJSON_FIRST && id <= MsgID_PackageJSON_LAST {\n\t\t\treturn \"package.json\"\n\t\t}\n\t\tif id >= MsgID_TSConfigJSON_FIRST && id <= MsgID_TSConfigJSON_LAST {\n\t\t\treturn \"tsconfig.json\"\n\t\t}\n\t}\n\n\treturn \"\"\n}\n\n// Some message IDs are more diverse internally than externally (in case we\n// want to expand the set of them later on). So just map these to the largest\n// one arbitrarily since you can't tell the difference externally anyway.\nfunc StringToMaximumMsgID(id string) MsgID {\n\toverrides := make(map[MsgID]LogLevel)\n\tmaxID := MsgID_None\n\tStringToMsgIDs(id, LevelInfo, overrides)\n\tfor id := range overrides {\n\t\tif id > maxID {\n\t\t\tmaxID = id\n\t\t}\n\t}\n\treturn maxID\n}\n"
  },
  {
    "path": "internal/renamer/renamer.go",
    "content": "package renamer\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strconv\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/js_lexer\"\n)\n\nfunc ComputeReservedNames(moduleScopes []*js_ast.Scope, symbols ast.SymbolMap) map[string]uint32 {\n\tnames := make(map[string]uint32)\n\n\t// All keywords and strict mode reserved words are reserved names\n\tfor k := range js_lexer.Keywords {\n\t\tnames[k] = 1\n\t}\n\tfor k := range js_lexer.StrictModeReservedWords {\n\t\tnames[k] = 1\n\t}\n\n\t// All unbound symbols must be reserved names\n\tfor _, scope := range moduleScopes {\n\t\tcomputeReservedNamesForScope(scope, symbols, names)\n\t}\n\n\treturn names\n}\n\nfunc computeReservedNamesForScope(scope *js_ast.Scope, symbols ast.SymbolMap, names map[string]uint32) {\n\tfor _, member := range scope.Members {\n\t\tsymbol := symbols.Get(member.Ref)\n\t\tif symbol.Kind == ast.SymbolUnbound || symbol.Flags.Has(ast.MustNotBeRenamed) {\n\t\t\tnames[symbol.OriginalName] = 1\n\t\t}\n\t}\n\tfor _, ref := range scope.Generated {\n\t\tsymbol := symbols.Get(ref)\n\t\tif symbol.Kind == ast.SymbolUnbound || symbol.Flags.Has(ast.MustNotBeRenamed) {\n\t\t\tnames[symbol.OriginalName] = 1\n\t\t}\n\t}\n\n\t// If there's a direct \"eval\" somewhere inside the current scope, continue\n\t// traversing down the scope tree until we find it to get all reserved names\n\tif scope.ContainsDirectEval {\n\t\tfor _, child := range scope.Children {\n\t\t\tif child.ContainsDirectEval {\n\t\t\t\tcomputeReservedNamesForScope(child, symbols, names)\n\t\t\t}\n\t\t}\n\t}\n}\n\ntype Renamer interface {\n\tNameForSymbol(ref ast.Ref) string\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// noOpRenamer\n\ntype noOpRenamer struct {\n\tsymbols ast.SymbolMap\n}\n\nfunc NewNoOpRenamer(symbols ast.SymbolMap) Renamer {\n\treturn &noOpRenamer{\n\t\tsymbols: symbols,\n\t}\n}\n\nfunc (r *noOpRenamer) NameForSymbol(ref ast.Ref) string {\n\tref = ast.FollowSymbols(r.symbols, ref)\n\treturn r.symbols.Get(ref).OriginalName\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// MinifyRenamer\n\ntype symbolSlot struct {\n\tname               string\n\tcount              uint32\n\tneedsCapitalForJSX uint32 // This is really a bool but needs to be atomic\n}\n\ntype MinifyRenamer struct {\n\treservedNames        map[string]uint32\n\tslots                [4][]symbolSlot\n\ttopLevelSymbolToSlot map[ast.Ref]uint32\n\tsymbols              ast.SymbolMap\n}\n\nfunc NewMinifyRenamer(symbols ast.SymbolMap, firstTopLevelSlots ast.SlotCounts, reservedNames map[string]uint32) *MinifyRenamer {\n\treturn &MinifyRenamer{\n\t\tsymbols:       symbols,\n\t\treservedNames: reservedNames,\n\t\tslots: [4][]symbolSlot{\n\t\t\tmake([]symbolSlot, firstTopLevelSlots[0]),\n\t\t\tmake([]symbolSlot, firstTopLevelSlots[1]),\n\t\t\tmake([]symbolSlot, firstTopLevelSlots[2]),\n\t\t\tmake([]symbolSlot, firstTopLevelSlots[3]),\n\t\t},\n\t\ttopLevelSymbolToSlot: make(map[ast.Ref]uint32),\n\t}\n}\n\nfunc (r *MinifyRenamer) NameForSymbol(ref ast.Ref) string {\n\t// Follow links to get to the underlying symbol\n\tref = ast.FollowSymbols(r.symbols, ref)\n\tsymbol := r.symbols.Get(ref)\n\n\t// Skip this symbol if the name is pinned\n\tns := symbol.SlotNamespace()\n\tif ns == ast.SlotMustNotBeRenamed {\n\t\treturn symbol.OriginalName\n\t}\n\n\t// Check if it's a nested scope symbol\n\ti := symbol.NestedScopeSlot\n\n\t// If it's not (i.e. it's in a top-level scope), look up the slot\n\tif !i.IsValid() {\n\t\tindex, ok := r.topLevelSymbolToSlot[ref]\n\t\tif !ok {\n\t\t\t// If we get here, then we're printing a symbol that never had any\n\t\t\t// recorded uses. This is odd but can happen in certain scenarios.\n\t\t\t// For example, code in a branch with dead control flow won't mark\n\t\t\t// any uses but may still be printed. In that case it doesn't matter\n\t\t\t// what name we use since it's dead code.\n\t\t\treturn symbol.OriginalName\n\t\t}\n\t\ti = ast.MakeIndex32(index)\n\t}\n\n\treturn r.slots[ns][i.GetIndex()].name\n}\n\n// The InnerIndex should be stable because the parser for a single file is\n// single-threaded and deterministically assigns out InnerIndex values\n// sequentially. But the SourceIndex should be unstable because the main thread\n// assigns out source index values sequentially to newly-discovered dependencies\n// in a multi-threaded producer/consumer relationship. So instead we use the\n// index of the source in the DFS order over all entry points for stability.\ntype StableSymbolCount struct {\n\tStableSourceIndex uint32\n\tRef               ast.Ref\n\tCount             uint32\n}\n\n// This type is just so we can use Go's native sort function\ntype StableSymbolCountArray []StableSymbolCount\n\nfunc (a StableSymbolCountArray) Len() int          { return len(a) }\nfunc (a StableSymbolCountArray) Swap(i int, j int) { a[i], a[j] = a[j], a[i] }\n\nfunc (a StableSymbolCountArray) Less(i int, j int) bool {\n\tai, aj := a[i], a[j]\n\tif ai.Count > aj.Count {\n\t\treturn true\n\t}\n\tif ai.Count < aj.Count {\n\t\treturn false\n\t}\n\tif ai.StableSourceIndex < aj.StableSourceIndex {\n\t\treturn true\n\t}\n\tif ai.StableSourceIndex > aj.StableSourceIndex {\n\t\treturn false\n\t}\n\treturn ai.Ref.InnerIndex < aj.Ref.InnerIndex\n}\n\nfunc (r *MinifyRenamer) AccumulateSymbolUseCounts(\n\ttopLevelSymbols *StableSymbolCountArray,\n\tsymbolUses map[ast.Ref]js_ast.SymbolUse,\n\tstableSourceIndices []uint32,\n) {\n\t// NOTE: This function is run in parallel. Make sure to avoid data races.\n\n\tfor ref, use := range symbolUses {\n\t\tr.AccumulateSymbolCount(topLevelSymbols, ref, use.CountEstimate, stableSourceIndices)\n\t}\n}\n\nfunc (r *MinifyRenamer) AccumulateSymbolCount(\n\ttopLevelSymbols *StableSymbolCountArray,\n\tref ast.Ref,\n\tcount uint32,\n\tstableSourceIndices []uint32,\n) {\n\t// NOTE: This function is run in parallel. Make sure to avoid data races.\n\n\t// Follow links to get to the underlying symbol\n\tref = ast.FollowSymbols(r.symbols, ref)\n\tsymbol := r.symbols.Get(ref)\n\tfor symbol.NamespaceAlias != nil {\n\t\tref = ast.FollowSymbols(r.symbols, symbol.NamespaceAlias.NamespaceRef)\n\t\tsymbol = r.symbols.Get(ref)\n\t}\n\n\t// Skip this symbol if the name is pinned\n\tns := symbol.SlotNamespace()\n\tif ns == ast.SlotMustNotBeRenamed {\n\t\treturn\n\t}\n\n\t// Check if it's a nested scope symbol\n\tif i := symbol.NestedScopeSlot; i.IsValid() {\n\t\t// If it is, accumulate the count using a parallel-safe atomic increment\n\t\tslot := &r.slots[ns][i.GetIndex()]\n\t\tatomic.AddUint32(&slot.count, count)\n\t\tif symbol.Flags.Has(ast.MustStartWithCapitalLetterForJSX) {\n\t\t\tatomic.StoreUint32(&slot.needsCapitalForJSX, 1)\n\t\t}\n\t\treturn\n\t}\n\n\t// If it's a top-level symbol, defer it to later since we have\n\t// to allocate slots for these in serial instead of in parallel\n\t*topLevelSymbols = append(*topLevelSymbols, StableSymbolCount{\n\t\tStableSourceIndex: stableSourceIndices[ref.SourceIndex],\n\t\tRef:               ref,\n\t\tCount:             count,\n\t})\n}\n\n// The parallel part of the symbol count accumulation algorithm above processes\n// nested symbols and generates an array of top-level symbols to process later.\n// After the parallel part has finished, that array of top-level symbols is passed\n// to this function which processes them in serial.\nfunc (r *MinifyRenamer) AllocateTopLevelSymbolSlots(topLevelSymbols StableSymbolCountArray) {\n\tfor _, stable := range topLevelSymbols {\n\t\tsymbol := r.symbols.Get(stable.Ref)\n\t\tslots := &r.slots[symbol.SlotNamespace()]\n\t\tif i, ok := r.topLevelSymbolToSlot[stable.Ref]; ok {\n\t\t\tslot := &(*slots)[i]\n\t\t\tslot.count += stable.Count\n\t\t\tif symbol.Flags.Has(ast.MustStartWithCapitalLetterForJSX) {\n\t\t\t\tslot.needsCapitalForJSX = 1\n\t\t\t}\n\t\t} else {\n\t\t\tneedsCapitalForJSX := uint32(0)\n\t\t\tif symbol.Flags.Has(ast.MustStartWithCapitalLetterForJSX) {\n\t\t\t\tneedsCapitalForJSX = 1\n\t\t\t}\n\t\t\ti = uint32(len(*slots))\n\t\t\t*slots = append(*slots, symbolSlot{\n\t\t\t\tcount:              stable.Count,\n\t\t\t\tneedsCapitalForJSX: needsCapitalForJSX,\n\t\t\t})\n\t\t\tr.topLevelSymbolToSlot[stable.Ref] = i\n\t\t}\n\t}\n}\n\nfunc (r *MinifyRenamer) AssignNamesByFrequency(minifier *ast.NameMinifier) {\n\tfor ns, slots := range r.slots {\n\t\t// Sort symbols by count\n\t\tsorted := make(slotAndCountArray, len(slots))\n\t\tfor i, item := range slots {\n\t\t\tsorted[i] = slotAndCount{slot: uint32(i), count: item.count}\n\t\t}\n\t\tsort.Sort(sorted)\n\n\t\t// Assign names to symbols\n\t\tnextName := 0\n\t\tfor _, data := range sorted {\n\t\t\tslot := &slots[data.slot]\n\t\t\tname := minifier.NumberToMinifiedName(nextName)\n\t\t\tnextName++\n\n\t\t\t// Make sure we never generate a reserved name. We only have to worry\n\t\t\t// about collisions with reserved identifiers for normal symbols, and we\n\t\t\t// only have to worry about collisions with keywords for labels. We do\n\t\t\t// not have to worry about either for private names because they start\n\t\t\t// with a \"#\" character.\n\t\t\tswitch ast.SlotNamespace(ns) {\n\t\t\tcase ast.SlotDefault:\n\t\t\t\tfor r.reservedNames[name] != 0 {\n\t\t\t\t\tname = minifier.NumberToMinifiedName(nextName)\n\t\t\t\t\tnextName++\n\t\t\t\t}\n\n\t\t\t\t// Make sure names of symbols used in JSX elements start with a capital letter\n\t\t\t\tif slot.needsCapitalForJSX != 0 {\n\t\t\t\t\tfor name[0] >= 'a' && name[0] <= 'z' {\n\t\t\t\t\t\tname = minifier.NumberToMinifiedName(nextName)\n\t\t\t\t\t\tnextName++\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tcase ast.SlotLabel:\n\t\t\t\tfor js_lexer.Keywords[name] != 0 {\n\t\t\t\t\tname = minifier.NumberToMinifiedName(nextName)\n\t\t\t\t\tnextName++\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Private names must be prefixed with \"#\"\n\t\t\tif ast.SlotNamespace(ns) == ast.SlotPrivateName {\n\t\t\t\tname = \"#\" + name\n\t\t\t}\n\n\t\t\tslot.name = name\n\t\t}\n\t}\n}\n\n// Returns the number of nested slots\nfunc AssignNestedScopeSlots(moduleScope *js_ast.Scope, symbols []ast.Symbol) (slotCounts ast.SlotCounts) {\n\t// Temporarily set the nested scope slots of top-level symbols to valid so\n\t// they aren't renamed in nested scopes. This prevents us from accidentally\n\t// assigning nested scope slots to variables declared using \"var\" in a nested\n\t// scope that are actually hoisted up to the module scope to become a top-\n\t// level symbol.\n\tvalidSlot := ast.MakeIndex32(1)\n\tfor _, member := range moduleScope.Members {\n\t\tsymbols[member.Ref.InnerIndex].NestedScopeSlot = validSlot\n\t}\n\tfor _, ref := range moduleScope.Generated {\n\t\tsymbols[ref.InnerIndex].NestedScopeSlot = validSlot\n\t}\n\n\t// Assign nested scope slots independently for each nested scope\n\tfor _, child := range moduleScope.Children {\n\t\tslotCounts.UnionMax(assignNestedScopeSlotsHelper(child, symbols, ast.SlotCounts{}))\n\t}\n\n\t// Then set the nested scope slots of top-level symbols back to zero. Top-\n\t// level symbols are not supposed to have nested scope slots.\n\tfor _, member := range moduleScope.Members {\n\t\tsymbols[member.Ref.InnerIndex].NestedScopeSlot = ast.Index32{}\n\t}\n\tfor _, ref := range moduleScope.Generated {\n\t\tsymbols[ref.InnerIndex].NestedScopeSlot = ast.Index32{}\n\t}\n\treturn\n}\n\nfunc assignNestedScopeSlotsHelper(scope *js_ast.Scope, symbols []ast.Symbol, slot ast.SlotCounts) ast.SlotCounts {\n\t// Sort member map keys for determinism\n\tsortedMembers := make([]int, 0, len(scope.Members))\n\tfor _, member := range scope.Members {\n\t\tsortedMembers = append(sortedMembers, int(member.Ref.InnerIndex))\n\t}\n\tsort.Ints(sortedMembers)\n\n\t// Assign slots for this scope's symbols. Only do this if the slot is\n\t// not already assigned. Nested scopes have copies of symbols from parent\n\t// scopes and we want to use the slot from the parent scope, not child scopes.\n\tfor _, innerIndex := range sortedMembers {\n\t\tsymbol := &symbols[innerIndex]\n\t\tif ns := symbol.SlotNamespace(); ns != ast.SlotMustNotBeRenamed && !symbol.NestedScopeSlot.IsValid() {\n\t\t\tsymbol.NestedScopeSlot = ast.MakeIndex32(slot[ns])\n\t\t\tslot[ns]++\n\t\t}\n\t}\n\tfor _, ref := range scope.Generated {\n\t\tsymbol := &symbols[ref.InnerIndex]\n\t\tif ns := symbol.SlotNamespace(); ns != ast.SlotMustNotBeRenamed && !symbol.NestedScopeSlot.IsValid() {\n\t\t\tsymbol.NestedScopeSlot = ast.MakeIndex32(slot[ns])\n\t\t\tslot[ns]++\n\t\t}\n\t}\n\n\t// Labels are always declared in a nested scope, so we don't need to check.\n\tif scope.Label.Ref != ast.InvalidRef {\n\t\tsymbol := &symbols[scope.Label.Ref.InnerIndex]\n\t\tsymbol.NestedScopeSlot = ast.MakeIndex32(slot[ast.SlotLabel])\n\t\tslot[ast.SlotLabel]++\n\t}\n\n\t// Assign slots for the symbols of child scopes\n\tslotCounts := slot\n\tfor _, child := range scope.Children {\n\t\tslotCounts.UnionMax(assignNestedScopeSlotsHelper(child, symbols, slot))\n\t}\n\treturn slotCounts\n}\n\ntype slotAndCount struct {\n\tslot  uint32\n\tcount uint32\n}\n\n// This type is just so we can use Go's native sort function\ntype slotAndCountArray []slotAndCount\n\nfunc (a slotAndCountArray) Len() int          { return len(a) }\nfunc (a slotAndCountArray) Swap(i int, j int) { a[i], a[j] = a[j], a[i] }\nfunc (a slotAndCountArray) Less(i int, j int) bool {\n\tai, aj := a[i], a[j]\n\treturn ai.count > aj.count || (ai.count == aj.count && ai.slot < aj.slot)\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// NumberRenamer\n\ntype NumberRenamer struct {\n\tsymbols ast.SymbolMap\n\troot    numberScope\n\tnames   [][]string\n}\n\nfunc NewNumberRenamer(symbols ast.SymbolMap, reservedNames map[string]uint32) *NumberRenamer {\n\treturn &NumberRenamer{\n\t\tsymbols: symbols,\n\t\tnames:   make([][]string, len(symbols.SymbolsForSource)),\n\t\troot:    numberScope{nameCounts: reservedNames},\n\t}\n}\n\nfunc (r *NumberRenamer) NameForSymbol(ref ast.Ref) string {\n\tref = ast.FollowSymbols(r.symbols, ref)\n\tif inner := r.names[ref.SourceIndex]; inner != nil {\n\t\tif name := inner[ref.InnerIndex]; name != \"\" {\n\t\t\treturn name\n\t\t}\n\t}\n\treturn r.symbols.Get(ref).OriginalName\n}\n\nfunc (r *NumberRenamer) AddTopLevelSymbol(ref ast.Ref) {\n\tr.assignName(&r.root, ref)\n}\n\nfunc (r *NumberRenamer) assignName(scope *numberScope, ref ast.Ref) {\n\tref = ast.FollowSymbols(r.symbols, ref)\n\n\t// Don't rename the same symbol more than once\n\tinner := r.names[ref.SourceIndex]\n\tif inner != nil && inner[ref.InnerIndex] != \"\" {\n\t\treturn\n\t}\n\n\t// Don't rename unbound symbols, symbols marked as reserved names, labels, or private names\n\tsymbol := r.symbols.Get(ref)\n\tns := symbol.SlotNamespace()\n\tif ns != ast.SlotDefault && ns != ast.SlotPrivateName {\n\t\treturn\n\t}\n\n\t// Make sure names of symbols used in JSX elements start with a capital letter\n\toriginalName := symbol.OriginalName\n\tif symbol.Flags.Has(ast.MustStartWithCapitalLetterForJSX) {\n\t\tif first := rune(originalName[0]); first >= 'a' && first <= 'z' {\n\t\t\toriginalName = fmt.Sprintf(\"%c%s\", first+('A'-'a'), originalName[1:])\n\t\t}\n\t}\n\n\t// Compute a new name\n\tname := scope.findUnusedName(originalName, ns)\n\n\t// Store the new name\n\tif inner == nil {\n\t\t// Note: This should not be a data race even though this method is run from\n\t\t// multiple threads. The parallel part only looks at symbols defined in\n\t\t// nested scopes, and those can only ever be accessed from within the file.\n\t\t// References to those symbols should never spread across files.\n\t\t//\n\t\t// While we could avoid the data race by densely preallocating the entire\n\t\t// \"names\" array ahead of time, that will waste a lot more memory for\n\t\t// builds that make heavy use of code splitting and have many chunks. Doing\n\t\t// things lazily like this means we use less memory but still stay safe.\n\t\tinner = make([]string, len(r.symbols.SymbolsForSource[ref.SourceIndex]))\n\t\tr.names[ref.SourceIndex] = inner\n\t}\n\tinner[ref.InnerIndex] = name\n}\n\nfunc (r *NumberRenamer) assignNamesInScope(scope *js_ast.Scope, sourceIndex uint32, parent *numberScope, sorted *[]int) *numberScope {\n\ts := &numberScope{parent: parent, nameCounts: make(map[string]uint32)}\n\n\tif len(scope.Members) > 0 {\n\t\t// Sort member map keys for determinism, reusing a shared memory buffer\n\t\t*sorted = (*sorted)[:0]\n\t\tfor _, member := range scope.Members {\n\t\t\t*sorted = append(*sorted, int(member.Ref.InnerIndex))\n\t\t}\n\t\tsort.Ints(*sorted)\n\n\t\t// Rename all user-defined symbols in this scope\n\t\tfor _, innerIndex := range *sorted {\n\t\t\tr.assignName(s, ast.Ref{SourceIndex: sourceIndex, InnerIndex: uint32(innerIndex)})\n\t\t}\n\t}\n\n\t// Also rename all generated symbols in this scope\n\tfor _, ref := range scope.Generated {\n\t\tr.assignName(s, ref)\n\t}\n\n\treturn s\n}\n\nfunc (r *NumberRenamer) assignNamesRecursive(scope *js_ast.Scope, sourceIndex uint32, parent *numberScope, sorted *[]int) {\n\t// For performance in extreme cases (e.g. 10,000 nested scopes), traversing\n\t// through singly-nested scopes uses iteration instead of recursion\n\tfor {\n\t\tif len(scope.Members) > 0 || len(scope.Generated) > 0 {\n\t\t\t// For performance in extreme cases (e.g. 10,000 nested scopes), only\n\t\t\t// allocate a scope when it's necessary. I'm not quite sure why allocating\n\t\t\t// one scope per level is so much overhead. It's not that many objects.\n\t\t\t// Or at least there are already that many objects for the AST that we're\n\t\t\t// traversing, so I don't know why 80% of the time in these extreme cases\n\t\t\t// is taken by this function (if we don't avoid this allocation).\n\t\t\tparent = r.assignNamesInScope(scope, sourceIndex, parent, sorted)\n\t\t}\n\t\tif children := scope.Children; len(children) == 1 {\n\t\t\tscope = children[0]\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Symbols in child scopes may also have to be renamed to avoid conflicts\n\tfor _, child := range scope.Children {\n\t\tr.assignNamesRecursive(child, sourceIndex, parent, sorted)\n\t}\n}\n\nfunc (r *NumberRenamer) AssignNamesByScope(nestedScopes map[uint32][]*js_ast.Scope) {\n\twaitGroup := sync.WaitGroup{}\n\twaitGroup.Add(len(nestedScopes))\n\n\t// Rename nested scopes from separate files in parallel\n\tfor sourceIndex, scopes := range nestedScopes {\n\t\tgo func(sourceIndex uint32, scopes []*js_ast.Scope) {\n\t\t\tvar sorted []int\n\t\t\tfor _, scope := range scopes {\n\t\t\t\tr.assignNamesRecursive(scope, sourceIndex, &r.root, &sorted)\n\t\t\t}\n\t\t\twaitGroup.Done()\n\t\t}(sourceIndex, scopes)\n\t}\n\n\twaitGroup.Wait()\n}\n\ntype numberScope struct {\n\tparent *numberScope\n\n\t// This is used as a set of used names in this scope. This also maps the name\n\t// to the number of times the name has experienced a collision. When a name\n\t// collides with an already-used name, we need to rename it. This is done by\n\t// incrementing a number at the end until the name is unused. We save the\n\t// count here so that subsequent collisions can start counting from where the\n\t// previous collision ended instead of having to start counting from 1.\n\tnameCounts map[string]uint32\n}\n\ntype nameUse uint8\n\nconst (\n\tnameUnused nameUse = iota\n\tnameUsed\n\tnameUsedInSameScope\n)\n\nfunc (s *numberScope) findNameUse(name string) nameUse {\n\toriginal := s\n\tfor {\n\t\tif _, ok := s.nameCounts[name]; ok {\n\t\t\tif s == original {\n\t\t\t\treturn nameUsedInSameScope\n\t\t\t}\n\t\t\treturn nameUsed\n\t\t}\n\t\ts = s.parent\n\t\tif s == nil {\n\t\t\treturn nameUnused\n\t\t}\n\t}\n}\n\nfunc (s *numberScope) findUnusedName(name string, ns ast.SlotNamespace) string {\n\t// We may not have a valid identifier if this is an internally-constructed name\n\tif ns == ast.SlotPrivateName {\n\t\tif id := name[1:]; !js_ast.IsIdentifier(id) {\n\t\t\tname = js_ast.ForceValidIdentifier(\"#\", id)\n\t\t}\n\t} else {\n\t\tif !js_ast.IsIdentifier(name) {\n\t\t\tname = js_ast.ForceValidIdentifier(\"\", name)\n\t\t}\n\t}\n\n\tif use := s.findNameUse(name); use != nameUnused {\n\t\t// If the name is already in use, generate a new name by appending a number\n\t\ttries := uint32(1)\n\t\tif use == nameUsedInSameScope {\n\t\t\t// To avoid O(n^2) behavior, the number must start off being the number\n\t\t\t// that we used last time there was a collision with this name. Otherwise\n\t\t\t// if there are many collisions with the same name, each name collision\n\t\t\t// would have to increment the counter past all previous name collisions\n\t\t\t// which is a O(n^2) time algorithm. Only do this if this symbol comes\n\t\t\t// from the same scope as the previous one since sibling scopes can reuse\n\t\t\t// the same name without problems.\n\t\t\ttries = s.nameCounts[name]\n\t\t}\n\t\tprefix := name\n\n\t\t// Keep incrementing the number until the name is unused\n\t\tfor {\n\t\t\ttries++\n\t\t\tname = prefix + strconv.Itoa(int(tries))\n\n\t\t\t// Make sure this new name is unused\n\t\t\tif s.findNameUse(name) == nameUnused {\n\t\t\t\t// Store the count so we can start here next time instead of starting\n\t\t\t\t// from 1. This means we avoid O(n^2) behavior.\n\t\t\t\tif use == nameUsedInSameScope {\n\t\t\t\t\ts.nameCounts[prefix] = tries\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\t// Each name starts off with a count of 1 so that the first collision with\n\t// \"name\" is called \"name2\"\n\ts.nameCounts[name] = 1\n\treturn name\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// ExportRenamer\n\ntype ExportRenamer struct {\n\tused  map[string]uint32\n\tcount int\n}\n\nfunc (r *ExportRenamer) NextRenamedName(name string) string {\n\tif r.used == nil {\n\t\tr.used = make(map[string]uint32)\n\t}\n\tif tries, ok := r.used[name]; ok {\n\t\tprefix := name\n\t\tfor {\n\t\t\ttries++\n\t\t\tname = prefix + strconv.Itoa(int(tries))\n\t\t\tif _, ok := r.used[name]; !ok {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tr.used[name] = tries\n\t} else {\n\t\tr.used[name] = 1\n\t}\n\treturn name\n}\n\nfunc (r *ExportRenamer) NextMinifiedName() string {\n\tname := ast.DefaultNameMinifierJS.NumberToMinifiedName(r.count)\n\tr.count++\n\treturn name\n}\n"
  },
  {
    "path": "internal/resolver/dataurl.go",
    "content": "package resolver\n\nimport (\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"strings\"\n)\n\ntype DataURL struct {\n\tmimeType string\n\tdata     string\n\tisBase64 bool\n}\n\nfunc ParseDataURL(url string) (parsed DataURL, ok bool) {\n\tif strings.HasPrefix(url, \"data:\") {\n\t\tif comma := strings.IndexByte(url, ','); comma != -1 {\n\t\t\tparsed.mimeType = url[len(\"data:\"):comma]\n\t\t\tparsed.data = url[comma+1:]\n\t\t\tif strings.HasSuffix(parsed.mimeType, \";base64\") {\n\t\t\t\tparsed.mimeType = parsed.mimeType[:len(parsed.mimeType)-len(\";base64\")]\n\t\t\t\tparsed.isBase64 = true\n\t\t\t}\n\t\t\tok = true\n\t\t}\n\t}\n\treturn\n}\n\ntype MIMEType uint8\n\nconst (\n\tMIMETypeUnsupported MIMEType = iota\n\tMIMETypeTextCSS\n\tMIMETypeTextJavaScript\n\tMIMETypeApplicationJSON\n)\n\nfunc (parsed DataURL) DecodeMIMEType() MIMEType {\n\t// Remove things like \";charset=utf-8\"\n\tmimeType := parsed.mimeType\n\tif semicolon := strings.IndexByte(mimeType, ';'); semicolon != -1 {\n\t\tmimeType = mimeType[:semicolon]\n\t}\n\n\t// Hard-code a few supported types\n\tswitch mimeType {\n\tcase \"text/css\":\n\t\treturn MIMETypeTextCSS\n\tcase \"text/javascript\":\n\t\treturn MIMETypeTextJavaScript\n\tcase \"application/json\":\n\t\treturn MIMETypeApplicationJSON\n\tdefault:\n\t\treturn MIMETypeUnsupported\n\t}\n}\n\nfunc (parsed DataURL) DecodeData() (string, error) {\n\t// Try to read base64 data\n\tif parsed.isBase64 {\n\t\tbytes, err := base64.StdEncoding.DecodeString(parsed.data)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"could not decode base64 data: %s\", err.Error())\n\t\t}\n\t\treturn string(bytes), nil\n\t}\n\n\t// Try to read percent-escaped data\n\tcontent, err := url.PathUnescape(parsed.data)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"could not decode percent-escaped data: %s\", err.Error())\n\t}\n\treturn content, nil\n}\n"
  },
  {
    "path": "internal/resolver/package_json.go",
    "content": "package resolver\n\nimport (\n\t\"fmt\"\n\t\"net/url\"\n\t\"path\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/js_lexer\"\n\t\"github.com/evanw/esbuild/internal/js_parser\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\ntype packageJSON struct {\n\tname           string\n\tmainFields     map[string]mainField\n\tmoduleTypeData js_ast.ModuleTypeData\n\n\t// \"TypeScript will first check whether package.json contains a \"tsconfig\"\n\t// field, and if it does, TypeScript will try to load a configuration file\n\t// from that field. If neither exists, TypeScript will try to read from a\n\t// tsconfig.json at the root.\"\n\t//\n\t// See: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-2.html#tsconfigjson-inheritance-via-nodejs-packages\n\ttsconfig string\n\n\t// Present if the \"browser\" field is present. This field is intended to be\n\t// used by bundlers and lets you redirect the paths of certain 3rd-party\n\t// modules that don't work in the browser to other modules that shim that\n\t// functionality. That way you don't have to rewrite the code for those 3rd-\n\t// party modules. For example, you might remap the native \"util\" node module\n\t// to something like https://www.npmjs.com/package/util so it works in the\n\t// browser.\n\t//\n\t// This field contains the original mapping object in \"package.json\". Mapping\n\t// to a nil path indicates that the module is disabled. As far as I can\n\t// tell, the official spec is an abandoned GitHub repo hosted by a user account:\n\t// https://github.com/defunctzombie/package-browser-field-spec. The npm docs\n\t// say almost nothing: https://docs.npmjs.com/files/package.json.\n\t//\n\t// Note that the non-package \"browser\" map has to be checked twice to match\n\t// Webpack's behavior: once before resolution and once after resolution. It\n\t// leads to some unintuitive failure cases that we must emulate around missing\n\t// file extensions:\n\t//\n\t// * Given the mapping \"./no-ext\": \"./no-ext-browser.js\" the query \"./no-ext\"\n\t//   should match but the query \"./no-ext.js\" should NOT match.\n\t//\n\t// * Given the mapping \"./ext.js\": \"./ext-browser.js\" the query \"./ext.js\"\n\t//   should match and the query \"./ext\" should ALSO match.\n\t//\n\tbrowserMap map[string]*string\n\n\t// If this is non-nil, each entry in this map is the absolute path of a file\n\t// with side effects. Any entry not in this map should be considered to have\n\t// no side effects, which means import statements for these files can be\n\t// removed if none of the imports are used. This is a convention from Webpack:\n\t// https://webpack.js.org/guides/tree-shaking/.\n\t//\n\t// Note that if a file is included, all statements that can't be proven to be\n\t// free of side effects must be included. This convention does not say\n\t// anything about whether any statements within the file have side effects or\n\t// not.\n\tsideEffectsMap     map[string]bool\n\tsideEffectsRegexps []*regexp.Regexp\n\tsideEffectsData    *SideEffectsData\n\n\t// This represents the \"imports\" field in this package.json file.\n\timportsMap *pjMap\n\n\t// This represents the \"exports\" field in this package.json file.\n\texportsMap *pjMap\n\n\tsource logger.Source\n}\n\ntype mainField struct {\n\trelPath string\n\tkeyLoc  logger.Loc\n}\n\ntype browserPathKind uint8\n\nconst (\n\tabsolutePathKind browserPathKind = iota\n\tpackagePathKind\n)\n\nfunc (r resolverQuery) checkBrowserMap(resolveDirInfo *dirInfo, inputPath string, kind browserPathKind) (remapped *string, ok bool) {\n\t// This only applies if the current platform is \"browser\"\n\tif r.options.Platform != config.PlatformBrowser {\n\t\treturn nil, false\n\t}\n\n\t// There must be an enclosing directory with a \"package.json\" file with a \"browser\" map\n\tif resolveDirInfo.enclosingBrowserScope == nil {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"No \\\"browser\\\" map found in directory %q\", resolveDirInfo.absPath))\n\t\t}\n\t\treturn nil, false\n\t}\n\n\tpackageJSON := resolveDirInfo.enclosingBrowserScope.packageJSON\n\tbrowserMap := packageJSON.browserMap\n\n\ttype implicitExtensions uint8\n\n\tconst (\n\t\tincludeImplicitExtensions implicitExtensions = iota\n\t\tskipImplicitExtensions\n\t)\n\n\tcheckPath := func(pathToCheck string, implicitExtensions implicitExtensions) bool {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Checking for %q in the \\\"browser\\\" map in %q\",\n\t\t\t\tpathToCheck, packageJSON.source.KeyPath.Text))\n\t\t}\n\n\t\t// Check for equality\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Checking for %q\", pathToCheck))\n\t\t}\n\t\tremapped, ok = browserMap[pathToCheck]\n\t\tif ok {\n\t\t\tinputPath = pathToCheck\n\t\t\treturn true\n\t\t}\n\n\t\t// If that failed, try adding implicit extensions\n\t\tif implicitExtensions == includeImplicitExtensions {\n\t\t\tfor _, ext := range r.options.ExtensionOrder {\n\t\t\t\textPath := pathToCheck + ext\n\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Checking for %q\", extPath))\n\t\t\t\t}\n\t\t\t\tremapped, ok = browserMap[extPath]\n\t\t\t\tif ok {\n\t\t\t\t\tinputPath = extPath\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If that failed, try assuming this is a directory and looking for an \"index\" file\n\t\tindexPath := path.Join(pathToCheck, \"index\")\n\t\tif IsPackagePath(indexPath) && !IsPackagePath(pathToCheck) {\n\t\t\tindexPath = \"./\" + indexPath\n\t\t}\n\n\t\t// Check for equality\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Checking for %q\", indexPath))\n\t\t}\n\t\tremapped, ok = browserMap[indexPath]\n\t\tif ok {\n\t\t\tinputPath = indexPath\n\t\t\treturn true\n\t\t}\n\n\t\t// If that failed, try adding implicit extensions\n\t\tif implicitExtensions == includeImplicitExtensions {\n\t\t\tfor _, ext := range r.options.ExtensionOrder {\n\t\t\t\textPath := indexPath + ext\n\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Checking for %q\", extPath))\n\t\t\t\t}\n\t\t\t\tremapped, ok = browserMap[extPath]\n\t\t\t\tif ok {\n\t\t\t\t\tinputPath = extPath\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn false\n\t}\n\n\t// Turn absolute paths into paths relative to the \"browser\" map location\n\tif kind == absolutePathKind {\n\t\trelPath, ok := r.fs.Rel(resolveDirInfo.enclosingBrowserScope.absPath, inputPath)\n\t\tif !ok {\n\t\t\treturn nil, false\n\t\t}\n\t\tinputPath = strings.ReplaceAll(relPath, \"\\\\\", \"/\")\n\t}\n\n\tif inputPath == \".\" {\n\t\t// No bundler supports remapping \".\", so we don't either\n\t\treturn nil, false\n\t}\n\n\t// First try the import path as a package path\n\tif !checkPath(inputPath, includeImplicitExtensions) && IsPackagePath(inputPath) {\n\t\t// If a package path didn't work, try the import path as a relative path\n\t\tswitch kind {\n\t\tcase absolutePathKind:\n\t\t\tcheckPath(\"./\"+inputPath, includeImplicitExtensions)\n\n\t\tcase packagePathKind:\n\t\t\t// Browserify allows a browser map entry of \"./pkg\" to override a package\n\t\t\t// path of \"require('pkg')\". This is weird, and arguably a bug. But we\n\t\t\t// replicate this bug for compatibility. However, Browserify only allows\n\t\t\t// this within the same package. It does not allow such an entry in a\n\t\t\t// parent package to override this in a child package. So this behavior\n\t\t\t// is disallowed if there is a \"node_modules\" folder in between the child\n\t\t\t// package and the parent package.\n\t\t\tisInSamePackage := true\n\t\t\tfor info := resolveDirInfo; info != nil && info != resolveDirInfo.enclosingBrowserScope; info = info.parent {\n\t\t\t\tif info.isNodeModules {\n\t\t\t\t\tisInSamePackage = false\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif isInSamePackage {\n\t\t\t\trelativePathPrefix := \"./\"\n\n\t\t\t\t// Use the relative path from the file containing the import path to the\n\t\t\t\t// enclosing package.json file. This includes any subdirectories within the\n\t\t\t\t// package if there are any.\n\t\t\t\tif relPath, ok := r.fs.Rel(resolveDirInfo.enclosingBrowserScope.absPath, resolveDirInfo.absPath); ok && relPath != \".\" {\n\t\t\t\t\trelativePathPrefix += strings.ReplaceAll(relPath, \"\\\\\", \"/\") + \"/\"\n\t\t\t\t}\n\n\t\t\t\t// Browserify lets \"require('pkg')\" match \"./pkg\" but not \"./pkg.js\".\n\t\t\t\t// So don't add implicit extensions specifically in this place so we\n\t\t\t\t// match Browserify's behavior.\n\t\t\t\tcheckPath(relativePathPrefix+inputPath, skipImplicitExtensions)\n\t\t\t}\n\t\t}\n\t}\n\n\tif r.debugLogs != nil {\n\t\tif ok {\n\t\t\tif remapped == nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Found %q marked as disabled\", inputPath))\n\t\t\t} else {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Found %q mapping to %q\", inputPath, *remapped))\n\t\t\t}\n\t\t} else {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Failed to find %q\", inputPath))\n\t\t}\n\t}\n\treturn\n}\n\nfunc (r resolverQuery) parsePackageJSON(inputPath string) *packageJSON {\n\tpackageJSONPath := r.fs.Join(inputPath, \"package.json\")\n\tcontents, err, originalError := r.caches.FSCache.ReadFile(r.fs, packageJSONPath)\n\tif r.debugLogs != nil && originalError != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Failed to read file %q: %s\", packageJSONPath, originalError.Error()))\n\t}\n\tif err != nil {\n\t\tprettyPaths := MakePrettyPaths(r.fs, logger.Path{Text: packageJSONPath, Namespace: \"file\"})\n\t\tr.log.AddError(nil, logger.Range{}, fmt.Sprintf(\"Cannot read file %q: %s\",\n\t\t\tprettyPaths.Select(r.options.LogPathStyle), err.Error()))\n\t\treturn nil\n\t}\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"The file %q exists\", packageJSONPath))\n\t}\n\n\tkeyPath := logger.Path{Text: packageJSONPath, Namespace: \"file\"}\n\tjsonSource := logger.Source{\n\t\tKeyPath:     keyPath,\n\t\tPrettyPaths: MakePrettyPaths(r.fs, keyPath),\n\t\tContents:    contents,\n\t}\n\ttracker := logger.MakeLineColumnTracker(&jsonSource)\n\n\tjson, ok := r.caches.JSONCache.Parse(r.log, jsonSource, js_parser.JSONOptions{})\n\tif !ok {\n\t\treturn nil\n\t}\n\n\tpackageJSON := &packageJSON{\n\t\tsource:     jsonSource,\n\t\tmainFields: make(map[string]mainField),\n\t}\n\n\t// Read the \"name\" field\n\tif nameJSON, _, ok := getProperty(json, \"name\"); ok {\n\t\tif nameValue, ok := getString(nameJSON); ok {\n\t\t\tpackageJSON.name = nameValue\n\t\t}\n\t}\n\n\t// Read the \"type\" field\n\tif typeJSON, typeKeyLoc, ok := getProperty(json, \"type\"); ok {\n\t\tif typeValue, ok := getString(typeJSON); ok {\n\t\t\tswitch typeValue {\n\t\t\tcase \"commonjs\":\n\t\t\t\tpackageJSON.moduleTypeData = js_ast.ModuleTypeData{\n\t\t\t\t\tType:   js_ast.ModuleCommonJS_PackageJSON,\n\t\t\t\t\tSource: &packageJSON.source,\n\t\t\t\t\tRange:  jsonSource.RangeOfString(typeJSON.Loc),\n\t\t\t\t}\n\t\t\tcase \"module\":\n\t\t\t\tpackageJSON.moduleTypeData = js_ast.ModuleTypeData{\n\t\t\t\t\tType:   js_ast.ModuleESM_PackageJSON,\n\t\t\t\t\tSource: &packageJSON.source,\n\t\t\t\t\tRange:  jsonSource.RangeOfString(typeJSON.Loc),\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tnotes := []logger.MsgData{{Text: \"The \\\"type\\\" field must be set to either \\\"commonjs\\\" or \\\"module\\\".\"}}\n\t\t\t\tkind := logger.Warning\n\n\t\t\t\t// If someone does something like \"type\": \"./index.d.ts\" then they\n\t\t\t\t// likely meant \"types\" instead of \"type\". Customize the message\n\t\t\t\t// for this and hide it if it's inside a published npm package.\n\t\t\t\tif strings.HasSuffix(typeValue, \".d.ts\") {\n\t\t\t\t\tnotes[0] = tracker.MsgData(jsonSource.RangeOfString(typeKeyLoc),\n\t\t\t\t\t\t\"TypeScript type declarations use the \\\"types\\\" field, not the \\\"type\\\" field:\")\n\t\t\t\t\tnotes[0].Location.Suggestion = \"\\\"types\\\"\"\n\t\t\t\t\tif helpers.IsInsideNodeModules(jsonSource.KeyPath.Text) {\n\t\t\t\t\t\tkind = logger.Debug\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tr.log.AddIDWithNotes(logger.MsgID_PackageJSON_InvalidType, kind, &tracker, jsonSource.RangeOfString(typeJSON.Loc),\n\t\t\t\t\tfmt.Sprintf(\"%q is not a valid value for the \\\"type\\\" field\", typeValue),\n\t\t\t\t\tnotes)\n\t\t\t}\n\t\t} else {\n\t\t\tr.log.AddID(logger.MsgID_PackageJSON_InvalidType, logger.Warning, &tracker, logger.Range{Loc: typeJSON.Loc},\n\t\t\t\t\"The value for \\\"type\\\" must be a string\")\n\t\t}\n\t}\n\n\t// Read the \"tsconfig\" field\n\tif tsconfigJSON, _, ok := getProperty(json, \"tsconfig\"); ok {\n\t\tif tsconfigValue, ok := getString(tsconfigJSON); ok {\n\t\t\tpackageJSON.tsconfig = tsconfigValue\n\t\t}\n\t}\n\n\t// Read the \"main\" fields\n\tmainFields := r.options.MainFields\n\tif mainFields == nil {\n\t\tmainFields = defaultMainFields[r.options.Platform]\n\t}\n\tfor _, field := range mainFields {\n\t\tif mainJSON, mainLoc, ok := getProperty(json, field); ok {\n\t\t\tif main, ok := getString(mainJSON); ok && main != \"\" {\n\t\t\t\tpackageJSON.mainFields[field] = mainField{keyLoc: mainLoc, relPath: main}\n\t\t\t}\n\t\t}\n\t}\n\tfor _, field := range mainFieldsForFailure {\n\t\tif _, ok := packageJSON.mainFields[field]; !ok {\n\t\t\tif mainJSON, mainLoc, ok := getProperty(json, field); ok {\n\t\t\t\tif main, ok := getString(mainJSON); ok && main != \"\" {\n\t\t\t\t\tpackageJSON.mainFields[field] = mainField{keyLoc: mainLoc, relPath: main}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Read the \"browser\" property, but only when targeting the browser\n\tif browserJSON, _, ok := getProperty(json, \"browser\"); ok && r.options.Platform == config.PlatformBrowser {\n\t\t// We both want the ability to have the option of CJS vs. ESM and the\n\t\t// option of having node vs. browser. The way to do this is to use the\n\t\t// object literal form of the \"browser\" field like this:\n\t\t//\n\t\t//   \"main\": \"dist/index.node.cjs.js\",\n\t\t//   \"module\": \"dist/index.node.esm.js\",\n\t\t//   \"browser\": {\n\t\t//     \"./dist/index.node.cjs.js\": \"./dist/index.browser.cjs.js\",\n\t\t//     \"./dist/index.node.esm.js\": \"./dist/index.browser.esm.js\"\n\t\t//   },\n\t\t//\n\t\tif browser, ok := browserJSON.Data.(*js_ast.EObject); ok {\n\t\t\t// The value is an object\n\t\t\tbrowserMap := make(map[string]*string)\n\n\t\t\t// Remap all files in the browser field\n\t\t\tfor _, prop := range browser.Properties {\n\t\t\t\tif key, ok := getString(prop.Key); ok && prop.ValueOrNil.Data != nil {\n\t\t\t\t\tif value, ok := getString(prop.ValueOrNil); ok {\n\t\t\t\t\t\t// If this is a string, it's a replacement package\n\t\t\t\t\t\tbrowserMap[key] = &value\n\t\t\t\t\t} else if value, ok := getBool(prop.ValueOrNil); ok {\n\t\t\t\t\t\t// If this is false, it means the package is disabled\n\t\t\t\t\t\tif !value {\n\t\t\t\t\t\t\tbrowserMap[key] = nil\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tr.log.AddID(logger.MsgID_PackageJSON_InvalidBrowser, logger.Warning, &tracker, logger.Range{Loc: prop.ValueOrNil.Loc},\n\t\t\t\t\t\t\t\"Each \\\"browser\\\" mapping must be a string or a boolean\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpackageJSON.browserMap = browserMap\n\t\t}\n\t}\n\n\t// Read the \"sideEffects\" property\n\tif sideEffectsJSON, sideEffectsLoc, ok := getProperty(json, \"sideEffects\"); ok {\n\t\tswitch data := sideEffectsJSON.Data.(type) {\n\t\tcase *js_ast.EBoolean:\n\t\t\tif !data.Value {\n\t\t\t\t// Make an empty map for \"sideEffects: false\", which indicates all\n\t\t\t\t// files in this module can be considered to not have side effects.\n\t\t\t\tpackageJSON.sideEffectsMap = make(map[string]bool)\n\t\t\t\tpackageJSON.sideEffectsData = &SideEffectsData{\n\t\t\t\t\tIsSideEffectsArrayInJSON: false,\n\t\t\t\t\tSource:                   &jsonSource,\n\t\t\t\t\tRange:                    jsonSource.RangeOfString(sideEffectsLoc),\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *js_ast.EArray:\n\t\t\t// The \"sideEffects: []\" format means all files in this module but not in\n\t\t\t// the array can be considered to not have side effects.\n\t\t\tpackageJSON.sideEffectsMap = make(map[string]bool)\n\t\t\tpackageJSON.sideEffectsData = &SideEffectsData{\n\t\t\t\tIsSideEffectsArrayInJSON: true,\n\t\t\t\tSource:                   &jsonSource,\n\t\t\t\tRange:                    jsonSource.RangeOfString(sideEffectsLoc),\n\t\t\t}\n\t\t\tfor _, itemJSON := range data.Items {\n\t\t\t\titem, ok := itemJSON.Data.(*js_ast.EString)\n\t\t\t\tif !ok || item.Value == nil {\n\t\t\t\t\tr.log.AddID(logger.MsgID_PackageJSON_InvalidSideEffects, logger.Warning, &tracker, logger.Range{Loc: itemJSON.Loc},\n\t\t\t\t\t\t\"Expected string in array for \\\"sideEffects\\\"\")\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Reference: https://github.com/webpack/webpack/blob/ed175cd22f89eb9fecd0a70572a3fd0be028e77c/lib/optimize/SideEffectsFlagPlugin.js\n\t\t\t\tpattern := helpers.UTF16ToString(item.Value)\n\t\t\t\tif !strings.ContainsRune(pattern, '/') {\n\t\t\t\t\tpattern = \"**/\" + pattern\n\t\t\t\t}\n\t\t\t\tabsPattern := r.fs.Join(inputPath, pattern)\n\t\t\t\tabsPattern = strings.ReplaceAll(absPattern, \"\\\\\", \"/\") // Avoid problems with Windows-style slashes\n\t\t\t\tre, hadWildcard := globstarToEscapedRegexp(absPattern)\n\n\t\t\t\t// Wildcard patterns require more expensive matching\n\t\t\t\tif hadWildcard {\n\t\t\t\t\tpackageJSON.sideEffectsRegexps = append(packageJSON.sideEffectsRegexps, regexp.MustCompile(re))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Normal strings can be matched with a map lookup\n\t\t\t\tpackageJSON.sideEffectsMap[absPattern] = true\n\t\t\t}\n\n\t\tdefault:\n\t\t\tr.log.AddID(logger.MsgID_PackageJSON_InvalidSideEffects, logger.Warning, &tracker, logger.Range{Loc: sideEffectsJSON.Loc},\n\t\t\t\t\"The value for \\\"sideEffects\\\" must be a boolean or an array\")\n\t\t}\n\t}\n\n\t// Read the \"imports\" map\n\tif importsJSON, importsLoc, ok := getProperty(json, \"imports\"); ok {\n\t\tif importsMap := parseImportsExportsMap(jsonSource, r.log, importsJSON, \"imports\", importsLoc); importsMap != nil {\n\t\t\tif importsMap.root.kind != pjObject {\n\t\t\t\tr.log.AddID(logger.MsgID_PackageJSON_InvalidImportsOrExports, logger.Warning, &tracker, importsMap.root.firstToken,\n\t\t\t\t\t\"The value for \\\"imports\\\" must be an object\")\n\t\t\t}\n\t\t\tpackageJSON.importsMap = importsMap\n\t\t}\n\t}\n\n\t// Read the \"exports\" map\n\tif exportsJSON, exportsLoc, ok := getProperty(json, \"exports\"); ok {\n\t\tif exportsMap := parseImportsExportsMap(jsonSource, r.log, exportsJSON, \"exports\", exportsLoc); exportsMap != nil {\n\t\t\tpackageJSON.exportsMap = exportsMap\n\t\t}\n\t}\n\n\treturn packageJSON\n}\n\n// Reference: https://github.com/fitzgen/glob-to-regexp/blob/2abf65a834259c6504ed3b80e85f893f8cd99127/index.js\nfunc globstarToEscapedRegexp(glob string) (string, bool) {\n\tsb := strings.Builder{}\n\tsb.WriteByte('^')\n\thadWildcard := false\n\tn := len(glob)\n\n\tfor i := 0; i < n; i++ {\n\t\tc := glob[i]\n\t\tswitch c {\n\t\tcase '\\\\', '^', '$', '.', '+', '|', '(', ')', '[', ']', '{', '}':\n\t\t\tsb.WriteByte('\\\\')\n\t\t\tsb.WriteByte(c)\n\n\t\tcase '?':\n\t\t\tsb.WriteByte('.')\n\t\t\thadWildcard = true\n\n\t\tcase '*':\n\t\t\t// Move over all consecutive \"*\"'s.\n\t\t\t// Also store the previous and next characters\n\t\t\tprevChar := -1\n\t\t\tif i > 0 {\n\t\t\t\tprevChar = int(glob[i-1])\n\t\t\t}\n\t\t\tstarCount := 1\n\t\t\tfor i+1 < n && glob[i+1] == '*' {\n\t\t\t\tstarCount++\n\t\t\t\ti++\n\t\t\t}\n\t\t\tnextChar := -1\n\t\t\tif i+1 < n {\n\t\t\t\tnextChar = int(glob[i+1])\n\t\t\t}\n\n\t\t\t// Determine if this is a globstar segment\n\t\t\tisGlobstar := starCount > 1 && // multiple \"*\"'s\n\t\t\t\t(prevChar == '/' || prevChar == -1) && // from the start of the segment\n\t\t\t\t(nextChar == '/' || nextChar == -1) // to the end of the segment\n\n\t\t\tif isGlobstar {\n\t\t\t\t// It's a globstar, so match zero or more path segments\n\t\t\t\tsb.WriteString(\"(?:[^/]*(?:/|$))*\")\n\t\t\t\ti++ // Move over the \"/\"\n\t\t\t} else {\n\t\t\t\t// It's not a globstar, so only match one path segment\n\t\t\t\tsb.WriteString(\"[^/]*\")\n\t\t\t}\n\n\t\t\thadWildcard = true\n\n\t\tdefault:\n\t\t\tsb.WriteByte(c)\n\t\t}\n\t}\n\n\tsb.WriteByte('$')\n\treturn sb.String(), hadWildcard\n}\n\n// Reference: https://nodejs.org/api/esm.html#esm_resolver_algorithm_specification\ntype pjMap struct {\n\troot           pjEntry\n\tpropertyKey    string\n\tpropertyKeyLoc logger.Loc\n}\n\ntype pjKind uint8\n\nconst (\n\tpjNull pjKind = iota\n\tpjString\n\tpjArray\n\tpjObject\n\tpjInvalid\n)\n\ntype pjEntry struct {\n\tstrData       string\n\tarrData       []pjEntry\n\tmapData       []pjMapEntry // Can't be a \"map\" because order matters\n\texpansionKeys expansionKeysArray\n\tfirstToken    logger.Range\n\tkind          pjKind\n}\n\ntype pjMapEntry struct {\n\tkey      string\n\tvalue    pjEntry\n\tkeyRange logger.Range\n}\n\n// This type is just so we can use Go's native sort function\ntype expansionKeysArray []pjMapEntry\n\nfunc (a expansionKeysArray) Len() int          { return len(a) }\nfunc (a expansionKeysArray) Swap(i int, j int) { a[i], a[j] = a[j], a[i] }\n\nfunc (a expansionKeysArray) Less(i int, j int) bool {\n\t// Assert: keyA ends with \"/\" or contains only a single \"*\".\n\t// Assert: keyB ends with \"/\" or contains only a single \"*\".\n\tkeyA := a[i].key\n\tkeyB := a[j].key\n\n\t// Let baseLengthA be the index of \"*\" in keyA plus one, if keyA contains \"*\", or the length of keyA otherwise.\n\t// Let baseLengthB be the index of \"*\" in keyB plus one, if keyB contains \"*\", or the length of keyB otherwise.\n\tstarA := strings.IndexByte(keyA, '*')\n\tstarB := strings.IndexByte(keyB, '*')\n\tvar baseLengthA int\n\tvar baseLengthB int\n\tif starA >= 0 {\n\t\tbaseLengthA = starA\n\t} else {\n\t\tbaseLengthA = len(keyA)\n\t}\n\tif starB >= 0 {\n\t\tbaseLengthB = starB\n\t} else {\n\t\tbaseLengthB = len(keyB)\n\t}\n\n\t// If baseLengthA is greater than baseLengthB, return -1.\n\t// If baseLengthB is greater than baseLengthA, return 1.\n\tif baseLengthA > baseLengthB {\n\t\treturn true\n\t}\n\tif baseLengthB > baseLengthA {\n\t\treturn false\n\t}\n\n\t// If keyA does not contain \"*\", return 1.\n\t// If keyB does not contain \"*\", return -1.\n\tif starA < 0 {\n\t\treturn false\n\t}\n\tif starB < 0 {\n\t\treturn true\n\t}\n\n\t// If the length of keyA is greater than the length of keyB, return -1.\n\t// If the length of keyB is greater than the length of keyA, return 1.\n\tif len(keyA) > len(keyB) {\n\t\treturn true\n\t}\n\tif len(keyB) > len(keyA) {\n\t\treturn false\n\t}\n\n\treturn false\n}\n\nfunc (entry pjEntry) valueForKey(key string) (pjEntry, bool) {\n\tfor _, item := range entry.mapData {\n\t\tif item.key == key {\n\t\t\treturn item.value, true\n\t\t}\n\t}\n\treturn pjEntry{}, false\n}\n\nfunc parseImportsExportsMap(source logger.Source, log logger.Log, json js_ast.Expr, propertyKey string, propertyKeyLoc logger.Loc) *pjMap {\n\tvar visit func(expr js_ast.Expr) pjEntry\n\ttracker := logger.MakeLineColumnTracker(&source)\n\n\tvisit = func(expr js_ast.Expr) pjEntry {\n\t\tvar firstToken logger.Range\n\n\t\tswitch e := expr.Data.(type) {\n\t\tcase *js_ast.ENull:\n\t\t\treturn pjEntry{\n\t\t\t\tkind:       pjNull,\n\t\t\t\tfirstToken: js_lexer.RangeOfIdentifier(source, expr.Loc),\n\t\t\t}\n\n\t\tcase *js_ast.EString:\n\t\t\treturn pjEntry{\n\t\t\t\tkind:       pjString,\n\t\t\t\tfirstToken: source.RangeOfString(expr.Loc),\n\t\t\t\tstrData:    helpers.UTF16ToString(e.Value),\n\t\t\t}\n\n\t\tcase *js_ast.EArray:\n\t\t\tarrData := make([]pjEntry, len(e.Items))\n\t\t\tfor i, item := range e.Items {\n\t\t\t\tarrData[i] = visit(item)\n\t\t\t}\n\t\t\treturn pjEntry{\n\t\t\t\tkind:       pjArray,\n\t\t\t\tfirstToken: logger.Range{Loc: expr.Loc, Len: 1},\n\t\t\t\tarrData:    arrData,\n\t\t\t}\n\n\t\tcase *js_ast.EObject:\n\t\t\tmapData := make([]pjMapEntry, len(e.Properties))\n\t\t\texpansionKeys := make(expansionKeysArray, 0, len(e.Properties))\n\t\t\tfirstToken := logger.Range{Loc: expr.Loc, Len: 1}\n\t\t\tisConditionalSugar := false\n\n\t\t\ttype DeadCondition struct {\n\t\t\t\treason string\n\t\t\t\tranges []logger.Range\n\t\t\t\tnotes  []logger.MsgData\n\t\t\t}\n\t\t\tvar foundDefault logger.Range\n\t\t\tvar foundImport logger.Range\n\t\t\tvar foundRequire logger.Range\n\t\t\tvar deadCondition DeadCondition\n\n\t\t\tfor i, property := range e.Properties {\n\t\t\t\tkeyStr, _ := property.Key.Data.(*js_ast.EString)\n\t\t\t\tkey := helpers.UTF16ToString(keyStr.Value)\n\t\t\t\tkeyRange := source.RangeOfString(property.Key.Loc)\n\n\t\t\t\t// If exports is an Object with both a key starting with \".\" and a key\n\t\t\t\t// not starting with \".\", throw an Invalid Package Configuration error.\n\t\t\t\tcurIsConditionalSugar := !strings.HasPrefix(key, \".\")\n\t\t\t\tif i == 0 {\n\t\t\t\t\tisConditionalSugar = curIsConditionalSugar\n\t\t\t\t} else if isConditionalSugar != curIsConditionalSugar {\n\t\t\t\t\tprevEntry := mapData[i-1]\n\t\t\t\t\tlog.AddIDWithNotes(logger.MsgID_PackageJSON_InvalidImportsOrExports, logger.Warning, &tracker, keyRange,\n\t\t\t\t\t\t\"This object cannot contain keys that both start with \\\".\\\" and don't start with \\\".\\\"\",\n\t\t\t\t\t\t[]logger.MsgData{tracker.MsgData(prevEntry.keyRange,\n\t\t\t\t\t\t\tfmt.Sprintf(\"The key %q is incompatible with the previous key %q:\", key, prevEntry.key))})\n\t\t\t\t\treturn pjEntry{\n\t\t\t\t\t\tkind:       pjInvalid,\n\t\t\t\t\t\tfirstToken: firstToken,\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track \"dead\" conditional branches that can never be reached\n\t\t\t\tif foundDefault.Len != 0 || (foundImport.Len != 0 && foundRequire.Len != 0) {\n\t\t\t\t\tdeadCondition.ranges = append(deadCondition.ranges, keyRange)\n\t\t\t\t\t// Note: Don't warn about the \"default\" condition as it's supposed to be a catch-all condition\n\t\t\t\t\tif deadCondition.reason == \"\" && key != \"default\" {\n\t\t\t\t\t\tif foundDefault.Len != 0 {\n\t\t\t\t\t\t\tdeadCondition.reason = \"\\\"default\\\"\"\n\t\t\t\t\t\t\tdeadCondition.notes = []logger.MsgData{\n\t\t\t\t\t\t\t\ttracker.MsgData(foundDefault, \"The \\\"default\\\" condition comes earlier and will always be chosen:\"),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdeadCondition.reason = \"both \\\"import\\\" and \\\"require\\\"\"\n\t\t\t\t\t\t\tdeadCondition.notes = []logger.MsgData{\n\t\t\t\t\t\t\t\ttracker.MsgData(foundImport, \"The \\\"import\\\" condition comes earlier and will be used for all \\\"import\\\" statements:\"),\n\t\t\t\t\t\t\t\ttracker.MsgData(foundRequire, \"The \\\"require\\\" condition comes earlier and will be used for all \\\"require\\\" calls:\"),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tswitch key {\n\t\t\t\t\tcase \"default\":\n\t\t\t\t\t\tfoundDefault = keyRange\n\t\t\t\t\tcase \"import\":\n\t\t\t\t\t\tfoundImport = keyRange\n\t\t\t\t\tcase \"require\":\n\t\t\t\t\t\tfoundRequire = keyRange\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tentry := pjMapEntry{\n\t\t\t\t\tkey:      key,\n\t\t\t\t\tkeyRange: keyRange,\n\t\t\t\t\tvalue:    visit(property.ValueOrNil),\n\t\t\t\t}\n\n\t\t\t\tif strings.HasSuffix(key, \"/\") || strings.IndexByte(key, '*') >= 0 {\n\t\t\t\t\texpansionKeys = append(expansionKeys, entry)\n\t\t\t\t}\n\n\t\t\t\tmapData[i] = entry\n\t\t\t}\n\n\t\t\t// Let expansionKeys be the list of keys of matchObj either ending in \"/\"\n\t\t\t// or containing only a single \"*\", sorted by the sorting function\n\t\t\t// PATTERN_KEY_COMPARE which orders in descending order of specificity.\n\t\t\tsort.Stable(expansionKeys)\n\n\t\t\t// Warn about \"dead\" conditional branches that can never be reached\n\t\t\tif deadCondition.reason != \"\" {\n\t\t\t\tkind := logger.Warning\n\t\t\t\tif helpers.IsInsideNodeModules(source.KeyPath.Text) {\n\t\t\t\t\tkind = logger.Debug\n\t\t\t\t}\n\t\t\t\tvar conditions strings.Builder\n\t\t\t\tconditionWord := \"condition\"\n\t\t\t\titComesWord := \"it comes\"\n\t\t\t\tif len(deadCondition.ranges) > 1 {\n\t\t\t\t\tconditionWord = \"conditions\"\n\t\t\t\t\titComesWord = \"they come\"\n\t\t\t\t}\n\t\t\t\tfor i, r := range deadCondition.ranges {\n\t\t\t\t\tif i > 0 {\n\t\t\t\t\t\tconditions.WriteString(\" and \")\n\t\t\t\t\t}\n\t\t\t\t\tconditions.WriteString(source.TextForRange(r))\n\t\t\t\t}\n\t\t\t\tlog.AddIDWithNotes(logger.MsgID_PackageJSON_DeadCondition, kind, &tracker, deadCondition.ranges[0],\n\t\t\t\t\tfmt.Sprintf(\"The %s %s here will never be used as %s after %s\", conditionWord, conditions.String(), itComesWord, deadCondition.reason),\n\t\t\t\t\tdeadCondition.notes)\n\t\t\t}\n\n\t\t\treturn pjEntry{\n\t\t\t\tkind:          pjObject,\n\t\t\t\tfirstToken:    firstToken,\n\t\t\t\tmapData:       mapData,\n\t\t\t\texpansionKeys: expansionKeys,\n\t\t\t}\n\n\t\tcase *js_ast.EBoolean:\n\t\t\tfirstToken = js_lexer.RangeOfIdentifier(source, expr.Loc)\n\n\t\tcase *js_ast.ENumber:\n\t\t\tfirstToken = source.RangeOfNumber(expr.Loc)\n\n\t\tdefault:\n\t\t\tfirstToken.Loc = expr.Loc\n\t\t}\n\n\t\tlog.AddID(logger.MsgID_PackageJSON_InvalidImportsOrExports, logger.Warning, &tracker, firstToken,\n\t\t\t\"This value must be a string, an object, an array, or null\")\n\t\treturn pjEntry{\n\t\t\tkind:       pjInvalid,\n\t\t\tfirstToken: firstToken,\n\t\t}\n\t}\n\n\troot := visit(json)\n\n\tif root.kind == pjNull {\n\t\treturn nil\n\t}\n\n\treturn &pjMap{\n\t\troot:           root,\n\t\tpropertyKey:    propertyKey,\n\t\tpropertyKeyLoc: propertyKeyLoc,\n\t}\n}\n\nfunc (entry pjEntry) keysStartWithDot() bool {\n\treturn len(entry.mapData) > 0 && strings.HasPrefix(entry.mapData[0].key, \".\")\n}\n\ntype pjStatus uint8\n\nconst (\n\tpjStatusUndefined                  pjStatus = iota\n\tpjStatusUndefinedNoConditionsMatch          // A more friendly error message for when no conditions are matched\n\tpjStatusNull\n\tpjStatusExact\n\tpjStatusExactEndsWithStar\n\tpjStatusInexact        // This means we may need to try CommonJS-style extension suffixes\n\tpjStatusPackageResolve // Need to re-run package resolution on the result\n\n\t// Module specifier is an invalid URL, package name or package subpath specifier.\n\tpjStatusInvalidModuleSpecifier\n\n\t// package.json configuration is invalid or contains an invalid configuration.\n\tpjStatusInvalidPackageConfiguration\n\n\t// Package exports or imports define a target module for the package that is an invalid type or string target.\n\tpjStatusInvalidPackageTarget\n\n\t// Package exports do not define or permit a target subpath in the package for the given module.\n\tpjStatusPackagePathNotExported\n\n\t// Package imports do not define the specifiespecifier\n\tpjStatusPackageImportNotDefined\n\n\t// The package or module requested does not exist.\n\tpjStatusModuleNotFound\n\tpjStatusModuleNotFoundMissingExtension // The user just needs to add the missing extension\n\n\t// The resolved path corresponds to a directory, which is not a supported target for module imports.\n\tpjStatusUnsupportedDirectoryImport\n\tpjStatusUnsupportedDirectoryImportMissingIndex // The user just needs to add the missing \"/index.js\" suffix\n)\n\nfunc (status pjStatus) isUndefined() bool {\n\treturn status == pjStatusUndefined || status == pjStatusUndefinedNoConditionsMatch\n}\n\ntype pjDebug struct {\n\t// If the status is \"pjStatusInvalidPackageTarget\" or \"pjStatusInvalidModuleSpecifier\",\n\t// then this is the reason. It always starts with \" because\".\n\tinvalidBecause string\n\n\t// If the status is \"pjStatusUndefinedNoConditionsMatch\", this is the set of\n\t// conditions that didn't match, in the order that they were found in the file.\n\t// This information is used for error messages.\n\tunmatchedConditions []logger.Span\n\n\t// This is the range of the token to use for error messages\n\ttoken logger.Range\n\n\t// If true, the token is a \"null\" literal\n\tisBecauseOfNullLiteral bool\n}\n\nfunc (r resolverQuery) esmHandlePostConditions(\n\tresolved string,\n\tstatus pjStatus,\n\tdebug pjDebug,\n) (string, pjStatus, pjDebug) {\n\tif status != pjStatusExact && status != pjStatusExactEndsWithStar && status != pjStatusInexact {\n\t\treturn resolved, status, debug\n\t}\n\n\t// If resolved contains any percent encodings of \"/\" or \"\\\" (\"%2f\" and \"%5C\"\n\t// respectively), then throw an Invalid Module Specifier error.\n\tresolvedPath, err := url.PathUnescape(resolved)\n\tif err != nil {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The path %q contains invalid URL escapes: %s\", resolved, err.Error()))\n\t\t}\n\t\treturn resolved, pjStatusInvalidModuleSpecifier, debug\n\t}\n\tvar found string\n\tif strings.Contains(resolved, \"%2f\") {\n\t\tfound = \"%2f\"\n\t} else if strings.Contains(resolved, \"%2F\") {\n\t\tfound = \"%2F\"\n\t} else if strings.Contains(resolved, \"%5c\") {\n\t\tfound = \"%5c\"\n\t} else if strings.Contains(resolved, \"%5C\") {\n\t\tfound = \"%5C\"\n\t}\n\tif found != \"\" {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The path %q is not allowed to contain %q\", resolved, found))\n\t\t}\n\t\treturn resolved, pjStatusInvalidModuleSpecifier, debug\n\t}\n\n\t// If the file at resolved is a directory, then throw an Unsupported Directory\n\t// Import error.\n\tif strings.HasSuffix(resolvedPath, \"/\") || strings.HasSuffix(resolvedPath, \"\\\\\") {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The path %q is not allowed to end with a slash\", resolved))\n\t\t}\n\t\treturn resolved, pjStatusUnsupportedDirectoryImport, debug\n\t}\n\n\t// Set resolved to the real path of resolved.\n\treturn resolvedPath, status, debug\n}\n\nfunc (r resolverQuery) esmPackageImportsResolve(\n\tspecifier string,\n\timports pjEntry,\n\tconditions map[string]bool,\n) (string, pjStatus, pjDebug) {\n\t// ALGORITHM DEVIATION: Provide a friendly error message if \"imports\" is not an object\n\tif imports.kind != pjObject {\n\t\treturn \"\", pjStatusInvalidPackageConfiguration, pjDebug{token: imports.firstToken}\n\t}\n\n\tresolved, status, debug := r.esmPackageImportsExportsResolve(specifier, imports, \"/\", true, conditions)\n\tif status != pjStatusNull && status != pjStatusUndefined {\n\t\treturn resolved, status, debug\n\t}\n\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"The package import %q is not defined\", specifier))\n\t}\n\treturn specifier, pjStatusPackageImportNotDefined, pjDebug{token: imports.firstToken}\n}\n\nfunc (r resolverQuery) esmPackageExportsResolve(\n\tpackageURL string,\n\tsubpath string,\n\texports pjEntry,\n\tconditions map[string]bool,\n) (string, pjStatus, pjDebug) {\n\tif exports.kind == pjInvalid {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(\"Invalid package configuration\")\n\t\t}\n\t\treturn \"\", pjStatusInvalidPackageConfiguration, pjDebug{token: exports.firstToken}\n\t}\n\n\tdebugToReturn := pjDebug{token: exports.firstToken}\n\tif subpath == \".\" {\n\t\tmainExport := pjEntry{kind: pjNull}\n\t\tif exports.kind == pjString || exports.kind == pjArray || (exports.kind == pjObject && !exports.keysStartWithDot()) {\n\t\t\tmainExport = exports\n\t\t} else if exports.kind == pjObject {\n\t\t\tif dot, ok := exports.valueForKey(\".\"); ok {\n\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\tr.debugLogs.addNote(\"Using the entry for \\\".\\\"\")\n\t\t\t\t}\n\t\t\t\tmainExport = dot\n\t\t\t}\n\t\t}\n\t\tif mainExport.kind != pjNull {\n\t\t\tresolved, status, debug := r.esmPackageTargetResolve(packageURL, mainExport, \"\", false, false, conditions)\n\t\t\tif status != pjStatusNull && status != pjStatusUndefined {\n\t\t\t\treturn resolved, status, debug\n\t\t\t} else {\n\t\t\t\tdebugToReturn = debug\n\t\t\t}\n\t\t}\n\t} else if exports.kind == pjObject && exports.keysStartWithDot() {\n\t\tresolved, status, debug := r.esmPackageImportsExportsResolve(subpath, exports, packageURL, false, conditions)\n\t\tif status != pjStatusNull && status != pjStatusUndefined {\n\t\t\treturn resolved, status, debug\n\t\t} else {\n\t\t\tdebugToReturn = debug\n\t\t}\n\t}\n\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"The path %q is not exported\", subpath))\n\t}\n\treturn \"\", pjStatusPackagePathNotExported, debugToReturn\n}\n\nfunc (r resolverQuery) esmPackageImportsExportsResolve(\n\tmatchKey string,\n\tmatchObj pjEntry,\n\tpackageURL string,\n\tisImports bool,\n\tconditions map[string]bool,\n) (string, pjStatus, pjDebug) {\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Checking object path map for %q\", matchKey))\n\t}\n\n\t// If matchKey is a key of matchObj and does not end in \"/\" or contain \"*\", then\n\tif !strings.HasSuffix(matchKey, \"/\") && strings.IndexByte(matchKey, '*') < 0 {\n\t\tif target, ok := matchObj.valueForKey(matchKey); ok {\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Found exact match for %q\", matchKey))\n\t\t\t}\n\t\t\treturn r.esmPackageTargetResolve(packageURL, target, \"\", false, isImports, conditions)\n\t\t}\n\t}\n\n\tfor _, expansion := range matchObj.expansionKeys {\n\t\t// If expansionKey contains \"*\", set patternBase to the substring of\n\t\t// expansionKey up to but excluding the first \"*\" character\n\t\tif star := strings.IndexByte(expansion.key, '*'); star >= 0 {\n\t\t\tpatternBase := expansion.key[:star]\n\n\t\t\t// If patternBase is not null and matchKey starts with but is not equal\n\t\t\t// to patternBase, then\n\t\t\tif strings.HasPrefix(matchKey, patternBase) {\n\t\t\t\t// Let patternTrailer be the substring of expansionKey from the index\n\t\t\t\t// after the first \"*\" character.\n\t\t\t\tpatternTrailer := expansion.key[star+1:]\n\n\t\t\t\t// If patternTrailer has zero length, or if matchKey ends with\n\t\t\t\t// patternTrailer and the length of matchKey is greater than or\n\t\t\t\t// equal to the length of expansionKey, then\n\t\t\t\tif patternTrailer == \"\" || (strings.HasSuffix(matchKey, patternTrailer) && len(matchKey) >= len(expansion.key)) {\n\t\t\t\t\ttarget := expansion.value\n\t\t\t\t\tsubpath := matchKey[len(patternBase) : len(matchKey)-len(patternTrailer)]\n\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The key %q matched with %q left over\", expansion.key, subpath))\n\t\t\t\t\t}\n\t\t\t\t\treturn r.esmPackageTargetResolve(packageURL, target, subpath, true, isImports, conditions)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Otherwise if patternBase is null and matchKey starts with\n\t\t\t// expansionKey, then\n\t\t\tif strings.HasPrefix(matchKey, expansion.key) {\n\t\t\t\ttarget := expansion.value\n\t\t\t\tsubpath := matchKey[len(expansion.key):]\n\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The key %q matched with %q left over\", expansion.key, subpath))\n\t\t\t\t}\n\t\t\t\tresult, status, debug := r.esmPackageTargetResolve(packageURL, target, subpath, false, isImports, conditions)\n\t\t\t\tif status == pjStatusExact || status == pjStatusExactEndsWithStar {\n\t\t\t\t\t// Return the object { resolved, exact: false }.\n\t\t\t\t\tstatus = pjStatusInexact\n\t\t\t\t}\n\t\t\t\treturn result, status, debug\n\t\t\t}\n\t\t}\n\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The key %q did not match\", expansion.key))\n\t\t}\n\t}\n\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"No keys matched %q\", matchKey))\n\t}\n\treturn \"\", pjStatusNull, pjDebug{token: matchObj.firstToken}\n}\n\n// If path split on \"/\" or \"\\\" contains any \".\", \"..\" or \"node_modules\"\n// segments after the first segment, throw an Invalid Package Target error.\nfunc findInvalidSegment(path string) string {\n\tslash := strings.IndexAny(path, \"/\\\\\")\n\tif slash == -1 {\n\t\treturn \"\"\n\t}\n\tpath = path[slash+1:]\n\tfor path != \"\" {\n\t\tslash := strings.IndexAny(path, \"/\\\\\")\n\t\tsegment := path\n\t\tif slash != -1 {\n\t\t\tsegment = path[:slash]\n\t\t\tpath = path[slash+1:]\n\t\t} else {\n\t\t\tpath = \"\"\n\t\t}\n\t\tif segment == \".\" || segment == \"..\" || segment == \"node_modules\" {\n\t\t\treturn segment\n\t\t}\n\t}\n\treturn \"\"\n}\n\nfunc (r resolverQuery) esmPackageTargetResolve(\n\tpackageURL string,\n\ttarget pjEntry,\n\tsubpath string,\n\tpattern bool,\n\tinternal bool,\n\tconditions map[string]bool,\n) (string, pjStatus, pjDebug) {\n\tswitch target.kind {\n\tcase pjString:\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Checking path %q against target %q\", subpath, target.strData))\n\t\t\tr.debugLogs.increaseIndent()\n\t\t\tdefer r.debugLogs.decreaseIndent()\n\t\t}\n\n\t\t// If pattern is false, subpath has non-zero length and target\n\t\t// does not end with \"/\", throw an Invalid Module Specifier error.\n\t\tif !pattern && subpath != \"\" && !strings.HasSuffix(target.strData, \"/\") {\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The target %q is invalid because it doesn't end in \\\"/\\\"\", target.strData))\n\t\t\t}\n\t\t\treturn target.strData, pjStatusInvalidModuleSpecifier, pjDebug{\n\t\t\t\ttoken:          target.firstToken,\n\t\t\t\tinvalidBecause: \" because it doesn't end in \\\"/\\\"\",\n\t\t\t}\n\t\t}\n\n\t\t// If target does not start with \"./\", then...\n\t\tif !strings.HasPrefix(target.strData, \"./\") {\n\t\t\tif internal && !strings.HasPrefix(target.strData, \"../\") && !strings.HasPrefix(target.strData, \"/\") {\n\t\t\t\tif pattern {\n\t\t\t\t\tresult := strings.ReplaceAll(target.strData, \"*\", subpath)\n\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Substituted %q for \\\"*\\\" in %q to get %q\", subpath, target.strData, result))\n\t\t\t\t\t}\n\t\t\t\t\treturn result, pjStatusPackageResolve, pjDebug{token: target.firstToken}\n\t\t\t\t}\n\t\t\t\tresult := target.strData + subpath\n\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Joined %q to %q to get %q\", target.strData, subpath, result))\n\t\t\t\t}\n\t\t\t\treturn result, pjStatusPackageResolve, pjDebug{token: target.firstToken}\n\t\t\t}\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The target %q is invalid because it doesn't start with \\\"./\\\"\", target.strData))\n\t\t\t}\n\t\t\treturn target.strData, pjStatusInvalidPackageTarget, pjDebug{\n\t\t\t\ttoken:          target.firstToken,\n\t\t\t\tinvalidBecause: \" because it doesn't start with \\\"./\\\"\",\n\t\t\t}\n\t\t}\n\n\t\t// If target split on \"/\" or \"\\\" contains any \".\", \"..\" or \"node_modules\"\n\t\t// segments after the first segment, throw an Invalid Package Target error.\n\t\tif invalidSegment := findInvalidSegment(target.strData); invalidSegment != \"\" {\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The target %q is invalid because it contains invalid segment %q\", target.strData, invalidSegment))\n\t\t\t}\n\t\t\treturn target.strData, pjStatusInvalidPackageTarget, pjDebug{\n\t\t\t\ttoken:          target.firstToken,\n\t\t\t\tinvalidBecause: fmt.Sprintf(\" because it contains invalid segment %q\", invalidSegment),\n\t\t\t}\n\t\t}\n\n\t\t// Let resolvedTarget be the URL resolution of the concatenation of packageURL and target.\n\t\tresolvedTarget := path.Join(packageURL, target.strData)\n\n\t\t// If subpath split on \"/\" or \"\\\" contains any \".\", \"..\" or \"node_modules\"\n\t\t// segments, throw an Invalid Module Specifier error.\n\t\tif invalidSegment := findInvalidSegment(subpath); invalidSegment != \"\" {\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The path %q is invalid because it contains invalid segment %q\", subpath, invalidSegment))\n\t\t\t}\n\t\t\treturn subpath, pjStatusInvalidModuleSpecifier, pjDebug{\n\t\t\t\ttoken:          target.firstToken,\n\t\t\t\tinvalidBecause: fmt.Sprintf(\" because it contains invalid segment %q\", invalidSegment),\n\t\t\t}\n\t\t}\n\n\t\tif pattern {\n\t\t\t// Return the URL resolution of resolvedTarget with every instance of \"*\" replaced with subpath.\n\t\t\tresult := strings.ReplaceAll(resolvedTarget, \"*\", subpath)\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Substituted %q for \\\"*\\\" in %q to get %q\", subpath, \".\"+resolvedTarget, \".\"+result))\n\t\t\t}\n\t\t\tstatus := pjStatusExact\n\t\t\tif strings.HasSuffix(resolvedTarget, \"*\") && strings.IndexByte(resolvedTarget, '*') == len(resolvedTarget)-1 {\n\t\t\t\tstatus = pjStatusExactEndsWithStar\n\t\t\t}\n\t\t\treturn result, status, pjDebug{token: target.firstToken}\n\t\t} else {\n\t\t\t// Return the URL resolution of the concatenation of subpath and resolvedTarget.\n\t\t\tresult := path.Join(resolvedTarget, subpath)\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Joined %q to %q to get %q\", subpath, \".\"+resolvedTarget, \".\"+result))\n\t\t\t}\n\t\t\treturn result, pjStatusExact, pjDebug{token: target.firstToken}\n\t\t}\n\n\tcase pjObject:\n\t\tif r.debugLogs != nil {\n\t\t\tkeys := make([]string, 0, len(conditions))\n\t\t\tfor key := range conditions {\n\t\t\t\tkeys = append(keys, fmt.Sprintf(\"%q\", key))\n\t\t\t}\n\t\t\tsort.Strings(keys)\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Checking condition map for one of [%s]\", strings.Join(keys, \", \")))\n\t\t\tr.debugLogs.increaseIndent()\n\t\t\tdefer r.debugLogs.decreaseIndent()\n\t\t}\n\n\t\tvar didFindMapEntry bool\n\t\tvar lastMapEntry pjMapEntry\n\n\t\tfor _, p := range target.mapData {\n\t\t\tif p.key == \"default\" || conditions[p.key] {\n\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The key %q applies\", p.key))\n\t\t\t\t}\n\t\t\t\tresolved, status, debug := r.esmPackageTargetResolve(packageURL, p.value, subpath, pattern, internal, conditions)\n\t\t\t\tif status.isUndefined() {\n\t\t\t\t\tdidFindMapEntry = true\n\t\t\t\t\tlastMapEntry = p\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\treturn resolved, status, debug\n\t\t\t}\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The key %q does not apply\", p.key))\n\t\t\t}\n\t\t}\n\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(\"No keys in the map were applicable\")\n\t\t}\n\n\t\t// ALGORITHM DEVIATION: Provide a friendly error message if no conditions matched\n\t\tif len(target.mapData) > 0 && !target.keysStartWithDot() {\n\t\t\tif didFindMapEntry && lastMapEntry.value.kind == pjObject &&\n\t\t\t\tlen(lastMapEntry.value.mapData) > 0 && !lastMapEntry.value.keysStartWithDot() {\n\t\t\t\t// If a top-level condition did match but no sub-condition matched,\n\t\t\t\t// complain about the sub-condition instead of the top-level condition.\n\t\t\t\t// This leads to a less confusing error message. For example:\n\t\t\t\t//\n\t\t\t\t//   \"exports\": {\n\t\t\t\t//     \"node\": {\n\t\t\t\t//       \"require\": \"./dist/bwip-js-node.js\"\n\t\t\t\t//     }\n\t\t\t\t//   },\n\t\t\t\t//\n\t\t\t\t// We want the warning to say this:\n\t\t\t\t//\n\t\t\t\t//   note: None of the conditions in the package definition (\"require\") match any of the\n\t\t\t\t//         currently active conditions (\"default\", \"import\", \"node\")\n\t\t\t\t//   14 |       \"node\": {\n\t\t\t\t//      |               ^\n\t\t\t\t//\n\t\t\t\t// We don't want the warning to say this:\n\t\t\t\t//\n\t\t\t\t//   note: None of the conditions in the package definition (\"browser\", \"electron\", \"node\")\n\t\t\t\t//         match any of the currently active conditions (\"default\", \"import\", \"node\")\n\t\t\t\t//   7 |   \"exports\": {\n\t\t\t\t//     |              ^\n\t\t\t\t//\n\t\t\t\t// More information: https://github.com/evanw/esbuild/issues/1484\n\t\t\t\ttarget = lastMapEntry.value\n\t\t\t}\n\t\t\tkeys := make([]logger.Span, len(target.mapData))\n\t\t\tfor i, p := range target.mapData {\n\t\t\t\tkeys[i] = logger.Span{Text: p.key, Range: p.keyRange}\n\t\t\t}\n\t\t\treturn \"\", pjStatusUndefinedNoConditionsMatch, pjDebug{\n\t\t\t\ttoken:               target.firstToken,\n\t\t\t\tunmatchedConditions: keys,\n\t\t\t}\n\t\t}\n\n\t\treturn \"\", pjStatusUndefined, pjDebug{token: target.firstToken}\n\n\tcase pjArray:\n\t\tif len(target.arrData) == 0 {\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The path %q is set to an empty array\", subpath))\n\t\t\t}\n\t\t\treturn \"\", pjStatusNull, pjDebug{token: target.firstToken}\n\t\t}\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Checking for %q in an array\", subpath))\n\t\t\tr.debugLogs.increaseIndent()\n\t\t\tdefer r.debugLogs.decreaseIndent()\n\t\t}\n\t\tlastException := pjStatusUndefined\n\t\tlastDebug := pjDebug{token: target.firstToken}\n\t\tfor _, targetValue := range target.arrData {\n\t\t\t// Let resolved be the result, continuing the loop on any Invalid Package Target error.\n\t\t\tresolved, status, debug := r.esmPackageTargetResolve(packageURL, targetValue, subpath, pattern, internal, conditions)\n\t\t\tif status == pjStatusInvalidPackageTarget || status == pjStatusNull {\n\t\t\t\tlastException = status\n\t\t\t\tlastDebug = debug\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif status.isUndefined() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn resolved, status, debug\n\t\t}\n\n\t\t// Return or throw the last fallback resolution null return or error.\n\t\treturn \"\", lastException, lastDebug\n\n\tcase pjNull:\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The path %q is set to null\", subpath))\n\t\t}\n\t\treturn \"\", pjStatusNull, pjDebug{token: target.firstToken, isBecauseOfNullLiteral: true}\n\t}\n\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Invalid package target for path %q\", subpath))\n\t}\n\treturn \"\", pjStatusInvalidPackageTarget, pjDebug{token: target.firstToken}\n}\n\nfunc esmParsePackageName(packageSpecifier string) (packageName string, packageSubpath string, ok bool) {\n\tif packageSpecifier == \"\" {\n\t\treturn\n\t}\n\n\tslash := strings.IndexByte(packageSpecifier, '/')\n\tif !strings.HasPrefix(packageSpecifier, \"@\") {\n\t\tif slash == -1 {\n\t\t\tslash = len(packageSpecifier)\n\t\t}\n\t\tpackageName = packageSpecifier[:slash]\n\t} else {\n\t\tif slash == -1 {\n\t\t\treturn\n\t\t}\n\t\tslash2 := strings.IndexByte(packageSpecifier[slash+1:], '/')\n\t\tif slash2 == -1 {\n\t\t\tslash2 = len(packageSpecifier[slash+1:])\n\t\t}\n\t\tpackageName = packageSpecifier[:slash+1+slash2]\n\t}\n\n\tif strings.HasPrefix(packageName, \".\") || strings.ContainsAny(packageName, \"\\\\%\") {\n\t\treturn\n\t}\n\n\tpackageSubpath = \".\" + packageSpecifier[len(packageName):]\n\tok = true\n\treturn\n}\n\nfunc (r resolverQuery) esmPackageExportsReverseResolve(\n\tquery string,\n\troot pjEntry,\n\tconditions map[string]bool,\n) (bool, string, logger.Range) {\n\tif root.kind == pjObject && root.keysStartWithDot() {\n\t\tif ok, subpath, token := r.esmPackageImportsExportsReverseResolve(query, root, conditions); ok {\n\t\t\treturn true, subpath, token\n\t\t}\n\t}\n\n\treturn false, \"\", logger.Range{}\n}\n\nfunc (r resolverQuery) esmPackageImportsExportsReverseResolve(\n\tquery string,\n\tmatchObj pjEntry,\n\tconditions map[string]bool,\n) (bool, string, logger.Range) {\n\tif !strings.HasSuffix(query, \"*\") {\n\t\tfor _, entry := range matchObj.mapData {\n\t\t\tif ok, subpath, token := r.esmPackageTargetReverseResolve(query, entry.key, entry.value, esmReverseExact, conditions); ok {\n\t\t\t\treturn true, subpath, token\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, expansion := range matchObj.expansionKeys {\n\t\tif strings.HasSuffix(expansion.key, \"*\") {\n\t\t\tif ok, subpath, token := r.esmPackageTargetReverseResolve(query, expansion.key, expansion.value, esmReversePattern, conditions); ok {\n\t\t\t\treturn true, subpath, token\n\t\t\t}\n\t\t}\n\n\t\tif ok, subpath, token := r.esmPackageTargetReverseResolve(query, expansion.key, expansion.value, esmReversePrefix, conditions); ok {\n\t\t\treturn true, subpath, token\n\t\t}\n\t}\n\n\treturn false, \"\", logger.Range{}\n}\n\ntype esmReverseKind uint8\n\nconst (\n\tesmReverseExact esmReverseKind = iota\n\tesmReversePattern\n\tesmReversePrefix\n)\n\nfunc (r resolverQuery) esmPackageTargetReverseResolve(\n\tquery string,\n\tkey string,\n\ttarget pjEntry,\n\tkind esmReverseKind,\n\tconditions map[string]bool,\n) (bool, string, logger.Range) {\n\tswitch target.kind {\n\tcase pjString:\n\t\tswitch kind {\n\t\tcase esmReverseExact:\n\t\t\tif query == target.strData {\n\t\t\t\treturn true, key, target.firstToken\n\t\t\t}\n\n\t\tcase esmReversePrefix:\n\t\t\tif strings.HasPrefix(query, target.strData) {\n\t\t\t\treturn true, key + query[len(target.strData):], target.firstToken\n\t\t\t}\n\n\t\tcase esmReversePattern:\n\t\t\tstar := strings.IndexByte(target.strData, '*')\n\t\t\tkeyWithoutTrailingStar := strings.TrimSuffix(key, \"*\")\n\n\t\t\t// Handle the case of no \"*\"\n\t\t\tif star == -1 {\n\t\t\t\tif query == target.strData {\n\t\t\t\t\treturn true, keyWithoutTrailingStar, target.firstToken\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Only support tracing through a single \"*\"\n\t\t\tprefix := target.strData[0:star]\n\t\t\tsuffix := target.strData[star+1:]\n\t\t\tif !strings.ContainsRune(suffix, '*') && strings.HasPrefix(query, prefix) {\n\t\t\t\tif afterPrefix := query[len(prefix):]; strings.HasSuffix(afterPrefix, suffix) {\n\t\t\t\t\tstarData := afterPrefix[:len(afterPrefix)-len(suffix)]\n\t\t\t\t\treturn true, keyWithoutTrailingStar + starData, target.firstToken\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\tcase pjObject:\n\t\tfor _, p := range target.mapData {\n\t\t\tif p.key == \"default\" || conditions[p.key] {\n\t\t\t\tif ok, subpath, token := r.esmPackageTargetReverseResolve(query, key, p.value, kind, conditions); ok {\n\t\t\t\t\treturn true, subpath, token\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\tcase pjArray:\n\t\tfor _, targetValue := range target.arrData {\n\t\t\tif ok, subpath, token := r.esmPackageTargetReverseResolve(query, key, targetValue, kind, conditions); ok {\n\t\t\t\treturn true, subpath, token\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false, \"\", logger.Range{}\n}\n"
  },
  {
    "path": "internal/resolver/resolver.go",
    "content": "package resolver\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"path\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"syscall\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/cache\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/fs\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\nvar defaultMainFields = map[config.Platform][]string{\n\t// Note that this means if a package specifies \"main\", \"module\", and\n\t// \"browser\" then \"browser\" will win out over \"module\". This is the\n\t// same behavior as webpack: https://github.com/webpack/webpack/issues/4674.\n\t//\n\t// This is deliberate because the presence of the \"browser\" field is a\n\t// good signal that the \"module\" field may have non-browser stuff in it,\n\t// which will crash or fail to be bundled when targeting the browser.\n\tconfig.PlatformBrowser: {\"browser\", \"module\", \"main\"},\n\n\t// Note that this means if a package specifies \"module\" and \"main\", the ES6\n\t// module will not be selected. This means tree shaking will not work when\n\t// targeting node environments.\n\t//\n\t// This is unfortunately necessary for compatibility. Some packages\n\t// incorrectly treat the \"module\" field as \"code for the browser\". It\n\t// actually means \"code for ES6 environments\" which includes both node\n\t// and the browser.\n\t//\n\t// For example, the package \"@firebase/app\" prints a warning on startup about\n\t// the bundler incorrectly using code meant for the browser if the bundler\n\t// selects the \"module\" field instead of the \"main\" field.\n\t//\n\t// If you want to enable tree shaking when targeting node, you will have to\n\t// configure the main fields to be \"module\" and then \"main\". Keep in mind\n\t// that some packages may break if you do this.\n\tconfig.PlatformNode: {\"main\", \"module\"},\n\n\t// The neutral platform is for people that don't want esbuild to try to\n\t// pick good defaults for their platform. In that case, the list of main\n\t// fields is empty by default. You must explicitly configure it yourself.\n\tconfig.PlatformNeutral: {},\n}\n\n// These are the main fields to use when the \"main fields\" setting is configured\n// to something unusual, such as something without the \"main\" field.\nvar mainFieldsForFailure = []string{\"main\", \"module\"}\n\n// Path resolution is a mess. One tricky issue is the \"module\" override for the\n// \"main\" field in \"package.json\" files. Bundlers generally prefer \"module\" over\n// \"main\" but that breaks packages that export a function in \"main\" for use with\n// \"require()\", since resolving to \"module\" means an object will be returned. We\n// attempt to handle this automatically by having import statements resolve to\n// \"module\" but switch that out later for \"main\" if \"require()\" is used too.\ntype PathPair struct {\n\t// Either secondary will be empty, or primary will be \"module\" and secondary\n\t// will be \"main\"\n\tPrimary   logger.Path\n\tSecondary logger.Path\n\n\tIsExternal bool\n}\n\nfunc (pp *PathPair) iter() []*logger.Path {\n\tresult := []*logger.Path{&pp.Primary, &pp.Secondary}\n\tif !pp.HasSecondary() {\n\t\tresult = result[:1]\n\t}\n\treturn result\n}\n\nfunc (pp *PathPair) HasSecondary() bool {\n\treturn pp.Secondary.Text != \"\"\n}\n\ntype SideEffectsData struct {\n\tSource *logger.Source\n\n\t// If non-empty, this false value came from a plugin\n\tPluginName string\n\n\tRange logger.Range\n\n\t// If true, \"sideEffects\" was an array. If false, \"sideEffects\" was false.\n\tIsSideEffectsArrayInJSON bool\n}\n\ntype ResolveResult struct {\n\tPathPair PathPair\n\n\t// If this was resolved by a plugin, the plugin gets to store its data here\n\tPluginData interface{}\n\n\tDifferentCase *fs.DifferentCase\n\n\t// If present, any ES6 imports to this file can be considered to have no side\n\t// effects. This means they should be removed if unused.\n\tPrimarySideEffectsData *SideEffectsData\n\n\t// These are from \"tsconfig.json\"\n\tTSConfigJSX    config.TSConfigJSX\n\tTSConfig       *config.TSConfig\n\tTSAlwaysStrict *config.TSAlwaysStrict\n\n\t// This is the \"type\" field from \"package.json\"\n\tModuleTypeData js_ast.ModuleTypeData\n}\n\ntype suggestionRange uint8\n\nconst (\n\tsuggestionRangeFull suggestionRange = iota\n\tsuggestionRangeEnd\n)\n\ntype DebugMeta struct {\n\tnotes              []logger.MsgData\n\tsuggestionText     string\n\tsuggestionMessage  string\n\tsuggestionRange    suggestionRange\n\tModifiedImportPath string\n}\n\nfunc (dm DebugMeta) LogErrorMsg(log logger.Log, source *logger.Source, r logger.Range, text string, suggestion string, notes []logger.MsgData) {\n\ttracker := logger.MakeLineColumnTracker(source)\n\n\tif source != nil && dm.suggestionMessage != \"\" {\n\t\tsuggestionRange := r\n\t\tif dm.suggestionRange == suggestionRangeEnd {\n\t\t\tsuggestionRange = logger.Range{Loc: logger.Loc{Start: r.End() - 1}}\n\t\t}\n\t\tdata := tracker.MsgData(suggestionRange, dm.suggestionMessage)\n\t\tdata.Location.Suggestion = dm.suggestionText\n\t\tdm.notes = append(dm.notes, data)\n\t}\n\n\tmsg := logger.Msg{\n\t\tKind:  logger.Error,\n\t\tData:  tracker.MsgData(r, text),\n\t\tNotes: append(dm.notes, notes...),\n\t}\n\n\tif msg.Data.Location != nil && suggestion != \"\" {\n\t\tmsg.Data.Location.Suggestion = suggestion\n\t}\n\n\tlog.AddMsg(msg)\n}\n\ntype Resolver struct {\n\tfs     fs.FS\n\tlog    logger.Log\n\tcaches *cache.CacheSet\n\n\ttsConfigOverride *TSConfigJSON\n\n\t// These are sets that represent various conditions for the \"exports\" field\n\t// in package.json.\n\tesmConditionsDefault map[string]bool\n\tesmConditionsImport  map[string]bool\n\tesmConditionsRequire map[string]bool\n\n\t// A special filtered import order for CSS \"@import\" imports.\n\t//\n\t// The \"resolve extensions\" setting determines the order of implicit\n\t// extensions to try when resolving imports with the extension omitted.\n\t// Sometimes people create a JavaScript/TypeScript file and a CSS file with\n\t// the same name when they create a component. At a high level, users expect\n\t// implicit extensions to resolve to the JS file when being imported from JS\n\t// and to resolve to the CSS file when being imported from CSS.\n\t//\n\t// Different bundlers handle this in different ways. Parcel handles this by\n\t// having the resolver prefer the same extension as the importing file in\n\t// front of the configured \"resolve extensions\" order. Webpack's \"css-loader\"\n\t// plugin just explicitly configures a special \"resolve extensions\" order\n\t// consisting of only \".css\" for CSS files.\n\t//\n\t// It's unclear what behavior is best here. What we currently do is to create\n\t// a special filtered version of the configured \"resolve extensions\" order\n\t// for CSS files that filters out any extension that has been explicitly\n\t// configured with a non-CSS loader. This still gives users control over the\n\t// order but avoids the scenario where we match an import in a CSS file to a\n\t// JavaScript-related file. It's probably not perfect with plugins in the\n\t// picture but it's better than some alternatives and probably pretty good.\n\tcssExtensionOrder []string\n\n\t// A special sorted import order for imports inside packages.\n\t//\n\t// The \"resolve extensions\" setting determines the order of implicit\n\t// extensions to try when resolving imports with the extension omitted.\n\t// Sometimes people author a package using TypeScript and publish both the\n\t// compiled JavaScript and the original TypeScript. The compiled JavaScript\n\t// depends on the \"tsconfig.json\" settings that were passed to \"tsc\" when\n\t// it was compiled, and we don't know what they are (they may even be\n\t// unknowable if the \"tsconfig.json\" file wasn't published).\n\t//\n\t// To work around this, we sort TypeScript file extensions after JavaScript\n\t// file extensions (but only within packages) so that esbuild doesn't load\n\t// the original source code in these scenarios. Instead we should load the\n\t// compiled code, which is what will be loaded by node at run-time.\n\tnodeModulesExtensionOrder []string\n\n\t// This cache maps a directory path to information about that directory and\n\t// all parent directories\n\tdirCache map[string]*dirInfo\n\n\tpnpManifestWasChecked bool\n\tpnpManifest           *pnpData\n\n\toptions config.Options\n\n\t// This mutex serves two purposes. First of all, it guards access to \"dirCache\"\n\t// which is potentially mutated during path resolution. But this mutex is also\n\t// necessary for performance. The \"React admin\" benchmark mysteriously runs\n\t// twice as fast when this mutex is locked around the whole resolve operation\n\t// instead of around individual accesses to \"dirCache\". For some reason,\n\t// reducing parallelism in the resolver helps the rest of the bundler go\n\t// faster. I'm not sure why this is but please don't change this unless you\n\t// do a lot of testing with various benchmarks and there aren't any regressions.\n\tmutex sync.Mutex\n}\n\ntype resolverQuery struct {\n\t*Resolver\n\tdebugMeta *DebugMeta\n\tdebugLogs *debugLogs\n\tkind      ast.ImportKind\n}\n\nfunc NewResolver(call config.APICall, fs fs.FS, log logger.Log, caches *cache.CacheSet, options *config.Options) *Resolver {\n\t// Filter out non-CSS extensions for CSS \"@import\" imports\n\tcssExtensionOrder := make([]string, 0, len(options.ExtensionOrder))\n\tfor _, ext := range options.ExtensionOrder {\n\t\tif loader := config.LoaderFromFileExtension(options.ExtensionToLoader, ext); loader == config.LoaderNone || loader.IsCSS() {\n\t\t\tcssExtensionOrder = append(cssExtensionOrder, ext)\n\t\t}\n\t}\n\n\t// Sort all TypeScript file extensions after all JavaScript file extensions\n\t// for imports of files inside of \"node_modules\" directories. But insert\n\t// the TypeScript file extensions right after the last JavaScript file\n\t// extension instead of at the end so that they might come before the\n\t// first CSS file extension, which is important to people that publish\n\t// TypeScript and CSS code to npm with the same file names for both.\n\tnodeModulesExtensionOrder := make([]string, 0, len(options.ExtensionOrder))\n\tsplit := 0\n\tfor i, ext := range options.ExtensionOrder {\n\t\tif loader := config.LoaderFromFileExtension(options.ExtensionToLoader, ext); loader == config.LoaderJS || loader == config.LoaderJSX {\n\t\t\tsplit = i + 1 // Split after the last JavaScript extension\n\t\t}\n\t}\n\tif split != 0 { // Only do this if there are any JavaScript extensions\n\t\tfor _, ext := range options.ExtensionOrder[:split] { // Non-TypeScript extensions before the split\n\t\t\tif loader := config.LoaderFromFileExtension(options.ExtensionToLoader, ext); !loader.IsTypeScript() {\n\t\t\t\tnodeModulesExtensionOrder = append(nodeModulesExtensionOrder, ext)\n\t\t\t}\n\t\t}\n\t\tfor _, ext := range options.ExtensionOrder { // All TypeScript extensions\n\t\t\tif loader := config.LoaderFromFileExtension(options.ExtensionToLoader, ext); loader.IsTypeScript() {\n\t\t\t\tnodeModulesExtensionOrder = append(nodeModulesExtensionOrder, ext)\n\t\t\t}\n\t\t}\n\t\tfor _, ext := range options.ExtensionOrder[split:] { // Non-TypeScript extensions after the split\n\t\t\tif loader := config.LoaderFromFileExtension(options.ExtensionToLoader, ext); !loader.IsTypeScript() {\n\t\t\t\tnodeModulesExtensionOrder = append(nodeModulesExtensionOrder, ext)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Generate the condition sets for interpreting the \"exports\" field\n\tesmConditionsDefault := map[string]bool{\"default\": true}\n\tesmConditionsImport := map[string]bool{\"import\": true}\n\tesmConditionsRequire := map[string]bool{\"require\": true}\n\tfor _, condition := range options.Conditions {\n\t\tesmConditionsDefault[condition] = true\n\t}\n\tswitch options.Platform {\n\tcase config.PlatformBrowser:\n\t\tesmConditionsDefault[\"browser\"] = true\n\tcase config.PlatformNode:\n\t\tesmConditionsDefault[\"node\"] = true\n\t}\n\tfor key := range esmConditionsDefault {\n\t\tesmConditionsImport[key] = true\n\t\tesmConditionsRequire[key] = true\n\t}\n\n\tfs.Cwd()\n\n\tres := &Resolver{\n\t\tfs:                        fs,\n\t\tlog:                       log,\n\t\toptions:                   *options,\n\t\tcaches:                    caches,\n\t\tdirCache:                  make(map[string]*dirInfo),\n\t\tcssExtensionOrder:         cssExtensionOrder,\n\t\tnodeModulesExtensionOrder: nodeModulesExtensionOrder,\n\t\tesmConditionsDefault:      esmConditionsDefault,\n\t\tesmConditionsImport:       esmConditionsImport,\n\t\tesmConditionsRequire:      esmConditionsRequire,\n\t}\n\n\t// Handle the \"tsconfig.json\" override when the resolver is created. This\n\t// isn't done when we validate the build options both because the code for\n\t// \"tsconfig.json\" handling is already in the resolver, and because we want\n\t// watch mode to pick up changes to \"tsconfig.json\" and rebuild.\n\tvar debugMeta DebugMeta\n\tif options.TSConfigPath != \"\" || options.TSConfigRaw != \"\" {\n\t\tr := resolverQuery{\n\t\t\tResolver:  res,\n\t\t\tdebugMeta: &debugMeta,\n\t\t}\n\t\tvar visited map[string]bool\n\t\tvar err error\n\t\tif call == config.BuildCall {\n\t\t\tvisited = make(map[string]bool)\n\t\t}\n\t\tif options.TSConfigPath != \"\" {\n\t\t\tif r.log.Level <= logger.LevelDebug {\n\t\t\t\tr.debugLogs = &debugLogs{what: fmt.Sprintf(\"Resolving tsconfig file %q\", options.TSConfigPath)}\n\t\t\t}\n\t\t\tres.tsConfigOverride, err = r.parseTSConfig(options.TSConfigPath, visited, fs.Dir(options.TSConfigPath))\n\t\t} else {\n\t\t\tsource := logger.Source{\n\t\t\t\tKeyPath:     logger.Path{Text: fs.Join(fs.Cwd(), \"<tsconfig.json>\"), Namespace: \"file\"},\n\t\t\t\tPrettyPaths: logger.PrettyPaths{Abs: \"<tsconfig.json>\", Rel: \"<tsconfig.json>\"},\n\t\t\t\tContents:    options.TSConfigRaw,\n\t\t\t}\n\t\t\tres.tsConfigOverride, err = r.parseTSConfigFromSource(source, visited, fs.Cwd())\n\t\t}\n\t\tif err != nil {\n\t\t\tif err == syscall.ENOENT {\n\t\t\t\tprettyPaths := MakePrettyPaths(r.fs, logger.Path{Text: options.TSConfigPath, Namespace: \"file\"})\n\t\t\t\tr.log.AddError(nil, logger.Range{}, fmt.Sprintf(\"Cannot find tsconfig file %q\",\n\t\t\t\t\tprettyPaths.Select(options.LogPathStyle)))\n\t\t\t} else if err != errParseErrorAlreadyLogged {\n\t\t\t\tprettyPaths := MakePrettyPaths(r.fs, logger.Path{Text: options.TSConfigPath, Namespace: \"file\"})\n\t\t\t\tr.log.AddError(nil, logger.Range{}, fmt.Sprintf(\"Cannot read file %q: %s\",\n\t\t\t\t\tprettyPaths.Select(options.LogPathStyle), err.Error()))\n\t\t\t}\n\t\t} else {\n\t\t\tr.flushDebugLogs(flushDueToSuccess)\n\t\t}\n\t}\n\n\t// Mutate the provided options by settings from \"tsconfig.json\" if present\n\tif res.tsConfigOverride != nil {\n\t\toptions.TS.Config = res.tsConfigOverride.Settings\n\t\tres.tsConfigOverride.JSXSettings.ApplyTo(&options.JSX)\n\t\toptions.TSAlwaysStrict = res.tsConfigOverride.TSAlwaysStrictOrStrict()\n\t}\n\n\treturn res\n}\n\nfunc (res *Resolver) Resolve(sourceDir string, importPath string, kind ast.ImportKind) (*ResolveResult, DebugMeta) {\n\tvar debugMeta DebugMeta\n\tr := resolverQuery{\n\t\tResolver:  res,\n\t\tdebugMeta: &debugMeta,\n\t\tkind:      kind,\n\t}\n\tif r.log.Level <= logger.LevelDebug {\n\t\tr.debugLogs = &debugLogs{what: fmt.Sprintf(\n\t\t\t\"Resolving import %q in directory %q of type %q\",\n\t\t\timportPath, sourceDir, kind.StringForMetafile())}\n\t}\n\n\t// Apply package alias substitutions first\n\tif r.options.PackageAliases != nil && IsPackagePath(importPath) {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(\"Checking for package alias matches\")\n\t\t}\n\t\tlongestKey := \"\"\n\t\tlongestValue := \"\"\n\n\t\tfor key, value := range r.options.PackageAliases {\n\t\t\tif len(key) > len(longestKey) && strings.HasPrefix(importPath, key) && (len(importPath) == len(key) || importPath[len(key)] == '/') {\n\t\t\t\tlongestKey = key\n\t\t\t\tlongestValue = value\n\t\t\t}\n\t\t}\n\n\t\tif longestKey != \"\" {\n\t\t\tdebugMeta.ModifiedImportPath = longestValue\n\t\t\tif tail := importPath[len(longestKey):]; tail != \"/\" {\n\t\t\t\t// Don't include the trailing characters if they are equal to a\n\t\t\t\t// single slash. This comes up because you can abuse this quirk of\n\t\t\t\t// node's path resolution to force node to load the package from the\n\t\t\t\t// file system instead of as a built-in module. For example, \"util\"\n\t\t\t\t// is node's built-in module while \"util/\" is one on the file system.\n\t\t\t\t// Leaving the trailing slash in place causes problems for people:\n\t\t\t\t// https://github.com/evanw/esbuild/issues/2730. It should be ok to\n\t\t\t\t// always strip the trailing slash even when using the alias feature\n\t\t\t\t// to swap one package for another (except when you swap a reference\n\t\t\t\t// to one built-in node module with another but really why would you\n\t\t\t\t// do that).\n\t\t\t\tdebugMeta.ModifiedImportPath += tail\n\t\t\t}\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Matched with alias from %q to %q\", longestKey, longestValue))\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Modified import path from %q to %q\", importPath, debugMeta.ModifiedImportPath))\n\t\t\t}\n\t\t\timportPath = debugMeta.ModifiedImportPath\n\n\t\t\t// Resolve the package using the current path instead of the original\n\t\t\t// path. This is trying to resolve the substitute in the top-level\n\t\t\t// package instead of the nested package, which lets the top-level\n\t\t\t// package control the version of the substitution. It's also critical\n\t\t\t// when using Yarn PnP because Yarn PnP doesn't allow nested packages\n\t\t\t// to \"reach outside\" of their normal dependency lists.\n\t\t\tsourceDir = r.fs.Cwd()\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Changed resolve directory to %q\", sourceDir))\n\t\t\t}\n\t\t} else if r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(\"  Failed to find any package alias matches\")\n\t\t}\n\t}\n\n\t// Certain types of URLs default to being external for convenience\n\tif isExplicitlyExternal := r.isExternal(r.options.ExternalSettings.PreResolve, importPath, kind); isExplicitlyExternal ||\n\n\t\t// \"fill: url(#filter);\"\n\t\t(kind == ast.ImportURL && strings.HasPrefix(importPath, \"#\")) ||\n\n\t\t// \"background: url(http://example.com/images/image.png);\"\n\t\tstrings.HasPrefix(importPath, \"http://\") ||\n\n\t\t// \"background: url(https://example.com/images/image.png);\"\n\t\tstrings.HasPrefix(importPath, \"https://\") ||\n\n\t\t// \"background: url(//example.com/images/image.png);\"\n\t\tstrings.HasPrefix(importPath, \"//\") {\n\n\t\tif r.debugLogs != nil {\n\t\t\tif isExplicitlyExternal {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The path %q was marked as external by the user\", importPath))\n\t\t\t} else {\n\t\t\t\tr.debugLogs.addNote(\"Marking this path as implicitly external\")\n\t\t\t}\n\t\t}\n\n\t\tr.flushDebugLogs(flushDueToSuccess)\n\t\treturn &ResolveResult{\n\t\t\tPathPair: PathPair{Primary: logger.Path{Text: importPath}, IsExternal: true},\n\t\t}, debugMeta\n\t}\n\n\tif pathPair, ok, sideEffects := r.checkForBuiltInNodeModules(importPath); ok {\n\t\tr.flushDebugLogs(flushDueToSuccess)\n\t\treturn &ResolveResult{\n\t\t\tPathPair:               pathPair,\n\t\t\tPrimarySideEffectsData: sideEffects,\n\t\t}, debugMeta\n\t}\n\n\tif parsed, ok := ParseDataURL(importPath); ok {\n\t\t// \"import 'data:text/javascript,console.log(123)';\"\n\t\t// \"@import 'data:text/css,body{background:white}';\"\n\t\tif parsed.DecodeMIMEType() != MIMETypeUnsupported {\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(\"Putting this path in the \\\"dataurl\\\" namespace\")\n\t\t\t}\n\t\t\tr.flushDebugLogs(flushDueToSuccess)\n\t\t\treturn &ResolveResult{\n\t\t\t\tPathPair: PathPair{Primary: logger.Path{Text: importPath, Namespace: \"dataurl\"}},\n\t\t\t}, debugMeta\n\t\t}\n\n\t\t// \"background: url(data:image/png;base64,iVBORw0KGgo=);\"\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(\"Marking this data URL as external\")\n\t\t}\n\t\tr.flushDebugLogs(flushDueToSuccess)\n\t\treturn &ResolveResult{\n\t\t\tPathPair: PathPair{Primary: logger.Path{Text: importPath}, IsExternal: true},\n\t\t}, debugMeta\n\t}\n\n\t// Fail now if there is no directory to resolve in. This can happen for\n\t// virtual modules (e.g. stdin) if a resolve directory is not specified.\n\tif sourceDir == \"\" {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(\"Cannot resolve this path without a directory\")\n\t\t}\n\t\tr.flushDebugLogs(flushDueToFailure)\n\t\treturn nil, debugMeta\n\t}\n\n\t// Glob imports only work in a multi-path context\n\tif strings.ContainsRune(importPath, '*') {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(\"Cannot resolve a path containing a wildcard character in a single-path context\")\n\t\t}\n\t\tr.flushDebugLogs(flushDueToFailure)\n\t\treturn nil, debugMeta\n\t}\n\n\tr.mutex.Lock()\n\tdefer r.mutex.Unlock()\n\n\t// Check for the Yarn PnP manifest if it hasn't already been checked for\n\tif !r.pnpManifestWasChecked {\n\t\tr.pnpManifestWasChecked = true\n\n\t\t// Use the current working directory to find the Yarn PnP manifest. We\n\t\t// can't necessarily use the entry point locations because the entry\n\t\t// point locations aren't necessarily file paths. For example, they could\n\t\t// be HTTP URLs that will be handled by a plugin.\n\t\tfor dirInfo := r.dirInfoCached(r.fs.Cwd()); dirInfo != nil; dirInfo = dirInfo.parent {\n\t\t\tif absPath := dirInfo.pnpManifestAbsPath; absPath != \"\" {\n\t\t\t\tif strings.HasSuffix(absPath, \".json\") {\n\t\t\t\t\tif json, source := r.extractYarnPnPDataFromJSON(absPath, pnpReportErrorsAboutMissingFiles); json.Data != nil {\n\t\t\t\t\t\tr.pnpManifest = compileYarnPnPData(absPath, r.fs.Dir(absPath), json, source)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif json, source := r.tryToExtractYarnPnPDataFromJS(absPath, pnpReportErrorsAboutMissingFiles); json.Data != nil {\n\t\t\t\t\t\tr.pnpManifest = compileYarnPnPData(absPath, r.fs.Dir(absPath), json, source)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif r.debugLogs != nil && r.pnpManifest != nil && r.pnpManifest.invalidIgnorePatternData != \"\" {\n\t\t\t\t\tr.debugLogs.addNote(\"  Invalid Go regular expression for \\\"ignorePatternData\\\": \" + r.pnpManifest.invalidIgnorePatternData)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tsourceDirInfo := r.dirInfoCached(sourceDir)\n\tif sourceDirInfo == nil {\n\t\t// Bail if the directory is missing for some reason\n\t\treturn nil, debugMeta\n\t}\n\n\tresult := r.resolveWithoutSymlinks(sourceDir, sourceDirInfo, importPath)\n\tif result == nil {\n\t\t// If resolution failed, try again with the URL query and/or hash removed\n\t\tsuffix := strings.IndexAny(importPath, \"?#\")\n\t\tif suffix < 1 {\n\t\t\tr.flushDebugLogs(flushDueToFailure)\n\t\t\treturn nil, debugMeta\n\t\t}\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Retrying resolution after removing the suffix %q\", importPath[suffix:]))\n\t\t}\n\t\tif result2 := r.resolveWithoutSymlinks(sourceDir, sourceDirInfo, importPath[:suffix]); result2 == nil {\n\t\t\tr.flushDebugLogs(flushDueToFailure)\n\t\t\treturn nil, debugMeta\n\t\t} else {\n\t\t\tresult = result2\n\t\t\tresult.PathPair.Primary.IgnoredSuffix = importPath[suffix:]\n\t\t\tif result.PathPair.HasSecondary() {\n\t\t\t\tresult.PathPair.Secondary.IgnoredSuffix = importPath[suffix:]\n\t\t\t}\n\t\t}\n\t}\n\n\t// If successful, resolve symlinks using the directory info cache\n\tr.finalizeResolve(result)\n\tr.flushDebugLogs(flushDueToSuccess)\n\treturn result, debugMeta\n}\n\n// This returns nil on failure and non-nil on success. Note that this may\n// return an empty array to indicate a successful search that returned zero\n// results.\nfunc (res *Resolver) ResolveGlob(sourceDir string, importPathPattern []helpers.GlobPart, kind ast.ImportKind, prettyPattern string) (map[string]ResolveResult, *logger.Msg) {\n\tvar debugMeta DebugMeta\n\tr := resolverQuery{\n\t\tResolver:  res,\n\t\tdebugMeta: &debugMeta,\n\t\tkind:      kind,\n\t}\n\n\tif r.log.Level <= logger.LevelDebug {\n\t\tr.debugLogs = &debugLogs{what: fmt.Sprintf(\n\t\t\t\"Resolving glob import %s in directory %q of type %q\",\n\t\t\tprettyPattern, sourceDir, kind.StringForMetafile())}\n\t}\n\n\tif len(importPathPattern) == 0 {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(\"Ignoring empty glob pattern\")\n\t\t}\n\t\tr.flushDebugLogs(flushDueToFailure)\n\t\treturn nil, nil\n\t}\n\tfirstPrefix := importPathPattern[0].Prefix\n\n\t// Glob patterns only work for relative URLs\n\tif !strings.HasPrefix(firstPrefix, \"./\") && !strings.HasPrefix(firstPrefix, \"../\") &&\n\t\t!strings.HasPrefix(firstPrefix, \".\\\\\") && !strings.HasPrefix(firstPrefix, \"..\\\\\") {\n\t\tif kind == ast.ImportEntryPoint {\n\t\t\t// Be permissive about forgetting \"./\" for entry points since it's common\n\t\t\t// to omit \"./\" on the command line. But don't accidentally treat absolute\n\t\t\t// paths as relative (even on Windows).\n\t\t\tif !r.fs.IsAbs(firstPrefix) {\n\t\t\t\tfirstPrefix = \"./\" + firstPrefix\n\t\t\t}\n\t\t} else {\n\t\t\t// Don't allow omitting \"./\" for other imports since node doesn't let you do this either\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(\"Ignoring glob import that doesn't start with \\\"./\\\" or \\\"../\\\"\")\n\t\t\t}\n\t\t\tr.flushDebugLogs(flushDueToFailure)\n\t\t\treturn nil, nil\n\t\t}\n\t}\n\n\t// Handle leading directories in the pattern (including \"../\")\n\tdirPrefix := 0\n\tfor {\n\t\tslash := strings.IndexAny(firstPrefix[dirPrefix:], \"/\\\\\")\n\t\tif slash == -1 {\n\t\t\tbreak\n\t\t}\n\t\tif star := strings.IndexByte(firstPrefix[dirPrefix:], '*'); star != -1 && slash > star {\n\t\t\tbreak\n\t\t}\n\t\tdirPrefix += slash + 1\n\t}\n\n\t// If the pattern is an absolute path, then just replace source directory.\n\t// Otherwise join the source directory with the prefix from the pattern.\n\tif suffix := firstPrefix[:dirPrefix]; r.fs.IsAbs(suffix) {\n\t\tsourceDir = suffix\n\t} else {\n\t\tsourceDir = r.fs.Join(sourceDir, suffix)\n\t}\n\n\tr.mutex.Lock()\n\tdefer r.mutex.Unlock()\n\n\t// Look up the directory to start from\n\tsourceDirInfo := r.dirInfoCached(sourceDir)\n\tif sourceDirInfo == nil {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Failed to find the directory %q\", sourceDir))\n\t\t}\n\t\tr.flushDebugLogs(flushDueToFailure)\n\t\treturn nil, nil\n\t}\n\n\t// Turn the glob pattern into a regular expression\n\tcanMatchOnSlash := false\n\twasGlobStar := false\n\tsb := strings.Builder{}\n\tsb.WriteByte('^')\n\tfor i, part := range importPathPattern {\n\t\tprefix := part.Prefix\n\t\tif i == 0 {\n\t\t\tprefix = firstPrefix\n\t\t}\n\t\tif wasGlobStar && len(prefix) > 0 && (prefix[0] == '/' || prefix[0] == '\\\\') {\n\t\t\tprefix = prefix[1:] // Move over the \"/\" after a globstar\n\t\t}\n\t\tsb.WriteString(regexp.QuoteMeta(prefix))\n\t\tswitch part.Wildcard {\n\t\tcase helpers.GlobAllIncludingSlash:\n\t\t\t// It's a globstar, so match zero or more path segments\n\t\t\tsb.WriteString(\"(?:[^/]*(?:/|$))*\")\n\t\t\tcanMatchOnSlash = true\n\t\t\twasGlobStar = true\n\t\tcase helpers.GlobAllExceptSlash:\n\t\t\t// It's not a globstar, so only match one path segment\n\t\t\tsb.WriteString(\"[^/]*\")\n\t\t\twasGlobStar = false\n\t\t}\n\t}\n\tsb.WriteByte('$')\n\tre := regexp.MustCompile(sb.String())\n\n\t// Initialize \"results\" to a non-nil value to indicate that the glob is valid\n\tresults := make(map[string]ResolveResult)\n\n\tvar visit func(dirInfo *dirInfo, dir string)\n\tvisit = func(dirInfo *dirInfo, dir string) {\n\t\tfor _, key := range dirInfo.entries.SortedKeys() {\n\t\t\tentry, _ := dirInfo.entries.Get(key)\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Considering entry %q\", r.fs.Join(dirInfo.absPath, key)))\n\t\t\t\tr.debugLogs.increaseIndent()\n\t\t\t}\n\n\t\t\tswitch entry.Kind(r.fs) {\n\t\t\tcase fs.DirEntry:\n\t\t\t\t// To avoid infinite loops, don't follow any symlinks\n\t\t\t\tif canMatchOnSlash && entry.Symlink(r.fs) == \"\" {\n\t\t\t\t\tif childDirInfo := r.dirInfoCached(r.fs.Join(dirInfo.absPath, key)); childDirInfo != nil {\n\t\t\t\t\t\tvisit(childDirInfo, fmt.Sprintf(\"%s%s/\", dir, key))\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tcase fs.FileEntry:\n\t\t\t\tif relPath := dir + key; re.MatchString(relPath) {\n\t\t\t\t\tvar result ResolveResult\n\n\t\t\t\t\tif r.isExternal(r.options.ExternalSettings.PreResolve, relPath, kind) {\n\t\t\t\t\t\tresult.PathPair = PathPair{Primary: logger.Path{Text: relPath}, IsExternal: true}\n\n\t\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The path %q was marked as external by the user\", result.PathPair.Primary.Text))\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tabsPath := r.fs.Join(dirInfo.absPath, key)\n\t\t\t\t\t\tresult.PathPair = PathPair{Primary: logger.Path{Text: absPath, Namespace: \"file\"}}\n\t\t\t\t\t}\n\n\t\t\t\t\tr.finalizeResolve(&result)\n\t\t\t\t\tresults[relPath] = result\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.decreaseIndent()\n\t\t\t}\n\t\t}\n\t}\n\n\tvisit(sourceDirInfo, firstPrefix[:dirPrefix])\n\n\tvar warning *logger.Msg\n\tif len(results) == 0 {\n\t\twarning = &logger.Msg{\n\t\t\tID:   logger.MsgID_Bundler_EmptyGlob,\n\t\t\tKind: logger.Warning,\n\t\t\tData: logger.MsgData{Text: fmt.Sprintf(\"The glob pattern %s did not match any files\", prettyPattern)},\n\t\t}\n\t}\n\n\tr.flushDebugLogs(flushDueToSuccess)\n\treturn results, warning\n}\n\nfunc (r resolverQuery) isExternal(matchers config.ExternalMatchers, path string, kind ast.ImportKind) bool {\n\tif kind == ast.ImportEntryPoint {\n\t\t// Never mark an entry point as external. This is not useful.\n\t\treturn false\n\t}\n\tif _, ok := matchers.Exact[path]; ok {\n\t\treturn true\n\t}\n\tfor _, pattern := range matchers.Patterns {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Checking %q against the external pattern %q\", path, pattern.Prefix+\"*\"+pattern.Suffix))\n\t\t}\n\t\tif len(path) >= len(pattern.Prefix)+len(pattern.Suffix) &&\n\t\t\tstrings.HasPrefix(path, pattern.Prefix) &&\n\t\t\tstrings.HasSuffix(path, pattern.Suffix) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// This tries to run \"Resolve\" on a package path as a relative path. If\n// successful, the user just forgot a leading \"./\" in front of the path.\nfunc (res *Resolver) ProbeResolvePackageAsRelative(sourceDir string, importPath string, kind ast.ImportKind) (*ResolveResult, DebugMeta) {\n\tvar debugMeta DebugMeta\n\tr := resolverQuery{\n\t\tResolver:  res,\n\t\tdebugMeta: &debugMeta,\n\t\tkind:      kind,\n\t}\n\tabsPath := r.fs.Join(sourceDir, importPath)\n\n\tr.mutex.Lock()\n\tdefer r.mutex.Unlock()\n\n\tif pair, ok, diffCase := r.loadAsFileOrDirectory(absPath); ok {\n\t\tresult := &ResolveResult{PathPair: pair, DifferentCase: diffCase}\n\t\tr.finalizeResolve(result)\n\t\tr.flushDebugLogs(flushDueToSuccess)\n\t\treturn result, debugMeta\n\t}\n\n\treturn nil, debugMeta\n}\n\ntype debugLogs struct {\n\twhat   string\n\tindent string\n\tnotes  []logger.MsgData\n}\n\nfunc (d *debugLogs) addNote(text string) {\n\tif d.indent != \"\" {\n\t\ttext = d.indent + text\n\t}\n\td.notes = append(d.notes, logger.MsgData{Text: text, DisableMaximumWidth: true})\n}\n\nfunc (d *debugLogs) increaseIndent() {\n\td.indent += \"  \"\n}\n\nfunc (d *debugLogs) decreaseIndent() {\n\td.indent = d.indent[2:]\n}\n\ntype flushMode uint8\n\nconst (\n\tflushDueToFailure flushMode = iota\n\tflushDueToSuccess\n)\n\nfunc (r resolverQuery) flushDebugLogs(mode flushMode) {\n\tif r.debugLogs != nil {\n\t\tif mode == flushDueToFailure {\n\t\t\tr.log.AddIDWithNotes(logger.MsgID_None, logger.Debug, nil, logger.Range{}, r.debugLogs.what, r.debugLogs.notes)\n\t\t} else if r.log.Level <= logger.LevelVerbose {\n\t\t\tr.log.AddIDWithNotes(logger.MsgID_None, logger.Verbose, nil, logger.Range{}, r.debugLogs.what, r.debugLogs.notes)\n\t\t}\n\t}\n}\n\nfunc (r resolverQuery) finalizeResolve(result *ResolveResult) {\n\tif !result.PathPair.IsExternal && r.isExternal(r.options.ExternalSettings.PostResolve, result.PathPair.Primary.Text, r.kind) {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The path %q was marked as external by the user\", result.PathPair.Primary.Text))\n\t\t}\n\t\tresult.PathPair.IsExternal = true\n\t} else {\n\t\tfor i, path := range result.PathPair.iter() {\n\t\t\tif path.Namespace != \"file\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tdirInfo := r.dirInfoCached(r.fs.Dir(path.Text))\n\t\t\tif dirInfo == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tbase := r.fs.Base(path.Text)\n\n\t\t\t// If the path contains symlinks, rewrite the path to the real path\n\t\t\tif !r.options.PreserveSymlinks {\n\t\t\t\tif entry, _ := dirInfo.entries.Get(base); entry != nil {\n\t\t\t\t\tsymlink := entry.Symlink(r.fs)\n\t\t\t\t\tif symlink != \"\" {\n\t\t\t\t\t\t// This means the entry itself is a symlink\n\t\t\t\t\t} else if dirInfo.absRealPath != \"\" {\n\t\t\t\t\t\t// There is at least one parent directory with a symlink\n\t\t\t\t\t\tsymlink = r.fs.Join(dirInfo.absRealPath, base)\n\t\t\t\t\t}\n\t\t\t\t\tif symlink != \"\" {\n\t\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Resolved symlink %q to %q\", path.Text, symlink))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpath.Text = symlink\n\n\t\t\t\t\t\t// Look up the directory over again if it was changed\n\t\t\t\t\t\tdirInfo = r.dirInfoCached(r.fs.Dir(path.Text))\n\t\t\t\t\t\tif dirInfo == nil {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbase = r.fs.Base(path.Text)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Path attributes are only taken from the primary path\n\t\t\tif i > 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Path attributes are not taken from disabled files\n\t\t\tif path.IsDisabled() {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Look up this file in the \"sideEffects\" map in the nearest enclosing\n\t\t\t// directory with a \"package.json\" file.\n\t\t\t//\n\t\t\t// Only do this for the primary path. Some packages have the primary\n\t\t\t// path marked as having side effects and the secondary path marked\n\t\t\t// as not having side effects. This is likely a bug in the package\n\t\t\t// definition but we don't want to consider the primary path as not\n\t\t\t// having side effects just because the secondary path is marked as\n\t\t\t// not having side effects.\n\t\t\tif pkgJSON := dirInfo.enclosingPackageJSON; pkgJSON != nil {\n\t\t\t\tif pkgJSON.sideEffectsMap != nil {\n\t\t\t\t\thasSideEffects := false\n\t\t\t\t\tpathLookup := strings.ReplaceAll(path.Text, \"\\\\\", \"/\") // Avoid problems with Windows-style slashes\n\t\t\t\t\tif pkgJSON.sideEffectsMap[pathLookup] {\n\t\t\t\t\t\t// Fast path: map lookup\n\t\t\t\t\t\thasSideEffects = true\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Slow path: glob tests\n\t\t\t\t\t\tfor _, re := range pkgJSON.sideEffectsRegexps {\n\t\t\t\t\t\t\tif re.MatchString(pathLookup) {\n\t\t\t\t\t\t\t\thasSideEffects = true\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif !hasSideEffects {\n\t\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Marking this file as having no side effects due to %q\",\n\t\t\t\t\t\t\t\tpkgJSON.source.KeyPath.Text))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresult.PrimarySideEffectsData = pkgJSON.sideEffectsData\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Also copy over the \"type\" field\n\t\t\t\tresult.ModuleTypeData = pkgJSON.moduleTypeData\n\t\t\t}\n\n\t\t\t// Copy various fields from the nearest enclosing \"tsconfig.json\" file if present\n\t\t\tif tsConfigJSON := r.tsConfigForDir(dirInfo); tsConfigJSON != nil {\n\t\t\t\tresult.TSConfig = &tsConfigJSON.Settings\n\t\t\t\tresult.TSConfigJSX = tsConfigJSON.JSXSettings\n\t\t\t\tresult.TSAlwaysStrict = tsConfigJSON.TSAlwaysStrictOrStrict()\n\n\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"This import is under the effect of %q\",\n\t\t\t\t\t\ttsConfigJSON.AbsPath))\n\t\t\t\t\tif result.TSConfigJSX.JSXFactory != nil {\n\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"\\\"jsxFactory\\\" is %q due to %q\",\n\t\t\t\t\t\t\tstrings.Join(result.TSConfigJSX.JSXFactory, \".\"),\n\t\t\t\t\t\t\ttsConfigJSON.AbsPath))\n\t\t\t\t\t}\n\t\t\t\t\tif result.TSConfigJSX.JSXFragmentFactory != nil {\n\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"\\\"jsxFragment\\\" is %q due to %q\",\n\t\t\t\t\t\t\tstrings.Join(result.TSConfigJSX.JSXFragmentFactory, \".\"),\n\t\t\t\t\t\t\ttsConfigJSON.AbsPath))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Primary path is %q in namespace %q\", result.PathPair.Primary.Text, result.PathPair.Primary.Namespace))\n\t\tif result.PathPair.HasSecondary() {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Secondary path is %q in namespace %q\", result.PathPair.Secondary.Text, result.PathPair.Secondary.Namespace))\n\t\t}\n\t}\n}\n\nfunc (r resolverQuery) resolveWithoutSymlinks(sourceDir string, sourceDirInfo *dirInfo, importPath string) *ResolveResult {\n\t// This implements the module resolution algorithm from node.js, which is\n\t// described here: https://nodejs.org/api/modules.html#modules_all_together\n\tvar result ResolveResult\n\n\t// Return early if this is already an absolute path. In addition to asking\n\t// the file system whether this is an absolute path, we also explicitly check\n\t// whether it starts with a \"/\" and consider that an absolute path too. This\n\t// is because relative paths can technically start with a \"/\" on Windows\n\t// because it's not an absolute path on Windows. Then people might write code\n\t// with imports that start with a \"/\" that works fine on Windows only to\n\t// experience unexpected build failures later on other operating systems.\n\t// Treating these paths as absolute paths on all platforms means Windows\n\t// users will not be able to accidentally make use of these paths.\n\tif strings.HasPrefix(importPath, \"/\") || r.fs.IsAbs(importPath) {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The import %q is being treated as an absolute path\", importPath))\n\t\t}\n\n\t\t// First, check path overrides from the nearest enclosing TypeScript \"tsconfig.json\" file\n\t\tif tsConfigJSON := r.tsConfigForDir(sourceDirInfo); tsConfigJSON != nil && tsConfigJSON.Paths != nil {\n\t\t\tif absolute, ok, diffCase := r.matchTSConfigPaths(tsConfigJSON, importPath); ok {\n\t\t\t\treturn &ResolveResult{PathPair: absolute, DifferentCase: diffCase}\n\t\t\t}\n\t\t}\n\n\t\t// Run node's resolution rules (e.g. adding \".js\")\n\t\tif absolute, ok, diffCase := r.loadAsFileOrDirectory(importPath); ok {\n\t\t\treturn &ResolveResult{PathPair: absolute, DifferentCase: diffCase}\n\t\t} else {\n\t\t\treturn nil\n\t\t}\n\t}\n\n\t// Check both relative and package paths for CSS URL tokens, with relative\n\t// paths taking precedence over package paths to match Webpack behavior.\n\tisPackagePath := IsPackagePath(importPath)\n\tcheckRelative := !isPackagePath || r.kind.IsFromCSS()\n\tcheckPackage := isPackagePath\n\n\tif checkRelative {\n\t\tabsPath := r.fs.Join(sourceDir, importPath)\n\n\t\t// Check for external packages first\n\t\tif r.isExternal(r.options.ExternalSettings.PostResolve, absPath, r.kind) {\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The path %q was marked as external by the user\", absPath))\n\t\t\t}\n\t\t\treturn &ResolveResult{PathPair: PathPair{Primary: logger.Path{Text: absPath, Namespace: \"file\"}, IsExternal: true}}\n\t\t}\n\n\t\t// Node's actual behavior deviates from its published algorithm by not\n\t\t// running the \"LOAD_AS_FILE\" step if the import path looks like it\n\t\t// resolves to a directory instead of a file. Attempt to replicate that\n\t\t// behavior here. This really only matters for intentionally confusing\n\t\t// edge cases where a directory is named the same thing as a file.\n\t\t// Unfortunately people actually create situations like this.\n\t\thasTrailingSlash := importPath == \".\" ||\n\t\t\timportPath == \"..\" ||\n\t\t\tstrings.HasSuffix(importPath, \"/\") ||\n\t\t\tstrings.HasSuffix(importPath, \"/.\") ||\n\t\t\tstrings.HasSuffix(importPath, \"/..\")\n\n\t\t// Check the \"browser\" map\n\t\tif importDirInfo := r.dirInfoCached(r.fs.Dir(absPath)); importDirInfo != nil {\n\t\t\tif remapped, ok := r.checkBrowserMap(importDirInfo, absPath, absolutePathKind); ok {\n\t\t\t\tif remapped == nil {\n\t\t\t\t\treturn &ResolveResult{PathPair: PathPair{Primary: logger.Path{Text: absPath, Namespace: \"file\", Flags: logger.PathDisabled}}}\n\t\t\t\t}\n\t\t\t\tif remappedResult, ok, diffCase, sideEffects := r.resolveWithoutRemapping(importDirInfo.enclosingBrowserScope, *remapped); ok {\n\t\t\t\t\tresult = ResolveResult{PathPair: remappedResult, DifferentCase: diffCase, PrimarySideEffectsData: sideEffects}\n\t\t\t\t\thasTrailingSlash = false\n\t\t\t\t\tcheckRelative = false\n\t\t\t\t\tcheckPackage = false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif hasTrailingSlash {\n\t\t\tif absolute, ok, diffCase := r.loadAsDirectory(absPath); ok {\n\t\t\t\tcheckPackage = false\n\t\t\t\tresult = ResolveResult{PathPair: absolute, DifferentCase: diffCase}\n\t\t\t} else if !checkPackage {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t} else {\n\t\t\tif checkRelative {\n\t\t\t\tif absolute, ok, diffCase := r.loadAsFileOrDirectory(absPath); ok {\n\t\t\t\t\tcheckPackage = false\n\t\t\t\t\tresult = ResolveResult{PathPair: absolute, DifferentCase: diffCase}\n\t\t\t\t} else if !checkPackage {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif checkPackage {\n\t\t// Support remapping one package path to another via the \"browser\" field\n\t\tif remapped, ok := r.checkBrowserMap(sourceDirInfo, importPath, packagePathKind); ok {\n\t\t\tif remapped == nil {\n\t\t\t\t// \"browser\": {\"module\": false}\n\t\t\t\tif absolute, ok, diffCase, sideEffects := r.loadNodeModules(importPath, sourceDirInfo, false /* forbidImports */); ok {\n\t\t\t\t\tabsolute.Primary = logger.Path{Text: absolute.Primary.Text, Namespace: \"file\", Flags: logger.PathDisabled}\n\t\t\t\t\tif absolute.HasSecondary() {\n\t\t\t\t\t\tabsolute.Secondary = logger.Path{Text: absolute.Secondary.Text, Namespace: \"file\", Flags: logger.PathDisabled}\n\t\t\t\t\t}\n\t\t\t\t\treturn &ResolveResult{PathPair: absolute, DifferentCase: diffCase, PrimarySideEffectsData: sideEffects}\n\t\t\t\t} else {\n\t\t\t\t\treturn &ResolveResult{PathPair: PathPair{Primary: logger.Path{Text: importPath, Flags: logger.PathDisabled}}, DifferentCase: diffCase}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// \"browser\": {\"module\": \"./some-file\"}\n\t\t\t// \"browser\": {\"module\": \"another-module\"}\n\t\t\timportPath = *remapped\n\t\t\tsourceDirInfo = sourceDirInfo.enclosingBrowserScope\n\t\t}\n\n\t\tif absolute, ok, diffCase, sideEffects := r.resolveWithoutRemapping(sourceDirInfo, importPath); ok {\n\t\t\tresult = ResolveResult{PathPair: absolute, DifferentCase: diffCase, PrimarySideEffectsData: sideEffects}\n\t\t} else {\n\t\t\t// Note: node's \"self references\" are not currently supported\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn &result\n}\n\nfunc (r resolverQuery) resolveWithoutRemapping(sourceDirInfo *dirInfo, importPath string) (PathPair, bool, *fs.DifferentCase, *SideEffectsData) {\n\tif IsPackagePath(importPath) {\n\t\treturn r.loadNodeModules(importPath, sourceDirInfo, false /* forbidImports */)\n\t} else {\n\t\tabsolute, ok, diffCase := r.loadAsFileOrDirectory(r.fs.Join(sourceDirInfo.absPath, importPath))\n\t\treturn absolute, ok, diffCase, nil\n\t}\n}\n\nfunc MakePrettyPaths(fs fs.FS, path logger.Path) logger.PrettyPaths {\n\tabsPath := path.Text\n\trelPath := path.Text\n\n\tif path.Namespace == \"file\" {\n\t\tif rel, ok := fs.Rel(fs.Cwd(), relPath); ok {\n\t\t\trelPath = rel\n\t\t}\n\n\t\t// These human-readable paths are used in error messages, comments in output\n\t\t// files, source names in source maps, and paths in the metadata JSON file.\n\t\t// These should be platform-independent so our output doesn't depend on which\n\t\t// operating system it was run. Replace Windows backward slashes with standard\n\t\t// forward slashes.\n\t\trelPath = strings.ReplaceAll(relPath, \"\\\\\", \"/\")\n\t} else if path.Namespace != \"\" {\n\t\tabsPath = fmt.Sprintf(\"%s:%s\", path.Namespace, absPath)\n\t\trelPath = fmt.Sprintf(\"%s:%s\", path.Namespace, relPath)\n\t}\n\n\tif path.IsDisabled() {\n\t\tabsPath = \"(disabled):\" + absPath\n\t\trelPath = \"(disabled):\" + relPath\n\t}\n\n\treturn logger.PrettyPaths{\n\t\tAbs: absPath + path.IgnoredSuffix,\n\t\tRel: relPath + path.IgnoredSuffix,\n\t}\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\ntype dirInfo struct {\n\t// These objects are immutable, so we can just point to the parent directory\n\t// and avoid having to lock the cache again\n\tparent *dirInfo\n\n\t// A pointer to the enclosing dirInfo with a valid \"browser\" field in\n\t// package.json. We need this to remap paths after they have been resolved.\n\tenclosingBrowserScope *dirInfo\n\n\t// All relevant information about this directory\n\tabsPath               string\n\tpnpManifestAbsPath    string\n\tentries               fs.DirEntries\n\tpackageJSON           *packageJSON  // Is there a \"package.json\" file in this directory?\n\tenclosingPackageJSON  *packageJSON  // Is there a \"package.json\" file in this directory or a parent directory?\n\tenclosingTSConfigJSON *TSConfigJSON // Is there a \"tsconfig.json\" file in this directory or a parent directory?\n\tabsRealPath           string        // If non-empty, this is the real absolute path resolving any symlinks\n\tisNodeModules         bool          // Is the base name \"node_modules\"?\n\thasNodeModules        bool          // Is there a \"node_modules\" subdirectory?\n\tisInsideNodeModules   bool          // Is this within a  \"node_modules\" subtree?\n}\n\nfunc (r resolverQuery) tsConfigForDir(dirInfo *dirInfo) *TSConfigJSON {\n\tif dirInfo.isInsideNodeModules {\n\t\treturn nil\n\t}\n\tif r.tsConfigOverride != nil {\n\t\treturn r.tsConfigOverride\n\t}\n\tif dirInfo != nil {\n\t\treturn dirInfo.enclosingTSConfigJSON\n\t}\n\treturn nil\n}\n\nfunc (r resolverQuery) dirInfoCached(path string) *dirInfo {\n\t// First, check the cache\n\tcached, ok := r.dirCache[path]\n\n\t// Cache hit: stop now\n\tif !ok {\n\t\t// Update the cache to indicate failure. Even if the read failed, we don't\n\t\t// want to retry again later. The directory is inaccessible so trying again\n\t\t// is wasted. Doing this before calling \"dirInfoUncached\" prevents stack\n\t\t// overflow in case this directory is recursively encountered again.\n\t\tr.dirCache[path] = nil\n\n\t\t// Cache miss: read the info\n\t\tcached = r.dirInfoUncached(path)\n\n\t\t// Only update the cache again on success\n\t\tif cached != nil {\n\t\t\tr.dirCache[path] = cached\n\t\t}\n\t}\n\n\tif r.debugLogs != nil {\n\t\tif cached == nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Failed to read directory %q\", path))\n\t\t} else {\n\t\t\tcount := cached.entries.PeekEntryCount()\n\t\t\tentries := \"entries\"\n\t\t\tif count == 1 {\n\t\t\t\tentries = \"entry\"\n\t\t\t}\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Read %d %s for directory %q\", count, entries, path))\n\t\t}\n\t}\n\n\treturn cached\n}\n\nvar errParseErrorImportCycle = errors.New(\"(import cycle)\")\nvar errParseErrorAlreadyLogged = errors.New(\"(error already logged)\")\n\n// This may return \"parseErrorAlreadyLogged\" in which case there was a syntax\n// error, but it's already been reported. No further errors should be logged.\n//\n// Nested calls may also return \"parseErrorImportCycle\". In that case the\n// caller is responsible for logging an appropriate error message.\nfunc (r resolverQuery) parseTSConfig(file string, visited map[string]bool, configDir string) (*TSConfigJSON, error) {\n\t// Resolve any symlinks first before parsing the file\n\tif !r.options.PreserveSymlinks {\n\t\tif real, ok := r.fs.EvalSymlinks(file); ok {\n\t\t\tfile = real\n\t\t}\n\t}\n\n\t// Don't infinite loop if a series of \"extends\" links forms a cycle\n\tif visited[file] {\n\t\treturn nil, errParseErrorImportCycle\n\t}\n\n\tcontents, err, originalError := r.caches.FSCache.ReadFile(r.fs, file)\n\tif r.debugLogs != nil && originalError != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Failed to read file %q: %s\", file, originalError.Error()))\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"The file %q exists\", file))\n\t}\n\n\tkeyPath := logger.Path{Text: file, Namespace: \"file\"}\n\tsource := logger.Source{\n\t\tKeyPath:     keyPath,\n\t\tPrettyPaths: MakePrettyPaths(r.fs, keyPath),\n\t\tContents:    contents,\n\t}\n\tif visited != nil {\n\t\t// This is only non-nil for \"build\" API calls. This is nil for \"transform\"\n\t\t// API calls, which tells us to not process \"extends\" fields.\n\t\tvisited[file] = true\n\t}\n\tresult, err := r.parseTSConfigFromSource(source, visited, configDir)\n\tif visited != nil {\n\t\t// Reset this to back false in case something uses TypeScript 5.0's multiple\n\t\t// inheritance feature for \"tsconfig.json\" files. It should be valid to visit\n\t\t// the same base \"tsconfig.json\" file multiple times from different multiple\n\t\t// inheritance subtrees.\n\t\tvisited[file] = false\n\t}\n\treturn result, err\n}\n\nfunc (r resolverQuery) parseTSConfigFromSource(source logger.Source, visited map[string]bool, configDir string) (*TSConfigJSON, error) {\n\ttracker := logger.MakeLineColumnTracker(&source)\n\tfileDir := r.fs.Dir(source.KeyPath.Text)\n\tisExtends := len(visited) > 1\n\n\tresult := ParseTSConfigJSON(r.log, source, &r.caches.JSONCache, r.fs, fileDir, configDir, func(extends string, extendsRange logger.Range) *TSConfigJSON {\n\t\tif visited == nil {\n\t\t\t// If this is nil, then we're in a \"transform\" API call. In that case we\n\t\t\t// deliberately skip processing \"extends\" fields. This is because the\n\t\t\t// \"transform\" API is supposed to be without a file system.\n\t\t\treturn nil\n\t\t}\n\n\t\t// Note: This doesn't use the normal node module resolution algorithm\n\t\t// both because it's different (e.g. we don't want to match a directory)\n\t\t// and because it would deadlock since we're currently in the middle of\n\t\t// populating the directory info cache.\n\n\t\tmaybeFinishOurSearch := func(base *TSConfigJSON, err error, extendsFile string) (*TSConfigJSON, bool) {\n\t\t\tif err == nil {\n\t\t\t\treturn base, true\n\t\t\t}\n\n\t\t\tif err == syscall.ENOENT {\n\t\t\t\t// Return false to indicate that we should continue searching\n\t\t\t\treturn nil, false\n\t\t\t}\n\n\t\t\tif err == errParseErrorImportCycle {\n\t\t\t\tr.log.AddID(logger.MsgID_TSConfigJSON_Cycle, logger.Warning, &tracker, extendsRange,\n\t\t\t\t\tfmt.Sprintf(\"Base config file %q forms cycle\", extends))\n\t\t\t} else if err != errParseErrorAlreadyLogged {\n\t\t\t\tprettyPaths := MakePrettyPaths(r.fs, logger.Path{Text: extendsFile, Namespace: \"file\"})\n\t\t\t\tr.log.AddError(&tracker, extendsRange, fmt.Sprintf(\"Cannot read file %q: %s\",\n\t\t\t\t\tprettyPaths.Select(r.options.LogPathStyle), err.Error()))\n\t\t\t}\n\t\t\treturn nil, true\n\t\t}\n\n\t\t// Check for a Yarn PnP manifest and use that to rewrite the path\n\t\tif IsPackagePath(extends) {\n\t\t\tpnpData := r.pnpManifest\n\n\t\t\t// If we haven't loaded the Yarn PnP manifest yet, try to find one\n\t\t\tif pnpData == nil {\n\t\t\t\tcurrent := fileDir\n\t\t\t\tfor {\n\t\t\t\t\tif _, _, ok := fs.ParseYarnPnPVirtualPath(current); !ok {\n\t\t\t\t\t\tabsPath := r.fs.Join(current, \".pnp.data.json\")\n\t\t\t\t\t\tif json, source := r.extractYarnPnPDataFromJSON(absPath, pnpIgnoreErrorsAboutMissingFiles); json.Data != nil {\n\t\t\t\t\t\t\tpnpData = compileYarnPnPData(absPath, current, json, source)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tabsPath = r.fs.Join(current, \".pnp.cjs\")\n\t\t\t\t\t\tif json, source := r.tryToExtractYarnPnPDataFromJS(absPath, pnpIgnoreErrorsAboutMissingFiles); json.Data != nil {\n\t\t\t\t\t\t\tpnpData = compileYarnPnPData(absPath, current, json, source)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tabsPath = r.fs.Join(current, \".pnp.js\")\n\t\t\t\t\t\tif json, source := r.tryToExtractYarnPnPDataFromJS(absPath, pnpIgnoreErrorsAboutMissingFiles); json.Data != nil {\n\t\t\t\t\t\t\tpnpData = compileYarnPnPData(absPath, current, json, source)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Go to the parent directory, stopping at the file system root\n\t\t\t\t\tnext := r.fs.Dir(current)\n\t\t\t\t\tif current == next {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcurrent = next\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif pnpData != nil {\n\t\t\t\tif result := r.resolveToUnqualified(extends, fileDir, pnpData); result.status == pnpErrorGeneric {\n\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\tr.debugLogs.addNote(\"The Yarn PnP path resolution algorithm returned an error\")\n\t\t\t\t\t}\n\t\t\t\t\tgoto pnpError\n\t\t\t\t} else if result.status == pnpSuccess {\n\t\t\t\t\t// If Yarn PnP path resolution succeeded, run a custom abbreviated\n\t\t\t\t\t// version of node's module resolution algorithm. The Yarn PnP\n\t\t\t\t\t// specification says to use node's module resolution algorithm verbatim\n\t\t\t\t\t// but that isn't what Yarn actually does. See this for more info:\n\t\t\t\t\t// https://github.com/evanw/esbuild/issues/2473#issuecomment-1216774461\n\t\t\t\t\tif entries, _, dirErr := r.fs.ReadDirectory(result.pkgDirPath); dirErr == nil {\n\t\t\t\t\t\tif entry, _ := entries.Get(\"package.json\"); entry != nil && entry.Kind(r.fs) == fs.FileEntry {\n\t\t\t\t\t\t\t// Check the \"exports\" map\n\t\t\t\t\t\t\tif packageJSON := r.parsePackageJSON(result.pkgDirPath); packageJSON != nil && packageJSON.exportsMap != nil {\n\t\t\t\t\t\t\t\tif absolute, ok, _ := r.esmResolveAlgorithm(finalizeImportsExportsYarnPnPTSConfigExtends,\n\t\t\t\t\t\t\t\t\tresult.pkgIdent, \".\"+result.pkgSubpath, packageJSON, result.pkgDirPath, source.KeyPath.Text); ok {\n\t\t\t\t\t\t\t\t\tbase, err := r.parseTSConfig(absolute.Primary.Text, visited, configDir)\n\t\t\t\t\t\t\t\t\tif result, shouldReturn := maybeFinishOurSearch(base, err, absolute.Primary.Text); shouldReturn {\n\t\t\t\t\t\t\t\t\t\treturn result\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tgoto pnpError\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Continue with the module resolution algorithm from node.js\n\t\t\t\t\textends = r.fs.Join(result.pkgDirPath, result.pkgSubpath)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif IsPackagePath(extends) && !r.fs.IsAbs(extends) {\n\t\t\tesmPackageName, esmPackageSubpath, esmOK := esmParsePackageName(extends)\n\t\t\tif r.debugLogs != nil && esmOK {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Parsed tsconfig package name %q and package subpath %q\", esmPackageName, esmPackageSubpath))\n\t\t\t}\n\n\t\t\t// If this is still a package path, try to resolve it to a \"node_modules\" directory\n\t\t\tcurrent := fileDir\n\t\t\tfor {\n\t\t\t\t// Skip \"node_modules\" folders\n\t\t\t\tif r.fs.Base(current) != \"node_modules\" {\n\t\t\t\t\tjoin := r.fs.Join(current, \"node_modules\", extends)\n\n\t\t\t\t\t// Check to see if \"package.json\" exists\n\t\t\t\t\tpkgDir := r.fs.Join(current, \"node_modules\", esmPackageName)\n\t\t\t\t\tpjFile := r.fs.Join(pkgDir, \"package.json\")\n\t\t\t\t\tif _, err, originalError := r.fs.ReadFile(pjFile); err == nil {\n\t\t\t\t\t\tif packageJSON := r.parsePackageJSON(pkgDir); packageJSON != nil {\n\t\t\t\t\t\t\t// Try checking the \"tsconfig\" field of \"package.json\". The ability to use \"extends\" like this was added in TypeScript 3.2:\n\t\t\t\t\t\t\t// https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-2.html#tsconfigjson-inheritance-via-nodejs-packages\n\t\t\t\t\t\t\tif packageJSON.tsconfig != \"\" {\n\t\t\t\t\t\t\t\tjoin = packageJSON.tsconfig\n\t\t\t\t\t\t\t\tif !r.fs.IsAbs(join) {\n\t\t\t\t\t\t\t\t\tjoin = r.fs.Join(pkgDir, join)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Try checking the \"exports\" map. The ability to use \"extends\" like this was added in TypeScript 5.0:\n\t\t\t\t\t\t\t// https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/\n\t\t\t\t\t\t\tif packageJSON.exportsMap != nil {\n\t\t\t\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Looking for %q in \\\"exports\\\" map in %q\", esmPackageSubpath, packageJSON.source.KeyPath.Text))\n\t\t\t\t\t\t\t\t\tr.debugLogs.increaseIndent()\n\t\t\t\t\t\t\t\t\tdefer r.debugLogs.decreaseIndent()\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Note: TypeScript appears to always treat this as a \"require\" import\n\t\t\t\t\t\t\t\tconditions := r.esmConditionsRequire\n\t\t\t\t\t\t\t\tresolvedPath, status, debug := r.esmPackageExportsResolve(\"/\", esmPackageSubpath, packageJSON.exportsMap.root, conditions)\n\t\t\t\t\t\t\t\tresolvedPath, status, debug = r.esmHandlePostConditions(resolvedPath, status, debug)\n\n\t\t\t\t\t\t\t\t// This is a very abbreviated version of our ESM resolution\n\t\t\t\t\t\t\t\tif status == pjStatusExact || status == pjStatusExactEndsWithStar {\n\t\t\t\t\t\t\t\t\tfileToCheck := r.fs.Join(pkgDir, resolvedPath)\n\t\t\t\t\t\t\t\t\tbase, err := r.parseTSConfig(fileToCheck, visited, configDir)\n\n\t\t\t\t\t\t\t\t\tif result, shouldReturn := maybeFinishOurSearch(base, err, fileToCheck); shouldReturn {\n\t\t\t\t\t\t\t\t\t\treturn result\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if r.debugLogs != nil && originalError != nil {\n\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Failed to read file %q: %s\", pjFile, originalError.Error()))\n\t\t\t\t\t}\n\n\t\t\t\t\tfilesToCheck := []string{r.fs.Join(join, \"tsconfig.json\"), join, join + \".json\"}\n\t\t\t\t\tfor _, fileToCheck := range filesToCheck {\n\t\t\t\t\t\tbase, err := r.parseTSConfig(fileToCheck, visited, configDir)\n\n\t\t\t\t\t\t// Explicitly ignore matches if they are directories instead of files\n\t\t\t\t\t\tif err != nil && err != syscall.ENOENT {\n\t\t\t\t\t\t\tif entries, _, dirErr := r.fs.ReadDirectory(r.fs.Dir(fileToCheck)); dirErr == nil {\n\t\t\t\t\t\t\t\tif entry, _ := entries.Get(r.fs.Base(fileToCheck)); entry != nil && entry.Kind(r.fs) == fs.DirEntry {\n\t\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif result, shouldReturn := maybeFinishOurSearch(base, err, fileToCheck); shouldReturn {\n\t\t\t\t\t\t\treturn result\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Go to the parent directory, stopping at the file system root\n\t\t\t\tnext := r.fs.Dir(current)\n\t\t\t\tif current == next {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcurrent = next\n\t\t\t}\n\t\t} else {\n\t\t\textendsFile := extends\n\n\t\t\t// The TypeScript compiler has a strange behavior that seems like a bug\n\t\t\t// where \".\" and \"..\" behave differently than other forms such as \"./.\"\n\t\t\t// or \"../.\" and are interpreted as having an implicit \"tsconfig.json\"\n\t\t\t// suffix.\n\t\t\t//\n\t\t\t// I believe their bug is caused by some parts of their code checking for\n\t\t\t// relative paths using the literal \"./\" and \"../\" prefixes (requiring\n\t\t\t// the slash) and other parts checking using the regular expression\n\t\t\t// /^\\.\\.?($|[\\\\/])/ (with the slash optional).\n\t\t\t//\n\t\t\t// In any case, people are now relying on this behavior. One example is\n\t\t\t// this: https://github.com/esbuild-kit/tsx/pull/158. So we replicate this\n\t\t\t// bug in esbuild as well.\n\t\t\tif extendsFile == \".\" || extendsFile == \"..\" {\n\t\t\t\textendsFile += \"/tsconfig.json\"\n\t\t\t}\n\n\t\t\t// If this is a regular path, search relative to the enclosing directory\n\t\t\tif !r.fs.IsAbs(extendsFile) {\n\t\t\t\textendsFile = r.fs.Join(fileDir, extendsFile)\n\t\t\t}\n\t\t\tbase, err := r.parseTSConfig(extendsFile, visited, configDir)\n\n\t\t\t// TypeScript's handling of \"extends\" has some specific edge cases. We\n\t\t\t// must only try adding \".json\" if it's not already present, which is\n\t\t\t// unlike how node path resolution works. We also need to explicitly\n\t\t\t// ignore matches if they are directories instead of files. Some users\n\t\t\t// name directories the same name as their config files.\n\t\t\tif err != nil && !strings.HasSuffix(extendsFile, \".json\") {\n\t\t\t\tif entries, _, dirErr := r.fs.ReadDirectory(r.fs.Dir(extendsFile)); dirErr == nil {\n\t\t\t\t\textendsBase := r.fs.Base(extendsFile)\n\t\t\t\t\tif entry, _ := entries.Get(extendsBase); entry == nil || entry.Kind(r.fs) != fs.FileEntry {\n\t\t\t\t\t\tif entry, _ := entries.Get(extendsBase + \".json\"); entry != nil && entry.Kind(r.fs) == fs.FileEntry {\n\t\t\t\t\t\t\tbase, err = r.parseTSConfig(extendsFile+\".json\", visited, configDir)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif result, shouldReturn := maybeFinishOurSearch(base, err, extendsFile); shouldReturn {\n\t\t\t\treturn result\n\t\t\t}\n\t\t}\n\n\t\t// Suppress warnings about missing base config files inside \"node_modules\"\n\tpnpError:\n\t\tif !helpers.IsInsideNodeModules(source.KeyPath.Text) {\n\t\t\tvar notes []logger.MsgData\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tnotes = r.debugLogs.notes\n\t\t\t}\n\t\t\tr.log.AddIDWithNotes(logger.MsgID_TSConfigJSON_Missing, logger.Warning, &tracker, extendsRange,\n\t\t\t\tfmt.Sprintf(\"Cannot find base config file %q\", extends), notes)\n\t\t}\n\n\t\treturn nil\n\t})\n\n\tif result == nil {\n\t\treturn nil, errParseErrorAlreadyLogged\n\t}\n\n\t// Now that we have parsed the entire \"tsconfig.json\" file, filter out any\n\t// paths that are invalid due to being a package-style path without a base\n\t// URL specified. This must be done here instead of when we're parsing the\n\t// original file because TypeScript allows one \"tsconfig.json\" file to\n\t// specify \"baseUrl\" and inherit a \"paths\" from another file via \"extends\".\n\tif !isExtends && result.Paths != nil && result.BaseURL == nil {\n\t\tvar tracker *logger.LineColumnTracker\n\t\tfor key, paths := range result.Paths.Map {\n\t\t\tend := 0\n\t\t\tfor _, path := range paths {\n\t\t\t\tif isValidTSConfigPathNoBaseURLPattern(path.Text, r.log, &result.Paths.Source, &tracker, path.Loc) {\n\t\t\t\t\tpaths[end] = path\n\t\t\t\t\tend++\n\t\t\t\t}\n\t\t\t}\n\t\t\tif end < len(paths) {\n\t\t\t\tresult.Paths.Map[key] = paths[:end]\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result, nil\n}\n\nfunc (r resolverQuery) dirInfoUncached(path string) *dirInfo {\n\t// Get the info for the parent directory\n\tvar parentInfo *dirInfo\n\tparentDir := r.fs.Dir(path)\n\tif parentDir != path {\n\t\tparentInfo = r.dirInfoCached(parentDir)\n\n\t\t// Stop now if the parent directory doesn't exist\n\t\tif parentInfo == nil {\n\t\t\treturn nil\n\t\t}\n\t}\n\n\t// List the directories\n\tentries, err, originalError := r.fs.ReadDirectory(path)\n\tif err == syscall.EACCES || err == syscall.EPERM {\n\t\t// Just pretend this directory is empty if we can't access it. This is the\n\t\t// case on Unix for directories that only have the execute permission bit\n\t\t// set. It means we will just pass through the empty directory and\n\t\t// continue to check the directories above it, which is now node behaves.\n\t\tentries = fs.MakeEmptyDirEntries(path)\n\t\terr = nil\n\t}\n\tif r.debugLogs != nil && originalError != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Failed to read directory %q: %s\", path, originalError.Error()))\n\t}\n\tif err != nil {\n\t\t// Ignore \"ENOTDIR\" here so that calling \"ReadDirectory\" on a file behaves\n\t\t// as if there is nothing there at all instead of causing an error due to\n\t\t// the directory actually being a file. This is a workaround for situations\n\t\t// where people try to import from a path containing a file as a parent\n\t\t// directory. The \"pnpm\" package manager generates a faulty \"NODE_PATH\"\n\t\t// list which contains such paths and treating them as missing means we just\n\t\t// ignore them during path resolution.\n\t\tif err != syscall.ENOENT && err != syscall.ENOTDIR {\n\t\t\tprettyPaths := MakePrettyPaths(r.fs, logger.Path{Text: path, Namespace: \"file\"})\n\t\t\tr.log.AddError(nil, logger.Range{}, fmt.Sprintf(\"Cannot read directory %q: %s\",\n\t\t\t\tprettyPaths.Select(r.options.LogPathStyle), err.Error()))\n\t\t}\n\t\treturn nil\n\t}\n\tinfo := &dirInfo{\n\t\tabsPath: path,\n\t\tparent:  parentInfo,\n\t\tentries: entries,\n\t}\n\n\t// A \"node_modules\" directory isn't allowed to directly contain another \"node_modules\" directory\n\tbase := r.fs.Base(path)\n\tif base == \"node_modules\" {\n\t\tinfo.isNodeModules = true\n\t\tinfo.isInsideNodeModules = true\n\t} else if entry, _ := entries.Get(\"node_modules\"); entry != nil {\n\t\tinfo.hasNodeModules = entry.Kind(r.fs) == fs.DirEntry\n\t}\n\n\t// Propagate the browser scope into child directories\n\tif parentInfo != nil {\n\t\tinfo.enclosingPackageJSON = parentInfo.enclosingPackageJSON\n\t\tinfo.enclosingBrowserScope = parentInfo.enclosingBrowserScope\n\t\tinfo.enclosingTSConfigJSON = parentInfo.enclosingTSConfigJSON\n\t\tif parentInfo.isInsideNodeModules {\n\t\t\tinfo.isInsideNodeModules = true\n\t\t}\n\n\t\t// Make sure \"absRealPath\" is the real path of the directory (resolving any symlinks)\n\t\tif !r.options.PreserveSymlinks {\n\t\t\tif entry, _ := parentInfo.entries.Get(base); entry != nil {\n\t\t\t\tif symlink := entry.Symlink(r.fs); symlink != \"\" {\n\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Resolved symlink %q to %q\", path, symlink))\n\t\t\t\t\t}\n\t\t\t\t\tinfo.absRealPath = symlink\n\t\t\t\t} else if parentInfo.absRealPath != \"\" {\n\t\t\t\t\tsymlink := r.fs.Join(parentInfo.absRealPath, base)\n\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Resolved symlink %q to %q\", path, symlink))\n\t\t\t\t\t}\n\t\t\t\t\tinfo.absRealPath = symlink\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Record if this directory has a package.json file\n\tif entry, _ := entries.Get(\"package.json\"); entry != nil && entry.Kind(r.fs) == fs.FileEntry {\n\t\tinfo.packageJSON = r.parsePackageJSON(path)\n\n\t\t// Propagate this \"package.json\" file into child directories\n\t\tif info.packageJSON != nil {\n\t\t\tinfo.enclosingPackageJSON = info.packageJSON\n\t\t\tif info.packageJSON.browserMap != nil {\n\t\t\t\tinfo.enclosingBrowserScope = info\n\t\t\t}\n\t\t}\n\t}\n\n\t// Record if this directory has a tsconfig.json or jsconfig.json file\n\tif r.tsConfigOverride == nil {\n\t\tvar tsConfigPath string\n\t\tif entry, _ := entries.Get(\"tsconfig.json\"); entry != nil && entry.Kind(r.fs) == fs.FileEntry {\n\t\t\ttsConfigPath = r.fs.Join(path, \"tsconfig.json\")\n\t\t} else if entry, _ := entries.Get(\"jsconfig.json\"); entry != nil && entry.Kind(r.fs) == fs.FileEntry {\n\t\t\ttsConfigPath = r.fs.Join(path, \"jsconfig.json\")\n\t\t}\n\n\t\t// Except don't do this if we're inside a \"node_modules\" directory. Package\n\t\t// authors often publish their \"tsconfig.json\" files to npm because of\n\t\t// npm's default-include publishing model and because these authors\n\t\t// probably don't know about \".npmignore\" files.\n\t\t//\n\t\t// People trying to use these packages with esbuild have historically\n\t\t// complained that esbuild is respecting \"tsconfig.json\" in these cases.\n\t\t// The assumption is that the package author published these files by\n\t\t// accident.\n\t\t//\n\t\t// Ignoring \"tsconfig.json\" files inside \"node_modules\" directories breaks\n\t\t// the use case of publishing TypeScript code and having it be transpiled\n\t\t// for you, but that's the uncommon case and likely doesn't work with\n\t\t// many other tools anyway. So now these files are ignored.\n\t\tif tsConfigPath != \"\" && !info.isInsideNodeModules {\n\t\t\tvar err error\n\t\t\tinfo.enclosingTSConfigJSON, err = r.parseTSConfig(tsConfigPath, make(map[string]bool), r.fs.Dir(tsConfigPath))\n\t\t\tif err != nil {\n\t\t\t\tif err == syscall.ENOENT {\n\t\t\t\t\tprettyPaths := MakePrettyPaths(r.fs, logger.Path{Text: tsConfigPath, Namespace: \"file\"})\n\t\t\t\t\tr.log.AddError(nil, logger.Range{}, fmt.Sprintf(\"Cannot find tsconfig file %q\",\n\t\t\t\t\t\tprettyPaths.Select(r.options.LogPathStyle)))\n\t\t\t\t} else if err != errParseErrorAlreadyLogged {\n\t\t\t\t\tprettyPaths := MakePrettyPaths(r.fs, logger.Path{Text: tsConfigPath, Namespace: \"file\"})\n\t\t\t\t\tr.log.AddID(logger.MsgID_TSConfigJSON_Missing, logger.Debug, nil, logger.Range{},\n\t\t\t\t\t\tfmt.Sprintf(\"Cannot read file %q: %s\", prettyPaths.Select(r.options.LogPathStyle), err.Error()))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Record if this directory has a Yarn PnP manifest. This must not be done\n\t// for Yarn virtual paths because that will result in duplicate copies of\n\t// the same manifest which will result in multiple copies of the same virtual\n\t// directory in the same path, which we don't handle (and which also doesn't\n\t// match Yarn's behavior).\n\t//\n\t// For example, imagine a project with a manifest here:\n\t//\n\t//   /project/.pnp.cjs\n\t//\n\t// and a source file with an import of \"bar\" here:\n\t//\n\t//   /project/.yarn/__virtual__/pkg/1/foo.js\n\t//\n\t// If we didn't ignore Yarn PnP manifests in virtual folders, then we would\n\t// pick up on the one here:\n\t//\n\t//   /project/.yarn/__virtual__/pkg/1/.pnp.cjs\n\t//\n\t// which means we would potentially resolve the import to something like this:\n\t//\n\t//   /project/.yarn/__virtual__/pkg/1/.yarn/__virtual__/pkg/1/bar\n\t//\n\tif r.pnpManifest == nil {\n\t\tif _, _, ok := fs.ParseYarnPnPVirtualPath(path); !ok {\n\t\t\tif pnp, _ := entries.Get(\".pnp.data.json\"); pnp != nil && pnp.Kind(r.fs) == fs.FileEntry {\n\t\t\t\tinfo.pnpManifestAbsPath = r.fs.Join(path, \".pnp.data.json\")\n\t\t\t} else if pnp, _ := entries.Get(\".pnp.cjs\"); pnp != nil && pnp.Kind(r.fs) == fs.FileEntry {\n\t\t\t\tinfo.pnpManifestAbsPath = r.fs.Join(path, \".pnp.cjs\")\n\t\t\t} else if pnp, _ := entries.Get(\".pnp.js\"); pnp != nil && pnp.Kind(r.fs) == fs.FileEntry {\n\t\t\t\tinfo.pnpManifestAbsPath = r.fs.Join(path, \".pnp.js\")\n\t\t\t}\n\t\t}\n\t}\n\n\treturn info\n}\n\n// TypeScript-specific behavior: if the extension is \".js\" or \".jsx\", try\n// replacing it with \".ts\" or \".tsx\". At the time of writing this specific\n// behavior comes from the function \"loadModuleFromFile()\" in the file\n// \"moduleNameResolver.ts\" in the TypeScript compiler source code. It\n// contains this comment:\n//\n//\tIf that didn't work, try stripping a \".js\" or \".jsx\" extension and\n//\treplacing it with a TypeScript one; e.g. \"./foo.js\" can be matched\n//\tby \"./foo.ts\" or \"./foo.d.ts\"\n//\n// We don't care about \".d.ts\" files because we can't do anything with\n// those, so we ignore that part of the behavior.\n//\n// See the discussion here for more historical context:\n// https://github.com/microsoft/TypeScript/issues/4595\nvar rewrittenFileExtensions = map[string][]string{\n\t// Note that the official compiler code always tries \".ts\" before\n\t// \".tsx\" even if the original extension was \".jsx\".\n\t\".js\":  {\".ts\", \".tsx\"},\n\t\".jsx\": {\".ts\", \".tsx\"},\n\t\".mjs\": {\".mts\"},\n\t\".cjs\": {\".cts\"},\n}\n\nfunc (r resolverQuery) loadAsFile(path string, extensionOrder []string) (string, bool, *fs.DifferentCase) {\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Attempting to load %q as a file\", path))\n\t\tr.debugLogs.increaseIndent()\n\t\tdefer r.debugLogs.decreaseIndent()\n\t}\n\n\t// Read the directory entries once to minimize locking\n\tdirPath := r.fs.Dir(path)\n\tentries, err, originalError := r.fs.ReadDirectory(dirPath)\n\tif r.debugLogs != nil && originalError != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Failed to read directory %q: %s\", dirPath, originalError.Error()))\n\t}\n\tif err != nil {\n\t\tif err != syscall.ENOENT {\n\t\t\tprettyPaths := MakePrettyPaths(r.fs, logger.Path{Text: dirPath, Namespace: \"file\"})\n\t\t\tr.log.AddError(nil, logger.Range{}, fmt.Sprintf(\"Cannot read directory %q: %s\",\n\t\t\t\tprettyPaths.Select(r.options.LogPathStyle), err.Error()))\n\t\t}\n\t\treturn \"\", false, nil\n\t}\n\n\ttryFile := func(base string) (string, bool, *fs.DifferentCase) {\n\t\tbaseWithSuffix := base\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Checking for file %q\", baseWithSuffix))\n\t\t}\n\t\tif entry, diffCase := entries.Get(baseWithSuffix); entry != nil && entry.Kind(r.fs) == fs.FileEntry {\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Found file %q\", baseWithSuffix))\n\t\t\t}\n\t\t\treturn r.fs.Join(dirPath, baseWithSuffix), true, diffCase\n\t\t}\n\t\treturn \"\", false, nil\n\t}\n\n\tbase := r.fs.Base(path)\n\n\t// Given \"./x.js\", node's algorithm tries things in the following order:\n\t//\n\t//   ./x.js\n\t//   ./x.js.js\n\t//   ./x.js.json\n\t//   ./x.js.node\n\t//   ./x.js/index.js\n\t//   ./x.js/index.json\n\t//   ./x.js/index.node\n\t//\n\t// Given \"./x.js\", TypeScript's algorithm tries things in the following order:\n\t//\n\t//   ./x.js.ts\n\t//   ./x.js.tsx\n\t//   ./x.js.d.ts\n\t//   ./x.ts\n\t//   ./x.tsx\n\t//   ./x.d.ts\n\t//   ./x.js/index.ts\n\t//   ./x.js/index.tsx\n\t//   ./x.js/index.d.ts\n\t//   ./x.js.js\n\t//   ./x.js.jsx\n\t//   ./x.js\n\t//   ./x.jsx\n\t//   ./x.js/index.js\n\t//   ./x.js/index.jsx\n\t//\n\t// Our order below is a blend of both. We try to follow node's algorithm but\n\t// with the features of TypeScript's algorithm (omitting \".d.ts\" files, which\n\t// don't contain code). This means we should end up checking the same files\n\t// as TypeScript, but in a different order.\n\t//\n\t// One reason we use a different order is because we support a customizable\n\t// extension resolution order, which doesn't fit well into TypeScript's\n\t// algorithm. For example, you can configure esbuild to check for extensions\n\t// in the order \".js,.ts,.jsx,.tsx\" but TypeScript always checks TypeScript\n\t// extensions before JavaScript extensions, so we can't obey the user's\n\t// intent if we follow TypeScript's algorithm exactly.\n\t//\n\t// Another reason we deviate from TypeScript's order is because our code is\n\t// structured to handle node's algorithm and TypeScript's algorithm has a\n\t// different structure. It intermixes multiple calls to LOAD_AS_FILE and\n\t// LOAD_INDEX together while node always does one LOAD_AS_FILE before one\n\t// LOAD_INDEX.\n\n\t// Try the plain path without any extensions\n\tif absolute, ok, diffCase := tryFile(base); ok {\n\t\treturn absolute, ok, diffCase\n\t}\n\n\t// Try the path with extensions\n\tfor _, ext := range extensionOrder {\n\t\tif absolute, ok, diffCase := tryFile(base + ext); ok {\n\t\t\treturn absolute, ok, diffCase\n\t\t}\n\t}\n\n\t// TypeScript-specific behavior: try rewriting \".js\" to \".ts\"\n\tfor old, exts := range rewrittenFileExtensions {\n\t\tif !strings.HasSuffix(base, old) {\n\t\t\tcontinue\n\t\t}\n\t\tlastDot := strings.LastIndexByte(base, '.')\n\t\tfor _, ext := range exts {\n\t\t\tif absolute, ok, diffCase := tryFile(base[:lastDot] + ext); ok {\n\t\t\t\treturn absolute, ok, diffCase\n\t\t\t}\n\t\t}\n\t\tbreak\n\t}\n\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Failed to find file %q\", base))\n\t}\n\treturn \"\", false, nil\n}\n\nfunc (r resolverQuery) loadAsIndex(dirInfo *dirInfo, extensionOrder []string) (PathPair, bool, *fs.DifferentCase) {\n\t// Try the \"index\" file with extensions\n\tfor _, ext := range extensionOrder {\n\t\tbase := \"index\" + ext\n\t\tif entry, diffCase := dirInfo.entries.Get(base); entry != nil && entry.Kind(r.fs) == fs.FileEntry {\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Found file %q\", r.fs.Join(dirInfo.absPath, base)))\n\t\t\t}\n\t\t\treturn PathPair{Primary: logger.Path{Text: r.fs.Join(dirInfo.absPath, base), Namespace: \"file\"}}, true, diffCase\n\t\t}\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Failed to find file %q\", r.fs.Join(dirInfo.absPath, base)))\n\t\t}\n\t}\n\n\treturn PathPair{}, false, nil\n}\n\nfunc (r resolverQuery) loadAsIndexWithBrowserRemapping(dirInfo *dirInfo, path string, extensionOrder []string) (PathPair, bool, *fs.DifferentCase) {\n\t// Potentially remap using the \"browser\" field\n\tabsPath := r.fs.Join(path, \"index\")\n\tif remapped, ok := r.checkBrowserMap(dirInfo, absPath, absolutePathKind); ok {\n\t\tif remapped == nil {\n\t\t\treturn PathPair{Primary: logger.Path{Text: absPath, Namespace: \"file\", Flags: logger.PathDisabled}}, true, nil\n\t\t}\n\t\tremappedAbs := r.fs.Join(path, *remapped)\n\n\t\t// Is this a file?\n\t\tabsolute, ok, diffCase := r.loadAsFile(remappedAbs, extensionOrder)\n\t\tif ok {\n\t\t\treturn PathPair{Primary: logger.Path{Text: absolute, Namespace: \"file\"}}, true, diffCase\n\t\t}\n\n\t\t// Is it a directory with an index?\n\t\tif fieldDirInfo := r.dirInfoCached(remappedAbs); fieldDirInfo != nil {\n\t\t\tif absolute, ok, _ := r.loadAsIndex(fieldDirInfo, extensionOrder); ok {\n\t\t\t\treturn absolute, true, nil\n\t\t\t}\n\t\t}\n\n\t\treturn PathPair{}, false, nil\n\t}\n\n\treturn r.loadAsIndex(dirInfo, extensionOrder)\n}\n\nfunc getProperty(json js_ast.Expr, name string) (js_ast.Expr, logger.Loc, bool) {\n\tif obj, ok := json.Data.(*js_ast.EObject); ok {\n\t\tfor _, prop := range obj.Properties {\n\t\t\tif key, ok := prop.Key.Data.(*js_ast.EString); ok && key.Value != nil && helpers.UTF16EqualsString(key.Value, name) {\n\t\t\t\treturn prop.ValueOrNil, prop.Key.Loc, true\n\t\t\t}\n\t\t}\n\t}\n\treturn js_ast.Expr{}, logger.Loc{}, false\n}\n\nfunc getString(json js_ast.Expr) (string, bool) {\n\tif value, ok := json.Data.(*js_ast.EString); ok {\n\t\treturn helpers.UTF16ToString(value.Value), true\n\t}\n\treturn \"\", false\n}\n\nfunc getBool(json js_ast.Expr) (bool, bool) {\n\tif value, ok := json.Data.(*js_ast.EBoolean); ok {\n\t\treturn value.Value, true\n\t}\n\treturn false, false\n}\n\nfunc (r resolverQuery) loadAsFileOrDirectory(path string) (PathPair, bool, *fs.DifferentCase) {\n\textensionOrder := r.options.ExtensionOrder\n\tif r.kind.MustResolveToCSS() {\n\t\t// Use a special import order for CSS \"@import\" imports\n\t\textensionOrder = r.cssExtensionOrder\n\t} else if helpers.IsInsideNodeModules(path) {\n\t\t// Use a special import order for imports inside \"node_modules\"\n\t\textensionOrder = r.nodeModulesExtensionOrder\n\t}\n\n\t// Is this a file?\n\tabsolute, ok, diffCase := r.loadAsFile(path, extensionOrder)\n\tif ok {\n\t\treturn PathPair{Primary: logger.Path{Text: absolute, Namespace: \"file\"}}, true, diffCase\n\t}\n\n\treturn r.loadAsDirectory(path)\n}\n\nfunc (r resolverQuery) loadAsDirectory(path string) (PathPair, bool, *fs.DifferentCase) {\n\textensionOrder := r.options.ExtensionOrder\n\tif r.kind.MustResolveToCSS() {\n\t\t// Use a special import order for CSS \"@import\" imports\n\t\textensionOrder = r.cssExtensionOrder\n\t} else if helpers.IsInsideNodeModules(path) {\n\t\t// Use a special import order for imports inside \"node_modules\"\n\t\textensionOrder = r.nodeModulesExtensionOrder\n\t}\n\n\t// Is this a directory?\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Attempting to load %q as a directory\", path))\n\t\tr.debugLogs.increaseIndent()\n\t\tdefer r.debugLogs.decreaseIndent()\n\t}\n\tdirInfo := r.dirInfoCached(path)\n\tif dirInfo == nil {\n\t\treturn PathPair{}, false, nil\n\t}\n\n\t// Try using the main field(s) from \"package.json\"\n\tif absolute, ok, diffCase := r.loadAsMainField(dirInfo, path, extensionOrder); ok {\n\t\treturn absolute, true, diffCase\n\t}\n\n\t// Look for an \"index\" file with known extensions\n\tif absolute, ok, diffCase := r.loadAsIndexWithBrowserRemapping(dirInfo, path, extensionOrder); ok {\n\t\treturn absolute, true, diffCase\n\t}\n\n\treturn PathPair{}, false, nil\n}\n\nfunc (r resolverQuery) loadAsMainField(dirInfo *dirInfo, path string, extensionOrder []string) (PathPair, bool, *fs.DifferentCase) {\n\tif dirInfo.packageJSON == nil {\n\t\treturn PathPair{}, false, nil\n\t}\n\n\tmainFieldValues := dirInfo.packageJSON.mainFields\n\tmainFieldKeys := r.options.MainFields\n\tautoMain := false\n\n\t// If the user has not explicitly specified a \"main\" field order,\n\t// use a default one determined by the current platform target\n\tif mainFieldKeys == nil {\n\t\tmainFieldKeys = defaultMainFields[r.options.Platform]\n\t\tautoMain = true\n\t}\n\n\tloadMainField := func(fieldRelPath string, field string) (PathPair, bool, *fs.DifferentCase) {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Found main field %q with path %q\", field, fieldRelPath))\n\t\t\tr.debugLogs.increaseIndent()\n\t\t\tdefer r.debugLogs.decreaseIndent()\n\t\t}\n\n\t\t// Potentially remap using the \"browser\" field\n\t\tfieldAbsPath := r.fs.Join(path, fieldRelPath)\n\t\tif remapped, ok := r.checkBrowserMap(dirInfo, fieldAbsPath, absolutePathKind); ok {\n\t\t\tif remapped == nil {\n\t\t\t\treturn PathPair{Primary: logger.Path{Text: fieldAbsPath, Namespace: \"file\", Flags: logger.PathDisabled}}, true, nil\n\t\t\t}\n\t\t\tfieldAbsPath = r.fs.Join(path, *remapped)\n\t\t}\n\n\t\t// Is this a file?\n\t\tabsolute, ok, diffCase := r.loadAsFile(fieldAbsPath, extensionOrder)\n\t\tif ok {\n\t\t\treturn PathPair{Primary: logger.Path{Text: absolute, Namespace: \"file\"}}, true, diffCase\n\t\t}\n\n\t\t// Is it a directory with an index?\n\t\tif fieldDirInfo := r.dirInfoCached(fieldAbsPath); fieldDirInfo != nil {\n\t\t\tif absolute, ok, _ := r.loadAsIndexWithBrowserRemapping(fieldDirInfo, fieldAbsPath, extensionOrder); ok {\n\t\t\t\treturn absolute, true, nil\n\t\t\t}\n\t\t}\n\n\t\treturn PathPair{}, false, nil\n\t}\n\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Searching for main fields in %q\", dirInfo.packageJSON.source.KeyPath.Text))\n\t\tr.debugLogs.increaseIndent()\n\t\tdefer r.debugLogs.decreaseIndent()\n\t}\n\n\tfoundSomething := false\n\n\tfor _, key := range mainFieldKeys {\n\t\tvalue, ok := mainFieldValues[key]\n\t\tif !ok {\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Did not find main field %q\", key))\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tfoundSomething = true\n\n\t\tabsolute, ok, diffCase := loadMainField(value.relPath, key)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\t// If the user did not manually configure a \"main\" field order, then\n\t\t// use a special per-module automatic algorithm to decide whether to\n\t\t// use \"module\" or \"main\" based on whether the package is imported\n\t\t// using \"import\" or \"require\".\n\t\tif autoMain && key == \"module\" {\n\t\t\tvar absoluteMain PathPair\n\t\t\tvar okMain bool\n\t\t\tvar diffCaseMain *fs.DifferentCase\n\n\t\t\tif main, ok := mainFieldValues[\"main\"]; ok {\n\t\t\t\tif absolute, ok, diffCase := loadMainField(main.relPath, \"main\"); ok {\n\t\t\t\t\tabsoluteMain = absolute\n\t\t\t\t\tokMain = true\n\t\t\t\t\tdiffCaseMain = diffCase\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Some packages have a \"module\" field without a \"main\" field but\n\t\t\t\t// still have an implicit \"index.js\" file. In that case, treat that\n\t\t\t\t// as the value for \"main\".\n\t\t\t\tif absolute, ok, diffCase := r.loadAsIndexWithBrowserRemapping(dirInfo, path, extensionOrder); ok {\n\t\t\t\t\tabsoluteMain = absolute\n\t\t\t\t\tokMain = true\n\t\t\t\t\tdiffCaseMain = diffCase\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif okMain {\n\t\t\t\t// If both the \"main\" and \"module\" fields exist, use \"main\" if the\n\t\t\t\t// path is for \"require\" and \"module\" if the path is for \"import\".\n\t\t\t\t// If we're using \"module\", return enough information to be able to\n\t\t\t\t// fall back to \"main\" later if something ended up using \"require()\"\n\t\t\t\t// with this same path. The goal of this code is to avoid having\n\t\t\t\t// both the \"module\" file and the \"main\" file in the bundle at the\n\t\t\t\t// same time.\n\t\t\t\tif r.kind != ast.ImportRequire {\n\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Resolved to %q using the \\\"module\\\" field in %q\",\n\t\t\t\t\t\t\tabsolute.Primary.Text, dirInfo.packageJSON.source.KeyPath.Text))\n\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The fallback path in case of \\\"require\\\" is %q\",\n\t\t\t\t\t\t\tabsoluteMain.Primary.Text))\n\t\t\t\t\t}\n\t\t\t\t\treturn PathPair{\n\t\t\t\t\t\t// This is the whole point of the path pair\n\t\t\t\t\t\tPrimary:   absolute.Primary,\n\t\t\t\t\t\tSecondary: absoluteMain.Primary,\n\t\t\t\t\t}, true, diffCase\n\t\t\t\t} else {\n\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Resolved to %q because of \\\"require\\\"\", absoluteMain.Primary.Text))\n\t\t\t\t\t}\n\t\t\t\t\treturn absoluteMain, true, diffCaseMain\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Resolved to %q using the %q field in %q\",\n\t\t\t\tabsolute.Primary.Text, key, dirInfo.packageJSON.source.KeyPath.Text))\n\t\t}\n\t\treturn absolute, true, diffCase\n\t}\n\n\t// Let the user know if \"main\" exists but was skipped due to mis-configuration\n\tif !foundSomething {\n\t\tfor _, field := range mainFieldsForFailure {\n\t\t\tif main, ok := mainFieldValues[field]; ok {\n\t\t\t\ttracker := logger.MakeLineColumnTracker(&dirInfo.packageJSON.source)\n\t\t\t\tkeyRange := dirInfo.packageJSON.source.RangeOfString(main.keyLoc)\n\t\t\t\tif len(mainFieldKeys) == 0 && r.options.Platform == config.PlatformNeutral {\n\t\t\t\t\tr.debugMeta.notes = append(r.debugMeta.notes, tracker.MsgData(keyRange,\n\t\t\t\t\t\tfmt.Sprintf(\"The %q field here was ignored. Main fields must be configured explicitly when using the \\\"neutral\\\" platform.\",\n\t\t\t\t\t\t\tfield)))\n\t\t\t\t} else {\n\t\t\t\t\tr.debugMeta.notes = append(r.debugMeta.notes, tracker.MsgData(keyRange,\n\t\t\t\t\t\tfmt.Sprintf(\"The %q field here was ignored because the list of main fields to use is currently set to [%s].\",\n\t\t\t\t\t\t\tfield, helpers.StringArrayToQuotedCommaSeparatedString(mainFieldKeys))))\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\treturn PathPair{}, false, nil\n}\n\nfunc hasCaseInsensitiveSuffix(s string, suffix string) bool {\n\treturn len(s) >= len(suffix) && strings.EqualFold(s[len(s)-len(suffix):], suffix)\n}\n\n// This closely follows the behavior of \"tryLoadModuleUsingPaths()\" in the\n// official TypeScript compiler\nfunc (r resolverQuery) matchTSConfigPaths(tsConfigJSON *TSConfigJSON, path string) (PathPair, bool, *fs.DifferentCase) {\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Matching %q against \\\"paths\\\" in %q\", path, tsConfigJSON.AbsPath))\n\t\tr.debugLogs.increaseIndent()\n\t\tdefer r.debugLogs.decreaseIndent()\n\t}\n\n\tabsBaseURL := tsConfigJSON.BaseURLForPaths\n\n\t// The explicit base URL should take precedence over the implicit base URL\n\t// if present. This matters when a tsconfig.json file overrides \"baseUrl\"\n\t// from another extended tsconfig.json file but doesn't override \"paths\".\n\tif tsConfigJSON.BaseURL != nil {\n\t\tabsBaseURL = *tsConfigJSON.BaseURL\n\t}\n\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Using %q as \\\"baseUrl\\\"\", absBaseURL))\n\t}\n\n\t// Check for exact matches first\n\tfor key, originalPaths := range tsConfigJSON.Paths.Map {\n\t\tif key == path {\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Found an exact match for %q in \\\"paths\\\"\", key))\n\t\t\t}\n\t\t\tfor _, originalPath := range originalPaths {\n\t\t\t\t// Ignore \".d.ts\" files because this rule is obviously only here for type checking\n\t\t\t\tif hasCaseInsensitiveSuffix(originalPath.Text, \".d.ts\") {\n\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Ignoring substitution %q because it ends in \\\".d.ts\\\"\", originalPath.Text))\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Load the original path relative to the \"baseUrl\" from tsconfig.json\n\t\t\t\tabsoluteOriginalPath := originalPath.Text\n\t\t\t\tif !r.fs.IsAbs(absoluteOriginalPath) {\n\t\t\t\t\tabsoluteOriginalPath = r.fs.Join(absBaseURL, absoluteOriginalPath)\n\t\t\t\t}\n\t\t\t\tif absolute, ok, diffCase := r.loadAsFileOrDirectory(absoluteOriginalPath); ok {\n\t\t\t\t\treturn absolute, true, diffCase\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn PathPair{}, false, nil\n\t\t}\n\t}\n\n\ttype match struct {\n\t\tprefix        string\n\t\tsuffix        string\n\t\toriginalPaths []TSConfigPath\n\t}\n\n\t// Check for pattern matches next\n\tlongestMatchPrefixLength := -1\n\tlongestMatchSuffixLength := -1\n\tvar longestMatch match\n\tfor key, originalPaths := range tsConfigJSON.Paths.Map {\n\t\tif starIndex := strings.IndexByte(key, '*'); starIndex != -1 {\n\t\t\tprefix, suffix := key[:starIndex], key[starIndex+1:]\n\n\t\t\t// Find the match with the longest prefix. If two matches have the same\n\t\t\t// prefix length, pick the one with the longest suffix. This second edge\n\t\t\t// case isn't handled by the TypeScript compiler, but we handle it\n\t\t\t// because we want the output to always be deterministic and Go map\n\t\t\t// iteration order is deliberately non-deterministic.\n\t\t\tif strings.HasPrefix(path, prefix) && strings.HasSuffix(path, suffix) && (len(prefix) > longestMatchPrefixLength ||\n\t\t\t\t(len(prefix) == longestMatchPrefixLength && len(suffix) > longestMatchSuffixLength)) {\n\t\t\t\tlongestMatchPrefixLength = len(prefix)\n\t\t\t\tlongestMatchSuffixLength = len(suffix)\n\t\t\t\tlongestMatch = match{\n\t\t\t\t\tprefix:        prefix,\n\t\t\t\t\tsuffix:        suffix,\n\t\t\t\t\toriginalPaths: originalPaths,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// If there is at least one match, only consider the one with the longest\n\t// prefix. This matches the behavior of the TypeScript compiler.\n\tif longestMatchPrefixLength != -1 {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Found a fuzzy match for %q in \\\"paths\\\"\", longestMatch.prefix+\"*\"+longestMatch.suffix))\n\t\t}\n\n\t\tfor _, originalPath := range longestMatch.originalPaths {\n\t\t\t// Swap out the \"*\" in the original path for whatever the \"*\" matched\n\t\t\tmatchedText := path[len(longestMatch.prefix) : len(path)-len(longestMatch.suffix)]\n\t\t\toriginalPath := strings.Replace(originalPath.Text, \"*\", matchedText, 1)\n\n\t\t\t// Ignore \".d.ts\" files because this rule is obviously only here for type checking\n\t\t\tif hasCaseInsensitiveSuffix(originalPath, \".d.ts\") {\n\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Ignoring substitution %q because it ends in \\\".d.ts\\\"\", originalPath))\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Load the original path relative to the \"baseUrl\" from tsconfig.json\n\t\t\tabsoluteOriginalPath := originalPath\n\t\t\tif !r.fs.IsAbs(originalPath) {\n\t\t\t\tabsoluteOriginalPath = r.fs.Join(absBaseURL, originalPath)\n\t\t\t}\n\t\t\tif absolute, ok, diffCase := r.loadAsFileOrDirectory(absoluteOriginalPath); ok {\n\t\t\t\treturn absolute, true, diffCase\n\t\t\t}\n\t\t}\n\t}\n\n\treturn PathPair{}, false, nil\n}\n\nfunc (r resolverQuery) loadPackageImports(importPath string, dirInfoPackageJSON *dirInfo) (PathPair, bool, *fs.DifferentCase, *SideEffectsData) {\n\tpackageJSON := dirInfoPackageJSON.packageJSON\n\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Looking for %q in \\\"imports\\\" map in %q\", importPath, packageJSON.source.KeyPath.Text))\n\t\tr.debugLogs.increaseIndent()\n\t\tdefer r.debugLogs.decreaseIndent()\n\t}\n\n\t// Filter out invalid module specifiers now where we have more information for\n\t// a better error message instead of later when we're inside the algorithm.\n\tif importPath == \"#\" {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The path %q must not equal \\\"#\\\".\", importPath))\n\t\t}\n\t\ttracker := logger.MakeLineColumnTracker(&packageJSON.source)\n\t\tr.debugMeta.notes = append(r.debugMeta.notes, tracker.MsgData(packageJSON.importsMap.root.firstToken,\n\t\t\tfmt.Sprintf(\"This \\\"imports\\\" map was ignored because the module specifier %q is invalid:\", importPath)))\n\t\treturn PathPair{}, false, nil, nil\n\t}\n\n\t// The condition set is determined by the kind of import\n\tconditions := r.esmConditionsDefault\n\tswitch r.kind {\n\tcase ast.ImportStmt, ast.ImportDynamic:\n\t\tconditions = r.esmConditionsImport\n\tcase ast.ImportRequire, ast.ImportRequireResolve:\n\t\tconditions = r.esmConditionsRequire\n\t}\n\n\tresolvedPath, status, debug := r.esmPackageImportsResolve(importPath, packageJSON.importsMap.root, conditions)\n\tresolvedPath, status, debug = r.esmHandlePostConditions(resolvedPath, status, debug)\n\n\tif status == pjStatusPackageResolve {\n\t\tif pathPair, ok, sideEffects := r.checkForBuiltInNodeModules(resolvedPath); ok {\n\t\t\treturn pathPair, true, nil, sideEffects\n\t\t}\n\n\t\t// The import path was remapped via \"imports\" to another import path\n\t\t// that now needs to be resolved too. Set \"forbidImports\" to true\n\t\t// so we don't try to resolve \"imports\" again and end up in a loop.\n\t\tabsolute, ok, diffCase, sideEffects := r.loadNodeModules(resolvedPath, dirInfoPackageJSON, true /* forbidImports */)\n\t\tif !ok {\n\t\t\ttracker := logger.MakeLineColumnTracker(&packageJSON.source)\n\t\t\tr.debugMeta.notes = append(\n\t\t\t\t[]logger.MsgData{tracker.MsgData(debug.token,\n\t\t\t\t\tfmt.Sprintf(\"The remapped path %q could not be resolved:\", resolvedPath))},\n\t\t\t\tr.debugMeta.notes...)\n\t\t}\n\t\treturn absolute, ok, diffCase, sideEffects\n\t}\n\n\tabsolute, ok, diffCase := r.finalizeImportsExportsResult(\n\t\tfinalizeImportsExportsNormal,\n\t\tdirInfoPackageJSON.absPath, conditions, *packageJSON.importsMap, packageJSON,\n\t\tresolvedPath, status, debug,\n\t\t\"\", \"\", \"\",\n\t)\n\treturn absolute, ok, diffCase, nil\n}\n\nfunc (r resolverQuery) esmResolveAlgorithm(\n\tkind finalizeImportsExportsKind,\n\tesmPackageName string,\n\tesmPackageSubpath string,\n\tpackageJSON *packageJSON,\n\tabsPkgPath string,\n\tabsPath string,\n) (PathPair, bool, *fs.DifferentCase) {\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Looking for %q in \\\"exports\\\" map in %q\", esmPackageSubpath, packageJSON.source.KeyPath.Text))\n\t\tr.debugLogs.increaseIndent()\n\t\tdefer r.debugLogs.decreaseIndent()\n\t}\n\n\t// The condition set is determined by the kind of import\n\tconditions := r.esmConditionsDefault\n\tswitch r.kind {\n\tcase ast.ImportStmt, ast.ImportDynamic:\n\t\tconditions = r.esmConditionsImport\n\tcase ast.ImportRequire, ast.ImportRequireResolve:\n\t\tconditions = r.esmConditionsRequire\n\tcase ast.ImportEntryPoint:\n\t\t// Treat entry points as imports instead of requires for consistency with\n\t\t// Webpack and Rollup. More information:\n\t\t//\n\t\t// * https://github.com/evanw/esbuild/issues/1956\n\t\t// * https://github.com/nodejs/node/issues/41686\n\t\t// * https://github.com/evanw/entry-point-resolve-test\n\t\t//\n\t\tconditions = r.esmConditionsImport\n\t}\n\n\t// Resolve against the path \"/\", then join it with the absolute\n\t// directory path. This is done because ESM package resolution uses\n\t// URLs while our path resolution uses file system paths. We don't\n\t// want problems due to Windows paths, which are very unlike URL\n\t// paths. We also want to avoid any \"%\" characters in the absolute\n\t// directory path accidentally being interpreted as URL escapes.\n\tresolvedPath, status, debug := r.esmPackageExportsResolve(\"/\", esmPackageSubpath, packageJSON.exportsMap.root, conditions)\n\tresolvedPath, status, debug = r.esmHandlePostConditions(resolvedPath, status, debug)\n\n\treturn r.finalizeImportsExportsResult(\n\t\tkind,\n\t\tabsPkgPath, conditions, *packageJSON.exportsMap, packageJSON,\n\t\tresolvedPath, status, debug,\n\t\tesmPackageName, esmPackageSubpath, absPath,\n\t)\n}\n\nfunc (r resolverQuery) loadNodeModules(importPath string, dirInfo *dirInfo, forbidImports bool) (PathPair, bool, *fs.DifferentCase, *SideEffectsData) {\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Searching for %q in \\\"node_modules\\\" directories starting from %q\", importPath, dirInfo.absPath))\n\t\tr.debugLogs.increaseIndent()\n\t\tdefer r.debugLogs.decreaseIndent()\n\t}\n\n\t// First, check path overrides from the nearest enclosing TypeScript \"tsconfig.json\" file\n\tif tsConfigJSON := r.tsConfigForDir(dirInfo); tsConfigJSON != nil {\n\t\t// Try path substitutions first\n\t\tif tsConfigJSON.Paths != nil {\n\t\t\tif absolute, ok, diffCase := r.matchTSConfigPaths(tsConfigJSON, importPath); ok {\n\t\t\t\treturn absolute, true, diffCase, nil\n\t\t\t}\n\t\t}\n\n\t\t// Try looking up the path relative to the base URL\n\t\tif tsConfigJSON.BaseURL != nil {\n\t\t\tbasePath := r.fs.Join(*tsConfigJSON.BaseURL, importPath)\n\t\t\tif absolute, ok, diffCase := r.loadAsFileOrDirectory(basePath); ok {\n\t\t\t\treturn absolute, true, diffCase, nil\n\t\t\t}\n\t\t}\n\t}\n\n\t// Find the parent directory with the \"package.json\" file\n\tdirInfoPackageJSON := dirInfo\n\tfor dirInfoPackageJSON != nil && dirInfoPackageJSON.packageJSON == nil {\n\t\tdirInfoPackageJSON = dirInfoPackageJSON.parent\n\t}\n\n\t// Check for subpath imports: https://nodejs.org/api/packages.html#subpath-imports\n\tif dirInfoPackageJSON != nil && strings.HasPrefix(importPath, \"#\") && !forbidImports && dirInfoPackageJSON.packageJSON.importsMap != nil {\n\t\treturn r.loadPackageImports(importPath, dirInfoPackageJSON)\n\t}\n\n\t// \"import 'pkg'\" when all packages are external (vs. \"import './pkg'\")\n\tif r.options.ExternalPackages && IsPackagePath(importPath) {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(\"Marking this path as external because it's a package path\")\n\t\t}\n\t\treturn PathPair{Primary: logger.Path{Text: importPath}, IsExternal: true}, true, nil, nil\n\t}\n\n\t// If Yarn PnP is active, use it to find the package\n\tif r.pnpManifest != nil {\n\t\tif result := r.resolveToUnqualified(importPath, dirInfo.absPath, r.pnpManifest); result.status.isError() {\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(\"The Yarn PnP path resolution algorithm returned an error\")\n\t\t\t}\n\n\t\t\t// Try to provide more information about this error if it's available\n\t\t\tswitch result.status {\n\t\t\tcase pnpErrorDependencyNotFound:\n\t\t\t\tr.debugMeta.notes = []logger.MsgData{r.pnpManifest.tracker.MsgData(result.errorRange,\n\t\t\t\t\tfmt.Sprintf(\"The Yarn Plug'n'Play manifest forbids importing %q here because it's not listed as a dependency of this package:\", result.errorIdent))}\n\n\t\t\tcase pnpErrorUnfulfilledPeerDependency:\n\t\t\t\tr.debugMeta.notes = []logger.MsgData{r.pnpManifest.tracker.MsgData(result.errorRange,\n\t\t\t\t\tfmt.Sprintf(\"The Yarn Plug'n'Play manifest says this package has a peer dependency on %q, but the package %q has not been installed:\", result.errorIdent, result.errorIdent))}\n\t\t\t}\n\n\t\t\treturn PathPair{}, false, nil, nil\n\t\t} else if result.status == pnpSuccess {\n\t\t\tabsPath := r.fs.Join(result.pkgDirPath, result.pkgSubpath)\n\n\t\t\t// If Yarn PnP path resolution succeeded, run a custom abbreviated\n\t\t\t// version of node's module resolution algorithm. The Yarn PnP\n\t\t\t// specification says to use node's module resolution algorithm verbatim\n\t\t\t// but that isn't what Yarn actually does. See this for more info:\n\t\t\t// https://github.com/evanw/esbuild/issues/2473#issuecomment-1216774461\n\t\t\tif pkgDirInfo := r.dirInfoCached(result.pkgDirPath); pkgDirInfo != nil {\n\t\t\t\t// Check the \"exports\" map\n\t\t\t\tif packageJSON := pkgDirInfo.packageJSON; packageJSON != nil && packageJSON.exportsMap != nil {\n\t\t\t\t\tabsolute, ok, diffCase := r.esmResolveAlgorithm(finalizeImportsExportsNormal, result.pkgIdent, \".\"+result.pkgSubpath, packageJSON, pkgDirInfo.absPath, absPath)\n\t\t\t\t\treturn absolute, ok, diffCase, nil\n\t\t\t\t}\n\n\t\t\t\t// Check the \"browser\" map\n\t\t\t\tif remapped, ok := r.checkBrowserMap(pkgDirInfo, absPath, absolutePathKind); ok {\n\t\t\t\t\tif remapped == nil {\n\t\t\t\t\t\treturn PathPair{Primary: logger.Path{Text: absPath, Namespace: \"file\", Flags: logger.PathDisabled}}, true, nil, nil\n\t\t\t\t\t}\n\t\t\t\t\tif remappedResult, ok, diffCase, sideEffects := r.resolveWithoutRemapping(pkgDirInfo.enclosingBrowserScope, *remapped); ok {\n\t\t\t\t\t\treturn remappedResult, true, diffCase, sideEffects\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif absolute, ok, diffCase := r.loadAsFileOrDirectory(absPath); ok {\n\t\t\t\t\treturn absolute, true, diffCase, nil\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Failed to resolve %q to a file\", absPath))\n\t\t\t}\n\t\t\treturn PathPair{}, false, nil, nil\n\t\t}\n\t}\n\n\t// Try to parse the package name using node's ESM-specific rules\n\tesmPackageName, esmPackageSubpath, esmOK := esmParsePackageName(importPath)\n\tif r.debugLogs != nil && esmOK {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Parsed package name %q and package subpath %q\", esmPackageName, esmPackageSubpath))\n\t}\n\n\t// Check for self-references\n\tif dirInfoPackageJSON != nil {\n\t\tif packageJSON := dirInfoPackageJSON.packageJSON; packageJSON.name == esmPackageName && packageJSON.exportsMap != nil {\n\t\t\tabsolute, ok, diffCase := r.esmResolveAlgorithm(finalizeImportsExportsNormal, esmPackageName, esmPackageSubpath, packageJSON,\n\t\t\t\tdirInfoPackageJSON.absPath, r.fs.Join(dirInfoPackageJSON.absPath, esmPackageSubpath))\n\t\t\treturn absolute, ok, diffCase, nil\n\t\t}\n\t}\n\n\t// Common package resolution logic shared between \"node_modules\" and \"NODE_PATHS\"\n\ttryToResolvePackage := func(absDir string) (PathPair, bool, *fs.DifferentCase, *SideEffectsData, bool) {\n\t\tabsPath := r.fs.Join(absDir, importPath)\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Checking for a package in the directory %q\", absPath))\n\t\t}\n\n\t\t// Try node's new package resolution rules\n\t\tif esmOK {\n\t\t\tabsPkgPath := r.fs.Join(absDir, esmPackageName)\n\t\t\tif pkgDirInfo := r.dirInfoCached(absPkgPath); pkgDirInfo != nil {\n\t\t\t\t// Check the \"exports\" map\n\t\t\t\tif packageJSON := pkgDirInfo.packageJSON; packageJSON != nil && packageJSON.exportsMap != nil {\n\t\t\t\t\tabsolute, ok, diffCase := r.esmResolveAlgorithm(finalizeImportsExportsNormal, esmPackageName, esmPackageSubpath, packageJSON, absPkgPath, absPath)\n\t\t\t\t\treturn absolute, ok, diffCase, nil, true\n\t\t\t\t}\n\n\t\t\t\t// Check the \"browser\" map\n\t\t\t\tif remapped, ok := r.checkBrowserMap(pkgDirInfo, absPath, absolutePathKind); ok {\n\t\t\t\t\tif remapped == nil {\n\t\t\t\t\t\treturn PathPair{Primary: logger.Path{Text: absPath, Namespace: \"file\", Flags: logger.PathDisabled}}, true, nil, nil, true\n\t\t\t\t\t}\n\t\t\t\t\tif remappedResult, ok, diffCase, sideEffects := r.resolveWithoutRemapping(pkgDirInfo.enclosingBrowserScope, *remapped); ok {\n\t\t\t\t\t\treturn remappedResult, true, diffCase, sideEffects, true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Try node's old package resolution rules\n\t\tif absolute, ok, diffCase := r.loadAsFileOrDirectory(absPath); ok {\n\t\t\treturn absolute, true, diffCase, nil, true\n\t\t}\n\n\t\treturn PathPair{}, false, nil, nil, false\n\t}\n\n\t// Then check for the package in any enclosing \"node_modules\" directories\n\tfor {\n\t\t// Skip directories that are themselves called \"node_modules\", since we\n\t\t// don't ever want to search for \"node_modules/node_modules\"\n\t\tif dirInfo.hasNodeModules {\n\t\t\tif absolute, ok, diffCase, sideEffects, shouldStop := tryToResolvePackage(r.fs.Join(dirInfo.absPath, \"node_modules\")); shouldStop {\n\t\t\t\treturn absolute, ok, diffCase, sideEffects\n\t\t\t}\n\t\t}\n\n\t\t// Go to the parent directory, stopping at the file system root\n\t\tdirInfo = dirInfo.parent\n\t\tif dirInfo == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Then check the global \"NODE_PATH\" environment variable. It has been\n\t// clarified that this step comes last after searching for \"node_modules\"\n\t// directories: https://github.com/nodejs/node/issues/38128.\n\tfor _, absDir := range r.options.AbsNodePaths {\n\t\tif absolute, ok, diffCase, sideEffects, shouldStop := tryToResolvePackage(absDir); shouldStop {\n\t\t\treturn absolute, ok, diffCase, sideEffects\n\t\t}\n\t}\n\n\treturn PathPair{}, false, nil, nil\n}\n\nfunc (r resolverQuery) checkForBuiltInNodeModules(importPath string) (PathPair, bool, *SideEffectsData) {\n\t// \"import fs from 'fs'\"\n\tif r.options.Platform == config.PlatformNode && BuiltInNodeModules[importPath] {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(\"Marking this path as implicitly external due to it being a node built-in\")\n\t\t}\n\n\t\tr.flushDebugLogs(flushDueToSuccess)\n\t\treturn PathPair{Primary: logger.Path{Text: importPath}, IsExternal: true},\n\t\t\ttrue,\n\t\t\t&SideEffectsData{} // Mark this with \"sideEffects: false\"\n\t}\n\n\t// \"import fs from 'node:fs'\"\n\t// \"require('node:fs')\"\n\tif r.options.Platform == config.PlatformNode && strings.HasPrefix(importPath, \"node:\") {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(\"Marking this path as implicitly external due to the \\\"node:\\\" prefix\")\n\t\t}\n\n\t\t// If this is a known node built-in module, mark it with \"sideEffects: false\"\n\t\tvar sideEffects *SideEffectsData\n\t\tif BuiltInNodeModules[strings.TrimPrefix(importPath, \"node:\")] {\n\t\t\tsideEffects = &SideEffectsData{}\n\t\t}\n\n\t\t// Check whether the path will end up as \"import\" or \"require\"\n\t\tconvertImportToRequire := !r.options.OutputFormat.KeepESMImportExportSyntax()\n\t\tisImport := !convertImportToRequire && (r.kind == ast.ImportStmt || r.kind == ast.ImportDynamic)\n\t\tisRequire := r.kind == ast.ImportRequire || r.kind == ast.ImportRequireResolve ||\n\t\t\t(convertImportToRequire && (r.kind == ast.ImportStmt || r.kind == ast.ImportDynamic))\n\n\t\t// Check for support with \"import\"\n\t\tif isImport && r.options.UnsupportedJSFeatures.Has(compat.NodeColonPrefixImport) {\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(\"Removing the \\\"node:\\\" prefix because the target environment doesn't support it with \\\"import\\\" statements\")\n\t\t\t}\n\n\t\t\t// Automatically strip the prefix if it's not supported\n\t\t\timportPath = importPath[5:]\n\t\t}\n\n\t\t// Check for support with \"require\"\n\t\tif isRequire && r.options.UnsupportedJSFeatures.Has(compat.NodeColonPrefixRequire) {\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(\"Removing the \\\"node:\\\" prefix because the target environment doesn't support it with \\\"require\\\" calls\")\n\t\t\t}\n\n\t\t\t// Automatically strip the prefix if it's not supported\n\t\t\timportPath = importPath[5:]\n\t\t}\n\n\t\tr.flushDebugLogs(flushDueToSuccess)\n\t\treturn PathPair{Primary: logger.Path{Text: importPath}, IsExternal: true}, true, sideEffects\n\t}\n\n\treturn PathPair{}, false, nil\n}\n\ntype finalizeImportsExportsKind uint8\n\nconst (\n\tfinalizeImportsExportsNormal finalizeImportsExportsKind = iota\n\tfinalizeImportsExportsYarnPnPTSConfigExtends\n)\n\nfunc (r resolverQuery) finalizeImportsExportsResult(\n\tkind finalizeImportsExportsKind,\n\tabsDirPath string,\n\tconditions map[string]bool,\n\timportExportMap pjMap,\n\tpackageJSON *packageJSON,\n\n\t// Resolution results\n\tresolvedPath string,\n\tstatus pjStatus,\n\tdebug pjDebug,\n\n\t// Only for exports\n\tesmPackageName string,\n\tesmPackageSubpath string,\n\tabsImportPath string,\n) (PathPair, bool, *fs.DifferentCase) {\n\tmissingSuffix := \"\"\n\n\tif (status == pjStatusExact || status == pjStatusExactEndsWithStar || status == pjStatusInexact) && strings.HasPrefix(resolvedPath, \"/\") {\n\t\tabsResolvedPath := r.fs.Join(absDirPath, resolvedPath)\n\n\t\tswitch status {\n\t\tcase pjStatusExact, pjStatusExactEndsWithStar:\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The resolved path %q is exact\", absResolvedPath))\n\t\t\t}\n\n\t\t\t// Avoid calling \"dirInfoCached\" recursively for \"tsconfig.json\" extends with Yarn PnP\n\t\t\tif kind == finalizeImportsExportsYarnPnPTSConfigExtends {\n\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Resolved to %q\", absResolvedPath))\n\t\t\t\t}\n\t\t\t\treturn PathPair{Primary: logger.Path{Text: absResolvedPath, Namespace: \"file\"}}, true, nil\n\t\t\t}\n\n\t\t\tresolvedDirInfo := r.dirInfoCached(r.fs.Dir(absResolvedPath))\n\t\t\tbase := r.fs.Base(absResolvedPath)\n\t\t\textensionOrder := r.options.ExtensionOrder\n\t\t\tif r.kind.MustResolveToCSS() {\n\t\t\t\textensionOrder = r.cssExtensionOrder\n\t\t\t}\n\n\t\t\tif resolvedDirInfo == nil {\n\t\t\t\tstatus = pjStatusModuleNotFound\n\t\t\t} else {\n\t\t\t\tentry, diffCase := resolvedDirInfo.entries.Get(base)\n\n\t\t\t\t// TypeScript-specific behavior: try rewriting \".js\" to \".ts\"\n\t\t\t\tif entry == nil {\n\t\t\t\t\tfor old, exts := range rewrittenFileExtensions {\n\t\t\t\t\t\tif !strings.HasSuffix(base, old) {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlastDot := strings.LastIndexByte(base, '.')\n\t\t\t\t\t\tfor _, ext := range exts {\n\t\t\t\t\t\t\tbaseWithExt := base[:lastDot] + ext\n\t\t\t\t\t\t\tentry, diffCase = resolvedDirInfo.entries.Get(baseWithExt)\n\t\t\t\t\t\t\tif entry != nil {\n\t\t\t\t\t\t\t\tabsResolvedPath = r.fs.Join(resolvedDirInfo.absPath, baseWithExt)\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif entry == nil {\n\t\t\t\t\tendsWithStar := status == pjStatusExactEndsWithStar\n\t\t\t\t\tstatus = pjStatusModuleNotFound\n\n\t\t\t\t\t// Try to have a friendly error message if people forget the extension\n\t\t\t\t\tif endsWithStar {\n\t\t\t\t\t\tfor _, ext := range extensionOrder {\n\t\t\t\t\t\t\tif entry, _ := resolvedDirInfo.entries.Get(base + ext); entry != nil {\n\t\t\t\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The import %q is missing the extension %q\", path.Join(esmPackageName, esmPackageSubpath), ext))\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tstatus = pjStatusModuleNotFoundMissingExtension\n\t\t\t\t\t\t\t\tmissingSuffix = ext\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if kind := entry.Kind(r.fs); kind == fs.DirEntry {\n\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The path %q is a directory, which is not allowed\", absResolvedPath))\n\t\t\t\t\t}\n\t\t\t\t\tendsWithStar := status == pjStatusExactEndsWithStar\n\t\t\t\t\tstatus = pjStatusUnsupportedDirectoryImport\n\n\t\t\t\t\t// Try to have a friendly error message if people forget the \"/index.js\" suffix\n\t\t\t\t\tif endsWithStar {\n\t\t\t\t\t\tif resolvedDirInfo := r.dirInfoCached(absResolvedPath); resolvedDirInfo != nil {\n\t\t\t\t\t\t\tfor _, ext := range extensionOrder {\n\t\t\t\t\t\t\t\tbase := \"index\" + ext\n\t\t\t\t\t\t\t\tif entry, _ := resolvedDirInfo.entries.Get(base); entry != nil && entry.Kind(r.fs) == fs.FileEntry {\n\t\t\t\t\t\t\t\t\tstatus = pjStatusUnsupportedDirectoryImportMissingIndex\n\t\t\t\t\t\t\t\t\tmissingSuffix = \"/\" + base\n\t\t\t\t\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The import %q is missing the suffix %q\", path.Join(esmPackageName, esmPackageSubpath), missingSuffix))\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if kind != fs.FileEntry {\n\t\t\t\t\tstatus = pjStatusModuleNotFound\n\t\t\t\t} else {\n\t\t\t\t\tif r.debugLogs != nil {\n\t\t\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"Resolved to %q\", absResolvedPath))\n\t\t\t\t\t}\n\t\t\t\t\treturn PathPair{Primary: logger.Path{Text: absResolvedPath, Namespace: \"file\"}}, true, diffCase\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase pjStatusInexact:\n\t\t\t// If this was resolved against an expansion key ending in a \"/\"\n\t\t\t// instead of a \"*\", we need to try CommonJS-style implicit\n\t\t\t// extension and/or directory detection.\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"The resolved path %q is inexact\", absResolvedPath))\n\t\t\t}\n\t\t\tif absolute, ok, diffCase := r.loadAsFileOrDirectory(absResolvedPath); ok {\n\t\t\t\treturn absolute, true, diffCase\n\t\t\t}\n\t\t\tstatus = pjStatusModuleNotFound\n\t\t}\n\t}\n\n\tif strings.HasPrefix(resolvedPath, \"/\") {\n\t\tresolvedPath = \".\" + resolvedPath\n\t}\n\n\t// Provide additional details about the failure to help with debugging\n\ttracker := logger.MakeLineColumnTracker(&packageJSON.source)\n\tswitch status {\n\tcase pjStatusInvalidModuleSpecifier:\n\t\tr.debugMeta.notes = []logger.MsgData{tracker.MsgData(debug.token,\n\t\t\tfmt.Sprintf(\"The module specifier %q is invalid%s:\", resolvedPath, debug.invalidBecause))}\n\n\tcase pjStatusInvalidPackageConfiguration:\n\t\tr.debugMeta.notes = []logger.MsgData{tracker.MsgData(debug.token,\n\t\t\t\"The package configuration has an invalid value here:\")}\n\n\tcase pjStatusInvalidPackageTarget:\n\t\twhy := fmt.Sprintf(\"The package target %q is invalid%s:\", resolvedPath, debug.invalidBecause)\n\t\tif resolvedPath == \"\" {\n\t\t\t// \"PACKAGE_TARGET_RESOLVE\" is specified to throw an \"Invalid\n\t\t\t// Package Target\" error for what is actually an invalid package\n\t\t\t// configuration error\n\t\t\twhy = \"The package configuration has an invalid value here:\"\n\t\t}\n\t\tr.debugMeta.notes = []logger.MsgData{tracker.MsgData(debug.token, why)}\n\n\tcase pjStatusPackagePathNotExported:\n\t\tif debug.isBecauseOfNullLiteral {\n\t\t\tr.debugMeta.notes = []logger.MsgData{tracker.MsgData(debug.token,\n\t\t\t\tfmt.Sprintf(\"The path %q cannot be imported from package %q because it was explicitly disabled by the package author here:\", esmPackageSubpath, esmPackageName))}\n\t\t\tbreak\n\t\t}\n\n\t\tr.debugMeta.notes = []logger.MsgData{tracker.MsgData(debug.token,\n\t\t\tfmt.Sprintf(\"The path %q is not exported by package %q:\", esmPackageSubpath, esmPackageName))}\n\n\t\t// If this fails, try to resolve it using the old algorithm\n\t\tif absolute, ok, _ := r.loadAsFileOrDirectory(absImportPath); ok && absolute.Primary.Namespace == \"file\" {\n\t\t\tif relPath, ok := r.fs.Rel(absDirPath, absolute.Primary.Text); ok {\n\t\t\t\tquery := \".\" + path.Join(\"/\", strings.ReplaceAll(relPath, \"\\\\\", \"/\"))\n\n\t\t\t\t// If that succeeds, try to do a reverse lookup using the\n\t\t\t\t// \"exports\" map for the currently-active set of conditions\n\t\t\t\tif ok, subpath, token := r.esmPackageExportsReverseResolve(\n\t\t\t\t\tquery, importExportMap.root, conditions); ok {\n\t\t\t\t\tr.debugMeta.notes = append(r.debugMeta.notes, tracker.MsgData(token,\n\t\t\t\t\t\tfmt.Sprintf(\"The file %q is exported at path %q:\", query, subpath)))\n\n\t\t\t\t\t// Provide an inline suggestion message with the correct import path\n\t\t\t\t\tprettyPaths := MakePrettyPaths(r.fs, absolute.Primary)\n\t\t\t\t\tactualImportPath := path.Join(esmPackageName, subpath)\n\t\t\t\t\tr.debugMeta.suggestionText = string(helpers.QuoteForJSON(actualImportPath, false))\n\t\t\t\t\tr.debugMeta.suggestionMessage = fmt.Sprintf(\"Import from %q to get the file %q:\",\n\t\t\t\t\t\tactualImportPath, prettyPaths.Select(r.options.LogPathStyle))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\tcase pjStatusPackageImportNotDefined:\n\t\tr.debugMeta.notes = []logger.MsgData{tracker.MsgData(debug.token,\n\t\t\tfmt.Sprintf(\"The package import %q is not defined in this \\\"imports\\\" map:\", resolvedPath))}\n\n\tcase pjStatusModuleNotFound, pjStatusModuleNotFoundMissingExtension:\n\t\tr.debugMeta.notes = []logger.MsgData{tracker.MsgData(debug.token,\n\t\t\tfmt.Sprintf(\"The module %q was not found on the file system:\", resolvedPath))}\n\n\t\t// Provide an inline suggestion message with the correct import path\n\t\tif status == pjStatusModuleNotFoundMissingExtension {\n\t\t\tprettyPaths := MakePrettyPaths(r.fs, logger.Path{Text: r.fs.Join(absDirPath, resolvedPath+missingSuffix), Namespace: \"file\"})\n\t\t\tactualImportPath := path.Join(esmPackageName, esmPackageSubpath+missingSuffix)\n\t\t\tr.debugMeta.suggestionRange = suggestionRangeEnd\n\t\t\tr.debugMeta.suggestionText = missingSuffix\n\t\t\tr.debugMeta.suggestionMessage = fmt.Sprintf(\"Import from %q to get the file %q:\",\n\t\t\t\tactualImportPath, prettyPaths.Select(r.options.LogPathStyle))\n\t\t}\n\n\tcase pjStatusUnsupportedDirectoryImport, pjStatusUnsupportedDirectoryImportMissingIndex:\n\t\tr.debugMeta.notes = []logger.MsgData{\n\t\t\ttracker.MsgData(debug.token, fmt.Sprintf(\"Importing the directory %q is forbidden by this package:\", resolvedPath)),\n\t\t\ttracker.MsgData(packageJSON.source.RangeOfString(importExportMap.propertyKeyLoc),\n\t\t\t\tfmt.Sprintf(\"The presence of %q here makes importing a directory forbidden:\", importExportMap.propertyKey)),\n\t\t}\n\n\t\t// Provide an inline suggestion message with the correct import path\n\t\tif status == pjStatusUnsupportedDirectoryImportMissingIndex {\n\t\t\tprettyPaths := MakePrettyPaths(r.fs, logger.Path{Text: r.fs.Join(absDirPath, resolvedPath+missingSuffix), Namespace: \"file\"})\n\t\t\tactualImportPath := path.Join(esmPackageName, esmPackageSubpath+missingSuffix)\n\t\t\tr.debugMeta.suggestionRange = suggestionRangeEnd\n\t\t\tr.debugMeta.suggestionText = missingSuffix\n\t\t\tr.debugMeta.suggestionMessage = fmt.Sprintf(\"Import from %q to get the file %q:\",\n\t\t\t\tactualImportPath, prettyPaths.Select(r.options.LogPathStyle))\n\t\t}\n\n\tcase pjStatusUndefinedNoConditionsMatch:\n\t\tkeys := make([]string, 0, len(conditions))\n\t\tfor key := range conditions {\n\t\t\tkeys = append(keys, key)\n\t\t}\n\t\tsort.Strings(keys)\n\n\t\tunmatchedConditions := make([]string, len(debug.unmatchedConditions))\n\t\tfor i, key := range debug.unmatchedConditions {\n\t\t\tunmatchedConditions[i] = key.Text\n\t\t}\n\n\t\tr.debugMeta.notes = []logger.MsgData{\n\t\t\ttracker.MsgData(importExportMap.root.firstToken,\n\t\t\t\tfmt.Sprintf(\"The path %q is not currently exported by package %q:\",\n\t\t\t\t\tesmPackageSubpath, esmPackageName)),\n\n\t\t\ttracker.MsgData(debug.token,\n\t\t\t\tfmt.Sprintf(\"None of the conditions in the package definition (%s) match any of the currently active conditions (%s):\",\n\t\t\t\t\thelpers.StringArrayToQuotedCommaSeparatedString(unmatchedConditions),\n\t\t\t\t\thelpers.StringArrayToQuotedCommaSeparatedString(keys),\n\t\t\t\t)),\n\t\t}\n\n\t\tdidSuggestEnablingCondition := false\n\t\tfor _, key := range debug.unmatchedConditions {\n\t\t\tswitch key.Text {\n\t\t\tcase \"import\":\n\t\t\t\tif r.kind == ast.ImportRequire || r.kind == ast.ImportRequireResolve {\n\t\t\t\t\tr.debugMeta.suggestionMessage = \"Consider using an \\\"import\\\" statement to import this file, \" +\n\t\t\t\t\t\t\"which will work because the \\\"import\\\" condition is supported by this package:\"\n\t\t\t\t}\n\n\t\t\tcase \"require\":\n\t\t\t\tif r.kind == ast.ImportStmt || r.kind == ast.ImportDynamic {\n\t\t\t\t\tr.debugMeta.suggestionMessage = \"Consider using a \\\"require()\\\" call to import this file, \" +\n\t\t\t\t\t\t\"which will work because the \\\"require\\\" condition is supported by this package:\"\n\t\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\t// Note: Don't suggest the adding the \"types\" condition because\n\t\t\t\t// TypeScript uses that for type definitions, which are not\n\t\t\t\t// intended to be included in a bundle as executable code\n\t\t\t\tif !didSuggestEnablingCondition && key.Text != \"types\" {\n\t\t\t\t\tvar how string\n\t\t\t\t\tswitch logger.API {\n\t\t\t\t\tcase logger.CLIAPI:\n\t\t\t\t\t\thow = fmt.Sprintf(\"\\\"--conditions=%s\\\"\", key.Text)\n\t\t\t\t\tcase logger.JSAPI:\n\t\t\t\t\t\thow = fmt.Sprintf(\"\\\"conditions: ['%s']\\\"\", key.Text)\n\t\t\t\t\tcase logger.GoAPI:\n\t\t\t\t\t\thow = fmt.Sprintf(\"'Conditions: []string{%q}'\", key.Text)\n\t\t\t\t\t}\n\t\t\t\t\tr.debugMeta.notes = append(r.debugMeta.notes, tracker.MsgData(key.Range,\n\t\t\t\t\t\tfmt.Sprintf(\"Consider enabling the %q condition if this package expects it to be enabled. \"+\n\t\t\t\t\t\t\t\"You can use %s to do that:\", key.Text, how)))\n\t\t\t\t\tdidSuggestEnablingCondition = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn PathPair{}, false, nil\n}\n\n// Package paths are loaded from a \"node_modules\" directory. Non-package paths\n// are relative or absolute paths.\nfunc IsPackagePath(path string) bool {\n\treturn !strings.HasPrefix(path, \"/\") && !strings.HasPrefix(path, \"./\") &&\n\t\t!strings.HasPrefix(path, \"../\") && path != \".\" && path != \"..\"\n}\n\n// This list can be obtained with the following command:\n//\n//\tnode --experimental-wasi-unstable-preview1 -p \"[...require('module').builtinModules].join('\\n')\"\n//\n// Be sure to use the *LATEST* version of node when updating this list!\nvar BuiltInNodeModules = map[string]bool{\n\t\"_http_agent\":         true,\n\t\"_http_client\":        true,\n\t\"_http_common\":        true,\n\t\"_http_incoming\":      true,\n\t\"_http_outgoing\":      true,\n\t\"_http_server\":        true,\n\t\"_stream_duplex\":      true,\n\t\"_stream_passthrough\": true,\n\t\"_stream_readable\":    true,\n\t\"_stream_transform\":   true,\n\t\"_stream_wrap\":        true,\n\t\"_stream_writable\":    true,\n\t\"_tls_common\":         true,\n\t\"_tls_wrap\":           true,\n\t\"assert\":              true,\n\t\"assert/strict\":       true,\n\t\"async_hooks\":         true,\n\t\"buffer\":              true,\n\t\"child_process\":       true,\n\t\"cluster\":             true,\n\t\"console\":             true,\n\t\"constants\":           true,\n\t\"crypto\":              true,\n\t\"dgram\":               true,\n\t\"diagnostics_channel\": true,\n\t\"dns\":                 true,\n\t\"dns/promises\":        true,\n\t\"domain\":              true,\n\t\"events\":              true,\n\t\"fs\":                  true,\n\t\"fs/promises\":         true,\n\t\"http\":                true,\n\t\"http2\":               true,\n\t\"https\":               true,\n\t\"inspector\":           true,\n\t\"module\":              true,\n\t\"net\":                 true,\n\t\"os\":                  true,\n\t\"path\":                true,\n\t\"path/posix\":          true,\n\t\"path/win32\":          true,\n\t\"perf_hooks\":          true,\n\t\"process\":             true,\n\t\"punycode\":            true,\n\t\"querystring\":         true,\n\t\"readline\":            true,\n\t\"repl\":                true,\n\t\"stream\":              true,\n\t\"stream/consumers\":    true,\n\t\"stream/promises\":     true,\n\t\"stream/web\":          true,\n\t\"string_decoder\":      true,\n\t\"sys\":                 true,\n\t\"timers\":              true,\n\t\"timers/promises\":     true,\n\t\"tls\":                 true,\n\t\"trace_events\":        true,\n\t\"tty\":                 true,\n\t\"url\":                 true,\n\t\"util\":                true,\n\t\"util/types\":          true,\n\t\"v8\":                  true,\n\t\"vm\":                  true,\n\t\"wasi\":                true,\n\t\"worker_threads\":      true,\n\t\"zlib\":                true,\n}\n"
  },
  {
    "path": "internal/resolver/testExpectations.json",
    "content": "[{\n  \"manifest\": {\n    \"__info\": [],\n    \"dependencyTreeRoots\": [{\n      \"name\": \"root\",\n      \"reference\": \"workspace:.\"\n    }],\n    \"ignorePatternData\": null,\n    \"enableTopLevelFallback\": false,\n    \"fallbackPool\": [],\n    \"fallbackExclusionList\": [],\n    \"packageRegistryData\": [\n      [null, [\n        [null, {\n          \"packageLocation\": \"./\",\n          \"packageDependencies\": [[\"test\", \"npm:1.0.0\"]],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"root\", [\n        [\"workspace:.\", {\n          \"packageLocation\": \"./\",\n          \"packageDependencies\": [[\"test\", \"npm:1.0.0\"]],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"workspace-alias-dependency\", [\n        [\"workspace:workspace-alias-dependency\", {\n          \"packageLocation\": \"./workspace-alias-dependency/\",\n          \"packageDependencies\": [[\"alias\", [\"test\", \"npm:1.0.0\"]]],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"workspace-self-dependency\", [\n        [\"workspace:workspace-self-dependency\", {\n          \"packageLocation\": \"./workspace-self-dependency/\",\n          \"packageDependencies\": [[\"workspace-self-dependency\", \"workspace:workspace-self-dependency\"]],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"workspace-unfulfilled-peer-dependency\", [\n        [\"workspace:workspace-unfulfilled-peer-dependency\", {\n          \"packageLocation\": \"./workspace-unfulfilled-peer-dependency/\",\n          \"packageDependencies\": [[\"test\", null]],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"longer\", [\n        [\"workspace:longer\", {\n          \"packageLocation\": \"./longer/\",\n          \"packageDependencies\": [[\"test\", \"npm:2.0.0\"]],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"long\", [\n        [\"workspace:long\", {\n          \"packageLocation\": \"./long/\",\n          \"packageDependencies\": [[\"test\", \"npm:1.0.0\"]],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"longerer\", [\n        [\"workspace:longerer\", {\n          \"packageLocation\": \"./longerer/\",\n          \"packageDependencies\": [[\"test\", \"npm:3.0.0\"]],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"test\", [\n        [\"npm:1.0.0\", {\n          \"packageLocation\": \"./test-1.0.0/\",\n          \"packageDependencies\": [],\n          \"linkType\": \"HARD\"\n        }],\n        [\"npm:2.0.0\", {\n          \"packageLocation\": \"./test-2.0.0/\",\n          \"packageDependencies\": [],\n          \"linkType\": \"HARD\"\n        }],\n        [\"npm:3.0.0\", {\n          \"packageLocation\": \"./test-3.0.0/\",\n          \"packageDependencies\": [],\n          \"linkType\": \"HARD\"\n        }]\n      ]]\n    ]\n  },\n  \"tests\": [{\n    \"it\": \"should allow a package to import one of its dependencies\",\n    \"imported\": \"test\",\n    \"importer\": \"/path/to/project/\",\n    \"expected\": \"/path/to/project/test-1.0.0/\"\n  }, {\n    \"it\": \"should allow a package to import itself, if specified in its own dependencies\",\n    \"imported\": \"workspace-self-dependency\",\n    \"importer\": \"/path/to/project/workspace-self-dependency/\",\n    \"expected\": \"/path/to/project/workspace-self-dependency/\"\n  }, {\n    \"it\": \"should allow a package to import an aliased dependency\",\n    \"imported\": \"alias\",\n    \"importer\": \"/path/to/project/workspace-alias-dependency/\",\n    \"expected\": \"/path/to/project/test-1.0.0/\"\n  }, {\n    \"it\": \"shouldn't allow a package to import something that isn't one of its dependencies\",\n    \"imported\": \"missing-dependency\",\n    \"importer\": \"/path/to/project/\",\n    \"expected\": \"error!\"\n  }, {\n    \"it\": \"shouldn't accidentally discard the trailing slash from the package locations\",\n    \"imported\": \"test\",\n    \"importer\": \"/path/to/project/long/\",\n    \"expected\": \"/path/to/project/test-1.0.0/\"\n  }, {\n    \"it\": \"should throw an exception when trying to access an unfulfilled peer dependency\",\n    \"imported\": \"test\",\n    \"importer\": \"/path/to/project/workspace-unfulfilled-peer-dependency/\",\n    \"expected\": \"error!\"\n  }]\n}, {\n  \"manifest\": {\n    \"__info\": [],\n    \"dependencyTreeRoots\": [{\n      \"name\": \"root\",\n      \"reference\": \"workspace:.\"\n    }],\n    \"ignorePatternData\": null,\n    \"enableTopLevelFallback\": true,\n    \"fallbackPool\": [\n      [\"test-2\", \"npm:1.0.0\"],\n      [\"alias\", [\"test-1\", \"npm:1.0.0\"]]\n    ],\n    \"fallbackExclusionList\": [[\n      \"workspace-no-fallbacks\",\n      [\"workspace:workspace-no-fallbacks\"]\n    ]],\n    \"packageRegistryData\": [\n      [null, [\n        [null, {\n          \"packageLocation\": \"./\",\n          \"packageDependencies\": [[\"test-1\", \"npm:1.0.0\"]],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"root\", [\n        [\"workspace:.\", {\n          \"packageLocation\": \"./\",\n          \"packageDependencies\": [[\"test-1\", \"npm:1.0.0\"]],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"workspace-no-fallbacks\", [\n        [\"workspace:workspace-no-fallbacks\", {\n          \"packageLocation\": \"./workspace-no-fallbacks/\",\n          \"packageDependencies\": [],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"workspace-with-fallbacks\", [\n        [\"workspace:workspace-with-fallbacks\", {\n          \"packageLocation\": \"./workspace-with-fallbacks/\",\n          \"packageDependencies\": [],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"workspace-unfulfilled-peer-dependency\", [\n        [\"workspace:workspace-unfulfilled-peer-dependency\", {\n          \"packageLocation\": \"./workspace-unfulfilled-peer-dependency/\",\n          \"packageDependencies\": [\n            [\"test-1\", null],\n            [\"test-2\", null]\n          ],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"test-1\", [\n        [\"npm:1.0.0\", {\n          \"packageLocation\": \"./test-1/\",\n          \"packageDependencies\": [],\n          \"linkType\": \"HARD\"\n        }]\n      ]],\n      [\"test-2\", [\n        [\"npm:1.0.0\", {\n          \"packageLocation\": \"./test-2/\",\n          \"packageDependencies\": [],\n          \"linkType\": \"HARD\"\n        }]\n      ]]\n    ]\n  },\n  \"tests\": [{\n    \"it\": \"should allow resolution coming from the fallback pool if enableTopLevelFallback is set to true\",\n    \"imported\": \"test-1\",\n    \"importer\": \"/path/to/project/\",\n    \"expected\": \"/path/to/project/test-1/\"\n  }, {\n    \"it\": \"should allow the fallback pool to contain aliases\",\n    \"imported\": \"alias\",\n    \"importer\": \"/path/to/project/\",\n    \"expected\": \"/path/to/project/test-1/\"\n  }, {\n    \"it\": \"shouldn't use the fallback pool when the importer package is listed in fallbackExclusionList\",\n    \"imported\": \"test-1\",\n    \"importer\": \"/path/to/project/workspace-no-fallbacks/\",\n    \"expected\": \"error!\"\n  }, {\n    \"it\": \"should implicitly use the top-level package dependencies as part of the fallback pool\",\n    \"imported\": \"test-2\",\n    \"importer\": \"/path/to/project/workspace-with-fallbacks/\",\n    \"expected\": \"/path/to/project/test-2/\"\n  }, {\n    \"it\": \"should throw an error if a resolution isn't in in the package dependencies, nor inside the fallback pool\",\n    \"imported\": \"test-3\",\n    \"importer\": \"/path/to/project/workspace-with-fallbacks/\",\n    \"expected\": \"error!\"\n  }, {\n    \"it\": \"should use the top-level fallback if a dependency is missing because of an unfulfilled peer dependency\",\n    \"imported\": \"test-1\",\n    \"importer\": \"/path/to/project/workspace-unfulfilled-peer-dependency/\",\n    \"expected\": \"/path/to/project/test-1/\"\n  }, {\n    \"it\": \"should use the fallback pool if a dependency is missing because of an unfulfilled peer dependency\",\n    \"imported\": \"test-2\",\n    \"importer\": \"/path/to/project/workspace-unfulfilled-peer-dependency/\",\n    \"expected\": \"/path/to/project/test-2/\"\n  }]\n}, {\n  \"manifest\": {\n    \"__info\": [],\n    \"dependencyTreeRoots\": [{\n      \"name\": \"root\",\n      \"reference\": \"workspace:.\"\n    }],\n    \"ignorePatternData\": null,\n    \"enableTopLevelFallback\": false,\n    \"fallbackPool\": [\n      [\"test\", \"npm:1.0.0\"]\n    ],\n    \"fallbackExclusionList\": [],\n    \"packageRegistryData\": [\n      [null, [\n        [null, {\n          \"packageLocation\": \"./\",\n          \"packageDependencies\": [],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"root\", [\n        [\"workspace:.\", {\n          \"packageLocation\": \"./\",\n          \"packageDependencies\": [],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"test\", [\n        [\"npm:1.0.0\", {\n          \"packageLocation\": \"./test-1/\",\n          \"packageDependencies\": [],\n          \"linkType\": \"HARD\"\n        }]\n      ]]\n    ]\n  },\n  \"tests\": [{\n    \"it\": \"should ignore the fallback pool if enableTopLevelFallback is set to false\",\n    \"imported\": \"test\",\n    \"importer\": \"/path/to/project/\",\n    \"expected\": \"error!\"\n  }]\n}, {\n  \"manifest\": {\n    \"__info\": [],\n    \"dependencyTreeRoots\": [{\n      \"name\": \"root\",\n      \"reference\": \"workspace:.\"\n    }],\n    \"ignorePatternData\": \"^not-a-workspace(/|$)\",\n    \"enableTopLevelFallback\": false,\n    \"fallbackPool\": [],\n    \"fallbackExclusionList\": [],\n    \"packageRegistryData\": [\n      [null, [\n        [null, {\n          \"packageLocation\": \"./\",\n          \"packageDependencies\": [],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"root\", [\n        [\"workspace:.\", {\n          \"packageLocation\": \"./\",\n          \"packageDependencies\": [[\"test\", \"npm:1.0.0\"]],\n          \"linkType\": \"SOFT\"\n        }]\n      ]],\n      [\"test\", [\n        [\"npm:1.0.0\", {\n          \"packageLocation\": \"./test/\",\n          \"packageDependencies\": [],\n          \"linkType\": \"HARD\"\n        }]\n      ]]\n    ]\n  },\n  \"tests\": [{\n    \"it\": \"shouldn't go through PnP when trying to resolve dependencies from packages covered by ignorePatternData\",\n    \"imported\": \"test\",\n    \"importer\": \"/path/to/project/not-a-workspace/\",\n    \"expected\": \"error!\"\n  }]\n}]\n"
  },
  {
    "path": "internal/resolver/tsconfig_json.go",
    "content": "package resolver\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/cache\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/fs\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/js_lexer\"\n\t\"github.com/evanw/esbuild/internal/js_parser\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\ntype TSConfigJSON struct {\n\tAbsPath string\n\n\t// The absolute path of \"compilerOptions.baseUrl\"\n\tBaseURL *string\n\n\t// This is used if \"Paths\" is non-nil. It's equal to \"BaseURL\" except if\n\t// \"BaseURL\" is missing, in which case it is as if \"BaseURL\" was \".\". This\n\t// is to implement the \"paths without baseUrl\" feature from TypeScript 4.1.\n\t// More info: https://github.com/microsoft/TypeScript/issues/31869\n\tBaseURLForPaths string\n\n\t// The verbatim values of \"compilerOptions.paths\". The keys are patterns to\n\t// match and the values are arrays of fallback paths to search. Each key and\n\t// each fallback path can optionally have a single \"*\" wildcard character.\n\t// If both the key and the value have a wildcard, the substring matched by\n\t// the wildcard is substituted into the fallback path. The keys represent\n\t// module-style path names and the fallback paths are relative to the\n\t// \"baseUrl\" value in the \"tsconfig.json\" file.\n\tPaths *TSConfigPaths\n\n\ttsTargetKey    tsTargetKey\n\tTSStrict       *config.TSAlwaysStrict\n\tTSAlwaysStrict *config.TSAlwaysStrict\n\tJSXSettings    config.TSConfigJSX\n\tSettings       config.TSConfig\n}\n\nfunc (derived *TSConfigJSON) applyExtendedConfig(base TSConfigJSON) {\n\tif base.tsTargetKey.Range.Len > 0 {\n\t\tderived.tsTargetKey = base.tsTargetKey\n\t}\n\tif base.TSStrict != nil {\n\t\tderived.TSStrict = base.TSStrict\n\t}\n\tif base.TSAlwaysStrict != nil {\n\t\tderived.TSAlwaysStrict = base.TSAlwaysStrict\n\t}\n\tif base.BaseURL != nil {\n\t\tderived.BaseURL = base.BaseURL\n\t}\n\tif base.Paths != nil {\n\t\tderived.Paths = base.Paths\n\t\tderived.BaseURLForPaths = base.BaseURLForPaths\n\t}\n\tderived.JSXSettings.ApplyExtendedConfig(base.JSXSettings)\n\tderived.Settings.ApplyExtendedConfig(base.Settings)\n}\n\nfunc (config *TSConfigJSON) TSAlwaysStrictOrStrict() *config.TSAlwaysStrict {\n\tif config.TSAlwaysStrict != nil {\n\t\treturn config.TSAlwaysStrict\n\t}\n\n\t// If \"alwaysStrict\" is absent, it defaults to \"strict\" instead\n\treturn config.TSStrict\n}\n\n// This information is only used for error messages\ntype tsTargetKey struct {\n\tLowerValue string\n\tSource     logger.Source\n\tRange      logger.Range\n}\n\ntype TSConfigPath struct {\n\tText string\n\tLoc  logger.Loc\n}\n\ntype TSConfigPaths struct {\n\tMap map[string][]TSConfigPath\n\n\t// This may be different from the original \"tsconfig.json\" source if the\n\t// \"paths\" value is from another file via an \"extends\" clause.\n\tSource logger.Source\n}\n\nfunc ParseTSConfigJSON(\n\tlog logger.Log,\n\tsource logger.Source,\n\tjsonCache *cache.JSONCache,\n\tfs fs.FS,\n\tfileDir string,\n\tconfigDir string,\n\textends func(string, logger.Range) *TSConfigJSON,\n) *TSConfigJSON {\n\t// Unfortunately \"tsconfig.json\" isn't actually JSON. It's some other\n\t// format that appears to be defined by the implementation details of the\n\t// TypeScript compiler.\n\t//\n\t// Attempt to parse it anyway by modifying the JSON parser, but just for\n\t// these particular files. This is likely not a completely accurate\n\t// emulation of what the TypeScript compiler does (e.g. string escape\n\t// behavior may also be different).\n\tjson, ok := jsonCache.Parse(log, source, js_parser.JSONOptions{Flavor: js_lexer.TSConfigJSON})\n\tif !ok {\n\t\treturn nil\n\t}\n\n\tvar result TSConfigJSON\n\tresult.AbsPath = source.KeyPath.Text\n\ttracker := logger.MakeLineColumnTracker(&source)\n\n\t// Parse \"extends\"\n\tif extends != nil {\n\t\tif valueJSON, _, ok := getProperty(json, \"extends\"); ok {\n\t\t\tif value, ok := getString(valueJSON); ok {\n\t\t\t\tif base := extends(value, source.RangeOfString(valueJSON.Loc)); base != nil {\n\t\t\t\t\tresult.applyExtendedConfig(*base)\n\t\t\t\t}\n\t\t\t} else if array, ok := valueJSON.Data.(*js_ast.EArray); ok {\n\t\t\t\tfor _, item := range array.Items {\n\t\t\t\t\tif str, ok := getString(item); ok {\n\t\t\t\t\t\tif base := extends(str, source.RangeOfString(item.Loc)); base != nil {\n\t\t\t\t\t\t\tresult.applyExtendedConfig(*base)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Parse \"compilerOptions\"\n\tif compilerOptionsJSON, _, ok := getProperty(json, \"compilerOptions\"); ok {\n\t\t// Parse \"baseUrl\"\n\t\tif valueJSON, _, ok := getProperty(compilerOptionsJSON, \"baseUrl\"); ok {\n\t\t\tif value, ok := getString(valueJSON); ok {\n\t\t\t\tvalue = getSubstitutedPathWithConfigDirTemplate(fs, value, configDir)\n\t\t\t\tif !fs.IsAbs(value) {\n\t\t\t\t\tvalue = fs.Join(fileDir, value)\n\t\t\t\t}\n\t\t\t\tresult.BaseURL = &value\n\t\t\t}\n\t\t}\n\n\t\t// Parse \"jsx\"\n\t\tif valueJSON, _, ok := getProperty(compilerOptionsJSON, \"jsx\"); ok {\n\t\t\tif value, ok := getString(valueJSON); ok {\n\t\t\t\tswitch strings.ToLower(value) {\n\t\t\t\tcase \"preserve\":\n\t\t\t\t\tresult.JSXSettings.JSX = config.TSJSXPreserve\n\t\t\t\tcase \"react-native\":\n\t\t\t\t\tresult.JSXSettings.JSX = config.TSJSXReactNative\n\t\t\t\tcase \"react\":\n\t\t\t\t\tresult.JSXSettings.JSX = config.TSJSXReact\n\t\t\t\tcase \"react-jsx\":\n\t\t\t\t\tresult.JSXSettings.JSX = config.TSJSXReactJSX\n\t\t\t\tcase \"react-jsxdev\":\n\t\t\t\t\tresult.JSXSettings.JSX = config.TSJSXReactJSXDev\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Parse \"jsxFactory\"\n\t\tif valueJSON, _, ok := getProperty(compilerOptionsJSON, \"jsxFactory\"); ok {\n\t\t\tif value, ok := getString(valueJSON); ok {\n\t\t\t\tresult.JSXSettings.JSXFactory = parseMemberExpressionForJSX(log, &source, &tracker, valueJSON.Loc, value)\n\t\t\t}\n\t\t}\n\n\t\t// Parse \"jsxFragmentFactory\"\n\t\tif valueJSON, _, ok := getProperty(compilerOptionsJSON, \"jsxFragmentFactory\"); ok {\n\t\t\tif value, ok := getString(valueJSON); ok {\n\t\t\t\tresult.JSXSettings.JSXFragmentFactory = parseMemberExpressionForJSX(log, &source, &tracker, valueJSON.Loc, value)\n\t\t\t}\n\t\t}\n\n\t\t// Parse \"jsxImportSource\"\n\t\tif valueJSON, _, ok := getProperty(compilerOptionsJSON, \"jsxImportSource\"); ok {\n\t\t\tif value, ok := getString(valueJSON); ok {\n\t\t\t\tresult.JSXSettings.JSXImportSource = &value\n\t\t\t}\n\t\t}\n\n\t\t// Parse \"experimentalDecorators\"\n\t\tif valueJSON, _, ok := getProperty(compilerOptionsJSON, \"experimentalDecorators\"); ok {\n\t\t\tif value, ok := getBool(valueJSON); ok {\n\t\t\t\tif value {\n\t\t\t\t\tresult.Settings.ExperimentalDecorators = config.True\n\t\t\t\t} else {\n\t\t\t\t\tresult.Settings.ExperimentalDecorators = config.False\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Parse \"useDefineForClassFields\"\n\t\tif valueJSON, _, ok := getProperty(compilerOptionsJSON, \"useDefineForClassFields\"); ok {\n\t\t\tif value, ok := getBool(valueJSON); ok {\n\t\t\t\tif value {\n\t\t\t\t\tresult.Settings.UseDefineForClassFields = config.True\n\t\t\t\t} else {\n\t\t\t\t\tresult.Settings.UseDefineForClassFields = config.False\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Parse \"target\"\n\t\tif valueJSON, keyLoc, ok := getProperty(compilerOptionsJSON, \"target\"); ok {\n\t\t\tif value, ok := getString(valueJSON); ok {\n\t\t\t\tlowerValue := strings.ToLower(value)\n\t\t\t\tok := true\n\n\t\t\t\t// See https://www.typescriptlang.org/tsconfig#target\n\t\t\t\tswitch lowerValue {\n\t\t\t\tcase \"es3\", \"es5\", \"es6\", \"es2015\", \"es2016\", \"es2017\", \"es2018\", \"es2019\", \"es2020\", \"es2021\":\n\t\t\t\t\tresult.Settings.Target = config.TSTargetBelowES2022\n\t\t\t\tcase \"es2022\", \"es2023\", \"es2024\", \"esnext\":\n\t\t\t\t\tresult.Settings.Target = config.TSTargetAtOrAboveES2022\n\t\t\t\tdefault:\n\t\t\t\t\tok = false\n\t\t\t\t\tif !helpers.IsInsideNodeModules(source.KeyPath.Text) {\n\t\t\t\t\t\tlog.AddID(logger.MsgID_TSConfigJSON_InvalidTarget, logger.Warning, &tracker, source.RangeOfString(valueJSON.Loc),\n\t\t\t\t\t\t\tfmt.Sprintf(\"Unrecognized target environment %q\", value))\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ok {\n\t\t\t\t\tresult.tsTargetKey = tsTargetKey{\n\t\t\t\t\t\tSource:     source,\n\t\t\t\t\t\tRange:      source.RangeOfString(keyLoc),\n\t\t\t\t\t\tLowerValue: lowerValue,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Parse \"strict\"\n\t\tif valueJSON, keyLoc, ok := getProperty(compilerOptionsJSON, \"strict\"); ok {\n\t\t\tif value, ok := getBool(valueJSON); ok {\n\t\t\t\tvalueRange := js_lexer.RangeOfIdentifier(source, valueJSON.Loc)\n\t\t\t\tresult.TSStrict = &config.TSAlwaysStrict{\n\t\t\t\t\tName:   \"strict\",\n\t\t\t\t\tValue:  value,\n\t\t\t\t\tSource: source,\n\t\t\t\t\tRange:  logger.Range{Loc: keyLoc, Len: valueRange.End() - keyLoc.Start},\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Parse \"alwaysStrict\"\n\t\tif valueJSON, keyLoc, ok := getProperty(compilerOptionsJSON, \"alwaysStrict\"); ok {\n\t\t\tif value, ok := getBool(valueJSON); ok {\n\t\t\t\tvalueRange := js_lexer.RangeOfIdentifier(source, valueJSON.Loc)\n\t\t\t\tresult.TSAlwaysStrict = &config.TSAlwaysStrict{\n\t\t\t\t\tName:   \"alwaysStrict\",\n\t\t\t\t\tValue:  value,\n\t\t\t\t\tSource: source,\n\t\t\t\t\tRange:  logger.Range{Loc: keyLoc, Len: valueRange.End() - keyLoc.Start},\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Parse \"importsNotUsedAsValues\"\n\t\tif valueJSON, _, ok := getProperty(compilerOptionsJSON, \"importsNotUsedAsValues\"); ok {\n\t\t\tif value, ok := getString(valueJSON); ok {\n\t\t\t\tswitch value {\n\t\t\t\tcase \"remove\":\n\t\t\t\t\tresult.Settings.ImportsNotUsedAsValues = config.TSImportsNotUsedAsValues_Remove\n\t\t\t\tcase \"preserve\":\n\t\t\t\t\tresult.Settings.ImportsNotUsedAsValues = config.TSImportsNotUsedAsValues_Preserve\n\t\t\t\tcase \"error\":\n\t\t\t\t\tresult.Settings.ImportsNotUsedAsValues = config.TSImportsNotUsedAsValues_Error\n\t\t\t\tdefault:\n\t\t\t\t\tlog.AddID(logger.MsgID_TSConfigJSON_InvalidImportsNotUsedAsValues, logger.Warning, &tracker, source.RangeOfString(valueJSON.Loc),\n\t\t\t\t\t\tfmt.Sprintf(\"Invalid value %q for \\\"importsNotUsedAsValues\\\"\", value))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Parse \"preserveValueImports\"\n\t\tif valueJSON, _, ok := getProperty(compilerOptionsJSON, \"preserveValueImports\"); ok {\n\t\t\tif value, ok := getBool(valueJSON); ok {\n\t\t\t\tif value {\n\t\t\t\t\tresult.Settings.PreserveValueImports = config.True\n\t\t\t\t} else {\n\t\t\t\t\tresult.Settings.PreserveValueImports = config.False\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Parse \"verbatimModuleSyntax\"\n\t\tif valueJSON, _, ok := getProperty(compilerOptionsJSON, \"verbatimModuleSyntax\"); ok {\n\t\t\tif value, ok := getBool(valueJSON); ok {\n\t\t\t\tif value {\n\t\t\t\t\tresult.Settings.VerbatimModuleSyntax = config.True\n\t\t\t\t} else {\n\t\t\t\t\tresult.Settings.VerbatimModuleSyntax = config.False\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Parse \"paths\"\n\t\tif valueJSON, _, ok := getProperty(compilerOptionsJSON, \"paths\"); ok {\n\t\t\tif paths, ok := valueJSON.Data.(*js_ast.EObject); ok {\n\t\t\t\tresult.BaseURLForPaths = fileDir\n\t\t\t\tresult.Paths = &TSConfigPaths{Source: source, Map: make(map[string][]TSConfigPath)}\n\t\t\t\tfor _, prop := range paths.Properties {\n\t\t\t\t\tif key, ok := getString(prop.Key); ok {\n\t\t\t\t\t\tif !isValidTSConfigPathPattern(key, log, &source, &tracker, prop.Key.Loc) {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// The \"paths\" field is an object which maps a pattern to an\n\t\t\t\t\t\t// array of remapping patterns to try, in priority order. See\n\t\t\t\t\t\t// the documentation for examples of how this is used:\n\t\t\t\t\t\t// https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// One particular example:\n\t\t\t\t\t\t//\n\t\t\t\t\t\t//   {\n\t\t\t\t\t\t//     \"compilerOptions\": {\n\t\t\t\t\t\t//       \"baseUrl\": \"projectRoot\",\n\t\t\t\t\t\t//       \"paths\": {\n\t\t\t\t\t\t//         \"*\": [\n\t\t\t\t\t\t//           \"*\",\n\t\t\t\t\t\t//           \"generated/*\"\n\t\t\t\t\t\t//         ]\n\t\t\t\t\t\t//       }\n\t\t\t\t\t\t//     }\n\t\t\t\t\t\t//   }\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// Matching \"folder1/file2\" should first check \"projectRoot/folder1/file2\"\n\t\t\t\t\t\t// and then, if that didn't work, also check \"projectRoot/generated/folder1/file2\".\n\t\t\t\t\t\tif array, ok := prop.ValueOrNil.Data.(*js_ast.EArray); ok {\n\t\t\t\t\t\t\tfor _, item := range array.Items {\n\t\t\t\t\t\t\t\tif str, ok := getString(item); ok {\n\t\t\t\t\t\t\t\t\tif isValidTSConfigPathPattern(str, log, &source, &tracker, item.Loc) {\n\t\t\t\t\t\t\t\t\t\tstr = getSubstitutedPathWithConfigDirTemplate(fs, str, configDir)\n\t\t\t\t\t\t\t\t\t\tresult.Paths.Map[key] = append(result.Paths.Map[key], TSConfigPath{Text: str, Loc: item.Loc})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlog.AddID(logger.MsgID_TSConfigJSON_InvalidPaths, logger.Warning, &tracker, source.RangeOfString(prop.ValueOrNil.Loc), fmt.Sprintf(\n\t\t\t\t\t\t\t\t\"Substitutions for pattern %q should be an array\", key))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Warn about compiler options not wrapped in \"compilerOptions\".\n\t// For example: https://github.com/evanw/esbuild/issues/3301\n\tif obj, ok := json.Data.(*js_ast.EObject); ok {\n\tloop:\n\t\tfor _, prop := range obj.Properties {\n\t\t\tif key, ok := prop.Key.Data.(*js_ast.EString); ok && key.Value != nil {\n\t\t\t\tkey := helpers.UTF16ToString(key.Value)\n\t\t\t\tswitch key {\n\t\t\t\tcase \"alwaysStrict\",\n\t\t\t\t\t\"baseUrl\",\n\t\t\t\t\t\"experimentalDecorators\",\n\t\t\t\t\t\"importsNotUsedAsValues\",\n\t\t\t\t\t\"jsx\",\n\t\t\t\t\t\"jsxFactory\",\n\t\t\t\t\t\"jsxFragmentFactory\",\n\t\t\t\t\t\"jsxImportSource\",\n\t\t\t\t\t\"paths\",\n\t\t\t\t\t\"preserveValueImports\",\n\t\t\t\t\t\"strict\",\n\t\t\t\t\t\"target\",\n\t\t\t\t\t\"useDefineForClassFields\",\n\t\t\t\t\t\"verbatimModuleSyntax\":\n\t\t\t\t\tlog.AddIDWithNotes(logger.MsgID_TSConfigJSON_InvalidTopLevelOption, logger.Warning, &tracker, source.RangeOfString(prop.Key.Loc),\n\t\t\t\t\t\tfmt.Sprintf(\"Expected the %q option to be nested inside a \\\"compilerOptions\\\" object\", key),\n\t\t\t\t\t\t[]logger.MsgData{})\n\t\t\t\t\tbreak loop\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &result\n}\n\n// See: https://github.com/microsoft/TypeScript/pull/58042\nfunc getSubstitutedPathWithConfigDirTemplate(fs fs.FS, value string, basePath string) string {\n\tif strings.HasPrefix(value, \"${configDir}\") {\n\t\treturn fs.Join(basePath, \"./\"+value[12:])\n\t}\n\treturn value\n}\n\nfunc parseMemberExpressionForJSX(log logger.Log, source *logger.Source, tracker *logger.LineColumnTracker, loc logger.Loc, text string) []string {\n\tif text == \"\" {\n\t\treturn nil\n\t}\n\tparts := strings.Split(text, \".\")\n\tfor _, part := range parts {\n\t\tif !js_ast.IsIdentifier(part) {\n\t\t\twarnRange := source.RangeOfString(loc)\n\t\t\tlog.AddID(logger.MsgID_TSConfigJSON_InvalidJSX, logger.Warning, tracker, warnRange, fmt.Sprintf(\"Invalid JSX member expression: %q\", text))\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn parts\n}\n\nfunc isValidTSConfigPathPattern(text string, log logger.Log, source *logger.Source, tracker *logger.LineColumnTracker, loc logger.Loc) bool {\n\tfoundAsterisk := false\n\tfor i := 0; i < len(text); i++ {\n\t\tif text[i] == '*' {\n\t\t\tif foundAsterisk {\n\t\t\t\tr := source.RangeOfString(loc)\n\t\t\t\tlog.AddID(logger.MsgID_TSConfigJSON_InvalidPaths, logger.Warning, tracker, r, fmt.Sprintf(\n\t\t\t\t\t\"Invalid pattern %q, must have at most one \\\"*\\\" character\", text))\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfoundAsterisk = true\n\t\t}\n\t}\n\treturn true\n}\n\nfunc isSlash(c byte) bool {\n\treturn c == '/' || c == '\\\\'\n}\n\nfunc isValidTSConfigPathNoBaseURLPattern(text string, log logger.Log, source *logger.Source, tracker **logger.LineColumnTracker, loc logger.Loc) bool {\n\tvar c0 byte\n\tvar c1 byte\n\tvar c2 byte\n\tn := len(text)\n\n\tif n > 0 {\n\t\tc0 = text[0]\n\t\tif n > 1 {\n\t\t\tc1 = text[1]\n\t\t\tif n > 2 {\n\t\t\t\tc2 = text[2]\n\t\t\t}\n\t\t}\n\t}\n\n\t// Relative \".\" or \"..\"\n\tif c0 == '.' && (n == 1 || (n == 2 && c1 == '.')) {\n\t\treturn true\n\t}\n\n\t// Relative \"./\" or \"../\" or \".\\\\\" or \"..\\\\\"\n\tif c0 == '.' && (isSlash(c1) || (c1 == '.' && isSlash(c2))) {\n\t\treturn true\n\t}\n\n\t// Absolute POSIX \"/\" or UNC \"\\\\\"\n\tif isSlash(c0) {\n\t\treturn true\n\t}\n\n\t// Absolute DOS \"c:/\" or \"c:\\\\\"\n\tif ((c0 >= 'a' && c0 <= 'z') || (c0 >= 'A' && c0 <= 'Z')) && c1 == ':' && isSlash(c2) {\n\t\treturn true\n\t}\n\n\tr := source.RangeOfString(loc)\n\tif *tracker == nil {\n\t\tt := logger.MakeLineColumnTracker(source)\n\t\t*tracker = &t\n\t}\n\tlog.AddID(logger.MsgID_TSConfigJSON_InvalidPaths, logger.Warning, *tracker, r, fmt.Sprintf(\n\t\t\"Non-relative path %q is not allowed when \\\"baseUrl\\\" is not set (did you forget a leading \\\"./\\\"?)\", text))\n\treturn false\n}\n"
  },
  {
    "path": "internal/resolver/yarnpnp.go",
    "content": "package resolver\n\n// This file implements the Yarn PnP specification: https://yarnpkg.com/advanced/pnp-spec/\n\nimport (\n\t\"fmt\"\n\t\"path\"\n\t\"regexp\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/js_parser\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\ntype pnpData struct {\n\t// Keys are the package idents, values are sets of references. Combining the\n\t// ident with each individual reference yields the set of affected locators.\n\tfallbackExclusionList map[string]map[string]bool\n\n\t// A map of locators that all packages are allowed to access, regardless\n\t// whether they list them in their dependencies or not.\n\tfallbackPool map[string]pnpIdentAndReference\n\n\t// A nullable regexp. If set, all project-relative importer paths should be\n\t// matched against it. If the match succeeds, the resolution should follow\n\t// the classic Node.js resolution algorithm rather than the Plug'n'Play one.\n\t// Note that unlike other paths in the manifest, the one checked against this\n\t// regexp won't begin by `./`.\n\tignorePatternData        *regexp.Regexp\n\tinvalidIgnorePatternData string\n\n\t// This is the main part of the PnP data file. This table contains the list\n\t// of all packages, first keyed by package ident then by package reference.\n\t// One entry will have `null` in both fields and represents the absolute\n\t// top-level package.\n\tpackageRegistryData map[string]map[string]pnpPackage\n\n\tpackageLocatorsByLocations map[string]pnpPackageLocatorByLocation\n\n\t// If true, should a dependency resolution fail for an importer that isn't\n\t// explicitly listed in `fallbackExclusionList`, the runtime must first check\n\t// whether the resolution would succeed for any of the packages in\n\t// `fallbackPool`; if it would, transparently return this resolution. Note\n\t// that all dependencies from the top-level package are implicitly part of\n\t// the fallback pool, even if not listed here.\n\tenableTopLevelFallback bool\n\n\ttracker    logger.LineColumnTracker\n\tabsPath    string\n\tabsDirPath string\n}\n\n// This is called both a \"locator\" and a \"dependency target\" in the specification.\n// When it's used as a dependency target, it can only be in one of three states:\n//\n//  1. A reference, to link with the dependency name\n//     In this case ident is \"\".\n//\n//  2. An aliased package\n//     In this case neither ident nor reference are \"\".\n//\n//  3. A missing peer dependency\n//     In this case ident and reference are \"\".\ntype pnpIdentAndReference struct {\n\tident     string // Empty if null\n\treference string // Empty if null\n\tspan      logger.Range\n}\n\ntype pnpPackage struct {\n\tpackageDependencies      map[string]pnpIdentAndReference\n\tpackageLocation          string\n\tpackageDependenciesRange logger.Range\n\tdiscardFromLookup        bool\n}\n\ntype pnpPackageLocatorByLocation struct {\n\tlocator           pnpIdentAndReference\n\tdiscardFromLookup bool\n}\n\nfunc parseBareIdentifier(specifier string) (ident string, modulePath string, ok bool) {\n\tslash := strings.IndexByte(specifier, '/')\n\n\t// If specifier starts with \"@\", then\n\tif strings.HasPrefix(specifier, \"@\") {\n\t\t// If specifier doesn't contain a \"/\" separator, then\n\t\tif slash == -1 {\n\t\t\t// Throw an error\n\t\t\treturn\n\t\t}\n\n\t\t// Otherwise,\n\t\t// Set ident to the substring of specifier until the second \"/\" separator or the end of string, whatever happens first\n\t\tif slash2 := strings.IndexByte(specifier[slash+1:], '/'); slash2 != -1 {\n\t\t\tident = specifier[:slash+1+slash2]\n\t\t} else {\n\t\t\tident = specifier\n\t\t}\n\t} else {\n\t\t// Otherwise,\n\t\t// Set ident to the substring of specifier until the first \"/\" separator or the end of string, whatever happens first\n\t\tif slash != -1 {\n\t\t\tident = specifier[:slash]\n\t\t} else {\n\t\t\tident = specifier\n\t\t}\n\t}\n\n\t// Set modulePath to the substring of specifier starting from ident.length\n\tmodulePath = specifier[len(ident):]\n\n\t// Return {ident, modulePath}\n\tok = true\n\treturn\n}\n\ntype pnpStatus uint8\n\nconst (\n\tpnpErrorGeneric pnpStatus = iota\n\tpnpErrorDependencyNotFound\n\tpnpErrorUnfulfilledPeerDependency\n\tpnpSuccess\n\tpnpSkipped\n)\n\nfunc (status pnpStatus) isError() bool {\n\treturn status < pnpSuccess\n}\n\ntype pnpResult struct {\n\tstatus     pnpStatus\n\tpkgDirPath string\n\tpkgIdent   string\n\tpkgSubpath string\n\n\t// This is for error messages\n\terrorIdent string\n\terrorRange logger.Range\n}\n\n// Note: If this returns successfully then the node module resolution algorithm\n// (i.e. NM_RESOLVE in the Yarn PnP specification) is always run afterward\nfunc (r resolverQuery) resolveToUnqualified(specifier string, parentURL string, manifest *pnpData) pnpResult {\n\t// Let resolved be undefined\n\n\t// Let manifest be FIND_PNP_MANIFEST(parentURL)\n\t// (this is already done by the time we get here)\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Using Yarn PnP manifest from %q\", manifest.absPath))\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Resolving %q in %q\", specifier, parentURL))\n\t}\n\n\t// Let ident and modulePath be the result of PARSE_BARE_IDENTIFIER(specifier)\n\tident, modulePath, ok := parseBareIdentifier(specifier)\n\tif !ok {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Failed to parse specifier %q into a bare identifier\", specifier))\n\t\t}\n\t\treturn pnpResult{status: pnpErrorGeneric}\n\t}\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Parsed bare identifier %q and module path %q\", ident, modulePath))\n\t}\n\n\t// Let parentLocator be FIND_LOCATOR(manifest, parentURL)\n\tparentLocator, ok := r.findLocator(manifest, parentURL)\n\n\t// If parentLocator is null, then\n\t// Set resolved to NM_RESOLVE(specifier, parentURL) and return it\n\tif !ok {\n\t\treturn pnpResult{status: pnpSkipped}\n\t}\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Found parent locator: [%s, %s]\", quoteOrNullIfEmpty(parentLocator.ident), quoteOrNullIfEmpty(parentLocator.reference)))\n\t}\n\n\t// Let parentPkg be GET_PACKAGE(manifest, parentLocator)\n\tparentPkg, ok := r.getPackage(manifest, parentLocator.ident, parentLocator.reference)\n\tif !ok {\n\t\t// We aren't supposed to get here according to the Yarn PnP specification\n\t\treturn pnpResult{status: pnpErrorGeneric}\n\t}\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Found parent package at %q\", parentPkg.packageLocation))\n\t}\n\n\t// Let referenceOrAlias be the entry from parentPkg.packageDependencies referenced by ident\n\treferenceOrAlias, ok := parentPkg.packageDependencies[ident]\n\n\t// If referenceOrAlias is null or undefined, then\n\tif !ok || referenceOrAlias.reference == \"\" {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Failed to find %q in \\\"packageDependencies\\\" of parent package\", ident))\n\t\t}\n\n\t\t// If manifest.enableTopLevelFallback is true, then\n\t\tif manifest.enableTopLevelFallback {\n\t\t\tif r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(\"  Searching for a fallback because \\\"enableTopLevelFallback\\\" is true\")\n\t\t\t}\n\n\t\t\t// If parentLocator isn't in manifest.fallbackExclusionList, then\n\t\t\tif set := manifest.fallbackExclusionList[parentLocator.ident]; !set[parentLocator.reference] {\n\t\t\t\t// Let fallback be RESOLVE_VIA_FALLBACK(manifest, ident)\n\t\t\t\tfallback, _ := r.resolveViaFallback(manifest, ident)\n\n\t\t\t\t// If fallback is neither null nor undefined\n\t\t\t\tif fallback.reference != \"\" {\n\t\t\t\t\t// Set referenceOrAlias to fallback\n\t\t\t\t\treferenceOrAlias = fallback\n\t\t\t\t\tok = true\n\t\t\t\t}\n\t\t\t} else if r.debugLogs != nil {\n\t\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"    Stopping because [%s, %s] is in \\\"fallbackExclusionList\\\"\",\n\t\t\t\t\tquoteOrNullIfEmpty(parentLocator.ident), quoteOrNullIfEmpty(parentLocator.reference)))\n\t\t\t}\n\t\t}\n\t}\n\n\t// If referenceOrAlias is still undefined, then\n\tif !ok {\n\t\t// Throw a resolution error\n\t\treturn pnpResult{\n\t\t\tstatus:     pnpErrorDependencyNotFound,\n\t\t\terrorIdent: ident,\n\t\t\terrorRange: parentPkg.packageDependenciesRange,\n\t\t}\n\t}\n\n\t// If referenceOrAlias is still null, then\n\tif referenceOrAlias.reference == \"\" {\n\t\t// Note: It means that parentPkg has an unfulfilled peer dependency on ident\n\t\t// Throw a resolution error\n\t\treturn pnpResult{\n\t\t\tstatus:     pnpErrorUnfulfilledPeerDependency,\n\t\t\terrorIdent: ident,\n\t\t\terrorRange: referenceOrAlias.span,\n\t\t}\n\t}\n\n\tif r.debugLogs != nil {\n\t\tvar referenceOrAliasStr string\n\t\tif referenceOrAlias.ident != \"\" {\n\t\t\treferenceOrAliasStr = fmt.Sprintf(\"[%q, %q]\", referenceOrAlias.ident, referenceOrAlias.reference)\n\t\t} else {\n\t\t\treferenceOrAliasStr = quoteOrNullIfEmpty(referenceOrAlias.reference)\n\t\t}\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Found dependency locator: [%s, %s]\", quoteOrNullIfEmpty(ident), referenceOrAliasStr))\n\t}\n\n\t// Otherwise, if referenceOrAlias is an array, then\n\tvar dependencyPkg pnpPackage\n\tif referenceOrAlias.ident != \"\" {\n\t\t// Let alias be referenceOrAlias\n\t\talias := referenceOrAlias\n\n\t\t// Let dependencyPkg be GET_PACKAGE(manifest, alias)\n\t\tdependencyPkg, ok = r.getPackage(manifest, alias.ident, alias.reference)\n\t\tif !ok {\n\t\t\t// We aren't supposed to get here according to the Yarn PnP specification\n\t\t\treturn pnpResult{status: pnpErrorGeneric}\n\t\t}\n\t} else {\n\t\t// Otherwise,\n\t\t// Let dependencyPkg be GET_PACKAGE(manifest, {ident, reference})\n\t\tdependencyPkg, ok = r.getPackage(manifest, ident, referenceOrAlias.reference)\n\t\tif !ok {\n\t\t\t// We aren't supposed to get here according to the Yarn PnP specification\n\t\t\treturn pnpResult{status: pnpErrorGeneric}\n\t\t}\n\t}\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Found package %q at %q\", ident, dependencyPkg.packageLocation))\n\t}\n\n\t// Return path.resolve(manifest.dirPath, dependencyPkg.packageLocation, modulePath)\n\tabsDirPath := manifest.absDirPath\n\tisWindows := !strings.HasPrefix(absDirPath, \"/\")\n\tif isWindows {\n\t\t// Yarn converts Windows-style paths with volume labels into Unix-style\n\t\t// paths with a \"/\" prefix for the purpose of joining them together here.\n\t\t// So \"C:\\foo\\bar.txt\" becomes \"/C:/foo/bar.txt\". This is very important\n\t\t// because Yarn also stores a single global cache on the \"C:\" drive, many\n\t\t// developers do their work on the \"D:\" drive, and Yarn uses \"../C:\" to\n\t\t// traverse between the \"D:\" drive and the \"C:\" drive. Windows doesn't\n\t\t// allow you to do that (\"D:\\..\" is just \"D:\\\") so without temporarily\n\t\t// swapping to Unix-style paths here, esbuild would otherwise fail in this\n\t\t// case while Yarn itself would succeed.\n\t\tabsDirPath = \"/\" + strings.ReplaceAll(absDirPath, \"\\\\\", \"/\")\n\t}\n\tpkgDirPath := path.Join(absDirPath, dependencyPkg.packageLocation)\n\tif isWindows && strings.HasPrefix(pkgDirPath, \"/\") {\n\t\t// Convert the Unix-style path back into a Windows-style path afterwards\n\t\tpkgDirPath = strings.ReplaceAll(pkgDirPath[1:], \"\\\\\", \"//\")\n\t}\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Resolved %q via Yarn PnP to %q with subpath %q\", specifier, pkgDirPath, modulePath))\n\t}\n\treturn pnpResult{\n\t\tstatus:     pnpSuccess,\n\t\tpkgDirPath: pkgDirPath,\n\t\tpkgIdent:   ident,\n\t\tpkgSubpath: modulePath,\n\t}\n}\n\nfunc (r resolverQuery) findLocator(manifest *pnpData, moduleUrl string) (pnpIdentAndReference, bool) {\n\t// Let relativeUrl be the relative path between manifest and moduleUrl\n\trelativeUrl, ok := r.fs.Rel(manifest.absDirPath, moduleUrl)\n\tif !ok {\n\t\treturn pnpIdentAndReference{}, false\n\t} else {\n\t\t// Relative URLs on Windows will use \\ instead of /, which will break\n\t\t// everything we do below. Use normal slashes to keep things working.\n\t\trelativeUrl = strings.ReplaceAll(relativeUrl, \"\\\\\", \"/\")\n\t}\n\n\t// The relative path must not start with ./; trim it if needed\n\trelativeUrl = strings.TrimPrefix(relativeUrl, \"./\")\n\n\t// If relativeUrl matches manifest.ignorePatternData, then\n\tif manifest.ignorePatternData != nil && manifest.ignorePatternData.MatchString(relativeUrl) {\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Ignoring %q because it matches \\\"ignorePatternData\\\"\", relativeUrl))\n\t\t}\n\n\t\t// Return null\n\t\treturn pnpIdentAndReference{}, false\n\t}\n\n\t// Note: Make sure relativeUrl always starts with a ./ or ../\n\tif !strings.HasSuffix(relativeUrl, \"/\") {\n\t\trelativeUrl += \"/\"\n\t}\n\tif !strings.HasPrefix(relativeUrl, \"./\") && !strings.HasPrefix(relativeUrl, \"../\") {\n\t\trelativeUrl = \"./\" + relativeUrl\n\t}\n\n\t// This is the inner loop from Yarn's PnP resolver implementation. This is\n\t// different from the specification, which contains a hypothetical slow\n\t// algorithm instead. The algorithm from the specification can sometimes\n\t// produce different results from the one used by the implementation, so\n\t// we follow the implementation.\n\tfor {\n\t\tentry, ok := manifest.packageLocatorsByLocations[relativeUrl]\n\t\tif !ok || entry.discardFromLookup {\n\t\t\t// Remove the last path component and try again\n\t\t\trelativeUrl = relativeUrl[:strings.LastIndexByte(relativeUrl[:len(relativeUrl)-1], '/')+1]\n\t\t\tif relativeUrl == \"\" {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\treturn entry.locator, true\n\t}\n\n\treturn pnpIdentAndReference{}, false\n}\n\nfunc (r resolverQuery) resolveViaFallback(manifest *pnpData, ident string) (pnpIdentAndReference, bool) {\n\t// Let topLevelPkg be GET_PACKAGE(manifest, {null, null})\n\ttopLevelPkg, ok := r.getPackage(manifest, \"\", \"\")\n\tif !ok {\n\t\t// We aren't supposed to get here according to the Yarn PnP specification\n\t\treturn pnpIdentAndReference{}, false\n\t}\n\n\t// Let referenceOrAlias be the entry from topLevelPkg.packageDependencies referenced by ident\n\treferenceOrAlias, ok := topLevelPkg.packageDependencies[ident]\n\n\t// If referenceOrAlias is defined, then\n\tif ok {\n\t\t// Return it immediately\n\t\tif r.debugLogs != nil {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"    Found fallback for %q in \\\"packageDependencies\\\" of top-level package: [%s, %s]\", ident,\n\t\t\t\tquoteOrNullIfEmpty(referenceOrAlias.ident), quoteOrNullIfEmpty(referenceOrAlias.reference)))\n\t\t}\n\t\treturn referenceOrAlias, true\n\t}\n\n\t// Otherwise,\n\t// Let referenceOrAlias be the entry from manifest.fallbackPool referenced by ident\n\treferenceOrAlias, ok = manifest.fallbackPool[ident]\n\n\t// Return it immediately, whether it's defined or not\n\tif r.debugLogs != nil {\n\t\tif ok {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"    Found fallback for %q in \\\"fallbackPool\\\": [%s, %s]\", ident,\n\t\t\t\tquoteOrNullIfEmpty(referenceOrAlias.ident), quoteOrNullIfEmpty(referenceOrAlias.reference)))\n\t\t} else {\n\t\t\tr.debugLogs.addNote(fmt.Sprintf(\"    Failed to find fallback for %q in \\\"fallbackPool\\\"\", ident))\n\t\t}\n\t}\n\treturn referenceOrAlias, ok\n}\n\nfunc (r resolverQuery) getPackage(manifest *pnpData, ident string, reference string) (pnpPackage, bool) {\n\tif inner, ok := manifest.packageRegistryData[ident]; ok {\n\t\tif pkg, ok := inner[reference]; ok {\n\t\t\treturn pkg, true\n\t\t}\n\t}\n\n\tif r.debugLogs != nil {\n\t\t// We aren't supposed to get here according to the Yarn PnP specification:\n\t\t// \"Note: pkg cannot be undefined here; all packages referenced in any of the\n\t\t// Plug'n'Play data tables MUST have a corresponding entry inside packageRegistryData.\"\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Yarn PnP invariant violation: GET_PACKAGE failed to find a package: [%s, %s]\",\n\t\t\tquoteOrNullIfEmpty(ident), quoteOrNullIfEmpty(reference)))\n\t}\n\treturn pnpPackage{}, false\n}\n\nfunc quoteOrNullIfEmpty(str string) string {\n\tif str != \"\" {\n\t\treturn fmt.Sprintf(\"%q\", str)\n\t}\n\treturn \"null\"\n}\n\nfunc compileYarnPnPData(absPath string, absDirPath string, json js_ast.Expr, source logger.Source) *pnpData {\n\tdata := pnpData{\n\t\tabsPath:    absPath,\n\t\tabsDirPath: absDirPath,\n\t\ttracker:    logger.MakeLineColumnTracker(&source),\n\t}\n\n\tif value, _, ok := getProperty(json, \"enableTopLevelFallback\"); ok {\n\t\tif enableTopLevelFallback, ok := getBool(value); ok {\n\t\t\tdata.enableTopLevelFallback = enableTopLevelFallback\n\t\t}\n\t}\n\n\tif value, _, ok := getProperty(json, \"fallbackExclusionList\"); ok {\n\t\tif array, ok := value.Data.(*js_ast.EArray); ok {\n\t\t\tdata.fallbackExclusionList = make(map[string]map[string]bool, len(array.Items))\n\n\t\t\tfor _, item := range array.Items {\n\t\t\t\tif tuple, ok := item.Data.(*js_ast.EArray); ok && len(tuple.Items) == 2 {\n\t\t\t\t\tif ident, ok := getStringOrNull(tuple.Items[0]); ok {\n\t\t\t\t\t\tif array2, ok := tuple.Items[1].Data.(*js_ast.EArray); ok {\n\t\t\t\t\t\t\treferences := make(map[string]bool, len(array2.Items))\n\n\t\t\t\t\t\t\tfor _, item2 := range array2.Items {\n\t\t\t\t\t\t\t\tif reference, ok := getString(item2); ok {\n\t\t\t\t\t\t\t\t\treferences[reference] = true\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tdata.fallbackExclusionList[ident] = references\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif value, _, ok := getProperty(json, \"fallbackPool\"); ok {\n\t\tif array, ok := value.Data.(*js_ast.EArray); ok {\n\t\t\tdata.fallbackPool = make(map[string]pnpIdentAndReference, len(array.Items))\n\n\t\t\tfor _, item := range array.Items {\n\t\t\t\tif array2, ok := item.Data.(*js_ast.EArray); ok && len(array2.Items) == 2 {\n\t\t\t\t\tif ident, ok := getString(array2.Items[0]); ok {\n\t\t\t\t\t\tif dependencyTarget, ok := getDependencyTarget(array2.Items[1]); ok {\n\t\t\t\t\t\t\tdata.fallbackPool[ident] = dependencyTarget\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif value, _, ok := getProperty(json, \"ignorePatternData\"); ok {\n\t\tif ignorePatternData, ok := getString(value); ok {\n\t\t\t// The Go regular expression engine doesn't support some of the features\n\t\t\t// that JavaScript regular expressions support, including \"(?!\" negative\n\t\t\t// lookaheads which Yarn uses. This is deliberate on Go's part. See this:\n\t\t\t// https://github.com/golang/go/issues/18868.\n\t\t\t//\n\t\t\t// Yarn uses this feature to exclude the \".\" and \"..\" path segments in\n\t\t\t// the middle of a relative path. However, we shouldn't ever generate\n\t\t\t// such path segments in the first place. So as a hack, we just remove\n\t\t\t// the specific character sequences used by Yarn for this so that the\n\t\t\t// regular expression is more likely to be able to be compiled.\n\t\t\tignorePatternData = strings.ReplaceAll(ignorePatternData, `(?!\\.)`, \"\")\n\t\t\tignorePatternData = strings.ReplaceAll(ignorePatternData, `(?!(?:^|\\/)\\.)`, \"\")\n\t\t\tignorePatternData = strings.ReplaceAll(ignorePatternData, `(?!\\.{1,2}(?:\\/|$))`, \"\")\n\t\t\tignorePatternData = strings.ReplaceAll(ignorePatternData, `(?!(?:^|\\/)\\.{1,2}(?:\\/|$))`, \"\")\n\n\t\t\tif reg, err := regexp.Compile(ignorePatternData); err == nil {\n\t\t\t\tdata.ignorePatternData = reg\n\t\t\t} else {\n\t\t\t\tdata.invalidIgnorePatternData = ignorePatternData\n\t\t\t}\n\t\t}\n\t}\n\n\tif value, _, ok := getProperty(json, \"packageRegistryData\"); ok {\n\t\tif array, ok := value.Data.(*js_ast.EArray); ok {\n\t\t\tdata.packageRegistryData = make(map[string]map[string]pnpPackage, len(array.Items))\n\t\t\tdata.packageLocatorsByLocations = make(map[string]pnpPackageLocatorByLocation)\n\n\t\t\tfor _, item := range array.Items {\n\t\t\t\tif tuple, ok := item.Data.(*js_ast.EArray); ok && len(tuple.Items) == 2 {\n\t\t\t\t\tif packageIdent, ok := getStringOrNull(tuple.Items[0]); ok {\n\t\t\t\t\t\tif array2, ok := tuple.Items[1].Data.(*js_ast.EArray); ok {\n\t\t\t\t\t\t\treferences := make(map[string]pnpPackage, len(array2.Items))\n\t\t\t\t\t\t\tdata.packageRegistryData[packageIdent] = references\n\n\t\t\t\t\t\t\tfor _, item2 := range array2.Items {\n\t\t\t\t\t\t\t\tif tuple2, ok := item2.Data.(*js_ast.EArray); ok && len(tuple2.Items) == 2 {\n\t\t\t\t\t\t\t\t\tif packageReference, ok := getStringOrNull(tuple2.Items[0]); ok {\n\t\t\t\t\t\t\t\t\t\tpkg := tuple2.Items[1]\n\n\t\t\t\t\t\t\t\t\t\tif packageLocation, _, ok := getProperty(pkg, \"packageLocation\"); ok {\n\t\t\t\t\t\t\t\t\t\t\tif packageDependencies, _, ok := getProperty(pkg, \"packageDependencies\"); ok {\n\t\t\t\t\t\t\t\t\t\t\t\tif packageLocation, ok := getString(packageLocation); ok {\n\t\t\t\t\t\t\t\t\t\t\t\t\tif array3, ok := packageDependencies.Data.(*js_ast.EArray); ok {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdeps := make(map[string]pnpIdentAndReference, len(array3.Items))\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdiscardFromLookup := false\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tfor _, dep := range array3.Items {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif array4, ok := dep.Data.(*js_ast.EArray); ok && len(array4.Items) == 2 {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif ident, ok := getString(array4.Items[0]); ok {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif dependencyTarget, ok := getDependencyTarget(array4.Items[1]); ok {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdeps[ident] = dependencyTarget\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tif value, _, ok := getProperty(pkg, \"discardFromLookup\"); ok {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif value, ok := getBool(value); ok {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdiscardFromLookup = value\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\treferences[packageReference] = pnpPackage{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tpackageLocation:     packageLocation,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tpackageDependencies: deps,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tpackageDependenciesRange: logger.Range{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tLoc: packageDependencies.Loc,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tLen: array3.CloseBracketLoc.Start + 1 - packageDependencies.Loc.Start,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdiscardFromLookup: discardFromLookup,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// This is what Yarn's PnP implementation does (specifically in\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// \"hydrateRuntimeState\"), so we replicate that behavior here:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tif entry, ok := data.packageLocatorsByLocations[packageLocation]; !ok {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.packageLocatorsByLocations[packageLocation] = pnpPackageLocatorByLocation{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tlocator:           pnpIdentAndReference{ident: packageIdent, reference: packageReference},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdiscardFromLookup: discardFromLookup,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tentry.discardFromLookup = entry.discardFromLookup && discardFromLookup\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif !discardFromLookup {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tentry.locator = pnpIdentAndReference{ident: packageIdent, reference: packageReference}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata.packageLocatorsByLocations[packageLocation] = entry\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &data\n}\n\nfunc getStringOrNull(json js_ast.Expr) (string, bool) {\n\tswitch value := json.Data.(type) {\n\tcase *js_ast.EString:\n\t\treturn helpers.UTF16ToString(value.Value), true\n\n\tcase *js_ast.ENull:\n\t\treturn \"\", true\n\t}\n\n\treturn \"\", false\n}\n\nfunc getDependencyTarget(json js_ast.Expr) (pnpIdentAndReference, bool) {\n\tswitch d := json.Data.(type) {\n\tcase *js_ast.ENull:\n\t\treturn pnpIdentAndReference{span: logger.Range{Loc: json.Loc, Len: 4}}, true\n\n\tcase *js_ast.EString:\n\t\treturn pnpIdentAndReference{reference: helpers.UTF16ToString(d.Value), span: logger.Range{Loc: json.Loc}}, true\n\n\tcase *js_ast.EArray:\n\t\tif len(d.Items) == 2 {\n\t\t\tif name, ok := getString(d.Items[0]); ok {\n\t\t\t\tif reference, ok := getString(d.Items[1]); ok {\n\t\t\t\t\treturn pnpIdentAndReference{\n\t\t\t\t\t\tident:     name,\n\t\t\t\t\t\treference: reference,\n\t\t\t\t\t\tspan:      logger.Range{Loc: json.Loc, Len: d.CloseBracketLoc.Start + 1 - json.Loc.Start},\n\t\t\t\t\t}, true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn pnpIdentAndReference{}, false\n}\n\ntype pnpDataMode uint8\n\nconst (\n\tpnpIgnoreErrorsAboutMissingFiles pnpDataMode = iota\n\tpnpReportErrorsAboutMissingFiles\n)\n\nfunc (r resolverQuery) extractYarnPnPDataFromJSON(pnpDataPath string, mode pnpDataMode) (result js_ast.Expr, source logger.Source) {\n\tcontents, err, originalError := r.caches.FSCache.ReadFile(r.fs, pnpDataPath)\n\tif r.debugLogs != nil && originalError != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Failed to read file %q: %s\", pnpDataPath, originalError.Error()))\n\t}\n\tif err != nil {\n\t\tif mode == pnpReportErrorsAboutMissingFiles || err != syscall.ENOENT {\n\t\t\tprettyPaths := MakePrettyPaths(r.fs, logger.Path{Text: pnpDataPath, Namespace: \"file\"})\n\t\t\tr.log.AddError(nil, logger.Range{}, fmt.Sprintf(\"Cannot read file %q: %s\",\n\t\t\t\tprettyPaths.Select(r.options.LogPathStyle), err.Error()))\n\t\t}\n\t\treturn\n\t}\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"The file %q exists\", pnpDataPath))\n\t}\n\tkeyPath := logger.Path{Text: pnpDataPath, Namespace: \"file\"}\n\tsource = logger.Source{\n\t\tKeyPath:     keyPath,\n\t\tPrettyPaths: MakePrettyPaths(r.fs, keyPath),\n\t\tContents:    contents,\n\t}\n\tresult, _ = r.caches.JSONCache.Parse(r.log, source, js_parser.JSONOptions{})\n\treturn\n}\n\nfunc (r resolverQuery) tryToExtractYarnPnPDataFromJS(pnpDataPath string, mode pnpDataMode) (result js_ast.Expr, source logger.Source) {\n\tcontents, err, originalError := r.caches.FSCache.ReadFile(r.fs, pnpDataPath)\n\tif r.debugLogs != nil && originalError != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"Failed to read file %q: %s\", pnpDataPath, originalError.Error()))\n\t}\n\tif err != nil {\n\t\tif mode == pnpReportErrorsAboutMissingFiles || err != syscall.ENOENT {\n\t\t\tprettyPaths := MakePrettyPaths(r.fs, logger.Path{Text: pnpDataPath, Namespace: \"file\"})\n\t\t\tr.log.AddError(nil, logger.Range{}, fmt.Sprintf(\"Cannot read file %q: %s\",\n\t\t\t\tprettyPaths.Select(r.options.LogPathStyle), err.Error()))\n\t\t}\n\t\treturn\n\t}\n\tif r.debugLogs != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"The file %q exists\", pnpDataPath))\n\t}\n\n\tkeyPath := logger.Path{Text: pnpDataPath, Namespace: \"file\"}\n\tsource = logger.Source{\n\t\tKeyPath:     keyPath,\n\t\tPrettyPaths: MakePrettyPaths(r.fs, keyPath),\n\t\tContents:    contents,\n\t}\n\tast, _ := r.caches.JSCache.Parse(r.log, source, js_parser.OptionsForYarnPnP())\n\n\tif r.debugLogs != nil && ast.ManifestForYarnPnP.Data != nil {\n\t\tr.debugLogs.addNote(fmt.Sprintf(\"  Extracted JSON data from %q\", pnpDataPath))\n\t}\n\treturn ast.ManifestForYarnPnP, source\n}\n"
  },
  {
    "path": "internal/resolver/yarnpnp_test.go",
    "content": "package resolver\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/fs\"\n\t\"github.com/evanw/esbuild/internal/js_parser\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/test\"\n)\n\ntype pnpTestExpectation struct {\n\tManifest interface{}\n\tTests    []pnpTest\n}\n\ntype pnpTest struct {\n\tIt       string\n\tImported string\n\tImporter string\n\tExpected string\n}\n\nfunc TestYarnPnP(t *testing.T) {\n\tt.Helper()\n\tcontents, err := ioutil.ReadFile(\"testExpectations.json\")\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to read testExpectations.json: %s\", err.Error())\n\t}\n\n\tvar expectations []pnpTestExpectation\n\terr = json.Unmarshal(contents, &expectations)\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to parse testExpectations.json: %s\", err.Error())\n\t}\n\n\tfor i, expectation := range expectations {\n\t\tpath := fmt.Sprintf(\"testExpectations[%d].manifest\", i)\n\t\tcontents, err := json.Marshal(expectation.Manifest)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"Failed to generate JSON: %s\", err.Error())\n\t\t}\n\n\t\tsource := logger.Source{\n\t\t\tKeyPath:     logger.Path{Text: path},\n\t\t\tPrettyPaths: logger.PrettyPaths{Abs: path, Rel: path},\n\t\t\tContents:    string(contents),\n\t\t}\n\t\ttempLog := logger.NewDeferLog(logger.DeferLogAll, nil)\n\t\texpr, ok := js_parser.ParseJSON(tempLog, source, js_parser.JSONOptions{})\n\t\tif !ok {\n\t\t\tt.Fatalf(\"Failed to re-parse JSON: %s\", path)\n\t\t}\n\n\t\tmsgs := tempLog.Done()\n\t\tif len(msgs) != 0 {\n\t\t\tt.Fatalf(\"Log not empty after re-parsing JSON: %s\", path)\n\t\t}\n\n\t\tmanifest := compileYarnPnPData(path, \"/path/to/project/\", expr, source)\n\n\t\tfor _, current := range expectation.Tests {\n\t\t\tfunc(current pnpTest) {\n\t\t\t\tt.Run(current.It, func(t *testing.T) {\n\t\t\t\t\tfs := fs.MockFS(nil, fs.MockUnix, \"/\")\n\t\t\t\t\tr := resolverQuery{Resolver: NewResolver(config.BuildCall, fs, logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil), nil, &config.Options{})}\n\t\t\t\t\tresult := r.resolveToUnqualified(current.Imported, current.Importer, manifest)\n\n\t\t\t\t\tvar observed string\n\t\t\t\t\tswitch result.status {\n\t\t\t\t\tcase pnpSuccess:\n\t\t\t\t\t\tobserved = fs.Join(result.pkgDirPath, result.pkgSubpath)\n\t\t\t\t\tcase pnpSkipped:\n\t\t\t\t\t\tobserved = current.Imported\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tobserved = \"error!\"\n\t\t\t\t\t}\n\n\t\t\t\t\t// If a we aren't going through PnP, then we should just run the\n\t\t\t\t\t// normal node module resolution rules instead of throwing an error.\n\t\t\t\t\t// However, this test requires us to throw an error, which seems\n\t\t\t\t\t// incorrect. So we change the expected value of the test instead.\n\t\t\t\t\texpected := current.Expected\n\t\t\t\t\tif current.It == `shouldn't go through PnP when trying to resolve dependencies from packages covered by ignorePatternData` {\n\t\t\t\t\t\texpected = current.Imported\n\t\t\t\t\t} else if observed != \"error!\" && !strings.HasSuffix(observed, \"/\") {\n\t\t\t\t\t\t// This is important for matching Yarn PnP's expectations in tests,\n\t\t\t\t\t\t// but it's important for esbuild that the slash isn't present.\n\t\t\t\t\t\t// Otherwise esbuild's implementation of node module resolution\n\t\t\t\t\t\t// (which runs after Yarn PnP resolution) will fail. Specifically\n\t\t\t\t\t\t// \"foo/\" will look for \"foo/foo.js\" instead of \"foo/index.js\".\n\t\t\t\t\t\tobserved += \"/\"\n\t\t\t\t\t}\n\n\t\t\t\t\ttest.AssertEqualWithDiff(t, observed, expected)\n\t\t\t\t})\n\t\t\t}(current)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "internal/runtime/runtime.go",
    "content": "package runtime\n\n// This is esbuild's runtime code. It contains helper functions that are\n// automatically injected into output files to implement certain features. For\n// example, the \"**\" operator is replaced with a call to \"__pow\" when targeting\n// ES2015. Tree shaking automatically removes unused code from the runtime.\n\nimport (\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\n// The runtime source is always at a special index. The index is always zero\n// but this constant is always used instead to improve readability and ensure\n// all code that references this index can be discovered easily.\nconst SourceIndex = uint32(0)\n\nfunc Source(unsupportedJSFeatures compat.JSFeature) logger.Source {\n\t// Note: These helper functions used to be named similar things to the helper\n\t// functions from the TypeScript compiler. However, people sometimes use these\n\t// two projects in combination and TypeScript's implementation of these helpers\n\t// causes name collisions. Some examples:\n\t//\n\t// * The \"tslib\" library will overwrite esbuild's helper functions if the bundled\n\t//   code is run in the global scope: https://github.com/evanw/esbuild/issues/1102\n\t//\n\t// * Running the TypeScript compiler on esbuild's output to convert ES6 to ES5\n\t//   will also overwrite esbuild's helper functions because TypeScript doesn't\n\t//   change the names of its helper functions to avoid name collisions:\n\t//   https://github.com/microsoft/TypeScript/issues/43296\n\t//\n\t// These can both be considered bugs in TypeScript. However, they are unlikely\n\t// to be fixed and it's simplest to just avoid using the same names to avoid\n\t// these bugs. Forbidden names (from \"tslib\"):\n\t//\n\t//   __assign\n\t//   __asyncDelegator\n\t//   __asyncGenerator\n\t//   __asyncValues\n\t//   __await\n\t//   __awaiter\n\t//   __classPrivateFieldGet\n\t//   __classPrivateFieldSet\n\t//   __createBinding\n\t//   __decorate\n\t//   __exportStar\n\t//   __extends\n\t//   __generator\n\t//   __importDefault\n\t//   __importStar\n\t//   __makeTemplateObject\n\t//   __metadata\n\t//   __param\n\t//   __read\n\t//   __rest\n\t//   __spread\n\t//   __spreadArray\n\t//   __spreadArrays\n\t//   __values\n\t//\n\t// Note: The \"__objRest\" function has a for-of loop which requires ES6, but\n\t// transforming destructuring to ES5 isn't even supported so it's ok.\n\ttext := `\n\t\tvar __create = Object.create\n\t\tvar __freeze = Object.freeze\n\t\tvar __defProp = Object.defineProperty\n\t\tvar __defProps = Object.defineProperties\n\t\tvar __getOwnPropDesc = Object.getOwnPropertyDescriptor // Note: can return \"undefined\" due to a Safari bug\n\t\tvar __getOwnPropDescs = Object.getOwnPropertyDescriptors\n\t\tvar __getOwnPropNames = Object.getOwnPropertyNames\n\t\tvar __getOwnPropSymbols = Object.getOwnPropertySymbols\n\t\tvar __getProtoOf = Object.getPrototypeOf\n\t\tvar __hasOwnProp = Object.prototype.hasOwnProperty\n\t\tvar __propIsEnum = Object.prototype.propertyIsEnumerable\n\t\tvar __reflectGet = Reflect.get\n\t\tvar __reflectSet = Reflect.set\n\n\t\tvar __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for('Symbol.' + name)\n\t\tvar __typeError = msg => { throw TypeError(msg) }\n\n\t\texport var __pow = Math.pow\n\n\t\tvar __defNormalProp = (obj, key, value) => key in obj\n\t\t\t? __defProp(obj, key, {enumerable: true, configurable: true, writable: true, value})\n\t\t\t: obj[key] = value\n\n\t\texport var __spreadValues = (a, b) => {\n\t\t\tfor (var prop in b ||= {})\n\t\t\t\tif (__hasOwnProp.call(b, prop))\n\t\t\t\t\t__defNormalProp(a, prop, b[prop])\n\t\t\tif (__getOwnPropSymbols)\n\t\t`\n\n\t// Avoid \"of\" when not using ES6\n\tif !unsupportedJSFeatures.Has(compat.ForOf) {\n\t\ttext += `\n\t\t\t\tfor (var prop of __getOwnPropSymbols(b)) {\n\t\t`\n\t} else {\n\t\ttext += `\n\t\t\t\tfor (var props = __getOwnPropSymbols(b), i = 0, n = props.length, prop; i < n; i++) {\n\t\t\t\t\tprop = props[i]\n\t\t`\n\t}\n\n\ttext += `\n\t\t\t\t\tif (__propIsEnum.call(b, prop))\n\t\t\t\t\t\t__defNormalProp(a, prop, b[prop])\n\t\t\t\t}\n\t\t\treturn a\n\t\t}\n\t\texport var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b))\n\n\t\t// Update the \"name\" property on the function or class for \"--keep-names\"\n\t\texport var __name = (target, value) => __defProp(target, 'name', { value, configurable: true })\n\n\t\t// This fallback \"require\" function exists so that \"typeof require\" can\n\t\t// naturally be \"function\" even in non-CommonJS environments since esbuild\n\t\t// emulates a CommonJS environment (issue #1202). However, people want this\n\t\t// shim to fall back to \"globalThis.require\" even if it's defined later\n\t\t// (including property accesses such as \"require.resolve\") so we need to\n\t\t// use a proxy (issue #1614).\n\t\texport var __require =\n\t\t\t/* @__PURE__ */ (x =>\n\t\t\t\ttypeof require !== 'undefined' ? require :\n\t\t\t\ttypeof Proxy !== 'undefined' ? new Proxy(x, {\n\t\t\t\t\tget: (a, b) => (typeof require !== 'undefined' ? require : a)[b]\n\t\t\t\t}) : x\n\t\t\t)(function(x) {\n\t\t\t\tif (typeof require !== 'undefined') return require.apply(this, arguments)\n\t\t\t\tthrow Error('Dynamic require of \"' + x + '\" is not supported')\n\t\t\t})\n\n\t\t// This is used for glob imports\n\t\texport var __glob = map => path => {\n\t\t\tvar fn = map[path]\n\t\t\tif (fn) return fn()\n\t\t\tthrow new Error('Module not found in bundle: ' + path)\n\t\t}\n\n\t\t// For object rest patterns\n\t\texport var __restKey = key => typeof key === 'symbol' ? key : key + ''\n\t\texport var __objRest = (source, exclude) => {\n\t\t\tvar target = {}\n\t\t\tfor (var prop in source)\n\t\t\t\tif (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)\n\t\t\t\t\ttarget[prop] = source[prop]\n\t\t\tif (source != null && __getOwnPropSymbols)\n\t`\n\n\t// Avoid \"of\" when not using ES6\n\tif !unsupportedJSFeatures.Has(compat.ForOf) {\n\t\ttext += `\n\t\t\t\tfor (var prop of __getOwnPropSymbols(source)) {\n\t\t`\n\t} else {\n\t\ttext += `\n\t\t\t\tfor (var props = __getOwnPropSymbols(source), i = 0, n = props.length, prop; i < n; i++) {\n\t\t\t\t\tprop = props[i]\n\t\t`\n\t}\n\n\ttext += `\n\t\t\t\t\tif (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))\n\t\t\t\t\t\ttarget[prop] = source[prop]\n\t\t\t\t}\n\t\t\treturn target\n\t\t}\n\n\t\t// This is for lazily-initialized ESM code. This has two implementations, a\n\t\t// compact one for minified code and a verbose one that generates friendly\n\t\t// names in V8's profiler and in stack traces.\n\t\texport var __esm = (fn, res) => function __init() {\n\t\t\treturn fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res\n\t\t}\n\t\texport var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res)\n\n\t\t// Wraps a CommonJS closure and returns a require() function. This has two\n\t\t// implementations, a compact one for minified code and a verbose one that\n\t\t// generates friendly names in V8's profiler and in stack traces.\n\t\texport var __commonJS = (cb, mod) => function __require() {\n\t\t\treturn mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = {exports: {}}).exports, mod), mod.exports\n\t\t}\n\t\texport var __commonJSMin = (cb, mod) => () => (mod || cb((mod = {exports: {}}).exports, mod), mod.exports)\n\n\t\t// Used to implement ESM exports both for \"require()\" and \"import * as\"\n\t\texport var __export = (target, all) => {\n\t\t\tfor (var name in all)\n\t\t\t\t__defProp(target, name, { get: all[name], enumerable: true })\n\t\t}\n\n\t\tvar __copyProps = (to, from, except, desc) => {\n\t\t\tif (from && typeof from === 'object' || typeof from === 'function')\n\t`\n\n\t// Avoid \"let\" when not using ES6\n\tif !unsupportedJSFeatures.Has(compat.ForOf) && !unsupportedJSFeatures.Has(compat.ConstAndLet) {\n\t\ttext += `\n\t\t\t\tfor (let key of __getOwnPropNames(from))\n\t\t\t\t\tif (!__hasOwnProp.call(to, key) && key !== except)\n\t\t\t\t\t\t__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable })\n\t\t`\n\t} else {\n\t\ttext += `\n\t\t\t\tfor (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {\n\t\t\t\t\tkey = keys[i]\n\t\t\t\t\tif (!__hasOwnProp.call(to, key) && key !== except)\n\t\t\t\t\t\t__defProp(to, key, { get: (k => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable })\n\t\t\t\t}\n\t\t`\n\t}\n\n\ttext += `\n\t\t\treturn to\n\t\t}\n\n\t\t// This is used to implement \"export * from\" statements. It copies properties\n\t\t// from the imported module to the current module's ESM export object. If the\n\t\t// current module is an entry point and the target format is CommonJS, we\n\t\t// also copy the properties to \"module.exports\" in addition to our module's\n\t\t// internal ESM export object.\n\t\texport var __reExport = (target, mod, secondTarget) => (\n\t\t\t__copyProps(target, mod, 'default'),\n\t\t\tsecondTarget && __copyProps(secondTarget, mod, 'default')\n\t\t)\n\n\t\t// Converts the module from CommonJS to ESM. When in node mode (i.e. in an\n\t\t// \".mjs\" file, package.json has \"type: module\", or the \"__esModule\" export\n\t\t// in the CommonJS file is falsy or missing), the \"default\" property is\n\t\t// overridden to point to the original CommonJS exports object instead.\n\t\texport var __toESM = (mod, isNodeMode, target) => (\n\t\t\ttarget = mod != null ? __create(__getProtoOf(mod)) : {},\n\t\t\t__copyProps(\n\t\t\t\t// If the importer is in node compatibility mode or this is not an ESM\n\t\t\t\t// file that has been converted to a CommonJS file using a Babel-\n\t\t\t\t// compatible transform (i.e. \"__esModule\" has not been set), then set\n\t\t\t\t// \"default\" to the CommonJS \"module.exports\" for node compatibility.\n\t\t\t\tisNodeMode || !mod || !mod.__esModule\n\t\t\t\t\t? __defProp(target, 'default', { value: mod, enumerable: true })\n\t\t\t\t\t: target,\n\t\t\t\tmod)\n\t\t)\n\n\t\t// Converts the module from ESM to CommonJS. This clones the input module\n\t\t// object with the addition of a non-enumerable \"__esModule\" property set\n\t\t// to \"true\", which overwrites any existing export named \"__esModule\".\n\t\texport var __toCommonJS = mod => __copyProps(__defProp({}, '__esModule', { value: true }), mod)\n\n\t\t// For TypeScript experimental decorators\n\t\t// - kind === undefined: class\n\t\t// - kind === 1: method, parameter\n\t\t// - kind === 2: field\n\t\texport var __decorateClass = (decorators, target, key, kind) => {\n\t\t\tvar result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target\n\t\t\tfor (var i = decorators.length - 1, decorator; i >= 0; i--)\n\t\t\t\tif (decorator = decorators[i])\n\t\t\t\t\tresult = (kind ? decorator(target, key, result) : decorator(result)) || result\n\t\t\tif (kind && result) __defProp(target, key, result)\n\t\t\treturn result\n\t\t}\n\t\texport var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index)\n\n\t\t// For JavaScript decorators\n\t\texport var __decoratorStart = base => [, , , __create(base?.[__knownSymbol('metadata')] ?? null)]\n\t\tvar __decoratorStrings = ['class', 'method', 'getter', 'setter', 'accessor', 'field', 'value', 'get', 'set']\n\t\tvar __expectFn = fn => fn !== void 0 && typeof fn !== 'function' ? __typeError('Function expected') : fn\n\t\tvar __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: fn =>\n\t\t\tdone._ ? __typeError('Already initialized') : fns.push(__expectFn(fn || null)) })\n\t\texport var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol('metadata'), array[3])\n\t\texport var __runInitializers = (array, flags, self, value) => {\n\t\t\tfor (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value)\n\t\t\treturn value\n\t\t}\n\t\texport var __decorateElement = (array, flags, name, decorators, target, extra) => {\n\t\t\tvar fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16)\n\t\t\tvar j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings[k + 5]\n\t\t\tvar initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = [])\n\t\t\tvar desc = k && (\n\t\t\t\t!p && !s && (target = target.prototype),\n\t\t\t\tk < 5 && (k > 3 || !p) &&\n\t\t\t`\n\n\t// Avoid object extensions when not using ES6\n\tif !unsupportedJSFeatures.Has(compat.ObjectExtensions) && !unsupportedJSFeatures.Has(compat.ObjectAccessors) {\n\t\ttext += `__getOwnPropDesc(k < 4 ? target : { get [name]() { return __privateGet(this, extra) }, set [name](x) { return __privateSet(this, extra, x) } }, name)`\n\t} else {\n\t\ttext += `(k < 4 ? __getOwnPropDesc(target, name) : { get: () => __privateGet(this, extra), set: x => __privateSet(this, extra, x) })`\n\t}\n\n\ttext += `\n\t\t\t)\n\t\t\tk ? p && k < 4 && __name(extra, (k > 2 ? 'set ' : k > 1 ? 'get ' : '') + name) : __name(target, name)\n\n\t\t\tfor (var i = decorators.length - 1; i >= 0; i--) {\n\t\t\t\tctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers)\n\n\t\t\t\tif (k) {\n\t\t\t\t\tctx.static = s, ctx.private = p, access = ctx.access = { has: p ? x => __privateIn(target, x) : x => name in x }\n\t\t\t\t\tif (k ^ 3) access.get = p ? x => (k ^ 1 ? __privateGet : __privateMethod)(x, target, k ^ 4 ? extra : desc.get) : x => x[name]\n\t\t\t\t\tif (k > 2) access.set = p ? (x, y) => __privateSet(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y\n\t\t\t\t}\n\n\t\t\t\tit = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key] : k > 4 ? void 0 : { get: desc.get, set: desc.set } : target, ctx), done._ = 1\n\n\t\t\t\tif (k ^ 4 || it === void 0) __expectFn(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it)\n\t\t\t\telse if (typeof it !== 'object' || it === null) __typeError('Object expected')\n\t\t\t\telse __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn)\n\t\t\t}\n\n\t\t\treturn k || __decoratorMetadata(array, target),\n\t\t\t\tdesc && __defProp(target, name, desc),\n\t\t\t\tp ? k ^ 4 ? extra : desc : target\n\t\t}\n\n\t\t// For class members\n\t\texport var __publicField = (obj, key, value) => (\n\t\t\t__defNormalProp(obj, typeof key !== 'symbol' ? key + '' : key, value)\n\t\t)\n\t\tvar __accessCheck = (obj, member, msg) => (\n\t\t\tmember.has(obj) || __typeError('Cannot ' + msg)\n\t\t)\n\t\texport var __privateIn = (member, obj) => (\n\t\t\tObject(obj) !== obj ? __typeError('Cannot use the \"in\" operator on this value') :\n\t\t\tmember.has(obj)\n\t\t)\n\t\texport var __privateGet = (obj, member, getter) => (\n\t\t\t__accessCheck(obj, member, 'read from private field'),\n\t\t\tgetter ? getter.call(obj) : member.get(obj)\n\t\t)\n\t\texport var __privateAdd = (obj, member, value) => (\n\t\t\tmember.has(obj) ? __typeError('Cannot add the same private member more than once') :\n\t\t\tmember instanceof WeakSet ? member.add(obj) : member.set(obj, value)\n\t\t)\n\t\texport var __privateSet = (obj, member, value, setter) => (\n\t\t\t__accessCheck(obj, member, 'write to private field'),\n\t\t\tsetter ? setter.call(obj, value) : member.set(obj, value),\n\t\t\tvalue\n\t\t)\n\t\texport var __privateMethod = (obj, member, method) => (\n\t\t\t__accessCheck(obj, member, 'access private method'),\n\t\t\tmethod\n\t\t)\n\t\texport var __earlyAccess = (name) => {\n\t\t\tthrow ReferenceError('Cannot access \"' + name + '\" before initialization')\n\t\t}\n\t`\n\n\tif !unsupportedJSFeatures.Has(compat.ObjectAccessors) {\n\t\ttext += `\n\t\t\texport var __privateWrapper = (obj, member, setter, getter) => ({\n\t\t\t\tset _(value) { __privateSet(obj, member, value, setter) },\n\t\t\t\tget _() { return __privateGet(obj, member, getter) },\n\t\t\t})\n\t\t`\n\t} else {\n\t\ttext += `\n\t\texport var __privateWrapper = (obj, member, setter, getter) => __defProp({}, '_', {\n\t\t\tset: value => __privateSet(obj, member, value, setter),\n\t\t\tget: () => __privateGet(obj, member, getter),\n\t\t})\n\t\t`\n\t}\n\n\ttext += `\n\t\t// For \"super\" property accesses\n\t\texport var __superGet = (cls, obj, key) => __reflectGet(__getProtoOf(cls), key, obj)\n\t\texport var __superSet = (cls, obj, key, val) => (__reflectSet(__getProtoOf(cls), key, val, obj), val)\n\t`\n\n\tif !unsupportedJSFeatures.Has(compat.ObjectAccessors) {\n\t\ttext += `\n\t\t\texport var __superWrapper = (cls, obj, key) => ({\n\t\t\t\tget _() { return __superGet(cls, obj, key) },\n\t\t\t\tset _(val) { __superSet(cls, obj, key, val) },\n\t\t\t})\n\t\t`\n\t} else {\n\t\ttext += `\n\t\t\texport var __superWrapper = (cls, obj, key) => __defProp({}, '_', {\n\t\t\t\tget: () => __superGet(cls, obj, key),\n\t\t\t\tset: val => __superSet(cls, obj, key, val),\n\t\t\t})\n\t\t`\n\t}\n\n\ttext += `\n\t\t// For lowering tagged template literals\n\t\texport var __template = (cooked, raw) => __freeze(__defProp(cooked, 'raw', { value: __freeze(raw || cooked.slice()) }))\n\n\t\t// This helps for lowering async functions\n\t\texport var __async = (__this, __arguments, generator) => {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tvar fulfilled = value => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tstep(generator.next(value))\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\treject(e)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvar rejected = value => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tstep(generator.throw(value))\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\treject(e)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvar step = x => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected)\n\t\t\t\tstep((generator = generator.apply(__this, __arguments)).next())\n\t\t\t})\n\t\t}\n\n\t\t// These help for lowering async generator functions\n\t\texport var __await = function (promise, isYieldStar) {\n\t\t\tthis[0] = promise\n\t\t\tthis[1] = isYieldStar\n\t\t}\n\t\texport var __asyncGenerator = (__this, __arguments, generator) => {\n\t\t\tvar resume = (k, v, yes, no) => {\n\t\t\t\ttry {\n\t\t\t\t\tvar x = generator[k](v), isAwait = (v = x.value) instanceof __await, done = x.done\n\t\t\t\t\tPromise.resolve(isAwait ? v[0] : v)\n\t\t\t\t\t\t.then(y => isAwait\n\t\t\t\t\t\t\t? resume(k === 'return' ? k : 'next', v[1] ? { done: y.done, value: y.value } : y, yes, no)\n\t\t\t\t\t\t\t: yes({ value: y, done }))\n\t\t\t\t\t\t.catch(e => resume('throw', e, yes, no))\n\t\t\t\t} catch (e) {\n\t\t\t\t\tno(e)\n\t\t\t\t}\n\t\t\t}, method = k => it[k] = x => new Promise((yes, no) => resume(k, x, yes, no)), it = {}\n\t\t\treturn generator = generator.apply(__this, __arguments),\n\t\t\t\tit[__knownSymbol('asyncIterator')] = () => it,\n\t\t\t\tmethod('next'),\n\t\t\t\tmethod('throw'),\n\t\t\t\tmethod('return'),\n\t\t\t\tit\n\t\t}\n\t\texport var __yieldStar = value => {\n\t\t\tvar obj = value[__knownSymbol('asyncIterator')], isAwait = false, method, it = {}\n\t\t\tif (obj == null) {\n\t\t\t\tobj = value[__knownSymbol('iterator')]()\n\t\t\t\tmethod = k => it[k] = x => obj[k](x)\n\t\t\t} else {\n\t\t\t\tobj = obj.call(value)\n\t\t\t\tmethod = k => it[k] = v => {\n\t\t\t\t\tif (isAwait) {\n\t\t\t\t\t\tisAwait = false\n\t\t\t\t\t\tif (k === 'throw') throw v\n\t\t\t\t\t\treturn v\n\t\t\t\t\t}\n\t\t\t\t\tisAwait = true\n\t\t\t\t\treturn {\n\t\t\t\t\t\tdone: false,\n\t\t\t\t\t\tvalue: new __await(new Promise(resolve => {\n\t\t\t\t\t\t\tvar x = obj[k](v)\n\t\t\t\t\t\t\tif (!(x instanceof Object)) __typeError('Object expected')\n\t\t\t\t\t\t\tresolve(x)\n\t\t\t\t\t\t}), 1),\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn it[__knownSymbol('iterator')] = () => it,\n\t\t\t\tmethod('next'),\n\t\t\t\t'throw' in obj ? method('throw') : it.throw = x => { throw x },\n\t\t\t\t'return' in obj && method('return'),\n\t\t\t\tit\n\t\t}\n\n\t\t// This helps for lowering for-await loops\n\t\texport var __forAwait = (obj, it, method) =>\n\t\t\t(it = obj[__knownSymbol('asyncIterator')])\n\t\t\t\t? it.call(obj)\n\t\t\t\t: (obj = obj[__knownSymbol('iterator')](),\n\t\t\t\t\tit = {},\n\t\t\t\t\tmethod = (key, fn) =>\n\t\t\t\t\t\t(fn = obj[key]) && (it[key] = arg =>\n\t\t\t\t\t\t\tnew Promise((yes, no, done) => (\n\t\t\t\t\t\t\t\targ = fn.call(obj, arg),\n\t\t\t\t\t\t\t\tdone = arg.done,\n\t\t\t\t\t\t\t\tPromise.resolve(arg.value)\n\t\t\t\t\t\t\t\t\t.then(value => yes({ value, done }), no)\n\t\t\t\t\t\t\t))),\n\t\t\t\t\tmethod('next'),\n\t\t\t\t\tmethod('return'),\n\t\t\t\t\tit)\n\n\t\t// This is for the \"binary\" loader (custom code is ~2x faster than \"atob\")\n\t\texport var __toBinaryNode = Uint8Array.fromBase64 || (base64 => new Uint8Array(Buffer.from(base64, 'base64')))\n\t\texport var __toBinary = Uint8Array.fromBase64 || /* @__PURE__ */ (() => {\n\t\t\tvar table = new Uint8Array(128)\n\t\t\tfor (var i = 0; i < 64; i++) table[i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i * 4 - 205] = i\n\t\t\treturn base64 => {\n\t\t\t\tvar n = base64.length, bytes = new Uint8Array((n - (base64[n - 1] == '=') - (base64[n - 2] == '=')) * 3 / 4 | 0)\n\t\t\t\tfor (var i = 0, j = 0; i < n;) {\n\t\t\t\t\tvar c0 = table[base64.charCodeAt(i++)], c1 = table[base64.charCodeAt(i++)]\n\t\t\t\t\tvar c2 = table[base64.charCodeAt(i++)], c3 = table[base64.charCodeAt(i++)]\n\t\t\t\t\tbytes[j++] = (c0 << 2) | (c1 >> 4)\n\t\t\t\t\tbytes[j++] = (c1 << 4) | (c2 >> 2)\n\t\t\t\t\tbytes[j++] = (c2 << 6) | c3\n\t\t\t\t}\n\t\t\t\treturn bytes\n\t\t\t}\n\t\t})()\n\n\t\t// These are for the \"using\" statement in TypeScript 5.2+\n\t\texport var __using = (stack, value, async) => {\n\t\t\tif (value != null) {\n\t\t\t\tif (typeof value !== 'object' && typeof value !== 'function') __typeError('Object expected')\n\t\t\t\tvar dispose, inner\n\t\t\t\tif (async) dispose = value[__knownSymbol('asyncDispose')]\n\t\t\t\tif (dispose === void 0) {\n\t\t\t\t\tdispose = value[__knownSymbol('dispose')]\n\t\t\t\t\tif (async) inner = dispose\n\t\t\t\t}\n\t\t\t\tif (typeof dispose !== 'function') __typeError('Object not disposable')\n\t\t\t\tif (inner) dispose = function() { try { inner.call(this) } catch (e) { return Promise.reject(e) } }\n\t\t\t\tstack.push([async, dispose, value])\n\t\t\t} else if (async) {\n\t\t\t\tstack.push([async])\n\t\t\t}\n\t\t\treturn value\n\t\t}\n\t\texport var __callDispose = (stack, error, hasError) => {\n\t\t\tvar E = typeof SuppressedError === 'function' ? SuppressedError :\n\t\t\t\tfunction (e, s, m, _) { return _ = Error(m), _.name = 'SuppressedError', _.error = e, _.suppressed = s, _ }\n\t\t\tvar fail = e => error = hasError ? new E(e, error, 'An error was suppressed during disposal') : (hasError = true, e)\n\t\t\tvar next = (it) => {\n\t\t\t\twhile (it = stack.pop()) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tvar result = it[1] && it[1].call(it[2])\n\t\t\t\t\t\tif (it[0]) return Promise.resolve(result).then(next, (e) => (fail(e), next()))\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tfail(e)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (hasError) throw error\n\t\t\t}\n\t\t\treturn next()\n\t\t}\n\t`\n\n\treturn logger.Source{\n\t\tIndex:          SourceIndex,\n\t\tKeyPath:        logger.Path{Text: \"<runtime>\"},\n\t\tPrettyPaths:    logger.PrettyPaths{Abs: \"<runtime>\", Rel: \"<runtime>\"},\n\t\tIdentifierName: \"runtime\",\n\t\tContents:       text,\n\t}\n}\n\n// The TypeScript decorator transform behaves similar to the official\n// TypeScript compiler.\n//\n// One difference is that the \"__decorateClass\" function doesn't contain a reference\n// to the non-existent \"Reflect.decorate\" function. This function was never\n// standardized and checking for it is wasted code (as well as a potentially\n// dangerous cause of unintentional behavior changes in the future).\n//\n// Another difference is that the \"__decorateClass\" function doesn't take in an\n// optional property descriptor like it does in the official TypeScript\n// compiler's support code. This appears to be a dead code path in the official\n// support code that is only there for legacy reasons.\n//\n// Here are some examples of how esbuild's decorator transform works:\n//\n// ============================= Class decorator ==============================\n//\n//   // TypeScript                      // JavaScript\n//   @dec                               let C = class {\n//   class C {                          };\n//   }                                  C = __decorateClass([\n//                                        dec\n//                                      ], C);\n//\n// ============================ Method decorator ==============================\n//\n//   // TypeScript                      // JavaScript\n//   class C {                          class C {\n//     @dec                               foo() {}\n//     foo() {}                         }\n//   }                                  __decorateClass([\n//                                        dec\n//                                      ], C.prototype, 'foo', 1);\n//\n// =========================== Parameter decorator ============================\n//\n//   // TypeScript                      // JavaScript\n//   class C {                          class C {\n//     foo(@dec bar) {}                   foo(bar) {}\n//   }                                  }\n//                                      __decorateClass([\n//                                        __decorateParam(0, dec)\n//                                      ], C.prototype, 'foo', 1);\n//\n// ============================= Field decorator ==============================\n//\n//   // TypeScript                      // JavaScript\n//   class C {                          class C {\n//     @dec                               constructor() {\n//     foo = 123                            this.foo = 123\n//   }                                    }\n//                                      }\n//                                      __decorateClass([\n//                                        dec\n//                                      ], C.prototype, 'foo', 2);\n"
  },
  {
    "path": "internal/runtime/runtime_test.go",
    "content": "package runtime_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/js_parser\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/runtime\"\n)\n\nfunc TestUnsupportedFeatures(t *testing.T) {\n\tfor key, feature := range compat.StringToJSFeature {\n\t\tt.Run(key, func(t *testing.T) {\n\t\t\tsource := runtime.Source(feature)\n\t\t\tlog := logger.NewDeferLog(logger.DeferLogAll, nil)\n\n\t\t\tjs_parser.Parse(log, source, js_parser.OptionsFromConfig(&config.Options{\n\t\t\t\tUnsupportedJSFeatures: feature,\n\t\t\t\tTreeShaking:           true,\n\t\t\t}))\n\n\t\t\tif log.HasErrors() {\n\t\t\t\tmsgs := \"Internal error: failed to parse runtime:\\n\"\n\t\t\t\tfor _, msg := range log.Done() {\n\t\t\t\t\tmsgs += msg.String(logger.OutputOptions{IncludeSource: true}, logger.TerminalInfo{})\n\t\t\t\t}\n\t\t\t\tt.Fatal(msgs[:len(msgs)-1])\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/sourcemap/sourcemap.go",
    "content": "package sourcemap\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\ntype Mapping struct {\n\tGeneratedLine   int32 // 0-based\n\tGeneratedColumn int32 // 0-based count of UTF-16 code units\n\n\tSourceIndex    int32       // 0-based\n\tOriginalLine   int32       // 0-based\n\tOriginalColumn int32       // 0-based count of UTF-16 code units\n\tOriginalName   ast.Index32 // 0-based, optional\n}\n\ntype SourceMap struct {\n\tSources        []string\n\tSourcesContent []SourceContent\n\tMappings       []Mapping\n\tNames          []string\n}\n\ntype SourceContent struct {\n\t// This stores both the unquoted and the quoted values. We try to use the\n\t// already-quoted value if possible so we don't need to re-quote it\n\t// unnecessarily for maximum performance.\n\tQuoted string\n\n\t// But sometimes we need to re-quote the value, such as when it contains\n\t// non-ASCII characters and we are in ASCII-only mode. In that case we quote\n\t// this parsed UTF-16 value.\n\tValue []uint16\n}\n\nfunc (sm *SourceMap) Find(line int32, column int32) *Mapping {\n\tmappings := sm.Mappings\n\n\t// Binary search\n\tcount := len(mappings)\n\tindex := 0\n\tfor count > 0 {\n\t\tstep := count / 2\n\t\ti := index + step\n\t\tmapping := mappings[i]\n\t\tif mapping.GeneratedLine < line || (mapping.GeneratedLine == line && mapping.GeneratedColumn <= column) {\n\t\t\tindex = i + 1\n\t\t\tcount -= step + 1\n\t\t} else {\n\t\t\tcount = step\n\t\t}\n\t}\n\n\t// Handle search failure\n\tif index > 0 {\n\t\tmapping := &mappings[index-1]\n\n\t\t// Match the behavior of the popular \"source-map\" library from Mozilla\n\t\tif mapping.GeneratedLine == line {\n\t\t\treturn mapping\n\t\t}\n\t}\n\treturn nil\n}\n\nvar base64 = []byte(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\")\n\n// A single base 64 digit can contain 6 bits of data. For the base 64 variable\n// length quantities we use in the source map spec, the first bit is the sign,\n// the next four bits are the actual value, and the 6th bit is the continuation\n// bit. The continuation bit tells us whether there are more digits in this\n// value following this digit.\n//\n//\tContinuation\n//\t|    Sign\n//\t|    |\n//\tV    V\n//\t101011\nfunc encodeVLQ(encoded []byte, value int) []byte {\n\tvar vlq int\n\tif value < 0 {\n\t\tvlq = ((-value) << 1) | 1\n\t} else {\n\t\tvlq = value << 1\n\t}\n\n\t// Handle the common case\n\tif (vlq >> 5) == 0 {\n\t\tdigit := vlq & 31\n\t\tencoded = append(encoded, base64[digit])\n\t\treturn encoded\n\t}\n\n\tfor {\n\t\tdigit := vlq & 31\n\t\tvlq >>= 5\n\n\t\t// If there are still more digits in this value, we must make sure the\n\t\t// continuation bit is marked\n\t\tif vlq != 0 {\n\t\t\tdigit |= 32\n\t\t}\n\n\t\tencoded = append(encoded, base64[digit])\n\n\t\tif vlq == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn encoded\n}\n\nfunc DecodeVLQ(encoded []byte, start int) (int, int) {\n\tshift := 0\n\tvlq := 0\n\n\t// Scan over the input\n\tfor {\n\t\tindex := bytes.IndexByte(base64, encoded[start])\n\t\tif index < 0 {\n\t\t\tbreak\n\t\t}\n\n\t\t// Decode a single byte\n\t\tvlq |= (index & 31) << shift\n\t\tstart++\n\t\tshift += 5\n\n\t\t// Stop if there's no continuation bit\n\t\tif (index & 32) == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Recover the value\n\tvalue := vlq >> 1\n\tif (vlq & 1) != 0 {\n\t\tvalue = -value\n\t}\n\treturn value, start\n}\n\nfunc DecodeVLQUTF16(encoded []uint16) (int32, int, bool) {\n\tn := len(encoded)\n\tif n == 0 {\n\t\treturn 0, 0, false\n\t}\n\n\t// Scan over the input\n\tcurrent := 0\n\tshift := 0\n\tvar vlq int32\n\tfor {\n\t\tif current >= n {\n\t\t\treturn 0, 0, false\n\t\t}\n\t\tindex := int32(bytes.IndexByte(base64, byte(encoded[current])))\n\t\tif index < 0 {\n\t\t\treturn 0, 0, false\n\t\t}\n\n\t\t// Decode a single byte\n\t\tvlq |= (index & 31) << shift\n\t\tcurrent++\n\t\tshift += 5\n\n\t\t// Stop if there's no continuation bit\n\t\tif (index & 32) == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Recover the value\n\tvar value = vlq >> 1\n\tif (vlq & 1) != 0 {\n\t\tvalue = -value\n\t}\n\treturn value, current, true\n}\n\ntype LineColumnOffset struct {\n\tLines   int\n\tColumns int\n}\n\nfunc (a LineColumnOffset) ComesBefore(b LineColumnOffset) bool {\n\treturn a.Lines < b.Lines || (a.Lines == b.Lines && a.Columns < b.Columns)\n}\n\nfunc (a *LineColumnOffset) Add(b LineColumnOffset) {\n\tif b.Lines == 0 {\n\t\ta.Columns += b.Columns\n\t} else {\n\t\ta.Lines += b.Lines\n\t\ta.Columns = b.Columns\n\t}\n}\n\nfunc (offset *LineColumnOffset) AdvanceBytes(bytes []byte) {\n\tcolumns := offset.Columns\n\tfor len(bytes) > 0 {\n\t\tc, width := utf8.DecodeRune(bytes)\n\t\tbytes = bytes[width:]\n\t\tswitch c {\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t// Handle Windows-specific \"\\r\\n\" newlines\n\t\t\tif c == '\\r' && len(bytes) > 0 && bytes[0] == '\\n' {\n\t\t\t\tcolumns++\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\toffset.Lines++\n\t\t\tcolumns = 0\n\n\t\tdefault:\n\t\t\t// Mozilla's \"source-map\" library counts columns using UTF-16 code units\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tcolumns++\n\t\t\t} else {\n\t\t\t\tcolumns += 2\n\t\t\t}\n\t\t}\n\t}\n\toffset.Columns = columns\n}\n\nfunc (offset *LineColumnOffset) AdvanceString(text string) {\n\tcolumns := offset.Columns\n\tfor i, c := range text {\n\t\tswitch c {\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t// Handle Windows-specific \"\\r\\n\" newlines\n\t\t\tif c == '\\r' && i+1 < len(text) && text[i+1] == '\\n' {\n\t\t\t\tcolumns++\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\toffset.Lines++\n\t\t\tcolumns = 0\n\n\t\tdefault:\n\t\t\t// Mozilla's \"source-map\" library counts columns using UTF-16 code units\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tcolumns++\n\t\t\t} else {\n\t\t\t\tcolumns += 2\n\t\t\t}\n\t\t}\n\t}\n\toffset.Columns = columns\n}\n\ntype SourceMapPieces struct {\n\tPrefix   []byte\n\tMappings []byte\n\tSuffix   []byte\n}\n\nfunc (pieces SourceMapPieces) HasContent() bool {\n\treturn len(pieces.Prefix)+len(pieces.Mappings)+len(pieces.Suffix) > 0\n}\n\ntype SourceMapShift struct {\n\tBefore LineColumnOffset\n\tAfter  LineColumnOffset\n}\n\nfunc (pieces SourceMapPieces) Finalize(shifts []SourceMapShift) []byte {\n\t// An optimized path for when there are no shifts\n\tif len(shifts) == 1 {\n\t\tbytes := pieces.Prefix\n\t\tminCap := len(bytes) + len(pieces.Mappings) + len(pieces.Suffix)\n\t\tif cap(bytes) < minCap {\n\t\t\tbytes = append(make([]byte, 0, minCap), bytes...)\n\t\t}\n\t\tbytes = append(bytes, pieces.Mappings...)\n\t\tbytes = append(bytes, pieces.Suffix...)\n\t\treturn bytes\n\t}\n\n\tstartOfRun := 0\n\tcurrent := 0\n\tgenerated := LineColumnOffset{}\n\tprevShiftColumnDelta := 0\n\tj := helpers.Joiner{}\n\n\t// Start the source map\n\tj.AddBytes(pieces.Prefix)\n\n\t// This assumes that a) all mappings are valid and b) all mappings are ordered\n\t// by increasing generated position. This should be the case for all mappings\n\t// generated by esbuild, which should be the only mappings we process here.\n\tfor current < len(pieces.Mappings) {\n\t\t// Handle a line break\n\t\tif pieces.Mappings[current] == ';' {\n\t\t\tgenerated.Lines++\n\t\t\tgenerated.Columns = 0\n\t\t\tprevShiftColumnDelta = 0\n\t\t\tcurrent++\n\t\t\tcontinue\n\t\t}\n\n\t\tpotentialEndOfRun := current\n\n\t\t// Read the generated column\n\t\tgeneratedColumnDelta, next := DecodeVLQ(pieces.Mappings, current)\n\t\tgenerated.Columns += generatedColumnDelta\n\t\tcurrent = next\n\n\t\tpotentialStartOfRun := current\n\n\t\t// Skip over the original position information if present\n\t\tif current < len(pieces.Mappings) {\n\t\t\t_, current = DecodeVLQ(pieces.Mappings, current) // The original source\n\t\t\t_, current = DecodeVLQ(pieces.Mappings, current) // The original line\n\t\t\t_, current = DecodeVLQ(pieces.Mappings, current) // The original column\n\n\t\t\t// Skip over the original name if present\n\t\t\tif current < len(pieces.Mappings) {\n\t\t\t\t_, current = DecodeVLQ(pieces.Mappings, current)\n\t\t\t}\n\t\t}\n\n\t\t// Skip a trailing comma\n\t\tif current < len(pieces.Mappings) && pieces.Mappings[current] == ',' {\n\t\t\tcurrent++\n\t\t}\n\n\t\t// Detect crossing shift boundaries\n\t\tdidCrossBoundary := false\n\t\tfor len(shifts) > 1 && shifts[1].Before.ComesBefore(generated) {\n\t\t\tshifts = shifts[1:]\n\t\t\tdidCrossBoundary = true\n\t\t}\n\t\tif !didCrossBoundary {\n\t\t\tcontinue\n\t\t}\n\n\t\t// This shift isn't relevant if the next mapping after this shift is on a\n\t\t// following line. In that case, don't split and keep scanning instead.\n\t\tshift := shifts[0]\n\t\tif shift.After.Lines != generated.Lines {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Add all previous mappings in a single run for efficiency. Since source\n\t\t// mappings are relative, no data needs to be modified inside this run.\n\t\tj.AddBytes(pieces.Mappings[startOfRun:potentialEndOfRun])\n\n\t\t// Then modify the first mapping across the shift boundary with the updated\n\t\t// generated column value. It's simplest to only support column shifts. This\n\t\t// is reasonable because import paths should not contain newlines.\n\t\tif shift.Before.Lines != shift.After.Lines {\n\t\t\tpanic(\"Unexpected line change when shifting source maps\")\n\t\t}\n\t\tshiftColumnDelta := shift.After.Columns - shift.Before.Columns\n\t\tj.AddBytes(encodeVLQ(nil, generatedColumnDelta+shiftColumnDelta-prevShiftColumnDelta))\n\t\tprevShiftColumnDelta = shiftColumnDelta\n\n\t\t// Finally, start the next run after the end of this generated column offset\n\t\tstartOfRun = potentialStartOfRun\n\t}\n\n\t// Finish the source map\n\tj.AddBytes(pieces.Mappings[startOfRun:])\n\tj.AddBytes(pieces.Suffix)\n\treturn j.Done()\n}\n\n// Coordinates in source maps are stored using relative offsets for size\n// reasons. When joining together chunks of a source map that were emitted\n// in parallel for different parts of a file, we need to fix up the first\n// segment of each chunk to be relative to the end of the previous chunk.\ntype SourceMapState struct {\n\t// This isn't stored in the source map. It's only used by the bundler to join\n\t// source map chunks together correctly.\n\tGeneratedLine int\n\n\t// These are stored in the source map in VLQ format.\n\tGeneratedColumn int\n\tSourceIndex     int\n\tOriginalLine    int\n\tOriginalColumn  int\n\tOriginalName    int\n\tHasOriginalName bool\n}\n\n// Source map chunks are computed in parallel for speed. Each chunk is relative\n// to the zero state instead of being relative to the end state of the previous\n// chunk, since it's impossible to know the end state of the previous chunk in\n// a parallel computation.\n//\n// After all chunks are computed, they are joined together in a second pass.\n// This rewrites the first mapping in each chunk to be relative to the end\n// state of the previous chunk.\nfunc AppendSourceMapChunk(j *helpers.Joiner, prevEndState SourceMapState, startState SourceMapState, buffer MappingsBuffer) {\n\t// Handle line breaks in between this mapping and the previous one\n\tif startState.GeneratedLine != 0 {\n\t\tj.AddBytes(bytes.Repeat([]byte{';'}, startState.GeneratedLine))\n\t\tprevEndState.GeneratedColumn = 0\n\t}\n\n\t// Skip past any leading semicolons, which indicate line breaks\n\tsemicolons := 0\n\tfor buffer.Data[semicolons] == ';' {\n\t\tsemicolons++\n\t}\n\tif semicolons > 0 {\n\t\tj.AddBytes(buffer.Data[:semicolons])\n\t\tprevEndState.GeneratedColumn = 0\n\t\tstartState.GeneratedColumn = 0\n\t}\n\n\t// Strip off the first mapping from the buffer. The first mapping should be\n\t// for the start of the original file (the printer always generates one for\n\t// the start of the file).\n\t//\n\t// Note that we do not want to strip off the original name, even though it\n\t// could be a part of the first mapping. This will be handled using a special\n\t// case below instead. Original names are optional and are often omitted, so\n\t// we handle it uniformly by saving an index to the first original name,\n\t// which may or may not be a part of the first mapping.\n\tvar sourceIndex int\n\tvar originalLine int\n\tvar originalColumn int\n\tomitSource := false\n\tgeneratedColumn, i := DecodeVLQ(buffer.Data, semicolons)\n\tif i == len(buffer.Data) || strings.IndexByte(\",;\", buffer.Data[i]) != -1 {\n\t\tomitSource = true\n\t} else {\n\t\tsourceIndex, i = DecodeVLQ(buffer.Data, i)\n\t\toriginalLine, i = DecodeVLQ(buffer.Data, i)\n\t\toriginalColumn, i = DecodeVLQ(buffer.Data, i)\n\t}\n\n\t// Rewrite the first mapping to be relative to the end state of the previous\n\t// chunk. We now know what the end state is because we're in the second pass\n\t// where all chunks have already been generated.\n\tstartState.GeneratedColumn += generatedColumn\n\tstartState.SourceIndex += sourceIndex\n\tstartState.OriginalLine += originalLine\n\tstartState.OriginalColumn += originalColumn\n\tprevEndState.HasOriginalName = false // This is handled separately below\n\trewritten, _ := appendMappingToBuffer(nil, j.LastByte(), prevEndState, startState, omitSource)\n\tj.AddBytes(rewritten)\n\n\t// Next, if there's an original name, we need to rewrite that as well to be\n\t// relative to that of the previous chunk.\n\tif buffer.FirstNameOffset.IsValid() {\n\t\tbefore := int(buffer.FirstNameOffset.GetIndex())\n\t\toriginalName, after := DecodeVLQ(buffer.Data, before)\n\t\toriginalName += startState.OriginalName - prevEndState.OriginalName\n\t\tj.AddBytes(buffer.Data[i:before])\n\t\tj.AddBytes(encodeVLQ(nil, originalName))\n\t\tj.AddBytes(buffer.Data[after:])\n\t\treturn\n\t}\n\n\t// Otherwise, just append everything after that without modification\n\tj.AddBytes(buffer.Data[i:])\n}\n\nfunc appendMappingToBuffer(\n\tbuffer []byte, lastByte byte, prevState SourceMapState, currentState SourceMapState, omitSource bool,\n) ([]byte, ast.Index32) {\n\t// Put commas in between mappings\n\tif lastByte != 0 && lastByte != ';' && lastByte != '\"' {\n\t\tbuffer = append(buffer, ',')\n\t}\n\n\t// Record the mapping (note that the generated line is recorded using ';' elsewhere)\n\tbuffer = encodeVLQ(buffer, currentState.GeneratedColumn-prevState.GeneratedColumn)\n\tif !omitSource {\n\t\tbuffer = encodeVLQ(buffer, currentState.SourceIndex-prevState.SourceIndex)\n\t\tbuffer = encodeVLQ(buffer, currentState.OriginalLine-prevState.OriginalLine)\n\t\tbuffer = encodeVLQ(buffer, currentState.OriginalColumn-prevState.OriginalColumn)\n\t}\n\n\t// Record the optional original name\n\tvar nameOffset ast.Index32\n\tif currentState.HasOriginalName {\n\t\tnameOffset = ast.MakeIndex32(uint32(len(buffer)))\n\t\tbuffer = encodeVLQ(buffer, currentState.OriginalName-prevState.OriginalName)\n\t}\n\n\treturn buffer, nameOffset\n}\n\ntype LineOffsetTable struct {\n\t// The source map specification is very loose and does not specify what\n\t// column numbers actually mean. The popular \"source-map\" library from Mozilla\n\t// appears to interpret them as counts of UTF-16 code units, so we generate\n\t// those too for compatibility.\n\t//\n\t// We keep mapping tables around to accelerate conversion from byte offsets\n\t// to UTF-16 code unit counts. However, this mapping takes up a lot of memory\n\t// and generates a lot of garbage. Since most JavaScript is ASCII and the\n\t// mapping for ASCII is 1:1, we avoid creating a table for ASCII-only lines\n\t// as an optimization.\n\tcolumnsForNonASCII        []int32\n\tbyteOffsetToFirstNonASCII int32\n\n\tbyteOffsetToStartOfLine int32\n}\n\nfunc GenerateLineOffsetTables(contents string, approximateLineCount int32) []LineOffsetTable {\n\tvar ColumnsForNonASCII []int32\n\tByteOffsetToFirstNonASCII := int32(0)\n\tlineByteOffset := 0\n\tcolumnByteOffset := 0\n\tcolumn := int32(0)\n\n\t// Preallocate the top-level table using the approximate line count from the lexer\n\tlineOffsetTables := make([]LineOffsetTable, 0, approximateLineCount)\n\n\tfor i, c := range contents {\n\t\t// Mark the start of the next line\n\t\tif column == 0 {\n\t\t\tlineByteOffset = i\n\t\t}\n\n\t\t// Start the mapping if this character is non-ASCII\n\t\tif c > 0x7F && ColumnsForNonASCII == nil {\n\t\t\tcolumnByteOffset = i - lineByteOffset\n\t\t\tByteOffsetToFirstNonASCII = int32(columnByteOffset)\n\t\t\tColumnsForNonASCII = []int32{}\n\t\t}\n\n\t\t// Update the per-byte column offsets\n\t\tif ColumnsForNonASCII != nil {\n\t\t\tfor lineBytesSoFar := i - lineByteOffset; columnByteOffset <= lineBytesSoFar; columnByteOffset++ {\n\t\t\t\tColumnsForNonASCII = append(ColumnsForNonASCII, column)\n\t\t\t}\n\t\t}\n\n\t\tswitch c {\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t// Handle Windows-specific \"\\r\\n\" newlines\n\t\t\tif c == '\\r' && i+1 < len(contents) && contents[i+1] == '\\n' {\n\t\t\t\tcolumn++\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlineOffsetTables = append(lineOffsetTables, LineOffsetTable{\n\t\t\t\tbyteOffsetToStartOfLine:   int32(lineByteOffset),\n\t\t\t\tbyteOffsetToFirstNonASCII: ByteOffsetToFirstNonASCII,\n\t\t\t\tcolumnsForNonASCII:        ColumnsForNonASCII,\n\t\t\t})\n\t\t\tcolumnByteOffset = 0\n\t\t\tByteOffsetToFirstNonASCII = 0\n\t\t\tColumnsForNonASCII = nil\n\t\t\tcolumn = 0\n\n\t\tdefault:\n\t\t\t// Mozilla's \"source-map\" library counts columns using UTF-16 code units\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tcolumn++\n\t\t\t} else {\n\t\t\t\tcolumn += 2\n\t\t\t}\n\t\t}\n\t}\n\n\t// Mark the start of the next line\n\tif column == 0 {\n\t\tlineByteOffset = len(contents)\n\t}\n\n\t// Do one last update for the column at the end of the file\n\tif ColumnsForNonASCII != nil {\n\t\tfor lineBytesSoFar := len(contents) - lineByteOffset; columnByteOffset <= lineBytesSoFar; columnByteOffset++ {\n\t\t\tColumnsForNonASCII = append(ColumnsForNonASCII, column)\n\t\t}\n\t}\n\n\tlineOffsetTables = append(lineOffsetTables, LineOffsetTable{\n\t\tbyteOffsetToStartOfLine:   int32(lineByteOffset),\n\t\tbyteOffsetToFirstNonASCII: ByteOffsetToFirstNonASCII,\n\t\tcolumnsForNonASCII:        ColumnsForNonASCII,\n\t})\n\treturn lineOffsetTables\n}\n\ntype MappingsBuffer struct {\n\tData            []byte\n\tFirstNameOffset ast.Index32\n}\n\ntype Chunk struct {\n\tBuffer      MappingsBuffer\n\tQuotedNames [][]byte\n\n\t// This end state will be used to rewrite the start of the following source\n\t// map chunk so that the delta-encoded VLQ numbers are preserved.\n\tEndState SourceMapState\n\n\t// There probably isn't a source mapping at the end of the file (nor should\n\t// there be) but if we're appending another source map chunk after this one,\n\t// we'll need to know how many characters were in the last line we generated.\n\tFinalGeneratedColumn int\n\n\tShouldIgnore bool\n}\n\ntype ChunkBuilder struct {\n\tinputSourceMap      *SourceMap\n\tsourceMap           []byte\n\tquotedNames         [][]byte\n\tnamesMap            map[string]uint32\n\tlineOffsetTables    []LineOffsetTable\n\tprevOriginalName    string\n\tprevState           SourceMapState\n\tlastGeneratedUpdate int\n\tgeneratedColumn     int\n\tprevGeneratedLen    int\n\tprevOriginalLoc     logger.Loc\n\tfirstNameOffset     ast.Index32\n\thasPrevState        bool\n\tasciiOnly           bool\n\n\t// This is a workaround for a bug in the popular \"source-map\" library:\n\t// https://github.com/mozilla/source-map/issues/261. The library will\n\t// sometimes return null when querying a source map unless every line\n\t// starts with a mapping at column zero.\n\t//\n\t// The workaround is to replicate the previous mapping if a line ends\n\t// up not starting with a mapping. This is done lazily because we want\n\t// to avoid replicating the previous mapping if we don't need to.\n\tlineStartsWithMapping     bool\n\tcoverLinesWithoutMappings bool\n}\n\nfunc MakeChunkBuilder(inputSourceMap *SourceMap, lineOffsetTables []LineOffsetTable, asciiOnly bool) ChunkBuilder {\n\treturn ChunkBuilder{\n\t\tinputSourceMap:   inputSourceMap,\n\t\tprevOriginalLoc:  logger.Loc{Start: -1},\n\t\tlineOffsetTables: lineOffsetTables,\n\t\tasciiOnly:        asciiOnly,\n\t\tnamesMap:         make(map[string]uint32),\n\n\t\t// We automatically repeat the previous source mapping if we ever generate\n\t\t// a line that doesn't start with a mapping. This helps give files more\n\t\t// complete mapping coverage without gaps.\n\t\t//\n\t\t// However, we probably shouldn't do this if the input file has a nested\n\t\t// source map that we will be remapping through. We have no idea what state\n\t\t// that source map is in and it could be pretty scrambled.\n\t\t//\n\t\t// I've seen cases where blindly repeating the last mapping for subsequent\n\t\t// lines gives very strange and unhelpful results with source maps from\n\t\t// other tools.\n\t\tcoverLinesWithoutMappings: inputSourceMap == nil,\n\t}\n}\n\nfunc (b *ChunkBuilder) AddSourceMapping(originalLoc logger.Loc, originalName string, output []byte) {\n\t// Avoid generating duplicate mappings\n\tif originalLoc == b.prevOriginalLoc && (b.prevGeneratedLen == len(output) || b.prevOriginalName == originalName) {\n\t\treturn\n\t}\n\n\tb.prevOriginalLoc = originalLoc\n\tb.prevGeneratedLen = len(output)\n\tb.prevOriginalName = originalName\n\n\t// Binary search to find the line\n\tlineOffsetTables := b.lineOffsetTables\n\tcount := len(lineOffsetTables)\n\toriginalLine := 0\n\tfor count > 0 {\n\t\tstep := count / 2\n\t\ti := originalLine + step\n\t\tif lineOffsetTables[i].byteOffsetToStartOfLine <= originalLoc.Start {\n\t\t\toriginalLine = i + 1\n\t\t\tcount = count - step - 1\n\t\t} else {\n\t\t\tcount = step\n\t\t}\n\t}\n\toriginalLine--\n\n\t// Use the line to compute the column\n\tline := &lineOffsetTables[originalLine]\n\toriginalColumn := int(originalLoc.Start - line.byteOffsetToStartOfLine)\n\tif line.columnsForNonASCII != nil && originalColumn >= int(line.byteOffsetToFirstNonASCII) {\n\t\toriginalColumn = int(line.columnsForNonASCII[originalColumn-int(line.byteOffsetToFirstNonASCII)])\n\t}\n\n\tb.updateGeneratedLineAndColumn(output)\n\n\t// If this line doesn't start with a mapping and we're about to add a mapping\n\t// that's not at the start, insert a mapping first so the line starts with one.\n\tif b.coverLinesWithoutMappings && !b.lineStartsWithMapping && b.generatedColumn > 0 && b.hasPrevState {\n\t\tb.appendMappingWithoutRemapping(SourceMapState{\n\t\t\tGeneratedLine:   b.prevState.GeneratedLine,\n\t\t\tGeneratedColumn: 0,\n\t\t\tSourceIndex:     b.prevState.SourceIndex,\n\t\t\tOriginalLine:    b.prevState.OriginalLine,\n\t\t\tOriginalColumn:  b.prevState.OriginalColumn,\n\t\t})\n\t}\n\n\tb.appendMapping(originalName, SourceMapState{\n\t\tGeneratedLine:   b.prevState.GeneratedLine,\n\t\tGeneratedColumn: b.generatedColumn,\n\t\tOriginalLine:    originalLine,\n\t\tOriginalColumn:  originalColumn,\n\t})\n\n\t// This line now has a mapping on it, so don't insert another one\n\tb.lineStartsWithMapping = true\n}\n\nfunc (b *ChunkBuilder) GenerateChunk(output []byte) Chunk {\n\tb.updateGeneratedLineAndColumn(output)\n\tshouldIgnore := true\n\tfor _, c := range b.sourceMap {\n\t\tif c != ';' {\n\t\t\tshouldIgnore = false\n\t\t\tbreak\n\t\t}\n\t}\n\treturn Chunk{\n\t\tBuffer: MappingsBuffer{\n\t\t\tData:            b.sourceMap,\n\t\t\tFirstNameOffset: b.firstNameOffset,\n\t\t},\n\t\tQuotedNames:          b.quotedNames,\n\t\tEndState:             b.prevState,\n\t\tFinalGeneratedColumn: b.generatedColumn,\n\t\tShouldIgnore:         shouldIgnore,\n\t}\n}\n\n// Scan over the printed text since the last source mapping and update the\n// generated line and column numbers\nfunc (b *ChunkBuilder) updateGeneratedLineAndColumn(output []byte) {\n\tfor i, c := range string(output[b.lastGeneratedUpdate:]) {\n\t\tswitch c {\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t// Handle Windows-specific \"\\r\\n\" newlines\n\t\t\tif c == '\\r' {\n\t\t\t\tnewlineCheck := b.lastGeneratedUpdate + i + 1\n\t\t\t\tif newlineCheck < len(output) && output[newlineCheck] == '\\n' {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we're about to move to the next line and the previous line didn't have\n\t\t\t// any mappings, add a mapping at the start of the previous line.\n\t\t\tif b.coverLinesWithoutMappings && !b.lineStartsWithMapping && b.hasPrevState {\n\t\t\t\tb.appendMappingWithoutRemapping(SourceMapState{\n\t\t\t\t\tGeneratedLine:   b.prevState.GeneratedLine,\n\t\t\t\t\tGeneratedColumn: 0,\n\t\t\t\t\tSourceIndex:     b.prevState.SourceIndex,\n\t\t\t\t\tOriginalLine:    b.prevState.OriginalLine,\n\t\t\t\t\tOriginalColumn:  b.prevState.OriginalColumn,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tb.prevState.GeneratedLine++\n\t\t\tb.prevState.GeneratedColumn = 0\n\t\t\tb.generatedColumn = 0\n\t\t\tb.sourceMap = append(b.sourceMap, ';')\n\n\t\t\t// This new line doesn't have a mapping yet\n\t\t\tb.lineStartsWithMapping = false\n\n\t\tdefault:\n\t\t\t// Mozilla's \"source-map\" library counts columns using UTF-16 code units\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tb.generatedColumn++\n\t\t\t} else {\n\t\t\t\tb.generatedColumn += 2\n\t\t\t}\n\t\t}\n\t}\n\n\tb.lastGeneratedUpdate = len(output)\n}\n\nfunc (b *ChunkBuilder) appendMapping(originalName string, currentState SourceMapState) {\n\t// If the input file had a source map, map all the way back to the original\n\tif b.inputSourceMap != nil {\n\t\tmapping := b.inputSourceMap.Find(\n\t\t\tint32(currentState.OriginalLine),\n\t\t\tint32(currentState.OriginalColumn))\n\n\t\t// Some locations won't have a mapping\n\t\tif mapping == nil {\n\t\t\treturn\n\t\t}\n\n\t\tcurrentState.SourceIndex = int(mapping.SourceIndex)\n\t\tcurrentState.OriginalLine = int(mapping.OriginalLine)\n\t\tcurrentState.OriginalColumn = int(mapping.OriginalColumn)\n\n\t\t// Map all the way back to the original name if present. Otherwise, keep\n\t\t// the original name from esbuild, which corresponds to the name in the\n\t\t// intermediate source code. This is important for tools that only emit\n\t\t// a name mapping when the name is different than the original name.\n\t\tif mapping.OriginalName.IsValid() {\n\t\t\toriginalName = b.inputSourceMap.Names[mapping.OriginalName.GetIndex()]\n\t\t}\n\t}\n\n\t// Optionally reference the original name\n\tif originalName != \"\" {\n\t\ti, ok := b.namesMap[originalName]\n\t\tif !ok {\n\t\t\ti = uint32(len(b.quotedNames))\n\t\t\tb.quotedNames = append(b.quotedNames, helpers.QuoteForJSON(originalName, b.asciiOnly))\n\t\t\tb.namesMap[originalName] = i\n\t\t}\n\t\tcurrentState.OriginalName = int(i)\n\t\tcurrentState.HasOriginalName = true\n\t}\n\n\tb.appendMappingWithoutRemapping(currentState)\n}\n\nfunc (b *ChunkBuilder) appendMappingWithoutRemapping(currentState SourceMapState) {\n\tvar lastByte byte\n\tif len(b.sourceMap) != 0 {\n\t\tlastByte = b.sourceMap[len(b.sourceMap)-1]\n\t}\n\n\tvar nameOffset ast.Index32\n\tb.sourceMap, nameOffset = appendMappingToBuffer(b.sourceMap, lastByte, b.prevState, currentState, false)\n\tprevOriginalName := b.prevState.OriginalName\n\tb.prevState = currentState\n\tif !currentState.HasOriginalName {\n\t\t// Revert the original name change if it's invalid\n\t\tb.prevState.OriginalName = prevOriginalName\n\t} else if !b.firstNameOffset.IsValid() {\n\t\t// Keep track of the first name offset so we can jump right to it later\n\t\tb.firstNameOffset = nameOffset\n\t}\n\tb.hasPrevState = true\n}\n"
  },
  {
    "path": "internal/test/diff.go",
    "content": "package test\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\nfunc diff(old string, new string, color bool) string {\n\treturn strings.Join(diffRec(nil, strings.Split(old, \"\\n\"), strings.Split(new, \"\\n\"), color), \"\\n\")\n}\n\n// This is a simple recursive line-by-line diff implementation\nfunc diffRec(result []string, old []string, new []string, color bool) []string {\n\to, n, common := lcSubstr(old, new)\n\n\tif common == 0 {\n\t\t// Everything changed\n\t\tfor _, line := range old {\n\t\t\tif color {\n\t\t\t\tresult = append(result, fmt.Sprintf(\"%s-%s%s\", logger.TerminalColors.Red, line, logger.TerminalColors.Reset))\n\t\t\t} else {\n\t\t\t\tresult = append(result, \"-\"+line)\n\t\t\t}\n\t\t}\n\t\tfor _, line := range new {\n\t\t\tif color {\n\t\t\t\tresult = append(result, fmt.Sprintf(\"%s+%s%s\", logger.TerminalColors.Green, line, logger.TerminalColors.Reset))\n\t\t\t} else {\n\t\t\t\tresult = append(result, \"+\"+line)\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// Something in the middle stayed the same\n\t\tresult = diffRec(result, old[:o], new[:n], color)\n\t\tfor _, line := range old[o : o+common] {\n\t\t\tif color {\n\t\t\t\tresult = append(result, fmt.Sprintf(\"%s %s%s\", logger.TerminalColors.Dim, line, logger.TerminalColors.Reset))\n\t\t\t} else {\n\t\t\t\tresult = append(result, \" \"+line)\n\t\t\t}\n\t\t}\n\t\tresult = diffRec(result, old[o+common:], new[n+common:], color)\n\t}\n\n\treturn result\n}\n\n// From: https://en.wikipedia.org/wiki/Longest_common_substring_problem\nfunc lcSubstr(S []string, T []string) (int, int, int) {\n\tr := len(S)\n\tn := len(T)\n\tLprev := make([]int, n)\n\tLnext := make([]int, n)\n\tz := 0\n\tretI := 0\n\tretJ := 0\n\n\tfor i := 0; i < r; i++ {\n\t\tfor j := 0; j < n; j++ {\n\t\t\tif S[i] == T[j] {\n\t\t\t\tif j == 0 {\n\t\t\t\t\tLnext[j] = 1\n\t\t\t\t} else {\n\t\t\t\t\tLnext[j] = Lprev[j-1] + 1\n\t\t\t\t}\n\t\t\t\tif Lnext[j] > z {\n\t\t\t\t\tz = Lnext[j]\n\t\t\t\t\tretI = i + 1\n\t\t\t\t\tretJ = j + 1\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tLnext[j] = 0\n\t\t\t}\n\t\t}\n\t\tLprev, Lnext = Lnext, Lprev\n\t}\n\n\treturn retI - z, retJ - z, z\n}\n"
  },
  {
    "path": "internal/test/util.go",
    "content": "package test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/fs\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\nfunc AssertEqual(t *testing.T, observed interface{}, expected interface{}) {\n\tt.Helper()\n\tif observed != expected {\n\t\tt.Fatalf(\"%s != %s\", observed, expected)\n\t}\n}\n\nfunc AssertEqualWithDiff(t *testing.T, observed interface{}, expected interface{}) {\n\tt.Helper()\n\tif observed != expected {\n\t\tstringA := fmt.Sprintf(\"%v\", observed)\n\t\tstringB := fmt.Sprintf(\"%v\", expected)\n\t\tcolor := !fs.CheckIfWindows()\n\t\tt.Fatal(\"\\n\" + diff(stringB, stringA, color))\n\t}\n}\n\nfunc SourceForTest(contents string) logger.Source {\n\treturn logger.Source{\n\t\tIndex:          0,\n\t\tKeyPath:        logger.Path{Text: \"<stdin>\"},\n\t\tPrettyPaths:    logger.PrettyPaths{Abs: \"<stdin>\", Rel: \"<stdin>\"},\n\t\tContents:       contents,\n\t\tIdentifierName: \"stdin\",\n\t}\n}\n"
  },
  {
    "path": "internal/xxhash/LICENSE.txt",
    "content": "Copyright (c) 2016 Caleb Spare\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "internal/xxhash/README.md",
    "content": "This Go implementation of xxHash is from https://github.com/cespare/xxhash.\n"
  },
  {
    "path": "internal/xxhash/xxhash.go",
    "content": "// Package xxhash implements the 64-bit variant of xxHash (XXH64) as described\n// at http://cyan4973.github.io/xxHash/.\npackage xxhash\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"math/bits\"\n)\n\nconst (\n\tprime1 uint64 = 11400714785074694791\n\tprime2 uint64 = 14029467366897019727\n\tprime3 uint64 = 1609587929392839161\n\tprime4 uint64 = 9650029242287828579\n\tprime5 uint64 = 2870177450012600261\n)\n\n// NOTE(caleb): I'm using both consts and vars of the primes. Using consts where\n// possible in the Go code is worth a small (but measurable) performance boost\n// by avoiding some MOVQs. Vars are needed for the asm and also are useful for\n// convenience in the Go code in a few places where we need to intentionally\n// avoid constant arithmetic (e.g., v1 := prime1 + prime2 fails because the\n// result overflows a uint64).\nvar (\n\tprime1v = prime1\n\tprime2v = prime2\n\tprime3v = prime3\n\tprime4v = prime4\n\tprime5v = prime5\n)\n\n// Digest implements hash.Hash64.\ntype Digest struct {\n\tv1    uint64\n\tv2    uint64\n\tv3    uint64\n\tv4    uint64\n\ttotal uint64\n\tmem   [32]byte\n\tn     int // how much of mem is used\n}\n\n// New creates a new Digest that computes the 64-bit xxHash algorithm.\nfunc New() *Digest {\n\tvar d Digest\n\td.Reset()\n\treturn &d\n}\n\n// Reset clears the Digest's state so that it can be reused.\nfunc (d *Digest) Reset() {\n\td.v1 = prime1v + prime2\n\td.v2 = prime2\n\td.v3 = 0\n\td.v4 = -prime1v\n\td.total = 0\n\td.n = 0\n}\n\n// Size always returns 8 bytes.\nfunc (d *Digest) Size() int { return 8 }\n\n// BlockSize always returns 32 bytes.\nfunc (d *Digest) BlockSize() int { return 32 }\n\n// Write adds more data to d. It always returns len(b), nil.\nfunc (d *Digest) Write(b []byte) (n int, err error) {\n\tn = len(b)\n\td.total += uint64(n)\n\n\tif d.n+n < 32 {\n\t\t// This new data doesn't even fill the current block.\n\t\tcopy(d.mem[d.n:], b)\n\t\td.n += n\n\t\treturn\n\t}\n\n\tif d.n > 0 {\n\t\t// Finish off the partial block.\n\t\tcopy(d.mem[d.n:], b)\n\t\td.v1 = round(d.v1, u64(d.mem[0:8]))\n\t\td.v2 = round(d.v2, u64(d.mem[8:16]))\n\t\td.v3 = round(d.v3, u64(d.mem[16:24]))\n\t\td.v4 = round(d.v4, u64(d.mem[24:32]))\n\t\tb = b[32-d.n:]\n\t\td.n = 0\n\t}\n\n\tif len(b) >= 32 {\n\t\t// One or more full blocks left.\n\t\tnw := writeBlocks(d, b)\n\t\tb = b[nw:]\n\t}\n\n\t// Store any remaining partial block.\n\tcopy(d.mem[:], b)\n\td.n = len(b)\n\n\treturn\n}\n\n// Sum appends the current hash to b and returns the resulting slice.\nfunc (d *Digest) Sum(b []byte) []byte {\n\ts := d.Sum64()\n\treturn append(\n\t\tb,\n\t\tbyte(s>>56),\n\t\tbyte(s>>48),\n\t\tbyte(s>>40),\n\t\tbyte(s>>32),\n\t\tbyte(s>>24),\n\t\tbyte(s>>16),\n\t\tbyte(s>>8),\n\t\tbyte(s),\n\t)\n}\n\n// Sum64 returns the current hash.\nfunc (d *Digest) Sum64() uint64 {\n\tvar h uint64\n\n\tif d.total >= 32 {\n\t\tv1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4\n\t\th = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4)\n\t\th = mergeRound(h, v1)\n\t\th = mergeRound(h, v2)\n\t\th = mergeRound(h, v3)\n\t\th = mergeRound(h, v4)\n\t} else {\n\t\th = d.v3 + prime5\n\t}\n\n\th += d.total\n\n\ti, end := 0, d.n\n\tfor ; i+8 <= end; i += 8 {\n\t\tk1 := round(0, u64(d.mem[i:i+8]))\n\t\th ^= k1\n\t\th = rol27(h)*prime1 + prime4\n\t}\n\tif i+4 <= end {\n\t\th ^= uint64(u32(d.mem[i:i+4])) * prime1\n\t\th = rol23(h)*prime2 + prime3\n\t\ti += 4\n\t}\n\tfor i < end {\n\t\th ^= uint64(d.mem[i]) * prime5\n\t\th = rol11(h) * prime1\n\t\ti++\n\t}\n\n\th ^= h >> 33\n\th *= prime2\n\th ^= h >> 29\n\th *= prime3\n\th ^= h >> 32\n\n\treturn h\n}\n\nconst (\n\tmagic         = \"xxh\\x06\"\n\tmarshaledSize = len(magic) + 8*5 + 32\n)\n\n// MarshalBinary implements the encoding.BinaryMarshaler interface.\nfunc (d *Digest) MarshalBinary() ([]byte, error) {\n\tb := make([]byte, 0, marshaledSize)\n\tb = append(b, magic...)\n\tb = appendUint64(b, d.v1)\n\tb = appendUint64(b, d.v2)\n\tb = appendUint64(b, d.v3)\n\tb = appendUint64(b, d.v4)\n\tb = appendUint64(b, d.total)\n\tb = append(b, d.mem[:d.n]...)\n\tb = b[:len(b)+len(d.mem)-d.n]\n\treturn b, nil\n}\n\n// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.\nfunc (d *Digest) UnmarshalBinary(b []byte) error {\n\tif len(b) < len(magic) || string(b[:len(magic)]) != magic {\n\t\treturn errors.New(\"xxhash: invalid hash state identifier\")\n\t}\n\tif len(b) != marshaledSize {\n\t\treturn errors.New(\"xxhash: invalid hash state size\")\n\t}\n\tb = b[len(magic):]\n\tb, d.v1 = consumeUint64(b)\n\tb, d.v2 = consumeUint64(b)\n\tb, d.v3 = consumeUint64(b)\n\tb, d.v4 = consumeUint64(b)\n\tb, d.total = consumeUint64(b)\n\tcopy(d.mem[:], b)\n\td.n = int(d.total % uint64(len(d.mem)))\n\treturn nil\n}\n\nfunc appendUint64(b []byte, x uint64) []byte {\n\tvar a [8]byte\n\tbinary.LittleEndian.PutUint64(a[:], x)\n\treturn append(b, a[:]...)\n}\n\nfunc consumeUint64(b []byte) ([]byte, uint64) {\n\tx := u64(b)\n\treturn b[8:], x\n}\n\nfunc u64(b []byte) uint64 { return binary.LittleEndian.Uint64(b) }\nfunc u32(b []byte) uint32 { return binary.LittleEndian.Uint32(b) }\n\nfunc round(acc, input uint64) uint64 {\n\tacc += input * prime2\n\tacc = rol31(acc)\n\tacc *= prime1\n\treturn acc\n}\n\nfunc mergeRound(acc, val uint64) uint64 {\n\tval = round(0, val)\n\tacc ^= val\n\tacc = acc*prime1 + prime4\n\treturn acc\n}\n\nfunc rol1(x uint64) uint64  { return bits.RotateLeft64(x, 1) }\nfunc rol7(x uint64) uint64  { return bits.RotateLeft64(x, 7) }\nfunc rol11(x uint64) uint64 { return bits.RotateLeft64(x, 11) }\nfunc rol12(x uint64) uint64 { return bits.RotateLeft64(x, 12) }\nfunc rol18(x uint64) uint64 { return bits.RotateLeft64(x, 18) }\nfunc rol23(x uint64) uint64 { return bits.RotateLeft64(x, 23) }\nfunc rol27(x uint64) uint64 { return bits.RotateLeft64(x, 27) }\nfunc rol31(x uint64) uint64 { return bits.RotateLeft64(x, 31) }\n"
  },
  {
    "path": "internal/xxhash/xxhash_other.go",
    "content": "package xxhash\n\n// Sum64 computes the 64-bit xxHash digest of b.\nfunc Sum64(b []byte) uint64 {\n\t// A simpler version would be\n\t//   d := New()\n\t//   d.Write(b)\n\t//   return d.Sum64()\n\t// but this is faster, particularly for small inputs.\n\n\tn := len(b)\n\tvar h uint64\n\n\tif n >= 32 {\n\t\tv1 := prime1v + prime2\n\t\tv2 := prime2\n\t\tv3 := uint64(0)\n\t\tv4 := -prime1v\n\t\tfor len(b) >= 32 {\n\t\t\tv1 = round(v1, u64(b[0:8:len(b)]))\n\t\t\tv2 = round(v2, u64(b[8:16:len(b)]))\n\t\t\tv3 = round(v3, u64(b[16:24:len(b)]))\n\t\t\tv4 = round(v4, u64(b[24:32:len(b)]))\n\t\t\tb = b[32:len(b):len(b)]\n\t\t}\n\t\th = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4)\n\t\th = mergeRound(h, v1)\n\t\th = mergeRound(h, v2)\n\t\th = mergeRound(h, v3)\n\t\th = mergeRound(h, v4)\n\t} else {\n\t\th = prime5\n\t}\n\n\th += uint64(n)\n\n\ti, end := 0, len(b)\n\tfor ; i+8 <= end; i += 8 {\n\t\tk1 := round(0, u64(b[i:i+8:len(b)]))\n\t\th ^= k1\n\t\th = rol27(h)*prime1 + prime4\n\t}\n\tif i+4 <= end {\n\t\th ^= uint64(u32(b[i:i+4:len(b)])) * prime1\n\t\th = rol23(h)*prime2 + prime3\n\t\ti += 4\n\t}\n\tfor ; i < end; i++ {\n\t\th ^= uint64(b[i]) * prime5\n\t\th = rol11(h) * prime1\n\t}\n\n\th ^= h >> 33\n\th *= prime2\n\th ^= h >> 29\n\th *= prime3\n\th ^= h >> 32\n\n\treturn h\n}\n\nfunc writeBlocks(d *Digest, b []byte) int {\n\tv1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4\n\tn := len(b)\n\tfor len(b) >= 32 {\n\t\tv1 = round(v1, u64(b[0:8:len(b)]))\n\t\tv2 = round(v2, u64(b[8:16:len(b)]))\n\t\tv3 = round(v3, u64(b[16:24:len(b)]))\n\t\tv4 = round(v4, u64(b[24:32:len(b)]))\n\t\tb = b[32:len(b):len(b)]\n\t}\n\td.v1, d.v2, d.v3, d.v4 = v1, v2, v3, v4\n\treturn n - len(b)\n}\n"
  },
  {
    "path": "lib/README.md",
    "content": "This directory contains the TypeScript code that becomes the JavaScript API code in the `esbuild` and `esbuild-wasm` packages. It's automatically built during the build process for those packages (i.e. the top-level `make platform-neutral` and `make platform-wasm` commands).\n"
  },
  {
    "path": "lib/deno/external.d.ts",
    "content": "declare module \"https://deno.land/x/denoflate@1.2.1/mod.ts\" {\n  export function gunzip(input: Uint8Array): Uint8Array\n}\n\n// This is used by \"worker.ts\"\ndeclare let onmessage: (event: any) => void\n"
  },
  {
    "path": "lib/deno/mod.ts",
    "content": "import type * as types from \"../shared/types\"\nimport * as common from \"../shared/common\"\nimport * as ourselves from \"./mod\"\nimport * as denoflate from \"https://deno.land/x/denoflate@1.2.1/mod.ts\"\n\ndeclare const ESBUILD_VERSION: string\n\nexport let version = ESBUILD_VERSION\n\nexport let build: typeof types.build = (options: types.BuildOptions) =>\n  ensureServiceIsRunning().then(service =>\n    service.build(options))\n\nexport const context: typeof types.context = (options: types.BuildOptions) =>\n  ensureServiceIsRunning().then(service =>\n    service.context(options))\n\nexport const transform: typeof types.transform = (input: string | Uint8Array, options?: types.TransformOptions) =>\n  ensureServiceIsRunning().then(service =>\n    service.transform(input, options))\n\nexport const formatMessages: typeof types.formatMessages = (messages, options) =>\n  ensureServiceIsRunning().then(service =>\n    service.formatMessages(messages, options))\n\nexport const analyzeMetafile: typeof types.analyzeMetafile = (metafile, options) =>\n  ensureServiceIsRunning().then(service =>\n    service.analyzeMetafile(metafile, options))\n\nexport const buildSync: typeof types.buildSync = () => {\n  throw new Error(`The \"buildSync\" API does not work in Deno`)\n}\n\nexport const transformSync: typeof types.transformSync = () => {\n  throw new Error(`The \"transformSync\" API does not work in Deno`)\n}\n\nexport const formatMessagesSync: typeof types.formatMessagesSync = () => {\n  throw new Error(`The \"formatMessagesSync\" API does not work in Deno`)\n}\n\nexport const analyzeMetafileSync: typeof types.analyzeMetafileSync = () => {\n  throw new Error(`The \"analyzeMetafileSync\" API does not work in Deno`)\n}\n\nexport const stop = async () => {\n  if (stopService) await stopService()\n}\n\nlet initializeWasCalled = false\n\nexport const initialize: typeof types.initialize = async (options) => {\n  options = common.validateInitializeOptions(options || {})\n  if (options.wasmURL) throw new Error(`The \"wasmURL\" option only works in the browser`)\n  if (options.wasmModule) throw new Error(`The \"wasmModule\" option only works in the browser`)\n  if (options.worker) throw new Error(`The \"worker\" option only works in the browser`)\n  if (initializeWasCalled) throw new Error('Cannot call \"initialize\" more than once')\n  await ensureServiceIsRunning()\n  initializeWasCalled = true\n}\n\nasync function installFromNPM(name: string, subpath: string): Promise<string> {\n  const { finalPath, finalDir } = getCachePath(name)\n  try {\n    await Deno.stat(finalPath)\n    return finalPath\n  } catch (e) {\n  }\n\n  const npmRegistry = Deno.env.get(\"NPM_CONFIG_REGISTRY\") || \"https://registry.npmjs.org\"\n  const url = `${npmRegistry}/${name}/-/${name.replace(\"@esbuild/\", \"\")}-${version}.tgz`\n  const buffer = await fetch(url).then(r => r.arrayBuffer())\n  const executable = extractFileFromTarGzip(new Uint8Array(buffer), subpath)\n\n  await Deno.mkdir(finalDir, {\n    recursive: true,\n    mode: 0o700, // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html\n  })\n\n  await Deno.writeFile(finalPath, executable, { mode: 0o755 })\n  return finalPath\n}\n\nfunction getCachePath(name: string): { finalPath: string, finalDir: string } {\n  let baseDir: string | undefined\n\n  switch (Deno.build.os) {\n    case 'darwin':\n      baseDir = Deno.env.get('HOME')\n      if (baseDir) baseDir += '/Library/Caches'\n      break\n\n    case 'windows':\n      baseDir = Deno.env.get('LOCALAPPDATA')\n      if (!baseDir) {\n        baseDir = Deno.env.get('USERPROFILE')\n        if (baseDir) baseDir += '/AppData/Local'\n      }\n      if (baseDir) baseDir += '/Cache'\n      break\n\n    case 'linux':\n      // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html\n      const xdg = Deno.env.get('XDG_CACHE_HOME')\n      if (xdg && xdg[0] === '/') baseDir = xdg\n      break\n  }\n\n  if (!baseDir) {\n    baseDir = Deno.env.get('HOME')\n    if (baseDir) baseDir += '/.cache'\n  }\n\n  if (!baseDir) throw new Error('Failed to find cache directory')\n  const finalDir = baseDir + `/esbuild/bin`\n  const finalPath = finalDir + `/${name.replace('/', '-')}@${version}`\n  return { finalPath, finalDir }\n}\n\nfunction extractFileFromTarGzip(buffer: Uint8Array, file: string): Uint8Array {\n  try {\n    buffer = denoflate.gunzip(buffer)\n  } catch (err: any) {\n    throw new Error(`Invalid gzip data in archive: ${err && err.message || err}`)\n  }\n  let str = (i: number, n: number) => String.fromCharCode(...buffer.subarray(i, i + n)).replace(/\\0.*$/, '')\n  let offset = 0\n  file = `package/${file}`\n  while (offset < buffer.length) {\n    let name = str(offset, 100)\n    let size = parseInt(str(offset + 124, 12), 8)\n    offset += 512\n    if (!isNaN(size)) {\n      if (name === file) return buffer.subarray(offset, offset + size)\n      offset += (size + 511) & ~511\n    }\n  }\n  throw new Error(`Could not find ${JSON.stringify(file)} in archive`)\n}\n\nasync function install(): Promise<string> {\n  const overridePath = Deno.env.get('ESBUILD_BINARY_PATH')\n  if (overridePath) return overridePath\n\n  const platformKey = Deno.build.target\n  const knownWindowsPackages: Record<string, string> = {\n    'x86_64-pc-windows-msvc': '@esbuild/win32-x64',\n  }\n  const knownUnixlikePackages: Record<string, string> = {\n    // These are the only platforms that Deno supports\n    'aarch64-apple-darwin': '@esbuild/darwin-arm64',\n    'aarch64-unknown-linux-gnu': '@esbuild/linux-arm64',\n    'x86_64-apple-darwin': '@esbuild/darwin-x64',\n    'x86_64-unknown-linux-gnu': '@esbuild/linux-x64',\n\n    // These platforms are not supported by Deno\n    'aarch64-linux-android': '@esbuild/android-arm64',\n    'x86_64-unknown-freebsd': '@esbuild/freebsd-x64',\n    \"x86_64-alpine-linux-musl\": '@esbuild/linux-x64',\n  }\n\n  // Pick a package to install\n  if (platformKey in knownWindowsPackages) {\n    return await installFromNPM(knownWindowsPackages[platformKey], 'esbuild.exe')\n  } else if (platformKey in knownUnixlikePackages) {\n    return await installFromNPM(knownUnixlikePackages[platformKey], 'bin/esbuild')\n  } else {\n    throw new Error(`Unsupported platform: ${platformKey}`)\n  }\n}\n\ninterface Service {\n  build: typeof types.build\n  context: typeof types.context\n  transform: typeof types.transform\n  formatMessages: typeof types.formatMessages\n  analyzeMetafile: typeof types.analyzeMetafile\n}\n\nlet defaultWD = Deno.cwd()\nlet longLivedService: Promise<Service> | undefined\nlet stopService: (() => Promise<void>) | undefined\n\n// Declare a common subprocess API for the two implementations below\ntype SpawnFn = (cmd: string, options: {\n  args: string[]\n  stdin: 'piped' | 'inherit'\n  stdout: 'piped' | 'inherit'\n  stderr: 'inherit'\n}) => {\n  write(bytes: Uint8Array): void\n  read(): Promise<Uint8Array | null>\n  close(): Promise<void> | void\n  status(): Promise<{ code: number }>\n}\n\n// Deno ≥1.40\nconst spawnNew: SpawnFn = (cmd, { args, stdin, stdout, stderr }) => {\n  const child = new Deno.Command(cmd, {\n    args,\n    cwd: defaultWD,\n    stdin,\n    stdout,\n    stderr,\n  }).spawn()\n  // Note: Need to check for \"piped\" in Deno ≥1.31.0 to avoid a crash\n  const writer = stdin === 'piped' ? child.stdin.getWriter() : null\n  const reader = stdout === 'piped' ? child.stdout.getReader() : null\n  return {\n    write: writer ? bytes => writer.write(bytes) : () => Promise.resolve(),\n    read: reader ? () => reader.read().then(x => x.value || null) : () => Promise.resolve(null),\n    close: async () => {\n      // We can't call \"kill()\" because it doesn't seem to work. Tests will\n      // still fail with \"A child process was opened during the test, but not\n      // closed during the test\" even though we kill the child process.\n      //\n      // And we can't call both \"writer.close()\" and \"kill()\" because then\n      // there's a race as the child process exits when stdin is closed, and\n      // \"kill()\" fails when the child process has already been killed.\n      //\n      // So instead we just call \"writer.close()\" and then hope that this\n      // causes the child process to exit. It won't work if the stdin consumer\n      // thread in the child process is hung or busy, but that may be the best\n      // we can do.\n      //\n      // See this for more info: https://github.com/evanw/esbuild/pull/3611\n      if (writer) await writer.close()\n      if (reader) await reader.cancel()\n\n      // Wait for the process to exit. The new \"kill()\" API doesn't flag the\n      // process as having exited because processes can technically ignore the\n      // kill signal. Without this, Deno will fail tests that use esbuild with\n      // an error because the test spawned a process but didn't wait for it.\n      await child.status\n    },\n    status: () => child.status,\n  }\n}\n\n// Deno <1.40\nconst spawnOld: SpawnFn = (cmd, { args, stdin, stdout, stderr }) => {\n  const child = Deno.run({\n    cmd: [cmd].concat(args),\n    cwd: defaultWD,\n    stdin,\n    stdout,\n    stderr,\n  })\n  const stdoutBuffer = new Uint8Array(4 * 1024 * 1024)\n  let writeQueue: Uint8Array[] = []\n  let isQueueLocked = false\n\n  // We need to keep calling \"write()\" until it actually writes the data\n  const startWriteFromQueueWorker = () => {\n    if (isQueueLocked || writeQueue.length === 0) return\n    isQueueLocked = true\n    child.stdin!.write(writeQueue[0]).then(bytesWritten => {\n      isQueueLocked = false\n      if (bytesWritten === writeQueue[0].length) writeQueue.shift()\n      else writeQueue[0] = writeQueue[0].subarray(bytesWritten)\n      startWriteFromQueueWorker()\n    })\n  }\n\n  return {\n    write: bytes => {\n      writeQueue.push(bytes)\n      startWriteFromQueueWorker()\n    },\n    read: () => child.stdout!.read(stdoutBuffer).then(n => n === null ? null : stdoutBuffer.subarray(0, n)),\n    close: () => {\n      child.stdin!.close()\n      child.stdout!.close()\n      child.close()\n    },\n    status: () => child.status(),\n  }\n}\n\n// This is a shim for \"Deno.run\" for newer versions of Deno\nconst spawn: SpawnFn = Deno.Command ? spawnNew : spawnOld\n\nconst ensureServiceIsRunning = (): Promise<Service> => {\n  if (!longLivedService) {\n    longLivedService = (async (): Promise<Service> => {\n      const binPath = await install()\n      const isTTY = Deno.stderr.isTerminal\n        ? Deno.stderr.isTerminal() // Deno ≥1.40\n        : Deno.isatty(Deno.stderr.rid) // Deno <1.40\n\n      const child = spawn(binPath, {\n        args: [`--service=${version}`],\n        stdin: 'piped',\n        stdout: 'piped',\n        stderr: 'inherit',\n      })\n\n      stopService = async () => {\n        // Close all resources related to the subprocess.\n        await child.close()\n        initializeWasCalled = false\n        longLivedService = undefined\n        stopService = undefined\n      }\n\n      const { readFromStdout, afterClose, service } = common.createChannel({\n        writeToStdin(bytes) {\n          child.write(bytes)\n        },\n        isSync: false,\n        hasFS: true,\n        esbuild: ourselves,\n      })\n\n      const readMoreStdout = () => child.read().then(buffer => {\n        if (buffer === null) {\n          afterClose(null)\n        } else {\n          readFromStdout(buffer)\n          readMoreStdout()\n        }\n      }).catch(e => {\n        if (e instanceof Deno.errors.Interrupted || e instanceof Deno.errors.BadResource) {\n          // ignore the error if read was interrupted (stdout was closed)\n          afterClose(e)\n        } else {\n          throw e\n        }\n      })\n      readMoreStdout()\n\n      return {\n        build: (options: types.BuildOptions) =>\n          new Promise<types.BuildResult>((resolve, reject) => {\n            service.buildOrContext({\n              callName: 'build',\n              refs: null,\n              options,\n              isTTY,\n              defaultWD,\n              callback: (err, res) => err ? reject(err) : resolve(res as types.BuildResult),\n            })\n          }),\n\n        context: (options: types.BuildOptions) =>\n          new Promise<types.BuildContext>((resolve, reject) =>\n            service.buildOrContext({\n              callName: 'context',\n              refs: null,\n              options,\n              isTTY,\n              defaultWD,\n              callback: (err, res) => err ? reject(err) : resolve(res as types.BuildContext),\n            })),\n\n        transform: (input: string | Uint8Array, options?: types.TransformOptions) =>\n          new Promise<types.TransformResult>((resolve, reject) =>\n            service.transform({\n              callName: 'transform',\n              refs: null,\n              input,\n              options: options || {},\n              isTTY,\n              fs: {\n                readFile(tempFile, callback) {\n                  Deno.readFile(tempFile).then(\n                    bytes => {\n                      let text = new TextDecoder().decode(bytes)\n                      try {\n                        Deno.remove(tempFile)\n                      } catch (e) {\n                      }\n                      callback(null, text)\n                    },\n                    err => callback(err, null),\n                  )\n                },\n                writeFile(contents, callback) {\n                  Deno.makeTempFile().then(\n                    tempFile => Deno.writeFile(tempFile, typeof contents === 'string' ? new TextEncoder().encode(contents) : contents).then(\n                      () => callback(tempFile),\n                      () => callback(null)),\n                    () => callback(null))\n                },\n              },\n              callback: (err, res) => err ? reject(err) : resolve(res!),\n            })),\n\n        formatMessages: (messages, options) =>\n          new Promise((resolve, reject) =>\n            service.formatMessages({\n              callName: 'formatMessages',\n              refs: null,\n              messages,\n              options,\n              callback: (err, res) => err ? reject(err) : resolve(res!),\n            })),\n\n        analyzeMetafile: (metafile, options) =>\n          new Promise((resolve, reject) =>\n            service.analyzeMetafile({\n              callName: 'analyzeMetafile',\n              refs: null,\n              metafile: typeof metafile === 'string' ? metafile : JSON.stringify(metafile),\n              options,\n              callback: (err, res) => err ? reject(err) : resolve(res!),\n            })),\n      }\n    })()\n  }\n  return longLivedService\n}\n\n// If we're called as the main script, forward the CLI to the underlying executable\nif (import.meta.main) {\n  spawn(await install(), {\n    args: Deno.args,\n    stdin: 'inherit',\n    stdout: 'inherit',\n    stderr: 'inherit',\n  }).status().then(({ code }) => {\n    Deno.exit(code)\n  })\n}\n"
  },
  {
    "path": "lib/deno/wasm.ts",
    "content": "import type * as types from \"../shared/types\"\nimport * as common from \"../shared/common\"\nimport * as ourselves from \"./wasm\"\n\ninterface Go {\n  _scheduledTimeouts: Map<number, ReturnType<typeof setTimeout>>\n}\n\ndeclare const ESBUILD_VERSION: string\ndeclare let WEB_WORKER_SOURCE_CODE: string\ndeclare let WEB_WORKER_FUNCTION: (postMessage: (data: Uint8Array) => void) => (event: { data: Uint8Array | ArrayBuffer | WebAssembly.Module }) => Go\n\nexport let version = ESBUILD_VERSION\n\nexport let build: typeof types.build = (options: types.BuildOptions) =>\n  ensureServiceIsRunning().then(service =>\n    service.build(options))\n\nexport const context: typeof types.context = (options: types.BuildOptions) =>\n  ensureServiceIsRunning().then(service =>\n    service.context(options))\n\nexport const transform: typeof types.transform = (input: string | Uint8Array, options?: types.TransformOptions) =>\n  ensureServiceIsRunning().then(service =>\n    service.transform(input, options))\n\nexport const formatMessages: typeof types.formatMessages = (messages, options) =>\n  ensureServiceIsRunning().then(service =>\n    service.formatMessages(messages, options))\n\nexport const analyzeMetafile: typeof types.analyzeMetafile = (metafile, options) =>\n  ensureServiceIsRunning().then(service =>\n    service.analyzeMetafile(metafile, options))\n\nexport const buildSync: typeof types.buildSync = () => {\n  throw new Error(`The \"buildSync\" API does not work in Deno`)\n}\n\nexport const transformSync: typeof types.transformSync = () => {\n  throw new Error(`The \"transformSync\" API does not work in Deno`)\n}\n\nexport const formatMessagesSync: typeof types.formatMessagesSync = () => {\n  throw new Error(`The \"formatMessagesSync\" API does not work in Deno`)\n}\n\nexport const analyzeMetafileSync: typeof types.analyzeMetafileSync = () => {\n  throw new Error(`The \"analyzeMetafileSync\" API does not work in Deno`)\n}\n\nexport const stop = () => {\n  if (stopService) stopService()\n  return Promise.resolve()\n}\n\ninterface Service {\n  build: typeof types.build\n  context: typeof types.context\n  transform: typeof types.transform\n  formatMessages: typeof types.formatMessages\n  analyzeMetafile: typeof types.analyzeMetafile\n}\n\nlet initializePromise: Promise<Service> | undefined\nlet stopService: (() => void) | undefined\n\nlet ensureServiceIsRunning = (): Promise<Service> => {\n  return initializePromise || startRunningService('esbuild.wasm', undefined, true)\n}\n\nexport const initialize: typeof types.initialize = async (options) => {\n  options = common.validateInitializeOptions(options || {})\n  let wasmURL = options.wasmURL\n  let wasmModule = options.wasmModule\n  let useWorker = options.worker !== false\n  if (initializePromise) throw new Error('Cannot call \"initialize\" more than once')\n  initializePromise = startRunningService(wasmURL || 'esbuild.wasm', wasmModule, useWorker)\n  initializePromise.catch(() => {\n    // Let the caller try again if this fails\n    initializePromise = void 0\n  })\n  await initializePromise\n}\n\nconst startRunningService = async (wasmURL: string | URL, wasmModule: WebAssembly.Module | undefined, useWorker: boolean): Promise<Service> => {\n  let worker: {\n    onmessage?: ((event: any) => void) | null | undefined\n    postMessage: (data: Uint8Array | ArrayBuffer | WebAssembly.Module) => void\n    terminate: () => void\n  }\n\n  if (useWorker) {\n    // Run esbuild off the main thread\n    let blob = new Blob([`onmessage=${WEB_WORKER_SOURCE_CODE}(postMessage)`], { type: 'text/javascript' })\n    worker = new Worker(URL.createObjectURL(blob), { type: 'module' })\n  } else {\n    // Run esbuild on the main thread\n    let onmessage = WEB_WORKER_FUNCTION((data: Uint8Array) => worker.onmessage!({ data }))\n    let go: Go | undefined\n    worker = {\n      onmessage: null,\n      postMessage: data => setTimeout(() => go = onmessage({ data })),\n      terminate() {\n        if (go)\n          for (let timeout of go._scheduledTimeouts.values())\n            clearTimeout(timeout)\n      },\n    }\n  }\n\n  let firstMessageResolve: (value: void) => void\n  let firstMessageReject: (error: any) => void\n\n  const firstMessagePromise = new Promise((resolve, reject) => {\n    firstMessageResolve = resolve\n    firstMessageReject = reject\n  })\n\n  worker.onmessage = ({ data: error }) => {\n    worker.onmessage = ({ data }) => readFromStdout(data)\n    if (error) firstMessageReject(error)\n    else firstMessageResolve()\n  }\n\n  worker.postMessage(wasmModule || new URL(wasmURL, import.meta.url).toString())\n\n  let { readFromStdout, service } = common.createChannel({\n    writeToStdin(bytes) {\n      worker.postMessage(bytes)\n    },\n    isSync: false,\n    hasFS: false,\n    esbuild: ourselves,\n  })\n\n  // This will throw if WebAssembly module instantiation fails\n  await firstMessagePromise\n\n  stopService = () => {\n    worker.terminate()\n    initializePromise = undefined\n    stopService = undefined\n  }\n\n  return {\n    build: (options: types.BuildOptions) =>\n      new Promise<types.BuildResult>((resolve, reject) =>\n        service.buildOrContext({\n          callName: 'build',\n          refs: null,\n          options,\n          isTTY: false,\n          defaultWD: '/',\n          callback: (err, res) => err ? reject(err) : resolve(res as types.BuildResult),\n        })),\n\n    context: (options: types.BuildOptions) =>\n      new Promise<types.BuildContext>((resolve, reject) =>\n        service.buildOrContext({\n          callName: 'context',\n          refs: null,\n          options,\n          isTTY: false,\n          defaultWD: '/',\n          callback: (err, res) => err ? reject(err) : resolve(res as types.BuildContext),\n        })),\n\n    transform: (input: string | Uint8Array, options?: types.TransformOptions) =>\n      new Promise<types.TransformResult>((resolve, reject) =>\n        service.transform({\n          callName: 'transform',\n          refs: null,\n          input,\n          options: options || {},\n          isTTY: false,\n          fs: {\n            readFile(_, callback) { callback(new Error('Internal error'), null); },\n            writeFile(_, callback) { callback(null); },\n          },\n          callback: (err, res) => err ? reject(err) : resolve(res!),\n        })),\n\n    formatMessages: (messages, options) =>\n      new Promise((resolve, reject) =>\n        service.formatMessages({\n          callName: 'formatMessages',\n          refs: null,\n          messages,\n          options,\n          callback: (err, res) => err ? reject(err) : resolve(res!),\n        })),\n\n    analyzeMetafile: (metafile, options) =>\n      new Promise((resolve, reject) =>\n        service.analyzeMetafile({\n          callName: 'analyzeMetafile',\n          refs: null,\n          metafile: typeof metafile === 'string' ? metafile : JSON.stringify(metafile),\n          options,\n          callback: (err, res) => err ? reject(err) : resolve(res!),\n        })),\n  }\n}\n"
  },
  {
    "path": "lib/npm/browser.ts",
    "content": "import type * as types from \"../shared/types\"\nimport * as common from \"../shared/common\"\nimport * as ourselves from \"./browser\"\n\ninterface Go {\n  _scheduledTimeouts: Map<number, ReturnType<typeof setTimeout>>\n}\n\ndeclare const ESBUILD_VERSION: string\ndeclare let WEB_WORKER_SOURCE_CODE: string\ndeclare let WEB_WORKER_FUNCTION: (postMessage: (data: Uint8Array) => void) => (event: { data: Uint8Array | ArrayBuffer | WebAssembly.Module }) => Go\n\nexport let version = ESBUILD_VERSION\n\nexport let build: typeof types.build = (options: types.BuildOptions) =>\n  ensureServiceIsRunning().build(options)\n\nexport let context: typeof types.context = (options: types.BuildOptions) =>\n  ensureServiceIsRunning().context(options)\n\nexport const transform: typeof types.transform = (input: string | Uint8Array, options?: types.TransformOptions) =>\n  ensureServiceIsRunning().transform(input, options)\n\nexport const formatMessages: typeof types.formatMessages = (messages, options) =>\n  ensureServiceIsRunning().formatMessages(messages, options)\n\nexport const analyzeMetafile: typeof types.analyzeMetafile = (metafile, options) =>\n  ensureServiceIsRunning().analyzeMetafile(metafile, options)\n\nexport const buildSync: typeof types.buildSync = () => {\n  throw new Error(`The \"buildSync\" API only works in node`)\n}\n\nexport const transformSync: typeof types.transformSync = () => {\n  throw new Error(`The \"transformSync\" API only works in node`)\n}\n\nexport const formatMessagesSync: typeof types.formatMessagesSync = () => {\n  throw new Error(`The \"formatMessagesSync\" API only works in node`)\n}\n\nexport const analyzeMetafileSync: typeof types.analyzeMetafileSync = () => {\n  throw new Error(`The \"analyzeMetafileSync\" API only works in node`)\n}\n\nexport const stop = () => {\n  if (stopService) stopService()\n  return Promise.resolve()\n}\n\ninterface Service {\n  build: typeof types.build\n  context: typeof types.context\n  transform: typeof types.transform\n  formatMessages: typeof types.formatMessages\n  analyzeMetafile: typeof types.analyzeMetafile\n}\n\nlet initializePromise: Promise<void> | undefined\nlet stopService: (() => void) | undefined\nlet longLivedService: Service | undefined\n\nlet ensureServiceIsRunning = (): Service => {\n  if (longLivedService) return longLivedService\n  if (initializePromise) throw new Error('You need to wait for the promise returned from \"initialize\" to be resolved before calling this')\n  throw new Error('You need to call \"initialize\" before calling this')\n}\n\nexport const initialize: typeof types.initialize = options => {\n  options = common.validateInitializeOptions(options || {})\n  let wasmURL = options.wasmURL\n  let wasmModule = options.wasmModule\n  let useWorker = options.worker !== false\n  if (!wasmURL && !wasmModule) throw new Error('Must provide either the \"wasmURL\" option or the \"wasmModule\" option')\n  if (initializePromise) throw new Error('Cannot call \"initialize\" more than once')\n  initializePromise = startRunningService(wasmURL || '', wasmModule, useWorker)\n  initializePromise.catch(() => {\n    // Let the caller try again if this fails\n    initializePromise = void 0\n  })\n  return initializePromise\n}\n\nconst startRunningService = async (wasmURL: string | URL, wasmModule: WebAssembly.Module | undefined, useWorker: boolean): Promise<void> => {\n  let worker: {\n    onmessage: ((event: any) => void) | null\n    postMessage: (data: Uint8Array | ArrayBuffer | WebAssembly.Module) => void\n    terminate: () => void\n  }\n\n  let rejectAllWith: (error: unknown) => void\n  const rejectAllPromise = new Promise(resolve => rejectAllWith = resolve)\n\n  if (useWorker) {\n    // Run esbuild off the main thread\n    let blob = new Blob([`onmessage=${WEB_WORKER_SOURCE_CODE}(postMessage)`], { type: 'text/javascript' })\n    worker = new Worker(URL.createObjectURL(blob))\n  } else {\n    // Run esbuild on the main thread\n    let onmessage = WEB_WORKER_FUNCTION((data: Uint8Array) => worker.onmessage!({ data }))\n    let go: Go | undefined\n    worker = {\n      onmessage: null,\n      postMessage: data => setTimeout(() => {\n        try {\n          go = onmessage({ data })\n        } catch (error) {\n          rejectAllWith(error) // Catch strange crashes (e.g. stack overflow)\n        }\n      }),\n      terminate() {\n        if (go)\n          for (let timeout of go._scheduledTimeouts.values())\n            clearTimeout(timeout)\n      },\n    }\n  }\n\n  let firstMessageResolve: (value: void) => void\n  let firstMessageReject: (error: any) => void\n\n  const firstMessagePromise = new Promise((resolve, reject) => {\n    firstMessageResolve = resolve\n    firstMessageReject = reject\n  })\n\n  worker.onmessage = ({ data: error }) => {\n    worker.onmessage = ({ data }) => readFromStdout(data)\n    if (error) firstMessageReject(error)\n    else firstMessageResolve()\n  }\n\n  worker.postMessage(wasmModule || new URL(wasmURL, location.href).toString())\n\n  let { readFromStdout, service } = common.createChannel({\n    writeToStdin(bytes) {\n      worker.postMessage(bytes)\n    },\n    isSync: false,\n    hasFS: false,\n    esbuild: ourselves,\n  })\n\n  // This will throw if WebAssembly module instantiation fails\n  await firstMessagePromise\n\n  stopService = () => {\n    worker.terminate()\n    initializePromise = undefined\n    stopService = undefined\n    longLivedService = undefined\n  }\n\n  longLivedService = {\n    build: (options: types.BuildOptions) =>\n      new Promise<types.BuildResult>((resolve, reject) => {\n        rejectAllPromise.then(reject)\n        service.buildOrContext({\n          callName: 'build',\n          refs: null,\n          options,\n          isTTY: false,\n          defaultWD: '/',\n          callback: (err, res) => err ? reject(err) : resolve(res as types.BuildResult),\n        })\n      }),\n\n    context: (options: types.BuildOptions) =>\n      new Promise<types.BuildContext>((resolve, reject) => {\n        rejectAllPromise.then(reject)\n        service.buildOrContext({\n          callName: 'context',\n          refs: null,\n          options,\n          isTTY: false,\n          defaultWD: '/',\n          callback: (err, res) => err ? reject(err) : resolve(res as types.BuildContext),\n        })\n      }),\n\n    transform: (input: string | Uint8Array, options?: types.TransformOptions) =>\n      new Promise<types.TransformResult>((resolve, reject) => {\n        rejectAllPromise.then(reject)\n        service.transform({\n          callName: 'transform',\n          refs: null,\n          input,\n          options: options || {},\n          isTTY: false,\n          fs: {\n            readFile(_, callback) { callback(new Error('Internal error'), null); },\n            writeFile(_, callback) { callback(null); },\n          },\n          callback: (err, res) => err ? reject(err) : resolve(res!),\n        })\n      }),\n\n    formatMessages: (messages, options) =>\n      new Promise((resolve, reject) => {\n        rejectAllPromise.then(reject)\n        service.formatMessages({\n          callName: 'formatMessages',\n          refs: null,\n          messages,\n          options,\n          callback: (err, res) => err ? reject(err) : resolve(res!),\n        })\n      }),\n\n    analyzeMetafile: (metafile, options) =>\n      new Promise((resolve, reject) => {\n        rejectAllPromise.then(reject)\n        service.analyzeMetafile({\n          callName: 'analyzeMetafile',\n          refs: null,\n          metafile: typeof metafile === 'string' ? metafile : JSON.stringify(metafile),\n          options,\n          callback: (err, res) => err ? reject(err) : resolve(res!),\n        })\n      }),\n  }\n}\n\n// Export this module's exports as an export named \"default\" to try to work\n// around problems due to the \"default\" import mess. See the comment in\n// \"node.ts\" for more detail.\nexport default ourselves\n"
  },
  {
    "path": "lib/npm/node-install.ts",
    "content": "import { downloadedBinPath, ESBUILD_BINARY_PATH, isValidBinaryPath, pkgAndSubpathForCurrentPlatform } from './node-platform'\n\nimport fs = require('fs')\nimport os = require('os')\nimport path = require('path')\nimport zlib = require('zlib')\nimport https = require('https')\nimport child_process = require('child_process')\n\nconst versionFromPackageJSON: string = require(path.join(__dirname, 'package.json')).version\nconst toPath = path.join(__dirname, 'bin', 'esbuild')\nlet isToPathJS = true\n\nfunction validateBinaryVersion(...command: string[]): void {\n  command.push('--version')\n  let stdout: string\n  try {\n    stdout = child_process.execFileSync(command.shift()!, command, {\n      // Without this, this install script strangely crashes with the error\n      // \"EACCES: permission denied, write\" but only on Ubuntu Linux when node is\n      // installed from the Snap Store. This is not a problem when you download\n      // the official version of node. The problem appears to be that stderr\n      // (i.e. file descriptor 2) isn't writable?\n      //\n      // More info:\n      // - https://snapcraft.io/ (what the Snap Store is)\n      // - https://nodejs.org/dist/ (download the official version of node)\n      // - https://github.com/evanw/esbuild/issues/1711#issuecomment-1027554035\n      //\n      stdio: 'pipe',\n    }).toString().trim()\n  } catch (err) {\n    if (os.platform() === 'darwin' && /_SecTrustEvaluateWithError/.test(err + '')) {\n      let os = 'this version of macOS'\n      try {\n        os = 'macOS ' + child_process.execFileSync('sw_vers', ['-productVersion']).toString().trim()\n      } catch {\n      }\n      throw new Error(`The \"esbuild\" package cannot be installed because ${os} is too outdated.\n\nThe Go compiler (which esbuild relies on) no longer supports ${os},\nwhich means the \"esbuild\" binary executable can't be run. You can either:\n\n  * Update your version of macOS to one that the Go compiler supports\n  * Use the \"esbuild-wasm\" package instead of the \"esbuild\" package\n  * Build esbuild yourself using an older version of the Go compiler\n`)\n    }\n    throw err\n  }\n  if (stdout !== versionFromPackageJSON) {\n    throw new Error(`Expected ${JSON.stringify(versionFromPackageJSON)} but got ${JSON.stringify(stdout)}`)\n  }\n}\n\nfunction isYarn(): boolean {\n  const { npm_config_user_agent } = process.env\n  if (npm_config_user_agent) {\n    return /\\byarn\\//.test(npm_config_user_agent)\n  }\n  return false\n}\n\nfunction fetch(url: string): Promise<Buffer> {\n  return new Promise((resolve, reject) => {\n    https.get(url, res => {\n      if ((res.statusCode === 301 || res.statusCode === 302) && res.headers.location)\n        return fetch(res.headers.location).then(resolve, reject)\n      if (res.statusCode !== 200)\n        return reject(new Error(`Server responded with ${res.statusCode}`))\n      let chunks: Buffer[] = []\n      res.on('data', chunk => chunks.push(chunk))\n      res.on('end', () => resolve(Buffer.concat(chunks)))\n    }).on('error', reject)\n  })\n}\n\nfunction extractFileFromTarGzip(buffer: Buffer, subpath: string): Buffer {\n  try {\n    buffer = zlib.unzipSync(buffer)\n  } catch (err: any) {\n    throw new Error(`Invalid gzip data in archive: ${err && err.message || err}`)\n  }\n  let str = (i: number, n: number) => String.fromCharCode(...buffer.subarray(i, i + n)).replace(/\\0.*$/, '')\n  let offset = 0\n  subpath = `package/${subpath}`\n  while (offset < buffer.length) {\n    let name = str(offset, 100)\n    let size = parseInt(str(offset + 124, 12), 8)\n    offset += 512\n    if (!isNaN(size)) {\n      if (name === subpath) return buffer.subarray(offset, offset + size)\n      offset += (size + 511) & ~511\n    }\n  }\n  throw new Error(`Could not find ${JSON.stringify(subpath)} in archive`)\n}\n\nfunction installUsingNPM(pkg: string, subpath: string, binPath: string): void {\n  // Erase \"npm_config_global\" so that \"npm install --global esbuild\" works.\n  // Otherwise this nested \"npm install\" will also be global, and the install\n  // will deadlock waiting for the global installation lock.\n  const env = { ...process.env, npm_config_global: undefined }\n\n  // Create a temporary directory inside the \"esbuild\" package with an empty\n  // \"package.json\" file. We'll use this to run \"npm install\" in.\n  const esbuildLibDir = path.dirname(require.resolve('esbuild'))\n  const installDir = path.join(esbuildLibDir, 'npm-install')\n  fs.mkdirSync(installDir)\n  try {\n    fs.writeFileSync(path.join(installDir, 'package.json'), '{}')\n\n    // Run \"npm install\" in the temporary directory which should download the\n    // desired package. Try to avoid unnecessary log output. This uses the \"npm\"\n    // command instead of a HTTP request so that it hopefully works in situations\n    // where HTTP requests are blocked but the \"npm\" command still works due to,\n    // for example, a custom configured npm registry and special firewall rules.\n    child_process.execSync(`npm install --loglevel=error --prefer-offline --no-audit --progress=false ${pkg}@${versionFromPackageJSON}`,\n      { cwd: installDir, stdio: 'pipe', env })\n\n    // Move the downloaded binary executable into place. The destination path\n    // is the same one that the JavaScript API code uses so it will be able to\n    // find the binary executable here later.\n    const installedBinPath = path.join(installDir, 'node_modules', pkg, subpath)\n    fs.renameSync(installedBinPath, binPath)\n  } finally {\n    // Try to clean up afterward so we don't unnecessarily waste file system\n    // space. Leaving nested \"node_modules\" directories can also be problematic\n    // for certain tools that scan over the file tree and expect it to have a\n    // certain structure.\n    try {\n      removeRecursive(installDir)\n    } catch {\n      // Removing a file or directory can randomly break on Windows, returning\n      // EBUSY for an arbitrary length of time. I think this happens when some\n      // other program has that file or directory open (e.g. an anti-virus\n      // program). This is fine on Unix because the OS just unlinks the entry\n      // but keeps the reference around until it's unused. There's nothing we\n      // can do in this case so we just leave the directory there.\n    }\n  }\n}\n\nfunction removeRecursive(dir: string): void {\n  for (const entry of fs.readdirSync(dir)) {\n    const entryPath = path.join(dir, entry)\n    let stats\n    try {\n      stats = fs.lstatSync(entryPath)\n    } catch {\n      continue; // Guard against https://github.com/nodejs/node/issues/4760\n    }\n    if (stats.isDirectory()) removeRecursive(entryPath)\n    else fs.unlinkSync(entryPath)\n  }\n  fs.rmdirSync(dir)\n}\n\nfunction applyManualBinaryPathOverride(overridePath: string): void {\n  // Patch the CLI use case (the \"esbuild\" command)\n  const pathString = JSON.stringify(overridePath)\n  fs.writeFileSync(toPath, `#!/usr/bin/env node\\n` +\n    `require('child_process').execFileSync(${pathString}, process.argv.slice(2), { stdio: 'inherit' });\\n`)\n\n  // Patch the JS API use case (the \"require('esbuild')\" workflow)\n  const libMain = path.join(__dirname, 'lib', 'main.js')\n  const code = fs.readFileSync(libMain, 'utf8')\n  fs.writeFileSync(libMain, `var ESBUILD_BINARY_PATH = ${pathString};\\n${code}`)\n}\n\nfunction maybeOptimizePackage(binPath: string): void {\n  // This package contains a \"bin/esbuild\" JavaScript file that finds and runs\n  // the appropriate binary executable. However, this means that running the\n  // \"esbuild\" command runs another instance of \"node\" which is way slower than\n  // just running the binary executable directly.\n  //\n  // Here we optimize for this by replacing the JavaScript file with the binary\n  // executable at install time. This optimization does not work on Windows\n  // because on Windows the binary executable must be called \"esbuild.exe\"\n  // instead of \"esbuild\".\n  //\n  // This also doesn't work with Yarn both because of lack of support for binary\n  // files in Yarn 2+ (see https://github.com/yarnpkg/berry/issues/882) and\n  // because Yarn (even Yarn 1?) may run the same install scripts in the same\n  // place multiple times from different platforms, especially when people use\n  // Docker. Avoid idempotency issues by just not optimizing when using Yarn.\n  //\n  // This also doesn't work with WASM because it is not a single binary executable\n  // file. See https://github.com/evanw/esbuild/issues/4209 for more info.\n  //\n  // This optimization also doesn't apply when npm's \"--ignore-scripts\" flag is\n  // used since in that case this install script will not be run.\n  const { isWASM } = pkgAndSubpathForCurrentPlatform()\n  if (os.platform() !== 'win32' && !isYarn() && !isWASM) {\n    const tempPath = path.join(__dirname, 'bin-esbuild')\n    try {\n      // First link the binary with a temporary file. If this fails and throws an\n      // error, then we'll just end up doing nothing. This uses a hard link to\n      // avoid taking up additional space on the file system.\n      fs.linkSync(binPath, tempPath)\n\n      // Then use rename to atomically replace the target file with the temporary\n      // file. If this fails and throws an error, then we'll just end up leaving\n      // the temporary file there, which is harmless.\n      fs.renameSync(tempPath, toPath)\n\n      // If we get here, then we know that the target location is now a binary\n      // executable instead of a JavaScript file.\n      isToPathJS = false\n\n      // If this install script is being re-run, then \"renameSync\" will fail\n      // since the underlying inode is the same (it just returns without doing\n      // anything, and without throwing an error). In that case we should remove\n      // the file manually.\n      fs.unlinkSync(tempPath)\n    } catch {\n      // Ignore errors here since this optimization is optional\n    }\n  }\n}\n\nasync function downloadDirectlyFromNPM(pkg: string, subpath: string, binPath: string): Promise<void> {\n  // If that fails, the user could have npm configured incorrectly or could not\n  // have npm installed. Try downloading directly from npm as a last resort.\n  const url = `https://registry.npmjs.org/${pkg}/-/${pkg.replace('@esbuild/', '')}-${versionFromPackageJSON}.tgz`\n  console.error(`[esbuild] Trying to download ${JSON.stringify(url)}`)\n  try {\n    fs.writeFileSync(binPath, extractFileFromTarGzip(await fetch(url), subpath))\n    fs.chmodSync(binPath, 0o755)\n  } catch (e: any) {\n    console.error(`[esbuild] Failed to download ${JSON.stringify(url)}: ${e && e.message || e}`)\n    throw e\n  }\n}\n\nasync function checkAndPreparePackage(): Promise<void> {\n  // This feature was added to give external code a way to modify the binary\n  // path without modifying the code itself. Do not remove this because\n  // external code relies on this (in addition to esbuild's own test suite).\n  if (isValidBinaryPath(ESBUILD_BINARY_PATH)) {\n    if (!fs.existsSync(ESBUILD_BINARY_PATH)) {\n      console.warn(`[esbuild] Ignoring bad configuration: ESBUILD_BINARY_PATH=${ESBUILD_BINARY_PATH}`)\n    } else {\n      applyManualBinaryPathOverride(ESBUILD_BINARY_PATH)\n      return\n    }\n  }\n\n  const { pkg, subpath } = pkgAndSubpathForCurrentPlatform()\n\n  let binPath: string\n  try {\n    // First check for the binary package from our \"optionalDependencies\". This\n    // package should have been installed alongside this package at install time.\n    binPath = require.resolve(`${pkg}/${subpath}`)\n  } catch (e) {\n    console.error(`[esbuild] Failed to find package \"${pkg}\" on the file system\n\nThis can happen if you use the \"--no-optional\" flag. The \"optionalDependencies\"\npackage.json feature is used by esbuild to install the correct binary executable\nfor your current platform. This install script will now attempt to work around\nthis. If that fails, you need to remove the \"--no-optional\" flag to use esbuild.\n`)\n\n    // If that didn't work, then someone probably installed esbuild with the\n    // \"--no-optional\" flag. Attempt to compensate for this by downloading the\n    // package using a nested call to \"npm\" instead.\n    //\n    // THIS MAY NOT WORK. Package installation uses \"optionalDependencies\" for\n    // a reason: manually downloading the package has a lot of obscure edge\n    // cases that fail because people have customized their environment in\n    // some strange way that breaks downloading. This code path is just here\n    // to be helpful but it's not the supported way of installing esbuild.\n    binPath = downloadedBinPath(pkg, subpath)\n    try {\n      console.error(`[esbuild] Trying to install package \"${pkg}\" using npm`)\n      installUsingNPM(pkg, subpath, binPath)\n    } catch (e2: any) {\n      console.error(`[esbuild] Failed to install package \"${pkg}\" using npm: ${e2 && e2.message || e2}`)\n\n      // If that didn't also work, then something is likely wrong with the \"npm\"\n      // command. Attempt to compensate for this by manually downloading the\n      // package from the npm registry over HTTP as a last resort.\n      try {\n        await downloadDirectlyFromNPM(pkg, subpath, binPath)\n      } catch (e3: any) {\n        throw new Error(`Failed to install package \"${pkg}\"`)\n      }\n    }\n  }\n\n  maybeOptimizePackage(binPath)\n}\n\ncheckAndPreparePackage().then(() => {\n  if (isToPathJS) {\n    // We need \"node\" before this command since it's a JavaScript file\n    validateBinaryVersion(process.execPath, toPath)\n  } else {\n    // This is no longer a JavaScript file so don't run it using \"node\"\n    validateBinaryVersion(toPath)\n  }\n})\n"
  },
  {
    "path": "lib/npm/node-platform.ts",
    "content": "import fs = require('fs')\nimport os = require('os')\nimport path = require('path')\n\ndeclare const ESBUILD_VERSION: string\n\n// This feature was added to give external code a way to modify the binary\n// path without modifying the code itself. Do not remove this because\n// external code relies on this.\nexport var ESBUILD_BINARY_PATH: string | undefined = process.env.ESBUILD_BINARY_PATH || ESBUILD_BINARY_PATH\n\n// Someone made an unofficial \"esbuild\" package for Linux that sets the\n// environment variable \"ESBUILD_BINARY_PATH\" to \"/usr/bin/esbuild\". This\n// breaks all npm installations of esbuild. The unofficial package was fixed\n// after I reached out to them but the old broken packages will still be there\n// forever. Attempt to fix this by ignoring the \"/usr/bin/esbuild\" value.\nexport const isValidBinaryPath = (x: string | undefined): x is string => !!x && x !== '/usr/bin/esbuild'\n\nconst packageDarwin_arm64 = '@esbuild/darwin-arm64'\nconst packageDarwin_x64 = '@esbuild/darwin-x64'\n\nexport const knownWindowsPackages: Record<string, string> = {\n  'win32 arm64 LE': '@esbuild/win32-arm64',\n  'win32 ia32 LE': '@esbuild/win32-ia32',\n  'win32 x64 LE': '@esbuild/win32-x64',\n}\n\nexport const knownUnixlikePackages: Record<string, string> = {\n  'aix ppc64 BE': '@esbuild/aix-ppc64',\n  'android arm64 LE': '@esbuild/android-arm64',\n  'darwin arm64 LE': '@esbuild/darwin-arm64',\n  'darwin x64 LE': '@esbuild/darwin-x64',\n  'freebsd arm64 LE': '@esbuild/freebsd-arm64',\n  'freebsd x64 LE': '@esbuild/freebsd-x64',\n  'linux arm LE': '@esbuild/linux-arm',\n  'linux arm64 LE': '@esbuild/linux-arm64',\n  'linux ia32 LE': '@esbuild/linux-ia32',\n  'linux mips64el LE': '@esbuild/linux-mips64el',\n  'linux ppc64 LE': '@esbuild/linux-ppc64',\n  'linux riscv64 LE': '@esbuild/linux-riscv64',\n  'linux s390x BE': '@esbuild/linux-s390x',\n  'linux x64 LE': '@esbuild/linux-x64',\n  'linux loong64 LE': '@esbuild/linux-loong64',\n  'netbsd arm64 LE': '@esbuild/netbsd-arm64',\n  'netbsd x64 LE': '@esbuild/netbsd-x64',\n  'openbsd arm64 LE': '@esbuild/openbsd-arm64',\n  'openbsd x64 LE': '@esbuild/openbsd-x64',\n  'sunos x64 LE': '@esbuild/sunos-x64',\n}\n\nexport const knownWebAssemblyFallbackPackages: Record<string, string> = {\n  'android arm LE': '@esbuild/android-arm',\n  'android x64 LE': '@esbuild/android-x64',\n  'openharmony arm64 LE': '@esbuild/openharmony-arm64',\n}\n\nexport function pkgAndSubpathForCurrentPlatform(): { pkg: string, subpath: string, isWASM: boolean } {\n  let pkg: string\n  let subpath: string\n  let isWASM = false\n  let platformKey = `${process.platform} ${os.arch()} ${os.endianness()}`\n\n  if (platformKey in knownWindowsPackages) {\n    pkg = knownWindowsPackages[platformKey]\n    subpath = 'esbuild.exe'\n  }\n\n  else if (platformKey in knownUnixlikePackages) {\n    pkg = knownUnixlikePackages[platformKey]\n    subpath = 'bin/esbuild'\n  }\n\n  else if (platformKey in knownWebAssemblyFallbackPackages) {\n    pkg = knownWebAssemblyFallbackPackages[platformKey]\n    subpath = 'bin/esbuild'\n    isWASM = true\n  }\n\n  else {\n    throw new Error(`Unsupported platform: ${platformKey}`)\n  }\n\n  return { pkg, subpath, isWASM }\n}\n\nfunction pkgForSomeOtherPlatform(): string | null {\n  const libMainJS = require.resolve('esbuild')\n  const nodeModulesDirectory = path.dirname(path.dirname(path.dirname(libMainJS)))\n\n  if (path.basename(nodeModulesDirectory) === 'node_modules') {\n    for (const unixKey in knownUnixlikePackages) {\n      try {\n        const pkg = knownUnixlikePackages[unixKey]\n        if (fs.existsSync(path.join(nodeModulesDirectory, pkg))) return pkg\n      } catch {\n      }\n    }\n\n    for (const windowsKey in knownWindowsPackages) {\n      try {\n        const pkg = knownWindowsPackages[windowsKey]\n        if (fs.existsSync(path.join(nodeModulesDirectory, pkg))) return pkg\n      } catch {\n      }\n    }\n  }\n\n  return null\n}\n\nexport function downloadedBinPath(pkg: string, subpath: string): string {\n  const esbuildLibDir = path.dirname(require.resolve('esbuild'))\n  return path.join(esbuildLibDir, `downloaded-${pkg.replace('/', '-')}-${path.basename(subpath)}`)\n}\n\nexport function generateBinPath(): { binPath: string, isWASM: boolean } {\n  // This feature was added to give external code a way to modify the binary\n  // path without modifying the code itself. Do not remove this because\n  // external code relies on this (in addition to esbuild's own test suite).\n  if (isValidBinaryPath(ESBUILD_BINARY_PATH)) {\n    if (!fs.existsSync(ESBUILD_BINARY_PATH)) {\n      console.warn(`[esbuild] Ignoring bad configuration: ESBUILD_BINARY_PATH=${ESBUILD_BINARY_PATH}`)\n    } else {\n      return { binPath: ESBUILD_BINARY_PATH, isWASM: false }\n    }\n  }\n\n  const { pkg, subpath, isWASM } = pkgAndSubpathForCurrentPlatform()\n  let binPath: string\n\n  try {\n    // First check for the binary package from our \"optionalDependencies\". This\n    // package should have been installed alongside this package at install time.\n    binPath = require.resolve(`${pkg}/${subpath}`)\n  } catch (e) {\n    // If that didn't work, then someone probably installed esbuild with the\n    // \"--no-optional\" flag. Our install script attempts to compensate for this\n    // by manually downloading the package instead. Check for that next.\n    binPath = downloadedBinPath(pkg, subpath)\n    if (!fs.existsSync(binPath)) {\n      // If that didn't work too, check to see whether the package is even there\n      // at all. It may not be (for a few different reasons).\n      try {\n        require.resolve(pkg)\n      } catch {\n        // If we can't find the package for this platform, then it's possible\n        // that someone installed this for some other platform and is trying\n        // to use it without reinstalling. That won't work of course, but\n        // people do this all the time with systems like Docker. Try to be\n        // helpful in that case.\n        const otherPkg = pkgForSomeOtherPlatform()\n        if (otherPkg) {\n          let suggestions = `\nSpecifically the \"${otherPkg}\" package is present but this platform\nneeds the \"${pkg}\" package instead. People often get into this\nsituation by installing esbuild on Windows or macOS and copying \"node_modules\"\ninto a Docker image that runs Linux, or by copying \"node_modules\" between\nWindows and WSL environments.\n\nIf you are installing with npm, you can try not copying the \"node_modules\"\ndirectory when you copy the files over, and running \"npm ci\" or \"npm install\"\non the destination platform after the copy. Or you could consider using yarn\ninstead of npm which has built-in support for installing a package on multiple\nplatforms simultaneously.\n\nIf you are installing with yarn, you can try listing both this platform and the\nother platform in your \".yarnrc.yml\" file using the \"supportedArchitectures\"\nfeature: https://yarnpkg.com/configuration/yarnrc/#supportedArchitectures\nKeep in mind that this means multiple copies of esbuild will be present.\n`\n\n          // Use a custom message for macOS-specific architecture issues\n          if (\n            (pkg === packageDarwin_x64 && otherPkg === packageDarwin_arm64) ||\n            (pkg === packageDarwin_arm64 && otherPkg === packageDarwin_x64)\n          ) {\n            suggestions = `\nSpecifically the \"${otherPkg}\" package is present but this platform\nneeds the \"${pkg}\" package instead. People often get into this\nsituation by installing esbuild with npm running inside of Rosetta 2 and then\ntrying to use it with node running outside of Rosetta 2, or vice versa (Rosetta\n2 is Apple's on-the-fly x86_64-to-arm64 translation service).\n\nIf you are installing with npm, you can try ensuring that both npm and node are\nnot running under Rosetta 2 and then reinstalling esbuild. This likely involves\nchanging how you installed npm and/or node. For example, installing node with\nthe universal installer here should work: https://nodejs.org/en/download/. Or\nyou could consider using yarn instead of npm which has built-in support for\ninstalling a package on multiple platforms simultaneously.\n\nIf you are installing with yarn, you can try listing both \"arm64\" and \"x64\"\nin your \".yarnrc.yml\" file using the \"supportedArchitectures\" feature:\nhttps://yarnpkg.com/configuration/yarnrc/#supportedArchitectures\nKeep in mind that this means multiple copies of esbuild will be present.\n`\n          }\n\n          throw new Error(`\nYou installed esbuild for another platform than the one you're currently using.\nThis won't work because esbuild is written with native code and needs to\ninstall a platform-specific binary executable.\n${suggestions}\nAnother alternative is to use the \"esbuild-wasm\" package instead, which works\nthe same way on all platforms. But it comes with a heavy performance cost and\ncan sometimes be 10x slower than the \"esbuild\" package, so you may also not\nwant to do that.\n`)\n        }\n\n        // If that didn't work too, then maybe someone installed esbuild with\n        // both the \"--no-optional\" and the \"--ignore-scripts\" flags. The fix\n        // for this is to just not do that. We don't attempt to handle this\n        // case at all.\n        //\n        // In that case we try to have a nice error message if we think we know\n        // what's happening. Otherwise we just rethrow the original error message.\n        throw new Error(`The package \"${pkg}\" could not be found, and is needed by esbuild.\n\nIf you are installing esbuild with npm, make sure that you don't specify the\n\"--no-optional\" or \"--omit=optional\" flags. The \"optionalDependencies\" feature\nof \"package.json\" is used by esbuild to install the correct binary executable\nfor your current platform.`)\n      }\n      throw e\n    }\n  }\n\n  // This code below guards against the unlikely case that the user is using\n  // Yarn 2+ in PnP mode and that version is old enough that it doesn't support\n  // the \"preferUnplugged\" setting. If that's the case, then the path to the\n  // binary executable that we got above isn't actually a real path. Instead\n  // it's a path to a zip file with some extra stuff appended to it.\n  //\n  // Yarn's PnP mode tries hard to patch Node's file system APIs to pretend\n  // that these fake paths are real. So we can't check whether it's a real file\n  // or not by using Node's file system APIs (e.g. \"fs.existsSync\") because\n  // they have been patched to lie. But we can't return this fake path because\n  // Yarn hasn't patched \"child_process.execFileSync\" to work with fake paths,\n  // so attempting to execute the binary will fail.\n  //\n  // As a hack, we use Node's file system APIs to copy the file from the fake\n  // path to a real path. This will cause Yarn's hacked file system to extract\n  // the binary executable from the zip file and turn it into a real file that\n  // we can execute.\n  //\n  // This is only done when both \".zip/\" is present in the path and the\n  // \"pnpapi\" package is present, which is a strong indication that Yarn PnP is\n  // being used. There is no API at all for telling whether something is a real\n  // file or not as far as I can tell. Even Yarn's own code just checks for\n  // whether \".zip/\" is present in the path or not.\n  //\n  // Note to self: One very hacky way to tell if a path is under the influence\n  // of Yarn's file system hacks is to stat the file and check for the \"crc\"\n  // property in the result. If that's present, then the file is inside a zip\n  // file. However, I haven't done that here because it's not intended to be\n  // used that way. Who knows what Yarn versions it does or does not work on\n  // (including future versions).\n  if (/\\.zip\\//.test(binPath)) {\n    let pnpapi: any\n    try {\n      pnpapi = require('pnpapi')\n    } catch (e) {\n    }\n    if (pnpapi) {\n      // Copy the executable to \".cache/esbuild\". The official recommendation\n      // of the Yarn team is to use the directory \"node_modules/.cache/esbuild\":\n      // https://yarnpkg.com/advanced/rulebook/#packages-should-never-write-inside-their-own-folder-outside-of-postinstall\n      // People that use Yarn in PnP mode find this really annoying because they\n      // don't like seeing the \"node_modules\" directory. These people should\n      // either work with Yarn to change their recommendation, or upgrade their\n      // version of Yarn, since newer versions of Yarn shouldn't stick esbuild's\n      // binary executables in a zip file due to the \"preferUnplugged\" setting.\n      const root = pnpapi.getPackageInformation(pnpapi.topLevel).packageLocation\n      const binTargetPath = path.join(\n        root,\n        'node_modules',\n        '.cache',\n        'esbuild',\n        `pnpapi-${pkg.replace('/', '-')}-${ESBUILD_VERSION}-${path.basename(subpath)}`,\n      )\n      if (!fs.existsSync(binTargetPath)) {\n        fs.mkdirSync(path.dirname(binTargetPath), { recursive: true })\n        fs.copyFileSync(binPath, binTargetPath)\n        fs.chmodSync(binTargetPath, 0o755)\n      }\n      return { binPath: binTargetPath, isWASM }\n    }\n  }\n\n  return { binPath, isWASM }\n}\n"
  },
  {
    "path": "lib/npm/node-shim.ts",
    "content": "#!/usr/bin/env node\n\nimport { generateBinPath } from \"./node-platform\"\nconst { binPath, isWASM } = generateBinPath()\nif (isWASM) {\n  require('child_process').execFileSync('node', [binPath].concat(process.argv.slice(2)), { stdio: 'inherit' })\n} else {\n  require('child_process').execFileSync(binPath, process.argv.slice(2), { stdio: 'inherit' })\n}\n"
  },
  {
    "path": "lib/npm/node.ts",
    "content": "import type * as types from \"../shared/types\"\nimport * as common from \"../shared/common\"\nimport * as ourselves from \"./node\"\nimport { ESBUILD_BINARY_PATH, generateBinPath } from \"./node-platform\"\n\nimport child_process = require('child_process')\nimport crypto = require('crypto')\nimport path = require('path')\nimport fs = require('fs')\nimport os = require('os')\nimport tty = require('tty')\n\ndeclare const ESBUILD_VERSION: string\n\n// This file is used for both the \"esbuild\" package and the \"esbuild-wasm\"\n// package. \"WASM\" will be true for \"esbuild-wasm\" and false for \"esbuild\".\ndeclare const WASM: boolean\n\nlet worker_threads: typeof import('worker_threads') | undefined\n\nif (process.env.ESBUILD_WORKER_THREADS !== '0') {\n  // Don't crash if the \"worker_threads\" library isn't present\n  try {\n    worker_threads = require('worker_threads')\n  } catch {\n  }\n\n  // Creating a worker in certain node versions doesn't work. The specific\n  // error is \"TypeError: MessagePort was found in message but not listed\n  // in transferList\". See: https://github.com/nodejs/node/issues/32250.\n  // We just pretend worker threads are unavailable in these cases.\n  let [major, minor] = process.versions.node.split('.')\n  if (\n    // <v12.17.0 does not work\n    +major < 12 || (+major === 12 && +minor < 17)\n\n    // >=v13.0.0 && <v13.13.0 also does not work\n    || (+major === 13 && +minor < 13)\n  ) {\n    worker_threads = void 0\n  }\n}\n\n// This should only be true if this is our internal worker thread. We want this\n// library to be usable from other people's worker threads, so we should not be\n// checking for \"isMainThread\".\nlet isInternalWorkerThread = worker_threads?.workerData?.esbuildVersion === ESBUILD_VERSION\n\nlet esbuildCommandAndArgs = (): [string, string[]] => {\n  // Try to have a nice error message when people accidentally bundle esbuild\n  // without providing an explicit path to the binary, or when using WebAssembly.\n  if ((!ESBUILD_BINARY_PATH || WASM) && (path.basename(__filename) !== 'main.js' || path.basename(__dirname) !== 'lib')) {\n    throw new Error(\n      `The esbuild JavaScript API cannot be bundled. Please mark the \"esbuild\" ` +\n      `package as external so it's not included in the bundle.\\n` +\n      `\\n` +\n      `More information: The file containing the code for esbuild's JavaScript ` +\n      `API (${__filename}) does not appear to be inside the esbuild package on ` +\n      `the file system, which usually means that the esbuild package was bundled ` +\n      `into another file. This is problematic because the API needs to run a ` +\n      `binary executable inside the esbuild package which is located using a ` +\n      `relative path from the API code to the executable. If the esbuild package ` +\n      `is bundled, the relative path will be incorrect and the executable won't ` +\n      `be found.`)\n  }\n\n  if (WASM) {\n    return ['node', [path.join(__dirname, '..', 'bin', 'esbuild')]]\n  } else {\n    const { binPath, isWASM } = generateBinPath()\n    if (isWASM) {\n      return ['node', [binPath]]\n    } else {\n      return [binPath, []]\n    }\n  }\n}\n\n// Return true if stderr is a TTY\nlet isTTY = () => tty.isatty(2)\n\nlet fsSync: common.StreamFS = {\n  readFile(tempFile, callback) {\n    try {\n      let contents = fs.readFileSync(tempFile, 'utf8')\n      try {\n        fs.unlinkSync(tempFile)\n      } catch {\n      }\n      callback(null, contents)\n    } catch (err: any) {\n      callback(err, null)\n    }\n  },\n  writeFile(contents, callback) {\n    try {\n      let tempFile = randomFileName()\n      fs.writeFileSync(tempFile, contents)\n      callback(tempFile)\n    } catch {\n      callback(null)\n    }\n  },\n}\n\nlet fsAsync: common.StreamFS = {\n  readFile(tempFile, callback) {\n    try {\n      fs.readFile(tempFile, 'utf8', (err, contents) => {\n        try {\n          fs.unlink(tempFile, () => callback(err, contents))\n        } catch {\n          callback(err, contents)\n        }\n      })\n    } catch (err: any) {\n      callback(err, null)\n    }\n  },\n  writeFile(contents, callback) {\n    try {\n      let tempFile = randomFileName()\n      fs.writeFile(tempFile, contents, err =>\n        err !== null ? callback(null) : callback(tempFile))\n    } catch {\n      callback(null)\n    }\n  },\n}\n\nexport let version = ESBUILD_VERSION\n\nexport let build: typeof types.build = (options: types.BuildOptions) =>\n  ensureServiceIsRunning().build(options)\n\nexport let context: typeof types.context = (buildOptions: types.BuildOptions) =>\n  ensureServiceIsRunning().context(buildOptions)\n\nexport let transform: typeof types.transform = (input: string | Uint8Array, options?: types.TransformOptions) =>\n  ensureServiceIsRunning().transform(input, options)\n\nexport let formatMessages: typeof types.formatMessages = (messages, options) =>\n  ensureServiceIsRunning().formatMessages(messages, options)\n\nexport let analyzeMetafile: typeof types.analyzeMetafile = (messages, options) =>\n  ensureServiceIsRunning().analyzeMetafile(messages, options)\n\nexport let buildSync: typeof types.buildSync = (options: types.BuildOptions) => {\n  // Try using a long-lived worker thread to avoid repeated start-up overhead\n  if (worker_threads && !isInternalWorkerThread) {\n    if (!workerThreadService) workerThreadService = startWorkerThreadService(worker_threads)\n    return workerThreadService.buildSync(options)\n  }\n\n  let result: types.BuildResult\n  runServiceSync(service => service.buildOrContext({\n    callName: 'buildSync',\n    refs: null,\n    options,\n    isTTY: isTTY(),\n    defaultWD,\n    callback: (err, res) => { if (err) throw err; result = res as types.BuildResult },\n  }))\n  return result!\n}\n\nexport let transformSync: typeof types.transformSync = (input: string | Uint8Array, options?: types.TransformOptions) => {\n  // Try using a long-lived worker thread to avoid repeated start-up overhead\n  if (worker_threads && !isInternalWorkerThread) {\n    if (!workerThreadService) workerThreadService = startWorkerThreadService(worker_threads)\n    return workerThreadService.transformSync(input, options)\n  }\n\n  let result: types.TransformResult\n  runServiceSync(service => service.transform({\n    callName: 'transformSync',\n    refs: null,\n    input,\n    options: options || {},\n    isTTY: isTTY(),\n    fs: fsSync,\n    callback: (err, res) => { if (err) throw err; result = res! },\n  }))\n  return result!\n}\n\nexport let formatMessagesSync: typeof types.formatMessagesSync = (messages, options) => {\n  // Try using a long-lived worker thread to avoid repeated start-up overhead\n  if (worker_threads && !isInternalWorkerThread) {\n    if (!workerThreadService) workerThreadService = startWorkerThreadService(worker_threads)\n    return workerThreadService.formatMessagesSync(messages, options)\n  }\n\n  let result: string[]\n  runServiceSync(service => service.formatMessages({\n    callName: 'formatMessagesSync',\n    refs: null,\n    messages,\n    options,\n    callback: (err, res) => { if (err) throw err; result = res! },\n  }))\n  return result!\n}\n\nexport let analyzeMetafileSync: typeof types.analyzeMetafileSync = (metafile, options) => {\n  // Try using a long-lived worker thread to avoid repeated start-up overhead\n  if (worker_threads && !isInternalWorkerThread) {\n    if (!workerThreadService) workerThreadService = startWorkerThreadService(worker_threads)\n    return workerThreadService.analyzeMetafileSync(metafile, options)\n  }\n\n  let result: string\n  runServiceSync(service => service.analyzeMetafile({\n    callName: 'analyzeMetafileSync',\n    refs: null,\n    metafile: typeof metafile === 'string' ? metafile : JSON.stringify(metafile),\n    options,\n    callback: (err, res) => { if (err) throw err; result = res! },\n  }))\n  return result!\n}\n\nexport const stop = () => {\n  if (stopService) stopService()\n  if (workerThreadService) workerThreadService.stop()\n  return Promise.resolve()\n}\n\nlet initializeWasCalled = false\n\nexport let initialize: typeof types.initialize = options => {\n  options = common.validateInitializeOptions(options || {})\n  if (options.wasmURL) throw new Error(`The \"wasmURL\" option only works in the browser`)\n  if (options.wasmModule) throw new Error(`The \"wasmModule\" option only works in the browser`)\n  if (options.worker) throw new Error(`The \"worker\" option only works in the browser`)\n  if (initializeWasCalled) throw new Error('Cannot call \"initialize\" more than once')\n  ensureServiceIsRunning()\n  initializeWasCalled = true\n  return Promise.resolve()\n}\n\ninterface Service {\n  build: typeof types.build\n  context: typeof types.context\n  transform: typeof types.transform\n  formatMessages: typeof types.formatMessages\n  analyzeMetafile: typeof types.analyzeMetafile\n}\n\nlet defaultWD = process.cwd()\nlet longLivedService: Service | undefined\nlet stopService: (() => void) | undefined\n\nlet ensureServiceIsRunning = (): Service => {\n  if (longLivedService) return longLivedService\n  let [command, args] = esbuildCommandAndArgs()\n  let child = child_process.spawn(command, args.concat(`--service=${ESBUILD_VERSION}`, '--ping'), {\n    windowsHide: true,\n    stdio: ['pipe', 'pipe', 'inherit'],\n    cwd: defaultWD,\n  })\n\n  let { readFromStdout, afterClose, service } = common.createChannel({\n    writeToStdin(bytes) {\n      child.stdin.write(bytes, err => {\n        // Assume the service was stopped if we get an error writing to stdin\n        if (err) afterClose(err)\n      })\n    },\n    readFileSync: fs.readFileSync,\n    isSync: false,\n    hasFS: true,\n    esbuild: ourselves,\n  })\n\n  // Assume the service was stopped if we get an error writing to stdin\n  child.stdin.on('error', afterClose)\n\n  // Propagate errors about failure to run the executable itself\n  child.on('error', afterClose)\n\n  const stdin: typeof child.stdin & { unref?(): void } = child.stdin\n  const stdout: typeof child.stdout & { unref?(): void } = child.stdout\n\n  stdout.on('data', readFromStdout)\n  stdout.on('end', afterClose)\n\n  stopService = () => {\n    // Close all resources related to the subprocess.\n    stdin.destroy()\n    stdout.destroy()\n    child.kill()\n    initializeWasCalled = false\n    longLivedService = undefined\n    stopService = undefined\n  }\n\n  let refCount = 0\n  child.unref()\n  if (stdin.unref) {\n    stdin.unref()\n  }\n  if (stdout.unref) {\n    stdout.unref()\n  }\n\n  const refs: common.Refs = {\n    ref() { if (++refCount === 1) child.ref(); },\n    unref() { if (--refCount === 0) child.unref(); },\n  }\n\n  longLivedService = {\n    build: (options: types.BuildOptions) =>\n      new Promise<types.BuildResult>((resolve, reject) => {\n        service.buildOrContext({\n          callName: 'build',\n          refs,\n          options,\n          isTTY: isTTY(),\n          defaultWD,\n          callback: (err, res) => err ? reject(err) : resolve(res as types.BuildResult),\n        })\n      }),\n\n    context: (options: types.BuildOptions) =>\n      new Promise<types.BuildContext>((resolve, reject) =>\n        service.buildOrContext({\n          callName: 'context',\n          refs,\n          options,\n          isTTY: isTTY(),\n          defaultWD,\n          callback: (err, res) => err ? reject(err) : resolve(res as types.BuildContext),\n        })),\n\n    transform: (input: string | Uint8Array, options?: types.TransformOptions) =>\n      new Promise<types.TransformResult>((resolve, reject) =>\n        service.transform({\n          callName: 'transform',\n          refs,\n          input,\n          options: options || {},\n          isTTY: isTTY(),\n          fs: fsAsync,\n          callback: (err, res) => err ? reject(err) : resolve(res!),\n        })),\n\n    formatMessages: (messages, options) =>\n      new Promise((resolve, reject) =>\n        service.formatMessages({\n          callName: 'formatMessages',\n          refs,\n          messages,\n          options,\n          callback: (err, res) => err ? reject(err) : resolve(res!),\n        })),\n\n    analyzeMetafile: (metafile, options) =>\n      new Promise((resolve, reject) =>\n        service.analyzeMetafile({\n          callName: 'analyzeMetafile',\n          refs,\n          metafile: typeof metafile === 'string' ? metafile : JSON.stringify(metafile),\n          options,\n          callback: (err, res) => err ? reject(err) : resolve(res!),\n        })),\n  }\n  return longLivedService\n}\n\nlet runServiceSync = (callback: (service: common.StreamService) => void): void => {\n  let [command, args] = esbuildCommandAndArgs()\n  let stdin = new Uint8Array()\n  let { readFromStdout, afterClose, service } = common.createChannel({\n    writeToStdin(bytes) {\n      if (stdin.length !== 0) throw new Error('Must run at most one command')\n      stdin = bytes\n    },\n    isSync: true,\n    hasFS: true,\n    esbuild: ourselves,\n  })\n  callback(service)\n  let stdout = child_process.execFileSync(command, args.concat(`--service=${ESBUILD_VERSION}`), {\n    cwd: defaultWD,\n    windowsHide: true,\n    input: stdin,\n\n    // We don't know how large the output could be. If it's too large, the\n    // command will fail with ENOBUFS. Reserve 16mb for now since that feels\n    // like it should be enough. Also allow overriding this with an environment\n    // variable.\n    maxBuffer: +process.env.ESBUILD_MAX_BUFFER! || 16 * 1024 * 1024,\n  })\n  readFromStdout(stdout)\n  afterClose(null)\n}\n\nlet randomFileName = () => {\n  return path.join(os.tmpdir(), `esbuild-${crypto.randomBytes(32).toString('hex')}`)\n}\n\ninterface MainToWorkerMessage {\n  sharedBuffer: SharedArrayBuffer\n  id: number\n  command: string\n  args: any[]\n}\n\ninterface WorkerThreadService {\n  buildSync(options: types.BuildOptions): types.BuildResult\n  transformSync(input: string | Uint8Array, options?: types.TransformOptions): types.TransformResult\n  formatMessagesSync: typeof types.formatMessagesSync\n  analyzeMetafileSync: typeof types.analyzeMetafileSync\n  stop(): void\n}\n\nlet workerThreadService: WorkerThreadService | null = null\n\nlet startWorkerThreadService = (worker_threads: typeof import('worker_threads')): WorkerThreadService => {\n  let { port1: mainPort, port2: workerPort } = new worker_threads.MessageChannel()\n  let worker = new worker_threads.Worker(__filename, {\n    workerData: { workerPort, defaultWD, esbuildVersion: ESBUILD_VERSION },\n    transferList: [workerPort],\n\n    // From node's documentation: https://nodejs.org/api/worker_threads.html\n    //\n    //   Take care when launching worker threads from preload scripts (scripts loaded\n    //   and run using the `-r` command line flag). Unless the `execArgv` option is\n    //   explicitly set, new Worker threads automatically inherit the command line flags\n    //   from the running process and will preload the same preload scripts as the main\n    //   thread. If the preload script unconditionally launches a worker thread, every\n    //   thread spawned will spawn another until the application crashes.\n    //\n    execArgv: [],\n  })\n  let nextID = 0\n\n  // This forbids options which would cause structured clone errors\n  let fakeBuildError = (text: string) => {\n    let error: any = new Error(`Build failed with 1 error:\\nerror: ${text}`)\n    let errors: types.Message[] = [{ id: '', pluginName: '', text, location: null, notes: [], detail: void 0 }]\n    error.errors = errors\n    error.warnings = []\n    return error\n  }\n  let validateBuildSyncOptions = (options: types.BuildOptions | undefined): void => {\n    if (!options) return\n    let plugins = options.plugins\n    if (plugins && plugins.length > 0) throw fakeBuildError(`Cannot use plugins in synchronous API calls`)\n  }\n\n  // MessagePort doesn't copy the properties of Error objects. We still want\n  // error objects to have extra properties such as \"warnings\" so implement the\n  // property copying manually.\n  let applyProperties = (object: any, properties: Record<string, any>): void => {\n    for (let key in properties) {\n      object[key] = properties[key]\n    }\n  }\n\n  let runCallSync = (command: string, args: any[]): any => {\n    let id = nextID++\n\n    // Make a fresh shared buffer for every request. That way we can't have a\n    // race where a notification from the previous call overlaps with this call.\n    let sharedBuffer = new SharedArrayBuffer(8)\n    let sharedBufferView = new Int32Array(sharedBuffer)\n\n    // Send the message to the worker. Note that the worker could potentially\n    // complete the request before this thread returns from this call.\n    let msg: MainToWorkerMessage = { sharedBuffer, id, command, args }\n    worker.postMessage(msg)\n\n    // If the value hasn't changed (i.e. the request hasn't been completed,\n    // wait until the worker thread notifies us that the request is complete).\n    //\n    // Otherwise, if the value has changed, the request has already been\n    // completed. Don't wait in that case because the notification may never\n    // arrive if it has already been sent.\n    let status = Atomics.wait(sharedBufferView, 0, 0)\n    if (status !== 'ok' && status !== 'not-equal') throw new Error('Internal error: Atomics.wait() failed: ' + status)\n\n    let { message: { id: id2, resolve, reject, properties } } = worker_threads!.receiveMessageOnPort(mainPort)!\n    if (id !== id2) throw new Error(`Internal error: Expected id ${id} but got id ${id2}`)\n    if (reject) {\n      applyProperties(reject, properties)\n      throw reject\n    }\n    return resolve\n  }\n\n  // Calling unref() on a worker will allow the thread to exit if it's the last\n  // only active handle in the event system. This means node will still exit\n  // when there are no more event handlers from the main thread. So there's no\n  // need to call the \"stop()\" function.\n  worker.unref()\n\n  return {\n    buildSync(options) {\n      validateBuildSyncOptions(options)\n      return runCallSync('build', [options])\n    },\n    transformSync(input, options) {\n      return runCallSync('transform', [input, options])\n    },\n    formatMessagesSync(messages, options) {\n      return runCallSync('formatMessages', [messages, options])\n    },\n    analyzeMetafileSync(metafile, options) {\n      return runCallSync('analyzeMetafile', [metafile, options])\n    },\n    stop() {\n      worker.terminate()\n      workerThreadService = null\n    },\n  }\n}\n\nlet startSyncServiceWorker = () => {\n  let workerPort: import('worker_threads').MessagePort = worker_threads!.workerData.workerPort\n  let parentPort = worker_threads!.parentPort!\n\n  // MessagePort doesn't copy the properties of Error objects. We still want\n  // error objects to have extra properties such as \"warnings\" so implement the\n  // property copying manually.\n  let extractProperties = (object: any): Record<string, any> => {\n    let properties: Record<string, any> = {}\n    if (object && typeof object === 'object') {\n      for (let key in object) {\n        properties[key] = object[key]\n      }\n    }\n    return properties\n  }\n\n  try {\n    let service = ensureServiceIsRunning()\n\n    // Take the default working directory from the main thread because we want it\n    // to be consistent. This will be the working directory that was current at\n    // the time the \"esbuild\" package was first imported.\n    defaultWD = worker_threads!.workerData.defaultWD\n\n    parentPort.on('message', (msg: MainToWorkerMessage) => {\n      (async () => {\n        let { sharedBuffer, id, command, args } = msg\n        let sharedBufferView = new Int32Array(sharedBuffer)\n\n        try {\n          switch (command) {\n            case 'build':\n              workerPort.postMessage({ id, resolve: await service.build(args[0]) })\n              break\n\n            case 'transform':\n              workerPort.postMessage({ id, resolve: await service.transform(args[0], args[1]) })\n              break\n\n            case 'formatMessages':\n              workerPort.postMessage({ id, resolve: await service.formatMessages(args[0], args[1]) })\n              break\n\n            case 'analyzeMetafile':\n              workerPort.postMessage({ id, resolve: await service.analyzeMetafile(args[0], args[1]) })\n              break\n\n            default:\n              throw new Error(`Invalid command: ${command}`)\n          }\n        } catch (reject) {\n          workerPort.postMessage({ id, reject, properties: extractProperties(reject) })\n        }\n\n        // The message has already been posted by this point, so it should be\n        // safe to wake the main thread. The main thread should always get the\n        // message we sent above.\n\n        // First, change the shared value. That way if the main thread attempts\n        // to wait for us after this point, the wait will fail because the shared\n        // value has changed.\n        Atomics.add(sharedBufferView, 0, 1)\n\n        // Then, wake the main thread. This handles the case where the main\n        // thread was already waiting for us before the shared value was changed.\n        Atomics.notify(sharedBufferView, 0, Infinity)\n      })()\n    })\n  }\n\n  // Creating the service can fail if the on-disk state is corrupt. In that case\n  // we just fail all incoming messages with whatever error message we got.\n  // Otherwise incoming messages will hang forever waiting for a reply.\n  catch (reject) {\n    parentPort.on('message', (msg: MainToWorkerMessage) => {\n      let { sharedBuffer, id } = msg\n      let sharedBufferView = new Int32Array(sharedBuffer)\n      workerPort.postMessage({ id, reject, properties: extractProperties(reject) })\n\n      // The message has already been posted by this point, so it should be\n      // safe to wake the main thread. The main thread should always get the\n      // message we sent above.\n\n      // First, change the shared value. That way if the main thread attempts\n      // to wait for us after this point, the wait will fail because the shared\n      // value has changed.\n      Atomics.add(sharedBufferView, 0, 1)\n\n      // Then, wake the main thread. This handles the case where the main\n      // thread was already waiting for us before the shared value was changed.\n      Atomics.notify(sharedBufferView, 0, Infinity)\n    })\n  }\n}\n\n// If we're in the worker thread, start the worker code\nif (isInternalWorkerThread) {\n  startSyncServiceWorker()\n}\n\n// Export this module's exports as an export named \"default\" to try to work\n// around problems due to the \"default\" import mess.\n//\n// More detail: When this module is converted to CommonJS, we add Babel's\n// \"__esModule\" marker since this module used to be ESM. However, without this\n// default export below, tools that respect the \"__esModule\" marker will have\n// a default export of undefined since there was no default export. This is\n// problematic because node's implementation of importing CommonJS into ESM\n// broke compatibility with the ecosystem and decided to set the \"default\"\n// export to \"module.exports\" regardless of the \"__esModule\" marker. I'm hoping\n// that by setting \"module.exports.default = module.exports\", we can hopefully\n// make this work ok in both environments.\nexport default ourselves\n"
  },
  {
    "path": "lib/package.json",
    "content": "{\n  \"private\": true,\n  \"dependencies\": {\n    \"@types/node\": \"17.0.2\",\n    \"typescript\": \"4.5.4\"\n  }\n}\n"
  },
  {
    "path": "lib/shared/common.ts",
    "content": "import type * as types from \"./types\"\nimport * as protocol from \"./stdio_protocol\"\nimport { JSON_parse } from \"./uint8array_json_parser\"\n\ndeclare const ESBUILD_VERSION: string\n\nconst quote: (x: string) => string = JSON.stringify\n\nconst buildLogLevelDefault = 'warning'\nconst transformLogLevelDefault = 'silent'\n\nfunction validateAndJoinStringArray(values: string[], what: string): string {\n  const toJoin: string[] = []\n  for (const value of values) {\n    validateStringValue(value, what)\n    if (value.indexOf(',') >= 0) throw new Error(`Invalid ${what}: ${value}`)\n    toJoin.push(value)\n  }\n  return toJoin.join(',')\n}\n\nlet canBeAnything = () => null\n\nlet mustBeBoolean = (value: boolean | undefined): string | null =>\n  typeof value === 'boolean' ? null : 'a boolean'\n\nlet mustBeString = (value: string | undefined): string | null =>\n  typeof value === 'string' ? null : 'a string'\n\nlet mustBeRegExp = (value: RegExp | undefined): string | null =>\n  value instanceof RegExp ? null : 'a RegExp object'\n\nlet mustBeInteger = (value: number | undefined): string | null =>\n  typeof value === 'number' && value === (value | 0) ? null : 'an integer'\n\nlet mustBeValidPortNumber = (value: number | undefined): string | null =>\n  typeof value === 'number' && value === (value | 0) && value >= 0 && value <= 0xFFFF ? null : 'a valid port number'\n\nlet mustBeFunction = (value: Function | undefined): string | null =>\n  typeof value === 'function' ? null : 'a function'\n\nlet mustBeArray = <T>(value: T[] | undefined): string | null =>\n  Array.isArray(value) ? null : 'an array'\n\nlet mustBeArrayOfStrings = (value: string[] | undefined): string | null =>\n  Array.isArray(value) && value.every(x => typeof x === 'string') ? null : 'an array of strings'\n\nlet mustBeObject = (value: Object | undefined): string | null =>\n  typeof value === 'object' && value !== null && !Array.isArray(value) ? null : 'an object'\n\nlet mustBeEntryPoints = (value: types.BuildOptions['entryPoints']): string | null =>\n  typeof value === 'object' && value !== null ? null : 'an array or an object'\n\nlet mustBeWebAssemblyModule = (value: WebAssembly.Module | undefined): string | null =>\n  value instanceof WebAssembly.Module ? null : 'a WebAssembly.Module'\n\nlet mustBeObjectOrNull = (value: Object | null | undefined): string | null =>\n  typeof value === 'object' && !Array.isArray(value) ? null : 'an object or null'\n\nlet mustBeStringOrBoolean = (value: string | boolean | undefined): string | null =>\n  typeof value === 'string' || typeof value === 'boolean' ? null : 'a string or a boolean'\n\nlet mustBeStringOrObject = (value: string | Object | undefined): string | null =>\n  typeof value === 'string' || typeof value === 'object' && value !== null && !Array.isArray(value) ? null : 'a string or an object'\n\nlet mustBeStringOrArrayOfStrings = (value: string | string[] | undefined): string | null =>\n  typeof value === 'string' || (Array.isArray(value) && value.every(x => typeof x === 'string')) ? null : 'a string or an array of strings'\n\nlet mustBeStringOrUint8Array = (value: string | Uint8Array | undefined): string | null =>\n  typeof value === 'string' || value instanceof Uint8Array ? null : 'a string or a Uint8Array'\n\nlet mustBeStringOrURL = (value: string | URL | undefined): string | null =>\n  typeof value === 'string' || value instanceof URL ? null : 'a string or a URL'\n\ntype OptionKeys = { [key: string]: boolean }\n\nfunction getFlag<T, K extends (keyof T & string)>(object: T, keys: OptionKeys, key: K, mustBeFn: (value: T[K]) => string | null): T[K] | undefined {\n  let value = object[key]\n  keys[key + ''] = true\n  if (value === undefined) return undefined\n  let mustBe = mustBeFn(value)\n  if (mustBe !== null) throw new Error(`${quote(key)} must be ${mustBe}`)\n  return value\n}\n\nfunction checkForInvalidFlags(object: Object, keys: OptionKeys, where: string): void {\n  for (let key in object) {\n    if (!(key in keys)) {\n      throw new Error(`Invalid option ${where}: ${quote(key)}`)\n    }\n  }\n}\n\nexport function validateInitializeOptions(options: types.InitializeOptions): types.InitializeOptions {\n  let keys: OptionKeys = Object.create(null)\n  let wasmURL = getFlag(options, keys, 'wasmURL', mustBeStringOrURL)\n  let wasmModule = getFlag(options, keys, 'wasmModule', mustBeWebAssemblyModule)\n  let worker = getFlag(options, keys, 'worker', mustBeBoolean)\n  checkForInvalidFlags(options, keys, 'in initialize() call')\n  return {\n    wasmURL,\n    wasmModule,\n    worker,\n  }\n}\n\ntype MangleCache = Record<string, string | false>\n\nfunction validateMangleCache(mangleCache: MangleCache | undefined): MangleCache | undefined {\n  let validated: MangleCache | undefined\n  if (mangleCache !== undefined) {\n    validated = Object.create(null) as MangleCache\n    for (let key in mangleCache) {\n      let value = mangleCache[key]\n      if (typeof value === 'string' || value === false) {\n        validated[key] = value\n      } else {\n        throw new Error(`Expected ${quote(key)} in mangle cache to map to either a string or false`)\n      }\n    }\n  }\n  return validated\n}\n\ntype CommonOptions = types.BuildOptions | types.TransformOptions\n\nfunction pushLogFlags(flags: string[], options: CommonOptions, keys: OptionKeys, isTTY: boolean, logLevelDefault: types.LogLevel): void {\n  let color = getFlag(options, keys, 'color', mustBeBoolean)\n  let logLevel = getFlag(options, keys, 'logLevel', mustBeString)\n  let logLimit = getFlag(options, keys, 'logLimit', mustBeInteger)\n\n  if (color !== void 0) flags.push(`--color=${color}`)\n  else if (isTTY) flags.push(`--color=true`); // This is needed to fix \"execFileSync\" which buffers stderr\n  flags.push(`--log-level=${logLevel || logLevelDefault}`)\n  flags.push(`--log-limit=${logLimit || 0}`)\n}\n\nfunction validateStringValue(value: unknown, what: string, key?: string): string {\n  if (typeof value !== 'string') {\n    throw new Error(`Expected value for ${what}${key !== void 0 ? ' ' + quote(key) : ''} to be a string, got ${typeof value} instead`)\n  }\n  return value\n}\n\nfunction pushCommonFlags(flags: string[], options: CommonOptions, keys: OptionKeys): void {\n  let legalComments = getFlag(options, keys, 'legalComments', mustBeString)\n  let sourceRoot = getFlag(options, keys, 'sourceRoot', mustBeString)\n  let sourcesContent = getFlag(options, keys, 'sourcesContent', mustBeBoolean)\n  let target = getFlag(options, keys, 'target', mustBeStringOrArrayOfStrings)\n  let format = getFlag(options, keys, 'format', mustBeString)\n  let globalName = getFlag(options, keys, 'globalName', mustBeString)\n  let mangleProps = getFlag(options, keys, 'mangleProps', mustBeRegExp)\n  let reserveProps = getFlag(options, keys, 'reserveProps', mustBeRegExp)\n  let mangleQuoted = getFlag(options, keys, 'mangleQuoted', mustBeBoolean)\n  let minify = getFlag(options, keys, 'minify', mustBeBoolean)\n  let minifySyntax = getFlag(options, keys, 'minifySyntax', mustBeBoolean)\n  let minifyWhitespace = getFlag(options, keys, 'minifyWhitespace', mustBeBoolean)\n  let minifyIdentifiers = getFlag(options, keys, 'minifyIdentifiers', mustBeBoolean)\n  let lineLimit = getFlag(options, keys, 'lineLimit', mustBeInteger)\n  let drop = getFlag(options, keys, 'drop', mustBeArrayOfStrings)\n  let dropLabels = getFlag(options, keys, 'dropLabels', mustBeArrayOfStrings)\n  let charset = getFlag(options, keys, 'charset', mustBeString)\n  let treeShaking = getFlag(options, keys, 'treeShaking', mustBeBoolean)\n  let ignoreAnnotations = getFlag(options, keys, 'ignoreAnnotations', mustBeBoolean)\n  let jsx = getFlag(options, keys, 'jsx', mustBeString)\n  let jsxFactory = getFlag(options, keys, 'jsxFactory', mustBeString)\n  let jsxFragment = getFlag(options, keys, 'jsxFragment', mustBeString)\n  let jsxImportSource = getFlag(options, keys, 'jsxImportSource', mustBeString)\n  let jsxDev = getFlag(options, keys, 'jsxDev', mustBeBoolean)\n  let jsxSideEffects = getFlag(options, keys, 'jsxSideEffects', mustBeBoolean)\n  let define = getFlag(options, keys, 'define', mustBeObject)\n  let logOverride = getFlag(options, keys, 'logOverride', mustBeObject)\n  let supported = getFlag(options, keys, 'supported', mustBeObject)\n  let pure = getFlag(options, keys, 'pure', mustBeArrayOfStrings)\n  let keepNames = getFlag(options, keys, 'keepNames', mustBeBoolean)\n  let platform = getFlag(options, keys, 'platform', mustBeString)\n  let tsconfigRaw = getFlag(options, keys, 'tsconfigRaw', mustBeStringOrObject)\n  let absPaths = getFlag(options, keys, 'absPaths', mustBeArrayOfStrings)\n\n  if (legalComments) flags.push(`--legal-comments=${legalComments}`)\n  if (sourceRoot !== void 0) flags.push(`--source-root=${sourceRoot}`)\n  if (sourcesContent !== void 0) flags.push(`--sources-content=${sourcesContent}`)\n  if (target) flags.push(`--target=${validateAndJoinStringArray(Array.isArray(target) ? target : [target], 'target')}`)\n  if (format) flags.push(`--format=${format}`)\n  if (globalName) flags.push(`--global-name=${globalName}`)\n  if (platform) flags.push(`--platform=${platform}`)\n  if (tsconfigRaw) flags.push(`--tsconfig-raw=${typeof tsconfigRaw === 'string' ? tsconfigRaw : JSON.stringify(tsconfigRaw)}`)\n\n  if (minify) flags.push('--minify')\n  if (minifySyntax) flags.push('--minify-syntax')\n  if (minifyWhitespace) flags.push('--minify-whitespace')\n  if (minifyIdentifiers) flags.push('--minify-identifiers')\n  if (lineLimit) flags.push(`--line-limit=${lineLimit}`)\n  if (charset) flags.push(`--charset=${charset}`)\n  if (treeShaking !== void 0) flags.push(`--tree-shaking=${treeShaking}`)\n  if (ignoreAnnotations) flags.push(`--ignore-annotations`)\n  if (drop) for (let what of drop) flags.push(`--drop:${validateStringValue(what, 'drop')}`)\n  if (dropLabels) flags.push(`--drop-labels=${validateAndJoinStringArray(dropLabels, 'drop label')}`)\n  if (absPaths) flags.push(`--abs-paths=${validateAndJoinStringArray(absPaths, 'abs paths')}`)\n  if (mangleProps) flags.push(`--mangle-props=${jsRegExpToGoRegExp(mangleProps)}`)\n  if (reserveProps) flags.push(`--reserve-props=${jsRegExpToGoRegExp(reserveProps)}`)\n  if (mangleQuoted !== void 0) flags.push(`--mangle-quoted=${mangleQuoted}`)\n\n  if (jsx) flags.push(`--jsx=${jsx}`)\n  if (jsxFactory) flags.push(`--jsx-factory=${jsxFactory}`)\n  if (jsxFragment) flags.push(`--jsx-fragment=${jsxFragment}`)\n  if (jsxImportSource) flags.push(`--jsx-import-source=${jsxImportSource}`)\n  if (jsxDev) flags.push(`--jsx-dev`)\n  if (jsxSideEffects) flags.push(`--jsx-side-effects`)\n\n  if (define) {\n    for (let key in define) {\n      if (key.indexOf('=') >= 0) throw new Error(`Invalid define: ${key}`)\n      flags.push(`--define:${key}=${validateStringValue(define[key], 'define', key)}`)\n    }\n  }\n  if (logOverride) {\n    for (let key in logOverride) {\n      if (key.indexOf('=') >= 0) throw new Error(`Invalid log override: ${key}`)\n      flags.push(`--log-override:${key}=${validateStringValue(logOverride[key], 'log override', key)}`)\n    }\n  }\n  if (supported) {\n    for (let key in supported) {\n      if (key.indexOf('=') >= 0) throw new Error(`Invalid supported: ${key}`)\n      const value = supported[key]\n      if (typeof value !== 'boolean') throw new Error(`Expected value for supported ${quote(key)} to be a boolean, got ${typeof value} instead`)\n      flags.push(`--supported:${key}=${value}`)\n    }\n  }\n  if (pure) for (let fn of pure) flags.push(`--pure:${validateStringValue(fn, 'pure')}`)\n  if (keepNames) flags.push(`--keep-names`)\n}\n\nfunction flagsForBuildOptions(\n  callName: string,\n  options: types.BuildOptions,\n  isTTY: boolean,\n  logLevelDefault: types.LogLevel,\n  writeDefault: boolean,\n): {\n  entries: [string, string][],\n  flags: string[],\n  write: boolean,\n  stdinContents: Uint8Array | null,\n  stdinResolveDir: string | null,\n  absWorkingDir: string | undefined,\n  nodePaths: string[],\n  mangleCache: MangleCache | undefined,\n} {\n  let flags: string[] = []\n  let entries: [string, string][] = []\n  let keys: OptionKeys = Object.create(null)\n  let stdinContents: Uint8Array | null = null\n  let stdinResolveDir: string | null = null\n  pushLogFlags(flags, options, keys, isTTY, logLevelDefault)\n  pushCommonFlags(flags, options, keys)\n\n  let sourcemap = getFlag(options, keys, 'sourcemap', mustBeStringOrBoolean)\n  let bundle = getFlag(options, keys, 'bundle', mustBeBoolean)\n  let splitting = getFlag(options, keys, 'splitting', mustBeBoolean)\n  let preserveSymlinks = getFlag(options, keys, 'preserveSymlinks', mustBeBoolean)\n  let metafile = getFlag(options, keys, 'metafile', mustBeBoolean)\n  let outfile = getFlag(options, keys, 'outfile', mustBeString)\n  let outdir = getFlag(options, keys, 'outdir', mustBeString)\n  let outbase = getFlag(options, keys, 'outbase', mustBeString)\n  let tsconfig = getFlag(options, keys, 'tsconfig', mustBeString)\n  let resolveExtensions = getFlag(options, keys, 'resolveExtensions', mustBeArrayOfStrings)\n  let nodePathsInput = getFlag(options, keys, 'nodePaths', mustBeArrayOfStrings)\n  let mainFields = getFlag(options, keys, 'mainFields', mustBeArrayOfStrings)\n  let conditions = getFlag(options, keys, 'conditions', mustBeArrayOfStrings)\n  let external = getFlag(options, keys, 'external', mustBeArrayOfStrings)\n  let packages = getFlag(options, keys, 'packages', mustBeString)\n  let alias = getFlag(options, keys, 'alias', mustBeObject)\n  let loader = getFlag(options, keys, 'loader', mustBeObject)\n  let outExtension = getFlag(options, keys, 'outExtension', mustBeObject)\n  let publicPath = getFlag(options, keys, 'publicPath', mustBeString)\n  let entryNames = getFlag(options, keys, 'entryNames', mustBeString)\n  let chunkNames = getFlag(options, keys, 'chunkNames', mustBeString)\n  let assetNames = getFlag(options, keys, 'assetNames', mustBeString)\n  let inject = getFlag(options, keys, 'inject', mustBeArrayOfStrings)\n  let banner = getFlag(options, keys, 'banner', mustBeObject)\n  let footer = getFlag(options, keys, 'footer', mustBeObject)\n  let entryPoints = getFlag(options, keys, 'entryPoints', mustBeEntryPoints)\n  let absWorkingDir = getFlag(options, keys, 'absWorkingDir', mustBeString)\n  let stdin = getFlag(options, keys, 'stdin', mustBeObject)\n  let write = getFlag(options, keys, 'write', mustBeBoolean) ?? writeDefault; // Default to true if not specified\n  let allowOverwrite = getFlag(options, keys, 'allowOverwrite', mustBeBoolean)\n  let mangleCache = getFlag(options, keys, 'mangleCache', mustBeObject)\n  keys.plugins = true; // \"plugins\" has already been read earlier\n  checkForInvalidFlags(options, keys, `in ${callName}() call`)\n\n  if (sourcemap) flags.push(`--sourcemap${sourcemap === true ? '' : `=${sourcemap}`}`)\n  if (bundle) flags.push('--bundle')\n  if (allowOverwrite) flags.push('--allow-overwrite')\n  if (splitting) flags.push('--splitting')\n  if (preserveSymlinks) flags.push('--preserve-symlinks')\n  if (metafile) flags.push(`--metafile`)\n  if (outfile) flags.push(`--outfile=${outfile}`)\n  if (outdir) flags.push(`--outdir=${outdir}`)\n  if (outbase) flags.push(`--outbase=${outbase}`)\n  if (tsconfig) flags.push(`--tsconfig=${tsconfig}`)\n  if (packages) flags.push(`--packages=${packages}`)\n  if (resolveExtensions) flags.push(`--resolve-extensions=${validateAndJoinStringArray(resolveExtensions, 'resolve extension')}`)\n  if (publicPath) flags.push(`--public-path=${publicPath}`)\n  if (entryNames) flags.push(`--entry-names=${entryNames}`)\n  if (chunkNames) flags.push(`--chunk-names=${chunkNames}`)\n  if (assetNames) flags.push(`--asset-names=${assetNames}`)\n  if (mainFields) flags.push(`--main-fields=${validateAndJoinStringArray(mainFields, 'main field')}`)\n  if (conditions) flags.push(`--conditions=${validateAndJoinStringArray(conditions, 'condition')}`)\n  if (external) for (let name of external) flags.push(`--external:${validateStringValue(name, 'external')}`)\n  if (alias) {\n    for (let old in alias) {\n      if (old.indexOf('=') >= 0) throw new Error(`Invalid package name in alias: ${old}`)\n      flags.push(`--alias:${old}=${validateStringValue(alias[old], 'alias', old)}`)\n    }\n  }\n  if (banner) {\n    for (let type in banner) {\n      if (type.indexOf('=') >= 0) throw new Error(`Invalid banner file type: ${type}`)\n      flags.push(`--banner:${type}=${validateStringValue(banner[type], 'banner', type)}`)\n    }\n  }\n  if (footer) {\n    for (let type in footer) {\n      if (type.indexOf('=') >= 0) throw new Error(`Invalid footer file type: ${type}`)\n      flags.push(`--footer:${type}=${validateStringValue(footer[type], 'footer', type)}`)\n    }\n  }\n  if (inject) for (let path of inject) flags.push(`--inject:${validateStringValue(path, 'inject')}`)\n  if (loader) {\n    for (let ext in loader) {\n      if (ext.indexOf('=') >= 0) throw new Error(`Invalid loader extension: ${ext}`)\n      flags.push(`--loader:${ext}=${validateStringValue(loader[ext], 'loader', ext)}`)\n    }\n  }\n  if (outExtension) {\n    for (let ext in outExtension) {\n      if (ext.indexOf('=') >= 0) throw new Error(`Invalid out extension: ${ext}`)\n      flags.push(`--out-extension:${ext}=${validateStringValue(outExtension[ext], 'out extension', ext)}`)\n    }\n  }\n\n  if (entryPoints) {\n    if (Array.isArray(entryPoints)) {\n      for (let i = 0, n = entryPoints.length; i < n; i++) {\n        let entryPoint = entryPoints[i]\n        if (typeof entryPoint === 'object' && entryPoint !== null) {\n          let entryPointKeys: OptionKeys = Object.create(null)\n          let input = getFlag(entryPoint, entryPointKeys, 'in', mustBeString)\n          let output = getFlag(entryPoint, entryPointKeys, 'out', mustBeString)\n          checkForInvalidFlags(entryPoint, entryPointKeys, 'in entry point at index ' + i)\n          if (input === undefined) throw new Error('Missing property \"in\" for entry point at index ' + i)\n          if (output === undefined) throw new Error('Missing property \"out\" for entry point at index ' + i)\n          entries.push([output, input])\n        } else {\n          entries.push(['', validateStringValue(entryPoint, 'entry point at index ' + i)])\n        }\n      }\n    } else {\n      for (let key in entryPoints) {\n        entries.push([key, validateStringValue(entryPoints[key], 'entry point', key)])\n      }\n    }\n  }\n\n  if (stdin) {\n    let stdinKeys: OptionKeys = Object.create(null)\n    let contents = getFlag(stdin, stdinKeys, 'contents', mustBeStringOrUint8Array)\n    let resolveDir = getFlag(stdin, stdinKeys, 'resolveDir', mustBeString)\n    let sourcefile = getFlag(stdin, stdinKeys, 'sourcefile', mustBeString)\n    let loader = getFlag(stdin, stdinKeys, 'loader', mustBeString)\n    checkForInvalidFlags(stdin, stdinKeys, 'in \"stdin\" object')\n\n    if (sourcefile) flags.push(`--sourcefile=${sourcefile}`)\n    if (loader) flags.push(`--loader=${loader}`)\n    if (resolveDir) stdinResolveDir = resolveDir\n    if (typeof contents === 'string') stdinContents = protocol.encodeUTF8(contents)\n    else if (contents instanceof Uint8Array) stdinContents = contents\n  }\n\n  let nodePaths: string[] = []\n  if (nodePathsInput) {\n    for (let value of nodePathsInput) {\n      value += ''\n      nodePaths.push(value)\n    }\n  }\n\n  return {\n    entries,\n    flags,\n    write,\n    stdinContents,\n    stdinResolveDir,\n    absWorkingDir,\n    nodePaths,\n    mangleCache: validateMangleCache(mangleCache),\n  }\n}\n\nfunction flagsForTransformOptions(\n  callName: string,\n  options: types.TransformOptions,\n  isTTY: boolean,\n  logLevelDefault: types.LogLevel,\n): {\n  flags: string[],\n  mangleCache: MangleCache | undefined,\n} {\n  let flags: string[] = []\n  let keys: OptionKeys = Object.create(null)\n  pushLogFlags(flags, options, keys, isTTY, logLevelDefault)\n  pushCommonFlags(flags, options, keys)\n\n  let sourcemap = getFlag(options, keys, 'sourcemap', mustBeStringOrBoolean)\n  let sourcefile = getFlag(options, keys, 'sourcefile', mustBeString)\n  let loader = getFlag(options, keys, 'loader', mustBeString)\n  let banner = getFlag(options, keys, 'banner', mustBeString)\n  let footer = getFlag(options, keys, 'footer', mustBeString)\n  let mangleCache = getFlag(options, keys, 'mangleCache', mustBeObject)\n  checkForInvalidFlags(options, keys, `in ${callName}() call`)\n\n  if (sourcemap) flags.push(`--sourcemap=${sourcemap === true ? 'external' : sourcemap}`)\n  if (sourcefile) flags.push(`--sourcefile=${sourcefile}`)\n  if (loader) flags.push(`--loader=${loader}`)\n  if (banner) flags.push(`--banner=${banner}`)\n  if (footer) flags.push(`--footer=${footer}`)\n\n  return {\n    flags,\n    mangleCache: validateMangleCache(mangleCache),\n  }\n}\n\nexport interface StreamIn {\n  writeToStdin: (data: Uint8Array) => void\n  readFileSync?: (path: string, encoding: 'utf8') => string\n  isSync: boolean\n  hasFS: boolean\n  esbuild: types.PluginBuild['esbuild']\n}\n\nexport interface StreamOut {\n  readFromStdout: (data: Uint8Array) => void\n  afterClose: (error: Error | null) => void\n  service: StreamService\n}\n\nexport interface StreamFS {\n  writeFile(contents: string | Uint8Array, callback: (path: string | null) => void): void\n  readFile(path: string, callback: (err: Error | null, contents: string | null) => void): void\n}\n\nexport interface Refs {\n  ref(): void\n  unref(): void\n}\n\nexport interface StreamService {\n  buildOrContext(args: {\n    callName: string,\n    refs: Refs | null,\n    options: types.BuildOptions,\n    isTTY: boolean,\n    defaultWD: string,\n    callback: (err: Error | null, res: types.BuildResult | types.BuildContext | null) => void,\n  }): void\n\n  transform(args: {\n    callName: string,\n    refs: Refs | null,\n    input: string | Uint8Array,\n    options: types.TransformOptions,\n    isTTY: boolean,\n    fs: StreamFS,\n    callback: (err: Error | null, res: types.TransformResult | null) => void,\n  }): void\n\n  formatMessages(args: {\n    callName: string,\n    refs: Refs | null,\n    messages: types.PartialMessage[],\n    options: types.FormatMessagesOptions,\n    callback: (err: Error | null, res: string[] | null) => void,\n  }): void\n\n  analyzeMetafile(args: {\n    callName: string,\n    refs: Refs | null,\n    metafile: string,\n    options: types.AnalyzeMetafileOptions | undefined,\n    callback: (err: Error | null, res: string | null) => void,\n  }): void\n}\n\ntype CloseData = { didClose: boolean, reason: string }\ntype RequestCallback = (id: number, request: any) => Promise<void> | void\n\n// This can't use any promises in the main execution flow because it must work\n// for both sync and async code. There is an exception for plugin code because\n// that can't work in sync code anyway.\nexport function createChannel(streamIn: StreamIn): StreamOut {\n  const requestCallbacksByKey: { [key: number]: { [command: string]: RequestCallback } } = {}\n  const closeData: CloseData = { didClose: false, reason: '' }\n  let responseCallbacks: { [id: number]: (error: string | null, response: protocol.Value) => void } = {}\n  let nextRequestID = 0\n  let nextBuildKey = 0\n\n  // Use a long-lived buffer to store stdout data\n  let stdout = new Uint8Array(16 * 1024)\n  let stdoutUsed = 0\n  let readFromStdout = (chunk: Uint8Array) => {\n    // Append the chunk to the stdout buffer, growing it as necessary\n    let limit = stdoutUsed + chunk.length\n    if (limit > stdout.length) {\n      let swap = new Uint8Array(limit * 2)\n      swap.set(stdout)\n      stdout = swap\n    }\n    stdout.set(chunk, stdoutUsed)\n    stdoutUsed += chunk.length\n\n    // Process all complete (i.e. not partial) packets\n    let offset = 0\n    while (offset + 4 <= stdoutUsed) {\n      let length = protocol.readUInt32LE(stdout, offset)\n      if (offset + 4 + length > stdoutUsed) {\n        break\n      }\n      offset += 4\n      handleIncomingPacket(stdout.subarray(offset, offset + length))\n      offset += length\n    }\n    if (offset > 0) {\n      stdout.copyWithin(0, offset, stdoutUsed)\n      stdoutUsed -= offset\n    }\n  }\n\n  let afterClose = (error: Error | null) => {\n    // When the process is closed, fail all pending requests\n    closeData.didClose = true\n    if (error) closeData.reason = ': ' + (error.message || error)\n    const text = 'The service was stopped' + closeData.reason\n    for (let id in responseCallbacks) {\n      responseCallbacks[id](text, null)\n    }\n    responseCallbacks = {}\n  }\n\n  let sendRequest = <Req, Res>(refs: Refs | null, value: Req, callback: (error: string | null, response: Res | null) => void): void => {\n    if (closeData.didClose) return callback('The service is no longer running' + closeData.reason, null)\n    let id = nextRequestID++\n    responseCallbacks[id] = (error, response) => {\n      try {\n        callback(error, response as any)\n      } finally {\n        if (refs) refs.unref() // Do this after the callback so the callback can extend the lifetime if needed\n      }\n    }\n    if (refs) refs.ref()\n    streamIn.writeToStdin(protocol.encodePacket({ id, isRequest: true, value: value as any }))\n  }\n\n  let sendResponse = (id: number, value: protocol.Value): void => {\n    if (closeData.didClose) throw new Error('The service is no longer running' + closeData.reason)\n    streamIn.writeToStdin(protocol.encodePacket({ id, isRequest: false, value }))\n  }\n\n  let handleRequest = async (id: number, request: any) => {\n    // Catch exceptions in the code below so they get passed to the caller\n    try {\n      if (request.command === 'ping') {\n        sendResponse(id, {})\n        return\n      }\n\n      if (typeof request.key === 'number') {\n        const requestCallbacks = requestCallbacksByKey[request.key]\n        if (!requestCallbacks) {\n          // Ignore invalid commands for old builds that no longer exist.\n          // This can happen when \"context.cancel\" and \"context.dispose\"\n          // is called while esbuild is processing many files in parallel.\n          // See https://github.com/evanw/esbuild/issues/3318 for details.\n          return\n        }\n        const callback = requestCallbacks[request.command]\n        if (callback) {\n          await callback(id, request)\n          return\n        }\n      }\n\n      throw new Error(`Invalid command: ` + request.command)\n    } catch (e) {\n      const errors = [extractErrorMessageV8(e, streamIn, null, void 0, '')]\n      try {\n        sendResponse(id, { errors } as any)\n      } catch {\n        // This may fail if the esbuild process is no longer running, but\n        // that's ok. Catch and swallow this exception so that we don't\n        // cause an unhandled promise rejection. Our caller isn't expecting\n        // this call to fail and doesn't handle the promise rejection.\n      }\n    }\n  }\n\n  let isFirstPacket = true\n\n  let handleIncomingPacket = (bytes: Uint8Array): void => {\n    // The first packet is a version check\n    if (isFirstPacket) {\n      isFirstPacket = false\n\n      // Validate the binary's version number to make sure esbuild was installed\n      // correctly. This check was added because some people have reported\n      // errors that appear to indicate an incorrect installation.\n      let binaryVersion = String.fromCharCode(...bytes)\n      if (binaryVersion !== ESBUILD_VERSION) {\n        throw new Error(`Cannot start service: Host version \"${ESBUILD_VERSION}\" does not match binary version ${quote(binaryVersion)}`)\n      }\n      return\n    }\n\n    let packet = protocol.decodePacket(bytes) as any\n\n    if (packet.isRequest) {\n      handleRequest(packet.id, packet.value)\n    }\n\n    else {\n      let callback = responseCallbacks[packet.id]!\n      delete responseCallbacks[packet.id]\n      if (packet.value.error) callback(packet.value.error, {})\n      else callback(null, packet.value)\n    }\n  }\n\n  let buildOrContext: StreamService['buildOrContext'] = ({ callName, refs, options, isTTY, defaultWD, callback }) => {\n    let refCount = 0\n    const buildKey = nextBuildKey++\n    const requestCallbacks: { [command: string]: RequestCallback } = {}\n    const buildRefs: Refs = {\n      ref() {\n        if (++refCount === 1) {\n          if (refs) refs.ref()\n        }\n      },\n      unref() {\n        if (--refCount === 0) {\n          delete requestCallbacksByKey[buildKey]\n          if (refs) refs.unref()\n        }\n      },\n    }\n    requestCallbacksByKey[buildKey] = requestCallbacks\n\n    // Guard the whole \"build\" request with a temporary ref count bump. We\n    // don't want the ref count to be bumped above zero and then back down\n    // to zero before the callback is called.\n    buildRefs.ref()\n    buildOrContextImpl(\n      callName,\n      buildKey,\n      sendRequest,\n      sendResponse,\n      buildRefs,\n      streamIn,\n      requestCallbacks,\n      options,\n      isTTY,\n      defaultWD,\n      (err, res) => {\n        // Now that the initial \"build\" request is done, we can release our\n        // temporary ref count bump. Any code that wants to extend the life\n        // of the build will have to do so by explicitly retaining a count.\n        try {\n          callback(err, res)\n        } finally {\n          buildRefs.unref()\n        }\n      },\n    )\n  }\n\n  let transform: StreamService['transform'] = ({ callName, refs, input, options, isTTY, fs, callback }) => {\n    const details = createObjectStash()\n\n    // Ideally the \"transform()\" API would be faster than calling \"build()\"\n    // since it doesn't need to touch the file system. However, performance\n    // measurements with large files on macOS indicate that sending the data\n    // over the stdio pipe can be 2x slower than just using a temporary file.\n    //\n    // This appears to be an OS limitation. Both the JavaScript and Go code\n    // are using large buffers but the pipe only writes data in 8kb chunks.\n    // An investigation seems to indicate that this number is hard-coded into\n    // the OS source code. Presumably files are faster because the OS uses\n    // a larger chunk size, or maybe even reads everything in one syscall.\n    //\n    // The cross-over size where this starts to be faster is around 1mb on\n    // my machine. In that case, this code tries to use a temporary file if\n    // possible but falls back to sending the data over the stdio pipe if\n    // that doesn't work.\n    let start = (inputPath: string | null) => {\n      try {\n        if (typeof input !== 'string' && !(input instanceof Uint8Array))\n          throw new Error('The input to \"transform\" must be a string or a Uint8Array')\n        let {\n          flags,\n          mangleCache,\n        } = flagsForTransformOptions(callName, options, isTTY, transformLogLevelDefault)\n        let request: protocol.TransformRequest = {\n          command: 'transform',\n          flags,\n          inputFS: inputPath !== null,\n          input: inputPath !== null ? protocol.encodeUTF8(inputPath)\n            : typeof input === 'string' ? protocol.encodeUTF8(input)\n              : input,\n        }\n        if (mangleCache) request.mangleCache = mangleCache\n        sendRequest<protocol.TransformRequest, protocol.TransformResponse>(refs, request, (error, response) => {\n          if (error) return callback(new Error(error), null)\n          let errors = replaceDetailsInMessages(response!.errors, details)\n          let warnings = replaceDetailsInMessages(response!.warnings, details)\n          let outstanding = 1\n          let next = () => {\n            if (--outstanding === 0) {\n              let result: types.TransformResult = {\n                warnings,\n                code: response!.code,\n                map: response!.map,\n                mangleCache: undefined,\n                legalComments: undefined,\n              }\n              if ('legalComments' in response!) result.legalComments = response?.legalComments\n              if (response!.mangleCache) result.mangleCache = response?.mangleCache\n              callback(null, result)\n            }\n          }\n          if (errors.length > 0) return callback(failureErrorWithLog('Transform failed', errors, warnings), null)\n\n          // Read the JavaScript file from the file system\n          if (response!.codeFS) {\n            outstanding++\n            fs.readFile(response!.code, (err, contents) => {\n              if (err !== null) {\n                callback(err, null)\n              } else {\n                response!.code = contents!\n                next()\n              }\n            })\n          }\n\n          // Read the source map file from the file system\n          if (response!.mapFS) {\n            outstanding++\n            fs.readFile(response!.map, (err, contents) => {\n              if (err !== null) {\n                callback(err, null)\n              } else {\n                response!.map = contents!\n                next()\n              }\n            })\n          }\n\n          next()\n        })\n      } catch (e) {\n        let flags: string[] = []\n        try { pushLogFlags(flags, options, {}, isTTY, transformLogLevelDefault) } catch { }\n        const error = extractErrorMessageV8(e, streamIn, details, void 0, '')\n        sendRequest(refs, { command: 'error', flags, error }, () => {\n          error.detail = details.load(error.detail)\n          callback(failureErrorWithLog('Transform failed', [error], []), null)\n        })\n      }\n    }\n    if ((typeof input === 'string' || input instanceof Uint8Array) && input.length > 1024 * 1024) {\n      let next = start\n      start = () => fs.writeFile(input, next)\n    }\n    start(null)\n  }\n\n  let formatMessages: StreamService['formatMessages'] = ({ callName, refs, messages, options, callback }) => {\n    if (!options) throw new Error(`Missing second argument in ${callName}() call`)\n    let keys: OptionKeys = {}\n    let kind = getFlag(options, keys, 'kind', mustBeString)\n    let color = getFlag(options, keys, 'color', mustBeBoolean)\n    let terminalWidth = getFlag(options, keys, 'terminalWidth', mustBeInteger)\n    checkForInvalidFlags(options, keys, `in ${callName}() call`)\n    if (kind === void 0) throw new Error(`Missing \"kind\" in ${callName}() call`)\n    if (kind !== 'error' && kind !== 'warning') throw new Error(`Expected \"kind\" to be \"error\" or \"warning\" in ${callName}() call`)\n    let request: protocol.FormatMsgsRequest = {\n      command: 'format-msgs',\n      messages: sanitizeMessages(messages, 'messages', null, '', terminalWidth),\n      isWarning: kind === 'warning',\n    }\n    if (color !== void 0) request.color = color\n    if (terminalWidth !== void 0) request.terminalWidth = terminalWidth\n    sendRequest<protocol.FormatMsgsRequest, protocol.FormatMsgsResponse>(refs, request, (error, response) => {\n      if (error) return callback(new Error(error), null)\n      callback(null, response!.messages)\n    })\n  }\n\n  let analyzeMetafile: StreamService['analyzeMetafile'] = ({ callName, refs, metafile, options, callback }) => {\n    if (options === void 0) options = {}\n    let keys: OptionKeys = {}\n    let color = getFlag(options, keys, 'color', mustBeBoolean)\n    let verbose = getFlag(options, keys, 'verbose', mustBeBoolean)\n    checkForInvalidFlags(options, keys, `in ${callName}() call`)\n    let request: protocol.AnalyzeMetafileRequest = {\n      command: 'analyze-metafile',\n      metafile,\n    }\n    if (color !== void 0) request.color = color\n    if (verbose !== void 0) request.verbose = verbose\n    sendRequest<protocol.AnalyzeMetafileRequest, protocol.AnalyzeMetafileResponse>(refs, request, (error, response) => {\n      if (error) return callback(new Error(error), null)\n      callback(null, response!.result)\n    })\n  }\n\n  return {\n    readFromStdout,\n    afterClose,\n    service: {\n      buildOrContext,\n      transform,\n      formatMessages,\n      analyzeMetafile,\n    },\n  }\n}\n\nfunction buildOrContextImpl(\n  callName: string,\n  buildKey: number,\n  sendRequest: <Req, Res>(refs: Refs | null, value: Req, callback: (error: string | null, response: Res | null) => void) => void,\n  sendResponse: (id: number, value: protocol.Value) => void,\n  refs: Refs,\n  streamIn: StreamIn,\n  requestCallbacks: { [command: string]: RequestCallback },\n  options: types.BuildOptions,\n  isTTY: boolean,\n  defaultWD: string,\n  callback: (err: Error | null, res: types.BuildResult | types.BuildContext | null) => void,\n): void {\n  const details = createObjectStash()\n  const isContext = callName === 'context'\n\n  const handleError = (e: any, pluginName: string): void => {\n    const flags: string[] = []\n    try { pushLogFlags(flags, options, {}, isTTY, buildLogLevelDefault) } catch { }\n    const message = extractErrorMessageV8(e, streamIn, details, void 0, pluginName)\n    sendRequest(refs, { command: 'error', flags, error: message }, () => {\n      message.detail = details.load(message.detail)\n      callback(failureErrorWithLog(isContext ? 'Context failed' : 'Build failed', [message], []), null)\n    })\n  }\n\n  let plugins: types.Plugin[] | undefined\n  if (typeof options === 'object') {\n    const value = options.plugins\n    if (value !== void 0) {\n      if (!Array.isArray(value)) return handleError(new Error(`\"plugins\" must be an array`), '')\n      plugins = value\n    }\n  }\n\n  if (plugins && plugins.length > 0) {\n    if (streamIn.isSync) return handleError(new Error('Cannot use plugins in synchronous API calls'), '')\n\n    // Plugins can use async/await because they can't be run with \"buildSync\"\n    handlePlugins(\n      buildKey,\n      sendRequest,\n      sendResponse,\n      refs,\n      streamIn,\n      requestCallbacks,\n      options,\n      plugins,\n      details,\n    ).then(\n      result => {\n        if (!result.ok) return handleError(result.error, result.pluginName)\n        try {\n          buildOrContextContinue(result.requestPlugins, result.runOnEndCallbacks, result.scheduleOnDisposeCallbacks)\n        } catch (e) {\n          handleError(e, '')\n        }\n      },\n      e => handleError(e, ''),\n    )\n    return\n  }\n\n  try {\n    buildOrContextContinue(null, (result, done) => done([], []), () => { })\n  } catch (e) {\n    handleError(e, '')\n  }\n\n  // \"buildOrContext\" cannot be written using async/await due to \"buildSync\"\n  // and must be written in continuation-passing style instead\n  function buildOrContextContinue(requestPlugins: protocol.BuildPlugin[] | null, runOnEndCallbacks: RunOnEndCallbacks, scheduleOnDisposeCallbacks: () => void) {\n    const writeDefault = streamIn.hasFS\n    const {\n      entries,\n      flags,\n      write,\n      stdinContents,\n      stdinResolveDir,\n      absWorkingDir,\n      nodePaths,\n      mangleCache,\n    } = flagsForBuildOptions(callName, options, isTTY, buildLogLevelDefault, writeDefault)\n    if (write && !streamIn.hasFS) throw new Error(`The \"write\" option is unavailable in this environment`)\n\n    // Construct the request\n    const request: protocol.BuildRequest = {\n      command: 'build',\n      key: buildKey,\n      entries,\n      flags,\n      write,\n      stdinContents,\n      stdinResolveDir,\n      absWorkingDir: absWorkingDir || defaultWD,\n      nodePaths,\n      context: isContext,\n    }\n    if (requestPlugins) request.plugins = requestPlugins\n    if (mangleCache) request.mangleCache = mangleCache\n\n    // Factor out response handling so it can be reused for rebuilds\n    const buildResponseToResult = (\n      response: protocol.BuildResponse | null,\n      callback: (error: types.BuildFailure | null, result: types.BuildResult | null, onEndErrors: types.Message[], onEndWarnings: types.Message[]) => void,\n    ): void => {\n      const result: types.BuildResult = {\n        errors: replaceDetailsInMessages(response!.errors, details),\n        warnings: replaceDetailsInMessages(response!.warnings, details),\n        outputFiles: undefined,\n        metafile: undefined,\n        mangleCache: undefined,\n      }\n      const originalErrors = result.errors.slice()\n      const originalWarnings = result.warnings.slice()\n      if (response!.outputFiles) result.outputFiles = response!.outputFiles.map(convertOutputFiles)\n      if (response!.metafile) result.metafile = parseJSON(response!.metafile)\n      if (response!.mangleCache) result.mangleCache = response!.mangleCache\n      if (response!.writeToStdout !== void 0) console.log(protocol.decodeUTF8(response!.writeToStdout).replace(/\\n$/, ''))\n      runOnEndCallbacks(result, (onEndErrors, onEndWarnings) => {\n        if (originalErrors.length > 0 || onEndErrors.length > 0) {\n          const error = failureErrorWithLog('Build failed', originalErrors.concat(onEndErrors), originalWarnings.concat(onEndWarnings))\n          return callback(error, null, onEndErrors, onEndWarnings)\n        }\n        callback(null, result, onEndErrors, onEndWarnings)\n      })\n    }\n\n    // In context mode, Go runs the \"onEnd\" callbacks instead of JavaScript\n    let latestResultPromise: Promise<types.BuildResult> | undefined\n    let provideLatestResult: ((error: types.BuildFailure | null, result: types.BuildResult | null) => void) | undefined\n    if (isContext)\n      requestCallbacks['on-end'] = (id, request: protocol.OnEndRequest) =>\n        new Promise(resolve => {\n          buildResponseToResult(request, (err, result, onEndErrors, onEndWarnings) => {\n            const response: protocol.OnEndResponse = {\n              errors: onEndErrors,\n              warnings: onEndWarnings,\n            }\n            if (provideLatestResult) provideLatestResult(err, result)\n            latestResultPromise = undefined\n            provideLatestResult = undefined\n            sendResponse(id, response as any)\n            resolve()\n          })\n        })\n\n    sendRequest<protocol.BuildRequest, protocol.BuildResponse>(refs, request, (error, response) => {\n      if (error) return callback(new Error(error), null)\n      if (!isContext) {\n        return buildResponseToResult(response!, (err, res) => {\n          scheduleOnDisposeCallbacks()\n          return callback(err, res)\n        })\n      }\n\n      // Construct a context object\n      if (response!.errors.length > 0) {\n        return callback(failureErrorWithLog('Context failed', response!.errors, response!.warnings), null)\n      }\n      let didDispose = false\n      const result: types.BuildContext = {\n        rebuild: () => {\n          if (!latestResultPromise) latestResultPromise = new Promise((resolve, reject) => {\n            let settlePromise: (() => void) | undefined\n            provideLatestResult = (err, result) => {\n              if (!settlePromise) settlePromise = () => err ? reject(err) : resolve(result!)\n            }\n            const triggerAnotherBuild = (): void => {\n              const request: protocol.RebuildRequest = {\n                command: 'rebuild',\n                key: buildKey,\n              }\n              sendRequest<protocol.RebuildRequest, protocol.RebuildResponse>(refs, request, (error, response) => {\n                if (error) {\n                  reject(new Error(error))\n                } else if (settlePromise) {\n                  // It's possible to settle the promise that we returned from\n                  // this \"rebuild()\" function earlier than this point. However,\n                  // at that point the user could call \"rebuild()\" again which\n                  // would unexpectedly merge with the same build that's still\n                  // ongoing. To prevent that, we defer settling the promise\n                  // until now when we know that the build has finished.\n                  settlePromise()\n                } else {\n                  // When we call \"rebuild()\", we call out to the Go \"Rebuild()\"\n                  // API over IPC. That may trigger a build, but may also \"join\"\n                  // an existing build. At some point the Go code sends us an\n                  // \"on-end\" message with the build result to tell us to run\n                  // our \"onEnd\" plugins. We capture that build result and return\n                  // it here.\n                  //\n                  // However, there's a potential problem: For performance, the\n                  // Go code will only send us the result if it's needed, which\n                  // only happens if there are \"onEnd\" callbacks or if \"rebuild\"\n                  // was called. So there's a race where the following things\n                  // happen:\n                  //\n                  // 1. Go starts a rebuild (e.g. due to watch mode)\n                  // 2. JS calls \"rebuild()\"\n                  // 3. Go ends the build and starts Go's \"OnEnd\" callback\n                  // 4. Go's \"OnEnd\" callback sees no need to send the result\n                  // 5. JS asks Go to rebuild, which merges with the existing build\n                  // 6. Go's existing build ends\n                  // 7. The merged build ends, which wakes up JS and ends up here\n                  //\n                  // In that situation we didn't get an \"on-end\" message since\n                  // Go thought it wasn't necessary. In that situation, we\n                  // trigger another rebuild below so that Go will (almost\n                  // surely) send us an \"on-end\" message next time. I suspect\n                  // that this is a very rare case, so the performance impact\n                  // of building twice shouldn't really matter. It also only\n                  // happens when \"rebuild()\" is used with \"watch()\" and/or\n                  // \"serve()\".\n                  triggerAnotherBuild()\n                }\n              })\n            }\n            triggerAnotherBuild()\n          })\n          return latestResultPromise\n        },\n\n        watch: (options = {}) => new Promise((resolve, reject) => {\n          if (!streamIn.hasFS) throw new Error(`Cannot use the \"watch\" API in this environment`)\n          const keys: OptionKeys = {}\n          const delay = getFlag(options, keys, 'delay', mustBeInteger)\n          checkForInvalidFlags(options, keys, `in watch() call`)\n          const request: protocol.WatchRequest = {\n            command: 'watch',\n            key: buildKey,\n          }\n          if (delay) request.delay = delay\n          sendRequest<protocol.WatchRequest, null>(refs, request, error => {\n            if (error) reject(new Error(error))\n            else resolve(undefined)\n          })\n        }),\n\n        serve: (options = {}) => new Promise((resolve, reject) => {\n          if (!streamIn.hasFS) throw new Error(`Cannot use the \"serve\" API in this environment`)\n          const keys: OptionKeys = {}\n          const port = getFlag(options, keys, 'port', mustBeValidPortNumber)\n          const host = getFlag(options, keys, 'host', mustBeString)\n          const servedir = getFlag(options, keys, 'servedir', mustBeString)\n          const keyfile = getFlag(options, keys, 'keyfile', mustBeString)\n          const certfile = getFlag(options, keys, 'certfile', mustBeString)\n          const fallback = getFlag(options, keys, 'fallback', mustBeString)\n          const cors = getFlag(options, keys, 'cors', mustBeObject)\n          const onRequest = getFlag(options, keys, 'onRequest', mustBeFunction)\n          checkForInvalidFlags(options, keys, `in serve() call`)\n\n          const request: protocol.ServeRequest = {\n            command: 'serve',\n            key: buildKey,\n            onRequest: !!onRequest,\n          }\n          if (port !== void 0) request.port = port\n          if (host !== void 0) request.host = host\n          if (servedir !== void 0) request.servedir = servedir\n          if (keyfile !== void 0) request.keyfile = keyfile\n          if (certfile !== void 0) request.certfile = certfile\n          if (fallback !== void 0) request.fallback = fallback\n\n          if (cors) {\n            const corsKeys: OptionKeys = {}\n            const origin = getFlag(cors, corsKeys, 'origin', mustBeStringOrArrayOfStrings)\n            checkForInvalidFlags(cors, corsKeys, `on \"cors\" object`)\n            if (Array.isArray(origin)) request.corsOrigin = origin\n            else if (origin !== void 0) request.corsOrigin = [origin]\n          }\n\n          sendRequest<protocol.ServeRequest, protocol.ServeResponse>(refs, request, (error, response) => {\n            if (error) return reject(new Error(error))\n            if (onRequest) {\n              requestCallbacks['serve-request'] = (id, request: protocol.OnServeRequest) => {\n                onRequest(request.args)\n                sendResponse(id, {})\n              }\n            }\n            resolve(response!)\n          })\n        }),\n\n        cancel: () => new Promise(resolve => {\n          if (didDispose) return resolve()\n          const request: protocol.CancelRequest = {\n            command: 'cancel',\n            key: buildKey,\n          }\n          sendRequest<protocol.CancelRequest, null>(refs, request, () => {\n            resolve(); // We don't care about errors here\n          })\n        }),\n\n        dispose: () => new Promise(resolve => {\n          if (didDispose) return resolve()\n          didDispose = true // Don't dispose more than once\n          const request: protocol.DisposeRequest = {\n            command: 'dispose',\n            key: buildKey,\n          }\n          sendRequest<protocol.DisposeRequest, null>(refs, request, () => {\n            resolve(); // We don't care about errors here\n            scheduleOnDisposeCallbacks()\n\n            // Only remove the reference here when we know the Go code has seen\n            // this \"dispose\" call. We don't want to remove any registered\n            // callbacks before that point because the Go code might still be\n            // sending us events. If we remove the reference earlier then we\n            // will return errors for those events, which may end up being\n            // printed to the terminal where the user can see them, which would\n            // be very confusing.\n            refs.unref()\n          })\n        }),\n      }\n      refs.ref(); // Keep a reference until \"dispose\" is called\n      callback(null, result)\n    })\n  }\n}\n\ntype RunOnEndCallbacks = (result: types.BuildResult, done: (errors: types.Message[], warnings: types.Message[]) => void) => void\n\nlet handlePlugins = async (\n  buildKey: number,\n  sendRequest: <Req, Res>(refs: Refs | null, value: Req, callback: (error: string | null, response: Res | null) => void) => void,\n  sendResponse: (id: number, value: protocol.Value) => void,\n  refs: Refs,\n  streamIn: StreamIn,\n  requestCallbacks: { [command: string]: RequestCallback },\n  initialOptions: types.BuildOptions,\n  plugins: types.Plugin[],\n  details: ObjectStash,\n): Promise<\n  | { ok: true, requestPlugins: protocol.BuildPlugin[], runOnEndCallbacks: RunOnEndCallbacks, scheduleOnDisposeCallbacks: () => void }\n  | { ok: false, error: any, pluginName: string }\n> => {\n  let onStartCallbacks: {\n    name: string,\n    note: () => types.Note | undefined,\n    callback: () =>\n      (types.OnStartResult | null | void | Promise<types.OnStartResult | null | void>),\n  }[] = []\n\n  let onEndCallbacks: {\n    name: string,\n    note: () => types.Note | undefined,\n    callback: (result: types.BuildResult) =>\n      (types.OnEndResult | null | void | Promise<types.OnEndResult | null | void>),\n  }[] = []\n\n  let onResolveCallbacks: {\n    [id: number]: {\n      name: string,\n      note: () => types.Note | undefined,\n      callback: (args: types.OnResolveArgs) =>\n        (types.OnResolveResult | null | undefined | Promise<types.OnResolveResult | null | undefined>),\n    },\n  } = {}\n\n  let onLoadCallbacks: {\n    [id: number]: {\n      name: string,\n      note: () => types.Note | undefined,\n      callback: (args: types.OnLoadArgs) =>\n        (types.OnLoadResult | null | undefined | Promise<types.OnLoadResult | null | undefined>),\n    },\n  } = {}\n\n  let onDisposeCallbacks: (() => void)[] = []\n  let nextCallbackID = 0\n  let i = 0\n  let requestPlugins: protocol.BuildPlugin[] = []\n  let isSetupDone = false\n\n  // Clone the plugin array to guard against mutation during iteration\n  plugins = [...plugins]\n\n  for (let item of plugins) {\n    let keys: OptionKeys = {}\n    if (typeof item !== 'object') throw new Error(`Plugin at index ${i} must be an object`)\n    const name = getFlag(item, keys, 'name', mustBeString)\n    if (typeof name !== 'string' || name === '') throw new Error(`Plugin at index ${i} is missing a name`)\n    try {\n      let setup = getFlag(item, keys, 'setup', mustBeFunction)\n      if (typeof setup !== 'function') throw new Error(`Plugin is missing a setup function`)\n      checkForInvalidFlags(item, keys, `on plugin ${quote(name)}`)\n\n      let plugin: protocol.BuildPlugin = {\n        name,\n        onStart: false,\n        onEnd: false,\n        onResolve: [],\n        onLoad: [],\n      }\n      i++\n\n      let resolve = (path: string, options: types.ResolveOptions = {}): Promise<types.ResolveResult> => {\n        if (!isSetupDone) throw new Error('Cannot call \"resolve\" before plugin setup has completed')\n        if (typeof path !== 'string') throw new Error(`The path to resolve must be a string`)\n        let keys: OptionKeys = Object.create(null)\n        let pluginName = getFlag(options, keys, 'pluginName', mustBeString)\n        let importer = getFlag(options, keys, 'importer', mustBeString)\n        let namespace = getFlag(options, keys, 'namespace', mustBeString)\n        let resolveDir = getFlag(options, keys, 'resolveDir', mustBeString)\n        let kind = getFlag(options, keys, 'kind', mustBeString)\n        let pluginData = getFlag(options, keys, 'pluginData', canBeAnything)\n        let importAttributes = getFlag(options, keys, 'with', mustBeObject)\n        checkForInvalidFlags(options, keys, 'in resolve() call')\n\n        return new Promise((resolve, reject) => {\n          const request: protocol.ResolveRequest = {\n            command: 'resolve',\n            path,\n            key: buildKey,\n            pluginName: name,\n          }\n          if (pluginName != null) request.pluginName = pluginName\n          if (importer != null) request.importer = importer\n          if (namespace != null) request.namespace = namespace\n          if (resolveDir != null) request.resolveDir = resolveDir\n          if (kind != null) request.kind = kind\n          else throw new Error(`Must specify \"kind\" when calling \"resolve\"`)\n          if (pluginData != null) request.pluginData = details.store(pluginData)\n          if (importAttributes != null) request.with = sanitizeStringMap(importAttributes, 'with')\n\n          sendRequest<protocol.ResolveRequest, protocol.ResolveResponse>(refs, request, (error, response) => {\n            if (error !== null) reject(new Error(error))\n            else resolve({\n              errors: replaceDetailsInMessages(response!.errors, details),\n              warnings: replaceDetailsInMessages(response!.warnings, details),\n              path: response!.path,\n              external: response!.external,\n              sideEffects: response!.sideEffects,\n              namespace: response!.namespace,\n              suffix: response!.suffix,\n              pluginData: details.load(response!.pluginData),\n            })\n          })\n        })\n      }\n\n      let promise = setup({\n        initialOptions,\n\n        resolve,\n\n        onStart(callback) {\n          let registeredText = `This error came from the \"onStart\" callback registered here:`\n          let registeredNote = extractCallerV8(new Error(registeredText), streamIn, 'onStart')\n          onStartCallbacks.push({ name: name!, callback, note: registeredNote })\n          plugin.onStart = true\n        },\n\n        onEnd(callback) {\n          let registeredText = `This error came from the \"onEnd\" callback registered here:`\n          let registeredNote = extractCallerV8(new Error(registeredText), streamIn, 'onEnd')\n          onEndCallbacks.push({ name: name!, callback, note: registeredNote })\n          plugin.onEnd = true\n        },\n\n        onResolve(options, callback) {\n          let registeredText = `This error came from the \"onResolve\" callback registered here:`\n          let registeredNote = extractCallerV8(new Error(registeredText), streamIn, 'onResolve')\n          let keys: OptionKeys = {}\n          let filter = getFlag(options, keys, 'filter', mustBeRegExp)\n          let namespace = getFlag(options, keys, 'namespace', mustBeString)\n          checkForInvalidFlags(options, keys, `in onResolve() call for plugin ${quote(name)}`)\n          if (filter == null) throw new Error(`onResolve() call is missing a filter`)\n          let id = nextCallbackID++\n          onResolveCallbacks[id] = { name: name!, callback, note: registeredNote }\n          plugin.onResolve.push({ id, filter: jsRegExpToGoRegExp(filter), namespace: namespace || '' })\n        },\n\n        onLoad(options, callback) {\n          let registeredText = `This error came from the \"onLoad\" callback registered here:`\n          let registeredNote = extractCallerV8(new Error(registeredText), streamIn, 'onLoad')\n          let keys: OptionKeys = {}\n          let filter = getFlag(options, keys, 'filter', mustBeRegExp)\n          let namespace = getFlag(options, keys, 'namespace', mustBeString)\n          checkForInvalidFlags(options, keys, `in onLoad() call for plugin ${quote(name)}`)\n          if (filter == null) throw new Error(`onLoad() call is missing a filter`)\n          let id = nextCallbackID++\n          onLoadCallbacks[id] = { name: name!, callback, note: registeredNote }\n          plugin.onLoad.push({ id, filter: jsRegExpToGoRegExp(filter), namespace: namespace || '' })\n        },\n\n        onDispose(callback) {\n          onDisposeCallbacks.push(callback)\n        },\n\n        esbuild: streamIn.esbuild,\n      })\n\n      // Await a returned promise if there was one. This allows plugins to do\n      // some asynchronous setup while still retaining the ability to modify\n      // the build options. This deliberately serializes asynchronous plugin\n      // setup instead of running them concurrently so that build option\n      // modifications are easier to reason about.\n      if (promise) await promise\n\n      requestPlugins.push(plugin)\n    } catch (e) {\n      return { ok: false, error: e, pluginName: name }\n    }\n  }\n\n  requestCallbacks['on-start'] = async (id, request: protocol.OnStartRequest) => {\n    // Reset the \"pluginData\" map before each new build to avoid a memory leak.\n    // This is done before each new build begins instead of after each build ends\n    // because I believe the current API doesn't restrict when you can call\n    // \"resolve\" and there may be some uses of it that call it around when the\n    // build ends, and we don't want to accidentally break those use cases.\n    details.clear()\n\n    let response: protocol.OnStartResponse = { errors: [], warnings: [] }\n    await Promise.all(onStartCallbacks.map(async ({ name, callback, note }) => {\n      try {\n        let result = await callback()\n\n        if (result != null) {\n          if (typeof result !== 'object') throw new Error(`Expected onStart() callback in plugin ${quote(name)} to return an object`)\n          let keys: OptionKeys = {}\n          let errors = getFlag(result, keys, 'errors', mustBeArray)\n          let warnings = getFlag(result, keys, 'warnings', mustBeArray)\n          checkForInvalidFlags(result, keys, `from onStart() callback in plugin ${quote(name)}`)\n\n          if (errors != null) response.errors!.push(...sanitizeMessages(errors, 'errors', details, name, undefined))\n          if (warnings != null) response.warnings!.push(...sanitizeMessages(warnings, 'warnings', details, name, undefined))\n        }\n      } catch (e) {\n        response.errors!.push(extractErrorMessageV8(e, streamIn, details, note && note(), name))\n      }\n    }))\n    sendResponse(id, response as any)\n  }\n\n  requestCallbacks['on-resolve'] = async (id, request: protocol.OnResolveRequest) => {\n    let response: protocol.OnResolveResponse = {}, name = '', callback, note\n    for (let id of request.ids) {\n      try {\n        ({ name, callback, note } = onResolveCallbacks[id])\n        let result = await callback({\n          path: request.path,\n          importer: request.importer,\n          namespace: request.namespace,\n          resolveDir: request.resolveDir,\n          kind: request.kind,\n          pluginData: details.load(request.pluginData),\n          with: request.with,\n        })\n\n        if (result != null) {\n          if (typeof result !== 'object') throw new Error(`Expected onResolve() callback in plugin ${quote(name)} to return an object`)\n          let keys: OptionKeys = {}\n          let pluginName = getFlag(result, keys, 'pluginName', mustBeString)\n          let path = getFlag(result, keys, 'path', mustBeString)\n          let namespace = getFlag(result, keys, 'namespace', mustBeString)\n          let suffix = getFlag(result, keys, 'suffix', mustBeString)\n          let external = getFlag(result, keys, 'external', mustBeBoolean)\n          let sideEffects = getFlag(result, keys, 'sideEffects', mustBeBoolean)\n          let pluginData = getFlag(result, keys, 'pluginData', canBeAnything)\n          let errors = getFlag(result, keys, 'errors', mustBeArray)\n          let warnings = getFlag(result, keys, 'warnings', mustBeArray)\n          let watchFiles = getFlag(result, keys, 'watchFiles', mustBeArrayOfStrings)\n          let watchDirs = getFlag(result, keys, 'watchDirs', mustBeArrayOfStrings)\n          checkForInvalidFlags(result, keys, `from onResolve() callback in plugin ${quote(name)}`)\n\n          response.id = id\n          if (pluginName != null) response.pluginName = pluginName\n          if (path != null) response.path = path\n          if (namespace != null) response.namespace = namespace\n          if (suffix != null) response.suffix = suffix\n          if (external != null) response.external = external\n          if (sideEffects != null) response.sideEffects = sideEffects\n          if (pluginData != null) response.pluginData = details.store(pluginData)\n          if (errors != null) response.errors = sanitizeMessages(errors, 'errors', details, name, undefined)\n          if (warnings != null) response.warnings = sanitizeMessages(warnings, 'warnings', details, name, undefined)\n          if (watchFiles != null) response.watchFiles = sanitizeStringArray(watchFiles, 'watchFiles')\n          if (watchDirs != null) response.watchDirs = sanitizeStringArray(watchDirs, 'watchDirs')\n          break\n        }\n      } catch (e) {\n        response = { id, errors: [extractErrorMessageV8(e, streamIn, details, note && note(), name)] }\n        break\n      }\n    }\n    sendResponse(id, response as any)\n  }\n\n  requestCallbacks['on-load'] = async (id, request: protocol.OnLoadRequest) => {\n    let response: protocol.OnLoadResponse = {}, name = '', callback, note\n    for (let id of request.ids) {\n      try {\n        ({ name, callback, note } = onLoadCallbacks[id])\n        let result = await callback({\n          path: request.path,\n          namespace: request.namespace,\n          suffix: request.suffix,\n          pluginData: details.load(request.pluginData),\n          with: request.with,\n        })\n\n        if (result != null) {\n          if (typeof result !== 'object') throw new Error(`Expected onLoad() callback in plugin ${quote(name)} to return an object`)\n          let keys: OptionKeys = {}\n          let pluginName = getFlag(result, keys, 'pluginName', mustBeString)\n          let contents = getFlag(result, keys, 'contents', mustBeStringOrUint8Array)\n          let resolveDir = getFlag(result, keys, 'resolveDir', mustBeString)\n          let pluginData = getFlag(result, keys, 'pluginData', canBeAnything)\n          let loader = getFlag(result, keys, 'loader', mustBeString)\n          let errors = getFlag(result, keys, 'errors', mustBeArray)\n          let warnings = getFlag(result, keys, 'warnings', mustBeArray)\n          let watchFiles = getFlag(result, keys, 'watchFiles', mustBeArrayOfStrings)\n          let watchDirs = getFlag(result, keys, 'watchDirs', mustBeArrayOfStrings)\n          checkForInvalidFlags(result, keys, `from onLoad() callback in plugin ${quote(name)}`)\n\n          response.id = id\n          if (pluginName != null) response.pluginName = pluginName\n          if (contents instanceof Uint8Array) response.contents = contents\n          else if (contents != null) response.contents = protocol.encodeUTF8(contents)\n          if (resolveDir != null) response.resolveDir = resolveDir\n          if (pluginData != null) response.pluginData = details.store(pluginData)\n          if (loader != null) response.loader = loader\n          if (errors != null) response.errors = sanitizeMessages(errors, 'errors', details, name, undefined)\n          if (warnings != null) response.warnings = sanitizeMessages(warnings, 'warnings', details, name, undefined)\n          if (watchFiles != null) response.watchFiles = sanitizeStringArray(watchFiles, 'watchFiles')\n          if (watchDirs != null) response.watchDirs = sanitizeStringArray(watchDirs, 'watchDirs')\n          break\n        }\n      } catch (e) {\n        response = { id, errors: [extractErrorMessageV8(e, streamIn, details, note && note(), name)] }\n        break\n      }\n    }\n    sendResponse(id, response as any)\n  }\n\n  let runOnEndCallbacks: RunOnEndCallbacks = (result, done) => done([], [])\n\n  if (onEndCallbacks.length > 0) {\n    runOnEndCallbacks = (result, done) => {\n      (async () => {\n        const onEndErrors: types.Message[] = []\n        const onEndWarnings: types.Message[] = []\n\n        for (const { name, callback, note } of onEndCallbacks) {\n          let newErrors: types.Message[] | undefined\n          let newWarnings: types.Message[] | undefined\n\n          try {\n            const value = await callback(result)\n\n            if (value != null) {\n              if (typeof value !== 'object') throw new Error(`Expected onEnd() callback in plugin ${quote(name)} to return an object`)\n              let keys: OptionKeys = {}\n              let errors = getFlag(value, keys, 'errors', mustBeArray)\n              let warnings = getFlag(value, keys, 'warnings', mustBeArray)\n              checkForInvalidFlags(value, keys, `from onEnd() callback in plugin ${quote(name)}`)\n\n              if (errors != null) newErrors = sanitizeMessages(errors, 'errors', details, name, undefined)\n              if (warnings != null) newWarnings = sanitizeMessages(warnings, 'warnings', details, name, undefined)\n            }\n          } catch (e) {\n            newErrors = [extractErrorMessageV8(e, streamIn, details, note && note(), name)]\n          }\n\n          // Try adding the errors and warnings to the result object, but\n          // continue if something goes wrong. If error-reporting has errors\n          // then nothing can help us...\n          if (newErrors) {\n            onEndErrors.push(...newErrors)\n            try {\n              result.errors.push(...newErrors)\n            } catch {\n            }\n          }\n          if (newWarnings) {\n            onEndWarnings.push(...newWarnings)\n            try {\n              result.warnings.push(...newWarnings)\n            } catch {\n            }\n          }\n        }\n\n        done(onEndErrors, onEndWarnings)\n      })()\n    }\n  }\n\n  let scheduleOnDisposeCallbacks = (): void => {\n    // Run each \"onDispose\" callback with its own call stack\n    for (const cb of onDisposeCallbacks) {\n      setTimeout(() => cb(), 0)\n    }\n  }\n\n  isSetupDone = true\n  return {\n    ok: true,\n    requestPlugins,\n    runOnEndCallbacks,\n    scheduleOnDisposeCallbacks,\n  }\n}\n\n// This stores JavaScript objects on the JavaScript side and temporarily\n// substitutes them with an integer that can be passed through the Go side\n// and back. That way we can associate JavaScript objects with Go objects\n// even if the JavaScript objects aren't serializable. And we also avoid\n// the overhead of serializing large JavaScript objects.\ninterface ObjectStash {\n  clear(): void\n  load(id: number): any\n  store(value: any): number\n}\n\nfunction createObjectStash(): ObjectStash {\n  const map = new Map<number, any>()\n  let nextID = 0\n  return {\n    clear() {\n      map.clear()\n    },\n    load(id) {\n      return map.get(id)\n    },\n    store(value) {\n      if (value === void 0) return -1\n      const id = nextID++\n      map.set(id, value)\n      return id\n    },\n  }\n}\n\nfunction extractCallerV8(e: Error, streamIn: StreamIn, ident: string): () => types.Note | undefined {\n  let note: types.Note | undefined\n  let tried = false\n  return () => {\n    if (tried) return note\n    tried = true\n    try {\n      let lines = (e.stack + '').split('\\n')\n      lines.splice(1, 1)\n      let location = parseStackLinesV8(streamIn, lines, ident)\n      if (location) {\n        note = { text: e.message, location }\n        return note\n      }\n    } catch {\n    }\n  }\n}\n\nfunction extractErrorMessageV8(e: any, streamIn: StreamIn, stash: ObjectStash | null, note: types.Note | undefined, pluginName: string): types.Message {\n  let text = 'Internal error'\n  let location: types.Location | null = null\n\n  try {\n    text = ((e && e.message) || e) + ''\n  } catch {\n  }\n\n  // Optionally attempt to extract the file from the stack trace, works in V8/node\n  try {\n    location = parseStackLinesV8(streamIn, (e.stack + '').split('\\n'), '')\n  } catch {\n  }\n\n  return { id: '', pluginName, text, location, notes: note ? [note] : [], detail: stash ? stash.store(e) : -1 }\n}\n\nfunction parseStackLinesV8(streamIn: StreamIn, lines: string[], ident: string): types.Location | null {\n  let at = '    at '\n\n  // Check to see if this looks like a V8 stack trace\n  if (streamIn.readFileSync && !lines[0].startsWith(at) && lines[1].startsWith(at)) {\n    for (let i = 1; i < lines.length; i++) {\n      let line = lines[i]\n      if (!line.startsWith(at)) continue\n      line = line.slice(at.length)\n      while (true) {\n        // Unwrap a function name\n        let match = /^(?:new |async )?\\S+ \\((.*)\\)$/.exec(line)\n        if (match) {\n          line = match[1]\n          continue\n        }\n\n        // Unwrap an eval wrapper\n        match = /^eval at \\S+ \\((.*)\\)(?:, \\S+:\\d+:\\d+)?$/.exec(line)\n        if (match) {\n          line = match[1]\n          continue\n        }\n\n        // Match on the file location\n        match = /^(\\S+):(\\d+):(\\d+)$/.exec(line)\n        if (match) {\n          let contents\n          try {\n            contents = streamIn.readFileSync(match[1], 'utf8')\n          } catch {\n            break\n          }\n          let lineText = contents.split(/\\r\\n|\\r|\\n|\\u2028|\\u2029/)[+match[2] - 1] || ''\n          let column = +match[3] - 1\n          let length = lineText.slice(column, column + ident.length) === ident ? ident.length : 0\n          return {\n            file: match[1],\n            namespace: 'file',\n            line: +match[2],\n            column: protocol.encodeUTF8(lineText.slice(0, column)).length,\n            length: protocol.encodeUTF8(lineText.slice(column, column + length)).length,\n            lineText: lineText + '\\n' + lines.slice(1).join('\\n'),\n            suggestion: '',\n          }\n        }\n        break\n      }\n    }\n  }\n\n  return null\n}\n\nfunction failureErrorWithLog(text: string, errors: types.Message[], warnings: types.Message[]): types.BuildFailure {\n  let limit = 5\n  text += errors.length < 1 ? '' : ` with ${errors.length} error${errors.length < 2 ? '' : 's'}:` +\n    errors.slice(0, limit + 1).map((e, i) => {\n      if (i === limit) return '\\n...'\n      if (!e.location) return `\\nerror: ${e.text}`\n      let { file, line, column } = e.location\n      let pluginText = e.pluginName ? `[plugin: ${e.pluginName}] ` : ''\n      return `\\n${file}:${line}:${column}: ERROR: ${pluginText}${e.text}`\n    }).join('')\n  let error: any = new Error(text)\n\n  // Use a getter instead of a plain property so that when the error is thrown\n  // without being caught and the node process exits, the error objects aren't\n  // printed. The error objects are pretty big and not helpful because a) esbuild\n  // already prints errors to stderr by default and b) the error summary already\n  // has a more helpful abbreviated form of the error messages.\n  for (const [key, value] of [['errors', errors], ['warnings', warnings]] as const) {\n    Object.defineProperty(error, key, {\n      configurable: true,\n      enumerable: true,\n      get: () => value,\n      set: value => Object.defineProperty(error, key, {\n        configurable: true,\n        enumerable: true,\n        value,\n      }),\n    })\n  }\n\n  return error\n}\n\nfunction replaceDetailsInMessages(messages: types.Message[], stash: ObjectStash): types.Message[] {\n  for (const message of messages) {\n    message.detail = stash.load(message.detail)\n  }\n  return messages\n}\n\nfunction sanitizeLocation(location: types.PartialMessage['location'], where: string, terminalWidth: number | undefined): types.Message['location'] {\n  if (location == null) return null\n\n  let keys: OptionKeys = {}\n  let file = getFlag(location, keys, 'file', mustBeString)\n  let namespace = getFlag(location, keys, 'namespace', mustBeString)\n  let line = getFlag(location, keys, 'line', mustBeInteger)\n  let column = getFlag(location, keys, 'column', mustBeInteger)\n  let length = getFlag(location, keys, 'length', mustBeInteger)\n  let lineText = getFlag(location, keys, 'lineText', mustBeString)\n  let suggestion = getFlag(location, keys, 'suggestion', mustBeString)\n  checkForInvalidFlags(location, keys, where)\n\n  // Performance hack: Some people pass enormous minified files as the line\n  // text with a column near the beginning of the line and then complain\n  // when this function is slow. The slowness comes from serializing a huge\n  // string. But the vast majority of that string is unnecessary. Try to\n  // detect when this is the case and trim the string before serialization\n  // to avoid the performance hit. See: https://github.com/evanw/esbuild/issues/3467\n  if (lineText) {\n    // Try to conservatively guess the maximum amount of relevant text\n    const relevantASCII = lineText.slice(0,\n      (column && column > 0 ? column : 0) +\n      (length && length > 0 ? length : 0) +\n      (terminalWidth && terminalWidth > 0 ? terminalWidth : 80))\n\n    // Make sure it's ASCII (so the byte-oriented column and length values\n    // are correct) and that there are no newlines (so that our logging code\n    // doesn't look at the end of the string)\n    if (!/[\\x7F-\\uFFFF]/.test(relevantASCII) && !/\\n/.test(lineText)) {\n      lineText = relevantASCII\n    }\n  }\n\n  // Note: We could technically make this even faster by maintaining two copies\n  // of this code, one in Go and one in TypeScript. But I'm not going to do that.\n  // The point of this function is to call into the real Go code to get what it\n  // does. If someone wants a JS version, they can port it themselves.\n\n  return {\n    file: file || '',\n    namespace: namespace || '',\n    line: line || 0,\n    column: column || 0,\n    length: length || 0,\n    lineText: lineText || '',\n    suggestion: suggestion || '',\n  }\n}\n\nfunction sanitizeMessages(\n  messages: types.PartialMessage[],\n  property: string,\n  stash: ObjectStash | null,\n  fallbackPluginName: string,\n  terminalWidth: number | undefined,\n): types.Message[] {\n  let messagesClone: types.Message[] = []\n  let index = 0\n\n  for (const message of messages) {\n    let keys: OptionKeys = {}\n    let id = getFlag(message, keys, 'id', mustBeString)\n    let pluginName = getFlag(message, keys, 'pluginName', mustBeString)\n    let text = getFlag(message, keys, 'text', mustBeString)\n    let location = getFlag(message, keys, 'location', mustBeObjectOrNull)\n    let notes = getFlag(message, keys, 'notes', mustBeArray)\n    let detail = getFlag(message, keys, 'detail', canBeAnything)\n    let where = `in element ${index} of \"${property}\"`\n    checkForInvalidFlags(message, keys, where)\n\n    let notesClone: types.Note[] = []\n    if (notes) {\n      for (const note of notes) {\n        let noteKeys: OptionKeys = {}\n        let noteText = getFlag(note, noteKeys, 'text', mustBeString)\n        let noteLocation = getFlag(note, noteKeys, 'location', mustBeObjectOrNull)\n        checkForInvalidFlags(note, noteKeys, where)\n        notesClone.push({\n          text: noteText || '',\n          location: sanitizeLocation(noteLocation, where, terminalWidth),\n        })\n      }\n    }\n\n    messagesClone.push({\n      id: id || '',\n      pluginName: pluginName || fallbackPluginName,\n      text: text || '',\n      location: sanitizeLocation(location, where, terminalWidth),\n      notes: notesClone,\n      detail: stash ? stash.store(detail) : -1,\n    })\n    index++\n  }\n\n  return messagesClone\n}\n\nfunction sanitizeStringArray(values: any[], property: string): string[] {\n  const result: string[] = []\n  for (const value of values) {\n    if (typeof value !== 'string') throw new Error(`${quote(property)} must be an array of strings`)\n    result.push(value)\n  }\n  return result\n}\n\nfunction sanitizeStringMap(map: Record<string, any>, property: string): Record<string, string> {\n  const result: Record<string, string> = Object.create(null)\n  for (const key in map) {\n    const value = map[key]\n    if (typeof value !== 'string') throw new Error(`key ${quote(key)} in object ${quote(property)} must be a string`)\n    result[key] = value\n  }\n  return result\n}\n\nfunction convertOutputFiles({ path, contents, hash }: protocol.BuildOutputFile): types.OutputFile {\n  // The text is lazily-generated for performance reasons. If no one asks for\n  // it, then it never needs to be generated.\n  let text: string | null = null\n  return {\n    path,\n    contents,\n    hash,\n    get text() {\n      // People want to be able to set \"contents\" and have esbuild automatically\n      // derive \"text\" for them, so grab the contents off of this object instead\n      // of using our original value.\n      const binary = this.contents\n\n      // This deliberately doesn't do bidirectional derivation because that could\n      // result in the inefficiency. For example, if we did do this and then you\n      // set \"contents\" and \"text\" and then asked for \"contents\", the second\n      // setter for \"text\" will have erased our cached \"contents\" value so we'd\n      // need to regenerate it again. Instead, \"contents\" is unambiguously the\n      // primary value and \"text\" is unambiguously the derived value.\n      if (text === null || binary !== contents) {\n        contents = binary\n        text = protocol.decodeUTF8(binary)\n      }\n      return text\n    },\n  }\n}\n\nfunction jsRegExpToGoRegExp(regexp: RegExp): string {\n  let result = regexp.source\n  if (regexp.flags) result = `(?${regexp.flags})${result}`\n  return result\n}\n\nfunction parseJSON(bytes: Uint8Array): any {\n  let text: string\n  try {\n    // This may fail in V8 with the error \"Cannot create a string longer than\n    // 0x1fffffe8 characters\". Other JS engines may have similar limitations.\n    text = protocol.decodeUTF8(bytes)\n  } catch {\n    // In that case, we attempt to parse the JSON ourselves directly from the\n    // Uint8Array. This bypasses the string length limit as we no longer need\n    // to construct a string that's the length of the input. However, doing\n    // this is likely significantly slower (perhaps around ~4x slower?), so we\n    // only do it if we have to.\n    return JSON_parse(bytes)\n  }\n  return JSON.parse(text)\n}\n"
  },
  {
    "path": "lib/shared/stdio_protocol.ts",
    "content": "// The JavaScript API communicates with the Go child process over stdin/stdout\n// using this protocol. It's a very simple binary protocol that uses primitives\n// and nested arrays and maps. It's basically JSON with UTF-8 encoding and an\n// additional byte array primitive. You must send a response after receiving a\n// request because the other end is blocking on the response coming back.\n\nimport type * as types from \"./types\"\n\nexport interface BuildRequest {\n  command: 'build'\n  key: number\n  entries: [string, string][]; // Use an array instead of a map to preserve order\n  flags: string[]\n  write: boolean\n  stdinContents: Uint8Array | null\n  stdinResolveDir: string | null\n  absWorkingDir: string\n  nodePaths: string[]\n  context: boolean\n  plugins?: BuildPlugin[]\n  mangleCache?: Record<string, string | false>\n}\n\nexport interface ServeRequest {\n  command: 'serve'\n  key: number\n  onRequest: boolean\n  port?: number\n  host?: string\n  servedir?: string\n  keyfile?: string\n  certfile?: string\n  fallback?: string\n  corsOrigin?: string[]\n}\n\nexport interface ServeResponse {\n  port: number\n  hosts: string[]\n}\n\nexport interface BuildPlugin {\n  name: string\n  onStart: boolean\n  onEnd: boolean\n  onResolve: { id: number, filter: string, namespace: string }[]\n  onLoad: { id: number, filter: string, namespace: string }[]\n}\n\nexport interface BuildResponse {\n  errors: types.Message[]\n  warnings: types.Message[]\n  outputFiles?: BuildOutputFile[]\n  metafile?: Uint8Array\n  mangleCache?: Record<string, string | false>\n  writeToStdout?: Uint8Array\n}\n\nexport interface OnEndRequest extends BuildResponse {\n  command: 'on-end'\n}\n\nexport interface OnEndResponse {\n  errors: types.Message[]\n  warnings: types.Message[]\n}\n\nexport interface BuildOutputFile {\n  path: string\n  contents: Uint8Array\n  hash: string\n}\n\nexport interface PingRequest {\n  command: 'ping'\n}\n\nexport interface RebuildRequest {\n  command: 'rebuild'\n  key: number\n}\n\nexport interface RebuildResponse {\n  errors: types.Message[]\n  warnings: types.Message[]\n}\n\nexport interface DisposeRequest {\n  command: 'dispose'\n  key: number\n}\n\nexport interface CancelRequest {\n  command: 'cancel'\n  key: number\n}\n\nexport interface WatchRequest {\n  command: 'watch'\n  key: number\n  delay?: number\n}\n\nexport interface OnServeRequest {\n  command: 'serve-request'\n  key: number\n  args: types.ServeOnRequestArgs\n}\n\nexport interface TransformRequest {\n  command: 'transform'\n  flags: string[]\n  input: Uint8Array\n  inputFS: boolean\n  mangleCache?: Record<string, string | false>\n}\n\nexport interface TransformResponse {\n  errors: types.Message[]\n  warnings: types.Message[]\n\n  code: string\n  codeFS: boolean\n\n  map: string\n  mapFS: boolean\n\n  legalComments?: string\n  mangleCache?: Record<string, string | false>\n}\n\nexport interface FormatMsgsRequest {\n  command: 'format-msgs'\n  messages: types.Message[]\n  isWarning: boolean\n  color?: boolean\n  terminalWidth?: number\n}\n\nexport interface FormatMsgsResponse {\n  messages: string[]\n}\n\nexport interface AnalyzeMetafileRequest {\n  command: 'analyze-metafile'\n  metafile: string\n  color?: boolean\n  verbose?: boolean\n}\n\nexport interface AnalyzeMetafileResponse {\n  result: string\n}\n\nexport interface OnStartRequest {\n  command: 'on-start'\n  key: number\n}\n\nexport interface OnStartResponse {\n  errors?: types.PartialMessage[]\n  warnings?: types.PartialMessage[]\n}\n\nexport interface ResolveRequest {\n  command: 'resolve'\n  key: number\n  path: string\n  pluginName: string\n  importer?: string\n  namespace?: string\n  resolveDir?: string\n  kind?: string\n  pluginData?: number\n  with?: Record<string, string>\n}\n\nexport interface ResolveResponse {\n  errors: types.Message[]\n  warnings: types.Message[]\n\n  path: string\n  external: boolean\n  sideEffects: boolean\n  namespace: string\n  suffix: string\n  pluginData: number\n}\n\nexport interface OnResolveRequest {\n  command: 'on-resolve'\n  key: number\n  ids: number[]\n  path: string\n  importer: string\n  namespace: string\n  resolveDir: string\n  kind: types.ImportKind\n  pluginData: number\n  with: Record<string, string>\n}\n\nexport interface OnResolveResponse {\n  id?: number\n  pluginName?: string\n\n  errors?: types.PartialMessage[]\n  warnings?: types.PartialMessage[]\n\n  path?: string\n  external?: boolean\n  sideEffects?: boolean\n  namespace?: string\n  suffix?: string\n  pluginData?: number\n\n  watchFiles?: string[]\n  watchDirs?: string[]\n}\n\nexport interface OnLoadRequest {\n  command: 'on-load'\n  key: number\n  ids: number[]\n  path: string\n  namespace: string\n  suffix: string\n  pluginData: number\n  with: Record<string, string>\n}\n\nexport interface OnLoadResponse {\n  id?: number\n  pluginName?: string\n\n  errors?: types.PartialMessage[]\n  warnings?: types.PartialMessage[]\n\n  contents?: Uint8Array\n  resolveDir?: string\n  loader?: string\n  pluginData?: number\n\n  watchFiles?: string[]\n  watchDirs?: string[]\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nexport interface Packet {\n  id: number\n  isRequest: boolean\n  value: Value\n}\n\nexport type Value =\n  | null\n  | boolean\n  | number\n  | string\n  | Uint8Array\n  | Value[]\n  | { [key: string]: Value }\n\nexport function encodePacket(packet: Packet): Uint8Array {\n  let visit = (value: Value) => {\n    if (value === null) {\n      bb.write8(0)\n    } else if (typeof value === 'boolean') {\n      bb.write8(1)\n      bb.write8(+value)\n    } else if (typeof value === 'number') {\n      bb.write8(2)\n      bb.write32(value | 0)\n    } else if (typeof value === 'string') {\n      bb.write8(3)\n      bb.write(encodeUTF8(value))\n    } else if (value instanceof Uint8Array) {\n      bb.write8(4)\n      bb.write(value)\n    } else if (value instanceof Array) {\n      bb.write8(5)\n      bb.write32(value.length)\n      for (let item of value) {\n        visit(item)\n      }\n    } else {\n      let keys = Object.keys(value)\n      bb.write8(6)\n      bb.write32(keys.length)\n      for (let key of keys) {\n        bb.write(encodeUTF8(key))\n        visit(value[key])\n      }\n    }\n  }\n\n  let bb = new ByteBuffer\n  bb.write32(0); // Reserve space for the length\n  bb.write32((packet.id << 1) | +!packet.isRequest)\n  visit(packet.value)\n  writeUInt32LE(bb.buf, bb.len - 4, 0); // Patch the length in\n  return bb.buf.subarray(0, bb.len)\n}\n\nexport function decodePacket(bytes: Uint8Array): Packet {\n  let visit = (): Value => {\n    switch (bb.read8()) {\n      case 0: // null\n        return null\n      case 1: // boolean\n        return !!bb.read8()\n      case 2: // number\n        return bb.read32()\n      case 3: // string\n        return decodeUTF8(bb.read())\n      case 4: // Uint8Array\n        return bb.read()\n      case 5: { // Value[]\n        let count = bb.read32()\n        let value: Value[] = []\n        for (let i = 0; i < count; i++) {\n          value.push(visit())\n        }\n        return value\n      }\n      case 6: { // { [key: string]: Value }\n        let count = bb.read32()\n        let value: { [key: string]: Value } = {}\n        for (let i = 0; i < count; i++) {\n          value[decodeUTF8(bb.read())] = visit()\n        }\n        return value\n      }\n      default:\n        throw new Error('Invalid packet')\n    }\n  }\n\n  let bb = new ByteBuffer(bytes)\n  let id = bb.read32()\n  let isRequest = (id & 1) === 0\n  id >>>= 1\n  let value = visit()\n  if (bb.ptr !== bytes.length) {\n    throw new Error('Invalid packet')\n  }\n  return { id, isRequest, value }\n}\n\nclass ByteBuffer {\n  len = 0\n  ptr = 0\n\n  constructor(public buf = new Uint8Array(1024)) {\n  }\n\n  private _write(delta: number): number {\n    if (this.len + delta > this.buf.length) {\n      let clone = new Uint8Array((this.len + delta) * 2)\n      clone.set(this.buf)\n      this.buf = clone\n    }\n    this.len += delta\n    return this.len - delta\n  }\n\n  write8(value: number): void {\n    let offset = this._write(1)\n    this.buf[offset] = value\n  }\n\n  write32(value: number): void {\n    let offset = this._write(4)\n    writeUInt32LE(this.buf, value, offset)\n  }\n\n  write(bytes: Uint8Array): void {\n    let offset = this._write(4 + bytes.length)\n    writeUInt32LE(this.buf, bytes.length, offset)\n    this.buf.set(bytes, offset + 4)\n  }\n\n  private _read(delta: number): number {\n    if (this.ptr + delta > this.buf.length) {\n      throw new Error('Invalid packet')\n    }\n    this.ptr += delta\n    return this.ptr - delta\n  }\n\n  read8(): number {\n    return this.buf[this._read(1)]\n  }\n\n  read32(): number {\n    return readUInt32LE(this.buf, this._read(4))\n  }\n\n  read(): Uint8Array {\n    let length = this.read32()\n    let bytes = new Uint8Array(length)\n    let ptr = this._read(bytes.length)\n    bytes.set(this.buf.subarray(ptr, ptr + length))\n    return bytes\n  }\n}\n\nexport let encodeUTF8: (text: string) => Uint8Array\nexport let decodeUTF8: (bytes: Uint8Array) => string\nlet encodeInvariant: string\n\n// For the browser and node 12.x\nif (typeof TextEncoder !== 'undefined' && typeof TextDecoder !== 'undefined') {\n  let encoder = new TextEncoder()\n  let decoder = new TextDecoder()\n  encodeUTF8 = text => encoder.encode(text)\n  decodeUTF8 = bytes => decoder.decode(bytes)\n  encodeInvariant = 'new TextEncoder().encode(\"\")'\n}\n\n// For node 10.x\nelse if (typeof Buffer !== 'undefined') {\n  encodeUTF8 = text => Buffer.from(text)\n  decodeUTF8 = bytes => {\n    let { buffer, byteOffset, byteLength } = bytes\n    return Buffer.from(buffer, byteOffset, byteLength).toString()\n  }\n  encodeInvariant = 'Buffer.from(\"\")'\n}\n\nelse {\n  throw new Error('No UTF-8 codec found')\n}\n\n// Throw an error early if this isn't true. The test framework called \"Jest\"\n// has some bugs regarding this edge case, and letting esbuild proceed further\n// leads to confusing errors that make it seem like esbuild itself has a bug.\nif (!(encodeUTF8('') instanceof Uint8Array))\n  throw new Error(`Invariant violation: \"${encodeInvariant} instanceof Uint8Array\" is incorrectly false\n\nThis indicates that your JavaScript environment is broken. You cannot use\nesbuild in this environment because esbuild relies on this invariant. This\nis not a problem with esbuild. You need to fix your environment instead.\n`)\n\nexport function readUInt32LE(buffer: Uint8Array, offset: number): number {\n  return (\n    buffer[offset++] |\n    (buffer[offset++] << 8) |\n    (buffer[offset++] << 16) |\n    (buffer[offset++] << 24)\n  ) >>> 0\n}\n\nfunction writeUInt32LE(buffer: Uint8Array, value: number, offset: number): void {\n  buffer[offset++] = value\n  buffer[offset++] = value >> 8\n  buffer[offset++] = value >> 16\n  buffer[offset++] = value >> 24\n}\n"
  },
  {
    "path": "lib/shared/types.ts",
    "content": "export type Platform = 'browser' | 'node' | 'neutral'\nexport type Format = 'iife' | 'cjs' | 'esm'\nexport type Loader = 'base64' | 'binary' | 'copy' | 'css' | 'dataurl' | 'default' | 'empty' | 'file' | 'js' | 'json' | 'jsx' | 'local-css' | 'text' | 'ts' | 'tsx'\nexport type LogLevel = 'verbose' | 'debug' | 'info' | 'warning' | 'error' | 'silent'\nexport type Charset = 'ascii' | 'utf8'\nexport type Drop = 'console' | 'debugger'\nexport type AbsPaths = 'code' | 'log' | 'metafile'\n\ninterface CommonOptions {\n  /** Documentation: https://esbuild.github.io/api/#sourcemap */\n  sourcemap?: boolean | 'linked' | 'inline' | 'external' | 'both'\n  /** Documentation: https://esbuild.github.io/api/#legal-comments */\n  legalComments?: 'none' | 'inline' | 'eof' | 'linked' | 'external'\n  /** Documentation: https://esbuild.github.io/api/#source-root */\n  sourceRoot?: string\n  /** Documentation: https://esbuild.github.io/api/#sources-content */\n  sourcesContent?: boolean\n\n  /** Documentation: https://esbuild.github.io/api/#format */\n  format?: Format\n  /** Documentation: https://esbuild.github.io/api/#global-name */\n  globalName?: string\n  /** Documentation: https://esbuild.github.io/api/#target */\n  target?: string | string[]\n  /** Documentation: https://esbuild.github.io/api/#supported */\n  supported?: Record<string, boolean>\n  /** Documentation: https://esbuild.github.io/api/#platform */\n  platform?: Platform\n\n  /** Documentation: https://esbuild.github.io/api/#mangle-props */\n  mangleProps?: RegExp\n  /** Documentation: https://esbuild.github.io/api/#mangle-props */\n  reserveProps?: RegExp\n  /** Documentation: https://esbuild.github.io/api/#mangle-props */\n  mangleQuoted?: boolean\n  /** Documentation: https://esbuild.github.io/api/#mangle-props */\n  mangleCache?: Record<string, string | false>\n  /** Documentation: https://esbuild.github.io/api/#drop */\n  drop?: Drop[]\n  /** Documentation: https://esbuild.github.io/api/#drop-labels */\n  dropLabels?: string[]\n  /** Documentation: https://esbuild.github.io/api/#minify */\n  minify?: boolean\n  /** Documentation: https://esbuild.github.io/api/#minify */\n  minifyWhitespace?: boolean\n  /** Documentation: https://esbuild.github.io/api/#minify */\n  minifyIdentifiers?: boolean\n  /** Documentation: https://esbuild.github.io/api/#minify */\n  minifySyntax?: boolean\n  /** Documentation: https://esbuild.github.io/api/#line-limit */\n  lineLimit?: number\n  /** Documentation: https://esbuild.github.io/api/#charset */\n  charset?: Charset\n  /** Documentation: https://esbuild.github.io/api/#tree-shaking */\n  treeShaking?: boolean\n  /** Documentation: https://esbuild.github.io/api/#ignore-annotations */\n  ignoreAnnotations?: boolean\n\n  /** Documentation: https://esbuild.github.io/api/#jsx */\n  jsx?: 'transform' | 'preserve' | 'automatic'\n  /** Documentation: https://esbuild.github.io/api/#jsx-factory */\n  jsxFactory?: string\n  /** Documentation: https://esbuild.github.io/api/#jsx-fragment */\n  jsxFragment?: string\n  /** Documentation: https://esbuild.github.io/api/#jsx-import-source */\n  jsxImportSource?: string\n  /** Documentation: https://esbuild.github.io/api/#jsx-development */\n  jsxDev?: boolean\n  /** Documentation: https://esbuild.github.io/api/#jsx-side-effects */\n  jsxSideEffects?: boolean\n\n  /** Documentation: https://esbuild.github.io/api/#define */\n  define?: { [key: string]: string }\n  /** Documentation: https://esbuild.github.io/api/#pure */\n  pure?: string[]\n  /** Documentation: https://esbuild.github.io/api/#keep-names */\n  keepNames?: boolean\n\n  /** Documentation: https://esbuild.github.io/api/#abs-paths */\n  absPaths?: AbsPaths[]\n  /** Documentation: https://esbuild.github.io/api/#color */\n  color?: boolean\n  /** Documentation: https://esbuild.github.io/api/#log-level */\n  logLevel?: LogLevel\n  /** Documentation: https://esbuild.github.io/api/#log-limit */\n  logLimit?: number\n  /** Documentation: https://esbuild.github.io/api/#log-override */\n  logOverride?: Record<string, LogLevel>\n\n  /** Documentation: https://esbuild.github.io/api/#tsconfig-raw */\n  tsconfigRaw?: string | TsconfigRaw\n}\n\nexport interface TsconfigRaw {\n  compilerOptions?: {\n    alwaysStrict?: boolean\n    baseUrl?: string\n    experimentalDecorators?: boolean\n    importsNotUsedAsValues?: 'remove' | 'preserve' | 'error'\n    jsx?: 'preserve' | 'react-native' | 'react' | 'react-jsx' | 'react-jsxdev'\n    jsxFactory?: string\n    jsxFragmentFactory?: string\n    jsxImportSource?: string\n    paths?: Record<string, string[]>\n    preserveValueImports?: boolean\n    strict?: boolean\n    target?: string\n    useDefineForClassFields?: boolean\n    verbatimModuleSyntax?: boolean\n  }\n}\n\nexport interface BuildOptions extends CommonOptions {\n  /** Documentation: https://esbuild.github.io/api/#bundle */\n  bundle?: boolean\n  /** Documentation: https://esbuild.github.io/api/#splitting */\n  splitting?: boolean\n  /** Documentation: https://esbuild.github.io/api/#preserve-symlinks */\n  preserveSymlinks?: boolean\n  /** Documentation: https://esbuild.github.io/api/#outfile */\n  outfile?: string\n  /** Documentation: https://esbuild.github.io/api/#metafile */\n  metafile?: boolean\n  /** Documentation: https://esbuild.github.io/api/#outdir */\n  outdir?: string\n  /** Documentation: https://esbuild.github.io/api/#outbase */\n  outbase?: string\n  /** Documentation: https://esbuild.github.io/api/#external */\n  external?: string[]\n  /** Documentation: https://esbuild.github.io/api/#packages */\n  packages?: 'bundle' | 'external'\n  /** Documentation: https://esbuild.github.io/api/#alias */\n  alias?: Record<string, string>\n  /** Documentation: https://esbuild.github.io/api/#loader */\n  loader?: { [ext: string]: Loader }\n  /** Documentation: https://esbuild.github.io/api/#resolve-extensions */\n  resolveExtensions?: string[]\n  /** Documentation: https://esbuild.github.io/api/#main-fields */\n  mainFields?: string[]\n  /** Documentation: https://esbuild.github.io/api/#conditions */\n  conditions?: string[]\n  /** Documentation: https://esbuild.github.io/api/#write */\n  write?: boolean\n  /** Documentation: https://esbuild.github.io/api/#allow-overwrite */\n  allowOverwrite?: boolean\n  /** Documentation: https://esbuild.github.io/api/#tsconfig */\n  tsconfig?: string\n  /** Documentation: https://esbuild.github.io/api/#out-extension */\n  outExtension?: { [ext: string]: string }\n  /** Documentation: https://esbuild.github.io/api/#public-path */\n  publicPath?: string\n  /** Documentation: https://esbuild.github.io/api/#entry-names */\n  entryNames?: string\n  /** Documentation: https://esbuild.github.io/api/#chunk-names */\n  chunkNames?: string\n  /** Documentation: https://esbuild.github.io/api/#asset-names */\n  assetNames?: string\n  /** Documentation: https://esbuild.github.io/api/#inject */\n  inject?: string[]\n  /** Documentation: https://esbuild.github.io/api/#banner */\n  banner?: { [type: string]: string }\n  /** Documentation: https://esbuild.github.io/api/#footer */\n  footer?: { [type: string]: string }\n  /** Documentation: https://esbuild.github.io/api/#entry-points */\n  entryPoints?: (string | { in: string, out: string })[] | Record<string, string>\n  /** Documentation: https://esbuild.github.io/api/#stdin */\n  stdin?: StdinOptions\n  /** Documentation: https://esbuild.github.io/plugins/ */\n  plugins?: Plugin[]\n  /** Documentation: https://esbuild.github.io/api/#working-directory */\n  absWorkingDir?: string\n  /** Documentation: https://esbuild.github.io/api/#node-paths */\n  nodePaths?: string[]; // The \"NODE_PATH\" variable from Node.js\n}\n\nexport interface StdinOptions {\n  contents: string | Uint8Array\n  resolveDir?: string\n  sourcefile?: string\n  loader?: Loader\n}\n\nexport interface Message {\n  id: string\n  pluginName: string\n  text: string\n  location: Location | null\n  notes: Note[]\n\n  /**\n   * Optional user-specified data that is passed through unmodified. You can\n   * use this to stash the original error, for example.\n   */\n  detail: any\n}\n\nexport interface Note {\n  text: string\n  location: Location | null\n}\n\nexport interface Location {\n  file: string\n  namespace: string\n  /** 1-based */\n  line: number\n  /** 0-based, in bytes */\n  column: number\n  /** in bytes */\n  length: number\n  lineText: string\n  suggestion: string\n}\n\nexport interface OutputFile {\n  path: string\n  contents: Uint8Array\n  hash: string\n  /** \"contents\" as text (changes automatically with \"contents\") */\n  readonly text: string\n}\n\nexport interface BuildResult<ProvidedOptions extends BuildOptions = BuildOptions> {\n  errors: Message[]\n  warnings: Message[]\n  /** Only when \"write: false\" */\n  outputFiles: OutputFile[] | (ProvidedOptions['write'] extends false ? never : undefined)\n  /** Only when \"metafile: true\" */\n  metafile: Metafile | (ProvidedOptions['metafile'] extends true ? never : undefined)\n  /** Only when \"mangleCache\" is present */\n  mangleCache: Record<string, string | false> | (ProvidedOptions['mangleCache'] extends Object ? never : undefined)\n}\n\nexport interface BuildFailure extends Error {\n  errors: Message[]\n  warnings: Message[]\n}\n\n/** Documentation: https://esbuild.github.io/api/#serve-arguments */\nexport interface ServeOptions {\n  port?: number\n  host?: string\n  servedir?: string\n  keyfile?: string\n  certfile?: string\n  fallback?: string\n  cors?: CORSOptions\n  onRequest?: (args: ServeOnRequestArgs) => void\n}\n\n/** Documentation: https://esbuild.github.io/api/#cors */\nexport interface CORSOptions {\n  origin?: string | string[]\n}\n\nexport interface ServeOnRequestArgs {\n  remoteAddress: string\n  method: string\n  path: string\n  status: number\n  /** The time to generate the response, not to send it */\n  timeInMS: number\n}\n\n/** Documentation: https://esbuild.github.io/api/#serve-return-values */\nexport interface ServeResult {\n  port: number\n  hosts: string[]\n}\n\nexport interface TransformOptions extends CommonOptions {\n  /** Documentation: https://esbuild.github.io/api/#sourcefile */\n  sourcefile?: string\n  /** Documentation: https://esbuild.github.io/api/#loader */\n  loader?: Loader\n  /** Documentation: https://esbuild.github.io/api/#banner */\n  banner?: string\n  /** Documentation: https://esbuild.github.io/api/#footer */\n  footer?: string\n}\n\nexport interface TransformResult<ProvidedOptions extends TransformOptions = TransformOptions> {\n  code: string\n  map: string\n  warnings: Message[]\n  /** Only when \"mangleCache\" is present */\n  mangleCache: Record<string, string | false> | (ProvidedOptions['mangleCache'] extends Object ? never : undefined)\n  /** Only when \"legalComments\" is \"external\" */\n  legalComments: string | (ProvidedOptions['legalComments'] extends 'external' ? never : undefined)\n}\n\nexport interface TransformFailure extends Error {\n  errors: Message[]\n  warnings: Message[]\n}\n\nexport interface Plugin {\n  name: string\n  setup: (build: PluginBuild) => (void | Promise<void>)\n}\n\nexport interface PluginBuild {\n  /** Documentation: https://esbuild.github.io/plugins/#build-options */\n  initialOptions: BuildOptions\n\n  /** Documentation: https://esbuild.github.io/plugins/#resolve */\n  resolve(path: string, options?: ResolveOptions): Promise<ResolveResult>\n\n  /** Documentation: https://esbuild.github.io/plugins/#on-start */\n  onStart(callback: () =>\n    (OnStartResult | null | void | Promise<OnStartResult | null | void>)): void\n\n  /** Documentation: https://esbuild.github.io/plugins/#on-end */\n  onEnd(callback: (result: BuildResult) =>\n    (OnEndResult | null | void | Promise<OnEndResult | null | void>)): void\n\n  /** Documentation: https://esbuild.github.io/plugins/#on-resolve */\n  onResolve(options: OnResolveOptions, callback: (args: OnResolveArgs) =>\n    (OnResolveResult | null | undefined | Promise<OnResolveResult | null | undefined>)): void\n\n  /** Documentation: https://esbuild.github.io/plugins/#on-load */\n  onLoad(options: OnLoadOptions, callback: (args: OnLoadArgs) =>\n    (OnLoadResult | null | undefined | Promise<OnLoadResult | null | undefined>)): void\n\n  /** Documentation: https://esbuild.github.io/plugins/#on-dispose */\n  onDispose(callback: () => void): void\n\n  // This is a full copy of the esbuild library in case you need it\n  esbuild: {\n    context: typeof context,\n    build: typeof build,\n    buildSync: typeof buildSync,\n    transform: typeof transform,\n    transformSync: typeof transformSync,\n    formatMessages: typeof formatMessages,\n    formatMessagesSync: typeof formatMessagesSync,\n    analyzeMetafile: typeof analyzeMetafile,\n    analyzeMetafileSync: typeof analyzeMetafileSync,\n    initialize: typeof initialize,\n    version: typeof version,\n  }\n}\n\n/** Documentation: https://esbuild.github.io/plugins/#resolve-options */\nexport interface ResolveOptions {\n  pluginName?: string\n  importer?: string\n  namespace?: string\n  resolveDir?: string\n  kind?: ImportKind\n  pluginData?: any\n  with?: Record<string, string>\n}\n\n/** Documentation: https://esbuild.github.io/plugins/#resolve-results */\nexport interface ResolveResult {\n  errors: Message[]\n  warnings: Message[]\n\n  path: string\n  external: boolean\n  sideEffects: boolean\n  namespace: string\n  suffix: string\n  pluginData: any\n}\n\nexport interface OnStartResult {\n  errors?: PartialMessage[]\n  warnings?: PartialMessage[]\n}\n\nexport interface OnEndResult {\n  errors?: PartialMessage[]\n  warnings?: PartialMessage[]\n}\n\n/** Documentation: https://esbuild.github.io/plugins/#on-resolve-options */\nexport interface OnResolveOptions {\n  filter: RegExp\n  namespace?: string\n}\n\n/** Documentation: https://esbuild.github.io/plugins/#on-resolve-arguments */\nexport interface OnResolveArgs {\n  path: string\n  importer: string\n  namespace: string\n  resolveDir: string\n  kind: ImportKind\n  pluginData: any\n  with: Record<string, string>\n}\n\nexport type ImportKind =\n  | 'entry-point'\n\n  // JS\n  | 'import-statement'\n  | 'require-call'\n  | 'dynamic-import'\n  | 'require-resolve'\n\n  // CSS\n  | 'import-rule'\n  | 'composes-from'\n  | 'url-token'\n\n/** Documentation: https://esbuild.github.io/plugins/#on-resolve-results */\nexport interface OnResolveResult {\n  pluginName?: string\n\n  errors?: PartialMessage[]\n  warnings?: PartialMessage[]\n\n  path?: string\n  external?: boolean\n  sideEffects?: boolean\n  namespace?: string\n  suffix?: string\n  pluginData?: any\n\n  watchFiles?: string[]\n  watchDirs?: string[]\n}\n\n/** Documentation: https://esbuild.github.io/plugins/#on-load-options */\nexport interface OnLoadOptions {\n  filter: RegExp\n  namespace?: string\n}\n\n/** Documentation: https://esbuild.github.io/plugins/#on-load-arguments */\nexport interface OnLoadArgs {\n  path: string\n  namespace: string\n  suffix: string\n  pluginData: any\n  with: Record<string, string>\n}\n\n/** Documentation: https://esbuild.github.io/plugins/#on-load-results */\nexport interface OnLoadResult {\n  pluginName?: string\n\n  errors?: PartialMessage[]\n  warnings?: PartialMessage[]\n\n  contents?: string | Uint8Array\n  resolveDir?: string\n  loader?: Loader\n  pluginData?: any\n\n  watchFiles?: string[]\n  watchDirs?: string[]\n}\n\nexport interface PartialMessage {\n  id?: string\n  pluginName?: string\n  text?: string\n  location?: Partial<Location> | null\n  notes?: PartialNote[]\n  detail?: any\n}\n\nexport interface PartialNote {\n  text?: string\n  location?: Partial<Location> | null\n}\n\n/** Documentation: https://esbuild.github.io/api/#metafile */\nexport interface Metafile {\n  inputs: {\n    [path: string]: {\n      bytes: number\n      imports: {\n        path: string\n        kind: ImportKind\n        external?: boolean\n        original?: string\n        with?: Record<string, string>\n      }[]\n      format?: 'cjs' | 'esm'\n      with?: Record<string, string>\n    }\n  }\n  outputs: {\n    [path: string]: {\n      bytes: number\n      inputs: {\n        [path: string]: {\n          bytesInOutput: number\n        }\n      }\n      imports: {\n        path: string\n        kind: ImportKind | 'file-loader'\n        external?: boolean\n      }[]\n      exports: string[]\n      entryPoint?: string\n      cssBundle?: string\n    }\n  }\n}\n\nexport interface FormatMessagesOptions {\n  kind: 'error' | 'warning'\n  color?: boolean\n  terminalWidth?: number\n}\n\nexport interface AnalyzeMetafileOptions {\n  color?: boolean\n  verbose?: boolean\n}\n\n/** Documentation: https://esbuild.github.io/api/#watch-arguments */\nexport interface WatchOptions {\n  delay?: number // In milliseconds\n}\n\nexport interface BuildContext<ProvidedOptions extends BuildOptions = BuildOptions> {\n  /** Documentation: https://esbuild.github.io/api/#rebuild */\n  rebuild(): Promise<BuildResult<ProvidedOptions>>\n\n  /** Documentation: https://esbuild.github.io/api/#watch */\n  watch(options?: WatchOptions): Promise<void>\n\n  /** Documentation: https://esbuild.github.io/api/#serve */\n  serve(options?: ServeOptions): Promise<ServeResult>\n\n  cancel(): Promise<void>\n  dispose(): Promise<void>\n}\n\n// This is a TypeScript type-level function which replaces any keys in \"In\"\n// that aren't in \"Out\" with \"never\". We use this to reject properties with\n// typos in object literals. See: https://stackoverflow.com/questions/49580725\ntype SameShape<Out, In extends Out> = In & { [Key in Exclude<keyof In, keyof Out>]: never }\n\n/**\n * This function invokes the \"esbuild\" command-line tool for you. It returns a\n * promise that either resolves with a \"BuildResult\" object or rejects with a\n * \"BuildFailure\" object.\n *\n * - Works in node: yes\n * - Works in browser: yes\n *\n * Documentation: https://esbuild.github.io/api/#build\n */\nexport declare function build<T extends BuildOptions>(options: SameShape<BuildOptions, T>): Promise<BuildResult<T>>\n\n/**\n * This is the advanced long-running form of \"build\" that supports additional\n * features such as watch mode and a local development server.\n *\n * - Works in node: yes\n * - Works in browser: no\n *\n * Documentation: https://esbuild.github.io/api/#build\n */\nexport declare function context<T extends BuildOptions>(options: SameShape<BuildOptions, T>): Promise<BuildContext<T>>\n\n/**\n * This function transforms a single JavaScript file. It can be used to minify\n * JavaScript, convert TypeScript/JSX to JavaScript, or convert newer JavaScript\n * to older JavaScript. It returns a promise that is either resolved with a\n * \"TransformResult\" object or rejected with a \"TransformFailure\" object.\n *\n * - Works in node: yes\n * - Works in browser: yes\n *\n * Documentation: https://esbuild.github.io/api/#transform\n */\nexport declare function transform<T extends TransformOptions>(input: string | Uint8Array, options?: SameShape<TransformOptions, T>): Promise<TransformResult<T>>\n\n/**\n * Converts log messages to formatted message strings suitable for printing in\n * the terminal. This allows you to reuse the built-in behavior of esbuild's\n * log message formatter. This is a batch-oriented API for efficiency.\n *\n * - Works in node: yes\n * - Works in browser: yes\n */\nexport declare function formatMessages(messages: PartialMessage[], options: FormatMessagesOptions): Promise<string[]>\n\n/**\n * Pretty-prints an analysis of the metafile JSON to a string. This is just for\n * convenience to be able to match esbuild's pretty-printing exactly. If you want\n * to customize it, you can just inspect the data in the metafile yourself.\n *\n * - Works in node: yes\n * - Works in browser: yes\n *\n * Documentation: https://esbuild.github.io/api/#analyze\n */\nexport declare function analyzeMetafile(metafile: Metafile | string, options?: AnalyzeMetafileOptions): Promise<string>\n\n/**\n * A synchronous version of \"build\".\n *\n * - Works in node: yes\n * - Works in browser: no\n *\n * Documentation: https://esbuild.github.io/api/#build\n */\nexport declare function buildSync<T extends BuildOptions>(options: SameShape<BuildOptions, T>): BuildResult<T>\n\n/**\n * A synchronous version of \"transform\".\n *\n * - Works in node: yes\n * - Works in browser: no\n *\n * Documentation: https://esbuild.github.io/api/#transform\n */\nexport declare function transformSync<T extends TransformOptions>(input: string | Uint8Array, options?: SameShape<TransformOptions, T>): TransformResult<T>\n\n/**\n * A synchronous version of \"formatMessages\".\n *\n * - Works in node: yes\n * - Works in browser: no\n */\nexport declare function formatMessagesSync(messages: PartialMessage[], options: FormatMessagesOptions): string[]\n\n/**\n * A synchronous version of \"analyzeMetafile\".\n *\n * - Works in node: yes\n * - Works in browser: no\n *\n * Documentation: https://esbuild.github.io/api/#analyze\n */\nexport declare function analyzeMetafileSync(metafile: Metafile | string, options?: AnalyzeMetafileOptions): string\n\n/**\n * This configures the browser-based version of esbuild. It is necessary to\n * call this first and wait for the returned promise to be resolved before\n * making other API calls when using esbuild in the browser.\n *\n * - Works in node: yes\n * - Works in browser: yes (\"options\" is required)\n *\n * Documentation: https://esbuild.github.io/api/#browser\n */\nexport declare function initialize(options: InitializeOptions): Promise<void>\n\nexport interface InitializeOptions {\n  /**\n   * The URL of the \"esbuild.wasm\" file. This must be provided when running\n   * esbuild in the browser.\n   */\n  wasmURL?: string | URL\n\n  /**\n   * The result of calling \"new WebAssembly.Module(buffer)\" where \"buffer\"\n   * is a typed array or ArrayBuffer containing the binary code of the\n   * \"esbuild.wasm\" file.\n   *\n   * You can use this as an alternative to \"wasmURL\" for environments where it's\n   * not possible to download the WebAssembly module.\n   */\n  wasmModule?: WebAssembly.Module\n\n  /**\n   * By default esbuild runs the WebAssembly-based browser API in a web worker\n   * to avoid blocking the UI thread. This can be disabled by setting \"worker\"\n   * to false.\n   */\n  worker?: boolean\n}\n\nexport let version: string\n\n// Call this function to terminate esbuild's child process. The child process\n// is not terminated and re-created after each API call because it's more\n// efficient to keep it around when there are multiple API calls.\n//\n// In node this happens automatically before the parent node process exits. So\n// you only need to call this if you know you will not make any more esbuild\n// API calls and you want to clean up resources.\n//\n// Unlike node, Deno lacks the necessary APIs to clean up child processes\n// automatically. You must manually call stop() in Deno when you're done\n// using esbuild or Deno will continue running forever.\n//\n// Another reason you might want to call this is if you are using esbuild from\n// within a Deno test. Deno fails tests that create a child process without\n// killing it before the test ends, so you have to call this function (and\n// await the returned promise) in every Deno test that uses esbuild.\nexport declare function stop(): Promise<void>\n\n// Note: These declarations exist to avoid type errors when you omit \"dom\" from\n// \"lib\" in your \"tsconfig.json\" file. TypeScript confusingly declares the\n// global \"WebAssembly\" type in \"lib.dom.d.ts\" even though it has nothing to do\n// with the browser DOM and is present in many non-browser JavaScript runtimes\n// (e.g. node and deno). Declaring it here allows esbuild's API to be used in\n// these scenarios.\n//\n// There's an open issue about getting this problem corrected (although these\n// declarations will need to remain even if this is fixed for backward\n// compatibility with older TypeScript versions):\n//\n//   https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/826\n//\ndeclare global {\n  namespace WebAssembly {\n    interface Module {\n    }\n  }\n  interface URL {\n  }\n}\n"
  },
  {
    "path": "lib/shared/uint8array_json_parser.ts",
    "content": "const enum State {\n  TopLevel,\n  Array,\n  Object,\n}\n\nconst enum Char {\n  // Punctuation\n  Newline = 0x0A,\n  Space = 0x20,\n  Quote = 0x22,\n  Plus = 0x2B,\n  Comma = 0x2C,\n  Minus = 0x2D,\n  Dot = 0x2E,\n  Slash = 0x2F,\n  Colon = 0x3A,\n  OpenBracket = 0x5B,\n  Backslash = 0x5C,\n  CloseBracket = 0x5D,\n  OpenBrace = 0x7B,\n  CloseBrace = 0x7D,\n\n  // Numbers\n  Digit0 = 0x30,\n  Digit1 = 0x31,\n  Digit2 = 0x32,\n  Digit3 = 0x33,\n  Digit4 = 0x34,\n  Digit5 = 0x35,\n  Digit6 = 0x36,\n  Digit7 = 0x37,\n  Digit8 = 0x38,\n  Digit9 = 0x39,\n\n  // Uppercase letters\n  UpperA = 0x41,\n  UpperE = 0x45,\n  UpperF = 0x46,\n\n  // Lowercase letters\n  LowerA = 0x61,\n  LowerB = 0x62,\n  LowerE = 0x65,\n  LowerF = 0x66,\n  LowerL = 0x6C,\n  LowerN = 0x6E,\n  LowerR = 0x72,\n  LowerS = 0x73,\n  LowerT = 0x74,\n  LowerU = 0x75,\n}\n\nconst fromCharCode = String.fromCharCode\n\nfunction throwSyntaxError(bytes: Uint8Array, index: number, message?: string): void {\n  const c = bytes[index]\n  let line = 1\n  let column = 0\n\n  for (let i = 0; i < index; i++) {\n    if (bytes[i] === Char.Newline) {\n      line++\n      column = 0\n    } else {\n      column++\n    }\n  }\n\n  throw new SyntaxError(\n    message ? message :\n      index === bytes.length ? 'Unexpected end of input while parsing JSON' :\n        c >= 0x20 && c <= 0x7E ? `Unexpected character ${fromCharCode(c)} in JSON at position ${index} (line ${line}, column ${column})` :\n          `Unexpected byte 0x${c.toString(16)} in JSON at position ${index} (line ${line}, column ${column})`)\n}\n\nexport function JSON_parse(bytes: Uint8Array): any {\n  if (!(bytes instanceof Uint8Array)) {\n    throw new Error(`JSON input must be a Uint8Array`)\n  }\n\n  const propertyStack: (string | null)[] = []\n  const objectStack: any[] = []\n  const stateStack: State[] = []\n  const length = bytes.length\n  let property: string | null = null\n  let state = State.TopLevel\n  let object: any\n  let i = 0\n\n  while (i < length) {\n    let c = bytes[i++]\n\n    // Skip whitespace\n    if (c <= Char.Space) {\n      continue\n    }\n\n    let value: any\n\n    // Validate state inside objects\n    if (state === State.Object && property === null && c !== Char.Quote && c !== Char.CloseBrace) {\n      throwSyntaxError(bytes, --i)\n    }\n\n    switch (c) {\n      // True\n      case Char.LowerT: {\n        if (bytes[i++] !== Char.LowerR || bytes[i++] !== Char.LowerU || bytes[i++] !== Char.LowerE) {\n          throwSyntaxError(bytes, --i)\n        }\n\n        value = true\n        break\n      }\n\n      // False\n      case Char.LowerF: {\n        if (bytes[i++] !== Char.LowerA || bytes[i++] !== Char.LowerL || bytes[i++] !== Char.LowerS || bytes[i++] !== Char.LowerE) {\n          throwSyntaxError(bytes, --i)\n        }\n\n        value = false\n        break\n      }\n\n      // Null\n      case Char.LowerN: {\n        if (bytes[i++] !== Char.LowerU || bytes[i++] !== Char.LowerL || bytes[i++] !== Char.LowerL) {\n          throwSyntaxError(bytes, --i)\n        }\n\n        value = null\n        break\n      }\n\n      // Number begin\n      case Char.Minus:\n      case Char.Dot:\n      case Char.Digit0:\n      case Char.Digit1:\n      case Char.Digit2:\n      case Char.Digit3:\n      case Char.Digit4:\n      case Char.Digit5:\n      case Char.Digit6:\n      case Char.Digit7:\n      case Char.Digit8:\n      case Char.Digit9: {\n        let index = i\n        value = fromCharCode(c)\n        c = bytes[i]\n\n        // Scan over the rest of the number\n        while (true) {\n          switch (c) {\n            case Char.Plus:\n            case Char.Minus:\n            case Char.Dot:\n            case Char.Digit0:\n            case Char.Digit1:\n            case Char.Digit2:\n            case Char.Digit3:\n            case Char.Digit4:\n            case Char.Digit5:\n            case Char.Digit6:\n            case Char.Digit7:\n            case Char.Digit8:\n            case Char.Digit9:\n            case Char.LowerE:\n            case Char.UpperE: {\n              value += fromCharCode(c)\n              c = bytes[++i]\n              continue\n            }\n          }\n\n          // Number end\n          break\n        }\n\n        // Convert the string to a number\n        value = +value\n\n        // Validate the number\n        if (isNaN(value)) {\n          throwSyntaxError(bytes, --index, 'Invalid number')\n        }\n\n        break\n      }\n\n      // String begin\n      case Char.Quote: {\n        value = ''\n\n        while (true) {\n          if (i >= length) {\n            throwSyntaxError(bytes, length)\n          }\n\n          c = bytes[i++]\n\n          // String end\n          if (c === Char.Quote) {\n            break\n          }\n\n          // Escape sequence\n          else if (c === Char.Backslash) {\n            switch (bytes[i++]) {\n              // Normal escape sequence\n              case Char.Quote: value += '\\\"'; break\n              case Char.Slash: value += '\\/'; break\n              case Char.Backslash: value += '\\\\'; break\n              case Char.LowerB: value += '\\b'; break\n              case Char.LowerF: value += '\\f'; break\n              case Char.LowerN: value += '\\n'; break\n              case Char.LowerR: value += '\\r'; break\n              case Char.LowerT: value += '\\t'; break\n\n              // Unicode escape sequence\n              case Char.LowerU: {\n                let code = 0\n                for (let j = 0; j < 4; j++) {\n                  c = bytes[i++]\n                  code <<= 4\n                  if (c >= Char.Digit0 && c <= Char.Digit9) code |= c - Char.Digit0\n                  else if (c >= Char.LowerA && c <= Char.LowerF) code |= c + (10 - Char.LowerA)\n                  else if (c >= Char.UpperA && c <= Char.UpperF) code |= c + (10 - Char.UpperA)\n                  else throwSyntaxError(bytes, --i)\n                }\n                value += fromCharCode(code)\n                break\n              }\n\n              // Invalid escape sequence\n              default: throwSyntaxError(bytes, --i); break\n            }\n          }\n\n          // ASCII text\n          else if (c <= 0x7F) {\n            value += fromCharCode(c)\n          }\n\n          // 2-byte UTF-8 sequence\n          else if ((c & 0xE0) === 0xC0) {\n            value += fromCharCode(((c & 0x1F) << 6) | (bytes[i++] & 0x3F))\n          }\n\n          // 3-byte UTF-8 sequence\n          else if ((c & 0xF0) === 0xE0) {\n            value += fromCharCode(((c & 0x0F) << 12) | ((bytes[i++] & 0x3F) << 6) | (bytes[i++] & 0x3F))\n          }\n\n          // 4-byte UTF-8 sequence\n          else if ((c & 0xF8) == 0xF0) {\n            let codePoint = ((c & 0x07) << 18) | ((bytes[i++] & 0x3F) << 12) | ((bytes[i++] & 0x3F) << 6) | (bytes[i++] & 0x3F)\n            if (codePoint > 0xFFFF) {\n              codePoint -= 0x10000\n              value += fromCharCode(((codePoint >> 10) & 0x3FF) | 0xD800)\n              codePoint = 0xDC00 | (codePoint & 0x3FF)\n            }\n            value += fromCharCode(codePoint)\n          }\n        }\n\n        // Force V8's rope representation to be flattened to compact the string and avoid running out of memory\n        value[0]\n        break\n      }\n\n      // Array begin\n      case Char.OpenBracket: {\n        value = []\n\n        // Push the stack\n        propertyStack.push(property)\n        objectStack.push(object)\n        stateStack.push(state)\n\n        // Enter the array\n        property = null\n        object = value\n        state = State.Array\n        continue\n      }\n\n      // Object begin\n      case Char.OpenBrace: {\n        value = {}\n\n        // Push the stack\n        propertyStack.push(property)\n        objectStack.push(object)\n        stateStack.push(state)\n\n        // Enter the object\n        property = null\n        object = value\n        state = State.Object\n        continue\n      }\n\n      // Array end\n      case Char.CloseBracket: {\n        if (state !== State.Array) {\n          throwSyntaxError(bytes, --i)\n        }\n\n        // Leave the array\n        value = object\n\n        // Pop the stack\n        property = propertyStack.pop() as string | null\n        object = objectStack.pop()\n        state = stateStack.pop() as State\n        break\n      }\n\n      // Object end\n      case Char.CloseBrace: {\n        if (state !== State.Object) {\n          throwSyntaxError(bytes, --i)\n        }\n\n        // Leave the object\n        value = object\n\n        // Pop the stack\n        property = propertyStack.pop() as string | null\n        object = objectStack.pop()\n        state = stateStack.pop() as State\n        break\n      }\n\n      default: {\n        throwSyntaxError(bytes, --i)\n      }\n    }\n\n    c = bytes[i]\n\n    // Skip whitespace\n    while (c <= Char.Space) {\n      c = bytes[++i]\n    }\n\n    switch (state) {\n      case State.TopLevel: {\n        // Expect the end of the input\n        if (i === length) {\n          return value\n        }\n\n        break\n      }\n\n      case State.Array: {\n        object.push(value)\n\n        // Check for more values\n        if (c === Char.Comma) {\n          i++\n          continue\n        }\n\n        // Expect the end of the array\n        if (c === Char.CloseBracket) {\n          continue\n        }\n\n        break\n      }\n\n      case State.Object: {\n        // Property\n        if (property === null) {\n          property = value\n\n          // Expect a colon\n          if (c === Char.Colon) {\n            i++\n            continue\n          }\n        }\n\n        // Value\n        else {\n          object[property] = value\n          property = null\n\n          // Check for more values\n          if (c === Char.Comma) {\n            i++\n            continue\n          }\n\n          // Expect the end of the object\n          if (c === Char.CloseBrace) {\n            continue\n          }\n        }\n\n        break\n      }\n    }\n\n    // It's an error if we get here\n    break\n  }\n\n  throwSyntaxError(bytes, i)\n}\n"
  },
  {
    "path": "lib/shared/worker.ts",
    "content": "// This file is part of the web worker source code\n\ninterface Go {\n  argv: string[]\n  importObject: WebAssembly.Imports\n  run(instance: WebAssembly.Instance): void\n}\n\ndeclare const ESBUILD_VERSION: string\ndeclare function postMessage(message: any): void\n\nonmessage = ({ data: wasm }: { data: WebAssembly.Module | string }) => {\n  let decoder = new TextDecoder()\n  let fs = (globalThis as any).fs\n\n  let stderr = ''\n  fs.writeSync = (fd: number, buffer: Uint8Array) => {\n    if (fd === 1) {\n      postMessage(buffer)\n    } else if (fd === 2) {\n      stderr += decoder.decode(buffer)\n      let parts = stderr.split('\\n')\n      if (parts.length > 1) console.log(parts.slice(0, -1).join('\\n'))\n      stderr = parts[parts.length - 1]\n    } else {\n      throw new Error('Bad write')\n    }\n    return buffer.length\n  }\n\n  let stdin: Uint8Array[] = []\n  let resumeStdin: () => void\n  let stdinPos = 0\n\n  onmessage = ({ data }) => {\n    if (data.length > 0) {\n      stdin.push(data)\n      if (resumeStdin) resumeStdin()\n    }\n    return go\n  }\n\n  fs.read = (\n    fd: number, buffer: Uint8Array, offset: number, length: number,\n    position: null, callback: (err: Error | null, count?: number) => void,\n  ) => {\n    if (fd !== 0 || offset !== 0 || length !== buffer.length || position !== null) {\n      throw new Error('Bad read')\n    }\n\n    if (stdin.length === 0) {\n      resumeStdin = () => fs.read(fd, buffer, offset, length, position, callback)\n      return\n    }\n\n    let first = stdin[0]\n    let count = Math.max(0, Math.min(length, first.length - stdinPos))\n    buffer.set(first.subarray(stdinPos, stdinPos + count), offset)\n    stdinPos += count\n    if (stdinPos === first.length) {\n      stdin.shift()\n      stdinPos = 0\n    }\n    callback(null, count)\n  }\n\n  let go: Go = new (globalThis as any).Go()\n  go.argv = ['', `--service=${ESBUILD_VERSION}`]\n\n  // Try to instantiate the module in the worker, then report back to the main thread\n  tryToInstantiateModule(wasm, go).then(\n    instance => {\n      postMessage(null)\n      go.run(instance)\n    },\n    error => {\n      postMessage(error)\n    },\n  )\n\n  return go\n}\n\nasync function tryToInstantiateModule(wasm: WebAssembly.Module | string, go: Go): Promise<WebAssembly.Instance> {\n  if (wasm instanceof WebAssembly.Module) {\n    return WebAssembly.instantiate(wasm, go.importObject)\n  }\n\n  const res = await fetch(wasm)\n  if (!res.ok) throw new Error(`Failed to download ${JSON.stringify(wasm)}`)\n\n  // Attempt to use the superior \"instantiateStreaming\" API first\n  if ('instantiateStreaming' in WebAssembly && /^application\\/wasm($|;)/i.test(res.headers.get('Content-Type') || '')) {\n    const result = await WebAssembly.instantiateStreaming(res, go.importObject)\n    return result.instance\n  }\n\n  // Otherwise, fall back to the inferior \"instantiate\" API\n  const bytes = await res.arrayBuffer()\n  const result = await WebAssembly.instantiate(bytes, go.importObject)\n  return result.instance\n}\n"
  },
  {
    "path": "lib/tsconfig-deno.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"esnext\", // Allow the \"import.meta\" and top-level await syntax\n    \"target\": \"es2017\", // Allow calling APIs such as \"Object.entries\"\n    \"strict\": true,\n    \"skipLibCheck\": true,\n  },\n  \"exclude\": [\n    \"npm\",\n  ],\n}\n"
  },
  {
    "path": "lib/tsconfig-nolib.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"CommonJS\", // Allow the \"import assignment\" syntax\n    \"target\": \"es2017\", // Allow calling APIs such as \"Object.entries\"\n    \"strict\": true,\n    \"lib\": [], // Omit \"dom\" to test what happens with the \"WebAssembly\" type, which is defined in \"dom\"\n  },\n  \"include\": [\n    \"shared/types.ts\",\n  ],\n}\n"
  },
  {
    "path": "lib/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"CommonJS\", // Allow the \"import assignment\" syntax\n    \"target\": \"es2017\", // Allow calling APIs such as \"Object.entries\"\n    \"strict\": true,\n  },\n  \"exclude\": [\n    \"deno\",\n  ],\n}\n"
  },
  {
    "path": "npm/@esbuild/aix-ppc64/README.md",
    "content": "# esbuild\n\nThis is the IBM AIX PowerPC 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/aix-ppc64/package.json",
    "content": "{\n  \"name\": \"@esbuild/aix-ppc64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The IBM AIX PowerPC 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"aix\"\n  ],\n  \"cpu\": [\n    \"ppc64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/android-arm/README.md",
    "content": "# esbuild\n\nThis is a WebAssembly shim for esbuild on Android ARM. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/android-arm/package.json",
    "content": "{\n  \"name\": \"@esbuild/android-arm\",\n  \"version\": \"0.27.4\",\n  \"description\": \"A WebAssembly shim for esbuild on Android ARM.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"android\"\n  ],\n  \"cpu\": [\n    \"arm\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/android-arm64/README.md",
    "content": "# esbuild\n\nThis is the Android ARM 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/android-arm64/package.json",
    "content": "{\n  \"name\": \"@esbuild/android-arm64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The Android ARM 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"android\"\n  ],\n  \"cpu\": [\n    \"arm64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/android-x64/README.md",
    "content": "# esbuild\n\nThis is a WebAssembly shim for esbuild on Android x64. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/android-x64/package.json",
    "content": "{\n  \"name\": \"@esbuild/android-x64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"A WebAssembly shim for esbuild on Android x64.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"android\"\n  ],\n  \"cpu\": [\n    \"x64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/darwin-arm64/README.md",
    "content": "# esbuild\n\nThis is the macOS ARM 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/darwin-arm64/package.json",
    "content": "{\n  \"name\": \"@esbuild/darwin-arm64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The macOS ARM 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"darwin\"\n  ],\n  \"cpu\": [\n    \"arm64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/darwin-x64/README.md",
    "content": "# esbuild\n\nThis is the macOS 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/darwin-x64/package.json",
    "content": "{\n  \"name\": \"@esbuild/darwin-x64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The macOS 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"darwin\"\n  ],\n  \"cpu\": [\n    \"x64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/freebsd-arm64/README.md",
    "content": "# esbuild\n\nThis is the FreeBSD ARM 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/freebsd-arm64/package.json",
    "content": "{\n  \"name\": \"@esbuild/freebsd-arm64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The FreeBSD ARM 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"freebsd\"\n  ],\n  \"cpu\": [\n    \"arm64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/freebsd-x64/README.md",
    "content": "# esbuild\n\nThis is the FreeBSD 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/freebsd-x64/package.json",
    "content": "{\n  \"name\": \"@esbuild/freebsd-x64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The FreeBSD 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"freebsd\"\n  ],\n  \"cpu\": [\n    \"x64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/linux-arm/README.md",
    "content": "# esbuild\n\nThis is the Linux ARM binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/linux-arm/package.json",
    "content": "{\n  \"name\": \"@esbuild/linux-arm\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The Linux ARM binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"linux\"\n  ],\n  \"cpu\": [\n    \"arm\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/linux-arm64/README.md",
    "content": "# esbuild\n\nThis is the Linux ARM 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/linux-arm64/package.json",
    "content": "{\n  \"name\": \"@esbuild/linux-arm64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The Linux ARM 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"linux\"\n  ],\n  \"cpu\": [\n    \"arm64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/linux-ia32/README.md",
    "content": "# esbuild\n\nThis is the Linux 32-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/linux-ia32/package.json",
    "content": "{\n  \"name\": \"@esbuild/linux-ia32\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The Linux 32-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"linux\"\n  ],\n  \"cpu\": [\n    \"ia32\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/linux-loong64/README.md",
    "content": "# esbuild\n\nThis is the Linux LoongArch 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/linux-loong64/package.json",
    "content": "{\n  \"name\": \"@esbuild/linux-loong64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The Linux LoongArch 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"linux\"\n  ],\n  \"cpu\": [\n    \"loong64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/linux-mips64el/README.md",
    "content": "# esbuild\n\nThis is the Linux MIPS 64-bit Little Endian binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/linux-mips64el/package.json",
    "content": "{\n  \"name\": \"@esbuild/linux-mips64el\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The Linux MIPS 64-bit Little Endian binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"linux\"\n  ],\n  \"cpu\": [\n    \"mips64el\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/linux-ppc64/README.md",
    "content": "# esbuild\n\nThis is the Linux PowerPC 64-bit Little Endian binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/linux-ppc64/package.json",
    "content": "{\n  \"name\": \"@esbuild/linux-ppc64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The Linux PowerPC 64-bit Little Endian binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"linux\"\n  ],\n  \"cpu\": [\n    \"ppc64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/linux-riscv64/README.md",
    "content": "# esbuild\n\nThis is the Linux RISC-V 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/linux-riscv64/package.json",
    "content": "{\n  \"name\": \"@esbuild/linux-riscv64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The Linux RISC-V 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"linux\"\n  ],\n  \"cpu\": [\n    \"riscv64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/linux-s390x/README.md",
    "content": "# esbuild\n\nThis is the Linux IBM Z 64-bit Big Endian binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/linux-s390x/package.json",
    "content": "{\n  \"name\": \"@esbuild/linux-s390x\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The Linux IBM Z 64-bit Big Endian binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"linux\"\n  ],\n  \"cpu\": [\n    \"s390x\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/linux-x64/README.md",
    "content": "# esbuild\n\nThis is the Linux 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/linux-x64/package.json",
    "content": "{\n  \"name\": \"@esbuild/linux-x64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The Linux 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"linux\"\n  ],\n  \"cpu\": [\n    \"x64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/netbsd-arm64/README.md",
    "content": "# esbuild\n\nThis is the NetBSD ARM 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n\n⚠️ Note: NetBSD is not one of [Node's supported platforms](https://nodejs.org/api/process.html#process_process_platform), so installing esbuild may or may not work on NetBSD depending on how Node has been patched. This is not a problem with esbuild. ⚠️\n"
  },
  {
    "path": "npm/@esbuild/netbsd-arm64/package.json",
    "content": "{\n  \"name\": \"@esbuild/netbsd-arm64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The NetBSD ARM 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"netbsd\"\n  ],\n  \"cpu\": [\n    \"arm64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/netbsd-x64/README.md",
    "content": "# esbuild\n\nThis is the NetBSD AMD64 binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n\n⚠️ Note: NetBSD is not one of [Node's supported platforms](https://nodejs.org/api/process.html#process_process_platform), so installing esbuild may or may not work on NetBSD depending on how Node has been patched. This is not a problem with esbuild. ⚠️\n"
  },
  {
    "path": "npm/@esbuild/netbsd-x64/package.json",
    "content": "{\n  \"name\": \"@esbuild/netbsd-x64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The NetBSD AMD64 binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"netbsd\"\n  ],\n  \"cpu\": [\n    \"x64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/openbsd-arm64/README.md",
    "content": "# esbuild\n\nThis is the OpenBSD ARM 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/openbsd-arm64/package.json",
    "content": "{\n  \"name\": \"@esbuild/openbsd-arm64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The OpenBSD ARM 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"openbsd\"\n  ],\n  \"cpu\": [\n    \"arm64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/openbsd-x64/README.md",
    "content": "# esbuild\n\nThis is the OpenBSD 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/openbsd-x64/package.json",
    "content": "{\n  \"name\": \"@esbuild/openbsd-x64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The OpenBSD 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"openbsd\"\n  ],\n  \"cpu\": [\n    \"x64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/openharmony-arm64/README.md",
    "content": "# esbuild\n\nThis is a WebAssembly shim for esbuild on OpenHarmony ARM64. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/openharmony-arm64/package.json",
    "content": "{\n  \"name\": \"@esbuild/openharmony-arm64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"A WebAssembly shim for esbuild on OpenHarmony ARM64.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"openharmony\"\n  ],\n  \"cpu\": [\n    \"arm64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/sunos-x64/README.md",
    "content": "# esbuild\n\nThis is the illumos 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/sunos-x64/package.json",
    "content": "{\n  \"name\": \"@esbuild/sunos-x64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The illumos 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"sunos\"\n  ],\n  \"cpu\": [\n    \"x64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/wasi-preview1/README.md",
    "content": "# esbuild\n\nThis is the WASI (WebAssembly System Interface) preview 1 binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/wasi-preview1/package.json",
    "content": "{\n  \"name\": \"@esbuild/wasi-preview1\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The WASI (WebAssembly System Interface) preview 1 binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\"\n}\n"
  },
  {
    "path": "npm/@esbuild/win32-arm64/README.md",
    "content": "# esbuild\n\nThis is the Windows ARM 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/win32-arm64/package.json",
    "content": "{\n  \"name\": \"@esbuild/win32-arm64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The Windows ARM 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"win32\"\n  ],\n  \"cpu\": [\n    \"arm64\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/win32-ia32/README.md",
    "content": "# esbuild\n\nThis is the Windows 32-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/win32-ia32/package.json",
    "content": "{\n  \"name\": \"@esbuild/win32-ia32\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The Windows 32-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"win32\"\n  ],\n  \"cpu\": [\n    \"ia32\"\n  ]\n}\n"
  },
  {
    "path": "npm/@esbuild/win32-x64/README.md",
    "content": "# esbuild\n\nThis is the Windows 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.\n"
  },
  {
    "path": "npm/@esbuild/win32-x64/package.json",
    "content": "{\n  \"name\": \"@esbuild/win32-x64\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The Windows 64-bit binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"preferUnplugged\": true,\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"os\": [\n    \"win32\"\n  ],\n  \"cpu\": [\n    \"x64\"\n  ]\n}\n"
  },
  {
    "path": "npm/esbuild/LICENSE.md",
    "content": "MIT License\n\nCopyright (c) 2020 Evan Wallace\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "npm/esbuild/README.md",
    "content": "# esbuild\n\nThis is a JavaScript bundler and minifier. See https://github.com/evanw/esbuild and the [JavaScript API documentation](https://esbuild.github.io/api/) for details.\n"
  },
  {
    "path": "npm/esbuild/package.json",
    "content": "{\n  \"name\": \"esbuild\",\n  \"version\": \"0.27.4\",\n  \"description\": \"An extremely fast JavaScript and CSS bundler and minifier.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"scripts\": {\n    \"postinstall\": \"node install.js\"\n  },\n  \"main\": \"lib/main.js\",\n  \"types\": \"lib/main.d.ts\",\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"bin\": {\n    \"esbuild\": \"bin/esbuild\"\n  },\n  \"optionalDependencies\": {\n    \"@esbuild/aix-ppc64\": \"0.27.4\",\n    \"@esbuild/android-arm\": \"0.27.4\",\n    \"@esbuild/android-arm64\": \"0.27.4\",\n    \"@esbuild/android-x64\": \"0.27.4\",\n    \"@esbuild/darwin-arm64\": \"0.27.4\",\n    \"@esbuild/darwin-x64\": \"0.27.4\",\n    \"@esbuild/freebsd-arm64\": \"0.27.4\",\n    \"@esbuild/freebsd-x64\": \"0.27.4\",\n    \"@esbuild/linux-arm\": \"0.27.4\",\n    \"@esbuild/linux-arm64\": \"0.27.4\",\n    \"@esbuild/linux-ia32\": \"0.27.4\",\n    \"@esbuild/linux-loong64\": \"0.27.4\",\n    \"@esbuild/linux-mips64el\": \"0.27.4\",\n    \"@esbuild/linux-ppc64\": \"0.27.4\",\n    \"@esbuild/linux-riscv64\": \"0.27.4\",\n    \"@esbuild/linux-s390x\": \"0.27.4\",\n    \"@esbuild/linux-x64\": \"0.27.4\",\n    \"@esbuild/netbsd-arm64\": \"0.27.4\",\n    \"@esbuild/netbsd-x64\": \"0.27.4\",\n    \"@esbuild/openbsd-arm64\": \"0.27.4\",\n    \"@esbuild/openbsd-x64\": \"0.27.4\",\n    \"@esbuild/openharmony-arm64\": \"0.27.4\",\n    \"@esbuild/sunos-x64\": \"0.27.4\",\n    \"@esbuild/win32-arm64\": \"0.27.4\",\n    \"@esbuild/win32-ia32\": \"0.27.4\",\n    \"@esbuild/win32-x64\": \"0.27.4\"\n  },\n  \"license\": \"MIT\"\n}\n"
  },
  {
    "path": "npm/esbuild-wasm/LICENSE.md",
    "content": "MIT License\n\nCopyright (c) 2020 Evan Wallace\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "npm/esbuild-wasm/README.md",
    "content": "# esbuild\n\nThis is the cross-platform WebAssembly binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild and the [JavaScript API documentation](https://esbuild.github.io/api/) for details.\n"
  },
  {
    "path": "npm/esbuild-wasm/package.json",
    "content": "{\n  \"name\": \"esbuild-wasm\",\n  \"version\": \"0.27.4\",\n  \"description\": \"The cross-platform WebAssembly binary for esbuild, a JavaScript bundler.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/evanw/esbuild.git\"\n  },\n  \"license\": \"MIT\",\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"main\": \"lib/main.js\",\n  \"browser\": \"lib/browser.js\",\n  \"types\": \"lib/main.d.ts\",\n  \"directories\": {\n    \"bin\": \"bin\"\n  }\n}\n"
  },
  {
    "path": "pkg/api/api.go",
    "content": "// This API exposes esbuild's two main operations: building and transforming.\n// It's intended for integrating esbuild into other tools as a library.\n//\n// If you are just trying to run esbuild from Go without the overhead of\n// creating a child process, there is also an API for the command-line\n// interface itself: https://pkg.go.dev/github.com/evanw/esbuild/pkg/cli.\n//\n// # Build API\n//\n// This function runs an end-to-end build operation. It takes an array of file\n// paths as entry points, parses them and all of their dependencies, and\n// returns the output files to write to the file system. The available options\n// roughly correspond to esbuild's command-line flags.\n//\n// Example usage:\n//\n//\tpackage main\n//\n//\timport (\n//\t    \"os\"\n//\n//\t    \"github.com/evanw/esbuild/pkg/api\"\n//\t)\n//\n//\tfunc main() {\n//\t    result := api.Build(api.BuildOptions{\n//\t        EntryPoints: []string{\"input.js\"},\n//\t        Outfile:     \"output.js\",\n//\t        Bundle:      true,\n//\t        Write:       true,\n//\t        LogLevel:    api.LogLevelInfo,\n//\t    })\n//\n//\t    if len(result.Errors) > 0 {\n//\t        os.Exit(1)\n//\t    }\n//\t}\n//\n// # Transform API\n//\n// This function transforms a string of source code into JavaScript. It can be\n// used to minify JavaScript, convert TypeScript/JSX to JavaScript, or convert\n// newer JavaScript to older JavaScript. The available options roughly\n// correspond to esbuild's command-line flags.\n//\n// Example usage:\n//\n//\tpackage main\n//\n//\timport (\n//\t    \"fmt\"\n//\t    \"os\"\n//\n//\t    \"github.com/evanw/esbuild/pkg/api\"\n//\t)\n//\n//\tfunc main() {\n//\t    jsx := `\n//\t        import * as React from 'react'\n//\t        import * as ReactDOM from 'react-dom'\n//\n//\t        ReactDOM.render(\n//\t            <h1>Hello, world!</h1>,\n//\t            document.getElementById('root')\n//\t        );\n//\t    `\n//\n//\t    result := api.Transform(jsx, api.TransformOptions{\n//\t        Loader: api.LoaderJSX,\n//\t    })\n//\n//\t    fmt.Printf(\"%d errors and %d warnings\\n\",\n//\t        len(result.Errors), len(result.Warnings))\n//\n//\t    os.Stdout.Write(result.Code)\n//\t}\npackage api\n\nimport (\n\t\"time\"\n\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\ntype SourceMap uint8\n\nconst (\n\tSourceMapNone SourceMap = iota\n\tSourceMapInline\n\tSourceMapLinked\n\tSourceMapExternal\n\tSourceMapInlineAndExternal\n)\n\ntype SourcesContent uint8\n\nconst (\n\tSourcesContentInclude SourcesContent = iota\n\tSourcesContentExclude\n)\n\ntype LegalComments uint8\n\nconst (\n\tLegalCommentsDefault LegalComments = iota\n\tLegalCommentsNone\n\tLegalCommentsInline\n\tLegalCommentsEndOfFile\n\tLegalCommentsLinked\n\tLegalCommentsExternal\n)\n\ntype JSX uint8\n\nconst (\n\tJSXTransform JSX = iota\n\tJSXPreserve\n\tJSXAutomatic\n)\n\ntype Target uint8\n\nconst (\n\tDefaultTarget Target = iota\n\tESNext\n\tES5\n\tES2015\n\tES2016\n\tES2017\n\tES2018\n\tES2019\n\tES2020\n\tES2021\n\tES2022\n\tES2023\n\tES2024\n)\n\ntype Loader uint16\n\nconst (\n\tLoaderNone Loader = iota\n\tLoaderBase64\n\tLoaderBinary\n\tLoaderCopy\n\tLoaderCSS\n\tLoaderDataURL\n\tLoaderDefault\n\tLoaderEmpty\n\tLoaderFile\n\tLoaderGlobalCSS\n\tLoaderJS\n\tLoaderJSON\n\tLoaderJSX\n\tLoaderLocalCSS\n\tLoaderText\n\tLoaderTS\n\tLoaderTSX\n)\n\ntype Platform uint8\n\nconst (\n\tPlatformDefault Platform = iota\n\tPlatformBrowser\n\tPlatformNode\n\tPlatformNeutral\n)\n\ntype Format uint8\n\nconst (\n\tFormatDefault Format = iota\n\tFormatIIFE\n\tFormatCommonJS\n\tFormatESModule\n)\n\ntype Packages uint8\n\nconst (\n\tPackagesDefault Packages = iota\n\tPackagesBundle\n\tPackagesExternal\n)\n\ntype Engine struct {\n\tName    EngineName\n\tVersion string\n}\n\ntype Location struct {\n\tFile       string\n\tNamespace  string\n\tLine       int // 1-based\n\tColumn     int // 0-based, in bytes\n\tLength     int // in bytes\n\tLineText   string\n\tSuggestion string\n}\n\ntype Message struct {\n\tID         string\n\tPluginName string\n\tText       string\n\tLocation   *Location\n\tNotes      []Note\n\n\t// Optional user-specified data that is passed through unmodified. You can\n\t// use this to stash the original error, for example.\n\tDetail interface{}\n}\n\ntype Note struct {\n\tText     string\n\tLocation *Location\n}\n\ntype StderrColor uint8\n\nconst (\n\tColorIfTerminal StderrColor = iota\n\tColorNever\n\tColorAlways\n)\n\ntype LogLevel uint8\n\nconst (\n\tLogLevelSilent LogLevel = iota\n\tLogLevelVerbose\n\tLogLevelDebug\n\tLogLevelInfo\n\tLogLevelWarning\n\tLogLevelError\n)\n\ntype Charset uint8\n\nconst (\n\tCharsetDefault Charset = iota\n\tCharsetASCII\n\tCharsetUTF8\n)\n\ntype TreeShaking uint8\n\nconst (\n\tTreeShakingDefault TreeShaking = iota\n\tTreeShakingFalse\n\tTreeShakingTrue\n)\n\ntype Drop uint8\n\nconst (\n\tDropConsole Drop = 1 << iota\n\tDropDebugger\n)\n\ntype MangleQuoted uint8\n\nconst (\n\tMangleQuotedFalse MangleQuoted = iota\n\tMangleQuotedTrue\n)\n\ntype AbsPaths uint8\n\nconst (\n\tCodeAbsPath AbsPaths = 1 << iota\n\tLogAbsPath\n\tMetafileAbsPath\n)\n\n////////////////////////////////////////////////////////////////////////////////\n// Build API\n\ntype BuildOptions struct {\n\tColor       StderrColor         // Documentation: https://esbuild.github.io/api/#color\n\tLogLevel    LogLevel            // Documentation: https://esbuild.github.io/api/#log-level\n\tLogLimit    int                 // Documentation: https://esbuild.github.io/api/#log-limit\n\tLogOverride map[string]LogLevel // Documentation: https://esbuild.github.io/api/#log-override\n\tAbsPaths    AbsPaths            // Documentation: https://esbuild.github.io/api/#abs-path\n\n\tSourcemap      SourceMap      // Documentation: https://esbuild.github.io/api/#sourcemap\n\tSourceRoot     string         // Documentation: https://esbuild.github.io/api/#source-root\n\tSourcesContent SourcesContent // Documentation: https://esbuild.github.io/api/#sources-content\n\n\tTarget    Target          // Documentation: https://esbuild.github.io/api/#target\n\tEngines   []Engine        // Documentation: https://esbuild.github.io/api/#target\n\tSupported map[string]bool // Documentation: https://esbuild.github.io/api/#supported\n\n\tMangleProps       string                 // Documentation: https://esbuild.github.io/api/#mangle-props\n\tReserveProps      string                 // Documentation: https://esbuild.github.io/api/#mangle-props\n\tMangleQuoted      MangleQuoted           // Documentation: https://esbuild.github.io/api/#mangle-props\n\tMangleCache       map[string]interface{} // Documentation: https://esbuild.github.io/api/#mangle-props\n\tDrop              Drop                   // Documentation: https://esbuild.github.io/api/#drop\n\tDropLabels        []string               // Documentation: https://esbuild.github.io/api/#drop-labels\n\tMinifyWhitespace  bool                   // Documentation: https://esbuild.github.io/api/#minify\n\tMinifyIdentifiers bool                   // Documentation: https://esbuild.github.io/api/#minify\n\tMinifySyntax      bool                   // Documentation: https://esbuild.github.io/api/#minify\n\tLineLimit         int                    // Documentation: https://esbuild.github.io/api/#line-limit\n\tCharset           Charset                // Documentation: https://esbuild.github.io/api/#charset\n\tTreeShaking       TreeShaking            // Documentation: https://esbuild.github.io/api/#tree-shaking\n\tIgnoreAnnotations bool                   // Documentation: https://esbuild.github.io/api/#ignore-annotations\n\tLegalComments     LegalComments          // Documentation: https://esbuild.github.io/api/#legal-comments\n\n\tJSX             JSX    // Documentation: https://esbuild.github.io/api/#jsx-mode\n\tJSXFactory      string // Documentation: https://esbuild.github.io/api/#jsx-factory\n\tJSXFragment     string // Documentation: https://esbuild.github.io/api/#jsx-fragment\n\tJSXImportSource string // Documentation: https://esbuild.github.io/api/#jsx-import-source\n\tJSXDev          bool   // Documentation: https://esbuild.github.io/api/#jsx-dev\n\tJSXSideEffects  bool   // Documentation: https://esbuild.github.io/api/#jsx-side-effects\n\n\tDefine    map[string]string // Documentation: https://esbuild.github.io/api/#define\n\tPure      []string          // Documentation: https://esbuild.github.io/api/#pure\n\tKeepNames bool              // Documentation: https://esbuild.github.io/api/#keep-names\n\n\tGlobalName        string            // Documentation: https://esbuild.github.io/api/#global-name\n\tBundle            bool              // Documentation: https://esbuild.github.io/api/#bundle\n\tPreserveSymlinks  bool              // Documentation: https://esbuild.github.io/api/#preserve-symlinks\n\tSplitting         bool              // Documentation: https://esbuild.github.io/api/#splitting\n\tOutfile           string            // Documentation: https://esbuild.github.io/api/#outfile\n\tMetafile          bool              // Documentation: https://esbuild.github.io/api/#metafile\n\tOutdir            string            // Documentation: https://esbuild.github.io/api/#outdir\n\tOutbase           string            // Documentation: https://esbuild.github.io/api/#outbase\n\tAbsWorkingDir     string            // Documentation: https://esbuild.github.io/api/#working-directory\n\tPlatform          Platform          // Documentation: https://esbuild.github.io/api/#platform\n\tFormat            Format            // Documentation: https://esbuild.github.io/api/#format\n\tExternal          []string          // Documentation: https://esbuild.github.io/api/#external\n\tPackages          Packages          // Documentation: https://esbuild.github.io/api/#packages\n\tAlias             map[string]string // Documentation: https://esbuild.github.io/api/#alias\n\tMainFields        []string          // Documentation: https://esbuild.github.io/api/#main-fields\n\tConditions        []string          // Documentation: https://esbuild.github.io/api/#conditions\n\tLoader            map[string]Loader // Documentation: https://esbuild.github.io/api/#loader\n\tResolveExtensions []string          // Documentation: https://esbuild.github.io/api/#resolve-extensions\n\tTsconfig          string            // Documentation: https://esbuild.github.io/api/#tsconfig\n\tTsconfigRaw       string            // Documentation: https://esbuild.github.io/api/#tsconfig-raw\n\tOutExtension      map[string]string // Documentation: https://esbuild.github.io/api/#out-extension\n\tPublicPath        string            // Documentation: https://esbuild.github.io/api/#public-path\n\tInject            []string          // Documentation: https://esbuild.github.io/api/#inject\n\tBanner            map[string]string // Documentation: https://esbuild.github.io/api/#banner\n\tFooter            map[string]string // Documentation: https://esbuild.github.io/api/#footer\n\tNodePaths         []string          // Documentation: https://esbuild.github.io/api/#node-paths\n\n\tEntryNames string // Documentation: https://esbuild.github.io/api/#entry-names\n\tChunkNames string // Documentation: https://esbuild.github.io/api/#chunk-names\n\tAssetNames string // Documentation: https://esbuild.github.io/api/#asset-names\n\n\tEntryPoints         []string     // Documentation: https://esbuild.github.io/api/#entry-points\n\tEntryPointsAdvanced []EntryPoint // Documentation: https://esbuild.github.io/api/#entry-points\n\n\tStdin          *StdinOptions // Documentation: https://esbuild.github.io/api/#stdin\n\tWrite          bool          // Documentation: https://esbuild.github.io/api/#write\n\tAllowOverwrite bool          // Documentation: https://esbuild.github.io/api/#allow-overwrite\n\tPlugins        []Plugin      // Documentation: https://esbuild.github.io/plugins/\n}\n\ntype EntryPoint struct {\n\tInputPath  string\n\tOutputPath string\n}\n\ntype StdinOptions struct {\n\tContents   string\n\tResolveDir string\n\tSourcefile string\n\tLoader     Loader\n}\n\ntype BuildResult struct {\n\tErrors   []Message\n\tWarnings []Message\n\n\tOutputFiles []OutputFile\n\tMetafile    string\n\tMangleCache map[string]interface{}\n}\n\ntype OutputFile struct {\n\tPath     string\n\tContents []byte\n\tHash     string\n}\n\n// Documentation: https://esbuild.github.io/api/#build\nfunc Build(options BuildOptions) BuildResult {\n\tstart := time.Now()\n\n\tctx, errors := contextImpl(options)\n\tif ctx == nil {\n\t\treturn BuildResult{Errors: errors}\n\t}\n\n\tresult := ctx.Rebuild()\n\n\t// Print a summary of the generated files to stderr. Except don't do\n\t// this if the terminal is already being used for something else.\n\tif ctx.args.logOptions.LogLevel <= logger.LevelInfo && !ctx.args.options.WriteToStdout {\n\t\tprintSummary(ctx.args.logOptions.Color, result.OutputFiles, start)\n\t}\n\n\tctx.Dispose()\n\treturn result\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Transform API\n\ntype TransformOptions struct {\n\tColor       StderrColor         // Documentation: https://esbuild.github.io/api/#color\n\tLogLevel    LogLevel            // Documentation: https://esbuild.github.io/api/#log-level\n\tLogLimit    int                 // Documentation: https://esbuild.github.io/api/#log-limit\n\tLogOverride map[string]LogLevel // Documentation: https://esbuild.github.io/api/#log-override\n\tAbsPaths    AbsPaths            // Documentation: https://esbuild.github.io/api/#abs-path\n\n\tSourcemap      SourceMap      // Documentation: https://esbuild.github.io/api/#sourcemap\n\tSourceRoot     string         // Documentation: https://esbuild.github.io/api/#source-root\n\tSourcesContent SourcesContent // Documentation: https://esbuild.github.io/api/#sources-content\n\n\tTarget    Target          // Documentation: https://esbuild.github.io/api/#target\n\tEngines   []Engine        // Documentation: https://esbuild.github.io/api/#target\n\tSupported map[string]bool // Documentation: https://esbuild.github.io/api/#supported\n\n\tPlatform   Platform // Documentation: https://esbuild.github.io/api/#platform\n\tFormat     Format   // Documentation: https://esbuild.github.io/api/#format\n\tGlobalName string   // Documentation: https://esbuild.github.io/api/#global-name\n\n\tMangleProps       string                 // Documentation: https://esbuild.github.io/api/#mangle-props\n\tReserveProps      string                 // Documentation: https://esbuild.github.io/api/#mangle-props\n\tMangleQuoted      MangleQuoted           // Documentation: https://esbuild.github.io/api/#mangle-props\n\tMangleCache       map[string]interface{} // Documentation: https://esbuild.github.io/api/#mangle-props\n\tDrop              Drop                   // Documentation: https://esbuild.github.io/api/#drop\n\tDropLabels        []string               // Documentation: https://esbuild.github.io/api/#drop-labels\n\tMinifyWhitespace  bool                   // Documentation: https://esbuild.github.io/api/#minify\n\tMinifyIdentifiers bool                   // Documentation: https://esbuild.github.io/api/#minify\n\tMinifySyntax      bool                   // Documentation: https://esbuild.github.io/api/#minify\n\tLineLimit         int                    // Documentation: https://esbuild.github.io/api/#line-limit\n\tCharset           Charset                // Documentation: https://esbuild.github.io/api/#charset\n\tTreeShaking       TreeShaking            // Documentation: https://esbuild.github.io/api/#tree-shaking\n\tIgnoreAnnotations bool                   // Documentation: https://esbuild.github.io/api/#ignore-annotations\n\tLegalComments     LegalComments          // Documentation: https://esbuild.github.io/api/#legal-comments\n\n\tJSX             JSX    // Documentation: https://esbuild.github.io/api/#jsx\n\tJSXFactory      string // Documentation: https://esbuild.github.io/api/#jsx-factory\n\tJSXFragment     string // Documentation: https://esbuild.github.io/api/#jsx-fragment\n\tJSXImportSource string // Documentation: https://esbuild.github.io/api/#jsx-import-source\n\tJSXDev          bool   // Documentation: https://esbuild.github.io/api/#jsx-dev\n\tJSXSideEffects  bool   // Documentation: https://esbuild.github.io/api/#jsx-side-effects\n\n\tTsconfigRaw string // Documentation: https://esbuild.github.io/api/#tsconfig-raw\n\tBanner      string // Documentation: https://esbuild.github.io/api/#banner\n\tFooter      string // Documentation: https://esbuild.github.io/api/#footer\n\n\tDefine    map[string]string // Documentation: https://esbuild.github.io/api/#define\n\tPure      []string          // Documentation: https://esbuild.github.io/api/#pure\n\tKeepNames bool              // Documentation: https://esbuild.github.io/api/#keep-names\n\n\tSourcefile string // Documentation: https://esbuild.github.io/api/#sourcefile\n\tLoader     Loader // Documentation: https://esbuild.github.io/api/#loader\n}\n\ntype TransformResult struct {\n\tErrors   []Message\n\tWarnings []Message\n\n\tCode          []byte\n\tMap           []byte\n\tLegalComments []byte\n\n\tMangleCache map[string]interface{}\n}\n\n// Documentation: https://esbuild.github.io/api/#transform\nfunc Transform(input string, options TransformOptions) TransformResult {\n\treturn transformImpl(input, options)\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Context API\n\n// Documentation: https://esbuild.github.io/api/#serve-arguments\ntype ServeOptions struct {\n\tPort      int\n\tHost      string\n\tServedir  string\n\tKeyfile   string\n\tCertfile  string\n\tFallback  string\n\tCORS      CORSOptions\n\tOnRequest func(ServeOnRequestArgs)\n}\n\n// Documentation: https://esbuild.github.io/api/#cors\ntype CORSOptions struct {\n\tOrigin []string\n}\n\ntype ServeOnRequestArgs struct {\n\tRemoteAddress string\n\tMethod        string\n\tPath          string\n\tStatus        int\n\tTimeInMS      int // The time to generate the response, not to send it\n}\n\n// Documentation: https://esbuild.github.io/api/#serve-return-values\ntype ServeResult struct {\n\tPort  uint16\n\tHosts []string\n}\n\n// Documentation: https://esbuild.github.io/api/#watch-arguments\ntype WatchOptions struct {\n\tDelay int // In milliseconds\n}\n\ntype BuildContext interface {\n\t// Documentation: https://esbuild.github.io/api/#rebuild\n\tRebuild() BuildResult\n\n\t// Documentation: https://esbuild.github.io/api/#watch\n\tWatch(options WatchOptions) error\n\n\t// Documentation: https://esbuild.github.io/api/#serve\n\tServe(options ServeOptions) (ServeResult, error)\n\n\tCancel()\n\tDispose()\n}\n\ntype ContextError struct {\n\tErrors []Message // Option validation errors are returned here\n}\n\nfunc (err *ContextError) Error() string {\n\tif len(err.Errors) > 0 {\n\t\treturn err.Errors[0].Text\n\t}\n\treturn \"Context creation failed\"\n}\n\n// Documentation: https://esbuild.github.io/api/#build\nfunc Context(buildOptions BuildOptions) (BuildContext, *ContextError) {\n\tctx, errors := contextImpl(buildOptions)\n\tif ctx == nil {\n\t\treturn nil, &ContextError{Errors: errors}\n\t}\n\treturn ctx, nil\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Plugin API\n\ntype SideEffects uint8\n\nconst (\n\tSideEffectsTrue SideEffects = iota\n\tSideEffectsFalse\n)\n\ntype Plugin struct {\n\tName  string\n\tSetup func(PluginBuild)\n}\n\ntype PluginBuild struct {\n\t// Documentation: https://esbuild.github.io/plugins/#build-options\n\tInitialOptions *BuildOptions\n\n\t// Documentation: https://esbuild.github.io/plugins/#resolve\n\tResolve func(path string, options ResolveOptions) ResolveResult\n\n\t// Documentation: https://esbuild.github.io/plugins/#on-start\n\tOnStart func(callback func() (OnStartResult, error))\n\n\t// Documentation: https://esbuild.github.io/plugins/#on-end\n\tOnEnd func(callback func(result *BuildResult) (OnEndResult, error))\n\n\t// Documentation: https://esbuild.github.io/plugins/#on-resolve\n\tOnResolve func(options OnResolveOptions, callback func(OnResolveArgs) (OnResolveResult, error))\n\n\t// Documentation: https://esbuild.github.io/plugins/#on-load\n\tOnLoad func(options OnLoadOptions, callback func(OnLoadArgs) (OnLoadResult, error))\n\n\t// Documentation: https://esbuild.github.io/plugins/#on-dispose\n\tOnDispose func(callback func())\n}\n\n// Documentation: https://esbuild.github.io/plugins/#resolve-options\ntype ResolveOptions struct {\n\tPluginName string\n\tImporter   string\n\tNamespace  string\n\tResolveDir string\n\tKind       ResolveKind\n\tPluginData interface{}\n\tWith       map[string]string\n}\n\n// Documentation: https://esbuild.github.io/plugins/#resolve-results\ntype ResolveResult struct {\n\tErrors   []Message\n\tWarnings []Message\n\n\tPath        string\n\tExternal    bool\n\tSideEffects bool\n\tNamespace   string\n\tSuffix      string\n\tPluginData  interface{}\n}\n\ntype OnStartResult struct {\n\tErrors   []Message\n\tWarnings []Message\n}\n\ntype OnEndResult struct {\n\tErrors   []Message\n\tWarnings []Message\n}\n\n// Documentation: https://esbuild.github.io/plugins/#on-resolve-options\ntype OnResolveOptions struct {\n\tFilter    string\n\tNamespace string\n}\n\n// Documentation: https://esbuild.github.io/plugins/#on-resolve-arguments\ntype OnResolveArgs struct {\n\tPath       string\n\tImporter   string\n\tNamespace  string\n\tResolveDir string\n\tKind       ResolveKind\n\tPluginData interface{}\n\tWith       map[string]string\n}\n\n// Documentation: https://esbuild.github.io/plugins/#on-resolve-results\ntype OnResolveResult struct {\n\tPluginName string\n\n\tErrors   []Message\n\tWarnings []Message\n\n\tPath        string\n\tExternal    bool\n\tSideEffects SideEffects\n\tNamespace   string\n\tSuffix      string\n\tPluginData  interface{}\n\n\tWatchFiles []string\n\tWatchDirs  []string\n}\n\n// Documentation: https://esbuild.github.io/plugins/#on-load-options\ntype OnLoadOptions struct {\n\tFilter    string\n\tNamespace string\n}\n\n// Documentation: https://esbuild.github.io/plugins/#on-load-arguments\ntype OnLoadArgs struct {\n\tPath       string\n\tNamespace  string\n\tSuffix     string\n\tPluginData interface{}\n\tWith       map[string]string\n}\n\n// Documentation: https://esbuild.github.io/plugins/#on-load-results\ntype OnLoadResult struct {\n\tPluginName string\n\n\tErrors   []Message\n\tWarnings []Message\n\n\tContents   *string\n\tResolveDir string\n\tLoader     Loader\n\tPluginData interface{}\n\n\tWatchFiles []string\n\tWatchDirs  []string\n}\n\ntype ResolveKind uint8\n\nconst (\n\tResolveNone ResolveKind = iota\n\tResolveEntryPoint\n\tResolveJSImportStatement\n\tResolveJSRequireCall\n\tResolveJSDynamicImport\n\tResolveJSRequireResolve\n\tResolveCSSImportRule\n\tResolveCSSComposesFrom\n\tResolveCSSURLToken\n)\n\n////////////////////////////////////////////////////////////////////////////////\n// FormatMessages API\n\ntype MessageKind uint8\n\nconst (\n\tErrorMessage MessageKind = iota\n\tWarningMessage\n)\n\ntype FormatMessagesOptions struct {\n\tTerminalWidth int\n\tKind          MessageKind\n\tColor         bool\n}\n\nfunc FormatMessages(msgs []Message, opts FormatMessagesOptions) []string {\n\treturn formatMsgsImpl(msgs, opts)\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// AnalyzeMetafile API\n\ntype AnalyzeMetafileOptions struct {\n\tColor   bool\n\tVerbose bool\n}\n\n// Documentation: https://esbuild.github.io/api/#analyze\nfunc AnalyzeMetafile(metafile string, opts AnalyzeMetafileOptions) string {\n\treturn analyzeMetafileImpl(metafile, opts)\n}\n"
  },
  {
    "path": "pkg/api/api_impl.go",
    "content": "package api\n\n// This file implements most of the API. This includes the \"Build\", \"Transform\",\n// \"FormatMessages\", and \"AnalyzeMetafile\" functions.\n\nimport (\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"math\"\n\t\"os\"\n\t\"path\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\t\"unicode/utf8\"\n\n\t\"github.com/evanw/esbuild/internal/api_helpers\"\n\t\"github.com/evanw/esbuild/internal/ast\"\n\t\"github.com/evanw/esbuild/internal/bundler\"\n\t\"github.com/evanw/esbuild/internal/cache\"\n\t\"github.com/evanw/esbuild/internal/compat\"\n\t\"github.com/evanw/esbuild/internal/config\"\n\t\"github.com/evanw/esbuild/internal/css_ast\"\n\t\"github.com/evanw/esbuild/internal/fs\"\n\t\"github.com/evanw/esbuild/internal/graph\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/js_parser\"\n\t\"github.com/evanw/esbuild/internal/linker\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/resolver\"\n\t\"github.com/evanw/esbuild/internal/xxhash\"\n)\n\nfunc validatePathTemplate(template string) []config.PathTemplate {\n\tif template == \"\" {\n\t\treturn nil\n\t}\n\ttemplate = \"./\" + strings.ReplaceAll(template, \"\\\\\", \"/\")\n\n\tparts := make([]config.PathTemplate, 0, 4)\n\tsearch := 0\n\n\t// Split by placeholders\n\tfor search < len(template) {\n\t\t// Jump to the next \"[\"\n\t\tif found := strings.IndexByte(template[search:], '['); found == -1 {\n\t\t\tbreak\n\t\t} else {\n\t\t\tsearch += found\n\t\t}\n\t\thead, tail := template[:search], template[search:]\n\t\tplaceholder := config.NoPlaceholder\n\n\t\t// Check for a placeholder\n\t\tswitch {\n\t\tcase strings.HasPrefix(tail, \"[dir]\"):\n\t\t\tplaceholder = config.DirPlaceholder\n\t\t\tsearch += len(\"[dir]\")\n\n\t\tcase strings.HasPrefix(tail, \"[name]\"):\n\t\t\tplaceholder = config.NamePlaceholder\n\t\t\tsearch += len(\"[name]\")\n\n\t\tcase strings.HasPrefix(tail, \"[hash]\"):\n\t\t\tplaceholder = config.HashPlaceholder\n\t\t\tsearch += len(\"[hash]\")\n\n\t\tcase strings.HasPrefix(tail, \"[ext]\"):\n\t\t\tplaceholder = config.ExtPlaceholder\n\t\t\tsearch += len(\"[ext]\")\n\n\t\tdefault:\n\t\t\t// Skip past the \"[\" so we don't find it again\n\t\t\tsearch++\n\t\t\tcontinue\n\t\t}\n\n\t\t// Add a part for everything up to and including this placeholder\n\t\tparts = append(parts, config.PathTemplate{\n\t\t\tData:        head,\n\t\t\tPlaceholder: placeholder,\n\t\t})\n\n\t\t// Reset the search after this placeholder\n\t\ttemplate = template[search:]\n\t\tsearch = 0\n\t}\n\n\t// Append any remaining data as a part without a placeholder\n\tif search < len(template) {\n\t\tparts = append(parts, config.PathTemplate{\n\t\t\tData:        template,\n\t\t\tPlaceholder: config.NoPlaceholder,\n\t\t})\n\t}\n\n\treturn parts\n}\n\nfunc validatePlatform(value Platform) config.Platform {\n\tswitch value {\n\tcase PlatformDefault, PlatformBrowser:\n\t\treturn config.PlatformBrowser\n\tcase PlatformNode:\n\t\treturn config.PlatformNode\n\tcase PlatformNeutral:\n\t\treturn config.PlatformNeutral\n\tdefault:\n\t\tpanic(\"Invalid platform\")\n\t}\n}\n\nfunc validateFormat(value Format) config.Format {\n\tswitch value {\n\tcase FormatDefault:\n\t\treturn config.FormatPreserve\n\tcase FormatIIFE:\n\t\treturn config.FormatIIFE\n\tcase FormatCommonJS:\n\t\treturn config.FormatCommonJS\n\tcase FormatESModule:\n\t\treturn config.FormatESModule\n\tdefault:\n\t\tpanic(\"Invalid format\")\n\t}\n}\n\nfunc validateSourceMap(value SourceMap) config.SourceMap {\n\tswitch value {\n\tcase SourceMapNone:\n\t\treturn config.SourceMapNone\n\tcase SourceMapLinked:\n\t\treturn config.SourceMapLinkedWithComment\n\tcase SourceMapInline:\n\t\treturn config.SourceMapInline\n\tcase SourceMapExternal:\n\t\treturn config.SourceMapExternalWithoutComment\n\tcase SourceMapInlineAndExternal:\n\t\treturn config.SourceMapInlineAndExternal\n\tdefault:\n\t\tpanic(\"Invalid source map\")\n\t}\n}\n\nfunc validateLegalComments(value LegalComments, bundle bool) config.LegalComments {\n\tswitch value {\n\tcase LegalCommentsDefault:\n\t\tif bundle {\n\t\t\treturn config.LegalCommentsEndOfFile\n\t\t} else {\n\t\t\treturn config.LegalCommentsInline\n\t\t}\n\tcase LegalCommentsNone:\n\t\treturn config.LegalCommentsNone\n\tcase LegalCommentsInline:\n\t\treturn config.LegalCommentsInline\n\tcase LegalCommentsEndOfFile:\n\t\treturn config.LegalCommentsEndOfFile\n\tcase LegalCommentsLinked:\n\t\treturn config.LegalCommentsLinkedWithComment\n\tcase LegalCommentsExternal:\n\t\treturn config.LegalCommentsExternalWithoutComment\n\tdefault:\n\t\tpanic(\"Invalid legal comments\")\n\t}\n}\n\nfunc validateColor(value StderrColor) logger.UseColor {\n\tswitch value {\n\tcase ColorIfTerminal:\n\t\treturn logger.ColorIfTerminal\n\tcase ColorNever:\n\t\treturn logger.ColorNever\n\tcase ColorAlways:\n\t\treturn logger.ColorAlways\n\tdefault:\n\t\tpanic(\"Invalid color\")\n\t}\n}\n\nfunc validateLogLevel(value LogLevel) logger.LogLevel {\n\tswitch value {\n\tcase LogLevelVerbose:\n\t\treturn logger.LevelVerbose\n\tcase LogLevelDebug:\n\t\treturn logger.LevelDebug\n\tcase LogLevelInfo:\n\t\treturn logger.LevelInfo\n\tcase LogLevelWarning:\n\t\treturn logger.LevelWarning\n\tcase LogLevelError:\n\t\treturn logger.LevelError\n\tcase LogLevelSilent:\n\t\treturn logger.LevelSilent\n\tdefault:\n\t\tpanic(\"Invalid log level\")\n\t}\n}\n\nfunc validateASCIIOnly(value Charset) bool {\n\tswitch value {\n\tcase CharsetDefault, CharsetASCII:\n\t\treturn true\n\tcase CharsetUTF8:\n\t\treturn false\n\tdefault:\n\t\tpanic(\"Invalid charset\")\n\t}\n}\n\nfunc validateExternalPackages(value Packages) bool {\n\tswitch value {\n\tcase PackagesDefault, PackagesBundle:\n\t\treturn false\n\tcase PackagesExternal:\n\t\treturn true\n\tdefault:\n\t\tpanic(\"Invalid packages\")\n\t}\n}\n\nfunc validateTreeShaking(value TreeShaking, bundle bool, format Format) bool {\n\tswitch value {\n\tcase TreeShakingDefault:\n\t\t// If we're in an IIFE then there's no way to concatenate additional code\n\t\t// to the end of our output so we assume tree shaking is safe. And when\n\t\t// bundling we assume that tree shaking is safe because if you want to add\n\t\t// code to the bundle, you should be doing that by including it in the\n\t\t// bundle instead of concatenating it afterward, so we also assume tree\n\t\t// shaking is safe then. Otherwise we assume tree shaking is not safe.\n\t\treturn bundle || format == FormatIIFE\n\tcase TreeShakingFalse:\n\t\treturn false\n\tcase TreeShakingTrue:\n\t\treturn true\n\tdefault:\n\t\tpanic(\"Invalid tree shaking\")\n\t}\n}\n\nfunc validateLoader(value Loader) config.Loader {\n\tswitch value {\n\tcase LoaderBase64:\n\t\treturn config.LoaderBase64\n\tcase LoaderBinary:\n\t\treturn config.LoaderBinary\n\tcase LoaderCopy:\n\t\treturn config.LoaderCopy\n\tcase LoaderCSS:\n\t\treturn config.LoaderCSS\n\tcase LoaderDataURL:\n\t\treturn config.LoaderDataURL\n\tcase LoaderDefault:\n\t\treturn config.LoaderDefault\n\tcase LoaderEmpty:\n\t\treturn config.LoaderEmpty\n\tcase LoaderFile:\n\t\treturn config.LoaderFile\n\tcase LoaderGlobalCSS:\n\t\treturn config.LoaderGlobalCSS\n\tcase LoaderJS:\n\t\treturn config.LoaderJS\n\tcase LoaderJSON:\n\t\treturn config.LoaderJSON\n\tcase LoaderJSX:\n\t\treturn config.LoaderJSX\n\tcase LoaderLocalCSS:\n\t\treturn config.LoaderLocalCSS\n\tcase LoaderNone:\n\t\treturn config.LoaderNone\n\tcase LoaderText:\n\t\treturn config.LoaderText\n\tcase LoaderTS:\n\t\treturn config.LoaderTS\n\tcase LoaderTSX:\n\t\treturn config.LoaderTSX\n\tdefault:\n\t\tpanic(\"Invalid loader\")\n\t}\n}\n\nfunc extractPathStyle(absPaths AbsPaths, flag AbsPaths) logger.PathStyle {\n\tif (absPaths & flag) != 0 {\n\t\treturn logger.AbsPath\n\t} else {\n\t\treturn logger.RelPath\n\t}\n}\n\nvar versionRegex = regexp.MustCompile(`^([0-9]+)(?:\\.([0-9]+))?(?:\\.([0-9]+))?(-[A-Za-z0-9]+(?:\\.[A-Za-z0-9]+)*)?$`)\n\nfunc validateFeatures(log logger.Log, target Target, engines []Engine) (compat.JSFeature, compat.CSSFeature, map[css_ast.D]compat.CSSPrefix, string) {\n\tif target == DefaultTarget && len(engines) == 0 {\n\t\treturn 0, 0, nil, \"\"\n\t}\n\n\tconstraints := make(map[compat.Engine]compat.Semver)\n\ttargets := make([]string, 0, 1+len(engines))\n\n\tswitch target {\n\tcase ES5:\n\t\tconstraints[compat.ES] = compat.Semver{Parts: []int{5}}\n\tcase ES2015:\n\t\tconstraints[compat.ES] = compat.Semver{Parts: []int{2015}}\n\tcase ES2016:\n\t\tconstraints[compat.ES] = compat.Semver{Parts: []int{2016}}\n\tcase ES2017:\n\t\tconstraints[compat.ES] = compat.Semver{Parts: []int{2017}}\n\tcase ES2018:\n\t\tconstraints[compat.ES] = compat.Semver{Parts: []int{2018}}\n\tcase ES2019:\n\t\tconstraints[compat.ES] = compat.Semver{Parts: []int{2019}}\n\tcase ES2020:\n\t\tconstraints[compat.ES] = compat.Semver{Parts: []int{2020}}\n\tcase ES2021:\n\t\tconstraints[compat.ES] = compat.Semver{Parts: []int{2021}}\n\tcase ES2022:\n\t\tconstraints[compat.ES] = compat.Semver{Parts: []int{2022}}\n\tcase ES2023:\n\t\tconstraints[compat.ES] = compat.Semver{Parts: []int{2023}}\n\tcase ES2024:\n\t\tconstraints[compat.ES] = compat.Semver{Parts: []int{2024}}\n\tcase ESNext, DefaultTarget:\n\tdefault:\n\t\tpanic(\"Invalid target\")\n\t}\n\n\tfor _, engine := range engines {\n\t\tif match := versionRegex.FindStringSubmatch(engine.Version); match != nil {\n\t\t\tif major, err := strconv.Atoi(match[1]); err == nil {\n\t\t\t\tparts := []int{major}\n\t\t\t\tif minor, err := strconv.Atoi(match[2]); err == nil {\n\t\t\t\t\tparts = append(parts, minor)\n\t\t\t\t\tif patch, err := strconv.Atoi(match[3]); err == nil {\n\t\t\t\t\t\tparts = append(parts, patch)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconstraints[convertEngineName(engine.Name)] = compat.Semver{\n\t\t\t\t\tParts:      parts,\n\t\t\t\t\tPreRelease: match[4],\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\ttext := \"All version numbers passed to esbuild must be in the format \\\"X\\\", \\\"X.Y\\\", or \\\"X.Y.Z\\\" where X, Y, and Z are non-negative integers.\"\n\n\t\tlog.AddErrorWithNotes(nil, logger.Range{}, fmt.Sprintf(\"Invalid version: %q\", engine.Version),\n\t\t\t[]logger.MsgData{{Text: text}})\n\t}\n\n\tfor engine, version := range constraints {\n\t\ttargets = append(targets, engine.String()+version.String())\n\t}\n\tif target == ESNext {\n\t\ttargets = append(targets, \"esnext\")\n\t}\n\n\tsort.Strings(targets)\n\ttargetEnv := helpers.StringArrayToQuotedCommaSeparatedString(targets)\n\n\treturn compat.UnsupportedJSFeatures(constraints), compat.UnsupportedCSSFeatures(constraints), compat.CSSPrefixData(constraints), targetEnv\n}\n\nfunc validateSupported(log logger.Log, supported map[string]bool) (\n\tjsFeature compat.JSFeature,\n\tjsMask compat.JSFeature,\n\tcssFeature compat.CSSFeature,\n\tcssMask compat.CSSFeature,\n) {\n\tfor k, v := range supported {\n\t\tif js, ok := compat.StringToJSFeature[k]; ok {\n\t\t\tjsMask |= js\n\t\t\tif !v {\n\t\t\t\tjsFeature |= js\n\t\t\t}\n\t\t} else if css, ok := compat.StringToCSSFeature[k]; ok {\n\t\t\tcssMask |= css\n\t\t\tif !v {\n\t\t\t\tcssFeature |= css\n\t\t\t}\n\t\t} else {\n\t\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\"%q is not a valid feature name for the \\\"supported\\\" setting\", k))\n\t\t}\n\t}\n\treturn\n}\n\nfunc validateGlobalName(log logger.Log, text string, path string) []string {\n\tif text != \"\" {\n\t\tsource := logger.Source{\n\t\t\tKeyPath:     logger.Path{Text: path},\n\t\t\tPrettyPaths: logger.PrettyPaths{Abs: path, Rel: path},\n\t\t\tContents:    text,\n\t\t}\n\n\t\tif result, ok := js_parser.ParseGlobalName(log, source); ok {\n\t\t\treturn result\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc validateRegex(log logger.Log, what string, value string) *regexp.Regexp {\n\tif value == \"\" {\n\t\treturn nil\n\t}\n\tregex, err := regexp.Compile(value)\n\tif err != nil {\n\t\tlog.AddError(nil, logger.Range{},\n\t\t\tfmt.Sprintf(\"The %q setting is not a valid Go regular expression: %s\", what, value))\n\t\treturn nil\n\t}\n\treturn regex\n}\n\nfunc validateExternals(log logger.Log, fs fs.FS, paths []string) config.ExternalSettings {\n\tresult := config.ExternalSettings{\n\t\tPreResolve:  config.ExternalMatchers{Exact: make(map[string]bool)},\n\t\tPostResolve: config.ExternalMatchers{Exact: make(map[string]bool)},\n\t}\n\n\tfor _, path := range paths {\n\t\tif index := strings.IndexByte(path, '*'); index != -1 {\n\t\t\t// Wildcard behavior\n\t\t\tif strings.ContainsRune(path[index+1:], '*') {\n\t\t\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\"External path %q cannot have more than one \\\"*\\\" wildcard\", path))\n\t\t\t} else {\n\t\t\t\tresult.PreResolve.Patterns = append(result.PreResolve.Patterns, config.WildcardPattern{Prefix: path[:index], Suffix: path[index+1:]})\n\t\t\t\tif !resolver.IsPackagePath(path) {\n\t\t\t\t\tif absPath := validatePath(log, fs, path, \"external path\"); absPath != \"\" {\n\t\t\t\t\t\tif absIndex := strings.IndexByte(absPath, '*'); absIndex != -1 && !strings.ContainsRune(absPath[absIndex+1:], '*') {\n\t\t\t\t\t\t\tresult.PostResolve.Patterns = append(result.PostResolve.Patterns, config.WildcardPattern{Prefix: absPath[:absIndex], Suffix: absPath[absIndex+1:]})\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Non-wildcard behavior\n\t\t\tresult.PreResolve.Exact[path] = true\n\t\t\tif resolver.IsPackagePath(path) {\n\t\t\t\tresult.PreResolve.Patterns = append(result.PreResolve.Patterns, config.WildcardPattern{Prefix: path + \"/\"})\n\t\t\t} else if absPath := validatePath(log, fs, path, \"external path\"); absPath != \"\" {\n\t\t\t\tresult.PostResolve.Exact[absPath] = true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result\n}\n\nfunc validateAlias(log logger.Log, fs fs.FS, alias map[string]string) map[string]string {\n\tvalid := make(map[string]string, len(alias))\n\n\tfor old, new := range alias {\n\t\tif new == \"\" {\n\t\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\"Invalid alias substitution: %q\", new))\n\t\t\tcontinue\n\t\t}\n\n\t\t// Valid alias names:\n\t\t//   \"foo\"\n\t\t//   \"foo/bar\"\n\t\t//   \"@foo\"\n\t\t//   \"@foo/bar\"\n\t\t//   \"@foo/bar/baz\"\n\t\t//\n\t\t// Invalid alias names:\n\t\t//   \"./foo\"\n\t\t//   \"../foo\"\n\t\t//   \"/foo\"\n\t\t//   \"C:\\\\foo\"\n\t\t//   \".foo\"\n\t\t//   \"foo/\"\n\t\t//   \"@foo/\"\n\t\t//   \"foo/../bar\"\n\t\t//\n\t\tif !strings.HasPrefix(old, \".\") && !strings.HasPrefix(old, \"/\") && !fs.IsAbs(old) && path.Clean(strings.ReplaceAll(old, \"\\\\\", \"/\")) == old {\n\t\t\tvalid[old] = new\n\t\t\tcontinue\n\t\t}\n\n\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\"Invalid alias name: %q\", old))\n\t}\n\n\treturn valid\n}\n\nfunc isValidExtension(ext string) bool {\n\treturn len(ext) >= 2 && ext[0] == '.' && ext[len(ext)-1] != '.'\n}\n\nfunc validateResolveExtensions(log logger.Log, order []string) []string {\n\tif order == nil {\n\t\treturn []string{\".tsx\", \".ts\", \".jsx\", \".js\", \".css\", \".json\"}\n\t}\n\tfor _, ext := range order {\n\t\tif !isValidExtension(ext) {\n\t\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\"Invalid file extension: %q\", ext))\n\t\t}\n\t}\n\treturn order\n}\n\nfunc validateLoaders(log logger.Log, loaders map[string]Loader) map[string]config.Loader {\n\tresult := bundler.DefaultExtensionToLoaderMap()\n\tfor ext, loader := range loaders {\n\t\tif ext != \"\" && !isValidExtension(ext) {\n\t\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\"Invalid file extension: %q\", ext))\n\t\t}\n\t\tresult[ext] = validateLoader(loader)\n\t}\n\treturn result\n}\n\nfunc validateJSXExpr(log logger.Log, text string, name string) config.DefineExpr {\n\tif text != \"\" {\n\t\tif expr, _ := js_parser.ParseDefineExpr(text); len(expr.Parts) > 0 || (name == \"fragment\" && expr.Constant != nil) {\n\t\t\treturn expr\n\t\t}\n\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\"Invalid JSX %s: %q\", name, text))\n\t}\n\treturn config.DefineExpr{}\n}\n\n// This returns an arbitrary but unique key for each unique array of strings\nfunc mapKeyForDefine(parts []string) string {\n\tvar sb strings.Builder\n\tvar n [4]byte\n\tfor _, part := range parts {\n\t\tbinary.LittleEndian.PutUint32(n[:], uint32(len(part)))\n\t\tsb.Write(n[:])\n\t\tsb.WriteString(part)\n\t}\n\treturn sb.String()\n}\n\nfunc validateDefines(\n\tlog logger.Log,\n\tdefines map[string]string,\n\tpureFns []string,\n\tplatform config.Platform,\n\tisBuildAPI bool,\n\tminify bool,\n\tdrop Drop,\n) (*config.ProcessedDefines, []config.InjectedDefine) {\n\t// Sort injected defines for determinism, since the imports will be injected\n\t// into every file in the order that we return them from this function\n\tsortedKeys := make([]string, 0, len(defines))\n\tfor key := range defines {\n\t\tsortedKeys = append(sortedKeys, key)\n\t}\n\tsort.Strings(sortedKeys)\n\n\trawDefines := make(map[string]config.DefineData)\n\tnodeEnvParts := []string{\"process\", \"env\", \"NODE_ENV\"}\n\tnodeEnvMapKey := mapKeyForDefine(nodeEnvParts)\n\tvar injectedDefines []config.InjectedDefine\n\n\tfor _, key := range sortedKeys {\n\t\tvalue := defines[key]\n\t\tkeyParts := validateGlobalName(log, key, \"(define name)\")\n\t\tif keyParts == nil {\n\t\t\tcontinue\n\t\t}\n\t\tmapKey := mapKeyForDefine(keyParts)\n\n\t\t// Parse the value\n\t\tdefineExpr, injectExpr := js_parser.ParseDefineExpr(value)\n\n\t\t// Define simple expressions\n\t\tif defineExpr.Constant != nil || len(defineExpr.Parts) > 0 {\n\t\t\trawDefines[mapKey] = config.DefineData{KeyParts: keyParts, DefineExpr: &defineExpr}\n\n\t\t\t// Try to be helpful for common mistakes\n\t\t\tif len(defineExpr.Parts) == 1 && mapKey == nodeEnvMapKey {\n\t\t\t\tdata := logger.MsgData{\n\t\t\t\t\tText: fmt.Sprintf(\"%q is defined as an identifier instead of a string (surround %q with quotes to get a string)\", key, value),\n\t\t\t\t}\n\t\t\t\tpart := defineExpr.Parts[0]\n\n\t\t\t\tswitch logger.API {\n\t\t\t\tcase logger.CLIAPI:\n\t\t\t\t\tdata.Location = &logger.MsgLocation{\n\t\t\t\t\t\tFile:       logger.PrettyPaths{Abs: \"<cli>\", Rel: \"<cli>\"},\n\t\t\t\t\t\tLine:       1,\n\t\t\t\t\t\tColumn:     30,\n\t\t\t\t\t\tLength:     len(part),\n\t\t\t\t\t\tLineText:   fmt.Sprintf(\"--define:process.env.NODE_ENV=%s\", part),\n\t\t\t\t\t\tSuggestion: fmt.Sprintf(\"\\\\\\\"%s\\\\\\\"\", part),\n\t\t\t\t\t}\n\n\t\t\t\tcase logger.JSAPI:\n\t\t\t\t\tdata.Location = &logger.MsgLocation{\n\t\t\t\t\t\tFile:       logger.PrettyPaths{Abs: \"<js>\", Rel: \"<js>\"},\n\t\t\t\t\t\tLine:       1,\n\t\t\t\t\t\tColumn:     34,\n\t\t\t\t\t\tLength:     len(part) + 2,\n\t\t\t\t\t\tLineText:   fmt.Sprintf(\"define: { 'process.env.NODE_ENV': '%s' }\", part),\n\t\t\t\t\t\tSuggestion: fmt.Sprintf(\"'\\\"%s\\\"'\", part),\n\t\t\t\t\t}\n\n\t\t\t\tcase logger.GoAPI:\n\t\t\t\t\tdata.Location = &logger.MsgLocation{\n\t\t\t\t\t\tFile:       logger.PrettyPaths{Abs: \"<go>\", Rel: \"<go>\"},\n\t\t\t\t\t\tLine:       1,\n\t\t\t\t\t\tColumn:     50,\n\t\t\t\t\t\tLength:     len(part) + 2,\n\t\t\t\t\t\tLineText:   fmt.Sprintf(\"Define: map[string]string{\\\"process.env.NODE_ENV\\\": \\\"%s\\\"}\", part),\n\t\t\t\t\t\tSuggestion: fmt.Sprintf(\"\\\"\\\\\\\"%s\\\\\\\"\\\"\", part),\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlog.AddMsgID(logger.MsgID_JS_SuspiciousDefine, logger.Msg{\n\t\t\t\t\tKind: logger.Warning,\n\t\t\t\t\tData: data,\n\t\t\t\t})\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Inject complex expressions\n\t\tif injectExpr != nil {\n\t\t\tindex := ast.MakeIndex32(uint32(len(injectedDefines)))\n\t\t\tinjectedDefines = append(injectedDefines, config.InjectedDefine{\n\t\t\t\tSource: logger.Source{Contents: value},\n\t\t\t\tData:   injectExpr,\n\t\t\t\tName:   key,\n\t\t\t})\n\t\t\trawDefines[mapKey] = config.DefineData{KeyParts: keyParts, DefineExpr: &config.DefineExpr{InjectedDefineIndex: index}}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Anything else is unsupported\n\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\"Invalid define value (must be an entity name or JS literal): %s\", value))\n\t}\n\n\t// If we're bundling for the browser, add a special-cased define for\n\t// \"process.env.NODE_ENV\" that is \"development\" when not minifying and\n\t// \"production\" when minifying. This is a convention from the React world\n\t// that must be handled to avoid all React code crashing instantly. This\n\t// is only done if it's not already defined so that you can override it if\n\t// necessary.\n\tif isBuildAPI && platform == config.PlatformBrowser {\n\t\tif _, process := rawDefines[mapKeyForDefine([]string{\"process\"})]; !process {\n\t\t\tif _, processEnv := rawDefines[mapKeyForDefine([]string{\"process.env\"})]; !processEnv {\n\t\t\t\tif _, processEnvNodeEnv := rawDefines[nodeEnvMapKey]; !processEnvNodeEnv {\n\t\t\t\t\tvar value []uint16\n\t\t\t\t\tif minify {\n\t\t\t\t\t\tvalue = helpers.StringToUTF16(\"production\")\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvalue = helpers.StringToUTF16(\"development\")\n\t\t\t\t\t}\n\t\t\t\t\trawDefines[nodeEnvMapKey] = config.DefineData{KeyParts: nodeEnvParts, DefineExpr: &config.DefineExpr{Constant: &js_ast.EString{Value: value}}}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// If we're dropping all console API calls, replace each one with undefined\n\tif (drop & DropConsole) != 0 {\n\t\tconsoleParts := []string{\"console\"}\n\t\tconsoleMapKey := mapKeyForDefine(consoleParts)\n\t\tdefine := rawDefines[consoleMapKey]\n\t\tdefine.KeyParts = consoleParts\n\t\tdefine.Flags |= config.MethodCallsMustBeReplacedWithUndefined\n\t\trawDefines[consoleMapKey] = define\n\t}\n\n\tfor _, key := range pureFns {\n\t\tkeyParts := validateGlobalName(log, key, \"(pure name)\")\n\t\tif keyParts == nil {\n\t\t\tcontinue\n\t\t}\n\t\tmapKey := mapKeyForDefine(keyParts)\n\n\t\t// Merge with any previously-specified defines\n\t\tdefine := rawDefines[mapKey]\n\t\tdefine.KeyParts = keyParts\n\t\tdefine.Flags |= config.CallCanBeUnwrappedIfUnused\n\t\trawDefines[mapKey] = define\n\t}\n\n\t// Processing defines is expensive. Process them once here so the same object\n\t// can be shared between all parsers we create using these arguments.\n\tdefinesArray := make([]config.DefineData, 0, len(rawDefines))\n\tfor _, define := range rawDefines {\n\t\tdefinesArray = append(definesArray, define)\n\t}\n\tprocessed := config.ProcessDefines(definesArray)\n\treturn &processed, injectedDefines\n}\n\nfunc validateLogOverrides(input map[string]LogLevel) (output map[logger.MsgID]logger.LogLevel) {\n\toutput = make(map[uint8]logger.LogLevel)\n\tfor k, v := range input {\n\t\tlogger.StringToMsgIDs(k, validateLogLevel(v), output)\n\t}\n\treturn\n}\n\nfunc validatePath(log logger.Log, fs fs.FS, relPath string, pathKind string) string {\n\tif relPath == \"\" {\n\t\treturn \"\"\n\t}\n\tabsPath, ok := fs.Abs(relPath)\n\tif !ok {\n\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\"Invalid %s: %s\", pathKind, relPath))\n\t}\n\treturn absPath\n}\n\nfunc validateOutputExtensions(log logger.Log, outExtensions map[string]string) (js string, css string) {\n\tfor key, value := range outExtensions {\n\t\tif !isValidExtension(value) {\n\t\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\"Invalid output extension: %q\", value))\n\t\t}\n\t\tswitch key {\n\t\tcase \".js\":\n\t\t\tjs = value\n\t\tcase \".css\":\n\t\t\tcss = value\n\t\tdefault:\n\t\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\"Invalid output extension: %q (valid: .css, .js)\", key))\n\t\t}\n\t}\n\treturn\n}\n\nfunc validateBannerOrFooter(log logger.Log, name string, values map[string]string) (js string, css string) {\n\tfor key, value := range values {\n\t\tswitch key {\n\t\tcase \"js\":\n\t\t\tjs = value\n\t\tcase \"css\":\n\t\t\tcss = value\n\t\tdefault:\n\t\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\"Invalid %s file type: %q (valid: css, js)\", name, key))\n\t\t}\n\t}\n\treturn\n}\n\nfunc validateKeepNames(log logger.Log, options *config.Options) {\n\tif options.KeepNames && options.UnsupportedJSFeatures.Has(compat.FunctionNameConfigurable) {\n\t\twhere := config.PrettyPrintTargetEnvironment(options.OriginalTargetEnv, options.UnsupportedJSFeatureOverridesMask)\n\t\tlog.AddErrorWithNotes(nil, logger.Range{}, fmt.Sprintf(\"The \\\"keep names\\\" setting cannot be used with %s\", where), []logger.MsgData{{\n\t\t\tText: \"In this environment, the \\\"Function.prototype.name\\\" property is not configurable and assigning to it will throw an error. \" +\n\t\t\t\t\"Either use a newer target environment or disable the \\\"keep names\\\" setting.\"}})\n\t}\n}\n\nfunc convertLocationToPublic(loc *logger.MsgLocation, pathStyle logger.PathStyle) *Location {\n\tif loc != nil {\n\t\treturn &Location{\n\t\t\tFile:       loc.File.Select(pathStyle),\n\t\t\tNamespace:  loc.Namespace,\n\t\t\tLine:       loc.Line,\n\t\t\tColumn:     loc.Column,\n\t\t\tLength:     loc.Length,\n\t\t\tLineText:   loc.LineText,\n\t\t\tSuggestion: loc.Suggestion,\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc convertMessagesToPublic(kind logger.MsgKind, msgs []logger.Msg, pathStyle logger.PathStyle) []Message {\n\tvar filtered []Message\n\tfor _, msg := range msgs {\n\t\tif msg.Kind == kind {\n\t\t\tvar notes []Note\n\t\t\tfor _, note := range msg.Notes {\n\t\t\t\tnotes = append(notes, Note{\n\t\t\t\t\tText:     note.Text,\n\t\t\t\t\tLocation: convertLocationToPublic(note.Location, pathStyle),\n\t\t\t\t})\n\t\t\t}\n\t\t\tfiltered = append(filtered, Message{\n\t\t\t\tID:         logger.MsgIDToString(msg.ID),\n\t\t\t\tPluginName: msg.PluginName,\n\t\t\t\tText:       msg.Data.Text,\n\t\t\t\tLocation:   convertLocationToPublic(msg.Data.Location, pathStyle),\n\t\t\t\tNotes:      notes,\n\t\t\t\tDetail:     msg.Data.UserDetail,\n\t\t\t})\n\t\t}\n\t}\n\treturn filtered\n}\n\nfunc convertLocationToInternal(loc *Location) *logger.MsgLocation {\n\tif loc != nil {\n\t\tnamespace := loc.Namespace\n\t\tif namespace == \"\" {\n\t\t\tnamespace = \"file\"\n\t\t}\n\t\treturn &logger.MsgLocation{\n\t\t\tFile:       logger.PrettyPaths{Abs: loc.File, Rel: loc.File},\n\t\t\tNamespace:  namespace,\n\t\t\tLine:       loc.Line,\n\t\t\tColumn:     loc.Column,\n\t\t\tLength:     loc.Length,\n\t\t\tLineText:   loc.LineText,\n\t\t\tSuggestion: loc.Suggestion,\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc convertMessagesToInternal(msgs []logger.Msg, kind logger.MsgKind, messages []Message) []logger.Msg {\n\tfor _, message := range messages {\n\t\tvar notes []logger.MsgData\n\t\tfor _, note := range message.Notes {\n\t\t\tnotes = append(notes, logger.MsgData{\n\t\t\t\tText:     note.Text,\n\t\t\t\tLocation: convertLocationToInternal(note.Location),\n\t\t\t})\n\t\t}\n\t\tmsgs = append(msgs, logger.Msg{\n\t\t\tID:         logger.StringToMaximumMsgID(message.ID),\n\t\t\tPluginName: message.PluginName,\n\t\t\tKind:       kind,\n\t\t\tData: logger.MsgData{\n\t\t\t\tText:       message.Text,\n\t\t\t\tLocation:   convertLocationToInternal(message.Location),\n\t\t\t\tUserDetail: message.Detail,\n\t\t\t},\n\t\t\tNotes: notes,\n\t\t})\n\t}\n\treturn msgs\n}\n\nfunc convertErrorsAndWarningsToInternal(errors []Message, warnings []Message) []logger.Msg {\n\tif len(errors)+len(warnings) > 0 {\n\t\tmsgs := make(logger.SortableMsgs, 0, len(errors)+len(warnings))\n\t\tmsgs = convertMessagesToInternal(msgs, logger.Error, errors)\n\t\tmsgs = convertMessagesToInternal(msgs, logger.Warning, warnings)\n\t\tsort.Stable(msgs)\n\t\treturn msgs\n\t}\n\treturn nil\n}\n\nfunc cloneMangleCache(log logger.Log, mangleCache map[string]interface{}) map[string]interface{} {\n\tif mangleCache == nil {\n\t\treturn nil\n\t}\n\tclone := make(map[string]interface{}, len(mangleCache))\n\tfor k, v := range mangleCache {\n\t\tif v == \"__proto__\" {\n\t\t\t// This could cause problems for our binary serialization protocol. It's\n\t\t\t// also unnecessary because we already avoid mangling this property name.\n\t\t\tlog.AddError(nil, logger.Range{},\n\t\t\t\tfmt.Sprintf(\"Invalid identifier name %q in mangle cache\", k))\n\t\t} else if _, ok := v.(string); ok || v == false {\n\t\t\tclone[k] = v\n\t\t} else {\n\t\t\tlog.AddError(nil, logger.Range{},\n\t\t\t\tfmt.Sprintf(\"Expected %q in mangle cache to map to either a string or false\", k))\n\t\t}\n\t}\n\treturn clone\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Build API\n\nfunc contextImpl(buildOpts BuildOptions) (*internalContext, []Message) {\n\tlogOptions := logger.OutputOptions{\n\t\tIncludeSource: true,\n\t\tMessageLimit:  buildOpts.LogLimit,\n\t\tColor:         validateColor(buildOpts.Color),\n\t\tLogLevel:      validateLogLevel(buildOpts.LogLevel),\n\t\tPathStyle:     extractPathStyle(buildOpts.AbsPaths, LogAbsPath),\n\t\tOverrides:     validateLogOverrides(buildOpts.LogOverride),\n\t}\n\n\t// Validate that the current working directory is an absolute path\n\tabsWorkingDir := buildOpts.AbsWorkingDir\n\trealFS, err := fs.RealFS(fs.RealFSOptions{\n\t\tAbsWorkingDir: absWorkingDir,\n\n\t\t// This is a long-lived file system object so do not cache calls to\n\t\t// ReadDirectory() (they are normally cached for the duration of a build\n\t\t// for performance).\n\t\tDoNotCache: true,\n\t})\n\tif err != nil {\n\t\tlog := logger.NewStderrLog(logOptions)\n\t\tlog.AddError(nil, logger.Range{}, err.Error())\n\t\treturn nil, convertMessagesToPublic(logger.Error, log.Done(), logOptions.PathStyle)\n\t}\n\n\t// Do not re-evaluate plugins when rebuilding. Also make sure the working\n\t// directory doesn't change, since breaking that invariant would break the\n\t// validation that we just did above.\n\tcaches := cache.MakeCacheSet()\n\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, logOptions.Overrides)\n\tonEndCallbacks, onDisposeCallbacks, finalizeBuildOptions := loadPlugins(&buildOpts, realFS, log, caches)\n\toptions, entryPoints := validateBuildOptions(buildOpts, log, realFS)\n\tfinalizeBuildOptions(&options)\n\tif buildOpts.AbsWorkingDir != absWorkingDir {\n\t\tpanic(\"Mutating \\\"AbsWorkingDir\\\" is not allowed\")\n\t}\n\n\t// If we have errors already, then refuse to build any further. This only\n\t// happens when the build options themselves contain validation errors.\n\tmsgs := log.Done()\n\tif log.HasErrors() {\n\t\tif logOptions.LogLevel < logger.LevelSilent {\n\t\t\t// Print all deferred validation log messages to stderr. We defer all log\n\t\t\t// messages that are generated above because warnings are re-printed for\n\t\t\t// every rebuild and we don't want to double-print these warnings for the\n\t\t\t// first build.\n\t\t\tstderr := logger.NewStderrLog(logOptions)\n\t\t\tfor _, msg := range msgs {\n\t\t\t\tstderr.AddMsg(msg)\n\t\t\t}\n\t\t\tstderr.Done()\n\t\t}\n\t\treturn nil, convertMessagesToPublic(logger.Error, msgs, options.LogPathStyle)\n\t}\n\n\targs := rebuildArgs{\n\t\tcaches:             caches,\n\t\tonEndCallbacks:     onEndCallbacks,\n\t\tonDisposeCallbacks: onDisposeCallbacks,\n\t\tlogOptions:         logOptions,\n\t\tlogWarnings:        msgs,\n\t\tentryPoints:        entryPoints,\n\t\toptions:            options,\n\t\tmangleCache:        buildOpts.MangleCache,\n\t\tabsWorkingDir:      absWorkingDir,\n\t\twrite:              buildOpts.Write,\n\t}\n\n\treturn &internalContext{\n\t\targs:          args,\n\t\trealFS:        realFS,\n\t\tabsWorkingDir: absWorkingDir,\n\t}, nil\n}\n\ntype buildInProgress struct {\n\tstate     rebuildState\n\twaitGroup sync.WaitGroup\n\tcancel    config.CancelFlag\n}\n\ntype internalContext struct {\n\tmutex         sync.Mutex\n\targs          rebuildArgs\n\tactiveBuild   *buildInProgress\n\trecentBuild   *BuildResult\n\trealFS        fs.FS\n\tabsWorkingDir string\n\twatcher       *watcher\n\thandler       *apiHandler\n\tdidDispose    bool\n\n\t// This saves just enough information to be able to compute a useful diff\n\t// between two sets of output files. That way we don't need to hold both\n\t// sets of output files in memory at once to compute a diff.\n\tlatestHashes map[string]string\n}\n\nfunc (ctx *internalContext) rebuild() rebuildState {\n\tctx.mutex.Lock()\n\n\t// Ignore disposed contexts\n\tif ctx.didDispose {\n\t\tctx.mutex.Unlock()\n\t\treturn rebuildState{}\n\t}\n\n\t// If there's already an active build, just return that build's result\n\tif build := ctx.activeBuild; build != nil {\n\t\tctx.mutex.Unlock()\n\t\tbuild.waitGroup.Wait()\n\t\treturn build.state\n\t}\n\n\t// Otherwise, start a new build\n\tbuild := &buildInProgress{}\n\tbuild.waitGroup.Add(1)\n\tctx.activeBuild = build\n\targs := ctx.args\n\twatcher := ctx.watcher\n\thandler := ctx.handler\n\toldHashes := ctx.latestHashes\n\targs.options.CancelFlag = &build.cancel\n\tctx.mutex.Unlock()\n\n\t// Do the build without holding the mutex\n\tvar newHashes map[string]string\n\tbuild.state, newHashes = rebuildImpl(args, oldHashes)\n\tif handler != nil {\n\t\thandler.broadcastBuildResult(build.state.result, newHashes)\n\t}\n\tif watcher != nil {\n\t\twatcher.setWatchData(build.state.watchData)\n\t}\n\n\t// Store the recent build for the dev server\n\trecentBuild := &build.state.result\n\tctx.mutex.Lock()\n\tctx.activeBuild = nil\n\tctx.recentBuild = recentBuild\n\tctx.latestHashes = newHashes\n\tctx.mutex.Unlock()\n\n\t// Clear the recent build after it goes stale\n\tgo func() {\n\t\ttime.Sleep(250 * time.Millisecond)\n\t\tctx.mutex.Lock()\n\t\tif ctx.recentBuild == recentBuild {\n\t\t\tctx.recentBuild = nil\n\t\t}\n\t\tctx.mutex.Unlock()\n\t}()\n\n\tbuild.waitGroup.Done()\n\treturn build.state\n}\n\n// This is used by the dev server. The dev server does a rebuild on each\n// incoming request since a) we want incoming requests to always be up to\n// date and b) we don't necessarily know what output paths to even serve\n// without running another build (e.g. the hashes may have changed).\n//\n// However, there is a small period of time where we reuse old build results\n// instead of generating new ones. This is because page loads likely involve\n// multiple requests, and don't want to rebuild separately for each of those\n// requests.\nfunc (ctx *internalContext) activeBuildOrRecentBuildOrRebuild() BuildResult {\n\tctx.mutex.Lock()\n\n\t// If there's already an active build, wait for it and return that\n\tif build := ctx.activeBuild; build != nil {\n\t\tctx.mutex.Unlock()\n\t\tbuild.waitGroup.Wait()\n\t\treturn build.state.result\n\t}\n\n\t// Then try to return a recentl already-completed build\n\tif build := ctx.recentBuild; build != nil {\n\t\tctx.mutex.Unlock()\n\t\treturn *build\n\t}\n\n\t// Otherwise, fall back to rebuilding\n\tctx.mutex.Unlock()\n\treturn ctx.Rebuild()\n}\n\nfunc (ctx *internalContext) Rebuild() BuildResult {\n\treturn ctx.rebuild().result\n}\n\nfunc (ctx *internalContext) Watch(options WatchOptions) error {\n\tctx.mutex.Lock()\n\tdefer ctx.mutex.Unlock()\n\n\t// Ignore disposed contexts\n\tif ctx.didDispose {\n\t\treturn errors.New(\"Cannot watch a disposed context\")\n\t}\n\n\t// Don't allow starting watch mode multiple times\n\tif ctx.watcher != nil {\n\t\treturn errors.New(\"Watch mode has already been enabled\")\n\t}\n\n\tlogLevel := ctx.args.logOptions.LogLevel\n\tctx.watcher = &watcher{\n\t\tfs:        ctx.realFS,\n\t\tshouldLog: logLevel == logger.LevelInfo || logLevel == logger.LevelDebug || logLevel == logger.LevelVerbose,\n\t\tuseColor:  ctx.args.logOptions.Color,\n\t\tpathStyle: ctx.args.logOptions.PathStyle,\n\t\trebuild: func() fs.WatchData {\n\t\t\treturn ctx.rebuild().watchData\n\t\t},\n\t\tdelayInMS: time.Duration(options.Delay),\n\t}\n\n\t// All subsequent builds will be watch mode builds\n\tctx.args.options.WatchMode = true\n\n\t// Start the file watcher goroutine\n\tctx.watcher.start()\n\n\t// Do the first watch mode build on another goroutine\n\tgo func() {\n\t\tctx.mutex.Lock()\n\t\tbuild := ctx.activeBuild\n\t\tctx.mutex.Unlock()\n\n\t\t// If there's an active build, then it's not a watch build. Wait for it to\n\t\t// finish first so we don't just get this build when we call \"Rebuild()\".\n\t\tif build != nil {\n\t\t\tbuild.waitGroup.Wait()\n\t\t}\n\n\t\t// Trigger a rebuild now that we know all future builds will pick up on\n\t\t// our watcher. This build will populate the initial watch data, which is\n\t\t// necessary to be able to know what file system changes are relevant.\n\t\tctx.Rebuild()\n\t}()\n\treturn nil\n}\n\nfunc (ctx *internalContext) Cancel() {\n\tctx.mutex.Lock()\n\n\t// Ignore disposed contexts\n\tif ctx.didDispose {\n\t\tctx.mutex.Unlock()\n\t\treturn\n\t}\n\n\tbuild := ctx.activeBuild\n\tctx.mutex.Unlock()\n\n\tif build != nil {\n\t\t// Tell observers to cut this build short\n\t\tbuild.cancel.Cancel()\n\n\t\t// Wait for the build to finish before returning\n\t\tbuild.waitGroup.Wait()\n\t}\n}\n\nfunc (ctx *internalContext) Dispose() {\n\t// Only dispose once\n\tctx.mutex.Lock()\n\tif ctx.didDispose {\n\t\tctx.mutex.Unlock()\n\t\treturn\n\t}\n\tctx.didDispose = true\n\tctx.recentBuild = nil\n\tbuild := ctx.activeBuild\n\tctx.mutex.Unlock()\n\n\tif ctx.watcher != nil {\n\t\tctx.watcher.stop()\n\t}\n\tif ctx.handler != nil {\n\t\tctx.handler.stop()\n\t}\n\n\t// It's important to wait for the build to finish before returning. The JS\n\t// API will unregister its callbacks when it returns. If that happens while\n\t// the build is still in progress, that might cause the JS API to generate\n\t// errors when we send it events (e.g. when it runs \"onEnd\" callbacks) that\n\t// we then print to the terminal, which would be confusing.\n\tif build != nil {\n\t\tbuild.waitGroup.Wait()\n\t}\n\n\t// Run each \"OnDispose\" callback on its own goroutine\n\tfor _, fn := range ctx.args.onDisposeCallbacks {\n\t\tgo fn()\n\t}\n}\n\nfunc prettyPrintByteCount(n int) string {\n\tvar size string\n\tif n < 1024 {\n\t\tsize = fmt.Sprintf(\"%db \", n)\n\t} else if n < 1024*1024 {\n\t\tsize = fmt.Sprintf(\"%.1fkb\", float64(n)/(1024))\n\t} else if n < 1024*1024*1024 {\n\t\tsize = fmt.Sprintf(\"%.1fmb\", float64(n)/(1024*1024))\n\t} else {\n\t\tsize = fmt.Sprintf(\"%.1fgb\", float64(n)/(1024*1024*1024))\n\t}\n\treturn size\n}\n\nfunc printSummary(color logger.UseColor, outputFiles []OutputFile, start time.Time) {\n\tif len(outputFiles) == 0 {\n\t\treturn\n\t}\n\n\tvar table logger.SummaryTable = make([]logger.SummaryTableEntry, len(outputFiles))\n\n\tif cwd, err := os.Getwd(); err == nil {\n\t\tif realFS, err := fs.RealFS(fs.RealFSOptions{AbsWorkingDir: cwd}); err == nil {\n\t\t\tfor i, file := range outputFiles {\n\t\t\t\tpath, ok := realFS.Rel(realFS.Cwd(), file.Path)\n\t\t\t\tif !ok {\n\t\t\t\t\tpath = file.Path\n\t\t\t\t}\n\t\t\t\tbase := realFS.Base(path)\n\t\t\t\tn := len(file.Contents)\n\t\t\t\ttable[i] = logger.SummaryTableEntry{\n\t\t\t\t\tDir:         path[:len(path)-len(base)],\n\t\t\t\t\tBase:        base,\n\t\t\t\t\tSize:        prettyPrintByteCount(n),\n\t\t\t\t\tBytes:       n,\n\t\t\t\t\tIsSourceMap: strings.HasSuffix(base, \".map\"),\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Don't print the time taken by the build if we're running under Yarn 1\n\t// since Yarn 1 always prints its own copy of the time taken by each command\n\tif userAgent, ok := os.LookupEnv(\"npm_config_user_agent\"); ok {\n\t\tif strings.Contains(userAgent, \"yarn/1.\") {\n\t\t\tlogger.PrintSummary(color, table, nil)\n\t\t\treturn\n\t\t}\n\t}\n\n\tlogger.PrintSummary(color, table, &start)\n}\n\nfunc validateBuildOptions(\n\tbuildOpts BuildOptions,\n\tlog logger.Log,\n\trealFS fs.FS,\n) (\n\toptions config.Options,\n\tentryPoints []bundler.EntryPoint,\n) {\n\tjsFeatures, cssFeatures, cssPrefixData, targetEnv := validateFeatures(log, buildOpts.Target, buildOpts.Engines)\n\tjsOverrides, jsMask, cssOverrides, cssMask := validateSupported(log, buildOpts.Supported)\n\toutJS, outCSS := validateOutputExtensions(log, buildOpts.OutExtension)\n\tbannerJS, bannerCSS := validateBannerOrFooter(log, \"banner\", buildOpts.Banner)\n\tfooterJS, footerCSS := validateBannerOrFooter(log, \"footer\", buildOpts.Footer)\n\tminify := buildOpts.MinifyWhitespace && buildOpts.MinifyIdentifiers && buildOpts.MinifySyntax\n\tplatform := validatePlatform(buildOpts.Platform)\n\tdefines, injectedDefines := validateDefines(log, buildOpts.Define, buildOpts.Pure, platform, true /* isBuildAPI */, minify, buildOpts.Drop)\n\toptions = config.Options{\n\t\tCSSPrefixData:                      cssPrefixData,\n\t\tUnsupportedJSFeatures:              jsFeatures.ApplyOverrides(jsOverrides, jsMask),\n\t\tUnsupportedCSSFeatures:             cssFeatures.ApplyOverrides(cssOverrides, cssMask),\n\t\tUnsupportedJSFeatureOverrides:      jsOverrides,\n\t\tUnsupportedJSFeatureOverridesMask:  jsMask,\n\t\tUnsupportedCSSFeatureOverrides:     cssOverrides,\n\t\tUnsupportedCSSFeatureOverridesMask: cssMask,\n\t\tOriginalTargetEnv:                  targetEnv,\n\t\tJSX: config.JSXOptions{\n\t\t\tPreserve:         buildOpts.JSX == JSXPreserve,\n\t\t\tAutomaticRuntime: buildOpts.JSX == JSXAutomatic,\n\t\t\tFactory:          validateJSXExpr(log, buildOpts.JSXFactory, \"factory\"),\n\t\t\tFragment:         validateJSXExpr(log, buildOpts.JSXFragment, \"fragment\"),\n\t\t\tDevelopment:      buildOpts.JSXDev,\n\t\t\tImportSource:     buildOpts.JSXImportSource,\n\t\t\tSideEffects:      buildOpts.JSXSideEffects,\n\t\t},\n\t\tDefines:               defines,\n\t\tInjectedDefines:       injectedDefines,\n\t\tPlatform:              platform,\n\t\tSourceMap:             validateSourceMap(buildOpts.Sourcemap),\n\t\tLegalComments:         validateLegalComments(buildOpts.LegalComments, buildOpts.Bundle),\n\t\tSourceRoot:            buildOpts.SourceRoot,\n\t\tExcludeSourcesContent: buildOpts.SourcesContent == SourcesContentExclude,\n\t\tMinifySyntax:          buildOpts.MinifySyntax,\n\t\tMinifyWhitespace:      buildOpts.MinifyWhitespace,\n\t\tMinifyIdentifiers:     buildOpts.MinifyIdentifiers,\n\t\tLineLimit:             buildOpts.LineLimit,\n\t\tMangleProps:           validateRegex(log, \"mangle props\", buildOpts.MangleProps),\n\t\tReserveProps:          validateRegex(log, \"reserve props\", buildOpts.ReserveProps),\n\t\tMangleQuoted:          buildOpts.MangleQuoted == MangleQuotedTrue,\n\t\tDropLabels:            append([]string{}, buildOpts.DropLabels...),\n\t\tDropDebugger:          (buildOpts.Drop & DropDebugger) != 0,\n\t\tAllowOverwrite:        buildOpts.AllowOverwrite,\n\t\tASCIIOnly:             validateASCIIOnly(buildOpts.Charset),\n\t\tIgnoreDCEAnnotations:  buildOpts.IgnoreAnnotations,\n\t\tTreeShaking:           validateTreeShaking(buildOpts.TreeShaking, buildOpts.Bundle, buildOpts.Format),\n\t\tGlobalName:            validateGlobalName(log, buildOpts.GlobalName, \"(global name)\"),\n\t\tCodeSplitting:         buildOpts.Splitting,\n\t\tOutputFormat:          validateFormat(buildOpts.Format),\n\t\tAbsOutputFile:         validatePath(log, realFS, buildOpts.Outfile, \"outfile path\"),\n\t\tAbsOutputDir:          validatePath(log, realFS, buildOpts.Outdir, \"outdir path\"),\n\t\tAbsOutputBase:         validatePath(log, realFS, buildOpts.Outbase, \"outbase path\"),\n\t\tNeedsMetafile:         buildOpts.Metafile,\n\t\tEntryPathTemplate:     validatePathTemplate(buildOpts.EntryNames),\n\t\tChunkPathTemplate:     validatePathTemplate(buildOpts.ChunkNames),\n\t\tAssetPathTemplate:     validatePathTemplate(buildOpts.AssetNames),\n\t\tOutputExtensionJS:     outJS,\n\t\tOutputExtensionCSS:    outCSS,\n\t\tExtensionToLoader:     validateLoaders(log, buildOpts.Loader),\n\t\tExtensionOrder:        validateResolveExtensions(log, buildOpts.ResolveExtensions),\n\t\tExternalSettings:      validateExternals(log, realFS, buildOpts.External),\n\t\tExternalPackages:      validateExternalPackages(buildOpts.Packages),\n\t\tPackageAliases:        validateAlias(log, realFS, buildOpts.Alias),\n\t\tTSConfigPath:          validatePath(log, realFS, buildOpts.Tsconfig, \"tsconfig path\"),\n\t\tTSConfigRaw:           buildOpts.TsconfigRaw,\n\t\tMainFields:            buildOpts.MainFields,\n\t\tPublicPath:            buildOpts.PublicPath,\n\t\tKeepNames:             buildOpts.KeepNames,\n\t\tCodePathStyle:         extractPathStyle(buildOpts.AbsPaths, CodeAbsPath),\n\t\tLogPathStyle:          extractPathStyle(buildOpts.AbsPaths, LogAbsPath),\n\t\tMetafilePathStyle:     extractPathStyle(buildOpts.AbsPaths, MetafileAbsPath),\n\t\tInjectPaths:           append([]string{}, buildOpts.Inject...),\n\t\tAbsNodePaths:          make([]string, len(buildOpts.NodePaths)),\n\t\tJSBanner:              bannerJS,\n\t\tJSFooter:              footerJS,\n\t\tCSSBanner:             bannerCSS,\n\t\tCSSFooter:             footerCSS,\n\t\tPreserveSymlinks:      buildOpts.PreserveSymlinks,\n\t}\n\tvalidateKeepNames(log, &options)\n\tif buildOpts.Conditions != nil {\n\t\toptions.Conditions = append([]string{}, buildOpts.Conditions...)\n\t}\n\tif options.MainFields != nil {\n\t\toptions.MainFields = append([]string{}, options.MainFields...)\n\t}\n\tfor i, path := range buildOpts.NodePaths {\n\t\toptions.AbsNodePaths[i] = validatePath(log, realFS, path, \"node path\")\n\t}\n\tentryPoints = make([]bundler.EntryPoint, 0, len(buildOpts.EntryPoints)+len(buildOpts.EntryPointsAdvanced))\n\thasEntryPointWithWildcard := false\n\tfor _, ep := range buildOpts.EntryPoints {\n\t\tentryPoints = append(entryPoints, bundler.EntryPoint{InputPath: ep})\n\t\tif strings.ContainsRune(ep, '*') {\n\t\t\thasEntryPointWithWildcard = true\n\t\t}\n\t}\n\tfor _, ep := range buildOpts.EntryPointsAdvanced {\n\t\tentryPoints = append(entryPoints, bundler.EntryPoint{InputPath: ep.InputPath, OutputPath: ep.OutputPath})\n\t\tif strings.ContainsRune(ep.InputPath, '*') {\n\t\t\thasEntryPointWithWildcard = true\n\t\t}\n\t}\n\tentryPointCount := len(entryPoints)\n\tif buildOpts.Stdin != nil {\n\t\tentryPointCount++\n\t\toptions.Stdin = &config.StdinInfo{\n\t\t\tLoader:        validateLoader(buildOpts.Stdin.Loader),\n\t\t\tContents:      buildOpts.Stdin.Contents,\n\t\t\tSourceFile:    buildOpts.Stdin.Sourcefile,\n\t\t\tAbsResolveDir: validatePath(log, realFS, buildOpts.Stdin.ResolveDir, \"resolve directory path\"),\n\t\t}\n\t}\n\n\tif options.AbsOutputDir == \"\" && (entryPointCount > 1 || hasEntryPointWithWildcard) {\n\t\tlog.AddError(nil, logger.Range{},\n\t\t\t\"Must use \\\"outdir\\\" when there are multiple input files\")\n\t} else if options.AbsOutputDir == \"\" && options.CodeSplitting {\n\t\tlog.AddError(nil, logger.Range{},\n\t\t\t\"Must use \\\"outdir\\\" when code splitting is enabled\")\n\t} else if options.AbsOutputFile != \"\" && options.AbsOutputDir != \"\" {\n\t\tlog.AddError(nil, logger.Range{}, \"Cannot use both \\\"outfile\\\" and \\\"outdir\\\"\")\n\t} else if options.AbsOutputFile != \"\" {\n\t\t// If the output file is specified, use it to derive the output directory\n\t\toptions.AbsOutputDir = realFS.Dir(options.AbsOutputFile)\n\t} else if options.AbsOutputDir == \"\" {\n\t\toptions.WriteToStdout = true\n\n\t\t// Forbid certain features when writing to stdout\n\t\tif options.SourceMap != config.SourceMapNone && options.SourceMap != config.SourceMapInline {\n\t\t\tlog.AddError(nil, logger.Range{}, \"Cannot use an external source map without an output path\")\n\t\t}\n\t\tif options.LegalComments.HasExternalFile() {\n\t\t\tlog.AddError(nil, logger.Range{}, \"Cannot use linked or external legal comments without an output path\")\n\t\t}\n\t\tfor _, loader := range options.ExtensionToLoader {\n\t\t\tif loader == config.LoaderFile {\n\t\t\t\tlog.AddError(nil, logger.Range{}, \"Cannot use the \\\"file\\\" loader without an output path\")\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif loader == config.LoaderCopy {\n\t\t\t\tlog.AddError(nil, logger.Range{}, \"Cannot use the \\\"copy\\\" loader without an output path\")\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Use the current directory as the output directory instead of an empty\n\t\t// string because external modules with relative paths need a base directory.\n\t\toptions.AbsOutputDir = realFS.Cwd()\n\t}\n\n\tif !buildOpts.Bundle {\n\t\t// Disallow bundle-only options when not bundling\n\t\tif options.ExternalSettings.PreResolve.HasMatchers() || options.ExternalSettings.PostResolve.HasMatchers() {\n\t\t\tlog.AddError(nil, logger.Range{}, \"Cannot use \\\"external\\\" without \\\"bundle\\\"\")\n\t\t}\n\t\tif len(options.PackageAliases) > 0 {\n\t\t\tlog.AddError(nil, logger.Range{}, \"Cannot use \\\"alias\\\" without \\\"bundle\\\"\")\n\t\t}\n\t} else if options.OutputFormat == config.FormatPreserve {\n\t\t// If the format isn't specified, set the default format using the platform\n\t\tswitch options.Platform {\n\t\tcase config.PlatformBrowser:\n\t\t\toptions.OutputFormat = config.FormatIIFE\n\t\tcase config.PlatformNode:\n\t\t\toptions.OutputFormat = config.FormatCommonJS\n\t\tcase config.PlatformNeutral:\n\t\t\toptions.OutputFormat = config.FormatESModule\n\t\t}\n\t}\n\n\t// Set the output mode using other settings\n\tif buildOpts.Bundle {\n\t\toptions.Mode = config.ModeBundle\n\t} else if options.OutputFormat != config.FormatPreserve {\n\t\toptions.Mode = config.ModeConvertFormat\n\t}\n\n\t// Automatically enable the \"module\" condition for better tree shaking\n\tif options.Conditions == nil && options.Platform != config.PlatformNeutral {\n\t\toptions.Conditions = []string{\"module\"}\n\t}\n\n\t// Code splitting is experimental and currently only enabled for ES6 modules\n\tif options.CodeSplitting && options.OutputFormat != config.FormatESModule {\n\t\tlog.AddError(nil, logger.Range{}, \"Splitting currently only works with the \\\"esm\\\" format\")\n\t}\n\n\t// Code splitting is experimental and currently only enabled for ES6 modules\n\tif options.TSConfigPath != \"\" && options.TSConfigRaw != \"\" {\n\t\tlog.AddError(nil, logger.Range{}, \"Cannot provide \\\"tsconfig\\\" as both a raw string and a path\")\n\t}\n\n\t// If we aren't writing the output to the file system, then we can allow the\n\t// output paths to be the same as the input paths. This helps when serving.\n\tif !buildOpts.Write {\n\t\toptions.AllowOverwrite = true\n\t}\n\n\treturn\n}\n\ntype onEndCallback struct {\n\tpluginName string\n\tfn         func(*BuildResult) (OnEndResult, error)\n}\n\ntype rebuildArgs struct {\n\tcaches             *cache.CacheSet\n\tonEndCallbacks     []onEndCallback\n\tonDisposeCallbacks []func()\n\tlogOptions         logger.OutputOptions\n\tlogWarnings        []logger.Msg\n\tentryPoints        []bundler.EntryPoint\n\toptions            config.Options\n\tmangleCache        map[string]interface{}\n\tabsWorkingDir      string\n\twrite              bool\n}\n\ntype rebuildState struct {\n\tresult    BuildResult\n\twatchData fs.WatchData\n\toptions   config.Options\n}\n\nfunc rebuildImpl(args rebuildArgs, oldHashes map[string]string) (rebuildState, map[string]string) {\n\tlog := logger.NewStderrLog(args.logOptions)\n\n\t// All validation warnings are repeated for every rebuild\n\tfor _, msg := range args.logWarnings {\n\t\tlog.AddMsg(msg)\n\t}\n\n\t// Convert and validate the buildOpts\n\trealFS, err := fs.RealFS(fs.RealFSOptions{\n\t\tAbsWorkingDir: args.absWorkingDir,\n\t\tWantWatchData: args.options.WatchMode,\n\t})\n\tif err != nil {\n\t\t// This should already have been checked by the caller\n\t\tpanic(err.Error())\n\t}\n\n\tvar result BuildResult\n\tvar watchData fs.WatchData\n\tvar toWriteToStdout []byte\n\n\tvar timer *helpers.Timer\n\tif api_helpers.UseTimer {\n\t\ttimer = &helpers.Timer{}\n\t}\n\n\t// Scan over the bundle\n\tbundle := bundler.ScanBundle(config.BuildCall, log, realFS, args.caches, args.entryPoints, args.options, timer)\n\twatchData = realFS.WatchData()\n\n\t// The new build summary remains the same as the old one when there are\n\t// errors. A failed build shouldn't erase the previous successful build.\n\tnewHashes := oldHashes\n\n\t// Stop now if there were errors\n\tvar results []graph.OutputFile\n\tvar metafile string\n\tif !log.HasErrors() {\n\t\t// Compile the bundle\n\t\tresult.MangleCache = cloneMangleCache(log, args.mangleCache)\n\t\tresults, metafile = bundle.Compile(log, timer, result.MangleCache, linker.Link)\n\n\t\t// Canceling a build generates a single error at the end of the build\n\t\tif args.options.CancelFlag.DidCancel() {\n\t\t\tlog.AddError(nil, logger.Range{}, \"The build was canceled\")\n\t\t}\n\n\t\t// Stop now if there were errors\n\t\tif !log.HasErrors() {\n\t\t\tresult.Metafile = metafile\n\t\t}\n\t}\n\n\t// Populate the results to return\n\tvar hashBytes [8]byte\n\tresult.OutputFiles = make([]OutputFile, len(results))\n\tnewHashes = make(map[string]string)\n\tfor i, item := range results {\n\t\tif args.options.WriteToStdout {\n\t\t\titem.AbsPath = \"<stdout>\"\n\t\t}\n\t\thasher := xxhash.New()\n\t\thasher.Write(item.Contents)\n\t\tbinary.LittleEndian.PutUint64(hashBytes[:], hasher.Sum64())\n\t\thash := base64.RawStdEncoding.EncodeToString(hashBytes[:])\n\t\tresult.OutputFiles[i] = OutputFile{\n\t\t\tPath:     item.AbsPath,\n\t\t\tContents: item.Contents,\n\t\t\tHash:     hash,\n\t\t}\n\t\tnewHashes[item.AbsPath] = hash\n\t}\n\n\t// Write output files before \"OnEnd\" callbacks run so they can expect\n\t// output files to exist on the file system. \"OnEnd\" callbacks can be\n\t// used to move output files to a different location after the build.\n\tif args.write {\n\t\ttimer.Begin(\"Write output files\")\n\t\tif args.options.WriteToStdout {\n\t\t\t// Special-case writing to stdout\n\t\t\tif log.HasErrors() {\n\t\t\t\t// No output is printed if there were any build errors\n\t\t\t} else if len(results) != 1 {\n\t\t\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\n\t\t\t\t\t\"Internal error: did not expect to generate %d files when writing to stdout\", len(results)))\n\t\t\t} else {\n\t\t\t\t// Print this later on, at the end of the current function\n\t\t\t\ttoWriteToStdout = results[0].Contents\n\t\t\t}\n\t\t} else {\n\t\t\t// Delete old files that are no longer relevant\n\t\t\tvar toDelete []string\n\t\t\tfor absPath := range oldHashes {\n\t\t\t\tif _, ok := newHashes[absPath]; !ok {\n\t\t\t\t\ttoDelete = append(toDelete, absPath)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Process all file operations in parallel\n\t\t\twaitGroup := sync.WaitGroup{}\n\t\t\twaitGroup.Add(len(results) + len(toDelete))\n\t\t\tfor _, result := range results {\n\t\t\t\tgo func(result graph.OutputFile) {\n\t\t\t\t\tdefer waitGroup.Done()\n\t\t\t\t\tfs.BeforeFileOpen()\n\t\t\t\t\tdefer fs.AfterFileClose()\n\t\t\t\t\tif oldHash, ok := oldHashes[result.AbsPath]; ok && oldHash == newHashes[result.AbsPath] {\n\t\t\t\t\t\tif contents, err := ioutil.ReadFile(result.AbsPath); err == nil && bytes.Equal(contents, result.Contents) {\n\t\t\t\t\t\t\t// Skip writing out files that haven't changed since last time\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif err := fs.MkdirAll(realFS, realFS.Dir(result.AbsPath), 0755); err != nil {\n\t\t\t\t\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\n\t\t\t\t\t\t\t\"Failed to create output directory: %s\", err.Error()))\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar mode os.FileMode = 0666\n\t\t\t\t\t\tif result.IsExecutable {\n\t\t\t\t\t\t\tmode = 0777\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif err := ioutil.WriteFile(result.AbsPath, result.Contents, mode); err != nil {\n\t\t\t\t\t\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\n\t\t\t\t\t\t\t\t\"Failed to write to output file: %s\", err.Error()))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}(result)\n\t\t\t}\n\t\t\tfor _, absPath := range toDelete {\n\t\t\t\tgo func(absPath string) {\n\t\t\t\t\tdefer waitGroup.Done()\n\t\t\t\t\tfs.BeforeFileOpen()\n\t\t\t\t\tdefer fs.AfterFileClose()\n\t\t\t\t\tos.Remove(absPath)\n\t\t\t\t}(absPath)\n\t\t\t}\n\t\t\twaitGroup.Wait()\n\t\t}\n\t\ttimer.End(\"Write output files\")\n\t}\n\n\t// Only return the mangle cache for a successful build\n\tif log.HasErrors() {\n\t\tresult.MangleCache = nil\n\t}\n\n\t// Populate the result object with the messages so far\n\tmsgs := log.Peek()\n\tresult.Errors = convertMessagesToPublic(logger.Error, msgs, args.options.LogPathStyle)\n\tresult.Warnings = convertMessagesToPublic(logger.Warning, msgs, args.options.LogPathStyle)\n\n\t// Run any registered \"OnEnd\" callbacks now. These always run regardless of\n\t// whether the current build has bee canceled or not. They can check for\n\t// errors by checking the error array in the build result, and canceled\n\t// builds should always have at least one error.\n\ttimer.Begin(\"On-end callbacks\")\n\tfor _, onEnd := range args.onEndCallbacks {\n\t\tfromPlugin, thrown := onEnd.fn(&result)\n\n\t\t// Report errors and warnings generated by the plugin\n\t\tfor i := range fromPlugin.Errors {\n\t\t\tif fromPlugin.Errors[i].PluginName == \"\" {\n\t\t\t\tfromPlugin.Errors[i].PluginName = onEnd.pluginName\n\t\t\t}\n\t\t}\n\t\tfor i := range fromPlugin.Warnings {\n\t\t\tif fromPlugin.Warnings[i].PluginName == \"\" {\n\t\t\t\tfromPlugin.Warnings[i].PluginName = onEnd.pluginName\n\t\t\t}\n\t\t}\n\n\t\t// Report errors thrown by the plugin itself\n\t\tif thrown != nil {\n\t\t\tfromPlugin.Errors = append(fromPlugin.Errors, Message{\n\t\t\t\tPluginName: onEnd.pluginName,\n\t\t\t\tText:       thrown.Error(),\n\t\t\t})\n\t\t}\n\n\t\t// Log any errors and warnings generated above\n\t\tfor _, msg := range convertErrorsAndWarningsToInternal(fromPlugin.Errors, fromPlugin.Warnings) {\n\t\t\tlog.AddMsg(msg)\n\t\t}\n\n\t\t// Add the errors and warnings to the result object\n\t\tresult.Errors = append(result.Errors, fromPlugin.Errors...)\n\t\tresult.Warnings = append(result.Warnings, fromPlugin.Warnings...)\n\n\t\t// Stop if an \"onEnd\" callback failed. This counts as a build failure.\n\t\tif len(fromPlugin.Errors) > 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\ttimer.End(\"On-end callbacks\")\n\n\t// Log timing information now that we're all done\n\ttimer.Log(log)\n\n\t// End the log after \"OnEnd\" callbacks have added any additional errors and/or\n\t// warnings. This may may print any warnings that were deferred up until this\n\t// point, as well as a message with the number of errors and/or warnings\n\t// omitted due to the configured log limit.\n\tlog.Done()\n\n\t// Only write to stdout after the log has been finalized. We want this output\n\t// to show up in the terminal after the message that was printed above.\n\tif toWriteToStdout != nil {\n\t\tos.Stdout.Write(toWriteToStdout)\n\t}\n\n\treturn rebuildState{\n\t\tresult:    result,\n\t\toptions:   args.options,\n\t\twatchData: watchData,\n\t}, newHashes\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Transform API\n\nfunc transformImpl(input string, transformOpts TransformOptions) TransformResult {\n\tlog := logger.NewStderrLog(logger.OutputOptions{\n\t\tIncludeSource: true,\n\t\tMessageLimit:  transformOpts.LogLimit,\n\t\tColor:         validateColor(transformOpts.Color),\n\t\tLogLevel:      validateLogLevel(transformOpts.LogLevel),\n\t\tPathStyle:     extractPathStyle(transformOpts.AbsPaths, LogAbsPath),\n\t\tOverrides:     validateLogOverrides(transformOpts.LogOverride),\n\t})\n\tcaches := cache.MakeCacheSet()\n\n\t// Apply default values\n\tif transformOpts.Sourcefile == \"\" {\n\t\ttransformOpts.Sourcefile = \"<stdin>\"\n\t}\n\tif transformOpts.Loader == LoaderNone {\n\t\ttransformOpts.Loader = LoaderJS\n\t}\n\n\t// Convert and validate the transformOpts\n\tjsFeatures, cssFeatures, cssPrefixData, targetEnv := validateFeatures(log, transformOpts.Target, transformOpts.Engines)\n\tjsOverrides, jsMask, cssOverrides, cssMask := validateSupported(log, transformOpts.Supported)\n\tplatform := validatePlatform(transformOpts.Platform)\n\tdefines, injectedDefines := validateDefines(log, transformOpts.Define, transformOpts.Pure, platform, false /* isBuildAPI */, false /* minify */, transformOpts.Drop)\n\tmangleCache := cloneMangleCache(log, transformOpts.MangleCache)\n\toptions := config.Options{\n\t\tCSSPrefixData:                      cssPrefixData,\n\t\tUnsupportedJSFeatures:              jsFeatures.ApplyOverrides(jsOverrides, jsMask),\n\t\tUnsupportedCSSFeatures:             cssFeatures.ApplyOverrides(cssOverrides, cssMask),\n\t\tUnsupportedJSFeatureOverrides:      jsOverrides,\n\t\tUnsupportedJSFeatureOverridesMask:  jsMask,\n\t\tUnsupportedCSSFeatureOverrides:     cssOverrides,\n\t\tUnsupportedCSSFeatureOverridesMask: cssMask,\n\t\tOriginalTargetEnv:                  targetEnv,\n\t\tTSConfigRaw:                        transformOpts.TsconfigRaw,\n\t\tJSX: config.JSXOptions{\n\t\t\tPreserve:         transformOpts.JSX == JSXPreserve,\n\t\t\tAutomaticRuntime: transformOpts.JSX == JSXAutomatic,\n\t\t\tFactory:          validateJSXExpr(log, transformOpts.JSXFactory, \"factory\"),\n\t\t\tFragment:         validateJSXExpr(log, transformOpts.JSXFragment, \"fragment\"),\n\t\t\tDevelopment:      transformOpts.JSXDev,\n\t\t\tImportSource:     transformOpts.JSXImportSource,\n\t\t\tSideEffects:      transformOpts.JSXSideEffects,\n\t\t},\n\t\tDefines:               defines,\n\t\tInjectedDefines:       injectedDefines,\n\t\tPlatform:              platform,\n\t\tSourceMap:             validateSourceMap(transformOpts.Sourcemap),\n\t\tLegalComments:         validateLegalComments(transformOpts.LegalComments, false /* bundle */),\n\t\tSourceRoot:            transformOpts.SourceRoot,\n\t\tExcludeSourcesContent: transformOpts.SourcesContent == SourcesContentExclude,\n\t\tOutputFormat:          validateFormat(transformOpts.Format),\n\t\tGlobalName:            validateGlobalName(log, transformOpts.GlobalName, \"(global name)\"),\n\t\tMinifySyntax:          transformOpts.MinifySyntax,\n\t\tMinifyWhitespace:      transformOpts.MinifyWhitespace,\n\t\tMinifyIdentifiers:     transformOpts.MinifyIdentifiers,\n\t\tLineLimit:             transformOpts.LineLimit,\n\t\tMangleProps:           validateRegex(log, \"mangle props\", transformOpts.MangleProps),\n\t\tReserveProps:          validateRegex(log, \"reserve props\", transformOpts.ReserveProps),\n\t\tMangleQuoted:          transformOpts.MangleQuoted == MangleQuotedTrue,\n\t\tDropLabels:            append([]string{}, transformOpts.DropLabels...),\n\t\tDropDebugger:          (transformOpts.Drop & DropDebugger) != 0,\n\t\tASCIIOnly:             validateASCIIOnly(transformOpts.Charset),\n\t\tIgnoreDCEAnnotations:  transformOpts.IgnoreAnnotations,\n\t\tTreeShaking:           validateTreeShaking(transformOpts.TreeShaking, false /* bundle */, transformOpts.Format),\n\t\tAbsOutputFile:         transformOpts.Sourcefile + \"-out\",\n\t\tKeepNames:             transformOpts.KeepNames,\n\t\tCodePathStyle:         extractPathStyle(transformOpts.AbsPaths, CodeAbsPath),\n\t\tLogPathStyle:          extractPathStyle(transformOpts.AbsPaths, LogAbsPath),\n\t\tMetafilePathStyle:     extractPathStyle(transformOpts.AbsPaths, MetafileAbsPath),\n\t\tStdin: &config.StdinInfo{\n\t\t\tLoader:     validateLoader(transformOpts.Loader),\n\t\t\tContents:   input,\n\t\t\tSourceFile: transformOpts.Sourcefile,\n\t\t},\n\t}\n\tvalidateKeepNames(log, &options)\n\tif options.Stdin.Loader.IsCSS() {\n\t\toptions.CSSBanner = transformOpts.Banner\n\t\toptions.CSSFooter = transformOpts.Footer\n\t} else {\n\t\toptions.JSBanner = transformOpts.Banner\n\t\toptions.JSFooter = transformOpts.Footer\n\t}\n\tif options.SourceMap == config.SourceMapLinkedWithComment {\n\t\t// Linked source maps don't make sense because there's no output file name\n\t\tlog.AddError(nil, logger.Range{}, \"Cannot transform with linked source maps\")\n\t}\n\tif options.SourceMap != config.SourceMapNone && options.Stdin.SourceFile == \"\" {\n\t\tlog.AddError(nil, logger.Range{},\n\t\t\t\"Must use \\\"sourcefile\\\" with \\\"sourcemap\\\" to set the original file name\")\n\t}\n\tif logger.API == logger.CLIAPI {\n\t\tif options.LegalComments.HasExternalFile() {\n\t\t\tlog.AddError(nil, logger.Range{}, \"Cannot transform with linked or external legal comments\")\n\t\t}\n\t} else if options.LegalComments == config.LegalCommentsLinkedWithComment {\n\t\tlog.AddError(nil, logger.Range{}, \"Cannot transform with linked legal comments\")\n\t}\n\n\t// Set the output mode using other settings\n\tif options.OutputFormat != config.FormatPreserve {\n\t\toptions.Mode = config.ModeConvertFormat\n\t}\n\n\tvar results []graph.OutputFile\n\n\t// Stop now if there were errors\n\tif !log.HasErrors() {\n\t\tvar timer *helpers.Timer\n\t\tif api_helpers.UseTimer {\n\t\t\ttimer = &helpers.Timer{}\n\t\t}\n\n\t\t// Scan over the bundle\n\t\tmockFS := fs.MockFS(make(map[string]string), fs.MockUnix, \"/\")\n\t\tbundle := bundler.ScanBundle(config.TransformCall, log, mockFS, caches, nil, options, timer)\n\n\t\t// Stop now if there were errors\n\t\tif !log.HasErrors() {\n\t\t\t// Compile the bundle\n\t\t\tresults, _ = bundle.Compile(log, timer, mangleCache, linker.Link)\n\t\t}\n\n\t\ttimer.Log(log)\n\t}\n\n\t// Return the results\n\tvar code []byte\n\tvar sourceMap []byte\n\tvar legalComments []byte\n\n\tvar shortestAbsPath string\n\tfor _, result := range results {\n\t\tif shortestAbsPath == \"\" || len(result.AbsPath) < len(shortestAbsPath) {\n\t\t\tshortestAbsPath = result.AbsPath\n\t\t}\n\t}\n\n\t// Unpack the JavaScript file, the source map file, and the legal comments file\n\tfor _, result := range results {\n\t\tswitch result.AbsPath {\n\t\tcase shortestAbsPath:\n\t\t\tcode = result.Contents\n\t\tcase shortestAbsPath + \".map\":\n\t\t\tsourceMap = result.Contents\n\t\tcase shortestAbsPath + \".LEGAL.txt\":\n\t\t\tlegalComments = result.Contents\n\t\t}\n\t}\n\n\t// Only return the mangle cache for a successful build\n\tif log.HasErrors() {\n\t\tmangleCache = nil\n\t}\n\n\tmsgs := log.Done()\n\treturn TransformResult{\n\t\tErrors:        convertMessagesToPublic(logger.Error, msgs, options.LogPathStyle),\n\t\tWarnings:      convertMessagesToPublic(logger.Warning, msgs, options.LogPathStyle),\n\t\tCode:          code,\n\t\tMap:           sourceMap,\n\t\tLegalComments: legalComments,\n\t\tMangleCache:   mangleCache,\n\t}\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Plugin API\n\ntype pluginImpl struct {\n\tlog    logger.Log\n\tfs     fs.FS\n\tplugin config.Plugin\n}\n\nfunc (impl *pluginImpl) onStart(callback func() (OnStartResult, error)) {\n\timpl.plugin.OnStart = append(impl.plugin.OnStart, config.OnStart{\n\t\tName: impl.plugin.Name,\n\t\tCallback: func() (result config.OnStartResult) {\n\t\t\tresponse, err := callback()\n\n\t\t\tif err != nil {\n\t\t\t\tresult.ThrownError = err\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Convert log messages\n\t\t\tresult.Msgs = convertErrorsAndWarningsToInternal(response.Errors, response.Warnings)\n\t\t\treturn\n\t\t},\n\t})\n}\n\nfunc importKindToResolveKind(kind ast.ImportKind) ResolveKind {\n\tswitch kind {\n\tcase ast.ImportEntryPoint:\n\t\treturn ResolveEntryPoint\n\tcase ast.ImportStmt:\n\t\treturn ResolveJSImportStatement\n\tcase ast.ImportRequire:\n\t\treturn ResolveJSRequireCall\n\tcase ast.ImportDynamic:\n\t\treturn ResolveJSDynamicImport\n\tcase ast.ImportRequireResolve:\n\t\treturn ResolveJSRequireResolve\n\tcase ast.ImportAt:\n\t\treturn ResolveCSSImportRule\n\tcase ast.ImportComposesFrom:\n\t\treturn ResolveCSSComposesFrom\n\tcase ast.ImportURL:\n\t\treturn ResolveCSSURLToken\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\nfunc resolveKindToImportKind(kind ResolveKind) ast.ImportKind {\n\tswitch kind {\n\tcase ResolveEntryPoint:\n\t\treturn ast.ImportEntryPoint\n\tcase ResolveJSImportStatement:\n\t\treturn ast.ImportStmt\n\tcase ResolveJSRequireCall:\n\t\treturn ast.ImportRequire\n\tcase ResolveJSDynamicImport:\n\t\treturn ast.ImportDynamic\n\tcase ResolveJSRequireResolve:\n\t\treturn ast.ImportRequireResolve\n\tcase ResolveCSSImportRule:\n\t\treturn ast.ImportAt\n\tcase ResolveCSSComposesFrom:\n\t\treturn ast.ImportComposesFrom\n\tcase ResolveCSSURLToken:\n\t\treturn ast.ImportURL\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\nfunc (impl *pluginImpl) onResolve(options OnResolveOptions, callback func(OnResolveArgs) (OnResolveResult, error)) {\n\tfilter, err := config.CompileFilterForPlugin(impl.plugin.Name, \"OnResolve\", options.Filter)\n\tif filter == nil {\n\t\timpl.log.AddError(nil, logger.Range{}, err.Error())\n\t\treturn\n\t}\n\n\timpl.plugin.OnResolve = append(impl.plugin.OnResolve, config.OnResolve{\n\t\tName:      impl.plugin.Name,\n\t\tFilter:    filter,\n\t\tNamespace: options.Namespace,\n\t\tCallback: func(args config.OnResolveArgs) (result config.OnResolveResult) {\n\t\t\tresponse, err := callback(OnResolveArgs{\n\t\t\t\tPath:       args.Path,\n\t\t\t\tImporter:   args.Importer.Text,\n\t\t\t\tNamespace:  args.Importer.Namespace,\n\t\t\t\tResolveDir: args.ResolveDir,\n\t\t\t\tKind:       importKindToResolveKind(args.Kind),\n\t\t\t\tPluginData: args.PluginData,\n\t\t\t\tWith:       args.With.DecodeIntoMap(),\n\t\t\t})\n\t\t\tresult.PluginName = response.PluginName\n\t\t\tresult.AbsWatchFiles = impl.validatePathsArray(response.WatchFiles, \"watch file\")\n\t\t\tresult.AbsWatchDirs = impl.validatePathsArray(response.WatchDirs, \"watch directory\")\n\n\t\t\t// Restrict the suffix to start with \"?\" or \"#\" for now to match esbuild's behavior\n\t\t\tif err == nil && response.Suffix != \"\" && response.Suffix[0] != '?' && response.Suffix[0] != '#' {\n\t\t\t\terr = fmt.Errorf(\"Invalid path suffix %q returned from plugin (must start with \\\"?\\\" or \\\"#\\\")\", response.Suffix)\n\t\t\t}\n\n\t\t\tif err != nil {\n\t\t\t\tresult.ThrownError = err\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tresult.Path = logger.Path{\n\t\t\t\tText:          response.Path,\n\t\t\t\tNamespace:     response.Namespace,\n\t\t\t\tIgnoredSuffix: response.Suffix,\n\t\t\t}\n\t\t\tresult.External = response.External\n\t\t\tresult.IsSideEffectFree = response.SideEffects == SideEffectsFalse\n\t\t\tresult.PluginData = response.PluginData\n\n\t\t\t// Convert log messages\n\t\t\tresult.Msgs = convertErrorsAndWarningsToInternal(response.Errors, response.Warnings)\n\n\t\t\t// Warn if the plugin returned things without resolving the path\n\t\t\tif response.Path == \"\" && !response.External {\n\t\t\t\tvar what string\n\t\t\t\tif response.Namespace != \"\" {\n\t\t\t\t\twhat = \"namespace\"\n\t\t\t\t} else if response.Suffix != \"\" {\n\t\t\t\t\twhat = \"suffix\"\n\t\t\t\t} else if response.PluginData != nil {\n\t\t\t\t\twhat = \"pluginData\"\n\t\t\t\t} else if response.WatchFiles != nil {\n\t\t\t\t\twhat = \"watchFiles\"\n\t\t\t\t} else if response.WatchDirs != nil {\n\t\t\t\t\twhat = \"watchDirs\"\n\t\t\t\t}\n\t\t\t\tif what != \"\" {\n\t\t\t\t\tpath := \"path\"\n\t\t\t\t\tif logger.API == logger.GoAPI {\n\t\t\t\t\t\twhat = strings.Title(what)\n\t\t\t\t\t\tpath = strings.Title(path)\n\t\t\t\t\t}\n\t\t\t\t\tresult.Msgs = append(result.Msgs, logger.Msg{\n\t\t\t\t\t\tKind: logger.Warning,\n\t\t\t\t\t\tData: logger.MsgData{Text: fmt.Sprintf(\"Returning %q doesn't do anything when %q is empty\", what, path)},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn\n\t\t},\n\t})\n}\n\nfunc (impl *pluginImpl) onLoad(options OnLoadOptions, callback func(OnLoadArgs) (OnLoadResult, error)) {\n\tfilter, err := config.CompileFilterForPlugin(impl.plugin.Name, \"OnLoad\", options.Filter)\n\tif filter == nil {\n\t\timpl.log.AddError(nil, logger.Range{}, err.Error())\n\t\treturn\n\t}\n\n\timpl.plugin.OnLoad = append(impl.plugin.OnLoad, config.OnLoad{\n\t\tFilter:    filter,\n\t\tNamespace: options.Namespace,\n\t\tCallback: func(args config.OnLoadArgs) (result config.OnLoadResult) {\n\t\t\tresponse, err := callback(OnLoadArgs{\n\t\t\t\tPath:       args.Path.Text,\n\t\t\t\tNamespace:  args.Path.Namespace,\n\t\t\t\tPluginData: args.PluginData,\n\t\t\t\tSuffix:     args.Path.IgnoredSuffix,\n\t\t\t\tWith:       args.Path.ImportAttributes.DecodeIntoMap(),\n\t\t\t})\n\t\t\tresult.PluginName = response.PluginName\n\t\t\tresult.AbsWatchFiles = impl.validatePathsArray(response.WatchFiles, \"watch file\")\n\t\t\tresult.AbsWatchDirs = impl.validatePathsArray(response.WatchDirs, \"watch directory\")\n\n\t\t\tif err != nil {\n\t\t\t\tresult.ThrownError = err\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tresult.Contents = response.Contents\n\t\t\tresult.Loader = validateLoader(response.Loader)\n\t\t\tresult.PluginData = response.PluginData\n\t\t\tpathKind := fmt.Sprintf(\"resolve directory path for plugin %q\", impl.plugin.Name)\n\t\t\tif absPath := validatePath(impl.log, impl.fs, response.ResolveDir, pathKind); absPath != \"\" {\n\t\t\t\tresult.AbsResolveDir = absPath\n\t\t\t}\n\n\t\t\t// Convert log messages\n\t\t\tresult.Msgs = convertErrorsAndWarningsToInternal(response.Errors, response.Warnings)\n\t\t\treturn\n\t\t},\n\t})\n}\n\nfunc (impl *pluginImpl) validatePathsArray(pathsIn []string, name string) (pathsOut []string) {\n\tif len(pathsIn) > 0 {\n\t\tpathKind := fmt.Sprintf(\"%s path for plugin %q\", name, impl.plugin.Name)\n\t\tfor _, relPath := range pathsIn {\n\t\t\tif absPath := validatePath(impl.log, impl.fs, relPath, pathKind); absPath != \"\" {\n\t\t\t\tpathsOut = append(pathsOut, absPath)\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\nfunc loadPlugins(initialOptions *BuildOptions, fs fs.FS, log logger.Log, caches *cache.CacheSet) (\n\tonEndCallbacks []onEndCallback,\n\tonDisposeCallbacks []func(),\n\tfinalizeBuildOptions func(*config.Options),\n) {\n\t// Clone the plugin array to guard against mutation during iteration\n\tclone := append(make([]Plugin, 0, len(initialOptions.Plugins)), initialOptions.Plugins...)\n\n\tvar optionsForResolve *config.Options\n\tvar plugins []config.Plugin\n\n\t// This is called after the build options have been validated\n\tfinalizeBuildOptions = func(options *config.Options) {\n\t\toptions.Plugins = plugins\n\t\toptionsForResolve = options\n\t}\n\n\tfor i, item := range clone {\n\t\tif item.Name == \"\" {\n\t\t\tlog.AddError(nil, logger.Range{}, fmt.Sprintf(\"Plugin at index %d is missing a name\", i))\n\t\t\tcontinue\n\t\t}\n\n\t\timpl := &pluginImpl{\n\t\t\tfs:     fs,\n\t\t\tlog:    log,\n\t\t\tplugin: config.Plugin{Name: item.Name},\n\t\t}\n\n\t\tresolve := func(path string, options ResolveOptions) (result ResolveResult) {\n\t\t\t// If options are missing, then this is being called before plugin setup\n\t\t\t// has finished. That isn't allowed because plugin setup is allowed to\n\t\t\t// change the initial options object, which can affect path resolution.\n\t\t\tif optionsForResolve == nil {\n\t\t\t\treturn ResolveResult{Errors: []Message{{Text: \"Cannot call \\\"resolve\\\" before plugin setup has completed\"}}}\n\t\t\t}\n\n\t\t\tif options.Kind == ResolveNone {\n\t\t\t\treturn ResolveResult{Errors: []Message{{Text: \"Must specify \\\"kind\\\" when calling \\\"resolve\\\"\"}}}\n\t\t\t}\n\n\t\t\t// Make a new resolver so it has its own log\n\t\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, validateLogOverrides(initialOptions.LogOverride))\n\t\t\toptionsClone := *optionsForResolve\n\t\t\tresolver := resolver.NewResolver(config.BuildCall, fs, log, caches, &optionsClone)\n\n\t\t\t// Make sure the resolve directory is an absolute path, which can fail\n\t\t\tabsResolveDir := validatePath(log, fs, options.ResolveDir, \"resolve directory\")\n\t\t\tif log.HasErrors() {\n\t\t\t\tmsgs := log.Done()\n\t\t\t\tresult.Errors = convertMessagesToPublic(logger.Error, msgs, optionsClone.LogPathStyle)\n\t\t\t\tresult.Warnings = convertMessagesToPublic(logger.Warning, msgs, optionsClone.LogPathStyle)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Run path resolution\n\t\t\tkind := resolveKindToImportKind(options.Kind)\n\t\t\tresolveResult, _, _ := bundler.RunOnResolvePlugins(\n\t\t\t\tplugins,\n\t\t\t\tresolver,\n\t\t\t\tlog,\n\t\t\t\tfs,\n\t\t\t\t&caches.FSCache,\n\t\t\t\tnil,            // importSource\n\t\t\t\tlogger.Range{}, // importPathRange\n\t\t\t\tlogger.Path{Text: options.Importer, Namespace: options.Namespace},\n\t\t\t\tpath,\n\t\t\t\tlogger.EncodeImportAttributes(options.With),\n\t\t\t\tkind,\n\t\t\t\tabsResolveDir,\n\t\t\t\toptions.PluginData,\n\t\t\t\toptionsClone.LogPathStyle,\n\t\t\t)\n\t\t\tmsgs := log.Done()\n\n\t\t\t// Populate the result\n\t\t\tresult.Errors = convertMessagesToPublic(logger.Error, msgs, optionsClone.LogPathStyle)\n\t\t\tresult.Warnings = convertMessagesToPublic(logger.Warning, msgs, optionsClone.LogPathStyle)\n\t\t\tif resolveResult != nil {\n\t\t\t\tresult.Path = resolveResult.PathPair.Primary.Text\n\t\t\t\tresult.External = resolveResult.PathPair.IsExternal\n\t\t\t\tresult.SideEffects = resolveResult.PrimarySideEffectsData == nil\n\t\t\t\tresult.Namespace = resolveResult.PathPair.Primary.Namespace\n\t\t\t\tresult.Suffix = resolveResult.PathPair.Primary.IgnoredSuffix\n\t\t\t\tresult.PluginData = resolveResult.PluginData\n\t\t\t} else if len(result.Errors) == 0 {\n\t\t\t\t// Always fail with at least one error\n\t\t\t\tpluginName := item.Name\n\t\t\t\tif options.PluginName != \"\" {\n\t\t\t\t\tpluginName = options.PluginName\n\t\t\t\t}\n\t\t\t\ttext, _, notes := bundler.ResolveFailureErrorTextSuggestionNotes(\n\t\t\t\t\tresolver, path, kind, pluginName, fs, absResolveDir, optionsForResolve.Platform,\n\t\t\t\t\tlogger.PrettyPaths{}, \"\", optionsClone.LogPathStyle)\n\t\t\t\tresult.Errors = append(result.Errors, convertMessagesToPublic(logger.Error, []logger.Msg{{\n\t\t\t\t\tData:  logger.MsgData{Text: text},\n\t\t\t\t\tNotes: notes,\n\t\t\t\t}}, optionsClone.LogPathStyle)...)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tonEnd := func(fn func(*BuildResult) (OnEndResult, error)) {\n\t\t\tonEndCallbacks = append(onEndCallbacks, onEndCallback{\n\t\t\t\tpluginName: item.Name,\n\t\t\t\tfn:         fn,\n\t\t\t})\n\t\t}\n\n\t\tonDispose := func(fn func()) {\n\t\t\tonDisposeCallbacks = append(onDisposeCallbacks, fn)\n\t\t}\n\n\t\titem.Setup(PluginBuild{\n\t\t\tInitialOptions: initialOptions,\n\t\t\tResolve:        resolve,\n\t\t\tOnStart:        impl.onStart,\n\t\t\tOnEnd:          onEnd,\n\t\t\tOnDispose:      onDispose,\n\t\t\tOnResolve:      impl.onResolve,\n\t\t\tOnLoad:         impl.onLoad,\n\t\t})\n\n\t\tplugins = append(plugins, impl.plugin)\n\t}\n\n\treturn\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// FormatMessages API\n\nfunc formatMsgsImpl(msgs []Message, opts FormatMessagesOptions) []string {\n\tkind := logger.Error\n\tif opts.Kind == WarningMessage {\n\t\tkind = logger.Warning\n\t}\n\tlogMsgs := convertMessagesToInternal(nil, kind, msgs)\n\tstrings := make([]string, len(logMsgs))\n\tfor i, msg := range logMsgs {\n\t\tstrings[i] = msg.String(\n\t\t\tlogger.OutputOptions{\n\t\t\t\tIncludeSource: true,\n\t\t\t},\n\t\t\tlogger.TerminalInfo{\n\t\t\t\tUseColorEscapes: opts.Color,\n\t\t\t\tWidth:           opts.TerminalWidth,\n\t\t\t},\n\t\t)\n\t}\n\treturn strings\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// AnalyzeMetafile API\n\ntype metafileEntry struct {\n\tname       string\n\tentryPoint string\n\tentries    []metafileEntry\n\tsize       int\n}\n\n// This type is just so we can use Go's native sort function\ntype metafileArray []metafileEntry\n\nfunc (a metafileArray) Len() int          { return len(a) }\nfunc (a metafileArray) Swap(i int, j int) { a[i], a[j] = a[j], a[i] }\n\nfunc (a metafileArray) Less(i int, j int) bool {\n\tai := a[i]\n\taj := a[j]\n\treturn ai.size > aj.size || (ai.size == aj.size && ai.name < aj.name)\n}\n\nfunc getObjectProperty(expr js_ast.Expr, key string) js_ast.Expr {\n\tif obj, ok := expr.Data.(*js_ast.EObject); ok {\n\t\tfor _, prop := range obj.Properties {\n\t\t\tif helpers.UTF16EqualsString(prop.Key.Data.(*js_ast.EString).Value, key) {\n\t\t\t\treturn prop.ValueOrNil\n\t\t\t}\n\t\t}\n\t}\n\treturn js_ast.Expr{}\n}\n\nfunc getObjectPropertyNumber(expr js_ast.Expr, key string) *js_ast.ENumber {\n\tvalue, _ := getObjectProperty(expr, key).Data.(*js_ast.ENumber)\n\treturn value\n}\n\nfunc getObjectPropertyString(expr js_ast.Expr, key string) *js_ast.EString {\n\tvalue, _ := getObjectProperty(expr, key).Data.(*js_ast.EString)\n\treturn value\n}\n\nfunc getObjectPropertyObject(expr js_ast.Expr, key string) *js_ast.EObject {\n\tvalue, _ := getObjectProperty(expr, key).Data.(*js_ast.EObject)\n\treturn value\n}\n\nfunc getObjectPropertyArray(expr js_ast.Expr, key string) *js_ast.EArray {\n\tvalue, _ := getObjectProperty(expr, key).Data.(*js_ast.EArray)\n\treturn value\n}\n\nfunc analyzeMetafileImpl(metafile string, opts AnalyzeMetafileOptions) string {\n\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)\n\tsource := logger.Source{Contents: metafile}\n\n\tif result, ok := js_parser.ParseJSON(log, source, js_parser.JSONOptions{}); ok {\n\t\tif outputs := getObjectPropertyObject(result, \"outputs\"); outputs != nil {\n\t\t\tvar entries metafileArray\n\t\t\tvar entryPoints []string\n\n\t\t\t// Scan over the \"outputs\" object\n\t\t\tfor _, output := range outputs.Properties {\n\t\t\t\tif key := helpers.UTF16ToString(output.Key.Data.(*js_ast.EString).Value); !strings.HasSuffix(key, \".map\") {\n\t\t\t\t\tentryPointPath := \"\"\n\t\t\t\t\tif entryPoint := getObjectPropertyString(output.ValueOrNil, \"entryPoint\"); entryPoint != nil {\n\t\t\t\t\t\tentryPointPath = helpers.UTF16ToString(entryPoint.Value)\n\t\t\t\t\t\tentryPoints = append(entryPoints, entryPointPath)\n\t\t\t\t\t}\n\n\t\t\t\t\tif bytes := getObjectPropertyNumber(output.ValueOrNil, \"bytes\"); bytes != nil {\n\t\t\t\t\t\tif inputs := getObjectPropertyObject(output.ValueOrNil, \"inputs\"); inputs != nil {\n\t\t\t\t\t\t\tvar children metafileArray\n\n\t\t\t\t\t\t\tfor _, input := range inputs.Properties {\n\t\t\t\t\t\t\t\tif bytesInOutput := getObjectPropertyNumber(input.ValueOrNil, \"bytesInOutput\"); bytesInOutput != nil && bytesInOutput.Value > 0 {\n\t\t\t\t\t\t\t\t\tchildren = append(children, metafileEntry{\n\t\t\t\t\t\t\t\t\t\tname: helpers.UTF16ToString(input.Key.Data.(*js_ast.EString).Value),\n\t\t\t\t\t\t\t\t\t\tsize: int(bytesInOutput.Value),\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tsort.Sort(children)\n\n\t\t\t\t\t\t\tentries = append(entries, metafileEntry{\n\t\t\t\t\t\t\t\tname:       key,\n\t\t\t\t\t\t\t\tsize:       int(bytes.Value),\n\t\t\t\t\t\t\t\tentries:    children,\n\t\t\t\t\t\t\t\tentryPoint: entryPointPath,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsort.Sort(entries)\n\n\t\t\ttype importData struct {\n\t\t\t\timports []string\n\t\t\t}\n\n\t\t\ttype graphData struct {\n\t\t\t\tparent string\n\t\t\t\tdepth  uint32\n\t\t\t}\n\n\t\t\timportsForPath := make(map[string]importData)\n\n\t\t\t// Scan over the \"inputs\" object\n\t\t\tif inputs := getObjectPropertyObject(result, \"inputs\"); inputs != nil {\n\t\t\t\tfor _, prop := range inputs.Properties {\n\t\t\t\t\tif imports := getObjectPropertyArray(prop.ValueOrNil, \"imports\"); imports != nil {\n\t\t\t\t\t\tvar data importData\n\n\t\t\t\t\t\tfor _, item := range imports.Items {\n\t\t\t\t\t\t\tif path := getObjectPropertyString(item, \"path\"); path != nil {\n\t\t\t\t\t\t\t\tdata.imports = append(data.imports, helpers.UTF16ToString(path.Value))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\timportsForPath[helpers.UTF16ToString(prop.Key.Data.(*js_ast.EString).Value)] = data\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Returns a graph with links pointing from imports to importers\n\t\t\tgraphForEntryPoints := func(worklist []string) map[string]graphData {\n\t\t\t\tif !opts.Verbose {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\tgraph := make(map[string]graphData)\n\n\t\t\t\tfor _, entryPoint := range worklist {\n\t\t\t\t\tgraph[entryPoint] = graphData{}\n\t\t\t\t}\n\n\t\t\t\tfor len(worklist) > 0 {\n\t\t\t\t\ttop := worklist[len(worklist)-1]\n\t\t\t\t\tworklist = worklist[:len(worklist)-1]\n\t\t\t\t\tchildDepth := graph[top].depth + 1\n\n\t\t\t\t\tfor _, importPath := range importsForPath[top].imports {\n\t\t\t\t\t\timported, ok := graph[importPath]\n\t\t\t\t\t\tif !ok {\n\t\t\t\t\t\t\timported.depth = math.MaxUint32\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif imported.depth > childDepth {\n\t\t\t\t\t\t\timported.depth = childDepth\n\t\t\t\t\t\t\timported.parent = top\n\t\t\t\t\t\t\tgraph[importPath] = imported\n\t\t\t\t\t\t\tworklist = append(worklist, importPath)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn graph\n\t\t\t}\n\n\t\t\tgraphForAllEntryPoints := graphForEntryPoints(entryPoints)\n\n\t\t\ttype tableEntry struct {\n\t\t\t\tfirst      string\n\t\t\t\tsecond     string\n\t\t\t\tthird      string\n\t\t\t\tfirstLen   int\n\t\t\t\tsecondLen  int\n\t\t\t\tthirdLen   int\n\t\t\t\tisTopLevel bool\n\t\t\t}\n\n\t\t\tvar table []tableEntry\n\t\t\tvar colors logger.Colors\n\n\t\t\tif opts.Color {\n\t\t\t\tcolors = logger.TerminalColors\n\t\t\t}\n\n\t\t\t// Build up the table with an entry for each output file (other than \".map\" files)\n\t\t\tfor _, entry := range entries {\n\t\t\t\tsecond := prettyPrintByteCount(entry.size)\n\t\t\t\tthird := \"100.0%\"\n\n\t\t\t\ttable = append(table, tableEntry{\n\t\t\t\t\tfirst:      entry.name,\n\t\t\t\t\tfirstLen:   utf8.RuneCountInString(entry.name),\n\t\t\t\t\tsecond:     second,\n\t\t\t\t\tsecondLen:  len(second),\n\t\t\t\t\tthird:      third,\n\t\t\t\t\tthirdLen:   len(third),\n\t\t\t\t\tisTopLevel: true,\n\t\t\t\t})\n\n\t\t\t\tgraph := graphForAllEntryPoints\n\t\t\t\tif entry.entryPoint != \"\" {\n\t\t\t\t\t// If there are multiple entry points and this output file is from an\n\t\t\t\t\t// entry point, prefer import paths for this entry point. This is less\n\t\t\t\t\t// confusing than showing import paths for another entry point.\n\t\t\t\t\tgraph = graphForEntryPoints([]string{entry.entryPoint})\n\t\t\t\t}\n\n\t\t\t\t// Add a sub-entry for each input file in this output file\n\t\t\t\tfor j, child := range entry.entries {\n\t\t\t\t\tindent := \" ├ \"\n\t\t\t\t\tif j+1 == len(entry.entries) {\n\t\t\t\t\t\tindent = \" └ \"\n\t\t\t\t\t}\n\t\t\t\t\tpercent := 100.0 * float64(child.size) / float64(entry.size)\n\n\t\t\t\t\tfirst := indent + child.name\n\t\t\t\t\tsecond := prettyPrintByteCount(child.size)\n\t\t\t\t\tthird := fmt.Sprintf(\"%.1f%%\", percent)\n\n\t\t\t\t\ttable = append(table, tableEntry{\n\t\t\t\t\t\tfirst:     first,\n\t\t\t\t\t\tfirstLen:  utf8.RuneCountInString(first),\n\t\t\t\t\t\tsecond:    second,\n\t\t\t\t\t\tsecondLen: len(second),\n\t\t\t\t\t\tthird:     third,\n\t\t\t\t\t\tthirdLen:  len(third),\n\t\t\t\t\t})\n\n\t\t\t\t\t// If we're in verbose mode, also print the import chain from this file\n\t\t\t\t\t// up toward an entry point to show why this file is in the bundle\n\t\t\t\t\tif opts.Verbose {\n\t\t\t\t\t\tindent = \" │ \"\n\t\t\t\t\t\tif j+1 == len(entry.entries) {\n\t\t\t\t\t\t\tindent = \"   \"\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdata := graph[child.name]\n\t\t\t\t\t\tdepth := 0\n\n\t\t\t\t\t\tfor data.depth != 0 {\n\t\t\t\t\t\t\ttable = append(table, tableEntry{\n\t\t\t\t\t\t\t\tfirst: fmt.Sprintf(\"%s%s%s └ %s%s\", indent, colors.Dim, strings.Repeat(\" \", depth), data.parent, colors.Reset),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tdata = graph[data.parent]\n\t\t\t\t\t\t\tdepth += 3\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmaxFirstLen := 0\n\t\t\tmaxSecondLen := 0\n\t\t\tmaxThirdLen := 0\n\n\t\t\t// Calculate column widths\n\t\t\tfor _, entry := range table {\n\t\t\t\tif maxFirstLen < entry.firstLen {\n\t\t\t\t\tmaxFirstLen = entry.firstLen\n\t\t\t\t}\n\t\t\t\tif maxSecondLen < entry.secondLen {\n\t\t\t\t\tmaxSecondLen = entry.secondLen\n\t\t\t\t}\n\t\t\t\tif maxThirdLen < entry.thirdLen {\n\t\t\t\t\tmaxThirdLen = entry.thirdLen\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsb := strings.Builder{}\n\n\t\t\t// Render the columns now that we know the widths\n\t\t\tfor _, entry := range table {\n\t\t\t\tprefix := \"\\n\"\n\t\t\t\tcolor := colors.Bold\n\t\t\t\tif !entry.isTopLevel {\n\t\t\t\t\tprefix = \"\"\n\t\t\t\t\tcolor = \"\"\n\t\t\t\t}\n\n\t\t\t\t// Import paths don't have second and third columns\n\t\t\t\tif entry.second == \"\" && entry.third == \"\" {\n\t\t\t\t\tsb.WriteString(fmt.Sprintf(\"%s  %s\\n\",\n\t\t\t\t\t\tprefix,\n\t\t\t\t\t\tentry.first,\n\t\t\t\t\t))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tsecond := entry.second\n\t\t\t\tsecondTrimmed := strings.TrimRight(second, \" \")\n\t\t\t\tlineChar := \" \"\n\t\t\t\textraSpace := 0\n\n\t\t\t\tif opts.Verbose {\n\t\t\t\t\tlineChar = \"─\"\n\t\t\t\t\textraSpace = 1\n\t\t\t\t}\n\n\t\t\t\tsb.WriteString(fmt.Sprintf(\"%s  %s%s%s %s%s%s %s%s%s %s%s%s %s%s%s\\n\",\n\t\t\t\t\tprefix,\n\t\t\t\t\tcolor,\n\t\t\t\t\tentry.first,\n\t\t\t\t\tcolors.Reset,\n\t\t\t\t\tcolors.Dim,\n\t\t\t\t\tstrings.Repeat(lineChar, extraSpace+maxFirstLen-entry.firstLen+maxSecondLen-entry.secondLen),\n\t\t\t\t\tcolors.Reset,\n\t\t\t\t\tcolor,\n\t\t\t\t\tsecondTrimmed,\n\t\t\t\t\tcolors.Reset,\n\t\t\t\t\tcolors.Dim,\n\t\t\t\t\tstrings.Repeat(lineChar, extraSpace+maxThirdLen-entry.thirdLen+len(second)-len(secondTrimmed)),\n\t\t\t\t\tcolors.Reset,\n\t\t\t\t\tcolor,\n\t\t\t\t\tentry.third,\n\t\t\t\t\tcolors.Reset,\n\t\t\t\t))\n\t\t\t}\n\n\t\t\treturn sb.String()\n\t\t}\n\t}\n\n\treturn \"\"\n}\n\nfunc stripDirPrefix(path string, prefix string, allowedSlashes string) (string, bool) {\n\tif strings.HasPrefix(path, prefix) {\n\t\tpathLen := len(path)\n\t\tprefixLen := len(prefix)\n\n\t\t// Just return the path if there is no prefix\n\t\tif prefixLen == 0 {\n\t\t\treturn path, true\n\t\t}\n\n\t\t// Return the empty string if the path equals the prefix\n\t\tif pathLen == prefixLen {\n\t\t\treturn \"\", true\n\t\t}\n\n\t\tif strings.IndexByte(allowedSlashes, prefix[prefixLen-1]) >= 0 {\n\t\t\t// Return the suffix if the prefix ends in a slash. Examples:\n\t\t\t//\n\t\t\t//   stripDirPrefix(`/foo`, `/`, `/`) => `foo`\n\t\t\t//   stripDirPrefix(`C:\\foo`, `C:\\`, `\\/`) => `foo`\n\t\t\t//\n\t\t\treturn path[prefixLen:], true\n\t\t} else if strings.IndexByte(allowedSlashes, path[prefixLen]) >= 0 {\n\t\t\t// Return the suffix if there's a slash after the prefix. Examples:\n\t\t\t//\n\t\t\t//   stripDirPrefix(`/foo/bar`, `/foo`, `/`) => `bar`\n\t\t\t//   stripDirPrefix(`C:\\foo\\bar`, `C:\\foo`, `\\/`) => `bar`\n\t\t\t//\n\t\t\treturn path[prefixLen+1:], true\n\t\t}\n\t}\n\n\treturn \"\", false\n}\n"
  },
  {
    "path": "pkg/api/api_impl_test.go",
    "content": "package api\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/test\"\n)\n\nfunc TestStripDirPrefix(t *testing.T) {\n\texpectSuccess := func(path string, prefix string, allowedSlashes string, expected string) {\n\t\tt.Helper()\n\t\tt.Run(fmt.Sprintf(\"path=%s prefix=%s slashes=%s\", path, prefix, allowedSlashes), func(t *testing.T) {\n\t\t\tt.Helper()\n\t\t\tobserved, ok := stripDirPrefix(path, prefix, allowedSlashes)\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"Unexpected failure\")\n\t\t\t}\n\t\t\ttest.AssertEqualWithDiff(t, observed, expected)\n\t\t})\n\t}\n\n\texpectFailure := func(path string, prefix string, allowedSlashes string) {\n\t\tt.Helper()\n\t\tt.Run(fmt.Sprintf(\"path=%s prefix=%s slashes=%s\", path, prefix, allowedSlashes), func(t *testing.T) {\n\t\t\tt.Helper()\n\t\t\t_, ok := stripDirPrefix(path, prefix, allowedSlashes)\n\t\t\tif ok {\n\t\t\t\tt.Fatalf(\"Unexpected success\")\n\t\t\t}\n\t\t})\n\t}\n\n\t// Note: People sometimes set \"outdir\" to \"/\" and expect that to work:\n\t// https://github.com/evanw/esbuild/issues/3027\n\n\texpectSuccess(`/foo/bar/baz`, ``, `/`, `/foo/bar/baz`)\n\texpectSuccess(`/foo/bar/baz`, `/`, `/`, `foo/bar/baz`)\n\texpectSuccess(`/foo/bar/baz`, `/foo`, `/`, `bar/baz`)\n\texpectSuccess(`/foo/bar/baz`, `/foo/bar`, `/`, `baz`)\n\texpectSuccess(`/foo/bar/baz`, `/foo/bar/baz`, `/`, ``)\n\texpectSuccess(`/foo/bar//baz`, `/foo/bar`, `/`, `/baz`)\n\texpectSuccess(`C:\\foo\\bar\\baz`, ``, `\\/`, `C:\\foo\\bar\\baz`)\n\texpectSuccess(`C:\\foo\\bar\\baz`, `C:`, `\\/`, `foo\\bar\\baz`)\n\texpectSuccess(`C:\\foo\\bar\\baz`, `C:\\`, `\\/`, `foo\\bar\\baz`)\n\texpectSuccess(`C:\\foo\\bar\\baz`, `C:\\foo`, `\\/`, `bar\\baz`)\n\texpectSuccess(`C:\\foo\\bar\\baz`, `C:\\foo\\bar`, `\\/`, `baz`)\n\texpectSuccess(`C:\\foo\\bar\\baz`, `C:\\foo\\bar\\baz`, `\\/`, ``)\n\texpectSuccess(`C:\\foo\\bar\\\\baz`, `C:\\foo\\bar`, `\\/`, `\\baz`)\n\texpectSuccess(`C:\\foo\\bar/baz`, `C:\\foo\\bar`, `\\/`, `baz`)\n\n\texpectFailure(`/foo/bar`, `/foo/ba`, `/`)\n\texpectFailure(`/foo/bar`, `/fo`, `/`)\n\texpectFailure(`C:\\foo\\bar`, `C:\\foo\\ba`, `\\/`)\n\texpectFailure(`C:\\foo\\bar`, `C:\\fo`, `\\/`)\n\texpectFailure(`C:/foo/bar`, `C:\\foo`, `\\/`)\n}\n"
  },
  {
    "path": "pkg/api/api_js_table.go",
    "content": "// This file was automatically generated by \"js_table.ts\"\n\npackage api\n\nimport \"github.com/evanw/esbuild/internal/compat\"\n\ntype EngineName uint8\n\nconst (\n\tEngineChrome EngineName = iota\n\tEngineDeno\n\tEngineEdge\n\tEngineFirefox\n\tEngineHermes\n\tEngineIE\n\tEngineIOS\n\tEngineNode\n\tEngineOpera\n\tEngineRhino\n\tEngineSafari\n)\n\nfunc convertEngineName(engine EngineName) compat.Engine {\n\tswitch engine {\n\tcase EngineChrome:\n\t\treturn compat.Chrome\n\tcase EngineDeno:\n\t\treturn compat.Deno\n\tcase EngineEdge:\n\t\treturn compat.Edge\n\tcase EngineFirefox:\n\t\treturn compat.Firefox\n\tcase EngineHermes:\n\t\treturn compat.Hermes\n\tcase EngineIE:\n\t\treturn compat.IE\n\tcase EngineIOS:\n\t\treturn compat.IOS\n\tcase EngineNode:\n\t\treturn compat.Node\n\tcase EngineOpera:\n\t\treturn compat.Opera\n\tcase EngineRhino:\n\t\treturn compat.Rhino\n\tcase EngineSafari:\n\t\treturn compat.Safari\n\tdefault:\n\t\tpanic(\"Invalid engine name\")\n\t}\n}\n"
  },
  {
    "path": "pkg/api/api_test.go",
    "content": "package api_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/evanw/esbuild/internal/test\"\n\t\"github.com/evanw/esbuild/pkg/api\"\n)\n\nfunc TestFormatMessages(t *testing.T) {\n\tcheck := func(name string, opts api.FormatMessagesOptions, msg api.Message, expected string) {\n\t\tt.Helper()\n\t\tt.Run(name, func(t *testing.T) {\n\t\t\ttest.AssertEqualWithDiff(t, api.FormatMessages([]api.Message{msg}, opts)[0], expected)\n\t\t})\n\t}\n\n\tcheck(\"Error\", api.FormatMessagesOptions{Kind: api.ErrorMessage}, api.Message{Text: \"This is a test\"}, \"✘ [ERROR] This is a test\\n\\n\")\n\tcheck(\"Warning\", api.FormatMessagesOptions{Kind: api.WarningMessage}, api.Message{Text: \"This is a test\"}, \"▲ [WARNING] This is a test\\n\\n\")\n\n\tcheck(\"Basic location\",\n\t\tapi.FormatMessagesOptions{},\n\t\tapi.Message{Text: \"This is a test\", Location: &api.Location{\n\t\t\tFile:       \"some file.js\",\n\t\t\tLine:       100,\n\t\t\tColumn:     5, // 0-based\n\t\t\tLength:     3,\n\t\t\tLineText:   \"this.foo();\",\n\t\t\tSuggestion: \"bar\",\n\t\t}},\n\t\t`✘ [ERROR] This is a test\n\n    some file.js:100:5:\n      100 │ this.foo();\n          │      ~~~\n          ╵      bar\n\n`,\n\t)\n\n\tcheck(\"Unicode location\",\n\t\tapi.FormatMessagesOptions{\n\t\t\tKind: api.WarningMessage,\n\t\t},\n\t\tapi.Message{Text: \"This is a test\", Location: &api.Location{\n\t\t\tFile:       \"some file.js\",\n\t\t\tLine:       100,\n\t\t\tColumn:     17, // In UTF-8 bytes\n\t\t\tLength:     10, // In UTF-8 bytes\n\t\t\tLineText:   \"𝓉𝒽𝒾𝓈.𝒻ℴℴ();\",\n\t\t\tSuggestion: \"𝒷𝒶𝓇\",\n\t\t}},\n\t\t`▲ [WARNING] This is a test\n\n    some file.js:100:17:\n      100 │ 𝓉𝒽𝒾𝓈.𝒻ℴℴ();\n          │      ~~~\n          ╵      𝒷𝒶𝓇\n\n`,\n\t)\n\n\tcheck(\"Tab stop rendering\",\n\t\tapi.FormatMessagesOptions{\n\t\t\tKind: api.WarningMessage,\n\t\t},\n\t\tapi.Message{Text: \"This is a test\", Location: &api.Location{\n\t\t\tFile:     \"some file.js\",\n\t\t\tLine:     100,\n\t\t\tColumn:   6,\n\t\t\tLength:   4,\n\t\t\tLineText: \"0\\t1\\t23\\t45\\t678\",\n\t\t}},\n\t\t`▲ [WARNING] This is a test\n\n    some file.js:100:6:\n      100 │ 0 1 23  45  678\n          ╵       ~~~~~~\n\n`,\n\t)\n\n\tcheck(\"Truncated location tail, zero length\",\n\t\tapi.FormatMessagesOptions{\n\t\t\tTerminalWidth: 32,\n\t\t},\n\t\tapi.Message{Text: \"This is a test\", Location: &api.Location{\n\t\t\tFile:     \"some file.js\",\n\t\t\tLine:     100,\n\t\t\tColumn:   3,\n\t\t\tLength:   0,\n\t\t\tLineText: \"012345678 abcdefghi ABCDEFGHI 012345678 abcdefghi ABCDEFGHI\",\n\t\t}},\n\t\t`✘ [ERROR] This is a test\n\n    some file.js:100:3:\n      100 │ 012345678 abcdefg...\n          ╵    ^\n\n`,\n\t)\n\n\tcheck(\"Truncated location tail, nonzero length\",\n\t\tapi.FormatMessagesOptions{\n\t\t\tTerminalWidth: 32,\n\t\t},\n\t\tapi.Message{Text: \"This is a test\", Location: &api.Location{\n\t\t\tFile:     \"some file.js\",\n\t\t\tLine:     100,\n\t\t\tColumn:   3,\n\t\t\tLength:   6,\n\t\t\tLineText: \"012345678 abcdefghi ABCDEFGHI 012345678 abcdefghi ABCDEFGHI\",\n\t\t}},\n\t\t`✘ [ERROR] This is a test\n\n    some file.js:100:3:\n      100 │ 012345678 abcdefg...\n          ╵    ~~~~~~\n\n`,\n\t)\n\n\tcheck(\"Truncated location tail, truncated length\",\n\t\tapi.FormatMessagesOptions{\n\t\t\tTerminalWidth: 32,\n\t\t},\n\t\tapi.Message{Text: \"This is a test\", Location: &api.Location{\n\t\t\tFile:     \"some file.js\",\n\t\t\tLine:     100,\n\t\t\tColumn:   3,\n\t\t\tLength:   100,\n\t\t\tLineText: \"012345678 abcdefghi ABCDEFGHI 012345678 abcdefghi ABCDEFGHI\",\n\t\t}},\n\t\t`✘ [ERROR] This is a test\n\n    some file.js:100:3:\n      100 │ 012345678 abcdefg...\n          ╵    ~~~~~~~~~~~~~~\n\n`,\n\t)\n\n\tcheck(\"Truncated location head, zero length\",\n\t\tapi.FormatMessagesOptions{\n\t\t\tTerminalWidth: 32,\n\t\t},\n\t\tapi.Message{Text: \"This is a test\", Location: &api.Location{\n\t\t\tFile:     \"some file.js\",\n\t\t\tLine:     100,\n\t\t\tColumn:   200,\n\t\t\tLength:   0,\n\t\t\tLineText: \"012345678 abcdefghi ABCDEFGHI 012345678 abcdefghi ABCDEFGHI\",\n\t\t}},\n\t\t`✘ [ERROR] This is a test\n\n    some file.js:100:59:\n      100 │ ...defghi ABCDEFGHI\n          ╵                    ^\n\n`,\n\t)\n\n\tcheck(\"Truncated location head, nonzero length\",\n\t\tapi.FormatMessagesOptions{\n\t\t\tTerminalWidth: 32,\n\t\t},\n\t\tapi.Message{Text: \"This is a test\", Location: &api.Location{\n\t\t\tFile:     \"some file.js\",\n\t\t\tLine:     100,\n\t\t\tColumn:   50,\n\t\t\tLength:   200,\n\t\t\tLineText: \"012345678 abcdefghi ABCDEFGHI 012345678 abcdefghi ABCDEFGHI\",\n\t\t}},\n\t\t`✘ [ERROR] This is a test\n\n    some file.js:100:50:\n      100 │ ...cdefghi ABCDEFGHI\n          ╵            ~~~~~~~~~\n\n`,\n\t)\n\n\tcheck(\"Truncated location head and tail, truncated length\",\n\t\tapi.FormatMessagesOptions{\n\t\t\tTerminalWidth: 32,\n\t\t},\n\t\tapi.Message{Text: \"This is a test\", Location: &api.Location{\n\t\t\tFile:     \"some file.js\",\n\t\t\tLine:     100,\n\t\t\tColumn:   30,\n\t\t\tLength:   30,\n\t\t\tLineText: \"012345678 abcdefghi ABCDEFGHI 012345678 abcdefghi ABCDEFGHI\",\n\t\t}},\n\t\t`✘ [ERROR] This is a test\n\n    some file.js:100:30:\n      100 │ ... 012345678 abc...\n          ╵     ~~~~~~~~~~~~~\n\n`,\n\t)\n\n\tcheck(\"Truncated location head and tail, non-truncated length\",\n\t\tapi.FormatMessagesOptions{\n\t\t\tTerminalWidth: 32,\n\t\t},\n\t\tapi.Message{Text: \"This is a test\", Location: &api.Location{\n\t\t\tFile:     \"some file.js\",\n\t\t\tLine:     100,\n\t\t\tColumn:   30,\n\t\t\tLength:   9,\n\t\t\tLineText: \"012345678 abcdefghi ABCDEFGHI 012345678 abcdefghi ABCDEFGHI\",\n\t\t}},\n\t\t`✘ [ERROR] This is a test\n\n    some file.js:100:30:\n      100 │ ...HI 012345678 a...\n          ╵       ~~~~~~~~~\n\n`,\n\t)\n\n\tcheck(\"Multi-line line text\",\n\t\tapi.FormatMessagesOptions{},\n\t\tapi.Message{Text: \"ReferenceError: Cannot access 'foo' before initialization\", Location: &api.Location{\n\t\t\tFile:   \"some file.js\",\n\t\t\tLine:   100,\n\t\t\tColumn: 2,\n\t\t\tLineText: `  foo();\n    at ModuleJob.run (node:internal/modules/esm/module_job:185:25)\n    at async Promise.all (index 0)\n    at async ESMLoader.import (node:internal/modules/esm/loader:281:24)\n    at async loadESM (node:internal/process/esm_loader:88:5)\n    at async handleMainPromise (node:internal/modules/run_main:65:12)`,\n\t\t}},\n\t\t`✘ [ERROR] ReferenceError: Cannot access 'foo' before initialization\n\n    some file.js:100:2:\n      100 │   foo();\n          ╵   ^\n\n    at ModuleJob.run (node:internal/modules/esm/module_job:185:25)\n    at async Promise.all (index 0)\n    at async ESMLoader.import (node:internal/modules/esm/loader:281:24)\n    at async loadESM (node:internal/process/esm_loader:88:5)\n    at async handleMainPromise (node:internal/modules/run_main:65:12)\n\n`,\n\t)\n\n\tcheck(\"Note formatting\",\n\t\tapi.FormatMessagesOptions{\n\t\t\tTerminalWidth: 40,\n\t\t},\n\t\tapi.Message{\n\t\t\tText: \"Why would you do this?\",\n\t\t\tLocation: &api.Location{\n\t\t\t\tFile:     \"some file.js\",\n\t\t\t\tLine:     1,\n\t\t\t\tColumn:   10,\n\t\t\t\tLength:   16,\n\t\t\t\tLineText: \"let ten = +([+!+[]]+[+[]]);\",\n\t\t\t},\n\t\t\tNotes: []api.Note{{\n\t\t\t\tText: \"This is 1:\",\n\t\t\t\tLocation: &api.Location{\n\t\t\t\t\tFile:       \"some file.js\",\n\t\t\t\t\tLine:       1,\n\t\t\t\t\tColumn:     12,\n\t\t\t\t\tLength:     7,\n\t\t\t\t\tLineText:   \"let ten = +([+!+[]]+[+[]]);\",\n\t\t\t\t\tSuggestion: \"'1'\",\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tText: \"This is 0:\",\n\t\t\t\tLocation: &api.Location{\n\t\t\t\t\tFile:       \"some file.js\",\n\t\t\t\t\tLine:       1,\n\t\t\t\t\tColumn:     20,\n\t\t\t\t\tLength:     5,\n\t\t\t\t\tLineText:   \"let ten = +([+!+[]]+[+[]]);\",\n\t\t\t\t\tSuggestion: \"'0'\",\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tText: \"The number 0 is created by +[], where [] is the empty array and + is the unary plus, \" +\n\t\t\t\t\t\"used to convert the right side to a numeric value. The number 1 is formed as +!+[], where \" +\n\t\t\t\t\t\"the boolean value true is converted into the numeric value 1 by the prepended plus sign.\",\n\t\t\t}},\n\t\t},\n\t\t`✘ [ERROR] Why would you do this?\n\n    some file.js:1:10:\n      1 │ let ten = +([+!+[]]+[+[]]);\n        ╵           ~~~~~~~~~~~~~~~~\n\n  This is 1:\n\n    some file.js:1:12:\n      1 │ let ten = +([+!+[]]+[+[]]);\n        │             ~~~~~~~\n        ╵             '1'\n\n  This is 0:\n\n    some file.js:1:20:\n      1 │ let ten = +([+!+[]]+[+[]]);\n        │                     ~~~~~\n        ╵                     '0'\n\n  The number 0 is created by +[], where\n  [] is the empty array and + is the\n  unary plus, used to convert the right\n  side to a numeric value. The number 1\n  is formed as +!+[], where the boolean\n  value true is converted into the\n  numeric value 1 by the prepended plus\n  sign.\n\n`,\n\t)\n}\n"
  },
  {
    "path": "pkg/api/favicon.go",
    "content": "package api\n\n// This is the \"favicon.ico\" file used by esbuild's built-in development server\nvar favicon_ico_gz = []byte{\n\t0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x63, 0x60, 0x60, 0x64, 0x60, 0x62,\n\t0x10, 0x10, 0x60, 0x00, 0xD2, 0x0A, 0x0C, 0x19, 0x2C, 0x0C, 0x0C, 0x6A, 0x0C, 0x0C, 0x0C, 0x0A,\n\t0x0A, 0x10, 0xBE, 0x86, 0x20, 0x03, 0x43, 0x1F, 0x50, 0x4C, 0x03, 0x28, 0x26, 0x00, 0x12, 0x67,\n\t0x80, 0x88, 0x13, 0x04, 0xE7, 0xFF, 0xFF, 0x27, 0x09, 0xD3, 0x4A, 0xFF, 0xC9, 0xEF, 0xFF, 0x59,\n\t0x97, 0x9F, 0x81, 0xAB, 0x63, 0x5B, 0x72, 0xF2, 0x3F, 0xC3, 0x99, 0xDF, 0x44, 0xEB, 0xE7, 0x29,\n\t0xE9, 0xF9, 0x2F, 0xAE, 0xA8, 0x02, 0xD6, 0xC7, 0x74, 0xE0, 0xCD, 0x7F, 0x09, 0x45, 0xE5, 0xFF,\n\t0x02, 0xA1, 0xA9, 0x98, 0x66, 0xE0, 0xB1, 0x5F, 0xC8, 0x27, 0x12, 0x6E, 0x06, 0xFB, 0xEC, 0x7D,\n\t0xFF, 0x25, 0xE4, 0x14, 0x30, 0xCD, 0xC0, 0xE7, 0x7F, 0xA0, 0x19, 0xC2, 0x0E, 0xDE, 0x60, 0x33,\n\t0x58, 0x36, 0x5C, 0xFF, 0xCF, 0x31, 0x79, 0xF3, 0x7F, 0x49, 0x49, 0xC9, 0xFF, 0xFC, 0xB1, 0xF9,\n\t0x44, 0xE9, 0x47, 0xB6, 0x93, 0xF1, 0xD8, 0x17, 0x14, 0xF7, 0x10, 0xD2, 0x4F, 0x94, 0x5E, 0x02,\n\t0xFA, 0x05, 0x42, 0x53, 0xC0, 0x7E, 0x85, 0xE9, 0xC7, 0xD0, 0x4B, 0xCB, 0xF8, 0xA7, 0x85, 0xFE,\n\t0x9A, 0x99, 0x68, 0x78, 0x56, 0x3D, 0xF9, 0xFA, 0xB1, 0xE8, 0x25, 0x5A, 0x3F, 0x0E, 0xBD, 0x44,\n\t0xE9, 0xC7, 0xA3, 0x97, 0xA0, 0x7E, 0x02, 0x7A, 0x29, 0x00, 0x1A, 0xD0, 0x32, 0xC6, 0x81, 0xD8,\n\t0x72, 0x86, 0xDC, 0xF8, 0xA6, 0x34, 0x7D, 0x8C, 0xDA, 0x3F, 0x6A, 0x3F, 0x01, 0xFB, 0x99, 0x77,\n\t0x3C, 0xFA, 0x2F, 0xEC, 0x1E, 0x0C, 0xA6, 0xD1, 0xE5, 0x58, 0xD7, 0x5C, 0x06, 0xCB, 0x31, 0x1D,\n\t0xF9, 0x48, 0x13, 0xFB, 0x41, 0x76, 0x8A, 0x19, 0x98, 0x81, 0xEB, 0x09, 0x11, 0x1B, 0x57, 0x14,\n\t0x7B, 0x40, 0x76, 0x4B, 0xA8, 0xA8, 0x63, 0x95, 0xA3, 0x85, 0xFD, 0xE8, 0xF6, 0xE0, 0x93, 0xA3,\n\t0x76, 0xF8, 0x53, 0xCD, 0x0D, 0x64, 0xA6, 0x3F, 0xAA, 0xB9, 0x81, 0x82, 0xF4, 0x4F, 0x15, 0x37,\n\t0x50, 0x98, 0xFF, 0xD8, 0x16, 0x1E, 0x85, 0xDB, 0x01, 0xC2, 0x02, 0x71, 0x05, 0x70, 0x39, 0x8E,\n\t0x69, 0xDB, 0x71, 0xCA, 0x0D, 0x75, 0xFF, 0x0F, 0x64, 0xFC, 0x0F, 0x64, 0xFA, 0x1F, 0xE8, 0xFC,\n\t0x3F, 0xD0, 0xE5, 0xDF, 0x40, 0x97, 0xFF, 0xA3, 0xF5, 0xEF, 0xA8, 0xFD, 0x44, 0x61, 0x8C, 0xBE,\n\t0x0C, 0x36, 0x3C, 0xA7, 0x7E, 0xE0, 0xEC, 0x9F, 0x53, 0x4F, 0xD3, 0xF6, 0x3F, 0x35, 0xEC, 0xA6,\n\t0x89, 0xFD, 0x73, 0x48, 0xEB, 0x63, 0x51, 0xD5, 0xFE, 0x39, 0xA4, 0xF7, 0xEF, 0xA8, 0x66, 0xFF,\n\t0x1C, 0xF2, 0xFA, 0x96, 0x54, 0xB1, 0x7F, 0x0E, 0xF9, 0xFD, 0x5A, 0x8A, 0xED, 0x9F, 0x43, 0x59,\n\t0x9F, 0x9A, 0x22, 0xFB, 0xE7, 0x50, 0xDE, 0x9F, 0x27, 0xDB, 0xFE, 0x39, 0x34, 0x1B, 0x4B, 0x18,\n\t0xCE, 0x00, 0x00, 0xDA, 0xEB, 0x61, 0xFD, 0xB6, 0x15, 0x00, 0x00,\n}\n"
  },
  {
    "path": "pkg/api/serve_other.go",
    "content": "//go:build !js || !wasm\n// +build !js !wasm\n\npackage api\n\n// This file implements the \"Serve()\" function in esbuild's public API. It\n// provides a basic web server that can serve a directory tree over HTTP. When\n// a directory is visited the \"index.html\" will be served if present, otherwise\n// esbuild will automatically generate a directory listing page with links for\n// each file in the directory. If there is a build configured that generates\n// output files, those output files are not written to disk but are instead\n// \"overlayed\" virtually on top of the real file system. The server responds to\n// HTTP requests for output files from the build with the latest in-memory\n// build results.\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"path\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/evanw/esbuild/internal/fs\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n)\n\n////////////////////////////////////////////////////////////////////////////////\n// Serve API\n\ntype apiHandler struct {\n\tonRequest        func(ServeOnRequestArgs)\n\trebuild          func() BuildResult\n\tstop             func()\n\tfs               fs.FS\n\tabsOutputDir     string\n\toutdirPathPrefix string\n\tpublicPath       string\n\tservedir         string\n\tkeyfileToLower   string\n\tcertfileToLower  string\n\tfallback         string\n\thosts            []string\n\tcorsOrigin       []string\n\tserveWaitGroup   sync.WaitGroup\n\tactiveStreams    []chan serverSentEvent\n\tcurrentHashes    map[string]string\n\tmutex            sync.Mutex\n}\n\ntype serverSentEvent struct {\n\tevent string\n\tdata  string\n}\n\nfunc escapeForHTML(text string) string {\n\ttext = strings.ReplaceAll(text, \"&\", \"&amp;\")\n\ttext = strings.ReplaceAll(text, \"<\", \"&lt;\")\n\ttext = strings.ReplaceAll(text, \">\", \"&gt;\")\n\treturn text\n}\n\nfunc escapeForAttribute(text string) string {\n\ttext = escapeForHTML(text)\n\ttext = strings.ReplaceAll(text, \"\\\"\", \"&quot;\")\n\ttext = strings.ReplaceAll(text, \"'\", \"&apos;\")\n\treturn text\n}\n\nfunc (h *apiHandler) notifyRequest(duration time.Duration, req *http.Request, status int) {\n\tif h.onRequest != nil {\n\t\th.onRequest(ServeOnRequestArgs{\n\t\t\tRemoteAddress: req.RemoteAddr,\n\t\t\tMethod:        req.Method,\n\t\t\tPath:          req.URL.Path,\n\t\t\tStatus:        status,\n\t\t\tTimeInMS:      int(duration.Milliseconds()),\n\t\t})\n\t}\n}\n\nfunc errorsToString(errors []Message) string {\n\tstderrOptions := logger.OutputOptions{IncludeSource: true}\n\tterminalOptions := logger.TerminalInfo{}\n\tsb := strings.Builder{}\n\tlimit := 5\n\tfor i, msg := range convertMessagesToInternal(nil, logger.Error, errors) {\n\t\tif i == limit {\n\t\t\tsb.WriteString(fmt.Sprintf(\"%d out of %d errors shown\\n\", limit, len(errors)))\n\t\t\tbreak\n\t\t}\n\t\tsb.WriteString(msg.String(stderrOptions, terminalOptions))\n\t}\n\treturn sb.String()\n}\n\nfunc (h *apiHandler) ServeHTTP(res http.ResponseWriter, req *http.Request) {\n\tstart := time.Now()\n\n\t// Add CORS headers to all relevant requests\n\tif origin := req.Header.Get(\"Origin\"); origin != \"\" {\n\t\tfor _, allowed := range h.corsOrigin {\n\t\t\tif allowed == \"*\" {\n\t\t\t\tres.Header().Set(\"Access-Control-Allow-Origin\", \"*\")\n\t\t\t\tbreak\n\t\t\t} else if star := strings.IndexByte(allowed, '*'); star >= 0 {\n\t\t\t\tprefix, suffix := allowed[:star], allowed[star+1:]\n\t\t\t\tif len(origin) >= len(prefix)+len(suffix) && strings.HasPrefix(origin, prefix) && strings.HasSuffix(origin, suffix) {\n\t\t\t\t\tres.Header().Set(\"Access-Control-Allow-Origin\", origin)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t} else if origin == allowed {\n\t\t\t\tres.Header().Set(\"Access-Control-Allow-Origin\", origin)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\t// HEAD requests omit the body\n\tmaybeWriteResponseBody := func(bytes []byte) { res.Write(bytes) }\n\tisHEAD := req.Method == \"HEAD\"\n\tif isHEAD {\n\t\tmaybeWriteResponseBody = func([]byte) { res.Write(nil) }\n\t}\n\n\t// Check the \"Host\" header to prevent DNS rebinding attacks\n\tif strings.ContainsRune(req.Host, ':') {\n\t\t// Try to strip off the port number\n\t\tif host, _, err := net.SplitHostPort(req.Host); err == nil {\n\t\t\treq.Host = host\n\t\t}\n\t}\n\tif req.Host != \"localhost\" {\n\t\tok := false\n\t\tfor _, allowed := range h.hosts {\n\t\t\tif req.Host == allowed {\n\t\t\t\tok = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !ok {\n\t\t\tgo h.notifyRequest(time.Since(start), req, http.StatusForbidden)\n\t\t\tres.WriteHeader(http.StatusForbidden)\n\t\t\tmaybeWriteResponseBody([]byte(fmt.Sprintf(\"403 - Forbidden: The host %q is not allowed\", req.Host)))\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Special-case the esbuild event stream\n\tif req.Method == \"GET\" && req.URL.Path == \"/esbuild\" && req.Header.Get(\"Accept\") == \"text/event-stream\" {\n\t\th.serveEventStream(start, req, res)\n\t\treturn\n\t}\n\n\t// Handle GET and HEAD requests\n\tif (isHEAD || req.Method == \"GET\") && strings.HasPrefix(req.URL.Path, \"/\") {\n\t\tqueryPath := path.Clean(req.URL.Path)[1:]\n\t\tresult := h.rebuild()\n\n\t\t// Requests fail if the build had errors\n\t\tif len(result.Errors) > 0 {\n\t\t\tres.Header().Set(\"Content-Type\", \"text/plain; charset=utf-8\")\n\t\t\tgo h.notifyRequest(time.Since(start), req, http.StatusServiceUnavailable)\n\t\t\tres.WriteHeader(http.StatusServiceUnavailable)\n\t\t\tmaybeWriteResponseBody([]byte(errorsToString(result.Errors)))\n\t\t\treturn\n\t\t}\n\n\t\ttype fileToServe struct {\n\t\t\tabsPath  string\n\t\t\tcontents fs.OpenedFile\n\t\t}\n\n\t\tvar kind fs.EntryKind\n\t\tvar file fileToServe\n\t\tdirEntries := make(map[string]bool)\n\t\tfileEntries := make(map[string]bool)\n\n\t\t// Check for a match with the results if we're within the output directory\n\t\tif outdirQueryPath, ok := stripDirPrefix(queryPath, h.outdirPathPrefix, \"/\"); ok {\n\t\t\tresultKind, inMemoryBytes, absPath, isImplicitIndexHTML := h.matchQueryPathToResult(outdirQueryPath, &result, dirEntries, fileEntries)\n\t\t\tkind = resultKind\n\t\t\tfile = fileToServe{\n\t\t\t\tabsPath:  absPath,\n\t\t\t\tcontents: &fs.InMemoryOpenedFile{Contents: inMemoryBytes},\n\t\t\t}\n\t\t\tif isImplicitIndexHTML {\n\t\t\t\tqueryPath = path.Join(queryPath, \"index.html\")\n\t\t\t}\n\t\t} else {\n\t\t\t// Create a fake directory entry for the output path so that it appears to be a real directory\n\t\t\tp := h.outdirPathPrefix\n\t\t\tfor p != \"\" {\n\t\t\t\tvar dir string\n\t\t\t\tvar base string\n\t\t\t\tif slash := strings.IndexByte(p, '/'); slash == -1 {\n\t\t\t\t\tbase = p\n\t\t\t\t} else {\n\t\t\t\t\tdir = p[:slash]\n\t\t\t\t\tbase = p[slash+1:]\n\t\t\t\t}\n\t\t\t\tif dir == queryPath {\n\t\t\t\t\tkind = fs.DirEntry\n\t\t\t\t\tdirEntries[base] = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tp = dir\n\t\t\t}\n\t\t}\n\n\t\t// Check for a file in the \"servedir\" directory\n\t\tif h.servedir != \"\" && kind != fs.FileEntry {\n\t\t\tabsPath := h.fs.Join(h.servedir, queryPath)\n\t\t\tif absDir := h.fs.Dir(absPath); absDir != absPath {\n\t\t\t\tif entries, err, _ := h.fs.ReadDirectory(absDir); err == nil {\n\t\t\t\t\tif entry, _ := entries.Get(h.fs.Base(absPath)); entry != nil && entry.Kind(h.fs) == fs.FileEntry {\n\t\t\t\t\t\tif h.keyfileToLower != \"\" || h.certfileToLower != \"\" {\n\t\t\t\t\t\t\tif toLower := strings.ToLower(absPath); toLower == h.keyfileToLower || toLower == h.certfileToLower {\n\t\t\t\t\t\t\t\t// Don't serve the HTTPS key or certificate. This uses a case-\n\t\t\t\t\t\t\t\t// insensitive check because some file systems are case-sensitive.\n\t\t\t\t\t\t\t\tgo h.notifyRequest(time.Since(start), req, http.StatusForbidden)\n\t\t\t\t\t\t\t\tres.WriteHeader(http.StatusForbidden)\n\t\t\t\t\t\t\t\tmaybeWriteResponseBody([]byte(\"403 - Forbidden\"))\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif contents, err, _ := h.fs.OpenFile(absPath); err == nil {\n\t\t\t\t\t\t\tdefer contents.Close()\n\t\t\t\t\t\t\tfile = fileToServe{absPath: absPath, contents: contents}\n\t\t\t\t\t\t\tkind = fs.FileEntry\n\t\t\t\t\t\t} else if err != syscall.ENOENT {\n\t\t\t\t\t\t\tgo h.notifyRequest(time.Since(start), req, http.StatusInternalServerError)\n\t\t\t\t\t\t\tres.WriteHeader(http.StatusInternalServerError)\n\t\t\t\t\t\t\tmaybeWriteResponseBody([]byte(fmt.Sprintf(\"500 - Internal server error: %s\", err.Error())))\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Check for a directory in the \"servedir\" directory\n\t\tvar servedirIndexName string\n\t\tif h.servedir != \"\" && kind != fs.FileEntry {\n\t\t\tif entries, err, _ := h.fs.ReadDirectory(h.fs.Join(h.servedir, queryPath)); err == nil {\n\t\t\t\tkind = fs.DirEntry\n\t\t\t\tfor _, name := range entries.SortedKeys() {\n\t\t\t\t\tentry, _ := entries.Get(name)\n\t\t\t\t\tswitch entry.Kind(h.fs) {\n\t\t\t\t\tcase fs.DirEntry:\n\t\t\t\t\t\tdirEntries[name] = true\n\t\t\t\t\tcase fs.FileEntry:\n\t\t\t\t\t\tfileEntries[name] = true\n\t\t\t\t\t\tif name == \"index.html\" {\n\t\t\t\t\t\t\tservedirIndexName = name\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if err != syscall.ENOENT {\n\t\t\t\tgo h.notifyRequest(time.Since(start), req, http.StatusInternalServerError)\n\t\t\t\tres.WriteHeader(http.StatusInternalServerError)\n\t\t\t\tmaybeWriteResponseBody([]byte(fmt.Sprintf(\"500 - Internal server error: %s\", err.Error())))\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// Redirect to a trailing slash for directories\n\t\tif kind == fs.DirEntry && !strings.HasSuffix(req.URL.Path, \"/\") {\n\t\t\tres.Header().Set(\"Location\", path.Clean(req.URL.Path)+\"/\")\n\t\t\tgo h.notifyRequest(time.Since(start), req, http.StatusFound)\n\t\t\tres.WriteHeader(http.StatusFound)\n\t\t\tmaybeWriteResponseBody(nil)\n\t\t\treturn\n\t\t}\n\n\t\t// Serve an \"index.html\" file if present\n\t\tif kind == fs.DirEntry && servedirIndexName != \"\" {\n\t\t\tqueryPath += \"/\" + servedirIndexName\n\t\t\tabsPath := h.fs.Join(h.servedir, queryPath)\n\t\t\tif contents, err, _ := h.fs.OpenFile(absPath); err == nil {\n\t\t\t\tdefer contents.Close()\n\t\t\t\tfile = fileToServe{absPath: absPath, contents: contents}\n\t\t\t\tkind = fs.FileEntry\n\t\t\t} else if err != syscall.ENOENT {\n\t\t\t\tgo h.notifyRequest(time.Since(start), req, http.StatusInternalServerError)\n\t\t\t\tres.WriteHeader(http.StatusInternalServerError)\n\t\t\t\tmaybeWriteResponseBody([]byte(fmt.Sprintf(\"500 - Internal server error: %s\", err.Error())))\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// Serve the fallback HTML page if one was provided\n\t\tif kind != fs.FileEntry && h.fallback != \"\" {\n\t\t\tif contents, err, _ := h.fs.OpenFile(h.fallback); err == nil {\n\t\t\t\tdefer contents.Close()\n\t\t\t\tfile = fileToServe{absPath: h.fallback, contents: contents}\n\t\t\t\tkind = fs.FileEntry\n\t\t\t} else if err != syscall.ENOENT {\n\t\t\t\tgo h.notifyRequest(time.Since(start), req, http.StatusInternalServerError)\n\t\t\t\tres.WriteHeader(http.StatusInternalServerError)\n\t\t\t\tmaybeWriteResponseBody([]byte(fmt.Sprintf(\"500 - Internal server error: %s\", err.Error())))\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// Serve a file\n\t\tif kind == fs.FileEntry {\n\t\t\t// Default to serving the whole file\n\t\t\tstatus := http.StatusOK\n\t\t\tfileContentsLen := file.contents.Len()\n\t\t\tbegin := 0\n\t\t\tend := fileContentsLen\n\t\t\tisRange := false\n\n\t\t\t// Handle range requests so that video playback works in Safari\n\t\t\tif rangeBegin, rangeEnd, ok := parseRangeHeader(req.Header.Get(\"Range\"), fileContentsLen); ok && rangeBegin < rangeEnd {\n\t\t\t\t// Note: The content range is inclusive so subtract 1 from the end\n\t\t\t\tisRange = true\n\t\t\t\tbegin = rangeBegin\n\t\t\t\tend = rangeEnd\n\t\t\t\tstatus = http.StatusPartialContent\n\t\t\t}\n\n\t\t\t// Try to read the range from the file, which may fail\n\t\t\tfileBytes, err := file.contents.Read(begin, end)\n\t\t\tif err != nil {\n\t\t\t\tgo h.notifyRequest(time.Since(start), req, http.StatusInternalServerError)\n\t\t\t\tres.WriteHeader(http.StatusInternalServerError)\n\t\t\t\tmaybeWriteResponseBody([]byte(fmt.Sprintf(\"500 - Internal server error: %s\", err.Error())))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// If we get here, the request was successful\n\t\t\tif contentType := helpers.MimeTypeByExtension(h.fs.Ext(file.absPath)); contentType != \"\" {\n\t\t\t\tres.Header().Set(\"Content-Type\", contentType)\n\t\t\t} else {\n\t\t\t\tres.Header().Set(\"Content-Type\", \"application/octet-stream\")\n\t\t\t}\n\t\t\tif isRange {\n\t\t\t\tres.Header().Set(\"Content-Range\", fmt.Sprintf(\"bytes %d-%d/%d\", begin, end-1, fileContentsLen))\n\t\t\t}\n\t\t\tres.Header().Set(\"Content-Length\", fmt.Sprintf(\"%d\", len(fileBytes)))\n\t\t\tgo h.notifyRequest(time.Since(start), req, status)\n\t\t\tres.WriteHeader(status)\n\t\t\tmaybeWriteResponseBody(fileBytes)\n\t\t\treturn\n\t\t}\n\n\t\t// Serve a directory listing\n\t\tif kind == fs.DirEntry {\n\t\t\thtml := respondWithDirList(queryPath, dirEntries, fileEntries)\n\t\t\tres.Header().Set(\"Content-Type\", \"text/html; charset=utf-8\")\n\t\t\tres.Header().Set(\"Content-Length\", fmt.Sprintf(\"%d\", len(html)))\n\t\t\tgo h.notifyRequest(time.Since(start), req, http.StatusOK)\n\t\t\tmaybeWriteResponseBody(html)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Satisfy requests for \"favicon.ico\" to avoid errors in Firefox developer tools\n\tif req.Method == \"GET\" && req.URL.Path == \"/favicon.ico\" {\n\t\tfor _, encoding := range strings.Split(req.Header.Get(\"Accept-Encoding\"), \",\") {\n\t\t\tif semi := strings.IndexByte(encoding, ';'); semi >= 0 {\n\t\t\t\tencoding = encoding[:semi]\n\t\t\t}\n\t\t\tif strings.TrimSpace(encoding) == \"gzip\" {\n\t\t\t\tres.Header().Set(\"Content-Encoding\", \"gzip\")\n\t\t\t\tres.Header().Set(\"Content-Type\", \"image/vnd.microsoft.icon\")\n\t\t\t\tgo h.notifyRequest(time.Since(start), req, http.StatusOK)\n\t\t\t\tmaybeWriteResponseBody(favicon_ico_gz)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Default to a 404\n\tres.Header().Set(\"Content-Type\", \"text/plain; charset=utf-8\")\n\tgo h.notifyRequest(time.Since(start), req, http.StatusNotFound)\n\tres.WriteHeader(http.StatusNotFound)\n\tmaybeWriteResponseBody([]byte(\"404 - Not Found\"))\n}\n\n// This exposes an event stream to clients using server-sent events:\n// https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events\nfunc (h *apiHandler) serveEventStream(start time.Time, req *http.Request, res http.ResponseWriter) {\n\tif flusher, ok := res.(http.Flusher); ok {\n\t\tif closer, ok := res.(http.CloseNotifier); ok {\n\t\t\t// Add a new stream to the array of active streams\n\t\t\tstream := make(chan serverSentEvent)\n\t\t\th.mutex.Lock()\n\t\t\th.activeStreams = append(h.activeStreams, stream)\n\t\t\th.mutex.Unlock()\n\n\t\t\t// Start the event stream\n\t\t\tres.Header().Set(\"Content-Type\", \"text/event-stream\")\n\t\t\tres.Header().Set(\"Connection\", \"keep-alive\")\n\t\t\tres.Header().Set(\"Cache-Control\", \"no-cache\")\n\t\t\tgo h.notifyRequest(time.Since(start), req, http.StatusOK)\n\t\t\tres.WriteHeader(http.StatusOK)\n\t\t\tres.Write([]byte(\"retry: 500\\n\"))\n\t\t\tflusher.Flush()\n\n\t\t\t// Send incoming messages over the stream\n\t\t\tstreamWasClosed := make(chan struct{}, 1)\n\t\t\tgo func() {\n\t\t\t\tfor {\n\t\t\t\t\tvar msg []byte\n\t\t\t\t\tselect {\n\t\t\t\t\tcase next, ok := <-stream:\n\t\t\t\t\t\tif !ok {\n\t\t\t\t\t\t\tstreamWasClosed <- struct{}{}\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmsg = []byte(fmt.Sprintf(\"event: %s\\ndata: %s\\n\\n\", next.event, next.data))\n\t\t\t\t\tcase <-time.After(30 * time.Second):\n\t\t\t\t\t\t// Send an occasional keep-alive\n\t\t\t\t\t\tmsg = []byte(\":\\n\\n\")\n\t\t\t\t\t}\n\t\t\t\t\tif _, err := res.Write(msg); err != nil {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tflusher.Flush()\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\t// When the stream is closed (either by them or by us), remove it\n\t\t\t// from the array and end the response body to clean up resources\n\t\t\tselect {\n\t\t\tcase <-closer.CloseNotify():\n\t\t\tcase <-streamWasClosed:\n\t\t\t}\n\t\t\th.mutex.Lock()\n\t\t\tfor i := range h.activeStreams {\n\t\t\t\tif h.activeStreams[i] == stream {\n\t\t\t\t\tend := len(h.activeStreams) - 1\n\t\t\t\t\th.activeStreams[i] = h.activeStreams[end]\n\t\t\t\t\th.activeStreams = h.activeStreams[:end]\n\n\t\t\t\t\t// Only close the stream if it's present in the list of active\n\t\t\t\t\t// streams. Stopping the server can also call close on this\n\t\t\t\t\t// stream and Go only lets you close a channel once before\n\t\t\t\t\t// panicking, so we don't want to close it twice.\n\t\t\t\t\tclose(stream)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\th.mutex.Unlock()\n\t\t\treturn\n\t\t}\n\t}\n\n\t// If we get here, then event streaming isn't possible\n\tgo h.notifyRequest(time.Since(start), req, http.StatusInternalServerError)\n\tres.WriteHeader(http.StatusInternalServerError)\n\tres.Write([]byte(\"500 - Event stream error\"))\n}\n\nfunc (h *apiHandler) broadcastBuildResult(result BuildResult, newHashes map[string]string) {\n\th.mutex.Lock()\n\n\tvar added []string\n\tvar removed []string\n\tvar updated []string\n\n\turlForPath := func(absPath string) (string, bool) {\n\t\tif relPath, ok := stripDirPrefix(absPath, h.absOutputDir, \"\\\\/\"); ok {\n\t\t\trelPath = strings.ReplaceAll(relPath, \"\\\\\", \"/\")\n\t\t\trelPath = path.Join(h.outdirPathPrefix, relPath)\n\t\t\tpublicPath := h.publicPath\n\t\t\tslash := \"/\"\n\t\t\tif publicPath != \"\" && strings.HasSuffix(h.publicPath, \"/\") {\n\t\t\t\tslash = \"\"\n\t\t\t}\n\t\t\treturn fmt.Sprintf(\"%s%s%s\", publicPath, slash, relPath), true\n\t\t}\n\t\treturn \"\", false\n\t}\n\n\t// Diff the old and new states, but only if the build succeeded. We shouldn't\n\t// make it appear as if all files were removed when there is a build error.\n\tif len(result.Errors) == 0 {\n\t\toldHashes := h.currentHashes\n\t\th.currentHashes = newHashes\n\n\t\tfor absPath, newHash := range newHashes {\n\t\t\tif oldHash, ok := oldHashes[absPath]; !ok {\n\t\t\t\tif url, ok := urlForPath(absPath); ok {\n\t\t\t\t\tadded = append(added, url)\n\t\t\t\t}\n\t\t\t} else if newHash != oldHash {\n\t\t\t\tif url, ok := urlForPath(absPath); ok {\n\t\t\t\t\tupdated = append(updated, url)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor absPath := range oldHashes {\n\t\t\tif _, ok := newHashes[absPath]; !ok {\n\t\t\t\tif url, ok := urlForPath(absPath); ok {\n\t\t\t\t\tremoved = append(removed, url)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Only notify listeners if there's a change that's worth sending. That way\n\t// you can implement a simple \"reload on any change\" script without having\n\t// to do this check in the script.\n\tif len(added) > 0 || len(removed) > 0 || len(updated) > 0 {\n\t\tsort.Strings(added)\n\t\tsort.Strings(removed)\n\t\tsort.Strings(updated)\n\n\t\t// Assemble the diff\n\t\tvar sb strings.Builder\n\t\tsb.WriteString(\"{\\\"added\\\":[\")\n\t\tfor i, path := range added {\n\t\t\tif i > 0 {\n\t\t\t\tsb.WriteRune(',')\n\t\t\t}\n\t\t\tsb.Write(helpers.QuoteForJSON(path, false))\n\t\t}\n\t\tsb.WriteString(\"],\\\"removed\\\":[\")\n\t\tfor i, path := range removed {\n\t\t\tif i > 0 {\n\t\t\t\tsb.WriteRune(',')\n\t\t\t}\n\t\t\tsb.Write(helpers.QuoteForJSON(path, false))\n\t\t}\n\t\tsb.WriteString(\"],\\\"updated\\\":[\")\n\t\tfor i, path := range updated {\n\t\t\tif i > 0 {\n\t\t\t\tsb.WriteRune(',')\n\t\t\t}\n\t\t\tsb.Write(helpers.QuoteForJSON(path, false))\n\t\t}\n\t\tsb.WriteString(\"]}\")\n\t\tjson := sb.String()\n\n\t\t// Broadcast the diff to all streams\n\t\tfor _, stream := range h.activeStreams {\n\t\t\tstream <- serverSentEvent{event: \"change\", data: json}\n\t\t}\n\t}\n\n\th.mutex.Unlock()\n}\n\n// Handle enough of the range specification so that video playback works in Safari\nfunc parseRangeHeader(r string, contentLength int) (int, int, bool) {\n\tif strings.HasPrefix(r, \"bytes=\") {\n\t\tr = r[len(\"bytes=\"):]\n\t\tif dash := strings.IndexByte(r, '-'); dash != -1 {\n\t\t\t// Note: The range is inclusive so the limit is deliberately \"length - 1\"\n\t\t\tif begin, ok := parseRangeInt(r[:dash], contentLength-1); ok {\n\t\t\t\tif end, ok := parseRangeInt(r[dash+1:], contentLength-1); ok {\n\t\t\t\t\t// Note: The range is inclusive so a range of \"0-1\" is two bytes long\n\t\t\t\t\treturn begin, end + 1, true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn 0, 0, false\n}\n\nfunc parseRangeInt(text string, maxValue int) (int, bool) {\n\tif text == \"\" {\n\t\treturn 0, false\n\t}\n\tvalue := 0\n\tfor _, c := range text {\n\t\tif c < '0' || c > '9' {\n\t\t\treturn 0, false\n\t\t}\n\t\tvalue = value*10 + int(c-'0')\n\t\tif value > maxValue {\n\t\t\treturn 0, false\n\t\t}\n\t}\n\treturn value, true\n}\n\nfunc (h *apiHandler) matchQueryPathToResult(\n\tqueryPath string,\n\tresult *BuildResult,\n\tdirEntries map[string]bool,\n\tfileEntries map[string]bool,\n) (fs.EntryKind, []byte, string, bool) {\n\tqueryIsDir := false\n\tqueryDir := queryPath\n\tif queryDir != \"\" {\n\t\tqueryDir += \"/\"\n\t}\n\n\t// Check the output files for a match\n\tfor _, file := range result.OutputFiles {\n\t\tif relPath, ok := h.fs.Rel(h.absOutputDir, file.Path); ok {\n\t\t\trelPath = strings.ReplaceAll(relPath, \"\\\\\", \"/\")\n\n\t\t\t// An exact match\n\t\t\tif relPath == queryPath {\n\t\t\t\treturn fs.FileEntry, file.Contents, file.Path, false\n\t\t\t}\n\n\t\t\t// Serve an \"index.html\" file if present\n\t\t\tif dir, base := path.Split(relPath); base == \"index.html\" && queryDir == dir {\n\t\t\t\treturn fs.FileEntry, file.Contents, file.Path, true\n\t\t\t}\n\n\t\t\t// A match inside this directory\n\t\t\tif strings.HasPrefix(relPath, queryDir) {\n\t\t\t\tentry := relPath[len(queryDir):]\n\t\t\t\tqueryIsDir = true\n\t\t\t\tif slash := strings.IndexByte(entry, '/'); slash == -1 {\n\t\t\t\t\tfileEntries[entry] = true\n\t\t\t\t} else if dir := entry[:slash]; !dirEntries[dir] {\n\t\t\t\t\tdirEntries[dir] = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Treat this as a directory if it's non-empty\n\tif queryIsDir {\n\t\treturn fs.DirEntry, nil, \"\", false\n\t}\n\n\treturn 0, nil, \"\", false\n}\n\nfunc respondWithDirList(queryPath string, dirEntries map[string]bool, fileEntries map[string]bool) []byte {\n\tqueryPath = \"/\" + queryPath\n\tqueryDir := queryPath\n\tif queryDir != \"/\" {\n\t\tqueryDir += \"/\"\n\t}\n\thtml := strings.Builder{}\n\thtml.WriteString(\"<!doctype html>\\n\")\n\thtml.WriteString(\"<meta charset=\\\"utf8\\\">\\n\")\n\thtml.WriteString(\"<style>\\n\")\n\thtml.WriteString(\"body { margin: 30px; color: #222; background: #fff; font: 16px/22px sans-serif; }\\n\")\n\thtml.WriteString(\"a { color: inherit; text-decoration: none; }\\n\")\n\thtml.WriteString(\"a:hover { text-decoration: underline; }\\n\")\n\thtml.WriteString(\"a:visited { color: #777; }\\n\")\n\thtml.WriteString(\"@media (prefers-color-scheme: dark) {\\n\")\n\thtml.WriteString(\"  body { color: #fff; background: #222; }\\n\")\n\thtml.WriteString(\"  a:visited { color: #aaa; }\\n\")\n\thtml.WriteString(\"}\\n\")\n\thtml.WriteString(\"</style>\\n\")\n\thtml.WriteString(\"<title>Directory: \")\n\thtml.WriteString(escapeForHTML(queryDir))\n\thtml.WriteString(\"</title>\\n\")\n\thtml.WriteString(\"<h1>Directory: \")\n\tvar parts []string\n\tif queryPath == \"/\" {\n\t\tparts = []string{\"\"}\n\t} else {\n\t\tparts = strings.Split(queryPath, \"/\")\n\t}\n\tfor i, part := range parts {\n\t\tif i+1 < len(parts) {\n\t\t\thtml.WriteString(\"<a href=\\\"\")\n\t\t\thtml.WriteString(escapeForAttribute(strings.Join(parts[:i+1], \"/\")))\n\t\t\thtml.WriteString(\"/\\\">\")\n\t\t}\n\t\thtml.WriteString(escapeForHTML(part))\n\t\thtml.WriteString(\"/\")\n\t\tif i+1 < len(parts) {\n\t\t\thtml.WriteString(\"</a>\")\n\t\t}\n\t}\n\thtml.WriteString(\"</h1>\\n\")\n\n\t// Link to the parent directory\n\tif queryPath != \"/\" {\n\t\tparentDir := path.Dir(queryPath)\n\t\tif parentDir != \"/\" {\n\t\t\tparentDir += \"/\"\n\t\t}\n\t\thtml.WriteString(fmt.Sprintf(\"<div>📁 <a href=\\\"%s\\\">../</a></div>\\n\", escapeForAttribute(parentDir)))\n\t}\n\n\t// Link to child directories\n\tstrings := make([]string, 0, len(dirEntries)+len(fileEntries))\n\tfor entry := range dirEntries {\n\t\tstrings = append(strings, entry)\n\t}\n\tsort.Strings(strings)\n\tfor _, entry := range strings {\n\t\thtml.WriteString(fmt.Sprintf(\"<div>📁 <a href=\\\"%s/\\\">%s/</a></div>\\n\", escapeForAttribute(path.Join(queryPath, entry)), escapeForHTML(entry)))\n\t}\n\n\t// Link to files in the directory\n\tstrings = strings[:0]\n\tfor entry := range fileEntries {\n\t\tstrings = append(strings, entry)\n\t}\n\tsort.Strings(strings)\n\tfor _, entry := range strings {\n\t\thtml.WriteString(fmt.Sprintf(\"<div>📄 <a href=\\\"%s\\\">%s</a></div>\\n\", escapeForAttribute(path.Join(queryPath, entry)), escapeForHTML(entry)))\n\t}\n\n\treturn []byte(html.String())\n}\n\n// This is used to make error messages platform-independent\nfunc prettyPrintPath(fs fs.FS, path string) string {\n\tif relPath, ok := fs.Rel(fs.Cwd(), path); ok {\n\t\treturn strings.ReplaceAll(relPath, \"\\\\\", \"/\")\n\t}\n\treturn path\n}\n\nfunc (ctx *internalContext) Serve(serveOptions ServeOptions) (ServeResult, error) {\n\tctx.mutex.Lock()\n\tdefer ctx.mutex.Unlock()\n\n\t// Ignore disposed contexts\n\tif ctx.didDispose {\n\t\treturn ServeResult{}, errors.New(\"Cannot serve a disposed context\")\n\t}\n\n\t// Don't allow starting serve mode multiple times\n\tif ctx.handler != nil {\n\t\treturn ServeResult{}, errors.New(\"Serve mode has already been enabled\")\n\t}\n\n\t// Don't allow starting serve mode multiple times\n\tif (serveOptions.Keyfile != \"\") != (serveOptions.Certfile != \"\") {\n\t\treturn ServeResult{}, errors.New(\"Must specify both key and certificate for HTTPS\")\n\t}\n\n\t// Validate the \"servedir\" path\n\tif serveOptions.Servedir != \"\" {\n\t\tif absPath, ok := ctx.realFS.Abs(serveOptions.Servedir); ok {\n\t\t\tserveOptions.Servedir = absPath\n\t\t} else {\n\t\t\treturn ServeResult{}, fmt.Errorf(\"Invalid serve path: %s\", serveOptions.Servedir)\n\t\t}\n\t}\n\n\t// Validate the \"fallback\" path\n\tif serveOptions.Fallback != \"\" {\n\t\tif absPath, ok := ctx.realFS.Abs(serveOptions.Fallback); ok {\n\t\t\tserveOptions.Fallback = absPath\n\t\t} else {\n\t\t\treturn ServeResult{}, fmt.Errorf(\"Invalid fallback path: %s\", serveOptions.Fallback)\n\t\t}\n\t}\n\n\t// Validate the CORS origins\n\tfor _, origin := range serveOptions.CORS.Origin {\n\t\tif star := strings.IndexByte(origin, '*'); star >= 0 && strings.ContainsRune(origin[star+1:], '*') {\n\t\t\treturn ServeResult{}, fmt.Errorf(\"Invalid origin: %s\", origin)\n\t\t}\n\t}\n\n\t// Stuff related to the output directory only matters if there are entry points\n\toutdirPathPrefix := \"\"\n\tif len(ctx.args.entryPoints) > 0 {\n\t\t// Don't allow serving when builds are written to stdout\n\t\tif ctx.args.options.WriteToStdout {\n\t\t\twhat := \"entry points\"\n\t\t\tif len(ctx.args.entryPoints) == 1 {\n\t\t\t\twhat = \"an entry point\"\n\t\t\t}\n\t\t\treturn ServeResult{}, fmt.Errorf(\"Cannot serve %s without an output path\", what)\n\t\t}\n\n\t\t// Compute the output path prefix\n\t\tif serveOptions.Servedir != \"\" && ctx.args.options.AbsOutputDir != \"\" {\n\t\t\t// Make sure the output directory is contained in the \"servedir\" directory\n\t\t\trelPath, ok := ctx.realFS.Rel(serveOptions.Servedir, ctx.args.options.AbsOutputDir)\n\t\t\tif !ok {\n\t\t\t\treturn ServeResult{}, fmt.Errorf(\n\t\t\t\t\t\"Cannot compute relative path from %q to %q\\n\", serveOptions.Servedir, ctx.args.options.AbsOutputDir)\n\t\t\t}\n\t\t\trelPath = strings.ReplaceAll(relPath, \"\\\\\", \"/\") // Fix paths on Windows\n\t\t\tif relPath == \"..\" || strings.HasPrefix(relPath, \"../\") {\n\t\t\t\treturn ServeResult{}, fmt.Errorf(\n\t\t\t\t\t\"Output directory %q must be contained in serve directory %q\",\n\t\t\t\t\tprettyPrintPath(ctx.realFS, ctx.args.options.AbsOutputDir),\n\t\t\t\t\tprettyPrintPath(ctx.realFS, serveOptions.Servedir),\n\t\t\t\t)\n\t\t\t}\n\t\t\tif relPath != \".\" {\n\t\t\t\toutdirPathPrefix = relPath\n\t\t\t}\n\t\t}\n\t}\n\n\t// Determine the host\n\tvar listener net.Listener\n\tnetwork := \"tcp4\"\n\thost := \"0.0.0.0\"\n\thostIsIP := true\n\tif serveOptions.Host != \"\" {\n\t\thost = serveOptions.Host\n\t\tip := net.ParseIP(host)\n\n\t\t// Only use \"tcp4\" if this is an IPv4 address, otherwise use \"tcp\"\n\t\tif ip == nil || ip.To4() == nil {\n\t\t\tnetwork = \"tcp\"\n\t\t}\n\n\t\t// Remember whether the host is a valid IP address or not\n\t\tif ip == nil {\n\t\t\thostIsIP = false\n\t\t}\n\t}\n\n\t// Pick the port\n\tif serveOptions.Port == 0 {\n\t\t// Default to picking a \"800X\" port\n\t\tfor port := 8000; port <= 8009; port++ {\n\t\t\tif result, err := net.Listen(network, net.JoinHostPort(host, fmt.Sprintf(\"%d\", port))); err == nil {\n\t\t\t\tlistener = result\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tif listener == nil {\n\t\t// Otherwise pick the provided port\n\t\tport := serveOptions.Port\n\t\tif port < 0 || port > 0xFFFF {\n\t\t\tport = 0 // Pick a random port if the provided port is out of range\n\t\t}\n\t\tif result, err := net.Listen(network, net.JoinHostPort(host, fmt.Sprintf(\"%d\", port))); err != nil {\n\t\t\treturn ServeResult{}, err\n\t\t} else {\n\t\t\tlistener = result\n\t\t}\n\t}\n\n\t// Try listening on the provided port\n\taddr := listener.Addr().String()\n\n\t// Extract the real port in case we passed a port of \"0\"\n\tvar result ServeResult\n\tvar boundHost string\n\tif host, text, err := net.SplitHostPort(addr); err == nil {\n\t\tif port, err := strconv.ParseInt(text, 10, 32); err == nil {\n\t\t\tresult.Port = uint16(port)\n\t\t\tboundHost = host\n\t\t}\n\t}\n\n\t// Build up a list of all hosts we use\n\tif ip := net.ParseIP(boundHost); ip != nil && ip.IsUnspecified() {\n\t\t// If this is \"0.0.0.0\" or \"::\", list all relevant IP addresses\n\t\tif addrs, err := net.InterfaceAddrs(); err == nil {\n\t\t\tfor _, addr := range addrs {\n\t\t\t\tif addr, ok := addr.(*net.IPNet); ok && (addr.IP.To4() != nil) == (ip.To4() != nil) && !addr.IP.IsLinkLocalUnicast() {\n\t\t\t\t\tresult.Hosts = append(result.Hosts, addr.IP.String())\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tresult.Hosts = append(result.Hosts, boundHost)\n\t}\n\n\t// If the host isn't a valid IP address, add it to the list of allowed hosts.\n\t// For example, mapping \"local.example.com\" to \"127.0.0.1\" in \"/etc/hosts\"\n\t// and then using \"--serve=local.example.com:8000\" should make it possible to\n\t// successfully visit \"http://local.example.com:8000/\" in a browser.\n\tif !hostIsIP {\n\t\tresult.Hosts = append(result.Hosts, host)\n\t}\n\n\t// HTTPS-related files should be absolute paths\n\tisHTTPS := serveOptions.Keyfile != \"\" && serveOptions.Certfile != \"\"\n\tif isHTTPS {\n\t\tserveOptions.Keyfile, _ = ctx.realFS.Abs(serveOptions.Keyfile)\n\t\tserveOptions.Certfile, _ = ctx.realFS.Abs(serveOptions.Certfile)\n\t}\n\n\tvar shouldStop int32\n\n\t// The first build will just build normally\n\thandler := &apiHandler{\n\t\tonRequest:        serveOptions.OnRequest,\n\t\toutdirPathPrefix: outdirPathPrefix,\n\t\tabsOutputDir:     ctx.args.options.AbsOutputDir,\n\t\tpublicPath:       ctx.args.options.PublicPath,\n\t\tservedir:         serveOptions.Servedir,\n\t\tkeyfileToLower:   strings.ToLower(serveOptions.Keyfile),\n\t\tcertfileToLower:  strings.ToLower(serveOptions.Certfile),\n\t\tfallback:         serveOptions.Fallback,\n\t\thosts:            append([]string{}, result.Hosts...),\n\t\tcorsOrigin:       append([]string{}, serveOptions.CORS.Origin...),\n\t\trebuild: func() BuildResult {\n\t\t\tif atomic.LoadInt32(&shouldStop) != 0 {\n\t\t\t\t// Don't start more rebuilds if we were told to stop\n\t\t\t\treturn BuildResult{}\n\t\t\t} else {\n\t\t\t\treturn ctx.activeBuildOrRecentBuildOrRebuild()\n\t\t\t}\n\t\t},\n\t\tfs: ctx.realFS,\n\t}\n\n\t// Create the server\n\tserver := &http.Server{Addr: addr, Handler: handler}\n\n\t// When stop is called, block further rebuilds and then close the server\n\thandler.stop = func() {\n\t\tatomic.StoreInt32(&shouldStop, 1)\n\n\t\t// Close the server and wait for it to close\n\t\tserver.Close()\n\n\t\t// Close all open event streams\n\t\thandler.mutex.Lock()\n\t\tfor _, stream := range handler.activeStreams {\n\t\t\tclose(stream)\n\t\t}\n\t\thandler.activeStreams = nil\n\t\thandler.mutex.Unlock()\n\n\t\thandler.serveWaitGroup.Wait()\n\t}\n\n\t// HACK: Go's HTTP API doesn't appear to provide a way to separate argument\n\t// validation errors from eventual network errors. Specifically \"ServeTLS\"\n\t// blocks for an arbitrarily long time before returning an error. So we\n\t// intercept the first call to \"Accept\" on the listener and say that the\n\t// serve call succeeded without an error if we get to that point.\n\thack := &hackListener{Listener: listener}\n\thack.waitGroup.Add(1)\n\n\t// Start the server and signal on \"serveWaitGroup\" when it stops\n\thandler.serveWaitGroup.Add(1)\n\tgo func() {\n\t\tvar err error\n\t\tif isHTTPS {\n\t\t\terr = server.ServeTLS(hack, serveOptions.Certfile, serveOptions.Keyfile)\n\t\t} else {\n\t\t\terr = server.Serve(hack)\n\t\t}\n\t\tif err != http.ErrServerClosed {\n\t\t\thack.mutex.Lock()\n\t\t\tif !hack.done {\n\t\t\t\thack.done = true\n\t\t\t\thack.err = err\n\t\t\t\thack.waitGroup.Done()\n\t\t\t}\n\t\t\thack.mutex.Unlock()\n\t\t}\n\t\thandler.serveWaitGroup.Done()\n\t}()\n\n\t// Return an error if the server failed to start accepting connections\n\thack.waitGroup.Wait()\n\tif hack.err != nil {\n\t\treturn ServeResult{}, hack.err\n\t}\n\n\t// There appears to be some issue with Linux (but not with macOS) where\n\t// destroying and recreating a server with the same port as the previous\n\t// server had sometimes causes subsequent connections to fail with\n\t// ECONNRESET (shows up in node as \"Error: socket hang up\").\n\t//\n\t// I think the problem is sort of that Go sets SO_REUSEADDR to 1 for listener\n\t// sockets (specifically in \"setDefaultListenerSockopts\"). In some ways this\n\t// is good, because it's more convenient for the user if the port is the\n\t// same. However, I believe this sends a TCP RST packet to kill any previous\n\t// connections. That can then be received by clients attempting to connect\n\t// to the new server.\n\t//\n\t// As a hack to work around this problem, we wait for an additional short\n\t// amount of time before returning. I observed this problem even with a 5ms\n\t// timeout but I did not observe this problem with a 10ms timeout. So I'm\n\t// setting this timeout to 50ms to be extra safe.\n\ttime.Sleep(50 * time.Millisecond)\n\n\t// Only set the context handler if the server started successfully\n\tctx.handler = handler\n\n\t// Print the URL(s) that the server can be reached at\n\tif ctx.args.logOptions.LogLevel <= logger.LevelInfo {\n\t\tprintURLs(handler.hosts, result.Port, isHTTPS, ctx.args.logOptions.Color)\n\t}\n\n\t// Start the first build shortly after this function returns (but not\n\t// immediately so that stuff we print right after this will come first).\n\t//\n\t// This also helps the CLI not do two builds when serve and watch mode\n\t// are enabled together. Watch mode is enabled after serve mode because\n\t// we want the stderr output for watch to come after the stderr output for\n\t// serve, but watch mode will do another build if the current build is\n\t// not a watch mode build.\n\tgo func() {\n\t\ttime.Sleep(10 * time.Millisecond)\n\t\thandler.rebuild()\n\t}()\n\treturn result, nil\n}\n\ntype hackListener struct {\n\tnet.Listener\n\tmutex     sync.Mutex\n\twaitGroup sync.WaitGroup\n\terr       error\n\tdone      bool\n}\n\nfunc (hack *hackListener) Accept() (net.Conn, error) {\n\thack.mutex.Lock()\n\tif !hack.done {\n\t\thack.done = true\n\t\thack.waitGroup.Done()\n\t}\n\thack.mutex.Unlock()\n\treturn hack.Listener.Accept()\n}\n\nfunc printURLs(hosts []string, port uint16, https bool, useColor logger.UseColor) {\n\tlogger.PrintTextWithColor(os.Stderr, useColor, func(colors logger.Colors) string {\n\t\tsb := strings.Builder{}\n\t\tsb.WriteString(colors.Reset)\n\n\t\t// Determine the host kinds\n\t\tkinds := make([]string, len(hosts))\n\t\tmaxLen := 0\n\t\tfor i, host := range hosts {\n\t\t\tkind := \"Network\"\n\t\t\tif ip := net.ParseIP(host); ip != nil && ip.IsLoopback() {\n\t\t\t\tkind = \"Local\"\n\t\t\t}\n\t\t\tkinds[i] = kind\n\t\t\tif len(kind) > maxLen {\n\t\t\t\tmaxLen = len(kind)\n\t\t\t}\n\t\t}\n\n\t\t// Pretty-print the host list\n\t\tprotocol := \"http\"\n\t\tif https {\n\t\t\tprotocol = \"https\"\n\t\t}\n\t\tfor i, kind := range kinds {\n\t\t\tsb.WriteString(fmt.Sprintf(\"\\n > %s:%s %s%s://%s/%s\",\n\t\t\t\tkind, strings.Repeat(\" \", maxLen-len(kind)), colors.Underline, protocol,\n\t\t\t\tnet.JoinHostPort(hosts[i], fmt.Sprintf(\"%d\", port)), colors.Reset))\n\t\t}\n\n\t\tsb.WriteString(\"\\n\\n\")\n\t\treturn sb.String()\n\t})\n}\n"
  },
  {
    "path": "pkg/api/serve_wasm.go",
    "content": "//go:build js && wasm\n// +build js,wasm\n\npackage api\n\nimport \"fmt\"\n\n// Remove the serve API in the WebAssembly build. This removes 2.7mb of stuff.\n\nfunc (*internalContext) Serve(ServeOptions) (ServeResult, error) {\n\treturn ServeResult{}, fmt.Errorf(\"The \\\"serve\\\" API is not supported when using WebAssembly\")\n}\n\ntype apiHandler struct {\n}\n\nfunc (*apiHandler) broadcastBuildResult(BuildResult, map[string]string) {\n}\n\nfunc (*apiHandler) stop() {\n}\n"
  },
  {
    "path": "pkg/api/watcher.go",
    "content": "package api\n\n// This file implements a polling file watcher for esbuild (i.e. it detects\n// when files are changed by repeatedly checking their contents). Polling is\n// used instead of more efficient platform-specific file system APIs because:\n//\n//   * Go's standard library doesn't have built-in APIs for file watching\n//   * Using platform-specific APIs means using cgo, which I want to avoid\n//   * Polling is cross-platform and esbuild needs to work on 20+ platforms\n//   * Platform-specific APIs might be unreliable and could introduce bugs\n//\n// That said, this polling system is designed to use relatively little CPU vs.\n// a more traditional polling system that scans the whole directory tree at\n// once. The file system is still scanned regularly but each scan only checks\n// a random subset of your files, which means a change to a file will be picked\n// up soon after the change is made but not necessarily instantly.\n//\n// With the current heuristics, large projects should be completely scanned\n// around every 2 seconds so in the worst case it could take up to 2 seconds\n// for a change to be noticed. However, after a change has been noticed the\n// change's path goes on a short list of recently changed paths which are\n// checked on every scan, so further changes to recently changed files should\n// be noticed almost instantly.\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"os\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/evanw/esbuild/internal/fs\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/resolver\"\n)\n\n// The time to wait between watch intervals\nconst watchIntervalSleep = 100 * time.Millisecond\n\n// The maximum number of recently-edited items to check every interval\nconst maxRecentItemCount = 16\n\n// The minimum number of non-recent items to check every interval\nconst minItemCountPerIter = 64\n\n// The maximum number of intervals before a change is detected\nconst maxIntervalsBeforeUpdate = 20\n\ntype watcher struct {\n\tdata              fs.WatchData\n\tfs                fs.FS\n\trebuild           func() fs.WatchData\n\tdelayInMS         time.Duration\n\trecentItems       []string\n\titemsToScan       []string\n\tmutex             sync.Mutex\n\titemsPerIteration int\n\tshouldStop        int32\n\tshouldLog         bool\n\tuseColor          logger.UseColor\n\tpathStyle         logger.PathStyle\n\tstopWaitGroup     sync.WaitGroup\n}\n\nfunc (w *watcher) setWatchData(data fs.WatchData) {\n\tdefer w.mutex.Unlock()\n\tw.mutex.Lock()\n\n\t// Print something for the end of the first build\n\tif w.shouldLog && w.data.Paths == nil {\n\t\tlogger.PrintTextWithColor(os.Stderr, w.useColor, func(colors logger.Colors) string {\n\t\t\tvar delay string\n\t\t\tif w.delayInMS > 0 {\n\t\t\t\tdelay = fmt.Sprintf(\" with a %dms delay\", w.delayInMS)\n\t\t\t}\n\t\t\treturn fmt.Sprintf(\"%s[watch] build finished, watching for changes%s...%s\\n\", colors.Dim, delay, colors.Reset)\n\t\t})\n\t}\n\n\tw.data = data\n\tw.itemsToScan = w.itemsToScan[:0] // Reuse memory\n\n\t// Remove any recent items that weren't a part of the latest build\n\tend := 0\n\tfor _, path := range w.recentItems {\n\t\tif data.Paths[path] != nil {\n\t\t\tw.recentItems[end] = path\n\t\t\tend++\n\t\t}\n\t}\n\tw.recentItems = w.recentItems[:end]\n}\n\nfunc (w *watcher) start() {\n\tw.stopWaitGroup.Add(1)\n\n\tgo func() {\n\t\t// Note: Do not change these log messages without a breaking version change.\n\t\t// People want to run regexes over esbuild's stderr stream to look for these\n\t\t// messages instead of using esbuild's API.\n\n\t\tfor atomic.LoadInt32(&w.shouldStop) == 0 {\n\t\t\t// Sleep for the watch interval\n\t\t\ttime.Sleep(watchIntervalSleep)\n\n\t\t\t// Rebuild if we're dirty\n\t\t\tif absPath := w.tryToFindDirtyPath(); absPath != \"\" {\n\t\t\t\t// Optionally wait before rebuilding\n\t\t\t\tif w.delayInMS > 0 {\n\t\t\t\t\ttime.Sleep(w.delayInMS * time.Millisecond)\n\t\t\t\t}\n\n\t\t\t\tif w.shouldLog {\n\t\t\t\t\tlogger.PrintTextWithColor(os.Stderr, w.useColor, func(colors logger.Colors) string {\n\t\t\t\t\t\tprettyPaths := resolver.MakePrettyPaths(w.fs, logger.Path{Text: absPath, Namespace: \"file\"})\n\t\t\t\t\t\treturn fmt.Sprintf(\"%s[watch] build started (change: %q)%s\\n\",\n\t\t\t\t\t\t\tcolors.Dim, prettyPaths.Select(w.pathStyle), colors.Reset)\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\t// Run the build\n\t\t\t\tw.setWatchData(w.rebuild())\n\n\t\t\t\tif w.shouldLog {\n\t\t\t\t\tlogger.PrintTextWithColor(os.Stderr, w.useColor, func(colors logger.Colors) string {\n\t\t\t\t\t\treturn fmt.Sprintf(\"%s[watch] build finished%s\\n\", colors.Dim, colors.Reset)\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tw.stopWaitGroup.Done()\n\t}()\n}\n\nfunc (w *watcher) stop() {\n\tatomic.StoreInt32(&w.shouldStop, 1)\n\tw.stopWaitGroup.Wait()\n}\n\nfunc (w *watcher) tryToFindDirtyPath() string {\n\tdefer w.mutex.Unlock()\n\tw.mutex.Lock()\n\n\t// If we ran out of items to scan, fill the items back up in a random order\n\tif len(w.itemsToScan) == 0 {\n\t\titems := w.itemsToScan[:0] // Reuse memory\n\t\tfor path := range w.data.Paths {\n\t\t\titems = append(items, path)\n\t\t}\n\t\trand.Seed(time.Now().UnixNano())\n\t\tfor i := int32(len(items) - 1); i > 0; i-- { // Fisher-Yates shuffle\n\t\t\tj := rand.Int31n(i + 1)\n\t\t\titems[i], items[j] = items[j], items[i]\n\t\t}\n\t\tw.itemsToScan = items\n\n\t\t// Determine how many items to check every iteration, rounded up\n\t\tperIter := (len(items) + maxIntervalsBeforeUpdate - 1) / maxIntervalsBeforeUpdate\n\t\tif perIter < minItemCountPerIter {\n\t\t\tperIter = minItemCountPerIter\n\t\t}\n\t\tw.itemsPerIteration = perIter\n\t}\n\n\t// Always check all recent items every iteration\n\tfor i, path := range w.recentItems {\n\t\tif dirtyPath := w.data.Paths[path](); dirtyPath != \"\" {\n\t\t\t// Move this path to the back of the list (i.e. the \"most recent\" position)\n\t\t\tcopy(w.recentItems[i:], w.recentItems[i+1:])\n\t\t\tw.recentItems[len(w.recentItems)-1] = path\n\t\t\treturn dirtyPath\n\t\t}\n\t}\n\n\t// Check a constant number of items every iteration\n\tremainingCount := len(w.itemsToScan) - w.itemsPerIteration\n\tif remainingCount < 0 {\n\t\tremainingCount = 0\n\t}\n\ttoCheck, remaining := w.itemsToScan[remainingCount:], w.itemsToScan[:remainingCount]\n\tw.itemsToScan = remaining\n\n\t// Check if any of the entries in this iteration have been modified\n\tfor _, path := range toCheck {\n\t\tif dirtyPath := w.data.Paths[path](); dirtyPath != \"\" {\n\t\t\t// Mark this item as recent by adding it to the back of the list\n\t\t\tw.recentItems = append(w.recentItems, path)\n\t\t\tif len(w.recentItems) > maxRecentItemCount {\n\t\t\t\t// Remove items from the front of the list when we hit the limit\n\t\t\t\tcopy(w.recentItems, w.recentItems[1:])\n\t\t\t\tw.recentItems = w.recentItems[:maxRecentItemCount]\n\t\t\t}\n\t\t\treturn dirtyPath\n\t\t}\n\t}\n\treturn \"\"\n}\n"
  },
  {
    "path": "pkg/cli/cli.go",
    "content": "// This API exposes the command-line interface for esbuild. It can be used to\n// run esbuild from Go without the overhead of creating a child process.\n//\n// Example usage:\n//\n//\tpackage main\n//\n//\timport (\n//\t    \"os\"\n//\n//\t    \"github.com/evanw/esbuild/pkg/cli\"\n//\t)\n//\n//\tfunc main() {\n//\t    os.Exit(cli.Run(os.Args[1:]))\n//\t}\npackage cli\n\nimport (\n\t\"errors\"\n\n\t\"github.com/evanw/esbuild/pkg/api\"\n)\n\n// This function invokes the esbuild CLI. It takes an array of command-line\n// arguments (excluding the executable argument itself) and returns an exit\n// code. There are some minor differences between this CLI and the actual\n// \"esbuild\" executable such as the lack of auxiliary flags (e.g. \"--help\" and\n// \"--version\") but it is otherwise exactly the same code.\nfunc Run(osArgs []string) int {\n\treturn runImpl(osArgs, []api.Plugin{})\n}\n\n// This is similar to \"Run()\" but also takes an array of plugins to be used\n// during the build process.\nfunc RunWithPlugins(osArgs []string, plugins []api.Plugin) int {\n\treturn runImpl(osArgs, plugins)\n}\n\n// This parses an array of strings into an options object suitable for passing\n// to \"api.Build()\". Use this if you need to reuse the same argument parsing\n// logic as the esbuild CLI.\n//\n// Example usage:\n//\n//\toptions, err := cli.ParseBuildOptions([]string{\n//\t    \"input.js\",\n//\t    \"--bundle\",\n//\t    \"--minify\",\n//\t})\n//\n//\tresult := api.Build(options)\nfunc ParseBuildOptions(osArgs []string) (options api.BuildOptions, err error) {\n\toptions = newBuildOptions()\n\t_, errWithNote := parseOptionsImpl(osArgs, &options, nil, kindExternal)\n\tif errWithNote != nil {\n\t\terr = errors.New(errWithNote.Text)\n\t}\n\treturn\n}\n\n// This parses an array of strings into an options object suitable for passing\n// to \"api.Transform()\". Use this if you need to reuse the same argument\n// parsing logic as the esbuild CLI.\n//\n// Example usage:\n//\n//\toptions, err := cli.ParseTransformOptions([]string{\n//\t    \"--minify\",\n//\t    \"--loader=tsx\",\n//\t    \"--define:DEBUG=false\",\n//\t})\n//\n//\tresult := api.Transform(input, options)\nfunc ParseTransformOptions(osArgs []string) (options api.TransformOptions, err error) {\n\toptions = newTransformOptions()\n\t_, errWithNote := parseOptionsImpl(osArgs, nil, &options, kindExternal)\n\tif errWithNote != nil {\n\t\terr = errors.New(errWithNote.Text)\n\t}\n\treturn\n}\n\n// This parses an array of strings into an options object suitable for passing\n// to \"api.Serve()\". The remaining non-serve arguments are returned in another\n// array to then be passed to \"api.ParseBuildOptions()\". Use this if you need\n// to reuse the same argument parsing logic as the esbuild CLI.\n//\n// Example usage:\n//\n//\tserveOptions, args, err := cli.ParseServeOptions([]string{\n//\t    \"--serve=8000\",\n//\t})\n//\n//\tbuildOptions, err := cli.ParseBuildOptions(args)\n//\n//\tresult := api.Serve(serveOptions, buildOptions)\nfunc ParseServeOptions(osArgs []string) (options api.ServeOptions, remainingArgs []string, err error) {\n\treturn parseServeOptionsImpl(osArgs)\n}\n"
  },
  {
    "path": "pkg/cli/cli_impl.go",
    "content": "package cli\n\n// This file implements the public CLI. It's deliberately implemented using\n// esbuild's public \"Build\", \"Transform\", and \"AnalyzeMetafile\" APIs instead of\n// using internal APIs so that any tests that cover the CLI also implicitly\n// cover the public API as well.\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"net\"\n\t\"os\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/evanw/esbuild/internal/cli_helpers\"\n\t\"github.com/evanw/esbuild/internal/fs\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/pkg/api\"\n)\n\nfunc newBuildOptions() api.BuildOptions {\n\treturn api.BuildOptions{\n\t\tBanner:      make(map[string]string),\n\t\tDefine:      make(map[string]string),\n\t\tFooter:      make(map[string]string),\n\t\tLoader:      make(map[string]api.Loader),\n\t\tLogOverride: make(map[string]api.LogLevel),\n\t\tSupported:   make(map[string]bool),\n\t}\n}\n\nfunc newTransformOptions() api.TransformOptions {\n\treturn api.TransformOptions{\n\t\tDefine:      make(map[string]string),\n\t\tLogOverride: make(map[string]api.LogLevel),\n\t\tSupported:   make(map[string]bool),\n\t}\n}\n\ntype parseOptionsKind uint8\n\nconst (\n\t// This means we're parsing it for our own internal use\n\tkindInternal parseOptionsKind = iota\n\n\t// This means the result is returned through a public API\n\tkindExternal\n)\n\ntype parseOptionsExtras struct {\n\twatch       bool\n\twatchDelay  int\n\tmetafile    *string\n\tmangleCache *string\n}\n\nfunc isBoolFlag(arg string, flag string) bool {\n\tif strings.HasPrefix(arg, flag) {\n\t\tremainder := arg[len(flag):]\n\t\treturn len(remainder) == 0 || remainder[0] == '='\n\t}\n\treturn false\n}\n\nfunc parseBoolFlag(arg string, defaultValue bool) (bool, *cli_helpers.ErrorWithNote) {\n\tequals := strings.IndexByte(arg, '=')\n\tif equals == -1 {\n\t\treturn defaultValue, nil\n\t}\n\tvalue := arg[equals+1:]\n\tswitch value {\n\tcase \"false\":\n\t\treturn false, nil\n\tcase \"true\":\n\t\treturn true, nil\n\t}\n\treturn false, cli_helpers.MakeErrorWithNote(\n\t\tfmt.Sprintf(\"Invalid value %q in %q\", value, arg),\n\t\t\"Valid values are \\\"true\\\" or \\\"false\\\".\",\n\t)\n}\n\nfunc parseOptionsImpl(\n\tosArgs []string,\n\tbuildOpts *api.BuildOptions,\n\ttransformOpts *api.TransformOptions,\n\tkind parseOptionsKind,\n) (extras parseOptionsExtras, err *cli_helpers.ErrorWithNote) {\n\thasBareSourceMapFlag := false\n\n\t// Parse the arguments now that we know what we're parsing\n\tfor _, arg := range osArgs {\n\t\tswitch {\n\t\tcase isBoolFlag(arg, \"--bundle\") && buildOpts != nil:\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else {\n\t\t\t\tbuildOpts.Bundle = value\n\t\t\t}\n\n\t\tcase isBoolFlag(arg, \"--preserve-symlinks\") && buildOpts != nil:\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else {\n\t\t\t\tbuildOpts.PreserveSymlinks = value\n\t\t\t}\n\n\t\tcase isBoolFlag(arg, \"--splitting\") && buildOpts != nil:\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else {\n\t\t\t\tbuildOpts.Splitting = value\n\t\t\t}\n\n\t\tcase isBoolFlag(arg, \"--allow-overwrite\") && buildOpts != nil:\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else {\n\t\t\t\tbuildOpts.AllowOverwrite = value\n\t\t\t}\n\n\t\tcase isBoolFlag(arg, \"--watch\") && buildOpts != nil:\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else {\n\t\t\t\textras.watch = value\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--watch-delay=\") && buildOpts != nil:\n\t\t\tvalue := arg[len(\"--watch-delay=\"):]\n\t\t\tdelay, err := strconv.Atoi(value)\n\t\t\tif err != nil {\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Invalid value %q in %q\", value, arg),\n\t\t\t\t\t\"The watch delay must be an integer.\",\n\t\t\t\t)\n\t\t\t}\n\t\t\textras.watchDelay = delay\n\n\t\tcase isBoolFlag(arg, \"--minify\"):\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else if buildOpts != nil {\n\t\t\t\tbuildOpts.MinifySyntax = value\n\t\t\t\tbuildOpts.MinifyWhitespace = value\n\t\t\t\tbuildOpts.MinifyIdentifiers = value\n\t\t\t} else {\n\t\t\t\ttransformOpts.MinifySyntax = value\n\t\t\t\ttransformOpts.MinifyWhitespace = value\n\t\t\t\ttransformOpts.MinifyIdentifiers = value\n\t\t\t}\n\n\t\tcase isBoolFlag(arg, \"--minify-syntax\"):\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else if buildOpts != nil {\n\t\t\t\tbuildOpts.MinifySyntax = value\n\t\t\t} else {\n\t\t\t\ttransformOpts.MinifySyntax = value\n\t\t\t}\n\n\t\tcase isBoolFlag(arg, \"--minify-whitespace\"):\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else if buildOpts != nil {\n\t\t\t\tbuildOpts.MinifyWhitespace = value\n\t\t\t} else {\n\t\t\t\ttransformOpts.MinifyWhitespace = value\n\t\t\t}\n\n\t\tcase isBoolFlag(arg, \"--minify-identifiers\"):\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else if buildOpts != nil {\n\t\t\t\tbuildOpts.MinifyIdentifiers = value\n\t\t\t} else {\n\t\t\t\ttransformOpts.MinifyIdentifiers = value\n\t\t\t}\n\n\t\tcase isBoolFlag(arg, \"--mangle-quoted\"):\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else {\n\t\t\t\tvar mangleQuoted *api.MangleQuoted\n\t\t\t\tif buildOpts != nil {\n\t\t\t\t\tmangleQuoted = &buildOpts.MangleQuoted\n\t\t\t\t} else {\n\t\t\t\t\tmangleQuoted = &transformOpts.MangleQuoted\n\t\t\t\t}\n\t\t\t\tif value {\n\t\t\t\t\t*mangleQuoted = api.MangleQuotedTrue\n\t\t\t\t} else {\n\t\t\t\t\t*mangleQuoted = api.MangleQuotedFalse\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--mangle-props=\"):\n\t\t\tvalue := arg[len(\"--mangle-props=\"):]\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.MangleProps = value\n\t\t\t} else {\n\t\t\t\ttransformOpts.MangleProps = value\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--reserve-props=\"):\n\t\t\tvalue := arg[len(\"--reserve-props=\"):]\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.ReserveProps = value\n\t\t\t} else {\n\t\t\t\ttransformOpts.ReserveProps = value\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--mangle-cache=\") && buildOpts != nil && kind == kindInternal:\n\t\t\tvalue := arg[len(\"--mangle-cache=\"):]\n\t\t\textras.mangleCache = &value\n\n\t\tcase strings.HasPrefix(arg, \"--drop:\"):\n\t\t\tvalue := arg[len(\"--drop:\"):]\n\t\t\tswitch value {\n\t\t\tcase \"console\":\n\t\t\t\tif buildOpts != nil {\n\t\t\t\t\tbuildOpts.Drop |= api.DropConsole\n\t\t\t\t} else {\n\t\t\t\t\ttransformOpts.Drop |= api.DropConsole\n\t\t\t\t}\n\t\t\tcase \"debugger\":\n\t\t\t\tif buildOpts != nil {\n\t\t\t\t\tbuildOpts.Drop |= api.DropDebugger\n\t\t\t\t} else {\n\t\t\t\t\ttransformOpts.Drop |= api.DropDebugger\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Invalid value %q in %q\", value, arg),\n\t\t\t\t\t\"Valid values are \\\"console\\\" or \\\"debugger\\\".\",\n\t\t\t\t)\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--drop-labels=\"):\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.DropLabels = splitWithEmptyCheck(arg[len(\"--drop-labels=\"):], \",\")\n\t\t\t} else {\n\t\t\t\ttransformOpts.DropLabels = splitWithEmptyCheck(arg[len(\"--drop-labels=\"):], \",\")\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--legal-comments=\"):\n\t\t\tvalue := arg[len(\"--legal-comments=\"):]\n\t\t\tvar legalComments api.LegalComments\n\t\t\tswitch value {\n\t\t\tcase \"none\":\n\t\t\t\tlegalComments = api.LegalCommentsNone\n\t\t\tcase \"inline\":\n\t\t\t\tlegalComments = api.LegalCommentsInline\n\t\t\tcase \"eof\":\n\t\t\t\tlegalComments = api.LegalCommentsEndOfFile\n\t\t\tcase \"linked\":\n\t\t\t\tlegalComments = api.LegalCommentsLinked\n\t\t\tcase \"external\":\n\t\t\t\tlegalComments = api.LegalCommentsExternal\n\t\t\tdefault:\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Invalid value %q in %q\", value, arg),\n\t\t\t\t\t\"Valid values are \\\"none\\\", \\\"inline\\\", \\\"eof\\\", \\\"linked\\\", or \\\"external\\\".\",\n\t\t\t\t)\n\t\t\t}\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.LegalComments = legalComments\n\t\t\t} else {\n\t\t\t\ttransformOpts.LegalComments = legalComments\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--charset=\"):\n\t\t\tvar value *api.Charset\n\t\t\tif buildOpts != nil {\n\t\t\t\tvalue = &buildOpts.Charset\n\t\t\t} else {\n\t\t\t\tvalue = &transformOpts.Charset\n\t\t\t}\n\t\t\tname := arg[len(\"--charset=\"):]\n\t\t\tswitch name {\n\t\t\tcase \"ascii\":\n\t\t\t\t*value = api.CharsetASCII\n\t\t\tcase \"utf8\":\n\t\t\t\t*value = api.CharsetUTF8\n\t\t\tdefault:\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Invalid value %q in %q\", name, arg),\n\t\t\t\t\t\"Valid values are \\\"ascii\\\" or \\\"utf8\\\".\",\n\t\t\t\t)\n\t\t\t}\n\n\t\tcase isBoolFlag(arg, \"--tree-shaking\"):\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else {\n\t\t\t\tvar treeShaking *api.TreeShaking\n\t\t\t\tif buildOpts != nil {\n\t\t\t\t\ttreeShaking = &buildOpts.TreeShaking\n\t\t\t\t} else {\n\t\t\t\t\ttreeShaking = &transformOpts.TreeShaking\n\t\t\t\t}\n\t\t\t\tif value {\n\t\t\t\t\t*treeShaking = api.TreeShakingTrue\n\t\t\t\t} else {\n\t\t\t\t\t*treeShaking = api.TreeShakingFalse\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase isBoolFlag(arg, \"--ignore-annotations\"):\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else if buildOpts != nil {\n\t\t\t\tbuildOpts.IgnoreAnnotations = value\n\t\t\t} else {\n\t\t\t\ttransformOpts.IgnoreAnnotations = value\n\t\t\t}\n\n\t\tcase isBoolFlag(arg, \"--keep-names\"):\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else if buildOpts != nil {\n\t\t\t\tbuildOpts.KeepNames = value\n\t\t\t} else {\n\t\t\t\ttransformOpts.KeepNames = value\n\t\t\t}\n\n\t\tcase arg == \"--sourcemap\":\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.Sourcemap = api.SourceMapLinked\n\t\t\t} else {\n\t\t\t\ttransformOpts.Sourcemap = api.SourceMapInline\n\t\t\t}\n\t\t\thasBareSourceMapFlag = true\n\n\t\tcase strings.HasPrefix(arg, \"--sourcemap=\"):\n\t\t\tvalue := arg[len(\"--sourcemap=\"):]\n\t\t\tvar sourcemap api.SourceMap\n\t\t\tswitch value {\n\t\t\tcase \"linked\":\n\t\t\t\tsourcemap = api.SourceMapLinked\n\t\t\tcase \"inline\":\n\t\t\t\tsourcemap = api.SourceMapInline\n\t\t\tcase \"external\":\n\t\t\t\tsourcemap = api.SourceMapExternal\n\t\t\tcase \"both\":\n\t\t\t\tsourcemap = api.SourceMapInlineAndExternal\n\t\t\tdefault:\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Invalid value %q in %q\", value, arg),\n\t\t\t\t\t\"Valid values are \\\"linked\\\", \\\"inline\\\", \\\"external\\\", or \\\"both\\\".\",\n\t\t\t\t)\n\t\t\t}\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.Sourcemap = sourcemap\n\t\t\t} else {\n\t\t\t\ttransformOpts.Sourcemap = sourcemap\n\t\t\t}\n\t\t\thasBareSourceMapFlag = false\n\n\t\tcase strings.HasPrefix(arg, \"--source-root=\"):\n\t\t\tsourceRoot := arg[len(\"--source-root=\"):]\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.SourceRoot = sourceRoot\n\t\t\t} else {\n\t\t\t\ttransformOpts.SourceRoot = sourceRoot\n\t\t\t}\n\n\t\tcase isBoolFlag(arg, \"--sources-content\"):\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else {\n\t\t\t\tvar sourcesContent *api.SourcesContent\n\t\t\t\tif buildOpts != nil {\n\t\t\t\t\tsourcesContent = &buildOpts.SourcesContent\n\t\t\t\t} else {\n\t\t\t\t\tsourcesContent = &transformOpts.SourcesContent\n\t\t\t\t}\n\t\t\t\tif value {\n\t\t\t\t\t*sourcesContent = api.SourcesContentInclude\n\t\t\t\t} else {\n\t\t\t\t\t*sourcesContent = api.SourcesContentExclude\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--sourcefile=\"):\n\t\t\tif buildOpts != nil {\n\t\t\t\tif buildOpts.Stdin == nil {\n\t\t\t\t\tbuildOpts.Stdin = &api.StdinOptions{}\n\t\t\t\t}\n\t\t\t\tbuildOpts.Stdin.Sourcefile = arg[len(\"--sourcefile=\"):]\n\t\t\t} else {\n\t\t\t\ttransformOpts.Sourcefile = arg[len(\"--sourcefile=\"):]\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--resolve-extensions=\") && buildOpts != nil:\n\t\t\tbuildOpts.ResolveExtensions = splitWithEmptyCheck(arg[len(\"--resolve-extensions=\"):], \",\")\n\n\t\tcase strings.HasPrefix(arg, \"--main-fields=\") && buildOpts != nil:\n\t\t\tbuildOpts.MainFields = splitWithEmptyCheck(arg[len(\"--main-fields=\"):], \",\")\n\n\t\tcase strings.HasPrefix(arg, \"--conditions=\") && buildOpts != nil:\n\t\t\tbuildOpts.Conditions = splitWithEmptyCheck(arg[len(\"--conditions=\"):], \",\")\n\n\t\tcase strings.HasPrefix(arg, \"--public-path=\") && buildOpts != nil:\n\t\t\tbuildOpts.PublicPath = arg[len(\"--public-path=\"):]\n\n\t\tcase strings.HasPrefix(arg, \"--global-name=\"):\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.GlobalName = arg[len(\"--global-name=\"):]\n\t\t\t} else {\n\t\t\t\ttransformOpts.GlobalName = arg[len(\"--global-name=\"):]\n\t\t\t}\n\n\t\tcase arg == \"--metafile\" && buildOpts != nil && kind == kindExternal:\n\t\t\tbuildOpts.Metafile = true\n\n\t\tcase strings.HasPrefix(arg, \"--metafile=\") && buildOpts != nil && kind == kindInternal:\n\t\t\tvalue := arg[len(\"--metafile=\"):]\n\t\t\tbuildOpts.Metafile = true\n\t\t\textras.metafile = &value\n\n\t\tcase strings.HasPrefix(arg, \"--outfile=\") && buildOpts != nil:\n\t\t\tbuildOpts.Outfile = arg[len(\"--outfile=\"):]\n\n\t\tcase strings.HasPrefix(arg, \"--outdir=\") && buildOpts != nil:\n\t\t\tbuildOpts.Outdir = arg[len(\"--outdir=\"):]\n\n\t\tcase strings.HasPrefix(arg, \"--outbase=\") && buildOpts != nil:\n\t\t\tbuildOpts.Outbase = arg[len(\"--outbase=\"):]\n\n\t\tcase strings.HasPrefix(arg, \"--tsconfig=\") && buildOpts != nil:\n\t\t\tbuildOpts.Tsconfig = arg[len(\"--tsconfig=\"):]\n\n\t\tcase strings.HasPrefix(arg, \"--tsconfig-raw=\"):\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.TsconfigRaw = arg[len(\"--tsconfig-raw=\"):]\n\t\t\t} else {\n\t\t\t\ttransformOpts.TsconfigRaw = arg[len(\"--tsconfig-raw=\"):]\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--entry-names=\") && buildOpts != nil:\n\t\t\tbuildOpts.EntryNames = arg[len(\"--entry-names=\"):]\n\n\t\tcase strings.HasPrefix(arg, \"--chunk-names=\") && buildOpts != nil:\n\t\t\tbuildOpts.ChunkNames = arg[len(\"--chunk-names=\"):]\n\n\t\tcase strings.HasPrefix(arg, \"--asset-names=\") && buildOpts != nil:\n\t\t\tbuildOpts.AssetNames = arg[len(\"--asset-names=\"):]\n\n\t\tcase strings.HasPrefix(arg, \"--define:\"):\n\t\t\tvalue := arg[len(\"--define:\"):]\n\t\t\tequals := strings.IndexByte(value, '=')\n\t\t\tif equals == -1 {\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Missing \\\"=\\\" in %q\", arg),\n\t\t\t\t\t\"You need to use \\\"=\\\" to specify both the original value and the replacement value. \"+\n\t\t\t\t\t\t\"For example, \\\"--define:DEBUG=true\\\" replaces \\\"DEBUG\\\" with \\\"true\\\".\",\n\t\t\t\t)\n\t\t\t}\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.Define[value[:equals]] = value[equals+1:]\n\t\t\t} else {\n\t\t\t\ttransformOpts.Define[value[:equals]] = value[equals+1:]\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--log-override:\"):\n\t\t\tvalue := arg[len(\"--log-override:\"):]\n\t\t\tequals := strings.IndexByte(value, '=')\n\t\t\tif equals == -1 {\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Missing \\\"=\\\" in %q\", arg),\n\t\t\t\t\t\"You need to use \\\"=\\\" to specify both the message name and the log level. \"+\n\t\t\t\t\t\t\"For example, \\\"--log-override:css-syntax-error=error\\\" turns all \\\"css-syntax-error\\\" log messages into errors.\",\n\t\t\t\t)\n\t\t\t}\n\t\t\tlogLevel, err := parseLogLevel(value[equals+1:], arg)\n\t\t\tif err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t}\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.LogOverride[value[:equals]] = logLevel\n\t\t\t} else {\n\t\t\t\ttransformOpts.LogOverride[value[:equals]] = logLevel\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--abs-paths=\"):\n\t\t\tvalues := splitWithEmptyCheck(arg[len(\"--abs-paths=\"):], \",\")\n\t\t\tvar absPaths api.AbsPaths\n\t\t\tfor _, value := range values {\n\t\t\t\tswitch value {\n\t\t\t\tcase \"code\":\n\t\t\t\t\tabsPaths |= api.CodeAbsPath\n\t\t\t\tcase \"log\":\n\t\t\t\t\tabsPaths |= api.LogAbsPath\n\t\t\t\tcase \"metafile\":\n\t\t\t\t\tabsPaths |= api.MetafileAbsPath\n\t\t\t\tdefault:\n\t\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\t\tfmt.Sprintf(\"Invalid value %q in %q\", value, arg),\n\t\t\t\t\t\t\"Valid values are \\\"code\\\", \\\"log\\\", or \\\"metafile\\\".\",\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.AbsPaths = absPaths\n\t\t\t} else {\n\t\t\t\ttransformOpts.AbsPaths = absPaths\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--supported:\"):\n\t\t\tvalue := arg[len(\"--supported:\"):]\n\t\t\tequals := strings.IndexByte(value, '=')\n\t\t\tif equals == -1 {\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Missing \\\"=\\\" in %q\", arg),\n\t\t\t\t\t\"You need to use \\\"=\\\" to specify both the name of the feature and whether it is supported or not. \"+\n\t\t\t\t\t\t\"For example, \\\"--supported:arrow=false\\\" marks arrow functions as unsupported.\",\n\t\t\t\t)\n\t\t\t}\n\t\t\tif isSupported, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else if buildOpts != nil {\n\t\t\t\tbuildOpts.Supported[value[:equals]] = isSupported\n\t\t\t} else {\n\t\t\t\ttransformOpts.Supported[value[:equals]] = isSupported\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--pure:\"):\n\t\t\tvalue := arg[len(\"--pure:\"):]\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.Pure = append(buildOpts.Pure, value)\n\t\t\t} else {\n\t\t\t\ttransformOpts.Pure = append(transformOpts.Pure, value)\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--loader:\") && buildOpts != nil:\n\t\t\tvalue := arg[len(\"--loader:\"):]\n\t\t\tequals := strings.IndexByte(value, '=')\n\t\t\tif equals == -1 {\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Missing \\\"=\\\" in %q\", arg),\n\t\t\t\t\t\"You need to specify the file extension that the loader applies to. \"+\n\t\t\t\t\t\t\"For example, \\\"--loader:.js=jsx\\\" applies the \\\"jsx\\\" loader to files with the \\\".js\\\" extension.\",\n\t\t\t\t)\n\t\t\t}\n\t\t\text, text := value[:equals], value[equals+1:]\n\t\t\tloader, err := cli_helpers.ParseLoader(text)\n\t\t\tif err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t}\n\t\t\tbuildOpts.Loader[ext] = loader\n\n\t\tcase strings.HasPrefix(arg, \"--loader=\"):\n\t\t\tvalue := arg[len(\"--loader=\"):]\n\t\t\tloader, err := cli_helpers.ParseLoader(value)\n\t\t\tif err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t}\n\t\t\tif loader == api.LoaderFile || loader == api.LoaderCopy {\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"%q is not supported when transforming stdin\", arg),\n\t\t\t\t\tfmt.Sprintf(\"Using esbuild to transform stdin only generates one output file, so you cannot use the %q loader \"+\n\t\t\t\t\t\t\"since that needs to generate two output files.\", value),\n\t\t\t\t)\n\t\t\t}\n\t\t\tif buildOpts != nil {\n\t\t\t\tif buildOpts.Stdin == nil {\n\t\t\t\t\tbuildOpts.Stdin = &api.StdinOptions{}\n\t\t\t\t}\n\t\t\t\tbuildOpts.Stdin.Loader = loader\n\t\t\t} else {\n\t\t\t\ttransformOpts.Loader = loader\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--target=\"):\n\t\t\ttarget, engines, err := parseTargets(splitWithEmptyCheck(arg[len(\"--target=\"):], \",\"), arg)\n\t\t\tif err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t}\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.Target = target\n\t\t\t\tbuildOpts.Engines = engines\n\t\t\t} else {\n\t\t\t\ttransformOpts.Target = target\n\t\t\t\ttransformOpts.Engines = engines\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--out-extension:\") && buildOpts != nil:\n\t\t\tvalue := arg[len(\"--out-extension:\"):]\n\t\t\tequals := strings.IndexByte(value, '=')\n\t\t\tif equals == -1 {\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Missing \\\"=\\\" in %q\", arg),\n\t\t\t\t\t\"You need to use either \\\"--out-extension:.js=...\\\" or \\\"--out-extension:.css=...\\\" \"+\n\t\t\t\t\t\t\"to specify the file type that the output extension applies to .\",\n\t\t\t\t)\n\t\t\t}\n\t\t\tif buildOpts.OutExtension == nil {\n\t\t\t\tbuildOpts.OutExtension = make(map[string]string)\n\t\t\t}\n\t\t\tbuildOpts.OutExtension[value[:equals]] = value[equals+1:]\n\n\t\tcase strings.HasPrefix(arg, \"--platform=\"):\n\t\t\tvalue := arg[len(\"--platform=\"):]\n\t\t\tvar platform api.Platform\n\t\t\tswitch value {\n\t\t\tcase \"browser\":\n\t\t\t\tplatform = api.PlatformBrowser\n\t\t\tcase \"node\":\n\t\t\t\tplatform = api.PlatformNode\n\t\t\tcase \"neutral\":\n\t\t\t\tplatform = api.PlatformNeutral\n\t\t\tdefault:\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Invalid value %q in %q\", value, arg),\n\t\t\t\t\t\"Valid values are \\\"browser\\\", \\\"node\\\", or \\\"neutral\\\".\",\n\t\t\t\t)\n\t\t\t}\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.Platform = platform\n\t\t\t} else {\n\t\t\t\ttransformOpts.Platform = platform\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--format=\"):\n\t\t\tvalue := arg[len(\"--format=\"):]\n\t\t\tvar format api.Format\n\t\t\tswitch value {\n\t\t\tcase \"iife\":\n\t\t\t\tformat = api.FormatIIFE\n\t\t\tcase \"cjs\":\n\t\t\t\tformat = api.FormatCommonJS\n\t\t\tcase \"esm\":\n\t\t\t\tformat = api.FormatESModule\n\t\t\tdefault:\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Invalid value %q in %q\", value, arg),\n\t\t\t\t\t\"Valid values are \\\"iife\\\", \\\"cjs\\\", or \\\"esm\\\".\",\n\t\t\t\t)\n\t\t\t}\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.Format = format\n\t\t\t} else {\n\t\t\t\ttransformOpts.Format = format\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--packages=\") && buildOpts != nil:\n\t\t\tvalue := arg[len(\"--packages=\"):]\n\t\t\tvar packages api.Packages\n\t\t\tswitch value {\n\t\t\tcase \"bundle\":\n\t\t\t\tpackages = api.PackagesBundle\n\t\t\tcase \"external\":\n\t\t\t\tpackages = api.PackagesExternal\n\t\t\tdefault:\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Invalid value %q in %q\", value, arg),\n\t\t\t\t\t\"Valid values are \\\"bundle\\\" or \\\"external\\\".\",\n\t\t\t\t)\n\t\t\t}\n\t\t\tbuildOpts.Packages = packages\n\n\t\tcase strings.HasPrefix(arg, \"--external:\") && buildOpts != nil:\n\t\t\tbuildOpts.External = append(buildOpts.External, arg[len(\"--external:\"):])\n\n\t\tcase strings.HasPrefix(arg, \"--inject:\") && buildOpts != nil:\n\t\t\tbuildOpts.Inject = append(buildOpts.Inject, arg[len(\"--inject:\"):])\n\n\t\tcase strings.HasPrefix(arg, \"--alias:\") && buildOpts != nil:\n\t\t\tvalue := arg[len(\"--alias:\"):]\n\t\t\tequals := strings.IndexByte(value, '=')\n\t\t\tif equals == -1 {\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Missing \\\"=\\\" in %q\", arg),\n\t\t\t\t\t\"You need to use \\\"=\\\" to specify both the original package name and the replacement package name. \"+\n\t\t\t\t\t\t\"For example, \\\"--alias:old=new\\\" replaces package \\\"old\\\" with package \\\"new\\\".\",\n\t\t\t\t)\n\t\t\t}\n\t\t\tif buildOpts.Alias == nil {\n\t\t\t\tbuildOpts.Alias = make(map[string]string)\n\t\t\t}\n\t\t\tbuildOpts.Alias[value[:equals]] = value[equals+1:]\n\n\t\tcase strings.HasPrefix(arg, \"--jsx=\"):\n\t\t\tvalue := arg[len(\"--jsx=\"):]\n\t\t\tvar mode api.JSX\n\t\t\tswitch value {\n\t\t\tcase \"transform\":\n\t\t\t\tmode = api.JSXTransform\n\t\t\tcase \"preserve\":\n\t\t\t\tmode = api.JSXPreserve\n\t\t\tcase \"automatic\":\n\t\t\t\tmode = api.JSXAutomatic\n\t\t\tdefault:\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Invalid value %q in %q\", value, arg),\n\t\t\t\t\t\"Valid values are \\\"transform\\\", \\\"automatic\\\", or \\\"preserve\\\".\",\n\t\t\t\t)\n\t\t\t}\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.JSX = mode\n\t\t\t} else {\n\t\t\t\ttransformOpts.JSX = mode\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--jsx-factory=\"):\n\t\t\tvalue := arg[len(\"--jsx-factory=\"):]\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.JSXFactory = value\n\t\t\t} else {\n\t\t\t\ttransformOpts.JSXFactory = value\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--jsx-fragment=\"):\n\t\t\tvalue := arg[len(\"--jsx-fragment=\"):]\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.JSXFragment = value\n\t\t\t} else {\n\t\t\t\ttransformOpts.JSXFragment = value\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--jsx-import-source=\"):\n\t\t\tvalue := arg[len(\"--jsx-import-source=\"):]\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.JSXImportSource = value\n\t\t\t} else {\n\t\t\t\ttransformOpts.JSXImportSource = value\n\t\t\t}\n\n\t\tcase isBoolFlag(arg, \"--jsx-dev\"):\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else if buildOpts != nil {\n\t\t\t\tbuildOpts.JSXDev = value\n\t\t\t} else {\n\t\t\t\ttransformOpts.JSXDev = value\n\t\t\t}\n\n\t\tcase isBoolFlag(arg, \"--jsx-side-effects\"):\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else if buildOpts != nil {\n\t\t\t\tbuildOpts.JSXSideEffects = value\n\t\t\t} else {\n\t\t\t\ttransformOpts.JSXSideEffects = value\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--banner=\") && transformOpts != nil:\n\t\t\ttransformOpts.Banner = arg[len(\"--banner=\"):]\n\n\t\tcase strings.HasPrefix(arg, \"--footer=\") && transformOpts != nil:\n\t\t\ttransformOpts.Footer = arg[len(\"--footer=\"):]\n\n\t\tcase strings.HasPrefix(arg, \"--banner:\") && buildOpts != nil:\n\t\t\tvalue := arg[len(\"--banner:\"):]\n\t\t\tequals := strings.IndexByte(value, '=')\n\t\t\tif equals == -1 {\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Missing \\\"=\\\" in %q\", arg),\n\t\t\t\t\t\"You need to use either \\\"--banner:js=...\\\" or \\\"--banner:css=...\\\" to specify the language that the banner applies to.\",\n\t\t\t\t)\n\t\t\t}\n\t\t\tbuildOpts.Banner[value[:equals]] = value[equals+1:]\n\n\t\tcase strings.HasPrefix(arg, \"--footer:\") && buildOpts != nil:\n\t\t\tvalue := arg[len(\"--footer:\"):]\n\t\t\tequals := strings.IndexByte(value, '=')\n\t\t\tif equals == -1 {\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Missing \\\"=\\\" in %q\", arg),\n\t\t\t\t\t\"You need to use either \\\"--footer:js=...\\\" or \\\"--footer:css=...\\\" to specify the language that the footer applies to.\",\n\t\t\t\t)\n\t\t\t}\n\t\t\tbuildOpts.Footer[value[:equals]] = value[equals+1:]\n\n\t\tcase strings.HasPrefix(arg, \"--log-limit=\"):\n\t\t\tvalue := arg[len(\"--log-limit=\"):]\n\t\t\tlimit, err := strconv.Atoi(value)\n\t\t\tif err != nil || limit < 0 {\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Invalid value %q in %q\", value, arg),\n\t\t\t\t\t\"The log limit must be a non-negative integer.\",\n\t\t\t\t)\n\t\t\t}\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.LogLimit = limit\n\t\t\t} else {\n\t\t\t\ttransformOpts.LogLimit = limit\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"--line-limit=\"):\n\t\t\tvalue := arg[len(\"--line-limit=\"):]\n\t\t\tlimit, err := strconv.Atoi(value)\n\t\t\tif err != nil || limit < 0 {\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\tfmt.Sprintf(\"Invalid value %q in %q\", value, arg),\n\t\t\t\t\t\"The line limit must be a non-negative integer.\",\n\t\t\t\t)\n\t\t\t}\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.LineLimit = limit\n\t\t\t} else {\n\t\t\t\ttransformOpts.LineLimit = limit\n\t\t\t}\n\n\t\t\t// Make sure this stays in sync with \"PrintErrorToStderr\"\n\t\tcase isBoolFlag(arg, \"--color\"):\n\t\t\tif value, err := parseBoolFlag(arg, true); err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t} else {\n\t\t\t\tvar color *api.StderrColor\n\t\t\t\tif buildOpts != nil {\n\t\t\t\t\tcolor = &buildOpts.Color\n\t\t\t\t} else {\n\t\t\t\t\tcolor = &transformOpts.Color\n\t\t\t\t}\n\t\t\t\tif value {\n\t\t\t\t\t*color = api.ColorAlways\n\t\t\t\t} else {\n\t\t\t\t\t*color = api.ColorNever\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Make sure this stays in sync with \"PrintErrorToStderr\"\n\t\tcase strings.HasPrefix(arg, \"--log-level=\"):\n\t\t\tvalue := arg[len(\"--log-level=\"):]\n\t\t\tlogLevel, err := parseLogLevel(value, arg)\n\t\t\tif err != nil {\n\t\t\t\treturn parseOptionsExtras{}, err\n\t\t\t}\n\t\t\tif buildOpts != nil {\n\t\t\t\tbuildOpts.LogLevel = logLevel\n\t\t\t} else {\n\t\t\t\ttransformOpts.LogLevel = logLevel\n\t\t\t}\n\n\t\tcase strings.HasPrefix(arg, \"'--\"):\n\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\t\tfmt.Sprintf(\"Unexpected single quote character before flag: %s\", arg),\n\t\t\t\t\"This typically happens when attempting to use single quotes to quote arguments with a shell that doesn't recognize single quotes. \"+\n\t\t\t\t\t\"Try using double quote characters to quote arguments instead.\",\n\t\t\t)\n\n\t\tcase !strings.HasPrefix(arg, \"-\") && buildOpts != nil:\n\t\t\tif equals := strings.IndexByte(arg, '='); equals != -1 {\n\t\t\t\tbuildOpts.EntryPointsAdvanced = append(buildOpts.EntryPointsAdvanced, api.EntryPoint{\n\t\t\t\t\tOutputPath: arg[:equals],\n\t\t\t\t\tInputPath:  arg[equals+1:],\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tbuildOpts.EntryPoints = append(buildOpts.EntryPoints, arg)\n\t\t\t}\n\n\t\tdefault:\n\t\t\tbare := map[string]bool{\n\t\t\t\t\"allow-overwrite\":    true,\n\t\t\t\t\"bundle\":             true,\n\t\t\t\t\"ignore-annotations\": true,\n\t\t\t\t\"jsx-dev\":            true,\n\t\t\t\t\"jsx-side-effects\":   true,\n\t\t\t\t\"keep-names\":         true,\n\t\t\t\t\"minify-identifiers\": true,\n\t\t\t\t\"minify-syntax\":      true,\n\t\t\t\t\"minify-whitespace\":  true,\n\t\t\t\t\"minify\":             true,\n\t\t\t\t\"preserve-symlinks\":  true,\n\t\t\t\t\"sourcemap\":          true,\n\t\t\t\t\"splitting\":          true,\n\t\t\t\t\"watch\":              true,\n\t\t\t}\n\n\t\t\tequals := map[string]bool{\n\t\t\t\t\"abs-paths\":          true,\n\t\t\t\t\"allow-overwrite\":    true,\n\t\t\t\t\"asset-names\":        true,\n\t\t\t\t\"banner\":             true,\n\t\t\t\t\"bundle\":             true,\n\t\t\t\t\"certfile\":           true,\n\t\t\t\t\"charset\":            true,\n\t\t\t\t\"chunk-names\":        true,\n\t\t\t\t\"color\":              true,\n\t\t\t\t\"conditions\":         true,\n\t\t\t\t\"cors-origin\":        true,\n\t\t\t\t\"drop-labels\":        true,\n\t\t\t\t\"entry-names\":        true,\n\t\t\t\t\"footer\":             true,\n\t\t\t\t\"format\":             true,\n\t\t\t\t\"global-name\":        true,\n\t\t\t\t\"ignore-annotations\": true,\n\t\t\t\t\"jsx-factory\":        true,\n\t\t\t\t\"jsx-fragment\":       true,\n\t\t\t\t\"jsx-import-source\":  true,\n\t\t\t\t\"jsx\":                true,\n\t\t\t\t\"keep-names\":         true,\n\t\t\t\t\"keyfile\":            true,\n\t\t\t\t\"legal-comments\":     true,\n\t\t\t\t\"loader\":             true,\n\t\t\t\t\"log-level\":          true,\n\t\t\t\t\"log-limit\":          true,\n\t\t\t\t\"main-fields\":        true,\n\t\t\t\t\"mangle-cache\":       true,\n\t\t\t\t\"mangle-props\":       true,\n\t\t\t\t\"mangle-quoted\":      true,\n\t\t\t\t\"metafile\":           true,\n\t\t\t\t\"minify-identifiers\": true,\n\t\t\t\t\"minify-syntax\":      true,\n\t\t\t\t\"minify-whitespace\":  true,\n\t\t\t\t\"minify\":             true,\n\t\t\t\t\"outbase\":            true,\n\t\t\t\t\"outdir\":             true,\n\t\t\t\t\"outfile\":            true,\n\t\t\t\t\"packages\":           true,\n\t\t\t\t\"platform\":           true,\n\t\t\t\t\"preserve-symlinks\":  true,\n\t\t\t\t\"public-path\":        true,\n\t\t\t\t\"reserve-props\":      true,\n\t\t\t\t\"resolve-extensions\": true,\n\t\t\t\t\"serve-fallback\":     true,\n\t\t\t\t\"serve\":              true,\n\t\t\t\t\"servedir\":           true,\n\t\t\t\t\"source-root\":        true,\n\t\t\t\t\"sourcefile\":         true,\n\t\t\t\t\"sourcemap\":          true,\n\t\t\t\t\"sources-content\":    true,\n\t\t\t\t\"splitting\":          true,\n\t\t\t\t\"target\":             true,\n\t\t\t\t\"tree-shaking\":       true,\n\t\t\t\t\"tsconfig-raw\":       true,\n\t\t\t\t\"tsconfig\":           true,\n\t\t\t\t\"watch\":              true,\n\t\t\t\t\"watch-delay\":        true,\n\t\t\t}\n\n\t\t\tcolon := map[string]bool{\n\t\t\t\t\"alias\":         true,\n\t\t\t\t\"banner\":        true,\n\t\t\t\t\"define\":        true,\n\t\t\t\t\"drop\":          true,\n\t\t\t\t\"external\":      true,\n\t\t\t\t\"footer\":        true,\n\t\t\t\t\"inject\":        true,\n\t\t\t\t\"loader\":        true,\n\t\t\t\t\"log-override\":  true,\n\t\t\t\t\"out-extension\": true,\n\t\t\t\t\"pure\":          true,\n\t\t\t\t\"supported\":     true,\n\t\t\t}\n\n\t\t\tnote := \"\"\n\n\t\t\t// Try to provide helpful hints when we can recognize the mistake\n\t\t\tswitch {\n\t\t\tcase arg == \"-o\":\n\t\t\t\tnote = \"Use \\\"--outfile=\\\" to configure the output file instead of \\\"-o\\\".\"\n\n\t\t\tcase arg == \"-v\":\n\t\t\t\tnote = \"Use \\\"--log-level=verbose\\\" to generate verbose logs instead of \\\"-v\\\".\"\n\n\t\t\tcase strings.HasPrefix(arg, \"--\"):\n\t\t\t\tif i := strings.IndexByte(arg, '='); i != -1 && colon[arg[2:i]] {\n\t\t\t\t\tnote = fmt.Sprintf(\"Use %q instead of %q. Flags that can be re-specified multiple times use \\\":\\\" instead of \\\"=\\\".\",\n\t\t\t\t\t\targ[:i]+\":\"+arg[i+1:], arg)\n\t\t\t\t}\n\n\t\t\t\tif i := strings.IndexByte(arg, ':'); i != -1 && equals[arg[2:i]] {\n\t\t\t\t\tnote = fmt.Sprintf(\"Use %q instead of %q. Flags that can only be specified once use \\\"=\\\" instead of \\\":\\\".\",\n\t\t\t\t\t\targ[:i]+\"=\"+arg[i+1:], arg)\n\t\t\t\t}\n\n\t\t\tcase strings.HasPrefix(arg, \"-\"):\n\t\t\t\tisValid := bare[arg[1:]]\n\t\t\t\tfix := \"-\" + arg\n\n\t\t\t\tif i := strings.IndexByte(arg, '='); i != -1 && equals[arg[1:i]] {\n\t\t\t\t\tisValid = true\n\t\t\t\t} else if i != -1 && colon[arg[1:i]] {\n\t\t\t\t\tisValid = true\n\t\t\t\t\tfix = fmt.Sprintf(\"-%s:%s\", arg[:i], arg[i+1:])\n\t\t\t\t} else if i := strings.IndexByte(arg, ':'); i != -1 && colon[arg[1:i]] {\n\t\t\t\t\tisValid = true\n\t\t\t\t} else if i != -1 && equals[arg[1:i]] {\n\t\t\t\t\tisValid = true\n\t\t\t\t\tfix = fmt.Sprintf(\"-%s=%s\", arg[:i], arg[i+1:])\n\t\t\t\t}\n\n\t\t\t\tif isValid {\n\t\t\t\t\tnote = fmt.Sprintf(\"Use %q instead of %q. Flags are always specified with two dashes instead of one dash.\",\n\t\t\t\t\t\tfix, arg)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif buildOpts != nil {\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(fmt.Sprintf(\"Invalid build flag: %q\", arg), note)\n\t\t\t} else {\n\t\t\t\treturn parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(fmt.Sprintf(\"Invalid transform flag: %q\", arg), note)\n\t\t\t}\n\t\t}\n\t}\n\n\t// If we're building, the last source map flag is \"--sourcemap\", and there\n\t// is no output path, change the source map option to \"inline\" because we're\n\t// going to be writing to stdout which can only represent a single file.\n\tif buildOpts != nil && hasBareSourceMapFlag && buildOpts.Outfile == \"\" && buildOpts.Outdir == \"\" {\n\t\tbuildOpts.Sourcemap = api.SourceMapInline\n\t}\n\n\treturn\n}\n\nfunc parseTargets(targets []string, arg string) (target api.Target, engines []api.Engine, err *cli_helpers.ErrorWithNote) {\n\tvalidTargets := map[string]api.Target{\n\t\t\"esnext\": api.ESNext,\n\t\t\"es5\":    api.ES5,\n\t\t\"es6\":    api.ES2015,\n\t\t\"es2015\": api.ES2015,\n\t\t\"es2016\": api.ES2016,\n\t\t\"es2017\": api.ES2017,\n\t\t\"es2018\": api.ES2018,\n\t\t\"es2019\": api.ES2019,\n\t\t\"es2020\": api.ES2020,\n\t\t\"es2021\": api.ES2021,\n\t\t\"es2022\": api.ES2022,\n\t\t\"es2023\": api.ES2023,\n\t\t\"es2024\": api.ES2024,\n\t}\n\nouter:\n\tfor _, value := range targets {\n\t\tif valid, ok := validTargets[strings.ToLower(value)]; ok {\n\t\t\ttarget = valid\n\t\t\tcontinue\n\t\t}\n\n\t\tfor engine, name := range validEngines {\n\t\t\tif strings.HasPrefix(value, engine) {\n\t\t\t\tversion := value[len(engine):]\n\t\t\t\tif version == \"\" {\n\t\t\t\t\treturn 0, nil, cli_helpers.MakeErrorWithNote(\n\t\t\t\t\t\tfmt.Sprintf(\"Target %q is missing a version number in %q\", value, arg),\n\t\t\t\t\t\t\"\",\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tengines = append(engines, api.Engine{Name: name, Version: version})\n\t\t\t\tcontinue outer\n\t\t\t}\n\t\t}\n\n\t\tengines := make([]string, 0, len(validEngines))\n\t\tengines = append(engines, \"\\\"esN\\\"\")\n\t\tfor key := range validEngines {\n\t\t\tengines = append(engines, fmt.Sprintf(\"%q\", key+\"N\"))\n\t\t}\n\t\tsort.Strings(engines)\n\t\treturn 0, nil, cli_helpers.MakeErrorWithNote(\n\t\t\tfmt.Sprintf(\"Invalid target %q in %q\", value, arg),\n\t\t\tfmt.Sprintf(\"Valid values are %s, or %s where N is a version number.\",\n\t\t\t\tstrings.Join(engines[:len(engines)-1], \", \"), engines[len(engines)-1]),\n\t\t)\n\t}\n\treturn\n}\n\nfunc isArgForBuild(arg string) bool {\n\treturn !strings.HasPrefix(arg, \"-\") || arg == \"--bundle\"\n}\n\n// This returns either BuildOptions, TransformOptions, or an error\nfunc parseOptionsForRun(osArgs []string) (*api.BuildOptions, *api.TransformOptions, parseOptionsExtras, *cli_helpers.ErrorWithNote) {\n\t// If there's an entry point or we're bundling, then we're building\n\tfor _, arg := range osArgs {\n\t\tif isArgForBuild(arg) {\n\t\t\toptions := newBuildOptions()\n\n\t\t\t// Apply defaults appropriate for the CLI\n\t\t\toptions.LogLimit = 6\n\t\t\toptions.LogLevel = api.LogLevelInfo\n\t\t\toptions.Write = true\n\n\t\t\textras, err := parseOptionsImpl(osArgs, &options, nil, kindInternal)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, nil, parseOptionsExtras{}, err\n\t\t\t}\n\t\t\treturn &options, nil, extras, nil\n\t\t}\n\t}\n\n\t// Otherwise, we're transforming\n\toptions := newTransformOptions()\n\n\t// Apply defaults appropriate for the CLI\n\toptions.LogLimit = 6\n\toptions.LogLevel = api.LogLevelInfo\n\n\t_, err := parseOptionsImpl(osArgs, nil, &options, kindInternal)\n\tif err != nil {\n\t\treturn nil, nil, parseOptionsExtras{}, err\n\t}\n\tif options.Sourcemap != api.SourceMapNone && options.Sourcemap != api.SourceMapInline {\n\t\tvar sourceMapMode string\n\t\tswitch options.Sourcemap {\n\t\tcase api.SourceMapExternal:\n\t\t\tsourceMapMode = \"external\"\n\t\tcase api.SourceMapInlineAndExternal:\n\t\t\tsourceMapMode = \"both\"\n\t\tcase api.SourceMapLinked:\n\t\t\tsourceMapMode = \"linked\"\n\t\t}\n\t\treturn nil, nil, parseOptionsExtras{}, cli_helpers.MakeErrorWithNote(\n\t\t\tfmt.Sprintf(\"Use \\\"--sourcemap\\\" instead of \\\"--sourcemap=%s\\\" when transforming stdin\", sourceMapMode),\n\t\t\tfmt.Sprintf(\"Using esbuild to transform stdin only generates one output file. You cannot use the %q source map mode \"+\n\t\t\t\t\"since that needs to generate two output files.\", sourceMapMode),\n\t\t)\n\t}\n\treturn nil, &options, parseOptionsExtras{}, nil\n}\n\nfunc splitWithEmptyCheck(s string, sep string) []string {\n\t// Special-case the empty string to return [] instead of [\"\"]\n\tif s == \"\" {\n\t\treturn []string{}\n\t}\n\n\treturn strings.Split(s, sep)\n}\n\ntype analyzeMode uint8\n\nconst (\n\tanalyzeDisabled analyzeMode = iota\n\tanalyzeEnabled\n\tanalyzeVerbose\n)\n\nfunc filterAnalyzeFlags(osArgs []string) ([]string, analyzeMode) {\n\tfor _, arg := range osArgs {\n\t\tif isArgForBuild(arg) {\n\t\t\tanalyze := analyzeDisabled\n\t\t\tend := 0\n\t\t\tfor _, arg := range osArgs {\n\t\t\t\tswitch arg {\n\t\t\t\tcase \"--analyze\":\n\t\t\t\t\tanalyze = analyzeEnabled\n\t\t\t\tcase \"--analyze=verbose\":\n\t\t\t\t\tanalyze = analyzeVerbose\n\t\t\t\tdefault:\n\t\t\t\t\tosArgs[end] = arg\n\t\t\t\t\tend++\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn osArgs[:end], analyze\n\t\t}\n\t}\n\treturn osArgs, analyzeDisabled\n}\n\n// Print metafile analysis after the build if it's enabled\nfunc addAnalyzePlugin(buildOptions *api.BuildOptions, analyze analyzeMode, osArgs []string) {\n\tbuildOptions.Plugins = append(buildOptions.Plugins, api.Plugin{\n\t\tName: \"PrintAnalysis\",\n\t\tSetup: func(build api.PluginBuild) {\n\t\t\tcolor := logger.OutputOptionsForArgs(osArgs).Color\n\t\t\tbuild.OnEnd(func(result *api.BuildResult) (api.OnEndResult, error) {\n\t\t\t\tif result.Metafile != \"\" {\n\t\t\t\t\tlogger.PrintTextWithColor(os.Stderr, color, func(colors logger.Colors) string {\n\t\t\t\t\t\treturn api.AnalyzeMetafile(result.Metafile, api.AnalyzeMetafileOptions{\n\t\t\t\t\t\t\tColor:   colors != logger.Colors{},\n\t\t\t\t\t\t\tVerbose: analyze == analyzeVerbose,\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t\tos.Stderr.WriteString(\"\\n\")\n\t\t\t\t}\n\t\t\t\treturn api.OnEndResult{}, nil\n\t\t\t})\n\t\t},\n\t})\n\n\t// Always generate a metafile if we're analyzing, even if it won't be written out\n\tbuildOptions.Metafile = true\n}\n\nfunc runImpl(osArgs []string, plugins []api.Plugin) int {\n\t// Special-case running a server\n\tfor _, arg := range osArgs {\n\t\tif arg == \"--serve\" ||\n\t\t\tstrings.HasPrefix(arg, \"--serve=\") ||\n\t\t\tstrings.HasPrefix(arg, \"--servedir=\") ||\n\t\t\tstrings.HasPrefix(arg, \"--serve-fallback=\") {\n\t\t\tserveImpl(osArgs)\n\t\t\treturn 1 // There was an error starting the server if we get here\n\t\t}\n\t}\n\n\tosArgs, analyze := filterAnalyzeFlags(osArgs)\n\tbuildOptions, transformOptions, extras, err := parseOptionsForRun(osArgs)\n\n\t// Add any plugins from the caller after parsing the build options\n\tif buildOptions != nil {\n\t\tbuildOptions.Plugins = append(buildOptions.Plugins, plugins...)\n\n\t\t// The \"--analyze\" flag is implemented as a plugin\n\t\tif analyze != analyzeDisabled {\n\t\t\taddAnalyzePlugin(buildOptions, analyze, osArgs)\n\t\t}\n\t}\n\n\tswitch {\n\tcase buildOptions != nil:\n\t\t// Read the \"NODE_PATH\" from the environment. This is part of node's\n\t\t// module resolution algorithm. Documentation for this can be found here:\n\t\t// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders\n\t\tif value, ok := os.LookupEnv(\"NODE_PATH\"); ok {\n\t\t\tseparator := \":\"\n\t\t\tif fs.CheckIfWindows() {\n\t\t\t\t// On Windows, NODE_PATH is delimited by semicolons instead of colons\n\t\t\t\tseparator = \";\"\n\t\t\t}\n\t\t\tbuildOptions.NodePaths = splitWithEmptyCheck(value, separator)\n\t\t}\n\n\t\t// Read from stdin when there are no entry points\n\t\tif len(buildOptions.EntryPoints)+len(buildOptions.EntryPointsAdvanced) == 0 {\n\t\t\tif buildOptions.Stdin == nil {\n\t\t\t\tbuildOptions.Stdin = &api.StdinOptions{}\n\t\t\t}\n\t\t\tbytes, err := ioutil.ReadAll(os.Stdin)\n\t\t\tif err != nil {\n\t\t\t\tlogger.PrintErrorToStderr(osArgs, fmt.Sprintf(\n\t\t\t\t\t\"Could not read from stdin: %s\", err.Error()))\n\t\t\t\treturn 1\n\t\t\t}\n\t\t\tbuildOptions.Stdin.Contents = string(bytes)\n\t\t\tbuildOptions.Stdin.ResolveDir, _ = os.Getwd()\n\t\t} else if buildOptions.Stdin != nil {\n\t\t\tif buildOptions.Stdin.Sourcefile != \"\" {\n\t\t\t\tlogger.PrintErrorToStderr(osArgs,\n\t\t\t\t\t\"\\\"sourcefile\\\" only applies when reading from stdin\")\n\t\t\t} else {\n\t\t\t\tlogger.PrintErrorToStderr(osArgs,\n\t\t\t\t\t\"\\\"loader\\\" without extension only applies when reading from stdin\")\n\t\t\t}\n\t\t\treturn 1\n\t\t}\n\n\t\t// Validate the metafile absolute path and directory ahead of time so we\n\t\t// don't write any output files if it's incorrect. That makes this API\n\t\t// option consistent with how we handle all other API options.\n\t\tvar writeMetafile func(string)\n\t\tif extras.metafile != nil {\n\t\t\tvar metafileAbsPath string\n\t\t\tvar metafileAbsDir string\n\n\t\t\tif buildOptions.Outfile == \"\" && buildOptions.Outdir == \"\" {\n\t\t\t\t// Cannot use \"metafile\" when writing to stdout\n\t\t\t\tlogger.PrintErrorToStderr(osArgs, \"Cannot use \\\"metafile\\\" without an output path\")\n\t\t\t\treturn 1\n\t\t\t}\n\t\t\trealFS, realFSErr := fs.RealFS(fs.RealFSOptions{AbsWorkingDir: buildOptions.AbsWorkingDir})\n\t\t\tif realFSErr == nil {\n\t\t\t\tabsPath, ok := realFS.Abs(*extras.metafile)\n\t\t\t\tif !ok {\n\t\t\t\t\tlogger.PrintErrorToStderr(osArgs, fmt.Sprintf(\"Invalid metafile path: %s\", *extras.metafile))\n\t\t\t\t\treturn 1\n\t\t\t\t}\n\t\t\t\tmetafileAbsPath = absPath\n\t\t\t\tmetafileAbsDir = realFS.Dir(absPath)\n\t\t\t} else {\n\t\t\t\t// Don't fail in this case since the error will be reported by \"api.Build\"\n\t\t\t}\n\n\t\t\twriteMetafile = func(json string) {\n\t\t\t\tif json == \"\" || realFSErr != nil {\n\t\t\t\t\treturn // Don't write out the metafile on build errors\n\t\t\t\t}\n\t\t\t\tif err != nil {\n\t\t\t\t\t// This should already have been checked above\n\t\t\t\t\tpanic(err.Text)\n\t\t\t\t}\n\t\t\t\tfs.BeforeFileOpen()\n\t\t\t\tdefer fs.AfterFileClose()\n\t\t\t\tif err := fs.MkdirAll(realFS, metafileAbsDir, 0755); err != nil {\n\t\t\t\t\tlogger.PrintErrorToStderr(osArgs, fmt.Sprintf(\n\t\t\t\t\t\t\"Failed to create output directory: %s\", err.Error()))\n\t\t\t\t} else {\n\t\t\t\t\tif err := ioutil.WriteFile(metafileAbsPath, []byte(json), 0666); err != nil {\n\t\t\t\t\t\tlogger.PrintErrorToStderr(osArgs, fmt.Sprintf(\n\t\t\t\t\t\t\t\"Failed to write to output file: %s\", err.Error()))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Also validate the mangle cache absolute path and directory ahead of time\n\t\t// for the same reason\n\t\tvar writeMangleCache func(map[string]interface{})\n\t\tif extras.mangleCache != nil {\n\t\t\tvar mangleCacheAbsPath string\n\t\t\tvar mangleCacheAbsDir string\n\t\t\tvar mangleCacheOrder []string\n\t\t\trealFS, realFSErr := fs.RealFS(fs.RealFSOptions{AbsWorkingDir: buildOptions.AbsWorkingDir})\n\t\t\tif realFSErr == nil {\n\t\t\t\tabsPath, ok := realFS.Abs(*extras.mangleCache)\n\t\t\t\tif !ok {\n\t\t\t\t\tlogger.PrintErrorToStderr(osArgs, fmt.Sprintf(\"Invalid mangle cache path: %s\", *extras.mangleCache))\n\t\t\t\t\treturn 1\n\t\t\t\t}\n\t\t\t\tmangleCacheAbsPath = absPath\n\t\t\t\tmangleCacheAbsDir = realFS.Dir(absPath)\n\t\t\t\tbuildOptions.MangleCache, mangleCacheOrder = parseMangleCache(osArgs, realFS, *extras.mangleCache)\n\t\t\t\tif buildOptions.MangleCache == nil {\n\t\t\t\t\treturn 1 // Stop now if parsing failed\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Don't fail in this case since the error will be reported by \"api.Build\"\n\t\t\t}\n\n\t\t\twriteMangleCache = func(mangleCache map[string]interface{}) {\n\t\t\t\tif mangleCache == nil || realFSErr != nil {\n\t\t\t\t\treturn // Don't write out the metafile on build errors\n\t\t\t\t}\n\t\t\t\tif err != nil {\n\t\t\t\t\t// This should already have been checked above\n\t\t\t\t\tpanic(err.Text)\n\t\t\t\t}\n\t\t\t\tfs.BeforeFileOpen()\n\t\t\t\tdefer fs.AfterFileClose()\n\t\t\t\tif err := fs.MkdirAll(realFS, mangleCacheAbsDir, 0755); err != nil {\n\t\t\t\t\tlogger.PrintErrorToStderr(osArgs, fmt.Sprintf(\n\t\t\t\t\t\t\"Failed to create output directory: %s\", err.Error()))\n\t\t\t\t} else {\n\t\t\t\t\tbytes := printMangleCache(mangleCache, mangleCacheOrder, buildOptions.Charset == api.CharsetASCII)\n\t\t\t\t\tif err := ioutil.WriteFile(mangleCacheAbsPath, bytes, 0666); err != nil {\n\t\t\t\t\t\tlogger.PrintErrorToStderr(osArgs, fmt.Sprintf(\n\t\t\t\t\t\t\t\"Failed to write to output file: %s\", err.Error()))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Handle post-build actions with a plugin so they also work in watch mode\n\t\tbuildOptions.Plugins = append(buildOptions.Plugins, api.Plugin{\n\t\t\tName: \"PostBuildActions\",\n\t\t\tSetup: func(build api.PluginBuild) {\n\t\t\t\tbuild.OnEnd(func(result *api.BuildResult) (api.OnEndResult, error) {\n\t\t\t\t\t// Write the metafile to the file system\n\t\t\t\t\tif writeMetafile != nil {\n\t\t\t\t\t\twriteMetafile(result.Metafile)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Write the mangle cache to the file system\n\t\t\t\t\tif writeMangleCache != nil {\n\t\t\t\t\t\twriteMangleCache(result.MangleCache)\n\t\t\t\t\t}\n\n\t\t\t\t\treturn api.OnEndResult{}, nil\n\t\t\t\t})\n\t\t\t},\n\t\t})\n\n\t\t// Handle watch mode\n\t\tif extras.watch {\n\t\t\tctx, err := api.Context(*buildOptions)\n\n\t\t\t// Only start watching if the build options passed validation\n\t\t\tif err != nil {\n\t\t\t\treturn 1\n\t\t\t}\n\n\t\t\tctx.Watch(api.WatchOptions{\n\t\t\t\tDelay: extras.watchDelay,\n\t\t\t})\n\n\t\t\t// Do not exit if we're in watch mode\n\t\t\t<-make(chan struct{})\n\t\t}\n\n\t\t// This prints the summary which the context API doesn't do\n\t\tresult := api.Build(*buildOptions)\n\n\t\t// Return a non-zero exit code if there were errors\n\t\tif len(result.Errors) > 0 {\n\t\t\treturn 1\n\t\t}\n\n\tcase transformOptions != nil:\n\t\t// Read the input from stdin\n\t\tbytes, err := ioutil.ReadAll(os.Stdin)\n\t\tif err != nil {\n\t\t\tlogger.PrintErrorToStderr(osArgs, fmt.Sprintf(\n\t\t\t\t\"Could not read from stdin: %s\", err.Error()))\n\t\t\treturn 1\n\t\t}\n\n\t\t// Run the transform and stop if there were errors\n\t\tresult := api.Transform(string(bytes), *transformOptions)\n\t\tif len(result.Errors) > 0 {\n\t\t\treturn 1\n\t\t}\n\n\t\t// Write the output to stdout\n\t\tos.Stdout.Write(result.Code)\n\n\tcase err != nil:\n\t\tlogger.PrintErrorWithNoteToStderr(osArgs, err.Text, err.Note)\n\t\treturn 1\n\t}\n\n\treturn 0\n}\n\nfunc parseServeOptionsImpl(osArgs []string) (api.ServeOptions, []string, error) {\n\thost := \"\"\n\tportText := \"\"\n\tservedir := \"\"\n\tkeyfile := \"\"\n\tcertfile := \"\"\n\tfallback := \"\"\n\tvar corsOrigin []string\n\n\t// Filter out server-specific flags\n\tfilteredArgs := make([]string, 0, len(osArgs))\n\tfor _, arg := range osArgs {\n\t\tif arg == \"--serve\" {\n\t\t\t// Just ignore this flag\n\t\t} else if strings.HasPrefix(arg, \"--serve=\") {\n\t\t\tportText = arg[len(\"--serve=\"):]\n\t\t} else if strings.HasPrefix(arg, \"--servedir=\") {\n\t\t\tservedir = arg[len(\"--servedir=\"):]\n\t\t} else if strings.HasPrefix(arg, \"--keyfile=\") {\n\t\t\tkeyfile = arg[len(\"--keyfile=\"):]\n\t\t} else if strings.HasPrefix(arg, \"--certfile=\") {\n\t\t\tcertfile = arg[len(\"--certfile=\"):]\n\t\t} else if strings.HasPrefix(arg, \"--serve-fallback=\") {\n\t\t\tfallback = arg[len(\"--serve-fallback=\"):]\n\t\t} else if strings.HasPrefix(arg, \"--cors-origin=\") {\n\t\t\tcorsOrigin = strings.Split(arg[len(\"--cors-origin=\"):], \",\")\n\t\t} else {\n\t\t\tfilteredArgs = append(filteredArgs, arg)\n\t\t}\n\t}\n\n\t// Specifying the host is optional\n\tvar err error\n\tif strings.ContainsRune(portText, ':') {\n\t\thost, portText, err = net.SplitHostPort(portText)\n\t\tif err != nil {\n\t\t\treturn api.ServeOptions{}, nil, err\n\t\t}\n\t}\n\n\t// Parse the port\n\tvar port int64\n\tif portText != \"\" {\n\t\tport, err = strconv.ParseInt(portText, 10, 32)\n\t\tif err != nil {\n\t\t\treturn api.ServeOptions{}, nil, err\n\t\t}\n\t\tif port < 0 || port > 0xFFFF {\n\t\t\treturn api.ServeOptions{}, nil, fmt.Errorf(\"Invalid port number: %s\", portText)\n\t\t}\n\t\tif port == 0 {\n\t\t\t// 0 is the default value in Go, which we interpret as \"try to\n\t\t\t// pick port 8000\". So Go uses -1 as the sentinel value instead.\n\t\t\tport = -1\n\t\t}\n\t}\n\n\treturn api.ServeOptions{\n\t\tPort:     int(port),\n\t\tHost:     host,\n\t\tServedir: servedir,\n\t\tKeyfile:  keyfile,\n\t\tCertfile: certfile,\n\t\tFallback: fallback,\n\t\tCORS: api.CORSOptions{\n\t\t\tOrigin: corsOrigin,\n\t\t},\n\t}, filteredArgs, nil\n}\n\nfunc serveImpl(osArgs []string) {\n\tserveOptions, filteredArgs, err := parseServeOptionsImpl(osArgs)\n\tif err != nil {\n\t\tlogger.PrintErrorWithNoteToStderr(osArgs, err.Error(), \"\")\n\t\treturn\n\t}\n\n\toptions := newBuildOptions()\n\n\t// Apply defaults appropriate for the CLI\n\toptions.LogLimit = 5\n\toptions.LogLevel = api.LogLevelInfo\n\n\tfilteredArgs, analyze := filterAnalyzeFlags(filteredArgs)\n\textras, errWithNote := parseOptionsImpl(filteredArgs, &options, nil, kindInternal)\n\tif errWithNote != nil {\n\t\tlogger.PrintErrorWithNoteToStderr(osArgs, errWithNote.Text, errWithNote.Note)\n\t\treturn\n\t}\n\tif analyze != analyzeDisabled {\n\t\taddAnalyzePlugin(&options, analyze, osArgs)\n\t}\n\n\tserveOptions.OnRequest = func(args api.ServeOnRequestArgs) {\n\t\tlogger.PrintText(os.Stderr, logger.LevelInfo, filteredArgs, func(colors logger.Colors) string {\n\t\t\tstatusColor := colors.Red\n\t\t\tif args.Status >= 200 && args.Status <= 299 {\n\t\t\t\tstatusColor = colors.Green\n\t\t\t} else if args.Status >= 300 && args.Status <= 399 {\n\t\t\t\tstatusColor = colors.Yellow\n\t\t\t}\n\t\t\treturn fmt.Sprintf(\"%s%s - %q %s%d%s [%dms]%s\\n\",\n\t\t\t\tcolors.Dim, args.RemoteAddress, args.Method+\" \"+args.Path,\n\t\t\t\tstatusColor, args.Status, colors.Dim, args.TimeInMS, colors.Reset)\n\t\t})\n\t}\n\n\t// Validate build options\n\tctx, ctxErr := api.Context(options)\n\tif ctxErr != nil {\n\t\treturn\n\t}\n\n\t// Try to enable serve mode\n\tif _, err = ctx.Serve(serveOptions); err != nil {\n\t\tlogger.PrintErrorWithNoteToStderr(osArgs, err.Error(), \"\")\n\t\treturn\n\t}\n\n\t// Also enable watch mode if it was requested\n\tif extras.watch {\n\t\tif err := ctx.Watch(api.WatchOptions{}); err != nil {\n\t\t\tlogger.PrintErrorWithNoteToStderr(osArgs, err.Error(), \"\")\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Do not exit if we're in serve mode\n\t<-make(chan struct{})\n}\n\nfunc parseLogLevel(value string, arg string) (api.LogLevel, *cli_helpers.ErrorWithNote) {\n\tswitch value {\n\tcase \"verbose\":\n\t\treturn api.LogLevelVerbose, nil\n\tcase \"debug\":\n\t\treturn api.LogLevelDebug, nil\n\tcase \"info\":\n\t\treturn api.LogLevelInfo, nil\n\tcase \"warning\":\n\t\treturn api.LogLevelWarning, nil\n\tcase \"error\":\n\t\treturn api.LogLevelError, nil\n\tcase \"silent\":\n\t\treturn api.LogLevelSilent, nil\n\tdefault:\n\t\treturn api.LogLevelSilent, cli_helpers.MakeErrorWithNote(\n\t\t\tfmt.Sprintf(\"Invalid value %q in %q\", value, arg),\n\t\t\t\"Valid values are \\\"verbose\\\", \\\"debug\\\", \\\"info\\\", \\\"warning\\\", \\\"error\\\", or \\\"silent\\\".\",\n\t\t)\n\t}\n}\n"
  },
  {
    "path": "pkg/cli/cli_js_table.go",
    "content": "// This file was automatically generated by \"js_table.ts\"\n\npackage cli\n\nimport \"github.com/evanw/esbuild/pkg/api\"\n\nvar validEngines = map[string]api.EngineName{\n\t\"chrome\":  api.EngineChrome,\n\t\"deno\":    api.EngineDeno,\n\t\"edge\":    api.EngineEdge,\n\t\"firefox\": api.EngineFirefox,\n\t\"hermes\":  api.EngineHermes,\n\t\"ie\":      api.EngineIE,\n\t\"ios\":     api.EngineIOS,\n\t\"node\":    api.EngineNode,\n\t\"opera\":   api.EngineOpera,\n\t\"rhino\":   api.EngineRhino,\n\t\"safari\":  api.EngineSafari,\n}\n"
  },
  {
    "path": "pkg/cli/mangle_cache.go",
    "content": "package cli\n\n// The mangle cache is a JSON file that remembers esbuild's property renaming\n// decisions. It's a flat map where the keys are strings and the values are\n// either strings or the boolean value \"false\". This is the case both in JSON\n// and in Go (so the \"interface{}\" values are also either strings or \"false\").\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"github.com/evanw/esbuild/internal/fs\"\n\t\"github.com/evanw/esbuild/internal/helpers\"\n\t\"github.com/evanw/esbuild/internal/js_ast\"\n\t\"github.com/evanw/esbuild/internal/js_lexer\"\n\t\"github.com/evanw/esbuild/internal/js_parser\"\n\t\"github.com/evanw/esbuild/internal/logger\"\n\t\"github.com/evanw/esbuild/internal/resolver\"\n)\n\nfunc parseMangleCache(osArgs []string, fs fs.FS, absPath string) (map[string]interface{}, []string) {\n\t// Log problems with the mangle cache to stderr\n\tlog := logger.NewStderrLog(logger.OutputOptionsForArgs(osArgs))\n\tdefer log.Done()\n\n\t// Try to read the existing file\n\tprettyPath := absPath\n\tif rel, ok := fs.Rel(fs.Cwd(), absPath); ok {\n\t\tprettyPath = rel\n\t}\n\tprettyPath = strings.ReplaceAll(prettyPath, \"\\\\\", \"/\")\n\tbytes, err, originalError := fs.ReadFile(absPath)\n\tif err != nil {\n\t\t// It's ok if it's just missing\n\t\tif err == syscall.ENOENT {\n\t\t\treturn make(map[string]interface{}), []string{}\n\t\t}\n\n\t\t// Otherwise, report the error\n\t\tlog.AddError(nil, logger.Range{},\n\t\t\tfmt.Sprintf(\"Failed to read from mangle cache file %q: %s\", prettyPath, originalError.Error()))\n\t\treturn nil, nil\n\t}\n\n\t// Use our JSON parser so we get pretty-printed error messages\n\tkeyPath := logger.Path{Text: absPath, Namespace: \"file\"}\n\tsource := logger.Source{\n\t\tKeyPath:     keyPath,\n\t\tPrettyPaths: resolver.MakePrettyPaths(fs, keyPath),\n\t\tContents:    string(bytes),\n\t}\n\tresult, ok := js_parser.ParseJSON(log, source, js_parser.JSONOptions{})\n\tif !ok || log.HasErrors() {\n\t\t// Stop if there were any errors so we don't continue and then overwrite this file\n\t\treturn nil, nil\n\t}\n\ttracker := logger.MakeLineColumnTracker(&source)\n\n\t// Validate the top-level object\n\troot, ok := result.Data.(*js_ast.EObject)\n\tif !ok {\n\t\tlog.AddError(&tracker, logger.Range{Loc: result.Loc},\n\t\t\t\"Expected a top-level object in mangle cache file\")\n\t\treturn nil, nil\n\t}\n\n\tmangleCache := make(map[string]interface{}, len(root.Properties))\n\torder := make([]string, 0, len(root.Properties))\n\n\tfor _, property := range root.Properties {\n\t\tkey := helpers.UTF16ToString(property.Key.Data.(*js_ast.EString).Value)\n\t\torder = append(order, key)\n\n\t\tswitch v := property.ValueOrNil.Data.(type) {\n\t\tcase *js_ast.EBoolean:\n\t\t\tif v.Value {\n\t\t\t\tlog.AddError(&tracker, js_lexer.RangeOfIdentifier(source, property.ValueOrNil.Loc),\n\t\t\t\t\tfmt.Sprintf(\"Expected %q in mangle cache file to map to either a string or false\", key))\n\t\t\t} else {\n\t\t\t\tmangleCache[key] = false\n\t\t\t}\n\n\t\tcase *js_ast.EString:\n\t\t\tmangleCache[key] = helpers.UTF16ToString(v.Value)\n\n\t\tdefault:\n\t\t\tlog.AddError(&tracker, logger.Range{Loc: property.ValueOrNil.Loc},\n\t\t\t\tfmt.Sprintf(\"Expected %q in mangle cache file to map to either a string or false\", key))\n\t\t}\n\t}\n\n\tif log.HasErrors() {\n\t\treturn nil, nil\n\t}\n\treturn mangleCache, order\n}\n\nfunc printMangleCache(mangleCache map[string]interface{}, originalOrder []string, asciiOnly bool) []byte {\n\tj := helpers.Joiner{}\n\tj.AddString(\"{\")\n\n\t// Determine the order to print the keys in\n\torder := originalOrder\n\tif len(mangleCache) > len(order) {\n\t\torder = make([]string, 0, len(mangleCache))\n\t\tif sort.StringsAreSorted(originalOrder) {\n\t\t\t// If they came sorted, keep them sorted\n\t\t\tfor key := range mangleCache {\n\t\t\t\torder = append(order, key)\n\t\t\t}\n\t\t\tsort.Strings(order)\n\t\t} else {\n\t\t\t// Otherwise add all new keys to the end, and only sort the new keys\n\t\t\toriginalKeys := make(map[string]bool, len(originalOrder))\n\t\t\tfor _, key := range originalOrder {\n\t\t\t\toriginalKeys[key] = true\n\t\t\t}\n\t\t\torder = append(order, originalOrder...)\n\t\t\tfor key := range mangleCache {\n\t\t\t\tif !originalKeys[key] {\n\t\t\t\t\torder = append(order, key)\n\t\t\t\t}\n\t\t\t}\n\t\t\tsort.Strings(order[len(originalOrder):])\n\t\t}\n\t}\n\n\t// Print the JSON while preserving the existing order of the keys\n\tfor i, key := range order {\n\t\t// Print the key\n\t\tif i > 0 {\n\t\t\tj.AddString(\",\\n  \")\n\t\t} else {\n\t\t\tj.AddString(\"\\n  \")\n\t\t}\n\t\tj.AddBytes(helpers.QuoteForJSON(key, asciiOnly))\n\n\t\t// Print the value\n\t\tif value := mangleCache[key]; value != false {\n\t\t\tj.AddString(\": \")\n\t\t\tj.AddBytes(helpers.QuoteForJSON(value.(string), asciiOnly))\n\t\t} else {\n\t\t\tj.AddString(\": false\")\n\t\t}\n\t}\n\n\tif len(order) > 0 {\n\t\tj.AddString(\"\\n\")\n\t}\n\tj.AddString(\"}\\n\")\n\treturn j.Done()\n}\n"
  },
  {
    "path": "require/old-ts/README.md",
    "content": "# Old TypeScript version\n\nThis is used to ensure that our type definitions don't accidentally use newer features that break in older versions of TypeScript.\n"
  },
  {
    "path": "require/old-ts/package.json",
    "content": "{\n  \"dependencies\": {\n    \"typescript\": \"3.5.3\"\n  }\n}\n"
  },
  {
    "path": "require/parcel2/.terserrc",
    "content": "{\n  \"format\": {\n    \"comments\": false\n  }\n}\n"
  },
  {
    "path": "require/parcel2/package.json",
    "content": "{\n  \"dependencies\": {\n    \"parcel\": \"2.10.0\",\n    \"typescript\": \"4.9.3\"\n  }\n}\n"
  },
  {
    "path": "require/rollup/package.json",
    "content": "{\n  \"dependencies\": {\n    \"@rollup/plugin-terser\": \"0.4.4\",\n    \"rollup\": \"4.0.2\"\n  }\n}\n"
  },
  {
    "path": "require/webpack5/package.json",
    "content": "{\n  \"dependencies\": {\n    \"ts-loader\": \"9.5.0\",\n    \"typescript\": \"4.9.3\",\n    \"webpack\": \"5.88.2\",\n    \"webpack-cli\": \"5.1.4\"\n  }\n}\n"
  },
  {
    "path": "require/yarnpnp/.gitignore",
    "content": "/.pnp*\n/.yarn*\n/out*.js\n"
  },
  {
    "path": "require/yarnpnp/bar/index.js",
    "content": "exports.bar = require('bar-pkg').bar\n"
  },
  {
    "path": "require/yarnpnp/foo/index.js",
    "content": "export default 'foo'\n"
  },
  {
    "path": "require/yarnpnp/foo/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"name\": \"foo\"\n}\n"
  },
  {
    "path": "require/yarnpnp/in.mjs",
    "content": "console.log('Running Yarn PnP tests...')\n\nimport * as rd from 'react-dom'\nif (rd.version !== '18.2.0') throw '❌ react-dom'\n\nimport * as s3 from 'strtok3'\nimport * as s3_core from 'strtok3/core'\nif (!s3.fromFile) throw '❌ strtok3'\nif (!s3_core.fromBuffer) throw '❌ strtok3/core'\n\nimport * as d3 from 'd3-time'\nif (!d3.utcDay) throw '❌ d3-time'\n\nimport * as mm from 'mime'\nif (mm.default.getType('txt') !== 'text/plain') throw '❌ mime'\n\nimport * as ajv from 'aws-jwt-verify'\nif (!ajv.CognitoJwtVerifier) throw '❌ aws-jwt-verify'\n\nimport * as foo from 'foo'\nif (foo.default !== 'foo') throw '❌ foo'\n\nimport * as bar from './bar/index.js'\nif (bar.bar !== 'bar') throw '❌ bar'\n\nconsole.log('✅ Yarn PnP tests passed')\n"
  },
  {
    "path": "require/yarnpnp/package.json",
    "content": "{\n  \"workspaces\": [\n    \"./foo\"\n  ],\n  \"packageManager\": \"yarn@4.0.0-rc.22\",\n  \"dependencies\": {\n    \"@vue/tsconfig\": \"0.1.3\",\n    \"aws-jwt-verify\": \"3.1.0\",\n    \"d3-time\": \"3.0.0\",\n    \"foo\": \"workspace:*\",\n    \"mime\": \"3.0.0\",\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"strtok3\": \"7.0.0\"\n  }\n}\n"
  },
  {
    "path": "require/yarnpnp/tsconfig.json",
    "content": "{\n  \"extends\": \"@vue/tsconfig/tsconfig.json\"\n}\n"
  },
  {
    "path": "scripts/browser/browser-tests.js",
    "content": "const http = require('http')\nconst path = require('path')\nconst url = require('url')\nconst fs = require('fs')\n\nconst js = fs.readFileSync(path.join(__dirname, '..', '..', 'npm', 'esbuild-wasm', 'lib', 'browser.js'))\nconst jsMin = fs.readFileSync(path.join(__dirname, '..', '..', 'npm', 'esbuild-wasm', 'lib', 'browser.min.js'))\nconst esm = fs.readFileSync(path.join(__dirname, '..', '..', 'npm', 'esbuild-wasm', 'esm', 'browser.js'))\nconst esmMin = fs.readFileSync(path.join(__dirname, '..', '..', 'npm', 'esbuild-wasm', 'esm', 'browser.min.js'))\nconst wasm = fs.readFileSync(path.join(__dirname, '..', '..', 'npm', 'esbuild-wasm', 'esbuild.wasm'))\nconst html = fs.readFileSync(path.join(__dirname, '..', '..', 'scripts', 'browser', 'index.html'))\n\nconst server = http.createServer((req, res) => {\n  console.log(`[http] ${req.method} ${req.url}`)\n\n  try {\n    if (req.method === 'GET' && req.url) {\n      const parsed = url.parse(req.url)\n\n      if (parsed.pathname === '/npm/esbuild-wasm/lib/browser.js') {\n        res.writeHead(200, { 'Content-Type': 'text/javascript' })\n        res.end(js)\n        return\n      }\n\n      if (parsed.pathname === '/npm/esbuild-wasm/lib/browser.min.js') {\n        res.writeHead(200, { 'Content-Type': 'text/javascript' })\n        res.end(jsMin)\n        return\n      }\n\n      if (parsed.pathname === '/npm/esbuild-wasm/esm/browser.js') {\n        res.writeHead(200, { 'Content-Type': 'text/javascript' })\n        res.end(esm)\n        return\n      }\n\n      if (parsed.pathname === '/npm/esbuild-wasm/esm/browser.min.js') {\n        res.writeHead(200, { 'Content-Type': 'text/javascript' })\n        res.end(esmMin)\n        return\n      }\n\n      if (parsed.pathname === '/npm/esbuild-wasm/esbuild.wasm') {\n        res.writeHead(200, { 'Content-Type': 'application/wasm' })\n        res.end(wasm)\n        return\n      }\n\n      if (parsed.pathname === '/scripts/browser/index.html') {\n        res.writeHead(200, { 'Content-Type': 'text/html' })\n        res.end(html)\n        return\n      }\n\n      if (parsed.pathname === '/scripts/browser/esbuild.wasm.bagel') {\n        res.writeHead(200, { 'Content-Type': 'application/octet-stream' })\n        res.end(wasm)\n        return\n      }\n    }\n\n    res.writeHead(404)\n    res.end('404 Not Found')\n  }\n\n  catch (err) {\n    res.writeHead(500)\n    res.end('500 Internal Server Error')\n    console.error(err)\n  }\n})\n\nserver.listen()\nconst { address, port } = server.address()\nconst serverURL = url.format({ protocol: 'http', hostname: address, port })\nconsole.log(`[http] listening on ${serverURL}`)\n\nasync function main() {\n  let allTestsPassed = true\n  try {\n    const browser = await require('puppeteer').launch({\n      // This is here because since December 2024, GitHub changed something about\n      // their CI that causes this error:\n      //\n      // [FATAL:zygote_host_impl_linux.cc(128)] No usable sandbox! If you are running\n      // on Ubuntu 23.10+ or another Linux distro that has disabled unprivileged user\n      // namespaces with AppArmor, see https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md.\n      // Otherwise see https://chromium.googlesource.com/chromium/src/+/main/docs/linux/suid_sandbox_development.md\n      // for more information on developing with the (older) SUID sandbox. If you want\n      // to live dangerously and need an immediate workaround, you can try using\n      // --no-sandbox.\n      args: ['--no-sandbox'],\n    })\n\n    const page = await browser.newPage()\n    page.on('console', obj => {\n      console.log(`[console.${obj.type()}] ${obj.text()}`)\n    })\n\n    page.exposeFunction('testBegin', args => {\n      const config = Object.entries(JSON.parse(args)).map(([k, v]) => `${k}=${v}`).join(', ')\n      console.log(`💬 config: ${config}`)\n    })\n\n    page.exposeFunction('testEnd', args => {\n      if (args === null) console.log(`👍 success`)\n      else {\n        const { test, error } = JSON.parse(args)\n        console.log(`❌ error${test ? ` [${test}]` : ``}: ${error}`)\n        allTestsPassed = false\n      }\n    })\n\n    const testDone = new Promise(resolve => {\n      page.exposeFunction('testDone', resolve)\n    })\n\n    await page.goto(`${serverURL}/scripts/browser/index.html`, { waitUntil: 'domcontentloaded' })\n    await testDone\n    await page.close()\n    await browser.close()\n  }\n\n  catch (e) {\n    allTestsPassed = false\n    console.log(`❌ error: ${e && e.stack || e && e.message || e}`)\n  }\n\n  server.close()\n\n  if (!allTestsPassed) {\n    console.error(`❌ browser test failed`)\n    process.exit(1)\n  } else {\n    console.log(`✅ browser test passed`)\n  }\n}\n\nmain().catch(error => setTimeout(() => { throw error }))\n"
  },
  {
    "path": "scripts/browser/index.html",
    "content": "<!DOCTYPE html>\n\n<head>\n  <meta charset=\"utf8\">\n  <style></style>\n</head>\n\n<body>\n</body>\n\n<script>\n  async function expectThrownError(fn, err) {\n    try {\n      await fn()\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assertStrictEqual(e.message, err)\n    }\n  }\n\n  function assertStrictEqual(a, b, message = 'Assertion failed') {\n    if (a !== b) {\n      throw new Error(`${message}:\n  Observed: ${JSON.stringify(a)}\n  Expected: ${JSON.stringify(b)}`);\n    }\n  }\n\n  async function assertSameColorsWithNestingTransform(esbuild, { css, html }) {\n    const crawlColors = node => {\n      const { color } = getComputedStyle(node)\n      const children = Array.from(node.children).map(crawlColors)\n      return children.length ? [color, children] : color\n    }\n    const style = document.querySelector('style')\n    document.body.innerHTML = html\n    style.textContent = css\n    const original = JSON.stringify(crawlColors(document.body))\n\n    // Test minified CSS\n    const minified = await esbuild.transform(css, {\n      loader: 'css',\n      minify: true,\n    })\n    style.textContent = minified.code\n    assertStrictEqual(original, JSON.stringify(crawlColors(document.body)), 'Compare minified CSS')\n\n    // Test lowered CSS\n    const lowered = await esbuild.transform(css, {\n      loader: 'css',\n      supported: { nesting: false },\n    })\n    style.textContent = lowered.code\n    assertStrictEqual(original, JSON.stringify(crawlColors(document.body)), 'Compare lowered CSS')\n  }\n\n  const coreTests = ({ esbuild }) => ({\n    async defaultExport() {\n      assertStrictEqual(typeof esbuild.version, 'string')\n      assertStrictEqual(esbuild.version, esbuild.default.version)\n      assertStrictEqual(esbuild.version, esbuild.default.default.version)\n      assertStrictEqual(esbuild.version, esbuild.default.default.default.version)\n    },\n\n    async transformJS() {\n      const { code } = await esbuild.transform('1+2')\n      assertStrictEqual(code, '1 + 2;\\n')\n    },\n\n    async transformTS() {\n      const { code } = await esbuild.transform('1 as any + <any>2', { loader: 'ts' })\n      assertStrictEqual(code, '1 + 2;\\n')\n    },\n\n    async transformCSS() {\n      const { code } = await esbuild.transform('div { color: red }', { loader: 'css' })\n      assertStrictEqual(code, 'div {\\n  color: red;\\n}\\n')\n    },\n\n    async buildFib() {\n      const fibonacciPlugin = {\n        name: 'fib',\n        setup(build) {\n          build.onResolve({ filter: /^fib\\((\\d+)\\)/ }, args => {\n            return { path: args.path, namespace: 'fib' }\n          })\n          build.onLoad({ filter: /^fib\\((\\d+)\\)/, namespace: 'fib' }, args => {\n            let match = /^fib\\((\\d+)\\)/.exec(args.path), n = +match[1]\n            let contents = n < 2 ? `export default ${n}` : `\n              import n1 from 'fib(${n - 1}) ${args.path}'\n              import n2 from 'fib(${n - 2}) ${args.path}'\n              export default n1 + n2`\n            return { contents }\n          })\n        },\n      }\n      const result = await esbuild.build({\n        stdin: {\n          contents: `\n            import x from 'fib(10)'\n            module.exports = x\n          `,\n        },\n        format: 'cjs',\n        bundle: true,\n        plugins: [fibonacciPlugin],\n      })\n      assertStrictEqual(result.outputFiles.length, 1)\n      assertStrictEqual(result.outputFiles[0].path, '<stdout>')\n      const code = result.outputFiles[0].text\n      const answer = {}\n      new Function('module', code)(answer)\n      assertStrictEqual(answer.exports, 55)\n    },\n\n    async buildRelativeIssue693() {\n      const result = await esbuild.build({\n        stdin: {\n          contents: `const x=1`,\n        },\n        write: false,\n        outfile: 'esbuild.js',\n      });\n      assertStrictEqual(result.outputFiles.length, 1)\n      assertStrictEqual(result.outputFiles[0].path, '/esbuild.js')\n      assertStrictEqual(result.outputFiles[0].text, 'const x = 1;\\n')\n    },\n\n    async watch() {\n      const context = await esbuild.context({})\n      try {\n        await expectThrownError(context.watch, 'Cannot use the \"watch\" API in this environment')\n      } finally {\n        context.dispose()\n      }\n    },\n\n    async serve() {\n      const context = await esbuild.context({})\n      try {\n        await expectThrownError(context.serve, 'Cannot use the \"serve\" API in this environment')\n      } finally {\n        context.dispose()\n      }\n    },\n\n    async esbuildBuildSync() {\n      await expectThrownError(esbuild.buildSync, 'The \"buildSync\" API only works in node')\n    },\n\n    async esbuildTransformSync() {\n      await expectThrownError(esbuild.transformSync, 'The \"transformSync\" API only works in node')\n    },\n  })\n\n  function setupForProblemCSS(prefix) {\n    // https://github.com/tailwindlabs/tailwindcss/issues/2889\n    const original = `\n      /* Variant 1 */\n      .${prefix}-v1 { --a: ; --b: ; max-width: var(--a) var(--b); }\n      .${prefix}-a { --a: 1px; }\n      .${prefix}-b { --b: 2px; }\n\n      /* Variant 2 */\n      .${prefix}-v2 { max-width: var(--a, ) var(--b, ); }\n      .${prefix}-a { --a: 1px; }\n      .${prefix}-b { --b: 2px; }\n    `\n    const style = document.querySelector('style')\n    const test1a = document.createElement('div')\n    const test1b = document.createElement('div')\n    const test2a = document.createElement('div')\n    const test2b = document.createElement('div')\n    test1a.className = `${prefix}-v1 ${prefix}-a`\n    test1b.className = `${prefix}-v1 ${prefix}-b`\n    test2a.className = `${prefix}-v2 ${prefix}-a`\n    test2b.className = `${prefix}-v2 ${prefix}-b`\n    return [original, css => {\n      style.textContent = css\n      document.body.innerHTML = ''\n      document.body.appendChild(test1a)\n      document.body.appendChild(test1b)\n      document.body.appendChild(test2a)\n      document.body.appendChild(test2b)\n      assertStrictEqual(getComputedStyle(test1a).maxWidth, `1px`)\n      assertStrictEqual(getComputedStyle(test1b).maxWidth, `2px`)\n      assertStrictEqual(getComputedStyle(test2a).maxWidth, `1px`)\n      assertStrictEqual(getComputedStyle(test2b).maxWidth, `2px`)\n    }]\n  }\n\n  const cssTests = ({ esbuild }) => ({\n    async problemCSSOriginal() {\n      const [original, runAsserts] = setupForProblemCSS('original')\n      runAsserts(original)\n    },\n\n    async problemCSSPrettyPrinted() {\n      const [original, runAsserts] = setupForProblemCSS('pretty-print')\n      const { code: prettyPrinted } = await esbuild.transform(original, { loader: 'css' })\n      runAsserts(prettyPrinted)\n    },\n\n    async problemCSSMinified() {\n      const [original, runAsserts] = setupForProblemCSS('pretty-print')\n      const { code: minified } = await esbuild.transform(original, { loader: 'css', minify: true })\n      runAsserts(minified)\n    },\n\n    // See: https://github.com/evanw/esbuild/issues/3877\n    async cssNestingIssue3877() {\n      await assertSameColorsWithNestingTransform(esbuild, {\n        css: `\n          .a .b:has(> span) {\n            .a & span {\n              color: green;\n            }\n          }\n        `,\n        html: `\n          <div class=\"a\">\n            <div class=\"b\">\n              <span>1</span>\n              <div><span>2</span></div>\n            </div>\n            <div class=\"b\">\n              <div><span>3</span></div>\n            </div>\n          </div>\n        `,\n      })\n    },\n\n    // See: https://github.com/evanw/esbuild/issues/3877#issuecomment-2631385559\n    async cssNestingIssue3877Comment2631385559() {\n      await assertSameColorsWithNestingTransform(esbuild, {\n        css: `\n          .a {\n            :has(>&) {\n              color: red;\n            }\n          }\n        `,\n        html: `\n          <div class=\"a\">a</div>\n        `,\n      })\n    },\n\n    // See: https://github.com/evanw/esbuild/issues/3997\n    async cssNestingIssue3997() {\n      await assertSameColorsWithNestingTransform(esbuild, {\n        css: `\n          .foo {\n            color: blue;\n            && { color: red; }\n            & { color: green; }\n          }\n        `,\n        html: `\n          <div class=\"foo\">x</div>\n        `,\n      })\n    },\n\n    // See: https://github.com/evanw/esbuild/issues/4005\n    async cssNestingIssue4005() {\n      await assertSameColorsWithNestingTransform(esbuild, {\n        css: `\n          .foo {\n            :where(& > .bar) {\n              color: red;\n            }\n          }\n        `,\n        html: `\n          <div class=\"foo\">\n            <div class=\"bar\">bar</div>\n          </div>\n        `,\n      })\n    },\n\n    // See: https://github.com/evanw/esbuild/pull/4037\n    async cssNestingIssue4037() {\n      await assertSameColorsWithNestingTransform(esbuild, {\n        css: `\n          .parent {\n            > .a,\n            > .b1 > .b2 {\n              color: red;\n            }\n          }\n        `,\n        html: `\n          <div class=\"parent\">\n            <div class=\"a\">a</div>\n            <div class=\"b1\">\n              <div class=\"b2\">b2</div>\n            </div>\n          </div>\n        `,\n      })\n    },\n  })\n\n  async function runTest(test, fn) {\n    try {\n      await fn()\n    } catch (e) {\n      e.test = test\n      throw e\n    }\n  }\n\n  async function loadScript(url) {\n    const tag = document.createElement('script')\n    document.head.appendChild(tag)\n    await new Promise((resolve, reject) => {\n      tag.onload = resolve\n      tag.onerror = () => reject(new Error('Failed to load script: ' + url))\n      tag.src = url\n    })\n    const esbuild = window.esbuild\n    delete window.esbuild\n    return esbuild\n  }\n\n  async function testStart() {\n    let allTestsPassed = true\n\n    if (!window.testBegin) window.testBegin = args => {\n      const config = Object.entries(JSON.parse(args)).map(([k, v]) => `${k}=${v}`).join(', ')\n      console.log(`💬 config: ${config}`)\n    }\n\n    if (!window.testEnd) window.testEnd = args => {\n      if (args === null) console.log(`👍 success`)\n      else {\n        const { test, stack, error } = JSON.parse(args)\n        console.log(`❌ error${test ? ` [${test}]` : ``}: ${error}`)\n        allTestsPassed = false\n      }\n    }\n\n    if (!window.testDone) window.testDone = error => {\n      console.log(allTestsPassed ? `✅ done` : `❌ done`)\n    }\n\n    // Just run CSS tests through a single configuration, but run each test separately\n    {\n      const url = '/npm/esbuild-wasm/esbuild.wasm?' + Math.random()\n      const initializePromise = import('/npm/esbuild-wasm/esm/browser.js?' + Math.random())\n        .then(esbuild => esbuild.initialize({ wasmURL: new URL(url, location.href) })\n          .then(() => esbuild))\n      const tests = cssTests({ esbuild: await initializePromise.catch(() => null) })\n      for (const test in tests) {\n        try {\n          testBegin(JSON.stringify({ type: 'css', test }))\n          await initializePromise\n          await runTest(test, tests[test])\n          testEnd(null)\n        } catch (e) {\n          testEnd(JSON.stringify({\n            test: e.test || null,\n            stack: e.stack || null,\n            error: (e && e.message || e) + '',\n          }))\n        }\n      }\n    }\n\n    // Run all core tests through every configuration, but run all tests together (stop after one failure)\n    for (const esm of [false, true]) {\n      for (const min of [false, true]) {\n        for (const worker of [false, true]) {\n          for (const mime of ['correct', 'incorrect']) {\n            for (const approach of ['string', 'url', 'module']) {\n              try {\n                testBegin(JSON.stringify({ esm, min, worker, mime, approach }))\n                const esbuild = esm\n                  ? await import('/npm/esbuild-wasm/esm/browser' + (min ? '.min' : '') + '.js?' + Math.random())\n                  : await loadScript('/npm/esbuild-wasm/lib/browser' + (min ? '.min' : '') + '.js?' + Math.random())\n                const url = mime === 'correct' ? '/npm/esbuild-wasm/esbuild.wasm' : '/scripts/browser/esbuild.wasm.bagel'\n                const initializePromise = {\n                  string: () => esbuild.initialize({ wasmURL: url, worker }),\n                  url: () => esbuild.initialize({ wasmURL: new URL(url, location.href), worker }),\n                  module: () => fetch(url)\n                    .then(r => r.arrayBuffer())\n                    .then(bytes => WebAssembly.compile(bytes))\n                    .then(module => esbuild.initialize({ wasmModule: module, worker })),\n                }[approach]()\n                await initializePromise\n                const tests = coreTests({ esbuild })\n                const promises = []\n                for (const test in tests) promises.push(runTest(test, tests[test]))\n                await Promise.all(promises)\n                testEnd(null)\n              } catch (e) {\n                testEnd(JSON.stringify({\n                  test: e.test || null,\n                  stack: e.stack || null,\n                  error: (e && e.message || e) + '',\n                }))\n              }\n            }\n          }\n        }\n      }\n    }\n\n    testDone()\n  }\n\n  testStart()\n\n</script>\n"
  },
  {
    "path": "scripts/browser/package.json",
    "content": "{\n  \"dependencies\": {\n    \"puppeteer\": \"23.11.1\"\n  }\n}\n"
  },
  {
    "path": "scripts/dataurl-escapes.html",
    "content": "<!DOCTYPE html>\n<p>\n  This script checks to see what characters need to be escaped in a data URL\n  (in addition to % for percent-encoded hexadecimal escapes) for a browser to\n  parse it correctly. This information is used to implement esbuild's\n  <code>dataurl</code> loader. Here is what your current browser requires:\n</p>\n<pre id=\"result\"></pre>\n<p>\n  The answer that works across Chrome, Firefox, and Safari appears to be:\n  <br>\n  <br>Always percent-encode these values: <code>0x09, 0x0A, 0x0D, 0x23</code>\n  <br>Only percent-encode these values in the trailing position: <code>0x00 to 0x08, 0x0B, 0x0C, 0x0E to 0x20</code>\n</p>\n<script>\n\n  function percentEncode(i) {\n    if (i >= 0x80) return encodeURIComponent(String.fromCharCode(i))\n    return '%' + (0x100 | i).toString(16).slice(-2)\n  }\n\n  async function urlDoesDecodeTo(url, to) {\n    return to === await fetch(url).then(r => r.text())\n  }\n\n  async function check() {\n    const shouldEncode = []\n\n    for (let i = 0; i <= 0xFF; i++) {\n      const ch = String.fromCharCode(i)\n      const chPercent = percentEncode(i)\n\n      if (!await urlDoesDecodeTo('data:text/plain,' + chPercent, ch)) {\n        throw new Error('Assertion failed: Cannot decode ' + chPercent)\n      }\n\n      const leading = await urlDoesDecodeTo('data:text/plain,' + ch + 'foo', ch + 'foo')\n      const trailing = await urlDoesDecodeTo('data:text/plain,foo' + ch, 'foo' + ch)\n      const embedded = await urlDoesDecodeTo('data:text/plain,foo' + ch + 'foo', 'foo' + ch + 'foo')\n\n      if (!leading && !trailing && !embedded) {\n        shouldEncode.push('U+' + i.toString(16) + ' (' + ch + ')')\n      } else {\n        if (!leading) shouldEncode.push('U+' + i.toString(16) + ' (' + ch + ') leading')\n        if (!trailing) shouldEncode.push('U+' + i.toString(16) + ' (' + ch + ') trailing')\n        if (!embedded) shouldEncode.push('U+' + i.toString(16) + ' (' + ch + ') embedded')\n      }\n    }\n\n    document.getElementById('result').textContent = 'shouldEncode = ' + JSON.stringify(shouldEncode, null, 2)\n  }\n\n  check()\n\n</script>\n"
  },
  {
    "path": "scripts/decorator-tests.js",
    "content": "var __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for(\"Symbol.\" + name);\nvar __typeError = (msg) => {\n  throw TypeError(msg);\n};\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\nvar __decoratorStart = (base) => [, , , __create(base?.[__knownSymbol(\"metadata\")] ?? null)];\nvar __decoratorStrings = [\"class\", \"method\", \"getter\", \"setter\", \"accessor\", \"field\", \"value\", \"get\", \"set\"];\nvar __expectFn = (fn) => fn !== void 0 && typeof fn !== \"function\" ? __typeError(\"Function expected\") : fn;\nvar __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError(\"Already initialized\") : fns.push(__expectFn(fn || null)) });\nvar __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol(\"metadata\"), array[3]);\nvar __runInitializers = (array, flags, self, value) => {\n  for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);\n  return value;\n};\nvar __decorateElement = (array, flags, name, decorators, target, extra) => {\n  var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);\n  var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings[k + 5];\n  var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);\n  var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc(k < 4 ? target : { get [name]() {\n    return __privateGet(this, extra);\n  }, set [name](x) {\n    return __privateSet(this, extra, x);\n  } }, name));\n  k ? p && k < 4 && __name(extra, (k > 2 ? \"set \" : k > 1 ? \"get \" : \"\") + name) : __name(target, name);\n  for (var i = decorators.length - 1; i >= 0; i--) {\n    ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);\n    if (k) {\n      ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn(target, x) : (x) => name in x };\n      if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet : __privateMethod)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name];\n      if (k > 2) access.set = p ? (x, y) => __privateSet(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y;\n    }\n    it = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key] : k > 4 ? void 0 : { get: desc.get, set: desc.set } : target, ctx), done._ = 1;\n    if (k ^ 4 || it === void 0) __expectFn(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it);\n    else if (typeof it !== \"object\" || it === null) __typeError(\"Object expected\");\n    else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn);\n  }\n  return k || __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;\n};\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nvar __accessCheck = (obj, member, msg) => member.has(obj) || __typeError(\"Cannot \" + msg);\nvar __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use the \"in\" operator on this value') : member.has(obj);\nvar __privateGet = (obj, member, getter) => (__accessCheck(obj, member, \"read from private field\"), getter ? getter.call(obj) : member.get(obj));\nvar __privateAdd = (obj, member, value) => member.has(obj) ? __typeError(\"Cannot add the same private member more than once\") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);\nvar __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, \"write to private field\"), setter ? setter.call(obj, value) : member.set(obj, value), value);\nvar __privateMethod = (obj, member, method) => (__accessCheck(obj, member, \"access private method\"), method);\nif (!(\"metadata\" in Symbol)) {\n  Symbol.metadata = /* @__PURE__ */ Symbol(\"Symbol.metadata\");\n}\nif (!(Symbol.metadata in Function)) {\n  Object.defineProperty(Function.prototype, Symbol.metadata, { value: null });\n}\nconst tests = {\n  // Class decorators\n  \"Class decorators: Basic statement\": () => {\n    var _Foo_decorators, _init;\n    let old;\n    const dec = (name) => (cls, ctx) => {\n      assertEq(() => typeof cls, \"function\");\n      assertEq(() => cls.name, name);\n      assertEq(() => ctx.kind, \"class\");\n      assertEq(() => ctx.name, name);\n      assertEq(() => \"static\" in ctx, false);\n      assertEq(() => \"private\" in ctx, false);\n      assertEq(() => \"access\" in ctx, false);\n      old = cls;\n    };\n    _Foo_decorators = [dec(\"Foo\")];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    Foo2 = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, Foo2);\n    __runInitializers(_init, 1, Foo2);\n    assertEq(() => Foo2, old);\n  },\n  \"Class decorators: Basic expression: Anonymous\": () => {\n    var _class_decorators, _init, _a, _Baz_decorators, _init2, _b;\n    let old;\n    const dec = (name) => (cls, ctx) => {\n      assertEq(() => typeof cls, \"function\");\n      assertEq(() => cls.name, name);\n      assertEq(() => ctx.kind, \"class\");\n      assertEq(() => ctx.name, name);\n      assertEq(() => \"static\" in ctx, false);\n      assertEq(() => \"private\" in ctx, false);\n      assertEq(() => \"access\" in ctx, false);\n      old = cls;\n    };\n    const Foo2 = /* @__PURE__ */ ((x) => x)((_class_decorators = [dec(\"\")], _a = class {\n    }, _init = __decoratorStart(null), _a = __decorateElement(_init, 0, \"\", _class_decorators, _a), __runInitializers(_init, 1, _a), _a));\n    assertEq(() => Foo2, old);\n    const Bar = /* @__PURE__ */ ((x) => x)((_Baz_decorators = [dec(\"Baz\")], _b = class {\n    }, _init2 = __decoratorStart(null), _b = __decorateElement(_init2, 0, \"Baz\", _Baz_decorators, _b), __runInitializers(_init2, 1, _b), _b));\n    assertEq(() => Bar, old);\n  },\n  \"Class decorators: Basic expression: Property value\": () => {\n    var _Foo_decorators, _init, _a, _Baz_decorators, _init2, _b;\n    let old;\n    const dec = (name) => (cls, ctx) => {\n      assertEq(() => typeof cls, \"function\");\n      assertEq(() => cls.name, name);\n      assertEq(() => ctx.kind, \"class\");\n      assertEq(() => ctx.name, name);\n      assertEq(() => \"static\" in ctx, false);\n      assertEq(() => \"private\" in ctx, false);\n      assertEq(() => \"access\" in ctx, false);\n      old = cls;\n    };\n    const obj = {\n      Foo: (_Foo_decorators = [dec(\"Foo\")], _a = class {\n      }, _init = __decoratorStart(null), _a = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _a), __runInitializers(_init, 1, _a), _a)\n    };\n    assertEq(() => obj.Foo, old);\n    const obj2 = {\n      Bar: (_Baz_decorators = [dec(\"Baz\")], _b = class {\n      }, _init2 = __decoratorStart(null), _b = __decorateElement(_init2, 0, \"Baz\", _Baz_decorators, _b), __runInitializers(_init2, 1, _b), _b)\n    };\n    assertEq(() => obj2.Bar, old);\n  },\n  \"Class decorators: Basic expression: Variable initializer\": () => {\n    var _Foo_decorators, _init, _a, _Baz_decorators, _init2, _b;\n    let old;\n    const dec = (name) => (cls, ctx) => {\n      assertEq(() => typeof cls, \"function\");\n      assertEq(() => cls.name, name);\n      assertEq(() => ctx.kind, \"class\");\n      assertEq(() => ctx.name, name);\n      assertEq(() => \"static\" in ctx, false);\n      assertEq(() => \"private\" in ctx, false);\n      assertEq(() => \"access\" in ctx, false);\n      old = cls;\n    };\n    const Foo2 = (_Foo_decorators = [dec(\"Foo\")], _a = class {\n    }, _init = __decoratorStart(null), _a = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _a), __runInitializers(_init, 1, _a), _a);\n    assertEq(() => Foo2, old);\n    const Bar = (_Baz_decorators = [dec(\"Baz\")], _b = class {\n    }, _init2 = __decoratorStart(null), _b = __decorateElement(_init2, 0, \"Baz\", _Baz_decorators, _b), __runInitializers(_init2, 1, _b), _b);\n    assertEq(() => Bar, old);\n  },\n  \"Class decorators: Basic expression: Array binding\": () => {\n    var _Foo_decorators, _init, _a, _Baz_decorators, _init2, _b;\n    let old;\n    const dec = (name) => (cls, ctx) => {\n      assertEq(() => typeof cls, \"function\");\n      assertEq(() => cls.name, name);\n      assertEq(() => ctx.kind, \"class\");\n      assertEq(() => ctx.name, name);\n      assertEq(() => \"static\" in ctx, false);\n      assertEq(() => \"private\" in ctx, false);\n      assertEq(() => \"access\" in ctx, false);\n      old = cls;\n    };\n    const [Foo2 = (_Foo_decorators = [dec(\"Foo\")], _a = class {\n    }, _init = __decoratorStart(null), _a = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _a), __runInitializers(_init, 1, _a), _a)] = [];\n    assertEq(() => Foo2, old);\n    const [Bar = (_Baz_decorators = [dec(\"Baz\")], _b = class {\n    }, _init2 = __decoratorStart(null), _b = __decorateElement(_init2, 0, \"Baz\", _Baz_decorators, _b), __runInitializers(_init2, 1, _b), _b)] = [];\n    assertEq(() => Bar, old);\n  },\n  \"Class decorators: Basic expression: Object binding\": () => {\n    var _Foo_decorators, _init, _a, _Baz_decorators, _init2, _b;\n    let old;\n    const dec = (name) => (cls, ctx) => {\n      assertEq(() => typeof cls, \"function\");\n      assertEq(() => cls.name, name);\n      assertEq(() => ctx.kind, \"class\");\n      assertEq(() => ctx.name, name);\n      assertEq(() => \"static\" in ctx, false);\n      assertEq(() => \"private\" in ctx, false);\n      assertEq(() => \"access\" in ctx, false);\n      old = cls;\n    };\n    const { Foo: Foo2 = (_Foo_decorators = [dec(\"Foo\")], _a = class {\n    }, _init = __decoratorStart(null), _a = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _a), __runInitializers(_init, 1, _a), _a) } = {};\n    assertEq(() => Foo2, old);\n    const { Bar = (_Baz_decorators = [dec(\"Baz\")], _b = class {\n    }, _init2 = __decoratorStart(null), _b = __decorateElement(_init2, 0, \"Baz\", _Baz_decorators, _b), __runInitializers(_init2, 1, _b), _b) } = {};\n    assertEq(() => Bar, old);\n  },\n  \"Class decorators: Basic expression: Assignment initializer\": () => {\n    var _Foo_decorators, _init, _a, _Baz_decorators, _init2, _b;\n    let old;\n    const dec = (name) => (cls, ctx) => {\n      assertEq(() => typeof cls, \"function\");\n      assertEq(() => cls.name, name);\n      assertEq(() => ctx.kind, \"class\");\n      assertEq(() => ctx.name, name);\n      assertEq(() => \"static\" in ctx, false);\n      assertEq(() => \"private\" in ctx, false);\n      assertEq(() => \"access\" in ctx, false);\n      old = cls;\n    };\n    let Foo2;\n    Foo2 = (_Foo_decorators = [dec(\"Foo\")], _a = class {\n    }, _init = __decoratorStart(null), _a = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _a), __runInitializers(_init, 1, _a), _a);\n    assertEq(() => Foo2, old);\n    let Bar;\n    Bar = (_Baz_decorators = [dec(\"Baz\")], _b = class {\n    }, _init2 = __decoratorStart(null), _b = __decorateElement(_init2, 0, \"Baz\", _Baz_decorators, _b), __runInitializers(_init2, 1, _b), _b);\n    assertEq(() => Bar, old);\n  },\n  \"Class decorators: Basic expression: Assignment array binding\": () => {\n    var _Foo_decorators, _init, _a, _Baz_decorators, _init2, _b;\n    let old;\n    const dec = (name) => (cls, ctx) => {\n      assertEq(() => typeof cls, \"function\");\n      assertEq(() => cls.name, name);\n      assertEq(() => ctx.kind, \"class\");\n      assertEq(() => ctx.name, name);\n      assertEq(() => \"static\" in ctx, false);\n      assertEq(() => \"private\" in ctx, false);\n      assertEq(() => \"access\" in ctx, false);\n      old = cls;\n    };\n    let Foo2;\n    [Foo2 = (_Foo_decorators = [dec(\"Foo\")], _a = class {\n    }, _init = __decoratorStart(null), _a = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _a), __runInitializers(_init, 1, _a), _a)] = [];\n    assertEq(() => Foo2, old);\n    let Bar;\n    [Bar = (_Baz_decorators = [dec(\"Baz\")], _b = class {\n    }, _init2 = __decoratorStart(null), _b = __decorateElement(_init2, 0, \"Baz\", _Baz_decorators, _b), __runInitializers(_init2, 1, _b), _b)] = [];\n    assertEq(() => Bar, old);\n  },\n  \"Class decorators: Basic expression: Assignment object binding\": () => {\n    var _Foo_decorators, _init, _a, _Baz_decorators, _init2, _b;\n    let old;\n    const dec = (name) => (cls, ctx) => {\n      assertEq(() => typeof cls, \"function\");\n      assertEq(() => cls.name, name);\n      assertEq(() => ctx.kind, \"class\");\n      assertEq(() => ctx.name, name);\n      assertEq(() => \"static\" in ctx, false);\n      assertEq(() => \"private\" in ctx, false);\n      assertEq(() => \"access\" in ctx, false);\n      old = cls;\n    };\n    let Foo2;\n    ({ Foo: Foo2 = (_Foo_decorators = [dec(\"Foo\")], _a = class {\n    }, _init = __decoratorStart(null), _a = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _a), __runInitializers(_init, 1, _a), _a) } = {});\n    assertEq(() => Foo2, old);\n    let Bar;\n    ({ Bar = (_Baz_decorators = [dec(\"Baz\")], _b = class {\n    }, _init2 = __decoratorStart(null), _b = __decorateElement(_init2, 0, \"Baz\", _Baz_decorators, _b), __runInitializers(_init2, 1, _b), _b) } = {});\n    assertEq(() => Bar, old);\n  },\n  \"Class decorators: Basic expression: Instance field initializer\": () => {\n    var _Foo_decorators, _init, _a, _Baz_decorators, _init2, _b;\n    let old;\n    const dec = (name) => (cls, ctx) => {\n      assertEq(() => typeof cls, \"function\");\n      assertEq(() => cls.name, name);\n      assertEq(() => ctx.kind, \"class\");\n      assertEq(() => ctx.name, name);\n      assertEq(() => \"static\" in ctx, false);\n      assertEq(() => \"private\" in ctx, false);\n      assertEq(() => \"access\" in ctx, false);\n      old = cls;\n    };\n    class Class {\n      Foo = (_Foo_decorators = [dec(\"Foo\")], _a = class {\n      }, _init = __decoratorStart(null), _a = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _a), __runInitializers(_init, 1, _a), _a);\n    }\n    const Foo2 = new Class().Foo;\n    assertEq(() => Foo2, old);\n    class Class2 {\n      Bar = (_Baz_decorators = [dec(\"Baz\")], _b = class {\n      }, _init2 = __decoratorStart(null), _b = __decorateElement(_init2, 0, \"Baz\", _Baz_decorators, _b), __runInitializers(_init2, 1, _b), _b);\n    }\n    const Bar = new Class2().Bar;\n    assertEq(() => Bar, old);\n  },\n  \"Class decorators: Basic expression: Static field initializer\": () => {\n    var _Foo_decorators, _init, _a, _Baz_decorators, _init2, _b;\n    let old;\n    const dec = (name) => (cls, ctx) => {\n      assertEq(() => typeof cls, \"function\");\n      assertEq(() => cls.name, name);\n      assertEq(() => ctx.kind, \"class\");\n      assertEq(() => ctx.name, name);\n      assertEq(() => \"static\" in ctx, false);\n      assertEq(() => \"private\" in ctx, false);\n      assertEq(() => \"access\" in ctx, false);\n      old = cls;\n    };\n    class Class {\n      static Foo = (_Foo_decorators = [dec(\"Foo\")], _a = class {\n      }, _init = __decoratorStart(null), _a = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _a), __runInitializers(_init, 1, _a), _a);\n    }\n    assertEq(() => Class.Foo, old);\n    class Class2 {\n      static Bar = (_Baz_decorators = [dec(\"Baz\")], _b = class {\n      }, _init2 = __decoratorStart(null), _b = __decorateElement(_init2, 0, \"Baz\", _Baz_decorators, _b), __runInitializers(_init2, 1, _b), _b);\n    }\n    assertEq(() => Class2.Bar, old);\n  },\n  \"Class decorators: Basic expression: Instance auto-accessor initializer\": () => {\n    var _Foo_decorators, _init, _a, _Baz_decorators, _init2, _b;\n    let old;\n    const dec = (name) => (cls, ctx) => {\n      assertEq(() => typeof cls, \"function\");\n      assertEq(() => cls.name, name);\n      assertEq(() => ctx.kind, \"class\");\n      assertEq(() => ctx.name, name);\n      assertEq(() => \"static\" in ctx, false);\n      assertEq(() => \"private\" in ctx, false);\n      assertEq(() => \"access\" in ctx, false);\n      old = cls;\n    };\n    class Class {\n      #Foo = (_Foo_decorators = [dec(\"Foo\")], _a = class {\n      }, _init = __decoratorStart(null), _a = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _a), __runInitializers(_init, 1, _a), _a);\n      get Foo() {\n        return this.#Foo;\n      }\n      set Foo(_) {\n        this.#Foo = _;\n      }\n    }\n    const Foo2 = new Class().Foo;\n    assertEq(() => Foo2, old);\n    class Class2 {\n      #Bar = (_Baz_decorators = [dec(\"Baz\")], _b = class {\n      }, _init2 = __decoratorStart(null), _b = __decorateElement(_init2, 0, \"Baz\", _Baz_decorators, _b), __runInitializers(_init2, 1, _b), _b);\n      get Bar() {\n        return this.#Bar;\n      }\n      set Bar(_) {\n        this.#Bar = _;\n      }\n    }\n    const Bar = new Class2().Bar;\n    assertEq(() => Bar, old);\n  },\n  \"Class decorators: Basic expression: Static auto-accessor initializer\": () => {\n    var _Foo_decorators, _init, _a, _Baz_decorators, _init2, _b;\n    let old;\n    const dec = (name) => (cls, ctx) => {\n      assertEq(() => typeof cls, \"function\");\n      assertEq(() => cls.name, name);\n      assertEq(() => ctx.kind, \"class\");\n      assertEq(() => ctx.name, name);\n      assertEq(() => \"static\" in ctx, false);\n      assertEq(() => \"private\" in ctx, false);\n      assertEq(() => \"access\" in ctx, false);\n      old = cls;\n    };\n    class Class {\n      static #Foo = (_Foo_decorators = [dec(\"Foo\")], _a = class {\n      }, _init = __decoratorStart(null), _a = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _a), __runInitializers(_init, 1, _a), _a);\n      static get Foo() {\n        return this.#Foo;\n      }\n      static set Foo(_) {\n        this.#Foo = _;\n      }\n    }\n    assertEq(() => Class.Foo, old);\n    class Class2 {\n      static #Bar = (_Baz_decorators = [dec(\"Baz\")], _b = class {\n      }, _init2 = __decoratorStart(null), _b = __decorateElement(_init2, 0, \"Baz\", _Baz_decorators, _b), __runInitializers(_init2, 1, _b), _b);\n      static get Bar() {\n        return this.#Bar;\n      }\n      static set Bar(_) {\n        this.#Bar = _;\n      }\n    }\n    assertEq(() => Class2.Bar, old);\n  },\n  \"Class decorators: Order\": () => {\n    var _Foo_decorators, _init;\n    const log = [];\n    let Bar;\n    let Baz;\n    const dec1 = (cls, ctx) => {\n      log.push(2);\n      Bar = function() {\n        log.push(4);\n        return new cls();\n      };\n      return Bar;\n    };\n    const dec2 = (cls, ctx) => {\n      log.push(1);\n      Baz = function() {\n        log.push(5);\n        return new cls();\n      };\n      return Baz;\n    };\n    log.push(0);\n    _Foo_decorators = [dec1, dec2];\n    class Foo2 {\n      constructor() {\n        log.push(6);\n      }\n    }\n    _init = __decoratorStart(null);\n    Foo2 = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, Foo2);\n    __runInitializers(_init, 1, Foo2);\n    log.push(3);\n    new Foo2();\n    log.push(7);\n    assertEq(() => Foo2, Bar);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5,6,7\");\n  },\n  \"Class decorators: Return null\": () => {\n    assertThrows(() => {\n      var _Foo_decorators, _init;\n      const dec = (cls, ctx) => {\n        return null;\n      };\n      _Foo_decorators = [dec];\n      class Foo2 {\n      }\n      _init = __decoratorStart(null);\n      Foo2 = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, Foo2);\n      __runInitializers(_init, 1, Foo2);\n    }, TypeError);\n  },\n  \"Class decorators: Return object\": () => {\n    assertThrows(() => {\n      var _Foo_decorators, _init;\n      const dec = (cls, ctx) => {\n        return {};\n      };\n      _Foo_decorators = [dec];\n      class Foo2 {\n      }\n      _init = __decoratorStart(null);\n      Foo2 = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, Foo2);\n      __runInitializers(_init, 1, Foo2);\n    }, TypeError);\n  },\n  \"Class decorators: Extra initializer\": () => {\n    var _Foo_decorators, _init;\n    let oldAddInitializer;\n    let got;\n    const dec = (cls, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _Foo_decorators = [dec, dec];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    Foo2 = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, Foo2);\n    __runInitializers(_init, 1, Foo2);\n    assertEq(() => got.this, Foo2);\n    assertEq(() => got.args.length, 0);\n  },\n  // Method decorators\n  \"Method decorators: Basic (instance method)\": () => {\n    var _baz_dec, _a, _bar_dec, _b, _foo_dec, _init;\n    const old = {};\n    const dec = (key, name) => (fn, ctx) => {\n      assertEq(() => typeof fn, \"function\");\n      assertEq(() => fn.name, name);\n      assertEq(() => ctx.kind, \"method\");\n      assertEq(() => ctx.name, key);\n      assertEq(() => ctx.static, false);\n      assertEq(() => ctx.private, false);\n      assertEq(() => ctx.access.has({ [key]: false }), true);\n      assertEq(() => ctx.access.has({ bar: true }), false);\n      assertEq(() => ctx.access.get({ [key]: 123 }), 123);\n      assertEq(() => \"set\" in ctx.access, false);\n      old[key] = fn;\n    };\n    const bar = /* @__PURE__ */ Symbol(\"bar\");\n    const baz = /* @__PURE__ */ Symbol();\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n      }\n      foo() {\n      }\n      [(_foo_dec = [dec(\"foo\", \"foo\")], _b = (_bar_dec = [dec(bar, \"[bar]\")], bar))]() {\n      }\n      [_a = (_baz_dec = [dec(baz, \"\")], baz)]() {\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 1, \"foo\", _foo_dec, Foo2);\n    __decorateElement(_init, 1, _b, _bar_dec, Foo2);\n    __decorateElement(_init, 1, _a, _baz_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => Foo2.prototype.foo, old[\"foo\"]);\n    assertEq(() => Foo2.prototype[bar], old[bar]);\n    assertEq(() => Foo2.prototype[baz], old[baz]);\n  },\n  \"Method decorators: Basic (static method)\": () => {\n    var _baz_dec, _a, _bar_dec, _b, _foo_dec, _init;\n    const old = {};\n    const dec = (key, name) => (fn, ctx) => {\n      assertEq(() => typeof fn, \"function\");\n      assertEq(() => fn.name, name);\n      assertEq(() => ctx.kind, \"method\");\n      assertEq(() => ctx.name, key);\n      assertEq(() => ctx.static, true);\n      assertEq(() => ctx.private, false);\n      assertEq(() => ctx.access.has({ [key]: false }), true);\n      assertEq(() => ctx.access.has({ bar: true }), false);\n      assertEq(() => ctx.access.get({ [key]: 123 }), 123);\n      assertEq(() => \"set\" in ctx.access, false);\n      old[key] = fn;\n    };\n    const bar = /* @__PURE__ */ Symbol(\"bar\");\n    const baz = /* @__PURE__ */ Symbol();\n    class Foo2 {\n      static foo() {\n      }\n      static [(_foo_dec = [dec(\"foo\", \"foo\")], _b = (_bar_dec = [dec(bar, \"[bar]\")], bar))]() {\n      }\n      static [_a = (_baz_dec = [dec(baz, \"\")], baz)]() {\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 9, \"foo\", _foo_dec, Foo2);\n    __decorateElement(_init, 9, _b, _bar_dec, Foo2);\n    __decorateElement(_init, 9, _a, _baz_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    assertEq(() => Foo2.foo, old[\"foo\"]);\n    assertEq(() => Foo2[bar], old[bar]);\n    assertEq(() => Foo2[baz], old[baz]);\n  },\n  \"Method decorators: Basic (private instance method)\": () => {\n    var _foo_dec, _init, _Foo_instances, foo_fn;\n    let old;\n    let lateAsserts;\n    const dec = (fn, ctx) => {\n      assertEq(() => typeof fn, \"function\");\n      assertEq(() => fn.name, \"#foo\");\n      assertEq(() => ctx.kind, \"method\");\n      assertEq(() => ctx.name, \"#foo\");\n      assertEq(() => ctx.static, false);\n      assertEq(() => ctx.private, true);\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(new Foo2()), true);\n        assertEq(() => ctx.access.has({}), false);\n        assertEq(() => ctx.access.get(new Foo2()), $foo);\n        assertEq(() => \"set\" in ctx.access, false);\n      };\n      old = fn;\n    };\n    let $foo;\n    _foo_dec = [dec];\n    const _Foo = class _Foo {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __privateAdd(this, _Foo_instances);\n      }\n    };\n    _init = __decoratorStart(null);\n    _Foo_instances = new WeakSet();\n    foo_fn = function() {\n    };\n    foo_fn = __decorateElement(_init, 17, \"#foo\", _foo_dec, _Foo_instances, foo_fn);\n    __decoratorMetadata(_init, _Foo);\n    $foo = __privateMethod(new _Foo(), _Foo_instances, foo_fn);\n    let Foo2 = _Foo;\n    assertEq(() => $foo, old);\n    lateAsserts();\n  },\n  \"Method decorators: Basic (private static method)\": () => {\n    var _foo_dec, _init, _Foo_static, foo_fn;\n    let old;\n    let lateAsserts;\n    const dec = (fn, ctx) => {\n      assertEq(() => typeof fn, \"function\");\n      assertEq(() => fn.name, \"#foo\");\n      assertEq(() => ctx.kind, \"method\");\n      assertEq(() => ctx.name, \"#foo\");\n      assertEq(() => ctx.static, true);\n      assertEq(() => ctx.private, true);\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(Foo2), true);\n        assertEq(() => ctx.access.has({}), false);\n        assertEq(() => ctx.access.get(Foo2), $foo);\n        assertEq(() => \"set\" in ctx.access, false);\n      };\n      old = fn;\n    };\n    let $foo;\n    _foo_dec = [dec];\n    const _Foo = class _Foo {\n    };\n    _init = __decoratorStart(null);\n    _Foo_static = new WeakSet();\n    foo_fn = function() {\n    };\n    foo_fn = __decorateElement(_init, 25, \"#foo\", _foo_dec, _Foo_static, foo_fn);\n    __privateAdd(_Foo, _Foo_static);\n    __decoratorMetadata(_init, _Foo);\n    __runInitializers(_init, 3, _Foo);\n    $foo = __privateMethod(_Foo, _Foo_static, foo_fn);\n    let Foo2 = _Foo;\n    assertEq(() => $foo, old);\n    lateAsserts();\n  },\n  \"Method decorators: Shim (instance method)\": () => {\n    var _foo_dec, _init;\n    let bar;\n    const dec = (fn, ctx) => {\n      bar = function() {\n        return fn.call(this) + 1;\n      };\n      return bar;\n    };\n    _foo_dec = [dec];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __publicField(this, \"bar\", 123);\n      }\n      foo() {\n        return this.bar;\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 1, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => Foo2.prototype.foo, bar);\n    assertEq(() => new Foo2().foo(), 124);\n  },\n  \"Method decorators: Shim (static method)\": () => {\n    var _foo_dec, _init;\n    let bar;\n    const dec = (fn, ctx) => {\n      bar = function() {\n        return fn.call(this) + 1;\n      };\n      return bar;\n    };\n    _foo_dec = [dec];\n    class Foo2 {\n      static foo() {\n        return this.bar;\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 9, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    __publicField(Foo2, \"bar\", 123);\n    assertEq(() => Foo2.foo, bar);\n    assertEq(() => Foo2.foo(), 124);\n  },\n  \"Method decorators: Shim (private instance method)\": () => {\n    var _foo_dec, _init, _Foo_instances, foo_fn;\n    let bar;\n    const dec = (fn, ctx) => {\n      bar = function() {\n        return fn.call(this) + 1;\n      };\n      return bar;\n    };\n    let $foo;\n    _foo_dec = [dec];\n    const _Foo = class _Foo {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __privateAdd(this, _Foo_instances);\n        __publicField(this, \"bar\", 123);\n      }\n    };\n    _init = __decoratorStart(null);\n    _Foo_instances = new WeakSet();\n    foo_fn = function() {\n      return this.bar;\n    };\n    foo_fn = __decorateElement(_init, 17, \"#foo\", _foo_dec, _Foo_instances, foo_fn);\n    __decoratorMetadata(_init, _Foo);\n    $foo = __privateMethod(new _Foo(), _Foo_instances, foo_fn);\n    let Foo2 = _Foo;\n    assertEq(() => $foo, bar);\n    assertEq(() => bar.call(new Foo2()), 124);\n  },\n  \"Method decorators: Shim (private static method)\": () => {\n    var _foo_dec, _init, _Foo_static, foo_fn;\n    let bar;\n    const dec = (fn, ctx) => {\n      bar = function() {\n        return fn.call(this) + 1;\n      };\n      return bar;\n    };\n    let $foo;\n    _foo_dec = [dec];\n    const _Foo = class _Foo {\n    };\n    _init = __decoratorStart(null);\n    _Foo_static = new WeakSet();\n    foo_fn = function() {\n      return this.bar;\n    };\n    foo_fn = __decorateElement(_init, 25, \"#foo\", _foo_dec, _Foo_static, foo_fn);\n    __privateAdd(_Foo, _Foo_static);\n    __decoratorMetadata(_init, _Foo);\n    __runInitializers(_init, 3, _Foo);\n    __publicField(_Foo, \"bar\", 123);\n    $foo = __privateMethod(_Foo, _Foo_static, foo_fn);\n    let Foo2 = _Foo;\n    assertEq(() => $foo, bar);\n    assertEq(() => bar.call(Foo2), 124);\n  },\n  \"Method decorators: Order (instance method)\": () => {\n    var _foo_dec, _init;\n    const log = [];\n    let bar;\n    let baz;\n    const dec1 = (fn, ctx) => {\n      log.push(2);\n      bar = function() {\n        log.push(4);\n        return fn.call(this);\n      };\n      return bar;\n    };\n    const dec2 = (fn, ctx) => {\n      log.push(1);\n      baz = function() {\n        log.push(5);\n        return fn.call(this);\n      };\n      return baz;\n    };\n    log.push(0);\n    _foo_dec = [dec1, dec2];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n      }\n      foo() {\n        return log.push(6);\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 1, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    log.push(3);\n    new Foo2().foo();\n    log.push(7);\n    assertEq(() => Foo2.prototype.foo, bar);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5,6,7\");\n  },\n  \"Method decorators: Order (static method)\": () => {\n    var _foo_dec, _init;\n    const log = [];\n    let bar;\n    let baz;\n    const dec1 = (fn, ctx) => {\n      log.push(2);\n      bar = function() {\n        log.push(4);\n        return fn.call(this);\n      };\n      return bar;\n    };\n    const dec2 = (fn, ctx) => {\n      log.push(1);\n      baz = function() {\n        log.push(5);\n        return fn.call(this);\n      };\n      return baz;\n    };\n    log.push(0);\n    _foo_dec = [dec1, dec2];\n    class Foo2 {\n      static foo() {\n        return log.push(6);\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 9, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    log.push(3);\n    Foo2.foo();\n    log.push(7);\n    assertEq(() => Foo2.foo, bar);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5,6,7\");\n  },\n  \"Method decorators: Order (private instance method)\": () => {\n    var _foo_dec, _init, _Foo_instances, foo_fn;\n    const log = [];\n    let bar;\n    let baz;\n    const dec1 = (fn, ctx) => {\n      log.push(2);\n      bar = function() {\n        log.push(4);\n        return fn.call(this);\n      };\n      return bar;\n    };\n    const dec2 = (fn, ctx) => {\n      log.push(1);\n      baz = function() {\n        log.push(5);\n        return fn.call(this);\n      };\n      return baz;\n    };\n    log.push(0);\n    let $foo;\n    _foo_dec = [dec1, dec2];\n    const _Foo = class _Foo {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __privateAdd(this, _Foo_instances);\n      }\n    };\n    _init = __decoratorStart(null);\n    _Foo_instances = new WeakSet();\n    foo_fn = function() {\n      return log.push(6);\n    };\n    foo_fn = __decorateElement(_init, 17, \"#foo\", _foo_dec, _Foo_instances, foo_fn);\n    __decoratorMetadata(_init, _Foo);\n    $foo = __privateMethod(new _Foo(), _Foo_instances, foo_fn);\n    let Foo2 = _Foo;\n    log.push(3);\n    $foo.call(new Foo2());\n    log.push(7);\n    assertEq(() => $foo, bar);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5,6,7\");\n  },\n  \"Method decorators: Order (private static method)\": () => {\n    var _foo_dec, _init, _Foo_static, foo_fn;\n    const log = [];\n    let bar;\n    let baz;\n    const dec1 = (fn, ctx) => {\n      log.push(2);\n      bar = function() {\n        log.push(4);\n        return fn.call(this);\n      };\n      return bar;\n    };\n    const dec2 = (fn, ctx) => {\n      log.push(1);\n      baz = function() {\n        log.push(5);\n        return fn.call(this);\n      };\n      return baz;\n    };\n    log.push(0);\n    let $foo;\n    _foo_dec = [dec1, dec2];\n    const _Foo = class _Foo {\n    };\n    _init = __decoratorStart(null);\n    _Foo_static = new WeakSet();\n    foo_fn = function() {\n      return log.push(6);\n    };\n    foo_fn = __decorateElement(_init, 25, \"#foo\", _foo_dec, _Foo_static, foo_fn);\n    __privateAdd(_Foo, _Foo_static);\n    __decoratorMetadata(_init, _Foo);\n    __runInitializers(_init, 3, _Foo);\n    $foo = __privateMethod(_Foo, _Foo_static, foo_fn);\n    let Foo2 = _Foo;\n    log.push(3);\n    $foo.call(Foo2);\n    log.push(7);\n    assertEq(() => $foo, bar);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5,6,7\");\n  },\n  \"Method decorators: Return null (instance method)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (fn, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __runInitializers(_init, 5, this);\n        }\n        foo() {\n        }\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 1, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Method decorators: Return null (static method)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (fn, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        static foo() {\n        }\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 9, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n      __runInitializers(_init, 3, Foo2);\n    }, TypeError);\n  },\n  \"Method decorators: Return null (private instance method)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _Foo_instances, foo_fn;\n      const dec = (fn, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __runInitializers(_init, 5, this);\n          __privateAdd(this, _Foo_instances);\n        }\n      }\n      _init = __decoratorStart(null);\n      _Foo_instances = new WeakSet();\n      foo_fn = function() {\n      };\n      foo_fn = __decorateElement(_init, 17, \"#foo\", _foo_dec, _Foo_instances, foo_fn);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Method decorators: Return null (private static method)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _Foo_static, foo_fn;\n      const dec = (fn, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n      }\n      _init = __decoratorStart(null);\n      _Foo_static = new WeakSet();\n      foo_fn = function() {\n      };\n      foo_fn = __decorateElement(_init, 25, \"#foo\", _foo_dec, _Foo_static, foo_fn);\n      __privateAdd(Foo2, _Foo_static);\n      __decoratorMetadata(_init, Foo2);\n      __runInitializers(_init, 3, Foo2);\n    }, TypeError);\n  },\n  \"Method decorators: Return object (instance method)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (fn, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __runInitializers(_init, 5, this);\n        }\n        foo() {\n        }\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 1, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Method decorators: Return object (static method)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (fn, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        static foo() {\n        }\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 9, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n      __runInitializers(_init, 3, Foo2);\n    }, TypeError);\n  },\n  \"Method decorators: Return object (private instance method)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _Foo_instances, foo_fn;\n      const dec = (fn, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __runInitializers(_init, 5, this);\n          __privateAdd(this, _Foo_instances);\n        }\n      }\n      _init = __decoratorStart(null);\n      _Foo_instances = new WeakSet();\n      foo_fn = function() {\n      };\n      foo_fn = __decorateElement(_init, 17, \"#foo\", _foo_dec, _Foo_instances, foo_fn);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Method decorators: Return object (private static method)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _Foo_static, foo_fn;\n      const dec = (fn, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n      }\n      _init = __decoratorStart(null);\n      _Foo_static = new WeakSet();\n      foo_fn = function() {\n      };\n      foo_fn = __decorateElement(_init, 25, \"#foo\", _foo_dec, _Foo_static, foo_fn);\n      __privateAdd(Foo2, _Foo_static);\n      __decoratorMetadata(_init, Foo2);\n      __runInitializers(_init, 3, Foo2);\n    }, TypeError);\n  },\n  \"Method decorators: Extra initializer (instance method)\": () => {\n    var _foo_dec, _init;\n    let oldAddInitializer;\n    let got;\n    const dec = (fn, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n      }\n      foo() {\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 1, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => got, void 0);\n    const instance = new Foo2();\n    assertEq(() => got.this, instance);\n    assertEq(() => got.args.length, 0);\n  },\n  \"Method decorators: Extra initializer (static method)\": () => {\n    var _foo_dec, _init;\n    let oldAddInitializer;\n    let got;\n    const dec = (fn, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n      static foo() {\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 9, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    assertEq(() => got.this, Foo2);\n    assertEq(() => got.args.length, 0);\n  },\n  \"Method decorators: Extra initializer (private instance method)\": () => {\n    var _foo_dec, _init, _Foo_instances, foo_fn;\n    let oldAddInitializer;\n    let got;\n    const dec = (fn, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __privateAdd(this, _Foo_instances);\n      }\n    }\n    _init = __decoratorStart(null);\n    _Foo_instances = new WeakSet();\n    foo_fn = function() {\n    };\n    foo_fn = __decorateElement(_init, 17, \"#foo\", _foo_dec, _Foo_instances, foo_fn);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => got, void 0);\n    const instance = new Foo2();\n    assertEq(() => got.this, instance);\n    assertEq(() => got.args.length, 0);\n  },\n  \"Method decorators: Extra initializer (private static method)\": () => {\n    var _foo_dec, _init, _Foo_static, foo_fn;\n    let oldAddInitializer;\n    let got;\n    const dec = (fn, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _Foo_static = new WeakSet();\n    foo_fn = function() {\n    };\n    foo_fn = __decorateElement(_init, 25, \"#foo\", _foo_dec, _Foo_static, foo_fn);\n    __privateAdd(Foo2, _Foo_static);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    assertEq(() => got.this, Foo2);\n    assertEq(() => got.args.length, 0);\n  },\n  // Field decorators\n  \"Field decorators: Basic (instance field)\": () => {\n    var _baz_dec, _a, _bar_dec, _b, _foo_dec, _init;\n    const dec = (key) => (value, ctx) => {\n      assertEq(() => value, void 0);\n      assertEq(() => ctx.kind, \"field\");\n      assertEq(() => ctx.name, key);\n      assertEq(() => ctx.static, false);\n      assertEq(() => ctx.private, false);\n      assertEq(() => ctx.access.has({ [key]: false }), true);\n      assertEq(() => ctx.access.has({ bar: true }), false);\n      assertEq(() => ctx.access.get({ [key]: 123 }), 123);\n      assertEq(() => {\n        const obj = {};\n        ctx.access.set(obj, 321);\n        return obj[key];\n      }, 321);\n    };\n    const bar = /* @__PURE__ */ Symbol(\"bar\");\n    const baz = /* @__PURE__ */ Symbol();\n    _foo_dec = [dec(\"foo\")], _b = (_bar_dec = [dec(bar)], bar), _a = (_baz_dec = [dec(baz)], baz);\n    class Foo2 {\n      constructor() {\n        __publicField(this, \"foo\", __runInitializers(_init, 8, this, 123)), __runInitializers(_init, 11, this);\n        __publicField(this, _b, __runInitializers(_init, 12, this, 123)), __runInitializers(_init, 15, this);\n        __publicField(this, _a, __runInitializers(_init, 16, this, 123)), __runInitializers(_init, 19, this);\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 5, \"foo\", _foo_dec, Foo2);\n    __decorateElement(_init, 5, _b, _bar_dec, Foo2);\n    __decorateElement(_init, 5, _a, _baz_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => new Foo2().foo, 123);\n    assertEq(() => new Foo2()[bar], 123);\n    assertEq(() => new Foo2()[baz], 123);\n  },\n  \"Field decorators: Basic (static field)\": () => {\n    var _baz_dec, _a, _bar_dec, _b, _foo_dec, _init;\n    const dec = (key) => (value, ctx) => {\n      assertEq(() => value, void 0);\n      assertEq(() => ctx.kind, \"field\");\n      assertEq(() => ctx.name, key);\n      assertEq(() => ctx.static, true);\n      assertEq(() => ctx.private, false);\n      assertEq(() => ctx.access.has({ [key]: false }), true);\n      assertEq(() => ctx.access.has({ bar: true }), false);\n      assertEq(() => ctx.access.get({ [key]: 123 }), 123);\n      assertEq(() => {\n        const obj = {};\n        ctx.access.set(obj, 321);\n        return obj[key];\n      }, 321);\n    };\n    const bar = /* @__PURE__ */ Symbol(\"bar\");\n    const baz = /* @__PURE__ */ Symbol();\n    _foo_dec = [dec(\"foo\")], _b = (_bar_dec = [dec(bar)], bar), _a = (_baz_dec = [dec(baz)], baz);\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 13, \"foo\", _foo_dec, Foo2);\n    __decorateElement(_init, 13, _b, _bar_dec, Foo2);\n    __decorateElement(_init, 13, _a, _baz_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    __publicField(Foo2, \"foo\", __runInitializers(_init, 8, Foo2, 123)), __runInitializers(_init, 11, Foo2);\n    __publicField(Foo2, _b, __runInitializers(_init, 12, Foo2, 123)), __runInitializers(_init, 15, Foo2);\n    __publicField(Foo2, _a, __runInitializers(_init, 16, Foo2, 123)), __runInitializers(_init, 19, Foo2);\n    assertEq(() => Foo2.foo, 123);\n    assertEq(() => Foo2[bar], 123);\n    assertEq(() => Foo2[baz], 123);\n  },\n  \"Field decorators: Basic (private instance field)\": () => {\n    var _foo_dec, _init, _foo;\n    let lateAsserts;\n    const dec = (value, ctx) => {\n      assertEq(() => value, void 0);\n      assertEq(() => ctx.kind, \"field\");\n      assertEq(() => ctx.name, \"#foo\");\n      assertEq(() => ctx.static, false);\n      assertEq(() => ctx.private, true);\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(new Foo2()), true);\n        assertEq(() => ctx.access.has({}), false);\n        assertEq(() => ctx.access.get(new Foo2()), 123);\n        assertEq(() => {\n          const obj = new Foo2();\n          ctx.access.set(obj, 321);\n          return get$foo(obj);\n        }, 321);\n      };\n    };\n    let get$foo;\n    _foo_dec = [dec];\n    class Foo2 {\n      constructor() {\n        __privateAdd(this, _foo, __runInitializers(_init, 8, this, 123)), __runInitializers(_init, 11, this);\n      }\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    __decorateElement(_init, 21, \"#foo\", _foo_dec, _foo);\n    __decoratorMetadata(_init, Foo2);\n    get$foo = (x) => __privateGet(x, _foo);\n    assertEq(() => get$foo(new Foo2()), 123);\n    lateAsserts();\n  },\n  \"Field decorators: Basic (private static field)\": () => {\n    var _foo_dec, _init, _foo;\n    let lateAsserts;\n    const dec = (value, ctx) => {\n      assertEq(() => value, void 0);\n      assertEq(() => ctx.kind, \"field\");\n      assertEq(() => ctx.name, \"#foo\");\n      assertEq(() => ctx.static, true);\n      assertEq(() => ctx.private, true);\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(Foo2), true);\n        assertEq(() => ctx.access.has({}), false);\n        assertEq(() => ctx.access.get(Foo2), 123);\n        assertEq(() => {\n          ctx.access.set(Foo2, 321);\n          return get$foo(Foo2);\n        }, 321);\n      };\n    };\n    let get$foo;\n    _foo_dec = [dec];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    __decorateElement(_init, 29, \"#foo\", _foo_dec, _foo);\n    __decoratorMetadata(_init, Foo2);\n    __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2, 123)), __runInitializers(_init, 11, Foo2);\n    get$foo = (x) => __privateGet(x, _foo);\n    assertEq(() => get$foo(Foo2), 123);\n    lateAsserts();\n  },\n  \"Field decorators: Shim (instance field)\": () => {\n    var _bar_dec, _foo_dec, _init;\n    let log = [];\n    const dec = (value, ctx) => {\n      return function(x) {\n        assertEq(() => this instanceof Foo2, true);\n        return log.push(\"foo\" in this, \"bar\" in this, x);\n      };\n    };\n    _foo_dec = [dec], _bar_dec = [dec];\n    class Foo2 {\n      constructor() {\n        __publicField(this, \"foo\", __runInitializers(_init, 8, this, 123)), __runInitializers(_init, 11, this);\n        __publicField(this, \"bar\", __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 5, \"foo\", _foo_dec, Foo2);\n    __decorateElement(_init, 5, \"bar\", _bar_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => log + \"\", \"\");\n    var obj = new Foo2();\n    assertEq(() => obj.foo, 3);\n    assertEq(() => obj.bar, 6);\n    assertEq(() => log + \"\", \"false,false,123,true,false,\");\n  },\n  \"Field decorators: Shim (static field)\": () => {\n    var _bar_dec, _foo_dec, _init;\n    let foo;\n    let log = [];\n    const dec = (value, ctx) => {\n      return function(x) {\n        assertEq(() => this, foo);\n        return log.push(\"foo\" in this, \"bar\" in this, x);\n      };\n    };\n    assertEq(() => log + \"\", \"\");\n    _foo_dec = [dec], _bar_dec = [dec];\n    const _Foo = class _Foo {\n    };\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 13, \"foo\", _foo_dec, _Foo);\n    __decorateElement(_init, 13, \"bar\", _bar_dec, _Foo);\n    __decoratorMetadata(_init, _Foo);\n    foo = _Foo;\n    __publicField(_Foo, \"foo\", __runInitializers(_init, 8, _Foo, 123)), __runInitializers(_init, 11, _Foo);\n    __publicField(_Foo, \"bar\", __runInitializers(_init, 12, _Foo)), __runInitializers(_init, 15, _Foo);\n    let Foo2 = _Foo;\n    assertEq(() => Foo2.foo, 3);\n    assertEq(() => Foo2.bar, 6);\n    assertEq(() => log + \"\", \"false,false,123,true,false,\");\n  },\n  \"Field decorators: Shim (private instance field)\": () => {\n    var _bar_dec, _foo_dec, _init, _foo, _bar;\n    let log = [];\n    const dec = (value, ctx) => {\n      return function(x) {\n        assertEq(() => this instanceof Foo2, true);\n        return log.push(has$foo(this), has$bar(this), x);\n      };\n    };\n    let has$foo;\n    let has$bar;\n    let get$foo;\n    let get$bar;\n    _foo_dec = [dec], _bar_dec = [dec];\n    class Foo2 {\n      constructor() {\n        __privateAdd(this, _foo, __runInitializers(_init, 8, this, 123)), __runInitializers(_init, 11, this);\n        __privateAdd(this, _bar, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n      }\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    _bar = new WeakMap();\n    __decorateElement(_init, 21, \"#foo\", _foo_dec, _foo);\n    __decorateElement(_init, 21, \"#bar\", _bar_dec, _bar);\n    __decoratorMetadata(_init, Foo2);\n    has$foo = (x) => __privateIn(_foo, x);\n    has$bar = (x) => __privateIn(_bar, x);\n    get$foo = (x) => __privateGet(x, _foo);\n    get$bar = (x) => __privateGet(x, _bar);\n    assertEq(() => log + \"\", \"\");\n    var obj = new Foo2();\n    assertEq(() => get$foo(obj), 3);\n    assertEq(() => get$bar(obj), 6);\n    assertEq(() => log + \"\", \"false,false,123,true,false,\");\n  },\n  \"Field decorators: Shim (private static field)\": () => {\n    var _bar_dec, _foo_dec, _init, _foo, _bar;\n    let foo;\n    let log = [];\n    const dec = (value, ctx) => {\n      return function(x) {\n        assertEq(() => this, foo);\n        return log.push(has$foo(this), has$bar(this), x);\n      };\n    };\n    assertEq(() => log + \"\", \"\");\n    let has$foo;\n    let has$bar;\n    let get$foo;\n    let get$bar;\n    _foo_dec = [dec], _bar_dec = [dec];\n    const _Foo = class _Foo {\n    };\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    _bar = new WeakMap();\n    __decorateElement(_init, 29, \"#foo\", _foo_dec, _foo);\n    __decorateElement(_init, 29, \"#bar\", _bar_dec, _bar);\n    __decoratorMetadata(_init, _Foo);\n    foo = _Foo;\n    has$foo = (x) => __privateIn(_foo, x);\n    has$bar = (x) => __privateIn(_bar, x);\n    get$foo = (x) => __privateGet(x, _foo);\n    get$bar = (x) => __privateGet(x, _bar);\n    __privateAdd(_Foo, _foo, __runInitializers(_init, 8, _Foo, 123)), __runInitializers(_init, 11, _Foo);\n    __privateAdd(_Foo, _bar, __runInitializers(_init, 12, _Foo)), __runInitializers(_init, 15, _Foo);\n    let Foo2 = _Foo;\n    assertEq(() => get$foo(Foo2), 3);\n    assertEq(() => get$bar(Foo2), 6);\n    assertEq(() => log + \"\", \"false,false,123,true,false,\");\n  },\n  \"Field decorators: Order (instance field)\": () => {\n    var _foo_dec, _init;\n    const log = [];\n    const dec1 = (value, ctx) => {\n      log.push(2);\n      return () => log.push(4);\n    };\n    const dec2 = (value, ctx) => {\n      log.push(1);\n      return () => log.push(5);\n    };\n    log.push(0);\n    _foo_dec = [dec1, dec2];\n    class Foo2 {\n      constructor() {\n        __publicField(this, \"foo\", __runInitializers(_init, 8, this, 123)), __runInitializers(_init, 11, this);\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 5, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    log.push(3);\n    var obj = new Foo2();\n    log.push(6);\n    assertEq(() => obj.foo, 6);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5,6\");\n  },\n  \"Field decorators: Order (static field)\": () => {\n    var _foo_dec, _init;\n    const log = [];\n    const dec1 = (value, ctx) => {\n      log.push(2);\n      return () => log.push(3);\n    };\n    const dec2 = (value, ctx) => {\n      log.push(1);\n      return () => log.push(4);\n    };\n    log.push(0);\n    _foo_dec = [dec1, dec2];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 13, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    __publicField(Foo2, \"foo\", __runInitializers(_init, 8, Foo2, 123)), __runInitializers(_init, 11, Foo2);\n    log.push(5);\n    assertEq(() => Foo2.foo, 5);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5\");\n  },\n  \"Field decorators: Order (private instance field)\": () => {\n    var _foo_dec, _init, _foo;\n    const log = [];\n    const dec1 = (value, ctx) => {\n      log.push(2);\n      return () => log.push(4);\n    };\n    const dec2 = (value, ctx) => {\n      log.push(1);\n      return () => log.push(5);\n    };\n    log.push(0);\n    let get$foo;\n    _foo_dec = [dec1, dec2];\n    class Foo2 {\n      constructor() {\n        __privateAdd(this, _foo, __runInitializers(_init, 8, this, 123)), __runInitializers(_init, 11, this);\n      }\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    __decorateElement(_init, 21, \"#foo\", _foo_dec, _foo);\n    __decoratorMetadata(_init, Foo2);\n    get$foo = (x) => __privateGet(x, _foo);\n    log.push(3);\n    var obj = new Foo2();\n    log.push(6);\n    assertEq(() => get$foo(obj), 6);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5,6\");\n  },\n  \"Field decorators: Order (private static field)\": () => {\n    var _foo_dec, _init, _foo;\n    const log = [];\n    const dec1 = (value, ctx) => {\n      log.push(2);\n      return () => log.push(3);\n    };\n    const dec2 = (value, ctx) => {\n      log.push(1);\n      return () => log.push(4);\n    };\n    log.push(0);\n    let get$foo;\n    _foo_dec = [dec1, dec2];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    __decorateElement(_init, 29, \"#foo\", _foo_dec, _foo);\n    __decoratorMetadata(_init, Foo2);\n    __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2, 123)), __runInitializers(_init, 11, Foo2);\n    get$foo = (x) => __privateGet(x, _foo);\n    log.push(5);\n    assertEq(() => get$foo(Foo2), 5);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5\");\n  },\n  \"Field decorators: Return null (instance field)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (value, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __publicField(this, \"foo\", __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);\n        }\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 5, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Field decorators: Return null (static field)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (value, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 13, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n      __publicField(Foo2, \"foo\", __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n    }, TypeError);\n  },\n  \"Field decorators: Return null (private instance field)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _foo;\n      const dec = (value, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __privateAdd(this, _foo, __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);\n        }\n      }\n      _init = __decoratorStart(null);\n      _foo = new WeakMap();\n      __decorateElement(_init, 21, \"#foo\", _foo_dec, _foo);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Field decorators: Return null (private static field)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _foo;\n      const dec = (value, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n      }\n      _init = __decoratorStart(null);\n      _foo = new WeakMap();\n      __decorateElement(_init, 29, \"#foo\", _foo_dec, _foo);\n      __decoratorMetadata(_init, Foo2);\n      __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n    }, TypeError);\n  },\n  \"Field decorators: Return object (instance field)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (value, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __publicField(this, \"foo\", __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);\n        }\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 5, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Field decorators: Return object (static field)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (value, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 13, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n      __publicField(Foo2, \"foo\", __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n    }, TypeError);\n  },\n  \"Field decorators: Return object (private instance field)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _foo;\n      const dec = (value, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __privateAdd(this, _foo, __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);\n        }\n      }\n      _init = __decoratorStart(null);\n      _foo = new WeakMap();\n      __decorateElement(_init, 21, \"#foo\", _foo_dec, _foo);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Field decorators: Return object (private static field)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _foo;\n      const dec = (value, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n      }\n      _init = __decoratorStart(null);\n      _foo = new WeakMap();\n      __decorateElement(_init, 29, \"#foo\", _foo_dec, _foo);\n      __decoratorMetadata(_init, Foo2);\n      __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n    }, TypeError);\n  },\n  \"Field decorators: Extra initializer (instance field)\": () => {\n    var _foo_dec, _init;\n    let oldAddInitializer;\n    let got;\n    const dec = (value, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n      constructor() {\n        __publicField(this, \"foo\", __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 5, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => got, void 0);\n    const instance = new Foo2();\n    assertEq(() => got.this, instance);\n    assertEq(() => got.args.length, 0);\n  },\n  \"Field decorators: Extra initializer (static field)\": () => {\n    var _foo_dec, _init;\n    let oldAddInitializer;\n    let got;\n    const dec = (value, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 13, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    __publicField(Foo2, \"foo\", __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n    assertEq(() => got.this, Foo2);\n    assertEq(() => got.args.length, 0);\n  },\n  \"Field decorators: Extra initializer (private instance field)\": () => {\n    var _foo_dec, _init, _foo;\n    let oldAddInitializer;\n    let got;\n    const dec = (value, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n      constructor() {\n        __privateAdd(this, _foo, __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);\n      }\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    __decorateElement(_init, 21, \"#foo\", _foo_dec, _foo);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => got, void 0);\n    const instance = new Foo2();\n    assertEq(() => got.this, instance);\n    assertEq(() => got.args.length, 0);\n  },\n  \"Field decorators: Extra initializer (private static field)\": () => {\n    var _foo_dec, _init, _foo;\n    let oldAddInitializer;\n    let got;\n    const dec = (value, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    __decorateElement(_init, 29, \"#foo\", _foo_dec, _foo);\n    __decoratorMetadata(_init, Foo2);\n    __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n    assertEq(() => got.this, Foo2);\n    assertEq(() => got.args.length, 0);\n  },\n  // Getter decorators\n  \"Getter decorators: Basic (instance getter)\": () => {\n    var _baz_dec, _a, _bar_dec, _b, _foo_dec, _init;\n    const dec = (key, name) => (fn, ctx) => {\n      assertEq(() => typeof fn, \"function\");\n      assertEq(() => fn.name, name);\n      assertEq(() => ctx.kind, \"getter\");\n      assertEq(() => ctx.name, key);\n      assertEq(() => ctx.static, false);\n      assertEq(() => ctx.private, false);\n      assertEq(() => ctx.access.has({ [key]: false }), true);\n      assertEq(() => ctx.access.has({ bar: true }), false);\n      assertEq(() => ctx.access.get({ [key]: 123 }), 123);\n      assertEq(() => \"set\" in ctx.access, false);\n    };\n    const bar = /* @__PURE__ */ Symbol(\"bar\");\n    const baz = /* @__PURE__ */ Symbol();\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __publicField(this, \"bar\", 123);\n      }\n      get foo() {\n        return this.bar;\n      }\n      get [(_foo_dec = [dec(\"foo\", \"get foo\")], _b = (_bar_dec = [dec(bar, \"get [bar]\")], bar))]() {\n        return this.bar;\n      }\n      get [_a = (_baz_dec = [dec(baz, \"get \")], baz)]() {\n        return this.bar;\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 2, \"foo\", _foo_dec, Foo2);\n    __decorateElement(_init, 2, _b, _bar_dec, Foo2);\n    __decorateElement(_init, 2, _a, _baz_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => new Foo2().foo, 123);\n    assertEq(() => new Foo2()[bar], 123);\n    assertEq(() => new Foo2()[baz], 123);\n  },\n  \"Getter decorators: Basic (static getter)\": () => {\n    var _baz_dec, _a, _bar_dec, _b, _foo_dec, _init;\n    const dec = (key, name) => (fn, ctx) => {\n      assertEq(() => typeof fn, \"function\");\n      assertEq(() => fn.name, name);\n      assertEq(() => ctx.kind, \"getter\");\n      assertEq(() => ctx.name, key);\n      assertEq(() => ctx.static, true);\n      assertEq(() => ctx.private, false);\n      assertEq(() => ctx.access.has({ [key]: false }), true);\n      assertEq(() => ctx.access.has({ bar: true }), false);\n      assertEq(() => ctx.access.get({ [key]: 123 }), 123);\n      assertEq(() => \"set\" in ctx.access, false);\n    };\n    const bar = /* @__PURE__ */ Symbol(\"bar\");\n    const baz = /* @__PURE__ */ Symbol();\n    class Foo2 {\n      static get foo() {\n        return this.bar;\n      }\n      static get [(_foo_dec = [dec(\"foo\", \"get foo\")], _b = (_bar_dec = [dec(bar, \"get [bar]\")], bar))]() {\n        return this.bar;\n      }\n      static get [_a = (_baz_dec = [dec(baz, \"get \")], baz)]() {\n        return this.bar;\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 10, \"foo\", _foo_dec, Foo2);\n    __decorateElement(_init, 10, _b, _bar_dec, Foo2);\n    __decorateElement(_init, 10, _a, _baz_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    __publicField(Foo2, \"bar\", 123);\n    assertEq(() => Foo2.foo, 123);\n    assertEq(() => Foo2[bar], 123);\n    assertEq(() => Foo2[baz], 123);\n  },\n  \"Getter decorators: Basic (private instance getter)\": () => {\n    var _foo_dec, _bar, _init, _Foo_instances, foo_get;\n    let lateAsserts;\n    const dec = (fn, ctx) => {\n      assertEq(() => typeof fn, \"function\");\n      assertEq(() => fn.name, \"get #foo\");\n      assertEq(() => ctx.kind, \"getter\");\n      assertEq(() => ctx.name, \"#foo\");\n      assertEq(() => ctx.static, false);\n      assertEq(() => ctx.private, true);\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(new Foo2()), true);\n        assertEq(() => ctx.access.has({}), false);\n        assertEq(() => ctx.access.get(new Foo2()), 123);\n        assertEq(() => \"set\" in ctx.access, false);\n      };\n    };\n    let get$foo;\n    _foo_dec = [dec];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __privateAdd(this, _Foo_instances);\n        __privateAdd(this, _bar, 123);\n      }\n    }\n    _init = __decoratorStart(null);\n    _bar = new WeakMap();\n    _Foo_instances = new WeakSet();\n    foo_get = function() {\n      return __privateGet(this, _bar);\n    };\n    foo_get = __decorateElement(_init, 18, \"#foo\", _foo_dec, _Foo_instances, foo_get);\n    __decoratorMetadata(_init, Foo2);\n    get$foo = (x) => __privateGet(x, _Foo_instances, foo_get);\n    assertEq(() => get$foo(new Foo2()), 123);\n    lateAsserts();\n  },\n  \"Getter decorators: Basic (private static getter)\": () => {\n    var _foo_dec, _bar, _init, _Foo_static, foo_get;\n    let lateAsserts;\n    const dec = (fn, ctx) => {\n      assertEq(() => typeof fn, \"function\");\n      assertEq(() => fn.name, \"get #foo\");\n      assertEq(() => ctx.kind, \"getter\");\n      assertEq(() => ctx.name, \"#foo\");\n      assertEq(() => ctx.static, true);\n      assertEq(() => ctx.private, true);\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(Foo2), true);\n        assertEq(() => ctx.access.has({}), false);\n        assertEq(() => ctx.access.get(Foo2), 123);\n        assertEq(() => \"set\" in ctx.access, false);\n      };\n    };\n    let get$foo;\n    _foo_dec = [dec];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _bar = new WeakMap();\n    _Foo_static = new WeakSet();\n    foo_get = function() {\n      return __privateGet(this, _bar);\n    };\n    foo_get = __decorateElement(_init, 26, \"#foo\", _foo_dec, _Foo_static, foo_get);\n    __privateAdd(Foo2, _Foo_static);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    __privateAdd(Foo2, _bar, 123);\n    get$foo = (x) => __privateGet(x, _Foo_static, foo_get);\n    assertEq(() => get$foo(Foo2), 123);\n    lateAsserts();\n  },\n  \"Getter decorators: Shim (instance getter)\": () => {\n    var _foo_dec, _init;\n    let bar;\n    const dec = (fn, ctx) => {\n      bar = function() {\n        return fn.call(this) + 1;\n      };\n      return bar;\n    };\n    _foo_dec = [dec];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __publicField(this, \"bar\", 123);\n      }\n      get foo() {\n        return this.bar;\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 2, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo2.prototype, \"foo\").get, bar);\n    assertEq(() => new Foo2().foo, 124);\n  },\n  \"Getter decorators: Shim (static getter)\": () => {\n    var _foo_dec, _init;\n    let bar;\n    const dec = (fn, ctx) => {\n      bar = function() {\n        return fn.call(this) + 1;\n      };\n      return bar;\n    };\n    _foo_dec = [dec];\n    class Foo2 {\n      static get foo() {\n        return this.bar;\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 10, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    __publicField(Foo2, \"bar\", 123);\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo2, \"foo\").get, bar);\n    assertEq(() => Foo2.foo, 124);\n  },\n  \"Getter decorators: Shim (private instance getter)\": () => {\n    var _foo_dec, _bar, _init, _Foo_instances, foo_get;\n    let bar;\n    const dec = (fn, ctx) => {\n      bar = function() {\n        return fn.call(this) + 1;\n      };\n      return bar;\n    };\n    let get$foo;\n    _foo_dec = [dec];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __privateAdd(this, _Foo_instances);\n        __privateAdd(this, _bar, 123);\n      }\n    }\n    _init = __decoratorStart(null);\n    _bar = new WeakMap();\n    _Foo_instances = new WeakSet();\n    foo_get = function() {\n      return __privateGet(this, _bar);\n    };\n    foo_get = __decorateElement(_init, 18, \"#foo\", _foo_dec, _Foo_instances, foo_get);\n    __decoratorMetadata(_init, Foo2);\n    get$foo = (x) => __privateGet(x, _Foo_instances, foo_get);\n    assertEq(() => get$foo(new Foo2()), 124);\n  },\n  \"Getter decorators: Shim (private static getter)\": () => {\n    var _foo_dec, _bar, _init, _Foo_static, foo_get;\n    let bar;\n    const dec = (fn, ctx) => {\n      bar = function() {\n        return fn.call(this) + 1;\n      };\n      return bar;\n    };\n    let get$foo;\n    _foo_dec = [dec];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _bar = new WeakMap();\n    _Foo_static = new WeakSet();\n    foo_get = function() {\n      return __privateGet(this, _bar);\n    };\n    foo_get = __decorateElement(_init, 26, \"#foo\", _foo_dec, _Foo_static, foo_get);\n    __privateAdd(Foo2, _Foo_static);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    __privateAdd(Foo2, _bar, 123);\n    get$foo = (x) => __privateGet(x, _Foo_static, foo_get);\n    assertEq(() => get$foo(Foo2), 124);\n  },\n  \"Getter decorators: Order (instance getter)\": () => {\n    var _foo_dec, _init;\n    const log = [];\n    let bar;\n    let baz;\n    const dec1 = (fn, ctx) => {\n      log.push(2);\n      bar = function() {\n        log.push(4);\n        return fn.call(this);\n      };\n      return bar;\n    };\n    const dec2 = (fn, ctx) => {\n      log.push(1);\n      baz = function() {\n        log.push(5);\n        return fn.call(this);\n      };\n      return baz;\n    };\n    log.push(0);\n    _foo_dec = [dec1, dec2];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n      }\n      get foo() {\n        return log.push(6);\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 2, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    log.push(3);\n    new Foo2().foo;\n    log.push(7);\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo2.prototype, \"foo\").get, bar);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5,6,7\");\n  },\n  \"Getter decorators: Order (static getter)\": () => {\n    var _foo_dec, _init;\n    const log = [];\n    let bar;\n    let baz;\n    const dec1 = (fn, ctx) => {\n      log.push(2);\n      bar = function() {\n        log.push(4);\n        return fn.call(this);\n      };\n      return bar;\n    };\n    const dec2 = (fn, ctx) => {\n      log.push(1);\n      baz = function() {\n        log.push(5);\n        return fn.call(this);\n      };\n      return baz;\n    };\n    log.push(0);\n    _foo_dec = [dec1, dec2];\n    class Foo2 {\n      static get foo() {\n        return log.push(6);\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 10, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    log.push(3);\n    Foo2.foo;\n    log.push(7);\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo2, \"foo\").get, bar);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5,6,7\");\n  },\n  \"Getter decorators: Order (private instance getter)\": () => {\n    var _foo_dec, _init, _Foo_instances, foo_get;\n    const log = [];\n    let bar;\n    let baz;\n    const dec1 = (fn, ctx) => {\n      log.push(2);\n      bar = function() {\n        log.push(4);\n        return fn.call(this);\n      };\n      return bar;\n    };\n    const dec2 = (fn, ctx) => {\n      log.push(1);\n      baz = function() {\n        log.push(5);\n        return fn.call(this);\n      };\n      return baz;\n    };\n    log.push(0);\n    let get$foo;\n    _foo_dec = [dec1, dec2];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __privateAdd(this, _Foo_instances);\n      }\n    }\n    _init = __decoratorStart(null);\n    _Foo_instances = new WeakSet();\n    foo_get = function() {\n      return log.push(6);\n    };\n    foo_get = __decorateElement(_init, 18, \"#foo\", _foo_dec, _Foo_instances, foo_get);\n    __decoratorMetadata(_init, Foo2);\n    get$foo = (x) => __privateGet(x, _Foo_instances, foo_get);\n    log.push(3);\n    assertEq(() => get$foo(new Foo2()), 7);\n    log.push(7);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5,6,7\");\n  },\n  \"Getter decorators: Order (private static getter)\": () => {\n    var _foo_dec, _init, _Foo_static, foo_get;\n    const log = [];\n    let bar;\n    let baz;\n    const dec1 = (fn, ctx) => {\n      log.push(2);\n      bar = function() {\n        log.push(4);\n        return fn.call(this);\n      };\n      return bar;\n    };\n    const dec2 = (fn, ctx) => {\n      log.push(1);\n      baz = function() {\n        log.push(5);\n        return fn.call(this);\n      };\n      return baz;\n    };\n    log.push(0);\n    let get$foo;\n    _foo_dec = [dec1, dec2];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _Foo_static = new WeakSet();\n    foo_get = function() {\n      return log.push(6);\n    };\n    foo_get = __decorateElement(_init, 26, \"#foo\", _foo_dec, _Foo_static, foo_get);\n    __privateAdd(Foo2, _Foo_static);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    get$foo = (x) => __privateGet(x, _Foo_static, foo_get);\n    log.push(3);\n    assertEq(() => get$foo(Foo2), 7);\n    log.push(7);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5,6,7\");\n  },\n  \"Getter decorators: Return null (instance getter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (fn, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __runInitializers(_init, 5, this);\n        }\n        get foo() {\n          return;\n        }\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 2, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Getter decorators: Return null (static getter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (fn, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        static get foo() {\n          return;\n        }\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 10, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n      __runInitializers(_init, 3, Foo2);\n    }, TypeError);\n  },\n  \"Getter decorators: Return null (private instance getter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _Foo_instances, foo_get;\n      const dec = (fn, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __runInitializers(_init, 5, this);\n          __privateAdd(this, _Foo_instances);\n        }\n      }\n      _init = __decoratorStart(null);\n      _Foo_instances = new WeakSet();\n      foo_get = function() {\n        return;\n      };\n      foo_get = __decorateElement(_init, 18, \"#foo\", _foo_dec, _Foo_instances, foo_get);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Getter decorators: Return null (private static getter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _Foo_static, foo_get;\n      const dec = (fn, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n      }\n      _init = __decoratorStart(null);\n      _Foo_static = new WeakSet();\n      foo_get = function() {\n        return;\n      };\n      foo_get = __decorateElement(_init, 26, \"#foo\", _foo_dec, _Foo_static, foo_get);\n      __privateAdd(Foo2, _Foo_static);\n      __decoratorMetadata(_init, Foo2);\n      __runInitializers(_init, 3, Foo2);\n    }, TypeError);\n  },\n  \"Getter decorators: Return object (instance getter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (fn, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __runInitializers(_init, 5, this);\n        }\n        get foo() {\n          return;\n        }\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 2, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Getter decorators: Return object (static getter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (fn, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        static get foo() {\n          return;\n        }\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 10, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n      __runInitializers(_init, 3, Foo2);\n    }, TypeError);\n  },\n  \"Getter decorators: Return object (private instance getter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _Foo_instances, foo_get;\n      const dec = (fn, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __runInitializers(_init, 5, this);\n          __privateAdd(this, _Foo_instances);\n        }\n      }\n      _init = __decoratorStart(null);\n      _Foo_instances = new WeakSet();\n      foo_get = function() {\n        return;\n      };\n      foo_get = __decorateElement(_init, 18, \"#foo\", _foo_dec, _Foo_instances, foo_get);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Getter decorators: Return object (private static getter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _Foo_static, foo_get;\n      const dec = (fn, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n      }\n      _init = __decoratorStart(null);\n      _Foo_static = new WeakSet();\n      foo_get = function() {\n        return;\n      };\n      foo_get = __decorateElement(_init, 26, \"#foo\", _foo_dec, _Foo_static, foo_get);\n      __privateAdd(Foo2, _Foo_static);\n      __decoratorMetadata(_init, Foo2);\n      __runInitializers(_init, 3, Foo2);\n    }, TypeError);\n  },\n  \"Getter decorators: Extra initializer (instance getter)\": () => {\n    var _foo_dec, _init;\n    let oldAddInitializer;\n    let got;\n    const dec = (fn, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n      }\n      get foo() {\n        return;\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 2, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => got, void 0);\n    const instance = new Foo2();\n    assertEq(() => got.this, instance);\n    assertEq(() => got.args.length, 0);\n  },\n  \"Getter decorators: Extra initializer (static getter)\": () => {\n    var _foo_dec, _init;\n    let oldAddInitializer;\n    let got;\n    const dec = (fn, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n      static get foo() {\n        return;\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 10, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    assertEq(() => got.this, Foo2);\n    assertEq(() => got.args.length, 0);\n  },\n  \"Getter decorators: Extra initializer (private instance getter)\": () => {\n    var _foo_dec, _init, _Foo_instances, foo_get;\n    let oldAddInitializer;\n    let got;\n    const dec = (fn, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __privateAdd(this, _Foo_instances);\n      }\n    }\n    _init = __decoratorStart(null);\n    _Foo_instances = new WeakSet();\n    foo_get = function() {\n      return;\n    };\n    foo_get = __decorateElement(_init, 18, \"#foo\", _foo_dec, _Foo_instances, foo_get);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => got, void 0);\n    const instance = new Foo2();\n    assertEq(() => got.this, instance);\n    assertEq(() => got.args.length, 0);\n  },\n  \"Getter decorators: Extra initializer (private static getter)\": () => {\n    var _foo_dec, _init, _Foo_static, foo_get;\n    let oldAddInitializer;\n    let got;\n    const dec = (fn, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _Foo_static = new WeakSet();\n    foo_get = function() {\n      return;\n    };\n    foo_get = __decorateElement(_init, 26, \"#foo\", _foo_dec, _Foo_static, foo_get);\n    __privateAdd(Foo2, _Foo_static);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    assertEq(() => got.this, Foo2);\n    assertEq(() => got.args.length, 0);\n  },\n  // Setter decorators\n  \"Setter decorators: Basic (instance setter)\": () => {\n    var _baz_dec, _a, _bar_dec, _b, _foo_dec, _init;\n    const dec = (key, name) => (fn, ctx) => {\n      assertEq(() => typeof fn, \"function\");\n      assertEq(() => fn.name, name);\n      assertEq(() => ctx.kind, \"setter\");\n      assertEq(() => ctx.name, key);\n      assertEq(() => ctx.static, false);\n      assertEq(() => ctx.private, false);\n      assertEq(() => ctx.access.has({ [key]: false }), true);\n      assertEq(() => ctx.access.has({ bar: true }), false);\n      assertEq(() => \"get\" in ctx.access, false);\n      const obj2 = {};\n      ctx.access.set(obj2, 123);\n      assertEq(() => obj2[key], 123);\n      assertEq(() => \"bar\" in obj2, false);\n    };\n    const bar = /* @__PURE__ */ Symbol(\"bar\");\n    const baz = /* @__PURE__ */ Symbol();\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __publicField(this, \"bar\", 0);\n      }\n      set foo(x) {\n        this.bar = x;\n      }\n      set [(_foo_dec = [dec(\"foo\", \"set foo\")], _b = (_bar_dec = [dec(bar, \"set [bar]\")], bar))](x) {\n        this.bar = x;\n      }\n      set [_a = (_baz_dec = [dec(baz, \"set \")], baz)](x) {\n        this.bar = x;\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 3, \"foo\", _foo_dec, Foo2);\n    __decorateElement(_init, 3, _b, _bar_dec, Foo2);\n    __decorateElement(_init, 3, _a, _baz_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    var obj = new Foo2();\n    obj.foo = 321;\n    assertEq(() => obj.bar, 321);\n    obj[bar] = 4321;\n    assertEq(() => obj.bar, 4321);\n    obj[baz] = 54321;\n    assertEq(() => obj.bar, 54321);\n  },\n  \"Setter decorators: Basic (static setter)\": () => {\n    var _baz_dec, _a, _bar_dec, _b, _foo_dec, _init;\n    const dec = (key, name) => (fn, ctx) => {\n      assertEq(() => typeof fn, \"function\");\n      assertEq(() => fn.name, name);\n      assertEq(() => ctx.kind, \"setter\");\n      assertEq(() => ctx.name, key);\n      assertEq(() => ctx.static, true);\n      assertEq(() => ctx.private, false);\n      assertEq(() => ctx.access.has({ [key]: false }), true);\n      assertEq(() => ctx.access.has({ bar: true }), false);\n      assertEq(() => \"get\" in ctx.access, false);\n      const obj = {};\n      ctx.access.set(obj, 123);\n      assertEq(() => obj[key], 123);\n      assertEq(() => \"bar\" in obj, false);\n    };\n    const bar = /* @__PURE__ */ Symbol(\"bar\");\n    const baz = /* @__PURE__ */ Symbol();\n    class Foo2 {\n      static set foo(x) {\n        this.bar = x;\n      }\n      static set [(_foo_dec = [dec(\"foo\", \"set foo\")], _b = (_bar_dec = [dec(bar, \"set [bar]\")], bar))](x) {\n        this.bar = x;\n      }\n      static set [_a = (_baz_dec = [dec(baz, \"set \")], baz)](x) {\n        this.bar = x;\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 11, \"foo\", _foo_dec, Foo2);\n    __decorateElement(_init, 11, _b, _bar_dec, Foo2);\n    __decorateElement(_init, 11, _a, _baz_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    __publicField(Foo2, \"bar\", 0);\n    Foo2.foo = 321;\n    assertEq(() => Foo2.bar, 321);\n    Foo2[bar] = 4321;\n    assertEq(() => Foo2.bar, 4321);\n    Foo2[baz] = 54321;\n    assertEq(() => Foo2.bar, 54321);\n  },\n  \"Setter decorators: Basic (private instance setter)\": () => {\n    var _foo_dec, _init, _Foo_instances, foo_set;\n    let lateAsserts;\n    const dec = (fn, ctx) => {\n      assertEq(() => typeof fn, \"function\");\n      assertEq(() => fn.name, \"set #foo\");\n      assertEq(() => ctx.kind, \"setter\");\n      assertEq(() => ctx.name, \"#foo\");\n      assertEq(() => ctx.static, false);\n      assertEq(() => ctx.private, true);\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(new Foo2()), true);\n        assertEq(() => ctx.access.has({}), false);\n        assertEq(() => \"get\" in ctx.access, false);\n        assertEq(() => {\n          const obj2 = new Foo2();\n          ctx.access.set(obj2, 123);\n          return obj2.bar;\n        }, 123);\n      };\n    };\n    let set$foo;\n    _foo_dec = [dec];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __privateAdd(this, _Foo_instances);\n        __publicField(this, \"bar\", 0);\n      }\n    }\n    _init = __decoratorStart(null);\n    _Foo_instances = new WeakSet();\n    foo_set = function(x) {\n      this.bar = x;\n    };\n    foo_set = __decorateElement(_init, 19, \"#foo\", _foo_dec, _Foo_instances, foo_set);\n    __decoratorMetadata(_init, Foo2);\n    set$foo = (x, y) => {\n      __privateSet(x, _Foo_instances, y, foo_set);\n    };\n    lateAsserts();\n    var obj = new Foo2();\n    assertEq(() => set$foo(obj, 321), void 0);\n    assertEq(() => obj.bar, 321);\n  },\n  \"Setter decorators: Basic (private static setter)\": () => {\n    var _foo_dec, _init, _Foo_static, foo_set;\n    let lateAsserts;\n    const dec = (fn, ctx) => {\n      assertEq(() => typeof fn, \"function\");\n      assertEq(() => fn.name, \"set #foo\");\n      assertEq(() => ctx.kind, \"setter\");\n      assertEq(() => ctx.name, \"#foo\");\n      assertEq(() => ctx.static, true);\n      assertEq(() => ctx.private, true);\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(Foo2), true);\n        assertEq(() => ctx.access.has({}), false);\n        assertEq(() => \"get\" in ctx.access, false);\n        assertEq(() => {\n          ctx.access.set(Foo2, 123);\n          return Foo2.bar;\n        }, 123);\n      };\n    };\n    let set$foo;\n    _foo_dec = [dec];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _Foo_static = new WeakSet();\n    foo_set = function(x) {\n      this.bar = x;\n    };\n    foo_set = __decorateElement(_init, 27, \"#foo\", _foo_dec, _Foo_static, foo_set);\n    __privateAdd(Foo2, _Foo_static);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    __publicField(Foo2, \"bar\", 0);\n    set$foo = (x, y) => {\n      __privateSet(x, _Foo_static, y, foo_set);\n    };\n    lateAsserts();\n    assertEq(() => set$foo(Foo2, 321), void 0);\n    assertEq(() => Foo2.bar, 321);\n  },\n  \"Setter decorators: Shim (instance setter)\": () => {\n    var _foo_dec, _init;\n    let bar;\n    const dec = (fn, ctx) => {\n      bar = function(x) {\n        fn.call(this, x + 1);\n      };\n      return bar;\n    };\n    _foo_dec = [dec];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __publicField(this, \"bar\", 123);\n      }\n      set foo(x) {\n        this.bar = x;\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 3, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo2.prototype, \"foo\").set, bar);\n    var obj = new Foo2();\n    obj.foo = 321;\n    assertEq(() => obj.bar, 322);\n  },\n  \"Setter decorators: Shim (static setter)\": () => {\n    var _foo_dec, _init;\n    let bar;\n    const dec = (fn, ctx) => {\n      bar = function(x) {\n        fn.call(this, x + 1);\n      };\n      return bar;\n    };\n    _foo_dec = [dec];\n    class Foo2 {\n      static set foo(x) {\n        this.bar = x;\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 11, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    __publicField(Foo2, \"bar\", 123);\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo2, \"foo\").set, bar);\n    Foo2.foo = 321;\n    assertEq(() => Foo2.bar, 322);\n  },\n  \"Setter decorators: Shim (private instance setter)\": () => {\n    var _foo_dec, _init, _Foo_instances, foo_set;\n    let bar;\n    const dec = (fn, ctx) => {\n      bar = function(x) {\n        fn.call(this, x + 1);\n      };\n      return bar;\n    };\n    let set$foo;\n    _foo_dec = [dec];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __privateAdd(this, _Foo_instances);\n        __publicField(this, \"bar\", 123);\n      }\n    }\n    _init = __decoratorStart(null);\n    _Foo_instances = new WeakSet();\n    foo_set = function(x) {\n      this.bar = x;\n    };\n    foo_set = __decorateElement(_init, 19, \"#foo\", _foo_dec, _Foo_instances, foo_set);\n    __decoratorMetadata(_init, Foo2);\n    set$foo = (x, y) => {\n      __privateSet(x, _Foo_instances, y, foo_set);\n    };\n    var obj = new Foo2();\n    assertEq(() => set$foo(obj, 321), void 0);\n    assertEq(() => obj.bar, 322);\n  },\n  \"Setter decorators: Shim (private static setter)\": () => {\n    var _foo_dec, _init, _Foo_static, foo_set;\n    let bar;\n    const dec = (fn, ctx) => {\n      bar = function(x) {\n        fn.call(this, x + 1);\n      };\n      return bar;\n    };\n    let set$foo;\n    _foo_dec = [dec];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _Foo_static = new WeakSet();\n    foo_set = function(x) {\n      this.bar = x;\n    };\n    foo_set = __decorateElement(_init, 27, \"#foo\", _foo_dec, _Foo_static, foo_set);\n    __privateAdd(Foo2, _Foo_static);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    __publicField(Foo2, \"bar\", 123);\n    set$foo = (x, y) => {\n      __privateSet(x, _Foo_static, y, foo_set);\n    };\n    assertEq(() => set$foo(Foo2, 321), void 0);\n    assertEq(() => Foo2.bar, 322);\n  },\n  \"Setter decorators: Order (instance setter)\": () => {\n    var _foo_dec, _init;\n    const log = [];\n    let bar;\n    let baz;\n    const dec1 = (fn, ctx) => {\n      log.push(2);\n      bar = function(x) {\n        log.push(4);\n        fn.call(this, x);\n      };\n      return bar;\n    };\n    const dec2 = (fn, ctx) => {\n      log.push(1);\n      baz = function(x) {\n        log.push(5);\n        fn.call(this, x);\n      };\n      return baz;\n    };\n    log.push(0);\n    _foo_dec = [dec1, dec2];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n      }\n      set foo(x) {\n        log.push(6);\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 3, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    log.push(3);\n    new Foo2().foo = 123;\n    log.push(7);\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo2.prototype, \"foo\").set, bar);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5,6,7\");\n  },\n  \"Setter decorators: Order (static setter)\": () => {\n    var _foo_dec, _init;\n    const log = [];\n    let bar;\n    let baz;\n    const dec1 = (fn, ctx) => {\n      log.push(2);\n      bar = function(x) {\n        log.push(4);\n        fn.call(this, x);\n      };\n      return bar;\n    };\n    const dec2 = (fn, ctx) => {\n      log.push(1);\n      baz = function(x) {\n        log.push(5);\n        fn.call(this, x);\n      };\n      return baz;\n    };\n    log.push(0);\n    _foo_dec = [dec1, dec2];\n    class Foo2 {\n      static set foo(x) {\n        log.push(6);\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 11, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    log.push(3);\n    Foo2.foo = 123;\n    log.push(7);\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo2, \"foo\").set, bar);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5,6,7\");\n  },\n  \"Setter decorators: Order (private instance setter)\": () => {\n    var _foo_dec, _init, _Foo_instances, foo_set;\n    const log = [];\n    let bar;\n    let baz;\n    const dec1 = (fn, ctx) => {\n      log.push(2);\n      bar = function(x) {\n        log.push(4);\n        fn.call(this, x);\n      };\n      return bar;\n    };\n    const dec2 = (fn, ctx) => {\n      log.push(1);\n      baz = function(x) {\n        log.push(5);\n        fn.call(this, x);\n      };\n      return baz;\n    };\n    log.push(0);\n    let set$foo;\n    _foo_dec = [dec1, dec2];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __privateAdd(this, _Foo_instances);\n      }\n    }\n    _init = __decoratorStart(null);\n    _Foo_instances = new WeakSet();\n    foo_set = function(x) {\n      log.push(6);\n    };\n    foo_set = __decorateElement(_init, 19, \"#foo\", _foo_dec, _Foo_instances, foo_set);\n    __decoratorMetadata(_init, Foo2);\n    set$foo = (x, y) => {\n      __privateSet(x, _Foo_instances, y, foo_set);\n    };\n    log.push(3);\n    assertEq(() => set$foo(new Foo2(), 123), void 0);\n    log.push(7);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5,6,7\");\n  },\n  \"Setter decorators: Order (private static setter)\": () => {\n    var _foo_dec, _init, _Foo_static, foo_set;\n    const log = [];\n    let bar;\n    let baz;\n    const dec1 = (fn, ctx) => {\n      log.push(2);\n      bar = function(x) {\n        log.push(4);\n        fn.call(this, x);\n      };\n      return bar;\n    };\n    const dec2 = (fn, ctx) => {\n      log.push(1);\n      baz = function(x) {\n        log.push(5);\n        fn.call(this, x);\n      };\n      return baz;\n    };\n    log.push(0);\n    let set$foo;\n    _foo_dec = [dec1, dec2];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _Foo_static = new WeakSet();\n    foo_set = function(x) {\n      log.push(6);\n    };\n    foo_set = __decorateElement(_init, 27, \"#foo\", _foo_dec, _Foo_static, foo_set);\n    __privateAdd(Foo2, _Foo_static);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    set$foo = (x, y) => {\n      __privateSet(x, _Foo_static, y, foo_set);\n    };\n    log.push(3);\n    assertEq(() => set$foo(Foo2, 123), void 0);\n    log.push(7);\n    assertEq(() => log + \"\", \"0,1,2,3,4,5,6,7\");\n  },\n  \"Setter decorators: Return null (instance setter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (fn, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __runInitializers(_init, 5, this);\n        }\n        set foo(x) {\n        }\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 3, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Setter decorators: Return null (static setter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (fn, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        static set foo(x) {\n        }\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 11, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n      __runInitializers(_init, 3, Foo2);\n    }, TypeError);\n  },\n  \"Setter decorators: Return null (private instance setter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _Foo_instances, foo_set;\n      const dec = (fn, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __runInitializers(_init, 5, this);\n          __privateAdd(this, _Foo_instances);\n        }\n      }\n      _init = __decoratorStart(null);\n      _Foo_instances = new WeakSet();\n      foo_set = function(x) {\n      };\n      foo_set = __decorateElement(_init, 19, \"#foo\", _foo_dec, _Foo_instances, foo_set);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Setter decorators: Return null (private static setter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _Foo_static, foo_set;\n      const dec = (fn, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n      }\n      _init = __decoratorStart(null);\n      _Foo_static = new WeakSet();\n      foo_set = function(x) {\n      };\n      foo_set = __decorateElement(_init, 27, \"#foo\", _foo_dec, _Foo_static, foo_set);\n      __privateAdd(Foo2, _Foo_static);\n      __decoratorMetadata(_init, Foo2);\n      __runInitializers(_init, 3, Foo2);\n    }, TypeError);\n  },\n  \"Setter decorators: Return object (instance setter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (fn, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __runInitializers(_init, 5, this);\n        }\n        set foo(x) {\n        }\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 3, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Setter decorators: Return object (static setter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init;\n      const dec = (fn, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        static set foo(x) {\n        }\n      }\n      _init = __decoratorStart(null);\n      __decorateElement(_init, 11, \"foo\", _foo_dec, Foo2);\n      __decoratorMetadata(_init, Foo2);\n      __runInitializers(_init, 3, Foo2);\n    }, TypeError);\n  },\n  \"Setter decorators: Return object (private instance setter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _Foo_instances, foo_set;\n      const dec = (fn, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __runInitializers(_init, 5, this);\n          __privateAdd(this, _Foo_instances);\n        }\n      }\n      _init = __decoratorStart(null);\n      _Foo_instances = new WeakSet();\n      foo_set = function(x) {\n      };\n      foo_set = __decorateElement(_init, 19, \"#foo\", _foo_dec, _Foo_instances, foo_set);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Setter decorators: Return object (private static setter)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _Foo_static, foo_set;\n      const dec = (fn, ctx) => {\n        return {};\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n      }\n      _init = __decoratorStart(null);\n      _Foo_static = new WeakSet();\n      foo_set = function(x) {\n      };\n      foo_set = __decorateElement(_init, 27, \"#foo\", _foo_dec, _Foo_static, foo_set);\n      __privateAdd(Foo2, _Foo_static);\n      __decoratorMetadata(_init, Foo2);\n      __runInitializers(_init, 3, Foo2);\n    }, TypeError);\n  },\n  \"Setter decorators: Extra initializer (instance setter)\": () => {\n    var _foo_dec, _init;\n    let oldAddInitializer;\n    let got;\n    const dec = (fn, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n      }\n      set foo(x) {\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 3, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => got, void 0);\n    const instance = new Foo2();\n    assertEq(() => got.this, instance);\n    assertEq(() => got.args.length, 0);\n  },\n  \"Setter decorators: Extra initializer (static setter)\": () => {\n    var _foo_dec, _init;\n    let oldAddInitializer;\n    let got;\n    const dec = (fn, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n      static set foo(x) {\n      }\n    }\n    _init = __decoratorStart(null);\n    __decorateElement(_init, 11, \"foo\", _foo_dec, Foo2);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    assertEq(() => got.this, Foo2);\n    assertEq(() => got.args.length, 0);\n  },\n  \"Setter decorators: Extra initializer (private instance setter)\": () => {\n    var _foo_dec, _init, _Foo_instances, foo_set;\n    let oldAddInitializer;\n    let got;\n    const dec = (fn, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __privateAdd(this, _Foo_instances);\n      }\n    }\n    _init = __decoratorStart(null);\n    _Foo_instances = new WeakSet();\n    foo_set = function(x) {\n    };\n    foo_set = __decorateElement(_init, 19, \"#foo\", _foo_dec, _Foo_instances, foo_set);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => got, void 0);\n    const instance = new Foo2();\n    assertEq(() => got.this, instance);\n    assertEq(() => got.args.length, 0);\n  },\n  \"Setter decorators: Extra initializer (private static setter)\": () => {\n    var _foo_dec, _init, _Foo_static, foo_set;\n    let oldAddInitializer;\n    let got;\n    const dec = (fn, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _Foo_static = new WeakSet();\n    foo_set = function(x) {\n    };\n    foo_set = __decorateElement(_init, 27, \"#foo\", _foo_dec, _Foo_static, foo_set);\n    __privateAdd(Foo2, _Foo_static);\n    __decoratorMetadata(_init, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    assertEq(() => got.this, Foo2);\n    assertEq(() => got.args.length, 0);\n  },\n  // Auto-accessor decorators\n  \"Auto-accessor decorators: Basic (instance auto-accessor)\": () => {\n    var _baz_dec, _a, _bar_dec, _b, _foo_dec, _init, _foo, __b, __a;\n    const dec = (key, getName, setName) => (target, ctx) => {\n      assertEq(() => typeof target.get, \"function\");\n      assertEq(() => typeof target.set, \"function\");\n      assertEq(() => target.get.name, getName);\n      assertEq(() => target.set.name, setName);\n      assertEq(() => ctx.kind, \"accessor\");\n      assertEq(() => ctx.name, key);\n      assertEq(() => ctx.static, false);\n      assertEq(() => ctx.private, false);\n      assertEq(() => ctx.access.has({ [key]: false }), true);\n      assertEq(() => ctx.access.has({ bar: true }), false);\n      assertEq(() => ctx.access.get({ [key]: 123 }), 123);\n      assertEq(() => {\n        const obj2 = {};\n        ctx.access.set(obj2, 123);\n        return obj2[key];\n      }, 123);\n    };\n    const bar = /* @__PURE__ */ Symbol(\"bar\");\n    const baz = /* @__PURE__ */ Symbol();\n    _foo_dec = [dec(\"foo\", \"get foo\", \"set foo\")], _b = (_bar_dec = [dec(bar, \"get [bar]\", \"set [bar]\")], bar), _a = (_baz_dec = [dec(baz, \"get \", \"set \")], baz);\n    class Foo2 {\n      constructor() {\n        __privateAdd(this, _foo, __runInitializers(_init, 8, this, 0)), __runInitializers(_init, 11, this);\n        __privateAdd(this, __b, __runInitializers(_init, 12, this, 0)), __runInitializers(_init, 15, this);\n        __privateAdd(this, __a, __runInitializers(_init, 16, this, 0)), __runInitializers(_init, 19, this);\n      }\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    __b = new WeakMap();\n    __a = new WeakMap();\n    __decorateElement(_init, 4, \"foo\", _foo_dec, Foo2, _foo);\n    __decorateElement(_init, 4, _b, _bar_dec, Foo2, __b);\n    __decorateElement(_init, 4, _a, _baz_dec, Foo2, __a);\n    __decoratorMetadata(_init, Foo2);\n    var obj = new Foo2();\n    obj.foo = 321;\n    assertEq(() => obj.foo, 321);\n    obj[bar] = 4321;\n    assertEq(() => obj[bar], 4321);\n    obj[baz] = 54321;\n    assertEq(() => obj[baz], 54321);\n  },\n  \"Auto-accessor decorators: Basic (static auto-accessor)\": () => {\n    var _baz_dec, _a, _bar_dec, _b, _foo_dec, _init, _foo, __b, __a;\n    const dec = (key, getName, setName) => (target, ctx) => {\n      assertEq(() => typeof target.get, \"function\");\n      assertEq(() => typeof target.set, \"function\");\n      assertEq(() => target.get.name, getName);\n      assertEq(() => target.set.name, setName);\n      assertEq(() => ctx.kind, \"accessor\");\n      assertEq(() => ctx.name, key);\n      assertEq(() => ctx.static, true);\n      assertEq(() => ctx.private, false);\n      assertEq(() => ctx.access.has({ [key]: false }), true);\n      assertEq(() => ctx.access.has({ bar: true }), false);\n      assertEq(() => ctx.access.get({ [key]: 123 }), 123);\n      assertEq(() => {\n        const obj = {};\n        ctx.access.set(obj, 123);\n        return obj[key];\n      }, 123);\n    };\n    const bar = /* @__PURE__ */ Symbol(\"bar\");\n    const baz = /* @__PURE__ */ Symbol();\n    _foo_dec = [dec(\"foo\", \"get foo\", \"set foo\")], _b = (_bar_dec = [dec(bar, \"get [bar]\", \"set [bar]\")], bar), _a = (_baz_dec = [dec(baz, \"get \", \"set \")], baz);\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    __b = new WeakMap();\n    __a = new WeakMap();\n    __decorateElement(_init, 12, \"foo\", _foo_dec, Foo2, _foo);\n    __decorateElement(_init, 12, _b, _bar_dec, Foo2, __b);\n    __decorateElement(_init, 12, _a, _baz_dec, Foo2, __a);\n    __decoratorMetadata(_init, Foo2);\n    __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2, 0)), __runInitializers(_init, 11, Foo2);\n    __privateAdd(Foo2, __b, __runInitializers(_init, 12, Foo2, 0)), __runInitializers(_init, 15, Foo2);\n    __privateAdd(Foo2, __a, __runInitializers(_init, 16, Foo2, 0)), __runInitializers(_init, 19, Foo2);\n    Foo2.foo = 321;\n    assertEq(() => Foo2.foo, 321);\n    Foo2[bar] = 4321;\n    assertEq(() => Foo2[bar], 4321);\n    Foo2[baz] = 54321;\n    assertEq(() => Foo2[baz], 54321);\n  },\n  \"Auto-accessor decorators: Basic (private instance auto-accessor)\": () => {\n    var _foo_dec, _init, _foo, _a, foo_get, foo_set, _Foo_instances;\n    let lateAsserts;\n    const dec = (target, ctx) => {\n      assertEq(() => typeof target.get, \"function\");\n      assertEq(() => typeof target.set, \"function\");\n      assertEq(() => target.get.name, \"get #foo\");\n      assertEq(() => target.set.name, \"set #foo\");\n      assertEq(() => ctx.kind, \"accessor\");\n      assertEq(() => ctx.name, \"#foo\");\n      assertEq(() => ctx.static, false);\n      assertEq(() => ctx.private, true);\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(new Foo2()), true);\n        assertEq(() => ctx.access.has({}), false);\n        assertEq(() => ctx.access.get(new Foo2()), 0);\n        assertEq(() => {\n          const obj2 = new Foo2();\n          ctx.access.set(obj2, 123);\n          return get$foo(obj2);\n        }, 123);\n      };\n    };\n    let get$foo;\n    let set$foo;\n    _foo_dec = [dec];\n    class Foo2 {\n      constructor() {\n        __privateAdd(this, _Foo_instances);\n        __privateAdd(this, _foo, __runInitializers(_init, 8, this, 0)), __runInitializers(_init, 11, this);\n      }\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    _Foo_instances = new WeakSet();\n    _a = __decorateElement(_init, 20, \"#foo\", _foo_dec, _Foo_instances, _foo), foo_get = _a.get, foo_set = _a.set;\n    __decoratorMetadata(_init, Foo2);\n    get$foo = (x) => __privateGet(x, _Foo_instances, foo_get);\n    set$foo = (x, y) => {\n      __privateSet(x, _Foo_instances, y, foo_set);\n    };\n    lateAsserts();\n    var obj = new Foo2();\n    assertEq(() => set$foo(obj, 321), void 0);\n    assertEq(() => get$foo(obj), 321);\n  },\n  \"Auto-accessor decorators: Basic (private static auto-accessor)\": () => {\n    var _foo_dec, _init, _foo, _a, foo_get, foo_set, _Foo_static;\n    let lateAsserts;\n    const dec = (target, ctx) => {\n      assertEq(() => typeof target.get, \"function\");\n      assertEq(() => typeof target.set, \"function\");\n      assertEq(() => target.get.name, \"get #foo\");\n      assertEq(() => target.set.name, \"set #foo\");\n      assertEq(() => ctx.kind, \"accessor\");\n      assertEq(() => ctx.name, \"#foo\");\n      assertEq(() => ctx.static, true);\n      assertEq(() => ctx.private, true);\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(Foo2), true);\n        assertEq(() => ctx.access.has({}), false);\n        assertEq(() => ctx.access.get(Foo2), 0);\n        assertEq(() => {\n          ctx.access.set(Foo2, 123);\n          return get$foo(Foo2);\n        }, 123);\n      };\n    };\n    let get$foo;\n    let set$foo;\n    _foo_dec = [dec];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    _Foo_static = new WeakSet();\n    _a = __decorateElement(_init, 28, \"#foo\", _foo_dec, _Foo_static, _foo), foo_get = _a.get, foo_set = _a.set;\n    __privateAdd(Foo2, _Foo_static);\n    __decoratorMetadata(_init, Foo2);\n    __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2, 0)), __runInitializers(_init, 11, Foo2);\n    get$foo = (x) => __privateGet(x, _Foo_static, foo_get);\n    set$foo = (x, y) => {\n      __privateSet(x, _Foo_static, y, foo_set);\n    };\n    lateAsserts();\n    assertEq(() => set$foo(Foo2, 321), void 0);\n    assertEq(() => get$foo(Foo2), 321);\n  },\n  \"Auto-accessor decorators: Shim (instance auto-accessor)\": () => {\n    var _foo_dec, _init, _foo;\n    let get;\n    let set;\n    const dec = (target, ctx) => {\n      function init(x) {\n        assertEq(() => this instanceof Foo2, true);\n        return x + 1;\n      }\n      get = function() {\n        return target.get.call(this) * 10;\n      };\n      set = function(x) {\n        target.set.call(this, x * 2);\n      };\n      return { get, set, init };\n    };\n    _foo_dec = [dec];\n    class Foo2 {\n      constructor() {\n        __privateAdd(this, _foo, __runInitializers(_init, 8, this, 123)), __runInitializers(_init, 11, this);\n      }\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    __decorateElement(_init, 4, \"foo\", _foo_dec, Foo2, _foo);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo2.prototype, \"foo\").get, get);\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo2.prototype, \"foo\").set, set);\n    var obj = new Foo2();\n    assertEq(() => obj.foo, (123 + 1) * 10);\n    obj.foo = 321;\n    assertEq(() => obj.foo, 321 * 2 * 10);\n  },\n  \"Auto-accessor decorators: Shim (static auto-accessor)\": () => {\n    var _foo_dec, _init, _foo;\n    let foo;\n    let get;\n    let set;\n    const dec = (target, ctx) => {\n      function init(x) {\n        assertEq(() => this, foo);\n        return x + 1;\n      }\n      get = function() {\n        return target.get.call(this) * 10;\n      };\n      set = function(x) {\n        target.set.call(this, x * 2);\n      };\n      return { get, set, init };\n    };\n    _foo_dec = [dec];\n    const _Foo = class _Foo {\n    };\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    __decorateElement(_init, 12, \"foo\", _foo_dec, _Foo, _foo);\n    __decoratorMetadata(_init, _Foo);\n    foo = _Foo;\n    __privateAdd(_Foo, _foo, __runInitializers(_init, 8, _Foo, 123)), __runInitializers(_init, 11, _Foo);\n    let Foo2 = _Foo;\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo2, \"foo\").get, get);\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo2, \"foo\").set, set);\n    assertEq(() => Foo2.foo, (123 + 1) * 10);\n    Foo2.foo = 321;\n    assertEq(() => Foo2.foo, 321 * 2 * 10);\n  },\n  \"Auto-accessor decorators: Shim (private instance auto-accessor)\": () => {\n    var _foo_dec, _init, _foo, _a, foo_get, foo_set, _Foo_instances;\n    let get;\n    let set;\n    const dec = (target, ctx) => {\n      function init(x) {\n        assertEq(() => this instanceof Foo2, true);\n        return x + 1;\n      }\n      get = function() {\n        return target.get.call(this) * 10;\n      };\n      set = function(x) {\n        target.set.call(this, x * 2);\n      };\n      return { get, set, init };\n    };\n    let get$foo;\n    let set$foo;\n    _foo_dec = [dec];\n    class Foo2 {\n      constructor() {\n        __privateAdd(this, _Foo_instances);\n        __privateAdd(this, _foo, __runInitializers(_init, 8, this, 123)), __runInitializers(_init, 11, this);\n      }\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    _Foo_instances = new WeakSet();\n    _a = __decorateElement(_init, 20, \"#foo\", _foo_dec, _Foo_instances, _foo), foo_get = _a.get, foo_set = _a.set;\n    __decoratorMetadata(_init, Foo2);\n    get$foo = (x) => __privateGet(x, _Foo_instances, foo_get);\n    set$foo = (x, y) => {\n      __privateSet(x, _Foo_instances, y, foo_set);\n    };\n    var obj = new Foo2();\n    assertEq(() => get$foo(obj), (123 + 1) * 10);\n    assertEq(() => set$foo(obj, 321), void 0);\n    assertEq(() => get$foo(obj), 321 * 2 * 10);\n  },\n  \"Auto-accessor decorators: Shim (private static auto-accessor)\": () => {\n    var _foo_dec, _init, _foo, _a, foo_get, foo_set, _Foo_static;\n    let foo;\n    let get;\n    let set;\n    const dec = (target, ctx) => {\n      function init(x) {\n        assertEq(() => this, foo);\n        return x + 1;\n      }\n      get = function() {\n        return target.get.call(this) * 10;\n      };\n      set = function(x) {\n        target.set.call(this, x * 2);\n      };\n      return { get, set, init };\n    };\n    let get$foo;\n    let set$foo;\n    _foo_dec = [dec];\n    const _Foo = class _Foo {\n    };\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    _Foo_static = new WeakSet();\n    _a = __decorateElement(_init, 28, \"#foo\", _foo_dec, _Foo_static, _foo), foo_get = _a.get, foo_set = _a.set;\n    __privateAdd(_Foo, _Foo_static);\n    __decoratorMetadata(_init, _Foo);\n    foo = _Foo;\n    get$foo = (x) => __privateGet(x, _Foo_static, foo_get);\n    set$foo = (x, y) => {\n      __privateSet(x, _Foo_static, y, foo_set);\n    };\n    __privateAdd(_Foo, _foo, __runInitializers(_init, 8, _Foo, 123)), __runInitializers(_init, 11, _Foo);\n    let Foo2 = _Foo;\n    assertEq(() => get$foo(Foo2), (123 + 1) * 10);\n    assertEq(() => set$foo(Foo2, 321), void 0);\n    assertEq(() => get$foo(Foo2), 321 * 2 * 10);\n  },\n  \"Auto-accessor decorators: Return null (instance auto-accessor)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _foo;\n      const dec = (target, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __privateAdd(this, _foo, __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);\n        }\n      }\n      _init = __decoratorStart(null);\n      _foo = new WeakMap();\n      __decorateElement(_init, 4, \"foo\", _foo_dec, Foo2, _foo);\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Auto-accessor decorators: Return null (static auto-accessor)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _foo;\n      const dec = (target, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n      }\n      _init = __decoratorStart(null);\n      _foo = new WeakMap();\n      __decorateElement(_init, 12, \"foo\", _foo_dec, Foo2, _foo);\n      __decoratorMetadata(_init, Foo2);\n      __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n    }, TypeError);\n  },\n  \"Auto-accessor decorators: Return null (private instance auto-accessor)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _foo, _a, foo_get, foo_set, _Foo_instances;\n      const dec = (target, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n        constructor() {\n          __privateAdd(this, _Foo_instances);\n          __privateAdd(this, _foo, __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);\n        }\n      }\n      _init = __decoratorStart(null);\n      _foo = new WeakMap();\n      _Foo_instances = new WeakSet();\n      _a = __decorateElement(_init, 20, \"#foo\", _foo_dec, _Foo_instances, _foo), foo_get = _a.get, foo_set = _a.set;\n      __decoratorMetadata(_init, Foo2);\n    }, TypeError);\n  },\n  \"Auto-accessor decorators: Return null (private static auto-accessor)\": () => {\n    assertThrows(() => {\n      var _foo_dec, _init, _foo, _a, foo_get, foo_set, _Foo_static;\n      const dec = (target, ctx) => {\n        return null;\n      };\n      _foo_dec = [dec];\n      class Foo2 {\n      }\n      _init = __decoratorStart(null);\n      _foo = new WeakMap();\n      _Foo_static = new WeakSet();\n      _a = __decorateElement(_init, 28, \"#foo\", _foo_dec, _Foo_static, _foo), foo_get = _a.get, foo_set = _a.set;\n      __privateAdd(Foo2, _Foo_static);\n      __decoratorMetadata(_init, Foo2);\n      __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n    }, TypeError);\n  },\n  \"Auto-accessor decorators: Extra initializer (instance auto-accessor)\": () => {\n    var _foo_dec, _init, _foo;\n    let oldAddInitializer;\n    let got;\n    const dec = (target, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n      constructor() {\n        __privateAdd(this, _foo, __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);\n      }\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    __decorateElement(_init, 4, \"foo\", _foo_dec, Foo2, _foo);\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => got, void 0);\n    const instance = new Foo2();\n    assertEq(() => got.this, instance);\n    assertEq(() => got.args.length, 0);\n  },\n  \"Auto-accessor decorators: Extra initializer (static auto-accessor)\": () => {\n    var _foo_dec, _init, _foo;\n    let oldAddInitializer;\n    let got;\n    const dec = (target, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    __decorateElement(_init, 12, \"foo\", _foo_dec, Foo2, _foo);\n    __decoratorMetadata(_init, Foo2);\n    __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n    assertEq(() => got.this, Foo2);\n    assertEq(() => got.args.length, 0);\n  },\n  \"Auto-accessor decorators: Extra initializer (private instance auto-accessor)\": () => {\n    var _foo_dec, _init, _foo, _a, foo_get, foo_set, _Foo_instances;\n    let oldAddInitializer;\n    let got;\n    const dec = (target, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n      constructor() {\n        __privateAdd(this, _Foo_instances);\n        __privateAdd(this, _foo, __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);\n      }\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    _Foo_instances = new WeakSet();\n    _a = __decorateElement(_init, 20, \"#foo\", _foo_dec, _Foo_instances, _foo), foo_get = _a.get, foo_set = _a.set;\n    __decoratorMetadata(_init, Foo2);\n    assertEq(() => got, void 0);\n    const instance = new Foo2();\n    assertEq(() => got.this, instance);\n    assertEq(() => got.args.length, 0);\n  },\n  \"Auto-accessor decorators: Extra initializer (private static auto-accessor)\": () => {\n    var _foo_dec, _init, _foo, _a, foo_get, foo_set, _Foo_static;\n    let oldAddInitializer;\n    let got;\n    const dec = (target, ctx) => {\n      ctx.addInitializer(function(...args) {\n        got = { this: this, args };\n      });\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer(() => {\n      }), TypeError);\n      assertThrows(() => ctx.addInitializer({}), TypeError);\n      oldAddInitializer = ctx.addInitializer;\n    };\n    _foo_dec = [dec, dec];\n    class Foo2 {\n    }\n    _init = __decoratorStart(null);\n    _foo = new WeakMap();\n    _Foo_static = new WeakSet();\n    _a = __decorateElement(_init, 28, \"#foo\", _foo_dec, _Foo_static, _foo), foo_get = _a.get, foo_set = _a.set;\n    __privateAdd(Foo2, _Foo_static);\n    __decoratorMetadata(_init, Foo2);\n    __privateAdd(Foo2, _foo, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n    assertEq(() => got.this, Foo2);\n    assertEq(() => got.args.length, 0);\n  },\n  // Decorator list evaluation\n  \"Decorator list evaluation: Computed names (class statement)\": () => {\n    var _dec, _a, _dec2, _b, _dec3, _c, _dec4, _d, _dec5, _e, _dec6, _f, _dec7, _g, _dec8, _h, _dec9, _i, _dec10, _j, _Foo_decorators, _init, __b, __a, _k;\n    const log = [];\n    const foo = (n) => {\n      log.push(n);\n      return () => {\n      };\n    };\n    const computed = {\n      get method() {\n        log.push(log.length);\n        return /* @__PURE__ */ Symbol(\"method\");\n      },\n      get field() {\n        log.push(log.length);\n        return /* @__PURE__ */ Symbol(\"field\");\n      },\n      get getter() {\n        log.push(log.length);\n        return /* @__PURE__ */ Symbol(\"getter\");\n      },\n      get setter() {\n        log.push(log.length);\n        return /* @__PURE__ */ Symbol(\"setter\");\n      },\n      get accessor() {\n        log.push(log.length);\n        return /* @__PURE__ */ Symbol(\"accessor\");\n      }\n    };\n    _Foo_decorators = [foo(0)];\n    class Foo2 extends (_k = (foo(1), Object)) {\n      constructor() {\n        super(...arguments);\n        __runInitializers(_init, 5, this);\n        __publicField(this, _h, __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n        __privateAdd(this, __b, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n      }\n      [_j = (_dec10 = [foo(2)], computed.method)]() {\n      }\n      static [_i = (_dec9 = [foo(4)], computed.method)]() {\n      }\n      get [(_h = (_dec8 = [foo(6)], computed.field), _g = (_dec7 = [foo(8)], computed.field), _f = (_dec6 = [foo(10)], computed.getter))]() {\n        return;\n      }\n      static get [_e = (_dec5 = [foo(12)], computed.getter)]() {\n        return;\n      }\n      set [_d = (_dec4 = [foo(14)], computed.setter)](x) {\n      }\n      static set [(_c = (_dec3 = [foo(16)], computed.setter), _b = (_dec2 = [foo(18)], computed.accessor), _a = (_dec = [foo(20)], computed.accessor), _c)](x) {\n      }\n    }\n    _init = __decoratorStart(_k);\n    __b = new WeakMap();\n    __a = new WeakMap();\n    __decorateElement(_init, 9, _i, _dec9, Foo2);\n    __decorateElement(_init, 10, _e, _dec5, Foo2);\n    __decorateElement(_init, 11, _c, _dec3, Foo2);\n    __decorateElement(_init, 12, _a, _dec, Foo2, __a);\n    __decorateElement(_init, 1, _j, _dec10, Foo2);\n    __decorateElement(_init, 2, _f, _dec6, Foo2);\n    __decorateElement(_init, 3, _d, _dec4, Foo2);\n    __decorateElement(_init, 4, _b, _dec2, Foo2, __b);\n    __decorateElement(_init, 13, _g, _dec7, Foo2);\n    __decorateElement(_init, 5, _h, _dec8, Foo2);\n    Foo2 = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    __publicField(Foo2, _g, __runInitializers(_init, 16, Foo2)), __runInitializers(_init, 19, Foo2);\n    __privateAdd(Foo2, __a, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n    __runInitializers(_init, 1, Foo2);\n    assertEq(() => \"\" + log, \"0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21\");\n  },\n  \"Decorator list evaluation: Computed names (class expression)\": () => {\n    var _dec, _a, _dec2, _b, _dec3, _c, _dec4, _d, _dec5, _e, _dec6, _f, _dec7, _g, _dec8, _h, _dec9, _i, _dec10, _j, _class_decorators, _init, _k, __b, __a, _l;\n    const log = [];\n    const foo = (n) => {\n      log.push(n);\n      return () => {\n      };\n    };\n    const computed = {\n      get method() {\n        log.push(log.length);\n        return /* @__PURE__ */ Symbol(\"method\");\n      },\n      get field() {\n        log.push(log.length);\n        return /* @__PURE__ */ Symbol(\"field\");\n      },\n      get getter() {\n        log.push(log.length);\n        return /* @__PURE__ */ Symbol(\"getter\");\n      },\n      get setter() {\n        log.push(log.length);\n        return /* @__PURE__ */ Symbol(\"setter\");\n      },\n      get accessor() {\n        log.push(log.length);\n        return /* @__PURE__ */ Symbol(\"accessor\");\n      }\n    };\n    _class_decorators = [foo(0)], _k = class extends (_l = (foo(1), Object)) {\n      constructor() {\n        super(...arguments);\n        __runInitializers(_init, 5, this);\n        __publicField(this, _h, __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n        __privateAdd(this, __b, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n      }\n      [_j = (_dec10 = [foo(2)], computed.method)]() {\n      }\n      static [_i = (_dec9 = [foo(4)], computed.method)]() {\n      }\n      get [(_h = (_dec8 = [foo(6)], computed.field), _g = (_dec7 = [foo(8)], computed.field), _f = (_dec6 = [foo(10)], computed.getter))]() {\n        return;\n      }\n      static get [_e = (_dec5 = [foo(12)], computed.getter)]() {\n        return;\n      }\n      set [_d = (_dec4 = [foo(14)], computed.setter)](x) {\n      }\n      static set [(_c = (_dec3 = [foo(16)], computed.setter), _b = (_dec2 = [foo(18)], computed.accessor), _a = (_dec = [foo(20)], computed.accessor), _c)](x) {\n      }\n    }, _init = __decoratorStart(_l), __b = new WeakMap(), __a = new WeakMap(), __decorateElement(_init, 9, _i, _dec9, _k), __decorateElement(_init, 10, _e, _dec5, _k), __decorateElement(_init, 11, _c, _dec3, _k), __decorateElement(_init, 12, _a, _dec, _k, __a), __decorateElement(_init, 1, _j, _dec10, _k), __decorateElement(_init, 2, _f, _dec6, _k), __decorateElement(_init, 3, _d, _dec4, _k), __decorateElement(_init, 4, _b, _dec2, _k, __b), __decorateElement(_init, 13, _g, _dec7, _k), __decorateElement(_init, 5, _h, _dec8, _k), _k = __decorateElement(_init, 0, \"\", _class_decorators, _k), __runInitializers(_init, 3, _k), __publicField(_k, _g, __runInitializers(_init, 16, _k)), __runInitializers(_init, 19, _k), __privateAdd(_k, __a, __runInitializers(_init, 8, _k)), __runInitializers(_init, 11, _k), __runInitializers(_init, 1, _k), _k;\n    assertEq(() => \"\" + log, \"0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21\");\n  },\n  'Decorator list evaluation: \"this\" (class statement)': () => {\n    const log = [];\n    const dummy = () => {\n    };\n    const ctx = {\n      foo(n) {\n        log.push(n);\n      }\n    };\n    function wrapper() {\n      var _accessor_dec, _accessor_dec2, _setter_dec, _setter_dec2, _getter_dec, _getter_dec2, _field_dec, _field_dec2, _method_dec, _method_dec2, _a, _Foo_decorators, _init, _accessor, _accessor2;\n      _Foo_decorators = [(assertEq(() => this.foo(0), void 0), dummy)];\n      class Foo2 extends (_a = (assertEq(() => this.foo(1), void 0), Object), _method_dec2 = [(assertEq(() => this.foo(2), void 0), dummy)], _method_dec = [(assertEq(() => this.foo(3), void 0), dummy)], _field_dec2 = [(assertEq(() => this.foo(4), void 0), dummy)], _field_dec = [(assertEq(() => this.foo(5), void 0), dummy)], _getter_dec2 = [(assertEq(() => this.foo(6), void 0), dummy)], _getter_dec = [(assertEq(() => this.foo(7), void 0), dummy)], _setter_dec2 = [(assertEq(() => this.foo(8), void 0), dummy)], _setter_dec = [(assertEq(() => this.foo(9), void 0), dummy)], _accessor_dec2 = [(assertEq(() => this.foo(10), void 0), dummy)], _accessor_dec = [(assertEq(() => this.foo(11), void 0), dummy)], _a) {\n        constructor() {\n          super(...arguments);\n          __runInitializers(_init, 5, this);\n          __publicField(this, \"field\", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n          __privateAdd(this, _accessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n        }\n        method() {\n        }\n        static method() {\n        }\n        get getter() {\n          return;\n        }\n        static get getter() {\n          return;\n        }\n        set setter(x) {\n        }\n        static set setter(x) {\n        }\n      }\n      _init = __decoratorStart(_a);\n      _accessor = new WeakMap();\n      _accessor2 = new WeakMap();\n      __decorateElement(_init, 9, \"method\", _method_dec, Foo2);\n      __decorateElement(_init, 10, \"getter\", _getter_dec, Foo2);\n      __decorateElement(_init, 11, \"setter\", _setter_dec, Foo2);\n      __decorateElement(_init, 12, \"accessor\", _accessor_dec, Foo2, _accessor2);\n      __decorateElement(_init, 1, \"method\", _method_dec2, Foo2);\n      __decorateElement(_init, 2, \"getter\", _getter_dec2, Foo2);\n      __decorateElement(_init, 3, \"setter\", _setter_dec2, Foo2);\n      __decorateElement(_init, 4, \"accessor\", _accessor_dec2, Foo2, _accessor);\n      __decorateElement(_init, 13, \"field\", _field_dec, Foo2);\n      __decorateElement(_init, 5, \"field\", _field_dec2, Foo2);\n      Foo2 = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, Foo2);\n      __runInitializers(_init, 3, Foo2);\n      __publicField(Foo2, \"field\", __runInitializers(_init, 16, Foo2)), __runInitializers(_init, 19, Foo2);\n      __privateAdd(Foo2, _accessor2, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n      __runInitializers(_init, 1, Foo2);\n    }\n    wrapper.call(ctx);\n    assertEq(() => \"\" + log, \"0,1,2,3,4,5,6,7,8,9,10,11\");\n  },\n  'Decorator list evaluation: \"this\" (class expression)': () => {\n    const log = [];\n    const dummy = () => {\n    };\n    const ctx = {\n      foo(n) {\n        log.push(n);\n      }\n    };\n    function wrapper() {\n      var _accessor_dec, _accessor_dec2, _setter_dec, _setter_dec2, _getter_dec, _getter_dec2, _field_dec, _field_dec2, _method_dec, _method_dec2, _a, _class_decorators, _init, _b, _accessor, _accessor2;\n      _class_decorators = [(assertEq(() => this.foo(0), void 0), dummy)], _b = class extends (_a = (assertEq(() => this.foo(1), void 0), Object), _method_dec2 = [(assertEq(() => this.foo(2), void 0), dummy)], _method_dec = [(assertEq(() => this.foo(3), void 0), dummy)], _field_dec2 = [(assertEq(() => this.foo(4), void 0), dummy)], _field_dec = [(assertEq(() => this.foo(5), void 0), dummy)], _getter_dec2 = [(assertEq(() => this.foo(6), void 0), dummy)], _getter_dec = [(assertEq(() => this.foo(7), void 0), dummy)], _setter_dec2 = [(assertEq(() => this.foo(8), void 0), dummy)], _setter_dec = [(assertEq(() => this.foo(9), void 0), dummy)], _accessor_dec2 = [(assertEq(() => this.foo(10), void 0), dummy)], _accessor_dec = [(assertEq(() => this.foo(11), void 0), dummy)], _a) {\n        constructor() {\n          super(...arguments);\n          __runInitializers(_init, 5, this);\n          __publicField(this, \"field\", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n          __privateAdd(this, _accessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n        }\n        method() {\n        }\n        static method() {\n        }\n        get getter() {\n          return;\n        }\n        static get getter() {\n          return;\n        }\n        set setter(x) {\n        }\n        static set setter(x) {\n        }\n      }, _init = __decoratorStart(_a), _accessor = new WeakMap(), _accessor2 = new WeakMap(), __decorateElement(_init, 9, \"method\", _method_dec, _b), __decorateElement(_init, 10, \"getter\", _getter_dec, _b), __decorateElement(_init, 11, \"setter\", _setter_dec, _b), __decorateElement(_init, 12, \"accessor\", _accessor_dec, _b, _accessor2), __decorateElement(_init, 1, \"method\", _method_dec2, _b), __decorateElement(_init, 2, \"getter\", _getter_dec2, _b), __decorateElement(_init, 3, \"setter\", _setter_dec2, _b), __decorateElement(_init, 4, \"accessor\", _accessor_dec2, _b, _accessor), __decorateElement(_init, 13, \"field\", _field_dec, _b), __decorateElement(_init, 5, \"field\", _field_dec2, _b), _b = __decorateElement(_init, 0, \"\", _class_decorators, _b), __runInitializers(_init, 3, _b), __publicField(_b, \"field\", __runInitializers(_init, 16, _b)), __runInitializers(_init, 19, _b), __privateAdd(_b, _accessor2, __runInitializers(_init, 8, _b)), __runInitializers(_init, 11, _b), __runInitializers(_init, 1, _b), _b;\n    }\n    wrapper.call(ctx);\n    assertEq(() => \"\" + log, \"0,1,2,3,4,5,6,7,8,9,10,11\");\n  },\n  'Decorator list evaluation: \"await\" (class statement)': async () => {\n    const log = [];\n    const dummy = () => {\n    };\n    async function wrapper() {\n      var _accessor_dec, _accessor_dec2, _setter_dec, _setter_dec2, _getter_dec, _getter_dec2, _field_dec, _field_dec2, _method_dec, _method_dec2, _a, _Foo_decorators, _init, _accessor, _accessor2;\n      _Foo_decorators = [(log.push(await Promise.resolve(0)), dummy)];\n      class Foo2 extends (_a = (log.push(await Promise.resolve(1)), Object), _method_dec2 = [(log.push(await Promise.resolve(2)), dummy)], _method_dec = [(log.push(await Promise.resolve(3)), dummy)], _field_dec2 = [(log.push(await Promise.resolve(4)), dummy)], _field_dec = [(log.push(await Promise.resolve(5)), dummy)], _getter_dec2 = [(log.push(await Promise.resolve(6)), dummy)], _getter_dec = [(log.push(await Promise.resolve(7)), dummy)], _setter_dec2 = [(log.push(await Promise.resolve(8)), dummy)], _setter_dec = [(log.push(await Promise.resolve(9)), dummy)], _accessor_dec2 = [(log.push(await Promise.resolve(10)), dummy)], _accessor_dec = [(log.push(await Promise.resolve(11)), dummy)], _a) {\n        constructor() {\n          super(...arguments);\n          __runInitializers(_init, 5, this);\n          __publicField(this, \"field\", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n          __privateAdd(this, _accessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n        }\n        method() {\n        }\n        static method() {\n        }\n        get getter() {\n          return;\n        }\n        static get getter() {\n          return;\n        }\n        set setter(x) {\n        }\n        static set setter(x) {\n        }\n      }\n      _init = __decoratorStart(_a);\n      _accessor = new WeakMap();\n      _accessor2 = new WeakMap();\n      __decorateElement(_init, 9, \"method\", _method_dec, Foo2);\n      __decorateElement(_init, 10, \"getter\", _getter_dec, Foo2);\n      __decorateElement(_init, 11, \"setter\", _setter_dec, Foo2);\n      __decorateElement(_init, 12, \"accessor\", _accessor_dec, Foo2, _accessor2);\n      __decorateElement(_init, 1, \"method\", _method_dec2, Foo2);\n      __decorateElement(_init, 2, \"getter\", _getter_dec2, Foo2);\n      __decorateElement(_init, 3, \"setter\", _setter_dec2, Foo2);\n      __decorateElement(_init, 4, \"accessor\", _accessor_dec2, Foo2, _accessor);\n      __decorateElement(_init, 13, \"field\", _field_dec, Foo2);\n      __decorateElement(_init, 5, \"field\", _field_dec2, Foo2);\n      Foo2 = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, Foo2);\n      __runInitializers(_init, 3, Foo2);\n      __publicField(Foo2, \"field\", __runInitializers(_init, 16, Foo2)), __runInitializers(_init, 19, Foo2);\n      __privateAdd(Foo2, _accessor2, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n      __runInitializers(_init, 1, Foo2);\n    }\n    await wrapper();\n    assertEq(() => \"\" + log, \"0,1,2,3,4,5,6,7,8,9,10,11\");\n  },\n  'Decorator list evaluation: \"await\" (class expression)': async () => {\n    const log = [];\n    const dummy = () => {\n    };\n    async function wrapper() {\n      var _accessor_dec, _accessor_dec2, _setter_dec, _setter_dec2, _getter_dec, _getter_dec2, _field_dec, _field_dec2, _method_dec, _method_dec2, _a, _class_decorators, _init, _b, _accessor, _accessor2;\n      _class_decorators = [(log.push(await Promise.resolve(0)), dummy)], _b = class extends (_a = (log.push(await Promise.resolve(1)), Object), _method_dec2 = [(log.push(await Promise.resolve(2)), dummy)], _method_dec = [(log.push(await Promise.resolve(3)), dummy)], _field_dec2 = [(log.push(await Promise.resolve(4)), dummy)], _field_dec = [(log.push(await Promise.resolve(5)), dummy)], _getter_dec2 = [(log.push(await Promise.resolve(6)), dummy)], _getter_dec = [(log.push(await Promise.resolve(7)), dummy)], _setter_dec2 = [(log.push(await Promise.resolve(8)), dummy)], _setter_dec = [(log.push(await Promise.resolve(9)), dummy)], _accessor_dec2 = [(log.push(await Promise.resolve(10)), dummy)], _accessor_dec = [(log.push(await Promise.resolve(11)), dummy)], _a) {\n        constructor() {\n          super(...arguments);\n          __runInitializers(_init, 5, this);\n          __publicField(this, \"field\", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n          __privateAdd(this, _accessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n        }\n        method() {\n        }\n        static method() {\n        }\n        get getter() {\n          return;\n        }\n        static get getter() {\n          return;\n        }\n        set setter(x) {\n        }\n        static set setter(x) {\n        }\n      }, _init = __decoratorStart(_a), _accessor = new WeakMap(), _accessor2 = new WeakMap(), __decorateElement(_init, 9, \"method\", _method_dec, _b), __decorateElement(_init, 10, \"getter\", _getter_dec, _b), __decorateElement(_init, 11, \"setter\", _setter_dec, _b), __decorateElement(_init, 12, \"accessor\", _accessor_dec, _b, _accessor2), __decorateElement(_init, 1, \"method\", _method_dec2, _b), __decorateElement(_init, 2, \"getter\", _getter_dec2, _b), __decorateElement(_init, 3, \"setter\", _setter_dec2, _b), __decorateElement(_init, 4, \"accessor\", _accessor_dec2, _b, _accessor), __decorateElement(_init, 13, \"field\", _field_dec, _b), __decorateElement(_init, 5, \"field\", _field_dec2, _b), _b = __decorateElement(_init, 0, \"\", _class_decorators, _b), __runInitializers(_init, 3, _b), __publicField(_b, \"field\", __runInitializers(_init, 16, _b)), __runInitializers(_init, 19, _b), __privateAdd(_b, _accessor2, __runInitializers(_init, 8, _b)), __runInitializers(_init, 11, _b), __runInitializers(_init, 1, _b), _b;\n    }\n    await wrapper();\n    assertEq(() => \"\" + log, \"0,1,2,3,4,5,6,7,8,9,10,11\");\n  },\n  \"Decorator list evaluation: Outer private name (class statement)\": () => {\n    var _accessor_dec, _accessor_dec2, _setter_dec, _setter_dec2, _getter_dec, _getter_dec2, _field_dec, _field_dec2, _method_dec, _method_dec2, _a, _Foo_decorators, _init, _accessor, _accessor2;\n    const log = [];\n    class Dummy {\n      static #foo(n) {\n        log.push(n);\n        return () => {\n        };\n      }\n      static {\n        const dummy = this;\n        _Foo_decorators = [dummy.#foo(0)];\n        class Foo2 extends (_a = (dummy.#foo(1), Object), _method_dec2 = [dummy.#foo(2)], _method_dec = [dummy.#foo(3)], _field_dec2 = [dummy.#foo(4)], _field_dec = [dummy.#foo(5)], _getter_dec2 = [dummy.#foo(6)], _getter_dec = [dummy.#foo(7)], _setter_dec2 = [dummy.#foo(8)], _setter_dec = [dummy.#foo(9)], _accessor_dec2 = [dummy.#foo(10)], _accessor_dec = [dummy.#foo(11)], _a) {\n          constructor() {\n            super(...arguments);\n            __runInitializers(_init, 5, this);\n            __publicField(this, \"field\", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n            __privateAdd(this, _accessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n          }\n          method() {\n          }\n          static method() {\n          }\n          get getter() {\n            return;\n          }\n          static get getter() {\n            return;\n          }\n          set setter(x) {\n          }\n          static set setter(x) {\n          }\n        }\n        _init = __decoratorStart(_a);\n        _accessor = new WeakMap();\n        _accessor2 = new WeakMap();\n        __decorateElement(_init, 9, \"method\", _method_dec, Foo2);\n        __decorateElement(_init, 10, \"getter\", _getter_dec, Foo2);\n        __decorateElement(_init, 11, \"setter\", _setter_dec, Foo2);\n        __decorateElement(_init, 12, \"accessor\", _accessor_dec, Foo2, _accessor2);\n        __decorateElement(_init, 1, \"method\", _method_dec2, Foo2);\n        __decorateElement(_init, 2, \"getter\", _getter_dec2, Foo2);\n        __decorateElement(_init, 3, \"setter\", _setter_dec2, Foo2);\n        __decorateElement(_init, 4, \"accessor\", _accessor_dec2, Foo2, _accessor);\n        __decorateElement(_init, 13, \"field\", _field_dec, Foo2);\n        __decorateElement(_init, 5, \"field\", _field_dec2, Foo2);\n        Foo2 = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, Foo2);\n        __runInitializers(_init, 3, Foo2);\n        __publicField(Foo2, \"field\", __runInitializers(_init, 16, Foo2)), __runInitializers(_init, 19, Foo2);\n        __privateAdd(Foo2, _accessor2, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n        __runInitializers(_init, 1, Foo2);\n      }\n    }\n    assertEq(() => \"\" + log, \"0,1,2,3,4,5,6,7,8,9,10,11\");\n  },\n  \"Decorator list evaluation: Outer private name (class expression)\": () => {\n    var _accessor_dec, _accessor_dec2, _setter_dec, _setter_dec2, _getter_dec, _getter_dec2, _field_dec, _field_dec2, _method_dec, _method_dec2, _a, _class_decorators, _init, _b, _accessor, _accessor2;\n    const log = [];\n    class Dummy {\n      static #foo(n) {\n        log.push(n);\n        return () => {\n        };\n      }\n      static {\n        const dummy = this;\n        _class_decorators = [dummy.#foo(0)], _b = class extends (_a = (dummy.#foo(1), Object), _method_dec2 = [dummy.#foo(2)], _method_dec = [dummy.#foo(3)], _field_dec2 = [dummy.#foo(4)], _field_dec = [dummy.#foo(5)], _getter_dec2 = [dummy.#foo(6)], _getter_dec = [dummy.#foo(7)], _setter_dec2 = [dummy.#foo(8)], _setter_dec = [dummy.#foo(9)], _accessor_dec2 = [dummy.#foo(10)], _accessor_dec = [dummy.#foo(11)], _a) {\n          constructor() {\n            super(...arguments);\n            __runInitializers(_init, 5, this);\n            __publicField(this, \"field\", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n            __privateAdd(this, _accessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n          }\n          method() {\n          }\n          static method() {\n          }\n          get getter() {\n            return;\n          }\n          static get getter() {\n            return;\n          }\n          set setter(x) {\n          }\n          static set setter(x) {\n          }\n        }, _init = __decoratorStart(_a), _accessor = new WeakMap(), _accessor2 = new WeakMap(), __decorateElement(_init, 9, \"method\", _method_dec, _b), __decorateElement(_init, 10, \"getter\", _getter_dec, _b), __decorateElement(_init, 11, \"setter\", _setter_dec, _b), __decorateElement(_init, 12, \"accessor\", _accessor_dec, _b, _accessor2), __decorateElement(_init, 1, \"method\", _method_dec2, _b), __decorateElement(_init, 2, \"getter\", _getter_dec2, _b), __decorateElement(_init, 3, \"setter\", _setter_dec2, _b), __decorateElement(_init, 4, \"accessor\", _accessor_dec2, _b, _accessor), __decorateElement(_init, 13, \"field\", _field_dec, _b), __decorateElement(_init, 5, \"field\", _field_dec2, _b), _b = __decorateElement(_init, 0, \"\", _class_decorators, _b), __runInitializers(_init, 3, _b), __publicField(_b, \"field\", __runInitializers(_init, 16, _b)), __runInitializers(_init, 19, _b), __privateAdd(_b, _accessor2, __runInitializers(_init, 8, _b)), __runInitializers(_init, 11, _b), __runInitializers(_init, 1, _b), _b;\n      }\n    }\n    assertEq(() => \"\" + log, \"0,1,2,3,4,5,6,7,8,9,10,11\");\n  },\n  \"Decorator list evaluation: Inner private name (class statement)\": () => {\n    var _accessor_dec, _accessor_dec2, _setter_dec, _setter_dec2, _getter_dec, _getter_dec2, _field_dec, _field_dec2, _method_dec, _method_dec2, _Foo_decorators, _foo, _init, _accessor, _accessor2;\n    const fns = [];\n    const capture = (fn) => {\n      fns.push(fn);\n      return () => {\n      };\n    };\n    class Dummy {\n      static #foo = NaN;\n      static {\n        _Foo_decorators = [capture(() => new Foo2().#foo + 0)], _method_dec2 = [capture(() => __privateGet(new _Foo(), _foo) + 1)], _method_dec = [capture(() => __privateGet(new _Foo(), _foo) + 2)], _field_dec2 = [capture(() => __privateGet(new _Foo(), _foo) + 3)], _field_dec = [capture(() => __privateGet(new _Foo(), _foo) + 4)], _getter_dec2 = [capture(() => __privateGet(new _Foo(), _foo) + 5)], _getter_dec = [capture(() => __privateGet(new _Foo(), _foo) + 6)], _setter_dec2 = [capture(() => __privateGet(new _Foo(), _foo) + 7)], _setter_dec = [capture(() => __privateGet(new _Foo(), _foo) + 8)], _accessor_dec2 = [capture(() => __privateGet(new _Foo(), _foo) + 9)], _accessor_dec = [capture(() => __privateGet(new _Foo(), _foo) + 10)];\n        let _Foo = class _Foo {\n          constructor() {\n            __runInitializers(_init, 5, this);\n            __privateAdd(this, _foo, 10);\n            __publicField(this, \"field\", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n            __privateAdd(this, _accessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n          }\n          method() {\n          }\n          static method() {\n          }\n          get getter() {\n            return;\n          }\n          static get getter() {\n            return;\n          }\n          set setter(x) {\n          }\n          static set setter(x) {\n          }\n        };\n        _init = __decoratorStart(null);\n        _foo = new WeakMap();\n        _accessor = new WeakMap();\n        _accessor2 = new WeakMap();\n        __decorateElement(_init, 9, \"method\", _method_dec, _Foo);\n        __decorateElement(_init, 10, \"getter\", _getter_dec, _Foo);\n        __decorateElement(_init, 11, \"setter\", _setter_dec, _Foo);\n        __decorateElement(_init, 12, \"accessor\", _accessor_dec, _Foo, _accessor2);\n        __decorateElement(_init, 1, \"method\", _method_dec2, _Foo);\n        __decorateElement(_init, 2, \"getter\", _getter_dec2, _Foo);\n        __decorateElement(_init, 3, \"setter\", _setter_dec2, _Foo);\n        __decorateElement(_init, 4, \"accessor\", _accessor_dec2, _Foo, _accessor);\n        __decorateElement(_init, 13, \"field\", _field_dec, _Foo);\n        __decorateElement(_init, 5, \"field\", _field_dec2, _Foo);\n        _Foo = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _Foo);\n        __runInitializers(_init, 3, _Foo);\n        __publicField(_Foo, \"field\", __runInitializers(_init, 16, _Foo)), __runInitializers(_init, 19, _Foo);\n        __privateAdd(_Foo, _accessor2, __runInitializers(_init, 8, _Foo)), __runInitializers(_init, 11, _Foo);\n        __runInitializers(_init, 1, _Foo);\n        let Foo2 = _Foo;\n      }\n    }\n    const firstFn = fns.shift();\n    assertEq(() => {\n      try {\n        firstFn();\n        throw new Error(\"Expected a TypeError to be thrown\");\n      } catch (err) {\n        if (err instanceof TypeError) return true;\n        throw err;\n      }\n    }, true);\n    const log = [];\n    for (const fn of fns) log.push(fn());\n    assertEq(() => \"\" + log, \"11,12,13,14,15,16,17,18,19,20\");\n  },\n  \"Decorator list evaluation: Inner private name (class expression)\": () => {\n    var _accessor_dec, _accessor_dec2, _setter_dec, _setter_dec2, _getter_dec, _getter_dec2, _field_dec, _field_dec2, _method_dec, _method_dec2, _Foo_decorators, _foo, _init, _a, _accessor, _accessor2;\n    const fns = [];\n    const capture = (fn) => {\n      fns.push(fn);\n      return () => {\n      };\n    };\n    class Outer {\n      static #foo = 0;\n      static {\n        _Foo_decorators = [capture(() => Outer.#foo + 0)], _method_dec2 = [capture(() => __privateGet(new _a(), _foo) + 1)], _method_dec = [capture(() => __privateGet(new _a(), _foo) + 2)], _field_dec2 = [capture(() => __privateGet(new _a(), _foo) + 3)], _field_dec = [capture(() => __privateGet(new _a(), _foo) + 4)], _getter_dec2 = [capture(() => __privateGet(new _a(), _foo) + 5)], _getter_dec = [capture(() => __privateGet(new _a(), _foo) + 6)], _setter_dec2 = [capture(() => __privateGet(new _a(), _foo) + 7)], _setter_dec = [capture(() => __privateGet(new _a(), _foo) + 8)], _accessor_dec2 = [capture(() => __privateGet(new _a(), _foo) + 9)], _accessor_dec = [capture(() => __privateGet(new _a(), _foo) + 10)], _a = class {\n          constructor() {\n            __runInitializers(_init, 5, this);\n            __privateAdd(this, _foo, 10);\n            __publicField(this, \"field\", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n            __privateAdd(this, _accessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n          }\n          method() {\n          }\n          static method() {\n          }\n          get getter() {\n            return;\n          }\n          static get getter() {\n            return;\n          }\n          set setter(x) {\n          }\n          static set setter(x) {\n          }\n        }, _init = __decoratorStart(null), _foo = new WeakMap(), _accessor = new WeakMap(), _accessor2 = new WeakMap(), __decorateElement(_init, 9, \"method\", _method_dec, _a), __decorateElement(_init, 10, \"getter\", _getter_dec, _a), __decorateElement(_init, 11, \"setter\", _setter_dec, _a), __decorateElement(_init, 12, \"accessor\", _accessor_dec, _a, _accessor2), __decorateElement(_init, 1, \"method\", _method_dec2, _a), __decorateElement(_init, 2, \"getter\", _getter_dec2, _a), __decorateElement(_init, 3, \"setter\", _setter_dec2, _a), __decorateElement(_init, 4, \"accessor\", _accessor_dec2, _a, _accessor), __decorateElement(_init, 13, \"field\", _field_dec, _a), __decorateElement(_init, 5, \"field\", _field_dec2, _a), _a = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _a), __runInitializers(_init, 3, _a), __publicField(_a, \"field\", __runInitializers(_init, 16, _a)), __runInitializers(_init, 19, _a), __privateAdd(_a, _accessor2, __runInitializers(_init, 8, _a)), __runInitializers(_init, 11, _a), __runInitializers(_init, 1, _a), _a;\n      }\n    }\n    const log = [];\n    for (const fn of fns) log.push(fn());\n    assertEq(() => \"\" + log, \"0,11,12,13,14,15,16,17,18,19,20\");\n  },\n  \"Decorator list evaluation: Class binding (class statement)\": () => {\n    var _accessor_dec, _accessor_dec2, _setter_dec, _setter_dec2, _getter_dec, _getter_dec2, _field_dec, _field_dec2, _method_dec, _method_dec2, _Foo_decorators, _init, _accessor, _accessor2;\n    const fns = [];\n    const capture = (fn) => {\n      fns.push(fn);\n      assertThrows(() => fn(), ReferenceError);\n      return () => {\n      };\n    };\n    _Foo_decorators = [capture(() => Foo2)], _method_dec2 = [capture(() => _Foo)], _method_dec = [capture(() => _Foo)], _field_dec2 = [capture(() => _Foo)], _field_dec = [capture(() => _Foo)], _getter_dec2 = [capture(() => _Foo)], _getter_dec = [capture(() => _Foo)], _setter_dec2 = [capture(() => _Foo)], _setter_dec = [capture(() => _Foo)], _accessor_dec2 = [capture(() => _Foo)], _accessor_dec = [capture(() => _Foo)];\n    let _Foo = class _Foo {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __publicField(this, \"field\", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n        __privateAdd(this, _accessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n      }\n      method() {\n      }\n      static method() {\n      }\n      get getter() {\n        return;\n      }\n      static get getter() {\n        return;\n      }\n      set setter(x) {\n      }\n      static set setter(x) {\n      }\n    };\n    _init = __decoratorStart(null);\n    _accessor = new WeakMap();\n    _accessor2 = new WeakMap();\n    __decorateElement(_init, 9, \"method\", _method_dec, _Foo);\n    __decorateElement(_init, 10, \"getter\", _getter_dec, _Foo);\n    __decorateElement(_init, 11, \"setter\", _setter_dec, _Foo);\n    __decorateElement(_init, 12, \"accessor\", _accessor_dec, _Foo, _accessor2);\n    __decorateElement(_init, 1, \"method\", _method_dec2, _Foo);\n    __decorateElement(_init, 2, \"getter\", _getter_dec2, _Foo);\n    __decorateElement(_init, 3, \"setter\", _setter_dec2, _Foo);\n    __decorateElement(_init, 4, \"accessor\", _accessor_dec2, _Foo, _accessor);\n    __decorateElement(_init, 13, \"field\", _field_dec, _Foo);\n    __decorateElement(_init, 5, \"field\", _field_dec2, _Foo);\n    _Foo = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _Foo);\n    __runInitializers(_init, 3, _Foo);\n    __publicField(_Foo, \"field\", __runInitializers(_init, 16, _Foo)), __runInitializers(_init, 19, _Foo);\n    __privateAdd(_Foo, _accessor2, __runInitializers(_init, 8, _Foo)), __runInitializers(_init, 11, _Foo);\n    __runInitializers(_init, 1, _Foo);\n    let Foo2 = _Foo;\n    const originalFoo = Foo2;\n    for (const fn of fns) {\n      assertEq(() => fn(), originalFoo);\n    }\n    Foo2 = null;\n    const firstFn = fns.shift();\n    assertEq(() => firstFn(), null);\n    for (const fn of fns) {\n      assertEq(() => fn(), originalFoo);\n    }\n  },\n  \"Decorator list evaluation: Class binding (class expression)\": () => {\n    var _accessor_dec, _accessor_dec2, _setter_dec, _setter_dec2, _getter_dec, _getter_dec2, _field_dec, _field_dec2, _method_dec, _method_dec2, _Foo_decorators, _init, _a, _accessor, _accessor2;\n    const fns = [];\n    const capture = (fn) => {\n      fns.push(fn);\n      return () => {\n      };\n    };\n    const originalFoo = (_Foo_decorators = [capture(() => Foo)], _method_dec2 = [capture(() => _a)], _method_dec = [capture(() => _a)], _field_dec2 = [capture(() => _a)], _field_dec = [capture(() => _a)], _getter_dec2 = [capture(() => _a)], _getter_dec = [capture(() => _a)], _setter_dec2 = [capture(() => _a)], _setter_dec = [capture(() => _a)], _accessor_dec2 = [capture(() => _a)], _accessor_dec = [capture(() => _a)], _a = class {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __publicField(this, \"field\", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n        __privateAdd(this, _accessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n      }\n      method() {\n      }\n      static method() {\n      }\n      get getter() {\n        return;\n      }\n      static get getter() {\n        return;\n      }\n      set setter(x) {\n      }\n      static set setter(x) {\n      }\n    }, _init = __decoratorStart(null), _accessor = new WeakMap(), _accessor2 = new WeakMap(), __decorateElement(_init, 9, \"method\", _method_dec, _a), __decorateElement(_init, 10, \"getter\", _getter_dec, _a), __decorateElement(_init, 11, \"setter\", _setter_dec, _a), __decorateElement(_init, 12, \"accessor\", _accessor_dec, _a, _accessor2), __decorateElement(_init, 1, \"method\", _method_dec2, _a), __decorateElement(_init, 2, \"getter\", _getter_dec2, _a), __decorateElement(_init, 3, \"setter\", _setter_dec2, _a), __decorateElement(_init, 4, \"accessor\", _accessor_dec2, _a, _accessor), __decorateElement(_init, 13, \"field\", _field_dec, _a), __decorateElement(_init, 5, \"field\", _field_dec2, _a), _a = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _a), __runInitializers(_init, 3, _a), __publicField(_a, \"field\", __runInitializers(_init, 16, _a)), __runInitializers(_init, 19, _a), __privateAdd(_a, _accessor2, __runInitializers(_init, 8, _a)), __runInitializers(_init, 11, _a), __runInitializers(_init, 1, _a), _a);\n    const firstFn = fns.shift();\n    assertThrows(() => firstFn(), ReferenceError);\n    for (const fn of fns) {\n      assertEq(() => fn(), originalFoo);\n    }\n  },\n  // Decorator metadata\n  \"Decorator metadata: class statement\": () => {\n    var _staticSetter_dec, _staticGetter_dec, _staticMethod_dec, _staticAccessor_dec, _staticField_dec, _instanceSetter_dec, _instanceGetter_dec, _instanceMethod_dec, _instanceAccessor_dec, _instanceField_dec, _Foo_decorators, _init, _instanceAccessor, _staticAccessor, _staticSetter_dec2, _staticGetter_dec2, _staticMethod_dec2, _staticAccessor_dec2, _staticField_dec2, _instanceSetter_dec2, _instanceGetter_dec2, _instanceMethod_dec2, _instanceAccessor_dec2, _instanceField_dec2, _a, _Bar_decorators, _init2, _instanceField, _instanceAccessor2, _b, instanceAccessor_get, instanceAccessor_set, _Bar_instances, instanceMethod_fn, instanceGetter_get, instanceSetter_set, _staticField, _staticAccessor2, _c, staticAccessor_get, staticAccessor_set, _Bar_static, staticMethod_fn, staticGetter_get, staticSetter_set, _x_dec, _init3, _y_dec, _d, _init4;\n    let counter = 0;\n    const dec = (_, ctx) => {\n      ctx.metadata[ctx.name] = counter++;\n    };\n    _Foo_decorators = [dec], _instanceField_dec = [dec], _instanceAccessor_dec = [dec], _instanceMethod_dec = [dec], _instanceGetter_dec = [dec], _instanceSetter_dec = [dec], _staticField_dec = [dec], _staticAccessor_dec = [dec], _staticMethod_dec = [dec], _staticGetter_dec = [dec], _staticSetter_dec = [dec];\n    class Foo2 {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __publicField(this, \"instanceField\", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n        __privateAdd(this, _instanceAccessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n      }\n      instanceMethod() {\n      }\n      get instanceGetter() {\n        return;\n      }\n      set instanceSetter(_) {\n      }\n      static staticMethod() {\n      }\n      static get staticGetter() {\n        return;\n      }\n      static set staticSetter(_) {\n      }\n    }\n    _init = __decoratorStart(null);\n    _instanceAccessor = new WeakMap();\n    _staticAccessor = new WeakMap();\n    __decorateElement(_init, 12, \"staticAccessor\", _staticAccessor_dec, Foo2, _staticAccessor);\n    __decorateElement(_init, 9, \"staticMethod\", _staticMethod_dec, Foo2);\n    __decorateElement(_init, 10, \"staticGetter\", _staticGetter_dec, Foo2);\n    __decorateElement(_init, 11, \"staticSetter\", _staticSetter_dec, Foo2);\n    __decorateElement(_init, 4, \"instanceAccessor\", _instanceAccessor_dec, Foo2, _instanceAccessor);\n    __decorateElement(_init, 1, \"instanceMethod\", _instanceMethod_dec, Foo2);\n    __decorateElement(_init, 2, \"instanceGetter\", _instanceGetter_dec, Foo2);\n    __decorateElement(_init, 3, \"instanceSetter\", _instanceSetter_dec, Foo2);\n    __decorateElement(_init, 13, \"staticField\", _staticField_dec, Foo2);\n    __decorateElement(_init, 5, \"instanceField\", _instanceField_dec, Foo2);\n    Foo2 = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    __publicField(Foo2, \"staticField\", __runInitializers(_init, 16, Foo2)), __runInitializers(_init, 19, Foo2);\n    __privateAdd(Foo2, _staticAccessor, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n    __runInitializers(_init, 1, Foo2);\n    _Bar_decorators = [dec];\n    class Bar extends (_a = Foo2, _instanceField_dec2 = [dec], _instanceAccessor_dec2 = [dec], _instanceMethod_dec2 = [dec], _instanceGetter_dec2 = [dec], _instanceSetter_dec2 = [dec], _staticField_dec2 = [dec], _staticAccessor_dec2 = [dec], _staticMethod_dec2 = [dec], _staticGetter_dec2 = [dec], _staticSetter_dec2 = [dec], _a) {\n      constructor() {\n        super(...arguments);\n        __runInitializers(_init2, 5, this);\n        __privateAdd(this, _Bar_instances);\n        __privateAdd(this, _instanceField, __runInitializers(_init2, 20, this)), __runInitializers(_init2, 23, this);\n        __privateAdd(this, _instanceAccessor2, __runInitializers(_init2, 12, this)), __runInitializers(_init2, 15, this);\n      }\n    }\n    _init2 = __decoratorStart(_a);\n    _instanceField = new WeakMap();\n    _instanceAccessor2 = new WeakMap();\n    _Bar_instances = new WeakSet();\n    instanceMethod_fn = function() {\n    };\n    instanceGetter_get = function() {\n      return;\n    };\n    instanceSetter_set = function(_) {\n    };\n    _staticField = new WeakMap();\n    _staticAccessor2 = new WeakMap();\n    _Bar_static = new WeakSet();\n    staticMethod_fn = function() {\n    };\n    staticGetter_get = function() {\n      return;\n    };\n    staticSetter_set = function(_) {\n    };\n    _c = __decorateElement(_init2, 28, \"#staticAccessor\", _staticAccessor_dec2, _Bar_static, _staticAccessor2), staticAccessor_get = _c.get, staticAccessor_set = _c.set;\n    staticMethod_fn = __decorateElement(_init2, 25, \"#staticMethod\", _staticMethod_dec2, _Bar_static, staticMethod_fn);\n    staticGetter_get = __decorateElement(_init2, 26, \"#staticGetter\", _staticGetter_dec2, _Bar_static, staticGetter_get);\n    staticSetter_set = __decorateElement(_init2, 27, \"#staticSetter\", _staticSetter_dec2, _Bar_static, staticSetter_set);\n    _b = __decorateElement(_init2, 20, \"#instanceAccessor\", _instanceAccessor_dec2, _Bar_instances, _instanceAccessor2), instanceAccessor_get = _b.get, instanceAccessor_set = _b.set;\n    instanceMethod_fn = __decorateElement(_init2, 17, \"#instanceMethod\", _instanceMethod_dec2, _Bar_instances, instanceMethod_fn);\n    instanceGetter_get = __decorateElement(_init2, 18, \"#instanceGetter\", _instanceGetter_dec2, _Bar_instances, instanceGetter_get);\n    instanceSetter_set = __decorateElement(_init2, 19, \"#instanceSetter\", _instanceSetter_dec2, _Bar_instances, instanceSetter_set);\n    __decorateElement(_init2, 29, \"#staticField\", _staticField_dec2, _staticField);\n    __decorateElement(_init2, 21, \"#instanceField\", _instanceField_dec2, _instanceField);\n    __privateAdd(Bar, _Bar_static);\n    Bar = __decorateElement(_init2, 0, \"Bar\", _Bar_decorators, Bar);\n    __runInitializers(_init2, 3, Bar);\n    __privateAdd(Bar, _staticField, __runInitializers(_init2, 16, Bar)), __runInitializers(_init2, 19, Bar);\n    __privateAdd(Bar, _staticAccessor2, __runInitializers(_init2, 8, Bar)), __runInitializers(_init2, 11, Bar);\n    __runInitializers(_init2, 1, Bar);\n    const order = (meta) => \"\" + [\n      meta[\"staticAccessor\"],\n      meta[\"staticMethod\"],\n      meta[\"staticGetter\"],\n      meta[\"staticSetter\"],\n      meta[\"#staticAccessor\"],\n      meta[\"#staticMethod\"],\n      meta[\"#staticGetter\"],\n      meta[\"#staticSetter\"],\n      meta[\"instanceAccessor\"],\n      meta[\"instanceMethod\"],\n      meta[\"instanceGetter\"],\n      meta[\"instanceSetter\"],\n      meta[\"#instanceAccessor\"],\n      meta[\"#instanceMethod\"],\n      meta[\"#instanceGetter\"],\n      meta[\"#instanceSetter\"],\n      meta[\"staticField\"],\n      meta[\"#staticField\"],\n      meta[\"instanceField\"],\n      meta[\"#instanceField\"],\n      meta[\"Foo\"],\n      meta[\"Bar\"]\n    ];\n    const foo = Foo2[Symbol.metadata];\n    const bar = Bar[Symbol.metadata];\n    assertEq(() => order(foo), \"0,1,2,3,,,,,4,5,6,7,,,,,8,,9,,10,\");\n    assertEq(() => Object.getPrototypeOf(foo), null);\n    assertEq(() => order(bar), \"0,1,2,3,11,12,13,14,4,5,6,7,15,16,17,18,8,19,9,20,10,21\");\n    assertEq(() => Object.getPrototypeOf(bar), foo);\n    class FooNoDec {\n    }\n    class BarNoDec extends FooNoDec {\n    }\n    assertEq(() => FooNoDec[Symbol.metadata], null);\n    assertEq(() => BarNoDec[Symbol.metadata], null);\n    _x_dec = [dec];\n    class FooOneDec {\n      constructor() {\n        __publicField(this, \"x\", __runInitializers(_init3, 8, this)), __runInitializers(_init3, 11, this);\n      }\n    }\n    _init3 = __decoratorStart(null);\n    __decorateElement(_init3, 5, \"x\", _x_dec, FooOneDec);\n    __decoratorMetadata(_init3, FooOneDec);\n    class BarOneDec extends (_d = FooOneDec, _y_dec = [dec], _d) {\n      constructor() {\n        super(...arguments);\n        __publicField(this, \"y\", __runInitializers(_init4, 8, this)), __runInitializers(_init4, 11, this);\n      }\n    }\n    _init4 = __decoratorStart(_d);\n    __decorateElement(_init4, 5, \"y\", _y_dec, BarOneDec);\n    __decoratorMetadata(_init4, BarOneDec);\n    assertEq(() => JSON.stringify(FooOneDec[Symbol.metadata]), JSON.stringify({ x: 22 }));\n    assertEq(() => JSON.stringify(BarOneDec[Symbol.metadata]), JSON.stringify({ y: 23 }));\n    assertEq(() => Object.getPrototypeOf(BarOneDec[Symbol.metadata]), FooOneDec[Symbol.metadata]);\n  },\n  \"Decorator metadata: class expression\": () => {\n    var _staticSetter_dec, _staticGetter_dec, _staticMethod_dec, _staticAccessor_dec, _staticField_dec, _instanceSetter_dec, _instanceGetter_dec, _instanceMethod_dec, _instanceAccessor_dec, _instanceField_dec, _Foo_decorators, _init, _a, _instanceAccessor, _staticAccessor, _staticSetter_dec2, _staticGetter_dec2, _staticMethod_dec2, _staticAccessor_dec2, _staticField_dec2, _instanceSetter_dec2, _instanceGetter_dec2, _instanceMethod_dec2, _instanceAccessor_dec2, _instanceField_dec2, _b, _Bar_decorators, _init2, _instanceField, _instanceAccessor2, _c, instanceAccessor_get, instanceAccessor_set, _Bar_instances, instanceMethod_fn, instanceGetter_get, instanceSetter_set, _d, _staticField, _staticAccessor2, _e, staticAccessor_get, staticAccessor_set, _Bar_static, staticMethod_fn, staticGetter_get, staticSetter_set, _x_dec, _init3, _f, _y_dec, _g, _init4, _h;\n    let counter = 0;\n    const dec = (_, ctx) => {\n      ctx.metadata[ctx.name] = counter++;\n    };\n    const Foo2 = (_Foo_decorators = [dec], _instanceField_dec = [dec], _instanceAccessor_dec = [dec], _instanceMethod_dec = [dec], _instanceGetter_dec = [dec], _instanceSetter_dec = [dec], _staticField_dec = [dec], _staticAccessor_dec = [dec], _staticMethod_dec = [dec], _staticGetter_dec = [dec], _staticSetter_dec = [dec], _a = class {\n      constructor() {\n        __runInitializers(_init, 5, this);\n        __publicField(this, \"instanceField\", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n        __privateAdd(this, _instanceAccessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n      }\n      instanceMethod() {\n      }\n      get instanceGetter() {\n        return;\n      }\n      set instanceSetter(_) {\n      }\n      static staticMethod() {\n      }\n      static get staticGetter() {\n        return;\n      }\n      static set staticSetter(_) {\n      }\n    }, _init = __decoratorStart(null), _instanceAccessor = new WeakMap(), _staticAccessor = new WeakMap(), __decorateElement(_init, 12, \"staticAccessor\", _staticAccessor_dec, _a, _staticAccessor), __decorateElement(_init, 9, \"staticMethod\", _staticMethod_dec, _a), __decorateElement(_init, 10, \"staticGetter\", _staticGetter_dec, _a), __decorateElement(_init, 11, \"staticSetter\", _staticSetter_dec, _a), __decorateElement(_init, 4, \"instanceAccessor\", _instanceAccessor_dec, _a, _instanceAccessor), __decorateElement(_init, 1, \"instanceMethod\", _instanceMethod_dec, _a), __decorateElement(_init, 2, \"instanceGetter\", _instanceGetter_dec, _a), __decorateElement(_init, 3, \"instanceSetter\", _instanceSetter_dec, _a), __decorateElement(_init, 13, \"staticField\", _staticField_dec, _a), __decorateElement(_init, 5, \"instanceField\", _instanceField_dec, _a), _a = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _a), __runInitializers(_init, 3, _a), __publicField(_a, \"staticField\", __runInitializers(_init, 16, _a)), __runInitializers(_init, 19, _a), __privateAdd(_a, _staticAccessor, __runInitializers(_init, 8, _a)), __runInitializers(_init, 11, _a), __runInitializers(_init, 1, _a), _a), Bar = (_Bar_decorators = [dec], _d = class extends (_b = Foo2, _instanceField_dec2 = [dec], _instanceAccessor_dec2 = [dec], _instanceMethod_dec2 = [dec], _instanceGetter_dec2 = [dec], _instanceSetter_dec2 = [dec], _staticField_dec2 = [dec], _staticAccessor_dec2 = [dec], _staticMethod_dec2 = [dec], _staticGetter_dec2 = [dec], _staticSetter_dec2 = [dec], _b) {\n      constructor() {\n        super(...arguments);\n        __runInitializers(_init2, 5, this);\n        __privateAdd(this, _Bar_instances);\n        __privateAdd(this, _instanceField, __runInitializers(_init2, 20, this)), __runInitializers(_init2, 23, this);\n        __privateAdd(this, _instanceAccessor2, __runInitializers(_init2, 12, this)), __runInitializers(_init2, 15, this);\n      }\n    }, _init2 = __decoratorStart(_b), _instanceField = new WeakMap(), _instanceAccessor2 = new WeakMap(), _Bar_instances = new WeakSet(), instanceMethod_fn = function() {\n    }, instanceGetter_get = function() {\n      return;\n    }, instanceSetter_set = function(_) {\n    }, _staticField = new WeakMap(), _staticAccessor2 = new WeakMap(), _Bar_static = new WeakSet(), staticMethod_fn = function() {\n    }, staticGetter_get = function() {\n      return;\n    }, staticSetter_set = function(_) {\n    }, _e = __decorateElement(_init2, 28, \"#staticAccessor\", _staticAccessor_dec2, _Bar_static, _staticAccessor2), staticAccessor_get = _e.get, staticAccessor_set = _e.set, staticMethod_fn = __decorateElement(_init2, 25, \"#staticMethod\", _staticMethod_dec2, _Bar_static, staticMethod_fn), staticGetter_get = __decorateElement(_init2, 26, \"#staticGetter\", _staticGetter_dec2, _Bar_static, staticGetter_get), staticSetter_set = __decorateElement(_init2, 27, \"#staticSetter\", _staticSetter_dec2, _Bar_static, staticSetter_set), _c = __decorateElement(_init2, 20, \"#instanceAccessor\", _instanceAccessor_dec2, _Bar_instances, _instanceAccessor2), instanceAccessor_get = _c.get, instanceAccessor_set = _c.set, instanceMethod_fn = __decorateElement(_init2, 17, \"#instanceMethod\", _instanceMethod_dec2, _Bar_instances, instanceMethod_fn), instanceGetter_get = __decorateElement(_init2, 18, \"#instanceGetter\", _instanceGetter_dec2, _Bar_instances, instanceGetter_get), instanceSetter_set = __decorateElement(_init2, 19, \"#instanceSetter\", _instanceSetter_dec2, _Bar_instances, instanceSetter_set), __decorateElement(_init2, 29, \"#staticField\", _staticField_dec2, _staticField), __decorateElement(_init2, 21, \"#instanceField\", _instanceField_dec2, _instanceField), __privateAdd(_d, _Bar_static), _d = __decorateElement(_init2, 0, \"Bar\", _Bar_decorators, _d), __runInitializers(_init2, 3, _d), __privateAdd(_d, _staticField, __runInitializers(_init2, 16, _d)), __runInitializers(_init2, 19, _d), __privateAdd(_d, _staticAccessor2, __runInitializers(_init2, 8, _d)), __runInitializers(_init2, 11, _d), __runInitializers(_init2, 1, _d), _d);\n    const order = (meta) => \"\" + [\n      meta[\"staticAccessor\"],\n      meta[\"staticMethod\"],\n      meta[\"staticGetter\"],\n      meta[\"staticSetter\"],\n      meta[\"#staticAccessor\"],\n      meta[\"#staticMethod\"],\n      meta[\"#staticGetter\"],\n      meta[\"#staticSetter\"],\n      meta[\"instanceAccessor\"],\n      meta[\"instanceMethod\"],\n      meta[\"instanceGetter\"],\n      meta[\"instanceSetter\"],\n      meta[\"#instanceAccessor\"],\n      meta[\"#instanceMethod\"],\n      meta[\"#instanceGetter\"],\n      meta[\"#instanceSetter\"],\n      meta[\"staticField\"],\n      meta[\"#staticField\"],\n      meta[\"instanceField\"],\n      meta[\"#instanceField\"],\n      meta[\"Foo\"],\n      meta[\"Bar\"]\n    ];\n    const foo = Foo2[Symbol.metadata];\n    const bar = Bar[Symbol.metadata];\n    assertEq(() => order(foo), \"0,1,2,3,,,,,4,5,6,7,,,,,8,,9,,10,\");\n    assertEq(() => Object.getPrototypeOf(foo), null);\n    assertEq(() => order(bar), \"0,1,2,3,11,12,13,14,4,5,6,7,15,16,17,18,8,19,9,20,10,21\");\n    assertEq(() => Object.getPrototypeOf(bar), foo);\n    const FooNoDec = class {\n    };\n    const BarNoDec = class extends FooNoDec {\n    };\n    assertEq(() => FooNoDec[Symbol.metadata], null);\n    assertEq(() => BarNoDec[Symbol.metadata], null);\n    const FooOneDec = (_x_dec = [dec], _f = class {\n      constructor() {\n        __publicField(this, \"x\", __runInitializers(_init3, 8, this)), __runInitializers(_init3, 11, this);\n      }\n    }, _init3 = __decoratorStart(null), __decorateElement(_init3, 5, \"x\", _x_dec, _f), __decoratorMetadata(_init3, _f), _f);\n    const BarOneDec = (_h = class extends (_g = FooOneDec, _y_dec = [dec], _g) {\n      constructor() {\n        super(...arguments);\n        __publicField(this, \"y\", __runInitializers(_init4, 8, this)), __runInitializers(_init4, 11, this);\n      }\n    }, _init4 = __decoratorStart(_g), __decorateElement(_init4, 5, \"y\", _y_dec, _h), __decoratorMetadata(_init4, _h), _h);\n    assertEq(() => JSON.stringify(FooOneDec[Symbol.metadata]), JSON.stringify({ x: 22 }));\n    assertEq(() => JSON.stringify(BarOneDec[Symbol.metadata]), JSON.stringify({ y: 23 }));\n    assertEq(() => Object.getPrototypeOf(BarOneDec[Symbol.metadata]), FooOneDec[Symbol.metadata]);\n  },\n  // Initializer order\n  \"Initializer order (public members, class statement)\": () => {\n    var _accessor_dec, _accessor_dec2, _setter_dec, _setter_dec2, _getter_dec, _getter_dec2, _field_dec, _field_dec2, _method_dec, _method_dec2, _a, _Foo_decorators, _init, _accessor, _accessor2;\n    const log = [];\n    const classDec1 = (cls, ctxClass) => {\n      log.push(\"c2\");\n      if (!assertEq(() => typeof ctxClass.addInitializer, \"function\")) return;\n      ctxClass.addInitializer(() => log.push(\"c5\"));\n      ctxClass.addInitializer(() => log.push(\"c6\"));\n    };\n    const classDec2 = (cls, ctxClass) => {\n      log.push(\"c1\");\n      if (!assertEq(() => typeof ctxClass.addInitializer, \"function\")) return;\n      ctxClass.addInitializer(() => log.push(\"c3\"));\n      ctxClass.addInitializer(() => log.push(\"c4\"));\n    };\n    const methodDec1 = (fn, ctxMethod) => {\n      log.push(\"m2\");\n      if (!assertEq(() => typeof ctxMethod.addInitializer, \"function\")) return;\n      ctxMethod.addInitializer(() => log.push(\"m5\"));\n      ctxMethod.addInitializer(() => log.push(\"m6\"));\n    };\n    const methodDec2 = (fn, ctxMethod) => {\n      log.push(\"m1\");\n      if (!assertEq(() => typeof ctxMethod.addInitializer, \"function\")) return;\n      ctxMethod.addInitializer(() => log.push(\"m3\"));\n      ctxMethod.addInitializer(() => log.push(\"m4\"));\n    };\n    const staticMethodDec1 = (fn, ctxStaticMethod) => {\n      log.push(\"M2\");\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, \"function\")) return;\n      ctxStaticMethod.addInitializer(() => log.push(\"M5\"));\n      ctxStaticMethod.addInitializer(() => log.push(\"M6\"));\n    };\n    const staticMethodDec2 = (fn, ctxStaticMethod) => {\n      log.push(\"M1\");\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, \"function\")) return;\n      ctxStaticMethod.addInitializer(() => log.push(\"M3\"));\n      ctxStaticMethod.addInitializer(() => log.push(\"M4\"));\n    };\n    const fieldDec1 = (value, ctxField) => {\n      log.push(\"f2\");\n      if (!assertEq(() => typeof ctxField.addInitializer, \"function\")) return;\n      ctxField.addInitializer(() => log.push(\"f5\"));\n      ctxField.addInitializer(() => log.push(\"f6\"));\n      return () => {\n        log.push(\"f7\");\n      };\n    };\n    const fieldDec2 = (value, ctxField) => {\n      log.push(\"f1\");\n      if (!assertEq(() => typeof ctxField.addInitializer, \"function\")) return;\n      ctxField.addInitializer(() => log.push(\"f3\"));\n      ctxField.addInitializer(() => log.push(\"f4\"));\n      return () => {\n        log.push(\"f8\");\n      };\n    };\n    const staticFieldDec1 = (value, ctxStaticField) => {\n      log.push(\"F2\");\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, \"function\")) return;\n      ctxStaticField.addInitializer(() => log.push(\"F5\"));\n      ctxStaticField.addInitializer(() => log.push(\"F6\"));\n      return () => {\n        log.push(\"F7\");\n      };\n    };\n    const staticFieldDec2 = (value, ctxStaticField) => {\n      log.push(\"F1\");\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, \"function\")) return;\n      ctxStaticField.addInitializer(() => log.push(\"F3\"));\n      ctxStaticField.addInitializer(() => log.push(\"F4\"));\n      return () => {\n        log.push(\"F8\");\n      };\n    };\n    const getterDec1 = (fn, ctxGetter) => {\n      log.push(\"g2\");\n      if (!assertEq(() => typeof ctxGetter.addInitializer, \"function\")) return;\n      ctxGetter.addInitializer(() => log.push(\"g5\"));\n      ctxGetter.addInitializer(() => log.push(\"g6\"));\n    };\n    const getterDec2 = (fn, ctxGetter) => {\n      log.push(\"g1\");\n      if (!assertEq(() => typeof ctxGetter.addInitializer, \"function\")) return;\n      ctxGetter.addInitializer(() => log.push(\"g3\"));\n      ctxGetter.addInitializer(() => log.push(\"g4\"));\n    };\n    const staticGetterDec1 = (fn, ctxStaticGetter) => {\n      log.push(\"G2\");\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, \"function\")) return;\n      ctxStaticGetter.addInitializer(() => log.push(\"G5\"));\n      ctxStaticGetter.addInitializer(() => log.push(\"G6\"));\n    };\n    const staticGetterDec2 = (fn, ctxStaticGetter) => {\n      log.push(\"G1\");\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, \"function\")) return;\n      ctxStaticGetter.addInitializer(() => log.push(\"G3\"));\n      ctxStaticGetter.addInitializer(() => log.push(\"G4\"));\n    };\n    const setterDec1 = (fn, ctxSetter) => {\n      log.push(\"s2\");\n      if (!assertEq(() => typeof ctxSetter.addInitializer, \"function\")) return;\n      ctxSetter.addInitializer(() => log.push(\"s5\"));\n      ctxSetter.addInitializer(() => log.push(\"s6\"));\n    };\n    const setterDec2 = (fn, ctxSetter) => {\n      log.push(\"s1\");\n      if (!assertEq(() => typeof ctxSetter.addInitializer, \"function\")) return;\n      ctxSetter.addInitializer(() => log.push(\"s3\"));\n      ctxSetter.addInitializer(() => log.push(\"s4\"));\n    };\n    const staticSetterDec1 = (fn, ctxStaticSetter) => {\n      log.push(\"S2\");\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, \"function\")) return;\n      ctxStaticSetter.addInitializer(() => log.push(\"S5\"));\n      ctxStaticSetter.addInitializer(() => log.push(\"S6\"));\n    };\n    const staticSetterDec2 = (fn, ctxStaticSetter) => {\n      log.push(\"S1\");\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, \"function\")) return;\n      ctxStaticSetter.addInitializer(() => log.push(\"S3\"));\n      ctxStaticSetter.addInitializer(() => log.push(\"S4\"));\n    };\n    const accessorDec1 = (target, ctxAccessor) => {\n      log.push(\"a2\");\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, \"function\")) return;\n      ctxAccessor.addInitializer(() => log.push(\"a5\"));\n      ctxAccessor.addInitializer(() => log.push(\"a6\"));\n      return { init() {\n        log.push(\"a7\");\n      } };\n    };\n    const accessorDec2 = (target, ctxAccessor) => {\n      log.push(\"a1\");\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, \"function\")) return;\n      ctxAccessor.addInitializer(() => log.push(\"a3\"));\n      ctxAccessor.addInitializer(() => log.push(\"a4\"));\n      return { init() {\n        log.push(\"a8\");\n      } };\n    };\n    const staticAccessorDec1 = (target, ctxStaticAccessor) => {\n      log.push(\"A2\");\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, \"function\")) return;\n      ctxStaticAccessor.addInitializer(() => log.push(\"A5\"));\n      ctxStaticAccessor.addInitializer(() => log.push(\"A6\"));\n      return { init() {\n        log.push(\"A7\");\n      } };\n    };\n    const staticAccessorDec2 = (target, ctxStaticAccessor) => {\n      log.push(\"A1\");\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, \"function\")) return;\n      ctxStaticAccessor.addInitializer(() => log.push(\"A3\"));\n      ctxStaticAccessor.addInitializer(() => log.push(\"A4\"));\n      return { init() {\n        log.push(\"A8\");\n      } };\n    };\n    log.push(\"start\");\n    _Foo_decorators = [classDec1, classDec2];\n    class Foo2 extends (_a = (log.push(\"extends\"), Object), _method_dec2 = [methodDec1, methodDec2], _method_dec = [staticMethodDec1, staticMethodDec2], _field_dec2 = [fieldDec1, fieldDec2], _field_dec = [staticFieldDec1, staticFieldDec2], _getter_dec2 = [getterDec1, getterDec2], _getter_dec = [staticGetterDec1, staticGetterDec2], _setter_dec2 = [setterDec1, setterDec2], _setter_dec = [staticSetterDec1, staticSetterDec2], _accessor_dec2 = [accessorDec1, accessorDec2], _accessor_dec = [staticAccessorDec1, staticAccessorDec2], _a) {\n      constructor() {\n        log.push(\"ctor:start\");\n        super();\n        __runInitializers(_init, 5, this);\n        __publicField(this, \"field\", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n        __privateAdd(this, _accessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n        log.push(\"ctor:end\");\n      }\n      method() {\n      }\n      static method() {\n      }\n      get getter() {\n        return;\n      }\n      static get getter() {\n        return;\n      }\n      set setter(x) {\n      }\n      static set setter(x) {\n      }\n    }\n    _init = __decoratorStart(_a);\n    _accessor = new WeakMap();\n    _accessor2 = new WeakMap();\n    __decorateElement(_init, 9, \"method\", _method_dec, Foo2);\n    __decorateElement(_init, 10, \"getter\", _getter_dec, Foo2);\n    __decorateElement(_init, 11, \"setter\", _setter_dec, Foo2);\n    __decorateElement(_init, 12, \"accessor\", _accessor_dec, Foo2, _accessor2);\n    __decorateElement(_init, 1, \"method\", _method_dec2, Foo2);\n    __decorateElement(_init, 2, \"getter\", _getter_dec2, Foo2);\n    __decorateElement(_init, 3, \"setter\", _setter_dec2, Foo2);\n    __decorateElement(_init, 4, \"accessor\", _accessor_dec2, Foo2, _accessor);\n    __decorateElement(_init, 13, \"field\", _field_dec, Foo2);\n    __decorateElement(_init, 5, \"field\", _field_dec2, Foo2);\n    Foo2 = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    log.push(\"static:start\");\n    __publicField(Foo2, \"field\", __runInitializers(_init, 16, Foo2)), __runInitializers(_init, 19, Foo2);\n    __privateAdd(Foo2, _accessor2, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n    log.push(\"static:end\");\n    __runInitializers(_init, 1, Foo2);\n    log.push(\"after\");\n    new Foo2();\n    log.push(\"end\");\n    assertEq(() => log + \"\", \"start,extends,M1,M2,G1,G2,S1,S2,A1,A2,m1,m2,g1,g2,s1,s2,a1,a2,F1,F2,f1,f2,c1,c2,M3,M4,M5,M6,G3,G4,G5,G6,S3,S4,S5,S6,static:start,F7,F8,F3,F4,F5,F6,A7,A8,A3,A4,A5,A6,static:end,c3,c4,c5,c6,after,ctor:start,m3,m4,m5,m6,g3,g4,g5,g6,s3,s4,s5,s6,f7,f8,f3,f4,f5,f6,a7,a8,a3,a4,a5,a6,ctor:end,end\");\n  },\n  \"Initializer order (public members, class expression)\": () => {\n    var _accessor_dec, _accessor_dec2, _setter_dec, _setter_dec2, _getter_dec, _getter_dec2, _field_dec, _field_dec2, _method_dec, _method_dec2, _a, _Foo_decorators, _init, _b, _accessor, _accessor2;\n    const log = [];\n    const classDec1 = (cls, ctxClass) => {\n      log.push(\"c2\");\n      if (!assertEq(() => typeof ctxClass.addInitializer, \"function\")) return;\n      ctxClass.addInitializer(() => log.push(\"c5\"));\n      ctxClass.addInitializer(() => log.push(\"c6\"));\n    };\n    const classDec2 = (cls, ctxClass) => {\n      log.push(\"c1\");\n      if (!assertEq(() => typeof ctxClass.addInitializer, \"function\")) return;\n      ctxClass.addInitializer(() => log.push(\"c3\"));\n      ctxClass.addInitializer(() => log.push(\"c4\"));\n    };\n    const methodDec1 = (fn, ctxMethod) => {\n      log.push(\"m2\");\n      if (!assertEq(() => typeof ctxMethod.addInitializer, \"function\")) return;\n      ctxMethod.addInitializer(() => log.push(\"m5\"));\n      ctxMethod.addInitializer(() => log.push(\"m6\"));\n    };\n    const methodDec2 = (fn, ctxMethod) => {\n      log.push(\"m1\");\n      if (!assertEq(() => typeof ctxMethod.addInitializer, \"function\")) return;\n      ctxMethod.addInitializer(() => log.push(\"m3\"));\n      ctxMethod.addInitializer(() => log.push(\"m4\"));\n    };\n    const staticMethodDec1 = (fn, ctxStaticMethod) => {\n      log.push(\"M2\");\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, \"function\")) return;\n      ctxStaticMethod.addInitializer(() => log.push(\"M5\"));\n      ctxStaticMethod.addInitializer(() => log.push(\"M6\"));\n    };\n    const staticMethodDec2 = (fn, ctxStaticMethod) => {\n      log.push(\"M1\");\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, \"function\")) return;\n      ctxStaticMethod.addInitializer(() => log.push(\"M3\"));\n      ctxStaticMethod.addInitializer(() => log.push(\"M4\"));\n    };\n    const fieldDec1 = (value, ctxField) => {\n      log.push(\"f2\");\n      if (!assertEq(() => typeof ctxField.addInitializer, \"function\")) return;\n      ctxField.addInitializer(() => log.push(\"f5\"));\n      ctxField.addInitializer(() => log.push(\"f6\"));\n      return () => {\n        log.push(\"f7\");\n      };\n    };\n    const fieldDec2 = (value, ctxField) => {\n      log.push(\"f1\");\n      if (!assertEq(() => typeof ctxField.addInitializer, \"function\")) return;\n      ctxField.addInitializer(() => log.push(\"f3\"));\n      ctxField.addInitializer(() => log.push(\"f4\"));\n      return () => {\n        log.push(\"f8\");\n      };\n    };\n    const staticFieldDec1 = (value, ctxStaticField) => {\n      log.push(\"F2\");\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, \"function\")) return;\n      ctxStaticField.addInitializer(() => log.push(\"F5\"));\n      ctxStaticField.addInitializer(() => log.push(\"F6\"));\n      return () => {\n        log.push(\"F7\");\n      };\n    };\n    const staticFieldDec2 = (value, ctxStaticField) => {\n      log.push(\"F1\");\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, \"function\")) return;\n      ctxStaticField.addInitializer(() => log.push(\"F3\"));\n      ctxStaticField.addInitializer(() => log.push(\"F4\"));\n      return () => {\n        log.push(\"F8\");\n      };\n    };\n    const getterDec1 = (fn, ctxGetter) => {\n      log.push(\"g2\");\n      if (!assertEq(() => typeof ctxGetter.addInitializer, \"function\")) return;\n      ctxGetter.addInitializer(() => log.push(\"g5\"));\n      ctxGetter.addInitializer(() => log.push(\"g6\"));\n    };\n    const getterDec2 = (fn, ctxGetter) => {\n      log.push(\"g1\");\n      if (!assertEq(() => typeof ctxGetter.addInitializer, \"function\")) return;\n      ctxGetter.addInitializer(() => log.push(\"g3\"));\n      ctxGetter.addInitializer(() => log.push(\"g4\"));\n    };\n    const staticGetterDec1 = (fn, ctxStaticGetter) => {\n      log.push(\"G2\");\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, \"function\")) return;\n      ctxStaticGetter.addInitializer(() => log.push(\"G5\"));\n      ctxStaticGetter.addInitializer(() => log.push(\"G6\"));\n    };\n    const staticGetterDec2 = (fn, ctxStaticGetter) => {\n      log.push(\"G1\");\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, \"function\")) return;\n      ctxStaticGetter.addInitializer(() => log.push(\"G3\"));\n      ctxStaticGetter.addInitializer(() => log.push(\"G4\"));\n    };\n    const setterDec1 = (fn, ctxSetter) => {\n      log.push(\"s2\");\n      if (!assertEq(() => typeof ctxSetter.addInitializer, \"function\")) return;\n      ctxSetter.addInitializer(() => log.push(\"s5\"));\n      ctxSetter.addInitializer(() => log.push(\"s6\"));\n    };\n    const setterDec2 = (fn, ctxSetter) => {\n      log.push(\"s1\");\n      if (!assertEq(() => typeof ctxSetter.addInitializer, \"function\")) return;\n      ctxSetter.addInitializer(() => log.push(\"s3\"));\n      ctxSetter.addInitializer(() => log.push(\"s4\"));\n    };\n    const staticSetterDec1 = (fn, ctxStaticSetter) => {\n      log.push(\"S2\");\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, \"function\")) return;\n      ctxStaticSetter.addInitializer(() => log.push(\"S5\"));\n      ctxStaticSetter.addInitializer(() => log.push(\"S6\"));\n    };\n    const staticSetterDec2 = (fn, ctxStaticSetter) => {\n      log.push(\"S1\");\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, \"function\")) return;\n      ctxStaticSetter.addInitializer(() => log.push(\"S3\"));\n      ctxStaticSetter.addInitializer(() => log.push(\"S4\"));\n    };\n    const accessorDec1 = (target, ctxAccessor) => {\n      log.push(\"a2\");\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, \"function\")) return;\n      ctxAccessor.addInitializer(() => log.push(\"a5\"));\n      ctxAccessor.addInitializer(() => log.push(\"a6\"));\n      return { init() {\n        log.push(\"a7\");\n      } };\n    };\n    const accessorDec2 = (target, ctxAccessor) => {\n      log.push(\"a1\");\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, \"function\")) return;\n      ctxAccessor.addInitializer(() => log.push(\"a3\"));\n      ctxAccessor.addInitializer(() => log.push(\"a4\"));\n      return { init() {\n        log.push(\"a8\");\n      } };\n    };\n    const staticAccessorDec1 = (target, ctxStaticAccessor) => {\n      log.push(\"A2\");\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, \"function\")) return;\n      ctxStaticAccessor.addInitializer(() => log.push(\"A5\"));\n      ctxStaticAccessor.addInitializer(() => log.push(\"A6\"));\n      return { init() {\n        log.push(\"A7\");\n      } };\n    };\n    const staticAccessorDec2 = (target, ctxStaticAccessor) => {\n      log.push(\"A1\");\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, \"function\")) return;\n      ctxStaticAccessor.addInitializer(() => log.push(\"A3\"));\n      ctxStaticAccessor.addInitializer(() => log.push(\"A4\"));\n      return { init() {\n        log.push(\"A8\");\n      } };\n    };\n    log.push(\"start\");\n    const Foo2 = (_Foo_decorators = [classDec1, classDec2], _b = class extends (_a = (log.push(\"extends\"), Object), _method_dec2 = [methodDec1, methodDec2], _method_dec = [staticMethodDec1, staticMethodDec2], _field_dec2 = [fieldDec1, fieldDec2], _field_dec = [staticFieldDec1, staticFieldDec2], _getter_dec2 = [getterDec1, getterDec2], _getter_dec = [staticGetterDec1, staticGetterDec2], _setter_dec2 = [setterDec1, setterDec2], _setter_dec = [staticSetterDec1, staticSetterDec2], _accessor_dec2 = [accessorDec1, accessorDec2], _accessor_dec = [staticAccessorDec1, staticAccessorDec2], _a) {\n      constructor() {\n        log.push(\"ctor:start\");\n        super();\n        __runInitializers(_init, 5, this);\n        __publicField(this, \"field\", __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n        __privateAdd(this, _accessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n        log.push(\"ctor:end\");\n      }\n      method() {\n      }\n      static method() {\n      }\n      get getter() {\n        return;\n      }\n      static get getter() {\n        return;\n      }\n      set setter(x) {\n      }\n      static set setter(x) {\n      }\n    }, _init = __decoratorStart(_a), _accessor = new WeakMap(), _accessor2 = new WeakMap(), __decorateElement(_init, 9, \"method\", _method_dec, _b), __decorateElement(_init, 10, \"getter\", _getter_dec, _b), __decorateElement(_init, 11, \"setter\", _setter_dec, _b), __decorateElement(_init, 12, \"accessor\", _accessor_dec, _b, _accessor2), __decorateElement(_init, 1, \"method\", _method_dec2, _b), __decorateElement(_init, 2, \"getter\", _getter_dec2, _b), __decorateElement(_init, 3, \"setter\", _setter_dec2, _b), __decorateElement(_init, 4, \"accessor\", _accessor_dec2, _b, _accessor), __decorateElement(_init, 13, \"field\", _field_dec, _b), __decorateElement(_init, 5, \"field\", _field_dec2, _b), _b = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _b), __runInitializers(_init, 3, _b), log.push(\"static:start\"), __publicField(_b, \"field\", __runInitializers(_init, 16, _b)), __runInitializers(_init, 19, _b), __privateAdd(_b, _accessor2, __runInitializers(_init, 8, _b)), __runInitializers(_init, 11, _b), log.push(\"static:end\"), __runInitializers(_init, 1, _b), _b);\n    log.push(\"after\");\n    new Foo2();\n    log.push(\"end\");\n    assertEq(() => log + \"\", \"start,extends,M1,M2,G1,G2,S1,S2,A1,A2,m1,m2,g1,g2,s1,s2,a1,a2,F1,F2,f1,f2,c1,c2,M3,M4,M5,M6,G3,G4,G5,G6,S3,S4,S5,S6,static:start,F7,F8,F3,F4,F5,F6,A7,A8,A3,A4,A5,A6,static:end,c3,c4,c5,c6,after,ctor:start,m3,m4,m5,m6,g3,g4,g5,g6,s3,s4,s5,s6,f7,f8,f3,f4,f5,f6,a7,a8,a3,a4,a5,a6,ctor:end,end\");\n  },\n  \"Initializer order (private members, class statement)\": () => {\n    var _staticAccessor_dec, _accessor_dec, _staticSetter_dec, _setter_dec, _staticGetter_dec, _getter_dec, _staticField_dec, _field_dec, _staticMethod_dec, _method_dec, _a, _Foo_decorators, _init, _Foo_instances, method_fn, _Foo_static, staticMethod_fn, _field, _staticField, getter_get, staticGetter_get, setter_set, staticSetter_set, _accessor, _b, accessor_get, accessor_set, _staticAccessor, _c, staticAccessor_get, staticAccessor_set;\n    const log = [];\n    const classDec1 = (cls, ctxClass) => {\n      log.push(\"c2\");\n      if (!assertEq(() => typeof ctxClass.addInitializer, \"function\")) return;\n      ctxClass.addInitializer(() => log.push(\"c5\"));\n      ctxClass.addInitializer(() => log.push(\"c6\"));\n    };\n    const classDec2 = (cls, ctxClass) => {\n      log.push(\"c1\");\n      if (!assertEq(() => typeof ctxClass.addInitializer, \"function\")) return;\n      ctxClass.addInitializer(() => log.push(\"c3\"));\n      ctxClass.addInitializer(() => log.push(\"c4\"));\n    };\n    const methodDec1 = (fn, ctxMethod) => {\n      log.push(\"m2\");\n      if (!assertEq(() => typeof ctxMethod.addInitializer, \"function\")) return;\n      ctxMethod.addInitializer(() => log.push(\"m5\"));\n      ctxMethod.addInitializer(() => log.push(\"m6\"));\n    };\n    const methodDec2 = (fn, ctxMethod) => {\n      log.push(\"m1\");\n      if (!assertEq(() => typeof ctxMethod.addInitializer, \"function\")) return;\n      ctxMethod.addInitializer(() => log.push(\"m3\"));\n      ctxMethod.addInitializer(() => log.push(\"m4\"));\n    };\n    const staticMethodDec1 = (fn, ctxStaticMethod) => {\n      log.push(\"M2\");\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, \"function\")) return;\n      ctxStaticMethod.addInitializer(() => log.push(\"M5\"));\n      ctxStaticMethod.addInitializer(() => log.push(\"M6\"));\n    };\n    const staticMethodDec2 = (fn, ctxStaticMethod) => {\n      log.push(\"M1\");\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, \"function\")) return;\n      ctxStaticMethod.addInitializer(() => log.push(\"M3\"));\n      ctxStaticMethod.addInitializer(() => log.push(\"M4\"));\n    };\n    const fieldDec1 = (value, ctxField) => {\n      log.push(\"f2\");\n      if (!assertEq(() => typeof ctxField.addInitializer, \"function\")) return;\n      ctxField.addInitializer(() => log.push(\"f5\"));\n      ctxField.addInitializer(() => log.push(\"f6\"));\n      return () => {\n        log.push(\"f7\");\n      };\n    };\n    const fieldDec2 = (value, ctxField) => {\n      log.push(\"f1\");\n      if (!assertEq(() => typeof ctxField.addInitializer, \"function\")) return;\n      ctxField.addInitializer(() => log.push(\"f3\"));\n      ctxField.addInitializer(() => log.push(\"f4\"));\n      return () => {\n        log.push(\"f8\");\n      };\n    };\n    const staticFieldDec1 = (value, ctxStaticField) => {\n      log.push(\"F2\");\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, \"function\")) return;\n      ctxStaticField.addInitializer(() => log.push(\"F5\"));\n      ctxStaticField.addInitializer(() => log.push(\"F6\"));\n      return () => {\n        log.push(\"F7\");\n      };\n    };\n    const staticFieldDec2 = (value, ctxStaticField) => {\n      log.push(\"F1\");\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, \"function\")) return;\n      ctxStaticField.addInitializer(() => log.push(\"F3\"));\n      ctxStaticField.addInitializer(() => log.push(\"F4\"));\n      return () => {\n        log.push(\"F8\");\n      };\n    };\n    const getterDec1 = (fn, ctxGetter) => {\n      log.push(\"g2\");\n      if (!assertEq(() => typeof ctxGetter.addInitializer, \"function\")) return;\n      ctxGetter.addInitializer(() => log.push(\"g5\"));\n      ctxGetter.addInitializer(() => log.push(\"g6\"));\n    };\n    const getterDec2 = (fn, ctxGetter) => {\n      log.push(\"g1\");\n      if (!assertEq(() => typeof ctxGetter.addInitializer, \"function\")) return;\n      ctxGetter.addInitializer(() => log.push(\"g3\"));\n      ctxGetter.addInitializer(() => log.push(\"g4\"));\n    };\n    const staticGetterDec1 = (fn, ctxStaticGetter) => {\n      log.push(\"G2\");\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, \"function\")) return;\n      ctxStaticGetter.addInitializer(() => log.push(\"G5\"));\n      ctxStaticGetter.addInitializer(() => log.push(\"G6\"));\n    };\n    const staticGetterDec2 = (fn, ctxStaticGetter) => {\n      log.push(\"G1\");\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, \"function\")) return;\n      ctxStaticGetter.addInitializer(() => log.push(\"G3\"));\n      ctxStaticGetter.addInitializer(() => log.push(\"G4\"));\n    };\n    const setterDec1 = (fn, ctxSetter) => {\n      log.push(\"s2\");\n      if (!assertEq(() => typeof ctxSetter.addInitializer, \"function\")) return;\n      ctxSetter.addInitializer(() => log.push(\"s5\"));\n      ctxSetter.addInitializer(() => log.push(\"s6\"));\n    };\n    const setterDec2 = (fn, ctxSetter) => {\n      log.push(\"s1\");\n      if (!assertEq(() => typeof ctxSetter.addInitializer, \"function\")) return;\n      ctxSetter.addInitializer(() => log.push(\"s3\"));\n      ctxSetter.addInitializer(() => log.push(\"s4\"));\n    };\n    const staticSetterDec1 = (fn, ctxStaticSetter) => {\n      log.push(\"S2\");\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, \"function\")) return;\n      ctxStaticSetter.addInitializer(() => log.push(\"S5\"));\n      ctxStaticSetter.addInitializer(() => log.push(\"S6\"));\n    };\n    const staticSetterDec2 = (fn, ctxStaticSetter) => {\n      log.push(\"S1\");\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, \"function\")) return;\n      ctxStaticSetter.addInitializer(() => log.push(\"S3\"));\n      ctxStaticSetter.addInitializer(() => log.push(\"S4\"));\n    };\n    const accessorDec1 = (target, ctxAccessor) => {\n      log.push(\"a2\");\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, \"function\")) return;\n      ctxAccessor.addInitializer(() => log.push(\"a5\"));\n      ctxAccessor.addInitializer(() => log.push(\"a6\"));\n      return { init() {\n        log.push(\"a7\");\n      } };\n    };\n    const accessorDec2 = (target, ctxAccessor) => {\n      log.push(\"a1\");\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, \"function\")) return;\n      ctxAccessor.addInitializer(() => log.push(\"a3\"));\n      ctxAccessor.addInitializer(() => log.push(\"a4\"));\n      return { init() {\n        log.push(\"a8\");\n      } };\n    };\n    const staticAccessorDec1 = (target, ctxStaticAccessor) => {\n      log.push(\"A2\");\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, \"function\")) return;\n      ctxStaticAccessor.addInitializer(() => log.push(\"A5\"));\n      ctxStaticAccessor.addInitializer(() => log.push(\"A6\"));\n      return { init() {\n        log.push(\"A7\");\n      } };\n    };\n    const staticAccessorDec2 = (target, ctxStaticAccessor) => {\n      log.push(\"A1\");\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, \"function\")) return;\n      ctxStaticAccessor.addInitializer(() => log.push(\"A3\"));\n      ctxStaticAccessor.addInitializer(() => log.push(\"A4\"));\n      return { init() {\n        log.push(\"A8\");\n      } };\n    };\n    log.push(\"start\");\n    _Foo_decorators = [classDec1, classDec2];\n    class Foo2 extends (_a = (log.push(\"extends\"), Object), _method_dec = [methodDec1, methodDec2], _staticMethod_dec = [staticMethodDec1, staticMethodDec2], _field_dec = [fieldDec1, fieldDec2], _staticField_dec = [staticFieldDec1, staticFieldDec2], _getter_dec = [getterDec1, getterDec2], _staticGetter_dec = [staticGetterDec1, staticGetterDec2], _setter_dec = [setterDec1, setterDec2], _staticSetter_dec = [staticSetterDec1, staticSetterDec2], _accessor_dec = [accessorDec1, accessorDec2], _staticAccessor_dec = [staticAccessorDec1, staticAccessorDec2], _a) {\n      constructor() {\n        log.push(\"ctor:start\");\n        super();\n        __runInitializers(_init, 5, this);\n        __privateAdd(this, _Foo_instances);\n        __privateAdd(this, _field, __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n        __privateAdd(this, _accessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n        log.push(\"ctor:end\");\n      }\n    }\n    _init = __decoratorStart(_a);\n    _Foo_instances = new WeakSet();\n    method_fn = function() {\n    };\n    _Foo_static = new WeakSet();\n    staticMethod_fn = function() {\n    };\n    _field = new WeakMap();\n    _staticField = new WeakMap();\n    getter_get = function() {\n      return;\n    };\n    staticGetter_get = function() {\n      return;\n    };\n    setter_set = function(x) {\n    };\n    staticSetter_set = function(x) {\n    };\n    _accessor = new WeakMap();\n    _staticAccessor = new WeakMap();\n    staticMethod_fn = __decorateElement(_init, 25, \"#staticMethod\", _staticMethod_dec, _Foo_static, staticMethod_fn);\n    staticGetter_get = __decorateElement(_init, 26, \"#staticGetter\", _staticGetter_dec, _Foo_static, staticGetter_get);\n    staticSetter_set = __decorateElement(_init, 27, \"#staticSetter\", _staticSetter_dec, _Foo_static, staticSetter_set);\n    _c = __decorateElement(_init, 28, \"#staticAccessor\", _staticAccessor_dec, _Foo_static, _staticAccessor), staticAccessor_get = _c.get, staticAccessor_set = _c.set;\n    method_fn = __decorateElement(_init, 17, \"#method\", _method_dec, _Foo_instances, method_fn);\n    getter_get = __decorateElement(_init, 18, \"#getter\", _getter_dec, _Foo_instances, getter_get);\n    setter_set = __decorateElement(_init, 19, \"#setter\", _setter_dec, _Foo_instances, setter_set);\n    _b = __decorateElement(_init, 20, \"#accessor\", _accessor_dec, _Foo_instances, _accessor), accessor_get = _b.get, accessor_set = _b.set;\n    __decorateElement(_init, 29, \"#staticField\", _staticField_dec, _staticField);\n    __decorateElement(_init, 21, \"#field\", _field_dec, _field);\n    __privateAdd(Foo2, _Foo_static);\n    Foo2 = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, Foo2);\n    __runInitializers(_init, 3, Foo2);\n    log.push(\"static:start\");\n    __privateAdd(Foo2, _staticField, __runInitializers(_init, 16, Foo2)), __runInitializers(_init, 19, Foo2);\n    __privateAdd(Foo2, _staticAccessor, __runInitializers(_init, 8, Foo2)), __runInitializers(_init, 11, Foo2);\n    log.push(\"static:end\");\n    __runInitializers(_init, 1, Foo2);\n    log.push(\"after\");\n    new Foo2();\n    log.push(\"end\");\n    assertEq(() => log + \"\", \"start,extends,M1,M2,G1,G2,S1,S2,A1,A2,m1,m2,g1,g2,s1,s2,a1,a2,F1,F2,f1,f2,c1,c2,M3,M4,M5,M6,G3,G4,G5,G6,S3,S4,S5,S6,static:start,F7,F8,F3,F4,F5,F6,A7,A8,A3,A4,A5,A6,static:end,c3,c4,c5,c6,after,ctor:start,m3,m4,m5,m6,g3,g4,g5,g6,s3,s4,s5,s6,f7,f8,f3,f4,f5,f6,a7,a8,a3,a4,a5,a6,ctor:end,end\");\n  },\n  \"Initializer order (private members, class expression)\": () => {\n    var _staticAccessor_dec, _accessor_dec, _staticSetter_dec, _setter_dec, _staticGetter_dec, _getter_dec, _staticField_dec, _field_dec, _staticMethod_dec, _method_dec, _a, _Foo_decorators, _init, _Foo_instances, method_fn, _Foo_static, _b, staticMethod_fn, _field, _staticField, getter_get, staticGetter_get, setter_set, staticSetter_set, _accessor, _c, accessor_get, accessor_set, _staticAccessor, _d, staticAccessor_get, staticAccessor_set;\n    const log = [];\n    const classDec1 = (cls, ctxClass) => {\n      log.push(\"c2\");\n      if (!assertEq(() => typeof ctxClass.addInitializer, \"function\")) return;\n      ctxClass.addInitializer(() => log.push(\"c5\"));\n      ctxClass.addInitializer(() => log.push(\"c6\"));\n    };\n    const classDec2 = (cls, ctxClass) => {\n      log.push(\"c1\");\n      if (!assertEq(() => typeof ctxClass.addInitializer, \"function\")) return;\n      ctxClass.addInitializer(() => log.push(\"c3\"));\n      ctxClass.addInitializer(() => log.push(\"c4\"));\n    };\n    const methodDec1 = (fn, ctxMethod) => {\n      log.push(\"m2\");\n      if (!assertEq(() => typeof ctxMethod.addInitializer, \"function\")) return;\n      ctxMethod.addInitializer(() => log.push(\"m5\"));\n      ctxMethod.addInitializer(() => log.push(\"m6\"));\n    };\n    const methodDec2 = (fn, ctxMethod) => {\n      log.push(\"m1\");\n      if (!assertEq(() => typeof ctxMethod.addInitializer, \"function\")) return;\n      ctxMethod.addInitializer(() => log.push(\"m3\"));\n      ctxMethod.addInitializer(() => log.push(\"m4\"));\n    };\n    const staticMethodDec1 = (fn, ctxStaticMethod) => {\n      log.push(\"M2\");\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, \"function\")) return;\n      ctxStaticMethod.addInitializer(() => log.push(\"M5\"));\n      ctxStaticMethod.addInitializer(() => log.push(\"M6\"));\n    };\n    const staticMethodDec2 = (fn, ctxStaticMethod) => {\n      log.push(\"M1\");\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, \"function\")) return;\n      ctxStaticMethod.addInitializer(() => log.push(\"M3\"));\n      ctxStaticMethod.addInitializer(() => log.push(\"M4\"));\n    };\n    const fieldDec1 = (value, ctxField) => {\n      log.push(\"f2\");\n      if (!assertEq(() => typeof ctxField.addInitializer, \"function\")) return;\n      ctxField.addInitializer(() => log.push(\"f5\"));\n      ctxField.addInitializer(() => log.push(\"f6\"));\n      return () => {\n        log.push(\"f7\");\n      };\n    };\n    const fieldDec2 = (value, ctxField) => {\n      log.push(\"f1\");\n      if (!assertEq(() => typeof ctxField.addInitializer, \"function\")) return;\n      ctxField.addInitializer(() => log.push(\"f3\"));\n      ctxField.addInitializer(() => log.push(\"f4\"));\n      return () => {\n        log.push(\"f8\");\n      };\n    };\n    const staticFieldDec1 = (value, ctxStaticField) => {\n      log.push(\"F2\");\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, \"function\")) return;\n      ctxStaticField.addInitializer(() => log.push(\"F5\"));\n      ctxStaticField.addInitializer(() => log.push(\"F6\"));\n      return () => {\n        log.push(\"F7\");\n      };\n    };\n    const staticFieldDec2 = (value, ctxStaticField) => {\n      log.push(\"F1\");\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, \"function\")) return;\n      ctxStaticField.addInitializer(() => log.push(\"F3\"));\n      ctxStaticField.addInitializer(() => log.push(\"F4\"));\n      return () => {\n        log.push(\"F8\");\n      };\n    };\n    const getterDec1 = (fn, ctxGetter) => {\n      log.push(\"g2\");\n      if (!assertEq(() => typeof ctxGetter.addInitializer, \"function\")) return;\n      ctxGetter.addInitializer(() => log.push(\"g5\"));\n      ctxGetter.addInitializer(() => log.push(\"g6\"));\n    };\n    const getterDec2 = (fn, ctxGetter) => {\n      log.push(\"g1\");\n      if (!assertEq(() => typeof ctxGetter.addInitializer, \"function\")) return;\n      ctxGetter.addInitializer(() => log.push(\"g3\"));\n      ctxGetter.addInitializer(() => log.push(\"g4\"));\n    };\n    const staticGetterDec1 = (fn, ctxStaticGetter) => {\n      log.push(\"G2\");\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, \"function\")) return;\n      ctxStaticGetter.addInitializer(() => log.push(\"G5\"));\n      ctxStaticGetter.addInitializer(() => log.push(\"G6\"));\n    };\n    const staticGetterDec2 = (fn, ctxStaticGetter) => {\n      log.push(\"G1\");\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, \"function\")) return;\n      ctxStaticGetter.addInitializer(() => log.push(\"G3\"));\n      ctxStaticGetter.addInitializer(() => log.push(\"G4\"));\n    };\n    const setterDec1 = (fn, ctxSetter) => {\n      log.push(\"s2\");\n      if (!assertEq(() => typeof ctxSetter.addInitializer, \"function\")) return;\n      ctxSetter.addInitializer(() => log.push(\"s5\"));\n      ctxSetter.addInitializer(() => log.push(\"s6\"));\n    };\n    const setterDec2 = (fn, ctxSetter) => {\n      log.push(\"s1\");\n      if (!assertEq(() => typeof ctxSetter.addInitializer, \"function\")) return;\n      ctxSetter.addInitializer(() => log.push(\"s3\"));\n      ctxSetter.addInitializer(() => log.push(\"s4\"));\n    };\n    const staticSetterDec1 = (fn, ctxStaticSetter) => {\n      log.push(\"S2\");\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, \"function\")) return;\n      ctxStaticSetter.addInitializer(() => log.push(\"S5\"));\n      ctxStaticSetter.addInitializer(() => log.push(\"S6\"));\n    };\n    const staticSetterDec2 = (fn, ctxStaticSetter) => {\n      log.push(\"S1\");\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, \"function\")) return;\n      ctxStaticSetter.addInitializer(() => log.push(\"S3\"));\n      ctxStaticSetter.addInitializer(() => log.push(\"S4\"));\n    };\n    const accessorDec1 = (target, ctxAccessor) => {\n      log.push(\"a2\");\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, \"function\")) return;\n      ctxAccessor.addInitializer(() => log.push(\"a5\"));\n      ctxAccessor.addInitializer(() => log.push(\"a6\"));\n      return { init() {\n        log.push(\"a7\");\n      } };\n    };\n    const accessorDec2 = (target, ctxAccessor) => {\n      log.push(\"a1\");\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, \"function\")) return;\n      ctxAccessor.addInitializer(() => log.push(\"a3\"));\n      ctxAccessor.addInitializer(() => log.push(\"a4\"));\n      return { init() {\n        log.push(\"a8\");\n      } };\n    };\n    const staticAccessorDec1 = (target, ctxStaticAccessor) => {\n      log.push(\"A2\");\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, \"function\")) return;\n      ctxStaticAccessor.addInitializer(() => log.push(\"A5\"));\n      ctxStaticAccessor.addInitializer(() => log.push(\"A6\"));\n      return { init() {\n        log.push(\"A7\");\n      } };\n    };\n    const staticAccessorDec2 = (target, ctxStaticAccessor) => {\n      log.push(\"A1\");\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, \"function\")) return;\n      ctxStaticAccessor.addInitializer(() => log.push(\"A3\"));\n      ctxStaticAccessor.addInitializer(() => log.push(\"A4\"));\n      return { init() {\n        log.push(\"A8\");\n      } };\n    };\n    log.push(\"start\");\n    const Foo2 = (_Foo_decorators = [classDec1, classDec2], _b = class extends (_a = (log.push(\"extends\"), Object), _method_dec = [methodDec1, methodDec2], _staticMethod_dec = [staticMethodDec1, staticMethodDec2], _field_dec = [fieldDec1, fieldDec2], _staticField_dec = [staticFieldDec1, staticFieldDec2], _getter_dec = [getterDec1, getterDec2], _staticGetter_dec = [staticGetterDec1, staticGetterDec2], _setter_dec = [setterDec1, setterDec2], _staticSetter_dec = [staticSetterDec1, staticSetterDec2], _accessor_dec = [accessorDec1, accessorDec2], _staticAccessor_dec = [staticAccessorDec1, staticAccessorDec2], _a) {\n      constructor() {\n        log.push(\"ctor:start\");\n        super();\n        __runInitializers(_init, 5, this);\n        __privateAdd(this, _Foo_instances);\n        __privateAdd(this, _field, __runInitializers(_init, 20, this)), __runInitializers(_init, 23, this);\n        __privateAdd(this, _accessor, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);\n        log.push(\"ctor:end\");\n      }\n    }, _init = __decoratorStart(_a), _Foo_instances = new WeakSet(), method_fn = function() {\n    }, _Foo_static = new WeakSet(), staticMethod_fn = function() {\n    }, _field = new WeakMap(), _staticField = new WeakMap(), getter_get = function() {\n      return;\n    }, staticGetter_get = function() {\n      return;\n    }, setter_set = function(x) {\n    }, staticSetter_set = function(x) {\n    }, _accessor = new WeakMap(), _staticAccessor = new WeakMap(), staticMethod_fn = __decorateElement(_init, 25, \"#staticMethod\", _staticMethod_dec, _Foo_static, staticMethod_fn), staticGetter_get = __decorateElement(_init, 26, \"#staticGetter\", _staticGetter_dec, _Foo_static, staticGetter_get), staticSetter_set = __decorateElement(_init, 27, \"#staticSetter\", _staticSetter_dec, _Foo_static, staticSetter_set), _d = __decorateElement(_init, 28, \"#staticAccessor\", _staticAccessor_dec, _Foo_static, _staticAccessor), staticAccessor_get = _d.get, staticAccessor_set = _d.set, method_fn = __decorateElement(_init, 17, \"#method\", _method_dec, _Foo_instances, method_fn), getter_get = __decorateElement(_init, 18, \"#getter\", _getter_dec, _Foo_instances, getter_get), setter_set = __decorateElement(_init, 19, \"#setter\", _setter_dec, _Foo_instances, setter_set), _c = __decorateElement(_init, 20, \"#accessor\", _accessor_dec, _Foo_instances, _accessor), accessor_get = _c.get, accessor_set = _c.set, __decorateElement(_init, 29, \"#staticField\", _staticField_dec, _staticField), __decorateElement(_init, 21, \"#field\", _field_dec, _field), __privateAdd(_b, _Foo_static), _b = __decorateElement(_init, 0, \"Foo\", _Foo_decorators, _b), __runInitializers(_init, 3, _b), log.push(\"static:start\"), __privateAdd(_b, _staticField, __runInitializers(_init, 16, _b)), __runInitializers(_init, 19, _b), __privateAdd(_b, _staticAccessor, __runInitializers(_init, 8, _b)), __runInitializers(_init, 11, _b), log.push(\"static:end\"), __runInitializers(_init, 1, _b), _b);\n    log.push(\"after\");\n    new Foo2();\n    log.push(\"end\");\n    assertEq(() => log + \"\", \"start,extends,M1,M2,G1,G2,S1,S2,A1,A2,m1,m2,g1,g2,s1,s2,a1,a2,F1,F2,f1,f2,c1,c2,M3,M4,M5,M6,G3,G4,G5,G6,S3,S4,S5,S6,static:start,F7,F8,F3,F4,F5,F6,A7,A8,A3,A4,A5,A6,static:end,c3,c4,c5,c6,after,ctor:start,m3,m4,m5,m6,g3,g4,g5,g6,s3,s4,s5,s6,f7,f8,f3,f4,f5,f6,a7,a8,a3,a4,a5,a6,ctor:end,end\");\n  }\n};\nfunction prettyPrint(x) {\n  if (x && x.prototype && x.prototype.constructor === x) return \"class\";\n  if (typeof x === \"string\") return JSON.stringify(x);\n  try {\n    return x + \"\";\n  } catch {\n    return \"typeof \" + typeof x;\n  }\n}\nfunction assertEq(callback, expected) {\n  let details;\n  try {\n    let x = callback();\n    if (x === expected) return true;\n    details = `  Expected: ${prettyPrint(expected)}\n  Observed: ${prettyPrint(x)}`;\n  } catch (error) {\n    details = `  Throws: ${error}`;\n  }\n  const code = callback.toString().replace(/^\\(\\) => /, \"\").replace(/\\s+/g, \" \");\n  console.log(`\\u274C ${testName}\n  Code: ${code}\n${details}\n`);\n  failures++;\n  return false;\n}\nfunction assertThrows(callback, expected) {\n  let details;\n  try {\n    let x = callback();\n    details = `  Expected: throws instanceof ${expected.name}\n  Observed: returns ${prettyPrint(x)}`;\n  } catch (error) {\n    if (error instanceof expected) return true;\n    details = `  Expected: throws instanceof ${expected.name}\n  Observed: throws ${error}`;\n  }\n  const code = callback.toString().replace(/^\\(\\) => /, \"\").replace(/\\s+/g, \" \");\n  console.log(`\\u274C ${testName}\n  Code: ${code}\n${details}\n`);\n  failures++;\n  return false;\n}\nlet testName;\nlet failures = 0;\nasync function run() {\n  for (const [name, test] of Object.entries(tests)) {\n    testName = name;\n    try {\n      await test();\n    } catch (err) {\n      console.log(`\\u274C ${name}\n  Throws: ${err}\n`);\n      failures++;\n    }\n  }\n  if (failures > 0) {\n    console.log(`\\u274C ${failures} checks failed`);\n  } else {\n    console.log(`\\u2705 All checks passed`);\n  }\n}\nconst promise = run();\n"
  },
  {
    "path": "scripts/decorator-tests.ts",
    "content": "// Polyfill this in case it's missing\nif (!('metadata' in Symbol as any)) {\n  (Symbol as any).metadata = Symbol('Symbol.metadata')\n}\nif (!(Symbol.metadata in Function)) {\n  Object.defineProperty((Function as any).prototype, Symbol.metadata, { value: null })\n}\n\nconst tests: Record<string, () => Promise<void> | void> = {\n  // Class decorators\n  'Class decorators: Basic statement': () => {\n    let old: { new(): Foo }\n    const dec = (name: string) => (cls: { new(): Foo }, ctx: ClassDecoratorContext) => {\n      assertEq(() => typeof cls, 'function')\n      assertEq(() => cls.name, name)\n      assertEq(() => ctx.kind, 'class')\n      assertEq(() => ctx.name, name)\n      assertEq(() => 'static' in ctx, false)\n      assertEq(() => 'private' in ctx, false)\n      assertEq(() => 'access' in ctx, false)\n      old = cls\n    }\n    @dec('Foo') class Foo { }\n    assertEq(() => Foo, old!)\n  },\n  'Class decorators: Basic expression: Anonymous': () => {\n    let old: { new(): unknown }\n    const dec = (name: string) => (cls: { new(): unknown }, ctx: ClassDecoratorContext) => {\n      assertEq(() => typeof cls, 'function')\n      assertEq(() => cls.name, name)\n      assertEq(() => ctx.kind, 'class')\n      assertEq(() => ctx.name, name)\n      assertEq(() => 'static' in ctx, false)\n      assertEq(() => 'private' in ctx, false)\n      assertEq(() => 'access' in ctx, false)\n      old = cls\n    }\n    const Foo = (x => x)(@dec('') class { })\n    assertEq(() => Foo, old!)\n    const Bar = (x => x)(@dec('Baz') class Baz { })\n    assertEq(() => Bar, old!)\n  },\n  'Class decorators: Basic expression: Property value': () => {\n    let old: { new(): unknown }\n    const dec = (name: string) => (cls: { new(): unknown }, ctx: ClassDecoratorContext) => {\n      assertEq(() => typeof cls, 'function')\n      assertEq(() => cls.name, name)\n      assertEq(() => ctx.kind, 'class')\n      assertEq(() => ctx.name, name)\n      assertEq(() => 'static' in ctx, false)\n      assertEq(() => 'private' in ctx, false)\n      assertEq(() => 'access' in ctx, false)\n      old = cls\n    }\n    const obj = {\n      Foo: @dec('Foo') class { },\n    }\n    assertEq(() => obj.Foo, old!)\n    const obj2 = {\n      Bar: @dec('Baz') class Baz { },\n    }\n    assertEq(() => obj2.Bar, old!)\n  },\n  'Class decorators: Basic expression: Variable initializer': () => {\n    let old: { new(): unknown }\n    const dec = (name: string) => (cls: { new(): unknown }, ctx: ClassDecoratorContext) => {\n      assertEq(() => typeof cls, 'function')\n      assertEq(() => cls.name, name)\n      assertEq(() => ctx.kind, 'class')\n      assertEq(() => ctx.name, name)\n      assertEq(() => 'static' in ctx, false)\n      assertEq(() => 'private' in ctx, false)\n      assertEq(() => 'access' in ctx, false)\n      old = cls\n    }\n    const Foo = @dec('Foo') class { }\n    assertEq(() => Foo, old!)\n    const Bar = @dec('Baz') class Baz { }\n    assertEq(() => Bar, old!)\n  },\n  'Class decorators: Basic expression: Array binding': () => {\n    let old: { new(): unknown }\n    const dec = (name: string) => (cls: { new(): unknown }, ctx: ClassDecoratorContext) => {\n      assertEq(() => typeof cls, 'function')\n      assertEq(() => cls.name, name)\n      assertEq(() => ctx.kind, 'class')\n      assertEq(() => ctx.name, name)\n      assertEq(() => 'static' in ctx, false)\n      assertEq(() => 'private' in ctx, false)\n      assertEq(() => 'access' in ctx, false)\n      old = cls\n    }\n    const [Foo = @dec('Foo') class { }] = []\n    assertEq(() => Foo, old!)\n    const [Bar = @dec('Baz') class Baz { }] = []\n    assertEq(() => Bar, old!)\n  },\n  'Class decorators: Basic expression: Object binding': () => {\n    let old: { new(): unknown }\n    const dec = (name: string) => (cls: { new(): unknown }, ctx: ClassDecoratorContext) => {\n      assertEq(() => typeof cls, 'function')\n      assertEq(() => cls.name, name)\n      assertEq(() => ctx.kind, 'class')\n      assertEq(() => ctx.name, name)\n      assertEq(() => 'static' in ctx, false)\n      assertEq(() => 'private' in ctx, false)\n      assertEq(() => 'access' in ctx, false)\n      old = cls\n    }\n    const { Foo = @dec('Foo') class { } } = {}\n    assertEq(() => Foo, old!)\n    const { Bar = @dec('Baz') class Baz { } } = {}\n    assertEq(() => Bar, old!)\n  },\n  'Class decorators: Basic expression: Assignment initializer': () => {\n    let old: { new(): unknown }\n    const dec = (name: string) => (cls: { new(): unknown }, ctx: ClassDecoratorContext) => {\n      assertEq(() => typeof cls, 'function')\n      assertEq(() => cls.name, name)\n      assertEq(() => ctx.kind, 'class')\n      assertEq(() => ctx.name, name)\n      assertEq(() => 'static' in ctx, false)\n      assertEq(() => 'private' in ctx, false)\n      assertEq(() => 'access' in ctx, false)\n      old = cls\n    }\n    let Foo: { new(): unknown }\n    Foo = @dec('Foo') class { }\n    assertEq(() => Foo, old!)\n    let Bar: { new(): unknown }\n    Bar = @dec('Baz') class Baz { }\n    assertEq(() => Bar, old!)\n  },\n  'Class decorators: Basic expression: Assignment array binding': () => {\n    let old: { new(): unknown }\n    const dec = (name: string) => (cls: { new(): unknown }, ctx: ClassDecoratorContext) => {\n      assertEq(() => typeof cls, 'function')\n      assertEq(() => cls.name, name)\n      assertEq(() => ctx.kind, 'class')\n      assertEq(() => ctx.name, name)\n      assertEq(() => 'static' in ctx, false)\n      assertEq(() => 'private' in ctx, false)\n      assertEq(() => 'access' in ctx, false)\n      old = cls\n    }\n    let Foo: { new(): unknown };\n    [Foo = @dec('Foo') class { }] = []\n    assertEq(() => Foo, old!)\n    let Bar: { new(): unknown };\n    [Bar = @dec('Baz') class Baz { }] = []\n    assertEq(() => Bar, old!)\n  },\n  'Class decorators: Basic expression: Assignment object binding': () => {\n    let old: { new(): unknown }\n    const dec = (name: string) => (cls: { new(): unknown }, ctx: ClassDecoratorContext) => {\n      assertEq(() => typeof cls, 'function')\n      assertEq(() => cls.name, name)\n      assertEq(() => ctx.kind, 'class')\n      assertEq(() => ctx.name, name)\n      assertEq(() => 'static' in ctx, false)\n      assertEq(() => 'private' in ctx, false)\n      assertEq(() => 'access' in ctx, false)\n      old = cls\n    }\n    let Foo: { new(): unknown };\n    ({ Foo = @dec('Foo') class { } } = {})\n    assertEq(() => Foo, old!)\n    let Bar: { new(): unknown };\n    ({ Bar = @dec('Baz') class Baz { } } = {})\n    assertEq(() => Bar, old!)\n  },\n  'Class decorators: Basic expression: Instance field initializer': () => {\n    let old: { new(): unknown }\n    const dec = (name: string) => (cls: { new(): unknown }, ctx: ClassDecoratorContext) => {\n      assertEq(() => typeof cls, 'function')\n      assertEq(() => cls.name, name)\n      assertEq(() => ctx.kind, 'class')\n      assertEq(() => ctx.name, name)\n      assertEq(() => 'static' in ctx, false)\n      assertEq(() => 'private' in ctx, false)\n      assertEq(() => 'access' in ctx, false)\n      old = cls\n    }\n    class Class {\n      Foo = @dec('Foo') class { }\n    }\n    const Foo = new Class().Foo\n    assertEq(() => Foo, old!)\n    class Class2 {\n      Bar = @dec('Baz') class Baz { }\n    }\n    const Bar = new Class2().Bar\n    assertEq(() => Bar, old!)\n  },\n  'Class decorators: Basic expression: Static field initializer': () => {\n    let old: { new(): unknown }\n    const dec = (name: string) => (cls: { new(): unknown }, ctx: ClassDecoratorContext) => {\n      assertEq(() => typeof cls, 'function')\n      assertEq(() => cls.name, name)\n      assertEq(() => ctx.kind, 'class')\n      assertEq(() => ctx.name, name)\n      assertEq(() => 'static' in ctx, false)\n      assertEq(() => 'private' in ctx, false)\n      assertEq(() => 'access' in ctx, false)\n      old = cls\n    }\n    class Class {\n      static Foo = @dec('Foo') class { }\n    }\n    assertEq(() => Class.Foo, old!)\n    class Class2 {\n      static Bar = @dec('Baz') class Baz { }\n    }\n    assertEq(() => Class2.Bar, old!)\n  },\n  'Class decorators: Basic expression: Instance auto-accessor initializer': () => {\n    let old: { new(): unknown }\n    const dec = (name: string) => (cls: { new(): unknown }, ctx: ClassDecoratorContext) => {\n      assertEq(() => typeof cls, 'function')\n      assertEq(() => cls.name, name)\n      assertEq(() => ctx.kind, 'class')\n      assertEq(() => ctx.name, name)\n      assertEq(() => 'static' in ctx, false)\n      assertEq(() => 'private' in ctx, false)\n      assertEq(() => 'access' in ctx, false)\n      old = cls\n    }\n    class Class {\n      accessor Foo = @dec('Foo') class { }\n    }\n    const Foo = new Class().Foo\n    assertEq(() => Foo, old!)\n    class Class2 {\n      accessor Bar = @dec('Baz') class Baz { }\n    }\n    const Bar = new Class2().Bar\n    assertEq(() => Bar, old!)\n  },\n  'Class decorators: Basic expression: Static auto-accessor initializer': () => {\n    let old: { new(): unknown }\n    const dec = (name: string) => (cls: { new(): unknown }, ctx: ClassDecoratorContext) => {\n      assertEq(() => typeof cls, 'function')\n      assertEq(() => cls.name, name)\n      assertEq(() => ctx.kind, 'class')\n      assertEq(() => ctx.name, name)\n      assertEq(() => 'static' in ctx, false)\n      assertEq(() => 'private' in ctx, false)\n      assertEq(() => 'access' in ctx, false)\n      old = cls\n    }\n    class Class {\n      static accessor Foo = @dec('Foo') class { }\n    }\n    assertEq(() => Class.Foo, old!)\n    class Class2 {\n      static accessor Bar = @dec('Baz') class Baz { }\n    }\n    assertEq(() => Class2.Bar, old!)\n  },\n  'Class decorators: Order': () => {\n    const log: number[] = []\n    let Bar: { new(): Foo }\n    let Baz: { new(): Foo }\n    const dec1 = (cls: { new(): Foo }, ctx: ClassDecoratorContext) => {\n      log.push(2)\n      Bar = function () {\n        log.push(4)\n        return new cls\n      } as any\n      return Bar\n    }\n    const dec2 = (cls: { new(): Foo }, ctx: ClassDecoratorContext) => {\n      log.push(1)\n      Baz = function () {\n        log.push(5)\n        return new cls\n      } as any\n      return Baz\n    }\n    log.push(0)\n    @dec1 @dec2 class Foo {\n      constructor() { log.push(6) }\n    }\n    log.push(3)\n    new Foo\n    log.push(7)\n    assertEq(() => Foo, Bar!)\n    assertEq(() => log + '', '0,1,2,3,4,5,6,7')\n  },\n  'Class decorators: Return null': () => {\n    assertThrows(() => {\n      const dec = (cls: { new(): Foo }, ctx: ClassDecoratorContext): any => {\n        return null\n      }\n      @dec class Foo { }\n    }, TypeError)\n  },\n  'Class decorators: Return object': () => {\n    assertThrows(() => {\n      const dec = (cls: { new(): Foo }, ctx: ClassDecoratorContext): any => {\n        return {}\n      }\n      @dec class Foo { }\n    }, TypeError)\n  },\n  'Class decorators: Extra initializer': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (cls: { new(): Foo }, ctx: ClassDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    @dec @dec class Foo { }\n    assertEq(() => got.this, Foo)\n    assertEq(() => got.args.length, 0)\n  },\n\n  // Method decorators\n  'Method decorators: Basic (instance method)': () => {\n    const old: Record<PropertyKey, (this: Foo) => void> = {}\n    const dec = (key: PropertyKey, name: string) =>\n      (fn: (this: Foo) => void, ctx: ClassMethodDecoratorContext) => {\n        assertEq(() => typeof fn, 'function')\n        assertEq(() => fn.name, name)\n        assertEq(() => ctx.kind, 'method')\n        assertEq(() => ctx.name, key)\n        assertEq(() => ctx.static, false)\n        assertEq(() => ctx.private, false)\n        assertEq(() => ctx.access.has({ [key]: false }), true)\n        assertEq(() => ctx.access.has({ bar: true }), false)\n        assertEq(() => (ctx.access.get as any)({ [key]: 123 }), 123)\n        assertEq(() => 'set' in ctx.access, false)\n        old[key] = fn\n      }\n    const bar = Symbol('bar')\n    const baz = Symbol()\n    class Foo {\n      @dec('foo', 'foo') foo() { }\n      @dec(bar, '[bar]') [bar]() { }\n      @dec(baz, '') [baz]() { }\n    }\n    assertEq(() => Foo.prototype.foo, old['foo'])\n    assertEq(() => Foo.prototype[bar], old[bar])\n    assertEq(() => Foo.prototype[baz], old[baz])\n  },\n  'Method decorators: Basic (static method)': () => {\n    const old: Record<PropertyKey, (this: typeof Foo) => void> = {}\n    const dec = (key: PropertyKey, name: string) =>\n      (fn: (this: typeof Foo) => void, ctx: ClassMethodDecoratorContext) => {\n        assertEq(() => typeof fn, 'function')\n        assertEq(() => fn.name, name)\n        assertEq(() => ctx.kind, 'method')\n        assertEq(() => ctx.name, key)\n        assertEq(() => ctx.static, true)\n        assertEq(() => ctx.private, false)\n        assertEq(() => ctx.access.has({ [key]: false }), true)\n        assertEq(() => ctx.access.has({ bar: true }), false)\n        assertEq(() => (ctx.access.get as any)({ [key]: 123 }), 123)\n        assertEq(() => 'set' in ctx.access, false)\n        old[key] = fn\n      }\n    const bar = Symbol('bar')\n    const baz = Symbol()\n    class Foo {\n      @dec('foo', 'foo') static foo() { }\n      @dec(bar, '[bar]') static [bar]() { }\n      @dec(baz, '') static [baz]() { }\n    }\n    assertEq(() => Foo.foo, old['foo'])\n    assertEq(() => Foo[bar], old[bar])\n    assertEq(() => Foo[baz], old[baz])\n  },\n  'Method decorators: Basic (private instance method)': () => {\n    let old: (this: Foo) => void\n    let lateAsserts: () => void\n    const dec = (fn: (this: Foo) => void, ctx: ClassMethodDecoratorContext) => {\n      assertEq(() => typeof fn, 'function')\n      assertEq(() => fn.name, '#foo')\n      assertEq(() => ctx.kind, 'method')\n      assertEq(() => ctx.name, '#foo')\n      assertEq(() => ctx.static, false)\n      assertEq(() => ctx.private, true)\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(new Foo), true)\n        assertEq(() => ctx.access.has({}), false)\n        assertEq(() => ctx.access.get(new Foo), $foo)\n        assertEq(() => 'set' in ctx.access, false)\n      }\n      old = fn\n    }\n    let $foo: Function\n    class Foo {\n      @dec #foo() { }\n      static { $foo = new Foo().#foo }\n    }\n    assertEq(() => $foo, old!)\n    lateAsserts!()\n  },\n  'Method decorators: Basic (private static method)': () => {\n    let old: (this: typeof Foo) => void\n    let lateAsserts: () => void\n    const dec = (fn: (this: typeof Foo) => void, ctx: ClassMethodDecoratorContext) => {\n      assertEq(() => typeof fn, 'function')\n      assertEq(() => fn.name, '#foo')\n      assertEq(() => ctx.kind, 'method')\n      assertEq(() => ctx.name, '#foo')\n      assertEq(() => ctx.static, true)\n      assertEq(() => ctx.private, true)\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(Foo), true)\n        assertEq(() => ctx.access.has({}), false)\n        assertEq(() => ctx.access.get(Foo), $foo)\n        assertEq(() => 'set' in ctx.access, false)\n      }\n      old = fn\n    }\n    let $foo: Function\n    class Foo {\n      @dec static #foo() { }\n      static { $foo = this.#foo }\n    }\n    assertEq(() => $foo, old!)\n    lateAsserts!()\n  },\n  'Method decorators: Shim (instance method)': () => {\n    let bar: (this: Foo) => number\n    const dec = (fn: (this: Foo) => number, ctx: ClassMethodDecoratorContext) => {\n      bar = function () { return fn.call(this) + 1 }\n      return bar\n    }\n    class Foo {\n      bar = 123\n      @dec foo() { return this.bar }\n    }\n    assertEq(() => Foo.prototype.foo, bar!)\n    assertEq(() => new Foo().foo(), 124)\n  },\n  'Method decorators: Shim (static method)': () => {\n    let bar: (this: typeof Foo) => number\n    const dec = (fn: (this: typeof Foo) => number, ctx: ClassMethodDecoratorContext) => {\n      bar = function () { return fn.call(this) + 1 }\n      return bar\n    }\n    class Foo {\n      static bar = 123\n      @dec static foo() { return this.bar }\n    }\n    assertEq(() => Foo.foo, bar!)\n    assertEq(() => Foo.foo(), 124)\n  },\n  'Method decorators: Shim (private instance method)': () => {\n    let bar: (this: Foo) => number\n    const dec = (fn: (this: Foo) => number, ctx: ClassMethodDecoratorContext) => {\n      bar = function () { return fn.call(this) + 1 }\n      return bar\n    }\n    let $foo: (this: Foo) => number\n    class Foo {\n      bar = 123\n      @dec #foo() { return this.bar }\n      static { $foo = new Foo().#foo }\n    }\n    assertEq(() => $foo, bar!)\n    assertEq(() => bar.call(new Foo), 124)\n  },\n  'Method decorators: Shim (private static method)': () => {\n    let bar: (this: typeof Foo) => number\n    const dec = (fn: (this: typeof Foo) => number, ctx: ClassMethodDecoratorContext) => {\n      bar = function () { return fn.call(this) + 1 }\n      return bar\n    }\n    let $foo: (this: Foo) => number\n    class Foo {\n      static bar = 123\n      @dec static #foo() { return this.bar }\n      static { $foo = this.#foo }\n    }\n    assertEq(() => $foo, bar!)\n    assertEq(() => bar.call(Foo), 124)\n  },\n  'Method decorators: Order (instance method)': () => {\n    const log: number[] = []\n    let bar: (this: Foo) => number\n    let baz: (this: Foo) => number\n    const dec1 = (fn: (this: Foo) => number, ctx: ClassMethodDecoratorContext) => {\n      log.push(2)\n      bar = function () {\n        log.push(4)\n        return fn.call(this)\n      }\n      return bar\n    }\n    const dec2 = (fn: (this: Foo) => number, ctx: ClassMethodDecoratorContext) => {\n      log.push(1)\n      baz = function () {\n        log.push(5)\n        return fn.call(this)\n      }\n      return baz\n    }\n    log.push(0)\n    class Foo {\n      @dec1 @dec2 foo() { return log.push(6) }\n    }\n    log.push(3)\n    new Foo().foo()\n    log.push(7)\n    assertEq(() => Foo.prototype.foo, bar!)\n    assertEq(() => log + '', '0,1,2,3,4,5,6,7')\n  },\n  'Method decorators: Order (static method)': () => {\n    const log: number[] = []\n    let bar: (this: typeof Foo) => number\n    let baz: (this: typeof Foo) => number\n    const dec1 = (fn: (this: typeof Foo) => number, ctx: ClassMethodDecoratorContext) => {\n      log.push(2)\n      bar = function () {\n        log.push(4)\n        return fn.call(this)\n      }\n      return bar\n    }\n    const dec2 = (fn: (this: typeof Foo) => number, ctx: ClassMethodDecoratorContext) => {\n      log.push(1)\n      baz = function () {\n        log.push(5)\n        return fn.call(this)\n      }\n      return baz\n    }\n    log.push(0)\n    class Foo {\n      @dec1 @dec2 static foo() { return log.push(6) }\n    }\n    log.push(3)\n    Foo.foo()\n    log.push(7)\n    assertEq(() => Foo.foo, bar!)\n    assertEq(() => log + '', '0,1,2,3,4,5,6,7')\n  },\n  'Method decorators: Order (private instance method)': () => {\n    const log: number[] = []\n    let bar: (this: Foo) => number\n    let baz: (this: Foo) => number\n    const dec1 = (fn: (this: Foo) => number, ctx: ClassMethodDecoratorContext) => {\n      log.push(2)\n      bar = function () {\n        log.push(4)\n        return fn.call(this)\n      }\n      return bar\n    }\n    const dec2 = (fn: (this: Foo) => number, ctx: ClassMethodDecoratorContext) => {\n      log.push(1)\n      baz = function () {\n        log.push(5)\n        return fn.call(this)\n      }\n      return baz\n    }\n    log.push(0)\n    let $foo: Function\n    class Foo {\n      @dec1 @dec2 #foo() { return log.push(6) }\n      static { $foo = new Foo().#foo }\n    }\n    log.push(3)\n    $foo.call(new Foo)\n    log.push(7)\n    assertEq(() => $foo, bar!)\n    assertEq(() => log + '', '0,1,2,3,4,5,6,7')\n  },\n  'Method decorators: Order (private static method)': () => {\n    const log: number[] = []\n    let bar: (this: typeof Foo) => number\n    let baz: (this: typeof Foo) => number\n    const dec1 = (fn: (this: typeof Foo) => number, ctx: ClassMethodDecoratorContext) => {\n      log.push(2)\n      bar = function () {\n        log.push(4)\n        return fn.call(this)\n      }\n      return bar\n    }\n    const dec2 = (fn: (this: typeof Foo) => number, ctx: ClassMethodDecoratorContext) => {\n      log.push(1)\n      baz = function () {\n        log.push(5)\n        return fn.call(this)\n      }\n      return baz\n    }\n    log.push(0)\n    let $foo: (this: Foo) => number\n    class Foo {\n      @dec1 @dec2 static #foo() { return log.push(6) }\n      static { $foo = Foo.#foo }\n    }\n    log.push(3)\n    $foo.call(Foo)\n    log.push(7)\n    assertEq(() => $foo, bar!)\n    assertEq(() => log + '', '0,1,2,3,4,5,6,7')\n  },\n  'Method decorators: Return null (instance method)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: Foo) => void, ctx: ClassMethodDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec foo() { } }\n    }, TypeError)\n  },\n  'Method decorators: Return null (static method)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: typeof Foo) => void, ctx: ClassMethodDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec static foo() { } }\n    }, TypeError)\n  },\n  'Method decorators: Return null (private instance method)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: Foo) => void, ctx: ClassMethodDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec #foo() { } }\n    }, TypeError)\n  },\n  'Method decorators: Return null (private static method)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: typeof Foo) => void, ctx: ClassMethodDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec static #foo() { } }\n    }, TypeError)\n  },\n  'Method decorators: Return object (instance method)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: Foo) => void, ctx: ClassMethodDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec foo() { } }\n    }, TypeError)\n  },\n  'Method decorators: Return object (static method)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: typeof Foo) => void, ctx: ClassMethodDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec static foo() { } }\n    }, TypeError)\n  },\n  'Method decorators: Return object (private instance method)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: Foo) => void, ctx: ClassMethodDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec #foo() { } }\n    }, TypeError)\n  },\n  'Method decorators: Return object (private static method)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: typeof Foo) => void, ctx: ClassMethodDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec static #foo() { } }\n    }, TypeError)\n  },\n  'Method decorators: Extra initializer (instance method)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (fn: (this: Foo) => void, ctx: ClassMethodDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec foo() { } }\n    assertEq(() => got, undefined)\n    const instance = new Foo\n    assertEq(() => got.this, instance)\n    assertEq(() => got.args.length, 0)\n  },\n  'Method decorators: Extra initializer (static method)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (fn: (this: typeof Foo) => void, ctx: ClassMethodDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec static foo() { } }\n    assertEq(() => got.this, Foo)\n    assertEq(() => got.args.length, 0)\n  },\n  'Method decorators: Extra initializer (private instance method)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (fn: (this: Foo) => void, ctx: ClassMethodDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec #foo() { } }\n    assertEq(() => got, undefined)\n    const instance = new Foo\n    assertEq(() => got.this, instance)\n    assertEq(() => got.args.length, 0)\n  },\n  'Method decorators: Extra initializer (private static method)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (fn: (this: typeof Foo) => void, ctx: ClassMethodDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec static #foo() { } }\n    assertEq(() => got.this, Foo)\n    assertEq(() => got.args.length, 0)\n  },\n\n  // Field decorators\n  'Field decorators: Basic (instance field)': () => {\n    const dec = (key: PropertyKey) =>\n      (value: undefined, ctx: ClassFieldDecoratorContext) => {\n        assertEq(() => value, undefined)\n        assertEq(() => ctx.kind, 'field')\n        assertEq(() => ctx.name, key)\n        assertEq(() => ctx.static, false)\n        assertEq(() => ctx.private, false)\n        assertEq(() => ctx.access.has({ [key]: false }), true)\n        assertEq(() => ctx.access.has({ bar: true }), false)\n        assertEq(() => ctx.access.get({ [key]: 123 }), 123)\n        assertEq(() => {\n          const obj: any = {}\n          ctx.access.set(obj, 321)\n          return obj[key]\n        }, 321)\n      }\n    const bar = Symbol('bar')\n    const baz = Symbol()\n    class Foo {\n      @dec('foo') foo = 123\n      @dec(bar) [bar] = 123\n      @dec(baz) [baz] = 123\n    }\n    assertEq(() => new Foo().foo, 123)\n    assertEq(() => new Foo()[bar], 123)\n    assertEq(() => new Foo()[baz], 123)\n  },\n  'Field decorators: Basic (static field)': () => {\n    const dec = (key: PropertyKey) =>\n      (value: undefined, ctx: ClassFieldDecoratorContext) => {\n        assertEq(() => value, undefined)\n        assertEq(() => ctx.kind, 'field')\n        assertEq(() => ctx.name, key)\n        assertEq(() => ctx.static, true)\n        assertEq(() => ctx.private, false)\n        assertEq(() => ctx.access.has({ [key]: false }), true)\n        assertEq(() => ctx.access.has({ bar: true }), false)\n        assertEq(() => ctx.access.get({ [key]: 123 }), 123)\n        assertEq(() => {\n          const obj: any = {}\n          ctx.access.set(obj, 321)\n          return obj[key]\n        }, 321)\n      }\n    const bar = Symbol('bar')\n    const baz = Symbol()\n    class Foo {\n      @dec('foo') static foo = 123\n      @dec(bar) static [bar] = 123\n      @dec(baz) static [baz] = 123\n    }\n    assertEq(() => Foo.foo, 123)\n    assertEq(() => Foo[bar], 123)\n    assertEq(() => Foo[baz], 123)\n  },\n  'Field decorators: Basic (private instance field)': () => {\n    let lateAsserts: () => void\n    const dec = (value: undefined, ctx: ClassFieldDecoratorContext) => {\n      assertEq(() => value, undefined)\n      assertEq(() => ctx.kind, 'field')\n      assertEq(() => ctx.name, '#foo')\n      assertEq(() => ctx.static, false)\n      assertEq(() => ctx.private, true)\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(new Foo), true)\n        assertEq(() => ctx.access.has({}), false)\n        assertEq(() => ctx.access.get(new Foo), 123)\n        assertEq(() => {\n          const obj = new Foo\n          ctx.access.set(obj, 321)\n          return get$foo(obj)\n        }, 321)\n      }\n    }\n    let get$foo: (x: Foo) => number\n    class Foo {\n      @dec #foo = 123\n      static { get$foo = x => x.#foo }\n    }\n    assertEq(() => get$foo(new Foo()), 123)\n    lateAsserts!()\n  },\n  'Field decorators: Basic (private static field)': () => {\n    let lateAsserts: () => void\n    const dec = (value: undefined, ctx: ClassFieldDecoratorContext) => {\n      assertEq(() => value, undefined)\n      assertEq(() => ctx.kind, 'field')\n      assertEq(() => ctx.name, '#foo')\n      assertEq(() => ctx.static, true)\n      assertEq(() => ctx.private, true)\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(Foo), true)\n        assertEq(() => ctx.access.has({}), false)\n        assertEq(() => ctx.access.get(Foo), 123)\n        assertEq(() => {\n          ctx.access.set(Foo, 321)\n          return get$foo(Foo)\n        }, 321)\n      }\n    }\n    let get$foo: (x: typeof Foo) => number\n    class Foo {\n      @dec static #foo = 123\n      static { get$foo = x => x.#foo }\n    }\n    assertEq(() => get$foo(Foo), 123)\n    lateAsserts!()\n  },\n  'Field decorators: Shim (instance field)': () => {\n    let log: (boolean | number)[] = []\n    const dec = (value: undefined, ctx: ClassFieldDecoratorContext) => {\n      return function (this: Foo, x: number) {\n        assertEq(() => this instanceof Foo, true)\n        return log.push('foo' in this, 'bar' in this, x)\n      }\n    }\n    class Foo {\n      @dec foo = 123\n      @dec bar!: number\n    }\n    assertEq(() => log + '', '')\n    var obj = new Foo\n    assertEq(() => obj.foo, 3)\n    assertEq(() => obj.bar, 6)\n    assertEq(() => log + '', 'false,false,123,true,false,')\n  },\n  'Field decorators: Shim (static field)': () => {\n    let foo: typeof Foo\n    let log: (boolean | number)[] = []\n    const dec = (value: undefined, ctx: ClassFieldDecoratorContext) => {\n      return function (this: typeof Foo, x: number) {\n        assertEq(() => this, foo)\n        return log.push('foo' in this, 'bar' in this, x)\n      }\n    }\n    assertEq(() => log + '', '')\n    class Foo {\n      static {\n        foo = Foo\n      }\n      @dec static foo = 123\n      @dec static bar: number\n    }\n    assertEq(() => Foo.foo, 3)\n    assertEq(() => Foo.bar, 6)\n    assertEq(() => log + '', 'false,false,123,true,false,')\n  },\n  'Field decorators: Shim (private instance field)': () => {\n    let log: (boolean | number)[] = []\n    const dec = (value: undefined, ctx: ClassFieldDecoratorContext) => {\n      return function (this: Foo, x: number) {\n        assertEq(() => this instanceof Foo, true)\n        return log.push(has$foo(this), has$bar(this), x)\n      }\n    }\n    let has$foo: (x: Foo) => boolean\n    let has$bar: (x: Foo) => boolean\n    let get$foo: (x: Foo) => number\n    let get$bar: (x: Foo) => number\n    class Foo {\n      @dec #foo = 123\n      @dec #bar!: number\n      static {\n        has$foo = x => #foo in x\n        has$bar = x => #bar in x\n        get$foo = x => x.#foo\n        get$bar = x => x.#bar\n      }\n    }\n    assertEq(() => log + '', '')\n    var obj = new Foo\n    assertEq(() => get$foo(obj), 3)\n    assertEq(() => get$bar(obj), 6)\n    assertEq(() => log + '', 'false,false,123,true,false,')\n  },\n  'Field decorators: Shim (private static field)': () => {\n    let foo: typeof Foo\n    let log: (boolean | number)[] = []\n    const dec = (value: undefined, ctx: ClassFieldDecoratorContext) => {\n      return function (this: typeof Foo, x: number) {\n        assertEq(() => this, foo)\n        return log.push(has$foo(this), has$bar(this), x)\n      }\n    }\n    assertEq(() => log + '', '')\n    let has$foo: (x: typeof Foo) => boolean\n    let has$bar: (x: typeof Foo) => boolean\n    let get$foo: (x: typeof Foo) => number\n    let get$bar: (x: typeof Foo) => number\n    class Foo {\n      static {\n        foo = Foo\n        has$foo = x => #foo in x\n        has$bar = x => #bar in x\n        get$foo = x => x.#foo\n        get$bar = x => x.#bar\n      }\n      @dec static #foo = 123\n      @dec static #bar: number\n    }\n    assertEq(() => get$foo(Foo), 3)\n    assertEq(() => get$bar(Foo), 6)\n    assertEq(() => log + '', 'false,false,123,true,false,')\n  },\n  'Field decorators: Order (instance field)': () => {\n    const log: number[] = []\n    const dec1 = (value: undefined, ctx: ClassFieldDecoratorContext) => {\n      log.push(2)\n      return () => log.push(4)\n    }\n    const dec2 = (value: undefined, ctx: ClassFieldDecoratorContext) => {\n      log.push(1)\n      return () => log.push(5)\n    }\n    log.push(0)\n    class Foo {\n      @dec1 @dec2 foo = 123\n    }\n    log.push(3)\n    var obj = new Foo()\n    log.push(6)\n    assertEq(() => obj.foo, 6)\n    assertEq(() => log + '', '0,1,2,3,4,5,6')\n  },\n  'Field decorators: Order (static field)': () => {\n    const log: number[] = []\n    const dec1 = (value: undefined, ctx: ClassFieldDecoratorContext) => {\n      log.push(2)\n      return () => log.push(3)\n    }\n    const dec2 = (value: undefined, ctx: ClassFieldDecoratorContext) => {\n      log.push(1)\n      return () => log.push(4)\n    }\n    log.push(0)\n    class Foo {\n      @dec1 @dec2 static foo = 123\n    }\n    log.push(5)\n    assertEq(() => Foo.foo, 5)\n    assertEq(() => log + '', '0,1,2,3,4,5')\n  },\n  'Field decorators: Order (private instance field)': () => {\n    const log: number[] = []\n    const dec1 = (value: undefined, ctx: ClassFieldDecoratorContext) => {\n      log.push(2)\n      return () => log.push(4)\n    }\n    const dec2 = (value: undefined, ctx: ClassFieldDecoratorContext) => {\n      log.push(1)\n      return () => log.push(5)\n    }\n    log.push(0)\n    let get$foo: (x: Foo) => number\n    class Foo {\n      @dec1 @dec2 #foo = 123\n      static { get$foo = x => x.#foo }\n    }\n    log.push(3)\n    var obj = new Foo()\n    log.push(6)\n    assertEq(() => get$foo(obj), 6)\n    assertEq(() => log + '', '0,1,2,3,4,5,6')\n  },\n  'Field decorators: Order (private static field)': () => {\n    const log: number[] = []\n    const dec1 = (value: undefined, ctx: ClassFieldDecoratorContext) => {\n      log.push(2)\n      return () => log.push(3)\n    }\n    const dec2 = (value: undefined, ctx: ClassFieldDecoratorContext) => {\n      log.push(1)\n      return () => log.push(4)\n    }\n    log.push(0)\n    let get$foo: (x: typeof Foo) => number\n    class Foo {\n      @dec1 @dec2 static #foo = 123\n      static { get$foo = x => x.#foo }\n    }\n    log.push(5)\n    assertEq(() => get$foo(Foo), 5)\n    assertEq(() => log + '', '0,1,2,3,4,5')\n  },\n  'Field decorators: Return null (instance field)': () => {\n    assertThrows(() => {\n      const dec = (value: undefined, ctx: ClassFieldDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec foo: undefined }\n    }, TypeError)\n  },\n  'Field decorators: Return null (static field)': () => {\n    assertThrows(() => {\n      const dec = (value: undefined, ctx: ClassFieldDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec static foo: undefined }\n    }, TypeError)\n  },\n  'Field decorators: Return null (private instance field)': () => {\n    assertThrows(() => {\n      const dec = (value: undefined, ctx: ClassFieldDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec #foo: undefined }\n    }, TypeError)\n  },\n  'Field decorators: Return null (private static field)': () => {\n    assertThrows(() => {\n      const dec = (value: undefined, ctx: ClassFieldDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec static #foo: undefined }\n    }, TypeError)\n  },\n  'Field decorators: Return object (instance field)': () => {\n    assertThrows(() => {\n      const dec = (value: undefined, ctx: ClassFieldDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec foo: undefined }\n    }, TypeError)\n  },\n  'Field decorators: Return object (static field)': () => {\n    assertThrows(() => {\n      const dec = (value: undefined, ctx: ClassFieldDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec static foo: undefined }\n    }, TypeError)\n  },\n  'Field decorators: Return object (private instance field)': () => {\n    assertThrows(() => {\n      const dec = (value: undefined, ctx: ClassFieldDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec #foo: undefined }\n    }, TypeError)\n  },\n  'Field decorators: Return object (private static field)': () => {\n    assertThrows(() => {\n      const dec = (value: undefined, ctx: ClassFieldDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec static #foo: undefined }\n    }, TypeError)\n  },\n  'Field decorators: Extra initializer (instance field)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (value: undefined, ctx: ClassFieldDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec foo: undefined }\n    assertEq(() => got, undefined)\n    const instance = new Foo\n    assertEq(() => got.this, instance)\n    assertEq(() => got.args.length, 0)\n  },\n  'Field decorators: Extra initializer (static field)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (value: undefined, ctx: ClassFieldDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec static foo: undefined }\n    assertEq(() => got.this, Foo)\n    assertEq(() => got.args.length, 0)\n  },\n  'Field decorators: Extra initializer (private instance field)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (value: undefined, ctx: ClassFieldDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec #foo: undefined }\n    assertEq(() => got, undefined)\n    const instance = new Foo\n    assertEq(() => got.this, instance)\n    assertEq(() => got.args.length, 0)\n  },\n  'Field decorators: Extra initializer (private static field)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (value: undefined, ctx: ClassFieldDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec static #foo: undefined }\n    assertEq(() => got.this, Foo)\n    assertEq(() => got.args.length, 0)\n  },\n\n  // Getter decorators\n  'Getter decorators: Basic (instance getter)': () => {\n    const dec = (key: PropertyKey, name: string) =>\n      (fn: (this: Foo) => number, ctx: ClassGetterDecoratorContext) => {\n        assertEq(() => typeof fn, 'function')\n        assertEq(() => fn.name, name)\n        assertEq(() => ctx.kind, 'getter')\n        assertEq(() => ctx.name, key)\n        assertEq(() => ctx.static, false)\n        assertEq(() => ctx.private, false)\n        assertEq(() => ctx.access.has({ [key]: false }), true)\n        assertEq(() => ctx.access.has({ bar: true }), false)\n        assertEq(() => ctx.access.get({ [key]: 123 }), 123)\n        assertEq(() => 'set' in ctx.access, false)\n      }\n    const bar = Symbol('bar')\n    const baz = Symbol()\n    class Foo {\n      bar = 123\n      @dec('foo', 'get foo') get foo() { return this.bar }\n      @dec(bar, 'get [bar]') get [bar]() { return this.bar }\n      @dec(baz, 'get ') get [baz]() { return this.bar }\n    }\n    assertEq(() => new Foo().foo, 123)\n    assertEq(() => new Foo()[bar], 123)\n    assertEq(() => new Foo()[baz], 123)\n  },\n  'Getter decorators: Basic (static getter)': () => {\n    const dec = (key: PropertyKey, name: string) =>\n      (fn: (this: typeof Foo) => number, ctx: ClassGetterDecoratorContext) => {\n        assertEq(() => typeof fn, 'function')\n        assertEq(() => fn.name, name)\n        assertEq(() => ctx.kind, 'getter')\n        assertEq(() => ctx.name, key)\n        assertEq(() => ctx.static, true)\n        assertEq(() => ctx.private, false)\n        assertEq(() => ctx.access.has({ [key]: false }), true)\n        assertEq(() => ctx.access.has({ bar: true }), false)\n        assertEq(() => ctx.access.get({ [key]: 123 }), 123)\n        assertEq(() => 'set' in ctx.access, false)\n      }\n    const bar = Symbol('bar')\n    const baz = Symbol()\n    class Foo {\n      static bar = 123\n      @dec('foo', 'get foo') static get foo() { return this.bar }\n      @dec(bar, 'get [bar]') static get [bar]() { return this.bar }\n      @dec(baz, 'get ') static get [baz]() { return this.bar }\n    }\n    assertEq(() => Foo.foo, 123)\n    assertEq(() => Foo[bar], 123)\n    assertEq(() => Foo[baz], 123)\n  },\n  'Getter decorators: Basic (private instance getter)': () => {\n    let lateAsserts: () => void\n    const dec = (fn: (this: Foo) => number, ctx: ClassGetterDecoratorContext) => {\n      assertEq(() => typeof fn, 'function')\n      assertEq(() => fn.name, 'get #foo')\n      assertEq(() => ctx.kind, 'getter')\n      assertEq(() => ctx.name, '#foo')\n      assertEq(() => ctx.static, false)\n      assertEq(() => ctx.private, true)\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(new Foo), true)\n        assertEq(() => ctx.access.has({}), false)\n        assertEq(() => ctx.access.get(new Foo), 123)\n        assertEq(() => 'set' in ctx.access, false)\n      }\n    }\n    let get$foo: (x: Foo) => number\n    class Foo {\n      #bar = 123\n      @dec get #foo() { return this.#bar }\n      static { get$foo = x => x.#foo }\n    }\n    assertEq(() => get$foo(new Foo), 123)\n    lateAsserts!()\n  },\n  'Getter decorators: Basic (private static getter)': () => {\n    let lateAsserts: () => void\n    const dec = (fn: (this: typeof Foo) => number, ctx: ClassGetterDecoratorContext) => {\n      assertEq(() => typeof fn, 'function')\n      assertEq(() => fn.name, 'get #foo')\n      assertEq(() => ctx.kind, 'getter')\n      assertEq(() => ctx.name, '#foo')\n      assertEq(() => ctx.static, true)\n      assertEq(() => ctx.private, true)\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(Foo), true)\n        assertEq(() => ctx.access.has({}), false)\n        assertEq(() => ctx.access.get(Foo), 123)\n        assertEq(() => 'set' in ctx.access, false)\n      }\n    }\n    let get$foo: (x: typeof Foo) => number\n    class Foo {\n      static #bar = 123\n      @dec static get #foo() { return this.#bar }\n      static { get$foo = x => x.#foo }\n    }\n    assertEq(() => get$foo(Foo), 123)\n    lateAsserts!()\n  },\n  'Getter decorators: Shim (instance getter)': () => {\n    let bar: (this: Foo) => number\n    const dec = (fn: (this: Foo) => number, ctx: ClassGetterDecoratorContext) => {\n      bar = function () { return fn.call(this) + 1 }\n      return bar\n    }\n    class Foo {\n      bar = 123\n      @dec get foo() { return this.bar }\n    }\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo.prototype, 'foo')!.get, bar!)\n    assertEq(() => new Foo().foo, 124)\n  },\n  'Getter decorators: Shim (static getter)': () => {\n    let bar: (this: typeof Foo) => number\n    const dec = (fn: (this: typeof Foo) => number, ctx: ClassGetterDecoratorContext) => {\n      bar = function () { return fn.call(this) + 1 }\n      return bar\n    }\n    class Foo {\n      static bar = 123\n      @dec static get foo() { return this.bar }\n    }\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo, 'foo')!.get, bar!)\n    assertEq(() => Foo.foo, 124)\n  },\n  'Getter decorators: Shim (private instance getter)': () => {\n    let bar: (this: Foo) => number\n    const dec = (fn: (this: Foo) => number, ctx: ClassGetterDecoratorContext) => {\n      bar = function () { return fn.call(this) + 1 }\n      return bar\n    }\n    let get$foo: (x: Foo) => number\n    class Foo {\n      #bar = 123\n      @dec get #foo() { return this.#bar }\n      static { get$foo = x => x.#foo }\n    }\n    assertEq(() => get$foo(new Foo), 124)\n  },\n  'Getter decorators: Shim (private static getter)': () => {\n    let bar: (this: typeof Foo) => number\n    const dec = (fn: (this: typeof Foo) => number, ctx: ClassGetterDecoratorContext) => {\n      bar = function () { return fn.call(this) + 1 }\n      return bar\n    }\n    let get$foo: (x: typeof Foo) => number\n    class Foo {\n      static #bar = 123\n      @dec static get #foo() { return this.#bar }\n      static { get$foo = x => x.#foo }\n    }\n    assertEq(() => get$foo(Foo), 124)\n  },\n  'Getter decorators: Order (instance getter)': () => {\n    const log: number[] = []\n    let bar: (this: Foo) => number\n    let baz: (this: Foo) => number\n    const dec1 = (fn: (this: Foo) => number, ctx: ClassGetterDecoratorContext) => {\n      log.push(2)\n      bar = function () {\n        log.push(4)\n        return fn.call(this)\n      }\n      return bar\n    }\n    const dec2 = (fn: (this: Foo) => number, ctx: ClassGetterDecoratorContext) => {\n      log.push(1)\n      baz = function () {\n        log.push(5)\n        return fn.call(this)\n      }\n      return baz\n    }\n    log.push(0)\n    class Foo {\n      @dec1 @dec2 get foo() { return log.push(6) }\n    }\n    log.push(3)\n    new Foo().foo\n    log.push(7)\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo.prototype, 'foo')!.get, bar!)\n    assertEq(() => log + '', '0,1,2,3,4,5,6,7')\n  },\n  'Getter decorators: Order (static getter)': () => {\n    const log: number[] = []\n    let bar: (this: typeof Foo) => number\n    let baz: (this: typeof Foo) => number\n    const dec1 = (fn: (this: typeof Foo) => number, ctx: ClassGetterDecoratorContext) => {\n      log.push(2)\n      bar = function () {\n        log.push(4)\n        return fn.call(this)\n      }\n      return bar\n    }\n    const dec2 = (fn: (this: typeof Foo) => number, ctx: ClassGetterDecoratorContext) => {\n      log.push(1)\n      baz = function () {\n        log.push(5)\n        return fn.call(this)\n      }\n      return baz\n    }\n    log.push(0)\n    class Foo {\n      @dec1 @dec2 static get foo() { return log.push(6) }\n    }\n    log.push(3)\n    Foo.foo\n    log.push(7)\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo, 'foo')!.get, bar!)\n    assertEq(() => log + '', '0,1,2,3,4,5,6,7')\n  },\n  'Getter decorators: Order (private instance getter)': () => {\n    const log: number[] = []\n    let bar: (this: Foo) => number\n    let baz: (this: Foo) => number\n    const dec1 = (fn: (this: Foo) => number, ctx: ClassGetterDecoratorContext) => {\n      log.push(2)\n      bar = function () {\n        log.push(4)\n        return fn.call(this)\n      }\n      return bar\n    }\n    const dec2 = (fn: (this: Foo) => number, ctx: ClassGetterDecoratorContext) => {\n      log.push(1)\n      baz = function () {\n        log.push(5)\n        return fn.call(this)\n      }\n      return baz\n    }\n    log.push(0)\n    let get$foo: (x: Foo) => number\n    class Foo {\n      @dec1 @dec2 get #foo() { return log.push(6) }\n      static { get$foo = x => x.#foo }\n    }\n    log.push(3)\n    assertEq(() => get$foo(new Foo), 7)\n    log.push(7)\n    assertEq(() => log + '', '0,1,2,3,4,5,6,7')\n  },\n  'Getter decorators: Order (private static getter)': () => {\n    const log: number[] = []\n    let bar: (this: typeof Foo) => number\n    let baz: (this: typeof Foo) => number\n    const dec1 = (fn: (this: typeof Foo) => number, ctx: ClassGetterDecoratorContext) => {\n      log.push(2)\n      bar = function () {\n        log.push(4)\n        return fn.call(this)\n      }\n      return bar\n    }\n    const dec2 = (fn: (this: typeof Foo) => number, ctx: ClassGetterDecoratorContext) => {\n      log.push(1)\n      baz = function () {\n        log.push(5)\n        return fn.call(this)\n      }\n      return baz\n    }\n    log.push(0)\n    let get$foo: (x: typeof Foo) => number\n    class Foo {\n      @dec1 @dec2 static get #foo() { return log.push(6) }\n      static { get$foo = x => x.#foo }\n    }\n    log.push(3)\n    assertEq(() => get$foo(Foo), 7)\n    log.push(7)\n    assertEq(() => log + '', '0,1,2,3,4,5,6,7')\n  },\n  'Getter decorators: Return null (instance getter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: Foo) => undefined, ctx: ClassGetterDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec get foo(): undefined { return } }\n    }, TypeError)\n  },\n  'Getter decorators: Return null (static getter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: typeof Foo) => undefined, ctx: ClassGetterDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec static get foo(): undefined { return } }\n    }, TypeError)\n  },\n  'Getter decorators: Return null (private instance getter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: Foo) => undefined, ctx: ClassGetterDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec get #foo(): undefined { return } }\n    }, TypeError)\n  },\n  'Getter decorators: Return null (private static getter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: typeof Foo) => undefined, ctx: ClassGetterDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec static get #foo(): undefined { return } }\n    }, TypeError)\n  },\n  'Getter decorators: Return object (instance getter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: Foo) => undefined, ctx: ClassGetterDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec get foo(): undefined { return } }\n    }, TypeError)\n  },\n  'Getter decorators: Return object (static getter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: typeof Foo) => undefined, ctx: ClassGetterDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec static get foo(): undefined { return } }\n    }, TypeError)\n  },\n  'Getter decorators: Return object (private instance getter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: Foo) => undefined, ctx: ClassGetterDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec get #foo(): undefined { return } }\n    }, TypeError)\n  },\n  'Getter decorators: Return object (private static getter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: typeof Foo) => undefined, ctx: ClassGetterDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec static get #foo(): undefined { return } }\n    }, TypeError)\n  },\n  'Getter decorators: Extra initializer (instance getter)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (fn: (this: Foo) => undefined, ctx: ClassGetterDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec get foo(): undefined { return } }\n    assertEq(() => got, undefined)\n    const instance = new Foo\n    assertEq(() => got.this, instance)\n    assertEq(() => got.args.length, 0)\n  },\n  'Getter decorators: Extra initializer (static getter)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (fn: (this: typeof Foo) => undefined, ctx: ClassGetterDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec static get foo(): undefined { return } }\n    assertEq(() => got.this, Foo)\n    assertEq(() => got.args.length, 0)\n  },\n  'Getter decorators: Extra initializer (private instance getter)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (fn: (this: Foo) => undefined, ctx: ClassGetterDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec get #foo(): undefined { return } }\n    assertEq(() => got, undefined)\n    const instance = new Foo\n    assertEq(() => got.this, instance)\n    assertEq(() => got.args.length, 0)\n  },\n  'Getter decorators: Extra initializer (private static getter)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (fn: (this: typeof Foo) => undefined, ctx: ClassGetterDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec static get #foo(): undefined { return } }\n    assertEq(() => got.this, Foo)\n    assertEq(() => got.args.length, 0)\n  },\n\n  // Setter decorators\n  'Setter decorators: Basic (instance setter)': () => {\n    const dec = (key: PropertyKey, name: string) =>\n      (fn: (this: Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n        assertEq(() => typeof fn, 'function')\n        assertEq(() => fn.name, name)\n        assertEq(() => ctx.kind, 'setter')\n        assertEq(() => ctx.name, key)\n        assertEq(() => ctx.static, false)\n        assertEq(() => ctx.private, false)\n        assertEq(() => ctx.access.has({ [key]: false }), true)\n        assertEq(() => ctx.access.has({ bar: true }), false)\n        assertEq(() => 'get' in ctx.access, false)\n        const obj: any = {}\n        ctx.access.set(obj, 123)\n        assertEq(() => obj[key], 123)\n        assertEq(() => 'bar' in obj, false)\n      }\n    const bar = Symbol('bar')\n    const baz = Symbol()\n    class Foo {\n      bar = 0\n      @dec('foo', 'set foo') set foo(x: number) { this.bar = x }\n      @dec(bar, 'set [bar]') set [bar](x: number) { this.bar = x }\n      @dec(baz, 'set ') set [baz](x: number) { this.bar = x }\n    }\n    var obj = new Foo\n    obj.foo = 321\n    assertEq(() => obj.bar, 321)\n    obj[bar] = 4321\n    assertEq(() => obj.bar, 4321)\n    obj[baz] = 54321\n    assertEq(() => obj.bar, 54321)\n  },\n  'Setter decorators: Basic (static setter)': () => {\n    const dec = (key: PropertyKey, name: string) =>\n      (fn: (this: typeof Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n        assertEq(() => typeof fn, 'function')\n        assertEq(() => fn.name, name)\n        assertEq(() => ctx.kind, 'setter')\n        assertEq(() => ctx.name, key)\n        assertEq(() => ctx.static, true)\n        assertEq(() => ctx.private, false)\n        assertEq(() => ctx.access.has({ [key]: false }), true)\n        assertEq(() => ctx.access.has({ bar: true }), false)\n        assertEq(() => 'get' in ctx.access, false)\n        const obj: any = {}\n        ctx.access.set(obj, 123)\n        assertEq(() => obj[key], 123)\n        assertEq(() => 'bar' in obj, false)\n      }\n    const bar = Symbol('bar')\n    const baz = Symbol()\n    class Foo {\n      static bar = 0\n      @dec('foo', 'set foo') static set foo(x: number) { this.bar = x }\n      @dec(bar, 'set [bar]') static set [bar](x: number) { this.bar = x }\n      @dec(baz, 'set ') static set [baz](x: number) { this.bar = x }\n    }\n    Foo.foo = 321\n    assertEq(() => Foo.bar, 321)\n    Foo[bar] = 4321\n    assertEq(() => Foo.bar, 4321)\n    Foo[baz] = 54321\n    assertEq(() => Foo.bar, 54321)\n  },\n  'Setter decorators: Basic (private instance setter)': () => {\n    let lateAsserts: () => void\n    const dec = (fn: (this: Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n      assertEq(() => typeof fn, 'function')\n      assertEq(() => fn.name, 'set #foo')\n      assertEq(() => ctx.kind, 'setter')\n      assertEq(() => ctx.name, '#foo')\n      assertEq(() => ctx.static, false)\n      assertEq(() => ctx.private, true)\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(new Foo), true)\n        assertEq(() => ctx.access.has({}), false)\n        assertEq(() => 'get' in ctx.access, false)\n        assertEq(() => {\n          const obj = new Foo\n          ctx.access.set(obj, 123)\n          return obj.bar\n        }, 123)\n      }\n    }\n    let set$foo: (x: Foo, y: number) => void\n    class Foo {\n      bar = 0\n      @dec set #foo(x: number) { this.bar = x }\n      static { set$foo = (x, y) => { x.#foo = y } }\n    }\n    lateAsserts!()\n    var obj = new Foo\n    assertEq(() => set$foo(obj, 321), undefined)\n    assertEq(() => obj.bar, 321)\n  },\n  'Setter decorators: Basic (private static setter)': () => {\n    let lateAsserts: () => void\n    const dec = (fn: (this: typeof Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n      assertEq(() => typeof fn, 'function')\n      assertEq(() => fn.name, 'set #foo')\n      assertEq(() => ctx.kind, 'setter')\n      assertEq(() => ctx.name, '#foo')\n      assertEq(() => ctx.static, true)\n      assertEq(() => ctx.private, true)\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(Foo), true)\n        assertEq(() => ctx.access.has({}), false)\n        assertEq(() => 'get' in ctx.access, false)\n        assertEq(() => {\n          ctx.access.set(Foo, 123)\n          return Foo.bar\n        }, 123)\n      }\n    }\n    let set$foo: (x: typeof Foo, y: number) => void\n    class Foo {\n      static bar = 0\n      @dec static set #foo(x: number) { this.bar = x }\n      static { set$foo = (x, y) => { x.#foo = y } }\n    }\n    lateAsserts!()\n    assertEq(() => set$foo(Foo, 321), undefined)\n    assertEq(() => Foo.bar, 321)\n  },\n  'Setter decorators: Shim (instance setter)': () => {\n    let bar: (this: Foo, x: number) => void\n    const dec = (fn: (this: Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n      bar = function (x) { fn.call(this, x + 1) }\n      return bar\n    }\n    class Foo {\n      bar = 123\n      @dec set foo(x: number) { this.bar = x }\n    }\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo.prototype, 'foo')!.set, bar!)\n    var obj = new Foo\n    obj.foo = 321\n    assertEq(() => obj.bar, 322)\n  },\n  'Setter decorators: Shim (static setter)': () => {\n    let bar: (this: typeof Foo, x: number) => void\n    const dec = (fn: (this: typeof Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n      bar = function (x) { fn.call(this, x + 1) }\n      return bar\n    }\n    class Foo {\n      static bar = 123\n      @dec static set foo(x: number) { this.bar = x }\n    }\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo, 'foo')!.set, bar!)\n    Foo.foo = 321\n    assertEq(() => Foo.bar, 322)\n  },\n  'Setter decorators: Shim (private instance setter)': () => {\n    let bar: (this: Foo, x: number) => void\n    const dec = (fn: (this: Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n      bar = function (x) { fn.call(this, x + 1) }\n      return bar\n    }\n    let set$foo: (x: Foo, y: number) => void\n    class Foo {\n      bar = 123\n      @dec set #foo(x: number) { this.bar = x }\n      static { set$foo = (x, y) => { x.#foo = y } }\n    }\n    var obj = new Foo\n    assertEq(() => set$foo(obj, 321), undefined)\n    assertEq(() => obj.bar, 322)\n  },\n  'Setter decorators: Shim (private static setter)': () => {\n    let bar: (this: typeof Foo, x: number) => void\n    const dec = (fn: (this: typeof Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n      bar = function (x) { fn.call(this, x + 1) }\n      return bar\n    }\n    let set$foo: (x: typeof Foo, y: number) => void\n    class Foo {\n      static bar = 123\n      @dec static set #foo(x: number) { this.bar = x }\n      static { set$foo = (x, y) => { x.#foo = y } }\n    }\n    assertEq(() => set$foo(Foo, 321), undefined)\n    assertEq(() => Foo.bar, 322)\n  },\n  'Setter decorators: Order (instance setter)': () => {\n    const log: number[] = []\n    let bar: (this: Foo, x: number) => void\n    let baz: (this: Foo, x: number) => void\n    const dec1 = (fn: (this: Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n      log.push(2)\n      bar = function (x) {\n        log.push(4)\n        fn.call(this, x)\n      }\n      return bar\n    }\n    const dec2 = (fn: (this: Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n      log.push(1)\n      baz = function (x) {\n        log.push(5)\n        fn.call(this, x)\n      }\n      return baz\n    }\n    log.push(0)\n    class Foo {\n      @dec1 @dec2 set foo(x: number) { log.push(6) }\n    }\n    log.push(3)\n    new Foo().foo = 123\n    log.push(7)\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo.prototype, 'foo')!.set, bar!)\n    assertEq(() => log + '', '0,1,2,3,4,5,6,7')\n  },\n  'Setter decorators: Order (static setter)': () => {\n    const log: number[] = []\n    let bar: (this: typeof Foo, x: number) => void\n    let baz: (this: typeof Foo, x: number) => void\n    const dec1 = (fn: (this: typeof Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n      log.push(2)\n      bar = function (x) {\n        log.push(4)\n        fn.call(this, x)\n      }\n      return bar\n    }\n    const dec2 = (fn: (this: typeof Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n      log.push(1)\n      baz = function (x) {\n        log.push(5)\n        fn.call(this, x)\n      }\n      return baz\n    }\n    log.push(0)\n    class Foo {\n      @dec1 @dec2 static set foo(x: number) { log.push(6) }\n    }\n    log.push(3)\n    Foo.foo = 123\n    log.push(7)\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo, 'foo')!.set, bar!)\n    assertEq(() => log + '', '0,1,2,3,4,5,6,7')\n  },\n  'Setter decorators: Order (private instance setter)': () => {\n    const log: number[] = []\n    let bar: (this: Foo, x: number) => void\n    let baz: (this: Foo, x: number) => void\n    const dec1 = (fn: (this: Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n      log.push(2)\n      bar = function (x) {\n        log.push(4)\n        fn.call(this, x)\n      }\n      return bar\n    }\n    const dec2 = (fn: (this: Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n      log.push(1)\n      baz = function (x) {\n        log.push(5)\n        fn.call(this, x)\n      }\n      return baz\n    }\n    log.push(0)\n    let set$foo: (x: Foo, y: number) => void\n    class Foo {\n      @dec1 @dec2 set #foo(x: number) { log.push(6) }\n      static { set$foo = (x, y) => { x.#foo = y } }\n    }\n    log.push(3)\n    assertEq(() => set$foo(new Foo, 123), undefined)\n    log.push(7)\n    assertEq(() => log + '', '0,1,2,3,4,5,6,7')\n  },\n  'Setter decorators: Order (private static setter)': () => {\n    const log: number[] = []\n    let bar: (this: typeof Foo, x: number) => void\n    let baz: (this: typeof Foo, x: number) => void\n    const dec1 = (fn: (this: typeof Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n      log.push(2)\n      bar = function (x) {\n        log.push(4)\n        fn.call(this, x)\n      }\n      return bar\n    }\n    const dec2 = (fn: (this: typeof Foo, x: number) => void, ctx: ClassSetterDecoratorContext) => {\n      log.push(1)\n      baz = function (x) {\n        log.push(5)\n        fn.call(this, x)\n      }\n      return baz\n    }\n    log.push(0)\n    let set$foo: (x: typeof Foo, y: number) => void\n    class Foo {\n      @dec1 @dec2 static set #foo(x: number) { log.push(6) }\n      static { set$foo = (x, y) => { x.#foo = y } }\n    }\n    log.push(3)\n    assertEq(() => set$foo(Foo, 123), undefined)\n    log.push(7)\n    assertEq(() => log + '', '0,1,2,3,4,5,6,7')\n  },\n  'Setter decorators: Return null (instance setter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: Foo, x: undefined) => void, ctx: ClassSetterDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec set foo(x: undefined) { } }\n    }, TypeError)\n  },\n  'Setter decorators: Return null (static setter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: typeof Foo, x: undefined) => void, ctx: ClassSetterDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec static set foo(x: undefined) { } }\n    }, TypeError)\n  },\n  'Setter decorators: Return null (private instance setter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: Foo, x: undefined) => void, ctx: ClassSetterDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec set #foo(x: undefined) { } }\n    }, TypeError)\n  },\n  'Setter decorators: Return null (private static setter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: typeof Foo, x: undefined) => void, ctx: ClassSetterDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec static set #foo(x: undefined) { } }\n    }, TypeError)\n  },\n  'Setter decorators: Return object (instance setter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: Foo, x: undefined) => void, ctx: ClassSetterDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec set foo(x: undefined) { } }\n    }, TypeError)\n  },\n  'Setter decorators: Return object (static setter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: typeof Foo, x: undefined) => void, ctx: ClassSetterDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec static set foo(x: undefined) { } }\n    }, TypeError)\n  },\n  'Setter decorators: Return object (private instance setter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: Foo, x: undefined) => void, ctx: ClassSetterDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec set #foo(x: undefined) { } }\n    }, TypeError)\n  },\n  'Setter decorators: Return object (private static setter)': () => {\n    assertThrows(() => {\n      const dec = (fn: (this: typeof Foo, x: undefined) => void, ctx: ClassSetterDecoratorContext): any => {\n        return {}\n      }\n      class Foo { @dec static set #foo(x: undefined) { } }\n    }, TypeError)\n  },\n  'Setter decorators: Extra initializer (instance setter)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (fn: (this: Foo, x: undefined) => void, ctx: ClassSetterDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec set foo(x: undefined) { } }\n    assertEq(() => got, undefined)\n    const instance = new Foo\n    assertEq(() => got.this, instance)\n    assertEq(() => got.args.length, 0)\n  },\n  'Setter decorators: Extra initializer (static setter)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (fn: (this: typeof Foo, x: undefined) => void, ctx: ClassSetterDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec static set foo(x: undefined) { } }\n    assertEq(() => got.this, Foo)\n    assertEq(() => got.args.length, 0)\n  },\n  'Setter decorators: Extra initializer (private instance setter)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (fn: (this: Foo, x: undefined) => void, ctx: ClassSetterDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec set #foo(x: undefined) { } }\n    assertEq(() => got, undefined)\n    const instance = new Foo\n    assertEq(() => got.this, instance)\n    assertEq(() => got.args.length, 0)\n  },\n  'Setter decorators: Extra initializer (private static setter)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (fn: (this: typeof Foo, x: undefined) => void, ctx: ClassSetterDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec static set #foo(x: undefined) { } }\n    assertEq(() => got.this, Foo)\n    assertEq(() => got.args.length, 0)\n  },\n\n  // Auto-accessor decorators\n  'Auto-accessor decorators: Basic (instance auto-accessor)': () => {\n    const dec = (key: PropertyKey, getName: string, setName: string) =>\n      (target: ClassAccessorDecoratorTarget<Foo, number>, ctx: ClassAccessorDecoratorContext) => {\n        assertEq(() => typeof target.get, 'function')\n        assertEq(() => typeof target.set, 'function')\n        assertEq(() => target.get.name, getName)\n        assertEq(() => target.set.name, setName)\n        assertEq(() => ctx.kind, 'accessor')\n        assertEq(() => ctx.name, key)\n        assertEq(() => ctx.static, false)\n        assertEq(() => ctx.private, false)\n        assertEq(() => ctx.access.has({ [key]: false }), true)\n        assertEq(() => ctx.access.has({ bar: true }), false)\n        assertEq(() => ctx.access.get({ [key]: 123 }), 123)\n        assertEq(() => {\n          const obj: any = {}\n          ctx.access.set(obj, 123)\n          return obj[key]\n        }, 123)\n      }\n    const bar = Symbol('bar')\n    const baz = Symbol()\n    class Foo {\n      @dec('foo', 'get foo', 'set foo') accessor foo = 0\n      @dec(bar, 'get [bar]', 'set [bar]') accessor [bar] = 0\n      @dec(baz, 'get ', 'set ') accessor [baz] = 0\n    }\n    var obj = new Foo\n    obj.foo = 321\n    assertEq(() => obj.foo, 321)\n    obj[bar] = 4321\n    assertEq(() => obj[bar], 4321)\n    obj[baz] = 54321\n    assertEq(() => obj[baz], 54321)\n  },\n  'Auto-accessor decorators: Basic (static auto-accessor)': () => {\n    const dec = (key: PropertyKey, getName: string, setName: string) =>\n      (target: ClassAccessorDecoratorTarget<typeof Foo, number>, ctx: ClassAccessorDecoratorContext) => {\n        assertEq(() => typeof target.get, 'function')\n        assertEq(() => typeof target.set, 'function')\n        assertEq(() => target.get.name, getName)\n        assertEq(() => target.set.name, setName)\n        assertEq(() => ctx.kind, 'accessor')\n        assertEq(() => ctx.name, key)\n        assertEq(() => ctx.static, true)\n        assertEq(() => ctx.private, false)\n        assertEq(() => ctx.access.has({ [key]: false }), true)\n        assertEq(() => ctx.access.has({ bar: true }), false)\n        assertEq(() => ctx.access.get({ [key]: 123 }), 123)\n        assertEq(() => {\n          const obj: any = {}\n          ctx.access.set(obj, 123)\n          return obj[key]\n        }, 123)\n      }\n    const bar = Symbol('bar')\n    const baz = Symbol()\n    class Foo {\n      @dec('foo', 'get foo', 'set foo') static accessor foo = 0\n      @dec(bar, 'get [bar]', 'set [bar]') static accessor [bar] = 0\n      @dec(baz, 'get ', 'set ') static accessor [baz] = 0\n    }\n    Foo.foo = 321\n    assertEq(() => Foo.foo, 321)\n    Foo[bar] = 4321\n    assertEq(() => Foo[bar], 4321)\n    Foo[baz] = 54321\n    assertEq(() => Foo[baz], 54321)\n  },\n  'Auto-accessor decorators: Basic (private instance auto-accessor)': () => {\n    let lateAsserts: () => void\n    const dec = (target: ClassAccessorDecoratorTarget<Foo, number>, ctx: ClassAccessorDecoratorContext) => {\n      assertEq(() => typeof target.get, 'function')\n      assertEq(() => typeof target.set, 'function')\n      assertEq(() => target.get.name, 'get #foo')\n      assertEq(() => target.set.name, 'set #foo')\n      assertEq(() => ctx.kind, 'accessor')\n      assertEq(() => ctx.name, '#foo')\n      assertEq(() => ctx.static, false)\n      assertEq(() => ctx.private, true)\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(new Foo), true)\n        assertEq(() => ctx.access.has({}), false)\n        assertEq(() => ctx.access.get(new Foo), 0)\n        assertEq(() => {\n          const obj = new Foo\n          ctx.access.set(obj, 123)\n          return get$foo(obj)\n        }, 123)\n      }\n    }\n    let get$foo: (x: Foo) => number\n    let set$foo: (x: Foo, y: number) => void\n    class Foo {\n      @dec accessor #foo = 0\n      static {\n        get$foo = x => x.#foo\n        set$foo = (x, y) => { x.#foo = y }\n      }\n    }\n    lateAsserts!()\n    var obj = new Foo\n    assertEq(() => set$foo(obj, 321), undefined)\n    assertEq(() => get$foo(obj), 321)\n  },\n  'Auto-accessor decorators: Basic (private static auto-accessor)': () => {\n    let lateAsserts: () => void\n    const dec = (target: ClassAccessorDecoratorTarget<typeof Foo, number>, ctx: ClassAccessorDecoratorContext) => {\n      assertEq(() => typeof target.get, 'function')\n      assertEq(() => typeof target.set, 'function')\n      assertEq(() => target.get.name, 'get #foo')\n      assertEq(() => target.set.name, 'set #foo')\n      assertEq(() => ctx.kind, 'accessor')\n      assertEq(() => ctx.name, '#foo')\n      assertEq(() => ctx.static, true)\n      assertEq(() => ctx.private, true)\n      lateAsserts = () => {\n        assertEq(() => ctx.access.has(Foo), true)\n        assertEq(() => ctx.access.has({}), false)\n        assertEq(() => ctx.access.get(Foo), 0)\n        assertEq(() => {\n          ctx.access.set(Foo, 123)\n          return get$foo(Foo)\n        }, 123)\n      }\n    }\n    let get$foo: (x: typeof Foo) => number\n    let set$foo: (x: typeof Foo, y: number) => void\n    class Foo {\n      @dec static accessor #foo = 0\n      static {\n        get$foo = x => x.#foo\n        set$foo = (x, y) => { x.#foo = y }\n      }\n    }\n    lateAsserts!()\n    assertEq(() => set$foo(Foo, 321), undefined)\n    assertEq(() => get$foo(Foo), 321)\n  },\n  'Auto-accessor decorators: Shim (instance auto-accessor)': () => {\n    let get: (this: Foo) => number\n    let set: (this: Foo, x: number) => void\n    const dec = (target: ClassAccessorDecoratorTarget<Foo, number>, ctx: ClassAccessorDecoratorContext): ClassAccessorDecoratorResult<Foo, number> => {\n      function init(this: Foo, x: number): number {\n        assertEq(() => this instanceof Foo, true)\n        return x + 1\n      }\n      get = function () { return target.get.call(this) * 10 }\n      set = function (x) { target.set.call(this, x * 2) }\n      return { get, set, init }\n    }\n    class Foo {\n      @dec accessor foo = 123\n    }\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo.prototype, 'foo')!.get, get!)\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo.prototype, 'foo')!.set, set!)\n    var obj = new Foo\n    assertEq(() => obj.foo, (123 + 1) * 10)\n    obj.foo = 321\n    assertEq(() => obj.foo, (321 * 2) * 10)\n  },\n  'Auto-accessor decorators: Shim (static auto-accessor)': () => {\n    let foo: typeof Foo\n    let get: (this: typeof Foo) => number\n    let set: (this: typeof Foo, x: number) => void\n    const dec = (target: ClassAccessorDecoratorTarget<typeof Foo, number>, ctx: ClassAccessorDecoratorContext): ClassAccessorDecoratorResult<typeof Foo, number> => {\n      function init(this: typeof Foo, x: number): number {\n        assertEq(() => this, foo)\n        return x + 1\n      }\n      get = function () { return target.get.call(this) * 10 }\n      set = function (x) { target.set.call(this, x * 2) }\n      return { get, set, init }\n    }\n    class Foo {\n      static {\n        foo = Foo\n      }\n      @dec static accessor foo = 123\n    }\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo, 'foo')!.get, get!)\n    assertEq(() => Object.getOwnPropertyDescriptor(Foo, 'foo')!.set, set!)\n    assertEq(() => Foo.foo, (123 + 1) * 10)\n    Foo.foo = 321\n    assertEq(() => Foo.foo, (321 * 2) * 10)\n  },\n  'Auto-accessor decorators: Shim (private instance auto-accessor)': () => {\n    let get: (this: Foo) => number\n    let set: (this: Foo, x: number) => void\n    const dec = (target: ClassAccessorDecoratorTarget<Foo, number>, ctx: ClassAccessorDecoratorContext): ClassAccessorDecoratorResult<Foo, number> => {\n      function init(this: Foo, x: number): number {\n        assertEq(() => this instanceof Foo, true)\n        return x + 1\n      }\n      get = function () { return target.get.call(this) * 10 }\n      set = function (x) { target.set.call(this, x * 2) }\n      return { get, set, init }\n    }\n    let get$foo: (x: Foo) => number\n    let set$foo: (x: Foo, y: number) => void\n    class Foo {\n      @dec accessor #foo = 123\n      static {\n        get$foo = x => x.#foo\n        set$foo = (x, y) => { x.#foo = y }\n      }\n    }\n    var obj = new Foo\n    assertEq(() => get$foo(obj), (123 + 1) * 10)\n    assertEq(() => set$foo(obj, 321), undefined)\n    assertEq(() => get$foo(obj), (321 * 2) * 10)\n  },\n  'Auto-accessor decorators: Shim (private static auto-accessor)': () => {\n    let foo: typeof Foo\n    let get: (this: typeof Foo) => number\n    let set: (this: typeof Foo, x: number) => void\n    const dec = (target: ClassAccessorDecoratorTarget<typeof Foo, number>, ctx: ClassAccessorDecoratorContext): ClassAccessorDecoratorResult<typeof Foo, number> => {\n      function init(this: typeof Foo, x: number): number {\n        assertEq(() => this, foo)\n        return x + 1\n      }\n      get = function () { return target.get.call(this) * 10 }\n      set = function (x) { target.set.call(this, x * 2) }\n      return { get, set, init }\n    }\n    let get$foo: (x: typeof Foo) => number\n    let set$foo: (x: typeof Foo, y: number) => void\n    class Foo {\n      static {\n        foo = Foo\n        get$foo = x => x.#foo\n        set$foo = (x, y) => { x.#foo = y }\n      }\n      @dec static accessor #foo = 123\n    }\n    assertEq(() => get$foo(Foo), (123 + 1) * 10)\n    assertEq(() => set$foo(Foo, 321), undefined)\n    assertEq(() => get$foo(Foo), (321 * 2) * 10)\n  },\n  'Auto-accessor decorators: Return null (instance auto-accessor)': () => {\n    assertThrows(() => {\n      const dec = (target: ClassAccessorDecoratorTarget<Foo, undefined>, ctx: ClassAccessorDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec accessor foo: undefined }\n    }, TypeError)\n  },\n  'Auto-accessor decorators: Return null (static auto-accessor)': () => {\n    assertThrows(() => {\n      const dec = (target: ClassAccessorDecoratorTarget<typeof Foo, undefined>, ctx: ClassAccessorDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec static accessor foo: undefined }\n    }, TypeError)\n  },\n  'Auto-accessor decorators: Return null (private instance auto-accessor)': () => {\n    assertThrows(() => {\n      const dec = (target: ClassAccessorDecoratorTarget<Foo, undefined>, ctx: ClassAccessorDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec accessor #foo: undefined }\n    }, TypeError)\n  },\n  'Auto-accessor decorators: Return null (private static auto-accessor)': () => {\n    assertThrows(() => {\n      const dec = (target: ClassAccessorDecoratorTarget<typeof Foo, undefined>, ctx: ClassAccessorDecoratorContext): any => {\n        return null\n      }\n      class Foo { @dec static accessor #foo: undefined }\n    }, TypeError)\n  },\n  'Auto-accessor decorators: Extra initializer (instance auto-accessor)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (target: ClassAccessorDecoratorTarget<Foo, undefined>, ctx: ClassAccessorDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec accessor foo: undefined }\n    assertEq(() => got, undefined)\n    const instance = new Foo\n    assertEq(() => got.this, instance)\n    assertEq(() => got.args.length, 0)\n  },\n  'Auto-accessor decorators: Extra initializer (static auto-accessor)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (target: ClassAccessorDecoratorTarget<typeof Foo, undefined>, ctx: ClassAccessorDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec static accessor foo: undefined }\n    assertEq(() => got.this, Foo)\n    assertEq(() => got.args.length, 0)\n  },\n  'Auto-accessor decorators: Extra initializer (private instance auto-accessor)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (target: ClassAccessorDecoratorTarget<Foo, undefined>, ctx: ClassAccessorDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec accessor #foo: undefined }\n    assertEq(() => got, undefined)\n    const instance = new Foo\n    assertEq(() => got.this, instance)\n    assertEq(() => got.args.length, 0)\n  },\n  'Auto-accessor decorators: Extra initializer (private static auto-accessor)': () => {\n    let oldAddInitializer: DecoratorContext['addInitializer'] | null\n    let got: { this: any, args: any[] }\n    const dec = (target: ClassAccessorDecoratorTarget<typeof Foo, undefined>, ctx: ClassAccessorDecoratorContext): any => {\n      ctx.addInitializer(function (...args) {\n        got = { this: this, args }\n      })\n      if (oldAddInitializer) assertThrows(() => oldAddInitializer!(() => { }), TypeError)\n      assertThrows(() => ctx.addInitializer({} as any), TypeError)\n      oldAddInitializer = ctx.addInitializer\n    }\n    class Foo { @dec @dec static accessor #foo: undefined }\n    assertEq(() => got.this, Foo)\n    assertEq(() => got.args.length, 0)\n  },\n\n  // Decorator list evaluation\n  'Decorator list evaluation: Computed names (class statement)': () => {\n    const log: number[] = []\n    const foo = (n: number): Function => {\n      log.push(n)\n      return () => { }\n    }\n\n    const computed: {\n      readonly method: unique symbol,\n      readonly field: unique symbol,\n      readonly getter: unique symbol,\n      readonly setter: unique symbol,\n      readonly accessor: unique symbol,\n    } = {\n      get method() { log.push(log.length); return Symbol('method') },\n      get field() { log.push(log.length); return Symbol('field') },\n      get getter() { log.push(log.length); return Symbol('getter') },\n      get setter() { log.push(log.length); return Symbol('setter') },\n      get accessor() { log.push(log.length); return Symbol('accessor') },\n    } as any\n\n    @foo(0) class Foo\n      extends (foo(1), Object)\n    {\n      @foo(2) [computed.method]() { }\n      @foo(4) static [computed.method]() { }\n\n      @foo(6) [computed.field]: undefined\n      @foo(8) static [computed.field]: undefined\n\n      @foo(10) get [computed.getter](): undefined { return }\n      @foo(12) static get [computed.getter](): undefined { return }\n\n      @foo(14) set [computed.setter](x: undefined) { }\n      @foo(16) static set [computed.setter](x: undefined) { }\n\n      @foo(18) accessor [computed.accessor]: undefined\n      @foo(20) static accessor [computed.accessor]: undefined\n    }\n\n    assertEq(() => '' + log, '0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21')\n  },\n  'Decorator list evaluation: Computed names (class expression)': () => {\n    const log: number[] = []\n    const foo = (n: number): Function => {\n      log.push(n)\n      return () => { }\n    }\n\n    const computed: {\n      readonly method: unique symbol,\n      readonly field: unique symbol,\n      readonly getter: unique symbol,\n      readonly setter: unique symbol,\n      readonly accessor: unique symbol,\n    } = {\n      get method() { log.push(log.length); return Symbol('method') },\n      get field() { log.push(log.length); return Symbol('field') },\n      get getter() { log.push(log.length); return Symbol('getter') },\n      get setter() { log.push(log.length); return Symbol('setter') },\n      get accessor() { log.push(log.length); return Symbol('accessor') },\n    } as any\n\n    (@foo(0) class\n      extends (foo(1), Object)\n    {\n      @foo(2) [computed.method]() { }\n      @foo(4) static [computed.method]() { }\n\n      @foo(6) [computed.field]: undefined\n      @foo(8) static [computed.field]: undefined\n\n      @foo(10) get [computed.getter](): undefined { return }\n      @foo(12) static get [computed.getter](): undefined { return }\n\n      @foo(14) set [computed.setter](x: undefined) { }\n      @foo(16) static set [computed.setter](x: undefined) { }\n\n      @foo(18) accessor [computed.accessor]: undefined\n      @foo(20) static accessor [computed.accessor]: undefined\n    })\n\n    assertEq(() => '' + log, '0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21')\n  },\n  'Decorator list evaluation: \"this\" (class statement)': () => {\n    const log: number[] = []\n    const dummy: Function = () => { }\n    const ctx = {\n      foo(n: number) {\n        log.push(n)\n      }\n    }\n\n    function wrapper(this: typeof ctx) {\n      @(assertEq(() => this.foo(0), undefined), dummy) class Foo\n        extends (assertEq(() => this.foo(1), undefined), Object)\n      {\n        @(assertEq(() => this.foo(2), undefined), dummy) method() { }\n        @(assertEq(() => this.foo(3), undefined), dummy) static method() { }\n\n        @(assertEq(() => this.foo(4), undefined), dummy) field: undefined\n        @(assertEq(() => this.foo(5), undefined), dummy) static field: undefined\n\n        @(assertEq(() => this.foo(6), undefined), dummy) get getter(): undefined { return }\n        @(assertEq(() => this.foo(7), undefined), dummy) static get getter(): undefined { return }\n\n        @(assertEq(() => this.foo(8), undefined), dummy) set setter(x: undefined) { }\n        @(assertEq(() => this.foo(9), undefined), dummy) static set setter(x: undefined) { }\n\n        @(assertEq(() => this.foo(10), undefined), dummy) accessor accessor: undefined\n        @(assertEq(() => this.foo(11), undefined), dummy) static accessor accessor: undefined\n      }\n    }\n\n    wrapper.call(ctx)\n    assertEq(() => '' + log, '0,1,2,3,4,5,6,7,8,9,10,11')\n  },\n  'Decorator list evaluation: \"this\" (class expression)': () => {\n    const log: number[] = []\n    const dummy: Function = () => { }\n    const ctx = {\n      foo(n: number) {\n        log.push(n)\n      }\n    }\n\n    function wrapper(this: typeof ctx) {\n      (@(assertEq(() => this.foo(0), undefined), dummy) class\n        extends (assertEq(() => this.foo(1), undefined), Object)\n      {\n        @(assertEq(() => this.foo(2), undefined), dummy) method() { }\n        @(assertEq(() => this.foo(3), undefined), dummy) static method() { }\n\n        @(assertEq(() => this.foo(4), undefined), dummy) field: undefined\n        @(assertEq(() => this.foo(5), undefined), dummy) static field: undefined\n\n        @(assertEq(() => this.foo(6), undefined), dummy) get getter(): undefined { return }\n        @(assertEq(() => this.foo(7), undefined), dummy) static get getter(): undefined { return }\n\n        @(assertEq(() => this.foo(8), undefined), dummy) set setter(x: undefined) { }\n        @(assertEq(() => this.foo(9), undefined), dummy) static set setter(x: undefined) { }\n\n        @(assertEq(() => this.foo(10), undefined), dummy) accessor accessor: undefined\n        @(assertEq(() => this.foo(11), undefined), dummy) static accessor accessor: undefined\n      })\n    }\n\n    wrapper.call(ctx)\n    assertEq(() => '' + log, '0,1,2,3,4,5,6,7,8,9,10,11')\n  },\n  'Decorator list evaluation: \"await\" (class statement)': async () => {\n    const log: number[] = []\n    const dummy: Function = () => { }\n\n    async function wrapper() {\n      @(log.push(await Promise.resolve(0)), dummy) class Foo\n        extends (log.push(await Promise.resolve(1)), Object)\n      {\n        @(log.push(await Promise.resolve(2)), dummy) method() { }\n        @(log.push(await Promise.resolve(3)), dummy) static method() { }\n\n        @(log.push(await Promise.resolve(4)), dummy) field: undefined\n        @(log.push(await Promise.resolve(5)), dummy) static field: undefined\n\n        @(log.push(await Promise.resolve(6)), dummy) get getter(): undefined { return }\n        @(log.push(await Promise.resolve(7)), dummy) static get getter(): undefined { return }\n\n        @(log.push(await Promise.resolve(8)), dummy) set setter(x: undefined) { }\n        @(log.push(await Promise.resolve(9)), dummy) static set setter(x: undefined) { }\n\n        @(log.push(await Promise.resolve(10)), dummy) accessor accessor: undefined\n        @(log.push(await Promise.resolve(11)), dummy) static accessor accessor: undefined\n      }\n    }\n\n    await wrapper()\n    assertEq(() => '' + log, '0,1,2,3,4,5,6,7,8,9,10,11')\n  },\n  'Decorator list evaluation: \"await\" (class expression)': async () => {\n    const log: number[] = []\n    const dummy: Function = () => { }\n\n    async function wrapper() {\n      (@(log.push(await Promise.resolve(0)), dummy) class\n        extends (log.push(await Promise.resolve(1)), Object)\n      {\n        @(log.push(await Promise.resolve(2)), dummy) method() { }\n        @(log.push(await Promise.resolve(3)), dummy) static method() { }\n\n        @(log.push(await Promise.resolve(4)), dummy) field: undefined\n        @(log.push(await Promise.resolve(5)), dummy) static field: undefined\n\n        @(log.push(await Promise.resolve(6)), dummy) get getter(): undefined { return }\n        @(log.push(await Promise.resolve(7)), dummy) static get getter(): undefined { return }\n\n        @(log.push(await Promise.resolve(8)), dummy) set setter(x: undefined) { }\n        @(log.push(await Promise.resolve(9)), dummy) static set setter(x: undefined) { }\n\n        @(log.push(await Promise.resolve(10)), dummy) accessor accessor: undefined\n        @(log.push(await Promise.resolve(11)), dummy) static accessor accessor: undefined\n      })\n    }\n\n    await wrapper()\n    assertEq(() => '' + log, '0,1,2,3,4,5,6,7,8,9,10,11')\n  },\n  'Decorator list evaluation: Outer private name (class statement)': () => {\n    const log: number[] = []\n\n    class Dummy {\n      static #foo(n: number): Function {\n        log.push(n)\n        return () => { }\n      }\n\n      static {\n        const dummy = this\n        @(dummy.#foo(0)) class Foo\n          extends (dummy.#foo(1), Object)\n        {\n          @(dummy.#foo(2)) method() { }\n          @(dummy.#foo(3)) static method() { }\n\n          @(dummy.#foo(4)) field: undefined\n          @(dummy.#foo(5)) static field: undefined\n\n          @(dummy.#foo(6)) get getter(): undefined { return }\n          @(dummy.#foo(7)) static get getter(): undefined { return }\n\n          @(dummy.#foo(8)) set setter(x: undefined) { }\n          @(dummy.#foo(9)) static set setter(x: undefined) { }\n\n          @(dummy.#foo(10)) accessor accessor: undefined\n          @(dummy.#foo(11)) static accessor accessor: undefined\n        }\n      }\n    }\n\n    assertEq(() => '' + log, '0,1,2,3,4,5,6,7,8,9,10,11')\n  },\n  'Decorator list evaluation: Outer private name (class expression)': () => {\n    const log: number[] = []\n\n    class Dummy {\n      static #foo(n: number): Function {\n        log.push(n)\n        return () => { }\n      }\n\n      static {\n        const dummy = this;\n        (@(dummy.#foo(0)) class\n          extends (dummy.#foo(1), Object)\n        {\n          @(dummy.#foo(2)) method() { }\n          @(dummy.#foo(3)) static method() { }\n\n          @(dummy.#foo(4)) field: undefined\n          @(dummy.#foo(5)) static field: undefined\n\n          @(dummy.#foo(6)) get getter(): undefined { return }\n          @(dummy.#foo(7)) static get getter(): undefined { return }\n\n          @(dummy.#foo(8)) set setter(x: undefined) { }\n          @(dummy.#foo(9)) static set setter(x: undefined) { }\n\n          @(dummy.#foo(10)) accessor accessor: undefined\n          @(dummy.#foo(11)) static accessor accessor: undefined\n        })\n      }\n    }\n\n    assertEq(() => '' + log, '0,1,2,3,4,5,6,7,8,9,10,11')\n  },\n  'Decorator list evaluation: Inner private name (class statement)': () => {\n    const fns: (() => number)[] = []\n    const capture = (fn: () => number): Function => {\n      fns.push(fn)\n      return () => { }\n    }\n\n    class Dummy {\n      static #foo = NaN\n\n      static {\n        @(capture(() => (new Foo() as any).#foo + 0))\n        class Foo {\n          #foo = 10\n\n          @(capture(() => new Foo().#foo + 1)) method() { }\n          @(capture(() => new Foo().#foo + 2)) static method() { }\n\n          @(capture(() => new Foo().#foo + 3)) field: undefined\n          @(capture(() => new Foo().#foo + 4)) static field: undefined\n\n          @(capture(() => new Foo().#foo + 5)) get getter(): undefined { return }\n          @(capture(() => new Foo().#foo + 6)) static get getter(): undefined { return }\n\n          @(capture(() => new Foo().#foo + 7)) set setter(x: undefined) { }\n          @(capture(() => new Foo().#foo + 8)) static set setter(x: undefined) { }\n\n          @(capture(() => new Foo().#foo + 9)) accessor accessor: undefined\n          @(capture(() => new Foo().#foo + 10)) static accessor accessor: undefined\n        }\n      }\n    }\n\n    // Accessing \"#foo\" in the class decorator should fail. The \"#foo\" should\n    // refer to the outer \"#foo\", not the inner \"#foo\".\n    const firstFn = fns.shift()!\n    assertEq(() => {\n      try {\n        firstFn()\n        throw new Error('Expected a TypeError to be thrown')\n      } catch (err) {\n        if (err instanceof TypeError) return true\n        throw err\n      }\n    }, true)\n\n    // Accessing \"#foo\" from any of the class element decorators should succeed.\n    // Each \"#foo\" should refer to the inner \"#foo\", not the outer \"#foo\".\n    const log: number[] = []\n    for (const fn of fns) log.push(fn())\n    assertEq(() => '' + log, '11,12,13,14,15,16,17,18,19,20')\n  },\n  'Decorator list evaluation: Inner private name (class expression)': () => {\n    const fns: (() => number)[] = []\n    const capture = (fn: () => number): Function => {\n      fns.push(fn)\n      return () => { }\n    }\n\n    class Outer {\n      static #foo = 0\n\n      static {\n        (@(capture(() => Outer.#foo + 0))\n          class Foo {\n          #foo = 10\n\n          @(capture(() => new Foo().#foo + 1)) method() { }\n          @(capture(() => new Foo().#foo + 2)) static method() { }\n\n          @(capture(() => new Foo().#foo + 3)) field: undefined\n          @(capture(() => new Foo().#foo + 4)) static field: undefined\n\n          @(capture(() => new Foo().#foo + 5)) get getter(): undefined { return }\n          @(capture(() => new Foo().#foo + 6)) static get getter(): undefined { return }\n\n          @(capture(() => new Foo().#foo + 7)) set setter(x: undefined) { }\n          @(capture(() => new Foo().#foo + 8)) static set setter(x: undefined) { }\n\n          @(capture(() => new Foo().#foo + 9)) accessor accessor: undefined\n          @(capture(() => new Foo().#foo + 10)) static accessor accessor: undefined\n        })\n      }\n    }\n\n    // Accessing the outer \"#foo\" on \"Outer\" from within the class decorator\n    // should succeed. Class decorators are evaluated in the outer private\n    // environment before entering \"ClassDefinitionEvaluation\".\n    //\n    // Accessing the inner \"#foo\" on \"Foo\" from within any of the class element\n    // decorators should also succeed. Class element decorators are evaluated\n    // in the inner private environment inside \"ClassDefinitionEvaluation\".\n    const log: number[] = []\n    for (const fn of fns) log.push(fn())\n    assertEq(() => '' + log, '0,11,12,13,14,15,16,17,18,19,20')\n  },\n  'Decorator list evaluation: Class binding (class statement)': () => {\n    const fns: (() => typeof Foo)[] = []\n\n    const capture = (fn: () => typeof Foo): Function => {\n      fns.push(fn)\n\n      // Note: As far as I can tell, early reference to the class name should\n      // throw a reference error because:\n      //\n      // 1. Class decorators run first in the top-level scope before entering\n      //    BindingClassDeclarationEvaluation.\n      //\n      // 2. Class element decorators run in ClassDefinitionEvaluation, which\n      //    runs ClassElementEvaluation for each class element before eventually\n      //    running classEnv.InitializeBinding(classBinding, F).\n      //\n      assertThrows(() => fn(), ReferenceError)\n      return () => { }\n    }\n\n    @(capture(() => Foo)) class Foo {\n      @(capture(() => Foo)) method() { }\n      @(capture(() => Foo)) static method() { }\n\n      @(capture(() => Foo)) field: undefined\n      @(capture(() => Foo)) static field: undefined\n\n      @(capture(() => Foo)) get getter(): undefined { return }\n      @(capture(() => Foo)) static get getter(): undefined { return }\n\n      @(capture(() => Foo)) set setter(x: undefined) { }\n      @(capture(() => Foo)) static set setter(x: undefined) { }\n\n      @(capture(() => Foo)) accessor accessor: undefined\n      @(capture(() => Foo)) static accessor accessor: undefined\n    }\n\n    const originalFoo = Foo\n\n    // Once we get here, these should all reference the now-initialized class,\n    // either through classBinding (for class element decorators) or through\n    // className (for decorators on the class itself).\n    for (const fn of fns) {\n      assertEq(() => fn(), originalFoo)\n    }\n\n    // Mutating a class binding is allowed in JavaScript. Let's test what\n    // happens when we do this.\n    (Foo as any) = null as any\n\n    // As far as I can tell, class decorators should observe this change because\n    // they are evaluated in the top-level scope.\n    const firstFn = fns.shift()!\n    assertEq(() => firstFn(), null)\n\n    // But I believe class element decorators should not observe this change\n    // because they are evaluated in the environment that exists for the\n    // duration of ClassDefinitionEvaluation (i.e. classEnv, not env).\n    for (const fn of fns) {\n      assertEq(() => fn(), originalFoo)\n    }\n  },\n  'Decorator list evaluation: Class binding (class expression)': () => {\n    const fns: (() => { new(): Object })[] = []\n\n    const capture = (fn: () => { new(): Object }): Function => {\n      fns.push(fn)\n      return () => { }\n    }\n\n    const originalFoo = (@(capture(() => Foo)) class Foo {\n      @(capture(() => Foo)) method() { }\n      @(capture(() => Foo)) static method() { }\n\n      @(capture(() => Foo)) field: undefined\n      @(capture(() => Foo)) static field: undefined\n\n      @(capture(() => Foo)) get getter(): undefined { return }\n      @(capture(() => Foo)) static get getter(): undefined { return }\n\n      @(capture(() => Foo)) set setter(x: undefined) { }\n      @(capture(() => Foo)) static set setter(x: undefined) { }\n\n      @(capture(() => Foo)) accessor accessor: undefined\n      @(capture(() => Foo)) static accessor accessor: undefined\n    })\n\n    // Decorators on the class itself should reference a global called \"Foo\",\n    // which should still be a reference error. This is because a class\n    // expression runs \"DecoratorListEvaluation\" in the outer environment and\n    // then passes the evaluated decorators to \"ClassDefinitionEvaluation\".\n    const firstFn = fns.shift()!\n    assertThrows(() => firstFn(), ReferenceError)\n\n    // All other decorators should reference the classBinding called \"Foo\",\n    // which should now be initialized. This is because all other decorators\n    // are evaluated within \"ClassDefinitionEvaluation\" while the running\n    // execution context's environment is the nested class environment.\n    for (const fn of fns) {\n      assertEq(() => fn(), originalFoo)\n    }\n  },\n\n  // Decorator metadata\n  'Decorator metadata: class statement': () => {\n    let counter = 0\n    const dec = (_: any, ctx: DecoratorContext) => {\n      ctx.metadata[ctx.name!] = counter++\n    }\n    @dec class Foo {\n      @dec instanceField: undefined\n      @dec accessor instanceAccessor: undefined\n      @dec instanceMethod() { }\n      @dec get instanceGetter() { return }\n      @dec set instanceSetter(_: undefined) { }\n\n      @dec static staticField: undefined\n      @dec static accessor staticAccessor: undefined\n      @dec static staticMethod() { }\n      @dec static get staticGetter() { return }\n      @dec static set staticSetter(_: undefined) { }\n    }\n    @dec class Bar extends Foo {\n      @dec #instanceField: undefined\n      @dec accessor #instanceAccessor: undefined\n      @dec #instanceMethod() { }\n      @dec get #instanceGetter() { return }\n      @dec set #instanceSetter(_: undefined) { }\n\n      @dec static #staticField: undefined\n      @dec static accessor #staticAccessor: undefined\n      @dec static #staticMethod() { }\n      @dec static get #staticGetter() { return }\n      @dec static set #staticSetter(_: undefined) { }\n    }\n    const order = (meta: DecoratorMetadataObject) => '' + [\n      meta['staticAccessor'], meta['staticMethod'], meta['staticGetter'], meta['staticSetter'],\n      meta['#staticAccessor'], meta['#staticMethod'], meta['#staticGetter'], meta['#staticSetter'],\n      meta['instanceAccessor'], meta['instanceMethod'], meta['instanceGetter'], meta['instanceSetter'],\n      meta['#instanceAccessor'], meta['#instanceMethod'], meta['#instanceGetter'], meta['#instanceSetter'],\n      meta['staticField'], meta['#staticField'],\n      meta['instanceField'], meta['#instanceField'],\n      meta['Foo'], meta['Bar'],\n    ]\n    const foo = Foo[Symbol.metadata]!\n    const bar = Bar[Symbol.metadata]!\n    assertEq(() => order(foo), '0,1,2,3,,,,,4,5,6,7,,,,,8,,9,,10,')\n    assertEq(() => Object.getPrototypeOf(foo), null)\n    assertEq(() => order(bar), '0,1,2,3,11,12,13,14,4,5,6,7,15,16,17,18,8,19,9,20,10,21')\n    assertEq(() => Object.getPrototypeOf(bar), foo)\n\n    // Test an undecorated class\n    class FooNoDec { }\n    class BarNoDec extends FooNoDec { }\n    assertEq(() => FooNoDec[Symbol.metadata], null)\n    assertEq(() => BarNoDec[Symbol.metadata], null)\n\n    // Test a class with no class decorator\n    class FooOneDec { @dec x: undefined }\n    class BarOneDec extends FooOneDec { @dec y: undefined }\n    assertEq(() => JSON.stringify(FooOneDec[Symbol.metadata]!), JSON.stringify({ x: 22 }))\n    assertEq(() => JSON.stringify(BarOneDec[Symbol.metadata]!), JSON.stringify({ y: 23 }))\n    assertEq(() => Object.getPrototypeOf(BarOneDec[Symbol.metadata]!), FooOneDec[Symbol.metadata]!)\n  },\n  'Decorator metadata: class expression': () => {\n    let counter = 0\n    const dec = (_: any, ctx: DecoratorContext) => {\n      ctx.metadata[ctx.name!] = counter++\n    }\n    const Foo = @dec class {\n      @dec instanceField: undefined\n      @dec accessor instanceAccessor: undefined\n      @dec instanceMethod() { }\n      @dec get instanceGetter() { return }\n      @dec set instanceSetter(_: undefined) { }\n\n      @dec static staticField: undefined\n      @dec static accessor staticAccessor: undefined\n      @dec static staticMethod() { }\n      @dec static get staticGetter() { return }\n      @dec static set staticSetter(_: undefined) { }\n    }, Bar = @dec class extends Foo {\n      @dec #instanceField: undefined\n      @dec accessor #instanceAccessor: undefined\n      @dec #instanceMethod() { }\n      @dec get #instanceGetter() { return }\n      @dec set #instanceSetter(_: undefined) { }\n\n      @dec static #staticField: undefined\n      @dec static accessor #staticAccessor: undefined\n      @dec static #staticMethod() { }\n      @dec static get #staticGetter() { return }\n      @dec static set #staticSetter(_: undefined) { }\n    }\n    const order = (meta: DecoratorMetadataObject) => '' + [\n      meta['staticAccessor'], meta['staticMethod'], meta['staticGetter'], meta['staticSetter'],\n      meta['#staticAccessor'], meta['#staticMethod'], meta['#staticGetter'], meta['#staticSetter'],\n      meta['instanceAccessor'], meta['instanceMethod'], meta['instanceGetter'], meta['instanceSetter'],\n      meta['#instanceAccessor'], meta['#instanceMethod'], meta['#instanceGetter'], meta['#instanceSetter'],\n      meta['staticField'], meta['#staticField'],\n      meta['instanceField'], meta['#instanceField'],\n      meta['Foo'], meta['Bar'],\n    ]\n    const foo = Foo[Symbol.metadata]!\n    const bar = Bar[Symbol.metadata]!\n    assertEq(() => order(foo), '0,1,2,3,,,,,4,5,6,7,,,,,8,,9,,10,')\n    assertEq(() => Object.getPrototypeOf(foo), null)\n    assertEq(() => order(bar), '0,1,2,3,11,12,13,14,4,5,6,7,15,16,17,18,8,19,9,20,10,21')\n    assertEq(() => Object.getPrototypeOf(bar), foo)\n\n    // Test an undecorated class\n    const FooNoDec = class { }\n    const BarNoDec = class extends FooNoDec { }\n    assertEq(() => FooNoDec[Symbol.metadata], null)\n    assertEq(() => BarNoDec[Symbol.metadata], null)\n\n    // Test a class with no class decorator\n    const FooOneDec = class { @dec x: undefined }\n    const BarOneDec = class extends FooOneDec { @dec y: undefined }\n    assertEq(() => JSON.stringify(FooOneDec[Symbol.metadata]!), JSON.stringify({ x: 22 }))\n    assertEq(() => JSON.stringify(BarOneDec[Symbol.metadata]!), JSON.stringify({ y: 23 }))\n    assertEq(() => Object.getPrototypeOf(BarOneDec[Symbol.metadata]!), FooOneDec[Symbol.metadata]!)\n  },\n\n  // Initializer order\n  'Initializer order (public members, class statement)': () => {\n    const log: string[] = []\n\n    // Class decorators\n    const classDec1 = (cls: { new(): Foo }, ctxClass: ClassDecoratorContext) => {\n      log.push('c2')\n      if (!assertEq(() => typeof ctxClass.addInitializer, 'function')) return\n      ctxClass.addInitializer(() => log.push('c5'))\n      ctxClass.addInitializer(() => log.push('c6'))\n    }\n    const classDec2 = (cls: { new(): Foo }, ctxClass: ClassDecoratorContext) => {\n      log.push('c1')\n      if (!assertEq(() => typeof ctxClass.addInitializer, 'function')) return\n      ctxClass.addInitializer(() => log.push('c3'))\n      ctxClass.addInitializer(() => log.push('c4'))\n    }\n\n    // Method decorators\n    const methodDec1 = (fn: (this: Foo) => void, ctxMethod: ClassMethodDecoratorContext) => {\n      log.push('m2')\n      if (!assertEq(() => typeof ctxMethod.addInitializer, 'function')) return\n      ctxMethod.addInitializer(() => log.push('m5'))\n      ctxMethod.addInitializer(() => log.push('m6'))\n    }\n    const methodDec2 = (fn: (this: Foo) => void, ctxMethod: ClassMethodDecoratorContext) => {\n      log.push('m1')\n      if (!assertEq(() => typeof ctxMethod.addInitializer, 'function')) return\n      ctxMethod.addInitializer(() => log.push('m3'))\n      ctxMethod.addInitializer(() => log.push('m4'))\n    }\n    const staticMethodDec1 = (fn: (this: Foo) => void, ctxStaticMethod: ClassMethodDecoratorContext) => {\n      log.push('M2')\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, 'function')) return\n      ctxStaticMethod.addInitializer(() => log.push('M5'))\n      ctxStaticMethod.addInitializer(() => log.push('M6'))\n    }\n    const staticMethodDec2 = (fn: (this: Foo) => void, ctxStaticMethod: ClassMethodDecoratorContext) => {\n      log.push('M1')\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, 'function')) return\n      ctxStaticMethod.addInitializer(() => log.push('M3'))\n      ctxStaticMethod.addInitializer(() => log.push('M4'))\n    }\n\n    // Field decorators\n    const fieldDec1 = (\n      value: undefined,\n      ctxField: ClassFieldDecoratorContext,\n    ): ((this: Foo, value: undefined) => undefined) | undefined => {\n      log.push('f2')\n      if (!assertEq(() => typeof ctxField.addInitializer, 'function')) return\n      ctxField.addInitializer(() => log.push('f5'))\n      ctxField.addInitializer(() => log.push('f6'))\n      return () => { log.push('f7') }\n    }\n    const fieldDec2 = (\n      value: undefined,\n      ctxField: ClassFieldDecoratorContext,\n    ): ((this: Foo, value: undefined) => undefined) | undefined => {\n      log.push('f1')\n      if (!assertEq(() => typeof ctxField.addInitializer, 'function')) return\n      ctxField.addInitializer(() => log.push('f3'))\n      ctxField.addInitializer(() => log.push('f4'))\n      return () => { log.push('f8') }\n    }\n    const staticFieldDec1 = (\n      value: undefined,\n      ctxStaticField: ClassFieldDecoratorContext,\n    ): ((this: typeof Foo, value: undefined) => undefined) | undefined => {\n      log.push('F2')\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, 'function')) return\n      ctxStaticField.addInitializer(() => log.push('F5'))\n      ctxStaticField.addInitializer(() => log.push('F6'))\n      return () => { log.push('F7') }\n    }\n    const staticFieldDec2 = (\n      value: undefined,\n      ctxStaticField: ClassFieldDecoratorContext,\n    ): ((this: typeof Foo, value: undefined) => undefined) | undefined => {\n      log.push('F1')\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, 'function')) return\n      ctxStaticField.addInitializer(() => log.push('F3'))\n      ctxStaticField.addInitializer(() => log.push('F4'))\n      return () => { log.push('F8') }\n    }\n\n    // Getter decorators\n    const getterDec1 = (fn: (this: Foo) => undefined, ctxGetter: ClassGetterDecoratorContext) => {\n      log.push('g2')\n      if (!assertEq(() => typeof ctxGetter.addInitializer, 'function')) return\n      ctxGetter.addInitializer(() => log.push('g5'))\n      ctxGetter.addInitializer(() => log.push('g6'))\n    }\n    const getterDec2 = (fn: (this: Foo) => undefined, ctxGetter: ClassGetterDecoratorContext) => {\n      log.push('g1')\n      if (!assertEq(() => typeof ctxGetter.addInitializer, 'function')) return\n      ctxGetter.addInitializer(() => log.push('g3'))\n      ctxGetter.addInitializer(() => log.push('g4'))\n    }\n    const staticGetterDec1 = (fn: (this: Foo) => undefined, ctxStaticGetter: ClassGetterDecoratorContext) => {\n      log.push('G2')\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, 'function')) return\n      ctxStaticGetter.addInitializer(() => log.push('G5'))\n      ctxStaticGetter.addInitializer(() => log.push('G6'))\n    }\n    const staticGetterDec2 = (fn: (this: Foo) => undefined, ctxStaticGetter: ClassGetterDecoratorContext) => {\n      log.push('G1')\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, 'function')) return\n      ctxStaticGetter.addInitializer(() => log.push('G3'))\n      ctxStaticGetter.addInitializer(() => log.push('G4'))\n    }\n\n    // Setter decorators\n    const setterDec1 = (fn: (this: Foo, x: undefined) => void, ctxSetter: ClassSetterDecoratorContext) => {\n      log.push('s2')\n      if (!assertEq(() => typeof ctxSetter.addInitializer, 'function')) return\n      ctxSetter.addInitializer(() => log.push('s5'))\n      ctxSetter.addInitializer(() => log.push('s6'))\n    }\n    const setterDec2 = (fn: (this: Foo, x: undefined) => void, ctxSetter: ClassSetterDecoratorContext) => {\n      log.push('s1')\n      if (!assertEq(() => typeof ctxSetter.addInitializer, 'function')) return\n      ctxSetter.addInitializer(() => log.push('s3'))\n      ctxSetter.addInitializer(() => log.push('s4'))\n    }\n    const staticSetterDec1 = (fn: (this: Foo, x: undefined) => void, ctxStaticSetter: ClassSetterDecoratorContext) => {\n      log.push('S2')\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, 'function')) return\n      ctxStaticSetter.addInitializer(() => log.push('S5'))\n      ctxStaticSetter.addInitializer(() => log.push('S6'))\n    }\n    const staticSetterDec2 = (fn: (this: Foo, x: undefined) => void, ctxStaticSetter: ClassSetterDecoratorContext) => {\n      log.push('S1')\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, 'function')) return\n      ctxStaticSetter.addInitializer(() => log.push('S3'))\n      ctxStaticSetter.addInitializer(() => log.push('S4'))\n    }\n\n    // Auto-accessor decorators\n    const accessorDec1 = (\n      target: ClassAccessorDecoratorTarget<Foo, undefined>,\n      ctxAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<Foo, undefined> | undefined => {\n      log.push('a2')\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, 'function')) return\n      ctxAccessor.addInitializer(() => log.push('a5'))\n      ctxAccessor.addInitializer(() => log.push('a6'))\n      return { init() { log.push('a7') } }\n    }\n    const accessorDec2 = (\n      target: ClassAccessorDecoratorTarget<Foo, undefined>,\n      ctxAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<Foo, undefined> | undefined => {\n      log.push('a1')\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, 'function')) return\n      ctxAccessor.addInitializer(() => log.push('a3'))\n      ctxAccessor.addInitializer(() => log.push('a4'))\n      return { init() { log.push('a8') } }\n    }\n    const staticAccessorDec1 = (\n      target: ClassAccessorDecoratorTarget<typeof Foo, undefined>,\n      ctxStaticAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<typeof Foo, undefined> | undefined => {\n      log.push('A2')\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, 'function')) return\n      ctxStaticAccessor.addInitializer(() => log.push('A5'))\n      ctxStaticAccessor.addInitializer(() => log.push('A6'))\n      return { init() { log.push('A7') } }\n    }\n    const staticAccessorDec2 = (\n      target: ClassAccessorDecoratorTarget<typeof Foo, undefined>,\n      ctxStaticAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<typeof Foo, undefined> | undefined => {\n      log.push('A1')\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, 'function')) return\n      ctxStaticAccessor.addInitializer(() => log.push('A3'))\n      ctxStaticAccessor.addInitializer(() => log.push('A4'))\n      return { init() { log.push('A8') } }\n    }\n\n    log.push('start')\n    @classDec1 @classDec2 class Foo extends (log.push('extends'), Object) {\n      static { log.push('static:start') }\n\n      constructor() {\n        log.push('ctor:start')\n        super()\n        log.push('ctor:end')\n      }\n\n      @methodDec1 @methodDec2 method() { }\n      @staticMethodDec1 @staticMethodDec2 static method() { }\n\n      @fieldDec1 @fieldDec2 field: undefined\n      @staticFieldDec1 @staticFieldDec2 static field: undefined\n\n      @getterDec1 @getterDec2 get getter(): undefined { return }\n      @staticGetterDec1 @staticGetterDec2 static get getter(): undefined { return }\n\n      @setterDec1 @setterDec2 set setter(x: undefined) { }\n      @staticSetterDec1 @staticSetterDec2 static set setter(x: undefined) { }\n\n      @accessorDec1 @accessorDec2 accessor accessor: undefined\n      @staticAccessorDec1 @staticAccessorDec2 static accessor accessor: undefined\n\n      static { log.push('static:end') }\n    }\n    log.push('after')\n    new Foo\n    log.push('end')\n    assertEq(() => log + '', 'start,extends,' +\n      'M1,M2,G1,G2,S1,S2,A1,A2,' + // For each element e of staticElements if e.[[Kind]] is not field\n      'm1,m2,g1,g2,s1,s2,a1,a2,' + // For each element e of instanceElements if e.[[Kind]] is not field\n      'F1,F2,' + // For each element e of staticElements if e.[[Kind]] is field\n      'f1,f2,' + // For each element e of instanceElements if e.[[Kind]] is field\n      'c1,c2,' + // ApplyDecoratorsToClassDefinition\n      'M3,M4,M5,M6,G3,G4,G5,G6,S3,S4,S5,S6,' + // For each element initializer of staticMethodExtraInitializers\n      'static:start,' + // For each element elementRecord of staticElements\n      'F7,F8,F3,F4,F5,F6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'A7,A8,A3,A4,A5,A6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'static:end,' + // For each element elementRecord of staticElements\n      'c3,c4,c5,c6,' + // For each element initializer of classExtraInitializers\n      'after,' +\n      'ctor:start,' +\n      'm3,m4,m5,m6,g3,g4,g5,g6,s3,s4,s5,s6,' + // For each element initializer of constructor.[[Initializers]] (a.k.a. instanceMethodExtraInitializers)\n      'f7,f8,f3,f4,f5,f6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'a7,a8,a3,a4,a5,a6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'ctor:end,' +\n      'end')\n  },\n  'Initializer order (public members, class expression)': () => {\n    const log: string[] = []\n\n    // Class decorators\n    const classDec1 = (cls: { new(): Object }, ctxClass: ClassDecoratorContext) => {\n      log.push('c2')\n      if (!assertEq(() => typeof ctxClass.addInitializer, 'function')) return\n      ctxClass.addInitializer(() => log.push('c5'))\n      ctxClass.addInitializer(() => log.push('c6'))\n    }\n    const classDec2 = (cls: { new(): Object }, ctxClass: ClassDecoratorContext) => {\n      log.push('c1')\n      if (!assertEq(() => typeof ctxClass.addInitializer, 'function')) return\n      ctxClass.addInitializer(() => log.push('c3'))\n      ctxClass.addInitializer(() => log.push('c4'))\n    }\n\n    // Method decorators\n    const methodDec1 = (fn: (this: Object) => void, ctxMethod: ClassMethodDecoratorContext) => {\n      log.push('m2')\n      if (!assertEq(() => typeof ctxMethod.addInitializer, 'function')) return\n      ctxMethod.addInitializer(() => log.push('m5'))\n      ctxMethod.addInitializer(() => log.push('m6'))\n    }\n    const methodDec2 = (fn: (this: Object) => void, ctxMethod: ClassMethodDecoratorContext) => {\n      log.push('m1')\n      if (!assertEq(() => typeof ctxMethod.addInitializer, 'function')) return\n      ctxMethod.addInitializer(() => log.push('m3'))\n      ctxMethod.addInitializer(() => log.push('m4'))\n    }\n    const staticMethodDec1 = (fn: (this: Object) => void, ctxStaticMethod: ClassMethodDecoratorContext) => {\n      log.push('M2')\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, 'function')) return\n      ctxStaticMethod.addInitializer(() => log.push('M5'))\n      ctxStaticMethod.addInitializer(() => log.push('M6'))\n    }\n    const staticMethodDec2 = (fn: (this: Object) => void, ctxStaticMethod: ClassMethodDecoratorContext) => {\n      log.push('M1')\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, 'function')) return\n      ctxStaticMethod.addInitializer(() => log.push('M3'))\n      ctxStaticMethod.addInitializer(() => log.push('M4'))\n    }\n\n    // Field decorators\n    const fieldDec1 = (\n      value: undefined,\n      ctxField: ClassFieldDecoratorContext,\n    ): ((this: Object, value: undefined) => undefined) | undefined => {\n      log.push('f2')\n      if (!assertEq(() => typeof ctxField.addInitializer, 'function')) return\n      ctxField.addInitializer(() => log.push('f5'))\n      ctxField.addInitializer(() => log.push('f6'))\n      return () => { log.push('f7') }\n    }\n    const fieldDec2 = (\n      value: undefined,\n      ctxField: ClassFieldDecoratorContext,\n    ): ((this: Object, value: undefined) => undefined) | undefined => {\n      log.push('f1')\n      if (!assertEq(() => typeof ctxField.addInitializer, 'function')) return\n      ctxField.addInitializer(() => log.push('f3'))\n      ctxField.addInitializer(() => log.push('f4'))\n      return () => { log.push('f8') }\n    }\n    const staticFieldDec1 = (\n      value: undefined,\n      ctxStaticField: ClassFieldDecoratorContext,\n    ): ((this: Object, value: undefined) => undefined) | undefined => {\n      log.push('F2')\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, 'function')) return\n      ctxStaticField.addInitializer(() => log.push('F5'))\n      ctxStaticField.addInitializer(() => log.push('F6'))\n      return () => { log.push('F7') }\n    }\n    const staticFieldDec2 = (\n      value: undefined,\n      ctxStaticField: ClassFieldDecoratorContext,\n    ): ((this: Object, value: undefined) => undefined) | undefined => {\n      log.push('F1')\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, 'function')) return\n      ctxStaticField.addInitializer(() => log.push('F3'))\n      ctxStaticField.addInitializer(() => log.push('F4'))\n      return () => { log.push('F8') }\n    }\n\n    // Getter decorators\n    const getterDec1 = (fn: (this: Object) => undefined, ctxGetter: ClassGetterDecoratorContext) => {\n      log.push('g2')\n      if (!assertEq(() => typeof ctxGetter.addInitializer, 'function')) return\n      ctxGetter.addInitializer(() => log.push('g5'))\n      ctxGetter.addInitializer(() => log.push('g6'))\n    }\n    const getterDec2 = (fn: (this: Object) => undefined, ctxGetter: ClassGetterDecoratorContext) => {\n      log.push('g1')\n      if (!assertEq(() => typeof ctxGetter.addInitializer, 'function')) return\n      ctxGetter.addInitializer(() => log.push('g3'))\n      ctxGetter.addInitializer(() => log.push('g4'))\n    }\n    const staticGetterDec1 = (fn: (this: Object) => undefined, ctxStaticGetter: ClassGetterDecoratorContext) => {\n      log.push('G2')\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, 'function')) return\n      ctxStaticGetter.addInitializer(() => log.push('G5'))\n      ctxStaticGetter.addInitializer(() => log.push('G6'))\n    }\n    const staticGetterDec2 = (fn: (this: Object) => undefined, ctxStaticGetter: ClassGetterDecoratorContext) => {\n      log.push('G1')\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, 'function')) return\n      ctxStaticGetter.addInitializer(() => log.push('G3'))\n      ctxStaticGetter.addInitializer(() => log.push('G4'))\n    }\n\n    // Setter decorators\n    const setterDec1 = (fn: (this: Object, x: undefined) => void, ctxSetter: ClassSetterDecoratorContext) => {\n      log.push('s2')\n      if (!assertEq(() => typeof ctxSetter.addInitializer, 'function')) return\n      ctxSetter.addInitializer(() => log.push('s5'))\n      ctxSetter.addInitializer(() => log.push('s6'))\n    }\n    const setterDec2 = (fn: (this: Object, x: undefined) => void, ctxSetter: ClassSetterDecoratorContext) => {\n      log.push('s1')\n      if (!assertEq(() => typeof ctxSetter.addInitializer, 'function')) return\n      ctxSetter.addInitializer(() => log.push('s3'))\n      ctxSetter.addInitializer(() => log.push('s4'))\n    }\n    const staticSetterDec1 = (fn: (this: Object, x: undefined) => void, ctxStaticSetter: ClassSetterDecoratorContext) => {\n      log.push('S2')\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, 'function')) return\n      ctxStaticSetter.addInitializer(() => log.push('S5'))\n      ctxStaticSetter.addInitializer(() => log.push('S6'))\n    }\n    const staticSetterDec2 = (fn: (this: Object, x: undefined) => void, ctxStaticSetter: ClassSetterDecoratorContext) => {\n      log.push('S1')\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, 'function')) return\n      ctxStaticSetter.addInitializer(() => log.push('S3'))\n      ctxStaticSetter.addInitializer(() => log.push('S4'))\n    }\n\n    // Auto-accessor decorators\n    const accessorDec1 = (\n      target: ClassAccessorDecoratorTarget<Object, undefined>,\n      ctxAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<Object, undefined> | undefined => {\n      log.push('a2')\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, 'function')) return\n      ctxAccessor.addInitializer(() => log.push('a5'))\n      ctxAccessor.addInitializer(() => log.push('a6'))\n      return { init() { log.push('a7') } }\n    }\n    const accessorDec2 = (\n      target: ClassAccessorDecoratorTarget<Object, undefined>,\n      ctxAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<Object, undefined> | undefined => {\n      log.push('a1')\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, 'function')) return\n      ctxAccessor.addInitializer(() => log.push('a3'))\n      ctxAccessor.addInitializer(() => log.push('a4'))\n      return { init() { log.push('a8') } }\n    }\n    const staticAccessorDec1 = (\n      target: ClassAccessorDecoratorTarget<Object, undefined>,\n      ctxStaticAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<Object, undefined> | undefined => {\n      log.push('A2')\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, 'function')) return\n      ctxStaticAccessor.addInitializer(() => log.push('A5'))\n      ctxStaticAccessor.addInitializer(() => log.push('A6'))\n      return { init() { log.push('A7') } }\n    }\n    const staticAccessorDec2 = (\n      target: ClassAccessorDecoratorTarget<Object, undefined>,\n      ctxStaticAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<Object, undefined> | undefined => {\n      log.push('A1')\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, 'function')) return\n      ctxStaticAccessor.addInitializer(() => log.push('A3'))\n      ctxStaticAccessor.addInitializer(() => log.push('A4'))\n      return { init() { log.push('A8') } }\n    }\n\n    log.push('start')\n    const Foo = @classDec1 @classDec2 class extends (log.push('extends'), Object) {\n      static { log.push('static:start') }\n\n      constructor() {\n        log.push('ctor:start')\n        super()\n        log.push('ctor:end')\n      }\n\n      @methodDec1 @methodDec2 method() { }\n      @staticMethodDec1 @staticMethodDec2 static method() { }\n\n      @fieldDec1 @fieldDec2 field: undefined\n      @staticFieldDec1 @staticFieldDec2 static field: undefined\n\n      @getterDec1 @getterDec2 get getter(): undefined { return }\n      @staticGetterDec1 @staticGetterDec2 static get getter(): undefined { return }\n\n      @setterDec1 @setterDec2 set setter(x: undefined) { }\n      @staticSetterDec1 @staticSetterDec2 static set setter(x: undefined) { }\n\n      @accessorDec1 @accessorDec2 accessor accessor: undefined\n      @staticAccessorDec1 @staticAccessorDec2 static accessor accessor: undefined\n\n      static { log.push('static:end') }\n    }\n    log.push('after')\n    new Foo\n    log.push('end')\n    assertEq(() => log + '', 'start,extends,' +\n      'M1,M2,G1,G2,S1,S2,A1,A2,' + // For each element e of staticElements if e.[[Kind]] is not field\n      'm1,m2,g1,g2,s1,s2,a1,a2,' + // For each element e of instanceElements if e.[[Kind]] is not field\n      'F1,F2,' + // For each element e of staticElements if e.[[Kind]] is field\n      'f1,f2,' + // For each element e of instanceElements if e.[[Kind]] is field\n      'c1,c2,' + // ApplyDecoratorsToClassDefinition\n      'M3,M4,M5,M6,G3,G4,G5,G6,S3,S4,S5,S6,' + // For each element initializer of staticMethodExtraInitializers\n      'static:start,' + // For each element elementRecord of staticElements\n      'F7,F8,F3,F4,F5,F6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'A7,A8,A3,A4,A5,A6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'static:end,' + // For each element elementRecord of staticElements\n      'c3,c4,c5,c6,' + // For each element initializer of classExtraInitializers\n      'after,' +\n      'ctor:start,' +\n      'm3,m4,m5,m6,g3,g4,g5,g6,s3,s4,s5,s6,' + // For each element initializer of constructor.[[Initializers]] (a.k.a. instanceMethodExtraInitializers)\n      'f7,f8,f3,f4,f5,f6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'a7,a8,a3,a4,a5,a6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'ctor:end,' +\n      'end')\n  },\n  'Initializer order (private members, class statement)': () => {\n    const log: string[] = []\n\n    // Class decorators\n    const classDec1 = (cls: { new(): Foo }, ctxClass: ClassDecoratorContext) => {\n      log.push('c2')\n      if (!assertEq(() => typeof ctxClass.addInitializer, 'function')) return\n      ctxClass.addInitializer(() => log.push('c5'))\n      ctxClass.addInitializer(() => log.push('c6'))\n    }\n    const classDec2 = (cls: { new(): Foo }, ctxClass: ClassDecoratorContext) => {\n      log.push('c1')\n      if (!assertEq(() => typeof ctxClass.addInitializer, 'function')) return\n      ctxClass.addInitializer(() => log.push('c3'))\n      ctxClass.addInitializer(() => log.push('c4'))\n    }\n\n    // Method decorators\n    const methodDec1 = (fn: (this: Foo) => void, ctxMethod: ClassMethodDecoratorContext) => {\n      log.push('m2')\n      if (!assertEq(() => typeof ctxMethod.addInitializer, 'function')) return\n      ctxMethod.addInitializer(() => log.push('m5'))\n      ctxMethod.addInitializer(() => log.push('m6'))\n    }\n    const methodDec2 = (fn: (this: Foo) => void, ctxMethod: ClassMethodDecoratorContext) => {\n      log.push('m1')\n      if (!assertEq(() => typeof ctxMethod.addInitializer, 'function')) return\n      ctxMethod.addInitializer(() => log.push('m3'))\n      ctxMethod.addInitializer(() => log.push('m4'))\n    }\n    const staticMethodDec1 = (fn: (this: Foo) => void, ctxStaticMethod: ClassMethodDecoratorContext) => {\n      log.push('M2')\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, 'function')) return\n      ctxStaticMethod.addInitializer(() => log.push('M5'))\n      ctxStaticMethod.addInitializer(() => log.push('M6'))\n    }\n    const staticMethodDec2 = (fn: (this: Foo) => void, ctxStaticMethod: ClassMethodDecoratorContext) => {\n      log.push('M1')\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, 'function')) return\n      ctxStaticMethod.addInitializer(() => log.push('M3'))\n      ctxStaticMethod.addInitializer(() => log.push('M4'))\n    }\n\n    // Field decorators\n    const fieldDec1 = (\n      value: undefined,\n      ctxField: ClassFieldDecoratorContext,\n    ): ((this: Foo, value: undefined) => undefined) | undefined => {\n      log.push('f2')\n      if (!assertEq(() => typeof ctxField.addInitializer, 'function')) return\n      ctxField.addInitializer(() => log.push('f5'))\n      ctxField.addInitializer(() => log.push('f6'))\n      return () => { log.push('f7') }\n    }\n    const fieldDec2 = (\n      value: undefined,\n      ctxField: ClassFieldDecoratorContext,\n    ): ((this: Foo, value: undefined) => undefined) | undefined => {\n      log.push('f1')\n      if (!assertEq(() => typeof ctxField.addInitializer, 'function')) return\n      ctxField.addInitializer(() => log.push('f3'))\n      ctxField.addInitializer(() => log.push('f4'))\n      return () => { log.push('f8') }\n    }\n    const staticFieldDec1 = (\n      value: undefined,\n      ctxStaticField: ClassFieldDecoratorContext,\n    ): ((this: typeof Foo, value: undefined) => undefined) | undefined => {\n      log.push('F2')\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, 'function')) return\n      ctxStaticField.addInitializer(() => log.push('F5'))\n      ctxStaticField.addInitializer(() => log.push('F6'))\n      return () => { log.push('F7') }\n    }\n    const staticFieldDec2 = (\n      value: undefined,\n      ctxStaticField: ClassFieldDecoratorContext,\n    ): ((this: typeof Foo, value: undefined) => undefined) | undefined => {\n      log.push('F1')\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, 'function')) return\n      ctxStaticField.addInitializer(() => log.push('F3'))\n      ctxStaticField.addInitializer(() => log.push('F4'))\n      return () => { log.push('F8') }\n    }\n\n    // Getter decorators\n    const getterDec1 = (fn: (this: Foo) => undefined, ctxGetter: ClassGetterDecoratorContext) => {\n      log.push('g2')\n      if (!assertEq(() => typeof ctxGetter.addInitializer, 'function')) return\n      ctxGetter.addInitializer(() => log.push('g5'))\n      ctxGetter.addInitializer(() => log.push('g6'))\n    }\n    const getterDec2 = (fn: (this: Foo) => undefined, ctxGetter: ClassGetterDecoratorContext) => {\n      log.push('g1')\n      if (!assertEq(() => typeof ctxGetter.addInitializer, 'function')) return\n      ctxGetter.addInitializer(() => log.push('g3'))\n      ctxGetter.addInitializer(() => log.push('g4'))\n    }\n    const staticGetterDec1 = (fn: (this: Foo) => undefined, ctxStaticGetter: ClassGetterDecoratorContext) => {\n      log.push('G2')\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, 'function')) return\n      ctxStaticGetter.addInitializer(() => log.push('G5'))\n      ctxStaticGetter.addInitializer(() => log.push('G6'))\n    }\n    const staticGetterDec2 = (fn: (this: Foo) => undefined, ctxStaticGetter: ClassGetterDecoratorContext) => {\n      log.push('G1')\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, 'function')) return\n      ctxStaticGetter.addInitializer(() => log.push('G3'))\n      ctxStaticGetter.addInitializer(() => log.push('G4'))\n    }\n\n    // Setter decorators\n    const setterDec1 = (fn: (this: Foo, x: undefined) => void, ctxSetter: ClassSetterDecoratorContext) => {\n      log.push('s2')\n      if (!assertEq(() => typeof ctxSetter.addInitializer, 'function')) return\n      ctxSetter.addInitializer(() => log.push('s5'))\n      ctxSetter.addInitializer(() => log.push('s6'))\n    }\n    const setterDec2 = (fn: (this: Foo, x: undefined) => void, ctxSetter: ClassSetterDecoratorContext) => {\n      log.push('s1')\n      if (!assertEq(() => typeof ctxSetter.addInitializer, 'function')) return\n      ctxSetter.addInitializer(() => log.push('s3'))\n      ctxSetter.addInitializer(() => log.push('s4'))\n    }\n    const staticSetterDec1 = (fn: (this: Foo, x: undefined) => void, ctxStaticSetter: ClassSetterDecoratorContext) => {\n      log.push('S2')\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, 'function')) return\n      ctxStaticSetter.addInitializer(() => log.push('S5'))\n      ctxStaticSetter.addInitializer(() => log.push('S6'))\n    }\n    const staticSetterDec2 = (fn: (this: Foo, x: undefined) => void, ctxStaticSetter: ClassSetterDecoratorContext) => {\n      log.push('S1')\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, 'function')) return\n      ctxStaticSetter.addInitializer(() => log.push('S3'))\n      ctxStaticSetter.addInitializer(() => log.push('S4'))\n    }\n\n    // Auto-accessor decorators\n    const accessorDec1 = (\n      target: ClassAccessorDecoratorTarget<Foo, undefined>,\n      ctxAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<Foo, undefined> | undefined => {\n      log.push('a2')\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, 'function')) return\n      ctxAccessor.addInitializer(() => log.push('a5'))\n      ctxAccessor.addInitializer(() => log.push('a6'))\n      return { init() { log.push('a7') } }\n    }\n    const accessorDec2 = (\n      target: ClassAccessorDecoratorTarget<Foo, undefined>,\n      ctxAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<Foo, undefined> | undefined => {\n      log.push('a1')\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, 'function')) return\n      ctxAccessor.addInitializer(() => log.push('a3'))\n      ctxAccessor.addInitializer(() => log.push('a4'))\n      return { init() { log.push('a8') } }\n    }\n    const staticAccessorDec1 = (\n      target: ClassAccessorDecoratorTarget<typeof Foo, undefined>,\n      ctxStaticAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<typeof Foo, undefined> | undefined => {\n      log.push('A2')\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, 'function')) return\n      ctxStaticAccessor.addInitializer(() => log.push('A5'))\n      ctxStaticAccessor.addInitializer(() => log.push('A6'))\n      return { init() { log.push('A7') } }\n    }\n    const staticAccessorDec2 = (\n      target: ClassAccessorDecoratorTarget<typeof Foo, undefined>,\n      ctxStaticAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<typeof Foo, undefined> | undefined => {\n      log.push('A1')\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, 'function')) return\n      ctxStaticAccessor.addInitializer(() => log.push('A3'))\n      ctxStaticAccessor.addInitializer(() => log.push('A4'))\n      return { init() { log.push('A8') } }\n    }\n\n    log.push('start')\n    @classDec1 @classDec2 class Foo extends (log.push('extends'), Object) {\n      static { log.push('static:start') }\n\n      constructor() {\n        log.push('ctor:start')\n        super()\n        log.push('ctor:end')\n      }\n\n      @methodDec1 @methodDec2 #method() { }\n      @staticMethodDec1 @staticMethodDec2 static #staticMethod() { }\n\n      @fieldDec1 @fieldDec2 #field: undefined\n      @staticFieldDec1 @staticFieldDec2 static #staticField: undefined\n\n      @getterDec1 @getterDec2 get #getter(): undefined { return }\n      @staticGetterDec1 @staticGetterDec2 static get #staticGetter(): undefined { return }\n\n      @setterDec1 @setterDec2 set #setter(x: undefined) { }\n      @staticSetterDec1 @staticSetterDec2 static set #staticSetter(x: undefined) { }\n\n      @accessorDec1 @accessorDec2 accessor #accessor: undefined\n      @staticAccessorDec1 @staticAccessorDec2 static accessor #staticAccessor: undefined\n\n      static { log.push('static:end') }\n    }\n    log.push('after')\n    new Foo\n    log.push('end')\n    assertEq(() => log + '', 'start,extends,' +\n      'M1,M2,G1,G2,S1,S2,A1,A2,' + // For each element e of staticElements if e.[[Kind]] is not field\n      'm1,m2,g1,g2,s1,s2,a1,a2,' + // For each element e of instanceElements if e.[[Kind]] is not field\n      'F1,F2,' + // For each element e of staticElements if e.[[Kind]] is field\n      'f1,f2,' + // For each element e of instanceElements if e.[[Kind]] is field\n      'c1,c2,' + // ApplyDecoratorsToClassDefinition\n      'M3,M4,M5,M6,G3,G4,G5,G6,S3,S4,S5,S6,' + // For each element initializer of staticMethodExtraInitializers\n      'static:start,' + // For each element elementRecord of staticElements\n      'F7,F8,F3,F4,F5,F6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'A7,A8,A3,A4,A5,A6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'static:end,' + // For each element elementRecord of staticElements\n      'c3,c4,c5,c6,' + // For each element initializer of classExtraInitializers\n      'after,' +\n      'ctor:start,' +\n      'm3,m4,m5,m6,g3,g4,g5,g6,s3,s4,s5,s6,' + // For each element initializer of constructor.[[Initializers]] (a.k.a. instanceMethodExtraInitializers)\n      'f7,f8,f3,f4,f5,f6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'a7,a8,a3,a4,a5,a6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'ctor:end,' +\n      'end')\n  },\n  'Initializer order (private members, class expression)': () => {\n    const log: string[] = []\n\n    // Class decorators\n    const classDec1 = (cls: { new(): Object }, ctxClass: ClassDecoratorContext) => {\n      log.push('c2')\n      if (!assertEq(() => typeof ctxClass.addInitializer, 'function')) return\n      ctxClass.addInitializer(() => log.push('c5'))\n      ctxClass.addInitializer(() => log.push('c6'))\n    }\n    const classDec2 = (cls: { new(): Object }, ctxClass: ClassDecoratorContext) => {\n      log.push('c1')\n      if (!assertEq(() => typeof ctxClass.addInitializer, 'function')) return\n      ctxClass.addInitializer(() => log.push('c3'))\n      ctxClass.addInitializer(() => log.push('c4'))\n    }\n\n    // Method decorators\n    const methodDec1 = (fn: (this: Object) => void, ctxMethod: ClassMethodDecoratorContext) => {\n      log.push('m2')\n      if (!assertEq(() => typeof ctxMethod.addInitializer, 'function')) return\n      ctxMethod.addInitializer(() => log.push('m5'))\n      ctxMethod.addInitializer(() => log.push('m6'))\n    }\n    const methodDec2 = (fn: (this: Object) => void, ctxMethod: ClassMethodDecoratorContext) => {\n      log.push('m1')\n      if (!assertEq(() => typeof ctxMethod.addInitializer, 'function')) return\n      ctxMethod.addInitializer(() => log.push('m3'))\n      ctxMethod.addInitializer(() => log.push('m4'))\n    }\n    const staticMethodDec1 = (fn: (this: Object) => void, ctxStaticMethod: ClassMethodDecoratorContext) => {\n      log.push('M2')\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, 'function')) return\n      ctxStaticMethod.addInitializer(() => log.push('M5'))\n      ctxStaticMethod.addInitializer(() => log.push('M6'))\n    }\n    const staticMethodDec2 = (fn: (this: Object) => void, ctxStaticMethod: ClassMethodDecoratorContext) => {\n      log.push('M1')\n      if (!assertEq(() => typeof ctxStaticMethod.addInitializer, 'function')) return\n      ctxStaticMethod.addInitializer(() => log.push('M3'))\n      ctxStaticMethod.addInitializer(() => log.push('M4'))\n    }\n\n    // Field decorators\n    const fieldDec1 = (\n      value: undefined,\n      ctxField: ClassFieldDecoratorContext,\n    ): ((this: Object, value: undefined) => undefined) | undefined => {\n      log.push('f2')\n      if (!assertEq(() => typeof ctxField.addInitializer, 'function')) return\n      ctxField.addInitializer(() => log.push('f5'))\n      ctxField.addInitializer(() => log.push('f6'))\n      return () => { log.push('f7') }\n    }\n    const fieldDec2 = (\n      value: undefined,\n      ctxField: ClassFieldDecoratorContext,\n    ): ((this: Object, value: undefined) => undefined) | undefined => {\n      log.push('f1')\n      if (!assertEq(() => typeof ctxField.addInitializer, 'function')) return\n      ctxField.addInitializer(() => log.push('f3'))\n      ctxField.addInitializer(() => log.push('f4'))\n      return () => { log.push('f8') }\n    }\n    const staticFieldDec1 = (\n      value: undefined,\n      ctxStaticField: ClassFieldDecoratorContext,\n    ): ((this: Object, value: undefined) => undefined) | undefined => {\n      log.push('F2')\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, 'function')) return\n      ctxStaticField.addInitializer(() => log.push('F5'))\n      ctxStaticField.addInitializer(() => log.push('F6'))\n      return () => { log.push('F7') }\n    }\n    const staticFieldDec2 = (\n      value: undefined,\n      ctxStaticField: ClassFieldDecoratorContext,\n    ): ((this: Object, value: undefined) => undefined) | undefined => {\n      log.push('F1')\n      if (!assertEq(() => typeof ctxStaticField.addInitializer, 'function')) return\n      ctxStaticField.addInitializer(() => log.push('F3'))\n      ctxStaticField.addInitializer(() => log.push('F4'))\n      return () => { log.push('F8') }\n    }\n\n    // Getter decorators\n    const getterDec1 = (fn: (this: Object) => undefined, ctxGetter: ClassGetterDecoratorContext) => {\n      log.push('g2')\n      if (!assertEq(() => typeof ctxGetter.addInitializer, 'function')) return\n      ctxGetter.addInitializer(() => log.push('g5'))\n      ctxGetter.addInitializer(() => log.push('g6'))\n    }\n    const getterDec2 = (fn: (this: Object) => undefined, ctxGetter: ClassGetterDecoratorContext) => {\n      log.push('g1')\n      if (!assertEq(() => typeof ctxGetter.addInitializer, 'function')) return\n      ctxGetter.addInitializer(() => log.push('g3'))\n      ctxGetter.addInitializer(() => log.push('g4'))\n    }\n    const staticGetterDec1 = (fn: (this: Object) => undefined, ctxStaticGetter: ClassGetterDecoratorContext) => {\n      log.push('G2')\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, 'function')) return\n      ctxStaticGetter.addInitializer(() => log.push('G5'))\n      ctxStaticGetter.addInitializer(() => log.push('G6'))\n    }\n    const staticGetterDec2 = (fn: (this: Object) => undefined, ctxStaticGetter: ClassGetterDecoratorContext) => {\n      log.push('G1')\n      if (!assertEq(() => typeof ctxStaticGetter.addInitializer, 'function')) return\n      ctxStaticGetter.addInitializer(() => log.push('G3'))\n      ctxStaticGetter.addInitializer(() => log.push('G4'))\n    }\n\n    // Setter decorators\n    const setterDec1 = (fn: (this: Object, x: undefined) => void, ctxSetter: ClassSetterDecoratorContext) => {\n      log.push('s2')\n      if (!assertEq(() => typeof ctxSetter.addInitializer, 'function')) return\n      ctxSetter.addInitializer(() => log.push('s5'))\n      ctxSetter.addInitializer(() => log.push('s6'))\n    }\n    const setterDec2 = (fn: (this: Object, x: undefined) => void, ctxSetter: ClassSetterDecoratorContext) => {\n      log.push('s1')\n      if (!assertEq(() => typeof ctxSetter.addInitializer, 'function')) return\n      ctxSetter.addInitializer(() => log.push('s3'))\n      ctxSetter.addInitializer(() => log.push('s4'))\n    }\n    const staticSetterDec1 = (fn: (this: Object, x: undefined) => void, ctxStaticSetter: ClassSetterDecoratorContext) => {\n      log.push('S2')\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, 'function')) return\n      ctxStaticSetter.addInitializer(() => log.push('S5'))\n      ctxStaticSetter.addInitializer(() => log.push('S6'))\n    }\n    const staticSetterDec2 = (fn: (this: Object, x: undefined) => void, ctxStaticSetter: ClassSetterDecoratorContext) => {\n      log.push('S1')\n      if (!assertEq(() => typeof ctxStaticSetter.addInitializer, 'function')) return\n      ctxStaticSetter.addInitializer(() => log.push('S3'))\n      ctxStaticSetter.addInitializer(() => log.push('S4'))\n    }\n\n    // Auto-accessor decorators\n    const accessorDec1 = (\n      target: ClassAccessorDecoratorTarget<Object, undefined>,\n      ctxAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<Object, undefined> | undefined => {\n      log.push('a2')\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, 'function')) return\n      ctxAccessor.addInitializer(() => log.push('a5'))\n      ctxAccessor.addInitializer(() => log.push('a6'))\n      return { init() { log.push('a7') } }\n    }\n    const accessorDec2 = (\n      target: ClassAccessorDecoratorTarget<Object, undefined>,\n      ctxAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<Object, undefined> | undefined => {\n      log.push('a1')\n      if (!assertEq(() => typeof ctxAccessor.addInitializer, 'function')) return\n      ctxAccessor.addInitializer(() => log.push('a3'))\n      ctxAccessor.addInitializer(() => log.push('a4'))\n      return { init() { log.push('a8') } }\n    }\n    const staticAccessorDec1 = (\n      target: ClassAccessorDecoratorTarget<Object, undefined>,\n      ctxStaticAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<Object, undefined> | undefined => {\n      log.push('A2')\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, 'function')) return\n      ctxStaticAccessor.addInitializer(() => log.push('A5'))\n      ctxStaticAccessor.addInitializer(() => log.push('A6'))\n      return { init() { log.push('A7') } }\n    }\n    const staticAccessorDec2 = (\n      target: ClassAccessorDecoratorTarget<Object, undefined>,\n      ctxStaticAccessor: ClassAccessorDecoratorContext,\n    ): ClassAccessorDecoratorResult<Object, undefined> | undefined => {\n      log.push('A1')\n      if (!assertEq(() => typeof ctxStaticAccessor.addInitializer, 'function')) return\n      ctxStaticAccessor.addInitializer(() => log.push('A3'))\n      ctxStaticAccessor.addInitializer(() => log.push('A4'))\n      return { init() { log.push('A8') } }\n    }\n\n    log.push('start')\n    const Foo = @classDec1 @classDec2 class extends (log.push('extends'), Object) {\n      static { log.push('static:start') }\n\n      constructor() {\n        log.push('ctor:start')\n        super()\n        log.push('ctor:end')\n      }\n\n      @methodDec1 @methodDec2 #method() { }\n      @staticMethodDec1 @staticMethodDec2 static #staticMethod() { }\n\n      @fieldDec1 @fieldDec2 #field: undefined\n      @staticFieldDec1 @staticFieldDec2 static #staticField: undefined\n\n      @getterDec1 @getterDec2 get #getter(): undefined { return }\n      @staticGetterDec1 @staticGetterDec2 static get #staticGetter(): undefined { return }\n\n      @setterDec1 @setterDec2 set #setter(x: undefined) { }\n      @staticSetterDec1 @staticSetterDec2 static set #staticSetter(x: undefined) { }\n\n      @accessorDec1 @accessorDec2 accessor #accessor: undefined\n      @staticAccessorDec1 @staticAccessorDec2 static accessor #staticAccessor: undefined\n\n      static { log.push('static:end') }\n    }\n    log.push('after')\n    new Foo\n    log.push('end')\n    assertEq(() => log + '', 'start,extends,' +\n      'M1,M2,G1,G2,S1,S2,A1,A2,' + // For each element e of staticElements if e.[[Kind]] is not field\n      'm1,m2,g1,g2,s1,s2,a1,a2,' + // For each element e of instanceElements if e.[[Kind]] is not field\n      'F1,F2,' + // For each element e of staticElements if e.[[Kind]] is field\n      'f1,f2,' + // For each element e of instanceElements if e.[[Kind]] is field\n      'c1,c2,' + // ApplyDecoratorsToClassDefinition\n      'M3,M4,M5,M6,G3,G4,G5,G6,S3,S4,S5,S6,' + // For each element initializer of staticMethodExtraInitializers\n      'static:start,' + // For each element elementRecord of staticElements\n      'F7,F8,F3,F4,F5,F6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'A7,A8,A3,A4,A5,A6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'static:end,' + // For each element elementRecord of staticElements\n      'c3,c4,c5,c6,' + // For each element initializer of classExtraInitializers\n      'after,' +\n      'ctor:start,' +\n      'm3,m4,m5,m6,g3,g4,g5,g6,s3,s4,s5,s6,' + // For each element initializer of constructor.[[Initializers]] (a.k.a. instanceMethodExtraInitializers)\n      'f7,f8,f3,f4,f5,f6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'a7,a8,a3,a4,a5,a6,' + // InitializeFieldOrAccessor + For each element initializer of elementRecord.[[ExtraInitializers]]\n      'ctor:end,' +\n      'end')\n  },\n}\n\nfunction prettyPrint(x: any): any {\n  if (x && x.prototype && x.prototype.constructor === x) return 'class'\n  if (typeof x === 'string') return JSON.stringify(x)\n  try {\n    return x + ''\n  } catch {\n    return 'typeof ' + typeof x // Handle values that don't implement \"toString\"\n  }\n}\n\nfunction assertEq<T>(callback: () => T, expected: T): boolean {\n  let details: string\n  try {\n    let x: any = callback()\n    if (x === expected) return true\n    details = `  Expected: ${prettyPrint(expected)}\\n  Observed: ${prettyPrint(x)}`\n  } catch (error) {\n    details = `  Throws: ${error}`\n  }\n\n  const code = callback.toString().replace(/^\\(\\) => /, '').replace(/\\s+/g, ' ')\n  console.log(`❌ ${testName}\\n  Code: ${code}\\n${details}\\n`)\n  failures++\n  return false\n}\n\nfunction assertThrows<T extends Function>(callback: () => void, expected: T): boolean {\n  let details: string\n  try {\n    let x: any = callback()\n    details = `  Expected: throws instanceof ${expected.name}\\n  Observed: returns ${prettyPrint(x)}`\n  } catch (error) {\n    if (error instanceof expected) return true\n    details = `  Expected: throws instanceof ${expected.name}\\n  Observed: throws ${error}`\n  }\n\n  const code = callback.toString().replace(/^\\(\\) => /, '').replace(/\\s+/g, ' ')\n  console.log(`❌ ${testName}\\n  Code: ${code}\\n${details}\\n`)\n  failures++\n  return false\n}\n\nlet testName: string\nlet failures = 0\n\nasync function run() {\n  for (const [name, test] of Object.entries(tests)) {\n    testName = name\n    try {\n      await test()\n    } catch (err) {\n      console.log(`❌ ${name}\\n  Throws: ${err}\\n`)\n      failures++\n    }\n  }\n\n  if (failures > 0) {\n    console.log(`❌ ${failures} checks failed`)\n  } else {\n    console.log(`✅ All checks passed`)\n  }\n}\n\nconst promise = run()\n"
  },
  {
    "path": "scripts/deno-tests.js",
    "content": "// To run this, you must first build the Deno package with \"make platform-deno\"\nimport * as esbuildNative from '../deno/mod.js'\nimport * as esbuildWASM from '../deno/wasm.js'\nimport * as path from 'https://deno.land/std@0.95.0/path/mod.ts'\nimport * as asserts from 'https://deno.land/std@0.95.0/testing/asserts.ts'\n\nconst __dirname = path.dirname(path.fromFileUrl(import.meta.url))\nconst rootTestDir = path.join(__dirname, '.deno-tests')\nconst wasmModule = await WebAssembly.compile(await Deno.readFile(path.join(__dirname, '..', 'deno', 'esbuild.wasm')))\n\ntry {\n  Deno.removeSync(rootTestDir, { recursive: true })\n} catch {\n}\nDeno.mkdirSync(rootTestDir, { recursive: true })\n\nfunction test(name, backends, fn) {\n  // Note: Do not try to add a timeout for the tests below. It turns out that\n  // calling \"setTimeout\" from within \"Deno.test\" changes how Deno waits for\n  // promises in a way that masks problems that would otherwise occur. We want\n  // test coverage for the way that people will likely be using these API calls.\n  //\n  // Specifically tests that Deno would otherwise have failed with \"error:\n  // Promise resolution is still pending but the event loop has already\n  // resolved\" were being allowed to pass instead. See this issue for more\n  // information: https://github.com/evanw/esbuild/issues/3682\n\n  for (const backend of backends) {\n    switch (backend) {\n      case 'native':\n        Deno.test(name + '-native', async () => {\n          let testDir = path.join(rootTestDir, name + '-native')\n          await Deno.mkdir(testDir, { recursive: true })\n          try {\n            await fn({ esbuild: esbuildNative, testDir })\n            await Deno.remove(testDir, { recursive: true }).catch(() => null)\n          } finally {\n            await esbuildNative.stop()\n          }\n        })\n        break\n\n      case 'wasm-main':\n        Deno.test(name + '-wasm-main', async () => {\n          let testDir = path.join(rootTestDir, name + '-wasm-main')\n          await esbuildWASM.initialize({ wasmModule, worker: false })\n          await Deno.mkdir(testDir, { recursive: true })\n          try {\n            await fn({ esbuild: esbuildWASM, testDir })\n            await Deno.remove(testDir, { recursive: true }).catch(() => null)\n          } finally {\n            await esbuildWASM.stop()\n          }\n        })\n        break\n\n      case 'wasm-worker':\n        Deno.test(name + '-wasm-worker', async () => {\n          let testDir = path.join(rootTestDir, name + '-wasm-worker')\n          await esbuildWASM.initialize({ wasmModule, worker: true })\n          await Deno.mkdir(testDir, { recursive: true })\n          try {\n            await fn({ esbuild: esbuildWASM, testDir })\n            await Deno.remove(testDir, { recursive: true }).catch(() => null)\n          } finally {\n            await esbuildWASM.stop()\n          }\n        })\n        break\n    }\n  }\n}\n\naddEventListener(\"unload\", (e) => {\n  try {\n    Deno.removeSync(rootTestDir, { recursive: true })\n  } catch {\n    // root test dir possibly already removed, so ignore\n  }\n})\n\n// This test doesn't run in WebAssembly because it requires file system access\ntest(\"basicBuild\", ['native'], async ({ esbuild, testDir }) => {\n  const input = path.join(testDir, 'in.ts')\n  const dep = path.join(testDir, 'dep.ts')\n  const output = path.join(testDir, 'out.ts')\n  await Deno.writeTextFile(input, 'import dep from \"./dep.ts\"; export default dep === 123')\n  await Deno.writeTextFile(dep, 'export default 123')\n  await esbuild.build({\n    entryPoints: [input],\n    bundle: true,\n    outfile: output,\n    format: 'esm',\n  })\n  const result = await import(path.toFileUrl(output))\n  asserts.assertStrictEquals(result.default, true)\n})\n\ntest(\"basicContext\", ['native'], async ({ esbuild, testDir }) => {\n  const input = path.join(testDir, 'in.ts')\n  const dep = path.join(testDir, 'dep.ts')\n  const output = path.join(testDir, 'out.ts')\n  await Deno.writeTextFile(input, 'import dep from \"./dep.ts\"; export default dep === 123')\n  await Deno.writeTextFile(dep, 'export default 123')\n  const ctx = await esbuild.context({\n    entryPoints: ['in.ts'],\n    bundle: true,\n    outfile: output,\n    format: 'esm',\n    absWorkingDir: testDir,\n  })\n  const { errors, warnings } = await ctx.rebuild()\n  asserts.assertStrictEquals(errors.length, 0)\n  asserts.assertStrictEquals(warnings.length, 0)\n  await ctx.dispose()\n  const result = await import(path.toFileUrl(output))\n  asserts.assertStrictEquals(result.default, true)\n})\n\ntest(\"basicPlugin\", ['native', 'wasm-main', 'wasm-worker'], async ({ esbuild }) => {\n  const build = await esbuild.build({\n    entryPoints: ['<entry>'],\n    bundle: true,\n    format: 'esm',\n    write: false,\n    plugins: [{\n      name: 'plug',\n      setup(build) {\n        build.onResolve({ filter: /^<.*>$/ }, args => ({ path: args.path, namespace: '<>' }))\n        build.onLoad({ filter: /^<entry>$/ }, () => ({ contents: `import dep from \"<dep>\"; export default dep === 123` }))\n        build.onLoad({ filter: /^<dep>$/ }, () => ({ contents: `export default 123` }))\n      },\n    }],\n  })\n  const result = await import('data:application/javascript;base64,' + btoa(build.outputFiles[0].text))\n  asserts.assertStrictEquals(result.default, true)\n})\n\ntest(\"basicTransform\", ['native', 'wasm-main', 'wasm-worker'], async ({ esbuild }) => {\n  const ts = 'let x: number = 1+2'\n  const result = await esbuild.transform(ts, { loader: 'ts' })\n  asserts.assertStrictEquals(result.code, 'let x = 1 + 2;\\n')\n})\n\n// This test doesn't run in WebAssembly because of a stack overflow\ntest(\"largeTransform\", ['native'], async ({ esbuild }) => {\n  // This should be large enough to be bigger than Deno's write buffer\n  let x = '0'\n  for (let i = 0; i < 1000; i++) x += '+' + i\n  x += ','\n  let y = 'return['\n  for (let i = 0; i < 1000; i++) y += x\n  y += ']'\n  const result = await esbuild.build({\n    stdin: {\n      contents: y,\n    },\n    write: false,\n    minifyWhitespace: true,\n  })\n  asserts.assertStrictEquals(result.outputFiles[0].text, y.slice(0, -2) + '];\\n')\n})\n\ntest(\"analyzeMetafile\", ['native', 'wasm-main', 'wasm-worker'], async ({ esbuild }) => {\n  const result = await esbuild.analyzeMetafile({\n    outputs: {\n      'out.js': {\n        bytes: 4096,\n        inputs: {\n          'in.js': {\n            bytesInOutput: 1024,\n          },\n        },\n      },\n    },\n  })\n  asserts.assertStrictEquals(result, `\n  out.js    4.0kb  100.0%\n   └ in.js  1.0kb   25.0%\n`)\n})\n"
  },
  {
    "path": "scripts/destructuring-fuzzer.js",
    "content": "function generateTestCase(assign) {\n  let sideEffectCount = 0\n  let patternCount = 0\n  let limit = 10\n  let depth = 0\n\n  function choice(n) {\n    return Math.random() * n | 0\n  }\n\n  function patternAndValue() {\n    patternCount++\n    switch (choice(3)) {\n      case 0: return array()\n      case 1: return object()\n      case 2: return [assign(), choice(10), choice(10)]\n    }\n  }\n\n  function sideEffect(result) {\n    return `s(${sideEffectCount++}${result ? `, ${result}` : ''})`\n  }\n\n  function indent(open, items, close) {\n    let tab = '  '\n    items = items.map(i => `\\n${tab.repeat(depth + 1)}${i}`).join(',')\n    return `${open}${items}\\n${tab.repeat(depth)}${close}`\n  }\n\n  function id() {\n    return String.fromCharCode('a'.charCodeAt(0) + choice(3))\n  }\n\n  function array() {\n    let count = 1 + choice(2)\n    let pattern = []\n    let value = []\n\n    depth++\n    for (let i = 0; i < count; i++) {\n      if (patternCount > limit) break\n      let [pat, val, defVal] = patternAndValue()\n      switch (choice(3)) {\n        case 0:\n          pattern.push(pat)\n          value.push(val)\n          break\n        case 1:\n          pattern.push(`${pat} = ${sideEffect(defVal)}`)\n          value.push(val)\n          break\n        case 2:\n          pattern.push(`${pat} = ${sideEffect(defVal)}`)\n          value.push(defVal)\n          break\n      }\n      if (choice(10) < 8) value.push(val)\n    }\n    if (choice(2)) {\n      pattern.push(`...${assign()}`)\n      if (choice(10) < 8) value.push(choice(10))\n    }\n    depth--\n\n    return [\n      indent('[', pattern, ']'),\n      indent('[', value, ']'),\n      '[]',\n    ]\n  }\n\n  function object() {\n    let count = 1 + choice(2)\n    let pattern = []\n    let value = []\n    let valKeys = new Set()\n\n    depth++\n    for (let i = 0; i < count; i++) {\n      if (patternCount > limit) break\n      let valKey = id()\n      if (valKeys.has(valKey)) continue\n      valKeys.add(valKey)\n      let patKey = choice() ? valKey : `[${sideEffect(`'${valKey}'`)}]`\n      let [pat, val, defVal] = patternAndValue()\n      switch (choice(3)) {\n        case 0:\n          pattern.push(`${patKey}: ${pat}`)\n          value.push(`${valKey}: ${val}`)\n          break\n        case 1:\n          pattern.push(`${patKey}: ${pat} = ${sideEffect(defVal)}`)\n          value.push(`${valKey}: ${val}`)\n          break\n        case 2:\n          pattern.push(`${patKey}: ${pat} = ${sideEffect(defVal)}`)\n          value.push(`${valKey}: ${defVal}`)\n          break\n      }\n    }\n    if (choice(2)) {\n      pattern.push(`...${assign()}`)\n      if (choice(10) < 8) value.push(`${id()}: ${choice(10)}`)\n    }\n    depth--\n\n    return [\n      indent('{', pattern, '}'),\n      indent('{', value, '}'),\n      '{}',\n    ]\n  }\n\n  return choice(2) ? array() : object()\n}\n\nfunction evaluate(code) {\n  let effectTrace = []\n  let assignTarget = {}\n  let sideEffect = (id, value) => (effectTrace.push(id), value)\n  new Function('a', 's', code)(assignTarget, sideEffect)\n  return JSON.stringify({ assignTarget, effectTrace })\n}\n\nfunction generateTestCases(trials) {\n  let testCases = []\n\n  while (testCases.length < trials) {\n    let ids = []\n    let assignCount = 0\n    let [pattern, value] = generateTestCase(() => {\n      let id = `_${assignCount++}`\n      ids.push(id)\n      return id\n    })\n    try {\n      evaluate(`(${pattern.replace(/_/g, 'a._')} = ${value});`)\n      testCases.push([pattern, value, ids])\n    } catch (e) {\n    }\n  }\n\n  return testCases\n}\n\nfunction AssignmentOperator([pattern, value]) {\n  let ts = `(${pattern.replace(/_/g, 'a._')} = ${value});`\n  let js = ts\n  return { js, ts }\n}\n\nfunction NamespaceExport([pattern, value]) {\n  let ts = `namespace a { export const ${`${pattern} = ${value}`} }`\n  let js = `(${pattern.replace(/_/g, 'a._')} = ${value});`\n  return { js, ts }\n}\n\nfunction ConstDeclaration([pattern, value, ids]) {\n  let ts = `const ${pattern} = ${value};${ids.map(id => `\\na.${id} = ${id};`).join('')}`\n  let js = ts\n  return { js, ts }\n}\n\nfunction LetDeclaration([pattern, value, ids]) {\n  let ts = `let ${pattern} = ${value};${ids.map(id => `\\na.${id} = ${id};`).join('')}`\n  let js = ts\n  return { js, ts }\n}\n\nfunction VarDeclaration([pattern, value, ids]) {\n  let ts = `var ${pattern} = ${value};${ids.map(id => `\\na.${id} = ${id};`).join('')}`\n  let js = ts\n  return { js, ts }\n}\n\nfunction TryCatchBinding([pattern, value, ids]) {\n  let ts = `try { throw ${value} } catch (${pattern}) { ${ids.map(id => `a.${id} = ${id};`).join('\\n')} }`\n  let js = ts\n  return { js, ts }\n}\n\nfunction FunctionStatementArguments([pattern, value, ids]) {\n  let ts = `function foo(${pattern}) { ${ids.map(id => `a.${id} = ${id};`).join('\\n')} }\\nfoo(${value});`\n  let js = ts\n  return { js, ts }\n}\n\nfunction FunctionExpressionArguments([pattern, value, ids]) {\n  let ts = `(function(${pattern}) { ${ids.map(id => `a.${id} = ${id};`).join('\\n')} })(${value});`\n  let js = ts\n  return { js, ts }\n}\n\nfunction ArrowFunctionArguments([pattern, value, ids]) {\n  let ts = `((${pattern}) => { ${ids.map(id => `a.${id} = ${id};`).join('\\n')} })(${value});`\n  let js = ts\n  return { js, ts }\n}\n\nfunction ObjectMethodArguments([pattern, value, ids]) {\n  let ts = `({ foo(${pattern}) { ${ids.map(id => `a.${id} = ${id};`).join('\\n')} } }).foo(${value});`\n  let js = ts\n  return { js, ts }\n}\n\nfunction ClassStatementMethodArguments([pattern, value, ids]) {\n  let ts = `class Foo { foo(${pattern}) { ${ids.map(id => `a.${id} = ${id};`).join('\\n')} } }\\nnew Foo().foo(${value});`\n  let js = ts\n  return { js, ts }\n}\n\nfunction ClassExpressionMethodArguments([pattern, value, ids]) {\n  let ts = `(new (class { foo(${pattern}) { ${ids.map(id => `a.${id} = ${id};`).join('\\n')} } })).foo(${value});`\n  let js = ts\n  return { js, ts }\n}\n\nfunction ForLoopConst([pattern, value, ids]) {\n  let ts = `var i; for (const ${pattern} = ${value}; i < 1; i++) { ${ids.map(id => `a.${id} = ${id};`).join('\\n')} }`\n  let js = ts\n  return { js, ts }\n}\n\nfunction ForLoopLet([pattern, value, ids]) {\n  let ts = `for (let ${pattern} = ${value}, i = 0; i < 1; i++) { ${ids.map(id => `a.${id} = ${id};`).join('\\n')} }`\n  let js = ts\n  return { js, ts }\n}\n\nfunction ForLoopVar([pattern, value, ids]) {\n  let ts = `for (var ${pattern} = ${value}, i = 0; i < 1; i++) { ${ids.map(id => `a.${id} = ${id};`).join('\\n')} }`\n  let js = ts\n  return { js, ts }\n}\n\nfunction ForLoop([pattern, value]) {\n  let ts = `for (${pattern.replace(/_/g, 'a._')} = ${value}; 0; ) ;`\n  let js = ts\n  return { js, ts }\n}\n\nfunction ForOfLoopConst([pattern, value, ids]) {\n  let ts = `for (const ${pattern} of [${value}]) { ${ids.map(id => `a.${id} = ${id};`).join('\\n')} }`\n  let js = ts\n  return { js, ts }\n}\n\nfunction ForOfLoopLet([pattern, value, ids]) {\n  let ts = `for (let ${pattern} of [${value}]) { ${ids.map(id => `a.${id} = ${id};`).join('\\n')} }`\n  let js = ts\n  return { js, ts }\n}\n\nfunction ForOfLoopVar([pattern, value, ids]) {\n  let ts = `for (var ${pattern} of [${value}]) { ${ids.map(id => `a.${id} = ${id};`).join('\\n')} }`\n  let js = ts\n  return { js, ts }\n}\n\nfunction ForOfLoop([pattern, value]) {\n  let ts = `for (${pattern.replace(/_/g, 'a._')} of [${value}]) ;`\n  let js = ts\n  return { js, ts }\n}\n\nasync function verify(test, transform, testCases) {\n  let verbose = process.argv.indexOf('--verbose') >= 0\n  let indent = t => t.replace(/\\n/g, '\\n  ')\n  let newline = false\n  console.log(`${test.name} (${transform.name}):`)\n\n  await concurrentMap(testCases, 20, async (testCase) => {\n    let { js, ts } = test(testCase)\n    let expected\n    try {\n      expected = evaluate(js)\n    } catch (e) {\n      return\n    }\n\n    let transformed\n    try {\n      transformed = await transform(ts)\n    } catch (e) {\n      process.stdout.write('T')\n      newline = true\n\n      if (verbose) {\n        console.log('\\n' + '='.repeat(80))\n        console.log(indent(`Original code:\\n${ts}`))\n        console.log(indent(`Transform error:\\n${e}`))\n        newline = false\n      }\n      return\n    }\n\n    let actual\n    try {\n      actual = evaluate(transformed)\n    } catch (e) {\n      actual = e + ''\n    }\n\n    if (actual !== expected) {\n      process.stdout.write(actual.indexOf('SyntaxError') >= 0 ? 'S' : 'X')\n      newline = true\n\n      if (verbose) {\n        console.log('\\n' + '='.repeat(80))\n        console.log(indent(`Original code:\\n${ts}`))\n        console.log(indent(`Transformed code:\\n${transformed}`))\n        console.log(indent(`Expected output:\\n${expected}`))\n        console.log(indent(`Actual output:\\n${actual}`))\n        newline = false\n      }\n    } else {\n      process.stdout.write('-')\n      newline = true\n    }\n  })\n\n  if (newline) process.stdout.write('\\n')\n}\n\nfunction concurrentMap(items, batch, callback) {\n  return new Promise((resolve, reject) => {\n    let index = 0\n    let pending = 0\n    let next = () => {\n      if (index === items.length && pending === 0) {\n        resolve()\n      } else if (index < items.length) {\n        let item = items[index++]\n        pending++\n        callback(item).then(() => {\n          pending--\n          next()\n        }, e => {\n          items.length = 0\n          reject(e)\n        })\n      }\n    }\n    for (let i = 0; i < batch; i++)next()\n  })\n}\n\nasync function main() {\n  let es = require('./esbuild').installForTests()\n  let esbuild = async (x) => (await es.transform(x, { target: 'es6', loader: 'ts' })).code.trim()\n\n  console.log(`\nOptions:\n  --verbose = Print details for failures\n\nLegend:\n  - = The test passed\n  X = The test failed\n  T = The transform function itself failed\n  S = The generated code has a syntax error`)\n\n  let tests = [\n    // Bindings\n    ConstDeclaration,\n    LetDeclaration,\n    VarDeclaration,\n    TryCatchBinding,\n    FunctionStatementArguments,\n    FunctionExpressionArguments,\n    ArrowFunctionArguments,\n    ObjectMethodArguments,\n    ClassStatementMethodArguments,\n    ClassExpressionMethodArguments,\n    ForLoopConst,\n    ForLoopLet,\n    ForLoopVar,\n    ForOfLoopConst,\n    ForOfLoopLet,\n    ForOfLoopVar,\n\n    // Destructuring\n    AssignmentOperator,\n    ForLoop,\n    ForOfLoop,\n\n    // TypeScript-specific\n    NamespaceExport,\n  ]\n  let transforms = [\n    esbuild,\n  ]\n  let testCases = generateTestCases(100)\n\n  for (let transform of transforms) {\n    console.log()\n    for (let test of tests) {\n      await verify(test, transform, testCases)\n    }\n  }\n}\n\nmain().catch(e => setTimeout(() => { throw e }))\n"
  },
  {
    "path": "scripts/end-to-end-tests.js",
    "content": "const childProcess = require('child_process')\nconst { buildBinary, dirname, removeRecursiveSync, writeFileAtomic } = require('./esbuild.js')\nconst assert = require('assert')\nconst path = require('path')\nconst util = require('util')\nconst url = require('url')\nconst fs = require('fs').promises\n\nconst execFileAsync = util.promisify(childProcess.execFile)\nconst execAsync = util.promisify(childProcess.exec)\n\nconst nodeMajorVersion = +process.versions.node.split('.')[0]\nconst testDir = path.join(dirname, '.end-to-end-tests')\nconst errorIcon = process.platform !== 'win32' ? '✘' : 'X'\nconst esbuildPath = buildBinary()\nconst tests = []\nlet testCount = 0\n\n// Tests for \"--define\"\ntests.push(\n  test(['--define:foo=null', 'in.js', '--outfile=node.js'], { 'in.js': `if (foo !== null) throw 'fail'` }),\n  test(['--define:foo=true', 'in.js', '--outfile=node.js'], { 'in.js': `if (foo !== true) throw 'fail'` }),\n  test(['--define:foo=false', 'in.js', '--outfile=node.js'], { 'in.js': `if (foo !== false) throw 'fail'` }),\n  test(['--define:foo=\"abc\"', 'in.js', '--outfile=node.js'], { 'in.js': `if (foo !== \"abc\") throw 'fail'` }),\n  test(['--define:foo=123.456', 'in.js', '--outfile=node.js'], { 'in.js': `if (foo !== 123.456) throw 'fail'` }),\n  test(['--define:foo=-123.456', 'in.js', '--outfile=node.js'], { 'in.js': `if (foo !== -123.456) throw 'fail'` }),\n  test(['--define:foo=global', 'in.js', '--outfile=node.js'], { 'in.js': `foo.bar = 123; if (bar !== 123) throw 'fail'` }),\n  test(['--define:foo=bar', 'in.js', '--outfile=node.js'], { 'in.js': `let bar = {x: 123}; if (foo.x !== 123) throw 'fail'` }),\n  test(['--define:a.x=1', 'in.js', '--outfile=node.js'], { 'in.js': `if (a.x !== 1) throw 'fail'` }),\n  test(['--define:a.x=1', '--define:a.y=2', 'in.js', '--outfile=node.js'], { 'in.js': `if (a.x + a.y !== 3) throw 'fail'` }),\n  test(['--define:a.x=1', '--define:b.y=2', 'in.js', '--outfile=node.js'], { 'in.js': `if (a.x + b.y !== 3) throw 'fail'` }),\n  test(['--define:a.x=1', '--define:b.x=2', 'in.js', '--outfile=node.js'], { 'in.js': `if (a.x + b.x !== 3) throw 'fail'` }),\n  test(['--define:x=y', '--define:y=x', 'in.js', '--outfile=node.js'], {\n    'in.js': `eval('var x=\"x\",y=\"y\"'); if (x + y !== 'yx') throw 'fail'`,\n  }),\n)\n\n// Test recursive directory creation\ntests.push(\n  test(['entry.js', '--outfile=a/b/c/d/index.js'], {\n    'entry.js': `exports.foo = 123`,\n    'node.js': `const ns = require('./a/b/c/d'); if (ns.foo !== 123) throw 'fail'`,\n  }),\n)\n\n// Test bogus paths with a file as a parent directory (this happens when you use \"pnpx esbuild\")\ntests.push(\n  test(['entry.js', '--bundle'], {\n    'entry.js': `import \"./file.js/what/is/this\"`,\n    'file.js': `some file`,\n  }, {\n    expectedStderr: `${errorIcon} [ERROR] Could not resolve \"./file.js/what/is/this\"\n\n    entry.js:1:7:\n      1 │ import \"./file.js/what/is/this\"\n        ╵        ~~~~~~~~~~~~~~~~~~~~~~~~\n\n`,\n  }),\n)\n\n// Test absolute paths in log messages\ntests.push(\n  test(['entry.js', '--bundle', '--abs-paths=log'], {\n    'entry.js': `import \"./foo\"`,\n  }, {\n    expectedStderr: `${errorIcon} [ERROR] Could not resolve \"./foo\"\n\n    $ABS_PATH_PREFIX$entry.js:1:7:\n      1 │ import \"./foo\"\n        ╵        ~~~~~~~\n\n`,\n  }),\n)\n\n// Test resolving paths with a question mark (an invalid path on Windows)\ntests.push(\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `\n      import x from \"./file.js?ignore-me\"\n      if (x !== 123) throw 'fail'\n    `,\n    'file.js': `export default 123`,\n  }),\n)\n\n// Test TypeScript enum stuff\ntests.push(\n  // Scope merging\n  test(['entry.ts', '--bundle', '--minify', '--outfile=node.js'], {\n    'entry.ts': `\n      const id = x => x\n      enum a { b = 1 }\n      enum a { c = 2 }\n      if (id(a).c !== 2 || id(a)[2] !== 'c' || id(a).b !== 1 || id(a)[1] !== 'b') throw 'fail'\n    `,\n  }),\n  test(['entry.ts', '--bundle', '--minify', '--outfile=node.js'], {\n    'entry.ts': `\n      const id = x => x\n      {\n        enum a { b = 1 }\n      }\n      {\n        enum a { c = 2 }\n        if (id(a).c !== 2 || id(a)[2] !== 'c' || id(a).b !== void 0 || id(a)[1] !== void 0) throw 'fail'\n      }\n    `,\n  }),\n  test(['entry.ts', '--bundle', '--minify', '--outfile=node.js'], {\n    'entry.ts': `\n      const id = x => x\n      enum a { b = 1 }\n      namespace a {\n        if (id(a).b !== 1 || id(a)[1] !== 'b') throw 'fail'\n      }\n    `,\n  }),\n  test(['entry.ts', '--bundle', '--minify', '--outfile=node.js'], {\n    'entry.ts': `\n      const id = x => x\n      namespace a {\n        export function foo() {\n          if (id(a).b !== 1 || id(a)[1] !== 'b') throw 'fail'\n        }\n      }\n      enum a { b = 1 }\n      a.foo()\n    `,\n  }),\n  test(['entry.ts', '--bundle', '--minify', '--outfile=node.js'], {\n    'entry.ts': `\n      import './enum-to-namespace'\n      import './namespace-to-enum'\n      import './namespace-to-namespace'\n    `,\n    'enum-to-namespace.ts': `\n      let foo, bar, y = 2, z = 4\n      enum x { y = 1 }\n      namespace x { foo = y }\n      enum x { z = y * 3 }\n      namespace x { bar = z }\n      if (foo !== 2 || bar !== 4) throw 'fail'\n    `,\n    'namespace-to-enum.ts': `\n      let y = 2, z = 4\n      namespace x { export let y = 1 }\n      enum x { foo = y }\n      namespace x { export let z = y * 3 }\n      enum x { bar = z }\n      if (x.foo !== 2 || x.bar !== 4) throw 'fail'\n    `,\n    'namespace-to-namespace.ts': `\n      let foo, bar, y = 2, z = 4\n      namespace x { export const y = 1 }\n      namespace x { foo = y }\n      namespace x { export const z = y * 3 }\n      namespace x { bar = z }\n      if (foo !== 1 || bar !== 3) throw 'fail'\n    `,\n  }),\n\n  // https://github.com/evanw/esbuild/issues/3205\n  test(['entry.ts', '--outfile=node.js'], {\n    'entry.ts': `\n      // Note: The parentheses are important here\n      let x = (() => {\n        const enum E { a = 123 }\n        return () => E.a\n      })\n      if (x()() !== 123) throw 'fail'\n    `,\n  }),\n\n  // https://github.com/evanw/esbuild/issues/3210\n  test(['entry.ts', '--bundle', '--outfile=node.js'], {\n    'entry.ts': `\n      import { MyEnum } from './enums';\n      enum MyEnum2 {\n        'A.A' = 'a',\n        'aa' = 'aa',\n      }\n      if (\n        MyEnum['A.A'] !== 'a' || MyEnum2['A.A'] !== 'a' ||\n        MyEnum.aa !== 'aa' || MyEnum2['aa'] !== 'aa' ||\n        MyEnum['aa'] !== 'aa' || MyEnum2.aa !== 'aa'\n      ) throw 'fail'\n    `,\n    'enums.ts': `\n      export enum MyEnum {\n        'A.A' = 'a',\n        'aa' = 'aa',\n      }\n    `,\n  }),\n)\n\n// Check \"tsconfig.json\" behavior\ntests.push(\n  // See: https://github.com/evanw/esbuild/issues/2481\n  test(['main.ts', '--bundle', '--outfile=node.js'], {\n    'main.ts': `\n      import { foo } from 'js-pkg'\n      import { bar } from 'ts-pkg'\n      import { foo as shimFoo, bar as shimBar } from 'pkg'\n      if (foo !== 'foo') throw 'fail: foo'\n      if (bar !== 'bar') throw 'fail: bar'\n      if (shimFoo !== 'shimFoo') throw 'fail: shimFoo'\n      if (shimBar !== 'shimBar') throw 'fail: shimBar'\n    `,\n    'shim.ts': `\n      export let foo = 'shimFoo'\n      export let bar = 'shimBar'\n    `,\n    'tsconfig.json': `{\n      \"compilerOptions\": {\n        \"paths\": {\n          \"pkg\": [\"./shim\"],\n        },\n      },\n    }`,\n    'node_modules/js-pkg/index.js': `\n      import { foo as pkgFoo } from 'pkg'\n      export let foo = pkgFoo\n    `,\n    'node_modules/ts-pkg/index.ts': `\n      import { bar as pkgBar } from 'pkg'\n      export let bar = pkgBar\n    `,\n    'node_modules/pkg/index.js': `\n      export let foo = 'foo'\n      export let bar = 'bar'\n    `,\n  }),\n\n  // See: https://github.com/evanw/esbuild/issues/3767\n  test(['apps/client/src/index.ts', '--bundle', '--outfile=node.js'], {\n    'apps/client/src/index.ts': `\n      import { foo } from '~/foo'\n      if (foo !== 'foo') throw 'fail'\n    `,\n    'apps/client/src/foo.ts': `\n      export const foo = 'foo'\n    `,\n    'apps/client/tsconfig.json': `{\n      \"extends\": \"@repo/tsconfig/base\"\n    }`,\n    'apps/client/node_modules/@repo/tsconfig': {\n      symlink: `../../../../tooling/typescript`,\n    },\n    'tooling/typescript/base.json': `{\n      \"compilerOptions\": {\n        \"paths\": {\n          \"~/*\": [\"../../apps/client/src/*\"]\n        }\n      }\n    }`,\n  }),\n)\n\n// Test coverage for a special JSX error message\ntests.push(\n  test(['example.jsx', '--outfile=node.js'], {\n    'example.jsx': `let button = <Button content=\"some so-called \\\\\"button text\\\\\"\" />`,\n  }, {\n    expectedStderr: `${errorIcon} [ERROR] Unexpected backslash in JSX element\n\n    example.jsx:1:58:\n      1 │ let button = <Button content=\"some so-called \\\\\"button text\\\\\"\" />\n        ╵                                                           ^\n\n  Quoted JSX attributes use XML-style escapes instead of JavaScript-style escapes:\n\n    example.jsx:1:45:\n      1 │ let button = <Button content=\"some so-called \\\\\"button text\\\\\"\" />\n        │                                              ~~\n        ╵                                              &quot;\n\n  Consider using a JavaScript string inside {...} instead of a quoted JSX attribute:\n\n    example.jsx:1:29:\n      1 │ let button = <Button content=\"some so-called \\\\\"button text\\\\\"\" />\n        │                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n        ╵                              {\"some so-called \\\\\"button text\\\\\"\"}\n\n`,\n  }),\n  test(['example.jsx', '--outfile=node.js'], {\n    'example.jsx': `let button = <Button content='some so-called \\\\'button text\\\\'' />`,\n  }, {\n    expectedStderr: `${errorIcon} [ERROR] Unexpected backslash in JSX element\n\n    example.jsx:1:58:\n      1 │ let button = <Button content='some so-called \\\\'button text\\\\'' />\n        ╵                                                           ^\n\n  Quoted JSX attributes use XML-style escapes instead of JavaScript-style escapes:\n\n    example.jsx:1:45:\n      1 │ let button = <Button content='some so-called \\\\'button text\\\\'' />\n        │                                              ~~\n        ╵                                              &apos;\n\n  Consider using a JavaScript string inside {...} instead of a quoted JSX attribute:\n\n    example.jsx:1:29:\n      1 │ let button = <Button content='some so-called \\\\'button text\\\\'' />\n        │                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n        ╵                              {'some so-called \\\\'button text\\\\''}\n\n`,\n  }),\n)\n\n// Test the \"browser\" field in \"package.json\"\ntests.push(\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('foo')`,\n    'package.json': `{ \"browser\": { \"./foo\": \"./file\" } }`,\n    'file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('foo')`,\n    'package.json': `{ \"browser\": { \"foo\": \"./file\" } }`,\n    'file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('./foo')`,\n    'package.json': `{ \"browser\": { \"./foo\": \"./file\" } }`,\n    'file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('./foo')`,\n    'package.json': `{ \"browser\": { \"foo\": \"./file\" } }`,\n    'file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('pkg/foo/bar')`,\n    'node_modules/pkg/package.json': `{ \"browser\": { \"./foo/bar\": \"./file\" } }`,\n    'node_modules/pkg/foo/bar.js': `invalid syntax`,\n    'node_modules/pkg/file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('pkg/foo/bar')`,\n    'node_modules/pkg/package.json': `{ \"browser\": { \"foo/bar\": \"./file\" } }`,\n    'node_modules/pkg/foo/bar.js': `invalid syntax`,\n    'node_modules/pkg/file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('pkg/foo/bar')`,\n    'node_modules/pkg/package.json': `{ \"browser\": { \"./foo/bar\": \"./file\" } }`,\n    'node_modules/pkg/file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('pkg/foo/bar')`,\n    'node_modules/pkg/package.json': `{ \"browser\": { \"foo/bar\": \"./file\" } }`,\n    'node_modules/pkg/file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('pkg')`,\n    'node_modules/pkg/index.js': `require('foo/bar')`,\n    'node_modules/pkg/package.json': `{ \"browser\": { \"./foo/bar\": \"./file\" } }`,\n    'node_modules/pkg/file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('pkg')`,\n    'node_modules/pkg/index.js': `require('foo/bar')`,\n    'node_modules/pkg/package.json': `{ \"browser\": { \"foo/bar\": \"./file\" } }`,\n    'node_modules/pkg/file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('pkg')`,\n    'node_modules/pkg/index.js': `throw 'fail'`,\n    'node_modules/pkg/package.json': `{ \"browser\": { \"./index.js\": \"./file\" } }`,\n    'node_modules/pkg/file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('pkg')`,\n    'node_modules/pkg/package.json': `{ \"browser\": { \"./index.js\": \"./file\" } }`,\n    'node_modules/pkg/file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('pkg')`,\n    'node_modules/pkg/index.js': `throw 'fail'`,\n    'node_modules/pkg/package.json': `{ \"browser\": { \"./index\": \"./file\" } }`,\n    'node_modules/pkg/file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('pkg')`,\n    'node_modules/pkg/package.json': `{ \"browser\": { \"./index\": \"./file\" } }`,\n    'node_modules/pkg/file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('pkg')`,\n    'node_modules/pkg/main.js': `throw 'fail'`,\n    'node_modules/pkg/package.json': `{ \"main\": \"./main\",\\n  \"browser\": { \"./main.js\": \"./file\" } }`,\n    'node_modules/pkg/file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('pkg')`,\n    'node_modules/pkg/package.json': `{ \"main\": \"./main\",\\n  \"browser\": { \"./main.js\": \"./file\" } }`,\n    'node_modules/pkg/file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('pkg')`,\n    'package.json': `{ \"browser\": { \"pkg2\": \"pkg3\" } }`,\n    'node_modules/pkg/index.js': `require('pkg2')`,\n    'node_modules/pkg/package.json': `{ \"browser\": { \"pkg2\": \"./file\" } }`,\n    'node_modules/pkg/file.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('pkg')`,\n    'package.json': `{ \"browser\": { \"pkg2\": \"pkg3\" } }`,\n    'node_modules/pkg/index.js': `require('pkg2')`,\n    'node_modules/pkg2/index.js': `throw 'fail'`,\n    'node_modules/pkg3/index.js': `var works = true`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `require('pkg')`,\n    'package.json': `{ \"browser\": { \"pkg2\": \"pkg3\" } }`,\n    'node_modules/pkg/index.js': `require('pkg2')`,\n    'node_modules/pkg/package.json': `{ \"browser\": { \"./pkg2\": \"./file\" } }`,\n    'node_modules/pkg/file.js': `var works = true`,\n  }),\n)\n\n// Test arbitrary module namespace identifier names\n// See https://github.com/tc39/ecma262/pull/2154\ntests.push(\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `import {'*' as star} from './export.js'; if (star !== 123) throw 'fail'`,\n    'export.js': `let foo = 123; export {foo as '*'}`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `import {'\\\\0' as bar} from './export.js'; if (bar !== 123) throw 'fail'`,\n    'export.js': `let foo = 123; export {foo as '\\\\0'}`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `import {'\\\\uD800\\\\uDC00' as bar} from './export.js'; if (bar !== 123) throw 'fail'`,\n    'export.js': `let foo = 123; export {foo as '\\\\uD800\\\\uDC00'}`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `import {'🍕' as bar} from './export.js'; if (bar !== 123) throw 'fail'`,\n    'export.js': `let foo = 123; export {foo as '🍕'}`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `import {' ' as bar} from './export.js'; if (bar !== 123) throw 'fail'`,\n    'export.js': `export let foo = 123; export {foo as ' '} from './export.js'`,\n  }),\n  test(['entry.js', '--bundle', '--outfile=node.js'], {\n    'entry.js': `import {'' as ab} from './export.js'; if (ab.foo !== 123 || ab.bar !== 234) throw 'fail'`,\n    'export.js': `export let foo = 123, bar = 234; export * as '' from './export.js'`,\n  }),\n)\n\n// Tests for symlinks\n//\n// Note: These are disabled on Windows because they fail when run with GitHub\n// Actions. I'm not sure what the issue is because they pass for me when run in\n// my Windows VM (Windows 10 in VirtualBox on macOS).\nif (process.platform !== 'win32') {\n  tests.push(\n    // Without preserve symlinks\n    test(['--bundle', 'in.js', '--outfile=node.js'], {\n      'in.js': `import {foo} from 'foo'; if (foo !== 123) throw 'fail'`,\n      'registry/node_modules/foo/index.js': `export {bar as foo} from 'bar'`,\n      'registry/node_modules/bar/index.js': `export const bar = 123`,\n      'node_modules/foo': { symlink: `../registry/node_modules/foo` },\n    }),\n    test(['--bundle', 'in.js', '--outfile=node.js'], {\n      'in.js': `import {foo} from 'foo'; if (foo !== 123) throw 'fail'`,\n      'registry/node_modules/foo/index.js': `export {bar as foo} from 'bar'`,\n      'registry/node_modules/bar/index.js': `export const bar = 123`,\n      'node_modules/foo/index.js': { symlink: `../../registry/node_modules/foo/index.js` },\n    }),\n    test(['--bundle', 'in.js', '--outfile=node.js'], {\n      'in.js': `import {foo} from 'foo'; if (foo !== 123) throw 'fail'`,\n      'registry/node_modules/foo/index.js': `export {bar as foo} from 'bar'`,\n      'registry/node_modules/bar/index.js': `export const bar = 123`,\n      'node_modules/foo': { symlink: `TEST_DIR_ABS_PATH/registry/node_modules/foo` },\n    }),\n    test(['--bundle', 'in.js', '--outfile=node.js'], {\n      'in.js': `import {foo} from 'foo'; if (foo !== 123) throw 'fail'`,\n      'registry/node_modules/foo/index.js': `export {bar as foo} from 'bar'`,\n      'registry/node_modules/bar/index.js': `export const bar = 123`,\n      'node_modules/foo/index.js': { symlink: `TEST_DIR_ABS_PATH/registry/node_modules/foo/index.js` },\n    }),\n\n    // With preserve symlinks\n    test(['--bundle', 'src/in.js', '--outfile=node.js', '--preserve-symlinks'], {\n      'src/in.js': `import {foo} from 'foo'; if (foo !== 123) throw 'fail'`,\n      'registry/node_modules/foo/index.js': `export {bar as foo} from 'bar'`,\n      'src/node_modules/bar/index.js': `export const bar = 123`,\n      'src/node_modules/foo': { symlink: `../../registry/node_modules/foo` },\n    }),\n    test(['--bundle', 'src/in.js', '--outfile=node.js', '--preserve-symlinks'], {\n      'src/in.js': `import {foo} from 'foo'; if (foo !== 123) throw 'fail'`,\n      'registry/node_modules/foo/index.js': `export {bar as foo} from 'bar'`,\n      'src/node_modules/bar/index.js': `export const bar = 123`,\n      'src/node_modules/foo/index.js': { symlink: `../../../registry/node_modules/foo/index.js` },\n    }),\n    test(['--bundle', 'src/in.js', '--outfile=node.js', '--preserve-symlinks'], {\n      'src/in.js': `import {foo} from 'foo'; if (foo !== 123) throw 'fail'`,\n      'registry/node_modules/foo/index.js': `export {bar as foo} from 'bar'`,\n      'src/node_modules/bar/index.js': `export const bar = 123`,\n      'src/node_modules/foo': { symlink: `TEST_DIR_ABS_PATH/registry/node_modules/foo` },\n    }),\n    test(['--bundle', 'src/in.js', '--outfile=node.js', '--preserve-symlinks'], {\n      'src/in.js': `import {foo} from 'foo'; if (foo !== 123) throw 'fail'`,\n      'registry/node_modules/foo/index.js': `export {bar as foo} from 'bar'`,\n      'src/node_modules/bar/index.js': `export const bar = 123`,\n      'src/node_modules/foo/index.js': { symlink: `TEST_DIR_ABS_PATH/registry/node_modules/foo/index.js` },\n    }),\n\n    // This is a test for https://github.com/evanw/esbuild/issues/222\n    test(['--bundle', 'src/in.js', '--outfile=out/node.js', '--metafile=out/meta.json', '--platform=node', '--format=cjs'], {\n      'a/b/src/in.js': `\n        import {metafile} from './load'\n        const assert = require('assert')\n        assert.deepStrictEqual(Object.keys(metafile.inputs), ['src/load.js', 'src/in.js'])\n        assert.strictEqual(metafile.inputs['src/in.js'].imports[0].path, 'src/load.js')\n      `,\n      'a/b/src/load.js': `\n        export var metafile\n        // Hide the import path from the bundler\n        try {\n          let path = './meta.json'\n          metafile = require(path)\n        } catch (e) {\n        }\n      `,\n      'node.js': `\n        require('./a/b/out/node')\n      `,\n      'c': { symlink: `a/b` },\n    }, { cwd: 'c' }),\n\n    // This is a test for https://github.com/evanw/esbuild/issues/766\n    test(['--bundle', 'impl/index.mjs', '--outfile=node.js', '--format=cjs', '--resolve-extensions=.mjs'], {\n      'config/yarn/link/@monorepo-source/a': { symlink: `../../../../monorepo-source/packages/a` },\n      'config/yarn/link/@monorepo-source/b': { symlink: `../../../../monorepo-source/packages/b` },\n      'impl/node_modules/@monorepo-source/b': { symlink: `../../../config/yarn/link/@monorepo-source/b` },\n      'impl/index.mjs': `\n        import { fn } from '@monorepo-source/b';\n        if (fn() !== 123) throw 'fail';\n      `,\n      'monorepo-source/packages/a/index.mjs': `\n        export function foo() { return 123; }\n      `,\n      'monorepo-source/packages/b/node_modules/@monorepo-source/a': { symlink: `../../../../../config/yarn/link/@monorepo-source/a` },\n      'monorepo-source/packages/b/index.mjs': `\n        import { foo } from '@monorepo-source/a';\n        export function fn() { return foo(); }\n      `,\n    }),\n\n    // These tests are for https://github.com/evanw/esbuild/issues/2773\n    test(['--bundle', 'in.js', '--outfile=node.js'], {\n      'in.js': `import {foo} from './baz/bar/foo'; if (foo !== 444) throw 'fail'`,\n      'foo/index.js': `import {qux} from '../qux'; export const foo = 123 + qux`,\n      'qux/index.js': `export const qux = 321`,\n      'bar/foo': { symlink: `../foo` },\n      'baz/bar': { symlink: `../bar` },\n    }),\n    test(['--bundle', 'in.js', '--outfile=node.js'], {\n      'in.js': `import {foo} from './baz/bar/foo'; if (foo !== 444) throw 'fail'`,\n      'foo/index.js': `import {qux} from '../qux'; export const foo = 123 + qux`,\n      'qux/index.js': `export const qux = 321`,\n      'bar/foo': { symlink: `TEST_DIR_ABS_PATH/foo` },\n      'baz/bar': { symlink: `TEST_DIR_ABS_PATH/bar` },\n    }),\n  )\n}\n\n// Test custom output paths\ntests.push(\n  test(['node=entry.js', '--outdir=.'], {\n    'entry.js': ``,\n  }),\n)\n\n// Make sure that the \"asm.js\" directive is removed\ntests.push(\n  test(['in.js', '--outfile=node.js'], {\n    'in.js': `\n      function foo() { 'use asm'; eval(\"/* not asm.js */\") }\n      let emitWarning = process.emitWarning\n      let failed = false\n      try {\n        process.emitWarning = () => failed = true\n        foo()\n      } finally {\n        process.emitWarning = emitWarning\n      }\n      if (failed) throw 'fail'\n    `,\n  }),\n)\n\n// Check async generator lowering\nfor (const flags of [[], ['--target=es6', '--target=es2017', '--supported:async-generator=false', '--supported:async-await=false']]) {\n  tests.push(\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        function* x() {\n          yield 1\n          yield 2\n          return 3\n        }\n        async function y(arg) {\n          return -(await Promise.resolve(arg))\n        }\n        async function* z(arg) {\n          yield 1\n          yield Promise.resolve(2)\n          yield* [3, Promise.resolve(4)]\n          yield* {\n            [Symbol.iterator]() {\n              var value = 5\n              return { next: () => ({ value, done: value++ > 6 }) }\n            }\n          }\n          yield* {\n            [Symbol.asyncIterator]() {\n              var value = 7\n              return { next: async () => ({ value, done: value++ > 8 }) }\n            }\n          }\n          return -(await Promise.resolve(arg))\n        }\n        export let async = async () => {\n          let state\n\n          const X = x()\n          if (X[Symbol.iterator]() !== X) throw 'fail: x Symbol.iterator'\n          if (Symbol.asyncIterator in X) throw 'fail: x Symbol.asyncIterator'\n          state = X.next(); if (state.done !== false || state.value !== 1) throw 'fail: x 1: ' + JSON.stringify(state)\n          state = X.next(); if (state.done !== false || state.value !== 2) throw 'fail: x 2: ' + JSON.stringify(state)\n          state = X.next(); if (state.done !== true || state.value !== 3) throw 'fail: x 3: ' + JSON.stringify(state)\n\n          const Y = y(123)\n          if (Symbol.iterator in Y) throw 'fail: y Symbol.iterator'\n          if (Symbol.asyncIterator in Y) throw 'fail: y Symbol.asyncIterator'\n          if (await Y !== -123) throw 'fail: y'\n\n          const Z = z(123)\n          if (Symbol.iterator in Z) throw 'fail: z Symbol.iterator'\n          if (Z[Symbol.asyncIterator]() !== Z) throw 'fail: z Symbol.asyncIterator'\n          state = await Z.next(); if (state.done !== false || state.value !== 1) throw 'fail: z 1: ' + JSON.stringify(state)\n          state = await Z.next(); if (state.done !== false || state.value !== 2) throw 'fail: z 2: ' + JSON.stringify(state)\n          state = await Z.next(); if (state.done !== false || state.value !== 3) throw 'fail: z 3: ' + JSON.stringify(state)\n          state = await Z.next(); if (state.done !== false || state.value !== 4) throw 'fail: z 4: ' + JSON.stringify(state)\n          state = await Z.next(); if (state.done !== false || state.value !== 5) throw 'fail: z 5: ' + JSON.stringify(state)\n          state = await Z.next(); if (state.done !== false || state.value !== 6) throw 'fail: z 6: ' + JSON.stringify(state)\n          state = await Z.next(); if (state.done !== false || state.value !== 7) throw 'fail: z 7: ' + JSON.stringify(state)\n          state = await Z.next(); if (state.done !== false || state.value !== 8) throw 'fail: z 8: ' + JSON.stringify(state)\n          state = await Z.next(); if (state.done !== true || state.value !== -123) throw 'fail: z 123: ' + JSON.stringify(state)\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          yield* {\n            [Symbol.asyncIterator]: () => ({ next() { throw 'f' } })\n          }\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          try { await it.next(); throw 'fail: f: next' } catch (err) { if (err !== 'f') throw err }\n          state = await it.next()\n          if (state.done !== true || state.value !== void 0) throw 'fail: f: done'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          yield* {\n            [Symbol.asyncIterator]: () => ({ get next() { throw 'f' } })\n          }\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          try { await it.next(); throw 'fail: f: next' } catch (err) { if (err !== 'f') throw err }\n          state = await it.next()\n          if (state.done !== true || state.value !== void 0) throw 'fail: f: done'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          yield* {\n            [Symbol.asyncIterator]: () => ({ async next() { throw 'f' } })\n          }\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          try { await it.next(); throw 'fail: f: next' } catch (err) { if (err !== 'f') throw err }\n          state = await it.next()\n          if (state.done !== true || state.value !== void 0) throw 'fail: f: done'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          try {\n            yield* {\n              [Symbol.asyncIterator]: () => ({\n                next: () => ({\n                  done: false,\n                  get value() { throw 'f' }\n                })\n              }),\n            }\n          } catch (e) {\n            return e\n          }\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          state = await it.next()\n          if (state.done !== true || state.value !== 'f') throw 'fail: f: next'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          yield* [\n            Promise.reject('f.x'),\n            'f.y',\n          ]\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          try { await it.next(); throw 'fail: f: next' } catch (err) { if (err !== 'f.x') throw err }\n          state = await it.next()\n          if (state.done !== true || state.value !== void 0) throw 'fail: f: done'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          yield* {\n            [Symbol.iterator]: () => ({ next: () => 123 }),\n          }\n          return 'f'\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          try { await it.next(); throw 'fail: f: next' } catch (err) { if (!(err instanceof TypeError)) throw err }\n          state = await it.next()\n          if (state.done !== true || state.value !== void 0) throw 'fail: f: done'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          yield* {\n            [Symbol.asyncIterator]: () => ({ next: () => 123 }),\n          }\n          return 'f'\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          try { await it.next(); throw 'fail: f: next' } catch (err) { if (!(err instanceof TypeError)) throw err }\n          state = await it.next()\n          if (state.done !== true || state.value !== void 0) throw 'fail: f: done'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          yield* [\n            'f.x',\n            'f.y',\n          ]\n          return 'f'\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          state = await it.next()\n          if (state.done !== false || state.value !== 'f.x') throw 'fail: f: next'\n          try { await it.throw('f: throw') } catch (err) { var error = err }\n          if (error !== 'f: throw') throw 'fail: f: ' + error\n          state = await it.next()\n          if (state.done !== true || state.value !== void 0) throw 'fail: f: done'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          yield* {\n            [Symbol.iterator]: () => ({\n              next: a => ({ value: 'f.x.' + a, done: false }),\n              return: a => ({ value: 'f.y.' + a, done: true }),\n            })\n          }\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          state = await it.next('A')\n          if (state.done !== false || state.value !== 'f.x.undefined') throw 'fail: f: next'\n          state = await it.return('B')\n          if (state.done !== true || state.value !== 'f.y.B') throw 'fail: f: return'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          yield* {\n            [Symbol.asyncIterator]: () => ({\n              next: a => Promise.resolve({ value: 'f.x.' + a, done: false }),\n              return: a => Promise.resolve({ value: 'f.y.' + a, done: true }),\n            })\n          }\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          state = await it.next('A')\n          if (state.done !== false || state.value !== 'f.x.undefined') throw 'fail: f: next'\n          state = await it.return('B')\n          if (state.done !== true || state.value !== 'f.y.B') throw 'fail: f: return'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          yield* {\n            [Symbol.iterator]: () => ({\n              next: a => ({ value: 'f.x.' + a, done: false }),\n              throw: a => ({ value: 'f.y.' + a, done: true }),\n            })\n          }\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          state = await it.next('A')\n          if (state.done !== false || state.value !== 'f.x.undefined') throw 'fail: f: next'\n          state = await it.throw('B')\n          if (state.done !== true || state.value !== undefined) throw 'fail: f: throw'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          yield* {\n            [Symbol.asyncIterator]: () => ({\n              next: a => Promise.resolve({ value: 'f.x.' + a, done: false }),\n              throw: a => Promise.resolve({ value: 'f.y.' + a, done: true }),\n            })\n          }\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          state = await it.next('A')\n          if (state.done !== false || state.value !== 'f.x.undefined') throw 'fail: f: next'\n          state = await it.throw('B')\n          if (state.done !== true || state.value !== undefined) throw 'fail: f: throw'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          var value = 0\n          yield* {\n            [Symbol.iterator]: () => ({ next: () => ({ done: value > 10, value: value += 100 }) }),\n            get [Symbol.asyncIterator]() { value += 10; return undefined },\n          }\n          return value\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          state = await it.next(); if (state.done !== false || state.value !== 110) throw 'fail: f 110: ' + JSON.stringify(state)\n          state = await it.next(); if (state.done !== true || state.value !== 210) throw 'fail: f 210: ' + JSON.stringify(state)\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          var value = 0\n          yield* {\n            [Symbol.iterator]: () => ({ next: () => ({ done: value > 10, value: value += 100 }) }),\n            get [Symbol.asyncIterator]() { value += 10; return null },\n          }\n          return value\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          state = await it.next(); if (state.done !== false || state.value !== 110) throw 'fail: f 110: ' + JSON.stringify(state)\n          state = await it.next(); if (state.done !== true || state.value !== 210) throw 'fail: f 210: ' + JSON.stringify(state)\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          var value = 0\n          yield* {\n            [Symbol.iterator]: () => ({ next: () => ({ done: value > 10, value: value += 100 }) }),\n            get [Symbol.asyncIterator]() { value += 10; return false },\n          }\n          return value\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          try { await it.next() } catch (e) { var error = e }\n          if (!(error instanceof TypeError)) throw 'fail: f'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        async function* f() {\n          var value = 0\n          yield* {\n            [Symbol.iterator]: () => ({ next: () => ({ done: value > 10, value: value += 100 }) }),\n            get [Symbol.asyncIterator]() { value += 10; return 0 },\n          }\n          return value\n        }\n        export let async = async () => {\n          let it, state\n          it = f()\n          try { await it.next() } catch (e) { var error = e }\n          if (!(error instanceof TypeError)) throw 'fail: f'\n        }\n      `,\n    }, { async: true }),\n  )\n}\n\n// Check \"for await\" lowering\nfor (const flags of [[], ['--target=es6', '--target=es2017', '--supported:for-await=false']]) {\n  tests.push(\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        export let async = async () => {\n          const log = []\n          const it = {\n            [Symbol.iterator]() { return this },\n            next() { log.push(this === it && 'next'); return { value: 123, done: false } },\n            return() { log.push(this === it && 'return') },\n          }\n          try {\n            for await (const x of it) {\n              if (x !== 123) throw 'fail: ' + x\n              throw 'foo'\n            }\n          } catch (err) {\n            if (err !== 'foo') throw err\n          }\n          if (log + '' !== 'next,return') throw 'fail: ' + log\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        export let async = async () => {\n          const log = []\n          const it = {\n            [Symbol.asyncIterator]() { return this },\n            async next() { log.push(this === it && 'next'); return { value: 123, done: false } },\n            async return() { log.push(this === it && 'return') },\n          }\n          try {\n            for await (const x of it) {\n              if (x !== 123) throw 'fail: ' + x\n              throw 'foo'\n            }\n          } catch (err) {\n            if (err !== 'foo') throw err\n          }\n          if (log + '' !== 'next,return') throw 'fail: ' + log\n        }\n      `,\n    }, { async: true }),\n\n    // return() must not be called in this case (TypeScript has this bug: https://github.com/microsoft/TypeScript/issues/50525)\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        let pass = true\n        async function f() {\n          const y = {\n            [Symbol.asyncIterator]() {\n              let count = 0\n              return {\n                async next() {\n                  count++\n                  if (count === 2) throw 'error'\n                  return { value: count }\n                },\n                async return() {\n                  pass = false\n                },\n              }\n            },\n          }\n          for await (let x of y) {\n          }\n        }\n        f().catch(() => {\n          if (!pass) throw 'fail'\n        })\n      `,\n    }),\n\n    // return() must be called in this case\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        let pass = false\n        async function f() {\n          const y = {\n            [Symbol.asyncIterator]() {\n              let count = 0\n              return {\n                async next() {\n                  count++\n                  return { value: count }\n                },\n                async return() {\n                  pass = true\n                },\n              }\n            },\n          }\n          for await (let x of y) {\n            throw 'error'\n          }\n        }\n        f().catch(() => {\n          if (!pass) throw 'fail'\n        })\n      `,\n    }),\n  )\n}\n\n// Check object rest lowering\n// https://github.com/evanw/esbuild/issues/956\ntests.push(\n  test(['in.js', '--outfile=node.js', '--target=es6'], {\n    'in.js': `\n      let v, o = {b: 3, c: 5}, e = ({b: v, ...o} = o);\n      if (o === e || o.b !== void 0 || o.c !== 5 || e.b !== 3 || e.c !== 5 || v !== 3) throw 'fail'\n    `,\n  }),\n)\n\n// Check object spread lowering\n// https://github.com/evanw/esbuild/issues/1017\nconst objectAssignSemantics = `\n  var a, b, c, p, s = Symbol('s')\n\n  // Getter\n  a = { x: 1 }\n  b = { get x() {}, ...a }\n  if (b.x !== a.x) throw 'fail: 1'\n\n  // Symbol getter\n  a = {}\n  a[s] = 1\n  p = {}\n  Object.defineProperty(p, s, { get: () => {} })\n  b = { __proto__: p, ...a }\n  if (b[s] !== a[s]) throw 'fail: 2'\n\n  // Non-enumerable\n  a = {}\n  Object.defineProperty(a, 'x', { value: 1 })\n  b = { ...a }\n  if (b.x === a.x) throw 'fail: 3'\n\n  // Symbol non-enumerable\n  a = {}\n  Object.defineProperty(a, s, { value: 1 })\n  b = { ...a }\n  if (b[s] === a[s]) throw 'fail: 4'\n\n  // Prototype\n  a = Object.create({ x: 1 })\n  b = { ...a }\n  if (b.x === a.x) throw 'fail: 5'\n\n  // Symbol prototype\n  p = {}\n  p[s] = 1\n  a = Object.create(p)\n  b = { ...a }\n  if (b[s] === a[s]) throw 'fail: 6'\n\n  // Getter evaluation 1\n  a = 1\n  b = 10\n  p = { get x() { return a++ }, ...{ get y() { return b++ } } }\n  if (\n    p.x !== 1 || p.x !== 2 || p.x !== 3 ||\n    p.y !== 10 || p.y !== 10 || p.y !== 10\n  ) throw 'fail: 7'\n\n  // Getter evaluation 2\n  a = 1\n  b = 10\n  p = { ...{ get x() { return a++ } }, get y() { return b++ } }\n  if (\n    p.x !== 1 || p.x !== 1 || p.x !== 1 ||\n    p.y !== 10 || p.y !== 11 || p.y !== 12\n  ) throw 'fail: 8'\n\n  // Getter evaluation 3\n  a = 1\n  b = 10\n  c = 100\n  p = { ...{ get x() { return a++ } }, get y() { return b++ }, ...{ get z() { return c++ } } }\n  if (\n    p.x !== 1 || p.x !== 1 || p.x !== 1 ||\n    p.y !== 10 || p.y !== 11 || p.y !== 12 ||\n    p.z !== 100 || p.z !== 100 || p.z !== 100\n  ) throw 'fail: 9'\n\n  // Inline prototype property\n  p = { ...{ __proto__: null } }\n  if (Object.prototype.hasOwnProperty.call(p, '__proto__') || Object.getPrototypeOf(p) === null) throw 'fail: 10'\n`\ntests.push(\n  test(['in.js', '--outfile=node.js'], {\n    'in.js': objectAssignSemantics,\n  }),\n  test(['in.js', '--outfile=node.js', '--target=es6'], {\n    'in.js': objectAssignSemantics,\n  }),\n  test(['in.js', '--outfile=node.js', '--target=es5'], {\n    'in.js': objectAssignSemantics,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify-syntax'], {\n    'in.js': objectAssignSemantics,\n  }),\n)\n\n// Check big integer lowering\nfor (const minify of [[], '--minify']) {\n  for (const target of [[], ['--target=es6']]) {\n    tests.push(test(['in.js', '--outfile=node.js', '--bundle', '--log-override:bigint=silent'].concat(target).concat(minify), {\n      'in.js': `\n        var BigInt = function() {\n          throw 'fail: BigInt'\n        };\n\n        function check(a, b, c) {\n          if (b[a] !== true) throw 'fail 1: ' + a\n          if (c(b) !== true) throw 'fail 2: ' + a\n        }\n\n        check(0n, { 0n: true }, ({ 0n: x }) => x)\n        check(0b100101n, { 0b100101n: true }, ({ 0b100101n: x }) => x)\n        check(0B100101n, { 0B100101n: true }, ({ 0B100101n: x }) => x)\n        check(0o76543210n, { 0o76543210n: true }, ({ 0o76543210n: x }) => x)\n        check(0O76543210n, { 0O76543210n: true }, ({ 0O76543210n: x }) => x)\n        check(0xFEDCBA9876543210n, { 0xFEDCBA9876543210n: true }, ({ 0xFEDCBA9876543210n: x }) => x)\n        check(0XFEDCBA9876543210n, { 0XFEDCBA9876543210n: true }, ({ 0XFEDCBA9876543210n: x }) => x)\n        check(0xb0ba_cafe_f00dn, { 0xb0ba_cafe_f00dn: true }, ({ 0xb0ba_cafe_f00dn: x }) => x)\n        check(0xB0BA_CAFE_F00Dn, { 0xB0BA_CAFE_F00Dn: true }, ({ 0xB0BA_CAFE_F00Dn: x }) => x)\n        check(102030405060708090807060504030201n, { 102030405060708090807060504030201n: true }, ({ 102030405060708090807060504030201n: x }) => x)\n      `,\n    }))\n  }\n\n  tests.push(\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        // Must not be minified to \"if (!(a | b)) throw 'fail'\"\n        function foo(a, b) { if ((a | b) === 0) throw 'fail' }\n        foo(0n, 0n)\n        foo(1n, 1n)\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        // Must not be minified to \"if (!(a & b)) throw 'fail'\"\n        function foo(a, b) { if ((a & b) === 0) throw 'fail' }\n        foo(0n, 0n)\n        foo(1n, 1n)\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        // Must not be minified to \"if (!(a ^ b)) throw 'fail'\"\n        function foo(a, b) { if ((a ^ b) === 0) throw 'fail' }\n        foo(0n, 0n)\n        foo(0n, 1n)\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        // Must not be minified to \"if (!(a << b)) throw 'fail'\"\n        function foo(a, b) { if ((a << b) === 0) throw 'fail' }\n        foo(0n, 0n)\n        foo(1n, 1n)\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        // Must not be minified to \"if (!(a >> b)) throw 'fail'\"\n        function foo(a, b) { if ((a >> b) === 0) throw 'fail' }\n        foo(1n, 0n)\n        foo(1n, 1n)\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        // Must not be minified to \"if (!~a) throw 'fail'\"\n        function foo(a) { if (~a === 0) throw 'fail' }\n        foo(-1n)\n        foo(1n)\n      `,\n    }),\n  )\n}\n\n// Check template literal lowering\nfor (const target of ['--target=es5', '--target=es6', '--target=es2020']) {\n  tests.push(\n    // Untagged template literals\n    test(['in.js', '--outfile=node.js', target], {\n      'in.js': `\n        var obj = {\n          toString: () => 'b',\n          valueOf: () => 0,\n        }\n        if (\\`\\${obj}\\` !== 'b') throw 'fail'\n        if (\\`a\\${obj}\\` !== 'ab') throw 'fail'\n        if (\\`\\${obj}c\\` !== 'bc') throw 'fail'\n        if (\\`a\\${obj}c\\` !== 'abc') throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', target], {\n      'in.js': `\n        var obj = {}\n        obj[Symbol.toPrimitive] = hint => {\n          if (hint !== 'string') throw 'fail'\n          return 'b'\n        }\n        if (\\`\\${obj}\\` !== 'b') throw 'fail'\n        if (\\`a\\${obj}\\` !== 'ab') throw 'fail'\n        if (\\`\\${obj}c\\` !== 'bc') throw 'fail'\n        if (\\`a\\${obj}c\\` !== 'abc') throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', target], {\n      'in.js': `\n        var list = []\n        var trace = x => list.push(x)\n        var obj2 = { toString: () => trace(2) };\n        var obj4 = { toString: () => trace(4) };\n        \\`\\${trace(1), obj2}\\${trace(3), obj4}\\`\n        if (list.join('') !== '1234') throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', target], {\n      'in.js': `\n        x: {\n          try {\n            \\`\\${Symbol('y')}\\`\n          } catch {\n            break x\n          }\n          throw 'fail'\n        }\n      `,\n    }),\n\n    // Tagged template literals\n    test(['in.js', '--outfile=node.js', target], {\n      'in.js': `\n        if ((x => x[0] === 'y' && x.raw[0] === 'y')\\`y\\` !== true) throw 'fail'\n        if ((x => x[0] === 'y' && x.raw[0] === 'y')\\`y\\${0}\\` !== true) throw 'fail'\n        if ((x => x[1] === 'y' && x.raw[1] === 'y')\\`\\${0}y\\` !== true) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', target], {\n      'in.js': `\n        if ((x => x[0] === '\\\\xFF' && x.raw[0] === '\\\\\\\\xFF')\\`\\\\xFF\\` !== true) throw 'fail'\n        if ((x => x[0] === '\\\\xFF' && x.raw[0] === '\\\\\\\\xFF')\\`\\\\xFF\\${0}\\` !== true) throw 'fail'\n        if ((x => x[1] === '\\\\xFF' && x.raw[1] === '\\\\\\\\xFF')\\`\\${0}\\\\xFF\\` !== true) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', target], {\n      'in.js': `\n        if ((x => x[0] === void 0 && x.raw[0] === '\\\\\\\\u')\\`\\\\u\\` !== true) throw 'fail'\n        if ((x => x[0] === void 0 && x.raw[0] === '\\\\\\\\u')\\`\\\\u\\${0}\\` !== true) throw 'fail'\n        if ((x => x[1] === void 0 && x.raw[1] === '\\\\\\\\u')\\`\\${0}\\\\u\\` !== true) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', target], {\n      'in.js': `\n        if ((x => x !== x.raw)\\`y\\` !== true) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', target], {\n      'in.js': `\n        if ((x => (x.length = 2, x.length))\\`y\\` !== 1) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', target], {\n      'in.js': `\n        if ((x => (x.raw.length = 2, x.raw.length))\\`y\\` !== 1) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', target], {\n      'in.js': `\n        var count = 0\n        var foo = () => (() => ++count)\\`y\\`;\n        if (foo() !== 1 || foo() !== 2) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', target], {\n      'in.js': `\n        var foo = () => (x => x)\\`y\\`;\n        if (foo() !== foo()) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', target], {\n      'in.js': `\n        var foo = () => (x => x)\\`y\\`;\n        var bar = () => (x => x)\\`y\\`;\n        if (foo() === bar()) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', target], {\n      'in.js': `\n        var count = 0;\n        var obj = {\n          foo: function() {\n            if (this === obj) count++;\n          }\n        };\n        var bar = 'foo';\n        (obj?.foo)\\`\\`;\n        (obj?.[bar])\\`\\`;\n        var other = { obj };\n        (other?.obj.foo)\\`\\`;\n        (other?.obj[bar])\\`\\`;\n        if (count !== 4) throw 'fail';\n      `,\n    }),\n\n    // Unused minified template literals. See this for more info:\n    // https://github.com/terser/terser/issues/1128#issuecomment-994209801\n    test(['in.js', '--outfile=node.js', '--minify', target], {\n      'in.js': `\n        var text = '';\n        var foo = {\n          toString: () => text += 'toString',\n          valueOf: () => text += 'valueOf',\n        };\n        \\`\\${foo}\\`;\n        if (text !== 'toString') throw 'fail: ' + text + ' !== toString'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', '--minify', target], {\n      'in.js': `\n        var text = '';\n        var foo = {\n          toString: () => text += 'toString',\n        };\n        \\`abc \\${text += 'A', foo} xyz \\${text += 'B', foo} 123\\`;\n        if (text !== 'AtoStringBtoString') throw 'fail: ' + text + ' !== AtoStringBtoString'\n      `,\n    }),\n  )\n}\n\nlet simpleCyclicImportTestCase542 = {\n  'in.js': `\n    import {Test} from './lib';\n    export function fn() {\n      return 42;\n    }\n    export const foo = [Test];\n    if (Test.method() !== 42) throw 'fail'\n  `,\n  'lib.js': `\n    import {fn} from './in';\n    export class Test {\n      static method() {\n        return fn();\n      }\n    }\n  `,\n}\n\n// Test internal import order\ntests.push(\n  // See https://github.com/evanw/esbuild/issues/421\n  test(['--bundle', 'in.js', '--outfile=node.js'], {\n    'in.js': `\n      import {foo} from './cjs'\n      import {bar} from './esm'\n      if (foo !== 1 || bar !== 2) throw 'fail'\n    `,\n    'cjs.js': `exports.foo = 1; global.internal_import_order_test1 = 2`,\n    'esm.js': `export let bar = global.internal_import_order_test1`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=node.js'], {\n    'in.js': `\n      if (foo !== 3 || bar !== 4) throw 'fail'\n      import {foo} from './cjs'\n      import {bar} from './esm'\n    `,\n    'cjs.js': `exports.foo = 3; global.internal_import_order_test2 = 4`,\n    'esm.js': `export let bar = global.internal_import_order_test2`,\n  }),\n\n  // See https://github.com/evanw/esbuild/issues/542\n  test(['--bundle', 'in.js', '--outfile=node.js'], simpleCyclicImportTestCase542),\n  test(['--bundle', 'in.js', '--outfile=node.js', '--format=iife'], simpleCyclicImportTestCase542),\n  test(['--bundle', 'in.js', '--outfile=node.js', '--format=iife', '--global-name=someName'], simpleCyclicImportTestCase542),\n)\n\n// Test CommonJS semantics\ntests.push(\n  // \"module.require\" should work with internal modules\n  test(['--bundle', 'in.js', '--outfile=out.js', '--format=cjs'], {\n    'in.js': `export {foo, req} from './foo'`,\n    'foo.js': `exports.req = module.require; exports.foo = module.require('./bar')`,\n    'bar.js': `exports.bar = 123`,\n    'node.js': `if (require('./out').foo.bar !== 123 || require('./out').req !== undefined) throw 'fail'`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=out.js', '--format=cjs'], {\n    'in.js': `export {foo, req} from './foo'`,\n    'foo.js': `exports.req = module['require']; exports.foo = module['require']('./bar')`,\n    'bar.js': `exports.bar = 123`,\n    'node.js': `if (require('./out').foo.bar !== 123 || require('./out').req !== undefined) throw 'fail'`,\n  }),\n\n  // \"module.require\" should work with external modules\n  test(['--bundle', 'in.js', '--outfile=out.js', '--format=cjs', '--external:fs'], {\n    'in.js': `export {foo} from './foo'`,\n    'foo.js': `exports.foo = module.require('fs').exists`,\n    'node.js': `if (require('./out').foo !== require('fs').exists) throw 'fail'`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=out.js', '--format=cjs'], {\n    'in.js': `export {foo} from './foo'`,\n    'foo.js': `let fn = (m, p) => m.require(p); exports.foo = fn(module, 'fs').exists`,\n    'node.js': `try { require('./out') } catch (e) { return } throw 'fail'`,\n  }),\n\n  // \"module.exports\" should behave like a normal property\n  test(['--bundle', 'in.js', '--outfile=out.js', '--format=cjs'], {\n    'in.js': `export {foo} from './foo'`,\n    'foo.js': `exports.foo = module.exports`,\n    'node.js': `if (require('./out').foo !== require('./out').foo.foo) throw 'fail'`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=out.js', '--format=cjs'], {\n    'in.js': `export {default} from './foo'`,\n    'foo.js': `module.exports = 123`,\n    'node.js': `if (require('./out').default !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=out.js', '--format=cjs'], {\n    'in.js': `export {default} from './foo'`,\n    'foo.js': `let m = module; m.exports = 123`,\n    'node.js': `if (require('./out').default !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=out.js', '--format=cjs'], {\n    'in.js': `export {default} from './foo'`,\n    'foo.js': `let fn = (m, x) => m.exports = x; fn(module, 123)`,\n    'node.js': `if (require('./out').default !== 123) throw 'fail'`,\n  }),\n\n  // Deferred require shouldn't affect import\n  test(['--bundle', 'in.js', '--outfile=node.js', '--format=cjs'], {\n    'in.js': `\n      import { foo } from './a'\n      import './b'\n      if (foo !== 123) throw 'fail'\n    `,\n    'a.js': `\n      export let foo = 123\n    `,\n    'b.js': `\n      setTimeout(() => require('./a'), 0)\n    `,\n  }),\n\n  // Test the run-time value of \"typeof require\"\n  test(['--bundle', 'in.js', '--outfile=out.js', '--format=iife'], {\n    'in.js': `check(typeof require)`,\n    'node.js': `\n      const out = require('fs').readFileSync(__dirname + '/out.js', 'utf8')\n      const check = x => value = x\n      let value\n      new Function('check', 'require', out)(check)\n      if (value !== 'function') throw 'fail'\n    `,\n  }),\n  test(['--bundle', 'in.js', '--outfile=out.js', '--format=esm'], {\n    'in.js': `check(typeof require)`,\n    'node.js': `\n      import fs from 'fs'\n      import path from 'path'\n      import url from 'url'\n      const __dirname = path.dirname(url.fileURLToPath(import.meta.url))\n      const out = fs.readFileSync(__dirname + '/out.js', 'utf8')\n      const check = x => value = x\n      let value\n      new Function('check', 'require', out)(check)\n      if (value !== 'function') throw 'fail'\n    `,\n  }),\n  test(['--bundle', 'in.js', '--outfile=out.js', '--format=cjs'], {\n    'in.js': `check(typeof require)`,\n    'node.js': `\n      const out = require('fs').readFileSync(__dirname + '/out.js', 'utf8')\n      const check = x => value = x\n      let value\n      new Function('check', 'require', out)(check)\n      if (value !== 'undefined') throw 'fail'\n    `,\n  }),\n)\n\n// Test internal CommonJS export\ntests.push(\n  test(['--bundle', 'in.js', '--outfile=node.js'], {\n    'in.js': `const out = require('./foo'); if (out.__esModule || out.foo !== 123) throw 'fail'`,\n    'foo.js': `exports.foo = 123`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=node.js'], {\n    'in.js': `const out = require('./foo'); if (out.__esModule || out !== 123) throw 'fail'`,\n    'foo.js': `module.exports = 123`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=node.js'], {\n    'in.js': `const out = require('./foo'); if (!out.__esModule || out.foo !== 123) throw 'fail'`,\n    'foo.js': `export const foo = 123`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=node.js'], {\n    'in.js': `const out = require('./foo'); if (!out.__esModule || out.default !== 123) throw 'fail'`,\n    'foo.js': `export default 123`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=node.js'], {\n    'in.js': `const out = require('./foo'); if (!out.__esModule || out.default !== null) throw 'fail'`,\n    'foo.js': `export default function x() {} x = null`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=node.js'], {\n    'in.js': `const out = require('./foo'); if (!out.__esModule || out.default !== null) throw 'fail'`,\n    'foo.js': `export default class x {} x = null`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=node.js'], {\n    'in.js': `\n      // This is the JavaScript generated by \"tsc\" for the following TypeScript:\n      //\n      //   import fn from './foo'\n      //   if (typeof fn !== 'function') throw 'fail'\n      //\n      \"use strict\";\n      var __importDefault = (this && this.__importDefault) || function (mod) {\n        return (mod && mod.__esModule) ? mod : { \"default\": mod };\n      };\n      Object.defineProperty(exports, \"__esModule\", { value: true });\n      const foo_1 = __importDefault(require(\"./foo\"));\n      if (typeof foo_1.default !== 'function')\n        throw 'fail';\n    `,\n    'foo.js': `export default function fn() {}`,\n  }),\n\n  // Self export\n  test(['--bundle', 'in.js', '--outfile=node.js'], {\n    'in.js': `exports.foo = 123; const out = require('./in'); if (out.__esModule || out.foo !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=node.js'], {\n    'in.js': `module.exports = 123; const out = require('./in'); if (out.__esModule || out !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=node.js', '--format=cjs'], {\n    'in.js': `export const foo = 123; const out = require('./in'); if (!out.__esModule || out.foo !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=node.js', '--format=cjs', '--minify'], {\n    'in.js': `export const foo = 123; const out = require('./in'); if (!out.__esModule || out.foo !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=node.js', '--format=cjs'], {\n    'in.js': `export default 123; const out = require('./in'); if (!out.__esModule || out.default !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=node.js', '--format=esm'], {\n    'in.js': `export const foo = 123; const out = require('./in'); if (!out.__esModule || out.foo !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=node.js', '--format=esm', '--minify'], {\n    'in.js': `export const foo = 123; const out = require('./in'); if (!out.__esModule || out.foo !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=node.js', '--format=esm'], {\n    'in.js': `export default 123; const out = require('./in'); if (!out.__esModule || out.default !== 123) throw 'fail'`,\n  }),\n\n  // Test bundled and non-bundled double export star\n  test(['node.ts', '--bundle', '--format=cjs', '--outdir=.'], {\n    'node.ts': `\n      import {a, b} from './re-export'\n      if (a !== 'a' || b !== 'b') throw 'fail'\n    `,\n    're-export.ts': `\n      export * from './a'\n      export * from './b'\n    `,\n    'a.ts': `\n      export let a = 'a'\n    `,\n    'b.ts': `\n      export let b = 'b'\n    `,\n  }),\n  test(['node.ts', '--bundle', '--format=cjs', '--outdir=.'], {\n    'node.ts': `\n      import {a, b} from './re-export'\n      if (a !== 'a' || b !== 'b') throw 'fail'\n\n      // Try forcing all of these modules to be wrappers\n      require('./node')\n      require('./re-export')\n      require('./a')\n      require('./b')\n    `,\n    're-export.ts': `\n      export * from './a'\n      export * from './b'\n    `,\n    'a.ts': `\n      export let a = 'a'\n    `,\n    'b.ts': `\n      export let b = 'b'\n    `,\n  }),\n  test(['node.ts', '--bundle', '--format=cjs', '--outdir=.'], {\n    'node.ts': `\n      import {a, b, c, d} from './re-export'\n      if (a !== 'a' || b !== 'b' || c !== 'c' || d !== 'd') throw 'fail'\n\n      // Try forcing all of these modules to be wrappers\n      require('./node')\n      require('./re-export')\n      require('./a')\n      require('./b')\n    `,\n    're-export.ts': `\n      export * from './a'\n      export * from './b'\n      export * from './d'\n    `,\n    'a.ts': `\n      export let a = 'a'\n    `,\n    'b.ts': `\n      exports.b = 'b'\n    `,\n    'c.ts': `\n      exports.c = 'c'\n    `,\n    'd.ts': `\n      export * from './c'\n      export let d = 'd'\n    `,\n  }),\n  test(['node.ts', 're-export.ts', 'a.ts', 'b.ts', '--format=cjs', '--outdir=.'], {\n    'node.ts': `\n      import {a, b} from './re-export'\n      if (a !== 'a' || b !== 'b') throw 'fail'\n    `,\n    're-export.ts': `\n      export * from './a'\n      export * from './b'\n    `,\n    'a.ts': `\n      export let a = 'a'\n    `,\n    'b.ts': `\n      export let b = 'b'\n    `,\n  }),\n  test(['entry1.js', 'entry2.js', '--splitting', '--bundle', '--format=esm', '--outdir=out'], {\n    'entry1.js': `\n      import { abc, def, xyz } from './a'\n      export default [abc, def, xyz]\n    `,\n    'entry2.js': `\n      import * as x from './b'\n      export default x\n    `,\n    'a.js': `\n      export let abc = 'abc'\n      export * from './b'\n    `,\n    'b.js': `\n      export * from './c'\n      export const def = 'def'\n    `,\n    'c.js': `\n      exports.xyz = 'xyz'\n    `,\n    'node.js': `\n      import entry1 from './out/entry1.js'\n      import entry2 from './out/entry2.js'\n      if (entry1[0] !== 'abc' || entry1[1] !== 'def' || entry1[2] !== 'xyz') throw 'fail'\n      if (entry2.def !== 'def' || entry2.xyz !== 'xyz') throw 'fail'\n    `,\n  }),\n\n  // Complex circular bundled and non-bundled import case (https://github.com/evanw/esbuild/issues/758)\n  test(['node.ts', '--bundle', '--format=cjs', '--outdir=.'], {\n    'node.ts': `\n      import {a} from './re-export'\n      let fn = a()\n      if (fn === a || fn() !== a) throw 'fail'\n    `,\n    're-export.ts': `\n      export * from './a'\n    `,\n    'a.ts': `\n      import {b} from './b'\n      export let a = () => b\n    `,\n    'b.ts': `\n      import {a} from './re-export'\n      export let b = () => a\n    `,\n  }),\n  test(['node.ts', '--bundle', '--format=cjs', '--outdir=.'], {\n    'node.ts': `\n      import {a} from './re-export'\n      let fn = a()\n      if (fn === a || fn() !== a) throw 'fail'\n\n      // Try forcing all of these modules to be wrappers\n      require('./node')\n      require('./re-export')\n      require('./a')\n      require('./b')\n    `,\n    're-export.ts': `\n      export * from './a'\n    `,\n    'a.ts': `\n      import {b} from './b'\n      export let a = () => b\n    `,\n    'b.ts': `\n      import {a} from './re-export'\n      export let b = () => a\n    `,\n  }),\n  test(['node.ts', 're-export.ts', 'a.ts', 'b.ts', '--format=cjs', '--outdir=.'], {\n    'node.ts': `\n      import {a} from './re-export'\n      let fn = a()\n      if (fn === a || fn() !== a) throw 'fail'\n    `,\n    're-export.ts': `\n      export * from './a'\n    `,\n    'a.ts': `\n      import {b} from './b'\n      export let a = () => b\n    `,\n    'b.ts': `\n      import {a} from './re-export'\n      export let b = () => a\n    `,\n  }),\n\n  // Failure case due to a bug in https://github.com/evanw/esbuild/pull/2059\n  test(['in.ts', '--bundle', '--format=cjs', '--outfile=out.js', '--external:*.cjs'], {\n    'in.ts': `\n      export * from './a.cjs'\n      import * as inner from './inner.js'\n      export { inner }\n    `,\n    'inner.ts': `export * from './b.cjs'`,\n    'a.cjs': `exports.a = 'a'`,\n    'b.cjs': `exports.b = 'b'`,\n    'node.js': `\n      const out = require('./out.js')\n      if (out.a !== 'a' || out.inner === void 0 || out.inner.b !== 'b' || out.b !== void 0) throw 'fail'\n    `,\n  }),\n\n  // Validate internal and external export correctness regarding \"__esModule\".\n  // An ES module importing itself should not see \"__esModule\". But a CommonJS\n  // module importing an ES module should see \"__esModule\".\n  test(['in.ts', '--bundle', '--format=cjs', '--outfile=out.js', '--external:*.cjs'], {\n    'in.ts': `\n      export * from './a.cjs'\n      import * as us from './in.js'\n      if (us.a !== 'a' || us.__esModule !== void 0) throw 'fail'\n    `,\n    'a.cjs': `exports.a = 'a'`,\n    'node.js': `\n      const out = require('./out.js')\n      if (out.a !== 'a' || out.__esModule !== true) throw 'fail'\n    `,\n  }),\n\n  // Use \"eval\" to access CommonJS variables\n  test(['--bundle', 'in.js', '--outfile=node.js'], {\n    'in.js': `if (require('./eval').foo !== 123) throw 'fail'`,\n    'eval.js': `eval('exports.foo = 123')`,\n  }),\n  test(['--bundle', 'in.js', '--outfile=node.js'], {\n    'in.js': `if (require('./eval').foo !== 123) throw 'fail'`,\n    'eval.js': `eval('module.exports = {foo: 123}')`,\n  }),\n)\n\n// Test internal ES6 export\nfor (const minify of [[], ['--minify']]) {\n  for (const target of ['es5', 'es6']) {\n    tests.push(\n      test(['--bundle', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        'in.js': `import * as out from './foo'; if (out.foo !== 123) throw 'fail'`,\n        'foo.js': `exports.foo = 123`,\n      }),\n      test(['--bundle', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        'in.js': `import * as out from './foo'; if (out.default !== 123) throw 'fail'`,\n        'foo.js': `module.exports = 123`,\n      }),\n      test(['--bundle', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        'in.js': `import * as out from './foo'; if (out.default !== null) throw 'fail'`,\n        'foo.js': `module.exports = null`,\n      }),\n      test(['--bundle', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        'in.js': `import * as out from './foo'; if (out.default !== void 0) throw 'fail'`,\n        'foo.js': `module.exports = void 0`,\n      }),\n      test(['--bundle', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        'in.js': `import * as out from './foo'; if (out.foo !== 123) throw 'fail'`,\n        'foo.js': `export var foo = 123`,\n      }),\n      test(['--bundle', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        'in.js': `import * as out from './foo'; if (out.default !== 123) throw 'fail'`,\n        'foo.js': `export default 123`,\n      }),\n\n      // Self export\n      test(['--bundle', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        // Exporting like this doesn't work, but that's ok\n        'in.js': `exports.foo = 123; import * as out from './in'; if (out.foo !== undefined) throw 'fail'`,\n      }),\n      test(['--bundle', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        // Exporting like this doesn't work, but that's ok\n        'in.js': `module.exports = {foo: 123}; import * as out from './in'; if (out.foo !== undefined) throw 'fail'`,\n      }),\n      test(['--bundle', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        'in.js': `export var foo = 123; import * as out from './in'; if (out.foo !== 123) throw 'fail'`,\n      }),\n      test(['--bundle', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        'in.js': `export default 123; import * as out from './in'; if (out.default !== 123) throw 'fail'`,\n      }),\n\n      // Check the value of \"this\"\n      test(['--bundle', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        'in.js': `import {foo} from './foo'; if (foo() !== (function() { return this })()) throw 'fail'`,\n        'foo.js': `export function foo() { return this }`,\n      }),\n      test(['--bundle', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        'in.js': `import foo from './foo'; if (foo() !== (function() { return this })()) throw 'fail'`,\n        'foo.js': `export default function() { return this }`,\n      }),\n      test(['--bundle', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        'in.js': `import {foo} from './foo'; require('./foo'); if (foo() !== (function() { return this })()) throw 'fail'`,\n        'foo.js': `export function foo() { return this }`,\n      }),\n      test(['--bundle', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        'in.js': `import foo from './foo'; require('./foo'); if (foo() !== (function() { return this })()) throw 'fail'`,\n        'foo.js': `export default function() { return this }`,\n      }),\n      test(['--bundle', '--external:./foo', '--format=cjs', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        'in.js': `import {foo} from './foo'; if (foo() !== (function() { return this })()) throw 'fail'`,\n        'foo.js': `exports.foo = function() { return this }`,\n      }),\n      test(['--bundle', '--external:./foo', '--format=cjs', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        'in.js': `import foo from './foo'; if (foo() !== (function() { return this })()) throw 'fail'`,\n        'foo.js': `module.exports = function() { return this }`,\n      }),\n\n      // https://github.com/evanw/esbuild/issues/4348\n      test(['--bundle', '--format=cjs', 'in.js', '--outfile=node.js', '--target=' + target].concat(minify), {\n        'in.js': `\n          var foo = Object.entries({ ...require('./foo') }).join('|')\n          if (foo !== 'a,a|b,b|c,c|d,d|e,e|f,f|g,g|h,h|i,i|j,j') throw 'fail: ' + foo\n        `,\n        'foo.js': `\n          var a = 'a'\n          for (var b = 'b'; 0; ) ;\n          if (true) { var c = 'c' }\n          if (true) var d = 'd'\n          if (false) {} else var e = 'e'\n          var x = 1\n          while (x--) var f = 'f'\n          do var g = 'g'; while (0);\n          for (; x++; ) var h = 'h'\n          for (var y in 'y') var i = 'i'\n          for (var y ${target === 'es5' ? 'in' : 'of'} 'y') var j = 'j'\n          export { a, b, c, d, e, f, g, h, i, j }\n        `,\n      }),\n    )\n  }\n\n  tests.push(\n    // Make sure entry points where a dependency has top-level await are awaited\n    test(['--bundle', 'in.js', '--outfile=out.js', '--format=esm'].concat(minify), {\n      'in.js': `import './foo'; import('./in.js'); throw 'fail'`,\n      'foo.js': `throw await 'stop'`,\n      'node.js': `export let async = async () => { try { await import('./out.js') } catch (e) { if (e === 'stop') return } throw 'fail' }`,\n    }, { async: true }),\n\n    // Self export\n    test(['--bundle', 'in.js', '--outfile=node.js', '--format=esm'].concat(minify), {\n      'in.js': `export default 123; export let async = async () => { const out = await import('./in'); if (out.default !== 123) throw 'fail' }`,\n    }, { async: true }),\n    test(['--bundle', 'in.js', '--outfile=node.js', '--format=esm'].concat(minify), {\n      'in.js': `export default 123; import * as out from './in'; export let async = async () => { await import('./in'); if (out.default !== 123) throw 'fail' }`,\n    }, { async: true }),\n\n    // Inject\n    test(['--bundle', 'node.ts', 'node2.ts', '--outdir=.', '--format=esm', '--inject:foo.js', '--splitting'].concat(minify), {\n      'node.ts': `if (foo.bar !== 123) throw 'fail'`,\n      'node2.ts': `throw [foo.bar, require('./node2.ts')] // Force this file to be lazily initialized so foo.js is lazily initialized`,\n      'foo.js': `export let foo = {bar: 123}`,\n    }),\n\n    // https://github.com/evanw/esbuild/issues/2793\n    test(['--bundle', 'src/index.js', '--outfile=node.js', '--format=esm'].concat(minify), {\n      'src/a.js': `\n        export const A = 42;\n      `,\n      'src/b.js': `\n        export const B = async () => (await import(\".\")).A\n      `,\n      'src/index.js': `\n        export * from \"./a\"\n        export * from \"./b\"\n        import { B } from '.'\n        export let async = async () => { if (42 !== await B()) throw 'fail' }\n      `,\n    }, { async: true }),\n    test(['--bundle', 'src/node.js', '--outdir=.', '--format=esm', '--splitting'].concat(minify), {\n      'src/a.js': `\n        export const A = 42;\n      `,\n      'src/b.js': `\n        export const B = async () => (await import(\"./node\")).A\n      `,\n      'src/node.js': `\n        export * from \"./a\"\n        export * from \"./b\"\n        import { B } from './node'\n        export let async = async () => { if (42 !== await B()) throw 'fail' }\n      `,\n    }, { async: true }),\n  )\n}\n\n// Check that duplicate top-level exports don't collide in the presence of \"eval\"\ntests.push(\n  test(['--bundle', '--format=esm', 'in.js', '--outfile=node.js'], {\n    'in.js': `\n      import a from './a'\n      if (a !== 'runner1.js') throw 'fail'\n      import b from './b'\n      if (b !== 'runner2.js') throw 'fail'\n    `,\n    'a.js': `\n      import { run } from './runner1'\n      export default run()\n    `,\n    'runner1.js': `\n      let data = eval('\"runner1\" + \".js\"')\n      export function run() { return data }\n    `,\n    'b.js': `\n      import { run } from './runner2'\n      export default run()\n    `,\n    'runner2.js': `\n      let data = eval('\"runner2\" + \".js\"')\n      export function run() { return data }\n    `,\n  }, {\n    // There are two possible output orders due to log output order non-determinism\n    expectedStderr: [\n      `▲ [WARNING] Using direct eval with a bundler is not recommended and may cause problems [direct-eval]\n\n    runner1.js:2:17:\n      2 │       let data = eval('\"runner1\" + \".js\"')\n        ╵                  ~~~~\n\n  You can read more about direct eval and bundling here: https://esbuild.github.io/link/direct-eval\n\n▲ [WARNING] Using direct eval with a bundler is not recommended and may cause problems [direct-eval]\n\n    runner2.js:2:17:\n      2 │       let data = eval('\"runner2\" + \".js\"')\n        ╵                  ~~~~\n\n  You can read more about direct eval and bundling here: https://esbuild.github.io/link/direct-eval\n\n`, `▲ [WARNING] Using direct eval with a bundler is not recommended and may cause problems [direct-eval]\n\n    runner2.js:2:17:\n      2 │       let data = eval('\"runner2\" + \".js\"')\n        ╵                  ~~~~\n\n  You can read more about direct eval and bundling here: https://esbuild.github.io/link/direct-eval\n\n▲ [WARNING] Using direct eval with a bundler is not recommended and may cause problems [direct-eval]\n\n    runner1.js:2:17:\n      2 │       let data = eval('\"runner1\" + \".js\"')\n        ╵                  ~~~~\n\n  You can read more about direct eval and bundling here: https://esbuild.github.io/link/direct-eval\n\n`,\n    ],\n  }),\n  test(['--bundle', '--format=esm', '--splitting', 'in.js', 'in2.js', '--outdir=out'], {\n    'in.js': `\n      import a from './a'\n      import b from './b'\n      export default [a, b]\n    `,\n    'a.js': `\n      import { run } from './runner1'\n      export default run()\n    `,\n    'runner1.js': `\n      let data = eval('\"runner1\" + \".js\"')\n      export function run() { return data }\n    `,\n    'b.js': `\n      import { run } from './runner2'\n      export default run()\n    `,\n    'runner2.js': `\n      let data = eval('\"runner2\" + \".js\"')\n      export function run() { return data }\n    `,\n    'in2.js': `\n      import { run } from './runner2'\n      export default run()\n    `,\n    'node.js': `\n      import ab from './out/in.js'\n      if (ab[0] !== 'runner1.js' || ab[1] !== 'runner2.js') throw 'fail'\n    `,\n  }, {\n    // There are two possible output orders due to log output order non-determinism\n    expectedStderr: [\n      `▲ [WARNING] Using direct eval with a bundler is not recommended and may cause problems [direct-eval]\n\n    runner1.js:2:17:\n      2 │       let data = eval('\"runner1\" + \".js\"')\n        ╵                  ~~~~\n\n  You can read more about direct eval and bundling here: https://esbuild.github.io/link/direct-eval\n\n▲ [WARNING] Using direct eval with a bundler is not recommended and may cause problems [direct-eval]\n\n    runner2.js:2:17:\n      2 │       let data = eval('\"runner2\" + \".js\"')\n        ╵                  ~~~~\n\n  You can read more about direct eval and bundling here: https://esbuild.github.io/link/direct-eval\n\n`, `▲ [WARNING] Using direct eval with a bundler is not recommended and may cause problems [direct-eval]\n\n    runner2.js:2:17:\n      2 │       let data = eval('\"runner2\" + \".js\"')\n        ╵                  ~~~~\n\n  You can read more about direct eval and bundling here: https://esbuild.github.io/link/direct-eval\n\n▲ [WARNING] Using direct eval with a bundler is not recommended and may cause problems [direct-eval]\n\n    runner1.js:2:17:\n      2 │       let data = eval('\"runner1\" + \".js\"')\n        ╵                  ~~~~\n\n  You can read more about direct eval and bundling here: https://esbuild.github.io/link/direct-eval\n\n`,\n    ],\n  }),\n)\n\n// Test \"default\" exports in ESM-to-CommonJS conversion scenarios\ntests.push(\n  test(['in.js', '--outfile=node.js', '--format=cjs'], {\n    'in.js': `import def from './foo'; if (def !== 123) throw 'fail'`,\n    'foo.js': `exports.__esModule = true; exports.default = 123`,\n  }),\n  test(['in.js', '--outfile=node.js', '--format=cjs'], {\n    'in.js': `import * as ns from './foo'; if (ns.default !== 123) throw 'fail'`,\n    'foo.js': `exports.__esModule = true; exports.default = 123`,\n  }),\n  test(['in.js', '--outfile=node.js', '--format=cjs'], {\n    'in.js': `import def from './foo'; if (def !== void 0) throw 'fail'`,\n    'foo.js': `exports.__esModule = true; exports.foo = 123`,\n  }),\n  test(['in.js', '--outfile=node.js', '--format=cjs'], {\n    'in.js': `import * as ns from './foo'; if (ns.default !== void 0 || ns.foo !== 123) throw 'fail'`,\n    'foo.js': `exports.__esModule = true; exports.foo = 123`,\n  }),\n  test(['in.js', '--outfile=node.js', '--format=cjs'], {\n    'in.js': `import def from './foo'; if (!def || def.foo !== 123) throw 'fail'`,\n    'foo.js': `exports.__esModule = false; exports.foo = 123`,\n  }),\n  test(['in.js', '--outfile=node.js', '--format=cjs'], {\n    'in.js': `import * as ns from './foo'; if (!ns.default || ns.default.foo !== 123) throw 'fail'`,\n    'foo.js': `exports.__esModule = false; exports.foo = 123`,\n  }),\n  test(['in.mjs', '--outfile=node.js', '--format=cjs'], {\n    'in.mjs': `import def from './foo'; if (!def || def.foo !== 123) throw 'fail'`,\n    'foo.js': `exports.__esModule = true; exports.foo = 123`,\n  }),\n  test(['in.mjs', '--outfile=node.js', '--format=cjs'], {\n    'in.mjs': `import * as ns from './foo'; if (!ns.default || ns.default.foo !== 123) throw 'fail'`,\n    'foo.js': `exports.__esModule = true; exports.foo = 123`,\n  }),\n\n  // Make sure \"import {} from; export {}\" behaves like \"export {} from\"\n  // https://github.com/evanw/esbuild/issues/1890\n  test(['node.ts', 'foo.ts', '--outdir=.', '--format=cjs'], {\n    'node.ts': `import * as foo from './foo.js'; if (foo.bar !== 123) throw 'fail'`,\n    'foo.ts': `import bar from './lib.js'; export { bar }`,\n    'lib.js': `module.exports = 123`,\n  }),\n  test(['node.ts', 'foo.ts', '--outdir=.', '--format=cjs'], {\n    'node.ts': `import * as foo from './foo.js'; if (foo.bar !== 123) throw 'fail'`,\n    'foo.ts': `import { default as bar } from './lib.js'; export { bar }`,\n    'lib.js': `module.exports = 123`,\n  }),\n  test(['node.ts', 'foo.ts', '--outdir=.', '--format=cjs'], {\n    'node.ts': `import * as foo from './foo.js'; if (foo.bar !== 123) throw 'fail'`,\n    'foo.ts': `export { default as bar } from './lib.js'`,\n    'lib.js': `module.exports = 123`,\n  }),\n  test(['node.ts', 'foo.ts', '--outdir=.', '--format=cjs'], {\n    'node.ts': `import { foo } from './foo.js'; if (foo.default !== 123) throw 'fail'`,\n    'foo.ts': `import * as foo from './lib.js'; export { foo }`,\n    'lib.js': `module.exports = 123`,\n  }),\n  test(['node.ts', 'foo.ts', '--outdir=.', '--format=cjs'], {\n    'node.ts': `import { foo } from './foo.js'; if (foo.default !== 123) throw 'fail'`,\n    'foo.ts': `export * as foo from './lib.js'`,\n    'lib.js': `module.exports = 123`,\n  }),\n  test(['node.ts', 'foo.ts', '--outdir=.', '--format=cjs'], {\n    'node.ts': `import * as foo from './foo.js'; if (foo.default !== void 0) throw 'fail'`,\n    'foo.ts': `export * from './lib.js'`,\n    'lib.js': `module.exports = 123`,\n  }),\n)\n\n// Test external wildcards\ntests.push(\n  test(['--bundle', 'src/foo.js', '--outfile=node.js', '--external:./src/dir/*', '--format=cjs'], {\n    'src/foo.js': `\n      function foo() {\n        require('./dir/bar')\n      }\n      let worked = false\n      try {\n        foo()\n        worked = true\n      } catch (e) {\n      }\n      if (worked) throw 'fail'\n    `,\n  }),\n  test(['--bundle', 'src/foo.js', '--outfile=node.js', '--external:./src/dir/*', '--format=cjs'], {\n    'src/foo.js': `\n      require('./dir/bar')\n    `,\n    'src/dir/bar.js': ``,\n  }),\n)\n\n// Test external CommonJS export\ntests.push(\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=cjs'], {\n    'foo.js': `exports.foo = 123`,\n    'node.js': `const out = require('./out'); if (out.__esModule || out.foo !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=cjs'], {\n    'foo.js': `module.exports = 123`,\n    'node.js': `const out = require('./out'); if (out.__esModule || out !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=esm'], {\n    'foo.js': `exports.foo = 123`,\n    'node.js': `import out from './out.js'; if (out.foo !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=esm'], {\n    'foo.js': `module.exports = 123`,\n    'node.js': `import out from './out.js'; if (out !== 123) throw 'fail'`,\n  }),\n)\n\n// Test external ES6 export\ntests.push(\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=cjs', '--platform=node'], {\n    'foo.js': `export const foo = 123`,\n    'node.js': `const out = require('./out'); if (!out.__esModule || out.foo !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=cjs', '--platform=node'], {\n    'foo.js': `export default 123`,\n    'node.js': `const out = require('./out'); if (!out.__esModule || out.default !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=cjs', '--platform=node'], {\n    'foo.js': `const something = 123; export { something as 'some name' }`,\n    'node.js': `const out = require('./out'); if (!out.__esModule || out['some name'] !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=esm'], {\n    'foo.js': `export const foo = 123`,\n    'node.js': `import {foo} from './out.js'; if (foo !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=esm'], {\n    'foo.js': `export default 123`,\n    'node.js': `import out from './out.js'; if (out !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=esm'], {\n    'foo.js': `const something = 123; export { something as 'some name' }`,\n    'node.js': `import { 'some name' as out } from './out.js'; if (out !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=cjs', '--platform=node'], {\n    'foo.js': `\n      export function confuseNode(exports) {\n        // If this local is called \"exports\", node incorrectly\n        // thinks this file has an export called \"notAnExport\".\n        // We must make sure that it doesn't have that name\n        // when targeting Node with CommonJS. See also:\n        // https://github.com/evanw/esbuild/issues/3544\n        exports.notAnExport = function() {\n        };\n      }\n    `,\n    'node.js': `\n      exports.async = async () => {\n        const foo = await import('./out.js')\n        if (typeof foo.confuseNode !== 'function') throw 'fail: confuseNode'\n        if ('notAnExport' in foo) throw 'fail: notAnExport'\n      }\n    `,\n  }, { async: true }),\n\n  // External package\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=cjs', '--external:fs'], {\n    'foo.js': `import {exists} from \"fs\"; export {exists}`,\n    'node.js': `const out = require('./out'); if (!out.__esModule || out.exists !== require('fs').exists) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=esm', '--external:fs'], {\n    'foo.js': `import {exists} from \"fs\"; export {exists}`,\n    'node.js': `import {exists} from \"./out.js\"; import * as fs from \"fs\"; if (exists !== fs.exists) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=cjs', '--external:fs'], {\n    'foo.js': `import * as fs from \"fs\"; export let exists = fs.exists`,\n    'node.js': `const out = require('./out'); if (!out.__esModule || out.exists !== require('fs').exists) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=esm', '--external:fs'], {\n    'foo.js': `import * as fs from \"fs\"; export let exists = fs.exists`,\n    'node.js': `import {exists} from \"./out.js\"; import * as fs from \"fs\"; if (exists !== fs.exists) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=cjs', '--external:fs'], {\n    'foo.js': `export {exists} from \"fs\"`,\n    'node.js': `const out = require('./out'); if (!out.__esModule || out.exists !== require('fs').exists) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=esm', '--external:fs'], {\n    'foo.js': `export {exists} from \"fs\"`,\n    'node.js': `import {exists} from \"./out.js\"; import * as fs from \"fs\"; if (exists !== fs.exists) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=cjs', '--external:fs'], {\n    'foo.js': `export * from \"fs\"`,\n    'node.js': `const out = require('./out'); if (!out.__esModule || out.exists !== require('fs').exists) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=esm', '--external:fs'], {\n    'foo.js': `export * from \"fs\"`,\n    'node.js': `import {exists} from \"./out.js\"; import * as fs from \"fs\"; if (exists !== fs.exists) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=cjs', '--external:fs'], {\n    'foo.js': `export * as star from \"fs\"`,\n    'node.js': `const out = require('./out'); if (!out.__esModule || out.star.exists !== require('fs').exists) throw 'fail'`,\n  }),\n  test(['--bundle', 'foo.js', '--outfile=out.js', '--format=esm', '--external:fs'], {\n    'foo.js': `export * as star from \"fs\"`,\n    'node.js': `import {star} from \"./out.js\"; import * as fs from \"fs\"; if (star.exists !== fs.exists) throw 'fail'`,\n  }),\n)\n\n// ES6 export star of CommonJS module\ntests.push(\n  // Internal\n  test(['--bundle', 'entry.js', '--outfile=node.js'], {\n    'entry.js': `import * as ns from './re-export'; if (ns.foo !== 123) throw 'fail'`,\n    're-export.js': `export * from './commonjs'`,\n    'commonjs.js': `exports.foo = 123`,\n  }),\n  test(['--bundle', 'entry.js', '--outfile=node.js'], {\n    'entry.js': `import {foo} from './re-export'; if (foo !== 123) throw 'fail'`,\n    're-export.js': `export * from './commonjs'`,\n    'commonjs.js': `exports.foo = 123`,\n  }),\n\n  // External\n  test(['--bundle', 'entry.js', '--outfile=node.js', '--external:fs'], {\n    'entry.js': `import * as ns from './re-export'; if (typeof ns.exists !== 'function') throw 'fail'`,\n    're-export.js': `export * from 'fs'`,\n  }),\n  test(['--bundle', 'entry.js', '--outfile=node.js', '--external:fs'], {\n    'entry.js': `import {exists} from './re-export'; if (typeof exists !== 'function') throw 'fail'`,\n    're-export.js': `export * from 'fs'`,\n  }),\n\n  // External (masked)\n  test(['--bundle', 'entry.js', '--outfile=node.js', '--external:fs'], {\n    'entry.js': `import * as ns from './re-export'; if (ns.exists !== 123) throw 'fail'`,\n    're-export.js': `export * from 'fs'; export let exists = 123`,\n  }),\n  test(['--bundle', 'entry.js', '--outfile=node.js', '--external:fs'], {\n    'entry.js': `import {exists} from './re-export'; if (exists !== 123) throw 'fail'`,\n    're-export.js': `export * from 'fs'; export let exists = 123`,\n  }),\n\n  // Export CommonJS export from ES6 module\n  test(['--bundle', 'entry.js', '--outfile=out.js', '--format=cjs'], {\n    'entry.js': `export {bar} from './foo'`,\n    'foo.js': `exports.bar = 123`,\n    'node.js': `const out = require('./out.js'); if (out.bar !== 123) throw 'fail'`,\n  }),\n  test(['--bundle', 'entry.js', '--outfile=out.js', '--format=esm'], {\n    'entry.js': `export {bar} from './foo'`,\n    'foo.js': `exports.bar = 123`,\n    'node.js': `import {bar} from './out.js'; if (bar !== 123) throw 'fail'`,\n  }),\n)\n\n// Test imports from modules without any imports\ntests.push(\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import * as ns from 'pkg'\n      if (ns.default === void 0) throw 'fail'\n    `,\n    'node_modules/pkg/index.js': ``,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import * as ns from 'pkg/index.cjs'\n      if (ns.default === void 0) throw 'fail'\n    `,\n    'node_modules/pkg/index.cjs': ``,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import * as ns from 'pkg/index.cts'\n      if (ns.default === void 0) throw 'fail'\n    `,\n    'node_modules/pkg/index.cts': ``,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import * as ns from 'pkg/index.mjs'\n      if (ns.default !== void 0) throw 'fail'\n    `,\n    'node_modules/pkg/index.mjs': ``,\n  }, {\n    expectedStderr: `▲ [WARNING] Import \"default\" will always be undefined because there is no matching export in \"node_modules/pkg/index.mjs\" [import-is-undefined]\n\n    in.js:3:13:\n      3 │       if (ns.default !== void 0) throw 'fail'\n        ╵              ~~~~~~~\n\n`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import * as ns from 'pkg/index.mts'\n      if (ns.default !== void 0) throw 'fail'\n    `,\n    'node_modules/pkg/index.mts': ``,\n  }, {\n    expectedStderr: `▲ [WARNING] Import \"default\" will always be undefined because there is no matching export in \"node_modules/pkg/index.mts\" [import-is-undefined]\n\n    in.js:3:13:\n      3 │       if (ns.default !== void 0) throw 'fail'\n        ╵              ~~~~~~~\n\n`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import * as ns from 'pkg'\n      if (ns.default === void 0) throw 'fail'\n    `,\n    'node_modules/pkg/package.json': `{\n      \"type\": \"commonjs\"\n    }`,\n    'node_modules/pkg/index.js': ``,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import * as ns from 'pkg'\n      if (ns.default !== void 0) throw 'fail'\n    `,\n    'node_modules/pkg/package.json': `{\n      \"type\": \"module\"\n    }`,\n    'node_modules/pkg/index.js': ``,\n  }, {\n    expectedStderr: `▲ [WARNING] Import \"default\" will always be undefined because there is no matching export in \"node_modules/pkg/index.js\" [import-is-undefined]\n\n    in.js:3:13:\n      3 │       if (ns.default !== void 0) throw 'fail'\n        ╵              ~~~~~~~\n\n`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle', '--external:pkg'], {\n    'in.js': `\n      import * as ns from 'pkg'\n      if (ns.default === void 0) throw 'fail'\n    `,\n    'node_modules/pkg/index.js': ``,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle', '--external:pkg'], {\n    'in.js': `\n      import * as ns from 'pkg'\n      if (ns.foo !== void 0) throw 'fail'\n    `,\n    'node_modules/pkg/index.js': ``,\n  }),\n)\n\n// Test imports not being able to access the namespace object\ntests.push(\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import {foo} from './esm'\n      if (foo !== 123) throw 'fail'\n    `,\n    'esm.js': `Object.defineProperty(exports, 'foo', {value: 123, enumerable: false})`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import * as ns from './esm'\n      if (ns[Math.random() < 2 && 'foo'] !== 123) throw 'fail'\n    `,\n    'esm.js': `Object.defineProperty(exports, 'foo', {value: 123, enumerable: false})`,\n  }),\n)\n\n// Test imports of properties from the prototype chain of \"module.exports\" for Webpack compatibility\ntests.push(\n  // Imports\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import def from './cjs-proto'\n      import {prop} from './cjs-proto'\n      if (def.prop !== 123 || prop !== 123) throw 'fail'\n    `,\n    'cjs-proto.js': `module.exports = Object.create({prop: 123})`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import def, {prop} from './cjs-proto' // The TypeScript compiler fails with this syntax\n      if (def.prop !== 123 || prop !== 123) throw 'fail'\n    `,\n    'cjs-proto.js': `module.exports = Object.create({prop: 123})`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import * as star from './cjs-proto'\n      if (!star.default || star.default.prop !== 123 || star.prop !== 123) throw 'fail'\n    `,\n    'cjs-proto.js': `module.exports = Object.create({prop: 123})`,\n  }),\n\n  // Re-exports\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import * as test from './reexport'\n      if (test.def.prop !== 123 || test.prop !== 123) throw 'fail'\n    `,\n    'reexport.js': `\n      export {default as def} from './cjs-proto'\n      export {prop} from './cjs-proto'\n    `,\n    'cjs-proto.js': `module.exports = Object.create({prop: 123})`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import * as test from './reexport'\n      if (test.def.prop !== 123 || test.prop !== 123) throw 'fail'\n    `,\n    'reexport.js': `\n      export {default as def, prop} from './cjs-proto' // The TypeScript compiler fails with this syntax\n    `,\n    'cjs-proto.js': `module.exports = Object.create({prop: 123})`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import * as test from './reexport'\n      // Note: the specification says to ignore default exports in \"export * from\"\n      // Note: re-exporting prototype properties using \"export * from\" is not supported\n      if (test.default || test.prop !== void 0) throw 'fail'\n    `,\n    'reexport.js': `\n      export * from './cjs-proto'\n    `,\n    'cjs-proto.js': `module.exports = Object.create({prop: 123})`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import {star} from './reexport'\n      if (!star.default || star.default.prop !== 123 || star.prop !== 123) throw 'fail'\n    `,\n    'reexport.js': `\n      export * as star from './cjs-proto'\n    `,\n    'cjs-proto.js': `module.exports = Object.create({prop: 123})`,\n  }),\n)\n\n// Test for format conversion without bundling\ntests.push(\n  // ESM => ESM\n  test(['in.js', '--outfile=node.js', '--format=esm'], {\n    'in.js': `\n      import {exists} from 'fs'\n      if (!exists) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--format=esm'], {\n    'in.js': `\n      import fs from 'fs'\n      if (!fs.exists) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--format=esm'], {\n    'in.js': `\n      import * as fs from 'fs'\n      if (!fs.exists) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--format=esm'], {\n    'in.js': `\n      let fn = async () => {\n        let fs = await import('fs')\n        if (!fs.exists) throw 'fail'\n      }\n      export {fn as async}\n    `,\n  }, { async: true }),\n  test(['in.js', '--outfile=out.js', '--format=esm'], {\n    'in.js': `\n      export let foo = 'abc'\n      export default function() {\n        return 123\n      }\n    `,\n    'node.js': `\n      import * as out from './out.js'\n      if (out.foo !== 'abc' || out.default() !== 123) throw 'fail'\n    `,\n  }),\n\n  // ESM => CJS\n  test(['in.js', '--outfile=node.js', '--format=cjs'], {\n    'in.js': `\n      import {exists} from 'fs'\n      if (!exists) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--format=cjs'], {\n    'in.js': `\n      import fs from 'fs'\n      if (!fs.exists) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--format=cjs'], {\n    'in.js': `\n      import * as fs from 'fs'\n      if (!fs.exists) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--format=cjs'], {\n    'in.js': `\n      let fn = async () => {\n        let fs = await import('fs')\n        if (!fs.exists) throw 'fail'\n      }\n      export {fn as async}\n    `,\n  }, { async: true }),\n  test(['in.js', '--outfile=out.js', '--format=cjs'], {\n    'in.js': `\n      export let foo = 'abc'\n      export default function() {\n        return 123\n      }\n    `,\n    'node.js': `\n      const out = require('./out.js')\n      if (out.foo !== 'abc' || out.default() !== 123) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=out.cjs', '--format=cjs', '--platform=node'], {\n    'in.js': `\n      export let foo = 123\n      let bar = 234\n      export { bar as if }\n      export default 345\n    `,\n    'node.js': `\n      exports.async = async () => {\n        let out = await import('./out.cjs')\n        let keys = Object.keys(out)\n        if (\n          !keys.includes('default') || !keys.includes('foo') || !keys.includes('if') ||\n          out.foo !== 123 || out.if !== 234 ||\n          out.default.foo !== 123 || out.default.if !== 234 || out.default.default !== 345\n        ) throw 'fail'\n      }\n    `,\n  }, { async: true }),\n\n  // https://github.com/evanw/esbuild/issues/3029\n  test([\n    'node_modules/util-ex/src/index.js',\n    'node_modules/util-ex/src/fn1.js',\n    'node_modules/util-ex/src/fn2.js',\n    '--outdir=node_modules/util-ex/lib',\n    '--format=cjs',\n    '--platform=node',\n  ], {\n    'node_modules/util-ex/src/index.js': `\n      export * from './fn1'\n      export * from './fn2'\n    `,\n    'node_modules/util-ex/src/fn1.js': `\n      export function fn1() { return 1 }\n      export default fn1\n    `,\n    'node_modules/util-ex/src/fn2.js': `\n      export function fn2() { return 2 }\n      export default fn2\n    `,\n    'node_modules/util-ex/package.json': `{\n      \"main\": \"./lib/index.js\",\n      \"type\": \"commonjs\"\n    }`,\n    'node.js': `\n      import { fn1, fn2 } from 'util-ex'\n      if (fn1() !== 1) throw 'fail 1'\n      if (fn2() !== 2) throw 'fail 2'\n    `,\n    'package.json': `{\n      \"type\": \"module\"\n    }`,\n  }),\n\n  // ESM => IIFE\n  test(['in.js', '--outfile=node.js', '--format=iife'], {\n    'in.js': `\n      import {exists} from 'fs'\n      if (!exists) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--format=iife'], {\n    'in.js': `\n      import fs from 'fs'\n      if (!fs.exists) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--format=iife'], {\n    'in.js': `\n      import * as fs from 'fs'\n      if (!fs.exists) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=out.js', '--format=iife', '--global-name=test'], {\n    'in.js': `\n      let fn = async () => {\n        let fs = await import('fs')\n        if (!fs.exists) throw 'fail'\n      }\n      export {fn as async}\n    `,\n    'node.js': `\n      const code = require('fs').readFileSync(__dirname + '/out.js', 'utf8')\n      const out = new Function('require', code + '; return test')(require)\n      exports.async = out.async\n    `,\n  }, { async: true }),\n  test(['in.js', '--outfile=out.js', '--format=iife', '--global-name=test'], {\n    'in.js': `\n      export let foo = 'abc'\n      export default function() {\n        return 123\n      }\n    `,\n    'node.js': `\n      const code = require('fs').readFileSync(__dirname + '/out.js', 'utf8')\n      const out = new Function(code + '; return test')()\n      if (out.foo !== 'abc' || out.default() !== 123) throw 'fail'\n    `,\n  }),\n\n  // JSON\n  test(['in.json', '--outfile=out.js', '--format=esm'], {\n    'in.json': `{\"foo\": 123}`,\n    'node.js': `\n      import def from './out.js'\n      import {foo} from './out.js'\n      if (foo !== 123 || def.foo !== 123) throw 'fail'\n    `,\n  }),\n  test(['in.json', '--outfile=out.js', '--format=cjs'], {\n    'in.json': `{\"foo\": 123}`,\n    'node.js': `\n      const out = require('./out.js')\n      if (out.foo !== 123) throw 'fail'\n    `,\n  }),\n  test(['in.json', '--outfile=out.js', '--format=iife', '--global-name=test'], {\n    'in.json': `{\"foo\": 123}`,\n    'node.js': `\n      const code = require('fs').readFileSync(__dirname + '/out.js', 'utf8')\n      const out = new Function(code + '; return test')()\n      if (out.foo !== 123) throw 'fail'\n    `,\n  }),\n\n  // CJS => CJS\n  test(['in.js', '--outfile=node.js', '--format=cjs'], {\n    'in.js': `\n      const {exists} = require('fs')\n      if (!exists) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--format=cjs'], {\n    'in.js': `\n      const fs = require('fs')\n      if (!fs.exists) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=out.js', '--format=cjs'], {\n    'in.js': `\n      module.exports = 123\n    `,\n    'node.js': `\n      const out = require('./out.js')\n      if (out !== 123) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=out.js', '--format=cjs'], {\n    'in.js': `\n      exports.foo = 123\n    `,\n    'node.js': `\n      const out = require('./out.js')\n      if (out.foo !== 123) throw 'fail'\n    `,\n  }),\n\n  // CJS => IIFE\n  test(['in.js', '--outfile=out.js', '--format=iife'], {\n    'in.js': `\n      const {exists} = require('fs')\n      if (!exists) throw 'fail'\n    `,\n    'node.js': `\n      const code = require('fs').readFileSync(__dirname + '/out.js', 'utf8')\n      new Function('require', code)(require)\n    `,\n  }),\n  test(['in.js', '--outfile=out.js', '--format=iife'], {\n    'in.js': `\n      const fs = require('fs')\n      if (!fs.exists) throw 'fail'\n    `,\n    'node.js': `\n      const code = require('fs').readFileSync(__dirname + '/out.js', 'utf8')\n      new Function('require', code)(require)\n    `,\n  }),\n  test(['in.js', '--outfile=out.js', '--format=iife', '--global-name=test'], {\n    'in.js': `\n      module.exports = 123\n    `,\n    'node.js': `\n      const code = require('fs').readFileSync(__dirname + '/out.js', 'utf8')\n      const out = new Function(code + '; return test')()\n      if (out !== 123) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=out.js', '--format=iife', '--global-name=test'], {\n    'in.js': `\n      exports.foo = 123\n    `,\n    'node.js': `\n      const code = require('fs').readFileSync(__dirname + '/out.js', 'utf8')\n      const out = new Function(code + '; return test')()\n      if (out.foo !== 123) throw 'fail'\n    `,\n  }),\n\n  // CJS => ESM\n  test(['in.js', '--outfile=out.js', '--format=esm'], {\n    'in.js': `\n      const {exists} = require('fs')\n      if (!exists) throw 'fail'\n    `,\n    'node.js': `\n      let fn = async () => {\n        let error\n        await import('./out.js').catch(x => error = x)\n        if (!error || !error.message.includes('require is not defined')) throw 'fail'\n      }\n      export {fn as async}\n    `,\n  }, {\n    async: true,\n    expectedStderr: `▲ [WARNING] Converting \"require\" to \"esm\" is currently not supported [unsupported-require-call]\n\n    in.js:2:23:\n      2 │       const {exists} = require('fs')\n        ╵                        ~~~~~~~\n\n`,\n  }),\n  test(['in.js', '--outfile=out.js', '--format=esm'], {\n    'in.js': `\n      const fs = require('fs')\n      if (!fs.exists) throw 'fail'\n    `,\n    'node.js': `\n      let fn = async () => {\n        let error\n        await import('./out.js').catch(x => error = x)\n        if (!error || !error.message.includes('require is not defined')) throw 'fail'\n      }\n      export {fn as async}\n    `,\n  }, {\n    async: true,\n    expectedStderr: `▲ [WARNING] Converting \"require\" to \"esm\" is currently not supported [unsupported-require-call]\n\n    in.js:2:17:\n      2 │       const fs = require('fs')\n        ╵                  ~~~~~~~\n\n`,\n  }),\n  test(['in.js', '--outfile=out.js', '--format=esm'], {\n    'in.js': `\n      module.exports = 123\n    `,\n    'node.js': `\n      import out from './out.js'\n      if (out !== 123) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=out.js', '--format=esm'], {\n    'in.js': `\n      exports.foo = 123\n    `,\n    'node.js': `\n      import out from './out.js'\n      if (out.foo !== 123) throw 'fail'\n    `,\n  }),\n)\n\n// This shouldn't cause a syntax error\n// https://github.com/evanw/esbuild/issues/1082\ntests.push(\n  test(['in.js', '--outfile=node.js', '--minify', '--bundle'], {\n    'in.js': `\n      return import('./in.js')\n    `,\n  }),\n)\n\n// Check for file names of wrapped modules in non-minified stack traces (for profiling)\n// Context: https://github.com/evanw/esbuild/pull/1236\ntests.push(\n  test(['entry.js', '--outfile=node.js', '--bundle'], {\n    'entry.js': `\n      try {\n        require('./src/a')\n      } catch (e) {\n        if (!e.stack.includes('at __require') || !e.stack.includes('at src/a.ts') || !e.stack.includes('at src/b.ts'))\n          throw new Error(e.stack)\n      }\n    `,\n    'src/a.ts': `require('./b')`,\n    'src/b.ts': `throw new Error('fail')`,\n  }),\n  test(['entry.js', '--outfile=node.js', '--bundle', '--minify-identifiers'], {\n    'entry.js': `\n      try {\n        require('./src/a')\n      } catch (e) {\n        if (e.stack.includes('at __require') || e.stack.includes('at src/a.ts') || e.stack.includes('at src/b.ts'))\n          throw new Error(e.stack)\n      }\n    `,\n    'src/a.ts': `require('./b')`,\n    'src/b.ts': `throw new Error('fail')`,\n  }),\n  test(['entry.js', '--outfile=node.js', '--bundle'], {\n    'entry.js': `\n      try {\n        require('./src/a')\n      } catch (e) {\n        if (!e.stack.includes('at __init') || !e.stack.includes('at src/a.ts') || !e.stack.includes('at src/b.ts'))\n          throw new Error(e.stack)\n      }\n    `,\n    'src/a.ts': `export let esm = true; require('./b')`,\n    'src/b.ts': `export let esm = true; throw new Error('fail')`,\n  }),\n  test(['entry.js', '--outfile=node.js', '--bundle', '--minify-identifiers'], {\n    'entry.js': `\n      try {\n        require('./src/a')\n      } catch (e) {\n        if (e.stack.includes('at __init') || e.stack.includes('at src/a.ts') || e.stack.includes('at src/b.ts'))\n          throw new Error(e.stack)\n      }\n    `,\n    'src/a.ts': `export let esm = true; require('./b')`,\n    'src/b.ts': `export let esm = true; throw new Error('fail')`,\n  }),\n)\n\n// This shouldn't crash\n// https://github.com/evanw/esbuild/issues/1080\ntests.push(\n  // Various CommonJS cases\n  test(['in.js', '--outfile=node.js', '--define:foo={\"x\":0}', '--bundle'], {\n    'in.js': `if (foo.x !== 0) throw 'fail'; return`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:foo.bar={\"x\":0}', '--bundle'], {\n    'in.js': `if (foo.bar.x !== 0) throw 'fail'; return`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:module={\"x\":0}', '--bundle'], {\n    'in.js': `if (module.x !== void 0) throw 'fail'; return`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:module.foo={\"x\":0}', '--bundle'], {\n    'in.js': `if (module.foo !== void 0) throw 'fail'; return`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:exports={\"x\":0}', '--bundle'], {\n    'in.js': `if (exports.x !== void 0) throw 'fail'; return`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:exports.foo={\"x\":0}', '--bundle'], {\n    'in.js': `if (exports.foo !== void 0) throw 'fail'; return`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:foo=[\"x\"]', '--bundle'], {\n    'in.js': `if (foo[0] !== 'x') throw 'fail'; return`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:foo.bar=[\"x\"]', '--bundle'], {\n    'in.js': `if (foo.bar[0] !== 'x') throw 'fail'; return`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:module=[\"x\"]', '--bundle'], {\n    'in.js': `if (module[0] !== void 0) throw 'fail'; return`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:module.foo=[\"x\"]', '--bundle'], {\n    'in.js': `if (module.foo !== void 0) throw 'fail'; return`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:exports=[\"x\"]', '--bundle'], {\n    'in.js': `if (exports[0] !== void 0) throw 'fail'; return`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:exports.foo=[\"x\"]', '--bundle'], {\n    'in.js': `if (exports.foo !== void 0) throw 'fail'; return`,\n  }),\n\n  // Various ESM cases\n  test(['in.js', '--outfile=node.js', '--bundle', '--log-level=error'], {\n    'in.js': `import \"pkg\"`,\n    'node_modules/pkg/package.json': `{ \"sideEffects\": false }`,\n    'node_modules/pkg/index.js': `module.exports = null; throw 'fail'`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:foo={\"x\":0}', '--bundle'], {\n    'in.js': `if (foo.x !== 0) throw 'fail'; export {}`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:foo.bar={\"x\":0}', '--bundle'], {\n    'in.js': `if (foo.bar.x !== 0) throw 'fail'; export {}`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:module={\"x\":0}', '--bundle'], {\n    'in.js': `if (module.x !== 0) throw 'fail'; export {}`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:module.foo={\"x\":0}', '--bundle'], {\n    'in.js': `if (module.foo.x !== 0) throw 'fail'; export {}`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:exports={\"x\":0}', '--bundle'], {\n    'in.js': `if (exports.x !== 0) throw 'fail'; export {}`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:exports.foo={\"x\":0}', '--bundle'], {\n    'in.js': `if (exports.foo.x !== 0) throw 'fail'; export {}`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:foo=[\"x\"]', '--bundle'], {\n    'in.js': `if (foo[0] !== 'x') throw 'fail'; export {}`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:foo.bar=[\"x\"]', '--bundle'], {\n    'in.js': `if (foo.bar[0] !== 'x') throw 'fail'; export {}`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:module=[\"x\"]', '--bundle'], {\n    'in.js': `if (module[0] !== 'x') throw 'fail'; export {}`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:module.foo=[\"x\"]', '--bundle'], {\n    'in.js': `if (module.foo[0] !== 'x') throw 'fail'; export {}`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:exports=[\"x\"]', '--bundle'], {\n    'in.js': `if (exports[0] !== 'x') throw 'fail'; export {}`,\n  }),\n  test(['in.js', '--outfile=node.js', '--define:exports.foo=[\"x\"]', '--bundle'], {\n    'in.js': `if (exports.foo[0] !== 'x') throw 'fail'; export {}`,\n  }),\n)\n\n// Check for \"sideEffects: false\" wrapper handling\n// https://github.com/evanw/esbuild/issues/1088\nfor (const pkgJSON of [`{}`, `{\"sideEffects\": false}`]) {\n  for (const entry of [\n    `export let async = async () => { if (require(\"pkg\").foo() !== 123) throw 'fail' }`,\n    `export let async = () => import(\"pkg\").then(x => { if (x.foo() !== 123) throw 'fail' })`,\n  ]) {\n    for (const index of [`export {foo} from \"./foo.js\"`, `import {foo} from \"./foo.js\"; export {foo}`]) {\n      for (const foo of [`export let foo = () => 123`, `exports.foo = () => 123`]) {\n        tests.push(test(['in.js', '--outfile=node.js', '--bundle'], {\n          'in.js': entry,\n          'node_modules/pkg/package.json': pkgJSON,\n          'node_modules/pkg/index.js': index,\n          'node_modules/pkg/foo.js': foo,\n        }, { async: true }))\n      }\n    }\n  }\n  for (const entry of [\n    `export let async = async () => { try { require(\"pkg\") } catch (e) { return } throw 'fail' }`,\n    `export let async = () => import(\"pkg\").then(x => { throw 'fail' }, () => {})`,\n  ]) {\n    tests.push(test(['in.js', '--outfile=node.js', '--bundle'], {\n      'in.js': entry,\n      'node_modules/pkg/package.json': pkgJSON,\n      'node_modules/pkg/index.js': `\n        export {foo} from './b.js'\n      `,\n      'node_modules/pkg/b.js': `\n        export {foo} from './c.js'\n        throw 'stop'\n      `,\n      'node_modules/pkg/c.js': `\n        export let foo = () => 123\n      `,\n    }, { async: true }))\n  }\n}\n\n// Tests for \"arguments\" scope issues\ntests.push(\n  test(['in.js', '--outfile=node.js', '--minify'], {\n    'in.js': `\n      function arguments() {\n        return arguments.length\n      }\n      if (arguments(0, 1) !== 2) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify'], {\n    'in.js': `\n      let value = (function arguments() {\n        return arguments.length\n      })(0, 1)\n      if (value !== 2) throw 'fail'\n    `,\n  }),\n)\n\n// Tests for catch scope issues\ntests.push(\n  test(['in.js', '--outfile=node.js', '--minify'], {\n    'in.js': `\n      var x = 0, y = []\n      try {\n        throw 1\n      } catch (x) {\n        y.push(x)\n        var x = 2\n        y.push(x)\n      }\n      y.push(x)\n      if (y + '' !== '1,2,0') throw 'fail: ' + y\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify'], {\n    'in.js': `\n      var x = 0, y = []\n      try {\n        throw 1\n      } catch (x) {\n        y.push(x)\n        var x = 2\n        y.push(x)\n      }\n      finally { x = 3 }\n      y.push(x)\n      if (y + '' !== '1,2,3') throw 'fail: ' + y\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify'], {\n    'in.js': `\n      var y = []\n      try {\n        throw 1\n      } catch (x) {\n        y.push(x)\n        var x = 2\n        y.push(x)\n      }\n      y.push(x)\n      if (y + '' !== '1,2,') throw 'fail: ' + y\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify'], {\n    'in.js': `\n      var y = []\n      try {\n        throw 1\n      } catch (x) {\n        y.push(x)\n        x = 2\n        y.push(x)\n      }\n      y.push(typeof x)\n      if (y + '' !== '1,2,undefined') throw 'fail: ' + y\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify'], {\n    'in.js': `\n      var y = []\n      try {\n        throw 1\n      } catch (x) {\n        y.push(x)\n        try {\n          throw 2\n        } catch (x) {\n          y.push(x)\n          var x = 3\n          y.push(x)\n        }\n        y.push(x)\n      }\n      y.push(x)\n      if (y + '' !== '1,2,3,1,') throw 'fail: ' + y\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify'], {\n    'in.js': `\n      var y = []\n      try { x; y.push('fail') } catch (e) {}\n      try {\n        throw 1\n      } catch (x) {\n        y.push(x)\n      }\n      try { x; y.push('fail') } catch (e) {}\n      if (y + '' !== '1') throw 'fail: ' + y\n    `,\n  }),\n\n  // https://github.com/evanw/esbuild/issues/1812\n  test(['in.js', '--outfile=node.js'], {\n    'in.js': `\n      let a = 1;\n      let def = \"PASS2\";\n      try {\n        throw [ \"FAIL2\", \"PASS1\" ];\n      } catch ({ [a]: b, 3: d = def }) {\n        let a = 0, def = \"FAIL3\";\n        if (b !== 'PASS1' || d !== 'PASS2') throw 'fail: ' + b + ' ' + d\n      }\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      let a = 1;\n      let def = \"PASS2\";\n      try {\n        throw [ \"FAIL2\", \"PASS1\" ];\n      } catch ({ [a]: b, 3: d = def }) {\n        let a = 0, def = \"FAIL3\";\n        if (b !== 'PASS1' || d !== 'PASS2') throw 'fail: ' + b + ' ' + d\n      }\n    `,\n  }),\n  test(['in.js', '--outfile=node.js'], {\n    'in.js': `\n      try {\n        throw { x: 'z', z: 123 }\n      } catch ({ x, [x]: y }) {\n        if (y !== 123) throw 'fail'\n      }\n    `,\n  }),\n\n  // https://github.com/evanw/esbuild/issues/4351\n  test(['in.js', '--outfile=node.js', '--minify'], {\n    'in.js': `\n    function f(x) {\n        d: {\n          e: {\n            try {\n              while (x()) { break d }\n            } catch { break e }\n          }\n          return 2\n        }\n        return 1\n      }\n      if (f(() => 1) !== 1) throw 'fail: 1'\n      if (f('empty') !== 2) throw 'fail: 2'\n    `,\n  }),\n)\n\n// Test cyclic import issues (shouldn't crash on evaluation)\ntests.push(\n  test(['--bundle', 'entry.js', '--outfile=node.js'], {\n    'entry.js': `import * as foo from './foo'; export default {foo, bar: require('./bar')}`,\n    'foo.js': `import * as a from './entry'; import * as b from './bar'; export default {a, b}`,\n    'bar.js': `const entry = require('./entry'); export function foo() { return entry }`,\n  }),\n)\n\n// Test import attributes\ntests.push(\n  test(['--bundle', 'entry.js', '--outfile=node.js', '--format=esm'], {\n    'entry.js': `\n      import * as foo from './package.json' with { type: 'json' }\n      if (foo.default.type !== 'module' || 'type' in foo) throw 'fail: static'\n\n      const bar = await import('./package.json', { with: { type: 'json' } })\n      if (bar.default.type !== 'module' || 'type' in bar) throw 'fail: dynamic'\n    `,\n    'package.json': `{ \"type\": \"module\" }`,\n  }),\n)\n\n// Test directive preservation\ntests.push(\n  // The \"__pow\" symbol must not be hoisted above \"use strict\"\n  test(['entry.js', '--outfile=node.js', '--target=es6'], {\n    'entry.js': `\n      'use strict'\n      function f(a) {\n        a **= 2\n        return [a, arguments[0]]\n      }\n      let pair = f(2)\n      if (pair[0] !== 4 || pair[1] !== 2) throw 'fail'\n    `,\n  }),\n  test(['entry.js', '--outfile=node.js', '--target=es6'], {\n    'entry.js': `\n      //! @legal comment\n      'use strict'\n      function f(a) {\n        a **= 2\n        return [a, arguments[0]]\n      }\n      let pair = f(2)\n      if (pair[0] !== 4 || pair[1] !== 2) throw 'fail'\n    `,\n  }),\n)\n\n// Test comments inside expressions\ntests.push(\n  test(['entry.js', '--outfile=node.js', '--target=es6'], {\n    'entry.js': `\n      let foo;\n      (\n        /* x */\n        {\n          y() {\n            foo = this.y.name\n          }\n        }\n      ).y();\n      if (foo !== 'y') throw 'fail'\n    `,\n  }),\n\n  test(['entry.js', '--outfile=node.js', '--target=es6'], {\n    'entry.js': `\n      let foo;\n      (\n        /* x */\n        function y() {\n          foo = y.name\n        }\n      )();\n      if (foo !== 'y') throw 'fail'\n    `,\n  }),\n\n  test(['entry.js', '--outfile=node.js', '--target=es6'], {\n    'entry.js': `\n      let foo;\n      (\n        /* x */\n        class y {\n          static z() {\n            foo = y.name\n          }\n        }\n      ).z();\n      if (foo !== 'y') throw 'fail'\n    `,\n  }),\n\n  test(['entry.js', '--outfile=node.js', '--target=es6'], {\n    'entry.js': `\n      let foo;\n      (/* @__PURE__ */ (() => foo = 'y')());\n      if (foo !== 'y') throw 'fail'\n    `,\n  }),\n)\n\n// Test certain minification transformations\nfor (const minify of [[], ['--minify-syntax']]) {\n  tests.push(\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `let fn = (x) => { if (x && y) return; function y() {} throw 'fail' }; fn(fn)`,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `let fn = (a, b) => { if (a && (x = () => y) && b) return; var x; let y = 123; if (x() !== 123) throw 'fail' }; fn(fn)`,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        var x = { [-0]: 1 }; if (x['0'] !== 1 || x['-0'] !== void 0) throw 'fail: -0'\n        var x = { [-1]: 1 }; if (x['-1'] !== 1) throw 'fail: -1'\n        var x = { [NaN]: 1 }; if (x['NaN'] !== 1) throw 'fail: NaN'\n        var x = { [Infinity]: 1 }; if (x['Infinity'] !== 1) throw 'fail: Infinity'\n        var x = { [-Infinity]: 1 }; if (x['-Infinity'] !== 1) throw 'fail: -Infinity'\n        var x = { [1e5]: 1 }; if (x['100000'] !== 1) throw 'fail: 1e5'\n        var x = { [-1e5]: 1 }; if (x['-100000'] !== 1) throw 'fail: -1e5'\n        var x = { [1e100]: 1 }; if (x['1e+100'] !== 1) throw 'fail: 1e100'\n        var x = { [-1e100]: 1 }; if (x['-1e+100'] !== 1) throw 'fail: -1e100'\n        var x = { [0xFFFF_FFFF_FFFF]: 1 }; if (x['281474976710655'] !== 1) throw 'fail: 0xFFFF_FFFF_FFFF'\n        var x = { [-0xFFFF_FFFF_FFFF]: 1 }; if (x['-281474976710655'] !== 1) throw 'fail: -0xFFFF_FFFF_FFFF'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        var x = class { static [-0] = 1 }; if (x['0'] !== 1 || x['-0'] !== void 0) throw 'fail: -0'\n        var x = class { static [-1] = 1 }; if (x['-1'] !== 1) throw 'fail: -1'\n        var x = class { static [NaN] = 1 }; if (x['NaN'] !== 1) throw 'fail: NaN'\n        var x = class { static [Infinity] = 1 }; if (x['Infinity'] !== 1) throw 'fail: Infinity'\n        var x = class { static [-Infinity] = 1 }; if (x['-Infinity'] !== 1) throw 'fail: -Infinity'\n        var x = class { static [1e5] = 1 }; if (x['100000'] !== 1) throw 'fail: 1e5'\n        var x = class { static [-1e5] = 1 }; if (x['-100000'] !== 1) throw 'fail: -1e5'\n        var x = class { static [1e100] = 1 }; if (x['1e+100'] !== 1) throw 'fail: 1e100'\n        var x = class { static [-1e100] = 1 }; if (x['-1e+100'] !== 1) throw 'fail: -1e100'\n        var x = class { static [0xFFFF_FFFF_FFFF] = 1 }; if (x['281474976710655'] !== 1) throw 'fail: 0xFFFF_FFFF_FFFF'\n        var x = class { static [-0xFFFF_FFFF_FFFF] = 1 }; if (x['-281474976710655'] !== 1) throw 'fail: -0xFFFF_FFFF_FFFF'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        function test(x) {\n          let log = ''\n          switch (x) {\n            case 0:\n              log += '0'\n            case 1:\n            default:\n              log += '1'\n          }\n          return log\n        }\n        if (test(0) !== '01') throw 'fail: 0'\n        if (test(1) !== '1') throw 'fail: 1'\n        if (test(2) !== '1') throw 'fail: 2'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        function test(x) {\n          let log = ''\n          switch (x) {\n            case 0:\n              log += '0'\n              break\n            case 1:\n            default:\n              log += '1'\n          }\n          return log\n        }\n        if (test(0) !== '0') throw 'fail: 0'\n        if (test(1) !== '1') throw 'fail: 1'\n        if (test(2) !== '1') throw 'fail: 2'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        function test(x) {\n          let log = ''\n          switch (x) {\n            case 0:\n              log += '0'\n            case 1:\n            default:\n              log += '1'\n            case 2:\n              log += '2'\n          }\n          return log\n        }\n        if (test(0) !== '012') throw 'fail: 0'\n        if (test(1) !== '12') throw 'fail: 1'\n        if (test(2) !== '2') throw 'fail: 2'\n        if (test(3) !== '12') throw 'fail: 3'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        function test(x) {\n          let log = ''\n          switch (x) {\n            case 0: // Note: This case must not be removed\n            default:\n              log += '1'\n            case 0:\n              log += '2'\n          }\n          return log\n        }\n        if (test(0) !== '12') throw 'fail: 0'\n        if (test(1) !== '12') throw 'fail: 1'\n      `,\n    }, {\n      expectedStderr: `▲ [WARNING] This case clause will never be evaluated because it duplicates an earlier case clause [duplicate-case]\n\n    in.js:8:12:\n      8 │             case 0:\n        ╵             ~~~~\n\n  The earlier case clause is here:\n\n    in.js:5:12:\n      5 │             case 0: // Note: This case must not be removed\n        ╵             ~~~~\n\n`,\n    }),\n\n    // We potentially need to keep let/const declarations in dead cases\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        function test() {\n          switch (1) {\n            case 0:\n              var deadVarInSwitch // This must not be removed\n            case 1:\n            case 2:\n              return deadVarInSwitch\n          }\n        }\n        globalThis.deadVarInSwitch = 'fail'\n        if (test() !== undefined) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        function test() {\n          switch (1) {\n            case 0:\n              let deadLetInSwitch // This must not be removed\n            case 1:\n            case 2:\n              return deadLetInSwitch\n          }\n        }\n        globalThis.deadLetInSwitch = 'fail'\n        try {\n          test()\n          throw 'fail'\n        } catch (e) {\n          if (!(e instanceof ReferenceError))\n            throw e\n        }\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        function test() {\n          switch (1) {\n            case 0:\n              const deadConstInSwitch = 0 // This must not be removed (or inlined as a constant)\n            case 1:\n            case 2:\n              return deadConstInSwitch\n          }\n        }\n        globalThis.deadConstInSwitch = 'fail'\n        try {\n          test()\n          throw 'fail'\n        } catch (e) {\n          if (!(e instanceof ReferenceError))\n            throw e\n        }\n      `,\n    }),\n\n    // See: https://github.com/evanw/esbuild/issues/3195\n    test(['in.js', '--outfile=node.js', '--keep-names'].concat(minify), {\n      'in.js': `\n        const log = [];\n        const sideEffect = x => log.push(x);\n        (() => {\n          function f() {}\n          sideEffect(1, f());\n        })();\n        (() => {\n          function g() {}\n          debugger;\n          sideEffect(2, g());\n        })();\n        if (log + '' !== '1,2') throw 'fail: ' + log;\n      `,\n    }),\n  )\n\n  // Check property access simplification\n  for (const access of [['.a'], ['[\"a\"]']]) {\n    tests.push(\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `if ({a: 1}${access} !== 1) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `if ({a: {a: 1}}${access}${access} !== 1) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `if ({a: {b: 1}}${access}.b !== 1) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `if ({b: {a: 1}}.b${access} !== 1) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js', '--log-level=error'].concat(minify), {\n        'in.js': `if ({a: 1, a: 2}${access} !== 2) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js', '--log-level=error'].concat(minify), {\n        'in.js': `if ({a: 1, [String.fromCharCode(97)]: 2}${access} !== 2) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `let a = {a: 1}; if ({...a}${access} !== 1) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `if ({ get a() { return 1 } }${access} !== 1) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `if ({ __proto__: {a: 1} }${access} !== 1) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `if ({ __proto__: null, a: 1 }${access} !== 1) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `if ({ __proto__: null, b: 1 }${access} !== void 0) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `if ({ __proto__: null }.__proto__ !== void 0) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `if ({ ['__proto__']: null }.__proto__ !== null) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `let x = 100; if ({ b: ++x, a: 1 }${access} !== 1 || x !== 101) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `if ({ a: function() { return this.b }, b: 1 }${access}() !== 1) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `if ({ a: function() { return this.b }, b: 1 }${access}\\`\\` !== 1) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `if (({a: 2}${access} = 1) !== 1) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `if ({a: 1}${access}++ !== 1) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `if (++{a: 1}${access} !== 2) throw 'fail'`,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `\n          Object.defineProperty(Object.prototype, 'MIN_OBJ_LIT', {value: 1})\n          if ({}.MIN_OBJ_LIT !== 1) throw 'fail'\n        `,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `\n          let x = false\n          function y() { x = true }\n          if ({ b: y(), a: 1 }${access} !== 1 || !x) throw 'fail'\n        `,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `\n          try { new ({ a() {} }${access}); throw 'fail' }\n          catch (e) { if (e === 'fail') throw e }\n        `,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(minify), {\n        'in.js': `\n          let x = 1;\n          ({ set a(y) { x = y } }${access} = 2);\n          if (x !== 2) throw 'fail'\n        `,\n      }),\n    )\n  }\n\n  // Check try/catch simplification\n  tests.push(\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        try {\n          try {\n            throw 0\n          } finally {\n            var x = 1\n          }\n        } catch {\n        }\n        if (x !== 1) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        let y\n        try {\n          throw 1\n        } catch (x) {\n          eval('y = x')\n        }\n        if (y !== 1) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        try {\n          throw 0\n        } catch (x) {\n          var x = 1\n        }\n        if (x !== void 0) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        let works\n        try {\n          throw { get a() { works = true } }\n        } catch ({ a }) {}\n        if (!works) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        let works\n        try {\n          throw { *[Symbol.iterator]() { works = true } }\n        } catch ([x]) {\n        }\n        if (!works) throw 'fail'\n      `,\n    }),\n  )\n\n  // Check variable initializer inlining\n  tests.push(\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        function foo() {\n          if (this !== globalThis) throw 'fail'\n        }\n        function main() {\n          let obj = { bar: foo };\n          let fn = obj.bar;\n          (0, fn)();\n        }\n        main()\n      `,\n    }),\n  );\n\n  // Check global constructor behavior\n  tests.push(\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        const check = (before, after) => {\n          if (Boolean(before) !== after) throw 'fail: Boolean(' + before + ') should not be ' + Boolean(before)\n          if (new Boolean(before) === after) throw 'fail: new Boolean(' + before + ') should not be ' + new Boolean(before)\n          if (new Boolean(before).valueOf() !== after) throw 'fail: new Boolean(' + before + ').valueOf() should not be ' + new Boolean(before).valueOf()\n        }\n        check(false, false); check(0, false); check(0n, false)\n        check(true, true); check(1, true); check(1n, true)\n        check(null, false); check(undefined, false)\n        check('', false); check('x', true)\n\n        const checkSpread = (before, after) => {\n          if (Boolean(...before) !== after) throw 'fail: Boolean(...' + before + ') should not be ' + Boolean(...before)\n          if (new Boolean(...before) === after) throw 'fail: new Boolean(...' + before + ') should not be ' + new Boolean(...before)\n          if (new Boolean(...before).valueOf() !== after) throw 'fail: new Boolean(...' + before + ').valueOf() should not be ' + new Boolean(...before).valueOf()\n        }\n        checkSpread([0], false); check([1], true)\n        checkSpread([], false)\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        class ToPrimitive { [Symbol.toPrimitive]() { return '100.001' } }\n        const someObject = { toString: () => 123, valueOf: () => 321 }\n\n        const check = (before, after) => {\n          if (Number(before) !== after) throw 'fail: Number(' + before + ') should not be ' + Number(before)\n          if (new Number(before) === after) throw 'fail: new Number(' + before + ') should not be ' + new Number(before)\n          if (new Number(before).valueOf() !== after) throw 'fail: new Number(' + before + ').valueOf() should not be ' + new Number(before).valueOf()\n        }\n        check(-1.23, -1.23)\n        check('-1.23', -1.23)\n        check(123n, 123)\n        check(null, 0)\n        check(false, 0)\n        check(true, 1)\n        check(someObject, 321)\n        check(new ToPrimitive(), 100.001)\n\n        const checkSpread = (before, after) => {\n          if (Number(...before) !== after) throw 'fail: Number(...' + before + ') should not be ' + Number(...before)\n          if (new Number(...before) === after) throw 'fail: new Number(...' + before + ') should not be ' + new Number(...before)\n          if (new Number(...before).valueOf() !== after) throw 'fail: new Number(...' + before + ').valueOf() should not be ' + new Number(...before).valueOf()\n        }\n        checkSpread(['123'], 123)\n        checkSpread([], 0)\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        class ToPrimitive { [Symbol.toPrimitive]() { return 100.001 } }\n        const someObject = { toString: () => 123, valueOf: () => 321 }\n\n        const check = (before, after) => {\n          if (String(before) !== after) throw 'fail: String(' + before + ') should not be ' + String(before)\n          if (new String(before) === after) throw 'fail: new String(' + before + ') should not be ' + new String(before)\n          if (new String(before).valueOf() !== after) throw 'fail: new String(' + before + ').valueOf() should not be ' + new String(before).valueOf()\n        }\n        check('', '')\n        check('x', 'x')\n        check(null, 'null')\n        check(false, 'false')\n        check(1.23, '1.23')\n        check(-123n, '-123')\n        check(someObject, '123')\n        check(new ToPrimitive(), '100.001')\n\n        const checkSpread = (before, after) => {\n          if (String(...before) !== after) throw 'fail: String(...' + before + ') should not be ' + String(...before)\n          if (new String(...before) === after) throw 'fail: new String(...' + before + ') should not be ' + new String(...before)\n          if (new String(...before).valueOf() !== after) throw 'fail: new String(...' + before + ').valueOf() should not be ' + new String(...before).valueOf()\n        }\n        checkSpread([123], '123')\n        checkSpread([], '')\n\n        const checkAndExpectNewToThrow = (before, after) => {\n          if (String(before) !== after) throw 'fail: String(...) should not be ' + String(before)\n          try {\n            new String(before)\n          } catch (e) {\n            return\n          }\n          throw 'fail: new String(...) should not succeed'\n        }\n        checkAndExpectNewToThrow(Symbol('abc'), 'Symbol(abc)')\n      `,\n    }),\n  );\n\n  // https://github.com/evanw/esbuild/issues/3125\n  tests.push(\n    test(['in.js', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        let y\n        {\n          // There was a bug where this incorrectly turned into \"y = (() => x)()\"\n          const f = () => x;\n          const x = 0;\n          y = f()\n        }\n        if (y !== 0) throw 'fail'\n      `,\n    }),\n  )\n\n  // https://github.com/evanw/esbuild/issues/3700\n  tests.push(\n    test(['in.js', '--bundle', '--outfile=node.js'].concat(minify), {\n      'in.js': `\n        import imported from './data.json'\n        const native = JSON.parse(\\`{\n          \"hello\": \"world\",\n          \"__proto__\": {\n            \"sky\": \"universe\"\n          }\n        }\\`)\n        const literal1 = {\n          \"hello\": \"world\",\n          \"__proto__\": {\n            \"sky\": \"universe\"\n          }\n        }\n        const literal2 = {\n          \"hello\": \"world\",\n          [\"__proto__\"]: {\n            \"sky\": \"universe\"\n          }\n        }\n        if (Object.getPrototypeOf(native)?.sky) throw 'fail: native'\n        if (!Object.getPrototypeOf(literal1)?.sky) throw 'fail: literal1'\n        if (Object.getPrototypeOf(literal2)?.sky) throw 'fail: literal2'\n        if (Object.getPrototypeOf(imported)?.sky) throw 'fail: imported'\n      `,\n      'data.json': `{\n        \"hello\": \"world\",\n        \"__proto__\": {\n          \"sky\": \"universe\"\n        }\n      }`,\n    }),\n  )\n}\n\n// Test minification of top-level symbols\ntests.push(\n  test(['in.js', '--outfile=node.js', '--minify'], {\n    // Top-level names should not be minified\n    'in.js': `function foo() {} if (foo.name !== 'foo') throw 'fail: ' + foo.name`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify'], {\n    // Nested names should be minified\n    'in.js': `(() => { function foo() {} if (foo.name === 'foo') throw 'fail: ' + foo.name })()`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--target=es6'], {\n    // Importing the \"__pow()\" runtime function should not affect top-level name minification\n    'in.js': `let _8 = 2 ** 3; function foo8() {} if (foo8.name !== 'foo' + _8) throw 'fail: ' + foo8.name`,\n  }),\n)\n\n// Test name preservation\nfor (let flags of [[], ['--minify', '--keep-names']]) {\n  tests.push(\n    // Arrow functions\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let fn = () => {}; if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let fn; fn = () => {}; if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let [fn = () => {}] = []; if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let fn; [fn = () => {}] = []; if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let {fn = () => {}} = {}; if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let {prop: fn = () => {}} = {}; if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let fn; ({fn = () => {}} = {}); if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let fn; ({prop: fn = () => {}} = {}); if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let obj = {}; obj.fn = () => {}; if (obj.fn.name !== '') throw 'fail: ' + obj.fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let obj = {}; obj['fn'] = () => {}; if (obj.fn.name !== '') throw 'fail: ' + obj.fn.name })()`,\n    }),\n\n    // Functions\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { function foo() {} if (foo.name !== 'foo') throw 'fail: ' + foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let fn = function foo() {}; if (fn.name !== 'foo') throw 'fail' })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let fn = function() {}; if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let fn; fn = function() {}; if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let [fn = function() {}] = []; if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let fn; [fn = function() {}] = []; if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let {fn = function() {}} = {}; if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let {prop: fn = function() {}} = {}; if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let fn; ({fn = function() {}} = {}); if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let fn; ({prop: fn = function() {}} = {}); if (fn.name !== 'fn') throw 'fail: ' + fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let obj = {}; obj.fn = function() {}; if (obj.fn.name !== '') throw 'fail: ' + obj.fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let obj = {}; obj['fn'] = function() {}; if (obj.fn.name !== '') throw 'fail: ' + obj.fn.name })()`,\n    }),\n\n    // Classes\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { class foo {} if (foo.name !== 'foo') throw 'fail: ' + foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let cls = class foo {}; if (cls.name !== 'foo') throw 'fail: ' + cls.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let cls = class {}; if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let cls; cls = class {}; if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let [cls = class {}] = []; if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let cls; [cls = class {}] = []; if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let {cls = class {}} = {}; if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let {prop: cls = class {}} = {}; if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let cls; ({cls = class {}} = {}); if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let cls; ({prop: cls = class {}} = {}); if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let obj = {}; obj.cls = class {}; if (obj.cls.name !== '') throw 'fail: ' + obj.cls.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let obj = {}; obj['cls'] = class {}; if (obj.cls.name !== '') throw 'fail: ' + obj.cls.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { class Foo { static foo } if (Foo.name !== 'Foo') throw 'fail: ' + Foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { class Foo { static name = 123 } if (Foo.name !== 123) throw 'fail: ' + Foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { class Foo { static name() { return 123 } } if (Foo.name() !== 123) throw 'fail: ' + Foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { class Foo { static get name() { return 123 } } if (Foo.name !== 123) throw 'fail: ' + Foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { class Foo { static ['name'] = 123 } if (Foo.name !== 123) throw 'fail: ' + Foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let Foo = class Bar { static foo }; if (Foo.name !== 'Bar') throw 'fail: ' + Foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let Foo = class Bar { static name = 123 }; if (Foo.name !== 123) throw 'fail: ' + Foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let Foo = class Bar { static name() { return 123 } }; if (Foo.name() !== 123) throw 'fail: ' + Foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let Foo = class Bar { static get name() { return 123 } }; if (Foo.name !== 123) throw 'fail: ' + Foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let Foo = class Bar { static ['name'] = 123 }; if (Foo.name !== 123) throw 'fail: ' + Foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let Foo = class { static foo }; if (Foo.name !== 'Foo') throw 'fail: ' + Foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let Foo = class { static name = 123 }; if (Foo.name !== 123) throw 'fail: ' + Foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let Foo = class { static name() { return 123 } }; if (Foo.name() !== 123) throw 'fail: ' + Foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let Foo = class { static get name() { return 123 } }; if (Foo.name !== 123) throw 'fail: ' + Foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let Foo = class { static ['name'] = 123 }; if (Foo.name !== 123) throw 'fail: ' + Foo.name })()`,\n    }),\n\n    // Methods\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let obj = { foo() {} }; if (obj.foo.name !== 'foo') throw 'fail: ' + obj.foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let obj = { foo: () => {} }; if (obj.foo.name !== 'foo') throw 'fail: ' + obj.foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { class Foo { foo() {} }; if (new Foo().foo.name !== 'foo') throw 'fail: ' + new Foo().foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { class Foo { static foo() {} }; if (Foo.foo.name !== 'foo') throw 'fail: ' + Foo.foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let Foo = class { foo() {} }; if (new Foo().foo.name !== 'foo') throw 'fail: ' + new Foo().foo.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let Foo = class { static foo() {} }; if (Foo.foo.name !== 'foo') throw 'fail: ' + Foo.foo.name })()`,\n    }),\n\n    // See: https://github.com/evanw/esbuild/issues/3199\n    test(['in.ts', '--outfile=node.js', '--target=es6'].concat(flags), {\n      'in.ts': `\n        namespace foo { export class Foo {} }\n        if (foo.Foo.name !== 'Foo') throw 'fail: ' + foo.Foo.name\n      `,\n    }),\n    test(['in.ts', '--outfile=node.js', '--target=esnext'].concat(flags), {\n      'in.ts': `\n        namespace foo { export class Foo {} }\n        if (foo.Foo.name !== 'Foo') throw 'fail: ' + foo.Foo.name\n      `,\n    }),\n\n    // See: https://github.com/evanw/esbuild/issues/3756\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let obj = { fn() {} }; if (obj.fn.name !== 'fn') throw 'fail: ' + obj.fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let obj = { *fn() {} }; if (obj.fn.name !== 'fn') throw 'fail: ' + obj.fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => { let obj = { async fn() {} }; if (obj.fn.name !== 'fn') throw 'fail: ' + obj.fn.name })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => {\n        let obj = { get fn() {} }, { get } = Object.getOwnPropertyDescriptor(obj, 'fn')\n        if (get.name !== 'get fn') throw 'fail: ' + get.name\n      })()`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `(() => {\n        let obj = { set fn(_) {} }, { set } = Object.getOwnPropertyDescriptor(obj, 'fn')\n        if (set.name !== 'set fn') throw 'fail: ' + set.name\n      })()`,\n    }),\n  )\n}\ntests.push(\n  // Arrow functions\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle'], {\n    'in.js': `import foo from './other'; if (foo.name !== 'default') throw 'fail: ' + foo.name`,\n    'other.js': `export default () => {}`,\n  }),\n\n  // Functions\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle'], {\n    'in.js': `import foo from './other'; if (foo.name !== 'foo') throw 'fail: ' + foo.name`,\n    'other.js': `export default function foo() {}`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle'], {\n    'in.js': `import foo from './other'; if (foo.name !== 'default') throw 'fail: ' + foo.name`,\n    'other.js': `export default function() {}`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle'], {\n    'in.js': `import foo from './other'; if (foo.name !== 'default') throw 'fail: ' + foo.name`,\n    'other.js': `export default (function() {})`,\n  }),\n\n  // Classes\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle'], {\n    'in.js': `import foo from './other'; if (foo.name !== 'foo') throw 'fail: ' + foo.name`,\n    'other.js': `export default class foo {}`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle'], {\n    'in.js': `import foo from './other'; if (foo.name !== 'default') throw 'fail: ' + foo.name`,\n    'other.js': `export default class {}`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle'], {\n    'in.js': `import foo from './other'; if (foo.name !== 'default') throw 'fail: ' + foo.name`,\n    'other.js': `export default (class {})`,\n  }),\n  test(['in.js', '--outfile=out.js', '--minify', '--keep-names', '--format=esm'], {\n    'node.js': `import foo from './out.js'; if (foo.name !== 'foo') throw 'fail: ' + foo.name`,\n    'in.js': `export default class foo {}`,\n  }),\n  test(['in.js', '--outfile=out.js', '--minify', '--keep-names', '--format=esm'], {\n    'node.js': `import foo from './out.js'; if (foo.name !== 'default') throw 'fail: ' + foo.name`,\n    'in.js': `export default class {}`,\n  }),\n  test(['in.js', '--outfile=out.js', '--minify', '--keep-names', '--format=esm'], {\n    'node.js': `import foo from './out.js'; if (foo.name !== 'default') throw 'fail: ' + foo.name`,\n    'in.js': `export default (class {})`,\n  }),\n\n  // Class fields\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle', '--target=es6'], {\n    'in.js': `(() => { class Foo { foo = () => {} } if (new Foo().foo.name !== 'foo') throw 'fail: ' + new Foo().foo.name })()`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle', '--target=es6'], {\n    'in.js': `(() => { class Foo { static foo = () => {} } if (Foo.foo.name !== 'foo') throw 'fail: ' + Foo.foo.name })()`,\n  }),\n\n  // Private methods\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle', '--target=es6'], {\n    'in.js': `(() => { class foo { a() { return this.#b } #b() {} } if (foo.name !== 'foo') throw 'fail: ' + foo.name })()`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle', '--target=es6'], {\n    'in.js': `(() => { let cls = class foo { a() { return this.#b } #b() {} }; if (cls.name !== 'foo') throw 'fail: ' + cls.name })()`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle', '--target=es6'], {\n    'in.js': `(() => { let cls = class { a() { return this.#b } #b() {} }; if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle', '--target=es6'], {\n    'in.js': `(() => { let cls; cls = class { a() { return this.#b } #b() {} }; if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle', '--target=es6'], {\n    'in.js': `(() => { let [cls = class { a() { return this.#b } #b() {} }] = []; if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle', '--target=es6'], {\n    'in.js': `(() => { let cls; [cls = class { a() { return this.#b } #b() {} }] = []; if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle', '--target=es6'], {\n    'in.js': `(() => { let {cls = class { a() { return this.#b } #b() {} }} = {}; if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle', '--target=es6'], {\n    'in.js': `(() => { let {prop: cls = class { a() { return this.#b } #b() {} }} = {}; if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle', '--target=es6'], {\n    'in.js': `(() => { let cls; ({cls = class { a() { return this.#b } #b() {} }} = {}); if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle', '--target=es6'], {\n    'in.js': `(() => { let cls; ({prop: cls = class { a() { return this.#b } #b() {} }} = {}); if (cls.name !== 'cls') throw 'fail: ' + cls.name })()`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle', '--target=es6'], {\n    'in.js': `import foo from './other'; if (foo.name !== 'foo') throw 'fail: ' + foo.name`,\n    'other.js': `export default class foo { a() { return this.#b } #b() {} }`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle', '--target=es6'], {\n    'in.js': `import foo from './other'; if (foo.name !== 'default') throw 'fail: ' + foo.name`,\n    'other.js': `export default class { a() { return this.#b } #b() {} }`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--bundle', '--target=es6'], {\n    'in.js': `import foo from './other'; if (foo.name !== 'default') throw 'fail: ' + foo.name`,\n    'other.js': `export default (class { a() { return this.#b } #b() {} })`,\n  }),\n  test(['in.js', '--outfile=out.js', '--minify', '--keep-names', '--format=esm', '--target=es6'], {\n    'node.js': `import foo from './out.js'; if (foo.name !== 'foo') throw 'fail: ' + foo.name`,\n    'in.js': `export default class foo { a() { return this.#b } #b() {} }`,\n  }),\n  test(['in.js', '--outfile=out.js', '--minify', '--keep-names', '--format=esm', '--target=es6'], {\n    'node.js': `import foo from './out.js'; if (foo.name !== 'default') throw 'fail: ' + foo.name`,\n    'in.js': `export default class { a() { return this.#b } #b() {} }`,\n  }),\n  test(['in.js', '--outfile=out.js', '--minify', '--keep-names', '--format=esm', '--target=es6'], {\n    'node.js': `import foo from './out.js'; if (foo.name !== 'default') throw 'fail: ' + foo.name`,\n    'in.js': `export default (class { a() { return this.#b } #b() {} })`,\n  }),\n\n  // Private fields\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--format=esm', '--target=es6'], {\n    'in.js': `class Foo { foo = this.#foo; #foo() {} } if (new Foo().foo.name !== '#foo') throw 'fail: ' + new Foo().foo.name`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--format=esm', '--target=es6'], {\n    'in.js': `class Foo { static foo = this.#foo; static #foo() {} } if (Foo.foo.name !== '#foo') throw 'fail: ' + Foo.foo.name`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--format=esm', '--target=es6'], {\n    'in.js': `class Foo { #foo = function() {}; foo = this.#foo } if (new Foo().foo.name !== '#foo') throw 'fail: ' + new Foo().foo.name`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--format=esm', '--target=es6'], {\n    'in.js': `class Foo { static #foo = function() {}; static foo = this.#foo } if (Foo.foo.name !== '#foo') throw 'fail: ' + Foo.foo.name`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--format=esm', '--target=es6'], {\n    'in.js': `class Foo { #foo = () => {}; foo = this.#foo } if (new Foo().foo.name !== '#foo') throw 'fail: ' + new Foo().foo.name`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--format=esm', '--target=es6'], {\n    'in.js': `class Foo { static #foo = () => {}; static foo = this.#foo } if (Foo.foo.name !== '#foo') throw 'fail: ' + Foo.foo.name`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--format=esm', '--target=es6'], {\n    'in.js': `class Foo { #foo = class {}; foo = this.#foo } if (new Foo().foo.name !== '#foo') throw 'fail: ' + new Foo().foo.name`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--format=esm', '--target=es6'], {\n    'in.js': `class Foo { static #foo = class {}; static foo = this.#foo } if (Foo.foo.name !== '#foo') throw 'fail: ' + Foo.foo.name`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--format=esm', '--target=es6'], {\n    'in.js': `class Foo { #foo = class { #bar = 123; bar = this.#bar }; foo = this.#foo } if (new Foo().foo.name !== '#foo') throw 'fail: ' + new Foo().foo.name`,\n  }),\n  test(['in.js', '--outfile=node.js', '--minify', '--keep-names', '--format=esm', '--target=es6'], {\n    'in.js': `class Foo { static #foo = class { #bar = 123; bar = this.#bar }; static foo = this.#foo } if (Foo.foo.name !== '#foo') throw 'fail: ' + Foo.foo.name`,\n  }),\n\n  // https://github.com/evanw/esbuild/issues/2149\n  test(['in.js', '--outfile=node.js', '--target=es6', '--keep-names'], {\n    'in.js': `\n      class Foo {\n        static get #foo() { return Foo.name }\n        static get foo() { return this.#foo }\n      }\n      let Bar = Foo\n      if (Foo.name !== 'Foo') throw 'fail: ' + Foo.name\n      if (Bar.foo !== 'Foo') throw 'fail: ' + Bar.foo\n      Foo = { name: 'Bar' }\n      if (Foo.name !== 'Bar') throw 'fail: ' + Foo.name\n      if (Bar.foo !== 'Foo') throw 'fail: ' + Bar.foo\n    `,\n  }),\n)\n\n// Test minification of mangled properties (class and object) with a keyword before them\ntests.push(\n  test(['in.js', '--outfile=node.js', '--minify', '--mangle-props=.'], {\n    'in.js': `\n      class Foo {\n        static bar = { get baz() { return 123 } }\n      }\n      if (Foo.bar.baz !== 123) throw 'fail'\n    `,\n  }),\n)\n\n// Test minification of hoisted top-level symbols declared in nested scopes.\n// Previously this code was incorrectly transformed into this, which crashes:\n//\n//   var c = false;\n//   var d = function a() {\n//     b[a]();\n//   };\n//   for (var a = 0, b = [() => c = true]; a < b.length; a++) {\n//     d();\n//   }\n//   export default c;\n//\n// The problem is that \"var i\" is declared in a nested scope but hoisted to\n// the top-level scope. So it's accidentally assigned a nested scope slot\n// even though it's a top-level symbol, not a nested scope symbol.\ntests.push(\n  test(['in.js', '--outfile=out.js', '--format=esm', '--minify', '--bundle'], {\n    'in.js': `\n      var worked = false\n      var loop = function fn() {\n        array[i]();\n      };\n      for (var i = 0, array = [() => worked = true]; i < array.length; i++) {\n        loop();\n      }\n      export default worked\n    `,\n    'node.js': `\n      import worked from './out.js'\n      if (!worked) throw 'fail'\n    `,\n  }),\n)\n\n// Check for an obscure bug with minification, symbol renaming, and sloppy\n// nested function declarations: https://github.com/evanw/esbuild/issues/2809.\n// Previously esbuild generated the following code:\n//\n//   let f = 0;\n//   for (let l of [1, 2]) {\n//     let t = function(o) {\n//       return o;\n//     };\n//     var f = t;\n//     f += t(l);\n//   }\n//   if (f !== 3)\n//     throw \"fail\";\n//\n// Notice how \"f\" is declared twice, leading to a syntax error.\nfor (const flags of [[], ['--minify']]) {\n  tests.push(\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `\n        let total = 0\n        for (let value of [1, 2]) {\n          function f(x) { return x }\n          total += f(value)\n        }\n        if (total !== 3) throw 'fail'\n      `,\n    }),\n  )\n}\n\n// Test hoisting variables inside for loop initializers outside of lazy ESM\n// wrappers. Previously this didn't work due to a bug that considered for\n// loop initializers to already be in the top-level scope. For more info\n// see: https://github.com/evanw/esbuild/issues/1455.\ntests.push(\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      if (require('./nested').foo() !== 10) throw 'fail'\n    `,\n    'nested.js': `\n      for (var i = 0; i < 10; i++) ;\n      export function foo() { return i }\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      if (require('./nested').foo() !== 'c') throw 'fail'\n    `,\n    'nested.js': `\n      for (var i in {a: 1, b: 2, c: 3}) ;\n      export function foo() { return i }\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      if (require('./nested').foo() !== 3) throw 'fail'\n    `,\n    'nested.js': `\n      for (var i of [1, 2, 3]) ;\n      export function foo() { return i }\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle', '--target=es6'], {\n    'in.js': `\n      if (JSON.stringify(require('./nested').foo()) !== '{\"b\":2,\"c\":3}') throw 'fail'\n    `,\n    'nested.js': `\n      for (var {a, ...i} = {a: 1, b: 2, c: 3}; 0; ) ;\n      export function foo() { return i }\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle', '--target=es6'], {\n    'in.js': `\n      if (JSON.stringify(require('./nested').foo()) !== '{\"0\":\"c\"}') throw 'fail'\n    `,\n    'nested.js': `\n      for (var {a, ...i} in {a: 1, b: 2, c: 3}) ;\n      export function foo() { return i }\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle', '--target=es6'], {\n    'in.js': `\n      if (JSON.stringify(require('./nested').foo()) !== '{\"b\":2,\"c\":3}') throw 'fail'\n    `,\n    'nested.js': `\n      for (var {a, ...i} of [{a: 1, b: 2, c: 3}]) ;\n      export function foo() { return i }\n    `,\n  }),\n)\n\n// Test tree shaking\ntests.push(\n  // Keep because used (ES6)\n  test(['--bundle', 'entry.js', '--outfile=node.js'], {\n    'entry.js': `import * as foo from './foo'; if (global.dce0 !== 123 || foo.abc !== 'abc') throw 'fail'`,\n    'foo/index.js': `global.dce0 = 123; export const abc = 'abc'`,\n    'foo/package.json': `{ \"sideEffects\": false }`,\n  }),\n\n  // Remove because unused (ES6)\n  test(['--bundle', 'entry.js', '--outfile=node.js'], {\n    'entry.js': `import * as foo from './foo'; if (global.dce1 !== void 0) throw 'fail'`,\n    'foo/index.js': `global.dce1 = 123; export const abc = 'abc'`,\n    'foo/package.json': `{ \"sideEffects\": false }`,\n  }),\n\n  // Keep because side effects (ES6)\n  test(['--bundle', 'entry.js', '--outfile=node.js'], {\n    'entry.js': `import * as foo from './foo'; if (global.dce2 !== 123) throw 'fail'`,\n    'foo/index.js': `global.dce2 = 123; export const abc = 'abc'`,\n    'foo/package.json': `{ \"sideEffects\": true }`,\n  }),\n\n  // Keep because used (CommonJS)\n  test(['--bundle', 'entry.js', '--outfile=node.js'], {\n    'entry.js': `import foo from './foo'; if (global.dce3 !== 123 || foo.abc !== 'abc') throw 'fail'`,\n    'foo/index.js': `global.dce3 = 123; exports.abc = 'abc'`,\n    'foo/package.json': `{ \"sideEffects\": false }`,\n  }),\n\n  // Remove because unused (CommonJS)\n  test(['--bundle', 'entry.js', '--outfile=node.js'], {\n    'entry.js': `import foo from './foo'; if (global.dce4 !== void 0) throw 'fail'`,\n    'foo/index.js': `global.dce4 = 123; exports.abc = 'abc'`,\n    'foo/package.json': `{ \"sideEffects\": false }`,\n  }),\n\n  // Keep because side effects (CommonJS)\n  test(['--bundle', 'entry.js', '--outfile=node.js'], {\n    'entry.js': `import foo from './foo'; if (global.dce5 !== 123) throw 'fail'`,\n    'foo/index.js': `global.dce5 = 123; exports.abc = 'abc'`,\n    'foo/package.json': `{ \"sideEffects\": true }`,\n  }),\n\n  // Note: Tree shaking this could technically be considered incorrect because\n  // the import is for a property whose getter in this case has a side effect.\n  // However, this is very unlikely and the vast majority of the time people\n  // would likely rather have the code be tree-shaken. This test case enforces\n  // the technically incorrect behavior as documentation that this edge case\n  // is being ignored.\n  test(['--bundle', 'entry.js', '--outfile=node.js'], {\n    'entry.js': `import {foo, bar} from './foo'; let unused = foo; if (bar) throw 'expected \"foo\" to be tree-shaken'`,\n    'foo.js': `module.exports = {get foo() { module.exports.bar = 1 }, bar: 0}`,\n  }),\n\n  // Test for an implicit and explicit \"**/\" prefix (see https://github.com/evanw/esbuild/issues/1184)\n  test(['--bundle', 'entry.js', '--outfile=node.js'], {\n    'entry.js': `import './foo'; if (global.dce6 !== 123) throw 'fail'`,\n    'foo/dir/x.js': `global.dce6 = 123`,\n    'foo/package.json': `{ \"main\": \"dir/x\", \"sideEffects\": [\"x.*\"] }`,\n  }),\n  test(['--bundle', 'entry.js', '--outfile=node.js'], {\n    'entry.js': `import './foo'; if (global.dce6 !== 123) throw 'fail'`,\n    'foo/dir/x.js': `global.dce6 = 123`,\n    'foo/package.json': `{ \"main\": \"dir/x\", \"sideEffects\": [\"**/x.*\"] }`,\n  }),\n\n  // Test side effect detection for destructuring\n  test(['--bundle', 'entry.js', '--outfile=out.js'], {\n    'entry.js': `\n      let [a] = {}; // This must not be tree-shaken\n    `,\n    'node.js': `\n      pass: {\n        try {\n          require('./out.js')\n        } catch (e) {\n          break pass\n        }\n        throw 'fail'\n      }\n    `,\n  }),\n  test(['--bundle', 'entry.js', '--outfile=node.js'], {\n    'entry.js': `\n      let sideEffect = false\n      let { a } = { // This must not be tree-shaken\n        get a() {\n          sideEffect = true\n        },\n      };\n      if (!sideEffect) throw 'fail'\n    `,\n  }),\n\n  // Keep because side effects (decorators)\n  test(['--bundle', 'entry.ts', '--outfile=node.js', '--target=es2022'], {\n    'entry.ts': `\n      import { order } from './decorator'\n      import './class'\n      import './field'\n      import './method'\n      import './accessor'\n      import './parameter'\n      import './static-field'\n      import './static-method'\n      import './static-accessor'\n      import './static-parameter'\n      if (order + '' !== ',field,method,accessor,parameter,staticField,staticMethod,staticAccessor,staticParameter') throw 'fail: ' + order\n    `,\n    'decorator.ts': `\n      export const order = []\n      export const fn = (_, name) => {\n        order.push(name)\n      }\n    `,\n    'class.ts': `import { fn } from './decorator'; @fn class Foo {}`,\n    'field.ts': `import { fn } from './decorator'; class Foo { @fn field }`,\n    'method.ts': `import { fn } from './decorator'; class Foo { @fn method() {} }`,\n    'accessor.ts': `import { fn } from './decorator'; class Foo { @fn accessor accessor }`,\n    'parameter.ts': `import { fn } from './decorator'; class Foo { parameter(@fn arg) {} }`,\n    'static-field.ts': `import { fn } from './decorator'; class Foo { @fn static staticField }`,\n    'static-method.ts': `import { fn } from './decorator'; class Foo { @fn static staticMethod() {} }`,\n    'static-accessor.ts': `import { fn } from './decorator'; class Foo { @fn static accessor staticAccessor }`,\n    'static-parameter.ts': `import { fn } from './decorator'; class Foo { static staticParameter(@fn arg) {} }`,\n    'tsconfig.json': `{\n      \"compilerOptions\": {\n        \"experimentalDecorators\": true\n      }\n    }`,\n  }),\n)\n\n// Test obscure CommonJS symbol edge cases\ntests.push(\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `const ns = require('./foo'); if (ns.foo !== 123 || ns.bar !== 123) throw 'fail'`,\n    'foo.js': `var exports, module; module.exports.foo = 123; exports.bar = exports.foo`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `require('./foo'); require('./bar')`,\n    'foo.js': `let exports; if (exports !== void 0) throw 'fail'`,\n    'bar.js': `let module; if (module !== void 0) throw 'fail'`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `const ns = require('./foo'); if (ns.foo !== void 0 || ns.default.foo !== 123) throw 'fail'`,\n    'foo.js': `var exports = {foo: 123}; export default exports`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `const ns = require('./foo'); if (ns !== 123) throw 'fail'`,\n    'foo.ts': `let module = 123; export = module`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `require('./foo')`,\n    'foo.js': `var require; if (require !== void 0) throw 'fail'`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `require('./foo')`,\n    'foo.js': `var require = x => x; if (require('does not exist') !== 'does not exist') throw 'fail'`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `const ns = require('./foo'); if (ns.a !== 123 || ns.b.a !== 123) throw 'fail'`,\n    'foo.js': `exports.a = 123; exports.b = this`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle', '--log-level=error'], {\n    'in.js': `const ns = require('./foo'); if (ns.a !== 123 || ns.b !== void 0) throw 'fail'`,\n    'foo.js': `export let a = 123, b = this`,\n  }),\n)\n\n// Optional chain lowering tests\nfor (let [code, expected] of [\n  ['array?.map?.(x => -x).filter', '[].filter'],\n  ['array?.map?.(x => -x)[\"filter\"]', '[].filter'],\n  ['array?.map?.(x => -x).filter(x => x < -1)', '[-2, -3]'],\n  ['array?.map?.(x => -x)[\"filter\"](x => x < -1)', '[-2, -3]'],\n]) {\n  tests.push(\n    test(['in.js', '--outfile=node.js', '--target=es6', '--format=esm'], {\n      'in.js': `\n        import * as assert from 'assert';\n        let array = [1, 2, 3];\n        let result = ${code};\n        assert.deepStrictEqual(result, ${expected});\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', '--target=es6', '--format=esm'], {\n      'in.js': `\n        import * as assert from 'assert';\n        function test(array, result = ${code}) {\n          return result\n        }\n        assert.deepStrictEqual(test([1, 2, 3]), ${expected});\n      `,\n    }),\n  )\n}\n\n// Class lowering tests\nfor (let flags of [['--target=es2022'], ['--target=es6'], ['--bundle', '--target=es2022'], ['--bundle', '--target=es6']]) {\n  // Skip running these tests untransformed. I believe V8 actually has a bug\n  // here and esbuild is correct, both because SpiderMonkey and JavaScriptCore\n  // run this code fine and because the specification says that the left operand\n  // of the assignment operator should be evaluated first but V8 appears to be\n  // evaluating it later on. The bug with V8 has been filed here for reference:\n  // https://bugs.chromium.org/p/v8/issues/detail?id=12352\n  if (flags.includes('--target=es6')) {\n    tests.push(\n      test(['in.js', '--outfile=node.js'].concat(flags), {\n        'in.js': `\n          let bar\n          class Foo {\n            get #foo() { bar = new Foo; return this.result }\n            set #foo(x) { this.result = x }\n            bar() {\n              bar = this\n              bar.result = 2\n              bar.#foo *= 3\n            }\n          }\n          let foo = new Foo()\n          foo.bar()\n          if (foo === bar || foo.result !== 6 || bar.result !== void 0) throw 'fail'\n        `,\n      }),\n      test(['in.js', '--outfile=node.js'].concat(flags), {\n        'in.js': `\n          let bar\n          class Foo {\n            get #foo() { bar = new Foo; return this.result }\n            set #foo(x) { this.result = x }\n            bar() {\n              bar = this\n              bar.result = 2\n              bar.#foo **= 3\n            }\n          }\n          let foo = new Foo()\n          foo.bar()\n          if (foo === bar || foo.result !== 8 || bar.result !== void 0) throw 'fail'\n        `,\n      }),\n    )\n  }\n\n  // This log message is only an error during bundling\n  const assignToConstantMessage = flags.includes('--bundle')\n    ? `${errorIcon} [ERROR] Cannot assign to \"Foo\" because it is a constant`\n    : `▲ [WARNING] This assignment will throw because \"Foo\" is a constant [assign-to-constant]`\n\n  tests.push(\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          foo = 123\n          self = this\n          #method() {\n            if (this.foo !== 123) throw 'fail'\n          }\n          bar() {\n            let that = () => this\n            that().#method()\n            that().#method?.()\n            that()?.#method()\n            that()?.#method?.()\n            that().self.#method()\n            that().self.#method?.()\n            that().self?.#method()\n            that().self?.#method?.()\n            that()?.self.#method()\n            that()?.self.#method?.()\n            that()?.self?.#method()\n            that()?.self?.#method?.()\n          }\n        }\n        new Foo().bar()\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          foo = 123\n          get #bar() { return this.foo }\n          set #bar(x) { this.foo = x }\n          bar() {\n            let that = () => this\n            that().#bar **= 2\n            if (this.foo !== 15129) throw 'fail'\n          }\n        }\n        new Foo().bar()\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        let bar\n        class Foo {\n          get #foo() { bar = new Foo; return this.result }\n          set #foo(x) { this.result = x }\n          bar() {\n            bar = this\n            bar.result = 2\n            ++bar.#foo\n          }\n        }\n        let foo = new Foo()\n        foo.bar()\n        if (foo === bar || foo.result !== 3 || bar.result !== void 0) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        function print(x) {\n          return typeof x + ':' + x\n        }\n\n        function check(before, op, after) {\n          let result = new Foo(before)[op]()\n          if (result !== after) throw before + ' ' + op + ' should be ' + after + ' but was ' + result\n        }\n\n        class Foo {\n          #foo\n          constructor(foo) { this.#foo = foo }\n          preInc = () => print(++this.#foo) + ' ' + print(this.#foo)\n          preDec = () => print(--this.#foo) + ' ' + print(this.#foo)\n          postInc = () => print(this.#foo++) + ' ' + print(this.#foo)\n          postDec = () => print(this.#foo--) + ' ' + print(this.#foo)\n        }\n\n        check(123, 'preInc', 'number:124 number:124')\n        check(123, 'preDec', 'number:122 number:122')\n        check(123, 'postInc', 'number:123 number:124')\n        check(123, 'postDec', 'number:123 number:122')\n\n        check('123', 'preInc', 'number:124 number:124')\n        check('123', 'preDec', 'number:122 number:122')\n        check('123', 'postInc', 'number:123 number:124')\n        check('123', 'postDec', 'number:123 number:122')\n\n        check('x', 'preInc', 'number:NaN number:NaN')\n        check('x', 'preDec', 'number:NaN number:NaN')\n        check('x', 'postInc', 'number:NaN number:NaN')\n        check('x', 'postDec', 'number:NaN number:NaN')\n\n        check(BigInt(123), 'preInc', 'bigint:124 bigint:124')\n        check(BigInt(123), 'preDec', 'bigint:122 bigint:122')\n        check(BigInt(123), 'postInc', 'bigint:123 bigint:124')\n        check(BigInt(123), 'postDec', 'bigint:123 bigint:122')\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        function print(x) {\n          return typeof x + ':' + x\n        }\n\n        function check(before, op, after) {\n          let result = new Foo(before)[op]()\n          if (result !== after) throw before + ' ' + op + ' should be ' + after + ' but was ' + result\n        }\n\n        class Foo {\n          get #foo() { return this.__foo }\n          set #foo(x) { this.__foo = x }\n          constructor(foo) { this.#foo = foo }\n          preInc = () => print(++this.#foo) + ' ' + print(this.#foo)\n          preDec = () => print(--this.#foo) + ' ' + print(this.#foo)\n          postInc = () => print(this.#foo++) + ' ' + print(this.#foo)\n          postDec = () => print(this.#foo--) + ' ' + print(this.#foo)\n        }\n\n        check(123, 'preInc', 'number:124 number:124')\n        check(123, 'preDec', 'number:122 number:122')\n        check(123, 'postInc', 'number:123 number:124')\n        check(123, 'postDec', 'number:123 number:122')\n\n        check('123', 'preInc', 'number:124 number:124')\n        check('123', 'preDec', 'number:122 number:122')\n        check('123', 'postInc', 'number:123 number:124')\n        check('123', 'postDec', 'number:123 number:122')\n\n        check('x', 'preInc', 'number:NaN number:NaN')\n        check('x', 'preDec', 'number:NaN number:NaN')\n        check('x', 'postInc', 'number:NaN number:NaN')\n        check('x', 'postDec', 'number:NaN number:NaN')\n\n        check(BigInt(123), 'preInc', 'bigint:124 bigint:124')\n        check(BigInt(123), 'preDec', 'bigint:122 bigint:122')\n        check(BigInt(123), 'postInc', 'bigint:123 bigint:124')\n        check(BigInt(123), 'postDec', 'bigint:123 bigint:122')\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        function print(x) {\n          return typeof x + ':' + x\n        }\n\n        function check(before, op, after) {\n          Foo.setup(before)\n          let result = Foo[op]()\n          if (result !== after) throw before + ' ' + op + ' should be ' + after + ' but was ' + result\n        }\n\n        class Foo {\n          static #foo\n          static setup(x) { Foo.#foo = x }\n          static preInc = () => print(++Foo.#foo) + ' ' + print(Foo.#foo)\n          static preDec = () => print(--Foo.#foo) + ' ' + print(Foo.#foo)\n          static postInc = () => print(Foo.#foo++) + ' ' + print(Foo.#foo)\n          static postDec = () => print(Foo.#foo--) + ' ' + print(Foo.#foo)\n        }\n\n        check(123, 'preInc', 'number:124 number:124')\n        check(123, 'preDec', 'number:122 number:122')\n        check(123, 'postInc', 'number:123 number:124')\n        check(123, 'postDec', 'number:123 number:122')\n\n        check('123', 'preInc', 'number:124 number:124')\n        check('123', 'preDec', 'number:122 number:122')\n        check('123', 'postInc', 'number:123 number:124')\n        check('123', 'postDec', 'number:123 number:122')\n\n        check('x', 'preInc', 'number:NaN number:NaN')\n        check('x', 'preDec', 'number:NaN number:NaN')\n        check('x', 'postInc', 'number:NaN number:NaN')\n        check('x', 'postDec', 'number:NaN number:NaN')\n\n        check(BigInt(123), 'preInc', 'bigint:124 bigint:124')\n        check(BigInt(123), 'preDec', 'bigint:122 bigint:122')\n        check(BigInt(123), 'postInc', 'bigint:123 bigint:124')\n        check(BigInt(123), 'postDec', 'bigint:123 bigint:122')\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        function print(x) {\n          return typeof x + ':' + x\n        }\n\n        function check(before, op, after) {\n          Foo.setup(before)\n          let result = Foo[op]()\n          if (result !== after) throw before + ' ' + op + ' should be ' + after + ' but was ' + result\n        }\n\n        class Foo {\n          static get #foo() { return this.__foo }\n          static set #foo(x) { this.__foo = x }\n          static setup(x) { this.#foo = x }\n          static preInc = () => print(++this.#foo) + ' ' + print(this.#foo)\n          static preDec = () => print(--this.#foo) + ' ' + print(this.#foo)\n          static postInc = () => print(this.#foo++) + ' ' + print(this.#foo)\n          static postDec = () => print(this.#foo--) + ' ' + print(this.#foo)\n        }\n\n        check(123, 'preInc', 'number:124 number:124')\n        check(123, 'preDec', 'number:122 number:122')\n        check(123, 'postInc', 'number:123 number:124')\n        check(123, 'postDec', 'number:123 number:122')\n\n        check('123', 'preInc', 'number:124 number:124')\n        check('123', 'preDec', 'number:122 number:122')\n        check('123', 'postInc', 'number:123 number:124')\n        check('123', 'postDec', 'number:123 number:122')\n\n        check('x', 'preInc', 'number:NaN number:NaN')\n        check('x', 'preDec', 'number:NaN number:NaN')\n        check('x', 'postInc', 'number:NaN number:NaN')\n        check('x', 'postDec', 'number:NaN number:NaN')\n\n        check(BigInt(123), 'preInc', 'bigint:124 bigint:124')\n        check(BigInt(123), 'preDec', 'bigint:122 bigint:122')\n        check(BigInt(123), 'postInc', 'bigint:123 bigint:124')\n        check(BigInt(123), 'postDec', 'bigint:123 bigint:122')\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        function expect(fn, msg) {\n          try {\n            fn()\n          } catch (e) {\n            ${flags.includes('--target=es6')\n          // Only check the exact error message for esbuild\n          ? `if (e instanceof TypeError && e.message === msg) return`\n          // For node, just check whether a type error is thrown\n          : `if (e instanceof TypeError) return`\n        }\n          }\n          throw 'expected ' + msg\n        }\n        class Foo {\n          #foo\n          #method() {}\n          get #getter() {}\n          set #setter(x) {}\n          bar() {\n            let obj = {}\n            expect(() => obj.#foo, 'Cannot read from private field')\n            expect(() => obj.#foo = 1, 'Cannot write to private field')\n            expect(() => obj.#getter, 'Cannot read from private field')\n            expect(() => obj.#setter = 1, 'Cannot write to private field')\n            expect(() => obj.#method, 'Cannot access private method')\n            expect(() => obj.#method = 1, 'Cannot write to private field')\n            expect(() => this.#setter, 'member.get is not a function')\n            expect(() => this.#getter = 1, 'member.set is not a function')\n            expect(() => this.#method = 1, 'member.set is not a function')\n          }\n        }\n        new Foo().bar()\n      `,\n    }, {\n      expectedStderr: `▲ [WARNING] Writing to read-only method \"#method\" will throw [private-name-will-throw]\n\n    in.js:22:29:\n      22 │             expect(() => obj.#method = 1, 'Cannot write to private...\n         ╵                              ~~~~~~~\n\n▲ [WARNING] Reading from setter-only property \"#setter\" will throw [private-name-will-throw]\n\n    in.js:23:30:\n      23 │             expect(() => this.#setter, 'member.get is not a functi...\n         ╵                               ~~~~~~~\n\n▲ [WARNING] Writing to getter-only property \"#getter\" will throw [private-name-will-throw]\n\n    in.js:24:30:\n      24 │             expect(() => this.#getter = 1, 'member.set is not a fu...\n         ╵                               ~~~~~~~\n\n▲ [WARNING] Writing to read-only method \"#method\" will throw [private-name-will-throw]\n\n    in.js:25:30:\n      25 │             expect(() => this.#method = 1, 'member.set is not a fu...\n         ╵                               ~~~~~~~\n\n`,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        let setterCalls = 0\n        class Foo {\n          key\n          set key(x) { setterCalls++ }\n        }\n        let foo = new Foo()\n        if (setterCalls !== 0 || !foo.hasOwnProperty('key') || foo.key !== void 0) throw 'fail'\n      `,\n    }, {\n      expectedStderr: `▲ [WARNING] Duplicate member \"key\" in class body [duplicate-class-member]\n\n    in.js:5:14:\n      5 │           set key(x) { setterCalls++ }\n        ╵               ~~~\n\n  The original member \"key\" is here:\n\n    in.js:4:10:\n      4 │           key\n        ╵           ~~~\n\n`,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        let setterCalls = 0\n        class Foo {\n          key = 123\n          set key(x) { setterCalls++ }\n        }\n        let foo = new Foo()\n        if (setterCalls !== 0 || !foo.hasOwnProperty('key') || foo.key !== 123) throw 'fail'\n      `,\n    }, {\n      expectedStderr: `▲ [WARNING] Duplicate member \"key\" in class body [duplicate-class-member]\n\n    in.js:5:14:\n      5 │           set key(x) { setterCalls++ }\n        ╵               ~~~\n\n  The original member \"key\" is here:\n\n    in.js:4:10:\n      4 │           key = 123\n        ╵           ~~~\n\n`,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        let toStringCalls = 0\n        let setterCalls = 0\n        class Foo {\n          [{toString() {\n            toStringCalls++\n            return 'key'\n          }}]\n          set key(x) { setterCalls++ }\n        }\n        let foo = new Foo()\n        if (setterCalls !== 0 || toStringCalls !== 1 || !foo.hasOwnProperty('key') || foo.key !== void 0) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        let toStringCalls = 0\n        let setterCalls = 0\n        class Foo {\n          [{toString() {\n            toStringCalls++\n            return 'key'\n          }}] = 123\n          set key(x) { setterCalls++ }\n        }\n        let foo = new Foo()\n        if (setterCalls !== 0 || toStringCalls !== 1 || !foo.hasOwnProperty('key') || foo.key !== 123) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        let key = Symbol('key')\n        let setterCalls = 0\n        class Foo {\n          [key]\n          set [key](x) { setterCalls++ }\n        }\n        let foo = new Foo()\n        if (setterCalls !== 0 || !foo.hasOwnProperty(key) || foo[key] !== void 0) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        let key = Symbol('key')\n        let setterCalls = 0\n        class Foo {\n          [key] = 123\n          set [key](x) { setterCalls++ }\n        }\n        let foo = new Foo()\n        if (setterCalls !== 0 || !foo.hasOwnProperty(key) || foo[key] !== 123) throw 'fail'\n      `,\n    }),\n\n    // Test class re-assignment\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          foo = () => this\n        }\n        let foo = new Foo()\n        if (foo.foo() !== foo) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          static foo = () => this\n        }\n        let old = Foo\n        let foo = Foo.foo\n        Foo = class Bar {}\n        if (foo() !== old) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          bar = 'works'\n          foo = () => class {\n            [this.bar]\n          }\n        }\n        let foo = new Foo().foo\n        if (!('works' in new (foo()))) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          static bar = 'works'\n          static foo = () => class {\n            [this.bar]\n          }\n        }\n        let foo = Foo.foo\n        Foo = class Bar {}\n        if (!('works' in new (foo()))) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          static foo() { return this.#foo }\n          static #foo = Foo\n        }\n        let old = Foo\n        Foo = class Bar {}\n        if (old.foo() !== old) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          static foo() { return this.#foo() }\n          static #foo() { return Foo }\n        }\n        let old = Foo\n        Foo = class Bar {}\n        if (old.foo() !== old) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        try {\n          class Foo {\n            static foo() { return this.#foo }\n            static #foo = Foo = class Bar {}\n          }\n          throw 'fail'\n        } catch (e) {\n          if (!(e instanceof TypeError))\n            throw e\n        }\n      `,\n    }, {\n      expectedStderr: assignToConstantMessage + `\n\n    in.js:5:26:\n      5 │             static #foo = Foo = class Bar {}\n        ╵                           ~~~\n\n  The symbol \"Foo\" was declared a constant here:\n\n    in.js:3:16:\n      3 │           class Foo {\n        ╵                 ~~~\n\n`,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          static foo() { return this.#foo() }\n          static #foo() { Foo = class Bar{} }\n        }\n        try {\n          Foo.foo()\n          throw 'fail'\n        } catch (e) {\n          if (!(e instanceof TypeError))\n            throw e\n        }\n      `,\n    }, {\n      expectedStderr: assignToConstantMessage + `\n\n    in.js:4:26:\n      4 │           static #foo() { Foo = class Bar{} }\n        ╵                           ~~~\n\n  The symbol \"Foo\" was declared a constant here:\n\n    in.js:2:14:\n      2 │         class Foo {\n        ╵               ~~~\n\n`,\n    }),\n\n    // Issue: https://github.com/evanw/esbuild/issues/901\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class A {\n          pub = this.#priv;\n          #priv() {\n            return 'Inside #priv';\n          }\n        }\n        if (new A().pub() !== 'Inside #priv') throw 'fail';\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class A {\n          static pub = this.#priv;\n          static #priv() {\n            return 'Inside #priv';\n          }\n        }\n        if (A.pub() !== 'Inside #priv') throw 'fail';\n      `,\n    }),\n\n    // Issue: https://github.com/evanw/esbuild/issues/1066\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Test {\n          #x = 2;\n          #y = [];\n          z = 2;\n\n          get x() { return this.#x; }\n          get y() { return this.#y; }\n\n          world() {\n            return [1,[2,3],4];\n          }\n\n          hello() {\n            [this.#x,this.#y,this.z] = this.world();\n          }\n        }\n\n        var t = new Test();\n        t.hello();\n        if (t.x !== 1 || t.y[0] !== 2 || t.y[1] !== 3 || t.z !== 4) throw 'fail';\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      'in.js': `\n        import x from './class'\n        if (x.bar !== 123) throw 'fail'\n      `,\n      'class.js': `\n        class Foo {\n          static foo = 123\n        }\n        export default class extends Foo {\n          static #foo = super.foo\n          static bar = this.#foo\n        }\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle', '--keep-names'].concat(flags), {\n      'in.js': `\n        import x from './class'\n        if (x.bar !== 123) throw 'fail'\n        if (x.name !== 'default') throw 'fail: ' + x.name\n      `,\n      'class.js': `\n        class Foo {\n          static foo = 123\n        }\n        export default class extends Foo {\n          static #foo = super.foo\n          static bar = this.#foo\n        }\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          #a\n          #b\n          #c\n          foo() {\n            [this.#a, this.#b, this.#c] = {\n              [Symbol.iterator]() {\n                let value = 0\n                return {\n                  next() {\n                    return { value: ++value, done: false }\n                  }\n                }\n              }\n            }\n            return [this.#a, this.#b, this.#c].join(' ')\n          }\n        }\n        if (new Foo().foo() !== '1 2 3') throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          #a\n          #b\n          #c\n          #d\n          #e\n          #f\n          foo() {\n            [\n              {x: this.#a},\n              [[, this.#b, ,]],\n              {y: this.#c = 3},\n              {x: this.x, y: this.y, ...this.#d},\n              [, , ...this.#e],\n              [{x: [{y: [this.#f]}]}],\n            ] = [\n              {x: 1},\n              [[1, 2, 3]],\n              {},\n              {x: 2, y: 3, z: 4, w: 5},\n              [4, 5, 6, 7, 8],\n              [{x: [{y: [9]}]}],\n            ]\n            return JSON.stringify([\n              this.#a,\n              this.#b,\n              this.#c,\n              this.#d,\n              this.#e,\n              this.#f,\n            ])\n          }\n        }\n        if (new Foo().foo() !== '[1,2,3,{\"z\":4,\"w\":5},[6,7,8],9]') throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          values = []\n          set #a(a) { this.values.push(a) }\n          set #b(b) { this.values.push(b) }\n          set #c(c) { this.values.push(c) }\n          set #d(d) { this.values.push(d) }\n          set #e(e) { this.values.push(e) }\n          set #f(f) { this.values.push(f) }\n          foo() {\n            [\n              {x: this.#a},\n              [[, this.#b, ,]],\n              {y: this.#c = 3},\n              {x: this.x, y: this.y, ...this.#d},\n              [, , ...this.#e],\n              [{x: [{y: [this.#f]}]}],\n            ] = [\n              {x: 1},\n              [[1, 2, 3]],\n              {},\n              {x: 2, y: 3, z: 4, w: 5},\n              [4, 5, 6, 7, 8],\n              [{x: [{y: [9]}]}],\n            ]\n            return JSON.stringify(this.values)\n          }\n        }\n        if (new Foo().foo() !== '[1,2,3,{\"z\":4,\"w\":5},[6,7,8],9]') throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          #a\n          #b\n          #c\n          #d\n          #e\n          #f\n          foo() {\n            for ([\n              {x: this.#a},\n              [[, this.#b, ,]],\n              {y: this.#c = 3},\n              {x: this.x, y: this.y, ...this.#d},\n              [, , ...this.#e],\n              [{x: [{y: [this.#f]}]}],\n            ] of [[\n              {x: 1},\n              [[1, 2, 3]],\n              {},\n              {x: 2, y: 3, z: 4, w: 5},\n              [4, 5, 6, 7, 8],\n              [{x: [{y: [9]}]}],\n            ]]) ;\n            return JSON.stringify([\n              this.#a,\n              this.#b,\n              this.#c,\n              this.#d,\n              this.#e,\n              this.#f,\n            ])\n          }\n        }\n        if (new Foo().foo() !== '[1,2,3,{\"z\":4,\"w\":5},[6,7,8],9]') throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          #a\n          #b() {}\n          get #c() {}\n          set #d(x) {}\n          bar(x) {\n            return #a in x && #b in x && #c in x && #d in x\n          }\n        }\n        let foo = new Foo()\n        if (foo.bar(foo) !== true || foo.bar(Foo) !== false) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          #a\n          #b() {}\n          get #c() {}\n          set #d(x) {}\n          bar(x) {\n            return #a in x && #b in x && #c in x && #d in x\n          }\n        }\n        function mustFail(x) {\n          let foo = new Foo()\n          try {\n            foo.bar(x)\n          } catch (e) {\n            if (e instanceof TypeError) return\n            throw e\n          }\n          throw 'fail'\n        }\n        mustFail(null)\n        mustFail(void 0)\n        mustFail(0)\n        mustFail('')\n        mustFail(Symbol('x'))\n      `,\n    }),\n\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        let b = 0\n        class Foo {\n          a\n          [(() => ++b)()]\n          declare c\n          declare [(() => ++b)()]\n        }\n        const foo = new Foo\n        if (b !== 1 || 'a' in foo || 1 in foo || 'c' in foo || 2 in foo) throw 'fail'\n      `,\n      'tsconfig.json': `{\n\t\t\t\t\"compilerOptions\": {\n\t\t\t\t\t\"useDefineForClassFields\": false\n\t\t\t\t}\n\t\t\t}`,\n    }),\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        let b = 0\n        class Foo {\n          a\n          [(() => ++b)()]\n          declare c\n          declare [(() => ++b)()]\n        }\n        const foo = new Foo\n        if (b !== 1 || !('a' in foo) || !(1 in foo) || 'c' in foo || 2 in foo) throw 'fail'\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"useDefineForClassFields\": true\n        }\n      }`\n    }),\n\n    // Validate \"branding\" behavior\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Base { constructor(x) { return x } }\n        class Derived extends Base { #y = true; static is(z) { return z.#y } }\n        const foo = {}\n        try { Derived.is(foo); throw 'fail 1' } catch (e) { if (e === 'fail 1') throw e }\n        new Derived(foo)\n        if (Derived.is(foo) !== true) throw 'fail 2'\n        try { new Derived(foo); throw 'fail 3' } catch (e) { if (e === 'fail 3') throw e }\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Base { constructor(x) { return x } }\n        class Derived extends Base { #y = true; static is(z) { return z.#y } }\n        const foo = 123\n        try { Derived.is(foo); throw 'fail 1' } catch (e) { if (e === 'fail 1') throw e }\n        new Derived(foo)\n        try { Derived.is(foo); throw 'fail 2' } catch (e) { if (e === 'fail 2') throw e }\n        new Derived(foo)\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Base { constructor(x) { return x } }\n        class Derived extends Base { #y = true; static is(z) { return z.#y } }\n        const foo = null\n        try { Derived.is(foo); throw 'fail 1' } catch (e) { if (e === 'fail 1') throw e }\n        new Derived(foo)\n        try { Derived.is(foo); throw 'fail 2' } catch (e) { if (e === 'fail 2') throw e }\n        new Derived(foo)\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Base { constructor(x) { return x } }\n        class Derived extends Base { #y() { return true } static is(z) { return z.#y } }\n        const foo = {}\n        try { Derived.is(foo); throw 'fail 1' } catch (e) { if (e === 'fail 1') throw e }\n        new Derived(foo)\n        if (Derived.is(foo)() !== true) throw 'fail 2'\n        try { new Derived(foo); throw 'fail 3' } catch (e) { if (e === 'fail 3') throw e }\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Base { constructor(x) { return x } }\n        class Derived extends Base { #y() {} static is(z) { return z.#y } }\n        const foo = 123\n        try { Derived.is(foo); throw 'fail 1' } catch (e) { if (e === 'fail 1') throw e }\n        new Derived(foo)\n        try { Derived.is(foo); throw 'fail 2' } catch (e) { if (e === 'fail 2') throw e }\n        new Derived(foo)\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Base { constructor(x) { return x } }\n        class Derived extends Base { #y() {} static is(z) { return z.#y } }\n        const foo = null\n        try { Derived.is(foo); throw 'fail 1' } catch (e) { if (e === 'fail 1') throw e }\n        new Derived(foo)\n        try { Derived.is(foo); throw 'fail 2' } catch (e) { if (e === 'fail 2') throw e }\n        new Derived(foo)\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        let a, b, c, x = 123\n        class Foo {\n          #a() { a = { this: this, args: arguments } }\n          get #b() { return function () { b = { this: this, args: arguments } } }\n          #c = function () { c = { this: this, args: arguments } }\n          bar() { (this.#a)\\`a\\${x}aa\\`; (this.#b)\\`b\\${x}bb\\`; (this.#c)\\`c\\${x}cc\\` }\n        }\n        new Foo().bar()\n        if (!(a.this instanceof Foo) || !(b.this instanceof Foo) || !(c.this instanceof Foo)) throw 'fail'\n        if (JSON.stringify([...a.args, ...b.args, ...c.args]) !== JSON.stringify([['a', 'aa'], 123, ['b', 'bb'], 123, ['c', 'cc'], 123])) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        let a, b, c, x = 123\n        class Foo {\n          #a() { a = { this: this, args: arguments } }\n          get #b() { return function () { b = { this: this, args: arguments } } }\n          #c = function () { c = { this: this, args: arguments } }\n          bar() { (0, this.#a)\\`a\\${x}aa\\`; (0, this.#b)\\`b\\${x}bb\\`; (0, this.#c)\\`c\\${x}cc\\` }\n        }\n        new Foo().bar()\n        if (a.this instanceof Foo || b.this instanceof Foo || c.this instanceof Foo) throw 'fail'\n        if (JSON.stringify([...a.args, ...b.args, ...c.args]) !== JSON.stringify([['a', 'aa'], 123, ['b', 'bb'], 123, ['c', 'cc'], 123])) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        let it\n        class Foo {\n          constructor() { it = this; it = it.#fn\\`\\` }\n          get #fn() { it = null; return function() { return this } }\n        }\n        new Foo\n        if (!(it instanceof Foo)) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        let it\n        class Foo {\n          constructor() { it = this; it = it.#fn() }\n          get #fn() { it = null; return function() { return this } }\n        }\n        new Foo\n        if (!(it instanceof Foo)) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        const order = []\n        class Test {\n          static first = order.push(1)\n          static { order.push(2) }\n          static third = order.push(3)\n        }\n        if ('' + order !== '1,2,3') throw 'fail: ' + order\n      `,\n    }),\n\n    // Check side effect order of computed properties with assign semantics\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        const order = []\n        const check = x => {\n          order.push(x)\n          return x\n        }\n        class Foo {\n          [check('a')]() {}\n          [check('b')];\n          [check('c')] = 1;\n          [check('d')]() {}\n          static [check('e')];\n          static [check('f')] = 2;\n          static [check('g')]() {}\n          [check('h')];\n        }\n        class Bar {\n          // Use a class with a single static field to check that the computed\n          // key isn't deferred outside of the class body while the initializer\n          // is left inside.\n          static [check('i')] = 3\n        }\n        if (order + '' !== 'a,b,c,d,e,f,g,h,i') throw 'fail: ' + order\n        const foo = new Foo\n        if (typeof foo.a !== 'function') throw 'fail: a'\n        if ('b' in foo) throw 'fail: b'\n        if (foo.c !== 1) throw 'fail: c'\n        if (typeof foo.d !== 'function') throw 'fail: d'\n        if ('e' in Foo) throw 'fail: e'\n        if (Foo.f !== 2) throw 'fail: f'\n        if (typeof Foo.g !== 'function') throw 'fail: g'\n        if ('h' in foo) throw 'fail: h'\n        if (Bar.i !== 3) throw 'fail: i'\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"useDefineForClassFields\": false,\n        },\n      }`,\n    }),\n\n    // Check for the specific reference behavior of TypeScript's implementation\n    // of \"experimentalDecorators\" with class decorators, which mutate the class\n    // binding itself. This test passes on TypeScript's implementation.\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        let oldFoo: any\n        let e: any\n        let decorate = (foo: any): any => {\n          oldFoo = foo\n          return { foo }\n        }\n        @decorate\n        class newFoo {\n          a(): any { return [newFoo, () => newFoo] }\n          b: any = [newFoo, () => newFoo]\n          static c(): any { return [newFoo, () => newFoo] }\n          static d: any = [newFoo, () => newFoo]\n          static { e = [newFoo, () => newFoo] }\n        }\n        const fail: string[] = []\n        if ((newFoo as any).foo !== oldFoo) fail.push('decorate')\n        if (new oldFoo().a()[0] !== newFoo) fail.push('a[0]')\n        if (new oldFoo().a()[1]() !== newFoo) fail.push('a[1]')\n        if (new oldFoo().b[0] !== newFoo) fail.push('b[0]')\n        if (new oldFoo().b[1]() !== newFoo) fail.push('b[1]')\n        if (oldFoo.c()[0] !== newFoo) fail.push('c[0]')\n        if (oldFoo.c()[1]() !== newFoo) fail.push('c[1]')\n        if (oldFoo.d[0] !== oldFoo) fail.push('d[0]')\n        if (oldFoo.d[1]() !== newFoo) fail.push('d[1]')\n        if (e[0] !== oldFoo) fail.push('e[0]')\n        if (e[1]() !== newFoo) fail.push('e[1]')\n        if (fail.length) throw 'fail: ' + fail\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true,\n        },\n      }`,\n    }),\n\n    // https://github.com/evanw/esbuild/issues/2800\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Baz {\n          static thing = \"value\"\n          static {\n            this.prototype.thing = \"value\"\n          }\n        }\n        if (new Baz().thing !== 'value') throw 'fail'\n      `,\n    }),\n\n    // https://github.com/evanw/esbuild/issues/2950\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class SomeClass {\n          static { this.One = 1; }\n          static { this.Two = SomeClass.One * 2; }\n        }\n        if (SomeClass.Two !== 2) throw 'fail'\n      `,\n    }),\n\n    // https://github.com/evanw/esbuild/issues/3025\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo {\n          static {\n            Foo.prototype.foo = 'foo'\n          }\n        }\n        if (new Foo().foo !== 'foo') throw 'fail'\n      `,\n    }),\n\n    // https://github.com/evanw/esbuild/issues/2389\n    test(['in.js', '--outfile=node.js', '--minify', '--keep-names'].concat(flags), {\n      'in.js': `\n        class DirectlyReferenced { static type = DirectlyReferenced.name }\n        class ReferencedViaThis { static type = this.name }\n        class StaticBlockViaThis { static { if (this.name !== 'StaticBlockViaThis') throw 'fail StaticBlockViaThis: ' + this.name } }\n        class StaticBlockDirectly { static { if (StaticBlockDirectly.name !== 'StaticBlockDirectly') throw 'fail StaticBlockDirectly: ' + StaticBlockDirectly.name } }\n        if (DirectlyReferenced.type !== 'DirectlyReferenced') throw 'fail DirectlyReferenced: ' + DirectlyReferenced.type\n        if (ReferencedViaThis.type !== 'ReferencedViaThis') throw 'fail ReferencedViaThis: ' + ReferencedViaThis.type\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', '--minify', '--keep-names'].concat(flags), {\n      'in.js': `\n        let ReferencedViaThis = class { static type = this.name }\n        let StaticBlockViaThis = class { static { if (this.name !== 'StaticBlockViaThis') throw 'fail StaticBlockViaThis: ' + this.name } }\n        if (ReferencedViaThis.type !== 'ReferencedViaThis') throw 'fail ReferencedViaThis: ' + ReferencedViaThis.type\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', '--keep-names', '--format=esm'].concat(flags), {\n      'in.js': `\n        // Cause the names in the inner scope to be renamed\n        if (\n          typeof DirectlyReferenced !== 'undefined' ||\n          typeof ReferencedViaThis !== 'undefined' ||\n          typeof StaticBlockViaThis !== 'undefined' ||\n          typeof StaticBlockDirectly !== 'undefined'\n        ) {\n          throw 'fail'\n        }\n        function innerScope() {\n          class DirectlyReferenced { static type = DirectlyReferenced.name }\n          class ReferencedViaThis { static type = this.name }\n          class StaticBlockViaThis { static { if (this.name !== 'StaticBlockViaThis') throw 'fail StaticBlockViaThis: ' + this.name } }\n          class StaticBlockDirectly { static { if (StaticBlockDirectly.name !== 'StaticBlockDirectly') throw 'fail StaticBlockDirectly: ' + StaticBlockDirectly.name } }\n          if (DirectlyReferenced.type !== 'DirectlyReferenced') throw 'fail DirectlyReferenced: ' + DirectlyReferenced.type\n          if (ReferencedViaThis.type !== 'ReferencedViaThis') throw 'fail ReferencedViaThis: ' + ReferencedViaThis.type\n        }\n        innerScope()\n      `,\n    }),\n\n    // https://github.com/evanw/esbuild/issues/2629\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        // Stub out the decorator so TSC doesn't complain.\n        const someDecorator = (): PropertyDecorator => () => {};\n\n        class Foo {\n          static message = 'Hello world!';\n          static msgLength = Foo.message.length;\n\n          @someDecorator()\n          foo() {}\n        }\n\n        if (Foo.message !== 'Hello world!' || Foo.msgLength !== 12) throw 'fail'\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true,\n        },\n      }`,\n    }),\n\n    // https://github.com/evanw/esbuild/issues/2045\n    test(['in.js', '--bundle', '--outfile=node.js', '--log-override:class-name-will-throw=silent'].concat(flags), {\n      'in.js': `\n        let A = {a: 'a'} // This should not be used\n\n        let field\n        try { class A { static a = 1; [A.a] = 2 } } catch (err) { field = err }\n        if (!field) throw 'fail: field'\n\n        let staticField\n        try { class A { static a = 1; static [A.a] = 2 } } catch (err) { staticField = err }\n        if (!staticField) throw 'fail: staticField'\n\n        let method\n        try { class A { static a = 1; [A.a]() { return 2 } } } catch (err) { method = err }\n        if (!method) throw 'fail: method'\n\n        let staticMethod\n        try { class A { static a = 1; static [A.a]() { return 2 } } } catch (err) { staticMethod = err }\n        if (!staticMethod) throw 'fail: staticMethod'\n      `,\n    }),\n    test(['in.js', '--bundle', '--outfile=node.js', '--log-override:class-name-will-throw=silent'].concat(flags), {\n      'in.js': `\n        let A = {a: 'a'} // This should not be used\n\n        let field\n        try { class A { capture = () => A; static a = 1; [A.a] = 2 } } catch (err) { field = err }\n        if (!field) throw 'fail: field'\n\n        let staticField\n        try { class A { capture = () => A; static a = 1; static [A.a] = 2 } } catch (err) { staticField = err }\n        if (!staticField) throw 'fail: staticField'\n\n        let method\n        try { class A { capture = () => A; static a = 1; [A.a]() { return 2 } } } catch (err) { method = err }\n        if (!method) throw 'fail: method'\n\n        let staticMethod\n        try { class A { capture = () => A; static a = 1; static [A.a]() { return 2 } } } catch (err) { staticMethod = err }\n        if (!staticMethod) throw 'fail: staticMethod'\n      `,\n    }),\n    test(['in.js', '--bundle', '--outfile=node.js', '--log-override:class-name-will-throw=silent'].concat(flags), {\n      'in.js': `\n        let A = {a: 'a'} // This should not be used\n        let temp\n\n        let field\n        try { temp = (class A { static a = 1; [A.a] = 2 }) } catch (err) { field = err }\n        if (!field) throw 'fail: field'\n\n        let staticField\n        try { temp = (class A { static a = 1; static [A.a] = 2 }) } catch (err) { staticField = err }\n        if (!staticField) throw 'fail: staticField'\n\n        let method\n        try { temp = (class A { static a = 1; [A.a]() { return 2 } }) } catch (err) { method = err }\n        if (!method) throw 'fail: method'\n\n        let staticMethod\n        try { temp = (class A { static a = 1; static [A.a]() { return 2 } }) } catch (err) { staticMethod = err }\n        if (!staticMethod) throw 'fail: staticMethod'\n      `,\n    }),\n    test(['in.js', '--bundle', '--outfile=node.js', '--log-override:class-name-will-throw=silent'].concat(flags), {\n      'in.js': `\n        let A = {a: 'a'} // This should not be used\n        let temp\n\n        let field\n        try { temp = (class A { capture = () => A; static a = 1; [A.a] = 2 }) } catch (err) { field = err }\n        if (!field) throw 'fail: field'\n\n        let staticField\n        try { temp = (class A { capture = () => A; static a = 1; static [A.a] = 2 }) } catch (err) { staticField = err }\n        if (!staticField) throw 'fail: staticField'\n\n        let method\n        try { temp = (class A { capture = () => A; static a = 1; [A.a]() { return 2 } }) } catch (err) { method = err }\n        if (!method) throw 'fail: method'\n\n        let staticMethod\n        try { temp = (class A { capture = () => A; static a = 1; static [A.a]() { return 2 } }) } catch (err) { staticMethod = err }\n        if (!staticMethod) throw 'fail: staticMethod'\n      `,\n    }),\n\n    // https://github.com/evanw/esbuild/issues/3326\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        const log: string[] = []\n        class Test1 {\n          static deco(target: any, key: any, desc: any): any { log.push('Test1') }\n          @Test1.deco static test(): void { }\n        }\n        class Test2 {\n          static deco(target: any, key: any, desc: any): any { log.push('Test2') }\n          @Test2.deco static test(): Test2 { return new Test2(); }\n        }\n        @Test3.deco\n        class Test3 {\n          static deco(target: any): any { log.push('Test3') }\n        }\n        if (log + '' !== 'Test1,Test2,Test3') throw 'fail: ' + log\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true,\n        },\n      }`,\n    }),\n\n    // https://github.com/evanw/esbuild/issues/3394\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        const dec = (arg: number): ParameterDecorator => () => { answer = arg }\n        let answer = 0\n\n        class Foo {\n          static #foo = 123\n          static bar = 234\n          method(@dec(Foo.#foo + Foo.bar) arg: any) {\n          }\n        }\n\n        if (answer !== 357) throw 'fail: ' + answer\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true,\n        },\n      }`,\n    }),\n\n    // https://github.com/evanw/esbuild/issues/3538\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo extends Array {\n          pass = false\n          constructor() {\n            let base = super()\n            this.pass = base === this &&\n              base instanceof Array &&\n              base instanceof Foo\n          }\n        }\n        if (!new Foo().pass) throw 'fail'\n      `,\n    }),\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        class Foo extends Array {\n          pass: boolean = false\n          constructor() {\n            let base = super()\n            this.pass = base === this &&\n              base instanceof Array &&\n              base instanceof Foo\n          }\n        }\n        if (!new Foo().pass) throw 'fail'\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"useDefineForClassFields\": false,\n        },\n      }`,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Bar {\n          constructor(x) {\n            return x\n          }\n        }\n        class Foo extends Bar {\n          pass = false\n          constructor() {\n            let base = super([])\n            this.pass = base === this &&\n              base instanceof Array &&\n              !(base instanceof Foo)\n          }\n        }\n        if (!new Foo().pass) throw 'fail'\n      `,\n    }),\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        class Bar {\n          constructor(x) {\n            return x\n          }\n        }\n        class Foo extends Bar {\n          pass: boolean = false\n          constructor() {\n            let base = super([])\n            this.pass = base === this &&\n              base instanceof Array &&\n              !(base instanceof Foo)\n          }\n        }\n        if (!new Foo().pass) throw 'fail'\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"useDefineForClassFields\": false,\n        },\n      }`,\n    }),\n\n    // https://github.com/evanw/esbuild/issues/3559\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        class Foo extends Array {\n          #private: any\n          pass: any\n          constructor() {\n            super()\n            this.pass = true\n          }\n        }\n        if (!new Foo().pass) throw 'fail'\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"useDefineForClassFields\": false,\n        },\n      }`,\n    }),\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        class Foo extends Array {\n          #private: any\n          pass = true\n          constructor() {\n            super()\n          }\n        }\n        if (!new Foo().pass) throw 'fail'\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"useDefineForClassFields\": false,\n        },\n      }`,\n    }),\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        class Foo extends Array {\n          #private = 123\n          pass: any\n          constructor() {\n            super()\n            this.pass = true\n          }\n        }\n        if (!new Foo().pass) throw 'fail'\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"useDefineForClassFields\": false,\n        },\n      }`,\n    }),\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        class Foo extends Array {\n          #private = 123\n          pass: any = true\n          constructor() {\n            super()\n          }\n        }\n        if (!new Foo().pass) throw 'fail'\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"useDefineForClassFields\": false,\n        },\n      }`,\n    }),\n\n    // https://github.com/evanw/esbuild/issues/3913\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        function testDecorator(_value: unknown, context: DecoratorContext) {\n          if (context.kind === \"field\") {\n            return () => \"dec-ok\";\n          }\n        }\n\n        class DecClass {\n          @testDecorator\n          decInit = \"init\";\n\n          @testDecorator\n          decNoInit: any;\n        }\n\n        const foo = new DecClass\n        if (foo.decInit !== 'dec-ok') throw 'fail: decInit'\n        if (foo.decNoInit !== 'dec-ok') throw 'fail: decNoInit'\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"useDefineForClassFields\": false,\n        },\n      }`,\n    }),\n\n    // Check various combinations of flags\n    test(['in.ts', '--outfile=node.js', '--supported:class-field=false'].concat(flags), {\n      'in.ts': `\n        class Foo {\n          accessor foo = 1\n          static accessor bar = 2\n        }\n        if (new Foo().foo !== 1 || Foo.bar !== 2) throw 'fail'\n      `,\n    }),\n    test(['in.ts', '--outfile=node.js', '--supported:class-static-field=false'].concat(flags), {\n      'in.ts': `\n        class Foo {\n          accessor foo = 1\n          static accessor bar = 2\n        }\n        if (new Foo().foo !== 1 || Foo.bar !== 2) throw 'fail'\n      `,\n    }),\n\n    // Make sure class body side effects aren't reordered\n    test(['in.ts', '--outfile=node.js', '--supported:class-field=false'].concat(flags), {\n      'in.ts': `\n        const log = []\n        class Foo extends (log.push(1), Object) {\n          [log.push(2)] = 123;\n          [log.push(3)] = 123;\n        }\n        if (log + '' !== '1,2,3') throw 'fail: ' + log\n      `,\n    }),\n    test(['in.ts', '--outfile=node.js', '--supported:class-static-field=false'].concat(flags), {\n      'in.ts': `\n        const log = []\n        class Foo extends (log.push(1), Object) {\n          static [log.push(2)] = 123;\n          static [log.push(3)] = 123;\n        }\n        if (log + '' !== '1,2,3') throw 'fail: ' + log\n      `,\n    }),\n    test(['in.ts', '--outfile=node.js', '--supported:class-field=false'].concat(flags), {\n      'in.ts': `\n        const log = []\n        class Foo {\n          static [log.push(1)]() {}\n          [log.push(2)] = 123;\n          static [log.push(3)]() {}\n        }\n        if (log + '' !== '1,2,3') throw 'fail: ' + log\n      `,\n    }),\n    test(['in.ts', '--outfile=node.js', '--supported:class-static-field=false'].concat(flags), {\n      'in.ts': `\n        const log = []\n        class Foo {\n          [log.push(1)]() {}\n          static [log.push(2)] = 123;\n          [log.push(3)]() {}\n        }\n        if (log + '' !== '1,2,3') throw 'fail: ' + log\n      `,\n    }),\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        const log = []\n        class Foo {\n          @(() => { log.push(3) }) [log.push(1)]() {}\n          [log.push(2)] = 123;\n        }\n        if (log + '' !== '1,2,3') throw 'fail: ' + log\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true\n        }\n      }`,\n    }),\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        const log = []\n        class Foo {\n          @(() => { log.push(3) }) static [log.push(1)]() {}\n          static [log.push(2)] = 123;\n        }\n        if (log + '' !== '1,2,3') throw 'fail: ' + log\n      `,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true\n        }\n      }`,\n    }),\n\n    // Check \"await\" in computed property names\n    test(['in.ts', '--outfile=node.js', '--format=cjs', '--supported:class-field=false'].concat(flags), {\n      'in.ts': `\n        exports.async = async () => {\n          class Foo {\n            [await Promise.resolve('foo')] = 123\n          }\n          if (new Foo().foo !== 123) throw 'fail'\n        }\n      `,\n    }, { async: true }),\n    test(['in.ts', '--outfile=node.js', '--format=cjs', '--supported:class-static-field=false'].concat(flags), {\n      'in.ts': `\n        exports.async = async () => {\n          class Foo {\n            static [await Promise.resolve('foo')] = 123\n          }\n          if (Foo.foo !== 123) throw 'fail'\n        }\n      `,\n    }, { async: true }),\n  )\n\n  // https://github.com/evanw/esbuild/issues/3177\n  const input3177 = `\n    const props: Record<number, string> = {}\n    const dec = (n: number) => (_: any, prop: string): void => {\n      props[n] = prop\n    }\n    class Foo {\n      @dec(1) prop1: any\n      @dec(2) prop2_: any\n      @dec(3) ['prop3']: any\n      @dec(4) ['prop4_']: any\n      @dec(5) [/* @__KEY__ */ 'prop5']: any\n      @dec(6) [/* @__KEY__ */ 'prop6_']: any\n    }\n    if (props[1] !== 'prop1') throw 'fail 1: ' + props[1]\n    if (props[2] !== /* @__KEY__ */ 'prop2_') throw 'fail 2: ' + props[2]\n    if (props[3] !== 'prop3') throw 'fail 3: ' + props[3]\n    if (props[4] !== 'prop4_') throw 'fail 4: ' + props[4]\n    if (props[5] !== 'prop5') throw 'fail 5: ' + props[5]\n    if (props[6] !== /* @__KEY__ */ 'prop6_') throw 'fail 6: ' + props[6]\n  `\n  tests.push(\n    test(['in.ts', '--outfile=node.js', '--mangle-props=_'].concat(flags), {\n      'in.ts': input3177,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true,\n          \"useDefineForClassFields\": true,\n        },\n      }`,\n    }),\n    test(['in.ts', '--outfile=node.js', '--mangle-props=_'].concat(flags), {\n      'in.ts': input3177,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true,\n          \"useDefineForClassFields\": false,\n        },\n      }`,\n    }),\n  )\n\n  // Test TypeScript experimental decorators and accessors\n  const experimentalDecoratorsAndAccessors = `\n    const log: string[] = []\n    const decorate = (target: any, key: string, descriptor: PropertyDescriptor): any => {\n      if (descriptor.get === void 0) throw 'fail: get ' + key\n      if (descriptor.set === void 0) throw 'fail: set ' + key\n      return {\n        get() {\n          const value = descriptor.get!.call(this)\n          log.push('get ' + key + ' ' + value)\n          return value\n        },\n        set(value: any) {\n          descriptor.set!.call(this, value)\n          log.push('set ' + key + ' ' + value)\n        },\n      }\n    }\n\n    // With esbuild's accessor syntax\n    class Foo {\n      @decorate accessor x = 1\n      @decorate static accessor y = 2\n    }\n    const foo = new Foo\n    if (++foo.x !== 2) throw 'fail: foo.x'\n    if (++Foo.y !== 3) throw 'fail: foo.y'\n    if (log + '' !== 'get x 1,set x 2,get y 2,set y 3') throw 'fail: foo ' + log\n\n    log.length = 0\n\n    // Without esbuild's accessor syntax (should be the same)\n    class Bar {\n      #x = 1\n      @decorate get x() { return this.#x }\n      set x(_) { this.#x = _ }\n      static #y = 2\n      @decorate static get y() { return this.#y }\n      static set y(_) { this.#y = _ }\n    }\n    const bar = new Bar\n    if (++bar.x !== 2) throw 'fail: bar.x'\n    if (++Bar.y !== 3) throw 'fail: Bar.y'\n    if (log + '' !== 'get x 1,set x 2,get y 2,set y 3') throw 'fail: bar ' + log\n  `\n  tests.push(\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': experimentalDecoratorsAndAccessors,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true,\n          \"useDefineForClassFields\": true,\n        },\n      }`,\n    }),\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': experimentalDecoratorsAndAccessors,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"experimentalDecorators\": true,\n          \"useDefineForClassFields\": false,\n        },\n      }`,\n    }),\n  )\n\n  // Test class accessors\n  const classAccessorTest = `\n    const checkAccessor = (obj, key, value) => {\n      if (obj[key] !== value) throw 'fail: ' + key + ' get'\n      obj[key] = null\n      if (obj[key] !== null) throw 'fail: ' + key + ' set'\n    }\n\n    checkAccessor(new class { accessor undef }, 'undef')\n    checkAccessor(new class { accessor undef2; x = 0 }, 'undef2')\n    checkAccessor(new class { accessor def = 123 }, 'def', 123)\n    checkAccessor(new class { accessor def2 = 123; x = 0 }, 'def2', 123)\n\n    checkAccessor(class { static accessor staticUndef }, 'staticUndef')\n    checkAccessor(class { static accessor staticUndef2; x = 0 }, 'staticUndef2')\n    checkAccessor(class { static accessor staticDef = 123 }, 'staticDef', 123)\n    checkAccessor(class { static accessor staticDef2 = 123; x = 0 }, 'staticDef2', 123)\n\n    checkAccessor(new class { accessor #x; get privateUndef() { return this.#x } set privateUndef(_) { this.#x = _ } }, 'privateUndef')\n    checkAccessor(new class { accessor #x; get privateUndef2() { return this.#x } set privateUndef2(_) { this.#x = _ } x = 0 }, 'privateUndef2')\n    checkAccessor(new class { accessor #x = 123; get privateDef() { return this.#x } set privateDef(_) { this.#x = _ } }, 'privateDef', 123)\n    checkAccessor(new class { accessor #x = 123; get privateDef2() { return this.#x } set privateDef2(_) { this.#x = _ } x = 0 }, 'privateDef2', 123)\n\n    checkAccessor(class { static accessor #x; static get staticPrivateUndef() { return this.#x } static set staticPrivateUndef(_) { this.#x = _ } }, 'staticPrivateUndef')\n    checkAccessor(class { static accessor #x; static get staticPrivateUndef2() { return this.#x } static set staticPrivateUndef2(_) { this.#x = _ } x = 0 }, 'staticPrivateUndef2')\n    checkAccessor(class { static accessor #x = 123; static get staticPrivateDef() { return this.#x } static set staticPrivateDef(_) { this.#x = _ } }, 'staticPrivateDef', 123)\n    checkAccessor(class { static accessor #x = 123; static get staticPrivateDef2() { return this.#x } static set staticPrivateDef2(_) { this.#x = _ } x = 0 }, 'staticPrivateDef2', 123)\n\n    const order = []\n    const checkOrder = x => {\n      order.push(x)\n      return x\n    }\n    class Foo {\n      a = checkOrder(8)\n      #a = checkOrder(9)\n      accessor b = checkOrder(10)\n      accessor #b = checkOrder(11)\n      accessor [checkOrder(1)] = checkOrder(12)\n      static c = checkOrder(3)\n      static #c = checkOrder(4)\n      static accessor d = checkOrder(5)\n      static accessor #d = checkOrder(6)\n      static accessor [checkOrder(2)] = checkOrder(7)\n      'get#a'() { return this.#a }\n      'get#b'() { return this.#b }\n      static 'get#c'() { return this.#c }\n      static 'get#d'() { return this.#d }\n    }\n    const foo = new Foo\n    if (order + '' !== '1,2,3,4,5,6,7,8,9,10,11,12') throw 'fail: ' + order\n    if (foo.a !== 8) throw 'fail: a'\n    if (foo['get#a']() !== 9) throw 'fail: #a'\n    if (foo.b !== 10) throw 'fail: b'\n    if (foo['get#b']() !== 11) throw 'fail: #b'\n    if (foo[1] !== 12) throw 'fail: 1'\n    if (Foo.c !== 3) throw 'fail: c'\n    if (Foo['get#c']() !== 4) throw 'fail: #c'\n    if (Foo.d !== 5) throw 'fail: d'\n    if (Foo['get#d']() !== 6) throw 'fail: #d'\n    if (Foo[2] !== 7) throw 'fail: 2'\n  `\n  tests.push(\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': classAccessorTest,\n    }),\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': classAccessorTest,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"useDefineForClassFields\": true,\n        }\n      }`,\n    }),\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': classAccessorTest,\n      'tsconfig.json': `{\n        \"compilerOptions\": {\n          \"useDefineForClassFields\": false,\n        }\n      }`,\n    }),\n  )\n\n  // https://github.com/evanw/esbuild/issues/3768\n  tests.push(\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        const bar = x => x\n        class Foo {\n          @bar baz() { return Foo }\n        }\n        if (new Foo().baz() !== Foo) throw 'fail'\n      `,\n    }),\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        class Foo {}\n        const bar = x => x\n        class Baz extends Foo {\n          @bar baz() { return Baz }\n        }\n        if (new Baz().baz() !== Baz) throw 'fail'\n      `,\n    }),\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        const bar = () => x => x\n        class Foo {\n          @bar baz = Foo\n        }\n        if (new Foo().baz !== Foo) throw 'fail'\n      `,\n    }),\n    test(['in.ts', '--outfile=node.js'].concat(flags), {\n      'in.ts': `\n        class Foo {}\n        const bar = () => x => x\n        class Baz extends Foo {\n          @bar baz = Baz\n        }\n        if (new Baz().baz !== Baz) throw 'fail'\n      `,\n    }),\n  )\n}\n\n// Async lowering tests\nfor (let flags of [[], ['--target=es2017'], ['--target=es6']]) {\n  tests.push(\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        exports.async = async () => {\n          const value = await Promise.resolve(123)\n          if (value !== 123) throw 'fail'\n\n          let uncaught = false\n          let caught = false\n          try {\n            await Promise.reject(234)\n            uncaught = true\n          } catch (error) {\n            if (error !== 234) throw 'fail'\n            caught = true\n          }\n          if (uncaught || !caught) throw 'fail'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        async function throws() {\n          throw 123\n        }\n        exports.async = () => throws().then(\n          () => {\n            throw 'fail'\n          },\n          error => {\n            if (error !== 123) throw 'fail'\n          }\n        )\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        exports.async = async () => {\n          \"use strict\"\n          async function foo() {\n            return [this, arguments]\n          }\n          let [t, a] = await foo.call(0, 1, 2, 3)\n          if (t !== 0 || a.length !== 3 || a[0] !== 1 || a[1] !== 2 || a[2] !== 3) throw 'fail'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        let couldThrow = () => 'b'\n        exports.async = async () => {\n          \"use strict\"\n          async function f0() {\n            let bar = async (x, y) => [x, y, this, arguments]\n            return await bar('a', 'b')\n          }\n          async function f1() {\n            let bar = async (x, ...y) => [x, y[0], this, arguments]\n            return await bar('a', 'b')\n          }\n          async function f2() {\n            let bar = async (x, y = 'b') => [x, y, this, arguments]\n            return await bar('a')\n          }\n          async function f3() {\n            let bar = async (x, y = couldThrow()) => [x, y, this, arguments]\n            return await bar('a')\n          }\n          async function f4() {\n            let bar = async (x, y = couldThrow()) => (() => [x, y, this, arguments])()\n            return await bar('a')\n          }\n          async function f5() {\n            let bar = () => async (x, y = couldThrow()) => [x, y, this, arguments]\n            return await bar()('a')\n          }\n          async function f6() {\n            let bar = async () => async (x, y = couldThrow()) => [x, y, this, arguments]\n            return await (await bar())('a')\n          }\n          for (let foo of [f0, f1, f2, f3, f4, f5, f6]) {\n            let [x, y, t, a] = await foo.call(0, 1, 2, 3)\n            if (x !== 'a' || y !== 'b' || t !== 0 || a.length !== 3 || a[0] !== 1 || a[1] !== 2 || a[2] !== 3) throw 'fail'\n          }\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // The async transform must not change the argument count\n      'in.js': `\n        async function a(x, y) {}\n        if (a.length !== 2) throw 'fail: a'\n\n        async function b(x, y = x(), z) {}\n        if (b.length !== 1) throw 'fail: b'\n\n        async function c(x, y, ...z) {}\n        if (c.length !== 2) throw 'fail: c'\n\n        let d = async function(x, y) {}\n        if (d.length !== 2) throw 'fail: d'\n\n        let e = async function(x, y = x(), z) {}\n        if (e.length !== 1) throw 'fail: e'\n\n        let f = async function(x, y, ...z) {}\n        if (f.length !== 2) throw 'fail: f'\n\n        let g = async (x, y) => {}\n        if (g.length !== 2) throw 'fail: g'\n\n        let h = async (x, y = x(), z) => {}\n        if (h.length !== 1) throw 'fail: h'\n\n        let i = async (x, y, ...z) => {}\n        if (i.length !== 2) throw 'fail: i'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Functions must be able to access default arguments past the last non-default argument\n      'in.js': `\n        exports.async = async () => {\n          async function a(x, y = 0) { return y }\n          let b = async function(x, y = 0) { return y }\n          let c = async (x, y = 0) => y\n          for (let fn of [a, b, c]) {\n            if ((await fn('x', 'y')) !== 'y') throw 'fail: ' + fn\n          }\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Functions must be able to access arguments past the argument count using \"arguments\"\n      'in.js': `\n        exports.async = async () => {\n          async function a() { return arguments[2] }\n          async function b(x, y) { return arguments[2] }\n          async function c(x, y = x) { return arguments[2] }\n          let d = async function() { return arguments[2] }\n          let e = async function(x, y) { return arguments[2] }\n          let f = async function(x, y = x) { return arguments[2] }\n          for (let fn of [a, b, c, d, e, f]) {\n            if ((await fn('x', 'y', 'z')) !== 'z') throw 'fail: ' + fn\n          }\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Functions must be able to access arguments past the argument count using a rest argument\n      'in.js': `\n        exports.async = async () => {\n          async function a(...rest) { return rest[3] }\n          async function b(x, y, ...rest) { return rest[1] }\n          async function c(x, y = x, ...rest) { return rest[1] }\n          let d = async function(...rest) { return rest[3] }\n          let e = async function(x, y, ...rest) { return rest[1] }\n          let f = async function(x, y = x, ...rest) { return rest[1] }\n          let g = async (...rest) => rest[3]\n          let h = async (x, y, ...rest) => rest[1]\n          let i = async (x, y = x, ...rest) => rest[1]\n          for (let fn of [a, b, c, d, e, f, g, h, i]) {\n            if ((await fn(11, 22, 33, 44)) !== 44) throw 'fail: ' + fn\n          }\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Functions must be able to modify arguments using \"arguments\"\n      'in.js': `\n        exports.async = async () => {\n          async function a(x) { let y = [x, arguments[0]]; arguments[0] = 'y'; return y.concat(x, arguments[0]) }\n          let b = async function(x) { let y = [x, arguments[0]]; arguments[0] = 'y'; return y.concat(x, arguments[0]) }\n          for (let fn of [a, b]) {\n            let values = (await fn('x')) + ''\n            if (values !== 'x,x,y,y') throw 'fail: ' + values\n          }\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Errors in the evaluation of async function arguments should reject the resulting promise\n      'in.js': `\n        exports.async = async () => {\n          let expected = new Error('You should never see this error')\n          let throws = () => { throw expected }\n          async function a(x, y = throws()) {}\n          async function b({ [throws()]: x }) {}\n          let c = async function (x, y = throws()) {}\n          let d = async function ({ [throws()]: x }) {}\n          let e = async (x, y = throws()) => {}\n          let f = async ({ [throws()]: x }) => {}\n          for (let fn of [a, b, c, d, e, f]) {\n            let promise = fn({})\n            try {\n              await promise\n            } catch (e) {\n              if (e === expected) continue\n            }\n            throw 'fail: ' + fn\n          }\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Functions handle \"super\" property accesses in classes\n      'in.js': `\n        exports.async = async () => {\n          let counter = 0\n          let returnsBar = () => (++counter, 'bar')\n          class Base {\n            foo(x, y) {\n              return x + y\n            }\n            get bar() { return this._bar }\n            set bar(x) { this._bar = x }\n          }\n          class Derived extends Base {\n            get bar() { throw 'fail' }\n            set bar(x) { throw 'fail' }\n            async test(foo, bar) {\n              return [\n                await super.foo,\n                await super[foo],\n\n                ([super.bar] = [BigInt('1')])[0],\n                ([super[bar]] = [BigInt('2')])[0],\n                ([super[returnsBar()]] = [BigInt('3')])[0],\n\n                (super.bar = BigInt('4')),\n                (super.bar += BigInt('2')),\n                super.bar++,\n                ++super.bar,\n\n                (super[bar] = BigInt('9')),\n                (super[bar] += BigInt('2')),\n                super[bar]++,\n                ++super[bar],\n\n                (super[returnsBar()] = BigInt('14')),\n                (super[returnsBar()] += BigInt('2')),\n                super[returnsBar()]++,\n                ++super[returnsBar()],\n\n                await super.foo.name,\n                await super[foo].name,\n                await super.foo?.name,\n                await super[foo]?.name,\n                await super._foo?.name,\n                await super['_' + foo]?.name,\n\n                await super.foo(1, 2),\n                await super[foo](1, 2),\n                await super.foo?.(1, 2),\n                await super[foo]?.(1, 2),\n                await super._foo?.(1, 2),\n                await super['_' + foo]?.(1, 2),\n              ]\n            }\n          }\n          let d = new Derived\n          let observed = await d.test('foo', 'bar')\n          let expected = [\n            d.foo, d.foo,\n            BigInt('1'), BigInt('2'), BigInt('3'),\n            BigInt('4'), BigInt('6'), BigInt('6'), BigInt('8'),\n            BigInt('9'), BigInt('11'), BigInt('11'), BigInt('13'),\n            BigInt('14'), BigInt('16'), BigInt('16'), BigInt('18'),\n            d.foo.name, d.foo.name, d.foo.name, d.foo.name, void 0, void 0,\n            3, 3, 3, 3, void 0, void 0,\n          ]\n          observed.push(d._bar, Base.prototype._bar, counter)\n          expected.push(BigInt('18'), undefined, 5)\n          for (let i = 0; i < expected.length; i++) {\n            if (observed[i] !== expected[i]) {\n              console.log(i, observed[i], expected[i])\n              throw 'fail'\n            }\n          }\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Functions handle \"super\" property accesses in objects\n      'in.js': `\n        exports.async = async () => {\n          let counter = 0\n          let returnsBar = () => (++counter, 'bar')\n          let b = {\n            foo(x, y) {\n              return x + y\n            },\n            get bar() { return this._bar },\n            set bar(x) { this._bar = x },\n          }\n          let d = {\n            get bar() { throw 'fail' },\n            set bar(x) { throw 'fail' },\n            async test(foo, bar) {\n              return [\n                await super.foo,\n                await super[foo],\n\n                ([super.bar] = [BigInt('1')])[0],\n                ([super[bar]] = [BigInt('2')])[0],\n                ([super[returnsBar()]] = [BigInt('3')])[0],\n\n                (super.bar = BigInt('4')),\n                (super.bar += BigInt('2')),\n                super.bar++,\n                ++super.bar,\n\n                (super[bar] = BigInt('9')),\n                (super[bar] += BigInt('2')),\n                super[bar]++,\n                ++super[bar],\n\n                (super[returnsBar()] = BigInt('14')),\n                (super[returnsBar()] += BigInt('2')),\n                super[returnsBar()]++,\n                ++super[returnsBar()],\n\n                await super.foo.name,\n                await super[foo].name,\n                await super.foo?.name,\n                await super[foo]?.name,\n                await super._foo?.name,\n                await super['_' + foo]?.name,\n\n                await super.foo(1, 2),\n                await super[foo](1, 2),\n                await super.foo?.(1, 2),\n                await super[foo]?.(1, 2),\n                await super._foo?.(1, 2),\n                await super['_' + foo]?.(1, 2),\n              ]\n            },\n          }\n          Object.setPrototypeOf(d, b)\n          let observed = await d.test('foo', 'bar')\n          let expected = [\n            d.foo, d.foo,\n            BigInt('1'), BigInt('2'), BigInt('3'),\n            BigInt('4'), BigInt('6'), BigInt('6'), BigInt('8'),\n            BigInt('9'), BigInt('11'), BigInt('11'), BigInt('13'),\n            BigInt('14'), BigInt('16'), BigInt('16'), BigInt('18'),\n            d.foo.name, d.foo.name, d.foo.name, d.foo.name, void 0, void 0,\n            3, 3, 3, 3, void 0, void 0,\n          ]\n          observed.push(d._bar, b._bar, counter)\n          expected.push(BigInt('18'), undefined, 5)\n          for (let i = 0; i < expected.length; i++) {\n            if (observed[i] !== expected[i]) {\n              console.log(i, observed[i], expected[i])\n              throw 'fail'\n            }\n          }\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Handle \"super\" property accesses in static class fields\n      'in.js': `\n        exports.async = async () => {\n          let counter = 0\n          let returnsBar = () => (++counter, 'bar')\n          class Base {\n            static foo(x, y) {\n              return x + y\n            }\n            static get bar() { return this._bar }\n            static set bar(x) { this._bar = x }\n          }\n          class Derived extends Base {\n            static get bar() { throw 'fail' }\n            static set bar(x) { throw 'fail' }\n            static test = async (foo, bar) => {\n              return [\n                await super.foo,\n                await super[foo],\n\n                ([super.bar] = [BigInt('1')])[0],\n                ([super[bar]] = [BigInt('2')])[0],\n                ([super[returnsBar()]] = [BigInt('3')])[0],\n\n                (super.bar = BigInt('4')),\n                (super.bar += BigInt('2')),\n                super.bar++,\n                ++super.bar,\n\n                (super[bar] = BigInt('9')),\n                (super[bar] += BigInt('2')),\n                super[bar]++,\n                ++super[bar],\n\n                (super[returnsBar()] = BigInt('14')),\n                (super[returnsBar()] += BigInt('2')),\n                super[returnsBar()]++,\n                ++super[returnsBar()],\n\n                await super.foo.name,\n                await super[foo].name,\n                await super.foo?.name,\n                await super[foo]?.name,\n                await super._foo?.name,\n                await super['_' + foo]?.name,\n\n                await super.foo(1, 2),\n                await super[foo](1, 2),\n                await super.foo?.(1, 2),\n                await super[foo]?.(1, 2),\n                await super._foo?.(1, 2),\n                await super['_' + foo]?.(1, 2),\n              ]\n            }\n          }\n          let observed = await Derived.test('foo', 'bar')\n          let expected = [\n            Derived.foo, Derived.foo,\n            BigInt('1'), BigInt('2'), BigInt('3'),\n            BigInt('4'), BigInt('6'), BigInt('6'), BigInt('8'),\n            BigInt('9'), BigInt('11'), BigInt('11'), BigInt('13'),\n            BigInt('14'), BigInt('16'), BigInt('16'), BigInt('18'),\n            Derived.foo.name, Derived.foo.name, Derived.foo.name, Derived.foo.name, void 0, void 0,\n            3, 3, 3, 3, void 0, void 0,\n          ]\n          observed.push(Derived._bar, Base._bar, counter)\n          expected.push(BigInt('18'), undefined, 5)\n          for (let i = 0; i < expected.length; i++) {\n            if (observed[i] !== expected[i]) {\n              console.log(i, observed[i], expected[i])\n              throw 'fail'\n            }\n          }\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Handle \"super\" property accesses in async arrow functions\n      'in.js': `\n        exports.async = async () => {\n          const log = [];\n          class Base {\n            foo(x) { log.push(x) }\n          }\n          class Derived extends Base {\n            foo1() { return async () => super.foo('foo1') }\n            foo2() { return async () => () => super.foo('foo2') }\n            foo3() { return () => async () => super.foo('foo3') }\n            foo4() { return async () => async () => super.foo('foo4') }\n            bar1 = async () => super.foo('bar1')\n            bar2 = async () => () => super.foo('bar2')\n            bar3 = () => async () => super.foo('bar3')\n            bar4 = async () => async () => super.foo('bar4')\n            async baz1() { return () => super.foo('baz1') }\n            async baz2() { return () => () => super.foo('baz2') }\n\n            #foo1() { return async () => super.foo('foo1') }\n            #foo2() { return async () => () => super.foo('foo2') }\n            #foo3() { return () => async () => super.foo('foo3') }\n            #foo4() { return async () => async () => super.foo('foo4') }\n            #bar1 = async () => super.foo('bar1')\n            #bar2 = async () => () => super.foo('bar2')\n            #bar3 = () => async () => super.foo('bar3')\n            #bar4 = async () => async () => super.foo('bar4')\n            async #baz1() { return () => super.foo('baz1') }\n            async #baz2() { return () => () => super.foo('baz2') }\n\n            async run() {\n              await derived.foo1()();\n              (await derived.foo2()())();\n              await derived.foo3()()();\n              await (await derived.foo4()())();\n              await derived.bar1();\n              (await derived.bar2())();\n              await derived.bar3()();\n              await (await derived.bar4())();\n              (await derived.baz1())();\n              (await derived.baz2())()();\n\n              await this.#foo1()();\n              (await this.#foo2()())();\n              await this.#foo3()()();\n              await (await this.#foo4()())();\n              await this.#bar1();\n              (await this.#bar2())();\n              await this.#bar3()();\n              await (await this.#bar4())();\n              (await this.#baz1())();\n              (await this.#baz2())()();\n            }\n          }\n          let derived = new Derived;\n          await derived.run();\n          let observed = log.join(',');\n          let expected = 'foo1,foo2,foo3,foo4,bar1,bar2,bar3,bar4,baz1,baz2';\n          expected += ',' + expected;\n          if (observed !== expected) throw 'fail: ' + observed + ' != ' + expected;\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Handle \"super\" property writes in async arrow functions\n      'in.js': `\n        exports.async = async () => {\n          const log = [];\n          class Base {\n            set foo(x) { log.push(x) }\n          }\n          class Derived extends Base {\n            foo1() { return async () => super.foo = 'foo1' }\n            foo2() { return async () => () => super.foo = 'foo2' }\n            foo3() { return () => async () => super.foo = 'foo3' }\n            foo4() { return async () => async () => super.foo = 'foo4' }\n            bar1 = async () => super.foo = 'bar1'\n            bar2 = async () => () => super.foo = 'bar2'\n            bar3 = () => async () => super.foo = 'bar3'\n            bar4 = async () => async () => super.foo = 'bar4'\n            async baz1() { return () => super.foo = 'baz1' }\n            async baz2() { return () => () => super.foo = 'baz2' }\n\n            #foo1() { return async () => super.foo = 'foo1' }\n            #foo2() { return async () => () => super.foo = 'foo2' }\n            #foo3() { return () => async () => super.foo = 'foo3' }\n            #foo4() { return async () => async () => super.foo = 'foo4' }\n            #bar1 = async () => super.foo = 'bar1'\n            #bar2 = async () => () => super.foo = 'bar2'\n            #bar3 = () => async () => super.foo = 'bar3'\n            #bar4 = async () => async () => super.foo = 'bar4'\n            async #baz1() { return () => super.foo = 'baz1' }\n            async #baz2() { return () => () => super.foo = 'baz2' }\n\n            async run() {\n              await this.foo1()();\n              (await this.foo2()())();\n              await this.foo3()()();\n              await (await this.foo4()())();\n              await this.bar1();\n              (await this.bar2())();\n              await this.bar3()();\n              await (await this.bar4())();\n              (await this.baz1())();\n              (await this.baz2())()();\n\n              await this.#foo1()();\n              (await this.#foo2()())();\n              await this.#foo3()()();\n              await (await this.#foo4()())();\n              await this.#bar1();\n              (await this.#bar2())();\n              await this.#bar3()();\n              await (await this.#bar4())();\n              (await this.#baz1())();\n              (await this.#baz2())()();\n            }\n          }\n          let derived = new Derived;\n          await derived.run();\n          let observed = log.join(',');\n          let expected = 'foo1,foo2,foo3,foo4,bar1,bar2,bar3,bar4,baz1,baz2';\n          expected += ',' + expected;\n          if (observed !== expected) throw 'fail: ' + observed + ' != ' + expected;\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Handle static \"super\" property accesses in async arrow functions\n      'in.js': `\n        exports.async = async () => {\n          const log = [];\n          class Base {\n            static foo(x) { log.push(x) }\n          }\n          class Derived extends Base {\n            static foo1() { return async () => super.foo('foo1') }\n            static foo2() { return async () => () => super.foo('foo2') }\n            static foo3() { return () => async () => super.foo('foo3') }\n            static foo4() { return async () => async () => super.foo('foo4') }\n            static bar1 = async () => super.foo('bar1')\n            static bar2 = async () => () => super.foo('bar2')\n            static bar3 = () => async () => super.foo('bar3')\n            static bar4 = async () => async () => super.foo('bar4')\n            static async baz1() { return () => super.foo('baz1') }\n            static async baz2() { return () => () => super.foo('baz2') }\n\n            static #foo1() { return async () => super.foo('foo1') }\n            static #foo2() { return async () => () => super.foo('foo2') }\n            static #foo3() { return () => async () => super.foo('foo3') }\n            static #foo4() { return async () => async () => super.foo('foo4') }\n            static #bar1 = async () => super.foo('bar1')\n            static #bar2 = async () => () => super.foo('bar2')\n            static #bar3 = () => async () => super.foo('bar3')\n            static #bar4 = async () => async () => super.foo('bar4')\n            static async #baz1() { return () => super.foo('baz1') }\n            static async #baz2() { return () => () => super.foo('baz2') }\n\n            static async run() {\n              await this.foo1()();\n              (await this.foo2()())();\n              await this.foo3()()();\n              await (await this.foo4()())();\n              await this.bar1();\n              (await this.bar2())();\n              await this.bar3()();\n              await (await this.bar4())();\n              (await this.baz1())();\n              (await this.baz2())()();\n\n              await this.#foo1()();\n              (await this.#foo2()())();\n              await this.#foo3()()();\n              await (await this.#foo4()())();\n              await this.#bar1();\n              (await this.#bar2())();\n              await this.#bar3()();\n              await (await this.#bar4())();\n              (await this.#baz1())();\n              (await this.#baz2())()();\n            }\n          }\n          await Derived.run();\n          let observed = log.join(',');\n          let expected = 'foo1,foo2,foo3,foo4,bar1,bar2,bar3,bar4,baz1,baz2';\n          expected += ',' + expected;\n          if (observed !== expected) throw 'fail: ' + observed + ' != ' + expected;\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Handle static \"super\" property writes in async arrow functions\n      'in.js': `\n        exports.async = async () => {\n          const log = [];\n          class Base {\n            static set foo(x) { log.push(x) }\n          }\n          class Derived extends Base {\n            static foo1() { return async () => super.foo = 'foo1' }\n            static foo2() { return async () => () => super.foo = 'foo2' }\n            static foo3() { return () => async () => super.foo = 'foo3' }\n            static foo4() { return async () => async () => super.foo = 'foo4' }\n            static bar1 = async () => super.foo = 'bar1'\n            static bar2 = async () => () => super.foo = 'bar2'\n            static bar3 = () => async () => super.foo = 'bar3'\n            static bar4 = async () => async () => super.foo = 'bar4'\n            static async baz1() { return () => super.foo = 'baz1' }\n            static async baz2() { return () => () => super.foo = 'baz2' }\n\n            static #foo1() { return async () => super.foo = 'foo1' }\n            static #foo2() { return async () => () => super.foo = 'foo2' }\n            static #foo3() { return () => async () => super.foo = 'foo3' }\n            static #foo4() { return async () => async () => super.foo = 'foo4' }\n            static #bar1 = async () => super.foo = 'bar1'\n            static #bar2 = async () => () => super.foo = 'bar2'\n            static #bar3 = () => async () => super.foo = 'bar3'\n            static #bar4 = async () => async () => super.foo = 'bar4'\n            static async #baz1() { return () => super.foo = 'baz1' }\n            static async #baz2() { return () => () => super.foo = 'baz2' }\n\n            static async run() {\n              await this.foo1()();\n              (await this.foo2()())();\n              await this.foo3()()();\n              await (await this.foo4()())();\n              await this.bar1();\n              (await this.bar2())();\n              await this.bar3()();\n              await (await this.bar4())();\n              (await this.baz1())();\n              (await this.baz2())()();\n\n              await this.#foo1()();\n              (await this.#foo2()())();\n              await this.#foo3()()();\n              await (await this.#foo4()())();\n              await this.#bar1();\n              (await this.#bar2())();\n              await this.#bar3()();\n              await (await this.#bar4())();\n              (await this.#baz1())();\n              (await this.#baz2())()();\n            }\n          }\n          await Derived.run();\n          let observed = log.join(',');\n          let expected = 'foo1,foo2,foo3,foo4,bar1,bar2,bar3,bar4,baz1,baz2';\n          expected += ',' + expected;\n          if (observed !== expected) throw 'fail: ' + observed + ' != ' + expected;\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Check various \"super\" edge cases\n      'in.js': `\n        exports.async = async () => {\n          const log = [];\n          let o, Base, Derived;\n\n          ({\n            __proto__: { foo() { log.push(1) } },\n            bar() { super.foo() },\n          }.bar());\n\n          o = { bar() { super.foo() } };\n          o.__proto__ = { foo() { log.push(2) } };\n          o.bar();\n\n          o = {\n            __proto__: { foo() { log.push(3) } },\n            bar() { super.foo() },\n          };\n          ({ bar: o.bar }).bar();\n\n          Base = class { foo() { log.push(4) } };\n          Derived = class extends Base { bar() { super.foo() } };\n          new Derived().bar();\n\n          Base = class {};\n          Derived = class extends Base { bar() { super.foo() } };\n          Derived.prototype.__proto__ = { foo() { log.push(5) } };\n          new Derived().bar();\n\n          Base = class { foo() { log.push(6) } };\n          Derived = class extends Base { bar() { super.foo() } };\n          ({ bar: Derived.prototype.bar }).bar();\n\n          Base = class { foo() { log.push(7) } };\n          Derived = class extends Base { bar() { super.foo() } };\n          Derived.prototype.foo = () => log.push(false);\n          new Derived().bar();\n\n          Base = class { foo() { log.push(8) } };\n          Derived = class extends Base { bar = () => super.foo() };\n          new Derived().bar();\n\n          Base = class { foo() { log.push(9) } };\n          Derived = class extends Base { bar = () => super.foo() };\n          o = new Derived();\n          o.__proto__ = {};\n          o.bar();\n\n          Base = class { static foo() { log.push(10) } };\n          Derived = class extends Base { static bar() { super.foo() } };\n          Derived.bar();\n\n          Base = class { static foo() { log.push(11) } };\n          Derived = class extends Base { static bar() { super.foo() } };\n          ({ bar: Derived.bar }).bar();\n\n          Base = class {};\n          Derived = class extends Base { static bar() { super.foo() } };\n          Derived.__proto__ = { foo() { log.push(12) } };\n          Derived.bar();\n\n          Base = class { static foo() { log.push(13) } };\n          Derived = class extends Base { static bar = () => super.foo() };\n          Derived.bar();\n\n          Base = class { static foo() { log.push(14) } };\n          Derived = class extends Base { static bar = () => super.foo() };\n          ({ bar: Derived.bar }).bar();\n\n          Base = class {};\n          Derived = class extends Base { static bar = () => super.foo() };\n          Derived.__proto__ = { foo() { log.push(15) } };\n          Derived.bar();\n\n          Base = class { foo() { return 'bar' } };\n          Derived = class extends Base { async x() { return class { [super.foo()] = 123 } } };\n          if (new (await new Derived().x())().bar === 123) log.push(16);\n\n          Base = class { foo() { return 'bar' } };\n          Derived = class extends Base { x = async () => class { [super.foo()] = 123 } };\n          if (new (await new Derived().x())().bar === 123) log.push(17);\n\n          Base = class { static foo() { return 'bar' } };\n          Derived = class extends Base { static async x() { return class { [super.foo()] = 123 } } };\n          if (new (await Derived.x())().bar === 123) log.push(18);\n\n          Base = class { static foo() { return 'bar' } };\n          Derived = class extends Base { static x = async () => class { [super.foo()] = 123 } };\n          if (new (await Derived.x())().bar === 123) log.push(19);\n\n          // Check that an captured temporary for object methods has the correct scope\n          o = [];\n          for (let i = 0; i < 3; i++) o.push({\n            __proto__: { foo() { return i } },\n            async bar() { return super.foo() },\n          })\n          for (const x of o) log.push(20 + await x.bar());\n\n          const observed = log.join(',');\n          const expected = '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22';\n          if (observed !== expected) throw 'fail: ' + observed + ' != ' + expected;\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--bundle'].concat(flags), {\n      // Check edge case in https://github.com/evanw/esbuild/issues/2158\n      'in.js': `\n      class Foo {\n        constructor(x) {\n          this.base = x\n        }\n      }\n      class Bar extends Foo {\n        static FOO = 1\n        constructor() {\n          super(2)\n          this.derived = this.#foo + Bar.FOO\n        }\n        #foo = 3\n      }\n      let bar = new Bar\n      if (bar.base !== 2 || bar.derived !== 4) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', '--keep-names', '--bundle'].concat(flags), {\n      // Check default export name preservation with lowered \"super\" inside lowered \"async\"\n      'in.js': `\n        import fn from './export'\n        import pfn from './export-private'\n        if (fn.name !== 'default') throw 'fail: ' + fn.name\n        if (pfn.name !== 'default') throw 'fail: ' + pfn.name\n      `,\n      'export.js': `\n        export default class extends Object {\n          async foo() { super.bar() }\n        }\n      `,\n      'export-private.js': `\n        export default class extends Object {\n          async #foo() { super.bar() }\n        }\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', '--keep-names', '--bundle', '--minify'].concat(flags), {\n      // (minified) Check default export name preservation with lowered \"super\" inside lowered \"async\"\n      'in.js': `\n        import fn from './export'\n        import pfn from './export-private'\n        if (fn.name !== 'default') throw 'fail: ' + fn.name\n        if (pfn.name !== 'default') throw 'fail: ' + pfn.name\n      `,\n      'export.js': `\n        export default class extends Object {\n          async foo() { super.bar() }\n        }\n      `,\n      'export-private.js': `\n        export default class extends Object {\n          async #foo() { super.bar() }\n        }\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Test coverage for a TypeScript bug: https://github.com/microsoft/TypeScript/issues/46580\n      'in.js': `\n        class A {\n          static x = 1\n        }\n        class B extends A {\n          static y = () => super.x\n        }\n        class C {\n          static x = 2\n        }\n        if (B.y() !== 1) throw 'fail'\n        Object.setPrototypeOf(B, C)\n        if (B.y() !== 2) throw 'fail'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Check the behavior of method tear-off\n      'in.js': `\n        exports.async = async () => {\n          class Base {\n            set x(y) {\n              this.foo = 'Base'\n            }\n          }\n          class Derived extends Base {\n            set x(y) {\n              this.foo = 'Derived'\n            }\n            async set(z) {\n              super.x = z\n            }\n          }\n          let base = {\n            set x(y) {\n              this.foo = 'base'\n            }\n          }\n          let derived = Object.create(base)\n          derived.set = new Derived().set\n          await derived.set(123)\n          if (base.foo !== void 0 || derived.foo !== 'Base') throw 'fail'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Check the behavior of static method tear-off\n      'in.js': `\n        exports.async = async () => {\n          class Base {\n            static set x(y) {\n              this.foo = 'Base'\n            }\n          }\n          class Derived extends Base {\n            static set x(y) {\n              this.foo = 'Derived'\n            }\n            static async set(z) {\n              super.x = z\n            }\n          }\n          let base = {\n            set x(y) {\n              this.foo = 'base'\n            }\n          }\n          let derived = Object.create(base)\n          derived.set = Derived.set\n          await derived.set(123)\n          if (base.foo !== void 0 || derived.foo !== 'Base') throw 'fail'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Check the behavior of static field tear-off (no async)\n      'in.js': `\n        exports.async = async () => {\n          class Base {\n            static set x(y) {\n              this.foo = 'Base'\n            }\n          }\n          class Derived extends Base {\n            static set x(y) {\n              this.foo = 'Derived'\n            }\n            static set = z => {\n              super.x = z\n            }\n          }\n          let base = {\n            set x(y) {\n              this.foo = 'base'\n            }\n          }\n          let derived = Object.create(base)\n          derived.set = Derived.set\n          derived.set(123)\n          if (base.foo !== void 0 || Derived.foo !== 'Base') throw 'fail'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      // Check the behavior of static field tear-off (async)\n      'in.js': `\n        exports.async = async () => {\n          class Base {\n            static set x(y) {\n              this.foo = 'Base'\n            }\n          }\n          class Derived extends Base {\n            static set x(y) {\n              this.foo = 'Derived'\n            }\n            static set = async (z) => {\n              super.x = z\n            }\n          }\n          let base = {\n            set x(y) {\n              this.foo = 'base'\n            }\n          }\n          let derived = Object.create(base)\n          derived.set = Derived.set\n          await derived.set(123)\n          if (base.foo !== void 0 || Derived.foo !== 'Base') throw 'fail'\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        class Foo extends (class {\n          foo() {\n            return this\n          }\n        }) {\n          x = async (foo) => [\n            super.foo(),\n            super.foo\\`\\`,\n            super[foo](),\n            super[foo]\\`\\`,\n            super['foo'](),\n            super['foo']\\`\\`,\n            this.#bar(),\n            this.#bar\\`\\`,\n          ]\n          #bar() {\n            return this\n          }\n        }\n        exports.async = async () => {\n          const foo = new Foo\n          for (const bar of await foo.x('foo'))\n            if (foo !== bar)\n              throw 'fail'\n        }\n      `,\n    }, { async: true }),\n\n    // https://github.com/arogozine/LinqToTypeScript/issues/29\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        exports.async = async () => {\n          let total = 0\n        outer:\n          for await (const n of [Promise.resolve(1), Promise.resolve(2), Promise.resolve(5)]) {\n            for (let i = 1; i <= n; i++) {\n              if (i === 4) continue outer\n              total += i\n            }\n          }\n          if (total !== 1 + (1 + 2) + (1 + 2 + 3)) throw 'fail'\n        }\n      `,\n    }, { async: true }),\n\n    // https://github.com/evanw/esbuild/issues/4141\n    test(['in.js', '--outfile=node.js'].concat(flags), {\n      'in.js': `\n        exports.async = () => new Promise((resolve, reject) => {\n          new (class Foo extends class { } {\n            constructor() {\n              let x = 1;\n              (async () => {\n                if (x !== 1) reject('fail 1');  // (1) Sync phase\n                await 1;\n                if (x !== 2) reject('fail 2');  // (2) Async phase\n                resolve();\n              })();\n              super();\n              x = 2;\n            }\n          })();\n        })\n      `,\n    }, { async: true }),\n  )\n}\n\n// Function hoisting tests\ntests.push(\n  test(['in.js', '--outfile=node.js'], {\n    'in.js': `\n      if (1) {\n        function f() {\n          return f\n        }\n        f = null\n      }\n      if (typeof f !== 'function' || f() !== null) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=node.js'], {\n    'in.js': `\n      'use strict'\n      if (1) {\n        function f() {\n          return f\n        }\n        f = null\n      }\n      if (typeof f !== 'undefined') throw 'fail'\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--format=esm'], {\n    'in.js': `\n      export {}\n      if (1) {\n        function f() {\n          return f\n        }\n        f = null\n      }\n      if (typeof f !== 'undefined') throw 'fail'\n    `,\n  }),\n  test(['in.js', '--bundle', '--outfile=node.js'], {\n    'in.js': `\n      if (1) {\n        function f() {\n          return f\n        }\n        f = null\n      }\n      if (typeof f !== 'function' || f() !== null) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--bundle', '--outfile=node.js'], {\n    'in.js': `\n      var f\n      if (1) {\n        function f() {\n          return f\n        }\n        f = null\n      }\n      if (typeof f !== 'function' || f() !== null) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--bundle', '--outfile=node.js'], {\n    'in.js': `\n      'use strict'\n      if (1) {\n        function f() {\n          return f\n        }\n      }\n      if (typeof f !== 'undefined') throw 'fail'\n    `,\n  }),\n  test(['in.js', '--bundle', '--outfile=node.js'], {\n    'in.js': `\n      export {}\n      if (1) {\n        function f() {\n          return f\n        }\n      }\n      if (typeof f !== 'undefined') throw 'fail'\n    `,\n  }),\n  test(['in.js', '--bundle', '--outfile=node.js'], {\n    'in.js': `\n      var f = 1\n      if (1) {\n        function f() {\n          return f\n        }\n        f = null\n      }\n      if (typeof f !== 'function' || f() !== null) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--bundle', '--outfile=node.js'], {\n    'in.js': `\n      'use strict'\n      var f = 1\n      if (1) {\n        function f() {\n          return f\n        }\n      }\n      if (f !== 1) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--bundle', '--outfile=node.js'], {\n    'in.js': `\n      export {}\n      var f = 1\n      if (1) {\n        function f() {\n          return f\n        }\n      }\n      if (f !== 1) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--bundle', '--outfile=node.js'], {\n    'in.js': `\n      import {f, g} from './other'\n      if (f !== void 0 || g !== 'g') throw 'fail'\n    `,\n    'other.js': `\n      'use strict'\n      var f\n      if (1) {\n        function f() {\n          return f\n        }\n      }\n      exports.f = f\n      exports.g = 'g'\n    `,\n  }),\n  test(['in.js', '--bundle', '--outfile=node.js'], {\n    'in.js': `\n      let f = 1\n      // This should not be turned into \"if (1) let f\" because that's a syntax error\n      if (1)\n        function f() {\n          return f\n        }\n      if (f !== 1) throw 'fail'\n    `,\n  }),\n  test(['in.js', '--bundle', '--outfile=node.js'], {\n    'in.js': `\n      x: function f() { return 1 }\n      if (f() !== 1) throw 'fail'\n    `,\n  }),\n  test(['in.ts', '--outfile=node.js'], {\n    'in.ts': `\n      if (1) {\n        var a = 'a'\n        for (var b = 'b'; 0; ) ;\n        for (var c in { c: 0 }) ;\n        for (var d of ['d']) ;\n        for (var e = 'e' in {}) ;\n        function f() { return 'f' }\n      }\n      const observed = JSON.stringify({ a, b, c, d, e, f: f() })\n      const expected = JSON.stringify({ a: 'a', b: 'b', c: 'c', d: 'd', e: 'e', f: 'f' })\n      if (observed !== expected) throw observed\n    `,\n  }),\n  test(['in.ts', '--bundle', '--outfile=node.js'], {\n    'in.ts': `\n      if (1) {\n        var a = 'a'\n        for (var b = 'b'; 0; ) ;\n        for (var c in { c: 0 }) ;\n        for (var d of ['d']) ;\n        for (var e = 'e' in {}) ;\n        function f() { return 'f' }\n      }\n      const observed = JSON.stringify({ a, b, c, d, e, f: f() })\n      const expected = JSON.stringify({ a: 'a', b: 'b', c: 'c', d: 'd', e: 'e', f: 'f' })\n      if (observed !== expected) throw observed\n    `,\n  }),\n  test(['in.js', '--outfile=node.js', '--keep-names'], {\n    'in.js': `\n      var f\n      if (1) function f() { return f }\n      if (typeof f !== 'function' || f.name !== 'f') throw 'fail: ' + f.name\n    `,\n  }),\n  test(['in.js', '--bundle', '--outfile=node.js', '--keep-names'], {\n    'in.js': `\n      var f\n      if (1) function f() { return f }\n      if (typeof f !== 'function' || f.name !== 'f') throw 'fail: ' + f.name\n    `,\n  }),\n  test(['in.ts', '--outfile=node.js', '--keep-names'], {\n    'in.ts': `\n      if (1) {\n        var a = 'a'\n        for (var b = 'b'; 0; ) ;\n        for (var c in { c: 0 }) ;\n        for (var d of ['d']) ;\n        for (var e = 'e' in {}) ;\n        function f() {}\n      }\n      const observed = JSON.stringify({ a, b, c, d, e, f: f.name })\n      const expected = JSON.stringify({ a: 'a', b: 'b', c: 'c', d: 'd', e: 'e', f: 'f' })\n      if (observed !== expected) throw observed\n    `,\n  }),\n  test(['in.ts', '--bundle', '--outfile=node.js', '--keep-names'], {\n    'in.ts': `\n      if (1) {\n        var a = 'a'\n        for (var b = 'b'; 0; ) ;\n        for (var c in { c: 0 }) ;\n        for (var d of ['d']) ;\n        for (var e = 'e' in {}) ;\n        function f() {}\n      }\n      const observed = JSON.stringify({ a, b, c, d, e, f: f.name })\n      const expected = JSON.stringify({ a: 'a', b: 'b', c: 'c', d: 'd', e: 'e', f: 'f' })\n      if (observed !== expected) throw observed\n    `,\n  }),\n)\n\n// Object rest pattern tests\ntests.push(\n  // Test the correctness of side effect order for the TypeScript namespace exports\n  test(['in.ts', '--outfile=node.js'], {\n    'in.ts': `\n      function fn() {\n        let trail = []\n        let t = k => (trail.push(k), k)\n        let [\n          { [t('a')]: a } = { a: t('x') },\n          { [t('b')]: b, ...c } = { b: t('y') },\n          { [t('d')]: d } = { d: t('z') },\n        ] = [{ a: 1 }, { b: 2, bb: 3 }]\n        return JSON.stringify({a, b, c, d, trail})\n      }\n      namespace ns {\n        let trail = []\n        let t = k => (trail.push(k), k)\n        export let [\n          { [t('a')]: a } = { a: t('x') },\n          { [t('b')]: b, ...c } = { b: t('y') },\n          { [t('d')]: d } = { d: t('z') },\n        ] = [{ a: 1 }, { b: 2, bb: 3 }]\n        export let result = JSON.stringify({a, b, c, d, trail})\n      }\n      if (fn() !== ns.result) throw 'fail'\n    `,\n  }),\n\n  // Test the array and object rest patterns in TypeScript namespace exports\n  test(['in.ts', '--outfile=node.js'], {\n    'in.ts': `\n      let obj = {};\n      ({a: obj.a, ...obj.b} = {a: 1, b: 2, c: 3});\n      [obj.c, , ...obj.d] = [1, 2, 3];\n      ({e: obj.e, f: obj.f = 'f'} = {e: 'e'});\n      [obj.g, , obj.h = 'h'] = ['g', 'gg'];\n      namespace ns {\n        export let {a, ...b} = {a: 1, b: 2, c: 3};\n        export let [c, , ...d] = [1, 2, 3];\n        export let {e, f = 'f'} = {e: 'e'};\n        export let [g, , h = 'h'] = ['g', 'gg'];\n      }\n      if (JSON.stringify(obj) !== JSON.stringify(ns)) throw 'fail'\n    `,\n  }),\n\n  // Test the initializer being overwritten\n  test(['in.ts', '--outfile=node.js', '--target=es6'], {\n    'in.ts': `\n      var z = {x: {z: 'z'}, y: 'y'}, {x: z, ...y} = z\n      if (y.y !== 'y' || z.z !== 'z') throw 'fail'\n    `,\n  }),\n  test(['in.ts', '--outfile=node.js', '--target=es6'], {\n    'in.ts': `\n      var z = {x: {x: 'x'}, y: 'y'}, {[(z = {z: 'z'}, 'x')]: x, ...y} = z\n      if (x.x !== 'x' || y.y !== 'y' || z.z !== 'z') throw 'fail'\n    `,\n  }),\n)\n\n// Code splitting tests\ntests.push(\n  // Code splitting via sharing\n  test(['a.js', 'b.js', '--outdir=out', '--splitting', '--format=esm', '--bundle'], {\n    'a.js': `\n      import * as ns from './common'\n      export let a = 'a' + ns.foo\n    `,\n    'b.js': `\n      import * as ns from './common'\n      export let b = 'b' + ns.foo\n    `,\n    'common.js': `\n      export let foo = 123\n    `,\n    'node.js': `\n      import {a} from './out/a.js'\n      import {b} from './out/b.js'\n      if (a !== 'a123' || b !== 'b123') throw 'fail'\n    `,\n  }),\n\n  // Code splitting via sharing with name templates\n  test([\n    'a.js', 'b.js', '--outdir=out', '--splitting', '--format=esm', '--bundle',\n    '--entry-names=[name][dir]x', '--chunk-names=[name]/[hash]',\n  ], {\n    'a.js': `\n      import * as ns from './common'\n      export let a = 'a' + ns.foo\n    `,\n    'b.js': `\n      import * as ns from './common'\n      export let b = 'b' + ns.foo\n    `,\n    'common.js': `\n      export let foo = 123\n    `,\n    'node.js': `\n      import {a} from './out/a/x.js'\n      import {b} from './out/b/x.js'\n      if (a !== 'a123' || b !== 'b123') throw 'fail'\n    `,\n  }),\n\n  // Code splitting via sharing with name templates\n  test([\n    'pages/a/index.js', 'pages/b/index.js', '--outbase=.',\n    '--outdir=out', '--splitting', '--format=esm', '--bundle',\n    '--entry-names=[name][dir]y', '--chunk-names=[name]/[hash]',\n  ], {\n    'pages/a/index.js': `\n      import * as ns from '../common'\n      export let a = 'a' + ns.foo\n    `,\n    'pages/b/index.js': `\n      import * as ns from '../common'\n      export let b = 'b' + ns.foo\n    `,\n    'pages/common.js': `\n      export let foo = 123\n    `,\n    'node.js': `\n      import {a} from './out/index/pages/ay.js'\n      import {b} from './out/index/pages/by.js'\n      if (a !== 'a123' || b !== 'b123') throw 'fail'\n    `,\n  }),\n\n  // Code splitting via ES6 module double-imported with sync and async imports\n  test(['a.js', '--outdir=out', '--splitting', '--format=esm', '--bundle'], {\n    'a.js': `\n      import * as ns1 from './b'\n      export default async function () {\n        const ns2 = await import('./b')\n        return [ns1.foo, -ns2.foo]\n      }\n    `,\n    'b.js': `\n      export let foo = 123\n    `,\n    'node.js': `\n      export let async = async () => {\n        const {default: fn} = await import('./out/a.js')\n        const [a, b] = await fn()\n        if (a !== 123 || b !== -123) throw 'fail'\n      }\n    `,\n  }, { async: true }),\n\n  // Code splitting via CommonJS module double-imported with sync and async imports\n  test(['a.js', '--outdir=out', '--splitting', '--format=esm', '--bundle'], {\n    'a.js': `\n      import * as ns1 from './b.cjs'\n      export default async function () {\n        const ns2 = await import('./b.cjs')\n        return [ns1.foo, -ns2.default.foo]\n      }\n    `,\n    'b.cjs': `\n      exports.foo = 123\n    `,\n    'node.js': `\n      export let async = async () => {\n        const {default: fn} = await import('./out/a.js')\n        const [a, b] = await fn()\n        if (a !== 123 || b !== -123) throw 'fail'\n      }\n    `,\n  }, { async: true }),\n\n  // Identical output chunks should not be shared\n  test(['a.js', 'b.js', 'c.js', '--outdir=out', '--splitting', '--format=esm', '--bundle', '--minify'], {\n    'a.js': `\n      import {foo as common1} from './common1'\n      import {foo as common2} from './common2'\n      export let a = [common1, common2]\n    `,\n    'b.js': `\n      import {foo as common2} from './common2'\n      import {foo as common3} from './common3'\n      export let b = [common2, common3]\n    `,\n    'c.js': `\n      import {foo as common3} from './common3'\n      import {foo as common1} from './common1'\n      export let c = [common3, common1]\n    `,\n    'common1.js': `\n      export let foo = {}\n    `,\n    'common2.js': `\n      export let foo = {}\n    `,\n    'common3.js': `\n      export let foo = {}\n    `,\n    'node.js': `\n      import {a} from './out/a.js'\n      import {b} from './out/b.js'\n      import {c} from './out/c.js'\n      if (a[0] === a[1]) throw 'fail'\n      if (b[0] === b[1]) throw 'fail'\n      if (c[0] === c[1]) throw 'fail'\n    `,\n  }),\n  test(['a.js', 'b.js', 'c.js', '--outdir=out', '--splitting', '--format=esm', '--bundle', '--minify'], {\n    'a.js': `\n      export {a} from './common'\n    `,\n    'b.js': `\n      export {b} from './common'\n    `,\n    'c.js': `\n      export {a as ca, b as cb} from './common'\n    `,\n    'common.js': `\n      export let a = {}\n      export let b = {}\n    `,\n    'node.js': `\n      import {a} from './out/a.js'\n      import {b} from './out/b.js'\n      import {ca, cb} from './out/c.js'\n      if (a === b || ca === cb || a !== ca || b !== cb) throw 'fail'\n    `,\n  }),\n\n  // \"sideEffects\": false\n  // https://github.com/evanw/esbuild/issues/1081\n  test(['entry.js', '--outdir=out', '--splitting', '--format=esm', '--bundle', '--chunk-names=[name]'], {\n    'entry.js': `import('./a'); import('./b')`,\n    'a.js': `import { bar } from './shared'; bar()`,\n    'b.js': `import './shared'`,\n    'shared.js': `import { foo } from './foo'; export let bar = foo`,\n    'foo/index.js': `export let foo = () => {}`,\n    'foo/package.json': `{ \"sideEffects\": false }`,\n    'node.js': `\n      import path from 'path'\n      import url from 'url'\n      const __dirname = path.dirname(url.fileURLToPath(import.meta.url))\n\n      // Read the output files\n      import fs from 'fs'\n      const a = fs.readFileSync(path.join(__dirname, 'out', 'a.js'), 'utf8')\n      const chunk = fs.readFileSync(path.join(__dirname, 'out', 'chunk.js'), 'utf8')\n\n      // Make sure the two output files don't import each other\n      import assert from 'assert'\n      assert.notStrictEqual(chunk.includes('a.js'), a.includes('chunk.js'), 'chunks must not import each other')\n    `,\n  }),\n  test(['entry.js', '--outdir=out', '--splitting', '--format=esm', '--bundle'], {\n    'entry.js': `await import('./a'); await import('./b')`,\n    'a.js': `import { bar } from './shared'; bar()`,\n    'b.js': `import './shared'`,\n    'shared.js': `import { foo } from './foo'; export let bar = foo`,\n    'foo/index.js': `export let foo = () => {}`,\n    'foo/package.json': `{ \"sideEffects\": false }`,\n    'node.js': `\n      // This must not crash\n      import './out/entry.js'\n    `,\n  }),\n\n  // Code splitting where only one entry point uses the runtime\n  // https://github.com/evanw/esbuild/issues/1123\n  test(['a.js', 'b.js', '--outdir=out', '--splitting', '--format=esm', '--bundle'], {\n    'a.js': `\n      import * as foo from './shared'\n      export default foo\n    `,\n    'b.js': `\n      import {bar} from './shared'\n      export default bar\n    `,\n    'shared.js': `\n      export function foo() {\n        return 'foo'\n      }\n      export function bar() {\n        return 'bar'\n      }\n    `,\n    'node.js': `\n      import a from './out/a.js'\n      import b from './out/b.js'\n      if (a.foo() !== 'foo') throw 'fail'\n      if (b() !== 'bar') throw 'fail'\n    `,\n  }),\n\n  // Code splitting with a dynamic import that imports a CSS file\n  // https://github.com/evanw/esbuild/issues/1125\n  test(['parent.js', '--outdir=out', '--splitting', '--format=esm', '--bundle'], {\n    'parent.js': `\n      // This should import the primary JS chunk, not the secondary CSS chunk\n      await import('./child')\n    `,\n    'child.js': `\n      import './foo.css'\n    `,\n    'foo.css': `\n      body {\n        color: black;\n      }\n    `,\n    'node.js': `\n      import './out/parent.js'\n    `,\n  }),\n\n  // Code splitting with an entry point that exports two different\n  // symbols with the same original name (minified and not minified)\n  // https://github.com/evanw/esbuild/issues/1201\n  test(['entry1.js', 'entry2.js', '--outdir=out', '--splitting', '--format=esm', '--bundle'], {\n    'test1.js': `export const sameName = { test: 1 }`,\n    'test2.js': `export const sameName = { test: 2 }`,\n    'entry1.js': `\n      export { sameName } from './test1.js'\n      export { sameName as renameVar } from './test2.js'\n    `,\n    'entry2.js': `export * from './entry1.js'`,\n    'node.js': `\n      import { sameName as a, renameVar as b } from './out/entry1.js'\n      import { sameName as c, renameVar as d } from './out/entry2.js'\n      if (a.test !== 1 || b.test !== 2 || c.test !== 1 || d.test !== 2) throw 'fail'\n    `,\n  }),\n  test(['entry1.js', 'entry2.js', '--outdir=out', '--splitting', '--format=esm', '--bundle', '--minify'], {\n    'test1.js': `export const sameName = { test: 1 }`,\n    'test2.js': `export const sameName = { test: 2 }`,\n    'entry1.js': `\n      export { sameName } from './test1.js'\n      export { sameName as renameVar } from './test2.js'\n    `,\n    'entry2.js': `export * from './entry1.js'`,\n    'node.js': `\n      import { sameName as a, renameVar as b } from './out/entry1.js'\n      import { sameName as c, renameVar as d } from './out/entry2.js'\n      if (a.test !== 1 || b.test !== 2 || c.test !== 1 || d.test !== 2) throw 'fail'\n    `,\n  }),\n\n  // https://github.com/evanw/esbuild/issues/1252\n  test(['client.js', 'utilities.js', '--splitting', '--bundle', '--format=esm', '--outdir=out'], {\n    'client.js': `export { Observable } from './utilities'`,\n    'utilities.js': `export { Observable } from './observable'`,\n    'observable.js': `\n      import Observable from './zen-observable'\n      export { Observable }\n    `,\n    'zen-observable.js': `module.exports = 123`,\n    'node.js': `\n      import {Observable as x} from './out/client.js'\n      import {Observable as y} from './out/utilities.js'\n      if (x !== 123 || y !== 123) throw 'fail'\n    `,\n  })\n)\n\n// Test the binary loader\nfor (const length of [0, 1, 2, 3, 4, 5, 6, 7, 8, 256]) {\n  const code = `\n    import bytes from './data.bin'\n    if (!(bytes instanceof Uint8Array)) throw 'not Uint8Array'\n    if (bytes.length !== ${length}) throw 'Uint8Array.length !== ${length}'\n    if (bytes.buffer.byteLength !== ${length}) throw 'ArrayBuffer.byteLength !== ${length}'\n    for (let i = 0; i < ${length}; i++) if (bytes[i] !== (i ^ 0x55)) throw 'bad element ' + i\n  `\n  const data = Buffer.from([...' '.repeat(length)].map((_, i) => i ^ 0x55))\n  tests.push(\n    test(['entry.js', '--bundle', '--outfile=node.js', '--loader:.bin=binary', '--platform=browser', '--supported:from-base64=false'], {\n      'entry.js': code,\n      'data.bin': data,\n    }),\n    test(['entry.js', '--bundle', '--outfile=node.js', '--loader:.bin=binary', '--platform=node', '--supported:from-base64=false'], {\n      'entry.js': code,\n      'data.bin': data,\n    }),\n  )\n}\n\n// Test file handle errors other than ENOENT\n{\n  const errorText = process.platform === 'win32' ? 'Incorrect function.' : 'is a directory';\n  tests.push(\n    test(['src/entry.js', '--bundle', '--outfile=node.js', '--sourcemap'], {\n      'src/entry.js': `\n        //# sourceMappingURL=entry.js.map\n      `,\n      'src/entry.js.map/x': ``,\n    }, {\n      expectedStderr: `▲ [WARNING] Cannot read file \"src/entry.js.map\": ${errorText} [missing-source-map]\n\n    src/entry.js:2:29:\n      2 │         //# sourceMappingURL=entry.js.map\n        ╵                              ~~~~~~~~~~~~\n\n`,\n    }),\n    test(['src/entry.js', '--bundle', '--outfile=node.js'], {\n      'src/entry.js': ``,\n      'src/tsconfig.json': `{\"extends\": \"./base.json\"}`,\n      'src/base.json/x': ``,\n    }, {\n      expectedStderr: `${errorIcon} [ERROR] Cannot read file \"src/base.json\": ${errorText}\n\n    src/tsconfig.json:1:12:\n      1 │ {\"extends\": \"./base.json\"}\n        ╵             ~~~~~~~~~~~~~\n\n`,\n    }),\n    test(['src/entry.js', '--bundle', '--outfile=node.js'], {\n      'src/entry.js': ``,\n      'src/tsconfig.json': `{\"extends\": \"foo\"}`,\n      'node_modules/foo/tsconfig.json/x': ``,\n    }, {\n      expectedStderr: `▲ [WARNING] Cannot find base config file \"foo\" [tsconfig.json]\n\n    src/tsconfig.json:1:12:\n      1 │ {\"extends\": \"foo\"}\n        ╵             ~~~~~\n\n`,\n    }),\n    test(['src/entry.js', '--bundle', '--outfile=node.js'], {\n      'src/entry.js': ``,\n\n      // These missing directories shouldn't cause any errors on Windows\n      'package.json': `{\n        \"main\": \"dist/cjs/index.js\",\n        \"module\": \"dist/esm/index.js\"\n      }`,\n    }),\n    test(['src/entry.js', '--bundle', '--outfile=node.js'], {\n      'src/entry.js': ``,\n      'src/tsconfig.json': `{\"extends\": \"./lib\"}`,\n      'src/lib.json': `{\"compilerOptions\": {\"target\": \"1\"}}`, // We should get a warning about this file\n      'src/lib/index.json': `{\"compilerOptions\": {\"target\": \"2\"}}`, // Not about this file\n    }, {\n      expectedStderr: `▲ [WARNING] Unrecognized target environment \"1\" [tsconfig.json]\n\n    src/lib.json:1:31:\n      1 │ {\"compilerOptions\": {\"target\": \"1\"}}\n        ╵                                ~~~\n\n`,\n    }),\n  )\n}\n\n// Test a special-case error message for people trying to use \"'--\" on Windows\ntests.push(\n  test(['in.js', `'--define:process.env.NODE_ENV=\"production\"'`], {\n    'in.js': ``,\n  }, {\n    expectedStderr: `${errorIcon} [ERROR] Unexpected single quote character before flag: '--define:process.env.NODE_ENV=\"production\"'\n\n  This typically happens when attempting to use single quotes to quote arguments with a shell that doesn't recognize single quotes. `+\n      `Try using double quote characters to quote arguments instead.\n\n`,\n  }),\n)\n\n// Test injecting banner and footer\ntests.push(\n  test(['in.js', '--outfile=node.js', '--banner:js=const bannerDefined = true;'], {\n    'in.js': `if (!bannerDefined) throw 'fail'`\n  }),\n  test(['in.js', '--outfile=node.js', '--footer:js=function footer() { }'], {\n    'in.js': `footer()`\n  }),\n  test(['a.js', 'b.js', '--outdir=out', '--bundle', '--format=cjs', '--banner:js=const bannerDefined = true;', '--footer:js=function footer() { }'], {\n    'a.js': `\n      module.exports = { banner: bannerDefined, footer };\n    `,\n    'b.js': `\n      module.exports = { banner: bannerDefined, footer };\n    `,\n    'node.js': `\n      const a = require('./out/a');\n      const b = require('./out/b');\n\n      if (!a.banner || !b.banner) throw 'fail';\n      a.footer();\n      b.footer();\n    `\n  }),\n)\n\n// Test \"imports\" and \"exports\" in package.json\nfor (const flags of [[], ['--bundle']]) {\n  tests.push(\n    // \"imports\"\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `import abc from '#pkg'; if (abc !== 123) throw 'fail'`,\n      'package.json': `{\n        \"type\": \"module\",\n        \"imports\": {\n          \"#pkg\": \"./foo.js\"\n        }\n      }`,\n      'foo.js': `export default 123`,\n    }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `import abc from '#pkg/bar.js'; if (abc !== 123) throw 'fail'`,\n      'package.json': `{\n        \"type\": \"module\",\n        \"imports\": {\n          \"#pkg/*\": \"./foo/*\"\n        }\n      }`,\n      'foo/bar.js': `export default 123`,\n    }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `import abc from '#pkg'; if (abc !== 123) throw 'fail'`,\n      'package.json': `{\n        \"type\": \"module\",\n        \"imports\": {\n          \"#pkg\": {\n            \"import\": \"./yes.js\",\n            \"default\": \"./no.js\"\n          }\n        }\n      }`,\n      'yes.js': `export default 123`,\n    }),\n    test(['in.js', '--outfile=node.js', '--format=cjs'].concat(flags), {\n      'in.js': `const abc = require('#pkg'); if (abc !== 123) throw 'fail'`,\n      'package.json': `{\n        \"type\": \"commonjs\",\n        \"imports\": {\n          \"#pkg\": {\n            \"require\": \"./yes.js\",\n            \"default\": \"./no.js\"\n          }\n        }\n      }`,\n      'yes.js': `module.exports = 123`,\n    }),\n\n    // \"exports\"\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `import abc from 'pkg'; if (abc !== 123) throw 'fail'`,\n      'package.json': `{ \"type\": \"module\" }`,\n      'node_modules/pkg/subdir/foo.js': `export default 123`,\n      'node_modules/pkg/package.json': `{\n        \"type\": \"module\",\n        \"exports\": {\n          \".\": \"./subdir/foo.js\"\n        }\n      }`,\n    }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `import abc from 'pkg'; if (abc !== 123) throw 'fail'`,\n      'package.json': `{ \"type\": \"module\" }`,\n      'node_modules/pkg/subdir/foo.js': `export default 123`,\n      'node_modules/pkg/package.json': `{\n        \"type\": \"module\",\n        \"exports\": {\n          \".\": {\n            \"default\": \"./subdir/foo.js\"\n          }\n        }\n      }`,\n    }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `import abc from 'pkg'; if (abc !== 123) throw 'fail'`,\n      'package.json': `{ \"type\": \"module\" }`,\n      'node_modules/pkg/subdir/foo.js': `export default 123`,\n      'node_modules/pkg/package.json': `{\n        \"type\": \"module\",\n        \"exports\": {\n          \"default\": \"./subdir/foo.js\"\n        }\n      }`,\n    }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `import abc from '@scope/pkg'; if (abc !== 123) throw 'fail'`,\n      'package.json': `{ \"type\": \"module\" }`,\n      'node_modules/@scope/pkg/subdir/foo.js': `export default 123`,\n      'node_modules/@scope/pkg/package.json': `{\n        \"type\": \"module\",\n        \"exports\": {\n          \".\": \"./subdir/foo.js\"\n        }\n      }`,\n    }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `import abc from '@scope/pkg'; if (abc !== 123) throw 'fail'`,\n      'package.json': `{ \"type\": \"module\" }`,\n      'node_modules/@scope/pkg/subdir/foo.js': `export default 123`,\n      'node_modules/@scope/pkg/package.json': `{\n        \"type\": \"module\",\n        \"exports\": {\n          \".\": {\n            \"default\": \"./subdir/foo.js\"\n          }\n        }\n      }`,\n    }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `import abc from '@scope/pkg'; if (abc !== 123) throw 'fail'`,\n      'package.json': `{ \"type\": \"module\" }`,\n      'node_modules/@scope/pkg/subdir/foo.js': `export default 123`,\n      'node_modules/@scope/pkg/package.json': `{\n        \"type\": \"module\",\n        \"exports\": {\n          \"default\": \"./subdir/foo.js\"\n        }\n      }`,\n    }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `import abc from 'pkg/dirwhat'; if (abc !== 123) throw 'fail'`,\n      'package.json': `{ \"type\": \"module\" }`,\n      'node_modules/pkg/sub/what/dirwhat/foo.js': `export default 123`,\n      'node_modules/pkg/package.json': `{\n        \"type\": \"module\",\n        \"exports\": {\n          \"./di*\": \"./nope.js\",\n          \"./dir*\": \"./sub/*/dir*/foo.js\",\n          \"./long*\": \"./nope.js\",\n          \"./d*\": \"./nope.js\"\n        }\n      }`,\n    }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `import abc from 'pkg/foo'; if (abc !== 123) throw 'fail'`,\n      'package.json': `{ \"type\": \"module\" }`,\n      'node_modules/pkg/yes.js': `export default 123`,\n      'node_modules/pkg/package.json': `{\n        \"type\": \"module\",\n        \"exports\": {\n          \"./foo\": [\n            { \"unused\": \"./no.js\" },\n            \"./yes.js\"\n          ]\n        }\n      }`,\n    }),\n    test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n      'in.js': `import abc from 'pkg/foo'; if (abc !== 123) throw 'fail'`,\n      'package.json': `{ \"type\": \"module\" }`,\n      'node_modules/pkg/yes.js': `export default 123`,\n      'node_modules/pkg/package.json': `{\n        \"type\": \"module\",\n        \"exports\": {\n          \"./foo\": [\n            { \"default\": \"./yes.js\" },\n            \"./no.js\"\n          ]\n        }\n      }`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle', '--platform=browser'].concat(flags), {\n      'in.js': `import abc from 'pkg'; if (abc !== 'module') throw 'fail'`,\n      'node_modules/pkg/default.js': `module.exports = 'default'`,\n      'node_modules/pkg/module.js': `export default 'module'`,\n      'node_modules/pkg/package.json': `{\n        \"exports\": {\n          \".\": {\n            \"module\": \"./module.js\",\n            \"default\": \"./default.js\"\n          }\n        }\n      }`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle', '--platform=node', '--packages=bundle'].concat(flags), {\n      'in.js': `import abc from 'pkg'; if (abc !== 'module') throw 'fail'`,\n      'node_modules/pkg/default.js': `module.exports = 'default'`,\n      'node_modules/pkg/module.js': `export default 'module'`,\n      'node_modules/pkg/package.json': `{\n        \"exports\": {\n          \".\": {\n            \"module\": \"./module.js\",\n            \"default\": \"./default.js\"\n          }\n        }\n      }`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle', '--platform=neutral'].concat(flags), {\n      'in.js': `import abc from 'pkg'; if (abc !== 'default') throw 'fail'`,\n      'node_modules/pkg/default.js': `module.exports = 'default'`,\n      'node_modules/pkg/module.js': `export default 'module'`,\n      'node_modules/pkg/package.json': `{\n        \"exports\": {\n          \".\": {\n            \"module\": \"./module.js\",\n            \"default\": \"./default.js\"\n          }\n        }\n      }`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle', '--conditions='].concat(flags), {\n      'in.js': `import abc from 'pkg'; if (abc !== 'default') throw 'fail'`,\n      'node_modules/pkg/default.js': `module.exports = 'default'`,\n      'node_modules/pkg/module.js': `export default 'module'`,\n      'node_modules/pkg/package.json': `{\n        \"exports\": {\n          \".\": {\n            \"module\": \"./module.js\",\n            \"default\": \"./default.js\"\n          }\n        }\n      }`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle', '--platform=node', '--packages=external', '--format=esm'].concat(flags), {\n      'in.js': `import abc from 'pkg'; if (abc !== 'import') throw 'fail'`,\n      'node_modules/pkg/fail.js': `TEST FAILED`, // This package should not be bundled\n      'node_modules/pkg/require.cjs': `module.exports = 'require'`,\n      'node_modules/pkg/import.mjs': `export default 'import'`,\n      'node_modules/pkg/package.json': `{\n        \"exports\": {\n          \".\": {\n            \"module\": \"./fail.js\",\n            \"import\": \"./import.mjs\",\n            \"require\": \"./require.cjs\"\n          }\n        }\n      }`,\n    }),\n    test(['in.js', '--outfile=node.js', '--bundle', '--platform=node', '--packages=external', '--format=cjs'].concat(flags), {\n      'in.js': `import abc from 'pkg'; if (abc !== 'require') throw 'fail'`,\n      'node_modules/pkg/fail.js': `TEST FAILED`, // This package should not be bundled\n      'node_modules/pkg/require.cjs': `module.exports = 'require'`,\n      'node_modules/pkg/import.mjs': `export default 'import'`,\n      'node_modules/pkg/package.json': `{\n        \"exports\": {\n          \".\": {\n            \"module\": \"./fail.js\",\n            \"import\": \"./import.mjs\",\n            \"require\": \"./require.cjs\"\n          }\n        }\n      }`,\n    }),\n\n    // Check the default behavior of \"--platform=node\"\n    test(['in.js', '--outfile=node.js', '--bundle', '--platform=node', '--format=esm'].concat(flags), {\n      'in.js': `import abc from 'pkg'; if (abc !== 'module') throw 'fail'`,\n      'node_modules/pkg/module.js': `export default 'module'`,\n      'node_modules/pkg/require.cjs': `module.exports = 'require'`,\n      'node_modules/pkg/import.mjs': `export default 'import'`,\n      'node_modules/pkg/package.json': `{\n        \"exports\": {\n          \".\": {\n            \"module\": \"./module.js\",\n            \"import\": \"./import.mjs\",\n            \"require\": \"./require.cjs\"\n          }\n        }\n      }`,\n    }),\n\n    // This is an edge case for extensionless files. The file should be treated\n    // as CommonJS even though package.json says \"type\": \"module\" because that\n    // only applies to \".js\" files in node, not to all JavaScript files.\n    test(['in.js', '--outfile=node.js', '--bundle'], {\n      'in.js': `\n        const fn = require('yargs/yargs')\n        if (fn() !== 123) throw 'fail'\n      `,\n      'node_modules/yargs/package.json': `{\n        \"main\": \"./index.cjs\",\n        \"exports\": {\n          \"./package.json\": \"./package.json\",\n          \".\": [\n            {\n              \"import\": \"./index.mjs\",\n              \"require\": \"./index.cjs\"\n            },\n            \"./index.cjs\"\n          ],\n          \"./yargs\": [\n            {\n              \"import\": \"./yargs.mjs\",\n              \"require\": \"./yargs\"\n            },\n            \"./yargs\"\n          ]\n        },\n        \"type\": \"module\",\n        \"module\": \"./index.mjs\"\n      }`,\n      'node_modules/yargs/index.cjs': ``,\n      'node_modules/yargs/index.mjs': ``,\n      'node_modules/yargs/yargs.mjs': ``,\n      'node_modules/yargs/yargs': `\n        module.exports = function() {\n          return 123\n        }\n      `,\n    }),\n  )\n\n  // Node 17+ deliberately broke backward compatibility with packages using mappings\n  // ending in \"/\". See https://github.com/nodejs/node/pull/40121 for more info.\n  if (flags.length === 0 && nodeMajorVersion >= 17) {\n    console.log(`Skipping tests with path mappings ending in \"/\" since you are running node 17+`)\n  } else {\n    tests.push(\n      test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n        'in.js': `import abc from '#pkg/bar.js'; if (abc !== 123) throw 'fail'`,\n        'package.json': `{\n          \"type\": \"module\",\n          \"imports\": {\n            \"#pkg/\": \"./foo/\"\n          }\n        }`,\n        'foo/bar.js': `export default 123`,\n      }),\n      test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n        'in.js': `import abc from 'pkg/foo.js'; if (abc !== 123) throw 'fail'`,\n        'package.json': `{ \"type\": \"module\" }`,\n        'node_modules/pkg/subdir/foo.js': `export default 123`,\n        'node_modules/pkg/package.json': `{\n          \"type\": \"module\",\n          \"exports\": {\n            \"./\": \"./subdir/\"\n          }\n        }`,\n      }),\n      test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n        'in.js': `import abc from 'pkg/foo.js'; if (abc !== 123) throw 'fail'`,\n        'package.json': `{ \"type\": \"module\" }`,\n        'node_modules/pkg/subdir/foo.js': `export default 123`,\n        'node_modules/pkg/package.json': `{\n          \"type\": \"module\",\n          \"exports\": {\n            \"./\": {\n              \"default\": \"./subdir/\"\n            }\n          }\n        }`,\n      }),\n      test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n        'in.js': `import abc from 'pkg/dir/foo.js'; if (abc !== 123) throw 'fail'`,\n        'package.json': `{ \"type\": \"module\" }`,\n        'node_modules/pkg/subdir/foo.js': `export default 123`,\n        'node_modules/pkg/package.json': `{\n          \"type\": \"module\",\n          \"exports\": {\n            \"./dir/\": \"./subdir/\"\n          }\n        }`,\n      }),\n      test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n        'in.js': `import abc from 'pkg/dir/foo.js'; if (abc !== 123) throw 'fail'`,\n        'package.json': `{ \"type\": \"module\" }`,\n        'node_modules/pkg/subdir/foo.js': `export default 123`,\n        'node_modules/pkg/package.json': `{\n          \"type\": \"module\",\n          \"exports\": {\n            \"./dir/\": {\n              \"default\": \"./subdir/\"\n            }\n          }\n        }`,\n      }),\n      test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n        'in.js': `import abc from '@scope/pkg/foo.js'; if (abc !== 123) throw 'fail'`,\n        'package.json': `{ \"type\": \"module\" }`,\n        'node_modules/@scope/pkg/subdir/foo.js': `export default 123`,\n        'node_modules/@scope/pkg/package.json': `{\n          \"type\": \"module\",\n          \"exports\": {\n            \"./\": \"./subdir/\"\n          }\n        }`,\n      }),\n      test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n        'in.js': `import abc from '@scope/pkg/foo.js'; if (abc !== 123) throw 'fail'`,\n        'package.json': `{ \"type\": \"module\" }`,\n        'node_modules/@scope/pkg/subdir/foo.js': `export default 123`,\n        'node_modules/@scope/pkg/package.json': `{\n          \"type\": \"module\",\n          \"exports\": {\n            \"./\": {\n              \"default\": \"./subdir/\"\n            }\n          }\n        }`,\n      }),\n      test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n        'in.js': `import abc from '@scope/pkg/dir/foo.js'; if (abc !== 123) throw 'fail'`,\n        'package.json': `{ \"type\": \"module\" }`,\n        'node_modules/@scope/pkg/subdir/foo.js': `export default 123`,\n        'node_modules/@scope/pkg/package.json': `{\n          \"type\": \"module\",\n          \"exports\": {\n            \"./dir/\": \"./subdir/\"\n          }\n        }`,\n      }),\n      test(['in.js', '--outfile=node.js', '--format=esm'].concat(flags), {\n        'in.js': `import abc from '@scope/pkg/dir/foo.js'; if (abc !== 123) throw 'fail'`,\n        'package.json': `{ \"type\": \"module\" }`,\n        'node_modules/@scope/pkg/subdir/foo.js': `export default 123`,\n        'node_modules/@scope/pkg/package.json': `{\n          \"type\": \"module\",\n          \"exports\": {\n            \"./dir/\": {\n              \"default\": \"./subdir/\"\n            }\n          }\n        }`,\n      }),\n      test(['in.js', '--outfile=node.js', '--format=cjs'].concat(flags), {\n        'in.js': `const abc = require('pkg/dir/test'); if (abc !== 123) throw 'fail'`,\n        'package.json': `{ \"type\": \"commonjs\" }`,\n        'node_modules/pkg/sub/test.js': `module.exports = 123`,\n        'node_modules/pkg/package.json': `{\n          \"exports\": {\n            \"./dir/\": \"./sub/\"\n          }\n        }`,\n      }),\n      test(['in.js', '--outfile=node.js', '--format=cjs'].concat(flags), {\n        'in.js': `const abc = require('pkg/dir/test'); if (abc !== 123) throw 'fail'`,\n        'package.json': `{ \"type\": \"commonjs\" }`,\n        'node_modules/pkg/sub/test/index.js': `module.exports = 123`,\n        'node_modules/pkg/package.json': `{\n          \"exports\": {\n            \"./dir/\": \"./sub/\"\n          }\n        }`,\n      }),\n    )\n  }\n}\n\n// Top-level await tests\ntests.push(\n  test(['in.js', '--outdir=out', '--format=esm', '--bundle'], {\n    'in.js': `\n      function foo() {\n        globalThis.tlaTrace.push(2)\n        return import('./a.js')\n      }\n\n      globalThis.tlaTrace = []\n      globalThis.tlaTrace.push(1)\n      const it = (await foo()).default\n      globalThis.tlaTrace.push(6)\n      if (it !== 123 || globalThis.tlaTrace.join(',') !== '1,2,3,4,5,6') throw 'fail'\n    `,\n    'a.js': `\n      globalThis.tlaTrace.push(5)\n      export { default } from './b.js'\n    `,\n    'b.js': `\n      globalThis.tlaTrace.push(3)\n      export default await Promise.resolve(123)\n      globalThis.tlaTrace.push(4)\n    `,\n    'node.js': `\n      import './out/in.js'\n    `,\n  }),\n)\n\n// Test the alias feature\ntests.push(\n  test(['in.js', '--outfile=node.js', '--bundle', '--alias:foo=./bar/baz'], {\n    'in.js': `import \"foo\"`,\n    'node_modules/foo/index.js': `test failure`,\n    'bar/baz.js': ``,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle', '--alias:foo=./bar/../baz'], {\n    'in.js': `import \"foo\"`,\n    'node_modules/foo/index.js': `test failure`,\n    'baz.js': ``,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle', '--alias:@scope=./bar'], {\n    'in.js': `import \"@scope/foo\"`,\n    'node_modules/@scope/foo/index.js': `test failure`,\n    'bar/foo.js': ``,\n  }),\n)\n\n// Tests for CSS modules\ntests.push(\n  test(['in.js', '--outfile=node.js', '--bundle', '--loader:.css=local-css'], {\n    'in.js': `\n      import * as ns from './styles.css'\n      if (ns.buton !== void 0) throw 'fail'\n    `,\n    'styles.css': `\n      .bu\\\\74 ton { color: red }\n    `,\n  }, {\n    expectedStderr: `▲ [WARNING] Import \"buton\" will always be undefined because there is no matching export in \"styles.css\" [import-is-undefined]\n\n    in.js:3:13:\n      3 │       if (ns.buton !== void 0) throw 'fail'\n        │              ~~~~~\n        ╵              button\n\n  Did you mean to import \"button\" instead?\n\n    styles.css:2:7:\n      2 │       .bu\\\\74 ton { color: red }\n        ╵        ~~~~~~~~~\n\n`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import * as foo_styles from \"./foo.css\"\n      import * as bar_styles from \"./bar\"\n      const { foo } = foo_styles\n      const { bar } = bar_styles\n      if (foo !== void 0) throw 'fail: foo=' + foo\n      if (bar !== void 0) throw 'fail: bar=' + bar\n    `,\n    'foo.css': `.foo { color: red }`,\n    'bar.css': `.bar { color: green }`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle'], {\n    'in.js': `\n      import * as foo_styles from \"./foo.module.css\"\n      import * as bar_styles from \"./bar.module\"\n      const { foo } = foo_styles\n      const { bar } = bar_styles\n      if (foo !== 'foo_foo') throw 'fail: foo=' + foo\n      if (bar !== 'bar_bar') throw 'fail: bar=' + bar\n    `,\n    'foo.module.css': `.foo { color: red }`,\n    'bar.module.css': `.bar { color: green }`,\n  }),\n  test(['in.js', '--outfile=node.js', '--bundle', '--loader:.module.css=css'], {\n    'in.js': `\n      import * as foo_styles from \"./foo.module.css\"\n      import * as bar_styles from \"./bar.module\"\n      const { foo } = foo_styles\n      const { bar } = bar_styles\n      if (foo !== void 0) throw 'fail: foo=' + foo\n      if (bar !== void 0) throw 'fail: bar=' + bar\n    `,\n    'foo.module.css': `.foo { color: red }`,\n    'bar.module.css': `.bar { color: green }`,\n  }),\n)\n\n// Tests for analyze\ntests.push(\n  test(['in.js', '--analyze', '--outfile=node.js'], {\n    'in.js': `let x = 1 + 2`,\n  }, {\n    expectedStderr: `\n  node.js   15b   100.0%\n   └ in.js  15b   100.0%\n\n`,\n  }),\n  test(['in.js', '--invalid-flag', '--analyze'], {\n    'in.js': `let x = 1 + 2`,\n  }, {\n    expectedStderr: `${errorIcon} [ERROR] Invalid build flag: \"--invalid-flag\"\\n\\n`,\n  }),\n  test(['--analyze'], {}, {\n    expectedStderr: `${errorIcon} [ERROR] Invalid transform flag: \"--analyze\"\\n\\n`,\n  }),\n)\n\n// Test writing to stdout\ntests.push(\n  // These should succeed\n  testStdout('exports.foo = 123', [], async (build) => {\n    const stdout = await build()\n    assert.strictEqual(stdout, `exports.foo = 123;\\n`)\n  }),\n  testStdout('exports.foo = 123', ['--bundle', '--format=cjs'], async (build) => {\n    const stdout = await build()\n    assert.strictEqual(stdout, `// example.js\\nexports.foo = 123;\\n`)\n  }),\n  testStdout('exports.foo = 123', ['--sourcemap'], async (build) => {\n    const stdout = await build()\n    const start = `exports.foo = 123;\\n//# sourceMappingURL=data:application/json;base64,`\n    assert(stdout.startsWith(start))\n    const json = JSON.parse(Buffer.from(stdout.slice(start.length), 'base64').toString())\n    assert.strictEqual(json.version, 3)\n    assert.deepStrictEqual(json.sources, ['example.js'])\n  }),\n  testStdout('exports.foo = 123', ['--bundle', '--format=cjs', '--sourcemap'], async (build) => {\n    const stdout = await build()\n    const start = `// example.js\\nexports.foo = 123;\\n//# sourceMappingURL=data:application/json;base64,`\n    assert(stdout.startsWith(start))\n    const json = JSON.parse(Buffer.from(stdout.slice(start.length), 'base64').toString())\n    assert.strictEqual(json.version, 3)\n    assert.deepStrictEqual(json.sources, ['example.js'])\n  }),\n  testStdout('stuff', ['--loader:.js=text'], async (build) => {\n    const stdout = await build()\n    assert.strictEqual(stdout, `module.exports = \"stuff\";\\n`)\n  }),\n\n  // These should fail\n  testStdout('exports.foo = 123', ['--metafile=graph.json'], async (build) => {\n    try { await build() } catch (e) { return }\n    throw new Error('Expected build failure for \"--metafile\"')\n  }),\n  testStdout('exports.foo = 123', ['--sourcemap=external'], async (build) => {\n    try { await build() } catch (e) { return }\n    throw new Error('Expected build failure for \"--metafile\"')\n  }),\n  testStdout('exports.foo = 123', ['--loader:.js=file'], async (build) => {\n    try { await build() } catch (e) { return }\n    throw new Error('Expected build failure for \"--metafile\"')\n  }),\n)\n\n// Test for a Windows-specific issue where paths starting with \"/\" could be\n// treated as relative paths, leading to inconvenient cross-platform failures:\n// https://github.com/evanw/esbuild/issues/822\ntests.push(\n  test(['in.js', '--bundle'], {\n    'in.js': `\n      import \"/file.js\"\n    `,\n    'file.js': `This file should not be imported on Windows`,\n  }, {\n    expectedStderr: `${errorIcon} [ERROR] Could not resolve \"/file.js\"\n\n    in.js:2:13:\n      2 │       import \"/file.js\"\n        ╵              ~~~~~~~~~~\n\n`,\n  }),\n)\n\n// Test that importing a path with the wrong case works ok. This is necessary\n// to handle case-insensitive file systems.\nif (process.platform === 'darwin' || process.platform === 'win32') {\n  tests.push(\n    test(['in.js', '--bundle', '--outfile=node.js'], {\n      'in.js': `\n        import x from \"./File1.js\"\n        import y from \"./file2.js\"\n        if (x !== 123 || y !== 234) throw 'fail'\n      `,\n      'file1.js': `export default 123`,\n      'File2.js': `export default 234`,\n    }, {\n      expectedStderr: `▲ [WARNING] Use \"file1.js\" instead of \"File1.js\" to avoid issues with case-sensitive file systems [different-path-case]\n\n    in.js:2:22:\n      2 │         import x from \"./File1.js\"\n        ╵                       ~~~~~~~~~~~~\n\n▲ [WARNING] Use \"File2.js\" instead of \"file2.js\" to avoid issues with case-sensitive file systems [different-path-case]\n\n    in.js:3:22:\n      3 │         import y from \"./file2.js\"\n        ╵                       ~~~~~~~~~~~~\n\n`,\n    }),\n    test(['in.js', '--bundle', '--outfile=node.js'], {\n      'in.js': `\n        import x from \"./Dir1/file.js\"\n        import y from \"./dir2/file.js\"\n        if (x !== 123 || y !== 234) throw 'fail'\n      `,\n      'dir1/file.js': `export default 123`,\n      'Dir2/file.js': `export default 234`,\n    }),\n\n    // Warn when importing something inside node_modules\n    test(['in.js', '--bundle', '--outfile=node.js'], {\n      'in.js': `\n        import x from \"pkg/File1.js\"\n        import y from \"pkg/file2.js\"\n        if (x !== 123 || y !== 234) throw 'fail'\n      `,\n      'node_modules/pkg/file1.js': `export default 123`,\n      'node_modules/pkg/File2.js': `export default 234`,\n    }, {\n      expectedStderr: `▲ [WARNING] Use \"node_modules/pkg/file1.js\" instead of \"node_modules/pkg/File1.js\" to avoid issues with case-sensitive file systems [different-path-case]\n\n    in.js:2:22:\n      2 │         import x from \"pkg/File1.js\"\n        ╵                       ~~~~~~~~~~~~~~\n\n▲ [WARNING] Use \"node_modules/pkg/File2.js\" instead of \"node_modules/pkg/file2.js\" to avoid issues with case-sensitive file systems [different-path-case]\n\n    in.js:3:22:\n      3 │         import y from \"pkg/file2.js\"\n        ╵                       ~~~~~~~~~~~~~~\n\n`,\n    }),\n\n    // Don't warn when the importer is inside node_modules\n    test(['in.js', '--bundle', '--outfile=node.js'], {\n      'in.js': `\n        import {x, y} from \"pkg\"\n        if (x !== 123 || y !== 234) throw 'fail'\n      `,\n      'node_modules/pkg/index.js': `\n        export {default as x} from \"./File1.js\"\n        export {default as y} from \"./file2.js\"\n      `,\n      'node_modules/pkg/file1.js': `export default 123`,\n      'node_modules/pkg/File2.js': `export default 234`,\n    }),\n  )\n}\n\n// Test glob import behavior\nfor (const ext of ['.js', '.ts']) {\n  tests.push(\n    test(['./src/*' + ext, '--outdir=out', '--bundle', '--format=cjs'], {\n      'node.js': `\n        if (require('./out/a.js') !== 10) throw 'fail: a'\n        if (require('./out/b.js') !== 11) throw 'fail: b'\n        if (require('./out/c.js') !== 12) throw 'fail: c'\n      `,\n      ['src/a' + ext]: `module.exports = 10`,\n      ['src/b' + ext]: `module.exports = 11`,\n      ['src/c' + ext]: `module.exports = 12`,\n    }),\n    test(['in' + ext, '--outfile=node.js', '--bundle'], {\n      ['in' + ext]: `\n        for (let i = 0; i < 3; i++) {\n          const value = require('./' + i + '${ext}')\n          if (value !== i + 10) throw 'fail: ' + i\n        }\n      `,\n      ['0' + ext]: `module.exports = 10`,\n      ['1' + ext]: `module.exports = 11`,\n      ['2' + ext]: `module.exports = 12`,\n    }),\n    test(['in' + ext, '--outfile=node.js', '--bundle'], {\n      ['in' + ext]: `\n        for (let i = 0; i < 3; i++) {\n          const value = require(\\`./\\${i}${ext}\\`)\n          if (value !== i + 10) throw 'fail: ' + i\n        }\n      `,\n      ['0' + ext]: `module.exports = 10`,\n      ['1' + ext]: `module.exports = 11`,\n      ['2' + ext]: `module.exports = 12`,\n    }),\n    test(['in' + ext, '--outfile=node.js', '--bundle'], {\n      ['in' + ext]: `\n        export let async = async () => {\n          for (let i = 0; i < 3; i++) {\n            const { default: value } = await import('./' + i + '${ext}')\n            if (value !== i + 10) throw 'fail: ' + i\n          }\n        }\n      `,\n      ['0' + ext]: `export default 10`,\n      ['1' + ext]: `export default 11`,\n      ['2' + ext]: `export default 12`,\n    }, { async: true }),\n    test(['in' + ext, '--outfile=node.js', '--bundle'], {\n      ['in' + ext]: `\n        export let async = async () => {\n          for (let i = 0; i < 3; i++) {\n            const { default: value } = await import(\\`./\\${i}${ext}\\`)\n            if (value !== i + 10) throw 'fail: ' + i\n          }\n        }\n      `,\n      ['0' + ext]: `export default 10`,\n      ['1' + ext]: `export default 11`,\n      ['2' + ext]: `export default 12`,\n    }, { async: true }),\n  )\n}\n\n// Test \"using\" declarations\nfor (const flags of [[], '--supported:async-await=false']) {\n  tests.push(\n    test(['in.js', '--outfile=node.js', '--supported:using=false'].concat(flags), {\n      'in.js': `\n        Symbol.dispose ||= Symbol.for('Symbol.dispose')\n        const log = []\n        {\n          using x = { [Symbol.dispose]() { log.push('x') } }\n          using y = { [Symbol.dispose]() { log.push('y') } }\n          using z1 = null\n          using z2 = undefined\n          try {\n            using no = 0\n          } catch {\n            log.push('no')\n          }\n          log.push('z')\n        }\n        if (log + '' !== 'no,z,y,x') throw 'fail: ' + log\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', '--supported:using=false', '--format=esm'].concat(flags), {\n      'in.js': `\n        Symbol.asyncDispose ||= Symbol.for('Symbol.asyncDispose')\n        export let async = async () => {\n          const log = []\n          {\n            await using x = { [Symbol.asyncDispose]() {\n              log.push('x1')\n              Promise.resolve().then(() => log.push('x2'))\n              return Promise.resolve()\n            } }\n            await using y = { [Symbol.asyncDispose]() {\n              log.push('y1')\n              Promise.resolve().then(() => log.push('y2'))\n              return Promise.resolve()\n            } }\n            await using z1 = null\n            await using z2 = undefined\n            try {\n              await using no = 0\n            } catch {\n              log.push('no')\n            }\n            log.push('z')\n          }\n          if (log + '' !== 'no,z,y1,y2,x1,x2') throw 'fail: ' + log\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--supported:using=false'].concat(flags), {\n      'in.js': `\n        Symbol.dispose ||= Symbol.for('Symbol.dispose')\n        const log = []\n        for (using x of [\n          { [Symbol.dispose]() { log.push('x') } },\n          null,\n          { [Symbol.dispose]() { log.push('y') } },\n          undefined,\n        ]) {\n          try {\n            using no = 0\n          } catch {\n            log.push('no')\n          }\n          log.push('z')\n        }\n        if (log + '' !== 'no,z,x,no,z,no,z,y,no,z') throw 'fail: ' + log\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', '--supported:using=false', '--format=esm'].concat(flags), {\n      'in.js': `\n        Symbol.dispose ||= Symbol.for('Symbol.dispose')\n        Symbol.asyncDispose ||= Symbol.for('Symbol.asyncDispose')\n        export let async = async () => {\n          const log = []\n          for (await using x of [\n            { [Symbol.dispose]() { log.push('x') } },\n            null,\n            { [Symbol.asyncDispose]() {\n              log.push('y1')\n              Promise.resolve().then(() => log.push('y2'))\n              return Promise.resolve()\n            } },\n            undefined,\n          ]) {\n            try {\n              using no = 0\n            } catch {\n              log.push('no')\n            }\n            log.push('z')\n          }\n          if (log + '' !== 'no,z,x,no,z,no,z,y1,y2,no,z') throw 'fail: ' + log\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--supported:using=false', '--format=esm'].concat(flags), {\n      'in.js': `\n        Symbol.dispose ||= Symbol.for('Symbol.dispose')\n        export let async = async () => {\n          const log = []\n          for await (using x of [\n            { [Symbol.dispose]() { log.push('x1') } },\n            Promise.resolve({ [Symbol.dispose]() { log.push('x2') } }),\n            null,\n            Promise.resolve(null),\n            undefined,\n            Promise.resolve(undefined),\n          ]) {\n            try {\n              using no = 0\n            } catch {\n              log.push('no')\n            }\n            log.push('z')\n          }\n          if (log + '' !== 'no,z,x1,no,z,x2,no,z,no,z,no,z,no,z') throw 'fail: ' + log\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--supported:using=false', '--format=esm'].concat(flags), {\n      'in.js': `\n        Symbol.dispose ||= Symbol.for('Symbol.dispose')\n        Symbol.asyncDispose ||= Symbol.for('Symbol.asyncDispose')\n        export let async = async () => {\n          const log = []\n          for await (await using x of [\n            { [Symbol.dispose]() { log.push('x1') } },\n            Promise.resolve({ [Symbol.dispose]() { log.push('x2') } }),\n            { [Symbol.asyncDispose]() { log.push('y1') } },\n            Promise.resolve({ [Symbol.asyncDispose]() { log.push('y2') } }),\n            null,\n            Promise.resolve(null),\n            undefined,\n            Promise.resolve(undefined),\n          ]) {\n            try {\n              using no = 0\n            } catch {\n              log.push('no')\n            }\n            log.push('z')\n          }\n          if (log + '' !== 'no,z,x1,no,z,x2,no,z,y1,no,z,y2,no,z,no,z,no,z,no,z') throw 'fail: ' + log\n        }\n      `,\n    }, { async: true }),\n    test(['in.js', '--outfile=node.js', '--supported:using=false'].concat(flags), {\n      'in.js': `\n        Symbol.dispose ||= Symbol.for('Symbol.dispose')\n        class Foo { [Symbol.dispose]() { throw new Error('x') } }\n        try {\n          using x = new Foo\n          throw new Error('y')\n        } catch (err) {\n          var result = err\n        }\n        if (result.name !== 'SuppressedError') throw 'fail: SuppressedError'\n        if (result.error.message !== 'x') throw 'fail: x'\n        if (result.suppressed.message !== 'y') throw 'fail: y'\n        try {\n          using x = new Foo\n        } catch (err) {\n          var result = err\n        }\n        if (result.message !== 'x') throw 'fail: x (2)'\n      `,\n    }),\n    test(['in.js', '--outfile=node.js', '--supported:using=false', '--format=esm'].concat(flags), {\n      'in.js': `\n        Symbol.asyncDispose ||= Symbol.for('Symbol.asyncDispose')\n        class Foo { [Symbol.asyncDispose]() { throw new Error('x') } }\n        export let async = async () => {\n          try {\n            await using x = new Foo\n            throw new Error('y')\n          } catch (err) {\n            var result = err\n          }\n          if (result.name !== 'SuppressedError') throw 'fail: SuppressedError'\n          if (result.error.message !== 'x') throw 'fail: x'\n          if (result.suppressed.message !== 'y') throw 'fail: y'\n          try {\n            await using x = new Foo\n          } catch (err) {\n            var result = err\n          }\n          if (result.message !== 'x') throw 'fail: x (2)'\n        }\n      `,\n    }, { async: true }),\n\n    // From https://github.com/microsoft/TypeScript/pull/58624\n    test(['in.ts', '--outfile=node.js', '--supported:using=false', '--format=esm'].concat(flags), {\n      'in.ts': `\n        Symbol.asyncDispose ||= Symbol.for('Symbol.asyncDispose')\n        Symbol.dispose ||= Symbol.for('Symbol.dispose')\n        export const output: any[] = [];\n        export async function main() {\n          const promiseDispose = new Promise<void>((resolve) => {\n            setTimeout(() => {\n              output.push(\"y dispose promise body\");\n              resolve();\n            }, 0);\n          });\n          {\n            await using x = {\n              async [Symbol.asyncDispose]() {\n                output.push(\"x asyncDispose body\");\n              },\n            };\n            await using y = {\n              [Symbol.dispose]() {\n                output.push(\"y dispose body\");\n                return promiseDispose;\n              },\n            };\n          }\n          output.push(\"body\");\n          await promiseDispose;\n          return output;\n        }\n        export let async = async () => {\n          const output = await main()\n          const expected = [\n            \"y dispose body\",\n            \"x asyncDispose body\",\n            \"body\",\n            \"y dispose promise body\",\n          ]\n          if (output.join(',') !== expected.join(',')) throw 'fail: ' + output\n        }\n      `,\n    }, { async: true }),\n    test(['in.ts', '--outfile=node.js', '--supported:using=false', '--format=esm'].concat(flags), {\n      'in.ts': `\n        Symbol.dispose ||= Symbol.for('Symbol.dispose')\n        export const output: any[] = [];\n        export async function main() {\n          const interleave = Promise.resolve().then(() => { output.push(\"interleave\"); });\n          try {\n            await using x = {\n              [Symbol.dispose]() {\n                output.push(\"dispose\");\n                throw null;\n              },\n            };\n          }\n          catch {\n            output.push(\"catch\");\n          }\n          await interleave;\n          return output;\n        }\n        export let async = async () => {\n          const output = await main()\n          const expected = [\n            \"dispose\",\n            \"interleave\",\n            \"catch\",\n        ]\n          if (output.join(',') !== expected.join(',')) throw 'fail: ' + output\n        }\n      `,\n    }, { async: true }),\n  )\n}\n\n// End-to-end watch mode tests\ntests.push(\n  // Validate that the CLI watch mode correctly updates the metafile\n  testWatch({ metafile: true }, async ({ infile, outfile, metafile }) => {\n    await waitForCondition(\n      'initial build',\n      20,\n      () => fs.writeFile(infile, 'foo()'),\n      async () => {\n        assert.strictEqual(await fs.readFile(outfile, 'utf8'), 'foo();\\n')\n        assert.strictEqual(JSON.parse(await fs.readFile(metafile, 'utf8')).inputs[path.basename(infile)].bytes, 5)\n      },\n    )\n\n    await waitForCondition(\n      'subsequent build',\n      20,\n      () => fs.writeFile(infile, 'foo(123)'),\n      async () => {\n        assert.strictEqual(await fs.readFile(outfile, 'utf8'), 'foo(123);\\n')\n        assert.strictEqual(JSON.parse(await fs.readFile(metafile, 'utf8')).inputs[path.basename(infile)].bytes, 8)\n      },\n    )\n  }),\n\n  // Validate that the CLI watch mode correctly updates the mangle cache\n  testWatch({ args: ['--mangle-props=.'], mangleCache: true }, async ({ infile, outfile, mangleCache }) => {\n    await waitForCondition(\n      'initial build',\n      20,\n      () => fs.writeFile(infile, 'foo()'),\n      async () => {\n        assert.strictEqual(await fs.readFile(outfile, 'utf8'), 'foo();\\n')\n        assert.strictEqual(await fs.readFile(mangleCache, 'utf8'), '{}\\n')\n      },\n    )\n\n    await waitForCondition(\n      'subsequent build',\n      20,\n      () => fs.writeFile(infile, 'foo(bar.baz)'),\n      async () => {\n        assert.strictEqual(await fs.readFile(outfile, 'utf8'), 'foo(bar.a);\\n')\n        assert.strictEqual(await fs.readFile(mangleCache, 'utf8'), '{\\n  \"baz\": \"a\"\\n}\\n')\n      },\n    )\n  }),\n\n  // This tests that watch mode writes to stdout correctly\n  testWatchStdout([\n    {\n      input: 'console.log(1+2)',\n      stdout: ['console.log(1 + 2);'],\n      stderr: ['[watch] build finished, watching for changes...'],\n    },\n    {\n      input: 'console.log(2+3)',\n      stdout: ['console.log(2 + 3);'],\n      stderr: ['[watch] build started (change: \"in.js\")', '[watch] build finished'],\n    },\n    {\n      input: 'console.log(3+4)',\n      stdout: ['console.log(3 + 4);'],\n      stderr: ['[watch] build started (change: \"in.js\")', '[watch] build finished'],\n    },\n  ]),\n)\n\nfunction waitForCondition(what, seconds, mutator, condition) {\n  return new Promise(async (resolve, reject) => {\n    const start = Date.now()\n    let e\n    try {\n      await mutator()\n      while (true) {\n        if (Date.now() - start > seconds * 1000) {\n          throw new Error(`Timeout of ${seconds} seconds waiting for ${what}` + (e ? `: ${e && e.message || e}` : ''))\n        }\n        await new Promise(r => setTimeout(r, 50))\n        try {\n          await condition()\n          break\n        } catch (err) {\n          e = err\n        }\n      }\n      resolve()\n    } catch (e) {\n      reject(e)\n    }\n  })\n}\n\nfunction test(args, files, options) {\n  return async () => {\n    const hasBundle = args.includes('--bundle')\n    const hasIIFE = args.includes('--format=iife')\n    const hasCJS = args.includes('--format=cjs')\n    const hasESM = args.includes('--format=esm')\n    const formats = hasIIFE ? ['iife'] : hasESM ? ['esm'] : hasCJS || !hasBundle ? ['cjs'] : ['cjs', 'esm']\n    const baseExpectedStderr = (options && options.expectedStderr || '')\n\n    // If the test doesn't specify a format, test both formats\n    for (const format of formats) {\n      const formatArg = `--format=${format}`\n      const logLevelArgs = args.some(arg => arg.startsWith('--log-level=')) ? [] : ['--log-level=warning']\n      const modifiedArgs = (!hasBundle || args.includes(formatArg) ? args : args.concat(formatArg)).concat(logLevelArgs)\n      const thisTestDir = path.join(testDir, '' + testCount++)\n      const patchString = str => str.replace('$ABS_PATH_PREFIX$', path.join(thisTestDir, 'x').slice(0, -1))\n      const expectedStderr = Array.isArray(baseExpectedStderr) ? baseExpectedStderr.map(patchString) : patchString(baseExpectedStderr)\n      await fs.mkdir(thisTestDir, { recursive: true })\n\n      try {\n        // Test setup\n        for (const file in files) {\n          const filePath = path.join(thisTestDir, file)\n          const contents = files[file]\n          await fs.mkdir(path.dirname(filePath), { recursive: true })\n\n          // Optionally symlink the file if the test requests it\n          if (contents.symlink) await fs.symlink(contents.symlink.replace('TEST_DIR_ABS_PATH', thisTestDir), filePath)\n          else await fs.writeFile(filePath, contents)\n        }\n\n        // Run esbuild\n        let stderr\n        if (options && options.cwd) {\n          // Use the shell to set the working directory instead of using node's\n          // \"child_process\" module. For some reason it looks like node doesn't\n          // handle symlinks correctly and some of these tests check esbuild's\n          // behavior in the presence of symlinks. Using the shell is the only\n          // way I could find to do this correctly.\n          const quote = arg => arg.replace(/([#!\"$&'()*,:;<=>?@\\[\\\\\\]^`{|}])/g, '\\\\$1')\n          const cwd = path.join(thisTestDir, options.cwd)\n          const command = ['cd', quote(cwd), '&&', quote(esbuildPath)].concat(modifiedArgs.map(quote)).join(' ')\n          stderr = (await execAsync(command, { stdio: 'pipe' })).stderr\n        } else {\n          stderr = (await execFileAsync(esbuildPath, modifiedArgs, { cwd: thisTestDir, stdio: 'pipe' })).stderr\n        }\n        if (Array.isArray(expectedStderr)) {\n          // An array of possible outputs (due to log output order non-determinism)\n          if (!expectedStderr.includes(stderr))\n            assert.strictEqual(stderr, expectedStderr[0]);\n        } else {\n          assert.strictEqual(stderr, expectedStderr);\n        }\n\n        // Run the resulting node.js file and make sure it exits cleanly. The\n        // use of \"pathToFileURL\" is a workaround for a problem where node\n        // only supports absolute paths on Unix-style systems, not on Windows.\n        // See https://github.com/nodejs/node/issues/31710 for more info.\n        const nodePath = path.join(thisTestDir, 'node')\n        const pjPath = path.join(thisTestDir, 'package.json')\n        const pjExists = await fs.stat(pjPath).then(() => true, () => false)\n        let testExports\n        switch (format) {\n          case 'cjs':\n          case 'iife':\n            if (!pjExists) await fs.writeFile(pjPath, '{\"type\": \"commonjs\"}')\n            testExports = (await import(url.pathToFileURL(`${nodePath}.js`))).default\n            break\n\n          case 'esm':\n            if (!pjExists) await fs.writeFile(pjPath, '{\"type\": \"module\"}')\n            testExports = await import(url.pathToFileURL(`${nodePath}.js`))\n            break\n        }\n\n        // If this is an async test, run the async part\n        if (options && options.async) {\n          if (!(testExports.async instanceof Function))\n            throw new Error('Expected async instanceof Function')\n          await testExports.async()\n        }\n\n        // Clean up test output\n        removeRecursiveSync(thisTestDir)\n      }\n\n      catch (e) {\n        if (e && e.stderr !== void 0) {\n          try {\n            if (Array.isArray(expectedStderr)) {\n              // An array of possible outputs (due to log output order non-determinism)\n              if (!expectedStderr.includes(e.stderr))\n                assert.strictEqual(e.stderr, expectedStderr[0]);\n            } else {\n              assert.strictEqual(e.stderr, expectedStderr);\n            }\n\n            // Clean up test output\n            removeRecursiveSync(thisTestDir)\n            continue;\n          } catch (e2) {\n            e = e2;\n          }\n        }\n        console.error(`❌ test failed: ${e && e.message || e}\n  dir: ${path.relative(dirname, thisTestDir)}\n  args: ${modifiedArgs.join(' ')}\n  files: ${Object.entries(files).map(([k, v]) => `\\n    ${k}: ${JSON.stringify(v)}`).join('')}\n`)\n        return false\n      }\n    }\n\n    return true\n  }\n}\n\n// There's a feature where bundling without \"outfile\" or \"outdir\" writes to stdout instead\nfunction testStdout(input, args, callback) {\n  return async () => {\n    const thisTestDir = path.join(testDir, '' + testCount++)\n\n    try {\n      await fs.mkdir(thisTestDir, { recursive: true })\n      const inputFile = path.join(thisTestDir, 'example.js')\n      await fs.writeFile(inputFile, input)\n\n      // Run whatever check the caller is doing\n      await callback(async () => {\n        const { stdout } = await execFileAsync(\n          esbuildPath, [inputFile, '--log-level=warning'].concat(args), { cwd: thisTestDir, stdio: 'pipe' })\n        return stdout\n      })\n\n      // Clean up test output\n      removeRecursiveSync(thisTestDir)\n    } catch (e) {\n      console.error(`❌ test failed: ${e && e.message || e}\n  dir: ${path.relative(dirname, thisTestDir)}`)\n      return false\n    }\n\n    return true\n  }\n}\n\nfunction testWatch(options, callback) {\n  return async () => {\n    const thisTestDir = path.join(testDir, '' + testCount++)\n    const infile = path.join(thisTestDir, 'in.js')\n    const outdir = path.join(thisTestDir, 'out')\n    const outfile = path.join(outdir, path.basename(infile))\n    const args = ['--watch=forever', infile, '--outdir=' + outdir, '--color'].concat(options.args || [])\n    let metafile\n    let mangleCache\n\n    if (options.metafile) {\n      metafile = path.join(thisTestDir, 'meta.json')\n      args.push('--metafile=' + metafile)\n    }\n\n    if (options.mangleCache) {\n      mangleCache = path.join(thisTestDir, 'mangle.json')\n      args.push('--mangle-cache=' + mangleCache)\n    }\n\n    let stderrPromise\n    try {\n      await fs.mkdir(thisTestDir, { recursive: true })\n      const maxSeconds = 60\n\n      // Start the child\n      const child = childProcess.spawn(esbuildPath, args, {\n        cwd: thisTestDir,\n        stdio: ['inherit', 'inherit', 'pipe'],\n        timeout: maxSeconds * 1000,\n      })\n\n      // Make sure the child is always killed\n      try {\n        // Buffer stderr in case we need it\n        const stderr = []\n        child.stderr.on('data', data => stderr.push(data))\n        const exitPromise = new Promise((_, reject) => {\n          child.on('close', code => reject(new Error(`Child \"esbuild\" process exited with code ${code}`)))\n        })\n        stderrPromise = new Promise(resolve => {\n          child.stderr.on('end', () => resolve(Buffer.concat(stderr).toString()))\n        })\n\n        // Run whatever check the caller is doing\n        let timeout\n        await Promise.race([\n          new Promise((_, reject) => {\n            timeout = setTimeout(() => reject(new Error(`Timeout of ${maxSeconds} seconds exceeded`)), maxSeconds * 1000)\n          }),\n          exitPromise,\n          callback({\n            infile,\n            outfile,\n            metafile,\n            mangleCache,\n          }),\n        ])\n        clearTimeout(timeout)\n\n        // Clean up test output\n        removeRecursiveSync(thisTestDir)\n      } finally {\n        child.kill()\n      }\n    } catch (e) {\n      let stderr = stderrPromise ? '\\n  stderr:' + ('\\n' + await stderrPromise).split('\\n').join('\\n    ') : ''\n      console.error(`❌ test failed: ${e && e.message || e}\n  dir: ${path.relative(dirname, thisTestDir)}\n  args: ${args.join(' ')}` + stderr)\n      return false\n    }\n\n    return true\n  }\n}\n\nfunction testWatchStdout(sequence) {\n  return async () => {\n    const thisTestDir = path.join(testDir, '' + testCount++)\n    const infile = path.join(thisTestDir, 'in.js')\n    const args = ['--watch=forever', infile]\n\n    try {\n      await fs.mkdir(thisTestDir, { recursive: true })\n      await fs.writeFile(infile, sequence[0].input)\n      const maxSeconds = 60\n\n      // Start the child\n      const child = childProcess.spawn(esbuildPath, args, {\n        cwd: thisTestDir,\n        stdio: ['inherit', 'pipe', 'pipe'],\n        timeout: maxSeconds * 1000,\n      })\n\n      // Make sure the child is always killed\n      try {\n        for (const { input, stdout: expectedStdout, stderr: expectedStderr } of sequence) {\n          let totalStdout = ''\n          let totalStderr = ''\n          let stdoutBuffer = ''\n          let stderrBuffer = ''\n          const onstdout = data => {\n            totalStdout += data\n            stdoutBuffer += data\n            check()\n          }\n          const onstderr = data => {\n            totalStderr += data\n            stderrBuffer += data\n            check()\n          }\n          let check = () => { }\n\n          child.stdout.on('data', onstdout)\n          child.stderr.on('data', onstderr)\n\n          await new Promise((resolve, reject) => {\n            const seconds = 30\n            const timeout = setTimeout(() => reject(new Error(\n              `Watch mode + stdout test failed to match expected output after ${seconds} seconds\n  input: ${JSON.stringify(input)}\n  stdout: ${JSON.stringify(totalStdout)}\n  stderr: ${JSON.stringify(totalStderr)}\n`)), seconds * 1000)\n\n            check = () => {\n              let index\n\n              while ((index = stdoutBuffer.indexOf('\\n')) >= 0) {\n                const line = stdoutBuffer.slice(0, index)\n                stdoutBuffer = stdoutBuffer.slice(index + 1)\n                if (line === expectedStdout[0]) expectedStdout.shift()\n              }\n\n              while ((index = stderrBuffer.indexOf('\\n')) >= 0) {\n                const line = stderrBuffer.slice(0, index)\n                stderrBuffer = stderrBuffer.slice(index + 1)\n                if (line === expectedStderr[0]) expectedStderr.shift()\n              }\n\n              if (!expectedStdout.length && !expectedStderr.length) {\n                clearTimeout(timeout)\n                resolve()\n              }\n            }\n\n            writeFileAtomic(infile, input)\n          })\n\n          child.stdout.off('data', onstdout)\n          child.stderr.off('data', onstderr)\n        }\n      } finally {\n        child.kill()\n      }\n    } catch (e) {\n      console.error(`❌ test failed: ${e && e.message || e}\n  dir: ${path.relative(dirname, thisTestDir)}\n  args: ${args.join(' ')}`)\n      return false\n    }\n\n    return true\n  }\n}\n\nasync function main() {\n  // Create a fresh test directory\n  removeRecursiveSync(testDir)\n  await fs.mkdir(testDir, { recursive: true })\n\n  // Run tests in batches so they work in CI, which has a limited memory ceiling\n  let allTestsPassed = true\n  let batch = 32\n  for (let i = 0; i < tests.length; i += batch) {\n    let promises = []\n    for (let test of tests.slice(i, i + batch)) {\n      let promise = test()\n      promise.then(\n        success => { if (!success) allTestsPassed = false },\n        () => allTestsPassed = false,\n      )\n      promises.push(promise)\n    }\n    await Promise.all(promises)\n  }\n\n  if (!allTestsPassed) {\n    console.error(`❌ end-to-end tests failed`)\n    process.exit(1)\n  } else {\n    console.log(`✅ end-to-end tests passed`)\n    removeRecursiveSync(testDir)\n  }\n}\n\nmain()\n"
  },
  {
    "path": "scripts/esbuild.js",
    "content": "const childProcess = require('child_process')\nconst path = require('path')\nconst fs = require('fs')\nconst os = require('os')\n\nconst repoDir = path.dirname(__dirname)\nconst denoDir = path.join(repoDir, 'deno')\nconst npmDir = path.join(repoDir, 'npm', 'esbuild')\nconst version = fs.readFileSync(path.join(repoDir, 'version.txt'), 'utf8').trim()\nconst nodeTarget = 'node10'; // See: https://nodejs.org/en/about/releases/\nconst denoTarget = 'deno1'; // See: https://docs.deno.com/runtime/fundamentals/stability_and_releases/\nconst umdBrowserTarget = 'es2015'; // Transpiles \"async\"\nconst esmBrowserTarget = 'es2017'; // Preserves \"async\"\n\nconst buildNeutralLib = (esbuildPath) => {\n  const libDir = path.join(npmDir, 'lib')\n  const binDir = path.join(npmDir, 'bin')\n  fs.mkdirSync(libDir, { recursive: true })\n  fs.mkdirSync(binDir, { recursive: true })\n\n  // Generate \"npm/esbuild/install.js\"\n  childProcess.execFileSync(esbuildPath, [\n    path.join(repoDir, 'lib', 'npm', 'node-install.ts'),\n    '--outfile=' + path.join(npmDir, 'install.js'),\n    '--bundle',\n    '--target=' + nodeTarget,\n    // Note: https://socket.dev have complained that inlining the version into\n    // the install script messes up some internal scanning that they do by\n    // making it seem like esbuild's install script code changes with every\n    // esbuild release. So now we read it from \"package.json\" instead.\n    // '--define:ESBUILD_VERSION=' + JSON.stringify(version),\n    '--external:esbuild',\n    '--platform=node',\n    '--log-level=warning',\n  ], { cwd: repoDir })\n\n  // Generate \"npm/esbuild/lib/main.js\"\n  childProcess.execFileSync(esbuildPath, [\n    path.join(repoDir, 'lib', 'npm', 'node.ts'),\n    '--outfile=' + path.join(libDir, 'main.js'),\n    '--bundle',\n    '--target=' + nodeTarget,\n    '--define:WASM=false',\n    '--define:ESBUILD_VERSION=' + JSON.stringify(version),\n    '--external:esbuild',\n    '--platform=node',\n    '--log-level=warning',\n  ], { cwd: repoDir })\n\n  // Generate \"npm/esbuild/bin/esbuild\"\n  childProcess.execFileSync(esbuildPath, [\n    path.join(repoDir, 'lib', 'npm', 'node-shim.ts'),\n    '--outfile=' + path.join(binDir, 'esbuild'),\n    '--bundle',\n    '--target=' + nodeTarget,\n    '--define:ESBUILD_VERSION=' + JSON.stringify(version),\n    '--external:esbuild',\n    '--platform=node',\n    '--log-level=warning',\n  ], { cwd: repoDir })\n\n  // Generate \"npm/esbuild/lib/main.d.ts\"\n  const types_ts = fs.readFileSync(path.join(repoDir, 'lib', 'shared', 'types.ts'), 'utf8')\n  fs.writeFileSync(path.join(libDir, 'main.d.ts'), types_ts)\n\n  // Get supported platforms\n  const platforms = { exports: {} }\n  new Function('module', 'exports', 'require', childProcess.execFileSync(esbuildPath, [\n    path.join(repoDir, 'lib', 'npm', 'node-platform.ts'),\n    '--bundle',\n    '--target=' + nodeTarget,\n    '--external:esbuild',\n    '--platform=node',\n    '--log-level=warning',\n  ], { cwd: repoDir }))(platforms, platforms.exports, require)\n  const optionalDependencies = Object.fromEntries(Object.values({\n    ...platforms.exports.knownWindowsPackages,\n    ...platforms.exports.knownUnixlikePackages,\n    ...platforms.exports.knownWebAssemblyFallbackPackages,\n  }).sort().map(x => [x, version]))\n\n  // Update \"npm/esbuild/package.json\"\n  const pjPath = path.join(npmDir, 'package.json')\n  const package_json = JSON.parse(fs.readFileSync(pjPath, 'utf8'))\n  package_json.optionalDependencies = optionalDependencies\n  fs.writeFileSync(pjPath, JSON.stringify(package_json, null, 2) + '\\n')\n}\n\nasync function generateWorkerCode({ esbuildPath, wasm_exec_js, minify, target }) {\n  const input = `\n    let onmessage\n    let globalThis = {}\n    for (let o = self; o; o = Object.getPrototypeOf(o))\n      for (let k of Object.getOwnPropertyNames(o))\n        if (!(k in globalThis))\n          Object.defineProperty(globalThis, k, { get: () => self[k] })\n    ${wasm_exec_js.replace(/\\bfs\\./g, 'globalThis.fs.')}\n    ${fs.readFileSync(path.join(repoDir, 'lib', 'shared', 'worker.ts'), 'utf8')}\n    return m => onmessage(m)\n  `\n  const args = [\n    '--loader=ts',\n    '--target=' + target,\n    '--define:ESBUILD_VERSION=' + JSON.stringify(version),\n  ].concat(minify ? ['--minify'] : [])\n\n  // Note: This uses \"execFile\" because \"execFileSync\" in node appears to have\n  // a bug. Specifically when using the \"input\" option of \"execFileSync\" to\n  // provide stdin, sometimes (~2% of the time?) node writes all of the input\n  // but then doesn't close the stream. The Go side is stuck reading from stdin\n  // within \"ioutil.ReadAll(os.Stdin)\" so I suspect it's a bug in node, not in\n  // Go. Explicitly calling \"stdin.end()\" on the node side appears to fix it.\n  const wasmExecAndWorker = (await new Promise((resolve, reject) => {\n    const proc = childProcess.execFile(esbuildPath, args, { cwd: repoDir }, (err, stdout) => {\n      if (err) reject(err)\n      else resolve(stdout)\n    })\n    proc.stdin.write(input)\n    proc.stdin.end()\n  })).toString().trim()\n\n  const commentLines = wasm_exec_js.split('\\n')\n  const firstNonComment = commentLines.findIndex(line => !line.startsWith('//'))\n  const commentPrefix = '\\n' + commentLines.slice(0, firstNonComment).join('\\n') + '\\n'\n  if (minify) return `(postMessage=>{${commentPrefix}${wasmExecAndWorker}})`\n  return `((postMessage) => {${(commentPrefix + wasmExecAndWorker).replace(/\\n/g, '\\n      ')}\\n    })`\n}\n\nexports.buildWasmLib = async (esbuildPath) => {\n  // Asynchronously start building the WebAssembly module\n  const npmWasmDir = path.join(repoDir, 'npm', 'esbuild-wasm')\n  const goBuildPromise = new Promise((resolve, reject) => childProcess.execFile('go',\n    [\n      'build',\n      '-o', path.join(npmWasmDir, 'esbuild.wasm'),\n      '-ldflags=-s -w', // This removes ~0.14mb of unnecessary WebAssembly code\n      '-trimpath',\n      path.join(repoDir, 'cmd', 'esbuild'),\n    ],\n    { cwd: repoDir, stdio: 'inherit', env: { ...process.env, GOOS: 'js', GOARCH: 'wasm' } },\n    err => err ? reject(err) : resolve()))\n\n  const libDir = path.join(npmWasmDir, 'lib')\n  const esmDir = path.join(npmWasmDir, 'esm')\n  fs.mkdirSync(libDir, { recursive: true })\n  fs.mkdirSync(esmDir, { recursive: true })\n\n  // Generate \"npm/esbuild-wasm/wasm_exec.js\"\n  const GOROOT = childProcess.execFileSync('go', ['env', 'GOROOT']).toString().trim()\n  let wasm_exec_js = fs.readFileSync(path.join(GOROOT, 'lib', 'wasm', 'wasm_exec.js'), 'utf8')\n  let wasm_exec_node_js = fs.readFileSync(path.join(GOROOT, 'lib', 'wasm', 'wasm_exec_node.js'), 'utf8')\n  fs.writeFileSync(path.join(npmWasmDir, 'wasm_exec.js'), wasm_exec_js)\n  fs.writeFileSync(path.join(npmWasmDir, 'wasm_exec_node.js'), wasm_exec_node_js)\n\n  // Generate \"npm/esbuild-wasm/lib/main.js\"\n  childProcess.execFileSync(esbuildPath, [\n    path.join(repoDir, 'lib', 'npm', 'node.ts'),\n    '--outfile=' + path.join(libDir, 'main.js'),\n    '--bundle',\n    '--target=' + nodeTarget,\n    '--format=cjs',\n    '--define:WASM=true',\n    '--define:ESBUILD_VERSION=' + JSON.stringify(version),\n    '--external:esbuild',\n    '--platform=node',\n    '--log-level=warning',\n  ], { cwd: repoDir })\n\n  // Generate \"npm/esbuild-wasm/lib/main.d.ts\" and \"npm/esbuild-wasm/lib/browser.d.ts\"\n  const types_ts = fs.readFileSync(path.join(repoDir, 'lib', 'shared', 'types.ts'), 'utf8')\n  fs.writeFileSync(path.join(libDir, 'main.d.ts'), types_ts)\n  fs.writeFileSync(path.join(libDir, 'browser.d.ts'), types_ts)\n  fs.writeFileSync(path.join(esmDir, 'browser.d.ts'), types_ts)\n\n  for (const minify of [false, true]) {\n    const minifyFlags = minify ? ['--minify'] : []\n    const wasmWorkerCodeUMD = await generateWorkerCode({ esbuildPath, wasm_exec_js, minify, target: umdBrowserTarget })\n    const wasmWorkerCodeESM = await generateWorkerCode({ esbuildPath, wasm_exec_js, minify, target: esmBrowserTarget })\n\n    // Generate \"npm/esbuild-wasm/lib/browser.*\"\n    const umdPrefix = `(module=>{`\n    const umdSuffix = `})(typeof module===\"object\"?module:{set exports(x){(typeof self!==\"undefined\"?self:this).esbuild=x}});`\n    const browserCJS = childProcess.execFileSync(esbuildPath, [\n      path.join(repoDir, 'lib', 'npm', 'browser.ts'),\n      '--bundle',\n      '--target=' + umdBrowserTarget,\n      '--format=cjs',\n      '--define:ESBUILD_VERSION=' + JSON.stringify(version),\n      '--define:WEB_WORKER_SOURCE_CODE=' + JSON.stringify(wasmWorkerCodeUMD),\n      '--banner:js=' + umdPrefix,\n      '--footer:js=' + umdSuffix,\n      '--log-level=warning',\n    ].concat(minifyFlags), { cwd: repoDir }).toString().replace('WEB_WORKER_FUNCTION', wasmWorkerCodeUMD)\n    fs.writeFileSync(path.join(libDir, minify ? 'browser.min.js' : 'browser.js'), browserCJS)\n\n    // Generate \"npm/esbuild-wasm/esm/browser.*\"\n    const browserESM = childProcess.execFileSync(esbuildPath, [\n      path.join(repoDir, 'lib', 'npm', 'browser.ts'),\n      '--bundle',\n      '--target=' + esmBrowserTarget,\n      '--format=esm',\n      '--define:ESBUILD_VERSION=' + JSON.stringify(version),\n      '--define:WEB_WORKER_SOURCE_CODE=' + JSON.stringify(wasmWorkerCodeESM),\n      '--log-level=warning',\n    ].concat(minifyFlags), { cwd: repoDir }).toString().replace('WEB_WORKER_FUNCTION', wasmWorkerCodeESM)\n    fs.writeFileSync(path.join(esmDir, minify ? 'browser.min.js' : 'browser.js'), browserESM)\n  }\n\n  // Join with the asynchronous WebAssembly build\n  await goBuildPromise\n\n  // Also copy this into the WebAssembly shim directories\n  for (const dir of [\n    path.join(repoDir, 'npm', '@esbuild', 'android-arm'),\n    path.join(repoDir, 'npm', '@esbuild', 'android-x64'),\n    path.join(repoDir, 'npm', '@esbuild', 'openharmony-arm64'),\n  ]) {\n    fs.mkdirSync(path.join(dir, 'bin'), { recursive: true })\n    fs.writeFileSync(path.join(dir, 'wasm_exec.js'), wasm_exec_js)\n    fs.writeFileSync(path.join(dir, 'wasm_exec_node.js'), wasm_exec_node_js)\n    fs.copyFileSync(path.join(npmWasmDir, 'bin', 'esbuild'), path.join(dir, 'bin', 'esbuild'))\n    fs.copyFileSync(path.join(npmWasmDir, 'esbuild.wasm'), path.join(dir, 'esbuild.wasm'))\n  }\n}\n\nconst buildDenoLib = async (esbuildPath) => {\n  // Generate \"deno/mod.js\"\n  childProcess.execFileSync(esbuildPath, [\n    path.join(repoDir, 'lib', 'deno', 'mod.ts'),\n    '--bundle',\n    '--outfile=' + path.join(denoDir, 'mod.js'),\n    '--target=' + denoTarget,\n    '--define:ESBUILD_VERSION=' + JSON.stringify(version),\n    '--platform=neutral',\n    '--log-level=warning',\n    '--banner:js=/// <reference types=\"./mod.d.ts\" />',\n  ], { cwd: repoDir })\n\n  // Generate \"deno/wasm.js\"\n  const GOROOT = childProcess.execFileSync('go', ['env', 'GOROOT']).toString().trim()\n  let wasm_exec_js = fs.readFileSync(path.join(GOROOT, 'lib', 'wasm', 'wasm_exec.js'), 'utf8')\n  const wasmWorkerCode = await generateWorkerCode({ esbuildPath, wasm_exec_js, minify: true, target: denoTarget })\n  const modWASM = childProcess.execFileSync(esbuildPath, [\n    path.join(repoDir, 'lib', 'deno', 'wasm.ts'),\n    '--bundle',\n    '--target=' + denoTarget,\n    '--define:ESBUILD_VERSION=' + JSON.stringify(version),\n    '--define:WEB_WORKER_SOURCE_CODE=' + JSON.stringify(wasmWorkerCode),\n    '--platform=neutral',\n    '--log-level=warning',\n    '--banner:js=/// <reference types=\"./wasm.d.ts\" />',\n  ], { cwd: repoDir }).toString().replace('WEB_WORKER_FUNCTION', wasmWorkerCode)\n  fs.writeFileSync(path.join(denoDir, 'wasm.js'), modWASM)\n\n  // Generate \"deno/mod.d.ts\"\n  const types_ts = fs.readFileSync(path.join(repoDir, 'lib', 'shared', 'types.ts'), 'utf8')\n  fs.writeFileSync(path.join(denoDir, 'mod.d.ts'), types_ts)\n  fs.writeFileSync(path.join(denoDir, 'wasm.d.ts'), types_ts)\n\n  // And copy the WebAssembly file over to the Deno library as well\n  fs.copyFileSync(path.join(repoDir, 'npm', 'esbuild-wasm', 'esbuild.wasm'), path.join(repoDir, 'deno', 'esbuild.wasm'))\n}\n\n// Writing a file atomically is important for watch mode tests since we don't\n// want to read the file after it has been truncated but before the new contents\n// have been written.\nexports.writeFileAtomic = (where, contents) => {\n  // Note: Can't use \"os.tmpdir()\" because that doesn't work on Windows. CI runs\n  // tests on D:\\ and the temporary directory is on C:\\ or the other way around.\n  // And apparently it's impossible to move files between C:\\ and D:\\ or something.\n  // So we have to write the file in the same directory as the destination. This is\n  // unfortunate because it will unnecessarily trigger extra watch mode rebuilds.\n  // So we have to make our tests extra robust so they can still work with random\n  // extra rebuilds thrown in.\n  const file = path.join(path.dirname(where), '.esbuild-atomic-file-' + Math.random().toString(36).slice(2))\n  fs.writeFileSync(file, contents)\n  fs.renameSync(file, where)\n}\n\nexports.buildBinary = () => {\n  childProcess.execFileSync('go', ['build', '-ldflags=-s -w', '-trimpath', './cmd/esbuild'], { cwd: repoDir, stdio: 'ignore' })\n  return path.join(repoDir, process.platform === 'win32' ? 'esbuild.exe' : 'esbuild')\n}\n\nexports.removeRecursiveSync = path => {\n  try {\n    fs.rmSync(path, { recursive: true })\n  } catch (e) {\n    // Removing stuff on Windows is flaky and unreliable. Don't fail tests\n    // on CI if Windows is just being a pain. Common causes of flakes include\n    // random EPERM and ENOTEMPTY errors.\n    //\n    // The general \"solution\" to this is to try asking Windows to redo the\n    // failing operation repeatedly until eventually giving up after a\n    // timeout. But that doesn't guarantee that flakes will be fixed so we\n    // just give up instead. People that want reasonable file system\n    // behavior on Windows should use WSL instead.\n  }\n}\n\nconst updateVersionPackageJSON = pathToPackageJSON => {\n  const version = fs.readFileSync(path.join(path.dirname(__dirname), 'version.txt'), 'utf8').trim()\n  const json = JSON.parse(fs.readFileSync(pathToPackageJSON, 'utf8'))\n\n  if (json.version !== version) {\n    json.version = version\n    fs.writeFileSync(pathToPackageJSON, JSON.stringify(json, null, 2) + '\\n')\n  }\n}\n\nexports.installForTests = () => {\n  // Build the \"esbuild\" binary and library\n  const esbuildPath = exports.buildBinary()\n  buildNeutralLib(esbuildPath)\n\n  // Install the \"esbuild\" package to a temporary directory. On Windows, it's\n  // sometimes randomly impossible to delete this installation directory. My\n  // best guess is that this is because the esbuild process is kept alive until\n  // the process exits for \"buildSync\" and \"transformSync\", and that sometimes\n  // prevents Windows from deleting the directory it's in. The call in tests to\n  // \"rimraf.sync()\" appears to hang when this happens. Other operating systems\n  // don't have a problem with this. This has only been a problem on the Windows\n  // VM in GitHub CI. I cannot reproduce this issue myself.\n  const installDir = path.join(os.tmpdir(), 'esbuild-' + Math.random().toString(36).slice(2))\n  const env = { ...process.env, ESBUILD_BINARY_PATH: esbuildPath }\n  fs.mkdirSync(installDir)\n  fs.writeFileSync(path.join(installDir, 'package.json'), '{}')\n  childProcess.execSync(`npm pack --silent \"${npmDir}\"`, { cwd: installDir, stdio: 'inherit' })\n  childProcess.execSync(`npm install --silent --no-audit --no-optional --ignore-scripts=false --progress=false esbuild-${version}.tgz`, { cwd: installDir, env, stdio: 'inherit' })\n\n  // Evaluate the code\n  const ESBUILD_PACKAGE_PATH = path.join(installDir, 'node_modules', 'esbuild')\n  const mod = require(ESBUILD_PACKAGE_PATH)\n  Object.defineProperty(mod, 'ESBUILD_PACKAGE_PATH', { value: ESBUILD_PACKAGE_PATH })\n  return mod\n}\n\nconst updateVersionGo = () => {\n  const version_txt = fs.readFileSync(path.join(repoDir, 'version.txt'), 'utf8').trim()\n  const version_go = `package main\\n\\nconst esbuildVersion = \"${version_txt}\"\\n`\n  const version_go_path = path.join(repoDir, 'cmd', 'esbuild', 'version.go')\n\n  // Update this atomically to avoid issues with this being overwritten during use\n  const temp_path = version_go_path + Math.random().toString(36).slice(1)\n  fs.writeFileSync(temp_path, version_go)\n  fs.renameSync(temp_path, version_go_path)\n}\n\n// This is helpful for ES6 modules which don't have access to __dirname\nexports.dirname = __dirname\n\n// The main Makefile invokes this script before publishing\nif (require.main === module) {\n  if (process.argv.indexOf('--wasm') >= 0) exports.buildWasmLib(process.argv[2])\n  else if (process.argv.indexOf('--deno') >= 0) buildDenoLib(process.argv[2])\n  else if (process.argv.indexOf('--version') >= 0) updateVersionPackageJSON(process.argv[2])\n  else if (process.argv.indexOf('--neutral') >= 0) buildNeutralLib(process.argv[2])\n  else if (process.argv.indexOf('--update-version-go') >= 0) updateVersionGo()\n  else throw new Error('Expected a flag')\n}\n"
  },
  {
    "path": "scripts/gen-unicode-table.js",
    "content": "const fs = require('fs')\nconst path = require('path')\n\n// ES5 reference: https://es5.github.io/\n//\n// A conforming implementation of this International standard shall interpret\n// characters in conformance with the Unicode Standard, Version 3.0 or later\n// and ISO/IEC 10646-1 with either UCS-2 or UTF-16 as the adopted encoding\n// form, implementation level 3. If the adopted ISO/IEC 10646-1 subset is not\n// otherwise specified, it is presumed to be the BMP subset, collection 300.\n//\n// UnicodeLetter: any character in the Unicode categories “Uppercase letter (Lu)”,\n// “Lowercase letter (Ll)”, “Titlecase letter (Lt)”, “Modifier letter (Lm)”,\n// “Other letter (Lo)”, or “Letter number (Nl)”.\nconst idStartES5 = [].concat(\n  require('@unicode/unicode-3.0.0/General_Category/Uppercase_Letter/code-points'),\n  require('@unicode/unicode-3.0.0/General_Category/Lowercase_Letter/code-points'),\n  require('@unicode/unicode-3.0.0/General_Category/Titlecase_Letter/code-points'),\n  require('@unicode/unicode-3.0.0/General_Category/Modifier_Letter/code-points'),\n  require('@unicode/unicode-3.0.0/General_Category/Other_Letter/code-points'),\n\n  // The \"letter number\" category is not included because old versions of Safari\n  // had a bug where they didn't include it. This means it does not match ES5.\n  // We need to make sure we escape these characters so Safari can read them.\n  // See https://github.com/evanw/esbuild/issues/1349 for more information.\n  // require('@unicode/unicode-3.0.0/General_Category/Letter_Number/code-points'),\n).sort((a, b) => a - b)\n\n// UnicodeCombiningMark: any character in the Unicode categories “Non-spacing mark (Mn)”\n// or “Combining spacing mark (Mc)”\n// UnicodeDigit: any character in the Unicode category “Decimal number (Nd)”\n// UnicodeConnectorPunctuation: any character in the Unicode category “Connector punctuation (Pc)”\nconst idContinueES5 = idStartES5.concat(\n  require('@unicode/unicode-3.0.0/General_Category/Nonspacing_Mark/code-points'),\n  require('@unicode/unicode-3.0.0/General_Category/Spacing_Mark/code-points'),\n  require('@unicode/unicode-3.0.0/General_Category/Decimal_Number/code-points'),\n  require('@unicode/unicode-3.0.0/General_Category/Connector_Punctuation/code-points'),\n).sort((a, b) => a - b)\n\n// ESNext reference: https://tc39.es/ecma262/\n//\n// A conforming implementation of ECMAScript must interpret source text input\n// in conformance with the Unicode Standard, Version 5.1.0 or later and ISO/IEC\n// 10646. If the adopted ISO/IEC 10646-1 subset is not otherwise specified, it\n// is presumed to be the Unicode set, collection 10646.\n//\n// UnicodeIDStart: any Unicode code point with the Unicode property “ID_Start”\nconst idStartESNext = require('@unicode/unicode-15.1.0/Binary_Property/ID_Start/code-points')\nconst idStartESNextSet = new Set(idStartESNext)\n\n// Unicode 4.1 through Unicode 15 omitted these two characters from ID_Continue\n// by accident. However, this accident was corrected in Unicode 15.1. Any JS VM\n// that supports ES6+ but that uses a version of Unicode earlier than 15.1 will\n// consider these to be a syntax error, so we deliberately omit these characters\n// from the set of identifiers that are valid in both ES5 and ES6+. For more info\n// see 2.2 in https://www.unicode.org/L2/L2023/23160-utc176-properties-recs.pdf\nconst ID_Continue_mistake = new Set([0x30FB, 0xFF65])\n\n// UnicodeIDContinue: any Unicode code point with the Unicode property “ID_Continue”\nconst idContinueESNext = require('@unicode/unicode-15.1.0/Binary_Property/ID_Continue/code-points')\nconst idContinueESNextSet = new Set(idContinueESNext)\n\n// These identifiers are valid in both ES5 and ES6+ (i.e. an intersection of both)\nconst idStartES5AndESNext = idStartES5.filter(n => idStartESNextSet.has(n))\nconst idContinueES5AndESNext = idContinueES5.filter(n => idContinueESNextSet.has(n) && !ID_Continue_mistake.has(n))\n\n// These identifiers are valid in either ES5 or ES6+ (i.e. a union of both)\nconst idStartES5OrESNext = [...new Set(idStartES5.concat(idStartESNext))].sort((a, b) => a - b)\nconst idContinueES5OrESNext = [...new Set(idContinueES5.concat(idContinueESNext))].sort((a, b) => a - b)\n\nfunction generateRangeTable(codePoints) {\n  let lines = []\n  let index = 0\n  let latinOffset = 0\n\n  while (latinOffset < codePoints.length && codePoints[latinOffset] <= 0xFF) {\n    latinOffset++\n  }\n\n  lines.push(\n    `&unicode.RangeTable{`,\n    `\\tLatinOffset: ${latinOffset},`,\n    `\\tR16: []unicode.Range16{`,\n  )\n\n  // 16-bit code points\n  while (index < codePoints.length && codePoints[index] < 0x1000) {\n    let start = codePoints[index]\n    index++\n    while (index < codePoints.length && codePoints[index] < 0x1000 && codePoints[index] === codePoints[index - 1] + 1) {\n      index++\n    }\n    let end = codePoints[index - 1]\n    lines.push(`\\t\\t{Lo: 0x${start.toString(16)}, Hi: 0x${end.toString(16)}, Stride: 1},`)\n  }\n\n  lines.push(\n    `\\t},`,\n    `\\tR32: []unicode.Range32{`,\n  )\n\n  // 32-bit code points\n  while (index < codePoints.length) {\n    let start = codePoints[index]\n    index++\n    while (index < codePoints.length && codePoints[index] === codePoints[index - 1] + 1) {\n      index++\n    }\n    let end = codePoints[index - 1]\n    lines.push(`\\t\\t{Lo: 0x${start.toString(16)}, Hi: 0x${end.toString(16)}, Stride: 1},`)\n  }\n\n  lines.push(\n    `\\t},`,\n    `}`,\n  )\n  return lines.join('\\n')\n}\n\nfs.writeFileSync(path.join(__dirname, '..', 'internal', 'js_ast', 'unicode.go'),\n  `// This file was automatically generated by ${path.basename(__filename)}. Do not edit.\npackage js_ast\n\nimport \"unicode\"\n\nvar idStartES5AndESNext = ${generateRangeTable(idStartES5AndESNext)}\n\nvar idContinueES5AndESNext = ${generateRangeTable(idContinueES5AndESNext)}\n\nvar idStartES5OrESNext = ${generateRangeTable(idStartES5OrESNext)}\n\nvar idContinueES5OrESNext = ${generateRangeTable(idContinueES5OrESNext)}\n`)\n"
  },
  {
    "path": "scripts/gradient-tests.css",
    "content": ".linear.red_to_green-esbuild {\n  background: linear-gradient(to right, color(display-p3 1 0 0), color(display-p3 0 0.6 0));\n}\n\n.radial.red_to_green-esbuild {\n  background: radial-gradient(color(display-p3 1 0 0), color(display-p3 0 0.6 0));\n}\n\n.conic.red_to_green-esbuild {\n  background: conic-gradient(color(display-p3 1 0 0), color(display-p3 0 0.6 0));\n}\n\n.linear.rainbow_shorter-esbuild {\n  background: linear-gradient(to right in hwb shorter hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n}\n\n.radial.rainbow_shorter-esbuild {\n  background: radial-gradient(in hwb shorter hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n}\n\n.conic.rainbow_shorter-esbuild {\n  background: conic-gradient(in hwb shorter hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n}\n\n.linear.rainbow_longer-esbuild {\n  background: linear-gradient(to right in hsl longer hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n}\n\n.radial.rainbow_longer-esbuild {\n  background: radial-gradient(in hsl longer hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n}\n\n.conic.rainbow_longer-esbuild {\n  background: conic-gradient(in hsl longer hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n}\n\n.linear.rainbow_increasing-esbuild {\n  background: linear-gradient(to right in lch increasing hue, hsl(240deg 100% 75%) 10%, hsl(180deg 100% 75%) 90%);\n}\n\n.radial.rainbow_increasing-esbuild {\n  background: radial-gradient(in lch increasing hue, hsl(240deg 100% 75%) 10%, hsl(180deg 100% 75%) 90%);\n}\n\n.conic.rainbow_increasing-esbuild {\n  background: conic-gradient(in lch increasing hue, hsl(240deg 100% 75%) 10%, hsl(180deg 100% 75%) 90%);\n}\n\n.linear.rainbow_decreasing-esbuild {\n  background: linear-gradient(to right in oklch decreasing hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n}\n\n.radial.rainbow_decreasing-esbuild {\n  background: radial-gradient(in oklch decreasing hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n}\n\n.conic.rainbow_decreasing-esbuild {\n  background: conic-gradient(in oklch decreasing hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n}\n\n.linear.midpoint_hint-esbuild {\n  background: linear-gradient(to right, #f00, #ff0, 75%, #0ff, #00f);\n}\n\n.radial.midpoint_hint-esbuild {\n  background: radial-gradient(#f00, #ff0, 75%, #0ff, #00f);\n}\n\n.conic.midpoint_hint-esbuild {\n  background: conic-gradient(#f00, #ff0, 75%, #0ff, #00f);\n}\n\n.linear.premultiplied_alpha-esbuild {\n  background: linear-gradient(to right, #f00f, 10%, #00f1, 90%, #0f0f);\n}\n\n.radial.premultiplied_alpha-esbuild {\n  background: radial-gradient(#f00f, 10%, #00f1, 90%, #0f0f);\n}\n\n.conic.premultiplied_alpha-esbuild {\n  background: conic-gradient(#f00f, 10%, #00f1, 90%, #0f0f);\n}\n\n.linear.mixed_units-esbuild {\n  background: linear-gradient(to right, color(display-p3 0.4 0 1) 30px, color(display-p3 0.96 0.75 0.4) 60%);\n}\n\n.radial.mixed_units-esbuild {\n  background: radial-gradient(color(display-p3 0.4 0 1) 30px, color(display-p3 1 0.75 0.4) 60%);\n}\n\n.conic.mixed_units-esbuild {\n  background: conic-gradient(color(display-p3 0.4 0 1) 30deg, color(display-p3 1 0.75 0.4) 60%);\n}\n"
  },
  {
    "path": "scripts/gradient-tests.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n  <meta charset=\"utf8\">\n  <link rel=\"stylesheet\" href=\"out.css\">\n  <style>\n    body {\n      margin: 30px;\n      font: 16px/20px sans-serif;\n      color: black;\n      background: white;\n    }\n\n    @media (prefers-color-scheme: dark) {\n      body {\n        color: white;\n        background: black;\n      }\n    }\n\n    a {\n      color: inherit;\n    }\n\n    p {\n      margin: 20px 0;\n    }\n\n    pre {\n      margin: 20px 0 10px 0;\n      font: 14px/20px Monaco, monospace;\n      white-space: pre-wrap;\n    }\n\n    h2 {\n      margin: 50px 0 0 0;\n    }\n\n    .linear {\n      max-width: 400px;\n      height: 20px;\n      text-indent: 4px;\n      font-size: 14px;\n      color: white;\n      text-shadow: 0 0 3px black;\n      background: repeating-linear-gradient(-45deg,\n          rgba(191, 191, 191, 0.4) 0 7px,\n          transparent 7px 14px);\n    }\n\n    section {\n      margin-top: 12px;\n      display: flex;\n    }\n\n    .radial+.radial {\n      margin-right: 12px;\n    }\n\n    .radial,\n    .conic {\n      width: 97px;\n      height: 97px;\n      text-align: center;\n      line-height: 97px;\n      font-size: 14px;\n      color: white;\n      text-shadow: 0 0 3px black;\n      background: repeating-linear-gradient(-45deg,\n          transparent 0 6.86px,\n          rgba(191, 191, 191, 0.4) 6.86px 13.72px);\n    }\n\n    .checkerboard {\n      position: relative;\n    }\n\n    .checkerboard:after {\n      content: ' ';\n      display: block;\n      position: absolute;\n      left: 0;\n      top: 0;\n      right: 0;\n      bottom: 0;\n      z-index: -1;\n      background: url('data:image/svg+xml,<svg width=\"20\" height=\"20\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"20\" height=\"20\" fill=\"white\"/><path d=\"M0 10V0H10V10H20V20H10V10H0Z\" fill=\"%23EEEEEE\"/></svg>');\n    }\n\n    .linear.red_to_green-native {\n      background: linear-gradient(to right, color(display-p3 1 0 0), color(display-p3 0 0.6 0));\n    }\n\n    .radial.red_to_green-native {\n      background: radial-gradient(color(display-p3 1 0 0), color(display-p3 0 0.6 0));\n    }\n\n    .conic.red_to_green-native {\n      background: conic-gradient(color(display-p3 1 0 0), color(display-p3 0 0.6 0));\n    }\n\n    .linear.rainbow_shorter-native {\n      background: linear-gradient(to right in hwb shorter hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n    }\n\n    .radial.rainbow_shorter-native {\n      background: radial-gradient(in hwb shorter hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n    }\n\n    .conic.rainbow_shorter-native {\n      background: conic-gradient(in hwb shorter hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n    }\n\n    .linear.rainbow_longer-native {\n      background: linear-gradient(to right in hsl longer hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n    }\n\n    .radial.rainbow_longer-native {\n      background: radial-gradient(in hsl longer hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n    }\n\n    .conic.rainbow_longer-native {\n      background: conic-gradient(in hsl longer hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n    }\n\n    .linear.rainbow_increasing-native {\n      background: linear-gradient(to right in lch increasing hue, hsl(240deg 100% 75%) 10%, hsl(180deg 100% 75%) 90%);\n    }\n\n    .radial.rainbow_increasing-native {\n      background: radial-gradient(in lch increasing hue, hsl(240deg 100% 75%) 10%, hsl(180deg 100% 75%) 90%);\n    }\n\n    .conic.rainbow_increasing-native {\n      background: conic-gradient(in lch increasing hue, hsl(240deg 100% 75%) 10%, hsl(180deg 100% 75%) 90%);\n    }\n\n    .linear.rainbow_decreasing-native {\n      background: linear-gradient(to right in oklch decreasing hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n    }\n\n    .radial.rainbow_decreasing-native {\n      background: radial-gradient(in oklch decreasing hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n    }\n\n    .conic.rainbow_decreasing-native {\n      background: conic-gradient(in oklch decreasing hue, hsl(180deg 100% 75%) 10%, hsl(240deg 100% 75%) 90%);\n    }\n\n    .linear.midpoint_hint-native {\n      background: linear-gradient(to right, #f00, #ff0, 75%, #0ff, #00f);\n    }\n\n    .radial.midpoint_hint-native {\n      background: radial-gradient(#f00, #ff0, 75%, #0ff, #00f);\n    }\n\n    .conic.midpoint_hint-native {\n      background: conic-gradient(#f00, #ff0, 75%, #0ff, #00f);\n    }\n\n    .linear.premultiplied_alpha-native {\n      background: linear-gradient(to right, #f00f, 10%, #00f1, 90%, #0f0f);\n    }\n\n    .radial.premultiplied_alpha-native {\n      background: radial-gradient(#f00f, 10%, #00f1, 90%, #0f0f);\n    }\n\n    .conic.premultiplied_alpha-native {\n      background: conic-gradient(#f00f, 10%, #00f1, 90%, #0f0f);\n    }\n\n    .linear.mixed_units-native {\n      background: linear-gradient(to right, color(display-p3 0.4 0 1) 30px, color(display-p3 1 0.75 0.4) 60%);\n    }\n\n    .radial.mixed_units-native {\n      background: radial-gradient(color(display-p3 0.4 0 1) 30px, color(display-p3 1 0.75 0.4) 60%);\n    }\n\n    .conic.mixed_units-native {\n      background: conic-gradient(color(display-p3 0.4 0 1) 30deg, color(display-p3 1 0.75 0.4) 60%);\n    }\n\n  </style>\n</head>\n\n<body>\n  <p>This page is a visual test of esbuild's CSS gradient transformation. Run it like this:</p>\n  <pre>./esbuild --servedir=scripts --outfile=scripts/out.css scripts/gradient-tests.css --target=firefox30</pre>\n  <p>Then open this page as <a\n      href=\"http://localhost:8000/gradient-tests.html\">http://localhost:8000/gradient-tests.html</a>.</p>\n\n  <h2>1. Red to green in P3</h2>\n  <pre>gradient(\n  color(display-p3 1 0 0),\n  color(display-p3 0 0.6 0))</pre>\n  <div class=\"linear red_to_green-native\">native</div>\n  <div class=\"linear red_to_green-esbuild\">esbuild</div>\n  <section>\n    <div class=\"radial red_to_green-native\">native</div>\n    <div class=\"radial red_to_green-esbuild\">esbuild</div>\n    <div class=\"conic red_to_green-native\">native</div>\n    <div class=\"conic red_to_green-esbuild\">esbuild</div>\n  </section>\n\n  <h2>2. Rainbow using shorter hue</h2>\n  <pre>gradient(\n  in hwb shorter hue,\n  hsl(180deg 100% 75%) 10%,\n  hsl(240deg 100% 75%) 90%)</pre>\n  <div class=\"linear rainbow_shorter-native\">native</div>\n  <div class=\"linear rainbow_shorter-esbuild\">esbuild</div>\n  <section>\n    <div class=\"radial rainbow_shorter-native\">native</div>\n    <div class=\"radial rainbow_shorter-esbuild\">esbuild</div>\n    <div class=\"conic rainbow_shorter-native\">native</div>\n    <div class=\"conic rainbow_shorter-esbuild\">esbuild</div>\n  </section>\n\n  <h2>3. Rainbow using longer hue</h2>\n  <pre>gradient(\n  in hsl longer hue,\n  hsl(180deg 100% 75%) 10%,\n  hsl(240deg 100% 75%) 90%)</pre>\n  <div class=\"linear rainbow_longer-native\">native</div>\n  <div class=\"linear rainbow_longer-esbuild\">esbuild</div>\n  <section>\n    <div class=\"radial rainbow_longer-native\">native</div>\n    <div class=\"radial rainbow_longer-esbuild\">esbuild</div>\n    <div class=\"conic rainbow_longer-native\">native</div>\n    <div class=\"conic rainbow_longer-esbuild\">esbuild</div>\n  </section>\n\n  <h2>4. Rainbow using increasing hue</h2>\n  <pre>gradient(\n  in lch increasing hue,\n  hsl(240deg 100% 75%) 10%,\n  hsl(180deg 100% 75%) 90%)</pre>\n  <div class=\"linear rainbow_increasing-native\">native</div>\n  <div class=\"linear rainbow_increasing-esbuild\">esbuild</div>\n  <section>\n    <div class=\"radial rainbow_increasing-native\">native</div>\n    <div class=\"radial rainbow_increasing-esbuild\">esbuild</div>\n    <div class=\"conic rainbow_increasing-native\">native</div>\n    <div class=\"conic rainbow_increasing-esbuild\">esbuild</div>\n  </section>\n\n  <h2>5. Rainbow using decreasing hue</h2>\n  <pre>gradient(\n  in oklch decreasing hue,\n  hsl(180deg 100% 75%) 10%,\n  hsl(240deg 100% 75%) 90%)</pre>\n  <div class=\"linear rainbow_decreasing-native\">native</div>\n  <div class=\"linear rainbow_decreasing-esbuild\">esbuild</div>\n  <section>\n    <div class=\"radial rainbow_decreasing-native\">native</div>\n    <div class=\"radial rainbow_decreasing-esbuild\">esbuild</div>\n    <div class=\"conic rainbow_decreasing-native\">native</div>\n    <div class=\"conic rainbow_decreasing-esbuild\">esbuild</div>\n  </section>\n\n  <h2>6. Transition hint / midpoint</h2>\n  <pre>gradient(#f00, #ff0, 75%, #0ff, #00f)</pre>\n  <div class=\"linear midpoint_hint-native\">native</div>\n  <div class=\"linear midpoint_hint-esbuild\">esbuild</div>\n  <section>\n    <div class=\"radial midpoint_hint-native\">native</div>\n    <div class=\"radial midpoint_hint-esbuild\">esbuild</div>\n    <div class=\"conic midpoint_hint-native\">native</div>\n    <div class=\"conic midpoint_hint-esbuild\">esbuild</div>\n  </section>\n\n  <h2>7. Premultiplied alpha</h2>\n  <pre>gradient(#f00f, 10%, #00f1, 90%, #0f0f)</pre>\n  <div class=\"checkerboard linear premultiplied_alpha-native\">native</div>\n  <div class=\"checkerboard linear premultiplied_alpha-esbuild\">esbuild</div>\n  <section>\n    <div class=\"checkerboard radial premultiplied_alpha-native\">native</div>\n    <div class=\"checkerboard radial premultiplied_alpha-esbuild\">esbuild</div>\n    <div class=\"checkerboard conic premultiplied_alpha-native\">native</div>\n    <div class=\"checkerboard conic premultiplied_alpha-esbuild\">esbuild</div>\n  </section>\n\n  <h2>8. Mixed units</h2>\n  <pre>gradient(\n  color(display-p3 0.4 0 1) 30px,\n  color(display-p3 1 0.75 0.4) 60%)</pre>\n  <div class=\"linear mixed_units-native\">native</div>\n  <div class=\"linear mixed_units-esbuild\">esbuild</div>\n  <section>\n    <div class=\"radial mixed_units-native\">native</div>\n    <div class=\"radial mixed_units-esbuild\">esbuild</div>\n    <div class=\"conic mixed_units-native\">native</div>\n    <div class=\"conic mixed_units-esbuild\">esbuild</div>\n  </section>\n</body>\n\n</html>\n"
  },
  {
    "path": "scripts/graph-debugger.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n  <meta charset=\"utf8\">\n  <title>Graph debugger</title>\n  <style>\n    body {\n      margin: 0;\n      overflow: hidden;\n      font: 14px/20px sans-serif;\n      background: #fff;\n      color: #000;\n    }\n\n    @media (prefers-color-scheme: dark) {\n      body {\n        background: #222;\n        color: #ddd;\n      }\n    }\n\n    canvas {\n      position: fixed;\n      left: 0;\n      top: 0;\n      width: 100%;\n      height: 100%;\n    }\n\n    #instructions {\n      padding: 20px;\n    }\n\n  </style>\n</head>\n\n<body>\n  <div id=\"instructions\">\n    This is a debugger for some of esbuild's internals. To use:\n    <ol>\n      <li>Set \"debugVerboseMetafile = true\"</li>\n      <li>Serve the esbuild repo over localhost</li>\n      <li>Visit this page with \"#metafile=path/to/metafile.json\"</li>\n    </ol>\n  </div>\n  <canvas></canvas>\n  <script type=\"module\">\n\n    const lightColors = {\n      bg: '#fff',\n      fg: '#000',\n      accent: '#7BF',\n    }\n\n    const darkColors = {\n      bg: '#222',\n      fg: '#ddd',\n      accent: '#FB0',\n    }\n\n    const prefersColorSchemeDark = matchMedia(\"(prefers-color-scheme: dark)\")\n\n    function lightOrDarkColors() {\n      return prefersColorSchemeDark.matches ? darkColors : lightColors\n    }\n\n    const paddingX = 10\n    const paddingY = 10\n\n    class InputFile {\n      constructor(source, data) {\n        this.source = source\n        this.data = data\n        this.x = 0\n        this.y = 0\n        this.w = 0\n        this.h = 0\n        this.measure()\n      }\n\n      measure() {\n        this.w = 0\n        this.h = 0\n\n        // Title\n        c.font = titleFont\n        this.w = Math.max(this.w, c.measureText(this.source).width)\n        this.h += titleLineHeight\n\n        // Parts\n        let prevIndent = 0\n        c.font = codeFont\n        for (const part of this.data.parts) {\n          let code = part.code.replace(/\\t/g, '  ')\n          const lastNewline = code.lastIndexOf('\\n')\n          let nextIndent = 0\n          if (lastNewline >= 0) {\n            const lastLine = code.slice(lastNewline + 1)\n            nextIndent = lastLine.length\n            if (!/\\S/.test(lastLine)) code = code.slice(0, lastNewline)\n          }\n          code = ' '.repeat(prevIndent) + code\n          prevIndent = nextIndent\n          part.lines = code.split('\\n')\n          part.y = this.h\n          for (const line of part.lines) {\n            this.w = Math.max(this.w, c.measureText(line).width)\n            this.h += codeLineHeight\n          }\n          if (part.nsExportPartIndex) {\n            this.w = Math.max(this.w, c.measureText('/* <nsExportPartIndex> */').width)\n          }\n          if (part.wrapperPartIndex) {\n            this.w = Math.max(this.w, c.measureText('/* <wrapperPartIndex> */').width)\n          }\n          part.h = this.h - part.y\n        }\n\n        this.w += paddingX * 2\n        this.h += paddingY * 2\n      }\n\n      render() {\n        const colors = lightOrDarkColors()\n\n        // Background\n        c.clearRect(this.x, this.y, this.w, this.h)\n\n        // Title\n        c.font = titleFont\n        c.textBaseline = 'middle'\n        c.fillStyle = colors.fg\n        c.fillText(this.source, this.x + paddingX, this.y + paddingY + titleLineHeight / 2)\n\n        // Lines\n        c.font = codeFont\n        c.textBaseline = 'middle'\n        c.fillStyle = colors.fg\n        for (const part of this.data.parts) {\n          c.globalAlpha = part.isLive ? 1 : 0.2\n          for (let i = 0; i < part.lines.length; i++) {\n            c.fillText(part.lines[i], this.x + paddingX, this.y + paddingY + part.y + i * codeLineHeight + codeLineHeight / 2)\n          }\n          if (part.nsExportPartIndex) {\n            c.fillText('/* <nsExportPartIndex> */', this.x + paddingX, this.y + paddingY + part.y + codeLineHeight / 2)\n          }\n          if (part.wrapperPartIndex) {\n            c.fillText('/* <wrapperPartIndex> */', this.x + paddingX, this.y + paddingY + part.y + codeLineHeight / 2)\n          }\n        }\n\n        // Border\n        c.globalAlpha = 0.2\n        c.strokeStyle = colors.fg\n        c.strokeRect(this.x, this.y, this.w, this.h)\n        c.globalAlpha = 1\n      }\n\n      renderHover() {\n        const colors = lightOrDarkColors()\n\n        if (this.hoveredPart === -1) {\n          c.fillStyle = colors.accent\n          c.globalAlpha = 0.2\n          c.fillRect(this.x, this.y + paddingY, this.w, titleLineHeight)\n          c.globalAlpha = 1\n          c.fillRect(this.x, this.y + paddingY, 4, titleLineHeight)\n\n          c.strokeStyle = colors.fg\n          c.fillStyle = colors.fg\n          for (const part of this.data.parts) {\n            if (part.canBeRemovedIfUnused) continue\n            drawArrow(\n              this.x, this.y + paddingY + titleLineHeight / 2, -1,\n              this.x, this.y + paddingY + part.y + codeLineHeight / 2, -1,\n            )\n          }\n        } else if (this.hoveredPart !== null) {\n          const part = this.data.parts[this.hoveredPart]\n          c.fillStyle = colors.accent\n          c.globalAlpha = 0.2\n          c.fillRect(this.x, this.y + paddingY + part.y, this.w, part.h)\n          c.globalAlpha = 1\n          c.fillRect(this.x, this.y + paddingY + part.y, 4, part.h)\n\n          c.strokeStyle = colors.fg\n          c.fillStyle = colors.fg\n          drawArrow(\n            this.x, this.y + paddingY + part.y + codeLineHeight / 2, -1,\n            this.x, this.y + paddingY + titleLineHeight / 2, -1,\n          )\n\n          for (const dep of part.dependencies) {\n            if (dep.source === this.source) {\n              const otherPart = this.data.parts[dep.partIndex]\n              drawArrow(\n                this.x, this.y + paddingY + part.y + codeLineHeight / 2, -1,\n                this.x, this.y + paddingY + otherPart.y + codeLineHeight / 2, -1,\n              )\n              continue\n            }\n\n            const otherFile = inputFiles.find(file => file.source === dep.source)\n            if (!otherFile) continue\n            const otherPart = otherFile.data.parts[dep.partIndex]\n            drawArrow(\n              this.x + this.w, this.y + paddingY + part.y + codeLineHeight / 2, 1,\n              otherFile.x, otherFile.y + paddingY + otherPart.y + codeLineHeight / 2, -1,\n            )\n          }\n\n          for (const record of part.importRecords) {\n            const otherFile = inputFiles.find(file => file.source === record.source)\n            if (!otherFile) continue\n            drawArrow(\n              this.x + this.w, this.y + paddingY + part.y + codeLineHeight / 2, 1,\n              otherFile.x, otherFile.y + paddingY + titleLineHeight / 2, -1,\n            )\n          }\n\n          let lines = []\n          lines.push(`isLive: ${part.isLive}`)\n          if (part.declaredSymbols.length > 0) {\n            lines.push(`declaredSymbols:`)\n            for (const declSym of part.declaredSymbols) {\n              lines.push(`    ${declSym.name}`)\n            }\n          }\n          if (part.symbolUses.length > 0) {\n            lines.push(`symbolUses:`)\n            for (const use of part.symbolUses) {\n              lines.push(`    ${use.name} ${use.countEstimate}x`)\n            }\n          }\n          if (part.importRecords.length > 0) {\n            lines.push(`importRecords:`)\n            for (const record of part.importRecords) {\n              lines.push(`    ${record.source}`)\n            }\n          }\n\n          c.font = normalFont\n          c.textBaseline = 'middle'\n          c.fillStyle = colors.fg\n          for (let i = 0; i < lines.length; i++) {\n            c.fillText(lines[i], this.x + 10, this.y + this.h + 10 + i * normalLineHeight + normalLineHeight / 2)\n          }\n        }\n      }\n\n      hoveredPart = null\n\n      onHover(mouseX, mouseY) {\n        this.hoveredPart = null\n\n        if (mouseX !== null && mouseY !== null &&\n          mouseX >= this.x && mouseX < this.x + this.w &&\n          mouseY >= this.y && mouseY < this.y + this.h) {\n          let y = mouseY - this.y - paddingY\n\n          if (y >= 0 && y < titleLineHeight) {\n            this.hoveredPart = -1\n            return true\n          }\n\n          for (let i = 0; i < this.data.parts.length; i++) {\n            const part = this.data.parts[i]\n            if (y >= part.y && y < part.y + part.h) {\n              this.hoveredPart = i\n              return true\n            }\n          }\n        }\n      }\n\n      onMouseMove(mouseX, mouseY) {\n        if (mouseX >= this.x && mouseX < this.x + this.w &&\n          mouseY >= this.y && mouseY < this.y + this.h) {\n          document.body.style.cursor = 'move'\n          return true\n        }\n      }\n\n      oldX = 0\n      oldY = 0\n\n      onMouseDown(mouseX, mouseY) {\n        if (mouseX >= this.x && mouseX < this.x + this.w &&\n          mouseY >= this.y && mouseY < this.y + this.h) {\n          this.oldX = mouseX\n          this.oldY = mouseY\n          document.body.style.cursor = 'move'\n          return true\n        }\n      }\n\n      onMouseDrag(mouseX, mouseY) {\n        this.x += mouseX - this.oldX\n        this.y += mouseY - this.oldY\n        this.oldX = mouseX\n        this.oldY = mouseY\n        document.body.style.cursor = 'move'\n      }\n\n      onMouseUp(e) {\n      }\n    }\n\n    function drawArrow(ax, ay, adx, bx, by, bdx) {\n      let dx = bx - ax\n      let dy = by - ay\n      let d = Math.sqrt(dx * dx + dy * dy)\n      let scale = d / 2\n      c.beginPath()\n      c.moveTo(ax, ay)\n      c.bezierCurveTo(\n        ax + adx * (10 + scale), ay,\n        bx + bdx * 10 + bdx * scale, by,\n        bx + bdx * 10, by,\n      )\n      c.stroke()\n      c.beginPath()\n      c.moveTo(bx, by)\n      c.lineTo(bx + bdx * 10, by - 5)\n      c.lineTo(bx + bdx * 10, by + 5)\n      c.fill()\n    }\n\n    const canvas = document.querySelector('canvas')\n    const c = canvas.getContext('2d')\n    const titleFont = '20px sans-serif'\n    const titleLineHeight = 30\n    const codeFont = '12px monospace'\n    const codeLineHeight = 18\n    const normalFont = '14px sans-serif'\n    const normalLineHeight = 18\n    let width = 0, height = 0\n    let scrollX = 0, scrollY = 0\n\n    let metafile\n    const instructions = document.getElementById('instructions')\n    try {\n      if (!location.hash.startsWith('#metafile=')) throw new Error('Expected \"#metafile=\" in URL')\n      metafile = await fetch(location.hash.slice('#metafile='.length)).then(r => r.json())\n    } catch (err) {\n      const error = document.createElement('div')\n      error.style.color = 'red'\n      error.textContent = err\n      instructions.append(error)\n      throw err\n    }\n    instructions.remove()\n\n    const outputSource = Object.keys(metafile.outputs)[0]\n    const output = metafile.outputs[outputSource]\n    const inputFiles = Object.entries(output.inputs).map(([source, data]) => new InputFile(source, data)).reverse()\n\n    for (let i = 0; i < inputFiles.length; i++) {\n      const file = inputFiles[i]\n      file.y = 100\n      if (i === 0) {\n        file.x = 100\n      } else {\n        const prevFile = inputFiles[i - 1]\n        file.x = prevFile.x + prevFile.w + 100\n      }\n    }\n\n    function render() {\n      const colors = lightOrDarkColors()\n\n      width = innerWidth\n      height = innerHeight\n      const ratio = devicePixelRatio\n      canvas.width = Math.round(width * ratio)\n      canvas.height = Math.round(height * ratio)\n      canvas.style.background = colors.bg\n      c.scale(ratio, ratio)\n\n      // Title\n      c.font = titleFont\n      c.textBaseline = 'top'\n      c.fillStyle = colors.fg\n      c.fillText(outputSource, 10, 10)\n\n      // Content\n      c.translate(-scrollX, -scrollY)\n\n      // Inputs\n      for (let i = inputFiles.length - 1; i >= 0; i--) inputFiles[i].render()\n      for (let i = inputFiles.length - 1; i >= 0; i--) inputFiles[i].renderHover()\n    }\n\n    addEventListener('wheel', e => {\n      e.preventDefault()\n      if (e.ctrlKey) return\n      scrollX += e.deltaX\n      scrollY += e.deltaY\n    }, { passive: false })\n\n    let draggingFile = null\n    let isDragging = false\n\n    onmousemove = e => {\n      let mouseX = e.pageX + scrollX\n      let mouseY = e.pageY + scrollY\n      document.body.style.cursor = 'default'\n      if (isDragging) {\n        if (draggingFile) {\n          draggingFile.onMouseDrag(mouseX, mouseY)\n        }\n      } else {\n        for (const file of inputFiles) {\n          if (file.onMouseMove(mouseX, mouseY)) {\n            break\n          }\n        }\n        onhover(mouseX, mouseY)\n      }\n    }\n\n    onmousedown = e => {\n      let mouseX = e.pageX + scrollX\n      let mouseY = e.pageY + scrollY\n      if (!isDragging) {\n        isDragging = true\n        for (const file of inputFiles) {\n          if (file.onMouseDown(mouseX, mouseY)) {\n            draggingFile = file\n            break\n          }\n        }\n      }\n      onhover(mouseX, mouseY)\n    }\n\n    onmouseup = e => {\n      let mouseX = e.pageX + scrollX\n      let mouseY = e.pageY + scrollY\n      if (isDragging) {\n        if (draggingFile) {\n          draggingFile.onMouseUp(mouseX, mouseY)\n          draggingFile = null\n        }\n        isDragging = false\n      }\n      onhover(mouseX, mouseY)\n    }\n\n    function onhover(mouseX, mouseY) {\n      for (const file of inputFiles) {\n        if (file.onHover(mouseX, mouseY)) {\n          mouseX = null\n          mouseY = null\n        }\n      }\n    }\n\n    onblur = () => {\n      draggingFile = null\n      isDragging = false\n    }\n\n    function tick() {\n      requestAnimationFrame(tick)\n      render()\n    }\n\n    tick()\n\n  </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "scripts/js-api-tests.js",
    "content": "const { installForTests, removeRecursiveSync, writeFileAtomic } = require('./esbuild')\nconst child_process = require('child_process')\nconst assert = require('assert')\nconst path = require('path')\nconst http = require('http')\nconst https = require('https')\nconst events = require('events')\nconst fs = require('fs')\nconst vm = require('vm')\n\nconst readFileAsync = fs.promises.readFile\nconst writeFileAsync = fs.promises.writeFile\nconst mkdirAsync = fs.promises.mkdir\n\nconst repoDir = path.dirname(__dirname)\nconst rootTestDir = path.join(repoDir, 'scripts', '.js-api-tests')\nconst errorIcon = process.platform !== 'win32' ? '✘' : 'X'\n\nlet buildTests = {\n  async errorIfEntryPointsNotArray({ esbuild }) {\n    try {\n      await esbuild.build({\n        entryPoints: 'this is not an array',\n        logLevel: 'silent',\n      })\n      throw new Error('Expected build failure');\n    } catch (e) {\n      if (!e.errors || !e.errors[0] || e.errors[0].text !== '\"entryPoints\" must be an array or an object') {\n        throw e;\n      }\n    }\n  },\n\n  async errorIfBadWorkingDirectory({ esbuild }) {\n    try {\n      await esbuild.build({\n        absWorkingDir: 'what is this? certainly not an absolute path',\n        logLevel: 'silent',\n        write: false,\n      })\n      throw new Error('Expected build failure');\n    } catch (e) {\n      if (e.message !== 'Build failed with 1 error:\\nerror: The working directory ' +\n        '\"what is this? certainly not an absolute path\" is not an absolute path') {\n        throw e;\n      }\n    }\n  },\n\n  // Verify that it's possible to disable a loader by setting it to \"default\".\n  // In particular, verify that it's possible to disable the special loader \"\"\n  // for extensionless files.\n  async errorIfExtensionlessLoaderIsDisabled({ esbuild, testDir }) {\n    let entry = path.join(testDir, 'entry.js');\n    let what = path.join(testDir, 'what');\n    await writeFileAsync(entry, 'import \"./what\"')\n    await writeFileAsync(what, 'foo()')\n    await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      write: false,\n    })\n    try {\n      await esbuild.build({\n        entryPoints: [entry],\n        bundle: true,\n        write: false,\n        logLevel: 'silent',\n        loader: { '': 'default' },\n      })\n      throw new Error('Expected build failure');\n    } catch (e) {\n      const relPath = path.relative(process.cwd(), what).split(path.sep).join('/')\n      if (!e.errors || !e.errors[0] || e.errors[0].text !== 'Do not know how to load path: ' + relPath) {\n        throw e;\n      }\n    }\n  },\n\n  async mangleCacheBuild({ esbuild }) {\n    var result = await esbuild.build({\n      stdin: {\n        contents: `x = { x_: 0, y_: 1, z_: 2 }`,\n      },\n      mangleProps: /_/,\n      mangleCache: { x_: 'FIXED', z_: false },\n      write: false,\n    })\n    assert.strictEqual(result.outputFiles[0].text, 'x = { FIXED: 0, a: 1, z_: 2 };\\n')\n    assert.deepStrictEqual(result.mangleCache, { x_: 'FIXED', y_: 'a', z_: false })\n  },\n\n  async windowsBackslashPathTest({ esbuild, testDir }) {\n    let entry = path.join(testDir, 'entry.js');\n    let nested = path.join(testDir, 'nested.js');\n    let outfile = path.join(testDir, 'out.js');\n\n    // On Windows, backslash and forward slash should be treated the same\n    fs.writeFileSync(entry, `\n      import ${JSON.stringify(nested)}\n      import ${JSON.stringify(nested.split(path.sep).join('/'))}\n    `);\n    fs.writeFileSync(nested, `console.log('once')`);\n\n    const result = await esbuild.build({\n      entryPoints: [entry],\n      outfile,\n      bundle: true,\n      write: false,\n      minify: true,\n      format: 'esm',\n    })\n\n    assert.strictEqual(result.outputFiles[0].text, 'console.log(\"once\");\\n')\n  },\n\n  async workingDirTest({ esbuild, testDir }) {\n    let aDir = path.join(testDir, 'a');\n    let bDir = path.join(testDir, 'b');\n    let aFile = path.join(aDir, 'a-in.js');\n    let bFile = path.join(bDir, 'b-in.js');\n    let aOut = path.join(aDir, 'a-out.js');\n    let bOut = path.join(bDir, 'b-out.js');\n    fs.mkdirSync(aDir, { recursive: true });\n    fs.mkdirSync(bDir, { recursive: true });\n    fs.writeFileSync(aFile, 'exports.x = true');\n    fs.writeFileSync(bFile, 'exports.y = true');\n\n    await Promise.all([\n      esbuild.build({\n        entryPoints: [path.basename(aFile)],\n        outfile: path.basename(aOut),\n        absWorkingDir: aDir,\n      }),\n      esbuild.build({\n        entryPoints: [path.basename(bFile)],\n        outfile: path.basename(bOut),\n        absWorkingDir: bDir,\n      }),\n    ]);\n\n    assert.strictEqual(require(aOut).x, true)\n    assert.strictEqual(require(bOut).y, true)\n  },\n\n  async absPathsCodeTest({ esbuild, testDir }) {\n    let srcDir = path.join(testDir, 'src');\n    let outfile = path.join(testDir, 'out', 'result.js');\n    let entry = path.join(srcDir, 'entry.js');\n    fs.mkdirSync(srcDir, { recursive: true });\n    fs.writeFileSync(entry, `x = typeof y == \"null\"`);\n\n    const { metafile, warnings, outputFiles } = await esbuild.build({\n      entryPoints: [entry],\n      outfile,\n      bundle: true,\n      write: false,\n      metafile: true,\n      format: 'cjs',\n      logLevel: 'silent',\n      absPaths: ['code'],\n    })\n    const cwd = process.cwd()\n    const makePath = absPath => path.relative(cwd, absPath).split(path.sep).join('/')\n\n    assert.strictEqual(outputFiles.length, 1)\n    assert.deepStrictEqual(outputFiles[0].path, outfile)\n    assert.deepStrictEqual(outputFiles[0].text, `// ${entry}\\nx = typeof y == \"null\";\\n`)\n\n    assert.deepStrictEqual(Object.keys(metafile.inputs), [makePath(entry)])\n    assert.deepStrictEqual(Object.keys(metafile.outputs), [makePath(outfile)])\n    assert.strictEqual(metafile.inputs[makePath(entry)].imports.length, 0)\n    assert.strictEqual(metafile.outputs[makePath(outfile)].entryPoint, makePath(entry))\n\n    assert.strictEqual(warnings.length, 1)\n    assert.strictEqual(warnings[0].text, 'The \"typeof\" operator will never evaluate to \"null\"')\n    assert.strictEqual(warnings[0].location.file, makePath(entry))\n  },\n\n  async absPathsLogTest({ esbuild, testDir }) {\n    let srcDir = path.join(testDir, 'src');\n    let outfile = path.join(testDir, 'out', 'result.js');\n    let entry = path.join(srcDir, 'entry.js');\n    fs.mkdirSync(srcDir, { recursive: true });\n    fs.writeFileSync(entry, `x = typeof y == \"null\"`);\n\n    const { metafile, warnings, outputFiles } = await esbuild.build({\n      entryPoints: [entry],\n      outfile,\n      bundle: true,\n      write: false,\n      metafile: true,\n      format: 'cjs',\n      logLevel: 'silent',\n      absPaths: ['log'],\n    })\n    const cwd = process.cwd()\n    const makePath = absPath => path.relative(cwd, absPath).split(path.sep).join('/')\n\n    assert.strictEqual(outputFiles.length, 1)\n    assert.deepStrictEqual(outputFiles[0].path, outfile)\n    assert.deepStrictEqual(outputFiles[0].text, `// ${makePath(entry)}\\nx = typeof y == \"null\";\\n`)\n\n    assert.deepStrictEqual(Object.keys(metafile.inputs), [makePath(entry)])\n    assert.deepStrictEqual(Object.keys(metafile.outputs), [makePath(outfile)])\n    assert.strictEqual(metafile.inputs[makePath(entry)].imports.length, 0)\n    assert.strictEqual(metafile.outputs[makePath(outfile)].entryPoint, makePath(entry))\n\n    assert.strictEqual(warnings.length, 1)\n    assert.strictEqual(warnings[0].text, 'The \"typeof\" operator will never evaluate to \"null\"')\n    assert.strictEqual(warnings[0].location.file, entry)\n  },\n\n  async absPathsMetafileTest({ esbuild, testDir }) {\n    let srcDir = path.join(testDir, 'src');\n    let outfile = path.join(testDir, 'out', 'result.js');\n    let entry = path.join(srcDir, 'entry.js');\n    fs.mkdirSync(srcDir, { recursive: true });\n    fs.writeFileSync(entry, `x = typeof y == \"null\"`);\n\n    const { metafile, warnings, outputFiles } = await esbuild.build({\n      entryPoints: [entry],\n      outfile,\n      bundle: true,\n      write: false,\n      metafile: true,\n      format: 'cjs',\n      logLevel: 'silent',\n      absPaths: ['metafile'],\n    })\n    const cwd = process.cwd()\n    const makePath = absPath => path.relative(cwd, absPath).split(path.sep).join('/')\n\n    assert.strictEqual(outputFiles.length, 1)\n    assert.deepStrictEqual(outputFiles[0].path, outfile)\n    assert.deepStrictEqual(outputFiles[0].text, `// ${makePath(entry)}\\nx = typeof y == \"null\";\\n`)\n\n    assert.deepStrictEqual(Object.keys(metafile.inputs), [entry])\n    assert.deepStrictEqual(Object.keys(metafile.outputs), [outfile])\n    assert.strictEqual(metafile.inputs[entry].imports.length, 0)\n    assert.strictEqual(metafile.outputs[outfile].entryPoint, entry)\n\n    assert.strictEqual(warnings.length, 1)\n    assert.strictEqual(warnings[0].text, 'The \"typeof\" operator will never evaluate to \"null\"')\n    assert.strictEqual(warnings[0].location.file, makePath(entry))\n  },\n\n  async aliasValidity({ esbuild }) {\n    const valid = async alias => {\n      const result = await esbuild.build({\n        stdin: { contents: 'import ' + JSON.stringify(alias) },\n        bundle: true,\n        alias: { [alias]: 'foo' },\n        external: ['foo'],\n        format: 'esm',\n        write: false,\n      })\n      assert.strictEqual(result.outputFiles[0].text, '// <stdin>\\nimport \"foo\";\\n')\n    }\n\n    const invalid = async alias => {\n      try {\n        await esbuild.build({\n          bundle: true,\n          alias: { [alias]: 'foo' },\n          logLevel: 'silent',\n        })\n      } catch {\n        return\n      }\n      throw new Error('Expected an error for alias: ' + alias)\n    }\n\n    await Promise.all([\n      valid('foo'),\n      valid('foo/bar'),\n      valid('@foo'),\n      valid('@foo/bar'),\n      valid('@foo/bar/baz'),\n\n      invalid('./foo'),\n      invalid('../foo'),\n      invalid('/foo'),\n      invalid('C:\\\\foo'),\n      invalid('.foo'),\n      invalid('foo/'),\n      invalid('@foo/'),\n      invalid('foo/../bar'),\n    ])\n  },\n\n  async pathResolverEACCS({ esbuild, testDir }) {\n    let outerDir = path.join(testDir, 'outer');\n    let innerDir = path.join(outerDir, 'inner');\n    let pkgDir = path.join(testDir, 'node_modules', 'pkg');\n    let entry = path.join(innerDir, 'entry.js');\n    let sibling = path.join(innerDir, 'sibling.js');\n    let index = path.join(pkgDir, 'index.js');\n    let outfile = path.join(innerDir, 'out.js');\n    fs.mkdirSync(pkgDir, { recursive: true });\n    fs.mkdirSync(innerDir, { recursive: true });\n    fs.writeFileSync(entry, `\n      import a from \"./sibling.js\"\n      import b from \"pkg\"\n      export default {a, b}\n    `);\n    fs.writeFileSync(sibling, `export default 'sibling'`);\n    fs.writeFileSync(index, `export default 'pkg'`);\n    fs.chmodSync(outerDir, 0o111);\n\n    try {\n      await esbuild.build({\n        entryPoints: [entry],\n        bundle: true,\n        outfile,\n        format: 'cjs',\n      });\n\n      const result = require(outfile);\n      assert.deepStrictEqual(result.default, { a: 'sibling', b: 'pkg' });\n    }\n\n    finally {\n      // Restore permission when the test ends so test cleanup works\n      fs.chmodSync(outerDir, 0o755);\n    }\n  },\n\n  async nodePathsTest({ esbuild, testDir }) {\n    let srcDir = path.join(testDir, 'src');\n    let pkgDir = path.join(testDir, 'pkg');\n    let outfile = path.join(testDir, 'out.js');\n    let entry = path.join(srcDir, 'entry.js');\n    let other = path.join(pkgDir, 'other.js');\n    fs.mkdirSync(srcDir, { recursive: true });\n    fs.mkdirSync(pkgDir, { recursive: true });\n    fs.writeFileSync(entry, `export {x} from 'other'`);\n    fs.writeFileSync(other, `export let x = 123`);\n\n    await esbuild.build({\n      entryPoints: [entry],\n      outfile,\n      bundle: true,\n      nodePaths: [pkgDir],\n      format: 'cjs',\n    })\n\n    assert.strictEqual(require(outfile).x, 123)\n  },\n\n  // A local \"node_modules\" path should be preferred over \"NODE_PATH\".\n  // See: https://github.com/evanw/esbuild/issues/1117\n  async nodePathsLocalPreferredTestIssue1117({ esbuild, testDir }) {\n    let srcDir = path.join(testDir, 'src');\n    let srcOtherDir = path.join(testDir, 'src', 'node_modules', 'other');\n    let pkgDir = path.join(testDir, 'pkg');\n    let outfile = path.join(testDir, 'out.js');\n    let entry = path.join(srcDir, 'entry.js');\n    let srcOther = path.join(srcOtherDir, 'index.js');\n    let pkgOther = path.join(pkgDir, 'other.js');\n    fs.mkdirSync(srcDir, { recursive: true });\n    fs.mkdirSync(srcOtherDir, { recursive: true });\n    fs.mkdirSync(pkgDir, { recursive: true });\n    fs.writeFileSync(entry, `export {x} from 'other'`);\n    fs.writeFileSync(srcOther, `export let x = 234`);\n    fs.writeFileSync(pkgOther, `export let x = 123`);\n\n    await esbuild.build({\n      entryPoints: [entry],\n      outfile,\n      bundle: true,\n      nodePaths: [pkgDir],\n      format: 'cjs',\n    })\n\n    assert.strictEqual(require(outfile).x, 234)\n  },\n\n  async es6_to_cjs({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, 'export default 123')\n    const value = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n    })\n    assert.strictEqual(value.outputFiles, void 0)\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n    assert.strictEqual(result.__esModule, true)\n  },\n\n  // Test recursive directory creation\n  async recursiveMkdir({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'a/b/c/d/out.js')\n    await writeFileAsync(input, 'export default 123')\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n    assert.strictEqual(result.__esModule, true)\n  },\n\n  async outExtensionJS({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'in.mjs')\n    await writeFileAsync(input, 'console.log(\"test\")')\n    await esbuild.build({\n      entryPoints: [input],\n      outdir: testDir,\n      outExtension: { '.js': '.mjs' },\n    })\n    const mjs = await readFileAsync(output, 'utf8')\n    assert.strictEqual(mjs, 'console.log(\"test\");\\n')\n  },\n\n  async outExtensionCSS({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.css')\n    const output = path.join(testDir, 'in.notcss')\n    await writeFileAsync(input, 'body {}')\n    await esbuild.build({\n      entryPoints: [input],\n      outdir: testDir,\n      outExtension: { '.css': '.notcss' },\n    })\n    const notcss = await readFileAsync(output, 'utf8')\n    assert.strictEqual(notcss, 'body {\\n}\\n')\n  },\n\n  async sourceMapTrue({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const content = 'exports.foo = 123'\n    await writeFileAsync(input, content)\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      sourcemap: true,\n    })\n    const result = require(output)\n    assert.strictEqual(result.foo, 123)\n    const outputFile = await readFileAsync(output, 'utf8')\n    const match = /\\/\\/# sourceMappingURL=(.*)/.exec(outputFile)\n    assert.strictEqual(match[1], 'out.js.map')\n    const resultMap = await readFileAsync(output + '.map', 'utf8')\n    const json = JSON.parse(resultMap)\n    assert.strictEqual(json.version, 3)\n    assert.strictEqual(json.sources[0], path.basename(input))\n    assert.strictEqual(json.sourcesContent[0], content)\n  },\n\n  async sourceMapLinked({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const content = 'exports.foo = 123'\n    await writeFileAsync(input, content)\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      sourcemap: 'linked',\n    })\n    const result = require(output)\n    assert.strictEqual(result.foo, 123)\n    const outputFile = await readFileAsync(output, 'utf8')\n    const match = /\\/\\/# sourceMappingURL=(.*)/.exec(outputFile)\n    assert.strictEqual(match[1], 'out.js.map')\n    const resultMap = await readFileAsync(output + '.map', 'utf8')\n    const json = JSON.parse(resultMap)\n    assert.strictEqual(json.version, 3)\n    assert.strictEqual(json.sources[0], path.basename(input))\n    assert.strictEqual(json.sourcesContent[0], content)\n  },\n\n  async sourceMapExternal({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const content = 'exports.foo = 123'\n    await writeFileAsync(input, content)\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      sourcemap: 'external',\n    })\n    const result = require(output)\n    assert.strictEqual(result.foo, 123)\n    const outputFile = await readFileAsync(output, 'utf8')\n    const match = /\\/\\/# sourceMappingURL=(.*)/.exec(outputFile)\n    assert.strictEqual(match, null)\n    const resultMap = await readFileAsync(output + '.map', 'utf8')\n    const json = JSON.parse(resultMap)\n    assert.strictEqual(json.version, 3)\n    assert.strictEqual(json.sources[0], path.basename(input))\n    assert.strictEqual(json.sourcesContent[0], content)\n  },\n\n  async sourceMapInline({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const content = 'exports.foo = 123'\n    await writeFileAsync(input, content)\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      sourcemap: 'inline',\n    })\n    const result = require(output)\n    assert.strictEqual(result.foo, 123)\n    const outputFile = await readFileAsync(output, 'utf8')\n    const match = /\\/\\/# sourceMappingURL=data:application\\/json;base64,(.*)/.exec(outputFile)\n    const json = JSON.parse(Buffer.from(match[1], 'base64').toString())\n    assert.strictEqual(json.version, 3)\n    assert.strictEqual(json.sources[0], path.basename(input))\n    assert.strictEqual(json.sourcesContent[0], content)\n  },\n\n  async sourceMapBoth({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const content = 'exports.foo = 123'\n    await writeFileAsync(input, content)\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      sourcemap: 'both',\n    })\n    const result = require(output)\n    assert.strictEqual(result.foo, 123)\n    const outputFile = await readFileAsync(output, 'utf8')\n    const match = /\\/\\/# sourceMappingURL=data:application\\/json;base64,(.*)/.exec(outputFile)\n    const json = JSON.parse(Buffer.from(match[1], 'base64').toString())\n    assert.strictEqual(json.version, 3)\n    assert.strictEqual(json.sources[0], path.basename(input))\n    assert.strictEqual(json.sourcesContent[0], content)\n    const outputFileMap = await readFileAsync(output + '.map', 'utf8')\n    assert.strictEqual(Buffer.from(match[1], 'base64').toString(), outputFileMap)\n  },\n\n  async sourceMapIncludeSourcesContent({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const content = 'exports.foo = 123'\n    await writeFileAsync(input, content)\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      sourcemap: true,\n      sourcesContent: true,\n    })\n    const result = require(output)\n    assert.strictEqual(result.foo, 123)\n    const outputFile = await readFileAsync(output, 'utf8')\n    const match = /\\/\\/# sourceMappingURL=(.*)/.exec(outputFile)\n    assert.strictEqual(match[1], 'out.js.map')\n    const resultMap = await readFileAsync(output + '.map', 'utf8')\n    const json = JSON.parse(resultMap)\n    assert.strictEqual(json.version, 3)\n    assert.strictEqual(json.sources[0], path.basename(input))\n    assert.strictEqual(json.sourcesContent[0], content)\n  },\n\n  async sourceMapExcludeSourcesContent({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const content = 'exports.foo = 123'\n    await writeFileAsync(input, content)\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      sourcemap: true,\n      sourcesContent: false,\n    })\n    const result = require(output)\n    assert.strictEqual(result.foo, 123)\n    const outputFile = await readFileAsync(output, 'utf8')\n    const match = /\\/\\/# sourceMappingURL=(.*)/.exec(outputFile)\n    assert.strictEqual(match[1], 'out.js.map')\n    const resultMap = await readFileAsync(output + '.map', 'utf8')\n    const json = JSON.parse(resultMap)\n    assert.strictEqual(json.version, 3)\n    assert.strictEqual(json.sources[0], path.basename(input))\n    assert.strictEqual(json.sourcesContent, void 0)\n  },\n\n  async sourceMapSourceRoot({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const content = 'exports.foo = 123'\n    await writeFileAsync(input, content)\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      sourcemap: true,\n      sourceRoot: 'https://example.com/'\n    })\n    const result = require(output)\n    assert.strictEqual(result.foo, 123)\n    const outputFile = await readFileAsync(output, 'utf8')\n    const match = /\\/\\/# sourceMappingURL=(.*)/.exec(outputFile)\n    assert.strictEqual(match[1], 'out.js.map')\n    const resultMap = await readFileAsync(output + '.map', 'utf8')\n    const json = JSON.parse(resultMap)\n    assert.strictEqual(json.version, 3)\n    assert.strictEqual(json.sources[0], path.basename(input))\n    assert.strictEqual(json.sourceRoot, 'https://example.com/')\n  },\n\n  async sourceMapWithDisabledFile({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const disabled = path.join(testDir, 'disabled.js')\n    const packageJSON = path.join(testDir, 'package.json')\n    const output = path.join(testDir, 'out.js')\n    const content = 'exports.foo = require(\"./disabled\")'\n    await writeFileAsync(input, content)\n    await writeFileAsync(disabled, 'module.exports = 123')\n    await writeFileAsync(packageJSON, `{\"browser\": {\"./disabled.js\": false}}`)\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      sourcemap: true,\n      bundle: true,\n    })\n    const result = require(output)\n    assert.strictEqual(result.foo, void 0)\n    const resultMap = await readFileAsync(output + '.map', 'utf8')\n    const json = JSON.parse(resultMap)\n    assert.strictEqual(json.version, 3)\n    assert.strictEqual(json.sources.length, 1)\n    assert.strictEqual(json.sources[0], path.basename(input))\n    assert.strictEqual(json.sourcesContent[0], content)\n  },\n\n  async sourceMapWithEmptyFile({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const empty = path.join(testDir, 'file.empty')\n    const output = path.join(testDir, 'out.js')\n    const content = 'exports.foo = require(\"./file.empty\")'\n    await writeFileAsync(input, content)\n    await writeFileAsync(empty, 'module.exports = 123')\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      sourcemap: true,\n      bundle: true,\n      loader: { '.empty': 'empty' },\n    })\n    const result = require(output)\n    assert.strictEqual(result.foo, void 0)\n    const resultMap = await readFileAsync(output + '.map', 'utf8')\n    const json = JSON.parse(resultMap)\n    assert.strictEqual(json.version, 3)\n    assert.strictEqual(json.sources.length, 1)\n    assert.strictEqual(json.sources[0], path.basename(input))\n    assert.strictEqual(json.sourcesContent[0], content)\n  },\n\n  async sourceMapWithDisabledModule({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const disabled = path.join(testDir, 'node_modules', 'disabled', 'index.js')\n    const packageJSON = path.join(testDir, 'package.json')\n    const output = path.join(testDir, 'out.js')\n    const content = 'exports.foo = require(\"disabled\")'\n    await mkdirAsync(path.dirname(disabled), { recursive: true })\n    await writeFileAsync(input, content)\n    await writeFileAsync(disabled, 'module.exports = 123')\n    await writeFileAsync(packageJSON, `{\"browser\": {\"disabled\": false}}`)\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      sourcemap: true,\n      bundle: true,\n    })\n    const result = require(output)\n    assert.strictEqual(result.foo, void 0)\n    const resultMap = await readFileAsync(output + '.map', 'utf8')\n    const json = JSON.parse(resultMap)\n    assert.strictEqual(json.version, 3)\n    assert.strictEqual(json.sources.length, 1)\n    assert.strictEqual(json.sources[0], path.basename(input))\n    assert.strictEqual(json.sourcesContent[0], content)\n  },\n\n  async resolveExtensionOrder({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js');\n    const inputBare = path.join(testDir, 'module.js')\n    const inputSomething = path.join(testDir, 'module.something.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, 'exports.result = require(\"./module\").foo')\n    await writeFileAsync(inputBare, 'exports.foo = 321')\n    await writeFileAsync(inputSomething, 'exports.foo = 123')\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      format: 'cjs',\n      bundle: true,\n      resolveExtensions: ['.something.js', '.js'],\n    })\n    assert.strictEqual(require(output).result, 123)\n  },\n\n  async defineObject({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js');\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, 'export default {abc, xyz}')\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      format: 'cjs',\n      bundle: true,\n      define: {\n        abc: '[\"a\", \"b\", \"c\"]',\n        xyz: '{\"x\": 1, \"y\": 2, \"z\": 3}',\n      },\n    })\n    assert.deepStrictEqual(require(output).default, {\n      abc: ['a', 'b', 'c'],\n      xyz: { x: 1, y: 2, z: 3 },\n    })\n  },\n\n  async inject({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js');\n    const inject = path.join(testDir, 'inject.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, 'export default foo * 10 + 4')\n    await writeFileAsync(inject, 'export let foo = 123')\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      format: 'cjs',\n      bundle: true,\n      inject: [inject],\n    })\n    assert.strictEqual(require(output).default, 1234)\n  },\n\n  async minifyWithoutInject({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js');\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, 'function exampleFn() { return Math.min(4, 3) }')\n\n    const result = await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      write: false,\n      minify: true,\n    })\n    assert.strictEqual(3, new Function(result.outputFiles[0].text + '\\nreturn exampleFn()')())\n  },\n\n  // This should be the same as \"minifyWithoutInject\" above\n  async minifyWithInject({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js');\n    const inject = path.join(testDir, 'inject.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, 'function exampleFn() { return Math.min(4, 3) }')\n    await writeFileAsync(inject, 'let min = Math.min; export { min as \"Math.min\" }')\n\n    const result = await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      inject: [inject],\n      write: false,\n      minify: true,\n    })\n    assert.strictEqual(3, new Function(result.outputFiles[0].text + '\\nreturn exampleFn()')())\n  },\n\n  async mainFields({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const mainFieldsDir = path.join(testDir, 'node_modules', 'main-fields-test')\n    const mainFieldsA = path.join(mainFieldsDir, 'a.js')\n    const mainFieldsB = path.join(mainFieldsDir, 'b.js')\n    const mainFieldsPackage = path.join(mainFieldsDir, 'package.json')\n    await mkdirAsync(mainFieldsDir, { recursive: true })\n    await writeFileAsync(input, 'export * from \"main-fields-test\"')\n    await writeFileAsync(mainFieldsA, 'export let foo = \"a\"')\n    await writeFileAsync(mainFieldsB, 'export let foo = \"b\"')\n    await writeFileAsync(mainFieldsPackage, '{ \"a\": \"./a.js\", \"b\": \"./b.js\", \"c\": \"./c.js\" }')\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: output,\n      bundle: true,\n      format: 'cjs',\n      mainFields: ['c', 'b', 'a'],\n    })\n    const result = require(output)\n    assert.strictEqual(result.foo, 'b')\n  },\n\n  async requireAbsolutePath({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const dependency = path.join(testDir, 'dep.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `import value from ${JSON.stringify(dependency)}; export default value`)\n    await writeFileAsync(dependency, `export default 123`)\n    const value = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n    })\n    assert.strictEqual(value.outputFiles, void 0)\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n    assert.strictEqual(result.__esModule, true)\n  },\n\n  async buildLoaderStdinBase64({ esbuild }) {\n    // UTF-16\n    var result = await esbuild.build({\n      stdin: {\n        contents: `\\xFF`,\n        loader: 'base64',\n      },\n      write: false,\n    })\n    assert.strictEqual(result.outputFiles[0].text, `module.exports = \"w78=\";\\n`)\n\n    // Binary\n    var result = await esbuild.build({\n      stdin: {\n        contents: new Uint8Array([0xFF]),\n        loader: 'base64',\n      },\n      write: false,\n    })\n    assert.strictEqual(result.outputFiles[0].text, `module.exports = \"/w==\";\\n`)\n  },\n\n  async fileLoader({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const data = path.join(testDir, 'data.bin')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `export {default as value} from ${JSON.stringify(data)}`)\n    await writeFileAsync(data, `stuff`)\n    const value = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      loader: { '.bin': 'file' },\n    })\n    assert.strictEqual(value.outputFiles, void 0)\n    const result = require(output)\n    assert.strictEqual(result.value, './data-BYATPJRB.bin')\n    assert.strictEqual(result.__esModule, true)\n  },\n\n  async fileLoaderEntryHash({ esbuild, testDir }) {\n    const input = path.join(testDir, 'index.js')\n    const data = path.join(testDir, 'data.bin')\n    const outdir = path.join(testDir, 'out')\n    await writeFileAsync(input, `export {default as value} from ${JSON.stringify(data)}`)\n    await writeFileAsync(data, `stuff`)\n    const result1 = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outdir,\n      format: 'cjs',\n      loader: { '.bin': 'file' },\n      entryNames: '[name]-[hash]',\n      write: false,\n    })\n    await writeFileAsync(data, `more stuff`)\n    const result2 = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outdir,\n      format: 'cjs',\n      loader: { '.bin': 'file' },\n      entryNames: '[name]-[hash]',\n      write: false,\n    })\n    assert.strictEqual(result1.outputFiles.length, 2)\n    assert.strictEqual(result2.outputFiles.length, 2)\n\n    // Make sure each path is unique. This tests for a bug where the hash in\n    // the output filename corresponding to the \"index.js\" entry point wasn't\n    // including the filename for the \"file\" loader.\n    assert.strictEqual(new Set(result1.outputFiles.concat(result2.outputFiles).map(x => x.path)).size, 4)\n  },\n\n  async fileLoaderEntryHashNoChange({ esbuild, testDir }) {\n    const input = path.join(testDir, 'index.js')\n    const data = path.join(testDir, 'data.bin')\n    const outdir = path.join(testDir, 'out')\n    await writeFileAsync(input, `export {default as value} from ${JSON.stringify(data)}`)\n    await writeFileAsync(data, `stuff`)\n    const result1 = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outdir,\n      format: 'cjs',\n      loader: { '.bin': 'file' },\n      entryNames: '[name]-[hash]',\n      assetNames: '[name]',\n      write: false,\n    })\n    await writeFileAsync(data, `more stuff`)\n    const result2 = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outdir,\n      format: 'cjs',\n      loader: { '.bin': 'file' },\n      entryNames: '[name]-[hash]',\n      assetNames: '[name]',\n      write: false,\n    })\n    assert.strictEqual(result1.outputFiles.length, 2)\n    assert.strictEqual(result2.outputFiles.length, 2)\n\n    // The paths should be the same. The hash augmentation from the previous\n    // test should only be checking for a file name difference, not a difference\n    // in content, because the JS output file only contains the file name for\n    // something using the \"file\" loader.\n    assert.strictEqual(new Set(result1.outputFiles.concat(result2.outputFiles).map(x => x.path)).size, 2)\n  },\n\n  async splittingPublicPath({ esbuild, testDir }) {\n    const input1 = path.join(testDir, 'a', 'in1.js')\n    const input2 = path.join(testDir, 'b', 'in2.js')\n    const shared = path.join(testDir, 'c', 'shared.js')\n    const outdir = path.join(testDir, 'out')\n    await mkdirAsync(path.dirname(input1), { recursive: true })\n    await mkdirAsync(path.dirname(input2), { recursive: true })\n    await mkdirAsync(path.dirname(shared), { recursive: true })\n    await writeFileAsync(input1, `export {default as input1} from ${JSON.stringify(shared)}`)\n    await writeFileAsync(input2, `export {default as input2} from ${JSON.stringify(shared)}`)\n    await writeFileAsync(shared, `export default function foo() { return 123 }`)\n    const value = await esbuild.build({\n      entryPoints: [input1, input2],\n      bundle: true,\n      outdir,\n      format: 'esm',\n      splitting: true,\n      publicPath: 'https://www.example.com/assets',\n      write: false,\n    })\n    assert.deepStrictEqual(value.outputFiles.length, 3)\n    assert.deepStrictEqual(value.outputFiles[0].path, path.join(outdir, 'a', 'in1.js'))\n    assert.deepStrictEqual(value.outputFiles[1].path, path.join(outdir, 'b', 'in2.js'))\n    assert.deepStrictEqual(value.outputFiles[2].path, path.join(outdir, 'chunk-3MCOY2GR.js'))\n    assert.deepStrictEqual(value.outputFiles[0].text, `import {\n  foo\n} from \"https://www.example.com/assets/chunk-3MCOY2GR.js\";\nexport {\n  foo as input1\n};\n`)\n    assert.deepStrictEqual(value.outputFiles[1].text, `import {\n  foo\n} from \"https://www.example.com/assets/chunk-3MCOY2GR.js\";\nexport {\n  foo as input2\n};\n`)\n    assert.deepStrictEqual(value.outputFiles[2].text, `// scripts/.js-api-tests/splittingPublicPath/c/shared.js\nfunction foo() {\n  return 123;\n}\n\nexport {\n  foo\n};\n`)\n  },\n\n  async publicPathHashing({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const data = path.join(testDir, 'data.bin')\n    const outdir = path.join(testDir, 'out')\n    await writeFileAsync(input, `export {default} from ${JSON.stringify(data)}`)\n    await writeFileAsync(data, `stuff`)\n\n    const [result1, result2] = await Promise.all([\n      esbuild.build({\n        entryPoints: [input],\n        bundle: true,\n        outdir,\n        format: 'cjs',\n        loader: { '.bin': 'file' },\n        entryNames: '[name]-[hash]',\n        write: false,\n      }),\n      esbuild.build({\n        entryPoints: [input],\n        bundle: true,\n        outdir,\n        format: 'cjs',\n        loader: { '.bin': 'file' },\n        entryNames: '[name]-[hash]',\n        publicPath: 'https://www.example.com',\n        write: false,\n      }),\n    ])\n\n    const names1 = result1.outputFiles.map(x => path.basename(x.path)).sort()\n    const names2 = result2.outputFiles.map(x => path.basename(x.path)).sort()\n\n    // Check that the public path is included in chunk hashes but not asset hashes\n    assert.deepStrictEqual(names1, ['data-BYATPJRB.bin', 'in-6QN3TZ3A.js'])\n    assert.deepStrictEqual(names2, ['data-BYATPJRB.bin', 'in-EJERHMG4.js'])\n  },\n\n  async fileLoaderPublicPath({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const data = path.join(testDir, 'data.bin')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `export {default as value} from ${JSON.stringify(data)}`)\n    await writeFileAsync(data, `stuff`)\n    const value = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      loader: { '.bin': 'file' },\n      publicPath: 'https://www.example.com/assets',\n    })\n    assert.strictEqual(value.outputFiles, void 0)\n    const result = require(output)\n    assert.strictEqual(result.value, 'https://www.example.com/assets/data-BYATPJRB.bin')\n    assert.strictEqual(result.__esModule, true)\n  },\n\n  async fileLoaderCSS({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.css')\n    const data = path.join(testDir, 'data.bin')\n    const output = path.join(testDir, 'out.css')\n    await writeFileAsync(input, `body { background: url(${JSON.stringify(data)}) }`)\n    await writeFileAsync(data, `stuff`)\n    const value = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      loader: { '.bin': 'file' },\n      publicPath: 'https://www.example.com/assets',\n    })\n    assert.strictEqual(value.outputFiles, void 0)\n    assert.strictEqual(await readFileAsync(output, 'utf8'), `/* scripts/.js-api-tests/fileLoaderCSS/in.css */\nbody {\n  background: url(\"https://www.example.com/assets/data-BYATPJRB.bin\");\n}\n`)\n  },\n\n  async fileLoaderWithAssetPath({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const data = path.join(testDir, 'data.bin')\n    const outdir = path.join(testDir, 'out')\n    await writeFileAsync(input, `export {default as value} from ${JSON.stringify(data)}`)\n    await writeFileAsync(data, `stuff`)\n    const value = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outdir,\n      format: 'cjs',\n      loader: { '.bin': 'file' },\n      assetNames: 'assets/name=[name]/hash=[hash]',\n    })\n    assert.strictEqual(value.outputFiles, void 0)\n    const result = require(path.join(outdir, path.basename(input)))\n    assert.strictEqual(result.value, './assets/name=data/hash=BYATPJRB.bin')\n    assert.strictEqual(result.__esModule, true)\n    const stuff = fs.readFileSync(path.join(outdir, result.value), 'utf8')\n    assert.strictEqual(stuff, 'stuff')\n  },\n\n  async fileLoaderWithAssetPathAndPublicPath({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const data = path.join(testDir, 'data.bin')\n    const outdir = path.join(testDir, 'out')\n    await writeFileAsync(input, `export {default as value} from ${JSON.stringify(data)}`)\n    await writeFileAsync(data, `stuff`)\n    const value = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outdir,\n      format: 'cjs',\n      loader: { '.bin': 'file' },\n      assetNames: 'assets/name=[name]/hash=[hash]',\n      publicPath: 'https://www.example.com',\n    })\n    assert.strictEqual(value.outputFiles, void 0)\n    const result = require(path.join(outdir, path.basename(input)))\n    assert.strictEqual(result.value, 'https://www.example.com/assets/name=data/hash=BYATPJRB.bin')\n    assert.strictEqual(result.__esModule, true)\n    const stuff = fs.readFileSync(path.join(outdir, 'assets', 'name=data', 'hash=BYATPJRB.bin'), 'utf8')\n    assert.strictEqual(stuff, 'stuff')\n  },\n\n  async fileLoaderBinaryVsText({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const valid = path.join(testDir, 'valid.bin')\n    const invalid = path.join(testDir, 'invalid.bin')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `\n      import valid from ${JSON.stringify(valid)}\n      import invalid from ${JSON.stringify(invalid)}\n      console.log(valid, invalid)\n    `)\n    await writeFileAsync(valid, Buffer.from([0xCF, 0x80]))\n    await writeFileAsync(invalid, Buffer.from([0x80, 0xCF]))\n    const value = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      loader: { '.bin': 'file' },\n      write: false,\n    })\n    assert.strictEqual(value.outputFiles.length, 3)\n\n    // Valid UTF-8 should decode correctly\n    assert.deepEqual(value.outputFiles[0].contents, new Uint8Array([207, 128]))\n    assert.strictEqual(value.outputFiles[0].text, 'π')\n\n    // Invalid UTF-8 should be preserved as bytes but should be replaced by the U+FFFD replacement character when decoded\n    assert.deepEqual(value.outputFiles[1].contents, new Uint8Array([128, 207]))\n    assert.strictEqual(value.outputFiles[1].text, '\\uFFFD\\uFFFD')\n  },\n\n  async metafile({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const imported = path.join(testDir, 'imported.js')\n    const text = path.join(testDir, 'text.txt')\n    const css = path.join(testDir, 'example.css')\n    const outputJS = path.join(testDir, 'out.js')\n    const outputCSS = path.join(testDir, 'out.css')\n    await writeFileAsync(entry, `\n      import x from \"./imported\"\n      const y = require(\"./text.txt\")\n      import * as z from \"./example.css\"\n      console.log(x, y, z)\n    `)\n    await writeFileAsync(imported, 'export default 123')\n    await writeFileAsync(text, 'some text')\n    await writeFileAsync(css, 'body { some: css; }')\n    const result = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      outfile: outputJS,\n      metafile: true,\n      sourcemap: true,\n      loader: { '.txt': 'file' },\n    })\n\n    const json = result.metafile\n    assert.strictEqual(Object.keys(json.inputs).length, 4)\n    assert.strictEqual(Object.keys(json.outputs).length, 5)\n    const cwd = process.cwd()\n    const makePath = absPath => path.relative(cwd, absPath).split(path.sep).join('/')\n\n    // Check inputs\n    assert.deepStrictEqual(json.inputs[makePath(entry)].bytes, 144)\n    assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [\n      { path: makePath(imported), kind: 'import-statement', original: './imported' },\n      { path: makePath(css), kind: 'import-statement', original: './example.css' },\n      { path: makePath(text), kind: 'require-call', original: './text.txt' },\n    ])\n    assert.deepStrictEqual(json.inputs[makePath(imported)].bytes, 18)\n    assert.deepStrictEqual(json.inputs[makePath(imported)].imports, [])\n    assert.deepStrictEqual(json.inputs[makePath(text)].bytes, 9)\n    assert.deepStrictEqual(json.inputs[makePath(text)].imports, [])\n    assert.deepStrictEqual(json.inputs[makePath(css)].bytes, 19)\n    assert.deepStrictEqual(json.inputs[makePath(css)].imports, [])\n\n    // Check outputs\n    assert.strictEqual(typeof json.outputs[makePath(outputJS)].bytes, 'number')\n    assert.strictEqual(typeof json.outputs[makePath(outputCSS)].bytes, 'number')\n    assert.strictEqual(typeof json.outputs[makePath(outputJS) + '.map'].bytes, 'number')\n    assert.strictEqual(typeof json.outputs[makePath(outputCSS) + '.map'].bytes, 'number')\n    assert.strictEqual(json.outputs[makePath(outputJS)].entryPoint, makePath(entry))\n    assert.strictEqual(json.outputs[makePath(outputCSS)].entryPoint, undefined) // This is deliberately undefined\n    assert.deepStrictEqual(json.outputs[makePath(outputJS) + '.map'].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outputJS) + '.map'].exports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outputJS) + '.map'].inputs, {})\n    assert.deepStrictEqual(json.outputs[makePath(outputCSS) + '.map'].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outputCSS) + '.map'].exports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outputCSS) + '.map'].inputs, {})\n\n    // Check inputs for main output\n    const outputInputs = json.outputs[makePath(outputJS)].inputs\n    assert.strictEqual(Object.keys(outputInputs).length, 4)\n    assert.strictEqual(typeof outputInputs[makePath(entry)].bytesInOutput, 'number')\n    assert.strictEqual(typeof outputInputs[makePath(imported)].bytesInOutput, 'number')\n    assert.strictEqual(typeof outputInputs[makePath(text)].bytesInOutput, 'number')\n    assert.strictEqual(typeof outputInputs[makePath(css)].bytesInOutput, 'number')\n  },\n\n  async metafileSplitting({ esbuild, testDir }) {\n    const entry1 = path.join(testDir, 'entry1.js')\n    const entry2 = path.join(testDir, 'entry2.js')\n    const imported = path.join(testDir, 'imported.js')\n    const outdir = path.join(testDir, 'out')\n    await writeFileAsync(entry1, `\n      import x, {f1} from \"./${path.basename(imported)}\"\n      console.log(1, x, f1())\n      export {x}\n    `)\n    await writeFileAsync(entry2, `\n      import x, {f2} from \"./${path.basename(imported)}\"\n      console.log('entry 2', x, f2())\n      export {x as y}\n    `)\n    await writeFileAsync(imported, `\n      export default 123\n      export function f1() {}\n      export function f2() {}\n      console.log('shared')\n    `)\n    const result = await esbuild.build({\n      entryPoints: [entry1, entry2],\n      bundle: true,\n      outdir,\n      metafile: true,\n      splitting: true,\n      format: 'esm',\n    })\n\n    const json = result.metafile\n    assert.strictEqual(Object.keys(json.inputs).length, 3)\n    assert.strictEqual(Object.keys(json.outputs).length, 3)\n    const cwd = process.cwd()\n    const makeOutPath = basename => path.relative(cwd, path.join(outdir, basename)).split(path.sep).join('/')\n    const makeInPath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')\n\n    // Check metafile\n    const inEntry1 = makeInPath(entry1);\n    const inEntry2 = makeInPath(entry2);\n    const inImported = makeInPath(imported);\n    const chunk = 'chunk-YNV25ITT.js';\n    const outEntry1 = makeOutPath(path.basename(entry1));\n    const outEntry2 = makeOutPath(path.basename(entry2));\n    const outChunk = makeOutPath(chunk);\n\n    assert.deepStrictEqual(json.inputs[inEntry1], {\n      bytes: 94,\n      imports: [{ path: inImported, kind: 'import-statement', original: './' + path.basename(imported) }],\n      format: 'esm',\n    })\n    assert.deepStrictEqual(json.inputs[inEntry2], {\n      bytes: 107,\n      imports: [{ path: inImported, kind: 'import-statement', original: './' + path.basename(imported) }],\n      format: 'esm',\n    })\n    assert.deepStrictEqual(json.inputs[inImported], {\n      bytes: 118,\n      imports: [],\n      format: 'esm',\n    })\n\n    assert.deepStrictEqual(json.outputs[outEntry1].imports, [{ path: makeOutPath(chunk), kind: 'import-statement' }])\n    assert.deepStrictEqual(json.outputs[outEntry2].imports, [{ path: makeOutPath(chunk), kind: 'import-statement' }])\n    assert.deepStrictEqual(json.outputs[outChunk].imports, [])\n\n    assert.deepStrictEqual(json.outputs[outEntry1].exports, ['x'])\n    assert.deepStrictEqual(json.outputs[outEntry2].exports, ['y'])\n    assert.deepStrictEqual(json.outputs[outChunk].exports, ['f1', 'f2', 'imported_default'])\n\n    assert.deepStrictEqual(json.outputs[outEntry1].inputs, { [inEntry1]: { bytesInOutput: 40 } })\n    assert.deepStrictEqual(json.outputs[outEntry2].inputs, { [inEntry2]: { bytesInOutput: 48 } })\n    assert.deepStrictEqual(json.outputs[outChunk].inputs, { [inImported]: { bytesInOutput: 87 } })\n  },\n\n  async metafileSplittingPublicPath({ esbuild, testDir }) {\n    const entry1 = path.join(testDir, 'entry1.js')\n    const entry2 = path.join(testDir, 'entry2.js')\n    const imported = path.join(testDir, 'imported.js')\n    const outdir = path.join(testDir, 'out')\n    await writeFileAsync(entry1, `\n      import x, {f1} from \"./${path.basename(imported)}\"\n      console.log(1, x, f1())\n      export {x}\n    `)\n    await writeFileAsync(entry2, `\n      import x, {f2} from \"./${path.basename(imported)}\"\n      console.log('entry 2', x, f2())\n      export {x as y}\n    `)\n    await writeFileAsync(imported, `\n      export default 123\n      export function f1() {}\n      export function f2() {}\n      console.log('shared')\n    `)\n    const result = await esbuild.build({\n      entryPoints: [entry1, entry2],\n      bundle: true,\n      outdir,\n      metafile: true,\n      splitting: true,\n      format: 'esm',\n      publicPath: 'public',\n    })\n\n    const json = result.metafile\n    assert.strictEqual(Object.keys(json.inputs).length, 3)\n    assert.strictEqual(Object.keys(json.outputs).length, 3)\n    const cwd = process.cwd()\n    const makeOutPath = basename => path.relative(cwd, path.join(outdir, basename)).split(path.sep).join('/')\n    const makeInPath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')\n\n    // Check metafile\n    const inEntry1 = makeInPath(entry1);\n    const inEntry2 = makeInPath(entry2);\n    const inImported = makeInPath(imported);\n    const chunk = 'chunk-ELD4XOGW.js';\n    const outEntry1 = makeOutPath(path.basename(entry1));\n    const outEntry2 = makeOutPath(path.basename(entry2));\n    const outChunk = makeOutPath(chunk);\n\n    assert.deepStrictEqual(json.inputs[inEntry1], {\n      bytes: 94,\n      imports: [{ path: inImported, kind: 'import-statement', original: './' + path.basename(imported) }],\n      format: 'esm',\n    })\n    assert.deepStrictEqual(json.inputs[inEntry2], {\n      bytes: 107,\n      imports: [{ path: inImported, kind: 'import-statement', original: './' + path.basename(imported) }],\n      format: 'esm',\n    })\n    assert.deepStrictEqual(json.inputs[inImported], {\n      bytes: 118,\n      imports: [],\n      format: 'esm',\n    })\n\n    assert.deepStrictEqual(json.outputs[outEntry1].imports, [{ path: makeOutPath(chunk), kind: 'import-statement' }])\n    assert.deepStrictEqual(json.outputs[outEntry2].imports, [{ path: makeOutPath(chunk), kind: 'import-statement' }])\n    assert.deepStrictEqual(json.outputs[outChunk].imports, [])\n\n    assert.deepStrictEqual(json.outputs[outEntry1].exports, ['x'])\n    assert.deepStrictEqual(json.outputs[outEntry2].exports, ['y'])\n    assert.deepStrictEqual(json.outputs[outChunk].exports, ['f1', 'f2', 'imported_default'])\n\n    assert.deepStrictEqual(json.outputs[outEntry1].inputs, { [inEntry1]: { bytesInOutput: 40 } })\n    assert.deepStrictEqual(json.outputs[outEntry2].inputs, { [inEntry2]: { bytesInOutput: 48 } })\n    assert.deepStrictEqual(json.outputs[outChunk].inputs, { [inImported]: { bytesInOutput: 87 } })\n  },\n\n  async metafileSplittingDoubleDynamicImport({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const importDir = path.join(testDir, 'import-dir')\n    const import1 = path.join(importDir, 'import1.js')\n    const import2 = path.join(importDir, 'import2.js')\n    const shared = path.join(testDir, 'shared.js')\n    const outdir = path.join(testDir, 'out')\n    const makeImportPath = (importing, imported) => './' + path.relative(path.dirname(importing), imported).split(path.sep).join('/')\n    await mkdirAsync(importDir)\n    await writeFileAsync(entry, `\n      import ${JSON.stringify(makeImportPath(entry, shared))}\n      import(${JSON.stringify(makeImportPath(entry, import1))})\n      import(${JSON.stringify(makeImportPath(entry, import2))})\n    `)\n    await writeFileAsync(import1, `\n      import ${JSON.stringify(makeImportPath(import1, shared))}\n    `)\n    await writeFileAsync(import2, `\n      import ${JSON.stringify(makeImportPath(import2, shared))}\n    `)\n    await writeFileAsync(shared, `\n      console.log('side effect')\n    `)\n    const result = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      outdir,\n      metafile: true,\n      splitting: true,\n      format: 'esm',\n    })\n\n    const json = result.metafile\n    assert.strictEqual(Object.keys(json.inputs).length, 4)\n    assert.strictEqual(Object.keys(json.outputs).length, 4)\n    const cwd = process.cwd()\n    const makeOutPath = basename => path.relative(cwd, path.join(outdir, basename)).split(path.sep).join('/')\n    const makeInPath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')\n\n    // Check metafile\n    const inEntry = makeInPath(entry);\n    const inImport1 = makeInPath(import1);\n    const inImport2 = makeInPath(import2);\n    const inShared = makeInPath(shared);\n    const chunk = 'chunk-3GRHLZ7X.js';\n    const outEntry = makeOutPath(path.relative(testDir, entry));\n    const outImport1 = makeOutPath('import1-SELM3ZIG.js');\n    const outImport2 = makeOutPath('import2-3GSTEHBF.js');\n    const outChunk = makeOutPath(chunk);\n\n    assert.deepStrictEqual(json.inputs[inEntry], {\n      bytes: 112,\n      imports: [\n        { path: inShared, kind: 'import-statement', original: makeImportPath(entry, shared) },\n        { path: inImport1, kind: 'dynamic-import', original: makeImportPath(entry, import1) },\n        { path: inImport2, kind: 'dynamic-import', original: makeImportPath(entry, import2) },\n      ],\n      format: 'esm',\n    })\n    assert.deepStrictEqual(json.inputs[inImport1], {\n      bytes: 35,\n      imports: [\n        { path: inShared, kind: 'import-statement', original: makeImportPath(import1, shared) },\n      ],\n      format: 'esm',\n    })\n    assert.deepStrictEqual(json.inputs[inImport2], {\n      bytes: 35,\n      imports: [\n        { path: inShared, kind: 'import-statement', original: makeImportPath(import2, shared) },\n      ],\n      format: 'esm',\n    })\n    assert.deepStrictEqual(json.inputs[inShared], { bytes: 38, imports: [] })\n\n    assert.deepStrictEqual(Object.keys(json.outputs), [\n      outEntry,\n      outImport1,\n      outImport2,\n      outChunk,\n    ])\n\n    assert.deepStrictEqual(json.outputs[outEntry].imports, [\n      { path: outChunk, kind: 'import-statement' },\n      { path: outImport1, kind: 'dynamic-import' },\n      { path: outImport2, kind: 'dynamic-import' },\n    ])\n    assert.deepStrictEqual(json.outputs[outImport1].imports, [{ path: outChunk, kind: 'import-statement' }])\n    assert.deepStrictEqual(json.outputs[outImport2].imports, [{ path: outChunk, kind: 'import-statement' }])\n    assert.deepStrictEqual(json.outputs[outChunk].imports, [])\n\n    assert.deepStrictEqual(json.outputs[outEntry].exports, [])\n    assert.deepStrictEqual(json.outputs[outImport1].exports, [])\n    assert.deepStrictEqual(json.outputs[outImport2].exports, [])\n    assert.deepStrictEqual(json.outputs[outChunk].exports, [])\n\n    assert.deepStrictEqual(json.outputs[outEntry].inputs, { [inEntry]: { bytesInOutput: 66 } })\n    assert.deepStrictEqual(json.outputs[outImport1].inputs, { [inImport1]: { bytesInOutput: 0 } })\n    assert.deepStrictEqual(json.outputs[outImport2].inputs, { [inImport2]: { bytesInOutput: 0 } })\n    assert.deepStrictEqual(json.outputs[outChunk].inputs, { [inShared]: { bytesInOutput: 28 } })\n  },\n\n  async metafileCJSInFormatIIFE({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const outfile = path.join(testDir, 'out.js')\n    await writeFileAsync(entry, `module.exports = {}`)\n    const result = await esbuild.build({\n      entryPoints: [entry],\n      outfile,\n      metafile: true,\n      format: 'iife',\n    })\n    const cwd = process.cwd()\n    const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')\n    const json = result.metafile\n    assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].exports, [])\n  },\n\n  async metafileCJSInFormatCJS({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const outfile = path.join(testDir, 'out.js')\n    await writeFileAsync(entry, `module.exports = {}`)\n    const result = await esbuild.build({\n      entryPoints: [entry],\n      outfile,\n      metafile: true,\n      format: 'cjs',\n    })\n    const cwd = process.cwd()\n    const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')\n    const json = result.metafile\n    assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].exports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].entryPoint, makePath(entry))\n  },\n\n  async metafileCJSInFormatESM({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const outfile = path.join(testDir, 'out.js')\n    await writeFileAsync(entry, `module.exports = {}`)\n    const result = await esbuild.build({\n      entryPoints: [entry],\n      outfile,\n      metafile: true,\n      format: 'esm',\n    })\n    const cwd = process.cwd()\n    const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')\n    const json = result.metafile\n    assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].exports, ['default'])\n  },\n\n  async metafileESMInFormatIIFE({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const outfile = path.join(testDir, 'out.js')\n    await writeFileAsync(entry, `export let a = 1, b = 2`)\n    const result = await esbuild.build({\n      entryPoints: [entry],\n      outfile,\n      metafile: true,\n      format: 'iife',\n    })\n    const cwd = process.cwd()\n    const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')\n    const json = result.metafile\n    assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].exports, [])\n  },\n\n  async metafileESMInFormatCJS({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const outfile = path.join(testDir, 'out.js')\n    await writeFileAsync(entry, `export let a = 1, b = 2`)\n    const result = await esbuild.build({\n      entryPoints: [entry],\n      outfile,\n      metafile: true,\n      format: 'cjs',\n    })\n    const cwd = process.cwd()\n    const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')\n    const json = result.metafile\n    assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].exports, [])\n  },\n\n  async metafileESMInFormatESM({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const outfile = path.join(testDir, 'out.js')\n    await writeFileAsync(entry, `export let a = 1, b = 2`)\n    const result = await esbuild.build({\n      entryPoints: [entry],\n      outfile,\n      metafile: true,\n      format: 'esm',\n    })\n    const cwd = process.cwd()\n    const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')\n    const json = result.metafile\n    assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].exports, ['a', 'b'])\n  },\n\n  async metafileNestedExportNames({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const nested1 = path.join(testDir, 'nested1.js')\n    const nested2 = path.join(testDir, 'nested2.js')\n    const nested3 = path.join(testDir, 'nested3.js')\n    const outfile = path.join(testDir, 'out.js')\n    await writeFileAsync(entry, `\n      export {nested1} from ${JSON.stringify(nested1)}\n      export * from ${JSON.stringify(nested2)}\n      export let topLevel = 0\n    `)\n    await writeFileAsync(nested1, `\n      import {nested3} from ${JSON.stringify(nested3)}\n      export default 1\n      export let nested1 = nested3\n    `)\n    await writeFileAsync(nested2, `\n      export default 'nested2'\n      export let nested2 = 2\n    `)\n    await writeFileAsync(nested3, `\n      export let nested3 = 3\n    `)\n    const result = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      outfile,\n      metafile: true,\n      format: 'esm',\n    })\n    const cwd = process.cwd()\n    const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')\n    const json = result.metafile\n    assert.deepStrictEqual(json.inputs[makePath(entry)].imports, [\n      { path: makePath(nested1), kind: 'import-statement', original: nested1 },\n      { path: makePath(nested2), kind: 'import-statement', original: nested2 },\n    ])\n    assert.deepStrictEqual(json.inputs[makePath(nested1)].imports, [\n      { path: makePath(nested3), kind: 'import-statement', original: nested3 },\n    ])\n    assert.deepStrictEqual(json.inputs[makePath(nested2)].imports, [])\n    assert.deepStrictEqual(json.inputs[makePath(nested3)].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].imports, [])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].exports, ['nested1', 'nested2', 'topLevel'])\n    assert.deepStrictEqual(json.outputs[makePath(outfile)].entryPoint, makePath(entry))\n  },\n\n  async metafileCSS({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.css')\n    const imported = path.join(testDir, 'imported.css')\n    const image = path.join(testDir, 'example.png')\n    const output = path.join(testDir, 'out.css')\n    await writeFileAsync(entry, `\n      @import \"./imported\";\n      body { background: url(https://example.com/external.png) }\n    `)\n    await writeFileAsync(imported, `\n      a { background: url(./example.png) }\n    `)\n    await writeFileAsync(image, 'an image')\n    const result = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      outfile: output,\n      metafile: true,\n      sourcemap: true,\n      loader: { '.png': 'dataurl' },\n    })\n\n    const json = result.metafile\n    assert.strictEqual(Object.keys(json.inputs).length, 3)\n    assert.strictEqual(Object.keys(json.outputs).length, 2)\n    const cwd = process.cwd()\n    const makePath = absPath => path.relative(cwd, absPath).split(path.sep).join('/')\n\n    // Check inputs\n    assert.deepStrictEqual(json, {\n      inputs: {\n        [makePath(entry)]: {\n          bytes: 98,\n          imports: [\n            { path: makePath(imported), kind: 'import-rule', original: './imported' },\n            { external: true, kind: 'url-token', path: 'https://example.com/external.png' },\n          ]\n        },\n        [makePath(image)]: { bytes: 8, imports: [] },\n        [makePath(imported)]: { bytes: 48, imports: [{ path: makePath(image), kind: 'url-token', original: './example.png' }] },\n      },\n      outputs: {\n        [makePath(output)]: {\n          bytes: 253,\n          entryPoint: makePath(entry),\n          imports: [\n            { kind: 'url-token', path: 'data:image/png,an image' },\n            { external: true, kind: 'url-token', path: 'https://example.com/external.png' },\n          ],\n          inputs: {\n            [makePath(entry)]: { bytesInOutput: 62 },\n            [makePath(imported)]: { bytesInOutput: 51 },\n          },\n        },\n        [makePath(output + '.map')]: {\n          bytes: 325,\n          exports: [],\n          imports: [],\n          inputs: {},\n        },\n      },\n    })\n  },\n\n  async metafileLoaderFileMultipleEntry({ esbuild, testDir }) {\n    const entry1 = path.join(testDir, 'entry1.js')\n    const entry2 = path.join(testDir, 'entry2.js')\n    const file = path.join(testDir, 'x.file')\n    const outdir = path.join(testDir, 'out')\n    await writeFileAsync(entry1, `\n      export {default} from './x.file'\n    `)\n    await writeFileAsync(entry2, `\n      import z from './x.file'\n      console.log(z)\n    `)\n    await writeFileAsync(file, `This is a file`)\n    const result = await esbuild.build({\n      entryPoints: [entry1, entry2],\n      bundle: true,\n      loader: { '.file': 'file' },\n      outdir,\n      metafile: true,\n      format: 'cjs',\n    })\n    const json = result.metafile\n    const cwd = process.cwd()\n    const makePath = pathname => path.relative(cwd, pathname).split(path.sep).join('/')\n    const fileName = require(path.join(outdir, 'entry1.js')).default\n    const fileKey = makePath(path.join(outdir, fileName))\n    assert.deepStrictEqual(json.outputs[fileKey].imports, [])\n    assert.deepStrictEqual(json.outputs[fileKey].exports, [])\n    assert.deepStrictEqual(json.outputs[fileKey].inputs, { [makePath(file)]: { bytesInOutput: 14 } })\n  },\n\n  // Test in-memory output files\n  async writeFalse({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const inputCode = 'console.log()'\n    await writeFileAsync(input, inputCode)\n\n    const value = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      sourcemap: true,\n      format: 'esm',\n      metafile: true,\n      write: false,\n    })\n\n    assert.strictEqual(fs.existsSync(output), false)\n    assert.notStrictEqual(value.outputFiles, void 0)\n    assert.strictEqual(value.outputFiles.length, 2)\n    assert.strictEqual(value.outputFiles[0].path, output + '.map')\n    assert.strictEqual(value.outputFiles[0].contents.constructor, Uint8Array)\n    assert.strictEqual(value.outputFiles[0].hash, 'BIjVBRZOQ5s')\n    assert.strictEqual(value.outputFiles[1].path, output)\n    assert.strictEqual(value.outputFiles[1].contents.constructor, Uint8Array)\n    assert.strictEqual(value.outputFiles[1].hash, 'zvyzJPvi96o')\n\n    const sourceMap = JSON.parse(Buffer.from(value.outputFiles[0].contents).toString())\n    const js = Buffer.from(value.outputFiles[1].contents).toString()\n    assert.strictEqual(sourceMap.version, 3)\n    assert.strictEqual(js, `// scripts/.js-api-tests/writeFalse/in.js\\nconsole.log();\\n//# sourceMappingURL=out.js.map\\n`)\n\n    const cwd = process.cwd()\n    const makePath = file => path.relative(cwd, file).split(path.sep).join('/')\n    const meta = value.metafile\n    assert.strictEqual(meta.inputs[makePath(input)].bytes, inputCode.length)\n    assert.strictEqual(meta.outputs[makePath(output)].bytes, js.length)\n    assert.strictEqual(meta.outputs[makePath(output + '.map')].bytes, value.outputFiles[0].contents.length)\n  },\n\n  async allowOverwrite({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.mjs')\n    await writeFileAsync(input, `export default FOO`)\n\n    // Fail without \"allowOverwrite\"\n    try {\n      await esbuild.build({\n        entryPoints: [input],\n        outfile: input,\n        logLevel: 'silent',\n      })\n      throw new Error('Expected build failure');\n    } catch (e) {\n      if (!e || !e.errors || !e.errors.length || !e.errors[0].text.includes('Refusing to overwrite input file'))\n        throw e\n    }\n\n    // Succeed with \"allowOverwrite\"\n    await esbuild.build({\n      entryPoints: [input],\n      outfile: input,\n      allowOverwrite: true,\n      define: { FOO: '123' },\n    })\n\n    // This needs to use relative paths to avoid breaking on Windows.\n    // Importing by absolute path doesn't work on Windows in node.\n    const result = await import('./' + path.relative(__dirname, input))\n\n    assert.strictEqual(result.default, 123)\n  },\n\n  async splittingRelativeSameDir({ esbuild, testDir }) {\n    const inputA = path.join(testDir, 'a.js')\n    const inputB = path.join(testDir, 'b.js')\n    const inputCommon = path.join(testDir, 'common.js')\n    await writeFileAsync(inputA, `\n      import x from \"./${path.basename(inputCommon)}\"\n      console.log('a' + x)\n    `)\n    await writeFileAsync(inputB, `\n      import x from \"./${path.basename(inputCommon)}\"\n      console.log('b' + x)\n    `)\n    await writeFileAsync(inputCommon, `\n      export default 'common'\n    `)\n    const outdir = path.join(testDir, 'out')\n    const value = await esbuild.build({\n      entryPoints: [inputA, inputB],\n      bundle: true,\n      outdir,\n      format: 'esm',\n      splitting: true,\n      write: false,\n    })\n    assert.strictEqual(value.outputFiles.length, 3)\n\n    // These should all use forward slashes, even on Windows\n    const chunk = 'chunk-P3NHLAOZ.js'\n    assert.strictEqual(Buffer.from(value.outputFiles[0].contents).toString(), `import {\n  common_default\n} from \"./${chunk}\";\n\n// scripts/.js-api-tests/splittingRelativeSameDir/a.js\nconsole.log(\"a\" + common_default);\n`)\n    assert.strictEqual(Buffer.from(value.outputFiles[1].contents).toString(), `import {\n  common_default\n} from \"./${chunk}\";\n\n// scripts/.js-api-tests/splittingRelativeSameDir/b.js\nconsole.log(\"b\" + common_default);\n`)\n    assert.strictEqual(Buffer.from(value.outputFiles[2].contents).toString(), `// scripts/.js-api-tests/splittingRelativeSameDir/common.js\nvar common_default = \"common\";\n\nexport {\n  common_default\n};\n`)\n\n    assert.strictEqual(value.outputFiles[0].path, path.join(outdir, path.basename(inputA)))\n    assert.strictEqual(value.outputFiles[1].path, path.join(outdir, path.basename(inputB)))\n    assert.strictEqual(value.outputFiles[2].path, path.join(outdir, chunk))\n  },\n\n  async splittingRelativeNestedDir({ esbuild, testDir }) {\n    const inputA = path.join(testDir, 'a/demo.js')\n    const inputB = path.join(testDir, 'b/demo.js')\n    const inputCommon = path.join(testDir, 'common.js')\n    await mkdirAsync(path.dirname(inputA)).catch(x => x)\n    await mkdirAsync(path.dirname(inputB)).catch(x => x)\n    await writeFileAsync(inputA, `\n      import x from \"../${path.basename(inputCommon)}\"\n      console.log('a' + x)\n    `)\n    await writeFileAsync(inputB, `\n      import x from \"../${path.basename(inputCommon)}\"\n      console.log('b' + x)\n    `)\n    await writeFileAsync(inputCommon, `\n      export default 'common'\n    `)\n    const outdir = path.join(testDir, 'out')\n    const value = await esbuild.build({\n      entryPoints: [inputA, inputB],\n      bundle: true,\n      outdir,\n      format: 'esm',\n      splitting: true,\n      write: false,\n    })\n    assert.strictEqual(value.outputFiles.length, 3)\n\n    // These should all use forward slashes, even on Windows\n    const chunk = 'chunk-BPDO6GL2.js'\n    assert.strictEqual(Buffer.from(value.outputFiles[0].contents).toString(), `import {\n  common_default\n} from \"../${chunk}\";\n\n// scripts/.js-api-tests/splittingRelativeNestedDir/a/demo.js\nconsole.log(\"a\" + common_default);\n`)\n    assert.strictEqual(Buffer.from(value.outputFiles[1].contents).toString(), `import {\n  common_default\n} from \"../${chunk}\";\n\n// scripts/.js-api-tests/splittingRelativeNestedDir/b/demo.js\nconsole.log(\"b\" + common_default);\n`)\n    assert.strictEqual(Buffer.from(value.outputFiles[2].contents).toString(), `// scripts/.js-api-tests/splittingRelativeNestedDir/common.js\nvar common_default = \"common\";\n\nexport {\n  common_default\n};\n`)\n\n    assert.strictEqual(value.outputFiles[0].path, path.join(outdir, path.relative(testDir, inputA)))\n    assert.strictEqual(value.outputFiles[1].path, path.join(outdir, path.relative(testDir, inputB)))\n    assert.strictEqual(value.outputFiles[2].path, path.join(outdir, chunk))\n  },\n\n  async splittingWithChunkPath({ esbuild, testDir }) {\n    const inputA = path.join(testDir, 'a/demo.js')\n    const inputB = path.join(testDir, 'b/demo.js')\n    const inputCommon = path.join(testDir, 'common.js')\n    await mkdirAsync(path.dirname(inputA)).catch(x => x)\n    await mkdirAsync(path.dirname(inputB)).catch(x => x)\n    await writeFileAsync(inputA, `\n      import x from \"../${path.basename(inputCommon)}\"\n      console.log('a' + x)\n    `)\n    await writeFileAsync(inputB, `\n      import x from \"../${path.basename(inputCommon)}\"\n      console.log('b' + x)\n    `)\n    await writeFileAsync(inputCommon, `\n      export default 'common'\n    `)\n    const outdir = path.join(testDir, 'out')\n    const value = await esbuild.build({\n      entryPoints: [inputA, inputB],\n      bundle: true,\n      outdir,\n      format: 'esm',\n      splitting: true,\n      write: false,\n      chunkNames: 'chunks/name=[name]/hash=[hash]',\n    })\n    assert.strictEqual(value.outputFiles.length, 3)\n\n    // These should all use forward slashes, even on Windows\n    const chunk = 'chunks/name=chunk/hash=7RIY4OCQ.js'\n    assert.strictEqual(value.outputFiles[0].text, `import {\n  common_default\n} from \"../${chunk}\";\n\n// scripts/.js-api-tests/splittingWithChunkPath/a/demo.js\nconsole.log(\"a\" + common_default);\n`)\n    assert.strictEqual(value.outputFiles[1].text, `import {\n  common_default\n} from \"../${chunk}\";\n\n// scripts/.js-api-tests/splittingWithChunkPath/b/demo.js\nconsole.log(\"b\" + common_default);\n`)\n    assert.strictEqual(value.outputFiles[2].text, `// scripts/.js-api-tests/splittingWithChunkPath/common.js\nvar common_default = \"common\";\n\nexport {\n  common_default\n};\n`)\n\n    assert.strictEqual(value.outputFiles[0].path, path.join(outdir, path.relative(testDir, inputA)))\n    assert.strictEqual(value.outputFiles[1].path, path.join(outdir, path.relative(testDir, inputB)))\n    assert.strictEqual(value.outputFiles[2].path, path.join(outdir, chunk))\n  },\n\n  async splittingWithEntryHashes({ esbuild, testDir }) {\n    const inputA = path.join(testDir, 'a/demo.js')\n    const inputB = path.join(testDir, 'b/demo.js')\n    const inputCommon = path.join(testDir, 'common.js')\n    await mkdirAsync(path.dirname(inputA)).catch(x => x)\n    await mkdirAsync(path.dirname(inputB)).catch(x => x)\n    await writeFileAsync(inputA, `\n      import x from \"../${path.basename(inputCommon)}\"\n      console.log('a' + x.name)\n    `)\n    await writeFileAsync(inputB, `\n      import x from \"../${path.basename(inputCommon)}\"\n      console.log('b' + x.name)\n    `)\n    await writeFileAsync(inputCommon, `\n      export default { name: 'common' }\n    `)\n    const outdir = path.join(testDir, 'out')\n    const value = await esbuild.build({\n      entryPoints: [inputA, inputB],\n      bundle: true,\n      outdir,\n      format: 'esm',\n      splitting: true,\n      write: false,\n      entryNames: 'entry/name=[name]/hash=[hash]',\n      chunkNames: 'chunks/name=[name]/hash=[hash]',\n    })\n    assert.strictEqual(value.outputFiles.length, 3)\n\n    // These should all use forward slashes, even on Windows\n    const chunk = 'chunks/name=chunk/hash=6VLJRT45.js'\n    assert.strictEqual(value.outputFiles[0].text, `import {\n  common_default\n} from \"../../${chunk}\";\n\n// scripts/.js-api-tests/splittingWithEntryHashes/a/demo.js\nconsole.log(\"a\" + common_default.name);\n`)\n    assert.strictEqual(value.outputFiles[1].text, `import {\n  common_default\n} from \"../../${chunk}\";\n\n// scripts/.js-api-tests/splittingWithEntryHashes/b/demo.js\nconsole.log(\"b\" + common_default.name);\n`)\n    assert.strictEqual(value.outputFiles[2].text, `// scripts/.js-api-tests/splittingWithEntryHashes/common.js\nvar common_default = { name: \"common\" };\n\nexport {\n  common_default\n};\n`)\n\n    const outputA = 'entry/name=demo/hash=ZKX5HN4L.js'\n    const outputB = 'entry/name=demo/hash=TYTZIN4P.js'\n    assert.strictEqual(value.outputFiles[0].path, path.join(outdir, outputA))\n    assert.strictEqual(value.outputFiles[1].path, path.join(outdir, outputB))\n    assert.strictEqual(value.outputFiles[2].path, path.join(outdir, chunk))\n  },\n\n  async splittingWithChunkPathAndCrossChunkImportsIssue899({ esbuild, testDir }) {\n    const entry1 = path.join(testDir, 'src', 'entry1.js')\n    const entry2 = path.join(testDir, 'src', 'entry2.js')\n    const entry3 = path.join(testDir, 'src', 'entry3.js')\n    const shared1 = path.join(testDir, 'src', 'shared1.js')\n    const shared2 = path.join(testDir, 'src', 'shared2.js')\n    const shared3 = path.join(testDir, 'src', 'shared3.js')\n    await mkdirAsync(path.join(testDir, 'src')).catch(x => x)\n    await writeFileAsync(entry1, `\n      import { shared1 } from './shared1';\n      import { shared2 } from './shared2';\n      export default async function() {\n        return shared1() + shared2();\n      }\n    `)\n    await writeFileAsync(entry2, `\n      import { shared2 } from './shared2';\n      import { shared3 } from './shared3';\n      export default async function() {\n        return shared2() + shared3();\n      }\n    `)\n    await writeFileAsync(entry3, `\n      import { shared3 } from './shared3';\n      import { shared1 } from './shared1';\n      export default async function() {\n        return shared3() + shared1();\n      }\n    `)\n    await writeFileAsync(shared1, `\n      import { shared2 } from './shared2';\n      export function shared1() {\n        return shared2().replace('2', '1');\n      }\n    `)\n    await writeFileAsync(shared2, `\n      import { shared3 } from './shared3'\n      export function shared2() {\n        return 'shared2';\n      }\n    `)\n    await writeFileAsync(shared3, `\n      export function shared3() {\n        return 'shared3';\n      }\n    `)\n    const outdir = path.join(testDir, 'out')\n    await esbuild.build({\n      entryPoints: [entry1, entry2, entry3],\n      bundle: true,\n      outdir,\n      format: 'esm',\n      splitting: true,\n      outExtension: { '.js': '.mjs' },\n      chunkNames: 'chunks/[hash]/[name]',\n    })\n\n    // This needs to use relative paths to avoid breaking on Windows.\n    // Importing by absolute path doesn't work on Windows in node.\n    const result1 = await import('./' + path.relative(__dirname, path.join(outdir, 'entry1.mjs')))\n    const result2 = await import('./' + path.relative(__dirname, path.join(outdir, 'entry2.mjs')))\n    const result3 = await import('./' + path.relative(__dirname, path.join(outdir, 'entry3.mjs')))\n\n    assert.strictEqual(await result1.default(), 'shared1shared2');\n    assert.strictEqual(await result2.default(), 'shared2shared3');\n    assert.strictEqual(await result3.default(), 'shared3shared1');\n  },\n\n  async splittingStaticImportHashChange({ esbuild, testDir }) {\n    const input1 = path.join(testDir, 'a', 'in1.js')\n    const input2 = path.join(testDir, 'b', 'in2.js')\n    const outdir = path.join(testDir, 'out')\n\n    await mkdirAsync(path.dirname(input1), { recursive: true })\n    await mkdirAsync(path.dirname(input2), { recursive: true })\n    await writeFileAsync(input1, `import ${JSON.stringify(input2)}`)\n    await writeFileAsync(input2, `console.log(123)`)\n\n    const result1 = await esbuild.build({\n      entryPoints: [input1, input2],\n      bundle: true,\n      outdir,\n      format: 'esm',\n      splitting: true,\n      write: false,\n      entryNames: '[name]-[hash]',\n    })\n\n    await writeFileAsync(input2, `console.log(321)`)\n\n    const result2 = await esbuild.build({\n      entryPoints: [input1, input2],\n      bundle: true,\n      outdir,\n      format: 'esm',\n      splitting: true,\n      write: false,\n      entryNames: '[name]-[hash]',\n    })\n\n    assert.strictEqual(result1.outputFiles.length, 3)\n    assert.strictEqual(result2.outputFiles.length, 3)\n\n    // The hashes of both output files must change. Previously there was a bug\n    // where hash changes worked for static imports but not for dynamic imports.\n    for (const { path: oldPath } of result1.outputFiles)\n      for (const { path: newPath } of result2.outputFiles)\n        assert.notStrictEqual(oldPath, newPath)\n  },\n\n  async splittingDynamicImportHashChangeIssue1076({ esbuild, testDir }) {\n    const input1 = path.join(testDir, 'a', 'in1.js')\n    const input2 = path.join(testDir, 'b', 'in2.js')\n    const outdir = path.join(testDir, 'out')\n\n    await mkdirAsync(path.dirname(input1), { recursive: true })\n    await mkdirAsync(path.dirname(input2), { recursive: true })\n    await writeFileAsync(input1, `import(${JSON.stringify(input2)})`)\n    await writeFileAsync(input2, `console.log(123)`)\n\n    const result1 = await esbuild.build({\n      entryPoints: [input1],\n      bundle: true,\n      outdir,\n      format: 'esm',\n      splitting: true,\n      write: false,\n      entryNames: '[name]-[hash]',\n    })\n\n    await writeFileAsync(input2, `console.log(321)`)\n\n    const result2 = await esbuild.build({\n      entryPoints: [input1],\n      bundle: true,\n      outdir,\n      format: 'esm',\n      splitting: true,\n      write: false,\n      entryNames: '[name]-[hash]',\n    })\n\n    assert.strictEqual(result1.outputFiles.length, 2)\n    assert.strictEqual(result2.outputFiles.length, 2)\n\n    // The hashes of both output files must change. Previously there was a bug\n    // where hash changes worked for static imports but not for dynamic imports.\n    for (const { path: oldPath } of result1.outputFiles)\n      for (const { path: newPath } of result2.outputFiles)\n        assert.notStrictEqual(oldPath, newPath)\n  },\n\n  async stdinStdoutBundle({ esbuild, testDir }) {\n    const auxiliary = path.join(testDir, 'auxiliary.js')\n    await writeFileAsync(auxiliary, 'export default 123')\n    const value = await esbuild.build({\n      stdin: {\n        contents: `\n          import x from './auxiliary.js'\n          console.log(x)\n        `,\n        resolveDir: testDir,\n      },\n      bundle: true,\n      write: false,\n    })\n    assert.strictEqual(value.outputFiles.length, 1)\n    assert.strictEqual(value.outputFiles[0].path, '<stdout>')\n    assert.strictEqual(Buffer.from(value.outputFiles[0].contents).toString(), `(() => {\n  // scripts/.js-api-tests/stdinStdoutBundle/auxiliary.js\n  var auxiliary_default = 123;\n\n  // <stdin>\n  console.log(auxiliary_default);\n})();\n`)\n  },\n\n  async stdinOutfileBundle({ esbuild, testDir }) {\n    const auxiliary = path.join(testDir, 'auxiliary.js')\n    const outfile = path.join(testDir, 'out.js')\n    await writeFileAsync(auxiliary, 'export default 123')\n    const value = await esbuild.build({\n      stdin: {\n        contents: `\n          import x from './auxiliary.js'\n          export {x as fromStdin}\n        `,\n        resolveDir: testDir,\n      },\n      bundle: true,\n      outfile,\n      format: 'cjs',\n    })\n    assert.strictEqual(value.outputFiles, void 0)\n    const result = require(outfile)\n    assert.strictEqual(result.fromStdin, 123)\n  },\n\n  async stdinAndEntryBundle({ esbuild, testDir }) {\n    const srcDir = path.join(testDir, 'src')\n    const entry = path.join(srcDir, 'entry.js')\n    const auxiliary = path.join(srcDir, 'auxiliary.js')\n    const outdir = path.join(testDir, 'out')\n    await mkdirAsync(srcDir)\n    await writeFileAsync(auxiliary, 'export default 123')\n    await writeFileAsync(entry, `\n      import x from './auxiliary.js'\n      export let fromEntry = x\n    `)\n    const value = await esbuild.build({\n      entryPoints: [entry],\n      stdin: {\n        contents: `\n          import x from './src/auxiliary.js'\n          export {x as fromStdin}\n        `,\n        resolveDir: testDir,\n      },\n      bundle: true,\n      outdir,\n      format: 'cjs',\n    })\n    assert.strictEqual(value.outputFiles, void 0)\n    const entryResult = require(path.join(outdir, path.basename(entry)))\n    assert.strictEqual(entryResult.fromEntry, 123)\n    const stdinResult = require(path.join(outdir, path.basename('stdin.js')))\n    assert.strictEqual(stdinResult.fromStdin, 123)\n  },\n\n  async forceTsConfig({ esbuild, testDir }) {\n    // ./tsconfig.json\n    // ./a/forced-config.json\n    // ./a/b/test-impl.js\n    // ./a/b/c/in.js\n    const aDir = path.join(testDir, 'a')\n    const bDir = path.join(aDir, 'b')\n    const cDir = path.join(bDir, 'c')\n    await mkdirAsync(aDir).catch(x => x)\n    await mkdirAsync(bDir).catch(x => x)\n    await mkdirAsync(cDir).catch(x => x)\n    const input = path.join(cDir, 'in.js')\n    const forced = path.join(bDir, 'test-impl.js')\n    const tsconfigIgnore = path.join(testDir, 'tsconfig.json')\n    const tsconfigForced = path.join(aDir, 'forced-config.json')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, 'import \"test\"')\n    await writeFileAsync(forced, 'console.log(\"success\")')\n    await writeFileAsync(tsconfigIgnore, '{\"compilerOptions\": {\"baseUrl\": \"./a\", \"paths\": {\"test\": [\"./ignore.js\"]}}}')\n    await writeFileAsync(tsconfigForced, '{\"compilerOptions\": {\"baseUrl\": \"./b\", \"paths\": {\"test\": [\"./test-impl.js\"]}}}')\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      tsconfig: tsconfigForced,\n      format: 'esm',\n    })\n    const result = await readFileAsync(output, 'utf8')\n    assert.strictEqual(result, `// scripts/.js-api-tests/forceTsConfig/a/b/test-impl.js\nconsole.log(\"success\");\n`)\n  },\n\n  async forceTsConfigRaw({ esbuild, testDir }) {\n    // ./a/tsconfig.json\n    // ./a/b/test-impl.js\n    // ./a/b/c/in.js\n    const aDir = path.join(testDir, 'a')\n    const bDir = path.join(aDir, 'b')\n    const cDir = path.join(bDir, 'c')\n    await mkdirAsync(aDir).catch(x => x)\n    await mkdirAsync(bDir).catch(x => x)\n    await mkdirAsync(cDir).catch(x => x)\n    const input = path.join(cDir, 'in.js')\n    const forced = path.join(bDir, 'test-impl.js')\n    const tsconfigIgnore = path.join(aDir, 'tsconfig.json')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, 'import \"test\"')\n    await writeFileAsync(forced, 'console.log(\"success\")')\n    await writeFileAsync(tsconfigIgnore, '{\"compilerOptions\": {\"baseUrl\": \"./b\", \"paths\": {\"test\": [\"./ignore.js\"]}}}')\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      absWorkingDir: testDir, // \"paths\" are resolved relative to the current working directory\n      tsconfigRaw: {\n        compilerOptions: {\n          baseUrl: './a/b',\n          paths: {\n            test: ['./test-impl.js'],\n          },\n        },\n      },\n      format: 'esm',\n    })\n    const result = await readFileAsync(output, 'utf8')\n    assert.strictEqual(result, `// a/b/test-impl.js\nconsole.log(\"success\");\n`)\n  },\n\n  async forceTsConfigRawStdin({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const test = path.join(testDir, 'test-impl.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, 'import \"test\"')\n    await writeFileAsync(test, 'console.log(\"success\")')\n    await esbuild.build({\n      stdin: {\n        contents: `import \"test\"`,\n        resolveDir: '.',\n      },\n      bundle: true,\n      outfile: output,\n      absWorkingDir: testDir,\n      tsconfigRaw: {\n        compilerOptions: {\n          paths: {\n            test: ['./test-impl.js'],\n          },\n        },\n      },\n      format: 'esm',\n    })\n    const result = await readFileAsync(output, 'utf8')\n    assert.strictEqual(result, `// test-impl.js\nconsole.log(\"success\");\n`)\n  },\n\n  async es5({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const cjs = path.join(testDir, 'cjs.js')\n    const esm = path.join(testDir, 'esm.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `\n      export {foo} from \"./cjs\"\n      export * as bar from \"./esm\"\n    `)\n    await writeFileAsync(cjs, 'exports.foo = 123')\n    await writeFileAsync(esm, 'export var foo = 123')\n    const value = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      target: 'es5',\n    })\n    assert.strictEqual(value.outputFiles, void 0)\n    const result = require(output)\n    assert.strictEqual(result.foo, 123)\n    assert.strictEqual(result.bar.foo, 123)\n    assert.strictEqual(result.__esModule, true)\n    const contents = await readFileAsync(output, 'utf8')\n    assert.strictEqual(contents.indexOf('=>'), -1)\n    assert.strictEqual(contents.indexOf('const'), -1)\n  },\n\n  async outbaseImplicit({ esbuild, testDir }) {\n    const outbase = path.join(testDir, 'pages', 'a')\n    const b = path.join(outbase, 'b', 'index.js')\n    const c = path.join(outbase, 'c', 'index.js')\n    const outdir = path.join(testDir, 'outdir')\n    await mkdirAsync(path.dirname(b), { recursive: true })\n    await mkdirAsync(path.dirname(c), { recursive: true })\n    await writeFileAsync(b, 'module.exports = \"b\"')\n    await writeFileAsync(c, 'module.exports = \"c\"')\n    await esbuild.build({\n      entryPoints: [\n        path.relative(process.cwd(), b),\n        path.relative(process.cwd(), c),\n      ],\n      outdir,\n      format: 'cjs',\n    })\n    const outB = path.join(outdir, path.relative(outbase, b))\n    const outC = path.join(outdir, path.relative(outbase, c))\n    assert.strictEqual(require(outB), 'b')\n    assert.strictEqual(require(outC), 'c')\n  },\n\n  async outbaseRelPath({ esbuild, testDir }) {\n    const outbase = path.join(testDir, 'pages')\n    const b = path.join(outbase, 'a', 'b', 'index.js')\n    const c = path.join(outbase, 'a', 'c', 'index.js')\n    const outdir = path.join(testDir, 'outdir')\n    await mkdirAsync(path.dirname(b), { recursive: true })\n    await mkdirAsync(path.dirname(c), { recursive: true })\n    await writeFileAsync(b, 'module.exports = \"b\"')\n    await writeFileAsync(c, 'module.exports = \"c\"')\n    await esbuild.build({\n      entryPoints: [\n        path.relative(process.cwd(), b),\n        path.relative(process.cwd(), c),\n      ],\n      outdir,\n      outbase,\n      format: 'cjs',\n    })\n    const outB = path.join(outdir, path.relative(outbase, b))\n    const outC = path.join(outdir, path.relative(outbase, c))\n    assert.strictEqual(require(outB), 'b')\n    assert.strictEqual(require(outC), 'c')\n  },\n\n  async outbaseAbsPath({ esbuild, testDir }) {\n    const outbase = path.join(testDir, 'pages')\n    const b = path.join(outbase, 'a', 'b', 'index.js')\n    const c = path.join(outbase, 'a', 'c', 'index.js')\n    const outdir = path.join(testDir, 'outdir')\n    await mkdirAsync(path.dirname(b), { recursive: true })\n    await mkdirAsync(path.dirname(c), { recursive: true })\n    await writeFileAsync(b, 'module.exports = \"b\"')\n    await writeFileAsync(c, 'module.exports = \"c\"')\n    await esbuild.build({\n      entryPoints: [b, c],\n      outdir,\n      outbase,\n      format: 'cjs',\n    })\n    const outB = path.join(outdir, path.relative(outbase, b))\n    const outC = path.join(outdir, path.relative(outbase, c))\n    assert.strictEqual(require(outB), 'b')\n    assert.strictEqual(require(outC), 'c')\n  },\n\n  async bundleTreeShakingDefault({ esbuild }) {\n    const { outputFiles } = await esbuild.build({\n      stdin: {\n        contents: `\n          let removeMe1 = /* @__PURE__ */ fn();\n          let removeMe2 = <div/>;\n        `,\n        loader: 'jsx',\n      },\n      write: false,\n      bundle: true,\n    })\n    assert.strictEqual(outputFiles[0].text, `(() => {\\n})();\\n`)\n  },\n\n  async bundleTreeShakingTrue({ esbuild }) {\n    const { outputFiles } = await esbuild.build({\n      stdin: {\n        contents: `\n          let removeMe1 = /* @__PURE__ */ fn();\n          let removeMe2 = <div/>;\n        `,\n        loader: 'jsx',\n      },\n      write: false,\n      bundle: true,\n      treeShaking: true,\n    })\n    assert.strictEqual(outputFiles[0].text, `(() => {\\n})();\\n`)\n  },\n\n  async bundleTreeShakingIgnoreAnnotations({ esbuild }) {\n    const { outputFiles } = await esbuild.build({\n      stdin: {\n        contents: `\n          let keepMe1 = /* @__PURE__ */ fn();\n          let keepMe2 = <div/>;\n        `,\n        loader: 'jsx',\n      },\n      write: false,\n      bundle: true,\n      ignoreAnnotations: true,\n    })\n    assert.strictEqual(outputFiles[0].text, `(() => {\n  // <stdin>\n  var keepMe1 = fn();\n  var keepMe2 = React.createElement(\"div\", null);\n})();\n`)\n  },\n\n  async externalWithWildcard({ esbuild }) {\n    const { outputFiles } = await esbuild.build({\n      stdin: {\n        contents: `require('/assets/file.png')`,\n      },\n      write: false,\n      bundle: true,\n      external: ['/assets/*.png'],\n      platform: 'node',\n    })\n    assert.strictEqual(outputFiles[0].text, `// <stdin>\nrequire(\"/assets/file.png\");\n`)\n  },\n\n  async externalPackages({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const pkgPath = path.join(testDir, 'node_modules', 'pkg', 'path.js')\n    const dirPath = path.join(testDir, 'dir', 'path.js')\n    await mkdirAsync(path.dirname(pkgPath), { recursive: true })\n    await mkdirAsync(path.dirname(dirPath), { recursive: true })\n    await writeFileAsync(input, `\n      import 'pkg/path.js'\n      import './dir/path.js'\n      import 'before/alias'\n    `)\n    await writeFileAsync(pkgPath, `console.log('pkg')`)\n    await writeFileAsync(dirPath, `console.log('dir')`)\n    const { outputFiles } = await esbuild.build({\n      entryPoints: [input],\n      write: false,\n      bundle: true,\n      packages: 'external',\n      format: 'esm',\n      alias: { 'before': 'after' },\n    })\n    assert.strictEqual(outputFiles[0].text, `// scripts/.js-api-tests/externalPackages/in.js\nimport \"pkg/path.js\";\n\n// scripts/.js-api-tests/externalPackages/dir/path.js\nconsole.log(\"dir\");\n\n// scripts/.js-api-tests/externalPackages/in.js\nimport \"after/alias\";\n`)\n  },\n\n  async errorInvalidExternalWithTwoWildcards({ esbuild }) {\n    try {\n      await esbuild.build({\n        entryPoints: ['in.js'],\n        external: ['a*b*c'],\n        write: false,\n        logLevel: 'silent',\n      })\n      throw new Error('Expected build failure');\n    } catch (e) {\n      if (e.message !== 'Build failed with 1 error:\\nerror: External path \"a*b*c\" cannot have more than one \"*\" wildcard') {\n        throw e;\n      }\n    }\n  },\n\n  async jsBannerBuild({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const outfile = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `if (!bannerDefined) throw 'fail'`)\n    await esbuild.build({\n      entryPoints: [input],\n      outfile,\n      banner: { js: 'const bannerDefined = true' },\n    })\n    require(outfile)\n  },\n\n  async jsFooterBuild({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const outfile = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `footer()`)\n    await esbuild.build({\n      entryPoints: [input],\n      outfile,\n      footer: { js: 'function footer() {}' },\n    })\n    require(outfile)\n  },\n\n  async jsBannerFooterBuild({ esbuild, testDir }) {\n    const aPath = path.join(testDir, 'a.js')\n    const bPath = path.join(testDir, 'b.js')\n    const outdir = path.join(testDir, 'out')\n    await writeFileAsync(aPath, `module.exports = { banner: bannerDefined, footer };`)\n    await writeFileAsync(bPath, `module.exports = { banner: bannerDefined, footer };`)\n    await esbuild.build({\n      entryPoints: [aPath, bPath],\n      outdir,\n      banner: { js: 'const bannerDefined = true' },\n      footer: { js: 'function footer() {}' },\n    })\n    const a = require(path.join(outdir, path.basename(aPath)))\n    const b = require(path.join(outdir, path.basename(bPath)))\n    if (!a.banner || !b.banner) throw 'fail'\n    a.footer()\n    b.footer()\n  },\n\n  async cssBannerFooterBuild({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.css')\n    const outfile = path.join(testDir, 'out.css')\n    await writeFileAsync(input, `div { color: red }`)\n    await esbuild.build({\n      entryPoints: [input],\n      outfile,\n      banner: { css: '/* banner */' },\n      footer: { css: '/* footer */' },\n    })\n    const code = await readFileAsync(outfile, 'utf8')\n    assert.strictEqual(code, `/* banner */\\ndiv {\\n  color: red;\\n}\\n/* footer */\\n`)\n  },\n\n  async buildRelativeIssue693({ esbuild }) {\n    const result = await esbuild.build({\n      stdin: {\n        contents: `const x=1`,\n      },\n      write: false,\n      outfile: 'esbuild.js',\n    });\n    assert.strictEqual(result.outputFiles.length, 1)\n    assert.strictEqual(result.outputFiles[0].path, path.join(process.cwd(), 'esbuild.js'))\n    assert.strictEqual(result.outputFiles[0].text, 'const x = 1;\\n')\n  },\n\n  async rebuildBasic({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const context = await esbuild.context({\n      entryPoints: [input],\n      outfile: output,\n      format: 'esm',\n    });\n\n    // Build 1\n    await writeFileAsync(input, `console.log('abc')`)\n    const result1 = await context.rebuild();\n    assert.strictEqual(result1.outputFiles, void 0)\n    assert.strictEqual(await readFileAsync(output, 'utf8'), `console.log(\"abc\");\\n`)\n\n    // Build 2\n    await writeFileAsync(input, `console.log('xyz')`)\n    const result2 = await context.rebuild();\n    assert.strictEqual(result2.outputFiles, void 0)\n    assert.strictEqual(await readFileAsync(output, 'utf8'), `console.log(\"xyz\");\\n`)\n\n    // Build 3\n    await writeFileAsync(input, `console.log(123)`)\n    const result3 = await context.rebuild();\n    assert.strictEqual(result3.outputFiles, void 0)\n    assert.strictEqual(await readFileAsync(output, 'utf8'), `console.log(123);\\n`)\n\n    // Further rebuilds should not be possible after a dispose\n    context.dispose()\n    try {\n      await context.rebuild()\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert.strictEqual(e.message, 'Cannot rebuild')\n    }\n  },\n\n  async rebuildMerging({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `console.log(123)`)\n\n    let resolveWait\n    let waitPromise = new Promise(resolve => {\n      resolveWait = resolve\n    })\n    const waitPlugin = {\n      name: 'wait-plugin',\n      setup(build) {\n        build.onStart(() => waitPromise)\n      },\n    }\n\n    const context = await esbuild.context({\n      entryPoints: [input],\n      outfile: output,\n      format: 'esm',\n      plugins: [waitPlugin],\n      write: false,\n    });\n\n    try {\n      // Do two rebuilds\n      const rebuild1 = context.rebuild()\n      const rebuild2 = context.rebuild()\n\n      // Let the build end\n      resolveWait()\n\n      // Get both rebuild results\n      const result1 = await rebuild1;\n      const result2 = await rebuild2;\n      assert.strictEqual(result1, result2)\n      assert.strictEqual(result1.outputFiles.length, 1)\n      assert.strictEqual(result1.outputFiles[0].text, 'console.log(123);\\n')\n\n      // Make an edit\n      await writeFileAsync(input, `console.log(234)`)\n\n      // Do two more rebuilds\n      waitPromise = new Promise(resolve => {\n        resolveWait = resolve\n      })\n      const rebuild3 = context.rebuild()\n      const rebuild4 = context.rebuild()\n\n      // Let the build end\n      resolveWait()\n\n      // Get both rebuild results\n      const result3 = await rebuild3;\n      const result4 = await rebuild4;\n      assert.strictEqual(result3, result4)\n      assert.notStrictEqual(result3, result1)\n      assert.strictEqual(result3.outputFiles.length, 1)\n      assert.strictEqual(result3.outputFiles[0].text, 'console.log(234);\\n')\n    } finally {\n      await context.dispose()\n    }\n  },\n\n  async rebuildIndependent({ esbuild, testDir }) {\n    const inputA = path.join(testDir, 'in-a.js')\n    const inputB = path.join(testDir, 'in-b.js')\n    const outputA = path.join(testDir, 'out-a.js')\n    const outputB = path.join(testDir, 'out-b.js')\n    const contextA = await esbuild.context({\n      entryPoints: [inputA],\n      outfile: outputA,\n      format: 'esm',\n    })\n    const contextB = await esbuild.context({\n      entryPoints: [inputB],\n      outfile: outputB,\n      format: 'esm',\n    })\n\n    // Build 1\n    await writeFileAsync(inputA, `console.log('a')`)\n    await writeFileAsync(inputB, `console.log('b')`)\n    assert.notStrictEqual(contextA.rebuild, contextB.rebuild)\n    const resultA1 = await contextA.rebuild()\n    const resultB1 = await contextB.rebuild()\n    assert.strictEqual(resultA1.outputFiles, void 0)\n    assert.strictEqual(resultB1.outputFiles, void 0)\n    assert.strictEqual(await readFileAsync(outputA, 'utf8'), `console.log(\"a\");\\n`)\n    assert.strictEqual(await readFileAsync(outputB, 'utf8'), `console.log(\"b\");\\n`)\n\n    // Build 2\n    await writeFileAsync(inputA, `console.log(1)`)\n    await writeFileAsync(inputB, `console.log(2)`)\n    const promiseA = contextA.rebuild();\n    const promiseB = contextB.rebuild();\n    const resultA2 = await promiseA;\n    const resultB2 = await promiseB;\n    assert.strictEqual(resultA2.outputFiles, void 0)\n    assert.strictEqual(resultB2.outputFiles, void 0)\n    assert.strictEqual(await readFileAsync(outputA, 'utf8'), `console.log(1);\\n`)\n    assert.strictEqual(await readFileAsync(outputB, 'utf8'), `console.log(2);\\n`)\n\n    // Further rebuilds should not be possible after a dispose\n    contextA.dispose()\n    try {\n      await contextA.rebuild()\n      throw new Error('Expected an error to be thrown (context A)')\n    } catch (e) {\n      assert.strictEqual(e.message, 'Cannot rebuild')\n    }\n\n    // Build 3\n    await writeFileAsync(inputB, `console.log(3)`)\n    const resultB3 = await contextB.rebuild()\n    assert.strictEqual(resultB3.outputFiles, void 0)\n    assert.strictEqual(await readFileAsync(outputB, 'utf8'), `console.log(3);\\n`)\n\n    // Further rebuilds should not be possible after a dispose\n    contextB.dispose()\n    try {\n      await contextB.rebuild()\n      throw new Error('Expected an error to be thrown (context B)')\n    } catch (e) {\n      assert.strictEqual(e.message, 'Cannot rebuild')\n    }\n  },\n\n  async rebuildParallel({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const context = await esbuild.context({\n      entryPoints: [input],\n      outfile: output,\n      format: 'esm',\n    })\n\n    try {\n      // Build 1\n      await writeFileAsync(input, `console.log('abc')`)\n      const result1 = await context.rebuild()\n      assert.strictEqual(result1.outputFiles, void 0)\n      assert.strictEqual(await readFileAsync(output, 'utf8'), `console.log(\"abc\");\\n`)\n\n      // Build 2\n      await writeFileAsync(input, `console.log('xyz')`)\n      const promise2A = context.rebuild();\n      const promise2B = context.rebuild();\n      const result2A = await promise2A;\n      const result2B = await promise2B;\n      assert.strictEqual(result2A.outputFiles, void 0)\n      assert.strictEqual(result2B.outputFiles, void 0)\n      assert.strictEqual(await readFileAsync(output, 'utf8'), `console.log(\"xyz\");\\n`)\n\n      // Build 3\n      await writeFileAsync(input, `console.log(123)`)\n      const promise3A = context.rebuild();\n      const promise3B = context.rebuild();\n      const result3A = await promise3A;\n      const result3B = await promise3B;\n      assert.strictEqual(result3A.outputFiles, void 0)\n      assert.strictEqual(result3B.outputFiles, void 0)\n      assert.strictEqual(await readFileAsync(output, 'utf8'), `console.log(123);\\n`)\n    } finally {\n      context.dispose()\n    }\n\n    // Further rebuilds should not be possible after a dispose\n    try {\n      await context.rebuild()\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert.strictEqual(e.message, 'Cannot rebuild')\n    }\n  },\n\n  async rebuildCancel({ esbuild }) {\n    let loopForever = true\n    let onEndResult\n    let onLoadCallback\n\n    const context = await esbuild.context({\n      entryPoints: ['entry'],\n      bundle: true,\n      write: false,\n      logLevel: 'silent',\n      format: 'esm',\n      plugins: [{\n        name: '∞',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => {\n            return { path: args.path, namespace: '∞' }\n          })\n          build.onLoad({ filter: /.*/ }, async (args) => {\n            onLoadCallback()\n            if (!loopForever) return { contents: 'foo()' }\n            await new Promise(r => setTimeout(r, 10))\n            return { contents: 'import ' + JSON.stringify(args.path + '.') }\n          })\n          build.onEnd(result => {\n            onEndResult = result\n          })\n        },\n      }],\n    })\n\n    try {\n      // Build 1\n      {\n        // Stop the build when \"onLoad\" has been called at least 5 times\n        const shouldCancelPromise = new Promise(resolve => {\n          let count = 0\n          onLoadCallback = () => {\n            if (++count > 5) resolve()\n          }\n        })\n\n        // Start a build\n        const buildPromise = context.rebuild()\n\n        // Add a dummy catch handler to avoid terminating due to an unhandled exception\n        buildPromise.catch(() => { })\n\n        // Cancel the build\n        await shouldCancelPromise\n        await context.cancel()\n\n        // Check the result\n        try {\n          await buildPromise\n          throw new Error('Expected an error to be thrown')\n        } catch (error) {\n          assert.strictEqual(error.message, `Build failed with 1 error:\\nerror: The build was canceled`)\n          assert.strictEqual(error.errors.length, 1)\n          assert.strictEqual(error.warnings.length, 0)\n          assert.notStrictEqual(onEndResult, undefined)\n          assert.strictEqual(onEndResult.errors.length, 1)\n          assert.strictEqual(onEndResult.errors[0].text, 'The build was canceled')\n          assert.strictEqual(onEndResult.warnings.length, 0)\n          assert.strictEqual(onEndResult.outputFiles.length, 0)\n        }\n      }\n\n      // Build 2\n      {\n        // Stop the build when \"onLoad\" has been called at least 5 times\n        const shouldCancelPromise = new Promise(resolve => {\n          let count = 0\n          onLoadCallback = () => {\n            if (++count > 5) resolve()\n          }\n        })\n\n        // Start a build\n        const buildPromise = context.rebuild()\n\n        // Add a dummy catch handler to avoid terminating due to an unhandled exception\n        buildPromise.catch(() => { })\n\n        // Cancel the build\n        await shouldCancelPromise\n        await context.cancel()\n\n        // Check the result\n        try {\n          await buildPromise\n          throw new Error('Expected an error to be thrown')\n        } catch (error) {\n          assert.strictEqual(error.message, `Build failed with 1 error:\\nerror: The build was canceled`)\n          assert.strictEqual(error.errors.length, 1)\n          assert.strictEqual(error.warnings.length, 0)\n          assert.notStrictEqual(onEndResult, undefined)\n          assert.strictEqual(onEndResult.errors.length, 1)\n          assert.strictEqual(onEndResult.errors[0].text, 'The build was canceled')\n          assert.strictEqual(onEndResult.warnings.length, 0)\n          assert.strictEqual(onEndResult.outputFiles.length, 0)\n        }\n      }\n\n      // Build 3\n      loopForever = false\n      {\n        const result = await context.rebuild()\n        assert.strictEqual(result.errors.length, 0)\n        assert.strictEqual(result.warnings.length, 0)\n        assert.strictEqual(result.outputFiles.length, 1)\n        assert.strictEqual(result.outputFiles[0].text, `// ∞:entry\\nfoo();\\n`)\n        assert.strictEqual(onEndResult, result)\n      }\n    } finally {\n      context.dispose()\n    }\n  },\n\n  // This test checks for races between manual \"rebuild()\" and \"cancel()\".\n  // Ideally calling \"cancel()\" after \"rebuild()\" will always cancel it even\n  // if the Go side hasn't started running the rebuild yet. Since Go is multi-\n  // threaded, Go can actually start running the \"cancel()\" before the\n  // \"rebuild()\" (i.e. in the other order). The Go code does some complex stuff\n  // with mutexes to try to make this ideal behavior happen despite multi-\n  // threading.\n  async rapidRebuildCancel({ esbuild }) {\n    const context = await esbuild.context({\n      entryPoints: ['entry'],\n      logLevel: 'silent',\n      plugins: [{\n        name: '∞',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => {\n            return { path: args.path, namespace: '∞' }\n          })\n          build.onLoad({ filter: /.*/ }, async (args) => {\n            await new Promise(r => setTimeout(r, 10))\n            return { contents: 'import ' + JSON.stringify(args.path + '.') }\n          })\n        },\n      }],\n    })\n\n    try {\n      const promises = []\n      for (let i = 0; i < 100; i++) {\n        const promise = context.rebuild()\n        promise.catch(() => { /* avoid termination due to an uncaught exception */ })\n        promises.push(promise)\n        await context.cancel()\n      }\n\n      for (let i = 0; i < promises.length; i++) {\n        try {\n          await promises[i]\n          throw new Error('Expected an error to be thrown for rebuild ' + i)\n        } catch (err) {\n          if (!err.errors || err.errors.length !== 1 || err.errors[0].text !== 'The build was canceled')\n            throw err\n        }\n      }\n    } finally {\n      context.dispose()\n    }\n  },\n\n  async bundleAvoidTDZ({ esbuild }) {\n    var { outputFiles } = await esbuild.build({\n      stdin: {\n        contents: `\n          class Foo {\n            // The above line will be transformed into \"var\". However, the\n            // symbol \"Foo\" must still be defined before the class body ends.\n            static foo = new Foo\n          }\n          if (!(Foo.foo instanceof Foo))\n            throw 'fail'\n        `,\n      },\n      bundle: true,\n      write: false,\n    })\n    assert.strictEqual(outputFiles.length, 1)\n    new Function(outputFiles[0].text)()\n  },\n\n  async bundleTSAvoidTDZ({ esbuild }) {\n    var { outputFiles } = await esbuild.build({\n      stdin: {\n        contents: `\n          class Foo {\n            // The above line will be transformed into \"var\". However, the\n            // symbol \"Foo\" must still be defined before the class body ends.\n            static foo = new Foo\n          }\n          if (!(Foo.foo instanceof Foo))\n            throw 'fail'\n        `,\n        loader: 'ts',\n      },\n      bundle: true,\n      write: false,\n    })\n    assert.strictEqual(outputFiles.length, 1)\n    new Function(outputFiles[0].text)()\n  },\n\n  async bundleTSDecoratorAvoidTDZ({ testDir, esbuild }) {\n    const input = path.join(testDir, 'input.ts')\n    await writeFileAsync(input, `\n      class Bar {}\n      var oldFoo\n      function swap(target) {\n        oldFoo = target\n        return Bar\n      }\n      @swap\n      class Foo {\n        bar() { return new Foo }\n        static foo = new Foo\n      }\n      if (!(oldFoo.foo instanceof oldFoo))\n        throw 'fail: foo'\n      if (!(oldFoo.foo.bar() instanceof Bar))\n        throw 'fail: bar'\n    `)\n    await writeFileAsync(path.join(testDir, 'tsconfig.json'), `{\n      \"compilerOptions\": {\n        \"experimentalDecorators\": true,\n      },\n    }`)\n    var { outputFiles } = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      write: false,\n    })\n    assert.strictEqual(outputFiles.length, 1)\n    new Function(outputFiles[0].text)()\n  },\n\n  async automaticEntryPointOutputPathsWithDot({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.file.ts')\n    const css = path.join(testDir, 'file.css')\n    await writeFileAsync(input, `import './file.css'; console.log('test')`)\n    await writeFileAsync(css, `body { color: red }`)\n    var { outputFiles } = await esbuild.build({\n      entryPoints: [input],\n      outdir: testDir,\n      bundle: true,\n      write: false,\n    })\n    assert.strictEqual(outputFiles.length, 2)\n    assert.strictEqual(outputFiles[0].path, path.join(testDir, 'in.file.js'))\n    assert.strictEqual(outputFiles[1].path, path.join(testDir, 'in.file.css'))\n  },\n\n  async customEntryPointOutputPathsWithDot({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.file.ts')\n    const css = path.join(testDir, 'file.css')\n    await writeFileAsync(input, `import './file.css'; console.log('test')`)\n    await writeFileAsync(css, `body { color: red }`)\n    var { outputFiles } = await esbuild.build({\n      entryPoints: {\n        'out.test': input,\n      },\n      outdir: testDir,\n      bundle: true,\n      write: false,\n    })\n    assert.strictEqual(outputFiles.length, 2)\n    assert.strictEqual(outputFiles[0].path, path.join(testDir, 'out.test.js'))\n    assert.strictEqual(outputFiles[1].path, path.join(testDir, 'out.test.css'))\n  },\n\n  async customEntryPointOutputPathsRel({ esbuild, testDir }) {\n    const input1 = path.join(testDir, 'in1.js')\n    const input2 = path.join(testDir, 'in2.js')\n    const output1 = 'out/1.cjs'\n    const output2 = 'out/2.mjs'\n    await writeFileAsync(input1, `console.log('in1')`)\n    await writeFileAsync(input2, `console.log('in2')`)\n    var { outputFiles } = await esbuild.build({\n      entryPoints: {\n        [output1]: input1,\n        [output2]: input2,\n      },\n      entryNames: 'entry/[dir]/[hash]-[name]',\n      outdir: testDir,\n      write: false,\n    })\n    assert.strictEqual(outputFiles.length, 2)\n    assert.strictEqual(outputFiles[0].path, path.join(testDir, 'entry', 'out', 'CXHWNMAN-1.cjs.js'))\n    assert.strictEqual(outputFiles[1].path, path.join(testDir, 'entry', 'out', 'EYSNILNO-2.mjs.js'))\n  },\n\n  async customEntryPointOutputPathsAbs({ esbuild, testDir }) {\n    const input1 = path.join(testDir, 'in1.js')\n    const input2 = path.join(testDir, 'in2.js')\n    const output1 = path.join(testDir, 'out/1')\n    const output2 = path.join(testDir, 'out/2')\n    await writeFileAsync(input1, `console.log('in1')`)\n    await writeFileAsync(input2, `console.log('in2')`)\n    var { outputFiles } = await esbuild.build({\n      entryPoints: {\n        [output1]: input1,\n        [output2]: input2,\n      },\n      entryNames: 'entry/[dir]/[hash]-[name]',\n      outdir: testDir,\n      write: false,\n    })\n    assert.strictEqual(outputFiles.length, 2)\n    assert.strictEqual(outputFiles[0].path, path.join(testDir, 'entry', 'out', 'TIORPBNU-1.js'))\n    assert.strictEqual(outputFiles[1].path, path.join(testDir, 'entry', 'out', '3KY7NOSR-2.js'))\n  },\n\n  async customEntryPointOutputPathsDuplicates({ esbuild, testDir }) {\n    const input1 = path.join(testDir, 'foo.js')\n    const input2 = path.join(testDir, 'bar.css')\n    await writeFileAsync(input1, `foo()`)\n    await writeFileAsync(input2, `.bar {}`)\n    var { outputFiles } = await esbuild.build({\n      entryPoints: [\n        { in: input1, out: 'abc' },\n        { in: input2, out: 'abc' },\n      ],\n      outdir: testDir,\n      write: false,\n    })\n    assert.strictEqual(outputFiles.length, 2)\n    assert.strictEqual(outputFiles[0].path, path.join(testDir, 'abc.js'))\n    assert.strictEqual(outputFiles[1].path, path.join(testDir, 'abc.css'))\n  },\n\n  async nodeColonPrefixImport({ esbuild }) {\n    const tryTargetESM = async target => {\n      const result = await esbuild.build({\n        stdin: { contents: `import fs from 'node:fs'; import('node:fs'); fs()` },\n        bundle: true,\n        platform: 'node',\n        target: target.split(','),\n        format: 'esm',\n        write: false,\n      })\n      const code = result.outputFiles[0].text\n      return code.slice(code.indexOf(`// <stdin>\\n`))\n    }\n\n    assert.strictEqual(await tryTargetESM('node14.13.1'), `// <stdin>\\nimport fs from \"node:fs\";\\nimport(\"node:fs\");\\nfs();\\n`)\n    assert.strictEqual(await tryTargetESM('node14.13.0'), `// <stdin>\\nimport fs from \"fs\";\\nimport(\"fs\");\\nfs();\\n`)\n    assert.strictEqual(await tryTargetESM('node13'), `// <stdin>\\nimport fs from \"fs\";\\nPromise.resolve().then(() => __toESM(__require(\"fs\")));\\nfs();\\n`)\n    assert.strictEqual(await tryTargetESM('node12.99'), `// <stdin>\\nimport fs from \"node:fs\";\\nimport(\"node:fs\");\\nfs();\\n`)\n    assert.strictEqual(await tryTargetESM('node12.20'), `// <stdin>\\nimport fs from \"node:fs\";\\nimport(\"node:fs\");\\nfs();\\n`)\n    assert.strictEqual(await tryTargetESM('node12.19'), `// <stdin>\\nimport fs from \"fs\";\\nPromise.resolve().then(() => __toESM(__require(\"fs\")));\\nfs();\\n`)\n    assert.strictEqual(await tryTargetESM('node18,es6'), `// <stdin>\\nimport fs from \"node:fs\";\\nimport(\"node:fs\");\\nfs();\\n`)\n  },\n\n  async nodeColonPrefixRequire({ esbuild }) {\n    const tryTargetESM = async target => {\n      const result = await esbuild.build({\n        stdin: { contents: `require('node:fs'); require.resolve('node:fs')` },\n        bundle: true,\n        platform: 'node',\n        target: target.split(','),\n        format: 'cjs',\n        write: false,\n      })\n      const code = result.outputFiles[0].text\n      return code.slice(code.indexOf(`// <stdin>\\n`))\n    }\n\n    assert.strictEqual(await tryTargetESM('node16'), `// <stdin>\\nrequire(\"node:fs\");\\nrequire.resolve(\"node:fs\");\\n`)\n    assert.strictEqual(await tryTargetESM('node15.99'), `// <stdin>\\nrequire(\"fs\");\\nrequire.resolve(\"fs\");\\n`)\n    assert.strictEqual(await tryTargetESM('node15'), `// <stdin>\\nrequire(\"fs\");\\nrequire.resolve(\"fs\");\\n`)\n    assert.strictEqual(await tryTargetESM('node14.99'), `// <stdin>\\nrequire(\"node:fs\");\\nrequire.resolve(\"node:fs\");\\n`)\n    assert.strictEqual(await tryTargetESM('node14.18'), `// <stdin>\\nrequire(\"node:fs\");\\nrequire.resolve(\"node:fs\");\\n`)\n    assert.strictEqual(await tryTargetESM('node14.17'), `// <stdin>\\nrequire(\"fs\");\\nrequire.resolve(\"fs\");\\n`)\n    assert.strictEqual(await tryTargetESM('node18,es6'), `// <stdin>\\nrequire(\"node:fs\");\\nrequire.resolve(\"node:fs\");\\n`)\n  },\n\n  async nodeColonPrefixImportTurnedIntoRequire({ esbuild }) {\n    const tryTargetESM = async target => {\n      const result = await esbuild.build({\n        stdin: { contents: `import fs from 'node:fs'; import('node:fs'); fs()` },\n        bundle: true,\n        platform: 'node',\n        target: target.split(','),\n        format: 'cjs',\n        write: false,\n      })\n      const code = result.outputFiles[0].text\n      return code.slice(code.indexOf(`// <stdin>\\n`))\n    }\n\n    assert.strictEqual(await tryTargetESM('node16'), `// <stdin>\\nvar import_node_fs = __toESM(require(\"node:fs\"));\\nimport(\"node:fs\");\\n(0, import_node_fs.default)();\\n`)\n    assert.strictEqual(await tryTargetESM('node15.99'), `// <stdin>\\nvar import_node_fs = __toESM(require(\"fs\"));\\nimport(\"fs\");\\n(0, import_node_fs.default)();\\n`)\n    assert.strictEqual(await tryTargetESM('node15'), `// <stdin>\\nvar import_node_fs = __toESM(require(\"fs\"));\\nimport(\"fs\");\\n(0, import_node_fs.default)();\\n`)\n    assert.strictEqual(await tryTargetESM('node14.99'), `// <stdin>\\nvar import_node_fs = __toESM(require(\"node:fs\"));\\nimport(\"node:fs\");\\n(0, import_node_fs.default)();\\n`)\n    assert.strictEqual(await tryTargetESM('node14.18'), `// <stdin>\\nvar import_node_fs = __toESM(require(\"node:fs\"));\\nimport(\"node:fs\");\\n(0, import_node_fs.default)();\\n`)\n    assert.strictEqual(await tryTargetESM('node14.17'), `// <stdin>\\nvar import_node_fs = __toESM(require(\"fs\"));\\nimport(\"fs\");\\n(0, import_node_fs.default)();\\n`)\n    assert.strictEqual(await tryTargetESM('node18,es6'), `// <stdin>\\nvar import_node_fs = __toESM(require(\"node:fs\"));\\nimport(\"node:fs\");\\n(0, import_node_fs.default)();\\n`)\n  },\n\n  async zipFile({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const zip = path.join(testDir, 'test.zip')\n\n    await writeFileAsync(entry, `\n      import foo from './test.zip/foo.js'\n      import bar from './test.zip/bar/bar.js'\n\n      import __virtual__1 from './test.zip/__virtual__/ignored/0/foo.js'\n      import __virtual__2 from './test.zip/ignored/__virtual__/ignored/1/foo.js'\n      import __virtual__3 from './test.zip/__virtual__/ignored/1/test.zip/foo.js'\n\n      import $$virtual1 from './test.zip/$$virtual/ignored/0/foo.js'\n      import $$virtual2 from './test.zip/ignored/$$virtual/ignored/1/foo.js'\n      import $$virtual3 from './test.zip/$$virtual/ignored/1/test.zip/foo.js'\n\n      console.log({\n        foo,\n        bar,\n\n        __virtual__1,\n        __virtual__2,\n        __virtual__3,\n\n        $$virtual1,\n        $$virtual2,\n        $$virtual3,\n      })\n    `)\n\n    // This uses the real file system instead of the mock file system so that\n    // we can check that everything works as expected on Windows, which is not\n    // a POSIX environment.\n    await writeFileAsync(zip, Buffer.from(\n      `UEsDBAoAAgAAAG1qCFUSAXosFQAAABUAAAAGABwAZm9vLmpzVVQJAAOeRfFioEXxYnV4C` +\n      `wABBPUBAAAEFAAAAGV4cG9ydCBkZWZhdWx0ICdmb28nClBLAwQKAAIAAABzaghVwuDbLR` +\n      `UAAAAVAAAACgAcAGJhci9iYXIuanNVVAkAA6lF8WKrRfFidXgLAAEE9QEAAAQUAAAAZXh` +\n      `wb3J0IGRlZmF1bHQgJ2JhcicKUEsBAh4DCgACAAAAbWoIVRIBeiwVAAAAFQAAAAYAGAAA` +\n      `AAAAAQAAAKSBAAAAAGZvby5qc1VUBQADnkXxYnV4CwABBPUBAAAEFAAAAFBLAQIeAwoAA` +\n      `gAAAHNqCFXC4NstFQAAABUAAAAKABgAAAAAAAEAAACkgVUAAABiYXIvYmFyLmpzVVQFAA` +\n      `OpRfFidXgLAAEE9QEAAAQUAAAAUEsFBgAAAAACAAIAnAAAAK4AAAAAAA==`, 'base64'))\n\n    const value = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      write: false,\n    })\n\n    assert.strictEqual(value.outputFiles.length, 1)\n    assert.strictEqual(value.outputFiles[0].text, `(() => {\n  // scripts/.js-api-tests/zipFile/test.zip/foo.js\n  var foo_default = \"foo\";\n\n  // scripts/.js-api-tests/zipFile/test.zip/bar/bar.js\n  var bar_default = \"bar\";\n\n  // scripts/.js-api-tests/zipFile/test.zip/__virtual__/ignored/0/foo.js\n  var foo_default2 = \"foo\";\n\n  // scripts/.js-api-tests/zipFile/test.zip/ignored/__virtual__/ignored/1/foo.js\n  var foo_default3 = \"foo\";\n\n  // scripts/.js-api-tests/zipFile/test.zip/__virtual__/ignored/1/test.zip/foo.js\n  var foo_default4 = \"foo\";\n\n  // scripts/.js-api-tests/zipFile/test.zip/$$virtual/ignored/0/foo.js\n  var foo_default5 = \"foo\";\n\n  // scripts/.js-api-tests/zipFile/test.zip/ignored/$$virtual/ignored/1/foo.js\n  var foo_default6 = \"foo\";\n\n  // scripts/.js-api-tests/zipFile/test.zip/$$virtual/ignored/1/test.zip/foo.js\n  var foo_default7 = \"foo\";\n\n  // scripts/.js-api-tests/zipFile/entry.js\n  console.log({\n    foo: foo_default,\n    bar: bar_default,\n    __virtual__1: foo_default2,\n    __virtual__2: foo_default3,\n    __virtual__3: foo_default4,\n    $$virtual1: foo_default5,\n    $$virtual2: foo_default6,\n    $$virtual3: foo_default7\n  });\n})();\n`)\n  },\n\n  async yarnPnP_pnp_data_json({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const manifest = path.join(testDir, '.pnp.data.json')\n    const leftPad = path.join(testDir, '.yarn', 'cache', 'left-pad-zip', 'node_modules', 'left-pad', 'index.js')\n\n    await writeFileAsync(entry, `\n      import leftPad from 'left-pad'\n      console.log(leftPad())\n    `)\n\n    await writeFileAsync(manifest, `{\n      \"packageRegistryData\": [\n        [null, [\n          [null, {\n            \"packageLocation\": \"./\",\n            \"packageDependencies\": [\n              [\"left-pad\", \"npm:1.3.0\"]\n            ],\n            \"linkType\": \"SOFT\"\n          }]\n        ]],\n        [\"left-pad\", [\n          [\"npm:1.3.0\", {\n            \"packageLocation\": \"./.yarn/cache/left-pad-zip/node_modules/left-pad/\",\n            \"packageDependencies\": [\n              [\"left-pad\", \"npm:1.3.0\"]\n            ],\n            \"linkType\": \"HARD\"\n          }]\n        ]]\n      ]\n    }`)\n\n    await mkdirAsync(path.dirname(leftPad), { recursive: true })\n    await writeFileAsync(leftPad, `export default function() {}`)\n\n    const value = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      write: false,\n      absWorkingDir: testDir,\n    })\n\n    assert.strictEqual(value.outputFiles.length, 1)\n    assert.strictEqual(value.outputFiles[0].text, `(() => {\n  // .yarn/cache/left-pad-zip/node_modules/left-pad/index.js\n  function left_pad_default() {\n  }\n\n  // entry.js\n  console.log(left_pad_default());\n})();\n`)\n  },\n\n  async yarnPnP_pnp_js_object_literal({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const manifest = path.join(testDir, '.pnp.js')\n    const leftPad = path.join(testDir, '.yarn', 'cache', 'left-pad-zip', 'node_modules', 'left-pad', 'index.js')\n\n    await writeFileAsync(entry, `\n      import leftPad from 'left-pad'\n      console.log(leftPad())\n    `)\n\n    await writeFileAsync(manifest, `#!/usr/bin/env node\n      /* eslint-disable */\n\n      try {\n        Object.freeze({}).detectStrictMode = true;\n      } catch (error) {\n        throw new Error();\n      }\n\n      function $$SETUP_STATE(hydrateRuntimeState, basePath) {\n        return hydrateRuntimeState({\n          \"packageRegistryData\": [\n            [null, [\n              [null, {\n                \"packageLocation\": \"./\",\n                \"packageDependencies\": [\n                  [\"left-pad\", \"npm:1.3.0\"]\n                ],\n                \"linkType\": \"SOFT\"\n              }]\n            ]],\n            [\"left-pad\", [\n              [\"npm:1.3.0\", {\n                \"packageLocation\": \"./.yarn/cache/left-pad-zip/node_modules/left-pad/\",\n                \"packageDependencies\": [\n                  [\"left-pad\", \"npm:1.3.0\"]\n                ],\n                \"linkType\": \"HARD\"\n              }]\n            ]]\n          ]\n        })\n      }\n    `)\n\n    await mkdirAsync(path.dirname(leftPad), { recursive: true })\n    await writeFileAsync(leftPad, `export default function() {}`)\n\n    const value = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      write: false,\n      absWorkingDir: testDir,\n    })\n\n    assert.strictEqual(value.outputFiles.length, 1)\n    assert.strictEqual(value.outputFiles[0].text, `(() => {\n  // .yarn/cache/left-pad-zip/node_modules/left-pad/index.js\n  function left_pad_default() {\n  }\n\n  // entry.js\n  console.log(left_pad_default());\n})();\n`)\n  },\n\n  async yarnPnP_pnp_cjs_JSON_parse_string_literal({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const manifest = path.join(testDir, '.pnp.cjs')\n    const leftPad = path.join(testDir, '.yarn', 'cache', 'left-pad-zip', 'node_modules', 'left-pad', 'index.js')\n\n    await writeFileAsync(entry, `\n      import leftPad from 'left-pad'\n      console.log(leftPad())\n    `)\n\n    await writeFileAsync(manifest, `#!/usr/bin/env node\n      /* eslint-disable */\n\n      try {\n        Object.freeze({}).detectStrictMode = true;\n      } catch (error) {\n        throw new Error();\n      }\n\n      function $$SETUP_STATE(hydrateRuntimeState, basePath) {\n        return hydrateRuntimeState(JSON.parse('{\\\\\n          \"packageRegistryData\": [\\\\\n            [null, [\\\\\n              [null, {\\\\\n                \"packageLocation\": \"./\",\\\\\n                \"packageDependencies\": [\\\\\n                  [\"left-pad\", \"npm:1.3.0\"]\\\\\n                ],\\\\\n                \"linkType\": \"SOFT\"\\\\\n              }]\\\\\n            ]],\\\\\n            [\"left-pad\", [\\\\\n              [\"npm:1.3.0\", {\\\\\n                \"packageLocation\": \"./.yarn/cache/left-pad-zip/node_modules/left-pad/\",\\\\\n                \"packageDependencies\": [\\\\\n                  [\"left-pad\", \"npm:1.3.0\"]\\\\\n                ],\\\\\n                \"linkType\": \"HARD\"\\\\\n              }]\\\\\n            ]]\\\\\n          ]\\\\\n        }'))\n      }\n    `)\n\n    await mkdirAsync(path.dirname(leftPad), { recursive: true })\n    await writeFileAsync(leftPad, `export default function() {}`)\n\n    const value = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      write: false,\n      absWorkingDir: testDir,\n    })\n\n    assert.strictEqual(value.outputFiles.length, 1)\n    assert.strictEqual(value.outputFiles[0].text, `(() => {\n  // .yarn/cache/left-pad-zip/node_modules/left-pad/index.js\n  function left_pad_default() {\n  }\n\n  // entry.js\n  console.log(left_pad_default());\n})();\n`)\n  },\n\n  async yarnPnP_pnp_cjs_JSON_parse_identifier({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const manifest = path.join(testDir, '.pnp.cjs')\n    const leftPad = path.join(testDir, '.yarn', 'cache', 'left-pad-zip', 'node_modules', 'left-pad', 'index.js')\n\n    await writeFileAsync(entry, `\n      import leftPad from 'left-pad'\n      console.log(leftPad())\n    `)\n\n    await writeFileAsync(manifest, `#!/usr/bin/env node\n      /* eslint-disable */\n\n      try {\n        Object.freeze({}).detectStrictMode = true;\n      } catch (error) {\n        throw new Error();\n      }\n\n      const RAW_RUNTIME_STATE = '{\\\\\n        \"packageRegistryData\": [\\\\\n          [null, [\\\\\n            [null, {\\\\\n              \"packageLocation\": \"./\",\\\\\n              \"packageDependencies\": [\\\\\n                [\"left-pad\", \"npm:1.3.0\"]\\\\\n              ],\\\\\n              \"linkType\": \"SOFT\"\\\\\n            }]\\\\\n          ]],\\\\\n          [\"left-pad\", [\\\\\n            [\"npm:1.3.0\", {\\\\\n              \"packageLocation\": \"./.yarn/cache/left-pad-zip/node_modules/left-pad/\",\\\\\n              \"packageDependencies\": [\\\\\n                [\"left-pad\", \"npm:1.3.0\"]\\\\\n              ],\\\\\n              \"linkType\": \"HARD\"\\\\\n            }]\\\\\n          ]]\\\\\n        ]\\\\\n      }'\n\n      function $$SETUP_STATE(hydrateRuntimeState, basePath) {\n        return hydrateRuntimeState(JSON.parse(RAW_RUNTIME_STATE))\n      }\n    `)\n\n    await mkdirAsync(path.dirname(leftPad), { recursive: true })\n    await writeFileAsync(leftPad, `export default function() {}`)\n\n    const value = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      write: false,\n      absWorkingDir: testDir,\n    })\n\n    assert.strictEqual(value.outputFiles.length, 1)\n    assert.strictEqual(value.outputFiles[0].text, `(() => {\n  // .yarn/cache/left-pad-zip/node_modules/left-pad/index.js\n  function left_pad_default() {\n  }\n\n  // entry.js\n  console.log(left_pad_default());\n})();\n`)\n  },\n\n  async yarnPnP_ignoreNestedManifests({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const foo = path.join(testDir, 'node_modules', 'foo', 'index.js')\n    const bar = path.join(testDir, 'node_modules', 'bar', 'index.js')\n    const manifest = path.join(testDir, '.pnp.data.json')\n\n    await writeFileAsync(entry, `\n      import foo from 'foo'\n      console.log(foo)\n    `)\n\n    await mkdirAsync(path.dirname(foo), { recursive: true })\n    await writeFileAsync(foo, `\n      import bar from 'bar'\n      export default 'foo' + bar\n    `)\n\n    await mkdirAsync(path.dirname(bar), { recursive: true })\n    await writeFileAsync(bar, `\n      export default 'bar'\n    `)\n\n    await writeFileAsync(manifest, `{\n      \"packageRegistryData\": [\n        [null, [\n          [null, {\n            \"packageLocation\": \"./\",\n            \"packageDependencies\": [\n              [\"foo\", \"npm:1.0.0\"],\n              [\"bar\", \"npm:1.0.0\"]\n            ],\n            \"linkType\": \"SOFT\"\n          }]\n        ]],\n        [\"foo\", [\n          [\"npm:1.0.0\", {\n            \"packageLocation\": \"./__virtual__/whatever/0/node_modules/foo/\",\n            \"packageDependencies\": [\n              [\"bar\", \"npm:1.0.0\"]\n            ],\n            \"linkType\": \"HARD\"\n          }]\n        ]],\n        [\"bar\", [\n          [\"npm:1.0.0\", {\n            \"packageLocation\": \"./__virtual__/whatever/0/node_modules/bar/\",\n            \"packageDependencies\": [],\n            \"linkType\": \"HARD\"\n          }]\n        ]]\n      ]\n    }`)\n\n    const value = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      write: false,\n      absWorkingDir: testDir,\n    })\n\n    assert.strictEqual(value.outputFiles.length, 1)\n    assert.strictEqual(value.outputFiles[0].text, `(() => {\n  // __virtual__/whatever/0/node_modules/bar/index.js\n  var bar_default = \"bar\";\n\n  // __virtual__/whatever/0/node_modules/foo/index.js\n  var foo_default = \"foo\" + bar_default;\n\n  // entry.js\n  console.log(foo_default);\n})();\n`)\n  },\n\n  async yarnPnP_tsconfig({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.jsx')\n    const tsconfigExtends = path.join(testDir, 'tsconfig.json')\n    const tsconfigBase = path.join(testDir, 'foo', 'tsconfig.json')\n    const manifest = path.join(testDir, '.pnp.data.json')\n\n    await writeFileAsync(entry, `\n      console.log(<div/>)\n    `)\n\n    await writeFileAsync(tsconfigExtends, `{\n      \"extends\": \"@scope/base/tsconfig.json\",\n    }`)\n\n    await mkdirAsync(path.dirname(tsconfigBase), { recursive: true })\n    await writeFileAsync(tsconfigBase, `{\n      \"compilerOptions\": {\n        \"jsxFactory\": \"success\"\n      }\n    }`)\n\n    await writeFileAsync(manifest, `{\n      \"packageRegistryData\": [\n        [null, [\n          [null, {\n            \"packageLocation\": \"./\",\n            \"packageDependencies\": [\n              [\"@scope/base\", \"npm:1.0.0\"]\n            ],\n            \"linkType\": \"SOFT\"\n          }]\n        ]],\n        [\"@scope/base\", [\n          [\"npm:1.0.0\", {\n            \"packageLocation\": \"./foo/\",\n            \"packageDependencies\": [],\n            \"linkType\": \"HARD\"\n          }]\n        ]]\n      ]\n    }`)\n\n    const value = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      write: false,\n      absWorkingDir: testDir,\n    })\n\n    assert.strictEqual(value.outputFiles.length, 1)\n    assert.strictEqual(value.outputFiles[0].text, `(() => {\n  // entry.jsx\n  console.log(/* @__PURE__ */ success(\"div\", null));\n})();\n`)\n  },\n\n  async yarnPnP_indexJs({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const fooIndex = path.join(testDir, 'node_modules', '@some', 'pkg', 'index.js')\n    const fooFoo = path.join(testDir, 'node_modules', '@some', 'pkg', 'foo.js')\n    const manifest = path.join(testDir, '.pnp.data.json')\n\n    await writeFileAsync(entry, `\n      import x from '@some/pkg'\n      x()\n    `)\n\n    await mkdirAsync(path.dirname(fooIndex), { recursive: true })\n    await writeFileAsync(fooIndex, `export default success`)\n\n    await mkdirAsync(path.dirname(fooFoo), { recursive: true })\n    await writeFileAsync(fooFoo, `failure!`)\n\n    await writeFileAsync(manifest, `{\n      \"packageRegistryData\": [\n        [null, [\n          [null, {\n            \"packageLocation\": \"./\",\n            \"packageDependencies\": [\n              [\"@some/pkg\", \"npm:1.0.0\"]\n            ],\n            \"linkType\": \"SOFT\"\n          }]\n        ]],\n        [\"@some/pkg\", [\n          [\"npm:1.0.0\", {\n            \"packageLocation\": \"./node_modules/@some/pkg/\",\n            \"packageDependencies\": [],\n            \"linkType\": \"HARD\"\n          }]\n        ]]\n      ]\n    }`)\n\n    const value = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      write: false,\n      absWorkingDir: testDir,\n    })\n\n    assert.strictEqual(value.outputFiles.length, 1)\n    assert.strictEqual(value.outputFiles[0].text, `(() => {\n  // node_modules/@some/pkg/index.js\n  var pkg_default = success;\n\n  // entry.js\n  pkg_default();\n})();\n`)\n  },\n\n  async yarnPnP_depOfVirtual({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const pkg = path.join(testDir, '.yarn', 'cache', 'pkg-zip', 'node_modules', 'pkg', 'index.js')\n    const dep = path.join(testDir, '.yarn', 'cache', 'dep-zip', 'node_modules', 'dep', 'index.js')\n    const manifest = path.join(testDir, '.pnp.data.json')\n\n    await writeFileAsync(entry, `import 'pkg'`)\n\n    await mkdirAsync(path.dirname(pkg), { recursive: true })\n    await writeFileAsync(pkg, `import 'dep'`)\n\n    await mkdirAsync(path.dirname(dep), { recursive: true })\n    await writeFileAsync(dep, `success()`)\n\n    await writeFileAsync(manifest, `{\n      \"packageRegistryData\": [\n        [null, [\n          [null, {\n            \"packageLocation\": \"./\",\n            \"packageDependencies\": [\n              [\"pkg\", \"virtual:some-path\"]\n            ],\n            \"linkType\": \"SOFT\"\n          }]\n        ]],\n        [\"demo\", [\n          [\"workspace:.\", {\n            \"packageLocation\": \"./\",\n            \"packageDependencies\": [\n              [\"demo\", \"workspace:.\"],\n              [\"pkg\", \"virtual:some-path\"]\n            ],\n            \"linkType\": \"SOFT\"\n          }]\n        ]],\n        [\"pkg\", [\n          [\"npm:1.0.0\", {\n            \"packageLocation\": \"./.yarn/cache/pkg-zip/node_modules/pkg/\",\n            \"packageDependencies\": [\n              [\"pkg\", \"npm:1.0.0\"]\n            ],\n            \"linkType\": \"SOFT\"\n          }],\n          [\"virtual:some-path\", {\n            \"packageLocation\": \"./.yarn/__virtual__/pkg-virtual/0/cache/pkg-zip/node_modules/pkg/\",\n            \"packageDependencies\": [\n              [\"pkg\", \"virtual:some-path\"],\n              [\"dep\", \"npm:1.0.0\"]\n            ],\n            \"linkType\": \"HARD\"\n          }]\n        ]],\n        [\"dep\", [\n          [\"npm:1.0.0\", {\n            \"packageLocation\": \"./.yarn/cache/dep-zip/node_modules/dep/\",\n            \"packageDependencies\": [\n              [\"dep\", \"npm:1.0.0\"]\n            ],\n            \"linkType\": \"HARD\"\n          }]\n        ]]\n      ]\n    }`)\n\n    const value = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      write: false,\n      absWorkingDir: testDir,\n    })\n\n    assert.strictEqual(value.outputFiles.length, 1)\n    assert.strictEqual(value.outputFiles[0].text, `(() => {\n  // .yarn/cache/dep-zip/node_modules/dep/index.js\n  success();\n})();\n`)\n  },\n\n  // https://github.com/evanw/esbuild/issues/3915\n  async yarnPnP_stackOverflow({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.jsx')\n\n    await writeFileAsync(entry, `console.log(<div />)`)\n    await writeFileAsync(path.join(testDir, 'tsconfig.json'), `{ \"extends\": \"tsconfigs/config\" }`)\n    await mkdirAsync(path.join(testDir, 'packages/tsconfigs/configs'), { recursive: true })\n    await writeFileAsync(path.join(testDir, 'packages/tsconfigs/package.json'), `{ \"exports\": { \"./config\": \"./configs/tsconfig.json\" } }`)\n    await writeFileAsync(path.join(testDir, 'packages/tsconfigs/configs/tsconfig.json'), `{ \"compilerOptions\": { \"jsxFactory\": \"success\" } }`)\n\n    await writeFileAsync(path.join(testDir, '.pnp.data.json'), `{\n      \"packageRegistryData\": [\n        [null, [\n          [null, {\n            \"packageLocation\": \"./\",\n            \"packageDependencies\": [\n              [\"tsconfigs\", \"virtual:some-path\"]\n            ],\n            \"linkType\": \"SOFT\"\n          }]\n        ]],\n        [\"tsconfigs\", [\n          [\"virtual:some-path\", {\n            \"packageLocation\": \"./.yarn/__virtual__/tsconfigs-virtual-f56a53910e/1/packages/tsconfigs/\",\n            \"packageDependencies\": [\n              [\"tsconfigs\", \"virtual:some-path\"]\n            ],\n            \"packagePeers\": [],\n            \"linkType\": \"SOFT\"\n          }],\n          [\"workspace:packages/tsconfigs\", {\n            \"packageLocation\": \"./packages/tsconfigs/\",\n            \"packageDependencies\": [\n              [\"tsconfigs\", \"workspace:packages/tsconfigs\"]\n            ],\n            \"linkType\": \"SOFT\"\n          }]\n        ]]\n      ]\n    }`)\n\n    const value = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      write: false,\n      absWorkingDir: testDir,\n    })\n\n    assert.strictEqual(value.outputFiles.length, 1)\n    assert.strictEqual(value.outputFiles[0].text, `(() => {\n  // entry.jsx\n  console.log(/* @__PURE__ */ success(\"div\", null));\n})();\n`)\n  },\n}\n\nfunction fetch(host, port, path, { headers, method = 'GET' } = {}) {\n  return new Promise((resolve, reject) => {\n    http.request({ method, host, port, path, headers }, res => {\n      const chunks = []\n      res.on('data', chunk => chunks.push(chunk))\n      res.on('end', () => {\n        const content = Buffer.concat(chunks)\n        if (res.statusCode < 200 || res.statusCode > 299) {\n          const error = new Error(`${res.statusCode} when fetching \"${path}\": ${content}`)\n          error.statusCode = res.statusCode\n          reject(error)\n        } else {\n          content.headers = res.headers\n          resolve(content)\n        }\n      })\n    }).on('error', reject).end()\n  })\n}\n\nfunction fetchHTTPS(host, port, path, { certfile }) {\n  return new Promise((resolve, reject) => {\n    const checkServerIdentity = (hostname, cert) => {\n      // I'm not sure why node seems to always reject the host \"127.0.0.1\"\n      assert.strictEqual(hostname, '127.0.0.1')\n      assert.strictEqual(cert.subject.CN, '127.0.0.1')\n    }\n    const ca = [fs.readFileSync(certfile, 'utf8')]\n    https.get({ host, port, path, ca, checkServerIdentity }, res => {\n      const chunks = []\n      res.on('data', chunk => chunks.push(chunk))\n      res.on('end', () => {\n        const content = Buffer.concat(chunks)\n        if (res.statusCode < 200 || res.statusCode > 299) {\n          const error = new Error(`${res.statusCode} when fetching \"${path}\": ${content}`)\n          error.statusCode = res.statusCode\n          reject(error)\n        } else {\n          content.headers = res.headers\n          resolve(content)\n        }\n      })\n    }).on('error', reject)\n  })\n}\n\nfunction partialFetch(host, port, path, { headers, method = 'GET' } = {}) {\n  return new Promise((resolve, reject) => {\n    http.request({ method, host, port, path, headers }, res => {\n      resolve(res)\n      res.socket.destroy()\n    }).on('error', reject).end()\n  })\n}\n\nconst makeEventStream = (host, port, path) => {\n  return new Promise((resolve, reject) => {\n    const headers = {\n      'Accept': 'text/event-stream',\n    }\n\n    http.get({ host, port, path, headers }, res => {\n      if (res.statusCode !== 200) {\n        reject(new Error(`${res.statusCode} when fetching \"${path}\"`))\n        return\n      }\n\n      const stream = new events.EventEmitter\n      let buffer = ''\n\n      res.on('data', chunk => {\n        buffer += chunk\n        while (true) {\n          const index = buffer.indexOf('\\n\\n')\n          if (index < 0) break\n\n          const lines = buffer.slice(0, index).split('\\n')\n          const fields = Object.create(null)\n          buffer = buffer.slice(index + 2)\n\n          for (const line of lines) {\n            const colon = line.indexOf(':')\n            if (colon >= 0) {\n              const key = line.slice(0, colon).trim()\n              const value = line.slice(colon + 1).trim()\n              fields[key] = value\n            }\n          }\n\n          if ('data' in fields) {\n            stream.emit('event' in fields ? fields.event : 'message', fields)\n          }\n        }\n      })\n\n      res.on('close', () => stream.emit('close'))\n\n      stream.destroy = () => res.destroy()\n\n      stream.waitFor = name => new Promise((resolve, reject) => {\n        const timeout = setTimeout(() => {\n          reject(new Error('Timeout after 30 seconds'))\n          stream.destroy()\n        }, 30 * 1000)\n\n        stream.once(name, value => {\n          clearTimeout(timeout)\n          resolve(value)\n        })\n      })\n\n      resolve(stream)\n    }).on('error', reject)\n  })\n}\n\nconst makeRebuildUntilPlugin = () => {\n  let onEnd\n\n  return {\n    rebuildUntil: (mutator, condition) => new Promise((resolve, reject) => {\n      let timeout = setTimeout(() => reject(new Error('Timeout after 30 seconds')), 30 * 1000)\n      onEnd = result => {\n        try { if (result && condition(result)) clearTimeout(timeout), resolve(result) }\n        catch (e) { clearTimeout(timeout), reject(e) }\n      }\n      mutator()\n    }),\n\n    plugin: {\n      name: 'rebuildUntil',\n      setup(build) {\n        build.onEnd(result => onEnd(result))\n      },\n    },\n  }\n}\n\nlet watchTests = {\n  async watchTwice({ esbuild }) {\n    const context = await esbuild.context({})\n    try {\n      // Watch once\n      await context.watch()\n\n      // Watch twice\n      try {\n        await context.watch()\n        throw new Error('Expected an error to be thrown')\n      } catch (err) {\n        assert.strictEqual(err.message, 'Watch mode has already been enabled')\n      }\n    } finally {\n      await context.dispose()\n    }\n  },\n\n  async watchEditSession({ esbuild, testDir }) {\n    const srcDir = path.join(testDir, 'src')\n    const outfile = path.join(testDir, 'out.js')\n    const input = path.join(srcDir, 'in.js')\n    await mkdirAsync(srcDir, { recursive: true })\n    await writeFileAsync(input, `throw 1`)\n\n    const { rebuildUntil, plugin } = makeRebuildUntilPlugin()\n    const context = await esbuild.context({\n      entryPoints: [input],\n      outfile,\n      format: 'esm',\n      logLevel: 'silent',\n      plugins: [plugin],\n    })\n\n    try {\n      const result = await rebuildUntil(\n        () => context.watch(),\n        () => true,\n      )\n      assert.strictEqual(result.outputFiles, void 0)\n      assert.strictEqual(result.errors.length, 0)\n      assert.strictEqual(await readFileAsync(outfile, 'utf8'), 'throw 1;\\n')\n\n      // First rebuild: edit\n      {\n        const result2 = await rebuildUntil(\n          () => writeFileAtomic(input, `throw 2`),\n          () => fs.readFileSync(outfile, 'utf8') === 'throw 2;\\n',\n        )\n        assert.strictEqual(result2.outputFiles, void 0)\n        assert.strictEqual(result2.errors.length, 0)\n        assert.strictEqual(await readFileAsync(outfile, 'utf8'), 'throw 2;\\n')\n      }\n\n      // Second rebuild: edit\n      {\n        const result2 = await rebuildUntil(\n          () => writeFileAtomic(input, `throw 3`),\n          () => fs.readFileSync(outfile, 'utf8') === 'throw 3;\\n',\n        )\n        assert.strictEqual(result2.outputFiles, void 0)\n        assert.strictEqual(result2.errors.length, 0)\n        assert.strictEqual(await readFileAsync(outfile, 'utf8'), 'throw 3;\\n')\n      }\n\n      // Third rebuild: syntax error\n      {\n        const result2 = await rebuildUntil(\n          () => writeFileAtomic(input, `throw 1 2`),\n          result => result.errors.length > 0,\n        )\n        assert.strictEqual(result2.errors.length, 1)\n        assert.strictEqual(result2.errors[0].text, 'Expected \";\" but found \"2\"')\n        assert.strictEqual(fs.existsSync(outfile), false)\n      }\n\n      // Fourth rebuild: edit\n      {\n        const result2 = await rebuildUntil(\n          () => writeFileAtomic(input, `throw 4`),\n          () => fs.readFileSync(outfile, 'utf8') === 'throw 4;\\n',\n        )\n        assert.strictEqual(result2.outputFiles, void 0)\n        assert.strictEqual(result2.errors.length, 0)\n        assert.strictEqual(await readFileAsync(outfile, 'utf8'), 'throw 4;\\n')\n      }\n\n      // Fifth rebuild: delete\n      {\n        const result2 = await rebuildUntil(\n          () => fs.promises.unlink(input),\n          result => result.errors.length > 0,\n        )\n        assert.strictEqual(result2.errors.length, 1)\n        assert.strictEqual(fs.existsSync(outfile), false)\n      }\n\n      // Sixth rebuild: restore\n      {\n        const result2 = await rebuildUntil(\n          () => writeFileAtomic(input, `throw 5`),\n          () => fs.readFileSync(outfile, 'utf8') === 'throw 5;\\n',\n        )\n        assert.strictEqual(result2.outputFiles, void 0)\n        assert.strictEqual(result2.errors.length, 0)\n        assert.strictEqual(await readFileAsync(outfile, 'utf8'), 'throw 5;\\n')\n      }\n    } finally {\n      await context.dispose()\n    }\n  },\n\n  async watchWriteFalse({ esbuild, testDir }) {\n    const srcDir = path.join(testDir, 'src')\n    const outdir = path.join(testDir, 'out')\n    const input = path.join(srcDir, 'in.js')\n    const output = path.join(outdir, 'in.js')\n    await mkdirAsync(srcDir, { recursive: true })\n    await writeFileAsync(input, `throw 1`)\n\n    const { rebuildUntil, plugin } = makeRebuildUntilPlugin()\n    const context = await esbuild.context({\n      entryPoints: [input],\n      outdir,\n      format: 'esm',\n      logLevel: 'silent',\n      write: false,\n      plugins: [plugin],\n    })\n\n    try {\n      const result = await rebuildUntil(\n        () => context.watch(),\n        () => true,\n      )\n      assert.strictEqual(result.errors.length, 0)\n      assert.strictEqual(result.outputFiles[0].text, 'throw 1;\\n')\n      assert.strictEqual(fs.existsSync(output), false)\n\n      // First rebuild: edit\n      {\n        const result2 = await rebuildUntil(\n          () => writeFileAtomic(input, `throw 2`),\n          res => res.outputFiles[0].text === 'throw 2;\\n',\n        )\n        assert.strictEqual(result2.errors.length, 0)\n        assert.strictEqual(fs.existsSync(output), false)\n      }\n\n      // Second rebuild: edit\n      {\n        const result2 = await rebuildUntil(\n          () => writeFileAtomic(input, `throw 3`),\n          res => res.outputFiles[0].text === 'throw 3;\\n',\n        )\n        assert.strictEqual(result2.errors.length, 0)\n        assert.strictEqual(fs.existsSync(output), false)\n      }\n    } finally {\n      await context.dispose()\n    }\n  },\n\n  async watchMetafile({ esbuild, testDir }) {\n    const srcDir = path.join(testDir, 'src')\n    const outdir = path.join(testDir, 'out')\n    const input = path.join(srcDir, 'in.js')\n    const output = path.join(outdir, 'in.js')\n    await mkdirAsync(srcDir, { recursive: true })\n    await writeFileAsync(input, `foo()`)\n\n    const { rebuildUntil, plugin } = makeRebuildUntilPlugin()\n    const context = await esbuild.context({\n      entryPoints: [input],\n      outdir,\n      format: 'esm',\n      logLevel: 'silent',\n      metafile: true,\n      plugins: [plugin],\n    })\n\n    try {\n      const result = await rebuildUntil(\n        () => context.watch(),\n        () => true,\n      )\n      assert.strictEqual(result.errors.length, 0)\n      const relInput = path.relative(process.cwd(), input).split(path.sep).join('/')\n      assert.strictEqual(result.metafile.inputs[relInput].bytes, 5)\n      assert.strictEqual(await readFileAsync(output, 'utf8'), 'foo();\\n')\n\n      // Rebuild and check that the metafile has been updated\n      {\n        const result2 = await rebuildUntil(\n          () => writeFileAtomic(input, `foo(123)`),\n          () => fs.readFileSync(output, 'utf8') === 'foo(123);\\n',\n        )\n        assert.strictEqual(result2.errors.length, 0)\n        assert.strictEqual(result2.metafile.inputs[relInput].bytes, 8)\n      }\n    } finally {\n      await context.dispose()\n    }\n  },\n\n  async watchMangleCache({ esbuild, testDir }) {\n    const srcDir = path.join(testDir, 'src')\n    const outdir = path.join(testDir, 'out')\n    const input = path.join(srcDir, 'in.js')\n    const output = path.join(outdir, 'in.js')\n    await mkdirAsync(srcDir, { recursive: true })\n    await writeFileAsync(input, `foo()`)\n\n    const { rebuildUntil, plugin } = makeRebuildUntilPlugin()\n    const context = await esbuild.context({\n      entryPoints: [input],\n      outdir,\n      format: 'esm',\n      logLevel: 'silent',\n      mangleProps: /./,\n      mangleCache: {},\n      plugins: [plugin],\n    })\n\n    try {\n      const result = await rebuildUntil(\n        () => context.watch(),\n        () => true,\n      )\n      assert.strictEqual(result.errors.length, 0)\n      assert.strictEqual(JSON.stringify(result.mangleCache), '{}')\n\n      // Rebuild and check that the mangle cache has been updated\n      {\n        const result2 = await rebuildUntil(\n          () => writeFileAtomic(input, `foo(bar.baz)`),\n          () => fs.readFileSync(output, 'utf8') === 'foo(bar.a);\\n',\n        )\n        assert.strictEqual(result2.errors.length, 0)\n        assert.strictEqual(JSON.stringify(result2.mangleCache), '{\"baz\":\"a\"}')\n      }\n    } finally {\n      await context.dispose()\n    }\n  },\n\n  // See: https://github.com/evanw/esbuild/issues/3062\n  async watchNodePaths({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const outfile = path.join(testDir, 'out.js')\n    const libDir = path.join(testDir, 'lib')\n    const libFile = path.join(libDir, 'foo.js')\n    await mkdirAsync(libDir, { recursive: true })\n    await writeFileAsync(input, `\n      import { foo } from ${JSON.stringify(path.basename(libFile))}\n      console.log(foo)\n    `)\n\n    const { rebuildUntil, plugin } = makeRebuildUntilPlugin()\n    const context = await esbuild.context({\n      entryPoints: [input],\n      outfile,\n      write: false,\n      bundle: true,\n      minifyWhitespace: true,\n      format: 'esm',\n      logLevel: 'silent',\n      plugins: [plugin],\n      nodePaths: [libDir],\n    })\n\n    try {\n      const result = await rebuildUntil(\n        () => {\n          context.watch()\n          writeFileAtomic(libFile, `export let foo = 0`)\n        },\n        result => result.outputFiles.length === 1,\n      )\n      assert.strictEqual(result.outputFiles[0].text, `var foo=0;console.log(foo);\\n`)\n\n      // Make sure watch mode works for files imported via NODE_PATH\n      for (let i = 1; i <= 3; i++) {\n        const result2 = await rebuildUntil(\n          () => writeFileAtomic(libFile, `export let foo = ${i}`),\n          result => result.outputFiles.length === 1 && result.outputFiles[0].text.includes(i),\n        )\n        assert.strictEqual(result2.outputFiles[0].text, `var foo=${i};console.log(foo);\\n`)\n      }\n    } finally {\n      await context.dispose()\n    }\n  },\n\n  async watchDelay({ esbuild, testDir }) {\n    const srcDir = path.join(testDir, 'src')\n    const outdir = path.join(testDir, 'out')\n    const input = path.join(srcDir, 'in.js')\n    const output = path.join(outdir, 'in.js')\n    await mkdirAsync(srcDir, { recursive: true })\n    await writeFileAsync(input, `throw 1`)\n\n    const { rebuildUntil, plugin } = makeRebuildUntilPlugin()\n    const context = await esbuild.context({\n      entryPoints: [input],\n      outdir,\n      format: 'esm',\n      logLevel: 'silent',\n      plugins: [plugin],\n    })\n\n    try {\n      const delay = 2000\n      const result = await rebuildUntil(\n        () => context.watch({ delay }),\n        () => true,\n      )\n      assert.strictEqual(result.errors.length, 0)\n      assert.strictEqual(await readFileAsync(output, 'utf8'), 'throw 1;\\n')\n\n      // Edit a file\n      const startTime = Date.now()\n      const editPromise = rebuildUntil(\n        () => writeFileAtomic(input, `throw 2`),\n        () => fs.readFileSync(output, 'utf8') === 'throw 2;\\n',\n      )\n\n      // Wait for half the delay time\n      await new Promise(resolve => setTimeout(resolve, delay / 2))\n\n      // The rebuild should not have happened yet (check synchronously)\n      if (Date.now() - startTime < delay) {\n        assert.strictEqual(fs.readFileSync(output, 'utf8'), 'throw 1;\\n')\n      } else {\n        // To avoid a flaky test, don't check and assert if the CPU is busy and we missed our window\n      }\n\n      // Wait for the rebuild to happen\n      const result2 = await editPromise\n      assert.strictEqual(result2.errors.length, 0)\n    } finally {\n      await context.dispose()\n    }\n  },\n}\n\nlet serveTests = {\n  async serveTwice({ esbuild }) {\n    const context = await esbuild.context({})\n    try {\n      // Serve once\n      await context.serve()\n\n      // Serve twice\n      try {\n        await context.serve()\n        throw new Error('Expected an error to be thrown')\n      } catch (err) {\n        assert.strictEqual(err.message, 'Serve mode has already been enabled')\n      }\n    } finally {\n      await context.dispose()\n    }\n  },\n\n  async serveWatch({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.ts')\n    const outfile = path.join(testDir, 'out.js')\n\n    const { rebuildUntil, plugin } = makeRebuildUntilPlugin()\n    const context = await esbuild.context({\n      entryPoints: [input],\n      outfile,\n      logLevel: 'silent',\n      plugins: [plugin],\n    })\n\n    try {\n      await context.watch()\n      const server = await context.serve({\n        host: '127.0.0.1',\n      })\n\n      // Try fetching the non-existent file\n      try {\n        await fetch(server.hosts[0], server.port, '/' + path.basename(outfile))\n        throw new Error('Expected an error to be thrown')\n      } catch (err) {\n        if (err.statusCode !== 503) throw err\n      }\n\n      // Check that watch mode works\n      for (let i = 0; i < 5; i++) {\n        const result = await rebuildUntil(\n          () => writeFileAtomic(input, `throw ${i}`),\n          () => fs.readFileSync(outfile, 'utf8') === `throw ${i};\\n`,\n        )\n        assert.strictEqual(result.errors.length, 0)\n        assert.strictEqual(fs.readFileSync(outfile, 'utf8'), `throw ${i};\\n`)\n      }\n\n      // Try fetching the file now\n      const data = await fetch(server.hosts[0], server.port, '/' + path.basename(outfile))\n      assert.strictEqual(data.toString(), 'throw 4;\\n')\n    } finally {\n      await context.dispose()\n    }\n  },\n\n  async serveBasic({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, `console.log(123)`)\n\n    let onRequest;\n\n    const context = await esbuild.context({\n      entryPoints: [input],\n      format: 'esm',\n      outdir: testDir,\n      write: false,\n    });\n    try {\n      const result = await context.serve({\n        host: '127.0.0.1',\n        onRequest: args => onRequest(args),\n      })\n      assert.deepStrictEqual(result.hosts, ['127.0.0.1']);\n      assert.strictEqual(typeof result.port, 'number');\n\n      // GET /in.js\n      {\n        const singleRequestPromise = new Promise(resolve => { onRequest = resolve });\n        const buffer = await fetch(result.hosts[0], result.port, '/in.js')\n        assert.strictEqual(buffer.toString(), `console.log(123);\\n`);\n        assert.strictEqual(fs.readFileSync(input, 'utf8'), `console.log(123)`)\n\n        let singleRequest = await singleRequestPromise;\n        assert.strictEqual(singleRequest.method, 'GET');\n        assert.strictEqual(singleRequest.path, '/in.js');\n        assert.strictEqual(singleRequest.status, 200);\n        assert.strictEqual(typeof singleRequest.remoteAddress, 'string');\n        assert.strictEqual(typeof singleRequest.timeInMS, 'number');\n      }\n\n      // HEAD /in.js\n      {\n        const singleRequestPromise = new Promise(resolve => { onRequest = resolve });\n        const buffer = await fetch(result.hosts[0], result.port, '/in.js', { method: 'HEAD' })\n        assert.strictEqual(buffer.toString(), ``); // HEAD omits the content\n        assert.strictEqual(fs.readFileSync(input, 'utf8'), `console.log(123)`)\n\n        let singleRequest = await singleRequestPromise;\n        assert.strictEqual(singleRequest.method, 'HEAD');\n        assert.strictEqual(singleRequest.path, '/in.js');\n        assert.strictEqual(singleRequest.status, 200);\n        assert.strictEqual(typeof singleRequest.remoteAddress, 'string');\n        assert.strictEqual(typeof singleRequest.timeInMS, 'number');\n      }\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveBasicHTTPS({ esbuild, testDir }) {\n    const run = command => new Promise((resolve, reject) => {\n      child_process.execFile(command.shift(), command, (error, stdout, stderr) => {\n        if (error) reject(error)\n        else resolve()\n      })\n    })\n\n    try {\n      await run(['which', 'openssl'])\n    } catch {\n      console.warn('Skipping HTTPS tests because the \"openssl\" command was not found')\n      return\n    }\n\n    const keyfile = path.join(testDir, 'key.pem')\n    const certfile = path.join(testDir, 'cert.pem')\n    await run(['openssl', 'req', '-x509', '-newkey', 'rsa:4096', '-keyout', keyfile, '-out', certfile, '-days', '9999', '-nodes', '-subj', '/CN=127.0.0.1'])\n\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, `console.log(123)`)\n\n    let onRequest;\n    let singleRequestPromise = new Promise(resolve => {\n      onRequest = resolve;\n    });\n\n    const context = await esbuild.context({\n      entryPoints: [input],\n      format: 'esm',\n      outdir: testDir,\n      write: false,\n    });\n    try {\n      const result = await context.serve({\n        host: '127.0.0.1',\n        keyfile,\n        certfile,\n        onRequest,\n      })\n      assert.deepStrictEqual(result.hosts, ['127.0.0.1']);\n      assert.strictEqual(typeof result.port, 'number');\n\n      const buffer = await fetchHTTPS(result.hosts[0], result.port, '/in.js', { certfile })\n      assert.strictEqual(buffer.toString(), `console.log(123);\\n`);\n      assert.strictEqual(fs.readFileSync(input, 'utf8'), `console.log(123)`)\n\n      let singleRequest = await singleRequestPromise;\n      assert.strictEqual(singleRequest.method, 'GET');\n      assert.strictEqual(singleRequest.path, '/in.js');\n      assert.strictEqual(singleRequest.status, 200);\n      assert.strictEqual(typeof singleRequest.remoteAddress, 'string');\n      assert.strictEqual(typeof singleRequest.timeInMS, 'number');\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveSlashRedirect({ esbuild, testDir }) {\n    const nestedDir = path.join(testDir, 'nested', 'dir')\n    const index = path.join(nestedDir, 'index.html')\n    await mkdirAsync(nestedDir, { recursive: true })\n    await writeFileAsync(index, `<!doctype html>`)\n\n    const context = await esbuild.context({});\n    try {\n      const result = await context.serve({\n        host: '127.0.0.1',\n        servedir: testDir,\n      })\n      assert.deepStrictEqual(result.hosts, ['127.0.0.1']);\n      assert.strictEqual(typeof result.port, 'number');\n\n      // With a trailing slash\n      {\n        const buffer = await fetch(result.hosts[0], result.port, '/nested/dir/index.html')\n        assert.strictEqual(buffer.toString(), `<!doctype html>`)\n      }\n      {\n        const buffer = await fetch(result.hosts[0], result.port, '/nested/dir/')\n        assert.strictEqual(buffer.toString(), `<!doctype html>`)\n      }\n      {\n        const buffer = await fetch(result.hosts[0], result.port, '/nested/./dir/')\n        assert.strictEqual(buffer.toString(), `<!doctype html>`)\n      }\n      {\n        const buffer = await fetch(result.hosts[0], result.port, '/./nested/./dir/./')\n        assert.strictEqual(buffer.toString(), `<!doctype html>`)\n      }\n      {\n        const buffer = await fetch(result.hosts[0], result.port, '/nested/dir//')\n        assert.strictEqual(buffer.toString(), `<!doctype html>`)\n      }\n      {\n        const buffer = await fetch(result.hosts[0], result.port, '/nested//dir/')\n        assert.strictEqual(buffer.toString(), `<!doctype html>`)\n      }\n\n      // Without a trailing slash\n      {\n        const res = await partialFetch(result.hosts[0], result.port, '/nested')\n        assert.strictEqual(res.statusCode, 302)\n        assert.strictEqual(res.headers.location, '/nested/')\n      }\n      {\n        const res = await partialFetch(result.hosts[0], result.port, '/nested/dir')\n        assert.strictEqual(res.statusCode, 302)\n        assert.strictEqual(res.headers.location, '/nested/dir/')\n      }\n      {\n        const res = await partialFetch(result.hosts[0], result.port, '/nested//dir')\n        assert.strictEqual(res.statusCode, 302)\n        assert.strictEqual(res.headers.location, '/nested/dir/')\n      }\n\n      // With leading double slashes (looks like a protocol-relative URL)\n      {\n        const res = await partialFetch(result.hosts[0], result.port, '//nested')\n        assert.strictEqual(res.statusCode, 302)\n        assert.strictEqual(res.headers.location, '/nested/')\n      }\n      {\n        const res = await partialFetch(result.hosts[0], result.port, '//nested/dir')\n        assert.strictEqual(res.statusCode, 302)\n        assert.strictEqual(res.headers.location, '/nested/dir/')\n      }\n      {\n        const res = await partialFetch(result.hosts[0], result.port, '//nested//dir')\n        assert.strictEqual(res.statusCode, 302)\n        assert.strictEqual(res.headers.location, '/nested/dir/')\n      }\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveOutfile({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const outfile = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `console.log(123)`)\n\n    let onRequest;\n    let singleRequestPromise = new Promise(resolve => {\n      onRequest = resolve;\n    });\n\n    const context = await esbuild.context({\n      entryPoints: [input],\n      format: 'esm',\n      outfile,\n    });\n    try {\n      const result = await context.serve({\n        host: '127.0.0.1',\n        onRequest,\n      })\n      assert.deepStrictEqual(result.hosts, ['127.0.0.1']);\n      assert.strictEqual(typeof result.port, 'number');\n\n      const buffer = await fetch(result.hosts[0], result.port, '/out.js')\n      assert.strictEqual(buffer.toString(), `console.log(123);\\n`);\n\n      let singleRequest = await singleRequestPromise;\n      assert.strictEqual(singleRequest.method, 'GET');\n      assert.strictEqual(singleRequest.path, '/out.js');\n      assert.strictEqual(singleRequest.status, 200);\n      assert.strictEqual(typeof singleRequest.remoteAddress, 'string');\n      assert.strictEqual(typeof singleRequest.timeInMS, 'number');\n\n      try {\n        await fetch(result.hosts[0], result.port, '/in.js')\n        throw new Error('Expected a 404 error for \"/in.js\"')\n      } catch (err) {\n        if (err.message !== '404 when fetching \"/in.js\": 404 - Not Found')\n          throw err\n      }\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveWithServedir({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const wwwDir = path.join(testDir, 'www')\n    const index = path.join(wwwDir, 'index.html')\n    await mkdirAsync(wwwDir, { recursive: true })\n    await writeFileAsync(input, `console.log(123)`)\n    await writeFileAsync(index, `<!doctype html>`)\n\n    let onRequest;\n    let nextRequestPromise;\n\n    (function generateNewPromise() {\n      nextRequestPromise = new Promise(resolve => {\n        onRequest = args => {\n          generateNewPromise();\n          resolve(args);\n        };\n      });\n    })();\n\n    const context = await esbuild.context({\n      entryPoints: [input],\n      format: 'esm',\n      outdir: wwwDir,\n      write: false,\n    });\n    try {\n      const result = await context.serve({\n        host: '127.0.0.1',\n        onRequest: args => onRequest(args),\n        servedir: wwwDir,\n      })\n      assert.deepStrictEqual(result.hosts, ['127.0.0.1']);\n      assert.strictEqual(typeof result.port, 'number');\n\n      let promise, buffer, req;\n\n      promise = nextRequestPromise;\n      buffer = await fetch(result.hosts[0], result.port, '/in.js')\n      assert.strictEqual(buffer.toString(), `console.log(123);\\n`);\n      assert.strictEqual(fs.existsSync(path.join(wwwDir, path.basename(input))), false);\n      req = await promise;\n      assert.strictEqual(req.method, 'GET');\n      assert.strictEqual(req.path, '/in.js');\n      assert.strictEqual(req.status, 200);\n      assert.strictEqual(typeof req.remoteAddress, 'string');\n      assert.strictEqual(typeof req.timeInMS, 'number');\n\n      promise = nextRequestPromise;\n      buffer = await fetch(result.hosts[0], result.port, '/')\n      assert.strictEqual(buffer.toString(), `<!doctype html>`);\n      req = await promise;\n      assert.strictEqual(req.method, 'GET');\n      assert.strictEqual(req.path, '/');\n      assert.strictEqual(req.status, 200);\n      assert.strictEqual(typeof req.remoteAddress, 'string');\n      assert.strictEqual(typeof req.timeInMS, 'number');\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveWithServedirAndSiblingOutputDir({ esbuild, testDir }) {\n    const context = await esbuild.context({\n      entryPoints: [path.join(testDir, 'in.js')],\n      outdir: 'out',\n    });\n    try {\n      await context.serve({\n        servedir: 'www',\n      });\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert.strictEqual(e.message, `Output directory \"out\" must be contained in serve directory \"www\"`)\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveWithServedirAndParentOutputDir({ esbuild, testDir }) {\n    const context = await esbuild.context({\n      entryPoints: [path.join(testDir, 'in.js')],\n      outdir: testDir,\n      absWorkingDir: testDir,\n    });\n    try {\n      await context.serve({\n        servedir: path.join(testDir, 'www'),\n      })\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert.strictEqual(e.message, `Output directory \".\" must be contained in serve directory \"www\"`)\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveWithServedirAndOutputDir({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const outputDir = path.join(testDir, 'www/out')\n    const wwwDir = path.join(testDir, 'www')\n    const index = path.join(wwwDir, 'index.html')\n    await mkdirAsync(wwwDir, { recursive: true })\n    await writeFileAsync(input, `console.log(123)`)\n    await writeFileAsync(index, `<!doctype html>`)\n\n    let onRequest;\n    let nextRequestPromise;\n\n    (function generateNewPromise() {\n      nextRequestPromise = new Promise(resolve => {\n        onRequest = args => {\n          generateNewPromise();\n          resolve(args);\n        };\n      });\n    })();\n\n    const context = await esbuild.context({\n      entryPoints: [input],\n      format: 'esm',\n      outdir: outputDir,\n    })\n    try {\n      const result = await context.serve({\n        host: '127.0.0.1',\n        onRequest: args => onRequest(args),\n        servedir: wwwDir,\n      })\n      assert.deepStrictEqual(result.hosts, ['127.0.0.1']);\n      assert.strictEqual(typeof result.port, 'number');\n\n      let promise, buffer, req;\n\n      promise = nextRequestPromise;\n      buffer = await fetch(result.hosts[0], result.port, '/out/in.js')\n      assert.strictEqual(buffer.toString(), `console.log(123);\\n`);\n      req = await promise;\n      assert.strictEqual(req.method, 'GET');\n      assert.strictEqual(req.path, '/out/in.js');\n      assert.strictEqual(req.status, 200);\n      assert.strictEqual(typeof req.remoteAddress, 'string');\n      assert.strictEqual(typeof req.timeInMS, 'number');\n\n      promise = nextRequestPromise;\n      buffer = await fetch(result.hosts[0], result.port, '/')\n      assert.strictEqual(buffer.toString(), `<!doctype html>`);\n      req = await promise;\n      assert.strictEqual(req.method, 'GET');\n      assert.strictEqual(req.path, '/');\n      assert.strictEqual(req.status, 200);\n      assert.strictEqual(typeof req.remoteAddress, 'string');\n      assert.strictEqual(typeof req.timeInMS, 'number');\n\n      // Make sure the output directory prefix requires a slash separator\n      promise = nextRequestPromise;\n      try {\n        await fetch(result.hosts[0], result.port, '/outin.js')\n        throw new Error('Expected an error to be thrown')\n      } catch (err) {\n        if (err.statusCode !== 404) throw err\n      }\n      req = await promise;\n      assert.strictEqual(req.method, 'GET');\n      assert.strictEqual(req.path, '/outin.js');\n      assert.strictEqual(req.status, 404);\n      assert.strictEqual(typeof req.remoteAddress, 'string');\n      assert.strictEqual(typeof req.timeInMS, 'number');\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveWithServedirNoEntryPoints({ esbuild, testDir }) {\n    const index = path.join(testDir, 'index.html')\n    await writeFileAsync(index, `<!doctype html>`)\n\n    let onRequest;\n    let nextRequestPromise;\n\n    (function generateNewPromise() {\n      nextRequestPromise = new Promise(resolve => {\n        onRequest = args => {\n          generateNewPromise();\n          resolve(args);\n        };\n      });\n    })();\n\n    const context = await esbuild.context({});\n    try {\n      const result = await context.serve({\n        host: '127.0.0.1',\n        onRequest: args => onRequest(args),\n        servedir: testDir,\n      })\n      assert.deepStrictEqual(result.hosts, ['127.0.0.1']);\n      assert.strictEqual(typeof result.port, 'number');\n\n      let promise, buffer, req;\n\n      promise = nextRequestPromise;\n      buffer = await fetch(result.hosts[0], result.port, '/')\n      assert.strictEqual(buffer.toString(), `<!doctype html>`);\n      req = await promise;\n      assert.strictEqual(req.method, 'GET');\n      assert.strictEqual(req.path, '/');\n      assert.strictEqual(req.status, 200);\n      assert.strictEqual(typeof req.remoteAddress, 'string');\n      assert.strictEqual(typeof req.timeInMS, 'number');\n\n      // Check that removing the file removes it from the directory listing (i.e. the\n      // \"fs.FS\" object in Go does not cache the result of calling \"ReadDirectory\")\n      await fs.promises.unlink(index)\n      promise = nextRequestPromise;\n      buffer = await fetch(result.hosts[0], result.port, '/')\n      assert.notStrictEqual(buffer.toString(), '<!doctype html>')\n      req = await promise;\n      assert.strictEqual(req.method, 'GET');\n      assert.strictEqual(req.path, '/');\n      assert.strictEqual(req.status, 200);\n      assert.strictEqual(typeof req.remoteAddress, 'string');\n      assert.strictEqual(typeof req.timeInMS, 'number');\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveRange({ esbuild, testDir }) {\n    const big = path.join(testDir, 'big.txt')\n    const byteCount = 16 * 1024 * 1024\n    const buffer = require('crypto').randomBytes(byteCount)\n    await writeFileAsync(big, buffer)\n\n    const context = await esbuild.context({});\n    try {\n      const result = await context.serve({\n        host: '127.0.0.1',\n        servedir: testDir,\n      })\n\n      // Test small to big ranges\n      const minLength = 1\n      const maxLength = buffer.length\n\n      for (let i = 0, n = 16; i < n; i++) {\n        const length = Math.round(minLength + (maxLength - minLength) * i / (n - 1))\n        const start = Math.floor(Math.random() * (buffer.length - length))\n        const headers = {\n          // Subtract 1 because range headers are inclusive on both ends\n          Range: `bytes=${start}-${start + length - 1}`,\n        }\n        const fetched = await fetch(result.hosts[0], result.port, '/big.txt', { headers })\n        delete fetched.headers.date // This changes every time\n        delete fetched.headers.connection // Node v19+ no longer sends this\n        const expected = buffer.slice(start, start + length)\n        expected.headers = {\n          'content-length': `${length}`,\n          'content-range': `bytes ${start}-${start + length - 1}/${byteCount}`,\n          'content-type': 'application/octet-stream',\n        }\n        assert.deepStrictEqual(fetched, expected)\n      }\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveWatchCopyLoaderWithEntryPoint({ esbuild, testDir }) {\n    const ts = path.join(testDir, 'script.ts')\n    const html = path.join(testDir, 'index.html')\n    const outdir = path.join(testDir, 'out')\n    await writeFileAsync(ts, `console.log(123)`)\n    await writeFileAsync(html, `<script src=script.js></script>`)\n\n    const context = await esbuild.context({\n      entryPoints: [ts, html],\n      outdir,\n      loader: { '.html': 'copy' },\n    });\n    try {\n      const server = await context.serve({\n        host: '127.0.0.1',\n        servedir: testDir,\n      })\n      await context.watch()\n\n      const js = await fetch(server.hosts[0], server.port, '/out/script.js')\n      assert.strictEqual(js.toString(), `console.log(123);\\n`);\n\n      const explicitHTML = await fetch(server.hosts[0], server.port, '/out/index.html')\n      assert.strictEqual(explicitHTML.toString(), `<script src=script.js></script>`);\n\n      // The server should support implicit \"index.html\" extensions on entry point files\n      const implicitHTML = await fetch(server.hosts[0], server.port, '/out/')\n      assert.strictEqual(implicitHTML.toString(), `<script src=script.js></script>`);\n\n      // Make a change to the HTML\n      await writeFileAsync(html, `<!DOCTYPE html><script src=script.js></script>`)\n\n      // Wait for watch mode to rebuild\n      const start = Date.now()\n      while (true) {\n        if (Date.now() - start > 30 * 1000) throw new Error('Timeout after 30 seconds')\n        const toCheck = fs.readFileSync(path.join(outdir, 'index.html'), 'utf8')\n        if (toCheck === `<!DOCTYPE html><script src=script.js></script>`) break\n      }\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveWithoutServedirWatchLiveReload({ esbuild, testDir }) {\n    const js = path.join(testDir, 'app.js')\n    const css = path.join(testDir, 'app.css')\n    const outdir = path.join(testDir, 'out')\n    await writeFileAsync(css, ``)\n\n    let endPromise\n    const context = await esbuild.context({\n      entryPoints: [js],\n      outdir,\n      bundle: true,\n      logLevel: 'silent',\n    });\n\n    try {\n      const server = await context.serve({\n        host: '127.0.0.1',\n      })\n      const stream = await makeEventStream(server.hosts[0], server.port, '/esbuild')\n      await context.rebuild().then(\n        () => Promise.reject(new Error('Expected an error to be thrown')),\n        () => { /* Ignore the build error due to the missing JS file */ },\n      )\n\n      // Event 1: a new JavaScript file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, ``)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: ['/app.js'], removed: [], updated: [] })\n\n      // Event 2: edit the JavaScript file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, `foo()`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: [], removed: [], updated: ['/app.js'] })\n\n      // Event 3: a new CSS file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, `import \"./app.css\"; foo()`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: ['/app.css'], removed: [], updated: [] })\n\n      // Event 4: edit the CSS file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(css, `a { color: red }`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: [], removed: [], updated: ['/app.css'] })\n\n      // Event 5: remove the CSS file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, `bar()`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: [], removed: ['/app.css'], updated: ['/app.js'] })\n\n      // Wait for the stream to end once we call \"dispose()\" below\n      endPromise = stream.waitFor('close')\n    }\n\n    finally {\n      await context.dispose();\n    }\n\n    // This stream should end once \"dispose()\" is called above\n    await endPromise\n  },\n\n  async serveWithServedirWatchLiveReload({ esbuild, testDir }) {\n    const js = path.join(testDir, 'app.js')\n    const css = path.join(testDir, 'app.css')\n    const outdir = path.join(testDir, 'out')\n    await writeFileAsync(css, ``)\n\n    let endPromise\n    const context = await esbuild.context({\n      entryPoints: [js],\n      outdir,\n      bundle: true,\n      logLevel: 'silent',\n    });\n\n    try {\n      const server = await context.serve({\n        host: '127.0.0.1',\n        servedir: testDir,\n      })\n      const stream = await makeEventStream(server.hosts[0], server.port, '/esbuild')\n      await context.rebuild().then(\n        () => Promise.reject(new Error('Expected an error to be thrown')),\n        () => { /* Ignore the build error due to the missing JS file */ },\n      )\n\n      // Event 1: a new JavaScript file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, ``)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: ['/out/app.js'], removed: [], updated: [] })\n\n      // Event 2: edit the JavaScript file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, `foo()`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: [], removed: [], updated: ['/out/app.js'] })\n\n      // Event 3: a new CSS file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, `import \"./app.css\"; foo()`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: ['/out/app.css'], removed: [], updated: [] })\n\n      // Event 4: edit the CSS file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(css, `a { color: red }`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: [], removed: [], updated: ['/out/app.css'] })\n\n      // Event 5: remove the CSS file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, `bar()`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: [], removed: ['/out/app.css'], updated: ['/out/app.js'] })\n\n      // Wait for the stream to end once we call \"dispose()\" below\n      endPromise = stream.waitFor('close')\n    }\n\n    finally {\n      await context.dispose();\n    }\n\n    // This stream should end once \"dispose()\" is called above\n    await endPromise\n  },\n\n  async serveWithoutServedirWatchLiveReloadPublicPath({ esbuild, testDir }) {\n    const js = path.join(testDir, 'app.js')\n    const css = path.join(testDir, 'app.css')\n    const outdir = path.join(testDir, 'out')\n    await writeFileAsync(css, ``)\n\n    let endPromise\n    const context = await esbuild.context({\n      entryPoints: [js],\n      outdir,\n      bundle: true,\n      logLevel: 'silent',\n      publicPath: 'http://example.com/about',\n    });\n\n    try {\n      const server = await context.serve({\n        host: '127.0.0.1',\n      })\n      const stream = await makeEventStream(server.hosts[0], server.port, '/esbuild')\n      await context.rebuild().then(\n        () => Promise.reject(new Error('Expected an error to be thrown')),\n        () => { /* Ignore the build error due to the missing JS file */ },\n      )\n\n      // Event 1: a new JavaScript file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, ``)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: ['http://example.com/about/app.js'], removed: [], updated: [] })\n\n      // Event 2: edit the JavaScript file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, `foo()`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: [], removed: [], updated: ['http://example.com/about/app.js'] })\n\n      // Event 3: a new CSS file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, `import \"./app.css\"; foo()`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: ['http://example.com/about/app.css'], removed: [], updated: [] })\n\n      // Event 4: edit the CSS file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(css, `a { color: red }`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: [], removed: [], updated: ['http://example.com/about/app.css'] })\n\n      // Event 5: remove the CSS file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, `bar()`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: [], removed: ['http://example.com/about/app.css'], updated: ['http://example.com/about/app.js'] })\n\n      // Wait for the stream to end once we call \"dispose()\" below\n      endPromise = stream.waitFor('close')\n    }\n\n    finally {\n      await context.dispose();\n    }\n\n    // This stream should end once \"dispose()\" is called above\n    await endPromise\n  },\n\n  async serveWithServedirWatchLiveReloadPublicPath({ esbuild, testDir }) {\n    const js = path.join(testDir, 'app.js')\n    const css = path.join(testDir, 'app.css')\n    const outdir = path.join(testDir, 'out')\n    await writeFileAsync(css, ``)\n\n    let endPromise\n    const context = await esbuild.context({\n      entryPoints: [js],\n      outdir,\n      bundle: true,\n      logLevel: 'silent',\n      publicPath: 'http://example.com/about',\n    });\n\n    try {\n      const server = await context.serve({\n        host: '127.0.0.1',\n        servedir: testDir,\n      })\n      const stream = await makeEventStream(server.hosts[0], server.port, '/esbuild')\n      await context.rebuild().then(\n        () => Promise.reject(new Error('Expected an error to be thrown')),\n        () => { /* Ignore the build error due to the missing JS file */ },\n      )\n\n      // Event 1: a new JavaScript file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, ``)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: ['http://example.com/about/out/app.js'], removed: [], updated: [] })\n\n      // Event 2: edit the JavaScript file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, `foo()`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: [], removed: [], updated: ['http://example.com/about/out/app.js'] })\n\n      // Event 3: a new CSS file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, `import \"./app.css\"; foo()`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: ['http://example.com/about/out/app.css'], removed: [], updated: [] })\n\n      // Event 4: edit the CSS file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(css, `a { color: red }`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: [], removed: [], updated: ['http://example.com/about/out/app.css'] })\n\n      // Event 5: remove the CSS file\n      var eventPromise = stream.waitFor('change')\n      await writeFileAsync(js, `bar()`)\n      await context.rebuild()\n      var data = JSON.parse((await eventPromise).data)\n      assert.deepStrictEqual(data, { added: [], removed: ['http://example.com/about/out/app.css'], updated: ['http://example.com/about/out/app.js'] })\n\n      // Wait for the stream to end once we call \"dispose()\" below\n      endPromise = stream.waitFor('close')\n    }\n\n    finally {\n      await context.dispose();\n    }\n\n    // This stream should end once \"dispose()\" is called above\n    await endPromise\n  },\n\n  async serveWithFallback({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const wwwDir = path.join(testDir, 'www')\n    const index = path.join(wwwDir, 'app', 'index.html')\n    const fallback = path.join(testDir, 'fallback.html')\n    await mkdirAsync(path.dirname(index), { recursive: true })\n    await writeFileAsync(input, `console.log(123)`)\n    await writeFileAsync(index, `<p>index</p>`)\n    await writeFileAsync(fallback, `<p>fallback</p>`)\n\n    const context = await esbuild.context({\n      entryPoints: [input],\n      format: 'esm',\n      outdir: wwwDir,\n      write: false,\n    });\n    try {\n      const result = await context.serve({\n        host: '127.0.0.1',\n        servedir: wwwDir,\n        fallback,\n      })\n      assert.deepStrictEqual(result.hosts, ['127.0.0.1']);\n      assert.strictEqual(typeof result.port, 'number');\n\n      let buffer;\n\n      buffer = await fetch(result.hosts[0], result.port, '/in.js')\n      assert.strictEqual(buffer.toString(), `console.log(123);\\n`);\n\n      buffer = await fetch(result.hosts[0], result.port, '/')\n      assert.strictEqual(buffer.toString(), `<p>fallback</p>`);\n\n      buffer = await fetch(result.hosts[0], result.port, '/app/')\n      assert.strictEqual(buffer.toString(), `<p>index</p>`);\n\n      buffer = await fetch(result.hosts[0], result.port, '/app/?foo')\n      assert.strictEqual(buffer.toString(), `<p>index</p>`);\n\n      buffer = await fetch(result.hosts[0], result.port, '/app/foo')\n      assert.strictEqual(buffer.toString(), `<p>fallback</p>`);\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveHostCheckIPv4({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, `console.log(123)`)\n\n    let onRequest;\n\n    const context = await esbuild.context({\n      entryPoints: [input],\n      format: 'esm',\n      outdir: testDir,\n      write: false,\n    });\n    try {\n      const result = await context.serve({\n        port: 0,\n        onRequest: args => onRequest(args),\n      })\n      assert(result.hosts.includes('127.0.0.1'));\n      assert.strictEqual(typeof result.port, 'number');\n\n      // GET /in.js from each host\n      for (const host of result.hosts) {\n        const singleRequestPromise = new Promise(resolve => { onRequest = resolve });\n        const buffer = await fetch(host, result.port, '/in.js')\n        assert.strictEqual(buffer.toString(), `console.log(123);\\n`);\n        assert.strictEqual(fs.readFileSync(input, 'utf8'), `console.log(123)`)\n\n        let singleRequest = await singleRequestPromise;\n        assert.strictEqual(singleRequest.method, 'GET');\n        assert.strictEqual(singleRequest.path, '/in.js');\n        assert.strictEqual(singleRequest.status, 200);\n        assert.strictEqual(typeof singleRequest.remoteAddress, 'string');\n        assert.strictEqual(typeof singleRequest.timeInMS, 'number');\n      }\n\n      // GET /in.js with a forbidden host header\n      const forbiddenHosts = [\n        'evil.com',\n        'evil.com:666',\n        '1.2.3.4',\n        '1.2.3.4:666',\n        '::1234',\n        '[::1234]:666',\n        '[',\n      ]\n      for (const forbiddenHost of forbiddenHosts) {\n        const singleRequestPromise = new Promise(resolve => { onRequest = resolve });\n        try {\n          await fetch(result.hosts[0], result.port, '/in.js', { headers: { Host: forbiddenHost } })\n        } catch {\n        }\n\n        let singleRequest = await singleRequestPromise;\n        assert.strictEqual(singleRequest.method, 'GET');\n        assert.strictEqual(singleRequest.path, '/in.js');\n        assert.strictEqual(singleRequest.status, 403, forbiddenHost); // 403 means \"Forbidden\"\n        assert.strictEqual(typeof singleRequest.remoteAddress, 'string');\n        assert.strictEqual(typeof singleRequest.timeInMS, 'number');\n      }\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveHostCheckIPv6({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, `console.log(123)`)\n\n    let onRequest;\n\n    const context = await esbuild.context({\n      entryPoints: [input],\n      format: 'esm',\n      outdir: testDir,\n      write: false,\n    });\n    try {\n      const result = await context.serve({\n        host: '::',\n        port: 0,\n        onRequest: args => onRequest(args),\n      })\n      assert(result.hosts.includes('::1'));\n      assert.strictEqual(typeof result.port, 'number');\n\n      // GET /in.js from each host\n      for (const host of result.hosts) {\n        const singleRequestPromise = new Promise(resolve => { onRequest = resolve });\n        const buffer = await fetch(host, result.port, '/in.js')\n        assert.strictEqual(buffer.toString(), `console.log(123);\\n`);\n        assert.strictEqual(fs.readFileSync(input, 'utf8'), `console.log(123)`)\n\n        let singleRequest = await singleRequestPromise;\n        assert.strictEqual(singleRequest.method, 'GET');\n        assert.strictEqual(singleRequest.path, '/in.js');\n        assert.strictEqual(singleRequest.status, 200);\n        assert.strictEqual(typeof singleRequest.remoteAddress, 'string');\n        assert.strictEqual(typeof singleRequest.timeInMS, 'number');\n      }\n\n      // GET /in.js with a forbidden host header\n      const forbiddenHosts = [\n        'evil.com',\n        'evil.com:666',\n        '1.2.3.4',\n        '1.2.3.4:666',\n        '::1234',\n        '[::1234]:666',\n        '[',\n      ]\n      for (const forbiddenHost of forbiddenHosts) {\n        const singleRequestPromise = new Promise(resolve => { onRequest = resolve });\n        try {\n          await fetch(result.hosts[0], result.port, '/in.js', { headers: { Host: forbiddenHost } })\n        } catch {\n        }\n\n        let singleRequest = await singleRequestPromise;\n        assert.strictEqual(singleRequest.method, 'GET');\n        assert.strictEqual(singleRequest.path, '/in.js');\n        assert.strictEqual(singleRequest.status, 403, forbiddenHost); // 403 means \"Forbidden\"\n        assert.strictEqual(typeof singleRequest.remoteAddress, 'string');\n        assert.strictEqual(typeof singleRequest.timeInMS, 'number');\n      }\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveCORSNoOrigins({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, `console.log(123)`)\n\n    const context = await esbuild.context({\n      entryPoints: [input],\n      format: 'esm',\n      outdir: testDir,\n      write: false,\n    });\n    try {\n      const result = await context.serve({\n        port: 0,\n        cors: {},\n      })\n      assert(result.hosts.length > 0);\n      assert.strictEqual(typeof result.port, 'number');\n\n      // There should be no CORS header\n      const origin = 'https://example.com'\n      const buffer = await fetch(result.hosts[0], result.port, '/in.js', { headers: { Origin: origin } })\n      assert.strictEqual(buffer.toString(), `console.log(123);\\n`);\n      assert.strictEqual(fs.readFileSync(input, 'utf8'), `console.log(123)`)\n      assert.strictEqual(buffer.headers['access-control-allow-origin'], undefined)\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveCORSAllOrigins({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, `console.log(123)`)\n\n    const context = await esbuild.context({\n      entryPoints: [input],\n      format: 'esm',\n      outdir: testDir,\n      write: false,\n    });\n    try {\n      const result = await context.serve({\n        port: 0,\n        cors: { origin: '*' },\n      })\n      assert(result.hosts.length > 0);\n      assert.strictEqual(typeof result.port, 'number');\n\n      // There should be a CORS header allowing all origins\n      const origin = 'https://example.com'\n      const buffer = await fetch(result.hosts[0], result.port, '/in.js', { headers: { Origin: origin } })\n      assert.strictEqual(buffer.toString(), `console.log(123);\\n`);\n      assert.strictEqual(fs.readFileSync(input, 'utf8'), `console.log(123)`)\n      assert.strictEqual(buffer.headers['access-control-allow-origin'], '*')\n    } finally {\n      await context.dispose();\n    }\n  },\n\n  async serveCORSSpecificOrigins({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, `console.log(123)`)\n\n    const context = await esbuild.context({\n      entryPoints: [input],\n      format: 'esm',\n      outdir: testDir,\n      write: false,\n    });\n    try {\n      const result = await context.serve({\n        port: 0,\n        cors: {\n          origin: [\n            'http://example.com',\n            'http://foo.example.com',\n            'https://*.example.com',\n          ],\n        },\n      })\n      assert(result.hosts.length > 0);\n      assert.strictEqual(typeof result.port, 'number');\n\n      const allowedOrigins = [\n        'http://example.com',\n        'http://foo.example.com',\n        'https://bar.example.com',\n      ]\n\n      const forbiddenOrigins = [\n        'http://bar.example.com',\n        'https://example.com',\n        'http://evil.com',\n        'https://evil.com',\n      ]\n\n      // GET /in.js from each allowed origin\n      for (const origin of allowedOrigins) {\n        const buffer = await fetch(result.hosts[0], result.port, '/in.js', { headers: { Origin: origin } })\n        assert.strictEqual(buffer.toString(), `console.log(123);\\n`);\n        assert.strictEqual(fs.readFileSync(input, 'utf8'), `console.log(123)`)\n        assert.strictEqual(buffer.headers['access-control-allow-origin'], origin)\n      }\n\n      // GET /in.js from each forbidden origin\n      for (const origin of forbiddenOrigins) {\n        const buffer = await fetch(result.hosts[0], result.port, '/in.js', { headers: { Origin: origin } })\n        assert.strictEqual(buffer.toString(), `console.log(123);\\n`);\n        assert.strictEqual(fs.readFileSync(input, 'utf8'), `console.log(123)`)\n        assert.strictEqual(buffer.headers['access-control-allow-origin'], undefined)\n      }\n    } finally {\n      await context.dispose();\n    }\n  },\n}\n\nasync function futureSyntax(esbuild, js, targetBelow, targetAbove) {\n  failure: {\n    try { await esbuild.transform(js, { target: targetBelow }) }\n    catch { break failure }\n    throw new Error(`Expected failure for ${targetBelow}: ${js}`)\n  }\n\n  try { await esbuild.transform(js, { target: targetAbove }) }\n  catch (e) { throw new Error(`Expected success for ${targetAbove}: ${js}\\n${e}`) }\n}\n\nlet transformTests = {\n  async transformWithNonString({ esbuild }) {\n    try {\n      await esbuild.transform(Object.create({ toString() { return '1+2' } }))\n      throw new Error('Expected an error to be thrown');\n    } catch (e) {\n      assert.strictEqual(e.errors ? e.errors[0].text : e + '', 'The input to \"transform\" must be a string or a Uint8Array')\n    }\n  },\n\n  async version({ esbuild }) {\n    const version = fs.readFileSync(path.join(repoDir, 'version.txt'), 'utf8').trim()\n    assert.strictEqual(esbuild.version, version);\n  },\n\n  async ignoreUndefinedOptions({ esbuild }) {\n    // This should not throw\n    await esbuild.transform(``, { jsxFactory: void 0 })\n  },\n\n  async throwOnBadOptions({ esbuild }) {\n    // This should throw\n    try {\n      await esbuild.transform(``, { jsxFactory: ['React', 'createElement'] })\n      throw new Error('Expected transform failure');\n    } catch (e) {\n      if (!e.errors || !e.errors[0] || e.errors[0].text !== '\"jsxFactory\" must be a string') {\n        throw e;\n      }\n    }\n  },\n\n  async transformLoaderBase64({ esbuild }) {\n    // UTF-16\n    var result = await esbuild.transform(`\\xFF`, { loader: 'base64' })\n    assert.strictEqual(result.code, `module.exports = \"w78=\";\\n`)\n\n    // Binary\n    var result = await esbuild.transform(new Uint8Array([0xFF]), { loader: 'base64' })\n    assert.strictEqual(result.code, `module.exports = \"/w==\";\\n`)\n  },\n\n  async avoidTDZ({ esbuild }) {\n    var { code } = await esbuild.transform(`\n      class Foo {\n        // The above line will be transformed into \"var\". However, the\n        // symbol \"Foo\" must still be defined before the class body ends.\n        static foo = new Foo\n      }\n      if (!(Foo.foo instanceof Foo))\n        throw 'fail'\n    `)\n    new Function(code)()\n  },\n\n  async tsAvoidTDZ({ esbuild }) {\n    var { code } = await esbuild.transform(`\n      class Foo {\n        // The above line will be transformed into \"var\". However, the\n        // symbol \"Foo\" must still be defined before the class body ends.\n        static foo = new Foo\n      }\n      if (!(Foo.foo instanceof Foo))\n        throw 'fail'\n    `, {\n      loader: 'ts',\n    })\n    new Function(code)()\n  },\n\n  // Note: The TypeScript compiler's transformer doesn't handle this case.\n  // Using \"this\" like this is a syntax error instead. However, we can handle\n  // it without too much trouble so we handle it here. This is defensive in\n  // case the TypeScript compiler team fixes this in the future.\n  async tsAvoidTDZThis({ esbuild }) {\n    var { code } = await esbuild.transform(`\n      class Foo {\n        static foo = 123\n        static bar = this.foo // \"this\" must be rewritten when the property is relocated\n      }\n      if (Foo.bar !== 123) throw 'fail'\n    `, {\n      loader: 'ts',\n      tsconfigRaw: {\n        compilerOptions: {\n          useDefineForClassFields: false,\n        },\n      },\n    })\n    new Function(code)()\n  },\n\n  async tsDecoratorAvoidTDZ({ esbuild }) {\n    var { code } = await esbuild.transform(`\n      class Bar {}\n      var oldFoo\n      function swap(target) {\n        oldFoo = target\n        return Bar\n      }\n      @swap\n      class Foo {\n        bar() { return new Foo }\n        static foo = new Foo\n      }\n      if (!(oldFoo.foo instanceof oldFoo))\n        throw 'fail: foo'\n      if (!(oldFoo.foo.bar() instanceof Bar))\n        throw 'fail: bar'\n    `, {\n      loader: 'ts',\n      tsconfigRaw: {\n        compilerOptions: {\n          useDefineForClassFields: false,\n          experimentalDecorators: true,\n        },\n      },\n    })\n    new Function(code)()\n  },\n\n  async mangleQuotedTransform({ esbuild }) {\n    var { code } = await esbuild.transform(`x.foo_ = 'foo_' in x`, {\n      mangleProps: /_/,\n      mangleQuoted: true,\n    })\n    assert.strictEqual(code, 'x.a = \"a\" in x;\\n')\n  },\n\n  async mangleCacheTransform({ esbuild }) {\n    var { code, mangleCache } = await esbuild.transform(`x = { x_: 0, y_: 1, z_: 2 }`, {\n      mangleProps: /_/,\n      mangleCache: { x_: 'FIXED', z_: false },\n    })\n    assert.strictEqual(code, 'x = { FIXED: 0, a: 1, z_: 2 };\\n')\n    assert.deepStrictEqual(mangleCache, { x_: 'FIXED', y_: 'a', z_: false })\n  },\n\n  async jsBannerTransform({ esbuild }) {\n    var { code } = await esbuild.transform(`\n      if (!bannerDefined) throw 'fail'\n    `, {\n      banner: 'const bannerDefined = true',\n    })\n    new Function(code)()\n  },\n\n  async jsFooterTransform({ esbuild }) {\n    var { code } = await esbuild.transform(`\n      footer()\n    `, {\n      footer: 'function footer() {}',\n    })\n    new Function(code)()\n    new Function(code)()\n  },\n\n  async jsBannerFooterTransform({ esbuild }) {\n    var { code } = await esbuild.transform(`\n      return { banner: bannerDefined, footer };\n    `, {\n      banner: 'const bannerDefined = true',\n      footer: 'function footer() {}',\n    })\n    const result = new Function(code)()\n    if (!result.banner) throw 'fail'\n    result.footer()\n  },\n\n  async cssBannerFooterTransform({ esbuild }) {\n    for (const loader of ['css', 'local-css', 'global-css']) {\n      var { code } = await esbuild.transform(`\n        div { color: red }\n      `, {\n        loader,\n        banner: '/* banner */',\n        footer: '/* footer */',\n      })\n      assert.strictEqual(code, `/* banner */\\ndiv {\\n  color: red;\\n}\\n/* footer */\\n`)\n    }\n  },\n\n  async transformDirectEval({ esbuild }) {\n    var { code } = await esbuild.transform(`\n      export let abc = 123\n      eval('console.log(abc)')\n    `, {\n      minify: true,\n    })\n    assert.strictEqual(code, `export let abc=123;eval(\"console.log(abc)\");\\n`)\n  },\n\n  async tsconfigRawImportsNotUsedAsValuesDefault({ esbuild }) {\n    const { code } = await esbuild.transform(`import {T} from 'path'`, {\n      tsconfigRaw: {\n        compilerOptions: {},\n      },\n      loader: 'ts',\n    })\n    assert.strictEqual(code, ``)\n  },\n\n  async tsconfigRawImportsNotUsedAsValuesRemove({ esbuild }) {\n    const { code } = await esbuild.transform(`import {T} from 'path'`, {\n      tsconfigRaw: {\n        compilerOptions: {\n          importsNotUsedAsValues: 'remove',\n        },\n      },\n      loader: 'ts',\n    })\n    assert.strictEqual(code, ``)\n  },\n\n  async tsconfigRawImportsNotUsedAsValuesPreserve({ esbuild }) {\n    const { code } = await esbuild.transform(`import {T} from 'path'`, {\n      tsconfigRaw: {\n        compilerOptions: {\n          importsNotUsedAsValues: 'preserve',\n        },\n      },\n      loader: 'ts',\n    })\n    assert.strictEqual(code, `import \"path\";\\n`)\n  },\n\n  async tsconfigRawImportsNotUsedAsValuesError({ esbuild }) {\n    const { code } = await esbuild.transform(`import {T} from 'path'`, {\n      tsconfigRaw: {\n        compilerOptions: {\n          importsNotUsedAsValues: 'error',\n        },\n      },\n      loader: 'ts',\n    })\n    assert.strictEqual(code, `import \"path\";\\n`)\n  },\n\n  async tsconfigRawImportsNotUsedAsValuesRemoveJS({ esbuild }) {\n    const { code } = await esbuild.transform(`import {T} from 'path'`, {\n      tsconfigRaw: {\n        compilerOptions: {\n          importsNotUsedAsValues: 'remove',\n        },\n      },\n    })\n    assert.strictEqual(code, `import { T } from \"path\";\\n`)\n  },\n\n  async tsconfigRawImportsNotUsedAsValuesPreserveJS({ esbuild }) {\n    const { code } = await esbuild.transform(`import {T} from 'path'`, {\n      tsconfigRaw: {\n        compilerOptions: {\n          importsNotUsedAsValues: 'preserve',\n        },\n      },\n    })\n    assert.strictEqual(code, `import { T } from \"path\";\\n`)\n  },\n\n  async tsconfigRawPreserveValueImportsDefault({ esbuild }) {\n    const { code } = await esbuild.transform(`import {T} from 'path'`, {\n      tsconfigRaw: {\n        compilerOptions: {},\n      },\n      loader: 'ts',\n    })\n    assert.strictEqual(code, ``)\n  },\n\n  async tsconfigRawPreserveValueImportsFalse({ esbuild }) {\n    const { code } = await esbuild.transform(`import {T} from 'path'`, {\n      tsconfigRaw: {\n        compilerOptions: {\n          preserveValueImports: false,\n        },\n      },\n      loader: 'ts',\n    })\n    assert.strictEqual(code, ``)\n  },\n\n  async tsconfigRawPreserveValueImportsTrue({ esbuild }) {\n    const { code } = await esbuild.transform(`import {T} from 'path'`, {\n      tsconfigRaw: {\n        compilerOptions: {\n          preserveValueImports: true,\n        },\n      },\n      loader: 'ts',\n    })\n    assert.strictEqual(code, `import { T } from \"path\";\\n`)\n  },\n\n  async tsconfigRawPreserveValueImportsTrueMinifyIdentifiers({ esbuild }) {\n    const { code } = await esbuild.transform(`import {T} from 'path'`, {\n      tsconfigRaw: {\n        compilerOptions: {\n          preserveValueImports: true,\n        },\n      },\n      loader: 'ts',\n      minifyIdentifiers: true,\n    })\n    assert.strictEqual(code, `import \"path\";\\n`)\n  },\n\n  async tsconfigRawPreserveValueImportsTrueImportsNotUsedAsValuesRemove({ esbuild }) {\n    const { code } = await esbuild.transform(`import {T} from 'path'`, {\n      tsconfigRaw: {\n        compilerOptions: {\n          importsNotUsedAsValues: 'remove',\n          preserveValueImports: true,\n        },\n      },\n      loader: 'ts',\n    })\n    assert.strictEqual(code, `import { T } from \"path\";\\n`)\n  },\n\n  async tsconfigRawCommentsInJSON({ esbuild }) {\n    // Can use a string, which allows weird TypeScript pseudo-JSON with comments and trailing commas\n    const { code: code5 } = await esbuild.transform(`import {T} from 'path'`, {\n      tsconfigRaw: `{\n        \"compilerOptions\": {\n          \"preserveValueImports\": true, // there is a trailing comment here\n        },\n      }`,\n      loader: 'ts',\n    })\n    assert.strictEqual(code5, `import { T } from \"path\";\\n`)\n  },\n\n  async tsconfigRawUseDefineForClassFields({ esbuild }) {\n    const { code: code1 } = await esbuild.transform(`class Foo { foo }`, {\n      tsconfigRaw: {\n        compilerOptions: {\n          useDefineForClassFields: false,\n        },\n      },\n      loader: 'ts',\n    })\n    assert.strictEqual(code1, `class Foo {\\n}\\n`)\n\n    const { code: code2 } = await esbuild.transform(`class Foo { foo }`, {\n      tsconfigRaw: {\n        compilerOptions: {\n          useDefineForClassFields: true,\n        },\n      },\n      loader: 'ts',\n    })\n    assert.strictEqual(code2, `class Foo {\\n  foo;\\n}\\n`)\n  },\n\n  async tsconfigRawAlwaysStrict({ esbuild }) {\n    const input = `console.log(123)`\n\n    assert.strictEqual((await esbuild.transform(input, { loader: 'ts', tsconfigRaw: { compilerOptions: { strict: false } } })).code, `console.log(123);\\n`)\n    assert.strictEqual((await esbuild.transform(input, { loader: 'ts', tsconfigRaw: { compilerOptions: { alwaysStrict: false } } })).code, `console.log(123);\\n`)\n    assert.strictEqual((await esbuild.transform(input, { loader: 'ts', tsconfigRaw: { compilerOptions: { alwaysStrict: false, strict: true } } })).code, `console.log(123);\\n`)\n\n    assert.strictEqual((await esbuild.transform(input, { loader: 'ts', tsconfigRaw: { compilerOptions: { strict: true } } })).code, `\"use strict\";\\nconsole.log(123);\\n`)\n    assert.strictEqual((await esbuild.transform(input, { loader: 'ts', tsconfigRaw: { compilerOptions: { alwaysStrict: true } } })).code, `\"use strict\";\\nconsole.log(123);\\n`)\n    assert.strictEqual((await esbuild.transform(input, { loader: 'ts', tsconfigRaw: { compilerOptions: { alwaysStrict: true, strict: false } } })).code, `\"use strict\";\\nconsole.log(123);\\n`)\n  },\n\n  async tsconfigRawTarget({ esbuild }) {\n    // The \"target\" from \"tsconfig.json\" should not apply, but esbuild's \"target\" should apply\n\n    assert.strictEqual((await esbuild.transform('x => x', { loader: 'ts', tsconfigRaw: { compilerOptions: { target: 'ES6' } } })).code, `(x) => x;\\n`)\n    assert.strictEqual((await esbuild.transform('x => x', { loader: 'ts', tsconfigRaw: { compilerOptions: { target: 'ES5' } } })).code, `(x) => x;\\n`)\n\n    assert.strictEqual((await esbuild.transform('x => x', { loader: 'ts', target: 'es6' })).code, `(x) => x;\\n`)\n    assert.strictEqual((await esbuild.transform('x => x', { loader: 'ts', target: 'es5' })).code, `(function(x) {\\n  return x;\\n});\\n`)\n\n    assert.strictEqual((await esbuild.transform('x => x', { loader: 'ts', target: 'es5', tsconfigRaw: { compilerOptions: { target: 'ES6' } } })).code, `(function(x) {\\n  return x;\\n});\\n`)\n    assert.strictEqual((await esbuild.transform('x => x', { loader: 'ts', target: 'es6', tsconfigRaw: { compilerOptions: { target: 'ES5' } } })).code, `(x) => x;\\n`)\n  },\n\n  async tsconfigRawExtends({ esbuild }) {\n    // Uses of \"extends\" in \"tsconfigRaw\" should be ignored for the transform API\n    const result = await esbuild.transform('let foo: bar', {\n      loader: 'ts',\n      logOverride: { 'tsconfig.json': 'error' },\n      tsconfigRaw: {\n        extends: __filename,\n      },\n    })\n    assert.strictEqual(result.code, `let foo;\\n`)\n  },\n\n  async tsImplicitUseDefineForClassFields({ esbuild }) {\n    var { code } = await esbuild.transform(`class Foo { foo }`, {\n      loader: 'ts',\n    })\n    assert.strictEqual(code, `class Foo {\\n  foo;\\n}\\n`)\n\n    var { code } = await esbuild.transform(`class Foo { foo }`, {\n      target: 'es2021',\n      loader: 'ts',\n    })\n    assert.strictEqual(code, `var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nclass Foo {\n  constructor() {\n    __publicField(this, \"foo\");\n  }\n}\n`)\n\n    var { code } = await esbuild.transform(`class Foo { foo }`, {\n      target: 'es2022',\n      loader: 'ts',\n    })\n    assert.strictEqual(code, `class Foo {\\n  foo;\\n}\\n`)\n\n    var { code } = await esbuild.transform(`class Foo { foo }`, {\n      target: 'esnext',\n      loader: 'ts',\n    })\n    assert.strictEqual(code, `class Foo {\\n  foo;\\n}\\n`)\n  },\n\n  async tsconfigRawJSX({ esbuild }) {\n    const { code: code1 } = await esbuild.transform(`<><div/></>`, {\n      tsconfigRaw: {\n        compilerOptions: {\n        },\n      },\n      loader: 'jsx',\n    })\n    assert.strictEqual(code1, `/* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(\"div\", null));\\n`)\n\n    const { code: code2 } = await esbuild.transform(`<><div/></>`, {\n      tsconfigRaw: {\n        compilerOptions: {\n          jsxFactory: 'factory',\n          jsxFragmentFactory: 'fragment',\n        },\n      },\n      loader: 'jsx',\n    })\n    assert.strictEqual(code2, `/* @__PURE__ */ factory(fragment, null, /* @__PURE__ */ factory(\"div\", null));\\n`)\n\n    const { code: code3 } = await esbuild.transform(`<><div/></>`, {\n      tsconfigRaw: {\n        compilerOptions: {\n          jsx: 'react-jsx'\n        },\n      },\n      loader: 'jsx',\n    })\n    assert.strictEqual(code3, `import { Fragment, jsx } from \"react/jsx-runtime\";\\n/* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(\"div\", {}) });\\n`)\n\n    const { code: code4 } = await esbuild.transform(`<><div/></>`, {\n      tsconfigRaw: {\n        compilerOptions: {\n          jsx: 'react-jsx',\n          jsxImportSource: 'notreact'\n        },\n      },\n      loader: 'jsx',\n    })\n    assert.strictEqual(code4, `import { Fragment, jsx } from \"notreact/jsx-runtime\";\\n/* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(\"div\", {}) });\\n`)\n\n    const { code: code5 } = await esbuild.transform(`<><div/></>`, {\n      tsconfigRaw: {\n        compilerOptions: {\n          jsx: 'react-jsxdev'\n        },\n      },\n      loader: 'jsx',\n    })\n    assert.strictEqual(code5, `import { Fragment, jsxDEV } from \"react/jsx-dev-runtime\";\\n/* @__PURE__ */ jsxDEV(Fragment, { children: /* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\\n  fileName: \"<stdin>\",\\n  lineNumber: 1,\\n  columnNumber: 3\\n}, this) }, void 0, false, {\\n  fileName: \"<stdin>\",\\n  lineNumber: 1,\\n  columnNumber: 1\\n}, this);\\n`)\n  },\n\n  // Note: tree shaking is disabled when the output format isn't IIFE\n  async treeShakingDefault({ esbuild }) {\n    const { code } = await esbuild.transform(`\n      var unused = 123\n      var used = 234\n      export { used }\n    `, {\n      loader: 'jsx',\n      format: 'esm',\n      treeShaking: undefined,\n    })\n    assert.strictEqual(code, `var unused = 123;\\nvar used = 234;\\nexport {\\n  used\\n};\\n`)\n  },\n\n  async treeShakingFalse({ esbuild }) {\n    const { code } = await esbuild.transform(`\n      var unused = 123\n      var used = 234\n      export { used }\n    `, {\n      loader: 'jsx',\n      format: 'esm',\n      treeShaking: false,\n    })\n    assert.strictEqual(code, `var unused = 123;\\nvar used = 234;\\nexport {\\n  used\\n};\\n`)\n  },\n\n  async treeShakingTrue({ esbuild }) {\n    const { code } = await esbuild.transform(`\n      var unused = 123\n      var used = 234\n      export { used }\n    `, {\n      loader: 'jsx',\n      format: 'esm',\n      treeShaking: true,\n    })\n    assert.strictEqual(code, `var used = 234;\\nexport {\\n  used\\n};\\n`)\n  },\n\n  // Note: tree shaking is enabled when the output format is IIFE\n  async treeShakingDefaultIIFE({ esbuild }) {\n    const { code } = await esbuild.transform(`var unused = 123`, {\n      loader: 'jsx',\n      format: 'iife',\n      treeShaking: undefined,\n    })\n    assert.strictEqual(code, `(() => {\\n})();\\n`)\n  },\n\n  async treeShakingFalseIIFE({ esbuild }) {\n    const { code } = await esbuild.transform(`var unused = 123`, {\n      loader: 'jsx',\n      format: 'iife',\n      treeShaking: false,\n    })\n    assert.strictEqual(code, `(() => {\\n  var unused = 123;\\n})();\\n`)\n  },\n\n  async treeShakingTrueIIFE({ esbuild }) {\n    const { code } = await esbuild.transform(`var unused = 123`, {\n      loader: 'jsx',\n      format: 'iife',\n      treeShaking: true,\n    })\n    assert.strictEqual(code, `(() => {\\n})();\\n`)\n  },\n\n  async ignoreAnnotationsDefault({ esbuild }) {\n    const { code } = await esbuild.transform(`/* @__PURE__ */ fn(); <div/>`, {\n      loader: 'jsx',\n      minifySyntax: true,\n    })\n    assert.strictEqual(code, ``)\n  },\n\n  async ignoreAnnotationsFalse({ esbuild }) {\n    const { code } = await esbuild.transform(`/* @__PURE__ */ fn(); <div/>`, {\n      loader: 'jsx',\n      minifySyntax: true,\n      ignoreAnnotations: false,\n    })\n    assert.strictEqual(code, ``)\n  },\n\n  async ignoreAnnotationsTrue({ esbuild }) {\n    const { code } = await esbuild.transform(`/* @__PURE__ */ fn(); <div/>`, {\n      loader: 'jsx',\n      minifySyntax: true,\n      ignoreAnnotations: true,\n    })\n    assert.strictEqual(code, `fn(), React.createElement(\"div\", null);\\n`)\n  },\n\n  async jsCharsetDefault({ esbuild }) {\n    const { code } = await esbuild.transform(`let π = 'π'`, {})\n    assert.strictEqual(code, `let \\\\u03C0 = \"\\\\u03C0\";\\n`)\n  },\n\n  async jsCharsetASCII({ esbuild }) {\n    const { code } = await esbuild.transform(`let π = 'π'`, { charset: 'ascii' })\n    assert.strictEqual(code, `let \\\\u03C0 = \"\\\\u03C0\";\\n`)\n  },\n\n  async jsCharsetUTF8({ esbuild }) {\n    const { code } = await esbuild.transform(`let π = 'π'`, { charset: 'utf8' })\n    assert.strictEqual(code, `let π = \"π\";\\n`)\n  },\n\n  async cssCharsetDefault({ esbuild }) {\n    const { code } = await esbuild.transform(`.π:after { content: 'π' }`, { loader: 'css' })\n    assert.strictEqual(code, `.\\\\3c0:after {\\n  content: \"\\\\3c0\";\\n}\\n`)\n  },\n\n  async cssCharsetASCII({ esbuild }) {\n    const { code } = await esbuild.transform(`.π:after { content: 'π' }`, { loader: 'css', charset: 'ascii' })\n    assert.strictEqual(code, `.\\\\3c0:after {\\n  content: \"\\\\3c0\";\\n}\\n`)\n  },\n\n  async cssCharsetUTF8({ esbuild }) {\n    const { code } = await esbuild.transform(`.π:after { content: 'π' }`, { loader: 'css', charset: 'utf8' })\n    assert.strictEqual(code, `.π:after {\\n  content: \"π\";\\n}\\n`)\n  },\n\n  async cssSyntaxErrorWarning({ esbuild }) {\n    const { code } = await esbuild.transform(`. {}`, { loader: 'css' })\n    assert.strictEqual(code, `. {\\n}\\n`)\n  },\n\n  async cssSyntaxErrorWarningOverride({ esbuild }) {\n    try {\n      await esbuild.transform(`. {}`, { loader: 'css', logOverride: { 'css-syntax-error': 'error' } })\n      throw new Error('Expected a transform failure')\n    } catch (e) {\n      assert.strictEqual((e && e.message || e) + '', `Transform failed with 1 error:\\n<stdin>:1:1: ERROR: Expected identifier but found whitespace`)\n    }\n  },\n\n  async cssMinify({ esbuild }) {\n    const { code } = await esbuild.transform(`div { color: #abcd }`, { loader: 'css', minify: true })\n    assert.strictEqual(code, `div{color:#abcd}\\n`)\n  },\n\n  // Using an \"es\" target shouldn't affect CSS\n  async cssMinifyTargetES6({ esbuild }) {\n    const { code } = await esbuild.transform(`div { color: #abcd }`, { loader: 'css', minify: true, target: 'es6' })\n    assert.strictEqual(code, `div{color:#abcd}\\n`)\n  },\n\n  // Using a \"node\" target shouldn't affect CSS\n  async cssMinifyTargetNode({ esbuild }) {\n    const { code } = await esbuild.transform(`div { color: #abcd }`, { loader: 'css', minify: true, target: 'node8' })\n    assert.strictEqual(code, `div{color:#abcd}\\n`)\n  },\n\n  // Using an older browser target should affect CSS\n  async cssMinifyTargetChrome8({ esbuild }) {\n    const { code } = await esbuild.transform(`div { color: #abcd }`, { loader: 'css', minify: true, target: 'chrome8' })\n    assert.strictEqual(code, `div{color:rgba(170,187,204,.867)}\\n`)\n  },\n\n  // Using a newer browser target shouldn't affect CSS\n  async cssMinifyTargetChrome80({ esbuild }) {\n    const { code } = await esbuild.transform(`div { color: #abcd }`, { loader: 'css', minify: true, target: 'chrome80' })\n    assert.strictEqual(code, `div{color:#abcd}\\n`)\n  },\n\n  async cssNestingExpansionLimitWithoutIs({ esbuild }) {\n    const css = `a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{color:red}}}}}}}}}}}}}}}}}}}}`\n    try {\n      await esbuild.transform(css, { loader: 'css', target: 'safari1' })\n      throw new Error('Expected a transform failure')\n    } catch (e) {\n      assert.strictEqual(e.errors.length, 1)\n      assert.strictEqual(e.errors[0].text, 'CSS nesting is causing too much expansion')\n    }\n  },\n\n  async cssNestingExpansionLimitWithIs({ esbuild }) {\n    const css = `a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{color:red}}}}}}}}}}}}}}}}}}}}`\n    try {\n      await esbuild.transform(css, { loader: 'css', target: 'safari14' })\n      throw new Error('Expected a transform failure')\n    } catch (e) {\n      assert.strictEqual(e.errors.length, 1)\n      assert.strictEqual(e.errors[0].text, 'CSS nesting is causing too much expansion')\n    }\n  },\n\n  async cjs_require({ esbuild }) {\n    const { code } = await esbuild.transform(`const {foo} = require('path')`, {})\n    assert.strictEqual(code, `const { foo } = require(\"path\");\\n`)\n  },\n\n  async cjs_exports({ esbuild }) {\n    const { code } = await esbuild.transform(`exports.foo = 123`, {})\n    assert.strictEqual(code, `exports.foo = 123;\\n`)\n  },\n\n  async es6_import({ esbuild }) {\n    const { code } = await esbuild.transform(`import {foo} from 'path'`, {})\n    assert.strictEqual(code, `import { foo } from \"path\";\\n`)\n  },\n\n  async es6_export({ esbuild }) {\n    const { code } = await esbuild.transform(`export const foo = 123`, {})\n    assert.strictEqual(code, `export const foo = 123;\\n`)\n  },\n\n  async es6_import_to_iife({ esbuild }) {\n    const { code } = await esbuild.transform(`import {exists} from \"fs\"; if (!exists) throw 'fail'`, { format: 'iife' })\n    new Function('require', code)(require)\n  },\n\n  async es6_import_star_to_iife({ esbuild }) {\n    const { code } = await esbuild.transform(`import * as fs from \"fs\"; if (!fs.exists) throw 'fail'`, { format: 'iife' })\n    new Function('require', code)(require)\n  },\n\n  async es6_export_to_iife({ esbuild }) {\n    const { code } = await esbuild.transform(`export {exists} from \"fs\"`, { format: 'iife', globalName: 'out' })\n    const out = new Function('require', code + ';return out')(require)\n    if (out.exists !== fs.exists) throw 'fail'\n  },\n\n  async es6_export_star_to_iife({ esbuild }) {\n    const { code } = await esbuild.transform(`export * from \"fs\"`, { format: 'iife', globalName: 'out' })\n    const out = new Function('require', code + ';return out')(require)\n    if (out.exists !== fs.exists) throw 'fail'\n  },\n\n  async es6_export_star_as_to_iife({ esbuild }) {\n    const { code } = await esbuild.transform(`export * as fs from \"fs\"`, { format: 'iife', globalName: 'out' })\n    const out = new Function('require', code + ';return out')(require)\n    if (out.fs.exists !== fs.exists) throw 'fail'\n  },\n\n  async es6_import_to_cjs({ esbuild }) {\n    const { code } = await esbuild.transform(`import {exists} from \"fs\"; if (!exists) throw 'fail'`, { format: 'cjs' })\n    new Function('require', code)(require)\n  },\n\n  async es6_import_star_to_cjs({ esbuild }) {\n    const { code } = await esbuild.transform(`import * as fs from \"fs\"; if (!fs.exists) throw 'fail'`, { format: 'cjs' })\n    new Function('require', code)(require)\n  },\n\n  async es6_export_to_cjs({ esbuild }) {\n    const { code } = await esbuild.transform(`export {exists} from \"fs\"`, { format: 'cjs' })\n    const module = { exports: {} }\n    new Function('module', 'exports', 'require', code)(module, module.exports, require)\n    if (module.exports.exists !== fs.exists) throw 'fail'\n  },\n\n  async es6_export_star_to_cjs({ esbuild }) {\n    const { code } = await esbuild.transform(`export * from \"fs\"`, { format: 'cjs' })\n    const module = { exports: {} }\n    new Function('module', 'exports', 'require', code)(module, module.exports, require)\n    if (module.exports.exists !== fs.exists) throw 'fail'\n  },\n\n  async es6_export_star_as_to_cjs({ esbuild }) {\n    const { code } = await esbuild.transform(`export * as fs from \"fs\"`, { format: 'cjs' })\n    const module = { exports: {} }\n    new Function('module', 'exports', 'require', code)(module, module.exports, require)\n    if (module.exports.fs.exists !== fs.exists) throw 'fail'\n  },\n\n  async es6_import_to_esm({ esbuild }) {\n    const { code } = await esbuild.transform(`import {exists} from \"fs\"; if (!exists) throw 'fail'`, { format: 'esm' })\n    assert.strictEqual(code, `import { exists } from \"fs\";\\nif (!exists) throw \"fail\";\\n`)\n  },\n\n  async es6_import_star_to_esm({ esbuild }) {\n    const { code } = await esbuild.transform(`import * as fs from \"fs\"; if (!fs.exists) throw 'fail'`, { format: 'esm' })\n    assert.strictEqual(code, `import * as fs from \"fs\";\\nif (!fs.exists) throw \"fail\";\\n`)\n  },\n\n  async es6_export_to_esm({ esbuild }) {\n    const { code } = await esbuild.transform(`export {exists} from \"fs\"`, { format: 'esm' })\n    assert.strictEqual(code, `import { exists } from \"fs\";\\nexport {\\n  exists\\n};\\n`)\n  },\n\n  async es6_export_star_to_esm({ esbuild }) {\n    const { code } = await esbuild.transform(`export * from \"fs\"`, { format: 'esm' })\n    assert.strictEqual(code, `export * from \"fs\";\\n`)\n  },\n\n  async es6_export_star_as_to_esm({ esbuild }) {\n    const { code } = await esbuild.transform(`export * as fs from \"fs\"`, { format: 'esm' })\n    assert.strictEqual(code, `import * as fs from \"fs\";\\nexport {\\n  fs\\n};\\n`)\n  },\n\n  async iifeGlobalName({ esbuild }) {\n    const { code } = await esbuild.transform(`export default 123`, { format: 'iife', globalName: 'testName' })\n    const globals = {}\n    vm.createContext(globals)\n    vm.runInContext(code, globals)\n    assert.strictEqual(globals.testName.default, 123)\n  },\n\n  async iifeGlobalNameCompound({ esbuild }) {\n    const { code } = await esbuild.transform(`export default 123`, { format: 'iife', globalName: 'test.name' })\n    const globals = {}\n    vm.createContext(globals)\n    vm.runInContext(code, globals)\n    assert.strictEqual(globals.test.name.default, 123)\n  },\n\n  async iifeGlobalNameString({ esbuild }) {\n    const { code } = await esbuild.transform(`export default 123`, { format: 'iife', globalName: 'test[\"some text\"]' })\n    const globals = {}\n    vm.createContext(globals)\n    vm.runInContext(code, globals)\n    assert.strictEqual(globals.test['some text'].default, 123)\n  },\n\n  async iifeGlobalNameUnicodeEscape({ esbuild }) {\n    const { code } = await esbuild.transform(`export default 123`, { format: 'iife', globalName: 'π[\"π 𐀀\"].𐀀[\"𐀀 π\"]' })\n    const globals = {}\n    vm.createContext(globals)\n    vm.runInContext(code, globals)\n    assert.strictEqual(globals.π[\"π 𐀀\"].𐀀[\"𐀀 π\"].default, 123)\n    assert.strictEqual(code.slice(0, code.indexOf('(() => {\\n')), `var \\\\u03C0;\n(((\\\\u03C0 ||= {})[\"\\\\u03C0 \\\\uD800\\\\uDC00\"] ||= {})[\"\\\\uD800\\\\uDC00\"] ||= {})[\"\\\\uD800\\\\uDC00 \\\\u03C0\"] = `)\n  },\n\n  async iifeGlobalNameUnicodeNoEscape({ esbuild }) {\n    const { code } = await esbuild.transform(`export default 123`, { format: 'iife', globalName: 'π[\"π 𐀀\"].𐀀[\"𐀀 π\"]', charset: 'utf8' })\n    const globals = {}\n    vm.createContext(globals)\n    vm.runInContext(code, globals)\n    assert.strictEqual(globals.π[\"π 𐀀\"].𐀀[\"𐀀 π\"].default, 123)\n    assert.strictEqual(code.slice(0, code.indexOf('(() => {\\n')), `var π;\n(((π ||= {})[\"π 𐀀\"] ||= {})[\"𐀀\"] ||= {})[\"𐀀 π\"] = `)\n  },\n\n  async iifeGlobalNameUnicodeEscapeNoLogicalAssignment({ esbuild }) {\n    const { code } = await esbuild.transform(`export default 123`, { format: 'iife', globalName: 'π[\"π 𐀀\"].𐀀[\"𐀀 π\"]', supported: { 'logical-assignment': false } })\n    const globals = {}\n    vm.createContext(globals)\n    vm.runInContext(code, globals)\n    assert.strictEqual(globals.π[\"π 𐀀\"].𐀀[\"𐀀 π\"].default, 123)\n    assert.strictEqual(code.slice(0, code.indexOf('(() => {\\n')), `var \\\\u03C0 = \\\\u03C0 || {};\n\\\\u03C0[\"\\\\u03C0 \\\\uD800\\\\uDC00\"] = \\\\u03C0[\"\\\\u03C0 \\\\uD800\\\\uDC00\"] || {};\n\\\\u03C0[\"\\\\u03C0 \\\\uD800\\\\uDC00\"][\"\\\\uD800\\\\uDC00\"] = \\\\u03C0[\"\\\\u03C0 \\\\uD800\\\\uDC00\"][\"\\\\uD800\\\\uDC00\"] || {};\n\\\\u03C0[\"\\\\u03C0 \\\\uD800\\\\uDC00\"][\"\\\\uD800\\\\uDC00\"][\"\\\\uD800\\\\uDC00 \\\\u03C0\"] = `)\n  },\n\n  async iifeGlobalNameUnicodeNoEscapeNoLogicalAssignment({ esbuild }) {\n    const { code } = await esbuild.transform(`export default 123`, { format: 'iife', globalName: 'π[\"π 𐀀\"].𐀀[\"𐀀 π\"]', supported: { 'logical-assignment': false }, charset: 'utf8' })\n    const globals = {}\n    vm.createContext(globals)\n    vm.runInContext(code, globals)\n    assert.strictEqual(globals.π[\"π 𐀀\"].𐀀[\"𐀀 π\"].default, 123)\n    assert.strictEqual(code.slice(0, code.indexOf('(() => {\\n')),\n      `var π = π || {};\nπ[\"π 𐀀\"] = π[\"π 𐀀\"] || {};\nπ[\"π 𐀀\"][\"𐀀\"] = π[\"π 𐀀\"][\"𐀀\"] || {};\nπ[\"π 𐀀\"][\"𐀀\"][\"𐀀 π\"] = `)\n  },\n\n  async iifeGlobalNameThis({ esbuild }) {\n    const { code } = await esbuild.transform(`export default 123`, { format: 'iife', globalName: 'this.foo.bar' })\n    const globals = {}\n    vm.createContext(globals)\n    vm.runInContext(code, globals)\n    assert.strictEqual(globals.foo.bar.default, 123)\n    assert.strictEqual(code.slice(0, code.indexOf('(() => {\\n')), `(this.foo ||= {}).bar = `)\n  },\n\n  async iifeGlobalNameImportMeta({ esbuild }) {\n    const { code } = await esbuild.transform(`export default 123`, { format: 'iife', globalName: 'import.meta.foo.bar' })\n    const { default: import_meta } = await import('data:text/javascript,' + code + '\\nexport default import.meta')\n    assert.strictEqual(import_meta.foo.bar.default, 123)\n    assert.strictEqual(code.slice(0, code.indexOf('(() => {\\n')), `(import.meta.foo ||= {}).bar = `)\n  },\n\n  async jsx({ esbuild }) {\n    const { code } = await esbuild.transform(`console.log(<div/>)`, { loader: 'jsx' })\n    assert.strictEqual(code, `console.log(/* @__PURE__ */ React.createElement(\"div\", null));\\n`)\n  },\n\n  async jsxTransform({ esbuild }) {\n    const { code } = await esbuild.transform(`console.log(<div/>)`, { loader: 'jsx', jsx: 'transform' })\n    assert.strictEqual(code, `console.log(/* @__PURE__ */ React.createElement(\"div\", null));\\n`)\n  },\n\n  async jsxPreserve({ esbuild }) {\n    const { code } = await esbuild.transform(`console.log(<div/>)`, { loader: 'jsx', jsx: 'preserve' })\n    assert.strictEqual(code, `console.log(<div />);\\n`)\n  },\n\n  async jsxRuntimeAutomatic({ esbuild }) {\n    const { code } = await esbuild.transform(`console.log(<div/>)`, { loader: 'jsx', jsx: 'automatic' })\n    assert.strictEqual(code, `import { jsx } from \"react/jsx-runtime\";\\nconsole.log(/* @__PURE__ */ jsx(\"div\", {}));\\n`)\n  },\n\n  async jsxDev({ esbuild }) {\n    const { code } = await esbuild.transform(`console.log(<div/>)`, { loader: 'jsx', jsx: 'automatic', jsxDev: true })\n    assert.strictEqual(code, `import { jsxDEV } from \"react/jsx-dev-runtime\";\\nconsole.log(/* @__PURE__ */ jsxDEV(\"div\", {}, void 0, false, {\\n  fileName: \"<stdin>\",\\n  lineNumber: 1,\\n  columnNumber: 13\\n}, this));\\n`)\n  },\n\n  async jsxImportSource({ esbuild }) {\n    const { code } = await esbuild.transform(`console.log(<div/>)`, { loader: 'jsx', jsx: 'automatic', jsxImportSource: 'notreact' })\n    assert.strictEqual(code, `import { jsx } from \"notreact/jsx-runtime\";\\nconsole.log(/* @__PURE__ */ jsx(\"div\", {}));\\n`)\n  },\n\n  async jsxSideEffects({ esbuild }) {\n    const { code } = await esbuild.transform(`<b/>`, { loader: 'jsx', jsxSideEffects: true })\n    assert.strictEqual(code, `React.createElement(\"b\", null);\\n`)\n  },\n\n  async ts({ esbuild }) {\n    const { code } = await esbuild.transform(`enum Foo { FOO }`, { loader: 'ts' })\n    assert.strictEqual(code, `var Foo = /* @__PURE__ */ ((Foo2) => {\\n  Foo2[Foo2[\"FOO\"] = 0] = \"FOO\";\\n  return Foo2;\\n})(Foo || {});\\n`)\n  },\n\n  async tsx({ esbuild }) {\n    const { code } = await esbuild.transform(`console.log(<Foo<T>/>)`, { loader: 'tsx' })\n    assert.strictEqual(code, `console.log(/* @__PURE__ */ React.createElement(Foo, null));\\n`)\n  },\n\n  async minify({ esbuild }) {\n    const { code } = await esbuild.transform(`console.log(\"a\" + \"b\" + c)`, { minify: true })\n    assert.strictEqual(code, `console.log(\"ab\"+c);\\n`)\n  },\n\n  async keepConsole({ esbuild }) {\n    const { code } = await esbuild.transform(`console.log('foo')`, { drop: [] })\n    assert.strictEqual(code, `console.log(\"foo\");\\n`)\n  },\n\n  async dropConsole({ esbuild }) {\n    const { code: drop } = await esbuild.transform(`\n      console.log('foo')\n      console.log(foo())\n      console.log.call(console, foo())\n      console.log.apply(console, foo())\n      x = console.log(bar())\n      console['log']('foo')\n    `, { drop: ['console'] })\n    assert.strictEqual(drop, `x = void 0;\\n`)\n\n    const { code: keepArrow } = await esbuild.transform(`\n      console('foo')\n      console.abc.xyz('foo')\n      console['log']('foo')\n      console[abc][xyz]('foo')\n      console[foo()][bar()]('foo')\n      const x = {\n        log: console.log.bind(console),\n      }\n    `, { drop: ['console'] })\n    assert.strictEqual(keepArrow, `console(\"foo\");\n(() => {\n}).xyz(\"foo\");\nconsole[abc][xyz](\"foo\");\nconsole[foo()][bar()](\"foo\");\nconst x = {\n  log: (() => {\n  }).bind(console)\n};\n`)\n\n    const { code: keepFn } = await esbuild.transform(`\n      console('foo')\n      console.abc.xyz('foo')\n      console['log']('foo')\n      console[abc][xyz]('foo')\n      console[foo()][bar()]('foo')\n      const x = {\n        log: console.log.bind(console),\n      }\n    `, { drop: ['console'], supported: { arrow: false } })\n    assert.strictEqual(keepFn, `console(\"foo\");\n(function() {\n}).xyz(\"foo\");\nconsole[abc][xyz](\"foo\");\nconsole[foo()][bar()](\"foo\");\nconst x = {\n  log: function() {\n  }.bind(console)\n};\n`)\n  },\n\n  async keepDebugger({ esbuild }) {\n    const { code } = await esbuild.transform(`if (x) debugger`, { drop: [] })\n    assert.strictEqual(code, `if (x) debugger;\\n`)\n  },\n\n  async dropDebugger({ esbuild }) {\n    const { code } = await esbuild.transform(`if (x) debugger`, { drop: ['debugger'] })\n    assert.strictEqual(code, `if (x) ;\\n`)\n  },\n\n  async defineProcessEnvNodeEnv({ esbuild }) {\n    const define = { 'process.env.NODE_ENV': '\"something\"' }\n\n    const { code: code1 } = await esbuild.transform(`console.log(process.env.NODE_ENV)`, { define })\n    assert.strictEqual(code1, `console.log(\"something\");\\n`)\n\n    const { code: code2 } = await esbuild.transform(`console.log(process.env['NODE_ENV'])`, { define })\n    assert.strictEqual(code2, `console.log(\"something\");\\n`)\n\n    const { code: code3 } = await esbuild.transform(`console.log(process['env'].NODE_ENV)`, { define })\n    assert.strictEqual(code3, `console.log(\"something\");\\n`)\n\n    const { code: code4 } = await esbuild.transform(`console.log(process['env']['NODE_ENV'])`, { define })\n    assert.strictEqual(code4, `console.log(\"something\");\\n`)\n\n    const { code: code5 } = await esbuild.transform(`console.log(process.env.NODE_ENV)`, {})\n    assert.strictEqual(code5, `console.log(process.env.NODE_ENV);\\n`)\n\n    const { code: code6 } = await esbuild.transform(`console.log(process.env.NODE_ENV)`, { platform: 'browser' })\n    assert.strictEqual(code6, `console.log(process.env.NODE_ENV);\\n`)\n  },\n\n  async defineBuiltInConstants({ esbuild }) {\n    const define = { a: 'NaN', b: 'Infinity', c: 'undefined', d: 'something', e: 'null' }\n    const { code } = await esbuild.transform(`console.log([typeof a, typeof b, typeof c, typeof d, typeof e])`, { define })\n    assert.strictEqual(code, `console.log([\"number\", \"number\", \"undefined\", typeof something, \"object\"]);\\n`)\n  },\n\n  async defineArray({ esbuild }) {\n    const define = { 'process.env.NODE_ENV': '[1,2,3]', 'something.else': '[2,3,4]' }\n    const { code } = await esbuild.transform(`console.log(process.env.NODE_ENV)`, { define })\n    assert.strictEqual(code, `var define_process_env_NODE_ENV_default = [1, 2, 3];\\nconsole.log(define_process_env_NODE_ENV_default);\\n`)\n  },\n\n  async defineThis({ esbuild }) {\n    const { code: code1 } = await esbuild.transform(`console.log(a, b); export {}`, { define: { a: 'this', b: 'this.foo' }, format: 'esm' })\n    assert.strictEqual(code1, `console.log(void 0, (void 0).foo);\\n`)\n\n    const { code: code2 } = await esbuild.transform(`console.log(this, this.x); export {}`, { define: { this: 'a', 'this.x': 'b' }, format: 'esm' })\n    assert.strictEqual(code2, `console.log(a, b);\\n`)\n  },\n\n  async defineImportMetaESM({ esbuild }) {\n    const { code: code1 } = await esbuild.transform(`console.log(a, b); export {}`, { define: { a: 'import.meta', b: 'import.meta.foo' }, format: 'esm' })\n    assert.strictEqual(code1, `console.log(import.meta, import.meta.foo);\\n`)\n\n    const { code: code2 } = await esbuild.transform(`console.log(import.meta, import.meta.x); export {}`, { define: { 'import.meta': 'a', 'import.meta.x': 'b' }, format: 'esm' })\n    assert.strictEqual(code2, `console.log(a, b);\\n`)\n  },\n\n  async defineImportMetaIIFE({ esbuild }) {\n    const { code } = await esbuild.transform(`console.log(a, b); export {}`, { define: { a: 'import.meta', b: 'import.meta.foo' }, format: 'iife' })\n    assert.strictEqual(code, `(() => {\\n  const import_meta = {};\\n  console.log(import_meta, import_meta.foo);\\n})();\\n`)\n  },\n\n  async defineIdentifierVsStringWarningIssue466Transform({ esbuild }) {\n    const { warnings } = await esbuild.transform(``, { define: { 'process.env.NODE_ENV': 'production' } })\n    const formatted = await esbuild.formatMessages(warnings, { kind: 'warning' })\n    assert.strictEqual(formatted[0],\n      `▲ [WARNING] \"process.env.NODE_ENV\" is defined as an identifier instead of a string (surround \"production\" with quotes to get a string) [suspicious-define]\n\n    <js>:1:34:\n      1 │ define: { 'process.env.NODE_ENV': 'production' }\n        │                                   ~~~~~~~~~~~~\n        ╵                                   '\"production\"'\n\n`)\n  },\n\n  async defineIdentifierVsStringWarningIssue466Build({ esbuild }) {\n    const { warnings } = await esbuild.build({ define: { 'process.env.NODE_ENV': 'production' }, logLevel: 'silent' })\n    const formatted = await esbuild.formatMessages(warnings, { kind: 'warning' })\n    assert.strictEqual(formatted[0],\n      `▲ [WARNING] \"process.env.NODE_ENV\" is defined as an identifier instead of a string (surround \"production\" with quotes to get a string) [suspicious-define]\n\n    <js>:1:34:\n      1 │ define: { 'process.env.NODE_ENV': 'production' }\n        │                                   ~~~~~~~~~~~~\n        ╵                                   '\"production\"'\n\n`)\n  },\n\n  async defineQuotedPropertyNameTransform({ esbuild }) {\n    const { code: code1 } = await esbuild.transform(`return x.y['z!']`, { define: { 'x.y[\"z!\"]': 'true' } })\n    assert.strictEqual(code1, `return true;\\n`)\n\n    const { code: code2 } = await esbuild.transform(`foo(x['y'].z, x.y['z'], x['y']['z'])`, { define: { 'x.y.z': 'true' } })\n    assert.strictEqual(code2, `foo(true, true, true);\\n`)\n\n    const { code: code3 } = await esbuild.transform(`foo(x['y'].z, x.y['z'], x['y']['z'])`, { define: { 'x[\"y\"].z': 'true' } })\n    assert.strictEqual(code3, `foo(true, true, true);\\n`)\n\n    const { code: code4 } = await esbuild.transform(`foo(x['y'].z, x.y['z'], x['y']['z'])`, { define: { 'x.y[\"z\"]': 'true' } })\n    assert.strictEqual(code4, `foo(true, true, true);\\n`)\n\n    const { code: code5 } = await esbuild.transform(`foo(x['y'].z, x.y['z'], x['y']['z'])`, { define: { 'x[\"y\"][\\'z\\']': 'true' } })\n    assert.strictEqual(code5, `foo(true, true, true);\\n`)\n\n    const { code: code6 } = await esbuild.transform(`foo(import.meta['y'].z, import.meta.y['z'], import.meta['y']['z'])`, { define: { 'import.meta[\"y\"].z': 'true' } })\n    assert.strictEqual(code6, `foo(true, true, true);\\n`)\n\n    const { code: code7 } = await esbuild.transform(`foo(import.meta['y!'].z, import.meta.y['z!'], import.meta['y!']['z!'])`, {\n      define: {\n        'import.meta[\"y!\"].z': 'true',\n        'import.meta.y[\"z!\"]': 'true',\n        'import.meta[\"y!\"][\"z!\"]': 'true'\n      },\n    })\n    assert.strictEqual(code7, `foo(true, true, true);\\n`)\n  },\n\n\n  async defineQuotedPropertyNameBuild({ esbuild }) {\n    const { outputFiles } = await esbuild.build({\n      stdin: { contents: `return process.env['SOME-TEST-VAR']` },\n      define: { 'process.env[\"SOME-TEST-VAR\"]': 'true' },\n      write: false,\n    })\n    assert.strictEqual(outputFiles[0].text, `return true;\\n`)\n  },\n\n  async defineBigInt({ esbuild }) {\n    const { code } = await esbuild.transform(`console.log(a, b); export {}`, { define: { a: '0n', b: '{\"x\":[123n]}' }, format: 'esm' })\n    assert.strictEqual(code, `var define_b_default = { x: [123n] };\\nconsole.log(0n, define_b_default);\\n`)\n  },\n\n  async json({ esbuild }) {\n    const { code } = await esbuild.transform(`{ \"x\": \"y\" }`, { loader: 'json' })\n    assert.strictEqual(code, `module.exports = { x: \"y\" };\\n`)\n  },\n\n  async jsonMinified({ esbuild }) {\n    const { code } = await esbuild.transform(`{ \"x\": \"y\" }`, { loader: 'json', minify: true })\n    const module = {}\n    new Function('module', code)(module)\n    assert.deepStrictEqual(module.exports, { x: 'y' })\n  },\n\n  async jsonESM({ esbuild }) {\n    const { code } = await esbuild.transform(`{ \"x\": \"y\" }`, { loader: 'json', format: 'esm' })\n    assert.strictEqual(code, `var x = \"y\";\\nvar stdin_default = { x };\\nexport {\\n  stdin_default as default,\\n  x\\n};\\n`)\n  },\n\n  async jsonInvalidIdentifierStart({ esbuild }) {\n    // This character is a valid \"ID_Continue\" but not a valid \"ID_Start\" so it must be quoted\n    const { code } = await esbuild.transform(`{ \"\\\\uD835\\\\uDFCE\": \"y\" }`, { loader: 'json' })\n    assert.strictEqual(code, `module.exports = { \"\\\\u{1D7CE}\": \"y\" };\\n`)\n  },\n\n  async text({ esbuild }) {\n    const { code } = await esbuild.transform(`This is some text`, { loader: 'text' })\n    assert.strictEqual(code, `module.exports = \"This is some text\";\\n`)\n  },\n\n  async textESM({ esbuild }) {\n    const { code } = await esbuild.transform(`This is some text`, { loader: 'text', format: 'esm' })\n    assert.strictEqual(code, `var stdin_default = \"This is some text\";\\nexport {\\n  stdin_default as default\\n};\\n`)\n  },\n\n  async base64({ esbuild }) {\n    const { code } = await esbuild.transform(`\\x00\\x01\\x02`, { loader: 'base64' })\n    assert.strictEqual(code, `module.exports = \"AAEC\";\\n`)\n  },\n\n  async dataurl({ esbuild }) {\n    const { code: code1 } = await esbuild.transform(`\\x00\\x01\\x02`, { loader: 'dataurl' })\n    assert.strictEqual(code1, `module.exports = \"data:application/octet-stream,%00%01%02\";\\n`)\n\n    const { code: code2 } = await esbuild.transform(`\\xFD\\xFE\\xFF`, { loader: 'dataurl' })\n    assert.strictEqual(code2, `module.exports = \"data:text/plain;charset=utf-8,\\\\xFD\\\\xFE\\\\xFF\";\\n`)\n\n    const { code: code3 } = await esbuild.transform(new Uint8Array([0xFD, 0xFE, 0xFF]), { loader: 'dataurl' })\n    assert.strictEqual(code3, `module.exports = \"data:text/plain;charset=utf-8;base64,/f7/\";\\n`)\n  },\n\n  async sourceMapTrueWithName({ esbuild }) {\n    const { code, map } = await esbuild.transform(`let       x`, { sourcemap: true, sourcefile: 'afile.js' })\n    assert.strictEqual(code, `let x;\\n`)\n    await assertSourceMap(map, 'afile.js')\n  },\n\n  async sourceMapLinkedWithName({ esbuild }) {\n    try {\n      await esbuild.transform(`let       x`, { sourcemap: 'linked', sourcefile: 'afile.js' })\n      throw new Error('Expected a transform failure')\n    } catch (e) {\n      assert.strictEqual(e + '', `Error: Transform failed with 1 error:\\nerror: Cannot transform with linked source maps`)\n    }\n  },\n\n  async sourceMapExternalWithName({ esbuild }) {\n    const { code, map } = await esbuild.transform(`let       x`, { sourcemap: 'external', sourcefile: 'afile.js' })\n    assert.strictEqual(code, `let x;\\n`)\n    await assertSourceMap(map, 'afile.js')\n  },\n\n  async sourceMapInlineWithName({ esbuild }) {\n    const { code, map } = await esbuild.transform(`let       x`, { sourcemap: 'inline', sourcefile: 'afile.js' })\n    assert(code.startsWith(`let x;\\n//# sourceMappingURL=`))\n    assert.strictEqual(map, '')\n    const base64 = code.slice(code.indexOf('base64,') + 'base64,'.length)\n    await assertSourceMap(Buffer.from(base64.trim(), 'base64').toString(), 'afile.js')\n  },\n\n  async sourceMapBothWithName({ esbuild }) {\n    const { code, map } = await esbuild.transform(`let       x`, { sourcemap: 'both', sourcefile: 'afile.js' })\n    assert(code.startsWith(`let x;\\n//# sourceMappingURL=`))\n    await assertSourceMap(map, 'afile.js')\n    const base64 = code.slice(code.indexOf('base64,') + 'base64,'.length)\n    await assertSourceMap(Buffer.from(base64.trim(), 'base64').toString(), 'afile.js')\n  },\n\n  async sourceMapRoot({ esbuild }) {\n    const { code, map } = await esbuild.transform(`let       x`, { sourcemap: true, sourcefile: 'afile.js', sourceRoot: \"https://example.com/\" })\n    assert.strictEqual(code, `let x;\\n`)\n    assert.strictEqual(JSON.parse(map).sourceRoot, 'https://example.com/');\n  },\n\n  async numericLiteralPrinting({ esbuild }) {\n    async function checkLiteral(text) {\n      const { code } = await esbuild.transform(`return ${text}`, { minify: true })\n      assert.strictEqual(+text, new Function(code)())\n    }\n    const promises = []\n    for (let i = 0; i < 10; i++) {\n      for (let j = 0; j < 10; j++) {\n        promises.push(checkLiteral(`0.${'0'.repeat(i)}${'123456789'.slice(0, j)}`))\n        promises.push(checkLiteral(`1${'0'.repeat(i)}.${'123456789'.slice(0, j)}`))\n        promises.push(checkLiteral(`1${'123456789'.slice(0, j)}${'0'.repeat(i)}`))\n      }\n    }\n    await Promise.all(promises)\n  },\n\n  async tryCatchScopeMerge({ esbuild }) {\n    const code = `\n      var x = 1\n      if (x !== 1) throw 'fail'\n      try {\n        throw 2\n      } catch (x) {\n        if (x !== 2) throw 'fail'\n        {\n          if (x !== 2) throw 'fail'\n          var x = 3\n          if (x !== 3) throw 'fail'\n        }\n        if (x !== 3) throw 'fail'\n      }\n      if (x !== 1) throw 'fail'\n    `;\n    new Function(code)(); // Verify that the code itself is correct\n    new Function((await esbuild.transform(code)).code)();\n  },\n\n  async nestedFunctionHoist({ esbuild }) {\n    const code = `\n      if (x !== void 0) throw 'fail'\n      {\n        if (x !== void 0) throw 'fail'\n        {\n          x()\n          function x() {}\n          x()\n        }\n        x()\n      }\n      x()\n    `;\n    new Function(code)(); // Verify that the code itself is correct\n    new Function((await esbuild.transform(code)).code)();\n  },\n\n  async nestedFunctionHoistBefore({ esbuild }) {\n    const code = `\n      var x = 1\n      if (x !== 1) throw 'fail'\n      {\n        if (x !== 1) throw 'fail'\n        {\n          x()\n          function x() {}\n          x()\n        }\n        x()\n      }\n      x()\n    `;\n    new Function(code)(); // Verify that the code itself is correct\n    new Function((await esbuild.transform(code)).code)();\n  },\n\n  async nestedFunctionHoistAfter({ esbuild }) {\n    const code = `\n      if (x !== void 0) throw 'fail'\n      {\n        if (x !== void 0) throw 'fail'\n        {\n          x()\n          function x() {}\n          x()\n        }\n        x()\n      }\n      x()\n      var x = 1\n    `;\n    new Function(code)(); // Verify that the code itself is correct\n    new Function((await esbuild.transform(code)).code)();\n  },\n\n  async nestedFunctionShadowBefore({ esbuild }) {\n    const code = `\n      let x = 1\n      if (x !== 1) throw 'fail'\n      {\n        if (x !== 1) throw 'fail'\n        {\n          x()\n          function x() {}\n          x()\n        }\n        if (x !== 1) throw 'fail'\n      }\n      if (x !== 1) throw 'fail'\n    `;\n    new Function(code)(); // Verify that the code itself is correct\n    new Function((await esbuild.transform(code)).code)();\n  },\n\n  async nestedFunctionShadowAfter({ esbuild }) {\n    const code = `\n      try { x; throw 'fail' } catch (e) { if (!(e instanceof ReferenceError)) throw e }\n      {\n        try { x; throw 'fail' } catch (e) { if (!(e instanceof ReferenceError)) throw e }\n        {\n          x()\n          function x() {}\n          x()\n        }\n        try { x; throw 'fail' } catch (e) { if (!(e instanceof ReferenceError)) throw e }\n      }\n      try { x; throw 'fail' } catch (e) { if (!(e instanceof ReferenceError)) throw e }\n      let x = 1\n    `;\n    new Function(code)(); // Verify that the code itself is correct\n    new Function((await esbuild.transform(code)).code)();\n  },\n\n  async sourceMapControlCharacterEscapes({ esbuild }) {\n    let chars = ''\n    for (let i = 0; i < 32; i++) chars += String.fromCharCode(i);\n    const input = `return \\`${chars}\\``;\n    const { code, map } = await esbuild.transform(input, { sourcemap: true, sourcefile: 'afile.code' })\n    const fn = new Function(code)\n    assert.strictEqual(fn(), chars.replace('\\r', '\\n'))\n    const json = JSON.parse(map)\n    assert.strictEqual(json.version, 3)\n    assert.strictEqual(json.sourcesContent.length, 1)\n    assert.strictEqual(json.sourcesContent[0], input)\n  },\n\n  async transformLegalCommentsJS({ esbuild }) {\n    assert.strictEqual((await esbuild.transform(`//!x\\ny()`, { legalComments: 'none' })).code, `y();\\n`)\n    assert.strictEqual((await esbuild.transform(`//!x\\ny()`, { legalComments: 'inline' })).code, `//!x\\ny();\\n`)\n\n    const eofResult = await esbuild.transform(`//!x\\ny()`, { legalComments: 'eof' })\n    assert.strictEqual(eofResult.code, `y();\\n//!x\\n`)\n    assert.strictEqual(eofResult.legalComments, undefined)\n\n    const externalResult = await esbuild.transform(`//!x\\ny()`, { legalComments: 'external' })\n    assert.strictEqual(externalResult.code, `y();\\n`)\n    assert.strictEqual(externalResult.legalComments, `//!x\\n`)\n\n    try {\n      await esbuild.transform(``, { legalComments: 'linked' })\n      throw new Error('Expected a transform failure')\n    } catch (e) {\n      if (!e || !e.errors || !e.errors[0] || e.errors[0].text !== 'Cannot transform with linked legal comments')\n        throw e\n    }\n  },\n\n  async transformLegalCommentsCSS({ esbuild }) {\n    assert.strictEqual((await esbuild.transform(`/*!x*/\\ny{}`, { loader: 'css', legalComments: 'none' })).code, `y {\\n}\\n`)\n    assert.strictEqual((await esbuild.transform(`/*!x*/\\ny{}`, { loader: 'css', legalComments: 'inline' })).code, `/*!x*/\\ny {\\n}\\n`)\n\n    const eofResult = await esbuild.transform(`/*!x*/\\ny{}`, { loader: 'css', legalComments: 'eof' })\n    assert.strictEqual(eofResult.code, `y {\\n}\\n/*!x*/\\n`)\n    assert.strictEqual(eofResult.legalComments, undefined)\n\n    const externalResult = await esbuild.transform(`/*!x*/\\ny{}`, { loader: 'css', legalComments: 'external' })\n    assert.strictEqual(externalResult.code, `y {\\n}\\n`)\n    assert.strictEqual(externalResult.legalComments, `/*!x*/\\n`)\n\n    try {\n      await esbuild.transform(``, { legalComments: 'linked' })\n      throw new Error('Expected a transform failure')\n    } catch (e) {\n      if (!e || !e.errors || !e.errors[0] || e.errors[0].text !== 'Cannot transform with linked legal comments')\n        throw e\n    }\n  },\n\n  async tsDecorators({ esbuild }) {\n    const { code } = await esbuild.transform(`\n      let observed = [];\n      let on = key => (...args) => {\n        observed.push({ key, args });\n      };\n\n      @on('class')\n      class Foo {\n        @on('field') field;\n        @on('method') method() { }\n        @on('staticField') static staticField;\n        @on('staticMethod') static staticMethod() { }\n        fn(@on('param') x) { }\n        static staticFn(@on('staticParam') x) { }\n      }\n\n      // This is what the TypeScript compiler itself generates\n      let expected = [\n        { key: 'field', args: [Foo.prototype, 'field', undefined] },\n        { key: 'method', args: [Foo.prototype, 'method', { value: Foo.prototype.method, writable: true, enumerable: false, configurable: true }] },\n        { key: 'param', args: [Foo.prototype, 'fn', 0] },\n        { key: 'staticField', args: [Foo, 'staticField', undefined] },\n        { key: 'staticMethod', args: [Foo, 'staticMethod', { value: Foo.staticMethod, writable: true, enumerable: false, configurable: true }] },\n        { key: 'staticParam', args: [Foo, 'staticFn', 0] },\n        { key: 'class', args: [Foo] }\n      ];\n\n      return {observed, expected};\n    `, {\n      loader: 'ts',\n      tsconfigRaw: {\n        compilerOptions: {\n          experimentalDecorators: true,\n        },\n      },\n    });\n    const { observed, expected } = new Function(code)();\n    assert.deepStrictEqual(observed, expected);\n  },\n\n  async pureCallPrint({ esbuild }) {\n    const { code: code1 } = await esbuild.transform(`print(123, foo)`, { minifySyntax: true, pure: [] })\n    assert.strictEqual(code1, `print(123, foo);\\n`)\n\n    const { code: code2 } = await esbuild.transform(`print(123, foo)`, { minifySyntax: true, pure: ['print'] })\n    assert.strictEqual(code2, `foo;\\n`)\n  },\n\n  async pureCallConsoleLog({ esbuild }) {\n    const { code: code1 } = await esbuild.transform(`console.log(123, foo)`, { minifySyntax: true, pure: [] })\n    assert.strictEqual(code1, `console.log(123, foo);\\n`)\n\n    const { code: code2 } = await esbuild.transform(`console.log(123, foo)`, { minifySyntax: true, pure: ['console.log'] })\n    assert.strictEqual(code2, `foo;\\n`)\n  },\n\n  async pureImportMeta({ esbuild }) {\n    const { code: code1 } = await esbuild.transform(`import.meta.foo(123, foo)`, { minifySyntax: true, pure: [] })\n    assert.strictEqual(code1, `import.meta.foo(123, foo);\\n`)\n\n    const { code: code2 } = await esbuild.transform(`import.meta.foo(123, foo)`, { minifySyntax: true, pure: ['import.meta.foo'] })\n    assert.strictEqual(code2, `foo;\\n`)\n  },\n\n  async nameCollisionEvalRename({ esbuild }) {\n    const { code } = await esbuild.transform(`\n      // \"arg\" must not be renamed to \"arg2\"\n      return function(arg2) {\n        function foo(arg) {\n          return arg + arg2;\n        }\n        // \"eval\" prevents \"arg2\" from being renamed\n        // \"arg\" below causes \"arg\" above to be renamed\n        return eval(foo(1)) + arg\n      }(2);\n    `)\n    const result = new Function('arg', code)(10)\n    assert.strictEqual(result, 13)\n  },\n\n  async nameCollisionEvalMinify({ esbuild }) {\n    const { code } = await esbuild.transform(`\n      // \"arg\" must not be renamed to \"$\"\n      return function($) {\n        function foo(arg) {\n          return arg + $;\n        }\n        // \"eval\" prevents \"$\" from being renamed\n        // Repeated \"$\" puts \"$\" at the top of the character frequency histogram\n        return eval(foo($$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$))\n      }(2);\n    `, { minifyIdentifiers: true })\n    const result = new Function('$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$', code)(1)\n    assert.strictEqual(result, 3)\n  },\n\n  async singleUseExpressionSubstitution({ esbuild }) {\n    function run(code) {\n      try {\n        return JSON.stringify(new Function(code)())\n      } catch (error) {\n        return error + ''\n      }\n    }\n    let bugs = ''\n    for (let input of [\n      `let fn = () => { throw new Error }; let x = undef; return fn() + x`,\n      `let fn = () => { throw new Error }; let x = fn(); return undef + x`,\n\n      `let fn = () => arg0 = 0; let x = fn(); return arg0 + x`,\n      `let fn = () => arg0 = 0; let x = fn(); return arg0 = x`,\n      `let fn = () => arg0 = 0; let x = fn(); return arg0 += x`,\n      `let fn = () => arg0 = 0; let x = fn(); return arg0 ||= x`,\n      `let fn = () => arg0 = 0; let x = fn(); return arg0 &&= x`,\n\n      `let fn = () => arg0 = 0; let obj = [1]; let x = arg0; return obj[fn()] + x`,\n      `let fn = () => arg0 = 0; let obj = [1]; let x = arg0; return obj[fn()] = x`,\n      `let fn = () => arg0 = 0; let obj = [1]; let x = arg0; return obj[fn()] += x`,\n      `let fn = () => arg0 = 0; let obj = [1]; let x = arg0; return obj[fn()] ||= x`,\n      `let fn = () => arg0 = 0; let obj = [1]; let x = arg0; return obj[fn()] &&= x`,\n\n      `let obj = { get y() { arg0 = 0; return 1 } }; let x = obj.y; return arg0 + x`,\n      `let obj = { get y() { arg0 = 0; return 1 } }; let x = arg0; return obj.y + x`,\n\n      `let x = undef; return arg0 || x`,\n      `let x = undef; return arg0 && x`,\n      `let x = undef; return arg0 ? x : 1`,\n      `let x = undef; return arg0 ? 1 : x`,\n\n      `let fn = () => { throw new Error }; let x = fn(); return arg0 || x`,\n      `let fn = () => { throw new Error }; let x = fn(); return arg0 && x`,\n      `let fn = () => { throw new Error }; let x = fn(); return arg0 ? x : 1`,\n      `let fn = () => { throw new Error }; let x = fn(); return arg0 ? 1 : x`,\n    ]) {\n      input = `function f(arg0) { ${input} } return f(123)`\n      const { code: minified } = await esbuild.transform(input, { minify: true })\n      if (run(input) !== run(minified)) bugs += '\\n  ' + input\n    }\n    if (bugs !== '') throw new Error('Single-use expression substitution bugs:' + bugs)\n  },\n\n  async platformNode({ esbuild }) {\n    const { code } = await esbuild.transform(`export let foo = 123`, { format: 'cjs', platform: 'node' })\n    assert(code.slice(code.indexOf('let foo')), `let foo = 123;\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n  foo\n});\n`)\n  },\n\n  async dynamicImportString({ esbuild }) {\n    const { code } = await esbuild.transform(`import('foo')`, { target: 'chrome63' })\n    assert.strictEqual(code, `import(\"foo\");\\n`)\n  },\n\n  async dynamicImportStringES6({ esbuild }) {\n    const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))\n    const { code } = await esbuild.transform(`import('foo')`, { target: 'chrome62' })\n    assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toESM(require(\"foo\")));\\n`)\n  },\n\n  async dynamicImportStringES5({ esbuild }) {\n    const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))\n    const { code } = await esbuild.transform(`import('foo')`, { target: 'chrome48' })\n    assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(function() {\\n  return __toESM(require(\"foo\"));\\n});\\n`)\n  },\n\n  async dynamicImportStringES5Minify({ esbuild }) {\n    const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))\n    const { code } = await esbuild.transform(`import('foo')`, { target: 'chrome48', minifyWhitespace: true })\n    assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(function(){return __toESM(require(\"foo\"))});\\n`)\n  },\n\n  async dynamicImportStringNode12_19({ esbuild }) {\n    const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))\n    const { code } = await esbuild.transform(`import('foo')`, { target: 'node12.19' })\n    assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toESM(require(\"foo\")));\\n`)\n  },\n\n  async dynamicImportStringNode12_20({ esbuild }) {\n    const { code } = await esbuild.transform(`import('foo')`, { target: 'node12.20' })\n    assert.strictEqual(code, `import(\"foo\");\\n`)\n  },\n\n  async dynamicImportStringNode13({ esbuild }) {\n    const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))\n    const { code } = await esbuild.transform(`import('foo')`, { target: 'node13' })\n    assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toESM(require(\"foo\")));\\n`)\n  },\n\n  async dynamicImportStringNode13_1({ esbuild }) {\n    const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))\n    const { code } = await esbuild.transform(`import('foo')`, { target: 'node13.1' })\n    assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toESM(require(\"foo\")));\\n`)\n  },\n\n  async dynamicImportStringNode13_2({ esbuild }) {\n    const { code } = await esbuild.transform(`import('foo')`, { target: 'node13.2' })\n    assert.strictEqual(code, `import(\"foo\");\\n`)\n  },\n\n  async dynamicImportExpression({ esbuild }) {\n    const { code } = await esbuild.transform(`import(foo)`, { target: 'chrome63' })\n    assert.strictEqual(code, `import(foo);\\n`)\n  },\n\n  async dynamicImportExpressionES6({ esbuild }) {\n    const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))\n    const { code: code2 } = await esbuild.transform(`import(foo)`, { target: 'chrome62' })\n    assert.strictEqual(fromPromiseResolve(code2), `Promise.resolve().then(() => __toESM(require(foo)));\\n`)\n  },\n\n  async dynamicImportExpressionES5({ esbuild }) {\n    const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))\n    const { code: code3 } = await esbuild.transform(`import(foo)`, { target: 'chrome48' })\n    assert.strictEqual(fromPromiseResolve(code3), `Promise.resolve().then(function() {\\n  return __toESM(require(foo));\\n});\\n`)\n  },\n\n  async dynamicImportExpressionES5Minify({ esbuild }) {\n    const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve'))\n    const { code: code4 } = await esbuild.transform(`import(foo)`, { target: 'chrome48', minifyWhitespace: true })\n    assert.strictEqual(fromPromiseResolve(code4), `Promise.resolve().then(function(){return __toESM(require(foo))});\\n`)\n  },\n\n  async classStaticBlocks({ esbuild }) {\n    // Check that empty static class blocks are still lowered (this was a regression in version 0.18.2)\n    assert.strictEqual((await esbuild.transform(`class Foo { static {} }`, { supported: { 'class-static-blocks': false } })).code, `class Foo {\\n}\\n`)\n    assert.strictEqual((await esbuild.transform(`class Foo { static { x } }`, { supported: { 'class-static-blocks': false } })).code, `class Foo {\\n}\\nx;\\n`)\n  },\n\n  async keepNamesUnsupported({ esbuild }) {\n    try {\n      await esbuild.transform(``, { keepNames: true, target: 'chrome36' })\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert.strictEqual(e.errors[0].text,\n        'The \"keep names\" setting cannot be used with the configured target environment (\"chrome36\")')\n    }\n\n    try {\n      await esbuild.transform(``, { keepNames: true, target: 'chrome46', supported: { 'function-name-configurable': false } })\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert.strictEqual(e.errors[0].text,\n        'The \"keep names\" setting cannot be used with the configured target environment (\"chrome46\" + 1 override)')\n    }\n\n    await esbuild.transform(``, { keepNames: true, target: 'chrome46' })\n  },\n\n  async inlineScript({ esbuild }) {\n    let p\n    assert.strictEqual((await esbuild.transform(`x = '</script>'`, {})).code, `x = \"<\\\\/script>\";\\n`)\n    assert.strictEqual((await esbuild.transform(`x = '</script> inline'`, { supported: { 'inline-script': true } })).code, `x = \"<\\\\/script> inline\";\\n`)\n    assert.strictEqual((await esbuild.transform(`x = '</script> noinline'`, { supported: { 'inline-script': false } })).code, `x = \"</script> noinline\";\\n`)\n\n    p = { platform: 'browser' }\n    assert.strictEqual((await esbuild.transform(`x = '</script> browser'`, { ...p })).code, `x = \"<\\\\/script> browser\";\\n`)\n    assert.strictEqual((await esbuild.transform(`x = '</script> browser inline'`, { ...p, supported: { 'inline-script': true } })).code, `x = \"<\\\\/script> browser inline\";\\n`)\n    assert.strictEqual((await esbuild.transform(`x = '</script> browser noinline'`, { ...p, supported: { 'inline-script': false } })).code, `x = \"</script> browser noinline\";\\n`)\n\n    p = { platform: 'node' }\n    assert.strictEqual((await esbuild.transform(`x = '</script> node'`, { ...p })).code, `x = \"</script> node\";\\n`)\n    assert.strictEqual((await esbuild.transform(`x = '</script> node inline'`, { ...p, supported: { 'inline-script': true } })).code, `x = \"<\\\\/script> node inline\";\\n`)\n    assert.strictEqual((await esbuild.transform(`x = '</script> node noinline'`, { ...p, supported: { 'inline-script': false } })).code, `x = \"</script> node noinline\";\\n`)\n\n    p = { platform: 'neutral' }\n    assert.strictEqual((await esbuild.transform(`x = '</script> neutral'`, { ...p })).code, `x = \"</script> neutral\";\\n`)\n    assert.strictEqual((await esbuild.transform(`x = '</script> neutral inline'`, { ...p, supported: { 'inline-script': true } })).code, `x = \"<\\\\/script> neutral inline\";\\n`)\n    assert.strictEqual((await esbuild.transform(`x = '</script> neutral noinline'`, { ...p, supported: { 'inline-script': false } })).code, `x = \"</script> neutral noinline\";\\n`)\n\n    assert.strictEqual((await esbuild.transform(`x = '</script>'`, { target: 'esnext' })).code, `x = \"<\\\\/script>\";\\n`)\n    assert.strictEqual((await esbuild.transform(`x = '</script>'`, { target: 'es2020' })).code, `x = \"<\\\\/script>\";\\n`)\n    assert.strictEqual((await esbuild.transform(`x = '</script>'`, { target: 'es6' })).code, `x = \"<\\\\/script>\";\\n`)\n    assert.strictEqual((await esbuild.transform(`x = '</script>'`, { target: 'chrome999' })).code, `x = \"<\\\\/script>\";\\n`)\n    assert.strictEqual((await esbuild.transform(`x = '</script>'`, { target: 'chrome0' })).code, `x = \"<\\\\/script>\";\\n`)\n  },\n\n  async inlineStyle({ esbuild }) {\n    let p = { loader: 'css' }\n    assert.strictEqual((await esbuild.transform(`x { y: '</style>' }`, { ...p })).code, `x {\\n  y: \"<\\\\/style>\";\\n}\\n`)\n    assert.strictEqual((await esbuild.transform(`x { y: '</style> inline' }`, { ...p, supported: { 'inline-style': true } })).code, `x {\\n  y: \"<\\\\/style> inline\";\\n}\\n`)\n    assert.strictEqual((await esbuild.transform(`x { y: '</style> noinline' }`, { ...p, supported: { 'inline-style': false } })).code, `x {\\n  y: \"</style> noinline\";\\n}\\n`)\n\n    p = { loader: 'css', platform: 'browser' }\n    assert.strictEqual((await esbuild.transform(`x { y: '</style> browser' }`, { ...p })).code, `x {\\n  y: \"<\\\\/style> browser\";\\n}\\n`)\n    assert.strictEqual((await esbuild.transform(`x { y: '</style> browser inline' }`, { ...p, supported: { 'inline-style': true } })).code, `x {\\n  y: \"<\\\\/style> browser inline\";\\n}\\n`)\n    assert.strictEqual((await esbuild.transform(`x { y: '</style> browser noinline' }`, { ...p, supported: { 'inline-style': false } })).code, `x {\\n  y: \"</style> browser noinline\";\\n}\\n`)\n\n    p = { loader: 'css', platform: 'node' }\n    assert.strictEqual((await esbuild.transform(`x { y: '</style> node' }`, { ...p })).code, `x {\\n  y: \"</style> node\";\\n}\\n`)\n    assert.strictEqual((await esbuild.transform(`x { y: '</style> node inline' }`, { ...p, supported: { 'inline-style': true } })).code, `x {\\n  y: \"<\\\\/style> node inline\";\\n}\\n`)\n    assert.strictEqual((await esbuild.transform(`x { y: '</style> node noinline' }`, { ...p, supported: { 'inline-style': false } })).code, `x {\\n  y: \"</style> node noinline\";\\n}\\n`)\n\n    p = { loader: 'css', platform: 'neutral' }\n    assert.strictEqual((await esbuild.transform(`x { y: '</style> neutral' }`, { ...p })).code, `x {\\n  y: \"</style> neutral\";\\n}\\n`)\n    assert.strictEqual((await esbuild.transform(`x { y: '</style> neutral inline' }`, { ...p, supported: { 'inline-style': true } })).code, `x {\\n  y: \"<\\\\/style> neutral inline\";\\n}\\n`)\n    assert.strictEqual((await esbuild.transform(`x { y: '</style> neutral noinline' }`, { ...p, supported: { 'inline-style': false } })).code, `x {\\n  y: \"</style> neutral noinline\";\\n}\\n`)\n\n    p = { loader: 'css' }\n    assert.strictEqual((await esbuild.transform(`x { y: '</style>' }`, { ...p, target: 'esnext' })).code, `x {\\n  y: \"<\\\\/style>\";\\n}\\n`)\n    assert.strictEqual((await esbuild.transform(`x { y: '</style>' }`, { ...p, target: 'es2020' })).code, `x {\\n  y: \"<\\\\/style>\";\\n}\\n`)\n    assert.strictEqual((await esbuild.transform(`x { y: '</style>' }`, { ...p, target: 'es6' })).code, `x {\\n  y: \"<\\\\/style>\";\\n}\\n`)\n    assert.strictEqual((await esbuild.transform(`x { y: '</style>' }`, { ...p, target: 'chrome999' })).code, `x {\\n  y: \"<\\\\/style>\";\\n}\\n`)\n    assert.strictEqual((await esbuild.transform(`x { y: '</style>' }`, { ...p, target: 'chrome0' })).code, `x {\\n  y: \"<\\\\/style>\";\\n}\\n`)\n  },\n\n  async typeofEqualsUndefinedTarget({ esbuild }) {\n    assert.strictEqual((await esbuild.transform(`a = typeof b !== 'undefined'`, { minify: true })).code, `a=typeof b<\"u\";\\n`)\n    assert.strictEqual((await esbuild.transform(`a = typeof b !== 'undefined'`, { minify: true, target: 'es2020' })).code, `a=typeof b<\"u\";\\n`)\n    assert.strictEqual((await esbuild.transform(`a = typeof b !== 'undefined'`, { minify: true, target: 'chrome11' })).code, `a=typeof b<\"u\";\\n`)\n\n    assert.strictEqual((await esbuild.transform(`a = typeof b !== 'undefined'`, { minify: true, target: 'es2019' })).code, `a=typeof b!=\"undefined\";\\n`)\n    assert.strictEqual((await esbuild.transform(`a = typeof b !== 'undefined'`, { minify: true, target: 'ie11' })).code, `a=typeof b!=\"undefined\";\\n`)\n  },\n\n  async caseInsensitiveTarget({ esbuild }) {\n    assert.strictEqual((await esbuild.transform(`a ||= b`, { target: 'eS5' })).code, `a || (a = b);\\n`)\n    assert.strictEqual((await esbuild.transform(`a ||= b`, { target: 'eSnExT' })).code, `a ||= b;\\n`)\n  },\n\n  async propertyAccessBugWorkaroundForWebKit({ esbuild }) {\n    const check = async (target, input, expected) =>\n      assert.strictEqual((await esbuild.transform(input, { target })).code, expected)\n    await Promise.all([\n      check('safari16.2', `x(class{}.y=z)`, `x((class {\\n}).y = z);\\n`),\n      check('safari16.3', `x(class{}.y=z)`, `x(class {\\n}.y = z);\\n`),\n\n      check('safari16.2', `x(function(){}.y=z)`, `x((function() {\\n}).y = z);\\n`),\n      check('safari16.3', `x(function(){}.y=z)`, `x(function() {\\n}.y = z);\\n`),\n\n      check('safari16.2', `x(function*(){}.y=z)`, `x((function* () {\\n}).y = z);\\n`),\n      check('safari16.3', `x(function*(){}.y=z)`, `x(function* () {\\n}.y = z);\\n`),\n\n      check('safari16.2', `x(async function(){}.y=z)`, `x((async function() {\\n}).y = z);\\n`),\n      check('safari16.3', `x(async function(){}.y=z)`, `x(async function() {\\n}.y = z);\\n`),\n\n      check('safari16.2', `x(async function*(){}.y=z)`, `x((async function* () {\\n}).y = z);\\n`),\n      check('safari16.3', `x(async function*(){}.y=z)`, `x(async function* () {\\n}.y = z);\\n`),\n\n      // This should not be enabled by default\n      check('esnext', `x(class{}.y=z)`, `x(class {\\n}.y = z);\\n`),\n\n      // This doesn't need to be applied for methods in object literals\n      check('safari16.2', `x({f(a=-1){}}.y=z)`, `x({ f(a = -1) {\\n} }.y = z);\\n`),\n    ])\n  },\n\n  async multipleEngineTargets({ esbuild }) {\n    const check = async (target, expected) =>\n      assert.strictEqual((await esbuild.transform(`foo(a ?? b)`, { target })).code, expected)\n    await Promise.all([\n      check('es2020', `foo(a ?? b);\\n`),\n      check('es2019', `foo(a != null ? a : b);\\n`),\n\n      check('chrome80', `foo(a ?? b);\\n`),\n      check('chrome79', `foo(a != null ? a : b);\\n`),\n\n      check(['es2020', 'chrome80'], `foo(a ?? b);\\n`),\n      check(['es2020', 'chrome79'], `foo(a != null ? a : b);\\n`),\n      check(['es2019', 'chrome80'], `foo(a != null ? a : b);\\n`),\n    ])\n  },\n\n  async multipleEngineTargetsNotSupported({ esbuild }) {\n    try {\n      await esbuild.transform(`class X {}`, { target: ['es5', 'chrome1', 'safari2', 'firefox3'] })\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert.strictEqual(e.errors[0].text,\n        'Transforming class syntax to the configured target environment (\"chrome1\", \"es5\", \"firefox3\", \"safari2\") is not supported yet')\n    }\n  },\n\n  async supported({ esbuild }) {\n    const check = async (options, input, expected) => {\n      try {\n        assert.strictEqual((await esbuild.transform(input, options)).code, expected)\n      } catch (e) {\n        if (e.errors) assert.strictEqual(e.errors[0].text, expected)\n        else throw e\n      }\n    }\n\n    await Promise.all([\n      // JS: lower\n      check({ supported: { arrow: true } }, `x = () => y`, `x = () => y;\\n`),\n      check({ supported: { arrow: false } }, `x = () => y`, `x = function() {\\n  return y;\\n};\\n`),\n      check({ supported: { arrow: true }, target: 'es5' }, `x = () => y`, `x = () => y;\\n`),\n      check({ supported: { arrow: false }, target: 'es5' }, `x = () => y`, `x = function() {\\n  return y;\\n};\\n`),\n      check({ supported: { arrow: true }, target: 'es2022' }, `x = () => y`, `x = () => y;\\n`),\n      check({ supported: { arrow: false }, target: 'es2022' }, `x = () => y`, `x = function() {\\n  return y;\\n};\\n`),\n\n      // JS: error\n      check({ supported: { class: true } }, `class X {}`, `class X {\\n}\\n`),\n      check({ supported: { class: false } }, `class X {}`, `Transforming class syntax to the configured target environment is not supported yet`),\n      check({ supported: { class: true }, target: 'es5' }, `class X {}`, `class X {\\n}\\n`),\n      check({ supported: { class: false }, target: 'es5' }, `class X {}`, `Transforming class syntax to the configured target environment (\"es5\" + 11 overrides) is not supported yet`),\n      check({ supported: { class: true }, target: 'es6' }, `class X {}`, `class X {\\n}\\n`),\n      check({ supported: { class: false }, target: 'es6' }, `class X {}`, `Transforming class syntax to the configured target environment (\"es2015\" + 11 overrides) is not supported yet`),\n\n      // CSS: lower\n      check({ supported: { 'hex-rgba': true }, loader: 'css' }, `a { color: #1234 }`, `a {\\n  color: #1234;\\n}\\n`),\n      check({ supported: { 'hex-rgba': false }, loader: 'css' }, `a { color: #1234 }`, `a {\\n  color: rgba(17, 34, 51, .267);\\n}\\n`),\n      check({ target: 'safari15.3', loader: 'css' }, `a { mask-image: url(x.png) }`, `a {\\n  -webkit-mask-image: url(x.png);\\n  mask-image: url(x.png);\\n}\\n`),\n      check({ target: 'safari15.4', loader: 'css' }, `a { mask-image: url(x.png) }`, `a {\\n  mask-image: url(x.png);\\n}\\n`),\n\n      // Check for \"+ 2 overrides\"\n      check({ supported: { class: false, arrow: true }, target: 'es2022' }, `class X {}`, `Transforming class syntax to the configured target environment (\"es2022\" + 12 overrides) is not supported yet`),\n    ])\n  },\n\n  async regExpFeatures({ esbuild }) {\n    const check = async (target, input, expected) =>\n      assert.strictEqual((await esbuild.transform(input, { target })).code, expected)\n\n    await Promise.all([\n      // RegExpStickyAndUnicodeFlags\n      check('es6', `x1 = /./y`, `x1 = /./y;\\n`),\n      check('es6', `x2 = /./u`, `x2 = /./u;\\n`),\n      check('es5', `x3 = /./y`, `x3 = new RegExp(\".\", \"y\");\\n`),\n      check('es5', `x4 = /./u`, `x4 = new RegExp(\".\", \"u\");\\n`),\n\n      // RegExpDotAllFlag\n      check('es2018', `x1 = /a.b/s`, `x1 = /a.b/s;\\n`),\n      check('es2017', `x2 = /a.b/s`, `x2 = new RegExp(\"a.b\", \"s\");\\n`),\n\n      // RegExpLookbehindAssertions\n      check('es2018', `x1 = /(?<=x)/`, `x1 = /(?<=x)/;\\n`),\n      check('es2018', `x2 = /(?<!x)/`, `x2 = /(?<!x)/;\\n`),\n      check('es2017', `x3 = /(?<=x)/`, `x3 = new RegExp(\"(?<=x)\");\\n`),\n      check('es2017', `x4 = /(?<!x)/`, `x4 = new RegExp(\"(?<!x)\");\\n`),\n\n      // RegExpNamedCaptureGroups\n      check('es2018', `x1 = /(?<a>b)/`, `x1 = /(?<a>b)/;\\n`),\n      check('es2017', `x2 = /(?<a>b)/`, `x2 = new RegExp(\"(?<a>b)\");\\n`),\n\n      // RegExpUnicodePropertyEscapes\n      check('es2018', `x1 = /\\\\p{Emoji}/u`, `x1 = /\\\\p{Emoji}/u;\\n`),\n      check('es2017', `x2 = /\\\\p{Emoji}/u`, `x2 = new RegExp(\"\\\\\\\\p{Emoji}\", \"u\");\\n`),\n\n      // RegExpMatchIndices\n      check('es2022', `x1 = /y/d`, `x1 = /y/d;\\n`),\n      check('es2021', `x2 = /y/d`, `x2 = new RegExp(\"y\", \"d\");\\n`),\n\n      // RegExpSetNotation\n      check('es2024', `x1 = /[\\\\p{White_Space}&&\\\\p{ASCII}]/v`, `x1 = /[\\\\p{White_Space}&&\\\\p{ASCII}]/v;\\n`),\n      check('es2022', `x2 = /[\\\\p{White_Space}&&\\\\p{ASCII}]/v`, `x2 = new RegExp(\"[\\\\\\\\p{White_Space}&&\\\\\\\\p{ASCII}]\", \"v\");\\n`),\n    ])\n  },\n\n  // Future syntax\n  nonIdArrayRest: ({ esbuild }) => futureSyntax(esbuild, 'let [...[x]] = y', 'es2015', 'es2016'),\n  topLevelAwait: ({ esbuild }) => futureSyntax(esbuild, 'await foo', 'es2020', 'esnext'),\n  topLevelForAwait: ({ esbuild }) => futureSyntax(esbuild, 'for await (foo of bar) ;', 'es2020', 'esnext'),\n}\n\nfunction registerClassPrivateTests(target) {\n  let contents = `\n    class Field { #foo = 123; bar = this.#foo }\n    if (new Field().bar !== 123) throw 'fail: field'\n\n    class Method { bar = this.#foo(); #foo() { return 123 } }\n    if (new Method().bar !== 123) throw 'fail: method'\n\n    class Accessor { bar = this.#foo; get #foo() { return 123 } }\n    if (new Accessor().bar !== 123) throw 'fail: accessor'\n\n    class StaticField { static #foo = 123; static bar = StaticField.#foo }\n    if (StaticField.bar !== 123) throw 'fail: static field'\n\n    class StaticMethod { static bar = StaticMethod.#foo(); static #foo() { return 123 } }\n    if (StaticMethod.bar !== 123) throw 'fail: static method'\n\n    class StaticAccessor { static bar = StaticAccessor.#foo; static get #foo() { return 123 } }\n    if (StaticAccessor.bar !== 123) throw 'fail: static accessor'\n\n    class StaticFieldThis { static #foo = 123; static bar = this.#foo }\n    if (StaticFieldThis.bar !== 123) throw 'fail: static field'\n\n    class StaticMethodThis { static bar = this.#foo(); static #foo() { return 123 } }\n    if (StaticMethodThis.bar !== 123) throw 'fail: static method'\n\n    class StaticAccessorThis { static bar = this.#foo; static get #foo() { return 123 } }\n    if (StaticAccessorThis.bar !== 123) throw 'fail: static accessor'\n\n    class FieldFromStatic { #foo = 123; static bar = new FieldFromStatic().#foo }\n    if (FieldFromStatic.bar !== 123) throw 'fail: field from static'\n\n    class MethodFromStatic { static bar = new MethodFromStatic().#foo(); #foo() { return 123 } }\n    if (MethodFromStatic.bar !== 123) throw 'fail: method from static'\n\n    class AccessorFromStatic { static bar = new AccessorFromStatic().#foo; get #foo() { return 123 } }\n    if (AccessorFromStatic.bar !== 123) throw 'fail: accessor from static'\n  `\n\n  // Test this code as JavaScript\n  let buildOptions = {\n    stdin: { contents },\n    bundle: true,\n    write: false,\n    target,\n  }\n  transformTests[`transformClassPrivate_${target[0]}`] = async ({ esbuild }) =>\n    new Function((await esbuild.transform(contents, { target })).code)()\n  buildTests[`buildClassPrivate_${target[0]}`] = async ({ esbuild }) =>\n    new Function((await esbuild.build(buildOptions)).outputFiles[0].text)()\n\n  // Test this code as TypeScript\n  let buildOptionsTS = {\n    stdin: { contents, loader: 'ts' },\n    bundle: true,\n    write: false,\n  }\n  transformTests[`tsTransformClassPrivate_${target[0]}`] = async ({ esbuild }) =>\n    new Function((await esbuild.transform(contents, { target, loader: 'ts' })).code)()\n  buildTests[`tsBuildClassPrivate_${target[0]}`] = async ({ esbuild }) =>\n    new Function((await esbuild.build(buildOptionsTS)).outputFiles[0].text)()\n}\n\nfor (let es of ['es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext'])\n  registerClassPrivateTests([es])\nfor (let chrome = 49; chrome < 100; chrome++)\n  registerClassPrivateTests([`chrome${chrome}`])\nfor (let firefox = 45; firefox < 100; firefox++)\n  registerClassPrivateTests([`firefox${firefox}`])\nfor (let edge = 13; edge < 100; edge++)\n  registerClassPrivateTests([`edge${edge}`])\nfor (let safari = 10; safari < 20; safari++)\n  registerClassPrivateTests([`safari${safari}`])\n\nlet formatTests = {\n  async formatMessages({ esbuild }) {\n    const messages = await esbuild.formatMessages([\n      { text: 'This is an error' },\n      { text: 'Another error', location: { file: 'file.js' } },\n    ], {\n      kind: 'error',\n    })\n    assert.strictEqual(messages.length, 2)\n    assert.strictEqual(messages[0], `${errorIcon} [ERROR] This is an error\\n\\n`)\n    assert.strictEqual(messages[1], `${errorIcon} [ERROR] Another error\\n\\n    file.js:0:0:\\n      0 │ \\n        ╵ ^\\n\\n`)\n  },\n}\n\nlet analyzeTests = {\n  async analyzeMetafile({ esbuild }) {\n    const metafile = {\n      \"inputs\": {\n        \"entry.js\": {\n          \"bytes\": 50,\n          \"imports\": [\n            {\n              \"path\": \"lib.js\",\n              \"kind\": \"import-statement\"\n            }\n          ]\n        },\n        \"lib.js\": {\n          \"bytes\": 200,\n          \"imports\": []\n        }\n      },\n      \"outputs\": {\n        \"out.js\": {\n          \"imports\": [],\n          \"exports\": [],\n          \"entryPoint\": \"entry.js\",\n          \"inputs\": {\n            \"entry.js\": {\n              \"bytesInOutput\": 25\n            },\n            \"lib.js\": {\n              \"bytesInOutput\": 50\n            }\n          },\n          \"bytes\": 100\n        }\n      }\n    }\n    assert.strictEqual(await esbuild.analyzeMetafile(metafile), `\n  out.js       100b   100.0%\n   ├ lib.js     50b    50.0%\n   └ entry.js   25b    25.0%\n`)\n    assert.strictEqual(await esbuild.analyzeMetafile(metafile, { verbose: true }), `\n  out.js ────── 100b ── 100.0%\n   ├ lib.js ──── 50b ─── 50.0%\n   │  └ entry.js\n   └ entry.js ── 25b ─── 25.0%\n`)\n  },\n}\n\nlet functionScopeCases = [\n  'function x() {} { var x }',\n  'function* x() {} { var x }',\n  'async function x() {} { var x }',\n  'async function* x() {} { var x }',\n  '{ var x } function x() {}',\n  '{ var x } function* x() {}',\n  '{ var x } async function x() {}',\n  '{ var x } async function* x() {}',\n\n  '{ function x() {} { var x } }',\n  '{ function* x() {} { var x } }',\n  '{ async function x() {} { var x } }',\n  '{ async function* x() {} { var x } }',\n  '{ { var x } function x() {} }',\n  '{ { var x } function* x() {} }',\n  '{ { var x } async function x() {} }',\n  '{ { var x } async function* x() {} }',\n\n  'function f() { function x() {} { var x } }',\n  'function f() { function* x() {} { var x } }',\n  'function f() { async function x() {} { var x } }',\n  'function f() { async function* x() {} { var x } }',\n  'function f() { { var x } function x() {} }',\n  'function f() { { var x } function* x() {} }',\n  'function f() { { var x } async function x() {} }',\n  'function f() { { var x } async function* x() {} }',\n\n  'function f() { { function x() {} { var x } }}',\n  'function f() { { function* x() {} { var x } }}',\n  'function f() { { async function x() {} { var x } }}',\n  'function f() { { async function* x() {} { var x } }}',\n  'function f() { { { var x } function x() {} }}',\n  'function f() { { { var x } function* x() {} }}',\n  'function f() { { { var x } async function x() {} }}',\n  'function f() { { { var x } async function* x() {} }}',\n];\n\n{\n  let counter = 0;\n  for (let kind of ['var', 'let', 'const']) {\n    for (let code of functionScopeCases) {\n      code = code.replace('var', kind)\n      transformTests['functionScope' + counter++] = async ({ esbuild }) => {\n        let esbuildError\n        let nodeError\n        try { await esbuild.transform(code) } catch (e) { esbuildError = e }\n        try { new Function(code)() } catch (e) { nodeError = e }\n        if (!esbuildError !== !nodeError) {\n          throw new Error(`\n            code: ${code}\n            esbuild: ${esbuildError}\n            node: ${nodeError}\n          `)\n        }\n      }\n    }\n  }\n}\n\nlet apiSyncTests = {\n  async defaultExport({ esbuild }) {\n    assert.strictEqual(typeof esbuild.version, 'string')\n    assert.strictEqual(esbuild.version, esbuild.default.version)\n    assert.strictEqual(esbuild.version, esbuild.default.default.version)\n    assert.strictEqual(esbuild.version, esbuild.default.default.default.version)\n  },\n\n  async buildSync({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, 'export default 123')\n    esbuild.buildSync({ entryPoints: [input], bundle: true, outfile: output, format: 'cjs' })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n    assert.strictEqual(result.__esModule, true)\n  },\n\n  async buildSyncOutputFiles({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, 'module.exports = 123')\n    let prettyPath = path.relative(process.cwd(), input).split(path.sep).join('/')\n    let text = `// ${prettyPath}\\nmodule.exports = 123;\\n`\n    let result = esbuild.buildSync({ entryPoints: [input], bundle: true, outfile: output, format: 'cjs', write: false })\n    assert.strictEqual(result.outputFiles.length, 1)\n    assert.strictEqual(result.outputFiles[0].path, output)\n    assert.strictEqual(result.outputFiles[0].text, text)\n    assert.deepStrictEqual(result.outputFiles[0].contents, new Uint8Array(Buffer.from(text)))\n    assert.strictEqual(result.outputFiles[0].hash, 'H4KMzZ07fA0')\n  },\n\n  async transformSyncJSMap({ esbuild }) {\n    const { code, map } = esbuild.transformSync(`1+2`, { sourcemap: true })\n    assert.strictEqual(code, `1 + 2;\\n`)\n    assert.strictEqual(map, `{\n  \"version\": 3,\n  \"sources\": [\"<stdin>\"],\n  \"sourcesContent\": [\"1+2\"],\n  \"mappings\": \"AAAA,IAAE;\",\n  \"names\": []\n}\n`)\n  },\n\n  async transformSyncJSMapNoContent({ esbuild }) {\n    const { code, map } = esbuild.transformSync(`1+2`, { sourcemap: true, sourcesContent: false })\n    assert.strictEqual(code, `1 + 2;\\n`)\n    assert.strictEqual(map, `{\n  \"version\": 3,\n  \"sources\": [\"<stdin>\"],\n  \"mappings\": \"AAAA,IAAE;\",\n  \"names\": []\n}\n`)\n  },\n\n  async transformSyncCSS({ esbuild }) {\n    const { code, map } = esbuild.transformSync(`a{b:c}`, { loader: 'css' })\n    assert.strictEqual(code, `a {\\n  b: c;\\n}\\n`)\n    assert.strictEqual(map, '')\n  },\n\n  async transformSyncWithNonString({ esbuild }) {\n    try {\n      esbuild.transformSync(Object.create({ toString() { return '1+2' } }))\n      throw new Error('Expected an error to be thrown');\n    } catch (e) {\n      assert.strictEqual(e.errors ? e.errors[0].text : e + '', 'The input to \"transform\" must be a string or a Uint8Array')\n    }\n  },\n\n  async transformSync100x({ esbuild }) {\n    for (let i = 0; i < 100; i++) {\n      const { code } = esbuild.transformSync(`console.log(1+${i})`, {})\n      assert.strictEqual(code, `console.log(1 + ${i});\\n`)\n    }\n  },\n\n  async buildSyncThrow({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    try {\n      const output = path.join(testDir, 'out.js')\n      await writeFileAsync(input, '1+')\n      esbuild.buildSync({ entryPoints: [input], bundle: true, outfile: output, format: 'cjs', logLevel: 'silent' })\n      const result = require(output)\n      assert.strictEqual(result.default, 123)\n      assert.strictEqual(result.__esModule, true)\n      throw new Error('Expected an error to be thrown');\n    } catch (error) {\n      assert(error instanceof Error, 'Must be an Error object');\n      assert.strictEqual(error.message, `Build failed with 1 error:\n${path.relative(process.cwd(), input).split(path.sep).join('/')}:1:2: ERROR: Unexpected end of file`);\n      assert.strictEqual(error.errors.length, 1);\n      assert.strictEqual(error.warnings.length, 0);\n    }\n  },\n\n  async transformThrow({ esbuild }) {\n    try {\n      await esbuild.transform(`1+`, {})\n      throw new Error('Expected an error to be thrown');\n    } catch (error) {\n      assert(error instanceof Error, 'Must be an Error object');\n      assert.strictEqual(error.message, `Transform failed with 1 error:\\n<stdin>:1:2: ERROR: Unexpected end of file`);\n      assert.strictEqual(error.errors.length, 1);\n      assert.strictEqual(error.warnings.length, 0);\n    }\n  },\n\n  async formatMessagesSync({ esbuild }) {\n    const messages = esbuild.formatMessagesSync([\n      { text: 'This is an error' },\n      { text: 'Another error', location: { file: 'file.js' } },\n    ], {\n      kind: 'error',\n    })\n    assert.strictEqual(messages.length, 2)\n    assert.strictEqual(messages[0], `${errorIcon} [ERROR] This is an error\\n\\n`)\n    assert.strictEqual(messages[1], `${errorIcon} [ERROR] Another error\\n\\n    file.js:0:0:\\n      0 │ \\n        ╵ ^\\n\\n`)\n  },\n\n  async analyzeMetafileSync({ esbuild }) {\n    const metafile = {\n      \"inputs\": {\n        \"entry.js\": {\n          \"bytes\": 50,\n          \"imports\": [\n            {\n              \"path\": \"lib.js\",\n              \"kind\": \"import-statement\"\n            }\n          ]\n        },\n        \"lib.js\": {\n          \"bytes\": 200,\n          \"imports\": []\n        }\n      },\n      \"outputs\": {\n        \"out.js\": {\n          \"imports\": [],\n          \"exports\": [],\n          \"entryPoint\": \"entry.js\",\n          \"inputs\": {\n            \"entry.js\": {\n              \"bytesInOutput\": 25\n            },\n            \"lib.js\": {\n              \"bytesInOutput\": 50\n            }\n          },\n          \"bytes\": 100\n        }\n      }\n    }\n    assert.strictEqual(esbuild.analyzeMetafileSync(metafile), `\n  out.js       100b   100.0%\n   ├ lib.js     50b    50.0%\n   └ entry.js   25b    25.0%\n`)\n    assert.strictEqual(esbuild.analyzeMetafileSync(metafile, { verbose: true }), `\n  out.js ────── 100b ── 100.0%\n   ├ lib.js ──── 50b ─── 50.0%\n   │  └ entry.js\n   └ entry.js ── 25b ─── 25.0%\n`)\n  },\n}\n\nlet childProcessTests = {\n  // More info about this test case: https://github.com/evanw/esbuild/issues/2727\n  async testIncrementalChildProcessExit({ testDir, esbuild }) {\n    const file = path.join(testDir, 'build.js')\n\n    await writeFileAsync(file, `\n      const esbuild = require(${JSON.stringify(esbuild.ESBUILD_PACKAGE_PATH)})\n      esbuild.context({\n        entryPoints: [],\n      })\n      .then(context => context.rebuild())\n      .then(() => {\n        console.log('success')\n        process.exit(0)\n      })\n    `)\n\n    let timeout\n    const detectHangPromise = new Promise((_, reject) => {\n      timeout = setTimeout(() => {\n        reject(new Error('Timed out waiting for keep-alive check to terminate'))\n      }, 5 * 60 * 1000)\n    })\n\n    const testKeepAlivePingPromise = new Promise((resolve, reject) => {\n      child_process.execFile('node', [file], {\n        stdio: [\n          'inherit',\n          'inherit',\n          'pipe', // This is important for the test to check for the hang\n        ],\n      }, (error, stdout, stderr) => {\n        clearTimeout(timeout)\n        if (error) reject(error)\n        else if (stdout !== 'success\\n') reject(new Error('Unexpected stdout: ' + JSON.stringify(stdout)))\n        else if (stderr !== '') reject(new Error('Unexpected stderr: ' + JSON.stringify(stderr)))\n        else resolve()\n      })\n    })\n\n    await Promise.race([\n      detectHangPromise,\n      testKeepAlivePingPromise,\n    ])\n  },\n\n  async testWatchStdoutChildProcess({ testDir, esbuild }) {\n    const sequence = [\n      {\n        input: 'console.log(1+2)',\n        stdout: ['console.log(1 + 2);'],\n        stderr: ['[watch] build finished, watching for changes...'],\n      },\n      {\n        input: 'console.log(2+3)',\n        stdout: ['console.log(2 + 3);'],\n        stderr: ['[watch] build started (change: \"in.js\")', '[watch] build finished'],\n      },\n      {\n        input: 'console.log(3+4)',\n        stdout: ['console.log(3 + 4);'],\n        stderr: ['[watch] build started (change: \"in.js\")', '[watch] build finished'],\n      },\n    ]\n\n    const infile = path.join(testDir, 'in.js')\n    const file = path.join(testDir, 'build.js')\n    await writeFileAsync(infile, sequence[0].input)\n    await writeFileAsync(file, `\n      const esbuild = require(${JSON.stringify(esbuild.ESBUILD_PACKAGE_PATH)})\n      esbuild.context({\n        entryPoints: [${JSON.stringify(infile)}],\n        logLevel: 'info',\n      }).then(ctx => ctx.watch())\n    `)\n\n    // Start the child\n    const maxSeconds = 60\n    const child = child_process.spawn('node', [file], {\n      cwd: testDir,\n      stdio: ['inherit', 'pipe', 'pipe'],\n      timeout: maxSeconds * 1000,\n    })\n\n    // Make sure the child is always killed\n    try {\n      for (const { input, stdout: expectedStdout, stderr: expectedStderr } of sequence) {\n        let totalStdout = ''\n        let totalStderr = ''\n        let stdoutBuffer = ''\n        let stderrBuffer = ''\n        const onstdout = data => {\n          totalStdout += data\n          stdoutBuffer += data\n          check()\n        }\n        const onstderr = data => {\n          totalStderr += data\n          stderrBuffer += data\n          check()\n        }\n        let check = () => { }\n\n        child.stdout.on('data', onstdout)\n        child.stderr.on('data', onstderr)\n\n        await new Promise((resolve, reject) => {\n          const seconds = 30\n          const timeout = setTimeout(() => reject(new Error(\n            `Watch mode + stdout test failed to match expected output after ${seconds} seconds\n  input: ${JSON.stringify(input)}\n  stdout: ${JSON.stringify(totalStdout)}\n  stderr: ${JSON.stringify(totalStderr)}\n`)), seconds * 1000)\n\n          check = () => {\n            let index\n\n            while ((index = stdoutBuffer.indexOf('\\n')) >= 0) {\n              const line = stdoutBuffer.slice(0, index)\n              stdoutBuffer = stdoutBuffer.slice(index + 1)\n              if (line === expectedStdout[0]) expectedStdout.shift()\n            }\n\n            while ((index = stderrBuffer.indexOf('\\n')) >= 0) {\n              const line = stderrBuffer.slice(0, index)\n              stderrBuffer = stderrBuffer.slice(index + 1)\n              if (line === expectedStderr[0]) expectedStderr.shift()\n            }\n\n            if (!expectedStdout.length && !expectedStderr.length) {\n              clearTimeout(timeout)\n              resolve()\n            }\n          }\n\n          writeFileAtomic(infile, input)\n        })\n\n        child.stdout.off('data', onstdout)\n        child.stderr.off('data', onstderr)\n      }\n    } finally {\n      child.kill()\n    }\n  },\n}\n\nlet serialTests = {\n  async startStop({ esbuild }) {\n    for (let i = 0; i < 3; i++) {\n      let result1 = await esbuild.transform('1+2')\n      assert.strictEqual(result1.code, '1 + 2;\\n')\n\n      let result2 = esbuild.transformSync('2+3')\n      assert.strictEqual(result2.code, '2 + 3;\\n')\n\n      let result3 = await esbuild.build({ stdin: { contents: '1+2' }, write: false })\n      assert.strictEqual(result3.outputFiles[0].text, '1 + 2;\\n')\n\n      let result4 = esbuild.buildSync({ stdin: { contents: '2+3' }, write: false })\n      assert.strictEqual(result4.outputFiles[0].text, '2 + 3;\\n')\n\n      esbuild.stop()\n    }\n  },\n}\n\nasync function assertSourceMap(jsSourceMap, source) {\n  jsSourceMap = JSON.parse(jsSourceMap)\n  assert.deepStrictEqual(jsSourceMap.version, 3)\n  assert.deepStrictEqual(jsSourceMap.sources, [source])\n  assert.deepStrictEqual(jsSourceMap.sourcesContent, ['let       x'])\n  assert.deepStrictEqual(jsSourceMap.mappings, 'AAAA,IAAU;')\n}\n\nasync function main() {\n  const esbuild = installForTests()\n\n  // Create a fresh test directory\n  removeRecursiveSync(rootTestDir)\n  fs.mkdirSync(rootTestDir)\n\n  // Time out these tests after 5 minutes. This exists to help debug test hangs in CI.\n  let minutes = 5\n  let timeout = setTimeout(() => {\n    console.error(`❌ js api tests timed out after ${minutes} minutes, exiting...`)\n    process.exit(1)\n  }, minutes * 60 * 1000)\n\n  const runTest = async (name, fn) => {\n    let testDir = path.join(rootTestDir, name)\n    try {\n      await mkdirAsync(testDir)\n      await fn({ esbuild, testDir })\n      removeRecursiveSync(testDir)\n      return true\n    } catch (e) {\n      console.error(`❌ ${name}: ${e && e.message || e}`)\n      return false\n    }\n  }\n\n  const tests = [\n    ...Object.entries(buildTests),\n    ...Object.entries(watchTests),\n    ...Object.entries(serveTests),\n    ...Object.entries(transformTests),\n    ...Object.entries(formatTests),\n    ...Object.entries(analyzeTests),\n    ...Object.entries(apiSyncTests),\n    ...Object.entries(childProcessTests),\n  ]\n\n  // Run everything in \"tests\" concurrently\n  let allTestsPassed = (await Promise.all(tests.map(([name, fn]) => {\n    const promise = runTest(name, fn)\n\n    // Time out each individual test after 3 minutes. This exists to help debug test hangs in CI.\n    const minutes = 3\n    const timeout = setTimeout(() => {\n      console.error(`❌ the test \"${name}\" timed out after ${minutes} minutes, exiting...`)\n      process.exit(1)\n    }, minutes * 60 * 1000)\n    return promise.finally(() => clearTimeout(timeout))\n  }))).every(success => success)\n\n  // Run everything in \"serialTests\" in serial\n  for (let [name, fn] of Object.entries(serialTests)) {\n    if (!await runTest(name, fn)) {\n      allTestsPassed = false\n    }\n  }\n\n  if (!allTestsPassed) {\n    console.error(`❌ js api tests failed`)\n    process.exit(1)\n  } else {\n    console.log(`✅ js api tests passed`)\n    removeRecursiveSync(rootTestDir)\n  }\n\n  clearTimeout(timeout);\n}\n\nmain().catch(e => setTimeout(() => { throw e }))\n"
  },
  {
    "path": "scripts/node-unref-tests.js",
    "content": "// This test verifies that:\n//  - a running service will not prevent NodeJS to exit if there is no compilation in progress.\n//  - the NodeJS process will continue running if there is a serve() active or a transform or build in progress.\n\nconst assert = require('assert')\nconst { fork } = require('child_process');\n\n// The tests to run in the child process\nasync function tests() {\n  const esbuild = require('./esbuild').installForTests()\n\n  async function testTransform() {\n    const t1 = await esbuild.transform(`1+2`)\n    const t2 = await esbuild.transform(`1+3`)\n    assert.strictEqual(t1.code, `1 + 2;\\n`)\n    assert.strictEqual(t2.code, `1 + 3;\\n`)\n  }\n\n  async function testServe() {\n    const context = await esbuild.context({})\n    try {\n      const server = await context.serve({})\n      assert(server.hosts.includes('127.0.0.1'))\n      assert.strictEqual(typeof server.port, 'number')\n    } finally {\n      await context.dispose()\n    }\n  }\n\n  async function testBuild() {\n    const context = await esbuild.context({\n      stdin: { contents: '1+2' },\n      write: false,\n    })\n    try {\n\n      const result = await context.rebuild()\n      assert.deepStrictEqual(result.outputFiles.length, 1);\n      assert.deepStrictEqual(result.outputFiles[0].text, '1 + 2;\\n');\n\n      const result2 = await context.rebuild()\n      assert.deepStrictEqual(result2.outputFiles.length, 1);\n      assert.deepStrictEqual(result2.outputFiles[0].text, '1 + 2;\\n');\n    } finally {\n      await context.dispose()\n    }\n  }\n\n  async function testWatchAndIncremental() {\n    const context = await esbuild.context({\n      stdin: { contents: '1+2' },\n      write: false,\n    })\n    try {\n      await context.watch()\n\n      const result = await context.rebuild()\n      assert.deepStrictEqual(result.outputFiles.length, 1);\n      assert.deepStrictEqual(result.outputFiles[0].text, '1 + 2;\\n');\n\n    } finally {\n      await context.dispose()\n    }\n  }\n\n  await testTransform()\n  await testServe()\n  await testBuild()\n  await testWatchAndIncremental()\n}\n\n// Called when this is the child process to run the tests.\nfunction runTests() {\n  process.exitCode = 1;\n  tests().then(() => {\n    process.exitCode = 0;\n  }, (error) => {\n    console.error('❌', error)\n  });\n}\n\n// A child process need to be started to verify that a running service is not hanging node.\nfunction startChildProcess() {\n  const child = fork(__filename, ['__forked__'], { stdio: 'inherit', env: process.env });\n\n  const timeout = setTimeout(() => {\n    console.error('❌ node unref test timeout - child_process.unref() broken?')\n    process.exit(1);\n  }, 5 * 60 * 1000);\n\n  child.on('error', (error) => {\n    console.error('❌', error);\n    process.exit(1);\n  })\n\n  child.on('exit', (code) => {\n    clearTimeout(timeout);\n    if (code) {\n      console.error(`❌ node unref tests failed: child exited with code ${code}`)\n      process.exit(1);\n    } else {\n      console.log(`✅ node unref tests passed`)\n    }\n  })\n}\n\nif (process.argv[2] === '__forked__') {\n  runTests();\n} else {\n  startChildProcess();\n}\n"
  },
  {
    "path": "scripts/package.json",
    "content": "{\n  \"dependencies\": {\n    \"@types/node\": \"14.14.6\",\n    \"@unicode/unicode-15.1.0\": \"1.5.2\",\n    \"@unicode/unicode-3.0.0\": \"1.0.6\",\n    \"fuse.js\": \"3.2.0\",\n    \"js-yaml\": \"3.14.0\",\n    \"react\": \"17.0.1\",\n    \"source-map\": \"0.7.4\",\n    \"typescript\": \"4.7.4\"\n  }\n}\n"
  },
  {
    "path": "scripts/parse-ts-files.js",
    "content": "// This script parses all .ts and .tsx files in the current directory using\n// esbuild. This is useful to check for parser bugs and/or crashes in esbuild.\n\nconst fs = require('fs');\nconst os = require('os');\nconst path = require('path');\nconst ts = require('typescript');\nconst child_process = require('child_process');\nconst esbuildPath = path.join(path.dirname(__dirname), 'esbuild');\n\nfunction walkDir(root, cb) {\n  for (const entry of fs.readdirSync(root)) {\n    const absolute = path.join(root, entry);\n    if (fs.statSync(absolute).isDirectory()) {\n      walkDir(absolute, cb);\n    } else if ((entry.endsWith('.ts') && !entry.endsWith('.d.ts')) || entry.endsWith('.tsx')) {\n      cb(absolute)\n    }\n  }\n}\n\nchild_process.execSync('make', { cwd: path.dirname(__dirname) });\n\n// Doing one file at a time is useful for debugging crashes\nif (process.argv.includes('--individual')) {\n  walkDir(process.cwd(), absolute => {\n    let output = child_process.spawnSync(esbuildPath, [absolute, '--outfile=/dev/null'], { stdio: ['inherit', 'pipe', 'pipe'] });\n    if (output.status) {\n      let result;\n      try {\n        result = ts.transpileModule(fs.readFileSync(absolute, 'utf8'), { reportDiagnostics: true });\n      } catch (e) {\n        // Ignore this file if the TypeScript compiler crashes on it\n        return\n      }\n      if (result.diagnostics.length > 0) {\n        // Ignore this file if the TypeScript compiler has parse errors\n        return\n      }\n      console.log('-'.repeat(80));\n      console.log('Failure:', absolute);\n      console.log('-'.repeat(20) + ' esbuild output:');\n      console.log(output.stdout + output.stderr);\n    }\n  });\n}\n\n// Otherwise it's much faster to do everything at once\nelse {\n  const tempDir = path.join(os.tmpdir(), 'esbuild-parse-ts-files');\n  try {\n    fs.mkdirSync(tempDir);\n  } catch (e) {\n  }\n  const all = [];\n  walkDir(process.cwd(), absolute => all.push(absolute));\n  try {\n    child_process.execFileSync(esbuildPath, ['--outdir=' + tempDir].concat(all), { stdio: 'inherit' });\n  } catch (e) {\n  }\n}\n"
  },
  {
    "path": "scripts/plugin-tests.js",
    "content": "const { installForTests, removeRecursiveSync, writeFileAtomic } = require('./esbuild')\nconst assert = require('assert')\nconst path = require('path')\nconst util = require('util')\nconst http = require('http')\nconst url = require('url')\nconst fs = require('fs')\n\nconst readFileAsync = util.promisify(fs.readFile)\nconst writeFileAsync = util.promisify(fs.writeFile)\nconst mkdirAsync = util.promisify(fs.mkdir)\n\nconst repoDir = path.dirname(__dirname)\nconst rootTestDir = path.join(repoDir, 'scripts', '.plugin-tests')\n\nfunction fetch(host, port, path) {\n  return new Promise((resolve, reject) => {\n    http.get({ host, port, path }, res => {\n      const chunks = []\n      res.on('data', chunk => chunks.push(chunk))\n      res.on('end', () => {\n        const content = Buffer.concat(chunks)\n        if (res.statusCode < 200 || res.statusCode > 299) {\n          const error = new Error(`${res.statusCode} when fetching ${path}: ${content}`)\n          error.statusCode = res.statusCode\n          reject(error)\n        } else {\n          content.headers = res.headers\n          resolve(content)\n        }\n      })\n    }).on('error', reject)\n  })\n}\n\nfunction fetchUntilSuccessOrTimeout(host, port, path) {\n  const seconds = 5\n  let timeout\n  let stop = false\n  const cancel = () => clearTimeout(timeout)\n  const promise = Promise.race([\n    new Promise((_, reject) => {\n      timeout = setTimeout(() => {\n        stop = true\n        reject(new Error(`Waited more than ${seconds} seconds while trying to fetch \"http://${host}:${port}${path}\"`))\n      }, seconds * 1000)\n    }),\n    (async () => {\n      while (!stop) {\n        try {\n          return await fetch(host, port, path)\n        } catch {\n        }\n      }\n    })(),\n  ])\n  promise.then(cancel, cancel)\n  return promise\n}\n\nlet pluginTests = {\n  async noPluginsWithBuildSync({ esbuild }) {\n    try {\n      esbuild.buildSync({\n        entryPoints: [], logLevel: 'silent', plugins: [{\n          name: 'name',\n          setup() { },\n        }],\n      })\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert.strictEqual(e.message.split('\\n')[0], 'Build failed with 1 error:')\n      assert.notStrictEqual(e.errors, void 0)\n      assert.strictEqual(e.errors.length, 1)\n      assert.strictEqual(e.errors[0].text, 'Cannot use plugins in synchronous API calls')\n      assert.deepStrictEqual(e.warnings, [])\n    }\n  },\n\n  async emptyArray({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `export default 123`)\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n  },\n\n  async emptyArrayWithBuildSync({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `export default 123`)\n    esbuild.buildSync({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n  },\n\n  async invalidRegExp({ esbuild }) {\n    for (const filter of [/x(?=y)/, /x(?!y)/, /x(?<=y)/, /x(?<!y)/, /(x)\\1/]) {\n      // onResolve\n      try {\n        await esbuild.build({\n          entryPoints: ['invalid.js'],\n          write: false,\n          plugins: [{\n            name: 'name',\n            setup(build) {\n              build.onResolve({ filter }, () => { })\n            },\n          }],\n        })\n        throw new Error(`Expected filter ${filter} to fail`)\n      } catch (e) {\n        assert.strictEqual(e.message, `[name] \"onResolve\" filter is not a valid Go regular expression: ${JSON.stringify(filter.source)}`)\n      }\n\n      // onLoad\n      try {\n        await esbuild.build({\n          entryPoints: ['invalid.js'],\n          write: false,\n          plugins: [{\n            name: 'name',\n            setup(build) {\n              build.onLoad({ filter }, () => { })\n            },\n          }],\n        })\n        throw new Error(`Expected filter ${filter} to fail`)\n      } catch (e) {\n        assert.strictEqual(e.message, `[name] \"onLoad\" filter is not a valid Go regular expression: ${JSON.stringify(filter.source)}`)\n      }\n    }\n  },\n\n  async caseInsensitiveRegExp({ esbuild, testDir }) {\n    const inputJs = path.join(testDir, 'in.js')\n    await writeFileAsync(inputJs, `export default 123`)\n\n    const inputCpp = path.join(testDir, 'in.CpP')\n    await writeFileAsync(inputCpp, `export default 123`)\n\n    // onResolve\n    const onResolveResult = await esbuild.build({\n      entryPoints: ['example.CpP'],\n      write: false,\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /\\.c(pp|xx)?$/i }, args => {\n            assert.strictEqual(args.path, 'example.CpP')\n            return { path: inputJs }\n          })\n        },\n      }],\n    })\n    assert.strictEqual(onResolveResult.outputFiles.length, 1)\n    assert.strictEqual(onResolveResult.outputFiles[0].text, `export default 123;\\n`)\n\n    // onLoad\n    const onLoadResult = await esbuild.build({\n      entryPoints: [inputCpp],\n      write: false,\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onLoad({ filter: /\\.c(pp|xx)?$/i }, args => {\n            assert(args.path.endsWith('in.CpP'))\n            return { contents: 'export default true' }\n          })\n        },\n      }],\n    })\n    assert.strictEqual(onLoadResult.outputFiles.length, 1)\n    assert.strictEqual(onLoadResult.outputFiles[0].text, `export default true;\\n`)\n  },\n\n  async pluginMissingName({ esbuild }) {\n    try {\n      await esbuild.build({\n        entryPoints: [],\n        logLevel: 'silent',\n        plugins: [{\n          setup(build) {\n          },\n        }],\n      })\n    } catch (e) {\n      assert.strictEqual(e.message.split('\\n')[0], 'Build failed with 1 error:')\n      assert.notStrictEqual(e.errors, void 0)\n      assert.strictEqual(e.errors.length, 1)\n      assert.strictEqual(e.errors[0].text, 'Plugin at index 0 is missing a name')\n      assert.deepStrictEqual(e.warnings, [])\n    }\n  },\n\n  async pluginMissingSetup({ esbuild }) {\n    try {\n      await esbuild.build({\n        entryPoints: [],\n        logLevel: 'silent',\n        plugins: [{\n          name: 'x',\n        }],\n      })\n    } catch (e) {\n      assert.strictEqual(e.message.split('\\n')[0], 'Build failed with 1 error:')\n      assert.notStrictEqual(e.errors, void 0)\n      assert.strictEqual(e.errors.length, 1)\n      assert.strictEqual(e.errors[0].pluginName, 'x')\n      assert.strictEqual(e.errors[0].text, 'Plugin is missing a setup function')\n      assert.deepStrictEqual(e.warnings, [])\n    }\n  },\n\n  async badPluginProperty({ esbuild }) {\n    try {\n      await esbuild.build({\n        entryPoints: [],\n        logLevel: 'silent',\n        plugins: [{\n          name: 'x',\n          someRandomProperty: void 0,\n          setup(build) {\n          },\n        }],\n      })\n    } catch (e) {\n      assert.strictEqual(e.message.split('\\n')[0], 'Build failed with 1 error:')\n      assert.notStrictEqual(e.errors, void 0)\n      assert.strictEqual(e.errors.length, 1)\n      assert.strictEqual(e.errors[0].text, 'Invalid option on plugin \"x\": \"someRandomProperty\"')\n      assert.deepStrictEqual(e.warnings, [])\n    }\n  },\n\n  async badPluginOnResolveProperty({ esbuild }) {\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        logLevel: 'silent',\n        plugins: [{\n          name: 'x',\n          setup(build) {\n            build.onResolve({ whatIsThis: void 0 }, () => {\n            })\n          },\n        }],\n      })\n    } catch (e) {\n      assert.strictEqual(e.message.split('\\n')[0], 'Build failed with 1 error:')\n      assert.notStrictEqual(e.errors, void 0)\n      assert.strictEqual(e.errors.length, 1)\n      assert.strictEqual(e.errors[0].text, 'Invalid option in onResolve() call for plugin \"x\": \"whatIsThis\"')\n      assert.deepStrictEqual(e.warnings, [])\n    }\n\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        logLevel: 'silent',\n        write: false,\n        plugins: [{\n          name: 'x',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, () => {\n              return '/'\n            })\n          },\n        }],\n      })\n    } catch (e) {\n      assert(e.message.endsWith('ERROR: [plugin: x] Expected onResolve() callback in plugin \"x\" to return an object'), e.message)\n    }\n\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        logLevel: 'silent',\n        write: false,\n        plugins: [{\n          name: 'x',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, () => {\n              return { thisIsWrong: void 0 }\n            })\n          },\n        }],\n      })\n    } catch (e) {\n      assert(e.message.endsWith('ERROR: [plugin: x] Invalid option from onResolve() callback in plugin \"x\": \"thisIsWrong\"'), e.message)\n    }\n  },\n\n  async badPluginOnLoadProperty({ esbuild }) {\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        logLevel: 'silent',\n        plugins: [{\n          name: 'x',\n          setup(build) {\n            build.onLoad({ whatIsThis: void 0 }, () => {\n            })\n          },\n        }],\n      })\n    } catch (e) {\n      assert.strictEqual(e.message.split('\\n')[0], 'Build failed with 1 error:')\n      assert.notStrictEqual(e.errors, void 0)\n      assert.strictEqual(e.errors.length, 1)\n      assert.strictEqual(e.errors[0].text, 'Invalid option in onLoad() call for plugin \"x\": \"whatIsThis\"')\n      assert.deepStrictEqual(e.warnings, [])\n    }\n\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        logLevel: 'silent',\n        write: false,\n        plugins: [{\n          name: 'x',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, () => {\n              return { path: 'y', namespace: 'z' }\n            })\n            build.onLoad({ filter: /.*/ }, () => {\n              return \"\"\n            })\n          },\n        }],\n      })\n    } catch (e) {\n      assert(e.message.endsWith(`ERROR: [plugin: x] Expected onLoad() callback in plugin \"x\" to return an object`), e.message)\n    }\n\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        logLevel: 'silent',\n        write: false,\n        plugins: [{\n          name: 'x',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, () => {\n              return { path: 'y', namespace: 'z' }\n            })\n            build.onLoad({ filter: /.*/ }, () => {\n              return { thisIsWrong: void 0 }\n            })\n          },\n        }],\n      })\n    } catch (e) {\n      assert(e.message.endsWith('ERROR: [plugin: x] Invalid option from onLoad() callback in plugin \"x\": \"thisIsWrong\"'), e.message)\n    }\n  },\n\n  async modifyInitialOptions({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.what')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `export default 123`)\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'what',\n        setup(build) {\n          build.initialOptions.loader = { '.what': 'js' }\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n  },\n\n  async modifyInitialOptionsAsync({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.what')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `export default 123`)\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'what',\n        async setup(build) {\n          await new Promise(r => setTimeout(r, 100))\n          build.initialOptions.loader = { '.what': 'js' }\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n  },\n\n  async basicLoader({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const custom = path.join(testDir, 'example.custom')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `\n      import x from './example.custom'\n      export default x\n    `)\n    await writeFileAsync(custom, ``)\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onLoad({ filter: /\\.custom$/ }, args => {\n            assert.strictEqual(args.path, custom)\n            return { contents: 'this is custom', loader: 'text' }\n          })\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 'this is custom')\n  },\n\n  async basicResolver({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const custom = path.join(testDir, 'example.txt')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `\n      import x from 'test'\n      export default x\n    `)\n    await writeFileAsync(custom, `example text`)\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /^test$/ }, args => {\n            assert.strictEqual(args.path, 'test')\n            return { path: custom }\n          })\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 'example text')\n  },\n\n  async fibonacciResolverMemoized({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `\n      import x from 'fib(10)'\n      export default x\n    `)\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /^fib\\((\\d+)\\)$/ }, args => {\n            return { path: args.path, namespace: 'fib' }\n          })\n          build.onLoad({ filter: /^fib\\((\\d+)\\)$/, namespace: 'fib' }, args => {\n            let match = /^fib\\((\\d+)\\)$/.exec(args.path), n = +match[1]\n            let contents = n < 2 ? `export default ${n}` : `\n              import n1 from 'fib(${n - 1})'\n              import n2 from 'fib(${n - 2})'\n              export default n1 + n2`\n            return { contents }\n          })\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 55)\n  },\n\n  async fibonacciResolverNotMemoized({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `\n      import x from 'fib(10)'\n      export default x\n    `)\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /^fib\\((\\d+)\\)/ }, args => {\n            return { path: args.path, namespace: 'fib' }\n          })\n          build.onLoad({ filter: /^fib\\((\\d+)\\)/, namespace: 'fib' }, args => {\n            let match = /^fib\\((\\d+)\\)/.exec(args.path), n = +match[1]\n            let contents = n < 2 ? `export default ${n}` : `\n              import n1 from 'fib(${n - 1}) ${args.path}'\n              import n2 from 'fib(${n - 2}) ${args.path}'\n              export default n1 + n2`\n            return { contents }\n          })\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 55)\n  },\n\n  async resolversCalledInSequence({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const nested = path.join(testDir, 'nested.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `\n      import x from 'test'\n      export default x\n    `)\n    await writeFileAsync(nested, `\n      export default 123\n    `)\n    let trace = []\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [\n        {\n          name: 'plugin1',\n          setup(build) {\n            build.onResolve({ filter: /^.*$/ }, () => { trace.push('called first') })\n          },\n        },\n        {\n          name: 'plugin2',\n          setup(build) {\n            build.onResolve({ filter: /^ignore me$/ }, () => { trace.push('not called') })\n          },\n        },\n        {\n          name: 'plugin3',\n          setup(build) {\n            build.onResolve({ filter: /^.*$/ }, () => {\n              trace.push('called second')\n              return { path: nested }\n            })\n          },\n        },\n        {\n          name: 'plugin4',\n          setup(build) {\n            build.onResolve({ filter: /^.*$/ }, () => { trace.push('not called') })\n          },\n        }\n      ],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n    assert.deepStrictEqual(trace, [\n      'called first',\n      'called second',\n    ])\n  },\n\n  async loadersCalledInSequence({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const nested = path.join(testDir, 'nested.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `\n      import x from './nested.js'\n      export default x\n    `)\n    await writeFileAsync(nested, `\n      export default 123\n    `)\n    let trace = []\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [\n        {\n          name: 'plugin1',\n          setup(build) {\n            build.onLoad({ filter: /^.*$/ }, () => { trace.push('called first') })\n          },\n        },\n        {\n          name: 'plugin2',\n          setup(build) {\n            build.onLoad({ filter: /^.*$/, namespace: 'ignore-me' }, () => { trace.push('not called') })\n          },\n        },\n        {\n          name: 'plugin3',\n          setup(build) {\n            build.onLoad({ filter: /^.*$/, namespace: 'file' }, () => {\n              trace.push('called second')\n              return { contents: 'export default \"abc\"' }\n            })\n          },\n        },\n        {\n          name: 'plugin4',\n          setup(build) {\n            build.onLoad({ filter: /^.*$/, namespace: 'file' }, () => { trace.push('not called') })\n          },\n        },\n      ],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 'abc')\n    assert.deepStrictEqual(trace, [\n      'called first',\n      'called second',\n    ])\n  },\n\n  async httpRelative({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `\n      import x from 'http://example.com/assets/js/example.js'\n      export default x\n    `)\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /^http:\\/\\// }, args => {\n            return { path: args.path, namespace: 'http' }\n          })\n          build.onResolve({ filter: /.*/, namespace: 'http' }, args => {\n            return { path: new URL(args.path, args.importer).toString(), namespace: 'http' }\n          })\n          build.onLoad({ filter: /^http:\\/\\//, namespace: 'http' }, args => {\n            switch (args.path) {\n              case 'http://example.com/assets/js/example.js':\n                return { contents: `import y from './data/base.js'; export default y` }\n              case 'http://example.com/assets/js/data/base.js':\n                return { contents: `export default 123` }\n            }\n          })\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n  },\n\n  async rewriteExternalWithNamespace({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `\n      import {exists} from 'extern'\n      export default exists\n    `)\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /^extern$/ }, () => {\n            return { path: 'fs', external: true, namespace: 'for-testing' }\n          })\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, fs.exists)\n  },\n\n  async rewriteExternalWithoutNamespace({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `\n      import {exists} from 'extern'\n      export default exists\n    `)\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /^extern$/ }, () => {\n            return { path: 'fs', external: true }\n          })\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, fs.exists)\n  },\n\n  async rewriteExternalWithFileNamespace({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const outdir = path.join(testDir, 'out')\n    const outdir2 = path.join(testDir, 'out2')\n    const target = path.join(outdir2, 'target.js')\n    await writeFileAsync(input, `\n      import {exists} from 'extern'\n      export default exists\n    `)\n    await mkdirAsync(outdir2, { recursive: true })\n    await writeFileAsync(target, `\n      module.exports = require('fs')\n    `)\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outdir,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /^extern$/ }, () => {\n            return { path: path.join(outdir, 'target'), external: true, namespace: 'file' }\n          })\n        },\n      }],\n    })\n\n    // Move the file to show that the output has a relative path\n    await fs.promises.rename(path.join(outdir, 'in.js'), path.join(outdir2, 'in.js'))\n\n    const result = require(path.join(outdir2, 'in.js'))\n    assert.strictEqual(result.default, fs.exists)\n  },\n\n  async resolveDirInFileModule({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const example = path.join(testDir, 'example.custom')\n    const resolveDir = path.join(testDir, 'target')\n    const loadme = path.join(resolveDir, 'loadme.js')\n    await mkdirAsync(resolveDir)\n    await writeFileAsync(input, `\n      import value from './example.custom'\n      export default value\n    `)\n    await writeFileAsync(example, `\n      export {default} from './loadme'\n    `)\n    await writeFileAsync(loadme, `\n      export default 123\n    `)\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onLoad({ filter: /\\.custom$/ }, async (args) => {\n            return { contents: await readFileAsync(args.path), resolveDir }\n          })\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n  },\n\n  async resolveWithSideEffectsFalse({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n\n    await writeFileAsync(input, `\n      import './re-export-unused'\n      import {a, b, c} from './re-export-used'\n      import './import-unused'\n      use([a, b, c])\n    `)\n    await writeFileAsync(path.join(testDir, 're-export-unused.js'), `\n      export {default as a} from 'plugin:unused-false'\n      export {default as b} from 'plugin:unused-true'\n      export {default as c} from 'plugin:unused-none'\n    `)\n    await writeFileAsync(path.join(testDir, 're-export-used.js'), `\n      export {default as a} from 'plugin:used-false'\n      export {default as b} from 'plugin:used-true'\n      export {default as c} from 'plugin:used-none'\n    `)\n    await writeFileAsync(path.join(testDir, 'import-unused.js'), `\n      import 'plugin:ignored-false'\n      import 'plugin:ignored-true'\n      import 'plugin:ignored-none'\n    `)\n\n    const result = await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      write: false,\n      format: 'cjs',\n      logLevel: 'error',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /^plugin:/ }, args => {\n            return {\n              path: args.path,\n              namespace: 'ns',\n              sideEffects:\n                args.path.endsWith('-true') ? true :\n                  args.path.endsWith('-false') ? false :\n                    undefined,\n            };\n          });\n          build.onLoad({ filter: /^plugin:/ }, args => {\n            return { contents: `export default use(${JSON.stringify(args.path)})` };\n          });\n        },\n      }],\n    })\n\n    // Validate that the unused \"sideEffects: false\" files were omitted\n    const used = [];\n    new Function('use', result.outputFiles[0].text)(x => used.push(x));\n    assert.deepStrictEqual(used, [\n      'plugin:unused-true',\n      'plugin:unused-none',\n\n      'plugin:used-false',\n      'plugin:used-true',\n      'plugin:used-none',\n\n      'plugin:ignored-true',\n      'plugin:ignored-none',\n\n      [3, 4, 5],\n    ])\n\n    // Check that the warning for \"sideEffect: false\" imports mentions the plugin\n    assert.strictEqual(result.warnings.length, 1)\n    assert.strictEqual(result.warnings[0].text,\n      'Ignoring this import because \"ns:plugin:ignored-false\" was marked as having no side effects by plugin \"name\"')\n  },\n\n  async noResolveDirInFileModule({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const example = path.join(testDir, 'example.custom')\n    const resolveDir = path.join(testDir, 'target')\n    const loadme = path.join(resolveDir, 'loadme.js')\n    await mkdirAsync(resolveDir)\n    await writeFileAsync(input, `\n      import value from './example.custom'\n      export default value\n    `)\n    await writeFileAsync(example, `\n      export {default} from './target/loadme'\n    `)\n    await writeFileAsync(loadme, `\n      export default 123\n    `)\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onLoad({ filter: /\\.custom$/ }, async (args) => {\n            return { contents: await readFileAsync(args.path) }\n          })\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n  },\n\n  async resolveDirInVirtualModule({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const resolveDir = path.join(testDir, 'target')\n    const loadme = path.join(resolveDir, 'loadme.js')\n    await mkdirAsync(resolveDir)\n    await writeFileAsync(input, `\n      import value from 'virtual'\n      export default value\n    `)\n    await writeFileAsync(loadme, `\n      export default 123\n    `)\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          let contents = `export {default} from './loadme'`\n          build.onResolve({ filter: /^virtual$/ }, () => ({ path: 'virtual', namespace: 'for-testing' }))\n          build.onLoad({ filter: /.*/, namespace: 'for-testing' }, () => ({ contents, resolveDir }))\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n  },\n\n  async noResolveDirInVirtualModule({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const output = path.join(testDir, 'out.js')\n    const resolveDir = path.join(testDir, 'target')\n    const loadme = path.join(resolveDir, 'loadme.js')\n    await mkdirAsync(resolveDir)\n    await writeFileAsync(input, `\n      import value from 'virtual'\n      export default value\n    `)\n    await writeFileAsync(loadme, `\n      export default 123\n    `)\n    let error\n    try {\n      await esbuild.build({\n        entryPoints: [input],\n        bundle: true,\n        outfile: output,\n        format: 'cjs',\n        logLevel: 'silent', plugins: [{\n          name: 'name',\n          setup(build) {\n            let contents = `export {default} from './loadme'`\n            build.onResolve({ filter: /^virtual$/ }, () => ({ path: 'virtual', namespace: 'for-testing' }))\n            build.onLoad({ filter: /.*/, namespace: 'for-testing' }, () => ({ contents }))\n          },\n        }],\n      })\n    } catch (e) {\n      error = e\n    }\n    assert.notStrictEqual(error, void 0)\n    if (!Array.isArray(error.errors)) throw error\n    assert.strictEqual(error.errors.length, 1)\n    assert.strictEqual(error.errors[0].text, `Could not resolve \"./loadme\"`)\n    assert.strictEqual(error.errors[0].notes[0].text,\n      `The plugin \"name\" didn't set a resolve directory for the file \"for-testing:virtual\", ` +\n      `so esbuild did not search for \"./loadme\" on the file system.`)\n  },\n\n  async webAssembly({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    const wasm = path.join(testDir, 'test.wasm')\n    const output = path.join(testDir, 'out.js')\n    await writeFileAsync(input, `\n      import load from './test.wasm'\n      export default async (x, y) => (await load()).add(x, y)\n    `)\n    await writeFileAsync(wasm, Buffer.of(\n      // #[wasm_bindgen]\n      // pub fn add(x: i32, y: i32) -> i32 { x + y }\n      0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 0x60,\n      0x02, 0x7F, 0x7F, 0x01, 0x7F, 0x03, 0x02, 0x01, 0x00, 0x05, 0x03, 0x01,\n      0x00, 0x11, 0x07, 0x10, 0x02, 0x06, 0x6D, 0x65, 0x6D, 0x6F, 0x72, 0x79,\n      0x02, 0x00, 0x03, 0x61, 0x64, 0x64, 0x00, 0x00, 0x0A, 0x09, 0x01, 0x07,\n      0x00, 0x20, 0x00, 0x20, 0x01, 0x6A, 0x0B,\n    ))\n    await esbuild.build({\n      entryPoints: [input],\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      target: process.version.replace('v', 'node'),\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /\\.wasm$/ }, args => ({\n            path: path.isAbsolute(args.path) ? args.path : path.join(args.resolveDir, args.path),\n            namespace: args.namespace === 'wasm-stub' ? 'wasm-binary' : 'wasm-stub',\n          }))\n          build.onLoad({ filter: /.*/, namespace: 'wasm-binary' }, async (args) =>\n            ({ contents: await readFileAsync(args.path), loader: 'binary' }))\n          build.onLoad({ filter: /.*/, namespace: 'wasm-stub' }, async (args) => ({\n            contents: `import wasm from ${JSON.stringify(args.path)}\n              export default async (imports) =>\n                (await WebAssembly.instantiate(wasm, imports)).instance.exports` }))\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(await result.default(103, 20), 123)\n  },\n\n  async virtualEntryPoints({ esbuild, testDir }) {\n    const result = await esbuild.build({\n      entryPoints: ['1', '2', 'a<>:\"|?b', 'a/b/c.d.e'],\n      bundle: true,\n      write: false,\n      outdir: testDir,\n      format: 'esm',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => {\n            return { path: `input ${args.path}`, namespace: 'virtual-ns' }\n          })\n          build.onLoad({ filter: /.*/, namespace: 'virtual-ns' }, args => {\n            return { contents: `console.log(${JSON.stringify(args.path)})` }\n          })\n        },\n      }],\n    })\n    assert.strictEqual(result.outputFiles.length, 4)\n    assert.strictEqual(result.outputFiles[0].path, path.join(testDir, '1.js'))\n    assert.strictEqual(result.outputFiles[1].path, path.join(testDir, '2.js'))\n    assert.strictEqual(result.outputFiles[2].path, path.join(testDir, 'a_b.js'))\n    assert.strictEqual(result.outputFiles[3].path, path.join(testDir, 'a/b/c.d.js'))\n    assert.strictEqual(result.outputFiles[0].text, `// virtual-ns:input 1\\nconsole.log(\"input 1\");\\n`)\n    assert.strictEqual(result.outputFiles[1].text, `// virtual-ns:input 2\\nconsole.log(\"input 2\");\\n`)\n    assert.strictEqual(result.outputFiles[2].text, `// virtual-ns:input a<>:\"|?b\\nconsole.log('input a<>:\"|?b');\\n`)\n    assert.strictEqual(result.outputFiles[3].text, `// virtual-ns:input a/b/c.d.e\\nconsole.log(\"input a/b/c.d.e\");\\n`)\n  },\n\n  async entryPointFileNamespace({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    let worked = false\n    await writeFileAsync(input, 'stuff')\n    await esbuild.build({\n      entryPoints: [input],\n      write: false,\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /.*/, namespace: 'file' }, () => {\n            worked = true\n          })\n        },\n      }],\n    })\n    assert(worked)\n  },\n\n  async stdinImporter({ esbuild, testDir }) {\n    const output = path.join(testDir, 'out.js')\n    await esbuild.build({\n      stdin: {\n        contents: `import x from \"plugin\"; export default x`,\n        sourcefile: 'stdin-sourcefile',\n      },\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /^plugin$/ }, args => {\n            assert.strictEqual(args.namespace, '')\n            assert.strictEqual(args.importer, 'stdin-sourcefile')\n            assert.strictEqual(args.resolveDir, '')\n            assert.strictEqual(args.path, 'plugin')\n            return { path: args.path, namespace: 'worked' }\n          })\n          build.onLoad({ filter: /.*/, namespace: 'worked' }, () => {\n            return { contents: `export default 123` }\n          })\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n  },\n\n  async stdinImporterResolveDir({ esbuild, testDir }) {\n    const output = path.join(testDir, 'out.js')\n    await esbuild.build({\n      stdin: {\n        contents: `import x from \"plugin\"; export default x`,\n        sourcefile: 'stdin-sourcefile',\n        resolveDir: testDir,\n      },\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /^plugin$/ }, args => {\n            assert.strictEqual(args.namespace, 'file')\n            assert.strictEqual(args.importer, path.join(testDir, 'stdin-sourcefile'))\n            assert.strictEqual(args.resolveDir, testDir)\n            assert.strictEqual(args.path, 'plugin')\n            return { path: args.path, namespace: 'worked' }\n          })\n          build.onLoad({ filter: /.*/, namespace: 'worked' }, () => {\n            return { contents: `export default 123` }\n          })\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n  },\n\n  async stdinAbsoluteImporterResolveDir({ esbuild, testDir }) {\n    const output = path.join(testDir, 'out.js')\n    await esbuild.build({\n      stdin: {\n        contents: `import x from \"plugin\"; export default x`,\n        sourcefile: path.join(testDir, 'stdin-sourcefile'),\n        resolveDir: testDir,\n      },\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /^plugin$/ }, args => {\n            assert.strictEqual(args.namespace, 'file')\n            assert.strictEqual(args.importer, path.join(testDir, 'stdin-sourcefile'))\n            assert.strictEqual(args.resolveDir, testDir)\n            assert.strictEqual(args.path, 'plugin')\n            return { path: args.path, namespace: 'worked' }\n          })\n          build.onLoad({ filter: /.*/, namespace: 'worked' }, () => {\n            return { contents: `export default 123` }\n          })\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n  },\n\n  async stdinRelative({ esbuild, testDir }) {\n    const output = path.join(testDir, 'out.js')\n    await esbuild.build({\n      stdin: {\n        contents: `import x from \"./stdinRelative.js\"; export default x`,\n      },\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => {\n            assert.strictEqual(args.namespace, '')\n            assert.strictEqual(args.importer, '<stdin>')\n            assert.strictEqual(args.resolveDir, '')\n            assert.strictEqual(args.path, './stdinRelative.js')\n            return { path: args.path, namespace: 'worked' }\n          })\n          build.onLoad({ filter: /.*/, namespace: 'worked' }, () => {\n            return { contents: `export default 123` }\n          })\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n  },\n\n  async stdinRelativeResolveDir({ esbuild, testDir }) {\n    const output = path.join(testDir, 'out', 'out.js')\n    await esbuild.build({\n      stdin: {\n        contents: `import x from \"./stdinRelative.js\"; export default x`,\n        resolveDir: testDir,\n      },\n      bundle: true,\n      outfile: output,\n      format: 'cjs',\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => {\n            assert.strictEqual(args.namespace, '')\n            assert.strictEqual(args.importer, '<stdin>')\n            assert.strictEqual(args.resolveDir, testDir)\n            assert.strictEqual(args.path, './stdinRelative.js')\n            return { path: args.path, namespace: 'worked' }\n          })\n          build.onLoad({ filter: /.*/, namespace: 'worked' }, () => {\n            return { contents: `export default 123` }\n          })\n        },\n      }],\n    })\n    const result = require(output)\n    assert.strictEqual(result.default, 123)\n  },\n\n  async externalRequire({ esbuild, testDir }) {\n    const externalPlugin = external => ({\n      name: 'external',\n      setup(build) {\n        let escape = text => `^${text.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&')}$`\n        let filter = new RegExp(external.map(escape).join('|'))\n        build.onResolve({ filter: /.*/, namespace: 'external' }, args => ({\n          path: args.path, external: true\n        }))\n        build.onResolve({ filter }, args => ({\n          path: args.path, namespace: 'external'\n        }))\n        build.onLoad({ filter: /.*/, namespace: 'external' }, args => ({\n          contents: `import * as all from ${JSON.stringify(args.path)}; module.exports = all`\n        }))\n      },\n    })\n    const outfile = path.join(testDir, 'out', 'output.mjs')\n    await esbuild.build({\n      stdin: {\n        contents: `const fs = require('fs')\n          const url = require('url')\n          const path = require('path')\n          export default fs.readdirSync(path.dirname(url.fileURLToPath(import.meta.url)))\n        `,\n      },\n      bundle: true,\n      outfile,\n      format: 'esm',\n      plugins: [\n        externalPlugin(['fs', 'url', 'path'])\n      ],\n    })\n    const result = await import(url.pathToFileURL(outfile))\n    assert.deepStrictEqual(result.default, [path.basename(outfile)])\n  },\n\n  async newlineInPath({ esbuild }) {\n    // Using a path with a newline shouldn't cause a syntax error when the path is printed in a comment\n    for (let nl of ['\\r', '\\n', '\\r\\n', '\\u2028', '\\u2029']) {\n      let problem = `a b${nl}c d`\n      const plugin = {\n        name: 'test',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => ({\n            path: args.path, namespace: 'test',\n          }))\n          build.onLoad({ filter: /.*/, namespace: 'test' }, args => ({\n            contents: `return ${JSON.stringify(args.path)}`\n          }))\n        },\n      }\n      let result = await esbuild.build({\n        entryPoints: [problem],\n        bundle: true,\n        write: false,\n        format: 'cjs',\n        plugins: [plugin],\n      })\n      let value = new Function(result.outputFiles[0].text)()\n      assert.deepStrictEqual(value, problem)\n    }\n  },\n\n  async newlineInNamespace({ esbuild }) {\n    // Using a namespace with a newline shouldn't cause a syntax error when the namespace is printed in a comment\n    for (let nl of ['\\r', '\\n', '\\r\\n', '\\u2028', '\\u2029']) {\n      let problem = `a b${nl}c d`\n      const plugin = {\n        name: 'test',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => ({\n            path: args.path, namespace: problem,\n          }))\n          build.onLoad({ filter: /.*/, namespace: problem }, args => ({\n            contents: `return ${JSON.stringify(args.namespace)}`\n          }))\n        },\n      }\n      let result = await esbuild.build({\n        entryPoints: ['entry'],\n        bundle: true,\n        write: false,\n        format: 'cjs',\n        plugins: [plugin],\n      })\n      let value = new Function(result.outputFiles[0].text)()\n      assert.deepStrictEqual(value, problem)\n    }\n  },\n\n  async transformUndefinedDetailForError({ esbuild }) {\n    try {\n      await esbuild.transform('x y')\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert.deepStrictEqual(e.warnings, [])\n      assert.deepStrictEqual(e.errors, [{\n        id: '',\n        pluginName: '',\n        text: 'Expected \";\" but found \"y\"',\n        location: {\n          file: '<stdin>',\n          namespace: '',\n          line: 1,\n          column: 2,\n          length: 1,\n          lineText: 'x y',\n          suggestion: ';',\n        },\n        notes: [],\n        detail: void 0,\n      }])\n    }\n  },\n\n  async transformUndefinedDetailForWarning({ esbuild }) {\n    const result = await esbuild.transform('typeof x == \"null\"')\n    assert.deepStrictEqual(result.warnings, [{\n      id: 'impossible-typeof',\n      pluginName: '',\n      text: 'The \"typeof\" operator will never evaluate to \"null\"',\n      location: {\n        file: '<stdin>',\n        namespace: '',\n        line: 1,\n        column: 12,\n        length: 6,\n        lineText: 'typeof x == \"null\"',\n        suggestion: '',\n      },\n      notes: [\n        {\n          location: null,\n          text: 'The expression \"typeof x\" actually evaluates to \"object\" in JavaScript, not \"null\". You need to use \"x === null\" to test for null.'\n        }\n      ],\n      detail: void 0,\n    }])\n  },\n\n  async buildUndefinedDetailForError({ esbuild }) {\n    try {\n      await esbuild.build({\n        stdin: { contents: 'x y' },\n        write: false,\n        logLevel: 'silent',\n      })\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert.deepStrictEqual(e.warnings, [])\n      assert.deepStrictEqual(e.errors, [{\n        id: '',\n        pluginName: '',\n        text: 'Expected \";\" but found \"y\"',\n        location: {\n          file: '<stdin>',\n          namespace: '',\n          line: 1,\n          column: 2,\n          length: 1,\n          lineText: 'x y',\n          suggestion: ';',\n        },\n        notes: [],\n        detail: void 0,\n      }])\n    }\n  },\n\n  async buildUndefinedDetailForWarning({ esbuild }) {\n    const result = await esbuild.build({\n      stdin: { contents: 'typeof x == \"null\"' },\n      write: false,\n      logLevel: 'silent',\n    })\n    assert.deepStrictEqual(result.warnings, [{\n      id: 'impossible-typeof',\n      pluginName: '',\n      text: 'The \"typeof\" operator will never evaluate to \"null\"',\n      location: {\n        file: '<stdin>',\n        namespace: '',\n        line: 1,\n        column: 12,\n        length: 6,\n        lineText: 'typeof x == \"null\"',\n        suggestion: '',\n      },\n      notes: [\n        {\n          location: null,\n          text: 'The expression \"typeof x\" actually evaluates to \"object\" in JavaScript, not \"null\". You need to use \"x === null\" to test for null.'\n        }\n      ],\n      detail: void 0,\n    }])\n  },\n\n  async specificDetailForOnResolvePluginThrowError({ esbuild }) {\n    const theError = new Error('theError');\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        write: false,\n        logLevel: 'silent',\n        plugins: [{\n          name: 'the-plugin',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, () => {\n              throw theError;\n            })\n          },\n        }],\n      })\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert.strictEqual(e.warnings.length, 0)\n      assert.strictEqual(e.errors.length, 1)\n      assert.strictEqual(e.errors[0].pluginName, 'the-plugin')\n      assert.strictEqual(e.errors[0].text, 'theError')\n      assert.strictEqual(e.errors[0].detail, theError)\n    }\n  },\n\n  async specificDetailForOnLoadPluginThrowError({ esbuild }) {\n    const theError = new Error('theError');\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        write: false,\n        logLevel: 'silent',\n        plugins: [{\n          name: 'the-plugin',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, () => ({ path: 'abc', namespace: 'xyz' }))\n            build.onLoad({ filter: /.*/ }, () => {\n              throw theError;\n            })\n          },\n        }],\n      })\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert.strictEqual(e.warnings.length, 0)\n      assert.strictEqual(e.errors.length, 1)\n      assert.strictEqual(e.errors[0].pluginName, 'the-plugin')\n      assert.strictEqual(e.errors[0].text, 'theError')\n      assert.strictEqual(e.errors[0].detail, theError)\n    }\n  },\n\n  async specificDetailForOnResolvePluginReturnError({ esbuild }) {\n    const theError = new Error('theError');\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        write: false,\n        logLevel: 'silent',\n        plugins: [{\n          name: 'the-plugin',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, () => {\n              return {\n                errors: [{\n                  text: 'some error',\n                  location: {\n                    file: 'file1',\n                    namespace: 'ns1',\n                    line: 1,\n                    column: 2,\n                    length: 3,\n                    lineText: 'some text',\n                    suggestion: '',\n                  },\n                  notes: [{\n                    text: 'some note',\n                    location: {\n                      file: 'file2',\n                      namespace: 'ns2',\n                      line: 4,\n                      column: 5,\n                      length: 6,\n                      lineText: 'more text',\n                      suggestion: '',\n                    },\n                  }],\n                  detail: theError,\n                }],\n              };\n            })\n          },\n        }],\n      })\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert.strictEqual(e.warnings.length, 0)\n      assert.strictEqual(e.errors.length, 1)\n      assert.deepStrictEqual(e.errors[0], {\n        id: '',\n        pluginName: 'the-plugin',\n        text: 'some error',\n        location: {\n          file: 'ns1:file1',\n          namespace: 'ns1',\n          line: 1,\n          column: 2,\n          length: 3,\n          lineText: 'some text',\n          suggestion: '',\n        },\n        notes: [{\n          text: 'some note',\n          location: {\n            file: 'ns2:file2',\n            namespace: 'ns2',\n            line: 4,\n            column: 5,\n            length: 6,\n            lineText: 'more text',\n            suggestion: '',\n          },\n        }],\n        detail: theError,\n      })\n    }\n  },\n\n  async specificDetailForOnResolvePluginReturnWarning({ esbuild }) {\n    const theError = new Error('theError');\n    const result = await esbuild.build({\n      entryPoints: ['entry'],\n      write: false,\n      logLevel: 'silent',\n      plugins: [{\n        name: 'the-plugin',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, () => {\n            return {\n              path: 'abc', namespace: 'xyz', warnings: [{\n                pluginName: 'other-plugin',\n                text: 'some warning',\n                location: {\n                  file: 'file1',\n                  namespace: 'ns1',\n                  line: 1,\n                  column: 2,\n                  length: 3,\n                  lineText: 'some text',\n                  suggestion: '',\n                },\n                notes: [{\n                  text: 'some note',\n                  location: {\n                    file: 'file2',\n                    namespace: 'ns2',\n                    line: 4,\n                    column: 5,\n                    length: 6,\n                    lineText: 'more text',\n                    suggestion: '',\n                  },\n                }],\n                detail: theError,\n              }]\n            };\n          })\n          build.onLoad({ filter: /.*/ }, () => ({ contents: '' }))\n        },\n      }],\n    })\n    assert.strictEqual(result.warnings.length, 1)\n    assert.deepStrictEqual(result.warnings[0], {\n      id: '',\n      pluginName: 'other-plugin',\n      text: 'some warning',\n      location: {\n        file: 'ns1:file1',\n        namespace: 'ns1',\n        line: 1,\n        column: 2,\n        length: 3,\n        lineText: 'some text',\n        suggestion: '',\n      },\n      notes: [{\n        text: 'some note',\n        location: {\n          file: 'ns2:file2',\n          namespace: 'ns2',\n          line: 4,\n          column: 5,\n          length: 6,\n          lineText: 'more text',\n          suggestion: '',\n        },\n      }],\n      detail: theError,\n    })\n  },\n\n  async specificDetailForOnLoadPluginReturnError({ esbuild }) {\n    const theError = new Error('theError');\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        write: false,\n        logLevel: 'silent',\n        plugins: [{\n          name: 'the-plugin',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, () => ({ path: 'abc', namespace: 'xyz' }))\n            build.onLoad({ filter: /.*/ }, () => {\n              return {\n                errors: [{\n                  text: 'some error',\n                  location: {\n                    file: 'file1',\n                    namespace: 'ns1',\n                    line: 1,\n                    column: 2,\n                    length: 3,\n                    lineText: 'some text',\n                    suggestion: '',\n                  },\n                  notes: [{\n                    text: 'some note',\n                    location: {\n                      file: 'file2',\n                      namespace: 'ns2',\n                      line: 4,\n                      column: 5,\n                      length: 6,\n                      lineText: 'more text',\n                      suggestion: '',\n                    },\n                  }],\n                  detail: theError,\n                }],\n              };\n            })\n          },\n        }],\n      })\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert.strictEqual(e.warnings.length, 0)\n      assert.strictEqual(e.errors.length, 1)\n      assert.deepStrictEqual(e.errors[0], {\n        id: '',\n        pluginName: 'the-plugin',\n        text: 'some error',\n        location: {\n          file: 'ns1:file1',\n          namespace: 'ns1',\n          line: 1,\n          column: 2,\n          length: 3,\n          lineText: 'some text',\n          suggestion: '',\n        },\n        notes: [{\n          text: 'some note',\n          location: {\n            file: 'ns2:file2',\n            namespace: 'ns2',\n            line: 4,\n            column: 5,\n            length: 6,\n            lineText: 'more text',\n            suggestion: '',\n          },\n        }],\n        detail: theError,\n      })\n    }\n  },\n\n  async specificDetailForOnLoadPluginReturnWarning({ esbuild }) {\n    const theError = new Error('theError');\n    const result = await esbuild.build({\n      entryPoints: ['entry'],\n      write: false,\n      logLevel: 'silent',\n      plugins: [{\n        name: 'the-plugin',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, () => ({ path: 'abc', namespace: 'xyz' }))\n          build.onLoad({ filter: /.*/ }, () => {\n            return {\n              contents: '', warnings: [{\n                text: 'some warning',\n                location: {\n                  file: 'file1',\n                  namespace: 'ns1',\n                  line: 1,\n                  column: 2,\n                  length: 3,\n                  lineText: 'some text',\n                  suggestion: '',\n                },\n                notes: [{\n                  text: 'some note',\n                  location: {\n                    file: 'file2',\n                    namespace: 'ns2',\n                    line: 4,\n                    column: 5,\n                    length: 6,\n                    lineText: 'more text',\n                    suggestion: '',\n                  },\n                }],\n                detail: theError,\n              }],\n            };\n          })\n        },\n      }],\n    })\n    assert.strictEqual(result.warnings.length, 1)\n    assert.deepStrictEqual(result.warnings[0], {\n      id: '',\n      pluginName: 'the-plugin',\n      text: 'some warning',\n      location: {\n        file: 'ns1:file1',\n        namespace: 'ns1',\n        line: 1,\n        column: 2,\n        length: 3,\n        lineText: 'some text',\n        suggestion: '',\n      },\n      notes: [{\n        text: 'some note',\n        location: {\n          file: 'ns2:file2',\n          namespace: 'ns2',\n          line: 4,\n          column: 5,\n          length: 6,\n          lineText: 'more text',\n          suggestion: '',\n        },\n      }],\n      detail: theError,\n    })\n  },\n\n  async pluginDataResolveToLoad({ esbuild }) {\n    const theObject = {}\n    const result = await esbuild.build({\n      entryPoints: ['entry'],\n      write: false,\n      plugins: [{\n        name: 'plugin',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, () => ({\n            path: 'abc',\n            namespace: 'xyz',\n            pluginData: theObject,\n          }))\n          build.onLoad({ filter: /.*/ }, args => {\n            assert.strictEqual(args.pluginData, theObject)\n            return { contents: 'foo()' };\n          })\n        },\n      }],\n    })\n    assert.strictEqual(result.outputFiles[0].text, 'foo();\\n')\n  },\n\n  async pluginDataResolveToLoadNested({ esbuild }) {\n    const theObject = {}\n    const result = await esbuild.build({\n      entryPoints: ['entry'],\n      write: false,\n      bundle: true,\n      format: 'esm',\n      plugins: [{\n        name: 'plugin',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => {\n            if (args.path === 'entry') return { path: 'entry', namespace: 'xyz' }\n            return {\n              path: 'nested',\n              namespace: 'xyz',\n              pluginData: theObject,\n            }\n          })\n          build.onLoad({ filter: /.*/ }, args => {\n            if (args.path === 'entry') return { contents: 'import \"nested\"' };\n            assert.strictEqual(args.pluginData, theObject)\n            return { contents: 'foo()' };\n          })\n        },\n      }],\n    })\n    assert.strictEqual(result.outputFiles[0].text, '// xyz:nested\\nfoo();\\n')\n  },\n\n  async pluginDataLoadToResolve({ esbuild }) {\n    const theObject = {}\n    const result = await esbuild.build({\n      entryPoints: ['entry'],\n      write: false,\n      plugins: [{\n        name: 'plugin',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => {\n            if (args === 'import') {\n              assert.strictEqual(args.pluginData, theObject)\n              return { external: true }\n            }\n            return { path: 'abc', namespace: 'xyz' }\n          })\n          build.onLoad({ filter: /.*/ }, () => ({\n            contents: 'import(\"import\")',\n            pluginData: theObject,\n          }))\n        },\n      }],\n    })\n    assert.strictEqual(result.outputFiles[0].text, 'import(\"import\");\\n')\n  },\n\n  async resolveKindEntryPoint({ esbuild }) {\n    let resolveKind = '<missing>'\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        bundle: true,\n        write: false,\n        logLevel: 'silent',\n        plugins: [{\n          name: 'plugin',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, args => {\n              resolveKind = args.kind\n            })\n          },\n        }],\n      })\n    } catch (e) {\n    }\n    assert.strictEqual(resolveKind, 'entry-point')\n  },\n\n  async resolveKindImportStmt({ esbuild }) {\n    let resolveKind = '<missing>'\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        bundle: true,\n        write: false,\n        logLevel: 'silent',\n        plugins: [{\n          name: 'plugin',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, args => {\n              if (args.importer === '') return { path: args.path, namespace: 'ns' }\n              else resolveKind = args.kind\n            })\n            build.onLoad({ filter: /.*/, namespace: 'ns' }, () => {\n              return { contents: `import 'test'` }\n            })\n          },\n        }],\n      })\n    } catch (e) {\n    }\n    assert.strictEqual(resolveKind, 'import-statement')\n  },\n\n  async resolveKindRequireCall({ esbuild }) {\n    let resolveKind = '<missing>'\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        bundle: true,\n        write: false,\n        logLevel: 'silent',\n        plugins: [{\n          name: 'plugin',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, args => {\n              if (args.importer === '') return { path: args.path, namespace: 'ns' }\n              else resolveKind = args.kind\n            })\n            build.onLoad({ filter: /.*/, namespace: 'ns' }, () => {\n              return { contents: `require('test')` }\n            })\n          },\n        }],\n      })\n    } catch (e) {\n    }\n    assert.strictEqual(resolveKind, 'require-call')\n  },\n\n  async resolveKindDynamicImport({ esbuild }) {\n    let resolveKind = '<missing>'\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        bundle: true,\n        write: false,\n        logLevel: 'silent',\n        plugins: [{\n          name: 'plugin',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, args => {\n              if (args.importer === '') return { path: args.path, namespace: 'ns' }\n              else resolveKind = args.kind\n            })\n            build.onLoad({ filter: /.*/, namespace: 'ns' }, () => {\n              return { contents: `import('test')` }\n            })\n          },\n        }],\n      })\n    } catch (e) {\n    }\n    assert.strictEqual(resolveKind, 'dynamic-import')\n  },\n\n  async resolveKindRequireResolve({ esbuild }) {\n    let resolveKind = '<missing>'\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        bundle: true,\n        write: false,\n        logLevel: 'silent',\n        platform: 'node',\n        plugins: [{\n          name: 'plugin',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, args => {\n              if (args.importer === '') return { path: args.path, namespace: 'ns' }\n              else resolveKind = args.kind\n            })\n            build.onLoad({ filter: /.*/, namespace: 'ns' }, () => {\n              return { contents: `require.resolve('test')` }\n            })\n          },\n        }],\n      })\n    } catch (e) {\n    }\n    assert.strictEqual(resolveKind, 'require-resolve')\n  },\n\n  async resolveKindAtImport({ esbuild }) {\n    let resolveKind = '<missing>'\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        bundle: true,\n        write: false,\n        logLevel: 'silent',\n        plugins: [{\n          name: 'plugin',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, args => {\n              if (args.importer === '') return { path: args.path, namespace: 'ns' }\n              else resolveKind = args.kind\n            })\n            build.onLoad({ filter: /.*/, namespace: 'ns' }, () => {\n              return { contents: `@import \"test\";`, loader: 'css' }\n            })\n          },\n        }],\n      })\n    } catch (e) {\n    }\n    assert.strictEqual(resolveKind, 'import-rule')\n  },\n\n  async resolveKindComposesFrom({ esbuild }) {\n    let resolveKind = '<missing>'\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        bundle: true,\n        write: false,\n        logLevel: 'silent',\n        plugins: [{\n          name: 'plugin',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, args => {\n              if (args.importer === '') return { path: args.path, namespace: 'ns' }\n              else resolveKind = args.kind\n            })\n            build.onLoad({ filter: /.*/, namespace: 'ns' }, () => {\n              return { contents: `.foo { composes: bar from 'entry' }`, loader: 'local-css' }\n            })\n          },\n        }],\n      })\n    } catch (e) {\n    }\n    assert.strictEqual(resolveKind, 'composes-from')\n  },\n\n  async resolveKindURLToken({ esbuild }) {\n    let resolveKind = '<missing>'\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        bundle: true,\n        write: false,\n        logLevel: 'silent',\n        plugins: [{\n          name: 'plugin',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, args => {\n              if (args.importer === '') return { path: args.path, namespace: 'ns' }\n              else resolveKind = args.kind\n            })\n            build.onLoad({ filter: /.*/, namespace: 'ns' }, () => {\n              return { contents: `div { background: url('test') }`, loader: 'css' }\n            })\n          },\n        }],\n      })\n    } catch (e) {\n    }\n    assert.strictEqual(resolveKind, 'url-token')\n  },\n\n  async warnIfUnusedNoWarning({ esbuild }) {\n    const build = await esbuild.build({\n      entryPoints: ['entry'],\n      bundle: true,\n      write: false,\n      logLevel: 'silent',\n      plugins: [{\n        name: 'plugin',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => {\n            if (args.importer === '') return { path: args.path, namespace: 'entry' }\n            else return { path: args.path, namespace: 'bare-import' }\n          })\n          build.onLoad({ filter: /.*/, namespace: 'entry' }, () => {\n            return {\n              contents: `\n                import \"base64\"\n                import \"binary\"\n                import \"dataurl\"\n                import \"json\"\n                import \"text\"\n              `,\n            }\n          })\n          build.onLoad({ filter: /.*/, namespace: 'bare-import' }, args => {\n            return { contents: `[1, 2, 3]`, loader: args.path }\n          })\n        },\n      }],\n    })\n    assert.strictEqual(build.warnings.length, 0)\n  },\n\n  async onResolvePreserveOriginalEntryPointNameIssue945({ esbuild, testDir }) {\n    const build = await esbuild.build({\n      entryPoints: ['first'],\n      write: false,\n      logLevel: 'silent',\n      outdir: testDir,\n      plugins: [{\n        name: 'plugin',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, () => {\n            return { path: 'second', namespace: 'what' }\n          })\n          build.onLoad({ filter: /.*/ }, () => {\n            return { contents: `` }\n          })\n        },\n      }],\n    })\n    assert.strictEqual(build.outputFiles[0].path, path.join(testDir, 'first.js'))\n  },\n\n  async dynamicImportDuplicateChunkIssue1099({ esbuild, testDir }) {\n    const outdir = path.join(testDir, 'out')\n    await mkdirAsync(path.join(testDir, 'hi'), { recursive: true })\n    await writeFileAsync(path.join(testDir, 'index.js'), `import x from 'manifest'; console.log(x.name(), x.hi())`)\n    await writeFileAsync(path.join(testDir, 'name.js'), `import x from 'manifest'; console.log(x.index(), x.hi())`)\n    await writeFileAsync(path.join(testDir, 'hi', 'name.js'), `import x from 'manifest'; console.log(x.index(), x.name())`)\n    await esbuild.build({\n      entryPoints: [path.join(testDir, 'index.js')],\n      outdir,\n      bundle: true,\n      splitting: true,\n      format: 'esm',\n      plugins: [{\n        name: 'plugin',\n        setup(build) {\n          build.onResolve({ filter: /^manifest$/ }, () => {\n            return { path: 'manifest', namespace: 'Manifest' }\n          })\n          build.onLoad({ namespace: 'Manifest', filter: /.*/ }, () => {\n            return {\n              resolveDir: testDir,\n              contents: `\n                export const index = () => import('./index')\n                export const name = () => import('./name')\n                export const hi = () => import('./hi/name')\n                export default {index, name, hi}\n              `,\n            }\n          })\n        },\n      }],\n    })\n  },\n\n  async fileLoaderCustomNamespaceIssue1404({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.data')\n    const outdir = path.join(testDir, 'out')\n    await writeFileAsync(input, `some data`)\n    await esbuild.build({\n      entryPoints: [path.basename(input)],\n      absWorkingDir: testDir,\n      logLevel: 'silent',\n      outdir,\n      assetNames: '[name]',\n      plugins: [{\n        name: 'plugin',\n        setup(build) {\n          build.onResolve({ filter: /\\.data$/ }, args => {\n            return {\n              path: args.path,\n              namespace: 'ns',\n            }\n          })\n          build.onLoad({ filter: /.*/, namespace: 'ns' }, async (args) => {\n            const data = await readFileAsync(path.join(testDir, args.path), 'utf8')\n            return {\n              contents: data.split('').reverse().join(''),\n              loader: 'file',\n            }\n          })\n        },\n      }],\n    })\n    assert.strictEqual(await readFileAsync(input, 'utf8'), `some data`)\n    assert.strictEqual(require(path.join(outdir, 'in.js')), `./in.data`)\n  },\n\n  async esbuildProperty({ esbuild }) {\n    let esbuildFromBuild\n    await esbuild.build({\n      entryPoints: ['xyz'],\n      write: false,\n      plugins: [{\n        name: 'plugin',\n        setup(build) {\n          esbuildFromBuild = build.esbuild\n          build.onResolve({ filter: /.*/ }, () => ({ path: 'foo', namespace: 'bar' }))\n          build.onLoad({ filter: /.*/ }, () => ({ contents: '' }))\n        },\n      }],\n    })\n    assert.deepStrictEqual({ ...esbuildFromBuild }, { ...esbuild })\n  },\n\n  async onResolveSuffixWithoutPath({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, `works()`)\n    const result = await esbuild.build({\n      entryPoints: [input],\n      logLevel: 'silent',\n      write: false,\n      plugins: [{\n        name: 'the-plugin',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, () => ({ suffix: '?just suffix without path' }))\n        },\n      }],\n    })\n    assert.strictEqual(result.warnings.length, 1)\n    assert.strictEqual(result.warnings[0].text, `Returning \"suffix\" doesn't do anything when \"path\" is empty`)\n    assert.strictEqual(result.warnings[0].pluginName, 'the-plugin')\n  },\n\n  async onResolveInvalidPathSuffix({ esbuild }) {\n    try {\n      await esbuild.build({\n        entryPoints: ['foo'],\n        logLevel: 'silent',\n        plugins: [{\n          name: 'plugin',\n          setup(build) {\n            build.onResolve({ filter: /.*/ }, () => ({ path: 'bar', suffix: '%what' }))\n          },\n        }],\n      })\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert.strictEqual(e.message, `Build failed with 1 error:\nerror: Invalid path suffix \"%what\" returned from plugin (must start with \"?\" or \"#\")`)\n    }\n  },\n\n  async onResolveWithInternalOnLoadAndQuerySuffix({ testDir, esbuild }) {\n    const entry = path.join(testDir, 'entry.js')\n    await writeFileAsync(entry, `console.log('entry')`)\n    const onResolveSet = new Set()\n    const onLoadSet = new Set()\n    await esbuild.build({\n      stdin: {\n        resolveDir: testDir,\n        contents: `\n          import \"foo%a\"\n          import \"foo%b\"\n        `,\n      },\n      bundle: true,\n      write: false,\n      plugins: [{\n        name: 'plugin',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => {\n            onResolveSet.add({ path: args.path, suffix: args.suffix })\n            if (args.path.startsWith('foo%')) {\n              return {\n                path: entry,\n                suffix: '?' + args.path.slice(args.path.indexOf('%') + 1),\n              }\n            }\n          })\n          build.onLoad({ filter: /.*/ }, args => {\n            onLoadSet.add({ path: args.path, suffix: args.suffix })\n          })\n        },\n      }],\n    })\n    const order = (a, b) => {\n      a = JSON.stringify(a)\n      b = JSON.stringify(b)\n      return (a > b) - (a < b)\n    }\n    const observed = JSON.stringify({\n      onResolve: [...onResolveSet].sort(order),\n      onLoad: [...onLoadSet].sort(order),\n    }, null, 2)\n    const expected = JSON.stringify({\n      onResolve: [\n        { path: 'foo%a' },\n        { path: 'foo%b' },\n      ],\n      onLoad: [\n        { path: path.join(testDir, 'entry.js'), suffix: '?a' },\n        { path: path.join(testDir, 'entry.js'), suffix: '?b' },\n      ],\n    }, null, 2)\n    if (observed !== expected) throw new Error(`Observed ${observed}, expected ${expected}`)\n  },\n\n  async onLoadWithInternalOnResolveAndQuerySuffix({ testDir, esbuild }) {\n    const entry = path.join(testDir, 'entry.js')\n    await writeFileAsync(entry, `console.log('entry')`)\n    const onResolveSet = new Set()\n    const onLoadSet = new Set()\n    await esbuild.build({\n      stdin: {\n        resolveDir: testDir,\n        contents: `\n          import \"./entry?a\"\n          import \"./entry?b\"\n        `,\n      },\n      bundle: true,\n      write: false,\n      plugins: [{\n        name: 'plugin',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => {\n            onResolveSet.add({ path: args.path, suffix: args.suffix })\n          })\n          build.onLoad({ filter: /.*/ }, args => {\n            onLoadSet.add({ path: args.path, suffix: args.suffix })\n          })\n        },\n      }],\n    })\n    const order = (a, b) => {\n      a = JSON.stringify(a)\n      b = JSON.stringify(b)\n      return (a > b) - (a < b)\n    }\n    const observed = JSON.stringify({\n      onResolve: [...onResolveSet].sort(order),\n      onLoad: [...onLoadSet].sort(order),\n    }, null, 2)\n    const expected = JSON.stringify({\n      onResolve: [\n        { path: './entry?a' },\n        { path: './entry?b' },\n      ],\n      onLoad: [\n        { path: path.join(testDir, 'entry.js'), suffix: '?a' },\n        { path: path.join(testDir, 'entry.js'), suffix: '?b' },\n      ],\n    }, null, 2)\n    if (observed !== expected) throw new Error(`Observed ${observed}, expected ${expected}`)\n  },\n\n  async externalSideEffectsFalse({ esbuild }) {\n    const build = await esbuild.build({\n      entryPoints: ['entry'],\n      bundle: true,\n      write: false,\n      platform: 'node',\n      format: 'esm',\n      plugins: [{\n        name: 'plugin',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => {\n            if (args.importer === '') return { path: args.path, namespace: 'entry' }\n            else return { path: args.path, external: true, sideEffects: args.path !== 'noSideEffects' }\n          })\n          build.onLoad({ filter: /.*/, namespace: 'entry' }, () => {\n            return {\n              contents: `\n                import \"sideEffects\"\n                import \"noSideEffects\"\n              `,\n            }\n          })\n        },\n      }],\n    })\n    assert.strictEqual(build.outputFiles[0].text, `// entry:entry\\nimport \"sideEffects\";\\n`)\n  },\n\n  async callResolveTooEarlyError({ esbuild }) {\n    try {\n      await esbuild.build({\n        entryPoints: [],\n        logLevel: 'silent',\n        plugins: [{\n          name: 'plugin',\n          async setup(build) {\n            await build.resolve('foo', { kind: 'entry-point' })\n          },\n        }],\n      })\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert(e.message.includes('Cannot call \"resolve\" before plugin setup has completed'), e.message)\n    }\n  },\n\n  async callResolveTooLateError({ esbuild }) {\n    let resolve\n    await esbuild.build({\n      entryPoints: [],\n      plugins: [{\n        name: 'plugin',\n        async setup(build) {\n          resolve = build.resolve\n        },\n      }],\n    })\n    try {\n      const result = await resolve('foo', { kind: 'entry-point' })\n      console.log(result.errors)\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert(e.message.includes('Cannot call \\\"resolve\\\" on an inactive build'), e.message)\n    }\n  },\n\n  async callResolveBadKindError({ esbuild }) {\n    try {\n      await esbuild.build({\n        entryPoints: ['entry'],\n        logLevel: 'silent',\n        plugins: [{\n          name: 'plugin',\n          async setup(build) {\n            build.onResolve({ filter: /^entry$/ }, async () => {\n              return await build.resolve('foo', { kind: 'what' })\n            })\n          },\n        }],\n      })\n      throw new Error('Expected an error to be thrown')\n    } catch (e) {\n      assert(e.message.includes('Invalid kind: \"what\"'), e.message)\n    }\n  },\n\n  // Test that user options are taken into account\n  async callResolveUserOptionsExternal({ esbuild, testDir }) {\n    const result = await esbuild.build({\n      stdin: { contents: `import \"foo\"` },\n      write: false,\n      bundle: true,\n      external: ['bar'],\n      format: 'esm',\n      plugins: [{\n        name: 'plugin',\n        async setup(build) {\n          build.onResolve({ filter: /^foo$/ }, async () => {\n            const result = await build.resolve('bar', {\n              resolveDir: testDir,\n              kind: 'import-statement',\n            })\n            assert(result.external)\n            return { path: 'baz', external: true }\n          })\n        },\n      }],\n    })\n    assert.strictEqual(result.outputFiles[0].text, `// <stdin>\\nimport \"baz\";\\n`)\n  },\n\n  async callResolveBuiltInHandler({ esbuild, testDir }) {\n    const srcDir = path.join(testDir, 'src')\n    const input = path.join(srcDir, 'input.js')\n    await mkdirAsync(srcDir, { recursive: true })\n    await writeFileAsync(input, `console.log(123)`)\n    const result = await esbuild.build({\n      entryPoints: ['entry'],\n      write: false,\n      plugins: [{\n        name: 'plugin',\n        setup(build) {\n          build.onResolve({ filter: /^entry$/ }, async () => {\n            return await build.resolve('./' + path.basename(input), {\n              resolveDir: srcDir,\n              kind: 'import-statement',\n            })\n          })\n        },\n      }],\n    })\n    assert.strictEqual(result.outputFiles[0].text, `console.log(123);\\n`)\n  },\n\n  async callResolvePluginHandler({ esbuild, testDir }) {\n    const srcDir = path.join(testDir, 'src')\n    const input = path.join(srcDir, 'input.js')\n    await mkdirAsync(srcDir, { recursive: true })\n    await writeFileAsync(input, `console.log(123)`)\n    const result = await esbuild.build({\n      entryPoints: ['entry'],\n      write: false,\n      plugins: [{\n        name: 'plugin',\n        setup(build) {\n          build.onResolve({ filter: /^entry$/ }, async () => {\n            return await build.resolve('foo', {\n              importer: 'foo-importer',\n              namespace: 'foo-namespace',\n              resolveDir: 'foo-resolveDir',\n              pluginData: 'foo-pluginData',\n              kind: 'dynamic-import',\n            })\n          })\n          build.onResolve({ filter: /^foo$/ }, async (args) => {\n            assert.strictEqual(args.path, 'foo')\n            assert.strictEqual(args.importer, 'foo-importer')\n            assert.strictEqual(args.namespace, 'foo-namespace')\n            assert.strictEqual(args.resolveDir, path.join(process.cwd(), 'foo-resolveDir'))\n            assert.strictEqual(args.pluginData, 'foo-pluginData')\n            assert.strictEqual(args.kind, 'dynamic-import')\n            return { path: input }\n          })\n        },\n      }],\n    })\n    assert.strictEqual(result.outputFiles[0].text, `console.log(123);\\n`)\n  },\n\n  async injectWithVirtualFile({ esbuild, testDir }) {\n    const input = path.join(testDir, 'input.js')\n    await writeFileAsync(input, `console.log(test)`)\n    const result = await esbuild.build({\n      entryPoints: [input],\n      write: false,\n      inject: ['plugin-file'],\n      plugins: [{\n        name: 'plugin',\n        setup(build) {\n          build.onResolve({ filter: /^plugin-file$/ }, () => {\n            return { namespace: 'plugin', path: 'path' }\n          })\n          build.onLoad({ filter: /^path$/, namespace: 'plugin' }, () => {\n            return { contents: `export let test = 'injected'` }\n          })\n        },\n      }],\n    })\n    assert.strictEqual(result.outputFiles[0].text, `var test2 = \"injected\";\\nconsole.log(test2);\\n`)\n  },\n\n  async tsconfigRawAffectsVirtualFiles({ esbuild }) {\n    const result = await esbuild.build({\n      entryPoints: ['entry'],\n      tsconfigRaw: {\n        compilerOptions: {\n          jsxFactory: 'jay_ess_ex',\n        },\n      },\n      write: false,\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /entry/ }, () => {\n            return { path: 'foo', namespace: 'ns' }\n          })\n          build.onLoad({ filter: /foo/ }, () => {\n            return { loader: 'tsx', contents: 'console.log(<div/>)' }\n          })\n        },\n      }],\n    })\n    assert.strictEqual(result.outputFiles[0].text, 'console.log(/* @__PURE__ */ jay_ess_ex(\"div\", null));\\n')\n  },\n\n  async importAttributesOnResolve({ esbuild }) {\n    const result = await esbuild.build({\n      entryPoints: ['entry'],\n      bundle: true,\n      format: 'esm',\n      charset: 'utf8',\n      write: false,\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => {\n            if (args.with.type === 'cheese') return { path: 'cheese', namespace: 'ns' }\n            if (args.with.pizza === 'true') return { path: 'pizza', namespace: 'ns' }\n            return { path: args.path, namespace: 'ns' }\n          })\n          build.onLoad({ filter: /.*/ }, args => {\n            const entry = `\n              import a from 'foo' with { type: 'cheese' }\n              import b from 'foo' with { pizza: 'true' }\n              console.log(a, b)\n            `\n            if (args.path === 'entry') return { contents: entry }\n            if (args.path === 'cheese') return { contents: `export default \"🧀\"` }\n            if (args.path === 'pizza') return { contents: `export default \"🍕\"` }\n          })\n        },\n      }],\n    })\n    assert.strictEqual(result.outputFiles[0].text, `// ns:cheese\nvar cheese_default = \"🧀\";\n\n// ns:pizza\nvar pizza_default = \"🍕\";\n\n// ns:entry\nconsole.log(cheese_default, pizza_default);\n`)\n  },\n\n  async importAttributesOnLoad({ esbuild }) {\n    const result = await esbuild.build({\n      entryPoints: ['entry'],\n      bundle: true,\n      format: 'esm',\n      charset: 'utf8',\n      write: false,\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => {\n            return { path: args.path, namespace: 'ns' }\n          })\n          build.onLoad({ filter: /.*/ }, args => {\n            const entry = `\n              import a from 'foo' with { type: 'cheese' }\n              import b from 'foo' with { pizza: 'true' }\n              console.log(a, b)\n            `\n            if (args.path === 'entry') return { contents: entry }\n            if (args.with.type === 'cheese') return { contents: `export default \"🧀\"` }\n            if (args.with.pizza === 'true') return { contents: `export default \"🍕\"` }\n          })\n        },\n      }],\n    })\n    assert.strictEqual(result.outputFiles[0].text, `// ns:foo with { type: 'cheese' }\nvar foo_default = \"🧀\";\n\n// ns:foo with { pizza: 'true' }\nvar foo_default2 = \"🍕\";\n\n// ns:entry\nconsole.log(foo_default, foo_default2);\n`)\n  },\n\n  async importAttributesOnLoadGlob({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    const foo = path.join(testDir, 'foo.js')\n    await writeFileAsync(entry, `\n      Promise.all([\n        import('./foo' + js, { with: { type: 'cheese' } }),\n        import('./foo' + js, { with: { pizza: 'true' } }),\n      ]).then(resolve)\n    `)\n    await writeFileAsync(foo, `export default 123`)\n    const result = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      format: 'esm',\n      charset: 'utf8',\n      write: false,\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onLoad({ filter: /.*/ }, args => {\n            if (args.with.type === 'cheese') return { contents: `export default \"🧀\"` }\n            if (args.with.pizza === 'true') return { contents: `export default \"🍕\"` }\n          })\n        },\n      }],\n    })\n    const callback = new Function('js', 'resolve', result.outputFiles[0].text)\n    const [cheese, pizza] = await new Promise(resolve => callback('.js', resolve))\n    assert.strictEqual(cheese.default, '🧀')\n    assert.strictEqual(pizza.default, '🍕')\n  },\n\n  async importAttributesResolve({ esbuild }) {\n    const onResolve = []\n    const resolve = []\n\n    await esbuild.build({\n      entryPoints: [],\n      bundle: true,\n      format: 'esm',\n      charset: 'utf8',\n      write: false,\n      plugins: [{\n        name: 'name',\n        setup(build) {\n          build.onResolve({ filter: /.*/ }, args => {\n            onResolve.push(args)\n            return { external: true }\n          })\n          build.onStart(async () => {\n            resolve.push(await build.resolve('foo', {\n              kind: 'require-call',\n              with: { type: 'cheese' },\n            }))\n            resolve.push(await build.resolve('bar', {\n              kind: 'import-statement',\n              with: { pizza: 'true' },\n            }))\n          })\n        },\n      }],\n    })\n\n    assert.strictEqual(onResolve.length, 2)\n    assert.strictEqual(onResolve[0].path, 'foo')\n    assert.strictEqual(onResolve[0].with.type, 'cheese')\n    assert.strictEqual(onResolve[1].path, 'bar')\n    assert.strictEqual(onResolve[1].with.pizza, 'true')\n\n    assert.strictEqual(resolve.length, 2)\n    assert.strictEqual(resolve[0].path, 'foo')\n    assert.strictEqual(resolve[0].external, true)\n    assert.strictEqual(resolve[1].path, 'bar')\n    assert.strictEqual(resolve[1].external, true)\n  },\n\n  async internalCrashIssue3634({ esbuild }) {\n    await esbuild.build({\n      entryPoints: [],\n      bundle: true,\n      plugins: [{\n        name: 'abc',\n        setup(build) {\n          build.onStart(async () => {\n            const result = await build.resolve('/foo', {\n              kind: 'require-call',\n              resolveDir: 'bar',\n            })\n            assert.strictEqual(result.errors.length, 1)\n          })\n        }\n      }],\n    })\n  },\n\n  async sourceMapNamespacePrefixIssue4078({ esbuild, testDir }) {\n    const entry = path.join(testDir, 'entry.js')\n    await writeFileAsync(entry, `\n      import 'foo'\n      console.log('entry')\n    `)\n\n    const result = await esbuild.build({\n      entryPoints: [entry],\n      bundle: true,\n      sourcemap: true,\n      write: false,\n      outdir: path.join(testDir, 'out'),\n      plugins: [{\n        name: 'example',\n        setup(build) {\n          build.onResolve({ filter: /foo/ }, () => {\n            return { path: 'lib/foo', namespace: 'mynamespace' }\n          })\n          build.onLoad({ filter: /foo/, namespace: 'mynamespace' }, () => {\n            return { contents: 'console.log(\"foo\")' }\n          })\n        },\n      }],\n    })\n\n    assert.strictEqual(result.outputFiles.length, 2)\n    const map = result.outputFiles.find(file => file.path.endsWith('.js.map'))\n    const json = JSON.parse(map.text)\n    assert.deepStrictEqual(json.sources, ['mynamespace:lib/foo', '../entry.js'])\n  },\n}\n\nconst makeRebuildUntilPlugin = () => {\n  let onEnd\n\n  return {\n    rebuildUntil: (mutator, condition) => new Promise((resolve, reject) => {\n      let timeout = setTimeout(() => reject(new Error('Timeout after 30 seconds')), 30 * 1000)\n      onEnd = result => {\n        try { if (result && condition(result)) clearTimeout(timeout), resolve(result) }\n        catch (e) { clearTimeout(timeout), reject(e) }\n      }\n      mutator()\n    }),\n\n    plugin: {\n      name: 'rebuildUntil',\n      setup(build) {\n        build.onEnd(result => onEnd && onEnd(result))\n      },\n    },\n  }\n}\n\n// These tests have to run synchronously\nlet syncTests = {\n  async pluginWithWatchMode({ esbuild, testDir }) {\n    const srcDir = path.join(testDir, 'src')\n    const outfile = path.join(testDir, 'out.js')\n    const input = path.join(srcDir, 'in.js')\n    const example = path.join(srcDir, 'example.js')\n    await mkdirAsync(srcDir, { recursive: true })\n    await writeFileAsync(input, `import {x} from \"./example.js\"; exports.x = x`)\n    await writeFileAsync(example, `export let x = 1`)\n\n    const { rebuildUntil, plugin } = makeRebuildUntilPlugin()\n    const ctx = await esbuild.context({\n      entryPoints: [input],\n      outfile,\n      format: 'cjs',\n      logLevel: 'silent',\n      bundle: true,\n      plugins: [\n        {\n          name: 'some-plugin',\n          setup(build) {\n            build.onLoad({ filter: /example\\.js$/ }, async (args) => {\n              const contents = await fs.promises.readFile(args.path, 'utf8')\n              return { contents }\n            })\n          },\n        },\n        plugin,\n      ],\n    })\n\n    try {\n      // First build\n      const result = await ctx.rebuild()\n      let code = await readFileAsync(outfile, 'utf8')\n      let exports = {}\n      new Function('exports', code)(exports)\n      assert.strictEqual(result.outputFiles, void 0)\n      assert.strictEqual(exports.x, 1)\n      await ctx.watch()\n\n      // First rebuild: edit\n      {\n        const result2 = await rebuildUntil(\n          () => setTimeout(() => writeFileAtomic(example, `export let x = 2`), 250),\n          () => fs.readFileSync(outfile, 'utf8') !== code,\n        )\n        code = await readFileAsync(outfile, 'utf8')\n        exports = {}\n        new Function('exports', code)(exports)\n        assert.strictEqual(result2.outputFiles, void 0)\n        assert.strictEqual(exports.x, 2)\n      }\n    } finally {\n      await ctx.dispose()\n    }\n  },\n\n  async pluginWithWatchFiles({ esbuild, testDir }) {\n    const srcDir = path.join(testDir, 'src')\n    const otherDir = path.join(testDir, 'other')\n    const outfile = path.join(testDir, 'out.js')\n    const input = path.join(srcDir, 'in.js')\n    const example = path.join(otherDir, 'example.js')\n    await mkdirAsync(srcDir, { recursive: true })\n    await mkdirAsync(otherDir, { recursive: true })\n    await writeFileAsync(input, `import {x} from \"<virtual>\"; exports.x = x`)\n    await writeFileAsync(example, `export let x = 1`)\n\n    const { rebuildUntil, plugin } = makeRebuildUntilPlugin()\n    const ctx = await esbuild.context({\n      entryPoints: [input],\n      outfile,\n      format: 'cjs',\n      logLevel: 'silent',\n      bundle: true,\n      plugins: [\n        {\n          name: 'some-plugin',\n          setup(build) {\n            build.onResolve({ filter: /^<virtual>$/ }, args => {\n              return { path: args.path, namespace: 'ns' }\n            })\n            build.onLoad({ filter: /^<virtual>$/, namespace: 'ns' }, async (args) => {\n              const contents = await fs.promises.readFile(example, 'utf8')\n              return { contents, watchFiles: [example] }\n            })\n          },\n        },\n        plugin,\n      ],\n    })\n\n    try {\n      // First build\n      const result = await ctx.rebuild()\n      let code = await readFileAsync(outfile, 'utf8')\n      let exports = {}\n      new Function('exports', code)(exports)\n      assert.strictEqual(result.outputFiles, void 0)\n      assert.strictEqual(exports.x, 1)\n      await ctx.watch()\n\n      // First rebuild: edit\n      {\n        const result2 = await rebuildUntil(\n          () => setTimeout(() => writeFileAtomic(example, `export let x = 2`), 250),\n          () => fs.readFileSync(outfile, 'utf8') !== code,\n        )\n        code = await readFileAsync(outfile, 'utf8')\n        exports = {}\n        new Function('exports', code)(exports)\n        assert.strictEqual(result2.outputFiles, void 0)\n        assert.strictEqual(exports.x, 2)\n      }\n    } finally {\n      await ctx.dispose()\n    }\n  },\n\n  async pluginWithWatchDir({ esbuild, testDir }) {\n    const srcDir = path.join(testDir, 'src')\n    const otherDir = path.join(testDir, 'other')\n    const outfile = path.join(testDir, 'out.js')\n    const input = path.join(srcDir, 'in.js')\n    await mkdirAsync(srcDir, { recursive: true })\n    await mkdirAsync(otherDir, { recursive: true })\n    await writeFileAsync(input, `import {x} from \"<virtual>\"; exports.x = x`)\n\n    const { rebuildUntil, plugin } = makeRebuildUntilPlugin()\n    const ctx = await esbuild.context({\n      entryPoints: [input],\n      outfile,\n      format: 'cjs',\n      logLevel: 'silent',\n      bundle: true,\n      plugins: [\n        {\n          name: 'some-plugin',\n          setup(build) {\n            build.onResolve({ filter: /^<virtual>$/ }, args => {\n              return { path: args.path, namespace: 'ns' }\n            })\n            build.onLoad({ filter: /^<virtual>$/, namespace: 'ns' }, async () => {\n              const entries = await fs.promises.readdir(otherDir, 'utf8')\n              return { contents: `export let x = ${entries.length}`, watchDirs: [otherDir] }\n            })\n          },\n        },\n        plugin,\n      ],\n    })\n\n    try {\n      const result = await ctx.rebuild()\n      let code = await readFileAsync(outfile, 'utf8')\n      let exports = {}\n      new Function('exports', code)(exports)\n      assert.strictEqual(result.outputFiles, void 0)\n      assert.strictEqual(exports.x, 0)\n      await ctx.watch()\n\n      // First rebuild: edit\n      {\n        const result2 = await rebuildUntil(\n          () => setTimeout(() => writeFileAtomic(path.join(otherDir, 'file.txt'), `...`), 250),\n          () => fs.readFileSync(outfile, 'utf8') !== code,\n        )\n        code = await readFileAsync(outfile, 'utf8')\n        exports = {}\n        new Function('exports', code)(exports)\n        assert.strictEqual(result2.outputFiles, void 0)\n        assert.strictEqual(exports.x, 1)\n      }\n    } finally {\n      await ctx.dispose()\n    }\n  },\n\n  async onStartCallback({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, ``)\n\n    let onStartTimes = 0\n    let errorToThrow = null\n    let valueToReturn = null\n\n    const ctx = await esbuild.context({\n      entryPoints: [input],\n      write: false,\n      logLevel: 'silent',\n      plugins: [\n        {\n          name: 'some-plugin',\n          setup(build) {\n            build.onStart(() => {\n              if (errorToThrow) throw errorToThrow\n              if (valueToReturn) return valueToReturn\n              onStartTimes++\n            })\n          },\n        },\n      ],\n    })\n    try {\n      assert.strictEqual(onStartTimes, 0)\n\n      await ctx.rebuild()\n      assert.strictEqual(onStartTimes, 1)\n\n      await ctx.rebuild()\n      assert.strictEqual(onStartTimes, 2)\n\n      errorToThrow = new Error('throw test')\n      try {\n        await ctx.rebuild()\n        throw new Error('Expected an error to be thrown')\n      } catch (e) {\n        assert.notStrictEqual(e.errors, void 0)\n        assert.strictEqual(e.errors.length, 1)\n        assert.strictEqual(e.errors[0].pluginName, 'some-plugin')\n        assert.strictEqual(e.errors[0].text, 'throw test')\n      } finally {\n        errorToThrow = null\n      }\n\n      valueToReturn = { errors: [{ text: 'return test', location: { file: 'foo.js', line: 2 } }] }\n      try {\n        await ctx.rebuild()\n        throw new Error('Expected an error to be thrown')\n      } catch (e) {\n        assert.notStrictEqual(e.errors, void 0)\n        assert.strictEqual(e.errors.length, 1)\n        assert.strictEqual(e.errors[0].pluginName, 'some-plugin')\n        assert.strictEqual(e.errors[0].text, 'return test')\n        assert.notStrictEqual(e.errors[0].location, null)\n        assert.strictEqual(e.errors[0].location.file, 'foo.js')\n        assert.strictEqual(e.errors[0].location.line, 2)\n      } finally {\n        valueToReturn = null\n      }\n\n      assert.strictEqual(onStartTimes, 2)\n      valueToReturn = new Promise(resolve => setTimeout(() => {\n        onStartTimes++\n        resolve()\n      }, 500))\n      await ctx.rebuild()\n      assert.strictEqual(onStartTimes, 3)\n      valueToReturn = null\n    } finally {\n      await ctx.dispose()\n    }\n  },\n\n  async onStartCallbackWithDelay({ esbuild }) {\n    await esbuild.build({\n      entryPoints: ['foo'],\n      write: false,\n      logLevel: 'silent',\n      plugins: [\n        {\n          name: 'some-plugin',\n          setup(build) {\n            let isStarted = false\n            build.onStart(async () => {\n              await new Promise(r => setTimeout(r, 1000))\n              isStarted = true\n            })\n\n            // Verify that \"onStart\" is finished before \"onResolve\" and \"onLoad\" run\n            build.onResolve({ filter: /foo/ }, () => {\n              assert.strictEqual(isStarted, true)\n              return { path: 'foo', namespace: 'foo' }\n            })\n            build.onLoad({ filter: /foo/ }, () => {\n              assert.strictEqual(isStarted, true)\n              return { contents: '' }\n            })\n          },\n        },\n      ],\n    })\n  },\n\n  async onEndCallback({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, ``)\n\n    let onEndTimes = 0\n    let errorToThrow = null\n    let valueToReturn = null\n    let mutateFn = null\n\n    const ctx = await esbuild.context({\n      entryPoints: [input],\n      write: false,\n      logLevel: 'silent',\n      plugins: [\n        {\n          name: 'some-plugin',\n          setup(build) {\n            build.onEnd(result => {\n              if (errorToThrow) throw errorToThrow\n              if (valueToReturn) return valueToReturn\n              if (mutateFn) mutateFn(result)\n              onEndTimes++\n            })\n          },\n        },\n      ],\n    })\n    try {\n      assert.strictEqual(onEndTimes, 0)\n\n      await ctx.rebuild()\n      assert.strictEqual(onEndTimes, 1)\n\n      await ctx.rebuild()\n      assert.strictEqual(onEndTimes, 2)\n\n      errorToThrow = new Error('throw test')\n      try {\n        await ctx.rebuild()\n        throw new Error('Expected an error to be thrown')\n      } catch (e) {\n        assert.notStrictEqual(e.errors, void 0)\n        assert.strictEqual(e.errors.length, 1)\n        assert.strictEqual(e.errors[0].pluginName, 'some-plugin')\n        assert.strictEqual(e.errors[0].text, 'throw test')\n      } finally {\n        errorToThrow = null\n      }\n\n      assert.strictEqual(onEndTimes, 2)\n      valueToReturn = new Promise(resolve => setTimeout(() => {\n        onEndTimes++\n        resolve()\n      }, 500))\n      await ctx.rebuild()\n      assert.strictEqual(onEndTimes, 3)\n      valueToReturn = null\n\n      mutateFn = result => result.warnings.push(true)\n      const result2 = await ctx.rebuild()\n      assert.deepStrictEqual(result2.warnings, [true])\n      mutateFn = () => { }\n      const result3 = await ctx.rebuild()\n      assert.deepStrictEqual(result3.warnings, [])\n\n      // Adding an error this way does not fail the build (we don't scan the build object for modifications)\n      mutateFn = result => result.errors.push({ text: 'test failure' })\n      await ctx.rebuild()\n      mutateFn = () => { }\n\n      // Instead, plugins should return any additional errors from the \"onEnd\" callback itself\n      valueToReturn = { errors: [{ text: 'test failure 2' }] }\n      try {\n        await ctx.rebuild()\n        throw new Error('Expected an error to be thrown')\n      } catch (e) {\n        assert.notStrictEqual(e.errors, void 0)\n        assert.strictEqual(e.errors.length, 1)\n        assert.strictEqual(e.errors[0].pluginName, 'some-plugin')\n        assert.strictEqual(e.errors[0].text, 'test failure 2')\n        assert.strictEqual(e.errors[0].location, null)\n      }\n    } finally {\n      await ctx.dispose()\n    }\n  },\n\n  async onEndCallbackMutateContents({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, `x=y`)\n\n    let onEndTimes = 0\n\n    const result = await esbuild.build({\n      entryPoints: [input],\n      write: false,\n      plugins: [\n        {\n          name: 'some-plugin',\n          setup(build) {\n            build.onEnd(result => {\n              onEndTimes++\n\n              assert.deepStrictEqual(result.outputFiles[0].contents, new Uint8Array([120, 32, 61, 32, 121, 59, 10]))\n              assert.deepStrictEqual(result.outputFiles[0].text, 'x = y;\\n')\n\n              result.outputFiles[0].contents = new Uint8Array([120, 61, 121])\n              assert.deepStrictEqual(result.outputFiles[0].contents, new Uint8Array([120, 61, 121]))\n              assert.deepStrictEqual(result.outputFiles[0].text, 'x=y')\n\n              result.outputFiles[0].contents = new Uint8Array([121, 61, 120])\n              assert.deepStrictEqual(result.outputFiles[0].contents, new Uint8Array([121, 61, 120]))\n              assert.deepStrictEqual(result.outputFiles[0].text, 'y=x')\n            })\n          },\n        },\n      ],\n    })\n\n    assert.deepStrictEqual(onEndTimes, 1)\n    assert.deepStrictEqual(result.outputFiles.length, 1)\n    assert.deepStrictEqual(result.outputFiles[0].contents, new Uint8Array([121, 61, 120]))\n    assert.deepStrictEqual(result.outputFiles[0].text, 'y=x')\n  },\n\n  async onStartOnEndWatchMode({ esbuild, testDir }) {\n    const srcDir = path.join(testDir, 'src')\n    const outfile = path.join(testDir, 'out.js')\n    const input = path.join(srcDir, 'in.js')\n    const example = path.join(srcDir, 'example.js')\n    await mkdirAsync(srcDir, { recursive: true })\n    await writeFileAsync(input, `import {x} from \"./example.js\"; exports.x = x`)\n    await writeFileAsync(example, `export let x = 1`)\n\n    let onStartCalls = 0\n    let onEndCalls = 0\n\n    const { rebuildUntil, plugin } = makeRebuildUntilPlugin()\n    const ctx = await esbuild.context({\n      entryPoints: [input],\n      outfile,\n      format: 'cjs',\n      logLevel: 'silent',\n      bundle: true,\n      metafile: true,\n      plugins: [\n        {\n          name: 'some-plugin',\n          setup(build) {\n            build.onStart(() => {\n              onStartCalls++\n            })\n            build.onEnd(result => {\n              assert.notStrictEqual(result.metafile, void 0)\n              onEndCalls++\n            })\n\n            build.onLoad({ filter: /example\\.js$/ }, async (args) => {\n              const contents = await fs.promises.readFile(args.path, 'utf8')\n              return { contents }\n            })\n          },\n        },\n        plugin,\n      ],\n    })\n\n    try {\n      assert.strictEqual(onStartCalls, 0)\n      assert.strictEqual(onEndCalls, 0)\n\n      const result = await rebuildUntil(\n        () => ctx.watch(),\n        () => true,\n      )\n\n      assert.notStrictEqual(onStartCalls, 0)\n      assert.notStrictEqual(onEndCalls, 0)\n\n      const onStartAfterWatch = onStartCalls\n      const onEndAfterWatch = onEndCalls\n\n      let code = await readFileAsync(outfile, 'utf8')\n      let exports = {}\n      new Function('exports', code)(exports)\n      assert.strictEqual(result.outputFiles, void 0)\n      assert.strictEqual(exports.x, 1)\n\n      // First rebuild: edit\n      {\n        const result2 = await rebuildUntil(\n          () => setTimeout(() => writeFileAtomic(example, `export let x = 2`), 250),\n          () => fs.readFileSync(outfile, 'utf8') !== code,\n        )\n        code = await readFileAsync(outfile, 'utf8')\n        exports = {}\n        new Function('exports', code)(exports)\n        assert.strictEqual(result2.outputFiles, void 0)\n        assert.strictEqual(exports.x, 2)\n      }\n\n      assert.notStrictEqual(onStartCalls, onStartAfterWatch)\n      assert.notStrictEqual(onEndCalls, onEndAfterWatch)\n    } finally {\n      await ctx.dispose()\n    }\n  },\n\n  async pluginServeWriteTrueOnEnd({ esbuild, testDir }) {\n    const outfile = path.join(testDir, 'out.js')\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, `console.log(1+2`)\n\n    let latestResult\n    const ctx = await esbuild.context({\n      entryPoints: [input],\n      outfile,\n      logLevel: 'silent',\n      plugins: [\n        {\n          name: 'some-plugin',\n          setup(build) {\n            build.onEnd(result => {\n              latestResult = result\n            })\n          },\n        },\n      ],\n    })\n\n    try {\n      const server = await ctx.serve()\n\n      // Fetch once\n      try {\n        await fetch(server.hosts[0], server.port, '/out.js')\n        throw new Error('Expected an error to be thrown')\n      } catch (err) {\n        assert.strictEqual(err.statusCode, 503)\n      }\n      assert.strictEqual(latestResult.errors.length, 1)\n      assert.strictEqual(latestResult.errors[0].text, 'Expected \")\" but found end of file')\n\n      // Fix the error\n      await writeFileAsync(input, `console.log(1+2)`)\n\n      // Fetch again\n      const buffer = await fetchUntilSuccessOrTimeout(server.hosts[0], server.port, '/out.js')\n      assert.strictEqual(buffer.toString(), 'console.log(1 + 2);\\n')\n      assert.strictEqual(latestResult.errors.length, 0)\n      assert.strictEqual(latestResult.outputFiles, undefined)\n      assert.strictEqual(fs.readFileSync(outfile, 'utf8'), 'console.log(1 + 2);\\n')\n    } finally {\n      await ctx.dispose()\n    }\n  },\n\n  async pluginServeWriteFalseOnEnd({ esbuild, testDir }) {\n    const outfile = path.join(testDir, 'out.js')\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, `console.log(1+2`)\n\n    let latestResult\n    const ctx = await esbuild.context({\n      entryPoints: [input],\n      outfile,\n      logLevel: 'silent',\n      write: false,\n      plugins: [\n        {\n          name: 'some-plugin',\n          setup(build) {\n            build.onEnd(result => {\n              latestResult = result\n            })\n          },\n        },\n      ],\n    })\n\n    try {\n      const server = await ctx.serve()\n\n      // Fetch once\n      try {\n        await fetch(server.hosts[0], server.port, '/out.js')\n        throw new Error('Expected an error to be thrown')\n      } catch (err) {\n        assert.strictEqual(err.statusCode, 503)\n      }\n      assert.strictEqual(latestResult.errors.length, 1)\n      assert.strictEqual(latestResult.errors[0].text, 'Expected \")\" but found end of file')\n      assert.strictEqual(latestResult.outputFiles.length, 0)\n\n      // Fix the error\n      await writeFileAsync(input, `console.log(1+2)`)\n\n      // Fetch again\n      const buffer = await fetchUntilSuccessOrTimeout(server.hosts[0], server.port, '/out.js')\n      assert.strictEqual(buffer.toString(), 'console.log(1 + 2);\\n')\n      assert.strictEqual(latestResult.errors.length, 0)\n      assert.strictEqual(latestResult.outputFiles.length, 1)\n      assert.strictEqual(latestResult.outputFiles[0].text, 'console.log(1 + 2);\\n')\n      assert.strictEqual(fs.existsSync(outfile), false)\n    } finally {\n      await ctx.dispose()\n    }\n  },\n\n  async pluginOnDisposeAfterSuccessfulBuild({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, `1+2`)\n\n    let onDisposeCalled\n    let onDisposePromise = new Promise(resolve => onDisposeCalled = resolve)\n    await esbuild.build({\n      entryPoints: [input],\n      write: false,\n      plugins: [{\n        name: 'x', setup(build) {\n          build.onDispose(onDisposeCalled)\n        }\n      }]\n    })\n    await onDisposePromise\n  },\n\n  async pluginOnDisposeAfterFailedBuild({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n\n    let onDisposeCalled\n    let onDisposePromise = new Promise(resolve => onDisposeCalled = resolve)\n    try {\n      await esbuild.build({\n        entryPoints: [input],\n        write: false,\n        logLevel: 'silent',\n        plugins: [{\n          name: 'x', setup(build) {\n            build.onDispose(onDisposeCalled)\n          }\n        }]\n      })\n      throw new Error('Expected an error to be thrown')\n    } catch (err) {\n      if (!err.errors || err.errors.length !== 1)\n        throw err\n    }\n    await onDisposePromise\n  },\n\n  async pluginOnDisposeWithUnusedContext({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, `1+2`)\n\n    let onDisposeCalled\n    let onDisposePromise = new Promise(resolve => onDisposeCalled = resolve)\n    let ctx = await esbuild.context({\n      entryPoints: [input],\n      write: false,\n      plugins: [{\n        name: 'x', setup(build) {\n          build.onDispose(onDisposeCalled)\n        }\n      }]\n    })\n    await ctx.dispose()\n    await onDisposePromise\n  },\n\n  async pluginOnDisposeWithRebuild({ esbuild, testDir }) {\n    const input = path.join(testDir, 'in.js')\n    await writeFileAsync(input, `1+2`)\n\n    let onDisposeCalled\n    let onDisposeWasCalled = false\n    let onDisposePromise = new Promise(resolve => {\n      onDisposeCalled = () => {\n        onDisposeWasCalled = true\n        resolve()\n      }\n    })\n    let ctx = await esbuild.context({\n      entryPoints: [input],\n      write: false,\n      plugins: [{\n        name: 'x', setup(build) {\n          build.onDispose(onDisposeCalled)\n        }\n      }]\n    })\n\n    let result = await ctx.rebuild()\n    assert.strictEqual(result.outputFiles.length, 1)\n    assert.strictEqual(onDisposeWasCalled, false)\n\n    await ctx.dispose()\n    await onDisposePromise\n    assert.strictEqual(onDisposeWasCalled, true)\n  },\n}\n\nasync function main() {\n  const esbuild = installForTests()\n\n  // Create a fresh test directory\n  removeRecursiveSync(rootTestDir)\n  fs.mkdirSync(rootTestDir)\n\n  // Time out these tests after 5 minutes. This exists to help debug test hangs in CI.\n  let minutes = 5\n  let timeout = setTimeout(() => {\n    console.error(`❌ plugin tests timed out after ${minutes} minutes, exiting...`)\n    process.exit(1)\n  }, minutes * 60 * 1000)\n\n  // Run all tests concurrently\n  const runTest = async ([name, fn]) => {\n    let testDir = path.join(rootTestDir, name)\n    try {\n      await mkdirAsync(testDir)\n      await fn({ esbuild, testDir })\n      removeRecursiveSync(testDir)\n      return true\n    } catch (e) {\n      console.error(`❌ ${name}: ${e && e.message || e}`)\n      return false\n    }\n  }\n  const tests = Object.entries(pluginTests)\n  let allTestsPassed = (await Promise.all(tests.map(runTest))).every(success => success)\n\n  for (let test of Object.entries(syncTests)) {\n    if (!await runTest(test)) {\n      allTestsPassed = false\n    }\n  }\n\n  if (!allTestsPassed) {\n    console.error(`❌ plugin tests failed`)\n    process.exit(1)\n  } else {\n    console.log(`✅ plugin tests passed`)\n    removeRecursiveSync(rootTestDir)\n  }\n\n  clearTimeout(timeout);\n}\n\nmain().catch(e => setTimeout(() => { throw e }))\n"
  },
  {
    "path": "scripts/register-test.js",
    "content": "const { installForTests, removeRecursiveSync } = require('./esbuild')\nconst child_process = require('child_process')\nconst path = require('path')\nconst fs = require('fs')\nconst assert = require('assert')\nconst esbuild = installForTests()\n\n// Create a fresh test directory\nconst rootTestDir = path.join(__dirname, '.register-test')\nremoveRecursiveSync(rootTestDir)\nfs.mkdirSync(rootTestDir)\n\nconst entry = path.join(rootTestDir, 'entry.ts')\nfs.writeFileSync(entry, `\n  console.log('in entry.ts' as string)\n  require('./other.ts')\n`)\n\nconst other = path.join(rootTestDir, 'other.ts')\nfs.writeFileSync(other, `\n  console.log('in other.ts' as string)\n`)\n\nconst register = path.join(rootTestDir, 'register.js')\nfs.writeFileSync(register, `\n  const esbuild = require(${JSON.stringify(esbuild.ESBUILD_PACKAGE_PATH)});\n  const fs = require('fs');\n  require.extensions['.ts'] = (mod, filename) => {\n    const ts = fs.readFileSync(filename, 'utf8');\n    const { code } = esbuild.transformSync(ts, { loader: 'ts' });\n    mod._compile(code, filename);\n  };\n`)\n\nlet tests = {\n  async fromMainThread() {\n    let result = await new Promise((resolve, reject) => child_process.execFile('node', ['-r', register, entry], (err, stdout) => {\n      if (err) reject(err)\n      else resolve(stdout)\n    }))\n    assert.strictEqual(result, `in entry.ts\\nin other.ts\\n`)\n  },\n\n  async fromChildThread({ testDir }) {\n    const startThread = path.join(testDir, 'startThread.js')\n    fs.writeFileSync(startThread, `\n      const worker_threads = require('worker_threads')\n      if (worker_threads.isMainThread) {\n        console.log('in startThread.js')\n        const worker = new worker_threads.Worker(__filename)\n        worker.postMessage(null)\n        worker.on('message', logs => {\n          for (const log of logs) console.log(log)\n          worker.terminate()\n        })\n      } else {\n        worker_threads.parentPort.on('message', () => {\n          console.log('in worker')\n          let logs = []\n          console.log = x => logs.push(x)\n          require('../entry.ts')\n          worker_threads.parentPort.postMessage(logs)\n        })\n      }\n    `)\n\n    let result = await new Promise((resolve, reject) => child_process.execFile('node', ['-r', register, startThread], (err, stdout) => {\n      if (err) reject(err)\n      else resolve(stdout)\n    }))\n    assert.strictEqual(result, `in startThread.js\\nin worker\\nin entry.ts\\nin other.ts\\n`)\n  },\n}\n\nasync function main() {\n  // Time out these tests after 5 minutes. This exists to help debug test hangs in CI.\n  let minutes = 5\n  let timeout = setTimeout(() => {\n    console.error(`❌ register tests timed out after ${minutes} minutes, exiting...`)\n    process.exit(1)\n  }, minutes * 60 * 1000)\n\n  const runTest = async ([name, fn]) => {\n    let testDir = path.join(rootTestDir, name)\n    try {\n      fs.mkdirSync(testDir)\n      await fn({ esbuild, testDir })\n      removeRecursiveSync(testDir)\n      return true\n    } catch (e) {\n      console.error(`❌ ${name}: ${e && e.message || e}`)\n      return false\n    }\n  }\n\n  // Run all tests in serial\n  let allTestsPassed = true\n  for (let test of Object.entries(tests)) {\n    if (!await runTest(test)) {\n      allTestsPassed = false\n    }\n  }\n\n  if (!allTestsPassed) {\n    console.error(`❌ register tests failed`)\n    process.exit(1)\n  } else {\n    console.log(`✅ register tests passed`)\n    removeRecursiveSync(rootTestDir)\n  }\n\n  clearTimeout(timeout);\n}\n\nmain().catch(e => setTimeout(() => { throw e }))\n"
  },
  {
    "path": "scripts/terser-tests.js",
    "content": "const { installForTests } = require('./esbuild');\nconst childProcess = require('child_process');\nconst assert = require('assert');\nconst path = require('path');\nconst fs = require('fs');\n\nconst repoDir = path.dirname(__dirname);\nconst testDir = path.join(repoDir, 'scripts', '.terser-tests');\nconst terserDir = path.join(repoDir, 'demo', 'terser');\nlet U;\n\nmain().catch(e => setTimeout(() => { throw e }));\n\nasync function main() {\n  // Terser's stdout comparisons fail if this is true since stdout contains\n  // terminal color escape codes\n  process.stdout.isTTY = false;\n\n  // Make sure the tests are installed\n  console.log('Downloading terser...');\n  childProcess.execSync('make demo/terser', { cwd: repoDir, stdio: 'pipe' });\n  U = require(terserDir);\n\n  // Create a fresh test directory\n  childProcess.execSync(`rm -fr \"${testDir}\"`);\n  fs.mkdirSync(testDir)\n\n  // Start the esbuild service\n  const esbuild = installForTests();\n\n  // Find test files\n  const compressDir = path.join(terserDir, 'test', 'compress');\n  const files = fs.readdirSync(compressDir).filter(name => name.endsWith('.js'));\n\n  // Run all tests concurrently\n  let passedTotal = 0;\n  let failedTotal = 0;\n  const runTest = file => test_file(esbuild, path.join(compressDir, file))\n    .then(({ passed, failed }) => {\n      passedTotal += passed;\n      failedTotal += failed;\n    });\n  await Promise.all(files.map(runTest));\n\n  // Clean up test output\n  childProcess.execSync(`rm -fr \"${testDir}\"`);\n\n  console.log(`${failedTotal} failed out of ${passedTotal + failedTotal}`);\n  if (failedTotal) {\n    process.exit(1);\n  }\n}\n\nasync function test_file(esbuild, file) {\n  let passed = 0;\n  let failed = 0;\n  const tests = parse_test(file);\n  const runTest = name => test_case(esbuild, tests[name])\n    .then(() => passed++)\n    .catch(e => {\n      failed++;\n      console.error(`❌ ${file}: ${name}: ${(e && e.message || e).trim()}\\n`);\n      pass = false;\n    });\n  await Promise.all(Object.keys(tests).map(runTest));\n  return { passed, failed };\n}\n\n// Modified from \"terser/demo/test/compress.js\"\nasync function test_case(esbuild, test) {\n  const sandbox = require(path.join(terserDir, 'test', 'sandbox'));\n  const log = (format, args) => { throw new Error(tmpl(format, args)); };\n\n  var semver = require(path.join(terserDir, 'node_modules', 'semver'));\n  var output_options = test.beautify || {};\n\n  // Generate the input code\n  if (test.input instanceof U.AST_SimpleStatement\n    && test.input.body instanceof U.AST_TemplateString) {\n    try {\n      var input = U.parse(test.input.body.segments[0].value);\n    } catch (ex) {\n      return false;\n    }\n    var input_code = make_code(input, output_options);\n    var input_formatted = test.input.body.segments[0].value;\n  } else {\n    var input = as_toplevel(test.input, test.mangle);\n    var input_code = make_code(input, output_options);\n    var input_formatted = make_code(test.input, {\n      ecma: 2015,\n      beautify: true,\n      quote_style: 3,\n      keep_quoted_props: true\n    });\n  }\n\n  // Make sure it's valid\n  try {\n    U.parse(input_code);\n  } catch (ex) {\n    log(\"!!! Cannot parse input\\n---INPUT---\\n{input}\\n--PARSE ERROR--\\n{error}\\n\\n\", {\n      input: input_formatted,\n      error: ex,\n    });\n    return false;\n  }\n\n  // Pretty-print it\n  var ast = input.to_mozilla_ast();\n  var mozilla_options = {\n    ecma: output_options.ecma,\n    ascii_only: output_options.ascii_only,\n    comments: false,\n  };\n  var ast_as_string = U.AST_Node.from_mozilla_ast(ast).print_to_string(mozilla_options);\n\n  // Run esbuild as a minifier\n  try {\n    var { code: output } = await esbuild.transform(ast_as_string, {\n      minify: true,\n      keepNames: test.options.keep_fnames,\n    });\n  } catch (e) {\n    const formatError = ({ text, location }) => {\n      if (!location) return `\\nerror: ${text}`;\n      const { file, line, column } = location;\n      return `\\n${file}:${line}:${column}: ERROR: ${text}`;\n    }\n    log(\"!!! esbuild failed\\n---INPUT---\\n{input}\\n---ERROR---\\n{error}\\n\", {\n      input: ast_as_string,\n      error: (e && e.message || e) + '' + (e.errors ? e.errors.map(formatError) : ''),\n    });\n    return false;\n  }\n\n  // Make sure esbuild generates valid JavaScript\n  try {\n    U.parse(output);\n  } catch (ex) {\n    log(\"!!! Test matched expected result but cannot parse output\\n---INPUT---\\n{input}\\n---OUTPUT---\\n{output}\\n--REPARSE ERROR--\\n{error}\\n\\n\", {\n      input: input_formatted,\n      output: output,\n      error: ex.stack,\n    });\n    return false;\n  }\n\n  // Verify that the stdout matches our expectations\n  if (test.expect_stdout\n    && (!test.node_version || semver.satisfies(process.version, test.node_version))\n    && !process.env.TEST_NO_SANDBOX\n  ) {\n    if (test.expect_stdout === true) {\n      test.expect_stdout = sandbox.run_code(input_code, test.prepend_code);\n    }\n    var stdout = sandbox.run_code(output, test.prepend_code);\n    if (!sandbox.same_stdout(test.expect_stdout, stdout)) {\n      log(\"!!! failed\\n---INPUT---\\n{input}\\n---OUTPUT---\\n{output}\\n---EXPECTED {expected_type}---\\n{expected}\\n---ACTUAL {actual_type}---\\n{actual}\\n\\n\", {\n        input: input_formatted,\n        output: output,\n        expected_type: typeof test.expect_stdout == \"string\" ? \"STDOUT\" : \"ERROR\",\n        expected: test.expect_stdout,\n        actual_type: typeof stdout == \"string\" ? \"STDOUT\" : \"ERROR\",\n        actual: stdout,\n      });\n      return false;\n    }\n  }\n  return true;\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// The code below was copied verbatim from \"terser/demo/test/compress.js\"\n//\n// UglifyJS is released under the BSD license:\n//\n// Copyright 2012-2019 (c) Mihai Bazon <mihai.bazon@gmail.com>\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions\n// are met:\n//\n//     * Redistributions of source code must retain the above\n//       copyright notice, this list of conditions and the following\n//       disclaimer.\n//\n//     * Redistributions in binary form must reproduce the above\n//       copyright notice, this list of conditions and the following\n//       disclaimer in the documentation and/or other materials\n//       provided with the distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY\n// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE\n// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,\n// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\n// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n// SUCH DAMAGE.\n\nfunction tmpl() {\n  return U.string_template.apply(this, arguments);\n}\n\nfunction as_toplevel(input, mangle_options) {\n  if (!(input instanceof U.AST_BlockStatement))\n    throw new Error(\"Unsupported input syntax\");\n  for (var i = 0; i < input.body.length; i++) {\n    var stat = input.body[i];\n    if (stat instanceof U.AST_SimpleStatement && stat.body instanceof U.AST_String)\n      input.body[i] = new U.AST_Directive(stat.body);\n    else break;\n  }\n  var toplevel = new U.AST_Toplevel(input);\n  toplevel.figure_out_scope(mangle_options);\n  return toplevel;\n}\n\nfunction parse_test(file) {\n  var script = fs.readFileSync(file, \"utf8\");\n  // TODO try/catch can be removed after fixing https://github.com/mishoo/UglifyJS2/issues/348\n  try {\n    var ast = U.parse(script, {\n      filename: file\n    });\n  } catch (e) {\n    console.log(\"Caught error while parsing tests in \" + file + \"\\n\");\n    console.log(e);\n    throw e;\n  }\n  var tests = {};\n  var tw = new U.TreeWalker(function (node, descend) {\n    if (node instanceof U.AST_LabeledStatement\n      && tw.parent() instanceof U.AST_Toplevel) {\n      var name = node.label.name;\n      if (name in tests) {\n        throw new Error('Duplicated test name \"' + name + '\" in ' + file);\n      }\n      tests[name] = get_one_test(name, node.body);\n      return true;\n    }\n    if (!(node instanceof U.AST_Toplevel)) croak(node);\n  });\n  ast.walk(tw);\n  return tests;\n\n  function croak(node) {\n    throw new Error(tmpl(\"Can't understand test file {file} [{line},{col}]\\n{code}\", {\n      file: file,\n      line: node.start.line,\n      col: node.start.col,\n      code: make_code(node, { beautify: false })\n    }));\n  }\n\n  function read_boolean(stat) {\n    if (stat.TYPE == \"SimpleStatement\") {\n      var body = stat.body;\n      if (body instanceof U.AST_Boolean) {\n        return body.value;\n      }\n    }\n    throw new Error(\"Should be boolean\");\n  }\n\n  function read_string(stat) {\n    if (stat.TYPE == \"SimpleStatement\") {\n      var body = stat.body;\n      switch (body.TYPE) {\n        case \"String\":\n          return body.value;\n        case \"Array\":\n          return body.elements.map(function (element) {\n            if (element.TYPE !== \"String\")\n              throw new Error(\"Should be array of strings\");\n            return element.value;\n          }).join(\"\\n\");\n      }\n    }\n    throw new Error(\"Should be string or array of strings\");\n  }\n\n  function get_one_test(name, block) {\n    var test = {\n      name: name,\n      options: {},\n      reminify: true,\n    };\n    var tw = new U.TreeWalker(function (node, descend) {\n      if (node instanceof U.AST_Assign) {\n        if (!(node.left instanceof U.AST_SymbolRef)) {\n          croak(node);\n        }\n        var name = node.left.name;\n        test[name] = evaluate(node.right);\n        return true;\n      }\n      if (node instanceof U.AST_LabeledStatement) {\n        var label = node.label;\n        assert.ok(\n          [\n            \"input\",\n            \"prepend_code\",\n            \"expect\",\n            \"expect_error\",\n            \"expect_exact\",\n            \"expect_warnings\",\n            \"expect_stdout\",\n            \"node_version\",\n            \"reminify\",\n          ].includes(label.name),\n          tmpl(\"Unsupported label {name} [{line},{col}]\", {\n            name: label.name,\n            line: label.start.line,\n            col: label.start.col\n          })\n        );\n        var stat = node.body;\n        if (label.name == \"expect_exact\" || label.name == \"node_version\") {\n          test[label.name] = read_string(stat);\n        } else if (label.name == \"reminify\") {\n          var value = read_boolean(stat);\n          test.reminify = value == null || value;\n        } else if (label.name == \"expect_stdout\") {\n          var body = stat.body;\n          if (body instanceof U.AST_Boolean) {\n            test[label.name] = body.value;\n          } else if (body instanceof U.AST_Call) {\n            var ctor = global[body.expression.name];\n            assert.ok(ctor === Error || ctor.prototype instanceof Error, tmpl(\"Unsupported expect_stdout format [{line},{col}]\", {\n              line: label.start.line,\n              col: label.start.col\n            }));\n            test[label.name] = ctor.apply(null, body.args.map(function (node) {\n              assert.ok(node instanceof U.AST_Constant, tmpl(\"Unsupported expect_stdout format [{line},{col}]\", {\n                line: label.start.line,\n                col: label.start.col\n              }));\n              return node.value;\n            }));\n          } else {\n            test[label.name] = read_string(stat) + \"\\n\";\n          }\n        } else if (label.name === \"prepend_code\") {\n          test[label.name] = read_string(stat);\n        } else {\n          test[label.name] = stat;\n        }\n        return true;\n      }\n    });\n    block.walk(tw);\n    return test;\n  }\n}\n\nfunction make_code(ast, options) {\n  var stream = U.OutputStream(options);\n  ast.print(stream);\n  return stream.get();\n}\n\nfunction evaluate(code) {\n  if (code instanceof U.AST_Node)\n    code = make_code(code, { beautify: true });\n  return new Function(\"return(\" + code + \")\")();\n}\n"
  },
  {
    "path": "scripts/test-yarnpnp.js",
    "content": "const child_process = require('child_process')\nconst esbuild = require('./esbuild')\nconst path = require('path')\nconst fs = require('fs')\n\nconst ESBUILD_BINARY_PATH = esbuild.buildBinary()\nconst rootDir = path.join(__dirname, '..', 'require', 'yarnpnp')\n\nfunction run(command) {\n  console.log('\\n\\x1B[37m' + '$ ' + command + '\\x1B[0m')\n  child_process.execSync(command, { cwd: rootDir, stdio: 'inherit' })\n}\n\nfunction modTime(file) {\n  return fs.statSync(file).mtimeMs\n}\n\nfunction reinstallYarnIfNeeded() {\n  const yarnPath = path.join(rootDir, '.yarn', 'releases', 'yarn-4.0.0-rc.22.cjs')\n\n  if (fs.existsSync(yarnPath) && modTime(yarnPath) > Math.max(\n    modTime(path.join(rootDir, 'package.json')),\n    modTime(path.join(rootDir, 'yarn.lock')),\n  )) {\n    return\n  }\n\n  fs.rmSync(path.join(rootDir, '.pnp.cjs'), { recursive: true, force: true })\n  fs.rmSync(path.join(rootDir, '.pnp.loader.mjs'), { recursive: true, force: true })\n  fs.rmSync(path.join(rootDir, '.yarn'), { recursive: true, force: true })\n  fs.rmSync(path.join(rootDir, '.yarnrc.yml'), { recursive: true, force: true })\n\n  try {\n    run('yarn set version 4.0.0-rc.22')\n  } catch {\n    run('npm i -g yarn') // Install Yarn globally if it's not already installed\n    run('yarn set version 4.0.0-rc.22')\n  }\n\n  let rc\n  try {\n    rc = fs.readFileSync(path.join(rootDir, '.yarnrc.yml'), 'utf8')\n  } catch {\n    rc = '' // Sometimes this file doesn't exist, so pretend it's empty\n  }\n  fs.writeFileSync(path.join(rootDir, '.yarnrc.yml'), `\npnpEnableEsmLoader: true\npnpIgnorePatterns: [\"./bar/**\"]\n\n# Note: Yarn 4 defaults to \"enableGlobalCache: true\" which doesn't\n# work on Windows due to cross-drive issues with relative paths.\n# Explicitly set \"enableGlobalCache: false\" to avoid this issue.\nenableGlobalCache: false\n\n` + rc)\n\n  run('yarn install')\n}\n\nfunction runTests() {\n  // Make sure the tests are valid\n  run('yarn node in.mjs')\n\n  // Test the native build\n  child_process.execFileSync(ESBUILD_BINARY_PATH, [\n    'in.mjs',\n    '--bundle',\n    '--log-level=debug',\n    '--platform=node',\n    '--outfile=out-native.js',\n  ], { cwd: rootDir, stdio: 'inherit' })\n  run('node out-native.js')\n\n  // Test the WebAssembly build\n  esbuild.buildWasmLib(ESBUILD_BINARY_PATH)\n  run('node ../../npm/esbuild-wasm/bin/esbuild in.mjs --bundle --log-level=debug --platform=node --outfile=out-wasm.js')\n  run('node out-wasm.js')\n\n  // Test the WebAssembly build when run through Yarn's file system shim\n  esbuild.buildWasmLib(ESBUILD_BINARY_PATH)\n  run('yarn node ../../npm/esbuild-wasm/bin/esbuild in.mjs --bundle --log-level=debug --platform=node --outfile=out-wasm-yarn.js')\n  run('node out-wasm-yarn.js')\n}\n\nconst minutes = 10\nconst timeout = setTimeout(() => {\n  console.error(`❌ Yarn PnP tests timed out after ${minutes} minutes`)\n  process.exit(1)\n}, minutes * 60 * 1000)\n\nreinstallYarnIfNeeded()\nrunTests()\nclearTimeout(timeout)\n"
  },
  {
    "path": "scripts/test262-async.js",
    "content": "// This file runs test262 tests for the async iteration proposal:\n// https://github.com/tc39/proposal-async-iteration. It's intended\n// to be informative (to identify failure points) but not to be\n// run in CI. Not even node/V8 passes all of these tests.\n\nconst esbuild = require('./esbuild').installForTests()\nconst ts = require('./node_modules/typescript')\nconst fs = require('fs')\nconst vm = require('vm')\n\nconst test262Dir = __dirname + '/../demo/test262'\nconst shim = ``\n  + fs.readFileSync(test262Dir + '/harness/assert.js', 'utf8')\n  + fs.readFileSync(test262Dir + '/harness/asyncHelpers.js', 'utf8')\n  + fs.readFileSync(test262Dir + '/harness/compareArray.js', 'utf8')\n  + fs.readFileSync(test262Dir + '/harness/propertyHelper.js', 'utf8')\n  + fs.readFileSync(test262Dir + '/harness/sta.js', 'utf8')\n\nasync function main() {\n  const tests = []\n\n  for (const dir of [\n    test262Dir + '/test/language/statements/async-generator',\n    test262Dir + '/test/language/statements/for-await-of',\n  ]) {\n    for (const name of fs.readdirSync(dir)) {\n      if (name.endsWith('.js')) {\n        tests.push(dir + '/' + name)\n      }\n    }\n  }\n\n  for (const test of tests) {\n    const stuck = () => console.log(`❌ ${test}: stuck`)\n    process.on('exit', stuck)\n\n    let js = fs.readFileSync(test, 'utf8')\n    let negative = /negative:/.test(js)\n\n    let flags = /flags:.*/.exec(js)\n    flags = flags && new Set(/flags: \\[([^\\]]*)\\]/.exec(js)[1].split(', '))\n\n    let didFail = false\n\n    const check = async (kind, codePromise) => {\n      let error\n      try {\n        let { code } = await codePromise\n        code = shim + code\n        if (flags && flags.has('onlyStrict')) {\n          code = '\"use strict\";\\n' + code\n        }\n        await new Promise((resolve, reject) => {\n          if (flags && flags.has('async')) {\n            vm.runInContext(code, vm.createContext({ $DONE: err => err ? reject(err) : resolve() }))\n          } else {\n            vm.runInContext(code, vm.createContext({}))\n            resolve()\n          }\n        })\n      } catch (err) {\n        error = err\n      }\n      if (!error === !negative) {\n        return true\n      }\n      if (!didFail) {\n        didFail = true\n        console.log(`\\n❌ \\x1B[37m${test}\\x1B[0m`)\n      }\n      if (kind === 'native') kind = '\\x1B[32m[' + kind + ']\\x1B[0m'\n      else if (kind.startsWith('ts')) kind = '\\x1B[34m[' + kind + ']\\x1B[0m'\n      else kind = '\\x1B[33m[' + kind + ']\\x1B[0m'\n      console.log(`  ${kind} ${(error + '' || 'unexpected success').replace(/\\n/g, '\\\\n')}`)\n      return false\n    }\n\n    const tsTranspile = async (compilerOptions) => {\n      const { outputText } = ts.transpileModule(js, { compilerOptions })\n      return { code: outputText }\n    }\n\n    // See if node's native support checks out (it currently doesn't due to recent specification changes)\n    await check('native', { code: js })\n\n    // Ignore tests that check whether \"yield\" can be used as a valid\n    // identifier. This obviously doesn't work when we must transform\n    // async functions into generator functions, but that's fine.\n    const hasYieldKeyword = test.includes('yield-ident-valid') || test.includes('array-elem-target-yield-valid')\n\n    // Check \"tsc\"\n    await check('ts=esnext', tsTranspile({ target: ts.ScriptTarget.ESNext }))\n    await check('ts=es2017', tsTranspile({ target: ts.ScriptTarget.ES2017 }))\n    if (!hasYieldKeyword) {\n      await check('ts=es2016', { code: ts.transpileModule(js, { compilerOptions: { target: ts.ScriptTarget.ES2016 } }).outputText })\n    }\n\n    // Check \"esbuild\"\n    await check('target=esnext', esbuild.transform(js, { keepNames: true, target: 'esnext' }))\n    await check('target=es2017', esbuild.transform(js, { keepNames: true, target: 'es2017' }))\n    await check('for-await=false', esbuild.transform(js, { keepNames: true, supported: { 'for-await': false } }))\n    if (!hasYieldKeyword) {\n      await check('target=es2016', esbuild.transform(js, { keepNames: true, target: 'es2016' }))\n      await check('async-await=false', esbuild.transform(js, { keepNames: true, supported: { 'async-await': false } }))\n      await check('for-await=false,async-await=false', esbuild.transform(js, { keepNames: true, supported: { 'for-await': false, 'async-await': false } }))\n    }\n\n    process.off('exit', stuck)\n  }\n\n  console.log(`Done`)\n}\n\nmain()\n"
  },
  {
    "path": "scripts/test262.js",
    "content": "const vm = require('vm')\nconst fs = require('fs')\nconst path = require('path')\nconst jsYaml = require('js-yaml')\nconst isatty = require('tty').isatty(process.stdout.fd)\nconst { installForTests } = require('./esbuild')\n\nconst testDir = path.join(__dirname, '..', 'demo', 'test262', 'test')\nconst harnessDir = path.join(__dirname, '..', 'demo', 'test262', 'harness')\n\nconst progressBarLength = 64\nconst eraseProgressBar = () => {\n  previousProgressBar = null\n  let text = `\\r${' '.repeat(progressBarLength)}\\r`\n  if (printNewlineWhenErasing) {\n    printNewlineWhenErasing = false\n    text += '\\n'\n  }\n  return text\n}\nlet previousProgressBar = null\nlet printNewlineWhenErasing = false\n\nconst resetColor = isatty ? `\\x1b[0m` : ''\nconst boldColor = isatty ? `\\x1b[1m` : ''\nconst dimColor = isatty ? `\\x1b[37m` : ''\nconst underlineColor = isatty ? `\\x1b[4m` : ''\n\nconst redColor = isatty ? `\\x1b[31m` : ''\nconst greenColor = isatty ? `\\x1b[32m` : ''\nconst blueColor = isatty ? `\\x1b[34m` : ''\n\nconst cyanColor = isatty ? `\\x1b[36m` : ''\nconst magentaColor = isatty ? `\\x1b[35m` : ''\nconst yellowColor = isatty ? `\\x1b[33m` : ''\n\nconst redBgRedColor = isatty ? `\\x1b[41;31m` : ''\nconst redBgWhiteColor = isatty ? `\\x1b[41;97m` : ''\nconst greenBgGreenColor = isatty ? `\\x1b[42;32m` : ''\nconst greenBgWhiteColor = isatty ? `\\x1b[42;97m` : ''\nconst blueBgBlueColor = isatty ? `\\x1b[44;34m` : ''\nconst blueBgWhiteColor = isatty ? `\\x1b[44;97m` : ''\n\nconst cyanBgCyanColor = isatty ? `\\x1b[46;36m` : ''\nconst cyanBgBlackColor = isatty ? `\\x1b[46;30m` : ''\nconst magentaBgMagentaColor = isatty ? `\\x1b[45;35m` : ''\nconst magentaBgBlackColor = isatty ? `\\x1b[45;30m` : ''\nconst yellowBgYellowColor = isatty ? `\\x1b[43;33m` : ''\nconst yellowBgBlackColor = isatty ? `\\x1b[43;30m` : ''\n\nconst whiteBgWhiteColor = isatty ? `\\x1b[107;97m` : ''\nconst whiteBgBlackColor = isatty ? `\\x1b[107;30m` : ''\n\nconst skipTheseFeatures = new Set([\n  'regexp-v-flag',\n  'regexp-match-indices',\n  'regexp-named-groups',\n  'regexp-unicode-property-escapes',\n])\n\nconst skipTheseTests = new Set([\n  // Skip these tests because esbuild deliberately always supports ESM syntax\n  // in all files. Also esbuild doesn't support the script goal at all.\n  'language/expressions/import.meta/syntax/goal-script.js',\n  'language/global-code/export.js',\n  'language/global-code/import.js',\n\n  // Skip these tests because we deliberately support top-level return (input\n  // files are treated as CommonJS and/or ESM but never as global code, and\n  // top-level return is allowed in CommonJS)\n  'language/statements/return/S12.9_A1_T1.js',\n  'language/statements/return/S12.9_A1_T10.js',\n  'language/statements/return/S12.9_A1_T2.js',\n  'language/statements/return/S12.9_A1_T3.js',\n  'language/statements/return/S12.9_A1_T4.js',\n  'language/statements/return/S12.9_A1_T5.js',\n  'language/statements/return/S12.9_A1_T6.js',\n  'language/statements/return/S12.9_A1_T7.js',\n  'language/statements/return/S12.9_A1_T8.js',\n  'language/statements/return/S12.9_A1_T9.js',\n  'language/global-code/return.js',\n\n  // Skip these tests because we deliberately support parsing top-level await\n  // in all files. Files containing top-level await are always interpreted as\n  // ESM, never as CommonJS.\n  'language/expressions/assignmenttargettype/simple-basic-identifierreference-await.js',\n  'language/expressions/await/await-BindingIdentifier-in-global.js',\n  'language/expressions/await/await-in-global.js',\n  'language/expressions/await/await-in-nested-function.js',\n  'language/expressions/await/await-in-nested-generator.js',\n  'language/expressions/class/class-name-ident-await-escaped.js',\n  'language/expressions/class/class-name-ident-await.js',\n  'language/expressions/class/static-init-await-reference.js',\n  'language/expressions/dynamic-import/2nd-param-await-ident.js',\n  'language/expressions/dynamic-import/assignment-expression/await-identifier.js',\n  'language/expressions/function/static-init-await-reference.js',\n  'language/expressions/generators/static-init-await-reference.js',\n  'language/expressions/in/private-field-rhs-await-absent.js',\n  'language/expressions/object/identifier-shorthand-await-strict-mode.js',\n  'language/expressions/object/method-definition/static-init-await-reference-accessor.js',\n  'language/expressions/object/method-definition/static-init-await-reference-generator.js',\n  'language/expressions/object/method-definition/static-init-await-reference-normal.js',\n  'language/module-code/top-level-await/new-await-script-code.js',\n  'language/reserved-words/await-script.js',\n  'language/statements/class/class-name-ident-await-escaped.js',\n  'language/statements/class/class-name-ident-await.js',\n  'language/statements/labeled/value-await-non-module-escaped.js',\n  'language/statements/labeled/value-await-non-module.js',\n\n  // Skip these tests because we don't currently validate the contents of\n  // regular expressions. We could do this but it's not necessary to parse\n  // JavaScript successfully since we parse enough of it to be able to\n  // determine where the regular expression ends (just \"\\\" and \"[]\" pairs).\n  'language/literals/regexp/early-err-pattern.js',\n  'language/literals/regexp/invalid-braced-quantifier-exact.js',\n  'language/literals/regexp/invalid-braced-quantifier-lower.js',\n  'language/literals/regexp/invalid-braced-quantifier-range.js',\n  'language/literals/regexp/invalid-optional-lookbehind.js',\n  'language/literals/regexp/invalid-optional-negative-lookbehind.js',\n  'language/literals/regexp/invalid-range-lookbehind.js',\n  'language/literals/regexp/invalid-range-negative-lookbehind.js',\n  'language/literals/regexp/u-invalid-class-escape.js',\n  'language/literals/regexp/u-invalid-extended-pattern-char.js',\n  'language/literals/regexp/u-invalid-identity-escape.js',\n  'language/literals/regexp/u-invalid-legacy-octal-escape.js',\n  'language/literals/regexp/u-invalid-non-empty-class-ranges-no-dash-a.js',\n  'language/literals/regexp/u-invalid-non-empty-class-ranges-no-dash-ab.js',\n  'language/literals/regexp/u-invalid-non-empty-class-ranges-no-dash-b.js',\n  'language/literals/regexp/u-invalid-non-empty-class-ranges.js',\n  'language/literals/regexp/u-invalid-oob-decimal-escape.js',\n  'language/literals/regexp/u-invalid-optional-lookahead.js',\n  'language/literals/regexp/u-invalid-optional-lookbehind.js',\n  'language/literals/regexp/u-invalid-optional-negative-lookahead.js',\n  'language/literals/regexp/u-invalid-optional-negative-lookbehind.js',\n  'language/literals/regexp/u-invalid-range-lookahead.js',\n  'language/literals/regexp/u-invalid-range-lookbehind.js',\n  'language/literals/regexp/u-invalid-range-negative-lookahead.js',\n  'language/literals/regexp/u-invalid-range-negative-lookbehind.js',\n  'language/literals/regexp/u-unicode-esc-bounds.js',\n  'language/literals/regexp/u-unicode-esc-non-hex.js',\n  'language/literals/regexp/unicode-escape-nls-err.js',\n])\n\nconst skipEvaluatingTheseIncludes = new Set([\n  'nativeFunctionMatcher.js', // We don't preserve \"toString()\" on functions\n])\n\nconst skipEvaluatingTheseFeatures = new Set([\n  // Node's version of V8 doesn't implement these\n  'hashbang',\n  'legacy-regexp',\n  'regexp-duplicate-named-groups',\n  'symbols-as-weakmap-keys',\n  'tail-call-optimization',\n\n  // We don't care about API-related things\n  'ArrayBuffer',\n  'change-array-by-copy',\n  'DataView',\n  'resizable-arraybuffer',\n  'ShadowRealm',\n  'SharedArrayBuffer',\n  'String.prototype.toWellFormed',\n  'Symbol.match',\n  'Symbol.replace',\n  'Symbol.unscopables',\n  'Temporal',\n  'TypedArray',\n])\n\nconst skipEvaluatingTheseTests = new Set([\n  // This test is skipped because it crashes V8:\n  //\n  //   #\n  //   # Fatal error in , line 0\n  //   # Check failed: i < self->length().\n  //   #\n  //   #\n  //   #\n  //   #FailureMessage Object: 0x7fffac9a1c30\n  //    1: 0xc2abf1  [node]\n  //    2: 0x1f231d4 V8_Fatal(char const*, ...) [node]\n  //    3: 0xdac209 v8::FixedArray::Get(v8::Local<v8::Context>, int) const [node]\n  //    4: 0xb74ab7  [node]\n  //    5: 0xb76a2d  [node]\n  //    6: 0xf2436f v8::internal::Isolate::RunHostImportModuleDynamicallyCallback(v8::internal::MaybeHandle<v8::internal::Script>,\n  //                v8::internal::Handle<v8::internal::Object>, v8::internal::MaybeHandle<v8::internal::Object>) [node]\n  //    7: 0x137e3db v8::internal::Runtime_DynamicImportCall(int, unsigned long*, v8::internal::Isolate*) [node]\n  //    8: 0x17fd4f4  [node]\n  //\n  'language/expressions/dynamic-import/import-assertions/2nd-param-assert-enumeration.js',\n])\n\nfunction findFiles() {\n  function visit(dir) {\n    for (const entry of fs.readdirSync(dir)) {\n      const fullEntry = path.join(dir, entry)\n      const stats = fs.statSync(fullEntry)\n      if (stats.isDirectory()) {\n        visit(fullEntry)\n      } else if (stats.isFile() && entry.endsWith('.js') && !entry.includes('_FIXTURE')) {\n        files.push(fullEntry)\n      }\n    }\n  }\n\n  const files = []\n  for (const entry of fs.readdirSync(testDir)) {\n    if (entry === 'staging' || entry === 'intl402' || entry === 'built-ins') continue // We're not interested in these\n    visit(path.join(testDir, entry))\n  }\n\n  // Reverse for faster iteration times because many of the more interesting tests come last\n  return files.reverse()\n}\n\nasync function checkTransformAPI({ esbuild, file, content, yaml }) {\n  if (yaml.flags) {\n    if (yaml.flags.includes('onlyStrict')) content = '\"use strict\";' + content\n    if (yaml.flags.includes('module')) content += '\\nexport {}'\n  }\n\n  // Step 1: Try transforming the file normally\n  const shouldParse = !yaml.negative || yaml.negative.phase !== 'parse'\n  let result\n  try {\n    result = await esbuild.transform(content, { sourcefile: file })\n  } catch (error) {\n    if (shouldParse) {\n      error.kind = 'Transform'\n      throw error\n    }\n    return // Stop now if this test is supposed to fail\n  }\n  if (!shouldParse) {\n    const error = new Error('Unexpected successful transform')\n    error.kind = 'Transform'\n    throw error\n  }\n\n  // Step 2: Try transforming the output again (this should always succeed)\n  let result2\n  try {\n    result2 = await esbuild.transform(result.code, { sourcefile: file })\n  } catch (error) {\n    error.kind = 'Reparse'\n    throw error\n  }\n\n  // Step 3: The output should be the same the second time\n  if (result2.code !== result.code) {\n    const lines = result.code.split('\\n')\n    const lines2 = result2.code.split('\\n')\n    let i = 0\n    while (i < lines.length && i < lines2.length && lines[i] === lines2[i]) i++\n    const error = { toString: () => `${redColor}-${lines[i]}\\n${greenColor}+${lines2[i]}${resetColor}` }\n    error.kind = 'Reprint'\n    throw error\n  }\n\n  // Step 4: Try minifying the output once\n  let result4\n  try {\n    result4 = await esbuild.transform(result2.code, { sourcefile: file, minify: true })\n  } catch (error) {\n    error.kind = 'Minify'\n    throw error\n  }\n\n  // Step 5: Try minifying the output again\n  let result5\n  try {\n    result5 = await esbuild.transform(result4.code, { sourcefile: file, minify: true })\n  } catch (error) {\n    error.kind = 'Minify'\n    throw error\n  }\n}\n\nasync function checkBuildAPI({ esbuild, file, content, yaml }) {\n  const plugins = []\n  if (yaml.flags) {\n    const isOnlyStrict = yaml.flags.includes('onlyStrict')\n    const isModule = yaml.flags.includes('module')\n    if (isOnlyStrict || isModule) {\n      plugins.push({\n        name: 'modify',\n        setup(build) {\n          build.onLoad({ filter: /./ }, args => {\n            if (args.path === file) {\n              let loaded = content\n              if (isOnlyStrict) loaded = '\"use strict\";' + loaded\n              if (isModule) loaded += '\\nexport {}'\n              return { contents: loaded }\n            }\n          })\n        },\n      })\n    }\n  }\n\n  // Step 1: Try building the file normally\n  const isModule = yaml.flags && yaml.flags.includes('module')\n  const isDynamicImport = yaml.flags && yaml.flags.includes('dynamic-import')\n  const isAsync = yaml.flags && yaml.flags.includes('async')\n  const shouldParse = !yaml.negative || yaml.negative.phase === 'runtime'\n  let result\n  try {\n    const options = {\n      entryPoints: [file],\n      write: false,\n      keepNames: true,\n      logLevel: 'silent',\n      plugins,\n      target: 'node' + process.version.slice(1),\n      logOverride: { 'direct-eval': 'warning' },\n    }\n    if (isModule || isDynamicImport || isAsync) {\n      options.bundle = true\n      options.format = isModule ? 'esm' : 'iife'\n      options.external = [\n        '', // Some tests use this as a dummy argument to an \"import('')\" that is never evaluated\n      ]\n    }\n    result = await esbuild.build(options)\n  } catch (error) {\n    if (shouldParse) {\n      error.kind = 'Build'\n      throw error\n    }\n    return // Stop now if this test is supposed to fail\n  }\n  if (!shouldParse) {\n    const error = new Error('Unexpected successful build')\n    error.kind = 'Build'\n    throw error\n  }\n\n  // Don't evaluate problematic files\n  const hasDirectEval = result.warnings.some(msg => msg.id === 'direct-eval')\n  if (\n    hasDirectEval ||\n    skipEvaluatingTheseTests.has(path.relative(testDir, file)) ||\n    (yaml.includes && yaml.includes.some(include => skipEvaluatingTheseIncludes.has(include))) ||\n    (yaml.features && yaml.features.some(feature => skipEvaluatingTheseFeatures.has(feature)))\n  ) {\n    return\n  }\n\n  // Step 3: Try evaluating the file using node\n  const importDir = path.dirname(file)\n  const shouldEvaluate = !yaml.negative\n  try {\n    await runCodeInHarness(yaml, content, importDir)\n  } catch (error) {\n    // Ignore tests that fail when run in node\n    if (shouldEvaluate) console.log(eraseProgressBar() + dimColor + `IGNORING ${path.relative(testDir, file)}: ${error}` + resetColor)\n    return\n  }\n  if (!shouldEvaluate) {\n    // Ignore tests that incorrectly pass when run in node\n    return\n  }\n\n  // Step 3: Try evaluating the file we generated\n  const code = result.outputFiles[0].text\n  try {\n    await runCodeInHarness(yaml, code, importDir)\n  } catch (error) {\n    if (shouldEvaluate) {\n      if (typeof error === 'string') error = new Error(error)\n      error.kind = 'Evaluate'\n      throw error\n    }\n    return // Stop now if this test is supposed to fail\n  }\n  if (!shouldEvaluate) {\n    const error = new Error('Unexpected successful evaluation')\n    error.kind = 'Evaluate'\n    throw error\n  }\n\n  // Step 4: If evaluation worked and was supposed to work, check to see\n  // if it still works after running esbuild's syntax lowering pass on it\n  for (let version = 2015; version <= 2022; version++) {\n    let result\n    try {\n      result = await esbuild.transform(code, { sourcefile: file, target: `es${version}` })\n    } catch (error) {\n      continue // This means esbuild doesn't support lowering this code to this old a version\n    }\n    try {\n      await runCodeInHarness(yaml, code, importDir)\n    } catch (error) {\n      if (typeof error === 'string') error = new Error(error)\n      error.kind = 'Lower'\n      throw error\n    }\n    break\n  }\n}\n\nasync function main() {\n  const startTime = Date.now()\n\n  // Get this warning out of the way so it's not in the middle of our output.\n  // Note: If this constructor is missing, you need to run node with the\n  // \"--experimental-vm-modules\" flag (and use a version of node that has it).\n  {\n    const temp = new vm.SourceTextModule('')\n    await temp.link(() => { throw new Error })\n    await temp.evaluate()\n  }\n\n  console.log(`\\n${dimColor}Finding tests...${resetColor}`)\n  const files = findFiles()\n  console.log(`Found ${files.length} test files`)\n\n  console.log(`\\n${dimColor}Installing esbuild...${resetColor}`)\n  const esbuild = installForTests()\n\n  console.log(`\\n${dimColor}Running tests...${resetColor}\\n`)\n  const errorCounts = {}\n  let skippedCount = 0\n\n  await forEachInParallel(files, 32, async (file) => {\n    // Don't parse files that esbuild deliberately handles differently\n    if (skipTheseTests.has(path.relative(testDir, file))) {\n      skippedCount++\n      return\n    }\n\n    try {\n      const content = fs.readFileSync(file, 'utf8')\n      const start = content.indexOf('/*---')\n      const end = content.indexOf('---*/')\n      if (start < 0 || end < 0) throw new Error(`Missing YAML metadata`)\n      const yaml = jsYaml.safeLoad(content.slice(start + 5, end))\n\n      // Don't parse files that test things we don't care about\n      if (yaml.features && yaml.features.some(feature => skipTheseFeatures.has(feature))) {\n        skippedCount++\n        return\n      }\n\n      await checkTransformAPI({ esbuild, file, content, yaml })\n      await checkBuildAPI({ esbuild, file, content, yaml })\n    }\n\n    catch (error) {\n      errorCounts[error.kind] = (errorCounts[error.kind] || 0) + 1\n      printError(file, error)\n    }\n  })\n\n  const table = []\n  table.push(['Total tests', `${files.length}`])\n  table.push(['Tests ran', `${files.length - skippedCount}`])\n  table.push(['Tests skipped', `${skippedCount}`])\n  for (const kind of Object.keys(errorCounts).sort()) {\n    table.push([kind + ' errors', `${errorCounts[kind]}`])\n  }\n  const seconds = (Date.now() - startTime) / 1000\n  const minutes = Math.floor(seconds / 60)\n  table.push(['Time taken', `${minutes ? `${minutes} min ${+(seconds - minutes * 60).toFixed(1)} sec` : `${+seconds.toFixed(1)} sec`}`])\n  const maxLength = Math.max(...table.map(x => x[0].length))\n  printNewlineWhenErasing = true\n  process.stdout.write(eraseProgressBar())\n  for (const [key, value] of table) {\n    console.log(`${boldColor}${(key + ':').padEnd(maxLength + 1)}${resetColor} ${value}`)\n  }\n}\n\nfunction forEachInParallel(items, batchSize, callback) {\n  return new Promise((resolve, reject) => {\n    let inFlight = 0\n    let i = 0\n\n    function next() {\n      if (i === items.length && inFlight === 0) {\n        process.stdout.write(eraseProgressBar())\n        return resolve()\n      }\n\n      const completed = Math.floor(progressBarLength * i / items.length)\n      if (previousProgressBar !== completed) {\n        previousProgressBar = completed\n        const progressHead = '\\u2501'.repeat(Math.max(0, completed - 1))\n        const progressBoundary = completed ? '\\u252B' : ''\n        const progressTail = '\\u2500'.repeat(progressBarLength - completed)\n        process.stdout.write(`\\r` + greenColor + progressHead + progressBoundary + dimColor + progressTail + resetColor)\n      }\n\n      while (i < items.length && inFlight < batchSize) {\n        inFlight++\n        callback(items[i++]).then(() => {\n          inFlight--\n          next()\n        }, reject)\n      }\n    }\n\n    next()\n  })\n}\n\nconst harnessFiles = new Map\nlet defaultHarness = ''\n\nfor (const entry of fs.readdirSync(harnessDir)) {\n  if (entry.startsWith('.') || !entry.endsWith('.js')) {\n    continue\n  }\n  const file = path.join(harnessDir, entry)\n  const content = fs.readFileSync(file, 'utf8')\n  if (entry === 'assert.js' || entry === 'sta.js') {\n    defaultHarness += content\n    continue\n  }\n  harnessFiles.set(entry, content)\n}\n\nfunction createHarnessForTest(yaml) {\n  let harness = defaultHarness\n\n  if (yaml.includes) {\n    for (const include of yaml.includes) {\n      const content = harnessFiles.get(include)\n      if (!content) throw new Error(`Included file is missing: ${include}`)\n      harness += content\n    }\n  }\n\n  return harness\n}\n\nasync function runCodeInHarness(yaml, code, importDir) {\n  const context = {}\n  const isAsync = yaml.flags && yaml.flags.includes('async')\n  const isModule = yaml.flags && yaml.flags.includes('module')\n  const isRaw = yaml.flags && yaml.flags.includes('raw')\n\n  // See: https://github.com/nodejs/node/issues/36351\n  const unique = () => '//' + Math.random()\n\n  const runCode = async () => {\n    const moduleCache = new Map\n    const dynamicImportCache = new Map\n\n    const findModule = (modulePath) => {\n      let module = moduleCache.get(modulePath)\n      if (!module) {\n        const code = fs.readFileSync(modulePath, 'utf8')\n        if (modulePath.endsWith('json')) {\n          const evaluate = function () {\n            this.setExport('default', vm.runInContext('JSON.parse', context)(code))\n          }\n          module = new vm.SyntheticModule(['default'], evaluate, { context })\n        } else {\n          module = new vm.SourceTextModule(code + unique(), { context, importModuleDynamically })\n        }\n        moduleCache.set(modulePath, module)\n      }\n      return module\n    }\n\n    const linker = (specifier, referencingModule) => {\n      return findModule(path.join(importDir, specifier))\n    }\n\n    const importModuleDynamically = (specifier, script) => {\n      const where = path.join(importDir, specifier)\n      let promise = dynamicImportCache.get(where)\n      if (!promise) {\n        const module = findModule(where, context)\n        if (module.status === 'unlinked') {\n          promise = module.link(linker)\n            .then(() => module.evaluate())\n            .then(() => module)\n        } else {\n          promise = Promise.resolve(module)\n        }\n        dynamicImportCache.set(where, promise)\n      }\n      return promise\n    }\n\n    vm.createContext(context)\n    if (!isRaw) vm.runInContext(createHarnessForTest(yaml), context)\n\n    if (isModule) {\n      const module = new vm.SourceTextModule(code + unique(), { context, importModuleDynamically })\n      await module.link(linker)\n      await module.evaluate()\n    } else {\n      const script = new vm.Script(code, { importModuleDynamically })\n      script.runInContext(context)\n    }\n  }\n\n  if (isAsync) {\n    await new Promise((resolve, reject) => {\n      context.$DONE = err => err ? reject(err) : resolve()\n      runCode(code, context).catch(reject)\n    })\n  } else {\n    await runCode(code, context)\n  }\n}\n\nfunction printError(file, error) {\n  let detail\n\n  if (error.errors) {\n    const { text, location } = error.errors[0]\n    if (location) {\n      const { file, line, column, lineText, length } = location\n      detail = '  ' + dimColor + path.basename(file) + ':' + line + ':' + column + ': ' + resetColor + text + '\\n' +\n        '  ' + dimColor + lineText.slice(0, column) + greenColor + lineText.slice(column, column + length) + dimColor + lineText.slice(column + length) + resetColor + '\\n' +\n        '  ' + greenColor + ' '.repeat(column) + (length > 1 ? '~'.repeat(length) : '^') + resetColor\n    } else {\n      detail = dimColor + ('\\n' + text).split('\\n').join('\\n  ').slice(1) + resetColor\n    }\n  } else {\n    detail = dimColor + ('\\n' + error).split('\\n').join('\\n  ').slice(1) + resetColor\n  }\n\n  const prettyPath = path.relative(testDir, file)\n  printNewlineWhenErasing = true\n  console.log(eraseProgressBar() + tagMap[error.kind] + ' ' + prettyPath + '\\n' + detail)\n  printNewlineWhenErasing = true\n}\n\nconst tagMap = {\n  Transform: redBgRedColor + `[` + redBgWhiteColor + `TRANSFORM ERROR` + redBgRedColor + `]` + resetColor,\n  Build: magentaBgMagentaColor + `[` + magentaBgBlackColor + `BUILD ERROR` + magentaBgMagentaColor + `]` + resetColor,\n  Reparse: yellowBgYellowColor + `[` + yellowBgBlackColor + `REPARSE ERROR` + yellowBgYellowColor + `]` + resetColor,\n  Reprint: cyanBgCyanColor + `[` + cyanBgBlackColor + `REPRINT ERROR` + cyanBgCyanColor + `]` + resetColor,\n  Minify: blueBgBlueColor + `[` + blueBgWhiteColor + `MINIFY ERROR` + blueBgBlueColor + `]` + resetColor,\n  Evaluate: greenBgGreenColor + `[` + greenBgWhiteColor + `EVALUATE ERROR` + greenBgGreenColor + `]` + resetColor,\n  Lower: whiteBgWhiteColor + `[` + whiteBgBlackColor + `LOWER ERROR` + whiteBgWhiteColor + `]` + resetColor,\n}\n\nprocess.on('unhandledRejection', () => {\n  // Don't exit when a test does this\n})\n\nmain().catch(e => setTimeout(() => {\n  throw e\n}))\n"
  },
  {
    "path": "scripts/try.html",
    "content": "<!-- This is a simple playground to try out esbuild in your browser -->\n<!DOCTYPE html>\n<html>\n\n<head>\n  <meta charset=\"utf8\">\n  <title>Try esbuild live</title>\n  <style>\n    body {\n      font: 15px/120% sans-serif;\n      overflow: hidden;\n    }\n\n    h2,\n    p {\n      cursor: default;\n      user-select: none;\n    }\n\n    textarea {\n      resize: none;\n      width: 100%;\n      height: 100%;\n    }\n\n    textarea,\n    #output .outer {\n      box-sizing: border-box;\n      padding: 4px;\n      color: inherit;\n      font-size: 13px;\n      line-height: 110%;\n      font-family: monospace;\n      cursor: text;\n      tab-size: 2;\n    }\n\n    #output .outer {\n      white-space: pre-wrap;\n      overflow-y: auto;\n    }\n\n    .minified {\n      word-break: break-all;\n    }\n\n    textarea:focus {\n      outline: none;\n      border: 1px solid #999;\n    }\n\n    hr {\n      border: 1px solid #999;\n      margin: 1em 0;\n    }\n\n    section {\n      position: absolute;\n      top: 0;\n      bottom: 0;\n      padding: 0 20px;\n      box-sizing: border-box;\n    }\n\n    section p {\n      line-height: 26px;\n    }\n\n    #input {\n      left: 0;\n      width: 50%;\n    }\n\n    #output {\n      right: 0;\n      width: 50%;\n    }\n\n    .outer {\n      position: absolute;\n      left: 20px;\n      top: 120px;\n      right: 20px;\n      bottom: 20px;\n    }\n\n    #input .outer {\n      right: 10px;\n    }\n\n    #output .outer {\n      left: 10px;\n    }\n\n    label {\n      white-space: nowrap;\n    }\n\n    body {\n      background: #EEE;\n      color: #333;\n    }\n\n    textarea,\n    #output .outer {\n      background: #FFF;\n      border: 1px solid #CCC;\n    }\n\n    .terminal-1 {\n      font-weight: bold;\n    }\n\n    .terminal-37 {\n      color: #999;\n    }\n\n    .terminal-4 {\n      text-decoration: underline;\n    }\n\n    .terminal-31 {\n      color: #D00;\n    }\n\n    .terminal-32 {\n      color: #0D0;\n    }\n\n    .terminal-33 {\n      color: #CC0;\n    }\n\n    .terminal-35 {\n      color: #D0D;\n    }\n\n    @media (prefers-color-scheme: dark) {\n      body {\n        background: #333;\n        color: #DDD;\n      }\n\n      textarea,\n      #output .outer {\n        background: #111;\n        border: 1px solid #555;\n      }\n\n      .terminal-37 {\n        color: #777;\n      }\n    }\n\n  </style>\n</head>\n\n<body>\n  <section id=\"input\">\n    <h2>Input</h2>\n    <p>\n      <label for=\"target\">\n        Target: <select id=\"target\">\n          <option>ES5</option>\n          <option>ES2015</option>\n          <option>ES2016</option>\n          <option>ES2017</option>\n          <option>ES2018</option>\n          <option>ES2019</option>\n          <option>ES2020</option>\n          <option>ES2021</option>\n          <option selected>ESNext</option>\n\n          <option>Chrome70</option>\n          <option>Chrome71</option>\n          <option>Chrome72</option>\n          <option>Chrome73</option>\n          <option>Chrome74</option>\n          <option>Chrome75</option>\n          <option>Chrome76</option>\n          <option>Chrome77</option>\n          <option>Chrome78</option>\n          <option>Chrome79</option>\n\n          <option>Chrome80</option>\n          <option>Chrome81</option>\n          <option>Chrome82</option>\n          <option>Chrome83</option>\n          <option>Chrome84</option>\n          <option>Chrome85</option>\n          <option>Chrome86</option>\n          <option>Chrome87</option>\n          <option>Chrome88</option>\n          <option>Chrome89</option>\n        </select>\n      </label>\n      &nbsp; &nbsp;\n      <label for=\"loader\">\n        Loader: <select id=\"loader\">\n          <option selected>JS</option>\n          <option>JSX</option>\n          <option>TS</option>\n          <option>TSX</option>\n          <option>CSS</option>\n          <option>JSON</option>\n          <option>Text</option>\n          <option>Base64</option>\n          <option>DataURL</option>\n          <option>Binary</option>\n        </select>\n      </label>\n      &nbsp; &nbsp;\n      <label for=\"format\">\n        Format: <select id=\"format\">\n          <option selected>Preserve</option>\n          <option>IIFE</option>\n          <option>CJS</option>\n          <option>ESM</option>\n        </select>\n      </label>\n      <br>\n      <label for=\"bundle\">\n        <input id=\"bundle\" type=\"checkbox\">\n        Bundle\n      </label>\n      &nbsp; &nbsp;\n      <label for=\"ascii\">\n        <input id=\"ascii\" type=\"checkbox\">\n        ASCII\n      </label>\n      &nbsp; &nbsp;\n      <label for=\"keepNames\">\n        <input id=\"keepNames\" type=\"checkbox\">\n        Keep Names\n      </label>\n      &nbsp; &nbsp;\n      <label for=\"mangleProps\">\n        <input id=\"mangleProps\" type=\"checkbox\">\n        Mangle Props\n      </label>\n      &nbsp; &nbsp;\n      Minify:\n      <label for=\"minify-syntax\"><input id=\"minify-syntax\" type=\"checkbox\"> Syntax</label>\n      <label for=\"minify-idents\"><input id=\"minify-idents\" type=\"checkbox\"> Identifiers</label>\n      <label for=\"minify-spaces\"><input id=\"minify-spaces\" type=\"checkbox\"> Whitespace</label>\n    </p>\n    <div class=\"outer\"><textarea autofocus spellcheck=\"false\"></textarea></div>\n  </section>\n  <section id=\"output\">\n    <h2>Output</h2>\n    <div class=\"outer\"></div>\n  </section>\n  <script src=\"../npm/esbuild-wasm/lib/browser.js\"></script>\n  <script>\n    const input = document.querySelector('#input textarea')\n    const target = document.querySelector('#target')\n    const loader = document.querySelector('#loader')\n    const format = document.querySelector('#format')\n    const minifySyntax = document.querySelector('#minify-syntax')\n    const minifyIdents = document.querySelector('#minify-idents')\n    const minifySpaces = document.querySelector('#minify-spaces')\n    const ascii = document.querySelector('#ascii')\n    const bundle = document.querySelector('#bundle')\n    const keepNames = document.querySelector('#keepNames')\n    const mangleProps = document.querySelector('#mangleProps')\n    let runIfIdle\n\n    function persistValue(el, key) {\n      el.onchange = () => {\n        runIfIdle()\n        try {\n          sessionStorage.setItem(key, el.value)\n        } catch (e) {\n        }\n      }\n      try {\n        const old = sessionStorage.getItem(key)\n        if (old !== null) el.value = old\n      } catch (e) {\n      }\n    }\n\n    function persistChecked(el, key) {\n      el.onchange = () => {\n        runIfIdle()\n        try {\n          sessionStorage.setItem(key, el.checked)\n        } catch (e) {\n        }\n      }\n      try {\n        const old = sessionStorage.getItem(key)\n        if (old !== null) el.checked = old === 'true'\n      } catch (e) {\n      }\n    }\n\n    persistValue(target, 'target')\n    persistValue(loader, 'loader')\n    persistValue(format, 'format')\n    persistChecked(minifySyntax, 'minifySyntax')\n    persistChecked(minifyIdents, 'minifyIdents')\n    persistChecked(minifySpaces, 'minifySpaces')\n    persistChecked(ascii, 'ascii')\n    persistChecked(bundle, 'bundle')\n    persistChecked(keepNames, 'keepNames')\n    persistChecked(mangleProps, 'mangleProps')\n\n    try {\n      const old = sessionStorage.getItem('input')\n      if (old !== null) input.value = old\n    } catch (e) {\n    }\n\n    esbuild.initialize({\n      wasmURL: '../npm/esbuild-wasm/esbuild.wasm',\n    }).then(() => {\n      const output = document.querySelector('#output .outer')\n      let debounceTimeout = 0\n      let isRunning = false\n      let needsRun = false\n\n      input.oninput = () => {\n        clearTimeout(debounceTimeout)\n        debounceTimeout = setTimeout(runIfIdle, 50)\n      }\n\n      runIfIdle = async () => {\n        clearTimeout(debounceTimeout)\n\n        if (isRunning) {\n          needsRun = true\n          return\n        }\n\n        isRunning = true\n        needsRun = false\n\n        const inputValue = input.value\n        var code, warnings, errors\n        try {\n          if (bundle.checked) {\n            const results = await esbuild.build({\n              stdin: {\n                contents: inputValue,\n                loader: loader.value.toLowerCase(),\n              },\n              bundle: true,\n              target: target.value.toLowerCase(),\n              format: format.value === 'Preserve' ? void 0 : format.value.toLowerCase(),\n              minifySyntax: minifySyntax.checked,\n              minifyIdentifiers: minifyIdents.checked,\n              minifyWhitespace: minifySpaces.checked,\n              charset: ascii.checked ? 'ascii' : 'utf8',\n              keepNames: keepNames.checked,\n              mangleProps: mangleProps.checked ? /_$/ : void 0,\n              plugins: [{\n                name: 'external-all',\n                setup(build) {\n                  build.onResolve({ filter: /.*/ }, args => {\n                    return { path: args.path, external: true }\n                  })\n                },\n              }],\n            })\n            code = results.outputFiles[0].text\n            warnings = results.warnings\n          } else {\n            ({ code, warnings } = await esbuild.transform(inputValue, {\n              target: target.value.toLowerCase(),\n              loader: loader.value.toLowerCase(),\n              format: format.value === 'Preserve' ? void 0 : format.value.toLowerCase(),\n              minifySyntax: minifySyntax.checked,\n              minifyIdentifiers: minifyIdents.checked,\n              minifyWhitespace: minifySpaces.checked,\n              charset: ascii.checked ? 'ascii' : 'utf8',\n              keepNames: keepNames.checked,\n              mangleProps: mangleProps.checked ? /_$/ : void 0,\n            }))\n          }\n        } catch (error) {\n          ({ errors, warnings } = error)\n          if (!errors) {\n            output.textContent = (error && error.message) || (error + '')\n            isRunning = false\n            if (needsRun) runIfIdle()\n            return\n          }\n        }\n        if (warnings) warnings = await esbuild.formatMessages(warnings, { kind: 'warning', color: true })\n        if (errors) errors = await esbuild.formatMessages(errors, { kind: 'error', color: true })\n        const html = (errors || []).concat(warnings || []).map(messageToHTML).join('')\n        if (code) code = textToHTML(code)\n        if (code && minifySpaces.checked) code = `<span class=\"minified\">${code}</span>`\n        output.innerHTML = (html && html + '<hr>' || '') + (code || '')\n\n        try {\n          sessionStorage.setItem('input', inputValue)\n        } catch (e) {\n        }\n\n        isRunning = false\n        if (needsRun) runIfIdle()\n      }\n\n      function textToHTML(text) {\n        return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n      }\n\n      function messageToHTML(text) {\n        let reset = ''\n        text = textToHTML(text)\n        text = text.replace(/\\033\\[([^m]+)m/g, (_, value) => {\n          if (value === '0') {\n            value = reset\n            reset = ''\n          } else {\n            reset += '</span>'\n            value = `<span class=\"terminal-${value}\">`\n          }\n          return value\n        })\n        text += reset\n        return text\n      }\n\n      runIfIdle()\n    })\n  </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "scripts/ts-type-tests.js",
    "content": "const { removeRecursiveSync } = require('./esbuild')\nconst child_process = require('child_process')\nconst path = require('path')\nconst fs = require('fs')\n\nconst tsconfigJson = {\n  compilerOptions: {\n    module: 'CommonJS',\n    strict: true,\n  },\n}\n\nconst testsWithoutErrors = {\n  emptyBuildRequire: `\n    export {}\n    import esbuild = require('esbuild')\n    esbuild.buildSync({})\n    esbuild.build({})\n  `,\n  emptyBuildImport: `\n    import * as esbuild from 'esbuild'\n    esbuild.buildSync({})\n    esbuild.build({})\n  `,\n  emptyTransformRequire: `\n    export {}\n    import esbuild = require('esbuild')\n    esbuild.transformSync('')\n    esbuild.transformSync('', {})\n    esbuild.transform('')\n    esbuild.transform('', {})\n  `,\n  emptyTransformImport: `\n    import * as esbuild from 'esbuild'\n    esbuild.transformSync('')\n    esbuild.transformSync('', {})\n    esbuild.transform('')\n    esbuild.transform('', {})\n  `,\n\n  mangleCache: `\n    import * as esbuild from 'esbuild'\n    esbuild.buildSync({ mangleCache: {} }).mangleCache['x']\n    esbuild.build({ mangleCache: {} })\n      .then(result => result.mangleCache['x'])\n    esbuild.transformSync('', { mangleCache: {} }).mangleCache['x']\n    esbuild.transform('', { mangleCache: {} })\n      .then(result => result.mangleCache['x'])\n  `,\n  legalCommentsExternal: `\n    import * as esbuild from 'esbuild'\n    esbuild.transformSync('', { legalComments: 'external' }).legalComments.length\n    esbuild.transform('', { legalComments: 'external' })\n      .then(result => result.legalComments.length)\n  `,\n  writeFalseOutputFiles: `\n    import * as esbuild from 'esbuild'\n    esbuild.buildSync({ write: false }).outputFiles[0]\n    esbuild.build({ write: false })\n      .then(result => result.outputFiles[0])\n  `,\n  metafileTrue: `\n    import {build, buildSync, analyzeMetafile} from 'esbuild';\n    analyzeMetafile(buildSync({ metafile: true }).metafile)\n    build({ metafile: true })\n      .then(result => analyzeMetafile(result.metafile))\n  `,\n\n  contextMangleCache: `\n    import * as esbuild from 'esbuild'\n    esbuild.context({ mangleCache: {} })\n      .then(context => context.rebuild())\n      .then(result => result.mangleCache['x'])\n  `,\n  contextWriteFalseOutputFiles: `\n    import * as esbuild from 'esbuild'\n    esbuild.context({ write: false })\n      .then(context => context.rebuild())\n      .then(result => result.outputFiles[0])\n  `,\n  contextMetafileTrue: `\n    import {context, analyzeMetafile} from 'esbuild';\n    context({ metafile: true })\n      .then(context => context.rebuild())\n      .then(result => analyzeMetafile(result.metafile))\n  `,\n\n  allOptionsTransform: `\n    export {}\n    import {transform} from 'esbuild'\n    transform('', {\n      sourcemap: true,\n      format: 'iife',\n      globalName: '',\n      target: 'esnext',\n      minify: true,\n      minifyWhitespace: true,\n      minifyIdentifiers: true,\n      minifySyntax: true,\n      charset: 'utf8',\n      jsxFactory: '',\n      jsxFragment: '',\n      define: { 'x': 'y' },\n      pure: ['x'],\n      color: true,\n      logLevel: 'info',\n      logLimit: 0,\n      tsconfigRaw: {\n        compilerOptions: {\n          jsxFactory: '',\n          jsxFragmentFactory: '',\n          useDefineForClassFields: true,\n          importsNotUsedAsValues: 'preserve',\n          preserveValueImports: true,\n        },\n      },\n      sourcefile: '',\n      loader: 'ts',\n    }).then(result => {\n      let code: string = result.code;\n      let map: string = result.map;\n      for (let msg of result.warnings) {\n        let text: string = msg.text\n        if (msg.location !== null) {\n          let file: string = msg.location.file;\n          let namespace: string = msg.location.namespace;\n          let line: number = msg.location.line;\n          let column: number = msg.location.column;\n          let length: number = msg.location.length;\n          let lineText: string = msg.location.lineText;\n        }\n      }\n    })\n  `,\n  allOptionsBuild: `\n    export {}\n    import {build} from 'esbuild'\n    build({\n      sourcemap: true,\n      format: 'iife',\n      globalName: '',\n      target: 'esnext',\n      minify: true,\n      minifyWhitespace: true,\n      minifyIdentifiers: true,\n      minifySyntax: true,\n      charset: 'utf8',\n      jsxFactory: '',\n      jsxFragment: '',\n      define: { 'x': 'y' },\n      pure: ['x'],\n      color: true,\n      logLevel: 'info',\n      logLimit: 0,\n      bundle: true,\n      splitting: true,\n      outfile: '',\n      metafile: true,\n      outdir: '',\n      outbase: '',\n      platform: 'node',\n      external: ['x'],\n      loader: { 'x': 'ts' },\n      resolveExtensions: ['x'],\n      mainFields: ['x'],\n      write: true,\n      tsconfig: 'x',\n      outExtension: { 'x': 'y' },\n      publicPath: 'x',\n      inject: ['x'],\n      entryPoints: ['x'],\n      stdin: {\n        contents: '',\n        resolveDir: '',\n        sourcefile: '',\n        loader: 'ts',\n      },\n      plugins: [\n        {\n          name: 'x',\n          setup(build) {\n            build.onStart(() => {})\n            build.onStart(async () => {})\n            build.onStart(() => ({ warnings: [{text: '', location: {file: '', line: 0}}] }))\n            build.onStart(async () => ({ warnings: [{text: '', location: {file: '', line: 0}}] }))\n            build.onEnd(result => {})\n            build.onEnd(async result => {})\n            build.onLoad({filter: /./}, () => undefined)\n            build.onResolve({filter: /./, namespace: ''}, args => {\n              let path: string = args.path;\n              let importer: string = args.importer;\n              let namespace: string = args.namespace;\n              let resolveDir: string = args.resolveDir;\n              if (Math.random()) return\n              if (Math.random()) return {}\n              return {\n                pluginName: '',\n                errors: [\n                  {},\n                  {text: ''},\n                  {text: '', location: {}},\n                  {location: {file: '', line: 0}},\n                  {location: {file: '', namespace: '', line: 0, column: 0, length: 0, lineText: ''}},\n                ],\n                warnings: [\n                  {},\n                  {text: ''},\n                  {text: '', location: {}},\n                  {location: {file: '', line: 0}},\n                  {location: {file: '', namespace: '', line: 0, column: 0, length: 0, lineText: ''}},\n                ],\n                path: '',\n                external: true,\n                namespace: '',\n                suffix: '',\n              }\n            })\n            build.onLoad({filter: /./, namespace: ''}, args => {\n              let path: string = args.path;\n              let namespace: string = args.namespace;\n              let suffix: string = args.suffix;\n              if (Math.random()) return\n              if (Math.random()) return {}\n              return {\n                pluginName: '',\n                errors: [\n                  {},\n                  {text: ''},\n                  {text: '', location: {}},\n                  {location: {file: '', line: 0}},\n                  {location: {file: '', namespace: '', line: 0, column: 0, length: 0, lineText: ''}},\n                ],\n                warnings: [\n                  {},\n                  {text: ''},\n                  {text: '', location: {}},\n                  {location: {file: '', line: 0}},\n                  {location: {file: '', namespace: '', line: 0, column: 0, length: 0, lineText: ''}},\n                ],\n                contents: '',\n                resolveDir: '',\n                loader: 'ts',\n              }\n            })\n          },\n        }\n      ],\n    }).then(result => {\n      if (result.outputFiles !== undefined) {\n        for (let file of result.outputFiles) {\n          let path: string = file.path\n          let bytes: Uint8Array = file.contents\n        }\n      }\n      for (let msg of result.warnings) {\n        let text: string = msg.text\n        if (msg.location !== null) {\n          let file: string = msg.location.file;\n          let namespace: string = msg.location.namespace;\n          let line: number = msg.location.line;\n          let column: number = msg.location.column;\n          let length: number = msg.location.length;\n          let lineText: string = msg.location.lineText;\n        }\n      }\n    })\n  `,\n  objectEntryPointBuild: `\n    export {}\n    import {build} from 'esbuild'\n    build({\n      entryPoints: { x: 'x', y: 'z' },\n    })\n  `,\n  mixedEntryPointBuild: `\n    export {}\n    import {build} from 'esbuild'\n    build({\n      entryPoints: ['x', { in: 'y', out: 'z' }],\n    })\n  `,\n}\n\nconst testsWithErrors = {\n  badBuildRequire_invalidOption: `\n    export {}\n    import esbuild = require('esbuild')\n    esbuild.build({ invalidOption: true })\n  `,\n  badBuildSyncRequire_invalidOption: `\n    export {}\n    import esbuild = require('esbuild')\n    esbuild.buildSync({ invalidOption: true })\n  `,\n  badBuildImport_invalidOption: `\n    import * as esbuild from 'esbuild'\n    esbuild.build({ invalidOption: true })\n  `,\n  badBuildSyncImport_invalidOption: `\n    import * as esbuild from 'esbuild'\n    esbuild.build({ invalidOption: true })\n  `,\n  badTransformRequire_invalidOption: `\n    export {}\n    import esbuild = require('esbuild')\n    esbuild.transform('', { invalidOption: true })\n  `,\n  badTransformSyncRequire_invalidOption: `\n    export {}\n    import esbuild = require('esbuild')\n    esbuild.transformSync('', { invalidOption: true })\n  `,\n  badTransformImport_invalidOption: `\n    import * as esbuild from 'esbuild'\n    esbuild.transform('', { invalidOption: true })\n  `,\n  badTransformSyncImport_invalidOption: `\n    import * as esbuild from 'esbuild'\n    esbuild.transformSync('', { invalidOption: true })\n  `,\n\n  // mangleCache\n  mangleCacheBuild_undefined: `\n    import * as esbuild from 'esbuild'\n    esbuild.build({}).then(result => result.mangleCache['x'])\n  `,\n  mangleCacheBuildSync_undefined: `\n    import * as esbuild from 'esbuild'\n    esbuild.buildSync({}).mangleCache['x']\n  `,\n  mangleCacheTransform_undefined: `\n    import * as esbuild from 'esbuild'\n    esbuild.transform('', {}).then(result => result.mangleCache['x'])\n  `,\n  mangleCacheTransformSync_undefined: `\n    import * as esbuild from 'esbuild'\n    esbuild.transformSync('', {}).mangleCache['x']\n  `,\n\n  // legalComments\n  legalCommentsTransform_undefined: `\n    import * as esbuild from 'esbuild'\n    esbuild.transform('', { legalComments: 'eof' }).then(result => result.legalComments.length)\n  `,\n  legalCommentsTransformSync_undefined: `\n    import * as esbuild from 'esbuild'\n    esbuild.transformSync('', { legalComments: 'eof' }).legalComments.length\n  `,\n\n  // outputFiles\n  outputFilesBuild_undefined: `\n    import * as esbuild from 'esbuild'\n    esbuild.build({}).then(result => result.outputFiles[0])\n  `,\n  outputFilesBuildSync_undefined: `\n    import * as esbuild from 'esbuild'\n    esbuild.buildSync({}).outputFiles[0]\n  `,\n  outputFilesWriteTrueBuild_undefined: `\n    import * as esbuild from 'esbuild'\n    esbuild.build({ write: true }).then(result => result.outputFiles[0])\n  `,\n  outputFilesWriteTrueBuildSync_undefined: `\n    import * as esbuild from 'esbuild'\n    esbuild.buildSync({ write: true }).outputFiles[0]\n  `,\n\n  // metafile\n  metafileBuild_undefined: `\n    import * as esbuild from 'esbuild'\n    esbuild.build({}).then(result => esbuild.analyzeMetafile(result.metafile))\n  `,\n  metafileBuildSync_undefined: `\n    import * as esbuild from 'esbuild'\n    esbuild.analyzeMetafile(esbuild.buildSync({}).metafile)\n  `,\n  metafileFalseBuild_undefined: `\n    import * as esbuild from 'esbuild'\n    esbuild.build({ metafile: false }).then(result => esbuild.analyzeMetafile(result.metafile))\n  `,\n  metafileFalseBuildSync_undefined: `\n    import * as esbuild from 'esbuild'\n    esbuild.analyzeMetafile(esbuild.buildSync({ metafile: false }).metafile)\n  `,\n}\n\nasync function main() {\n  let testDir = path.join(__dirname, '.ts-types-test')\n  removeRecursiveSync(testDir)\n  fs.mkdirSync(testDir, { recursive: true })\n\n  const types = fs.readFileSync(path.join(__dirname, '..', 'lib', 'shared', 'types.ts'), 'utf8')\n  const tsc = path.join(__dirname, 'node_modules', 'typescript', 'lib', 'tsc.js')\n  const esbuild_d_ts = path.join(testDir, 'node_modules', 'esbuild', 'index.d.ts')\n  fs.mkdirSync(path.dirname(esbuild_d_ts), { recursive: true })\n  fs.writeFileSync(esbuild_d_ts, types)\n  let allTestsPassed = true\n\n  // Check tests without errors\n  if (allTestsPassed) {\n    const dir = path.join(testDir, 'without-errors')\n    fs.mkdirSync(dir, { recursive: true })\n    fs.writeFileSync(path.join(dir, 'tsconfig.json'), JSON.stringify(tsconfigJson))\n    for (const name in testsWithoutErrors) {\n      const input = path.join(dir, name + '.ts')\n      fs.writeFileSync(input, testsWithoutErrors[name])\n    }\n    allTestsPassed &&= await new Promise(resolve => {\n      const child = child_process.spawn('node', [tsc, '--project', '.'], { cwd: dir, stdio: 'inherit' })\n      child.on('close', exitCode => resolve(exitCode === 0))\n    })\n  }\n\n  // Check tests with errors\n  if (allTestsPassed) {\n    const dir = path.join(testDir, 'with-errors')\n    fs.mkdirSync(dir, { recursive: true })\n    fs.writeFileSync(path.join(dir, 'tsconfig.json'), JSON.stringify(tsconfigJson))\n    for (const name in testsWithErrors) {\n      const input = path.join(dir, name.split('_')[0] + '.ts')\n      fs.writeFileSync(input, testsWithErrors[name])\n    }\n    try {\n      child_process.execFileSync('node', [tsc, '--project', '.'], { cwd: dir })\n      throw new Error('Expected an error to be generated')\n    } catch (err) {\n      const stdout = err.stdout.toString()\n      const lines = stdout.split('\\n')\n      next: for (const name in testsWithErrors) {\n        const fileName = name.split('_')[0]\n        const expectedText = name.split('_')[1]\n        for (const line of lines) {\n          if (line.includes(fileName)) {\n            if (line.includes(expectedText)) {\n              console.log(`\\x1B[32mSUCCESS:\\x1B[0m ${line}`)\n            } else {\n              console.log(`\\x1B[31mFAILURE: ${line}\\x1B[0m`)\n              allTestsPassed = false\n            }\n            continue next\n          }\n        }\n        console.log(`\\x1B[31mFAILURE:\\x1B[0m ${name}: Could not find expected error in output from \"tsc\":`)\n        process.stdout.write(stdout)\n        allTestsPassed = false\n        break next\n      }\n    }\n  }\n\n  if (!allTestsPassed) {\n    console.error(`❌ typescript type tests failed`)\n    process.exit(1)\n  } else {\n    console.log(`✅ typescript type tests passed`)\n    removeRecursiveSync(testDir)\n  }\n}\n\nmain().catch(e => {\n  setTimeout(() => {\n    throw e\n  })\n})\n"
  },
  {
    "path": "scripts/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ESNext\", // Fix \"Symbol.metadata\" errors in decorator tests\n  }\n}\n"
  },
  {
    "path": "scripts/uglify-tests.js",
    "content": "const { installForTests } = require('./esbuild');\nconst childProcess = require('child_process');\nconst assert = require('assert');\nconst path = require('path');\nconst fs = require('fs');\n\nconst repoDir = path.dirname(__dirname);\nconst testDir = path.join(repoDir, 'scripts', '.uglify-tests');\nconst uglifyDir = path.join(repoDir, 'demo', 'uglify');\nconst SKIP = {};\nlet U;\n\nmain().catch(e => setTimeout(() => { throw e }));\n\nasync function main() {\n  // // Terser's stdout comparisons fail if this is true since stdout contains\n  // // terminal color escape codes\n  // process.stdout.isTTY = false;\n\n  // Make sure the tests are installed\n  childProcess.execSync('make demo/uglify', { cwd: repoDir, stdio: 'pipe' });\n  U = require(path.join(uglifyDir, 'test', 'node'));\n\n  // Create a fresh test directory\n  childProcess.execSync(`rm -fr \"${testDir}\"`);\n  fs.mkdirSync(testDir)\n\n  // Start the esbuild service\n  const esbuild = installForTests();\n\n  // Find test files\n  const compressDir = path.join(uglifyDir, 'test', 'compress');\n  const files = fs.readdirSync(compressDir).filter(name => name.endsWith('.js'));\n\n  // Run all tests concurrently\n  let passedTotal = 0;\n  let failedTotal = 0;\n  let skippedTotal = 0;\n  const runTest = file => test_file(esbuild, path.join(compressDir, file))\n    .then(({ passed, failed, skipped }) => {\n      passedTotal += passed;\n      failedTotal += failed;\n      skippedTotal += skipped;\n    });\n  await Promise.all(files.map(runTest));\n\n  // Clean up test output\n  childProcess.execSync(`rm -fr \"${testDir}\"`);\n\n  console.log(`${failedTotal} failed out of ${passedTotal + failedTotal}, with ${skippedTotal} skipped`);\n  if (failedTotal) {\n    process.exit(1);\n  }\n}\n\nasync function test_file(esbuild, file) {\n  let passed = 0;\n  let failed = 0;\n  let skipped = 0;\n  const tests = parse_test(file);\n  const runTest = name => test_case(esbuild, tests[name], path.basename(file))\n    .then(x => {\n      if (x === SKIP) {\n        skipped++;\n      } else {\n        passed++;\n      }\n    })\n    .catch(e => {\n      failed++;\n      console.error(`❌ ${file}: ${name}: ${(e && e.message || e).trim()}\\n`);\n      pass = false;\n    });\n  await Promise.all(Object.keys(tests).map(runTest));\n  return { passed, failed, skipped };\n}\n\n// Modified from \"uglify/demo/test/compress.js\"\nasync function test_case(esbuild, test, basename) {\n  const sandbox = require(path.join(uglifyDir, 'test', 'sandbox'));\n  const log = (format, args) => { throw new Error(tmpl(format, args)); };\n\n  var semver = require(path.join(uglifyDir, 'node_modules', 'semver'));\n\n  // Generate the input code\n  var input = to_toplevel(test.input, test.mangle);\n  var input_code = make_code(input);\n  var input_formatted = make_code(test.input, {\n    beautify: true,\n    comments: \"all\",\n    keep_quoted_props: true,\n    quote_style: 3,\n  });\n\n  // Make sure it's valid\n  try {\n    U.parse(input_code);\n  } catch (ex) {\n    log([\n      \"!!! Cannot parse input\",\n      \"---INPUT---\",\n      \"{input}\",\n      \"--PARSE ERROR--\",\n      \"{error}\",\n      \"\",\n      \"\",\n    ].join(\"\\n\"), {\n      input: input_formatted,\n      error: ex,\n    });\n  }\n\n  // Ignore tests that no longer pass in modern versions of node. These tests\n  // contain code that is now considered a syntax error. The relevant code is\n  // this:\n  //\n  //   try{throw 42}catch(a){console.log(a);function a(){}}\n  //\n  if (test.node_version && !semver.satisfies(process.version, test.node_version)) {\n    console.error(\"*** skipping test %j with node_version %j\", test.name, test.node_version);\n    return SKIP;\n  }\n\n  // Run esbuild as a minifier\n  try {\n    var { code: output } = await esbuild.transform(input_code, {\n      minify: true,\n      target: 'esnext',\n    });\n  } catch (e) {\n    // These tests fail because they contain syntax errors. These test failures\n    // do not indicate anything wrong with esbuild so the failures are ignored.\n    // Here is one of the tests:\n    //\n    //   try{}catch(a){const a=\"aa\"}\n    //\n    if ([\n      'const.js: issue_4290_1',\n      'const.js: issue_4305_2',\n      'const.js: retain_catch',\n      'const.js: skip_braces',\n      'exports.js: defaults',\n      'exports.js: drop_unused',\n      'exports.js: hoist_exports_1',\n      'exports.js: hoist_exports_2',\n      'exports.js: keep_return_values',\n      'exports.js: mangle_rename',\n      'exports.js: mangle',\n      'exports.js: refs',\n      'imports.js: issue_4708_1',\n      'imports.js: issue_4708_2',\n      'let.js: issue_4290_1',\n      'let.js: issue_4305_2',\n      'let.js: retain_catch',\n      'let.js: skip_braces',\n      'reduce_vars.js: defun_catch_4',\n      'reduce_vars.js: defun_catch_5',\n      'templates.js: malformed_evaluate_1',\n      'templates.js: malformed_evaluate_2',\n      'templates.js: malformed_evaluate_3',\n      'varify.js: issue_4290_1_const',\n      'varify.js: issue_4290_1_let',\n    ].indexOf(`${basename}: ${test.name}`) >= 0) {\n      console.error(`*** skipping test with known syntax error: ${basename}: ${test.name}`);\n      return SKIP;\n    }\n\n    // These tests fail because esbuild supports top-level await. Technically\n    // top-level await is only allowed inside a module, and can be used as a\n    // normal identifier in a script. But the script/module distinction causes\n    // a lot of pain due to the need to configure every single tool to say\n    // whether to parse the code as a script or a module, so esbuild mostly\n    // does away with the distinction and enables top-level await everywhere.\n    // This means it fails these tests but the failures are unlikely to matter\n    // in real-world code, so they can be ignored. Here's one test case:\n    //\n    //   async function await(){console.log(\"PASS\")}await();\n    //\n    if ([\n      'awaits.js: defun_name',\n      'awaits.js: drop_fname',\n      'awaits.js: functions_anonymous',\n      'awaits.js: functions_inner_var',\n      'awaits.js: issue_4335_1',\n      'awaits.js: keep_fname',\n      'classes.js: await',\n    ].indexOf(`${basename}: ${test.name}`) >= 0) {\n      console.error(`*** skipping test with top-level await as identifier: ${basename}: ${test.name}`);\n      return SKIP;\n    }\n\n    // These tests fail because esbuild makes assigning to an inlined constant\n    // a compile error to avoid code with incorrect behavior. This is a limitation\n    // due to esbuild's three-pass design but it shouldn't matter in practice. It\n    // just means esbuild rejects bad code at compile time instead of at run time.\n    if ([\n      'const.js: issue_4212_1',\n      'const.js: issue_4212_2',\n    ].indexOf(`${basename}: ${test.name}`) >= 0) {\n      console.error(`*** skipping test with assignment to an inlined constant: ${basename}: ${test.name}`);\n      return SKIP;\n    }\n\n    log(\"!!! esbuild failed\\n---INPUT---\\n{input}\\n---ERROR---\\n{error}\\n\", {\n      input: input_code,\n      error: e && e.message || e,\n    });\n  }\n\n  // Make sure esbuild generates valid JavaScript\n  try {\n    U.parse(output);\n  } catch (ex) {\n    log([\n      \"!!! Test matched expected result but cannot parse output\",\n      \"---INPUT---\",\n      \"{input}\",\n      \"---OUTPUT---\",\n      \"{output}\",\n      \"--REPARSE ERROR--\",\n      \"{error}\",\n      \"\",\n      \"\",\n    ].join(\"\\n\"), {\n      input: input_formatted,\n      output: output,\n      error: ex && ex.stack || ex,\n    });\n  }\n\n  // Verify that the stdout matches our expectations\n  if (test.expect_stdout && (!test.node_version || semver.satisfies(process.version, test.node_version))) {\n    var stdout = [run_code(input_code), run_code(input_code, true)];\n    var toplevel = sandbox.has_toplevel({\n      compress: test.options,\n      mangle: test.mangle\n    });\n    var actual = stdout[toplevel ? 1 : 0];\n    if (test.expect_stdout === true) {\n      test.expect_stdout = actual;\n    }\n    actual = run_code(output, toplevel);\n\n    // Ignore the known failures in CI, but not otherwise\n    const isExpectingFailure = !process.env.CI ? false : [\n      // Stdout difference\n      'const.js: issue_4225',\n      'const.js: issue_4229',\n      'const.js: issue_4245',\n      'const.js: use_before_init_3',\n      'default-values.js: retain_empty_iife',\n      'destructured.js: funarg_side_effects_2',\n      'destructured.js: funarg_side_effects_3',\n      'let.js: issue_4225',\n      'let.js: issue_4229',\n      'let.js: issue_4245',\n      'let.js: use_before_init_3',\n\n      // Error difference\n      'dead-code.js: dead_code_2_should_warn',\n\n      // These tests fail because esbuild assumes that declaring a class that\n      // extends a base class has no side effects. That's not true because\n      // extending a non-constructible object throws an error. But refusing to\n      // tree-shake every class with a base class is not a useful thing for a\n      // bundler to do. So we pretend that this edge case doesn't exist.\n      'classes.js: issue_4722_1',\n      'classes.js: issue_4722_2',\n      'classes.js: issue_4722_3',\n    ].indexOf(`${basename}: ${test.name}`) >= 0\n\n    if (!sandbox.same_stdout(test.expect_stdout, actual)) {\n      if (isExpectingFailure) {\n        console.error(`*** skipping test with known esbuild failure: ${basename}: ${test.name}`);\n        return SKIP;\n      }\n\n      log([\n        \"!!! failed\",\n        \"---INPUT---\",\n        \"{input}\",\n        \"---EXPECTED {expected_type}---\",\n        \"{expected}\",\n        \"---ACTUAL {actual_type}---\",\n        \"{actual}\",\n        \"\",\n        \"\",\n      ].join(\"\\n\"), {\n        input: input_formatted,\n        expected_type: typeof test.expect_stdout == \"string\" ? \"STDOUT\" : \"ERROR\",\n        expected: test.expect_stdout,\n        actual_type: typeof actual == \"string\" ? \"STDOUT\" : \"ERROR\",\n        actual: actual,\n      });\n    } else if (isExpectingFailure) {\n      throw new Error(`UPDATE NEEDED: expected failure for ${basename}: ${test.name}, please remove this test from known failure list`);\n    }\n  }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// The code below was copied verbatim from \"uglify/demo/test/compress.js\"\n//\n// UglifyJS is released under the BSD license:\n//\n// Copyright 2012-2019 (c) Mihai Bazon <mihai.bazon@gmail.com>\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions\n// are met:\n//\n//     * Redistributions of source code must retain the above\n//       copyright notice, this list of conditions and the following\n//       disclaimer.\n//\n//     * Redistributions in binary form must reproduce the above\n//       copyright notice, this list of conditions and the following\n//       disclaimer in the documentation and/or other materials\n//       provided with the distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY\n// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE\n// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,\n// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR\n// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n// SUCH DAMAGE.\n\nfunction evaluate(code) {\n  if (code instanceof U.AST_Node) code = make_code(code, { beautify: true });\n  return new Function(\"return(\" + code + \")\")();\n}\n\nfunction make_code(ast, options) {\n  var stream = U.OutputStream(options);\n  ast.print(stream);\n  return stream.get();\n}\n\nfunction parse_test(file) {\n  var script = fs.readFileSync(file, \"utf8\");\n  // TODO try/catch can be removed after fixing https://github.com/mishoo/UglifyJS/issues/348\n  try {\n    var ast = U.parse(script, {\n      filename: file\n    });\n  } catch (e) {\n    console.error(\"Caught error while parsing tests in \" + file);\n    console.error(e);\n    process.exit(1);\n  }\n  var tests = Object.create(null);\n  var tw = new U.TreeWalker(function (node, descend) {\n    if (node instanceof U.AST_LabeledStatement\n      && tw.parent() instanceof U.AST_Toplevel) {\n      var name = node.label.name;\n      if (name in tests) {\n        throw new Error('Duplicated test name \"' + name + '\" in ' + file);\n      }\n      tests[name] = get_one_test(name, node.body);\n      return true;\n    }\n    if (!(node instanceof U.AST_Toplevel)) croak(node);\n  });\n  ast.walk(tw);\n  return tests;\n\n  function croak(node) {\n    throw new Error(tmpl(\"Can't understand test file {file} [{line},{col}]\\n{code}\", {\n      file: file,\n      line: node.start.line,\n      col: node.start.col,\n      code: make_code(node, { beautify: false })\n    }));\n  }\n\n  function read_string(stat) {\n    if (stat.TYPE == \"SimpleStatement\") {\n      var body = stat.body;\n      switch (body.TYPE) {\n        case \"String\":\n          return body.value;\n        case \"Array\":\n          return body.elements.map(function (element) {\n            if (element.TYPE !== \"String\")\n              throw new Error(\"Should be array of strings\");\n            return element.value;\n          }).join(\"\\n\");\n      }\n    }\n    throw new Error(\"Should be string or array of strings\");\n  }\n\n  function get_one_test(name, block) {\n    var test = { name: name, options: {} };\n    var tw = new U.TreeWalker(function (node, descend) {\n      if (node instanceof U.AST_Assign) {\n        if (!(node.left instanceof U.AST_SymbolRef)) {\n          croak(node);\n        }\n        var name = node.left.name;\n        test[name] = evaluate(node.right);\n        return true;\n      }\n      if (node instanceof U.AST_LabeledStatement) {\n        var label = node.label;\n        assert.ok([\n          \"input\",\n          \"expect\",\n          \"expect_exact\",\n          \"expect_warnings\",\n          \"expect_stdout\",\n          \"node_version\",\n        ].indexOf(label.name) >= 0, tmpl(\"Unsupported label {name} [{line},{col}]\", {\n          name: label.name,\n          line: label.start.line,\n          col: label.start.col\n        }));\n        var stat = node.body;\n        if (label.name == \"expect_exact\" || label.name == \"node_version\") {\n          test[label.name] = read_string(stat);\n        } else if (label.name == \"expect_stdout\") {\n          var body = stat.body;\n          if (body instanceof U.AST_Boolean) {\n            test[label.name] = body.value;\n          } else if (body instanceof U.AST_Call) {\n            var ctor = global[body.expression.name];\n            assert.ok(ctor === Error || ctor.prototype instanceof Error, tmpl(\"Unsupported expect_stdout format [{line},{col}]\", {\n              line: label.start.line,\n              col: label.start.col\n            }));\n            test[label.name] = ctor.apply(null, body.args.map(function (node) {\n              assert.ok(node instanceof U.AST_Constant, tmpl(\"Unsupported expect_stdout format [{line},{col}]\", {\n                line: label.start.line,\n                col: label.start.col\n              }));\n              return node.value;\n            }));\n          } else {\n            test[label.name] = read_string(stat) + \"\\n\";\n          }\n        } else {\n          test[label.name] = stat;\n        }\n        return true;\n      }\n    });\n    block.walk(tw);\n    return test;\n  }\n}\n\nfunction run_code(code, toplevel) {\n  const sandbox = require(path.join(uglifyDir, 'test', 'sandbox'));\n\n  var result = sandbox.run_code(code, toplevel);\n  return typeof result == \"string\" ? result.replace(/\\u001b\\[\\d+m/g, \"\") : result;\n}\n\nfunction tmpl() {\n  return U.string_template.apply(null, arguments);\n}\n\nfunction to_toplevel(input, mangle_options) {\n  if (!(input instanceof U.AST_BlockStatement)) throw new Error(\"Unsupported input syntax\");\n  var directive = true;\n  var offset = input.start.line;\n  var tokens = [];\n  var toplevel = new U.AST_Toplevel(input.transform(new U.TreeTransformer(function (node) {\n    if (U.push_uniq(tokens, node.start)) node.start.line -= offset;\n    if (!directive || node === input) return;\n    if (node instanceof U.AST_SimpleStatement && node.body instanceof U.AST_String) {\n      return new U.AST_Directive(node.body);\n    } else {\n      directive = false;\n    }\n  })));\n  toplevel.figure_out_scope(mangle_options);\n  return toplevel;\n}\n"
  },
  {
    "path": "scripts/verify-source-map.js",
    "content": "const { SourceMapConsumer } = require('source-map')\nconst { buildBinary, removeRecursiveSync } = require('./esbuild')\nconst childProcess = require('child_process')\nconst path = require('path')\nconst util = require('util')\nconst url = require('url')\nconst fs = require('fs').promises\n\nconst execFileAsync = util.promisify(childProcess.execFile)\n\nconst esbuildPath = buildBinary()\nconst testDir = path.join(__dirname, '.verify-source-map')\nlet tempDirCount = 0\n\nconst toSearchBundle = {\n  a0: 'a.js',\n  a1: 'a.js',\n  a2: 'a.js',\n  b0: 'b-dir/b.js',\n  b1: 'b-dir/b.js',\n  b2: 'b-dir/b.js',\n  c0: 'b-dir/c-dir/c.js',\n  c1: 'b-dir/c-dir/c.js',\n  c2: 'b-dir/c-dir/c.js',\n}\n\nconst toSearchNoBundle = {\n  a0: 'a.js',\n  a1: 'a.js',\n  a2: 'a.js',\n}\n\nconst toSearchNoBundleTS = {\n  a0: 'a.ts',\n  a1: 'a.ts',\n  a2: 'a.ts',\n}\n\nconst testCaseES6 = {\n  'a.js': `\n    import {b0} from './b-dir/b'\n    function a0() { a1(\"a0\") }\n    function a1() { a2(\"a1\") }\n    function a2() { b0(\"a2\") }\n    a0()\n  `,\n  'b-dir/b.js': `\n    import {c0} from './c-dir/c'\n    export function b0() { b1(\"b0\") }\n    function b1() { b2(\"b1\") }\n    function b2() { c0(\"b2\") }\n  `,\n  'b-dir/c-dir/c.js': `\n    export function c0() { c1(\"c0\") }\n    function c1() { c2(\"c1\") }\n    function c2() { throw new Error(\"c2\") }\n  `,\n}\n\nconst testCaseCommonJS = {\n  'a.js': `\n    const {b0} = require('./b-dir/b')\n    function a0() { a1(\"a0\") }\n    function a1() { a2(\"a1\") }\n    function a2() { b0(\"a2\") }\n    a0()\n  `,\n  'b-dir/b.js': `\n    const {c0} = require('./c-dir/c')\n    exports.b0 = function() { b1(\"b0\") }\n    function b1() { b2(\"b1\") }\n    function b2() { c0(\"b2\") }\n  `,\n  'b-dir/c-dir/c.js': `\n    exports.c0 = function() { c1(\"c0\") }\n    function c1() { c2(\"c1\") }\n    function c2() { throw new Error(\"c2\") }\n  `,\n}\n\nconst testCaseDiscontiguous = {\n  'a.js': `\n    import {b0} from './b-dir/b.js'\n    import {c0} from './b-dir/c-dir/c.js'\n    function a0() { a1(\"a0\") }\n    function a1() { a2(\"a1\") }\n    function a2() { b0(\"a2\") }\n    a0(b0, c0)\n  `,\n  'b-dir/b.js': `\n    exports.b0 = function() { b1(\"b0\") }\n    function b1() { b2(\"b1\") }\n    function b2() { c0(\"b2\") }\n  `,\n  'b-dir/c-dir/c.js': `\n    export function c0() { c1(\"c0\") }\n    function c1() { c2(\"c1\") }\n    function c2() { throw new Error(\"c2\") }\n  `,\n}\n\nconst testCaseTypeScriptRuntime = {\n  'a.ts': `\n    namespace Foo {\n      export var {a, ...b} = foo() // This requires a runtime function to handle\n      console.log(a, b)\n    }\n    function a0() { a1(\"a0\") }\n    function a1() { a2(\"a1\") }\n    function a2() { throw new Error(\"a2\") }\n    a0()\n  `,\n}\n\nconst testCaseStdin = {\n  '<stdin>': `#!/usr/bin/env node\n    function a0() { a1(\"a0\") }\n    function a1() { a2(\"a1\") }\n    function a2() { throw new Error(\"a2\") }\n    a0()\n  `,\n}\n\nconst testCaseEmptyFile = {\n  'entry.js': `\n    import './before'\n    import {fn} from './re-export'\n    import './after'\n    fn()\n  `,\n  're-export.js': `\n    // This file will be empty in the generated code, which was causing\n    // an off-by-one error with the source index in the source map\n    export {default as fn} from './test'\n  `,\n  'test.js': `\n    export default function() {\n      console.log(\"test\")\n    }\n  `,\n  'before.js': `\n    console.log(\"before\")\n  `,\n  'after.js': `\n    console.log(\"after\")\n  `,\n}\n\nconst toSearchEmptyFile = {\n  before: 'before.js',\n  test: 'test.js',\n  after: 'after.js',\n}\n\nconst testCaseNonJavaScriptFile = {\n  'entry.js': `\n    import './before'\n    import text from './file.txt'\n    import './after'\n    console.log(text)\n  `,\n  'file.txt': `\n    This is some text.\n  `,\n  'before.js': `\n    console.log(\"before\")\n  `,\n  'after.js': `\n    console.log(\"after\")\n  `,\n}\n\nconst toSearchNonJavaScriptFile = {\n  before: 'before.js',\n  after: 'after.js',\n}\n\nconst testCaseCodeSplitting = {\n  'out.ts': `\n    import value from './shared'\n    console.log(\"out\", value)\n  `,\n  'other.ts': `\n    import value from './shared'\n    console.log(\"other\", value)\n  `,\n  'shared.ts': `\n    export default 123\n  `,\n}\n\nconst toSearchCodeSplitting = {\n  out: 'out.ts',\n}\n\nconst testCaseCodeSplittingEmptyFile = {\n  'entry1.ts': `\n    import './a.ts'\n    import './empty.ts'\n    import './b.ts'\n  `,\n  'entry2.ts': `\n    import './a.ts'\n    import './empty.ts'\n    import './b.ts'\n  `,\n  'a.ts': `'foo'.print()`,\n  'empty.ts': `//! @preserve`,\n  'b.ts': `'bar'.print()`,\n}\n\nconst toSearchCodeSplittingEmptyFile = {\n  foo: 'a.ts',\n  bar: 'b.ts',\n}\n\nconst testCaseUnicode = {\n  'entry.js': `\n    import './a'\n    import './b'\n  `,\n  'a.js': `\n    console.log('🍕🍕🍕', \"a\")\n  `,\n  'b.js': `\n    console.log({𐀀: \"b\"})\n  `,\n}\n\nconst toSearchUnicode = {\n  a: 'a.js',\n  b: 'b.js',\n}\n\nconst testCasePartialMappings = {\n  // The \"mappings\" value is \"A,Q,I;A,Q,I;A,Q,I;AAMA,QAAQ,IAAI;\" which contains\n  // partial mappings without original locations. This used to throw things off.\n  'entry.js': `console.log(1);\nconsole.log(2);\nconsole.log(3);\nconsole.log(\"entry\");\n//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKIC` +\n    `Aic291cmNlcyI6IFsiZW50cnkuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnNvb` +\n    `GUubG9nKDEpXG5cbmNvbnNvbGUubG9nKDIpXG5cbmNvbnNvbGUubG9nKDMpXG5cbmNvbnNv` +\n    `bGUubG9nKFwiZW50cnlcIilcbiJdLAogICJtYXBwaW5ncyI6ICJBLFEsSTtBLFEsSTtBLFE` +\n    `sSTtBQU1BLFFBQVEsSUFBSTsiLAogICJuYW1lcyI6IFtdCn0=\n`,\n}\n\nconst testCasePartialMappingsPercentEscape = {\n  // The \"mappings\" value is \"A,Q,I;A,Q,I;A,Q,I;AAMA,QAAQ,IAAI;\" which contains\n  // partial mappings without original locations. This used to throw things off.\n  'entry.js': `console.log(1);\nconsole.log(2);\nconsole.log(3);\nconsole.log(\"entry\");\n//# sourceMappingURL=data:,%7B%22version%22%3A3%2C%22sources%22%3A%5B%22entr` +\n    `y.js%22%5D%2C%22sourcesContent%22%3A%5B%22console.log(1)%5Cn%5Cnconsole` +\n    `.log(2)%5Cn%5Cnconsole.log(3)%5Cn%5Cnconsole.log(%5C%22entry%5C%22)%5Cn` +\n    `%22%5D%2C%22mappings%22%3A%22A%2CQ%2CI%3BA%2CQ%2CI%3BA%2CQ%2CI%3BAAMA%2` +\n    `CQAAQ%2CIAAI%3B%22%2C%22names%22%3A%5B%5D%7D\n`,\n}\n\nconst toSearchPartialMappings = {\n  entry: 'entry.js',\n}\n\nconst testCaseComplex = {\n  // \"fuse.js\" is included because it has a nested source map of some complexity.\n  // \"react\" is included after that because it's a big blob of code and helps\n  // make sure stuff after a nested source map works ok.\n  'entry.js': `\n    import Fuse from 'fuse.js'\n    import * as React from 'react'\n    console.log(Fuse, React)\n  `,\n}\n\nconst toSearchComplex = {\n  '[object Array]': 'webpack:///src/helpers/is_array.js',\n  'Score average:': 'webpack:///src/index.js',\n  '0123456789': '../../node_modules/object-assign/index.js',\n  'forceUpdate': '../../node_modules/react/cjs/react.production.min.js',\n};\n\nconst testCaseDynamicImport = {\n  'entry.js': `\n    const then = (x) => console.log(\"imported\", x);\n    console.log([import(\"./ext/a.js\").then(then), import(\"./ext/ab.js\").then(then), import(\"./ext/abc.js\").then(then)]);\n    console.log([import(\"./ext/abc.js\").then(then), import(\"./ext/ab.js\").then(then), import(\"./ext/a.js\").then(then)]);\n  `,\n  'ext/a.js': `\n    export default 'a'\n  `,\n  'ext/ab.js': `\n    export default 'ab'\n  `,\n  'ext/abc.js': `\n    export default 'abc'\n  `,\n}\n\nconst toSearchDynamicImport = {\n  './ext/a.js': 'entry.js',\n  './ext/ab.js': 'entry.js',\n  './ext/abc.js': 'entry.js',\n};\n\nconst toSearchBundleCSS = {\n  a0: 'a.css',\n  a1: 'a.css',\n  a2: 'a.css',\n  b0: 'b-dir/b.css',\n  b1: 'b-dir/b.css',\n  b2: 'b-dir/b.css',\n  c0: 'b-dir/c-dir/c.css',\n  c1: 'b-dir/c-dir/c.css',\n  c2: 'b-dir/c-dir/c.css',\n}\n\nconst testCaseBundleCSS = {\n  'entry.css': `\n    @import \"a.css\";\n  `,\n  'a.css': `\n    @import \"b-dir/b.css\";\n    a:nth-child(0):after { content: \"a0\"; }\n    a:nth-child(1):after { content: \"a1\"; }\n    a:nth-child(2):after { content: \"a2\"; }\n  `,\n  'b-dir/b.css': `\n    @import \"c-dir/c.css\";\n    b:nth-child(0):after { content: \"b0\"; }\n    b:nth-child(1):after { content: \"b1\"; }\n    b:nth-child(2):after { content: \"b2\"; }\n  `,\n  'b-dir/c-dir/c.css': `\n    c:nth-child(0):after { content: \"c0\"; }\n    c:nth-child(1):after { content: \"c1\"; }\n    c:nth-child(2):after { content: \"c2\"; }\n  `,\n}\n\nconst testCaseJSXRuntime = {\n  'entry.jsx': `\n    import { A0, A1, A2 } from './a.jsx';\n    console.log(<A0><A1/><A2/></A0>)\n  `,\n  'a.jsx': `\n    import {jsx} from './b-dir/b'\n    import {Fragment} from './b-dir/c-dir/c'\n    export function A0() { return <Fragment id=\"A0\"><>a0</></Fragment> }\n    export function A1() { return <div {...jsx} data-testid=\"A1\">a1</div> }\n    export function A2() { return <A1 id=\"A2\"><a/><b/></A1> }\n  `,\n  'b-dir/b.js': `\n    export const jsx = {id: 'jsx'}\n  `,\n  'b-dir/c-dir/c.jsx': `\n    exports.Fragment = function() { return <></> }\n  `,\n}\n\nconst toSearchJSXRuntime = {\n  A0: 'a.jsx',\n  A1: 'a.jsx',\n  A2: 'a.jsx',\n  jsx: 'b-dir/b.js',\n}\n\nconst testCaseNames = {\n  'entry.js': `\n    import \"./nested1\"\n\n    // Test regular name positions\n    var /**/foo = /**/foo || 0\n    function /**/fn(/**/bar) {}\n    class /**/cls {}\n    keep(fn, cls) // Make sure these aren't removed\n\n    // Test property mangling name positions\n    var { /**/mangle_: bar } = foo\n    var { /**/'mangle_': bar } = foo\n    foo./**/mangle_ = 1\n    foo[/**/'mangle_']\n    foo = { /**/mangle_: 0 }\n    foo = { /**/'mangle_': 0 }\n    foo = class { /**/mangle_ = 0 }\n    foo = class { /**/'mangle_' = 0 }\n    foo = /**/'mangle_' in bar\n  `,\n  'nested1.js': `\n    import { foo } from './nested2'\n    foo(bar)\n  `,\n  'nested2.jsx': `\n    export let /**/foo = /**/bar => /**/bar()\n  `\n}\n\nconst testCaseMissingSourcesContent = {\n  'foo.js': `// foo.ts\nvar foo = { bar: \"bar\" };\nconsole.log({ foo });\n//# sourceMappingURL=maps/foo.js.map\n`,\n  'maps/foo.js.map': `{\n  \"version\": 3,\n  \"sources\": [\"src/foo.ts\"],\n  \"mappings\": \";AAGA,IAAM,MAAW,EAAE,KAAK,MAAM;AAC9B,QAAQ,IAAI,EAAE,IAAI,CAAC;\",\n  \"names\": []\n}\n`,\n  'maps/src/foo.ts': `interface Foo {\n  bar: string\n}\nconst foo: Foo = { bar: 'bar' }\nconsole.log({ foo })\n`,\n}\n\nconst toSearchMissingSourcesContent = {\n  bar: 'maps/src/foo.ts',\n}\n\n// The \"null\" should be filled in by the contents of \"bar.ts\"\nconst testCaseNullSourcesContent = {\n  'entry.js': `import './foo.js'\\n`,\n  'foo.ts': `import './bar.ts'\\nconsole.log(\"foo\")`,\n  'bar.ts': `console.log(\"bar\")\\n`,\n  'foo.js': `(() => {\n  // bar.ts\n  console.log(\"bar\");\n\n  // foo.ts\n  console.log(\"foo\");\n})();\n//# sourceMappingURL=foo.js.map\n`,\n  'foo.js.map': `{\n  \"version\": 3,\n  \"sources\": [\"bar.ts\", \"foo.ts\"],\n  \"sourcesContent\": [null, \"import './bar.ts'\\\\nconsole.log(\\\\\"foo\\\\\")\"],\n  \"mappings\": \";;AAAA,UAAQ,IAAI,KAAK;;;ACCjB,UAAQ,IAAI,KAAK;\",\n  \"names\": []\n}\n`,\n}\n\nconst toSearchNullSourcesContent = {\n  bar: 'bar.ts',\n}\n\nconst testCaseFileNameWithSpaces = {\n  'file name with spaces.js': `console . log ( \"test\" )`,\n}\n\nconst toSearchFileNameWithSpaces = {\n  test: 'file name with spaces.js',\n}\n\nconst testCaseAbsoluteSourceMappingURL = {\n  'entry.js': `console.log(\"test\");\n//# sourceMappingURL={ABSOLUTE_FILE_URL}/entry.js.map\n`,\n  'entry.js.map': `{\n  \"version\": 3,\n  \"sources\": [\"input.js\"],\n  \"sourcesContent\": [\"console . log ( \\\\\\\"test\\\\\\\" )\"],\n  \"mappings\": \"AAAA,QAAU,IAAM,MAAO;\",\n  \"names\": []\n}\n`,\n}\n\nconst toSearchAbsoluteSourceMappingURL = {\n  test: 'input.js',\n}\n\nconst testCaseAbsoluteSourcesURL = {\n  'entry.js': `console.log(\"test\");\n//# sourceMappingURL=entry.js.map\n`,\n  'entry.js.map': `{\n  \"version\": 3,\n  \"sources\": [\"{ABSOLUTE_FILE_URL}/input.js\"],\n  \"sourcesContent\": [\"console . log ( \\\\\\\"test\\\\\\\" )\"],\n  \"mappings\": \"AAAA,QAAU,IAAM,MAAO;\",\n  \"names\": []\n}\n`,\n}\n\nconst toSearchAbsoluteSourcesURL = {\n  test: 'input.js',\n}\n\n// This test case was generated using the \"shadow-cljs\" tool by someone who has\n// no idea how to write Clojure code (i.e. me). See the following GitHub issue\n// for more details: https://github.com/evanw/esbuild/issues/3439\n//\n// Note that the mappings in the Clojure output strangely seem to be really\n// buggy. Many sub-expressions with two operands map the operands switched,\n// strings are way off, and there's even one mapping that's floating off in\n// space past the end of the line. This appears to just be bad output from the\n// Clojure tooling itself though, and not a problem with esbuild.\n//\n// For the example code below, I manually edited the mapping for the \"done\"\n// string to line up correctly so that this test can pass (it was off by\n// five lines).\nconst testCaseIndexSourceMap = {\n  'entry.js': `\n    import './app.main.js'\n    console.log('testing')\n  `,\n  'app.main.js': `export const $APP = {};\nexport const shadow$provide = {};\nexport const $jscomp = {};\n/*\n\n Copyright The Closure Library Authors.\n SPDX-License-Identifier: Apache-2.0\n*/\nconsole.log(function $app$lib$log_many$$($G__6268$jscomp$1_i$jscomp$282$$, $collection$$) {\n  return $G__6268$jscomp$1_i$jscomp$282$$ < $collection$$.length ? (console.` +\n    `log($collection$$.at($G__6268$jscomp$1_i$jscomp$282$$)), $G__6268$jscom` +\n    `p$1_i$jscomp$282$$ += 1, $app$lib$log_many$$.$cljs$core$IFn$_invoke$ari` +\n    `ty$2$ ? $app$lib$log_many$$.$cljs$core$IFn$_invoke$arity$2$($G__6268$js` +\n    `comp$1_i$jscomp$282$$, $collection$$) : $app$lib$log_many$$.call(null, ` +\n    `$G__6268$jscomp$1_i$jscomp$282$$, $collection$$)) : \"done\";\n}(0, Object.keys(console)));\nexport const render = {}.render;\n\n//# sourceMappingURL=app.main.js.map`,\n  'app.main.js.map': `{\"version\":3,\"file\":\"app.main.js\",\"sections\":[{\"offset` +\n    `\":{\"line\":3,\"column\":0},\"map\":{\"version\":3,\"file\":\"app.main.js\",\"lineCo` +\n    `unt\":10,\"mappings\":\"A;;;;;AAGMA,OAAAA,CAAAA,GAAAA,CCDAC,QAAAA,oBAAAA,CA` +\n    `AUC,gCAAVD,EAAYE,aAAZF,CAAYE;AAAlB,SACSD,gCADT,GACWC,aAAUA,CAAAA,MADrB,` +\n    `IAGYH,OAAAA,CAAAA,GAAAA,CAAgBG,aAAAA,CAAAA,EAAAA,CAAWD,gCAAXC,CAAhBH,CA` +\n    `CN,EAAUE,gCAAV,IAAaA,CAAb,EAAAE,mBAAAC,CAAAA,+BAAA,GAAAD,mBAAAC,CAAAA,+` +\n    `BAAA,CAAAC,gCAAA,EAAkBH,aAAlB,CAAA,GAAAI,mBAAAA,CAAAA,IAAAA,CAAAA,IAAAA` +\n    `,EAAAD,gCAAAC,EAAkBJ,aAAlBI,CAJN,IAKI,MALJ;AAAkBJ,CDCD,CAACF,CAAD,EAAgB` +\n    `O,MAAOC,CAAAA,IAAP,CAAiBT,OAAjB,CAAhB,CAAXA,CAAAA;AEFN,sBFDkBU,EECaC,CA` +\n    `AAA,MAA/B;;\",\"sources\":[\"app/app.cljs\",\"app/lib.cljs\",\"shadow/module/ap` +\n    `p.main/append.js\"],\"sourcesContent\":[\"(ns app.app\\\\n  (:require [app.li` +\n    `b :as lib]))\\\\n\\\\n(.log js/console (lib/log-many 0 (.keys js/Object js/` +\n    `console)))\\\\n\",\"(ns app.lib)\\\\n\\\\n(defn log-many [i collection]\\\\n  (if` +\n    ` (< i (.-length collection))\\\\n    (do\\\\n      (.log js/console (.at co` +\n    `llection i))\\\\n      (log-many (+ i 1) collection))\\\\n    \\\\\"done\\\\\"))` +\n    `\\\\n\",\"\\\\nshadow$export(\\\\\"render\\\\\",app.app.render);\"],\"names\":[\"js/con` +\n    `sole\",\"app.lib/log-many\",\"i\",\"collection\",\"app.lib.log_manycljs$core$IF` +\n    `n$_invoke$arity$2\",\"cljs$core$IFn$_invoke$arity$2\",\"G__6268\",\"G__6269\",` +\n    `\"Object\",\"js/Object\",\"app.apprender\",\"render\"],\"x_google_ignoreList\":[2` +\n    `]}}]}`,\n}\n\nconst toSearchIndexSourceMap = {\n  'done': 'app/lib.cljs',\n}\n\n// This case covers a crash when esbuild would generate an invalid source map\n// containing a mapping with an index of a source that's out of bounds of the\n// \"sources\" array. This happened when generating the namespace exports chunk\n// which in this case is triggered by \"export * as it from\". For more\n// information, see: https://github.com/evanw/esbuild/issues/4080\nconst testCaseNullMappingIssue4080 = {\n  'foo.js': `// foo.js\nhere.is.some.code = \"foo!\";\n//# sourceMappingURL=foo.js.map\n`,\n  'foo.js.map': `{\n  \"version\": 3,\n  \"sources\": [\"./src/foo.js\"],\n  \"sourcesContent\": [\"here\\\\n  .is\\\\n  .some\\\\n  .code\\\\n  = 'foo!'\\\\n\"],\n  \"mappings\": \";AAAA,KACG,GACA,KACA,OACC;\",\n  \"names\": []\n}`,\n  'bar.js': `// bar.js\nhere.is.some.more.code = \"bar!\";\n//# sourceMappingURL=bar.js.map\n`,\n  'bar.js.map': `{\n  \"version\": 3,\n  \"sources\": [\"./src/bar.js\"],\n  \"sourcesContent\": [\"here\\\\n  .is.some.more\\\\n  .code\\\\n  = 'bar!'\\\\n\"],\n  \"mappings\": \";AAAA,KACG,GAAG,KAAK,KACR,OACC;\",\n  \"names\": []\n}`,\n  'core.js': `// core.js\nimport \"./bar.js\";\n\n// lib.js\nvar value = \"lib!\";\nexport {\n  value\n};\n//# sourceMappingURL=core.js.map\n`,\n  'core.js.map': `{\n  \"version\": 3,\n  \"sources\": [\"./src/core.js\", \"./src/lib.js\"],\n  \"sourcesContent\": [\"import './bar.js'\\\\nexport { value } from './lib.js'\\\\n\", \"export const value = 'lib!'\\\\n\"],\n  \"mappings\": \";AAAA,OAAO;;;ACAA,IAAM,QAAQ;\",\n  \"names\": []\n}`,\n  'entry.js': `import './foo.js'\nexport * as it from './core.js'\n`,\n}\n\nconst toSearchNullMappingIssue4080 = {\n  'foo!': 'src/foo.js',\n  'bar!': 'src/bar.js',\n  'lib!': 'src/lib.js',\n}\n\nconst testCaseNestedFoldersIssue4070 = {\n  'src/main.js': `import { appConfig } from \"./app/app.config\";\nappConfig(\"foo\");\n//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKIC` +\n    `Aic291cmNlcyI6IFsibWFpbi5qcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0I` +\n    `HsgYXBwQ29uZmlnIH0gZnJvbSBcIi4vYXBwL2FwcC5jb25maWdcIjtcbmFwcENvbmZpZyhc` +\n    `ImZvb1wiKTsiXSwKICAibWFwcGluZ3MiOiAiQUFBQSxTQUFTLGlCQUFpQjtBQUMxQixVQUF` +\n    `VLEtBQUs7IiwKICAibmFtZXMiOiBbXQp9Cg==`,\n  'src/app/app.config.js': `export const appConfig = (x) => console.log(x, \"bar\");\n//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKIC` +\n    `Aic291cmNlcyI6IFsiYXBwLmNvbmZpZy5qcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiZ` +\n    `Xhwb3J0IGNvbnN0IGFwcENvbmZpZyA9IHggPT4gY29uc29sZS5sb2coeCwgXCJiYXJcIik7` +\n    `Il0sCiAgIm1hcHBpbmdzIjogIkFBQU8sYUFBTSxZQUFZLE9BQUssUUFBUSxJQUFJLEdBQUc` +\n    `sS0FBSzsiLAogICJuYW1lcyI6IFtdCn0K`,\n}\n\nconst toSearchNestedFoldersIssue4070 = {\n  'foo': 'src/main.js',\n  'bar': 'src/app/app.config.js',\n}\n\n// This test checks what happens when you use absolute paths in inlined source\n// maps. This is done two ways, first using a \"file://\" URL and second using\n// an actual absolute path.\n//\n// Only the first way is supposed to be valid, at least according to the formal\n// specification (https://tc39.es/ecma426/) which says that each source is \"a\n// string that is a (potentially relative) URL\".\n//\n// However, for a long time source maps was poorly-specified. The old source map\n// specification (https://sourcemaps.info/spec.html) only says \"sources\" is \"a\n// list of original sources used by the mappings entry\".\n//\n// So it makes sense that software which predates the formal specification of\n// source maps might fill in the sources array with absolute file paths instead\n// of URLs. So we test for that here to make sure esbuild works either way.\n//\n// Windows paths make this complicated. Here are all five possible combinations\n// of absolute paths for the file \"folder/file.js\":\n//\n// - Unix URL: \"file:///folder/file.js\"\n// - Unix path: \"/folder/file.js\"\n// - Windows URL: \"file:///C:/folder/file.js\"\n// - Windows path v1: \"C:/folder/file.js\" (not covered here)\n// - Windows path v2: \"C:\\folder\\file.js\"\n//\nconst rootDir = path.dirname(process.cwd().split(path.sep).slice(0, 2).join(path.sep))\nconst pathIssue4075 = path.join(rootDir, 'out', 'src', 'styles')\nconst urlIssue4075 = url.pathToFileURL(pathIssue4075)\nconst urlIssue4075Encoded = encodeURIComponent(JSON.stringify(urlIssue4075 + '1.scss'))\nconst pathIssue4075Encoded = encodeURIComponent(JSON.stringify(pathIssue4075 + '2.scss'))\nconst testCaseAbsolutePathIssue4075 = {\n  'entry.css': `\n    @import \"./styles1.css\";\n    @import \"./styles2.css\";\n  `,\n  'styles1.css': `/* You can add global styles to this file, and also import other style files */\n* {\n  content: \"foo\";\n}\n\n/*# sourceMappingURL=data:application/json;charset=utf-8,%7B%22version%22:3,` +\n    `%22sourceRoot%22:%22%22,%22sources%22:%5B${urlIssue4075Encoded}%5D,%22n` +\n    `ames%22:%5B%5D,%22mappings%22:%22AAAA;AACA;EACE,SAAS%22,%22file%22:%22o` +\n    `ut%22,%22sourcesContent%22:%5B%22/*%20You%20can%20add%20global%20styles` +\n    `%20to%20this%20file,%20and%20also%20import%20other%20style%20files%20%2` +\n    `A/%5Cn*%20%7B%5Cn%20%20content:%20%5C%22foo%5C%22%5Cn%7D%5Cn%22%5D%7D */`,\n  'styles2.css': `/* You can add global styles to this file, and also import other style files */\n* {\n  content: \"bar\";\n}\n\n/*# sourceMappingURL=data:application/json;charset=utf-8,%7B%22version%22:3,` +\n    `%22sourceRoot%22:%22%22,%22sources%22:%5B${pathIssue4075Encoded}%5D,%22` +\n    `names%22:%5B%5D,%22mappings%22:%22AAAA;AACA;EACE,SAAS%22,%22file%22:%22` +\n    `out%22,%22sourcesContent%22:%5B%22/*%20You%20can%20add%20global%20style` +\n    `s%20to%20this%20file,%20and%20also%20import%20other%20style%20files%20%` +\n    `2A/%5Cn*%20%7B%5Cn%20%20content:%20%5C%22bar%5C%22%5Cn%7D%5Cn%22%5D%7D */`,\n}\n\nconst toSearchAbsolutePathIssue4075 = {\n  foo: path.relative(path.join(testDir, '(this test)'), pathIssue4075 + '1.scss').replaceAll('\\\\', '/'),\n  bar: path.relative(path.join(testDir, '(this test)'), pathIssue4075 + '2.scss').replaceAll('\\\\', '/'),\n}\n\nconst testCaseMissingSourcesIssue4104 = {\n  'entry.js': `import { bootstrapApplication } from '@angular/platform-browser';\nimport { AppComponent } from './app.js';\n\nbootstrapApplication(AppComponent)\n  .catch((err) => console.error(err));`,\n  'app.component.html': `<div>`,\n  'app.js': `import { __decorate } from \"tslib\";\nimport __NG_CLI_RESOURCE__0 from \"./app.component.html\";\nimport { Component } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nlet AppComponent = class AppComponent {\n    title = 'ng19-sourcemap-repro';\n    onClick() {\n        debugger;\n    }\n};\nAppComponent = __decorate([\n    Component({\n        selector: 'app-root',\n        imports: [RouterOutlet],\n        template: __NG_CLI_RESOURCE__0,\n    })\n], AppComponent);\nexport { AppComponent };\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIj` +\n    `oiYXBwLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImFwcC5jb` +\n    `21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEVBQUUs` +\n    `U0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUF` +\n    `BTSxpQkFBaUIsQ0FBQztBQU94QyxJQUFNLFlBQVksR0FBbEIsTUFBTSxZQUFZO0lBQ3ZCLE` +\n    `tBQUssR0FBRyxzQkFBc0IsQ0FBQztJQUUvQixPQUFPO1FBQ0wsUUFBUSxDQUFDO0lBQ1gsQ` +\n    `0FBQztDQUNGLENBQUE7QUFOWSxZQUFZO0lBTHhCLFNBQVMsQ0FBQztRQUNULFFBQVEsRUFB` +\n    `RSxVQUFVO1FBQ3BCLE9BQU8sRUFBRSxDQUFDLFlBQVksQ0FBQztRQUN2Qiw4QkFBbUM7S0F` +\n    `DcEMsQ0FBQztHQUNXLFlBQVksQ0FNeEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgey` +\n    `BDb21wb25lbnQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJvdXRlck91d` +\n    `GxldCB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5cbkBDb21wb25lbnQoe1xuICBzZWxl` +\n    `Y3RvcjogJ2FwcC1yb290JyxcbiAgaW1wb3J0czogW1JvdXRlck91dGxldF0sXG4gIHRlbXB` +\n    `sYXRlVXJsOiAnLi9hcHAuY29tcG9uZW50Lmh0bWwnLFxufSlcbmV4cG9ydCBjbGFzcyBBcH` +\n    `BDb21wb25lbnQge1xuICB0aXRsZSA9ICduZzE5LXNvdXJjZW1hcC1yZXBybyc7XG5cbiAgb` +\n    `25DbGljaygpIHtcbiAgICBkZWJ1Z2dlcjtcbiAgfVxufVxuIl19`,\n}\n\nconst toSearchMissingSourcesIssue4104 = {\n  '@angular/platform-browser': 'entry.js',\n  '@angular/core': 'app.component.ts',\n  'ng19-sourcemap-repro': 'app.component.ts',\n  'app-root': 'app.component.ts',\n}\n\nconst testCaseDefineWithObjectIssue4169 = {\n  'entry.js': `console.log(OBJECT, ARRAY);`,\n}\n\nconst toSearchDefineWithObjectIssue4169 = {\n  'test object': '<define:OBJECT>',\n  'test array': '<define:ARRAY>',\n}\n\nasync function check(kind, testCase, toSearch, { outfile, flags, entryPoints, crlf, followUpFlags = [], checkFirstChunk }) {\n  let failed = 0\n\n  try {\n    const recordCheck = (success, message) => {\n      if (!success) {\n        failed++\n        console.error(`❌ [${kind}] ${message}`)\n      }\n    }\n\n    const tempDir = path.join(testDir, `${kind}-${tempDirCount++}`)\n    await fs.mkdir(tempDir, { recursive: true })\n\n    for (const name in testCase) {\n      if (name !== '<stdin>') {\n        const tempPath = path.join(tempDir, name)\n        let code = testCase[name]\n\n        // Make it possible to test absolute \"file://\" URLs\n        code = code.replace('{ABSOLUTE_FILE_URL}', url.pathToFileURL(tempDir).href)\n\n        await fs.mkdir(path.dirname(tempPath), { recursive: true })\n        if (crlf) code = code.replace(/\\n/g, '\\r\\n')\n        await fs.writeFile(tempPath, code)\n      }\n    }\n\n    if (outfile && !flags.some(flag => flag.startsWith('--outdir='))) flags.push('--outfile=' + outfile)\n    const args = ['--sourcemap', '--log-level=warning'].concat(flags)\n    const isStdin = '<stdin>' in testCase\n    let stdout = ''\n\n    await new Promise((resolve, reject) => {\n      args.unshift(...entryPoints)\n      const child = childProcess.spawn(esbuildPath, args, { cwd: tempDir, stdio: ['pipe', 'pipe', 'inherit'] })\n      if (isStdin) child.stdin.write(testCase['<stdin>'])\n      child.stdin.end()\n      child.stdout.on('data', chunk => stdout += chunk.toString())\n      child.stdout.on('end', resolve)\n      child.on('error', reject)\n    })\n\n    let outCode\n    let outCodeMap\n\n    // Optionally check the first chunk when splitting\n    if (checkFirstChunk && flags.includes('--splitting')) {\n      const entries = await fs.readdir(tempDir)\n      for (const entry of entries.sort()) {\n        if (entry.startsWith('chunk-')) {\n          outfile = entry\n          break\n        }\n      }\n    }\n\n    if (isStdin) {\n      outCode = stdout\n      recordCheck(outCode.includes(`# sourceMappingURL=data:application/json;base64,`), `stdin must contain source map`)\n      outCodeMap = Buffer.from(outCode.slice(outCode.indexOf('base64,') + 'base64,'.length).trim(), 'base64').toString()\n    }\n\n    else {\n      outCode = await fs.readFile(path.join(tempDir, outfile), 'utf8')\n      recordCheck(outCode.includes(`# sourceMappingURL=${encodeURIComponent(outfile)}.map`), `${outfile} file must link to ${outfile}.map`)\n      outCodeMap = await fs.readFile(path.join(tempDir, `${outfile}.map`), 'utf8')\n    }\n\n    // Check the mapping of various key locations back to the original source\n    const checkMap = (out, map) => {\n      for (const id in toSearch) {\n        const outIndex = out.indexOf(`\"${id}\"`)\n        if (outIndex < 0) throw new Error(`Failed to find \"${id}\" in output`)\n        const outLines = out.slice(0, outIndex).split('\\n')\n        const outLine = outLines.length\n        const outLastLine = outLines[outLines.length - 1]\n        let outColumn = outLastLine.length\n        const { source, line, column } = map.originalPositionFor({ line: outLine, column: outColumn })\n\n        const inSource = isStdin ? '<stdin>' : toSearch[id]\n        recordCheck(decodeURI(source) === inSource, `expected source: ${inSource}, observed source: ${source}`)\n\n        const inCode = map.sourceContentFor(source)\n        if (inCode === null) throw new Error(`Got null for source content for \"${source}\"`)\n        let inIndex = inCode.indexOf(`\"${id}\"`)\n        if (inIndex < 0) inIndex = inCode.indexOf(`'${id}'`)\n        if (inIndex < 0) throw new Error(`Failed to find \"${id}\" in input`)\n        const inLines = inCode.slice(0, inIndex).split('\\n')\n        const inLine = inLines.length\n        const inLastLine = inLines[inLines.length - 1]\n        let inColumn = inLastLine.length\n\n        const expected = JSON.stringify({ source, line: inLine, column: inColumn })\n        const observed = JSON.stringify({ source, line, column })\n        recordCheck(expected === observed, `expected original position: ${expected}, observed original position: ${observed}`)\n\n        // Also check the reverse mapping\n        const positions = map.allGeneratedPositionsFor({ source, line: inLine, column: inColumn })\n        recordCheck(positions.length > 0, `expected generated positions: 1, observed generated positions: ${positions.length}`)\n        let found = false\n        for (const { line, column } of positions) {\n          if (line === outLine && column === outColumn) {\n            found = true\n            break\n          }\n        }\n        const expectedPosition = JSON.stringify({ line: outLine, column: outColumn })\n        const observedPositions = JSON.stringify(positions)\n        recordCheck(found, `expected generated position: ${expectedPosition}, observed generated positions: ${observedPositions}`)\n      }\n    }\n\n    const sources = JSON.parse(outCodeMap).sources\n    for (let source of sources) {\n      if (sources.filter(s => s === source).length > 1) {\n        throw new Error(`Duplicate source ${JSON.stringify(source)} found in source map`)\n      }\n    }\n\n    const outMap = await new SourceMapConsumer(outCodeMap)\n    checkMap(outCode, outMap)\n\n    // Check that every generated location has an associated original position.\n    // This only works when not bundling because bundling includes runtime code.\n    if (flags.indexOf('--bundle') < 0) {\n      // The last line doesn't have a source map entry, but that should be ok.\n      const outLines = outCode.trimRight().split('\\n');\n\n      for (let outLine = 0; outLine < outLines.length; outLine++) {\n        if (outLines[outLine].startsWith('#!') || outLines[outLine].startsWith('//')) {\n          // Ignore the hashbang line and the source map comment itself\n          continue;\n        }\n\n        for (let outColumn = 0; outColumn <= outLines[outLine].length; outColumn++) {\n          const { line, column } = outMap.originalPositionFor({ line: outLine + 1, column: outColumn })\n          recordCheck(line !== null && column !== null, `missing location for line ${outLine} and column ${outColumn}`)\n        }\n      }\n    }\n\n    // Bundle again to test nested source map chaining\n    for (let order of [0, 1, 2]) {\n      const infile = isStdin ? `stdout.js` : outfile\n      const outfile2 = 'nested.' + infile\n      const nestedEntry = path.join(tempDir, `nested-entry.${infile}`)\n      if (isStdin) await fs.writeFile(path.join(tempDir, infile), outCode)\n      await fs.writeFile(path.join(tempDir, `extra.${infile}`), `console.log('extra')`)\n      const importKeyword = path.extname(infile) === '.css' ? '@import' : 'import'\n      await fs.writeFile(nestedEntry,\n        order === 1 ? `${importKeyword} './${infile}'; ${importKeyword} './extra.${infile}'` :\n          order === 2 ? `${importKeyword} './extra.${infile}'; ${importKeyword} './${infile}'` :\n            `${importKeyword} './${infile}'`)\n      await execFileAsync(esbuildPath, [\n        nestedEntry,\n        '--bundle',\n        '--outfile=' + path.join(tempDir, outfile2),\n        '--sourcemap',\n        '--format=esm',\n      ].concat(followUpFlags), { cwd: testDir })\n\n      const out2Code = await fs.readFile(path.join(tempDir, outfile2), 'utf8')\n      recordCheck(out2Code.includes(`# sourceMappingURL=${encodeURIComponent(outfile2)}.map`), `${outfile2} file must link to ${outfile2}.map`)\n      const out2CodeMap = await fs.readFile(path.join(tempDir, `${outfile2}.map`), 'utf8')\n\n      const out2Map = await new SourceMapConsumer(out2CodeMap)\n      checkMap(out2Code, out2Map)\n    }\n\n    if (!failed) removeRecursiveSync(tempDir)\n  }\n\n  catch (e) {\n    console.error(`❌ [${kind}] ${e && e.message || e}`)\n    failed++\n  }\n\n  return failed\n}\n\nasync function checkNames(kind, testCase, { outfile, flags, entryPoints, crlf }) {\n  let failed = 0\n\n  try {\n    const recordCheck = (success, message) => {\n      if (!success) {\n        failed++\n        console.error(`❌ [${kind}] ${message}`)\n      }\n    }\n\n    const tempDir = path.join(testDir, `${kind}-${tempDirCount++}`)\n    await fs.mkdir(tempDir, { recursive: true })\n\n    for (const name in testCase) {\n      const tempPath = path.join(tempDir, name)\n      let code = testCase[name]\n      await fs.mkdir(path.dirname(tempPath), { recursive: true })\n      if (crlf) code = code.replace(/\\n/g, '\\r\\n')\n      await fs.writeFile(tempPath, code)\n    }\n\n    if (outfile) flags.push('--outfile=' + outfile)\n    const args = ['--sourcemap', '--log-level=warning'].concat(flags)\n    let stdout = ''\n\n    await new Promise((resolve, reject) => {\n      args.unshift(...entryPoints)\n      const child = childProcess.spawn(esbuildPath, args, { cwd: tempDir, stdio: ['pipe', 'pipe', 'inherit'] })\n      child.stdin.end()\n      child.stdout.on('data', chunk => stdout += chunk.toString())\n      child.stdout.on('end', resolve)\n      child.on('error', reject)\n    })\n\n    const outCode = await fs.readFile(path.join(tempDir, outfile), 'utf8')\n    recordCheck(outCode.includes(`# sourceMappingURL=${encodeURIComponent(outfile)}.map`), `${outfile} file must link to ${outfile}.map`)\n    const outCodeMap = await fs.readFile(path.join(tempDir, `${outfile}.map`), 'utf8')\n\n    // Check the mapping of various key locations back to the original source\n    const checkMap = (out, map) => {\n      const undoQuotes = x => `'\"`.includes(x[0]) ? (0, eval)(x) : x.startsWith('(') ? x.slice(1, -1) : x\n      const generatedLines = out.split(/\\r\\n|\\r|\\n/g)\n\n      for (let i = 0; i < map.sources.length; i++) {\n        const source = map.sources[i]\n        const content = map.sourcesContent[i];\n        let index = 0\n\n        // The names for us to check are prefixed by \"/**/\" right before to mark them\n        const parts = content.split(/(\\/\\*\\*\\/(?:\\w+|'\\w+'|\"\\w+\"))/g)\n\n        for (let j = 1; j < parts.length; j += 2) {\n          const expectedName = undoQuotes(parts[j].slice(4))\n          index += parts[j - 1].length\n\n          const prefixLines = content.slice(0, index + 4).split(/\\r\\n|\\r|\\n/g)\n          const line = prefixLines.length\n          const column = prefixLines[prefixLines.length - 1].length\n          index += parts[j].length\n\n          // There may be multiple mappings if the expression is spread across\n          // multiple lines. Check each one to see if any pass the checks.\n          const allGenerated = map.allGeneratedPositionsFor({ source, line, column })\n          for (let i = 0; i < allGenerated.length; i++) {\n            const canSkip = i + 1 < allGenerated.length // Don't skip the last one\n            const generated = allGenerated[i]\n            const original = map.originalPositionFor(generated)\n            if (canSkip && (original.source !== source || original.line !== line || original.column !== column)) continue\n            recordCheck(original.source === source && original.line === line && original.column === column,\n              `\\n` +\n              `\\n  original position:               ${JSON.stringify({ source, line, column })}` +\n              `\\n  maps to generated position:      ${JSON.stringify(generated)}` +\n              `\\n  which maps to original position: ${JSON.stringify(original)}` +\n              `\\n`)\n\n            if (original.source === source && original.line === line && original.column === column) {\n              const generatedContentAfter = generatedLines[generated.line - 1].slice(generated.column)\n              const matchAfter = /^(?:\\w+|'\\w+'|\"\\w+\"|\\(\\w+\\))/.exec(generatedContentAfter)\n              if (canSkip && matchAfter === null) continue\n              recordCheck(matchAfter !== null, `expected the identifier ${JSON.stringify(expectedName)} starting on line ${generated.line} here: ${generatedContentAfter.slice(0, 100)}`)\n\n              if (matchAfter !== null) {\n                const observedName = undoQuotes(matchAfter[0])\n                if (canSkip && expectedName !== (original.name || observedName)) continue\n                recordCheck(expectedName === (original.name || observedName),\n                  `\\n` +\n                  `\\n  generated position: ${JSON.stringify(generated)}` +\n                  `\\n  original position:  ${JSON.stringify(original)}` +\n                  `\\n` +\n                  `\\n  original name:  ${JSON.stringify(expectedName)}` +\n                  `\\n  generated name: ${JSON.stringify(observedName)}` +\n                  `\\n  mapping name:   ${JSON.stringify(original.name)}` +\n                  `\\n`)\n              }\n            }\n\n            break\n          }\n        }\n      }\n    }\n\n    const outMap = await new SourceMapConsumer(outCodeMap)\n    checkMap(outCode, outMap)\n\n    // Bundle again to test nested source map chaining\n    for (let order of [0, 1, 2]) {\n      const infile = outfile\n      const outfile2 = 'nested.' + infile\n      const nestedEntry = path.join(tempDir, `nested-entry.${infile}`)\n      await fs.writeFile(path.join(tempDir, `extra.${infile}`), `console.log('extra')`)\n      await fs.writeFile(nestedEntry,\n        order === 1 ? `import './${infile}'; import './extra.${infile}'` :\n          order === 2 ? `import './extra.${infile}'; import './${infile}'` :\n            `import './${infile}'`)\n      await execFileAsync(esbuildPath, [\n        nestedEntry,\n        '--bundle',\n        '--outfile=' + path.join(tempDir, outfile2),\n        '--sourcemap',\n      ], { cwd: testDir })\n\n      const out2Code = await fs.readFile(path.join(tempDir, outfile2), 'utf8')\n      recordCheck(out2Code.includes(`# sourceMappingURL=${encodeURIComponent(outfile2)}.map`), `${outfile2} file must link to ${outfile2}.map`)\n      const out2CodeMap = await fs.readFile(path.join(tempDir, `${outfile2}.map`), 'utf8')\n\n      const out2Map = await new SourceMapConsumer(out2CodeMap)\n      checkMap(out2Code, out2Map)\n    }\n\n    if (!failed) removeRecursiveSync(tempDir)\n  }\n\n  catch (e) {\n    console.error(`❌ [${kind}] ${e && e.message || e}`)\n    failed++\n  }\n\n  return failed\n}\n\nasync function main() {\n  const promises = []\n  for (const crlf of [false, true]) {\n    for (const minify of [false, true]) {\n      const flags = minify ? ['--minify'] : []\n      const suffix = (crlf ? '-crlf' : '') + (minify ? '-min' : '')\n      promises.push(\n        check('commonjs' + suffix, testCaseCommonJS, toSearchBundle, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['a.js'],\n          crlf,\n        }),\n        check('es6' + suffix, testCaseES6, toSearchBundle, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['a.js'],\n          crlf,\n        }),\n        check('discontiguous' + suffix, testCaseDiscontiguous, toSearchBundle, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['a.js'],\n          crlf,\n        }),\n        check('ts' + suffix, testCaseTypeScriptRuntime, toSearchNoBundleTS, {\n          outfile: 'out.js',\n          flags,\n          entryPoints: ['a.ts'],\n          crlf,\n        }),\n        check('stdin-stdout' + suffix, testCaseStdin, toSearchNoBundle, {\n          flags: flags.concat('--sourcefile=<stdin>'),\n          entryPoints: [],\n          crlf,\n        }),\n        check('empty' + suffix, testCaseEmptyFile, toSearchEmptyFile, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['entry.js'],\n          crlf,\n        }),\n        check('non-js' + suffix, testCaseNonJavaScriptFile, toSearchNonJavaScriptFile, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['entry.js'],\n          crlf,\n        }),\n        check('splitting' + suffix, testCaseCodeSplitting, toSearchCodeSplitting, {\n          outfile: 'out.js',\n          flags: flags.concat('--outdir=.', '--bundle', '--splitting', '--format=esm'),\n          entryPoints: ['out.ts', 'other.ts'],\n          crlf,\n        }),\n        check('unicode' + suffix, testCaseUnicode, toSearchUnicode, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle', '--charset=utf8'),\n          entryPoints: ['entry.js'],\n          crlf,\n        }),\n        check('unicode-globalName' + suffix, testCaseUnicode, toSearchUnicode, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle', '--global-name=πππ', '--charset=utf8'),\n          entryPoints: ['entry.js'],\n          crlf,\n        }),\n        check('dummy' + suffix, testCasePartialMappings, toSearchPartialMappings, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['entry.js'],\n          crlf,\n        }),\n        check('dummy' + suffix, testCasePartialMappingsPercentEscape, toSearchPartialMappings, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['entry.js'],\n          crlf,\n        }),\n        check('banner-footer' + suffix, testCaseES6, toSearchBundle, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle', '--banner:js=\"/* LICENSE abc */\"', '--footer:js=\"/* end of file banner */\"'),\n          entryPoints: ['a.js'],\n          crlf,\n        }),\n        check('complex' + suffix, testCaseComplex, toSearchComplex, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle', '--define:process.env.NODE_ENV=\"production\"'),\n          entryPoints: ['entry.js'],\n          crlf,\n        }),\n        check('dynamic-import' + suffix, testCaseDynamicImport, toSearchDynamicImport, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle', '--external:./ext/*', '--format=esm'),\n          entryPoints: ['entry.js'],\n          crlf,\n          followUpFlags: ['--external:./ext/*', '--format=esm'],\n        }),\n        check('dynamic-require' + suffix, testCaseDynamicImport, toSearchDynamicImport, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle', '--external:./ext/*', '--format=cjs'),\n          entryPoints: ['entry.js'],\n          crlf,\n          followUpFlags: ['--external:./ext/*', '--format=cjs'],\n        }),\n        check('bundle-css' + suffix, testCaseBundleCSS, toSearchBundleCSS, {\n          outfile: 'out.css',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['entry.css'],\n          crlf,\n        }),\n        check('jsx-runtime' + suffix, testCaseJSXRuntime, toSearchJSXRuntime, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle', '--jsx=automatic', '--external:react/jsx-runtime'),\n          entryPoints: ['entry.jsx'],\n          crlf,\n        }),\n        check('jsx-dev-runtime' + suffix, testCaseJSXRuntime, toSearchJSXRuntime, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle', '--jsx=automatic', '--jsx-dev', '--external:react/jsx-dev-runtime'),\n          entryPoints: ['entry.jsx'],\n          crlf,\n        }),\n        check('file-name-with-spaces' + suffix, testCaseFileNameWithSpaces, toSearchFileNameWithSpaces, {\n          outfile: 'output name with spaces.js',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['file name with spaces.js'],\n          crlf,\n        }),\n        check('absolute-source-mapping-url' + suffix, testCaseAbsoluteSourceMappingURL, toSearchAbsoluteSourceMappingURL, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['entry.js'],\n          crlf,\n        }),\n        check('absolute-sources-url' + suffix, testCaseAbsoluteSourcesURL, toSearchAbsoluteSourcesURL, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['entry.js'],\n          crlf,\n        }),\n        check('indexed-source-map' + suffix, testCaseIndexSourceMap, toSearchIndexSourceMap, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['entry.js'],\n          crlf,\n        }),\n        check('issue-4070' + suffix, testCaseNestedFoldersIssue4070, toSearchNestedFoldersIssue4070, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['src/main.js'],\n          crlf,\n        }),\n        check('issue-4075' + suffix, testCaseAbsolutePathIssue4075, toSearchAbsolutePathIssue4075, {\n          outfile: 'out.css',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['entry.css'],\n          crlf,\n        }),\n        check('issue-4080' + suffix, testCaseNullMappingIssue4080, toSearchNullMappingIssue4080, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle', '--format=esm'),\n          entryPoints: ['entry.js'],\n          crlf,\n        }),\n        check('issue-4104' + suffix, testCaseMissingSourcesIssue4104, toSearchMissingSourcesIssue4104, {\n          outfile: 'out.js',\n          flags: flags.concat('--format=esm', '--sourcemap', '--bundle', '--loader:.html=text', '--packages=external'),\n          entryPoints: ['entry.js'],\n          crlf,\n          followUpFlags: ['--packages=external'],\n        }),\n        check('issue-4169' + suffix, testCaseDefineWithObjectIssue4169, toSearchDefineWithObjectIssue4169, {\n          outfile: 'out.js',\n          flags: flags.concat('--format=esm', '--sourcemap', '--bundle', '--define:OBJECT={\"test object\":1}', '--define:ARRAY=[\"test array\"]'),\n          entryPoints: ['entry.js'],\n          crlf,\n        }),\n\n        // Checks for the \"names\" field\n        checkNames('names' + suffix, testCaseNames, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['entry.js'],\n          crlf,\n        }),\n        checkNames('names-mangle' + suffix, testCaseNames, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle', '--mangle-props=^mangle_$'),\n          entryPoints: ['entry.js'],\n          crlf,\n        }),\n        checkNames('names-mangle-quoted' + suffix, testCaseNames, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle', '--mangle-props=^mangle_$', '--mangle-quoted'),\n          entryPoints: ['entry.js'],\n          crlf,\n        }),\n\n        // Checks for loading missing \"sourcesContent\" in nested source maps\n        check('missing-sources-content' + suffix, testCaseMissingSourcesContent, toSearchMissingSourcesContent, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['foo.js'],\n          crlf,\n        }),\n\n        // Checks for null entries in \"sourcesContent\" in nested source maps\n        check('null-sources-content' + suffix, testCaseNullSourcesContent, toSearchNullSourcesContent, {\n          outfile: 'out.js',\n          flags: flags.concat('--bundle'),\n          entryPoints: ['foo.js'],\n          crlf,\n        }),\n\n        // This checks for issues with files in a bundle that don't emit source maps\n        check('splitting-empty' + suffix, testCaseCodeSplittingEmptyFile, toSearchCodeSplittingEmptyFile, {\n          flags: flags.concat('--outdir=.', '--bundle', '--splitting', '--format=esm'),\n          entryPoints: ['entry1.ts', 'entry2.ts'],\n          crlf,\n          checkFirstChunk: true,\n        }),\n      )\n    }\n  }\n\n  const failed = (await Promise.all(promises)).reduce((a, b) => a + b, 0)\n  if (failed > 0) {\n    console.error(`❌ verify source map failed`)\n    process.exit(1)\n  } else {\n    console.log(`✅ verify source map passed`)\n    removeRecursiveSync(testDir)\n  }\n}\n\nmain().catch(e => setTimeout(() => { throw e }))\n"
  },
  {
    "path": "scripts/wasm-tests.js",
    "content": "const { removeRecursiveSync, buildWasmLib } = require('./esbuild.js');\nconst child_process = require('child_process');\nconst assert = require('assert');\nconst path = require('path');\nconst fs = require('fs');\n\nconst tests = {\n  serveTest({ testDir, esbuildPathWASM }) {\n    try {\n      child_process.execFileSync('node', [\n        esbuildPathWASM,\n        '--servedir=.',\n        '--log-level=warning',\n      ], {\n        stdio: 'pipe',\n        cwd: testDir,\n      });\n      throw new Error('Expected an error to be thrown');\n    } catch (err) {\n      assert.strictEqual(err.stderr + '', `✘ [ERROR] The \"serve\" API is not supported when using WebAssembly\\n\\n`)\n    }\n  },\n\n  basicStdinTest({ testDir, esbuildPathWASM }) {\n    const stdout = child_process.execFileSync('node', [\n      esbuildPathWASM,\n      '--format=cjs',\n      '--log-level=warning',\n    ], {\n      stdio: ['pipe', 'pipe', 'inherit'],\n      cwd: testDir,\n      input: `export default 1+2`,\n    }).toString();\n\n    // Check that the bundle is valid\n    const module = { exports: {} };\n    new Function('module', 'exports', stdout)(module, module.exports);\n    assert.deepStrictEqual(module.exports.default, 3);\n  },\n\n  stdinOutfileTest({ testDir, esbuildPathWASM }) {\n    const outfile = path.join(testDir, 'out.js')\n    child_process.execFileSync('node', [\n      esbuildPathWASM,\n      '--bundle',\n      '--format=cjs',\n      '--outfile=' + outfile,\n      '--log-level=warning',\n    ], {\n      stdio: ['pipe', 'pipe', 'inherit'],\n      cwd: testDir,\n      input: `export default 1+2`,\n    }).toString();\n\n    // Check that the bundle is valid\n    const exports = require(outfile);\n    assert.deepStrictEqual(exports.default, 3);\n  },\n\n  stdinStdoutUnicodeTest({ testDir, esbuildPathWASM }) {\n    const stdout = child_process.execFileSync('node', [\n      esbuildPathWASM,\n      '--format=cjs',\n      '--log-level=warning',\n    ], {\n      stdio: ['pipe', 'pipe', 'inherit'],\n      cwd: testDir,\n      input: `export default ['π', '🍕']`,\n    }).toString();\n\n    // Check that the bundle is valid\n    const module = { exports: {} };\n    new Function('module', 'exports', stdout)(module, module.exports);\n    assert.deepStrictEqual(module.exports.default, ['π', '🍕']);\n  },\n\n  stdinOutfileUnicodeTest({ testDir, esbuildPathWASM }) {\n    const outfile = path.join(testDir, 'out.js')\n    child_process.execFileSync('node', [\n      esbuildPathWASM,\n      '--bundle',\n      '--format=cjs',\n      '--outfile=' + outfile,\n      '--log-level=warning',\n    ], {\n      stdio: ['pipe', 'pipe', 'inherit'],\n      cwd: testDir,\n      input: `export default ['π', '🍕']`,\n    }).toString();\n\n    // Check that the bundle is valid\n    const exports = require(outfile);\n    assert.deepStrictEqual(exports.default, ['π', '🍕']);\n  },\n\n  stdoutLargeTest({ testDir, esbuildPathNative, esbuildPathWASM }) {\n    const entryPoint = path.join(__dirname, 'js-api-tests.js');\n\n    // Build with native\n    const stdoutNative = child_process.execFileSync(esbuildPathNative, [\n      entryPoint,\n      '--log-level=warning',\n    ], {\n      stdio: ['pipe', 'pipe', 'inherit'],\n      cwd: testDir,\n    }).toString();\n\n    // Build with WASM\n    const stdoutWASM = child_process.execFileSync('node', [\n      esbuildPathWASM,\n      entryPoint,\n      '--log-level=warning',\n    ], {\n      stdio: ['pipe', 'pipe', 'inherit'],\n      cwd: testDir,\n    }).toString();\n\n    // Check that the output is equal\n    assert.deepStrictEqual(stdoutNative.length, stdoutWASM.length);\n    assert.deepStrictEqual(stdoutNative, stdoutWASM);\n  },\n\n  outfileLargeTest({ testDir, esbuildPathNative, esbuildPathWASM }) {\n    const entryPoint = path.join(__dirname, 'js-api-tests.js');\n\n    // Build with native\n    const outfileNative = path.join(testDir, 'a.js');\n    const stdoutNative = child_process.execFileSync(esbuildPathNative, [\n      entryPoint,\n      '--outfile=' + outfileNative,\n      '--log-level=warning',\n    ], {\n      stdio: ['pipe', 'pipe', 'inherit'],\n      cwd: testDir,\n    }).toString();\n    const jsNative = fs.readFileSync(outfileNative, 'utf8');\n\n    // Build with WASM\n    const outfileWASM = path.join(testDir, 'b.js');\n    const stdoutWASM = child_process.execFileSync('node', [\n      esbuildPathWASM,\n      entryPoint,\n      '--outfile=' + outfileWASM,\n      '--log-level=warning',\n    ], {\n      stdio: ['pipe', 'pipe', 'inherit'],\n      cwd: testDir,\n    }).toString();\n    const jsWASM = fs.readFileSync(outfileWASM, 'utf8');\n\n    // Check that the output is equal\n    assert.deepStrictEqual(jsNative.length, jsWASM.length);\n    assert.deepStrictEqual(jsNative, jsWASM);\n  },\n\n  outfileNestedTest({ testDir, esbuildPathWASM }) {\n    const outfile = path.join(testDir, 'a', 'b', 'c', 'd', 'out.js');\n    child_process.execFileSync('node', [\n      esbuildPathWASM,\n      '--bundle',\n      '--format=cjs',\n      '--outfile=' + outfile,\n      '--log-level=warning',\n    ], {\n      stdio: ['pipe', 'pipe', 'inherit'],\n      cwd: testDir,\n      input: `export default 123`,\n    }).toString();\n\n    // Check that the bundle is valid\n    const exports = require(outfile);\n    assert.deepStrictEqual(exports.default, 123);\n  },\n\n  metafileNestedTest({ testDir, esbuildPathWASM }) {\n    const outfile = path.join(testDir, 'out.js');\n    const metafile = path.join(testDir, 'a', 'b', 'c', 'd', 'meta.json');\n    const cwd = path.join(testDir, 'a', 'b')\n    fs.mkdirSync(cwd, { recursive: true })\n    child_process.execFileSync('node', [\n      esbuildPathWASM,\n      '--bundle',\n      '--format=cjs',\n      '--outfile=' + outfile,\n      '--metafile=' + metafile,\n      '--log-level=warning',\n    ], {\n      stdio: ['pipe', 'pipe', 'inherit'],\n      cwd,\n      input: `export default 123`,\n    }).toString();\n\n    // Check that the bundle is valid\n    const exports = require(outfile);\n    assert.deepStrictEqual(exports.default, 123);\n    const json = JSON.parse(fs.readFileSync(metafile, 'utf8'));\n    assert.deepStrictEqual(json.outputs['../../out.js'].entryPoint, '<stdin>');\n  },\n\n  importRelativeFileTest({ testDir, esbuildPathWASM }) {\n    const outfile = path.join(testDir, 'out.js')\n    const packageJSON = path.join(__dirname, '..', 'npm', 'esbuild-wasm', 'package.json');\n    child_process.execFileSync('node', [\n      esbuildPathWASM,\n      '--bundle',\n      '--format=cjs',\n      '--outfile=' + outfile,\n      '--log-level=warning',\n    ], {\n      stdio: ['pipe', 'pipe', 'inherit'],\n      cwd: testDir,\n      input: `export {default} from ` + JSON.stringify('./' + path.relative(testDir, packageJSON)),\n    }).toString();\n\n    // Check that the bundle is valid\n    const exports = require(outfile);\n    assert.deepStrictEqual(exports.default, require(packageJSON));\n  },\n\n  importAbsoluteFileTest({ testDir, esbuildPathWASM }) {\n    const outfile = path.join(testDir, 'out.js')\n    const packageJSON = path.join(__dirname, '..', 'npm', 'esbuild-wasm', 'package.json');\n    child_process.execFileSync('node', [\n      esbuildPathWASM,\n      '--bundle',\n      '--format=cjs',\n      '--outfile=' + outfile,\n      '--log-level=warning',\n    ], {\n      stdio: ['pipe', 'pipe', 'inherit'],\n      cwd: testDir,\n      input: `export {default} from ` + JSON.stringify(packageJSON),\n    }).toString();\n\n    // Check that the bundle is valid\n    const exports = require(outfile);\n    assert.deepStrictEqual(exports.default, require(packageJSON));\n  },\n  zipFile({ testDir, esbuildPathWASM }) {\n    const entry = path.join(testDir, 'entry.js')\n    fs.writeFileSync(entry, `\n      import foo from './test.zip/foo.js'\n      import bar from './test.zip/bar/bar.js'\n\n      import __virtual__1 from './test.zip/__virtual__/ignored/0/foo.js'\n      import __virtual__2 from './test.zip/ignored/__virtual__/ignored/1/foo.js'\n      import __virtual__3 from './test.zip/__virtual__/ignored/1/test.zip/foo.js'\n\n      import $$virtual1 from './test.zip/$$virtual/ignored/0/foo.js'\n      import $$virtual2 from './test.zip/ignored/$$virtual/ignored/1/foo.js'\n      import $$virtual3 from './test.zip/$$virtual/ignored/1/test.zip/foo.js'\n\n      console.log({\n        foo,\n        bar,\n\n        __virtual__1,\n        __virtual__2,\n        __virtual__3,\n\n        $$virtual1,\n        $$virtual2,\n        $$virtual3,\n      })\n    `)\n\n    // This uses the real file system instead of the mock file system so that\n    // we can check that everything works as expected on Windows, which is not\n    // a POSIX environment.\n    fs.writeFileSync(path.join(testDir, 'test.zip'), Buffer.from(\n      `UEsDBAoAAgAAAG1qCFUSAXosFQAAABUAAAAGABwAZm9vLmpzVVQJAAOeRfFioEXxYnV4C` +\n      `wABBPUBAAAEFAAAAGV4cG9ydCBkZWZhdWx0ICdmb28nClBLAwQKAAIAAABzaghVwuDbLR` +\n      `UAAAAVAAAACgAcAGJhci9iYXIuanNVVAkAA6lF8WKrRfFidXgLAAEE9QEAAAQUAAAAZXh` +\n      `wb3J0IGRlZmF1bHQgJ2JhcicKUEsBAh4DCgACAAAAbWoIVRIBeiwVAAAAFQAAAAYAGAAA` +\n      `AAAAAQAAAKSBAAAAAGZvby5qc1VUBQADnkXxYnV4CwABBPUBAAAEFAAAAFBLAQIeAwoAA` +\n      `gAAAHNqCFXC4NstFQAAABUAAAAKABgAAAAAAAEAAACkgVUAAABiYXIvYmFyLmpzVVQFAA` +\n      `OpRfFidXgLAAEE9QEAAAQUAAAAUEsFBgAAAAACAAIAnAAAAK4AAAAAAA==`, 'base64'))\n\n    const stdout = child_process.execFileSync('node', [\n      esbuildPathWASM,\n      '--bundle',\n      entry,\n    ], {\n      stdio: 'pipe',\n      cwd: testDir,\n    }).toString();\n\n    assert.strictEqual(stdout, `(() => {\n  // test.zip/foo.js\n  var foo_default = \"foo\";\n\n  // test.zip/bar/bar.js\n  var bar_default = \"bar\";\n\n  // test.zip/__virtual__/ignored/0/foo.js\n  var foo_default2 = \"foo\";\n\n  // test.zip/ignored/__virtual__/ignored/1/foo.js\n  var foo_default3 = \"foo\";\n\n  // test.zip/__virtual__/ignored/1/test.zip/foo.js\n  var foo_default4 = \"foo\";\n\n  // test.zip/$$virtual/ignored/0/foo.js\n  var foo_default5 = \"foo\";\n\n  // test.zip/ignored/$$virtual/ignored/1/foo.js\n  var foo_default6 = \"foo\";\n\n  // test.zip/$$virtual/ignored/1/test.zip/foo.js\n  var foo_default7 = \"foo\";\n\n  // entry.js\n  console.log({\n    foo: foo_default,\n    bar: bar_default,\n    __virtual__1: foo_default2,\n    __virtual__2: foo_default3,\n    __virtual__3: foo_default4,\n    $$virtual1: foo_default5,\n    $$virtual2: foo_default6,\n    $$virtual3: foo_default7\n  });\n})();\n`)\n  },\n\n  // https://github.com/evanw/esbuild/issues/3001\n  nodePathsReaddirEINVAL({ testDir, esbuildPathWASM }) {\n    const libDir = path.join(testDir, 'lib');\n    const libFile = path.join(libDir, 'file.js');\n    fs.mkdirSync(libDir, { recursive: true });\n    fs.writeFileSync(libFile, 'foo()');\n    const stdout = child_process.execFileSync('node', [\n      esbuildPathWASM,\n      '--bundle',\n      '--format=esm',\n    ], {\n      stdio: ['pipe', 'pipe', 'inherit'],\n      cwd: testDir,\n      input: `import \"file.js\"`,\n      env: { ...process.env, NODE_PATH: libDir },\n    }).toString();\n\n    assert.deepStrictEqual(stdout, '// lib/file.js\\nfoo();\\n');\n  },\n};\n\nfunction runTest({ testDir, esbuildPathNative, esbuildPathWASM, test }) {\n  try {\n    fs.mkdirSync(testDir, { recursive: true })\n    test({ testDir, esbuildPathNative, esbuildPathWASM })\n    return true\n  } catch (e) {\n    console.error(`❌ ${test.name} failed: ${e && e.message || e}`)\n    return false\n  }\n}\n\nasync function main() {\n  // Generate the WebAssembly module\n  const esbuildPathNative = path.join(__dirname, '..', process.platform === 'win32' ? 'esbuild.exe' : 'esbuild');\n  await buildWasmLib(esbuildPathNative);\n\n  const esbuildPathWASM = path.join(__dirname, '..', 'npm', 'esbuild-wasm', 'bin', 'esbuild');\n  const testDir = path.join(__dirname, '.wasm-tests')\n\n  // Run all tests in serial because WebAssembly compilation is a CPU hog\n  let allTestsPassed = true;\n  for (const test in tests) {\n    if (!runTest({\n      testDir: path.join(testDir, test),\n      test: tests[test],\n      esbuildPathNative,\n      esbuildPathWASM,\n    })) {\n      allTestsPassed = false;\n    }\n  }\n\n  if (!allTestsPassed) {\n    console.error(`❌ wasm-tests failed`)\n    process.exit(1)\n  } else {\n    console.log(`✅ wasm-tests passed`)\n    removeRecursiveSync(testDir)\n  }\n}\n\nmain().catch(e => setTimeout(() => { throw e }))\n"
  },
  {
    "path": "staticcheck.conf",
    "content": "# I'm disabling this Go linter that they forced on everyone who uses VSCode's\n# Go support. The lints are annoying, distracting, and largely useless or\n# worse. Following the lints sometimes even harms code readability, such as\n# suggesting the removal of an important comment.\nchecks = []\n"
  },
  {
    "path": "version.txt",
    "content": "0.27.4\n"
  }
]